【机器学习】隐马尔可夫模型及其三个基本问题(三)模型参数学习算法及python实现

  • 一、一些概率与期望值的计算
  • 二、非监督学习方法(Baum-Welch算法)
  • 三、python实现

隐马尔可夫模型参数学习是根据观测序列 X={x1,x2,⋯ ,xn}X = \left\{ {{x_1},{x_2}, \cdots ,{x_n}} \right\}X={x1​,x2​,⋯,xn​}来估计模型 λ=[A,B,∏]\lambda = \left[ {A,B,\prod } \right]λ=[A,B,∏]。根据训练数据是包括观测序列和对应的状态序列还是只有观测序列,可以分为监督学习和非监督学习(参考资料1)。因为监督学习需要人工标注训练数据代价较高,因此本博文只介绍非监督学习。

一、一些概率与期望值的计算

(1)给定模型λ\lambdaλ和观测序列XXX,在ttt时刻处于状态qiq_iqi​的概率,记为γt(i)=P(it=qi∣X,λ){\gamma _t}(i) = P\left( {{i_t} = {q_i}\left| {X,\lambda } \right.} \right)γt​(i)=P(it​=qi​∣X,λ)

γt(i)=P(it=qi∣X,λ)=P(it=qi,X∣λ)P(X∣λ){\gamma _t}(i) = P\left( {{i_t} = {q_i}\left| {X,\lambda } \right.} \right) = \frac{{P\left( {{i_t} = {q_i},X\left| \lambda \right.} \right)}}{{P\left( {X\left| \lambda \right.} \right)}}γt​(i)=P(it​=qi​∣X,λ)=P(X∣λ)P(it​=qi​,X∣λ)​

由前向概率αt(i){\alpha _t}(i)αt​(i)和后向概率βt(i){\beta _t}(i)βt​(i)定义可知:

γt(i)=αt(i)βt(i)∑j=1Nαt(j)βt(j){\gamma _t}(i) = \frac{{{\alpha _t}(i){\beta _t}(i)}}{{\sum\limits_{j = 1}^N {{\alpha _t}(j){\beta _t}(j)} }}γt​(i)=j=1∑N​αt​(j)βt​(j)αt​(i)βt​(i)​

(2)给定模型λ\lambdaλ和观测序列XXX,在ttt时刻处于状态qiq_iqi​且t+1t+1t+1时刻处于状态qjq_jqj​的概率,记为
ξt(i,j)=P(it=qi,it+1=qj∣X,λ){\xi _t}(i,j) = P\left( {{i_t} = {q_i},{i_{t + 1}} = {q_j}\left| {X,\lambda } \right.} \right)ξt​(i,j)=P(it​=qi​,it+1​=qj​∣X,λ)

由前向概率αt(i){\alpha _t}(i)αt​(i)和后向概率βt(i){\beta _t}(i)βt​(i)计算:

ξt(i,j)=αt(i)aijbj(xt+1)βt+1(j)∑i=1N∑j=1Nαt(i)aijbj(xt+1)βt+1(j){\xi _t}(i,j) = \frac{{{\alpha _t}(i){a_{ij}}{b_j}({x_{t + 1}}){\beta _{t + 1}}(j)}}{{\sum\limits_{i = 1}^N {\sum\limits_{j = 1}^N {{\alpha _t}(i){a_{ij}}{b_j}({x_{t + 1}}){\beta _{t + 1}}(j)} } }}ξt​(i,j)=i=1∑N​j=1∑N​αt​(i)aij​bj​(xt+1​)βt+1​(j)αt​(i)aij​bj​(xt+1​)βt+1​(j)​

(3)一些有用的期望:
在观测序列XXX下状态iii出现的期望值为:∑t=1nγt(i)\sum\limits_{t = 1}^n {{\gamma _t}(i)}t=1∑n​γt​(i)
在观察序列XXX下状态iii转移的期望值为:∑t=1n−1γt(i)\sum\limits_{t = 1}^{n - 1} {{\gamma _t}(i)}t=1∑n−1​γt​(i)
在观察序列XXX下由状态iii转移到状态jjj的期望值为:∑t=1n−1ξt(i,j)\sum\limits_{t = 1}^{n - 1} {{\xi _t}(i,j)}t=1∑n−1​ξt​(i,j)

二、非监督学习方法(Baum-Welch算法)

