scikit learnを使用したマルチクラスケースの精度、再現率、精度、およびf1スコアを計算する方法


109

私はデータがこのように見える感情分析問題で働いています:

label instances
    5    1190
    4     838
    3     239
    1     204
    2     127

したがって、1190はでinstancesラベル付けされて5いるため、私のデータは不均衡です。分類については、scikitのSVCを使用しています。問題は、マルチクラスの場合の精度、再現率、精度、およびf1-scoreを正確に計算するために、データを正しい方法でバランスを取る方法がわからないことです。だから私は次のアプローチを試しました:

最初:

    wclf = SVC(kernel='linear', C= 1, class_weight={1: 10})
    wclf.fit(X, y)
    weighted_prediction = wclf.predict(X_test)

print 'Accuracy:', accuracy_score(y_test, weighted_prediction)
print 'F1 score:', f1_score(y_test, weighted_prediction,average='weighted')
print 'Recall:', recall_score(y_test, weighted_prediction,
                              average='weighted')
print 'Precision:', precision_score(y_test, weighted_prediction,
                                    average='weighted')
print '\n clasification report:\n', classification_report(y_test, weighted_prediction)
print '\n confussion matrix:\n',confusion_matrix(y_test, weighted_prediction)

第二:

auto_wclf = SVC(kernel='linear', C= 1, class_weight='auto')
auto_wclf.fit(X, y)
auto_weighted_prediction = auto_wclf.predict(X_test)

print 'Accuracy:', accuracy_score(y_test, auto_weighted_prediction)

print 'F1 score:', f1_score(y_test, auto_weighted_prediction,
                            average='weighted')

print 'Recall:', recall_score(y_test, auto_weighted_prediction,
                              average='weighted')

print 'Precision:', precision_score(y_test, auto_weighted_prediction,
                                    average='weighted')

print '\n clasification report:\n', classification_report(y_test,auto_weighted_prediction)

print '\n confussion matrix:\n',confusion_matrix(y_test, auto_weighted_prediction)

第三:

clf = SVC(kernel='linear', C= 1)
clf.fit(X, y)
prediction = clf.predict(X_test)


from sklearn.metrics import precision_score, \
    recall_score, confusion_matrix, classification_report, \
    accuracy_score, f1_score

print 'Accuracy:', accuracy_score(y_test, prediction)
print 'F1 score:', f1_score(y_test, prediction)
print 'Recall:', recall_score(y_test, prediction)
print 'Precision:', precision_score(y_test, prediction)
print '\n clasification report:\n', classification_report(y_test,prediction)
print '\n confussion matrix:\n',confusion_matrix(y_test, prediction)


F1 score:/usr/local/lib/python2.7/site-packages/sklearn/metrics/classification.py:676: DeprecationWarning: The default `weighted` averaging is deprecated, and from version 0.18, use of precision, recall or F-score with multiclass or multilabel data or pos_label=None will result in an exception. Please set an explicit value for `average`, one of (None, 'micro', 'macro', 'weighted', 'samples'). In cross validation use, for instance, scoring="f1_weighted" instead of scoring="f1".
  sample_weight=sample_weight)
/usr/local/lib/python2.7/site-packages/sklearn/metrics/classification.py:1172: DeprecationWarning: The default `weighted` averaging is deprecated, and from version 0.18, use of precision, recall or F-score with multiclass or multilabel data or pos_label=None will result in an exception. Please set an explicit value for `average`, one of (None, 'micro', 'macro', 'weighted', 'samples'). In cross validation use, for instance, scoring="f1_weighted" instead of scoring="f1".
  sample_weight=sample_weight)
/usr/local/lib/python2.7/site-packages/sklearn/metrics/classification.py:1082: DeprecationWarning: The default `weighted` averaging is deprecated, and from version 0.18, use of precision, recall or F-score with multiclass or multilabel data or pos_label=None will result in an exception. Please set an explicit value for `average`, one of (None, 'micro', 'macro', 'weighted', 'samples'). In cross validation use, for instance, scoring="f1_weighted" instead of scoring="f1".
  sample_weight=sample_weight)
 0.930416613529

