機器學習-隱馬爾科夫模型(HMM)

一,介紹

隱馬爾科夫模型(Hidden Markov Model,以下簡稱HMM)是比較經典的機器學習模型了,它在語言識別,自然語言處理,模式識別等領域得到廣泛的應用。目前隨着深度學習的崛起,尤其是RNNLSTM等神經網絡序列模型的火熱,HMM的地位有所下降。

使用HMM模型時我們的問題一般有這兩個特徵:1)我們的問題是基於序列的,比如時間序列,或者狀態序列。2)我們的問題中有兩類數據,一類序列數據是可以觀測到的,即觀測序列;而另一類數據是不能觀察到的,即隱藏狀態序列,簡稱狀態序列。我們常用的谷歌輸入法等就可以採用HMM模型,根據你之前的輸入,判斷你接下來要輸入什麼給出提示。

模型定義:

對於HMM模型,首先我們假設Q是所有可能的隱藏狀態的集合,V是所有觀測狀態的集合,即:

                                                           

其中,N是可能的隱藏狀態數,M是所有的可能的觀察狀態數。

對於一個長度爲T的序列,I對應的狀態序列, O是對應的觀察序列,即:

                                                           

 

其中,任意一個隱藏狀態it∈Q,任意一個觀察狀態ot∈V。

接着,我們做出以下假設:

1)齊次馬爾科夫鏈假設,即任意時刻的隱藏狀態只依賴於它前一個隱藏狀態。我們得到如果在時刻t的隱藏狀態是it=qi,在時刻t+1的隱藏狀態是it+1=qj, 則從時刻t到時刻t+1的HMM狀態轉移概率aij可以表示爲:

                                                                   

從而得到馬爾科夫鏈的狀態轉移矩陣A:

                                                                                 

2) 觀測獨立性假設,即任意時刻的觀察狀態只僅僅依賴於當前時刻的隱藏狀態。如果在時刻t的隱藏狀態是it=qj, 而對應的觀察狀態爲ot=vk, 則該時刻觀察狀態vk在隱藏狀態qj下生成的概率爲bj(k)爲:

                                                            

這樣bj(k)可以組成觀測狀態生成的概率矩陣B:

                                                                                 

我們再獲得一個初始狀態t=1的初始狀態概率分佈Π:

                                                 

根據上面的兩個假設和初始狀態就可以確定一個隱馬爾科夫模型。

確定HMM模型後,我們一共有三個經典的問題需要解決:

1) 評估觀察序列概率。即給定模型λ=(A,B,Π)和觀測序列O={o1,o2,...oT},計算在模型λ下觀測序列O出現的概率P(O|λ)。這個問題的求解需要用到前向後向算法。

2)模型參數學習問題。即給定觀測序列O={o1,o2,...oT},估計模型λ=(A,B,Π)的參數,使該模型下觀測序列的條件概率P(O|λ)最大。這個問題的求解需要用到基於EM算法的鮑姆-韋爾奇算法。

3)預測問題,也稱爲解碼問題。即給定模型λ=(A,B,Π)和觀測序列O={o1,o2,...oT},求給定觀測序列條件下,最可能出現的對應的狀態序列,這個問題的求解需要用到基於動態規劃的維特比算法。

二,代碼實現
前向算法:

輸入:HMM模型λ=(A,B,Π),觀測序列O=(o1,o2,...oT)

輸出:觀測序列概率P(O|λ)

1) 計算時刻1的各個隱藏狀態前向概率:

                                                  

2) 遞推時刻2,3,...T時刻的前向概率:

                                               

3) 計算最終結果:

                                                 

數據:

假設有三個盒子,裏面裝有白球和紅球如下:

盒子 1 2 3
紅球數 5 4 7
白球數 5 6 3

求O={紅,白,紅}概率

代碼:

 

import numpy as np

def FB():
    data = [[5,4,7],[5,6,3]]   # 初始數據
    pi = np.mat([0.2,0.4,0.4])         # t=1時,初始狀態概率
    A=np.mat([[0.5,0.2,0.3],[0.3,0.5,0.2],[0.2,0.3,0.5]])  # 狀態轉移矩陣
    B=np.mat([[0.5,0.5],[0.4,0.6],[0.7,0.3]])              # 觀察狀態矩陣
    N=2;M=3;O=[0,1,0]                              # 求輸出O概率,對應爲{紅、白、紅}
    a = np.multiply(pi,B[:,O[0]].T)                # 第一步,時刻1的各個隱藏狀態前向概率
    for i in range(1,M):
        tmp = a.copy()
        for j in range(M):
            a[0,j]=np.multiply(tmp,A[:,j].T).sum(axis=1)*B[j,O[i]]   # 第二步,遞推時刻2,3,...T時刻的前向概率
    p=a.sum(axis=1)     # 第三步,計算最終結果
    return p

if __name__=="__main__":
    p=FB()
    print(p)

{紅,白,紅}出現概率爲:0.130218

後向算法:

輸入:HMM模型λ=(A,B,Π),觀測序列O=(o1,o2,...oT)

輸出:觀測序列概率P(O|λ)

1) 初始化時刻T的各個隱藏狀態後向概率:

                                                              

2) 遞推時刻T−1,T−2,...1時刻的後向概率:

                                                            

3) 計算最終結果:

                                                           

代碼:

import numpy as np

# 後向算法
def BB():
    pi = np.mat([0.2, 0.4, 0.4])  # t=1時,初始狀態概率
    A = np.mat([[0.5, 0.2, 0.3], [0.3, 0.5, 0.2], [0.2, 0.3, 0.5]])  # 狀態轉移矩陣
    B = np.mat([[0.5, 0.5], [0.4, 0.6], [0.7, 0.3]])  # 觀察狀態矩陣
    b=np.mat([1.0,1.0,1.0])
    N = 2;M = 3;O = [0, 1, 0]  # 求輸出O概率,對應爲{紅、白、紅}
    i=M
    while i>1:
        tmp = b.copy()
        for j in range(M):
            ab = np.multiply(A[j,:],B[:,O[i-1]].T)
            b[0,j]=np.multiply(ab,tmp).sum(axis=1)   # 第二步,遞推時刻2,3,...T時刻的前向概率
        i-=1
    pib = np.multiply(b, pi)
    return  np.multiply(pib,B[:,0].T).sum(axis=1)

if __name__=="__main__":
    p=BB()
    print(p)

{紅,白,紅}出現概率爲:0.130218

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章