anofox-regression
Library Listed
A robust statistics library for regression analysis
- Downloads
- 8,310
- Dependents
- 6
- Stars
- 8
- Forks
- 3
- Contributors
- 1
- Commits
- 534
- Latest release
- 0.12.2 ·
About
Need to run this on 10GB of data? Use our DuckDB extension
Need to use this in a React Dashboard? Use our npm package
A robust statistics library for regression analysis in Rust, validated against R and scikit-learn (VALIDATION).
This library provides sklearn-style regression estimators with full statistical inference support including standard errors, t-statistics, p-values, confidence intervals, and prediction intervals.
Read the full README
Features
Linear Regression
- Ordinary Least Squares (OLS) with full inference
- Weighted Least Squares (WLS)
- Ridge Regression (L2 regularization)
- Elastic Net (L1 + L2 regularization, coordinate descent as
glmnet) - Huber Regression (robust to outliers, IRLS with Huber loss)
- Recursive Least Squares (RLS) with online learning
- Bounded Least Squares (BLS/NNLS) with box constraints
- Dynamic Linear Model (LmDynamic) with time-varying coefficients
- Least Angle Regression (LARS) and LassoLars with full coefficient path
- Ridge / elastic-net regularisation paths and
cv.glmnet-style CV (solvers::path), with group, leave-one-group-out, stratified, stratified-group and time-series (rolling-origin) folds, CV on explicit train / test splits and nested CV (solvers::cv) - Regression splines (
splines): restricted cubic splines with Harrell's default knots (rms::rcs), linear splines (rms::lsp), restricted interactions (%ia%) and the algebraic form of a fitted spline (rcspline.restate), as design-matrix columns for any model - Multi-d.f. Wald tests and the
rmsANOVA table (inference::anova,wald_test): chunk tests of predictors, nonlinearity and interactions from one fit with any (model, robust or bootstrap) covariance, on adesign::Designthat records its terms - Predictive accuracy indexes (
diagnostics::accuracy): C / Dxy / γ / τ-a, Harrell's C for censored data, Brier, Nagelkerke and adjusted R², g-indexes, thelrmstats vector andval.probcalibration (intercept, slope, Emax, …) - Cluster-robust covariance (
inference::cluster): one- and multi-way clustered sandwich (CR0 / CR1 / CR2 / CR3 assandwich::vcovCL,rms::robcov) for OLS / WLS, any GLM family and AFT - Nonparametric survival (
survival): Kaplan–Meier with Greenwood CIs, Nelson–Aalen / Fleming–Harrington hazards, median and restricted mean, strata, weights, left truncation, and log-rank / G-ρ tests (survfit,survdiff) - Cox proportional hazards (
survival::cox): Efron / Breslow ties, weights, offsets, strata, time-dependent covariates, ridge, robust variance and predicted survival curves (coxph,survfit.coxph,cph) - Model validation (
validation): optimism bootstrap, cross-validation and .632 validation of any modelling process, and overfitting-corrected calibration curves (rms::validate,rms::calibrate) - Incremental and distributed fits via
SufficientStats— a mergeable, serializable (versioned bytes) state of weighted means and centred co-moments.OlsRegressor,WlsRegressorandRidgeRegressor::fit_from_statereturn the same coefficients, aliasing, standard errors, R², F, log-likelihood and intervals asfit()on the concatenated rows; ridge applies λ at finalize, so one state serves a λ grid. Stays accurate for data with large offsets. The olderMomentAccumulator(raw moments, coefficients only) is kept (seecargo run --example streaming_ridge)
Robust & Bayesian Regression
- Theil-Sen (Vardi-Zhang spatial-median, ~29.3% breakdown point)
- RANSAC (consensus-set refit with Fischler-Bolles stop-probability)
- Bayesian Ridge (SVD evidence maximisation)
- ARD Regression (per-feature precisions with relevance pruning)
Generalized Linear Models
- Logistic Regression (binary classification with sklearn-like API)
- Multinomial logistic regression (softmax, sample weights, L2 / L1 / elastic-net; sklearn
LogisticRegression) - Poisson GLM (Log, Identity, Sqrt links) with offset support
- Negative Binomial GLM (overdispersed count data with theta estimation)
- Binomial GLM (Logistic, Probit, Complementary log-log)
- Tweedie GLM (Gaussian, Poisson, Gamma, Inverse-Gaussian, Compound Poisson-Gamma)
- Gamma Regression (sklearn-style wrapper for Tweedie(power=2), log link)
Generalized Linear Mixed Models
- GLMM with a random intercept, optional random slopes, and crossed / nested factors (
GlmmRegressor): Gaussian (profiled REML/ML, matcheslme4::lmer), Poisson and Binomial (Laplace PIRLS, matchesglmer(nAGQ=0)). Unstructured random-effects covariance profiled by golden-section (intercept) or Nelder–Mead (slopes / multiple factors);fit_crossedhandles(1|a) + (1|b)and(1|a/b).
- GLMM with a random intercept, optional random slopes, and crossed / nested factors (
Correlated, ordinal and survival outcomes
- Generalized least squares (
GlsRegressor,nlme::gls): AR(1), continuous AR(1), compound symmetry, spatial structures with nugget,varIdent/varPower/varExpvariance functions, REML / ML - Ordinal regression (
OrdinalRegressor,rms::orm/MASS::polr) with logit, probit, cloglog and loglog links, and the continuation-ratio model (ContinuationRatioRegressor,rms::cr.setup) - Accelerated failure time models (
AftRegressor,survival::survreg): Weibull, exponential, log-normal, log-logistic, with censoring
- Generalized least squares (
Penalized and smooth models
- Penalized GLMs with Normal / Laplace priors and Laplace-approximation inference
(
PenalizedGlmRegressor), penalty selection by effective AIC (pentrace,rms::pentrace) - P-splines (
PSplineRegressor,mgcvbs = "ps") and partial least squares (PlsRegressor,pls::plsr)
- Penalized GLMs with Normal / Laplace priors and Laplace-approximation inference
(
Regression modeling strategies (Harrell, RMS)
- Effects, contrasts and prediction grids on the covariate scale, simultaneous bands and
nomograms (
effects:summary.rms,contrast,Predict,nomogram) - Multiple imputation (
imputation::areg_impute,Hmisc::aregImpute) and Rubin's rules with D1 Wald tests (inference::pool_rubin,mice::pool) - Data reduction before modelling (
reduction):varclus,redun,spearman2, Hoeffding's D, principal components,transcan - Response transformations (
transform): Box–Cox profiles,aregoptimal transformations, smearing estimates - Likelihood-ratio and score tests, profile-likelihood intervals (
inference::lr_test,glm_score_test,profile_confint), fast backward elimination (fastbw), model approximation, bootstrap covariance (bootcov), causal mediation (mediate) and empirical-Bayes shrinkage (eb_shrink)
- Effects, contrasts and prediction grids on the covariate scale, simultaneous bands and
nomograms (
Online Learning
- Passive-Aggressive Regressor (PA-I and PA-II) with
partial_fit
- Passive-Aggressive Regressor (PA-I and PA-II) with
Augmented Linear Model (ALM)
- 24 distributions: Normal, Laplace, Student-t, Gamma, Beta, Log-Normal, and more
- Based on the greybox R package
Quantile & Monotonic Regression
- Quantile Regression (any τ ∈ (0,1); IRLS start polished to the exact LP optimum as
quantreg::rq, with iid / nid / bootstrap inference) - Isotonic Regression (PAVA algorithm for monotonic constraints)
- Quantile Regression (any τ ∈ (0,1); IRLS start polished to the exact LP optimum as
Smoothing & Classification
- LOWESS (Locally Weighted Scatterplot Smoothing)
- AID (Automatic Identification of Demand) classifier with optimized closed-form fitting
Loss Functions
- MAE, MSE, RMSE, MAPE, sMAPE, MASE, pinball loss
Model Diagnostics
- R², Adjusted R², RMSE, F-statistic, AIC, AICc, BIC
- Leverage, Cook's distance, VIF, studentized residuals
Installation
Add to your Cargo.toml:
[dependencies]
anofox-regression = "0.12"
The minimum supported Rust version is 1.87. The optional parallel feature runs
bootstrap and validation resamples on rayon. The optional serde feature
derives Serialize / Deserialize for every fitted model, the survival
results (CoxFit, SurvCurve, …) and the spline bases, so a fitted model can be stored
(JSON, MessagePack, …) and used for prediction and inference after loading.
NaN and ±∞ are written as the strings "NaN", "inf", "-inf", so JSON
round trips are exact; enable serde_json's float_roundtrip feature to read
the last bit back.
Examples
The library includes runnable examples demonstrating each major feature:
# Linear
cargo run --example ols # Ordinary Least Squares
cargo run --example wls # Weighted Least Squares
cargo run --example ridge # Ridge regression
cargo run --example elastic_net # Elastic Net
cargo run --example rls # Recursive Least Squares
cargo run --example bls # Bounded/Non-negative LS
cargo run --example pls # Partial Least Squares
cargo run --example streaming_ridge # Streaming fit via MomentAccumulator
cargo run --example lars # LARS and LassoLars
cargo run --example lm_dynamic # Dynamic Linear Model
cargo run --example collinearity_intervals # Intervals with aliased columns
cargo run --release --example many_small_fits # 100K small OLS fits (allocation benchmark)
# Robust & Bayesian
cargo run --example huber # Huber regression (robust)
cargo run --example theil_sen # Theil–Sen estimator
cargo run --example ransac # RANSAC regression
cargo run --example bayesian # Bayesian Ridge + ARD
# Online
cargo run --example passive_aggressive # PA-I / PA-II + partial_fit
# GLMs
cargo run --example poisson # Poisson GLM
cargo run --example negative_binomial # Negative Binomial GLM
cargo run --example binomial # Binomial GLM (logit/probit/cloglog)
cargo run --example logistic # LogisticRegressor (sklearn-style)
cargo run --example tweedie # Tweedie GLM
cargo run --example gamma # Gamma GLM (log link)
# Other
cargo run --example alm # Augmented Linear Model
cargo run --example lowess # LOWESS smoothing
cargo run --example aid # Demand classification
cargo run --example quantile # Quantile regression
cargo run --example isotonic # Isotonic regression
Quick Start
Every block below is a complete program (they run as doctests).
OLS Regression with Inference and Prediction Intervals
use anofox_regression::prelude::*;
use faer::{Col, Mat};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let x = Mat::from_fn(50, 2, |i, j| if j == 0 { i as f64 } else { (i as f64).sin() });
let y = Col::from_fn(50, |i| 1.0 + 2.0 * x[(i, 0)] - 0.5 * x[(i, 1)] + 0.1 * (i % 3) as f64);
let fitted = OlsRegressor::builder()
.with_intercept(true)
.compute_inference(true)
.build()
.fit(&x, &y)?;
let r = fitted.result();
println!("R² = {:.4}, coefficients = {:?}", r.r_squared, r.coefficients);
println!("standard errors = {:?}, p-values = {:?}", r.std_errors, r.p_values);
let x_new = Mat::from_fn(2, 2, |i, j| if j == 0 { 50.0 + i as f64 } else { 0.0 });
let pred = fitted.predict_with_interval(&x_new, Some(IntervalType::Prediction), 0.95);
println!("fit {:?}, lower {:?}, upper {:?}", pred.fit, pred.lower, pred.upper);
Ok(())
}
Poisson and Logistic GLMs
use anofox_regression::prelude::*;
use faer::{Col, Mat};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let x = Mat::from_fn(60, 1, |i, _| i as f64 / 20.0);
let counts = Col::from_fn(60, |i| ((0.5 + 0.8 * x[(i, 0)]).exp() + (i % 3) as f64).floor());
let poisson = PoissonRegressor::log().build().fit(&x, &counts)?;
println!("deviance = {}", poisson.deviance);
println!("expected counts = {:?}", poisson.predict_count(&x));
let events = Col::from_fn(60, |i| if (i * 7) % 10 < 6 * i / 60 + 2 { 1.0 } else { 0.0 });
let logistic = BinomialRegressor::logistic().build().fit(&x, &events)?;
println!("probabilities = {:?}", logistic.predict_probability(&x));
Ok(())
}
Robust and Quantile Regression
use anofox_regression::prelude::*;
use faer::{Col, Mat};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let x = Mat::from_fn(40, 1, |i, _| i as f64);
// a linear trend with two gross outliers
let y = Col::from_fn(40, |i| {
2.0 + 0.5 * i as f64 + if i == 5 || i == 30 { 25.0 } else { (i % 4) as f64 * 0.2 }
});
// Laplace (least absolute deviation) ALM
let laplace = AlmRegressor::builder()
.distribution(AlmDistribution::Laplace)
.build()
.fit(&x, &y)?;
println!("ALM log-likelihood = {}", laplace.result().log_likelihood);
// median and 90th-percentile regression
for tau in [0.5, 0.9] {
let q = QuantileRegressor::builder().tau(tau).build().fit(&x, &y)?;
println!("τ = {tau}: slope = {:.3}", q.result().coefficients[0]);
}
Ok(())
}
Isotonic Regression
use anofox_regression::prelude::*;
use faer::Col;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let x = Col::from_fn(20, |i| i as f64);
let y = Col::from_fn(20, |i| (i as f64).sqrt() + if i % 5 == 0 { -0.8 } else { 0.0 });
let fitted = IsotonicRegressor::builder().increasing(true).build().fit_1d(&x, &y)?;
println!("R² = {:.4}", fitted.result().r_squared);
println!("monotone fit at new points = {:?}", fitted.predict_1d(&Col::from_fn(3, |i| 2.5 + 5.0 * i as f64)));
Ok(())
}
Validation
This library is developed using Test-Driven Development (TDD) against established statistical oracles. Most estimators are validated against R; the sklearn-style estimators are validated against scikit-learn 1.9.1 via a pinned reproducible Python environment under validation/python/.
R-validated estimators
| Rust | R Equivalent | Package |
|---|---|---|
OlsRegressor | lm() | stats |
WlsRegressor | lm() with weights | stats |
RidgeRegressor, ElasticNetRegressor | glmnet() | glmnet |
HuberRegressor | rlm(psi=psi.huber) | MASS |
LogisticRegressor | glm(..., family=binomial) | stats |
BlsRegressor | nnls() | nnls |
PoissonRegressor | glm(..., family=poisson) | stats |
BinomialRegressor | glm(..., family=binomial) | stats |
NegativeBinomialRegressor | glm.nb() | MASS |
TweedieRegressor | tweedie() | statmod |
GammaRegressor | glm(family=Gamma(link="log")) | stats |
GlmmRegressor | lmer() / glmer(nAGQ=0) | lme4 |
AlmRegressor | alm() | greybox |
QuantileRegressor | rq() | quantreg |
IsotonicRegressor | isoreg() | stats |
GlsRegressor | gls() | nlme |
OrdinalRegressor, ContinuationRatioRegressor | orm(), polr(), lrm(cr.setup) | rms, MASS |
AftRegressor | survreg() | survival |
survival::cox | coxph(), survfit() | survival |
PenalizedGlmRegressor, pentrace | glmnet() with penalty factors, pentrace() | glmnet, rms |
PSplineRegressor | gam(s(x, bs = "ps")) | mgcv |
imputation, inference::pool_rubin | aregImpute(), pool() | Hmisc, mice |
effects, validation, reduction | summary.rms, validate, calibrate, varclus, redun | rms, Hmisc |
| Diagnostics | cooks.distance(), hatvalues(), vif() | stats, car |
scikit-learn-validated estimators
| Rust | scikit-learn equivalent |
|---|---|
TheilSenRegressor | linear_model.TheilSenRegressor |
RansacRegressor | linear_model.RANSACRegressor |
PassiveAggressiveRegressor | linear_model.PassiveAggressiveRegressor |
LarsRegressor, LassoLars variant | linear_model.Lars, linear_model.LassoLars |
BayesianRidgeRegressor | linear_model.BayesianRidge |
ArdRegressor | linear_model.ARDRegression |
745 reference comparisons check numerical agreement with the chosen oracle within documented tolerances; validation/VALIDATION.md maps every reference script to its tests.
For complete transparency on the validation process, see validation/VALIDATION.md, which documents the per-estimator tolerance rationale and reproduction instructions for both the R and Python pipelines.
Dependencies
- faer - High-performance linear algebra
- statrs - Statistical distributions
- basin - Numerical optimization (L-BFGS, Nelder–Mead)
- rayon - Parallel resampling (optional
parallelfeature) - serde - Model serialization (optional
serdefeature)
Attribution
This library includes Rust implementations of algorithms from several open-source projects. See THIRD_PARTY_NOTICES for complete attribution and license information.
Key attributions:
- greybox - ALM distributions and AID classifier methodology (independent implementation)
- basin (MIT/Apache-2.0) - L-BFGS optimization
- faer (MIT) - Linear algebra operations
- statrs (MIT) - Statistical distributions
Contributing and stability
See CONTRIBUTING.md (including how new results are validated), STABILITY.md (what the version number promises, MSRV and dependency policy) and SECURITY.md.
License
MIT License
Compatibility
- Runs on
- GPU support unknown
What shows it
- no dependency or feature matches a backend row
- Native code
- None found
- No native code found
- Python bindings
- No Python binding crate found
- License
- MIT
Compare with similar projects
Order: strongest tier first, then most downloads, then name, with unmeasured values last. A library counts downloads over 30 days. An app counts binary downloads per release. An app with none counts its crate downloads over 30 days. ML Rust runs this catalogue, so its closest project always gets a row.
| Project | Downloads | Dependents | Stars | Latest release | Runs on (GPU) | Native code | License |
|---|---|---|---|---|---|---|---|
|
A robust statistics library for regression analysis |
8,310 downloads over 30 days | 6 | 8 | 0.12.2 | GPU support unknown | No native code found | MIT |
|
linregress Listed
ordinary least squared linear regression with some basic statistics |
319,622 downloads over 30 days | 11 | 24 | 0.5.4 | GPU support unknown | No native code found | MIT |
|
radiate Listed
A Rust library for genetic algorithms and artificial evolution. Python bindings |
971 downloads over 30 days | 0 | 257 | 1.3.2 | GPU support unknown | No native code found | MIT |
|
Rust bindings for the liblinear C++ library |
922 downloads over 30 days | 1 | 10 | 1.0.0 | GPU support unknown | Binds native code: liblinear.a. Build uses a native toolchain: cc | MIT |
|
rust-automl Listed
Automated machine learning for classification and regression |
170 downloads over 30 days | 1 | 39 | 0.3.1 | GPU support unknown | No native code found | Apache-2.0 OR MIT |
|
treeboost Listed
Gradient-boosted decision trees for tabular data: trains a baseline model in one call, with full control over boosting modes and configs, and Scalar, AVX-512, SVE2, WGPU and CUDA backends. Python bindings |
18 downloads over 30 days | 0 | 9 | 0.1.2 | CUDA, WebGPU | No native code found | Apache-2.0 |
|
Rust library for Self Organising Maps (SOM). |
9 downloads over 30 days | 0 | 36 | 1.1.1 | GPU support unknown | No native code found | MIT |
Why ListedNo archive, New or Featured rule places it, so it is Listed.
What it lacks for Featured
- It has 0 active dependents and 0 new dependents in 365 days. Featured needs 11 active dependents or 9 new dependents in 365 days. The repository route reads 8 stars, 3 forks and 1 contributor. It needs 4,539 stars, 434 forks and 79 contributors together.
What else the check found
- The last activity is on 6 Nov 2026, 3 days ago. The rules expect an update within 365 days. Dormancy rule
Exact rules: Listed, Featured library. The check on applied thresholds version 9.
Every rule outcome, as the check records it
expected-interval: version 0.12.2 base 300, raised to the 365-day floor: E = 365 daysdormancy: last activity 2026-11-06, 3 days ago, E = 365: activefeatured: not featured: active_users 0 < 11 and new_adopters 0 < 9 and repository route stars 8 (needs 4539), forks 3 (needs 434), contributors 1 (needs 79)listed: listed: no archive, new or featured rule applies
Measurements and sources
Each signal row shows the raw value, its source and the fetch date. The Sources list gathers every distinct source on this page. Movement needs more history.
Sources6 sources
- Description: the crates.io description
- crates.io database dump, fetched
- RustSec advisory database, fetched
- GitHub repository, fetched
- crates.io package, fetched
- GitHub contributors, fetched
Adoption0 active dependents, 0 new dependents in 365 days1 not measured
| Signal | Value | Source | Fetched | Counts |
|---|---|---|---|---|
| Active dependents | 0 | crates.io database dump | Yes | |
| New dependents (365 days) | 0 | crates.io database dump | Yes | |
| Peak active dependents | 0 | crates.io database dump | Yes | |
| Active dependents as a share of the peak | 1 | crates.io database dump | Yes | |
| Binary downloads per release | Not measured | Yes |
MaintenanceLatest human commit: 3 days ago3 not measured
| Signal | Value | Source | Fetched | Counts |
|---|---|---|---|---|
| Latest human commit | 2026-11-06 | GitHub repository | Yes | |
| Latest release | 2026-11-06 | crates.io database dump | Yes | |
| First release | 2025-12-09 | crates.io database dump | Yes | |
| Latest version | 0.12.2 | crates.io database dump | Yes | |
| Days the oldest outside issue waits for a reply | 0 | GitHub repository | Yes | |
| Maintainer replies over 365 days | 16 | GitHub repository | Yes | |
| Repository archived | false | GitHub repository | Yes | |
| Repository gone | false | GitHub repository | Yes | |
| Release commit or manifest in the repo | true | crates.io package | Yes | |
| Published docs | true | crates.io database dump | Yes | |
| Latest release fails cargo check | Not measured | Yes | ||
| Build check date | Not measured | Yes | ||
| Build check toolchain | Not measured | Yes |
SecurityUnpatched vulnerabilities: none
| Signal | Value | Source | Fetched | Counts |
|---|---|---|---|---|
| Unpatched vulnerabilities past the grace window | none | RustSec advisory database | Yes | |
| RustSec unmaintained advisory | none | RustSec advisory database | Yes | |
| Deprecation notice | none | crates.io database dump | Yes | |
| Deprecated requirement | none | crates.io database dump | Yes |
Distribution53 releases, 8,310 downloads over 30 days5 not measured
| Signal | Value | Source | Fetched | Counts |
|---|---|---|---|---|
| Releases | 53 | crates.io database dump | Yes | |
| Downloads over 30 days | 8310 | crates.io database dump | Yes | |
| Binary downloads over the last 3 releases | Not measured | Yes | ||
| Homebrew installs on request over 365 days | Not measured | Yes | ||
| Repology repository families | Not measured | Yes | ||
| Docker pull growth over 90 days | Not measured | Yes | ||
| Docker pulls at the growth baseline | Not measured | Yes | ||
| Every version a prerelease | false | crates.io database dump | Yes | |
| Every version 0.0.x | false | crates.io database dump | Yes | |
| Every version yanked | false | crates.io database dump | Yes | |
| Crate deleted from crates.io | false | crates.io database dump | Yes |
Repository8 stars, 3 forks, 1 contributors, 534 commits. Stars alone never qualify a project.
| Signal | Value | Source | Fetched | Counts |
|---|---|---|---|---|
| GitHub stars | 8 | GitHub repository | Yes — one part of the repository route | |
| GitHub forks | 3 | GitHub repository | Yes — one part of the repository route | |
| Contributors with a GitHub account | 1 | GitHub contributors | Yes — one part of the repository route | |
| Commits on the default branch | 534 | GitHub repository | No | |
| Repository's main crate left out of the entry | none | crates.io database dump | Yes |
Facts that never count
| Signal | Value | Source | Fetched | Counts |
|---|---|---|---|---|
| License | MIT | crates.io database dump | No | |
| Runs on, from listed crates and their direct dependencies | GPU support unknown | crates.io database dump | No | |
| What shows each backend | no dependency or feature matches a backend row | crates.io database dump | No | |
| Native code, from listed crates and their dependencies | No native code found | crates.io database dump | No | |
| Python bindings, from direct dependencies of listed crates | No Python binding crate found | crates.io database dump | No | |
| Crates that depend on a listed crate directly | 6 | crates.io database dump | No |
Corrections and review history
No correction applies to this entry.
Judgments
A judgment enters only through an approved issue and a merged pull request.
No judgment applies to this entry.