テストエンジニアが機械学習してみた備忘録

広島とジト目が好きなテストエンジニアが機械学習に手を出した備忘録。

モデルの評価方法とsklearn.metricsの使い方調査

3.3. Model evaluation: quantifying the quality of predictions — scikit-learn 0.19.1 documentation

scikit-learnには、作成したモデルの評価を行うモジュールとしてsklearn.metricsが搭載されています。 今回はその中から目についたものをピックアップしてみようと思います。

また、参考文献としてはじパタの3章を参照しています。

はじめてのパターン認識

はじめてのパターン認識

混同行列

sklearn.metrics.confusion_matrix — scikit-learn 0.19.1 documentation

confucion_matrix()は混同行列を作成してくれる関数です。 第1引数に正解値の配列、第2引数に予測値の配列を渡すと混同行列を得られます。 3クラス以上の場合でも対応しているようです。

特に2クラス分類の場合は、あるクラスに属するか否かを判定することと同義なので、 正解値と予測値の比較結果は以下の4パターンのいずれかとなります。

  •  TP : あるクラスに属していることを予測できた(真陽性:True Positive)
  •  FN : あるクラスに属していることを予測できなかった(偽陰性:False Negative)
  •  FP : あるクラスに属していないを予測できなかった(偽陽性:False Positive)
  •  TN : あるクラスに属していないことを予測できた(真陰性:True Negative)

confucion_matrix()では返り値の二次元行列は[[ TN,  FP], [ FN,  TP]]となるようです。  TP TNが「正しく予測できた」ということで、雑に言うといい感じの結果が得られたケースになります。 初見ではややこしいですが、「属する」と予測した結果が P、「属さない」と予測した結果が Nで、 予測結果が正しいか否かを T Fで表しているようです。

さて、これらの値を用いることで以下の評価指標が算出できるようです。

適合率、再現率、F値、正確度

混同行列に登場する値を用いることで適合率(precision)と再現率(recall)を算出できます。また、適合率と再現率の調和平均を取ったF値という評価指標があるようです。F値の英訳は恐らくF1 scoreですが、なぜ1がついているのかはよくわかってません。(F2 scoreとかあるのか…?)

適合率は \frac{TP}{TP + FP}で算出します。 あるクラスに属しているという予測結果のうち、実際にはそのクラスに属していなかったデータが多いほど、適合率は下がります。 再現率は \frac{TP}{TP + FN}で算出します。 あるクラスに属しているデータのうち、そのクラスに属していないと予測されてしまったデータが多いほど、再現率は下がります。

例えば全てのデータを「あるクラスに属している」と予測すれば、 FN = 0なので再現率は 1になりますが、  FPも大きくなるので適合率は小さくなります。このように両者はトレードオフになっているようです。

これらの値はconfucion_matrix()で取得した値から算出することももちろんできますが、 classification_report()を用いればそれだけで算出してくれるようです。 なお、この関数も3クラス以上にも対応しているようです。

また、正確度(accuracy)は \frac{TP + TN}{TP + FP + TN + FN}で算出します。 これはデータの属するクラスを正しく予測できた割合を表し、accuracy_score()で導出できるようです。

sklearn.metrics.classification_report — scikit-learn 0.19.1 documentation

sklearn.metrics.accuracy_score — scikit-learn 0.19.1 documentation

ROC、AUC

sklearn.metrics.roc_curve — scikit-learn 0.19.1 documentation

ROC曲線は識別境界を変化させた時の偽陽性率( \frac{FP}{FP+TN})と真陽性率( \frac{TP}{TP+FN})の関係を表したグラフです。言い換えると、あるクラスに属すると誤って予測した割合(偽陽性率)と、あるクラスに属すると正しく予測した割合(真陽性率)の関係を識別境界毎に示します。ROC曲線が左上にあるほど、識別機の性能は良いと判断されるそうです。

また、ROC曲線の下側の面積をAUCと呼びます。 ROC曲線が左上にいくほど識別機の性能が良いということは、 言い換えるとAUCが1に近いほど性能が良いということになります。 AUCはROCの定義上、最大値は1になるので、AUCが1に近いほど良い識別機ということになるようです。

roc_curve()は偽陽性率、真陽性率、閾値の3つを返します。 X軸に偽陽性率、Y軸に真陽性率を指定してプロットすればROC曲線になります。 AUCはroc_auc_score()で得ることができます。

まとめ

sklearn.metricsは各関数のインタフェースが統一されており、 基本的には第1引数に正解値、第2引数に予測値を入れればよいのでわかりやすいです。 当然、得られる結果を正しく解釈するにはその指標がどういうものかを知っておく必要があるのですが、 はじパタをお供にscikit-learnのドキュメントを読んでいくとイメージがつかみやすかったです。

はじパタを読むだけじゃあんまりイメージ湧かなかったのですが、 実際に手を動かしてみるとイメージが湧いてきますね。 ROCとAUCの辺りはなんとなくイメージは持てたのですが、 まだ上手く説明はできそうにないのでもうちょっと読み込む必要がありそうです。