LogoLogo
  • README
  • 前端编程
    • 01 Node JS
    • 02-ES6详解
    • 03-NPM详解
    • 04-Babel详解
    • 05-前端模块化开发
    • 06-WebPack详解
    • 07-Vue详解
    • 08-Git详解
    • 09-微信小程序
  • 人工智能
    • 机器学习
      • 二次分配问题
      • 非负矩阵
      • 概率潜在语义分析
      • 概率图模型
      • 集成学习
      • 降维
      • 距离度量
      • 决策树
      • 逻辑回归
      • 马尔可夫决策过程
      • 马尔可夫链蒙特卡洛法
      • 朴素贝叶斯法
      • 谱聚类
      • 奇异值分解
      • 潜在狄利克雷分配
      • 潜在语义分析
      • 强化学习
      • 社区算法
      • 时间序列模型
      • 特征工程
      • 条件随机场
      • 图论基础
      • 线性分类
      • 线性回归
      • 信息论中的熵
      • 隐马尔科夫模型
      • 支持向量机
      • 主成分分析
      • EM算法
      • Hermite 矩阵的特征值不等式
      • k-means聚类
      • k近邻法
      • PageRank算法
    • 深度学习
      • Pytorch篇
        • 01-线性模型
        • 02-梯度下降法
        • 03-反向传播
        • 04-pytorch入门
        • 05-用pytorch实现线性回归
        • 06-logistic回归
        • 07-处理多维特征的输入
        • 08-加载数据集
        • 09-多分类问题
        • 10-卷积神经网络
        • 11-循环神经网络
    • 图神经网络
      • 图神经网络笔记01
        • 01-图(Graphs)的结构
        • 02-网络的性质和随机图模型
        • 03-网络工具
        • 04-网络中的主题和结构角色
        • 05-网络中的社区结构
      • 图神经网络笔记02
        • 01-深度学习引言
        • 02-神经网络基础
        • 03-卷积神经网络
        • 04-图信号处理与图卷积神经网络
        • 05-GNN的变体与框架-
        • [06-Google PPRGo 两分钟分类千万节点的最快GNN](人工智能/图神经网络/图神经网络笔记02/06-Google%20PPRGo 两分钟分类千万节点的最快GNN.md)
        • 07-序列模型
        • 08-变分自编码器
        • 09-对抗生成网络
  • 日常记录
    • 健身日记
    • 面经记录
    • 自动生成Summary文件
  • 实战项目
    • 谷粒商城
      • 00-项目概述
      • 01-分布式基础-全栈开发篇
      • 02-分布式高级-微服务架构篇
      • 03-高可用集群-架构师提升篇
  • 数据库
    • MySQL笔记
      • 01-MySQL基础篇
      • 02-MySQL架构篇
      • 03-MySQL索引及调优篇
      • 04-MySQL事务篇
      • 05-MySQL日志与备份篇
    • Redis笔记
      • 01-Redis基础篇
      • 02-Redis高级篇
    • 02-Redis篇
  • 算法笔记
    • 01-算法基础篇
    • 02-算法刷题篇
  • 职能扩展
    • 产品运营篇
  • Go编程
    • 01-Go基础
      • 01-Go基础篇
  • Java编程
    • 01-Java基础
      • 01-Java基础篇
      • 02-多线程篇
      • 03-注射与反解篇
      • 04-JUC并发编程篇
      • 05-JUC并发编程与源码分析
      • 06-JVM原理篇
      • 07-Netty原理篇
      • 08-设计模式篇
    • 02 Java Web
      • 01-Mybatis篇
      • 01-Mybatis篇(新版)
      • 02-Spring篇
      • 02-Spring篇(新版)
      • 03-SpringMVC篇
      • 04-MybatisPlus篇
    • 03-Java微服务
      • 01-SpringBoot篇
      • 01-SpringBoot篇(新版)
      • 02-SpringSecurity篇
      • 03-Shiro篇
      • 04-Swagger篇
      • 05-Zookeeper篇
      • 06-Dubbo篇
      • 07-SpringCloud篇
      • 08-SpringAlibaba篇
      • 09-SpringCloud篇(新版)
    • 04-Java中间件
      • 数据库篇
        • 01-分库分表概述
        • 02-MyCat篇
        • 03-MyCat2篇
        • 04-Sharding-jdbc篇
        • 05-ElasticSearch篇
      • 消息中间件篇
        • 01-MQ概述
        • 02-RabbitMQ篇
        • 03-Kafka篇
        • 04-RocketMQ篇
        • 05-Pulsar篇
    • 05-扩展篇
      • Dubbo篇
      • SpringBoot篇
      • SpringCloud篇
    • 06-第三方技术
      • 01-CDN技术篇
      • 02-POI技术篇
      • 03-第三方支付技术篇
      • 04-第三方登录技术篇
      • 05-第三方短信接入篇
      • 06-视频点播技术篇
      • 07-视频直播技术篇
    • 07-云原生
      • 01-Docker篇
      • 02-Kubernetes篇
      • 03-Kubesphere篇
  • Linux运维
    • 01-Linux篇
    • 02-Nginx篇
  • Python编程
    • 01-Python基础
      • 01.配置环境
      • 02.流程控制
      • 03.数值
      • 04.操作符
      • 05.列表
      • 06.元祖
      • 07.集合
      • 08.字典
      • 09.复制
      • 10.字符串
      • 11.函数
      • 12.常见内置函数
      • 13.变量
      • 14.异常和语法错误
      • 15.时间和日期
      • 16.正则表达式
    • 02 Python Web
      • flask篇
        • 01.前言
        • 02.路由
        • 03.模板
        • 04.视图进阶
        • 05.flask-sqlalchemy
        • 06.表单WTForms
        • 07.session与cookie
        • 08.上下文
        • 09.钩子函数
        • 10.flask 信号
        • 11.RESTFUL
        • 13.flask-mail
        • 14.flask+celery
        • 15.部署
        • 16.flask-login
        • 17.flask-cache
        • 18.flask-babel
        • 19.flask-dashed
        • 20.flask-pjax
        • 21.flask上传文件到第三方
        • 22.flask-restless
        • 23.flask-redis
        • 24.flask-flash
        • 25.消息通知
        • 26.分页
    • 03-Python数据分析
      • Matplotlib
      • Numpy
      • Pandas
      • Seaborn
    • 04-Python爬虫
      • 1.准备工作
      • 2.请求模块的使用
      • 3.解析模块的使用
      • 4.数据存储
      • 5.识别验证码
      • 6.爬取APP
      • 7.爬虫框架
      • 8.分布式爬虫
由 GitBook 提供支持
在本页
  • 基本概念​
  • 用途​
  • 前提
  • 随机变量
  • 随机过程
  • 马尔可夫链/过程
  • 状态空间模型
  • 马尔可夫奖励过程
  • 模型定义​
  • 概率计算问题
  • 直接计算法
  • 前向算法
  • 后向算法
  • 其他概率与期望值的计算
  • 学习问题
  • 监督学习算法
  • 非监督学习算法: $Baum-Welch$算法
  • 预测算法
  • 维特比算法
  • 代码实现

这有帮助吗?

在GitHub上编辑
  1. 人工智能
  2. 机器学习

隐马尔科夫模型

基本概念​

隐马尔可夫模型是关于时序的概率模型,描述由一个隐藏的马尔可夫链随机生成不可观察的状态随机序列,再由各个状态生成一个观测而产生随机序列的过程。隐藏的马尔可夫链随机生成的状态的序列,称为状态序列;每个状态生成一个观测,而由此产生的观测的随机序列,称为观测序列。序列的每一个未知又可以看做是一个时刻。​

用途​

隐马尔科夫模型是可用于标注问题的统计学习模型,描述由隐藏的马尔可夫链随机生成观测序列的过程,属于生成模型。

前提

随机变量

随机变量(Random Variable),通常用大写字母来表示一个随机事件。比如看下面的例子:

$X$:河水是咸的;$Y$:井水是甜的

很显然,$X$与$Y$两个随机事件是没有关系的。也就是说和之间是相互独立的。记作:

X⊥YX \perp YX⊥Y

随机过程

