2014年度マイコースプログラム

4回生K.K. @統計遺伝学分野

10月1日(水)

ロジスティック回帰モデル

3Dプロットは僕の理解の範疇を超えているようである。

意味が分からなさすぎて発狂しそうになったので、諦めてperspでグラフをつくってみた。

age <- c(18,21,22,25,26,28,33,34,35,37,42,47,55,56,58,61,65,68,75,77)
out <- c(0,0,0,0,0,0,0,0,0,0,1,1,0,1,0,1,1,1,1,1)

d <- cbind(age,out)

age.n <- d[which(d[,2]==0),1]
age.o <- d[which(d[,2]==1),1]

p.n <- function(a,x0){
1-1/(1+exp(-a*(age.n-x0)))
}

p.o <- function(a,x0){
1/(1+exp(-a*(age.o-x0)))
}

p <- function(a,x0){
prod(p.n(a,x0))*prod(p.o(a,x0))
}

a. <- seq(0,0.5,0.01)
x0. <- 20:70

z <- c()
for(i in a.)
for(j in x0.)
z <- c(z,p(i,j))
z. <- matrix(z,ncol=length(x0.),byrow=T)

persp(a.,x0.,z.,theta = 30)

f:id:kouri_don:20141001110724p:plain

また、max(z.)を調べたところ、a=0.3,x0=34のときに最も尤度が高くなることが分かった。
実際に係数をこれにしてグラフを描くと、

a <- 0.3
x0 <- 34

f <- function(x){
1/(1+exp(-a*(x-x0)))
}

plot(age,out,xlim=c(15,77),ylim=c(0,1),ylab="リスク",main="年齢とリスクの関係")

par(new=T)
curve(f,15,77,xlim=c(15,77),ylim=c(0,1),ann=F)

なるほど確かに、それらしい曲線が引けている。

なお、対数をとって微分する方法もやってみたのだが、うまく解が求められなかったので挫折した。
一応そういう方法もある、ということだけ頭に入れておこうと思う。

回帰モデルによる交絡の制御

回帰モデルの強みは、例えば曝露群と非曝露群とで年齢層が全く異なっていて、層化が使えないような場合でも統計量の推定が行えることである。
(ただし、モデルが合っている保証はないが)

曝露群、非曝露群で全く年齢層が異なっているデータを作って、曝露による効果の推定を行ってみた。

ここで、アウトカム= k0 + k1*(年齢)+ k2*(曝露の有無1or0)
(k0,k1,k2は定数)

というモデル式を設定した。

k0 <- 0.2
k1 <- 0.3
k2 <- 2

N <- 10000
n <- 100

out. <- function(x){
k0+k1*x[1]+k2*x[2]+rnorm(1)
}

a1.d <- sample(20:80,N,replace=T)
a2.d <- sample(0:1,N,replace=T)
a3.d <- apply(cbind(a1.d,a2.d),1,out.)

D <- cbind(a1.d,a2.d,a3.d)

d <- data.frame(D)

d.e <- d[sample(which(d[,1]<=50&d[,2]==1),n),]
d.n <- d[sample(which(d[,1]>50&d[,2]==0),n),]

plot(d.e[,1],d.e[,3],xlim=c(20,80),ylim=c(0,30))

par(new=T)
plot(d.n[,1],d.n[,3],xlim=c(20,80),ylim=c(0,30))

result.e <- lm(d.e[,3]~d.e[,1],data=d)
result.n <- lm(d.n[,3]~d.n[,1],data=d)

E <- result.e$coefficients[1]-result.n$coefficients[1]
E

> E
(Intercept) 
   1.736189 

このように、Rに装備されているlm()の利用によって推定値を出すことは出来た。

ただ、この場合年齢による効果(k2)は曝露によらず一定とするモデルで考えているので、その条件を加えて推定を行った方がよいと思われる。
そこで、自分で最小二乗法を利用してやってみた。
(もしかしたらRに装備されている関数で出来るのかもしれないが)

k0 <- 0.2
k1 <- 0.3
k2 <- 3

N <- 10000
n <- 100

out. <- function(x){
k0+k1*x[1]+k2*x[2]+rnorm(1)
}

a1.d <- sample(20:80,N,replace=T)
a2.d <- sample(0:1,N,replace=T)
a3.d <- apply(cbind(a1.d,a2.d),1,out.)

d <- cbind(a1.d,a2.d,a3.d)

x <- sample(which(d[,1]<=50&d[,2]==1),n)
x. <- sample(which(d[,1]>50&d[,2]==0),n)

age <- d[x,1]
age. <- d[x.,1]

f1 <- function(k1,b1){
k1*age+b1
}

f2 <- function(k1,b2){
k1*age.+b2
}

P <- function(X){
sum((d[x,3]-f1(X[1],X[2]))^2)+sum((d[x.,3]-f1(X[1],X[3]))^2)
}

P(c(0.3,0.2,3.2))

op <- optim(c(0.3,0.2,3.2),P)

E <- op$par[3]-op$par[2]
E

> E
[1] 6.1551

理論的には合ってるような気がするのだが、値がうまく合わない。
ちょっと理由が分からないので、明日また検討することにする。

以上