magli: Generalized Additive Models (GAMs) in Python
magli (Modelo Aditivo Generalizado Lineal): Modern Pythonic Generalized Additive Models (GAMs) based on classical statistical literature. It supports both single-term smooths (GAM / LinGAM) and multi-term formula-based models (GAMCore) with automatic hyperparameter tuning.
Full documentation: https://dacts23.github.io/magli/
Which Backend Engine Should I Use?
magli provides two complementary statistical engines under a unified API:
| Feature / Goal | backend="wood" (Default) |
backend="eilers" |
|---|---|---|
| Smoothing parameter ($\lambda$) | Continuous REML or GCV optimization (automatic during .fit(), no grid search needed) |
Discrete GCV grid search over candidate $(\lambda, K)$ pairs |
| Basis function suite | Thin plate (tp, ts), Cubic (cr, cs), Cyclic (cc), P-splines (ps, cp), B-splines (bs), Random effects (re) |
Uniform B-splines (bs) with linear extrapolation |
| Statistical summaries | Full summary tables with approximate F-tests and p-values (Wood 2013) | Basic statistics (EDF, GCV, deviance explained) |
| Shape constraints | Periodic boundaries via cyclic bases (cc, cp) |
Soft constraints: mono_inc, mono_dec, convex, concave, periodic |
| Observation weights | Weighted penalized least-squares (weights=...) |
Weighted penalized least-squares (weights=...) |
- Use
woodfor general regression, automatic parameter tuning, hypothesis testing, and maximum flexibility in basis types (equivalent to R'smgcv). - Use
eilerswhen you have physical domain constraints (e.g. monotonicity or convexity) or want explicit B-spline grid sweeps.
Why magli?
- R's
mgcvparity in pure Python:magliimplements Simon Wood's continuous REML smoothing parameter selection, Wood 2013 approximate F-tests and p-values, thin plate splines, and cyclic cubic bases without requiring an R runtime or rpy2. - Shape constraints: Soft shape constraints (monotonic increasing, monotonic decreasing, convex, concave) via the Eilers-Marx B-spline engine.
- Fast and numerically stable: SVD data augmentation and cached QR with Cholesky factorization avoid squaring condition numbers.
- Interpretable machine learning: Every term produces clean component decomposition plots and Bayesian confidence intervals.
Features
- Dual backend engines: choose between
wood(Wood 2011) andeilers(Eilers & Marx 1996) - Automatic hyperparameter tuning: continuous REML/GCV optimization or cached QR+Cholesky GCV grid search
- Rich basis suite: thin plate splines, cubic regression splines, cyclic cubic splines, P-splines, B-splines, random effects
- Tensor-product interactions: multidimensional smooths (
te) with Kronecker sum penalties - Shape constraints: monotonic increasing/decreasing, convex, concave, and periodic
- Observation weights: prior precision or frequency weights (
weights=...) infit()andgridsearch() - Uncertainty quantification: Bayesian posterior covariance and frequentist confidence/prediction intervals
- Summary tables: parametric coefficients, EDF, approximate F-statistics, and p-values (Wood 2013)
Installation
pip install numpy scipy matplotlib
pip install -e .
Quick Start
1. Wood (2011) Engine (Automatic REML Smoothing)
In the Wood engine, smoothing parameters are estimated continuously during fit via REML (no manual grid search required):
import numpy as np
from magli import GAM, GAMCore
np.random.seed(42)
x = np.linspace(0, 1, 200)
y = np.sin(2 * np.pi * x) + np.random.normal(0, 0.2, len(x))
# Single-term model with cubic regression splines
model = GAM(k=10, bs="cr", backend="wood")
model.fit(x, y)
print(model.summary())
y_pred = model.predict(x)
ci = model.confidence_intervals(x, width=0.95)
Multi-term formula with tensor-product interactions and linear terms:
# Multi-term dataset: 2 interactive variables + 1 linear variable
X = np.random.uniform(0, 10, (200, 3))
y_multi = np.sin(X[:, 0]) + 0.5 * X[:, 1] + 1.2 * X[:, 2] + np.random.normal(0, 0.2, 200)
gam = GAMCore("te(0, 1, bs='cr', k=4) + l(2)", backend="wood")
gam.fit(X, y_multi)
print(gam.summary())
2. Eilers & Marx (1996) Engine (B-Splines & Constraints)
The Eilers-Marx engine provides discrete GCV grid searches and shape constraints:
import numpy as np
from magli import GAM
# Reusing synthetic data x, y or generating new series
x = np.linspace(0, 1, 200)
y = np.sin(2 * np.pi * x) + np.random.normal(0, 0.2, len(x))
# Fast B-spline grid search over candidate lambda and spline counts
model = GAM(backend="eilers")
model.gridsearch(x, y)
y_pred = model.predict(x)
ci = model.confidence_intervals(x, width=0.95)
model.plot_decomposition(x, y)
Enforcing soft shape constraints (e.g. monotonic increasing dose-response):
# Enforce monotonic increasing trend
mono_model = GAM(n_splines=12, constraint="mono_inc", backend="eilers")
mono_model.fit(x, y)
Fitting with observation weights (e.g. inverse variance or down-weighted outliers):
# Weighted penalized least-squares
weighted_model = GAM(n_splines=12, backend="eilers")
weighted_model.fit(x, y, weights=w)
Formula Syntax
GAMCore uses an intuitive additive formula specification:
| Term Syntax | Meaning | Example |
|---|---|---|
s(col, ...) |
Univariate smooth spline | s(0, k=10, bs='cr') or s(0, n_splines=12, constraint='mono_inc') |
te(c1, c2, ...) |
Multidimensional tensor product | te(0, 1, k=5, bs='cr') |
f(col, ...) |
Categorical factor | f(2, coding='dummy') or f(2, coding='one-hot') |
l(col, ...) |
Parametric linear effect | l(3) |
Note: Predictor variables are identified by 0-indexed column numbers in input arrays.
Documentation
Full documentation, mathematical foundations, and end-to-end tutorials are available at:
→ https://dacts23.github.io/magli/
- Quick Start: installation and basic workflows
- Mathematical Foundations: theory behind both engines:
- Shape Constraints: monotonic, convex, concave, and periodic splines
- Smoothing Optimization: continuous REML and discrete GCV grid search
- Examples & Case Studies: worked examples across diverse problems
- API Reference: full class and method documentation
- Changelog: release history and version notes
Demo Scripts
Run any of the 15 self-contained demo scripts in the examples/ directory:
python examples/01_basic_lingam.py
python examples/10_engineering_case_study.py
python examples/11_wood_backend.py
python examples/12_concrete_demo.py
python examples/13_eilers_vs_wood_comparison.py
python examples/14_wood_basis_decomposition_plots.py
python examples/15_eilers_basis_decomposition_plots.py
License
GNU General Public License v3.0 (GPL-3.0-or-later) © 2026 David Ávila Cortés.
See LICENSE for full terms and third-party attributions (Simon N. Wood / mgcv and Daniel Serven / pygam).
Metadata
Release files for magli 0.3.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| magli-0.3.1.tar.gz | 57.3 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| magli-0.3.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 111.6 kB
Release files / magli-0.3.1.tar.gz
| Download URL | magli-0.3.1.tar.gz |
|---|---|
| Size | 57.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8d3ab61a092ddf54abcf80813999c7a3b1b650464f6c24f1cffa27b00b9bb552
|
|
BLAKE2b-256 checksum How to use checksums |
bfb5db74a9eab2f5c77ba18550dda86d6333b3ff204687d847de20e2ddb99742
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 17, 2026.
Transparency logRelease files / magli-0.3.1-py3-none-any.whl
| Download URL | magli-0.3.1-py3-none-any.whl |
|---|---|
| Size | 54.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c539db8d185927248bf22c86b39918c7633be730d9722fe4788214d7d01c128b
|
|
BLAKE2b-256 checksum How to use checksums |
2bdb7342e9740765efc459332819aeb3be352ad8b223a575e6ff4d1c74adca7b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 17, 2026.
Transparency logSecurity for magli 0.3.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for magli-0.3.1.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 17, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.