#動機
今年の5月頃に刊行された「詳解 ディープラーニング Tensorflfow・Kerasによる時系列データ処理」を読んでいたところ、乱数を生成する部分が出てきました。
毎回同じ乱数を生成するためにシードを設定する、ということでしたが、このあたりの記述がよく分からなかったので、簡単に調べてみました。
#擬似乱数
random関数で生成する乱数は、擬似乱数なのだとか。
擬似乱数 - Wikipedia
そもそも擬似乱数とは、一見法則性のない乱数に見えるけれども、ある確定的な計算(決まったアルゴリズム?)によってランダムかのように算出されている数値。
擬似乱数算出の際、初期状態として設定する数値がシードだ、ということです。
このシードを同じ数値にすることで、毎回同じ擬似乱数が生成される、ということで、シードを固定した状態で何度も擬似乱数を生成してみたのですが
import bumpy as np
rng = np.random.RandomState(100)
for i in range(10):
print(rng.randn(5)) #randn : 標準正規分布からサンプリング
生成結果:
[-1.74976547 0.3426804 1.1530358 -0.25243604 0.98132079]
[ 0.51421884 0.22117967 -1.07004333 -0.18949583 0.25500144]
[-0.45802699 0.43516349 -0.58359505 0.81684707 0.67272081]
[-0.10441114 -0.53128038 1.02973269 -0.43813562 -1.11831825]
[ 1.61898166 1.54160517 -0.25187914 -0.84243574 0.18451869]
[ 0.9370822 0.73100034 1.36155613 -0.32623806 0.05567601]
[ 0.22239961 -1.443217 -0.75635231 0.81645401 0.75044476]
[-0.45594693 1.18962227 -1.69061683 -1.35639905 -1.23243451]
[-0.54443916 -0.66817174 0.00731456 -0.61293874 1.29974807]
[-1.73309562 -0.9833101 0.35750775 -1.6135785 1.47071387]
おや、生成するたびに違う乱数だ...と思っていたのですが、2回目以降の生成では前回生成された乱数をもとに新たに生成されるようですね。
https://teratail.com/questions/15388
(こちらを参考にさせていただきました。)
上記スクリプトでは、シードを100にして長さ5の擬似乱数リストを10回生成する(つまり、乱数を50回生成している?)ということなので、毎回違うんですね。
もう一度同じスクリプトを実行すると、同じ乱数が生成されました。
シードを同じにすることで、同じアルゴリズムでいつも同じ1つ目の擬似乱数が生成される
↓
1つ目の擬似乱数に基づいて2つ目の擬似乱数が生成されるので、1つ目がいつも同じならば2つ目もいつも同じ
...
の繰り返しということですね。
毎回同じ擬似乱数が生成されるとはつまり、シードを設定した時点をスタートとして、同じ擬似乱数列が生成される、という意味なのでした。
(考えてみれば、常に同じ乱数が生成されるようでは、もはや乱数ではないですよね。)
機械学習などでも、ランダムな数値を用いて性能を評価したい場合、毎回異なる乱数を使っていると、乱数の差による性能の差なのか、パラメータなどの改善の結果なのか分からなくなってしまうことがあるということで、色々な使い道があるみたいですね。
ちなみにシードを設定しない場合は、システム時刻をシードとすることで、毎回異なるシードとなることを保証しているようですね。そんなカラクリだったのか。
https://docs.scipy.org/doc/numpy/reference/generated/numpy.random.RandomState.html
(こちらを参考にさせていただきました。)
#詳しい方がいらっしゃったら...
n番目の擬似乱数生成の際には、n-1番目の擬似乱数がシードになっているということなのでしょうか?