机器学习-概率图模型:隐马尔可夫模型(HMM)【解决序列问题】【前提假设:隐层状态序列符合马尔可夫性、观测序列的各观测值相互独立】【被RNN等神经网络模型取代】【生成模型:对联合概率建模】

机器学习-概率图模型:隐马尔可夫模型(HMM)【解决序列问题】【前提假设:隐层状态序列符合马尔可夫性、观测序列的各观测值相互独立】【被RNN等神经网络模型取代】【生成模型:对联合概率建模】_第1张图片

一、概述

隐马尔科夫模型(Hidden Markov Model,以下简称HMM)是比较经典的机器学习模型了,HMM是解决序列(时间序列、状态序列)问题的模型。在语言识别,自然语言处理,模式识别等领域得到广泛的应用。

当然,随着目前深度学习的崛起,尤其是RNN,LSTM等神经网络序列模型的火热,HMM的地位有所下降。

但是作为一个经典的模型,学习HMM的模型和对应算法,对我们解决问题建模的能力提高以及算法思路的拓展还是很好的。

1、什么样的问题需要HMM模型

首先我们来看看什么样的问题解决可以用HMM模型。使用HMM模型时我们的问题一般有这两个特征:

  1. 我们的问题是基于序列的,比如时间序列,或者状态序列。
  2. 我们的问题中有两类数据,一类序列数据是可以观测到的,即观测序列;而另一类数据是不能观察到的,即隐藏状态序列,简称状态序列。

有了这两个特征,那么这个问题一般可以用HMM模型来尝试解决。

这样的问题在实际生活中是很多的。比如:

  • 我现在在打字写博客,我在键盘上敲出来的一系列字符就是观测序列,而我实际想写的一段话就是隐藏序列,输入法的任务就是从敲入的一系列字符尽可能的猜测我要写的一段话,并把最可能的词语放在最前面让我选择,这就可以看做一个HMM模型了。
  • 再举一个,我在和你说话,我发出的一串连续的声音就是观测序列,而我实际要表达的一段话就是状态序列,你大脑的任务,就是从这一串连续的声音中判断出我最可能要表达的话的内容。

从这些例子中,我们可以发现,HMM模型可以无处不在。但是上面的描述还不精确,下面我们用精确的数学符号来表述我们的HMM模型。

2、HMM模型的两个前提假设

马尔科夫假设:当前隐层状态仅与上一个状态有关;

观测独立性假设: 任意时刻的观察状态仅仅依赖于当前时刻的隐藏状态

3、HMM三个典型问题

  1. 评估观察序列概率:已知模型 λ = ( Π , A , B ) \textbf{λ}=(\textbf{Π},\textbf{A},\textbf{B}) λ=(Π,A,B) 的所有参数和观测序列 O = { o 1 , o 2 , . . . o T } \textbf{O}=\{o_1,o_2,...o_T\} O={o1,o2,...oT},计算在模型 λ \textbf{λ} λ 下观测序列 O \textbf{O} O 出现的概率 P ( O ∣ λ ) P(O|λ) P(Oλ):可使用前向-后向算法求解。
  2. 解码问题 / 预测问题:已知模型 λ = ( Π , A , B ) \textbf{λ}=(\textbf{Π},\textbf{A},\textbf{B}) λ=(Π,A,B) 所有参数和观测序列 O = { o 1 , o 2 , . . . o T } \textbf{O}=\{o_1,o_2,...o_T\} O={o1,o2,...oT},计算最可能的隐状态序列 I I I,即:求给定观测序列的条件概率 P ( I ∣ O , λ ) P(I|O,λ) P(IO,λ) 最大时的隐藏状态序列 I I I。可使用经典的动态规划算法——维特比算法来求解最可能的状态序列。
  3. 学习问题:已知观测序列 O = { o 1 , o 2 , . . . o T } \textbf{O}=\{o_1,o_2,...o_T\} O={o1,o2,...oT},求解使得该观测序列概率 P ( O ∣ λ ) P(O|λ) P(Oλ) 最大的模型 λ = ( Π , A , B ) \textbf{λ}=(\textbf{Π},\textbf{A},\textbf{B}) λ=(Π,A,B) 的所有参数,包括隐状态序列、隐状态之间的转移概率分布以及从隐状态到观测状态的概率分布,可使用Baum-Welch算法进行参数的学习,*Baum-Welch算法*是最大期望算法(EM算法)的一个特例。

二、背景知识

1、联合概率

P ( x 1 x 2 x 3 x 4 ) = P ( x 1 ) ⋅ P ( x 2 ∣ x 1 ) ⋅ P ( x 3 ∣ x 1 x 2 ) ⋅ P ( x 4 ∣ x 1 x 2 x 3 ) ⇔ P ( x 1 x 2 ) ⋅ P ( x 3 ∣ x 1 x 2 ) ⋅ P ( x 4 ∣ x 1 x 2 x 3 ) ⇔ P ( x 1 x 2 x 3 ) ⋅ P ( x 4 ∣ x 1 x 2 x 3 ) ⇔ P ( x 1 x 2 x 3 x 4 ) \begin{aligned} P(x_1x_2x_3x_4)&=P(x_1)·P(x_2|x_1)·P(x_3|x_1x_2)·P(x_4|x_1x_2x_3)\\ &\Leftrightarrow P(x_1x_2)·P(x_3|x_1x_2)·P(x_4|x_1x_2x_3)\\ &\Leftrightarrow P(x_1x_2x_3)·P(x_4|x_1x_2x_3)\\ &\Leftrightarrow P(x_1x_2x_3x_4) \end{aligned} P(x1x2x3x4)=P(x1)P(x2x1)P(x3x1x2)P(x4x1x2x3)P(x1x2)P(x3x1x2)P(x4x1x2x3)P(x1x2x3)P(x4x1x2x3)P(x1x2x3x4)
N-grams:第N个词的出现只与前面N-1个词相关,而与其它任何词都不相关,整句的概率就是各个词出现概率的乘积。

这些概率可以通过直接从语料中统计N个词同时出现的次数得到。

常用的是二元的Bi-Gram和三元的Tri-Gram。

1.1 Unigrams(一元语法:马尔科夫假设)

P ( x 1 x 2 x 3 x 4 ) = P ( x 1 ) ⋅ P ( x 2 ∣ x 1 ) ⋅ P ( x 3 ∣ x 1 x 2 ) ⋅ P ( x 4 ∣ x 1 x 2 x 3 ) = P ( x 1 ) ⋅ P ( x 2 ) ⋅ P ( x 3 ) ⋅ P ( x 4 ) \begin{aligned} P(x_1x_2x_3x_4)&=P(x_1)·P(x_2|x_1)·P(x_3|x_1x_2)·P(x_4|x_1x_2x_3)\\ &=P(x_1)·P(x_2)·P(x_3)·P(x_4) \end{aligned} P(x1x2x3x4)=P(x1)P(x2x1)P(x3x1x2)P(x4x1x2x3)=P(x1)P(x2)P(x3)P(x4)

1.2 Bigrams(二元语法)

P ( x 1 x 2 x 3 x 4 ) = P ( x 1 ) ⋅ P ( x 2 ∣ x 1 ) ⋅ P ( x 3 ∣ x 1 x 2 ) ⋅ P ( x 4 ∣ x 1 x 2 x 3 ) = P ( x 1 ) ⋅ P ( x 2 ∣ x 1 ) ⋅ P ( x 3 ∣ x 2 ) ⋅ P ( x 4 ∣ x 3 ) \begin{aligned} P(x_1x_2x_3x_4)&=P(x_1)·P(x_2|x_1)·P(x_3|x_1x_2)·P(x_4|x_1x_2x_3)\\ &=P(x_1)·P(x_2|x_1)·P(x_3|x_2)·P(x_4|x_3) \end{aligned} P(x1x2x3x4)=P(x1)P(x2x1)P(x3x1x2)P(x4x1x2x3)=P(x1)P(x2x1)P(x3x2)P(x4x3)

1.3 Trigrams(三元语法)

