Generalized Additive Models › Example
Machine Learning from ScratchAll chapters Generalized Additive Models › ExampleSection view · Sections in this chapter6 / 10 ↓
Reading tools Definitions, links & notes
Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.
Article links
Make inline references clickable
The formula above is compact, but the algebra inside the penalized solve deserves to be seen once by hand. We now work through a tiny example where every matrix can be written out in full, using a deliberately small basis so the arithmetic stays readable. The lesson generalizes directly to cubic B-splines with many more knots; only the numbers change.
Suppose we have three points and responses . On the domain , place knots at , , and , giving three linear hat functions:
Evaluating these at our three values gives the basis matrix
We will add an intercept column as the first column, so the full design becomes
The coefficient vector is with the intercept and giving the smooth.
The unpenalized normal-equation quantities are
These come from the same rules as OLS: each entry of is a dot product of two columns of , and each entry of is a dot product of a column of with the response. If we stopped here we would just be doing OLS on the basis expansion, flexible in principle, but with no safeguard against a wiggly fit. The penalty is what adds that safeguard.
The penalty comes next. Our smooth has three coefficients, so the second-difference matrix has row, . The full penalty matrix has a zero row and column for the intercept (the intercept is not penalized) and in the smooth block:
Take . The penalized system is
with
Now compare the matrix above with the unpenalized . The off-diagonal entries (the and entries) are the change produced by the penalty. Those couplings come from second coefficient differences; they are the mechanism by which curvature is made expensive.
The displayed four-parameter system is still singular: the three hat functions sum to one, so their constant direction duplicates the intercept. Complete the fit by requiring the smooth to sum to zero at the three observations. Its constraint row is . We solve the normal equations and that constraint together, using a Lagrange multiplier (an extra unknown that enforces the constraint).
PythonIn [11]Expand
toy_B = np.array(
[[1.0, 0.8, 0.2, 0.0], [1.0, 0.0, 1.0, 0.0], [1.0, 0.0, 0.2, 0.8]]
)
toy_y = np.array([1.2, 2.0, 1.5])
toy_d = np.array([[0.0, 1.0, -2.0, 1.0]])
toy_P = toy_d.T @ toy_d
toy_A = toy_B.T @ toy_B + 0.1 * toy_P
toy_c = np.array([0.0, 0.8, 1.4, 0.8])
toy_system = np.block(
[[toy_A, toy_c[:, None]], [toy_c[None, :], np.zeros((1, 1))]]
)
toy_beta = np.linalg.solve(toy_system, np.r_[toy_B.T @ toy_y, 0.0])[:4]
toy_predictions = toy_B @ toy_beta
assert np.allclose(toy_c @ toy_beta, 0.0)ConsoleOut [12]Expand
Constrained coefficients: [ 1.5667 -0.3832 0.2237 -0.0082] Fitted responses: [1.3048 1.7903 1.6048] Squared error: 0.065947
The intercept is the sample response mean because the fitted smooth is centered. The fitted responses no longer interpolate all observations at this positive penalty.
If we now think about the extreme choices:
- With we recover the unpenalized fit, which on these three points fits every observation exactly (because the design, once the smooth is constrained by identifiability, leaves enough freedom to interpolate all three points), including any noise.
- With the penalty forces , meaning the fitted curve is exactly a straight line (a linear trend in the hat basis).
- For intermediate (here ) the fit is a compromise that follows the data closely without allowing spurious curvature.
Both fits use a quadratic penalty, but a difference penalty couples neighboring coefficients, whereas ordinary ridge penalizes coefficient magnitudes. Their common normal-equation structure explains the connection. The next chapter Ridge Regularization (L2 Regularization) develops the ridge view of the penalty in more depth.
The worked example shows the arithmetic. The more important question is whether we can recover the sinusoid and the quadratic from the earlier synthetic data. That is what we implement next.
Comments
Add to the conversation
A question, a correction, or an example from your own work.
No comments yet. Be the first to share your thoughts!