一直想用隐马可夫模型做图像识别,但是python的scikit-learn组件包的hmm module已经不再支持了,需要安装hmmlearn的组件,不过hmmlearn的多项式hmm每次出来的结果都不一样,= =||,难道是我用错了??后来又只能去参考网上C语言的组件,模仿着把向前向后算法“复制”到python里了,废了好大功夫,总算结果一样了o(╯□╰)o。。

把代码贴出来把,省的自己不小心啥时候删掉。。。

 #-*-coding:UTF-8-*-
'''
Created on 2014年9月25日
@author: Ayumi Phoenix
'''
import numpy as np class 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.0
for 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.0
for 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. Initialization
for 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. Induction
for t in range(T-1):
scale[t+1] = 0.0
for j in range(self.N):
sum = 0.0
for 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. Termination
for 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. Intialization
for i in range(self.N):
beta[T-1,i] = 1.0
# 2. Induction
for t in range(T-2,-1,-1):
for i in range(self.N):
sum = 0.0
for 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. Termination
pprob[0] = 0.0
for 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. Intialization
for i in range(self.N):
beta[T-1,i] = 1.0 # 2. Induction
for t in range(T-2,-1,-1):
for i in range(self.N):
sum = 0.0
for 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的路径I
def 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.0
for 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.0
for 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算法
# 输入 L个观察序列O,初始模型:HMM={A,B,pi,N,M}
def BaumWelch(self,L,T,O,alpha,beta,gamma):
print "BaumWelch"
DELTA = 0.01 ; round = 0 ; flag = 1 ; probf = [0.0]
delta = 0.0 ; deltaprev = 0.0 ; probprev = 0.0 ; ratio = 0.0 ; deltaprev = 10e-70 xi = 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 - step
for 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]/L
for j in range(self.N):
self.A[i,j] = 0.001/self.N + 0.999*numeratorA[i,j]/denominatorA[i]
numeratorA[i,j] = 0.0 for k in range(self.M):
self.B[i,k] = 0.001/self.M + 0.999*numeratorB[i,k]/denominatorB[i]
numeratorB[i,k] = 0.0 pi[i]=denominatorA[i]=denominatorB[i]=0.0; if flag == 1:
flag = 0
probprev = probf[0]
ratio = 1
continue delta = probf[0] - probprev
ratio = delta / deltaprev
probprev = probf[0]
deltaprev = delta
round += 1 if ratio <= DELTA :
print "num iteration ",round
break if __name__ == "__main__":
print "python my HMM" A = [[0.8125,0.1875],[0.2,0.8]]
B = [[0.875,0.125],[0.25,0.75]]
pi = [0.5,0.5]
hmm = HMM(A,B,pi) 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]) # T等于最长序列的长度就好了
alpha = np.zeros((T,hmm.N),np.float)
beta = np.zeros((T,hmm.N),np.float)
gamma = np.zeros((T,hmm.N),np.float)
hmm.BaumWelch(L,T,O,alpha,beta,gamma) hmm.printhmm()

由于为了自己理解方便,直接翻译公式。。。其实可以用numpy的函数写的简单点的O(∩_∩)O

使用python实现HMM的更多相关文章

  1. Python实现HMM(隐马尔可夫模型)

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

  2. HMM代码实现

    按照网上的代码,自己敲了一下,改了一点点,理解加深了一下. 还有训练HMM的EM算法没看懂,下次接着看: 参考连接:http://www.cnblogs.com/hanahimi/p/4011765. ...

  3. ghmm在 Linux 上安装

    ghmm在 Linux 上安装 http://ghmm.sourceforge.net/documentation.html http://www.ghmm.org http://www.comp.l ...

  4. NLTK和jieba这两个python的自然语言包(HMM,rnn,sigmoid

    HMM(Hidden Markov Model,隐马尔可夫模型) CRF(Conditional Random Field,条件随机场), RNN深度学习算法(Recurrent Neural Net ...

  5. 隐马尔科夫模型 介绍 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 ...

  6. 自制基于HMM的python中文分词器

    不像英文那样单词之间有空格作为天然的分界线, 中文词语之间没有明显界限.必须采用一些方法将中文语句划分为单词序列才能进一步处理, 这一划分步骤即是所谓的中文分词. 主流中文分词方法包括基于规则的分词, ...

  7. HMM 隐马尔科夫 Python 代码

    import numpy as np # -*- codeing:utf-8 -*- __author__ = 'youfei' # 隐状态 hidden_state = ['sunny', 'rai ...

  8. HMM算法python实现

    基础介绍,后5项为基础5元素 Q = ['q0', 'q1', 'q2', 'q3'] # 状态集合 States,共 N 种状态 V = ['v0', 'v1'] # 观测集合 Observatio ...

  9. 结巴分词3--基于汉字成词能力的HMM模型识别未登录词

    作者:zhbzz2007 出处:http://www.cnblogs.com/zhbzz2007 欢迎转载,也请保留这段声明.谢谢! 1 算法简介 在 结巴分词2--基于前缀词典及动态规划实现分词 博 ...

随机推荐

  1. xml基础小结

    XML基础 1)XML的作用 1.1 作为软件配置文件 1.2 作为小型的“数据库” 2)XML语法(由w3c组织规定的) 标签: 标签名不能以数字开头,中间不能有空格,区分大小写.有且仅有一个根标签 ...

  2. 推荐一个可视化的学习Git的好网站:LearnGitBranching

    博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:推荐一个可视化的学习Git的好网站:LearnGitBranching.

  3. centos7 搭建 docker 环境

    1. 安装centos7  http://isoredirect.centos.org/centos/7/isos/x86_64/ 下载 everything 版本,最小化版本可能缺失很多东西 我是在 ...

  4. POJ 1006 Biorhythms(中国剩余定理)

    题目地址:POJ 1006 学习了下中国剩余定理.參考的该博客.博客戳这里. 中国剩余定理的求解方法: 假如说x%c1=m1,x%c2=m2,x%c3=m3.那么能够设三个数R1,R2,R3.R1为c ...

  5. Glossary of Terms in the JavaTM platform --reference

    http://docs.oracle.com/javase/tutorial/information/glossary.html field :A data member of a class. Un ...

  6. JavaScript与html5写的贪吃蛇完整代码

    JavaScript与html5写的贪吃蛇完整代码 查看运行效果可访问http://www.codesocang.com/texiao/youxitexiao/2014/0402/7045.html# ...

  7. Hadoop 2.6.3动态增加/删除DataNode节点

    假设集群操作系统均为:CentOS 6.7 x64 Hadoop版本为:2.6.3 一.动态增加DataNode 1.准备新的DataNode节点机器,配置SSH互信,可以直接复制已有DataNode ...

  8. HttpWebRequest结合HtmlAgilityPack实现网页form提交

    年前一个项目,需要在某个系统实现系统自动操作. 系统页面使用form提交,页面参数较多,也参数设计一系列计算逻辑,改动一个值,其他值自动改变. 传统方法使用正则表达式匹配参数,构建post参数进行请求 ...

  9. Sql Server 2008 还原数据库 3154错误

    sqlserver2008还原数据库时出现了3154错误,具体错误信息如下: 错误信息 The backup set holds a backup of a database other than t ...

  10. A题笔记(5)

    No. 1385 挤牛奶问题 Tips: 查找之前对数据进行一下排列会比较好; 两个“最长”放在一趟遍历里查找. class LT { public: int bt; int ct; int dura ...