# Cookbook

The Whittaker Cookbook is filled with short and self-contained recipes that try to answer one question at a time. Every recipe is fully executable so you can copy the code and run it easily in your own environment.


# Getting started

Start here if you are new to Whittaker. These recipes cover the core workflow: fitting a model, picking the right response distribution, and reading the output.


<a href="../cookbook/fit-your-first-smooth.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Fit Your First Smooth


Go from raw data to a fitted GAM and a model summary in five lines.


<a href="../cookbook/fit-your-first-smooth.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


<a href="../cookbook/choose-a-response-family.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Choose a Response Family


Pick the right distribution for your outcome variable: Gaussian, Poisson, Binomial, and more.


<a href="../cookbook/choose-a-response-family.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


<a href="../cookbook/read-the-model-summary.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Read the Model Summary


Understand EDF, significance tests, and fit statistics at a glance.


<a href="../cookbook/read-the-model-summary.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


# Smooth terms

The smooth term (its basis type, basis dimension, and interaction structure) is the main modeling decision in a GAM. These recipes cover the most useful smooth types and how to configure them.


<a href="../cookbook/fit-a-thin-plate-regression-spline.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Fit a Thin Plate Regression Spline


Understand the default smooth basis and when to use it.


<a href="../cookbook/fit-a-thin-plate-regression-spline.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


<a href="../cookbook/control-basis-dimension.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Control Basis Dimension with k


Choose k large enough to avoid underfitting, then let REML handle the rest.


<a href="../cookbook/control-basis-dimension.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


<a href="../cookbook/fit-a-cyclic-smooth.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Fit a Cyclic Smooth to Seasonal Data


Use bs='cc' to model a periodic pattern without discontinuities at the boundary.


<a href="../cookbook/fit-a-cyclic-smooth.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


<a href="../cookbook/add-a-tensor-product.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Add a Tensor Product for Two Predictors


Model the joint nonlinear effect of two predictors, including their interaction, with te().


<a href="../cookbook/add-a-tensor-product.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


<a href="../cookbook/use-a-by-variable-smooth.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Use a By-Variable Smooth


Fit a separate smooth curve per group without assuming the groups share the same shape.


<a href="../cookbook/use-a-by-variable-smooth.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


<a href="../cookbook/add-a-random-effect.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Add a Random Effect


Account for repeated-measures clustering with s(group, bs='re').


<a href="../cookbook/add-a-random-effect.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


<a href="../cookbook/fit-a-spatial-smooth.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Fit a Spatial Smooth with a Tensor Product


Use te(x, y) to capture two-dimensional spatial autocorrelation over a geographic field.


<a href="../cookbook/fit-a-spatial-smooth.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


# Response families

The response family determines the assumed distribution of your outcome and the link function that connects it to the linear predictor. These recipes show how to handle counts, binary outcomes, and proportions (the most common departures from a Gaussian response).


<a href="../cookbook/model-count-data-with-poisson.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Model Count Data with Poisson


Fit a GAM when the response is a non-negative integer count, such as events per interval.


<a href="../cookbook/model-count-data-with-poisson.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


<a href="../cookbook/model-binary-outcomes-with-binomial.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Model Binary Outcomes with Binomial


Fit a logistic GAM for 0/1 responses. Predictions come back as probabilities.


<a href="../cookbook/model-binary-outcomes-with-binomial.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


<a href="../cookbook/model-skewed-positive-data-with-gamma.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Model Skewed Positive Data with Gamma


Use the Gamma family for right-skewed continuous responses such as wages, costs, or durations.


<a href="../cookbook/model-skewed-positive-data-with-gamma.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


<a href="../cookbook/handle-overdispersed-counts-with-negative-binomial.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Handle Overdispersed Counts with Negative Binomial


Switch from Poisson to NegativeBinomial when residual deviance greatly exceeds residual df.


<a href="../cookbook/handle-overdispersed-counts-with-negative-binomial.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


<a href="../cookbook/model-proportions-with-beta.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Model Proportions with Beta


Fit a Beta GAM for responses bounded strictly between 0 and 1, such as rates or fractions.


<a href="../cookbook/model-proportions-with-beta.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


<a href="../cookbook/estimate-a-survival-curve-with-cox-ph.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Estimate a Survival Curve with Cox PH


Model time-to-event data with right censoring using the Cox proportional hazards family.


<a href="../cookbook/estimate-a-survival-curve-with-cox-ph.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


# Prediction and inference

A fitted GAM is most useful when you can generate predictions at new inputs and attach uncertainty estimates. These recipes cover point predictions, standard errors, and several flavors of confidence interval.


<a href="../cookbook/predict-on-new-data.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Predict on New Data


