HMM學習筆記(三):動態規劃與維特比演算法
學習隱馬爾可夫模型(HMM),主要就是學習三個問題:概率計算問題,學習問題和預測問題。在前面講了概率計算問題:前後向演算法推導,Baum-Welch演算法。最後在這裡講最後的一個問題,預測問題。
預測問題:給定HMM引數 ,觀測序列 ,求條件概率 ,即給定觀測序列求最優可能的狀態序列。
記: 表示所有可能的狀態集合(後面可能也會直接用數字來表示), 表示所有可能的觀測集合。
表示狀態序列, 為對應的觀測序列。
下面給出HMM預測問題的兩種演算法:近似演算法和維特比演算法
近似演算法
近似演算法的思想是,在每個時刻 選擇最有可能的狀態 , 從1開始直到 ,所以可以求出狀態序列 ,將 作為預測結果。
記 ,即已知模型 ,給定觀測序列條件下,在 時刻狀態為 的概率,根據前後向演算法得出的結論1、2中有:
那麼在每一時刻 最有可能的狀態 為:
從而得到最有可能的狀態序列
。
該演算法簡單,但是不能保證整體是最有可能的預測狀態序列。
維特比演算法
維特比演算法實際上是用動態規劃(dp)來求解HMM預測問題。
關於動態規劃,也就是將大問題分解分眾多小問題,通過小問題的解來得到大問題的解。對各個小問題進行求解後,會將結果填入表中,下次要用的時候就不用再去計算而是直接拿來用了,這樣能有效避免重複計算問題(以空間換時間),基本上都會涉及到遞推。具體的可以去leetcode上刷兩題感受一下,下面寫個常見機器人走格子的動態規劃問題。
首先定義一個二維的表 int[][] dp,其中dp[i][j]表示從初始位置走到 位置有多少種走法。現在我們需要得到的是 dp[m-1][n-1],即從初始位置走到終點有多少種走法。初始有dp[0][0]=1,那麼遞推公式是怎樣的呢?考慮dp[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];
}
}
再來看維特比演算法
定義變數 :表示在 時刻,狀態為 的所有路徑中,概率的最大值。