python 实现 HMM算法

个人学习记录备份,内容只对本人有效,不保证正确性

# -*-coding:UTF-8-*-import numpy as npclass HMM:def __init__(self, Ann, Bnm, pi1n):# 状态转移概率矩阵self.A = np.array(Ann)# 观测概率矩阵self.B = np.array(Bnm)# 初始概率分布self.pi = np.array(pi1n)# 状态的数量self.N = self.A.shape[0]# 观测结果的数量self.M = self.B.shape[1]def printhmm(self):print("==================================================")print("HMM content: N =", self.N, ",M =", self.M)for i in range(self.N):if i == 0:print("hmm.A ", self.A[i, :], " hmm.B ", self.B[i, :])else:print("      ", self.A[i, :], "       ", self.B[i, :])print("hmm.pi", self.pi)print("==================================================")# 函数名称:Forward *功能:前向算法估计参数 *参数:phmm:指向HMM的指针# T:观察值序列的长度 O:观察值序列# alpha:运算中用到的临时数组 pprob:返回值,所要求的概率def Forward(self, T, O, alpha, pprob):#     1. Initialization 初始化for i in range(self.N):alpha[0, i] = self.pi[i] * self.B[i, O[0]]#     2. Induction 递归for t in range(T - 1):for j in range(self.N):sum = 0.0for i in range(self.N):sum += alpha[t, i] * self.A[i, j]alpha[t + 1, j] = sum * self.B[j, O[t + 1]]#     3. Termination 终止sum = 0.0for i in range(self.N):sum += alpha[T - 1, i]pprob[0] *= sum# 带修正的前向算法def ForwardWithScale(self, T, O, alpha, scale, pprob):scale[0] = 0.0#     1. Initializationfor i in range(self.N):alpha[0, i] = self.pi[i] * self.B[i, O[0]]scale[0] += alpha[0, i]for i in range(self.N):alpha[0, i] /= scale[0]#     2. Inductionfor t in range(T - 1):scale[t + 1] = 0.0for j in range(self.N):sum = 0.0for i in range(self.N):sum += alpha[t, i] * self.A[i, j]alpha[t + 1, j] = sum * self.B[j, O[t + 1]]scale[t + 1] += alpha[t + 1, j]for j in range(self.N):alpha[t + 1, j] /= scale[t + 1]#     3. Terminationfor t in range(T):pprob[0] += np.log(scale[t])# 函数名称:Backward * 功能:后向算法估计参数 * 参数:phmm:指向HMM的指针# T:观察值序列的长度 O:观察值序列# beta:运算中用到的临时数组 pprob:返回值,所要求的概率def Backword(self, T, O, beta, pprob):#     1. Intializationfor i in range(self.N):beta[T - 1, i] = 1.0#     2. Inductionfor t in range(T - 2, -1, -1):for i in range(self.N):sum = 0.0for j in range(self.N):sum += self.A[i, j] * self.B[j, O[t + 1]] * beta[t + 1, j]beta[t, i] = sum#     3. Terminationpprob[0] = 0.0for i in range(self.N):pprob[0] += self.pi[i] * self.B[i, O[0]] * beta[0, i]# 带修正的后向算法def BackwardWithScale(self, T, O, beta, scale):#     1. Intializationfor i in range(self.N):beta[T - 1, i] = 1.0#     2. Inductionfor t in range(T - 2, -1, -1):for i in range(self.N):sum = 0.0for j in range(self.N):sum += self.A[i, j] * self.B[j, O[t + 1]] * beta[t + 1, j]beta[t, i] = sum / scale[t + 1]# Viterbi算法# 输入:A,B,pi,O 输出P(O|lambda)最大时Poptimal的路径Idef viterbi(self, O):T = len(O)# 初始化delta = np.zeros((T, self.N), np.float)phi = np.zeros((T, self.N), np.float)I = np.zeros(T)for i in range(self.N):delta[0, i] = self.pi[i] * self.B[i, O[0]]phi[0, i] = 0# 递推for t in range(1, T):for i in range(self.N):delta[t, i] = (self.B[i, O[t]]* np.array([delta[t - 1, j] * self.A[j, i] for j in range(self.N)]).max())phi[t, i] = np.array([delta[t - 1, j] * self.A[j, i] for j in range(self.N)]).argmax()# 终结prob = delta[T - 1, :].max()I[T - 1] = delta[T - 1, :].argmax()# 状态序列求取for t in range(T - 2, -1, -1):I[t] = phi[t + 1, I[t + 1]]return I, prob# 计算gamma : 时刻t时马尔可夫链处于状态Si的概率def ComputeGamma(self, T, alpha, beta, gamma):for t in range(T):denominator = 0.0for j in range(self.N):gamma[t, j] = alpha[t, j] * beta[t, j]denominator += gamma[t, j]for i in range(self.N):gamma[t, i] = gamma[t, i] / denominator# 计算sai(i,j) 为给定训练序列O和模型lambda时:# 时刻t是马尔可夫链处于Si状态,二时刻t+1处于Sj状态的概率def ComputeXi(self, T, O, alpha, beta, gamma, xi):for t in range(T - 1):sum = 0.0for i in range(self.N):for j in range(self.N):xi[t, i, j] = (alpha[t, i]* beta[t + 1, j]* self.A[i, j]* self.B[j, O[t + 1]])sum += xi[t, i, j]for i in range(self.N):for j in range(self.N):xi[t, i, j] /= sum# Baum-Welch算法# 初始模型:HMM={A,B,pi,N,M}# 输入 L个观测序列Odef BaumWelch(self, L, T, O, alpha, beta, gamma):print("BaumWelch")DELTA = 0.01round = 0flag = 1probf = [0.0]delta = 0.0deltaprev = 0.0probprev = 0.0ratio = 0.0deltaprev = 10e-70xi = np.zeros((T, self.N, self.N))pi = np.zeros((T), np.float)denominatorA = np.zeros((self.N), np.float)denominatorB = np.zeros((self.N), np.float)numeratorA = np.zeros((self.N, self.N), np.float)numeratorB = np.zeros((self.N, self.M), np.float)scale = np.zeros((T), np.float)while True:probf[0] = 0# E - stepfor l in range(L):self.ForwardWithScale(T, O[l], alpha, scale, probf)self.BackwardWithScale(T, O[l], beta, scale)self.ComputeGamma(T, alpha, beta, gamma)self.ComputeXi(T, O[l], alpha, beta, gamma, xi)for i in range(self.N):pi[i] += gamma[0, i]for t in range(T - 1):denominatorA[i] += gamma[t, i]denominatorB[i] += gamma[t, i]denominatorB[i] += gamma[T - 1, i]for j in range(self.N):for t in range(T - 1):numeratorA[i, j] += xi[t, i, j]for k in range(self.M):for t in range(T):if O[l][t] == k:numeratorB[i, k] += gamma[t, i]# M - step# 重估状态转移矩阵 和 观察概率矩阵for i in range(self.N):self.pi[i] = 0.001 / self.N + 0.999 * pi[i] / Lfor j in range(self.N):self.A[i, j] = (0.001 / self.N + 0.999 * numeratorA[i, j] / denominatorA[i])numeratorA[i, j] = 0.0for k in range(self.M):self.B[i, k] = (0.001 / self.M + 0.999 * numeratorB[i, k] / denominatorB[i])numeratorB[i, k] = 0.0pi[i] = denominatorA[i] = denominatorB[i] = 0.0if flag == 1:flag = 0probprev = probf[0]ratio = 1continuedelta = probf[0] - probprevratio = delta / deltaprevprobprev = probf[0]deltaprev = deltaround += 1if ratio <= DELTA:print("num iteration ", round)breakif __name__ == "__main__":print("python my HMM")# 例子: 两枚硬币抛正反面,状态# 状态集合Q: [q0, q1], q0: 0号硬币, q1: 1号硬币# 状态转移概率矩阵A: [[q0 -> q0, q0 -> q1], [q1 -> q0, q1 -> q1]]A = [[0.75, 0.25], [0.25, 0.75]]# 观测集合V: [v0, v1], v0: 正面, v1: 反面# 观测概率矩阵B: [[v0|q0, v1|q0], [v0|q1, v1|q1]]B = [[0.51, 0.49], [0.48, 0.52]]# 初始概率分布pai: 表示时刻t=1处于状态qi的概率。pai = [0.5, 0.5]# 初始化 hmmhmm = HMM(A, B, pai)# 状态序列I 未知# 观测序列O 已知O = [[1, 0, 0, 1, 1, 0, 0, 0, 0],[1, 1, 0, 1, 0, 0, 1, 1, 0],[0, 0, 1, 1, 0, 0, 1, 1, 1],]# 观测次数L = len(O)# 观测序列的长度T = len(O[0])# 状态的个数lA = len(A)# 观测结果的个数alpha = np.zeros((T, lA), np.float)beta = np.zeros((T, lA), np.float)gamma = np.zeros((T, lA), np.float)hmm.BaumWelch(L, T, O, alpha, beta, gamma)hmm.printhmm()# 概率计算问题# 给定模型M=(A, B, pai)和观测序列O=(o1, o2, ..., oT),计算模型M下观测序列O出现的概率P(O|M)# TODO# 状态转移概率矩阵AA = [[0.5, 0.2, 0.3],[0.3, 0.5, 0.2],[0.2, 0.3, 0.5],]# 观测概率矩阵BB = [[0.5, 0.5],[0.4, 0.6],[0.7, 0.3],]# 状态集合QQ = [0, 1, 2]# 观测集合VV = [0, 1]# 初始概率分布pai: 只描述状态,表示时刻t=1处于状态qi的概率pai = [0.2, 0.4, 0.4]# 状态的个数lA = len(A)# 观测序列长度T = 3# 观测序列O = [0, 1, 0]# 前向算法计算# 给定隐马尔可夫模型λ,定义到时刻t部分观测序列为o1, o2, ..., ot,且状态为qi的概率为前向概率,记做alpha(t, i)# 首次可能观测到 o1 的概率分布alpha = [pai[i] * B[i][O[0]] for i in range(lA)]# 后续可能观测到 0t 的概率分布for t in range(1, T):alpha = [sum([alpha[j]*A[j][i] for j in range(lA)])*B[i][O[t]] for i in range(lA)]P_O_M = sum([alpha[i] for i in range(lA)])print(P_O_M)# 后向算法计算# 给定隐马尔可夫模型λ,定义在时刻t状态为qi的条件下,从t+1到T的部分观测序列为ot+1, ot+2, ..., oT的概率为后向概率,记做beta(t, i)beta = [1 for i in range(lA)]for t in range(T-1, 0, -1):beta = [sum([A[i][j] * B[j][O[t]] * beta[j] for j in range(lA)]) for i in range(lA)]P_O_M = sum([pai[i]*B[i][O[0]]*beta[i] for i in range(lA)])print(P_O_M)# 学习问题# 一直观测序列O=(o1, o2, ..., oT),估计模型M=(A, B, pai)的参数,使得在该模型下观测序列概率P(O|M)最大# 即 用极大似然估计的方法估计参数# TODO# 预测问题,也称为解码(decoding)问题# 已知模型M=(A, B, pai)和观测序列O=(o1,o2, ..., oT),求给定观测序列条件P(O|M)最大的状态序列I=(i1, i2, ..., iT)。# 即,给定观测序列,求最优可能的对应的状态序列。# TODO

