詳解隱馬爾科夫模型

隱馬爾科夫模型

摘要

本文重點講解隱馬爾科夫(HMM)模型的模型原理,以及與模型相關的三個最重要問題:求解、解碼和模型學習。python

隱馬爾科夫模型的簡單介紹

爲了方便,下文統一用HMM代替隱馬爾科夫模型。HMM其實是一種圖機率模型。之因此叫作隱馬爾科夫模型,是由於模型與普通的馬爾科夫模型不一樣的是,HMM含有隱變量空間,而且遵循馬爾科夫假設。這樣說太抽象,咱們看下圖:算法

其中\(Y_i\in Q={q_1,q_2,...,q_N}\)\(X_i \in V={v_1,v_2,...,v_M}\)。而且記觀測序列\(X = X_1,X_2,...,X_T\)網絡

隱狀態序列\(Y = Y_1,Y_2,...,Y_T\)。咱們首先介紹HMM三個重要參數,而後下面再解釋這些參數的具體物理含義。學習

\[狀態轉移矩陣: A = [a_{ij}]N\times N \\ a_{ij} =P(Y_t=q_j|Y_{t-1}=q_i),i=1,2,...,N\\ 觀測機率矩陣: B = [b_{jk}]N\times M \\ b_{jk} = P(X_t=v_k|Y_t=q_j), j = 1,2,...,N;k=1,2,...,M\\ 初始分佈: \pi=[\pi_1,\pi_2,...,\pi_N]\\ \pi_i = P(Y_0=q_i),i = 1,2,...,N \]

也就是說,狀態轉移機率決定了狀態間的單步轉移狀況,而觀測發射矩陣決定了從隱狀態到觀測狀態的轉移狀況。而初始分佈決定了模型的狀態初始分佈。爲了敘述方便,咱們記上面的參數爲\(\lambda=(A,B,\pi)\)優化

HMM有以下兩個假設,齊次性質假設和觀測獨立性假設,分別敘述以下:spa

  • 齊次馬爾科夫假設:

\[P(Y_t|X_1,...,X_{t-1},Y_1,...,Y_{t-1})=P(Y_t|Y_{t-1}) \]

也就是任什麼時候刻的隱藏狀態只與上一時刻的隱藏狀態有關,與其餘的隱藏狀態和觀測狀態無關。code

  • 觀測獨立性假設:

\[P(X_t|X_1,...,X_T,Y_1,...,Y_T)=P(X_t|Y_t) \]

即任意時刻的觀測只由其同時刻的隱狀態所決定,與其餘隱藏狀態和觀測狀態無關。blog

爲了更形象的理解這個模型,下面舉一個我以爲比較貼切的例子。遞歸

假設有兩我的分別記爲P1和P2,他們中間隔了一堵牆。其中P1被關在了牆裏面,P2在外面。這兩我的僅僅能經過一個窗子交流。兩我的分別有如下的特色:P1記性特別差,只能記住上一次說過的單詞。而且每次說話時也只受上一次說話內容所影響。而P2能夠當作一個特殊的轉錄機,他每次說的單詞都只受P1當前說的單詞所影響。而且P2有一個很長的紙帶,會把每次說的單詞記錄下來。而且假設P1和P2的詞彙表都是有限的。深度學習

  • 若是給定P2的文本片斷,咱們可否給出該文本片斷的機率(已知模型參數\(\lambda\))

  • 給定P2的文本片斷,假設咱們已經知道了P1的詞彙表,咱們可否給出P1最可能說了哪段話(已知模型參數\(\lambda\))

  • 給定大量的(P2,P1)文本對片斷,可否推測出模型參數\(\lambda\),或者僅僅給出大量的P2文本片斷,可否學出模型參數\(\lambda\)

實際上面的三個問題就對應着預測,解碼和模型學習的三個問題。而且若是P1的詞彙表是分詞標記標籤,P2的詞彙表是漢語,那麼所對應的就是分詞問題。把P1的詞彙表是命名實體標籤,P2的詞彙表是漢語,那麼所對應的問題實際上就是命名實體識別(NER)問題。

