2.1.13 · D2Data Preprocessing & Feature Engineering

Visual walkthrough — Data leakage identification and prevention

3,263 words15 min readBack to topic

Step 1 — What "learning" even means (the two worlds)

WHAT. A model lives in two worlds. World A is your laptop: a fixed table of rows you already collected. World B is production: an endless stream of new rows arriving in the future. Learning only works if these two worlds are secretly the same shape.

WHY. Every guarantee in machine learning rests on one bet: the future looks like the past. If World A and World B differ, a model tuned to A has no reason to work in B. We must picture both worlds before we can see what leakage breaks.

PICTURE. Two clouds of dots — each dot is one row (a person, a transaction, a day). The clouds have the same centre and same spread. That sameness is the whole ballgame.

The bet, in one line:

Each side is a cloud shape. The = says: same cloud. Hold onto this — leakage is the act of secretly reshaping the left cloud.


Step 2 — The score we want vs. the score we can measure

WHAT. We would love to know the model's average mistake over all of production. Call that the true risk . But production is the future — we can't measure it. So we settle for the average mistake over our laptop table: the empirical risk .

WHY. This gap between "what we want to know" and "what we can measure" is where leakage hides. If the two numbers move together, we're safe. Leakage is precisely what makes them move apart.

PICTURE. A dartboard. The bullseye is (true skill). Our measured score is where our darts land. Normally the darts cluster near the bullseye. We are about to see leakage yank the darts far off — while the scoreboard lies and says "bullseye!".

So low = "looks smart on my laptop" — but only trustworthy if the two clouds truly match.


Step 3 — A clean feature vs. a poisoned feature

WHAT. A feature is one column of . A clean feature is measurable at prediction time (transaction amount — you know it the instant the swipe happens). A poisoned feature is secretly built from the answer or from the future.

WHY. This is the birth of target leakage. We formalise the poison so we can watch it wreck the score in Step 4. The parent note wrote the poisoned feature as — let us picture exactly what that means.

PICTURE. Two scatter plots side by side. Left: a clean feature vs. the label — a fuzzy, weak trend. Right: a poisoned feature vs. the label — a razor-straight line, because the feature is literally a copy of the answer plus a whisper of noise.


Step 4 — Watch the training score fall to zero

WHAT. Give the model the poisoned column. Because is almost a perfect copy of , the model just learns to invert the recipe — undo — and read the answer straight off the feature.

WHY. This is the mechanism behind "99% accuracy". It is not intelligence; it is cheating with the answer key visible. We must see the training loss collapse to appreciate how convincing the lie is.

PICTURE. A staircase of predictions descending onto the true-label line. Each guess lands almost exactly on , so every red error-bar shrinks to nothing.

The model effectively computes:

  • :: the model's prediction (the "hat" means estimate of).
  • :: the inverse recipe — the question "which answer produced this feature value?". It undoes , just like square-root undoes squaring. (Valid because we assumed invertible above.)
  • :: applying a recipe then undoing it returns the original — so the prediction equals the truth.

Plug this into the empirical risk from Step 2, now with squared-error loss:

  • The inside is guess minus truth — a tiny number, because only the wobble survives.
  • Squaring makes every error positive so they can't cancel.
  • Averaging tiny numbers gives . The laptop scoreboard reads "perfect".

Step 5 — Production has no answer key

WHAT. Deploy the model. Production hands it a new row — but the poisoned column doesn't exist yet (the dispute hasn't happened, the future price hasn't formed). The model reaches for its cheat column and finds an empty slot.

WHY. This is the moment the two worlds of Step 1 stop being the same. The clean cloud and the poisoned cloud were different clouds all along — training on the wrong one.

PICTURE. The same descending staircase from Step 4, but now the poisoned column is greyed out / missing. Predictions scatter wildly off the true-label line; every red error-bar is huge again.

Because production is an endless stream, its risk is honestly an expectation (the ideal infinite average from Step 2), not a finite sum:

  • :: the true average over the whole production cloud — no fixed .
  • :: only the columns that truly exist at prediction time — the poison is gone.
  • still expects the poison, so its guesses are garbage.

In practice you can only estimate by collecting a finite batch of real deployed rows and averaging, ; by the law of large numbers this batch-average approaches the expectation as . Either way the value is : the real scoreboard reads "60%".


Step 6 — Temporal leakage: the same poison in disguise

