我需要对31000个观测值的数据集进行MLE估计,其中对数似然函数是自编码的。估计数据集有21个参数。为了进行估计,我在R.Hessian中使用带有newton-raphson方法的maxLik包,并且没有给函数本身提供对数似然函数的梯度。以下是数据读取和如何计算对数似然函数的方法。
[编辑@Patric,使用随机数据]
nObs <- 30000
nVeh <- runif(nObs, 1, 2)
adult1 <- runif(nObs, 0, 1)
adult2 <- runif(nObs, 0, 1)
adult3 <- runif(nObs, 0, 1)
adult4 <- runif(nObs, 0, 1)
params <- runif(21, 1, 4)
## Matrix to keep loglikelihood records for each observation
LL <- matrix (0, ncol=1, nrow=nObs)
logLik <- function(params){
for (i in 1:nObs){
V0 <- params[1]
V1 <- params[2] + params[6] * adult1[i] + params[10] * adult2[i] + params[14] * adult3[i] + params[18] * adult4[i]
V2 <- params[3] + params[7] * adult1[i] + params[11] * adult2[i] + params[15] * adult3[i] + params[19] * adult4[i]
V3 <- params[4] + params[8] * adult1[i] + params[12] * adult2[i] + params[16] * adult3[i] + params[20] * adult4[i]
V4 <- params[5] + params[9] * adult1[i] + params[13] * adult2[i] + params[17] * adult3[i] + params[21] * adult4[i]
vU <- matrix (c(V0, V1, V2, V3, V4), nrow = 1, ncol = 5)
pChosen <- exp(vU[min(nVeh[i] + 1,5)]) / sum(exp(vU))
LL[i] <- log(pChosen)
}
return(sum(LL))
}
system.time(logLik(params))
# user system elapsed
# 0.7 0.0 0.7
上面的代码运行得很慢。 MLE估计需要数天。因此,我根据分层随机抽样对数据进行了抽样,并将其从31000个观察值减少到5000个观察值。
然而,它仍然运行缓慢。因此,我决定使用doParallel和foreach库的后端函数来并行化对数似然函数中的循环。这是我为循环添加和更改的内容:
cl <- makeCluster(8)
registerDoParallel(cl)
..... some code here to read data ......
logLik <- function(params){
foreach (i=1:(nObs), .combine = "cbind") %do% {
...some more code content of log likelihood written above ...
}
return(sum(LL))
}
我不熟悉并行计算,我读了很多,并试图实现我在较小的函数示例中学到的东西。上述结构在相同的代码中工作,只有五个参数,假设V0,V1,V2,V3和V4都用常数定义。它在5分钟左右相对较快。然而,当我使用21个参数运行上述模型来估计5000个观测值的采样数据时,它再次非常缓慢。
还有其他方法可以让maxLik功能更快地运行吗?任何线索或提示,以及任何阅读材料,以更快的运行时间是值得赞赏的。我用搜索键“maxLik”,“在R中并行”等检查了网站,但我找不到建议或问题。
PS:由于没有样本数据,问题可能会出现负面影响,但由于机密性,我无法提供样本数据。
提前致谢