对于一类随机变量来说,它们之间存在着某种关系。

比如: :表示在 时刻某支股票的价格,那么$S_{t+1}$和$S_t$之间一定是有关系的,至于具体什么样的关系,这里原先不做深究,但有一点可以确定,两者之间一定存在的一种关系。随着时间$t$的变化,可以写出下面的形式:

⋯St,St+1,St+2⋯\cdots S_t,S_{t+1},S_{t+2}\cdots⋯St​,St+1​,St+2​⋯

这样就生成了一组随机变量,它们之间存在着一种相当复杂的关系,也就是说,各个随机变量之间存在着关系,即不相互独立。由此,我们会把按照某个时间或者次序上的一组不相互独立的随机变量的这样一个整体作为研究对象。这样的话,也就引出了另外的一个概念:随机过程(Stochastic Process)。也就是说随机过程的研究对象不在是单个的随机变量,而是一组随机变量,并且这一组随机变量之间存在着一种非常紧密的关系(不相互独立)。记作:

{St}t=1∞\{S_t\}^{\infty}_{t=1}{St​}t=1∞​

马尔可夫链/过程

**马尔科夫链(Markov Chain)**即马尔可夫过程,是一种特殊的随机过程——具备马尔可夫性的随机过程。

  • 马尔可夫性:(Markov Property): 如果满足$P(S_{t+1}|S_t,S_{t-1}\cdots S_1)=P(S_{t+1}|S_t)$,即具备了马尔可夫性。简单来说, 和之间存在关系,和以前的时刻的没有关系,即只和“最近的状态” 有关系。

  • 现实例子:**下一个时刻仅依赖于当前时刻,跟过去无关。**比如:一个老师讲课,明天的讲课状态一定和今天的状态最有关系,和过去十年的状态基本就没关系了。

  • 最主要考量:为了简化计算。$P(S_{t+1}|S_t,S_{t-1}\cdots S_1)=P(S_{t+1}|S_t)$ ,如果$S_{t+1}$和 $S_t,S_{t-1}\cdots S_1$都有关系的话,计算就会太大了,可能造成无法计算。

状态空间模型

状态空间模型(State Space Model),常应用于 HMM,Kalman Filterm Particle Filter。在这里就是指马尔可夫链 + 观测变量,即Markov Chain + Obervation。

如上图所示,s1-s2-s3为马尔可夫链,a1, a2, a3为观测变量,以a2为例,a2只和s2有关和s1, s3无关。状态空间模型可以说是由马尔可夫链演化而来的模型。记作:

P(St+1∣St)=P(St+1∣S1,⋯ ,St)P(S_{t+1}|S_t) = P(S_{t+1}|S1,\cdots,S_t)P(St+1​∣St​)=P(St+1​∣S1,⋯,St​)

马尔可夫奖励过程

马尔可夫奖励过程(Markov Reward Process),即马尔可夫链+奖励,即:Markov Chain + Reward。如下图:

举个例子,比如说你买了一支股票,然后你每天就会有“收益”,当然了这里的收益是泛化的概念,收益有可能是正的,也有可能是负的,有可能多,有可能少,总之从今天的状态$S_t$到明天的状态 $s_{t+1}$,会有一个reward。记作:

Rs=E[Rt+1∣St]R_s = E[R_{t+1}|S_t]Rs​=E[Rt+1​∣St​]

模型定义​

隐马尔可夫模型由初始概率分布、状态转移概率分布以及观测概率分布确定。隐马尔可夫模型的形式定义如下:

​ 设$Q$是所有可能的状态集合,$V$是所有可能的观测集合。

Q={q1,q2,⋯ ,qN},V={v1,v2,⋯ ,vM}Q = \{q_1,q_2,\cdots,q_N\},V = \{v_1,v_2,\cdots,v_M\}Q={q1​,q2​,⋯,qN​},V={v1​,v2​,⋯,vM​}

其中,$N$是可能的状态数,$M$是可能的观测数。

​ $I$是长度为$T$的状态序列,$O$是对应的观测序列。

I=(i1,i2,⋯ ,iT),O=(o1,o2,⋯ ,oT)I = (i_1,i_2,\cdots,i_T),O = (o_1,o_2,\cdots,o_T)I=(i1​,i2​,⋯,iT​),O=(o1​,o2​,⋯,oT​)

​ $A$是状态转移概率矩阵:

A=[aij]N×NA = [a_{ij}]_{N\times N}A=[aij​]N×N​

其中,

aij=P(it+1=qj∣it=qi),i=1,2,⋯ ,N;j=1,2,⋯ ,Na_{ij} = P(i_{t+1}=q_j|i_t=q_i),i=1,2,\cdots,N;j=1,2,\cdots,Naij​=P(it+1​=qj​∣it​=qi​),i=1,2,⋯,N;j=1,2,⋯,N

是在时刻$t$处于状态$q_i$的条件下在时刻$t+1$转移到状态$q_j$的概率。

​ $B$是观测概率矩阵:

bj(k)=P(ot=vk∣it=qj),k=1,2,⋯ ,M;j=1,2,⋯ ,Nb_j(k)=P(o_t=v_k|i_t=q_j),k=1,2,\cdots,M;j=1,2,\cdots,Nbj​(k)=P(ot​=vk​∣it​=qj​),k=1,2,⋯,M;j=1,2,⋯,N

是在时刻$t$处于状态$q_j$的条件下生成观测$v_k$的概率。

​ $\pi$是初始状态概率向量:

π=(πi)\pi = (\pi_i)π=(πi​)

其中,

πi=P(i1=qi),i=1,2,⋯ ,N\pi_i = P(i_1=q_i),i=1,2,\cdots,Nπi​=P(i1​=qi​),i=1,2,⋯,N

是时刻$t=1$处于状态$q_i$的概率。

$(i)$ 隐马尔可夫模型$\lambda = (\pi,A,B)$

隐马尔可夫模型由初始状态概率向量$\pi$、状态转移概率矩阵$A$以及观测概率矩阵$B$决定。$\pi$和$A$决定状态序列,$B$决定观测序列。因此,隐马尔可夫模型$\lambda$由如下表示:

λ=(π,A,B)\lambda = (\pi,A,B)λ=(π,A,B)

$(ii)$ 从定义可知,隐马尔可夫模型作了两个基本假设:

  1. 齐次马尔可夫性假设:假设隐藏的马尔科夫链在任意时刻$t$的状态只依赖于其前一时刻的状态,与其他的时刻的状态及观测无关,也与时刻$t$无关。

P(it+1∣i1⋯t,o1⋯t)=P(it+1∣it)P(i_{t+1}|i_{1\cdots t},o_{1\cdots t}) = P(i_{t+1}|i_t)P(it+1​∣i1⋯t​,o1⋯t​)=P(it+1​∣it​)
  1. 观测独立性假设:假设任意时刻的观测只依赖于该时刻的马尔可夫链的状态,与其他观测及状态无关。

P(Ot∣i1⋯t,o1⋯t)=P(Ot∣it)P(O_t|i_{1\cdots t},o_{1\cdots t}) = P(O_t|i_t)P(Ot​∣i1⋯t​,o1⋯t​)=P(Ot​∣it​)

$(iii)$ 三个问题

$(1).$ 概率计算问题。给定$\lambda$,求$P(O|\lambda)$

$(2).$ 学习问题

$(3).$ 预测问题(解码问题)

概率计算问题

直接计算法

状态序列$I=(i_1,i_2,\cdots,i_T)$的概率是:

P(I∣λ)=P(i1⋯T∣λ)=P(i1⋯T−1,iT∣λ)=P(iT∣iT−1)⋅P(i1⋯T∣λ)=πi1ai1i2ai2i3⋯aiT−1iT=πi1∏t=2Tait−1itP(I|\lambda)= P(i_{1\cdots T}|\lambda) = P(i_{1\cdots T-1},i_T|\lambda)=P(i_T|i_{T-1})\cdot P(i_{1\cdots T}|\lambda) = \pi_{i_1}a_{i_1i_2}a_{i_2i_3}\cdots a_{i_{T-1}i_T} = \pi_{i_1}\prod_{t=2}^Ta_{i_{t-1}i_t}P(I∣λ)=P(i1⋯T​∣λ)=P(i1⋯T−1​,iT​∣λ)=P(iT​∣iT−1​)⋅P(i1⋯T​∣λ)=πi1​​ai1​i2​​ai2​i3​​⋯aiT−1​iT​​=πi1​​t=2∏T​ait−1​it​​

