Quantcast
Channel: CodeSection,代码区,Python开发技术文章_教程 - CodeSec
Viewing all articles
Browse latest Browse all 9596

HMM三个基本问题的数学推导及python实现

$
0
0

计算观测序列概率主要有前向(forward)和后向(backward)算法,以及概念上可行但计算上不可行的直接计算法(枚举)。

直接计算法 给定模型,求给定长度为T的观测序列的概率,直接计算法的思路是枚举所有的长度T的状态序列,计算该状态序列与观测序列的联合概率(隐状态发射到观测),对所有的枚举项求和即可。在状态种类为N的情况下,一共有N^T种排列组合,每种组合计算联合概率的计算量为T,总的复杂度为
HMM三个基本问题的数学推导及python实现
,并不可取。 前向算法 定义(前向概率)给定马尔可夫模型
HMM三个基本问题的数学推导及python实现
,定义到时刻t部分观测序列为
HMM三个基本问题的数学推导及python实现
,且状态为
HMM三个基本问题的数学推导及python实现
的概率为前向概率,记作
HMM三个基本问题的数学推导及python实现
可以递推的求得前向概率
HMM三个基本问题的数学推导及python实现
及观测序列概率
HMM三个基本问题的数学推导及python实现
观测序列概率的前向算法 输入:隐马尔科夫模型
HMM三个基本问题的数学推导及python实现
,观测序列O; 输出: 观测序列概率
HMM三个基本问题的数学推导及python实现

(1) 初值


HMM三个基本问题的数学推导及python实现

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


HMM三个基本问题的数学推导及python实现
计算时刻t+1部分观测序列为
HMM三个基本问题的数学推导及python实现
且时刻t+1处于状态
HMM三个基本问题的数学推导及python实现
的前向概率.

(3)终止


HMM三个基本问题的数学推导及python实现

由于到了时间T,一共有N种状态发射了最后那个观测,所以最终的结果要将这些概率加起来。

由于每次递推都是在前一次的基础上进行的,所以降低了复杂度。准确来说,其计算过程如下图所示:


HMM三个基本问题的数学推导及python实现

下方标号表示时间节点,每个时间点都有N种状态,所以相邻两个时间之间的递推消耗N^2次计算。而每次递推都是在前一次的基础上做的,所以只需累加O(T)次,所以总体复杂度是O(T*N^2)。

后向算法 定义(前向概率)给定马尔可夫模型
HMM三个基本问题的数学推导及python实现
,定义在时刻t状态为qi的条件下,从t+1到T的部分观测序列为
HMM三个基本问题的数学推导及python实现
的概率为后向概率,记作:
HMM三个基本问题的数学推导及python实现
可以用递推的方法求得后向概率
HMM三个基本问题的数学推导及python实现
以及观测序列概率
HMM三个基本问题的数学推导及python实现
算法(观测序列概率的后向算法) 输入:隐马尔科夫模型
HMM三个基本问题的数学推导及python实现
,观测序列O; 输出: 观测序列概率
HMM三个基本问题的数学推导及python实现

(1)初值


HMM三个基本问题的数学推导及python实现

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

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


HMM三个基本问题的数学推导及python实现
(3)
HMM三个基本问题的数学推导及python实现

最后的求和是因为,在第一个时间点上有N种后向概率都能输出从2到T的观测序列,所以乘上输出O1的概率后求和得到最终结果。

学习算法

隐马尔可夫模型的学习,根据训练数据是包括观测序列和对应的状态序列还是只有观测序列,可以分别由监督学习与非监督学习实现。

监督学习方法 假设已给训练数据包含S个长度相同的观测序列和对应的状态序列
HMM三个基本问题的数学推导及python实现
“那么可以利用极大似然估计法来估计隐马尔可夫模型的参数。具体方法如下。 1.转移概率
HMM三个基本问题的数学推导及python实现
的估计 设样本中时刻t处于状态i时刻t+1转移到状态j的频数为
HMM三个基本问题的数学推导及python实现
,那么状态转移概率
HMM三个基本问题的数学推导及python实现
的估计是:
HMM三个基本问题的数学推导及python实现

