Overfitting, Validation and Tuning

Underfitting and overfitting computed on real fits, learning curves, regularization, hyperparameter search and keeping the test set honest.

Fitting the noise

Every measurement is the pattern plus noise. A flexible model can follow the noise in the training data as faithfully as the pattern, scoring brilliantly on data it has seen and poorly on anything new. This is overfitting. The opposite, a model too simple to capture the pattern, is underfitting. The cure is the same discipline throughout this guide: measure the error on data the model has not seen (see Data Preparation, Splitting and Leakage).

SymptomDiagnosisTry
Training error low, validation error highOverfitting (high variance)More data, a simpler model, regularization, fewer features, early stopping
Both errors highUnderfitting (high bias)Better features, a more flexible model, less regularization
Both low and closeAbout rightConfirm on the test set, then deploy
Validation error noisy between runsToo little validation dataCross-validation, a larger validation set (see Data Preparation, Splitting and Leakage)

Complexity against error: a computed example

Twenty noisy points follow a smooth curve. Ten (every other one) are used for training, ten for validation. Polynomials of degree 1 to 9 are fitted to the training points.

Underfitting, a good fit and overfitting00.250.50.75101234inputoutputFilled: trainingOpen: validationdegree 1train 0.63, val 0.61degree 3train 0.25, val 0.28degree 9train 0.00, val 6.02
Degree 1 underfits, degree 3 follows the curve, degree 9 passes through every training point and swings wildly between them.
DegreeTraining RMS errorValidation RMS errorVerdict
10.630.61underfits
20.620.65underfits
30.250.28best on validation
40.210.33overfits
50.160.44overfits
60.160.38overfits
70.081.34overfits
80.070.68overfits
90.006.02overfits
Error against model complexity, computed1234567890.00.51.01.52.02.53.0polynomial degreeRMS errorbest: degree 3trainingvalidation
Training error falls all the way to zero; validation error is lowest near the true complexity and then rises.

Reading the table

  • The training error keeps falling, reaching 0.00 at degree 9: ten parameters have memorized ten points. A model scored on its own training data always looks good.
  • The validation error is lowest at degree 3 (0.28) and climbs to 6.02 at degree 9.
  • The data were made with noise of about 0.23 (standard deviation), so no model can do better than that on new data: the noise floor. The best validation error of 0.28 is close to it. An error far below the noise floor on held-out data would mean a leak (see Data Preparation, Splitting and Leakage).
  • With only ten validation points these numbers are noisy: a different split might pick degree 2 or 4. That is why validation sets should be as large as you can afford, or replaced by cross-validation.

Bias and variance

The expected error on new data splits into three parts: bias² (the model is systematically wrong because it is too simple), variance (the fitted model changes a lot with each training set) and the irreducible noise.

expected squared error = bias² + variance + noise²

Worked example: measured by repeating the experiment

Draw 200 different training sets of 20 points from the same curve, fit each, and compare the fits with the true curve at 41 points:

ModelBias²VarianceNoise²Total expected error
Degree 10.4210.0070.0510.478
Degree 30.0110.0130.0510.074
Degree 90.0010.1450.0510.196
  • Degree 1 has a large bias² (0.421) and small variance: it is always wrong in the same way.
  • Degree 9 has a bias² of only 0.001 but a variance of 0.145: it fits each set of noise differently, so its average is right and its individual fits are not.
  • Degree 3 balances them, with the lowest total error (0.074). The noise term is the same for all and cannot be reduced.
  • You cannot see bias and variance on one data set, but the gap between training and validation error is a good indicator of variance, and a high error on both of bias.

Learning curves: would more data help?

A learning curve plots training and validation error against the amount of training data. It tells you where to spend effort.

Worked example: degree 3 against degree 9

Average over 40 random training sets of each size, validated on 200 fresh points:

Training pointsDegree 3: trainDegree 3: validationDegree 9: trainDegree 9: validation
120.200.280.101.29
160.210.270.140.49
240.220.260.170.30
400.230.250.190.25
800.240.250.210.24
1600.240.240.220.23
  • Degree 3 converges fast: by about 40 points the training and validation errors are close (near the 0.23 noise floor), so more data will not help; only better features or a less noisy sensor would.
  • Degree 9 needs far more data before its validation error falls to the same level: with few points the gap is huge. More data is the cure for variance; for bias it is not.
  • Use this yourself: train on 25 %, 50 %, 75 % and 100 % of your training data and plot both errors. If validation error is still falling steeply, collect more data.

Regularization

Regularization limits a model’s freedom. The common forms: a penalty on the size of the coefficients (ridge: λ Σ w²; lasso: λ Σ |w|), limits on tree depth or leaf size, dropout in neural networks, and early stopping. The penalty λ is a hyperparameter: you choose it by validation, not training.

Worked example: taming the degree-9 fit

Fit a degree-9 polynomial to 20 noisy points with different ridge penalties, and measure the error on 200 fresh points:

