Gamma 函数
在实数域可以表示为:
Γ ( x ) = ∫ 0 ∞ t x − 1 e − t d t \Gamma(x)=\int_0^{\infty} t^{x-1}e^{-t}dt Γ(x)=∫0∞tx−1e−tdt;
在整数域可以表示为:
Γ ( n ) = ( n − 1 ) ! \Gamma(n)=(n-1)! Γ(n)=(n−1)!。
此外,Gamma 函数具有如下性质:
Γ \Gamma Γ函数是阶乘在实数上的推广
。
"""
Beta 分布
@date 2019-05-09
@author wangxianpeng
"""
import numpy as np
from scipy.special import gamma
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(12,8))
# Gamma函数(Gamma function)
x = np.linspace(-1, 10, 1000)
plt.plot(x, gamma(x), ls='-', c='k', label='$\Gamma(x)$')
# (x-1)! for x = 1, 2, ..., 6
x2 = np.linspace(1,6,6)
y2 = np.array([1, 1, 2, 6, 24, 120])
plt.plot(x2, y2, marker='*', markersize=12, markeredgecolor='r',
markerfacecolor='r', ls='',c='r', label='$(x-1)!$')
plt.title('Gamma Function')
plt.ylim(0,25)
plt.xlim(0, 6)
plt.xlabel('$x$')
plt.ylabel('$\Gamma(x)$')
plt.legend()
plt.show()
对Gamma函数做个变形,可以得到如下式子: ∫ 0 ∞ t α − 1 e − t d t Γ ( α ) = 1   ( 1.3.1 ) \int_0^{\infty} \frac{t^{\alpha-1}e^{-t}dt}{\Gamma(\alpha)}=1 \: (1.3.1) ∫0∞Γ(α)tα−1e−tdt=1(1.3.1)
取等式左边积分中的函数作为概率密度,就得到一个简单的Gamma分布的密度函数: G a m m a ( t ∣ α ) = t α − 1 e − t Γ ( α ) Gamma(t|\alpha)=\frac{t^{\alpha-1}e^{-t}}{\Gamma(\alpha)} Gamma(t∣α)=Γ(α)tα−1e−t
如果做一个变换 t = β x t=\beta x t=βx,代入(1.3.1)式中,可得 ∫ 0 ∞ ( β x ) α − 1 e − β x d ( β x ) Γ ( α ) = 1 \int_0^{\infty} \frac{(\beta x)^{\alpha-1}e^{-\beta x}d(\beta x)}{\Gamma(\alpha)}=1 ∫0∞Γ(α)(βx)α−1e−βxd(βx)=1。于是就得到Gamma分布的更一般形式: G a m m a ( x ∣ α , β ) = β x α − 1 e − β x Γ ( α ) Gamma(x|\alpha,\beta)=\frac{\beta x^{\alpha-1}e^{-\beta x}}{\Gamma(\alpha)} Gamma(x∣α,β)=Γ(α)βxα−1e−βx。
其中, α 为Gamma分布的 shape parameter,主要决定了曲线的形状
;而 ββ为Gamma分布的 rate parameter 或者 inverse scale parameter,主要决定了曲线有多陡
。Gamma分布的归一化常数
(使得Gamma值为1的点)恰为 Γ \Gamma Γ函数在点 α 处的值 Γ ( α ) \Gamma(\alpha) Γ(α)。
Gamma分布的期望 E = α β E=\frac{\alpha}{\beta} E=βα、方差 D = α β 2 D=\frac{\alpha}{\beta^2} D=β2α。
下面看一下不同参数 α , β \alpha,\beta α,β情况下的Gamma分布
:
import numpy as np
from scipy.stats import gamma
from matplotlib import pyplot as plt
# Gamma分布(Gamma Distribution)
alpha_values = [1, 2, 3, 3, 3]
beta_values = [0.5, 0.5, 0.5, 1, 2]
color = ['b','r','g','y','m']
x = np.linspace(1E-6, 10, 1000)
fig, ax = plt.subplots(figsize=(12, 8))
for k, t, c in zip(alpha_values, beta_values, color):
dist = gamma(k, 0, t)
plt.plot(x, dist.pdf(x), c=c, label=r'$\alpha=%.1f,\ \theta=%.1f$' % (k, t))
plt.xlim(0, 10)
plt.ylim(0, 2)
plt.xlabel('$x$')
plt.ylabel(r'$p(x|\alpha,\beta)$')
plt.title('Gamma Distribution')
plt.legend(loc=0)
plt.show()
显示结果如下:
同时,我们可以发现Gamma分布的概率密度和Poisson分布在数学上的形式具有高度的一致性。参数 λ \lambda λ 的Poisson分布,概率为: P o s s i o n ( x = k ∣ λ ) = λ k k ! e − λ Possion(x=k|\lambda)=\frac{\lambda^k}{k!}e^{-\lambda} Possion(x=k∣λ)=k!λke−λ。
而在Gamma分布的密度函数中取 α = k + 1 , β = 1 \alpha=k+1,\beta = 1 α=k+1,β=1 ,可以得到: G a m m a ( x ∣ α = k + 1 , β = 1 ) = x k e − x k ! Gamma(x|\alpha=k+1,\beta=1)=\frac{x^ke^{-x}}{k!} Gamma(x∣α=k+1,β=1)=k!xke−x。
可以看到这两个分布在数学形式上是一致的,只是Poisson分布式离散的,Gamma分布式连续的,可以直观认为,Gamma分布式是Poisson分布在正实数集上连续化版本
。
Beta 函数
的定义: B ( α , β ) = ∫ 0 1 x α − 1 ( 1 − x ) β − 1 d x B(\alpha,\beta)=\int_{0}^{1}x^{\alpha-1}(1-x)^{\beta-1}\ dx B(α,β)=∫01xα−1(1−x)β−1 dx,其中 α , β > 0 α,β>0 α,β>0。
Beta函数性质:
与Γ函数的关系
: B ( α , β ) = Γ ( α ) Γ ( β ) Γ ( α + β ) \Beta(\alpha,\beta)=\frac{\Gamma(\alpha)\Gamma(\beta)}{\Gamma(\alpha+\beta)} B(α,β)=Γ(α+β)Γ(α)Γ(β),其中 α,β>0根据Beta函数的定义有: ∫ 0 1 x α − 1 ( 1 − x ) β − 1 B ( α , β ) d x = 1 \int_{0}^{1}\frac{x^{\alpha-1}(1-x)^{\beta-1}}{B(\alpha,\beta)}dx=1 ∫01B(α,β)xα−1(1−x)β−1dx=1
取等式左边积分中的函数作为概率密度,就得到了Beta分布
: B e t a ( p ∣ α , β ) = p α − 1 ( 1 − p ) β − 1 B ( α , β ) Beta(p|\alpha,\beta)=\frac{p^{\alpha-1}(1-p)^{\beta-1}}{B(\alpha,\beta)} Beta(p∣α,β)=B(α,β)pα−1(1−p)β−1。
可以发现Beta分布的归一化常数
(使得Beta值为1的点)恰为Beta函数在 (α,β) 处的值。
Beta 分布的期望 E = α α + β E=\frac{\alpha}{\alpha+\beta} E=α+βα、方差 D = α β ( α + β ) 2 ( α + β + 1 ) D=\frac{\alpha\beta}{(\alpha+\beta)^2(\alpha+\beta+1)} D=(α+β)2(α+β+1)αβ。
下面看一下不同参数 α , β \alpha,\beta α,β情况下的Beta分布:
# Beta 分布(Beta distribution)
import numpy as np
from scipy.stats import beta
from matplotlib import pyplot as plt
alpha_values = [1/3,2/3,1,1,2,2,4,10,20]
beta_values = [1,2/3,3,1,1,6,4,30,20]
colors = ['tab:blue', 'tab:orange', 'tab:green', 'tab:red', 'tab:purple',
'tab:brown', 'tab:pink', 'tab:gray', 'tab:olive']
x = np.linspace(0, 1, 1002)[1:-1]
fig, ax = plt.subplots(figsize=(14,9))
for a, b, c in zip(alpha_values, beta_values, colors):
dist = beta(a, b)
plt.plot(x, dist.pdf(x), c=c,label=r'$\alpha=%.1f,\ \beta=%.1f$' % (a, b))
plt.xlim(0, 1)
plt.ylim(0, 6)
plt.xlabel('$x$')
plt.ylabel(r'$p(x|\alpha,\beta)$')
plt.title('Beta Distribution')
ax.annotate('Beta(1/3,1)', xy=(0.014, 5), xytext=(0.04, 5.2),
arrowprops=dict(facecolor='black', arrowstyle='-'))
ax.annotate('Beta(10,30)', xy=(0.276, 5), xytext=(0.3, 5.4),
arrowprops=dict(facecolor='black', arrowstyle='-'))
ax.annotate('Beta(20,20)', xy=(0.5, 5), xytext=(0.52, 5.4),
arrowprops=dict(facecolor='black', arrowstyle='-'))
ax.annotate('Beta(1,3)', xy=(0.06, 2.6), xytext=(0.07, 3.1),
arrowprops=dict(facecolor='black', arrowstyle='-'))
ax.annotate('Beta(2,6)', xy=(0.256, 2.41), xytext=(0.2, 3.1),
arrowprops=dict(facecolor='black', arrowstyle='-'))
ax.annotate('Beta(4,4)', xy=(0.53, 2.15), xytext=(0.45, 2.6),
arrowprops=dict(facecolor='black', arrowstyle='-'))
ax.annotate('Beta(1,1)', xy=(0.8, 1), xytext=(0.7, 2),
arrowprops=dict(facecolor='black', arrowstyle='-'))
ax.annotate('Beta(2,1)', xy=(0.9, 1.8), xytext=(0.75, 2.6),
arrowprops=dict(facecolor='black', arrowstyle='-'))
ax.annotate('Beta(2/3,2/3)', xy=(0.99, 2.4), xytext=(0.86, 2.8),
arrowprops=dict(facecolor='black', arrowstyle='-'))
#plt.legend(loc=0)
plt.show()
显示结果如下:
注意到这里当 α = 1 , β = 1 \alpha=1,\beta=1 α=1,β=1时,Beta分布退化成一个均匀分布。
此外,前面提到Beta分布的均值 E = α α + β E=\frac{\alpha}{\alpha+\beta} E=α+βα,也可以通过采样的方法,在一个Beta分布中,采样,计算均值。
这里我们取 α = 2 , β = 1 \alpha=2,\beta=1 α=2,β=1,理论上均值应该是 2 3 \frac{2}{3} 32,我们看一下采样方法的结果:
import numpy as np
import numpy.random as nprnd
import scipy.stats as spstat
import scipy.special as ssp
import itertools as itt
import matplotlib.pyplot as plt
import pylab as pl
# Beta 分布的平均数
N = (np.arange(200) + 3) ** 2 * 20
betamean = np.zeros_like(N, dtype=np.float64)
for idx, i in enumerate(N):
betamean[idx] = np.mean(nprnd.beta(2, 1, i))
plt.plot(N, betamean, color='steelblue', lw=2)
plt.xscale('log')
plt.show()
print(spstat.beta(2, 1).mean(), 2.0 / (2 + 1))
结果显示如下:
这里可以看到,随着采样点的增加,样本点的均值也就更加的收敛,更加的接近 2 3 \frac{2}{3} 32。 这样,这个图片的结果也符合大数定理
,随着采样点的增加,只要样本点无限大,那么最终的均值就会无限的接近它的期望值 2 3 \frac{2}{3} 32.
Beta分布可以理解为它表示概率的概率分布
—也就是在我们不知道一件事的概率是多少的时候,它能表示一个概率的所有可能值。
Beta分布其实是二项分布的共轭分布。
在贝叶斯概率理论中,如果后验概率P(θ|x)和先验概率P(θ)满足同样的分布律,那么,先验分布和后验分布被叫做共轭分布
,同时,先验分布叫做似然函数的共轭先验分布。
贝叶斯参数估计的基本过程是:先验分布+数据知识=后验分布
因此可以得到: B e t a ( p ∣ k , n − k + 1 ) + B i n o m C o u n t ( m 1 , m 2 ) = B e t a ( p ∣ k + m 1 , n − k + 1 + m 2 ) Beta(p|k,n-k+1)+BinomCount(m1,m2)=Beta(p|k+m1,n-k+1+m2) Beta(p∣k,n−k+1)+BinomCount(m1,m2)=Beta(p∣k+m1,n−k+1+m2)。其中经过了m次伯努利实验
,有 m1 个比 p 小, m2 个比 p 大。更一般的,对于非负实数 α , β \alpha,\beta α,β ,我们有如下关系:
B e t a ( p ∣ α , β ) + B i n o m C o u n t ( m 1 , m 2 ) = B e t a ( p ∣ α + m 1 , β + m 2 ) Beta(p|\alpha,\beta)+BinomCount(m1,m2)=Beta(p|\alpha+m1,\beta+m2) Beta(p∣α,β)+BinomCount(m1,m2)=Beta(p∣α+m1,β+m2)
以上式子实际上描述的就是Beta-Binomial共轭
(Beta-二项分布共轭)。共轭意思是先验和后验都服从同一个分布形式。这种形式不变,我们能够在先验分布中赋予参数很明确的物理意义,这个物理意义可以延伸到后验分布中进行解释
,同时从先验变换到后验的过程中从数据中补充的知识也容易有物理解释。(还有另一个好处是:每当有新的观测数据,就把上次的后验概率作为先验概率,乘以新数据的likelihood,然后就得到新的后验概率,而不必用先验概率乘以所有数据的likelihood得到后验概率。)
那么我们简单说个Beta-Binomial共轭的应用。用一句话来说,beta分布可以看作一个概率的概率分布,当你不知道一个东西的具体概率是多少时,它可以给出了所有概率出现的可能性大小。
举一个简单的例子,熟悉棒球运动的都知道有一个指标就是棒球击球率(batting average),就是用一个运动员击中的球数除以击球的总数,我们一般认为0.266是正常水平的击球率,而如果击球率高达0.3就被认为是非常优秀的。现在有一个棒球运动员,我们希望能够预测他在这一赛季中的棒球击球率是多少。传统的频率学派会直接计算棒球击球率,用击中的数除以击球数,但是如果这个棒球运动员只打了一次,而且还命中了,那么他就击球率就是100%了,这显然是不合理的,因为根据棒球的历史信息,我们知道这个击球率应该是0.215到0.36之间才对。对于这个问题,我们可以用一个二项分布表示(一系列成功或失败),一个最好的方法来表示这些经验(在统计中称为先验信息)就是用beta分布,这表示在我们没有看到这个运动员打球之前,我们就有了一个大概的范围。beta分布的定义域是 (0,1) 这就跟概率的范围是一样的。接下来我们将这些先验信息转换为beta分布的参数,我们知道一个击球率应该是平均0.27左右,而他的范围是0.21到0.35,那么根据这个信息,我们可以取 α = 81 , β = 219 \alpha=81,\beta=219 α=81,β=219 。(这样取值可以从Beta的均值和分布考虑)。具体看下它的概率分布图:
import numpy as np
from scipy.stats import beta
from matplotlib import pyplot as plt
# 击球率为0.27左右时的Beta分布
x = np.linspace(0, 1, 1002)[1:-1]
fig, ax = plt.subplots(figsize=(10,6))
dist = beta(81, 219)
plt.plot(x, dist.pdf(x), c='b',label=r'$\alpha=%.1f,\ \beta=%.1f$' % (81, 219))
plt.xlim(0, .6)
plt.ylim(0, 16)
plt.xlabel('$x$')
plt.ylabel(r'$p(x|\alpha,\beta)$')
plt.title('Beta Distribution')
plt.legend(loc=0)
plt.show()
x 轴表示各个击球率的取值, x 对应的 y 值就是这个击球率所对应的概率
。也就是说beta分布可以看作一个概率的概率分布。
那么有了先验信息后,现在我们考虑一个运动员只打一次球,那么他现在的数据就是”1中;1击”。这时候我们就可以更新我们的分布了,让这个曲线做一些移动去适应我们的新信息。因beta分布与二项分布是共轭先验的(Conjugate_prior)。那么后验是: B e t a ( α 0 + h i t s , β 0 + m i s s e s ) Beta(\alpha_0+hits,\beta_0+misses) Beta(α0+hits,β0+misses) 。
其中 α 0 \alpha_0 α0 和 β 0 \beta_0 β0 是一开始的参数,在这里是81和219。所以在这一例子里, α \alpha α 增加了1(击中了一次)。 β \beta β 没有增加(没有漏球)。这就是我们的新的beta分布 B e t a ( 81 + 1 , 219 ) Beta(81+1,219) Beta(81+1,219) 。我们看下击中一次后新的击球率Beta分布:
import numpy as np
from scipy.stats import beta
from matplotlib import pyplot as plt
# 击中一次后的击球率Beta分布
x = np.linspace(0, 1, 1002)[1:-1]
fig, ax = plt.subplots(figsize=(10,6))
dist = beta(81, 219)
plt.plot(x, dist.pdf(x), c='b',label=r'$\alpha=%.1f,\ \beta=%.1f$' % (81, 219))
dist = beta(82, 219)
plt.plot(x, dist.pdf(x), c='r',label=r'$\alpha=%.1f,\ \beta=%.1f$' % (82, 219))
plt.xlim(0, .6)
plt.ylim(0, 16)
plt.xlabel('$x$')
plt.ylabel(r'$p(x|\alpha,\beta)$')
plt.title('Beta Distribution')
plt.legend(loc=0)
plt.show()
可以看到这个分布其实没多大变化,这是因为只打了1次球并不能说明什么问题。但是如果我们得到了更多的数据,假设一共打了300次,其中击中了100次,200次没击中,那么这一新分布就是: B e t a ( 81 + 100 , 219 + 200 ) Beta(81+100,219+200) Beta(81+100,219+200)。我们来看一下击中100次,失误200次之后新的击球率Beta分布:
import numpy as np
from scipy.stats import beta
from matplotlib import pyplot as plt
# 击中100,失误200次之后的击球率Beta分布
x = np.linspace(0, 1, 1002)[1:-1]
fig, ax = plt.subplots(figsize=(10,6))
dist = beta(81, 219)
plt.plot(x, dist.pdf(x), c='b',label=r'$\alpha=%.1f,\ \beta=%.1f$' % (81, 219))
dist = beta(181, 419)
plt.plot(x, dist.pdf(x), c='r',label=r'$\alpha=%.1f,\ \beta=%.1f$' % (181, 419))
plt.xlim(0, .6)
plt.ylim(0, 22)
plt.xlabel('$x$')
plt.ylabel(r'$p(x|\alpha,\beta)$')
plt.title('Beta Distribution')
plt.legend(loc=0)
plt.show()
注意到这个曲线变得更加尖,并且平移到了一个右边的位置,表示比平均水平要高。
一个有趣的事情是,根据这个新的beta分布,我们可以得出他的数学期望为: α α + β = 0.303 \frac{\alpha}{\alpha+\beta}=0.303 α+βα=0.303 ,这一结果要比直接的估计要小 100 100 + 200 = 0.333 \frac{100}{100+200}=0.333 100+200100=0.333 。你可能已经意识到,我们事实上就是在这个运动员在击球之前可以理解为他已经成功了81次,失败了219次这样一个先验信息。
因此,对于一个我们不知道概率是什么,而又有一些合理的猜测时,beta分布能很好的作为一个表示概率的概率分布。
Dirichlet(狄利克雷)可以看做是将Beta分布推广到多变量
的情形。概率密度函数定义如下 :
D i r ( p ⃗ ∣ α ⃗ ) = 1 B ( α ⃗ ) ∏ k = 1 K p k α k − 1 ( ∗ ) Dir(\vec p|\vec \alpha) = \frac{1}{B(\vec \alpha)} \prod_{k=1}^{K}p_{k}^{\alpha_{k}-1} \ \ \ \ \ (*) Dir(p∣α)=B(α)1k=1∏Kpkαk−1 (∗)
其中, α ⃗ = ( α 1 , α 2 , … , α K ) \vec \alpha = (\alpha_{1},\alpha_{2},\ldots,\alpha_{K}) α=(α1,α2,…,αK) 为Dirichlet分布的参数。满足: α 1 , α 2 , … , α K > 0 \alpha_{1},\alpha_{2},\dots,\alpha_{K} > 0 α1,α2,…,αK>0。
B ( α ⃗ ) B(\vec \alpha ) B(α) 表示 Dirichlet分布的归一化常数:
B ( α ⃗ ) = ∫ ∏ k = 1 K p k α k − 1 d p ⃗ B(\vec \alpha)=\int \prod_{k=1}^{K}p_{k}^{\alpha_{k}-1} \ d\vec p B(α)=∫k=1∏Kpkαk−1 dp
类似于Beta函数有以下等式成立:
B ( α ⃗ ) = Γ ( ∑ k = 1 K α k ) ∏ k = 1 K Γ ( α k ) B(\vec\alpha) = \frac{\Gamma(\sum_{k=1}^{K}\alpha_{k})}{\prod_{k=1}^{K}\Gamma(\alpha_{k})} B(α)=∏k=1KΓ(αk)Γ(∑k=1Kαk)
附:
code
参考:
THE END.