小白給小白詳解維特比算法(二)——隱馬爾科夫模型(HMM)

小白給小白詳解維特比算法(二)——隱馬爾科夫模型(HMM)


本文致力於解釋隱含馬爾科夫模型和上一篇我們提到的籬笆網絡的最短路徑問題的相同點和不同點,儘量通俗易懂但是也有些必要的公式。如果你有數學恐懼症,請無視所有的“注”。我的概率論學的很爛,如果“注”裏面有錯誤,請務必直接噴,不要留情,謝謝!

隱馬爾科夫模型(HMM)和籬笆網絡(神馬關係)

咱先別"隱身",先說說啥是馬爾科夫模型?

隱馬爾科夫模型,一聽這個名字就和馬爾科夫模型有着隱藏的聯繫。
所謂的馬爾科夫模型,其實說的就是好好一個人,是怎麼變來變去的(旁白:???)。比如說,一個人某一天可能輕微感冒,也可能正常,還可能重感冒(請原諒我對病不是很瞭解)。如果你認爲這個是上天隨機拋硬幣決定的倒也可以,比如我們可以認爲:

P(身體狀態=正常)=0.7
P(身體狀態=輕感冒)=0.2
P(身體狀態=重感冒)=0.1

但是可能更多的,某一天的身體狀態是由這個人長期以來作出來的……啊不是,是和前一天(或者N天)的身體狀態變來的。比如正常可能會更大概率讓第二天依然正常,而輕感冒比正常更容易讓第二天表現爲重感冒。
如果我們認爲某一天的身體狀態完全由前一天的身體狀態來決定(這叫做一階馬爾科夫假設,這算是這個世界上最不負責任的10000個假設之一了,好在很多情況下這種假設還蠻好用),那麼我們可以畫這樣一個圖出來:
image_1c6pb7e8e19tj1el1rd8lho17bim.png-99.7kB
圖1
簡單解釋一下,如果某個人在昨天是輕感冒,那麼在今天他有0.4的概率維持輕感冒的狀態,0.4的概率病情好轉,還有0.2的概率病情惡化。
Emmmm…看上去有點亂,如果只有這麼三個狀態還好,如果狀態再多點,感覺就要眼花繚亂了!
所以通常來說,我們使用類似下面的表格來描述整個馬爾科夫過程的。
image_1c6pbpu6t1i7312man3um2j1for9.png-30.5kB
圖2
這樣是不是清楚多了!那麼如果我們省去不必要的字,僅僅用一個矩陣來表示的話,可以這樣來寫(稱爲狀態轉移矩陣):
{0.70.20.10.40.40.20.20.50.3} \left\{ \begin{matrix} 0.7 & 0.2 & 0.1 \\ 0.4 & 0.4 & 0.2 \\ 0.2 & 0.5 & 0.3 \end{matrix} \right\}

當然了,既然有一階馬爾科夫假設,當然就有二階、三階乃至N階,他們都是假設今天(t時刻)的狀態僅僅和前n天(t-1,t-2…t-n時刻)的狀態來決定。比如如果基於二階馬爾科夫假設,某個人前天和昨天分別是重感冒、輕感冒,那麼今天說不定感冒也就快好了(美好的祝願),而今天的狀態僅僅和昨天前天有關,和再往前的歷史已經沒什麼關係了。

馬爾科夫模型和籬笆網絡

那麼這個時候我們就可以把上一篇文章的籬笆網絡弄過來了。
image_1c6pcaud619a9cnfqharjt1h7a9.png-56.7kB
圖3
咱們把這幅圖簡單改一下,把A和E去掉(當然可以留下A,這個時候是所謂的”先驗”,我們先不考慮這個),然後把節點的權重修改一下,就得到了“治病救人籬笆網絡”:
image_1c6pchsjo1ns4qal1fg41mlh1m62m.png-44.9kB
圖4

“我能在河邊,畫上一整天的圖!”納特·帕格興高采烈地說道。

