詳解隱馬爾可夫模型(HMM)中的維特比算法

筆記轉(zhuǎn)載于GitHub項目https://github.com/NLP-LOVE/Introduction-NLP

4. 隱馬爾可夫模型與序列標(biāo)注

第3章的n元語法模型從詞語接續(xù)的流暢度出發(fā)番枚,為全切分詞網(wǎng)中的二元接續(xù)打分姐仅,進而利用維特比算法求解似然概率最大的路徑铅乡。這種詞語級別的模型無法應(yīng)對 OOV(Out of Vocabulary些楣,即未登錄詞) 問題: 00V在最初的全切分階段就已經(jīng)不可能進人詞網(wǎng)了写半,更何談?wù)倩亍?/p>

例如下面一句:

頭上戴著束發(fā)嵌寶紫金冠,齊眉勒著二龍搶珠金抹額

加粗的就是相對陌生的新詞虱歪,之前的分詞算法識別不出霹抛,但人類確可以谴咸,是因為讀者能夠識別“戴著”轮听,這些構(gòu)詞法能讓人類擁有動態(tài)組詞的能力。我們需要更細粒度的模型岭佳,比詞語更細粒度的就是字符血巍。

具體說來,只要將每個漢字組詞時所處的位置(首尾等)作為標(biāo)簽珊随,則中文分詞就轉(zhuǎn)化為給定漢字序列找出標(biāo)簽序列的問題述寡。一般而言,由字構(gòu)詞是序列標(biāo)注模型的一種應(yīng)用叶洞。 在所有“序列標(biāo)注”模型中辨赐,隱馬爾可夫模型是最基礎(chǔ)的一種。

4.1 序列標(biāo)注問題

序列標(biāo)注指的是給定一個序列 x=x_1x_2...x_n京办,找出序列中每個元素對應(yīng)標(biāo)簽 y=y_1y_2...y_n 的問題。其中帆焕,y 所有可能的取值集合稱為標(biāo)注集惭婿。比如不恭,輸入一個自然數(shù)序列,輸出它們的奇偶性财饥。

image

求解序列標(biāo)注問題的模型一般稱為序列標(biāo)注器换吧,通常由模型從一個標(biāo)注數(shù)據(jù)集 \{X,Y\}=\{(x^{(i)},y^{(i)})\},i=1,...,K 中學(xué)習(xí)相關(guān)知識后再進行預(yù)測。再NLP問題中钥星,x 通常是字符或詞語沾瓦,而 y 則是待預(yù)測的組詞角色或詞性等標(biāo)簽。中文分詞谦炒、詞性標(biāo)注以及命名實體識別贯莺,都可以轉(zhuǎn)化為序列標(biāo)注問題。

  1. 序列標(biāo)注與中文分詞

    考慮一個字符序列(字符串) x宁改,想象切詞器真的是在拿刀切割字符串,如此,中文分詞轉(zhuǎn)化為標(biāo)注集{切淮菠,過}的序列標(biāo)注問題奔滑。

    image

分詞標(biāo)注集并非只有一種,為了捕捉漢字分別作為詞語收尾(Begin谜喊、End)潭兽、詞中(Middle)以及單字成詞(Single)時不同的成詞概率,人們提出了{B,M,E,S}這種最流行的標(biāo)注集斗遏。

