Python sci-kit learn(度量):r2_score和explained_variance_score之间的区别是什么?

31
我注意到 r2_scoreexplained_variance_score 都是用于回归问题的内置方法,存放在sklearn.metrics中。
我一直认为r2_score是模型解释方差的百分比。请问它与explained_variance_score有何不同?
你何时会选择其中一个?
谢谢!
2个回答

38
大多数我找到的答案(包括这里)都强调了R2解释方差分数之间的区别,即:残差平均值(即误差平均值)。
然而,有一个重要的问题被忽略了,那就是:为什么我需要考虑误差的平均值?
提醒一下:
R2:是确定系数,它测量由(最小二乘)线性回归解释的变化量。
你可以从不同的角度来看待它,以评估预测的y值的目的,如下所示:
actual_y的方差 × R2actual_y = 预测的y的方差
因此,直观地说,R2越接近1,实际的y和预测的y将具有相同的方差(即相同的传播)。
正如先前提到的,主要区别在于误差的平均值;如果我们查看公式,就会发现这是正确的:
R<sup>2</sup> = 1 - [(Sum of Squared Residuals / n) / Variance<sub>y_actual</sub>]

Explained Variance Score = 1 - [Variance<sub>(Y<sub>predicted</sub> - Y<sub>actual</sub>)</sub> / Variance<sub>y_actual</sub>]

其中:

Variance(Y<sub>predicted</sub> - Y<sub>actual</sub>) = (Sum of Squared Residuals - <b>Mean Error</b>) / n 

显然,唯一的区别是我们从第一个公式中减去了平均误差! ... 但为什么呢?


当我们将R2得分解释方差得分进行比较时,基本上是在检查平均误差; 因此,如果R2= 解释方差得分,则意味着:平均误差=

平均误差反映了我们估计器的倾向,即:有偏估计与无偏估计。


总而言之:

如果您希望拥有无偏估计器,以便我们的模型既不低估也不高估,那么您可能需要考虑考虑考虑误差平均值


1
那么您建议使用解释方差得分而不是R2得分吗? - basilisk
1
@msarafzadeh 看看通用方差公式,你会发现无论如何都无所谓。 - Yahya
1
@msarafzadeh 是的,Var(X+Z) = Var(X)+Var(Z),同时 Var(aZ) = a^2 * Var(Z),其中 'a' 是一个常数,那么 Var(Y-Yp)=Var(-1(Yp-Y))=(-1)^2 * Var(Yp-Y) = Var(Yp-Y)。 - vpz
2
我认为 Variance(Ypredicted - Yactual) = (Sum of Squared Residuals - Mean Error) / n 不正确。应该是 sum((Ypredicted - Yestimated - Mean Error)**2) / N。请查看源代码: https://github.com/scikit-learn/scikit-learn/blob/95119c13af77c76e150b753485c662b7c52a41a2/sklearn/metrics/_regression.py#L557 - Aleksandar Jovanovic
它们是同一件事情:(1) model = LinearRegression(); model.score(X=x_column_name, y=y_column_name]]) 和 (2) metrics.explained_variance_score(y_column_name, y_predicted) 将会给出完全相同的输出,即相同的百分比数值。两者都是线性回归模型的R平方。参考资料:R平方公式:https://www.ncl.ac.uk/webtemplate/ask-assets/external/maths-resources/statistics/regression-and-correlation/coefficient-of-determination-r-squared.html - undefined
显示剩余2条评论

14

好的,看这个例子:

In [123]:
#data
y_true = [3, -0.5, 2, 7]
y_pred = [2.5, 0.0, 2, 8]
print metrics.explained_variance_score(y_true, y_pred)
print metrics.r2_score(y_true, y_pred)
0.957173447537
0.948608137045
In [124]:
#what explained_variance_score really is
1-np.cov(np.array(y_true)-np.array(y_pred))/np.cov(y_true)
Out[124]:
0.95717344753747324
In [125]:
#what r^2 really is
1-((np.array(y_true)-np.array(y_pred))**2).sum()/(4*np.array(y_true).std()**2)
Out[125]:
0.94860813704496794
In [126]:
#Notice that the mean residue is not 0
(np.array(y_true)-np.array(y_pred)).mean()
Out[126]:
-0.25
In [127]:
#if the predicted values are different, such that the mean residue IS 0:
y_pred=[2.5, 0.0, 2, 7]
(np.array(y_true)-np.array(y_pred)).mean()
Out[127]:
0.0
In [128]:
#They become the same stuff
print metrics.explained_variance_score(y_true, y_pred)
print metrics.r2_score(y_true, y_pred)
0.982869379015
0.982869379015

因此,当平均残差为0时,它们是相同的。选择哪一个取决于您的需求,即平均残差是否假设为0?


为什么 metrics.r2_score(y_true, y_pred) 不等于 metrics.r2_score(y_pred, y_true) - Sean.H
1
我猜你本来可以使用np.var而不是np.cov。这让我有点困惑,因为你实际上并没有计算协方差,而是方差。同时,先取标准差再平方等价于取方差:4*np.array(y_true).std()**2 = 4*np.var(y_true) = 29.1875 - Mahesha999

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