【NumPy入門 np.random.choice】歪なサイコロを再現する関数とは?

こんにちは、インストラクターのフクロウです!

この記事では、配列の要素をランダムに取り出す関数であるnp.random.choiceについて紹介します。

np.randomモジュールは、確率的な機能が多数用意されています。

その中の一つがこのchice関数です。

配列の要素はどんな型でも良いのですが、例えば[1,2,3,4,5,6]のような配列であればnp.random.randintのように扱うこともできます。

この記事で解説するので、是非これ読んでみてくださいね。

目次

np.random.choiceの使い方

サイコロを作る関数choice

choiceは配列やリストから、ランダムに要素を取り出す関数です。

数字が入った配列を使えば、randintのような動作ができます。

import numpy as np
import matplotlib.pyplot as plt
from collections import Counter

dice = list(range(1, 7))
print(np.random.choice(dice))

# 出力結果
2

出力配列の形状を指定する

この関数では、第二引数sizeを指定することで、任意のサイズの配列を作ることができます。

choiceは取り出す値が重複することを許すので、sizeの値は元の配列の要素数を超えてもOKです。

for i in range(10):
    samples = np.random.choice(dice, i)
    print(samples)

[出力結果]

[]
[2]
[2 6]
[6 3 2]
[4 1 4 3]
[3 1 1 5 2]
[5 3 5 6 3 3]
[3 4 3 2 4 4 6]
[5 5 2 5 6 2 3 5]
[5 4 5 1 3 2 5 5 6]

また、実はこのsizeパラメータ、配列の形状を指定することで、出力を多次元配列を作ることもできます。

np.random.choice(dice, (2,3))

# 出力結果
array([[4, 3, 5],
       [4, 6, 1]])

応用的な使い方

歪なサイコロを作成する

これまでは、すべての要素が出る確率が同一でした。

ですがpパラメータを使うことで、各要素の出る確率が異なる場合にも対応できます。

pパラメータは第一引数と同じ要素数の配列を受け取り、要素の合計値が1にならないといけません。

prob = [0.1, 0.2, 0.3, 
     0.1, 0.2, 0.1]

np.random.choice(a=dice, 
                 size=10, 
                 p=prob)

# 出力結果
array([5, 6, 1, 1, 5, 5, 3, 3, 5, 5])

十分に大きい試行回数で、本当に歪なサイコロになっているか確かめてみましょう。

samples = np.random.choice(dice, size=100000, p=p)
tmp = Counter(samples)

X = sorted(tmp.keys())
Y = [tmp[x] for x in X]

plt.bar(X,Y)

最初に指定した確率通りの出現回数分布になっていることがわかります。

np.random.randintとの違い

randintはランダムに数字を取り出す関数でしたが、choiceはどんな型をもった配列からでもランダムに要素を取り出すことができます。

また、randintは一様な確率でサンプリングしますが、choiceは確率を任意に操作することが可能です。

np.random.randintについては以下の記事で解説しました。

まとめ

この記事では、np.random.choiceの使い方を解説しました。

配列からランダムに要素を取り出す機能を持ったnp.random.choiceは、非常に使う機会が多いでしょう。

是非ともこの記事で使い方を覚えて使いこなしてくださいね!

この記事を書いた人

第一言語はPythonです。
皆さんRustやりましょう。

目次