Plusieurs fois, j’ai vu la fonction set.seed
dans R avant de lancer le programme. Je sais que c'est essentiellement utilisé pour la génération de nombres aléatoires. Y at-il un besoin spécifique pour définir cela?
Le besoin est le désir possible d'obtenir des résultats reproductibles, qui peuvent par exemple provenir d'une tentative de débogage de votre programme, ou bien sûr d'une tentative de rétablissement de ce qu'il fait:
Nous ne reproduirons "jamais" ces deux résultats car je viens de demander quelque chose "au hasard":
R> sample(LETTERS, 5)
[1] "K" "N" "R" "Z" "G"
R> sample(LETTERS, 5)
[1] "L" "P" "J" "E" "D"
Ces deux, cependant, sont identiques parce que j'ai mis la graine:
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>
Il existe une vaste littérature sur tout cela; Wikipedia est un bon début. Essentiellement, ces RNG sont appelés générateurs de nombres pseudo-aléatoires car ils sont en fait entièrement algorithmiques: étant donné le même germe, vous obtenez la même séquence. Et cela est une fonctionnalité et pas un bug.
Vous devez définir une graine chaque fois que vous souhaitez obtenir un résultat aléatoire reproductible.
set.seed(1)
rnorm(4)
set.seed(1)
rnorm(4)
Il suffit d'ajouter quelques aspects supplémentaires. Nécessité de créer une graine: dans le monde universitaire, si l’on affirme que son algorithme atteint, par exemple, 98,05% des performances d’une simulation, les autres doivent pouvoir la reproduire.
?set.seed
En parcourant le fichier d'aide de cette fonction, voici quelques faits intéressants:
(1) set.seed () renvoie NULL, invisible
(2) "Initialement, il n’ya pas de graine; une nouvelle est créée à partir de l’heure et de l’identifiant du processus, le cas échéant. Par conséquent, différentes sessions donnent par défaut des résultats de simulation différents. Toutefois, la graine peut être restaurée à partir d’un fichier. session précédente si un espace de travail précédemment enregistré est restauré. ", c’est pourquoi vous voudriez appeler set.seed () avec les mêmes valeurs entières la prochaine fois que vous souhaitez une même séquence de séquence aléatoire.
La correction de la graine est essentielle lorsque nous essayons d'optimiser une fonction qui implique des nombres générés aléatoirement (par exemple dans une estimation basée sur une simulation). En gros, si nous ne corrigeons pas le germe, la variation due au tirage de nombres aléatoires différents entraînera probablement l'échec de l'algorithme d'optimisation.
Supposons que, pour une raison quelconque, vous souhaitiez estimer l'écart type (sd) d'une distribution normale moyenne égale à zéro par simulation, à partir d'un échantillon. Ceci peut être réalisé en effectuant une optimisation numérique autour des étapes
Les fonctions suivantes font cela, une fois sans l'étape 1., une fois l'inclure:
# 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)))
}
Nous pouvons vérifier les performances relatives des deux fonctions en découvrant la valeur réelle du paramètre avec une courte étude 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)
Les distributions résultantes des estimations de paramètres sont les suivantes:
Lorsque nous corrigeons le germe, la recherche numérique se rapproche beaucoup plus souvent de la valeur réelle du paramètre 2.
en gros, la fonction set.seed () aidera à réutiliser le même ensemble de variables aléatoires, ce dont nous aurons peut-être besoin à l'avenir pour réévaluer une tâche particulière avec les mêmes variables varibales aléatoires
nous avons juste besoin de le déclarer avant d'utiliser une fonction générant des nombres aléatoires.