WHAT. No obvious answer-column here — yet a rolling average computed before splitting still leaks. A test day's feature borrows values from days that sit in the training set (and vice-versa) because a 30-day window straddles the split line.

WHY. Time series is the sneakiest case: the leak is positional, not a whole column. We give it its own step because the fix is different — you split by time first, then engineer. See Time series forecasting fundamentals and Train-testvalidation split strategies.

PICTURE. A timeline with a vertical split bar at 1 July. A 30-day averaging window sits on a July test point but its left half reaches back across the bar into June (training) days — the arrow of information points backwards in time, which reality never allows.

  • :: the index of the split — everything is training.
  • :: a test point, days past the split.
  • :: the rolling mean feature for that test day.
  • Left sum :: window days that fall before the split — legitimately known.
  • Right sum :: window days after the split — but they mix with test values that leak into the feature the model trained its scaling/relationships on.
  • The mean blends the two, so training features quietly know about neighbouring test days.

Fix in one line: compute every window using only data strictly earlier than the prediction day — simulate standing in the past. Under Cross-validation techniques this becomes time-series CV (expanding windows), never plain shuffled folds.


Step 7 — Degenerate case: scaling on the whole table

WHAT. Even a "harmless" StandardScaler leaks if you .fit it on all rows before splitting. The mean and spread it learns are computed from test rows too.

WHY. This is the mildest leakage — often the gap is small — but it's the most common, so it deserves its own picture. It shows leakage isn't only about copying the answer; any statistic borrowed from unseen data counts. See Feature scaling and normalization and Pipeline and workflow automation.

PICTURE. A number line. Training houses cluster low (mean 1500), test houses cluster high (mean 3500). Fitting on all gives — a centre that sits in empty space between the two groups, so training values get scaled using a yardstick the test set moved.

Before reading the formula, name its counters. Let be the number of training rows and be the number of test rows; their sum is the total row count. Now the (leaky) all-data mean:

  • :: the mean the scaler learns from every row.
  • , :: counts of training and test rows (defined just above).
  • :: divide by the total number of rows to make an average.
  • :: add up the feature over training rows — allowed.
  • :: add up over test rows — this term should not be here; test rows are contaminating the training yardstick.

Now the honest production mean, so the symbols are matched. Because production is an endless stream, is again an expectation, not a finite sum:

  • :: the true long-run mean of the feature over the production cloud — the value the scaler should have used.
  • Generally (and likewise ), so the scaling learned on your laptop is simply wrong for new data.

Fix: scaler.fit(X_train) — fit on training only, then .transform train, test, and production identically. A Pipeline enforces this automatically inside cross-validation.


The one-picture summary

Everything above is one story: a hidden channel of information sneaks into the features, the laptop score plummets to zero, and production — lacking that channel — pays the bill. This final figure stacks all three leakage types over the same "true vs. measured score" axis so you can see the gap open up.

Recall Feynman retelling — say it to a 12-year-old

Imagine studying for a test. Normal studying: you practise problems that look like the exam. On the exam you do about as well as in practice — the two match. Cheating (target leakage): someone slips the answer key into your practice sheet. You "score" 100% at home because you're just copying answers — but on the real exam the key is gone and you flop. Peeking at the future (temporal leakage): your practice questions secretly used facts you'd only learn after the exam — impossible to reproduce on the day. Borrowing the grading curve (scaling contamination): you calibrated how hard the questions "feel" using the actual exam questions, so your practice felt easier than reality. In all three, the number on your fridge (the laptop score ) is a liar; the number that matters is how you do on the real thing (). Leakage is anything that lets these two numbers disagree — and the golden rule to prevent it is one sentence: only feed the model what it could genuinely know at the moment of prediction.

Recall

What is the leakage gap in words? ::: The size of the difference between real-world error and laptop error ; leakage makes it unbounded. Why does target leakage drive training error to ? ::: The poisoned feature is a near-copy of the answer, so the model just inverts (assuming invertible) and reads off directly. One-sentence prevention rule? ::: Only use features whose values are genuinely available at prediction time. Why is fitting a scaler on the whole table leakage? ::: Because the learned mean and spread absorb test-row values, so training features are scaled with information the model should never have seen — making the laptop yardstick wrong for real production data. When does a rolling-window temporal leak stop? ::: Once the test point is at least one window-length past the split (), the whole window lies in the test region and no training days leak in — the effect is a transient boundary band.