Data Leakage in Machine Learning: The Shortcut That Corrupts Evaluation
You train a model. The validation score comes back at 0.98. You feel like a genius. Then the model goes into the real world and performs like a coin flip.

Key topics
You train a model. The validation score comes back at 0.98. You feel like a genius. Then the model goes into the real world and performs like a coin flip.
That gap is the classic signature of data leakage. The score wasn't lying about what the model did on your validation data—it was lying about what the model actually learned. Somewhere between your raw data and your trained model, information crossed a line it was never supposed to cross.
The Score That Lies
Here's the scene. You train a classifier, see a near-perfect validation score, and assume you've won. You haven't. You've built a model that cheated on the exam.
Data leakage happens when information from outside the training set reaches the model during training. The model isn't learning general patterns. It's memorizing answers it was never supposed to see. The validation score looks fantastic because the model has effectively already seen the data it's being evaluated on—or something close enough to it.
The core mental model you need is the evaluation boundary. This is the line between what the model is allowed to see while being built and what it must never touch until the final evaluation. The test set represents the future. It's the data your model will encounter when it's deployed, making predictions on examples that didn't exist when you trained it.
Leakage is any shortcut that lets information cross that boundary early. It corrupts your evaluation, inflates your scores, and produces a model that fails in production. The model doesn't generalize. It memorizes.
Knowledge check
Check your understanding
Answer this question before you continue.
Why Leakage Inflates Your Scores
Think about what a model is supposed to do. It learns patterns from training data, then applies those patterns to new, unseen data. That's generalization.
Leakage breaks this process. When the model sees information that resembles or contains the answer, it takes the easy path. It memorizes patterns instead of learning rules. On the data it has effectively seen, it looks brilliant. On genuinely new data, it collapses.
Here's an analogy that captures it: imagine a student who finds the answer key before the exam. They ace the test. But they haven't learned anything. Give them a different exam on the same material, and they fail. The score was real—it just measured the wrong thing.
One honest nuance: leakage doesn't always inflate scores. In some cases, leaked information introduces noise that deflates performance. But the more common and more dangerous failure is the inflated score, because it sends you into production with false confidence.
The problem isn't the model. The model is doing exactly what you asked. The problem is the evaluation. The score no longer measures what you think it measures.
The Evaluation Boundary: Training, Validation, and Test
Before we go further, let's be precise about the boundary. It's not just "training versus test." A typical workflow has three roles:
- Training data fits the model's parameters.
- Validation data (or cross-validation folds) guides your choices: which features to keep, which hyperparameters to try, which model to select.
- Test data estimates how the finished workflow will perform on genuinely new data. You use it once, at the end.
Leakage occurs when information from the held-out portion enters the fitting or preprocessing for the portion being evaluated. If you fit a scaler on your full dataset before splitting, the training rows have been shaped by test-row statistics. If you train on rows that are near-duplicates of your validation rows, the validation score measures memory, not generalization.
One distinction matters here: using validation results to make model choices is expected. That's what validation is for. Leakage is different—it's when information from the evaluated rows sneaks into the model-building process itself.
Knowledge check
Check your understanding
Answer this question before you continue.
Feature Leakage: Columns That Carry the Answer
Feature leakage is the most common and often the most subtle form. A column in your dataset contains the answer, a proxy for the answer, or information that wouldn't be available when you actually make a prediction.
Some concrete data leakage examples:
- Predicting yearly salary with a
monthly_salarycolumn included. - Predicting whether a flight will be late with a
minutes_latecolumn. - Predicting fraud with a
flagged_after_investigationcolumn.
These features are anachronisms. They wouldn't exist at the moment of prediction. When you're building a model to predict whether a transaction is fraudulent, you don't yet know whether it will be flagged. That flag is the answer, wearing a disguise.
The audit rule is simple: for every column in your dataset, ask whether it would be available at the moment you make a prediction. If the answer is no, drop it. This includes identifiers like customer IDs or row numbers. They look harmless, but models can exploit them as leaky features.
This is where the feature-engineering rule becomes critical: reject features that would be unavailable or contaminated at prediction time. A feature that looks incredibly predictive but wouldn't exist in production isn't a feature. It's a leak.
Knowledge check
Check your understanding
Answer this question before you continue.
Preprocessing Leakage: Fitting Before the Split
This is the mistake I see beginners make most often. They load their data, scale it, impute missing values, and then split into training and test sets. It feels like the natural order: prepare the data, then build the model.
But consider what happens when you fit a scaler on the full dataset. You compute the mean and standard deviation using both training and test rows. Those statistics carry information about the test set. When you then transform the training data with that scaler, the training data has been shaped by test-set information.
The key distinction is fit versus transform. Some preprocessing steps are data-independent—they don't learn anything from the rows they touch. But most useful preprocessing learns from data:
- Scaling learns the mean and standard deviation.
- Imputation learns the median or most frequent value.
- Encoding learns the category set.
- Feature selection learns which columns matter.
Any learned transformation used in evaluation must be fitted without the evaluated rows. That's the real rule. The concern isn't the syntax order alone—it's whether the transformation learned from information in the rows being evaluated.
The structural fix is a scikit-learn pipeline. Pipelines force preprocessing to happen inside cross-validation folds, so each fold's preprocessing is fitted only on that fold's training portion. Pipelines make the correct order structural rather than a discipline you have to remember.
Knowledge check
Check your understanding
Answer this question before you continue.
Training-Example Leakage: Rows That Cross the Line
The second leakage family comes from the rows themselves. The split between training and test data is supposed to be clean. But several common practices blur it.
Duplicate rows. If identical or near-identical rows appear in both training and test sets, the test set becomes artificially easy. The model has already seen those examples. This often happens with oversampling techniques that duplicate rows to balance classes.
Resampling before splitting. Applying SMOTE or other oversampling methods before the train/test split pads your dataset with synthetic copies. Those copies can end up on both sides of the boundary. The model recognizes them during evaluation, and your score inflates.
Time leakage. For time-series data, a random split lets future observations leak into training. The model learns patterns from data that, in reality, wouldn't exist yet. Chronological splits are required: train on the past, test on the future.
The rule for this family: split first, then resample or augment only within the training fold. Never before.
How to Diagnose Leakage in Your Own Workflow
How do you know if your model is leaking? Start with the telltale signs:
- Suspiciously high accuracy. If your model performs at 0.99 on a problem that should be hard, something is probably wrong.
- A feature that seems too predictive. If one column dominates feature importance and it looks like a proxy for the target, investigate.
- Performance that collapses in production. If the model looked great in evaluation but fails on real data, leakage should be your first suspect.
One important distinction: a large gap between training and validation performance is primarily a sign of overfitting, not leakage. Overfitting means the model memorized noise in the training data. Leakage means the model saw information it shouldn't have. They require different fixes.
Here's a useful diagnostic order:
- Verify the split. Check for duplicate or near-duplicate rows across your training and test sets. For time-series data, confirm the split is chronological.
- Inspect feature availability. For each important feature, ask: would this column exist at prediction time?
- Audit your preprocessing. Was every learned transformation fitted only on training data?
- Then investigate overfitting. If the split is clean, features are valid, and preprocessing is isolated, a train-validation gap points to model complexity or insufficient data—not leakage.
Audit your feature importance scores. Models that rely heavily on counterintuitive features deserve scrutiny. If a model leans on a column that looks like it encodes the answer, remove that column and retrain. If performance collapses, you've found your leak.
The Leakage-Proof Workflow
Here's the workflow that prevents leakage, in order:
- Collect your data.
- Split into training and test sets first. The test set goes into a vault. You don't touch it until final evaluation.
- Fit all preprocessing inside the training fold. Scaling, imputation, encoding—everything fits on training data only.
- Engineer features only from information available at prediction time. If a feature wouldn't exist when you make a real prediction, it doesn't belong in training.
- Evaluate on the untouched test set. Once. At the end.
Two questions catch most leaks:
- Would this feature exist at prediction time?
- Was this statistic computed only from training data?
If either answer is no, you have a leak.
Use scikit-learn pipelines as your enforcement mechanism. They make the correct order the structural default rather than a discipline you have to remember. Pipelines are the difference between hoping you don't leak and making leakage structurally difficult.
Here's your next step: audit your most recent model against the three leakage families—feature leakage, preprocessing leakage, and training-example leakage. Then rebuild it with a pipeline that forces preprocessing inside the split.
And keep this decision rule close: if a feature or statistic would not exist at prediction time, it does not belong in training. The shortcut that inflates your validation score is the same shortcut that sinks your model in production.
Knowledge check
Final check
Finish the article by checking the ideas you just learned.
References
Research updated Sep 8, 2026


