$\Beta$分佈推導與視覺化

頎周發表於2023-04-14

$\Gamma$函式

  $\Gamma$函式(Gamma函式)是階乘函式在實數和複數域的擴充套件。對於正整數$n$,階乘函式表示為$n! = 1 \times 2 \times ... \times n$。然而,這個定義僅適用於正整數。Gamma函式的目的是將階乘擴充套件到實數和複數域,從而計算實數和複數的“階乘”。$\Gamma$函式定義如下:

$\displaystyle \Gamma(x) = \int_0^\infty t^{x-1}e^{-t} dt $

  其中,$x$是一個複數,定義域是$\{x|x\in C- Z^--\{0\}\}$,也就是除了負整數和$0$之外的所有複數。透過這個定義,$\Gamma$函式可以用來計算實數和複數的“階乘”。在實數域與複數域的視覺化如下:

  $\Gamma$函式具有以下性質:

  1、對於正整數$n$,有$\Gamma(n) = (n - 1)!$。這表明$\Gamma$函式在正整數上與階乘函式相符。

  2、$\Gamma$函式滿足遞推關係:$\Gamma(x + 1) = x\Gamma(x)$(注意和整數階乘的聯絡)。

  3、$\Gamma$函式用於定義很多常見的機率分佈,如$\Gamma$分佈、Beta分佈和t分佈等。

$\Beta$分佈

基於伯努利實驗的推導

  $\Beta$分佈(Beta分佈)與伯努利試驗相關。在伯努利試驗中,假設硬幣朝上的機率為$p$。當拋$a+b$次硬幣,硬幣朝上的次數為$a$時,計算該情況的機率為

$ \displaystyle C_{a+b}^ap^a(1-p)^b$

  上式表示二項分佈在這一事件(即$a+b$次實驗,$a$次正面)下的機率。則$\Beta$分佈表示:把機率$p$看做隨機變數,固定$a,b$,發生相應事件的機率分佈。為了獲取$\Beta$分佈的機率密度,需要計算以上機率關於$p$的積分的歸一化係數$k$,使得:

$\displaystyle k \int_0^1C_{a+b}^ap^a(1-p)^b  dp=1$

  推匯出

$\displaystyle k =\left(\int_0^1C_{a+b}^ap^a(1-p)^b dp\right)^{-1}=a+b+1 $

  以上積分我不會算,但是可以透過以下程式來驗證。

from scipy.special import comb

def Int(func, l, h, n=1000): #模擬定積分
    a = np.linspace(l, h, n)
    return func(a).sum()*(h-l)/n
a, b = 5, 2 #取任意整數
k = a + b + 1
def func(x):
    return comb(a+b, a) * (x**a) *((1-x)**b)
Int(func, 0, 1) * k # = 1

  獲得機率密度函式:

$ \begin{align} f(p; a, b)&=(a+b+1)C_{a+b}^ap^a(1-p)^b\\ &=\frac{(a+b+1)!}{a!b!}p^a(1-p)^b\\ \end{align} $

  把階乘擴充為$\Gamma$函式,上式就變成

$ \begin{align}f(p; a, b)= \frac{\Gamma(a+b+2)}{\Gamma(a+1)\Gamma(b+1)}p^a(1-p)^b\end{align}$

  令$a=\alpha-1,b=\beta-1,p=x$,就可以得到常見的$\Beta$分佈的密度函式表示形式:

$ \begin{align}\displaystyle f(x;\alpha,\beta)=\frac{\Gamma(\alpha+\beta)}{\Gamma(\alpha)\Gamma(\beta)}x^{\alpha-1}(1-x)^{\beta-1}=\frac{1}{\Beta(\alpha,\beta)}x^{\alpha-1}(1-x)^{\beta-1}\end{align}$

  其中$\alpha>0,\beta>0,0<x<1$。關於均值、方差什麼的這裡就不贅述了。

聯合機率密度

