贝叶斯方法学习笔记(一)
一.基本概念
先验概率:我们把对一个事件A发生的信念记作 P ( A ) P(A) P(A)
贝叶斯派思考事物的方式:随着证据的出现更新信念,而用 P ( A ∣ X ) P(A|X) P(A∣X)表示更新之后的信念。也即为得到证据 X X X后, A A A事件的概率,称为后验概率。
如果 N N N是我们拥有证据的数量。如果 N → ∞ N\rightarrow\infty N→∞,那么贝叶斯的结果通常和频率派的结果一致。
贝叶斯框架:我们对事件
A
A
A有一个先验估计,接下来我们根据证据不断调整心里的估计,这个估计值可以通过下面的公式完成:
P
(
A
∣
X
)
=
P
(
X
∣
A
)
P
(
A
)
P
(
X
)
P(A|X)=\frac{P(X|A)P(A)}{P(X)}
P(A∣X)=P(X)P(X∣A)P(A)
二.实例(史蒂文的身份):
史蒂文被描述为一个害羞但是乐于助人的人,他对其他人不太关注。他非常乐见事情处于合理的顺序,并且工作非常细心。你会认为史蒂文是图书管理员还是农民呢?(男性农民是男性图书馆员的20倍。)
在这里我们将问题简化。如果世界上只有两种职业::农民和图书馆管理员。并且数量相差的确20倍。那么,设: A A A:史蒂文是图书管理员(信息仅此而已)
那么先验概率
P
(
A
)
=
1
21
=
0.047
P(A)=\frac{1}{21}=0.047
P(A)=211=0.047。此时,如果我们从他的邻居哪里获得了关于他的信息,我们记录为
X
X
X。我们想知道的是
P
(
A
∣
X
)
P(A|X)
P(A∣X),根据贝叶斯定理:
P
(
A
∣
X
)
=
P
(
X
∣
A
)
P
(
A
)
P
(
X
)
P(A|X)=\frac{P(X|A)P(A)}{P(X)}
P(A∣X)=P(X)P(X∣A)P(A)
P
(
X
∣
A
)
:
P(X|A):
P(X∣A):被定义为在史蒂文真的是一个图书管理员的情况下,邻居给出某种描述的概率。但是,从常识上我们可以发现,如果史蒂文真的是一个图书管理员,那么他的邻居有极大的概率认为知道他到底是什么官职。也就是说:
P
(
X
∣
A
)
→
1
P(X|A)\rightarrow1
P(X∣A)→1
P
(
X
)
P(X)
P(X):对于
P
(
X
)
P(X)
P(X)可以进行逻辑上的改造:
P
(
X
)
=
P
(
X
∣
A
)
P
(
A
)
+
P
(
X
∣
A
‾
)
P
(
A
‾
)
P(X)=P(X|A)P(A)+P(X|\overline A)P(\overline A)
P(X)=P(X∣A)P(A)+P(X∣A)P(A)
而:
P
(
A
‾
)
=
1
−
1
21
=
0.953
P(\overline A) = 1-\frac{1}{21}=0.953
P(A)=1−211=0.953
现在我们要知道
P
(
A
∣
X
)
P(A|X)
P(A∣X),只需要知道
P
(
X
∣
A
‾
)
P(X|\overline A)
P(X∣A)就可以了。
P ( X ∣ A ‾ ) P(X|\overline A) P(X∣A):邻居在知道史蒂文不是图书馆管理员后给出的信息 X X X的概率,假设为 0.5 0.5 0.5
那么后验概率:
P
(
A
∣
X
)
=
1
×
0.047
0.953
×
0.5
+
1
×
0.047
=
0.09
P(A|X)=\frac{1\times0.047}{0.953\times0.5+1\times0.047}=0.09
P(A∣X)=0.953×0.5+1×0.0471×0.047=0.09
而用python绘图可以发现趋势:
from IPython.core.pylabtools import figsize
import numpy as np
from matplotlib import pyplot as plt
figsize(8,4)
plt.rcParams['savefig.dpi']=300
plt.rcParams['figure.dpi'] = 300
colors = ['blue','red']
prior = [1/21,20/21]
postPrior = [0.09,1-0.09]
plt.bar([0,0.7],prior,alpha = 0.70,width=0.25,color = colors[0],label = 'prior',lw = '0',edgecolor = 'blue')
plt.bar([0+0.25,0.7+0.25],postPrior,alpha = 0.7,width=0.25,color = colors[1],label = 'postprior',lw = '0',edgecolor = 'red')
plt.xticks([0.20,0.95],['Librarian','Farmer'])
plt.title("Probability of Prior and postPrior")
plt.ylabel("Probability")
plt.legend(loc = "upper left")
plt.show()
可以看出,很明显经过证据 X X X后,史蒂文是图书管理员的概率升高了,但是依然史蒂文还是农民的概率比较高。
三.基本的概率分布及其性质
1.离散分布:
设
Z
Z
Z服从泊松分布,
Z
∼
P
o
i
(
λ
)
Z\sim Poi(\lambda)
Z∼Poi(λ),
λ
\lambda
λ为其分布强度,且
E
(
Z
)
=
λ
E(Z) = \lambda
E(Z)=λ为任意正数。
P
(
Z
=
k
)
=
λ
k
e
−
λ
k
!
,
k
=
0
,
1
,
2...
P(Z=k)=\frac{\lambda^ke^{-\lambda}}{k!},k = 0,1,2...
P(Z=k)=k!λke−λ,k=0,1,2...
2.连续分布:
设
Z
Z
Z服从指数分布,
Z
∼
E
x
p
(
λ
)
Z\sim Exp(\lambda)
Z∼Exp(λ),且
E
(
Z
)
=
1
λ
,
λ
>
0
E(Z) = \frac{1}{\lambda},\lambda>0
E(Z)=λ1,λ>0
f
Z
(
Z
∣
λ
)
=
λ
e
−
λ
z
,
z
≥
0
f_Z(Z|\lambda)=\lambda e^{-\lambda z},z\geq0
fZ(Z∣λ)=λe−λz,z≥0
四.实例(用短信数据推断行为):
如果你得到了系统中一个用户每天的短信条数数据。你很好奇这个用户每天的短信使用行为是否随着时间有所改变,不管是循序渐进还是突然地变化。怎么模拟呢(假设是一个月)?
前面提到,
P
o
s
s
i
o
n
Possion
Possion变量能很好地模拟这种计数类型地数据,用
C
i
C_i
Ci表示第
i
i
i天地短信条数。
C
i
∼
P
o
i
(
λ
)
C_i\sim Poi(\lambda)
Ci∼Poi(λ)
尽管我们不能确定参数
λ
\lambda
λ的真实值,但是我们却可以发现
λ
\lambda
λ在某段时间内增加了。(当
λ
\lambda
λ增大时,更容易得到较大的结果值。)
假设在观察期的某些天(称其为
τ
\tau
τ),参数值
λ
\lambda
λ的取值变得比较大:
λ
=
{
λ
1
若
t
<
τ
λ
2
若
t
≥
τ
\lambda = \begin{cases} \lambda_1 &若 t<\tau\\ \lambda_2 &若 t \geq \tau \end{cases}
λ={λ1λ2若t<τ若t≥τ
在贝叶斯推断下,我们需要对不同的
λ
\lambda
λ分配相应的先验概率。
首先
λ
i
\lambda_i
λi是可以取任意正数,是连续分布。指数分布对任意正数都存在一个连续密度函数,因此我们就将该指数分布的参数定义为
α
\alpha
α(超参数/父变量)。
λ
1
∼
E
x
p
(
α
)
λ
2
∼
E
x
p
(
α
)
\lambda_1 \sim Exp(\alpha)\\ \lambda_2 \sim Exp(\alpha)
λ1∼Exp(α)λ2∼Exp(α)
α
\alpha
α对模型的影响应该不会特别大。
1
N
∑
i
=
0
N
λ
i
≈
E
(
λ
∣
α
)
=
1
α
\frac{1}{N}\sum_{i=0}^N\lambda_i \approx E(\lambda|{\alpha}) = \frac{1}{\alpha}
N1i=0∑Nλi≈E(λ∣α)=α1
而对于参数
τ
\tau
τ,由于噪声影响,很难挑选合适的先验证。我们假定每天的先验估计都是一样的。
P
(
τ
=
k
)
=
1
70
,
k
=
1
,
2
,
3...
P(\tau=k)=\frac{1}{70},k=1,2,3...
P(τ=k)=701,k=1,2,3...
由以上的知识比较好求出先验分布。
在这里,
α
=
1
20
。
\alpha=\frac{1}{20}。
α=201。
import pymc as pm
import numpy as np
import matplotlib.pyplot as plt
from IPython.core.pylabtools import figsize
figsize(12.5,10)
plt.title("The Artificial Model")
def plot_dataset():
tau = pm.rdiscrete_uniform(0,80)
N = 80
alpha = 1/20
lambda_1 ,lambda_2 = pm.rexponential(alpha,2)
lambda_ = np.r_[lambda_1*np.ones(tau),lambda_2*np.ones(N-tau)]
data = pm.rpoisson(lambda_)
plt.bar(np.arange(N),data,color = 'blue',label = 'Usual data')
plt.bar(tau-1,data[tau-1],color = 'red',label = 'Changed Point')
plt.xlim(0,80)
plt.xlabel("Days")
plt.ylabel("Received Messages")
plt.legend()
for i in range(4):
plt.subplot(4,1,i+1)
plot_dataset()
plt.show()