04 / 05 · cluster k=3
Calibrated XGBoost at AUC 0.893, after catching 5 data leaks that 20+ public notebooks missed.
Predicting default from a loan application is a classic binary classification task. Trusting the score takes three things: no leakage from the future, probabilities that mean what they say, and a model that is fair across groups. I tackled each of them on a 148,670-record Kaggle dataset.
First I found and removed 5 leakage columns that 20+ public Kaggle notebooks had missed. I imputed missing values with group medians: income by age group, property value by region, dtir1 by loan type. I handled class imbalance with scale_pos_weight, then fixed the score inflation it caused with CalibratedClassifierCV (cv=5). I compared 8 models, kept gender out of the model, and checked statistical parity and equalized odds across gender groups.
The final model is a calibrated XGBoost with 0.8928 test AUC. At a 0.25 threshold on the calibrated scale (0.40 raw), default recall is 0.73, precision 0.74 and F1 0.73. Every prediction is explained with SHAP beeswarm (global) and waterfall (single application) plots, all inside a Streamlit app.
Leakage audit (5 columns)
Group-median imputation
8-model comparison
Imbalance + calibration (cv=5)
Threshold 0.25 · bias analysis
SHAP + Streamlit
Python · pandas · NumPy · scikit-learn · XGBoost · LightGBM · CatBoost · SHAP · Streamlit · Matplotlib · Seaborn
The data comes from a single Kaggle source and hasn't been validated on a real lender's portfolio. The 0.25 threshold is a recall–precision trade-off and should be re-chosen under a different cost structure. The bias analysis covers gender only; the next step is extending it to other groups.