HMM理論及代碼實現

Ref:

  1. https://web.stanford.edu/~jurafsky/slp3/A.pdf
  2. https://en.wikipedia.org/wiki/Hidden_Markov_model

文中的例子和符號基本來自Ref[1]

基本概念:

Markov chain:隨機變量組成的序列,下一個序列狀態僅和當前狀態有關,而和過去的狀態無關。好比預測明天的天氣,僅考慮今天的氣候,而不用管昨天或以前的天氣情況。

Markov chain有助于計算可觀測序列狀態的概率,但很多時候,我們還關心那些無法直接觀測到的狀態序列。好比文本序列的pos tags,我們閱讀文字,然后再判斷這個文字是動詞,名詞還是其他,這些不可直接觀測的狀態,又稱為隱藏狀態(hidden state),HMM就是來幫助處理這種情況的。

Hidden Markov Model:有兩種隨機狀態序列,一種狀態可觀測,另一種狀態不可直接觀測,這個不可觀測的序列(下文用隱藏序列)服從Markov chain,且觀測序列依賴隱藏序列,HMM希望通過這些觀測序列來學習隱藏序列。

數學表達:

Y:可觀測狀態序列,下文的O
X:隱藏狀態序列,hidden state,下文的Q
假設:Y依賴X,在每個時間t, 僅依賴X_t ,和X_{<t},Y_{<t} 無關,HMM的狀態之間的時序變化如下圖:

wiki

概念

  1. Markov assumption
    對隱藏序列(對應上圖的X)Q = \lbrace{q_1,q_2,...,q_N \rbrace},有P(q_i=a|q_1,q_2,...,q_{i-1}) = P(q_i=a|q_{i-1})
  2. Transition probability matrix
    狀態轉移矩陣,A = \lbrace{a_{11}a_{12}...a_{n1}...a_{nn} \rbrace}
    a_{ij} 表示從隱藏狀態i轉移到隱藏狀態j的概率,\sum_j a_{ij} =1
  3. Initial probability distribution
    初始概率分布,\pi = \lbrace{\pi_1,\pi_2,...,\pi_N \rbrace},表示隱藏序列從哪個狀態開始;
    \sum_i \pi_{i} =1,注意,有些狀態可能為0;
  4. 觀測序列T
    O = \lbrace{ o_1, o_2,...o_T \rbrace}
  5. Emission probability
    發射概率,B = b_i(o_t) ,表示隱藏狀態為i時,對應的觀測狀態為t的概率。

HMM:

2個假設

  1. Markov assumption: 隱藏狀態i只和上一個隱藏狀態i-1有關,P(q_i=a|q_1,q_2,...,q_{i-1}) = P(q_i=a|q_{i-1})
  2. 觀測狀態僅依賴于當時的隱層狀態,而和之前的觀測狀態or之前的隱層狀態無關: P(o_i|q_1,...q_i,...q_T,o_1,...,o_i,...,o_T) = P(o_i|q_i)

HMM可以看成3個問題

  1. Likelihood:已知觀測序列O,參數 \lambda=(\pi,A,B) ,計算likelihood P(O|\lambda);
  2. Decoding:已知觀測序列O,參數 \lambda=(\pi,A,B) ,找到最佳的隱藏序列Q,用Viterbi;
  3. Learning:已知觀測序列O,一系列的HMM狀態,學習參數 \lambda=(\pi,A,B),用EM。

案例分析:吃冰淇淋與氣溫的關系,如下圖:

1. Likelihood computation:Forward algorithm

動態規劃算法,計算觀測的概率。
即,知道了一條觀測序列,所有可能的隱藏序列,觀測和隱藏序列之間的關系(轉移概率A和發射概率B),初始隱藏序列的概率分布(π),求這個觀測序列的likelihood。

輸入:觀測序列O,模型參數 \lambda=(\pi,A,B)
輸出: P(O|Q) = \Pi_i P(o_i|q_i)

