###隐马尔可夫模型的定义
隐马尔可夫模型是关于时序的概率模型,描述由一个隐藏的马尔可夫链随机生成不可观测的状态随机序列,再由各个状态生成一个观测而产生观测随机序列的过程。
隐马尔可夫链随机生成的状态的序列,称为状态序列(state sequence);每个状态生成一个观测,而由此产生的观测的随机序列,称为观测序列(observation sequence)。序列的每一个位置又可以看作是一个时刻。
设Q是所有可能的状态的集合,V是所有可能的观测的集合。
Q = { q 1 , q 2 , . . . q N } , V = { v 1 , v 2 , . . . v M } Q = \{q_1,q_2,...q_N\}, V = \{v_1,v_2,...v_M\} Q={q1,q2,...qN},V={v1,v2,...vM}
其中, N N N是可能的状态数, M M M是可能的观测数。状态 q q q是不可见的,观测 v v v是可见的。应用到词性标注系统,词就是 v v v,词性就是 q q q。应用到语音识别系统,语音就是 v v v,语素就是 q q q。
I I I是长度为 T T T的状态序列, O O O是对应的观测序列。
I = { i 1 , i 2 , . . . i T } , O = { o 1 , o 2 , . . . o T } I = \{i_1,i_2,...i_T\}, O = \{o_1,o_2,...o_T\} I={i1,i2,...iT},O={o1,o2,...oT}
这可以理解为给定了一个词(O)+词性(I)的训练集,于是我们手上有了一个可以用隐马尔可夫模型解决的实际问题。
A为状态转移概率矩阵:
A = [ a i j ] N ∗ N A = [a_{ij}]_{N*N} A=[aij]N∗N
其中, a i j = P ( i t + 1 = q j ∣ i t = q i ) , i = 1 , 2... , N ; j = 1 , 2 , . . . N a_{ij}= P(i_t+1 = q_j|i_t = q_i), i = 1,2...,N; j = 1,2,...N aij=P(it+1=qj∣it=qi),i=1,2...,N;j=1,2,...N
是在时刻 t t t处于状态 q j q_j qj的条件下在时刻t+1转移到状态 q j q_j qj的概率。
这实际在表述一个一阶的HMM,所作的假设是每个状态只跟前一个状态有关。
B是观测概率矩阵:
B = [ b j ( k ) ] N ∗ N B = [b_j(k)]_{N*N} B=[bj(k)]N∗N
其中, b j ( k ) = P ( o t = v k ∣ i t = q j ) , k = 1 , 2... , M ; j = 1 , 2 , . . . N b_j(k)= P(o_t = v_k|i_t = q_j), k = 1,2...,M; j = 1,2,...N bj(k)=P(ot=vk∣it=qj),k=1,2...,M;j=1,2,...N 是在时刻 t t t处于状态 q j q_j qj的条件下生成观测 v k v_k vk的概率,也就是所谓的“发射概率”。
这实际上在作另一个假设,观测是由当前时刻的状态决定的,跟其他因素无关,这有点像Moore自动机。
π \pi π是初始状态概率向量:
π = ( π i ) \pi = (\pi_i) π=(πi)
其中, π i = P ( i 1 = q i ) , i = 1 , 2 , . . . N \pi_i= P(i_1 = q_i), i= 1,2,...N πi=P(i1=qi),i=1,2,...N 是时刻t=1处于状态 q j q_j qj的概率。
隐马尔可夫模型由初始状态概率向量 π \pi π、状态转移概率矩阵 A A A和观测概率矩阵 B B B决定。 π \pi π和 A A A决定状态序列, B B B决定观测序列。因此,隐马尔可夫模型 λ \lambda λ可以用三元符号表示,即
λ = ( A , B , π ) \lambda = (A,B,\pi) λ=(A,B,π)
A , B , π A,B,\pi A,B,π称为隐马尔可夫模型的三要素。
状态转移概率矩阵 A A A与初始状态概率向量 π π π确定了隐藏的马尔可夫链,生成不可观测的状态序列。观测概率矩阵B确定了如何从状态生成观测,与状态序列综合确定了如何产生观测序列。
从定义可知,隐马尔可夫模型作了两个基本假设:
(1)齐次马尔可夫性假设,即假设隐藏的马尔可夫链在任意时刻t的状态只依赖于其前一时刻的状态,与其他时刻的状态及观测无关。
P ( i t ∣ i t − 1 , o t − 1 , . . . i 1 , o 1 ) = P ( i t ∣ i t − 1 ) , t = 1 , 2 , . . . T P(i_t|i_t-1,o_t-1,...i_1,o_1 ) = P(i_t|i_t-1), t = 1,2,...T P(it∣it−1,ot−1,...i1,o1)=P(it∣it−1),t=1,2,...T
从上式左右两边的复杂程度来看,齐次马尔可夫性假设简化了许多计算。
(2)观测独立性假设,即假设任意时刻的观测只依赖于该时刻的马尔可夫链的状态,与其他观测及状态无关。
P ( o t ∣ i T , o T , i T − 1 , o T − 1 , . . . i t , o t , . . . i 1 , o 1 ) = P ( i t ∣ o t ) P(o_t|i_T,o_T,i_T-1,o_T-1,...i_t,o_t,...i_1,o_1 ) = P(i_t|o_t) P(ot∣iT,oT,iT−1,oT−1,...it,ot,...i1,o1)=P(it∣ot)
隐马尔可夫模型有3类基本问题:
(1)概率计算
给定模型 λ = ( A , B , π ) \lambda = (A,B,\pi) λ=(A,B,π) 和观测序列 O = ( o 1 , o 2 , . . . o T ) O = (o_1,o_2,...o_T) O=(o1,o2,...oT),计算在观测序列O出现的概率 P = ( O ∣ λ ) P = (O|\lambda) P=(O∣λ)。
(2)学习问题
己知观测序列 O = ( o 1 , o 2 , . . . o T ) O = (o_1,o_2,...o_T) O=(o1,o2,...oT),估计模型参数 λ = ( A , B , π ) \lambda = (A,B,\pi) λ=(A,B,π),使得在该模型下观测序列概率 P = ( O ∣ λ ) P = (O|\lambda) P=(O∣λ)最大。即用极大似然估计的方法估计参数。
(3)预测问题
也称为解码问题(decoding)。已知模型 λ = ( A , B , π ) \lambda = (A,B,\pi) λ=(A,B,π)和观测序列 O = ( o 1 , o 2 , . . . o T ) O = (o_1,o_2,...o_T) O=(o1,o2,...oT),求对给定观测序列条件概率 P = ( O ∣ λ ) P = (O|\lambda) P=(O∣λ)最大的状态序列 I = ( i 1 , i 2 , . . . i T ) I = (i_1,i_2,...i_T) I=(i1,i2,...iT)。即给定观测序列,求最有可能的对应的状态序列。
概率计算方法
给定模型 λ = ( A , B , π ) \lambda = (A,B,\pi) λ=(A,B,π) 和观测序列 O = ( o 1 , o 2 , . . . o T ) O = (o_1,o_2,...o_T) O=(o1,o2,...oT),,求 P = ( O ∣ λ ) P = (O|\lambda) P=(O∣λ)
直接计算法
直接计算法的思路是枚举所有长度 T T T的状态序列,然后计算该状态序列与观测序列的联合概率,对所有的枚举项求和即可。在状态种类为N的情况下,一共有 N T N^T NT种排列,每种排列计算联合概率的计算量为 T T T,总的复杂度为 O ( T ∗ N T ) O(T*N^T) O(T∗NT)。
直接计算法只是一种理论方法,可以用来解释整个计算过程,而不会被用于计算。因为只需做简单的改进,就能很大程度上地减少运算量。这些改进,只是用到了合并同类项的思想。直接计算法在状态种类为N的情况下,一共有 N T N^T NT种排列。这 N T N^T NT种排列并不都需要从0开始计算,而是可以利用已经计算的结果,减少运算量。这就有了前向算法和后向算法。
假设长度为3的序列,一共有2种状态,分别为A,B。序列AAA和AAB,用直接计算法,这里需要4次乘法。而如果利用AA这个已有状态的结果,再分别计算AAA和AAB,则只有3次乘法。这就是前向和后向算法的基础。
前向算法
给定隐马尔可夫模型 λ \lambda λ,定义到时刻 t t t为止的观测序列为 o 1 , o 2 . . . o t o_1,o_2...o_t o1,o2...ot,且状态为 q t q_t qt的概率为前向概率,记作
α t ( i ) = P ( o 1 , o 2 . . . , o t , i t = q t ∣ λ ) \alpha_t(i) = P(o_1,o_2...,o_t, i_t = q_t | \lambda) αt(i)=P(o1,o2...,ot,it=qt∣λ)
(1) 初始状态, t = 0 t = 0 t=0时刻
α 1 ( i ) = π i b i ( o 1 ) , i = 1 , 2 , . . . N \alpha_1(i) = \pi_ib_i(o_1), i = 1,2,...N α1(i)=πibi(o1),i=1,2,...N
初始状态有N种可能,所以这个概率有N个。
前向概率的定义限定了两个条件,一是到当前为止的观测序列,另一个是当前的状态。所以初值的计算也有两项,一项是初始状态概率,另一项是发射到当前观测的概率。
(2) t = 2 , 3 , . . . T − 1 t = 2,3,... T-1 t=2,3,...T−1时刻
α t + 1 ( i ) = [ ∑ j = 1 N α t ( j ) a j i ] ∗ b i ( o t + 1 ) , i = 1 , 2 , . . . N \alpha_{t+1}(i) = [\sum_{j=1}^N \alpha_t(j) a_{ji}] *b_i(o_{t+1}), i = 1,2,...N αt+1(i)=[j=1∑Nαt(j)aji]∗bi(ot+1),i=1,2,...N
整个计算过程分两部分,第一部分是到当前状态转移概率,第二部分是到观测序列的发射概率。
α t ( j ) \alpha_t(j) αt(j)表示t时刻的概率,一共有 N N N项。 j j j表示t时刻的状态,而 i i i表示 t + 1 t+1 t+1时刻的状态,所以 j = 1 , 2 , . . . N j=1,2,...N j=1,2,...N, i = 1 , 2 , . . . N i=1,2,...N i=1,2,...N。那么从状态 j j j到状态 i i i,需要计算 N 2 N^2 N2次。如果这个状态序列有 T T T时刻,则复杂度为 O ( T N 2 ) O(TN^2) O(TN2),远小于直接计算法的 O ( T N T ) O(TN^T) O(TNT)。
(3)最终状态 t = T t =T t=T时刻
p ( O ∣ λ ) = ∑ i = 1 N α T ( i ) p(O|\lambda) = \sum_{i=1}^N\alpha_T(i) p(O∣λ)=i=1∑NαT(i)
从 t = T − 1 t = T-1 t=T−1 到 t = T t = T t=T,一共有 N N N种状态可以到达目标状态,需要求和
参考代码如下。 N N N表示状态数, T T T是时间数, A A A是转移矩阵, B B B是发射矩阵, F F F对应 α \alpha α。
def _forward(self, obs_seq):
N = self.A.shape[0]
T = len(obs_seq)
F = np.zeros((N,T))
F[:,0] = self.pi * self.B[:, obs_seq[0]]
for t in range(1, T):
for n in range(N):
F[n,t] = np.dot(F[:,t-1], (self.A[:,n])) * self.B[n, obs_seq[t]]
return F
后向算法
给定隐马尔可夫模型 λ \lambda λ,定义时刻 t t t的状态为 q t q_t qt,且从时刻 t + 1 t+1 t+1到时刻 T T T为止的观测序列为 o t + 1 , o t + 2 . . . o T o_{t+1},o_{t+2}...o_T ot+1,ot+2...oT的概率为后向概率,记作
β t ( i ) = P ( o t + 1 , o t + 2 . . . , o T ∣ i t = q t , λ ) \beta_t(i) = P(o_{t+1},o_{t+2}...,o_T | i_t = q_t , \lambda) βt(i)=P(ot+1,ot+2...,oT∣it=qt,λ)
(1) 初始状态, t t t = T T T时刻
β 1 ( i ) = 1 , i = 1 , 2 , . . . N \beta_1(i) = 1, i = 1,2,...N β1(i)=1,i=1,2,...N
因为从 t = T + 1 t = T+1 t=T+1时刻到 t = T t = T t=T 时刻的概率并不存在,默认为1.
(2) t = T − 1 , T − 2...2 , 1 t = T-1, T-2... 2,1 t=T−1,T−2...2,1 时刻
β t ( i ) = ∑ j = 1 N β t + 1 ( j ) ∗ b j ( O t + 1 ) ∗ a j i , i = 1 , 2 , . . . N \beta_t(i) = \sum_{j=1} ^N \beta_{t+1}(j) * b_j(O_{t+1}) * a_{ji}, i = 1,2,...N βt(i)=j=1∑Nβt+1(j)∗bj(Ot+1)∗aji,i=1,2,...N
(3) 最终状态, t = 0 t = 0 t=0 时刻
p ( O ∣ λ ) = ∑ i = 1 N β 1 ( i ) ∗ b i ( O 1 ) ∗ a j i p(O|\lambda) = \sum_{i = 1}^N \beta_1(i) * b_i(O_1) * a_{ji} p(O∣λ)=i=1∑Nβ1(i)∗bi(O1)∗aji
在 t t t= 1时间点上有 N N N种后向概率都能输出从 1 1 1到 T T T的观测序列,乘以对应的初始概率,再乘以输出 O 1 O1 O1的概率后,求和得到最终结果
参考代码如下。 N N N表示状态数, T T T是时间数, A A A是转移矩阵, B B B是发射矩阵, X X X对应 β \beta β。注意这里求和方式与前向方法的区别。前向算法里面发射概率是当前层的下标 i i i,后向算法里发射概率是后一层的下标 j j j。前向算法求和符号不包括发射概率,而后项算法的求和概率包括了发射概率。
def _backward(self, obs_seq):
N = self.A.shape[0]
T = len(obs_seq)
X = np.zeros((N,T))
X[:,-1:] = 1
for t in reversed(range(T-1)):
for n in range(N):
X[n,t] = np.sum(X[:,t+1] * self.A[n,:] * self.B[:, obs_seq[t+1]])
return X
来源:oschina
链接:https://my.oschina.net/u/4301949/blog/3216466