我們很容易發現,只要把原本的節點間的距離,換成狀態轉移矩陣中的轉移概率,我們就輕鬆地把“跑腿不累籬笆網絡”改成了“治病救人籬笆網絡”。
那你看這個時候你的老師就很容易考你了,“已知一個人2月1號重感冒,2月5號正常,告訴我他經歷了哪條狀態序列的概率最大!”(旁白:鬼知道他經歷了什麼,大概是吃了感冒藥吧!)你會發現這個問題和上一篇文章的“跑腿不累籬笆網絡”幾乎沒什麼區別,如果硬要說有區別的話,既然每一天轉移都是獨立的,那麼概率需要乘在一起(見下注),最後看誰最大,而不是“跑腿”中的簡單做加法。
image_1c6pd9qki19do1eal3gtcbj1dab13.png-42.7kB
圖5
比如他經歷了“重感冒、正常、輕感冒、重感冒、輕感冒、正常”(旁白:這個人也是體弱多病!)的概率是P=0.2×0.2×0.2×0.5×0.4=0.0016P = 0.2\times 0.2 \times 0.2 \times 0.5 \times 0.4=0.0016。我們可以算出所有路徑的概率得到最大的那個,但是我們上一篇已經學會了維特比算法,你應該學會減少了很多路徑。

注:爲什麼我們簡單把路徑上的概率乘在一起就可以呢?(一階)馬爾科夫假設事實上是這樣一個東西(豎線|表示“給定,以…爲條件”):image_1c6qsenns13e97qfd7k10bl1b6m9.png-1.9kB(來自維基百科),即在已經出現了前N個狀態的條件下得到第N+1個狀態的概率等於已經出現了第N個狀態時出現第N+1個概率(所以才說“和前天無關只和昨天有關”)。而根據條件概率,我們有P(Xn+1=,Xn=)=P(Xn+1=Xn=)P(Xn=)(0)P(X_{n+1}=輕感冒,X_{n}=重感冒)=P(X_{n+1}=輕感冒|X_n=重感冒)P(X_n=重感冒)\tag{0}這個人昨天重感冒今天輕感冒的概率(聯合概率)=在昨天重感冒的情況下今天輕感冒的概率(轉移概率)×\times這個人昨天重感冒的概率。所以如果我們已知昨天這個人重感冒,那麼P(Xn=)=1P(X_n=重感冒)=1,這個聯合概率和轉移概率就相等了。
那麼如果轉移兩天呢?比如我們已知一個人第n天重感冒,求第n+1天第n+2天分別是輕感冒、正常的概率呢?我們嘗試着把公式寫出來:
KaTeX parse error: \tag works only in display equations
P(Xn+2=Xn+1=,Xn=)×P(Xn+1=,Xn=)P(X_{n+2}=重感冒|X_{n+1}=輕感冒,X_n=重感冒)\times P(X_{n+1}=輕感冒,X_n=重感冒)
也就是說,這三天出現“重感冒、輕感冒、正常”的概率,等於在已知前兩天分別是“重感冒、輕感冒”而最後一天“正常”的概率,乘以前兩天分別“重感冒、輕感冒”的概率。而根據一階馬爾科夫假設,我們知道最後一天“正常”和第一天是什麼狀態並沒有什麼關係,僅僅和第二天的狀態有關,也就意味着我們發現等式右邊的第一項其實與第二天到第三天的轉移概率相等:
P(Xn+2=Xn+1=,Xn=)=P(Xn+2=Xn+1=)P(X_{n+2}=正常|X_{n+1}=輕感冒,X_n=重感冒)=P(X_{n+2}=正常|X_{n+1}=輕感冒)
所以(1)式就變爲了:
P(Xn+2=,Xn+1=,Xn=)=P(X_{n+2}=正常,X_{n+1}=輕感冒,X_n=重感冒)=
P(Xn+2=Xn+1=)×P(Xn+1=,Xn=)P(X_{n+2}=正常|X_{n+1}=輕感冒)\times P(X_{n+1}=輕感冒,X_n=重感冒)
這時候再看最後一項:這個我們熟,在上面(0)呢:
P(Xn+1=,Xn=)=P(Xn+1=Xn=)P(Xn=)P(X_{n+1}=輕感冒,X_{n}=重感冒)=P(X_{n+1}=輕感冒|X_n=重感冒)P(X_n=重感冒)
所以最後(1)式就變爲:
P(Xn+2=,Xn+1=,Xn=)=P(X_{n+2}=正常,X_{n+1}=輕感冒,X_n=重感冒)=
P(Xn+2=Xn+1=)P(Xn+1=Xn=)P(Xn=)P(X_{n+2}=正常|X_{n+1}=輕感冒)P(X_{n+1}=輕感冒|X_n=重感冒)P(X_n=重感冒)
也就是說,如果我們知道了第一天“重感冒”的概率P(Xn=)P(X_n=重感冒),想要得到接下來兩天“輕感冒、正常”的概率,我們只需要把相應的轉移概率乘在上面就可以了。所以說如果給定了馬爾科夫鏈的狀態序列,我們就從頭到尾把所有的轉移概率乘在一起就得到了最終這條狀態序列出現的概率。

