Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -176,20 +176,14 @@ with tab1:
|
|
176 |
|
177 |
total_income = applicant_income + coapplicant_income
|
178 |
|
179 |
-
# Metrics already shown above with monthly payment
|
180 |
-
|
181 |
# Calculate monthly payment (simplified calculation)
|
182 |
-
# Convert loan term to years for calculation
|
183 |
-
loan_term_years = loan_term / 12
|
184 |
-
|
185 |
-
# Simple monthly payment calculation (approximation)
|
186 |
interest_rate = 0.05 # Assuming 5% annual interest rate
|
187 |
monthly_interest = interest_rate / 12
|
188 |
num_payments = loan_term
|
189 |
|
190 |
# Monthly payment using the loan amortization formula
|
191 |
-
if monthly_interest == 0:
|
192 |
-
monthly_payment =
|
193 |
else:
|
194 |
monthly_payment = loan_amount * (monthly_interest * (1 + monthly_interest) ** num_payments) / \
|
195 |
((1 + monthly_interest) ** num_payments - 1)
|
@@ -203,7 +197,7 @@ with tab1:
|
|
203 |
col2.metric("Estimated Monthly Payment", f"${monthly_payment:.2f}")
|
204 |
col3.metric("Loan Term", f"{loan_term//12} years")
|
205 |
|
206 |
-
#
|
207 |
st.markdown("<h4>Debt-to-Income Assessment</h4>", unsafe_allow_html=True)
|
208 |
|
209 |
# Cap the displayed percentage at 100% for the visual
|
@@ -237,22 +231,51 @@ with tab1:
|
|
237 |
</div>
|
238 |
""", unsafe_allow_html=True)
|
239 |
|
240 |
-
# Show a simple
|
241 |
if dti_percent > 100:
|
242 |
st.markdown(f"""
|
243 |
<div style="padding: 10px; background-color: #FFEBEE; border-radius: 5px; margin-bottom: 15px;">
|
244 |
-
{emoji} <strong>Your monthly
|
245 |
-
<p style="margin: 5px 0 0 0; font-size: 0.9rem;">Most lenders
|
246 |
</div>
|
247 |
""", unsafe_allow_html=True)
|
248 |
else:
|
249 |
st.markdown(f"""
|
250 |
<div style="padding: 10px; background-color: #F5F5F5; border-radius: 5px; margin-bottom: 15px;">
|
251 |
-
{emoji} <strong>Your monthly
|
252 |
-
<p style="margin: 5px 0 0 0; font-size: 0.9rem;">Most lenders
|
253 |
</div>
|
254 |
""", unsafe_allow_html=True)
|
255 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
256 |
st.markdown('</div>', unsafe_allow_html=True)
|
257 |
|
258 |
# Prediction button with enhanced styling
|
@@ -275,9 +298,8 @@ with tab1:
|
|
275 |
# Convert Term from months to years
|
276 |
term_years = loan_term / 12
|
277 |
|
278 |
-
# Compute Derived Features
|
279 |
-
|
280 |
-
debt_to_income = loan_amount / total_income if total_income > 0 else 0 # Avoid divide by zero
|
281 |
credit_amount_interaction = loan_amount * credit_history_num # Interaction effect
|
282 |
income_term_ratio = total_income / term_years if term_years > 0 else 0 # Avoid divide by zero
|
283 |
|
@@ -295,8 +317,26 @@ with tab1:
|
|
295 |
input_data = preprocess_input()
|
296 |
prediction = model.predict(input_data)
|
297 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
298 |
# Show result with enhanced styling
|
299 |
-
if
|
300 |
st.markdown("""
|
301 |
<div class="result-approved">
|
302 |
<h3 style="color: #2E7D32;">✅ Loan Approved</h3>
|
@@ -304,11 +344,12 @@ with tab1:
|
|
304 |
</div>
|
305 |
""", unsafe_allow_html=True)
|
306 |
else:
|
307 |
-
st.markdown("""
|
308 |
<div class="result-rejected">
|
309 |
<h3 style="color: #C62828;">❌ Loan Not Approved</h3>
|
310 |
<p>Unfortunately, based on your current information, we cannot approve your loan application.</p>
|
311 |
-
<p>
|
|
|
312 |
</div>
|
313 |
""", unsafe_allow_html=True)
|
314 |
|
@@ -316,7 +357,7 @@ with tab2:
|
|
316 |
st.markdown("""
|
317 |
<div class="section-card">
|
318 |
<h3>About the Loan Approval System</h3>
|
319 |
-
<p>This AI-powered system uses advanced machine learning algorithms to determine loan approval eligibility.</p>
|
320 |
</div>
|
321 |
""", unsafe_allow_html=True)
|
322 |
|
@@ -327,16 +368,33 @@ with tab2:
|
|
327 |
- Credit history status
|
328 |
- Loan amount and term
|
329 |
- Income and employment status
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
330 |
""")
|
331 |
|
332 |
-
st.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
333 |
|
334 |
st.markdown('<div class="section-card">', unsafe_allow_html=True)
|
335 |
-
st.markdown("<h3>Features</h3>", unsafe_allow_html=True)
|
336 |
st.write("Our system provides:")
|
337 |
st.markdown("""
|
338 |
- Instant loan approval decisions
|
339 |
- Transparent evaluation process
|
|
|
340 |
- Secure data handling
|
341 |
""")
|
342 |
st.markdown('</div>', unsafe_allow_html=True)
|
|
|
176 |
|
177 |
total_income = applicant_income + coapplicant_income
|
178 |
|
|
|
|
|
179 |
# Calculate monthly payment (simplified calculation)
|
|
|
|
|
|
|
|
|
180 |
interest_rate = 0.05 # Assuming 5% annual interest rate
|
181 |
monthly_interest = interest_rate / 12
|
182 |
num_payments = loan_term
|
183 |
|
184 |
# Monthly payment using the loan amortization formula
|
185 |
+
if monthly_interest == 0 or num_payments == 0:
|
186 |
+
monthly_payment = 0
|
187 |
else:
|
188 |
monthly_payment = loan_amount * (monthly_interest * (1 + monthly_interest) ** num_payments) / \
|
189 |
((1 + monthly_interest) ** num_payments - 1)
|
|
|
197 |
col2.metric("Estimated Monthly Payment", f"${monthly_payment:.2f}")
|
198 |
col3.metric("Loan Term", f"{loan_term//12} years")
|
199 |
|
200 |
+
# Create DTI visualization section
|
201 |
st.markdown("<h4>Debt-to-Income Assessment</h4>", unsafe_allow_html=True)
|
202 |
|
203 |
# Cap the displayed percentage at 100% for the visual
|
|
|
231 |
</div>
|
232 |
""", unsafe_allow_html=True)
|
233 |
|
234 |
+
# Show a simple explanation of DTI with actual values
|
235 |
if dti_percent > 100:
|
236 |
st.markdown(f"""
|
237 |
<div style="padding: 10px; background-color: #FFEBEE; border-radius: 5px; margin-bottom: 15px;">
|
238 |
+
{emoji} <strong>Your monthly payment (${monthly_payment:.2f}) would be {dti_percent/100:.1f}× your monthly income (${total_income:,})</strong>
|
239 |
+
<p style="margin: 5px 0 0 0; font-size: 0.9rem;">Most lenders require this to be below 43% for approval</p>
|
240 |
</div>
|
241 |
""", unsafe_allow_html=True)
|
242 |
else:
|
243 |
st.markdown(f"""
|
244 |
<div style="padding: 10px; background-color: #F5F5F5; border-radius: 5px; margin-bottom: 15px;">
|
245 |
+
{emoji} <strong>Your monthly payment (${monthly_payment:.2f}) would be {dti_percent:.1f}% of your monthly income (${total_income:,})</strong>
|
246 |
+
<p style="margin: 5px 0 0 0; font-size: 0.9rem;">Most lenders require this to be below 43% for approval</p>
|
247 |
</div>
|
248 |
""", unsafe_allow_html=True)
|
249 |
|
250 |
+
# Add eligibility check section
|
251 |
+
st.markdown('<h4>Loan Eligibility Check</h4>', unsafe_allow_html=True)
|
252 |
+
|
253 |
+
eligibility_issues = []
|
254 |
+
|
255 |
+
# Check minimum income threshold (example: $1500/month)
|
256 |
+
if total_income < 1500:
|
257 |
+
eligibility_issues.append("⚠️ Total monthly income below minimum requirement ($1,500)")
|
258 |
+
|
259 |
+
# Check if DTI is too high (above 43% is typically problematic)
|
260 |
+
if dti_percent > 43:
|
261 |
+
eligibility_issues.append("⚠️ Debt-to-income ratio exceeds maximum threshold (43%)")
|
262 |
+
|
263 |
+
# Credit history is critical
|
264 |
+
if credit_history == 0:
|
265 |
+
eligibility_issues.append("⚠️ Existing unsettled loans may affect approval odds")
|
266 |
+
|
267 |
+
# Display eligibility issues if any
|
268 |
+
if eligibility_issues:
|
269 |
+
st.markdown('<div style="background-color:#FFF3E0;padding:10px;border-radius:5px;margin-bottom:15px;">', unsafe_allow_html=True)
|
270 |
+
st.markdown("<p><strong>Potential eligibility concerns:</strong></p>", unsafe_allow_html=True)
|
271 |
+
for issue in eligibility_issues:
|
272 |
+
st.markdown(f"<p>{issue}</p>", unsafe_allow_html=True)
|
273 |
+
st.markdown("</div>", unsafe_allow_html=True)
|
274 |
+
else:
|
275 |
+
st.markdown('<div style="background-color:#E8F5E9;padding:10px;border-radius:5px;margin-bottom:15px;">', unsafe_allow_html=True)
|
276 |
+
st.markdown("<p>✅ <strong>No obvious eligibility concerns</strong></p>", unsafe_allow_html=True)
|
277 |
+
st.markdown("</div>", unsafe_allow_html=True)
|
278 |
+
|
279 |
st.markdown('</div>', unsafe_allow_html=True)
|
280 |
|
281 |
# Prediction button with enhanced styling
|
|
|
298 |
# Convert Term from months to years
|
299 |
term_years = loan_term / 12
|
300 |
|
301 |
+
# Compute Derived Features - use the same monthly payment calculated above
|
302 |
+
debt_to_income = monthly_payment / total_income if total_income > 0 else 0
|
|
|
303 |
credit_amount_interaction = loan_amount * credit_history_num # Interaction effect
|
304 |
income_term_ratio = total_income / term_years if term_years > 0 else 0 # Avoid divide by zero
|
305 |
|
|
|
317 |
input_data = preprocess_input()
|
318 |
prediction = model.predict(input_data)
|
319 |
|
320 |
+
# Apply additional rules to override the model in certain cases
|
321 |
+
manual_rejection = False
|
322 |
+
rejection_reason = ""
|
323 |
+
|
324 |
+
# Rule-based rejections that override the model
|
325 |
+
if total_income < 1500:
|
326 |
+
manual_rejection = True
|
327 |
+
rejection_reason = "Insufficient income (below $1,500 monthly minimum)"
|
328 |
+
elif dti_percent > 50: # Very high DTI is an automatic rejection
|
329 |
+
manual_rejection = True
|
330 |
+
rejection_reason = "Debt-to-income ratio too high (exceeds 50%)"
|
331 |
+
elif credit_history == 0 and dti_percent > 35:
|
332 |
+
manual_rejection = True
|
333 |
+
rejection_reason = "Combination of unsettled loans and high debt-to-income ratio"
|
334 |
+
|
335 |
+
# Final decision combines model prediction and manual eligibility checks
|
336 |
+
final_approval = (prediction[0] == 1) and not manual_rejection
|
337 |
+
|
338 |
# Show result with enhanced styling
|
339 |
+
if final_approval:
|
340 |
st.markdown("""
|
341 |
<div class="result-approved">
|
342 |
<h3 style="color: #2E7D32;">✅ Loan Approved</h3>
|
|
|
344 |
</div>
|
345 |
""", unsafe_allow_html=True)
|
346 |
else:
|
347 |
+
st.markdown(f"""
|
348 |
<div class="result-rejected">
|
349 |
<h3 style="color: #C62828;">❌ Loan Not Approved</h3>
|
350 |
<p>Unfortunately, based on your current information, we cannot approve your loan application.</p>
|
351 |
+
<p><strong>Primary reason:</strong> {rejection_reason if manual_rejection else "Multiple factors considered by our approval algorithm"}</p>
|
352 |
+
<p>Consider improving your credit score, reducing existing debt, or applying with a co-applicant with higher income.</p>
|
353 |
</div>
|
354 |
""", unsafe_allow_html=True)
|
355 |
|
|
|
357 |
st.markdown("""
|
358 |
<div class="section-card">
|
359 |
<h3>About the Loan Approval System</h3>
|
360 |
+
<p>This AI-powered system uses advanced machine learning algorithms to determine loan approval eligibility based on multiple factors.</p>
|
361 |
</div>
|
362 |
""", unsafe_allow_html=True)
|
363 |
|
|
|
368 |
- Credit history status
|
369 |
- Loan amount and term
|
370 |
- Income and employment status
|
371 |
+
- Debt-to-income ratio
|
372 |
+
""")
|
373 |
+
|
374 |
+
st.write("""
|
375 |
+
Our decision engine combines a trained machine learning model with industry-standard lending criteria.
|
376 |
+
The system evaluates your application against patterns from thousands of previous loan applications
|
377 |
+
while also applying standard financial rules used by major lenders.
|
378 |
""")
|
379 |
|
380 |
+
st.markdown('<div class="section-card">', unsafe_allow_html=True)
|
381 |
+
st.markdown("<h3>Important Factors for Approval</h3>", unsafe_allow_html=True)
|
382 |
+
st.write("To maximize your chances of approval:")
|
383 |
+
st.markdown("""
|
384 |
+
- Maintain a debt-to-income ratio below 43%
|
385 |
+
- Have sufficient monthly income (minimum $1,500)
|
386 |
+
- Clear existing unsettled loans when possible
|
387 |
+
- Consider adding a co-applicant to strengthen your application
|
388 |
+
""")
|
389 |
+
st.markdown('</div>', unsafe_allow_html=True)
|
390 |
|
391 |
st.markdown('<div class="section-card">', unsafe_allow_html=True)
|
392 |
+
st.markdown("<h3>Key Features</h3>", unsafe_allow_html=True)
|
393 |
st.write("Our system provides:")
|
394 |
st.markdown("""
|
395 |
- Instant loan approval decisions
|
396 |
- Transparent evaluation process
|
397 |
+
- Detailed eligibility assessment
|
398 |
- Secure data handling
|
399 |
""")
|
400 |
st.markdown('</div>', unsafe_allow_html=True)
|