機率分配

我們可以將機率分配想成:描述各個隨機變數的值發生機率的函數。

連續投擲兩次公正銅板的正面次數這個隨機變數 \(X\) 為例:

  • 樣本空間為 \(\mathcal{S} = \{(T, T), (T, H), (H, T), (H, H)\}\)

  • 隨機變數為函數 \(X: \mathcal{S} \rightarrow \mathbb{R}\) ,我們將樣本空間 \(\mathcal{S}\)事件映射到實數上,變成 \(\{0, 1, 1, 2\}\)

  • 樣本空間 \(\mathcal{S}\) 的樣本點發生機率都相同 (因為每次丟銅板出現正面或反面的機率都是相同的,舉例來說: 連續兩次反面的機率會等於第一次正面,第二次反面的機率。)

  • 我們可以看作:

\[\begin{split} \begin{cases} \frac{1}{4} & E = (T, T) \\ \frac{1}{4} & E = (T, H) \\ \frac{1}{4} & E = (H, T) \\ \frac{1}{4} & E = (H, H) \end{cases} \underset{\implies}{映射} \begin{cases} \frac{1}{4} & X = 0 \\ \frac{1}{4} & X = 1 \\ \frac{1}{4} & X = 1 \\ \frac{1}{4} & X = 2 \end{cases} \underset{\implies}{合併} \begin{cases} \frac{1}{4} & X = 0 \\ \frac{1}{2} & X = 1 \\ \frac{1}{4} & X = 2 \end{cases} \end{split}\]
  • 最後得到的式子,就是隨機變數 \(X\) 的機率分配,在離散隨機變數的情況下,又可以稱作機率質量函數

附上用程式碼畫出分佈的範例

from typing import Tuple
from itertools import groupby

import plotly.graph_objects as go

# 樣本空間
S = {('T', 'T'), ('T', 'H'), ('H', 'T'), ('H', 'H')}

# 隨機變數
def X(event: Tuple[str, str]) -> int:
    '''隨機變數 - 連續投擲兩次公正硬幣,正面的次數

    Args:
        event (Tuple[str, str]): 連續投擲兩次公正銅板的事件

    Returns:
        head (int): 正面的次數
    '''
    head = 0

    for trial in event:
        if trial == 'H':
            head += 1

    return head

# 將樣本空間映射
S_new = sorted([X(event) for event in S])

# 製作機率分配
distribution = []

for x, outcomes in groupby(S_new):
    distribution.append({
        'x': x,
        'prob': len([out for out in outcomes]) / len(S_new)
    })

# 畫圖
bar = go.Bar(
    x=[pt['x'] for pt in distribution],
    y=[pt['prob'] for pt in distribution],
)
fig = go.Figure(data=[bar])
fig.update_layout(
    title="連續投擲兩次公正銅板出現正面次數的機率分配",
    xaxis_title="正面的次數",
    yaxis_title="機率",
)
fig

離散型機率分配

機率質量函數 (probability mass function)

給定離散型隨機變數 \(X\) ,若函數 \(f_X(x)\) 滿足

  • \(0 \leq f_X(x) \leq 1, \forall x \in \mathbb{R}\)

  • \(\sum_{x \in \mathbb{R}} f_X(x) = 1\)

  • \(f_X(x \in A) = \sum_{x \in A} f_X(x)\)

我們稱其為隨機變數 \(X\) 的機率質量函數。

  • 機率質量函數的值就是機率。

伯努利分配 (Bernoulli Distribution)

定義

假設隨機變數 \(X\)一次隨機試驗成功的次數,其樣本空間 \(\mathcal{S} = \{ Success, Failure \}\) ,而機率質量函數 \(f_X(x)\)

\[\begin{split} f_X(x) = \begin{cases} 1 - p & x = 0 \\ p & x = 1 \\ 0 & otherwise \end{cases} \end{split}\]

\(0 \leq p \leq 1\) ,成功機率為 \(p\) ,失敗機率為 \(1 - p\)

我們記作

\[ X \sim \mathcal{Ber}(p) \]
  • Bernoulli 分配就是 \(n = 1\) 的 Binomial 分配

假設有一個不公正硬幣,其正面的機率為 \(p = 0.7\) ,隨機變數 \(X\) 為投擲一次這個硬幣出現正面的次數,所以其機率質量函數 \(f_X(x)\) 可以寫成

\[\begin{split} f_X(x) = \begin{cases} 0.7 & x = 1 \\ 0.3 & x = 0 \\ 0 & otherwise \end{cases} \end{split}\]

下面程式碼是畫出 \(p = 0.7\) 伯努利分配的機率質量函數。

import plotly.graph_objects as go

# 隨機變數
X = {0, 1}

# 機率質量函數
f = {0: 0.3, 1: 0.7}

# 畫出機率質量函數
bar = go.Bar(x=list(X), y=[f[x] for x in X])
fig = go.Figure(data=[bar],
                layout=go.Layout(
                    title={'text': 'Bernoulli Distribution (p = 0.7)'},
                    xaxis={'title': '$x$'},
                    yaxis={'title': '$f(x)$'}))
fig

二項分配 (Binomial Distribution)

定義

假設隨機變數 \(X\)n次隨機試驗成功的次數,其樣本空間 \(\mathcal{S} = \{(Success, Success, ...), ..., (Failure, Failure, ...)\}\) ,機率質量函數 \(f_X(x)\)

\[\begin{split} f_X(x) = \begin{cases} \binom{n}{x}p^x(1-p)^{(n-x)} & x = 0, 1, ..., n \\ 0 & otherwise \end{cases} \end{split}\]

我們記作

\[ X \sim \mathcal{Binom}(n, p) \]
  • 二項分配就是執行n次的伯努利分配

