【NumPy入門】乱数配列の作成(確率分布)

Pythonモジュール「NumPy」で確率分布に基づいた乱数配列を作成する方法についてまとめました。

【整数乱数】random.randint

Pythonでは、NumPyのnumpy.random.randintを利用することで、整数乱数配列を生成できます。

書式

x = numpy.random.randint(a0, an, size)

区間[a0, an) でサンプル数nの整数乱数配列xを生成します。
sizeは配列のサイズです。

# -*- coding: utf-8 -*-
import numpy as np

# 整数乱数の生成
x = np.random.randint(0, 5, 3) # 1次元配列
X = np.random.randint(0, 5, (3,2)) # 2次元配列(サイズは3 * 2)

# 結果表示
print(x) # [2 4 3]

print(X) # [[0 3]
            #  [3 4]
            #  [2 4]]
関連記事
1 【NumPy】整数乱数配列の生成

【一様乱数】random.rand

Pythonモジュール「NumPy」では、numpy.random.rand(N)でサンプル数Nの一様乱数を生成できます。
今回はこれを応用して一様乱数を含んだサンプルデータを生成します。

# -*- coding:utf-8 -*-
from matplotlib import pyplot as plt
import numpy as np


# サンプル数
N = 100

# 乱数係数
d = 5

# 2次元データの生成
x = np.arange(N) + np.random.rand(N) * d
y = np.arange(N) + np.random.rand(N) * d 


plt.plot(x, y, '.')
plt.xlabel('x')
plt.ylabel('y')
plt.grid()
plt.show()

関連記事
1 【Python/NumPy】一様乱数を含んだサンプルデータを生成

【正規分布】random.normal

正規分布(ガウス分布)は、平均値付近に集まるデータの確率分布です。
数値計算モジュールNumPyでは、「numpy.random.normal(mu, sigma)」で平均値mu、標準偏差sigmaの正規分布を求めることが出来ます。

# -*- coding: utf-8 -*-
import numpy as np

# 平均値10, 標準偏差2, サンプル数5の正規分布を生成
x = np.random.normal(10, 2, 5)

print(x)   # [ 11.00899141  10.42910975   8.99929733   7.34544016  12.09384608]
関連記事
1 【NumPy】正規分布(ガウス分布) numpy.random.normal

【標準正規分布】random.randn

標準正規分布は、平均0, 標準偏差1の正規分布(ガウス分布)です。
数値計算モジュールNumPyでは、「numpy.random.randn(n)」で標準正規分布をn個だけ求めることが出来ます。
今回はそれを試してみました。

# -*- coding: utf-8 -*-
import numpy as np

# 標準正規分布を5個生成
x = np.random.randn(5)

print(x)   # [-1.33131684 -0.23846007 0.92566298 -0.27661922 -0.38921705] 
関連記事
1 【NumPy】標準正規分布 numpy.random.randn

【二項分布】random.binomial

Pythonと数値計算モジュールNumPyの「numpy.random.binomial(n, p)」で、試行回数n、確率pの二項分布を求めることが出来ます。
今回はそれを試してみました。

# -*- coding: utf-8 -*-
import numpy as np

# 二項分布の計算(試行回数:1000, 確率:0.5, サンプル数:5)
x = np.random.binomial(1000, 0.5, 5)

print(x)   # [495 500 482 505 510] 

確率1/2で表が出るコインを1000回投げて表が出る回数を求める場合などに使えます。

関連記事
1 【NumPy】二項分布 numpy.random.binomial

【ポアソン分布】random.poisson

ポアソン分布は、発生する確率が低い事象に対する分布です。
つまり、滅多に起きない現象を長期間観察したときに、その現象が起きる回数を分布にしたものです。
Pythonと数値計算モジュールNumPyの「numpy.random.poisson(lam, n)」で、ポアソン分布を求めることが出来ます。
(lamは回数の平均、nはサンプル数)

# -*- coding: utf-8 -*-
import numpy as np

# 平均100のポアソン分布を計算
x = np.random.poisson(100, 5)

print(x)   # [126  85  84 119 102]
関連記事
1 【NumPy】ポアソン分布 numpy.random.binomial

【ベータ分布】random.beta

ベータ分布は、二項分布の共役事前分布などで使われる分布です。
数値計算モジュールNumPyでは、「numpy.random.beta(a,b)」でパラメータa,bのベータ分布を求めることが出来ます。
今回はそれを試してみました。

# -*- coding: utf-8 -*-
import numpy as np

# a=10、b=15、サンプル数5のベータ分布を生成
x = np.random.beta(10, 15, 5)

print(x)   # [ 0.65791516  0.33383715  0.39025457  0.34931183  0.32533295]
関連記事
1 【NumPy】ベータ分布 numpy.random.beta

【χ分布】random.chisquare

NumPyでは、numpy.random.chisquareでカイ二乗分布(χ分布)を作成できます。

書式

x = numpy.random.chisquare(df, n)

サンプル数nと自由度dfを指定してカイ二乗分布を作成します。

