当试图实现一个python函数来计算决定系数R²时,我注意到我得到了非常不同的结果,这取决于我使用的计算序列。
wikipedia page on R²给出了一个似乎非常清楚的解释,关于如何计算R²。我对维基页面上所说的话的麻木解释如下:
def calcR2_wikipedia(y, yhat):
# Mean value of the observed data y.
y_mean = np.mean(y)
# Total sum of squares.
SS_tot = np.sum((y - y_mean)**2)
# Residual sum of squares.
SS_res = np.sum((y - yhat)**2)
# Coefficient of determination.
R2 = 1.0 - (SS_res / SS_tot)
return R2
当我使用目标向量 y 和模型估计向量 yhat 尝试此方法时,此函数产生的R²值为-0.00301。
然而,this stackoverflow post discussing how to calculate R²给出了以下定义:
def calcR2_stackOverflow(y, yhat):
SST = np.sum((y - np.mean(y))**2)
SSReg = np.sum((yhat - np.mean(y))**2)
R2 = SSReg/SST
return R2
使用与之前相同的 y 和 yhat 向量,我现在得到的R²为0.319。
此外,在同一个stackoverflow帖子中,很多人似乎赞成用scipy模块计算R²:
import scipy
slope, intercept, r_value, p_value, std_err = scipy.stats.linregress(yhat, y)
R2 = r_value**2
在我的情况下,产生0.261。
所以我的问题是为什么从表面上被广泛接受的来源产生的R²值彼此之间根本不同?那么,计算两个向量之间的R²的正确方法是什么?
1条答案
按热度按时间cyvaqqii1#
定义
这是一种符号滥用,往往会导致误解。您正在比较两个不同的系数:
R^2
),它可以用于任何OLS回归,而不仅仅是线性回归(OLS对于拟合参数是线性的,而不是函数本身);r
或r^2
平方),仅用于线性回归。如果你仔细阅读维基百科页面上的决定系数的介绍,你会看到它在那里讨论,它开始如下:
R2有几种定义,只是有时候是等价的。
MCVE
您可以确认这些评分的经典实现返回预期结果:
然后你的函数
calcR2_wikipedia
(0.9265536406736125
)返回决定系数,它可以被确认为与sklearn.metrics.r2_score相同:另一方面,scipy.stats.linregress返回相关系数(仅对线性回归有效):
你可以交叉确认它的定义: