Python、機械学習

【Python】これだけ知っていれば十分な、乱数生成方法(ランダムな数)(random、rand、randint、randn)

Pythonで、適当なデータを作るために乱数を生成することがあります。

初心者向けの本や解説サイトでもよく出てくると思います。

しかしながら、何だか関数の名前がどれも似ていてごっちゃになってしまいます。

ここでは、よく見かける乱数生成方法を整理します。これだけ知っていれば十分かと思います。

乱数を生成する方法は大きく2通りある

乱数を生成する方法は大きく2通りあります。一つは、Numpyを使ったもの。もう一つは、randomというライブラリを使ったものです。

おそらく、Numpyの方だけ知っておけば十分だと思いますが、randomライブラリを使ったものも本やサイトではよく出てきますので、それぞれ説明します。

まずは、乱数生成方法の手法が2通りあることを頭に入れておきます。

1)Numpyを使う方法

こちらは、とりあえずNumpyをimportしておけば使えるものです。

import numpy as np

① 0から1までの数を□□個生成する:np.random.random()

0から1までの数をランダムに□□個生成するのが、np.random.random()です。

np.random.random(3)

array([0.37454012, 0.95071431, 0.73199394])

□□を省略すると、返ってくる数は1個になります。

np.random.random()

0.3745401188473625

ちなみに、返ってくる乱数は毎回バラバラです。

試しに、10,000個の乱数を発生させてグラフにしてみました。

from matplotlib import pyplot as plt
plt.hist(np.random.random(10000), bins=100)
plt.show()


0から1までの間で、いい感じに均等に数値が取れているのが分かります。

均等に数値を取るので、「一様乱数」と呼ばれます。

② np.random.rand()はnp.rondom.random()と全く同じ

なお、np.random.rand()というのもありますが、これはnp.random.random()と全く同じです。どちらを使ってもOKです。

③ 〇〇から△△までの整数を□□個生成する:np.random.randint()

〇〇から△△までの整数を□□個生成するのが、np.random.randint()です。

randintのお尻にint(整数)って付いていますので、覚えやすいかと思います。

np.random.randint(0, 100, 3)

array([51, 92, 14])

□□を省略すると、返ってくる数は1個になります。

np.random.randint(0, 100)

51

0から100までの整数を10,000個発生させてグラフにしてみました。

plt.hist(np.random.randint(0, 100, 10000), bins=100)
plt.show()


こちらも、いい感じに均等に数値が取れているのが分かります。

np.random.random()と同様、均等に数値を取るので、一様乱数です。

④ 平均0、標準偏差1の正規分布にしたがう数を□□個生成する:np.random.randn()

平均0、標準偏差1の正規分布にしたがう数を□□個生成するのがnp.random.randn()です。

np.random.randn(3)

array([0.49671415, -0.1382643, 0.64768854])

□□を省略すると、返ってくる数は1個になります。

np.random.randn()

0.4967141530112327

乱数を10,000個発生させてグラフにしてみましょう。

plt.hist(np.random.randn(10000), bins=100)
plt.show()


中心が0のきれいな正規分布になっていることが分かります。

余談ですが、平均と標準偏差を指定したいならnp.random.normal()を使います。括弧内に平均と標準偏差をつまり、np.random.randn()は、np.random.normal(0, 1)と同義です。

返ってくる乱数が毎回バラバラにならないようにしたい(再現性の確保)

返ってくる乱数が毎回同じにするには、次のようなコードを書きます。

np.random.seed(42)

コンピュータで生成する乱数というのは完全にランダムなわけではなく、一定の計算に沿って生成されるものです。計算によって生成される乱数を「疑似乱数」と呼びます。

疑似乱数は、乱数を発生させるための種になるものを使って計算されます。これをランダムシード(乱数種)と言います。

ランダムシードには追番がついています。下は0から、上はおそらく限りなく上まであります。上限がいくつかは分かりませんが、10,000は軽く超えます。

とりえあずここではランダムシード=42に指定しました。42じゃなくても何でもOKです。

ということで、乱数を発生させる前にnp.random.seed()と書いて、括弧内にランダムシードの追番を入力してやれば再現性を確保できます。

何度乱数を発生させても、毎回同じ乱数が返ってきます。

注意点

注意点は、Jupyter notebookのような対話型のソフトでPythonを書くときです。

np.random.seed()と、乱数発生のコードは必ずセットで書いて下さい。つまり、1行ずつ書いて実行するのではく、2行まとめて書いて、同時に実行するようにします。

np.random.seed(42)
np.random.randn()

0.4967141530112327

もし1行ずつ書いて実行すると、ランダムシードが固定されず、再現性が現れませんので注意して下さい。

2)randomライブラリを使う方法

まずはrandomライブラリをインポートします。

import random

 

① np.random.random()に相当するのが、random.random()です。カッコ内はタッチできません。乱数は1個だけ返ってきます。

random.random()

0.6394267984578837

② なお、random.rand()というものは存在しません。

③ np.random.randint()に相当するのが、random.randint()です。カッコ内は範囲のみの指定です。乱数は1個だけ返ってきます。

random.randint(0, 100)

81

④ np.random.randn()に相当するものはありません。ただし、np.random.normal()に相当するrandom.normalvariate()というものがありますので、次のように書くことができます。乱数は1個だけ返ってきます。

random.normalvariate(0, 1)

-1.0392540270777377

ランダムシードを固定する場合はこのように書きます。注意点はNumpyの時と同じです。

random.seed(42)

まとめ

・乱数生成方法には、Numpyを使ったものと、非Numpyのもの(randomライブラリ)がある。
・Numpyを使ったものには、np.random.random()、np.random.rand()、np.random.randint()、np.random.randn()をよく見かける。
・np.random.random()、np.random.rand()は全く同じ。
・np.random.seed()でランダムシードを固定できる。
・これらに対応する非Numpyのrandomライブラリがあるが、あまり使わないかと。