Generalized Additive Models › Practical Implications

Michael BrenndoerferOctober 25, 20266 min read
Machine Learning from ScratchAll chapters
Part 5 of 15Linear and Generalized Linear Models
Chapter 39Generalized Additive Models › Practical Implications
Reading section 8 of 10 · Practical Implications · 6 minSection 8 of 10 · 6 min

Section 8 of 10 · 6 min read

Generalized Additive Models › Practical ImplicationsSection view · Sections in this chapter8 / 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

Notes & comments

Fitting and choosing smoothness without leakage

The smoothing parameter λ\lambda is a hyperparameter. Choose it by scoring fits on observations excluded from fitting those coefficients. An untouched test set then assesses the selected procedure. For dependent observations, choose folds that match the generalization question. To evaluate transfer to unseen subjects, keep each subject in one fold. Forecasting requires a temporal split that matches deployment, including forecasting within already observed subjects when that is the target. Random folds below are appropriate for our independently generated observations.

The basis belongs inside that procedure too. Patsy's bs and statsmodels' BSplines can learn interior knot positions from training-predictor quantiles. Constructing that basis before splitting gives the fit information about validation inputs. That is a leakage path, although the size and direction of its effect on a score depend on the problem. Keep the fitted knot specification and training centering transformation, then reuse them on validation, test, and production rows. Our synthetic bounds [−3,3][-3,3] were fixed by the data-generation design; these are not estimated from held-out inputs. Both libraries' B-spline transforms reject points outside their boundary knots rather than silently performing polynomial extrapolation.

We use five folds and a predeclared grid of nine smoothing parameters. Each fold constructs its own basis and centering constraint using only that fold's training rows. The fold errors are averaged to select a shared λ\lambda for the two components. A separate synthetic test sample is generated only after selection, then scored once. The earlier full-sample component plots illustrate fitting; their training RMSE does not select the winning parameter.

PythonIn [25]
CollapseExpand
cv_lambdas = np.logspace(-4, 4, 9)
folds = np.array_split(np.random.default_rng(24).permutation(n), 5)
cv_mse = np.empty(len(cv_lambdas))
for a, lam in enumerate(cv_lambdas):
    fold_errors = []
    for validation_rows in folds:
        training_rows = np.setdiff1d(np.arange(n), validation_rows)
        _, _, fold_beta, fold_infos, fold_Q = fit_additive_gam(
            [x1[training_rows], x2[training_rows]], y[training_rows], lam=lam
        )
        validation_design = prediction_design(
            [x1[validation_rows], x2[validation_rows]], fold_infos, fold_Q
        )
        fold_errors.append(
            np.mean((y[validation_rows] - validation_design @ fold_beta) ** 2)
        )
    cv_mse[a] = np.mean(fold_errors)
selected_lambda = cv_lambdas[np.argmin(cv_mse)]
_, _, selected_beta, selected_infos, selected_Q = fit_additive_gam(
    [x1, x2], y, lam=selected_lambda
)
test_rng = np.random.default_rng(17)
test_X = test_rng.uniform(-3.0, 3.0, (120, 2))
test_y = (
    1.0
    + np.sin(test_X[:, 0])
    + 0.5 * test_X[:, 1] ** 2
    - 0.5 * test_X[:, 1]
    + test_rng.normal(0.0, 0.4, len(test_X))
)
test_design = prediction_design(
    [test_X[:, 0], test_X[:, 1]], selected_infos, selected_Q
)
test_rmse = np.sqrt(np.mean((test_y - test_design @ selected_beta) ** 2))
ConsoleOut [26]
CollapseExpand
Smoothing grid: [1.e-04 1.e-03 1.e-02 1.e-01 1.e+00 1.e+01 1.e+02 1.e+03 1.e+04]
Cross-validation RMSE: [0.3896 0.3895 0.3891 0.387  0.3833 0.3852 0.4813 0.9822 1.3658]
Selected lambda: 1
Independent synthetic test RMSE: 0.3698

