この記事は、様々な確率分布の擬似乱数を生成するために使用されるPythonの random モジュールについて書かれています。
Python random Module Methods
1. seed()
これは乱数発生器を初期化します。
新しい乱数列を生成するためには、現在のシステム時間に応じてシードを設定する必要があります。
random.seed() は乱数生成のためのシードを設定します。
2. getstate()
これはジェネレータの現在の状態を含むオブジェクトを返します。
状態を復元するには、そのオブジェクトを setstate() に渡す。
setstate(state_obj)
これは getstate() が呼ばれた時点のジェネレータの状態を、state オブジェクトを渡すことで復元します。
4. getrandbits(k)
これは k 個のランダムビットを持つ Python の整数を返します。
これは randrange() のような、乱数生成のために任意の大きな範囲を扱うメソッドに便利です。
>>> import random
>>> random.getrandbits(100) # Get a random integer having 100 bits
802952130840845478288641107953 |
以下は getstate() と setstate() メソッドを説明するための例です。
import random
random.seed(1)
# Get the state of the generatorstate = random.getstate()
print('Generating a random sequence of 3 integers...')
for i in range(3):
print(random.randint(1, 1000))
# Restore the state to a point before the sequence was generatedrandom.setstate(state)print('Generating the same identical sequence of 3 integers...')
for i in range(3):
print(random.randint(1, 1000))
|
可能な出力
Generating a random sequence of 3 integers...
138583868Generating the same identical sequence of 3 integers...
138583868 |
ランダムな整数を生成する
randomモジュールは、ランダムな整数を生成するためのいくつかの特別なメソッドを提供します。
1. randrange(start, stop, step)
range(start, stop, step)からランダムに選択された整数を返します。
もしstart>stopならばValueError` を発生させます。
2. randint(a, b)
a と b の間のランダムな整数を返します(両方を含む)。
a>bの場合、ValueError` も発生します。
以下は、上記の2つの関数を説明する例です。
import random
i = 100
j = 20e7
# Generates a random number between i and ja = random.randrange(i, j)
try:
b = random.randrange(j, i)
except ValueError:
print('ValueError on randrange() since start > stop')
c = random.randint(100, 200)
try:
d = random.randint(200, 100)
except ValueError:
print('ValueError on randint() since 200 > 100')
print('i =', i, ' and j =', j)
print('randrange() generated number:', a)
print('randint() generated number:', c)
|
可能な出力
ValueError on randrange() since start > stopValueError on randint() since 200 > 100
i = 100 and j = 200000000.0
randrange() generated number: 143577043
randint() generated number: 170
|
ランダムな浮動小数点数の生成
整数の生成と同様に、ランダムな浮動小数点数の列を生成する関数があります。
- random.random() -> [0.0 から 1.0) の間の次のランダムな浮動小数点数を返します。
- random.uniform(a, b) -> a <= N <= b かつ b <= N <= a if b < a のような乱数浮動小数点数
Nを返します。 - random.expovariate(lambda) -> 指数分布に対応する数値を返します。
- random.gauss(mu, sigma) -> ガウス分布に対応する数値を返します。
正規分布,ガンマ分布など,他の分布についても同様の関数があります。
これらの浮動小数点数を生成する例を以下に示す。
import random
print('Random number from 0 to 1 :', random.random())
print('Uniform Distribution between [1,5] :', random.uniform(1, 5))
print('Gaussian Distribution with mean = 0 and standard deviation = 1 :', random.gauss(0, 1))
print('Exponential Distribution with lambda = 0.1 :', random.expovariate(0.1))
print('Normal Distribution with mean = 1 and standard deviation = 2:', random.normalvariate(1, 5))
|
可能な出力
Random number from 0 to 1 : 0.44663645835100585
Uniform Distribution between [1,5] : 3.65657099941547
Gaussian Distribution with mean = 0 and standard deviation = 1 : -2.271813609629832
Exponential Distribution with lambda = 0.1 : 12.64275539117617
Normal Distribution with mean = 1 and standard deviation = 2 : 4.259037195111757
|
random モジュールを使った乱数配列
整数や浮動小数点数のシーケンスと同様に、一般的なシーケンスはリストやタプルのようなアイテムのコレクションになります。
random` モジュールは、シーケンスにランダム性を持たせることができる便利な関数を提供します。
1. random.shuffle(x)
これはシーケンスをその場でシャッフルするために使用されます。
シーケンスは要素を含む任意のリスト/タプルにすることができる。
シャッフルを説明するためのコード例
import random
sequence = [random.randint(0, i) for i in range(10)]
print('Before shuffling', sequence)
random.shuffle(sequence)print('After shuffling', sequence)
|
可能な出力。
Before shuffling [0, 0, 2, 0, 4, 5, 5, 0, 1, 9]
After shuffling [5, 0, 9, 1, 5, 0, 4, 2, 0, 0]
|
2. random.choice(seq)
これは、リストやシーケンスからランダムに項目を選ぶような場合に、実際に広く使われる関数です。
import random
a = ['one', 'eleven', 'twelve', 'five', 'six', 'ten']
print(a)
for i in range(5):
print(random.choice(a))
|
可能な出力
['one', 'eleven', 'twelve', 'five', 'six', 'ten']
tenelevensixtwelvetwelve |
3. random.sample(population, k)
長さ k のシーケンスから無作為なサンプルを返す。
import random
a = ['one', 'eleven', 'twelve', 'five', 'six', 'ten']
print(a)
for i in range(3):
b = random.sample(a, 2)
print('random sample:', b)
|
可能な出力
['one', 'eleven', 'twelve', 'five', 'six', 'ten']
random sample: ['five', 'twelve']
random sample: ['ten', 'six']
random sample: ['eleven', 'one']
|
ランダムシード
疑似乱数生成は直前の数値に基づいて行われるため、プログラムを実行するたびに新しい出力が得られるように、通常はシステム時間を利用します。
そのため、seedsを利用します。
Pythonは random.seed() を提供しており、これを用いて初期値を得るためにシードを設定することができます。
このシード値が乱数生成器の出力を決定するので、シード値が同じであれば出力も同じになります。
import random
random.seed(1)
print('Generating a random sequence of 4 numbers...')
print([random.randint(1, 100) for i in range(5)])
# Reset the seed to 1 againrandom.seed(1)
# We now get the same sequenceprint([random.randint(1, 100) for i in range(5)])
|
可能な出力
Generating a random sequence of 4 numbers...
[18, 73, 98, 9, 33]
[18, 73, 98, 9, 33]
|
このことから、擬似乱数列を扱う際には、種を変えないと列が繰り返される可能性があるので、種に注意する必要があることがわかる。
まとめ
Pythonのrandomモジュールが提供する、整数、浮動小数点数、Listなどの配列を扱うための様々なメソッドについて学びました。
また、種が疑似乱数の列にどのような影響を与えるかについても学びました。
参考文献
- Python random モジュール ドキュメント
- 乱数に関する JournalDev の記事