閱讀大概需要10分鐘

跟隨小博主,每天進步一丟丟

作者:

Yang Eninala鏈接:

https://www.zhihu.com/question/20962240/answer/33438846

昨天通俗易懂的講解了什麼是HMM,沒看的點這裡。那麼今天就來看看,具體理論是什麼以及數學上怎麼計算的呢?

導讀

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

1)知道骰子有幾種(隱含狀態數量),每種骰子是什麼(轉換概率),根據擲骰子擲出的結果(可見狀態鏈),我想知道每次擲出來的都是哪種骰子(隱含狀態鏈)。

這個問題呢,在語音識別領域呢,叫做解碼問題。這個問題其實有兩種解法,會給出兩個不同的答案。每個答案都對,只不過這些答案的意義不一樣。第一種解法求最大似然狀態路徑,說通俗點呢,就是我求一串骰子序列,這串骰子序列產生觀測結果的概率最大。第二種解法呢,就不是求一組骰子序列了,而是求每次擲出的骰子分別是某種骰子的概率。比如說我看到結果後,我可以求得第一次擲骰子是D4的概率是0.5,D6的概率是0.3,D8的概率是0.2.在這裡我們主要講第一種解法。

2)還是知道骰子有幾種(隱含狀態數量),每種骰子是什麼(轉換概率),根據擲骰子擲出的結果(可見狀態鏈),我想知道擲出這個結果的概率。看似這個問題意義不大,因為你擲出來的結果很多時候都對應了一個比較大的概率。問這個問題的目的呢,其實是檢測觀察到的結果和已知的模型是否吻合。如果很多次結果都對應了比較小的概率,那麼就說明我們已知的模型很有可能是錯的,有人偷偷把我們的骰子給換了。

3)知道骰子有幾種(隱含狀態數量),不知道每種骰子是什麼(轉換概率),觀測到很多次擲骰子的結果(可見狀態鏈),我想反推出每種骰子是什麼(轉換概率)。這個問題很重要,因為這是最常見的情況。很多時候我們只有可見結果,不知道HMM模型裏的參數,我們需要從可見結果估計出這些參數,這是建模的一個必要步驟。

問題闡述完了,下面就開始說解法。(0號問題在上面沒有提,只是作為解決上述問題的一個輔助)

0.一個簡單問題

其實這個問題實用價值不高。由於對下面較難的問題有幫助,所以先在這裡提一下。

知道骰子有幾種,每種骰子是什麼,每次擲的都是什麼骰子,根據擲骰子擲出的結果,求產生這個結果的概率。

解法無非就是概率相乘:

1.看見不可見的,破解骰子序列

這裡我說的是第一種解法,解最大似然路徑問題。舉例來說,我知道我有三個骰子,六面骰,四面骰,八面骰。我也知道我擲了十次的結果(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的最大概率是

同樣的,我們可以計算第二個骰子是D4或D8時的最大概率。我們發現,第二個骰子取到D6的概率最大。而使這個概率最大時,第一個骰子為D4。所以最大概率骰子序列就是D4 D6。

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

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

同上,我們可以計算第三個骰子是D6或D8時的最大概率。我們發現,第三個骰子取到D4的概率最大。而使這個概率最大時,第二個骰子為D6,第一個骰子為D4。所以最大概率骰子序列就是D4 D6 D4。

寫到這裡,大家應該看出點規律了。既然擲骰子一二三次可以算,擲多少次都可以以此類推。我們發現,我們要求最大概率骰子序列時要做這麼幾件事情。首先,不管序列多長,要從序列長度為1算起,算序列長度為1時取到每個骰子的最大概率。然後,逐漸增加長度,每增加一次長度,重新算一遍在這個長度下最後一個位置取到每個骰子的最大概率。因為上一個長度下的取到每個骰子的最大概率都算過了,重新計算的話其實不難。當我們算到最後一位時,就知道最後一位是哪個骰子的概率最大了。然後,我們要把對應這個最大概率的序列從後往前推出來。

2.誰動了我的骰子?

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

比如說擲骰子的結果是:

要算用正常的三個骰子擲出這個結果的概率,其實就是將所有可能情況的概率進行加和計算。同樣,簡單而暴力的方法就是把窮舉所有的骰子序列,還是計算每個骰子序列對應的概率,但是這回,我們不挑最大值了,而是把所有算出來的概率相加,得到的總概率就是我們要求的結果。這個方法依然不能應用於太長的骰子序列(馬爾可夫鏈)。

我們會應用一個和前一個問題類似的解法,只不過前一個問題關心的是概率最大值,這個問題關心的是概率之和。解決這個問題的演算法叫做前向演算法(forward algorithm)。

首先,如果我們只擲一次骰子:

看到結果為1.產生這個結果的總概率可以按照如下計算,總概率為0.18:

把這個情況拓展,我們擲兩次骰子:

看到結果為1,6.產生這個結果的總概率可以按照如下計算,總概率為0.05:

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

看到結果為1,6,3.產生這個結果的總概率可以按照如下計算,總概率為0.03:

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

3.擲一串骰子出來,讓我猜猜你是誰

(這個問題以後等講了EM演算法小博主再普及O.O)

一些話

上述演算法呢,其實用到了遞歸,逆向推導,循環這些方法,我只不過用很直白的語言寫出來了。如果你們去看專業書籍呢,會發現更加嚴謹和專業的描述。畢竟,我只做了會其意,要知其形,還是要看書的。

每日託福單詞

coastline n.海岸線

flock n.羣;棉束(=floc)

vt.聚集;成羣而行

n.人名(弗洛克)

log vi.伐木

vt.切;伐木;航行

記錄;航海日誌;原木

invader n. 侵略者;侵入物

linen n. 亞麻布,亞麻線;亞麻製品

adj. 亞麻的;亞麻布制的

n.人名;(利嫩)

推薦閱讀:

查看原文 >>
相關文章