机器学习之隐马尔科夫模型(HMM)
- 1、隐马尔科夫模型介绍
- 2、隐马尔科夫数学原理
- 3、Python代码实现隐马尔科夫模型
- 4、总结
隐马尔可夫模型介绍
马尔科夫模型(hidden Markov model,HMM)是关于时序的概率模型,描述由一个隐藏的马尔科夫随机生成不可观测的状态随机序列,再由各个状态生成一个观测从而产生观测随机序列的过程,属于一个生成模型。
下面我们来从概率学角度定义马尔科夫模型,从一个典型例子开始:
假设有4个盒子,每个盒子里面有不同数量的红、白两种颜色的球,具体如下表:
盒子编号 | 1 | 2 | 3 | 4 |
---|---|---|---|---|
红球数 | 5 | 3 | 6 | 8 |
白球数 | 5 | 7 | 4 | 2 |
现在从这些盒子中取出T个球,取样规则为每次选择一个盒子取出一个球,记录其颜色,放回。在这个过程中,我们只能观测到球的颜色的序列,观测不到球是从哪个盒子中取出来的,即观测不到盒子的序列,这里有两个随机序列,一个是盒子的序列(状态序列),一个是球的颜色的观测序列(观测序列),前者是隐藏的,只有后者是可观测的。这里就构成了一个马尔科夫的例子。
定义 Q \mathbf{Q} Q是所有的可能的状态集合,V是所有的可能的观测的集合:
Q = { q 1 , q 2 , ⋯ , q N } , V = { v 1 , v 2 , ⋯ , v M } Q = \{q_1,q_2,\cdots,q_N\}, V = \{v_1,v_2,\cdots,v_M\} Q={
q1,q2,⋯,qN}, V={
v1,v2,⋯,vM}
其中,N是可能的状态数,M是可能的观测数,例如上例中N=4,M=2。
I \mathbf{I} I是长度为T的状态序列, O \mathbf{O} O是对应的观测序列:
I = ( i 1 , i 2 , ⋯ , i T ) , O = ( o 1 , o 2 , ⋯ , o T ) I = (i_1,i_2,\cdots,i_T), O = (o_1,o_2,\cdots,o_T) I=(i1,i2,⋯,iT), O=(o1,o2,⋯,oT)
A是状态转移概率矩阵:
A = [ a i , j ] N × N A = [a_{i,j}]_{N \times N} A=[ai,j]N×N
其中, a i , j = P ( i t + 1 = q j ∣ i t = q i ) , i = 1 , 2 , ⋯ , N ; j = 1 , 2 , ⋯ , N a_{i,j} = P(i_{t+1} = q_j|i_t = q_i), i=1,2,\cdots,N;j=1,2,\cdots,N ai,j=P(it+1=qj∣it=qi), i=1,2,⋯,N;j=1,2,⋯,N 是指在时刻 t t t处于状态 q i q_i qi的条件下在时刻 t + 1 t+1 t+1转移到状态 q j q_j qj的概率。
B是观测概率矩阵:
B = [ b j ( k ) ] N × M B = [b_j(k)]_{N \times M} B=[bj(k)]N×M
其中, 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,\cdots,M;j=1,2,\cdots,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的概率。
π \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,\cdots,N πi=P(i1=qi), i=1,2,⋯,N 是指在时刻 t t t=1处于状态 q i q_i qi的概率。
由此可得到,隐马尔可夫模型 λ \lambda λ的三元符号表示,即
λ = ( A , B , π ) \lambda = (A,B,\pi) λ=(A,B,π)
A , B , π A,B,\pi A,B,π称为隐马尔可夫模型的三要素。
由定义可知隐马尔可夫模型做了两个基本假设:
(1)齐次马尔科夫性假设,即假设隐藏的马尔科夫链在任意时刻 t t t的状态只和 t t t-1状态有关;
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},\cdots,i_1,o_1) = P(i_t|i_{t-1}), t=1,2,\cdots,T P(it∣it−1,ot−1,⋯,i1,o1)=P(it∣it−1), t=1,2,⋯,T
(2)观测独立性假设,观测只和当前时刻状态有关;
P ( o t ∣ i T , i T − 1 , o T − 1 , ⋯ , i t + 1 , o t + 1 , i t , i t − 1 , o t − 1 , ⋯ , i 1 , o 1 ) = P ( O t ∣ i t ) P(o_t|i_T,i_{T-1},o_{T-1},\cdots,i_{t+1},o_{t+1},i_t,i_{t-1},o_{t-1},\cdots,i_1,o_1) = P(O_t|i_t) P(ot∣iT,iT−1,oT−1,⋯,it+1,ot+1,it,it−1,ot−1,⋯,i1,o1)=P(Ot∣it)
仍以上面的盒子取球为例,假设我们定义盒子和球模型:
-
状态集合: Q Q Q = {盒子1,盒子2,盒子3,盒子4}, N=4
-
观测集合: V V V = {红球,白球} M=2
-
初始化概率分布:
π = ( 0.25 , 0.25 , 0.25 , 0.25 ) T \pi = (0.25,0.25,0.25,0.25)^T π=(0.25,0.25,0.25,0.25)T -
状态转移矩阵:
A = [ 0 1 0 0 0.4 0 0.6 0 0 0.4 0 0.6 0 0 0.5 0.5 ] A = \left[ \begin{matrix} 0 & 1 & 0 & 0 \\ 0.4 & 0 & 0.6 & 0 \\ 0 & 0.4 & 0 & 0.6 \\ 0 & 0 & 0.5 & 0.5 \end{matrix} \right] A=⎣⎢⎢⎡00.400100.4000.600.5000.60.5⎦⎥⎥⎤ -
观测矩阵:
B = [ 0.5 0.5 0.3 0.7 0.6 0.4 0.8 0.2 ] B = \left[ \begin{matrix} 0.5 & 0.5 \\ 0.3 & 0.7 \\ 0.6 & 0.4 \\ 0.8 & 0.2 \end{matrix} \right] B=⎣⎢⎢⎡0.50.30.60.80.50.70.40.2⎦⎥⎥⎤
隐马尔可夫模型的三个基本问题
-
1、概率计算问题
给定: λ = ( A , B , π ) O = ( o 1 , o 2 , ⋯ , o T ) \lambda = (A,B,\pi) O=(o_1,o_2,\cdots,o_T) λ=(A,B,π) O=(o1,o2,⋯,oT)
计算: P ( O ∣ λ ) P(O|\lambda) P(O∣λ)
-
2、学习问题
已知: O = ( o 1 , o 2 , ⋯ , o T ) O=(o_1,o_2,\cdots,o_T) O=(o1,o2,⋯,oT)
估计: λ = ( A , B , π ) \lambda = (A,B,\pi) λ=(A,B,π),使 P ( O ∣ λ ) P(O|\lambda) P(O∣λ)最大
-
3、预测问题(解码)
已知: λ = ( A , B , π ) O = ( o 1 , o 2 , ⋯ , o T ) \lambda = (A,B,\pi) O=(o_1,o_2,\cdots,o_T) λ=(A,B,π) O=(o1,o2,⋯,oT)
求:使 P ( I ∣ O ) P(I|O) P(I∣O)最大的状态序列 I = ( i 1 , i 2 , ⋯ , i T ) I=(i_1,i_2,\cdots,i_T) I=(i1,i2,⋯,iT)
下面我们使用python代码写一个HMM模型生成序列 O O O的示例代码
import numpy as np
class HMM(object):
def __init__(self, N, M, pi=None, A=None, B=None):
self.N = N
self.M = M
self.pi = pi
self.A = A
self.B = B
def get_data_with_distribute(self, dist): # 根据给定的概率分布随机返回数据(索引)
r = np.random.rand()
for i, p in enumerate(dist):
if r < p: return i
r -= p
def generate(self, T: int):
'''
根据给定的参数生成观测序列
T: 指定要生成观测序列的长度
'''
result = []
for ind in range(T): # 依次生成状态和观测数据
if ind==0:
i = self.get_data_with_distribute(self.pi)
else:
i = self.get_data_with_distribute(self.A[i])
o = self.get_data_with_distribute(self.B[i])
result.append(o)
return result
if __name__ == "__main__":
pi = np.array([0.25, 0.25, 0.25, 0.25])
A = np.array([
[0, 1, 0, 0],
[0.4, 0, 0.6, 0],
[0, 0.4, 0, 0.6],
[0, 0, 0.5, 0.5]])
B = np.array([
[0.5, 0.5],
[0.3, 0.7],
[0.6, 0.4],
[0.8, 0.2]])
hmm = HMM(4, 2, pi, A, B)
print(hmm.generate(10)) # 生成10个数据
# 生成结果如下
[0, 0, 0, 0, 1, 1, 1, 1, 0, 0] # 0代表红球,1代表白球
隐马尔可夫模型数学原理
下面我们从隐马尔可夫模型的三个基本问题出发,逐个解释问题解法:
-
1、概率计算问题
- 直接计算法
- 前向算法
- 后向算法
直接计算法:
-
状态序列 I = ( i 1 , i 2 , ⋯ , i T ) I=(i_1,i_2,\cdots,i_T) I=(i1,i2,⋯,iT)概率: P ( I ∣ λ ) = π i 1 a i 1 i 2 a i 2 i 3 ⋯ a i T − 1 i T P(I|\lambda)=\pi_{i_1} a_{i_1 i_2} a_{i_2 i_3}\cdots a_{i_{T-1}i_T} P(I∣λ)=πi1ai1i2ai2i3⋯aiT−1iT
-
对固定的状态序列 I I I,观测序列 O O O的概率: P ( O ∣ I , λ ) P(O|I,\lambda) P(O∣I,λ)
P ( O ∣ I , λ ) = b i 1 ( o 1 ) b i 2 ( o 2 ) ⋯ b i T ( o T ) P(O|I,\lambda) = b_{i_1}(o_1) b_{i_2}(o_2) \cdots b_{i_T}(o_T) P(O∣I,λ)=bi1(o1)bi2(o2)⋯biT(oT) -
O O O和 I I I同时出现的联合概率为:
P ( O , I ∣ λ ) = P ( O ∣ I , λ ) P ( I ∣ λ ) = π i 1 b i 1 ( o 1 ) a i 1 i 2 b i 2 ( o 2 ) ⋯ a i T − 1 i T b i T ( o T ) P(O,I|\lambda) = P(O|I,\lambda)P(I|\lambda) = \pi_{i_1}b_{i_1}(o_1)a_{i_1 i_2} b_{i_2}(o_2) \cdots a_{i_{T-1}i_T}b_{i_T}(o_T) P(O,I∣λ)=P(O∣I,λ)P(I∣λ)=πi1bi1(o1)ai1i2bi2(o2)⋯aiT−1iTbiT(oT) -
对所有的可能的状态序列 I I I求和,得到观测序列 O O O的概率:
P ( O ∣ π ) = ∑ I P ( O ∣ i , λ ) P ( I ∣ λ ) = ∑ i 1 , i 2 , ⋯ , i T π i 1 b i 1 ( o 1 ) a i 1 i 2 b i 2 ( o 2 ) ⋯ a i T − 1 i T b i T ( o T ) P(O|\pi) = \sum_I{P(O|i,\lambda)P(I|\lambda)} = \sum_{i_1,i_2,\cdots,i_T}\pi_{i_1}b_{i_1}(o_1)a_{i_1 i_2} b_{i_2}(o_2) \cdots a_{i_{T-1}i_T}b_{i_T}(o_T) P(O∣π)=I∑P(O∣i,λ)P(I∣λ)=i1,i2,⋯,iT∑πi1bi1(o1)ai1i2bi2(o2)⋯aiT−1iTbiT(oT)此算法的复杂度为 O ( T N T ) O(TN^T) O(TNT),计算量太大,不可行。
前向算法:
-
前向概率定义:给定隐马尔科夫模型 λ \lambda λ,定义到时刻t部分观测序列为: o 1 , o 2 , ⋯ , o t o_1,o_2,\cdots,o_t o1,o2,⋯,ot,且状态为 q i q_i qi的概率为前向概率,记作:
α t ( i ) = P ( o 1 , o 2 , ⋯ , o t , i t = q t ∣ λ ) \alpha_t(i) = P(o_1,o_2,\cdots,o_t,i_t=q_t|\lambda) αt(i)=P(o1,o2,⋯,ot,it=qt∣λ)
输入:隐马尔可夫模型 λ \lambda λ,观测序列 O O O;输出:观测序列概率 P ( O ∣ λ ) P(O|\lambda) P(O∣λ)
初值: α 1 ( i ) =