# 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](../reference/CausalGAM.md#whittaker.CausalGAM.method) argument is passed to `fit()`. The dataset is `mcycle`, which deals with head acceleration over time during a simulated crash.


``` python
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")
```


# 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.


``` python
# REML
model_reml.smoothing_params[0]
```


    266.83963427768026


``` python
# GCV
model_gcv.smoothing_params[0]
```


    371.6516581290851


``` python
# 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.


``` python
# REML
model_reml.edf[0]
```


    8.151247447768561


``` python
# GCV
model_gcv.edf[0]
```


    7.915324259501651


``` python
# 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.


``` python
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


``` python
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


``` python
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.
