ML Systems Lab Open interactive version →
Intermediate 20 min read data driftPSIKS testdistribution monitoring

Data Drift Detection

PSI, KS test, chi-squared, Jensen-Shannon divergence, choosing thresholds

A loan model goes live in January. By March a new kind of applicant is showing up — recent graduates, a newly opened geographic market — and their median income has moved from about 55K to 70K dollars. The model still runs, still returns predictions at the same speed, still fires no alerts. But it is quietly making worse decisions, because it was tuned for a population that no longer shows up at the same rate. By the time a stakeholder notices the approval or default rate has drifted, it's July — and the root cause is six months old. This is silent model decay, and it is the *default* outcome when nobody is monitoring.


The idea: watch the inputs, don't wait for the labels

Instead of waiting for outcomes to confirm the damage, you compare each input feature's *current* distribution against its *training* distribution and measure how far apart they've moved. The question becomes concrete: how much has the income distribution shifted, and is that shift big enough to matter?


PSI: the metric the lending world built for exactly this

Population Stability Index sums, across bins of a feature, how much probability mass moved:

$PSI = \sum (p_{train} - p_{new}) ln(p_{train}/p_{new})$

Below 0.1 the population is stable; 0.1–0.2 is mild drift worth a look; above 0.2 is real drift that needs action. For income moving from 55K to 70K, here's the arithmetic behind that claim: split training income into 5 equal-frequency bins (<35K, 35–50K, 50–65K, 65–80K, >80K), each holding 20% of the training population by construction. After the shift, those same bins hold roughly 8%, 12%, 18%, 32%, and 30% of the new population — mass moves out of the bottom bins into the top two. Summing $(p_{train}-p_{new})ln(p_{train}/p_{new})$ bin by bin gives 0.110 + 0.041 + 0.002 + 0.056 + 0.041 ≈ 0.25, above the 0.2 action threshold — an actionable signal *months* before any label confirms the harm.


Other tests for other shapes of data

For continuous features, the Kolmogorov-Smirnov test takes the largest gap between two cumulative distributions:

$D = max|F_{train}(x) - F_{new}(x)|$

It's distribution-free and notices shifts anywhere, not just in the mean. The trap: with a million daily requests, D = 0.015 will be "statistically significant" (p < 0.001) yet operationally meaningless — so pair it with a *practical* floor like D > 0.05. For categorical features, chi-squared checks whether category frequencies still match training: $chi^2 = sum rac{(O_i - E_i)^2}{E_i}$, comparing observed category counts $O_i$ against the counts $E_i$ expected under the training distribution. And when you want one bounded, uniformly-thresholdable number across very different features, Jensen-Shannon divergence — computed with log base 2, unlike the natural-log PSI and KS above — sits neatly in [0, 1].


One caution on what an alert means. Statistical significance is not business significance. A drift alert means *investigate,* not *retrain.* Sometimes a feature moves a lot and the model stays accurate because the learned relationship still holds; other times a subtle shift in one important feature wrecks accuracy while 49 others look fine. So you run both: drift detection as the early warning that *something* changed, and performance monitoring on delayed labels as the confirmation that it *matters.* The alert says "look here." The labels tell you if it's a real problem.

Key points

Takeaway

Drift detection provides the early warning that silent model decay is accumulating. PSI above 0.2 on a high-importance feature is actionable even before labels arrive. But a drift alert triggers investigation, not automatic retraining — the question that matters is whether the drift actually degrades performance, which only labels can confirm.

Recap

Check your understanding

Q1. You have 1M daily serving requests and are monitoring feature drift. The KS test shows p<0.001 for "age" feature with KS statistic D=0.015. Should you alert?

Q2. Which two statements correctly explain why PSI uses 10 equal-frequency bins from the training distribution rather than equal-width bins?

Q3. A loan model's prediction score distribution shifts from mean 0.35 to mean 0.28 over two months. What is the fastest path to the root-cause feature?

Try it interactively

ML Systems Lab is a free interview-prep platform for ML engineers — work through the full interactive module, quizzes, and drills.

Open ML Systems Lab →