Lensa ML
Lensa ML

Data Drift & Model Monitoring

Step 1 of 6: Training vs Live Data

The world the model meets is not the one it learned

Shift in the live feature's mean+1.0
training sample (1,000)live sample (1,000, simulated)-4-2024feature value · shaded band: training 1st to 99th percentile
Training mean
−0.01
Live mean
+1.04
Histogram overlap
60%
Live outside band
11.2%

At a shift of +1.0, only 60% of the mass overlaps and 11.2% of live inputs land where the model saw almost no training examples.

Drag Shift in the live feature's mean to +1.0 and read the overlap and the share outside the band. For two unit normals a distance δ apart, the overlap is 2Φ(−δ/2), so a shift of one standard deviation leaves about 62% shared mass. The share above the training 99th percentile (2.33) grows to about 9%. In practice the shift rarely comes from one clean cause: seasonality, a new user segment, a changed sensor, or a logging change upstream all show up as a moved histogram.

Step 2 of 6: Three Kinds of Drift

Covariate, label and concept shift

Drift strength0.80
class 1class 0misclassifiedtrue rulemodelpredict class 1 abovex₁ →x₂ ↑
Training accuracy
91.9%
Live accuracy
72.5%
Class 1 share
39%
Mean of x₁
+1.56

Inputs moved right (mean x₁ +1.56). The true rule is unchanged, but the straight line only matched it near the training data, so accuracy falls to 72.5%.

Click each drift type, then drag Drift strength from 0 to 1. The joint distribution factors two ways, P(x, y) = P(y|x)·P(x) = P(x|y)·P(y), and each kind of drift changes one factor while holding the other. Label shift has a known fix: reweight by P_live(y) ÷ P_train(y), which can be estimated from the model's own confusion matrix without live labels. Concept drift has no such fix, because the old labels are now wrong. It can be sudden, gradual, or recurring, as with seasonal fraud patterns.

Step 3 of 6: The KS Test

Largest gap between two empirical CDFs

Shift in the live mean+0.20
Sample size (each)200
training ECDFlive ECDF (simulated)D, the max gap00.51-3-2-101234D = 0.115feature value · y axis: fraction of the sample at or below x
KS statistic D
0.115
p-value
0.13
Critical D at α = 0.05
0.136
Verdict
No drift

D = 0.115 is within sampling noise: two samples of 200 from one distribution often differ by this much (p = 0.13).

Drag Sample size up to 2,000 and slowly move Shift in the live mean to find the smallest shift that gets flagged. The statistic is D = max over x of |F_train(x) − F_live(x)|. At α = 0.05 the critical value is 1.358·√((n + m) ÷ (n·m)), about 0.061 for two samples of 1,000. The test is distribution-free and needs no binning, but it handles one feature at a time and assumes continuous values. For categorical features, a chi-square test on the category counts plays the same role.

Step 4 of 6: Population Stability Index

Binned drift score with rule-of-thumb bands

Shift in the live mean+0.30
Live spread1.00×
expected e (training)actual a (live, simulated)0.10.212345678910bins = training deciles · red: per-bin term (a − e)·ln(a/e)largest term: bin 10, 0.032
PSI
0.098
KL(a‖e)
0.049
KL(e‖a)
0.049
Band (convention)
Stable

PSI = 0.098, under the 0.1 line usually read as stable. Every bin holds close to its expected 10%.

Drag Shift in the live mean to 0.5 with Live spread at 1.00, then reset the shift and stretch the spread instead. PSI equals KL(a‖e) + KL(e‖a), the symmetric Jeffreys divergence, which the two KL cards add up to. For two normals a shift of δ standard deviations gives a Jeffreys divergence of δ², so 0.5 lands near 0.25; ten bins report slightly less. The index comes from credit scoring, where the 0.1 and 0.25 bands became a habit rather than a derived threshold. Empty bins need a small floor, or ln(a/e) is infinite.

Step 5 of 6: Alerting Without Noise

Many features, many checks, many false alarms

Features monitored200
Significance level α0.05
Checks per day24
One check of 200 features, none of which drifted (simulated p-values)9 false alarms at threshold 0.05
Expected per check
10.0
P(any false alarm)
100.0%
Expected per day
240
Alarms this check
9

200 stable features each tested at α = 0.05 give 10.0 false alarms per check, and 24 checks a day give about 240. An alert that fires this often gets ignored.