しかし、私はこのような警告を受けます:

/usr/local/lib/python2.7/site-packages/sklearn/metrics/classification.py:1172:
DeprecationWarning: The default `weighted` averaging is deprecated,
and from version 0.18, use of precision, recall or F-score with 
multiclass or multilabel data or pos_label=None will result in an 
exception. Please set an explicit value for `average`, one of (None, 
'micro', 'macro', 'weighted', 'samples'). In cross validation use, for 
instance, scoring="f1_weighted" instead of scoring="f1"

分類子のメトリックを正しい方法で計算するために、バランスの取れていないデータを正しく処理するにはどうすればよいですか?


それではaverage、3番目のケースでパラメーターを追加してみませんか?
ヤンジエ

1
@yangjieわからない。ドキュメントを確認するだけですが、不均衡データのメトリックを正しく使用する方法がわかりません。幅広い説明と例を提供していただけますか?ありがとう!
new_with_python 2015

回答:


164

どのウェイトが何に使用されているかについては、多くの混乱があると思います。私があなたの邪魔をするものを正確に知っているかどうかわからないので、私はさまざまなトピックをカバーするつもりです、私と一緒にください;)

クラスの重み

class_weightパラメータからの重みは、分類器トレーニングするために使用されます。これらは、使用しているメトリックの計算には使用されません。クラスの重みが異なると、分類子が異なるため、数値は異なります。

基本的に、すべてのscikit-learn分類子では、クラスの重みを使用して、クラスがどれほど重要であるかをモデルに伝えます。つまり、トレーニング中に、分類子は重みの高いクラスを適切に分類するために特別な努力をします。
その方法はアルゴリズムによって異なります。SVCでどのように機能するかについての詳細が必要で、ドキュメントが意味をなさない場合は、遠慮なく言及してください。

メトリック

分類子を取得したら、それがどれだけうまく機能しているかを知りたいと思います。ここaccuracyrecall_score、言及したメトリックを使用できます:、、f1_score...

通常、クラス分布が不均衡である場合、最も頻度の高いクラスを予測するだけのモデルに高いスコアを与えるため、精度は悪い選択と見なされます。

これらのすべてのメトリックについては詳しく説明しませんが、を除いてaccuracy、それらはクラスレベルで自然に適用されることに注意してくださいprint。分類レポートのこれを見るとわかるように、クラスごとに定義されています。彼らは、どのクラスがポジティブであるtrue positivesfalse negativeを定義することを必要とするなどの概念に依存しています。

             precision    recall  f1-score   support

          0       0.65      1.00      0.79        17
          1       0.57      0.75      0.65        16
          2       0.33      0.06      0.10        17
avg / total       0.52      0.60      0.51        50

警告

F1 score:/usr/local/lib/python2.7/site-packages/sklearn/metrics/classification.py:676: DeprecationWarning: The 
default `weighted` averaging is deprecated, and from version 0.18, 
use of precision, recall or F-score with multiclass or multilabel data  
or pos_label=None will result in an exception. Please set an explicit 
value for `average`, one of (None, 'micro', 'macro', 'weighted', 
'samples'). In cross validation use, for instance, 
scoring="f1_weighted" instead of scoring="f1".

計算方法を定義せずにf1-score、recall、precisionを使用しているため、この警告が表示されます!質問は言い換えることができます:上記の分類レポートから、f1-scoreに対して1つのグローバル番号をどのように出力しますか?あなたは出来る:

  1. 各クラスのf1スコアの平均をとりavg / totalます。これが上記の結果です。これは、マクロ平均化とも呼ばれます。
  2. 真陽性/偽陰性などのグローバルカウントを使用してf1-scoreを計算します(各クラスの真陽性/偽陰性の数を合計します)。別名マイクロ平均化。
  3. f1スコアの加重平均を計算します。'weighted'scikit-learnでを使用すると、クラスのサポートによってf1-scoreが比較されます。クラスが持つ要素が多いほど、計算でこのクラスのf1-scoreが重要になります。

これらはscikit-learnの3つのオプションです。警告の1つを選択する必要があることを示しています。したがってaverage、scoreメソッドの引数を指定する必要があります。

