[白话解析]以水浒传为例学习隐马尔可夫模型

[白话解析]以水浒传为例学习隐马尔可夫模型

0x00 摘要

本文将尽可能使用易懂的方式,尽量不涉及数学公式,而是从总体的思路上来看,运用感性直觉的思考来解释隐马尔可夫模型。而且从名著中找了个具体应用场景来帮助你们深刻这个概念。html

0x01 说明

在机器学习过程当中,会遇到不少晦涩的概念,相关数学公式不少,你们理解起来颇有困难。遇到相似状况,咱们应该多从直觉角度入手思考,用类别或者举例来附会,这样每每会有更好的效果。java

我在讲解论述过程当中给本身的要求是:在生活中或者名著中找一个例子,而后用本身的话语阐述出来。git

0x02 几率图

几率图模型是用图来表示变量几率依赖关系的理论,结合几率论与图论的知识,利用图来表示与模型有关的变量的联合几率分布。由图灵奖得到者Pearl开发出来。github

若是用一个词来形容几率图模型(Probabilistic Graphical Model)的话,那就是“优雅”。对于一个实际问题,咱们但愿可以挖掘隐含在数据中的知识。几率图模型构建了这样一幅图,用观测结点表示观测到的数据,用隐含结点表示潜在的知识,用边来描述知识与数据的相互关系,最后基于这样的关系图得到一个几率分布,很是“优雅”地解决了问题。算法

几率图中的节点分为隐含节点和观测节点,边分为有向边和无向边。从几率论的角度,节点对应于随机变量,边对应于随机变量的依赖或相关关系,其中有向边表示单向的依赖,无向边表示相互依赖关系网络

几率图模型分为贝叶斯网络(Bayesian Network)和马尔可夫网络(Markov Network)两大类。贝叶斯网络能够用一个有向图结构表示,马尔可夫网络能够表 示成一个无向图的网络结构。更详细地说,几率图模型包括了朴素贝叶斯模型、最大熵模型、隐马尔可夫模型、条件随机场、主题模型等,在机器学习的诸多场景中都有着普遍的应用。机器学习

0x03 生成式模型和判别式模型的区别

如今咱们知道,几率图能够分红有向图模型和无向图模型,顾名思义,就是图里面的边是否有方向。那么什么样的模型的边有方向,而什么样的没方向呢?这个很好想到,有方向的表达的是一种推演关系,也就是在A的前提下出现了B,这种模型又叫作生成式模型。而没有方向表达的是一种“这样就对了”的关系,也就是A和B同时存在就对了,这种模型又叫作判别式模型。函数

根据建模的到底是联合几率分布 P(x,y) 仍是条件几率分布 P(y|x)。派生出生成式模型与判别式模型。学习

1. 生成式模型

生成式模型通常用联合几率计算(由于咱们知道A的前提了,能够算联合几率),即经过对观测值和标注数据计算联合几率分布P(x,y)来达到断定估算y的目的。lua

生成式模型是模拟数据的生成过程,两类随机变量存在因果前后关系,先有因素 x,后有结果 y,这种因果关系由联合分布模拟:
\[ P(x,y) = P(x)P(y|x) \]
经过联合分布 P(x,y),生成式模型其实间接建模了 P(x):
\[ P(x) = \sum_y P(x,y) \]
须要注意的是,在模型训练中,我学习到的是X与Y的联合模型 P(X,Y) ,也就是说,我在训练阶段是只对 P(X,Y)建模,我须要肯定维护这个联合几率分布的全部的信息参数,要对每一个label (y) 都须要建模。因此没有什么判别边界。

完了以后在inference再对新的sample计算P(Y|X),导出 Y,最终选择最优几率的label为结果,但这已经不属于建模阶段了

这里有两个缺陷:

  • P(x) 很难准确估计,由于特征之间并不是相互独立,而是存在错综复杂的依赖关系。
  • P(x) 在分类中也没有直接做用。

为了克服这两个问题,判别式模型出现。

2. 判别式模型

判别式模型通常用条件几率计算(由于咱们不知道前提,因此只能"假设"A条件下B的几率)。即经过求解条件几率分布P(y|x)或者直接计算y的值来预测y。

