- 2つの選択肢があって、帰結が0/1であるときの決断方法について、ここなどで、選択肢が連続値で帰結も連続値であるときのことをここで書いた(そこではある変数によって定まる関数に関して積分する話があって、それは、functional integral 汎関数積分と呼ぶらしい。基本的にはそれは解析的には解けないらしい)
- 今日は、選択肢は連続値で帰結は0/1である場合にする(問題を簡単にしよう)
- 選択肢はx=[0,1]と有限範囲を仮定し、そのうえで、xの値に対して成功率を与える関数があるとする。たとえばこんな感じ。なんらかの規則はあるが、きれいな関数ではない、というようなそんなもの
true.p <- function(x){
ret <- x^2*0.6+0.2
s <- which(x<0.3)
ret[s] <- -(1-x[s])^2*(0.4-x[s])^3*(x[s]-0.8)*0.8+0.9
ret <- (sin(x*4*pi)+1)*0.3 +(x-0.4)^2
ss <- sample(1:length(x),length(x)*0.5)
ret[ss] <- sample(ret[ss])
ret
}
x <- seq(from=0,to=1,length=100)
p <- true.p(x)
plot(x,p)
- 背後にこんな成功率が潜んでいるけれど、まったくなんの情報もないところからスタートすることにする
- ある値xに関して、繰り返して帰結を観察すれば、その値xにおける成功率はベータ分布で考えても悪くないだろう
- 問題は、ある値xに繰り返して観察すると他の値xに関する情報が得られないこと
- その点を解決するために、xの範囲を適当にビンに区切って、そのビンごとに成功率が一定だという仮定をした上で、ベータ分布を想定してみることにする
- それを進める上で問題になるのは、ビンの幅をどうすればよいのか、ということ
- 1次元の量的データの場合に分布を図示方法としてヒストグラムがある。ヒストグラムの場合には、ビンの幅をどうするかの方法があってRではhist()関数の中にビン幅決めのデフォルト方法も実装してある
- 同様にdensity()関数にもある
- これらのビン幅決めルールを流用することにする
- 基本的には、このビン幅決めルールは、xの範囲に関して均等幅のビンを取る
- そのビン幅決め戦略は、ビン幅がだんだん狭くなっていくのだが、ビンが狭くなってそのビンにまったく帰結情報がない状態になると、そのビンの成功確率の分布は[0,1]で均等分布になることに留意する。情報のあるビンはどこも成功しにくいようなそんな真の成功率分布があるときには、このような「情報なしのビン」は相対的に選ばれやすくなり、帰結情報のないビンはなくなりがちになる。逆に、「情報ありのビン」の真の成功率が、高めのときは、情報のないビンは選ばれにくくなるが、情報ありのビンのxが繰り返し選ばれるときも、hist(),density()関数的には、ビンをどんどん狭くするわけではないから、情報なしビンが増えることは防止される
choose.bw <- function(x){
if(length(x)==1){
bw <- 2
}else{
d <- density(x)
bw <- d$bw
}
bw
}
choice.prob <- function(x,y,z=seq(from=0,to=1,length=100),n.trial=1000,silent=TRUE){
if(length(x)==0){
return(rep(1/length(z),length(z)))
}
bw <- choose.bw(x)
if(!silent){
if(length(which(y==1))>2){
plot(density(cbind(x,y)))
}
}
m <- matrix(0,length(z),2)
for(i in 1:length(z)){
st <- z[i]-bw/2
end <- z[i]+bw/2
selected <- which(x>=st & x< end)
m[i,1] <- length(which(y[selected]==0))
m[i,2] <- length(which(y[selected]==1))
}
R <- matrix(0,length(z),n.trial)
for(i in 1:length(z)){
R[i,] <- rbeta(n.trial,m[i,2]+1,m[i,1]+1)
}
ranks <- apply(R,2,rank,ties.method="max")
top.only <- ranks
top.only[which(top.only != length(z))] <- 0
top.only[which(top.only == length(z))] <- 1
s.top.only <- apply (top.only,2,sum)
s2.top.only <- t(t(top.only)/s.top.only)
s3.top.only <- apply(s2.top.only,1,sum)
s3.top.only/sum(s3.top.only)
}
n.iter <- 1000
x.history <- matrix(0,n.iter,2)
tmp.x <- runif(1)
tmp.p <- true.p(tmp.x)
x.history[1,1] <- tmp.x
x.history[1,2] <- sample(1:0,1,prob=c(tmp.p,1-tmp.p))
for(i in 2:n.iter){
z <- runif(100)
tmp.prob <- choice.prob(x.history[1:(i-1),1],x.history[1:(i-1),2],z,n.trial=100,silent=TRUE)
plot(z,tmp.prob,type="h")
tmp.x <- sample(z,1,prob=tmp.prob)
x.history[i,1] <- tmp.x
tmp.p <- true.p(tmp.x)
x.history[i,2] <- sample(1:0,1,prob=c(tmp.p,1-tmp.p))
}
par(mfcol=c(2,2))
plot(x.history)
plot(x,p)
plot(x.history[,1])
plot(cumsum(x.history[,2]))
abline(0,max(p),col=2)
abline(0,min(p),col=3)
abline(0,mean(p),col=4)
plot(true.p(x.history[,1]))