scikit-learnを用いた機械学習の初歩③~モデルの評価(追記)~

はじめに

前回の記事scikit-learnを用いた機械学習の初歩②~機械学習モデルの構築・評価~ではモデルの評価を次のようにしていました。
x_pred =knn.predict(X_test)#テストデータを学習モデルにセット
x_judge = x_pred == x_test #予測したデータと答えが一致しているか
true_count = len(np.where(x_judge==True)[0])#正解した数
print(x_judge)
print(true_count/len(x_judge))#正答率
調べてみるとscikit-learn内にaccuracy_scoreやclassification_reportと呼ばれる評価関数があったので、それらを使ってみました。

accuracy_scoreの使い方

これを使うことで正解率や正解数を見ることが出来ます。

from sklearn.metrics import accuracy_score
accuracy_score(y_true, y_pred, normalize=True, sample_weight=None)

y_true正解ラベル
y_pred予測した結果
normalizaTrueにすると正解率
Falseにすると正解数が表示
(デフォルト:True)
実際に前回使ったx_test、x_predを表示させてみます。

print(x_test)
print(x_pred)
print (accuracy_score(x_test, x_pred))
print (accuracy_score(x_test, x_pred,normalize=False))
図1:accuracy_score実行結果
図1を見てみると、一か所だけ2の所を1と予測しています。なので、正解率としては96.7%、正解数は29個となっています。

classification_reportの使い方

この関数を使うことでPrecision、Recall、F値、support(正解ラベルのデータの数)が分かります。



from sklearn.metrics import classification_report
classification_report(y_true, y_pred, labels=None, target_names=None, sample_weight=None, digits=2)

y_true正解ラベル
y_pred予測した結果
target_names分類するデータ名
(デフォルト:None)

Precision、Recall、F値について

Precision、Recall、F値について分からなかったので、下記のサイトを参考にしました。
Precision、Recall、F値について説明する際に以下の表を用います。


真の結果
予想結果
TPFP
FNTN

ここでTPはTrue Positive(予想が正(Positive)で結果と一致(True))、FPはFalse Positive(予想が正で不一致(False))、FNはFalse Negative(予想が負(Negative)で結果と不一致)、TNはTrue Negativi(予想が負で正解と一致)の略みたいです。

上記の表を用いてそれぞれ次のように表すことが出来ます。

Precision

\begin{equation} Precision = \frac{TP}{TP+FP} \end{equation} 
式を見てわかる通り予想結果が正の場合に対する正解率を表しています。

本の落丁を例として説明すると、この値が大きいということは、本当は落丁している本なのに、正しく製本できていると判断された数(FP)が少ないということになります。

この評価指標はFN(正しく製本できているのに、落丁していると判断)よりFP(落丁しているのに、正しく製本できていると判断)があっては困る場合に重要視します。

本の例では、落丁しているものが正しく製本できていると判断されると、お客様からクレームが来てしまうので、このPrecisionを重要視します。言い換えると正確性を重要視する指標です。また、後述するRecallとはトレードオフの関係性があります。

Recall

\begin{equation} Recall = \frac{TP}{TP+FN} \end{equation}
こちらは真の結果が正の場合に対する正解率を表しています

病気を例として説明すると、この値が大きいということは本当は病気なのに、健康と診断された数(FN)が少ないということになります。この評価指標はFP(病気じゃないのに病気であると診断)よりFN(病気であるのに、病気でないと診断)があっては困る場合に重要視します。

病気の例では、病気であるのに病気で無いと診断されるのは問題なので、このRecallを重要視します。言い換えると網羅性を重要視する指標です。

F値

\begin{equation} F-measure = \frac{2 \cdot Recall \cdot Recall}{Recall + Precision} \end{equation}
PrecisionとRecallがトレードオフの関係あるため、F値は
適合率と再現率の調和平均としています。なぜ調和平均としているかは、分からなかったので、調べてみます。

ちなみに上記の表を用いて正解率は次のように表すことが出来ます。
\begin{equation} Accuracy = \frac{TP + TN}{TP + FP + PN + TN} \end{equation}
個人的には正解率だけの評価でいいのではないかと思っていたのですが、
いまさら聞けない機械学習の評価関数を読んで、正解率だけで評価した場合の問題点が何となく理解できました。すべてのデータを負と評価するモデルに対して、正解ラベルがすべて負だったら精度が100%のモデルと評価することが出来ます。しかし、このモデルに正解ラベルがすべて正のデータを入力すると一気に精度が悪くなってしまいます。なので、他の評価指標が必要みたいです。

(補足)TP、FP、FN、TNについてのわかりやすい画像

TP、FP、FN、TNについてのわかりやすい画像を見つけたので、紹介します。

https://medium.com/@neeraj.kumar.iitg/statistical-performance-measures-12bad66694b7
初めて知ったのですが、FPのことをType1エラーやαエラーといい、FNのことをType2エラーやβエラーというみたいです。

classification_report実行結果

少し前置きが長くなってしまいましたが、classification_reportを使ったところ次のようになりました。
print(x_test)
print(x_pred)
print (classification_report(x_test, x_pred,target_names=iris_dataset["target_names"]))


図2:classification_report実行結果

今度の例では2か所で間違えています(本来は1なのに2と予想)。
setosa(0番)はすべて一致していることが分かります。

verisicolor(1番)のrecallが1より小さく、0.83となっています。すなわち本当はversicolorなのに違うものと診断されることが多いということが分かります。実際に数えてみるとTP(予想が1で結果も1である個数)は10個、FN(予想は1以外で、結果が1となる個数)
は2個なので、(2)式に当てはめると0.83となります。

また、virginica(2番)はprecisionが1より小さくなっています。すなわち本当はvirginicaではないのにvirginicaと診断されることが多いということが分かります。
実際に数えてみるとTP(予想が2で結果も2である個数)は7個で、FP(予想は2なのに、結果は2以外である個数)は2個なので、(1)式に当てはめると0.78となります。

まとめ

scikit-learn内にaccuracy_scoreやclassification_reportと呼ばれる評価関数を使って、モデルの評価を行いました。また、Recall、Precision、F値の違いについて紹介しました。

0 件のコメント :

コメントを投稿