案例分析

https://web.stanford.edu/~jurafsky/slp3/A.pdf
  1. 2種氣候狀態(不可觀測):HOT,COLD,對應的初始概率為0.8,0.2,即熱天的概率為0.8,氣溫變冷的概率為0.2,從HOT轉到HOT的概率為0.6,HOT轉到COLD的概率為0.4,反之0.5,COLD轉到COLD的概率為0.5;
  2. 觀測狀態:Jason可能吃的冰淇淋數量,O = {1,2,3}。
  1. 觀測序列:吃了冰淇淋數量為[3,1,3];
  2. 氣候序列:[hot,hot,cold];
  3. 冰淇淋數量O和氣溫高低的關系:p(3|hot) = 0.4p(1|hot) = 0.2 ,p(3|cold) = 0.1
    https://web.stanford.edu/~jurafsky/slp3/A.pdf
  • 計算條件概率 or likelihood
    P(O|Q) = P(3,1,3|hot,hot,cold) = p(3|hot)p(1|hot)p(3|cold) = 0.4*0.2*0.1 = 0.008

  • 但是實際上,我們并不知道真正的氣候序列是怎樣的,因此還要考慮實際的氣候序列(即隱藏序列):
    P(Q) = p(hot|start)*p(hot|hot)*p(cold|hot) = 0.8*0.6*0.4 = 0.192

  • 因此,給定一條觀測序列一條隱藏序列聯合概率為:
    P(O,Q) = P(O|Q)P(Q) = \Pi_iP(o_i|q_i) × \Pi_iP(q_i|q_{i-1}) = 0.008*0.192 = 0.001536

  • 而所有可能的隱藏序列對應的所有觀測序列的總概率為:P(O) = \sum_QP(O,Q) = \sum_QP(O|Q)P(Q)

如果有N個隱藏狀態和T個觀測序列,則可能有N^T個可能的隱藏序列。
N^T 太大,因此無法分別計算每一個隱藏狀態(N)下的觀測(T)的likelihood。因此,使用Forward algorithm。

算法

輸入:觀測狀態序列長度為T,隱藏狀態N

設,previous forward path probability:\alpha_{t-1}(i)
則,在第t個狀態下,隱藏狀態為j的所有可能路徑概率和:
\alpha_t(j) =\sum_i^N\alpha_{t-1}(i)a_{ij}b_j(o_t)

步驟:

  1. 初始化:\alpha_1(j) = \pi_jb_j(o_1), given 1<=j<=N
  2. 迭代:\alpha_t(j) = \sum_i^N \alpha_{t-1}a_{ij}b_j(o_t), given 1<=j<=N,1<=t<=T
  3. 終止:P(O|\lambda) = \sum_i^N\alpha_T(i)

案例分析

https://web.stanford.edu/~jurafsky/slp3/A.pdf

如上圖,\alpha_2(2),在時間t為2時,處于狀態2,產生的觀測序列為[3,1],有兩條路徑通向這個點,分別為:
\alpha_1(1) ×P(H|C)×P(1|H) = 0.02*0.5*0.2 = 0.002
\alpha_1(2) ×P(H|H)×P(1|H) = 0.32*0.6*0.2 = 0.0384
\alpha_2(2) = \alpha_1(1)+\alpha_1(2)=0.0404

代碼

def forward(obs,states, start_p, emission_p,trans_p):
    """
    obs = ('ice_3','ice_1','ice_3')
    states = ('HOT','COLD')
    start_p = {'HOT':0.8,'COLD':0.2}
    emission_p = {'HOT':{'ice_1':0.2,'ice_2':0.4,'ice_3':0.4},
                    'COLD':{'ice_1':0.5,'ice_2':0.4,'ice_3':0.1}}
    trans_p = {'HOT': {'HOT':0.6,'COLD':0.4},
                'COLD': {'HOT':0.5,'COLD':0.5}}

    """
    fwd = [{}]
    for state in states:
        fwd[0][state] = start_p[state] * emission_p[state][obs[0]]
    
    for t in range(1,len(obs)):
        fwd.append({})
        for state in states:
            fwd[t][state] = sum((fwd[t-1][s]*trans_p[s][state]*emission_p[state][obs[t]]) for s in states)
    prob = sum(fwd[len(obs)-1][s] for s in states)
    return prob 

