statsmodels: the inferential half of the Python scientific stack
Statsmodels: statistical modeling and econometrics in Python
At a glance
- What is it?
- A large Python package of statistical models that returns p-values and standard errors, covering regression, discrete choice, time series and survival analysis in one place.
- Who is it for?
- statsmodels is the package you reach for when a result needs an inference attached to it, because a coefficient on its own says nothing about whether it is distinguishable from zero. It covers a wide range of models and returns the diagnostics to back them up, at the cost of a large surface and a release cadence that has recently broken API compatibility on purpose.
- Can I use it commercially?
- Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 11, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Installing statsmodels with conda or a nightly wheel
The README gives two installation routes and they are not equivalent. Conda is the documented path, and the package is on conda-forge:
conda install statsmodelsFor people tracking the development branch, the README also points at nightly wheels on Anaconda's scientific-python channel, installed through pip rather than conda:
python -m pip install -i https://pypi.anaconda.org/scientific-python-nightly-wheels/simple statsmodels --upgrade --use-deprecated=legacy-resolverThe `--use-deprecated=legacy-resolver` flag is there because the nightly index has no lock file, so pip's modern resolver has nothing to pin against. Release tags are downloadable as source archives from GitHub, and binary distributions sit on PyPI.
There is a wrinkle worth knowing before you build from source. `pyproject.toml` names `meson-python` as the build backend, and its build requirements pull in Cython and a tighter set of numeric floors than the runtime does:
build-backend = 'mesonpy'
requires = [
'meson-python',
"numpy>=2.0.0,<3",
"scipy>=1.13,<2",
]That is a real split in the project's own configuration, and it has a practical consequence. The declared runtime dependencies in the same file are looser: NumPy from 1.23.5 and SciPy from 1.8, excluding 1.9.2 for a known bug. So a wheel built today is compiled against NumPy 2 and SciPy 1.13 or newer, while an installed wheel can run against NumPy 1.23. If you need the older numeric stack, take the conda or PyPI binary rather than compiling, because the compile step itself will not accept it. The README's answer to all of this is a single line: see `INSTALL.txt` or the installation page.
What the model list covers, and what it leaves out
The feature list in the README is long enough that it is more useful read as a map of statistical subfields. Linear regression is the entry point, and the variants listed under it are ordinary least squares, generalized least squares, weighted least squares, least squares with autoregressive errors, quantile regression, and recursive least squares. Each of those is a different answer to the question of what to do about heteroskedasticity, weighting, or time dependence in the errors, and statsmodels implements each rather than leaving it to the caller.
From there the list moves through generalized linear models for the one-parameter exponential family, Bayesian mixed GLM for binomial and Poisson outcomes, generalized estimating equations for one-way clustered or longitudinal data, and a discrete model group covering logit, probit, multinomial logit, Poisson, generalized Poisson, negative binomial, and zero-inflated count models. Time series is the widest branch: a complete state space framework with ARIMA, ARIMAX, VARMA, VARMAX, dynamic factor and unobserved component models, plus Markov switching, VAR and structural VAR, VECM, exponential smoothing, and a set of hypothesis tests for unit roots and cointegration.
Survival analysis is present with proportional hazards regression, Kaplan-Meier survivor function estimation, and cumulative incidence estimation. Multivariate methods cover principal component analysis with missing data, factor analysis with rotation, MANOVA, and canonical correlation. What is absent is as informative as what is present. There is no gradient boosted tree, no random forest, no neural network, and no cross-validation framework. statsmodels leaves model search to scikit-learn and focuses on estimation and inference.
Version 0.15.0 changed the API on purpose
Release 0.15.0, published 2026-08-27, is the largest entry in the project's recent history: 358 issues closed and 655 pull requests merged. Several of those changes will break code that worked on 0.14, so the release notes deserve a read before you upgrade rather than after.
The headline is randomness control. The package standardized on `rng` for seeding across the whole codebase, tracked as SPEC 007, replacing the older `seed` and `random_state` arguments. That is a consistency fix, but it is also a signature change on a large number of functions. Two more changes reach into everyday use: functions with variable-length tuple returns now hand back documented `NamedTuple` results, and a new abstracted formula engine lets the package sit on either `patsy` or `formulaic` as its backend. Formula strings such as the ones passed to `ols` and `logit` keep working, but the plumbing underneath them is swappable now, which is what makes formulaic the default choice in `requirements.txt`.
Polars DataFrames and Series are accepted as model input, which previously only pandas objects handled. New estimators arrived alongside: `CovDetMCD`, `CovDetS`, `CovDetMM`, and `RLMDetSMM` for covariance estimation, a Hamilton filter, a local false discovery rate correction, an L1-penalized GLM solver, and a delete-k block jackknife. `HurdleCountModel` gained `fit_regularized`, and `MICEData` is now iterable.
The two patch releases between 0.14 and 0.15 are a fair summary of the maintenance burden of a package this tightly coupled to the numeric stack. 0.14.5, from 2025-07-07, fixed an import failure against SciPy 1.16 and later. 0.14.6, from 2025-12-05, fixed the same class of failure against pandas 3.0.0. A package that depends on NumPy, SciPy, and pandas simultaneously will occasionally break at the seams, and these two releases are what that looks like in practice. The last push to the default branch was on 2026-09-21.
The sandbox folder marks what is not production ready
statsmodels ships a directory called `sandbox` for code the authors describe as being in various stages of development and testing, explicitly not production ready. Named inside it are generalized method of moments estimators, kernel regression, extensions to the SciPy distributions module, panel data models, and information theoretic measures.
This is unusual and useful. Most packages either hide work in progress or merge it and fix it later. Here the boundary is drawn in the repository itself, which means you can check whether the estimator you want is committed code before you write a script around it. If panel data models are on your list, check the sandbox first, because the README tells you the real status instead of leaving you to infer it from an incomplete docstring.
The repository tree is small and tells you where the weight sits: `statsmodels/` for the package itself, `docs/` for documentation sources, `examples/` split into `notebooks/`, `python/`, and an `incomplete/` directory, plus `tools/` and an `archive/` folder. At the top level there are `INSTALL.txt`, `CHANGES.md`, `CITATION.cff`, `AGENTS.md`, `COPYRIGHTS.txt`, and an `L1_ADDITION.txt` that appears to record work on an L1-penalized solver, which matches the new solver in 0.15.0.
Reading Stata files and getting tables back out
statsmodels reads Stata `.dta` files directly, and the README is honest about the limits of that support by noting that pandas has a more recent version. Table output goes to ascii, LaTeX, and HTML, which matters more than it sounds: an inferential result you cannot paste into a paper is not much use, and the LaTeX path removes a formatting step from most reporting workflows.
Beyond the models themselves, the package carries the supporting material that statistical work needs. Datasets used in examples and testing ship with it. The statistics group covers diagnostics and specification tests, goodness-of-fit and normality tests, and functions for multiple testing. Imputation includes MICE, regression on order statistic, and Gaussian imputation. Mediation analysis and graphics functions for visual inspection of data and model results are also in the list.
The comparison to scipy is stated in the README itself: statsmodels is a complement to scipy for statistical computations including descriptive statistics and estimation and inference. That division is the clearest way to position the package. scipy owns numerical methods and distributions. statsmodels owns the machinery around a fitted model, standard errors, hypothesis tests, and diagnostics.
Where the README ends and the API docs begin
The README is a project page rather than a manual. It gives you the install commands, the model inventory, the sandbox caveat, and pointers to four documentation locations: the stable docs for the latest release, the dev docs for the development version, the release notes, and archived copies of both at `statsmodels.github.io`.
That separation is the main thing to plan around. Anything about a specific estimator's arguments, the shape of a results object, or how a diagnostic is interpreted is in the API reference, not on the GitHub page. The one place the README does invite feedback is usability: development discussion happens on the `pystatsmodels` mailing list on Google Groups and in the issue tracker, and the project states plainly that it is interested in usability suggestions and improvement ideas.
Contributing follows the same split. The README points to the development test notes for installing statsmodels in editable mode, and the repository carries `CONTRIBUTING.md`, `azure-pipelines.yml` for CI, and `codecov.yml` for coverage, with Azure Pipelines and Codecov badges at the top of the README. Bugs go to the issue tracker. So the practical order is: install the binary, read the stable docs for the model you need, check the sandbox before assuming an estimator is finished, and read the release notes whenever you move between minor versions.
Editorial conclusion
statsmodels is the package you reach for when a result needs an inference attached to it, because a coefficient on its own says nothing about whether it is distinguishable from zero. It covers a wide range of models and returns the diagnostics to back them up, at the cost of a large surface and a release cadence that has recently broken API compatibility on purpose. The most useful thing in the repository is not any single model but the split between production code and the sandbox, which tells you in the author's own words which estimators are still experimental. Install the conda build for day to day work, read the 0.15.0 release notes before upgrading from 0.14, and treat the API reference rather than the README as the manual.
Frequently asked questions
Is statsmodels a Python library?
Yes. It is a Python package distributed on PyPI and conda-forge, described in its own README as a complement to scipy for statistical computations including descriptive statistics, and estimation and inference for statistical models. Installation is a single conda or pip command, with no compilation needed if you take a binary wheel.
What are the key differences between scipy and statsmodels?
scipy covers numerical methods, optimization, and distributions. statsmodels covers the layer above: fitting statistical models and reporting the inference around them, including standard errors, hypothesis tests, and diagnostics, across regression, discrete choice, time series, and survival analysis families. They are meant to be used together rather than as alternatives.
What are the key differences between sklearn and statsmodels?
scikit-learn is built around prediction: it supplies estimators, pipelines, and cross-validation, with gradient boosting and random forests among its models, and it says little about statistical significance. statsmodels is built around inference: it returns parameter standard errors, p-values, and model diagnostics, and its model list covers generalized linear models, count models, time series, and survival analysis that scikit-learn does not implement.
What does the "modulenotfounderror: no module named statsmodels" error mean and how can I fix it?
It means the interpreter you are running has no statsmodels installed, or you installed it into a different environment than the one running your script. The two documented fixes are `conda install statsmodels` and the pip nightly wheel command in the README. Checking which python your script actually uses settles most cases of this error.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/statsmodels-statsmodels)