
L0-Penalized Negative Binomial Regression
L0glm_negative_binomial.RdFit NB2 count models with a fixed or estimated shape parameter using
L0glm.fit and the mgcv::nb family constructor. Multiple response
channels may share a selected predictor support.
Details
For observation \(i\) in channel \(c\), $$E(Y_{ic})=\mu_{ic},\qquad \operatorname{Var}(Y_{ic})=\mu_{ic}+\mu_{ic}^2/\theta_c.$$ The scale dispersion is one. Shape \(\theta_c\) is a separate parameter, not an additional multiplicative dispersion. With case weights \(w_{ic}\), the log likelihood is the weighted sum of $$\log\Gamma(y+\theta)-\log\Gamma(\theta)-\log\Gamma(y+1) +\theta\log\theta+y\log\mu-(y+\theta)\log(\theta+\mu).$$ The mean satisfies \(g(\mu)=X\beta+o\), where \(o\) is an offset. Log, identity and square-root links are supported through the family object; identity/square-root fits require valid positive means.
mgcv::nb() estimates shape starting from one;
mgcv::nb(theta=2) fixes it at two; and
mgcv::nb(theta=-2) estimates it starting from two. Each response channel
has its own shape. The supplied family object is not mutated.
An intercept must be requested explicitly with intercept=TRUE.
Adaptive ridge and shape estimation
At each IRLS iteration, with \(\dot\mu=d\mu/d\eta\), the working quantities are
$$z=\eta-o+(y-\mu)/\dot\mu,\qquad
W=w\dot\mu^2/(\mu+\mu^2/\theta).$$
The existing ridge solver computes
$$(X^T W X+D)\beta^+=X^T Wz+Da,$$
where \(a\) is prior.mean in working coefficient coordinates.
Supply prior.mean in original predictor units as a scalar,
length-\(p\) vector shared across channels, or \(p\) by \(m\) matrix,
including any added intercept row; normalization is handled internally.
NULL uses zero centers. These targets concern regression coefficients,
not shape or dispersion. Nonzero targets cannot reactivate coefficients excluded
by explicit zero starts; excluded entries remain zero in the original sparse
output dimensions. Unpenalized mandatory terms are unaffected by their targets,
and the final relaxed refit removes the ridge penalty on retained support.
A selectable coefficient has the inverse-square adaptive ridge diagonal
\(D_j=\lambda/(4\beta_j^2)\). Grouped selection instead shares
\(D_{jc}=\lambda/(4\sum_h\beta_{jh}^2)\) across channels.
Mandatory terms, including intercepts, have zero penalty.
The factor one quarter retains the package's adaptive-ridge calibration;
the algorithm heuristically targets
$$-2\ell(B,\theta)+\lambda\,s(B),$$
where \(s\) counts nonzero coefficients or selected rows according to
grouped. This is not a certificate of global L0 optimality.
One safeguarded scalar shape update follows each coefficient update.
For fixed fitted means, write \(U=\partial\ell/\partial\theta\) and
\(H=\partial^2\ell/\partial\theta^2\). With \(b=\log\theta\),
$$U_b=\theta U,\qquad H_b=\theta^2H+\theta U.$$
The proposal \(-U_b/H_b\) is used when curvature is negative, otherwise an
ascent direction is used. Log steps are capped at one, bounded by
theta.min and theta.max, and backtracked against the exact NB
likelihood. This adds linear work per channel without a nested coefficient
fit. Shape convergence uses theta.tol. Defaults are
control.family=list(theta.min=1e-6,theta.max=1e7,theta.tol=1e-6).
The relative thresh rule and absolute cutoff 1e-20 apply during
selection only. Relaxed fitting removes the penalty on selected support and
does not hard threshold. Explicit starting zeroes remain structural zeroes,
except for intercept/mandatory terms. A grouped refit may recover other entries
within retained rows. Returned coefficients are sparse and in original units.
Scoring and tuning
L0glm.metrics reports the exact log likelihood, saturated-model
deviance, target objective, row GIC and parameter-count ICs.
Estimated shapes contribute one degree of freedom per channel to the latter.
logLik(fit) and fit$metrics use exact likelihoods.
External scoring defaults to mu_floor=1e-8; use zero for exact scoring.
CV scores held-out deviance using the shape estimated on the training fold,
without re-estimating it on held-out observations. Check all rows of
fit$convergence; difficult fits may need an explicit larger maxit.
These family-specific loops are serial; openmp and ncores do not
parallelize them.
Examples
if (requireNamespace("mgcv", quietly = TRUE)) {
set.seed(201)
X <- matrix(rnorm(300 * 6), 300, 6)
mu <- exp(0.4 + 0.8 * X[, 1] - 0.6 * X[, 2])
y <- rnbinom(300, mu = mu, size = 2)
fit_nb <- L0glm.fit(X, y, family = mgcv::nb(), intercept = TRUE,
lambda = "gic", relaxed = TRUE, maxit = 200, tol = 1e-8)
fit_nb$theta
fit_nb$coefficients
fit_nb$convergence
L0glm.metrics(fit_nb, mu_floor = 0)
head(predict(fit_nb, X[1:5, , drop = FALSE]))
}