Какой лучший способ ускорить симуляцию Монте-Карло?[закрыто]
-
05-07-2019 - |
Вопрос
Всякий раз, когда я запускаю крупномасштабное моделирование Монте-Карло в S-Plus, я всегда отращиваю бороду, пока жду его завершения.
Каковы лучшие приемы запуска моделирования Монте-Карло в R?Есть ли хорошие примеры запуска процессов распределенным образом?
Решение
Использование нескольких ядер/машин должно быть простым, если вы просто используете параллельные независимые репликации, но помните об распространенных недостатках генераторов случайных чисел (например,если использовать текущее время в качестве начального числа, создание множества процессов с одним ГСЧ для каждого может привести к созданию коррелированных случайных чисел, что приводит к неверные результаты - см. напр. Эта бумага)
Возможно, вы захотите использовать уменьшение дисперсии к уменьшить количество необходимых репликаций, т.е.уменьшить размер необходимой выборки.Более продвинутые методы уменьшения дисперсии можно найти во многих учебниках, например.в Вот этот.
Другие советы
Предварительно распределяйте ваши векторы!
> nsims <- 10000
> n <- 100
>
> system.time({
res <- NULL
for (i in 1:nsims) {
res <- c(res,mean(rnorm(n)))
}
})
user system elapsed
0.761 0.015 0.783
>
> system.time({
res <- rep(NA, nsims)
for (i in 1:nsims) {
res[i] <- mean(rnorm(n))
}
})
user system elapsed
0.485 0.001 0.488
>
Латинская выборка гиперкуба легко применяется и оказывает большое влияние на результаты. По сути, вы берете образец латинского гиперкуба из равномерного распределения (например, используя randomLHS () в пакете lhs) и преобразуете его в желаемое распределение, например, с помощью qnorm (uniformsample). Р>
Я знаю, что этот поток действительно старый, но если кто-то наткнется на него и ищет еще более быстрый метод, я думаю, что работает следующее:
library(data.table)
library(microbenchmark)
nsims <- 10000
n <- 100
# Answer from @Eduardo_Leoni:
preallocate<-function(nsims, n) {
res <- rep(NA, nsims)
for (i in 1:nsims) {
res[i] <- mean(rnorm(n))
}
return(res)
}
# Answer using data.table:
datatable<-function(nsims,n) {
dt <- data.table(i=1:nsims)[,list(res=mean(rnorm(1:n))),by=i]
return(dt)
}
# Timing benchmark:
microbenchmark(preallocate(nsims,n), datatable(nsims,n), times=100)
#Unit: milliseconds
# expr min lq median uq max neval
# preallocate(nsims, n) 428.4022 432.3249 434.2910 436.4806 489.2061 100
# datatable(nsims, n) 238.9006 242.3517 244.1229 246.5998 303.6133 100