2. Decoding:Viterbi algorithm

給定觀測序列O,參數 \lambda=(\pi,A,B) ,找到最佳的隱藏狀態序列Q,也就是找到最大的likelihood。一般來說,可以通過forward algorithm來計算某個隱藏狀態序列下的觀測序列的likelihood,然后再選擇likelihood最大的那條隱藏序列。

簡而言之,就是每個時間步下,都選擇最大的likelihood。

但是,正如之前提到的,序列狀態多種多樣,因此使用Viterbi algorithm。同前向算法,它也是個動態規劃問題。

算法

輸入:觀測狀態序列長度為T,隱藏狀態N,構造一條viterbi路徑概率矩陣[N,T]
輸出:最佳路徑,路徑概率

設,上一個時間步的Viterbi路徑概率previous Viterbi path probability:
v_{t-1}(i)
則,時間步t時,隱藏狀態為j的Viterbi值為:
v_t(j) =max_{q_1,...,q_{t-1}} p(o_1,o_2,...,o_t,q_t = j|\lambda ) = max_i^N v_{t-1}(i)a_{ij}b_j(o_t)

步驟:

  1. 初始化:
    1<=j<=N: v_1(j) = \pi_jb_j(o_1),b_1(j) = 0
  2. 迭代:
    1<=j<=N,1<=t<=T :
    v_t(j) = max_i \ v_{t-1}a_{ij}b_j(o_t)
    b_t(j) = argmax_i \ v_{t-1}a_{ij}b_j(o_t)
  3. 終止:
    best score: P* = \max_iv_T(i)
    start of backtrace: q_T* = argmax_i \ v_T(i)

案例分析

https://web.stanford.edu/~jurafsky/slp3/A.pdf

如上圖,對觀測序列[3,1,3],可能存在的隱藏序列路徑為:
START->H->H->H, START->H->C>H, START->H->C>C, START->H->H>C
SATRT ->C->C>C, START->C->H>C, START->C->H>J, START->C->C>H
Step t=1 時,觀測狀態為3,最大概率為0.32,最可能的路徑為START->H;
Step t=2 時,觀測狀態為1,最大概率為0.064,最可能的路徑為START->H->C;
Step t=3 時,觀測狀態為3,最大概率為0.0128,最可能的路徑為START->H->C>H。
因此,viterbi的輸出為:0.0128,START->H->C>H。
同時,viterbi還可以追溯,即H->C->H->START,如圖上藍色箭頭。

代碼

def viterbi(obs, states, start_p, emission_p, trans_p):
    V = [{}]
    path = {}
    # 建立t0時刻個狀態概率
    for state in states:
        V[0][state] = start_p[state] * emission_p[state][obs[0]]
        path[state] = [state]

    # 沿著時間1, 2..t進行計算
    for t in range(1, len(obs)):
        V.append({})
        newpath = {}

        # 根據t-1時刻狀態概率,觀測概率矩陣和轉移概率矩陣計算t時刻最大概率轉態 記錄路徑
        for state in states:
            # 看前一個狀態中, 那個狀態轉移到當前狀態并且當前狀態噴射出當前觀測值的概率大, 誰大誰就做前一個狀態
            (prob, next_state) = max([(V[t-1][s] * trans_p[s][state] * emission_p[state][obs[t]], s) for s in states])
            V[t][state] = prob
            newpath[state] = path[next_state] + [state]  # state狀態概率最大: 前一個狀態 和 當前能噴射出最大概率的狀態
            # print(V)
            # print(newpath)
        path = newpath
    # 最后結果:
    # (0.0128, ['HOT', 'COLD', 'HOT'])
    (prob, next_state) = max([(V[len(obs) - 1][s], s) for s in states])
    return (prob, path[next_state])

