150 synthetic rows are generated with three correlated features so that f2 can genuinely be predicted from f1 and f3:
f1 ~ U(-4, 4)
f2 = 0.7·f1 + N(0, 1.2) (the feature we knock out)
f3 = 0.5·f2 + 0.3·f1 + N(0, 1)
A fraction of f2 values are then hidden. MCAR (missing completely at random) hides each row with equal probability. MAR (missing at random, conditional on f1) raises the hiding probability for rows with high f1 — the realistic case where missingness correlates with an observed variable, which is exactly what mean/median imputation cannot detect.
Mean/Median: fill = mean(f2_observed) or median(f2_observed)
KNN(k): fill = average f2 of the k observed rows nearest
in (f1, f3) space, distance = √((Δf1)² + (Δf3)²)
Regression: fit f2 = a + b·f1 + c·f3 by least squares on the
observed rows, then predict the missing ones
RMSE = √( mean( (f2_imputed − f2_true)² ) ) over missing rows only
- Each hidden point renders as an amber ball at its imputed height, joined by a thin line to a small translucent gold ghost marking the true, hidden value — the line's length is the imputation error for that row.
- Mean/median imputation ignores f1 and f3 entirely, so under MAR it is systematically wrong in one direction and always shrinks the variance of f2 — watch the variance ratio drop below 1.
- KNN and regression exploit the f1–f3 correlation, so they track the ghosts much more closely and keep the variance ratio near 1, especially under MAR.
- Drop rows deletes the missing cases instead of filling them (no RMSE/variance is computable) — it wastes data and, under MAR, biases the remaining sample toward low f1.