概要
pythonで乱数生成するときに,再現性を担保するためにseedを指定する方が多いと思います.
乱数のseedの設定について,他スクリプトを呼び出す場合にどのような挙動をするかを実験しました.
自分用のメモも兼ねて投稿.
結論
- 別スクリプトで乱数を実行する場合でも
np.random.seed
は共有される模様. - 自分で関数とかを作って,読み込み元のスクリプト(
hoge.py
)でシードを設定すると実行先のスクリプト(fuga.py
)のシードも書き換えられてしまうので注意が必要 - それを避けるためには,
np.random.RandomState
を使うなどが挙げられる.(実際pandasの乱数とかはこれを使っていた)
実験
以下のようにhoge.py
を準備fuga.py
を準備します.
fuga.py
を実行した際にどのように乱数が生成されるかを見てみます.
hoge.py
import numpy as np
def hoge(seed=None, random_state=None):
if random_state is not None:
rs = np.random.RandomState(123)
print(rs.randint(0, 1000, 10))
else:
if seed is not None:
np.random.seed(seed)
print(np.random.randint(0, 1000, 10))
fuga.py
import numpy as np
import hoge
if __name__ == '__main__':
# 普通に実行
np.random.seed(123)
print(np.random.randint(0, 1000, 10))
### [510 365 382 322 988 98 742 17 595 106] (seed=123)
# fugaでseedを設定するが,hogeでは設定しない.
np.random.seed(123)
hoge.hoge()
### [510 365 382 322 988 98 742 17 595 106] (seed=123)
# fugaでseed(231)を設定し,hogeでは別のseed(123)を設定する.
np.random.seed(231)
hoge.hoge(seed=123)
### [510 365 382 322 988 98 742 17 595 106] (seed=123)
# hogeでnp.random.seed(213)を渡してしまうと,fugaにも反映してしまう.
np.random.seed(123)
hoge.hoge(seed=231)
### [599 176 660 457 779 710 514 478 887 340] (seed=231)
print(np.random.randint(0, 1000, 10))
### [874 241 274 802 828 546 33 291 401 556] (seed=231の2回目)
# hogeでnp.random.RandomStateを使えば,fugaには反映されない
np.random.seed(123)
hoge.hoge(random_state=231)
### [599 176 660 457 779 710 514 478 887 340] (seed=231)
print(np.random.randint(0, 1000, 10))
### [510 365 382 322 988 98 742 17 595 106] (seed=123)
変更履歴
- 2019/06/20 16:39
- めっちゃ間違えてたので大幅に変更
- 2020/08/17 10:52
- seed値を打ち間違えていたので修正