numpy.random.seed(0)は何をしますか?


282

np.random.seedScikit-Learnチュートリアルの以下のコードで何をしますか?私はNumPyのランダムステートジェネレーターについてはあまり詳しくないので、素人の専門家による用語説明を本当に感謝します。

np.random.seed(0)
indices = np.random.permutation(len(iris_X))

回答:


557

np.random.seed(0) 乱数を予測可能にします

>>> numpy.random.seed(0) ; numpy.random.rand(4)
array([ 0.55,  0.72,  0.6 ,  0.54])
>>> numpy.random.seed(0) ; numpy.random.rand(4)
array([ 0.55,  0.72,  0.6 ,  0.54])

シードをリセットすると(毎回)、同じ番号のセットが毎回表示されます。

ランダムシードがリセットされない場合、呼び出しごとに異なる数値が表示されます。

>>> numpy.random.rand(4)
array([ 0.42,  0.65,  0.44,  0.89])
>>> numpy.random.rand(4)
array([ 0.96,  0.38,  0.79,  0.53])

(疑似)乱数は、数値(シード)で開始し、それを大きな数で乗算し、オフセットを追加して、その合計のモジュロを取ることで機能します。結果の数値は、次の「ランダムな」数値を生成するためのシードとして使用されます。シードを(毎回)設定すると、毎回同じことを行い、同じ番号を与えます。

乱数のように見える場合は、シードを設定しないでください。ただし、デバッグする乱数を使用するコードがある場合、実行するたびにコードが同じことを実行するように、実行する前にシードを設定すると非常に役立ちます。

実行ごとに最もランダムな数値を取得するには、を呼び出しますnumpy.random.seed()これにより、numpyはシード/dev/urandomまたはWindowsアナログから取得した乱数をシードに設定します。これらのどちらも使用できない場合は、クロックを使用します。

シードを使用して疑似乱数を生成する方法の詳細については、ウィキペディアを参照してください。


86
この回答は、numpyのドキュメントに追加する必要があります。ありがとうございました。
gorjanz 2017年

8
また、を呼び出すとnumpy.random.seed(None)、「可能な場合は/ dev / urandom(またはWindowsのアナログ)からデータを読み取ろうとするか、そうでない場合はクロックからシードしようとします」。
ジョナサン

1
@ジョナサンについての優れた点numpy.random.seed(None)。その情報とドキュメントへのリンクで回答を更新しました。
John1024

@ curio1729実装はオペレーティングシステムによって異なる可能性がありますが、numpyはを含むコマンドをseed互換性のあるものにしようとします。
John1024

1
@ L3viathan良い点!より完全かつ正確にするには、オフセットが追加されることを述べておかなければなりません。回答を更新しました。詳細を知りたい方のために、ウィキペディアの疑似乱数発生器に関する議論へのリンクも追加しました。
John1024

38

np.random.seed(a_fixed_number)numpyの他のランダム関数を呼び出すたびに設定すると、結果は同じになります。

>>> import numpy as np
>>> np.random.seed(0) 
>>> perm = np.random.permutation(10) 
>>> print perm 
[2 8 4 9 1 6 7 3 0 5]
>>> np.random.seed(0) 
>>> print np.random.permutation(10) 
[2 8 4 9 1 6 7 3 0 5]
>>> np.random.seed(0) 
>>> print np.random.permutation(10) 
[2 8 4 9 1 6 7 3 0 5]
>>> np.random.seed(0) 
>>> print np.random.permutation(10) 
[2 8 4 9 1 6 7 3 0 5]
>>> np.random.seed(0) 
>>> print np.random.rand(4) 
[0.5488135  0.71518937 0.60276338 0.54488318]
>>> np.random.seed(0) 
>>> print np.random.rand(4) 
[0.5488135  0.71518937 0.60276338 0.54488318]

ただし、一度呼び出してさまざまなランダム関数を使用した場合でも、結果は異なります。

