Statsmodels:计算拟合值和R平方

11

我正在进行一项回归,如下所示(df 是一个 pandas 数据帧):

import statsmodels.api as sm
est = sm.OLS(df['p'], df[['e', 'varA', 'meanM', 'varM', 'covAM']]).fit()
est.summary()

其中之一是R方值为0.942。因此,我想绘制原始的y数值和拟合的数值。为此,我对原始数值进行了排序:

orig = df['p'].values
fitted = est.fittedvalues.values
args = np.argsort(orig)
import matplotlib.pyplot as plt
plt.plot(orig[args], 'bo')
plt.plot(orig[args]-resid[args], 'ro')
plt.show()

然而,这给了我一张数值完全不准确的图表。没有任何迹象表明R平方为0.9。因此,我尝试手动计算:

yBar = df['p'].mean()
SSTot = df['p'].apply(lambda x: (x-yBar)**2).sum()
SSReg = ((est.fittedvalues - yBar)**2).sum()  
1 - SSReg/SSTot
Out[79]: 0.2618159806908984

我是不是做错了什么?还是我的计算结果与statsmodels得到的结果相差很远有原因?SSTotSSReg 的值分别为 4808435495

2个回答

13
如果您的模型中不包含截距(常量解释变量),statsmodels会基于未居中的总平方和计算R-squared,即:
tss = (ys ** 2).sum()  # un-centred total sum of squares

与...相反
tss = ((ys - ys.mean())**2).sum()  # centred total sum of squares

作为结果,R平方值会更高。
这在数学上是正确的。因为R平方应该指示完整模型相对于简化模型解释了多少变异性。如果您将您的模型定义为:
ys = beta1 . xs + beta0 + noise

那么简化后的模型可以是:ys = beta0 + noise,其中beta0的估计值为样本平均值,因此我们有: noise = ys - ys.mean()。这就是拥有截距的模型中“去均值”(de-meaning)的来源。

但是对于如下模型:

ys = beta . xs + noise

您只能简化为:ys = noise。由于假定noise的均值为零,因此您不能将ys减去平均值。因此,在简化模型中未解释的变异是非居中的总平方和。

这在这里记录在rsquared项下。将yBar设置为零,我期望您会得到相同的数字。


在某些情况下,OLS使用中心模型,我不明白为什么会这样。它没有说过是中心的。你能不能检查一下这个链接:https://stats.stackexchange.com/questions/510040/statsmodels-ols-r2-calculation?noredirect=1#comment941381_510040 - Nurislom Rakhmatullaev

5

如果你的模型是:

a = <yourmodel>.fit()

然后,计算拟合值:

a.fittedvalues

计算 R 平方:

a.rsquared

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