NegativeBinomial

Negative Binomial family with log link (NB2 parameterization).

Usage

Source

NegativeBinomial(theta=1.0)

The Negative Binomial family models count data that is overdispersed relative to the Poisson distribution, i.e. where the observed variance exceeds the mean. This commonly arises when counts are driven by unobserved heterogeneity across observations (e.g. some individuals or locations are systematically more prone to events than others). Whittaker uses the NB2 parameterization, where the variance function is V(mu) = mu + mu^2/theta and theta controls the degree of overdispersion: as theta -> infinity the distribution converges to Poisson, while smaller theta implies heavier overdispersion. The canonical log link is used, giving the same multiplicative interpretation of coefficients as Poisson.

Parameters

theta: float = 1.0
Overdispersion (size) parameter, must be positive. Smaller values of theta imply greater overdispersion; larger values make the distribution approach Poisson. The value supplied at construction is used as the starting point and is refined during fitting via an outer iteration around P-IRLS unless explicitly held fixed by the caller.

Notes

The canonical link is the natural logarithm:

g(\mu) = \log(\mu)

The variance function is

V(\mu) = \mu + \frac{\mu^2}{\theta},

so the variance always exceeds the mean by the extra term \mu^2/\theta. The deviance is

D(y, \hat\mu) = 2 \sum_i \left[ y_i \log\!\left(\frac{y_i}{\hat\mu_i}\right) - (y_i + \theta) \log\!\left(\frac{y_i + \theta}{\hat\mu_i + \theta}\right) \right] .

Examples

Fit a GAM to overdispersed count data:

import numpy as np
import whittaker as wk

rng = np.random.default_rng(0)
n = 200
x = np.linspace(0, 2 * np.pi, n)
mu = np.exp(0.5 * np.sin(x))
theta = 3.0
y = rng.negative_binomial(theta, theta / (theta + mu))

data = {"x": x, "y": y}

model = wk.GAM("y ~ s(x)", family=wk.NegativeBinomial(theta=theta))
model.fit(data, method="REML")
print(model.summary())
GAM fit summary
============================================================
Formula:    y ~ s(x)
Family:     NegativeBinomial(theta=4.721, link='log')
Inference:  REML
Observations: 200
Coefficients: 10

Parametric coefficients:
  Term                       Estimate    Std.Err    z value    p-value
  ------------------------ ---------- ---------- ---------- ----------
  (Intercept)                 -0.0054     0.0792     -0.069     0.9451

Approximate significance of smooth terms:
  Term                        EDF Ref.df     Chi.sq    p-value
  ------------------------ ------ ------ ---------- ----------
  s(x)                       3.54      4     15.493   0.003781

Total EDF:  4.54
Scale est:  1.000000
Deviance:   210.5567
Null dev:   229.3245
Dev. expl:  8.2%
GCV score:  1.102291
AIC:        543.06
BIC:        558.05

Attributes

Name Description
scale_known Whether the dispersion parameter is fixed. Always True for NegativeBinomial.
theta Overdispersion (size) parameter theta of the NB2 distribution.

scale_known

Whether the dispersion parameter is fixed. Always True for NegativeBinomial.

scale_known: bool

The NB2 dispersion is governed entirely by theta rather than a separate scale parameter estimated during P-IRLS, so the scale is treated as fixed at 1. theta itself is refined by an outer iteration around P-IRLS rather than the usual scale estimation.


theta

Overdispersion (size) parameter theta of the NB2 distribution.

theta: float

Smaller values imply greater overdispersion relative to Poisson; larger values make the distribution approach Poisson as theta -> infinity. This value is used by variance, unit_deviance, log_likelihood, and simulate.

Methods

Name Description
deviance() Total NB2 deviance, the (weighted) sum of unit_deviance.
initialize() Starting values for mu: y nudged away from zero.
link() Apply the log link: \eta = \log(\mu).
link_derivative() Derivative of the log link: g'(\mu) = 1/\mu.
link_inverse() Apply the inverse log link: \mu = e^{\eta}.
log_likelihood() NB2 log-likelihood evaluated using the current theta.
simulate() Simulate NB2-distributed response values with mean mu and the current theta.
unit_deviance() Per-observation NB2 deviance contributions.
variance() NB2 variance function: V(\mu) = \mu + \mu^2/\theta.

deviance()

Total NB2 deviance, the (weighted) sum of unit_deviance.

Usage

Source

deviance(
    y,
    mu,
    *,
    weights=None,
)

Parameters

y: NDArray

Observed response values (counts), shape (n,).

mu: NDArray

Fitted conditional mean values, shape (n,).

weights: NDArray | None = None
Optional prior weights, shape (n,).

Returns

float
The total (weighted) deviance.

initialize()

Starting values for mu: y nudged away from zero.

Usage

Source

initialize(y)

Since the log link requires strictly positive mu, small or zero counts are pushed away from zero to avoid log(0) on the first P-IRLS iteration.

Parameters

y: NDArray
Observed response values (counts), shape (n,).

Returns

NDArray
Starting values for mu, shape (n,).




log_likelihood()

NB2 log-likelihood evaluated using the current theta.

Usage

Source

log_likelihood(
    y,
    mu,
    scale,
    *,
    weights=None,
)

The scale argument is accepted for interface compatibility but ignored; the overdispersion is instead governed by theta (see scale_known).

Parameters

y: NDArray

Observed response values (counts), shape (n,).

mu: NDArray

Fitted conditional mean values, shape (n,).

scale: float

Ignored.

weights: NDArray | None = None
Optional prior weights, shape (n,).

Returns

float
The total log-likelihood.

simulate()

Simulate NB2-distributed response values with mean mu and the current theta.

Usage

Source

simulate(
    mu,
    scale,
    rng,
)

Parameters

mu: NDArray

Mean (fitted values), shape (n,).

scale: float

Ignored; overdispersion is governed by theta.

rng: np.random.Generator
A numpy.random.Generator instance.

Returns

NDArray
Simulated response values, shape (n,).

unit_deviance()

Per-observation NB2 deviance contributions.

Usage

Source

unit_deviance(
    y,
    mu,
)

Computes d_i = 2 \left[ y_i \log(y_i/\hat\mu_i) - (y_i + \theta) \log\!\left(\frac{y_i+\theta}{\hat\mu_i+\theta}\right) \right], with the usual convention that the y_i \log(\cdot) term vanishes when y_i = 0.

Parameters

y: NDArray

Observed response values (counts), shape (n,).

mu: NDArray
Fitted conditional mean values, shape (n,).

Returns

NDArray
Per-observation deviance contributions, shape (n,).

variance()

NB2 variance function: V(\mu) = \mu + \mu^2/\theta.

Usage

Source

variance(mu)

The variance always exceeds the mean by the extra term \mu^2/\theta, which vanishes as theta -> infinity (recovering the Poisson variance V(mu) = mu).

Parameters

mu: NDArray
Conditional mean values, shape (n,).

Returns

NDArray
Variance values \mu + \mu^2/\theta, shape (n,).