Skip to main content

R-style regression diagnostic plots (plot(lm)) for statsmodels and scikit-learn

Project description

regdiag

PyPI version Python versions License: MIT CI

R's plot(lm_model) for Python — one line, works with both statsmodels and scikit-learn.

R has a famous one-liner for regression diagnostics: plot(lm_model) produces four classic diagnostic plots (Residuals vs Fitted, Normal Q-Q, Scale-Location, Residuals vs Leverage). Python has never had a clean equivalent — the pieces exist scattered across statsmodels (only works on its own OLS objects) and a few small, low-traction packages. regdiag fills that gap.

from sklearn.linear_model import LinearRegression
import regdiag

model = LinearRegression().fit(X, y)
regdiag.diagnose(model, X, y)

Regression diagnostics example

Why regdiag

  • One line, R-style output. regdiag.diagnose(model, X, y) gives you the full 4-panel figure, same as plot(lm).
  • Works with statsmodels and scikit-learn. Any sklearn estimator exposing .coef_/.intercept_ (LinearRegression, Ridge, Lasso, ElasticNet, SGDRegressor, BayesianRidge, ...) or a statsmodels OLS results object.
  • statsmodels is fully optional. Core dependencies are just numpy, scipy, matplotlib, and scikit-learn. VIF and the Breusch-Pagan test are computed with plain numpy/scipy — no statsmodels needed at runtime, even though it's the library people usually reach for to get those numbers.
  • Honest about black-box models. Pass a RandomForestRegressor or any other model that only exposes .predict() and regdiag switches to a clearly-labeled generic mode (Residuals vs Fitted, Residual Distribution, Actual vs Predicted). It will never compute leverage or Cook's distance for a model where the hat-matrix math doesn't apply — those statistics are only well-defined for linear models.

Install

pip install regdiag

# with statsmodels support (accept statsmodels OLS objects as input):
pip install "regdiag[statsmodels]"

Quickstart

import numpy as np
from sklearn.linear_model import LinearRegression
import regdiag

rng = np.random.default_rng(0)
X = rng.normal(size=(200, 3))
y = 1.0 + X @ np.array([2.0, -1.5, 0.5]) + rng.normal(scale=1.0, size=200)

model = LinearRegression().fit(X, y)

diag = regdiag.diagnose(model, X, y)   # fits nothing, model must already be fit; shows the 4-panel plot
print(diag.summary())                   # Breusch-Pagan test, VIF table, top Cook's-distance points

Also works directly with statsmodels:

import statsmodels.api as sm

X_const = sm.add_constant(X)
results = sm.OLS(y, X_const).fit()
regdiag.diagnose(results, X, y)

And degrades gracefully for black-box models instead of lying about statistics:

from sklearn.ensemble import RandomForestRegressor

rf = RandomForestRegressor().fit(X, y)
diag = regdiag.diagnose(rf, X, y)   # 3-panel generic residual analysis
diag.vif()                           # raises NotLinearModelError — VIF isn't defined here

API

regdiag.diagnose(model, X, y, *, feature_names=None, plot=True,
                  figsize=(10, 8), annotate=True, n_annotate=3, save=None)

Returns a RegressionDiagnostics object:

Attribute / method Linear mode Generic mode
.residuals, .fitted_values
.leverage, .cooks_distance, .studentized_residuals None
.plot() 4-panel 3-panel
.residuals_vs_fitted(), .qq_plot(), .scale_location(), .residuals_vs_leverage() raises NotLinearModelError
.residual_histogram(), .actual_vs_predicted()
.breusch_pagan(), .vif() raises NotLinearModelError
.summary() text report text report

Comparison

regdiag lmdiag statsmodels (raw) yellowbrick
Works with sklearn linear models
Works with statsmodels OLS
statsmodels is optional at runtime n/a
Built-in VIF / Breusch-Pagan ✅ (manual)
Honest black-box fallback (no fake leverage) partial
One-object API (diagnose(model, X, y)) functions manual partial

Statistical notes

  • Leverage is computed via QR decomposition of the design matrix (never forms the full n × n hat matrix).
  • Cook's distance uses the classic OLS-based formula. It's applied uniformly to any linear-coefficient model (including Ridge/Lasso) for simplicity, but strictly its "influence on fitted coefficients" interpretation assumes an OLS estimator — interpret with some caution for heavily regularized models.
  • Rank-deficient design matrices (collinear columns) and n ≤ p datasets raise a clear error rather than emitting NaN/inf silently.
  • statsmodels WLS/GLS results are not supported in v1 (OLS only).

See CHANGELOG.md for release notes and CONTRIBUTING.md to get set up for development.

License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

regdiag-0.1.1.tar.gz (242.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

regdiag-0.1.1-py3-none-any.whl (12.8 kB view details)

Uploaded Python 3

File details

Details for the file regdiag-0.1.1.tar.gz.

File metadata

  • Download URL: regdiag-0.1.1.tar.gz
  • Upload date:
  • Size: 242.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for regdiag-0.1.1.tar.gz
Algorithm Hash digest
SHA256 03d80d82e94e5146b56ae5c070197053b29897218fcf25a245b418e874c6538a
MD5 a88c842156642d7342b5054606889b97
BLAKE2b-256 88e277599098a8f44675f41e415ef905c5ead707f54aa04f5cb5b8a5469303ed

See more details on using hashes here.

Provenance

The following attestation bundles were made for regdiag-0.1.1.tar.gz:

Publisher: publish.yml on SparksFlash/regdiag

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file regdiag-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: regdiag-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 12.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for regdiag-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 88b0bc8c10aede2f6f66a4d4dbedc952a7cbe6ca610b315c97987fb60313a454
MD5 e6c500a965be6bbe7fc4818d7aab6837
BLAKE2b-256 966531984cd753bb95f667d3feaa38374bf922bc97df88874e09450c9015ea2a

See more details on using hashes here.

Provenance

The following attestation bundles were made for regdiag-0.1.1-py3-none-any.whl:

Publisher: publish.yml on SparksFlash/regdiag

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page