史诗级干货长文hmm模型(代码片段)

ZSYL ZSYL     2022-12-13     243

关键词:

1. 马尔科夫链

在机器学习算法中,马尔可夫链(Markov chain)是个很重要的概念。马尔可夫链(Markov chain),⼜称离散时间马尔可夫链(discrete-time Markov chain),因俄国数学家安德烈·⻢尔可夫(俄语:Андрей Андреевич Марков)得名。

1.1 简介

马尔科夫链即为状态空间中从⼀个状态到另⼀个状态转换的随机过程。

1.2 经典举例

下图中的马尔科夫链是⽤来表示股市模型,共有三种状态:⽜市(Bull market), 熊市(Bear market)和横盘 (Stagnant market)。

每⼀个状态都以⼀定的概率转化到下⼀个状态。比如,牛市以0.025的概率转化到横盘的状态。

1.3 小结

  • 马尔科夫链即为
    • 状态空间中从⼀个状态到另⼀个状态转换的随机过程。
    • 该过程要求具备“⽆记忆”的性质:
      • 下⼀状态的概率分布只能由当前状态决定,在时间序列中它前⾯的事件均与之⽆关。

2. HMM简介

隐⻢尔可夫模型(Hidden Markov Model,HMM)是统计模型,它⽤来描述⼀个含有隐含未知参数的⻢尔可夫过程。 其难点是从可观察的参数中确定该过程的隐含参数。然后利⽤这些参数来作进⼀步的分析,例如模式识别

2.1 简单案例

下⾯我们⼀起⽤⼀个简单的例⼦来阐述:

  • 假设我⼿⾥有三个不同的骰⼦。
    • 第⼀个骰⼦是我们平常⻅的骰⼦(称这个骰⼦为D6),6个⾯,每个⾯(1,2,3,4,5,6)出现的概率是 1/6。
    • 第⼆个骰⼦是个四⾯体(称这个骰⼦为D4),每个⾯(1,2,3,4)出现的概率是1/4。
    • 第三个骰⼦有⼋个⾯(称这个骰⼦为D8),每个⾯(1,2,3,4,5,6,7,8)出现的概率是1/8。





其实对于HMM来说,如果提前知道所有隐含状态之间的转换概率和所有隐含状态到所有可见状态之间的输出概率,做 模拟是相当容易的。但是应⽤HMM模型时候呢,往往是缺失了⼀部分信息的。

  • 有时候你知道骰⼦有⼏种,每种骰⼦是什么,但是不知道掷出来的骰⼦序列;
  • 有时候你只是看到了很多次掷骰⼦的结果,剩下的什么都不知道。

如果应⽤算法去估计这些缺失的信息,就成了⼀个很重要的问题。

2.2 案例进阶

2.2.1 问题阐述

2.2.2 问题解决

2.2.2.1 一个简单问题【对应问题2】

其实这个问题实⽤价值不⾼。由于对下⾯较难的问题有帮助,所以先在这⾥提⼀下。

  • 知道骰⼦有⼏种,每种骰⼦是什么,每次掷的都是什么骰⼦,根据掷骰⼦掷出的结果,求产⽣这个结果的概率。

2.2.2.2 看见不可见的,破解骰子序列【对应问题1】




写到这⾥,⼤家应该看出点规律了。既然掷骰⼦⼀、⼆、三次可以算,掷多少次都可以以此类推。 我们发现,我们要求最⼤概率骰⼦序列时要做这么⼏件事情。

  • ⾸先,不管序列多⻓,要从序列⻓度为1算起,算序列⻓度为1时取到每个骰⼦的最⼤概率。
  • 然后,逐渐增加⻓度,每增加⼀次⻓度,重新算⼀遍在这个⻓度下最后⼀个位置取到每个骰⼦的最⼤概率。因为上 ⼀个⻓度下的取到每个骰⼦的最⼤概率都算过了,重新计算的话其实不难。
  • 当我们算到最后⼀位时,就知道最后⼀位是哪个骰⼦的概率最⼤了。然后,我们要把对应这个最⼤概率的序列从后往前推出来。

