zoukankan      html  css  js  c++  java
  • 概率图模型1:隐马尔科夫(1)

    作者:孙相国

    转载请注明出处

    参考文献

    • 《机器学习郑捷》第11章
    • 机器学习周志华 14章
    • 《统计学系方法》第10章
    • 《概率图模型》第3章贝叶斯网表示和马尔科夫
    • 《驾驭文本》

    隐马尔科夫模型

    两个基本假设:

    1. 齐次马尔科夫性假设:隐藏的马尔科夫链在任意时刻(t)的状态只依赖于前一时刻的状态,与其他时刻的状态及观测无关,也与时刻(t)无关。

    2. 观测独立性假设:任意时刻的观测只依赖于该时刻的马尔科夫链的状态,与其他观测及状态无关。

    说人话,就下面这个图,其中箭头和连边表示概率依赖。

    这里写图片描述

    从这个图中,我们可以很轻松的对后面的一些公式做推导。比如:

    [left( o_{t+1}|o_{1:t},I_{t+1}=q_i ight)=left( o_{t+1}|I_{t+1}=q_i ight) ag{1.1} ]

    上面的公式为了书写简便,我们省略掉了概率符号(P)(下同),并且用(o_{1:t})表示(left(o_1,cdots,o_t ight))(下同)。

    [left( I_{t+1}=q_i|o_{1:t},I_t=q_j ight)=left( I_{t+1}=q_i|I_t=q_j ight) ag{1.2} ]

    [left( o_{t+1:T}|I_{t+1}=q_i,I_t=q_i ight)=left( o_{t+1:T}|I_{t+1}=q_i ight) ag{1.3} ]

    [left( o_{t+2:T}|I_{t+1}=q_j,o_{t+1} ight)=left( o_{t+2:T}|I_{t+1}=q_j ight) ag{1.4} ]

    [left( I_{t+1}|o_{1:t},I_t ight)=left( I_{t+1}|I_t ight) ag{1.5} ]

    [left(o_{t+1}|I_{t+1},o_{1:t},I_t ight)=left(o_{t+1}|I_{t+1} ight) ag{1.6} ]

    基本定义:

    转移概率(a_{ij}=left( I_{t+1}=q_j|I_t=q_i ight))

    观测概率(b_jleft(o_t ight)=left(o_t|I_t=q_j ight))

    初始状态概率(pi_i=Pleft(I_1=q_i ight))

    隐马尔科夫模型的3个基本问题

    1. 概率计算
    2. 学习问题
    3. 预测问题/解码问题

    概率计算问题

    前向算法

    前向概率(alpha_tleft(i ight)=left(o_{1:t},I_t=q_i ight))

    转移概率(a_{ij}=left( I_{t+1}=q_j|I_t=q_i ight))

    观测概率(b_jleft(o_t ight)=left(o_t|I_t=q_j ight))

    初始状态概率(pi_i=Pleft(I_1=q_i ight))

    初始前向概率:

    [egin{equation}egin{split}alpha_1left(i ight)&=left(o_{1},I_1=q_i ight) \&=left(I_1=q_i ight)left(o_1|I_1=q_i ight)\&=pi_ib_ileft(o_1 ight)end{split} ag{1.8}end{equation} ]

    前向概率的迭代推导:

    [egin{equation} egin{split} alpha_{t+1}left(i ight)&=left(o_{1:t+1},I_{t+1}=q_i ight) \ &= left(o_{1:t},I_{t+1}=q_i ight)left( o_{t+1}|o_{1:t},I_{t+1}=q_i ight)\ &= left(o_{1:t},I_{t+1}=q_i ight)left( o_{t+1}|I_{t+1}=q_i ight) ext{(由公式(1.1)得来)}\ &=left(o_{1:t},I_{t+1}=q_i ight)b_ileft(o_{t+1} ight)\ &=left(sum_jleft(o_{1:t},I_t=q_j,I_{t+1}=q_i ight) ight)b_ileft(o_{t+1} ight)\ &=left(sum_jleft(o_{1:t},I_t=q_j ight)left(I_{t+1}=q_i|o_{1:t},I_t=q_j ight) ight)b_ileft(o_{t+1} ight)\ &=left(sum_jleft(o_{1:t},I_t=q_j ight)left(I_{t+1}=q_i|I_t=q_j ight) ight)b_ileft(o_{t+1} ight) ext{(由公式(1.2)得来)}\ &=left(sum_jalpha_tleft(j ight)a_{ji} ight)b_ileft(o_{t+1} ight) end{split} ag{1.9} end{equation} ]

    终止状态推导:

    [egin{equation} egin{split} Pleft(O |lambda ight)&=left(o_{1:T}|lambda ight) \ &=sum_i^N left(o_{1:t},I_{T}=q_i ight)\ &=sum_i^Nalpha_Tleft(i ight) end{split} ag{1.10} end{equation} ]

    算法1.1(观测序列概率的前向算法)

    输入:隐马尔科夫模型(lambda),观测序列(O)

    输出:观测序列概率(Pleft( O|lambda ight))

    1. 根据公式((1.8)),设定初值。

    2. 根据公式((1.9))递推。其中(t=1,2,cdots,T-1)

    3. 终止。根据公式((1.10))得到输出。

    python实现(李航《统计学习方法》177页例题10.2):

    #!/usr/bin/env python
    # -*- coding: UTF-8 -*-
    """
    @author: XiangguoSun
    @contact: sunxiangguodut@qq.com
    @file: forward_prob.py
    @time: 2017/3/13 8:53
    @software: PyCharm
    """
    import numpy as np
    
    
    def forward_prob(model, Observe, States):
        '''
        马尔科夫前向算法
        '''
    
        A, B, pi = model
        N = States.size
        T = Observe.size
    
        alpha = pi*B[:, Observe[0]]
        print "(1)计算初值alpha_1(i):   ",alpha
    
        print "(2) 递推..."
        for t in xrange(0, T-1):
            print "t=", t+1,"   alpha_",t+1,"(i):",alpha
            alpha = alpha.dot(A)*B[:, Observe[t+1]]
    
        print "(3)终止。alpha_",T,"(i):    ", alpha
        print "输出Prob:  ",alpha.sum()
        return alpha.sum()
    
    
    if __name__ == '__main__':
        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 = np.array([0.2, 0.4, 0.4])
    
        model = (A, B, pi)
    
        Observe = np.array([0, 1, 0])
    
        States = np.array([1, 2, 3])
    
        forward_prob(model,Observe,States)
    

    后向算法

    后向概率:(eta_tleft( i ight)=left( o_{t+1:T}|I_t=q_i ight))

    初始后向概率:(eta_Tleft(i ight)=1,i=1,2,cdots,N)

    后向概率迭代推导:

    [egin{equation} egin{split} eta_tleft(i ight)&=left(o_{t+1:T}|I_t=q_i ight) \ &=sum_j^N left(o_{t+1:T},I_{t+1}=q_j|I_{t}=q_i ight)\ &=sum_j^Nleft(I_{t+1}=q_j|I_{t}=q_i ight) left(o_{t+1:T}|I_{t+1}=q_j,I_{t}=q_i ight)\ &=sum_j^Nleft(I_{t+1}=q_j|I_{t}=q_i ight) left(o_{t+1:T}|I_{t+1}=q_j ight) ext{(由公式(1.3)得到)}\ &=sum_j^Nleft(I_{t+1}=q_j|I_{t}=q_i ight) left(o_{t+1}|I_{t+1}=q_j ight)left(o_{t+2:T}|I_{t+1}=q_j,o_{t+1} ight)\ &=sum_j^N a_{ij} b_jleft(o_{t+1} ight) eta_{t+1}left(j ight) end{split} ag{1.11} end{equation} ]

    终止状态推导:

    [egin{equation} egin{split} Pleft(O|lambda ight)&=left(o_{1:T}|lambda ight) \ &=sum_{i=1}^N left(o_{1:T},I_{1}=q_i ight)\ &=sum_{i=1}^N left(I_1=q_i ight)left(o_{1:T}|I_{1}=q_i ight)\ &=sum_{i=1}^N left(I_1=q_i ight)left(o_1|I_1=q_i ight)left(o_{2:T}|o_1,I_{1}=q_i ight)\ &=sum_{i=1}^Npi_i b_ileft(o_i ight)left(o_{2:T}|I_{1}=q_i ight)\ &=sum_{i=1}^Npi_i b_ileft(o_i ight)eta_1left(i ight) end{split} ag{1.12} end{equation} ]

    算法1.2(观测序列概率的后向算法)

    输入:隐马尔科夫模型(lambda),观测序列(O)

    输出:观测序列概率(Pleft( O|lambda ight))

    1. 设定后向概率初值为1。
    2. 根据公式((1.11))递推。其中(t=T-1,T-2,cdots,1)
    3. 终止。根据公式((1.12))得到输出。

    python实现(李航《统计学习方法》177页例题10.2):

    #!/usr/bin/env python
    # -*- coding: UTF-8 -*-
    """
    @author: XiangguoSun
    @contact: sunxiangguodut@qq.com
    @file: markov.py
    @time: 2017/3/13 8:53
    @software: PyCharm
    """
    import numpy as np
    
    
    def forward_prob(model, Observe, States):
        '''
        马尔科夫前向算法
        '''
    
        A, B, pi = model
        N = States.size
        T = Observe.size
    
        alpha = pi*B[:, Observe[0]]
        print "(1)计算初值alpha_1(i):   ",alpha
    
        print "(2) 递推..."
        for t in xrange(0, T-1):
            alpha = alpha.dot(A)*B[:, Observe[t+1]]
            print "t=", t + 1, "   alpha_", t + 1, "(i):", alpha
    
        print "(3)终止。alpha_",T,"(i):    ", alpha
        print "输出Prob:  ",alpha.sum()
        return alpha.sum()
    
    
    def backward_prob(model,Observe,States):
        '''
          马尔科夫后向算法
          '''
    
        A, B, pi = model
        N = States.size
        T = Observe.size
    
        beta = np.ones((N,))  # beta_T
        print "(1)计算初值beta_",T,"(i):   ", beta
    
        print "(2) 递推..."
        for t in xrange(T - 2, -1, -1):  # t=T-2,...,0
            beta = A.dot(B[:, Observe[t + 1]] * beta)
            print "t=", t + 1, "   beta_", t + 1, "(i):", beta
    
        print "(3)终止。alpha_", 1, "(i):    ", beta
        prob = pi.dot(beta * B[:, Observe[0]])
        print "输出Prob:  ", prob
        return prob
    
    
    if __name__ == '__main__':
    
    
        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 = np.array([0.2, 0.4, 0.4])
    
        model = (A, B, pi)
    
        Observe = np.array([0, 1, 0])
    
        States = np.array([1, 2, 3])
    
        forward_prob(model,Observe,States)
    
        backward_prob(model, Observe, States)
    

    实验结果:

    这里写图片描述

  • 相关阅读:
    20201130-栈与链表
    K-means算法
    支持向量机-SVC
    贝叶斯-实现新闻数据分类
    贝叶斯-使用贝叶斯实现拼写检查器
    泰坦尼克求胜率预测-基于随机森林实现
    决策树算法-Python实现
    SQL_牛客网60题
    信用卡欺诈模型-逻辑回归
    用python实习逻辑回归
  • 原文地址:https://www.cnblogs.com/xiangguosun/p/6785378.html
Copyright © 2011-2022 走看看