2017年5月6日土曜日

Python ヒストグラムを作成する(2)

6面ダイスの場合、「6」の出る確率は理論上 1/6 であるが、実際に振ってみると出てくる数字に偏りがある。
前回の ThrowDice 関数を用いて、10 回投げてみる。
>> print(ThrowDice(6, 10))

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

>> print(ThrowDice(6, 19))

[3 5 4 2 2 4 2 5 4 1]
1回目の確率は 0.2 であるが、2 回目の確率は 0 である。投げる回数が多くなれば、1/6 に近づくか?
1000回投げた場合、理論上の値 1/6 には近づくが、多くの場合 1/6 にはならない。
>> x = ThrowDice(6, 1000)
>> print(1/6)
>> print(x[x == 6].size / x.size)

0.16666666666666666
0.177

>> x = ThrowDice(6, 1000)
>> print(1/6)
>> print(x[x == 6].size / x.size)

0.16666666666666666
0.153
1万回ダイスを振って「6」が出た確率を計算し、これを1万回繰り返した場合の確率の分布をヒストグラムで可視化する。
def getRatioList(dice, value, cnt1, cnt2):
    l = []
    for _ in range(cnt1):
        result = ThrowDice(dice, cnt2)
        r = (result[result == value]).size / result.size
        l.append(r)

    return l


l = getRatioList(6, 6, 10000, 10000)
plt.hist(l, align="mid", rwidth=0.5)
plt.grid(True)
plt.show()
1/6 = 0.166… 近辺が最も多くなっているが、0.175 や 0.160 にも値が出ている。より分かりやすくするため、y軸を割合に変更する。
なお、ダイスを振り直ししているため、表示されるグラフの形状が上のグラフと異なっている。
l = getRatioList(6, 6, 10000, 10000)
weight = np.ones_like(l)/len(l)
plt.hist(l, align="mid", rwidth=0.5, weights=weight)
plt.grid(True)
plt.show()
matplotlib.pyplot.hist 関数の weights パラメータは、グラフ上の値を weights パラメータで与えられたリストの各項で乗算する。上記例の場合は、ヒストグラムの各 bin の値に対して全体要素数の逆数を乗算し、当該binの全体に占める割合を算出している。
およそ 30% の割合で 6 回に 1 回の確率で「6」が出るが、10 % 程度の確率で 1/0.16 = 6.25 回振らないと「6」が出ない。
より分かりやすいように comulative パラメータを True に変更し、累積ヒストグラムを作成する。
…
plt.hist(l, align="left", bins=10, rwidth=0.5, weights=weight,
         cumulative=True)
…

例えば、携帯ゲームでレアカードの出現率が 1% (すなわち理論上 100 回に 1 回出現する)とする。100 回チャレンジを1万回繰り返した結果が以下の通りである。
100 回やっても全く該当カードが入手できない確率が 35% 以上もあることがわかる。

0 件のコメント:

コメントを投稿