计算观测序列概率主要有前向(forward)和后向(backward)算法,以及概念上可行但计算上不可行的直接计算法(枚举)。
直接计算法 给定模型,求给定长度为T的观测序列的概率,直接计算法的思路是枚举所有的长度T的状态序列,计算该状态序列与观测序列的联合概率(隐状态发射到观测),对所有的枚举项求和即可。在状态种类为N的情况下,一共有N^T种排列组合,每种组合计算联合概率的计算量为T,总的复杂度为
,并不可取。 前向算法 定义(前向概率)给定马尔可夫模型

,定义到时刻t部分观测序列为

,且状态为

的概率为前向概率,记作

可以递推的求得前向概率

及观测序列概率

观测序列概率的前向算法 输入:隐马尔科夫模型

,观测序列O; 输出: 观测序列概率

(1) 初值

(2) 递推,对t = 1, 2, …… ,T-1,

计算时刻t+1部分观测序列为

且时刻t+1处于状态

的前向概率.
(3)终止

由于到了时间T,一共有N种状态发射了最后那个观测,所以最终的结果要将这些概率加起来。
由于每次递推都是在前一次的基础上进行的,所以降低了复杂度。准确来说,其计算过程如下图所示:

下方标号表示时间节点,每个时间点都有N种状态,所以相邻两个时间之间的递推消耗N^2次计算。而每次递推都是在前一次的基础上做的,所以只需累加O(T)次,所以总体复杂度是O(T*N^2)。
后向算法 定义(前向概率)给定马尔可夫模型
,定义在时刻t状态为qi的条件下,从t+1到T的部分观测序列为

的概率为后向概率,记作:

可以用递推的方法求得后向概率

以及观测序列概率

算法(观测序列概率的后向算法) 输入:隐马尔科夫模型

,观测序列O; 输出: 观测序列概率

(1)初值

根据定义,从T+1到T的部分观测序列其实不存在,所以硬性规定这个值是1。
(2)对t = T-1, T-2,……,1

(3)

最后的求和是因为,在第一个时间点上有N种后向概率都能输出从2到T的观测序列,所以乘上输出O1的概率后求和得到最终结果。
学习算法隐马尔可夫模型的学习,根据训练数据是包括观测序列和对应的状态序列还是只有观测序列,可以分别由监督学习与非监督学习实现。
监督学习方法 假设已给训练数据包含S个长度相同的观测序列和对应的状态序列
“那么可以利用极大似然估计法来估计隐马尔可夫模型的参数。具体方法如下。 1.转移概率

的估计 设样本中时刻t处于状态i时刻t+1转移到状态j的频数为

,那么状态转移概率

的估计是:

2.观测概率的估计
设样本中状态为j并观测为k的频数是
,那么状态为j观测为k的概率的估计是

Baum-Welch算法 假设给定训练数据只包含S个长度为T的观测序列

而没有对应的状态序列,目标是学习隐马尔可夫模型

的参数。我们将观测序列数据看作观测数据O,状态序列数据看作不可观测的隐数据I,那么隐马尔可夫模型事实上是一个含有隐变量的概率模型

它的参数学习可以由EM算法实现。
1 确定完全数据的对数似然函数
所有观测数据写成
,所有隐数据写成

,完全数据是

,完全数据的对数似然函数是

。 2 EM算法的E步: 求Q的函数


其中,

是隐马尔可夫模型参数的当前估计值,

是要极大化的隐马尔可夫模型参数。 Q函数的标准定义是:

,公式内部其实是条件概率。

这个式子从左到右依次是初始概率、发射概率、转移概率、发射概率。
于是,函数
可以写成:

式中求和都是对所有训练数据的序列总长度T进行的。这个式子是将

代入

后,将初始概率,转移概率,发射概率这三部分乘积的对数拆分为对数之和,所以有三项。 3 EM算法的M步:极大化Q函数

求模型参数:

