【问题标题】:Accuracy Score ValueError: Can't Handle mix of binary and continuous targetAccuracy Score ValueError:无法处理二进制和连续目标的混合
【发布时间】:2016-10-27 04:17:11
【问题描述】:

我使用来自 scikit-learn 的 linear_model.LinearRegression 作为预测模型。它有效,而且非常完美。我在使用 accuracy_score 指标评估预测结果时遇到问题。

这是我的真实数据:

array([1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0])

我的预测数据:

array([ 0.07094605,  0.1994941 ,  0.19270157,  0.13379635,  0.04654469,
    0.09212494,  0.19952108,  0.12884365,  0.15685076, -0.01274453,
    0.32167554,  0.32167554, -0.10023553,  0.09819648, -0.06755516,
    0.25390082,  0.17248324])

我的代码:

accuracy_score(y_true, y_pred, normalize=False)

错误信息:

ValueError: Can't handle mix of binary and continuous target

【问题讨论】:

  • 愿意接受答案吗?

标签: python machine-learning scikit-learn linear-regression prediction


【解决方案1】:

问题是真正的 y 是二进制的(零和一),而您的预测不是。您可能生成了概率而不是预测,因此结果:) 尝试生成类成员资格,它应该可以工作!

【讨论】:

  • LinearRegression 产生数字预测,而不是概率;问题是由于尝试在回归设置中使用准确性,这是没有意义的,因此错误......
【解决方案2】:

accuracy_score 是一个分类指标,不能用于回归问题。

您可以在docs 中查看可用的回归指标。