判别式模型直接跳过了 P(x),直接对条件几率 P(y|x) 建模,就是说,直接根据X特征来对Y建模训练。无论 x 内部存在多复杂的关系,也不影响判别式模型对 y 的判断,因而就可以放心大胆的利用各类各样丰富的、有关联的特征

具体地,个人训练过程是肯定构件 P(Y|X) 模型里面“复杂映射关系”中的参数,对全部的样本只构建一个模型,确认整体判别边界。完了再去inference一批新的sample。观测到输入什么特征,就预测最可能的label。

3. 表明

生成式模型的表明是:n元语法模型、隐马尔可夫模型、朴素贝叶斯模型等。

判别式模型的表明是:最大熵模型、支持向量机、条件随机场、感知机模型等

他们之间的区别是这样的:

判别式模型是这么工做的,他们直接将数据的Y(或者label),根据所提供的features,学习,最后画出了一个明显或者比较明显的边界(具体怎么作到的?经过复杂的函数映射,或者决策叠加等等mechanism),这一点线性LR、线性SVM应该很明显吧。

生成式模型是这么工做的,他们先从训练样本数据中,将全部的数据的分布状况摸透,而后最终肯定一个分布,来做为个人全部的输入数据的分布,而且他是一个联合分布 P(X,Y) (注意X包含全部的特征x_i ,Y包含全部的label)。而后我来了新的样本数据(inference),好,经过学习来的模型的联合分布P(X,Y) ,再结合新样本给的X,经过条件几率就能出来Y
\[ P(类别|特征) = \frac {P(特征|类别)P(类别)}{P(特征)} \]


0x04 马尔可夫系列概念

提到马尔可夫就是一个值跟前面n个值有关,因此也就是条件几率,也就是生成式模型,也就是有向图模型。

马尔可夫假设:每一个事件的发生几率只取决于前一个事件。

马尔可夫链:将知足马尔可夫假设的连续多个事件串联起来,就构成了马尔可夫链。马尔科夫链的节点是状态,边是转移几率,是template CPD的一种有向状态转移表达。

马尔可夫链的两个假设

  • 齐次马尔可夫假设:即t时刻的状态只受t-1时刻状态的影响;

  • 观测独立性假设:即任意时刻的观测只受该时刻所处状态的影响;

马尔科夫模型 是一种无向几率图模型,其与马尔科夫链并非很同样。马尔科夫模型是与贝叶斯模型并列的一种几率图模型。其做用是描述互相影响,互相做用,不存在因果关系的两个随机变量之间的关系。由于做用是相互的,全部马尔科夫模型的边是无向的,或者能够说是双向的。

马尔科夫模型的强大之处在于它解除了贝叶斯模型中的因果关系,这也就使得它能够对不少平等的东西创建相互关系。好比一幅图片的各个像素就是平等的,可是各个像素之间能够相互影响(天在上,地在下)。全部马尔科夫模型被普遍的应用于图像处理/图像理解。

若是把事件具象为单词,那么马尔可夫模型就具象为二元语法模型。马尔可夫模型还能够当作是一个关于时间t的状态转换过程,也就是随机的有限状态机,那么状态序列的几率能够经过计算造成该序列全部状态之间转移弧上的几率乘积得出。

0x05 隐马尔可夫模型

隐马尔可夫模型(Hidden Markov Model,HMM)是统计模型,它用来描述一个含有隐含未知参数的马尔可夫过程。即描述一个系统隐性状态的转移和隐性状态的表现几率。系统的隐性状态指的就是一些外界不便观察(或观察不到)的状态。其难点是从可观察的参数中肯定该过程的隐含参数。而后利用这些参数来做进一步的分析。

HMM是一种生成式模型,它的理论基础是朴素贝叶斯,本质上就相似于咱们将朴素贝叶斯在单样本分类问题上的应用推广到序列样本分类问题上。

好比,HMM是描述两个时序序列联合分布 p(x,y) 的几率模型。

  • x 序列外界可见(外界指的是观测者),称为观测序列(obsevation sequence);

  • y 序列外界不可见,称为状态序列(state sequence)。

好比观测 x 为单词,状态 y 为词性,咱们须要根据单词序列去猜想它们的词性。

