scikitのマルチラベル分類メトリック


19

scikitを使用して既存のドキュメントにトピックを割り当てるために、マルチラベル分類子を構築しようとしています

私は、を介してそれらを渡す私の文書を処理していTfidfVectorizerて、ラベルMultiLabelBinarizerと作成したOneVsRestClassifierSGDClassifier推定として。

しかし、分類子をテストするとき、私は0.29までのスコアしか得ません。これは、私が読んだものから同様の問題に対してかなり低いです。TfidfVectorizerでストップワード、ユニグラム、ステミングなどの複数のオプションを試しましたが、何もそれほど結果を変えないようです。

またGridSearchCV、推定器に最適なパラメーターを取得するために使用していましたが、現在、次に何をしようかというアイデアがありません。

同時に、私が使用できないことを理解scikit.metricsしているOneVsRestClassifierので、何が間違っているのかを理解するために、どのようにいくつかのメトリック(F1、Precision、Recallなど)を取得できますか?

データコーパスに問題があるのでしょうか?

更新:とを使用CountVectorizerHashingVectorizerてパイプライン処理も試みましたTfidfTransformerが、結果は似ています。だから私は、word-of-wordsアプローチがトークン化ドメインで最善であり、残りは分類器次第だと推測しています...


1
0.29測定とは何ですか?正確さ?他に何か?
Sycoraxが復活モニカ言う

@GeneralAbrialはscikitのドキュメントによると、実行中のscore分類器に、Returns the mean accuracy on the given test data and labels. In multi-label classification, this is the subset accuracy which is a harsh metric since you require for each sample that each label set be correctly predicted.
メビウス

それはあなたがやったことですか?あなたの質問からこれが事実であるかどうかはまったく明らかではないので、完全に合理的な質問です。
Sycoraxが復活モニカ言う

@GeneralAbrialはい、これは私がやったことです。混乱して申し訳ありませんが、私は質問を開発モードではなく、より理論的なモードにしようとしていました。
メビウス

ここにコードを追加していただけますか?具体的には、SGDにsample_weight = "balanced"を使用していますか?ただし、コードを確認したら、他に注意すべきことがあるかもしれません。
ディエゴ

回答:


21

サブセットの精度は確かに厳しいメトリックです。0.29がどれだけ良いか悪いかの感覚をつかむために、いくつかのアイデアがあります:

  • 各サンプルの平均ラベル数を調べます
  • 可能な場合は、アノテーター間の合意を確認します(利用できない場合は、分類者であるときにどのサブセットの精度が得られたかを確認してください)
  • トピックが明確に定義されているかどうかを考える
  • 各ラベルにいくつのサンプルがあるかを見てください

また、ハミングスコアを計算して、分類器が無知であるかどうかを確認することもできます。以下を参照して、ハミングスコアを計算してください。

同時に、理解したことから、scikit.metricsをOneVsRestClassifierで使用できないので、何が間違っているかを把握するために、どのようにいくつかのメトリック(F1、Precision、Recallなど)を取得できますか?

マルチクラス-マルチラベル分類の精度/リコールの計算方法を参照してください。私はsklearnがそれをサポートしているかどうか忘れていました。例えば、sklearnは混同行列のマルチラベルをサポートしていません。これらの数字を実際に見るのは良い考えです。


ハミングスコア

マルチラベル分類設定、sklearn.metrics.accuracy_scoreのみ計算サブセット精度すなわち正確y_trueのラベルの対応するセットと一致している必要があり、試料について予測ラベルのセット:(3)。

精度を計算するこの方法は、正確な一致率(1)である可能性があります。

ここに画像の説明を入力してください

精度を計算する別の典型的な方法は、(1)および(2)で定義され、ハミングスコア(4)(ハミング損失と密接に関連しているため)、またはラベルベースの精度とあまり曖昧に呼ばれません。次のように計算されます。

ここに画像の説明を入力してください

ハミングスコアを計算するPythonメソッドは次のとおりです。

# Code by /programming//users/1953100/william
# Source: /programming//a/32239764/395857
# License: cc by-sa 3.0 with attribution required

import numpy as np

y_true = np.array([[0,1,0],
                   [0,1,1],
                   [1,0,1],
                   [0,0,1]])

y_pred = np.array([[0,1,1],
                   [0,1,1],
                   [0,1,0],
                   [0,0,0]])

