R
機械学習
統計学

2つの予測モデルどっちが良いの?(AUCの差の検定)

More than 1 year has passed since last update.

この記事は何?

機械学習を用いて構築された予測モデルの評価には,ROC曲線下面積(AUC)を用いることがよくあります.
例えば,SVMによる予測モデルとRandom Forestによる予測モデルの2つを構築し,どちらがより精度の高い予測モデルであるかをAUCによって評価するといったことが考えられます.
単純に考えればAUCが高い方が良い予測モデルなのですが,そのAUCの差は本当に2つの予測モデルの性能の差によるものなのか,それとも偶然生まれた差なのかを考えてみたいと思います.
これは確率統計における検定の知識を使えば良いのですが,AUCの差の検定の日本語の資料があまり無く理解につまずきました.
そこでこの記事では,AUCの差の検定の理論を理解するためのヒントおよびRを用いた検定の方法について解説します.

AUCの差の検定

統計量

2つの予測モデルAとBによって,AUC(A)とAUC(B)が得られたとします.
AUCの差の検定では,以下の式で表される$z$が標準正規分布に従うことを用います.

z = \frac{{\rm AUC(A)}-{\rm AUC(B)}}{\sqrt{V_A+V_B-2S_{AB}}}

ここで,$V_A$,$V_B$はそれぞれAUC(A),AUC(B)の分散を,$S_{AB}$はAUC(A)とAUC(B)の共分散を表します.

$V_A$($V_B$も同様ですが)は以下のように計算されます.

\psi(X,Y)=\begin{cases}1 & X>Y \\ \frac{1}{2} & X=Y \\ 0 & X<Y \end{cases}\\
V_A=\frac{1}{m(m-1)}\sum_{i=1}^{m}{\left(\frac{1}{n}\sum_{j=1}^{n}\psi(X_i^A,Y_j^A)-{\rm AUC(A)}\right)^2} \\
+\frac{1}{n(n-1)}\sum_{j=1}^{n}{\left(\frac{1}{m}\sum_{i=1}^{m}\psi(X_i^A,Y_j^A)-{\rm AUC(A)}\right)^2}

ここで,予測モデルAによる,データセットの正例に対する予測値を$X_i^A (i=1,\cdots ,m)$,負例に対する予測値を$Y_j^A(j=1,\cdots ,n)$としました.
また,$S_{AB}$は以下のように計算されます.

S_{AB}=\frac{1}{m(m-1)}\sum_{i=1}^{m}\left(\frac{1}{n}\sum_{j=1}^{n}\psi(X_i^A,Y_j^A)-{\rm AUC(A)}\right)\left(\frac{1}{n}\sum_{j=1}^{n}\psi(X_i^B,Y_j^B)-{\rm AUC(B)}\right) \\
+ \frac{1}{n(n-1)}\sum_{j=1}^{n}\left(\frac{1}{m}\sum_{i=1}^{m}\psi(X_i^A,Y_j^A)-{\rm AUC(A)}\right)\left(\frac{1}{m}\sum_{i=1}^{m}\psi(X_i^B,Y_j^B)-{\rm AUC(B)}\right)

検定

2つの予測モデルによるAUCの差が性能の差によるものなのか,それとも偶然生まれた差なのかを調べるために両側検定を行うことを考えます.
つまり,帰無仮説および対立仮説はそれぞれ

H_0: {\rm AUC(A)}={\rm AUC(B)} \\ H_1: {\rm AUC(A)}\neq {\rm AUC(B)}

で与えられます.

上で求められる$z$の値を用いて,下図の標準正規分布の両側面積を求め,有意水準と比較して有意かどうかを確認します.
normz.png

RによるAUCの差の検定

Rの"pROC"というパッケージにAUCの差の検定が実装されています.
以下のデータセットについてAUCの差の検定を行いたいと思います.

label,A,B
1,0.8,0.7
1,0.6,0.2
1,0.5,-0.4
1,-0.2,0.5
1,0.4,0.3
1,-1.2,-0.7
0,0.1,0.4
0,-0.3,-1.2
0,-1.0,-0.1

labelの列の1は正例,0は負例を表します.
A,Bの列はそれぞれ予測モデルAによる予測値,Bによる予測値を表します.

以下のRスクリプトを実行すると,AUCおよびp値を算出することができます.

library(pROC)
data <- read.csv("test_data.csv")
rocA <- roc(data$label, data$A)
rocB <- roc(data$label, data$B)
print(roc.test(rocA, rocB))

実行結果は以下のようになりました.

    DeLong's test for two correlated ROC curves

data:  rocA and rocB
Z = 0.50855, p-value = 0.6111
alternative hypothesis: true difference in AUC is not equal to 0
sample estimates:
AUC of roc1 AUC of roc2 
  0.8333333   0.7500000 

予測モデルAによるAUCは0.83,BによるAUCは0.75となり,予測モデルAによるAUCの方が高い値となりました.
しかし,p値を見ると0.6111とあり,これはとても有意とは言えません(データセットの要素数が少なすぎるのですが…).

その他

両側検定と片側検定はどちらを行うべきなのか悩ましいです.

roc.test(rocA, rocB, alternative="greater")

とすることで,片側検定も行えます.

参考文献