# -*- coding: utf-8 -*-
import numpy as np

# カイ二乗分布の生成
x = np.random.chisquare(2, 4) # 自由度2, サイズ4

# 結果表示
print(x) # [ 0.40048804  1.21452084  9.67861117  4.74037653]

関連記事
1 【NumPy】カイ二乗分布(χ分布)を作成

【ガンマ分布】random.gamma

ガンマ分布は、寿命や待ち時間など、経過時間にほとんど無関係なデータの解析に使われる確率分布です。

# -*- coding: utf-8 -*-
import numpy as np

# パラメータp=2、sigma=2でサンプル数10のガンマ分布を生成
x = np.random.gamma(2,2,10)

print(x)   # [ 2.23154819 1.0073614 6.59530984 3.41300524 1.2645674 8.97968952 5.64870617 4.4663702 7.57283312 6.03186415] 

【F分布】random.f

F分布は推定や検定でよく用いられる確率分布です。
数値計算モジュールNumPyでは、「numpy.random.f(num, den, n)」で分子の自由度num、分母の自由度den、サンプル数nのF分布を求めることが出来ます。
今回はそれを試してみました。

# -*- coding: utf-8 -*-
import numpy as np

# 分子の自由度5、分母の自由度8、サンプル数10のF分布を生成
x = np.random.f(5, 8, 10)

print(x)   # [ 1.61518496 0.47417557 1.27663486 0.95166294 2.52872343 0.71423807 1.04646356 3.43721285 1.72896257 0.27017609] 
関連記事
1 【NumPy】F分布 numpy.random.f

【指数分布】random.exponential

指数分布は、基本的な連続時間確率分布の1つです。
機械の寿命や耐用年数、店への来客間隔などのモデル化・解析に使われています。
数値計算モジュールNumPyでは、「numpy.random.exponential(mu, n)」でパラメータmu(分布の平均値)でサンプル数nの指数分布を求めることが出来ます。

# -*- coding: utf-8 -*-
import numpy as np

# パラメータmu=2でサンプル数10の指数分布を生成
x = np.random.exponential(2,10)

print(x)   # [ 3.60749869e-01 2.47586709e+00 2.04374082e+00 2.92558257e+00 1.67523725e-02 3.49127175e+00 3.97050912e+00 6.59820787e-01 1.99104447e+00 9.11290403e-04] 
関連記事
1 【NumPy】指数分布 exponential

【応用】乱数の偏らせる

NumPyでは、「numpy.random.rand」を使って一様乱数(0~1の実数値)を生成できます。
NumPyでは、F分布など様々な確率分布に従った乱数生成ができますが、もっと簡単な方法で乱数の出し方を偏らせることができます。
ゲームなどで活用できるテクニックです。

ヒストグラム(一様乱数)

①小さい値の出現回数を増やす

まずは、小さい値の出現回数を増やすテクニックです。
一様乱数同士を掛け合わせることで0に近い値ほど、出現回数が高くなります。
掛け合わせる回数を増やすほど、その効果も高くなります。

numpy.random.rand(N) * numpy.random.rand(N)

②大きい値の出現回数を増やす

次に、大きい値の出現回数を増やすテクニックです。
①を応用し、「1 – (一様乱数同士を掛け合わせた値)」を計算すれば逆に大きい値の出現回数を増やせます。

コード例

1 - (numpy.random.rand(N) * numpy.random.rand(N))

ヒストグラム

③中央値(0.5)付近の出現回数を増やす

最後に中央値の出現回数を増やすテクニックです。
一様乱数同士を加算し、2で割ると中央値に近い値ほど、出現回数が高くなります。
加算回数を増やすほど、その効果も高くなります。(3回足したら3で割ります)

(numpy.random.rand(N) + numpy.random.rand(N))/2

# -*- coding: utf-8 -*-
import numpy as np
import matplotlib.pyplot as plt

def main():
    # サンプル数
    N = 500

    # 乱数配列を生成(0~1の実数)
    x1 = np.random.rand(N)
    x2 = np.random.rand(N)
    
    #y = x1 # 一様に分布
    #y = x1 * x2 # 小さい値ほど、出現率が高い
    #y = 1 - (x1 * x2) # 大きい値ほど出現回数が高い
    y = (x1 + x2)/2 # 中央値(0.5)に近い値ほど、出現率が高い

    # ヒストグラムの算出
    hist, bins = np.histogram(y,N,[0,1])

    # ビンの末尾を削除して配列のサイズをhistと揃える
    bins = np.delete(bins, -1)

    # グラフ表示
    plt.xlim(0, 1) # x軸の範囲
    plt.ylim(-5, 20) # y軸の範囲 
    plt.scatter(bins, hist, s=5) # 散布図
    plt.xlabel("Value")
    plt.ylabel("Number of occurrences")
    plt.grid()
    plt.show()

if __name__ == '__main__':
    main()
関連記事
1 【NumPy】乱数(ランダム)の出し方を簡単に偏らせる方法
関連記事
1 Python入門 サンプル集
2 NumPy入門 サンプル集
関連記事