Inference¶
Hypothesis Tests¶
- aurora.inference.hypothesis.wald.wald_test(result, contrast, *, value=0.0, include_intercept=True)[source]¶
Perform a Wald test for (possibly multi-constraint) linear hypotheses.
- Parameters:
result (GLMResult) – Fitted GLM result providing coefficient estimates and covariance.
contrast (Iterable[float] | Sequence[Sequence[float]] | ndarray) – Coefficient weights defining the hypothesis
C beta = value. Accepts one-dimensional vectors (single constraint) or matrices with one row per constraint.value (float | Iterable[float] | ndarray) – Hypothesised values for the linear combination(s). Can be a scalar or an iterable matching the number of constraints.
include_intercept (bool) – Whether the contrast coefficients include the model intercept as the first element when present.
- Returns:
Mapping with keys
statistic,p_valueanddf.- Return type:
Confidence Intervals¶
Diagnostics¶
Robust Covariance¶
- aurora.inference.robust.robust_covariance(result, *, hc_type='HC3')[source]¶
Compute heteroscedasticity-consistent (sandwich) covariance matrix.
Computes robust standard errors that are valid under heteroscedasticity and potential model misspecification. The sandwich estimator has the form:
Var(β) = (X’WX)⁻¹ M (X’WX)⁻¹
where W is the diagonal of final IRLS weights and M is the meat, built from Pearson residuals with an HC-type correction.
- Parameters:
result (GLMResult) – Fitted GLM result object
hc_type ({'HC0', 'HC1', 'HC2', 'HC3', 'HC4'}, default='HC3') –
Type of heteroscedasticity-consistent standard errors:
’HC0’: White (1980) - basic sandwich estimator, no correction
’HC1’: Degrees of freedom correction (n/(n-p))
’HC2’: Leverage correction (1/(1-h_i))
’HC3’: MacKinnon & White (1985) - 1/(1-h_i)², better for small samples
’HC4’: Cribari-Neto (2004) - best for influential points
HC3 is recommended for general use.
- Returns:
Container with robust standard errors and covariance matrix
- Return type:
RobustInferenceResult
- Raises:
RuntimeError – If design matrix or response are not available in result
ValueError – If hc_type is not recognized
Notes
The GLM sandwich (Zeileis 2006) uses, unlike the plain OLS version:
bread = (XᵀWX)⁻¹ with the final IRLS weights W = diag(prior_wᵢ / [g’(μᵢ)² V(μᵢ)]). For Gaussian/identity models this reduces to (XᵀX)⁻¹. The dispersion estimate φ̂ cancels between bread and meat, so it is not applied explicitly (this matches statsmodels, whose GLM robust covariances are scale-free).
meat = Xᵀ diag(Wᵢ · rᵢ² · cᵢ) X with Pearson residuals rᵢ = (yᵢ − μᵢ)/√V(μᵢ) and the HC correction cᵢ.
leverage hᵢ from the weighted hat matrix H = W¹ᐟ²X(XᵀWX)⁻¹XᵀW¹ᐟ², used by HC2/HC3/HC4.
Verified against
statsmodels.GLM.fit(cov_type='HC0')(which, for GLMs, returns identical values for HC0–HC3: statsmodels does not apply leverage corrections to GLM sandwiches) and, for Gaussian/identity models, againststatsmodels.OLS.fit(cov_type='HC0'...'HC3')where the corrections do apply.Examples
>>> from aurora.models import fit_glm >>> from aurora.inference import robust_covariance >>> import numpy as np >>> >>> # Fit a model with heteroscedastic errors >>> x = np.random.randn(100) >>> y = 2 * x + np.random.randn(100) * (1 + 0.5 * np.abs(x)) >>> result = fit_glm(x.reshape(-1, 1), y, family='gaussian') >>> >>> # Get robust standard errors >>> robust_result = robust_covariance(result, hc_type='HC3') >>> print(robust_result.std_errors)
References
- White, H. (1980). A heteroskedasticity-consistent covariance matrix estimator
and a direct test for heteroskedasticity. Econometrica, 48(4), 817-838.
- MacKinnon, J.G., & White, H. (1985). Some heteroskedasticity-consistent
covariance matrix estimators with improved finite sample properties. Journal of Econometrics, 29(3), 305-325.
ANOVA¶
Analysis of variance (analysis of deviance) for GLM and GAM models.
This module provides ANOVA functionality for analyzing model effects and comparing nested models.
Single-model table¶
For a single fitted GLM, anova_glm reports partial (Type III-style)
Wald tests per coefficient:
W_j = β̂_j² / Var(β̂_j)
where Var(β̂_j) is the diagonal of the model covariance matrix (already
scaled by the dispersion estimate φ̂). For Gaussian models with
test='F' the reference distribution is F(1, df_resid) (equivalent to
the squared t-statistic, matching statsmodels.stats.anova_lm with
typ=3); otherwise W_j ~ χ²₁ asymptotically.
Model comparison¶
For several nested models, anova_glm reports sequential deviance
differences (analysis of deviance, R anova.glm convention):
test='Chisq'/'LRT': ΔD ~ χ²_Δdf — valid for nested GLMs of the same family with known dispersion (Poisson, Binomial), where the deviance difference equals the likelihood-ratio statistic.test='F': F = (ΔD/Δdf) / φ̂ with φ̂ taken from the largest model — the convention for Gaussian models with estimated dispersion. For non-Gaussian familiestest='F'falls back to the χ² test with a warning.
Examples
>>> from aurora.inference.anova import anova_glm, likelihood_ratio_test
>>>
>>> # Single-model Wald table (Type III-style)
>>> anova_glm(result, type=3)
>>>
>>> # Compare nested models
>>> anova_glm(reduced_model, full_model, test="Chisq")
>>> likelihood_ratio_test(reduced_model, full_model)
References
- class aurora.inference.anova.ANOVAResult(df, ss, ms, f_statistic, p_value, source, anova_type, residual_df, residual_ss, test='F')[source]¶
Bases:
objectResult of an ANOVA test.
- Variables:
df (ndarray) – Degrees of freedom for each source.
ss (ndarray) – Sum of squares for each source. For single-model Wald tables this holds the per-coefficient Wald statistics (χ² scale); for model comparisons it holds the (non-negative) deviance differences.
ms (ndarray) – Mean squares (SS / df).
f_statistic (ndarray) – Test statistics: F values when
test='F', χ² values otherwise.p_value (ndarray) – P-values for each test.
anova_type (int) – Type of ANOVA performed (1, 2, or 3).
residual_df (int) – Residual degrees of freedom of the (largest) model.
residual_ss (float) – Residual deviance (Gaussian: residual sum of squares) of the (largest) model.
test (str) – Reference distribution used for the p-values (‘F’ or ‘Chisq’).
- Parameters:
- class aurora.inference.anova.LRTResult(statistic, df, p_value, model_names, ll_reduced, ll_full, boundary_conditions=None, boundary_correction_applied=False)[source]¶
Bases:
objectResult of a likelihood ratio test.
- Variables:
statistic (float) – Chi-squared test statistic (2 * (LL_full - LL_reduced)).
df (int) – Degrees of freedom (difference in parameters).
p_value (float) – P-value from chi-squared distribution.
boundary_conditions (list of str) – Variance parameters detected at or near boundary.
boundary_correction_applied (bool) – Whether Self & Liang (1987) mixture correction was applied.
- Parameters:
- aurora.inference.anova.anova_glm(*models, type=3, test='F')[source]¶
Perform ANOVA on one or more GLM models.
- Parameters:
*models (ModelResult) – One or more fitted model results. With one model, produces a table of partial Wald tests per coefficient. With multiple models, performs a sequential analysis of deviance (models are sorted by number of parameters).
type ({1, 2, 3}, default=3) – Type of sum of squares. Only
type=3(partial tests) is supported for a single model: it requires no refits and is order-independent. For multiple models the comparison is always sequential (Type I style).test ({'F', 'Chisq', 'LRT'}, default='F') –
Test statistic / reference distribution:
'F': F test. For a single Gaussian model this is the squared t-statistic with F(1, df_resid) reference. For model comparison of Gaussian models, F = (ΔD/Δdf)/φ̂ with φ̂ from the largest model (Ranova.glmconvention). For non-Gaussian families it falls back to the χ² test with a warning.'Chisq'/'LRT': χ² test on the Wald statistics (single model) or on the deviance differences (model comparison). The deviance difference equals the likelihood-ratio statistic for families with unit dispersion (Poisson, Binomial).
- Returns:
result – ANOVA result with table and statistics.
- Return type:
Examples
>>> from aurora import fit_glm, Gaussian >>> from aurora.inference.anova import anova_glm >>> >>> result = fit_glm(X, y, family=Gaussian()) >>> anova_glm(result, type=3)
>>> # Compare nested models >>> m1 = fit_glm(X[:, :2], y) >>> m2 = fit_glm(X, y) >>> anova_glm(m1, m2, test="Chisq")
Notes
Type III (partial) tests: each coefficient is tested adjusted for all other terms via its Wald statistic. Sequential (Type I) tests for a single model would require refitting sub-models and are not currently implemented.
- aurora.inference.anova.anova(*models, type=3, test='F')¶
Perform ANOVA on one or more GLM models.
- Parameters:
*models (ModelResult) – One or more fitted model results. With one model, produces a table of partial Wald tests per coefficient. With multiple models, performs a sequential analysis of deviance (models are sorted by number of parameters).
type ({1, 2, 3}, default=3) – Type of sum of squares. Only
type=3(partial tests) is supported for a single model: it requires no refits and is order-independent. For multiple models the comparison is always sequential (Type I style).test ({'F', 'Chisq', 'LRT'}, default='F') –
Test statistic / reference distribution:
'F': F test. For a single Gaussian model this is the squared t-statistic with F(1, df_resid) reference. For model comparison of Gaussian models, F = (ΔD/Δdf)/φ̂ with φ̂ from the largest model (Ranova.glmconvention). For non-Gaussian families it falls back to the χ² test with a warning.'Chisq'/'LRT': χ² test on the Wald statistics (single model) or on the deviance differences (model comparison). The deviance difference equals the likelihood-ratio statistic for families with unit dispersion (Poisson, Binomial).
- Returns:
result – ANOVA result with table and statistics.
- Return type:
Examples
>>> from aurora import fit_glm, Gaussian >>> from aurora.inference.anova import anova_glm >>> >>> result = fit_glm(X, y, family=Gaussian()) >>> anova_glm(result, type=3)
>>> # Compare nested models >>> m1 = fit_glm(X[:, :2], y) >>> m2 = fit_glm(X, y) >>> anova_glm(m1, m2, test="Chisq")
Notes
Type III (partial) tests: each coefficient is tested adjusted for all other terms via its Wald statistic. Sequential (Type I) tests for a single model would require refitting sub-models and are not currently implemented.
- aurora.inference.anova.likelihood_ratio_test(model_reduced, model_full, *, names=None)[source]¶
Perform likelihood ratio test comparing two nested models.
- Parameters:
- Returns:
result – Likelihood ratio test result.
- Return type:
Examples
>>> from aurora.inference.anova import likelihood_ratio_test >>> >>> lrt = likelihood_ratio_test(reduced_model, full_model) >>> print(lrt)
Notes
The test statistic is:
\[\chi^2 = 2 (\ell_{full} - \ell_{reduced})\]This follows a chi-squared distribution with df equal to the difference in the number of parameters. The statistic is truncated at zero; a warning is issued when the raw difference is negative beyond numerical noise (the models are then likely not nested).
Boundary correction. When a variance component is detected at (or numerically near) the boundary of the parameter space (e.g. σ² ≈ 0), the null distribution is a 50:50 mixture of χ²_df and χ²_{df-1} (Self & Liang 1987, case 5; Stram & Lee 1994). For df = 1 the second component is χ²₀, a point mass at zero, whose survival function is 0 for any positive statistic, giving p = 0.5·P(χ²₁ > t). The correction is applied whenever any variance parameter of either model is at the boundary; this is conservative when the boundary parameter is not the one being tested.
GAMM caveats. Two warnings apply to
GAMMResultinputs:Non-Gaussian GAMMs are fitted by PQL, whose log-likelihood is a conditional (quasi-)likelihood given the variance components, not a marginal likelihood. Likelihood-ratio tests on it are not valid for comparing fixed effects (Pinheiro & Bates 2000, §2.4).
Gaussian GAMMs report the REML log-likelihood, which is not comparable between models with different fixed-effects structures.
- aurora.inference.anova.lrt(model_reduced, model_full, *, names=None)¶
Perform likelihood ratio test comparing two nested models.
- Parameters:
- Returns:
result – Likelihood ratio test result.
- Return type:
Examples
>>> from aurora.inference.anova import likelihood_ratio_test >>> >>> lrt = likelihood_ratio_test(reduced_model, full_model) >>> print(lrt)
Notes
The test statistic is:
\[\chi^2 = 2 (\ell_{full} - \ell_{reduced})\]This follows a chi-squared distribution with df equal to the difference in the number of parameters. The statistic is truncated at zero; a warning is issued when the raw difference is negative beyond numerical noise (the models are then likely not nested).
Boundary correction. When a variance component is detected at (or numerically near) the boundary of the parameter space (e.g. σ² ≈ 0), the null distribution is a 50:50 mixture of χ²_df and χ²_{df-1} (Self & Liang 1987, case 5; Stram & Lee 1994). For df = 1 the second component is χ²₀, a point mass at zero, whose survival function is 0 for any positive statistic, giving p = 0.5·P(χ²₁ > t). The correction is applied whenever any variance parameter of either model is at the boundary; this is conservative when the boundary parameter is not the one being tested.
GAMM caveats. Two warnings apply to
GAMMResultinputs:Non-Gaussian GAMMs are fitted by PQL, whose log-likelihood is a conditional (quasi-)likelihood given the variance components, not a marginal likelihood. Likelihood-ratio tests on it are not valid for comparing fixed effects (Pinheiro & Bates 2000, §2.4).
Gaussian GAMMs report the REML log-likelihood, which is not comparable between models with different fixed-effects structures.