142_Precision、Recall、F値といった評価尺度を理解し、実際の精度評価を行うことができる

解説

機械学習で回帰分析と並びよく使われる手法の一つに分類があります。
その分類問題において、結果をどのように評価すればよいでしょうか。

ここでは、分類問題の評価の説明でよくあげられる「病気の検査」を例に説明していきます。検査と結果のパターンには、以下の4種類があります。

①:検査で病気と診断され、実際に病気の場合
②:検査で病気と診断され、実際は病気でない場合
③:検査で病気ではないと診断され、実際は病気の場合
④:検査で病気ではないと診断され、実際に病気でない場合

この内容を整理すると以下の表のように表すことができます。

結果:病気 結果:病気ではない
検査:病気 ①True Positive(TP) ②False Positive(FP)
検査:病気ではない ③False Negative(FN) ④True Negative(TN)

 

この①〜④の値を用いることで、評価尺度を用いて、精度の評価を行うことができます。まずは、算出する前に、一般的によく使われる評価尺度とその説明を以下の表にまとめました。

# 評価尺度 説明
Precision
(適合率)
検査で病気と判断されて、実際に病気である割合
Recall
(再現率)
実際に病気の人が、病気と判定されるの割合
Specificity
(特異度)
病気ではない人が、病気ではないと判定される割合。
Accuracy
(正解率)
病気の有り無しを実際に正しく判定する割合
F-measure
(F値)
正確性と網羅性の総合的な評価の際に利用される尺度

 

各種評価尺度の算出方法は以下のとおりです。
1.Precision

[math]\LARGE{\frac{①TP}{①TP+②FP}}[/math]

2.Recall

[math]\LARGE{\frac{①TP}{①TP+③FN}}[/math]

3.Specificity

[math]\LARGE{\frac{④TN}{②FP+④TN}}[/math]

4.Accuracy

[math]\LARGE{\frac{①TP+④TN}{①TP+②FP+③FN+④TN}}[/math]

5.F-measure

[math]\LARGE{\ \frac{2Recall * Precision }{Recall+Precision}}[/math]

評価尺度の意味と、その算出方法を理解したところで、実際に評価尺度を算出してみます。ここでは、病院に来た100人の患者に対して医師が診断をして、結果正しく病気かどうかを診断できているかを尺度を利用して確認します。
なお、診断と実際の結果は以下のとおりとします。

結果:病気 結果:病気ではない
検査:病気 ①50 ②5
検査:病気ではない ③15 ④20

 

各評価尺度に値を代入して求めてみます。

1.Precision[math]\fallingdotseq91%[/math]

2.Recall[math]\fallingdotseq77%[/math]

3.Specificity[math]\fallingdotseq80%[/math]

4.Accuracy[math]\fallingdotseq78%[/math]

5.F-measure[math]\fallingdotseq83%[/math]

この結果から、実際に病気の人が、病気と判定される割合のRecallが低いため、診断としてはあまり評価されるものではないことが分かります。

ステップアップ

評価尺度の使い分けについて考える必要があります。例えば、病気と判定された人のうち病気の人の割合が重要である場合はPrecisionに注目すべきです。また、病気の人のうち病気と判定される人の割合が重要である場合はRecallに注目します。分類の対象にする問題に応じて、どの評価尺度を高めるべきか、あるいは下げてもよいかを定めた上で、考察したり、場合によってはプログラムのチューニングなどを行っていくことが重要です。

キーワード

  • Precision
  • Recall
  • Specificity
  • Accuracy
  • F-measure

ソースコード

rating_scales.py:評価尺度を算出するプログラム

# -*- coding: utf-8 -*-

#テストデータの作成
tp = 50
fp = 5
fn = 15
tn = 20

def calculate_rating_scales(tp,fp,fn,tn):

    # 評価尺度の算出式を定義する
    recall = float(tp)/(float(tp) + float(fn))
    specificity = float(tn)/(float(fp) + float(tn))
    accuracy = (float(tp) + float(tn))/(float(tp) + float(fp) + float(fn) + float(tn))

    if (float(tp) + float(fp)):
      precision = float(tp)/(float(tp) + float(fp))
      f1_measure = (2 * (precision * recall)) / (precision + recall)
    else:
      precision = 0
      f1_measure = 0

    # 結果を表示する
    print('Precision = ', precision)

    print('Recall = ', recall)

    print('Specificity = ', specificity)

    print('Accuracy = ', accuracy)

    print('F1 measure = ', f1_measure)

if __name__ == '__main__':
    calculate_rating_scales(tp,fp,fn,tn)

このプログラムを実行すると、各評価尺度を算出します。

('Precision = ', 0.9090909090909091)
('Recall = ', 0.7692307692307693)
('Specificity = ', 0.8)
('Accuracy = ', 0.7777777777777778)
('F1 measure = ', 0.8333333333333333)

データセット