Changelog
All notable changes to this project are documented here. The format follows Keep a Changelog and the project uses semantic versioning.
Unreleased
Fixed
- AIC, AICc and BIC of a Gaussian model whose formula transforms the response
(
np.log(y),np.log1p,np.log2,np.log10,np.sqrt,np.exporI(y**p)) now include the Jacobian of the transformation, as R'sperformancedoes. They were on the scale of the transformed response, socompare_performance()madenp.log(y) ~ xlook far better thany ~ x: on one dataset an AIC of 1110 instead of R's 3275, against 4050 for the untransformed model. Applies to OLS, WLS, Gaussian GLMs andMixedLM(with a warning under REML, as in R).Log_likis unchanged. compare_performance()no longer warns that the models were fit on different data when they only transform the same response differently.
0.2.0 - 2026-10-26
Changed
- Breaking:
check_model()no longer tests linear models for autocorrelation by default, so the report has no"autocorrelation"key and its result no longer counts towardsreport.passed. On cross-sectional data the Durbin-Watson test only reacts to how the rows happen to be sorted (themtcarsexample in the README reported p = 0.041), and R'scheck_model()does not run it either. It is added automatically when the observations are indexed by time (a pandasDatetimeIndexorPeriodIndex). To keep the 0.1.0 behaviour, request it:check_model(m, checks=[..., "autocorrelation"]).check_autocorrelation()is unchanged. The combined plot of a linear model has six panels instead of seven. check_collinearity()fails (passed=False) when the model matrix is rank deficient, with the message "Perfect collinearity: the model matrix is rank deficient (aliased terms: ...)". It still emits the "Model matrix is rank deficient" warning.- Normality checks that fail on 5000 or more residuals (Kolmogorov-Smirnov) add a note that large samples flag trivial departures and point to the Q-Q plot. The verdict and the p-value are unchanged.
- Plots of large models: past 5000 observations each panel draws a
deterministic subsample that keeps the points outside the bands and the
observations flagged by Cook's distance, the lowess smoother interpolates
between nearby fits, and density curves past 10 000 values use a binned
kernel density estimate.
check_model(fit).plot()on 200 000 observations takes a few seconds instead of about two minutes. Plots of up to 5000 observations are drawn exactly as before.
Added
CollinearityResult.rank_deficientandCollinearityResult.aliased: the design-matrix columns that are linear combinations of earlier ones, the coefficients R reports asNA. Also available asBaseAdapter.aliased.- A warning for penalized fits (
Ridge,Lasso,ElasticNet, penalizedLogisticRegression,PoissonRegressorandGammaRegressorwithalpha > 0): their leverage, Cook's distance and standardized residuals are computed as for the unpenalized model and are approximate.check_model()warns once and notes it in the report header;check_outliers(),check_normality(),check_heteroscedasticity()andcheck_collinearity()warn when called on their own. - A warning for binomial models with complete separation (every fitted
probability within 1e-6 of 0 or 1) from
check_model(),check_outliers(),check_collinearity(),binned_residuals()andcheck_residuals(). - README: status line, "Open in Colab" badges for the example notebooks, a
short table of R equivalents and how to request the autocorrelation check.
The notebooks install
checkmodeland read their data from GitHub when run on Colab. - Tests of the Bayesian model reader that need neither ArviZ, PyMC nor bambi,
so
_bayes.pyis fully covered on every supported Python version.
Fixed
- The
mtcarsexample in the README no longer reports a spurious "Autocorrelated residuals detected" warning. - A rank-deficient model (for example a dummy for every category plus the
intercept) was reported as "OK: Low collinearity" with
passed=True. - Diagnostics of penalized models were reported as "OK" with no sign that the influence measures ignore the penalty.
check_model(fit).plot()took minutes on large data (about 108 s for 200 000 rows), almost all of it in kernel density estimates of every replicated dataset.
0.1.0 - 2026-10-22
First public release.
Added
check_model(): runs every check that applies to a model and draws a combined diagnostic panel. Every model starts with a posterior predictive check, as in R;random_state=keeps reports reproducible.- Assumption checks with typed results (
.passed,.statistic,.p_value,.plot(),.to_dataframe()):check_normality()(residuals and random effects),check_heteroscedasticity(),check_collinearity(),check_outliers(),check_autocorrelation(),binned_residuals(),check_overdispersion(),check_zeroinflation(),check_singularity(),check_convergence()andcheck_predictions(). - Simulated residuals as in DHARMa:
simulate_residuals()andcheck_residuals(), used for non-Gaussian models and wherever R'sperformanceuses them. - Metrics:
r2()and its variants (Tjur, Cox & Snell, Nagelkerke, McFadden, Nakagawa, Bayesian),icc(),variance_components(),looic(),model_performance()andcompare_performance(). - Models:
- statsmodels OLS, WLS, GLM (Gaussian, binomial, Poisson, negative
binomial, Gamma, inverse Gaussian; logit, probit, cloglog, log, identity,
inverse and sqrt links),
Logit,Probit,Poisson,NegativeBinomialandMixedLM; - scikit-learn
LinearRegression,Ridge,Lasso,ElasticNet, binaryLogisticRegression,PoissonRegressorandGammaRegressor; - PyMC and bambi models through
bayesian()(pip install "checkmodel[bayes]", Python 3.12+); - anything implementing the
ModelAdapterprotocol, or registered withregister_adapter(). - Matplotlib plots for every check, in the style of R's
seepackage. - Validation against R: every statistic is compared with
performance0.18.2,lme4,lmtest,car,MASS,rstanarm,looandposterior(to 1e-4) on 27 reference models; Bayesian statistics on the same posterior draws. Deliberate differences are listed indocs/comparison-with-r.md.