【问题标题】:Why do coefficient of determination, R², implementations produce different results?为什么确定系数 R² 实现会产生不同的结果?
【发布时间】:2021-01-19 09:12:25
【问题描述】:

在尝试实现一个用于计算决定系数 R² 的 Python 函数时,我注意到我得到的结果完全不同,具体取决于我使用的计算顺序。

wikipedia page on R² 给出了关于如何计算 R² 的看似非常清楚的解释。我对 wiki 页面上所说的内容的 numpy 解释如下:

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 尝试此方法时,此函数产生 -0.00301 的 R² 值。

但是,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

使用与以前相同的 yyhat 向量的方法,我现在得到的 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² 的正确方法是什么?

【问题讨论】:

    标签: python numpy statistics coefficient-of-determination


    【解决方案1】:

    定义

    这是一种符号滥用,通常会导致误解。您正在比较两个不同的系数:

    如果你仔细阅读维基百科页面上关于确定系数的介绍,你会看到那里有讨论,开头如下:

    R2 有几个定义,只是有时 等价的。

    MCVE

    您可以确认这些分数的经典实现会返回预期结果:

    import numpy as np
    import scipy
    from sklearn import metrics
    
    np.random.seed(12345)
    x = np.linspace(-3, 3, 1001)
    yh = np.polynomial.polynomial.polyval(x, [1, 2])
    e = np.random.randn(x.size)
    yn = yh + e
    

    那么你的函数calcR2_wikipedia(0.9265536406736125)返回决定系数,可以确认返回与sklearn.metrics.r2_score相同:

    metrics.r2_score(yn, yh) # 0.9265536406736125
    

    另一方面,scipy.stats.linregress 返回相关系数(仅对线性回归有效):

    slope, intercept, r_value, p_value, std_err = scipy.stats.linregress(yh, yn)
    r_value # 0.9625821384210018
    

    你可以通过它的定义来交叉确认:

    C = np.cov(yh, yn)
    C[1,0]/np.sqrt(C[0,0]*C[1,1]) # 0.9625821384210017
    

    【讨论】:

    • 感谢您的回答。我还是有些疑惑,能否请您验证这两点:当您说“calcR2_wikipedia 返回相关系数”时,您真的是指决定系数吗? sklearn.metrics.r2_score 函数,尽管被命名为 r2,它是否返回决定系数 R2? (这将是一个平方 pearsons 相关系数的符号。)
    • @Petahanks 确实是决定系数 R2(大写字母,已更正)。如文档和维基百科中所述,它是 r 或 rho 值(线性相关)而不是 r2(小写,符号为您提供有关相关性的额外信息)。
    猜你喜欢
    • 1970-01-01
    • 2019-02-15
    • 2020-01-03
    • 2023-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-10
    相关资源
    最近更新 更多