LoginSignup
4
2

More than 5 years have passed since last update.

[CodeIQ]サイコロの確率分布を書いてみた(CodeIQ機械学習のための数学講座【確率分布編】より)

Last updated at Posted at 2017-01-09

はじめに

このエントリは、CodeIQの池澤あやかとプログラミングで学ぼう!機械学習のための数学講座【確率分布編】の後半部分の、サイコロの確率分布の記事中のコードが理解できなかったので、自分の理解できる範囲でコードを作った際の備忘です。

pythonは初心者のため、書き方が変な部分があるかもしれません。

環境

Python 2.7.10

サイコロの確率分布の公式の理解

公式

math-1.jpg
*画像は記事から引用

課題

Q. サイコロを5回投げて出る目の回数の確率分布を求めてください。確率分布は確率を列挙したものです。

サイコロの確率分布の公式は上記の式です。
公式の解説、確率分布とはということは、記事に詳しく書いてあるので、ここではコードを作るために必要な情報を書いていきます。

N

試行回数なので、課題では「サイコロを5回投げる」ので、N=5

N!

5の階乗。mathライブラリのfactorialメソッドを使います

k1 k2 k3 k4 k5 k6

サイコロをN回投げたとき、各サイコロの目の出た回数の組み合わせ
たとえば、5回投げた場合、

5回すべて1がでた場合、k1=5 k2=0 k3=0 k4=0 k5=0 k6=0
5回中6以外が1回ずつ出た場合、k1=1 k2=1 k3=1 k4=1 k5=1 k6=0

となります。
確率分布ではこの組み合わせごとの確率を求めていきます(という理解)。

確率分布を求めていく

まずはサイコロを5回投げたときの出目の組み合わせを洗い出します。

k1=5 k2=0 k3=0 k4=0 k5=0 k6=0のとき
k1=4 k2=1 k3=0 k4=0 k5=0 k6=0のとき
k1=4 k2=0 k3=1 k4=0 k5=0 k6=0のとき、、、

を考えてコードを書くのは大変なので、いったんkXが0~5すべて入った場合のk1~k6の組み合わせを全部出します

たとえばこんな感じ

#k1-k2-k3-k4-k5-k6
0-0-0-0-0-5
0-0-0-0-1-4
0-0-0-0-2-3
...
5-5-5-5-5-3
5-5-5-5-5-4
5-5-5-5-5-5

全組み合わせは下記のコードの再帰関数(create_pattern(k, list))で作っていきます。
その後、組み合わせのうち、k1~k6の合計が5になる組み合わせのみし、公式に合わせて確率を計算します。

python
#!/usr/bin/env python
import math 

#再帰関数で全組み合わせを作る
#ハイフン区切りの組み合わせにする
def create_pattern(k, list):
  if k ==  1:
     for i in xrange(0, 6):
      list.append(str(i))
  else:
    new_list = []
    for pattern in list:
      for j in xrange(0, 6):
        new_list.append(pattern + '-' + str(j))

    list = new_list

  if k == 6:
    return list
  else:
    k = k + 1
    return create_pattern(k, list)


# サイコロを投げる回数
n = 5

all_pattern_str_list = create_pattern(1, [])

#ハイフン区切りの組み合わせを分解して、合計が5の組み合わせのみ、確率を計算していく
for all_pattern_str in all_pattern_str_list:
  tmp_list = all_pattern_str.split('-')

  pattern_sum = 0
  pattern_list = []
  for tmp_str in tmp_list:
    pattern_list.append(int(tmp_str))

  if sum(pattern_list) == 5:
    print pattern_list

    #公式の分母(k1!k2!k3!k4!k5!k6!)を計算
    denom = 1
    for p in pattern_list:
      denom = denom * math.factorial(p)

    #確率の計算
    print (math.factorial(n) / denom) * (1.0 / 6.0 ** n)

まとめ

記事中にもありますが、コードに落とすと、数学も理解しやすくなりました。

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2