Python入門トップページ


目次

  1. 実数分布
  2. 整数分布
  3. シーケンス用の関数
  4. 乱数生成器の初期化
  5. 参考資料

乱数を使ってみよう

実数分布

シミュレーションやニューラルネットワーク(ディープラーニング)等で多数の乱数を発生させる必要がある場合は,処理速度等の理由から NumPy の乱数生成 (Random Generator) の使用を推奨します.

まずは,実数(浮動小数点数)を出力する関数を使ってみる.

random.random() 関数では,0.0 以上 1.0 未満の(つまり,\( [0.0,~1.0) \) の)浮動小数点数が生成される.もちろん,実行するたびに異なる値が得られるであろう.

乱数を1つ生成するimport random # プログラムの先頭でモジュールを読み込む
random.random()
0.307875959312755
乱数を10個生成するn = 10
for i in range(n):
    rnd = random.random()
    print(rnd)
0.19717484409230845
0.7559813495734007
0.4058681479275186
0.09860323973595408
0.4128542919796765
0.7232626241236154
0.23453376947613935
0.8194188802933575
0.2164427866692794
0.8042963801683684

random.uniform(a, b) 関数では,a 以上 b 以下の浮動小数点数が生成される.

5以上9未満の乱数n = 10
a = 5
b = 9
for i in range(n):
    rnd = random.uniform(a, b)
    print(rnd)
8.22956942276602
8.71816114039104
7.318089366385012
7.1971724442098965
6.555698401150572
8.678228651180987
8.520817929719577
7.721705524796164
5.093177859829925
7.510118174004649

正規分布に従う乱数を発生したければ random.normalvariate(mu, sigma) を使用すれば良い.ここで mu は平均,sigma は標準偏差である.出力結果を観察すると,平均値 (20) 付近のデータが多く生成されていることがわかる.

平均20,標準偏差3の正規乱数を生成し,ヒストグラムを描くimport matplotlib.pyplot as plt
n = 100
mu= 20
sigma = 3
rnd = []
for i in range(n):
    rnd.append(random.normalvariate(mu, sigma))
print(sorted(rnd))
# ヒストグラムを描く
fig, ax = plt.subplots(1, 1, figsize=(6, 4))
ax.hist(rnd, bins=15)
# plt.savefig('normal.png', dpi=300, facecolor='white')
plt.show()
[13.80312498938364, 13.98433387132934, 14.536838731094146, 15.470273393859781, 15.565602861924592, 15.68412490300932, 15.956519427640178, 16.059049227412444, 16.076400403489018, 16.091595784066985, 16.138218854436502, 16.359346085235792, 16.368844387194972, 16.39033091221568, 16.576251390037147, 16.94680944647721, 17.003512448250525, 17.137624349726796, 17.26564326714757, 17.316615085350918, 17.55771120162852, 17.582268089455813, 17.65484025424283, 17.6610549467154, 17.883823840587066, 18.031662117752006, 18.15755120073785, 18.372794392500452, 18.38699458903991, 18.428026302656914, 18.592801923908866, 18.64168731589714, 18.70262557922576, 18.713059081195464, 18.786296400797127, 18.81927380719902, 18.908703550153724, 18.950168025808043, 18.961337750985724, 18.967084036968714, 19.078346665139033, 19.15026553733965, 19.15533577280136, 19.28835174391877, 19.30875330459698, 19.5109370437007, 19.553019278723102, 19.75160362608554, 19.759445535519866, 19.783142443605932, 19.81630060197339, 19.883868178224795, 20.115717243831412, 20.172433839593886, 20.273993411146982, 20.27762015568849, 20.346805004024002, 20.371167360796814, 20.47974332890248, 20.513773359791177, 20.636333950490982, 20.73328856201616, 20.826142573409413, 20.880009769480562, 20.88301136668704, 20.97352656581278, 21.17148781281712, 21.438244399503088, 21.47548294077285, 21.681354117637447, 21.68560982609956, 21.823779457473897, 21.87671098869518, 21.88460320538494, 22.01221578617727, 22.032818002892036, 22.43941229447121, 22.457887014280043, 22.50477575220444, 22.562731854001623, 22.924763529090256, 23.05516916491794, 23.174828863513678, 23.21156520818652, 23.62931542670987, 23.633631200066418, 23.652494162689266, 23.70176240535463, 23.829067030900855, 24.074289708557913, 24.128115757067864, 24.274609878977614, 24.311115895892158, 24.357210113386493, 24.442316608255368, 25.690987136077958, 25.9462011719362, 26.380544591614544, 26.46396966832299, 27.446009740462653]
normal-100

なお,一様乱数から標準正規分布に従う乱数を自分で発生させたい場合には Box-Muller法を使うとよい.具体的には2つの独立な一様乱数 \(X\), \(Y\) から次の式(いずれか)を用いて生成できる.

\begin{eqnarray} Z_1 &=& \sqrt{-2 \log X} \sin(2 \pi Y) \\ Z_2 &=& \sqrt{-2 \log X} \cos(2 \pi Y) \end{eqnarray}

例えば,\( \sin \) の式を使って,平均 \(\mu\),標準偏差 \(\sigma\) の正規乱数を発生させるコードは次のようになる.具体的には,上の式で得られた標準正規乱数を \(\sigma\) 倍することで,平均 0,標準偏差 \(\sigma\) の正規乱数になる.さらにこれに \(\mu\) を足すことで平均 \(\mu\),標準偏差 \(\sigma\) の正規乱数になる.

標準正規分布import random
import numpy as np

def normal(mu=0, sigma=1):
    X = random.random()
    Y = random.random()
    return np.sqrt(-2.0 * np.log(X)) * np.sin(2 * np.pi * Y) * sigma + mu
#     return np.sqrt(-2.0 * np.log(X)) * np.cos(2 * np.pi * Y) * sigma + mu

n = 10000
mu = 20
sigma = 3
rnd = []
for i in range(n):
    rnd.append(normal(mu, sigma))
# print(sorted(rnd))
# ヒストグラムを描く
fig, ax = plt.subplots(1, 1, figsize=(6, 4))
ax.hist(rnd, bins=15)
# plt.savefig('normal-10000.png', dpi=300, facecolor='white')
plt.show()
normal-10000

目次に戻る