ブログ / 製品

適合率と再現率が重要な理由

Zubin Pratap 
2×2に並ぶ四角形。三つはセージグリーンと薄いグレーの水彩、一つは黒い輪郭線

二つの間違い方

機械学習モデルの評価を仕事にしていれば、適合率と再現率の違いは明らかでしょう。それ以外の人には、そうとは限りません。

例で考えると理解しやすくなります。

RAGパイプラインを開発していて、ベクトルストアから信頼できる検索結果を得たいとします。最初の疑問の一つは、何件のチャンクを取得するか、つまりtop_kをいくつにするかです。

3件を取得すれば、どれも関連性が高い可能性があります。しかし、4位や10位にある関連チャンクを見落とすかもしれません。必要な情報が抜け落ちることになります。

これを解決するため、top_kを50に増やすとします。関連する情報をすべて拾えますが、関係のない情報も多く含まれます。ベクトルストアの関連チャンクをすべて取得できても、LLMが無関係な情報を含む、雑音の多い応答を返す可能性は高くなります。

このトレードオフを、適合率と再現率と呼びます。

上位3件の検索は、結果の関連性が高く、的を射ているため適合率が高くなります。しかし、見落としがあるため再現率は低くなります。

一方、上位50件の検索は、すべて拾えるので再現率が高いものの、不要なものも多く拾うため適合率は低くなります。

適合率と再現率は、何かを検出するシステムならどこでも登場します。検出とは、Xを検出したか、していないかという二択の仕事です。その判断は正しいことも、間違っていることもあります。

後ほど混同行列を説明するときに、詳しく見ていきます。

ややこしい話なので、まずなぜ適合率と再現率を使うのかを理解するとよいでしょう。正解率だけを測ると誤解を招くからです。

正解率だけでは誤解を招く理由

検出器に100件の例を与え、そのうち10件に検出すべき事象が含まれているとします。しかし検出器は100件すべてに「事象なし」と返します。「事象なし」の判断が90%正しいので、このテストの正解率は90%です。

ところが、例に含まれる検出すべき事象に対しては、正しく検出できた割合は0%です。

建物の入り口の警備員を考えましょう。訪問者100人に1人だけが危険人物なら、全員を通す警備員も、安全な人を通すという点では「99%正しい」ことになります。しかし危険人物を入れない仕事の成功率で測れば0%です。その1人を見つけるのが仕事だからです。

つまり、データセットが一方の結果に大きく偏っていると、予測を当てずっぽうに行うモデルでも偶然高い得点が出て、数値上は正確に見えることがあります。それでも、本来予測すべきものは予測できていません。

検出する事象を定義する

混乱しやすい話なので、システムの検出の仕事を定義するまで、適合率と再現率の分析を始めないほうが理解しやすいと感じます。これらの指標は、果たすべき仕事に依存します。

まず、真陽性となるケースを決めます。

迷惑メールフィルターなら、検出する事象は「このメールは迷惑メールである」です。煙探知器なら「煙がある」です。

これが、検出すべき「事象」です。

では、システムに二つの仕事がある場合はどうでしょうか。自動ターン検出にも対応するAI音声認識モデルなら、「ユーザーが話し始めた」と「ユーザーが話すのを止めた」の両方が対象になりえます。話すのを止めることと、発話ターンを終えることは同じではありません。それぞれの事象に、別の適合率と再現率が必要です。

陽性とは、事象が起きたとシステムが判断したという意味です。検出の二択の片側を示すラベルであり、価値判断ではありません。

実際に発話があった実際には発話がなかった
システムが発話ありと判定真陽性(TP)偽陽性(FP)
システムが発話なしと判定偽陰性(FN)真陰性(TN)

この表を混同行列と呼びます。ある事象について、実際に起きたこととシステムの判断を対応させ、考えられるすべての検出結果を整理します。

指標を選ぶ前に、四つの問いに答えましょう。

  • システムはどの事象を検出すべきか。
  • 何をもってシステムが検出したとするか。
  • 偽陽性はどのようなケースか。
  • 偽陰性はどのようなケースか。

分母から考える

適合率と再現率の違いは、分母から考えると理解しやすくなります。

適合率

適合率の分母は、モデルが陽性と予測したすべての件数です。正しい予測と誤った予測、つまり真陽性と偽陽性を足します。

分子には、予測のうち正しかった件数である真陽性を置きます。

式は次のようになります。

precision = true positives / (true positives + false positives)

「発話開始」の検出を考えます。音声サンプルが100件あり、フィルターは80件を発話開始と判定しました。しかし実際に発話開始があったのは、そのうち60件でした。

真陽性は60件、偽陽性は80 - 60 = 20件です。したがって次のようになります。

precision = 60 / (60 + 20) = 75%

適合率が低いと、別の音や無音を発話と誤認します。

適合率は、正しく検出したものと誤って検出したものの合計に対する、正しく検出したものの割合です。

再現率

再現率の分母は、実際に存在する陽性の総数です。検出したものと見逃したもの、つまり真陽性と偽陰性を足します。モデルが見つけたかどうかにかかわらず、すべての実際の事象が分母に入ります。