状态$i_t$的状态转移概率分布{$a_{i_t,i_{t+1}}$}产生状态$i_{t+1}$

对固定的状态序列$I=(i_1,i_2,\cdots,i_T)$,观测序列$O=(o_1,o_2,\cdots,o_T)$的概率是$P(O|I,\lambda)$:

P(O∣I,λ)=bi1(o1)bi2(o2)⋯biT(oT)P(O|I,\lambda) = b_{i_1}(o_1)b_{i_2}(o_2)\cdots b_{i_T}(o_T)P(O∣I,λ)=bi1​​(o1​)bi2​​(o2​)⋯biT​​(oT​)

状态$i_t$的观测概率分布$b_{i_t}(k)$生成$o_t$

然后,对所有可能的状态序列$I$求和,得到观测序列$O$的概率$P(O|\lambda)$,即

P(O∣λ)=∑IP(I,O∣λ)=∑IP(I∣λ)P(O∣I,λ)=∑i1,i2,⋯ ,iTπi1∏t=2Tait−1,it∏t=1Tbit(ot)P(O|\lambda)=\sum_{I} P(I,O|\lambda)=\sum_{I} P(I|\lambda)P(O|I,\lambda)=\sum_{i_1,i_2,\cdots,i_T}\pi_{i_1}\prod_{t=2}^T{a_{i_{t-1},i_t}}\prod_{t=1}^Tb_{i_t}(o_t)P(O∣λ)=I∑​P(I,O∣λ)=I∑​P(I∣λ)P(O∣I,λ)=i1​,i2​,⋯,iT​∑​πi1​​t=2∏T​ait−1​,it​​t=1∏T​bit​​(ot​)

由于空间复杂度为$O(TN^T)$,故该算法理论上可行,实际不可行。

前向算法

前向概率定义:给定隐马尔可夫模型$\lambda$,定义到时刻$t$部分观测序列为$o_1,o_2,\cdots,o_t$且状态为$q_i$的概率为前向概率,记作:

αt(i)=P(o1,o2,⋯ ,ot,it=qi∣λ)\alpha_t(i)=P(o_1,o_2,\cdots,o_t,i_t=q_i|\lambda)αt​(i)=P(o1​,o2​,⋯,ot​,it​=qi​∣λ)

有,

αT(i)=P(O,it=qi∣λ)\alpha_T(i) = P(O,i_t=q_i|\lambda)αT​(i)=P(O,it​=qi​∣λ)

算法过程:

输入:隐马尔可夫模型$\lambda$,观测序列$O$;

输出:观测序列概率$P(O|\lambda)$。

  1. 初值

α1(i)=πibi(o1),i=1,2,⋯ ,N\alpha_1(i) = \pi_ib_i(o_1),i=1,2,\cdots,Nα1​(i)=πi​bi​(o1​),i=1,2,⋯,N
  1. 递推,对$t=1,2,\cdots,T-1$

αt+1(j)=P(o1,⋯ ,ot,ot+1,it+1=qj∣λ)=∑i=1NP(o1,⋯ ,ot,ot+1,it+1=qj,it=qi∣λ)=∑i=1NP(ot+1∣o1,⋯ ,ot,it=qi,it+1=qj,λ)⋅P(o1,⋯ ,ot,it=qi,it+1=qj∣λ)=∑i=1NP(ot+1∣it+1=qj,λ)⋅P(it+1=qj∣o1,⋯ ,ot,it=qi,λ)⋅P(o1,⋯ ,ot,it=qi∣λ)=∑i=1NP(ot+1∣it+1=qj,λ)⋅P(it+1=qj∣it=qi,λ)⋅P(o1,⋯ ,ot,it=qi∣λ)=∑i=1Nbj(ot+1)⋅aij⋅αt(i)=∑i=1N[αt(i)aij]bj(ot+1)\begin{align} \alpha_{t+1}(j) &= P(o_1,\cdots,o_t,o_{t+1},i_{t+1}=q_j|\lambda) \\ &= \sum_{i=1}^N P(o_1,\cdots,o_t,o_{t+1},i_{t+1}=q_j,i_t=q_i|\lambda) \\ &= \sum_{i=1}^N P(o_{t+1}|o_1,\cdots,o_t,i_t=q_i,i_{t+1}=q_j,\lambda)\cdot P(o_1,\cdots,o_t,i_t=q_i,i_{t+1}=q_j|\lambda) \\ &= \sum_{i=1}^N P(o_{t+1}|i_{t+1}=q_j,\lambda)\cdot P(i_{t+1}=q_j|o_1,\cdots,o_t,i_t=q_i,\lambda)\cdot P(o_1,\cdots,o_t,i_t=q_i|\lambda) \\ &= \sum_{i=1}^N P(o_{t+1}|i_{t+1}=q_j,\lambda)\cdot P(i_{t+1}=q_j|i_t=q_i,\lambda)\cdot P(o_1,\cdots,o_t,i_t=q_i|\lambda) \\ &= \sum_{i=1}^N b_j(o_{t+1})\cdot a_{ij}\cdot \alpha_t(i) \\ &= \sum_{i=1}^N [\alpha_t(i)a_{ij}]b_j(o_{t+1}) \end{align}αt+1​(j)​=P(o1​,⋯,ot​,ot+1​,it+1​=qj​∣λ)=i=1∑N​P(o1​,⋯,ot​,ot+1​,it+1​=qj​,it​=qi​∣λ)=i=1∑N​P(ot+1​∣o1​,⋯,ot​,it​=qi​,it+1​=qj​,λ)⋅P(o1​,⋯,ot​,it​=qi​,it+1​=qj​∣λ)=i=1∑N​P(ot+1​∣it+1​=qj​,λ)⋅P(it+1​=qj​∣o1​,⋯,ot​,it​=qi​,λ)⋅P(o1​,⋯,ot​,it​=qi​∣λ)=i=1∑N​P(ot+1​∣it+1​=qj​,λ)⋅P(it+1​=qj​∣it​=qi​,λ)⋅P(o1​,⋯,ot​,it​=qi​∣λ)=i=1∑N​bj​(ot+1​)⋅aij​⋅αt​(i)=i=1∑N​[αt​(i)aij​]bj​(ot+1​)​​
  1. 终止

P(O∣λ)=∑i=1NαT(i)P(O|\lambda) = \sum_{i=1}^N \alpha_T(i)P(O∣λ)=i=1∑N​αT​(i)

后向算法

后向概率定义:给定隐马尔可夫模型$\lambda$,定义在时刻$t$状态为$q_i$的条件下,从$t+1$到$T$的部分观测序列为$o_{t+1},o_{t+2},\cdots,o_T$的概率为后向概率,记作:

βt(i)=P(ot+1,ot+2,⋯ ,oT∣it=qi,λ)\beta_t(i) = P(o_{t+1},o_{t+2},\cdots,o_T|i_t=q_i,\lambda)βt​(i)=P(ot+1​,ot+2​,⋯,oT​∣it​=qi​,λ)

算法过程:

输入:隐马尔可夫模型$\lambda$,观测序列$O$;

输出:观测序列概率$P(O|\lambda)$。

  1. 初值

βT(i)=1,i=1,2,⋯ ,N\beta_T(i) = 1,i=1,2,\cdots,NβT​(i)=1,i=1,2,⋯,N
  1. 递推,对$t=T-1,T-2,\cdots,1$

