晚上好 我目前正在使用R中的nlminb()函数处理最大化问题.Heres是代码的一部分。这些是初始输入参数
w <- rnorm(12,0.5,1)
y <- 1:12
x <- rnorm(12,0,1)
h <- 0.25
n <- length(x)
g <- sd(x)
将从中评估参数的两个函数中的第一个
Resid <- function(par, data)
{
alpha.0 <- par[1]
alpha.1 <- par[2]
beta.1 <- par[3]
mu1 <- par[4]
mu2 <- par[5]
n <- length(x)
sigma.sqs <- numeric(n)
epsilon <- numeric(n)
sigma.sqs[1] <- g
epsilon[1] = x[1] - mean(x)
for(ii in c(1:(n-1))) {
sigma.sqs[ii + 1] <- (
alpha.0 +
alpha.1 * (epsilon[ii])^2 +
beta.1 * sigma.sqs[ii])
epsilon[ii+1] <- (x[ii+1]-mu1-mu2*x[ii])/sigma.sqs[ii]
Ksum <- 0
for(j in (1:(n-1))){
Ksum <- Ksum + (((epsilon[ii]/(sigma.sqs[ii]^0.5))-w[j])/h)
}
}
return(list(et = epsilon, ht = sigma.sqs, xt=Ksum))
}
第二部分,从函数Resid
中获取sigma和epsilons LogL <- function(par, data) {
res <- Resid(par, data)
sigma.sqs <- res$ht
epsilon <- res$et
f <- res$xt
return( 1/n * sum( log(1/(n*h)*(1/((2*pi)^0.5))*exp(-0.5*(f)^2)) + log(1/(sigma.sqs^0.5))))
}
并最终最大化
o <- nlminb(start=c(0.001,0.001,0.001,0.001,0.001), objective= LogL, lower= 0.0000001 )
print(o)
代码运行,但它提出了NaNs。问题似乎出现在for-loop regaring
中 Ksum <- 0
for(j in (1:(n-1))){
Ksum <- Ksum + (((epsilon[ii]/(sigma.sqs[ii]^0.5))-w[j])/h)
}
循环应该计算Ksum的向量,每x个一个。我一直在试图找出问题所在,但我已经对解决方案视而不见了。
有什么想法吗?
干杯
答案 0 :(得分:1)
实际上,看起来你的问题出现在LogL函数中。这似乎是第一个NaN值出现的地方,它们似乎来自exp(-0.5*(f)^2)
由Ksum
值生成的术语。问题(至少当我运行它时)是f变小到R返回exp(-0.5*(-313.5329)^2)=0
,然后你记录了你得到NaN值的日志。
因此,为了使其在数值上更稳定,我使用log(a*b)=log(a)+log(b)
来重写函数。你想要验证我写的在数学上是否相同,但似乎不太可能产生越界问题。
return( 1/n * sum(
log( 1/(n*h) ) + log( 1/(2*pi)^0.5 ) + -0.5*(f)^2 +
log(1/(sigma.sqs^0.5))
))
答案 1 :(得分:0)
你说你想要循环来计算Ksum的矢量,每x个一个。
你的循环实际上做的是为每个x计算一次标量Ksum,每次重写它,然后将最终x生成的单个Ksum值传递给LogL函数。
看起来你需要改变
Ksum <- 0
到
Ksum <- numeric(n)
并将该行代码移到较大的for循环for(ii in c(1:(n-1)))
之外,这样您就不会在x的每个新值中覆盖计算值。
您还需要更改此行
Ksum <- Ksum + (((epsilon[ii]/(sigma.sqs[ii]^0.5))-w[j])/h)
引用你想要的任何索引,例如
Ksum[ii] <- Ksum[ii] + (((epsilon[ii]/(sigma.sqs[ii]^0.5))-w[j])/h)
希望这有帮助。