web-dev-qa-db-ja.com

Scikitlearnエラーメッセージ '適合率とFスコアが明確に定義されておらず、ラベルで0.0に設定されています'

二項分類モデルに取り組んでいる私は、分類器は単純ベイズです。ほぼバランスの取れたデータセットがありますが、予測すると次のエラーメッセージが表示されます。

UndefinedMetricWarning: Precision and F-score are ill-defined and being set to 0.0 in labels with no predicted samples.
  'precision', 'predicted', average, warn_for)

CV k-fold 10でgridsearchを使用しています。テストセットと予測には両方のクラスが含まれているため、メッセージがわかりません。私は同じデータセット、トレーニング/テスト分割、cv、および他の6つのモデルのランダムシードに取り組んでおり、それらは完璧に機能します。データは外部からデータフレームに取り込まれ、ランダム化され、シードが修正されます。次に、単純ベイズ分類モデルは、このコードスニペットの前の先頭でファイルを分類します。

X_train, X_test, y_train, y_test, len_train, len_test = \
     train_test_split(data['X'], data['y'], data['len'], test_size=0.4)
pipeline = Pipeline([
    ('classifier', MultinomialNB()) 
])

cv=StratifiedKFold(len_train, n_folds=10)

len_train = len_train.reshape(-1,1)
len_test = len_test.reshape(-1,1)

params = [
  {'classifier__alpha': [0, 0.0001, 0.001, 0.01]}

]

grid = GridSearchCV(
    pipeline,
    param_grid=params,
    refit=True,  
    n_jobs=-1, 
    scoring='accuracy',
    cv=cv, 
)

nb_fit = grid.fit(len_train, y_train)

preds = nb_fit.predict(len_test)

print(confusion_matrix(y_test, preds, labels=['1','0']))
print(classification_report(y_test, preds))

私はpythonによってシリーズの形を変更するように強制されました、多分それが原因ですか?

8
OAK

警告の意味

ここでの他の回答が示唆しているように、適合率F-Scoreは、その定義(適合率/再現率が0に等しい)のために計算できない状況に遭遇します。この場合、メトリックのスコアは0で評価されます。

テストデータにはすべてのラベルが含まれていますが、なぜこれがまだ発生するのですか?

さて、あなたはK-Fold(特にあなたの場合はk=10)を使用しています。これは、1つの特定の分割に1つのクラスの0サンプルが含まれる可能性があることを意味します

層化Kフォールドを使用している場合でも発生します

これは少し注意が必要です。層化Kフォールドは、各分割で各クラスの同じ部分を保証します。ただし、これは実際のクラスに依存するだけではありません。たとえば、Precisionは次のように計算されます:TP/predicted yes。何らかの理由で、すべてのサンプルをNoで予測している場合、predicted yes=0があり、精度が定義されていません(未定義のF-Scoreにつながる可能性があります)。

これはエッジの場合のように聞こえますが、グリッド検索では、おそらく完全にずれている可能性のあるさまざまな組み合わせを多数検索しているため、このようなシナリオが発生する可能性があることを考慮してください。

これがあなたの質問に答えることを願っています!

6
Ori

Aadelがコメントしているように、正として分類されるデータポイントがない場合、精度はTP /(TP + FP)として定義されるため、ゼロで除算されます(つまり、真の正/真と偽)ポジティブ)。次に、ライブラリは精度を0に設定しますが、実際には値が未定義であるため、警告を発行します。 F1は精度に依存するため、定義されていません。

これに気付いたら、次の方法で警告を無効にすることを選択できます。

import warnings
import sklearn.exceptions
warnings.filterwarnings("ignore", category=sklearn.exceptions.UndefinedMetricWarning)
5
user1544337