Back to discipline

Risk analytics / policy governance

Credit Policy Lab

This browser lab starts from a hash-verified Lending Club backtest and keeps offline scores separate from expected-loss math, policy thresholds, review capacity, monitoring, and the final recorded decision.

PD × LGD × EADCalibration & BrierPSI / vintage monitoringPolicy simulationDirectional SHAP reason codesParquet + DuckDB-WASM
Problem
A probability and one cutoff cannot capture loss economics, review capacity, score drift, or the human decision that sets policy.
Audience
Credit policy managers, risk analysts, and applied-ML governance teams whose job starts where the score ends.
What I built
I built the time-disciplined Lending Club training/backtest pipeline, source locks, score-to-policy contracts, expected-loss and queue engine, monitoring, audit flow, browser UI, governed fixture, and tests.
Result
The default path verifies committed offline scores, then recomputes approve/review/decline bands, swap sets, queue overflow, expected loss, calibration, vintage drift, descriptive slices, and a policy audit record.
Links

How it works

  1. 01
    Backtest

    Train, calibrate, and score disjoint chronological Lending Club windows offline.

  2. 02
    Economics

    Compute expected loss from PD, LGD, and EAD.

  3. 03
    Policy

    Apply approve, review, and decline thresholds.

  4. 04
    Review

    Enforce analyst-capacity constraints.

  5. 05
    Monitor

    Backtest vintages, PSI, slices, and audit changes.

Try it

The committed scored backtest is requested first. If its Parquet fails validation, the lab keeps the fixed-seed synthetic fallback active and shows the blocked state.
Loading the requested credit source...

Methods / Results / Real-data analysis

Loading the pipeline-backed methods report…

How this was verified

  • The default source is real: a 3,107-row compact preview spans every vintage, is generated from the exact 120,000-row backtest, and is bound to both source and preview-row SHA-256 values. An explicit complete-data action downloads and verifies scored-backtest.parquet, then queries all rows through DuckDB-WASM; failure preserves the labeled real preview and blocks full mode.
  • Real mode loads 120,000 deterministically selected applications from the 1,347,681-row UCM-curated Lending Club granting archive (Zenodo 10.5281/zenodo.11295916, CC BY 4.0, retrieved 2026-07-17); the source size, MD5, SHA-256, creators, and time cutoffs are embedded in the Parquet metadata.
  • The committed artifact contains disjoint time-ordered 72,000 / 24,000 / 24,000 train, isotonic-calibration, and later backtest rows, observed final outcomes, calibrated logistic/XGBoost scores, and top-three SHAP-derived reason codes.
  • The optional seed-2026071302 fixture contains 12,000 fictional applications and remains isolated as a reproducible fallback and test mode.
  • The inherited Streamlit/HF demo is prior work only; no original model is claimed as recovered or validated.

What this does not prove

  • Synthetic Brier, PSI, loss, and slice values are fixture results, not real performance or fairness evidence.
  • The lab does not process PII or represent regulatory compliance, deployed accuracy, or a real applicant decision.
  • LGD is a disclosed 45% assumption; legacy browser fields absent upstream use explicit unavailable sentinels, and home-ownership slices are descriptive only.
  • This granted-loan-only archive does not represent rejected applicants or identify acceptance-population policy effects; it is an offline historical backtest, not causal impact, live or production decisioning, regulatory validation, or real-world fairness evidence.