2.2.2.3 谁动了我的骰子?【对应问题3】

⽐如说你怀疑⾃⼰的六⾯骰被赌场动过⼿脚了,有可能被换成另⼀种六⾯骰,这种六⾯骰掷出来是1的概率更⼤,是 1/2,掷出来是2,3,4,5,6的概率是1/10。你怎么办么?

  • 答案很简单,算⼀算正常的三个骰⼦掷出⼀段序列的概率,再算⼀算不正常的六⾯骰和另外两个正常骰⼦掷出这段序列的概率。如果前者⽐后者⼩,你就要⼩⼼了。

⽐如说掷骰⼦的结果是:


要算⽤正常的三个骰⼦掷出这个结果的概率,其实就是将所有可能情况的概率进⾏加和计算。

同样,简单⽽暴⼒的⽅法就是把穷举所有的骰⼦序列,还是计算每个骰⼦序列对应的概率,但是这回,我们不挑最⼤值 了,⽽是把所有算出来的概率相加,得到的总概率就是我们要求的结果。这个⽅法依然不能应⽤于太⻓的骰⼦序列(⻢ 尔可夫链)。 我们会应⽤⼀个和前⼀个问题类似的解法,只不过前⼀个问题关⼼的是概率最⼤值,这个问题关⼼的是概率之和。解决这个问题的算法叫做前向算法(forward algorithm)。

⾸先,如果我们只掷⼀次骰⼦:


看到结果为1.产⽣这个结果的总概率可以按照如下计算,总概率为0.18:


把这个情况拓展,我们掷两次骰子:


看到结果为1,6.产⽣这个结果的总概率可以按照如下计算,总概率为0.05:


继续拓展,我们掷三次骰⼦:


看到结果为1,6,3.产⽣这个结果的总概率可以按照如下计算,总概率为0.03:


同样的,我们⼀步⼀步的算,有多长算多长,再⻓的⻢尔可夫链总能算出来的。

⽤同样的⽅法,也可以算出不正常的六⾯骰和另外两个正常骰⼦掷出这段序列的概率,然后我们⽐较⼀下这两个概率⼤ ⼩,就能知道你的骰⼦是不是被⼈换了。

2.3 小结

  • 隐马尔可夫模型(Hidden Markov Model,HMM)是统计模型,它⽤来描述⼀个含有隐含未知参数的⻢尔可夫过程。
  • 常见术语
    • 可见状态链
    • 隐含状态链
    • 转换概率
    • 输出概率

3. HMM模型基础

3.1 什么样的问题需要HMM模型

3.2 HMM模型的定义


HMM模型做了两个很重要的假设如下:

1) 齐次马尔科夫链假设。


2) 观测独立性假设。

3.3 一个HMM模型实例

下⾯我们⽤⼀个简单的实例来描述上⾯抽象出的HMM模型。这是⼀个盒⼦与球的模型。

例⼦来源于李航的《统计学习方法》。

假设我们有3个盒⼦,每个盒⼦⾥都有红⾊和⽩⾊两种球,这三个盒⼦里球的数量分别是:

按照下⾯的⽅法从盒⼦⾥抽球,开始的时候,

  • 从第⼀个盒⼦抽球的概率是0.2,
  • 从第⼆个盒⼦抽球的概率是0.4,
  • 从第三个盒⼦抽球的概率是0.4。

3.4 HMM观测序列的生成

3.5 HMM模型的三个基本问题

3.4 小结

  • 什么样的问题可以⽤HMM模型解决
    • 基于序列的,⽐如时间序列;
    • 问题中包含两类数据,⼀类是可以观测到的观测序列;另⼀类是不能观察到的隐藏状态序列。
  • HMM模型的两个重要假设
    • 其次⻢尔科夫链假设
    • 观测独⽴性假设
  • HMM模型的三个基本问题
    • 评估观察序列概率—— 前向后向的概率计算
    • 预测问题,也称为解码问题 ——维特⽐(Viterbi)算法
    • 模型参数学习问题 —— 鲍姆-⻙尔奇(Baum-Welch)算法

