一 马尔可夫模型

我们通过一个具体的例子来介绍一下什么是马尔可夫模型

我们假设天气有3种情况,阴天,雨天,晴天,它们之间的转换关系如下:
(稍微解释一下这个图,我们可以这样认为,已知第一天是阴天,那第二天是阴天的概率是0.1, 第二天是晴天的概率是0.3,第二天是雨天的概率是0.6)

每一个状态转换到另一个状态或者自身的状态都有一定的概率。

马尔可夫模型就是用来表述上述问题的一个模型。

有这样一个状态链,第一天是阴天,第二天是晴天,第三天是雨天。 这样一个状态链就是马尔可夫链。

在上述例子中,如果我们并不知道今天天气属于什么状况,我们只知道今明后三天的水藻的干燥湿润状态,因为水藻的状态与天气有关,我们用水藻状态来推测出这三天的天气,就需要用到隐马尔科夫模型。

下面我们将介绍一下隐马尔可夫模型

二 隐马尔可夫模型

隐马尔可夫模型定义

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

隐马尔可夫模型的组成
(这一块看的比较懵没关系,下面会结合例子解释哦)

设 Q是所有可能的状态集合 Q ={q1,q2,…qN} V是所有可能的观测的集合 V={v1,v2,…vM}

N是可能的状态数,M是可能的观测数

I 是长度为T的状态序列 I={i1,i2,…iT}

O 是状态序列对应的观测序列 O={o1,o2,…oT}

隐马尔可夫模型由以下三部分组成

1 初始状态概率向量 π

π=(πi)

其中 πi=P(i1 = qi) 表示在时刻 t=1 处于状态qi的概率

2 状态转移概率矩阵 A

A=[aij] N*N

其中aij = P( it+1 = qj | it = qi) 表示在t时刻处于状态qi 的情况下在t+1时刻转移到状态qj 的概率。

3 观测概率矩阵 B

B = [ bj(k) ] N*M

bj(k) = P(ot = vk| it = qj) 表示在时刻 t 处于状态qj 的条件下生成观测vk 的概率。

隐马尔可夫模型一般表示为

我们来看一个具体的例子体会一下这些符号都是什么意思

我们有三种骰子 分别是六面体骰子(它的值为1,2,3,4,5,6) 四面体骰子(它的值为1,2,3,4) 八面体骰子 (它的值为1,2,3,4,5,6,7,8) 把这三种骰子放到一个盒子中 有放回的去抽一个骰子,拿到这个骰子之后,抛起这个骰子记录它的数字。重复这个动作多次,得到一个数字序列。
假设我们做了10次这个动作 得到的序列为 1,6,3,5,2,7,3,5,2,4

假设状态转换图是这样的

(解释一下: 假如某一次的骰子是D4 那下一次抽到的骰子是D4的概率是0.1 ,下一次抽到的骰子是D8的概率是 0.4 下一次抽到的骰子是D6 的概率是0.5.)

题目介绍完了,我们来分析一下

在本例中,我们的状态就是不同种类的骰子
所以 Q={D4,D6,D8} N=3

我们的观测集合就是骰子上的数字可能的情况
V={1,2,3,4,5,6,7,8} M=8

我们的观测序列是 多次掷骰子得到的一个数字序列 1,6,3,5,2,7,3,5,2,4

初始时刻 我们从盒子里选择一个骰子,因为是随机选择,抽到每一个骰子的概率都是 1/3.

则初始状态向量 π =(1/3,1/3,1/3)

状态转移概率矩阵 A (根据上方给出的状态转换图得到)
观测概率矩阵 B (在某一状态下,生成某一观测的概率)

隐马尔可夫模型的两个假设

齐次马尔可夫性假设,即假设隐藏的马尔可夫链在任意时刻 t 的状态只依赖于其前一时刻的状态

观测独立性假设,即假设任意时刻的观测只依赖于该时刻的马尔可夫链的状态


隐马尔可夫模型有三个需要解决的问题分别是概率计算问题,学习问题,预测问题。在下文将一 一 介绍。

三 概率计算问题

概率计算问题指的是给定一个隐马尔可夫模型 λ =(A,B,π) ,和观测序列O = (o1, o2, … , oT), 在模型 λ 下观测序列O 出现的概率P(OIλ)。

直接计算法

这是一种理论上可行,但是由于计算量太大,导致计算上不可行的方法,了解即可。

前向算法

先介绍一个概念: 前向概率

给定隐马尔可夫模型 λ,定义到时刻 t 部分观测序列为 o1, o2, … , ot 且状态为 qi 的概率为前向概率,记作 αt(i) = P(o1,o2,…,ot, it=qi| λ)