The reported test RMSE describes this one synthetic sample from the stated generating model. It is not evidence that GAMs will attain that error on another dataset. A separate λj\lambda_j per smooth allows different flexibility across predictors, at the cost of a larger tuning problem. Sharing a parameter is a simplifying restriction here, not a universal GAM default.

For a Gaussian linear smoother, generalized cross-validation (GCV) offers another selection criterion: GCV=n∥y−y^∥2/(n−tr⁡H)2\mathrm{GCV}=n\|\mathbf{y}-\hat{\mathbf{y}}\|^2/(n-\operatorname{tr}\mathbf{H})^2, provided the denominator is nonzero. Here nn is the training-sample size and tr⁡H\operatorname{tr}\mathbf{H} is the total effective degrees of freedom for that fixed basis and penalty. GCV approximates leave-one-out assessment by replacing individual leverage values with their average; it is not identical to every held-out split. Packages also provide likelihood-based smoothness selection methods. Choose a criterion that respects the data structure and evaluation question.

For a dense implementation with qq identifiable coefficients and nn rows, forming the cross-product matrix costs O(nq2)O(nq^2) and a direct solve costs O(q3)O(q^3), with O(nq+q2)O(nq+q^2) storage when the design is retained. Within a fixed fold, the basis and its cross-products can be reused across smoothing candidates. For non-Gaussian models fitted by IRLS, each iteration solves a weighted penalized system; runtime and convergence depend on the data and link. Effective degrees of freedom describe model flexibility; neither their size nor training RMSE alone diagnoses generalization.

Component interpretation, interactions, and limitations

Our constraint makes each fitted component average zero over its training observations, so the intercept and smooths have a specified reference. At two values of xjx_j, the difference in f^j\hat f_j gives the change in the fitted additive predictor while the other inputs are held fixed. With an identity link, a rise of 0.50.5 corresponds to a 0.50.5 increase in the fitted conditional mean. With a logit link it multiplies fitted odds by e0.5≈1.65e^{0.5}\approx1.65; with a log link it multiplies the fitted mean by that factor. It does not imply an additive change of 0.50.5 in probability for a logit GAM. On the response scale, a nonlinear inverse link also makes the size of a mean change depend on the other predictors' values.

Component curves describe fitted associations. Interpreting them as causal effects needs additional identification assumptions and a design that supports those assumptions. Correlation between inputs can limit which combinations the data support. Concurvity is the more specific problem in which a smooth term can be approximated by other model terms: it can make the allocation among fitted components unstable even when total predictions look adequate. Exact overlap in unpenalized directions can leave a model unidentifiable despite centering. Check supported predictor combinations and basis conditioning before interpreting a component in isolation.

Inspect residuals for patterns involving pairs of predictors, then compare a plausible interaction model using the same validation protocol. Residual plots can suggest a failure of additivity; absence of a visible pattern does not prove additivity. A tensor-product term fjk(xj,xk)f_{jk}(x_j,x_k) starts from the row-wise products of two marginal bases. Before constraints, it has KjKkK_jK_k coefficients: two 12-function bases give 144 products. Identifiability constraints and removal of overlapping main-effect directions can reduce that count. The interaction needs its own penalties and evidence that the added flexibility helps. There are p(p−1)/2p(p-1)/2 possible pairs, so domain knowledge can help limit the candidates.

Boundary regions often contain less information than the interior. The displayed example has known finite support; production data need explicit handling of out-of-domain inputs and monitoring for distribution shifts. Natural cubic splines impose linear tails, whereas the B-spline transforms used here refuse points beyond their boundary knots. Neither policy establishes that predictions beyond observed support are reliable. Rebuilding a basis on a new training window changes the fitted model and requires validation again.

For uncertainty, component intervals require a covariance calculation matched to the fitted likelihood, penalty, and centering convention. The fixed-smoothing Gaussian covariance given earlier is one such conditional calculation. It omits smoothing-selection uncertainty and does not turn an association into a causal effect. These limits matter when a curve is used to explain a prediction as well as when it is used for inference.

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!

Newsletter

Stay up to date

Get new articles, book updates, and notes on AI and technology.

Unsubscribe at any time. Privacy policy