どちらを選択するかは、分類子のパフォーマンスをどのように測定するかによって異なります。たとえば、マクロ平均ではクラスの不均衡は考慮されず、クラス1のf1-scoreはクラスのf1-scoreと同じくらい重要です。 5.加重平均を使用すると、クラス5の重要性が高まります。

これらのメトリックの引数全体の仕様は、現在scikit-learnでは明確ではありません。ドキュメントによれば、バージョン0.18で改善されます。彼らはいくつかの非自明な標準動作を削除しており、開発者がそれに気づくように警告を出しています。

スコアの計算

最後に触れておきたいのは(気付いている場合は自由にスキップしてください)スコアは、分類子が見ことのないデータで計算された場合にのみ意味があるということです。分類器の適合に使用されたデータで取得するスコアはまったく無関係であるため、これは非常に重要です。

StratifiedShuffleSplitこれはを使用して行う方法です。これにより、データのランダムな分割(シャッフル後)が可能になり、ラベルの分布が維持されます。

from sklearn.datasets import make_classification
from sklearn.cross_validation import StratifiedShuffleSplit
from sklearn.metrics import accuracy_score, f1_score, precision_score, recall_score, classification_report, confusion_matrix

# We use a utility to generate artificial classification data.
X, y = make_classification(n_samples=100, n_informative=10, n_classes=3)
sss = StratifiedShuffleSplit(y, n_iter=1, test_size=0.5, random_state=0)
for train_idx, test_idx in sss:
    X_train, X_test, y_train, y_test = X[train_idx], X[test_idx], y[train_idx], y[test_idx]
    svc.fit(X_train, y_train)
    y_pred = svc.predict(X_test)
    print(f1_score(y_test, y_pred, average="macro"))
    print(precision_score(y_test, y_pred, average="macro"))
    print(recall_score(y_test, y_pred, average="macro"))    

お役に立てれば。


マルチクラスの場合、クラスの重みをどのように指定しますか?たとえば、class_weight={1:10}3つのクラスを持つデータの意味は何ですか?
Aziz Javed 2017年

とにかくラベルごとの正確性スコアを取得することはできますか?
Ankur Sinha

マイクロがどのように機能するかをより明確に説明できますか。また、バイナリについては何も言及していません
控えめな

私にとっては、成層化されたシャッフルが問題を引き起こしていたので、表示されていたとおりに列車テスト分割に切り替えましたValueError: The least populated class in y has only 1 member, which is too few. The minimum number of labels for any class cannot be less than 2.。train-test splitで問題なく機能していますが、SSSでこのエラーが発生する理由を誰かが手伝ってくれる?ありがとう。
Akash Kandpal 2018

こんにちはあなたのコードをテストしましたが、このエラーメッセージがありますC:\ Users \\ Anaconda3 \ lib \ site-packages \ sklearn \ metrics \ classification.py:976:DeprecationWarning:バージョン0.18以降、使用時にバイナリ入力が特別に処理されません平均精度/リコール/ Fスコア。ポジティブクラスのパフォーマンスのみを報告するには、average = 'binary'を使用してください。「ポジティブクラスパフォーマンス」、DeprecationWarning)
Chedi Bechikh

73

ここには非常に詳細な答えがたくさんありますが、あなたが正しい質問に答えているとは思いません。質問を理解すると、2つの懸念があります。

  1. マルチクラス問題を採点するにはどうすればよいですか?
  2. 不均衡なデータをどのように処理しますか?

1。

scikit-learnでは、マルチクラス問題とシングルクラス問題の両方でほとんどのスコアリング関数を使用できます。例:

from sklearn.metrics import precision_recall_fscore_support as score

predicted = [1,2,3,4,5,1,2,1,1,4,5] 
y_test = [1,2,3,4,5,1,2,1,1,4,1]

precision, recall, fscore, support = score(y_test, predicted)

print('precision: {}'.format(precision))
print('recall: {}'.format(recall))
print('fscore: {}'.format(fscore))
print('support: {}'.format(support))

このようにして、各クラスの具体的で解釈可能な数値が得られます。