前向算法可以递推地求得前向概率αt(i) 从而得到观测序列概率 P(OIλ)。

观测序列概率的前向算法如下:

前向算法的一些推导


前向算法计算例子

后向算法

后向概率

给定隐马尔可夫模型 λ,定义在时刻 t 状态为 qi 的条件下,从 t+1 到 T 的部分观测序列为 Ot+1, Ot+2, … , OT的概率为后向概率,记作βt(i) = P(Ot+1, Ot+2 ,…,OT| it = qi, λ)


观测序列概率的后向算法


后向算法相关推导

利用前向概率和后向概率的定义可以将观测序列概率 P(OIλ) 统一写成

我们可以根据前向概率和后向概率来表示一些概率和期望值的计算。
根据以上则

在观测O下状态 i 出现的期望值:
在观测 O 下由状态 i 转移的期望值:
在观测O下由状态 i 转移到状态 j 的期望值:

四 隐马尔可夫模型的学习问题

假设给定训练数据只包含 S 个长度为 T 的观测序列 {O1,O2,…, Os} 而没有对应的状态序列,隐马尔可夫模型的学习问题的目标是学习隐马尔可夫模型 λ = (A, B, π )的参数。我们将观测序列数据看作观测数据 O,状态序列数据看作不可观测的隐数据 I,那么隐马尔可夫模型事实上是一个含有隐变量的概率模型.

它的参数学习可以由 EM 算法实现,该算法命名为Baum-Welch.

下面给出用EM算法求解隐马尔可夫模型参数的详细推导

参数估计为

五 隐马尔可夫模型的预测问题

隐马尔可夫模型的预测问题,也称为解码问题。已知模型 λ = (A, B, π ) 和观测序列O=(o1,o2,…oT),求对给定观测序列条件概率P(I |O) 最大的状态序列I=(i1,i2,…iT). 即给定观测序列,求最有可能的对应的状态序列。

我们用的方法是维特比算法,下面介绍一下维特比算法。

维特比算法是一个基于动态规划思想的方法,它把求解状态序列看作寻找一条最优路径。


维特比算法是这样的


维特比算法示例
该示例代码实现如下

class Viterbi:def __init__(self,o,A,B,PI,index):self.o=oself.A=Aself.B=Bself.index = indexself.N=self.A.shape[0] #状态集合有多少元素self.M = len(self.index)  # 观测集合有多少元素self.T =len(self.o) #观测序列一共有多少值self.PI=PI # 初始状态概率self.delte=[[0]*self.N]*self.Tself.I=[] #得到的状态序列是self.keci=[[0]*self.N]*self.Tdef cal_delte(self):# 在书中时刻t的取值是 1到 T 但是写代码数组是从0 开始的 方便起见 我们讲t也从0开始o1=self.o[0]#第一个观测变量是o1_index=self.index[o1] #第一个观测变量的下标是for i in range(self.N):self.delte[0][i] = self.PI[i]*self.B[i][o1_index]for t in range(1,self.T):#从时刻t=1 开始 到T-1ot=self.o[t]ot_index=self.index[ot]for i in range(self.N):max=0maxj=0for j in range(self.N):a = self.delte[t-1][j] *self.A[j][i]*self.B[i][ot_index]if a>max:max=amaxj=jself.delte[t][i]= maxself.keci[t][i]=maxjdef cal_max_path(self):max=0maxi=0path=[]for i in range(self.N):a=self.delte[self.T-1][i]if a>max:max=amaxi=ipath.append(maxi+1)for t in range(self.T-1,0,-1):maxi=self.keci[t][maxi]path.append(maxi+1)for i in range(len(path)-1,-1,-1):self.I.append(path[i])print(self.I)
A=np.array([[0.5,0.2,0.3],[0.3,0.5,0.2],[0.2,0.3,0.5]])
B=np.array([[0.5,0.5],[0.4,0.6],[0.7,0.3]])
PI=np.array([[0.2],[0.4],[0.4]])
o=['红','白','红']
index={'红':0,'白':1}
hmm=Viterbi(o,A,B,PI,index)
hmm.cal_delte()
hmm.cal_max_path()

六 隐马尔可夫模型代码实现

