File size: 12,330 Bytes
3efedb0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
import streamlit as st
import requests
import pandas as pd
import plotly.express as px
import traceback

# API endpoint
API_URL = "http://127.0.0.1:8000/predict"

def show_loan_prediction():
    st.title("Loan Approval Prediction System")
    
    # Create sidebar for inputs
    with st.sidebar:
        st.header("Loan Application Details")
        
        # Personal information
        st.subheader("Personal Information")
        no_of_dependents = st.slider("Number of Dependents", 0, 10, 2)
        education = st.selectbox("Education", ["Graduate", "Not Graduate"])
        self_employed = st.selectbox("Self Employed", ["Yes", "No"])
        
        # Financial information
        st.subheader("Financial Information")
        income_annum = st.number_input("Annual Income (₹)", min_value=100000, max_value=20000000, value=5000000, step=100000)
        loan_amount = st.number_input("Loan Amount (₹)", min_value=100000, max_value=50000000, value=10000000, step=100000)
        loan_term = st.slider("Loan Term (years)", 2, 30, 15)
        cibil_score = st.slider("CIBIL Score", 300, 900, 650)
        
        # Assets information
        st.subheader("Assets Information")
        residential_assets_value = st.number_input("Residential Assets Value (₹)", min_value=0, max_value=50000000, value=5000000, step=100000)
        commercial_assets_value = st.number_input("Commercial Assets Value (₹)", min_value=0, max_value=50000000, value=2000000, step=100000)
        luxury_assets_value = st.number_input("Luxury Assets Value (₹)", min_value=0, max_value=50000000, value=1000000, step=100000)
        bank_asset_value = st.number_input("Bank Assets Value (₹)", min_value=0, max_value=50000000, value=3000000, step=100000)
        
        # Submit button
        predict_button = st.button("Predict Loan Approval")
    
    # Main content area
    if predict_button or ('prediction_result' in st.session_state and st.session_state.prediction_result):
        # If button was just pressed, API call happens
        if predict_button:
            # Prepare data for API
            data = {
                "no_of_dependents": no_of_dependents,
                "education": education,
                "self_employed": self_employed,
                "income_annum": income_annum,
                "loan_amount": loan_amount,
                "loan_term": loan_term,
                "cibil_score": cibil_score,
                "residential_assets_value": residential_assets_value,
                "commercial_assets_value": commercial_assets_value,
                "luxury_assets_value": luxury_assets_value,
                "bank_asset_value": bank_asset_value
            }
            
            # Call API
            with st.spinner("Predicting..."):
                try:
                    # Update the API endpoint to use the specific loan endpoint
                    response = requests.post(
                        "http://127.0.0.1:8000/predict/loan",
                        json={"features": data}
                    )
                    
                    if response.status_code == 200:
                        result = response.json()
                        
                        # Store result in session state
                        st.session_state.prediction_result = result
                        st.session_state.loan_data = data
                except Exception as e:
                    st.error(f"Error connecting to API: {str(e)}")
                    st.error(traceback.format_exc())
                    st.info("Make sure the FastAPI backend is running with: python -m uvicorn src.api.main:app --reload")
                    return
        
        # Use stored result if available
        if 'prediction_result' in st.session_state:
            result = st.session_state.prediction_result
            data = st.session_state.loan_data
            
            # Display prediction result
            if result["prediction"]:
                st.success("### Loan Approved! ✅")
            else:
                st.error("### Loan Rejected ❌")
            
            # Display approval probability
            col1, col2 = st.columns(2)
            with col1:
                st.subheader("Explanation")
                st.write("Based on your financial profile and application details, here's why your loan was approved/rejected.")
                
                # Display factors affecting application
                st.subheader("Factors Affecting Your Application")
                
                # Create feature importance dataframe
                feature_names = [
                    "CIBIL Score", 
                    "Annual Income", 
                    "Loan Amount", 
                    "Loan Term", 
                    "Residential Assets",
                    "Commercial Assets",
                    "Luxury Assets",
                    "Bank Assets",
                    "Dependents",
                    "Education",
                    "Self Employed"
                ]
                
                # Make sure we have the right number of feature names
                importance_values = result.get("feature_importance", [])
                
                # If no feature importance is returned, create dummy values
                if not importance_values:
                    importance_values = [0.2, 0.15, 0.15, 0.1, 0.1, 0.08, 0.07, 0.05, 0.05, 0.03, 0.02]
                
                # Adjust lengths if needed
                if len(importance_values) != len(feature_names):
                    if len(importance_values) > len(feature_names):
                        feature_names = feature_names + [f"Feature {i+1}" for i in range(len(feature_names), len(importance_values))]
                    else:
                        importance_values = importance_values + [0] * (len(feature_names) - len(importance_values))
                
                # Create and sort the dataframe
                importance_df = pd.DataFrame({
                    "Feature": feature_names[:len(importance_values)],
                    "Importance": importance_values
                })
                importance_df = importance_df.sort_values("Importance", ascending=False)
                
                # Create the bar chart
                fig = px.bar(
                    importance_df,
                    x="Importance",
                    y="Feature",
                    orientation='h',
                    color="Importance",
                    color_continuous_scale=px.colors.sequential.Blues
                )
                fig.update_layout(
                    margin=dict(l=20, r=20, t=30, b=20),
                    height=400
                )
                st.plotly_chart(fig, use_container_width=True)
            
            with col2:
                # Display approval probability
                st.subheader("Approval Probability")
                st.markdown("### Confidence")
                probability = result["probability"] * 100
                st.markdown(f"### {probability:.2f}%")
                
                # Display financial metrics
                st.subheader("Application Summary")
                st.subheader("Detailed Financial Metrics")
                
                metrics_col1, metrics_col2, metrics_col3 = st.columns(3)
                
                with metrics_col1:
                    st.markdown("**CIBIL Score**")
                    st.markdown(f"### {data['cibil_score']}")
                    if data['cibil_score'] >= 700:
                        st.markdown("Good - Favorable credit history")
                    elif data['cibil_score'] >= 600:
                        st.markdown("Fair - Average credit history")
                    else:
                        st.markdown("Poor - Unfavorable credit history")
                
                with metrics_col2:
                    # Calculate debt-to-income ratio
                    monthly_income = data['income_annum'] / 12
                    loan_amount = data['loan_amount']
                    interest_rate = 0.08  # Assuming 8% interest rate
                    loan_term_months = data['loan_term'] * 12
                    
                    # Calculate monthly payment using the formula: P = L[i(1+i)^n]/[(1+i)^n-1]
                    monthly_interest = interest_rate / 12
                    monthly_payment = loan_amount * (monthly_interest * (1 + monthly_interest) ** loan_term_months) / ((1 + monthly_interest) ** loan_term_months - 1)
                    
                    debt_to_income = monthly_payment / monthly_income
                    
                    st.markdown("**Debt-to-Income**")
                    st.markdown(f"### {debt_to_income:.2f}")
                    
                    if debt_to_income <= 0.36:
                        st.markdown("Low - Manageable debt burden")
                    elif debt_to_income <= 0.43:
                        st.markdown("Medium - Moderate debt burden")
                    else:
                        st.markdown("High - Significant debt burden")
                
                with metrics_col3:
                    # Calculate assets-to-loan ratio
                    total_assets = data['residential_assets_value'] + data['commercial_assets_value'] + data['luxury_assets_value'] + data['bank_asset_value']
                    assets_to_loan = total_assets / loan_amount
                    
                    st.markdown("**Assets-to-Loan**")
                    st.markdown(f"### {assets_to_loan:.2f}")
                    
                    if assets_to_loan >= 2:
                        st.markdown("Strong - Excellent asset coverage")
                    elif assets_to_loan >= 1:
                        st.markdown("Fair - Minimal asset coverage")
                    else:
                        st.markdown("Weak - Insufficient asset coverage")
                
                # Monthly payment analysis
                st.subheader("Monthly Payment Analysis")
                
                payment_col1, payment_col2 = st.columns(2)
                
                with payment_col1:
                    st.markdown("**Monthly Payment**")
                    st.markdown(f"### ₹{monthly_payment:,.2f}")
                    
                    payment_ratio = monthly_payment / monthly_income
                    payment_percentage = payment_ratio * 100
                    
                    st.markdown(f"This represents {payment_percentage:.2f}% of your monthly income (₹{monthly_income:,.2f}).")
                    
                    if payment_ratio <= 0.28:
                        st.markdown("Excellent - Very affordable payment")
                    elif payment_ratio <= 0.36:
                        st.markdown("Good - Affordable payment")
                    elif payment_ratio <= 0.43:
                        st.markdown("Fair - Manageable payment")
                    else:
                        st.markdown("Poor - High payment burden")
                
                with payment_col2:
                    # Create pie chart for income allocation
                    remaining_income = monthly_income - monthly_payment
                    
                    income_allocation = pd.DataFrame({
                        'Category': ['Loan Payment', 'Remaining Income'],
                        'Amount': [monthly_payment, remaining_income]
                    })
                    
                    fig = px.pie(
                        income_allocation, 
                        values='Amount', 
                        names='Category',
                        color_discrete_sequence=['#FF9900', '#0066CC'],
                        hole=0.4
                    )
                    fig.update_layout(
                        margin=dict(l=20, r=20, t=20, b=20),
                        height=200
                    )
                    st.plotly_chart(fig, use_container_width=True)