File size: 7,877 Bytes
7eccd3a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
"""
Simple Streamlit App for Loan Prediction - Fixed for PyTorch compatibility
"""
import streamlit as st
import pandas as pd
import numpy as np
import os
import sys

# Add the project directory to the path
current_dir = os.path.dirname(os.path.abspath(__file__))
project_dir = os.path.dirname(current_dir)
sys.path.append(project_dir)
sys.path.append(os.path.join(project_dir, 'src'))

# Page configuration
st.set_page_config(
    page_title="Loan Prediction App",
    page_icon="๐Ÿฆ",
    layout="wide"
)

# Initialize session state
if 'predictor' not in st.session_state:
    st.session_state.predictor = None
    st.session_state.model_loaded = False

@st.cache_resource
def load_predictor():
    """Load the predictor with caching to avoid reloading"""
    try:
        # Import only when needed
        from src.inference import LoanPredictor
        return LoanPredictor()
    except Exception as e:
        st.error(f"Error loading model: {e}")
        return None

def main():
    # Header
    st.title("๐Ÿฆ Loan Prediction System")
    st.markdown("AI-Powered Loan Approval Decision Support")
    
    # Load model
    if st.session_state.predictor is None:
        with st.spinner("Loading model..."):
            st.session_state.predictor = load_predictor()
    
    if st.session_state.predictor is None:
        st.error("Failed to load the prediction model. Please check your setup.")
        st.stop()
    
    st.success("โœ… Model loaded successfully!")
    
    # Sidebar for navigation
    st.sidebar.title("Navigation")
    page = st.sidebar.selectbox("Choose page", ["Single Prediction", "Model Info"])
    
    if page == "Single Prediction":
        single_prediction_page()
    else:
        model_info_page()

def single_prediction_page():
    st.header("๐Ÿ“‹ Single Loan Application")
    
    # Create input form
    col1, col2 = st.columns(2)
    
    with col1:
        st.subheader("Financial Information")
        annual_inc = st.number_input("Annual Income ($)", min_value=0.0, value=50000.0, step=1000.0)
        dti = st.number_input("Debt-to-Income Ratio (%)", min_value=0.0, max_value=100.0, value=15.0, step=0.1)
        installment = st.number_input("Monthly Installment ($)", min_value=0.0, value=300.0, step=10.0)
        int_rate = st.number_input("Interest Rate (%)", min_value=0.0, max_value=50.0, value=12.0, step=0.1)
        revol_bal = st.number_input("Revolving Balance ($)", min_value=0.0, value=5000.0, step=100.0)
    
    with col2:
        st.subheader("Credit Information")
        credit_history_length = st.number_input("Credit History Length (years)", min_value=0.0, value=10.0, step=0.5)
        revol_util = st.number_input("Revolving Utilization (%)", min_value=0.0, max_value=100.0, value=30.0, step=0.1)
        debt_to_credit_ratio = st.number_input("Debt-to-Credit Ratio", min_value=0.0, max_value=1.0, value=0.3, step=0.01)
        total_credit_lines = st.number_input("Total Credit Lines", min_value=0, value=10, step=1)
    
    # Threshold control
    st.subheader("โš™๏ธ Prediction Settings")
    threshold = st.slider("Decision Threshold", min_value=0.0, max_value=1.0, value=0.6, step=0.05, 
                         help="Higher threshold = more conservative approval")
    
    # Prediction button
    if st.button("๐Ÿ”ฎ Predict Loan Outcome", type="primary"):
        input_data = {
            'annual_inc': annual_inc,
            'dti': dti,
            'installment': installment,
            'int_rate': int_rate,
            'revol_bal': revol_bal,
            'credit_history_length': credit_history_length,
            'revol_util': revol_util,
            'debt_to_credit_ratio': debt_to_credit_ratio,
            'total_credit_lines': total_credit_lines
        }
        
        try:
            with st.spinner("Making prediction..."):
                result = st.session_state.predictor.predict_single(input_data)
            
            # Display results
            probability = result['probability_fully_paid']
            custom_prediction = 1 if probability >= threshold else 0
            
            st.subheader("๐Ÿ“Š Prediction Results")
            
            # Metrics
            col1, col2, col3 = st.columns(3)
            with col1:
                st.metric("Probability", f"{probability:.3f}")
            with col2:
                st.metric("Threshold", f"{threshold:.3f}")
            with col3:
                decision = "APPROVED" if custom_prediction == 1 else "REJECTED"
                color = "green" if custom_prediction == 1 else "red"
                st.markdown(f"<h3 style='color: {color};'>{decision}</h3>", unsafe_allow_html=True)
            
            # Explanation
            if custom_prediction == 1:
                st.success(f"โœ… **LOAN APPROVED** - Probability ({probability:.3f}) โ‰ฅ Threshold ({threshold:.3f})")
            else:
                st.error(f"โŒ **LOAN REJECTED** - Probability ({probability:.3f}) < Threshold ({threshold:.3f})")
            
            # Risk assessment
            if probability > 0.8:
                risk_level = "Low Risk"
                risk_color = "green"
            elif probability > 0.6:
                risk_level = "Medium Risk"
                risk_color = "orange"
            else:
                risk_level = "High Risk"
                risk_color = "red"
            
            st.markdown(f"**Risk Level:** <span style='color: {risk_color};'>{risk_level}</span>", 
                       unsafe_allow_html=True)
            
            # Additional insights
            st.info(f"""๐Ÿ“ˆ **Business Insights:**
            - Default probability: {(1-probability):.1%}
            - Confidence level: {max(probability, 1-probability):.1%}
            - Recommendation: {"Approve with standard terms" if probability > 0.8 else "Consider additional review" if probability > 0.6 else "High risk - requires careful evaluation"}
            """)
            
        except Exception as e:
            st.error(f"Error making prediction: {str(e)}")

