web-dev-qa-db-ja.com

Pythonのnumpy.randomとrandom.randomの違い

Pythonには大きなスクリプトがあります。私は他の人のコードにインスピレーションを与えたので、いくつかのことのためにnumpy.randomモジュールを使用することになりました(たとえば、二項分布から取得した乱数の配列を作成するため)および他の場所でモジュールrandom.randomを使用します。

誰かが2つの主な違いを教えてもらえますか? 2つのそれぞれのドキュメントWebページを見ると、numpy.randomにはさらにメソッドがあるだけのように思えますが、乱数の生成がどのように異なるかはわかりません。

私が尋ねている理由は、デバッグのためにメインプログラムをシードする必要があるためです。しかし、インポートするすべてのモジュールで同じ乱数ジェネレーターを使用しないと機能しません。これは正しいですか?

また、別の投稿でnumpy.random.seed()を使用しないことに関する議論を読みましたが、なぜこれがそんなに悪い考えであるのか本当に理解していませんでした。なぜそうなのか、誰かが私に説明してくれたら本当にありがたいです。

87
Laura

すでに多くの正しい観測を行っています!

両方のランダムジェネレータをシードする場合を除き、長い目で見ればどちらかのジェネレータを選択する方がおそらく簡単です。

numpy.random.seed()の主な難点は、スレッドセーフではないことです。つまり、 多数の異なる実行スレッド がある場合、使用するのは安全ではありません。 2つの異なるスレッドが同時に関数を実行している場合に機能します。スレッドを使用しておらず、将来この方法でプログラムを書き換える必要がないと合理的に予想できる場合は、numpy.random.seed()で十分です。将来的にスレッドが必要になると思われる理由がある場合は、提案されたとおりに行うこと、および _numpy.random.Random_クラスのローカルインスタンスを作成する を実行する方が長期的にははるかに安全です。私が知る限り、random.random.seed()はスレッドセーフです(または、少なくとも、逆の証拠は見つかりませんでした)。

_numpy.random_ライブラリには、科学研究で一般的に使用されるいくつかの追加の確率分布と、ランダムデータの配列を生成するための便利な関数がいくつか含まれています。 _random.random_ライブラリーはもう少し軽量であり、統計で科学的な研究や他の種類の作業をしていない場合は問題ないはずです。

それ以外の場合、両方とも Mersenneツイスターシーケンス を使用して乱数を生成し、両方とも完全に決定論的です。つまり、いくつかの重要な情報を知っていれば、絶対確実に予測することができます。 次に来る番号 。このため、numpy.randomもrandom.randomも 深刻な暗号化の使用 には適していません。しかし、シーケンスは非常に長いので、データをリバースエンジニアリングしようとする人々が心配されない場合、どちらも乱数を生成するのに適しています。これは、ランダムな値をシードする必要がある理由でもあります。毎回同じ場所で開始すると、常に同じ乱数列が得られます。

サイドノートとして、do暗号化レベルのランダム性が必要な場合、 secrets モジュール、または-のようなものを使用する必要があります Crypto.Random Python Python 3.6。

104
Hannele

データ分析用Python から、モジュールnumpy.randomは、Python randomを補完し、多くの種類の確率分布からサンプル値の配列全体を効率的に生成するための関数です。

対照的に、Pythonの組み込みrandomモジュールは一度に1つの値のみをサンプリングしますが、numpy.randomは、非常に大きなサンプルをより速く生成できます。 IPythonマジック関数を使用する%timeitどのモジュールがより高速に実行されるかを見ることができます。

In [1]: from random import normalvariate
In [2]: N = 1000000

In [3]: %timeit samples = [normalvariate(0, 1) for _ in xrange(N)]
1 loop, best of 3: 963 ms per loop

In [4]: %timeit np.random.normal(size=N)
10 loops, best of 3: 38.5 ms per loop
11
lmiguelvargasf

シードのソースと使用される分布プロファイルは出力に影響します-暗号のランダム性を探している場合、os.urandom()からシードすると、デバイスチャッター(つまり、イーサネットまたはディスク)からほぼ実際のランダムバイトが取得されます(つまり/ BSDのdev/random)

これにより、シードを与えて決定論的乱数を生成することを回避できます。ただし、ランダムコールを使用すると、数値を分布に適合させることができます(科学的なランダムネスと呼びます-最終的に必要なのは、乱数のベルカーブ分布だけです。numpyがこれを判断するのに最適です。

ええ、1つのジェネレーターを使い続けますが、必要なランダムを決定します-ランダムですが、分散曲線から、または量子デバイスなしで取得できる限りランダムです。