我正在尝试使用metropolis-hastings算法编写一个程序来估计AR(1)系数。我的R代码如下,
set.seed(101)
#loglikelihood
logl <- function(b,data) {
ly = length(data)
-sum(dnorm(data[-1],b[1]+b[2]*data[1:(ly-1)],(b[3])^2,log=TRUE))
}
#proposal function
proposalfunction <- function(param,s){
return(rnorm(3,mean = param, sd= s))
}
#MH sampler
MCMC <- function(startvalue, iterations,data,s){
i=1
chain = array(dim = c(iterations+1,3))
chain[i,] = startvalue
while (i <= iterations){
proposal = proposalfunction(chain[i,],s)
probab = exp(logl(proposal,data = data) - logl(chain[i,],data = data))
if(!is.na(probab)){
if (runif(1) <= min(1,probab)){
chain[i+1,] = proposal
}else{
chain[i+1,] = chain[i,]
}
i=i+1
}else{
cat('\r !')
}
}
acceptance = round((1-mean(duplicated(chain)))*100,1)
print(acceptance)
return(chain)
}
#example
#generating data
data <- arima.sim(list(order = c(1,0,0), ar = 0.7), n = 2000,sd = sqrt(1))
r=MCMC(c(0,.7,1),50000,data,s=.00085)
在这个例子中,我必须得到平均值为零,系数为0.7,误差方差为1。但每次运行此代码时,我都会得到完全不同的值。我试图调整提案规模,但我仍然得到远远不是真实值的结果。下图显示了结果。
答案 0 :(得分:2)
您已在日志似然功能中翻转了该符号。这是一个容易犯的错误,因为最大似然估计通常通过最小化负对数似然来进行,但MCMC中的要求是使用似然本身(而不是它的逆)。
此外:
dnorm()
将标准偏差作为其第三个参数,而不是方差。您可以使用head(data,-1)
来简化代码,以获取向量中除最后一个元素之外的所有元素。所以你的对数可能性是:sum(dnorm(data[-1],b[1]+b[2]*head(data,-1),b[3],log=TRUE))