Next-generation GAMs for Python: flexible smoothing, principled inference, beautiful output.
What is Whittaker?
Whittaker is a Python library for Generalized Additive Models (GAMs), the flexible regression models that replace rigid linear assumptions with smooth, data-driven functions. Whether you're fitting a dose-response curve, modeling spatial patterns, or building prediction intervals, Whittaker gives you the smooth catalog, inference machinery, and diagnostic tools to do it right!
Why Whittaker?
- it works with your dataframe library: Pandas, Polars, PyArrow, or anything supported by Narwhals
- it gives you the full smooth catalog from R's mgcv: thin plate regression splines, cubic splines, P-splines, tensor products, cyclic splines, random effects, factor smooths, and more
- smoothness selection is principled: REML by default, with GCV, ML, and fREML as alternatives
- you get beautiful, interactive plots: partial effects, diagnostics, term comparisons, and prediction intervals, all powered by Altair
- it goes well beyond the mean: distributional regression (GAMLSS), quantile regression, conformal prediction, causal inference, streaming GAMs, and functional regression are all built in
- it offers principled Bayesian inference: variational inference for fast approximate posteriors, and NUTS (No-U-Turn Sampler) MCMC for exact posterior sampling with full convergence diagnostics
What's included
Core GAM fitting:
- GAM: the central class that can fit penalized regression splines with automatic smoothness selection via REML, GCV, or ML. Full summary, diagnostics, and partial-effect visualization
- Formula syntax: R-style formulas like
"y ~ s(x1) + s(x2, k=20) + te(x3, x4) + x5"with smooth terms, tensor products, linear terms, interactions, offsets, and by-variable smooths - Response families: Gaussian, Poisson, Binomial, Gamma, Negative Binomial, Beta, Tweedie, Inverse Gaussian, Cox PH, and more. Each with appropriate link functions and variance structure
- Smooth basis types: TPRS (default), cubic regression splines, P-splines, cyclic variants, shrinkage smooths, thin plate splines, Duchon splines, Gaussian processes, soap film smooths, Markov random fields, random effects, and factor smooths
- Shape constraints: monotone increasing/decreasing, convex, and concave smooths via constrained P-splines with PAVA projection
Prediction and inference:
- Prediction: point estimates, standard errors, confidence intervals (pointwise and simultaneous), prediction intervals, and term-level contributions. All on response or link scale
- Diagnostics:
model.summary()for EDF and significance tests,model.check()for basis dimension adequacy (k-index test), concurvity analysis, and residual plots - Cross-validation: k-fold CV with deviance, MSE, or MAE scoring via
cross_validate()
Advanced models:
- Bayesian inference: variational inference (
method="VI") for fast approximate posteriors, and NUTS MCMC (method="MCMC") for exact posterior sampling (both with R-hat, ESS, and divergence diagnostics) - Distributional regression (
GAMLSS): model location, scale, and shape simultaneously (Gaussian, Gamma, and Beta location-scale families, plus zero-inflated Poisson and Negative Binomial) - Quantile regression (
QuantileGAM): fit conditional quantiles with ELF loss, optional non-crossing constraints, and sigma calibration - Conformal prediction (
ConformalPredictor): distribution-free prediction intervals via split, CV+, and jackknife+ methods - Causal inference (
CausalGAM): double/debiased machine learning for ATE and CATE estimation, with mediation analysis - Streaming GAMs (
StreamingGAM): incremental fitting via sufficient statistics with exponential decay for tracking distribution shift - Multi-response GAMs (
MultiResponseGAM): joint fitting of multiple responses with optional residual correlation modeling - Functional regression (
FunctionalGAM): scalar-on-function regression with B-spline or Fourier bases for functional covariates
Scalability and deployment:
- Large datasets:
BigGAM(discretized P-IRLS),PolarsGAM(streaming from Polars/files), andDuckDBGAM(SQL-native streaming) for datasets that exceed memory - Serialization:
save_gam()/load_gam()for compact.npzarchives, andto_mgcv_dict/from_mgcv_dictfor R interoperability - scikit-learn integration:
GAMRegressorandGAMClassifierfor use in pipelines and grid search
Get started
Here's a simple example: fit a smooth to noisy data, inspect the fit, and predict on new observations.
import numpy as np
import whittaker as wk
# Generate some data
rng = np.random.default_rng(23)
x = np.linspace(0, 2 * np.pi, 200)
y = np.sin(x) + rng.normal(0, 0.3, 200)
# Fit a GAM with automatic smoothness selection
model = wk.GAM("y ~ s(x)")
model.fit({"x": x, "y": y}, method="REML")
model.summary()
# Predict with standard errors
preds = model.predict({"x": np.linspace(0, 2 * np.pi, 50)}, se=True)
# Check model adequacy
model.check()
See the user guide for a comprehensive tour of all features, from basic smoothing to distributional regression and causal inference.
See more
A more complete example showing multiple predictors, a non-Gaussian family, and model comparison:
import numpy as np
import whittaker as wk
# Simulate Poisson count data with two smooth effects
rng = np.random.default_rng(23)
n = 500
x1 = rng.uniform(0, 2 * np.pi, n)
x2 = rng.uniform(0, 1, n)
mu = np.exp(0.5 + 0.8 * np.sin(x1) + 2 * x2)
y = rng.poisson(mu).astype(float)
data = {"x1": x1, "x2": x2, "y": y}
# Fit a Poisson GAM
model = wk.GAM("y ~ s(x1) + s(x2)", family=wk.Poisson())
model.fit(data, method="REML")
model.summary()
# Cross-validate to check out-of-sample performance
cv = wk.cross_validate("y ~ s(x1) + s(x2)", data, family=wk.Poisson(), n_folds=5)
print(f"CV score: {cv.cv_score:.4f} (SE: {cv.cv_se:.4f})")
# Predict on new data with confidence intervals
preds = model.predict(
{"x1": np.linspace(0, 2 * np.pi, 100), "x2": np.full(100, 0.5)},
interval="confidence", level=0.95,
)
# Save the fitted model for deployment
wk.save_gam(model, "poisson_model.npz")
loaded = wk.load_gam("poisson_model.npz")
Installation
pip install whittaker
For optional backends and visualization:
pip install "whittaker[all]" # Pandas, Polars, PyArrow, Altair
pip install "whittaker[pl,altair]" # Just Polars and Altair
License
MIT (c) Richard Iannone.
Release files for whittaker 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| whittaker-0.2.0.tar.gz | 3.3 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| whittaker-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 3.6 MB
Release files / whittaker-0.2.0.tar.gz
| Download URL | whittaker-0.2.0.tar.gz |
|---|---|
| Size | 3.3 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
fe0a0d553c267c4d9d41b0ce47da6dbe9595684a4aadf948c64ee124648ddad4
|
|
BLAKE2b-256 checksum How to use checksums |
13e746c729f98324c514e7a3b934b0412264d6b67f7c429ed22be8bb74e8ccf6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / whittaker-0.2.0-py3-none-any.whl
| Download URL | whittaker-0.2.0-py3-none-any.whl |
|---|---|
| Size | 328.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
cdd4fa408fe0b3d8d57295d9b4debe71c1c13d8ce0271049d90bb1a0b71a87b4
|
|
BLAKE2b-256 checksum How to use checksums |
4cf036bff764d0ccdbc5e2c4b0c5e1fa91de40a0ebe6b24b3448fe069712f6ff
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|