import gradio as gr import joblib import numpy as np import pandas as pd import shap model = joblib.load("model.pkl") benchmarks = joblib.load("benchmarks.pkl") columns = joblib.load("columns.pkl") explainer = shap.TreeExplainer(model.named_steps['gbdt']) def predict(age, income, loan_amount, home_ownership, loan_intent, employment_length, credit_history_length, default_on_file): percent_income = loan_amount / (income + 1) income_stability = income * employment_length age_to_credit_history_ratio = age / (credit_history_length + 1) df = pd.DataFrame([{ "person_age": age, "person_income": income, "person_emp_length": employment_length, "loan_amnt": loan_amount, "person_home_ownership": home_ownership, "loan_intent": loan_intent, "loan_percent_income": percent_income, "cb_person_default_on_file": default_on_file, "cb_person_cred_hist_length": credit_history_length, "income_stability": income_stability, "age_to_cred_hist_ratio": age_to_credit_history_ratio }]) df = pd.get_dummies(df) df = df.reindex(columns=columns, fill_value=False) df_scaled = model.named_steps['scaler'].transform(df) shap_values = explainer.shap_values(df_scaled)[0] shap_df = pd.DataFrame({"feature": columns, "shap_value": shap_values}).sort_values("shap_value", ascending=False) # ilst of recommendations recommendations = { "loan_percent_income": f"Your loan-to-income ratio is {percent_income:.2f}, while good borrowers tend to average {benchmarks.get('loan_percent_income'):.2f}\n Consider reducing the loan amount.", "person_income": f"Your income is {income:,.0f}, while good borrowers tend to average ${benchmarks.get('person_income'):,.0f}\n A co-signer might help.", "loan_amnt": f"The loan amount of {loan_amount:,.0f} is high, while approved loan amounts tend to average {benchmarks.get('loan_amnt'):,.0f}\n Consider reducing the loan amount.", "person_emp_length": f"Your employment length of {employment_length}, which is off-norm. A \"good\" employment length tends to average around {benchmarks.get('person_emp_length')} years", "cb_person_cred_hist_length": f"Your credit history length of {credit_history_length} is off-norm. A good length can be considered to be around {benchmarks.get('cb_person_cred_hist_length')}", "income_stability": f"Income stability score is low (employment time with income taken into account), reflecting how both longer employment and higher pay can help your case.", "age_to_cred_hist_ratio": f"Credit history is short relative to age" } prob = model.named_steps['gbdt'].predict_proba(df_scaled)[0][1] prediction = "HIGH RISK" if prob > 0.5 else "LOW RISK" top_3 = shap_df[shap_df["shap_value"] > 0].head(3) # output lines = [] lines.append("=" * 50) lines.append(f"PREDICTION: {prediction}") lines.append(f"Probability: {prob:.1%}") lines.append("=" * 50) lines.append("") if (prob > 0.5): # bad lines.append("RECOMMENDATIONS:") lines.append("") if top_3.empty: lines.append("No single feature is the driver of your result") else: for feature in top_3["feature"]: if feature in recommendations: lines.append(recommendations[feature]) lines.append("") else: lines.append("No major risk factors found.\n Your profile is similar to those who get their loans paid off.") lines.append("=" * 50) return "\n".join(lines) gr.Interface(fn = predict, inputs = [ gr.Number(label = "Age"), gr.Number(label = "Income ($)"), gr.Number(label = "Loan Amount ($)"), gr.Dropdown(["RENT", "OWN", "MORTGAGE", "OTHER"], label = "Home ownership"), gr.Dropdown(["EDUCATION","MEDICAL","PERSONAL","VENTURE","HOMEIMPROVEMENT","DEBTCONSOLIDATION"], label="Loan purpose"), gr.Number(label="Employment length (years)"), gr.Number(label="Credit history length (years)"), gr.Radio(["Y","N"], label="Previous default on file") ], outputs = gr.Textbox(label="Result", lines=15), title="Credit Risk Predictor", description="Enter applicant details to predict default risk", flagging_mode="never" ).launch()