Save a fitted GAM to a .npz archive.
Serializes everything needed to reconstruct a fitted ~whittaker.gam.GAM for prediction and inference without recomputing basis fits or re-running P-IRLS. Use this to persist a model between sessions, ship a fitted model to another machine, or cache an expensive fit. The archive is a standard numpy .npz file (produced with numpy.savez_compressed) and can, in principle, be inspected with numpy.load alone, though load_gam is the supported way to read it back.
Internally the archive stores two kinds of data under one file:
- A single JSON-encoded metadata blob under the key
"__metadata__", containing the formula (response, intercept flag, and each term), the family (class name and any extra parameters such as a Tweedie power or negative-binomial dispersion), fit statistics (smoothing parameters, scale, GCV score, EDF, deviance, iteration count, convergence flag, AIC/BIC, etc.), model-matrix metadata (column names, intercept/parametric counts, offset expressions), and, per smooth term, its formula term, coefficient column range, null-space dimension, penalty indices, and basis state (attribute values of the fitted ~whittaker.smooths.base.SmoothBasis).
- Raw
numpy arrays stored alongside the metadata: coefficients, linear_predictor, fitted_values, residuals, the training design matrix X, the response vector, and, when present, weights, prior_weights, pseudo_data, and offset. Each smooth’s penalty matrix is stored as penalty_{i} (one array per penalty block, in the order the smooths contribute penalties). Any array-valued attribute of a smooth’s fitted basis (e.g. knot locations, training covariate values) is stored under a key of the form smooth_{idx}_basis_{attr} (or smooth_{idx}_basis_{attr}_{subkey} for nested dict attributes), with a {"__ndarray__": key} pointer left in the metadata blob so load_gam can find it.
Note that the archive has no explicit format-version field: there is currently no mechanism to detect or migrate across schema changes, so a saved archive is only guaranteed to load correctly with a whittaker version compatible with the one that wrote it.
Parameters
model: GAM
-
A fitted ~whittaker.gam.GAM instance, i.e. one on which fit() has already been called.
path: str or pathlib.Path
-
Output file path.
numpy.savez_compressed appends a .npz extension automatically if the given path does not already end in one.
Raises
TypeError
-
If model is not a GAM instance.
RuntimeError
-
If
model has not been fitted (model.is_fitted is False).
Examples
import numpy as np
import whittaker as wt
from whittaker.io import save_gam, load_gam
rng = np.random.default_rng(0)
x = np.sort(rng.uniform(0, 1, 200))
y = np.sin(2 * np.pi * x) + rng.normal(scale=0.2, size=200)
model = wt.GAM("y ~ s(x)").fit({"x": x, "y": y})
save_gam(model, "gam_model.npz")
reloaded = load_gam("gam_model.npz")
new_x = np.linspace(0, 1, 5)
np.allclose(
model.predict({"x": new_x}).values,
reloaded.predict({"x": new_x}).values,
)