圖解隱馬爾可夫模型(HMM)

寫在前面

最近在寫論文過程當中,研究了一些關於機率統計的算法,也從網上收集了很多資料,在此整理一下與各位朋友分享。html

隱馬爾可夫模型,簡稱HMM(Hidden Markov Model), 是一種基於機率的統計分析模型,用來描述一個系統隱性狀態的轉移和隱性狀態的表現機率。算法

本文適用於對HMM感興趣的入門讀者,爲了讓文章更加通俗易懂,我會多闡述數學思想,儘量的撇開公式,撇開推導。結合實際例子,爭取作到雅俗共賞,童叟無欺。沒有公式,就沒有傷害。安全

建議看一下吳軍博士的《數學之美》,裏面有簡單的說明。而後看下HMM的三個計算問題和對應的解答,你會發現基本就是動態規劃的思想。網絡

本文非徹底原創,部份內容來自互聯網,本身在此基礎上加入了我的的理解,若有侵權還請告知! 機器學習

從擲骰子提及

假設我手裏有三個不一樣的骰子:學習

  • 第一個骰子是咱們日常見的骰子(稱這個骰子爲D6),6個面,每一個面(1,2,3,4,5,6)出現的機率是1/6。
  • 第二個骰子是個四面體(稱這個骰子爲D4),每一個面(1,2,3,4)出現的機率是1/4。
  • 第三個骰子有八個面(稱這個骰子爲D8),每一個面(1,2,3,4,5,6,7,8)出現的機率是1/8。

 

如今開始擲骰子:lua

  1. 挑骰子:從三個骰子裏挑一個(挑到每個骰子的機率都是1/3)
  2. 擲骰子:將獲得一個數字(1,2,3,4,5,6,7,8中的一個)

不停的重複上述過程,咱們會獲得一串數字,例如咱們可能獲得這麼一串數字(擲骰子10次):3d

1 6 3 5 2 7 3 5 2 4視頻

咱們稱這串數字叫作可見狀態鏈。htm

在隱馬爾可夫模型中,不只僅有這麼一串可見狀態鏈,還有一串隱含狀態鏈。在這個例子裏,這串隱含狀態鏈就是你用的骰子的序列。好比,隱含狀態鏈有多是:

D6 D8 D8 D6 D4 D8 D6 D6 D4 D8

通常來講,HMM中說到的馬爾可夫鏈實際上是指隱含狀態鏈,由於隱含狀態(骰子)之間存在轉換機率(transition probability)。

在這個例子裏,D6的下一個狀態是D4,D6,D8的機率都是1/3。D4,D8的下一個狀態是D4,D6,D8的轉換機率也都同樣是1/3。咱們其實能夠隨意設定轉換機率的。好比,咱們能夠這樣定義:D6後面不能接D4,D6後面是D6的機率是0.9,是D8的機率是0.1。這樣就是一個新的HMM。

一樣的,儘管可見狀態之間沒有轉換機率,可是隱含狀態和可見狀態之間有一個機率叫作輸出機率(emission probability)。就咱們的例子來講,六面骰(D6)產生1的輸出機率是1/6。產生2,3,4,5,6的機率也都是1/6。咱們一樣能夠對輸出機率進行其餘定義。好比,我有一個被賭場動過手腳的六面骰子,擲出來是1的機率更大,是1/2,擲出來是2,3,4,5,6的機率是1/10。

其實對於HMM來講,若是提早知道全部隱含狀態之間的轉換機率和全部隱含狀態到全部可見狀態之間的輸出機率,作模擬是至關容易的。但在實際運用中,每每會缺失一部分信息:有時候你知道骰子有幾種,每種骰子是什麼,可是不知道擲出來的骰子序列;有時候你知道骰子序列,剩下的什麼都不知道。如何應用算法去估計這些缺失的信息,就成了一個頗有研究價值的問題。這些算法我會在下面詳細講。