def hamming_score(y_true, y_pred, normalize=True, sample_weight=None):
    '''
    Compute the Hamming score (a.k.a. label-based accuracy) for the multi-label case
    /programming//q/32239577/395857
    '''
    acc_list = []
    for i in range(y_true.shape[0]):
        set_true = set( np.where(y_true[i])[0] )
        set_pred = set( np.where(y_pred[i])[0] )
        #print('\nset_true: {0}'.format(set_true))
        #print('set_pred: {0}'.format(set_pred))
        tmp_a = None
        if len(set_true) == 0 and len(set_pred) == 0:
            tmp_a = 1
        else:
            tmp_a = len(set_true.intersection(set_pred))/\
                    float( len(set_true.union(set_pred)) )
        #print('tmp_a: {0}'.format(tmp_a))
        acc_list.append(tmp_a)
    return np.mean(acc_list)

if __name__ == "__main__":
    print('Hamming score: {0}'.format(hamming_score(y_true, y_pred))) # 0.375 (= (0.5+1+0+0)/4)

    # For comparison sake:
    import sklearn.metrics

    # Subset accuracy
    # 0.25 (= 0+1+0+0 / 4) --> 1 if the prediction for one sample fully matches the gold. 0 otherwise.
    print('Subset accuracy: {0}'.format(sklearn.metrics.accuracy_score(y_true, y_pred, normalize=True, sample_weight=None)))

    # Hamming loss (smaller is better)
    # $$ \text{HammingLoss}(x_i, y_i) = \frac{1}{|D|} \sum_{i=1}^{|D|} \frac{xor(x_i, y_i)}{|L|}, $$
    # where
    #  - \\(|D|\\) is the number of samples  
    #  - \\(|L|\\) is the number of labels  
    #  - \\(y_i\\) is the ground truth  
    #  - \\(x_i\\)  is the prediction.  
    # 0.416666666667 (= (1+0+3+1) / (3*4) )
    print('Hamming loss: {0}'.format(sklearn.metrics.hamming_loss(y_true, y_pred))) 

出力:

Hamming score: 0.375
Subset accuracy: 0.25
Hamming loss: 0.416666666667

(1)Sorower、Mohammad S.「マルチラベル学習のためのアルゴリズムに関する文献調査。」オレゴン州立大学、コーバリス(2010)。

(2)Tsoumakas、Grigorios、およびIoannis Katakis。「マルチラベル分類:概要。」ギリシャ、テッサロニキのアリストテレ大学、情報学部(2006)。

(3)Ghamrawi、Nadia、およびAndrew McCallum。「集合的なマルチラベル分類。」情報および知識管理に関する第14回ACM国際会議の議事録。ACM、2005。

(4)Godbole、Shantanu、およびSunita Sarawagi。「マルチラベル分類の識別方法。」知識発見とデータマイニングの進歩。スプリンガーベルリンハイデルベルク、2004年。


素晴らしい答え、それはちょうど私を良くしました:)私はそれをより徹底的に読んで、ハミングスコアを試して、あなたに戻ります!
メビウス

正直に言うと、サブセットの正確性(完全一致率)が正確に何であるかは完全にはわかりません。もう少し説明してもらえますか?マルチクラスの場合、これはリコールと同じようです。
Poete Maudit

このhamming_score関数はKerasでエラーになります:<ipython-input-34-16066d66dfdd> in hamming_score(y_true、y_pred、normalize、sample_weight)60 '' '61 acc_list = [] ---> 62 for i in range(y_true.shape [ 0]):63 set_true = set(np.where(y_true [i])[0])64 set_pred = set(np.where(y_pred [i])[0])TypeError:インデックスが非整数を返しました(タイプNoneType )
rjurney

0

0.29スコアでは十分ではありませんか?混同マトリックスはどのように見えますか?単語の内容だけを見ても区別できないトピックはありますか?

そうでない場合は、問題を回避してみてください。低スコアが実際に分類器がデータに対して実行できる最高の仮説であるという仮説を立てます。つまり、このアプローチを使用してドキュメントを分類することはできません。

この仮説をテストするには、既知のbag-of-word特性を備えた一連のテスト文書が必要です(自分で作成します)。100%のスコアを取得する必要があります。

そうでない場合は、バグがあります。それ以外の場合は、ドキュメントを分類するための別のアプローチが必要です。自問してください:異なるクラスのドキュメントはどのように異なるのですか?文書のその他の機能などを調べる必要がありますか


数値とは別に、0.29は低いと感じています。トレーニング済みのモデルを使用して、トレーニングで既に使用したドキュメントのトピックを予測し、分類子を手動でテストします。ユーザーがドキュメントに手動で入力したトピックと少なくとも同じ数のトピックを取得できませんでした。通常、それらのサブセットのみを取得します。また、混同行列の質問に関して、私はscikit.metricsを使用してOneVsRestClassifier上の混同行列を得ることができるとは思わない...私はかかわらず、それをチェックアウトします
メビウス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.