image
  1. 序列標(biāo)注與詞性標(biāo)注

    詞性標(biāo)注任務(wù)是一個天然的序列標(biāo)注問題:x 是單詞序列山卦,y 是相應(yīng)的詞性序列。需要綜合考慮前后的單詞與詞性才能決定當(dāng)前單詞的詞性最易。
    image
  1. 序列標(biāo)注與命名實體識別

    所謂命名實體怒坯,指的是現(xiàn)實存在的實體,比如人名藻懒、地名和機構(gòu)名剔猿,命名實體是 OOV 的主要組成部分。

    考慮到字符級別中文分詞和詞語級別命名實體識別有著類似的特點嬉荆,都是組合短單位形成長單位的問題归敬。所以命名實體識別可以復(fù)用BMES標(biāo)注集,并沿用中文分詞的邏輯鄙早,只不過標(biāo)注的對象由字符變?yōu)閱卧~而已汪茧。唯一不同的是,命名實體識別還需要確定實體所屬的類別限番。這個額外的要求依然是個標(biāo)注問題舱污,可以通過將命名實體類別附著到BMES標(biāo)簽來達到目的。比如弥虐,構(gòu)成地名的單詞標(biāo)注為“B/M/E/S-地名”扩灯,以此類推媚赖。對于那些不構(gòu)成命名實體的單詞,則統(tǒng)-標(biāo)注為O ( Outside), 即復(fù)合詞之外珠插。

    image

總之惧磺,序列標(biāo)注問題是NLP中最常見的問題之一。許多應(yīng)用任務(wù)都可以變換思路捻撑,轉(zhuǎn)化為序列標(biāo)注來解決磨隘。所以一個準確的序列標(biāo)注模型非常重要,直接關(guān)系到NLP系統(tǒng)的準確率顾患。機器學(xué)習(xí)領(lǐng)域為NLP提供了許多標(biāo)注模型番捂,本著循序漸進的原則,本章介紹其中最基礎(chǔ)的一個隱馬爾可夫模型描验。

4.2 隱馬爾可夫模型

隱馬爾可夫模型( Hidden Markov Model, HMM)是描述兩個時序序列聯(lián)合分布 p(x,y) 的概率模型: x 序列外界可見(外界指的是觀測者)白嘁,稱為觀測序列(obsevation sequence); y 序列外界不可見,稱為狀態(tài)序列(state sequence)膘流。比如觀測 x 為單詞絮缅,狀態(tài) y 為詞性,我們需要根據(jù)單詞序列去猜測它們的詞性呼股。隱馬爾可夫模型之所以稱為“隱”耕魄,是因為從外界來看,狀
態(tài)序列(例如詞性)隱藏不可見彭谁,是待求的因變量吸奴。從這個角度來講,人們也稱狀態(tài)為隱狀態(tài)(hidden state),而稱觀測為顯狀態(tài)( visible state)缠局。隱馬爾可夫模型之所以稱為“馬爾可夫模型”则奥,”是因為它滿足馬爾可夫假設(shè)

  1. 從馬爾可夫假設(shè)到隱馬爾可夫模型

    馬爾可夫假設(shè):每個事件的發(fā)生概率只取決于前一個事件狭园。

    馬爾可夫鏈:將滿足馬爾可夫假設(shè)的連續(xù)多個事件串聯(lián)起來读处,就構(gòu)成了馬爾可夫鏈。

    如果把事件具象為單詞唱矛,那么馬爾可夫模型就具象為二元語法模型罚舱。

隱馬爾可夫模型:它的馬爾可夫假設(shè)作用于狀態(tài)序列,

假設(shè) ① 當(dāng)前狀態(tài) Yt 僅僅依賴于前一個狀態(tài) Yt-1绎谦, 連續(xù)多個狀態(tài)構(gòu)成隱馬爾可夫鏈 y管闷。有了隱馬爾可夫鏈,如何與觀測序列 x 建立聯(lián)系呢窃肠?

隱馬爾可夫模型做了第二個假設(shè): ② 任意時刻的觀測 x 只依賴于該時刻的狀態(tài) Yt包个,與其他時刻的狀態(tài)或觀測獨立無關(guān)。如果用箭頭表示事件的依賴關(guān)系(箭頭終點是結(jié)果冤留,依賴于起點的因緣)赃蛛,則隱馬爾可夫模型可以表示為下圖所示

image