βt(i)=P(ot+1,ot+2,⋯ ,oT∣it=qi,λ)=∑j=1NP(ot+1,ot+2,⋯ ,oT,it+1=qj∣it=qi,λ)=∑j=1NP(ot+1,ot+2,⋯ ,oT∣it=qi,it+1=qj,λ)⋅P(it+1=qj∣it=qi,λ)=∑j=1NP(ot+2,⋯ ,oT∣it+1=qj,λ)⋅P(ot+1∣ot+2,⋯ ,oT,it+1=qj,it=qi,λ)⋅P(it+1=qj∣it=qi,λ)=∑j=1NP(ot+1∣it+1=qj,λ)⋅P(it+1=qj∣it=qi,λ)⋅P(ot+2,⋯ ,oT∣it+1=qj,λ)=∑j=1Nbj(ot+1)aijβt+1(j)\begin{align} \beta_t(i) &= P(o_{t+1},o_{t+2},\cdots,o_T|i_t=q_i,\lambda) \\ &= \sum_{j=1}^N P(o_{t+1},o_{t+2},\cdots,o_T,i_{t+1}=q_j|i_t=q_i,\lambda) \\ &= \sum_{j=1}^N P(o_{t+1},o_{t+2},\cdots,o_T|i_t=q_i,i_{t+1}=q_j,\lambda)\cdot P(i_{t+1}=q_j|i_t=q_i,\lambda) \\ &= \sum_{j=1}^N P(o_{t+2},\cdots,o_T|i_{t+1}=q_j,\lambda)\cdot P(o_{t+1}|o_{t+2},\cdots,o_T,i_{t+1}=q_j,i_t=q_i,\lambda)\cdot P(i_{t+1}=q_j|i_t=q_i,\lambda) \\ &= \sum_{j=1}^N P(o_{t+1}|i_{t+1}=q_j,\lambda)\cdot P(i_{t+1}=q_j|i_t=q_i,\lambda)\cdot P(o_{t+2},\cdots,o_T|i_{t+1}=q_j,\lambda) \\ &= \sum_{j=1}^N b_j(o_{t+1})a_{ij}\beta_{t+1}(j) \end{align}βt​(i)​=P(ot+1​,ot+2​,⋯,oT​∣it​=qi​,λ)=j=1∑N​P(ot+1​,ot+2​,⋯,oT​,it+1​=qj​∣it​=qi​,λ)=j=1∑N​P(ot+1​,ot+2​,⋯,oT​∣it​=qi​,it+1​=qj​,λ)⋅P(it+1​=qj​∣it​=qi​,λ)=j=1∑N​P(ot+2​,⋯,oT​∣it+1​=qj​,λ)⋅P(ot+1​∣ot+2​,⋯,oT​,it+1​=qj​,it​=qi​,λ)⋅P(it+1​=qj​∣it​=qi​,λ)=j=1∑N​P(ot+1​∣it+1​=qj​,λ)⋅P(it+1​=qj​∣it​=qi​,λ)⋅P(ot+2​,⋯,oT​∣it+1​=qj​,λ)=j=1∑N​bj​(ot+1​)aij​βt+1​(j)​​
  1. 终止

P(O∣λ)=P(o1,⋯ ,oT∣λ)=∑i=1NP(o1,⋯ ,oT,i1=qi∣λ)=∑i=1NP(o1,⋯ ,oT∣i1=qi,λ)⋅P(i1=qi∣λ)=∑i=1NP(o1∣o2,⋯ ,oT,i1=qi,λ)⋅P(o2,⋯ ,oT∣i1=qi,λ)⋅πi=∑i=1NP(o1∣i1=qi,λ)⋅P(o2,⋯ ,oT∣i1=qi,λ)⋅πi=∑i=1Nbi(o1)β1(i)πi\begin{align} P(O|\lambda) &= P(o_1,\cdots,o_T|\lambda) \\ &= \sum_{i=1}^N P(o_1,\cdots,o_T,i_1=q_i|\lambda) \\ &= \sum_{i=1}^N P(o_1,\cdots,o_T|i_1=q_i,\lambda)\cdot P(i_1=q_i|\lambda) \\ &= \sum_{i=1}^N P(o_1|o_2,\cdots,o_T,i_1=q_i,\lambda)\cdot P(o_2,\cdots,o_T|i_1=q_i,\lambda) \cdot \pi_i \\ &= \sum_{i=1}^N P(o_1|i_1=q_i,\lambda)\cdot P(o_2,\cdots,o_T|i_1=q_i,\lambda) \cdot \pi_i \\ &= \sum_{i=1}^N b_i(o_1)\beta_1(i)\pi_i \end{align}P(O∣λ)​=P(o1​,⋯,oT​∣λ)=i=1∑N​P(o1​,⋯,oT​,i1​=qi​∣λ)=i=1∑N​P(o1​,⋯,oT​∣i1​=qi​,λ)⋅P(i1​=qi​∣λ)=i=1∑N​P(o1​∣o2​,⋯,oT​,i1​=qi​,λ)⋅P(o2​,⋯,oT​∣i1​=qi​,λ)⋅πi​=i=1∑N​P(o1​∣i1​=qi​,λ)⋅P(o2​,⋯,oT​∣i1​=qi​,λ)⋅πi​=i=1∑N​bi​(o1​)β1​(i)πi​​​

其他概率与期望值的计算

利用前向概率和后向概率,可以得到关于单个状态和两个状态概率的计算公式。

  1. 由前向概率$\alpha_t(i)$和后向概率$\beta_t(i)$定义可知:

αt(i)βt(i)=P(o1,⋯ ,ot,it=qi∣λ)⋅P(ot+1,⋯ ,oT∣it=qi,λ)=P(o1,⋯ ,ot,it=qi∣λ)⋅P(ot+1,⋯ ,oT∣it=qi,o1,⋯ ,ot,λ)=P(o1,⋯ ,ot,ot+1,⋯ ,oT,it=qi∣λ)=P(O,it=qi∣λ)\begin{align} \alpha_t(i)\beta_t(i) &= P(o_1,\cdots,o_t,i_t=q_i|\lambda)\cdot P(o_{t+1},\cdots,o_T|i_t=q_i,\lambda) \\ &= P(o_1,\cdots,o_t,i_t=q_i|\lambda)\cdot P(o_{t+1},\cdots,o_T|i_t=q_i,o_1,\cdots,o_t,\lambda) \\ &= P(o_1,\cdots,o_t,o_{t+1},\cdots,o_T,i_t=q_i|\lambda) \\ &= P(O,i_t=q_i|\lambda) \end{align}αt​(i)βt​(i)​=P(o1​,⋯,ot​,it​=qi​∣λ)⋅P(ot+1​,⋯,oT​∣it​=qi​,λ)=P(o1​,⋯,ot​,it​=qi​∣λ)⋅P(ot+1​,⋯,oT​∣it​=qi​,o1​,⋯,ot​,λ)=P(o1​,⋯,ot​,ot+1​,⋯,oT​,it​=qi​∣λ)=P(O,it​=qi​∣λ)​​
  1. 给定模型$\lambda$和观测$O$,在时刻$t$处于状态$q_i$的概率,记为:

γt(i)=P(it=qi∣O,λ)=P(it=qi,O∣λ)P(O∣λ)=P(it=qi,O∣λ)∑j=1NP(it=qj,O∣λ)=αt(i)βt(i)∑j=1Nαt(j)βt(j)\begin{align} \gamma_t(i) &= P(i_t=q_i|O,\lambda) \\ &=\frac{P(i_t=q_i,O|\lambda)}{P(O|\lambda)} \\ &=\frac{P(i_t=q_i,O|\lambda)}{\sum_{j=1}^N P(i_t=q_j,O|\lambda)} \\ &=\frac{\alpha_t(i)\beta_t(i)}{\sum_{j=1}^N \alpha_t(j)\beta_t(j)} \end{align}γt​(i)​=P(it​=qi​∣O,λ)=P(O∣λ)P(it​=qi​,O∣λ)​=∑j=1N​P(it​=qj​,O∣λ)P(it​=qi​,O∣λ)​=∑j=1N​αt​(j)βt​(j)αt​(i)βt​(i)​​​
  1. 给定模型$\lambda$和观测$O$,在时刻$t$处于状态$q_i$且在时刻$t+1$处于状态$q_j$的概率。记为:

