import whittaker as wk
# Load data and fit with each smoothing method
data = wk.load_dataset("mcycle")
model_reml = wk.GAM("accel ~ s(times)").fit(data, method="REML")
model_gcv = wk.GAM("accel ~ s(times)").fit(data, method="GCV")
model_ml = wk.GAM("accel ~ s(times)").fit(data, method="ML")Choose a Smoothing Method
The smoothing method controls how the penalty strength λ is selected during fitting. A well-chosen λ balances the fidelity of the smooth to the data against its wiggliness. Whittaker offers three methods: REML (the default), GCV, and ML. All three produce a fitted model but they differ in their statistical criterion and their tendency to over or undersmooth.
Fit with each method
The method argument is passed to fit(). The dataset is mcycle, which deals with head acceleration over time during a simulated crash.
Smoothing parameters
Each fitted model exposes smoothing_params: the selected λ values (one per smooth). A larger λ compresses the smooth toward a straight line; a smaller λ allows more wiggle. Compare the value selected by each method.
# REML
model_reml.smoothing_params[0]266.83963427768026
# GCV
model_gcv.smoothing_params[0]371.6516581290851
# ML
model_ml.smoothing_params[0]266.83963427768026
GCV often selects a smaller λ than REML, meaning it allows a wigglier smooth. REML and ML tend to be closer to each other.
Effective degrees of freedom
edf measures the wiggliness of each smooth: higher EDF means more curvature. Lower means more compression toward a line. Check how much each method differs.
# REML
model_reml.edf[0]8.151247447768561
# GCV
model_gcv.edf[0]7.915324259501651
# ML
model_ml.edf[0]8.151247447768561
Small differences in EDF across methods are normal. Large differences (more than a unit or two) suggest the criterion matters for this dataset and REML is usually the safer choice.
Full summaries
Read the full summaries to compare deviance explained, GCV score, and AIC across methods.
model_reml.summary()GAM fit summary
============================================================
Formula: accel ~ s(times)
Family: Gaussian(link='identity')
Inference: REML
Observations: 133
Coefficients: 10
Parametric coefficients:
Term Estimate Std.Err t value p-value
------------------------ ---------- ---------- ---------- ----------
(Intercept) -45.6924 1.8352 -24.898 < 1e-16
Approximate significance of smooth terms:
Term EDF Ref.df Chi.sq p-value
------------------------ ------ ------ ---------- ----------
s(times) 8.15 9 667.987 < 1e-16
Total EDF: 9.15
Scale est: 447.915129
Deviance: 55473.7300
Null dev: 357878.4929
Dev. expl: 84.5%
GCV score: 481.011806
AIC: 1198.50
BIC: 1224.95
model_gcv.summary()GAM fit summary
============================================================
Formula: accel ~ s(times)
Family: Gaussian(link='identity')
Inference: GCV
Observations: 133
Coefficients: 10
Parametric coefficients:
Term Estimate Std.Err t value p-value
------------------------ ---------- ---------- ---------- ----------
(Intercept) -45.6924 1.8364 -24.882 < 1e-16
Approximate significance of smooth terms:
Term EDF Ref.df Chi.sq p-value
------------------------ ------ ------ ---------- ----------
s(times) 7.92 8 663.379 < 1e-16
Total EDF: 8.92
Scale est: 448.520495
Deviance: 55654.5201
Null dev: 357878.4929
Dev. expl: 84.4%
GCV score: 480.746115
AIC: 1198.44
BIC: 1224.21
model_ml.summary()GAM fit summary
============================================================
Formula: accel ~ s(times)
Family: Gaussian(link='identity')
Inference: ML
Observations: 133
Coefficients: 10
Parametric coefficients:
Term Estimate Std.Err t value p-value
------------------------ ---------- ---------- ---------- ----------
(Intercept) -45.6924 1.8352 -24.898 < 1e-16
Approximate significance of smooth terms:
Term EDF Ref.df Chi.sq p-value
------------------------ ------ ------ ---------- ----------
s(times) 8.15 9 667.987 < 1e-16
Total EDF: 9.15
Scale est: 447.915129
Deviance: 55473.7300
Null dev: 357878.4929
Dev. expl: 84.5%
GCV score: 481.011806
AIC: 1198.50
BIC: 1224.95
Comparison table
| Method | Criterion | Tendency | When to use |
|---|---|---|---|
| REML | Restricted maximum likelihood | Balanced; slightly conservative | Default, most datasets |
| GCV | Generalized cross-validation | Can undersmooth (too wiggly) | Quick exploration, large n |
| ML | Maximum likelihood | Similar to REML, no correction for fixed effects | Comparing models with different fixed-effect structures |
Rule of thumb
It’s often good to use REML unless you have a specific reason to switch to something else. GCV is a reasonable alternative for large datasets where speed matters and mild undersmoothing is acceptable. Use ML only when you need to compare models that differ in their parametric (non-smooth) terms. ML (unlike REML) produces a likelihood that is directly comparable across such models.