狀態(tài)與觀測之間的依賴關(guān)系確定之后恃锉,隱馬爾可夫模型利用三個要素來模擬時序序列的發(fā)生過程----即初始狀態(tài)概率向量、狀態(tài)轉(zhuǎn)移概率矩陣和發(fā)射概率矩陣呕臂。

  1. 初始狀態(tài)概率向量

    系統(tǒng)啟動時進入的第一個狀態(tài) Y1 稱為初始狀態(tài),假設(shè) y 有 N 種可能的取值肪跋,那么 Y1 就是一個獨立的離散型隨機變量歧蒋,由 P(y1 | π) 描述。其中
    \pi=\left(\pi_{1}, \cdots, \pi_{N}\right)^{\mathrm{T}}, 0 \leqslant \pi_{i} \leqslant 1, \sum_{i=1}^{N} \pi_{i}=1
    是概率分布的參數(shù)向量州既,稱為初始狀態(tài)概率向量谜洽。

    image

給定 π ,初始狀態(tài) Y1 的取值分布就確定了吴叶,比如采用{B,M,E,S}標(biāo)注集時概率如下:
p(y_1=B)=0.7\\ p(y_1=M)=0\\ p(y_1=E)=0\\ p(y_1=S)=0.3
那么此時隱馬爾可夫模型的初始狀態(tài)概率向量為 π=[0.7阐虚,0,0蚌卤,0.3]实束,注意,句子第一個詞是單字的可能性要小一些逊彭。

  1. 狀態(tài)轉(zhuǎn)移矩陣

    Yt 如何轉(zhuǎn)移到 Yt+1 呢咸灿?根據(jù)馬爾可夫假設(shè),t+1 時的狀態(tài)僅僅取決于 t 時的狀態(tài)侮叮,既然一共有 N 種狀態(tài)避矢,那么從狀態(tài) Si 到狀態(tài) Sj 的概率就構(gòu)成了一個 NN 的方陣,稱為狀態(tài)轉(zhuǎn)移矩陣 A
    A=\left[p\left(y_{t+1}=s_{j} | y_{t}=s_{i}\right)\right]_{N \times N}
    其中下標(biāo) i囊榜、j 分別表示狀態(tài)的第 i审胸、j 種取值。狀態(tài)轉(zhuǎn)移概率的存在有其實際意義卸勺,在中文分詞中砂沛,標(biāo)簽 B 的后面不可能是 S,于是就有 P(Yt+1 = S | Yt = B) = 0孔庭。同樣尺上,詞性標(biāo)注中的“形容詞->名詞”“副詞->動詞”也可通過狀態(tài)轉(zhuǎn)移概率來模擬,這些
    概率分布參數(shù)不需要手動設(shè)置圆到,而是通過語料庫上的統(tǒng)計自動學(xué)習(xí)*怎抛。

  1. 發(fā)射概率矩陣

    有了狀態(tài) Yt 之后,如何確定觀測 Xt 的概率分布呢芽淡?根據(jù)隱馬爾可夫假設(shè)②马绝,當(dāng)前觀測 Xt 僅僅取決于當(dāng)前狀態(tài) Yt。也就是說挣菲,給定每種 y富稻,x 都是一個獨立的離散型隨機變量掷邦,其參數(shù)對應(yīng)一個向量。 假設(shè)觀測 x 一共有 M 種可能的取值椭赋,則 x 的概率分布參數(shù)向量維度為 M抚岗。由于 y 共有 N 種,所以這些參數(shù)向量構(gòu)成了 NM 的矩陣哪怔,稱為發(fā)射概率矩陣B*宣蔚。

    \boldsymbol{B}=\left[p\left(x_{t}=o_{i} | y_{t}=s_{j}\right)\right]_{N \times M}

    其中,第 i 行 j 列的元素下標(biāo) i 和 j 分別代表觀測和狀態(tài)的第 i 種和第 j 種取值认境。

  1. 隱馬爾可夫模型的三個基本用法

    • 樣本生成問題:給定模型胚委,如何有效計算產(chǎn)生觀測序列的概率?換言之叉信,如何評估模型與觀測序列之間的匹配程度亩冬?

    • 序列預(yù)測問題:給定模型和觀測序列,如何找到與此觀測序列最匹配的狀態(tài)序列硼身?換言之硅急,如何根據(jù)觀測序列推斷出隱藏的模型狀態(tài)?

    • 模型訓(xùn)練問題:給定觀測序列鸠姨,如何調(diào)整模型參數(shù)使得該序列出現(xiàn)的概率最大铜秆?換言之,如何訓(xùn)練模型使其能最好地描述觀測數(shù)據(jù)讶迁?

    前兩個問題是模式識別的問題:1) 根據(jù)隱馬爾科夫模型得到一個可觀察狀態(tài)序列的概率(評價)连茧;2) 找到一個隱藏狀態(tài)的序列使得這個序列產(chǎn)生一個可觀察狀態(tài)序列的概率最大(解碼)。第三個問題就是根據(jù)一個可以觀察到的狀態(tài)序列集產(chǎn)生一個隱馬爾科夫模型(學(xué)習(xí))巍糯。

