前言:在前几次的学习中一直把理论的学习作为重点,由于不熟悉Python,所以更加没有注重实践,直到这次才发现本末倒置,故而这次的学习,注重实践环节,先大致理解原理。
参考:https://www.zhihu.com/question/35866596/answer/236886066
概率图
在概率图模型中数据样本由公式G=(V,E)建模表示(很像图论中的图的表示方法)。
- V表示节点,即随机变量,具体的,用 Y = ( y 1 , y 2 , ⋯ , y n ) Y=(y_1,y_2,\cdots ,y_n) Y=(y1,y2,⋯,yn)为随机变量建模, P ( Y ) P(Y) P(Y)为这些随机变量的概率分布。
- E表示边,即概率依赖关系,具体看后文解释。
有向图与无向图
贝叶斯网络都是有向的,马尔科夫网络无向。所以,==贝叶斯网络适合为有单向依赖的数据建模,而马尔科夫网络适合实体之间相互依赖的建模。==具体地,他们的核心差异表现在如何求
Y
Y
Y的概率分布上。
1.有向图
对于有向图模型,这么求联合概率:
P
(
Y
)
=
∏
i
=
0
P
(
x
i
∣
π
(
x
i
)
)
P(Y)=\prod _{i=0}P(x_i|\pi (x_i))
P(Y)=∏i=0P(xi∣π(xi))
对于上图所表示的随机变量,求他们的联合分布:
P
(
x
1
,
x
2
,
⋯
,
x
n
)
=
P
(
x
1
)
⋅
P
(
x
2
∣
x
1
)
⋅
P
(
x
3
∣
x
2
)
⋅
P
(
x
4
∣
x
2
)
⋅
P
(
x
5
∣
x
3
)
⋅
P
(
x
5
∣
x
4
)
P(x_1,x_2,\cdots,x_n)=P(x_1)\cdot P(x_2|x_1)\cdot P(x_3|x_2)\cdot P(x_4|x_2)\cdot P(x_5|x_3)\cdot P(x_5|x_4)
P(x1,x2,⋯,xn)=P(x1)⋅P(x2∣x1)⋅P(x3∣x2)⋅P(x4∣x2)⋅P(x5∣x3)⋅P(x5∣x4)
2.无向图
对于无向图,一般指马尔科夫网络。
如果一个graph太大,可以用因子分解将
P
(
Y
)
P(Y)
P(Y)写成若干个联合概率分布的乘积。分解是指将一个图分成若干个“小团”,每个“小团”必须是最大团(每个小团任何两个点之间可到达,类似于最大连通子图),则有:
P
(
Y
)
=
1
Z
(
x
)
∏
c
ψ
c
(
Y
c
)
P(Y)=\frac{1}{Z(x)}\prod _{c}\psi _{c}(Y_c)
P(Y)=Z(x)1c∏ψc(Yc),其中
Z
(
x
)
=
∑
Y
∏
c
ψ
(
Y
c
)
Z(x)=\sum _{Y}\prod_{c}\psi (Y_c)
Z(x)=∑Y∏cψ(Yc),归一化是为了让结果算作概率。
所以向上面的无向图:
P
(
Y
)
=
1
Z
(
x
)
(
ψ
1
(
X
1
,
X
3
,
X
4
)
⋅
ψ
2
(
X
2
,
X
3
,
X
4
)
)
P(Y)=\frac{1}{Z(x)}(\psi_1(X_1,X_3,X_4)\cdot \psi_2(X_2,X_3,X_4))
P(Y)=Z(x)1(ψ1(X1,X3,X4)⋅ψ2(X2,X3,X4))其中,
ψ
c
(
Y
c
)
\psi_c(Y_c)
ψc(Yc)是最大团C上随机变量们的联合概率分布,一般取指数函数的:
ψ
c
(
Y
c
)
=
e
−
E
(
Y
c
)
=
e
∑
k
λ
k
f
k
(
c
,
y
∣
c
,
x
)
\psi_c(Y_c)=e^{-E(Y_c)}=e^{\sum_{k}\lambda_kf_k(c,y|c,x)}
ψc(Yc)=e−E(Yc)=e∑kλkfk(c,y∣c,x)这个叫做势函数。
那么概率无向图的联合概率分布在因子分解下可表示为:
P
(
Y
)
=
1
Z
(
x
)
∏
c
ψ
c
(
Y
c
)
=
1
Z
(
x
)
∏
c
e
∑
k
λ
k
f
k
(
c
,
y
∣
c
,
x
)
=
1
Z
(
x
)
e
∑
c
∑
k
λ
k
f
k
(
y
i
,
y
i
−
1
,
x
,
i
)
P(Y)=\frac{1}{Z(x)}\prod_c\psi_c(Y_c)=\frac{1}{Z(x)}\prod_ce^{\sum_k\lambda_kf_k(c,y|c,x)}=\frac{1}{Z(x)}e^{\sum_c\sum_{k}\lambda_kf_k(y_i,y_{i-1},x,i)}
P(Y)=Z(x)1c∏ψc(Yc)=Z(x)1c∏e∑kλkfk(c,y∣c,x)=Z(x)1e∑c∑kλkfk(yi,yi−1,x,i)(这里还不太理解,但继续往下)
马尔科夫假设与马尔科夫性
1.马尔科夫假设
马尔科夫链
(
x
1
,
⋯
,
x
n
)
(x_1,\cdots,x_n)
(x1,⋯,xn)里的
x
i
x_i
xi总是只受
x
i
−
1
x_{i-1}
xi−1的影响。
马尔科夫过程即在一个过程中,每个状态的转移只依赖于前n个状态,并且只是个n阶的模型,最简单的马尔科夫过程是一阶的,即只依赖于其哪一个状态。
2.马尔科夫性
马尔科夫性的内容:当一个随机过程在给定现在状态及所有过去状态情况下,其未来状态的条件概率分布仅依赖于当前状态;换句话说,在给定现在状态时,它与过去状态(即该过程的历史路径)是条件独立的,那么此随机过程即具有马尔可夫性质。具有马尔可夫性质的过程通常称之为马尔可夫过程。(摘自百度百科)
三点:成对,局部,全局(尚不理解)
马尔科夫性是保证或者判断概率图是否为概率无向图的条件。
3.序列建模
连续的序列在分析时也会先离散化处理。
常见的序列有:时序数据,文章句子,语音数据等等
对不同的序列有不同的问题需求,常见的序列建模方法总结如下:
1.拟合,预测未来节点(或走势分析)
a.常规序列建模方法:AR,MA, ARMA, ARIMA模型
b.回归拟合
c.Neural Networks神经网络
2.判断不同序列类别,即分类问题:HMM、CRF、General Classifier
3.不同时序对应的状态分析,即序列标注问题:HMM,CRF,RecurrentNNs
HMM
对于常规的序列数据,一般用马尔科夫模型就可以胜任,但是实际上碰到更多的还是每个节点 X i X_i Xi下还附带着另一个节点 Y i Y_i Yi,即隐含马尔科夫模型,在这种情况下,除了正常的节点,还要将隐含的状态节点也要建模进去。这时,将 X i , Y i X_i,Y_i Xi,Yi记录成 i i , o i i_i,o_i ii,oi,并且它们的名称变为状态节点,观测节点。状态节点是隐含状态。
HMM是典型的生成式模型。是要从训练数据中学到数据的各种分布,那么有哪些分布以及是什莫呢?下面是HMM的五要素,其中有三个是整个数据的不同角度概率分布:
- N,隐藏状态集 N = { q 1 , … , q N } N= \{ q_1,\dots,q_N \} N={q1,…,qN},隐藏节点不能随意取,只能限定取包含在隐藏状态集中的符号。
- M,观测集 M = { v 1 , … , v n } M=\{v_1,\dots,v_n\} M={v1,…,vn},同样,观测节点不能随意取,只能限定取包含在观测节点中的符号。
- A,状态转移概率矩阵,这就是其中一个概率分布。它是个矩阵, A = [ a i j ] N × N A=[a_{ij}]_{N\times N} A=[aij]N×N(N为隐藏状态集元素的个数),其中 a i j = P ( i t + 1 ∣ i t ) a_{ij}=P(i_{t+1}|i_t) aij=P(it+1∣it), i t i_t it即第 i i i个隐状态节点,即所谓的状态转移。
- B,观测概率矩阵,这个就是另一个概率分布。它是个矩阵, B = [ b i j ] N × M B=[b_{ij}]_{N\times M} B=[bij]N×M(N为隐藏状态集元素个数,M为观测集元素个数),其中 b i j = P ( o t ∣ i t ) b_{ij}=P(o_t|i_t) bij=P(ot∣it), o t o_t ot即第 i i i个观测节点, i t i_t it即第 i i i个隐状态节点, b [ i j ] b_[ij] b[ij]即所谓的观测概率(发射概率)嘛。
-
π
\pi
π,在第一个隐状态节点
i
t
i_t
it,我得人工单独赋予,我第一个隐状态节点的隐状态是
N
N
N中的每一个概率分别是多少,然后
π
\pi
π就是其概率分布。
首先,隐状态节点是不能直接观测到的数据点,
o
t
o_t
ot才是能观测到的节点,并且注意箭头的指向表示依赖生成条件关系,
i
t
i_t
it在A的指导下生成下一个隐状态节点
i
t
+
1
i_{t+1}
it+1,并且
i
t
i_t
it在B的指导下生成依赖于该
i
t
i_t
it的观测节点
o
t
o_t
ot,并且我只能观测到序列
(
o
1
,
⋯
,
o
i
)
(o_1,\cdots,o_i)
(o1,⋯,oi)。
举例说明
input:“学习出一个模型,然后再预测出一条指定”
expected output:学/B习/E出/S一/B个/E模/B型/E,/S然/B后/E再/E预/B测/E……
其中,input里面所有char构成的字表,形成观测集M,因为字序列是我在inference阶段能够看见的。标注集BES构成隐藏状态集N,这些是我无法直接获取的,也是我的预测任务。至于
A
,
B
,
π
A ,B,\pi
A,B,π,这些概率分布信息(上帝信息)都是我在学习过程中所获得的参数。
1.根据概率图的分类,HMM属于有向图,并且是生成式模型,直接对联合概率分布建模
P
(
O
,
I
)
=
∑
t
=
1
T
P
(
O
t
∣
O
t
−
1
)
P
(
I
t
∣
O
t
)
P(O,I)=\sum_{t=1}^{T}P(O_t|O_{t-1})P(I_t|O_t)
P(O,I)=∑t=1TP(Ot∣Ot−1)P(It∣Ot) (注意,这个公式不在模型运行的任何阶段能体现出来,只是我们都去这么来表示HMM是个生成式模型,他的联合概率
P
(
O
,
I
)
P(O,I)
P(O,I)就是这麽计算出来的。
2.并且在B中
b
i
j
=
P
(
o
t
∣
i
t
)
b_{ij}=P(o_t|i_t)
bij=P(ot∣it)这就意味着o对i有依赖性。
3.在A中,
a
i
j
=
P
(
i
t
+
1
∣
i
t
)
a_{ij}=P(i_{t+1}|i_t)
aij=P(it+1∣it),也就是说只遵循了一阶马尔科夫假设,1-gram。试想,如果数据的依赖超过1-gram,那肯定HMM肯定是考虑不进去的。这一点限制了HMM的性能。
模型运行过程
模型的运行过程(工作流程)对应了HMM的3个问题
1.学习训练过程
HMM的学习训练过程,就是找出数据的分布情况,也就是模型参数的确定。
主要学习算法按照训练数据除了观测状态序列
(
o
1
,
⋯
,
o
i
)
(o_1,\cdots,o_i)
(o1,⋯,oi)是否还有隐状态序列
(
i
1
,
⋯
,
i
i
)
(i_1,\cdots,i_i)
(i1,⋯,ii)分为:
- 极大似然估计,含有隐状态序列。
- Baum-Welch(前向后向算法),无隐状态序列。
简要介绍一下:
- 极大似然估计
一般做NLP的序列标注任务,在训练阶段肯定有隐状态序列,所以极大似然估计法是非常常用的算法。
- step1.算A
a ^ i j = A i j ∑ j = 1 M A i j \hat{a}_{ij}=\frac{A_{ij}}{\sum_{j=1}^{M}A_{ij}} a^ij=∑j=1MAijAij - step2.算B
b ^ j ( k ) = B j k ∑ j = 1 M B j k \hat{b}_{j}(k)=\frac{B_{jk}}{\sum_{j=1}^{M}B_{jk}} b^j(k)=∑j=1MBjkBjk - step3.直接估计 π \pi π
- 前向后向算法
其实是一个EM的过程。
因为我们手中没有隐状态序列 ( i 1 , ⋯ , i i ) (i_1,\cdots,i_i) (i1,⋯,ii)的信息,所以我先必须给初值 a i j 0 , b j 0 ( k ) , π 0 a_{ij}^{0},b_{j}^{0}(k),\pi^{0} aij0,bj0(k),π0,初步确立模型,然后在迭代计算出 a i j n , b j n ( k ) , π n a_{ij}^{n},b_{j}^{n}(k),\pi^{n} aijn,bjn(k),πn,中间计算过程会用到给出的观测状态序列 ( o 1 , ⋯ , o i ) (o_1,\cdots,o_i) (o1,⋯,oi)。
2.序列标注(解码)过程
学习完了HMM的分布参数,也就确定了一个HMM模型。需要注意的是,这个HMM是对我这一批全部的数据进行训练所得到的参数。
序列标注问题也就是预测过程,通常称为解码过程。对应了序列建模的问题3,不同时序进行的状态分析。对于序列标注问题,我们只需要学习出以后一个HMM模型即可。
我们要在给定的观测序列下找出一条隐状态序列,条件是这个隐状态序列必须是最有可能的那个(概率最大的)
在学习过程之后我们已知了
P
(
Q
,
O
)
P(Q,O)
P(Q,O),现在要求出
P
(
Q
∣
O
)
P(Q|O)
P(Q∣O),
Q
m
a
x
=
a
r
g
m
a
x
a
l
l
Q
P
(
Q
,
O
)
P
(
O
)
Q_{max}=argmax_{allQ}\frac{P(Q,O)}{P(O)}
Qmax=argmaxallQP(O)P(Q,O)
具体地,都是用Viterbi算法
解码,是用DP思想减少重复的计算。Viterbi不是HMM的专属,也不是任何模型的专属,他只是恰好被满足了被HMM用来使用的条件。
3.序列概率过程
我通过HMM计算出序列的概率又有什么用?针对这个点我把这个问题详细说一下。 实际上,序列概率过程对应了序列建模问题2.,即序列分类。在序列标注问题中,我用一批完整的数据训练出了一支HMM模型即可。好,那在序列分类问题就不是训练一个HMM模型了。我应该这么做(结合语音分类识别例子):
目标:识别声音是A发出的还是B发出的。
HMM建模过程:
- 训练:我将所有A说的语音数据作为dataset_A,将所有B说的语音数据作为dataset_B(当然,先要分别对dataset A ,B做预处理encode为元数据节点,形成sequences),然后分别用dataset_A、dataset_B去训练出HMM_A/HMM_B
- inference:来了一条新的sample(sequence),我不知道是A的还是B的,没问题,分别用HMM_A/HMM_B计算一遍序列的概率得到 ,比较两者大小,哪个概率大说明哪个更合理,更大概率作为目标类别。所以,本小节的理解重点在于,如何对一条序列计算其整体的概率。即目标是计算出 P ( O ∣ λ ) P(O|\lambda) P(O∣λ) 。这个问题前辈们在他们的经典中说的非常好了,比如参考李航老师整理的:
- 直接计算法(穷举搜索)
- 前向算法
- 后向算法
后面两个算法采用了DP思想,减少计算量,即每一次直接引用前一个时刻的计算结果以避免重复计算,跟Viterbi一样的技巧。