Set Features monitored to 200 and α to 0.05, then click New check a few times. The chance of at least one false alarm is 1 − (1 − α)^k, which is 99.996% here. Bonferroni keeps that family-wise rate under α but loses power as k grows. The Benjamini–Hochberg procedure controls the expected share of false alarms among the alerts instead, which suits large feature sets. Many teams also alert only when a feature stays drifted for several windows, or when its effect size, such as PSI, passes a set level.

Step 6 of 6: Responding to Drift

Proxies, label delay, and the fix

Label delay10 days
Simulated monitoring, day 0 of 59Input PSI (no labels needed)Accuracy (needs labels)00.250.560%80%100%0204059
Day
0
PSI today
0.03
PSI alert
none yet
Accuracy alert
none yet

Day 0: PSI stays near 0.04 and accuracy near 91%. Accuracy is only known up to day 0, 10 days behind.

Pick an event, set Label delay, and press Play or Step through the 60 days. Real label delays are often much longer: a chargeback can take weeks to confirm fraud, and a loan default can take months. Until labels arrive, teams watch proxies such as input drift, the predicted positive rate, and the model's average confidence. A retrained model is usually run in shadow mode or against the current model on recent data before it takes traffic, so that a fix for drift does not ship a new bug.

What is data drift in machine learning?

Data drift is a change in the data a deployed model receives compared with the data it was trained on. A model learns patterns from one sample of the world, and when the inputs, the class mix, or the link between inputs and labels moves, its predictions can get worse without any error being raised. Model monitoring is the practice of measuring that change in production and acting on it.

Every production model needs monitoring. Fraud models face attackers who change tactics, demand forecasts meet new seasons and products, credit models see a different economy, and a broken upstream pipeline can feed a model values in the wrong units overnight. Teams track input statistics such as the KS test and the population stability index, watch the prediction distribution, and compare accuracy once labels arrive, then decide whether to retrain, recalibrate, or roll back.

Key ideas

  • Data drift is any change between the training distribution and the data a model sees in production.
  • Covariate shift changes P(x), label shift changes P(y), and concept drift changes P(y|x), the rule itself.
  • Concept drift breaks a model even when the inputs look unchanged, so input monitoring alone cannot catch it.
  • The KS test measures the largest gap between two empirical CDFs and flags even tiny shifts at large sample sizes.
  • PSI sums (a − e)·ln(a/e) over bins and equals the symmetric KL divergence between the binned distributions.
  • Testing many features on every check produces false alarms unless the threshold is corrected, for example with Bonferroni.

Short takes on this topic

Common questions

How often should a model be retrained?

There is no fixed schedule that suits every model. Some teams retrain on a calendar, such as weekly or monthly, and others retrain when monitoring shows drift or a drop in accuracy. Calendar retraining is simple but can miss sudden changes, while trigger-based retraining depends on the alerts being trustworthy. Many systems combine both.

Should I use the KS test, PSI, or another drift metric?

The KS test gives a p-value and needs no bins, so it suits continuous features, but with large samples it flags shifts too small to matter. PSI and other distances such as Wasserstein or Jensen-Shannon give an effect size, which is easier to threshold. Chi-square tests cover categorical features. Many teams report one test and one distance for each feature.

What is training-serving skew?

Training-serving skew is a difference between the features computed for training and the features computed at serving time for the same example. It usually comes from separate code paths, such as a batch job and an online service that round, join, or fill missing values differently. It looks like drift on day one of deployment, and the fix is in the pipeline rather than in retraining.

How do you detect drift in images, text, or embeddings?

Raw pixels and tokens are too high-dimensional for per-feature tests. A common approach is to reduce each input to a few numbers, such as the model's own softmax outputs or a low-dimensional projection of embeddings, and test those. Rabanser et al. found that tests on the outputs of a trained classifier detect many kinds of shift well. A domain classifier, trained to tell training inputs from live inputs, is another option: if it does better than chance, the distributions differ.

Related explainers

References

  1. Rabanser, Günnemann & Lipton (2019), "Failing Loudly: An Empirical Study of Methods for Detecting Dataset Shift"
  2. Gama et al. (2014), "A Survey on Concept Drift Adaptation", ACM Computing Surveys
  3. Lipton, Wang & Smola (2018), "Detecting and Correcting for Label Shift with Black Box Predictors"

Last updated