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.2.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.2-py3-none-any.whl (12.8 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: regdiag-0.1.2.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.2.tar.gz
Algorithm Hash digest
SHA256 05a8c73375f5dd43acfdd97f5f4f66e7f3d03c22ed961e78630ac9aba06a01c0
MD5 50af97a9f2b8c45c13e5432e0640a5d8
BLAKE2b-256 5e7f24025a58d5aca771fad9d865e0b8a645dba30a416381dac1fa9a56d49b66

See more details on using hashes here.

Provenance

The following attestation bundles were made for regdiag-0.1.2.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.2-py3-none-any.whl.

File metadata

  • Download URL: regdiag-0.1.2-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.2-py3-none-any.whl
Algorithm Hash digest
SHA256 b4edd90a2f6a9d39f20256cd9a35ca9d57cbe5cbe1069384c030ee78e34eb08c
MD5 81a51b82526d57a8d4e7359664f635f6
BLAKE2b-256 3aefd12bbfc32c503ae708026436eb2c6d5b141524077f014b88ca2f643c2fd7

See more details on using hashes here.

Provenance

The following attestation bundles were made for regdiag-0.1.2-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