Définir la graine avant chaque bloc de code ou une fois par projet?

12

Il est conseillé de définir une graine aléatoire afin que les résultats puissent être reproduits. Cependant, comme la graine est avancée à mesure que des nombres pseudo-aléatoires sont tirés, les résultats peuvent changer si un morceau de code tire un nombre supplémentaire.

À première vue, le contrôle de version semble être une solution à cela, car il vous permettrait au moins de revenir en arrière et de reproduire la version existante lorsque vous avez noté les résultats dans vos notes ou votre papier. Cependant, comme il ne faut qu'un tirage au sort pour gâcher les choses, si vous mettez à jour R, les résultats peuvent également changer.

Je me rends compte que cela n'est probablement problématique que dans de rares cas, mais je suis curieux de savoir s'il existe des meilleures pratiques ici. C'est quelque chose avec lequel je me bats dans mon propre travail.

Ari B. Friedman
la source

Réponses:

8

Cela dépend de la façon dont vous exécuterez le code ou s'il existe un code quelque peu stochastique en ce qu'il dessine des nombres aléatoires de manière aléatoire. (Un exemple de ceci est les tests de permutation dans notre package végétalien où nous continuons à permuter jusqu'à ce que nous ayons accumulé suffisamment de données pour savoir si un résultat est différent de l'erreur de type I indiquée en tenant compte d'un taux d'erreur de type II.) Bien que même cela ne devrait pas affecter les tirages ...

Si le script final ne sera exécuté qu'en tant que travail par lots ou dans son intégralité et qu'il n'y a pas de tirages stochastiques du générateur de nombres pseudo-aléatoires, il est sûr de définir une graine en haut du script et de l'exécuter dans son intégralité .

Si vous voulez parcourir le code, peut-être en réexécutant des blocs, vous avez besoin d'un set.seed()appel avant chaque appel de fonction qui proviendra du générateur de nombres pseudo-aléatoires.

Pour mes articles scientifiques, je vais régulièrement en super défensive et je mets des graines avant chaque morceau de code; cela permet des mises à jour du script à une date ultérieure qui pourraient devoir être insérées à tout moment dans le script existant - disons pour répondre aux commentaires des critiques ou des co-auteurs.

Nous espérons que vos résultats ne dépendront pas d'un ensemble particulier de valeurs pseduo-aléatoires, donc le problème est de pouvoir reproduire les valeurs exactes indiquées dans un rapport ou un document. Même si vous pouvez être super défensif et définir une graine sur chaque bloc de code, vous devrez peut-être recréer l'installation exacte --- version R et versions de package, il est donc essentiel d'enregistrer ces détails. Pour plus de sécurité, vous devrez conserver les versions et packages R précédents pour des projets / documents spécifiques. En effet, beaucoup de gens le font.

Gavin Simpson
la source
+1. Concernant le dernier paragraphe: vous n'avez pas à enregistrer toutes ces ordures et vous n'avez pas à recréer une installation entière. Si vous êtes précis sur le RNG que vous utilisez, alors plutôt que d'accepter les valeurs par défaut, tout ce qui doit être sauvegardé est (1) le code source de ce RNG (qui est généralement court) et (2) l'état du RNG à chaque étape cruciale . Pour la plupart des Rtravaux, cet état se trouve dans .Random.seed. Ma plus grande préoccupation Rest que certaines routines pourraient contourner cela - et pourraient peut-être ignorer set.seedcomplètement dans certains cas.
whuber
2
@whuber J'y pensais plus généralement - si le problème est de reproduire l'ensemble exact des résultats, vous aurez plus que probablement besoin de la version de R et des versions de tous les packages utilisés. Pour Pentecôte; R 3.0.0 a changé la précision avec laquelle il a signalé des valeurs - pas majeur mais cela a suffi pour annuler tous les nombreux tests de vérification de package qui supposaient trop de précision. De plus, les packages sont mis à jour régulièrement et les choses changent.
Gavin Simpson