一、什么是 Statsmodels?
statsmodels(全称:Statistical Models)是一个基于 NumPy、SciPy 和 pandas 构建的 Python 库,主要用于:
- 拟合统计模型(如线性回归、逻辑回归、广义线性模型)
- 执行统计检验(t检验、F检验、卡方检验等)
- 进行时间序列分析(ARIMA、VAR 等)
- 输出详细的统计结果报告(包含 p 值、置信区间、R² 等)
它广泛应用于经济学、社会科学、生物统计等领域。
安装方式
pip install statsmodels导入常用模块:
import statsmodels.api as sm import statsmodels.formula.api as smf import numpy as np import pandas as pd from scipy import stats二、核心功能介绍
1. 线性回归分析
使用statsmodels.api进行 OLS 回归
我们以经典的“身高-体重”数据为例,演示如何进行普通最小二乘法(OLS)回归。
# 生成示例数据 np.random.seed(42) height = np.random.normal(170, 10, 100) weight = 0.8 * height - 100 + np.random.normal(0, 5, 100) # 添加常数项(截距) X = sm.add_constant(height) # 添加截距列 y = weight # 拟合模型 model = sm.OLS(y, X).fit() # 输出结果摘要 print(model.summary())输出内容包括:
- 回归系数(coef)及其标准误
- t 统计量和对应的 p 值(判断显著性)
- R-squared 和调整后的 R²
- F-statistic 及其 p 值(整体模型显著性)
- AIC/BIC 信息准则
关键优势:相比其他库,
statsmodels提供了完整的统计推断信息,帮助我们判断变量是否真正“显著”。
使用公式接口(类似 R 语言风格)
smf.ols()支持使用字符串公式,语法更直观:
# 构造 DataFrame data = pd.DataFrame({'weight': weight, 'height': height}) # 使用公式拟合 model = smf.ols('weight ~ height', data=data).fit() print(model.summary())支持多项式项、分类变量自动编码等高级功能:
# 包含平方项 model = smf.ols('weight ~ height + np.power(height, 2)', data=data).fit()2. 假设检验
statsmodels提供了多种经典的统计检验方法。
(1) t 检验:单样本与双样本
from scipy.stats import ttest_1samp, ttest_ind # 单样本 t 检验:均值是否等于某个值? sample = np.random.normal(5.5, 1, 30) t_stat, p_val = ttest_1samp(sample, popmean=5.0) print(f"t={t_stat:.3f}, p={p_val:.3f}")(2) 正态性检验(Shapiro-Wilk)
from scipy.stats import shapiro stat, p = shapiro(residuals) if p > 0.05: print("残差服从正态分布(无法拒绝原假设)") else: print("残差不服从正态分布")(3) 同方差性检验(Breusch-Pagan)
from statsmodels.stats.diagnostic import het_breuschpagan bp_test = het_breuschpagan(model.resid, model.model.exog) labels = ['LM Statistic', 'LM-Test p-value', 'F-Statistic', 'F-Test p-value'] print(dict(zip(labels, bp_test)))用于检测回归模型中是否存在异方差问题。
(4) 多重共线性诊断(VIF)
from statsmodels.stats.outliers_influence import variance_inflation_factor X_vif = X.iloc[:, 1:] # 去掉常数项 vif = [variance_inflation_factor(X_vif.values, i) for i in range(X_vif.shape[1])] pd.DataFrame({'variable': X_vif.columns, 'VIF': vif})VIF > 10 表示存在严重多重共线性。
3. 广义线性模型(GLM)
当因变量不符合正态分布时,可以使用 GLM。例如:
- 二分类问题 → 逻辑回归(Logit / Probit)
- 计数数据 → 泊松回归
# 生成二分类数据 data['high_weight'] = (data['weight'] > data['weight'].median()).astype(int) # 逻辑回归 logit_model = smf.logit('high_weight ~ height', data=data).fit() print(logit_model.summary())输出包括 Odds Ratio 解释、Wald 检验等。
4. 时间序列分析
statsmodels在时间序列建模方面非常强大。
(1) ARIMA 模型
from statsmodels.tsa.arima.model import ARIMA # 示例:模拟时间序列 ts = np.cumsum(np.random.normal(0, 1, 100)) + np.linspace(0, 10, 100) # 拟合 ARIMA(p,d,q) arima_model = ARIMA(ts, order=(1,1,1)).fit() print(arima_model.summary()) # 预测未来5步 forecast = arima_model.forecast(steps=5)(2) 单位根检验(ADF 检验)
判断时间序列是否平稳:
from statsmodels.tsa.stattools import adfuller result = adfuller(ts) print(f'ADF Statistic: {result[0]}') print(f'p-value: {result[1]}') if result[1] <= 0.05: print("序列平稳") else: print("序列非平稳,需差分")(3) 格兰杰因果检验
检验一个时间序列是否对另一个有预测能力:
from statsmodels.tsa.stattools import grangercausalitytests # 构造双变量时间序列 data_ts = pd.DataFrame(np.column_stack([ts, np.roll(ts, shift=1)]), columns=['x', 'y']) grangercausalitytests(data_ts[['y','x']], maxlag=2)三、可视化辅助分析
结合matplotlib和seaborn,我们可以绘制回归诊断图:
import matplotlib.pyplot as plt fig, ax = plt.subplots(2, 2, figsize=(10, 8)) sm.graphics.plot_regress_exog(model, 'height', fig=fig) plt.tight_layout() plt.show()常见诊断图包括:
- 残差 vs 拟合值(检查异方差)
- Q-Q 图(检查正态性)
- 杠杆值与残差图(识别异常点)
四、与其他库的对比
| 特性 | statsmodels | scikit-learn |
|---|---|---|
| 目标 | 统计推断、因果分析 | 预测建模、机器学习 |
| 输出 | 参数显著性、置信区间、p值 | 预测值、评分(如准确率) |
| 易用性 | 公式接口友好,适合统计背景用户 | API 统一,适合工程部署 |
| 模型类型 | OLS、GLM、ARIMA、面板数据等 | 回归、分类、聚类、降维等 |
✅ 推荐组合使用:用statsmodels分析变量关系和显著性,用scikit-learn构建高性能预测模型。
五、总结
statsmodels是 Python 中进行严谨统计分析不可或缺的工具。它的主要优势在于:
- 提供完整的统计推断结果,便于科学决策;
- 支持广泛的经典统计模型(线性模型、时间序列、离散选择模型等);
- 丰富的假设检验和诊断工具,保障模型有效性;
- 兼容 pandas 数据结构,易于集成进数据分析流程。
参考资料
- 官方文档:https://www.statsmodels.org/
- GitHub 仓库:https://github.com/statsmodels/statsmodels
- 书籍推荐:《Python for Data Analysis》by Wes McKinney