本博文不涉及Baum-Welch算法的推导过程,如有需要可以参考资料1。

Baum-Welch算法
输入:观测序列X={x1,x2,⋯ ,xn}X = \left\{ {{x_1},{x_2}, \cdots ,{x_n}} \right\}X={x1​,x2​,⋯,xn​}
输出:隐马尔可夫模型参数λ=[A,B,∏]\lambda = \left[ {A,B,\prod } \right]λ=[A,B,∏]
(1)初始化
迭代次数m = 0时,初始化参数aij(0)a_{ij}^{(0)}aij(0)​,bik(0)b_{ik}^{(0)}bik(0)​,πi(0)\pi _i^{(0)}πi(0)​, 初始化模型λ(0)=[A(0),B(0),∏(0)]{\lambda ^{(0)}} = \left[ {{A^{(0)}},{B^{(0)}},{\prod ^{(0)}}} \right]λ(0)=[A(0),B(0),∏(0)]
(2)递推,m=1,2,⋯m = 1,2, \cdotsm=1,2,⋯

aijm+1=∑t=1n−1ξt(i,j)∑t=1n−1γt(i)a_{ij}^{m + 1} = \frac{{\sum\limits_{t = 1}^{n - 1} {{\xi _t}(i,j)} }}{{\sum\limits_{t = 1}^{n - 1} {{\gamma _t}(i)} }}aijm+1​=t=1∑n−1​γt​(i)t=1∑n−1​ξt​(i,j)​

bjkm+1=∑t=1,xt=vknγt(j)∑t=1nγt(j)b_{jk}^{m + 1} = \frac{{\sum\limits_{t = 1,{x_t} = {v_k}}^n {{\gamma _t}(j)} }}{{\sum\limits_{t = 1}^n {{\gamma _t}(j)} }}bjkm+1​=t=1∑n​γt​(j)t=1,xt​=vk​∑n​γt​(j)​

πim+1=γ1(i)\pi _i^{m + 1} = {\gamma _1}(i)πim+1​=γ1​(i)

上面三个公式的右侧值都是由观测序列和模型λ(m)=[A(m),B(m),∏(m)]{\lambda ^{(m)}} = \left[ {{A^{(m)}},{B^{(m)}},{\prod ^{(m)}}} \right]λ(m)=[A(m),B(m),∏(m)]计算。

(3)终止。
得到模型 λ(m+1)=[A(m+1),B(m+1),∏(m+1)]{\lambda ^{(m+1)}} = \left[ {{A^{(m+1)}},{B^{(m+1)}},{\prod ^{(m+1)}}} \right]λ(m+1)=[A(m+1),B(m+1),∏(m+1)]

三、python实现

代码参考资料2.