一个马尔科夫过程是状态间的转移仅依赖于前n个状态的过程。这个过程被称之为n阶马尔科夫模型,其中n是影响下一个状态选择的(前)n个状态。最简单的马尔科夫过程是一阶模型,它的状态选择仅与前一个状态有关。这里要注意它与肯定性系统并不相同,由于下一个状态的选择由相应的几率决定,并非肯定性的。

隐马尔可夫模型之因此称为“隐”,是由于从外界来看,状 态序列(例如词性)隐藏不可见,是待求的因变量。从这个角度来说,人们也称 y 状态为隐状态(hidden state),而称观测 x 为显状态( visible state)

“隐”指的是其中某一阶的信息咱们不知道,就像是咱们知道人的祖先是三叶虫,可是由三叶虫经历了怎样的演变过程才演变到人的样子咱们是不知道的,咱们只能经过化石资料了解分布信息,若是这类资料不少,那么就能够利用隐马尔可夫模型来建模,由于缺乏的信息较多,因此这一模型的算法比较复杂。

状态与观测之间的依赖关系肯定以后,隐马尔可夫模型利用三个要素来模拟时序序列的发生过程----即初始状态几率向量、状态转移几率矩阵和发射几率矩阵

1. 隐马尔可夫三大问题

  • 几率计算问题:给定模型,如何有效计算产生观测序列的几率?换言之,如何评估模型与观测序列之间的匹配程度?
  • 预测问题:给定模型和观测序列,如何找到与此观测序列最匹配的状态序列?换言之,如何根据观测序列推断出隐藏的模型状态?
  • 学习问题:给定观测序列,如何调整模型参数使得该序列出现的几率最大?换言之,如何训练模型使其能最好地描述观测数据?

前两个问题是模式识别的问题:1) 根据隐马尔科夫模型获得一个可观察状态序列的几率(评价),被用来测量一个模型的相对适用性;2) 找到一个隐藏状态的序列使得这个序列产生一个可观察状态序列的几率最大(解码),即用来推测模型隐藏的部分在作什么(“到底发生了”什么)。第三个问题就是根据一个能够观察到的状态序列集产生一个隐马尔科夫模型(学习)。

第二个问题是隐马尔可夫模型的核心,不少领域对隐马尔可夫模型的应用大部分会是问题(2),好比在机器翻译作中文对英文的翻译时,单词的翻译老是有不少个意思,而词性每每起到很重要的做用,乍一看词性这一序列怎么跟咱们说到的隐含的状态序列=()很像呢!相似这样的还有不少.......

对应的三大问题解法:

  1. 向前算法(Forward Algorithm)、向后算法(Backward Algorithm)
  2. 维特比算法(Viterbi Algorithm)
  3. 鲍姆-韦尔奇算法(Baum-Welch Algorithm) (约等于EM算法)

网上经典例子

小明如今有三天的假期,他为了打发时间,能够在每一天中选择三件事情来作,这三件事情分别是散步、购物、打扫卫生(对应着可观测序列),但是在生活中咱们所作的决定通常都受到天气的影响,可能晴天的时候想要去购物或者散步,可能下雨天的时候不想出门,留在家里打扫卫生。而天气(晴天、下雨天)就属于隐藏状态,

那么,咱们提出三个问题,分别对应马尔可夫的三大问题:

  1. 已知整个模型,我观测到连续三天作的事情是:散步,购物,收拾。那么,根据模型,计算产生这些行为的几率是多少。
  2. 一样知晓这个模型,一样是这三件事,我想猜,这三天的天气是怎么样的。
  3. 最复杂的,我只知道这三天作了这三件事儿,而其余什么信息都没有。我得创建一个模型,晴雨转换几率,第一每天气状况的几率分布,根据天气状况选择作某事的几率分布。

2. 隐马尔可夫的难点/建模

其实对于HMM来讲,若是提早知道全部隐含状态之间的转换几率和全部隐含状态到全部可见状态之间的输出几率,作模拟是至关容易的。可是应用HMM模型时候呢,每每是缺失了一部分信息的,如何应用算法去估计这些缺失的信息,就成了一个很重要的问题。这些东西就是HMM要解决的问题。

