- 一昨日(こちら)、たくさんの受験者の結果を全部使うと、使わない場合より、個々人の真の正答力を、より正確に推定できるという話を書いた
- より正確に推定する方法をJames-Stein Estimatorと言った
- 「ふーん」と思いやすい例はないかと考えた
- こんな風に考える
- 今、ある科目について、設問に正解する確率というものを個人が持っていて、それを「真の正解力」と呼ぶことにする。
- 『私』がN問の試験を受けて、問正解したとする
- 『私』の真の正解力はと推定するのがよいだろう
- この試験を一人きりで受けていたら、これで話は終わりである。
- もし、一緒に受けていた友人がいて、その友人が「僕は問正解していたよ」と教えてくれたとしよう
- このとき、『私』の「真の正解力」はあいかわらずと推定するのがよい
- 2人目の友人が「問正解したよ」と教えてくれるとが『私』の真の正解力の推定値としておくのがよいかどうかに影響をうけはじめる。『私』の「真の正解力」はと考えるよりも、自分と友人とのみんなの平均点を考慮する方が「真の正解力」に近いことが多いことが知られている、というのがJames-Stein推定です
- 友達の多い『私』なので、3人目の友人が「だった」と教えてくれたとする。さらに影響をうける。
- 「『私』は友人と仲良しかもしれないが、正解力に関して関係ない」と思っても、完全に外れている場合(実は、自分はエイリアンだった、というくらいのはずれ具合)以外は、友人の正解数を参考にした方がよい、とこういうことである
- その様子を友人数を1人ずつ増やしつつ、「友人を考慮した推定値」が「真の正解力」に近づく様子をグラフにしてみる
- もちろん、1回の試験なので、どんなに友人数が増えても「真の正解力」に収束するわけではなく、1回だけの試験での『まぐれ』を発揮すれば、「真の正解力」をある程度隠ぺいできる
- ただし注意が必要
- 「友人」の結果を参考することで推定精度が上がる、というのは、すべての人について見渡した場合であって、特定の個人についての推定結果が必ずよくなるというわけではない
- 詳細は一昨日の記事(こちら)で
js.binom <- function(y,N){
n <- length(y)
x <- y/N
M <- mean(x)
a <- M*(1-M)/N
Inv.Aa <- (n-3)/sum((x-M)^2)
k <- 1-a*Inv.Aa
ret <- k*(x-M) + M
return(ret)
}
max.n <- 1000
thetas <-rbeta(max.n,1,2)
my.theta <- 0.7
Ns <- 1:100
est.js <- est.ml <- matrix(0,length(Ns),max.n+1)
test.result <- matrix(0,max.n+1,max(Ns))
test.result[1,] <-cumsum(sample(0:1,max(Ns),replace=TRUE,prob=c(1-my.theta,my.theta)))
for(i in 1:max.n){
test.result[i+1,] <-cumsum(sample(0:1,max(Ns),replace=TRUE,prob=c(1-thetas[i],thetas[i])))
}
EST.ML <- EST.JS <- matrix(0,max.n+1,max(Ns))
for(i in 1:(max.n+1)){
for(j in 1:max(Ns)){
EST.ML[i,j] <- test.result[1,j]/j
if(i<3){
EST.JS[i,j] <- EST.ML[i,j]
}else{
tmp <- js.binom(test.result[1:i,j],j)
EST.JS[i,j] <- tmp[1]
}
}
}
check.N <- 40
n.friend <- 100
matplot(0:n.friend,cbind(EST.ML[1:(n.friend+1),check.N],EST.JS[1:(n.friend+1),check.N]),type="l",ylim = range(c(my.theta,EST.ML[,check.N],EST.JS[,check.N])),xlab="友人数",ylab="得点力・推定値")
abline(h=my.theta,col=3)
legend(50, 0.74, c("得点率そのまま","JS推定値","真の得点力"), col = 1:3, lty = c(1,2,1))
head(EST.JS[,check.N])