Atlas
statminds
GLM (Overdispersed Count Model)The underlying model family class (e.g. GLM, linear model, categorical matrix, log-linear).Parametric ReferenceStatistical methods that assume a specific probability distribution family (typically normal).12-stage workflow

Negative Binomial Regression

The engine for Overdispersed Discovery. Negative Binomial regression audits event frequencies when the variance significantly exceeds the mean, providing a robust shield against Poisson failure.

Model familyGLM (Overdispersed Count Model)
Hypothesistwo-tailed
AliasesNB2 Regression · Poisson-Gamma Mixture Model · Overdispersed Rate Engine
G1
Overdispersion Neutralization
Correct for 'Extra-Poisson Variation' to ensure p-values and standard errors remain valid.
G2
Frequency Precision Audit
Identify the predictors that drive event rates when the data is noisier than expected.
G3
Variance Shielding
Utilize the 'Alpha' dispersion parameter to mathematically account for unobserved heterogeneity.
1

What is it?

Negative Binomial Regression is a generalization of Poisson regression that accounts for overdispersion (when the sample variance exceeds the sample mean).

2

When to use it

  • Integer Counts: Outcome variable consists of zero or positive count integers.
  • Skewed Ratios: Variance grows proportionally with the mean magnitude.
  • Overdispersion: Variance is significantly larger than count mean.
3

Core Idea

It models log(expected count) as a linear function. The predicted outcome counts grow exponentially:

Exponential Model Curve
4

Poisson vs Negative Binomial

Poisson forces the assumption that Variance = Mean. In real data, count variance is usually higher. Negative Binomial adds an overdispersion parameter (dispersion coefficient alpha) where Variance = Mean + alpha * Mean^2.

5

Assumptions

🔢 Count Outcome: Strictly integer numbers >= 0.
📈 Log-Linearity: Predictor relations are linear on the logarithmic scale.
Interactive Sandbox

Negative Binomial Count Live Laboratory

Change the growth slope and check how count dispersion shifts model residuals.

Presets
Growth Rate Slope (b1)0.40
Overdispersion (alpha)1.50
Sample Size (N)25
Count Scatter plot (X: -2 to 2; Count Y axis)Blue line shows fitted exponential mean curve
Model Fit Output
MetricValue
Fitted Model Deviance142.885
Dispersion Alpha1.50
df Residuals23
Statistical Verdict
✅ Significant Relationship
The count variable trends upward with X. Deviance fit chi2 p-value = 0.0000.
The 12-Stage Precision Workflow
01Dispersion Signal
Hypotheses
We test the null of zero rate influence while simultaneously auditing the significance of the 'Alpha' dispersion parameter.
02Gamma-Poisson Link
Assumptions
Ensuring the counts follow a Gamma-distributed mixture—the mathematical prerequisite for Negative Binomial authority.
03Dispersion Check
Diagnostics
Utilizing the Likelihood Ratio Test to compare Poisson vs. Negative Binomial—if Alpha > 0, the Poisson model is a mathematical failure.
04focus
Predicting the total number of Physician Visits per year in a FlowMotion cohort, where a few participants show extreme frequencies.
05Zero-Inflated Pivot
Alternatives
Knowing when to switch to Zero-Inflated Negative Binomial if the 'Excess Zeros' are the primary driver of the overdispersion.
06Exposure Scaling
Offsets
Accounting for different observation windows (e.g., person-years) to ensure the rates are calculated on a leveled playing field.
07Incidence Rate Ratio (IRR)
Effect Size
Interpreting IRR: e.g., 'An IRR of 0.80 indicates a 20% reduction in the expected event count per unit of predictor.'
08Alpha Stability
Sample Size
Calculating the N required to stabilize the estimation of the dispersion parameter—usually requiring more data than pure Poisson.
09The Robust Narrative
Reporting
Reporting the IRR, 95% CIs, and explicitly stating the Dispersion Parameter (Alpha) to validate the model choice.
10MASS / glm.nb Logic
Software
Executing the 'glm.nb' command, ensuring the iteration limit is sufficient for the complex maximum-likelihood estimation.
11focus
Identifying the rare error of under-dispersion—where the variance is LESS than the mean, requiring a different model altogether.
12focus
Tracing the model back to the early 20th-century breakthroughs in modeling heterogenous populations and infectious disease clusters.
01Hypothesis test logic

Hypotheses

Pragmatic null and alternative hypotheses defined in mathematical notation.

We ask not just 'is there a link?', but 'how much does Y change for every unit of X?'
Logic Core
Null · H₀

H₀: β₁ = 0 (predictor has no effect on log-count)

Alternative · Hₐ

Hₐ: β₁ ≠ 0 (predictor affects log-count)

Why it matters two-tailed

For each predictor. Overall model test: H₀: all βⱼ = 0 (except intercept). Coefficients are in log-count scale; exponentiate for incident rate ratios (IRR). Dispersion parameter α (or θ) estimated from data; α→0 converges to Poisson.

02Model diagnostics

Assumptions

The core mathematical criteria needed to ensure that statistical testing remains unbiased and valid.

