模型 HMM=(A, B, \pi)

初始化三个参数:隐状态初始状态概率向量\pi,状态转移概率矩阵A,隐状态生成观测状态概率矩阵B。

实现三个方法:

1、2. 计算给定观测状态序列向量的概率(前向和后向两种计算方法),

3. 给定观测状态序列,求出与该序列最匹配的隐状态序列及其概率(Viterbi算法)。

程序如下:

# -*- coding: utf-8 -*-# @Author : ZhaoKe# @Time : 2022-09-18 14:43from typing import Listimport numpy as npclass HMM():    def __init__(self):        # 对应三个隐状态初始化概率矩阵        self.init_prob = np.array([0.4, 0.3, 0.3])        # 隐状态会生成观测状态的概率矩阵        self.gene_prob = np.array([            [0.8, 0.2],            [0.6, 0.4],            [0.3, 0.7]        ])        # 状态转移概率矩阵        self.tran_prob = np.array([            [0.4, 0.5, 0.1],            [0.3, 0.4, 0.3],            [0.1, 0.5, 0.4]        ])    # 求解生成特定的序列的概率    # 例如,输入[0, 1, 0]    def forward_prob_generate(self, series: List):        # 行数等于隐状态个数,列数等于序列长度        # print(len(self.init_prob), len(series))        res = np.zeros((len(self.init_prob), len(series)))        res[:, 0] = np.multiply(self.init_prob, self.gene_prob[:, series[0]])        for i in range(1, len(series)):            res[:, i] = np.multiply(np.matmul(res[:, i-1], self.tran_prob), self.gene_prob[:, series[i]])        print(res)    # 后向生成特定序列的概率    def backward_prob_generate(self, series: List):        res = np.zeros((len(self.init_prob), len(series)))        n = len(series)        res[:, n-1] = 1        for i in range(n-2, -1, -1):            res[:, i] = np.matmul(self.tran_prob, np.multiply(self.gene_prob[:, series[i+1]], res[:, i+1]))        print(res)        print(np.sum(self.init_prob * self.gene_prob[:, 1] * res[:, 0]))    # 维特比算法求解特定观测序列的最优隐状态向量及其概率    def viterbi(self, series: List):        # 动态规划        dp = np.zeros((3, 4))        dp[:, 0] = 1        dp[:, 1] = self.init_prob * self.gene_prob[:, series[0]]        per = list(map(int, np.zeros(len(series)+1)))        per[1] = np.argmax(dp[:, 1])        # print(dp)        # print(per)        for i in range(2, len(series)+1):            for j in range(0, 3):                tmp = dp[:, i-1] * self.tran_prob[:, j]                dp[j, i] = np.max(tmp) * self.gene_prob[j][series[i-1]]            print(dp[:, i])            per[i] = np.argmax(dp[:, i])        print("动态规划矩阵:\n", dp)        print("最优路径:", per)        print("概率计算:", dp[per[-1], 3])if __name__ == '__main__':    hmm = HMM()    # hmm.forward_prob_generate([0, 1, 0])    # hmm.backward_prob_generate([1, 0, 1])    # hmm.viterbi([0,0,0])    # hmm.viterbi([0,0,1])    # hmm.viterbi([0,1,0])    # hmm.viterbi([0,1,1])    hmm.viterbi([1,0,0])    # hmm.viterbi([1,0,1])    # hmm.viterbi([1,1,0])    # hmm.viterbi([1,1,1])

和例题对照,结果正确