2016-04-25 5 views
11

numpy.random.seed()の中にさまざまな数字を入れることができます。たとえば、numpy.random.seed(1)numpy.random.seed(101)などです。異なる数字は何を意味しますか?あなたはどのように番号を選んでいますか?numpy.random.seed()に入れることができる数字は何ですか?

+1

次の「ランダム」シーケンスの内容を決定するだけで、実際には関係ありません。値が実行ごとに変化しないようにテストに役立ちます。私は通常、「42」を使用します... – martineau

答えて

0

基本的に、この数字は毎回同じ「ランダム性」を保証します。

より適切には、数値は整数、任意の長さの整数の配列(またはその他の順序)、またはデフォルト(なし)のいずれかのシードです。 seedがnoneの場合、randomは利用可能であれば/ dev/urandomからデータを読み取ろうとするか、そうでなければclockからseedを作ります。

編集:あなたのプログラムがスーパーセキュアである必要があるものでない限り、ほとんどの正直なところ、あなたが選んだものは問題ではありません。このような場合は、これらのメソッドを使用しないでください。暗号で安全な擬似乱数ジェネレータが必要な場合は、os.urandom()またはSystemRandomを使用してください。

ここで理解する最も重要な概念は、擬似ランダム性の概念です。このアイデアを理解したら、プログラムに本当に種子などが必要かどうかを判断できます。hereを読むことをお勧めします。

+4

この回答は私には不完全です。 "random.seed(random.random())"と書いてもいいですか? 7は4より良いですか?配列をハッシュするだけですか?基本的に、ここで何が起こっているのですか? "どのように番号を選ぶのですか"という質問の中で最も重要な行と思われるimo –

+0

@en_Knight - 私はちょうど私の答えでこの種の細部を与えることを試みた。 –

0

ランダムシードの意味を理解するには、値が決定論的アルゴリズムを使用して計算されるため、「疑似ランダム」数列を最初に理解する必要があります。

この番号は、ランダムジェネレータから取得する次の番号を計算するための開始値と考えることができます。ここで同じ値を設定すると、毎回プログラムが同じ「ランダム」な値になるので、プログラムは決定的になります。

としては、このpost

彼ら(numpy.randomrandom.random)の中で述べて両方の彼らの乱数を生成するためにメルセンヌツイスター・シーケンスを使用して、彼らは両方とも完全に決定論的だ - つまり、あなたはいくつかのキーを知っていれば情報のビット数によって、次に何が来るかを絶対確実に予測することが可能です。

ランダム性が本当に気になる場合は、ノイズ(いくつかの任意の単語)を生成するか、シードとしてシステム時間を入力するようにユーザーに依頼してください。

あなたのコードがインテルCPU(または最新のチップを搭載したAMD)で実行されている場合は、rdrandを使用して「真」(ハードウェア)ランダム性を収集するRdRandパッケージをチェックすることをお勧めします。

参考文献:Z[i]ith乱数、あり、ここで

Z[i] = (a*Z[i-1] + c) % m 

  1. Random seed
  2. What is a seed in terms of generating a random number
+0

これは重要だと思われます。「本当にランダム性が気になる場合は、ノイズ(いくつかの任意の単語)を生成するか、シードとしてシステム時間を入れるようにユーザーに依頼してください」しかし、私はその半分しか買っていないと思う。ユーザが毎回同じような共通の言葉を「ランダムに」選ぶかもしれないように思える - pplはランダムではない。時間はかなり良いアドバイスです。しかし、ここでは私が何をすべきかを知るのに十分ではありません。例えば、あなたが書いたことに基づいて、セッションで種まきをリセットし続けることは賢明です。実際にそうすることは、逆効果である –

+0

私は、リセットを続けることをお勧めしませんでした。対照的に、シード**は一度しか設定しないでください**。要点は、攻撃者があなたの乱数を推測するのを防ぐことです。誰かが最初にあなたの種子を推測できるなら、私は彼/彼女が残りを知ることもできると思います。 – gdlmx

+0

セキュリティタグは表示されません。モデリングとシミュレーションにnumpyが使用されています。その場合は、実験を再現できるほど攻撃者に気にしないでしょうか? 「再設定を続ける」という私のコメントは、あなたが明示的に*それを主張しているのではなく、シードの実際の働きについての情報はあまりないということです。私が種子を選ぶ方法を尋ねると、その種の共通のミスを払拭するための何もない、種と種を設定する方法を知るのに十分な情報があるはずです。 –

6