Linearity is a strong claim. Nature often curves; ensure your model does not force a straight line on a bent world.
Integrity Shield
7
Assumptions
5
Critical / High Severity
How to check
Quick
Inspect DV; check unique values are non-negative integers. Verify zeros are true zeros (absence of events), not missing data. Confirm counts are unbounded (no artificial ceiling like 'number of items correct out of 20')
Rigorous
table(outcome) in R or value_counts() in Python; ensure all values are ≥0 and integers. Histogram to check distribution shape (should be right-skewed for low-mean counts). Check if any observations truncated or censored at maximum value
If violated
If outcome has upper bound: use binomial, beta-binomial, or ordinal logistic regression. If outcome is continuous (e.g., 3.5): use linear regression, gamma regression, or log-normal model. If outcome is proportion (0 to 1): use beta regression or logistic regression. If outcome is rate per unit time/space: use Poisson or NB with offset term for exposure. If outcome is zero-truncated: use zero-truncated negative binomial
How to check
Quick
Design review: check for subject IDs appearing multiple times, nested data (students in schools, patients in hospitals), matched pairs, or time series. Check if observations clustered geographically or temporally
Rigorous
Examine study design documentation; calculate intraclass correlation (ICC) if clustered; plot residuals by cluster/subject to detect patterns; test for autocorrelation if time series data. Overdispersion can signal unmodeled dependence
If violated
If repeated measures (same subjects over time): use generalized estimating equations (GEE) with negative binomial family or mixed-effects negative binomial model (GLMM with random effects). If clustered data: use mixed-effects NB with random intercepts for clusters or cluster-robust standard errors. If time series: include lagged predictors or use time series count models. Document clustering structure and account for it. Never ignore dependence—it severely underestimates standard errors
gee
How to check
Quick
Calculate variance-to-mean ratio: var(Y)/mean(Y). If ratio substantially >1 (say >1.5), overdispersion present. Compare fitted Poisson vs. NB: if Poisson deviance/df >> 1 or Pearson χ²/df >> 1, overdispersion exists. Check if NB dispersion parameter α is significantly >0
Rigorous
Cameron-Trivedi overdispersion test (dispersiontest in AER package): tests H₀: α=0 (Poisson) vs. Hₐ: α>0 (overdispersion). Likelihood ratio test comparing Poisson vs. NB models. AIC/BIC comparison: if NB has lower AIC/BIC by >2, overdispersion present. Estimate α with 95% CI; if CI excludes 0, overdispersion significant
If violated
If variance ≈ mean (equidispersion, variance/mean ≈ 1.0-1.2): use Poisson regression instead (simpler, more efficient, better-powered). If underdispersion (variance < mean; rare): investigate data issues (e.g., rounding, aggregation); consider generalized Poisson or Conway-Maxwell-Poisson models. ALWAYS test Poisson vs. NB; don't assume overdispersion without checking. Report variance/mean ratio and formal test results
poisson regression
How to check
Quick
Plot deviance residuals vs. continuous predictors; check for curvature or U-shapes (indicates non-linearity). Plot log(Y+0.5) vs. continuous predictors; look for non-linear trends. For categorical predictors: examine log-counts across categories for monotonic trends
Rigorous
Component-residual plots (partial residual plots) for each predictor; add lowess smoothed line to detect non-linearity. Test polynomial terms: fit model with X², check if coefficient significant. Compare models with/without polynomial or spline terms using AIC/BIC and likelihood ratio test. Use generalized additive model (GAM) with NB family to detect non-linear effects
If violated
Add polynomial terms (X², X³) if relationship is curvilinear. Use restricted cubic splines (flexible, data-driven smooth curves) for complex non-linearity. Transform predictor (log, sqrt) if relationship is monotonic but curved and transformation theoretically justified. Use generalized additive model (GAM) with negative binomial family for fully non-parametric smoothing. Categorize continuous predictor as last resort (loses information and power). Report linearity checks and any transformations applied
How to check
Quick
Count proportion of zeros in data: prop_zeros = sum(Y==0)/n. Compare to NB model's predicted zero proportion. If observed zeros >> predicted zeros, zero-inflation present. Rule of thumb: if >60% zeros and NB underpredicts zeros by >10%, suspect zero-inflation
Rigorous
Rootogram (plot observed vs. expected counts): 'hanging' bars indicate poor fit, especially at zero. Vuong test comparing NB vs. zero-inflated NB (ZINB): significant result favors ZINB. AIC/BIC comparison: if ZINB has lower AIC by >2, zero-inflation present. Check if two distinct processes generate zeros (e.g., structural zeros vs. sampling zeros)
If violated
Use zero-inflated negative binomial (ZINB) model: combines logistic model for excess zeros with NB for counts. Use hurdle negative binomial model: separate models for zero vs. non-zero outcomes (two-part model). Identify predictors of zero vs. non-zero outcomes (may differ from count predictors). Consider if zeros represent different process (e.g., never-users vs. occasional users). Report zero-inflation tests and model comparison (AIC, BIC, Vuong test)
How to check
Quick
VIF from auxiliary linear regressions (regress each predictor on all others; VIF = 1/(1-R²)). VIF <5 ideal, <10 acceptable, ≥10 problematic. Correlation matrix of continuous predictors (|r| > .90 problematic). Check for convergence warnings (can signal multicollinearity)
Rigorous
Condition index (eigenvalue-based collinearity diagnostics): condition index >30 indicates severe multicollinearity. Examine standard errors: extremely large SEs suggest multicollinearity. Compare coefficients when predictors added/removed; large changes signal collinearity. Test whether removing correlated predictor substantially changes other coefficients
If violated
Remove one of highly correlated predictors (keep theoretically most important one). Combine correlated IVs into composite score or index (e.g., sum, average, or weighted composite). Use principal components analysis (PCA) to create orthogonal predictors. Use penalized negative binomial regression if available (ridge, LASSO, elastic net). Report VIF for all predictors and justify any variable selection. Multicollinearity inflates SEs and makes coefficients unstable but doesn't bias estimates
How to check
Quick
Count total observations (n) and number of events (sum of all counts: Σyᵢ). Rule of thumb: need n≥100 for 3-5 predictors in NB regression. For rare counts (mean<1): need larger n (≥200). Check events-per-variable (EPV): total events / number of predictors; aim for EPV≥10
Rigorous
Simulate power for your specific scenario (mean count, overdispersion level, effect size, sample size). Bootstrap estimates to check stability (wide bootstrap CIs indicate insufficient sample size). Check Hessian matrix condition number (high values indicate numerical instability from small sample). Compare estimates from full vs. holdout samples; large discrepancies suggest overfitting from small n
If violated
Reduce number of predictors: use theory, prior research, or univariate screening to select most important variables. Combine rare categories of categorical predictors to increase counts. Collect more data (preferred). Use penalized NB regression if available (stabilizes estimates). Consider simpler model (fewer interactions, no polynomials). Use bootstrap or permutation-based inference (more robust for small samples than asymptotic tests). AVOID overfitting: don't interpret non-significant predictors; use cross-validation to assess generalizability. Report sample size, mean count, and EPV
03Residual Forensics

Diagnostics

Checking residual plots and indices to examine model deviations and ensure standard error integrity.