Penalty λTraining RMSValidation RMSLargest coefficient
0 (none)0.130.5678.5
0.00010.170.3417.0
0.0010.180.316.0
0.010.200.274.5best
0.10.290.322.9
10.510.521.6
100.790.820.5
  • With no penalty the largest coefficient is huge and the validation error is poor; the curve swings wildly to touch every point.
  • A modest penalty (λ = 0.01) gives the lowest validation error, 0.27, with smaller coefficients and a slightly worse training error: the signature of a better model.
  • Too large a penalty underfits: both errors rise. The best λ sits in between.
  • Scale the features first, or the penalty acts unevenly on inputs of different size (see Data Preparation, Splitting and Leakage).

Tuning without fooling yourself

Hyperparameters (tree depth, k, the penalty, the learning rate, the number of layers) are chosen by trying values and comparing validation scores. Do this with grid search (every combination of a few values), random search (random combinations, which covers important parameters better when few matter) or Bayesian tools such as Optuna. But every comparison on the validation set uses up a little of its honesty.

Worked example: the winner’s curse

  • Train 100 models that are pure random guessers (true accuracy 50 %) and score each on the same 50 validation cases. The scores average 50.10 %, as they should, but the best one scores 72 %, about 3.1 standard errors above chance (the standard error is 7.1 points).
  • On 1 000 fresh cases that best model scores 48 %: it was never any good. Picking the maximum of many noisy scores selects luck.
  • The same happens, more gently, whenever you try 20 hyperparameter combinations on a small validation set and report the best score. The reported score is optimistic; the test set, used once, is the honest one.
  • Keep the test set out of the loop. If a test score changes any decision, it has become part of validation; get new test data.
  • Use nested cross-validation when data is scarce: an inner loop picks the hyperparameters, an outer loop scores the whole procedure.
  • Prefer fewer, bigger choices: a handful of values over a wide grid, and the simplest model within one standard error of the best (“one-standard-error rule”).
  • Set the random seeds and record them, so that an experiment can be repeated (see What Machine Learning Is and When to Use It).
from sklearn.model_selection import GridSearchCV, StratifiedKFold
from sklearn.ensemble import RandomForestClassifier
grid = {"max_depth": [3, 5, 8, None], "min_samples_leaf": [1, 3, 10]}
search = GridSearchCV(RandomForestClassifier(n_estimators=300, random_state=0), grid, scoring="f1",
                      cv=StratifiedKFold(5, shuffle=True, random_state=0)).fit(X_train, y_train)
print(search.best_params_, search.best_score_)     # a validation score: optimistic
print(search.score(X_test, y_test))                # use the test set once, at the very end

Early stopping and other brakes

  • Early stopping: for iterative training (boosted trees, neural networks) watch the validation error each round or epoch and stop when it stops improving for a set number of rounds; keep the model from the best round. A common default patience is 5 to 20 epochs.
  • Simpler models and fewer features: remove inputs that carry no physical meaning; each extra input is another chance to fit noise.
  • Data augmentation: adding realistic variation (noise, shifts, scaling) to training examples makes a model less sensitive to the exact examples.
  • Ensembles: averaging many models (forests, bagging) reduces variance (see Trees, Clustering and Anomaly Detection).
  • More and better data is the strongest remedy for overfitting; check with a learning curve first.

A validation checklist

CheckWhy
A baseline is reported beside the modelA score means nothing without the simple alternative
Splits follow the real use (by machine, by time)Otherwise the score is too good
Scaling and feature selection are fitted on training data onlyNo leakage through preprocessing
Validation score uncertainty is stated (cross-validation spread or a margin of error)Small differences are noise
Training and validation errors are both shownThe gap shows over- or underfitting
The test set was used onceIt is the honest number
The error is compared with the noise floor and with the requirementBetter than the noise is a warning; worse than the need is a failure
The model is tried on a new machine, batch or season before launchThe first real deployment test

Related

FAQ

How do I know if I am overfitting?

Compare training and validation error. A low training error with a much higher validation error is overfitting. Plot both against model complexity or training size to see it.

How big should the validation set be?

Large enough that the uncertainty of the score is smaller than the differences you want to see. For a classifier near 90 % accuracy, about 600 samples give a margin of about 2.4 points; with rare faults you need enough faults, not just rows.

Is it wrong to look at the test set more than once?

Each look that changes a decision makes the test score optimistic. Use it once, at the end; if you need to look again, collect fresh test data.

Does regularization always help?

It helps when the model is too flexible for the data. If the model is already underfitting, more regularization makes it worse. Choose the strength by validation.

References

  • Hastie, T., Tibshirani, R. and Friedman, J., The Elements of Statistical Learning, chapters 7 and 3 (bias-variance and shrinkage).
  • Cawley, G. C. and Talbot, N. L. C., “On over-fitting in model selection and subsequent selection bias in performance evaluation”, JMLR, 11 (2010).
  • Géron, A., Hands-On Machine Learning with Scikit-Learn, Keras and TensorFlow, chapter 4 (learning curves and regularization).

Last reviewed: October 2026. All numbers on this page come from the simulated data described; the pattern, not the values, is what carries over.