和HMM模型相關的算法主要分爲三類,分別解決三種問題:

  1. 知道骰子有幾種(隱含狀態數量),每種骰子是什麼(轉換機率),根據擲骰子擲出的結果(可見狀態鏈),我想知道每次擲出來的都是哪一種骰子(隱含狀態鏈)。這個問題,在語音識別領域,叫作解碼問題。這個問題其實有兩種解法,會給出兩個不一樣的答案。每一個答案都對,只不過這些答案的意義不同。第一種解法求最大似然狀態路徑,說通俗點,就是我求一串骰子序列,這串骰子序列產生觀測結果的機率最大。第二種解法,就不是求骰子序列了,而是求每次擲出的骰子分別是某種骰子的機率。好比說我看到結果後,我能夠求得第一次擲骰子是D4的機率是0.5,D6的機率是0.3,D8的機率是0.2。第一種解法我會在下面說到,可是第二種解法我就不寫在這裏了。
  2. 仍是知道骰子有幾種(隱含狀態數量),每種骰子是什麼(轉換機率),根據擲骰子擲出的結果(可見狀態鏈),我想知道擲出這個結果的機率。看似這個問題意義不大,由於你擲出來的結果不少時候都對應了一個比較大的機率。問這個問題的目的,實際上是檢測觀察到的結果和已知的模型是否吻合。若是不少次結果都對應了比較小的機率,那麼就說明咱們已知的模型頗有多是錯的,有人偷偷把咱們的骰子給換了。
  3. 知道骰子有幾種(隱含狀態數量),不知道每種骰子是什麼(轉換機率),觀測到不少次擲骰子的結果(可見狀態鏈),我想反推出每種骰子是什麼(轉換機率)。這個問題很重要,由於這是最多見的狀況。不少時候咱們只有可見結果,不知道HMM模型裏的參數,咱們須要從可見結果估計出這些參數,這是建模的一個必要步驟。

問題闡述完了,下面就開始說解法。

一個簡單問題

其實這個問題實用價值不高。因爲對下面較難的問題有幫助,因此先在這裏提一下。

知道骰子有幾種,每種骰子是什麼,每次擲的都是什麼骰子,給出一串數字序列,求產生這個序列的機率。

解法無非就是機率相乘:

破解骰子序列

這裏我說的是第一種解法,解最大似然路徑問題。

舉例來講,我知道我有三個骰子,六面骰,四面骰,八面骰。我也知道我擲了十次的結果(1 6 3 5 2 7 3 5 2 4),我不知道每次用了哪一種骰子,我想知道最有可能的骰子序列。

其實最簡單而暴力的方法就是窮舉全部可能的骰子序列,而後依照第零個問題的解法把每一個序列對應的機率算出來。而後咱們從裏面把對應最大機率的序列挑出來就好了。若是馬爾可夫鏈不長,固然可行。若是長的話,窮舉的數量太大,就很難完成了。

另一種頗有名的算法叫作Viterbi algorithm. 要理解這個算法,咱們先看幾個簡單的列子。

首先,若是咱們只擲一次骰子:


看到結果爲1,對應的最大機率骰子序列就是D4,由於D4產生1的機率是1/4,高於1/6和1/8.

把這個狀況拓展,咱們擲兩次骰子:


結果爲1,6,這時問題變得複雜起來,咱們要計算三個值,分別是第二個骰子是D6,D4,D8的最大機率。顯然,要取到最大機率,第一個骰子必須爲D4。這時,第二個骰子取到D6的最大機率是

P2(D6)=P(D4)*P(D4\rightarrow 1)*P(D4\rightarrow D6)*P(D6\rightarrow 6)
=\frac{1}{3} *\frac{1}{4} *\frac{1}{3} *\frac{1}{6}

一樣的,咱們能夠計算第二個骰子是D4或D8時的最大機率。咱們發現,第二個骰子取到D6的機率最大。而使這個機率最大時,第一個骰子爲D4。因此最大機率骰子序列就是D4 D6。