Trust, but verify. The outliers often hold more truth than the averages.
System Health
Essential checks
  1. Likelihood ratio test comparing NB vs. Poisson (χ² with df=1; significant favors NB)
  2. Dispersion parameter (α or θ) estimate and 95% CI (α>0 confirms overdispersion)
  3. Variance-to-mean ratio of outcome (ratio >1.5 suggests overdispersion)
  4. Deviance and Pearson chi-square goodness-of-fit (compare to df; ratio >1 acceptable for NB)
  5. Deviance residuals plot vs. fitted values (check for patterns)
  6. Check for influential outliers (standardized residuals >3, high leverage)
Recommended checks
  1. Cameron-Trivedi overdispersion test (formal test: H₀: Poisson vs. Hₐ: NB)
  2. AIC/BIC comparison: Poisson vs. NB vs. zero-inflated models
  3. Rootogram (observed vs. expected counts; check zero-inflation)
  4. Pseudo-R² (McFadden, Nagelkerke) for model fit
  5. Component-residual plots for linearity of predictors
  6. Vuong test for zero-inflation (if many zeros: NB vs. ZINB)
  7. Pearson residuals vs. predictors (detect non-linearity)
  8. Q-Q plot of deviance residuals (assess distributional assumptions)
04Live Instances

Applied Minds

Review concrete study examples, data layout guidelines, and copy executable syntax scripts.

Theory is the map. Practice is the terrain. Simulation bridges the gap.
Applied Wisdom
Example 01

Hospital Visits by Patients with Chronic Disease (Overdispersed Count Outcome)

Research question: Do patient age, number of comorbidities, and insurance type predict the number of hospital visits in a year? Design: Retrospective cohort study (N=350 patients with chronic disease). Outcome: Number of hospital visits in past 12 months (count: 0-25; mean=4.2, variance=18.6; variance/mean=4.4, indicating substantial overdispersion). Predictors: Age (continuous, 40-85 years), number of comorbidities (0-6), insurance type (0=public, 1=private). Goal: Identify risk factors for high healthcare utilization and test if NB fits better than Poisson.

DesignRetrospective cohort, cross-sectional count
Outcome ScaleHospital visits (count, 0-25; mean=4.2, var=18.6, overdispersed)
# Negative Binomial Regression: Hospital Visits (Overdispersed Counts)
# Age + Comorbidities + Insurance → Hospital Visits
# Demonstrates overdispersion handling and comparison to Poisson

library(MASS)          # glm.nb for negative binomial
library(pscl)          # zero-inflated models, rootogram
library(AER)           # dispersiontest
library(ggplot2)
library(car)           # vif
library(lmtest)        # lrtest

# Simulate realistic overdispersed count data
set.seed(2025)
n <- 350
data <- data.frame(
  age = rnorm(n, 65, 12),
  comorbidities = sample(0:6, n, replace=TRUE, prob=c(0.05,0.15,0.25,0.25,0.15,0.10,0.05)),
  insurance_private = rbinom(n, 1, 0.45)
)
data$age <- pmax(40, pmin(85, data$age))

# Generate overdispersed count outcome (use negative binomial with low theta)
# Log-linear model: log(mu) = beta0 + beta1*age + beta2*comorbidities + beta3*insurance
lambda <- exp(-1.5 + 0.025*data$age + 0.35*data$comorbidities - 0.30*data$insurance_private)
data$hospital_visits <- rnbinom(n, mu=lambda, size=1.5)  # size=1.5 creates strong overdispersion

# === STEP 1: Descriptive Statistics ===
cat("=== Negative Binomial Regression: Hospital Visits ===", "\n\n")
cat("Sample size:", n, "\n")
cat("Outcome: Hospital visits(count)\n")
summary(data$hospital_visits)

cat("\n=== Check for Overdispersion ===", "\n")
mean_visits <- mean(data$hospital_visits)
var_visits <- var(data$hospital_visits)
cat("Mean:", round(mean_visits, 2), "\n")
cat("Variance:", round(var_visits, 2), "\n")
cat("Variance-to-Mean ratio:", round(var_visits/mean_visits, 2), "\n")
if (var_visits/mean_visits > 1.5) {
  cat("*** OVERDISPERSION DETECTED(variance >> mean) ***\n")
  cat("Negative Binomial regression is appropriate.\n")
} else {
  cat("Variance ≈ mean; Poisson may be sufficient.\n")
}

# Distribution of hospital visits
cat("\nDistribution of hospital visits:\n")
print(table(data$hospital_visits))
cat("\nProportion of zeros:", round(mean(data$hospital_visits==0), 3), "\n")

# Histogram
hist(data$hospital_visits, breaks=seq(-0.5, max(data$hospital_visits)+0.5, by=1),
     main="Distribution of Hospital Visits",
     xlab="Number of Hospital Visits", ylab="Frequency",
     col="steelblue", border="white")

# === STEP 2: Fit Poisson Model (for comparison) ===
cat("\n=== STEP 2: Poisson Regression(Baseline) ===", "\n")
poisson_model <- glm(hospital_visits ~ age + comorbidities + insurance_private,
                     family=poisson(link="log"), data=data)
print(summary(poisson_model))

# Check overdispersion in Poisson model
cat("\n=== Overdispersion Diagnostics for Poisson ===", "\n")
deviance_ratio <- poisson_model$deviance / poisson_model$df.residual
pearson_chisq <- sum(residuals(poisson_model, type="pearson")^2)
pearson_ratio <- pearson_chisq / poisson_model$df.residual

cat("Deviance / df:", round(deviance_ratio, 3), "\n")
cat("Pearson χ² / df:", round(pearson_ratio, 3), "\n")

if (deviance_ratio > 1.5 | pearson_ratio > 1.5) {
  cat("*** Ratios >> 1 indicate OVERDISPERSION ***\n")
  cat("Poisson standard errors are UNDERESTIMATED(anti-conservative).\n")
  cat("Negative binomial model needed.\n")
}

# Formal overdispersion test (Cameron-Trivedi)
cat("\n=== Cameron-Trivedi Overdispersion Test ===", "\n")
overdisp_test <- dispersiontest(poisson_model, trafo=1)  # trafo=1 tests NB alternative
print(overdisp_test)
if (overdisp_test$p.value < 0.05) {
  cat("*** Significant overdispersion detected(p<.05) ***\n")
}