class HMM:def __init__(self,o,status,observe,n):self.o=o #观测数据self.status= status #状态集合self.observe=observe# 观测集合self.N = len(self.status)  # 状态集合有多少元素self.M = len(observe)  # 观测集合有多少元素self.A = [[1 / self.N] * self.N] * self.Nself.B = [[1/self.M]*self.M]* self.Nself.T = len(self.o)  # 观测序列一共有多少值self.PI = [1/self.N]*self.N  # 初始状态概率 N个状态 每个状态的概率是1/Nself.delte = [[0] * self.N] * self.Tself.I = []  # 得到的状态序列是self.psi = [[0] * self.N] * self.Tself.a=self.cal_a()self.b=self.cal_b()self.n=ndef cal_a(self):#计算前向概率o1=self.o[0]o1_index=self.observe[o1]a=[[0]*self.N]*self.Tfor i in range(self.N):a[0][i]=self.PI[i]*self.B[i][o1_index]for t in range(1, self.T):  # 从时刻t=1 开始 到T-1ot=self.o[t]ot_index = self.observe[ot]for i in range(self.N):sum=0for j in range(self.N):sum += a[t-1][j]*self.A[j][i]a[t][i]=sum*self.B[i][ot_index]return adef cal_b(self):#计算后向概率b = [[0] * self.N] * self.Tfor i in range(self.N):b[self.T-1][i] = 1for t in range(self.T-2,-1,-1):ot_add_1 = self.o[t+1]ot_ot_add_1_index = self.observe[ot_add_1]for i in range(self.N):sum=0for j in range(self.N):sum+=self.A[i][j]*self.B[j][ot_ot_add_1_index]*b[t+1][j]b[t][i]=sumreturn bdef cal_gamma(self, t, i):# 计算李航《统计学习方法》 p202 公式10.24sum = 0for j in range(self.N):sum += self.a[t][j] * self.b[t][j]# print(self.a)# print(self.b)return self.a[t][i] * self.b[t][i] / sumdef cal_xi(self, t, i1, j1):# 计算李航《统计学习方法》 p203 公式10.26sum = 0ot_add_1 = self.o[t + 1]ot_ot_add_1_index = self.observe[ot_add_1]for i in range(self.N):for j in range(self.N):sum += self.a[t][i] * self.A[i][j] * self.B[j][ot_ot_add_1_index] * self.b[t + 1][j]p = self.a[t][i1] * self.A[i1][j1] * self.B[j1][ot_ot_add_1_index] * self.b[t + 1][j1]return p / sumdef update_A(self):for i in range(self.N):for j in range(self.N):sum1=0sum2=0for t in range(self.T - 1):sum1+=self.cal_xi(t,i,j)sum2+=self.cal_gamma(t,i)self.A[i][j]=sum1/sum2def update_B(self):for j in range(self.N):for k in range(self.M):sum1=0sum2=0for t in range(self.T):ot=self.o[t]ot_index=self.observe[ot]if ot_index == k:sum1+=self.cal_gamma(t,j)sum2+=self.cal_gamma(t,j)self.B[j][k]=sum1/sum2def update_pi(self):for i in range(self.N):self.PI[i]=self.cal_gamma(0,i)def fit(self):for i in range(self.n):print(i)self.update_A()self.update_B()self.update_pi()self.a = self.cal_a()self.b = self.cal_b()def cal_delte(self):# 在书中时刻t的取值是 1到 T 但是写代码数组是从0 开始的 方便起见 我们讲t也从0开始o1=self.o[0]#第一个观测变量是o1_index=self.observe[o1] #第一个观测变量的下标是for i in range(self.N):self.delte[0][i] = self.PI[i]*self.B[i][o1_index]for t in range(1,self.T):#从时刻t=1 开始 到T-1ot=self.o[t]ot_index=self.observe[ot]for i in range(self.N):max=0maxj=0for j in range(self.N):a = self.delte[t-1][j] *self.A[j][i]*self.B[i][ot_index]if a>max:max=amaxj=jself.delte[t][i]= maxself.psi[t][i]=maxjdef cal_max_path(self):max=0maxi=0path=[]for i in range(self.N):a=self.delte[self.T-1][i]if a>max:max=amaxi=ipath.append(maxi+1)for t in range(self.T-1,0,-1):maxi=self.psi[t][maxi]path.append(maxi+1)for i in range(len(path)-1,-1,-1):self.I.append(path[i])print(self.I)o=['红','白','红']
observe={'红':0,'白':1}
status=[1,2,3]
hmm=HMM(o,status,observe,200)
hmm.fit()
hmm.cal_delte()
hmm.cal_max_path()

参考

李航《统计学习方法》

b站视频 机器学习-白板推导系列(十四)-隐马尔可夫模型HMM

