0. 简述
本文主要参考"A Tutorial On Hidden Markov Models",这个文章可以在http://vision.ai.uiuc.edu/dugad/上面找到。主要是通过阅读这篇技术报告来了解一些HMM的学习算法,即分段K-Means和向前向后算法(也称为BaumWelch算法)。
前面两篇文章介绍过HMM的基础了,这里就更多的直接上公式了。那两篇文章是:隐马尔可夫模型-HMM-简述-1-原理-示例,隐马尔可夫模型-HMM-简述-2-评估-解码-学习。
1. 关于符号说明
这里简单说明一下,这篇文章将隐藏状态简称为状态,将观察状态简称为符号。
N:状态的种类,M:符号的种类,T:符号序列长度(这里假设观察样本长度都是有一样长的)。
i_t:t时刻的状态。
{V}:符号集合。
Π:状态的初始概率向量。
a_i_j:P(t+1时刻处于状态j | t时刻处于状态i),这是状态之间的转移,是相邻时间的,t时刻到t+1时刻。
b_j(k):P(t时刻的符号是k | t时刻处于状态j),这是状态到符号的条件概率,是同一时间的,都是t时刻。
O_t:t时刻的符号。
λ=(A,B,Π):HMM模型,或者说是HMM的参数。
2. 评估
评估问题:已知HMM参数,计算符号序列的概率,即P(O | λ)。
首先介绍一种直接的计算方式,计算该符号序列对应每一种状态序列的概率,然后将这些概率值求和,即为这个符号序列的概率。
I = i_1,i_2,...,i_T表示任意一个状态序列,O = O_1,O_2,...,O_T表示任意一个符号序列。
P(O,I | λ) = P(O | λ,I) * P(I | λ)
P(O | λ,I) = b_i_1(O_1) * b_i_2(O_2) * ··· * b_i_T(O_T)
P(I | λ) = Π_i_1 * a_i_1_i_2 * ··· * a_i_T-1_i_T
P(O,I | λ)对所有的I求和,即为P(O | λ)
这样计算复杂度较高,对于每个状态I,计算时间为2T,状态I序列的数量为N^T,所以时间复杂度为2T * N^T,是T的指数函数。原文中的公式推导:
4. 学习
学习问题:根据符号序列和与其相关的状态集合,计算是符号序列概率最大的HMM参数。
有两个方法,一个是分段KMeans(The Segmental K-means Algorithm),另一个是向前向后算法(也称为Baum-Welch算法)。
The Segmental K-means Algorithm:通过最大化P(O,I | λ),来调整λ=(A,B,Π),其中I根据解码方法得到的最优状态序列。
The Baum-Welch re-estimation Formulas:通过增加P(O | λ)到一个最大值,来调整λ=(A,B,Π)。P(O | λ)的计算需要针对涉及所有的状态序列I,通过将P(O,I | λ)求和得到。因此这个算法关注的是所有的状态序列,而segmental K-means关注的是最优的状态序列。
4.1 分割K-means算法 (The Segmental K-means Algorithm)
假设λ为当前参数,λ'为新计算的参数,I为λ对应计算出的最优状态序列,I'为λ'计算出的最优状态序列,如果P(O,I|λ) < P(O,I'|λ'),那么继续迭代,令λ=λ'。训练这个模型,我们需要一些符号序列。假设有w个符号,每个符号序列为O=O1,O2,...,OT,长度都为T。每个符号假设是一个D(>=1)的向量。这个算法由以下几个步骤组成:
第一步,随机选择N个符号(D维的向量),然后将wT个符号的每一个符号,分到与其欧氏距离最小的类别中。这样产生了N个类,每个类称为一个状态(从1到N)。这个初始类的划分不会决定最终HMM的参数,但是会决定得到最终HMM参数需要迭代的次数。在我们的例子中,我们均匀的选取N个符号序列,使得这N个符号序列之间相间的符号序列个数相同,并且从每个符号序列中选取一个符号,即在第1个序列中选择第1个符号,在2个序列中选择第2个符号,...,在第N个符号序列中选取第N个符号。具体如何选择可以根据个人意愿进行选择。
第二步,计算初始概率和转移概率,估计Π_i和a_i_j。Π_i=在类别i中O1的个数 / O1的个数。这个很好理解,比如,初始有w个符号序列,那么就有w个O1,分母就是w,分子就是这w个O1有多少个被分到类别i中。a_i_j=O_t在类别i中且O_t+1在类别j中的个数 / O_t在类别i中的个数。
第三步,计算每个状态(指每个类别)的均值和方差。
第四步,估计观察状态到符号的概率。通过计算符号在每个状态(分类)中的分布来估计。这里假定符号的分布服从高斯分布。
第五步,根据估计的HMM参数,计算每个观察序列的最优状态序列I'。如果I'与I不同,那么对应不同的Oi会被重新分配,比如I'与I在第3个元素上不同,那么O3就会重新分配到I'第三个元素对应的分类上去。
第六步,如果在第二步中有重新分配的情况,那么跳转到第二步,进行迭代。
分段K-means算法,在一些观察密度函数和我们假设的高斯密度函数上,收敛到“状态最优似然函数”。
4.2 向前向后算法(Baum-Welch 算法)
这个方法首先假设有一个初始的HMM模型,然后通过下文介绍的方法来改进HMM模型使得P(O|λ)最大化。一个初始的HMM模型可以使用任何的方法构造,但是我们可以使用分段K-means算法的前五步来构造,这样可以得到一个相对合理的HMM的估计。不管怎样,我们经假设一个初始的HMM是已知的。这个算法通过调整参数λ,来使得P(O | λ)最大化。这个优化标准被称为最大似然标标准。P(O | λ)被称为似然函数。
下面首先说明一些计算变量:
γ_t(i)表示t时刻处于状态i的概率,分子刚好是向前因子与向后因子的乘积。
ξ_t(i,j)表示t时刻在状态i,t+1时刻在状态j的概率。
参数估计的公式为:
其中,Π_i的公式感觉应该是Π_i= γ_1(i),即第一个时刻是状态i的概率。(不知道作者是不是写错了,感觉是写错了)
a_i_j的分子是从i状态转移到j状态的联合概率,分母是i状态的概率,相除刚好是从i状态到j状态的转移概率。
b_j(k)的分子是在j状态且符号为k的联合概率,分母是在j状态的概率,相除刚好是已知j状态,输出符号为k的条件概率。
这样计算分两个步骤:第一,根据λ,计算λ';第二,如果P(O | λ')>P(O | λ),那么更新λ为λ'迭代计算,否则停止计算。
Baum-Welch算法需要很多乘法,因此数值可能容易溢出,这需要一些可能的处理技术。而Segmental K-means算法使用Viterbi算法来产生I,因此溢出问题不严重。Segmental K-means的优势在于,有时我们比较关注最优状态序列产生的观察序列,而对所有状态序列产生的观察序列并不关心。此外Segmental K-means的计算量很小。