このブログではデータサイエンスに関わる情報を発信しています。
今回はnumpyの使い方4回目という事で、乱数生成機能について解説します。
なにかと使う事も多い機能ですのでしっかりと把握しておきましょう。
前回のがまだという人は↓からどうぞ!
【python】Numpyの使い方講座③:行列のサイズとスライシング
numpyの乱数生成とは
numpyの乱数生成は、ランダムな数値の配列を作成するための非常に便利なツールです。これを使えば、様々なデータ分析や機械学習のシミュレーションに役立ちます。
乱数とは?
numpyの乱数生成を理解するためには、まず「乱数」という概念を知る必要があります
乱数とは、予測できないランダムな値のことです。
この乱数は、様々な場面で利用されています。例えば、カジノでのルーレットやブラックジャックの結果、宝くじの当選番号、セキュリティのためのパスワード生成など、多くの場面で利用されています。
numpyの乱数生成では、乱数の種類や分布を指定することができます。
これにより、さまざまな応用に対応できるようになります。それでは、次のセクションで実際にnumpyの乱数生成を詳しく見ていきましょう!
numpyの乱数生成の基本的な使い方
乱数生成をする際には、基本的には以下の3つの関数を使います。
- np.random.rand()関数
- np.random.randn()関数
- np.random.randint()関数
それぞれの使い方を見ていきましょう。
np.random.rand()
np.random.rand()関数は0以上1未満の範囲の一様分布に従った乱数を生成します。
引数は以下の様になっています。
- np.random.rand(生成する乱数の数)
- np.random.rand(生成する乱数の行数, 列数)
- np.random.rand(生成する乱数の層、行数、列数)
このように、引数毎に各次元の数を指定する事ができます。
引数に何も入れないと1つの乱数が生成されます。
引数を1つ与えると、その値が生成する乱数の数になります。
引数を2つ与えると、第1引数が生成する乱数の行数、第2引数が列数になります。
3つ以上の引数を与えると、それぞれの引数が生成する乱数の寸法になります。
まずは1つの乱数を生成してみましょう。
1 2 3 |
# 1つの乱数を生成する x = np.random.rand() print(x) |
->0.49215885468985643
今回は0.49,,,でしたが、もちろん毎回実行するごとに結果は変わります。
続いて個数を指定しましょう。今回は2つ指定します。
1 2 3 |
# 2つの乱数を生成する y = np.random.rand(2) print(y) |
->[0.37793942 0.82004684]
次は行と列の数を指定します。
3行2列を指定してみましょう。
1 2 3 |
# 行と列を指定して生成 z = np.random.rand(3, 2) print(z) |
->[[0.88973393 0.88843751]
[0.36660918 0.28807105]
[0.5944659 0.10985607]]
最後に層・行・列を指定します。
2層1行3列のパターンを見てみましょう。
1 2 3 |
# 層・行・列を指定して生成 l = np.random.rand(2, 1, 3) print(l) |
[[[0.02659479 0.53374997 0.20817961]]
[[0.9249116 0.77701214 0.58581093]]]
np.random.rand()関数は、機械学習やデータ分析などでよく使用されます。
たとえば、ニューラルネットワークの初期化や、シミュレーションのための乱数生成などです。
注意点として、np.random.rand()関数で生成された乱数は、疑似乱数であるため、完全にランダムではありません。
ただし、大量のデータを生成すれば、ランダムに近い分布を得ることができます。
また、np.random.rand()関数は、引数に乱数の範囲を指定することができないため、必要に応じて他の乱数生成関数を使用する必要があります。
np.random.randn()関数
これは先ほどのにnがプラスされた関数です。typoではありませんww
この関数は、平均0、分散1の正規分布(標準正規分布)に従う乱数を生成するために使用されます。
そのため、後から平均値と標準偏差を与える事でより実際のデータに近い乱数を生成する事ができます。
引数の指定方法はrand()関数と一緒で、多次元配列を生成する事もできます。
1 2 3 |
# 2層1行3列の標準正規分布に従う乱数を生成 n = np.random.randn(2, 1, 3) print(n) |
[[[-0.24665565 -0.46894058 0.87354296]]
[[-0.62688331 1.49903523 0.39907359]]]
簡単ですね!
では、続いてrandn()関数を使って身長のサンプルのデータセットを作ってみましょう。
条件は↓です。
- 平均身長170cm
- 標準偏差5cm
- 乱数を10個生成
この条件でコードを書いてみます。
1 2 3 |
# 平均170cm、標準偏差5cmの正規分布に従う10個のデータを生成 heights = 5 * np.random.randn(10) + 170 print(heights) |
->[177.27448278 163.01626522 172.45008233 165.97098444 163.07682221 175.17243881 173.73659405 160.09225991 171.08831395 172.57587923]
この様に、無事10人分の身長データがランダムに生成されました。
np.random.randint()関数
np.random.randint()関数は、指定された範囲内の整数からランダムに値を生成するnumpyの関数です。
この関数を使うことで、ランダムな整数の配列を簡単に生成することができます。
引数に↓になっています。
np.random.randint(low, high=None, size=None, dtype=int)
それぞれの引数の詳細です。
- low: 生成される値の最小値
- high: 生成される値の最大値(指定しない場合はlow以上high未満の値を生成)
- size: 生成される配列の形状(タプルで指定)
- dtype: 生成される配列のデータ型
例えば、0から9までの範囲でランダムな整数を生成する場合は、下記のようになります。
1 2 3 4 5 6 7 8 9 10 11 |
# 0から9までのランダムな整数を1つ生成 x = np.random.randint(10) print(x) # 出力例: 5 # 0から9までのランダムな整数を3つ生成して配列に格納 arr = np.random.randint(10, size=3) print(arr) # 出力例: [2 6 9] # 1から10までのランダムな整数を3×3の配列に格納 arr = np.random.randint(1, 11, size=(3, 3)) print(arr) # 出力例: [[2 5 9] [9 7 2] [5 1 5]] |
->9
->[3 5 2]
->[[ 5 5 8]
[ 1 10 4]
[ 8 7 5]]
また、np.random.randint()関数を用いることで、乱数によるランダムなインデックス選択を実現することもできます。
例えば、リストからランダムに要素を選択する場合は、下記のようになります。
フルーツのリストを作ってそこからランダムに3つ取得してます。
書き方としては、リスト内包表記でfor文を回しています。
1 2 3 4 5 6 |
my_list = ['apple', 'banana', 'cherry', 'durian', 'elderberry'] # リストからランダムに3つの要素を選択 random_indexes = np.random.randint(len(my_list), size=3) random_items = [my_list[i] for i in random_indexes] print(random_items) # 出力例: ['banana', 'elderberry', 'apple'] |
->[‘durian’, ‘durian’, ‘apple’]
乱数生成におけるシードの設定