分子は適合率と同じで、真陽性を数えます。

recall = true positives / (true positives + false negatives)

再現率は、正しく検出したものと、本来検出すべきだったのに除外してしまったものの合計に対する、正しく検出したものの割合です。

先ほどの発話検出の例では、真陽性は60件です。実際の発話をすべて検出し、さらに余計なものまで拾っているので、偽陰性は0件です。

計算すると次のようになります。

recall = 60 / (60 + 0) = 100%

これでは再現率の役割がわかりにくいので、例を変えましょう。音声サンプル100件のうち、実際に発話開始があるのは60件ですが、モデルが発話開始と判定したのは50件とします。

真陽性が50件なら、偽陰性は60 - 50 = 10件です。モデルが10件の発話開始を見逃しました。

計算は次のようになります。

recall = 50 / (50 + 10) = 83%
precision = 50 / (50 + 0) = 100%

この例では偽陽性が0件なので、適合率は100%です。

単純な「正解率」との違いにも注目してください。

accuracy = (true positives + true negatives) / all samples

各判断の損失が同程度で、評価データが本番環境を代表しているなら、正解率を使えます。しかし、対象の事象がまれだったり、二つの間違いが異なる損失をもたらしたりする場合は、混同行列に沿った報告が性能の理解を大きく変えます。

数式や関連する指標を詳しく知りたい方は、Wikipediaの解説をご覧ください。

適合率と再現率のトレードオフ

ここまでの例からわかるように、一方を上げると、もう一方は下がりがちです。

冒頭の検索の例が、その理由を示しています。文書を多く取得すれば再現率が上がり、適合率は下がります。少なく取得すれば適合率が上がり、再現率は下がります。

実際には、多くのモデルは検出に対する確信度を0から1の数値で出します。しきい値は、「0.7を超えたら陽性とする」のように、利用者が選ぶ境目です。

補聴器の音量つまみに似ています。感度を上げればあらゆる会話が聞こえますが、エアコン、車、隣家のテレビまで聞こえます。下げれば大きく明瞭な声だけが聞こえ、静かな声は聞き逃します。

しきい値を上げると偽陽性が減り、適合率が上がります。

しきい値を下げると、より多くの事象を正しく検出し、偽陰性が減るため、再現率が上がります。

CartesiaのInk-2のようにパレートフロンティア上にあるモデルは、これらのトレードオフを最適に均衡させます。

音声AIに当てはめる

音声AIには、検出や予測の仕事がいくつも含まれます。すべてを一つの正解率で採点してはいけません。

**音声区間検出(VAD)**は、ある音声の区間に発話が含まれるかを判断します。テストデータには、発話のフレームより無音のフレームがはるかに多いことがあります。毎回無音と予測すれば、すべての発話を見逃していても正確に見えます。発話に対する適合率と再現率を測り、どの程度正しく検出し、どの程度見逃すかを報告しましょう。

ターン検出は、話者が会話の発言権を得る、または譲るタイミングを判断します。開始と終了の事象には別々の指標が必要です。ここでは、二つのInk-2 ASRのターンイベントを使います。

turn_start:ユーザーは話し始めたか

対象は「ユーザーが話し始めた」という事象です。システムがturn_startイベントを出したとき、検出したとします。

  • 偽陽性は、キーボードの音、背景の話し声、マイクへの回り込み、エージェント自身の音声に対してturn_startを出すことです。
  • 偽陰性は、ユーザーが話し始めたのにシステムが見逃すことです。

turn_startの適合率が低いと、ユーザー以外の音声にシステムが反応します。turn_startで再生を停止する場合、偽陽性によって不要な割り込みが発生します。

turn_startの再現率が低いと、実際の発話が後続のパイプラインに届かないことがあります。

turn_end:話者は話し終えたか

対象は「ユーザーが自分の発話ターンを終えた」という事象です。システムがturn_endイベントを出すと検出となり、アプリケーションは応答できます。

  • 偽陽性は、ユーザーがまだ話すつもりなのにturn_endを出すことです。
  • 偽陰性は、ユーザーが話し終えたのにシステムが待ち続けることです。

turn_endの適合率が低いと、考える、言い直す、息を吸うための間でユーザーを遮ってしまいます。再現率が低いと、ユーザーが話し終えてから無言の時間が続きます。

どちらのイベントでも、予測時刻とラベル付けした時刻の一致を何で判断するかを定義しましょう。得点を計算する前に、対象の話者、重なった発話や背景音声のラベル付け、「話し終わった」の意味を決めます。

失敗の影響に合わせて指標を選ぶ

  • turn_startとturn_endの適合率と再現率を別々に報告する。
  • 製品にとって、どちらの誤りの損失が大きいかをもとにしきい値を選ぶ。
  • 集計値だけでなく、偽陽性と偽陰性の実例を確認する。
  • 正解率は補足情報として使い、評価のすべてにしない。

次にモデルが正解率90%と報告したら、何を検出したのか、その事象はどのくらい起きたのか、その得点がどの間違いを隠しているのかを確かめてください。