¿Cuál es el mejor truco para acelerar una simulación de Monte Carlo? [cerrado]
-
05-07-2019 - |
Pregunta
Cada vez que ejecuto simulaciones de Monte Carlo a gran escala en S-Plus, siempre termino creciendo una barba mientras espero que se complete.
¿Cuáles son los mejores trucos para ejecutar simulaciones de monte carlo en R? ¿Algún buen ejemplo de procesos en ejecución distribuidos?
Solución
-
El uso de múltiples núcleos / máquinas debería ser simple si solo está utilizando replicaciones independientes paralelas , pero tenga en cuenta las deficiencias comunes de los generadores de números aleatorios (por ejemplo, si utiliza la hora actual como semilla). , generando muchos procesos con un RNG para cada uno podría producir números aleatorios correlacionados, lo que lleva a resultados no válidos - vea, por ejemplo, este documento )
-
Es posible que desee utilizar reducción de varianza para reducir el número de replicaciones requeridas , es decir, reducir el tamaño de la muestra requerida. Se pueden encontrar técnicas más avanzadas de reducción de la varianza en muchos libros de texto, por ejemplo, en éste .
Otros consejos
¡Preasigna tus vectores!
> 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
>
El muestreo de hipercubo latino se aplica fácilmente y tiene una gran influencia en los resultados. Básicamente, toma una muestra de hipercubo latino de una distribución uniforme (por ejemplo, usando randomLHS () en el paquete lhs) y transforma esto a su distribución deseada usando, por ejemplo, qnorm (muestra de uniformes).
Sé que este hilo es realmente viejo, pero si alguien se topa con él y está buscando un método aún más rápido, creo que los siguientes trabajos:
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