Razões para usar a função set.seed


Respostas:


264

A necessidade é o desejo possível de resultados reproduzíveis, que podem, por exemplo, resultar da tentativa de depurar seu programa ou, claro, da tentativa de refazer o que ele faz:

Esses dois resultados "nunca" serão reproduzidos, pois pedi algo "aleatório":

R> sample(LETTERS, 5)
[1] "K" "N" "R" "Z" "G"
R> sample(LETTERS, 5)
[1] "L" "P" "J" "E" "D"

Estes dois, no entanto, são idênticos porque eu coloquei a semente :

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 vasta literatura sobre tudo isso; A Wikipedia é um bom começo. Em essência, esses RNGs são chamados de Geradores de Números Aleatórios Pseudo-Aleatórios porque, na verdade, são totalmente algorítmicos : dada a mesma semente, você obtém a mesma sequência. E isso é um recurso e não um bug.


5
Obrigado Dirk, por um exemplo tão bom .. Eu limpei com 99%, mas ainda questiono. 1. Na sua resposta, você usou set.seed com 42 como argumento .. existe algum motivo relacionado para escolher esse valor?
— Vignesh

43
Para um RNG normal de qualidade decente, o valor não importa. "42" é uma referência a um livro famoso; outras pessoas usam seu aniversário ou "123" ou apenas "1".
— Dirk Eddelbuettel 30/11

7
A char2seedfunção no pacote TeachingDemos permite definir a semente (ou escolher uma semente para passar set.seed) com base em uma sequência de caracteres. Por exemplo, você pode fazer com que os alunos usem seu nome como semente, e cada aluno tem um conjunto de dados exclusivo, mas o instrutor também pode criar os mesmos conjuntos de dados para a classificação.
— Greg Neve

8
É possível executar novamente o mesmo código com sementes diferentes até que você obtenha o "melhor" resultado (eu fiz isso por exemplo). Para evitar acusações, é melhor escolher uma semente que tenha algum significado óbvio, sempre a mesma semente ou a data, ou eu uso char2seede o sobrenome do investigador principal em um projeto.
— Greg Neve

5
O valor da semente @DirkEddelbuettel pode ser importante por razões não computacionais, um amigo meu teve problemas com a publicação de seus resultados baseados em simulação porque o código começou com set.seed(666)e os revisores não gostaram da semente Devils no código ...
— Tim

33

Você precisa definir a semente toda vez que deseja obter um resultado aleatório reproduzível.

set.seed(1)
rnorm(4)
set.seed(1)
rnorm(4)

17

Apenas adicionando alguns aspectos adicionais. Necessidade de definir sementes: no mundo acadêmico, se alguém afirma que seu algoritmo alcança, digamos 98,05% de desempenho em uma simulação, outros precisam ser capazes de reproduzi-lo.

?set.seed

Percorrendo o arquivo de ajuda desta função, estes são alguns fatos interessantes:

(1) set.seed () retorna NULL, invisível

(2) "Inicialmente, não há semente; uma nova é criada a partir do horário atual e o ID do processo quando necessário. Portanto, sessões diferentes fornecerão resultados de simulação diferentes, por padrão. No entanto, a semente pode ser restaurada de um sessão anterior, se um espaço de trabalho salvo anteriormente for restaurado. ", é por isso que você deseja chamar set.seed () com os mesmos valores inteiros da próxima vez que desejar uma mesma sequência de sequência aleatória.


7

A correção da semente é essencial quando tentamos otimizar uma função que envolve números gerados aleatoriamente (por exemplo, em estimativas baseadas em simulação). Em termos gerais, se não corrigirmos a semente, a variação devido ao desenho de diferentes números aleatórios provavelmente fará com que o algoritmo de otimização falhe.

Suponha que, por algum motivo, você queira estimar o desvio padrão (dp) de uma distribuição normal média zero por simulação, dada uma amostra. Isso pode ser alcançado executando uma otimização numérica em torno das etapas

  1. (Configurando a semente)
  2. Dado um valor para sd, gere dados normalmente distribuídos
  3. Avalie a probabilidade de seus dados, dadas as distribuições simuladas

As seguintes funções fazem isso, uma vez sem a etapa 1., uma vez incluindo-a:

# 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 o desempenho relativo das duas funções na descoberta do verdadeiro valor do parâmetro com um breve estudo 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)

As distribuições resultantes das estimativas de parâmetros são:

Histograma de estimativas de parâmetros sem fixar a semente Histograma de estimativas de parâmetros que fixam a semente

Quando consertamos a semente, a pesquisa numérica acaba perto do valor real do parâmetro 2 com muito mais frequência.


6

A função basicamente set.seed () ajudará a reutilizar o mesmo conjunto de variáveis ​​aleatórias, que poderemos precisar no futuro para avaliar novamente determinada tarefa novamente com as mesmas variáveis ​​aleatórias

só precisamos declará-lo antes de usar qualquer função de geração de números aleatórios.


elaborar a resposta
— Spry Techies
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.