SILENT ACCURACY DEGRADATION
monitoring/drift_detector.py · LoanSense platform
B
BYTECOP
CONCEPT · BEHAVIORAL DRIFT
The analogy

A fitness app launches a calorie estimator. It was trained on six months of data from early adopters: mostly runners and gym-goers, skewing male, ages 25-35, who logged every workout. The model is very accurate on that group. In month four of launch, the app goes viral on TikTok. The new users are walkers, cyclists, dancers, and people doing 15-minute home routines. The calorie expenditure patterns for those activities look nothing like running data.

The model keeps running. It keeps returning numbers. Nobody disabled it. The numbers look plausible, because calorie counts always look like calorie counts. But the population the model was measured on has become a minority of the population it is now serving. That's behavioral drift: the model's weights didn't change, its code didn't change, but its accuracy did, because the world it's operating in changed first.

This is the failure mode that does not appear in logs. No exception is thrown. The prediction endpoint returns 200 OK every time. The only signal is that the model is gradually more wrong, and that signal arrives in user surveys, churn data, or a business metric report three quarters later. By then, the mismatch between training data and serving data is large enough that retraining from scratch is faster than patching.

Behavioral drift happens in two shapes. The first: the mean of a feature shifts. Average income in the user base rises. Average tenure at a job falls. The model was calibrated for one mean; it now sees another. The second, subtler shape: the variance changes. The distribution narrows (everyone submits from mobile now, not desktop, removing a whole dimension of behavioral variance) or widens (a feature that used to be predictable now has huge spread). A model that checked only means would miss both shapes of variance drift entirely.

# what you see in logs: nothing
GET /predict HTTP/1.1 → 200 OK  {"score": 0.72}
# what is actually happening
accuracy_on_launch_day  = 0.91
accuracy_today          = 0.63  # measured by nobody
Zero-knowledge primer: how distribution drift works

A model learns relationships between input features and outputs by looking at a training dataset. If the distribution of inputs at serving time differs from training time, the learned relationships may no longer apply. The standard measure is PSI (Population Stability Index): if PSI is below 0.10 the distribution is stable, between 0.10 and 0.25 warrants monitoring, and above 0.25 is considered significant drift requiring action.

TRAIN
Model learns from data collected in a specific time window.
DEPLOY
Model scores live traffic. Accuracy is measured at launch.
DRIFT
World changes. Input distribution shifts away from training data.
SILENT
No alert fires. Model still returns predictions. Accuracy degrades quietly.
DETECT
PSI monitor catches the divergence. Retrain or rollback.
Concept · going deeper

Behavioral Drift

A model that was correct on launch day can become wrong over time without a single line of code changing. The cause is not a bug in the usual sense: it is a mismatch between the world the model was trained on and the world it is currently operating in. This mismatch grows silently, because models do not know what they do not know.

The model's uncertainty doesn't increase as distribution drifts. This is the counterintuitive part. A model trained on one population and then evaluated on a shifted population does not become less confident. It returns the same confidence intervals, the same score ranges, the same output format. The score of 0.72 looks exactly as authoritative on day 1 as it does on day 400. The degradation is invisible to the model; it has to be measured externally.

Mean shift and variance shift are two different problems. If the average loan amount in your training data was $285,000 and it is now $340,000, that is a mean shift: the center of the distribution moved. A good drift detector catches it by normalizing the gap against the training standard deviation. But if the average loan amount stayed the same and the spread doubled (some users borrowing $50,000, some borrowing $800,000, rather than most borrowing $250-320,000), that is variance shift: the shape of the distribution changed even though the mean did not. A detector that only checks means misses this entirely, and variance shift can degrade model accuracy just as badly as mean shift.

Without a drift detector, a model runs indefinitely on stale assumptions. In the absence of monitoring, the only signals are business metrics: increasing default rates, decreasing satisfaction scores, rising manual-review queues. Those signals arrive weeks or months late. A PSI monitor with proper normalization and variance checking can catch the divergence at the data level, before it manifests as a business outcome.

The rule: a model correct at launch degrades silently as the input distribution shifts. Drift detection requires normalized mean checks and variance checks, both, to catch what the model cannot see about itself.
Behavioral Drift: training distribution vs drifted serving distribution, mean and variance shifts Mean shift training mean=285k serving mean=340k +$55k shift $150k $500k loan amount Variance shift (same mean) training std=45 serving std=92 credit score (same mean, 2x std)
training distribution  ·  serving distribution at time of drift  ·  shift magnitude. Left: mean moved. Right: mean stayed, variance doubled. Both degrade accuracy.

Don't take our word for it. Watch a real distribution drift across 36 months of serving data.

Distribution Drift Timeline

Drag the timeline forward from Jan 2022 (near training cutoff) to Dec 2024. Watch how the serving distribution diverges from training, how the PSI score climbs, and how model accuracy degrades without any code change.

Jan 2022 Jan 2022 Dec 2024
training cutoff 12 months 24 months 36 months
PSI SCORE (population stability index)
0.00
stable — no action needed
MODEL ACCURACY (on current serving population)
91%
measured at launch: 91%
TRAINING DISTRIBUTION (fixed, Jul 2021)
SERVING DISTRIBUTION (Jan 2022)

Drag the timeline to at least month 28 to see PSI exceed the critical threshold of 0.25 and model accuracy fall below 70%.

monitoringdrift_detector.py
drift_detector.py
tap a line to flag the bug

Find the line where drift detection goes wrong, then fix the function.

Hints