機械学習

適合率再現率F値

適合率・再現率・F1値を、見落としと誤検知のどちらを避けたいかという運用判断から使い分けます。

  • B|標準
  • 機械学習

数式の記号で止まったら 記号の読み方 (∂・⊙・転置・上付き添字を、読み方から)

ひとことで言うと

適合率(precision)は「陽性と判定したもののうち、実際に陽性だった割合」です。再現率(recall)は「実際の陽性を、どれだけ拾えたか」です。F1値は両者を同時に高くしたいときの代表的な要約値です。どれを採用するかは、誤検知と見逃しのどちらが困るかで変わります。

迷子の捜索で考えると、再現率は「見つけるべき人を何人見つけたか」、適合率は「見つけたと報告した人のうち本当に対象だった割合」です。捜索範囲を広げれば見逃しは減りますが、誤報も増えます。

なぜ必要か

正解率だけでは、陽性が少ない現場の失敗を隠します。たとえば不正取引が全体の1%なら、すべてを正常と判定しても正解率は99%です。しかし不正を一件も見つけていないため、検知の目的には役立ちません。少数クラスを拾う仕事では、正解率と一緒に適合率・再現率を確認します。

指標は目的に合わせて選びます。誤警報の調査コストが高いなら適合率を重く見て、病気や不正の見逃しが致命的なら再現率を重く見ます。分類器が確率やスコアを返す場合、判定閾値を動かすと通常は再現率が上がる一方、適合率は上がるとは限りません。厳しい閾値では報告数が減り、適合率が改善することがありますが、拾える陽性も減ります。

困ることまず見る指標判定の方向
誤警報が多い適合率陽性判定の確かさを上げる
見逃しが多い再現率実際の陽性を広く拾う
一方だけを優先できないF1値両方の低い方に引っ張られる値で比較する

仕組み

二値分類で、TPを正しく陽性とした件数、FPを誤って陽性とした件数、FNを見逃した陽性の件数とします。ここでは陽性クラスを評価対象に固定します。

precision=TPTP+FP,recall=TPTP+FN\mathrm{precision}=\frac{\mathrm{TP}}{\mathrm{TP}+\mathrm{FP}},\qquad \mathrm{recall}=\frac{\mathrm{TP}}{\mathrm{TP}+\mathrm{FN}}

適合率の分母は「陽性と予測した総数」、再現率の分母は「実際の陽性の総数」です。同じTPを使っていても分母が違うので、数値が異なります。F1値は適合率 PP と再現率 RR の調和平均です。

F1=2PRP+RF_1=\frac{2PR}{P+R}

調和平均は、片方だけが高いケースを厳しく評価します。適合率0.9、再現率0.1なら、算術平均は0.5ですが、F1値はおよそ0.18です。これは「見逃しを大量に残したモデルを、適合率の高さだけで良く見せない」という意図に合います。なお、両方を同じ重みで扱うのがF1で、再現率をより重くしたい場合はF値のベータを変えます。

試験でどう問われるか

問われ方正解に寄る条件引っかけ
分母を選ぶ適合率は予測陽性、再現率は実陽性が分母TPが共通だから式も同じとする
用途から指標を選ぶ見逃しを避けるなら再現率、誤警報を避けるなら適合率常にF1が最適だと決める
閾値変更の影響低い閾値では再現率が上がりやすく、適合率はデータ次第両方が必ず単調に上がるとする
不均衡データを評価する少数陽性を拾えているかを適合率・再現率で見る高い正解率だけで十分とする

実装で確かめる

予測確率を閾値で二値化し、同じデータから3指標を計算します。pos_label に相当する陽性を1と決めておくことが、ライブラリ利用時にも重要です。

import numpy as np

y_true = np.array([1, 1, 1, 0, 0, 0])
score = np.array([0.95, 0.60, 0.40, 0.55, 0.30, 0.10])
threshold = 0.50
y_pred = score >= threshold
tp = np.sum((y_true == 1) & y_pred)
fp = np.sum((y_true == 0) & y_pred)
fn = np.sum((y_true == 1) & ~y_pred)
precision = tp / (tp + fp)
recall = tp / (tp + fn)
f1 = 2 * precision * recall / (precision + recall)
print(precision, recall, f1)

この例の出力は 0.6666666666666666 0.6666666666666666 0.6666666666666666 です。閾値を0.3へ下げると、陰性をさらに陽性判定するため、再現率は1.0に上がる一方、適合率は下がります。閾値は指標の後付け設定ではなく、運用上の誤検知・見逃しの費用と一緒に決めます。

取り違えやすいもの

指標・概念適合率・再現率・F1との違い
正解率全サンプル中の正解割合。陽性が少ないと多数派の正解だけで高くなる
適合率予測陽性を基準にした指標。FPが増えると下がる
再現率実陽性を基準にした指標。FNが増えると下がる
F1値適合率と再現率を一つにまとめるが、誤検知と見逃しの費用そのものではない

scikit-learnの classification_report はクラスごとの適合率・再現率・F1値と support(正解データ中の各クラスの件数)をまとめます。二値分類でも、どちらを陽性クラスとして報告したかを確認しないと、同じ予測から別の結論になります。ゼロ件の予測陽性などで分母が0になる場合は、実装の zero_division 設定も確認します。

想起チェック

適合率と再現率で分母が違うのはなぜか

適合率は予測陽性の確かさ、再現率は実陽性の捕捉率だからです。前者の分母はTP+FP、後者の分母はTP+FNです。

F1値が算術平均ではなく調和平均なのはなぜか

片方だけが高いモデルを高く評価しないためです。適合率と再現率の両方が高いときにだけ、F1値も高くなります。

不均衡データで正解率だけを見ると何を見落とすか

多数派を常に予測するだけで高い値になり、少数派の見逃しや誤検知を評価できません。少数陽性を扱う目的なら適合率と再現率を併記します。

出典