隱馬爾可夫模型(HMM)及Viterbi演算法
HMM簡介
對於演算法愛好者來說,隱馬爾可夫模型的大名那是如雷貫耳。那麼,這個模型到底長什麼樣?具體的原理又是什麼呢?有什麼具體的應用場景呢?本文將會解答這些疑惑。
本文將通過具體形象的例子來引入該模型,並深入探究隱馬爾可夫模型及Viterbi演算法,希望能對大家有所啟發。
隱馬爾可夫模型(HMM,hidden Markov model)是可用於標註問題的統計學模型,描述由隱藏的馬爾可夫鏈隨機生成觀測序列的過程,屬於生成模型。HMM模型在實際的生活和生產中有著廣泛的應用,包括語音識別,自然語言處理,生物資訊,模式識別等領域。
引入
某天,你的女神告訴你說,她放假三天,將要去上海遊玩,準備去歡樂谷、迪士尼和外灘(不一定三個都會去)。
她呢,會選擇在這三個地方中的某幾個逗留並決定是否購物,而且每天只待在一個地方。根據你對她的瞭解,知道她去哪個地方,僅取決於她去的上一個地方,且是否購物的概率僅取決於她去的地方。已知她去的三個地方的轉移概率表如下:
上個地方 | 歡樂谷 | 迪士尼 | 外灘 |
---|---|---|---|
歡樂谷 | 0.8 | 0.05 | 0.15 |
迪士尼 | 0.2 | 0.6 | 0.3 |
外灘 | 0.2 | 0.3 | 0.5 |
稍微對這個表格做些說明,比如第一行,前一天去了歡樂谷後,第二天還待在歡樂谷的概率為0.8,去迪士尼的概率為0.05,去外灘的概率為0.15。
她在每個地方的購物概率為:
地點 | 購物概率 |
---|---|
歡樂谷 | 0.1 |
迪士尼 | 0.8 |
外灘 | 0.3 |
在出發的時候,她跟你說去每個地方的可能性相同。後來,放假回來後,你看了她的朋友圈,發現她的購物情況如下:第一天不購物,第二三天都購物了。於是,你很好奇,她這三天都去了哪些地方。
怎麼樣,聰明的你能求解出來嗎?
HMM的模型引數
接下來,我們將會介紹隱馬爾可夫模型(HMM)。
隱馬爾可夫模型是關於時序的概率模型,描述由一個隱藏的馬爾可夫鏈隨機生成不可觀測的狀態隨機序列,再由各個狀態生成一個觀測而產生觀測隨機序列的過程。隱藏的馬爾可夫鏈隨機生成的狀態的序列,稱為狀態序列;每個狀態生成一個觀測,而由此產生的觀測的隨機序列,稱為觀測序列。序列的每一個位置又可以看作是一個時刻。
隱馬爾可夫模型由初始概率分佈、狀態轉移概率分佈以及觀測概率分佈確定。隱馬爾可夫模型的形式定義如下:
設Q是所有可能的狀態的集合,V是所有可能的觀測的集合,也就是說,Q是不可見的,而V是可見的,是我們觀測到的可能結果。
\[q=\{q_1,q_2,...,q_N\}, V=\{v_1,v_2,...,v_M\}\]
其中,N是可能的狀態數,M是可能的觀測數。
在剛才的例子中, \(Q\) 是不可見的狀態集合,應為 \(Q=\{歡樂谷,迪士尼,外灘\}\) ,而 \(V\) 是可以觀測的集合,應為 \(V=\{購物,不購物\}\) 。
I是長度為T的狀態序列,O是對應的觀測序列。
\[I=(i_1,i_2,...,i_T), O=(o_1,o_2,...,o_T)\]
在剛才的例子中, \(I\) 這個序列是我們需要求解的,即女生去了哪些地方,而 \(O\) 是你知道的序列, \(O=\{不購物,購物,購物\}\) 。
A是狀態轉移概率矩陣:
\[A=[a_{ij}]_{N\times N}\]
其中, \(a_{ij}=P(i_{t+1}=q_j|i_{t}=q_{i}), i=1,2,...,N; j=1,2,..,N\) 是在時刻t處於狀態 \(q_i\)的條件下在時刻t+1轉移到狀態
\(q_j\)
的概率。在剛才的例子中,轉移概率矩陣為:
\[ A= \begin{bmatrix} {0.8}&{0.05}&{0.15}\\ {0.6}&{0.6}&{0.2}\\ {0.2}&{0.3}&{0.5}\\ \end{bmatrix} \]
B是觀測概率矩陣:
\[B=[b_{j}(k)]_{N\times M}\]
其中, \(b_{j}(k)=P(o_t = v_{k}|i_{t}=q_{j}), k=1,2,...,M; j=1,2,...,N\) 是在時刻t處於狀態 \(q_{j}\) 的條件下生成觀測 \(v_{k}\) 的概率。在剛才的例子中:
\[ B= \begin{bmatrix} {0.1}&{0.9}\\ {0.8}&{0.2}\\ {0.3}&{0.7}\\ \end{bmatrix} \]
\(\pi\) 是初始狀態概率向量 \(\pi=(\pi_i)\) ,其中 \(\pi_i = P(i_1 = q_i), i=1,2,...,N\) 是時刻t=1處於狀態 \(q_{j}\) 的概率。在剛才的例子中, \(\pi = (\frac{1}{3}, \frac{1}{3}, \frac{1}{3}).\)
綜上,我們已經講完HMM中的基本概念。同時,我們可以知道,隱馬爾可夫模型由初始狀態概率向量 \(\pi\) ,狀態轉移概率矩陣 \(A\) 和觀測概率矩陣 \(B\) 決定。 \(\pi\) 和 \(A\) 決定狀態序列, \(B\)決定觀測序列。因此,隱馬爾可夫模型
\(\lambda\)
可用三元符號表示,即
\[\lambda = (A, B, \pi)\]
\(A,B,\pi\) 稱為HMM的三要素。
當然,隱馬爾可夫模型之所以被稱為馬爾可夫模型,是因為它使用了兩個基本的假設,其中之一為馬爾可夫假設。它們分別是:
- 齊次馬爾科夫假設,即假設隱藏的馬爾可夫鏈在任意時刻t的狀態只依賴於其前一時刻的狀態,與其他時刻的狀態及觀測無關,也與時刻t無關。
\[P(i_{i}|i_{t-1},o_{t-1},...,i_1,o_1)=P(i_{t}|i_{t-1}), t=1,2,...,T\]
- 觀測獨立性假設,即假設任意時刻的觀測只依賴於該時刻的馬爾可夫鏈的狀態,與其他觀測及狀態無關。
\[P(o_{i}|i_{T},o_{T},...,i_{t+1},o_{t+1},i_{t}, t_{t-1},o_{t-1},...,i_{1},o_{1})=P(o_{t}|i_{t}), t=1,2,...,T\]
在剛才的假設中,我們對應的兩個假設分別為:她去哪個地方,僅取決於她去的上一個地方;是否購物的概率僅取決於她去的地方。前一個條件為齊次馬爾科夫假設,後一個條件為觀測獨立性假設。
以上,我們就介紹了HMM的基本概念及假設。而HMM的三個基本問題如下:
- 概率計算問題。給定模型 \(\lambda=(A,B,\pi)\) 和觀測序列 \(O=(o_1,o_2,...,o_T)\) ,計算在模型 \(\lambda\) 下觀測序列 \(O\) 出現的概率 \(P(O|\lambda).\)
- 學習問題。已知觀測序列 \(O=(o_1,o_2,...,o_T)\) ,估計模型 \(\lambda=(A,B,\pi)\) 引數,使得在該模型下觀測序列概率 \(P(O|\lambda)\) 最大。
- 預測問題。已知模型 \(\lambda=(A,B,\pi)\) 和觀測序列 \(O=(o_1,o_2,...,o_T)\) ,求對給定觀測序列條件概率 \(P(I|O)\) 最大的狀態序列 \(I=(i_1,i_2,...,i_T).\) 即給定觀測序列,求最有可能的對應的狀態序列。
上面的例子即為HMM的第三個基本問題,也就是,給定觀測序列{不購物,購物,購物},結果最有可能的狀態序列,即遊玩的地方。
Viterbi演算法
求解HMM的第三個基本問題,會用到大名鼎鼎的維特比演算法(Viterbi Algorithm)。
維特比演算法以安德魯·維特比(Andrew Viterbi)命名,是現代數字通訊中最常用的演算法,同時也是很多自然語言處理採用的解碼演算法。可以毫不誇張地講,維特比是對我們的生活影音力最大的科學家之一,因為基於CDMA的3G行動通訊標準主要就是他和厄文·雅各布(Irwin Mark Jacobs)創辦的高通公司(Qualcomm)指定的。
維特比演算法是一個特殊但應用最廣的動態規劃(dynamic programming)演算法,利用動態規劃,可以解決任何一個圖中的最短路徑問題,同時,它也是求解HMM描述的第三個基本問題的演算法。
在維特比演算法中,需要引入兩個變數 \(\delta\) 和 \(\psi.\)定義在時刻t狀態i的所有單個路徑
\((i_1,i_2,...,i_t)\)
中概率最大值為
\[\delta_{t+1}(i) = \max_{1\leq j \leq N}[\delta_{t}(j)a_{ji}]b_{i}(o_{t+1}), i=1,2,...,N; t=1,2,...,T.\]
定義在時刻t狀態為i的所有單個路徑 \((i_1,i_2,...,i_{t-1},i)\) 中概率最大的路徑的第i-1個節點為
\[\psi_{t}(i) = arg \max_{1\leq j \leq N}[\delta_{t-1}(j)a_{ji}], i=1,2,...,N; t=1,2,...,T.\]
下面是維特比演算法在HMM的第三個基本問題的演算法:
Python程式碼實現
下面,對於剛才給出的例子,我們將使用Python,來寫程式碼實現Viterbi演算法,同時求解剛才的問題。
# -*- coding: utf-8 -*- # HMM.py # Using Vertibi algorithm import numpy as np def Viterbi(A, B, PI, V, Q, obs): N = len(Q) T = len(obs) delta = np.array([[0] * N] * T, dtype=np.float64) phi = np.array([[0] * N] * T, dtype=np.int64) # 初始化 for i in range(N): delta[0, i] = PI[i]*B[i][V.index(obs[0])] phi[0, i] = 0 # 遞迴計算 for i in range(1, T): for j in range(N): tmp = [delta[i-1, k]*A[k][j] for k in range(N)] delta[i,j] = max(tmp) * B[j][V.index(obs[i])] phi[i,j] = tmp.index(max(tmp)) # 最終的概率及節點 P = max(delta[T-1, :]) I = int(np.argmax(delta[T-1, :])) # 最優路徑path path = [I] for i in reversed(range(1, T)): end = path[-1] path.append(phi[i, end]) hidden_states = [Q[i] for i in reversed(path)] return P, hidden_states def main(): # 狀態集合 Q = ('歡樂谷', '迪士尼', '外灘') # 觀測集合 V = ['購物', '不購物'] # 轉移概率: Q -> Q A = [[0.8, 0.05, 0.15], [0.2, 0.6, 0.2], [0.2, 0.3, 0.5] ] # 發射概率, Q -> V B = [[0.1, 0.9], [0.8, 0.2], [0.3, 0.7] ] # 初始概率 PI = [1/3, 1/3, 1/3] # 觀測序列 obs = ['不購物', '購物', '購物'] P, hidden_states = Viterbi(A,B,PI,V,Q,obs) print('最大的概率為: %.5f.'%P) print('隱藏序列為:%s.'%hidden_states) main()
輸出結果如下:
最大的概率為: 0.02688. 隱藏序列為:['外灘', '迪士尼', '迪士尼'].
現在,你有很大的把握可以確定,你的女神去了外灘和迪士尼。
注意:本人現已開通微信公眾號: Python爬蟲與演算法(微訊號為:easy_web_scrape), 歡迎大家關注哦~~
參考文獻
- 一文搞懂HMM(隱馬爾可夫模型): ofollow,noindex" target="_blank">https://www.cnblogs.com/skyme/p/4651331.html
- 李航《統計學習方法》 清華大學出版社
- HMM與分詞、詞性標註、命名實體識別: http://www.hankcs.com/nlp/hmm-and-segmentation-tagging-named-entity-recognition.html
- Hidden Markov Models 1: http://docplayer.net/21306742-Hidden-markov-models-1.html
- 吳軍 《數學之美》 人民郵電出版社