观察到的状态序列与隐藏过程有必定的几率关系。咱们使用隐马尔科夫模型对这样的过程建模,这个模型包含了一个底层隐藏的随时间改变的马尔科夫过程,以及一个与隐藏状态某种程度相关的可观察到的状态集合。

咱们使用一个隐马尔科夫模型(HMM)对这些例子建模。这个模型包含两组状态集合和三组几率集合:

  • 隐藏状态:一个系统的(真实)状态,能够由一个马尔科夫过程进行描述。
  • 观察状态:在这个过程当中‘可视’的状态。
  • pi向量:包含了(隐)模型在时间t=1时一个特殊的隐藏状态的几率(初始几率)。
  • 状态转移矩阵:包含了一个隐藏状态到另外一个隐藏状态的几率
  • 混淆矩阵:包含了给定隐马尔科夫模型的某一个特殊的隐藏状态,观察到的某个观察状态的几率。

所以一个隐马尔科夫模型是在一个标准的马尔科夫过程当中引入一组观察状态,以及其与隐藏状态间的一些几率关系。

0x06 水浒传中的隐马尔可夫应用

水浒传中,梁中书突围大名府就是个 能够被改造以便于说明的 隐马尔可夫(HMM)案例。

却说梁中书正在衙前醉了闲坐,初听报说,尚自不甚慌;次后没半个更次,流星探马,接连报来,吓得魂不附体,慌忙快叫备马。说言未了,只见翠云楼上,烈焰冲天,火光夺月,十分浩大。梁中书见了,急上得马,却待要去看时,只见两条大汉,推两辆车子,放在当路,便去取碗挂的灯来,望车子上点着,随即火起。梁中书要出东门时,两条大汉口称:“李应、史进在此!”手拈朴刀,大踏步杀来。把门官军,吓得走了,手边的伤了十数个。杜迁、宋万却好接着出来,四个合作一处,把住东门。梁中书见不是头势,带领随行伴当,飞奔南门。南门传说道:“一个胖大和尚,抡动铁禅杖;一个虎面行者,掣出双戒刀,发喊杀入城来。”梁中书回马,再到留守司前,只看法珍、解宝手拈钢叉,在那里东撞西撞;急待回州衙,不敢近前。王太守却好过来,刘唐、杨雄两条水火棍齐下,打得脑浆迸流,眼珠突出,死于街前。虞候押番,各逃残生去了。梁中书急急回马奔西门,只听得城隍庙里,火炮齐响,轰天震地。邹渊、邹润手拿竹竿,只顾就房檐下放起火来。南瓦子前,王矮虎、一丈青杀未来。孙新、顾大嫂身边掣出暗器,就那里协助。铜寺前,张青、孙二娘入去,爬上鳌山,放起火来。此时北京城内百姓黎民,一个个鼠撺狼奔,一家家神号鬼哭,四下里十数处火光亘天,四方不辨。
  却说梁中书奔到西门,接着李成军马,急到南门城上,勒住马,在鼓楼上看时,只见城下兵马摆满,旗号上写道:“大将呼延灼。”火焰光中,抖擞精神,施逞骁勇;左有韩滔,右有彭玘,黄信在后,催动人马,雁翅通常横杀未来,随到门下。梁中书出不得城去,和李成躲在北门城下,望见火光明亮,军马不知其数,倒是豹子头林冲,跃马横枪,左有马麟,右有邓飞,花荣在后,催动人马,飞奔未来。再转东门,一连火把丛中,只见没遮拦穆弘,左有杜兴,右有郑天寿,三筹步军好汉当先,手拈朴刀,引领一千余人,杀入城来。梁中书径奔南门,舍命夺路而走。吊桥边火把齐明,只见黑旋风李逵,左有李立,右有曹正。李逵浑身脱剥,咬定牙根,手双斧,从城濠里飞杀过来。李立、曹正,一齐俱到。李成当先,杀开条血路,奔出城来,护着梁中书便走。只见左手下杀声震响,火把丛中,军马无数,倒是大刀关胜,拍动赤兔马,手舞青龙刀,径抢梁中书。李成手举双刀,前来迎敌。那
