Machine learningLoading progress…

Splits and generalization

Define a learning problem, establish a baseline and evaluate it on data not used for fitting.

Why not test on the data you trained on?

A model that memorises its training examples scores perfectly on them and tells you nothing about new data. So the data is divided into roles:

  • Training set: used to fit the parameters.
  • Validation set: used to compare models and settings (like the degree). You look at it repeatedly while making choices.
  • Test set: touched once, at the end, for an honest estimate of future performance.

Generalization means doing well on data the model has not seen. Because you tune against the validation set, it slowly stops being independent. That is why the test set is kept sealed until the end.

A random split can still leak

Shuffling rows and cutting them into 60/20/20 is the default. It assumes rows are independent. Often they are not: several sales from one account, several photos of one patient, repeated copies of one record. If one account's sales land in both train and test, the model can score well just by finding the sibling it already saw.

30 synthetic sales from 10 accounts, 3 near-identical sales each. train, validation, test. A red outline marks a test sale whose account also sits in train.

A1
val
A1
train
A1
test
A2
val
A2
train
A2
train
A3
train
A3
train
A3
train
A4
train
A4
train
A4
train
A5
train
A5
train
A5
val
A6
train
A6
test
A6
test
A7
train
A7
val
A7
test
A8
train
A8
test
A8
test
A9
train
A9
train
A9
val
A10
train
A10
train
A10
val
test accounts also in train: 4 (A1, A6, A7, A8) 1-nearest-neighbour test MAE (this shuffle): 3.7 thousand validation MAE (this shuffle): 3.5 thousand average test MAE over 60 shuffles, random split: 16.4 thousand

Test sales have near-copies in train, so the model scores well by memorising. That number will not hold for new accounts.

30 sales from 10 accounts. Compare the two split modes. A 1-nearest-neighbour model (it copies the most similar training sale) is scored on test.

Averaged over 60 shuffles, the random split reports a test error of about 16 thousand. Keeping whole accounts together reports 81 thousand. The second number is the honest one if the model will meet new accounts.

Predict first. Why keep all records from one patient in the same split?

Match the split to deployment

Ask how the model will be used, and make the split mimic that.

  • Forecasting the future: train on the past, test on later dates. A random split would let the model peek at the future.
  • New customers: split by customer.
  • Any scaling or filling of missing values: compute it from the training set only, then apply it to the others. Computing the mean over all rows first lets test data influence training.
Chapter context

A learning algorithm chooses a model from data rather than requiring a person to specify every decision rule. The resulting model is useful only if its predictions transfer to the intended future inputs under a clearly defined objective.

Chapter reference: math, worked example & code

This section belongs to the whole chapter, so it is the same on every lesson in it and may cover a different lesson's topic. The code for the experiment you just ran is inside the experiment itself.

Math and notation

For labeled data D={(xi,yi)}i=1nD=\{(x_i,y_i)\}_{i=1}^n, empirical risk is

R^(θ)=1n∑iℓ(fθ(xi),yi).\hat R(\theta)=\frac1n\sum_i\ell(f_\theta(x_i),y_i).

It estimates performance on the sampled population, not automatically on every deployment population. Accuracy is the fraction of correct predictions when classification is the task.

Worked example

A classifier predicts five held-out labels: [1,0,1,1,0] for actual labels [1,0,0,1,0]. Four are correct, so accuracy is 4/5=0.8. This number says nothing about its training accuracy or behavior on a differently collected test set.

Reference code

The following example uses the Python standard library and does not call a remote service.

actual = [1,0,0,1,0]
predicted = [1,0,1,1,0]
correct = sum(a == b for a,b in zip(actual,predicted))
assert correct == 4
assert correct/len(actual) == .8

Python examples are provided for study and local execution; this page does not execute Python.

Common mistakes

Learning a pattern does not establish causation. Validation data used repeatedly for model selection is no longer an untouched test. A random split is not always an independent split.