Generator.standard_normal – 標準正規分布から乱数配列を生成する方法

Generators.standard_normal は、NumPyのrandomモジュールで標準正規分布(平均0標準偏差1)から乱数配列を生成するためのジェネレータメソッドです。

これと同じ操作は、NumPyのversion1.17までは random.standard_normal関数や、random.randn関数で行っていました。しかし現在では、default_rng で作成したインスタンス(「ジェネレータオブジェクト」とも言う)に対して、Generator.standard_normal メソッドを呼び出すことで行うようになりました。

なお、default_rng については、『numpy.random.default_rng – 乱数生成のためのジェネレータオブジェクトの作成』で解説しているので確認しておいて下さい。

このページでは、このGenerators.standard_normalの使い方を解説します。こちらの方が従来の関数を使った乱数生成よりも大幅に高速で、大量のデータを扱う科学技術計算に適していますので、ぜひ抑えておきましょう。

目次

1. 書式

Generator.standard_normal

書き方:

Generator.standard_normal(size=None, dtype=np.float64, out=None)

パラメーター:

size: int or tuple of ints, optional
出力する配列のshapeを指定する。デフォルト値のNoneでは、1つの乱数を返す。
dtype: dtype, optional
出力する配列の要素の型を指定する。float64とfloat32のみ指定可能。デフォルト値はnp.float64
out: ndarray, optional
戻り値を出力する場所を指定する。sizeがNoneでない場合は、戻り値のshapeと、出力先の配列のshapeが合致している必要がある。

戻り値: 

out: float or ndarray
要素が浮動小数点(float型)で任意のshapeの配列。sizeを渡していない場合はランダムな数値。

標準正規分布とは

Generator.standard_normalは、平均0標準偏差1の正規分布(「ガウス分布」とも言う)から乱数を生成する関数です。正規分布とは、以下のように平均値付近にデータが集積するような確率分布のことです。

In [1]:
import numpy as np
import matplotlib.pyplot as plt
rng = np.random.default_rng()
r = rng.standard_normal(1000000)
plt.hist(r, bins=300)
plt.xlabel('x')
plt.ylabel('frequency')
plt.xlim(-5, 5)
plt.show()

つまり、標準正規分布(平均0標準偏差1)では、平均である0付近の乱数が最も得やすく、そこから離れた乱数ほど得られ難いという分布をしています。

2. サンプルコード

ジェネレータメソッドは、すべて default_rng で作成したインスタンスに対して使用します。インスタンスの作成は、以下のコードのように、任意の変数にdefault_rng を代入することで行います。

In [1]:
import numpy as np
rng = np.random.default_rng()
rng
Out[1]:
Generator(PCG64) at 0x7FE45029E408

これで、ジェネレータオブジェクトの rng が作成されました。さて、ここから連続一様分布から0.0以上1.0未満の浮動小数点数の乱数を取得するには、このジェネレータオブジェクト rng に対して standard_normal メソッドを使います。

まず、引数に何も指定しない場合は、標準正規分布から乱数を1つ取得します。

In [2]:
rng.standard_normal()
Out[2]:
1.7968086631369877

size の指定

オプション引数のsizeでは、出力する配列のshapeを指定することができます。shapeについては『NumPyのshape属性 – 配列の形状の確認と変更』で解説しています。

In [3]:
rng.standard_normal(5)
Out[3]:
array([-0.81737484,  1.49017972,  0.21987996, -0.50285156, -0.09033983])

2次元配列以上を指定する場合は、shapeをタプルで渡します。

In [4]:
rng.standard_normal((5, 2))
Out[4]:
array([[ 0.6783608 ,  0.50853697],
       [-0.74729755, -1.08764893],
       [ 1.21679049,  0.31248734],
       [-0.2450052 ,  1.4441936 ],
       [ 1.7157579 ,  1.12374975]])

dtype の指定

オプション引数のdtypeでは、出力する配列の要素の型をfloat64にするかfloat32にするかを指定することができます。デフォルト値はfloat64です。

In [5]:
rng.standard_normal(5, dtype=np.float32)
Out[5]:
array([-0.6137521 , -1.769938  ,  1.9909625 , -0.66614056, -1.0448095 ],
      dtype=float32)

基本的にfloat32にすると処理速度が高速になります。ただし、float64と32では、内部での計算方法が異なる部分があるため注意が必要です。この点も含めて『NumPyのdtype属性の一覧と参照・指定・変更方法』で詳しく解説しています。

out の指定

オプション引数のoutでは、出力する配列で既存の配列を上書きすることができます。この場合、出力する配列と上書きする配列のshapeが一致している必要があります。

In [6]:
arr = np.zeros((3, 3))
rng.standard_normal((3, 3), out=arr)
arr
Out[6]:
array([[ 1.22219497,  0.28467593,  0.18549921],
       [ 0.19072461, -0.65931668, -0.08793845],
       [-0.14414122,  0.31735662, -0.20928704]])

任意の平均と標準偏差を指定したい場合

もし平均がμ、分散がσ2 の正規分布 N(μ, σ2) からランダムな数値を得たいとしたら、次のように書きます。なお、σは標準偏差です(※標準偏差 = √分散2

μ + σ * rng.standard_normal(size=...)

例として、N(3, 6.25)の正規分布からランダムな値を得たいとします。この場合、標準偏差は、√6.25=2.5です。そのため次のように書きます。

In [7]:
# N(3, 6.25)から乱数を生成
3 + 2.5 * rng.standard_normal((2, 4))
Out[7]:
array([[5.64076858, 0.37798596, 6.69987659, 2.87023256],
       [3.94890744, 1.48787759, 4.59541984, 6.18473446]])

ただし、任意の平均や標準偏差の正規分布から乱数を生成したい場合は、Generator.normalメソッドを使う方がはるかに簡単です。このメソッドでは、引数で平均と標準偏差を指定することができます。以下で解説しています。

3. まとめ

以上が Generators.standard_normalの使い方です。これまでは、同じ操作をするのに、random.standard_normal関数や、random.randn関数が使われてきましたが、これからはこの Generators.standard_normalを使うようにしていきましょう。



よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

目次
閉じる