非常に基本的な乱数生成器を考えてみましょう0は乗算器で、cはインクリメントです - 異なるacmの組み合わせで、それぞれ異なるジェネレータがあります。これは、Lehmerによって紹介されたlinear congruential generatorとして知られています。その除算の残りの部分または係数(%)は、0とm-1の間の数値を生成し、U[i] = Z[i]/mを設定すると、ゼロと1の間の乱数が得られます。

この世代のプロセスを開始するには、Z[1]にするには、初期値であるZ[0]が必要です。プロセスを開始するこの初期値はシードと呼ばれます。この例を見てみましょう:

enter image description here

初期値を、種子は、処理を開始し7のように決定されます。ただし、その値は乱数の生成には使用されません。代わりに、最初のZを生成するために使用されます。

擬似乱数ジェネレータの最も重要な機能は予測不可能なことです。一般的に、あなたの種子を共有しない限り、今日のジェネレータはこれよりもはるかに複雑であるため、すべての種子でうまくいきます。しかし、さらなるステップとして、ランダムにシードを生成することもできます。もう1つの方法として、最初のnの数字を省略することもできます。

主な情報源:Law、A. M.(2007)。シミュレーションモデリングと解析。タタ・マグロウヒル。

+0

私はこの答えが好きです。 "ほとんどの重要な機能は...予測不可能です":逆の予測可能性が必要な場合は、アルゴリズムによる再現性が必要になることがあります(セキュリティではなくモデリングを行うためです)。また、乱数を生成するための種を持つ前にランダムに種を生成する方法はありますか?発生したrecursion-overflow例外のタイムスタンプを取る:)また、numpyは明示的にそのランダムジェネレータを使用しません - このアドバイスはnumpyのランダムモジュールに対して保持されますか? –

+0

私は再現性が非常に重要であることに同意します。それが私たちがシードを共有する理由ですが、再現性は私が思う予測可能性を正確に意味しません。数字には依然として統一性と独立性の特徴があります。それらの数字だけを使って予測することはできません。それらは基礎となるプロセスを知っている*計算*することができます。 – ayhan

+0

AFAIK:AFAIK多くのアプリケーションでは、あなたが作成したものに似た何かを使用しています:現時点のmodのナノ秒その他のものなどPythonはMersenne-Twisterを使用していますが、 https://en.wikipedia.org/wiki/Mersenne_Twister線形合同ジェネレータとは異なりますが、この再帰的プロセスもあります。プロセスを開始するための種と呼ばれるものがあれば、同じロジックが適用されるはずです。 :) – ayhan

1

短い答え:

  • 使用引数なしまたは使用None - RNGは、OSの乱数発生器から自身を初期化:

    numpy.randomseed()乱数発生器への3つの方法があります。 (一般的には暗号的にランダムです)

  • いくつかの32ビット整数Nを使用します - RNGはこれを使用して確定的関数に基づいて状態を初期化します→同じ状態)

  • 等、 N 32ビット整数のアレイ状の配列を使用し、N 、N - 再度、RNGは、その状態を初期化するためにこれを使用します決定的な関数(同じ状態のシードの同じ値)に基づいて計算されます。これはソースコードにマジックナンバーがありますが、なぜ彼らが何をやっているのかは分かりませんが、ソートのハッシュ関数を使って行うことを意図しています。

繰り返し可能で簡単な操作を行う場合は、単一の整数を使用します。

再現性があるものの、第三者に推測されそうなことをしたい場合は、タプルやリスト、または32ビット整数のシーケンスを含むnumpy配列を使用します。たとえば、numpy.randomNoneという種子で使用すると、OSのRNGから32ビットの整数(32ビット、合計で1024ビット)が生成され、シードに格納されます。Sいくつかの秘密の場所に保存し、そのシードを使用して、任意の擬似乱数列Rを生成します。次に、Sを再度シードして、そのシーケンスを後で再作成することができます。そして、Sの値を秘密(生成された数R)に保つ限り、誰もそのシーケンスRを再現することはできません。単一の整数を使用すると、わずか40億の可能性しかなく、誰かがそれらをすべて試みる可能性があります。それは妄想の側で少しかもしれませんが、あなたはそれをすることができます。

長い

numpy.randomモジュールを使用すると、次のいずれかの方法で自分自身を確認することができMersenne Twisterアルゴリズムを使用しています

