隱馬爾科夫模型-HMM和Viterbi算法

由於最近初學,故寫下此筆記

我們在講解隱馬模型之前,先了解一下馬爾科夫模型:

每個狀態只依賴之前有限個狀態:

  1. N階馬爾科夫:依賴之前n個狀態

  2. 1階馬爾科夫:僅僅依賴之前一個狀態

馬爾科夫模型重要的三類參數:

  1. 狀態

  2. 初始概率

  3. 狀態轉移概率

那麼其中狀態狀態轉移概率怎麼計算得到:

        p(St+1=l|St=k)=l緊跟k出現的次數/k出現的總次數,我們可以這樣理解:轉移概率由一個狀態到另外一個狀態的轉移概率,前一個字和後面一個字的詞性相同過的概率還是比較大的, 根據貝葉斯公式

p(A,B)= p(B|A)*p(A)計算出各個狀態轉移的概率

初始概率是怎麼計算得到:P(S1=k)=k 作爲序列開始的次數/觀測序列總數 也可以這麼理解:查看該狀態的開頭有多少個字,計算一下該狀態的概率

馬爾科夫模型是對一個序列數據的建模,但是有時候我們會對兩個序列數據進行建模,因此就引出了隱馬爾科夫模型即HMM

例如:我們在發音真高興的時候,語音爲zhen,gao,xing三個觀察序列,觀察序列爲已知的,期望找到真高興三個狀態序列,或是下面圖中的廣州塔,首先對每個觀測序列進行分析背後的狀態和詞性(B代表開始,M代表中間,E代表結束,S代表單個詞,但是這個狀態只是針對詞語,對於句子還需要另外區分其狀態)。

發射概率意思是在“真”詞中,發射出zhen的語音概率爲多大

那麼什麼是隱馬:

每一個時刻的狀態都是不可見的, 沒法觀測到一個s1, s2, ..., st的 狀態,  但是HMM在每個時刻都會輸出一個符號ot, 而且ot僅與st相關, 這個稱爲獨立輸出假設。 So, HMM是基於馬爾科夫假設和獨立輸出假設。

我們由此可以計算出, 在某個特定的狀態序列s1 , s2, .., st 產生o1, o2, ..., ot的概率: 根據乘法公式展開: 

P(s1 , s2, .., st , o1, o2, ..., ot) = P(o1, o2, ..., ot | s1 , s2, .., st) * P(s1 , s2, .., st)  =  P(ot | st) * P(st |  st-1) , t從1 到 T 連乘,  其中在語音識別中P(s1 , s2, .., st) 稱爲語言模型, P(o1, o2, ..., ot | s1 , s2, .., st) 稱爲聲學模型。

到此爲止基本的概念就介紹完了, 不難發現,HMM 其實只是一種結構模型,由一系列的參數來構成  入 = (PI,  A , B),其中PI 是初始的狀態概率, A是狀態之間的轉移概率矩陣, B是在某一狀態下到觀測值之間的生成概率矩陣

那麼有了隱馬,這個隱馬主要是來解決什麼問題,因此拋出隱馬解決的三個問題:

1、 給定一個模型,如何計算出某個特定的輸出序列的概率

2、 給定一個模型和某個特定的輸出序列,如何找到最可能產生這個輸出的狀態序列

3、 給定足夠的觀測數據, 如何估計出HMM的參數(即轉移概率矩陣和省城概率矩陣)

這裏爲只說明一下每個問題的解決的方式,由於知識有限,

  • 第一個問題,我們需要採用前向後向算法來解決該問題,那麼什麼是前向算法和後向算法:

前向概率解決問題;當一個狀態爲K的前提下,計算t時刻爲k的觀測序列的概率

後向概率解決問題:當t時刻狀態爲k的前提下,計算t+1時刻到T時刻觀測序列的概率。

  • 第二個問題,這裏我們就需要引出Viterbi算法,利用動態規劃求最優的路徑的方式來求解,那麼什麼是Viterbi算法

維特比算法是一個特殊但應用最廣的動態規劃算法,它是針對籬笆網絡的有向圖(Lattice)的最短路徑問題而提出的。凡是使用隱含馬爾可夫模型描述的問題都可以用維特比算法來解碼,包括今天的數字通信、語音識別、機器翻譯、拼音轉漢字、分詞等,通俗的講就是利用HMM模型來達到計算最優路徑的算法,既然要利用HMM模型,那麼就離不開HMM的五大參數來求解

  1. 狀態

  2. 觀測序列

  3. 初始概率

  4. 狀態轉移概率

  5. 發射概率