給定隨機變數 \(X\)投擲10次公正硬幣出現正面的次數,其中出現正面的機率 \(p = 0.5\) ,機率質量函數可以寫成

\[\begin{split} f_X(x) = \begin{cases} \binom{10}{x} \cdot 0.5^{x} \cdot (1 - 0.5)^{10 - x} & x = 0, 1, ..., 10 \\ 0 & otherwise \end{cases} \end{split}\]

下面提供畫出隨機變數 \(X\) 機率質量函數的程式碼

from typing import Tuple
from itertools import product
from collections import Counter

import plotly.graph_objects as go

# 樣本空間
S = {out for out in product([0, 1], repeat=10)}

# 隨機變數


def X(event: Tuple) -> int:
    '''隨機變數 - 連續投擲10次公正硬幣出現正面的次數

    Args:
        event (Tuple): 連續投擲10次公正硬幣的結果

    Returns:
        head (int): 出現正面的次數
    '''
    return sum(event)


# 將樣本空間映射
S_new = [X(event) for event in S]

# 機率分配
distribution = Counter(S_new)

# 畫圖
data = [
    go.Bar(
        x=[x for x in range(0, 11)],
        y=[
            distribution[count] / sum(distribution.values())
            for count in range(0, 11)
        ],
    )
]
fig = go.Figure(data=data,
                layout=go.Layout(
                    title={'text': 'Binomial Distribution (n=10, p=0.5)'},
                    xaxis={'title': '$x$'},
                    yaxis={'title': '$f(x)$'}))
fig

二項分配近似常態分配

二項分配在 \(n\) 夠大的時候會近似常態分配。

假設有隨機變數 \(X_n \sim \mathcal{Binom}(n, p), \forall n \in \mathbb{Z}\) ,在 \(n\) 夠大時會趨近於常態分配

\[ \lim_{n \rightarrow \infty} X_n \overset{\text{approx.}}{\sim} \mathcal{N}(\mu = np, \sigma^2 = np(1 - p)) \]

期望值 \(\mu = np\) ,變異數 \(\sigma^2 = np(1-p)\)

import numpy as np
from scipy.stats import binom, norm
from plotly.subplots import make_subplots
import plotly.graph_objects as go

ns = [10, 30, 100]
p = 0.5

fig = make_subplots(rows=3, cols=1, subplot_titles=[f'$n = {n}$' for n in ns])

for i, n in enumerate(ns, start=1):
    # 畫出二項分配 pmf
    fig.add_trace(
        go.Bar(x=[x for x in range(n + 1)],
               y=[binom.pmf(x, n, p) for x in range(n + 1)],
               name=f'$\mathcal{{B}}(n = {n}, p={p})$'),
        row=i,
        col=1,
    )

    # 畫出常態分配 N(np, np(1-p)) 的 pdf
    mean = n * p
    var = n * p * (1 - p)
    std_error = np.sqrt(var)
    points = np.linspace(mean - 3 * std_error, mean + 3 * std_error, 1000)

    label = r'$\mathcal{{N}}(\mu = {mu}, \sigma = \sqrt{{{var}}})$'.format(
        mu=mean, var=var)
    fig.add_trace(
        go.Scatter(x=points,
                   y=[norm.pdf(x, mean, std_error) for x in points],
                   mode='lines',
                   name=label),
        row=i,
        col=1,
    )

fig.update_layout(title={'text': '二項分配近似常態分配'})
fig

連續型機率分配

機率密度函數 (probability density function)

給定連續型隨機變數 \(X\) ,若函數 \(f_X(x)\) 滿足

  • \(f_X(x) \geq 0\)

  • \(\int_{\mathbb{R}}f_X(x)dx = 1\)

  • \(\mathbb{P}(X \in A) = \int_{A} f_X(x) dx, A \subset \mathbb{R}\)

我們稱其為隨機變數 \(X\) 的機率密度函數。

  • 機率密度函數的值不是機率,機率需要對特定區域積分獲得。

假設有一個隨機變數 \(X\) 在0到100間出現的機率都相等,其機率密度函數可以寫成

\[\begin{split} f_X(x) = \begin{cases} \frac{1}{100 - 0} & 0 \leq x \leq 100 \\ 0 & otherwise \end{cases} \end{split}\]

因為連續型的隨機變數,其機率需要靠積分得到,所以單點機率 \(\mathbb{P}(X = x) = \int_{x}^x f_X(x)dx = 0\)

但若給定範圍,例如 \(\mathbb{P}(0 \leq X \leq 50) = \int_{0}^{50} f_X(x)dx = \int_{0}^{50} \frac{1}{100}dx = \frac{x}{100}\big|_{0}^{50} = 0.5\)

此分配又稱為均勻分配

下面的程式碼示範將這個隨機變數的機率密度函數畫出來

import plotly.graph_objects as go
import numpy as np

# 上界與下界
a, b = 0, 100

# 機率密度函數


def f(a, b, x):
    if x >= a and x <= b:
        return 1 / (b - a)
    else:
        return 0


# 製作機率密度函數的點
xs = np.linspace(a - 10, b + 10, 1000)
ys = [f(a, b, x) for x in xs]

# 製作0到50機率面積的點
prob_xs = np.linspace(0, 50, 1000)
prob_ys = [f(a, b, x) for x in prob_xs]

# 畫出機率密度函數與0到50的機率
data = [
    go.Scatter(x=xs, y=ys, mode='lines', name='機率密度函數'),
    go.Scatter(x=prob_xs,
               y=prob_ys,
               mode='lines',
               fill='tozeroy',
               name='0到50的機率值')
]
fig = go.Figure(data,
                layout=go.Layout(title={'text': '連續型機率分配'},
                                 xaxis={'title': '$x$'},
                                 yaxis={'title': '$f(x)$'}))
fig