Predict on New Data

Generate fitted values for any set of covariate values after fitting.

Once a GAM is fitted, predict() accepts any dict mapping predictor names to arrays of new covariate values. There is no need to refit. You can evaluate the model at a fine grid, at held-out observations, or at arbitrary hypothetical inputs.

Fit

Start with the mcycle dataset and a single-smooth Gaussian GAM.

import whittaker as wk

# Load mcycle dataset
data = wk.load_dataset("mcycle")

# Fit single-smooth Gaussian GAM
model = wk.GAM("accel ~ s(times)").fit(data)
model.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

Predict on a grid

Build a 200-point grid covering the full range of times, then call predict().

import numpy as np

# Build 200-point grid over full time range
grid = {"times": np.linspace(0, 57.6, 200)}

# Predict acceleration on the grid
preds = model.predict(grid)
preds.values[:5].round(2)
array([3.27, 4.18, 5.08, 5.97, 6.83])

The first five fitted values show the smooth near the start of the time range. To see the full spread, check the minimum and maximum of the predictions.

preds.values.min(), preds.values.max()
(np.float64(-122.67436599182616), np.float64(11.786547134320472))

The predicted range spans a wide swath of acceleration values, reflecting the sharp impulse captured by the smooth. A fine grid like this is also useful for plotting a smooth curve through the data.

Multiple columns

When the formula has more than one predictor, every predictor named in the formula must appear in the new-data dict. The wages dataset demonstrates this with two predictors, age and experience.

# Load wages data and fit two-predictor GAM
wages_data = wk.load_dataset("wages")
wages_model = wk.GAM("wage ~ s(age) + s(experience)").fit(wages_data)

Pass both predictors together. Each position in the arrays corresponds to one new observation.

# Build new-data with paired age and experience values
new_data = {
    "age": np.array([25, 35, 45, 55]),
    "experience": np.array([2, 8, 15, 25]),
}

# Predict wages at new covariate values
preds_wages = wages_model.predict(new_data)
preds_wages.values.round(2)
array([18.86, 38.75, 60.36, 75.58])

Omitting any predictor named in the formula raises an error, so the dict must be complete even if you are only interested in varying one variable.