Skip to content

From statsmodels¤

This page maps common statsmodels patterns to their glmax equivalents. The two libraries share most of the same statistical concepts — GLM families, link functions, offsets, robust standard errors — but differ in API shape.

The key structural difference: statsmodels bundles fitting, inference, and prediction into a single result object. glmax separates them into explicit verbs that return explicit nouns. There's no .summary() method; inference lives in glmax.infer.


Fitting a GLM¤

statsmodels exposes a mix of family-specific constructors (sm.OLS, sm.Logit, sm.Poisson) and a generic sm.GLM. glmax uses one entry point for everything — the family is an argument, not part of the class name.

statsmodels:

import statsmodels.api as sm
import numpy as np

X = sm.add_constant(X_raw)   # statsmodels adds the intercept for you

result = sm.OLS(y, X).fit()                                      # Gaussian
result = sm.Logit(y, X).fit()                                    # Binomial / logit
result = sm.Poisson(y, X).fit()                                  # Poisson
result = sm.GLM(y, X, family=sm.families.Gamma()).fit()          # Gamma
result = sm.NegativeBinomial(y, X).fit()                         # Negative Binomial

glmax:

import jax.numpy as jnp
import glmax

# glmax does not add an intercept automatically — include it in X
X = jnp.column_stack([jnp.ones(n), X_raw])

fitted = glmax.fit(glmax.Gaussian(), X, y)
fitted = glmax.fit(glmax.Binomial(), X, y)
fitted = glmax.fit(glmax.Poisson(), X, y)
fitted = glmax.fit(glmax.Gamma(), X, y)
fitted = glmax.fit(glmax.NegativeBinomial(), X, y)

Fitting returns a FittedGLM noun. Inference is a separate step:

result = glmax.infer(fitted)
result.params.beta   # coefficients  (cf. result.params)
result.se            # standard errors  (cf. result.bse)
result.stat          # test statistics  (cf. result.tvalues)
result.p             # p-values  (cf. result.pvalues)

fitted.mu            # fitted means  (cf. result.fittedvalues)
glmax.predict(fitted.family, fitted.params, X_new)   # out-of-sample  (cf. result.predict)

For Negative Binomial the overdispersion parameter lives in fitted.params.aux rather than appended to the coefficient vector.


statsmodels:

result = sm.GLM(
    y, X,
    family=sm.families.Binomial(sm.families.links.Probit())
).fit()

glmax:

fitted = glmax.fit(glmax.Binomial(glmax.ProbitLink()), X, y)

The link is passed directly to the family constructor. See Families & Links for all supported combinations.


Offsets¤

Both libraries use offset= as a keyword argument. In statsmodels it goes to .fit(); in glmax it goes to fit() directly. Either way, the offset is added to the linear predictor before the inverse link is applied.

statsmodels:

result = sm.Poisson(y, X).fit(offset=np.log(exposure))

glmax:

fitted = glmax.fit(glmax.Poisson(), X, y, offset=jnp.log(exposure))

Robust (sandwich) standard errors¤

statsmodels:

result = sm.Poisson(y, X).fit(cov_type="HC3")

glmax:

result = glmax.infer(fitted, stderr=glmax.HuberError())

Residuals¤

statsmodels:

result.resid_pearson    # Pearson residuals
result.resid_deviance   # deviance residuals

glmax:

pearson  = glmax.check(fitted, diagnostic=glmax.PearsonResidual())
deviance = glmax.check(fitted, diagnostic=glmax.DevianceResidual())
quantile = glmax.check(fitted, diagnostic=glmax.QuantileResidual())

Quantile residuals are also available — they're randomised probability integral transform residuals and are especially useful for discrete families like Poisson and Binomial, where Pearson and deviance residuals don't follow a clean reference distribution.


Goodness-of-fit statistics¤

statsmodels:

result.deviance          # residual deviance
result.pearson_chi2      # Pearson χ²
result.aic               # AIC

glmax:

gof = glmax.check(fitted, diagnostic=glmax.GoodnessOfFit())
gof.deviance       # residual deviance
gof.pearson_chi2   # Pearson χ²
gof.aic            # AIC

What glmax doesn't have (yet)¤

A few things statsmodels provides that glmax doesn't yet support:

  • .summary() formatted tables — inference results are structured arrays, not formatted text. Use result.params.beta, result.se, etc. directly.
  • Dispersion inference — standard errors on the dispersion parameter for Gaussian and Gamma are on the roadmap.
  • Per-sample weights — not yet implemented; passing weights= raises ValueError.

What glmax adds¤

Beyond the API differences, glmax is built on JAX, which gives you:

  • Batched fitting — fit the same model to hundreds of response vectors simultaneously with eqx.filter_vmap.
  • Gradients through fitjax.grad and jax.jvp work through the fit itself via an Implicit Function Theorem-based custom derivative rule.
  • JIT compilation — all verbs compile on first call and run fast on CPU, GPU, or TPU thereafter.

See JAX Transformations for examples.