使用scipy.stats和statsmodels计算线性回归得到不同的结果

5

我尝试用这两个库进行OLS拟合时,r ^ 2(决定系数)的值不同,我无法完全弄清楚原因。

In [1]: import pandas as pd       
In [2]: import numpy as np
In [3]: import statsmodels.api as sm
In [4]: import scipy.stats
In [5]: np.random.seed(100)
In [6]: x = np.linspace(0, 10, 100) + 5*np.random.randn(100)
In [7]: y = np.arange(100)

In [8]: slope, intercept, r, p, std_err = scipy.stats.linregress(x, y)

In [9]: r**2
Out[9]: 0.22045988449873671

In [10]: model = sm.OLS(y, x)
In [11]: est = model.fit()

In [12]: est.rsquared
Out[12]: 0.5327910685035413

这里发生了什么事?我无法理解!是否有错误出现?
2个回答

3

这并不是对已有答案的回复。

关于没有常数项的回归中的R-squared。

一个问题是,没有截距的回归没有标准定义的R^2。

实际上,在有截距的模型中,作为拟合优度的R-squared将完整模型与仅具有截距的模型进行比较。如果完整模型没有截距,则R^2的标准定义可能会产生奇怪的结果,如负R^2。

在没有常数项的回归中,传统定义将其除以因变量的总平方和而不是去均值后的平方和。带有常数项和没有常数项的回归之间的R^2不能以有意义的方式进行比较。

例如,请参见触发更改statsmodels以“正确”处理无常数回归中的R^2的问题:https://github.com/statsmodels/statsmodels/issues/785


这个链接扩展了每种情况下的典型公式: tss = (ys ** 2).sum() #未居中总平方和 tss = ((ys - ys.mean())**2).sum() #居中总平方和 https://dev59.com/sWAf5IYBdhLWcg3wQgxt#24852415 - Afflatus

1

0.2205是来自一个带有截距项的模型,如果去掉截距项,结果为0.5328。

基本上,一个软件包在建模"y = bx",而另一个(很贴心地)假设您还想要一个截距项(即"y = a + bx")。[注意:这种假设的优点是,否则每次运行回归都需要将"x"与一个一列绑定(否则您会得到一个"有偏"的模型)]

请查看此帖子以获取更详细的讨论。

祝你好运!


是的,我在 R 中运行了它以进行双重检查。 - Steve S
你知道为什么我的直觉是错误的原因吗? - James
此外,问题的一部分在于您使用了一个有些疯狂的模型。尝试简化一下(例如,使用 x = np.random.randn(100)y = 4 + 11*x 这样的东西),然后再运行回归分析——这样您就会知道要寻找什么(即截距=4,斜率=11)。 - Steve S
是的,这很令人困惑,特别是因为有些软件包会自动添加截距,而有些则不会(显然)。 - Steve S
1
詹姆斯:尝试以通常的方式计算相关性(即**cov(x,y)/(sd(x)sd(y))*)-结果(约为0.47)与带有截距的回归的R ^ 2项一致(因为0.47 ^ 2约为0.22)。原因是当您处理OLS回归(即带有*截距)时,sqrt(R ** 2)仅等于相关系数。请参见[此处](http://en.wikipedia.org/wiki/R-squared#As_squared_correlation_coefficient) - Steve S
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接