シードとは、乱数生成アルゴリズムにおいて、初期値として設定される整数値のことです。
乱数生成アルゴリズムは、ある決まったシードから、一定の法則に基づいて乱数を生成します。
そのため、同じシードを使えば同じ乱数が得られます。
つまり、チーム内で同じ結果を再現したい時など、シードを設定する事で全く同じ乱数を取得してデータの検証を行う事ができます。
シードの設定方法
NumPyにおいて、シードを設定するには、numpy.random.seed()
関数を使います。
この関数に整数を渡すことで、その整数をシードとして乱数を生成するアルゴリズムの初期値を設定します。
例えば、以下のように記述します。
1 2 3 4 5 6 |
# シードを設定 np.random.seed(1234) # 乱数を生成 arr = np.random.rand(5) print(arr) |
->[0.19151945 0.62210877 0.43772774 0.78535858 0.77997581]
この場合、シードには整数の1234
を設定しています。そのため、何度実行しても同じ値が返ってきます。
もし、異なる乱数を生成したい場合は、異なるシードを設定する必要があります。
また、シードの設定は乱数生成アルゴリズム全般に影響を与えるため、注意が必要です。
特に、シードを設定しない場合は、実行ごとに異なる乱数が生成されるため、再現性が担保されなくなります。
np.random.choice()関数とは?
np.random.choice()関数は、特定の範囲からランダムに要素を抽出するために使用される関数です。
この関数を使用すると、与えられた配列(リストやndarrayなど)から、指定した数の要素をランダムに抽出することができます。
np.random.choice()関数の構文は以下の通りです。
np.random.choice(a, size=None, replace=True, p=None)
引数の詳細はこの様になっています。
- a: 抽出元の配列
- size: 抽出する要素数
- replace: 重複を許すかどうかのフラグ(True:許す、False:許さない)
- p: 配列の各要素が選ばれる確率
具体的には、以下のような使い方ができます。
1 2 3 4 5 6 7 |
# 0から9までの数字をランダムに2つ選ぶ a = np.random.choice(10, 2) print(a) # [3 1] # リストからランダムに3つ選ぶ b = np.random.choice(['dog', 'cat', 'rabbit', 'panda', 'lion'], 3, replace=False) print(b) # ['lion' 'panda' 'rabbit'] |
->[3 1]
->[‘lion’ ‘panda’ ‘rabbit’]
この例では、np.random.choice()
関数を用いて、整数のリストと文字列のリストから、それぞれ指定した数の要素をランダムに抽出しています。
また、replace
引数をFalse
に設定することで、抽出した要素に重複がないようにできます。
np.random.permutation()関数とは?
np.random.permutation()関数は、引数として与えられた配列の要素をランダムに並び替えた新しい配列を返します。
また、引数として与えられた配列の要素をランダムに並び替えた新しい配列を返すため、元の配列は変更されません。
np.random.permutation()の使い方
np.random.permutation()関数は、ndarrayを引数として受け取ります。以下は、np.random.permutation()関数の基本的な使用方法です。
1 2 3 |
arr = np.array([1, 2, 3, 4, 5]) shuffle_arr = np.random.permutation(arr) print(shuffle_arr) |
->[5 3 2 1 4]
上記のコードでは、arrの要素をランダムに並び替えた新しい配列shuffle_arrを生成しています。
引数として与えたndarrayの形状を持ったランダムなインデックスを生成する場合は、np.random.permutation()関数の代わりに、np.random.permutation()関数の引数として、ndarrayの要素数を指定することもできます。
1 2 3 |
arr_len = 5 shuffle_arr_idx = np.random.permutation(arr_len) print(shuffle_arr_idx) |
->[0 3 2 1 4]
このコードでは、配列をシャッフルするのではなく、指定された長さのランダムなインデックスが生成されます。
まとめ
いかがでしたでしょうか?
乱数生成の方法を一気に紹介してしまったので、それぞれの違いがイマイチ分かってない人も多いと思います。
まずは慣れる事が一番だと思いますので、実際に手を動かしながら乱数を生成していきましょう。
Work illustrations by Storyset