Is a blank cell signal, or just missing?
Sometimes an empty cell is the most informative thing in the row. The trouble is that you
usually only know which case you're in by reading the data dictionary — and that doesn't
scale to 800 columns named f_0347. So we measure it instead, then check the answer
against the literature.
Ames housing · 1,460 sales · 79 columns · 19 of them contain blanks
"Drop any column that's more than 70% missing." I've written that line into more pipelines
than I can count. On Ames it deletes four columns — and three of them have real price
signal sitting in the gap.
The blanks in this dataset are structural. A blank GarageQual doesn't mean the value
was lost; it means the house has no garage. A blank Alley means no alley access. The
emptiness is the measurement.
That's easy to see here because the columns have English names and a published data
dictionary. It is not easy to see on a vendor feed of anonymised features, which is what
most real projects look like. So the question worth answering isn't "does missingness carry
signal" — it's can you tell, without knowing what the column means?
| 0.41 | R² from the blank/not-blank pattern alone — every value discarded |
| 1.00 | AUC recovering the garage blanks from other columns' values |
| ±0.9% | Total spread across five strategies — inside a ±1.5% CV noise band |
1 · A blank cell has a price tag
Start with the crude check: does sale price differ between rows where a column is blank and
rows where it isn't? Columns that go blank on the same rows describe one fact, so the five
garage columns collapse into one.
Fig 1. Median sale price, blank rows vs. valued rows. No garage is a $68k median
discount on a $163k median house. Note the sign flip: houses that have an alley or fence
are the cheaper ones — those features mark older, denser blocks. "Blank = worse" is not a
rule you can assume.
Then the harder test. Throw away every value in the table and keep only a 19-column matrix
of True/False — was this cell empty? Fit on that and nothing else.
Fig 2. Five-fold CV. A model that has never seen a floor area, a neighbourhood or a
year built reaches R² = 0.41 purely from which cells are empty.
The blanks are loud. But we only understood them by reading the data dictionary — and
that's the part that doesn't scale.
2 · Two questions, and most people only ask the first
For every column that contains a blank, ask two things — neither of which requires knowing
what the column means.
Axis 1 — does the blank move the target? Standardised difference in log price between
blank and non-blank rows, with a permutation test and a Benjamini–Hochberg correction
across the eight column groups. This is the axis everybody already runs.
Axis 2 — is the blank already recoverable from other columns' values? Predict "is this
cell blank?" from every other column, with every other column's own missingness destroyed
first, so the classifier can only use values you can actually observe. AUC near 1.0 means
some other column already tells you. AUC near 0.5–0.8 means nothing else in the table
knows.
Axis 1 alone is a trap. A blank can be powerfully associated with the target and still be
worth nothing, because a neighbouring column carries the same fact.
| Column group | % blank | effect | adj. p | recover AUC | verdict |
|---|---|---|---|---|---|
| Fence | 80.8 | +0.45 | 0.0007 | 0.765 | flag it |
| Alley | 93.8 | +0.55 | 0.0007 | 0.942 | flag it |
| Bsmt ×5 | 2.6 | −1.23 | 0.0007 | 0.982 | flag it |
| MiscFeature | 96.3 | +0.41 | 0.0051 | 0.983 | flag it |
| LotFrontage | 17.7 | +0.12 | 0.0930 | 0.824 | no signal |
| MasVnrType | 59.7 | −0.79 | 0.0007 | 0.999 | redundant |
| FireplaceQu | 47.3 | −1.02 | 0.0007 | 1.000 | redundant |
| Garage ×5 | 5.5 | −1.41 | 0.0007 | 1.000 | redundant |
Fig 3. The two axes together. Bubble size is the share of rows blank. Everything in the
shaded band is already encoded somewhere else in the table.
The interesting cases sit on the left. Fence at AUC 0.77 and Alley at 0.94: nothing
else in the table encodes them. Their blanks are the sole carrier of their fact — and
they are precisely the columns a "drop >70% missing" rule deletes.
LotFrontage, the classic "just median-impute it" column, lands at the bottom with
adjusted p = 0.09. The screen agrees with the folklore: impute it, move on.
Did it get the right answer? Now we allow ourselves the semantics we withheld, purely
to check the method. A blank GarageType means GarageCars == 0 in 100% of those
rows. Same for BsmtQual and TotalBsmtSF, same for FireplaceQu and Fireplaces.
MasVnrType is 98.5%.
The screen found those duplicate columns by itself, without being told what a garage is.
And for Fence and Alley there is no companion column anywhere in the table, which is
exactly why they land where they do.
3 · And then the model refuses to care
Five strategies, one model, nested cross-validation — the screen refit inside every
training fold, so column selection never sees the test rows. The screen is stable: it picks
Fence, Alley and MiscFeature in all five folds, and never once picks the garage,
basement or fireplace blanks.
Fig 4. Every strategy sits inside every other strategy's error bar. Plotted as dots
rather than bars because the differences are far smaller than the uncertainty, and a bar
chart would imply otherwise.
That's a null result, and it's the most useful thing here. Push it further — delete columns
at every threshold from 95% down to "anything with a blank at all":
Fig 5. You can delete all 19 columns that contain a blank and the model does not move.
Section 2 predicted this before a single regression ran. The recoverability axis was pinned
near 1.0 for every high-effect column: GarageCars == 0 says "no garage" perfectly, so the
flag is a duplicate. On a table this redundant, missingness is real signal that is also
entirely spare.
The screen's answer here was don't bother — which is worth knowing before you build the
pipeline, not after.
4 · The null had a literature-shaped explanation
A null result is only interesting if the theory predicted something else. So before blaming
the dataset, it is worth asking what the missing-data literature says should happen here.
Josse, Chen, Prost, Varoquaux & Scornet (2024) — On the consistency of supervised
learning with missing values. Constant imputation is
Bayes-consistent — but only with a powerful, non-linear learner. For trees, MIA
("missing incorporated in attributes") is the most versatile strategy, and it is what
HistGradientBoosting already does natively. Better missing-value handling mainly buys
sample efficiency.
Van Ness, Bosschieter, Halpin-Gregorio & Udell (KDD 2023) — The Missing Indicator
Method: From Low to High Dimensions. Indicators do not
hurt linear models asymptotically, but uninformative ones cause overfitting in high
dimensions. Their fix, SMIM, keeps an indicator only if isna is significantly
associated with the target — a t-test with Benjamini–Hochberg at FDR 0.1. Benefits are most
pronounced for linear models.
Le Morvan & Varoquaux (ICLR 2025) — Imputation for prediction: beware of diminishing
returns. Imputation accuracy matters less with expressive models, and less when
indicators are already present.
Two earlier results turn out to be confirmations rather than anomalies: ridge gained from
indicators where boosting gained nothing — that is Theorem 3's condition — and
IterativeImputer tied plain median, which is the diminishing-returns result exactly.
The ablation that settles it
Ames ships a complete numeric companion for nearly every categorical quality column:
GarageCars, TotalBsmtSF, Fireplaces, MasVnrArea. Dropping those ten — a feature
ablation on the real data, with no synthetic missingness — gives the table Ames would have
been without the duplication. Most real datasets look like that one.
| full table | companion-free | |
|---|---|---|
| ridge + indicators | +0.44% | +2.77% |
| boosting + indicators | -0.35% | +0.81% |
| boosting + MIA | -0.36% | +1.36% |
Fig 6. Left: the table as shipped — every line on zero at every sample size, so there
is no gap for a sample-size story to explain. Right: companions removed. Ridge gains
2.1% (±0.18 SE), and MIA's edge is largest when data is scarce
(2.3% at n=250) and smallest at the full sample
(0.4%) — Theorem 3 in a picture.
Note the two boosting lines move in opposite directions on the right. MIA's advantage
shrinks as rows accumulate, while explicit indicators need rows before they pay — seventeen
extra columns cost variance first and earn it back later. MIA gets the same information for
free inside the split rule.
What a second axis buys over SMIM
SMIM is exactly our Axis 1. Our screen adds the recoverability axis. Head to head, both
refit inside every training fold:
Fig 7. On the full table the second axis is pure parsimony: SMIM keeps 17
indicators, ours keeps 4, and ridge gains about the same (+0.80%
vs +0.68%). On the companion-free table ours keeps 11 — the
blanks it previously rejected are no longer recoverable.
The screen is measuring a property of the table, not of the column. Remove the columns
that gave the blanks away and it starts keeping them.
It also does not beat plain MIM when nearly everything is informative
(+2.43% vs +2.77%). That is the honest cost: dropping any genuinely
informative indicator costs a little. The second axis buys a smaller feature set at roughly
equal accuracy — not a better model. And on that table MIA beat every
impute-plus-indicator variant under boosting (+1.36%), which is precisely what
Josse et al. recommend.
And the imputer itself?
Fig 8. Signed contrasts against median imputation, paired within folds. No imputer
contrast anywhere exceeds 0.0015 RMSE. The one that clears 2 SE — IterativeImputer
on companion-free ridge — is worth 0.00026, against 0.00394 for the indicator
in that same setting.
This does not say what a headline would want it to. The imputer choice never pays. A
median, a round-robin regression model and a nearest-neighbour search are separated by at
most 0.0015 RMSE anywhere. In the one setting where an imputer contrast clears
2 SE, it is worth 0.00026 — against 0.00394 for the indicator in that same
setting, about 15× more from a one-line change.
But for gradient boosting nothing here reaches 1.5 SE — not the imputers, not the
indicators. And five folds is weak evidence either way; the properly-powered result is
Fig 6, which repeats twelve times against a held-out test set.
| Prediction | Source | On Ames |
|---|---|---|
| Constant imputation is consistent with a powerful learner | Josse Thm 3 | confirmed |
| MIA is the most versatile tree strategy | Josse §5 | confirmed |
| Indicators help linear models more than powerful ones | Van Ness §3 | confirmed |
| Screening keeps the gain with fewer features | Van Ness Alg. 1 | confirmed, extended |
| Imputation accuracy barely matters for prediction | Le Morvan & Varoquaux | confirmed |
Every prediction holds. The null was a property of this table, not a counterexample to
the theory — and removing ten columns makes Ames behave exactly as the literature says it
should.
Four things worth stealing
- A missingness threshold is not a triage rule. It deleted the only three columns whose blanks weren't duplicated elsewhere, and kept the ones that were.
- "Strong missingness effect" is not a reason to keep a flag. "…and nothing else can reconstruct it" is. That second test costs one classifier per column.
-
Neither test needs semantics. Both run on
f_0347exactly as well as onGarageQual— the case where you can't read the docs. Axis 1 is Van Ness et al.'s SMIM; Axis 2 is the addition. - Run the screen inside your CV folds. Axis 1 touches the target, so selecting columns on the full dataset leaks. It changes which columns get picked fold to fold, and that variation is information too.
Where this flips. Ames is unusually redundant — it ships a numeric companion for nearly
every categorical quality column. Tables without that luxury are where the second axis earns
its keep: survey non-response, lab panels ordered only when a clinician suspects something,
credit-application fields a declining applicant left empty. There the blank is often the
only place the fact lives. The method doesn't assume either way — it measures.








Top comments (0)