李成无意恋战,拨马便走。左有宣赞,右有郝思文,两肋里撞来。孙立在后,催动人马,并力杀来。正斗间,背后遇上小李广花荣,拈弓搭箭,射中李成副将,翻身落马。李成见了,飞马奔走,未及半箭之地,只见右手下锣鼓乱鸣,火光夺目,倒是霹雳火秦明跃马舞棍,引着燕顺、欧鹏,背后杨志,又杀未来。李成且战且走,折军大半,护着梁中书,冲路走脱。

突围有四个选择:东南西北四门。每一个门都有不一样的梁山好汉。如今梁中书面对的梁山好汉就构成了一条人名链。

好比去南门,碰见武松,再去东门,碰见史进,再去北门,碰见林冲,再去西门,碰见宋江。 那么能获得以下一串好汉名字:武松,史进,林冲,宋江

这串好汉名字叫作可见状态链。可是在隐马尔可夫模型中,咱们不只仅有这么一串可见状态链,还有一串隐含状态链。在这个例子里,这串隐含状态链就是梁中书选择门的序列: 南门,东门,北门,西门

后续咱们就围绕 梁中书 碰见如下各位好汉来讲明: 武松,史进,林冲,宋江

1. 状态转移矩阵

状态转移矩阵包含了一个隐藏状态到另外一个隐藏状态的几率。通常来讲,HMM中说到的马尔可夫链实际上是指隐含状态链,由于隐含状态(城门)之间存在转换几率(transition probability)。

好比,梁中书在西门突围失败以后,下一个状态是南门,东门,北门,西门的几率都是1/4。这样设定是为了容易说清楚。可是咱们实际上是能够随意设定转换几率的。好比,咱们能够这样定义规则以下:

* 顺时针以下:东门 ----> 南门 ----> 西门 ----> 北门 ---> 东门 ---> ...  

* 已经到达某门,再次选择此门的几率是1/8,好比 东门 ---> 东门 (不大可能再次原地突围)

* 已经到达某门,若是顺时针或者逆时针选择下一个门的几率是3/8, 好比 东门 ----> 南门 或者 东门 ----> 北门
  
* 已经到达某门,选择 正对门 的几率是1/8, 好比 东门 ----> 西门 (不大可能选择穿过大名府去对面城门突围)

状态转移矩阵以下:
\[ A= \left\{ \begin{matrix} \frac18 & \frac38 & \frac18 & \frac38\\ \frac38 & \frac18 & \frac38 & \frac18\\ \frac18 & \frac38 & \frac18 & \frac38\\ \frac38 & \frac18 & \frac38 & \frac18\\ \end{matrix} \right\} \]

2. 混淆矩阵

混淆矩阵:包含了给定隐马尔科夫模型的某一个特殊的隐藏状态,观察到的某个观察状态的几率。即尽管可见状态之间没有转换几率,可是隐含状态和可见状态之间有一个几率叫作输出几率(emission probability)。

水浒传真实总结出的四个门对应的梁山好汉是:

* 水浒传真实总结
   
 * 南门: 武松,鲁智深,呼延灼,韩滔,彭杞,黄信,李逵,李立,曹正,关胜,宣赞,郝思文,孙立,秦明,燕顺、欧鹏,杨志。
 * 东门:李应,史进,穆弘,杜兴,郑天寿
 * 北门:林冲,马麟,邓飞,花荣
 * 西门:梁山好汉大部军马。
   
 * 真实中,北门碰见林冲的几率是1/4, 南门碰见武松的几率是1/17。

但这些是肯定的几率,无法说明咱们的HMM模型。

因此咱们须要从梁中书/吴学究的角度改造。假设吴学究派兵部署时候,给每一个好汉分配到每一个门是有必定几率的,也就是说,梁中书在去了某门以后,遇到某一好汉是有必定几率的。

咱们这里是简化版本,只给定几位好汉:武松,史进,林冲,宋江

