Evaluation Leakage and Validation Hygiene
Why your AUC is 0.99 in the lab and 0.6 in production
Leakage makes evaluation numbers lie: the test set echoes the training signal. Target leakage, row leakage and preprocessing leakage inflate scores that collapse in production. Clean validation is a discipline, not a setting.
What you will learn
- Recognize the three leakage types: target, row, and preprocessing
- Keep preprocessing inside cross-validation folds
- Audit a pipeline for contamination before trusting any number
What is this?
Leakage is any path that lets the model (or its evaluation) see information it shouldn't at prediction time. Target leakage hides the answer in a feature (e.g., an 'is_refund' flag predicting churn); row leakage duplicates or co-splits records that came from the same entity; preprocessing leakage fits scalers/encoders/imputers on the whole dataset before splitting. All three inflate evaluation and collapse on genuinely unseen data.
Why do you need it?
- Leakage is the #1 cause of 'great offline, dead in prod' ML failures.
- It is silent — the code 'works', the metrics look excellent, no error is raised.
- Fixing leaked metrics retroactively shakes the confidence of every downstream decision made on them.
- Prevention is cheap once you know the three patterns; debugging contaminated pipelines is expensive.
Mental model
An exam with the answer key photocopied into the study guide
A leaked model
Students (the model) ace the exam (test set) because the answers were visible during study, and nobody learns the material — exactly what happens when a pipeline leaks future or label information.
How it works
- Target leakage: a feature that is only known after the label occurs (a duplicate/derivative of y) sneaks into training.
- Row leakage: group-corrrelated rows (same user, same image) are split across train and test, so the model 'recognizes the person'.
- Preprocessing leakage: fit_transform on the full dataset (scaler, encoder, imputer, target encoder) bakes test statistics into training.
- The leaking fitter runs before the split in a pipeline, so even correct CV code evaluates on contaminated folds.
- Symptoms: absurd AUC (>0.98) on hard problems, instant test-set overfitting, and monotonic score gaps train-vs-prod.
Three leakage channels all feed evaluation, not just training.
In production
- A recommendation team splits by user ID so the same user's actions never straddle train and test.
- A forecasting team uses only past data for training and strictly future data for validation — any lag feature is shifted correctly.
- A feature store ships with per-row 'as-of' timestamps so features are joined at prediction time, not at training time.
Best practices
- Define the 'prediction time view' of every feature — what was knowable at that instant — and build features accordingly.
- Split groups (user, item, session) rather than raw rows when entities repeat.
- Put ALL preprocessing inside a single Pipeline whose fit happens per-fold.
- Audit: sample a few features that look predictive and check 'could I know this at inference?'
Common mistakes
- Calling train_test_split after StandardScaler fit_transform on the whole set — scaler leaks set statistics.
- Adding 'days_since_last_purchase' computed with the target date rather than the prediction time.
- Deduplicating images/rows after splitting, so duplicates cross the boundary.
- Using validation metrics to pick the final model, then 'confirming' on validation because the test set was consumed.
Common issues
AUC 0.99 in CV, 0.65 in A/B testLeakage somewhere in the pipeline (preprocessing, target copies, group split)
Audit each preprocessing step for fit-before-split and each feature for knowability at prediction time.
Model 'predicts the future' — high score on next week despite no signalLag features shifted incorrectly or target used at feature build
Rebuild features as-of each prediction timestamp and re-split strictly by time.
Debugging tips
- If any single feature has an absurd importance/permutation spike, test it for label resemblance.
- Check for duplicate row hashes across the split boundary.
- Fit the pipeline on train only, then transform test — compare metrics to the 'leaky' run.
- Add a leakage probe: a dummy feature equal to the label (should spike) confirms your audit works, then remove it.
Interview checkpoint
Quick quiz
Which is the strongest early warning sign of leakage?
Fitting StandardScaler once on the full dataset, then splitting, is safe.