You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Statsmodels OLS与Numpy矩阵代数OLS结果不一致?

为什么手动Numpy矩阵OLS与Statsmodels OLS结果不一致?

一、示例中X.T@X不可逆的原因

你的示例数据里,X的第二列是第一列的2倍(X[:,1] = 2 * X[:,0]),这意味着X的列存在完全多重共线性,导致X.T@X成为奇异矩阵,无法求逆。

而Statsmodels的OLS遇到完全共线性时,会自动识别并丢弃冗余自变量(比如示例中的第二列),因此能正常输出系数。你可以通过results.model.exog_names查看哪些变量被保留。

二、实际数据中系数差异显著的常见原因

1. 截距项处理不一致

Statsmodels的sm.OLS(y, X)默认不会自动添加截距项,只有通过sm.add_constant(X)给X加上常数列后,才会拟合截距。如果手动计算和Statsmodels在截距项的处理上不一致,结果必然不同:

  • 若手动方法没加常数列,但Statsmodels加了;
  • 或手动加了常数列,Statsmodels没加;

要让两者结果一致,需保持截距处理统一:

无截距的一致写法

# Numpy手动计算
coeff_np = np.linalg.inv(X.T@X)@X.T@y

# Statsmodels
model = sm.OLS(y, X)
results = model.fit()
coeff_sm = results.params

带截距的一致写法

# Numpy手动计算(添加常数列)
X_with_const = np.hstack([np.ones((X.shape[0], 1)), X])
coeff_np = np.linalg.inv(X_with_const.T@X_with_const)@X_with_const.T@y

# Statsmodels(添加常数列)
X_with_const = sm.add_constant(X)
model = sm.OLS(y, X_with_const)
results = model.fit()
coeff_sm = results.params

2. 数值稳定性差异

直接用np.linalg.inv(X.T@X)@X.T@y计算OLS系数的数值稳定性极差,尤其是当X.T@X的条件数很大(即自变量存在近似共线性)时,求逆操作会放大计算误差,导致结果偏离真实值。

Statsmodels内部采用QR分解或**奇异值分解(SVD)**求解OLS,这些方法在数值稳定性上远优于直接求逆,能有效降低近似共线性带来的误差。

如果想用Numpy实现更稳定的OLS计算,推荐使用np.linalg.lstsq(内部同样基于QR/SVD),结果会和Statsmodels更接近:

coeff_np, _, _, _ = np.linalg.lstsq(X, y, rcond=None)

3. 其他潜在因素

  • 数据预处理差异:手动方法和Statsmodels是否对数据做了相同的标准化、中心化处理;
  • 缺失值/异常值:Statsmodels默认会处理缺失值,而手动方法需自行处理,若数据存在缺失值但处理不一致,会导致结果差异;
  • 权重设置:若Statsmodels中指定了weights参数,而手动方法未考虑权重,结果也会不同。

内容的提问来源于stack exchange,提问作者firstname

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 14:52:26