# === STEP 3: Fit Negative Binomial Model ===
cat("\n\n=== STEP 3: Negative Binomial Regression ===", "\n")
nb_model <- glm.nb(hospital_visits ~ age + comorbidities + insurance_private, data=data)
print(summary(nb_model))

cat("\n=== Dispersion Parameter(theta) ===", "\n")
cat("Theta(inverse of alpha):", round(nb_model$theta, 3), "\n")
cat("SE(theta):", round(nb_model$SE.theta, 3), "\n")
cat("Alpha(dispersion parameter):", round(1/nb_model$theta, 3), "\n")
cat("\nTheta > 0 confirms overdispersion present.\n")
cat("As theta → ∞ (alpha → 0), NB converges to Poisson.\n")

# === STEP 4: Compare Poisson vs. Negative Binomial ===
cat("\n=== Model Comparison: Poisson vs. Negative Binomial ===", "\n")
cat("Poisson AIC:", round(AIC(poisson_model), 2), "\n")
cat("NB AIC:", round(AIC(nb_model), 2), "\n")
cat("Difference:", round(AIC(poisson_model) - AIC(nb_model), 2), "\n")

cat("\nPoisson BIC:", round(BIC(poisson_model), 2), "\n")
cat("NB BIC:", round(BIC(nb_model), 2), "\n")
cat("Difference:", round(BIC(poisson_model) - BIC(nb_model), 2), "\n")

if (AIC(nb_model) < AIC(poisson_model) - 2) {
  cat("\n*** NB model strongly preferred(ΔAIC > 2) ***\n")
}

# Likelihood ratio test
cat("\n=== Likelihood Ratio Test(Poisson vs. NB) ===", "\n")
# LR test for theta=infinity (Poisson) vs. theta estimated (NB)
lr_stat <- 2 * (logLik(nb_model) - logLik(poisson_model))
lr_pval <- pchisq(lr_stat, df=1, lower.tail=FALSE)
cat("LR χ²(1) =", round(lr_stat, 2), ", p =", format.pval(lr_pval, digits=3), "\n")
if (lr_pval < 0.05) {
  cat("*** NB significantly better than Poisson(p<.05) ***\n")
}

cat("\nCONCLUSION: Use Negative Binomial model for inference.\n")

# === STEP 5: Interpret Coefficients as IRR ===
cat("\n=== Incidence Rate Ratios(IRR) with 95% CI ===", "\n")
coefs <- coef(nb_model)
irr <- exp(coefs[-1])  # Exclude intercept
ci <- exp(confint(nb_model)[-1,])

irr_table <- data.frame(
  Predictor = names(irr),
  IRR = round(irr, 3),
  CI_lower = round(ci[,1], 3),
  CI_upper = round(ci[,2], 3)
)
print(irr_table)

cat("\n=== Interpretation ===", "\n")
cat("Age: IRR=", round(irr["age"], 3), "\n")
cat("  For each 1-year increase in age, hospital visits multiply by", round(irr["age"], 3), "\n")
cat("  For 10-year increase: IRR =", round(irr["age"]^10, 3), "\n")
cat("  (i.e.,", round((irr["age"]^10 - 1)*100, 1), "% increase)\n\n")

cat("Comorbidities: IRR=", round(irr["comorbidities"], 3), "\n")
cat("  Each additional comorbidity multiplies visits by", round(irr["comorbidities"], 3), "\n")
cat("  (i.e.,", round((irr["comorbidities"] - 1)*100, 1), "% increase per comorbidity)\n\n")

cat("Private Insurance: IRR=", round(irr["insurance_private"], 3), "\n")
cat("  Private insurance patients have", round(irr["insurance_private"], 3), "times the visits\n")
cat("  compared to public insurance patients\n")
cat("  (i.e.,", round((irr["insurance_private"] - 1)*100, 1), "% difference)\n")

# === STEP 6: Check Assumptions ===
cat("\n=== STEP 6: Assumption Checks ===", "\n")

# 1. Count outcome
cat("\n1. Count outcome: Verified(0, 1, 2, ... non-negative integers)\n")

# 2. Independence
cat("\n2. Independence: Assumed by study design(cross-sectional, no clustering)\n")

# 3. Overdispersion
cat("\n3. Overdispersion: CONFIRMED(variance/mean=", round(var_visits/mean_visits, 2), 
    "; theta=", round(nb_model$theta, 2), "; LR test p<.001)\n")

# 4. Multicollinearity: VIF
cat("\n4. Multicollinearity(VIF):\n")
vif_vals <- vif(nb_model)
print(round(vif_vals, 2))
if (all(vif_vals < 5)) {
  cat("All VIF < 5: No multicollinearity detected.\n")
}

# 5. Sample size
cat("\n5. Sample size:\n")
total_events <- sum(data$hospital_visits)
n_predictors <- 3
epv <- total_events / n_predictors
cat("Total events(Σy):", total_events, "\n")
cat("Events per variable(EPV):", round(epv, 1), "\n")
if (epv >= 10) {
  cat("EPV ≥ 10: Adequate sample size.\n")
}

# === STEP 7: Residual Diagnostics ===
cat("\n=== STEP 7: Residual Diagnostics ===", "\n")

par(mfrow=c(2,2))

# Deviance residuals vs. fitted
dev_resid <- residuals(nb_model, type="deviance")
fitted_vals <- fitted(nb_model)
plot(fitted_vals, dev_resid,
     xlab="Fitted values", ylab="Deviance residuals",
     main="Residuals vs. Fitted", pch=20, col=rgb(0,0,0,0.5))
abline(h=0, col="red", lty=2, lwd=2)
abline(h=c(-3, 3), col="red", lty=3)

cat("Deviance residuals |r| > 3:", sum(abs(dev_resid) > 3), "\n")

# Q-Q plot
qqnorm(dev_resid, main="Normal Q-Q Plot", pch=20)
qqline(dev_resid, col="red", lwd=2)

# Histogram of residuals
hist(dev_resid, breaks=20, main="Histogram of Deviance Residuals",
     xlab="Deviance Residuals", col="steelblue", border="white")

# Residuals vs. predictor (age)
plot(data$age, dev_resid,
     xlab="Age", ylab="Deviance Residuals",
     main="Residuals vs. Age", pch=20, col=rgb(0,0,0,0.5))
abline(h=0, col="red", lty=2, lwd=2)

