web-dev-qa-db-ja.com

精度スコアValueError:バイナリターゲットと連続ターゲットの混在を処理できません

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:バイナリターゲットと連続ターゲットの混在を処理できません

助けて ?ありがとうございました。

42
DataAddicted

編集(コメントの後):以下はコーディングの問題を解決しますが、非常に推奨されません

以下の@desertnautによるよく書かれた回答を読んでください。このエラーが、なぜ「修正」する必要があるのではなく、機械学習アプローチの何かが間違っていることのヒントである理由を説明しています。

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

ここでは、予測を数値的に操作することでエラーを回避しようとする誤った回答が多数ありますが、エラーの根本的な原因は、理論上のであり、計算上の問題ではありません:使用しようとしていますclassification回帰(数値予測)モデルのメトリック(精度)(LinearRegression)、つまりmeanlessless

大部分のパフォーマンスメトリックと同様に、精度はリンゴとリンゴを比較します(つまり、0/1の真のラベルと0/1の予測を再度比較します)。そのため、関数にバイナリの真のラベル(リンゴ)と連続予測(オレンジ)を比較するように依頼すると、期待されるエラーが発生します。メッセージは計算による問題を正確に伝えます 視点:

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

このメッセージは、問題に対して無効なメトリックを計算しようとしていることを直接伝えないにもかかわらず(そして、実際にそこまで行くことを期待すべきではありません)、確かにそれをscikitで学ぶのは良いことです少なくとも、何か間違ったことをしようとしているという直接的かつ明確な警告をあなたに与えます。これは必ずしも他のフレームワークの場合ではありません。たとえば、 非常によく似た状況でのKerasの動作 を参照してください。警告がまったく表示されず、回帰設定...

私はここにある他のすべての回答(受け入れられ、非常に支持されたものを含む)に驚くばかりで、単にエラーを取り除くために予測を操作することを効果的に提案しています。一連の数字になったら、コードを動作させるためにさまざまな方法(丸め、しきい値設定など)でそれらを混ぜることは確かにできますが、これはもちろん、数値操作が意味のある解決しようとしているML問題の特定のコンテキストで。

まとめると、問題は、モデル(LinearRegression)にinappropriateであるメトリック(精度)を適用していることです:分類設定の場合、モデルを変更する必要があります(たとえば、代わりにLogisticRegressionを使用します)。回帰(数値予測)設定の場合は、メトリックを変更する必要があります。 scikit-learnで利用可能なメトリックのリスト を確認します。ここでは、精度が分類でのみ使用されていることを確認できます。

OPがモデルのリストの精度を取得しようとしている recent SO question の状況も比較してください。

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つのモデルは正常に機能しますが、残りの(コメント化された)モデルはすべて同じエラーを返します。これまでに、コメントアウトされたモデルはすべて(分類ではなく)回帰モデルであり、したがって正当化されたエラーであると納得できるはずです。

最後の重要な注意事項:誰かが主張することは正当であるように聞こえるかもしれません:

わかりましたが、線形回帰を使用して、出力をラウンド/しきい値処理し、予測を「確率」として効果的に処理して、モデルを分類器に変換したい

実際、これは暗黙的であるかどうかにかかわらず、ここの他のいくつかの回答ですでに提案されています。繰り返しますが、これはinvalidアプローチです(そして、否定的な予測があるという事実は、確率として解釈できないことを既に警告しているはずです)。 Andrew NgはCourseraの人気の機械学習コースで、なぜこれが悪いアイデアなのかを説明しています-彼の 講義6.1-ロジスティック回帰|分類 Youtubeで(説明は〜3:00から)、セクション4.2(分類のため)なぜ線形回帰(分類用)なのか?教科書 統計学習入門 Hastie、Tibshirani、同僚による...

28
desertnaut

precision_scoreは分類メトリックです。回帰問題に使用することはできません。

利用可能な回帰メトリックはこちらで確認できます

4
Amey Yadav

Sklearn.metrics .accuracy_score(y_true、y_pred)メソッドは、y_predを次のように定義します。

y_pred:1次元配列のような、またはラベルインジケーター配列/スパース行列。 予測ラベル、分類子によって返されるもの。

つまり、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'をprecision_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]

4
MLKing

たぶん、これはこの質問を見つけた人を助ける:

JohnnyQがすでに指摘したように、問題はy_predに非バイナリ(0または1ではない)値があることです。 e。追加するとき

print(((y_pred != 0.) & (y_pred != 1.)).any())

出力にTrueが表示されます。 (このコマンドは、0または1以外の値があるかどうかを調べます)。

以下を使用して、非バイナリ値を表示できます。

non_binary_values = y_pred[(y_pred['score'] != 1) & (y_pred['score'] != 0)]
non_binary_idxs = y_pred[(y_pred['score'] != 1) & (y_pred['score'] != 0)].index

Printステートメントは、上記の派生変数を出力できます。

最後に、この関数はすべての非バイナリエントリのデータを消去できます。

def remove_unlabelled_data(X, y):
    drop_indexes = X[(y['score'] != 1) & (y['score'] != 0)].index
    return X.drop(drop_indexes), y.drop(drop_indexes)
1
Manu CJ

問題は、真のyがバイナリ(ゼロと1)であるのに対し、予測はそうではないことです。あなたはおそらく予測ではなく確率を生成したので、結果:)代わりにクラスメンバーシップを生成してみてください、それは動作するはずです!

1
JohnnyQ