| Label | Precision | Recall | FScore | Support |
|-------|-----------|--------|--------|---------|
| 1     | 94%       | 83%    | 0.88   | 204     |
| 2     | 71%       | 50%    | 0.54   | 127     |
| ...   | ...       | ...    | ...    | ...     |
| 4     | 80%       | 98%    | 0.89   | 838     |
| 5     | 93%       | 81%    | 0.91   | 1190    |

その後...

2。

...不均衡なデータが問題であるかどうかがわかります。あまり表現されていないクラス(クラス1および2)のスコアリングが、トレーニングサンプルが多いクラス(クラス4および5)のスコアリングよりも低い場合、不均衡データが実際に問題であることがわかり、次のように対処できます。このスレッドの他の回答のいくつかに記載されています。ただし、予測するデータに同じクラス分布が存在する場合、不均衡なトレーニングデータはデータをよく表すため、不均衡は良いことです。


1
素晴らしいポストとよく言った。ありがとう
アルビス

1
ちょっとフォローアップの質問です:どのようにしてラベルを印刷しましたprecision_recall_fscore_supportか?ラベルは注文順に印刷されていますか?
BigD 2017

@BigDええ、一番下のscikit-learn.org/stable/modules/generated/…を参照してください。average=Noneラベルを設定して定義すると、指定したラベルごとに、探している指標が表示されます。
wonderkid2

とにかくラベルごとの正確性スコアを取得することはできますか?
Ankur Sinha

@trollsterどういう意味かわかりませんか?回答のラベルごとの精度スコアに表示されているものではありませんか?
wonderkid2

16

提起された質問

「不均衡なデータを持つマルチクラス分類にどのメトリックを使用する必要があるか」という質問への回答:Macro-F1-measure。マクロ精度とマクロリコールも使用できますが、それらはバイナリ分類のように簡単に解釈できず、それらはすでにFメジャーに組み込まれており、過剰なメトリックはメソッドの比較、パラメーターのチューニングなどを複雑にします。

マイクロ平均はクラスの不均衡に敏感です。たとえば、メソッドが最も一般的なラベルに適していて、他のラベルを完全に混乱させている場合、マイクロ平均メトリックは良い結果を示します。

加重平均は、ラベルの数によって加重するため、不均衡なデータにはあまり適していません。さらに、それはあまりにも解釈が難しく、不評です。たとえば、以下の非常に詳細な調査では、そのような平均化について言及していないので、一読することを強くお勧めします。

ソコロバ、マリーナ、ガイラパルム。「分類タスクのパフォーマンス測定値の体系的な分析。」情報処理および管理45.4(2009):427-437。

アプリケーション固有の質問

しかし、あなたの仕事に戻って、私は2つのトピックを研究します:

  1. 特定のタスクに一般的に使用される指標-これにより、(a)メソッドを他のメソッドと比較して、何か間違ったことを理解し、(b)自分でこれを調査せず、他の誰かの発見を再利用できます。
  2. メソッドのさまざまなエラーのコスト-たとえば、アプリケーションのユースケースは4つ星と5つ星のレビューのみに依存する可能性があります-この場合、適切なメトリックはこれら2つのラベルのみをカウントする必要があります。

一般的に使用される指標。 文献を調べて推測できるように、2つの主要な評価指標があります。

  1. 使用される精度、例えば

ゆう、エイプリル、ダリル・チャン。「Yelpビジネスを使用したマルチクラス感情予測。」

リンク)-著者はほぼ同じ評価分布で作業していることに注意してください。図5を参照してください。

パン、ボー、リリアン・リー。「星を見る:評価尺度に関する感情分類のためにクラスの関係を利用する」第43回計算言語学会の年次総会の議事録。計算言語学協会、2005年。

リンク

  1. MSE(または、それほど頻繁ではないが、平均絶対誤差 -MAE)-たとえば、

Lee、Moontae、およびR. Grafe。「レストランレビューによるマルチクラス感情分析。」CS N 224(2010)の最終プロジェクト。

リンク)-精度とMSEの両方を調査し、後者の方が優れていると考えています

