使用Metropolis-Hastings算法(MCMC)模拟Probit模型

时间:2017-01-09 22:44:48

标签: r statistics bayesian mcmc

我在R工作,这是我的代码:

n <- 1000
trueB0 <- 0
trueB1 <- 0.1
prior.mean0 <- 0
prior.sd0 <- 10
prior.mean1 <- 0
prior.sd1 <- 10

x <- rnorm( n, 0, 1 )
eta <- trueB0 + trueB1 * x
P <- pnorm(eta)
Y <- rbinom(n, 1, P)

prior <- function(param){
  b0=param[1]
  b1=param[2]
  B0prior <- dnorm(b0, mean = prior.mean0, sd = prior.sd0, log = T)
  B1prior <- dnorm(b1, mean = prior.mean1, sd = prior.sd1, log = T)
  return(B0prior + B1prior)
}

likelihood <- function(param){
  b0=param[1]
  b1=param[2]
  eta.l <- b0 + b1 * x
  P.l <- pnorm(eta.l)
  singlelikelihoods = dbinom(Y, 1, P.l, log = T)
  sumall=sum(singlelikelihoods)
  return(sumall)
}

posterior <- function(param){
  return(prior(param)+likelihood(param))
}

rho <- 0
sd0 <- 1
sd1 <- 1
sigma <- matrix(c(sd0^2, sd0*sd1*rho, sd0*sd1*rho, sd1^2), ncol = 2)

proposalfunction <- function(param){
  return(rmvnorm(1, mean = param, sigma))
}

q <- function(m1, m2){
  return(dmvnorm(m1, mean = m2, sigma, log = T))
}

run_metropolis_MCMC <- function(initialvalue, iterations){
  chain = array(dim = c(iterations+1,2))
  chain[1,] = initialvalue
  for (i in 1:iterations){
    proposal = proposalfunction(chain[i, ])
    #bug here in the q evaluatoin part
    alpha = exp(posterior(proposal) - posterior(chain[i, ]) + q(chain[i, ], proposal) - q(proposal, chain[i, ]))
    if (runif(1) < min(1,alpha)) 
    {
      chain[i+1,] = proposal
    }
    else
    {
      chain[i+1,] = chain[i,]
    }
  }  
  return(chain)
}

initialvalue <- c(0 , 0.1)
iterations <- 10000
MH = run_metropolis_MCMC(initialvalue, iterations)

我想问题是,当计算MH部分的alpha时,我应该得到q(beta | beta *)/ q(beta * | beta)(q是提议函数,beta是当前的链值和beta *是q使用beta生成的值。 但是我无法弄清楚如何在R代码中获取它。 (我知道q应该是一个双变量正态分布密度,但我不知道如何在函数中实现beta和beta *并得到q的评估)

1 个答案:

答案 0 :(得分:1)

我运行你的代码,如果我添加库(mvtnorm),我在q评估中没有任何错误。我真的很困惑你的问题是什么,因为你的q函数给出了这样的:q(chain [i,],proposal)= q(beta | beta *)对于双变量法线(它给出了对数密度)。

您的代码的一些一般性评论:

  • runif(1)&lt; min(1,alpha)与runif(1)&lt;阿尔法

  • 如果您的代码计算了已接受提案的数量,那就太好了,所以您知道它的百分比。如果该百分比很小,则您的提案sd很大,反之亦然。在for循环之前添加n.accept&lt; -0,在第一个if语句添加n.accept&lt; - n.accept + 1。然后在返回之前添加

    print(c(“接受的百分比为beta测试绘制:”,100 * n.accept / iterations))

如果有帮助,请将此答案标记为已接受。