4.3 隱馬爾可夫模型的訓(xùn)練

  1. 案例假設(shè)和模型構(gòu)造

    設(shè)想如下案例:某醫(yī)院招標(biāo)開發(fā)“智能”醫(yī)療診斷系統(tǒng)啸驯,用來輔助感冒診斷。已知①來診者只有兩種狀態(tài):要么健康祟峦,要么發(fā)燒罚斗。②來診者不確定自己到底是哪種狀態(tài),只能回答感覺頭暈宅楞、體寒或正常针姿。醫(yī)院認為,③感冒這種病厌衙,只跟病人前一天的狀態(tài)有關(guān)距淫,并且,④當(dāng)天的病情決定當(dāng)天的身體感覺婶希。有位來診者的病歷卡上完整地記錄了最近 T 天的身體感受(頭暈榕暇、體寒或正常),請預(yù)測這 T 天的身體狀態(tài)(健康或發(fā)燒)。由于醫(yī)療數(shù)據(jù)屬于機密隱私彤枢,醫(yī)院無法提供訓(xùn)練數(shù)據(jù)狰晚,但根據(jù)醫(yī)生經(jīng)驗,感冒發(fā)病的規(guī)律如下圖所示(箭頭上的數(shù)值表示概率):

    image

根據(jù)已知條件①②缴啡,病情狀態(tài)(健康壁晒、發(fā)燒)可作為隱馬爾可夫模型的隱狀態(tài)(上圖藍色狀態(tài)),而身體感受(頭暈盟猖、體寒或正常)可作為隱馬爾可夫模型的顯狀態(tài)(圖中白色狀態(tài))讨衣。條件③符合隱馬爾可夫模型假設(shè)一,條件④符 合隱馬爾可夫模型假設(shè)二式镐。這個案例其實描述了一個隱馬爾可夫模型, 并且參數(shù)已經(jīng)給定固蚤。構(gòu)造模型代碼見:

import numpy as np
from pyhanlp import *
from jpype import JArray, JFloat, JInt

to_str = JClass('java.util.Arrays').toString

## 隱馬爾可夫模型描述
states = ('Healthy', 'Fever')
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},
}
observations = ('normal', 'cold', 'dizzy')


def generate_index_map(lables):
    index_label = {}
    label_index = {}
    i = 0
    for l in lables:
        index_label[i] = l
        label_index[l] = i
        i += 1
    return label_index, index_label


states_label_index, states_index_label = generate_index_map(states)
observations_label_index, observations_index_label = generate_index_map(observations)



def convert_map_to_matrix(map, label_index1, label_index2):
    m = np.empty((len(label_index1), len(label_index2)), dtype=float)
    for line in map:
        for col in map[line]:
            m[label_index1[line]][label_index2[col]] = map[line][col]
    return JArray(JFloat, m.ndim)(m.tolist())

