草薙の研究ログ

英語の先生をやってます。

1/0の正誤データから信号検出理論:Rの自作関数

背景

手元に判断課題のデータがあって,信号検出理論の指標を出したいとする。大概の信号検出理論指標は計算が簡単なのでExcelでもできるのだけど,大量データだと結構面倒くさい。

信号検出理論では,反応を4種類に分ける。

Hit, Miss, CR, FA。

これを数え上げるのも結構面倒くさい。

大概,判断課題データは,1/0の行列で保存している。

列は問題i,行は被験者j。これがもっとも基本的なはず。

これから一気にHit, Miss...などを数え上げて,d'やA',β,C,B'',対数オッズといった指標を計算したい。

Rでやろう。

 

面倒くさいからR関数作ったった

Rの関数を作った。

 

sdt<-function(res,key,correc=T,plot=T){
mp<-sum(key==1)
mn<-sum(key==0)
acc<-rowMeans(res)
rt<-function(x,key){
h<-sum(x[key==1]==1)
m<-sum(x[key==1]==0)
cr<-sum(x[key==0]==1)
fa<-sum(x[key==0]==0)
list(h,m,cr,fa)
}
t4<-data.frame(t(matrix(unlist(apply(res,1,FUN=rt,key)),4,length(res[,1]))))
colnames(t4)<-c("Hit","Miss","CR","FA")
r4<-data.frame(t4[,1:2]/mp,t4[,3:4]/mn)
if(correc==T){
r4[,1:2][r4[,1:2]==1]<-(mp-.5)/mp
r4[,1:2][r4[,1:2]==0]<-.5/mp
r4[,3:4][r4[,3:4]==1]<-(mn-.5)/mn
r4[,3:4][r4[,3:4]==0]<-.5/mn
}else{
}
p<-(t4[,1]+t4[,4])
n<-(t4[,2]+t4[,3])
rp<-(t4[,1]+t4[,4])/length(key)
rn<-(t4[,2]+t4[,3])/length(key)
posneg<-data.frame("Positive"=p,"Negative"=n,"Positive.Ratio"=rp,"Negative.Ratio"=rn)
d.prime<-qnorm(r4[,1])-qnorm(r4[,4])
criterion<-.5*(qnorm(r4[,1])+qnorm(r4[,4]))
beta<-exp(d.prime*criterion)
A.prime<-1/2+( (r4[,1]-r4[,4])*(1+r4[,1]-r4[,4])/(4*r4[,1]*(1-r4[,4])))
B<-(r4[,1]*(1-r4[,1])-r4[,4]*(1-r4[,4]))/(r4[,1]*(1-r4[,1])+r4[,4]*(1-r4[,4]))
logOR<-log(r4[,1]*r4[,4]/r4[,2]/r4[,3])
sdti<-data.frame(d.prime,A.prime,criterion,beta,B,logOR)
if(plot==T){
plot(r4[,4],r4[,1],xlim=c(0,1),ylim=c(0,1),xlab="FA Ratio",ylab="Hit Ratio",pch=20,cex=1.5,main="ROC Space")
for(i in 1:3){
lines(pnorm(seq(-4,4,.01),i,1),pnorm(seq(-4,4,.01),0,1),lty=2,col="blue")
}
for(j in 1:3){
lines(pnorm(seq(-4,4,.01),0,1),pnorm(seq(-4,4,.01),j,1),lty=2,col="blue")
}
abline(0,1,lty=2,col="blue")
}else{
}
list("Accuracy"=acc,"Reaction.Table"=t4,"Reaction.Ratio"=r4,"Positive.Negative"=posneg,"SDT.indecies"=sdti)
}

 

使い方

関数はsdt。

この引数は4つ。

まずは,1/0の正誤が入ったデータフレームか行列(res)。次に反応のキー(文法的/非文法的など)。こっちはベクトルなどを入れる。文法文が1問から5問で6から10が非文法文だったら,c(1,1,1,1,1,0,0,0,0,0)など。1がポジティブ(シグナル),0がネガティブ(ノイズ)というように。

ほかは修正(correc)の有無(T/F)。Hit Ratioなどが1や0のとき,信号検出理論指標は正しく計算出来ない。そのときのための修正をするかどうか。デフォルトはT。修正の方法は,

Macmillan, N. A., & Creelman, C.D. (2004). Detection Theory-A User s Guide. Lawrence Erlbaum Associates. 

によった。それ以外の方法はまあいいでしょう(実装していない)。最後はplotの有無(T/F)。TにするとROCに全被験者の反応を置く。デフォルトはT。

 

なので,基本的には,

sdt(dat, c(1,1,1,1,1,0,0,0,0,0))

とやればいい。

 

出力はリスト形式で,

  • 各被験者の正答率
  • HIts, Miss, CR, FAの集計
  • 上記の比率
  • ポジティブな反応(yesなど)とネガティブな反応数(noなど),その比率
  • 信号検出理論の指標(d', A', Criterion, β, B'', 対数オッズ)

1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
0 1 1 1 1 1 1 1 0 1
1 1 1 1 1 1 1 1 0 1
0 0 1 1 1 0 0 1 1 0
1 1 1 1 1 1 1 0 1 1
0 1 0 1 1 0 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 0 0 0 1 1
0 1 1 1 1 1 1 1 1 1

前5問がシグナル,残りがノイズとする。

これを読み込んで,datに入れる。

それで,

sdt(dat, c(1,1,1,1,1,0,0,0,0,0))

 とするだけでいい。全部出す。

プロットはこんな感じ。

f:id:kusanagik:20150813235419p:plain

点線はそれぞれd' = 1, 2, 3を示している。

よし。

こっちにも貼った。

信号検出理論指標計算エクセルシート - 草薙邦広のページ