>>> import numpy as np
>>> np.random.seed(0) 
>>> perm = np.random.permutation(10)
>>> print perm 
[2 8 4 9 1 6 7 3 0 5]
>>> np.random.seed(0) 
>>> print np.random.permutation(10)
[2 8 4 9 1 6 7 3 0 5]
>>> print np.random.permutation(10) 
[3 5 1 2 9 8 0 6 7 4]
>>> print np.random.permutation(10) 
[2 3 8 4 5 1 0 6 9 7]
>>> print np.random.rand(4) 
[0.64817187 0.36824154 0.95715516 0.14035078]
>>> print np.random.rand(4) 
[0.87008726 0.47360805 0.80091075 0.52047748]

3
np.randomシードが変更されるまで、以降のすべての呼び出しに対してランダムシードが設定されるように、一度呼び出すことができる関数はありますか?毎回呼び出す必要があることは、不必要に冗長であり、忘れがちです。
Lubed Up Slug

@LubedUpSlugを使用すると、それらを装飾できます。少なくとも、テストしたいくつかの単純なケースでは、機能するはずです。def seed_first(fun, seed=0):| \tdef wrapped(*args, **kwargs):| \t\tnp.random.seed(seed)| \t\treturn fun(*args, **kwargs)| \treturn wrapped、次にfor m in np.random.__all__:| \tif m != 'seed':| \t\tsetattr(np.random, m, seed_first(getattr(np.random, m)))ただし、これは非常に微妙なバグや長期的には奇妙な動作につながる可能性があります。(\ tを4つのスペースで置き換え、|を改行で置き換えます...)
SebastianHöffner'27

1
@SebastianHöffnerコメントありがとうございます。「しかし、一度だけ呼び出してさまざまなランダム関数を使用すると、結果はまだ異なります。」という文に戸惑っていたため、私の質問は少し見当違いnp.random.seed()でした。プログラムの開始時に一度呼び出す と、常に同じ結果が生成されますnp.random関数への後続の呼び出しは後続の呼び出しのシードを決定的に変更するため、同じシードの場合。関数を呼び出すnp.random.seed()前に呼び出すとnp.random、望ましくない結果が生じる可能性があります。
Lubed Up Slug

17

前述のように、numpy.random.seed(0)はランダムシードを0に設定するため、randomから取得する疑似乱数は同じポイントから始まります。これは、デバッグに適している場合があります。しかし、いくつか読んだ後、スレッドセーフではないためにスレッドがある場合、これはそれを行うのに間違った方法のようです。

差分から-numpy-random-and-random-random-in-python

numpy.random.seed()の主な難点は、スレッドセーフではないことです。つまり、2つの異なるスレッドが実行されている場合に動作することが保証されていないため、実行の異なるスレッドが多数ある場合、使用するのは安全ではありません。同時に機能。スレッドを使用しておらず、今後この方法でプログラムを書き直す必要がないと合理的に期待できる場合は、テストの目的でnumpy.random.seed()で問題ありません。将来的にスレッドが必要になると思われる理由がある場合は、長期的には、提案されているようにしてnumpy.random.Randomクラスのローカルインスタンスを作成する方がはるかに安全です。私の知る限り、random.random.seed()はスレッドセーフです(または、少なくともその反対の証拠は見つかりませんでした)。

これに対処する方法の例:

from numpy.random import RandomState
prng = RandomState()
print prng.permutation(10)
prng = RandomState()
print prng.permutation(10)
prng = RandomState(42)
print prng.permutation(10)
prng = RandomState(42)
print prng.permutation(10)

与えるかもしれない:

[3 0 4 6 8 2 1 9 7 5]

[1 6 9 0 2 7 8 3 5 4]

[8 1 5 0 7 2 9 4 3 6]

[8 1 5 0 7 2 9 4 3 6]

最後に、(すべてのビットが0ではないシードとは対照的に)0に初期化すると、xorの動作方法が原因で、最初の数回の反復で不均一な分布になる場合がありますが、これはアルゴリズムによって異なります、そして私の現在の心配とこの質問の範囲を超えています。


12

