機械学習の2値分類の評価指標に AUC (Area Under the Curve) があります。
とてもお恥ずかしいのですが、私は AUC は「 ROC 曲線を積分したもので、その値は [0,1] に収まる」というくらいにしか理解しておらず、その解釈がとても曖昧だったところ、先日会社の後輩に AUC とは「モデルによる順序の保存性」を評価しているという解釈を教えてもらい、自分なりに導出とかをしてみたので記事として残しておきます。
AUC の定義
まずは、AUCの定義を振り返ります。
データサイズ $N$ の全てのアイテム $i$ に対して、
- 真の値 $y_i$ (正例: $y_i=1$, 負例: $y_i=0$)
- モデルの出力値 $p_i \in (0,1)$
が必ずつけられているものとします。
この時、モデルの出力値から真の値を予測する方法として、閾値 $k \in [0,1]$ を設けて、
- $p_i<k$ なら 負例 と予測
- $k \leq p_i$ なら 正例 と予測
と取り決めます。
これによって全てのアイテム $i$ に対して、予測値 (0 or 1) を割り振ることができ、真の値との組み合わせによって以下の混合行列のいずれかのパターンに該当することになります。
| 正例(予測) | 負例(予測) | |
|---|---|---|
| 正例(真) | TP / True Positive | FN / False Negative |
| 負例(真) | FP / False Positive | TN / True Negative |
そこで、以降では上記の混合行列のそれぞれのパターンに該当するアイテムの数を $N_{TP}, N_{FN}, N_{FP}, N_{TN}$ と書くことにします。当然ですが、$N=N_{TP} + N_{FN} + N_{FP} + N_{TN}$ です。
また、新たに次の量を定義します。
\displaylines{
TPR := \frac{N_{TP}}{N_{TP}+N_{FN}} = \frac{N_{TP}}{N_p} \tag{1} \\
FPR := \frac{N_{FP}}{N_{FP}+N_{TN}} = \frac{N_{FP}}{N_n}
}
TPR (FPR) は True Positive Rate (False Positive Rate) を意味し、その分母は真の正例 (負例) の総数 $N_p (N_n)$ なので、モデルに依存しない定数になっていることに注意です。
この TPR と FPR は閾値 $k$ の値に依存する量になっており、$k=1$ の時は全てのアイテムを負例と予測することになるので、$N_{TP} = N_{FP} = 0$ より、$(TPR, FPR) = (0, 0)$ 。逆に $k=0$ の時は全てのアイテムを正例と予測することになるので分母と分子が一致し、$(TPR, FPR) = (1, 1)$。さらにいうと、$k$ が $1 \to 0$ で正例と予測されるアイテムの集合は単調に大きくなるので、どちらの分子も単調に増加します。つまり、$TPR = f(FPR)$ とする1価の単調増加関数が定義できて、これを ROC 曲線と呼び、その積分値を AUC と呼びます。
...と形式的には AUC はこのように定義することができるのですが、改めて書いていてこの定義だけでは確かに解釈が難しいですね。
AUC の解釈
さて、ここからが AUC の解釈の話なんですが、言葉で書くより式で書いた方が分かりやすいと思うので、先に式を書きます。
AUC = \frac{1}{N_p \cdot N_n} \sum_{i: 正例 (真), j:負例 (真)} \theta(p_i - p_j) \tag{2}
ここで $\theta$ はステップ関数 (ヘヴィサイド関数) です。
つまり、AUC は「正例(真)のアイテムと負例(真)のアイテムの全ての組み合わせを考えた時、各アイテムに紐づくモデルの出力値が真の値の間の大小関係を保てている割合」を測っている量だということになります。
AUC は「モデルによる順序の保存性」を評価していると述べたのは、このことをもっと短めに表現したものになります。
導出
次に上式を導出します。ただし、この方法は自分が適当に考えたものだということはお断りしておきます。
まずは、TPR や FPR をステップ関数を使って書き直します。なお、分母は定数なのでそのままです。
\displaylines{
TPR &=& \frac{1}{N_p} \sum_{i=1}^{N} y_i \theta(p_i - k) \tag{3}\\
FPR &=& \frac{1}{N_n} \sum_{i=1}^{N} (1-y_i)\theta(p_i -k)
}
これで $k$ 依存性が明示的に数式で書き表せましたね。AUC はその定義より $TPR = f(FPR)$ を $FPR$ に沿って積分したものですが $TPR$ (以降の式の書きやすさのために$y$とします) や $FPR$ (同様に$x$とします) は $k$ に依存しているので、$k$ による積分に置き換えられます。
つまり、
\displaylines{
AUC = \int_{0}^{1} y \ dx = \int_{1}^{0} y \ \frac{dx}{dk} \ dk \tag{4} \\
= \int_{1}^{0} dk \ \frac{1}{N_p} \sum_{i=1}^{N} y_i \theta(p_i - k) \frac{d}{dk}
\left\{ \frac{1}{N_n} \sum_{j=1}^{N} (1-y_j)\theta(p_j -k) \right\} \\
= -\frac{1}{N_p \cdot N_n} \sum_{i,j} \int_1^0 dk \ y_i \theta(p_i - k)(1-y_j)\delta(p_j-k) \\
= \frac{1}{N_p \cdot N_n} \sum_{i,j} y_i (1-y_j) \int_0^1 dk \ \theta(p_i-k)\delta(p_j-k) \\
= \frac{1}{N_p \cdot N_n} \sum_{i,j} y_i (1-y_j) \theta(p_i - p_j)
}
こんな感じになります。ここでステップ関数の微分がディラックのデルタ関数になる(i.e. $d\theta(x) /dx = \delta(x)$)という性質と超関数としてのデルタ関数の積分ルールを使っています。もしかするとこの辺りの超関数の取り扱いはあまり知らない人も多いかも知れませんが、私がこの計算に慣れていることもありこんな感じで計算してみました。超関数を使わなくても同じような結果は得られると思います。
さて、これで初めに提示した式にかなり近い式がすでに得られているので、ここでやめてもいいですが、一応最後までやります。といってもこの後はほぼ自明で、$y_i, y_j$は 0 または 1 しかとらない量なので、$y_i=0$(負例)の時と $y_j=1$(正例)の時は sum の中身は 0 になり、$\sum_i y_i = \sum_{i:正例 (真)}$ 及び $\sum_j (1-y_j) = \sum_{j:負例 (真)}$ と書き換えることができ、結果、
AUC = \frac{1}{N_p \cdot N_n} \sum_{i: 正例 (真), j:負例 (真)} \theta(p_i - p_j)
が得られます。
AUC と Log Loss の違い
これまで分かったことから、AUC は「モデルの出力値のアイテム間の相対評価」を行っていることが分かります。2値分類の評価タスクには他にも有名なものとして、Log Loss がありますが、
LogLoss = - \frac{1}{N} \sum_{i=1}^N [y_i \mathrm{log} \ p_i + (1-y_i)\mathrm{log} (1-p_i)]
これは単一アイテムに対するモデルの出力値がラベルにどれだけ近いかを測る指標なので、ここに微妙な差がありお互いに異なる指標を測っていることが分かります。
対照的な言い方をするならば、Log Loss は「モデルの出力値の絶対的な精度」を測っているとも言えるかと思います。
AUC が良いのに Log Loss が悪いパターン
では、以上の解釈を踏まえて、AUC が良いのに Log Loss が悪いパターンというのを形式的に考えてみましょう。AUC は順序の保存性を測っているので、モデルの出力値の幅がどんなに狭くても順序が保存されていれば高い値になり得ます。極端な例としては、モデルの出力値がほぼ 0.99 近辺になっていても AUC は高くなり得るということですね。一方、 Log Loss にとっては上記のような例は好ましくありません。個々のアイテムに対するモデルの出力値とラベルの近さという観点では、負例(真)のアイテムにおいて Log Loss は悪化します。特に不均衡データなどで、正例が少なく負例が多いケースでは Log Loss は大きく悪化し得ることが分かります。
実際、このような極端な状況が起こる頻度はかなり少ないとは思いますが、評価指標はあくまでもモデルの性能の一側面を測っているに過ぎないということが分かる良い例のようにも思います。
終わりに
唐突に終わりますが、これでおわりです(久々に長文を書いて疲れた)(結びの言葉っぽいことを書こうかと思ったがポエムっぽくなりそうだったし、面倒くさくなった)。
皆さんも良い機械学習ライフを〜。