为什么我的r ^ 2值总是这么负?

时间:2019-06-02 00:14:31

标签: scikit-learn regression linear-regression scoring performance-measuring

我不确定问题是否出在我的回归估计模型上,或者我对r ^ 2拟合度度量的实际含义有所了解。我正在使用scikit learning和〜11种不同的回归估计量进行项目研究,以产生(大致!)棒球幻想表现的预测。某些模型总是比其他模型好(决策树回归和额外树回归产生最差的r ^ 2分数,而ElasticCV和LassoCV产生最佳的r ^ 2分数,有时甚至可能是一个稍微正的数字!)。

如果一条水平线的r ^ 2得分为0,那么即使我的所有模型都一文不值,字面上的预测值是零,并且完全随机地将数字分散开来,我也不应该得到小的正数有时,如果仅凭纯粹的愚蠢运气,就可以获得r ^ 2?我使用的11个估算器中有8个尽管运行了数百次不同的数据集,但从未为r ^ 2产生过很小的正数。

我误会了r ^ 2的工作原理吗?

我也不在sklearn的.score函数中切换顺序。我已经多次检查了两次。当我以错误的方式对y_pred和y_true进行排序时,它会生成r ^ 2的值,这些值是非常负的(例如<-50 big)

事实真是如此,这更使我感到困惑,因为r ^ 2是如何衡量适合度的,但我离题了……

## I don't know whether I'm supposed to include my df4 or even a
##sample, but suffice to say here is just a single row to show what
##kind of data we have.  It is all normalized and/or zscore'd
"""

>> print(df4.head(1))

        HomeAway  ParkFactor    Salary  HandedVs  Hand  oppoBullpen  \
Points                                                                       
3.0          1.0      -1.229 -0.122111       1.0          0.0     -0.90331   

        RibRunHistory  BibTibHistory  GrabBagHistory  oppoTotesRank  \
Points                                                                
3.0          0.964943       0.806874       -0.224993      -0.846859   

        oppoSwipesRank  oppoWalksRank      Temp    Precip  WindSpeed  \
Points                                                                 
3.0           -1.40371      -1.159115 -0.665324 -0.380048  -0.365671   

        WindDirection  oppoPositFantasy  oppoFantasy  
Points                                                
3.0          0.229944         -1.011505     0.919269  

"""



def ElasticNetValidation(df4):
    X = df4.values
    y = df4.index
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.1)

    ENTrain = ElasticNetCV(cv=20)
    ENTrain.fit(X_train, y_train)
    y_pred = ENTrain.predict(X_test)

    EN = ElasticNetCV(cv=20)
    ENModel = EN.fit(X, y)

    print('ElasticNet R^2: ' + str(r2_score(y_test, y_pred)))
    scores = cross_val_score(ENModel, X, y, cv=20)
    print("ElasticNet Accuracy: %0.2f (+/- %0.2f)" % (scores.mean(), scores.std() * 2))

    return ENModel

当我运行此估算器以及我正在尝试的其他十个回归估算器时,几乎每次都得到r2_score()和cross_val_score()。mean()均为负数。某些估计器始终会产生甚至不接近零的负分数(决策树回归器,额外树回归器)。某些估算器的性能会更好,甚至有时会产生很小的正值,尽管从不超过0.01,但即使在某些时候,这些估算器(elasticCV,lassoCV,linearRegression)在大多数情况下都是负数,尽管只是略微负数。

即使我正在构建的这些模型也是可怕的。说,它们完全是随机的,对目标没有任何预测能力:它难道不应该比普通水平线更好地预测吗?一个不相关的模型如何始终如一地预测比水平线高的POORER?

1 个答案:

答案 0 :(得分:0)

您最有可能遇到过拟合问题。就像您正确提到的那样,如果模型的性能远不止于拟合截距项,则可能会出现负R2值。您的模型可能未捕获任何“真实”基础依赖性,而仅拟合随机噪声。您正在一个小型测试集上计算R2分数,这种噪声拟合很可能始终比测试集上的简单拦截项产生更差的结果。

这是偏差方差折衷的典型情况。您的模型具有低偏差和高方差,因此在测试数据上的性能较差。有一些旨在减少过度拟合/差异的模型,例如套索和弹性网。这些模型实际上是您认为效果更好的模型之一。

为了使自己确信sklearn的r2_score函数可以正常工作并熟悉它,我建议您首先拟合仅根据训练数据预测模型(将CV保留为好)。在这种情况下,R2永远不能为负。此外,请确保您的模型包含拦截项(只要有)。