def convert_observations_to_index(observations, label_index):
    list = []
    for o in observations:
        list.append(label_index[o])
    return list

def convert_map_to_vector(map, label_index):
    v = np.empty(len(map), dtype=float)
    for e in map:
        v[label_index[e]] = map[e]
    return JArray(JFloat, v.ndim)(v.tolist())  # 將numpy數(shù)組轉(zhuǎn)為Java數(shù)組


## pi:初始狀態(tài)概率向量
## A:狀態(tài)轉(zhuǎn)移概率矩陣
## B:發(fā)射概率矩陣
A = convert_map_to_matrix(transition_probability, states_label_index, states_label_index)
B = convert_map_to_matrix(emission_probability, states_label_index, observations_label_index)
observations_index = convert_observations_to_index(observations, observations_label_index)
pi = convert_map_to_vector(start_probability, states_label_index)

FirstOrderHiddenMarkovModel = JClass('com.hankcs.hanlp.model.hmm.FirstOrderHiddenMarkovModel')
given_model = FirstOrderHiddenMarkovModel(pi, A, B)
  1. 樣本生成算法

    它的生成過程就是沿著隱馬爾可夫鏈走 T 步:

    • 根據(jù)初始狀態(tài)概率向量采樣第一個時刻的狀態(tài) Y1 = Si娘汞,即 Y1 ~ π。
    • Yt 采樣結(jié)束得到 Si 后夕玩,根據(jù)狀態(tài)轉(zhuǎn)移概率矩s陣第 i 行的概率向量你弦,采樣下一時刻的狀態(tài) Yt+1。
    • 對每個 Yt = Si燎孟,根據(jù)發(fā)射概率矩陣的第 i 行采樣 Xt禽作。
    • 重復(fù)步驟 2 共計 T-1 次,重復(fù)步驟 3 共計 T 次揩页,輸出序列 x 與 y旷偿。

    代碼如下(接上),直接通過模型進行生成:

    ## 第一個參數(shù):序列最低長度
    ## 第二個參數(shù):序列最高長度
    ## 第三個參數(shù):需要生成的樣本數(shù)
    for O, S in given_model.generate(3, 5, 2):
        print(" ".join((observations_index_label[o] + '/' + states_index_label[s]) for o, s in zip(O, S)))
    
  1. 隱馬爾可夫模型的訓(xùn)練

    樣本生成后爆侣,我們就可以利用生成的數(shù)據(jù)重新訓(xùn)練萍程,通過極大似然法來估計隱馬爾可夫模型的參數(shù)。參數(shù)指的是三元組(π兔仰,A茫负,B)。

    利用給定的隱馬爾可夫模型 P生成十萬個樣本乎赴,在這十萬個樣本上訓(xùn)練新模型Q忍法,比較新舊模型參數(shù)是否一致。

    trained_model = FirstOrderHiddenMarkovModel()
    
    ## 第一個參數(shù):序列最低長度
    ## 第二個參數(shù):序列最高長度
    ## 第三個參數(shù):需要生成的樣本數(shù)
    trained_model.train(given_model.generate(3, 10, 100000))
    print('新模型與舊模型是否相同:', trained_model.similar(given_model))
    

    輸出:

    新模型與舊模型是否相同: True
    

    運行后一般都成立榕吼,由于隨機數(shù)饿序,僅有小概率發(fā)生失敗。

4.4 隱馬爾可夫模型的預(yù)測