import numpy as npclass HMM:def __init__(self, A, B, Pi, O):self.A = np.array(A)  # 状态转移概率矩阵self.B = np.array(B)  # 观测概率矩阵self.Pi = np.array(Pi) # 初始状态概率矩阵self.O =  np.array(O)  # 观测序列self.N = self.A.shape[0] # 状态取值个数self.M = self.B.shape[1] # 观测值取值个数## 1. 前向算法def forward(self):n = len(self.O) #观测序列长度alpha = np.zeros((n,self.N)) # 初始化所有alpha值# 计算初始值for i in range(self.N):alpha[0,i] = self.Pi[i] * self.B[i,self.O[0]]# 递推for t in range(n-1):for i in range(self.N):summation = 0 for j in range(self.N):summation += alpha[t,j] * self.A[j,i]alpha[t+1,i] = summation * self.B[i,self.O[t+1]]# 终止Polambda = 0.0 # 在模型确定的情况下观测序列概率for i in range(self.N):Polambda += alpha[n-1,i]return Polambda,alpha## 2. 后向算法def backward(self):n = len(self.O) #观测序列长度beta = np.zeros((n,self.N)) # 初始化所有beta值# 计算初始值for i in range(self.N):beta[n-1,i] = 1.0# 递推for t in range(n-2,-1,-1):for i in range(self.N):summation = 0.0     # for every i 'summation' should reset to '0'for j in range(self.N):summation += self.A[i,j] * self.B[j, self.O[t+1]] * beta[t+1,j]beta[t,i] = summation# 终止Polambda = 0.0for i in range(self.N):Polambda += self.Pi[i] * self.B[i, self.O[0]] * beta[0, i]return Polambda,beta## 3.计算概率gamma和zetadef compute_gamma(self,alpha,beta):T = len(self.O)gamma = np.zeros((T, self.N))       # the probability of Ot=qfor t in range(T):for i in range(self.N):gamma[t, i] = alpha[t,i] * beta[t,i] / sum(alpha[t,j] * beta[t,j] for j in range(self.N) )return gammadef compute_zeta(self,alpha,beta):T = len(self.O)zeta = np.zeros((T-1, self.N, self.N))  # note that: not Tfor t in range(T-1):   # note: not Tfor i in range(self.N):for j in range(self.N):numerator = alpha[t,i] * self.A[i,j] * self.B[j,self.O[t+1]] * beta[t+1,j]denominator = sum( sum( alpha[t,i1] * self.A[i1,j1] * self.B[j1,self.O[t+1]] * beta[t+1,j1] for j1 in range(self.N) )   # the second sumfor i1 in range(self.N) )    # the first sumzeta[t,i,j] = numerator / denominatorreturn zeta## 4.Baum-Welch算法def Baum_Welch(self):T = len(self.O)V = [k for k in range(self.M)]m = 1  ## 递推指数while m < 10:  # xPolambda1, alpha = self.forward()           # get alphaPolambda2, beta = self.backward()            # get betagamma = self.compute_gamma(alpha,beta)     # use alpha, betaxi = self.compute_zeta(alpha,beta)# 更新状态转移矩阵Afor i in range(self.N):for j in range(self.N):numerator = sum(xi[t,i,j] for t in range(T-1))denominator = sum(gamma[t,i] for t in range(T-1))self.A[i, j] = numerator / denominator# 更新输出观测矩阵Bfor j in range(self.N):for k in range(self.M):numerator = sum(gamma[t,j] for t in range(T) if self.O[t] == V[k] )  # TBDdenominator = sum(gamma[t,j] for t in range(T))self.B[i, k] = numerator / denominator# 更新初始状态概率分布矩阵for i in range(self.N):self.Pi[i] = gamma[0,i]m += 1return self.A,self.B,self.Piif __name__ == '__main__':print('----------------1.初始化HMM模型参数------------------')A = [[0,1,0,0],[0.4,0,0.6,0],[0,0.4,0,0.6],[0,0,0.5,0.5]]B = [[0.5,0.5],[0.3,0.7],[0.6,0.4],[0.8,0.2]]Pi = [0.25,0.25,0.25,0.25]print('----------------2.观测序列---------------------------')O = [0,1,0]print('----------------3.Baum-Welch算法---------------------')hmm = HMM(A,B,Pi,O)A1,B1,Pi_1 = hmm.Baum_Welch()

参考资料
1、《统计学习方法》李航
2、https://www.cnblogs.com/d-roger/articles/5719979.html

