ml-004 · Clean two columns and calculate F1 — Concepts
The big idea
Real tabular data rarely arrives model-ready: a Boolean column may hold four different spellings of true/false plus tokens (“yes”) that cannot be mapped with confidence, and a numeric column may hold text with currency symbols and literal “N/A” strings. The first job is normalize, don’t guess: map only the tokens you recognize, turn everything else into an explicit missing value, and count what you lose. Once the table is clean, the smallest honest modeling loop is: a seeded stratified split (so both parts share the class balance), a logistic regression, hard predictions at a 0.5 threshold, and metrics computed by hand from the four confusion counts — because F1 is just arithmetic on TP, FP, and FN, and computing it yourself once is the fastest way to stop confusing it with accuracy.
Definitions
- Token normalization: lowercasing/trimming a string before mapping it, so “True”, “true”, and ” TRUE ” all hit the same dictionary entry. Unmapped tokens become missing, never a silent default.
- Stratified split: shuffling and splitting within each class so the train and validation parts each preserve the overall positive share.
- Confusion counts: TP (predicted 1, truly 1), FP (predicted 1, truly 0), FN (predicted 0, truly 1), TN (predicted 0, truly 0). Every threshold metric is a function of these four integers.
- Precision = TP / (TP + FP): of the rows flagged positive, how many were right. Recall = TP / (TP + FN): of the truly positive rows, how many were caught.
- F1 = 2 x precision x recall / (precision + recall): the harmonic mean. It is high only when both precision and recall are high, and it ignores TN entirely — which is why it can be low while accuracy looks fine.
Why it matters
The clean-split-fit-score loop in this practice is the skeleton of nearly every applied classification task. The cleaning half matters because silent coercion is the classic quiet bug: a “yes” mapped to true by accident, or a “$54.20” coerced to missing without a warning, changes the modeling table without ever raising an error. The metric half matters because on imbalanced data accuracy rewards the do-nothing classifier: with a ~30% positive share, a model can score ~70% accuracy while catching few positives, and only precision/recall/F1 expose that. Knowing the formulas cold — and the zero-denominator conventions — is a prerequisite for every later modeling practice.
Pitfalls
- Guessing ambiguous tokens. Mapping “yes” to true feels helpful but fabricates data; the honest move is missing plus a count of what was lost.
- Coercing the numeric column blindly. A blanket “convert, errors become missing” hides typos you would rather see; strip the known “$” case, map the known “N/A” case, and let anything unexpected fail loudly.
- Splitting without stratification. With a moderate positive share and a small validation set, a plain random split can shift the class balance by several points and quietly move every threshold metric.
- Reporting accuracy alone. TN dominates it on imbalanced data; F1 (or precision and recall separately) is the honest summary at a threshold.
- Dividing by zero. A model that predicts no positives has TP + FP = 0; precision is conventionally 0 there, not an exception. Handle it explicitly.
Check your understanding
TP = 8, FP = 5, FN = 20, TN = 55. Accuracy = (8 + 55) / 88 ≈ 0.716. Precision = 8/13 ≈ 0.615, recall = 8/28 ≈ 0.286, so F1 = 2(0.615)(0.286)/(0.615 + 0.286) ≈ 0.390. They disagree because accuracy credits the 55 true negatives — the easy majority class — while F1 ignores TN and is dragged down by the 20 missed positives. On imbalanced data the two metrics answer different questions, and F1’s is usually the one you care about.
Because the column’s contract is True/False in some casing, “yes” is evidence of a different data-entry path (another form, a manual edit, a bad merge) — you do not know whether that path used yes/no with the same meaning, inverted meaning, or as a default. Mapping it to true fabricates a label for the model feature; making it missing and counting the drops keeps the uncertainty visible and the decision reversible. If the “yes” rows mattered at scale, the right fix is upstream investigation, not a silent guess in the cleaning code.