什麼是隱馬爾科夫模型?

馬爾科夫模型介紹完了,那麼什麼是隱馬爾科夫模型?
咱們再舉個栗子,某個小鎮的醫療水平,根本測不出某個人到底是正常,還是輕感冒,還是重感冒。他們鎮的赤腳醫生只能看出來這個人到底是沒什麼症狀、咳嗽、發燒還是拉肚子(旁白:拉肚子是怎麼看出來的!)。在這個例子裏我們可以認爲這四種(活蹦亂跳、咳嗽、發燒、拉肚子)是外在表現,而正常和感冒等等被稱爲內在的狀態(事實上是狀態的“輸出”)。我們沒有辦法直接觀測內在狀態,因爲他們是隱藏的(沒有醫療器械),但是我們可以直接觀測外在表現。
假設病人的外在表現僅僅和他當天的內在狀態有關,和其他的條件無關(這叫做獨立輸出假設),關係如下表(對應的矩陣叫做發射矩陣,大概是因爲是從內在狀態發射出來的外在表現(輸出)吧):
image_1c6pe0ra54kh1i0s1rsg1jaqo821t.png-38.1kB
圖7
我們就可以通過觀察他的外在表現來推斷他的內在狀態了。比如如果一個人活蹦亂跳,常識你應該推斷他是正常的(事實上是基於極大似然,咱們先不提),但是如果告訴你這個人2月1號到5號分別是拉肚子、咳嗽、發燒、咳嗽、活蹦亂跳(這個序列叫做輸出序列),讓你寫出可能性最大的狀態序列,也就是他每一天的內在狀態分別是什麼,難度上就會大很多了。

隱馬爾科夫模型與籬笆網絡

事實上,在我們不考慮路徑的權重的情況下,整個問題和圖4的網絡沒什麼區別。每一天都有可能是三個狀態之一(當然從發射矩陣來看,如果第三天發燒,第三天不大可能是正常的,爲什麼?),而每一天的狀態遵循一階馬爾科夫假設,僅僅和前一天的狀態有關,所以整個圖的節點是沒有任何區別的。

但是概率(節點的權重)有區別。咱們舉個剛纔提到過的例子:第三天是發燒,第二天的任意一個節點指向第三天“正常”這個狀態的概率應該都是0:因爲正常這個狀態對發燒的發射概率是0。所以雖然t時刻的狀態僅僅和t-1時刻的狀態有關,但是既然給定了輸出序列,每一個時刻的輸出都給了我們更多關於當天的狀態的信息。
我們舉個更簡單的例子:

已知某人第一天輕感冒,第二天發燒,求第二天最可能的內在狀態。

表面上看是這樣:從第一天的輕感冒到第二天的三種狀態,僅僅對應着轉移概率:
圖8
圖8
但是其實可以認爲是從這樣:第一天輕感冒,經過轉移之後變爲第二天有可能的三種狀態,而每種狀態都會根據他們不同的發射概率發射出四類不同的外在表現:
image_1c6phanou19c35輕感冒4f9rk71cqs4e.png-44.6kB
圖9
退化成了這樣:因爲這個人第二天的外在表現是發燒,所以其他的外在表現就不考慮了
image_1c6pfu5vhffd1dp416k11mufvf134.png-24.5kB
圖10
不過請注意這不是真正的狀態轉移,因爲內在的狀態依然是僅僅和前一天的狀態有關,只是因爲給了一些新的附加的條件,我們可以對內在狀態的估計進行一定的“修正”。

