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(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。