パパス、ニコラオス、マルコーニ通り、アンドレイポペスクベリ。「スターの説明:アスペクトベースの感情分析のための加重複数インスタンス学習」自然言語処理における経験的方法に関する2014年会議の議事録。いいえ。EPFL-CONF-200899。2014。

リンク)-評価とベースラインのアプローチにscikit-learnを利用し、コードが利用可能であることを述べます。しかし、私はそれを見つけることができないので、もしあなたがそれを必要とするなら、作者に手紙を書いてください、その仕事はかなり新しく、Pythonで書かれているようです。

さまざまなエラーのコスト 1つ星から5つ星のレビューを依頼するなど、ひどい誤解を避けることにもっと関心がある場合は、MSEを見てください。違いが重要であるがそれほど重要でない場合は、MAEを試してください。それ以外の場合は、精度を維持します。

指標ではなくアプローチについて

SVRなどの回帰アプローチを試してください。これらは一般に、SVCやOVA SVMなどのマルチクラス分類子よりも優れているためです。


13

まず、カウント分析だけを使用してデータが不均衡かどうかを判断するのは少し難しいです。たとえば、1000分の1の肯定的な観測は、単なるノイズ、エラー、または科学の突破口ですか?あなたは、決して知らない。
したがって、利用可能なすべての知識を使用し、賢明にそのステータスを選択することは常に優れています。

さて、それが本当にアンバランスな場合はどうなりますか?
もう一度、あなたのデータを見てください。1つまたは2つの観測値に100倍を掛けたものが見つかることがあります。この偽の1クラス観測を作成すると便利な場合があります。
すべてのデータがクリーンである場合、次のステップは予測モデルでクラスの重みを使用することです。

では、マルチクラスメトリックについてはどうでしょうか。
私の経験では、どの指標も通常は使用されていません。主な理由は2つあります。
1つ目は、確実な予測よりも常に確率で作業することです(他に、0.9と0.6の予測でモデルを分離して、両方に同じクラスが与えられる場合はどうすればよいでしょうか)。次に
、予測モデルを比較して新しいモデルを作成する方がはるかに簡単です。 1つだけの適切なメトリックに依存するもの。
私の経験から、loglossまたはMSE(または単に2乗誤差を意味する)をお勧めできます。

sklearn警告を修正する方法?
単に(yangjieが気づいたように)averageこれらの値の1つでパラメーターを上書きします:('micro'グローバルに'macro'メトリックを計算)、(各ラベルのメトリックを計算)、または'weighted'(マクロと同じですが、自動重み付け)。

f1_score(y_test, prediction, average='weighted')

すべての警告は、マルチクラス予測には不適切なデフォルトaverage'binary'でメトリック関数を呼び出した後に発生しました。
頑張って機械学習を楽しんでください!

編集:
私は同意できない回帰アプローチ(SVRなど)に切り替えるための別の回答者の推奨事項を見つけました。私が覚えている限り、マルチクラス回帰のようなものすらありません。はい、まったく異なるマルチラベル回帰があり、はい、場合によっては回帰と分類を切り替えることができます(クラスが何らかの方法で並べ替えられている場合)。

(scikit-learnの範囲で)私が推奨するのは、別の非常に強力な分類ツールを試すことです:勾配ブースティングランダムフォレスト(私のお気に入り)、KNeighborsなど。

その後、予測間の算術平均または幾何平均を計算できます。ほとんどの場合、さらに良い結果が得られます。

final_prediction = (KNNprediction * RFprediction) ** 0.5

1
>「回帰と分類を切り替えます(クラスが何らかの方法でソートされている場合)がかなりまれです」ケースは5> 4> 3> 2> 1.です。このタスクのペーパーをご覧になることをお勧めします。タスクの多くの回帰および分類アプローチ(同じ作業に含まれる場合があります)。
Nikita Astrakhantsev

次に、それはマルチクラスの分類でもなく、単純な回帰です。
Vlad Mironov、2015

はい、内部的に、またはMLの観点からは、これは回帰ですが、最後のステップで回帰結果をラベルに変換するため、ユーザーまたはアプリケーションの観点から、マルチクラス分類になります。
Nikita Astrakhantsev
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.