P ( x 1 x 2 x 3 x 4 ) = P ( x 1 ) ⋅ P ( x 2 ∣ x 1 ) ⋅ P ( x 3 ∣ x 1 x 2 ) ⋅ P ( x 4 ∣ x 1 x 2 x 3 ) = P ( x 1 ) ⋅ P ( x 2 ∣ x 1 ) ⋅ P ( x 3 ∣ x 1 x 2 ) ⋅ P ( x 4 ∣ x 2 x 3 ) \begin{aligned} P(x_1x_2x_3x_4)&=P(x_1)·P(x_2|x_1)·P(x_3|x_1x_2)·P(x_4|x_1x_2x_3)\\ &=P(x_1)·P(x_2|x_1)·P(x_3|x_1x_2)·P(x_4|x_2x_3) \end{aligned} P(x1x2x3x4)=P(x1)P(x2x1)P(x3x1x2)P(x4x1x2x3)=P(x1)P(x2x1)P(x3x1x2)P(x4x2x3)

2、自动机

自动机:(又称为 有限自动机,有限状态自动机,FSA)是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。

例如:

我们常用的正则表达式就是一种用来描述字符串出现字符的自动机。

假如我们有正则表达式:baa+!,表示的是ba后面有1个或这多个a,最后是一个感叹号。

我们可以把上述的自动机用图来展示,如下:
机器学习-概率图模型:隐马尔可夫模型(HMM)【解决序列问题】【前提假设:隐层状态序列符合马尔可夫性、观测序列的各观测值相互独立】【被RNN等神经网络模型取代】【生成模型:对联合概率建模】_第2张图片
自动机从初始状态q0开始,反复进行下面的过程:找到第一个字母b,如果找到b那么进入到下一个状态,再去寻找下一个状态需要的字母,指导进行接收状态q4。

我们可以使用状态转移表来自动机:

机器学习-概率图模型:隐马尔可夫模型(HMM)【解决序列问题】【前提假设:隐层状态序列符合马尔可夫性、观测序列的各观测值相互独立】【被RNN等神经网络模型取代】【生成模型:对联合概率建模】_第3张图片
上述的状态机我们也称为确定的自动状态机DFSA(例如红绿灯),如果位于q3的循环在q2上,那么在q2状态下,看到a,他是不清楚要向那个地方进行转移的。所以把这种状态机成为非确定的自动状态机 NFSA,(比如天气)。

3、马尔科夫链

3.1 马尔可夫性

马尔可夫性:当一个随机过程在给定当前状态及所有过去状态情况下,其未来状态的条件概率分布仅依赖于当前状态;换句话说,在给定现在状态时,它与过去状态(即该过程的历史路径)是条件独立的,那么此随机过程即具有马尔可夫性质。具有马尔可夫性质的随机过程通常称之为马尔可夫过程

机器学习-概率图模型:隐马尔可夫模型(HMM)【解决序列问题】【前提假设:隐层状态序列符合马尔可夫性、观测序列的各观测值相互独立】【被RNN等神经网络模型取代】【生成模型:对联合概率建模】_第4张图片

3.2 马尔科夫链

马尔可链是自动状态机的扩展版,是一种带权的自动状态机。权重在马尔可夫链中就是连接弧的概率。离开一个节点的所有的概率和为1。

用马尔可夫链描述天气的变化,如果使用图模型来描述的话,可以有下面的示例:

机器学习-概率图模型:隐马尔可夫模型(HMM)【解决序列问题】【前提假设:隐层状态序列符合马尔可夫性、观测序列的各观测值相互独立】【被RNN等神经网络模型取代】【生成模型:对联合概率建模】_第5张图片
如果今天下雨,那么明天的天气会怎么样呢?

明天下雪的概率:0.02

明天下雨的概率:0.8

明天晴天的概率:0.18

上述的过程包含了概率上的一个重要假设:在一个一阶马尔可夫链中,一个特定状态的概率只和他的前一个状态是有关的:

马尔可夫假设
P ( q i ∣ q i − 1 ⋯ q 1 ) = P ( q i ∣ q i − 1 ) P(q_i|q_{i-1}\cdots q_1) = P(q_i|q_{i-1}) P(qiqi1q1)=P(qiqi1)
如果是把马尔可夫应用于NLP的文本序列,那么他表示的就是二元N-gram模型

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

机器学习-概率图模型:隐马尔可夫模型(HMM)【解决序列问题】【前提假设:隐层状态序列符合马尔可夫性、观测序列的各观测值相互独立】【被RNN等神经网络模型取代】【生成模型:对联合概率建模】_第6张图片
机器学习-概率图模型:隐马尔可夫模型(HMM)【解决序列问题】【前提假设:隐层状态序列符合马尔可夫性、观测序列的各观测值相互独立】【被RNN等神经网络模型取代】【生成模型:对联合概率建模】_第7张图片

该过程要求具备“无记忆”的性质:

  • 下一状态的概率分布只能由当前状态决定,在时间序列中它前面的事件均与之无关。这种特定类型的“无记忆性”称作马尔可夫性质。
  • 马尔科夫链作为实际过程的统计模型具有许多应用。
  • 在马尔可夫链的每一步,系统根据概率分布,可以从一个状态变到另一个状态,也可以保持当前状态。
  • 状态的改变叫做转移,与不同的状态改变相关的概率叫做转移概率。
  • 马尔可夫链的数学表示为:
    P ( x t + 1 ∣ x 0 , x 1 , . . . , x t − 1 , x t ) = P ( x t + 1 ∣ x t ) P(x_{t+1}|x_0,x_1,...,x_{t-1},x_t)=P(x_{t+1}|x_t) P(xt+1x0,x1,...,xt1,xt)=P(xt+1xt)
  • 既然某一时刻状态转移的概率只依赖前一个状态,那么只要求出系统中任意两个状态之间的转移概率,这个马尔科夫链的模型就定了

3.3 马尔科夫链的遍历性

机器学习-概率图模型:隐马尔可夫模型(HMM)【解决序列问题】【前提假设:隐层状态序列符合马尔可夫性、观测序列的各观测值相互独立】【被RNN等神经网络模型取代】【生成模型:对联合概率建模】_第8张图片

3.4 马尔科夫链经典举例

下图中的马尔科夫链是用来表示股市模型,共有三种状态:牛市(Bull market), 熊市(Bear market)和横盘(Stagnant market)。每一个状态都以一定的概率转化到下一个状态。比如,牛市以0.025的概率转化到横盘的状态。

机器学习-概率图模型:隐马尔可夫模型(HMM)【解决序列问题】【前提假设:隐层状态序列符合马尔可夫性、观测序列的各观测值相互独立】【被RNN等神经网络模型取代】【生成模型:对联合概率建模】_第9张图片

  • 这个状态概率转化图可以以矩阵的形式表示;
  • 如果我们定义矩阵阵 P P P 某一位置 P ( i , j ) P(i, j) P(i,j) 的值为 P ( j ∣ i ) P(j|i) P(ji),即从状态 i i i 变为状态 j j j 的概率;
  • 另外定义牛市、熊市、横盘的状态分别为 0、1、2;
  • 这样我们得到了马尔科夫链模型的状态转移矩阵为:

机器学习-概率图模型:隐马尔可夫模型(HMM)【解决序列问题】【前提假设:隐层状态序列符合马尔可夫性、观测序列的各观测值相互独立】【被RNN等神经网络模型取代】【生成模型:对联合概率建模】_第10张图片
当这个状态转移矩阵 P P P 确定以后,整个股市模型就已经确定!

三、隐马尔科夫模型概念

当我们要计算我们能够观察到的事件序列的概率的时候,马尔可夫链是很有用的。但是在很多情况下,我们感兴趣的概率是没有办法直接计算的。例如在词性标注的问题中,我们能够看到句子中的词,能够计算这个句子组合的概率。但是我们的目标是或者这个句子对应的词性的序列。这些词性序列是隐藏的,不能够直接被观察到,我们需要去推断隐藏的状态,这个时候我们就需要使用隐马尔科夫模型(HMM)

