"BOKU"のITな日常

興味のむくまま気の向くままに調べたり・まとめたりしてます。

離散的な値の分布の代表格「二項分布」と「ポアソン分布」をPythonで確認してみた

f:id:arakan_no_boku:20190722102259p:plain

 機械学習や統計の話題に頻出する「分布」の中で、モヤっとしがちだった「二項分布」と「ポアソン分布」について、文系的アプローチで整理を試みます。

目次

数学・統計の本には「離散的な値」とか「連続的な値」なんて表現が頻発します。

離散的な値とは

サイコロの目とかコインの表裏みたいに、とりうる状態(値)が有限個である(=数えることができる)ものをいうみたいです。

確かに、サイコロの目は6通りしかないですし、何かの製品の故障発生数とかも何件とかかぞえられるな・・と考えると、ちょっと感覚的に理解しやすいです。 

連続的な値とは

時間とか視聴率とか為替レートとかみたいに、とりうる値を数えることができないものをいうみたいです。

確かに、為替レートで105円と106円の間の取りえる値の数・・と言われても、105.000000000001みたいな値がぎっしり詰まっていると言えるので、数えられません。

連続的値に対する分布と離散的値に対する分布

分布にも連続的な値に対する分布と、離散的な値に対する分布が存在します。

例えば。

連続的(取りえる値の数を数えられない)な値に対する分布の主なもの。

離散的(とりえる値の数を数えられる)な値に対する分布の主なもの。

とかです。

今回は、上記のうち、よりわかりにくにな・・と思っていた「離散的な値に対する分布」である2つを、ざっくり整理してみようかなと思っています。

離散的な分布1:二項分布

 例えば「株価があがるかさがるか」「コインの表がでるか裏がでるか」など2種類の結果しかない片方を「成功」と呼ぶ時の「成功する回数」の分布です。

数式はやめて、イメージをPythonで確かめてみます。

例として、一番わかりやすいのがコイントスです。

表がでることを成功と呼ぶことにします。

コインの場合、どちらがでる確率も「0.5」です。

このコイントスを50回して、表が何回でるかを1回だけ試してみる・・というと、こんな感じになります。

import numpy.random as nr

r = nr.binomial(50, 0.5, 1)

これを実行すると、22とか25とか24とか、実行都度色々表示されます。

1回だけだとばらついて当然です。

なのですが、理論的に言えば、この試行を何回も繰り返せば、確率0.5、つまり25回に近づいていくということになってます。

それを確かめるのに、300回くらい繰り返してみます。

さすがに回数の羅列をみるだけだとつらいので、バラつきがわかるようにグラフに表示もしてみます。

py_stat_binomial.py

import numpy.random as nr
import numpy as np
from matplotlib import pyplot as plt

labels = [n for n in range(300)]
r2 = nr.binomial(50, 0.5, 300)
av = np.average(r2)
print(av)
plt.scatter(x=labels, y=r2)
plt.show()

結果をグラフでみると、かなりばらついてます。

f:id:arakan_no_boku:20190722154610p:plain

でも、平均をみると

av = np.average(r2)

この回では「25.08」でした。

なるほど・・、確かに25回(確率0.5)に収束しつつありますね。

離散的な分布2:ポアソン分布

ポアソン分布は事象が発生する確率が非常に小さい時に適用されます。

例えば。

  • 天災による被害がおきる
  • 製品に故障が派生する
  • 出版本に誤植がある

など、本来はおこらないはずだが、わずかな確率で発生すると思われることに対して適用して、例えば「1日あたりの平均故障件数がわかっている時に、故障件数が3件以下である確率をもとめる」みたいな計算をする時に使う感じです。

numpy.random.poissonを使うと、指定した確率の事象を生成してくれます。

例えば。

import numpy.random as nr

d = nr.poisson(0.05, 100)
print(d) 

これは、発生確率0.05で100回試行する場合なのですが、生成されるリストはこんな感じになります。

[0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0]

 0が発生しない。

1が発生する。

まあ、そっくりそのままですね。

二項分布みたいに回数を返さないので、回数が必要ならカウントする必要がありますが、毎回結構なバラつきがでます。

せっかくなので、視覚化して、二項分布の結果と比較してみます。

といっても、同じように300回繰り返して試行したときの結果のバラつき具合を比べるだけですが。

事象は、1時間(3600秒)に平均10回発生するとします。

それを1試行3600(=1時間を仮定)で事象を生成し、それを合計したものを、300回繰り返して試行してみます。

import numpy.random as nr
import numpy as np
from matplotlib import pyplot as plt

r = nr.poisson(10/3600, [300, 3600])
r2 = []
for x in r:
    r2.append(np.sum(x))

labels = [n for n in range(300)]
av = np.average(r2)
print(av)
plt.scatter(x=labels, y=r2)
plt.show()

これを実行すると、こんな感じです。

f:id:arakan_no_boku:20190722205042p:plain

かなり大きな幅でばらついてます。

2回・3回レベルから20回くらいまでですからね。

二項分布の表と比べると、そのブレ幅の大きさがわかります。

でも、平均は。

10.256666666666666

なんと、ちゃんと10に近似していきます。

二項分布とポアソン分布は似てるなあ

上記のようなアプローチをやりながら、ふと気づいたことがあります。

それは。

二項分布とポアソン分布って似てるよな?ということです。

それで調べてみたら、実際そうみたいで、同じ問題にポアソン分布を用いた場合と二項分布を用いた場合で大差ない場合があるそうです。

知っている人には「当たり前」なんでしょうけど、今回、それに気づいて、自分はちょっと嬉しかったです(笑)。

今回はこんなところで。

ではでは。