隱馬爾可夫模型最具實際意義的問題當(dāng)屬序列標(biāo)注了:給定觀測序列友题,求解最可能的狀態(tài)序列及其概率嗤堰。

  1. 概率計算的前向算法

    給定觀測序列 x 和一個狀態(tài)序列 y,就可以估計兩者的聯(lián)合概率 P(x,y),聯(lián)合概率就是一種結(jié)果的概率踢匣,在這些結(jié)果當(dāng)中找到最大的聯(lián)合概率就是找到最有可能的結(jié)果預(yù)測告匠。聯(lián)合概率:P(x,y) = P(y) P(x|y),下面我們來分別求出P(y)和P(x|y)

  • 順著隱馬爾可夫鏈走离唬,首先 t=1 時初始狀態(tài)沒有前驅(qū)狀態(tài)后专,發(fā)生概率由 π 決定:

    P(y_1=s_i)=\pi_i

  • 接著對 t >= 2,狀態(tài) Yt 由前驅(qū)狀態(tài) Yt-1 轉(zhuǎn)移而來输莺,轉(zhuǎn)移矩陣由矩陣 A 決定:

    P(y_t=s_j|y_{t-1}=s_i)=A_{i,j}

    所以狀態(tài)序列的概率為上面式子的乘積:

    p(y)=p\left(y_{1}, \cdots, y_{r}\right)=p\left(y_{1}\right) \prod_{i=2}^{T} p\left(y_{i} | y_{i-1}\right)

  • P(y) 我們已經(jīng)求出來了戚哎,下面要求 P(x|y)

    對于每個 Yt = Si,都會“發(fā)射”一個 Xt = Oj嫂用,發(fā)射概率由矩陣 B 決定:

    P(x_t=O_j|y_t=s_i)=B_{i,j}

  • 那么給定一個狀態(tài)序列 Y型凳,對應(yīng)的 X 的概率累積形式:

    p(x | y)=\prod_{t=1}^{T} p\left(x_{t} | y_{t}\right)

  • 最后帶入聯(lián)合概率公式得:
    \begin{aligned} p(x, y) &=p(y) p(x | y) \\ &=p\left(y_{1}\right) \prod_{t=2}^{T} p\left(y_{t} | y_{t-1}\right) \prod_{t=1}^{T} p\left(x_{t} | y_{t}\right) \end{aligned}

將其中的每個 Xt、Yt 對應(yīng)上實際發(fā)生序列的 Si嘱函、Oj甘畅,就能帶入(π,A,B)中的相應(yīng)元素,從而計算出任意序列的概率往弓,最后找出這些概率的最大值就得到預(yù)測結(jié)果疏唾。找出概率最大值要用到維特比算法

  1. 搜索狀態(tài)序列的維特比算法

    理解了前向算法之后函似,找尋最大概率所對應(yīng)的狀態(tài)序列無非是一個搜索問題槐脏。具體說來,將每個狀態(tài)作為有向圖中的一個節(jié)點撇寞, 節(jié)點間的距離由轉(zhuǎn)移概率決定顿天,節(jié)點本身的花費由發(fā)射概率決定。那么所有備選狀態(tài)構(gòu)成一幅有 向無環(huán)圖重抖,待求的概率最大的狀態(tài)序列就是圖中的最長路徑露氮,此時的搜索算法稱為維特比算法,如圖下圖所示:

    image