隐马尔可夫模型(Hidden Markov Model;缩写:HMM)或称作隐性马尔可夫模型,是统计模型,它用来描述一个含有隐含未知参数的马尔可夫过程。其难点是从可观察的参数求出该过程的隐含参数。然后利用求出的这些参数来作进一步的分析,例如模式识别。

  • 隐马尔科夫模型可用标注问题,在语音识别、NLP、生物信息、模式识别等领域被实践证明是有效的算法。

  • 隐马尔科夫模型是关于时间序列的概率模型,描述由一个隐藏的马尔科夫链生成不可观测的“状态随机序列”,再由各个“状态”生成“观测随机序列”的过程。

  • 隐马尔科夫模型随机生成的状态随机序列,称为状态序列;每一个状态生成一个观测,由此产生的观测随机序列,称为观测序列

  • 在正常的马尔可夫模型中,状态对于观察者来说是直接可见的。这样状态的转换概率便是全部的参数。而在隐马尔可夫模型中,状态并不是直接可见的,但受状态影响的某些变量则是可见的。每一个状态在可能输出的符号上都有一概率分布。因此输出符号的序列能够透露出状态序列的一些信息

  • 隐马尔可夫模型(HMM)是一种贝叶斯网络。

下边的图示强调了HMM的状态变迁。有时,明确的表示出模型的演化也是有用的,我们用 x ( t 1 ) x(t_1) x(t1) x ( t 2 ) x(t_2) x(t2) 来表达不同时刻 t 1 t_1 t1 t 2 t_2 t2 的状态。

机器学习-概率图模型:隐马尔可夫模型(HMM)【解决序列问题】【前提假设:隐层状态序列符合马尔可夫性、观测序列的各观测值相互独立】【被RNN等神经网络模型取代】【生成模型:对联合概率建模】_第11张图片

  • 图中箭头方向则表示不同信息间的关系性,因此可以得知 x ( t ) x(t) x(t) x ( t − 1 ) x(t-1) x(t1) 有关,而 x ( t − 1 ) x(t-1) x(t1) 又和 x ( t − 2 ) x(t-2) x(t2) 有关。
  • 而每个 y ( t ) y(t) y(t) 只和 x ( t ) x(t) x(t) 有关,其中 x ( t ) x(t) x(t) 我们称为隐藏变量(hidden variable),是观察者无法得知的变量
  • 隐性马尔可夫模型常被用来解决有未知条件的数学问题。
  • 假设隐藏状态的值对应到的空间有 N N N 个元素,也就是说在时间 t t t 时,隐藏状态会有 N N N 种可能。
  • 同样的,在时间 t + 1 t+1 t+1 也会有 N N N 种可能的值,所以从 t t t t + 1 t+1 t+1 间的关系会有 N 2 N^2 N2 种可能。
  • 除了 x ( t ) x(t) x(t) 间的关系外,每组 x ( t ) , y ( t ) x(t),y(t) x(t),y(t) 间也有对应的关系。
  • 若观察到的 y ( t ) y(t) y(t) M M M 种可能的值,则从 x ( t ) x(t) x(t) y ( t ) y(t) y(t) 的输出模型复杂度为 O ( N M ) O(NM) O(NM)。如果 y ( t ) y(t) y(t) 是一个 M M M 维的向量,则从 x ( t ) x(t) x(t) y ( t ) y(t) y(t) 的输出模型复杂度为 O ( N M ) O(NM) O(NM)

隐马尔可夫模型可以使用以下内容来进行描述:

  • Q = q 1 , q 2 , ⋯ q N Q = q_1,q_2,\cdots q_N Q=q1,q2,qN 隐层状态N的集合
  • A = a 11 , a 12 , ⋯   , a n n A = a_{11},a_{12},\cdots,a_{nn} A=a11,a12,ann 转移概率矩阵A。每一个转移概率 a i j a_{ij} aij表示从状态i转移到状态j的概率,同时从某一个状态出发的转移概率和为1
  • O = O 1 , O 2 ⋯ O n O = O_1,O_2 \cdots O_n O=O1,O2On 观察到的序列T
  • B = b i ( O i ) B = b_i(O_i) B=bi(Oi) 观察似然度,也叫做发射概率,表示从状态i得到观察 O i O_i Oi的概率
  • q 0 , q F q_0,q_F q0,qF 表示初始状态和终结状态

隐马尔可夫模型中,除了马尔可夫假设之外,还有另外一个假设,即输出独立性假设,即:

一个输出观察 O i O_i Oi的概率只和产生该观察的状态 q i q_i qi有关

P ( O i ∣ q 1 , q 2 ⋯ q T , O 1 , O 2 ⋯ O T ) = P ( O i ∣ q i ) P(O_i|q_1,q_2\cdots q_T ,O_1,O_2 \cdots O_T) = P(O_i|q_i) P(Oiq1,q2qTO1,O2OT)=P(Oiqi)

在类似词性标注的问题中,我们需要做的事情,在含有n个单词的观察序列的所有可能的隐藏序列中找到一个概率最大的隐藏序列,写成公式如下(其中帽子符号 ^ \hat{} ^表示对正确序列的估计):

t ^ n = a r g m a x t n P ( t n ∣ w n ) \hat{t}_n = \mathop{argmax}_{t_n}P(t_n|w_n) t^n=argmaxtnP(tnwn)

根据前面的两个概率假设,上述公式也可以写为:

t ^ n = a r g m a x t n P ( t n ∣ w n ) = a r g m a x t n P ( t n , w n ) P ( w n ) = a r g m a x t n P ( t n , w n ) = a r g m a x t n ∏ i = 1 n P ( w i ∣ t i ) P ( t i ∣ t i − 1 ) = a r g m a x t n P ( w i ∣ t i ) P ( t i ∣ t i − 1 ) \begin{aligned} \hat{t}_n &= \mathop{argmax}_{t_n}P(t_n|w_n) \\ &= \mathop{argmax}_{t_n}\frac{P(t_n,w_n)}{P(w_n)} \\ &= \mathop{argmax}_{t_n}P(t_n,w_n) \\ &= \mathop{argmax}_{t_n}\prod_{i=1}^{n} P(w_i|t_i)P(t_i|t_{i-1}) \\ &= \mathop{argmax}_{t_n}P(w_i|t_i)P(t_i|t_{i-1}) \end{aligned} t^n=argmaxtnP(tnwn)=argmaxtnP(wn)P(tn,wn)=argmaxtnP(tn,wn)=argmaxtni=1nP(witi)P(titi1)=argmaxtnP(witi)P(titi1)

上述的公式中包含两个概率:

  1. 标记的 转移概率 P ( t i ∣ t i − 1 ) P(t_i|t_{i-1}) P(titi1)

  2. 单词的似然度(likelihood):又称为发射概率,即在状态 t i t_i ti的情况下发现观测值为 w i w_i wi的概率。

    似然度:likelihood的中文翻译,表示可能性、概率的意思

转移概率的计算方法:通过极大似然估计(MLE),通过现有的语料,直接计算即可:

即:状态从 t i − 1 到 t i t_{i-1}到t_i ti1ti的总数 除以 t i − 1 t_{i-1} ti1的总数

P ( t i ∣ t i − 1 ) = C ( t i − 1 , t i ) C ( t i − 1 ) P(t_i|t_{i-1}) = \frac{C(t_{i-1},t_i)}{C(t_{i-1})} P(titi1)=C(ti1)C(ti1,ti)

极大似然估计:是一种概率在统计学中的应用,是一种参数估计方法,说的是说的是已知某个随机样本满足某种概率分布,但是其中具体的参数不清楚,参数估计就是通过若干次试验,使用实验得出的概率作为样本的概率。

似然度概率的计算方法同理:

P ( w i ∣ t i ) = C ( t i , w i ) C ( t i ) P(w_i|t_i) = \frac{C(t_i,w_i)}{C(t_i)} P(witi)=C(ti)C(ti,wi)

即数据集中所有的 w i 为 t i w_i为t_i witi的样本数量 除以 该状态 t i t_i ti的总数。

四、HMM模型的组成

任何一个HMM都可以通过下列五元组来描述:

  • :param states:隐状态 I I I
  • :param start_p:隐状态初始概率分布 Π Π Π
  • :param trans_p:隐状态转移概率分布 A A A
  • :param emit_p: 发射概率分布 B B B (隐状态表现为显状态的概率)
  • :param obs:观测序列 O O O

机器学习-概率图模型:隐马尔可夫模型(HMM)【解决序列问题】【前提假设:隐层状态序列符合马尔可夫性、观测序列的各观测值相互独立】【被RNN等神经网络模型取代】【生成模型:对联合概率建模】_第12张图片