2.观测概率的估计

设样本中状态为j并观测为k的频数是
HMM三个基本问题的数学推导及python实现
,那么状态为j观测为k的概率的估计是
HMM三个基本问题的数学推导及python实现
Baum-Welch算法 假设给定训练数据只包含S个长度为T的观测序列
HMM三个基本问题的数学推导及python实现
而没有对应的状态序列,目标是学习隐马尔可夫模型
HMM三个基本问题的数学推导及python实现
的参数。我们将观测序列数据看作观测数据O,状态序列数据看作不可观测的隐数据I,那么隐马尔可夫模型事实上是一个含有隐变量的概率模型
HMM三个基本问题的数学推导及python实现

它的参数学习可以由EM算法实现。

1 确定完全数据的对数似然函数

所有观测数据写成
HMM三个基本问题的数学推导及python实现
,所有隐数据写成
HMM三个基本问题的数学推导及python实现
,完全数据是
HMM三个基本问题的数学推导及python实现
,完全数据的对数似然函数是
HMM三个基本问题的数学推导及python实现
。 2 EM算法的E步: 求Q的函数
HMM三个基本问题的数学推导及python实现
HMM三个基本问题的数学推导及python实现
其中,
HMM三个基本问题的数学推导及python实现
是隐马尔可夫模型参数的当前估计值,
HMM三个基本问题的数学推导及python实现
是要极大化的隐马尔可夫模型参数。 Q函数的标准定义是:
HMM三个基本问题的数学推导及python实现
,公式内部其实是条件概率。
HMM三个基本问题的数学推导及python实现

这个式子从左到右依次是初始概率、发射概率、转移概率、发射概率。

于是,函数
HMM三个基本问题的数学推导及python实现
可以写成:
HMM三个基本问题的数学推导及python实现
式中求和都是对所有训练数据的序列总长度T进行的。这个式子是将
HMM三个基本问题的数学推导及python实现
代入
HMM三个基本问题的数学推导及python实现
后,将初始概率,转移概率,发射概率这三部分乘积的对数拆分为对数之和,所以有三项。 3 EM算法的M步:极大化Q函数
HMM三个基本问题的数学推导及python实现
求模型参数:
HMM三个基本问题的数学推导及python实现

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

第一项可以写成:


HMM三个基本问题的数学推导及python实现
注意到
HMM三个基本问题的数学推导及python实现
满足约束条件利用拉格朗日乘子法,写出拉格朗日函数:
HMM三个基本问题的数学推导及python实现

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


HMM三个基本问题的数学推导及python实现

得到:


HMM三个基本问题的数学推导及python实现

对i求和得到:


HMM三个基本问题的数学推导及python实现
代入
HMM三个基本问题的数学推导及python实现
中得到:
HMM三个基本问题的数学推导及python实现

第二项可以写成:


HMM三个基本问题的数学推导及python实现
应用具有约束条件
HMM三个基本问题的数学推导及python实现
的拉格朗日乘子法可以求出:
HMM三个基本问题的数学推导及python实现

第三项为:


HMM三个基本问题的数学推导及python实现
同样用拉格朗日乘子法,约束条件是
HMM三个基本问题的数学推导及python实现
。注意,只有在对
HMM三个基本问题的数学推导及python实现

HMM三个基本问题的数学推导及python实现

HMM三个基本问题的数学推导及python实现
的偏导数才不为0,以
HMM三个基本问题的数学推导及python实现
表示。求得:
HMM三个基本问题的数学推导及python实现
Baum-Welch模型参数估计公式

将这三个式子中的各概率分别简写如下:


HMM三个基本问题的数学推导及python实现
HMM三个基本问题的数学推导及python实现

则可将相应的公式写成:


HMM三个基本问题的数学推导及python实现

这三个表达式就是Baum-Welch算法(Baum-Welch algorithm),它是EM算法在隐马尔可夫模型学习中的具体实现,由Baum和Welch提出。

