Spaces:
Sleeping
Sleeping
| 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() |