私はこれをニューラルネットワークで頻繁に使用しています。ニューラルネットワークのトレーニングを開始すると、ランダムに重みを初期化することはよく知られています。モデルは、特定のデータセットのこれらの重みでトレーニングされます。エポックの数の後、トレーニングされた重みのセットを取得します。

ここで、もう一度最初からトレーニングするか、モデルを他の人に渡して結果を再現する場合、重みは再び初期化され、乱数は以前の乱数とほとんど異なります。以前と同じ数のエポック(同じデータと他のパラメーターを保持)の後で取得されたトレーニング済みの重みは異なります。問題は、モデルを再現できないことです。つまり、モデルを最初からトレーニングするたびに、異なる重みのセットが提供されます。これは、モデルが毎回異なる乱数によって初期化されているためです。

最初からトレーニングを開始するたびに、モデルが同じランダムな初期化重みのセットに初期化されるとどうなりますか?この場合、モデルは再現可能になる可能性があります。これは、numpy.random.seed(0)によって実現されます。特定の数値にseed()を言及することにより、常に同じ乱数のセットにつかまっています。


3

たくさんの「ランダムな」数字を使って何かをコーディングする方法を誰かに示していると想像してください。numpyシードを使用することで、同じシード番号を使用し、同じ「ランダム」番号のセットを取得できます。

アルゴリズムは数値を吐き出すので、厳密にランダムではありませんが、ランダムに生成された束のように見えます。


0

ランダムシードは、コンピューターが乱数列を生成するときの開始点を指定します。

たとえば、Excelで乱数を生成したいとしましょう(注:Excelではシードに9999の制限が設定されています)。処理中に[ランダムシード]ボックスに数値を入力すると、同じ乱数セットを再び使用できるようになります。ボックスに「77」と入力し、次に乱数ジェネレータを実行するときに「77」と入力すると、Excelは同じ乱数のセットを表示します。「99」と入力すると、まったく異なる数字のセットが表示されます。しかし、77のシードに戻すと、最初と同じ乱数のセットが得られます。

たとえば、「数値xを取り、900 + xを加算し、次に52を減算します。」プロセスを開始するには、開始番号x(シード)を指定する必要があります。77番から始めましょう。

900 + 77 = 977を加算52 = 925を減算同じアルゴリズムに従って、2番目の「ランダムな」数値は次のようになります。

900 + 925 = 1825減算52 = 1773この単純な例はパターンに従いますが、コンピューター番号生成の背後にあるアルゴリズムははるかに複雑です


0

特定のシード値を設定した後に生成されるすべての乱数は、すべてのプラットフォーム/システムで同じです。



0
numpy.random.seed(0)
numpy.random.randint(10, size=5)

これにより、次の出力が生成されます。 array([5, 0, 3, 3, 7]) ここでも、同じコードを実行すると、同じ結果が得られます。

ここで、シード値0を1またはその他に変更すると、次のようになります。

numpy.random.seed(1)
numpy.random.randint(10, size=5)

これにより、次の出力array([5 8 9 5 0])が生成されます。ただし、出力は上記と同じではありません。


0

上記のすべての回答はnp.random.seed()、コードでのの実装を示しています。それが実際に起こる理由を簡単に説明するために最善を尽くします。コンピューターは、事前定義されたアルゴリズムに基づいて設計されたマシンです。コンピュータからの出力は、入力に実装されたアルゴリズムの結果です。したがって、コンピューターに乱数の生成を要求するときは、それらがランダムであることを確認してください。

したがってnp.random.seed(any_number_here)、アルゴリズムを記述すると、引数に固有の特定の数値セットが出力されますany_number_here。正しい引数を渡せば、特定の乱数セットを取得できるのとほとんど同じです。しかし、これにはアルゴリズムがどのように機能するかを知る必要がありますが、これはかなり退屈な作業です。

したがって、たとえば、np.random.seed(10)取得した特定の数値セットを書き込んだ場合、アルゴリズムが変更されない限り、10年後に同じ行を実行しても同じままになります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.