API reference
Model checks
checkmodel.check_model(model, X=None, y=None, *, checks='all', alpha=0.05, random_state=0)
Run every assumption check that applies to model.
The model type decides what runs, as in performance::check_model().
Every model gets a posterior predictive check first, then:
- linear models: normality, heteroscedasticity, collinearity and
outliers, plus autocorrelation when the observations are indexed by
time (a :class:
pandas.DatetimeIndexor :class:pandas.PeriodIndex); - linear mixed models: normality of residuals and of random effects, heteroscedasticity, collinearity, outliers, singularity and convergence;
- logistic regression: collinearity, outliers, binned residuals and uniformity of simulated residuals;
- count models (Poisson, negative binomial): collinearity, outliers, overdispersion and uniformity of simulated residuals;
- other GLMs: collinearity, outliers and uniformity of simulated residuals;
- Bayesian models (see :func:
checkmodel.bayesian): convergence.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
Model
|
A fitted statsmodels or scikit-learn model, or a Bayesian model. |
required |
X
|
ArrayLike | None
|
Training data; required for scikit-learn models. |
None
|
y
|
ArrayLike | None
|
Training data; required for scikit-learn models. |
None
|
checks
|
str | Iterable[str]
|
|
'all'
|
alpha
|
float
|
Significance level for the formal tests. |
0.05
|
random_state
|
int | None
|
Seed for the simulations (predictive check, simulated residuals), so
that reports are reproducible; |
0
|
Returns:
| Type | Description |
|---|---|
ModelCheckReport
|
|
Warns:
| Type | Description |
|---|---|
UserWarning
|
Once per call, for a penalized fit (ridge, lasso, ...), whose leverage, Cook's distance and standardized residuals ignore the penalty, and for a binomial model with complete separation. |
Examples:
>>> report = check_model(fit)
>>> report.plot()
>>> report["normality"].p_value
>>> check_model(fit, checks=["normality", "autocorrelation"])
checkmodel.ModelCheckReport
Bases: Mapping[str, CheckResult]
All checks run by :func:check_model, accessible by name.
Behaves like a read-only dictionary, report["normality"], and adds
:meth:summary and :meth:plot.
Attributes:
| Name | Type | Description |
|---|---|---|
skipped |
Checks that were requested but do not apply, with the reason. |
passed
property
True when every check that ran passed.
summary()
One row per check: method, statistic, p-value, verdict and message.
to_dataframe()
Alias of :meth:summary.
plot(**kwargs)
Draw every diagnostic in one grid (up to 2 rows x 3 columns).
Keyword arguments are passed to
:func:checkmodel.plotting.plot_model_check.
checkmodel.check_normality(model, X=None, y=None, *, alpha=0.05, effects='fixed')
check_normality(model: Model, X: ArrayLike | None = ..., y: ArrayLike | None = ..., *, alpha: float = ..., effects: Literal['fixed'] = ...) -> NormalityResult
check_normality(model: Model, X: ArrayLike | None = ..., y: ArrayLike | None = ..., *, alpha: float = ..., effects: Literal['random']) -> RandomEffectsNormalityResult
Check whether the residuals of a linear model are normally distributed.
Port of performance::check_normality(). The studentized residuals
(rstandard() in R, rstudent() for mixed models) are tested with
Shapiro-Wilk when there are fewer than 5000 of them, and with a
Kolmogorov-Smirnov test against the standard normal otherwise.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
Model
|
A fitted linear model (statsmodels OLS/WLS/MixedLM, a Gaussian GLM with identity link, or a scikit-learn linear regressor). |
required |
X
|
ArrayLike | None
|
Training data; required for scikit-learn models. |
None
|
y
|
ArrayLike | None
|
Training data; required for scikit-learn models. |
None
|
alpha
|
float
|
Significance level. The check fails when |
0.05
|
effects
|
Literal['fixed', 'random']
|
|
'fixed'
|
Returns:
| Type | Description |
|---|---|
NormalityResult or RandomEffectsNormalityResult
|
|
Raises:
| Type | Description |
|---|---|
CheckNotApplicableError
|
For non-Gaussian models, where normal residuals are not expected, or
|
Warns:
| Type | Description |
|---|---|
UserWarning
|
For a penalized fit, whose standardized residuals ignore the penalty. |
Notes
Formal normality tests reject trivial departures in large samples. Look
at the Q-Q plot (result.plot()) before acting on a small p-value.
Examples:
>>> import statsmodels.formula.api as smf
>>> from checkmodel import check_normality
>>> fit = smf.ols("mpg ~ wt + hp", data=mtcars).fit()
>>> check_normality(fit)
Warning: Non-normality of residuals detected (p = 0.021).
checkmodel.check_heteroscedasticity(model, X=None, y=None, *, alpha=0.05)
Test a linear model for non-constant error variance.
Port of performance::check_heteroscedasticity(): the original
(non-studentized) Breusch-Pagan / Cook-Weisberg score test of the
squared Pearson residuals against the fitted values, as in
car::ncvTest(). It is equivalent to
statsmodels.stats.diagnostic.het_breuschpagan(resid, [1, fitted],
robust=False).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
Model
|
A fitted linear model. |
required |
X
|
ArrayLike | None
|
Training data; required for scikit-learn models. |
None
|
y
|
ArrayLike | None
|
Training data; required for scikit-learn models. |
None
|
alpha
|
float
|
Significance level. The check fails when |
0.05
|
Returns:
| Type | Description |
|---|---|
HeteroscedasticityResult
|
|
Raises:
| Type | Description |
|---|---|
CheckNotApplicableError
|
For non-Gaussian models. |
Warns:
| Type | Description |
|---|---|
UserWarning
|
For a penalized fit, whose residual degrees of freedom ignore the penalty. |
checkmodel.check_collinearity(model, X=None, y=None, *, ci=0.95, threshold=HIGH_VIF)
Compute variance inflation factors for each model term.
Port of performance::check_collinearity(). VIFs come from the
correlation matrix of the coefficient estimates, so a term encoded by
several columns (a categorical variable) gets one generalized VIF
(Fox & Monette, 1992). Confidence intervals follow Marcoulides et al.
(2019).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
Model
|
Any supported model with at least two terms. |
required |
X
|
ArrayLike | None
|
Training data; required for scikit-learn models. |
None
|
y
|
ArrayLike | None
|
Training data; required for scikit-learn models. |
None
|
ci
|
float
|
Confidence level of the VIF intervals. |
0.95
|
threshold
|
float
|
The check fails when any VIF reaches this value. VIF < 5 is considered low, 5-10 moderate and >= 10 high. |
HIGH_VIF
|
Returns:
| Type | Description |
|---|---|
CollinearityResult
|
|
Raises:
| Type | Description |
|---|---|
CheckNotApplicableError
|
If the model has fewer than two terms. |
Warns:
| Type | Description |
|---|---|
UserWarning
|
When the model has no intercept or its model matrix is rank deficient; also for a penalized fit and for a binomial model with complete separation. |
Notes
For scikit-learn models the coefficient correlation is computed from
X (weighted by p(1-p) for logistic regression), which equals the
unpenalized fit. The VIF describes the predictors, not the penalty.
checkmodel.check_outliers(model, X=None, y=None, *, threshold='f')
Find influential observations with Cook's distance.
Port of performance::check_outliers(method = "cook").
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
Model
|
Any supported model. |
required |
X
|
ArrayLike | None
|
Training data; required for scikit-learn models. |
None
|
y
|
ArrayLike | None
|
Training data; required for scikit-learn models. |
None
|
threshold
|
float | Literal['f', '4/n']
|
|
'f'
|
Returns:
| Type | Description |
|---|---|
OutliersResult
|
|
Warns:
| Type | Description |
|---|---|
UserWarning
|
For a penalized fit, and for a binomial model with complete separation. |
Notes
For penalized scikit-learn models (ridge, lasso, elastic net) leverage comes from the design matrix, as if the model were unpenalized; the residuals are the penalized model's own.
checkmodel.check_autocorrelation(model, X=None, y=None, *, alpha=0.05, method='auto', nsim=1000, random_state=None)
Test residuals of a linear model for first-order autocorrelation.
Computes the Durbin-Watson statistic with a two-sided p-value. Rows are taken in the order the model was fitted on, so sort time series by time before fitting.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
Model
|
A fitted linear model. |
required |
X
|
ArrayLike | None
|
Training data; required for scikit-learn models. |
None
|
y
|
ArrayLike | None
|
Training data; required for scikit-learn models. |
None
|
alpha
|
float
|
Significance level. The check fails when |
0.05
|
method
|
Method
|
How to compute the p-value:
|
'auto'
|
nsim
|
int
|
Bootstrap replicates ( |
1000
|
random_state
|
int | None
|
Seed for the bootstrap. |
None
|
Returns:
| Type | Description |
|---|---|
AutocorrelationResult
|
|
Raises:
| Type | Description |
|---|---|
CheckNotApplicableError
|
For non-Gaussian models. |
checkmodel.binned_residuals(model, X=None, y=None, *, term=None, n_bins=None, ci=0.95, ci_type='exact', residuals=None)
Average residuals within bins of the fitted values of a binomial model.
Port of performance::binned_residuals(). With a well-specified model
about 95% of the binned mean residuals fall inside the error bounds; the
check fails when fewer than 80% do.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
Model
|
A fitted binomial model (logistic regression). |
required |
X
|
ArrayLike | None
|
Training data; required for scikit-learn models. |
None
|
y
|
ArrayLike | None
|
Training data; required for scikit-learn models. |
None
|
term
|
str | None
|
Name of a design-matrix column to bin on instead of the fitted values. |
None
|
n_bins
|
int | None
|
Number of bins; defaults to |
None
|
ci
|
float
|
Coverage of the error bounds. |
0.95
|
ci_type
|
Literal['exact', 'gaussian']
|
|
'exact'
|
residuals
|
Literal['response', 'pearson', 'deviance'] | None
|
Residual type; |
None
|
Returns:
| Type | Description |
|---|---|
BinnedResidualsResult
|
|
checkmodel.check_overdispersion(model, X=None, y=None, *, alpha=0.05, residual_type=None, alternative='two-sided', iterations=250, random_state=None)
Test a generalized linear (mixed) model for over- or underdispersion.
Port of performance::check_overdispersion(). Which residuals are used
follows R:
- Poisson GLMs: the Pearson chi-squared statistic
sum((y - mu)^2 / mu)against a chi-squared distribution onn - kdegrees of freedom (Gelman & Hill, 2007). - Bernoulli, binomial, negative binomial and other GLMs, and mixed models:
DHARMa's test on simulated residuals (see :func:
simulate_residuals), which compares the variance of the observed residuals with the variance of residuals simulated from the model.
A dispersion ratio well above 1 means the variance exceeds what the model allows, so standard errors are too small; consider a negative binomial or quasi-Poisson model.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
Model | SimulatedResiduals
|
A fitted GLM or mixed model, or the output of :func: |
required |
X
|
ArrayLike | None
|
Training data; required for scikit-learn models. |
None
|
y
|
ArrayLike | None
|
Training data; required for scikit-learn models. |
None
|
alpha
|
float
|
Significance level. The check fails when |
0.05
|
residual_type
|
str | None
|
|
None
|
alternative
|
str
|
Alternative hypothesis of the simulated test: |
'two-sided'
|
iterations
|
int
|
Number of simulations for the simulated test. |
250
|
random_state
|
int | Generator | None
|
Seed for the simulations. |
None
|
Returns:
| Type | Description |
|---|---|
OverdispersionResult
|
|
Raises:
| Type | Description |
|---|---|
CheckNotApplicableError
|
For linear models fitted by least squares, and for Pearson residuals of Bernoulli, non-count or mixed models. |
checkmodel.check_zeroinflation(model, X=None, y=None, *, tolerance=None, alternative='two-sided', iterations=250, random_state=None)
Compare the zeros a count model predicts with the zeros observed.
Port of performance::check_zeroinflation(). For Poisson models the
predicted number of zeros is round(sum(exp(-mu))). For negative
binomial models, or when given the output of :func:simulate_residuals,
it is the mean number of zeros over the simulated datasets, and a p-value
compares the observed count with the simulated ones. When the ratio of
predicted to observed zeros falls below 1 - tolerance the model
underfits zeros, a sign of zero-inflation; consider a zero-inflated or
hurdle model.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
Model | SimulatedResiduals
|
A fitted Poisson or negative binomial model, or the output of
:func: |
required |
X
|
ArrayLike | None
|
Training data; required for scikit-learn models. |
None
|
y
|
ArrayLike | None
|
Training data; required for scikit-learn models. |
None
|
tolerance
|
float | None
|
Accepted relative deviation of the ratio from 1. Defaults to 0.05, or 0.1 with simulated residuals, as in R. |
None
|
alternative
|
str
|
Alternative hypothesis of the simulated test. |
'two-sided'
|
iterations
|
int
|
Number of simulations for negative binomial models. |
250
|
random_state
|
int | Generator | None
|
Seed for the simulations. |
None
|
Returns:
| Type | Description |
|---|---|
ZeroInflationResult
|
|
Raises:
| Type | Description |
|---|---|
CheckNotApplicableError
|
For models that are not count models, or when the response has no zeros. |
checkmodel.check_singularity(model, X=None, y=None, *, tolerance=1e-05)
Check whether a mixed model's random-effects structure is singular.
Port of performance::check_singularity(): the fit is singular when
the determinant of the random-effects variance-covariance matrix is below
tolerance, that is when some variance is (close to) zero or some
correlation is (close to) ±1. A singular fit usually means the
random-effects structure is too complex for the data.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
Model
|
A fitted statsmodels |
required |
X
|
ArrayLike | None
|
Unused; accepted for a uniform signature. |
None
|
y
|
ArrayLike | None
|
Unused; accepted for a uniform signature. |
None
|
tolerance
|
float
|
Determinant below which the fit counts as singular. |
1e-05
|
Returns:
| Type | Description |
|---|---|
SingularityResult
|
|
Raises:
| Type | Description |
|---|---|
CheckNotApplicableError
|
If the model has no random effects. |
checkmodel.check_convergence(model, X=None, y=None, *, tolerance=0.001)
Check whether the model fit converged.
Port of performance::check_convergence(). For mixed models the fit
counts as converged when the optimizer reports success and the largest
absolute relative gradient (H^-1 g) at the optimum is below
tolerance, the criterion R uses for lme4 fits. Other models use
their optimizer's own report: IRLS for GLMs, the iteration limit for
iterative scikit-learn estimators; OLS and WLS are solved exactly.
Bayesian models converge when every parameter has rank-normalized
R-hat below 1.01 and bulk and tail effective sample sizes of at least 100
per chain (Vehtari et al., 2021), computed as R's posterior package.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
Model
|
Any supported model. |
required |
X
|
ArrayLike | None
|
Training data; required for scikit-learn models. |
None
|
y
|
ArrayLike | None
|
Training data; required for scikit-learn models. |
None
|
tolerance
|
float
|
Largest acceptable relative gradient (mixed models only). |
0.001
|
Returns:
| Type | Description |
|---|---|
ConvergenceResult
|
|
Notes
statsmodels and lme4 parameterize the random effects differently, so the gradient value itself is not comparable with R's; the verdict is.
checkmodel.check_predictions(model, X=None, y=None, *, iterations=50, alpha=0.05, random_state=None)
Compare data replicated from the model with the observed data.
Port of performance::check_predictions(). For Bayesian models the
replications are posterior predictive draws; for frequentist models they
are simulated from the fitted distribution (simulate() in R; mixed
models draw new group effects). The plot overlays the replicated and
observed distributions; the table reports posterior predictive p-values
for the mean, the SD and, for counts, the share of zeros.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
Model
|
A frequentist model, or a Bayesian one from :func: |
required |
X
|
ArrayLike | None
|
Training data; required for scikit-learn models. |
None
|
y
|
ArrayLike | None
|
Training data; required for scikit-learn models. |
None
|
iterations
|
int
|
Number of replicated datasets to simulate and plot. For Bayesian models the p-values use every posterior predictive draw. |
50
|
alpha
|
float
|
The check fails when a p-value falls outside |
0.05
|
random_state
|
int | None
|
Seed for the simulations and for choosing which draws to plot. |
None
|
Returns:
| Type | Description |
|---|---|
PredictionsResult
|
|
checkmodel.check_residuals(model, X=None, y=None, *, alternative='two-sided', distribution=None, iterations=250, alpha=0.05, random_state=None)
Test whether simulated quantile residuals are uniformly distributed.
Port of performance::check_residuals(). The residuals from
:func:simulate_residuals are uniform when the model is right, so a
Kolmogorov-Smirnov test against the uniform distribution detects a wrong
family, over- or underdispersion, zero-inflation and similar problems in
any model, Gaussian or not.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
Model | SimulatedResiduals
|
A fitted model, or the output of :func: |
required |
X
|
ArrayLike | None
|
Training data; required for scikit-learn models. |
None
|
y
|
ArrayLike | None
|
Training data; required for scikit-learn models. |
None
|
alternative
|
str
|
|
'two-sided'
|
distribution
|
Callable[[FloatArray], FloatArray] | None
|
Cumulative distribution function to test against; uniform by default. |
None
|
iterations
|
int
|
Number of simulations when |
250
|
alpha
|
float
|
Significance level. The check fails when |
0.05
|
random_state
|
int | Generator | None
|
Seed for the simulations when |
None
|
Returns:
| Type | Description |
|---|---|
ResidualsResult
|
|
Simulated residuals
checkmodel.simulate_residuals(model, X=None, y=None, *, iterations=250, random_state=None)
Simulate randomized quantile residuals from a model.
Port of performance::simulate_residuals(), which wraps
DHARMa::simulateResiduals(). New responses are drawn iterations
times from the fitted model (mixed models draw new group effects); each
observation's residual is the share of its simulated values that fall
below it, with ties randomized (Dunn & Smyth, 1996). If the model is right
the residuals are uniform on [0, 1] whatever its family, which makes
them the residuals of choice for non-Gaussian models.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
Model
|
A fitted frequentist model. |
required |
X
|
ArrayLike | None
|
Training data; required for scikit-learn models. |
None
|
y
|
ArrayLike | None
|
Training data; required for scikit-learn models. |
None
|
iterations
|
int
|
Number of simulated datasets, at least 2. R's default is 250. |
250
|
random_state
|
int | Generator | None
|
Seed or generator, for reproducible residuals. |
None
|
Returns:
| Type | Description |
|---|---|
SimulatedResiduals
|
|
Raises:
| Type | Description |
|---|---|
CheckNotApplicableError
|
When responses cannot be simulated for the model's family. |
checkmodel.SimulatedResiduals
dataclass
Randomized quantile residuals simulated from a fitted model.
Returned by :func:simulate_residuals; can be passed to
:func:check_residuals, :func:~checkmodel.check_overdispersion and
:func:~checkmodel.check_zeroinflation so that they all use the same
simulations, as R's performance_simres objects.
Attributes:
| Name | Type | Description |
|---|---|---|
adapter |
BaseAdapter
|
The model the responses were simulated from. |
observed |
FloatArray
|
Observed response. |
fitted |
FloatArray
|
Fitted values on the response scale. |
simulated |
FloatArray
|
Simulated responses, shape |
scaled_residuals |
FloatArray
|
Quantile residuals in |
iterations
property
Number of simulated datasets.
residuals(quantile_function=None, outlier_values=None)
Return the scaled residuals, optionally transformed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
quantile_function
|
Callable[[FloatArray], FloatArray] | None
|
Applied to the residuals, e.g. :func: |
None
|
outlier_values
|
tuple[float, float] | None
|
Values that replace |
None
|
Returns:
| Type | Description |
|---|---|
ndarray
|
|
to_dataframe()
One row per observation: observed and fitted values and the scaled residual.
plot(ax=None)
Q-Q plot of the scaled residuals against the uniform distribution.
Result types
checkmodel.CheckResult
dataclass
Outcome of a single assumption check.
Attributes:
| Name | Type | Description |
|---|---|---|
passed |
bool
|
Whether the assumption holds at the chosen threshold. |
method |
str
|
Name of the test or rule that was applied. |
statistic |
float | None
|
Test statistic, when the check is a formal test. |
p_value |
float | None
|
p-value of the test, when there is one. |
message |
str
|
One-line verdict in the style of R's |
summary()
Return the one-line verdict.
to_dataframe()
Return the result as a one-row :class:pandas.DataFrame.
plot(ax=None)
Draw the diagnostic plot for this check.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ax
|
Axes | None
|
Axes to draw on. When omitted a new figure is created; some checks then add a second panel (normality adds a histogram). |
None
|
Returns:
| Type | Description |
|---|---|
Figure
|
|
checkmodel.NormalityResult
dataclass
Bases: CheckResult
Result of :func:check_normality.
Attributes:
| Name | Type | Description |
|---|---|---|
residuals |
FloatArray
|
The standardized residuals that were tested. |
checkmodel.HeteroscedasticityResult
dataclass
Bases: CheckResult
Result of :func:check_heteroscedasticity.
statistic is the score chi² with df degrees of freedom.
checkmodel.CollinearityResult
dataclass
Bases: CheckResult
Result of :func:check_collinearity.
statistic is the largest VIF. table has one row per model term
with the same columns as R: Term, VIF, VIF_CI_low,
VIF_CI_high, SE_factor, Tolerance, Tolerance_CI_low and
Tolerance_CI_high.
Attributes:
| Name | Type | Description |
|---|---|---|
rank_deficient |
bool
|
Whether the model matrix is rank deficient (perfect collinearity). The check then fails whatever the VIFs say. |
aliased |
list[str]
|
Design-matrix columns that are exact linear combinations of earlier
ones: the coefficients R reports as |
vif
property
VIF per term.
to_dataframe()
Return the VIF table, one row per term.
checkmodel.OutliersResult
dataclass
Bases: CheckResult
Result of :func:check_outliers.
Attributes:
| Name | Type | Description |
|---|---|---|
distances |
Series
|
Cook's distance per observation, indexed by the observation labels. |
threshold |
float
|
Cut-off above which an observation counts as influential. |
outliers |
list[Any]
|
Labels of the influential observations. |
to_dataframe()
Return one row per observation with its influence measures.
checkmodel.AutocorrelationResult
dataclass
checkmodel.BinnedResidualsResult
dataclass
Bases: CheckResult
Result of :func:binned_residuals.
statistic is the share of bins whose mean residual lies inside the
error bounds; table has one row per bin.
to_dataframe()
Return the per-bin table.
checkmodel.RandomEffectsNormalityResult
dataclass
Bases: CheckResult
Result of check_normality(model, effects="random").
p_value is the smallest p-value across random-effect terms; table
has one row per term and effects the conditional modes (BLUPs) tested.
to_dataframe()
Return one row per random-effect term.
checkmodel.OverdispersionResult
dataclass
Bases: CheckResult
Result of :func:check_overdispersion.
With Pearson residuals, statistic is Pearson's chi-squared and
dispersion_ratio that statistic divided by the residual degrees of
freedom df. With simulated residuals there is no chi-squared statistic:
dispersion_ratio compares the variance of the observed residuals with
that of the simulated ones, and simulation holds the simulations.
checkmodel.ZeroInflationResult
dataclass
Bases: CheckResult
Result of :func:check_zeroinflation. statistic is predicted / observed zeros.
p_value is set, and simulation holds the simulations, when the
check uses simulated residuals.
checkmodel.SingularityResult
dataclass
Bases: CheckResult
Result of :func:check_singularity.
statistic is the determinant of the random-effects covariance matrix;
variances lists the variance of each random-effect term.
to_dataframe()
Return one row per random-effect term with its variance.
checkmodel.ConvergenceResult
dataclass
Bases: CheckResult
Result of :func:check_convergence.
For mixed models statistic is the largest absolute relative gradient
at the optimum; it is None when only the optimizer's flag is known.
For Bayesian models it is the largest R-hat, and table lists R-hat
and bulk/tail effective sample sizes per parameter.
to_dataframe()
Return the per-parameter diagnostics (Bayesian models) or the summary row.
checkmodel.PredictionsResult
dataclass
Bases: CheckResult
Result of :func:check_predictions.
Attributes:
| Name | Type | Description |
|---|---|---|
observed |
FloatArray
|
The observed response. |
simulated |
FloatArray
|
Replicated datasets, one per row (posterior predictive draws, or simulations from the fitted model). |
table |
DataFrame
|
For each test statistic: observed value, mean over replications and
the posterior predictive p-value |
discrete |
bool
|
Whether the response takes few integer values (counts, 0/1). |
to_dataframe()
Return one row per test statistic.
checkmodel.ResidualsResult
dataclass
Bases: CheckResult
Result of :func:check_residuals.
statistic is the Kolmogorov-Smirnov D.
Attributes:
| Name | Type | Description |
|---|---|---|
simulation |
SimulatedResiduals | None
|
The :class: |
alternative |
str
|
Alternative hypothesis of the test. |
residuals
property
The scaled (quantile) residuals.
Performance metrics
checkmodel.r2
Coefficients of determination and pseudo-R² measures.
R2Result
Bases: Mapping[str, float]
Read-only mapping of R² measures, e.g. {"R2": 0.83, "R2_adjusted": 0.81}.
to_dataframe()
Return the measures as a one-row :class:pandas.DataFrame.
r2(model, X=None, y=None)
Compute the R² measure that suits the model, as performance::r2().
- Linear models: R² and adjusted R².
- Gaussian GLMs: R² (
1 - SSE/SST). - Logistic regression (logit link) with a 0/1 outcome: Tjur's R².
- Other GLMs (Poisson, probit, ...): Nagelkerke's R².
- Linear mixed models: Nakagawa's conditional and marginal R².
- Bayesian models: Bayesian R² (see :func:
r2_bayes).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
Model
|
Any supported model. |
required |
X
|
ArrayLike | None
|
Training data; required for scikit-learn models. |
None
|
y
|
ArrayLike | None
|
Training data; required for scikit-learn models. |
None
|
Returns:
| Type | Description |
|---|---|
R2Result
|
Mapping from measure name to value. |
r2_tjur(model, X=None, y=None)
Tjur's coefficient of discrimination for binary outcomes.
The difference between the mean predicted probability of the two outcome groups (Tjur, 2009).
r2_coxsnell(model, X=None, y=None)
Cox & Snell's pseudo-R², 1 - exp((D - D0) / n).
r2_nagelkerke(model, X=None, y=None)
Nagelkerke's pseudo-R²: Cox & Snell's rescaled to reach 1.
r2_mcfadden(model, X=None, y=None)
McFadden's pseudo-R² and its adjusted version, 1 - (LL - k) / LL0.
checkmodel.R2Result
Bases: Mapping[str, float]
Read-only mapping of R² measures, e.g. {"R2": 0.83, "R2_adjusted": 0.81}.
to_dataframe()
Return the measures as a one-row :class:pandas.DataFrame.
checkmodel.r2_tjur(model, X=None, y=None)
Tjur's coefficient of discrimination for binary outcomes.
The difference between the mean predicted probability of the two outcome groups (Tjur, 2009).
checkmodel.r2_coxsnell(model, X=None, y=None)
Cox & Snell's pseudo-R², 1 - exp((D - D0) / n).
checkmodel.r2_nagelkerke(model, X=None, y=None)
Nagelkerke's pseudo-R²: Cox & Snell's rescaled to reach 1.
checkmodel.r2_mcfadden(model, X=None, y=None)
McFadden's pseudo-R² and its adjusted version, 1 - (LL - k) / LL0.
checkmodel.r2_nakagawa(model, X=None, y=None, *, tolerance=1e-08)
Nakagawa's marginal and conditional R² for linear mixed models.
Port of performance::r2_nakagawa(). The marginal R² is the variance
explained by the fixed effects; the conditional R² by fixed and random
effects together (Nakagawa, Johnson & Schielzeth, 2017).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
Model
|
A fitted statsmodels |
required |
X
|
ArrayLike | None
|
Unused; accepted for a uniform signature. |
None
|
y
|
ArrayLike | None
|
Unused; accepted for a uniform signature. |
None
|
tolerance
|
float
|
Singularity tolerance. For a singular fit the conditional R² is
|
1e-08
|
Returns:
| Type | Description |
|---|---|
R2Result
|
|
checkmodel.model_performance(model, X=None, y=None, *, metrics='all', estimator=None)
Compute performance metrics for one model, as performance::model_performance().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
Model
|
Any supported model. |
required |
X
|
ArrayLike | None
|
Training data; required for scikit-learn models. |
None
|
y
|
ArrayLike | None
|
Training data; required for scikit-learn models. |
None
|
metrics
|
str | Iterable[str]
|
|
'all'
|
estimator
|
Literal['ML', 'REML'] | None
|
Likelihood behind AIC, AICc and BIC for mixed models: |
None
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
One row. Metrics that do not apply to the model are left out, as in R:
for example |
Notes
AIC and BIC count the residual variance as a parameter for Gaussian
models, like R's AIC(). statsmodels' OLSResults.aic does not, so
its values are 2 lower. Penalized scikit-learn models have no
likelihood-based criteria; AIC, AICc and BIC are omitted for them.
When the formula transforms a Gaussian response (np.log(y),
np.log1p, np.log2, np.log10, np.sqrt, np.exp or
I(y**p)), AIC, AICc and BIC include the Jacobian of the
transformation, as in R. They are then on the scale of y and can be
compared with those of y ~ .... Log_lik is left uncorrected.
checkmodel.compare_performance(*models, names=None, metrics='all', rank=False, X=None, y=None, verbose=True, **named_models)
Compare the performance of several models, as performance::compare_performance().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
*models
|
Any
|
Fitted models. A scikit-learn model fitted on its own data can be
given as a |
()
|
names
|
Sequence[str] | None
|
Names for the positional models; defaults to |
None
|
metrics
|
str | Iterable[str]
|
Passed to :func: |
'all'
|
rank
|
bool
|
Add a |
False
|
X
|
ArrayLike | None
|
Shared training data for scikit-learn models. |
None
|
y
|
ArrayLike | None
|
Shared training data for scikit-learn models. |
None
|
verbose
|
bool
|
Warn when the models were apparently not fit on the same data. |
True
|
**named_models
|
Any
|
Models passed by keyword use the keyword as their name:
|
{}
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
One row per model with |
Mixed models
checkmodel.icc
Variance decomposition of mixed models: ICC and Nakagawa's R².
VarianceComponents
dataclass
Variance decomposition of a linear mixed model, as insight::get_variance().
Attributes:
| Name | Type | Description |
|---|---|---|
fixed |
float
|
Variance of the fixed-effects predictions, |
random |
float
|
Mean variance explained by the random effects, |
residual |
float
|
Residual variance, |
ICCResult
variance_components(model, X=None, y=None, *, tolerance=1e-08)
Split the variance of a linear mixed model into fixed, random and residual parts.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
Model
|
A fitted statsmodels |
required |
X
|
ArrayLike | None
|
Unused; accepted for a uniform signature. |
None
|
y
|
ArrayLike | None
|
Unused; accepted for a uniform signature. |
None
|
tolerance
|
float
|
Below this determinant of the random-effects covariance the fit is
singular and the random variance is reported as |
1e-08
|
Returns:
| Type | Description |
|---|---|
VarianceComponents
|
|
icc(model, X=None, y=None, *, tolerance=1e-05)
Intraclass correlation coefficient of a linear mixed model.
Port of performance::icc(). The adjusted ICC is the share of the
random-effects variance in the random plus residual variance; the
unadjusted (conditional) ICC also counts the fixed-effects variance in
the denominator. With random slopes the random variance is averaged over
the observed covariate values (Johnson, 2014).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
Model
|
A fitted statsmodels |
required |
X
|
ArrayLike | None
|
Unused; accepted for a uniform signature. |
None
|
y
|
ArrayLike | None
|
Unused; accepted for a uniform signature. |
None
|
tolerance
|
float
|
Singularity tolerance. For a singular fit R returns |
1e-05
|
Returns:
| Type | Description |
|---|---|
ICCResult
|
|
Raises:
| Type | Description |
|---|---|
CheckNotApplicableError
|
If the model has no random effects. |
r2_nakagawa(model, X=None, y=None, *, tolerance=1e-08)
Nakagawa's marginal and conditional R² for linear mixed models.
Port of performance::r2_nakagawa(). The marginal R² is the variance
explained by the fixed effects; the conditional R² by fixed and random
effects together (Nakagawa, Johnson & Schielzeth, 2017).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
Model
|
A fitted statsmodels |
required |
X
|
ArrayLike | None
|
Unused; accepted for a uniform signature. |
None
|
y
|
ArrayLike | None
|
Unused; accepted for a uniform signature. |
None
|
tolerance
|
float
|
Singularity tolerance. For a singular fit the conditional R² is
|
1e-08
|
Returns:
| Type | Description |
|---|---|
R2Result
|
|
checkmodel.ICCResult
checkmodel.variance_components(model, X=None, y=None, *, tolerance=1e-08)
Split the variance of a linear mixed model into fixed, random and residual parts.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
Model
|
A fitted statsmodels |
required |
X
|
ArrayLike | None
|
Unused; accepted for a uniform signature. |
None
|
y
|
ArrayLike | None
|
Unused; accepted for a uniform signature. |
None
|
tolerance
|
float
|
Below this determinant of the random-effects covariance the fit is
singular and the random variance is reported as |
1e-08
|
Returns:
| Type | Description |
|---|---|
VarianceComponents
|
|
checkmodel.VarianceComponents
dataclass
Variance decomposition of a linear mixed model, as insight::get_variance().
Attributes:
| Name | Type | Description |
|---|---|---|
fixed |
float
|
Variance of the fixed-effects predictions, |
random |
float
|
Mean variance explained by the random effects, |
residual |
float
|
Residual variance, |
Bayesian models
checkmodel.bayesian(idata, model=None, *, response=None, mu='mu', sigma='sigma', family=None, mu_marginal=None)
Prepare a fitted Bayesian model for checkmodel.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
idata
|
Any
|
Result of |
required |
model
|
Any
|
The |
None
|
response
|
str | None
|
Name of the observed variable; needed only when |
None
|
mu
|
str
|
PyMC only: posterior variable holding the expected value of each
observation, e.g. |
'mu'
|
sigma
|
str
|
PyMC only: posterior variable holding the residual SD. |
'sigma'
|
family
|
str | None
|
PyMC only: |
None
|
mu_marginal
|
str | None
|
PyMC only: posterior variable with expected values that leave out the group-level effects, for marginal R² of multilevel models. |
None
|
Returns:
| Type | Description |
|---|---|
BayesianModel
|
|
Examples:
>>> import bambi as bmb
>>> m = bmb.Model("Reaction ~ Days + (1|Subject)", sleepstudy)
>>> fit = bayesian(m.fit(), m)
>>> check_model(fit)
checkmodel.BayesianModel
dataclass
Posterior draws of a Bayesian regression, shaped (chains, draws, ...).
Build it with :func:bayesian. Attributes ending in _draws and
y_rep/log_lik hold one row per observation in the last axis.
Attributes:
| Name | Type | Description |
|---|---|---|
y |
FloatArray
|
Observed response (0/1 for binary models). |
mu |
FloatArray
|
Draws of the expected value of each observation ( |
family |
str
|
|
sigma |
FloatArray | None
|
Draws of the residual standard deviation (Gaussian models). |
mu_marginal |
FloatArray | None
|
Expected values without the group-level effects (mixed models). |
y_rep |
FloatArray | None
|
Posterior predictive draws. |
log_lik |
FloatArray | None
|
Pointwise log-likelihood draws. |
parameters |
dict[str, FloatArray]
|
Draws of each scalar parameter, used for convergence diagnostics. |
checkmodel.r2_bayes(model, *, ci=0.95, robust=True)
Bayesian R² (Gelman, Goodrich, Gabry & Vehtari, 2019), as performance::r2_bayes().
One R² per posterior draw: var(mu) / (var(mu) + residual variance),
with the model's residual variance (sigma² for Gaussian models,
mean(mu (1 - mu)) for binomial ones). For multilevel models the
residual variance is that of y - mu and a marginal R² (without the
group-level effects) is reported too, as R does for stanreg fits.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
Any
|
Output of :func: |
required |
ci
|
float
|
Probability mass of the highest density interval. |
0.95
|
robust
|
bool
|
Summarise with median and MAD (default, as R) instead of mean and SD. |
True
|
Returns:
| Type | Description |
|---|---|
BayesR2Result
|
|
checkmodel.BayesR2Result
Bases: Mapping[str, float]
Posterior summary of Bayesian R²: a mapping of point estimates.
Attributes:
| Name | Type | Description |
|---|---|---|
se |
Spread of each R² posterior (MAD when |
|
ci |
Highest density interval of each R² posterior. |
|
draws |
The R² posterior draws themselves. |
checkmodel.looic(model, *, use_relative_eff=False)
PSIS leave-one-out cross-validation, as performance::looic() / loo::loo().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
Any
|
Output of :func: |
required |
use_relative_eff
|
bool
|
Account for autocorrelation of the draws when choosing the Pareto tail
length, as |
False
|
Returns:
| Type | Description |
|---|---|
LooResult
|
ELPD, LOOIC and effective number of parameters with their standard errors, plus the Pareto k diagnostic of each observation. |
checkmodel.LooResult
dataclass
Pointwise and summed PSIS-LOO estimates, as loo::loo().
n_bad_k
property
Observations whose Pareto k exceeds 0.7 (unreliable importance sampling).
Plotting
checkmodel.plotting.plot_model_check(report, ncols=None, panel_size=(4.6, 3.7))
Draw every diagnostic of a :class:~checkmodel.ModelCheckReport in one grid.
Linear models get six panels: the posterior predictive check, linearity, homogeneity of variance, influential observations, collinearity and normality, plus autocorrelation when the report includes it. Bayesian models show the predictive check and the R-hat of each parameter. Mixed models add one Q-Q panel per random-effect term; count models an overdispersion panel; non-Gaussian models a uniform Q-Q plot of simulated residuals. Singularity and convergence have no plot.
With more than 5000 observations each panel draws a fixed-seed subsample that always keeps the points outside the bands and those flagged by Cook's distance; the checks themselves use every observation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
report
|
ModelCheckReport
|
Output of :func: |
required |
ncols
|
int | None
|
Number of grid columns; 3 by default (2 when there are four panels or fewer). |
None
|
panel_size
|
tuple[float, float]
|
Width and height of each panel in inches. |
(4.6, 3.7)
|
checkmodel.plotting.plot_uniformity(source, ax=None)
Q-Q plot of simulated quantile residuals against the uniform distribution.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
Any
|
A :class: |
required |
ax
|
Axes | None
|
Axes to draw on; a new figure is created when omitted. |
None
|
Returns:
| Type | Description |
|---|---|
Figure
|
|
Extending checkmodel
checkmodel.ModelAdapter
Bases: Protocol
Minimal interface checkmodel needs to diagnose a model.
Implement these five methods on any object (or pass a wrapper around your
model) and every check and metric in checkmodel will accept it. See
CONTRIBUTING.md for a worked example.
model_type()
Describe the model family, link and backend.
get_response()
Return the observed response, recoded to 0/1 for binary models.
get_fitted()
Return fitted values on the response scale.
get_residuals()
Return response residuals (observed minus fitted).
get_model_matrix()
Return the design matrix, including the intercept column if any.
checkmodel.ModelType
dataclass
What kind of model an adapter wraps.
The flags mirror insight::model_info() in R, which is what decides
which checks and metrics apply to a model.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
family
|
str
|
Error distribution: |
required |
link
|
str
|
Link function name, e.g. |
required |
backend
|
str
|
Library the model comes from ( |
required |
model_class
|
str
|
Class name of the wrapped model, used in comparison tables. |
required |
is_bernoulli
|
bool
|
Binomial model whose response is a single 0/1 outcome. |
False
|
is_penalized
|
bool
|
Fitted with a penalty (ridge, lasso, ...). Likelihood-based criteria such as AIC are not defined for these and are reported as missing. |
False
|
is_mixed
|
bool
|
Has random effects (a mixed model). |
False
|
is_linear
property
Gaussian family with identity link (an ordinary linear model).
is_binomial
property
Binomial family (logistic, probit, ... regression).
is_count
property
Count-data family (Poisson or negative binomial).
has_dispersion
property
Whether the family estimates a dispersion parameter (counts in AIC).
checkmodel.BaseAdapter
Bases: ABC
Uniform, cached view of a fitted model.
Subclasses implement the five :class:~checkmodel.ModelAdapter
primitives and, optionally, the metadata hooks (column_names,
terms, prior_weights, ...). Everything else is derived.
checkmodel.register_adapter(match, factory)
Teach checkmodel to read a new kind of model.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
match
|
type | Callable[[Any], bool]
|
A class (instances and subclasses match) or a predicate
|
required |
factory
|
AdapterFactory
|
Called as |
required |
Examples:
>>> from checkmodel import BaseAdapter, register_adapter
>>> class MyAdapter(BaseAdapter): ...
>>> register_adapter(MyModel, lambda m, X=None, y=None: MyAdapter(m))
checkmodel.as_adapter(model, X=None, y=None)
Wrap model in the adapter that knows how to read it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
Model
|
A fitted statsmodels result, a fitted scikit-learn estimator, an
existing adapter, or any object implementing
:class: |
required |
X
|
ArrayLike | None
|
Training data; required for scikit-learn models, ignored otherwise. |
None
|
y
|
ArrayLike | None
|
Training data; required for scikit-learn models, ignored otherwise. |
None
|
Raises:
| Type | Description |
|---|---|
UnsupportedModelError
|
If no adapter can read the model. |
Errors
checkmodel.CheckNotApplicableError
Bases: ValueError
Raised when a check does not make sense for the given model.
For example, testing residuals for normality is only meaningful for
linear (Gaussian, identity-link) models. :func:checkmodel.check_model
catches this error and simply skips the check.
checkmodel.UnsupportedModelError
Bases: TypeError
Raised when checkmodel does not know how to read a model object.