* 如下为吴学究派兵时候,每一个好汉分配到每一个门的几率
   
 * 南门:武松 1/2,史进 1/4,林冲 1/8,宋江 1/8
 * 东门:武松 1/4,史进 1/2,林冲 1/8,宋江 1/8
 * 北门:武松 1/8,史进 1/8,林冲 1/2,宋江 1/4
 * 西门:武松 1/8,史进 1/8,林冲 1/4,宋江 1/2
   
 * 就咱们的例子来讲,梁中书在北门 遇到武松的几率是1/8,碰见史进的几率是1/8,碰见林冲的几率是1/2,......

混淆矩阵以下:
\[ B = \left\{ \begin{matrix} \frac12 & \frac14 & \frac18 & \frac18\\ \frac14 & \frac12 & \frac18 & \frac18\\ \frac18 & \frac18 & \frac12 & \frac14\\ \frac18 & \frac18 & \frac14 & \frac12\\ \end{matrix} \right\} \]
在状态转移矩阵及混淆矩阵中的每个几率都是时间无关的——也就是说,当系统演化时这些矩阵并不随时间改变。实际上,这是马尔科夫模型关于真实世界最不现实的一个假设。

3. pi向量(初始几率)

梁山大部军马在西门偷袭李成,梁中书去西门可能性甚小,去东门可能性最大

* 南门: 1/4
* 东门:7/16
* 北门:1/4
* 西门:1/16

pi向量以下:
\[ pi= \left\{ \begin{matrix} \frac14 \\ \frac7{16} \\ \frac14 \\ \frac1{16} \\ \end{matrix} \right\} \]

0x07 水浒传HMM对应的三类问题

1. 序列几率过程 --- 估计(Evaluation)

几率计算问题:给定模型,如何有效计算产生观测序列的几率。即根据隐马尔科夫模型获得一个可观察状态序列的几率(评价)。

结合咱们水浒传的例子,就是已经知道门有几种(隐含状态数量),每种门是什么(转换几率),根据"选门以后看到哪位好汉"的结果(可见状态链),我想知道看到这个结果的几率。

好比连续三次,看到的人分别是:武松,史进,林冲。那么根据模型,计算产生这些行为的几率是多少。

1.1 直接计算法(穷举搜索)

列举全部可能的状态序列,而后计算每种状态序列状况下的观测序列几率,最后求和。时间复杂度很是高,对于每个t,都有N种隐藏状态,那整个序列T的全部可能就是N的T次方,而后求和又是T的全部复杂度。

1.2 前向算法(基本动态规划思想)

咱们使用前向算法(forward algorithm)来计算给定隐马尔科夫模型(HMM)后的一个观察序列的几率,并所以选择最合适的隐马尔科夫模型(HMM)。

这个算法采用了DP思想,减小计算量,即每一次直接引用前一个时刻的计算结果以免重复计算,跟Viterbi同样的技巧相应地,其时间复杂度与T成线性关系。

给定一个隐马尔科夫模型(HMM),咱们将考虑递归地计算一个观察序列的几率。咱们首先定义局部几率(partial probability),它是到达网格中的某个中间状态时的几率。对于最后的观察状态,其局部几率包括了经过全部可能的路径到达这些状态的几率。因而可知,对于这些最终局部几率求和等价于对于网格中全部可能的路径几率求和,也就求出了给定隐马尔科夫模型(HMM)后的观察序列几率。

注:穷举搜索的时间复杂度是2TN^T,前向算法的时间复杂度是N^2T,其中T指的是观察序列长度,N指的是隐藏状态数目。

2. 序列标注过程 --- 解码(Decoding)

预测问题:给定模型和观测序列,如何找到与此观测序列最匹配的状态序列?换言之,如何根据观测序列推断出隐藏的模型状态?对于一个特殊的隐马尔科夫模型(HMM)及一个相应的观察序列,咱们经常但愿能找到生成此序列最可能的隐藏状态序列

结合咱们水浒传的例子就是,知道门有几种(隐含状态数量),每种门是什么(转换几率),根据"选门以后看到哪位好汉"的结果(可见状态链),我想知道每次选中的是哪一个门(隐含状态链)。

好比连续三次,看到的人分别是:武松,史进,林冲。那么这三次每次选的是哪一个门?

我如今要在给定的观测序列下找出一条隐状态序列,条件是这个隐状态序列的几率是最大的那个

2.1 Viterbi 算法

