2.1.2 · D4Data Preprocessing & Feature Engineering

Exercises — Handling missing values (deletion, imputation strategies)

3,746 words17 min readBack to topic

This is a self-testing page. Read each problem, try it on paper, THEN open the collapsible solution. The problems climb a ladder: L1 Recognition → L2 Application → L3 Analysis → L4 Synthesis → L5 Mastery. Each level ends with a [!mistake] callout that steel-mans the trap most people fall into there.

Parent: Handling missing values. Related tools you may lean on: 2.1.01-Data-quality-issues-and-detection, 2.1.03-Outlier-detection-and-treatment, 2.2.01-Feature-scaling-and-normalization, 3.1.02-Training-validation-test-split, 4.3.01-Bias-variance-tradeoff, 5.2.03-Data-leakage-prevention.


Level 1 — Recognition

Can you name the mechanism and pick the safe reflex?

Exercise L1.1

A temperature sensor logs a reading every minute. Due to a hardware glitch it randomly drops exactly 3% of readings, and the glitch has nothing to do with the temperature, the time, or anything else. Name the missingness mechanism.

Recall Solution

MCAR — Missing Completely At Random. The definition: missingness has zero relationship to any variable, observed or unobserved. The glitch is a coin flip independent of everything. Because it is unrelated to the data, deleting those rows loses information (fewer samples) but introduces no bias — the rows that survive are a fair random sample of all rows.

Exercise L1.2

In a survey, people with very high salaries deliberately leave the Income box blank because they don't want to reveal it. The blank depends on the salary value that is itself missing. Name the mechanism, and say whether mean-imputation will fix the bias.

Recall Solution

MNAR — Missing Not At Random. The reason a value is missing depends on the unobserved value itself (the high salary). Mean imputation will not fix it. You only observe the lower and middle salaries, so their mean is below the true population mean. Filling the blanks with that too-low mean drags your estimate even further from the truth. MNAR needs domain knowledge or sensitivity analysis, not a standard formula.


Level 2 — Application

Plug into the formulas.

Exercise L2.1 — Mean imputation and its variance dent

Data (one feature): . (a) Impute the NaN with the mean of the observed values. (b) Compute the population variance after imputation.

Recall Solution

(a) Mean of observed : Filled series: .

(b) Population variance = average squared distance from the mean of the filled series. The filled mean is still (imputing at the mean never moves the mean). Notice the imputed point sits exactly on the mean, contributing to the spread — so it silently shrinks the variance. The figure below makes this visible.

Figure — Handling missing values (deletion, imputation strategies)

Exercise L2.2 — Forward fill (including the leading-gap edge case)

A stock's daily close: . (a) Apply forward fill. (b) Now suppose instead the series starts with a blank: . What happens to the leading NaN under forward fill, and how do you fix it?

Recall Solution

(a) Forward fill carries the last observed value into each gap: The last value before the gap is . Both blanks inherit it: It assumes prices change slowly day-to-day (temporal autocorrelation). If a real jump to happened gradually across the gap, forward fill underestimates the intermediate days.

(b) The leading-gap edge case. Forward fill needs a previous value to carry. But the very first slot has nothing before it — there is no . So the rule is undefined at , and the leading NaN stays NaN: Fixes, in order of preference:

  1. Backward fill for the leading positions: use the next observed value, , so the first slot inherits . This is the standard companion to forward fill precisely for edges.
  2. A global fallback (mean/median of the observed series) for any slot that neither a previous nor a next value can reach.
  3. Drop the leading rows if the series must not begin with a fabricated value (e.g. a strict time index where invented starting prices would mislead). Moral: forward fill alone cannot fill a gap at the very start (nor can backward fill at the very end) — always pair them or set an explicit fallback for the boundaries.

Exercise L2.3 — Median vs mean under an outlier

Data: . Compute both the mean-imputation value and the median-imputation value for the NaN.

Recall Solution

Mean of observed : Median of observed = middle of the sorted list . There are four numbers (an even count), so the median is the average of the two middle ones (the 2nd and 3rd after sorting): The single outlier yanks the mean to but barely touches the median (it only sits at the far end of the sorted order and never becomes a "middle" value). That is why median is the safer imputation for skewed / outlier-heavy features (it minimises , which is robust, instead of , which is dominated by the far point).


Level 3 — Analysis

Compare strategies and reason about consequences.

Exercise L3.1 — How much data does listwise deletion cost?

You have features, each independently missing of the time (MCAR). Under listwise deletion (drop a row if any feature is NaN), what fraction of rows survives, and what fraction is lost?

Recall Solution

A row survives only if all 8 features are present. Each is present with probability , and they are independent, so we multiply: Fraction lost: Even with a modest per column, listwise deletion throws away more than half the data. This is the "loss of power" cost of MCAR: no bias, but brutal shrinkage of your sample.

Exercise L3.2 — KNN imputation, worked distances

Impute Weight for patient A using nearest neighbours and uniform weights.