HMM(隐马尔可夫)模型由:隐状态初始概率分布 Π Π Π、隐状态转移概率分布 A A A、发射概率分布 B B B 唯一确定

λ = ( Π , A , B ) \color{red}{\textbf{λ}=(\textbf{Π},\textbf{A},\textbf{B})} λ=(Π,A,B)

  • Π \textbf{Π} Π:初始隐状态概率分布。表示初始的隐状态概率分布, Π 1 × n = ( π 1 , π 2 , . . . , π n ) Π_{1×n}=(π_1,π_2,...,π_n) Π1×n=(π1,π2,...,πn) n n n表示所有状态的个数;
  • A \textbf{A} A:隐状态转移概率分布。隐状态转移矩阵: A n × n \textbf{A}_{n×n} An×n n n n表示所有状态的个数;
  • B \textbf{B} B:观测概率(发射概率)分布,即隐状态表现为显状态的概率;【观测(发射概率)矩阵: B n × m \textbf{B}_{n×m} Bn×m n n n表示所有状态的个数, m m m表示所有观测值的个数】
  • λ 1 × m = Π 1 × n ⋅ A n × n ⋅ B n × m \textbf{λ}_{1×m}=\textbf{Π}_{1×n}·\textbf{A}_{n×n}·\textbf{B}_{n×m} λ1×m=Π1×nAn×nBn×m

机器学习-概率图模型:隐马尔可夫模型(HMM)【解决序列问题】【前提假设:隐层状态序列符合马尔可夫性、观测序列的各观测值相互独立】【被RNN等神经网络模型取代】【生成模型:对联合概率建模】_第13张图片

五、HMM三个典型问题

  1. 评估观察序列概率:已知模型 λ = ( Π , A , B ) \textbf{λ}=(\textbf{Π},\textbf{A},\textbf{B}) λ=(Π,A,B) 的所有参数和观测序列 O = { o 1 , o 2 , . . . o T } \textbf{O}=\{o_1,o_2,...o_T\} O={o1,o2,...oT},计算在模型 λ \textbf{λ} λ 下观测序列 O \textbf{O} O 出现的概率 P ( O ∣ λ ) P(O|λ) P(Oλ):可使用前向-后向算法求解。
  2. 解码问题 / 预测问题:已知模型 λ = ( Π , A , B ) \textbf{λ}=(\textbf{Π},\textbf{A},\textbf{B}) λ=(Π,A,B) 所有参数和观测序列 O = { o 1 , o 2 , . . . o T } \textbf{O}=\{o_1,o_2,...o_T\} O={o1,o2,...oT},计算最可能的隐状态序列 I I I,即:求给定观测序列的条件概率 P ( I ∣ O , λ ) P(I|O,λ) P(IO,λ) 最大时的隐藏状态序列 I I I。可使用经典的动态规划算法——维特比算法来求解最可能的状态序列。
  3. 学习问题:已知观测序列 O = { o 1 , o 2 , . . . o T } \textbf{O}=\{o_1,o_2,...o_T\} O={o1,o2,...oT},求解使得该观测序列概率 P ( O ∣ λ ) P(O|λ) P(Oλ) 最大的模型 λ = ( Π , A , B ) \textbf{λ}=(\textbf{Π},\textbf{A},\textbf{B}) λ=(Π,A,B) 的所有参数,包括隐状态序列、隐状态之间的转移概率分布以及从隐状态到观测状态的概率分布,可使用Baum-Welch算法进行参数的学习,*Baum-Welch算法*是最大期望算法(EM算法)的一个特例。

其中问题三:学习问题前面已经讲解,通过语料进行统计,通过极大似然估计就可以计算。

评估观察序列概率 解码问题 / 预测问题 学习问题
已知模型 λ = ( Π , A , B ) \textbf{λ}=(\textbf{Π},\textbf{A},\textbf{B}) λ=(Π,A,B) 的所有参数和观测序列 O = { o 1 , o 2 , . . . o T } \textbf{O}=\{o_1,o_2,...o_T\} O={o1,o2,...oT}

计算在模型 λ \textbf{λ} λ 下观测序列 O \textbf{O} O 出现的概率: P ( O ∥ λ ) P(O\|λ) P(Oλ)
已知模型 λ = ( Π , A , B ) \textbf{λ}=(\textbf{Π},\textbf{A},\textbf{B}) λ=(Π,A,B) 所有参数和观测序列 O = { o 1 , o 2 , . . . o T } \textbf{O}=\{o_1,o_2,...o_T\} O={o1,o2,...oT}