【讨论】:

    【解决方案3】:

    sklearn.metrics.accuracy_score(y_true, y_pred) 方法定义了y_pred as:

    y_pred:一维数组,或标签指示数组/稀疏矩阵。 预测标签,由分类器返回。

    这意味着y_pred 必须是 1 或 0(谓词标签)的数组。它们不应该是概率。

    预测标签(1 和 0)和/或预测概率可以分别使用 LinearRegression() 模型的方法 predict() 和 predict_proba() 生成。

    1.生成预测标签:

    LR = linear_model.LinearRegression()
    y_preds=LR.predict(X_test)
    print(y_preds)
    

    输出:

    [1 1 0 1]
    

    y_preds 现在可用于accuracy_score() 方法:accuracy_score(y_true, y_pred)

    2。为标签生成概率:

    'precision_recall_curve(y_true, probas_pred)'等一些指标需要概率,可以如下生成:

    LR = linear_model.LinearRegression()
    y_preds=LR.predict_proba(X_test)
    print(y_preds)
    

    输出:

    [0.87812372 0.77490434 0.30319547 0.84999743]
    

    【讨论】:

    • LinearRegression 返回数字预测,当然不是概率;后者由 logistic 回归模型返回。
    • scikit-learn 的LinearRegression 确实不 包含predict_proba 方法(docs),如果包含确实会很奇怪。你真的运行了这里显示的代码 sn-ps 吗?
    • 友好的建议:仅仅因为他们碰巧获得了一些赞成票而保留错误和无效的答案既不是一个好主意,也不是 SO 的工作原理。我建议你删除这个(从长远来看,这对你的声誉也会更好)。
    【解决方案4】:

    尽管这里有过多的错误答案试图通过数值操纵预测来规避错误,但您的错误的根本原因是 理论 而不是计算问题:您尝试使用 分类 回归(即数值预测)模型 (LinearRegression) 中的度量(准确度),这是无意义。

    就像大多数性能指标一样,准确率将苹果与苹果进行比较(即真实标签为 0/1,预测再次为 0/1);因此,当您要求该函数将二进制真实标签(苹果)与连续预测(橙子)进行比较时,您会得到一个预期的错误,该消息会从 计算 的角度准确地告诉您问题所在观点:

    Classification metrics can't handle a mix of binary and continuous target
    

    尽管该消息没有直接告诉您您正在尝试计算一个对您的问题无效的指标(我们实际上不应该期望它走那么远),但 scikit 无疑是一件好事-learn 至少会给你一个直接而明确的警告,表明你正在尝试做错事;其他框架不一定是这种情况 - 例如参见behavior of Keras in a very similar situation,您根本没有收到任何警告,并且最终会抱怨回归设置中的“准确性”低......

    我对这里的所有其他答案(包括接受和高度赞成的答案)感到非常惊讶,有效地建议操纵预测以简单地消除错误;确实,一旦我们最终得到一组数字,我们当然可以开始以各种方式(四舍五入,阈值处理等)与它们混合以使我们的代码正常运行,但这当然并不意味着我们的数字操作是有意义在我们试图解决的机器学习问题的特定上下文中。

    所以,总结一下:问题是您正在为您的模型 (LinearRegression) 应用一个不合适的指标(准确性):如果您处于分类设置中,您应该更改您的模型(例如,改用LogisticRegression);如果您处于回归(即数字预测)设置中,则应更改指标。检查list of metrics available in scikit-learn,您可以在其中确认准确度仅用于分类。

    还将情况与recent SO question 进行比较,其中 OP 正在尝试获取模型列表的准确性:

    models = []
    models.append(('SVM', svm.SVC()))
    models.append(('LR', LogisticRegression()))
    models.append(('LDA', LinearDiscriminantAnalysis()))
    models.append(('KNN', KNeighborsClassifier()))
    models.append(('CART', DecisionTreeClassifier()))
    models.append(('NB', GaussianNB()))
    #models.append(('SGDRegressor', linear_model.SGDRegressor())) #ValueError: Classification metrics can't handle a mix of binary and continuous targets
    #models.append(('BayesianRidge', linear_model.BayesianRidge())) #ValueError: Classification metrics can't handle a mix of binary and continuous targets
    #models.append(('LassoLars', linear_model.LassoLars())) #ValueError: Classification metrics can't handle a mix of binary and continuous targets
    #models.append(('ARDRegression', linear_model.ARDRegression())) #ValueError: Classification metrics can't handle a mix of binary and continuous targets
    #models.append(('PassiveAggressiveRegressor', linear_model.PassiveAggressiveRegressor())) #ValueError: Classification metrics can't handle a mix of binary and continuous targets
    #models.append(('TheilSenRegressor', linear_model.TheilSenRegressor())) #ValueError: Classification metrics can't handle a mix of binary and continuous targets
    #models.append(('LinearRegression', linear_model.LinearRegression())) #ValueError: Classification metrics can't handle a mix of binary and continuous targets
    

    前 6 个模型工作正常,而所有其余(已注释掉)的模型都给出相同的错误。到目前为止,您应该能够说服自己所有被注释掉的模型都是回归(而不是分类)模型,因此是合理的错误。

    最后一个重要提示:某人声称可能听起来合法:

    好的,但我想使用线性回归,然后就 舍入/阈值输出,有效地将预测视为 “概率”,从而将模型转换为分类器

    实际上,这里的其他几个答案已经暗示了这一点,无论是否隐含;同样,这是一种无效方法(您有负面预测的事实应该已经提醒您它们不能被解释为概率)。 Andrew Ng 在 Coursera 的热门机器学习课程中解释了为什么这是一个坏主意 - 请参阅他在 Youtube 上的 Lecture 6.1 - Logistic Regression | Classification(解释从 ~ 3:00 开始),以及 4.2 为什么不是线性回归 [用于分类]? 的(强烈推荐和免费提供的)教科书 An Introduction to Statistical Learning Hastie、Tibshirani 和同事...

    【讨论】:

    • 我同意;为什么在我们有逻辑时使用线性回归?但是,在 ISL 中该部分的倒数第二段(在第七版中?),作者似乎暗示它实际上在二进制分类情况下可能并没有那么糟糕:“可以证明 $X使用线性回归获得的 \hat{\beta}$ 实际上是在这种特殊情况下对 $Pr(\text{drug overdose}\mid X)$ 的估计”并且“分类......将与线性判别分析(LDA)程序”。有什么见解吗?
    • 这个和另一个答案是正确的,解释得很好。
    【解决方案5】:

    错误是因为 y_pred 和 y_true 的数据类型不同。 y_true 可能是数据帧,而 y_pred 是数组列表。如果将两者都转换为数组,则问题将得到解决。

    【讨论】:

    • 请阅读@desertnaut 的回答。尝试这样做在理论上是错误的。
    【解决方案6】:

    随便用

    y_pred = (y_pred > 0.5)
    accuracy_score(y_true, y_pred, normalize=False)
    

    【讨论】:

    • 这是完全错误的;请参阅上面解释原因的自己的答案。
    【解决方案7】:

    我遇到了同样的问题。y_test 和 y_pred 的 dtype 不同。确保两者的 dtypes 相同。

    【讨论】:

      【解决方案8】:

      accuracy_score 是一个分类指标,不能用于回归问题。

      这样使用:

      accuracy_score(y_true, np.round(abs(y_pred)), normalize=False) 
      

      【讨论】:

      • 你开始正确,你应该停在那里;试图按照您的建议操纵结果是无效的,它实际上与您的第一个(正确)陈述相矛盾。请注意,这正是最初被接受(和错误)的答案中的建议,现在已被删除。
      【解决方案9】:

      这为我解决了同样的问题, 使用 .round() 进行预测,

      accuracy_score(y_true, y_pred.round(), normalize=False)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-01-25
        • 2014-07-26
        • 2019-06-24
        • 2018-04-21
        • 2014-07-30
        • 2021-12-20
        • 2020-06-29
        • 2017-08-14
        相关资源
        最近更新 更多