web-dev-qa-db-ja.com

NumPyの乱数ジェネレーターの現在のシードを取得するにはどうすればよいですか?

以下はNumPyをインポートし、シードを設定します。

_import numpy as np
np.random.seed(42)
_

しかし、私は種を設定することに興味はありませんが、それを読むことに興味があります。 random.get_state()にはシードが含まれていないようです。 documentation は明らかな答えを示していません。

手動で設定しなかったと仮定して、_numpy.random_によって使用される現在のシードを取得するにはどうすればよいですか?

現在のシードを使用して、プロセスの次の反復に持ち越します。

46
Mast

簡単な答えは、単純にできないことです(少なくとも一般的にはできません)。

Numpyが使用する Mersenne Twister RNGには2があります19937-1可能な内部状態。一方、単一の64ビット整数には264 可能な値。したがって、すべてのRNG状態を一意の整数シードにマッピングすることは不可能です。

can を使用して、 np.random.get_state および np.random.set_stateを使用してRNGの内部状態を直接取​​得および設定します。get_stateの出力は、2番目の要素が32ビット整数の(624,)配列であるタプルです。この配列には、RNGのすべての可能な内部状態を表すのに十分なビットがあります(2624 * 32 > 219937-1)。

get_stateによって返されるTupleは、シードのように使用して、再現可能な乱数シーケンスを作成できます。例えば:

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]
58
ali_m

この回答は、当面の問題に関する詳細を見つけた後に編集されました。現在のところ、私はそれがALi_mからの回答の明確化として、またドンジャスティンからの回答の重要な修正として役立つことを望んでいます。

これらは私の発見です:

  1. np.random.seed(X)を使用してランダムシードを設定した後、np.random.get_state()[1][0]を使用してcanを再度見つけます。
  2. ただし、これはほとんど役に立ちません。

次のコードセクションの出力は、両方のステートメントが正しい理由を示しています。


Statement 1-np.random.get_state()[1][0].を使用してランダムシードを見つけることができます

np.random.seed(123)を使用してランダムシードを設定すると、state = np.random.get_state()を使用してランダム状態をタプルとして取得できます。以下は、stateの詳細です(SpyderでVariable Explorerを使用しています)。タプルの2番目の要素の配列のサイズのためにprint(state)を使用するとコンソールがあふれるので、スクリーンショットを使用しています。

enter image description here

123は、2番目の要素に含まれる配列の最初の数値として簡単に確認できます。 seed = np.random.get_state()[1][0]willを使用すると、123が得られます。完璧?そうではない、なぜなら:

Statement 2-ただし、あまり役に立ちません:

ただし、最初はそうではないように見えるかもしれません。 could を使用してnp.random.seed(123)を使用し、seed = np.random.get_state()[1][0]で同じ番号を取得し、np.random.seed(444)でシードをリセットし、(見たところ)123に戻すnp.random.seed(seed)のシナリオ。しかし、あなたはすでにあなたのランダムシードwasが何であるかをすでに知っているので、そのようにする必要はありません。次のコードセクションでは、np.random.get_state()[1][0]を使用してランダムな状態の最初の数をcannotで取得し、その正確なシナリオを再作成することも期待しています。これを確認するには、ほとんどの場合、カーネルをシャットダウンして再起動する必要があることに注意してください complete /(またはnp.random.seed(None)を呼び出します)。

次のスニペットはnp.random.randint()を使用して、-10〜10の5つのランダムな整数を生成し、プロセスに関する情報を保存します。

スニペット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)

seedStateという名前の列は、stateの下の最初の数値と同じであることに注意してください。スタンドアロンの番号として印刷することもできましたが、すべて同じ場所に保管したかったのです。また、seedSet = 123およびnp.random.seed(seedSet)がこれまでコメントアウトされていることに注意してください。そして、ランダムなシードが設定されていないため、あなたの数字は私のものとは異なります。しかし、それはここで重要なことではなく、結果の内部一貫性です。

出力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

この特定のケースでは、seed = np.random.get_state()[1][0]1558056443と等しくなります。そして、Dong Justinsの回答(およびこの編集前の私自身の回答)のロジックに従って、np.random.seed(1558056443)でランダムシードを設定し、同じランダム状態を取得できます。次のスニペットでは、できません

スニペット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)

出力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

違いを見ます? np.random.get_state()[1][0]は出力1と出力2で同じですが、出力の残りは同じではありません(最も重要なのは、乱数が同じではないことです)。したがって、ALi_mがすでに明確に述べているように:

したがって、すべてのRNG状態を一意の整数シードにマッピングすることは不可能です。

11
vestland

np.random.get_state()によって返された配列の最初の要素を確認してください。それはまさにランダムな種のようです。

1
Dong Justin