可使用Viterbi 算法(Viterbi algorithm)肯定(搜索)已知观察序列及HMM下最可能的隐藏状态序列。

维特比算法致力于寻找一条最佳路径,以便能最好地解释观测到的序列。咱们能够经过列出全部可能的隐藏状态序列而且计算对于每一个组合相应的观察序列的几率来找到最可能的隐藏状态序列。最可能的隐藏状态序列是使下面这个几率最大的组合:

      Pr(观察序列|隐藏状态的组合)

这个思想的基础是这样的,若是从p1到pN存在一条最好的路是k,若是这条路k通过了p‘,则p’到pN必定是最优的,若是不是最优的,就存在另一条路k‘,他的p’到pN更好,那这条路就不是k了,矛盾。因此咱们只要找到最大几率的最后一个结点,而后一步一步向前就能求出来最优路径。

具体在应用中,维特比算法对于网格中的每个单元(cell)都计算一个局部几率,同时包括一个反向指针用来指示最可能的到达该单元的路径。咱们首先定义局部几率,它是到达网格中的某个特殊的中间状态时的几率。这些局部几率与前向算法中所计算的局部几率是不一样的,由于它们表示的是时刻t时到达某个状态最可能的路径的几率,而不是全部路径几率的总和。当完成整个计算过程后,首先在终止时刻找到最可能的状态,而后经过反向指针(这个指针指向最优的引起当前状态的前一时刻的某个状态)回溯到t=1时刻,这样回溯路径上的状态序列就是最可能的隐藏状态序列了。

3. 学习问题(Learning)

学习问题:给定观测序列,如何调整模型参数使得该序列出现的几率最大?换言之,如何训练模型使其能最好地描述观测数据?即根据一个能够观察到的状态序列集产生一个隐马尔科夫模型(学习)。

结合咱们水浒传的例子就是,知道门有几种(隐含状态数量),不知道每种门是什么(转换几率),观测到不少次"选门以后看到哪位好汉"的结果(可见状态链),我想反推出每种门是什么(转换几率)。

好比连续三次,梁中书看到的人分别是:武松,史进,林冲。而其余什么信息都没有。要创建一个模型,找出各类门之间转换几率,固然也有这些门外他遇到好汉的几率分布。

不少时候咱们只有可见结果,不知道HMM模型里的参数,咱们须要从可见结果估计出这些参数,这是建模的一个必要步骤。

这个问题,也是与HMM相关的问题中最难的,根据一个观察序列(来自于已知的集合),以及与其有关的一个隐藏状态集,估计一个最合适的隐马尔科夫模型(HMM),也就是肯定对已知序列描述的最合适的(pi,A,B)三元组。

3.1 监督学习算法——频数/总数就是几率

首先监督学习算法,就是数据足够,而后人工标注好,其实你只须要统计出来各类频数就能够了。
好比分词的时候:
统计B到E的频数,B到M的频数什么的都能求出来,转移矩阵A有了。每一个字分别为BEMS的频数,观测矩阵B有了
样本中第一个字为B和S分别的几率。初始几率PI有了。而后就解决问题了,其实分词就是这样的,在人工标注好的数据集上统计就行了。

3.2 非监督学习算法——鲍姆-韦尔奇算法

没有标注的状况下,你只有一堆句子(假设句子长短一致,都是T个字),这时候矩阵A和B不可以直接被(估计)测量,学习这些参数,就要用EM算法对于HMM参数学习问题的适配版——Baum-Welch算法。

参数学习算法又叫前向后向算法。要是计算整个序列的几率,前向就解决了。要是计算整个序列某个子序列出现的几率,那就必需要二者一块儿来算了。

0x08 参考代码

UMDHMM(Hidden Markov Model Toolkit):

Hidden Markov Model (HMM) Software: Implementation of Forward-Backward, Viterbi, and Baum-Welch algorithms.
这款属于轻量级的HMM版本。UMDHMM主页:http://www.kanungo.com/software/software.html

前向算法程序(forward.c)

/* 函数参数说明:
  *phmm:已知的HMM模型;T:观察符号序列长度;
  *O:观察序列;**alpha:局部几率;*pprob:最终的观察几率
 */