【机器学习】隐马尔可夫模型及其三个基本问题(三)模型参数学习算法及python实现相关推荐

  1. 机器学习——隐马尔科夫(HHM)原理

    机器学习--隐马尔科夫(HHM)模型原理 1 从马尔科夫模型到隐马尔科夫模型 1.1 马尔科夫过程引入 首先,我们先给出一张图: 在上面的图里,给出的是一个链式的结构,结构中的每一个节点称之为一个状态 ...

  2. 机器学习-隐马尔科夫python实现及数学原理讲解

    文章目录 1. 隐马尔科夫 2. 直观分析 3. 数学原理 4. 实现 4.1 代码 1. 隐马尔科夫   隐马尔可夫模型(hidden Markov model,HMM)是关于时序的概率模型,描述由 ...

  3. 【机器学习】隐马尔可夫模型

    点击上方蓝色字体,关注AI小白入门哟 跟着博主的脚步,每天进步一点点 本文介绍了隐马尔可夫模型,首先介绍了隐马尔科夫模型定义,核心思想是引入了隐状态序列(引入隐状态是所有隐因子模型最巧妙的地方,如:隐 ...

  4. 机器学习笔记之隐马尔可夫模型(六)解码问题

    机器学习笔记之隐马尔可夫模型--解码问题 引言 解码问题介绍 解码问题分析 引言 上一节介绍了使用狭义EM算法对模型参数λ\lambdaλ.本节将介绍使用维特比算法(Viterbi)处理解码问题(De ...

  5. 机器学习算法总结(七)——隐马尔科夫模型(前向后向算法、鲍姆-韦尔奇算法、维特比算法)...

    概率图模型是一类用图来表达变量相关关系的概率模型.它以图为表示工具,最常见的是用一个结点表示一个或一组随机变量,结点之间的变表是变量间的概率相关关系.根据边的性质不同,可以将概率图模型分为两类:一类是 ...

  6. 机器学习算法拾遗:(七)隐马尔科夫模型(前向后向算法、鲍姆-韦尔奇算法、维特比算法)

    1.隐马尔科夫模型HMM 隐马尔科夫模型的图结构如下 从上图中主要有两个信息:一是观测变量xi 仅仅与与之对应的状态变量yi 有关:二是当前的状态变量yi 仅仅与它的前一个状态变量yi-1 有关. 隐 ...

  7. 机器学习中隐马尔可夫模型(Hidden Markov Model, HMM)理论

    隐马尔可夫模型(Hidden Markov Model, HMM) 前言 :内容从实际案例到模型提取.建立.求解以及应用,侧重于该模型在机器学习中的研究和应用. 参考书: <统计学习方法> ...

  8. python手势识别隐马尔可夫模型_手势识别身份认证的连续隐马尔可夫模型

    2018 收稿日期 :2017 - 03 - 18 收修改稿日期 :2017 - 04 - 25 基金项目 : 国家自然科学基金项目 (61373126) 资助 ; 中央高校基本科研业务费专项基金 项 ...

  9. 隐马尔科夫模型(前向后向算法、鲍姆-韦尔奇算法、维特比算法)

    隐马尔科夫模型(前向后向算法.鲍姆-韦尔奇算法.维特比算法) 概率图模型是一类用图来表达变量相关关系的概率模型.它以图为表示工具,最常见的是用一个结点表示一个或一组随机变量,结点之间的变表是变量间的概 ...

  10. (转载)机器学习知识点(十一)隐马尔可夫模型

           隐马尔可夫模型 (Hidden Markov Model,HMM) 最初由 L. E. Baum 和其它一些学者发表在一系列的统计学论文中,随后在语言识别,自然语言处理以及生物信息等领域 ...

最新文章

  1. 【Android 逆向】arm 汇编 ( 使用 IDA 解析 arm 架构的动态库文件 | 使用 IDA 打开 arm 动态库文件 | 切换 IDA 中汇编代码显示样式 )
  2. 课程三(Structuring Machine Learning Projects),第二周(ML strategy(2)) —— 0.Learning Goals...
  3. c语言设计成行考核答案,20秋广东开放大学C语言程序设计成性考核参考答案(10页)-原创力文档...
  4. less中的for循环
  5. ceph Luminous版手动安装零散记录
  6. 【2021.02.09更新】数字信号处理公式推导
  7. php把数据创建一个表格,PHP创建(导出Excel数据表格)
  8. (step4.3.1) hdu 1010(Tempter of the Bone——DFS)
  9. 读写文件--with open
  10. 洛谷P4782 2-SAT问题
  11. 小秘书的福音——使用Word VBA打造自动排版工具
  12. chrome控制台出现/null访问
  13. Android Studio入门级教程(详细)【小白必看】
  14. java日期 国际化_java中国际化的时间处理
  15. css设置文字外发光
  16. 线上教学软件哪个平台好?
  17. img标签前面加冒号:src和src的区别
  18. 宝塔linux开启缓存,宝塔面板缓存在哪里
  19. bzoj 3398: [Usaco2009 Feb]Bullcow 牡牛和牝牛
  20. python批量删除文件中多余的空行

热门文章

  1. STL - MainTao - 博客园
  2. MatLab 2014a编译jar包时mcc无法使用的问题
  3. 图片-标签、格式\内联框架\音视频播放——HTML
  4. 集成学习-蒸汽量预测案例
  5. Scala学习(一、环境配置和基础)
  6. 开源linux 二进制工具,又一款开源好物:逐字节分析的二进制数据分析工具bitinsight...
  7. cad字体hztxt用什么代替_为什么CAD的字体库相同但打开图纸的效果却不同?
  8. 迪杰斯特拉算法 php,最短路径算法
  9. at指令代码 stm32f030_汇编语言程序设计第二篇——80X86汇编语言伪指令
  10. R语言︱用excel VBA把xlsx批量转化为csv格式