UAgarwal7's picture
Update app.py
2fe1128 verified
Raw
History Blame Contribute Delete
4.38 kB
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()