ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

统计学习方法--隐马尔可夫模型

2022-01-25 19:03:40  阅读:202  来源: 互联网

标签:index -- 模型 print 马尔可夫 np alpha PI self


1.隐马尔可夫模型简介

隐马尔可夫模型由一个状态序列,一个观测序列组成,其中状态序列是不可观测的,因此叫做隐马尔可夫模型(HMM)。
几个重要的参数:Q,V,A,B,O, π \pi π,
Q是所有可能出现的状态的集合(可能的状态由N个),V是所有可能出现的观测结果的集合(可能的观测结果由M个),A是状态转移概率矩阵,是一个NN维的方针,B是一个观测概率矩阵,是一个NM维度的矩阵,O是观测序列,长度为T, π \pi π是初始的状态概率向量,是一个N*1的向量。

2.python代码实现

在这部分的代码中包含了HMM的3个算法:前向,后向以及viterbi算法。
其中viterbi算法适合于求解最优路径,适合动态路径规划的求解。

# 定义马尔可夫类
# 包含前向、后向以及维特比三个算法
# 难点是循环部分的代码,书中的公式是求和,这里可以直接用矩阵的内积简单计算
# 在计算时,维度要对齐
import numpy as np 
class HMM:
    def __init__(self):
        self.alpha = None
        self.farward_p = None
        self.back_p = None

    def farward(self,Q,V,A,B,O,PI):
        N = len(Q)
        M = len(O)
        alpha = np.zeros((N,M))

        T= M
        for t in range(T):
            index = V.index(O[t])
             ## 接下来是遍历每一个状态
             ## 先是遍历每一个时刻,接下来是遍历每一个状态
            for i in range(N):
                if t == 0:
                    alpha[i][t] = PI[t][i]*B[i][index]  # PI这里的索引存在疑问
                    print('alnpha1(%d) = p%db%db(o1) = %f' %
                          (i + 1, i, i, alpha[i][t]))
                else:
                    alpha[i][t] = np.dot(alpha[:,t-1],A[:,i]) * B[i][index]
                    print('alpha%d(%d) = [sigma alpha%d(i)ai%d]b%d(o%d) = %f' %
                          (t + 1, i + 1, t - 1, i, i, t, alpha[i][t]))
        self.farward_p = np.sum(alpha[:,-1])
        self.alpha = alpha
        print('==========================================')
        print('Backward P(O|lambda): %.6f' % self.farward_p)
        print('==========================================')

    def backward(self,Q,V,A,B,O,PI):
        # 后向算法过程用到了一个后向排序的过程
        # for i in range(M - 2, -1, -1)
        N = len(Q)
        M = len(O)
        beta = np.zeros((N,M))        
        T = M
        for t in range(T-1,-1,-1):            
            for i in range(N):
                if t == M-1:
                    beta[i,-1] = 1
                    print('Beta[%d][%d]= %f' % (t+1,i+1,beta[i,-1]))
                else:
                    index = V.index(O[t+1])
                    beta[i][t] = np.dot(np.multiply(A[i,:],B[:,index]),beta[:,t+1])
                    print('Beta[%d][%d]= %f' % (t+1,i+1,beta[i,t]))

        index_1 = V.index(O[0])
        back_p = [B[i][index_1]*PI[0][i]*beta[i][0] for i in range(N)]
        # print(np.sum(back_p))
        self.back_p = np.sum(back_p)
        print('==========================================')
        print('Backward P(O|lambda): %.6f' % self.back_p)
        print('==========================================')

    def viterbi(self,Q,V,A,B,O,PI):
        N = len(Q)
        M = len(O)
        T = M
        delta =np.zeros((N,T))  
        phai = np.zeros((N,T))

        # 遍历每一个时刻,相当于前向传播的计算
        for t in range(T):
            for i in range(N):
                if t == 0:
                    index = V.index(O[t])
                    delta[i][t] = PI[0][i] * B[i,index]
                    phai[i][t] = 0
                else:
                    index = V.index(O[t])
                    delta[i][t] = np.max(np.multiply(delta[:,t-1],A[:,i]))*B[i,index]
                    phai[i][t] = np.argmax(np.multiply(delta[:,t-1],A[:,i]))

        p_star = np.max(delta[:,-1])
        i_T = np.argmax(delta[:,-1])
        path = np.zeros(T)
        path[-1] = i_T+1
        # 第四步是最优路径的回溯,返回去寻找最优的路径
        for t in range(T-2,-1,-1):
            i_t = phai[int(i_T),t+1]
            path[t] = i_t + 1
            i_T = i_t        
        print('==========================================')
        print('Viterbi P(O|lambda): %.6f' % p)
        print('The best path is: %s-->%s-->%s-->%s' % (int(path[0]),int(path[1]),int(path[2]),int(path[3])))
        # print('Backward Algorithm P(O|lambda): %.6f' % p)
        print('==========================================')

结合李航《统计学习方法》书中的p13课后习题1,下面分别实现前向、后向以及维特比算法。

if __name__ == '__main__':
    #习题10.1
    Q = [1, 2, 3]
    V = ['红', '白'] ## 一共有几种观测结果,表示的只是不同结果的个数
    ## 3个不同的盒子就是3个不同的状态;
    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]])

    # O = ['红', '白', '红', '红', '白', '红', '白', '白']
    O = ['红', '白', '红','白',]    #习题10.1的例子
    PI = [[0.2, 0.4, 0.4]]
    my_hmm = HMM()
    my_hmm.farward(Q,V,A,B,O,PI)
    my_hmm.backward(Q,V,A,B,O,PI)
    my_hmm.viterbi(Q,V,A,B,O,PI)

前向算法结果:
在这里插入图片描述

后向算法结果:
在这里插入图片描述
维特比算法结果:
在这里插入图片描述

标签:index,--,模型,print,马尔可夫,np,alpha,PI,self
来源: https://blog.csdn.net/LuminCynthia_/article/details/122690443

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有