22 votes

Questions sur set.seed() en R

Je comprends ce que set.seed() fait et quand je pourrais l'utiliser, mais j'ai encore beaucoup de questions sur la fonction. Voici quelques-unes :

  1. Est-il possible de "réinitialiser" set.seed() vers quelque chose de "plus aléatoire" si vous avez déjà appelé set.seed() plus tôt dans votre session ? Est-ce même nécessaire ?
  2. Est-il possible de voir la graine que R utilise actuellement ?
  3. Existe-t-il un moyen de faire en sorte que set.seed() autorise des graines alphanumériques, de la même manière que l'on peut les saisir sur random.org (assurez-vous d'être en mode avancé, et voyez la "Partie 3" du formulaire pour comprendre ce que je veux dire) ?

18voto

Ben Bolker Points 50041

Juste pour le plaisir :

set.seed.alpha <- function(x) {
  require("digest")
  hexval <- paste0("0x",digest(x,"crc32"))
  intval <- type.convert(hexval) %% .Machine$integer.max
  set.seed(intval)
}

Vous pouvez donc faire :

set.seed.alpha("hello world")

(en fait x peut être n'importe quel objet R, pas seulement une chaîne alphanumérique)

15voto

Fhnuzoag Points 1034

Il est possible, si vous définissez la graine sur quelque chose comme les chiffres finaux de votre époque temporelle, mais ce n'est vraiment pas nécessaire. L'utilisation prévue des générateurs de nombres pseudo-aléatoires (PRNG) est que vous définissiez la graine une fois au début d'une session, et utilisiez des variables générées successivement à partir de celle-ci. Si vous faites les choses différemment, vous ne pourrez pas profiter des diverses bonnes propriétés théoriques et empiriques des PRNG de R.

Mais je ne suis pas sûr que vous compreniez vraiment le but de set.seed. Ce n'est pas vraiment là pour que vous obteniez des nombres "plus aléatoires". Si vous réalisez une sorte d'application pour laquelle le PRNG de R est insuffisant (par exemple, si vous avez besoin d'aléatoire cryptographique), vous feriez aussi bien de générer tous vos nombres aléatoires par une méthode alternative et de les utiliser directement. Le vrai but de set.seed est de produire de la reproductibilité dans les résultats utilisant les PRNG. Si vous démarrez la même analyse en utilisant la même séquence de génération de nombres aléatoires, et définissez la graine sur la même valeur, vous obtiendrez toujours le même résultat. C'est utile pour le débogage et pour d'autres personnes révisant vos résultats.

Pour utiliser l'heure epoch, faites quelque chose comme

t <- as.numeric(Sys.time())
seed <- 1e8 * (t - floor(t))
set.seed(seed); print(seed)

7voto

Greg Snow Points 22040

Pour votre question 3, il existe la fonction char2seed dans le package TeachingDemos qui prendra une chaîne de caractères (alpha numérique) et la convertira en entier et utilisera par défaut cela pour définir une nouvelle graine. L'idée était que les étudiants pourraient utiliser leur nom (ou une combinaison/sous-ensemble de noms) comme graine afin que chaque étudiant obtienne un ensemble de données différent, mais le professeur puisse reproduire l'ensemble de données de chaque étudiant.

3voto

Faheem Mitha Points 1589

Pour une réponse à 2, consultez d'abord la page d'aide ?RNGkind.

Pour trouver le type de RNG en cours d'utilisation :

RNGkind()
# [1] "Mersenne-Twister" "Inversion" 

Le Mersenne Twister est le paramètre par défaut.

À partir de la page d'aide :

‘"Mersenne-Twister":’ De Matsumoto et Nishimura (1998). Un GFSR tordu avec une période de 2^19937 - 1 et une équidistribution en 623 dimensions consécutives (sur toute la période). La ‘seed’ est un ensemble de 624 dimensions de nombres entiers de 32 bits plus une position actuelle dans cet ensemble.

Pour trouver la graine actuelle en cours d'utilisation, vous devez d'abord appeler le générateur de nombres aléatoires.

runif(1, 0, 1)                                                                                                                                                  
# [1] 0.9834062                                                                                                                                                      
.Random.seed
# [Fournit un vecteur de longueur 626]

Appeler set.seed(some_integer) suivi de .Random.seed, donnera toujours le même vecteur de longueur 626 si vous utilisez le même some_integer. Pour le dire autrement, le vecteur de longueur 626 est déterminé uniquement par some_integer, si l'on utilise le Mersenne Twister, bien sûr.

Aussi, bien sûr, exécuter set.seed à une valeur fixée vous donnera les mêmes valeurs pour les appels aux routines de nombres aléatoires suivantes. C'est son principal intérêt en pratique, pour garantir la reproductibilité. Par exemple,

set.seed(1)
runif(5, 0, 1)
# [1] 0.2655087 0.3721239 0.5728534 0.9082078 0.2016819
rnorm(1, 0, 1)
# [1] 1.272429
set.seed(1)
runif(5, 0, 1)
# [1] 0.2655087 0.3721239 0.5728534 0.9082078 0.2016819
rnorm(1, 0, 1)
# [1] 1.272429

Tout le code de génération de nombres de base en R se trouve dans le fichier src/main/RNG.c du code source.

Il est en C, mais assez facile à suivre.

1voto

outboundbird Points 582

J'ai le même problème que dans la question 1. J'ai ensuite réalisé que je pouvais simplement réinitialiser la graine dans la boucle en :

set.seed(123)
x<- rnorm(10,1,1)
set.seed(null)

Ainsi, à la fin de chaque boucle, la graine est simplement supprimée. Cela a fonctionné pour moi.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X