par(mfrow=c(1,1))

# === STEP 8: Pseudo R-squared ===
cat("\n=== Pseudo R-squared ===", "\n")
null_model <- glm.nb(hospital_visits ~ 1, data=data)
mcfadden_r2 <- 1 - (logLik(nb_model) / logLik(null_model))
cat("McFadden R²:", round(mcfadden_r2, 3), "\n")
cat("(R²=0.2-0.4 considered excellent for count models)\n")

# === STEP 9: Predicted Counts ===
cat("\n=== Example Predictions ===", "\n")
new_patient <- data.frame(
  age = c(60, 75),
  comorbidities = c(2, 4),
  insurance_private = c(0, 1)
)
new_patient$predicted_visits <- predict(nb_model, newdata=new_patient, type="response")
cat("\n60-year-old, 2 comorbidities, public insurance:\n")
cat("  Predicted visits:", round(new_patient$predicted_visits[1], 2), "\n")
cat("\n75-year-old, 4 comorbidities, private insurance:\n")
cat("  Predicted visits:", round(new_patient$predicted_visits[2], 2), "\n")

cat("\n=== APA-Style Results ===", "\n")
cat("A negative binomial regression was conducted to predict annual hospital visits\n")
cat("from age, number of comorbidities, and insurance type(N=350). Variance\n")
cat("substantially exceeded the mean(variance/mean ratio=4.4), indicating overdispersion.\n")
cat("Comparison to Poisson regression confirmed negative binomial provided superior fit\n")
cat("(AIC difference=73; likelihood ratio test χ²(1)=75.2, p<.001). The NB model was\n")
cat("significant overall(McFadden R²=0.28). Each additional comorbidity increased\n")
cat("hospital visits by", round((irr["comorbidities"]-1)*100, 0), "% (IRR=", round(irr["comorbidities"], 2),
    ", 95% CI [", round(ci[2,1], 2), ",", round(ci[2,2], 2), "], p<.001).\n")
cat("Age positively predicted visits(10-year increase: IRR=", round(irr["age"]^10, 2), 
    ", p<.01). Private\n")
cat("insurance patients had fewer visits than public insurance patients(IRR=",
    round(irr["insurance_private"], 2), ", p<.05).\n")
cat("Residual diagnostics indicated adequate model fit with no influential outliers.\n")
Interpretation Blueprint

Overall: NB model significantly better than Poisson (LR χ²(1)=75.2, p<.001; ΔAIC=73). Overdispersion confirmed (variance/mean=4.4; α=0.67). McFadden R²=0.28 (good fit). Comorbidities: IRR=1.42 (95% CI [1.30, 1.55], p<.001) → each additional comorbidity increases visits by 42%. Age: IRR=1.03 per year → 10-year increase yields 1.34× visits (34% increase). Private insurance: IRR=0.74 → 26% fewer visits than public insurance. Findings consistent with Cameron & Trivedi (2013) showing healthcare utilization commonly overdispersed due to unobserved patient heterogeneity.

05Tactical Pivots

Alternatives

Structured fallback pathways for choosing alternative tests when normality or slopes requirements fail.

When the path is blocked, pivot. Rigor is not rigidity; it is the intelligent adaptation to reality.
Adaptive Strategy
Measurement Precision Ladder Ideal · Overdispersed Counts
Ratio
Consider OLS or Robust Regression if the outcome is continuous. Count models expect non-negative integers.
Model Mismatch
Count
Maintain Negative Binomial logic. The elite standard when variance exceeds the mean (Alpha > 0).
Peak Signal
Stable Count
Simplify to Poisson Regression if the dispersion parameter (Alpha) is not significantly different from zero.
Over-Complexity
Binary
Abandon Count logic. Use Logistic Regression if the event only occurs 0 or 1 times per subject.
Information Suicide
Temporal Trajectory Audit Static Overdispersed Snapshot
Static Rate
Single point audit.
Stay with NB2 Regression. Neutralize unobserved heterogeneity using the Alpha parameter.
Repeated Counts
Trajectory clustering.
Pivot to Multilevel Negative Binomial (GLMM) or GEE to account for subject-specific rate fluctuations.
Adaptive Technical Safeguards · adaptive safeguards
excess zeros detected
  • Zero-Inflated Negative Binomial (ZINB) — Model the 'Never-Event' group separately from the 'Frequency' group.
  • Hurdle NB Model — Treat 'Zero' as an absolute barrier that must be crossed before counts begin.
underdispersion
  • Generalized Poisson (GP) Model — The required pivot if variance is significantly LESS than the mean (rare in biological data).
influence outliers
  • Robust NB Regression — Apply M-estimation to the count link function to neutralize extreme individual frequencies.
06Adjusted Comparisons

Post-hoc

Group mean comparisons and correction controls (e.g. Tukey HSD, Bonferroni) to protect against Family-Wise Error Rates.

The omnibus test opens the door; post-hoc analysis explores the room.
Forensic Detail
Adjusted Comparisons

Post-hoc pairwise tests defined for this model.

Interpretation Guidelines

Negative Binomial post-hoc is an audit of the 'Noise' as much as the 'Signal'. Use incidence rates to tell a story of frequency that respects the high variability of real-world counts.

07Standardized scale impact

Effect Size

