© Thinh Ngo, 2026
← All work
05

Microloan Default

A credit-risk model that flags likely microloan defaulters before disbursement — then turns the maths into one screening rule a credit team can actually use.

Course
RMIT — ECON1612 Big Data, Machine Learning and Society
Type
Individual (Assessment 2)
Focus
Credit-risk classification, imbalanced data
Best model
Logistic Regression · test ROC-AUC 0.93
Stack
Python, scikit-learn, SHAP
Output
Model + a 7.5x-risk screening rule

TL;DR

An end-to-end credit-risk pipeline on 6,000 Vietnamese microloan applications. I built it leakage-free — a time-based out-of-time split, every transform fit on train only — compared three models, and read the drivers three ways. The useful part isn’t the score: a simple rule isolates 8.4% of applicants whose default rate is 54.6%, against 7.3% for everyone else.

The problem

A lender needs to catch high-risk applicants before the money goes out. Both mistakes cost — approving a defaulter loses the principal, rejecting a good borrower loses a customer. The target is default within 90 days, and only 10.9% of applicants default, so the class is heavily imbalanced. That imbalance shaped every decision.

What I built

I split train and test by application date, not randomly, so the model is judged on predicting future borrowers from past ones — and I fit every transform on the training window only, so nothing leaks backward. Then the unglamorous work that actually decides quality: missingness flags, sentinel-code detection (the 999 placeholder), logical-consistency checks, and IQR winsorization instead of dropping rows.

What the model found

Across Logistic Regression, HistGradientBoosting, and Random Forest, Logistic Regression won on the out-of-time test set (ROC-AUC 0.93) and stayed interpretable. I read importance three ways — coefficients, permutation, SHAP — so the drivers agreed rather than resting on one method. Savings balance dominated; unemployed applicants defaulted at 50%, against 6% for the formally employed. I tuned the threshold toward recall, since a missed defaulter usually costs more than a second look at a good one.

The decision, not just the score

A model is only useful if someone can act on it — so I derived a plain screening rule (low savings, high debt-to-income, high loan-to-income) that flags 8.4% of applicants whose actual default rate is 54.6%, against 7.3% for the rest. That’s a 7.5x concentration of risk in a small, explainable segment a credit officer can apply without running a model live.

Honest framing

This is a synthetic teaching dataset, and one feature — savings balance — carries most of the signal, which inflates the AUC beyond what real lending data would give. On real data I’d expect lower scores, and I’d guard against any single feature dominating. The value here is the method, not the number.

Artifacts