LoginSignup
21
9

More than 3 years have passed since last update.

【NumPy】np.randomじゃなくてRandomStateを使いたい理由

Last updated at Posted at 2021-02-23

結論から

np.randomは広範囲に影響があるので、RandomStateを使いましょう。

はじめに

hoge君が以下のようなコードを作りました。

import numpy as np

np.random.seed(1234)

# 処理Aのブロック
for i in range(1,5):
    arr1 = np.random.randint(1,10,10)

    #------------------------------------
    # ...(略:arr1を使った具体的な処理)...
    #------------------------------------

後日、hoge君は処理Aの前に処理Bを実装する必要が出てきました。

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

# 処理B
arr2 = np.random.randint(1,10,10)

#------------------------------------
# ...(略:arr2を使った具体的な処理)...
#------------------------------------

# 処理Aのブロック
for i in range(1,5):
    arr = np.random.randint(1,10,10)
    print(aaa)

    #------------------------------------
    # ...(略:arr1を使った具体的な処理)...
    #------------------------------------

A君「ああ、まずい。これでは処理Aの結果が以前と変わってしまう。。。」

A君「あ!でももう一度シード設定すればいっか」(安易)

import numpy as np

# 処理B
np.random.seed(2345) # 一応別のシードにした
arr2 = np.random.randint(1,10,10)

#------------------------------------
# ...(略:arr2を使った具体的な処理)...
#------------------------------------

# 処理Aのブロック
np.random.seed(1234) # こっちはさっきと同じシード
for i in range(1,5):
    arr = np.random.randint(1,10,10)
    print(aaa)

    #------------------------------------
    # ...(略:arr1を使った具体的な処理)...
    #------------------------------------

A君「これで一安心~」

数日後

先輩「この前作ってもらった処理、ユーザー毎にマルチスレッドで処理したいんだよね」

A君「」

結論

要はnp.random.seed()はグローバルにいろんな範囲に影響あるからやめようねって話です。
一人での開発ならばなんとか管理できるかもしれないけど、複数人の開発や
並列処理や関数化・クラス化などの実装を進めると、どこで再現性が取れなくなっているか追えなくなります。

RandomStateを使えば、ほかの処理に影響を与えずに乱数生成ができる。

import numpy as np

# 処理B
rs2 = np.random.RandomState(2345)
arr2 = rs2.randint(1,10,10)
# ...(略:具体的な処理)...

# 処理Aのブロック
rs1 = np.random.RandomState(1234)
for i in range(1,5):
    arr = rs1.randint(1,10,10)
    print(aaa)
    # ...(略:具体的な処理)...

補足

ちなみに以下は同じ乱数列を返します。
グローバルなseed=1234と、RandomStateのseed=1234は同じ乱数を生成する。

import numpy as np

np.random.seed(1234)
print(np.random.randint(1,10,10))

rs = np.random.RandomState(1234)
print(rs.randint(1,10,10))
21
9
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
9