オッズ比が役立つ事例とは?
顧客ごとに広告を見たか見ていないかという説明変数群と、キャンペーンに応募したかどうかという目的変数(=アウトカム)からなるデータがあります。オッズ比は、「キャンペーンに応募」したのはどの広告を見た顧客なのか、どの広告がキャンペーン応募に影響を与えたのか、センサーとなる広告を見つけるために有効な指標の1つといえます。
入力データセット
1.ダミー変数のデータセット
- 目的変数、説明変数ともダミー変数
- 目的変数となる変数を最終列に配置し、それ以外は説明変数からなるデータセット。
2.変数ラベルデータ
対象とする広告の種類が膨大な場合、変数のラベルは別のファイルにします。idは列の番号です。
var_list.txt

アウトプットイメージ
- オッズ比の降順に並び替えています。
- 有意と判定された説明変数(要因)のみを抽出しています。
- オッズ比1以上、オッズ比の下限が1以上、かつp値が0.05以下。
- Epiパッケージのtwoby2関数を使っています(有意性検定はWald検定、有意水準は5%)。
結果の解釈
- オッズ比が2.631の広告:「無料サービス」で、この「無料サービス」を見なかった人に対して見た人は、2.63倍キャンペーンに応募した。
- 「無料サービス」のオッズ比は2.631と最も高いが、その信頼区間は1.19〜5.802と広い。信頼区間の幅が最も狭い(1.595-1.060=0.012)「モバイルゲーム」の広告のほうがオッズ比の値としては信頼できる(サンプルを別のものに変えても95%の確率でオッズ比が信頼区間内に収まる)。
- オッズ比が高く信頼区間の幅が狭い指標は、安定したセンサーとして活用できる。
解釈上の注意
- オッズ比の値だけでなく、オッズ比の信頼区間にも注意を払う必要があります。信頼区間の幅が広い変数のオッズ比は、その広告を見た人数が少ないことによって影響され過大に大きくなるためです。
- オッズ比が1は、その広告を見た人も見ていない人も、キャンペーンの応募率は同じであることを意味します。オッズ比が1以下は、広告を見た人は、見なかった人よりもキャンペーンに応募しなかった(負の相関がある)ことになります。ここで問題にしてるのは「応募した人」の特徴なので、負の相関となる1未満のケースは抽出対象から除きました。
Rスクリプト
calc_sig_or.R
# データの読み込み
df<-read.table("testdataset.tsv",header=T)
# 列の数をnに保存
n<-ncol(df)
# 変数名データの読み込み
var_list<-read.table("varname.txt",header=T)
# Epiパッケージを読み込みます。
library(Epi)
# アウトプットのマトリクスを用意.
out<-matrix(0,nrow=n,ncol=5)
k<-0
# new_planと他の変数との全てのオッズ比を求め、下限が1以上、有意なオッズ比のみ抽出する
for(i in 1:(n-1)){
#念のため、df3[,i]のカテゴリが1つだけではないことをチェック
#カテゴリが1つだけだと、2×2のクロス表にならないため。
if(length(table(df[,i]))==2)
{
#twoy2(要因となる変数、結果変数)
#結果変数は、campaign
res<-twoby2(df[,i],df$campaign)
#オッズ比
oddsr<-res$measures[2,1]
#信頼区間の下限
CI_l<-res$measures[2,2]
#信頼区間の上限
CI_U<-res$measure[2,3]
#p値
pval<-res$p.value
#オッズ比1以上、下限が1以上、p値が5%以下の場合、記録する
if(is.finite(oddsr) )
{
if( oddsr>=1 & CI_l >=1 & pval<=0.05){
k<-k+1
out[k,1]<-i
out[k,2]<-oddsr
out[k,3]<-CI_l
out[k,4]<-CI_U
out[k,5]<-pval
}
}
}
}
# 余計な列を削除
out<-out[1:k,]
# 出力用にデータフレームにする
out<-data.frame(out)
colnames(out)<-c("col_no","オッズ比","信頼区間下限","信頼区間上限","p値")
# 変数連番から変数名を紐付ける
out2<-merge(out,var_list,by.x="col_no",by.y="id",all.x=TRUE)
# オッズ比の降順に並べ替える
out3<-out2[order(out2$オッズ比,decreasing=T),]
# 出力する
write.table(out3,"目的変数_有意なオッズ比.txt",sep="\t",fileEncoding = "CP932",row.names = F)