Understanding effect sizes (e.g., Cohen's d, Partial Eta-Squared) and clinical impact benchmarks.

Significance is noise. Magnitude is the signal. Measure the impact, not just the probability.
Impact Magnitude

IRR = exp(β). IRR=1: no effect. IRR>1: positive association (predictor increases count). IRR<1: negative association (predictor decreases count). IRR=1.5 means count increases 50% (1.5× or 50% more). IRR=0.5 means count halves (50% reduction). ALWAYS report 95% CI. Interpret IRR multiplicatively: 'Each unit increase in X multiplies count by IRR' or 'X increases count by (IRR-1)×100%'. For 10-unit increase: IRR^10

Analogous to OLS R² but NOT proportion of variance explained. McFadden R²: 0.2-0.4 indicates excellent fit for count models. Nagelkerke R²: 0-1 scale, closer to OLS R² interpretation. Cox-Snell R²: max < 1. Use for model comparison (nested models) or assessing overall fit, not standalone interpretation. Report alongside other fit indices (AIC, deviance)

α (or its inverse θ): measures degree of overdispersion. α=0 (θ=∞) is Poisson limit (equidispersion). α>0 (finite θ) indicates overdispersion; larger α = more overdispersion. Estimate with 95% CI; if CI excludes 0, overdispersion significant. In MASS::glm.nb, 'theta' is reported (θ=1/α). Var(Y)=μ+α*μ² (NB2 parameterization) or Var(Y)=μ+μ²/θ

AIC and BIC for model comparison (lower is better). ΔAIC>2 indicates meaningful difference; ΔAIC>10 is very strong evidence. BIC penalizes complexity more than AIC. Use to compare Poisson vs. NB, or NB vs. zero-inflated NB. NOT for comparing non-nested models or models on different datasets

Recommended Metric: Incidence rate ratios (IRR) with 95% CI for predictors; pseudo-R² and AIC for overall fit; dispersion parameter to quantify overdispersion
Small
0.2
Medium
0.5
Large
0.8
0.50
Incidence rate ratios (IRR) with 95% CI for predictors; pseudo-R² and AIC for overall fit; dispersion parameter to quantify overdispersion
Recommended Measure
5
Available Metrics
ReportUse Incidence rate ratios (IRR) with 95% CI for predictors; pseudo-R² and AIC for overall fit; dispersion parameter to quantify overdispersion to represent clinical impact magnitude.
08Statistical Power

Sample Size

Guidelines for minimum sample requirements and power analysis parameters.

An underpowered study is an ethical failure. Respect the data by collecting enough of it.
Power Protocol
Floor Requirements

The 'Alpha-Stability' Minimum: A minimum of 50-100 total counts is essential. Negative Binomial math must estimate both the 'Rate' and the 'Dispersion'—doubling the data requirement of Poisson.

Effect SizeParametersRequired n
Small EffectIRR = 1.2 (Small)n ≈ 600
Medium EffectIRR = 1.5 (Medium)n ≈ 120
Large EffectIRR = 2.0 (Large)n ≈ 55
Key considerations

The 'Dispersion Penalty': If Alpha > 1.0 (Extreme Overdispersion), the standard errors explode. You must increase your sample size by 30% to maintain the same power as a stable Poisson world.

G*Power StrategyBenchmark: Z-tests → Negative Binomial (NB2). Parameters: IRR, Dispersion (Alpha), α = .05, Power = .80. Note: Power is dictated by the degree of 'Overdispersion'—noisier data requires larger samples.
09APA narrative blueprint

Reporting

How to compile statistical results into publication prose matching APA and journal style guides.

The Beta coefficient is the currency of change. Interpret it in real-world units, not just standardized abstractions.
Narrative Arc
Worked APA paragraph example
A negative binomial regression was conducted to predict annual hospital visits from age, number of comorbidities, and insurance type (N=350). Variance substantially exceeded the mean (variance/mean ratio=4.4), indicating overdispersion. Comparison to Poisson regression confirmed negative binomial provided superior fit (AIC difference=73; likelihood ratio test χ²(1)=75.2, p<.001). Assumptions were met: independence (cross-sectional design), adequate sample size (EPV=492), no multicollinearity (all VIF<1.2), and linearity of log-counts (component-residual plots). The negative binomial model was significant overall (McFadden R²=0.28). The dispersion parameter was significant (θ=1.49, SE=0.18), confirming overdispersion. Each additional comorbidity increased hospital visits by 42% (IRR=1.42, 95% CI [1.30, 1.55], z=7.85, p<.001). Age positively predicted visits: each 10-year increase multiplied visits by 1.34 (IRR=1.03 per year, 95% CI [1.01, 1.05], z=2.73, p=.006). Private insurance patients had 26% fewer visits than public insurance patients (IRR=0.74, 95% CI [0.58, 0.95], z=-2.31, p=.021). Residual diagnostics indicated adequate fit with 2 observations showing high leverage but not influential (Cook's D<0.5). Findings highlight comorbidity burden as strongest predictor of healthcare utilization.
Reusable template

A negative binomial regression was conducted to predict count outcome from list predictors (N = XXX). State why NB chosen: e.g., variance substantially exceeded mean (variance/mean ratio = X.XX), indicating overdispersion. Comparison to Poisson regression confirmed negative binomial provided superior fit (AIC difference = XX; likelihood ratio test χ²(1) = XX.XX, p < .XXX). State assumption checks: independence, linearity, multicollinearity, sample size. The negative binomial model was significant overall (McFadden R² = .XX). Report dispersion parameter: theta = X.XX, SE = X.XX, confirming overdispersion. For each significant predictor: Predictor name was a significant positive/negative predictor (IRR = X.XX, 95% CI X.XX, X.XX, z = X.XX, p = .XXX), indicating substantive interpretation: e.g., 'each unit increase multiplied count by X.XX' or 'increased count by XX%'. Residual diagnostics indicated adequate model fit with number influential outliers if any; describe handling. Conclude with interpretation in context.

Essential statistics to report
  • Sample size (n) and outcome description (count, range, mean, variance, variance/mean ratio)
  • Justification for NB over Poisson (variance/mean ratio, overdispersion test, AIC/BIC comparison, LR test)
  • Overall model test: χ² (or deviance difference), df, p-value
  • Pseudo-R² (at least one: McFadden, Nagelkerke, or Cox-Snell)
  • Dispersion parameter (θ or α) with SE or 95% CI
  • For each predictor: IRR (exp(β)), 95% CI, z-statistic, p-value
  • Substantive interpretation of IRRs (e.g., 'X% increase per unit' or 'multiplies count by X.XX')
  • Statement about assumption checks (independence, overdispersion confirmed, linearity, multicollinearity/VIF, sample size/EPV)
  • Residual diagnostics (deviance residuals, influential cases)
  • Model comparison results if testing against other models (Poisson, zero-inflated, etc.)
10Exhibit Builder

Manuscript Lab

Copy standard summary tables and forensic reporting grids to outline analysis details.

Table 1: Negative Binomial Regression for Overdispersed Counts
PredictorBSEzpIRR95% CI
(Intercept)0.850.223.86< .0012.34[1.52, 3.60]
Severity Score0.420.085.25< .0011.52[1.30, 1.78]
Follow-up (1=Yes)-0.650.15-4.33< .0010.52[0.39, 0.70]
Note. Outcome: Frequency of hospital readmissions. Dispersion Parameter (theta) = 2.45 (p < .001). N = 320.
theta (2.45)Confirms the 'Clustering Effect'. Hospital readmissions are highly variable; NB is required to prevent standard error deflation.
Follow-up IRR = 0.52Powerful proof of efficacy. Active follow-up programs reduce readmission rates by 48%.
Header glossary

The Overdispersion Anchor. A significant theta proves that the variance exceeds the mean, justifying the use of NB over Poisson.

Incidence Rate Ratio. Interpreted as the factor by which the count changes for a unit increase in the predictor.

11Algorithmic Logic

Command Center

Syntax libraries and function parameters for executing calculations in stats packages.

Code your model to handle residuals. The errors tell you what your model missed.
Execution Engine
# 1. Fit Negative Binomial Model
model <- MASS::glm.nb(readmissions ~ severity + followup, data = df)

# 2. Extract IRR with CIs
parameters::model_parameters(model, exponentiate = TRUE)
Library stack
R
MASSparameters
Python
statsmodels
Elite Forensic Strike

Negative Binomial is the 'Safe Haven' for count data. If you aren't 100% sure your variance equals your mean, use NB.

# Rootogram Audit (Visualizing Over/Under Fitting of Counts)
countreg::rootogram(model)

# Direct Comparison (Poisson vs NB)
performance::compare_performance(poisson_mod, nb_mod)
12The Over-adjustment Trap

Common Mistakes

Analytical caveats and corrections to maintain modeling integrity.

Wisdom is learning from the failures of others. Anticipate the error before it occurs.
Defensive Logic
Why it's wrong
When variance exceeds mean (overdispersion), Poisson standard errors are severely underestimated, leading to inflated Type I error rates (false positives). P-values are anti-conservative (too small), confidence intervals too narrow, and significance tests invalid. This is the MOST COMMON and SERIOUS mistake in count modeling. Example: if true variance/mean=4.0, Poisson SEs are roughly halved, making non-significant effects appear significant. Overdispersion is nearly universal in real data due to unobserved heterogeneity
The correction
ALWAYS check for overdispersion before using Poisson: (1) Calculate variance/mean ratio; if >1.5, suspect overdispersion; (2) Fit Poisson model and check deviance/df or Pearson χ²/df (ratios >1.5 indicate overdispersion); (3) Conduct formal Cameron-Trivedi overdispersion test (dispersiontest in AER package); (4) Compare Poisson vs. NB using AIC/BIC (ΔAIC>2 favors NB) and likelihood ratio test. If overdispersed, use negative binomial regression. Report all diagnostics: variance/mean ratio, dispersion parameter estimate, LR test, AIC comparison. State: 'Overdispersion detected; negative binomial model used to correct standard errors and provide valid inference'
Why it's wrong
Raw NB coefficients (β) are on the log-count scale and nearly impossible to interpret meaningfully. A coefficient of 0.35 does NOT mean 'count increases by 0.35'—it means log(count) increases by 0.35, which corresponds to a multiplicative effect. Failure to exponentiate leads to misinterpretation and inability to communicate results. Reviewers and readers expect IRRs, not log-IRRs
The correction
ALWAYS exponentiate coefficients to obtain Incidence Rate Ratios: IRR = exp(β). Report IRRs with substantive interpretation: 'IRR=1.42 means a 42% increase in count per unit increase in predictor' or 'IRR=1.42 indicates count multiplies by 1.42'. For multi-unit changes: IRR^k (e.g., 10-year increase: IRR^10). Exponentiate confidence intervals too: exp(CI_lower), exp(CI_upper). Include both β (for technical audience) and IRR (for interpretation) in supplementary tables. Never report only log-coefficients without IRRs
Why it's wrong
If data are NOT overdispersed (variance ≈ mean), Poisson regression is more efficient, has better power, and is simpler (fewer parameters). Using NB unnecessarily adds complexity, reduces power slightly, and wastes degrees of freedom. Assuming overdispersion without testing is as bad as assuming equidispersion. Example: if true variance/mean=1.1, NB dispersion parameter will be near zero and Poisson is preferred
The correction
ALWAYS compare Poisson vs. NB: (1) Fit both models and compare AIC/BIC (lower is better; ΔAIC>2 is meaningful); (2) Conduct likelihood ratio test (LR test χ²(1) tests H₀: α=0); (3) Examine dispersion parameter estimate and 95% CI (if CI includes 0 or θ is very large, Poisson may suffice); (4) Report comparison: 'NB provided superior fit (AIC=1487 vs. 1560 for Poisson; LR χ²(1)=75.2, p<.001)'. If Poisson adequate, use it. Document decision process. Don't default to NB without justification
Why it's wrong
Standard NB assumes zeros occur at rate predicted by negative binomial distribution. Excess zeros (more than NB predicts) indicate a separate process generating zeros, violating distributional assumptions and producing poor fit. Example: In publication counts, structural zeros (researchers who never publish) differ from sampling zeros (active researchers with zero pubs in observation window). NB underpredicts zeros, leading to biased estimates and poor predictions
The correction
Examine frequency of zeros: calculate observed proportion vs. NB-predicted proportion. Use rootogram (plot observed vs. expected counts; 'hanging' bars at zero indicate poor fit). If observed zeros >> expected zeros (say, observed 40% vs. expected 20%), consider zero-inflated negative binomial (ZINB) model. Conduct Vuong test comparing NB vs. ZINB (significant result favors ZINB). Compare AIC/BIC. Report: 'Zero-inflation detected (45% observed vs. 22% predicted zeros); ZINB model used (Vuong z=3.8, p<.001)'. ZINB combines logistic model for excess zeros with NB for counts
Why it's wrong
NB assumes predictors have linear relationships with log(count): log(E[Y])=β₀+β₁X. Non-linear relationships (U-shaped, threshold effects) lead to biased estimates, poor predictions, and missed effects. Example: If age has U-shaped effect (high counts for young and old, low for middle-aged), linear age term misses this pattern and may show no effect when strong non-linear effect exists. Simply plotting raw count vs. predictor is insufficient (must check on log scale)
The correction
Test linearity on log scale: (1) Plot deviance residuals vs. continuous predictors; look for curvature or patterns; (2) Component-residual plots (partial residual plots) with lowess smoother; (3) Test polynomial terms: fit model with X², check if coefficient significant; (4) Compare models with/without polynomial or spline terms using AIC/BIC and likelihood ratio test. If non-linear: add X² or X³ terms; use restricted cubic splines (rcs package); or use generalized additive model (GAM) with NB family for fully non-parametric smoothing. Report linearity checks: 'Linearity assessed via component-residual plots; no violations detected' or 'Age showed non-linear effect; quadratic term added (LR χ²(1)=12.5, p<.001)'
Why it's wrong
When observations have different exposure periods (e.g., patients monitored for different lengths of time) or different areas/populations (e.g., counties with different populations), raw counts aren't comparable. NB without offset estimates total counts, not rates, producing misleading comparisons. Example: Comparing hospital visits for patient monitored 6 months vs. 12 months without offset biases results—longer exposure mechanically produces higher counts independent of predictors
The correction
Include offset term when exposure varies: glm.nb(count ~ x1 + x2 + offset(log(exposure))). Offset forces coefficient to 1 (not estimated), modeling rates (count per unit exposure) rather than raw counts. Exposure must be >0 and on same scale for all observations. IRRs then represent rate ratios controlling for exposure. Example: For county crime counts with different populations, use offset(log(population)). For longitudinal counts with variable follow-up, use offset(log(time)). Report: 'Offset for exposure time included to model rates'. ALWAYS use offset when exposure/population/area varies
Why it's wrong
NB assumes independence of observations. Clustered data (multiple observations per unit: students in schools, patients in hospitals) or repeated measures (same subjects over time) violate independence, leading to underestimated standard errors and inflated Type I error. Observations within clusters are correlated; ignoring this treats them as independent, artificially inflating effective sample size. Overdispersion often signals unmodeled dependence, but accounting for overdispersion alone doesn't fix dependence problem
The correction
For clustered data: use mixed-effects negative binomial model (GLMM with random intercepts for clusters): glmer.nb in lme4 package. For repeated measures: use generalized estimating equations (GEE) with NB family or mixed-effects NB with random intercepts/slopes for subjects. For spatial data: include spatial random effects or spatial correlation structures. Test for within-cluster correlation (ICC). Adjust inferences: cluster-robust standard errors if clustering mild. Report: 'Mixed-effects NB with random intercepts for hospitals accounted for clustering (ICC=0.18)'. NEVER ignore clustering—it severely biases SEs and invalidates tests
Why it's wrong
With small samples relative to number of predictors, NB estimates are unstable, standard errors are underestimated (inflating Type I error), and overfitting occurs (model fits noise, doesn't generalize). Example: n=50 with 5 predictors and mean count=3 yields only 150 total events, or 30 events per predictor—below recommended EPV≥50-100 for count models. You may get 'significant' results that are spurious and don't replicate. Small sample problems more severe for count models than linear models
The correction
Calculate EPV = (total events) / (number of predictors), where total events = Σyᵢ (sum of all counts, not just n). Aim for EPV≥10 absolute minimum, EPV≥50-100 preferred for stable estimates. If EPV<10: (1) Reduce predictors (use theory, prior research, or univariate screening); (2) Collect more data (preferred); (3) Use penalized NB if available (ridge, LASSO—stabilizes estimates); (4) Simplify model (no interactions, no polynomials). AVOID overfitting: don't interpret marginal predictors; use cross-validation to assess generalizability. ALWAYS report: n, mean count, variance, EPV. State: 'Adequate sample size (EPV=85)' or 'Limited sample size (EPV=12); results interpreted cautiously'
13Academic Lineage

References

Scholarly lineage and citation keys grounding the statistical framework.

We stand on the shoulders of giants. Honor the source of the method.
Academic Lineage
[1]
Cameron, A. C., & Trivedi, P. K. (2013). Regression analysis of count data (2nd ed.). Cambridge University Press.
Definitive textbook on count models. Comprehensive coverage of Poisson, negative binomial, zero-inflated, and hurdle models. Includes overdispersion tests, model diagnostics, and extensions. Essential reference for NB regression theory and applications in economics and social sciences
doi: 10.1017/CBO9781139013567
[2]
Hilbe, J. M. (2014). Modeling count data. Cambridge University Press.
Practical guide to count regression models with extensive examples across disciplines. Covers NB regression, zero-inflation, hurdle models, and mixed-effects count models. Includes software implementations in R, Stata, and SAS. Excellent for applied researchers
doi: 10.1017/CBO9781139236065
[3]
Ver Hoef, J. M., & Boveng, P. L. (2007). Quasi-Poisson vs. negative binomial regression: How should we model overdispersed count data? Ecology, 88(11), 2766-2772.
Compares approaches to handling overdispersion: quasi-Poisson (adjusts SEs only) vs. negative binomial (models overdispersion explicitly). Recommends NB for most applications because it provides full likelihood and better model comparison (AIC/BIC). Demonstrates ecological applications
doi: 10.1890/07-0043.1
[4]
Gardner, W., Mulvey, E. P., & Shaw, E. C. (1995). Regression analyses of counts and rates: Poisson, overdispersed Poisson, and negative binomial models. Psychological Bulletin, 118(3), 392-404.
Accessible introduction to Poisson and negative binomial regression for behavioral scientists. Explains overdispersion clearly with psychological examples (hospitalization, arrests, violent incidents). Demonstrates why overdispersion is ubiquitous in social science data and consequences of ignoring it
doi: 10.1037/0033-2909.118.3.392
[5]
Long, J. S. (1997). Regression models for categorical and limited dependent variables. Sage Publications.
Chapter 8 covers count models (Poisson, negative binomial, zero-inflated) with focus on interpretation and presentation. Uses faculty publication data as running example, showing overdispersion due to unobserved heterogeneity in ability and resources. Excellent for understanding substantive interpretation of count models in social research
doi: 10.4135/9781412984782
In the world of counts, the Poisson model is an ideal; the Negative Binomial is the reality. Respect the noise, or the noise will silence your discovery.
The Interpretive Rigor Directive
statminds · NegativeMind reference · v2.2 · updated 2026-01-1715 of 15 sections