NAMpy is a suite of interpretable models for regression, classification, and distributional regression tasks for tabular data offering generalized additive models (GAMs) with statistical inference, automatic smoothness selection, diagnostics, shape constraints etc. along with neural additive models (such as NAM, NBM, IGANN, GPNAM, SIAN, SPAM, NodeGAM, and related architectures). The models are available for regression, classification and distributional regression, denoted by LSS. Hence, they are available as e.g. NAMRegressor, NAMClassifier or NAMLSS. NAMpy models adhere to scikit-learn's BaseEstimator interface, making them highly compatible with the familiar scikit-learn ecosystem.
NAMpy supports Python 3.11 and 3.12. Install all functionality with:
pip install "nampy[all]"NAMpy models express predictions as sums of interpretable term contributions-
where
GAMs represent the functions
This preserves an additive decomposition on the parameter/link scale while allowing location, scale, shape, quantiles, or class probabilities to vary with the inputs.
NAMpy’s public estimator classes follow the scikit-learn estimator interface and implement familiar methods such as fit(), predict(), score() and supporting scikit-learn workflows like cross-validation and hyperparameter search.
The sklearn-style adapters default to automatic REML smoothness selection.
import numpy as np
import pandas as pd
from nampy.models import GAMRegressor
rng = np.random.default_rng(7)
x = np.linspace(0.0, 1.0, 300)
data = pd.DataFrame(
{
"x": x,
"group": rng.choice(["a", "b"], size=x.size),
"y": np.sin(2 * np.pi * x) + rng.normal(scale=0.15, size=x.size),
}
)
model = GAMRegressor(
formula="y ~ s(x, bs='cr', k=12) + group",
smoothing_method="reml",
).fit(data)
prediction = model.predict(data)
summary = model.summary()
components = model.predict_components(data)
components.validate_additive_reconstruction()Without a formula, the adapter creates one smooth main effect per input column:
model = GAMRegressor(k=10, basis="tp").fit(X_train, y_train)
prediction = model.predict(X_test)
standard_error = model.standard_errors(X_test)Use the dedicated GAMLSS estimator when multiple additive predictors jointly
describe one response distribution:
from nampy.models import GAMLSS
model = GAMLSS(
family="normal",
formula={
"mu": "y ~ s(x0, bs='cr', k=10)",
"sigma": "~ s(x1, bs='cr', k=8)",
},
).fit(data)
parameters = model.predict(data) # columns: mu, sigma
point_prediction = model.predict_point(data)
raw_predictors = model.predict(data, raw=True)GAMRegressor accepts single-predictor regression families,
GAMClassifier accepts binary binomial families, and GAMLSS accepts
multi-parameter GAMLSS families. The low-level nampy.gam.GAM remains
unrestricted and keeps its mgcv-shaped response conventions.
NAMpy's GAM implementation covers the statistical model lifecycle from formula parsing and smooth construction through fitting, prediction, inference, and diagnostics. Ordinary and shape-constrained terms share the same formula, result, and prediction interfaces.
| Formula surface | Supported terms |
|---|---|
| Univariate smooths | s(..., bs='cr'), cs, cc, ps, tp, ts |
| Structured smooths | random effects re, factor smooths fs, sum-to-zero factor smooths sz |
| Tensor products | te(...) and ti(...) over supported numeric marginals |
| Parametric terms | numeric and factor terms, supported interactions, intercept policies, and formula offsets |
| Shared smoothing | supported id= groups, fixed/free smoothing parameters, select=True, and pc= on supported bases |
Selecting one of the following bases applies the corresponding constraint during fitting. The constraint is encoded in the smooth and coefficient parameterization rather than imposed by modifying predictions afterward.
| Constraint | Basis codes |
|---|---|
| Monotone | mpi, mpd |
| Convex or concave | cx, cv |
| Monotonicity and curvature | micx, micv, mdcx, mdcv |
| Positive | po, ipo, dpo, cyclic-positive cpop |
| Anchored monotone | miso, mifo |
| Numeric-by variants | mpiby, mpdby, micxby, micvby, mdcxby, mdcvby, cxby, cvby |
| Local constraints | lmpi, lipl with the change point supplied through xt |
| Bivariate shape constraints | tedmi, tedmd, temicx, temicv, tedecx, tedecv, tecxcx, tecvcv, tecxcv, tescx, tescv, tesmi1, tesmd1, tesmi2, tesmd2, tismi, tismd |
Shape-constrained functionality includes fixed smoothing, the supported automatic BFGS GCV/UBRE path, exponential and softplus positive transforms, transformed covariance, prediction standard errors, summaries, residuals, first and second derivatives, linear-functional terms, and supported Gaussian AR(1) errors.
| Surface | Supported behavior |
|---|---|
| Ordinary families | Gaussian, binomial, Poisson, and Gamma with the implemented canonical and noncanonical links |
| Extended families | negative binomial (nb and fixed-theta negbin), beta regression (betar), Tweedie (tw), and ordered categorical (ocat) |
| Multi-predictor families | GAMLSS with normal/gaulss and gamma/gammals; raw GAM also accepts the mgcv family names |
| Smoothness criteria | fixed smoothing, GCV/Cp, UBRE, ML, REML, and general-family LAML where the selected family and model combination supports them |
| Smoothness optimizers | outer Newton, BFGS, EFS, and guarded optim/L-BFGS-B routes |
| Prediction | link, response, terms, interaction terms, linear-predictor matrices, and pointwise standard errors |
| Inference and diagnostics | covariance choices, derivatives, residuals, summaries, ANOVA, log likelihood, AIC/BIC, concurvity, k_check, gam_check, and plot data/rendering |
NAMpy provides multiple neural additive architectures behind consistent regression, classification, and distributional-regression APIs. Models retain their published structural and training differences while sharing data preparation, prediction, scoring, persistence, and term-inspection conventions.
from nampy.models import NAMRegressor
model = NAMRegressor(
layer_sizes=[64, 32],
dropout=0.1,
numerical_preprocessing="minmax",
).fit(
X_train,
y_train,
max_epochs=100,
batch_size=128,
patience=12,
random_state=7,
)
prediction = model.predict(X_test)
components = model.predict_components(X_test, center=True)
importance = model.term_importance(X_test)
figures = model.plot_terms(X_test)| Architecture | Model idea |
|---|---|
| Neural Linear Regression (LinReg) | Neural-objective-compatible linear baseline |
| Neural Additive Models (NAM) | One feature network per logical feature, with optional explicit interactions |
| Sparse Interaction Additive Networks (SIAN) | Sparse higher-order additive terms discovered with Archipelago/FIS |
| Sparse Neural Additive Models (SNAM) | NAM subnetworks with group-lasso feature and term sparsity |
| Gaussian Process Neural Additive Models (GPNAM) | Random Fourier feature approximations to GP shape functions and GP-NA2M terms |
| Interpretable Generalized Additive Neural Networks (IGANN) | Linear initialization followed by sequential feature-wise ELM boosting |
| Neural Basis Models (NBM) | Learned basis functions shared across features, with dense, sparse, and higher-order modes |
| Scalable Polynomial Additive Model (SPAM) | Low-rank polynomial additive effects with local term importance |
| Neural Basis Model-Scalable Polynomial Additive Model (NBM-SPAM) | NBM concepts combined with SPAM polynomial interaction structure |
| Neural Attentive Tabular Transformer (NATT) | Additive tabular transformer representations |
| Transformer-based Neural Additive Model (NAMformer) | Transformer backbone with identifiable marginal feature effects |
| Tree-based Neural Additive Model (TreeNAM) | One differentiable neural decision tree per term |
| Neural Generalized Additive Model (NodeGAM) | Differentiable oblivious trees with additive term extraction |
| Quantile Neural Additive Model (QNAM) | Non-crossing additive quantile outputs |
| Spline Neural Additive Model (SplineNAM) | Cubic-spline feature and interaction layers with smoothing penalties |
Regressor, Classifier, and LSS suffixes form the concrete class names, for example NBMRegressor, NBMClassifier, and NBMLSS. Most architectures support all three estimator types; QNAM is distributional-only, SplineNAM is regression-only, and IGANN does not advertise interaction terms.
LSS estimators learn every parameter of a conditional distribution. This
surface follows the NAMLSS framework:
the family owns output width, valid parameter transforms, loss, prediction,
and metrics, while the registered architecture supplies additive predictors.
from nampy.models import NAMLSS
model = NAMLSS(family="normal").fit(
X_train,
y_train,
max_epochs=150,
patience=15,
)
parameters = model.predict(X_test)
negative_nll = model.score(X_test, y_test)
components = model.predict_components(X_test)
components.validate_additive_reconstruction() # raw parameter/link scale| Family group | Registered names |
|---|---|
| Continuous | normal, robustnormal, studentt, gamma, inversegamma, beta, lognormal, weibull, loglogistic, tweedie |
| Counts | poisson, negativebinom, zip, zinb, hurdlepoisson, hurdlenegativebinom |
| Discrete and ordered | categorical, ordinal |
| Multivariate | dirichlet, mvnormdiag |
| Quantiles | quantile |
Both GAM and neural estimators expose predict_components(). It
returns an AdditivePrediction containing:
| Field | Meaning |
|---|---|
response |
Prediction after the inverse link or distribution parameter transform |
link |
Additive prediction before that transform |
terms |
Ordered mapping from term names to link-scale contributions |
intercept |
Fitted intercept contribution |
offset |
Optional link-scale offset |
For an ordinary scalar predictor, the central invariant is:
components.link == (
components.intercept
+ sum(components.terms.values())
+ (0.0 if components.offset is None else components.offset)
)Use the built-in check in application code:
components.validate_additive_reconstruction()
table = model.explain_terms(X_test)
importance = model.term_importance(X_test)
interaction_importance = model.interaction_importance(X_test)Neural models additionally provide component centering and term/interaction plots. GAM estimators provide statistical smooth plots through the same public plotting interface. For LSS models, reconstruction is defined on the raw distribution-parameter/link scale.
The two model families share estimator conventions while retaining their own data preparation and fitting workflows. GAMs build model frames and design matrices from formulas. Neural estimators use PreTab and the training procedure required by the selected model.
Neural estimators use PreTab 0.0.3 for preprocessing which is fitted on training rows only and returns grouped numerical and categorical feature blocks. Architectures declare how those blocks are interpreted; for example, NAM preserves one network per logical source feature, while NBM, SPAM, and NBM-SPAM flatten grouped blocks into scalar concepts. GAM estimators do not use these preprocessing options.
High-level neural estimators accept preprocessing options directly:
model = NAMRegressor(
numerical_preprocessing="ple",
categorical_preprocessing="one-hot",
n_bins=32,
)Gradient-trained models accept controls such as max_epochs, max_steps,
batch_size, patience, learning-rate schedules, checkpoint averaging,
sample weights, and explicit Lightning trainer arguments. Architecture-native
and fixed-basis solvers retain their own hyperparameter meanings.
NeuralEnsemble fits independently cloned regressors or classifiers with
optional bootstrapping and joblib parallelism:
from nampy.models import NAMRegressor, NeuralEnsemble
ensemble = NeuralEnsemble(
NAMRegressor(layer_sizes=[64, 32]),
n_estimators=5,
bootstrap=True,
n_jobs=2,
random_state=7,
).fit(X_train, y_train, max_epochs=100)
mean_prediction = ensemble.predict(X_test)
uncertainty = ensemble.predict_component_uncertainty(X_test)Fitted GAM adapters and neural estimators share a versioned persistence API:
path = model.save_model("model.pkl")
restored = type(model).load_model(path)These artifacts use Python pickle. Load them only from trusted sources.
Both model families keep predictions decomposable into named terms:
prediction = intercept + main effects + optional interactions + optional offset
NAMpy gives them a shared estimator and interpretation surface without hiding their different numerical semantics. GAM inference remains statistical GAM inference; neural architectures retain their own training algorithms.