ξt(i,j)=P(it=qi,it+1=qj∣O,λ)=P(it=qi,it+1=qj,O∣λ)P(O∣λ)=P(it=qi,it+1=qj,O∣λ)∑i=1N∑j=1NP(it=qi,it+1=qj,O∣λ)=αt(i)aijbj(ot+1)βt+1(j)∑i=1N∑j=1Nαt(i)aijbj(ot+1)βt+1(j)\begin{align} \xi_t(i,j) &= P(i_t=q_i,i_{t+1}=q_j|O,\lambda) \\ &= \frac{P(i_t=q_i,i_{t+1}=q_j,O|\lambda)}{P(O|\lambda)} \\ &= \frac{P(i_t=q_i,i_{t+1}=q_j,O|\lambda)}{\sum_{i=1}^N\sum_{j=1}^N P(i_t=q_i,i_{t+1}=q_j,O|\lambda)} \\ &= \frac{\alpha_t(i) a_{ij} b_j(o_{t+1})\beta_{t+1}(j)}{\sum_{i=1}^N \sum_{j=1}^N \alpha_t(i) a_{ij} b_j(o_{t+1})\beta_{t+1}(j)} \end{align}ξt​(i,j)​=P(it​=qi​,it+1​=qj​∣O,λ)=P(O∣λ)P(it​=qi​,it+1​=qj​,O∣λ)​=∑i=1N​∑j=1N​P(it​=qi​,it+1​=qj​,O∣λ)P(it​=qi​,it+1​=qj​,O∣λ)​=∑i=1N​∑j=1N​αt​(i)aij​bj​(ot+1​)βt+1​(j)αt​(i)aij​bj​(ot+1​)βt+1​(j)​​​

其中,

P(it=qi,it+1=qj,O∣λ)=P(it=qi,o1,⋯ ,ot,it+1=qj,ot+1,⋯ ,oT∣λ)=P(it=qi,o1,⋯ ,ot∣λ)⋅P(it+1=qj,ot+1,⋯ ,oT∣it=qi,o1,⋯ ,ot,λ)=αt(i)⋅P(it+1=qj∣it=qi,O,λ)⋅P(ot+1,⋯ ,oT∣it+1=qj,it=qi,o1,⋯ ,ot,λ)=αt(i)⋅aij⋅P(ot+1,ot+2,⋯ ,oT∣it+1=qj,it=qi,o1,⋯ ,ot,λ)=αt(i)⋅aij⋅P(ot+1∣it+1=qj,it=qi,o1,⋯ ,ot)⋅P(ot+2,⋯ ,oT∣it+1=qj,it=qi,o1,⋯ ,ot,ot+1)=αt(i)⋅aij⋅P(ot+1∣it+1)⋅P(ot+2,⋯ ,oT∣it+1=qj)=αt(i)aijbj(ot+1)βt+1(j)\begin{align} P(i_t=q_i,i_{t+1}=q_j,O|\lambda) &= P(i_t=q_i,o_1,\cdots,o_t,i_{t+1}=q_j,o_{t+1},\cdots,o_T | \lambda) \\ &= P(i_t=q_i,o_1,\cdots,o_t|\lambda)\cdot P(i_{t+1}=q_j,o_{t+1},\cdots,o_T|i_t=q_i,o_1,\cdots,o_t,\lambda) \\ &= \alpha_t(i)\cdot P(i_{t+1}=q_j|i_t=q_i,O,\lambda)\cdot P(o_{t+1},\cdots,o_T|i_{t+1}=q_j,i_t=q_i,o_1,\cdots,o_t,\lambda) \\ &= \alpha_t(i)\cdot a_{ij}\cdot P(o_{t+1},o_{t+2},\cdots,o_T|i_{t+1}=q_j,i_t=q_i,o_1,\cdots,o_t,\lambda) \\ &= \alpha_t(i)\cdot a_{ij}\cdot P(o_{t+1}|i_{t+1}=q_j,i_t=q_i,o_1,\cdots,o_t)\cdot P(o_{t+2},\cdots,o_T|i_{t+1}=q_j,i_t=q_i,o_1,\cdots,o_t,o_{t+1}) \\ &= \alpha_t(i)\cdot a_{ij}\cdot P(o_{t+1}|i_{t+1})\cdot P(o_{t+2},\cdots,o_T|i_{t+1}=q_j) \\ &= \alpha_t(i) a_{ij} b_j(o_{t+1})\beta_{t+1}(j) \end{align}P(it​=qi​,it+1​=qj​,O∣λ)​=P(it​=qi​,o1​,⋯,ot​,it+1​=qj​,ot+1​,⋯,oT​∣λ)=P(it​=qi​,o1​,⋯,ot​∣λ)⋅P(it+1​=qj​,ot+1​,⋯,oT​∣it​=qi​,o1​,⋯,ot​,λ)=αt​(i)⋅P(it+1​=qj​∣it​=qi​,O,λ)⋅P(ot+1​,⋯,oT​∣it+1​=qj​,it​=qi​,o1​,⋯,ot​,λ)=αt​(i)⋅aij​⋅P(ot+1​,ot+2​,⋯,oT​∣it+1​=qj​,it​=qi​,o1​,⋯,ot​,λ)=αt​(i)⋅aij​⋅P(ot+1​∣it+1​=qj​,it​=qi​,o1​,⋯,ot​)⋅P(ot+2​,⋯,oT​∣it+1​=qj​,it​=qi​,o1​,⋯,ot​,ot+1​)=αt​(i)⋅aij​⋅P(ot+1​∣it+1​)⋅P(ot+2​,⋯,oT​∣it+1​=qj​)=αt​(i)aij​bj​(ot+1​)βt+1​(j)​​
  1. 将$\gamma_t(i)$和$\xi_t(i,j)$对各个时刻的$t$求和,可以得到一些有用的期望值。

$(1).$ 在观测$O$下状态$i$出现的期望值

∑t=1Tγt(i)\sum_{t=1}^T \gamma_t(i)t=1∑T​γt​(i)

$(2).$ 在观测$O$下由状态$i$转移的期望值

∑t=1T−1γt(i)\sum_{t=1}^{T-1}\gamma_t(i)t=1∑T−1​γt​(i)

$(3).$ 在观测$O$下由状态$i$转移到状态$j$的期望值

∑t=1Tξt(i,j)\sum_{t=1}^T \xi_t(i,j)t=1∑T​ξt​(i,j)

学习问题

隐马尔可夫模型的学习,根据训练数据是包括观测序列和对应的状态序列还是只有观测序列,可以分别由监督学习与非监督学习实现。

监督学习算法

假设已给训练数据包含$S$个长度相同的观测序列和对应的状态序列${(O_1,I_1),(O_2,I_2),\cdots,(O_S,I_S)}$,那么可以利用极大似然估计法来估计隐马尔可夫模型的参数。

算法过程:

  1. 转移概率$a_{ij}$的估计

设样本中时刻$t$处于状态$i$时刻$t+1$转移到状态$j$的频数为$A_{ij}$,那么状态转移概率$a_{ij}$的估计是:

aij^=Aij∑i=1NAij,i=1,2,⋯ ,N;j=1,2,⋯ ,N\hat{a_{ij}} = \frac{A_{ij}}{\sum_{i=1}^N A_{ij}},i=1,2,\cdots,N;j=1,2,\cdots,Naij​^​=∑i=1N​Aij​Aij​​,i=1,2,⋯,N;j=1,2,⋯,N
  1. 观测概率$b_j(k)$的估计

设样本中状态为$j$并观测为$k$的频数是$B_{jk}$,那么状态为$j$观测为$k$的概率$b_j(k)$的估计是:

bj(k)^=Bjk∑k=1MBjk,j=1,2,⋯ ,N;k=1,2,⋯ ,M\hat{b_j(k)} = \frac{B_{jk}}{\sum_{k=1}^M B_{jk}},j=1,2,\cdots,N;k=1,2,\cdots,Mbj​(k)^​=∑k=1M​Bjk​Bjk​​,j=1,2,⋯,N;k=1,2,⋯,M
  1. 初始化状态概率$\pi_i$的估计$\hat{\pi_i}$为$S$个样本中初始状态为$q_i$的概率

由于监督学习需要使用训练数据,而人工标注训练数据往往代价很高,有时就会利用非监督学习的方法。

非监督学习算法: $Baum-Welch$算法

