Frontend Labs
⋯

Chapter 13 — How do you know if a model is any good?

In one sentence

Test it on data it has never seen, with a metric that matches what you actually care about — and be paranoid about accidentally cheating.

The golden rule

Split your data BEFORE you do anything else:

   +-------------------- all your data --------------------+
   |  TRAIN (70-80%)      |  VALIDATION (10%) |  TEST (10%)|
   +----------------------+-------------------+------------+
      fit the knobs         choose settings     touch ONCE,
                            (learning rate,     at the very
                            model size, ...)    end

If you tune anything based on the test set, your test score becomes a lie.

Metrics: accuracy is usually the wrong one

Suppose 99% of emails are legitimate. A model that says "not spam" to everything gets 99% accuracy and is completely useless. You need:

                     PREDICTED
                  spam      not spam
            +-----------+-----------+
   spam     |    TP     |    FN     |   <- FN = spam that got through
ACTUAL      |  (caught) |  (missed) |
            +-----------+-----------+
  not spam  |    FP     |    TN     |   <- FP = real email in the spam folder
            | (false    |  (correct)|
            |  alarm)   |           |
            +-----------+-----------+

Precision = TP / (TP + FP)   "when I say spam, how often am I right?"
Recall    = TP / (TP + FN)   "of all the spam, how much did I catch?"
F1        = harmonic mean of precision and recall

Which one matters depends on the cost of each mistake:

Application You care most about Why
Spam filter Precision A lost job offer in the spam folder is far worse than one spam in the inbox
Cancer screening Recall Missing a cancer is far worse than a false alarm that gets a second test
Search results Precision@10 Users only look at the first page
Fraud detection Depends on the money at stake — usually a tuned balance

Always ask "what is the cost of each kind of mistake?" before picking a metric.

Overfitting: the most common failure

error
  ^
  |  \                                       ___
  |   \                                 ____/     <- TEST error (what matters)
  |    \                          _____/
  |     \                    ____/
  |      \______________----/
  |       \___                                    <- TRAIN error
  |           \_____________________________
  +---------------------------------------------> training time / model size
      underfit      GOOD           overfit
                     ^
                     +-- stop here ("early stopping")
  • Underfitting: bad on train AND test. Model too simple. Fix: bigger model, better features, train longer.
  • Overfitting: great on train, bad on test. The model memorised instead of generalising. Fix: more data, simpler model, regularisation, early stopping.

Memorable analogy: underfitting is a student who didn't study. Overfitting is a student who memorised last year's exam answers word for word and fails when the questions change.

Data leakage: the sneaky killer

Leakage = information sneaking into training that won't exist at prediction time, or the test data influencing training. Symptom: suspiciously good scores that collapse in production.

Real examples:

  • Predicting churn using a feature account_closed_date — which only exists because they churned.
  • Scaling your features using statistics computed over the whole dataset (including the test set) before splitting.
  • The same customer appearing in both train and test.
  • Predicting stock prices with a random split instead of a time-based split.
  • (LLM era) the benchmark's questions appearing in the pretraining data — called contamination, and a serious ongoing problem in AI evaluation.

A famous real case: a pneumonia detector scored 0.95 AUC in the lab and failed in the clinic. It had learned to recognise the portable X-ray machine marker — used on sicker, bed-bound patients — rather than the lungs. The fix was a hospital-stratified split.

Practice (25 min)

from sklearn.datasets import fetch_20newsgroups
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.metrics import classification_report, confusion_matrix
import numpy as np

data = fetch_20newsgroups(subset="all",
        categories=["rec.sport.baseball", "sci.space", "talk.politics.misc"],
        remove=("headers","footers","quotes"))

X_train, X_test, y_train, y_test = train_test_split(
    data.data, data.target, test_size=0.2, stratify=data.target, random_state=0)

vec = TfidfVectorizer(min_df=2)
Xtr = vec.fit_transform(X_train)     # fit ONLY on train  <-- avoids leakage
Xte = vec.transform(X_test)          # transform test with the SAME vocabulary

clf = LogisticRegression(max_iter=1000).fit(Xtr, y_train)
pred = clf.predict(Xte)

print(classification_report(y_test, pred, target_names=data.target_names))
print("Confusion matrix (rows=true, cols=predicted):")
print(confusion_matrix(y_test, pred))
print("\n5-fold CV on training data:",
      cross_val_score(clf, Xtr, y_train, cv=5).round(3))

Now deliberately cause leakage and watch the score inflate:

# WRONG: fit the vectorizer on ALL data before splitting
vec_bad = TfidfVectorizer(min_df=2)
X_all = vec_bad.fit_transform(data.data)          # <-- sees the test set!
Xtr2, Xte2, ytr2, yte2 = train_test_split(X_all, data.target, test_size=0.2,
                                          stratify=data.target, random_state=0)
clf2 = LogisticRegression(max_iter=1000).fit(Xtr2, ytr2)
print("leaky score: ", clf2.score(Xte2, yte2))
print("honest score:", clf.score(Xte, y_test))

The leaky number will be a bit higher. In this small case the difference is modest; in real projects with feature engineering it can be enormous. Build the habit: split first, always.

Common confusions

  • "My model is 99% accurate!" Check the class balance first. Always.
  • "Cross-validation instead of a test set?" CV replaces the validation split. Keep a final test set you touch once.
  • "Can I look at the test set to debug?" Once you look, it's no longer a clean estimate. Use validation for debugging.

Check yourself

  1. Why is accuracy a bad metric for rare events?
  2. Explain precision vs recall using the spam example.
  3. What is data leakage? Give an example.
  4. Would you optimise for precision or recall in a cancer screening test? Why?

Further reading

  • Video: StatQuest, "Machine Learning Fundamentals: Bias and Variance", "The Confusion Matrix", and "ROC and AUC, Clearly Explained" — three short videos that cover this chapter better than most courses.
  • Course: Google ML Crash Course — "Classification" module (accuracy, precision/recall, ROC/AUC), with interactive widgets.
  • Book: Hands-On Machine Learning (Géron), Chapter 3 — the best practical treatment of evaluation metrics.
  • Article: "Data Leakage in Machine Learning" — search for the Kaggle learn micro-course lesson; short and full of real examples.

End of Part 3 — Milestone check

You should now be able to:

  • Explain the six-step ML recipe from Chapter 8 from memory
  • Build a working text classifier in <20 lines
  • Explain what loss and gradient descent are, with the hillside analogy
  • Explain what a language model computes: p(next word | previous words)
  • Explain the two reasons n-gram models fail
  • Split data correctly and pick a metric that matches the business cost

If any box is unticked, revisit that chapter before moving on — Parts 4–6 build directly on all six.


Generated from real-life-ai-example-v1.md · 8 Oct 2026 16:36