若是咱們不關心模型的具體使用,只是關心HMM是一個什麼樣的模型,那麼到這裏徹底能夠將模型說明白。可是咱們要更細緻的瞭解HMM的話(從代碼層面上)那麼仍是逐一解決上述三個重要的問題。

預測問題

所謂的預測問題,其實是求下面的序列機率:

\[p = P(X_1,X_2,...,X_T;\lambda) \]

根據全機率公式咱們有:

\[\begin{align*} p&=P(X_1,X_2,...,X_T;\lambda)\\ &=\sum_{Y}P(X_1,X_2,...,X_t,Y_1,Y_2,...,Y_t;\lambda) \end{align*} \]

其中\(Y\)是隱狀態空間的內全部組合,顯然當隱狀態空間特別大時,若是經過簡單的枚舉加和方式,面臨着指數爆炸這一難題(簡單的分析可知,上述的求和複雜度是\(O(N^T)\))。

經過上述分析可知,高效的求解序列機率的關鍵在於求解聯合機率。根據鏈式法則及HMM的假設咱們能夠獲得以下公式:

\[\begin{align*} P(X_{<=T},Y_{<=T};\lambda)& = P(X_1,X_2,...,X_T,Y_1,Y_2,...,Y_T;\lambda) \\ &=P(X_T,Y_T|X_1,...,X_{T-1},Y_1,...,Y_{T-1}) \cdot P(X_1,...,X_{T-1},Y_1,...,Y_{T-1})\\ &=P(X_T|Y_T) \cdot P(Y_T|Y_{T-1})\cdot P(X_{<T},Y_{<T}) \end{align*} \]

其中前兩步分別是觀測獨立假設和齊次轉移假設,最後一步是咱們的遞歸定義。實際上上面的公式還能進一步拆分(根據遞歸定義拆解下去便可),這裏再也不展開說明。

根據鏈式法則,咱們能夠有如下結論,\(T\)時刻的機率計算僅僅依賴於\(T-1\)時刻,又涉及到指數狀態空間枚舉,那麼實際上必定會存在着大量的重複計算,這樣咱們就會想用動態規劃來進行優化。(這樣的思考確實有些跳躍,實際上我在剛剛接觸HMM時,也對於其中反覆運用的動態規劃感到跳躍,可是等我刷過一些算法題目以後,再回頭看HMM,其中運用的動態規劃便瓜熟蒂落了。

首先咱們定義\(\alpha_{t,j}\)\(t\)時刻對應的\(Y_{t}=q_j且觀測序列爲X={X_1,...,X_t}\)的全(路徑)機率。那麼顯然根據上面的定義,咱們有:

\[P(X_{<=T};\lambda) = \sum_{j=1}^N\alpha _{T,j} \]

而且,特別的,對於\(t=1\)時,咱們引入上面的初始分佈:

\[\alpha_{1,j} = \pi_j\cdot b_{j,X_1} \]

總結上面的算法,僞代碼敘述以下:

輸入:觀測序列X,模型參數 lambda = (A,B,pi)
輸出:序列X所對應的機率p

\[\begin{align*} &初始化: \alpha_{1,j} = \pi_j\cdot b_{j,X_1}\\ &動態遞推:\alpha_{t,j} = \sum_{i=1}^N\alpha_{t-1,i}\cdot a_{i,j}\cdot b_{j,X_t}\\ &結束求和: p = \sum_{j=1}^N \alpha_{T,j} \end{align*} \]

對應的python代碼(片斷)以下:

def forward_alpha(self,label_seq):
    T = len(label_seq)
    label_seq_idx = self.label_to_idx(label_seq)
    init_label_idx = label_seq_idx
    pre_alpha = [self.pi[j] * self.b[j][init_label_idx] for j in range(self.N)]
    for t in range(1,T):
        tmp_label_idx = label_seq_idx[t]
        tmp_alpha = [self.sum_vector([pre_alpha[i]*self.a[i][j] * b[j][tmp_label_idx]])
                     for j in range(self.N)]
        pre_alpha = tmp_alpha
     return self.sum_vecotr(tmp_alpha)

解碼問題

參考文獻:

《統計學習方法》第二版,李航,隱馬爾科夫模型

《神經網絡與深度學習》,邱錫鵬,機率圖模型

相關文章
相關標籤/搜索