使用 numpy 和 sklearn 计算 R^2(确定系数)给出不同的结果

Posted

技术标签:

【中文标题】使用 numpy 和 sklearn 计算 R^2(确定系数)给出不同的结果【英文标题】:R^2 (coefficient of deternimation) calculation using numpy and sklearn are giving different results 【发布时间】:2022-01-03 17:21:27 【问题描述】:

我需要计算线性回归模型的决定系数。

我得到一个奇怪的东西,使用definition 和numpy 函数的计算结果与sklearn.metrics.r2_score 的结果不同。 这段代码显示了区别:

import numpy as np
from sklearn.metrics import r2_score

y_true = np.array([2, -0.5, 2.5, 3, 0])
y_pred = np.array([2.5, 0.0, 3, 8, 0])

r2_score(y_true, y_pred)

>>> -1.6546391752577323
def my_r2_score(y_true, y_pred):
    return 1 - np.sum((y_true - y_pred) ** 2) / np.sum((np.average(y_true) - y_true) ** 2)

def my_r2_score_var(y_true, y_pred):
    return 1 - np.var(y_true - y_pred) / np.var(y_true)

print(my_r2_score(y_true, y_pred))
print(my_r2_score_var(y_true, y_pred))

>>>-1.6546391752577323
>>>-0.7835051546391754

任何机构都可以解释这种差异吗?

【问题讨论】:

R^2 取 0 到 1 之间的值,所以my_r2_score 肯定是错误的。 @vojtam my_r2_score 是正确的。当模型预测比总是预测y_true 的平均值更差时,就会出现负 R2。您在互联网上读到的关于 R^2 始终介于 0 和 1 之间的内容是完全不正确的,即使对于线性模型也是如此。 @timgeb 不,R^2 始终打开 (0,1)。您可能是指调整后的 R^2,它可能是负数。 @vojtam 对不起,这是不正确的。考虑以下数据集。 x = [0, 1, 2]y_true = [1, 2, 1]。为了预测y_true,我们使用了非常糟糕的线性模型y_pred(x) = 3*x + 1,即y_pred = [1, 4, 7]。这给了我们 RSS = 40 和 TSS = 2/3。所以 R^2 = 1 - RSS/TSS = -59。 @vojtam 不用担心!这是关于该主题的一个很酷的答案:stats.stackexchange.com/a/12991 【参考方案1】:

my_r2_score_var 错误,因为np.sum((y_true - y_pred) ** 2)/5 不等于np.var(y_true - y_pred)

>>> np.sum((y_true - y_pred) ** 2)/5
5.15
>>> np.var(y_true - y_pred)
3.46

您对np.var(y_true - y_pred) 所做的是:

>>> np.sum(((y_true - y_pred) - np.average(y_true - y_pred))**2)/5
3.46

np.sum((y_true - y_pred) ** 2) 是正确的 RSS。

您认为np.var(y_true - y_pred) 是平均 RSS(此处为 RSS/5),但事实并非如此。

但是,np.var(y_true) 恰好是平均 TSS。所以你把 1 - RSS/TSS 公式的 RSS 部分弄错了。

【讨论】:

以上是关于使用 numpy 和 sklearn 计算 R^2(确定系数)给出不同的结果的主要内容,如果未能解决你的问题,请参考以下文章

python常用库 - NumPy 和 sklearn入门

用于 sklearn 管道的 pandas 到 numpy 数组

如何使用 Python 和 Numpy 计算 r 平方?

windows下安装python的numpy,scipy,sklearn

如何在 MacOS 上正确卸载 numpy?

numpy 模块和 pandas 模块