SAARTHI β MSME Default Prediction
Credit default-prediction models trained entirely on public datasets for IDBI Innovate 2026 (Track 04, Default Prediction Model). No bank data was used at any point.
The headline design choice: SAARTHI ships pre-trained and then fine-tunes on a lender's own book, rather than cold-starting on every upload.
Methodology β why these numbers are trustworthy
Every metric below comes from a strict three-way split:
| Fold | Share | Used for |
|---|---|---|
| fit | 60% | training the boosters |
| calibrate | 15% | fitting the isotonic calibrator only |
| test | 25% | never seen by either β all reported metrics |
This matters: a common shortcut fits the probability calibrator and then measures calibration error on that same fold, which drives ECE artificially toward zero. Here the calibrator never sees the test fold, so the reported ECE is a real out-of-sample calibration estimate.
Per-dataset specialist models
Full native feature set per corpus. Ensemble of LightGBM + XGBoost + CatBoost, isotonic-calibrated.
| Dataset | n | Default rate | Test AUC | PR-AUC | ECE | Published reference |
|---|---|---|---|---|---|---|
sba |
897,167 | 0.1756 | 0.9800 | 0.9126 | 0.0015 | ~0.95 (literature) |
lending_club |
1,369,566 | 0.2124 | 0.7263 | 0.4104 | 0.0024 | ~0.70-0.73 (leakage-free) |
home_credit |
307,511 | 0.0807 | 0.7632 | 0.2449 | 0.0011 | 0.805 (Kaggle winner) |
gmsc |
150,000 | 0.0668 | 0.8522 | 0.3629 | 0.0041 | ~0.87 (Kaggle winner) |
taiwan |
30,000 | 0.2212 | 0.7698 | 0.5243 | 0.0074 | ~0.78 (literature) |
german |
1,000 | 0.3000 | 0.7668 | 0.5505 | 0.0680 | ~0.79 (literature) |
berka |
682 | 0.1111 | 0.8558 | 0.5725 | 0.0295 | n/a |
amex |
120,000 | 0.2598 | 0.9580 | 0.8858 | 0.0050 | ~0.96 AUC (winners; the 0.80 headline is a different metric) |
| hc2024 | β | β | failed | β | β | ~0.86 (Kaggle winner) |
sbaβ US Small Business Administration loans - closest public analogue to MSME lendinglending_clubβ 2007-2018 consumer loans, charge-off labelhome_creditβ Home Credit 2018 application + bureau aggregatesgmscβ Give Me Some Credit, 90+ DPD within 2 yearstaiwanβ Taiwan credit-card default, 6-month repayment panelgermanβ UCI German Credit, 1000 rowsberkaβ PKDD'99 Czech bank, pre-origination transaction aggregatesamexβ American Express monthly statement panelhc2024β Home Credit 2024 model-stability competition
Pooled global model (ships with the app)
Trained across corpora in a shared 15-field canonical credit vocabulary so it can score any loan book that maps onto it.
- Test AUC: 0.8605
- PR-AUC: 0.5795
- ECE: 0.0018 Β· Brier: 0.0868
- Test rows: 270,421
- Corpora pooled: sba, lending_club, home_credit, gmsc, taiwan, german, berka
Leave-one-dataset-out transfer β a negative result
Train on every corpus except one, then score the held-out corpus cold. This is the honest proxy for "will it transfer to a book it has never seen?" β the question that actually matters for deployment.
It does not transfer. Most hold-outs land at or below chance, which means the pooled model is not merely uninformative on an unseen corpus, it is anti-predictive: the featureβoutcome relationships invert across lending domains.
| Held-out corpus | n | Raw pooling | Rank-normalised |
|---|---|---|---|
berka |
682 | 0.4612 | 0.5155 |
german |
1,000 | 0.4646 | 0.4022 |
gmsc |
150,000 | 0.7786 | 0.7711 |
home_credit |
300,000 | 0.4991 | 0.5785 |
lending_club |
300,000 | 0.5228 | 0.5399 |
sba |
300,000 | 0.4103 | 0.2574 |
taiwan |
30,000 | 0.7038 | 0.6989 |
| mean | 0.5486 | 0.5377 |
Normalisation did NOT rescue it
The obvious hypothesis is scale mismatch β these corpora are denominated in USD, DM, NT$ and CZK, so a "loan amount" of 50,000 means different things in each. Converting every numeric feature to its within-corpus percentile rank tests that hypothesis directly, and it fails: mean transfer AUC moved 0.5486 β 0.5377, i.e. no better. SBA in particular degrades from 0.4103 to 0.2574.
The mechanism is therefore relational inversion, not scale. SBA is small-business lending, where a longer term and a larger SBA-guaranteed principal typically indicate a better-vetted, collateral-backed loan β the opposite of the consumer-credit corpora that dominate the pooled training set. Rank-normalising preserves that inverted ordering perfectly, which is why it cannot help.
Practical consequence: a single pooled "foundation" model for credit risk is not supported by this evidence. Domain-matched training plus fine-tuning on the lender's own book is the defensible architecture, which is what SAARTHI does.
Ablation β does transaction-as-language earn its place?
A CoLES-style contrastive encoder (GRU + InfoNCE over disjoint sub-sequence views) was pre-trained on unlabelled transaction streams, then its 256-d embedding was tested against the tabular features.
| Corpus | Tabular | Sequence only | Tabular + sequence | Lift |
|---|---|---|---|---|
berka |
0.8575 | 0.8097 | 0.8842 | +0.0267 |
amex |
0.9590 | 0.9156 | 0.9585 | -0.0006 |
When the sequence encoder earns its place: on Berka (16 tabular features, raw bank transactions) it adds +0.027 AUC. On Amex (941 hand-engineered aggregates over the same statement data) it adds nothing β the aggregates already capture what the encoder learns. The embedding substitutes for feature engineering rather than adding to it; it is most valuable exactly where a lender has raw transaction streams but few curated fields, which is the realistic MSME case.
Note also that on Amex the 256-d embedding alone reaches 0.9156 AUC with no hand-engineered features at all, versus 0.9590 for 941 engineered columns.
Linear probe on frozen embeddings
Logistic regression on the frozen encoder output β measures how much default signal the unsupervised embedding captured on its own.
amex: AUC 0.8717 (n=60,000)berka: AUC 0.7783 (n=682)
Known limitations
- Berka aggregates only pre-origination transactions. Using the full history yields AUC 1.0000 because 71% of an account's transactions occur after the loan date and encode the repayment behaviour that defines the label. The leaked figure is not reported here.
- Amex and Home Credit are Kaggle-competition datasets; they are used for research validation. The shipped global model is trained on the permissively-licensed core corpora.
- The pooled model uses a deliberately small shared vocabulary, so its AUC is lower than the specialists by construction. Its purpose is transfer, not peak in-corpus accuracy.
- No Indian MSME data was available; GST-behavioural fields are simulated against the schema IDBI published, not learned from real filings.
Files
| File | What it is |
|---|---|
global_canonical.joblib |
pooled global model + isotonic calibrator |
specialist_<corpus>.joblib |
per-corpus specialist ensembles |
coles.pt |
transaction-sequence encoder checkpoint |
metrics.json |
every number above, machine-readable |
ablation_sequence.json |
sequence-embedding ablation |
Usage
import joblib, pandas as pd
b = joblib.load('global_canonical.joblib')
X = df.reindex(columns=b['features']) # canonical vocabulary
raw = sum(m.predict_proba(X)[:, 1] for m in b['members'].values()) / len(b['members'])
pd_calibrated = b['calibrator'].predict(raw) # real probability of default
Generated 2026-08-31 from metrics files β numbers are not hand-entered.