Python实现隐马尔可夫模型的前向后向算法的示例代码
本篇文章对隐马尔可夫模型的前向和后向算法进行了Python实现,并且每种算法都给出了循环和递归两种方式的实现。
前向算法Python实现
循环方式
importnumpyasnp
defhmm_forward(Q,V,A,B,pi,T,O,p):
"""
:paramQ:状态集合
:paramV:观测集合
:paramA:状态转移概率矩阵
:paramB:观测概率矩阵
:parampi:初始概率分布
:paramT:观测序列和状态序列的长度
:paramO:观测序列
:paramp:存储各个状态的前向概率的列表,初始为空
"""
fortinrange(T):
#计算初值
ift==0:
foriinrange(len(Q)):
p.append(pi[i]*B[i,V[O[0]]])
#初值计算完毕后,进行下一时刻的递推运算
else:
alpha_t_=0
alpha_t_t=[]
foriinrange(len(Q)):
forjinrange(len(Q)):
alpha_t_+=p[j]*A[j,i]
alpha_t_t.append(alpha_t_*B[i,V[O[t]]])
alpha_t_=0
p=alpha_t_t
returnsum(p)
#《统计学习方法》书上例10.2
Q=[1,2,3]
V={'红':0,'白':1}
A=np.array([[0.5,0.2,0.3],[0.3,0.5,0.2],[0.2,0.3,0.5]])
B=np.array([[0.5,0.5],[0.4,0.6],[0.7,0.3]])
pi=[0.2,0.4,0.4]
T=3
O=['红','白','红']
p=[]
print(hmm_forward(Q,V,A,B,pi,T,O,p))#0.130218
递归方式
importnumpyasnp
defhmm_forward_(Q,V,A,B,pi,T,O,p,T_final):
"""
:paramT_final:递归的终止条件
"""
ifT==0:
foriinrange(len(Q)):
p.append(pi[i]*B[i,V[O[0]]])
else:
alpha_t_=0
alpha_t_t=[]
foriinrange(len(Q)):
forjinrange(len(Q)):
alpha_t_+=p[j]*A[j,i]
alpha_t_t.append(alpha_t_*B[i,V[O[T]]])
alpha_t_=0
p=alpha_t_t
ifT>=T_final:
returnsum(p)
returnhmm_forward_(Q,V,A,B,pi,T+1,O,p,T_final)
Q=[1,2,3]
V={'红':0,'白':1}
A=np.array([[0.5,0.2,0.3],[0.3,0.5,0.2],[0.2,0.3,0.5]])
B=np.array([[0.5,0.5],[0.4,0.6],[0.7,0.3]])
pi=[0.2,0.4,0.4]
T=0
O=['红','白','红']
p=[]
T_final=2#T的长度是3,T的取值是(0时刻,1时刻,2时刻)
print(hmm_forward_(Q,V,A,B,pi,T,O,p,T_final))
后向算法Python实现
循环方式
importnumpyasnp
defhmm_backward(Q,V,A,B,pi,T,O,beta_t,T_final):
fortinrange(T,-1,-1):
ift==T_final:
beta_t=beta_t
else:
beta_t_=0
beta_t_t=[]
foriinrange(len(Q)):
forjinrange(len(Q)):
beta_t_+=A[i,j]*B[j,V[O[t+1]]]*beta_t[j]
beta_t_t.append(beta_t_)
beta_t_=0
beta_t=beta_t_t
ift==0:
p=[]
foriinrange(len(Q)):
p.append(pi[i]*B[i,V[O[0]]]*beta_t[i])
beta_t=p
returnsum(beta_t)
#《统计学习方法》课后题10.1
Q=[1,2,3]
V={'红':0,'白':1}
A=np.array([[0.5,0.2,0.3],[0.3,0.5,0.2],[0.2,0.3,0.5]])
B=np.array([[0.5,0.5],[0.4,0.6],[0.7,0.3]])
pi=[0.2,0.4,0.4]
T=3
O=['红','白','红','白']
beta_t=[1,1,1]
T_final=3
print(hmm_backward_(Q,V,A,B,pi,T,O,beta_t,T_final))#0.06009
递归方式
importnumpyasnp
defhmm_backward(Q,V,A,B,pi,T,O,beta_t,T_final):
ifT==T_final:
beta_t=beta_t
else:
beta_t_=0
beta_t_t=[]
foriinrange(len(Q)):
forjinrange(len(Q)):
beta_t_+=A[i,j]*B[j,V[O[T+1]]]*beta_t[j]
beta_t_t.append(beta_t_)
beta_t_=0
beta_t=beta_t_t
ifT==0:
p=[]
foriinrange(len(Q)):
p.append(pi[i]*B[i,V[O[0]]]*beta_t[i])
beta_t=p
returnsum(beta_t)
returnhmm_backward(Q,V,A,B,pi,T-1,O,beta_t,T_final)
jpgQ=[1,2,3]
V={'红':0,'白':1}
A=np.array([[0.5,0.2,0.3],[0.3,0.5,0.2],[0.2,0.3,0.5]])
B=np.array([[0.5,0.5],[0.4,0.6],[0.7,0.3]])
pi=[0.2,0.4,0.4]
T=3
O=['红','白','红','白']
beta_t=[1,1,1]
T_final=3
print(hmm_backward_(Q,V,A,B,pi,T,O,beta_t,T_final))#0.06009
这里我有个问题不理解,这道题的正确答案应该是0.061328,我计算出的答案和实际有一点偏差,我跟踪了代码的计算过程,发现在第一次循环完成后,计算结果是正确的,第二次循环后的结果就出现了偏差,我怀疑是小数部分的精度造成,希望有人能给出一个更好的解答,如果是代码的问题也欢迎指正。
以上所述是小编给大家介绍的Python实现隐马尔可夫模型的前向后向算法,希望对大家有所帮助!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。