当前位置 主页 > 网站技术 > 代码类 >

    Python实现隐马尔可夫模型的前向后向算法的示例代码

    栏目:代码类 时间:2019-12-31 15:09

    本篇文章对隐马尔可夫模型的前向和后向算法进行了Python实现,并且每种算法都给出了循环和递归两种方式的实现。

    前向算法Python实现

    循环方式

    import numpy as np
    def hmm_forward(Q, V, A, B, pi, T, O, p):
      """
      :param Q: 状态集合
      :param V: 观测集合
      :param A: 状态转移概率矩阵
      :param B: 观测概率矩阵
      :param pi: 初始概率分布
      :param T: 观测序列和状态序列的长度
      :param O: 观测序列
      :param p: 存储各个状态的前向概率的列表,初始为空
      """
      for t in range(T):
        # 计算初值
        if t == 0:
          for i in range(len(Q)):
            p.append(pi[i] * B[i, V[O[0]]])
        # 初值计算完毕后,进行下一时刻的递推运算
        else:
          alpha_t_ = 0
          alpha_t_t = []
          for i in range(len(Q)):
            for j in range(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
      return sum(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

    递归方式

    import numpy as np
    def hmm_forward_(Q, V, A, B, pi, T, O, p, T_final):
      """
      :param T_final:递归的终止条件
      """
      if T == 0:
        for i in range(len(Q)):
          p.append(pi[i] * B[i, V[O[0]]])
      else:
        alpha_t_ = 0
        alpha_t_t = []
        for i in range(len(Q)):
          for j in range(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
      if T >= T_final:
        return sum(p)
      return hmm_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实现

    循环方式

    import numpy as np
    def hmm_backward(Q, V, A, B, pi, T, O, beta_t, T_final):
      for t in range(T, -1, -1):
        if t == T_final:
          beta_t = beta_t
        else:
          beta_t_ = 0
          beta_t_t = []
          for i in range(len(Q)):
            for j in range(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
        if t == 0:
          p=[]
          for i in range(len(Q)):
            p.append(pi[i] * B[i, V[O[0]]] * beta_t[i])
          beta_t = p
      return sum(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