版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_37334135/article/details/86314856
学习隐马尔可夫模型(HMM),主要就是学习三个问题:概率计算问题,学习问题和预测问题。在前面讲了概率计算问题:前后向算法推导,Baum-Welch算法。最后在这里讲最后的一个问题,预测问题。
预测问题:给定HMM参数
λ={π,A,B},观测序列
O={o1,o2,...,oT},求条件概率
P(I∣O,λ),即给定观测序列求最优可能的状态序列。
记:
Q={q1,q2,...,qN}表示所有可能的状态集合(后面可能也会直接用数字来表示),
V={v1,v2,...,vM}表示所有可能的观测集合。
I={i1,i2,...,iT} 表示状态序列,
O={o1,o2,...,oN} 为对应的观测序列。
下面给出HMM预测问题的两种算法:近似算法和维特比算法
近似算法
近似算法的思想是,在每个时刻
t 选择最有可能的状态
it∗,
t从1开始直到
T,所以可以求出状态序列
I∗=(i1∗,i2∗,...,iT∗),将
I∗作为预测结果。
记
γt(i)=P(it=qi∣O,λ),即已知模型
λ,给定观测序列条件下,在
t 时刻状态为
qi 的概率,根据前后向算法得出的结论1、2中有:
γt(i)=i=1∑Nαt(i)βt(i)αt(i)βt(i)
那么在每一时刻
t 最有可能的状态
it∗为:
it∗=argimaxγt(i)
从而得到最有可能的状态序列
I∗=(i1∗,i2∗,...,iT∗)。
该算法简单,但是不能保证整体是最有可能的预测状态序列。
维特比算法
维特比算法实际上是用动态规划(dp)来求解HMM预测问题。
关于动态规划,也就是将大问题分解分众多小问题,通过小问题的解来得到大问题的解。对各个小问题进行求解后,会将结果填入表中,下次要用的时候就不用再去计算而是直接拿来用了,这样能有效避免重复计算问题(以空间换时间),基本上都会涉及到递推。具体的可以去leetcode上刷两题感受一下,下面写个常见机器人走格子的动态规划问题。
首先定义一个二维的表 int[][] dp,其中dp[i][j]表示从初始位置走到
(i,j) 位置有多少种走法。现在我们需要得到的是 dp[m-1][n-1],即从初始位置走到终点有多少种走法。初始有dp[0][0]=1,那么递推公式是怎样的呢?考虑dp[i][j],由于到
(i,j)位置只能从该位置的左边或者上边走过来,左边走过来的方法数为dp[i][j-1],上边走过来的方法数为dp[i-1][j],两者之和就是走到该位置的方法数。根据dp[i][j-1],dp[i-1][j],需要初始化表的第一行和第一列。
class Solution {
//dp[i][j]表示从左上角走到i,j位置的路径数 dp[i][j] = dp[i-1][j]+dp[i][j-1]
//因为(i,j)位置只能由它上面走过来和左边走过来
public int uniquePaths(int m, int n) {
int[][] dp = new int[m][n];
for(int i = 0; i < m; i ++){
dp[i][0] = 1;
}
for(int j = 1; j < n; j ++){
dp[0][j] = 1;
}
for(int i = 1; i < m; i ++){
for(int j = 1; j < n; j ++){
dp[i][j] = dp[i-1][j] + dp[i][j-1];
}
}
return dp[m-1][n-1];
}
}
再来看维特比算法
定义变量
δt(i):表示在
t 时刻,状态为
i 的所有路径中,概率的最大值。
δt(i)=i1,i2,...,it−1maxP(it=i,it−1,it−2,...,i1,ot,ot−1,...,o1∣λ)
递推过程:
δ1(i)=P(i1=i,o1∣λ)=P(o1∣i1=i,λ)P(i1=i∣λ)=πibi(o1)
δt+1(i)=i1,i2,...,itmaxP(it+1=i,it,...,i1,ot+1,...,o1∣λ)=1≤j≤Nmax(δt(j)aji)bi(ot+1)
终止:
P∗=1≤i≤NmaxδT(i)
对于递推过程的递推公式
(δt(j)aji)bi(ot+1)=P(it=j,it−1,it−2,...,i1,ot,ot−1,...,o1∣λ)P(it+1=i∣it=j,λ)P(ot+1∣it+1=i,λ)=P(it−1,it−2,...,i1,ot,ot−1,...,o1∣it=j,λ)P(it=j∣λ)P(it+1=i∣it=j,λ)P(ot+1∣it+1=i,λ)
通过贝叶斯网络知道,在
it=j的条件下
it−1,it−2,...,i1,ot,ot−1,...,o1 与
it+1=i 是条件独立的,所以有:
P(it−1,it−2,...,i1,ot,ot−1,...,o1∣it=j,λ)P(it=j∣λ)P(it+1=i∣it=j,λ)=P(it+1=i,it−1,it−2,...,i1,ot,ot−1,...,o1∣it=j,λ)P(it=j∣λ)=P(it+1=i,it=j,it−1,it−2,...,i1,ot,ot−1,...,o1∣λ)
带入到
(δt(j)aji)bi(ot+1),得到
(δt(j)aji)bi(ot+1)=P(it+1=i,it=j,it−1,it−2,...,i1,ot,ot−1,...,o1∣λ)P(ot+1∣it+1=i,λ)=P(it=j,it−1,it−2,...,i1,ot,ot−1,...,o1∣λ)P(it+1=i∣λ)P(ot+1∣it+1=i,λ)
同样的方法得到
(δt(j)aji)bi(ot+1)=P(it+1=i,it=j,it−1,it−2,...,i1,ot+1,ot,ot−1,...,o1∣λ)
那么
1≤j≤Nmax(δt(j)aji)bi(ot+1)=1≤j≤NmaxP(it+1=i,it=j,it−1,it−2,...,i1,ot+1,ot,ot−1,...,o1∣λ)=i1,i2,...,itmaxP(it+1=i,it,...,i1,ot+1,...,o1∣λ)
如果要求对应的路径
I∗={i1∗,...,iT∗} 那么只要回溯去求即可。
还有明明是求
P(I∣O,λ)为什么这里是
P(I,O∣λ)呢
P(I∣O,λ)=P(O∣λ)P(I,O∣λ),由于预测前是知道了模型和观测序列,所以分母就是一常数,忽略掉。