sklearnのclassification_reportをよく使うのだが、一つハマったことがあったのでメモ。
classification_reportとは
以下sklearnの公式ドキュメントからの抜粋ですが、簡単に言うと予測ラベルと正解ラベルからprecision,recall,f1-scoreを算出しまとめてくれる機能です。
from sklearn.metrics import classification_report
y_true = [0, 1, 2, 2, 2]
y_pred = [0, 0, 2, 2, 1]
target_names = ['class 0', 'class 1', 'class 2']
print(classification_report(y_true, y_pred, target_names=target_names))
この場合の結果は以下になる。
precision recall f1-score support
class 0 0.50 1.00 0.67 1
class 1 0.00 0.00 0.00 1
class 2 1.00 0.67 0.80 3
avg / total 0.70 0.60 0.61 5
ハマったこと
実際作成したモデルに対して一部のテストデータを使って検証する場合、ラベルが『綺麗に』揃っていない場合がある。
以下のようなケースです。
from sklearn.metrics import classification_report
y_true = [1, 1, 2, 1, 1]
y_pred = [2, 2, 2, 2, 2]
target_names = ['class 0', 'class 1', 'class 2']
print(classification_report(y_true, y_pred, target_names=target_names))
この場合の結果は以下のようになる。
precision recall f1-score support
class 0 0.00 0.00 0.00 4
class 1 0.20 1.00 0.33 1
avg / total 0.04 0.20 0.07 5
class 1・・・・・・ ラベルが2なのでclass 2となるはずだが、class 1となってしまい、target_namesで定義したものと合わなくなってしまう。
また、以下のような警告が表示される。
UserWarning: labels size, 2, does not match size of target_names, 3
解決策
以下のように、あらかじめclassification_reportの引数labels=にラベルとなる数字のリストを用意しておく。この場合は実際、labels=[0,1,2]が入っている。
from sklearn.metrics import classification_report
import numpy as np
y_true = [1, 1, 2, 1, 1]
y_pred = [2, 2, 2, 2, 2]
target_names = ['class 0', 'class 1', 'class 2']
print(classification_report(y_true, y_pred, labels = np.arange(len(target_names)),target_names=target_names))
結果は
precision recall f1-score support
class 0 0.00 0.00 0.00 0
class 1 0.00 0.00 0.00 4
class 2 0.20 1.00 0.33 1
avg / total 0.04 0.20 0.07 5
直りました。