"BOKU"のITな日常

還暦越えの文系システムエンジニアの”BOKU”は新しいことが大好きです。

離散的な値の分布の代表格「二項分布」と「ポアソン分布」を文系SEっぽく整理してみる

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

f:id:arakan_no_boku:20190722102259p:plain

 

今回の目的は「文系SE」っぽく、ざっくり理解すること

 

いろいろ、しっくり来る例が載っている資料をあさってみました。

それで自分なりの言葉で整理してみました。

数学的な正確さを求めるなら使うべき数学用語にもあえて目をつぶり、ざっくりとイメージをつかむことを優先していますので「不正確だ!」と指摘したくなる人もあるかと思いますが、ご容赦ください。

だって「文系SE」なんですから(笑)

まずは前提になる知識と分類からです。

 

避けて通れない連続か離散かの違い

 

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

実際「分布」というものを整理するときも「離散」「連続」からは逃げられません。

なので先にそこだけまとめます。

 

離散的というのは。

 

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

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

 

対して、連続的というのは。

 

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

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

 

連続的な分布と離散的な分布

 

分布にも色々な種類があるのですが、当たり前ですが、連続的な値に対する分布と、離散的な値に対する分布が存在します。

例えば。

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

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

 

とかです。

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

 

まず「二項分布」です

 

例えば「株価があがるかさがるか」「コインの表がでるか裏がでるか」など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)に収束しつつありますね。

 

次は「ポアソン分布」です

 

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

例えば。

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

など、本来はおこらないはずだが、わずかな確率で発生すると思われることに対して適用して、例えば「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に近似していきます。

 

おまけです

 

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

それは。

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

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

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

今回はこんなところで。

ではでは。