LoginSignup
2
2

More than 3 years have passed since last update.

Pythonでポアソン分布

Posted at

前回の二項分布に引き続き今回はポアソン分布オブジェクトを作成したいと思います。素人なので間違いがあったら教えていただけると嬉しいです。

ポアソン分布って何

導出方法から見ると、ポアソン分布は二項分布の「全試行回数」が無限大になったバージョンだと考えていいと思います。

ポアソン分布の確率質量関数の導出方法

  • 二項分布の確率質量関数を用意する
  • 全試行回数n→∞、確率p→0 の場合の極限を求める

式変形はこちらの記事がわかりやすいです。
https://note.com/konpyu/n/ncede5754aba8

ポアソン分布の確率質量関数

上記の方法で導出されたポアソン分布の確率質量関数は以下のようになります。

単位区間(時間 or 空間)内における平均発生回数がλ回である事象が単位区間内にk回発生する確率(eはネイピア数):

P(k)=e^{-\lambda}\dfrac{\lambda^k}{k!}

なんで無限大にするのか

「地震の発生回数」のように人為的な試行が行われていないもの(つまり「全試行回数」が無いもの)を二項分布として扱うために「単位時間内に無限に試行が行われた」と仮定してるんじゃないかと考えると個人的にはしっくりきました。

こちらでも同じような説明がありました
https://bellcurve.jp/statistics/course/6984.html

どんなときに便利か

ポアソン分布で近似できる現象の例としては「一年間の地震の発生回数」、「ウェブサイトへの一時間あたりのアクセス数」などがあります。分母が無限(と仮定できる)もの全般に使える...と言いたいところですが、実際にあてはまるのは以下のような条件を満たす場合が多いようです。

(希少性):時間幅 ⊿t の間に着目している事象がちょうど1回起こる確率が {\displaystyle \lambda \Delta t+o(\Delta t)}{\displaystyle \lambda \Delta t+o(\Delta t)}、2回以上起こる確率が {\displaystyle o(\Delta t)}o(\Delta t)
(定常性):事象の起きる確率は、どの時間帯で同じ
(独立性):事象の起きる確率は、それ以前に起こった事象の回数や起こり方には無関係
ここで、o(⊿t) は ⊿t に対して高位の無限小を表しており、⊿t のスケールに注目したときに無視できる微小量であることを表す。

(Wikipediaより抜粋)

Pythonでポアソン分布してみた

確率質量関数を求める関数とグラフを描画する関数を持つクラスを作ってみます。ポイントはコンストラクタの引数が事象の平均発生回数λ(known_average)一個だけということです。
ちなみに今回は使いませんでしたがnumpyのnumpy.random.poisson()という関数でもポワソン分布の確率質量を求めることができます。

import math
import numpy as np
import matplotlib.pyplot as plt

class PoissonDistribution:
  """
    二項分布

    Attributes
    ----------
    known_average : int
      単位区間内における事象Aの平均発生回数.
    """

  def __init__(self, known_average):
    self.known_average = known_average

  def get_probability_mass(self, parameter_of_interest):
    """
     事象Aがk回起きる確率密度を求める.

     Parameters
    ----------
    parameter_of_interest : int
        確率質量を求めたい回数k(確率変数).

    Returns
    -------
    probability_mass : float
        kの確率質量.
    """

    probability_mass = (math.e ** (-self.known_average) * self.known_average ** parameter_of_interest) / math.factorial(parameter_of_interest)
    return probability_mass

  def draw_graph(self, min, max):
    """
     グラフを描画してpng形式で保存する.

     Parameters
    ----------
    min : int
        グラフの左端(回数).
    max : int
        グラフの右端(回数).
    """
    x = np.arange(min, max + 1, 1)
    y = []
    for k in range(min, max + 1):
      y.append(self.get_probability_mass(k))
    plt.plot(x, y)
    plt.savefig('graph.png')

実行


# 単位区間内における発生回数が5回の事象Aのポアソン分布オブジェクトを作成する.
poisson_distribution = PoissonDistribution(5)

# 事象Aが単位区間内において3回起きる場合の確率質量を計算する.
print(poisson_distribution.get_probability_mass(3))

# このポアソン分布を左端が0回、右端が20回(k=0,1,2 ... 20)のグラフに描画する.
poisson_distribution.draw_graph(0, 20)

結果

0.14037389581428059 #単位区間内における発生回数が5回の事象Aが3回起きる確率質量

スクリーンショット 2020-04-08 22.59.12.png

2
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
2
2