Generate fitted values for any set of covariate values after fitting (grids, held-out rows, or hypothetical inputs).


<a href="../cookbook/predict-on-new-data.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


<a href="../cookbook/get-confidence-intervals.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Get Confidence Intervals


Add pointwise, simultaneous, or prediction-interval uncertainty bands to any set of predictions.


<a href="../cookbook/get-confidence-intervals.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


<a href="../cookbook/get-simultaneous-confidence-bands.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Get Simultaneous Confidence Bands


Get bands that jointly cover the whole fitted curve at 95%, not just each point in isolation.


<a href="../cookbook/get-simultaneous-confidence-bands.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


<a href="../cookbook/get-prediction-intervals.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Get Prediction Intervals


Bound individual future observations, not just the conditional mean, with prediction intervals.


<a href="../cookbook/get-prediction-intervals.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


<a href="../cookbook/extract-term-level-contributions.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Extract Term-Level Contributions


Decompose a prediction into each smooth's individual contribution to the linear predictor.


<a href="../cookbook/extract-term-level-contributions.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


<a href="../cookbook/predict-on-the-link-scale.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Predict on the Link Scale


Get linear predictor values instead of back-transformed response-scale predictions.


<a href="../cookbook/predict-on-the-link-scale.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


# Diagnostics and model selection

Before trusting a model's predictions you should verify that it is well-specified. These recipes walk through basis dimension checks, residual analysis, and how to choose a smoothness selection criterion.


<a href="../cookbook/check-basis-dimension.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Check Basis Dimension Adequacy


Verify that k is large enough to capture the true shape using the k-index diagnostic.


<a href="../cookbook/check-basis-dimension.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


<a href="../cookbook/inspect-residuals.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Inspect Residuals


Plot deviance residuals and the QQ plot to spot patterns that signal a poor model fit.


<a href="../cookbook/inspect-residuals.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


<a href="../cookbook/compare-models-with-aic.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Compare Models with AIC


Rank nested or non-nested models by AIC to balance fit quality against model complexity.


<a href="../cookbook/compare-models-with-aic.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


<a href="../cookbook/cross-validate-a-gam.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Cross-Validate a GAM


Get an honest out-of-sample estimate of predictive performance using k-fold cross-validation.


<a href="../cookbook/cross-validate-a-gam.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


<a href="../cookbook/choose-a-smoothing-method.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Choose a Smoothing Method


Compare REML, GCV, and ML smoothness selection and know when each is the right choice.


<a href="../cookbook/choose-a-smoothing-method.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


<a href="../cookbook/use-select-smoothing.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Use Select Smoothing to Shrink Away a Term


Add an extra penalty so irrelevant smooth terms can shrink completely to zero during fitting.


<a href="../cookbook/use-select-smoothing.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


# Shape constraints

Shape-constrained smooths enforce monotone or convex behavior when domain knowledge demands it. Use them to make a GAM obey known physical constraints while still fitting the data nonparametrically.


<a href="../cookbook/fit-a-monotone-increasing-smooth.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Fit a Monotone Increasing Smooth


Constrain a smooth to be non-decreasing with bs='mpi' when the response must rise with the predictor.


<a href="../cookbook/fit-a-monotone-increasing-smooth.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


<a href="../cookbook/fit-a-monotone-decreasing-smooth.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Fit a Monotone Decreasing Smooth


Constrain a smooth to be non-increasing with bs='mpd' to model effects that can only fall.


<a href="../cookbook/fit-a-monotone-decreasing-smooth.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


<a href="../cookbook/fit-a-convex-smooth.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Fit a Convex Smooth


Enforce bowl-shaped curvature with bs='cx' for responses that have a known convex structure.


<a href="../cookbook/fit-a-convex-smooth.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


# Data input

Whittaker accepts Pandas DataFrames, Polars DataFrames, PyArrow Tables, plain dicts, and NumPy arrays interchangeably. This section shows how to work with data formats you may already have on hand, including how to account for exposure with an offset term.


<a href="../cookbook/use-a-polars-dataframe.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Use a Polars DataFrame


Pass a Polars DataFrame directly to fit() without converting to NumPy or pandas first.


<a href="../cookbook/use-a-polars-dataframe.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


<a href="../cookbook/use-a-pyarrow-table.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Use a PyArrow Table


Pass a PyArrow Table directly to fit(): Narwhals handles the conversion transparently.


<a href="../cookbook/use-a-pyarrow-table.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


<a href="../cookbook/use-an-offset-term-for-exposure.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Use an Offset Term for Exposure


Model rates instead of raw counts by fixing log(exposure) as an offset in a Poisson formula.


<a href="../cookbook/use-an-offset-term-for-exposure.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