注:這裏的0.4×0.2=0.080.4\times 0.2 =0.08事實上是聯合概率
KaTeX parse error: \tag works only in display equations
=P(Yn=Xn1=,Xn=)P(Xn1=,Xn=)=P(Y_n=發燒|X_{n-1}=輕感冒,X_n=輕感冒)P(X_{n-1}=輕感冒,X_{n}=輕感冒)
而因爲獨立輸出假設,第n天外在表現爲“發燒”,僅僅和第n天內在的狀態有關,和前一天的狀態無關:P(Yn=Xn1=,Xn=)=P(Yn=Xn=)P(Y_n=發燒|X_{n-1}=輕感冒,X_n=輕感冒)=P(Y_n=發燒|X_n=輕感冒)
所以最終(2)式就表現爲
P(Xn1=,Xn=,Yn=)P(X_{n-1}=輕感冒,X_{n}=輕感冒,Y_n=發燒)
=P(Yn=Xn=)P(Xn1=,Xn=)=P(Y_n=發燒|X_n=輕感冒)P(X_{n-1}=輕感冒,X_{n}=輕感冒)其中後一項我們上文已經討論過很多次了,通過轉移概率很容易計算,而前一項就是內在狀態到外在表現的發射概率。

所以最後權重變成了這樣:
image_1c6pg發燒8v1r7lffa1lttshthfu3h.png-17.4kB
圖11
從圖上可以看出,第二天內在狀態爲輕感冒的概率最大(0,0.08,0.06)。
細心的小夥伴可以看出,三條路徑加在一起並不等於1。的確是的,因爲這個聯合概率是要比原本的轉移概率“多了一個條件的”,需要利用貝葉斯公式進行“歸一化”的處理,但是因爲我們只需要比較哪條路徑的概率更大,所以我們簡單的把他們乘在一起也不算什麼錯誤。

注:理論上來講,我們路徑上標明的其實應該是“已知第一天輕感冒,在給定第二天發燒的條件下,求第二天內在狀態是輕感冒的概率”所以事實上是一個條件概率:
P(Xn=Yn=,Xn1=)P(X_{n}=輕感冒|Y_n=發燒,X_{n-1}=輕感冒)而不單單是聯合概率。根據貝葉斯公式我們有
P(Xn=Yn=,Xn1=)P(X_{n}=輕感冒|Y_n=發燒,X_{n-1}=輕感冒)
=P(Xn1=,Xn=,Yn=)P(Yn=,Xn1=)=\frac{P(X_{n-1}=輕感冒,X_{n}=輕感冒,Y_n=發燒)}{P(Y_n=發燒,X_{n-1}=輕感冒)}
=P(Yn=Xn1=,Xn=)P(Xn1=,Xn=)P(Yn=,Xn1=)=\frac{P(Y_n=發燒|X_{n-1}=輕感冒,X_n=輕感冒)P(X_{n-1}=輕感冒,X_{n}=輕感冒)}{P(Y_n=發燒,X_{n-1}=輕感冒)}
=P(Yn=Xn=)P(Xn1=,Xn=)P(Yn=,Xn1=)=\frac{P(Y_n=發燒|X_n=輕感冒)P(X_{n-1}=輕感冒,X_{n}=輕感冒)}{P(Y_n=發燒,X_{n-1}=輕感冒)}
而分數線下面的概率(歸一化係數),輸出僅與當天的內在狀態有關,和前一天的狀態無關
=P(Yn=Xn=)P(Xn1=,Xn=)P(Yn=)P(Xn1=)=\frac{P(Y_n=發燒|X_n=輕感冒)P(X_{n-1}=輕感冒,X_{n}=輕感冒)}{P(Y_n=發燒)P(X_{n-1}=輕感冒)}
根據全概率公式
=P(Yn=Xn=)P(Xn1=,Xn=)XnP(Yn=Xn)P(Xn1=)=\frac{P(Y_n=發燒|X_n=輕感冒)P(X_{n-1}=輕感冒,X_{n}=輕感冒)}{\sum_{X_{n}}P(Y_n=發燒|X_{n})P(X_{n-1}=輕感冒)}
看得出這個歸一化係數就是各條路徑的和,它總是個常數。所以如果我們僅僅考慮哪條路徑最大,是否歸一化其實也區別不大。
同時,對於標註問題來說,隱馬爾科夫模型求得的是一種生成模型,我們本身應該求的就是整條路徑的聯合概率,所以考慮這個問題其實沒有特別大的意義。

下篇文章:
爲什麼說標註問題可以看做隱馬爾科夫過程?

  • n-gram語言模型
  • 不是題外話的題外話:拼音輸入法
  • 標註問題
    維特比算法怎麼解決標註問題?

參考:
http://www.52nlp.cn/hmm-learn-best-practices-two-generating-patterns

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