NumPyの使い方(12) 乱数、random
乱数を発生させるライブラリは主に2つ。
randomライブラリとNumPyのrandom
2つのライブラリの一番の違いは乱数の発生個数。
乱数の発生個数
randomモジュール :乱数1個
numpyは配列の形をsize=~の形のキーワード引数で乱数の個数を指定できる。
size 省略 →1個の乱数
size = 数値 →1次元配列
size = タプル→多次元配列
乱数の初期化
random.seed(数値)
np.random.seed(数値)
同じ初期値にすると、再現性のある乱数列になる。
小数(一様uniform)
0~1の乱数
random.random() | 0~1の乱数乱数を1個生成。 |
np.random.rand(size) | 0~1の乱数列。配列生成後に再計算すると範囲を変えられる |
範囲を指定した乱数
random.uniform(low, high) | low以上high未満の一様乱数を1個生成 |
np.random.uniform(low, high, size) | low以上high未満の一様乱数 |
import numpy as np import random print(random.random()) # 0.9733563537374995 print(np.random.rand(3)) # [ 0.69962497 0.61950126 0.7944733 ] print(np.random.rand(2, 3)) # [[ 0.29315148 0.06560949 0.56110618] # [ 0.62784039 0.19218867 0.07087768]] np.random.uniform(1, 10, 3) 1以上10未満の一様乱数3個の配列。 # [ 8.77776521 4.21775806 9.269332 ]
・乱数で円周率を求める:
サンプルコードはこちら
・ランダムウォーク
0~1の乱数を生成し、0.5以上なら+1、0.5未満なら-1を加えていく。
# coding: utf-8 import numpy as np import matplotlib.pyplot as plt np.random.seed(1) # 乱数の初期化。 w = np.random.rand(1000) # 1000個の乱数生成 w = np.where(w > 0.5, 1, -1) # 0.5以上は1に、0.5未満は-1に変更 w = w.cumsum() # 累積和を取る print(w.min()) # -11 print(w.max()) # 35 print(w.argmin()) # 64 最初に-11になったインデックス print(w.argmax()) # 368 最初に35になったインデックス plt.plot(np.arange(1000), w) # 折れ線グラフとして表示 plt.scatter(w.argmin(), w.min(), marker="D", c="r") plt.scatter(w.argmax(), w.max(), marker="D", c="r") plt.text(w.argmin(), w.min(), "min", fontsize=16) plt.text(w.argmax(), w.max(), "max", fontsize=16) plt.show()
株価の変動のようなグラフになりますね。
seed()の値をいろいろ変えてみると面白そう。
小数(分布が一様ではない)
・正規分布(ガウス分布)に従う乱数 normal distribution
random.normalvariate(mu, sigma) | mu:平均、sigma:標準偏差 |
random.gauss(mu, sigma) | normalvariateより少し速い |
np.random.normal(loc, scale=1.0, size) | loc:平均、scale:標準偏差 |
・標準正規分布に従う standard normal distribution
np.random.randn(size) | 標準正規分布(平均0、標準偏差1) |
・β分布(ベータ分布)
random.betavariate(alpha, beta) | β分布の乱数 |
np.random.beta(a, b, size) |
・γ分布(ガンマ分布)
gammavariate(alpha, beta) | alpha>0, beta>0 |
random.gammavariate(alpha, beta) | ガンマ分布の乱数 |
・カイ2乗分布
np.random.chisquare(df,size) | df:自由度 |
・指数分布
random.expovariate(lambd) | lambdaは予約語なのでlambd |
np.random.exponential(scale, size) | scale:β=1/λ |
・対数分布
random.lognormvariate(mu, sigma) | 対数分布の乱数 |
np.random.lognormal(mean, sigma, size) | mean:平均、sigma:標準偏差 |
print(np.random.randn(3, 3)) #標準正規分布の3×3配列 # [[-0.52434526 0.16597271 -2.22295048] # [ 0.46995083 -0.64576356 -2.73155503] # [ 1.04575168 0.05712791 -0.46522963]] print(np.random.normal(10, 5, (2, 3))) #平均10、標準偏差5、2行3列 # [[ 15.15167613 9.56576376 5.79689885] # [ 18.18351327 17.17248557 3.4675871 ]]
mu(平均)=20、sd(標準偏差)=5の乱数を10000回発生させ、
ヒストグラム(青)で表示し、正規分布のグラフ(赤)と比較する。
import numpy as np import matplotlib.pyplot as plt mu, sd = 20, 5 s = np.random.normal(mu, sd, 10000) count, bins, ignored = plt.hist(s, 40, normed=True) plt.plot(bins, 1/(sd * np.sqrt(2 * np.pi)) * np.exp( - (bins - mu)**2 / (2 * sd**2) ), linewidth=2, color='r') plt.show()
整数
random.randint(low, high) | low以上、high以下の整数の乱数を1個生成 |
random.randrange(low, high, step) | low以上、high未満、stepの乱数を1個生成 |
np.random.randint(low, high, size) | low以上、high未満 |
np.random.random_integers | 非推奨 |
np.random.randint(1, 10, 2) #1以上10未満の整数2個のndarrayを生成。 np.random.randint(1, 10, (2, 3) #2行3列のndarrayを生成。 np.random.randint(2, size=8) #highを省略すると、lowの値をhigh扱い。 # array([1, 0, 0, 0, 1, 1, 1, 0]) np.random.randint(1, size=8) #1未満の整数、つまり0のみ。 # array([0, 0, 0, 0, 0, 0, 0, 0])
・2項分布に従う
np.random.binomial(n, p, size) | n:試行回数 p:確率 |
# コインを100回投げて表が出た回数 a = np.random.binomial(100, 0.5) print(a) # 48 #コインを100回投げて表が出た回数を10セット print(np.random.binomial(100, 0.5, (2, 5))) # [[53 43 48 49 44] # [48 47 55 44 60]]
選択
random.choice(seq) | seqから1個選択 |
np.random.choice(a) | aから複数個選択 |
np.random.choice(a, size=None, replace=True, p=None)
a:1次元のndarrayまたはリストの場合、その要素からチョイス。
数値の場合はnp.arange()で要素を準備
replace True:重複あり、False:重複なし
p:和が1となる重みづけのリスト。
seq1=[0、1、2、3] random.choice(seq1) #1回チョイス random.choice("hello") #5文字の中から1文字チョイス np.random.choice(seq1, 4) #重複ありで4回チョイスした配列 np.random.choice([2, 4, 6],2) #重複ありで2回チョイスした配列 np.random.choice([0, 1], (3, 3)) #size3×3の配列に0,1を埋める np.random.choice(5, 2) #np.randint(0, 5, 2)と同義
np.random.choiceで描いたバーンスレイのシダ。サンプルコードはこちら
シャッフル
random.shuffle(list) | listをシャッフルする。返り値はNone |
np.random.shuffle(x) | listまたはarrayをシャッフルする。返り値はNone |
arr = np.arange(10) np.random.shuffle(arr) #[1 7 5 2 9 4 3 6 0 8]
サンプリング
random.sample(population, k) populationの中からk個選んだリストを返す。
populationはシーケンスまたはset。ハッシュ可能でなくてもよい。値はダブり可
random.sample("abcd", 3) #['d', 'c', 'a'] random.sample("abcd", 6) #ValueError: Sample larger than population random.sample(range(1000), k=20) #0-999から20個選ぶ
参考:numpyのドキュメント