Comment puis-je récupérer la graine actuelle du générateur de nombres aléatoires de num Py?

les produits suivants importent peu et mettent la graine.

import numpy as np
np.random.seed(42)

cependant, je ne suis pas intéressé à mettre la graine mais plus à la lire. random.get_state() ne semble pas contenir de la graine. documentation ne donne pas de réponse évidente.

Comment puis-je récupérer la graine utilisée par numpy.random, en supposant que je ne l'ai pas réglé manuellement?

je veux utiliser la graine de report pour la prochaine itération du processus.

33
demandé sur ali_m 2015-08-24 01:10:14

3 réponses

la réponse courte est que vous ne pouvez tout simplement pas (du moins pas en général).

Mersenne Twister RNG utilisé par numpy a 219937 -1 états internes possibles, alors qu'un seul entier 64 bits n'a que 2 64 valeurs possibles. Il est donc impossible de cartographier chaque État de RNG à une graine entière unique.

Vous get et set de l'état interne du générateur de nombres aléatoires directement à l'aide de np.random.get_state et np.random.set_state. La sortie de get_state est un tuple dont le second élément est un (624,) tableau d'entiers de 32 bits. Ce tableau a plus qu'assez de bits pour représenter chaque état interne possible du RNG (2624 * 32 > 219937 -1).

Le tuple retournée par get_state peut être utilisé un peu comme une graine afin de créer des séquences reproductibles de nombres aléatoires. Par exemple:

import numpy as np

# randomly initialize the RNG from some platform-dependent source of entropy
np.random.seed(None)

# get the initial state of the RNG
st0 = np.random.get_state()

# draw some random numbers
print(np.random.randint(0, 100, 10))
# [ 8 76 76 33 77 26  3  1 68 21]

# set the state back to what it was originally
np.random.set_state(st0)

# draw again
print(np.random.randint(0, 100, 10))
# [ 8 76 76 33 77 26  3  1 68 21]
45
répondu ali_m 2016-07-02 22:01:00

j'ai révisé cette réponse en profondeur après avoir trouvé plus de détails sur le problème en question. Dans l'état actuel des choses, j'espère que cela servira bien de clarification à la réponse d'ali_m, et de correction importante à la réponse de Justin Dong.

ce sont mes conclusions:

  1. après avoir placé la graine au hasard en utilisant np.random.seed(X) vous le retrouver en utilisant np.random.get_state()[1][0].
  2. Il sera, cependant, de peu d'utilité pour vous.

la sortie des sections de code suivantes vous montrera pourquoi les deux énoncés sont corrects.


Déclaration 1 - vous pouvez trouver la graine aléatoire à l'aide de np.random.get_state()[1][0].

si vous définissez la graine au hasard en utilisant np.random.seed(123), vous pouvez récupérer l'état aléatoire comme un tuple en utilisant state = np.random.get_state(). Ci-dessous, un regard plus attentif sur state (j'utilise l'Explorateur de variables dans Spyder). Je suis à l'aide d'une capture d'écran depuis l'utilisation de print(state) inondera votre console à cause de la taille de la matrice dans le deuxième élément du tuple.

enter image description here

Vous pouvez facilement voir 123 comme le premier nombre dans le tableau contenu dans le deuxième élément. Et à l'aide de seed = np.random.get_state()[1][0] vous donner 123. Parfait? Pas tout à fait, parce que:

2 - Il sera, toutefois, être de peu d'utilité pour vous:

cela peut sembler ainsi à première vue si, parce que vous utiliser np.random.seed(123), récupérer le même nombre seed = np.random.get_state()[1][0], réinitialiser la graine avec np.random.seed(444), et puis (apparemment) ramenez-le au scénario 123 avec np.random.seed(seed). Mais alors vous saurez déjà ce que votre graine au hasard avant, donc vous n'auriez pas besoin de le faire de cette façon. La prochaine section de code montrera aussi que vous pas prendre le premier nombre de n'importe quel état aléatoire en utilisant np.random.get_state()[1][0] et s'attendre à recréer ce scénario exact. Note que vous devrez probablement arrêter et redémarrer votre noyau complètement (ou appeler np.random.seed(None)) afin de pouvoir le voir.

Le bout de code suivant utilise np.random.randint() pour générer 5 entiers aléatoires entre -10 et 10, ainsi que le stockage des informations sur le processus:

Extrait 1

# 1. Imports
import pandas as pd
import numpy as np

# 2. set random seed
#seedSet = None
seedSet = 123
np.random.seed(seedSet)

# 3. describe random state
state = np.random.get_state()
state5 = np.random.get_state()[1][:5]
seedState = np.random.get_state()[1][0]

# 4. generate random numbers
random = np.random.randint(-10, 10, size = 5)

# 5. organize and present findings
df = pd.DataFrame.from_dict({'seedSet':seedSet, 'seedState':seedState, 'state':state, 'random':random})
print(df)

Notez que la colonne nommée seedState est le même que le premier numéro sous state. J'ai pu l'imprimer comme un numéro autonome, mais je voulais garder tout au même endroit. Notez également que, seedSet = 123 et np.random.seed(seedSet) jusqu'à présent, ont été commentés. Et parce qu'aucune graine aléatoire n'a été établie, vos nombres seront différents des miens. Mais ce n'est pas ce qui est important ici, mais plutôt la consistance interne de vos résultats:

sortie 1:

   random seedSet   seedState       state
0       2    None  1558056443  1558056443
1      -1    None  1558056443  1808451632
2       4    None  1558056443   730968006
3      -4    None  1558056443  3568749506
4      -6    None  1558056443  3809593045

Dans ce cas particulier seed = np.random.get_state()[1][0] égale 1558056443. Et en suivant la logique de la réponse de Dong Justins ma propre réponse avant cette édition), vous pouvez définir la graine aléatoire avec np.random.seed(1558056443) et obtenir le même état aléatoire. Le prochain extrait de montrer que vous pas:

Extrait 2

# 1. Imports
import pandas as pd
import numpy as np

# 2. set random seed
#seedSet = None
seedSet = 1558056443
np.random.seed(seedSet)

# 3. describe random state
#state = np.random.get_state()
state = np.random.get_state()[1][:5]
seedState = np.random.get_state()[1][0]

# 4. generate random numbers
random = np.random.randint(-10, 10, size = 5)

# 5. organize and present findings
df = pd.DataFrame.from_dict({'seedSet':seedSet, 'seedState':seedState, 'state':state, 'random':random})
print(df)

sortie 2:

   random     seedSet   seedState       state
0       8  1558056443  1558056443  1558056443
1       3  1558056443  1558056443  1391218083
2       7  1558056443  1558056443  2754892524
3      -8  1558056443  1558056443  1971852777
4       4  1558056443  1558056443  2881604748

voyez la différence? np.random.get_state()[1][0] est identique pour la Sortie 1 et Sortie 2, mais le reste de la production est non (surtout les nombres aléatoires ne sont pas les mêmes). Donc, comme ali_m l'a déjà fait clairement:

il est donc impossible de cartographier chaque État RNG à une seule graine entière.

7
répondu vestland 2018-04-12 09:40:35

cochez le premier élément du tableau retourné par np.random.get_state(), il semble exactement la graine aléatoire pour moi.

0
répondu Dong Justin 2018-03-01 15:37:25