Section 4.6

Cross-Validation & Overfitting

A model's job is to predict data you don't have yet, not merely to fit the data you have. Give a model enough flexibility and it will happily "explain" every random wiggle in your sample, scoring beautifully on the training data and failing on the next dataset. That failure mode is overfitting, and cross-validation is the standard, honest way to catch it before it catches you.

The trap: fitting the noise

Every dataset is signal plus noise. A too-simple model misses part of the signal (underfitting); a too-flexible one chases the noise (overfitting). The treacherous part is that ordinary fit statistics computed on the training data (like R² or mean squared error) always improve as the model gets more flexible. Judged on its own training data, the most absurdly wiggly model always looks best. You cannot detect overfitting by asking the training data.

Held-out data tells the truth

The cure is to evaluate the model on data it never saw while being fit. k-fold cross-validation does this without wasting a single observation: split the data into k chunks ("folds"), fit the model on k−1 of them, measure prediction error on the held-out fold, and rotate until every fold has had its turn as the test set. Average the k error estimates and you have an honest score. With k = 5 you get the classic 5-fold CV used below.

🎮 The Overfitting Playground

The dots are a noisy sample from the dashed teal curve (the truth). Raise the polynomial degree and watch the orange fit: training error (teal line, bottom panel) only ever falls, but 5-fold CV error (orange line) turns back up the moment the model starts memorizing noise.

Training MSE
5-fold CV MSE
Best degree by CV

Play with it for a minute and the pattern becomes unmistakable: training error keeps rewarding complexity forever, while CV error traces a U: falling while extra flexibility captures real signal, then rising once it starts capturing noise. The degree at the bottom of the U is the complexity the data can actually support. Hit "New sample" a few times: the best degree wobbles a little from sample to sample, which is itself a useful reminder that model selection has uncertainty too.

The mistake that puts the optimism back

Cross-validation is only honest about choices it did not make. Use the CV error to pick the polynomial degree above, and that same CV error stops being an unbiased estimate of how the chosen model will perform, because you selected the winner partly on its luck across those particular folds. The number you report is then a best-of-many, and it flatters. The same applies to anything else tuned by looking at the folds: a regularization penalty, a variable-selection step, even the decision of which outcome to model. Two clean fixes, both standard: hold out a final test set that is touched exactly once, at the very end, after every choice is locked; or use nested cross-validation, where an inner loop does the tuning and an outer loop measures a model whose tuning it never saw. The gap between the naive and nested estimates is usually small for one tuned parameter and embarrassing for several.

The bias–variance trade-off, in one sentence

Simple models are wrong in a stable way (high bias, low variance); flexible models are right on average but wildly unstable from sample to sample (low bias, high variance). Prediction error is the sum of both, which is exactly why the CV curve is U-shaped, and why "more flexible" is not the same as "better."

Where you'll meet this idea again

Cross-validation is the workhorse behind choosing predictors in variable selection, comparing models honestly alongside AIC/BIC from model comparison, and tuning essentially every machine-learning method. It's the backbone of the ML habit of train/test splits and honest generalization. And its philosophical cousin — judging a procedure by how it behaves across repeated resampling — is the same move the bootstrap makes for uncertainty.

Why it matters: training-data fit flatters every model, so it can never be the judge. Evaluating on held-out data (via a test set or k-fold cross-validation) is the single most reliable habit for building models that survive contact with new data.

Problem 37 of the practice problems puts this side by side with the information criteria: four nested models, and the question of whether the one that fits best is the one to report.

Common questions

What value of k should I use for k-fold cross-validation?

k = 5 or k = 10 is the standard, well-studied compromise: each fold's training set is nearly the full data (low bias), without the variance and cost of leave-one-out (k = n). Small datasets lean toward k = 10 or repeated CV (multiple random fold splits, averaged) to stabilize the estimate. There's rarely a reason to deviate.

What is the difference between a validation set and a test set?

The validation set is used during modeling (comparing candidate models, tuning complexity), so decisions get optimized against it, and its error estimate becomes optimistic. The test set is opened exactly once, after all decisions are final, to report honest performance. Cross-validation typically replaces the validation set; the untouched final test set remains best practice.

Can I use cross-validation on time-series data?

Not the ordinary kind. Random folds put future observations in the training set and past ones in the test set, so the model gets to see what it is supposed to be predicting and the score comes out far too good. Use a scheme that respects the arrow of time instead: rolling-origin (also called forward-chaining) validation trains on everything up to a cut-off, tests on the stretch that follows, then slides the cut-off forward and repeats, so every evaluation only ever looks forward. If neighboring observations are correlated, leave a gap between the training window and the test window as well, since an observation an hour before the test period leaks nearly as much as one inside it. The same care applies to any data with structure that random splitting would break, including repeated measurements on the same person: split by person, not by row.