正整數情況

  關於(2)式,我們把其中的$a,b,p$都看作隨機變數,再除以一個歸一化係數,就可以構成這三個隨機變數的聯合機率密度,從而可以非常直觀地理解$\Beta$分佈。分別固定抽樣次數$n=0,1,2,5,10,15$,視覺化如下:

  其中,當以抽樣機率$p$為條件時,在y軸上,就是離散的關於$a$的二項分佈。當以$a$為條件時,在x軸上,就是連續的關於$p$的$\Beta$分佈。可以觀察到,當$a<b$時,$\Beta$分佈左偏,否則右偏,在$n=0$時,變為均勻分佈。

  此外,當在y軸方向上進行求和,可以得到$p$的邊緣分佈,為均勻分佈;而當在x軸方向上進行積分,得到$a$的邊緣分佈,也是均勻分佈。但感覺邊緣分佈似乎沒有什麼意義,不知理解是否正確。視覺化程式碼如下:

import matplotlib.pyplot as plt
from scipy.special import gamma
import numpy as np
import matplotlib 
matplotlib.rcParams['font.family'] = 'Times New Roman'

def Beta(a, b, p):
    g1, g2, g3 = gamma(a+b+2), gamma(a+1), gamma(b+1)
    return g1/(g2*g3) * p**(a) * (1-p)**(b)
def BetaHot(n, samp_n = 1000):
    p = np.linspace(0, 1, samp_n)
    a = np.linspace(0, n, n+1)
    P, A = np.meshgrid(p, a)

    Z = Beta(A, n-A, P)/(n+1)
    per_width = samp_n//(n+1)
    Z1 = np.repeat(Z, per_width, 0)
    # 熱力圖
    plt.imshow(Z1, origin='lower', cmap='Blues')
    plt.colorbar()
    # 關於p的密度圖
    for i, t in enumerate(Z):
        plt.plot(np.linspace(-0.5, samp_n-0.5, samp_n), i*per_width+per_width*t-0.5, '--', c='red')
    # 繪圖設定
    plt.xlabel("p")
    plt.ylabel('a')
    old_yticks = np.linspace(per_width/2-0.5, Z1.shape[0]-0.5-per_width/2, n+1)
    plt.yticks(old_yticks, [f'{i:.0f}' for i in np.linspace(0, n, n+1)])
    old_xticks = np.linspace(-0.5, samp_n-0.5, 6)
    plt.xticks(old_xticks, [f'{i:.1f}' for i in np.linspace(0, 1, 6)])
    plt.ylim([0, samp_n+4])
    plt.title("n = a + b = %d"%n)
    plt.savefig('img/n = %d.png'%n)
    plt.show()

for n in [0, 1, 2, 5, 10, 15]:
    BetaHot(n)

一般情況

  以上視覺化的是$a,b$取為正整數時$\Beta$分佈的情況,即(2)式。對於更一般的情況(4)式,即取$\alpha,\beta$為大於0的實數,在(3)式中就是$a>-1,b>-1$,儘管並不符合真實伯努利試驗的情況,但仍可以計算。視覺化如下:

 

  可以看出,$a,b$都小於0時,密度函式會變成U形。且依舊是,$a$相比$b$越小,形狀越往左偏。視覺化程式碼如下:

import matplotlib.pyplot as plt
from scipy.special import gamma
import numpy as np
import matplotlib 
matplotlib.rcParams['font.family'] = 'Times New Roman'

def Beta(a, b, p):
    g1, g2, g3 = gamma(a+b+2), gamma(a+1), gamma(b+1)
    beta = g1/(g2*g3) * p**(a) * (1-p)**(b)
    return beta

for n in [-1, 0, 1, 2, 5, 10]:
    for a in np.linspace(-0.9, n+0.9, 3):
        p = np.linspace(0.0001, 0.9999, 300)
        b = n-a
        y = Beta(a, b, p)
        plt.plot(p, y, label="a = %.1f, b = %.1f"%(a, b))
    plt.legend(loc='upper center')
    plt.ylim([-0.1, 3])
    plt.title('a + b = %.1f' % n)
    plt.savefig('img/a + b = %.1f.png' % n)
    plt.show()

參考

1.  共軛先驗: https://www.zhihu.com/question/41846423?sort=created

2. 狄利克雷分佈:https://zhuanlan.zhihu.com/p/425388698

相關文章