zoukankan      html  css  js  c++  java
  • HMM 前向后向算法(转)

    最近研究NLP颇感兴趣,但由于比较懒,所以只好找来网上别人的比较好的博客,备份一下,也方便自己以后方便查找(其实,一般是不会再回过头来看的,嘿嘿 -_-!!)

    代码自己重新写了一遍,所以就不把原文代码贴过来了。

    1. 前向算法(摘自http://www.cnblogs.com/kaituorensheng/archive/2012/12/01/2797230.html)

    隐马模型的评估问题即,在已知一个观察序列O=O1O2...OT,和模型μ=(A,B,π}的条件下,观察序列O的概率,即P(O|μ}

                       

          如果穷尽所有的状态组合,即S1S1...S1, S1S1...S2, S1S1...S3, ..., S3S3...S3。这样的话t1时刻有N个状态,t2时刻有N个状态...tT时刻有N个状态,这样的话一共有N*N*...*N= NT种组合,时间复杂度为O(NT),计算时,就会出现“指数爆炸”,当T很大时,简直无法计算这个值。为解决这一问题,Baum提出了前向算法。

          归纳过程

          首先引入前向变量αt(i):在时间t时刻,HMM输出序列为O1O2...OT,在第t时刻位于状态si的概率。

          当T=1时,输出序列为O1,此时计算概率为P(O1|μ):假设有三个状态(如下图)1、2、3,输出序列为O1,有三种可能一是状态1发出,二是从状态2发出,三是从状态3发出。另外从状态1发出观察值O1得概率为b1(O1),从状态2发出观察值O1得概率为b2(O1),从状态3发出观察值O1得概率为b3(O1)。因此可以算出

         P(O1|μ)= π1*b1(O1)+π2*b2(O1) +  π3*b3(O1)= α1(1) + α1(2) + α1(3)

                                         

          当T=2时,输出序列为O1O2,此时计算概率为P(O1O2|μ):假设有三个状态(如下图)1、2、3,输出序列为O1,有三种可能一是状态1发出,二是从状态2发出,三是从状态3发出。另外从状态1发出观察值O2得概率为b1(O2),从状态2发出观察值O2得概率为b2(O2),从状态3发出观察值O2得概率为b3(O2)。

          要是从状态1发出观察值O2,可能从第一时刻的1、2或3状态装换过来,要是从状态1转换过来,概率为α1(1)*a11*b1(O2),要是从状态2转换过来,概率为α1(2)*a21*b1(O2),要是从状态3转换过来,概率为α1(3)*a31*b1(O2),因此

         P(O1O2,q2=s1|μ)= α1(1)*a11*b1(O2)  + α1(2)*a21*b1(O2) + α1(3)*a31*b1(O2)=α2(1)

                                         

          同理:P(O1O2,q2=s1|μ)= α1(1)*a12*b2(O2)  + α1(2)*a22*b2(O2) + α1(3)*a32*b2(O2)=α2(2)

                   P(O1O2,q2=s1|μ)= α1(1)*a13*b1(O2)  + α1(2)*a23*b3(O2) + α1(3)*a33*b3(O2)=α2(3)

         所以:P(O1O2|μ)=P(O1O2,q2=s1|μ)+ P(O1O2,q2=s1|μ)+ P(O1O2,q2=s1|μ)

                                 =α2(1) + α2(2) + α2(3)

          以此类推。。。

          前向算法

           step1 初始化:α1(i) = πi*bi(O1), 1≤i≤N

           step2 归纳计算:

                               

           step3 终结:

                          P(O|μ)=

          时间复杂度

          计算某时刻的某个状态的前向变量需要看前一时刻的N个状态,此时时间复杂度为O(N),每个时刻有N个状态,此时时间复杂度为N*O(N)=O(N2),又有T个时刻,所以时间复杂度为T*O(N2)=O(N2T)。

          程序例证

           

            前向算法计算P(O|M):

            step1:α1(1) =π1*b1(red)=0.2*0.5=0.1          α1(2)=π2*b2(red)==0.4*0.4= 0.16          α1(3)=π3*b3(red)==0.4*0.7=0.21

            step2:α2(1)=α1(1)*a11*b1(white) + α1(2)*a21*b1(white) + α1(3)*a31*b1(white)

                         ...

            step3:P(O|M) = α3(1)+α3(2)+α3(3)

    2. 后向算法(摘自http://www.cnblogs.com/kaituorensheng/archive/2012/12/03/2800489.html)

    对于HMM的评估问题,利用动态规划可以用前向算法,从前到后算出前向变量;也可以采用后向算法,从后到前算出后向变量。

    先介绍后向变量βt(i):给定模型μ=(A,B,π),并且在时间 时刻t 状态为s的前提下,输出序列为Ot+1Ot+2...OT的概率,即

                                        βt(i)=P(Ot+1Ot+2...OT|qt=si,μ)

    归纳过程

        假设仍然有3个状态

                      

        当t=T时,按照定义:时间t  状态q输出为OT+1......的概率,从T+1开始的输出是不存在的(因为T时刻是终止终止状态),即T之后是空,是个必然事件,因此βt(i)=1,1≤1≤N

        当t=T-1时,

                              

                     βT-1(i)=P(OT|qT-1=si,μ) = ai1*b1(OT)*βT(1)  +  ai2*b2(OT)*βT(2)  +  ai3*b3(OT)*βT(3)

          ......

        当t=1时,

           β1(1)=P(O2O3...OT|q2=s1,μ) = a11*b1(O2)*β2(1) + a12*b2(O2)*β2(2) + a13*b3(O2)*β2(3)

           β1(2)=P(O2O3...OT|q2=s1,μ) = a21*b1(O2)*β2(1) + a22*b2(O2)*β2(2) + a23*b3(O2)*β2(3)

           β1(3)=P(O2O3...OT|q2=s1,μ) = a31*b1(O2)*β2(1) + a32*b2(O2)*β2(2) + a33*b3(O2)*β2(3)

           P(O1O2...OT|μ) =    

                                 =   

                                 =  

    后向算法

        step1 初始化:βT(i)=1, 1≤1≤N

        step2 归纳计算:

                           1≤t≤T-1, 1≤i≤N

        step3 求终结和:

                       P(O|μ)=  

    时间复杂度

        计算某时刻在某个状态下的后向变量需要看后一时刻的N个状态,此时时间复杂度为O(N),每个时刻有N个状态,此时时间复杂度为N*O(N)=O(N2),又有T个时刻,所以时间复杂度为T*O(N2)=O(N2T)。

    程序例证

                  

    后向算法

        计算P(O|M):

        step1:β4(1) = 1          β4(2) = 1          β4(3) = 1

        step2:β3(1) = β4(1)*a11*b1(white) + β4(2)*a12*b2(white) + β4(3)*a13*b3(white)

                         ...

        step3:P(O|M) = π11(1)*b1(O1) + π21(2)*b2(O1) + π31(3)*b3(O1)

    3.前向-后向算法(摘自http://www.cnblogs.com/kaituorensheng/archive/2012/12/05/2803182.html)

    重新回顾:

        前向变量αt(i):在时刻t,在已知模型μ=(A,B,π)的条件下,状态处于si,输出序列为O102...Ot,前向变量为αt(i)

        后向变量βt(i):在时刻t,在已知模型μ=(A,B,π)和状态处于si的条件下,输出序列为Ot+1Ot+2...OT,后向变量为βt(i)

    公式推导:

        P(O,qt=si|μ) = P(O1O2...OT, qt=si|μ)

                             =P(O1O2...Ot, qt=si,Ot+1Ot+2...OT|μ)

                             =P(O1O2...Ot, qt=si|μ) * P(Ot+1Ot+2...OT|O1O2...Ot, qt=si,μ)

                             =P(O1O2...Ot, qt=si|μ) * P(Ot+1Ot+2...OT|qt=si,μ)

                             =αt(i) *  βt(i)

         P(O|μ)=

    案例分析:

        

          分析:

            P(q4=s3|O,M) =  P(q4=s3, O|M)/P(O|M)

                                = P(O,q4=s3|M)/P(O|M)

                                = α4(3) *  β4(3)/  

  • 相关阅读:
    JavaScript正则表达式(四)
    JavaScript三元运算符以及运算符顺序
    JavaScript进制转换
    JavaScript赋值运算符和关系运算符
    JavaScript输出
    hadoop1.2.1的安装
    SSH免费登录
    使用java poi解析表格
    【深入理解JVM】:Java类继承关系中的初始化顺序
    解决yum安装mysql时Requires: libc.so.6(GLIBC_2.17)(64bit)
  • 原文地址:https://www.cnblogs.com/sjjsxl/p/6285629.html
Copyright © 2011-2022 走看看