HMM代码实现
按照网上的代码,自己敲了一下,改了一点点,理解加深了一下。
还有训练HMM的EM算法没看懂,下次接着看;
参考连接:http://www.cnblogs.com/hanahimi/p/4011765.html
- # -*- coding: utf-8 -*-
- '''
- function: 根据网上的代码,学习实现 HMM,前向计算概率,后向预测状态序列,学习算法参数
- date: 2017.8.9
- '''
- import numpy as np
- class HMM(object):
- """docstring Ann, Bnm, piln HMM"""
- def __init__(self, Ann, Bnm, piln):
- self.A = Ann
- self.B = Bnm
- self.pi = piln
- self.N = self.A.shape[0] #状态的种类个数
- self.M = self.B.shape[1] #观测序列的长度
- #打印hmm的信息
- 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('========================================')
- '''
- function: 维特比算法
- input: A,B,pi,O
- output: P(o|lambda) 最大的时候,状态的路径序列
- '''
- def viterbi(self, O):
- T = len(O) #观察序列的长度
- #初始化,这里从0~T-1
- #delta t行 n列,代表有t个时间点,每个时间点可能有n种状态
- delta = np.zeros((T, self.N), np.float) #二维数组记录计算的所有概率,包括了最有的点
- phi = np.zeros((T, self.N), np.int) #记录概率最大路径的前一个状态
- I = np.zeros(T, np.int) #这里如果不显示表明类型为 np.int,就是float?
- for i in range(self.N):
- delta[0,i] = self.pi[i] * self.B[i,O[0]] #t = 0时刻,各个状态的起始概率
- phi[0,i] = 0 #t=0时刻前缀状态都是0
- #递推
- for t in range(1,T): #从 1 开始
- 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() #T-1时刻是最后时刻,哪个状态在最后时刻概率最大就是最优路径的起始点
- I[T-1] = phi[T-1,:].argmax() #最优路径的起点状态编号
- #状态序列获取
- for t in range(T-2, -1, -1): #从 T-1 到 -1(不包括-1),间隔是-1,即递减
- I[t] = phi[t+1, I[t+1]]
- return I, prob
- '''
- function: 前向算法计算擦观察序列 O 出现的概率
- input: A,B,pi,O
- output: prob
- '''
- def forward(self, O):
- T = len(O)
- alpha = np.zeros((T, self.N), np.float) #暂存计算的所有概率,按照时间点向前推进
- #初始化
- for i in range(self.N):
- alpha[0,i] = self.pi[i] * self.B[i, O[0]]
- #迭代计算
- for t in range(T-1):
- for i in range(self.N): #这里B[i,O[t]]也可以放在for的外面乘
- alpha[t+1,i] = np.array([alpha[t, j]*self.A[j,i]*self.B[i,O[t+1]] for \
- j in range(self.N)]).sum()
- #终止
- prob = np.array([alpha[T-1, j] for j in range(self.N)]).sum()
- return prob
- '''
- function: 后向算法,计算观测序列出现的概率
- '''
- def backword(self, O):
- T = len(O)
- beta = np.zeros((T, self.N), np.float) #暂存计算的概率
- #初始化
- for i in range(self.N):
- beta[T-1, i] = 1 #从后向前
- #迭代计算
- for t in range(T-2, -1, -1):
- for i in range(self.N):
- beta[t,i] = np.array([[A[j,i] * B[j,O[t+1]] * beta[t+1,j]] for \
- j in range(self.N)]).sum()
- prob = np.array([self.pi[j] * self.B[i,O[1]] * beta[1,j] for j in range(self.N)]).sum()
- return prob
- if __name__ == 'main':
- print('python my HMM')
- #HMM模型的参数
- A = [[0.8125,0.1875],[0.2,0.8]]
- B = [[0.875,0.125], [0.25,0.75]] #每一行的和是 1
- pi = [0.5,0.5]
- hmm = HMM(A,B,pi) #构建HMM
- print(hmm)
- print('python my HMM')
- #HMM模型的参数
- A = np.mat([[0.8125,0.1875],[0.2,0.8]])
- B = np.mat([[0.875,0.125], [0.25,0.75]]) #每一行的和是 1
- pi = [0.5,0.5]
- 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]]
- hmm = HMM(A,B,pi) #构建HMM
- #计算前向概率,产生特定观测序列O的概率
- prob = hmm.forward(O[0])
- print('前向算法产生 O 序列的概率是: ' + str(prob))
- #后向算法计算观测序列的概率
- prob = hmm.backword(O[0])
- print('后向算法概率是: ' + str(prob))
- #计算隐含概率,维特比算法
- path, prob2 = hmm.viterbi(O[0])
- print('产生 O 序列最大概率路径是: ' + str(path))
- print('概率是: ' + str(prob2))
- hmm.printHmm()
HMM代码实现的更多相关文章
- HMM代码实践
本文主要转载于:http://www.52nlp.cn/hmm-learn-best-practices-eight-summary 这个文章是边看边实践加上自己的一些想法生成的初稿..... 状态转 ...
- Python实现HMM(隐马尔可夫模型)
1. 前言 隐马尔科夫HMM模型是一类重要的机器学习方法,其主要用于序列数据的分析,广泛应用于语音识别.文本翻译.序列预测.中文分词等多个领域.虽然近年来,由于RNN等深度学习方法的发展,HMM模型逐 ...
- 浅谈分词算法(4)基于字的分词方法(CRF)
目录 前言 目录 条件随机场(conditional random field CRF) 核心点 线性链条件随机场 简化形式 CRF分词 CRF VS HMM 代码实现 训练代码 实验结果 参考文献 ...
- 隐型马尔科夫模型(HMM)向前算法实例讲解(暴力求解+代码实现)---盒子模型
先来解释一下HMM的向前算法: 前向后向算法是前向算法和后向算法的统称,这两个算法都可以用来求HMM观测序列的概率.我们先来看看前向算法是如何求解这个问题的. 前向算法本质上属于动态规划的算法,也就是 ...
- 隐马尔科夫模型 介绍 HMM python代码
#HMM Forward algorithm #input Matrix A,B vector pi import numpy as np A=np.array([[0.5,0.2,0.3],[0.3 ...
- HMM 隐马尔科夫 Python 代码
import numpy as np # -*- codeing:utf-8 -*- __author__ = 'youfei' # 隐状态 hidden_state = ['sunny', 'rai ...
- 一文搞懂HMM(隐马尔可夫模型)
什么是熵(Entropy) 简单来说,熵是表示物质系统状态的一种度量,用它老表征系统的无序程度.熵越大,系统越无序,意味着系统结构和运动的不确定和无规则:反之,,熵越小,系统越有序,意味着具有确定和有 ...
- [综]隐马尔可夫模型Hidden Markov Model (HMM)
http://www.zhihu.com/question/20962240 Yang Eninala杜克大学 生物化学博士 线性代数 收录于 编辑推荐 •2216 人赞同 ×××××11月22日已更 ...
- [原创]java WEB学习笔记66:Struts2 学习之路--Struts的CRUD操作( 查看 / 删除/ 添加) 使用 paramsPrepareParamsStack 重构代码 ,PrepareInterceptor拦截器,paramsPrepareParamsStack 拦截器栈
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
随机推荐
- MySQL的order by子句
1.语法:select 字段列表 from 表名 [where 子句][group by 子句][having 子句][order by 子句]; 注解: 1.默认是从第一条记录开始升序, 2.des ...
- Laravel 5.1 Blade模板引擎
为什么要使用blade 它是干什么用的? blade模板引擎使我们写HTML页面的地方,使用它是因为它能给我们提供很多的遍历,减少代码的重复率 提高开发效率.我们写blade的路径是 resource ...
- ios中的coredata
本文转载至 http://blog.csdn.net/chen505358119/article/details/9334831 分类: ios2013-07-15 18:12 12449人阅读 评论 ...
- ASP.NET中RegisterStartupScript和RegisterClientScriptBlock有区别吗
今天用RegisterClientScriptBlock()方法调用了alertify.js(绚丽的实现alert()同样的提示功能): Page.ClientScript.RegisterClien ...
- Balala Power!(大数+思维)
Balala Power! Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)T ...
- NPOI操作Excel常用函数
最近因项目接触了NPOI,感觉还是蛮不错的,网络上的教程普遍版本较老,本篇记录所常用操作,采用NPOI 2.0版本. 推荐: NPOI官方网站 NPOI 1.2.4/1.2.5 官方教程 新建Exce ...
- Xamarin.Forms学习之Page Navigation(二)
在上一篇的文章中,对页面常规的导航做一些分享,然而在实际的编程中,页面数据的保持,传值等等都有很多,这篇文章就对这些相关内容做一个分享和记录,有问题,希望大家留言指正.这一篇从实现业务逻辑来讲并没有什 ...
- 初学习-python打印乘法表、正方形、三角形
for x in range(1,4): for o in range(0,x-1): print('*',end='') pass pass print('*') print('\n')print( ...
- git的安装-环境变量配置
windows安装git和环境变量配置 2015.10.12 评论(0) 10,729 点此嗨一下 Git是一款免费.开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目. Git是一个开源 ...
- Redis作者谈Redis应用场景(转)
add by zhj : 这是Redis的作者antirez在他的技术博客中写的一篇文章 英文原文:take-advantage-of-redis-adding-it-to-your-stack 译文 ...