4. 前向后向算法评估观察序列概率

4.1 回顾HMM问题⼀:求观测序列的概率



4.2 用前向算法求HMM观测序列的概率

前向后向算法是前向算法和后向算法的统称,这两个算法都可以⽤来求HMM观测序列的概率。我们先来看看前向算法 是如何求解这个问题的。

4.2.1 流程梳理


4.2.2 算法总结


从递推公式可以看出,我们的算法时间复杂度是O(TN2),比暴⼒解法的时间复杂度O(T NT )少了⼏个数量级。

4.3 HMM前向算法求解实例



4.4 用后向算法求HMM观测序列的概率

4.4.1 流程梳理

熟悉了⽤前向算法求HMM观测序列的概率,现在我们再来看看怎么⽤后向算法求HMM观测序列的概率。

后向算法和前向算法⾮常类似,都是⽤的动态规划,唯⼀的区别是选择的局部状态不同,后向算法⽤的是“后向概率”。

4.4.2 后向算法流程


4.5 小结


5. 维特比算法解码隐藏状态序列

学习⽬标

  • 知道维特⽐算法解码隐藏状态序列

在本篇我们会讨论维特⽐算法解码隐藏状态序列,即给定模型和观测序列,求给定观测序列条件下,最可能出现的对应 的隐藏状态序列。

HMM模型的解码问题最常⽤的算法是维特⽐算法,当然也有其他的算法可以求解这个问题。

同时维特⽐算法是⼀个通⽤的求序列最短路径的动态规划算法,也可以⽤于很多其他问题。

5.1 HMM最可能隐藏状态序列求解概述

5.2 维特⽐算法概述

维特⽐算法是⼀个通⽤的解码算法,是基于动态规划的求序列最短路径的⽅法。

既然是动态规划算法,那么就需要找到合适的局部状态,以及局部状态的递推公式。在HMM中,维特⽐算法定义了两 个局部状态⽤于递推。

  1. 第⼀个局部状态是在时刻t隐藏状态为i所有可能的状态转移路径i ,i , …i 中的概率最⼤值。

5.3 维特⽐算法流程总结


5.4 HMM维特⽐算法求解实例

下⾯我们仍然⽤盒⼦与球的例⼦来看看HMM维特⽐算法求解。 我们的观察集合是:

6. 鲍姆-韦尔奇算法简介

学习⽬标

  • 了解鲍姆-⻙尔奇算法

模型参数学习问题 —— 鲍姆-⻙尔奇(Baum-Welch)算法(状态未知) ,

6.2 鲍姆-⻙尔奇算法原理


7. HMM模型API介绍

7.1 API的安装

官⽹链接:https://hmmlearn.readthedocs.io/en/latest/

pip3 install hmmlearn

7.2 hmmlearn介绍

7.3 MultinomialHMM实例

下⾯我们⽤我们在前⾯讲的关于球的那个例⼦使⽤MultinomialHMM跑⼀遍。

import numpy as np 
from hmmlearn import hmm
# 设定隐藏状态的集合 
states = ["box 1", "box 2", "box3"] 
n_states = len(states) 

# 设定观察状态的集合 
observations = ["red", "white"] 
n_observations = len(observations) 

# 设定初始状态分布 
start_probability = np.array([0.2, 0.4, 0.4]) 

# 设定状态转移概率分布矩阵 
transition_probability = np.array([ 
	[0.5, 0.2, 0.3], 
	[0.3, 0.5, 0.2], 
	[0.2, 0.3, 0.5]
])

# 设定观测状态概率矩阵 
emission_probability = np.array([ 
	[0.5, 0.5], 
	[0.4, 0.6], 
	[0.7, 0.3] 
])
# 设定模型参数 
model = hmm.MultinomialHMM(n_components=n_states) 
model.startprob_=start_probability # 初始状态分布 
model.transmat_=transition_probability # 状态转移概率分布矩阵 
model.emissionprob_=emission_probability # 观测状态概率矩阵

