統計学を学んでいて、
プログラミングをしていると、
必ず出会うのが「乱数」です。
乱数は、統計学だけでなく、機械学習や人工知能などでも避けることができない技術です。
その他、統計学を基礎とするあらゆる応用に乱数が関係してきます。
乱数のシンプルな例は、サイコロです。
プログラムの中でサイコロを振りたい場合には、乱数の知識が必要です。
サイコロを振るというのは、シンプルですが、
確率的な現象をモデル化するときの基礎でとても重要です。
例えば、現実世界をモデル化するときには、誤差の影響を考慮する必要があることがあります。
誤差は毎回決まった値が出るわけでなく、不規則な値として出てくることが多いです。
誤差を考慮してモデルを作成する場合など、
- 乱数をうまく扱う
といった技術は必須になります。
というわけで、本記事では、
- Python を使って乱数を生成させる方法
をまとめたいと思います。
特に初学者向けとして、「一様乱数」という乱数についてまとめたいと思います。
【Python 乱数】乱数とは?一様乱数とは?Python で「一様乱数」を生成させたいあなたはこちらをどうぞ【乱数とは 一様乱数とは】
乱数とは?
「乱数」というのは、
- 数字が不規則に現れる数の配列
のことです。
数字は不規則に生成されるので、次に出る数は予測できないことになります。
一様乱数とは?
「一様乱数」の「一様」というのは、
- 出てくる数値は全部同じ確率
という意味です。
なので、一様乱数はで
- 数値は不規則に出てくる
- それぞれの数値が出てくる確率は同じ
ものになります。
一様乱数の具体例は?
具体的には、1−6の範囲の整数を、一様乱数として発生させるとすると、
1、2、3、4、5、6
の数字が不規則に、同じ確率で出てきます。
実際に発生させてみると、
5、2、4、3、6、1、・・・
のような感じです。
これは「サイコロ」のことですよね。
サイコロは一様乱数の発生装置なわけです。
Python で一様乱数を生成してみる
ここではPyhotn のライブラリの1つの NumPy を使って、一様乱数を生成してみます。
(1行目) numpyをインポートして、npと略して使うようにしています。
(3行目) numpy の中の、random というモジュールを使っています。
この使い方では、1−5までの整数の一様乱数を生成します。
つまり、randint(a, b)として使うと、
(a, b-1)の範囲の整数を乱数として生成することができます。
b の値は生成されないことに注意してください。
np.random.randomint( )1回使うと1個の乱数が生成されます。
複数の一様乱数(乱数列)を生成させてみます。
for を使って、繰り返して一様整数乱数を1−6の範囲で生成させています(カッコの中は1−7になっています)
この乱数生成プログラムはサイコロと同じです。
プログラムを実行すると以下のようになります。
10個生成させてみると、
1、3、4、5、6
が出ています。
- あれ、今回2は出ていないよ?
- 一様(等確率で生成してる)なら2も出るんじゃないの?
と思われるかもしれません。
結論から言うと、
乱数列は、小さい乱数列では、数値に偏りが見られたりします。
- ランダムに生成してるのに偏りが見られる
これは初学者の方からすると、
6回生成させたら1−6がそれぞれ1個ずつ出る、
ような初学者の方のイメージと違うことがあります。
これは最初は不思議に思われるかもしれませんが、
乱数列の数を増やして大量に生成すると、
ちゃんと等確率に出現していることがわかります。
以下で、乱数列を大量に生成して、その数をヒストグラム(度数分布)を作成してみます。
その前に、シードという考え方をご紹介します。
乱数のシード(seed)とは?
乱数のシードは、種の意味で、乱数を作る時に必要な初期値のことになります。
この初期値を変えると、得られる乱数列も変わります。
逆に言うと、
シード(初期値)を同じにすると同じ乱数列が得られます。
同じ乱数を生成させることで、複数の数値実験を比較する時に、乱数列の違いの影響をなくすことができます。
以下で確かめてみますね。
前半と後半で同じことをしています。
どちらも
np.random.seed(10)
を使っています。
この値 10 を変えなけれ同じ乱数列が生成されます。
以下の感じです↓
確かに同じ乱数列が生成されています。
これで固定された乱数列を生成できることがわかりました。
あなたが自分でプログラムすると
同じ結果を再現できますので、ぜひ手を動かしてみてください。
ちなみに、同じことをforを使わずに書くこともできます。
これを実行すると、以下のように出力されます。
確かに、上と同じ乱数列が生成されているのが確認できました。
np.random.randint(範囲の最初、範囲の最後の次の整数、生成させる乱数の数)
という使い方ができます。
ちなみに、生成させる数字が増えるとforを使うよりこちらの方が速いと思います。
では、乱数が一様(等確率)に生成されているかを確かめみます。
乱数列の分布をヒストグラム(度数分布)で表示させてみる
matplotlib は、ヒストグラムを表示するためライブラリです。
matplotlib.pyplot を plt と略して使っています。
ヒストグラムは、plt の hist関数で作成することができます。
今回は100個の乱数列を生成させています。
今回の乱数列では、1が多く、3と4が少ない結果が見て取れます。
1万個の乱数列を生成させるとこんな感じです↓
100万個の乱数列を生成させると↓
大量の乱数列を見てみると、ヒストグラムはフラットに見えます。
完全にではないですが、一様に生成されていると言えるかと思います。
擬似乱数とは?
実はコンピュータで生成する乱数列は、厳密な意味での乱数ではありません。
非常に多くの乱数を生成させると、周期が見えてきます。
ただし、100万の数字が必要な時、周期が100億の数字の生成の後に現れるなら、
100万の数字を生成させる時には周期は無い(不規則)
ということができますよね。
なので、乱数は擬似乱数と読んだりします。
- 実用上は問題ないけど、厳密には乱数ではない
と言った感じです。
あなたが調査したい内容が100万の数値が必要で、
乱数の周期がそれより短かったら、
乱数を使えていないことになりますので、
乱数生成の方法について把握しておくことが大事になります。
というわけで、本記事では、
- Python を使って一様乱数を生成させる方法
をまとめました。
乱数を学びたいあなたはこちらもございます↓