隱馬爾可夫模型(Hidden Markov Model,HMM)
- 主要內容
- HMM簡介
- HMM觀測序列、狀態序列、三要素
- HMM三個問題及其對應算法
- HMM應用
1、HMM簡介
隱馬爾可夫模型是可用於標註問題的統計學習模型,描述由隱藏的馬爾可夫鏈隨機生成觀測序列的過程。屬於生成模型(什麼是生成模型?什麼是判別模型?這裏不過多介紹,想了解的童鞋百度會給你答案)。
2、HMM觀測序列、狀態序列、三要素
關於HMM的“觀測序列”、“狀態序列”、“三要素”的講解,本文主要借鑑“大佬skyme——關於隱馬爾可夫模型”一文的思想,通過一個實例與大家分享。
假設我手裏有三個不同的骰子。第一個骰子是我們平常見的骰子(稱這個骰子爲D6),6個面,每個面(1,2,3,4,5,6)出現的概率是1/6。第二個骰子是個四面體(稱這個骰子爲D4),每個面(1,2,3,4)出現的概率是1/4。第三個骰子有八個面(稱這個骰子爲D8),每個面(1,2,3,4,5,6,7,8)出現的概率是1/8。
假設我現在開始擲骰子:
第一次擲骰子的時候,我隨機的選取一個骰子。其實,第一次擲骰子,每個骰子都有一定的概率被我選擇,且概率和爲1。這就是三要素之一的初始狀態概率向量。也就是第一次擲的時候,我選擇某個骰子的概率。可以表示爲
假設上一次擲骰子,我選擇了骰子D6,那麼這次擲骰子,我可以選擇骰子D6、D4、D8中的一個。由上次的D6跳轉到這次的D6 or D4 or D8,有一定的概率,且跳轉的概率和爲1。同理,假設我上次選擇了D4或者D8,那麼跳轉到這次的D6 or D4 or D8,也是有一定的概率的。這些概率組成的矩陣,就是三要素之一的狀態轉移概率矩陣。可以表示爲
我每次擲骰子都有可能得到(1,2,3,4,5,6,7,8)中的一個數字,且每個骰子得到(1,2,3,4,5,6,7,8)的概率不同。這三個骰子得到(1,2,3,4,5,6,7,8)的概率組成的矩陣,就是三要素之一的觀測概率矩陣。可以表示爲
假設我投擲了10次骰子,得到一串數字(1、8、2、7、3、6、4、5、1、8)。那麼這串數字就是觀測序列。
觀測序列中的每個數字,分別是由哪個骰子得到的呢?假設是由(D6、D8、D4、D8、D4、D6、D4、D6、D6、D8)得到的,那麼這個由骰子組成的序列,就是狀態序列。這個狀態序列其實就是HMM中的隱含狀態鏈,或者說就是隱藏的馬爾可夫鏈。
3、HMM三個問題及其對應算法
問題一,預測問題(解碼問題):已知三要素、觀測序列,求解概率最大的狀態序列。
解決方法:維特比算法。維特比算法其實就是通過動態規劃求解概率最大的路徑(最優路徑),這條路徑就是要求解的狀態序列。動態規劃,相對比較簡單,這裏就不展開介紹了。此處直接上代碼,看懂代碼,就看懂維特比算法了。建議讀者認真看一下此處給出的代碼,非常非常容易理解。這裏的代碼以上面骰子的例子爲背景。
//這裏的變量我就不初始化啦,大概給出主體思想的代碼
double Initial_Selection[3]={}; //初始狀態概率向量,第一次選擇某個骰子的概率
double Transition_Probability[3][3]={}; //狀態轉移概率矩陣,由某個骰子跳轉到另一個骰子的概率
double Observation_Probability[3][8]={}; //觀測概率矩陣,每個骰子得到(1,2,3,4,5,6,7,8)的概率
int Obs_vec[10]={}; //觀測序列,投擲了10次骰子
int Hidden_vec[10]; //狀態序列,需要求解的
int* DecodeFun()
{
double temp_MaxProbabilityVector[10]={0}; //臨時變量,存儲當前狀態概率的最大值,知道動態規劃的人都懂
Hidden_vec[0] = max(Initial_Selection); //這裏邊我偷懶啦,意思明白就行啦。如果觀測序列的第一個值爲8,那隻能選擇骰子D8啦;如果爲1,那就選擇初始狀態概率向量中最大的骰子
for(int i=1; i<10; i++)
{
for(int j=0; j<3; j++)
{
if(temp_MaxProbabilityVector[i] < temp_MaxProbabilityVector[i-1]*Transition_Probability[Hidden_vec[i-1]][j]*Observation_Probability[j][Obs_vec[i]])
{
temp_MaxProbabilityVector[i] = temp_MaxProbabilityVector[i-1]*Transition_Probability[Hidden_vec[i-1]][j]*Observation_Probability[j][Obs_vec[i]];
Hidden_vec[i] = j; //保存路徑(狀態)
}
}
}
return Hidden_vec; //Hidden_vec即爲所求解的狀態序列
}
問題二:學習問題:一個問題是已知觀測序列和狀態序列,求解三要素,這是監督學習;另一個是已知觀測序列,求解三要素,這是非監督學習。
已知觀測序列以及對應的狀態序列,求解三要素。可以通過極大似然估計進行求解。
已知觀測序列,求解三要素。可以通過Baum-Welch算法進行求解,其實吧,這個Baum-Welch算法就是EM算法嘛。EM算法詳細介紹,可以參考我之前的博客,“EM算法詳解”。
問題三:概率計算問題:已知三要素,觀測序列,計算在該模型下,該觀測序列出現的概率。
解決方法:前向算法、後向算法。這兩個算法,李航《統計學習方法》中的例子很清晰,也非常容易理解,感興趣的可以瞭解一下。博主偷懶啦,這裏就不詳細介紹啦。
4、HMM應用
關於HMM的應用,個人認爲比較廣泛的是問題一的應用。比如,預測問題(通過海藻變化來預測天氣:海藻的變化就是觀察序列,待預測的天氣就是狀態序列)、解碼問題(通過HMM進行中文分詞,這一塊兒,博主還在學習中,後續會有相關的博客進行更新)。