现在我们来跑⼀跑HMM问题三维特⽐算法的解码过程,使⽤和之前⼀样的观测序列来解码,代码如下:

seen = np.array([[0,1,0]]).T # 设定观测序列 
box = model.predict(seen) 

print("球的观测顺序为:\\n", ", ".join(map(lambda x: observations[x], seen.flatten()))) 
# 注意:需要使⽤flatten⽅法,把seen从⼆维变成⼀维 
print("最可能的隐藏状态序列为:\\n"", ".join(map(lambda x: states[x], box)))

我们再来看看求HMM问题⼀的观测序列的概率的问题,代码如下:

print(model.score(seen)) # 输出结果是:-2.03854530992

要注意的是score函数返回的是以⾃然对数为底的对数概率值,我们在HMM问题⼀中⼿动计算的结果是未取对数的原始 概率是0.13022。对⽐⼀下:

import math 
math.exp(-2.038545309915233) 
# ln0.13022≈−2.0385 
# 输出结果是:0.13021800000000003

加油!

感谢!

努力!

史诗级干货长文集成学习进阶(xgboost&lightgbm)(代码片段)

集成学习进阶1.xgboost算法原理1.1最优模型的构建方法1.2XGBoost的目标函数推导1.2.1目标函数确定1.2.2CART树的介绍1.2.3树的复杂度定义1.2.3.1定义每课树的复杂度1.2.3.2树的复杂度举例1.2.4目标函数推导1.3XGBoost的回归树构建方法1.3.1计算... 查看详情

史诗级干货长文集成学习算法(代码片段)

集成学习算法1.集成学习算法简介1.1什么是集成学习1.2复习:机器学习的两个核心任务1.3集成学习中boosting和Bagging1.4小结2.Bagging和随机森林2.1Bagging集成原理2.2随机森林构造过程2.3随机森林api介绍2.4随机森林预测案例2.5bagging集... 查看详情

史诗级干货长文线性回归算法(代码片段)

线性回归算法前言1.线性回归简介1.1线性回归应用场景1.2什么是线性回归1.2.1定义与公式1.2.2线性回归的特征与目标的关系分析2.线性回归API初步使用2.1线性回归API2.2举例2.2.1步骤分析2.2.2代码过程3.数学:求导3.1常见函数的导数3.2导... 查看详情

史诗级干货长文朴素贝叶斯(代码片段)

朴素贝叶斯学习目标1.朴素贝叶斯算法简介2.概率基础复习2.1概率定义2.2案例:判断女神对你的喜欢情况2.3联合概率、条件概率与相互独立2.4贝叶斯公式2.4.1公式介绍2.4.2案例计算2.4.3文章分类计算2.5小结3.案例:商品评论... 查看详情

史诗级干货长文k-近邻算法(代码片段)

K-近邻算法前言1.K-近邻算法简介1.1什么是K-近邻算法1.2K-近邻算法(KNN)概念1.3电影类型分析1.4KNN算法流程总结2.KNN算法API初步使用2.1Scikit-learn工具介绍2.1.1安装Scikit-learn2.1.2Scikit-learn包含的内容2.2K-近邻算法API2.3案例2.3.1步骤分析2.3.2... 查看详情

史诗级干货长文支持向量机(代码片段)

支持向量机SVM1.SVM算法简介1.1SVM算法导入1.2SVM算法定义1.2.1定义1.2.2超平面最大间隔介绍1.2.3硬间隔和软间隔1.2.3.1硬间隔分类1.2.3.2软间隔分类1.3小结2.SVM算法API初步使用3.SVM算法原理3.1定义输入数据3.2线性可分支持向量机3.3SVM的计... 查看详情

史诗级干货长文决策树算法(代码片段)

决策树算法1.决策树算法简介2.决策树分类原理3.cart剪枝3.1为什么要剪枝?3.2常用的减枝方法3.2.1预剪枝3.2.2后剪枝3.3小结4.特征工程-特征提取5.决策树算法API6.案例:泰坦尼克号乘客生存预测7.回归决策树1.决策树算法简介决策... 查看详情

