web-dev-qa-db-ja.com

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

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

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

1190 instances5というラベルが付けられているので、私のデータは不均衡です。シキットの SVC を使った分類Imの場合。問題は、マルチクラスの場合の精度、再現率、精度、およびF1スコアを正確に計算するために、データを正しい方法でバランスを取る方法がわからないことです。そこで私は以下のアプローチを試しました:

最初:

    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"

分類子のメトリックを正しい方法で計算するために、不均衡データを正しく処理するにはどうすればよいですか。

93
new_with_python

どの重みを何に使用するかについては、多くの混乱があると思います。何があなたを悩ませているのか正確にはわからないので、さまざまなトピックを取り上げます。

クラスの重み

class_weightパラメータからの重みは、分類器の学習に使用されます。それらは使用しているメトリックの計算には使用されません:クラスの重みが異なると、単に分類子が異なるという理由だけで数値が異なります。

基本的にどのscikit-learn分類子でも、クラスの重みはモデルがクラスの重要性を示すために使用されます。これは、トレーニング中に、分類器がクラスを高い重みで正しく分類するための追加の努力をすることを意味します。
それらがどのようにするかは、アルゴリズムによって異なります。 SVCでどのように機能するかについての詳細が必要で、その文書が意味をなさない場合は、気軽に言及してください。

メトリクス

分類器を入手したら、それがどの程度うまく機能しているかを知りたいと思います。ここで、あなたが言及したメトリックスを使用することができます:accuracyrecall_scoref1_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スコア、再現率、および精度を使用しているため、この警告が表示されます。質問は言い換えることができます:上記の分類レポートから、あなたはどう出力しますかone f1-スコアのための世界的な番号ですか?あなたは出来る:

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

これらはscikit-learnのオプションの3つです、警告はあなたを言うためにそこにあります1つを選ばなければなりません。そのため、スコアメソッドにはaverage引数を指定する必要があります。

どちらを選択するかは、分類子のパフォーマンスを測定する方法によって異なります。たとえば、マクロ平均化ではクラスの不均衡は考慮されず、クラス1のf1スコアはクラスのf1スコアと同じくらい重要になります。 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"))    

お役に立てれば。

133
ldirer

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

  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)よりも低い場合は、不均衡データが実際には問題であることがわかります。このスレッドの他のいくつかの回答で説明されています。ただし、予測したいデータに同じクラス分布が存在する場合、アンバランストレーニングデータはデータをよく表しているので、アンバランスは良いことです。

62
wonderkid2

提起された質問

「不均衡なデータを含む多クラス分類にはどのメトリックを使用すべきか」という質問への回答:マクロF1メジャー。 Macro PrecisionとMacro Recallも使用できますが、バイナリ分類の場合ほど簡単には解釈できず、すでにF-measureに組み込まれているため、過剰なメトリックはメソッドの比較やパラメータの調整などを複雑にします。

マイクロアベレージングは​​クラスの不均衡に敏感です。たとえば、自分の方法が最も一般的なラベルに適していて、他のラベルとまったく一致しない場合、マイクロアベレージングメトリックは良い結果を示します。

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

Sokolova、Marina、そしてGuy Lapalme。 「分類作業のための業績指標の系統的分析」情報処理及び管理45.4(2009):427−437。

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

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

  1. 特定のタスクに一般的に使用される測定基準 - (a)自分の方法を他のユーザーと比較して何か問題があるかどうかを理解すること、および(b)これを自分で調べずに他人の発見を再利用すること
  2. たとえば、アプリケーションのユースケースが4つ星および5つ星のレビューだけに頼っている場合など、メソッドのさまざまなエラーによるコストは、この2つのラベルのみを考慮に入れる必要があります。

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

  1. 精度。に

Yu、4月、Daryl Chang。 「Yelpビジネスを使用したマルチクラス感情の予測」

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

パン、ボー、そしてリリアン・リー。 「星を見ること:評価尺度に関して感情分類のためにクラス関係を利用すること。」第43回計算言語学連合学会年会予稿集計算言語学協会、2005年。

リンク

  1. MSE(または、まれに、平均絶対誤差 - MAE) - 例えば、

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

link ) - 精度とMSEの両方を検討します。後者の方が良いと考えます

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

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

さまざまなエラーのコスト あなたがグロスブランを避けることをもっと気にかけているなら、例えば1つ星から5つ星へのレビュー、またはそのようなものを割り当てている、MSEを見てください。違いが問題になる場合は、それほど重要ではないが、MAEを試してみてください。これは差分の平方ではありません。それ以外の場合は正確さを保ちます。

メトリクスではなくアプローチについて

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

15

まず第一に、あなたのデータが不均衡かどうかを見分けるために単にカウント分析を使うのは少し難しいです。例:1000年に1回の積極的な観測は、単なるノイズ、エラー、または科学の進歩です。あなたは、決して知らない。
したがって、利用可能なすべての知識を使用し、その状況を賢明に選択することをお勧めします。

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

では、マルチクラスメトリックスはどうでしょうか?
私の経験では、あなたの測定基準は通常使われていません。主な理由は2つあります。
最初:確実な予測よりも確率で作業するほうが常に良いです(0.9と0.6の予測でモデルが同じクラスを与えている場合、他の方法でモデルを分離する方法は他にありますか?)
そして次に、予測モデルを比較し、1つの優れた測定基準のみに基づいて新しい予測モデルを作成する方がはるかに簡単です。
私の経験から、 logloss または MSE (または単に二乗平均誤差)をお勧めします。

スクラーン警告を修正するにはどうすればいいですか?
(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
12
Vlad Mironov