繼續拓展,咱們擲三次骰子:

 

一樣,咱們計算第三個骰子分別是D6,D4,D8的最大機率。咱們再次發現,要取到最大機率,第二個骰子必須爲D6。這時,第三個骰子取到D4的最大機率是

同上,咱們能夠計算第三個骰子是D6或D8時的最大機率。咱們發現,第三個骰子取到D4的機率最大。而使這個機率最大時,第二個骰子爲D6,第一個骰子爲D4。因此最大機率骰子序列就是D4 D6 D4。

寫到這裏,你們應該看出點規律了,這其實就是機率DP問題(Dynamic Programming with Probability)。既然擲骰子一二三次能夠算,擲多少次均可以以此類推。咱們發現,咱們要求最大機率骰子序列時要作這麼幾件事情:

  • 首先,無論序列多長,要從序列長度爲1算起,算序列長度爲1時取到每一個骰子的最大機率。
  • 而後,逐漸增長長度,每增長一次長度,從新算一遍在這個長度下最後一個位置取到每一個骰子的最大機率。由於上一個長度下的取到每一個骰子的最大機率都算過了,從新計算的話其實不難。當咱們算到最後一位時,就知道最後一位是哪一個骰子的機率最大了。
  • 最後,咱們把對應這個最大機率的序列從後往前推出來。

誰動了個人骰子

若是你懷疑本身的六面骰被賭場動過手腳了,有可能被換成另外一種六面骰,這種六面骰擲出來是1的機率更大,是1/2,擲出來是2,3,4,5,6的機率是1/10。怎麼辦?答案很簡單,算一算正常的三個骰子擲出一段序列的機率,再算一算不正常的六面骰和另外兩個正常骰子擲出這段序列的機率。若是前者比後者小,你就要當心了。好比說擲骰子的結果是:

 

要算用正常的三個骰子擲出這個結果的機率,其實就是將全部可能狀況的機率進行加和計算。一樣,簡單而暴力的方法就是把窮舉全部的骰子序列,仍是計算每一個骰子序列對應的機率,可是這回,咱們不挑最大值了,而是把全部算出來的機率相加,獲得的總機率就是咱們要求的結果。這個方法依然不能應用於太長的骰子序列(馬爾可夫鏈)。咱們會應用一個和前一個問題相似的解法,只不過前一個問題關心的是機率最大值,這個問題關心的是機率之和。解決這個問題的算法叫作前向算法(forward algorithm)。首先,若是咱們只擲一次骰子:

 

看到結果爲1.產生這個結果的總機率能夠按照以下計算,總機率爲0.18:

把這個狀況拓展,咱們擲兩次骰子:

看到結果爲1,6.產生這個結果的總機率能夠按照以下計算,總機率爲0.05:

繼續拓展,咱們擲三次骰子:

看到結果爲1,6,3.產生這個結果的總機率能夠按照以下計算,總機率爲0.03:

 

一樣的,咱們一步一步的算,有多長算多長,再長的馬爾可夫鏈總能算出來的。用一樣的方法,也能夠算出不正常的六面骰和另外兩個正常骰子擲出這段序列的機率,而後咱們比較一下這兩個機率大小,就能知道你的骰子是否是被人換了。

HMM 的應用

以上例子是用HMM對擲骰子進行建模與分析。固然還有不少HMM經典的應用,能根據不一樣的應用需求,對問題進行建模。

可是使用HMM進行建模的問題,必須知足如下條件:

  1. 隱性狀態的轉移必須知足馬爾可夫性(狀態轉移的馬爾可夫性:一個狀態只與前一個狀態有關)
  2. 隱性狀態必須可以大概被估計

在知足條件的狀況下,肯定問題中的隱性狀態是什麼,隱性狀態的表現可能又有哪些。

HMM適用的問題:真正的狀態(隱態)難以被估計,而狀態與狀態之間又存在聯繫。

語音識別

語音識別問題就是將一段語音信號轉換爲文字序列的過程。