nlp电商评论处理-史诗级长文(代码片段)

#autherbioamin#nlpof电商评论#-*-conding=utf-8-*-importnumpyasnpimportpandasaspd#画图的包importmatplotlib.pyplotaspltimportseabornassnsplt.rcParams[‘font.sans-serif‘]=[‘SimHei‘]plt.rcParams[‘axes.unicode_minus 查看详情

史诗级选手之函数(代码片段)

函数上来就抛一个例子先赏赏眼>>>>>>>packagemainimport"fmt"funcadd(xint,yint)intreturnx+yfuncmain()fmt.Println(add(42,13))函数定义语法funcfunc_name(arg1type1,arg2type2)return_typefunctio 查看详情

认识hmm与crf模型(代码片段)

学习目标:了解HMM与CRF模型的输入和输出.了解HMM与CRF模型的作用.了解HMM与CRF模型的使用过程.了解HMM与CRF模型之间的差异.了解HMM和CRF的发展现状.HMM模型的输入和输出HMM(HiddenMarkovModel),中文称作隐含马尔科夫模型,因俄国数学... 查看详情

nlp带你认识经典的序列模型-hmm与crf(代码片段)

认识经典的序列模型HMM与CRF1.HMM模型1.1HMM模型的输入和输出1.2HMM模型的作用1.3HMM模型使用过程简述2.CRF模型2.1CRF模型的输入和输出2.2CRF模型的作用2.3CRF模型使用过程简述3.HMM与CRF模型之间差异4.HMM和CRF的发展现状5.总结1.HMM模型1.1HMM... 查看详情

springboot❤springclould常用注解史诗级汇总(代码片段)

什么是注解?Java注解是附加在代码中的一些元信息,用于一些工具在编译、运行时进行解析和使用,起到说明、配置的功能注解本质上继承Annotation接口,我们可以通过反射获取注解的相关信息,从而做些逻辑操作springboot里... 查看详情

微信“史诗级”更新,小而美终于回来啦!(代码片段)

...,版本号也来到了8.0.30。此次更新又被业界称之为“史诗级”更新,主要原因是新版本微信安装包体 查看详情

微信又变天,“史诗级”更新!网友“怕”了……(代码片段)

...完成PC端的登录。对此,网友表示,该功能属于“史诗级”更新,有网友调侃“别让我媳妇看到这个功能”ÿ 查看详情

一行小错为何产生巨大破坏-facebook史诗级故障大反思(代码片段)

...是生存的障碍,傲慢才是。10月4日FaceBook发生了一次史诗级中断事故,故障期间FaceBook所有旗下APP全面对外服务中断,而且故障的时间长达7个小时之久。根据Facebook最新的声明来看,故障的原因是由于工程师错误地... 查看详情

一行小错为何产生巨大破坏-facebook史诗级故障大反思(代码片段)

...是生存的障碍,傲慢才是。10月4日FaceBook发生了一次史诗级中断事故,故障期间FaceBook所有旗下APP全面对外服务中断,而且故障的时间长达7个小时之久。根据Facebook最新的声明来看,故障的原因是由于工程师错误地... 查看详情

史诗级更新,vscode可无缝调试浏览器了!(代码片段)

2021-07-16微软发布了一篇博客专门介绍了这个功能,VSCODE牛逼!在此之前,你想要在vscode内调试chrome或者edge需要借助于ChromeDebugger或者theMicrosoftEdgeDebuggerextension这两款vscode扩展。并且更重要的是,其仅能提供最基本... 查看详情

[长文干货]micropython移植到野火stm32f429开发板(代码片段)

最近通过参考网上的文章,成功将MicroPython移植到野火STM32F429开发板上,给大家分享一下自己的移植过程,可以作为STM32系列移植MicroPY的参考。1.移植前准备工作实验环境:WIN1064位+VmwareWorkstation虚拟机软件+Ub... 查看详情