適合率(Precision)と
再現率(Recall)
分類モデルを作ると、必ず「どれくらい当たっているか」を1つの数字で聞かれます。ところが正解率(Accuracy)だけでは、スパム判定・不正検知・解約予測のように陽性が数%しかない問題の実態を取り違えます。全件を「陰性」と答えるだけで正解率が95%を超えてしまうからです。
そこで使うのが適合率(Precision)と再現率(Recall)です。この2つは同じモデルのしきい値を動かして押し引きできる一組の指標で、切り離して眺めても判断材料になりません。本記事では、スコアの計算手順から運用への載せ方までを実数の例で追いかけます。
適合率と再現率は、採用する指標を選ぶ話に見えて、実際にはスコアを何点以上で陽性と扱うかを決める話です。しきい値が決まれば、2つの値は自動的に決まります。そのしきい値は、1件見逃したときの損失と1件空振りしたときの損失を比べて逆算するのが基本です。両者の重みが決められないときの出発点としてF1スコアが、見逃しを重く見たいときはF2(Fβのβ=2)が使えます。
- 適合率(Precision):陽性と予測したもののうち、実際に陽性だった割合。空振りの少なさを表す。医療では陽性的中率とも呼ぶ。
- 再現率(Recall):実際の陽性のうち、拾えた割合。見逃しの少なさを表す。感度(Sensitivity)・真陽性率も同義。
- しきい値(閾値):モデルが出すスコアの何点以上を陽性と扱うかの境目。既定の0.5は初期値にすぎない。
- F1スコア・Fβ:適合率と再現率の重み付き調和平均。βが大きいほど再現率を重く見る。
01.適合率と再現率の違い|同じ分子を違う分母で割る指標
ベン図で見る分子と分母
適合率と再現率が別々の指標に見えるのは、分子が同じで分母だけが違うことが見えていないからです。分子はどちらも「正しく陽性と当てた件数(真陽性)」で、適合率はそれを陽性と予測した件数で割り、再現率は実際に陽性だった件数で割ります。問い合わせのスパム判定を例に、実際のスパムと、モデルがスパムと判定したものを2つの円で重ねると、違いが一目で分かります。
図:ベン図で見る適合率と再現率|重なりの32件を、どちらの円で割るか
問い合わせ1,000件(うち実際のスパム50件)にスパム判定モデルをかけた例。外枠が全1,000件、青の円が実際のスパム、オレンジの円がスパムと判定されたもの。円の大きさと重なり方は模式的で、面積は件数に比例していない。
適合率(Precision)=重なり ÷ オレンジの円
32 ÷ 40 = 0.80。スパムと判定した40件のうち、本当にスパムだった割合。
再現率(Recall)=重なり ÷ 青の円
32 ÷ 50 = 0.64。実際のスパム50件のうち、モデルが見つけた割合。
図の重なりが、2つの指標に共通する分子です。オレンジの円で割れば適合率、青の円で割れば再現率になります。オレンジの円のうち青の円と重ならない部分が空振り、青の円のうちオレンジの円と重ならない部分が見逃しです。適合率は空振りが減るほど、再現率は見逃しが減るほど1.0に近づきます。scikit-learn の評価指標ドキュメントでは、適合率は陰性のサンプルを陽性と判定しない能力、再現率は陽性のサンプルをすべて見つけ出す能力として説明されています。
取り違えないための覚え方
名前が似ていて取り違えやすい2つですが、誰の問いに答える指標かで分けると覚えやすくなります。
図:取り違えないための覚え方|それぞれが答える問い
スパム判定の例で、2つの指標が答える問いを並べた。分子はどちらも真陽性(ベン図の重なり)で、誰の立場から見るかによって分母が変わる。
適合率(Precision)
「スパムと判定されたものは、本当にスパム?」
- 誰の問いか
- 判定結果を受け取って対応する人。判定を信じてよいかを知りたい
- 分母
- モデルが陽性と判定した件数(予測側・ベン図のオレンジの円)
- 低いと起きること
- 空振り(誤検知)が増え、判定そのものが信用されなくなる
再現率(Recall)
「実際のスパムを、どれだけ見つけられた?」
- 誰の問いか
- 見逃しを防ぎたい人。拾うべきものを拾えたかを知りたい
- 分母
- 実際に陽性だった件数(実際側・ベン図の青の円)
- 低いと起きること
- 見逃しが増え、拾うべきものが素通りする
英語の意味から覚える方法もあります。Precision(プレシジョン)は「的確さ」で、陽性と言い切ったときに外さないかを表します。Recall(リコール)は「呼び戻す」という意味で、製品のリコール(回収)に重ねると覚えやすくなります。市場に出た対象品のうち何割を回収できたか、という考え方は再現率とそのまま重なります。漢字から読むなら、適合率は「予測が実際に適合していた割合」、再現率は「実際の陽性を再現できた割合」です。
しきい値による2つの指標の押し引き
2つの指標の関係は、この分母の違いから決まります。しきい値を下げて陽性と判定する件数を増やすと、実際の陽性を拾える数が増えて再現率は上がります。ただし空振りも同時に増えるため、適合率は下がりやすくなります。だからこそ、どちらか一方だけを100%に近づけても意味がありません。全件を陽性と判定すれば再現率は1.0になりますし、最も自信のある1件だけを陽性と判定すれば適合率は1.0に近づくからです。
しきい値ごとの適合率と再現率の組を、横軸に再現率、縦軸に適合率を取って結んだ線をPR曲線と呼びます。しきい値を動かしても、点はこの曲線の上を移動するだけです。下げた範囲がたまたま陽性ばかりなら適合率も一緒に上がる区間はありますが、曲線より右上の点には届きません。どのしきい値でも両方を高くしたいなら、曲線そのものを右上へ押し出す、つまりモデルを良くする必要があります。
図:PR曲線|しきい値で動けるのは曲線の上だけ
横軸に再現率、縦軸に適合率を取り、しきい値ごとの組を結んだ線。点の数字はしきい値で、03章の表と同じスパム判定の例。破線は、より良いモデルの曲線を模式的に描いたもの。
- いまのモデル。しきい値を下げると、点は曲線の上をおおむね右下へ(再現率↑・適合率↓)
- より良いモデル。どのしきい値でも両方を高くするには、曲線ごと右上へ押し出す
| やりたいこと | 動かすもの | その結果 |
|---|---|---|
| 見逃しを減らしたい | しきい値を下げる | 再現率が上がる。空振りが増えて適合率は下がりやすく、対応リストも膨らむ |
| 空振りを減らしたい | しきい値を上げる | 適合率が上がる。拾える件数が減って再現率は下がる |
| 両方を同時に上げたい | しきい値ではなくモデル・特徴量を改善する | PR曲線そのものが右上へ移動する。いまの曲線より右上には、しきい値の調整では届かない |
しきい値の調整は、同じ曲線の上を左右に動くだけです。両方を同時に押し上げるには、特徴量を足す、学習データを増やす、ラベルの定義を見直す、といったモデル側の改善が要ります。レビューで「両方上げてほしい」と言われたときは、しきい値の話なのかモデルの話なのかを先に切り分けると議論が進みます。
02.計算式と求め方|混同行列の4マスからの算出
計算式の早見表
計算は混同行列の4マスから始めます。陽性と予測して当たった真陽性(TP)、陽性と予測して外れた偽陽性(FP)、陰性と予測して外れた偽陰性(FN)、陰性と予測して当たった真陰性(TN)の4つです。適合率・再現率と、一緒に使われることの多い指標の計算式を表にまとめます。
| 指標 | 計算式 | 別名・英語表記 | スパム判定の例 |
|---|---|---|---|
| 適合率 | TP ÷(TP+FP) | Precision(プレシジョン)、陽性的中率 | 32 ÷ 40 = 0.80 |
| 再現率 | TP ÷(TP+FN) | Recall(リコール)、感度、真陽性率 | 32 ÷ 50 = 0.64 |
| F1スコア | 2 × 適合率 × 再現率 ÷(適合率+再現率) | F1-score、F値 | 2 × 0.80 × 0.64 ÷ 1.44 = 0.711 |
| 正解率 | (TP+TN)÷ 全件 | Accuracy | 974 ÷ 1,000 = 0.974 |
| 特異度 | TN ÷(TN+FP) | Specificity、真陰性率 | 942 ÷ 950 = 0.992 |
医療や統計の分野では同じ指標を別の名前で呼ぶため、別名を押さえておくと、分野の違う文献でも同じ指標だと気づけます。F値(F-measure)は資料によって指す範囲が違い、Fβ全体の呼び名として使うこともあれば、β=1のF1スコアだけを指すこともあります。
混同行列の実数での計算
冒頭のベン図と同じスパム判定の例(問い合わせ1,000件のうち実際のスパム50件、スパムと判定40件、そのうち本当にスパムだった32件)を、混同行列の4マスに入れて計算します。
図:同じ32件を、横に割るか縦に割るか|適合率と再現率の分母の違い
問い合わせ1,000件(うち実際のスパム50件)にスパム判定モデルをかけた例。適合率は「予測した列」で割り、再現率は「実際の行」で割る。
32
真陽性(TP)
18
偽陰性(FN)=見逃し
8
偽陽性(FP)=空振り
942
真陰性(TN)
適合率=縦(予測:スパム列)で割る
32 ÷(32+8)= 0.80。スパムと判定した40件のうち、8割が本当にスパムだった。
再現率=横(実際:スパム行)で割る
32 ÷(32+18)= 0.64。実際のスパム50件のうち、拾えたのは6割強だった。
この例では適合率が0.80、再現率が0.64です。正解率(Accuracy)は(32+942)÷1,000で0.974になりますが、この0.974という数字は「ほとんどが通常の問い合わせだった」という事実をなぞっているだけで、スパムを何件取り逃したかを何も語っていません。陽性が少ないデータで正解率だけを報告してはいけないのは、このためです。
正解率をどこまで信じてよいかは、全件を多い方のクラスと答えたときの正解率と比べると判断できます。その読み方は別記事で詳しく整理しています。あわせてご覧ください。
正解率(Accuracy)の計算式と目安
全件を多い方のクラスと答えたときの正解率(多数派ベースライン)と比べる読み方を、条件を動かせる判定ツールとともに整理しています。
scikit-learn では、混同行列を自分で数えなくても classification_report がクラスごとの適合率・再現率・F1スコアをまとめて出してくれます。
from sklearn.metrics import classification_report, confusion_matrix
# y_true: 実際のラベル(1=スパム, 0=通常), y_pred: しきい値 0.5 で 0/1 にした予測
print(confusion_matrix(y_true, y_pred, labels=[1, 0]))
# [[ 32 18] <- 実際スパム: TP=32, FN=18
# [ 8 942]] <- 実際通常 : FP=8, TN=942
print(classification_report(y_true, y_pred, digits=3))
# precision recall f1-score support
# 0 0.981 0.992 0.986 950
# 1 0.800 0.640 0.711 50回帰のRMSEや相関係数まで含めた評価指標の全体像は、別記事の「予測モデル評価の指標と使い分け」で整理しています。本記事はそのうち適合率と再現率に絞り、しきい値をどう決めて運用へ載せるかを扱います。
予測モデル評価の指標と使い分け
分類・回帰・相関の3タスクごとに、どの評価指標を選ぶかを混同行列・ROC曲線の図解とともに整理しています。
医療検査での呼び方|感度・特異度・陽性的中率
医療の検査では、再現率を感度、適合率を陽性的中率と呼び、病気でない人を正しく陰性と判定できた割合を特異度で表します。総務省統計局の統計図書館コラム「感染検査の感度」では、総務省統計研究研修所の奥積雅彦氏が第110回医師国家試験の問題を例に計算しています。感度90%・特異度80%の検査でも、病気の人が0.1%しかいない集団では、陽性と出た人のうち実際に病気だった割合(陽性的中率)は0.45%にとどまります。
病気の人の割合(有病率)によって適合率がどれだけ動くかを、感度0.90・特異度0.95の検査で計算すると次のようになります。
図:同じ検査でも、病気の人が少ない集団ほど陽性的中率(適合率)は下がる
感度0.90・特異度0.95の検査を10,000人に使った計算例。棒は陽性と判定された人の内訳で、長さは人数に比例する。感度(再現率)はどちらも0.90のまま変わらない。
有病率1%(病気の人100人)
陽性的中率(適合率)0.15
陽性と判定された585人=本当に病気の90人+病気でない495人
有病率10%(病気の人1,000人)
陽性的中率(適合率)0.67
陽性と判定された1,350人=本当に病気の900人+病気でない450人
感度(再現率)は病気の人だけを分母にするため、病気の人の割合が変わっても動きません。一方の陽性的中率(適合率)は陽性と判定された人を分母にするため、病気でない人が多いほど偽陽性が増え、値が下がります。機械学習でも、陽性と陰性それぞれのスコアの分布は変わらず陽性の割合だけが違う場合は同じで、評価用データより陽性の割合が低い本番データでは、同じモデル・同じしきい値でも適合率が下がります。データの中身そのものが変わっている場合は感度や特異度も動くため、本番に近いデータで測り直すしかありません。評価用データのクラス比を本番に合わせる方法は、運用で踏みやすい落とし穴の表にまとめています。
03.トレードオフの理由|しきい値を動かしたときの変化
多くの分類モデルは0〜1のスコアを返し、そのスコアを0/1に変える境目がしきい値です。scikit-learn の predict() は0.5を境に判定しますが、この0.5はライブラリが置いた初期値にすぎません。先ほどのスパム判定の例で、しきい値だけを変えたときの判定の範囲をベン図で並べると、押し引きがはっきりします。
図:しきい値を下げると、スパムと判定する円が前の円を含んだまま広がる
青の円は実際のスパム50件で、どのしきい値でも変わらない。オレンジの円は、モデルがスパムと判定した範囲。円の大きさは模式的。数値は下の表と同じスパム判定の例から取っている。
しきい値 0.8
判定20件(うちスパム19件)
しきい値 0.5
判定40件(うちスパム32件)
しきい値 0.3
判定70件(うちスパム41件)
しきい値 0.1
判定150件(うちスパム47件)
しきい値を下げると、スパムと判定する範囲は前の範囲をまるごと含んだまま広がります。いったん拾った本物のスパムが外れることはないので、重なり(真陽性)は減らず、再現率は下がりません。一方、新たに範囲に入る件はスコアが低く、その多くは通常の問い合わせです。広げた分の多くが空振りになるため適合率は下がりやすく、2つの指標はトレードオフの関係になります。この偏りは、次のスコア分布の図で確かめられます。
図:この図の分布では、しきい値を右へ動かすほど適合率は上がり、再現率は下がる
横軸はモデルが出すスコア。左の山が通常の問い合わせ、右の山が実際のスパム。縦線より右を「スパム」と判定する。件数は通常の問い合わせが圧倒的に多いが、山の高さは形を比べやすくするため揃えている。なお、しきい値を上げたときに再現率が上がらないことはどの分布でも成り立つが、適合率が必ず上がるとは限らない。
同じ例の数字を表にすると次のとおりです。実際のスパムは常に50件なので、真陽性が増えれば見逃し(偽陰性)はその分だけ減ります。
| しきい値 | スパムと判定した件数 | 真陽性 / 偽陽性 | 適合率 | 再現率 |
|---|---|---|---|---|
| 0.8 | 20件 | 19件 / 1件 | 0.950 | 0.380 |
| 0.5 | 40件 | 32件 / 8件 | 0.800 | 0.640 |
| 0.3 | 70件 | 41件 / 29件 | 0.586 | 0.820 |
| 0.1 | 150件 | 47件 / 103件 | 0.313 | 0.940 |
しきい値0.1では実際のスパム50件のうち47件を拾えていますが、そのために103件の通常の問い合わせをスパム扱いしています。逆に0.8なら空振りは1件で済むものの、31件のスパムが通り抜けてしまいます。どの行が正解かはデータからは決まらず、業務側の損失の大きさで決まります。
表の4行のあいだも含めて、しきい値を0.05刻みで動かして確かめられます。点の色の変わり方と、2本の棒の押し引きを見比べてください。
しきい値ツール|動かすと変わる適合率と再現率
問い合わせ1,000件(うちスパム50件)に、モデルが0〜1のスコアを付けた例です。しきい値を動かすと、どれをスパムと判定するかが変わります。
- 拾えたスパム
- 見逃したスパム
- 空振り(通常をスパム扱い)
- 通常と判定した通常
1つの点が1件です。スコア0.1未満の通常の問い合わせ847件は、どのしきい値でも通常と判定されるため点を省いています。
スパムと判定した40件のうち、本物は32件
本物のスパム50件のうち、拾えたのは32件
いまは見逃し18件・空振り8件です。しきい値を0.05下げると、見逃しが2件減り、空振りが5件増えます。
記事の表の「しきい値0.5」の行と同じ件数です(通常の問い合わせは全950件)。
表の4つのしきい値で区切ってならすと、しきい値を下げるほど、見逃しを1件減らすのと引き換えに増える空振りの件数が大きくなります。1段ずつ動かすと、増え方にはばらつきがあります。この交換の比率を、見逃しと空振りの損失の比と突き合わせるのが次の章の考え方です。
しきい値を総当たりで試す必要はなく、precision_recall_curve がすべてのしきい値に対応する適合率と再現率を一度に返してくれます。
import numpy as np
from sklearn.metrics import precision_recall_curve
proba = model.predict_proba(X_valid)[:, 1] # 陽性クラスのスコア
precision, recall, thresholds = precision_recall_curve(y_valid, proba)
# precision / recall は thresholds より 1 要素長い(末尾は recall=0, precision=1 の点)
for t, p, r in zip(thresholds[::200], precision[::200], recall[::200]):
print(f"threshold={t:.2f} precision={p:.3f} recall={r:.3f}")04.優先順位の決め方|2種類の損失からの逆算
損失を金額に置き換えた合計の比較
しきい値を決める最も納得の得やすい方法は、見逃し1件あたりの損失と空振り1件あたりの損失を金額に置き換え、合計が最小になる点を選ぶことです。精度の議論を業務の議論に翻訳できるので、現場や経営層とも合意しやすくなります。
同じスパム判定モデルでも、置かれた状況によって答えが正反対になります。問い合わせフォームのスパム判定では、空振り(本物の問い合わせをスパム扱いする)が商談機会の損失に直結するため高くつきます。ここでは空振り1件を30,000円、見逃し1件を担当者の対応時間として1,000円と置いてみます。
| しきい値 | 空振り(偽陽性) | 見逃し(偽陰性) | 合計の損失 |
|---|---|---|---|
| 0.8 | 1件 × 30,000円 = 30,000円 | 31件 × 1,000円 = 31,000円 | 61,000円(最小) |
| 0.5 | 8件 × 30,000円 = 240,000円 | 18件 × 1,000円 = 18,000円 | 258,000円 |
| 0.3 | 29件 × 30,000円 = 870,000円 | 9件 × 1,000円 = 9,000円 | 879,000円 |
| 0.1 | 103件 × 30,000円 = 3,090,000円 | 3件 × 1,000円 = 3,000円 | 3,093,000円 |
用途による最小しきい値の違い
この置き方では、しきい値を高くして適合率を優先する0.8が最小になります。ところが同じモデルを不正決済の検知に使い、見逃し1件の損失を50,000円、空振り1件を目視確認の手間として500円と置き換えると、順位が完全に入れ替わります。しきい値0.8の合計損失は約1,550,500円まで膨らみ、0.1では201,500円まで下がります。指標の優劣ではなく、2つの損失の比率が答えを決めています。
損失を正確な金額にできなくても、見逃しは空振りの何倍重いかという比率さえ合意できれば、しきい値の順位は決まります。「見逃し1件は空振り10件分」と置いて計算し、現場に見せて違和感の有無を聞く進め方が取り組みやすい方法です。この比率は後述のFβのβとも対応しており、Fβはおおむね「再現率を適合率のβ²倍重く見る」重み付けにあたります。
優先順位の判断フロー
- 見逃しの損失が大きい拾った件数を人が対応しますか?
- 対応できる件数に上限がある再現率を優先しつつ、スコア上位k件に絞って渡すしきい値を固定せず、現場のキャパシティで件数を決める
- 自動処理なので上限がないしきい値を下げて再現率を優先する不正検知・スクリーニングなど。F2スコアを判断材料に使う
- 空振りの損失が大きいしきい値を上げて適合率を優先する問い合わせのスパム判定・高額アラートなど。F0.5スコアを判断材料に使う
- どちらとも決められないF1スコアが最大になるしきい値を出発点にする運用しながら、現場の不満がどちら側に出るかで調整する
05.1つの数字への集約|F1スコアとFβ
モデルを何本も比べるときは、適合率と再現率の2つを見比べるより1つの数字に畳んだ方が扱いやすくなります。そのための指標がFβです。scikit-learn の評価指標ドキュメントによると、Fβは適合率と再現率の重み付き調和平均で、Fβ = (1 + β²) × 適合率 × 再現率 ÷ (β² × 適合率 + 再現率) と表されます。β=1のときがF1スコアで、適合率と再現率を同じ重みで扱います。
単純平均ではなく調和平均を使うのは、片方が極端に低いときに全体を強く引き下げるためです。適合率1.0・再現率0.02のモデルは、単純平均なら0.51と悪くない値に見えますが、F1スコアでは0.039にとどまります。
βを1から動かすと、重みが移ります。先ほどの適合率0.80・再現率0.64のモデルで計算すると、次のようになります。
| 指標 | この例での値 | 重み | 使う場面 |
|---|---|---|---|
| F0.5スコア | 0.762(適合率0.80寄り) | 適合率を重く見る | 空振りのコストが高い。スパム判定・高額アラート・営業の架電リスト |
| F1スコア | 0.711(ちょうど中間) | 同じ重み | どちらを重く見るか決めていないときの出発点。モデル同士の比較 |
| F2スコア | 0.667(再現率0.64寄り) | 再現率を重く見る | 見逃しのコストが高い。不正検知・障害検知・一次スクリーニング |
F1スコアの計算には真陽性・偽陽性・偽陰性しか入らず、正しく陰性と判定した件数は一切効きません。そのため「陰性をきちんと陰性と判定できているか」もあわせて評価したい場面では、混同行列の4マスすべてを使うMCC(マシューズ相関係数)を併記すると偏りに気づきやすくなります。また、どのクラスを陽性と呼ぶかを入れ替えるとF1スコアの値も変わるため、レポートでは陽性クラスがどちらかを必ず明記してください。
from sklearn.metrics import fbeta_score, precision_recall_curve
import numpy as np
# beta=0.5 は適合率重視、beta=2 は再現率重視
print(fbeta_score(y_true, y_pred, beta=0.5)) # 0.762
print(fbeta_score(y_true, y_pred, beta=2.0)) # 0.667
# F2 が最大になるしきい値を検証用データで探す
precision, recall, thresholds = precision_recall_curve(y_valid, proba)
beta = 2.0
f_beta = (1 + beta**2) * precision * recall / (beta**2 * precision + recall + 1e-12)
best = int(np.nanargmax(f_beta[:-1])) # 末尾の点にはしきい値が対応しない
print(f"best threshold={thresholds[best]:.3f} F2={f_beta[best]:.3f}")06.PR曲線と平均適合率(AP)|不均衡データでの読み方
PR曲線と平均適合率(AP)の読み方
しきい値を1つに決める前に、このモデルはどこまで押し引きできるのかを見ておくと判断が早くなります。しきい値による2つの指標の押し引きで見たPR曲線を、モデル同士で比べるときは、曲線の下の面積を1つの数字にまとめます。
図:PR曲線の下の面積が平均適合率(AP)の目安|ランダム予測なら陽性割合の高さ
塗った部分がおおよその面積。APの実際の計算は、点と点を直線で結ばずに段差で足し合わせる。破線はランダムに予測した場合の目安で、高さは陽性割合(この例では0.05)に一致する。点に添えた数字はそのときのしきい値で、形状はスパム判定の例に基づく概形。
scikit-learn の average_precision_score のドキュメントによると、平均適合率(AP: Average Precision)は隣り合う点の再現率の増分に、そのときの適合率を掛けて足し合わせた値(AP = Σ (Rₙ − Rₙ₋₁) Pₙ)です。同じドキュメントは、台形則で面積を求める auc のように点と点を直線で結ぶ計算は性能を楽観的に見積もると注意しており、PR曲線の要約には average_precision_score を使うのが安全です。
比べる基準は陽性の割合です。Takaya Saito 氏と Marc Rehmsmeier 氏が2015年に PLOS ONE で発表したThe Precision-Recall Plot Is More Informative than the ROC Plot When Evaluating Binary Classifiers on Imbalanced Datasetsによると、PR曲線の基準線の高さは陽性と陰性の比で決まり、ランダムに予測した場合のPR曲線の面積は陽性の割合に一致します。スパム判定の例なら陽性割合は0.05なので、この水準を大きく上回っているかどうかが最初の確認になります。
ROC曲線との使い分け
PR曲線の方が実態を映す場面もはっきりしています。前節で引いた Takaya Saito 氏と Marc Rehmsmeier 氏の論文は、クラス比が偏ったデータでは、陽性と予測した中の正解割合を直接扱うPR曲線の方が、将来の分類性能を正しく見積もれると論じています。
| 観点 | PR曲線・平均適合率(AP) | ROC曲線・ROC-AUC |
|---|---|---|
| 縦横の軸 | 縦が適合率、横が再現率 | 縦が真陽性率(=再現率)、横が偽陽性率 |
| 陰性が増えたときの挙動 | 適合率が下がるため値も下がる。陽性が少ない問題の実感に近い | 偽陽性率の分母も増えるため値が動きにくく、高めに出やすい |
| ランダム予測の基準 | 陽性割合(例では0.05) | 常に0.5 |
| 向く場面 | 陽性が数%しかない不正検知・スパム判定・障害検知 | 陽性と陰性が同程度で、両クラスを対等に評価したいとき |
なお、PR曲線もROC曲線も測っているのは「陽性と陰性を順位づけできるか」という識別力です。モデルが返した0.82という数字をそのまま82%の確からしさとして報告してよいかは別の論点で、確率の目盛りを実際の頻度に合わせる作業(較正)が必要になります。
確率較正(キャリブレーション)の基礎
モデルが出す予測確率と実際に当たる割合のズレを測り、Platt Scalingなどで補正する手順を整理しています。
07.多クラスの平均化|macro・micro・weighted
クラスが3つ以上になると、適合率と再現率はクラスごとに出ます。それを1つにまとめる方法が複数あり、選び方で結論が変わります。顧客を「継続900件・アップセル候補80件・解約リスク20件」に分類するモデルで、クラスごとの再現率が0.97・0.55・0.30だった場合を考えます。
| 平均の取り方 | この例での再現率 | 計算の中身 | 選ぶ場面 |
|---|---|---|---|
| macro(マクロ平均) | 0.607 | クラスごとの値を単純平均する(0.97・0.55・0.30の平均) | 件数の少ないクラスも同じ重さで見たいとき。少数クラスの弱さが数字に出る |
| weighted(加重平均) | 0.923 | 各クラスの件数で重み付けして平均する | 全体の体感精度を1つの数字で示したいとき。多数クラスに引っ張られる |
| micro(マイクロ平均) | 0.923 | クラスごとに平均せず、全クラスの真陽性・偽陽性・偽陰性を合算してから割る | 1件1件を対等に扱いたいとき。マルチラベルや、多数クラスを除外して集計したいとき |
scikit-learn の多クラス・マルチラベル評価のドキュメントは、macro平均について、まれだが重要なクラスの性能を際立たせる手段になり得る一方で、すべてのクラスが等しく重要という前提が成り立たない場合は少数クラスの低い性能を過度に強調してしまうという趣旨のことを説明しています。weighted平均は逆に、件数の多いクラスの成績でほぼ決まります。この例では解約リスクの再現率が0.30でも、全体は0.923と好成績に見えてしまいます。
表で weighted 平均と micro 平均がどちらも0.923になっているのは偶然ではありません。再現率に限っては weighted 平均も同じ値になります。各クラスの再現率に件数を掛けて足すと真陽性の合計に戻るためで、適合率やF1スコアでは一般に一致しません。
1件につき1クラスだけを予測する多クラス分類で全クラスを集計対象にすると、ある予測ミスはあるクラスの偽陽性であると同時に別のクラスの偽陰性になります。両者の件数が一致するため、micro平均の適合率・再現率・F1スコアはいずれも正解率(Accuracy)と同じ値になり、指標を増やしても情報は増えません。活かすなら、scikit-learn のドキュメントが挙げているように多数クラスを集計対象から外す使い方が向きます。
from sklearn.metrics import classification_report, recall_score
print(classification_report(y_true, y_pred, digits=3))
# 末尾に macro avg と weighted avg の行が付く
print(recall_score(y_true, y_pred, average="macro")) # 0.607
print(recall_score(y_true, y_pred, average="weighted")) # 0.923
# 多数クラス(継続)を除いて micro 平均を取る
print(recall_score(y_true, y_pred, average="micro",
labels=["アップセル候補", "解約リスク"]))多クラス分類そのものの組み立て方(ソフトマックスで各クラスの確率を出す仕組みや、陽性が少ないときの学習側の対策)は、別記事で整理しています。
ロジスティック回帰分析
二値・多項の分類とオッズ比の読み方に加え、class_weightやSMOTEによる不均衡データ対策を扱っています。
08.検索・推薦・RAGでのPrecision@k・Recall@k
検索結果や推薦枠、社内文書を根拠にAIが答えるRAG(検索拡張生成)では、候補の全件を判定せず、上位k件だけを取り出して使います。この場合、しきい値ではなく「何件取るか」が押し引きのつまみになり、適合率と再現率もk件に限定して測ります。
- 1正解を先に定義する
質問ごとに「根拠になる文書はこれ」という正解集合を人手で決めます。ここが曖昧だと以降の数値はすべて揺れます。
- 2kを業務側から決める
AIに渡せる文脈の長さ、推薦枠の数など、実際に使える件数からkを決めます。
- 3Recall@kで取りこぼしを見る
正解文書のうち上位k件に入った割合です。ここが低ければ、生成側を調整しても正しい答えは出ません。
- 4Precision@kで雑音を見る
上位k件のうち本当に関係がある割合です。低いと無関係な文書が文脈を占領し、回答がぶれます。
- 5kを変えて両方を再測定する
kを増やすとRecall@kは上がり、Precision@kは下がります。使えるkの範囲で両方が許容できる点を選びます。
RAGの評価ライブラリ Ragas は、この考え方をそのまま指標にしています。Ragas の Context Precision のドキュメントによると、Context Precision@K は上位k件までの Precision@k を関連度で重み付けして平均する形で定義されています。Context Recall のドキュメントでは、正解文書に含まれる主張のうち検索結果で裏付けられたものの割合として定義され、文書IDだけを突き合わせる方式など複数の算出方法が用意されています。
実務で先に見るべきは Recall@k です。検索の段階で根拠が落ちていれば、生成側のプロンプトをどう工夫しても回答は直りません。逆にRecall@kが十分高いのに回答品質が上がらない場合は、Precision@kの低さ(無関係な文書の混入)か、生成側の指示に原因があると切り分けられます。
RAG実務入門
社内文書をAI回答の根拠にする設計を、チャンク分割・メタデータ・引用表示まで含めて整理しています。
09.運用で踏みやすい落とし穴
スコアの計算自体は数行で終わりますが、数字の意味を取り違える原因はその手前にあります。実務で頻度の高いものを並べます。
| 落とし穴 | 何が起きるか | どうするか |
|---|---|---|
| 評価データのクラス比を本番と変える | 再現率は陽性だけで計算するため影響を受けないが、適合率は陰性の件数に左右される。陰性を間引いたデータで測ると適合率だけが高く出る | 評価用データは本番の出現比率のまま残す。間引くなら本番比率に換算してから報告する |
| しきい値を評価用データで選ぶ | そのデータに最も都合のよい点を選ぶため、報告した数値が本番で再現しない | しきい値は検証用(validation)データで決め、触っていないテストデータで確認する |
| 再現率の分母が測れていない | ラベルが付いていない陽性があると見逃しを数えられず、再現率が過大に出る | 抽出したサンプルを人手で全数確認して分母を推定し、推定値であることを併記する |
| 正解ラベル自体が揺れている | 評価者ごとに判断が割れていると、モデルの出来より採点の揺れが数字を動かす | 評価者間の一致度を先に測り、必要ならラベル定義を書き直してから精度を議論する |
| 適合率と再現率を別条件で並べる | 別のしきい値や別の期間の数字を並べると、到達できない組み合わせを報告してしまう | 同じしきい値・同じデータで測った組として、しきい値も添えて報告する |
このうちラベルの揺れは、モデルを直しても解消しません。複数の評価者やモデルの判定がどれくらい揃っているかを測る手順は、別記事で扱っています。
一致度・信頼性の指標と使い分け
カッパ係数やICCで、評価者やモデルの判定がどれくらい揃っているかを測る方法を整理しています。
スパムの手口も、顧客の解約理由も、時間とともに変わります。決めたしきい値のまま運用を続けると、同じスコアでも実際の陽性割合が変わり、適合率が静かに下がることがあります。月次で混同行列を出し直し、現場から「空振りが増えた」「見逃しが増えた」という声がどちら側に出ているかと突き合わせると、再調整の時期を判断できます。
10.よくある質問(FAQ)
適合率と再現率は、どちらを見ればよいですか?
まずしきい値を決めます。しきい値が決まれば、適合率と再現率は両方とも自動的に決まります。判断の起点は、見逃し1件と空振り1件のどちらの損失が大きいかです。空振りのコストが高いスパム判定や高額アラートでは適合率を、見逃しのコストが高い不正検知や一次スクリーニングでは再現率を優先します。報告するときは必ず両方を、同じしきい値で測った組として並べるのがおすすめです。
しきい値は0.5のままではいけないのですか?
0.5は統計的な根拠がある値ではなく、ライブラリの初期値です。陽性が数%しかないデータでは0.5だと再現率が低く出やすく、逆に対応リストを絞りたい場面では0.5でも空振りが多すぎることがあります。見逃しと空振りの損失から合計が最小になる点を探すか、現場が対応できる件数からスコア上位k件で切る運用に置き換えると納得が得られます。
F1スコアが高ければ良いモデルと言えますか?
F1スコアは適合率と再現率を同じ重みで畳んだ値なので、どちらかを重く見るべき業務では判断材料として弱くなります。見逃しを重く見るならF2スコア、空振りを重く見るならF0.5スコアを併記します。またF1スコアの計算には真陰性が入らず、どちらのクラスを陽性と呼ぶかでも値が変わるため、陽性クラスの定義を明記したうえでMCC(マシューズ相関係数)など別の指標も添えると偏りに気づけます。
ROC-AUCとPR曲線は、どう使い分けますか?
陽性と陰性が同程度ならROC-AUCで構いませんが、陽性が数%しかない不均衡データではPR曲線と平均適合率(AP)の方が実態に近い評価になります。ROC-AUCはランダム予測が常に0.5なのに対し、平均適合率のランダム水準は陽性割合そのものなので、陽性が少ないほど厳しい基準になります。両方を出しておき、報告ではデータのクラス比を添えるのがおすすめです。
多クラス分類では、macro平均とweighted平均のどちらを報告すべきですか?
件数の少ないクラスこそ拾いたい場合はmacro平均を報告します。少数クラスの成績がそのまま数字に反映されるためです。全体の体感精度を示したい場合はweighted平均ですが、多数クラスの成績でほぼ決まる点に注意が必要です。なお単一ラベルの多クラス分類で全クラスを集計対象にすると、micro平均は正解率(Accuracy)と同じ値になるため、指標を増やす目的では役に立ちません。
適合率と再現率の覚え方はありますか?
分子はどちらも真陽性で共通なので、分母の向きだけ押さえれば足ります。適合率の分母は予測側(陽性と判定した件数)、再現率の分母は実際側(実際に陽性だった件数)です。立場ごとの問いと英語からの覚え方は、本文の取り違えないための覚え方にまとめています。迷ったときは、しきい値を上げた場合を考えて検算してみるのがおすすめです。判定を厳しくすると予測件数が減るので、適合率は上がりやすくなります。一方の再現率は、同じモデル・同じ評価データでしきい値だけを動かすなら拾える件数が増えないため、下がるか横ばいにとどまります。
適合率・再現率・F1スコアの目安はどれくらいですか?
目安は、陽性の割合や、見逃しと空振りのコストによって変わります。同じ0.7でも、十分な場合もあれば不十分な場合もあります。目安を置くなら、まず比較の基準を決めるのがおすすめです。ランダムな予測では、しきい値を決めたときの適合率もPR曲線の面積も、陽性の割合と同じ水準にとどまります(PR曲線と平均適合率(AP)の読み方)。陽性が5%のデータなら、適合率0.30でも基準の6倍にあたります。そのうえで、「再現率0.90以上を保ったまま適合率が最も高くなるしきい値」のように業務側の下限を条件にして選ぶと、目安を巡る議論が決着しやすくなります。
「精度」は適合率と正解率のどちらを指しますか?
どちらを指すかは文脈によって変わります。GoogleのMachine Learning Crash Course(日本語版)はAccuracyを「精度」、Precisionを「適合率」と訳していますが、情報検索の分野ではPrecisionを「精度」と訳す資料もあります。日常会話の「モデルの精度が高い」は、特定の指標ではなく性能全般を指していることもあります。報告や仕様書では、Accuracy・Precision・Recallの英語を併記し、どの指標の値かを明示するのがおすすめです。
物体検出(YOLOなど)では、適合率と再現率をどう数えますか?
予測した枠と正解の枠の重なりの割合(IoU:Intersection over Union)で、当たり外れを決めてから数えます。予測したクラスが正解と一致し、IoUがしきい値(たとえば0.50)以上で正解の枠と対応付けられた予測が真陽性です。対応する正解の枠が無い予測(クラス違いを含む)は偽陽性、どの予測にも拾われなかった正解の枠は偽陰性になります。1つの正解の枠に対応付けられる予測は1つだけなので、同じ物体を重複して検出した2つ目以降の予測も偽陽性に数えます。Ultralyticsのドキュメントによると、mAP50(mean Average Precision)は、IoUのしきい値を0.50にして計算した平均適合率(AP)をクラス間で平均した値です。mAP50-95は、IoUのしきい値を0.50から0.95まで変えて計算した値の平均です。
11.まとめ
適合率と再現率は、真陽性という同じ分子を、予測した件数と実際の件数という違う分母で割った指標です。しきい値を動かせば片方が上がり片方が下がるので、決めるべきなのはしきい値そのものです。その決め方は、見逃し1件と空振り1件の損失を比べて合計が最小になる点を選ぶのが基本で、重みを決めきれないときはF1スコア、見逃しを重く見たいときはF2スコアが出発点になります。陽性が少ないデータではPR曲線と平均適合率でモデルの上限を確かめ、多クラスではmacro平均とweighted平均のどちらで報告するかを先に決めておくと、数字の解釈がぶれません。
こうした指標の設計は、モデルの性能そのものより「業務のどの損失を重く見るか」を決める作業に近く、分析担当と現場のあいだで合意を取る工程がキーとなります。弊社でもこの部分を一緒に詰めるところから支援しています。
分類モデルのしきい値設計・評価指標の設計を伴走支援しています
弊社ではAIフル活用のデータ分析支援を提供しています。適合率と再現率のどちらを重く見るかの整理、損失に基づくしきい値の決定、運用後の監視設計まで、実データで伴走しながら整えています。お気軽にお問い合わせください。
データ分析・アルゴリズム 基礎知識集
一覧に戻る →全体像とカテゴリ早見
データの可視化
個別指標カテゴリ
- ›類似度・距離の指標の使い分け
- ›一致度・信頼性の指標の使い分け
- ›予測モデル評価の指標と使い分け
- ›適合率と再現率|しきい値で見逃しと空振りを調整する(この記事)
- ›正解率|多数派ベースラインと比べて読む
- ›確率較正(キャリブレーション)の基礎|事後較正・Vertex AI