上圖從左往右時序遞增钟沛,虛線由初始狀態(tài)概率決定畔规,實線則是轉(zhuǎn)移概率。由于受到觀測序列的約束恨统,不同狀態(tài)發(fā)射觀測的概率不同叁扫,所以每個節(jié)點本身也必須計算自己的花費,由發(fā)射概率決定畜埋。又由于 Yt+1 僅依賴于 Yt莫绣,所以網(wǎng)狀圖可以動態(tài)規(guī)劃的搜索,也就是維特比算法

  • 初始化悠鞍,t=1 時初始最優(yōu)路徑的備選由 N 個狀態(tài)組成对室,它們的前驅(qū)為空。
    \begin{aligned} \delta_{1, i}=\pi_{i} \boldsymbol{B}_{i, o_{1}}, & i=1, \cdots, N \\ \psi_{1, i}=0, & i=1, \cdots, N \end{aligned}
    其中,δ 存儲在時刻 t 以 Si 結(jié)尾的所有局部路徑的最大概率掩宜。ψ 存儲局部最優(yōu)路徑末狀態(tài) Yt 的前驅(qū)狀態(tài)蔫骂。

  • 遞推,t >= 2 時每條備選路徑像貪吃蛇一樣吃入一個新狀態(tài)牺汤,長度增加一個單位辽旋,根據(jù)轉(zhuǎn)移概率和發(fā)射概率計算花費。找出新的局部最優(yōu)路徑檐迟,更新 δ补胚、ψ 兩個數(shù)組。
    \begin{array}{ll} {\delta_{t, i}=\max _{1 \leqslant j \leqslant N}\left(\delta_{t-1, j} A_{j, i}\right) B_{i, o_{t}},} & {i=1, \cdots, N} \\ {\psi_{t, i}=\arg \max _{1 \leqslant j \leqslant N}\left(\delta_{t-1, j} A_{j, i}\right),} & {i=1, \cdots, N} \end{array}

  • 終止追迟,找出最終時刻 δt,i 數(shù)組中的最大概率 P*溶其,以及相應(yīng)的結(jié)尾狀態(tài)下標(biāo) i*t。
    \begin{aligned} &p^{*}=\max _{1 \leqslant i \leqslant N} \delta_{T, i}\\ &i_{T}^{*}=\arg \max _{1 \leqslant i \leqslant N} \delta_{T, i} \end{aligned}

  • 回溯敦间,根據(jù)前驅(qū)數(shù)組 ψ 回溯前驅(qū)狀態(tài)握联,取得最優(yōu)路徑狀態(tài)下標(biāo)。
    i_{t}^{*}=\psi_{t+1, i_{t+1}}, \quad t=T-1, T-2, \cdots, 1

預(yù)測代碼如下(接上面代碼):

pred = JArray(JInt, 1)([0, 0, 0])
prob = given_model.predict(observations_index, pred)
print(" ".join((observations_index_label[o] + '/' + states_index_label[s]) for o, s in
               zip(observations_index, pred)) + " {:.3f}".format(np.math.exp(prob)))

輸出為:

normal/Healthy cold/Healthy dizzy/Fever 0.015

觀察該結(jié)果每瞒,“/”隔開觀測和狀態(tài),最后的 0.015 是序列的聯(lián)合概率纯露。

4.5 隱馬爾可夫模型應(yīng)用于中文分詞

HanLP 已經(jīng)實現(xiàn)了基于隱馬爾可夫模型的中文分詞器 HMMSegmenter剿骨,并且實現(xiàn)了訓(xùn)練接口。代碼詳見:

hmm_cws.py:https://github.com/NLP-LOVE/Introduction-NLP/tree/master/code/ch04/hmm_cws.py

4.6 性能評測

如果隱馬爾可夫模型中每個狀態(tài)僅依賴于前一個狀態(tài)埠褪, 則稱為一階浓利;如果依賴于前兩個狀態(tài),則稱為二階钞速。既然一階隱馬爾可夫模型過于簡單贷掖,是否可以切換到二階來提高分數(shù)呢?

答案是可以的渴语,跟一階類似苹威,這里不再詳細介紹二階隱馬爾可夫模型,詳細請看原書驾凶。

這里我們使用 MSR語料庫進行評測牙甫,結(jié)果如下表所示:

算法 P R F1 R(oov) R(IV)
最長匹配 89.41 94.64 91.95 2.58 97.14
二元語法 92.38 96.70 94.49 2.58 99.26
一階HHM 78.49 80.38 79.42 41.11 81.44
二階HHM 78.34 80.01 79.16 42.06 81.04