# Advanced models

These recipes cover specialized GAM extensions for structured problems: heteroscedastic responses, zero-inflated counts, quantile and conformal inference, causal estimation, multiple correlated responses, functional predictors, and online learning.


<a href="../cookbook/model-location-and-scale-together.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Model Location and Scale Together (GAMLSS)


Fit both the mean and variance as smooth functions of covariates using a Gaussian location-scale model.


<a href="../cookbook/model-location-and-scale-together.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


<a href="../cookbook/model-zero-inflated-counts.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Model Zero-Inflated Counts


Handle excess zeros with a zero-inflated Poisson model and separate mean and zero-probability smooths.


<a href="../cookbook/model-zero-inflated-counts.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


<a href="../cookbook/fit-quantile-regression.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Fit Quantile Regression


Estimate multiple quantile curves simultaneously using a smooth quantile GAM.


<a href="../cookbook/fit-quantile-regression.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


<a href="../cookbook/enforce-non-crossing-quantiles.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Enforce Non-Crossing Quantiles


Prevent quantile curves from crossing by enabling the isotonic non-crossing constraint.


<a href="../cookbook/enforce-non-crossing-quantiles.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


<a href="../cookbook/build-conformal-prediction-intervals.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Build Conformal Prediction Intervals


Construct distribution-free prediction intervals with guaranteed coverage using split conformal prediction.


<a href="../cookbook/build-conformal-prediction-intervals.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


<a href="../cookbook/estimate-an-average-treatment-effect.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Estimate an Average Treatment Effect


Use a partially linear GAM to estimate a causal ATE while controlling for confounders nonparametrically.


<a href="../cookbook/estimate-an-average-treatment-effect.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


<a href="../cookbook/estimate-heterogeneous-treatment-effects.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Estimate Heterogeneous Treatment Effects (CATE)


Estimate how treatment effects vary with individual characteristics using an interactive causal GAM.


<a href="../cookbook/estimate-heterogeneous-treatment-effects.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


<a href="../cookbook/fit-a-multi-response-gam.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Fit a Multi-Response GAM


Model multiple correlated responses simultaneously with a shared covariate structure.


<a href="../cookbook/fit-a-multi-response-gam.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


<a href="../cookbook/fit-a-functional-covariate.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Fit a Functional Covariate


Model how a scalar response depends on an entire observed curve using a functional GAM.


<a href="../cookbook/fit-a-functional-covariate.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


<a href="../cookbook/update-a-streaming-gam-incrementally.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Update a Streaming GAM Incrementally


Fit a GAM online by calling partial_fit() on successive data batches, then solve() to update the model.


<a href="../cookbook/update-a-streaming-gam-incrementally.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


# Large datasets

When data is too large to hold in memory, these approaches fit the same smooth models without materializing the full design matrix (using discretization, DuckDB, or Polars streaming).


<a href="../cookbook/fit-a-biggam-on-a-large-dataframe.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Fit a BigGAM on a Large DataFrame


Use BigGAM to fit a smooth model on millions of rows without materializing the full design matrix.


<a href="../cookbook/fit-a-biggam-on-a-large-dataframe.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


<a href="../cookbook/query-with-duckdb-and-fit-in-database.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Query with DuckDB and Fit In-Database


Fit a GAM directly on data held in DuckDB without loading it into Python memory.


<a href="../cookbook/query-with-duckdb-and-fit-in-database.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


<a href="../cookbook/stream-a-polars-lazyframe.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Stream a Polars LazyFrame


Fit a GAM on a Polars LazyFrame, deferring data loading until fit time.


<a href="../cookbook/stream-a-polars-lazyframe.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


# Deployment

Once a model is fit, you will often need to persist it, share it, or work with it in an existing ML pipeline. These recipes cover serialization, scikit-learn compatibility, and R interoperability.


<a href="../cookbook/save-and-load-a-model.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Save and Load a Fitted Model


Persist a fitted model to disk with save_gam() and restore it for inference with load_gam().


<a href="../cookbook/save-and-load-a-model.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


<a href="../cookbook/use-in-sklearn-pipeline.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Use a GAM in a scikit-learn Pipeline


Wrap a GAM in a Pipeline for cross-validation and grid search using the sklearn-compatible estimators.


<a href="../cookbook/use-in-sklearn-pipeline.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


<a href="../cookbook/export-a-model-to-r-mgcv-format.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>


Export a Model to R's mgcv Format


Convert a fitted whittaker GAM to an mgcv-compatible dict for cross-language interoperability with R.


<a href="../cookbook/export-a-model-to-r-mgcv-format.html" style="display: block; padding: 1.25rem 1.5rem; color: inherit; text-decoration: none;"></a>
