maxLik в R используется с doParallel и foreach для более быстрой реализации
Мне нужно сделать MLE-оценку для набора данных из 31000 наблюдений, с функцией логарифмического правдоподобия. Есть 21 параметр для оценки для набора данных. Для оценки я использую пакет maxLik с методом Ньютона-Рафсона в R. Hessian, а градиенты логарифмической функции правдоподобия не передаются самой функции. Вот как рассчитывается чтение данных и как вычисляется функция логарифмического правдоподобия.
[Редактировать @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: вопрос может быть отмечен отрицательно из-за отсутствия данных выборки, однако из-за конфиденциальности я не могу предоставить пример данных.
заранее спасибо