可以看到,二階隱馬爾可夫模型的 Roov 有少許提升调违,但綜合 F1 反而下降了窟哺。這說明增加隱馬爾可夫模型的階數(shù)并不能提高分詞器的準確率,單靠提高轉(zhuǎn)移概率矩陣的復(fù)雜度并不能提高模型的擬合能力技肩,我們需要從別的方面想辦法且轨。目前市面上一些開源分詞器仍然停留在一階隱馬爾可夫模型的水平,比如著名的結(jié)巴分詞,它們的準確率也只能達到80%左右旋奢。

4.7 總結(jié)

這一章我們想解決的問題是新詞識別泳挥,為此從詞語級模型切換到字符級模型,將中文分詞任務(wù)轉(zhuǎn)換為序列標(biāo)注問題黄绩。作為新手起步羡洁,我們嘗試了最簡單的序列標(biāo)注模型----隱馬爾可夫模型。隱馬爾可夫模型的基本問題有三個:樣本生成爽丹、參數(shù)估計筑煮、序列預(yù)測

然而隱馬爾可夫模型用于中文分詞的效果并不理想粤蝎,雖然召回了一半的 OOV真仲,但綜合 F1 甚至低于詞典分詞。哪怕升級到二階隱馬爾可夫模型初澎, F1 值依然沒有提升秸应。 看來樸素的隱馬爾可夫模型不適合中文分詞,我們需要更高級的模型碑宴。

話說回來软啼,隱馬爾可夫模型作為入門模型,比較容易上手延柠,同時也是許多高級模型的基礎(chǔ)祸挪。打好基礎(chǔ),我們才能挑戰(zhàn)高級模型贞间。

4.8 GitHub項目

HanLP何晗--《自然語言處理入門》筆記:

https://github.com/NLP-LOVE/Introduction-NLP

項目持續(xù)更新中......

目錄


章節(jié)
第 1 章:新手上路
第 2 章:詞典分詞
第 3 章:二元語法與中文分詞
第 4 章:隱馬爾可夫模型與序列標(biāo)注
第 5 章:感知機分類與序列標(biāo)注
第 6 章:條件隨機場與序列標(biāo)注
第 7 章:詞性標(biāo)注
第 8 章:命名實體識別
第 9 章:信息抽取
第 10 章:文本聚類
第 11 章:文本分類
第 12 章:依存句法分析
第 13 章:深度學(xué)習(xí)與自然語言處理
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末贿条,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子增热,更是在濱河造成了極大的恐慌整以,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件峻仇,死亡現(xiàn)場離奇詭異公黑,居然都是意外死亡,警方通過查閱死者的電腦和手機础浮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門帆调,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人豆同,你說我怎么就攤上這事番刊。” “怎么了影锈?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵芹务,是天一觀的道長蝉绷。 經(jīng)常有香客問我,道長枣抱,這世上最難降的妖魔是什么熔吗? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮佳晶,結(jié)果婚禮上桅狠,老公的妹妹穿的比我還像新娘。我一直安慰自己轿秧,他們只是感情好中跌,可當(dāng)我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著菇篡,像睡著了一般漩符。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上驱还,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天嗜暴,我揣著相機與錄音,去河邊找鬼议蟆。 笑死闷沥,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的咐容。 我是一名探鬼主播狐赡,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼疟丙!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起鸟雏,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤享郊,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后孝鹊,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體炊琉,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年又活,在試婚紗的時候發(fā)現(xiàn)自己被綠了苔咪。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡柳骄,死狀恐怖团赏,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情耐薯,我是刑警寧澤舔清,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布丝里,位于F島的核電站,受9級特大地震影響体谒,放射性物質(zhì)發(fā)生泄漏杯聚。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一抒痒、第九天 我趴在偏房一處隱蔽的房頂上張望幌绍。 院中可真熱鬧,春花似錦故响、人聲如沸傀广。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽主儡。三九已至,卻和暖如春惨缆,著一層夾襖步出監(jiān)牢的瞬間糜值,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工坯墨, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留寂汇,地道東北人。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓捣染,卻偏偏與公主長得像骄瓣,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子耍攘,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容