- 複数の因子が多項(二項を含む)の生起確率に影響を与えるらしい
- サンプルについて因子を観察して生起を観察し、それに基づいて、新規サンプルについて因子を測定して、生起を予測したいというような場合
- パラメトリックにやるのもありだけれど、高次元化したりするとたちまち厄介になるのでノンパラでやってみたい
- 高次元空間のpoint cloudの密度推定にkNNを用いたことがある
- それを使う
- 近隣について多項の観測度数を数え上げていく
- 近傍に関して生起確率ベクトルが一定であるとみなすなら、k近傍までの度数から推定されるディリクレ分布の信頼区間はkを増やすことで狭くなるが、信頼区間がkによって外れることは少ないだろうことを基にする
- もしk近傍のkが大きくなり、もはや生起確率ベクトルが一定でないとすると、そのときには、k近傍までの集計の度数からの推定がそれまでのkの推定の信頼区間から外れそうだから、それをもって、生起確率ベクトルが一定であるだろうとするkの上限とすることにする
- このようにkの値を大きくとることで推定するディリクレ分布のピークを大きくする
- やってみる
- 空間に偏りをもって分布する母集団があり、その空間には多項生起確率ベクトルの場があるものとする
- 左上は観測標本における、「真の生起確率」
- 左中は、観測標本の「生起」
- 左下は、知りたい点(これも母集団分布に従っている)における「真の生起確率」
- 中上は、知りたい点の「推定生起確率」
- 中中は、知りたい点の「真と推定の相関」
- 中下は、知りたい点の「真と推定の確率の差」をドットの大小で表したもの
- 右上と右中は、知りたい点の真の値と、推定値(期待値とそのベータ―分布の2.5,97.5パーセンタイル)。右上は真の値でソートしたもの、右中は推定期待値でソートしたもの
library(MCMCpack)
my.beta.2moment <- function(a,b,z){
a*(a+1)/(a+b)/(a+b+1)-2*z*a/(a+b)+z^2
}
my.dirichlet.mean <- function(as){
as/sum(as)
}
my.dirichlet.var <- function(as){
sum.as <- sum(as)
as * (sum.as-as)/(sum.as^2 * (sum.as+1))
}
my.dirichlet.2moment <- function(as,t=0){
m <- my.dirichlet.mean(as)
my.dirichlet.var(as)+m^2-2*m*t+t^2
}
my.Dirichlet.knn.conf <- function(D,X,Y,Y.level,mm="est",r.n=100,q=0.95,n.mc=100,est=FALSE,self=TRUE){
qs <- sort(c((1-q)/2,1-(1-q)/2))
n.x <- length(X[1,])
n.y <- length(Y.level)
n.sample <- length(Y)
n.cnt <- length(D[,1])
D.mat <- t(apply(D,1,my.dist.mat,X))
rs <- seq(from=0,to=max(D.mat),length=r.n)
if(!self){
D.mat[which(D.mat==0)] <- max(D.mat)+1
}
D.ord <- t(apply(D.mat,1,order))
D.level.ord <- array(0,c(n.cnt,n.sample,n.y+1))
for(i in 1:n.cnt){
for(j in 1:n.y){
D.level.ord[i,which(Y[D.ord[i,]]==Y.level[j]),j] <- 1
}
D.level.ord[i,,n.y+1] <- 1
D.level.ord[i,,] <- apply(D.level.ord[i,,],2,cumsum)
}
Est <- Mode <- array(0,c(n.cnt,n.sample,n.y))
for(i in 1:n.cnt){
Est[i,,] <- (D.level.ord[i,,1:n.y]+1)/(D.level.ord[i,,n.y+1]+n.y)
Mode[i,,] <- (D.level.ord[i,,1:n.y])/D.level.ord[i,,n.y+1]
}
K <- rep(1,n.cnt)
if(mm=="mode"){
MM <- Mode
}else{
MM <- Est
}
for(i in 1:n.cnt){
loop <- TRUE
for(j in 2:n.sample){
for(j2 in 1:j){
if(n.y==2){
tmp.LU <- qbeta(qs,D.level.ord[i,j2,1]+1,D.level.ord[i,j2,2]+1)
if(prod(tmp.LU-MM[i,j,1])>0){
loop <- FALSE
break
}else{
K[i] <- j2
}
}else{
tmp.q <- my.qdirichlet(MM[i,j,],D.level.ord[i,j2,1:n.y]+1,n.mc)
if(tmp.q>q){
break
}else{
K[i] <- j2
}
}
}
if(!loop){
break
}
}
}
return(list(X=X,D=D,Y=Y,n.sample=n.sample,n.cnt=n.cnt,D.level.ord=D.level.ord,Est=Est,Mode=Mode,K=K))
}
my.qdirichlet <- function(v,a,n=10000){
r <- rdirichlet(n,a)
d <- ddirichlet(r,a)
d0 <- ddirichlet(v,a)
length(which(d>=d0))/n
}
my.Dirichlet.knn <- function(X,Y,Y.level,r.n=100,est=FALSE,self=TRUE){
n.x <- length(X[1,])
n.y <- length(Y.level)
n.sample <- length(Y)
D.mat <- as.matrix(dist(X))
rs <- seq(from=0,to=max(D.mat),length=r.n)
if(!self){
D.mat[which(D.mat==0)] <- max(D.mat)+1
}
D.ord <- t(apply(D.mat,1,order))
D.level.ord <- array(0,c(n.sample,n.sample,n.y+1))
for(i in 1:n.sample){
for(j in 1:n.y){
D.level.ord[i,which(Y[D.ord[i,]]==Y.level[j]),j] <- 1
}
D.level.ord[i,,n.y+1] <- 1
D.level.ord[i,,] <- apply(D.level.ord[i,,],2,cumsum)
}
LL.r <- rep(0,length(rs))
D.within <- matrix(0,length(rs),n.sample)
for(i in 1:length(rs)){
tmp <- apply((D.mat <= rs[i]),2,sum)
D.within[i,] <- tmp
}
cnt.r <- array(0,c(n.sample,length(rs),n.y+1))
for(i in 1:n.sample){
for(j in 1:length(rs)){
tmp <- D.within[j,i]
if(tmp>0){
cnt.r[i,j,] <- D.level.ord[i,D.within[j,i],]
}
}
}
for(i in 1:length(rs)){
for(j in 1:n.sample){
tmp.level <- which(Y.level==Y[j])
v <- cnt.r[j,i,1:n.y]
LL.r[i] <- LL.r[i] + log(dmultinom(v/sum(v),prob=(v+1)/sum(v+length(v))))
}
}
L.r <- exp(LL.r-max(LL.r))
L.r <- L.r/sum(L.r)
Est <- Var <- c()
if(est){
Est <- matrix(0,n.sample,n.y)
for(i in 1:n.sample){
for(j in 1:length(rs)){
Est[i,] <- Est[i,] + L.r[j] * my.dirichlet.mean(cnt.r[i,j,1:n.y]+1)
}
}
Var <- matrix(0,n.sample,n.y)
for(i in 1:n.sample){
for(j in 1:length(rs)){
Var[i,] <- Var[i,] + L.r[j] * my.dirichlet.2moment(cnt.r[i,j,1:n.y]+1,Est[i,])
}
}
}
return(list(X=X,Y=Y,L.r=L.r,rs=rs,Est=Est,Var=Var,cnt.r=cnt.r,n.x=n.x,n.y=n.y,n.sample=n.sample))
}
my.dist.mat <- function(x,X){
d <- length(x)
tmp <- t(t(X)-x)
sqrt(apply(tmp^2,1,sum))
}
my.dirichlet.est <- function(X.r,d.knn.out){
Est <- Var <- c()
X <- X.r
n.sample <- d.knn.out$n.sample
n.pnt <- length(X[,1])
n.y <- d.knn.out$n.y
rs <- d.knn.out$rs
L.r <- d.knn.out$L.r
cnt.r <- d.knn.out$cnt.r
Est <- matrix(0,n.pnt,n.y)
D.mat <- t(apply(X,1,my.dist.mat,d.knn.out$X))
D.ord <- t(apply(D.mat,1,order))
D.level.ord <- array(0,c(n.pnt,n.sample,n.y+1))
for(i in 1:n.pnt){
for(j in 1:n.y){
D.level.ord[i,which(Y[D.ord[i,]]==Y.level[j]),j] <- 1
}
D.level.ord[i,,n.y+1] <- 1
D.level.ord[i,,] <- apply(D.level.ord[i,,],2,cumsum)
}
LL.r <- rep(0,length(rs))
D.within <- matrix(0,length(rs),n.pnt)
for(i in 1:length(rs)){
tmp <- apply((D.mat <= rs[i]),1,sum)
D.within[i,] <- tmp
}
cnt.r <- array(0,c(n.pnt,length(rs),n.y+1))
for(i in 1:n.pnt){
for(j in 1:length(rs)){
tmp <- D.within[i,j]
if(tmp>0){
cnt.r[i,j,] <- D.level.ord[i,D.within[i,j],]
}
}
}
for(i in 1:n.pnt){
for(j in 1:length(rs)){
Est[i,] <- Est[i,] + L.r[j] * my.dirichlet.mean(cnt.r[i,j,1:n.y]+1)
}
}
Var <- matrix(0,n.pnt,n.y)
for(i in 1:n.pnt){
for(j in 1:length(rs)){
Var[i,] <- Var[i,] + L.r[j] * my.dirichlet.2moment(cnt.r[i,j,1:n.y]+1,Est[i,])
}
}
return(list(Est=Est,Var=Var))
}
n.x <- 3
n.x.a <- 2
n.y <- 2
Y.level <- 1:n.y
n.d <- 3
library(MCMCpack)
r <- rdirichlet(1,rep(1,n.d))
k.ctr <- 10
k.sd <- k.ctr/2
ctrs <- matrix(rnorm(n.d*n.x)*k.ctr,ncol=n.x)
sds <- matrix(runif(n.d*n.x)*k.sd,ncol=n.x)
k1 <- runif(1)
K1 <- 0.8
k2 <- 1
k3 <- runif(1) * (1-k1)
my.calc.p <- function(x,k1,k2,k3){
k1 * (sin(k2*sqrt(sum(x^2)))+1)/2+k3
}
n.s <- 500
X <- matrix(0,0,n.x)
Y <- rep(0,n.s)
r.d <- c(rmultinom(1,size=n.s,prob=r))
for(i in 1:n.d){
tmp <- matrix(0,r.d[i],0)
for(j in 1:n.x){
tmp <- cbind(tmp,rnorm(r.d[i],ctrs[i,j],sds[i,j]))
}
X <- rbind(X,tmp)
}
P <- apply(X[,1:n.x.a],1,my.calc.p,k1,k2,k3)
for(i in 1:n.s){
Y[i] <- sample(1:n.y,1,prob=c(P[i],1-P[i]))
}
plot(X[,1:2],col=Y)
est <- FALSE
n.r.pt <- 800
X.random <- matrix(0,0,n.x)
r.d <- c(rmultinom(1,size=n.r.pt,prob=r))
for(i in 1:n.d){
tmp <- matrix(0,r.d[i],0)
for(j in 1:n.x){
tmp <- cbind(tmp,rnorm(r.d[i],ctrs[i,j],sds[i,j]))
}
X.random <- rbind(X.random,tmp)
}
true.pr <- apply(X.random[,1:n.x.a],1,my.calc.p,k1,k2,k3)
matplot(cbind(c(true.pr),c(est.pr),c(est.pr+2*sqrt(est.var)),c(est.pr-2*sqrt(est.var)))[ord,],type="p",cex=0.1)
conf.out <- my.Dirichlet.knn.conf(X.random,X,Y,Y.level,r.n=100,q=0.75,n.mc=100,est=FALSE,self=TRUE)
conf.out$K
conf.ok <- rep(0,conf.out$n.cnt)
est.pr <- est.var <- est.L <- est.U <- conf.ok
for(i in 1:conf.out$n.cnt){
plot(ps,dbeta(ps,conf.out$D.level.ord[i,conf.out$K[i],1]+1,conf.out$D.level.ord[i,conf.out$K[i],2]+1))
abline(v=true.pr[i],col=2)
conf.ok[i] <- pbeta(true.pr[i],conf.out$D.level.ord[i,conf.out$K[i],1]+1,conf.out$D.level.ord[i,conf.out$K[i],2]+1)
est.pr[i] <- (conf.out$D.level.ord[i,conf.out$K[i],1]+1)/(conf.out$D.level.ord[i,conf.out$K[i],1]+1+conf.out$D.level.ord[i,conf.out$K[i],2]+1)
est.var[i] <- (conf.out$D.level.ord[i,conf.out$K[i],1]+1)*(conf.out$D.level.ord[i,conf.out$K[i],2]+1)/((conf.out$D.level.ord[i,conf.out$K[i],1]+1)+(conf.out$D.level.ord[i,conf.out$K[i],2]+1))^2*((conf.out$D.level.ord[i,conf.out$K[i],1]+1)+(conf.out$D.level.ord[i,conf.out$K[i],1]+1)+1)
est.L[i] <- qbeta(0.025,conf.out$D.level.ord[i,conf.out$K[i],1]+1,conf.out$D.level.ord[i,conf.out$K[i],2]+1)
est.U[i] <- qbeta(0.925,conf.out$D.level.ord[i,conf.out$K[i],1]+1,conf.out$D.level.ord[i,conf.out$K[i],2]+1)
}
ord <- order(true.pr)
matplot(cbind(true.pr[ord],est.pr[ord],est.L[ord],est.U[ord]),type="l")
par(ask=FALSE)
plot(true.pr,est.pr)
plot(true.pr,est.pr,xlim=c(0,1),ylim=c(0,1))
hist(conf.ok)
plot(sort(conf.ok))
length(which(conf.ok<0.025))
length(which(conf.ok>0.975))
length(conf.ok)
par(mfcol=c(3,3))
plot(X,col=rgb(P,0,1-P),pch=20,main="データ点の真の確率")
plot(X,col=Y,pch=20,main="データ点の生起0/1")
plot(X.random,col=rgb(true.pr,0,1-true.pr),pch=20,main="知りたい点の真の生起確率")
plot(X.random,col=rgb(est.pr,0,1-est.pr),pch=20,main="知りたい点の推定生起確率")
plot(true.pr,est.pr,main="真の生起確率と推定確率",xlim=c(0,1),ylim=c(0,1))
tmp <- abs((true.pr-est.pr))
plot(X.random,cex=tmp*5,pch=20,main="真の確率と推定確率の差")
ord <- order(true.pr)
matplot(cbind(true.pr[ord],est.pr[ord],est.L[ord],est.U[ord]),type="l",main="真の確率と推定確率とその推定信頼区間1")
ord <- order(est.pr)
matplot(cbind(true.pr[ord],est.pr[ord],est.L[ord],est.U[ord]),type="l",main="真の確率と推定確率とその推定信頼区間1")
par(mfcol=c(1,1))