假设给定训练数据只包含$S$个长度为$T$的观测序列${O_1,O_2,\cdots,O_S}$而没有对应的状态序列,目标是学习隐马尔可夫模型$\lambda=(A,B,\pi)$的参数。将观测序列数据看做观测数据$O$,状态序列数据看做不可预测的隐数据$I$,那么因马尔可夫模型事实上是一个含有隐变量的概率模型:

P(O∣λ)=∑IP(O∣I,λ)P(I∣λ)P(O|\lambda) = \sum_I P(O|I,\lambda)P(I|\lambda)P(O∣λ)=I∑​P(O∣I,λ)P(I∣λ)

该模型的参数可以由$EM$算法实现。

算法过程:

  1. 确定完全数据的对数似然函数

所有观测数据写成$O=(o_1,o_2,\cdots,o_T)$,所有隐数据写成$I=(i_1,i_2,\cdots,i_T)$,完全数据是$(O,I)=(o_1,o_2,\cdots,o_T,i_1,i_2,\cdots,i_T)$。完全数据的对数似然函数是$log\ P(O,I|\lambda)$。

  1. $EM$算法的$E$步:求$Q$函数$Q(\lambda,\lambda^{(t)})$

Q(λ,λ(t))=∑Ilop P(O,I∣λ)P(O,I∣λ(t))Q(\lambda,\lambda^{(t)}) = \sum_I lop\ P(O,I|\lambda)P(O,I|\lambda^{(t)})Q(λ,λ(t))=I∑​lop P(O,I∣λ)P(O,I∣λ(t))

其中,$\lambda^{(t)}$是隐马尔可夫模型参数的当前估计值,$\lambda$是要极大化的隐马尔可夫模型参数。

P(O,I∣λ)=πi1bi1(o1)ai1,i2bi2(o2)⋯aiT−1,iTbiT(oT)=πi1∏t=2Tait−1,it∏t=1Tbit(ot)P(O,I|\lambda) = \pi_{i_1}b_{i_1}(o_1)a_{i_1,i_2}b_{i_2}(o_2)\cdots a_{i_{T-1},i_T}b_{i_T}(o_T)=\pi_{i_1}\prod_{t=2}^Ta_{i_{t-1},i_t}\prod_{t=1}^T b_{i_t}(o_t)P(O,I∣λ)=πi1​​bi1​​(o1​)ai1​,i2​​bi2​​(o2​)⋯aiT−1​,iT​​biT​​(oT​)=πi1​​t=2∏T​ait−1​,it​​t=1∏T​bit​​(ot​)

于是:

Q(λ,λ(t))=∑I[log πi1∏t=2Tait−1,it∏t=1Tbit(ot)]P(O,I∣λ(t))=∑I[log πi1+∑t=2Tlog ait−1,it+∑t=1Tlog bit(ot)]P(O,I∣λ(t))\begin{align} Q(\lambda,\lambda^{(t)}) &= \sum_I[log \ \pi_{i_1}\prod_{t=2}^Ta_{i_{t-1},i_t}\prod_{t=1}^T b_{i_t}(o_t)]P(O,I|\lambda^{(t)}) \\ &= \sum_I[log \ \pi_{i_1}+ \sum_{t=2}^T log\ a_{i_{t-1},i_t} + \sum_{t=1}^T log\ b_{i_t}(o_t)]P(O,I|\lambda^{(t)}) \\ \end{align}Q(λ,λ(t))​=I∑​[log πi1​​t=2∏T​ait−1​,it​​t=1∏T​bit​​(ot​)]P(O,I∣λ(t))=I∑​[log πi1​​+t=2∑T​log ait−1​,it​​+t=1∑T​log bit​​(ot​)]P(O,I∣λ(t))​​
  1. $EM$算法的$M$步:极大化$Q$函数$Q(\lambda,\lambda^{(t)})$求模型参数$A$,$B$,$\pi$

λ(t+1)=argmaxλQ(λ,λ(t))=argmaxλ∑I[log πi1+∑t=2Tlog ait−1,it+∑t=1Tlog bit(ot)]P(O,I∣λ(t))\lambda^{(t+1)} = {argmax}_{\lambda}Q(\lambda,\lambda^{(t)})= argmax_{\lambda} \sum_I[\textcolor{blue}{log \ \pi_{i_1}}+ \textcolor{green}{\sum_{t=2}^T log\ a_{i_{t-1},i_t}} + \textcolor{orange}{\sum_{t=1}^T log\ b_{i_t}(o_t)}]P(O,I|\lambda^{(t)})λ(t+1)=argmaxλ​Q(λ,λ(t))=argmaxλ​I∑​[log πi1​​+t=2∑T​log ait−1​,it​​+t=1∑T​log bit​​(ot​)]P(O,I∣λ(t))

由上可知,三个参数分别单独在三个部分,在求解其中一个时,可以忽略掉其他两个,单独讨论。

对于$\pi$:

∑Iπi1P(O,I∣λ)=∑i=1Nlog πiP(O,i1=i∣λ(t))\sum_I \pi_{i_1}P(O,I|\lambda) = \sum_{i=1}^N log\ \pi_iP(O,i_1=i|\lambda^{(t)})I∑​πi1​​P(O,I∣λ)=i=1∑N​log πi​P(O,i1​=i∣λ(t))

由于$\pi$是一个概率分布,因此有一个约束条件$\sum_{i=1}^N \pi_i=1$,于是利用拉格朗日乘子法,构造拉格朗日函数,有:

∑i=1Nlog πiP(O,i1=i∣λ(t))+γ(∑i=1Nπi−1)\sum_{i=1}^N log\ \pi_iP(O,i_1=i|\lambda^{(t)})+\gamma(\sum_{i=1}^N \pi_i-1)i=1∑N​log πi​P(O,i1​=i∣λ(t))+γ(i=1∑N​πi​−1)

对其求偏导数并令结果为0,有:

∂∂πi[∑i=1Nlog πiP(O,i1=i∣λ(t))+γ(∑i=1Nπi−1)]=0\frac{\partial}{\partial\pi_i}[\sum_{i=1}^N log\ \pi_iP(O,i_1=i|\lambda^{(t)})+\gamma(\sum_{i=1}^N \pi_i-1)] = 0∂πi​∂​[i=1∑N​log πi​P(O,i1​=i∣λ(t))+γ(i=1∑N​πi​−1)]=0

得:

1πiP(O,i1=i∣λ(t))+γ=0P(O,i1=i∣λ(t))+γπi=0\begin{align} \frac{1}{\pi_i}P(O,i_1=i|\lambda^{(t)}) + \gamma &= 0 \\ P(O,i_1=i|\lambda^{(t)}) + \gamma\pi_i&=0 \end{align}πi​1​P(O,i1​=i∣λ(t))+γP(O,i1​=i∣λ(t))+γπi​​=0=0​​

同时进行连加,得到$\gamma$:

∑i=1NP(O,i1=i∣λ(t)+γπi)=P(O∣λ(t))+γ=0\sum_{i=1}^N P(O,i_1=i|\lambda^{(t)}+\gamma\pi_i) = P(O|\lambda^{(t)}) + \gamma = 0i=1∑N​P(O,i1​=i∣λ(t)+γπi​)=P(O∣λ(t))+γ=0

有:

γ=−P(O∣λ(t))\gamma = -P(O|\lambda^{(t)})γ=−P(O∣λ(t))

带入$P(O,i_1=i|\lambda^{(t)}) + \gamma\pi_i=0$得:

πi(t+1)=P(O,i1=i∣lambda(t))P(O∣λ(t))\pi_i^{(t+1)} = \frac{P(O,i_1=i|lambda^{(t)})}{P(O|\lambda^{(t)})}πi(t+1)​=P(O∣λ(t))P(O,i1​=i∣lambda(t))​

对于$a_{ij}$:

∑I∑t=2Tlog ait−1,itP(O,I∣λ)=∑i=1N∑j=1N∑t=1T−1log aijlog P(O,it=i,it+1=j∣λ(t))\sum_I \sum_{t=2}^T log\ a_{i_{t-1},i_t}P(O,I|\lambda) = \sum_{i=1}^N\sum_{j=1}^N \sum_{t=1}^{T-1} log\ a_{ij} log\ P(O,i_t=i,i_{t+1}=j|\lambda^{(t)})I∑​t=2∑T​log ait−1​,it​​P(O,I∣λ)=i=1∑N​j=1∑N​t=1∑T−1​log aij​log P(O,it​=i,it+1​=j∣λ(t))