def model_info_page():
    st.header("๐Ÿค– Model Information")
    
    st.subheader("๐Ÿ—๏ธ Model Architecture")
    st.write("""
    **Deep Artificial Neural Network (ANN)**
    - Input Layer: 9 features
    - Hidden Layer 1: 128 neurons (ReLU)
    - Hidden Layer 2: 64 neurons (ReLU)
    - Hidden Layer 3: 32 neurons (ReLU)
    - Hidden Layer 4: 16 neurons (ReLU)
    - Output Layer: 1 neuron (Sigmoid)
    - Dropout: [0.3, 0.3, 0.2, 0.1]
    """)
    
    st.subheader("๐Ÿ“Š Input Features")
    features_df = pd.DataFrame([
        {"Feature": "annual_inc", "Description": "Annual income ($)"},
        {"Feature": "dti", "Description": "Debt-to-income ratio (%)"},
        {"Feature": "installment", "Description": "Monthly loan installment ($)"},
        {"Feature": "int_rate", "Description": "Loan interest rate (%)"},
        {"Feature": "revol_bal", "Description": "Total revolving credit balance ($)"},
        {"Feature": "credit_history_length", "Description": "Credit history length (years)"},
        {"Feature": "revol_util", "Description": "Revolving credit utilization (%)"},
        {"Feature": "debt_to_credit_ratio", "Description": "Debt to available credit ratio"},
        {"Feature": "total_credit_lines", "Description": "Total number of credit lines"}
    ])
    st.dataframe(features_df, use_container_width=True)
    
    st.subheader("๐Ÿ“– How to Use")
    st.write("""
    1. **Enter loan application details** in the form
    2. **Adjust the threshold slider** to control approval strictness
    3. **Click "Predict"** to get results
    4. **Interpret results:**
       - Higher threshold = more conservative (fewer approvals)
       - Lower threshold = more liberal (more approvals)
       - Probability shows model confidence in loan repayment
    """)

if __name__ == "__main__":
    main()