Muchas veces he visto la set.seedfunción en R, antes de iniciar el programa. Sé que se usa básicamente para la generación de números aleatorios. ¿Existe alguna necesidad específica de configurar esto?
La necesidad es el posible deseo de obtener resultados reproducibles, que pueden provenir, por ejemplo, de intentar depurar su programa o, por supuesto, de intentar rehacer lo que hace:
Estos dos resultados "nunca" los reproduciremos, ya que pedí algo "aleatorio":
Existe una vasta literatura sobre todo eso; Wikipedia es un buen comienzo. En esencia, estos RNG se denominan Pseudo Generadores de números aleatorios porque de hecho son completamente algorítmicos : dada la misma semilla, se obtiene la misma secuencia. Y esa es una característica y no un error.
Gracias Dirk, por tan buen ejemplo ... Lo he aclarado con un 99%, pero aún tengo dudas. 1. En su respuesta ha utilizado set.seed con 42 como argumento ... ¿hay alguna razón relacionada para elegir este valor?
Vignesh
46
Para un RNG normal de calidad decente, el valor no importa. "42" es una referencia a un libro famoso; otras personas usan su cumpleaños o "123" o simplemente "1".
Dirk Eddelbuettel
8
La char2seedfunción en el paquete TeachingDemos le permite establecer la semilla (o elegir una semilla para pasar set.seed) en función de una cadena de caracteres. Por ejemplo, podría hacer que los estudiantes usen su nombre como semilla, luego cada estudiante tiene un conjunto de datos único, pero el instructor también puede crear los mismos conjuntos de datos para calificar.
Greg Snow
8
Es posible volver a ejecutar el mismo código con diferentes semillas hasta que obtenga el "mejor" resultado (he hecho esto por ejemplo). Para protegerse contra las acusaciones de hacer esto, es mejor elegir una semilla que tenga algún significado obvio, ya sea siempre la misma semilla, o la fecha, o utilizo char2seedy el apellido del investigador principal en un proyecto.
Greg Snow
6
El valor de la semilla de @DirkEddelbuettel puede ser importante por razones no computacionales, un amigo mío tuvo problemas con la publicación de sus resultados basados en simulación porque el código comenzó con set.seed(666)y a los revisores no les gustó la semilla de Devils en el código ...
Tim
34
Debe establecer semillas cada vez que desee obtener un resultado aleatorio reproducible.
Solo agrego algunos aspectos adicionales. Necesidad de sembrar la semilla: en el mundo académico, si uno afirma que su algoritmo logra, digamos, un rendimiento del 98,05% en una simulación, otros necesitan poder reproducirlo.
?set.seed
Pasando por el archivo de ayuda de esta función, estos son algunos datos interesantes:
(1) set.seed () devuelve NULL, invisible
(2) "Inicialmente, no hay semilla; se crea una nueva a partir del tiempo actual y el ID del proceso cuando se requiere una. Por lo tanto, diferentes sesiones darán resultados de simulación diferentes, de forma predeterminada. sesión anterior si se restaura un espacio de trabajo previamente guardado. ", por eso querrá llamar a set.seed () con los mismos valores enteros la próxima vez que desee una misma secuencia de secuencia aleatoria.
Arreglar la semilla es esencial cuando intentamos optimizar una función que involucra números generados aleatoriamente (por ejemplo, en una estimación basada en simulación). Hablando libremente, si no arreglamos la semilla, la variación debida al dibujo de diferentes números aleatorios probablemente hará que el algoritmo de optimización falle.
Suponga que, por alguna razón, desea estimar la desviación estándar (sd) de una distribución normal media cero mediante simulación, dada una muestra. Esto se puede lograr ejecutando una optimización numérica alrededor de los pasos
(Sembrando la semilla)
Dado un valor para sd, generar datos distribuidos normalmente
Evalúe la probabilidad de sus datos dadas las distribuciones simuladas
Las siguientes funciones hacen esto, una vez sin el paso 1., una vez incluido:
# without fixing the seed
simllh <- function(sd, y, Ns){
simdist <- density(rnorm(Ns, mean = 0, sd = sd))
llh <- sapply(y, function(x){ simdist$y[which.min((x - simdist$x)^2)] })
return(-sum(log(llh)))
}
# same function with fixed seed
simllh.fix.seed <- function(sd,y,Ns){
set.seed(48)
simdist <- density(rnorm(Ns,mean=0,sd=sd))
llh <- sapply(y,function(x){simdist$y[which.min((x-simdist$x)^2)]})
return(-sum(log(llh)))
}
Podemos verificar el desempeño relativo de las dos funciones al descubrir el verdadero valor del parámetro con un breve estudio de Monte Carlo:
N <- 20; sd <- 2# features of simulated data
est1 <- rep(NA,1000); est2 <- rep(NA,1000) # initialize the estimate storesfor (i in1:1000) {
as.numeric(Sys.time())-> t; set.seed((t - floor(t)) * 1e8 -> seed) # set the seed to random seed
y <- rnorm(N, sd = sd) # generate the data
est1[i] <- optim(1, simllh, y = y, Ns = 1000, lower = 0.01)$par
est2[i] <- optim(1, simllh.fix.seed, y = y, Ns = 1000, lower = 0.01)$par
}
hist(est1)
hist(est2)
Las distribuciones resultantes de las estimaciones de los parámetros son:
Cuando arreglamos la semilla, la búsqueda numérica termina cerca del valor verdadero del parámetro 2 con mucha más frecuencia.
Básicamente, la función set.seed () ayudará a reutilizar el mismo conjunto de variables aleatorias, que es posible que necesitemos en el futuro para evaluar nuevamente una tarea en particular con las mismas variables aleatorias
solo necesitamos declararlo antes de usar cualquier función generadora de números aleatorios.
Respuestas:
La necesidad es el posible deseo de obtener resultados reproducibles, que pueden provenir, por ejemplo, de intentar depurar su programa o, por supuesto, de intentar rehacer lo que hace:
Estos dos resultados "nunca" los reproduciremos, ya que pedí algo "aleatorio":
R> sample(LETTERS, 5) [1] "K" "N" "R" "Z" "G" R> sample(LETTERS, 5) [1] "L" "P" "J" "E" "D"
Estos dos, sin embargo, son idénticos porque puse la semilla :
R> set.seed(42); sample(LETTERS, 5) [1] "X" "Z" "G" "T" "O" R> set.seed(42); sample(LETTERS, 5) [1] "X" "Z" "G" "T" "O" R>
Existe una vasta literatura sobre todo eso; Wikipedia es un buen comienzo. En esencia, estos RNG se denominan Pseudo Generadores de números aleatorios porque de hecho son completamente algorítmicos : dada la misma semilla, se obtiene la misma secuencia. Y esa es una característica y no un error.
fuente
char2seed
función en el paquete TeachingDemos le permite establecer la semilla (o elegir una semilla para pasarset.seed
) en función de una cadena de caracteres. Por ejemplo, podría hacer que los estudiantes usen su nombre como semilla, luego cada estudiante tiene un conjunto de datos único, pero el instructor también puede crear los mismos conjuntos de datos para calificar.char2seed
y el apellido del investigador principal en un proyecto.set.seed(666)
y a los revisores no les gustó la semilla de Devils en el código ...Debe establecer semillas cada vez que desee obtener un resultado aleatorio reproducible.
set.seed(1) rnorm(4) set.seed(1) rnorm(4)
fuente
Solo agrego algunos aspectos adicionales. Necesidad de sembrar la semilla: en el mundo académico, si uno afirma que su algoritmo logra, digamos, un rendimiento del 98,05% en una simulación, otros necesitan poder reproducirlo.
Pasando por el archivo de ayuda de esta función, estos son algunos datos interesantes:
fuente
Arreglar la semilla es esencial cuando intentamos optimizar una función que involucra números generados aleatoriamente (por ejemplo, en una estimación basada en simulación). Hablando libremente, si no arreglamos la semilla, la variación debida al dibujo de diferentes números aleatorios probablemente hará que el algoritmo de optimización falle.
Suponga que, por alguna razón, desea estimar la desviación estándar (sd) de una distribución normal media cero mediante simulación, dada una muestra. Esto se puede lograr ejecutando una optimización numérica alrededor de los pasos
Las siguientes funciones hacen esto, una vez sin el paso 1., una vez incluido:
# without fixing the seed simllh <- function(sd, y, Ns){ simdist <- density(rnorm(Ns, mean = 0, sd = sd)) llh <- sapply(y, function(x){ simdist$y[which.min((x - simdist$x)^2)] }) return(-sum(log(llh))) } # same function with fixed seed simllh.fix.seed <- function(sd,y,Ns){ set.seed(48) simdist <- density(rnorm(Ns,mean=0,sd=sd)) llh <- sapply(y,function(x){simdist$y[which.min((x-simdist$x)^2)]}) return(-sum(log(llh))) }
Podemos verificar el desempeño relativo de las dos funciones al descubrir el verdadero valor del parámetro con un breve estudio de Monte Carlo:
N <- 20; sd <- 2 # features of simulated data est1 <- rep(NA,1000); est2 <- rep(NA,1000) # initialize the estimate stores for (i in 1:1000) { as.numeric(Sys.time())-> t; set.seed((t - floor(t)) * 1e8 -> seed) # set the seed to random seed y <- rnorm(N, sd = sd) # generate the data est1[i] <- optim(1, simllh, y = y, Ns = 1000, lower = 0.01)$par est2[i] <- optim(1, simllh.fix.seed, y = y, Ns = 1000, lower = 0.01)$par } hist(est1) hist(est2)
Las distribuciones resultantes de las estimaciones de los parámetros son:
Cuando arreglamos la semilla, la búsqueda numérica termina cerca del valor verdadero del parámetro 2 con mucha más frecuencia.
fuente
Básicamente, la función set.seed () ayudará a reutilizar el mismo conjunto de variables aleatorias, que es posible que necesitemos en el futuro para evaluar nuevamente una tarea en particular con las mismas variables aleatorias
solo necesitamos declararlo antes de usar cualquier función generadora de números aleatorios.
fuente