void Forward(HMM *phmm, int T, int *O, double **alpha, double *pprob) {
  int i, j;   /* 状态索引 */
  int t;    /* 时间索引 */
  double sum; /*求局部几率时的中间值 */

  /* 1. 初始化:计算t=1时刻全部状态的局部几率alpha: */
  for (i = 1; i <= phmm->N; i++)
    alpha[1][i] = phmm->pi[i]* phmm->B[i][O[1]];
  
  /* 2. 概括:递归计算每一个时间点,t=2,... ,T时的局部几率 */
  for (t = 1; t < T; t++) {     
      for (j = 1; j <= phmm->N; j++) {
      sum = 0.0;
      for (i = 1; i <= phmm->N; i++)
        sum += alpha[t][i]* (phmm->A[i][j]);
      alpha[t+1][j] = sum*(phmm->B[j][O[t+1]]);
    }
  }

  /* 3. 终止:观察序列的几率等于T时刻全部局部几率之和*/
  *pprob = 0.0;
  for (i = 1; i <= phmm->N; i++)
    *pprob += alpha[T][i];
}

维特比算法程序(viterbi.c)

void Viterbi(HMM *phmm, int T, int *O, double **delta, int **psi,int *q, double *pprob)
{
  int i, j; /* state indices */
  int t; /* time index */
  int maxvalind;
  double maxval, val;

  /* 1. Initialization */
  for (i = 1; i <= phmm->N; i++){
    delta[1][i] = phmm->pi[i] * (phmm->B[i][O[1]]);
    psi[1][i] = 0;
  }

  /* 2. Recursion */
  for (t = 2; t <= T; t++)   {     
       for (j = 1; j <= phmm->N; j++){
      maxval = 0.0;
      maxvalind = 1;
      for (i = 1; i <= phmm->N; i++) {
        val = delta[t-1][i]*(phmm->A[i][j]);
        if (val > maxval){
          maxval = val;
          maxvalind = i;
        }
      }
      delta[t][j] = maxval*(phmm->B[j][O[t]]);
      psi[t][j] = maxvalind;
    }
  }

  /* 3. Termination */
  *pprob = 0.0;
  q[T] = 1;
  for (i = 1; i <= phmm->N; i++){
    if (delta[T][i] > *pprob){
      *pprob = delta[T][i];
      q[T] = i;
    }
  }

  /* 4. Path (state sequence) backtracking */
  for (t = T - 1; t >= 1; t--)
    q[t] = psi[t+1][q[t+1]];
}

0x09 参考

[2] 如何用简单易懂的例子解释隐马尔可夫模型?[Online]

[3] ”相亲记“之从EM算法到Baum-Welch算法[Online]

Itenyh版-用HMM作中文分词一:序

HMM学习最佳范例一:介绍

条件随机场的简单理解

HMM隐马尔可夫模型详解

3.二元语法与中文分词.md

”相亲记“之从EM算法到Baum-Welch算法

(https://github.com/NLP-LOVE/Introduction-NLP/blob/master/chapter/3.%E4%BA%8C%E5%85%83%E8%AF%AD%E6%B3%95%E4%B8%8E%E4%B8%AD%E6%96%87%E5%88%86%E8%AF%8D.md)

https://github.com/NLP-LOVE/Introduction-NLP/blob/master/chapter/3.%E4%BA%8C%E5%85%83%E8%AF%AD%E6%B3%95%E4%B8%8E%E4%B8%AD%E6%96%87%E5%88%86%E8%AF%8D.md

如何轻松愉快地理解条件随机场(CRF)?

一文读懂机器学习几率图模型

十5、一篇文章读懂拿了图灵奖和诺贝尔奖的几率图模型

机器学习 —— 几率图模型(贝叶斯网络)

贝叶斯网络,看完这篇我终于理解了(附代码)!

几率图模型理解

几率图模型体系:HMM、MEMM、CRF

HMM算法学习——本身动手实现一个简单的HMM分词(java)

HMM学习最佳范例六:维特比算法1

wiki上一个比较好的HMM例子

https://hunch.net/

https://eps.leeds.ac.uk/computing

相关文章
相关标签/搜索