我們用一個例子來解釋這個Viterbi算法:

一、背景

假如我的身體情況只有兩種可能:健康或者發燒。
假設沒有體溫計或者百度這種神奇東西,我唯一判斷他身體情況的途徑就是到樓下的豬大炮詢問。
豬大炮通過詢問我的感覺,判斷我的病情,再假設我只會回答正常、頭暈或冷。
第一天我告訴豬大炮感覺正常。
第二天我告訴豬大炮感覺有點冷。
第三天我告訴豬大炮感覺有點頭暈。
那麼問題來了,豬大炮如何根據我的描述的情況,推斷出這三天中我的一個身體狀態呢?
二、已知情況

隱含的身體狀態 = { 健康 , 發燒 }
可觀察的感覺狀態 = { 正常 , 冷 , 頭暈 }
豬大炮預判的我身體狀態的概率分佈 = { 健康:0.6 , 發燒: 0.4 }
豬大炮認爲的我身體健康狀態的轉換概率分佈 = {
健康->健康: 0.7 ,
健康->發燒: 0.3 ,
發燒->健康:0.4 ,
發燒->發燒: 0.6
}
豬大炮認爲的在相應健康狀況條件下,我的感覺的概率分佈 = {
健康,正常:0.5 ,冷 :0.4 ,頭暈: 0.1 ;
發燒,正常:0.1 ,冷 :0.3 ,頭暈: 0.6 
}
我連續三天的身體感覺依次是: 正常、冷、頭暈 。

三、題目:

已知如上,求:我這三天的身體健康狀態變化的過程是怎麼樣的?

四、求解過程

根據 Viterbi 理論,後一天的狀態會依賴前一天的狀態和當前的可觀察的狀態。那麼只要根據第一天的正常狀態依次推算找出到達第三天頭暈狀態的最大的概率,就可以知道這三天的身體變化情況。
傳不了圖片,悲劇了。。。
1.初始情況:
P(健康) = 0.6,P(發燒)=0.4。
2.求第一天的身體情況:
計算在我感覺正常的情況下最可能的身體狀態。
P(今天健康) = P(健康|正常)*P(健康|初始情況) = 0.5 * 0.6 = 0.3
P(今天發燒) = P(發燒|正常)*P(發燒|初始情況) = 0.1 * 0.4 = 0.04
那麼取最優就可以認爲第一天最可能的身體狀態是:健康。
3.求第二天的身體狀況:
計算在我感覺冷的情況下最可能的身體狀態。
那麼第二天有四種情況,由於第一天的發燒或者健康轉換到第二天的發燒或者健康。
P(前一天發燒,今天發燒) = P(發燒|前一天)*P(發燒->發燒)*P(冷|發燒) = 0.04 * 0.6 * 0.3 = 0.0072
P(前一天發燒,今天健康) = P(健康|前一天)*P(發燒->健康)*P(冷|健康) = 0.04 * 0.4 * 0.4 = 0.0064
P(前一天健康,今天健康) = P(發燒|前一天)*P(健康->健康)*P(冷|健康) = 0.3 * 0.7 * 0.4 = 0.084
P(前一天健康,今天發燒) = P(健康|前一天)*P(健康->發燒)*P(冷|發燒) = 0.3 * 0.3 *.03 = 0.027
那麼取最優可以認爲,第二天最可能的狀態是:健康。
4.求第三天的身體狀態:
計算在我感覺頭暈的情況下最可能的身體狀態。
P(前一天發燒,今天發燒) = P(發燒|前一天)*P(發燒->發燒)*P(頭暈|發燒) = 0.027 * 0.6 * 0.6 = 0.00972
P(前一天發燒,今天健康) = P(健康|前一天)*P(發燒->健康)*P(頭暈|健康) = 0.027 * 0.4 * 0.1 = 0.00108
P(前一天健康,今天健康) = P(發燒|前一天)*P(健康->健康)*P(頭暈|健康) = 0.084 * 0.7 * 0.1 = 0.00588
P(前一天健康,今天發燒) = P(健康|前一天)*P(健康->發燒)*P(頭暈|發燒) = 0.084 * 0.3 *0.6 = 0.01512
那麼取最優可以認爲:第三天最可能的狀態是發燒。

五、結論:

根據如上計算。這樣豬大炮斷定,我這三天身體變化的序列是:健康->健康->發燒。

這個算法大概就是通過已知的可以觀察到的序列,和一些已知的狀態轉換之間的概率情況,通過綜合狀態之間的轉移概率和前一個狀態的情況計算出概率最大的狀態轉換路徑,從而推斷出隱含狀態的序列的情況。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章