由于$A$是一个概率分布的矩阵,其约束条件为$\sum_{j=1}^N a_{ij}=1$,与上述相同,利用拉格朗日乘子法,构造拉格朗日函数,求出得:

aij(t+1)=P(O,it=i,it+1=j∣λ(t)∑t=1T−1P(O,it=i∣λ(t))a_{ij}^{(t+1)} = \frac{P(O,i_t=i,i_{t+1}=j|\lambda^{(t)}}{\sum_{t=1}^{T-1}P(O,i_t=i|\lambda^{(t)})}aij(t+1)​=∑t=1T−1​P(O,it​=i∣λ(t))P(O,it​=i,it+1​=j∣λ(t)​

对于$b_j(k)$:

∑I[∑t=1Tlog bit(ot)]P(O,I∣λ(t))=∑j=1N∑t=1Tlog bj(ot)P(O,it=j∣λ(t))\sum_I[\sum_{t=1}^T log\ b_{i_t}(o_t)]P(O,I|\lambda^{(t)}) = \sum_{j=1}^N\sum_{t=1}^T log\ b_{j}(o_t)P(O,i_t=j|\lambda^{(t)})I∑​[t=1∑T​log bit​​(ot​)]P(O,I∣λ(t))=j=1∑N​t=1∑T​log bj​(ot​)P(O,it​=j∣λ(t))

由于$B$是一个概率分布的矩阵,其约束条件为$\sum_{k=1}^M b_j(o_k)=1$,与上述相同,利用拉格朗日乘子法,构造拉格朗日函数,求出得:

∂∂bj(k)[∑j=1N∑t=1Tlog bj(ot)P(O,it=j∣λ(t))+∑i=1Nηi(∑k=1M(bj(k)−1)]=0∑t=1T1bj(k)P(O,it=j∣λ(t))I(ot=vk)+∑i=1ηi=0\begin{align} \frac{\partial}{\partial b_j(k)}[\sum_{j=1}^N\sum_{t=1}^T log\ b_{j}(o_t)P(O,i_t=j|\lambda^{(t)})+\sum_{i=1}^N\eta_i(\sum_{k=1}^M (b_j(k)-1)] &= 0 \\ \sum_{t=1}^T \frac{1}{b_j(k)}P(O,i_t=j|\lambda^{(t)})\textcolor{blue}{I(o_t=v_k)}+\sum_{i=1}\eta_i &= 0 \end{align}∂bj​(k)∂​[j=1∑N​t=1∑T​log bj​(ot​)P(O,it​=j∣λ(t))+i=1∑N​ηi​(k=1∑M​(bj​(k)−1)]t=1∑T​bj​(k)1​P(O,it​=j∣λ(t))I(ot​=vk​)+i=1∑​ηi​​=0=0​​

注意,只有在$o_t=v_k$时,$b_j(o_t)$对$b_j(k)$的偏导数才不为0,以$I(o_t=v_k)$表示,该函数的作用是满足条件值为1,否则为0。

于是:

bj(k)(t+1)=−∑t=1TP(O,it=j∣λ(t))I(ot=vk)∑i=1ηib_j(k)^{(t+1)} = -\frac{\sum_{t=1}^T P(O,i_t=j|\lambda^{(t)}){I(o_t=v_k)}}{\sum_{i=1}\eta_i}bj​(k)(t+1)=−∑i=1​ηi​∑t=1T​P(O,it​=j∣λ(t))I(ot​=vk​)​

$Baum-Welch$模型的参数估计公式

利用其它概率与期望值的计算的公式,进行改写为如下式子:

aij=∑t=1Tξt(i,j)∑t=1Tγt(i)bj(k)=∑t=1,ot=vkTγt(j)∑t=1Tγt(j)πi=γ1(i)\begin{align} a_{ij} &= \frac{\sum_{t=1}^T\xi_t(i,j)}{\sum_{t=1}^T\gamma_t(i)} \\ b_j(k) &=\frac{\sum_{t=1,o_t=v_k}^T \gamma_t(j)}{\sum_{t=1}^T \gamma_t(j)} \\ \pi_i &= \gamma_1(i) \end{align}aij​bj​(k)πi​​=∑t=1T​γt​(i)∑t=1T​ξt​(i,j)​=∑t=1T​γt​(j)∑t=1,ot​=vk​T​γt​(j)​=γ1​(i)​​

预测算法

求概率最大的状态序列。

维特比算法

利用动态规划求解隐马尔可夫模型预测问题,即用动态规划求概率最大路径(最优路径)。这时一条路径对应着一个状态序列。

定义在时刻$t$状态为$i$的所有单个路径$(i_1,i_2,\cdots,i_t)$中概率最大值为:

δt(i)=maxi1,i2,⋯ ,it−1P(it=i,it−1,⋯ ,i1,ot,⋯ ,o1∣λ),i=1,2,⋯ ,N\delta_t(i) = max_{i_1,i_2,\cdots,i_{t-1}} P(i_t=i,i_{t-1},\cdots,i_1,o_t,\cdots,o_1|\lambda),i=1,2,\cdots,Nδt​(i)=maxi1​,i2​,⋯,it−1​​P(it​=i,it−1​,⋯,i1​,ot​,⋯,o1​∣λ),i=1,2,⋯,N

由定义可得变量$\delta$的递推公式为:

δt+1(i)=maxi1,i2,⋯ ,itP(it+1=i,it,⋯ ,i1,ot+1,⋯ ,o1∣λ)=max1≤j≤N[δt(j)aji]bi(ot+1),i=1,2,⋯ ,N;t=1,2,⋯ ,T−1\begin{align} \delta_{t+1}(i) &= max_{i_1,i_2,\cdots,i_{t}} P(i_{t+1}=i,i_{t},\cdots,i_1,o_{t+1},\cdots,o_1|\lambda) \\ &= max_{1\leq j \leq N}[\delta_t(j)a_{ji}]b_i(o_{t+1}),i=1,2,\cdots,N;t=1,2,\cdots,T-1 \end{align}δt+1​(i)​=maxi1​,i2​,⋯,it​​P(it+1​=i,it​,⋯,i1​,ot+1​,⋯,o1​∣λ)=max1≤j≤N​[δt​(j)aji​]bi​(ot+1​),i=1,2,⋯,N;t=1,2,⋯,T−1​​

定义在时刻$t$状态为$i$的所有单个路径$(i_1,i_2,\cdots,i_{t-1},i)$中概率最大的路径的第$t-1$个结点为:

ψt(i)=argmax1≤j≤N[δt−1(j)aji],i=1,2,⋯ ,N\psi_t(i) = argmax_{1 \leq j \leq N}[\delta_{t-1}(j)a_{ji}],i=1,2,\cdots,Nψt​(i)=argmax1≤j≤N​[δt−1​(j)aji​],i=1,2,⋯,N

算法过程:

输入:模型$\lambda=(A,B,\pi)$和观测$O=(o_1,o_2,\cdots,o_T)$;

输出:最优路径$I^=(i^_1,i^_2,\cdots,i^_T)$。

  1. 初始化

δ1(i)=πibi(o1),i=1,2,⋯ ,Nψ1(i)=0,i=1,2,⋯ ,N\delta_1(i) = \pi_ib_i(o_1),i=1,2,\cdots,N \\ \psi_1(i) = 0,i=1,2,\cdots,Nδ1​(i)=πi​bi​(o1​),i=1,2,⋯,Nψ1​(i)=0,i=1,2,⋯,N
  1. 递推,对$t=2,3,\cdots,T$

δt(i)=max1≤j≤N[δt−1(j)aji]bi(ot),i=1,2,⋯ ,Nψt(i)=argmax1≤j≤N[δt−1(j)aji],i=1,2,⋯ ,N\delta_{t}(i) = max_{1\leq j \leq N}[\delta_{t-1}(j)a_{ji}]b_i(o_{t}),i=1,2,\cdots,N \\ \psi_t(i) = argmax_{1 \leq j \leq N}[\delta_{t-1}(j)a_{ji}],i=1,2,\cdots,Nδt​(i)=max1≤j≤N​[δt−1​(j)aji​]bi​(ot​),i=1,2,⋯,Nψt​(i)=argmax1≤j≤N​[δt−1​(j)aji​],i=1,2,⋯,N
  1. 终止

P∗=max1≤i≤NδT(i)iT∗=argmax1≤i≤N[δT(i)]P^* = max_{1\leq i \leq N} \delta_T(i) \\ i^*_T = argmax_{1\leq i \leq N} [\delta_T(i)]P∗=max1≤i≤N​δT​(i)iT∗​=argmax1≤i≤N​[δT​(i)]
  1. 最有路径回溯,对$t=T-1,T-2,\cdots,1$

it∗=ψt+1(it+1∗)i^*_t = \psi_{t+1}(i^*_{t+1})it∗​=ψt+1​(it+1∗​)

求得最优路径$I^=(i^_1,i^_2,\cdots,i^_T)$。

代码实现

import logging
import numpy as np
np.set_printoptions(suppress=True, threshold=np.inf,precision=10)

class HMM:
    def __init__(self,M,N,epoches=10):
        self.A  = np.abs(np.random.randn(M,M))
        self.B  = np.abs(np.random.randn(M,N))
        self.pi = np.ones(M)
        self.T  = None
        self.O  = None
        self.M  = M # 可能的状态数
        self.N  = N # 可能的观察数
        self.alpha = None
        self.beta = None
        self.epoches = epoches
        self.logger = logging.getLogger(__name__)
        self.logger.setLevel(logging.DEBUG)
    
    def forward(self,):
        alpha = np.zeros((self.T,self.M))
        for t in range(self.T):
            if t == 0:
                alpha[t,:] = self.B[:,O[t]]*self.pi # 初始化
                continue
            alpha[t,:] = np.array([self.A[:,i].dot(alpha[t-1,:])*self.B[i,O[t]] for i in range(self.M)])
        return alpha

    def backward(self,):
        beta = np.zeros((self.T,self.M))
        beta[-1,:] = np.ones(self.M)
        for t in list(range(self.T-2,-1,-1)):
            beta[t,:] = np.array([np.sum(np.array([self.A[i,j]*self.B[j,O[t+1]]*beta[t+1,j] for j in range(self.M)])) for i in range(self.M)])
        return beta

    def calc_gamma(self,t,i):
        gamma = (self.alpha[t,i]*self.beta[t,i]) / np.sum(np.array([self.alpha[t,j]*self.beta[t,j] for j in range(self.M)]))
        return gamma

    def calc_kesai(self,t,i,j):
        kesai = (self.alpha[t,i]*self.A[i,j]*self.B[j,self.O[t+1]]*self.beta[t+1,j]) / np.sum(np.array([[self.alpha[t,i]*self.A[i,j]*self.B[j,self.O[t+1]]*self.beta[t+1,j] for j in range(M)] for i in range(M)]))
        return kesai
    
    def init_params(self,O,A,B,pi):
        self.T = len(O)
        self.O = O
        if A is not None:
            self.A = A
        if B is not None:
            self.B = B
        if pi is not None:
            self.pi = pi
        
        self.M,self.N = self.B.shape
        
        if A is None:
            self.A = self.A / np.sum(self.A)
            self.B = self.B / np.sum(self.B)
            self.pi = self.pi / np.sum(self.pi)
            

    def cal_probality(self,select=None):
        p = 0
        if select != "backward":
            self.logger.info("前向算法")
        else:
            self.logger.info("后向算法")
        self.alpha = self.forward()
        self.beta = self.backward()
        p = np.sum(self.alpha[-1,:])
        return p

    def baum_welch(self,):
        for e in range(self.epoches):
            
            self.alpha = self.forward()
            self.beta = self.backward()
            
            self.logger.info("第{}次迭代".format(e))
            
            A_ = np.zeros((self.M,self.M))
            B_ = np.zeros((self.M,self.N))
            pi_ = np.zeros(self.M)
                        
            # a_{ij}
            for i in range(self.M):
                for j in range(self.M):
                    molecular = 0.0
                    denominator = 0.0
                    for t in range(self.T-1):
                        molecular += self.calc_kesai(t,i,j)
                        denominator += self.calc_gamma(t,i)
                    A_[i,j] = molecular / denominator
                    
            # b_{jk}
            for j in range(self.M):
                for k in range(self.N):
                    molecular = 0.0
                    denominator = 0.0
                    for t in range(self.T):
                        if k == self.O[t]:
                            molecular += self.calc_gamma(t,j)
                        denominator += self.calc_gamma(t,j)
                    B_[j,k] = molecular / denominator
                    
            # pi_{i}
            for i in range(self.M):
                pi_[i] = self.calc_gamma(0,i)
            
            # 更新
            self.A  = A_/np.sum(A_)
            self.B  = np.array([self.B[i,:]/np.sum(self.B[i,:]) for i in range(self.M)])
            self.pi = pi_/np.sum(pi_)
        self.logger.info("更新完毕:\n A:\n{}\nB:\n{}\npi:\n{}\n".format(self.A.round(5),
                                                                                self.B.round(5),self.pi.round(5)))
        
    def viterbi(self,):
        delta = np.zeros((self.T,self.M))
        delta[0,:] = np.array([self.pi[i]*self.B[i,self.O[0]] for i in range(self.M)])
        psi = np.zeros((self.T,self.M))
        
        for t in range(1,self.T):
            for i in range(self.M):
                max_delta = np.array([delta[t-1,j]*self.A[j,i] for j in range(self.M)])
                delta[t,i] = np.max(max_delta)*self.B[i,self.O[t]]
                psi[t,i] = np.argmax(max_delta)
        print("delta:\n{},\npsi:\n{}".format(delta,psi))
        # 终止
        max_delta = delta[self.T-1,:]
        I = np.zeros(self.T,dtype=int)
        P = np.max(max_delta)
        I[-1] = np.argmax(max_delta)
        print("P(*)-最优路径的概率:{};最优路径的终点是:{}".format(P.round(5),I[-1]))
        
        
        # 回溯
        for t in range(self.T-2,-1,-1):
            I[t] = psi[t+1,I[t+1]]
        print("最优路径I(*):\n{}".format(I))
        
        
    def fit(self,O,A=None,B=None,pi=None,select=None):
        if A is None:
            select = "bw"
        self.init_params(O,A,B,pi)
        self.logger.info("初始化:\n A:\n{}\nB:\n{}\npi:\n{}\n状态数:{},观测数:{}".format(self.A.round(5),
                                                                                self.B.round(5),self.pi.round(5),self.M,self.N))
        if select == "bw" or select == "baum_welch":
            self.baum_welch()
        self.p = self.cal_probality()
        self.logger.info("当前p(o|lambda)={}".format(self.p.round(5)))
        self.p = self.cal_probality("backward")
        self.logger.info("当前p(o|lambda)={}".format(self.p.round(5)))
        print("p(o|lambda)的概率为:{}".format(self.p))
        
A = np.array([ # 状态转移概率分布
    [.5,.2,.3],
    [.3,.5,.2],
    [.2,.3,.5]
])
B = np.array([ # 观测概率分布
    [.5,.5],
    [.4,.6],
    [.7,.3]
])
pi = np.array([ # 初始概率分布 => 状态的分布
    .2,.4,.4
])

O = [0,1,0] # 1表示红,0表示白 # 观测序列


M,N = A.shape[1],B.shape[0]    
hmm = HMM(10,4)
hmm.fit(O,A,B,pi)
hmm.viterbi()
O = [0,1,0] # 1表示红,0表示白 # 观测序列

M,N = A.shape[1],B.shape[0]    
hmm = HMM(3,2)
hmm.fit(O)
hmm.viterbi()
上一页信息论中的熵下一页支持向量机

最后更新于3年前

这有帮助吗?

image-20210125210024542
image-20210125210341550
image-20210104222033435
image-20210104222912358
image-20210104223203109
image-20210105100709601
image-20210105134637569
image-20210105165436434
image-20210105165453785