Overfitting in Linear Regression
Page 902 produced a formula that works for any . This page asks what happens as grows, and the answer is Chapter 8’s §8.3.3 arriving with concrete numbers attached — “we suffer from overfitting”.
Three results, all measured: the training error cannot rise, which is why it cannot be trusted; the estimator stops being unique at ; and the degree the book picks is one draw of a random experiment, winning only of repeats.
What you’ll learn
Section titled “What you’ll learn”- Equation 9.23, the RMSE — and the two reasons the book prefers it, both checkable.
- Why “the training error never increases” is a theorem rather than an observation — verified across nine steps, zero increases.
- The book’s search bound , and what happens past it: measured, a null space of dimension and infinitely many estimators fitting equally well.
- Figure 9.6 reproduced: the test error bottoms out at at , then reaches at .
- At : training RMSE — the curve passes through every point — and the worst test error on the page.
- How stable that conclusion is. Repeated on fresh draws, wins , wins , wins .
Intuition: the exam you wrote yourself
Section titled “Intuition: the exam you wrote yourself”The training error can never rise as you add capacity, and the reason is set inclusion rather than statistics. Every degree-4 polynomial is also a degree-5 polynomial — set . So the degree-5 class contains everything the degree-4 class could do, and its best member cannot be worse.
That single fact is why a falling training curve carries no information. It would fall for a model that generalised perfectly and for one that memorised the data, and by it reaches zero — a polynomial through points exists and is unique, so the fit is exact and says nothing at all.
What it does leave behind is a fingerprint. Interpolating scattered points requires violent oscillation between them, and violent oscillation requires large coefficients. The parameter norm is the one warning visible without a test set — which is precisely the handle §9.2.3 grabs.
flowchart TD A["degree M class contains degree M-1 class
(set theta_M = 0)"] A --> B["best fit cannot get worse
THEOREM, not observation"] B --> C["training RMSE monotone
measured: 9 steps, 0 increases"] C --> D["at M = N-1 it hits 0
measured 6.5e-11"] D --> E["so it carries NO information
about generalization"] E --> F["a held-out set, Eq 9.23
test RMSE bottoms at M = 4"] E --> G["or the parameter norm
0.99 at M=4, 4.20 at M=9"] G -.->|"Section 9.2.3 acts on this"| H["a prior on theta"]
§9.2.2 Measuring the error
Section titled “§9.2.2 Measuring the error”The negative log-likelihood works, but since “the noise parameter is not a free model parameter, we can ignore the scaling by ”, leaving . The book then prefers the root mean square error, Equation 9.23:
for two stated reasons: it “(a) allows us to compare errors of datasets with different sizes” and “(b) has the same scale and the same units as the observed function values .”
The book’s own illustration: mapping post-codes to house prices in EUR gives an RMSE in EUR, while the squared error is in EUR², and including leaves “a unitless objective”.
The training error cannot rise
Section titled “The training error cannot rise”Note that the training error never increases when the degree of the polynomial increases.
Choosing the degree, and the bound
Section titled “Choosing the degree, and the bound”For model selection “we can use the RMSE (or the negative log-likelihood) to determine the best degree of the polynomial”, and since the degree is a natural number, “we can perform a brute-force search and enumerate all (reasonable) values of .”
For a training set of size it is sufficient to test . For , the maximum likelihood estimator is unique. For , we have more parameters than data points, and would need to solve an underdetermined system of linear equations so that there are infinitely many possible maximum likelihood estimators.
Figure 9.6, reproduced
Section titled “Figure 9.6, reproduced”The book’s setup: training points with and , , against a test set of “200 data points … a linear grid of 200 points in the interval .”
How much does Figure 9.6 actually tell you?
Section titled “How much does Figure 9.6 actually tell you?”Figure 9.6 is a single draw of a random experiment. The obvious question — would another draw give the same answer? — is not one the book asks.
Worked example by hand
Section titled “Worked example by hand”Why does a richer model class have a smaller training error? Prove it, then check the one case where equality can happen.
Step 1: state the claim. Let be the polynomials of degree at most , and . Claim: .
Step 2: the containment. Any can be written in by taking . So .
Step 3: a minimum over a larger set is no larger. If then , because every candidate in is also a candidate in . Hence
No property of polynomials was used — only nesting. The same argument covers adding any feature to any linear model.
Step 4: when is it an equality? Exactly when the extra column buys nothing, i.e. when the optimal is already zero — meaning is orthogonal to the residual of the smaller fit. Measured above at : a change of , nearly but not quite equality.
Step 5: the endpoint. At there is a unique polynomial of degree through distinct points, so the residual is exactly zero and . Measured: , which is zero to conditioning. No further degree can improve on zero, so the bound is not conservatism — it is where the training criterion runs out entirely.
Step 6: read the consequence. A quantity guaranteed to move one way regardless of the truth carries no information about the truth. That is the whole argument for a held-out set — and, from the other direction, for the prior §9.2.3 is about to introduce.
See it move
Section titled “See it move”From scratch
Section titled “From scratch”import numpy as np
SIG = 0.2
NTR = 10
def truth(x):
"""The book's generating function, Example 9.5."""
return -np.sin(x / 5) + np.cos(x)
def design(x, M):
return np.vander(np.asarray(x, float), M + 1, increasing=True)
def train_set(seed):
rng = np.random.default_rng(seed)
x = np.sort(rng.uniform(-5, 5, NTR))
return x, truth(x) + SIG * rng.standard_normal(NTR)
def rmse(a, b):
return float(np.sqrt(np.mean((a - b) ** 2))) # Equation 9.23
# the book's test set: "a linear grid of 200 points in the interval [-5, 5]"
xte = np.linspace(-5, 5, 200)
yte = truth(xte) + SIG * np.random.default_rng(1234).standard_normal(200)
# --- Figure 9.6 ---------------------------------------------------------
print("=== 1. Figure 9.6 reproduced: training and test RMSE ===")
x, y = train_set(4)
print(f"{'M':>4} {'K = M+1':>8} {'training RMSE':>15} {'test RMSE':>12} "
f"{'||theta||':>13}")
tr, te = [], []
for M in range(10):
P = design(x, M)
th = np.linalg.lstsq(P, y, rcond=None)[0]
a, b = rmse(y, P @ th), rmse(yte, design(xte, M) @ th)
tr.append(a); te.append(b)
print(f"{M:>4} {M+1:>8} {a:>15.6f} {b:>12.6f} "
f"{np.linalg.norm(th):>13.4f}")
print(f"\nbest test RMSE at M = {int(np.argmin(te))} ({min(te):.6f})")
# --- the training error never rises -------------------------------------
print("\n=== 2. the training error never increases with M ===")
print(f"{'M-1 -> M':>10} {'change in training RMSE':>26}")
for M in range(1, 10):
print(f"{M-1:>4} -> {M:<3} {tr[M]-tr[M-1]:>26.3e}")
print(f"steps where it went UP: "
f"{sum(1 for M in range(1,10) if tr[M] > tr[M-1])}")
print("a richer class contains the poorer one, so its best fit cannot be")
print("worse ON THE TRAINING SET. A theorem, not an observation.")
# --- the extreme case ----------------------------------------------------
print("\n=== 3. at M = N - 1 the curve passes through every point ===")
for M in (8, 9):
P = design(x, M)
th = np.linalg.lstsq(P, y, rcond=None)[0]
print(f"M = {M}: training RMSE {rmse(y, P @ th):.3e} "
f"test RMSE {rmse(yte, design(xte, M) @ th):>12.4f} "
f"||theta|| {np.linalg.norm(th):.4f}")
# --- past the bound, the estimator is not unique ------------------------
print("\n=== 4. for M >= N there are INFINITELY many estimators ===")
M = 10
P = design(x, M)
th_min = np.linalg.lstsq(P, y, rcond=None)[0]
ns = np.linalg.svd(P)[2][int(np.linalg.matrix_rank(P)):]
print(f"M = {M}, K = {P.shape[1]}, N = {NTR}, "
f"rk(Phi) = {int(np.linalg.matrix_rank(P))}")
print(f"dimension of the null space of Phi: {ns.shape[0]}")
print(f"\n{'estimator':>26} {'training RMSE':>15} {'||theta||':>14}")
print(f"{'minimum-norm (lstsq)':>26} {rmse(y, P @ th_min):>15.3e} "
f"{np.linalg.norm(th_min):>14.6f}")
for c in (1.0, 50.0, 5000.0):
alt = th_min + c * ns[0]
print(f"{' + ' + str(c) + ' * null vector':>26} "
f"{rmse(y, P @ alt):>15.3e} {np.linalg.norm(alt):>14.6f}")
print("all of them fit the training data equally well.")
# --- the RMSE has the units of y ----------------------------------------
print("\n=== 5. RMSE has the units of y; the NLL does not ===")
P = design(x, 4)
print(f"{'scale c on y':>14} {'RMSE':>14} {'RMSE / c':>14} "
f"{'NLL':>16} {'NLL / c':>16}")
for c in (1.0, 10.0, 1000.0):
yc = c * y
r = yc - P @ np.linalg.lstsq(P, yc, rcond=None)[0]
rc = float(np.sqrt(np.mean(r ** 2)))
nll = float(r @ r / (2 * SIG ** 2))
print(f"{c:>14.1f} {rc:>14.6f} {rc/c:>14.6f} {nll:>16.6f} "
f"{nll/c:>16.6f}")
print("RMSE scales exactly with c; the NLL scales with c^2 and carries")
print("sigma^2, so it is not in the units of y at all.")
# --- how stable is 'the best degree is 4'? ------------------------------
print("\n=== 6. how stable is 'the best degree is 4'? ===")
counts = np.zeros(10, dtype=int)
best_te = []
for s in range(2000):
xs, ys = train_set(10_000 + s)
scores = [rmse(yte, design(xte, M)
@ np.linalg.lstsq(design(xs, M), ys, rcond=None)[0])
for M in range(10)]
k = int(np.argmin(scores))
counts[k] += 1
best_te.append(scores[k])
print(f"{'M':>4} {'chosen':>9} {'share':>9}")
for M in range(10):
print(f"{M:>4} {counts[M]:>9} {counts[M]/2000:>8.1%}")
print(f"\nmedian best test RMSE: {np.median(best_te):.6f}")
print(f"the modal choice is M = {int(np.argmax(counts))}")
print("Figure 9.6 is one draw of a random experiment, and the degree it")
print("singles out moves with the draw.")=== 1. Figure 9.6 reproduced: training and test RMSE ===
M K = M+1 training RMSE test RMSE ||theta||
0 1 0.977999 0.893710 0.2135
1 2 0.743590 0.745097 0.2150
2 3 0.590009 0.688459 0.5211
3 4 0.524501 0.785402 0.7584
4 5 0.270626 0.324947 0.9904
5 6 0.270123 0.333082 1.0069
6 7 0.207586 0.473424 1.1985
7 8 0.192473 0.664497 0.9769
8 9 0.160893 7.420601 1.1314
9 10 0.000000 100.850623 4.2030
best test RMSE at M = 4 (0.324947)
=== 2. the training error never increases with M ===
M-1 -> M change in training RMSE
0 -> 1 -2.344e-01
1 -> 2 -1.536e-01
2 -> 3 -6.551e-02
3 -> 4 -2.539e-01
4 -> 5 -5.028e-04
5 -> 6 -6.254e-02
6 -> 7 -1.511e-02
7 -> 8 -3.158e-02
8 -> 9 -1.609e-01
steps where it went UP: 0
a richer class contains the poorer one, so its best fit cannot be
worse ON THE TRAINING SET. A theorem, not an observation.
=== 3. at M = N - 1 the curve passes through every point ===
M = 8: training RMSE 1.609e-01 test RMSE 7.4206 ||theta|| 1.1314
M = 9: training RMSE 6.506e-11 test RMSE 100.8506 ||theta|| 4.2030
=== 4. for M >= N there are INFINITELY many estimators ===
M = 10, K = 11, N = 10, rk(Phi) = 10
dimension of the null space of Phi: 1
estimator training RMSE ||theta||
minimum-norm (lstsq) 5.145e-10 3.441536
+ 1.0 * null vector 4.678e-10 3.583876
+ 50.0 * null vector 1.839e-09 50.118302
+ 5000.0 * null vector 2.342e-07 5000.001184
all of them fit the training data equally well.
=== 5. RMSE has the units of y; the NLL does not ===
scale c on y RMSE RMSE / c NLL NLL / c
1.0 0.270626 0.270626 9.154787 9.154787
10.0 2.706257 0.270626 915.478700 91.547870
1000.0 270.625749 0.270626 9154787.004056 9154.787004
RMSE scales exactly with c; the NLL scales with c^2 and carries
sigma^2, so it is not in the units of y at all.
=== 6. how stable is 'the best degree is 4'? ===
M chosen share
0 65 3.2%
1 226 11.3%
2 153 7.6%
3 1 0.1%
4 921 46.1%
5 152 7.6%
6 417 20.8%
7 56 2.8%
8 9 0.4%
9 0 0.0%
median best test RMSE: 0.418686
the modal choice is M = 4
Figure 9.6 is one draw of a random experiment, and the degree it
singles out moves with the draw.On real data
Section titled “On real data”Reading the plot
Section titled “Reading the plot”The first figure is Figure 9.5 with the numbers the book leaves in its prose. The dashed grey curve is the generating function; each panel’s two figures are its training and test RMSE. Reading down them is the entire lesson: training goes , never once rising, while test goes .
The panel is the one to sit with. The curve passes through all ten points. Its training error is — zero, to conditioning. And its test error is , the worst on the page by a factor of thirteen. A perfect fit and no knowledge, in the same object.
The second figure separates a theorem from an observation. The training curve’s monotonicity is not a pattern that happened to hold on this data. Every degree- polynomial is a degree- polynomial with a zero coefficient, so the larger class’s minimum cannot exceed the smaller’s. It would fall identically for a model that generalises and one that memorises, which is exactly why it carries no information.
The step is the interesting one: . Almost flat — the fifth-degree term buys essentially nothing — but still negative, because the theorem does not permit otherwise.
The right panel is what the training side can tell you. climbs from at the good degree to at . The book’s own sentence in §9.2.3 is “the magnitude of the parameter values becomes relatively large if we run into overfitting”, and it is the entire motivation for the prior on the next page. Interpolating scattered points requires oscillation, and oscillation requires large coefficients — so the fingerprint is visible without a test set.
And one honest deviation from the book’s description. The test error goes up from to — to — before the real minimum at . The book describes the curve as initially decreasing; on this draw it is noisy and roughly U-shaped, and a search that stopped at the first increase would have chosen and been wrong.
The third figure asks a question the book does not, and the answer changes how much Figure 9.6 is worth. Repeat the whole experiment — fresh , fresh noise, same , same test grid — two thousand times, and record which degree wins. wins times: . wins . wins .
So the book’s conclusion is right — is the modal answer and the median best test RMSE is — and it is right the way a coin that lands heads of the time is a reasonable bet, not the way a theorem is right. With ten training points the selection is simply not stable, which is the same -is-too-small boundary page 808 measured from the cross-validation side and page 902 measured in the noise-variance bias.
Note winning once in two thousand draws. The bump in the single-draw table was not an accident of that draw — degree 3 is genuinely poor here, caught between the low degrees that at least capture the trend and the degree-4 fit that finally accommodates the cosine.
The right panel is the bound made visible. At the null space has dimension
one, and the four plotted curves are for
. They all pass through all ten training points, and their norms run from
to . “The maximum likelihood estimator” is no longer a definite article.
np.linalg.lstsq returns the minimum-norm one — a sensible convention, but a convention, not something
the likelihood determined.
Compare
Section titled “Compare”| training error | test error | |
|---|---|---|
| direction as grows | monotone non-increasing, guaranteed | free to do anything |
| at | exactly (measured ) | worst on the page, |
| measured here | ||
| detects underfitting | yes | yes |
| detects overfitting | no | yes |
| needs held-out data | no | yes |
| RMSE, Eq 9.23 | squared error | negative log-likelihood | |
|---|---|---|---|
| units | same as (EUR) | squared (EUR²) | unitless |
| scaling by | |||
| comparable across | yes | no | no |
| contains | no | no | yes |
| vs | ||
| invertible | singular | |
| estimators | exactly one | infinitely many |
what lstsq returns | the estimator | the minimum-norm one, by convention |
| the book’s advice | search | do not go here |
-
The book says the training error never increases as the polynomial degree grows. Why is that guaranteed rather than merely observed?
No property of polynomials is used — only nesting, so the same argument covers adding any feature to any linear model. Measured across nine steps: zero increases, including the near-flat 4 to 5 step at -5.028e-4. And a quantity guaranteed to move one way regardless of the truth carries no information about the truth.
pch.quizShowAnswer
B — Because the degree-M class contains the degree-(M-1) class as the subset with the top coefficient zero, so its minimum cannot be larger — No property of polynomials is used — only nesting, so the same argument covers adding any feature to any linear model. Measured across nine steps: zero increases, including the near-flat 4 to 5 step at -5.028e-4. And a quantity guaranteed to move one way regardless of the truth carries no information about the truth.
-
At M = N - 1 = 9, what are the training and test RMSE?
There is a unique polynomial of degree at most N-1 through N distinct points, so the residual is exactly zero. That is also why the book's search bound stops there: no further degree can improve on zero, so the training criterion has run out entirely.
pch.quizShowAnswer
B — Training 6.5e-11 and test 100.85 — a perfect fit with the worst generalization on the page — There is a unique polynomial of degree at most N-1 through N distinct points, so the residual is exactly zero. That is also why the book's search bound stops there: no further degree can improve on zero, so the training criterion has run out entirely.
-
For M >= N the book says there are infinitely many maximum likelihood estimators. What does that look like concretely?
Measured: four estimators with norms from 3.44 to 5000.00, all fitting the training data to 1e-7 or better. np.linalg.lstsq silently returns the minimum-norm member — a reasonable convention, but a convention, not something the likelihood determined.
pch.quizShowAnswer
B — Phi has a null space — measured dimension 1 at M = 10 — so adding any multiple of a null vector gives another exact fit — Measured: four estimators with norms from 3.44 to 5000.00, all fitting the training data to 1e-7 or better. np.linalg.lstsq silently returns the minimum-norm member — a reasonable convention, but a convention, not something the likelihood determined.
-
The book prefers the RMSE partly because it 'has the same scale and the same units as the observed function values'. How was that checked?
The RMSE scales exactly with c, which is what having the units of y means operationally. The negative log-likelihood scales with c squared and carries sigma squared inside it, so it is unitless — the book's own point about EUR versus EUR squared.
pch.quizShowAnswer
B — By scaling y by c and refitting: RMSE divided by c returns 0.270626 at c = 1, 10 and 1000, while NLL divided by c does not — The RMSE scales exactly with c, which is what having the units of y means operationally. The negative log-likelihood scales with c squared and carries sigma squared inside it, so it is unitless — the book's own point about EUR versus EUR squared.
-
Repeating the whole experiment on 2000 fresh draws, how often does M = 4 come out best?
So the book's conclusion is right the way a coin landing heads 46 percent of the time is a reasonable bet, not the way a theorem is right. With ten training points the selection is simply not stable — the same too-small-N boundary that shows up in the noise-variance bias and in cross-validation standard errors.
pch.quizShowAnswer
B — 46.1 percent — the modal answer, but M = 6 wins 20.8 percent and M = 1 wins 11.3 percent — So the book's conclusion is right the way a coin landing heads 46 percent of the time is a reasonable bet, not the way a theorem is right. With ten training points the selection is simply not stable — the same too-small-N boundary that shows up in the noise-variance bias and in cross-validation standard errors.
-
What is the only sign of overfitting visible without a test set?
Interpolating scattered points requires oscillation between them, and oscillation requires large coefficients. The book's sentence opening Section 9.2.3 is exactly this — 'the magnitude of the parameter values becomes relatively large if we run into overfitting' — and it is the entire motivation for placing a prior on theta.
pch.quizShowAnswer
B — The parameter norm growing — measured 0.9904 at M = 4 and 4.2030 at M = 9 — Interpolating scattered points requires oscillation between them, and oscillation requires large coefficients. The book's sentence opening Section 9.2.3 is exactly this — 'the magnitude of the parameter values becomes relatively large if we run into overfitting' — and it is the entire motivation for placing a prior on theta.
🧪 Try It Yourself
Section titled “🧪 Try It Yourself”Exercise 1 – Rebuild Figure 9.6
Section titled “Exercise 1 – Rebuild Figure 9.6”Exercise 2 – The monotonicity is a theorem
Section titled “Exercise 2 – The monotonicity is a theorem”Exercise 3 – Past the bound, the estimator is not unique
Section titled “Exercise 3 – Past the bound, the estimator is not unique”Exercise 4 – RMSE carries the units of y
Section titled “Exercise 4 – RMSE carries the units of y”Exercise 5 – Is degree 4 really the answer?
Section titled “Exercise 5 – Is degree 4 really the answer?”Pitfalls
Section titled “Pitfalls”Recall card
Section titled “Recall card”- Equation 9.23 is the RMSE: the square root of the mean squared residual. It is comparable across dataset sizes and carries the units of y, while the squared error is in y-squared units and the negative log-likelihood is unitless.
- Measured: scaling y by c multiplies the RMSE by exactly c. Divide back out and you recover 0.270626 at c = 1, 10 and 1000. The NLL scales with c squared and contains sigma squared.
- The training error never increases with M, and that is a theorem from set inclusion: every degree-M polynomial is a degree-(M+1) polynomial with a zero top coefficient. Measured, nine steps and zero increases.
- So the training error carries no information about generalization. It would fall identically for a model that generalises and one that memorises.
- At M = N - 1 the fit is exact. Measured training RMSE 6.5e-11 with a test RMSE of 100.850623 — the worst on the page. A unique polynomial of degree at most N-1 passes through N distinct points.
- The book’s search bound is 0 to N-1, because past it the training criterion has already reached zero and cannot distinguish anything.
- For M at least N the estimator is not unique. Measured at M = 10, N = 10: null space of dimension 1, and four parameter vectors with norms from 3.44 to 5000.00 all fitting the training data to 1e-7 or better. lstsq returns the minimum-norm one by convention.
- Figure 9.6 reproduced: test RMSE bottoms at M = 4 with 0.324947, stays near it at M = 5 with 0.333082, then rises through 0.473, 0.664, 7.42 to 100.85.
- One honest deviation: the test error rises from M = 2 to M = 3 before the real minimum, so the curve is only roughly U-shaped and a first-increase stopping rule fails.
- The parameter norm is the only overfitting warning visible without a test set — 0.9904 at the good degree, 4.2030 at M = 9. Interpolating scattered points requires oscillation, and oscillation requires large coefficients.
- But the norm is a warning, not an ordering. It is non-monotone in the middle of the range; only the jump at M = N-1 is reliable.
- Over 2000 fresh draws of the same experiment, M = 4 wins only 46.1 percent of the time. M = 6 wins 20.8 percent, M = 1 wins 11.3 percent, and the median best test RMSE is 0.418686.
- So Figure 9.6 is one draw of a random experiment. Its conclusion is the modal answer, correct as a tendency and overclaimed as a determination — the same too-small-N boundary Chapter 8 kept arriving at.
Next: act on the parameter norm. MAP Estimation and Regularization
pch.coffeeTagline
pch.coffeeCtapch.feedbackHeading
pch.feedbackSubheading