准确度分数ValueError:无法处理二进制和连续目标的混合

Dat*_*ted 48 python machine-learning prediction linear-regression scikit-learn

我使用linear_model.LinearRegressionscikit-learn作为预测模型.它的工作原理很完美.我有一个问题是使用accuracy_score指标评估预测结果.这是我的真实数据:

array([1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0])
Run Code Online (Sandbox Code Playgroud)

我的预测数据:

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])
Run Code Online (Sandbox Code Playgroud)

我的代码:

accuracy_score(y_true, y_pred, normalize=False)
Run Code Online (Sandbox Code Playgroud)

错误信息:

ValueError:无法处理二进制和连续目标的混合

救命 ?谢谢.

des*_*aut 36

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

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

Classification metrics can't handle a mix of binary and continuous target
Run Code Online (Sandbox Code Playgroud)

尽管该消息并未直接告诉您,您正在尝试计算一个对您的问题无效的指标(我们实际上不应该期望它走得那么远),但是scikit-learn肯定是一件好事.至少会给你一个直接和明确的警告,你正在尝试做错事; 其他框架并不一定如此 - 例如,看看Keras在非常类似的情况下行为,你根本没有得到任何警告,而且最终抱怨回归设置中的"准确度"低......

我对这里的所有其他答案(包括被接受的和高度赞成的答案)非常惊讶,有效地建议操纵预测以简单地摆脱错误; 确实,一旦我们得到一组数字,我们当然可以开始以各种方式(舍入,阈值等)与它们混合以使我们的代码表现,但这当然并不意味着我们的数字操作是在我们试图解决的ML问题的特定背景下有意义.

所以,结束:问题是你正在应用一个适合你的模型的度量(精度)(LinearRegression如果你在分类设置中,你应该改变你的模型(例如使用LogisticRegression); 如果您处于回归(即数字预测)设置,则应更改度量标准.检查scikit-learn中可用的度量列表,您可以在其中确认仅在分类中使用准确性.

将情况与最近的SO问题进行比较,其中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
Run Code Online (Sandbox Code Playgroud)

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

最后一个重要的注意事项:某人声称:

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

实际上,这里已经在其他几个答案中暗示过,无论是否隐含; 再次,这是一种无效的方法(并且你有负面预测的事实应该已经提醒你它们不能被解释为概率).Andrew Ng在Coursera的流行机器学习课程中解释了为什么这是一个坏主意 - 请参阅他的第6.1讲 - 逻辑回归 Youtube上的分类(解释从~3:00开始),以及4.2为什么不是线性回归[用于分类]?(强烈推荐和免费提供)教科书Hastie,Tibshirani及其同事的统计学习简介 ......


nat*_*usa 30

编辑(评论后):下面将解决编码问题,但强烈建议不要使用此方法,因为线性回归模型是一个非常差的分类器,很可能不会正确地分类.

阅读@desertnaut下面写得很好的答案,解释为什么这个错误在机器学习方法中有一些错误,而不是你必须"修复"的东西.

accuracy_score(y_true, y_pred.round(), normalize=False)
Run Code Online (Sandbox Code Playgroud)

  • 对于谁来到这里:这个答案是明显错误的**; 错误的原因是尝试在*回归*设置中使用精度作为度量(注意OP的模型是`LinearRegression`,*not*`LogisticRegression`),这是没有意义的...... (11认同)

Ame*_*dav 11

Accuracy_score 是一个分类指标,您不能将其用于回归问题。

您可以在此处查看可用的回归指标


Joh*_*nyQ 7

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


MLK*_*ing 7

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

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

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

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

1. 生成预测标签:

LR = linear_model.LinearRegression()
y_preds=LR.predict(X_test)
print(y_preds)
Run Code Online (Sandbox Code Playgroud)

输出:

[1 1 0 1]
Run Code Online (Sandbox Code Playgroud)

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

2. 生成标签的概率:

某些指标(例如“ precision_recall_curve(y_true,probas_pred)”)需要概率,可以按如下方式生成:

[1 1 0 1]
Run Code Online (Sandbox Code Playgroud)

输出:

[0.87812372 0.77490434 0.30319547 0.84999743]
Run Code Online (Sandbox Code Playgroud)

  • scikit-learn 的“LinearRegression”**不**包含“predict_proba”方法([文档](https://scikit-learn.org/stable/modules/ generated/sklearn.linear_model.LinearRegression.html)),并且如果真是这样,那确实很奇怪。您实际上运行了此处显示的代码片段吗? (2认同)

Kir*_*ran 7

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

accuracy_score(y_true, y_pred.round(), normalize=False)
Run Code Online (Sandbox Code Playgroud)