计算最可能的隐状态序列 I I I(求条件概率 P ( I ∥ O , λ ) P(I\|O,λ) P(IO,λ) 最大时的隐藏状态序列 I I I
已知观测序列 O = { o 1 , o 2 , . . . o T } \textbf{O}=\{o_1,o_2,...o_T\} O={o1,o2,...oT},求解使得该观测序列概率 P ( O ∥ λ ) P(O\|λ) P(Oλ) 最大的模型 λ = ( Π , A , B ) \textbf{λ}=(\textbf{Π},\textbf{A},\textbf{B}) λ=(Π,A,B) 的所有参数
前向-后向算法 维特比算法 Baum-Welch算法

1、概率计算问题 / 似然度问题【评估观察序列概率: 前向-后向算法(动态规划)】

评估观察序列概率:即给定模型 λ = ( Π , A , B ) \textbf{λ}=(\textbf{Π},\textbf{A},\textbf{B}) λ=(Π,A,B)观测序列 O = { o 1 , o 2 , . . . o T } \textbf{O}=\{o_1,o_2,...o_T\} O={o1,o2,...oT},计算在模型 λ λ λ 下观测序列 O \textbf{O} O 出现的概率 P ( O ∣ λ ) P(\textbf{O}|\textbf{λ}) P(Oλ)。这个问题的求解需要用到 “前向-后向算法”。这个问题是HMM模型三个问题中最简单的。

  • 给定模型 λ = ( Π , A , B ) \textbf{λ}=(\textbf{Π},\textbf{A},\textbf{B}) λ=(Π,A,B)机器学习-概率图模型:隐马尔可夫模型(HMM)【解决序列问题】【前提假设:隐层状态序列符合马尔可夫性、观测序列的各观测值相互独立】【被RNN等神经网络模型取代】【生成模型:对联合概率建模】_第14张图片
  • 求连续6天的天气是 { S u n n y , S u n n y , W i n d y , R a i n y , R a i n y , S n o w y } \{Sunny,Sunny,Windy,Rainy,Rainy,Snowy\} {Sunny,Sunny,Windy,Rainy,Rainy,Snowy} 的概率。即求观测序列 O = { o 1 , o 2 , . . . o T } = { S u n n y , S u n n y , W i n d y , R a i n y , R a i n y , S n o w y } O=\{o_1,o_2,...o_T\}=\{Sunny,Sunny,Windy,Rainy,Rainy,Snowy\} O={o1,o2,...oT}={Sunny,Sunny,Windy,Rainy,Rainy,Snowy} 的概率 P ( O ∣ λ ) P(\textbf{O}|\textbf{λ}) P(Oλ)

1.1 直接计算法

由条件概率的乘法定理: P ( OI ) = P ( O ∣ I ) ⋅ P ( I ) P(\textbf{OI})=P(\textbf{O}|\textbf{I})·P(\textbf{I}) P(OI)=P(OI)P(I),可得:

  • 隐状态序列 I = { i 1 , i 2 , . . . i n } I=\{i_1,i_2,...i_n\} I={i1,i2,...in} 的概率 P ( I ∣ λ ) = π i 1 ⋅ A i 1 i 2 ⋅ A i 2 i 3 ⋅ A i 3 i 4 A i 4 i 5 ⋅ … ⋅ A i n − 1 i n P(\textbf{I}|\textbf{λ})=π_{i_1}·A_{i_1i_2}·A_{i_2i_3}·A_{i_3i_4}A_{i_4i_5}·…·A_{i_{n-1}i_n} P(Iλ)=πi1Ai1i2Ai2i3Ai3i4Ai4i5Ain1in
  • 对于固定的隐状态序列 I I I,观测序列 O \textbf{O} O 的概率 P ( O ∣ I , λ ) = B i 1 o 1 ⋅ B i 2 o 2 ⋅ B i 3 o 3 … ⋅ B i n o n P(\textbf{O}|\textbf{I},\textbf{λ})=B_{i_1o_1}·B_{i_2o_2}·B_{i_3o_3}…·B_{i_no_n} P(OI,λ)=Bi1o1Bi2o2Bi3o3Binon
    P ( O ∣ λ ) = ∑ I P ( OI ∣ λ ) = ∑ I [ P ( O ∣ I , λ ) ⋅ P ( I ∣ λ ) ] = ∑ I π i 1 B i 1 o 1 A i 1 i 2 B i 2 o 2 A i 2 i 3 B i 3 o 3 … A i n − 1 i n B i n o n \begin{aligned} P(\textbf{O}|\textbf{λ})&=\sum_IP(\textbf{O}\textbf{I}|\textbf{λ})=\sum_I[P(\textbf{O}|\textbf{I},\textbf{λ})·P(\textbf{I}|\textbf{λ})]\\ &=\sum_Iπ_{i_1}B_{i_1o_1}A_{i_1i_2}B_{i_2o_2}A_{i_2i_3}B_{i_3o_3}…A_{i_{n-1}i_n}B_{i_no_n} \end{aligned} P(Oλ)=IP(OIλ)=I[P(OI,λ)P(Iλ)]=Iπi1Bi1o1Ai1i2Bi2o2Ai2i3Bi3o3Ain1inBinon
  • 直接计算法的时间复杂度是 O ( T N T ) O(TN^T) O(TNT) 。指数级别,太大。

1.2 前向算法

我们可以使用向前算法来代替上述呈指数级增长的概率计算方法。向前算法是一种动态规划的方法。其核心思想就是,在计算观察序列的概率的时候,通过一个中间值来存储其中间值,同时对于中间状态的概率,使用 之前状态 乘 转移概率的求和计算得到

动态规划:把多阶段决策过程的最优化问题转化为一系列单阶段的问题

其计算过程如下:
机器学习-概率图模型:隐马尔可夫模型(HMM)【解决序列问题】【前提假设:隐层状态序列符合马尔可夫性、观测序列的各观测值相互独立】【被RNN等神经网络模型取代】【生成模型:对联合概率建模】_第15张图片

其计算过程的伪代码如下:

  1. 初始化

α 1 ( j ) = α 0 j b j ( o 1 ) \alpha_1(j) = \alpha_{0j}b_{j}(o_1) α1(j)=α0jbj(o1)

  1. 递归

α t ( j ) = ∑ i = 1 N α t − 1 ( i ) a i j b j ( o t ) \alpha_t(j) = \sum_{i=1}^N \alpha_{t-1}(i) a_{ij} b_{j}(o_{t}) αt(j)=i=1Nαt1(i)aijbj(ot)

  1. 结束

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

其 中 α t 表 示 中 间 概 率 , α i j 表 示 转 移 概 率 , b j ( o t ) 表 示 发 射 概 率 其中\alpha_t表示中间概率,\alpha_{ij}表示转移概率,b_j(o_t)表示发射概率 αtαijbj(ot)

前向算法的时间复杂度是 O ( N 2 T ) O(N^2T) O(N2T)
定义:给定 λ \textbf{λ} λ,定义到时刻 t t t 时,观测到部分序列为 o 1 , o 2 , . . . o t o_1,o_2,...o_t o1,o2,...ot,且隐状态为 q k q_k qk 的概率称为“前向概率”。记做: α t ( k ) = P ( o 1 , o 2 , . . . , o t , I t = q k ∣ λ ) α_t(k)=P(o_1,o_2,...,o_t,I_t=q_k|\textbf{λ}) αt(k)=P(o1,o2,...,ot,It=qkλ)

  1. 通过递推的方式,计算 t + 1 t+1 t+1 时刻的前向概率 α t + 1 ( k ) α_{t+1}(k) αt+1(k)

    • α 1 ( k ) = P ( o 1 , I 1 = q k ) = P ( o 1 ∣ I 1 = q k ) ⋅ P ( I 1 = q k ) = B q k o 1 π k \begin{aligned}α_1(k)=P(o_1,I_1=q_k)=P(o_1|I_1=q_k)·P(I_1=q_k)=B_{q_ko_1}π_k\end{aligned} α1(k)=P(o1,I1=qk)=P(o1I1=qk)P(I1=qk)=Bqko1πk
      其中:
      • B q k o 1 B_{q_ko_1} Bqko1 表示在 t = 1 t=1 t=1 时刻,由隐状态 q k q_k qk 发射到(触发)观测值 o 1 o_1 o1 的概率;
      • π k π_k πk 表示隐状态处于 q k q_k qk的概率
    • α 2 ( k ) = [ ∑ j n α 1 ( j ) A j k ] ⋅ B q k o 2 \begin{aligned}α_2(k)=[\sum^n_jα_1(j)A_{jk}]· B_{q_ko_2} \end{aligned} α2(k)=[jnα1(j)Ajk]Bqko2
      其中:
      • ∑ j n α 1 ( j ) A j k \sum^n_jα_1(j)A_{jk} jnα1(j)Ajk表示从 t = 1 t=1 t=1 时刻的随便一个隐状态 q j q_j qj 转移到 t = 2 t=2 t=2 时刻的隐状态 q k q_k qk 的概率;
      • B q k o 2 B_{q_ko_2} Bqko2 表示在 t = 2 t=2 t=2 时刻,由隐状态 q k q_k qk 发射到(触发)观测值 o 2 o_2 o2 的概率;
    • α t + 1 ( k ) = [ ∑ j n α t ( j ) A j k ] ⋅ B q k o t + 1 \begin{aligned}\color{red}{α_{t+1}(k)=[\sum^n_jα_t(j)A_{jk}]· B_{q_ko_{t+1}}}\end{aligned} αt+1(k)=[jnαt(j)Ajk]Bqkot+1
      其中:
      • ∑ j n α t ( j ) A j k \sum^n_jα_t(j)A_{jk} jnαt(j)Ajk表示从 t t t 时刻的随便一个隐状态 q j q_j qj 转移到 t + 1 t+1 t+1 时刻的隐状态 q k q_k qk 的概率;
      • B q k o t + 1 B_{q_ko_{t+1}} Bqkot+1 表示在 t + 1 t+1 t+1 时刻,由隐状态 q k q_k qk 发射到(触发)观测值 o t + 1 o_{t+1} ot+1 的概率;
  2. 最终计算得到的概率为:
    P ( O ∣ λ ) = ∑ k = 1 N α T ( k ) P(\textbf{O}|\textbf{λ})=\sum^N_{k=1}α_T(k) P(Oλ)=k=1NαT(k)
    其中: N N N 为隐状态总数; T T T 表示时刻 T T T

1.3 后向算法

类似前向算法,后向算法也可用于求解这个问题,只是方向是从后到前的。
定义:给定 λ \textbf{λ} λ,定义到时刻 t t t 时,隐状态为 q k q_k qk的条件下, 从时刻 t + 1 t+1 t+1 T T T 的部分观测序列为 o t + 1 , o t + 2 , … . o T o_{t+1}, o_{t+2},….o_T ot+1,ot+2,.oT 的概率称为“后向概率”,记为: β t ( k ) = P ( o t + 1 , o t + 2 , … . o T ∣ I t = q k , λ ) β_t(k) = P(o_{t+1}, o_{t+2},….o_T|I_t = q_k,λ) βt(k)=P(ot+1,ot+2,.oTIt=qk,λ)

  1. 通过递推的方式,计算 t t t 时刻的后向概率 α t ( k ) α_t(k) αt(k)

    • 初始状态定义为: β T ( j ) = 1 β_T(j) = 1 βT(j)=1, 其中: j = 1 , 2 , … n j=1,2,…n j=1,2,n 中的任意一个。这里概率为1的原因是本来还需要看看时刻 T T T 后面有什么东西,但因为最后一个时刻 T T T 后面已经没有时刻,即不需要再观测某个东西,所以随便给个什么状态都可以。
    • β T − 1 ( k ) = ∑ j n [ A k j B q j o T β T ( j ) ] = β T ( j ) = 1 ∑ j n ( A k j B q j o T ) \begin{aligned}β_{T-1}(k) = \sum^n_j[A_{kj}B_{q_jo_T}β_T(j)] \xlongequal{β_T(j) = 1} \sum^n_j(A_{kj}B_{q_jo_T})\end{aligned} βT1(k)=jn[AkjBqjoTβT(j)]βT(j)=1 jn(AkjBqjoT)
      其中:
      - ∑ j n A k j \sum^n_jA_{kj} jnAkj 表示从 T − 1 T-1 T1 时刻的隐状态 k k k T T T 时刻随便一个隐状态 q j q_j qj 的概率;
      - B q j o T B_{q_jo_T} BqjoT 表示在 T T T 时刻,由隐状态 q j q_j qj 发射到(触发)观测值 o T o_T oT 的概率;
      - β T ( j ) β_T(j) βT(j) 表示状态 q k q_k qk 之后的观测序列的后向概率
    • β t ( k ) = ∑ j n [ A k j B q j o ( t + 1 ) β t + 1 ( j ) ] \begin{aligned}\color{red}{β_t(k) = \sum^n_j[A_{kj}B_{q_jo_{(t+1)}}β_{t+1}(j)]}\end{aligned} βt(k)=jn[AkjBqjo(t+1)βt+1(j)]
      其中:
      - ∑ j n A k j \sum^n_jA_{kj} jnAkj 表示从 t t t 时刻的隐状态 k k k t + 1 t+1 t+1 时刻随便一个隐状态 q j q_j qj 的概率;
      - B q j o ( t + 1 ) B_{q_jo_{(t+1)}} Bqjo(t+1) 表示在 t + 1 t+1 t+1 时刻,由隐状态 q j q_j qj 发射到(触发)观测值 o ( t + 1 ) o_{(t+1)} o(t+1) 的概率;
      - β t + 1 ( j ) β_{t+1}(j) βt+1(j) 表示状态 q k q_k qk 之后的观测序列的后向概率
    • β 0 ( k ) = ∑ j n [ A k j B q j o 1 β 1 ( j ) ] \begin{aligned}β_0(k) = \sum^n_j[A_{kj}B_{q_jo_1}β_1(j)] \end{aligned} β0(k)=jn[AkjBqjo1β1(j)]
      其中:
      - ∑ j n β 1 ( j ) A k j \sum^n_jβ_1(j)A_{kj} jnβ1(j)Akj 表示从 t = 0 t=0 t=0 时刻的隐状态 k k k t = 1 t=1 t=1 时刻随便一个隐状态 q j q_j qj 的概率;
      - B q j o 1 B_{q_jo_1} Bqjo1 表示在 t = 1 t=1 t=1 时刻,由隐状态 q j q_j qj 发射到(触发)观测值 o 1 o_1 o1 的概率;
      - β 1 ( j ) β_1(j) β1(j) 表示状态 q k q_k qk 之后的观测序列的后向概率
  2. 最终计算得到的概率为:
    P ( O ∣ λ ) = ∑ k = 1 n π k B q k o 1 β 1 ( k ) P(O|λ) = \sum_{k=1}^n π_kB_{q_ko_1}β_1(k) P(Oλ)=k=1nπkBqko1β1(k)
    其中: N N N 为隐状态总数; 1 1 1 表示时刻 t = 1 t=1 t=1

1.4 前向后向概率的关系

机器学习-概率图模型:隐马尔可夫模型(HMM)【解决序列问题】【前提假设:隐层状态序列符合马尔可夫性、观测序列的各观测值相互独立】【被RNN等神经网络模型取代】【生成模型:对联合概率建模】_第16张图片

机器学习-概率图模型:隐马尔可夫模型(HMM)【解决序列问题】【前提假设:隐层状态序列符合马尔可夫性、观测序列的各观测值相互独立】【被RNN等神经网络模型取代】【生成模型:对联合概率建模】_第17张图片

1.5 前向-后向算法联合概率

P ( O ∣ λ ) = ∑ i = 1 N ∑ j = 1 N α t ( i ) A i j B q j o t + 1 β t + 1 ( j ) 其 中 : t = 1 , 2 , . . . , T − 1 P(O|λ)=\sum^N_{i=1}\sum^N_{j=1}α_t(i)A_{ij}B_{q_jo_{t+1}}β_{t+1}(j) \qquad 其中:t=1,2,...,T-1 P(Oλ)=i=1Nj=1Nαt(i)AijBqjot+1βt+1(j)t=1,2,...,T1

2、解码问题 / 预测问题【维特比(Viterbi)算法-动态规划】

预测问题:也称为解码问题。给定模型 λ = ( Π , A , B ) λ=(Π,A,B) λ=(Π,A,B) 和观测序列 O = { o 1 , o 2 , . . . o T } O=\{o_1,o_2,...o_T\} O={o1,o2,...oT},求给定观测序列的条件概率 P ( I ∣ O , λ ) P(I|O,λ) P(IO,λ) 最大时的隐藏状态序列 I I I。这个问题的求解需要用到基于动态规划的维特比算法。这个问题是HMM模型三个问题中复杂度居中的算法。

  • 假设根据大量观测数据 O = ( O 1 , O 2 , . . . O i , . . . , O n ) \textbf{O}=(O^1,O^2,...O^i,...,O^n) O=(O1,O2,...Oi,...,On)已经求出最优化模型 λ m a x = ( Π , A , B ) λ_{max}=(Π,A,B) λmax=(Π,A,B)

  • 求给定的观测序列 O j = { o 1 j , o 2 j , . . . o T j } O^j=\{o^j_1,o^j_2,...o^j_T\} Oj={o1j,o2j,...oTj} 的隐藏状态序列。即求: P ( I j ∣ O j , λ m a x ) P(I^j|O^j,λ_{max}) P(IjOj,λmax)

  • 解码问题理论上也可以通过穷举法来解决,就是穷举所有可能的隐含序列并计算在这个隐含序列下观测序列的概率,并选择概率最大的那个隐含序列,但是穷举所有可能的隐含序列的时间复杂度也是指数级别的,跟第一个问题一样,在实际中往往也是不常用的。

  • 实际中,解码问题通过动态规划来降低时间复杂度,并且已经有了成熟的解决方法,就是著名的维特比算法

根据观察序列确定隐藏序列的过程称之为Decoding(解码)Decoder(解码器)的任务就是发现最优隐藏序列

机器学习-概率图模型:隐马尔可夫模型(HMM)【解决序列问题】【前提假设:隐层状态序列符合马尔可夫性、观测序列的各观测值相互独立】【被RNN等神经网络模型取代】【生成模型:对联合概率建模】_第18张图片

其实现过程如下:

  1. 遍历所有的状态,根据初始状态的概率计算*观察序列对应的发射概率,得到第一次概率结果
  2. 遍历从第二次到最后的时间步
  3. 遍历所有的状态
  4. 计算:前一次的概率结果*转移概率*发射概率,选择概率最大的隐藏状态作为当前的隐藏状态

3、模型参数学习问题:Baum-Welch算法(状态未知)-EM(Baum-Welch)

模型参数学习问题:即给定观测序列 O = { o 1 , o 2 , . . . o T } O=\{o_1,o_2,...o_T\} O={o1,o2,...oT},估计模型 λ = ( Π , A , B ) λ=(Π,A,B) λ=(Π,A,B) 的参数,使得在该模型下观测序列 O O O概率 P ( O ∣ λ ) P(O|λ) P(Oλ) 最大。这个问题的求解需要用到基于EM算法的鲍姆-韦尔奇算法, 我们在这个系列的第三篇会详细讲解。这个问题是HMM模型三个问题中最复杂的。

  • 给定大量观测数据 O = ( O 1 , O 2 , . . . O i , . . . , O n ) \textbf{O}=(O^1,O^2,...O^i,...,O^n) O=(O1,O2,...Oi,...,On),其中 O i = { o 1 i , o 2 i , . . . o T i } O^i=\{o^i_1,o^i_2,...o^i_T\} Oi={o1i,o2i,...oTi}

  • 求使得观测数据 O \textbf{O} O最有可能发生的模型 λ m a x = ( Π , A , B ) λ_{max}=(Π,A,B) λmax=(Π,A,B) 的参数。即求: max ⁡ λ P ( O ∣ λ ) \begin{aligned}\max\limits_{λ}P(O|λ)\end{aligned} λmaxP(Oλ)

  • 学习问题要根据观测序列来推导模型参数,这一类的问题对应到概率论中的极大似估计问题。但是这里是有隐含变量的极大似然估计,因此直接无法通过直接求导进行求解,而要通过EM算法来求解这一类问题。

  • EM 算法是一类算法,用于解决有隐含变量的概率模型参数的极大似然估计,具体到隐马尔可夫模型中的具体算法是 Baum-Welch 算法

  • 注:

    • 这里采用 EM 算法的前提是问题仅给出了观测序列
    • 假如同时给出了观测序列隐含序列,可直接通过最大似然估计求解

这里只给出 Baum-Welch 算法的流程,而省去其推导过程:

  1. 初始化模型参数:选取 a i j ( 0 ) , b j ( 0 ) , π i ( 0 ) a_{ij}^{(0)}, b_j^{(0)}, \pi_i^{(0)} aij(0),bj(0),πi(0), 得到模型 π ( 0 ) = ( A ( 0 ) , B ( 0 ) , π ( 0 ) ) \pi^{(0)} = (A^{(0)}, B^{(0)}, \pi^{(0)}) π(0)=(A(0),B(0),π(0));
  2. E 步,求解两个中间变量 γ t ( i ) , ξ t ( i , j ) \gamma_t(i), \xi_t(i,j) γt(i),ξt(i,j),两者的含义如下:
    γ t ( i ) \gamma_t(i) γt(i):给定模型 λ \lambda λ和观测序列 O O O,在时刻 t t t的隐含状态为 q i q_i qi的概率, 即 γ t ( i ) = P ( x t = q i ∣ O , λ ) \gamma_t(i) = P(x_t = q_i | O, \lambda) γt(i)=P(xt=qiO,λ);
    ξ t ( i , j ) \xi_t(i,j) ξt(i,j):给定模型 λ \lambda λ和观测序列 O O O,在时刻 t t t的隐含状态为 q i q_i qi, 时刻 t + 1 t+1 t+1的隐含状态为 q i q_i qi的概率, 即 ξ t ( i , j ) = P ( x t = q i , x t + 1 = q j ∣ O , λ ) \xi_t(i,j) = P(x_t = q_i, x_{t+1} = q_j | O, \lambda) ξt(i,j)=P(xt=qi,xt+1=qjO,λ).

结合前面的前向概率和后向概率的定义,计算这两个中间变量的公式如下( m m m表示隐含状态的总个数):
γ t ( i ) = α t ( i ) β t ( i ) ∑ j = 1 m α t ( j ) β t ( j ) \gamma_t(i) = \frac{\alpha_t(i) \beta_t(i)}{\sum_{j=1}^m \alpha_t(j) \beta_t(j)} γt(i)=j=1mαt(j)βt(j)αt(i)βt(i)
ξ t ( i , j ) = α t ( i ) a i j b j ( o t + 1 ) β t + 1 ( j ) ∑ p = 1 m ∑ q = 1 m α t ( p ) a p q b q ( o t + 1 ) β t + 1 ( q ) \xi_t(i,j) = \frac{\alpha_t(i) a_{ij} b_j(o_{t+1})\beta_{t+1}(j)}{\sum_{p=1}^m \sum_{q=1}^m \alpha_t(p) a_{pq} b_q(o_{t+1})\beta_{t+1}(q)} ξt(i,j)=p=1mq=1mαt(p)apqbq(ot+1)βt+1(q)αt(i)aijbj(ot+1)βt+1(j)

  1. M步,同时E步求解出的两个中间变量来求解模型的参数,求解公式如下:
    a i j = ∑ t = 1 T ξ t ( i , j ) ∑ t = 1 T γ t ( i ) a_{ij} = \frac{\sum_{t=1}^T \xi_t(i,j)}{\sum_{t=1}^T \gamma_t(i)} aij=t=1Tγt(i)t=1Tξt(i,j)
    b j ( k ) = ∑ t = 1 T γ t ( j ) I ( o t = v k ) ∑ t = 1 T γ t ( j ) b_j(k) = \frac{\sum_{t=1}^T \gamma_t(j)I(o_t = v_k)}{\sum_{t=1}^T \gamma_t(j)} bj(k)=t=1Tγt(j)t=1Tγt(j)I(ot=vk)
    π i = γ 1 ( i ) \pi_i = \gamma_1(i) πi=γ1(i)

上式中的 I ( o t = v k ) I(o_t = v_k) I(ot=vk)表示时刻 t t t的观察状态为 v k v_k vk时, I ( o t = v k ) I(o_t = v_k) I(ot=vk)才为1,否则为0.

迭代进行E步骤和M步,将最终收敛的结果作为模型的参数.

六、HMM模型使用过程

  • 首先, HMM模型表示为: lambda = HMM(A, B, pi), 其中A, B, pi都是模型的参数, 分别称作: 转移概率矩阵, 发射概率矩阵和初始概率矩阵.
  • 接着, 我们开始训练HMM模型, 语料就是事先准备好的一定数量的观测序列及其对应的隐含序列, 通过极大似然估计求得一组参数, 使由观测序列到对应隐含序列的概率最大.
  • 在训练过程中, 为了简化计算, 马尔可夫提出一种假设: 隐含序列中每个单元的可能性只与上一个单元有关. 这个假设就是著名的隐含假设.
  • 训练后, 我们就得到了具备预测能力的新模型: lambda = HMM(A, B, pi), 其中的模型参数已经改变.
  • 之后给定输入序列(x1, x2, …, xn), 经过模型计算lambda(x1, x2, …, xn)得到对应隐含序列的条件概率分布.
  • 最后, 使用维特比算法从隐含序列的条件概率分布中找出概率最大的一条序列路径就是我们需要的隐含序列: (y1, y2, …, yn).

七、案例

下面我们使用语料,使用HMM设计一个模型进行分词

语料github地址:https://github.com/liwenzhu/corpusZh

语料内容如下

机器学习-概率图模型:隐马尔可夫模型(HMM)【解决序列问题】【前提假设:隐层状态序列符合马尔可夫性、观测序列的各观测值相互独立】【被RNN等神经网络模型取代】【生成模型:对联合概率建模】_第19张图片

其中词性标注的代码含义如下:

		n   普通名词
		nt  时间名词
		nd  方位名词
		nl  处所名词
		nh  人名
		nhf 姓
		nhs 名
		ns  地名
		nn  族名
		ni  机构名
		nz  其他专名
		v   动词
		vd  趋向动词
		vl  联系动词
		vu  能愿动词
		a   形容词
		f   区别词
		m   数词  
		q   量词
		d   副词
		r   代词
		p   介词
		c   连词
		u   助词
		e   叹词
		o   拟声词
		i   习用语
		j   缩略语
		h   前接成分
		k   后接成分
		g   语素字
		x   非语素字
		w   标点符号
		ws  非汉字字符串
		wu  其他未知的符号

该语料可以用来训练分词模型,也可以用来训练词性标注等模型。

如何对句子进行分词

思考:

如果使用上述的语料进行分词,我们应该如何准备我们的数据

通常在分词过程中,每个字会对应一个符号,然后我们根据预测的符号对句子进行划分。

例如:我们有下列四种符号表示所有单字的状态

B  表示 begin 词语的开始
M  表示 middle 词语的中间
E  表示 end  词语的结束
S  表示 single 单个字成词

那么,会有下列情况

我/S爱/S北/B京/E天/B安/M门/E

此时,我们把所有的E和S分开,就能够实现对句子的分词了

统计概率

根据前面的知识,我们知道,为了计算解码过程中,每个时间步上的概率最大值,需要统计四个概率,分别是

  1. 初始状态概率
  2. 状态转移概率
  3. 发射概率
  4. 结束状态概率

根据极大似然估计的思想,我们通过统计语料,可以得到上述概率

我们的思路如下:

  1. 定义保存概率的容器
  2. 对每个句子进行处理
  3. 对每个句子中的字进行统计
  4. 保存概率后续使用

我们可以定义一个对象, 来进行概率的统计

class ProbilityMartix:
    def __init__(self):
        self.state_list = ["B","M","E","S"] #初始的四种状态
        self.state_num = len(self.state_list)

        #初始概率向量 {B:200,S:400}
        self.PiVector = {i:0 for i in self.state_list}
        #总的句子数,或者是总得初始向量
        self.PiVector_size = 0

        #转移概率矩阵,从一个状态到另一个状态的数量 {B:{E:100,S:200...}}
        self.TransProbMatrix = {i:{j:0 for j in self.state_list} for i in self.state_list }
        #每个状态的总数,上面的/下面的 = 从一个状态到另一个状态的概率 {S:200,E:300}
        self.TransProbMatrix_size = {i:0 for i in self.state_list}

        #发射概率矩阵,从状态到词的数量,【后续求当前这个词到位某个状态的数量/ 状态的数量= 某个词为某个状态的概率】
        self.EmitProbMartix = {i:{} for i in self.state_list}
        #每个状态数量 {"S":100}
        self.EmitProbMartix_word_size = {}
        
        self.EndProbMartix = {i:0 for i in self.state_list}
        self.EndProbMartix_size = 0
        

之后,对每个句子进行处理和统计

   def sentence2states(self,sentence):
        '''
        :param sentence:['明日', '将', '与', '河北', '队', '作', '赛', '津', '队', '在', '实力', '上', '稍胜一筹', '可望', '取胜']
        :return: ["BE","S","S"....]
        '''
        state_output = []
        for word in sentence:
            word = word.strip()
            if len(word)<1:
                continue
            current_state = ""
            if len(word) ==1:
                current_state += "S"
            elif len(word)>1:
                M_num = len(word)-2
                current_state += "B"
                current_state += "M"*M_num
                current_state += "E"
            state_output.append(current_state)
        return state_output

    def start_count_by_sentence(self,sentence):
        states = self.sentence2states(sentence)

        #把词和状态链接到一起,方便后面统计
        joined_sentence = "".join(sentence) #明日将与河北'
        joined_states = "".join(states) #"BESSBE"
        
         #统计初始数量
        self.PiVector[joined_states[0]] +=1
        #统计初始总数
        self.PiVector_size+=1
        
        for i in range(len(joined_states)-1):
            #统计转移状态的数量
            self.TransProbMatrix[joined_states[i]][joined_states[i+1]] +=1
            #统计状态的数量
            self.TransProbMatrix_size[joined_states[i]] +=1

        for i in range(len(joined_states)):
            #统计发射词的数量
            if joined_sentence[i] in self.EmitProbMartix[joined_states[i]]:
                self.EmitProbMartix[joined_states[i]][joined_sentence[i]] +=1
            else:
                self.EmitProbMartix[joined_states[i]][joined_sentence[i]]=1

            #统计不同词的总数,应该是统计所有的状态
            if joined_states[i] in self.EmitProbMartix_word_size:
                self.EmitProbMartix_word_size[joined_states[i]] += 1
            else:
                self.EmitProbMartix_word_size[joined_states[i]] = 1
        #统计结束的概率
        last_state = joined_states[-1]
        self.EndProbMartix[last_state] += 1
        self.EndProbMartix_size += 1

之后进行计算和保存

def get_probility(self):
        '''
        开始计算概率
        :return:
        '''
        self.PiVector_prob = deepcopy(self.PiVector)
        self.TransProbMatrix_prob = deepcopy(self.TransProbMatrix)
        self.EmitProbMartix_prob = deepcopy(self.EmitProbMartix)

        for key in self.PiVector_prob:
            self.PiVector_prob[key] = np.log((self.PiVector_prob[key]/self.PiVector_size))
        for start in self.TransProbMatrix_prob:
            for end in self.TransProbMatrix_prob[start]:
                #避免算出来为0
                self.TransProbMatrix_prob[start][end] = 1 if self.TransProbMatrix_prob[start][end]==0 else self.TransProbMatrix_prob[start][end]

                self.TransProbMatrix_prob[start][end] = np.log((self.TransProbMatrix_prob[start][end]/self.TransProbMatrix_size[start]))

        #后续再使用的时候,没有出现的词让其概率低
        for key in self.EmitProbMartix_prob:
            for word in self.EmitProbMartix_prob[key]:
                self.EmitProbMartix_prob[key][word] = np.log((self.EmitProbMartix_prob[key][word]/self.EmitProbMartix_word_size[key]))
        
         #统计结束概率
        for key in self.EndProbMartix_prob:
            self.EndProbMartix_prob[key] = np.log(self.EndProbMartix_prob[key]/self.EndProbMartix_size)

    def save_probility(self):
        temp = {
            "EmitProbMartix_prob" : self.EmitProbMartix_prob,
            "PiVector_prob":self.PiVector_prob,
            "TransProbMatrix_prob":self.TransProbMatrix_prob,
            "EndProbMatrix_prob": self.EndProbMartix_prob
        }
        with open("./probility.pkl","wb") as f:
            pickle.dump(temp,f)

    def run(self):
        file_path = r"corpusZH-master/all.txt"
        for sentence in prepar_sentences(file_path):
            self.start_count_by_sentence(sentence)

        self.get_probility()
        self.save_probility()

使用viterbi算法进行解码

使用viterbi算法实现分词的部分代码实现如下:

    def start_calcute(self,sentence):
        '''
        通过viterbi算法计算结果
        :param sentence: "小明硕士毕业于中国科学院计算所"
        :return: "S...E"
        '''
        zero = -3.14e+100
        zero_log = np.log(-3.14e+100)
        init_state = self.prob_dict["PiVector_prob"]
        trans_prob = self.prob_dict["TransProbMatrix_prob"]
        emit_prob = self.prob_dict["EmitProbMartix_prob"]
        end_prob = self.prob_dict["EndProbMatrix_prob"]

        V = [{}] #其中的字典保存 每个时间步上的每个状态对应的概率
        path = {}

        #初始概率
        for y in self.state_list:
            V[0][y] = init_state[y] + emit_prob[y].get(sentence[0],zero_log)
            path[y] = [y]
		
        #从第二次到最后一个时间步
        for t in range(1,len(sentence)):
            V.append({})
            newpath = {}
            for y in self.state_list: #遍历所有的当前状态
                    temp_state_prob_list = []
                    for y0 in self.state_list: #遍历所有的前一次状态
                        cur_prob = V[t-1][y0]+trans_prob[y0][y]+emit_prob[y].get(sentence[t],zero_log)
                        temp_state_prob_list.append([cur_prob,y0])
					#取最大值,作为当前时间步的概率
                    prob,state =  sorted(temp_state_prob_list,key=lambda x:x[0],reverse=True)[0]
                    #保存当前时间步,当前状态的概率
                    V[t][y] = prob
                    #保存当前的状态到newpath中
                    newpath[y] = path[state] + [y]
			#让path为新建的newpath
            path = newpath

        #输出的最后一个结果只会是S(表示单个字)或者E(表示结束符)
        (prob, state) = max([(V[len(sentence)][y]+end_prob[y], y) for y in ["S","E"]])
        return (prob, path[state])



参考资料:
概率图模型体系:HMM、MEMM、CRF
谈谈序列标注三大模型HMM、MEMM、CRF
CRF 和 HMM 的区别与联系
隐马尔科夫模型HMM(一)HMM模型
隐马尔科夫模型HMM(二)前向后向算法评估观察序列概率
隐马尔科夫模型HMM(三)鲍姆-韦尔奇算法求解HMM参数
隐马尔科夫模型HMM(四)维特比算法解码隐藏状态序列
如何用简单易懂的例子解释条件随机场(CRF)模型?它和HMM有什么区别?
时间序列(七): 高冷贵族: 隐马尔可夫模型
隐马尔可夫模型(HMM)详解
一文搞懂HMM(隐马尔可夫模型)
60分钟看懂HMM的基本原理
隐马尔可夫模型(HMM)详解
HMM隐马尔可夫模型详解
HMM之模型详解
02 隐马尔可夫模型 - HMM的三个问题 - 概率计算问题
常见算法面试之样本不均衡的解决办法、交叉熵以及HMM、MEMM vs CRF

你可能感兴趣的:(#,ML/经典模型,人工智能,机器学习,自然语言处理,隐马尔可夫模型,HMM)