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)