ひとことで言うと
適合率(precision)は「陽性と判定したもののうち、実際に陽性だった割合」です。再現率(recall)は「実際の陽性を、どれだけ拾えたか」です。F1値は両者を同時に高くしたいときの代表的な要約値です。どれを採用するかは、誤検知と見逃しのどちらが困るかで変わります。
迷子の捜索で考えると、再現率は「見つけるべき人を何人見つけたか」、適合率は「見つけたと報告した人のうち本当に対象だった割合」です。捜索範囲を広げれば見逃しは減りますが、誤報も増えます。
なぜ必要か
正解率だけでは、陽性が少ない現場の失敗を隠します。たとえば不正取引が全体の1%なら、すべてを正常と判定しても正解率は99%です。しかし不正を一件も見つけていないため、検知の目的には役立ちません。少数クラスを拾う仕事では、正解率と一緒に適合率・再現率を確認します。
指標は目的に合わせて選びます。誤警報の調査コストが高いなら適合率を重く見て、病気や不正の見逃しが致命的なら再現率を重く見ます。分類器が確率やスコアを返す場合、判定閾値を動かすと通常は再現率が上がる一方、適合率は上がるとは限りません。厳しい閾値では報告数が減り、適合率が改善することがありますが、拾える陽性も減ります。
| 困ること | まず見る指標 | 判定の方向 |
|---|---|---|
| 誤警報が多い | 適合率 | 陽性判定の確かさを上げる |
| 見逃しが多い | 再現率 | 実際の陽性を広く拾う |
| 一方だけを優先できない | F1値 | 両方の低い方に引っ張られる値で比較する |
仕組み
二値分類で、TPを正しく陽性とした件数、FPを誤って陽性とした件数、FNを見逃した陽性の件数とします。ここでは陽性クラスを評価対象に固定します。
適合率の分母は「陽性と予測した総数」、再現率の分母は「実際の陽性の総数」です。同じTPを使っていても分母が違うので、数値が異なります。F1値は適合率 と再現率 の調和平均です。
調和平均は、片方だけが高いケースを厳しく評価します。適合率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値も高くなります。
不均衡データで正解率だけを見ると何を見落とすか
多数派を常に予測するだけで高い値になり、少数派の見逃しや誤検知を評価できません。少数陽性を扱う目的なら適合率と再現率を併記します。