読者です 読者をやめる 読者になる 読者になる

東京に棲む日々

データ分析、統計、ITを勉強中。未だ世に出ず。

モデル評価基準 追加 - リフトチャートに関して2 - R{ROCR}

highschoolstudent.hatenablog.com

highschoolstudent.hatenablog.com

 

上2つの記事に関連した追加。


そもそもリフトチャートと呼ばれるものは定義があいまいなようで、人によって使っているものが細かく違ったりする。

基本的に似たようなものであるのだが、”モデル評価基準 追加 - リフトチャートに関して2 - R{ROCR}”で作成したのとまたちょっと違ったリフトチャートを描いてみる。

 

業務上、このチャートを標準とすることとなった。確かに、シンプルで理解もしやすいのでお勧め。


以下の手順で作成できる。
1.予測値を小さいものから順に並べる。
2.いくつかのグループに分ける。(今回の19行のデータ数ではグループ数を大きくできないが、10とか20グループに分けるやり方が良く使われるらしい。)各グループ内でのデータ数(行数)は等しい。(必ずしも割り切れる訳ではないので、適当な調整を加える。)
3.各グループでの観測値の平均値を計算する。(観測値は0/1なので、各グループでの1の割合が計算される。)
4.横軸をグループ番号、縦軸を3.で計算した観測値の平均値をプロットする。すべての観測値での平均値もプロットしておくとグラフが理解しやすい。


データはこれまでと同じものを使用。
d_roc1 <- read.delim("clipboard", header=TRUE)
d_roc1

 

   pred1 pred2 observed
1   0.95  0.90        1
2   0.90  0.80        1
3   0.80  0.75        1
4   0.60  0.70        1
5   0.50  0.60        1
6   0.85  0.95        0
7   0.75  0.85        0
8   0.70  0.65        0
9   0.65  0.55        0
10  0.55  0.50        0
11  0.45  0.45        0
12  0.40  0.40        0
13  0.35  0.35        0
14  0.30  0.30        0
15  0.25  0.25        0
16  0.20  0.20        0
17  0.15  0.15        0
18  0.10  0.10        0
19  0.05  0.05        0

 

関数を定義する。 

fn_plot_Lift20bins <- function(pred, obs, aveline=TRUE, nbins=20, color="black"){
    df0 <- data.frame(pred=pred, obs=obs)
    df1 <- df0[order(df0$pred),]
    n <- nrow(df1)

    if(nbins*2>n) {stop(">>> Set smaller nbin. nbins*2 <= nrow")}

    meanobs <- mean(df1$obs)
    nrep <- floor(n/nbins)    # 各binに入る行数
    ndup <- n-nbins*nrep    # nbinでnが割り切れない場合の対処

    bin <- c()
    for(i in 1:nbins){
        if(i<=ndup){ bin <- c(bin, rep(i, nrep+1)) }    # nbinでnが割り切れない場合,最初のbinに1つづつ加えていく
        else{ bin <- c(bin, rep(i, nrep)) }
    }

    df2 <- data.frame(df1, bin=bin)
    #print( df2 )

    ratio <- tapply(df2$obs, df2$bin, mean)

    df3 <- data.frame(bin=1:nbins, ratio)
    print( df3 )

    plot( df3$bin, df3$ratio, type="b" , xlab="Bin", ylab="Ratio", col=color)
    abline(h=meanobs, col="yellow")
    abline( v=1:nbins, lty=3 )
}

 

pred: モデル予測値のベクトル

obs: 観測値のベクトル

aveline: 全観測値の平均線をプロットするかどうか

nbins: グループ数(データ数に対し大きいとエラーになる)

color: 線の色

 

pred1に対するリフトチャート。

fn_plot_Lift20bins(pred=d_roc1$pred1, obs=d_roc1$observed, aveline=TRUE, nbins=5)

  bin     ratio
1   1 0.0000000
2   2 0.0000000
3   3 0.5000000
4   4 0.2500000
5   5 0.6666667

f:id:High_School_Student:20150919145100j:plain


5グループに分けたので、各グループは3か4のデータ数となっている。(4*4+3*1=19)

各グループでの観測値の平均のデータフレームを表示し、それのプロットも出力される。
黄色の横線は、全観測値での平均値。

低い方から並べていっているので、基本的に右上がりのグラフとなる。

良いモデルでは、このリフトチャートは単調増加(monotone increasing)でカーブが急なものとなる。

今回の5グループのプロットだと、途中で平均値が落ちてしまっているが、3グループくらいにして、グループ内でのデータ数を確保すると単調増加のカーブになる。

 

定義した関数は重ね描きには対応してないので、今後修正の必要あり。

 

以上。