使用 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(确定系数)给出不同的结果的主要内容,如果未能解决你的问题,请参考以下文章
用于 sklearn 管道的 pandas 到 numpy 数组