Razones para utilizar la función set.seed

Respuestas:

272

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.

Dirk Eddelbuettel
fuente
5
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.

set.seed(1)
rnorm(4)
set.seed(1)
rnorm(4)
Chia-colgado
fuente
17

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.

Ridingstar
fuente
7

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

  1. (Sembrando la semilla)
  2. Dado un valor para sd, generar datos distribuidos normalmente
  3. 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 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:

Histograma de estimaciones de parámetros sin fijar la semilla Histograma de estimaciones de parámetros que fijan la semilla

Cuando arreglamos la semilla, la búsqueda numérica termina cerca del valor verdadero del parámetro 2 con mucha más frecuencia.

Matthias Schmidtblaicher
fuente
6

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.

user4388407
fuente
elabore la respuesta
Spry Techies