regression_diagnostics/lib.rs
1//! # regression-diagnostics
2//!
3//! Statistical diagnostics for **ordinary least squares** regression models in
4//! Rust — the surface R's `car`/`lmtest` and Python's `statsmodels` expose, in a
5//! dependency-light crate. It fills the specific ecosystem gap that no maintained
6//! Rust crate offers Variance Inflation Factor, adjusted R², or residual
7//! diagnostics (autocorrelation, heteroskedasticity, normality, influence).
8//!
9//! Everything operates on a single fitted-model type, [`OlsFit`], computed once
10//! and reused by every diagnostic.
11//!
12//! ## Scope
13//!
14//! The core is **OLS diagnostics**, whose closed-form structure (a well-defined
15//! hat matrix and Gaussian residuals) is what makes them well-defined. Two
16//! further model families each get their own module, because their diagnostics
17//! are genuinely different — not reskinned OLS formulas:
18//!
19//! * [`regularized`] — ridge and lasso, where the hat matrix changes
20//! (`H_λ = X(XᵀX + λI)⁻¹Xᵀ`) or does not exist in closed form; diagnostics are
21//! built on **effective degrees of freedom** and the **active set**.
22//! * [`logistic`] — binary logistic regression, a non-Gaussian likelihood with
23//! deviance/Pearson residuals, pseudo-R², and the Hosmer–Lemeshow test.
24//!
25//! ## Linear algebra
26//!
27//! Internals use `nalgebra` (pure-Rust QR/SVD, no system BLAS — chosen for
28//! portability); the public API speaks `ndarray`. That boundary and its tradeoff
29//! are documented in the README.
30//!
31//! ## Layout
32//!
33//! * [`OlsFit`] — the fitted model; constructed with [`OlsFit::new`] or
34//! [`OlsFit::with_intercept`]. **Read its intercept convention before use.**
35//! * [`multicollinearity`] — [`vif`](multicollinearity::vif),
36//! [`condition_number`](multicollinearity::condition_number).
37//! * [`fit_statistics`] — R²/adjusted R², F-statistic, AIC/BIC, log-likelihood.
38//! * [`residuals`] — Durbin-Watson, Breusch-Pagan, White, Jarque-Bera, the scaled
39//! residual forms, and QQ-plot data.
40//! * [`influence`] — leverage, Cook's distance, DFFITS.
41//! * [`coefficients`] — standardized (beta) coefficients.
42//! * [`Summary`] via [`OlsFit::summary`] — the one-call `statsmodels`-style report.
43//! * [`regularized`] — [`RidgeFit`](regularized::RidgeFit) and
44//! [`LassoFit`](regularized::LassoFit) with their shrinkage-aware diagnostics.
45//! * [`logistic`] — [`LogisticFit`](logistic::LogisticFit) with deviance/Pearson
46//! residuals, goodness-of-fit, Hosmer–Lemeshow, and logistic influence.
47//!
48//! ## Quick start
49//!
50//! ```
51//! use ndarray::array;
52//! use regression_diagnostics::OlsFit;
53//! use regression_diagnostics::multicollinearity::vif;
54//!
55//! // Caller supplies the intercept column (first column of ones).
56//! let x = array![
57//! [1.0, 1.0, 2.0],
58//! [1.0, 2.0, 4.1],
59//! [1.0, 3.0, 5.9],
60//! [1.0, 4.0, 8.0],
61//! [1.0, 5.0, 10.1],
62//! ];
63//! let y = array![2.0, 4.1, 6.1, 8.0, 10.2];
64//! let fit = OlsFit::new(x, y).unwrap();
65//!
66//! println!("{}", fit.summary()); // full statsmodels-style report
67//! let v = vif(&fit); // per-predictor VIF (NaN for intercept)
68//! assert!(v[1].is_finite());
69//! ```
70
71#![warn(missing_docs)]
72#![forbid(unsafe_code)]
73
74mod fit;
75mod linalg;
76mod summary;
77
78pub mod coefficients;
79pub mod error;
80pub mod fit_statistics;
81pub mod influence;
82pub mod logistic;
83pub mod multicollinearity;
84pub mod regularized;
85pub mod residuals;
86
87pub use error::{RegressionError, Result};
88pub use fit::OlsFit;
89pub use summary::{CoefficientRow, Summary};