Patient Height Age Weight
A 160 40 NaN
B 162 41 60
C 158 38 55
D 175 55 82

Distance uses every feature except Weight: .

Recall Solution

Step 1 — distances (Weight is excluded because it's what we're predicting; using it would be circular): Step 2 — pick nearest: the two smallest are B () and C (). D is far away and is excluded. Step 3 — impute (uniform weights = plain average of neighbours' Weight): This beats global mean imputation (which would be ) because it ignores the dissimilar patient D and trusts the locally similar B and C — the local-smoothness assumption at work.

Figure — Handling missing values (deletion, imputation strategies)

Level 4 — Synthesis

Combine mechanism + strategy + pipeline discipline.

Exercise L4.1 — Choose and justify

A dataset of loan applicants has Income missing for 35% of rows, and investigation shows younger applicants skip it far more often (missingness depends on the observed Age column). You must build a model. State the mechanism, reject two strategies with reasons, and pick one.

Recall Solution

Mechanism: missingness depends on an observed variable (Age) but not on the hidden income itself → MAR (see the up-front definition). Formally: among applicants of the same age, high- and low-income people skip equally; the skipping is explained entirely by the observed Age column. Reject listwise deletion: dropping of rows that are disproportionately young skews the survivors toward older applicants → biased model, not just weaker. (Under MAR, deletion biases; under MCAR it would only weaken.) Reject plain mean imputation: it ignores Age entirely, flattening the true Income-varies-with-Age structure, shrinking variance, and breaking the Age–Income correlation. Pick model-based / conditional imputation (e.g. MICE, or KNN on Age): because missingness depends on observed Age, a model that predicts Income from Age can recover the true conditional distribution. That is exactly the situation MAR is designed for.

Exercise L4.2 — Where in the pipeline does imputation belong?

You split data into train/validation/test. You compute the imputation mean. From which subset must the mean be computed, and why? Then say what goes wrong if you compute it from the whole dataset.

Recall Solution

Compute the imputation statistic (mean, KNN neighbours, MICE models) using the training set only, then apply that frozen statistic to fill validation and test. Why: the validation/test sets simulate unseen future data. If the imputation mean is computed over all rows, information from test rows leaks into the training pipeline — this is data leakage (5.2.03-Data-leakage-prevention). Your reported accuracy becomes optimistic and won't hold in production. Concrete failure: a test row's true value silently influenced the fill values used during training and validation, so your model "peeked." The fix is to fit the imputer on the train fold and transform the others — align this with your 3.1.02-Training-validation-test-split discipline.


Level 5 — Mastery

Prove a claim from first principles and handle a degenerate edge case.

Exercise L5.1 — Prove mean imputation cannot increase variance

Let observed values be with mean and observed variance (here counts over the observed values). Now append copies of (the imputed points), giving values. Show the new variance .

Recall Solution

Step 1 — the mean is unchanged. Sum of all values . Divide by : mean . (This is why imputing at the mean "doesn't change the mean.") Step 2 — squared deviations of the new points are zero. Each appended value equals , so . They contribute nothing to spread. Step 3 — total squared deviation is unchanged, but we divide by more. Step 4 — conclude. Since (with ), we get , equality only when (nothing imputed). Mean imputation always shrinks (never grows) the variance — a proof, not a slogan. (The same shrink factor appears whether you use the population or sample divisor, so the effect is not an artefact of our choosing the version.)

Sanity check with L2.1: there , so . ✓ Matches the we computed directly.

Exercise L5.2 — Degenerate KNN

For patient A you want to impute Weight, but every other patient in the dataset also has Weight = NaN. What does KNN imputation return, and what is the principled fallback?

Recall Solution

What KNN returns: nothing valid. KNN imputation fills a hole by averaging the target values of A's nearest neighbours: Every candidate neighbour has , so there is no neighbour with an observed Weight to average. There are zero valid terms in the numerator — the expression collapses to , which is undefined. In practice a library either raises an error or silently returns NaN, i.e. it cannot impute this feature by KNN. The reason is structural: KNN borrows information that must actually exist somewhere, and here it exists nowhere.

The principled fallback (in order of preference):

  1. If the entire column is empty (Weight NaN for everyone): the column carries no signal at all — there is nothing to learn or borrow from it. Drop the column. Keeping it only invites a fabricated fill that pretends to be data.
  2. If only A's local neighbourhood happens to be empty (some rows elsewhere do have Weight): widen the search — increase or the radius until you catch neighbours that possess an observed Weight, or fall back to a global statistic (mean/median of the observed Weights) for that one row. You trade locality for the ability to fill at all.
  3. Flag and investigate. A whole-column gap almost never happens by accident; it usually signals an upstream data-quality failure (a broken join, a field that was never collected). Log it and trace it back through 2.1.01-Data-quality-issues-and-detection before trusting any downstream model.

The moral: imputation can only redistribute existing information — it can never manufacture it. When the information is truly absent (empty column), the honest move is to remove the column, not to invent numbers.