に答える:

  • どちらかnumpy.random.RandomStateのドキュメントを見ることで、そのnumpy.randomは、numpy.random.*関数のインスタンスを使用します(ただし、独立した独立インスタンスの使用も可能です)

  • mtrand.pyxsource codeを見ると、Pyrexというものを使用して高速のC実装をラップし、randomkit.cinitarray.cとなります。いずれの場合においても

ここnumpy.random.RandomStateドキュメントを約seed()言うものです:

互換性の保証固定種と同じパラメータを使用してRandomStateメソッドの呼び出しの固定シリーズは、常に同じが生成されます値が正しくない場合を除いて丸め誤差が発生します。間違った値が修正され、修正が行われたNumPyのバージョンが関連するドキュメントストリングに記録されます。以前の動作が変更されない限り、既存のパラメータ範囲の拡張および新しいパラメータの追加が許可されます。

パラメータ:
種:{なし、INT、array_like}、擬似乱数生成器を初期化するために使用される任意

ランダムシードが。 0〜2 ** 32 - 1の整数、その​​ような整数の配列(または他のシーケンス)、またはNone(デフォルト)の任意の整数になります。シードがNoneの場合、RandomStateは可能であれば/dev/urandom(またはWindowsアナログ)からデータを読み取ろうとします。そうでない場合はクロックからシードします。

それは種子が使用されているか言っていませんが、あなたはそれがinit_by_array機能を参照するソースコードに掘る場合:(省略さドキュメンテーション文字列)

def seed(self, seed=None): 
    cdef rk_error errcode 
    cdef ndarray obj "arrayObject_obj" 
    try: 
     if seed is None: 
      with self.lock: 
       errcode = rk_randomseed(self.internal_state) 
     else: 
      idx = operator.index(seed) 
      if idx > int(2**32 - 1) or idx < 0: 
       raise ValueError("Seed must be between 0 and 2**32 - 1") 
      with self.lock: 
       rk_seed(idx, self.internal_state) 
    except TypeError: 
     obj = np.asarray(seed).astype(np.int64, casting='safe') 
     if ((obj > int(2**32 - 1)) | (obj < 0)).any(): 
      raise ValueError("Seed must be between 0 and 2**32 - 1") 
     obj = obj.astype('L', casting='unsafe') 
     with self.lock: 
      init_by_array(self.internal_state, <unsigned long *>PyArray_DATA(obj), 
       PyArray_DIM(obj, 0)) 

そして、ここでは何init_by_array機能のルックスです等:

extern void 
init_by_array(rk_state *self, unsigned long init_key[], npy_intp key_length) 
{ 
    /* was signed in the original code. RDH 12/16/2002 */ 
    npy_intp i = 1; 
    npy_intp j = 0; 
    unsigned long *mt = self->key; 
    npy_intp k; 

    init_genrand(self, 19650218UL); 
    k = (RK_STATE_LEN > key_length ? RK_STATE_LEN : key_length); 
    for (; k; k--) { 
     /* non linear */ 
     mt[i] = (mt[i]^((mt[i - 1]^(mt[i - 1] >> 30)) * 1664525UL)) 
      + init_key[j] + j; 
     /* for > 32 bit machines */ 
     mt[i] &= 0xffffffffUL; 
     i++; 
     j++; 
     if (i >= RK_STATE_LEN) { 
      mt[0] = mt[RK_STATE_LEN - 1]; 
      i = 1; 
     } 
     if (j >= key_length) { 
      j = 0; 
     } 
    } 
    for (k = RK_STATE_LEN - 1; k; k--) { 
     mt[i] = (mt[i]^((mt[i-1]^(mt[i-1] >> 30)) * 1566083941UL)) 
      - i; /* non linear */ 
     mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ 
     i++; 
     if (i >= RK_STATE_LEN) { 
      mt[0] = mt[RK_STATE_LEN - 1]; 
      i = 1; 
     } 
    } 

    mt[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */ 
    self->gauss = 0; 
    self->has_gauss = 0; 
    self->has_binomial = 0; 
} 

シード値の提供された配列内の各値を使用して、この本質的に非線形で「munges」乱数の状態を、ハッシュのような方法。

3

実際に乱数シーケンスと呼ばれるものは、値が決定論的アルゴリズムを使用して計算され、確率が実際の役割を果たすものではないため、「疑似乱数」シーケンスです。

"シード"はシーケンスの開始点であり、同じシードから開始する場合、同じシーケンス番号が返されるという保証があります。これは、デバッグなどの場合に非常に便利です(プログラムのエラーを探して、問題を再現して調べる必要がある場合、すべての実行が異なるため、非決定的なプログラムはデバッグするのがずっと難しくなります) 。