Generator.normal – 任意の平均・標準偏差の正規分布から乱数配列を作成

Generator.normal は、NumPyのrandomモジュールで任意の平均・標準偏差から乱数配列を生成するためのジェネレータメソッドです。

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

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

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

目次

1. 書式

Generator.normal

書き方:

Generator.normal(loc=0.0, scale=1.0, size=None)

パラメーター:

loc: float or array_like of floats
正規分布の平均値
scale: float or array_like of floats
正規分布の標準偏差
size: int or tuple of ints, optional
配列のshapeを指定する。Noneの場合で、locとscaleがどちらもスカラーなら、1つの数値を返す。それ以外の場合は、np.broadcast(loc, scale).size の個数の数値を返す。

戻り値: 

ndarray or scalar:
パラメータで指定した正規分布から数値を返す

一緒に確認したい関数:

  • scipy.stats.norm

正規分布とは

Generator.normalは、任意の平均・標準偏差の正規分布(「ガウス分布」とも言う)から乱数を生成します。

「正規分布」とは、以下の確率密度関数で表される分布です。

μ は平均値、σ は標準偏差、σ2 は分散です。この関数のピークは平均値にあり、広がりは x+σ と x-σ まであります。

数式を理解する必要はあまりありません。重要なことは、正規分布では平均値にある数値の方が得られやすく、そこから離れた値ほど得られにくくなるということです。

以下で確認しましょう。これは平均値0、標準偏差10の正規分布です。

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

平均値10・標準偏差を5に変更すると、次のような確率分布になります。

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

それではサンプルコードを確認していきましょう。

2. サンプルコード

ジェネレータメソッドは、すべて default_rng で作成したインスタンスに対して使用します。これについては、以下のページで解説しています。

インスタンスの作成は、以下のコードのように、任意の変数にdefault_rng を代入することで行います。

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

これで、ジェネレータオブジェクトの rng が作成されました。任意の正規分布から浮動小数点数の乱数を取得するには、このジェネレータオブジェクト rng に対して normal メソッドを使います。

まず、引数を何も指定しない場合は、平均値0.0標準偏差1.0の正規分布から乱数を1つ取得します。

In [2]:
rng.normal()
# >>> 平均0標準偏差1.0から乱数を1つ取得
Out[2]:
-0.8413583519290193

引数で任意の平均と標準偏差を指定することができます。

In [3]:
rng.normal(40, 10)
# >>> 平均40標準偏差10から乱数を1つ取得
Out[3]:
38.31812844463178

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

In [4]:
rng.normal(40, 10, 5)
# >>> shape(5, )
Out[4]:
array([42.64017114, 32.11372247, 38.36412815, 43.95162295, 33.74208412])

2次元配列以上を指定する場合は、shapeをタプルで渡す必要があります。タプルについては『Pythonのタプルの基本的操作のまとめ』で解説しています。

In [5]:
rng.normal(40, 10, (5, 2))
# >>> shape(5, 2)
Out[5]:
array([[44.45648956, 48.35700372],
       [44.24461095, 59.6719248 ],
       [35.27279466, 53.92793653],
       [37.66498119, 40.70888088],
       [43.50888587, 49.64624937]])

それでは、平均がμ、分散がσ2 の正規分布 N(μ, σ2) から乱数を生成するには、どう書けば良いでしょうか。

例えば、N(3, 6.25)としましょう。この場合、分散(σ2)が6.25なので、標準偏差のsigma(σ)は、√6.25=2.5です。そのため、次のように書きます。

In [6]:
# N(3, 6.25)
rng.normal(3, 2.5, 5)
Out[6]:
array([ 6.80003721,  4.58936533,  2.2751711 ,  5.69593054, -1.39116253])

3. まとめ

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



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

この記事を書いた人

コメント

コメントする

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

目次
閉じる