3. Learning:EM algorithm

已知觀測序列集O,一系列的HMM狀態,學習參數A,B。
注意,這里的觀測序列是無標簽的,也就是說,我們知道有哪些觀測值,但是觀測值的排列未知。同樣的,隱藏狀態已知,分布未知。
因此,對于前文提到的案例,我們的觀測序列,即吃的冰淇淋數量可能為:O ={1,3,2,...},以及知道存在的隱藏狀態為{HOT,COLD}。但不知道狀態轉移概率A和發射概率B。

EM(expectation-Maximization)algorithm:學習HMM的參數A和B。
EM是一種迭代算法,計算初始概率估計,然后使用這個估計去計算更好的估計,然后繼續根據這個估計再計算更好的估計。

案例分析

假如我們已經知道某幾天的氣溫以及冰淇淋的數量了,也就是說,已知:
ice cream count: temperature:

  1. 3->hot, 3->hot, 2->cold
  2. 1->cold, 1->cold, 2->cold
  3. 1->cold, 2->hot, 3->hot

則,初步判斷氣溫冷熱的初始化概率分布為:\pi_{hot}=1/3,\pi_{cold}=2/3
然后,計算狀態轉移矩陣A:
p(hot|hot) =2/3 ,p(cold|hot)=1/3
p(cold|cold) = 2/3,p(hot|cold) = 1/3
發射概率B:
p(1|hot) = 0, p(2|hot) = 1/4, p(3|hot) = 3/4
p(1|cold) = 3/5, p(2|cold) = 1/5, p(3|cold) = 0

如果我們并不清楚冷熱氣溫背后的冰淇淋數量呢?
Forward-backward or Baum-Welch,EM中的一種特例算法,可以不斷迭代來計算冰淇淋的數量。

Baum-Welch 算法

設,時間t狀態為i時,backward probability:\beta
則,\beta_t(i) = P(o_{t+1},o_{t+2},...,o_{T}|q_t=i,\lambda)

步驟:

  1. 初始化:1<=i<=N,\beta_t(i) =1
  2. 迭代:對1<=i<=N,1<=t<=T,
    \beta_t(i) = \sum_j^N a_{ij}b_j(o_{t+1})\beta_{t+1}(j)
  3. 終止:P(O|\lambda) = \sum_j^N\pi_jb_j(o_1)\beta_1(j)

數學推理

  1. 估計轉移概率
    \hat a_{ij}= (從狀態i轉移到狀態j的期望次數)/( 從狀態i轉移出去的期望次數)
    其中,分子可用聯合概率表示:
    \xi_t(i,j) = P(q_t=i,q_{t+1}=j|O,\lambda)
    因為:P(X|Y,Z) =\frac {p(X,Y|Z)}{P(Y|Z)}P(O|\lambda) = \sum_i^N \alpha_t(i)\beta_t(j)
    所以:\xi_t(i,j) = P(q_t=i,q_{t+1}=j|O, \lambda) = \frac {P(q_t=i,q_{t+1}=j,O|\lambda)} { \sum_i^N \alpha_t(i)\beta_t(j)}
    \hat a_{ij} = \frac{\sum_{t=1}^{T} \xi_t(i,j)}{ \sum_{t=1}^T \sum_{k=1}^{N} \xi_t(i,k)}

  2. 估計發射概率
    \hat b_j(v_k) = (隱藏狀態為j時觀測為k的期望次數)/(隱藏狀態為j的期望次數)
    首先,要知道在時間步t時,狀態為j的概率:
    \gamma_t(j) = P(q_t=j|O,\lambda) = \frac {P(q_t=j,O|\lambda)}{P(O|\lambda)} = \frac {\alpha_t(j)\beta_t(j)}{P(O|\lambda)}
    因此:\hat b_j(v_k) = \frac {\sum_{t=1,s.t.o_t = v_k}^T\gamma_t(j)}{ \sum_{t=1}^T\gamma_t(j)}
    其中:
    \sum_{t=1,s.t.o_t = v_k}^T:對所有的時間步t,觀測到的狀態為k的總和。