算法 (Baum-Welch算法) 输入:观测数据
HMM三个基本问题的数学推导及python实现

输出:隐马尔科夫模型参数

(1)初始化

对n = 0 选取
HMM三个基本问题的数学推导及python实现
得到模型
HMM三个基本问题的数学推导及python实现

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


HMM三个基本问题的数学推导及python实现
HMM三个基本问题的数学推导及python实现
(3)终止,得到模型参数
HMM三个基本问题的数学推导及python实现
。 预测算法

隐马尔可夫模型预测的两种算法:近似算法与维特比算法(Viterbi algorithm)。

近似算法 近似算法的想法是,在每个时刻t选择在该时刻最有可能出现的状态
HMM三个基本问题的数学推导及python实现
,从而得到一个状态序列
HMM三个基本问题的数学推导及python实现
,将它作为预测的结果。 给定隐马尔科夫模型和观测序列,在时刻t处于状态qi的概率
HMM三个基本问题的数学推导及python实现

HMM三个基本问题的数学推导及python实现
在每一时刻t最优可能的状态
HMM三个基本问题的数学推导及python实现

HMM三个基本问题的数学推导及python实现
从而得到状态序列
HMM三个基本问题的数学推导及python实现

近似算法的优点是计算简单,其缺点是不能保证预测的状态序列整体是最有可能的状态序列,因为预测的状态序列可能有实际不发生的部分。

维特比算法

维特比算法实际是用动态规划解隐马尔可夫模型预测问题,即用动态规划(dynamic programming)求概率最大路径(最优路径)。这时一条路径对应着一个状态序列。

根据动态规划原理,最优路径具有这样的特性:如果最优路径在时刻t通过结点
HMM三个基本问题的数学推导及python实现
,那么这一路径从结点
HMM三个基本问题的数学推导及python实现
到终点
HMM三个基本问题的数学推导及python实现
的部分路径,对于从
HMM三个基本问题的数学推导及python实现

HMM三个基本问题的数学推导及python实现
的所有可能的部分路径来说,必须是最优的。因为假如不是这样,那么从
HMM三个基本问题的数学推导及python实现

HMM三个基本问题的数学推导及python实现
就有另一条更好的部分路径存在,如果把它们和
HMM三个基本问题的数学推导及python实现
到达
HMM三个基本问题的数学推导及python实现
的部分路径连接起来,就会形成一条比原来的路径更优的路径,这是矛盾的。依据这一原理,我们只需从时刻t=l开始,递推地计算在时刻t状态为i的各条部分路径的最大概率,直至得到时刻t = T状态为i的各条路径的最大概率。时刻t = T的最大概率即为最优路径的概率是
HMM三个基本问题的数学推导及python实现
,最优路径的终结点
HMM三个基本问题的数学推导及python实现
也同时得到。之后,为了找出最优路径的各个结点,从终结点
HMM三个基本问题的数学推导及python实现
开始,由后向前逐步求得结点
HMM三个基本问题的数学推导及python实现
得到最优路径这就是维特比算法。 首先导入两个变量
HMM三个基本问题的数学推导及python实现

HMM三个基本问题的数学推导及python实现
,定义在时刻t状态为i的所有单个路径
HMM三个基本问题的数学推导及python实现
中概率最大值为:
HMM三个基本问题的数学推导及python实现

可得递推公式:


HMM三个基本问题的数学推导及python实现

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


HMM三个基本问题的数学推导及python实现

算法(维特比算法)

输入: 模型
HMM三个基本问题的数学推导及python实现
和观测
HMM三个基本问题的数学推导及python实现
; 输出: 最优路径
HMM三个基本问题的数学推导及python实现

(1)初始化


HMM三个基本问题的数学推导及python实现

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


HMM三个基本问题的数学推导及python实现

(3)终止


HMM三个基本问题的数学推导及python实现

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


HMM三个基本问题的数学推导及python实现
求得最优路径
HMM三个基本问题的数学推导及python实现

维特比算法的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

Viewing all articles
Browse latest Browse all 9596

Trending Articles