在個問題裏面,隱性狀態就是: 語音信號對應的文字序列。而顯性狀態就是: 語音信號。

MM模型的學習(Learning): 語音識別的模型學習和上文中經過觀察骰子序列創建起一個最有可能的模型不一樣。

語音識別的HMM模型學習有三個步驟:

  1. 統計文字的發音機率,創建隱性表現機率矩陣
  2. 統計字詞之間的轉換機率(不須要考慮語音,直接統計字詞之間的轉移機率便可)
  3. 語音模型的估計(Evaluation): 計算"是十四」,"四十四"等等的機率,比較得出最有可能出現的文字序列。

 因而可知,其原理和上面的破解骰子序列是同樣的。

手寫識別

手寫識別(HandWriting Recognition)是指將在手寫設備上書寫時產生的有序軌跡信息化轉化爲文字的過程。

原理和語音差很少,只不過手寫識別的過程是將字的圖像當成了顯性序列。

中文分詞

總所周知,在漢語中,詞與詞之間不存在分隔符,詞自己也缺少明顯的形態標記(英文中,詞與詞之間用空格分隔,這是自然的分詞標記)。所以,中文信息處理的特有問題就是如何將漢語的字串分割爲合理的詞語序。

 

例如,英文句子:you should go to kindergarten now. 自然的空格已然將詞分好,只需去除其中的介詞「to」便可;而「你如今應該去幼兒園了」這個句子表達一樣的意思卻沒有明顯的分隔符,中文分詞的目的是獲得「你/如今/應該/去/幼兒園/了」。那麼如何進行分詞呢?

主流的方法有三種:

  • 第1類是基於語言學知識的規則方法,如:各類形態的最大匹配、最少切分方法。
  • 第2類是基於大規模語料庫的機器學習方法,這是目前應用比較普遍、效果較好的解決方案。用到的統計模型有N元語言模型、信道—噪聲模型、最大指望、HMM等。
  • 第3類也是實際的分詞系統中用到的,即規則與統計等多類方法的綜合。

更多中文分詞相關介紹,參考個人另外一篇博客:一週亂談 - 中文分詞

拼音輸入法

拼音輸入法,是一個估測拼音字母對應想要輸入的文字(隱性狀態)的過程(好比, ‘pingyin’ -> 拼音)。

很明顯,拼音輸入法的觀察序列就是用戶的輸入拼音,好比」wo shi zhong guo ren」,咱們要推測出用戶想要輸入的是「我 是 中 國 人」,這是個很典型的隱馬爾科夫模型。

如上圖所示,咱們根據給定的觀察對象O,得到一個機率最大的序列S*。咱們所知道的數據有:

  • 全部觀察對象的值
  • 隱藏序列的馬爾科夫模型機率,這是經過統計得到的
  • 隱藏狀態到觀察狀態的機率,好比 「晴天」(隱藏狀態) 到 「出去玩」(觀察狀態)的機率

咱們要求的是S*各個狀態的連續機率最大的那個序列,和上面同理。

有關隱馬爾可夫模型的教學視頻,請參看coursera課程:Lecture 17 - 隱馬爾可夫模型

結語

隱馬爾可夫模型是可用於標註問題的統計學習的模型,描述由隱藏的馬爾可夫鏈隨機生成觀測序列的過程,屬於生成模型。

本文以一個例子爲主線,用理論結合實際的方法講解了HMM的基本原理和三個基本問題,以及三個問題的求解方法。最後,綜述了一些HMM在人類的行爲分析、網絡安全和信息抽取中的最新應用。

參考文獻

1. 數學之美 - 吳軍 - 隱馬爾科夫模型

2. 統計學習方法 - 李航 - 隱馬爾科夫模型

3. HMM學習最佳範例一:介紹 - 52nlp

4. HMM學習最佳範例二:生成模式 - 52nlp

5. POS - Stanford NLP

相關文章
相關標籤/搜索