乱数のシード

NumPyなどで生成される乱数は、擬似乱数といって必ずシードを元に作成されます。 シードは乱数の元になるもので、Pythonの環境を最初に実行した時に時刻などで初期化されます。 明示的にシードを指定しなくても、ランダムに乱数が発生するのはこのためです。

何度実行しても、同じ乱数列(結果の連なり)が出ることを再現性があるといいます。 次の2つの方法があります。

  • シードを指定する方法:default_rng()の引数でシードを指定

  • 状態を指定する方法:状態(bit_generator.state)を取得して、再現したいときに状態を設定

シードを指定する実行例

下記では、シードを指定しているので、何度実行しても同じ結果になります。 また、ループの中で指定しているので、同じ結果が2回出力されます。

from numpy.random import default_rng

for i in range(2):
    rng = default_rng(0)  # シードとして0を指定
    print(rng.random(3))

実行結果

[0.63696169 0.26978671 0.04097352]
[0.63696169 0.26978671 0.04097352]

(注)シードを指定すると、乱数がリセットされた状態になりますので、通常は、最初に一度だけ指定します。

状態を指定する実行例

下記では、シードが未指定なので、実行するたびに違う結果になります。 しかし、ループの中で状態を指定しているので、1ループ目と2ループ目の結果が同じになります。

rng = default_rng()  # シードを未指定

state = rng.bit_generator.state
for i in range(2):
    rng.bit_generator.state = state
    print(rng.random(3))

実行結果

[0.39006911 0.88310525 0.34391511]
[0.39006911 0.88310525 0.34391511]

再現性が必要な状況は、さまざまです。 たとえばテストが終わってない場合、シードを設定して再現するようにしておけば、デバッグしやすいでしょう。

シード設定時の注意

シードを設定する場合、気をつけないといけないことがあります。 たとえば、銀行のATMの待ち行列のシミュレーションを考えましょう。 乱数を使っているので、待ち行列は長くなったり短くなったりするでしょう。

しかし、間違えて、顧客の到着間隔の乱数のシードと、顧客がATMで手続きする処理時間の乱数のシードを同じにしたとします。 そうすると、待ち行列の長さは0のままになります。これは、到着間隔と処理時間の相関が1のためです。

乱数を使う場合、無相関を仮定するケースが多いです。その場合は、異なるシードを指定したり、最初の1回だけ指定するなどの方法があります。

当コンテンツの知的財産権は株式会社ビープラウドに所属します。詳しくは利用規約をご確認ください。