python 实现HMM相关推荐

  1. python做马尔科夫模型预测法_python实现隐马尔科夫模型HMM

    #coding=utf8 ''''' Created on 2017-8-5 里面的代码许多地方可以精简,但为了百分百还原公式,就没有精简了. @author: adzhua ''' import n ...

  2. Python在Jupyter上使用HMM进行中文分词,将新闻文本分词后提取其中的高频词

    首先,需要三个.txt文件: 需要提取高频词的搜狐新闻文本news.txt(需要5积分,不能白嫖,气四~) 训练HMM的trainCorpus.txt(需要5积分,不能白嫖,气四~) 停顿词stopw ...

  3. 隐马尔可夫模型(HMM)介绍

    理论介绍: 1. Python实现HMM(隐马尔可夫模型) - sinat_36005594的博客 - CSDN博客 2. HMM进阶(4)--前向算法(python) 3. 前向-后向算法(Forw ...

  4. NILMTK——因子隐马尔可夫之隐马尔可夫

    因子隐马尔可夫(FHMM)由Ghahramani在1997年提出,是一种多链隐马尔可夫模型,适合动态过程时间序列的建模,并具有强大的时序模型的分类能力,特别适合非平稳.再现性差的序列的分析. 1. 马 ...

  5. 语音识别入门:从菜鸟到大佬

    在人工智能飞速发展的今天,语音识别技术成为很多设备的标配,比如我们会对着手机说"siri,帮我打电话给老板",又或是"小度小度,放首歌"等等. 尽管语音技术在逐 ...

  6. NLP初学-Word Segmentation(分词)

    最近在看一些NLP相关的内容,用博客记录整理一下. 无论是CV还是NLP,说到底是将图像和文本转化为数据的方式,在计算机中进行用不同算法进行处理. 对文本处理的第一步一般都是分词.现在有很多现成的分词 ...

  7. python朴素贝叶斯调参_邹博机器学习升级版II附讲义、参考书与源码下载(数学 xgboost lda hmm svm)...

    课程介绍 本课程特点是从数学层面推导最经典的机器学习算法,以及每种算法的示例和代码实现(Python).如何做算法的参数调试.以实际应用案例分析各种算法的选择等. 1.每个算法模块按照"原理 ...

  8. 【机器学习基础】数学推导+纯Python实现机器学习算法24:HMM隐马尔可夫模型

    Python机器学习算法实现 Author:louwill Machine Learning Lab HMM(Hidden Markov Model)也就是隐马尔可夫模型,是一种由隐藏的马尔可夫链随机 ...

  9. python做马尔科夫模型预测法_Python实现HMM(隐马尔可夫模型)

    1. 前言 隐马尔科夫HMM模型是一类重要的机器学习方法,其主要用于序列数据的分析,广泛应用于语音识别.文本翻译.序列预测.中文分词等多个领域.虽然近年来,由于RNN等深度学习方法的发展,HMM模型逐 ...

最新文章

  1. 三维几何基础大合集(三维点积叉积、点线面、凸包)《计算几何全家桶(三)》
  2. python起步输入-Python编程起步——输入与输出
  3. matlab主程序和子函数不在一个文件夹下,怎么调用?
  4. [NDK 佳佳的魔法药水]
  5. linux 6.4 安装oracle10g,Red Hat Linux 6.4 安装 Oracle 10g 及问题解决
  6. 关于std::string和 C-style string的一些知识点备忘
  7. APP功能测试点汇总
  8. 计算机专业社会调研怎么写,计算机专业调研论文提纲格式 计算机专业调研论文提纲怎么写...
  9. python:文件写入出现ASII编码
  10. 如何修改、缩小截图图片大小,压缩图片。
  11. Linux基础和命令大全
  12. 三节点大数据环境安装详细教程
  13. 苹果android怎么设置,iphone小圆点怎么设置调出来 自定义手势怎么用
  14. 十四个很准的心理暗示
  15. 致远OA表单自定义函数(计算N年后今天的日期 )
  16. HR干货,怎样做好企业员工的晋升
  17. 清理 Visual Studio 工具箱 的冗杂控件(第三方控件卸载不完全)
  18. python爬取个人信息_Python爬取个人微信朋友信息操作示例
  19. 制作一款可以【记录运动历史数据】的智能呼啦圈——嵌入式功能实现
  20. 趋肤效应实验报告_无线电能传输(课程设计报告)实验报告

热门文章

  1. PCA9555PW 原厂封装 新到货
  2. vscode 对template 标签失效的问题
  3. 对于2个月至5岁的儿童,出现下列哪些症状时需惕重症肺炎
  4. 好奇号火星车旅行日志——January 20, 2017 - Friday——化学成分相机(ChemCam)故障
  5. 软测学习笔记(黑马程序员)
  6. Substitution 的用法
  7. 电动车实名制挂牌管理系统
  8. Linux Centos qW3xT.4 病毒解决过程
  9. python decode方法_Python中decode()方法有哪些功能?
  10. 小狐狸ChatGPT付费创作系统1.8.3独立版 + H5端 + 小程序前端安装测试教程