统计学习方法笔记-隐马尔可夫模型(内含Python代码实现)相关推荐

  1. 《统计学习方法》——隐马尔可夫模型(上)

    引言 这是<统计学习方法>第二版的读书笔记,由于包含书上所有公式的推导和大量的图示,因此文章较长,正文分成三篇,以及课后习题解答,在习题解答中用Numpy实现了维特比算法和前向后向算法. ...

  2. 《统计学习方法》——隐马尔可夫模型

        隐马尔可夫模型(hidden Markov model,HMM)是可用于标注问题的统计学模型,描述由隐藏的马尔可夫链生成观测序列的过程,属于生成模型. 10.1 隐马尔可夫模型的基本概念 10 ...

  3. 《统计学习方法》——10. 隐马尔可夫模型(Python实现)

    本文主要是在阅读过程中对本书的一些概念摘录,包括一些个人的理解,主要是思想理解不涉及到复杂的公式推导.会不定期更新,若有不准确的地方,欢迎留言指正交流 本文完整代码 github 地址:https:/ ...

  4. 灰色马尔可夫模型的Python代码实现

    本文通过Python实现了灰色模型的编写,并经过spssau初步验证,此外,本文将随机过程的马尔可夫和灰色模型相结合,以此来预测具有随机性.未来性的时间序列 文章目录 灰色模型 前沿 1.什么是灰色模 ...

  5. 10_隐马尔科夫模型HMM2_统计学习方法

    文章目录 四.学习算法 1.监督学习方法 2.非监督学习方法(Baum-Welch算法) 五.预测算法 1.近似算法 2.维特比算法 (1)最优路径特性 (2)两个变量 (3)维特比算法流程 隐马尔科 ...

  6. 10_隐马尔科夫模型HMM1_统计学习方法

    文章目录 一.几个基本概念 1.隐马尔可夫模型 2.马尔科夫链 3.随机过程 4.马尔科夫性质 二.隐马尔科夫模型 1.隐马尔科夫模型的引入 2.隐马尔科夫模型定义 3.隐马尔科夫模型的两个假设 4. ...

  7. 全面理解隐马尔可夫模型

    文章目录 隐马尔可夫模型的基本概念 隐马尔可夫模型的定义 观测序列的生成 隐马尔可夫模型的三个基本问题 概率计算算法 直接计算法 前向算法 后向算法 一些概率与期望值的计算 学习算法 监督学习方法 转 ...

  8. m基于隐马尔科夫模型(HMM)的手机用户行为预测(MMUB)算法matlab仿真

    目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 隐马尔可夫模型(Hidden Markov Model,HMM)是一种统计模型,广泛应用在语音识别, ...

  9. 马尔可夫模型及隐马尔可夫模型(HMM)

    马尔可夫模型 马尔可夫模型是由Andrei A. Markov于1913年提出的 ∙ ∙ 设  S S是一个由有限个状态组成的集合 S={1,2,3,-,n−1,n} S={1,2,3,-,n−1,n ...

最新文章

  1. 如何 判断 设备 是否 连接 上 了 wifi
  2. PHP GD库---之商详合成分享图片
  3. 计算机维修工国家职业标准,计算机维修工国家职业标准.pdf
  4. 【Coursera】SecondWeek(2)
  5. 第二个冲刺周期第二天
  6. 千里达v1000时速_重新定义性价比 千里达V1000碳架山地车 评测
  7. java 实现热搜_搜索推荐系统根据用户搜索频率(热搜)排序
  8. 基于51单片机——60秒倒计时时钟
  9. vsftp创建虚拟账户
  10. 深入ReentrantLock底层原理01
  11. 两台计算机能否共用一个ip地址,多台电脑共用一个WIFI,IP地址是不是一样?
  12. jspdf插件实现jsp页面导出为pdf文件
  13. 浏览器兼容问题,一直是自己最头疼,一直回避的问题,今天看得到了一些启发,发奋今天开始研究这个,哈哈,以下为转载文章,好好学习。...
  14. Android单元测试读写文件,Android-单元测试
  15. ISO8583报文签到怎么拿到服务器批次号和流水号
  16. 水位传感器c语言程序,简单水位报警器(水浸传感器)单片机源码
  17. java gbk转机内码_Java实现的UTF-8,GBK,Unicode编码相互转换的代码
  18. Mac下常用快捷键和chrome插件
  19. 【ACWing】1126. 最小花费
  20. 关于数据库建模,概念模型、逻辑模型、物理模型的区别和转化

热门文章

  1. springboot 7天签到功能设计 数据库表设计 加代码
  2. 复旦大学自考计算机软件难度,复旦大学自考本科难吗
  3. 阿里某员工:存够一百万不想再做程序员,回老家过简单生活
  4. Java多线程-Thread常用方法
  5. 计算机的教育领域的应用研究,浅析计算机科学技术在现代教育中的应用研究
  6. 深度学习(自监督:SimSiam)——Exploring Simple Siamese Representation Learning
  7. java获取上级菜单_java在多菜单中返回上级菜单如何实现
  8. 《加强5G公众移动通信系统无线电频率共享管理》最新解读来啦
  9. 安装部署halo博客
  10. 这可能是史上最全的 Python 算法集!| 技术头条