Machine Learning系列--維特比算法

維特比算法(Viterbi algorithm)是在一個用途很是廣的算法,本科學通訊的時候已經聽過這個算法,最近在看 HMM(Hidden Markov model) 的時候也看到了這個算法。因而決定研究一下這個算法的原理及其具體實現,若是瞭解動態規劃的同窗應該很容易瞭解維特比算法,由於維特比算法的核心就是動態規劃。python

對於 HMM 而言,其中一個重要的任務就是要找出最有可能產生其觀測序列的隱含序列。通常來講,HMM問題可由下面五個元素描述:算法

  1. 觀測序列(observations):實際觀測到的現象序列
  2. 隱含狀態(states):全部的可能的隱含狀態
  3. 初始機率(start_probability):每一個隱含狀態的初始機率
  4. 轉移機率(transition_probability):從一個隱含狀態轉移到另外一個隱含狀態的機率
  5. 發射機率(emission_probability):某種隱含狀態產生某種觀測現象的機率

下面以維基百科上的具體例子來講明:網絡

想象一個鄉村診所。村民有着很是理想化的特性,要麼健康要麼發燒。他們只有問診所的醫生的才能知道是否發燒。 聰明的醫生經過詢問病人的感受診斷他們是否發燒。村民只回答他們感受正常、頭暈或冷。
假設一個病人天天來到診所並告訴醫生他的感受。醫生相信病人的健康情況如同一個離散馬爾可夫鏈。病人的狀態有兩種「健康」和「發燒」,但醫生不能直接觀察到,這意味着狀態對他是「隱含」的。天天病人會告訴醫生本身有如下幾種由他的健康狀態決定的感受的一種:正常、冷或頭暈。這些是觀察結果。 整個系統爲一個隱馬爾可夫模型(HMM)。
醫生知道村民的整體健康情況,還知道發燒和沒發燒的病人一般會抱怨什麼症狀。 換句話說,醫生知道隱馬爾可夫模型的參數。則這些上面提到的五個元素表示以下:編碼

states = ('Healthy', 'Fever')
 
observations = ('normal', 'cold', 'dizzy')
 
start_probability = {'Healthy': 0.6, 'Fever': 0.4}
 
transition_probability = {
   'Healthy' : {'Healthy': 0.7, 'Fever': 0.3},
   'Fever' : {'Healthy': 0.4, 'Fever': 0.6},
   }
 
emission_probability = {
   'Healthy' : {'normal': 0.5, 'cold': 0.4, 'dizzy': 0.1},
   'Fever' : {'normal': 0.1, 'cold': 0.3, 'dizzy': 0.6},
   }

 

其對應的狀態轉移圖以下所示:spa

如今的問題是假設病人連續三天看醫生,醫生髮現第一天他感受正常,次日感受冷,第三天感受頭暈。 因而醫生產生了一個問題:怎樣的健康狀態序列最可以解釋這些觀察結果。維特比算法解答了這個問題。3d

首先直觀地看這個問題,在HMM中,一個觀測現象後面的對應的各個狀態都有一個機率值,咱們只須要選擇機率值最大的那個狀態便可,可是這個機率值是跟前面一個狀態有關的(馬爾科夫假設),所以不能獨立考慮每一個觀測現象。code

爲了從時間複雜度方面進行比較,如今將問題通常化:假設觀測序列的長度爲 m,隱含狀態個數爲 n。則有下面的隱含狀態轉移圖(下圖爲了便於表示,將只畫出n = 3 的圖)。orm

假如採用窮舉法,窮舉出全部可能的狀態序列再比較他們的機率值,則時間複雜度是$O(n^m)$, 顯然這樣的時間複雜度是沒法接受的,而經過維特比算法能把時間複雜度降到$O(m*n^2)$。xml

 從動態規劃的問題去考慮這個問題,根據上圖的定義,記last_state爲上一個觀測現象對應的各個隱含狀態的機率,curr_state爲如今的觀測現象對應的各個隱含狀態的機率。則求解curr_state實際上只依賴於last_state。而他們的依賴關係可經過下面的python代碼表示出來:blog

for cs in states:
    curr_state[cs] = max(last_state[ls] * 
                         transition_probability[ls][cs] *             
                         emission_probability[cs][observation] 
                         for ls in states)

計算過程利用了轉移機率transition_probability和發射機率emission_probability,選出那個最有可能產生當前狀態cs的上一狀態ls

除了上面的計算,同時要爲每一個隱含狀態維護一個路徑pathpath[s]表示到達狀態s前的最優狀態序列。經過前面的計算選出那個最有可能產生當前狀態cs的上一狀態ls後,往path[cs]中插入ls。則依照這種方法遍歷完全部的觀測序列後,只須要選擇curr_state中機率值最大的那個state做爲最終的隱含狀態,同時從path中取出path[state]做爲該最終隱含狀態前面的狀態序列。

從上面的分析可知,觀測序列只須要遍歷一遍,時間複雜度爲$O(m)$,而每次要計算當前各個狀態最可能的前一狀態,時間複雜度爲$O(n^2)$,所以整體的時間複雜度爲$O(m*n^2)$.

假如在NLP中應用HMM,則將詞序列看作是觀測到的現象,而詞性、標籤等信息看作是隱含狀態,那麼就能夠經過維特比算法求解其隱含狀態序列,而這也是HMM在分詞,詞性標註,命名實體識別中的應用。其關鍵每每是找出上面提到的初始機率(start_probability)、轉移機率(transition_probability)、發射機率(emission_probability)。

而在通訊領域中,假如將收到的編碼信息看做是觀測序列,對應的解碼信息爲隱含狀態,那麼經過維特比算法也可以找出機率最大的解碼信息。

須要注意的是維特比算法適用於多步驟多選擇的最優問題,相似於下面的網絡,《數學之美》中將其叫作「籬笆網絡(Lattice)」。每一步都有多個選擇,而且保留了前面一步各個選擇的最優解,經過回溯的方法找到最優選擇路徑。

 

這裏要強調的是viterbi算法能夠用於解決HMM問題,可是也能夠用於解決其餘符合上面描述的問題。

 

轉自博文:http://wulc.me/2017/03/02/維特比算法/

相關文章
相關標籤/搜索