由于要极大化的参数在Q函数表达式中单独的出现在3个项中,所以只需对各项分别极大化。
第一项可以写成:

注意到

满足约束条件利用拉格朗日乘子法,写出拉格朗日函数:

对其求偏导数,并令结果为0:

得到:

对i求和得到:

代入

中得到:

第二项可以写成:

应用具有约束条件

的拉格朗日乘子法可以求出:

第三项为:

同样用拉格朗日乘子法,约束条件是

。注意,只有在对

时

对

的偏导数才不为0,以

表示。求得:

Baum-Welch模型参数估计公式
将这三个式子中的各概率分别简写如下:


则可将相应的公式写成:

这三个表达式就是Baum-Welch算法(Baum-Welch algorithm),它是EM算法在隐马尔可夫模型学习中的具体实现,由Baum和Welch提出。
算法 (Baum-Welch算法) 输入:观测数据
输出:隐马尔科夫模型参数
(1)初始化
对n = 0 选取
得到模型

(2)递推。 对n = 1, 2 ……,


(3)终止,得到模型参数

。 预测算法
隐马尔可夫模型预测的两种算法:近似算法与维特比算法(Viterbi algorithm)。
近似算法 近似算法的想法是,在每个时刻t选择在该时刻最有可能出现的状态
,从而得到一个状态序列

,将它作为预测的结果。 给定隐马尔科夫模型和观测序列,在时刻t处于状态qi的概率

是

在每一时刻t最优可能的状态

是

从而得到状态序列

。
近似算法的优点是计算简单,其缺点是不能保证预测的状态序列整体是最有可能的状态序列,因为预测的状态序列可能有实际不发生的部分。
维特比算法维特比算法实际是用动态规划解隐马尔可夫模型预测问题,即用动态规划(dynamic programming)求概率最大路径(最优路径)。这时一条路径对应着一个状态序列。
根据动态规划原理,最优路径具有这样的特性:如果最优路径在时刻t通过结点
,那么这一路径从结点

到终点

的部分路径,对于从

到

的所有可能的部分路径来说,必须是最优的。因为假如不是这样,那么从

到

就有另一条更好的部分路径存在,如果把它们和

到达

的部分路径连接起来,就会形成一条比原来的路径更优的路径,这是矛盾的。依据这一原理,我们只需从时刻t=l开始,递推地计算在时刻t状态为i的各条部分路径的最大概率,直至得到时刻t = T状态为i的各条路径的最大概率。时刻t = T的最大概率即为最优路径的概率是

,最优路径的终结点

也同时得到。之后,为了找出最优路径的各个结点,从终结点

开始,由后向前逐步求得结点

得到最优路径这就是维特比算法。 首先导入两个变量

和

,定义在时刻t状态为i的所有单个路径

中概率最大值为:

可得递推公式:

定义在时刻t状态为i的所有单个路径中概率最大的路径的第t-1个结点为

算法(维特比算法)
输入: 模型
和观测

; 输出: 最优路径

(1)初始化

(2)递推,对t = 2, 3, ……,T

(3)终止

(4)最优路径回溯。 对t = T-1, T-2……1

求得最优路径

维特比算法的python实现
def viterbi(self, obs_seq): """ Returns ------- V : numpy.ndarray V [s][t] = Maximum probability of an observation sequence ending at time 't' with final state 's' prev : numpy.ndarray Contains a pointer to the previous state at t-1 that maximizes V[state][t] """ N = self.A.shape[0] T = len(obs_seq) prev = np.zeros((T - 1, N), dtype=int) # DP matrix containing max likelihood of state at a given time V = np.zeros((N, T)) V[:,0] = self.pi * self.B[:,obs_seq[0]] for t in range(1, T): for n in range(N): seq_probs = V[:,t-1] * self.A[:,n] * self.B[n, obs_seq[t]] prev[t-1,n] = np.argmax(seq_probs) V[n,t] = np.max(seq_probs) return V, prev