EM算法

已經知道轉移概率和發射概率的估計方式,通過EM算法來求解HMM的A和B吧。
輸入:觀測狀態,序列長度為T,隱藏狀態集Q
輸出:HMM的 \lambda=(\pi,A,B)

步驟:

  1. 初始化: \lambda=(\pi,A,B)

  2. 迭代直至收斂
    E-step:根據 \lambda=(\pi,A,B) ,計算期望
    \gamma_t(j) = \frac {\alpha_t(j)\beta_t(j)}{\alpha_T(q_F)}
    \xi_t(i,j) =\frac {P(q_t=i,q_{t+1}=j,O|\lambda)} { \alpha_T(q_F)}

    M-step:根據期望,進行最大值估計,重新估計參數
    \hat a_{ij} = \frac {\sum_{t=1}^{T} \xi_t(i,j)}{ \sum_{t=1}^T \sum_{k=1}^{N} \xi_t(i,k)}
    \hat b_j(v_k) = \frac {\sum_{t=1,s.t. o_t = v_k}^T\gamma_t(j)}{ \sum_{t=1}^T\gamma_t(j)}

  3. 返回估計的參數。

EM算法的初始化很重要,設置的不好,收斂不好。一般在實際應用時候,會根據經驗,手動初始化。

補充

知識點

  1. HMM的參數:初始概率\pi,轉移概率矩陣A,發射概率B
  2. 如果參數已知,還知道觀測序列,隱藏序列:
    求某個時間步下觀測序列的likelihood,用forward算法;
    求某個時間步下觀測序列對應的最可能的隱藏序列,用Viterbi算法;
  3. 如果參數未知,就EM走起。

Viterbi 算法和Foward 算法異同:

  1. Viterbi計算的最可能的路徑,求的是max,輸出最可能的路徑和得分;而Foward計算的likelihood,求的是sum;
  2. Viterbi還多了個backpointers(Viterbi模塊圖示的藍色箭頭)。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,316評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,481評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,241評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,939評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,697評論 6 409
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,182評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,247評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,406評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,933評論 1 334
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,772評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,973評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,516評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,209評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,638評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,866評論 1 285
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,644評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,953評論 2 373

推薦閱讀更多精彩內容

  • 一、HMM建模 HMM參數: 二、HMM的3個假設 (一)馬爾科夫假設 (二)觀測獨立性假設 (三)不變性假設 轉...
    cherryleechen閱讀 2,076評論 0 0
  • HMM簡介 ??對于算法愛好者來說,隱馬爾可夫模型的大名那是如雷貫耳。那么,這個模型到底長什么樣?具體的原理又是什...
    山陰少年閱讀 10,772評論 0 9
  • 1. 馬爾可夫鏈 ?馬爾可夫鏈是滿足馬爾可夫性質的隨機過程。馬爾可夫性質是無記憶性。?也就是說,這一時刻的狀態...
    xieyan0811閱讀 6,430評論 0 11
  • 隱形馬爾可夫模型,英文是 Hidden Markov Models,所以以下就簡稱 HMM。既是馬爾可夫模型,就一...
    errorrrr閱讀 1,032評論 0 4
  • 隱馬爾科夫模型 HMM 通常用于處理時間序列數據,數據包含長度一樣的隱藏狀態和觀測序列,可以通過觀測數據預測出隱藏...
    NLP與人工智能閱讀 1,514評論 0 2