Pythonで実装する確率モデル(標本空間、確率変数、確率分布)|スクラッチ実装で理解する基礎統計 #3

f:id:lib-arts:20190419173312p:plain

上記のシリーズで機械学習アルゴリズムの実装を行っているのですが、他の内容もできればということで同様のイメージで基礎統計を実装していければと思います。
#1、#2では記述統計を取り扱いました。

#3では確率モデルの基本となる標本空間、確率変数、確率分布などについて取り扱います。
以下目次になります。
 
1. 用語の整理
2. 確率変数とは
3. 確率分布とその実装について
3-1. 離散確率分布とPythonでの実装
3-2. 連続確率分布とPythonでの実装
4. まとめ

 

1. 用語の整理
基礎統計における確率モデルを考える際には、色々と用語が出てくるのでまずは概念を抑える必要があります。
したがって、用語の整理を以下で行います。(網羅的には記述していないので、基礎知識が怪しい方は大学教養課程レベルの入門書は一冊手元にあると望ましいです)

・試行(trial)
-> 実験や観測などを行うこと。確率モデルに基づいて論理展開を行っていくにあたっては、試行を行った結果を確率的に解釈していきます。

・標本空間(sample space)、事象(event)
-> 試行の結果を要素とする集合を標本空間、標本空間の部分集合を事象と言います。

・条件付確率(conditional probability)
-> 事象Bが起きたことがわかっているという条件の元手の事象Aの起こる確率。数式で表記する際はP(A|B)=\frac{P(A∩B)}{P(B)}と記載する。|を用いて表記することは意識しておくと良い。

ベイズの定理(Bayes' theorem)
-> なんらかの事象を観測する前と後での不確実性(確率)の変化を計る定理。

・事前確率(prior probability)、事後確率(posterior probability)
-> 事象を観測する前の確率と、事象を観測した後の確率。

・確率変数(random variable)
-> 2節で後述する。

・確率分布(probability distribution)
-> 3節、4節で後述する。

 
2. 確率変数とは
確率変数は少々わかりづらい概念です。

確率変数は、確率論ならびに統計学において、起こりうることがらに割り当てている値(ふつうは実数や整数)を取る変数。各事象は確率をもち、その比重に応じて確率変数はランダムに値をとる。

確率変数 - Wikipedia

上記はWikipediaから引っ張りましたが、少々わかりづらいです。そのため、具体的に話をしましょう。要は試行の結果観測される観測結果に確率変数を割り当てていると理解しておけば良いです。(以下はあくまで具体例をベースに直感的な解説を行うので、理解できている方は飛ばしていただければと思います。)
例えばサイコロを1個振った際は、1~6の目が出ます。この際は1~6の目がそれぞれ確率変数となり、これをXとおくとこの1~6のそれぞれに関してP(X=1)~P(X=6)が確率の値として得ることができます。確率変数はそれぞれ値を入れた際にそれに対応する確率を得る際にPに与える変数と把握しておくと良いかと思います。
また、サイコロを2個振った際は(1,1)~(6,6)までの36通りが観測されます。この際はこの36通りが確率変数となります。要は観測されるものの場合の数を考えることに似ているかと思います。
深く考えるとだんだんわからなくなるので、とにかく観測結果に変数を割り当てると把握しておくと良いです。

 

3. 確率分布とその実装について
確率変数と並び、初学の際にとっつきづらいのが確率分布です。

確率分布は、確率変数に対して、各々の値をとる確率を表したものである。日本工業規格では、「確率変数がある値となる確率,又はある集合に属する確率を与える関数」と定義している。

確率分布 - Wikipedia

 

こちらもWikipediaから引っ張りましたが、最初のうちはわかりづらいかと思います。要は、観測結果がそれぞれ観測される確率を分布の形にしたものが確率分布です。ヒストグラムをサンプル数で割ったものだと捉えておけば良いです。また、確率変数が離散の場合を離散確率分布、確率変数が連続の場合を連続確率分布と呼びます。
解説すればするほどわからなくなるので、以下実際に離散確率分布と連続確率分布に分けて実装例を元に解説を行っていきます。


3-1. 離散確率分布とPythonでの実装
ここまで解説してきた確率変数Xが飛び飛びの値しか取らない場合、Xは離散的な(discrete)値と呼びます。例えば、コイン投げは{表,裏}の2値、サイコロは{1,2,3,4,5,6}であるので、これは離散的な確率変数であると言えます。
以下では具体的な実装を元に確率分布について理解していきます。(若干冗長かつfor文を用いているのはNumPyの使い方としては良くない実装ですが、中身を把握しやすいようにあえてこのような実装にしました)

import matplotlib.pyplot as plt
import numpy as np

np.random.seed(87655678)
A = np.random.rand(1000)
x = np.array([1,2,3,4,5,6])
pd = np.zeros([6])
for rnd in A:
    if rnd < 1/6:
        pd[0]+=0.001
    elif rnd < 2/6:
        pd[1]+=0.001
    elif rnd < 3/6:
        pd[2]+=0.001
    elif rnd < 4/6:
        pd[3]+=0.001
    elif rnd < 5/6:
        pd[4]+=0.001
    else:
        pd[5]+=0.001

plt.bar(x, pd)
plt.show()

上記はサイコロを1000回振った試行を乱数を用いて疑似的に作成したコードです。実行結果は以下のようになります。

f:id:lib-arts:20190419183310p:plain

これは一様分布と言われている分布に近しく、全ての確率変数が同じ確率で観測されるということを示唆します。

 

3-2. 連続確率分布とPythonでの実装
一方で連続確率分布はXが連続値を取る際の確率分布のことです。連続確率分布の際によく用いられるのが正規分布なので、以下では正規分布についてご紹介します。正規分布は数式で表すと以下のように表すことができます。
f(x)=\frac{1}{\sqrt{2\pi}}exp(-\frac{x^2}{2})
この標準正規分布確率密度関数の数式は下記のコードを実行することで図示できます。

import matplotlib.pyplot as plt
from scipy.stats import norm

x = np.arange(-5,5,0.1)
y = norm.pdf(x)

plt.plot(x,y, color="green")
plt.show()

実行結果は以下のようになります。

f:id:lib-arts:20190419183836p:plain
グラフの解釈にあたっては、expは指数関数で中身の-x^2は常に0以下のため、-x^2=0となるx=0の際に最大の値をとることが納得ができます。


4. まとめ
基礎統計においての確率モデルは色々とややこしいことが多く、情報が少なくて逆にわかりづらいところではあるので、実装を元に概要だけつかんで、先に進みながら必要になればまた戻るような学習法の方が良いのではと思います。
特に、一般化線形モデル(GLM; Generalized Linear Model)の話などを取り扱う際に確率分布の概念をうまく利用するので、応用的な視点で必要になるまでは無理をしないでも十分かと思われます。