1. 程式人生 > >【中文分詞】隱馬爾可夫模型HMM

【中文分詞】隱馬爾可夫模型HMM

Nianwen Xue在《Chinese Word Segmentation as Character Tagging》中將中文分詞視作為序列標註問題(sequence tagging problem),由此引入監督學習演算法來解決分詞問題。

1. HMM

首先,我們將簡要地介紹HMM(主要參考了李航老師的《統計學習方法》)。HMM包含如下的五元組:

  • 狀態值集合\(Q=\{q_1, q_2, \cdots, q_N\}\),其中\(N\)為可能的狀態數;
  • 觀測值集合\(V=\{v_1, v_2, \cdots, v_M\}\),其中\(M\)為可能的觀測數;
  • 轉移概率矩陣\(A=\left[ a_{ij} \right]\)
    ,其中\(a_{ij}\)表示從狀態\(i\)轉移到狀態\(j\)的概率;
  • 發射概率矩陣(在[2]中稱之為觀測概率矩陣\(B=\left[ b_{j}(k) \right]\),其中\(b_{j}(k)\)表示在狀態\(j\)的條件下生成觀測\(v_k\)的概率;
  • 初始狀態分佈\(\pi\).

一般地,將HMM表示為模型\(\lambda = (A, B, \pi)\),狀態序列為\(I\),對應測觀測序列為\(O\)。對於這三個基本引數,HMM有三個基本問題:

  • 概率計算問題,在模型\(\lambda\)下觀測序列\(O\)出現的概率;
  • 學習問題,已知觀測序列\(O\),估計模型\(\lambda\)
    的引數,使得在該模型下觀測序列\(P(O|\lambda)\)最大;
  • 解碼(decoding)問題,已知模型\(\lambda\)與觀測序列\(O\),求解條件概率\(P(I|O)\)最大的狀態序列\(I\)

2. 中文分詞

將狀態值集合\(Q\)置為\(\{ B, E, M, S\}\),分別表示詞的開始、結束、中間(begin、end、middle)及字元獨立成詞(single);觀測序列即為中文句子。比如,“今天天氣不錯”通過HMM求解得到狀態序列“B E B E B E”,則分詞結果為“今天/天氣/不錯”。

通過上面例子,我們發現中文分詞的任務對應於解碼問題:對於字串\(C=\{ c_1, \cdots, c_n \}\)

,求解最大條件概率

\[ \max P(t_1, \cdots, t_n | c_1, \cdots, c_n) \]

其中,\(t_i\)表示字元\(c_i\)對應的狀態。應如何求解狀態序列呢?解決的辦法便是Viterbi演算法;其實,Viterbi演算法本質上是一個動態規劃演算法,利用到了狀態序列的最優路徑滿足這樣一個特性:最優路徑的子路徑也一定是最優的。定義在時刻\(t\)狀態為\(i\)的概率最大值為\(\delta_t(i)\),則有遞推公式:

\begin{equation}
\delta_{t+1}(i) = \max { [\delta_t(j) a_{ji}] b_i(o_{t+1}) }
\label{eq:hmm}
\end{equation}

其中,\(o_{t+1}\)即為字元\(c_{t+1}\)

3. 開源實現

以下的原始碼分析基於Jieba 0.36版本。

Jieba的jieba.finalseg實現HMM中文分詞。prob_start.py定義初始狀態分佈\(\pi\)

P={'B': -0.26268660809250016,
 'E': -3.14e+100,
 'M': -3.14e+100,
 'S': -1.4652633398537678}

prob_trans.py轉移概率矩陣\(A\)

P={'B': {'E': -0.510825623765990, 'M': -0.916290731874155},
 'E': {'B': -0.5897149736854513, 'S': -0.8085250474669937},
 'M': {'E': -0.33344856811948514, 'M': -1.2603623820268226},
 'S': {'B': -0.7211965654669841, 'S': -0.6658631448798212}}

prob_emit.py定義了發射概率矩陣\(B\),比如,P("和"|M)表示狀態為M的情況下出現“和”這個字的概率;

P={'B': {'一': -3.6544978750449433,
       '丁': -8.125041941842026,
       '七': -7.817392401429855,
    ...}
 'S': {':': -15.828865681131282,
       '一': -4.92368982120877,
       ...}
 ...}

關於訓練模型的生成,作者在這裡有解釋,來源主要有兩個:標準的切分語料 + ICTCLAS切分的txt小說。還有一個大家可能會疑惑的問題,為什麼Jieba中的概率矩陣中出現了負數?不急,我們先來看看Viterbi演算法的實現——jieba.finalseg.viterbi函式:

PrevStatus = {
    'B': 'ES',
    'M': 'MB',
    'S': 'SE',
    'E': 'BM'
}

def viterbi(obs, states, start_p, trans_p, emit_p):
    V = [{}]  # tabular
    path = {}
    for y in states:  # init
        V[0][y] = start_p[y] + emit_p[y].get(obs[0], MIN_FLOAT)
        path[y] = [y]
    for t in xrange(1, len(obs)):
        V.append({})
        newpath = {}
        for y in states:
            em_p = emit_p[y].get(obs[t], MIN_FLOAT)
            (prob, state) = max(
                [(V[t - 1][y0] + trans_p[y0].get(y, MIN_FLOAT) + em_p, y0) for y0 in PrevStatus[y]])
            V[t][y] = prob
            newpath[y] = path[state] + [y]
        path = newpath

    (prob, state) = max((V[len(obs) - 1][y], y) for y in 'ES')

    return (prob, path[state])

為了適配中文分詞任務,Jieba對Viterbi演算法做了如下的修改:

  • 狀態轉移時應滿足PrevStatus條件,即狀態\(B\)的前一狀態只能是\(E\)或者\(S\),...
  • 最後一個狀態只能是\(E\)或者\(S\),表示詞的結尾。

與此同時,Jieba在實現公式\eqref{eq:hmm}時,對其求對數,將相乘轉化成了相加:

\[ \ln \delta_{t+1}(i) = \max \{ \ln \delta_t(j) + \ln a_{ji} + \ln b_i(o_{t+1}) \} \]

這就回答了上面的問題——為什麼概率矩陣中出現了負數,是因為對其求了對數。

Jieba的HMM分詞:

from jieba.finalseg import cut

sentence = "小明碩士畢業於中國科學院計算所,後在日本京都大學深造"
print('/'.join(cut(sentence)))

分詞結果為“小明/碩士/畢業於/中國/科學院/計算/所/,/後/在/日/本京/都/大學/深造”,我們發現:關於“日本京都”出現分詞錯誤的情況。這是因為最大條件概率\(P(I|O)\)對應的狀態序列不一定是分詞正確的標註序列。此外,HMM做了兩個基本假設:

  • 齊次Markov性假設,即任意時刻t的狀態僅與前一時刻狀態相關,與其他時刻的狀態、時刻t均無關;
  • 觀測獨立性假設,任意時刻t的觀測僅依賴於該時刻HMM的狀態,與其他的觀測及狀態均無關。

HMM受限於這兩個假設(字元\(c_t\)僅與前一字元\(c_{t-1}\)相關),而不能學習到更多的特徵,泛化能力有限。

4. 參考資料

[1] Xue, Nianwen. "Chinese word segmentation as character tagging." Computational Linguistics and Chinese Language Processing 8.1 (2003): 29-48.
[2] 李航. "統計學習方法." 清華大學出版社, 北京 (2012).
[3] Itenyh, Itenyh版-用HMM做中文分詞二:模型準備.
[4] Django夢之隊, 對Python中文分詞模組結巴分詞演算法過程的理解和分析.(源連結掛了,為轉載連結)

相關推薦

中文模型HMM

Nianwen Xue在《Chinese Word Segmentation as Character Tagging》中將中文分詞視作為序列標註問題(sequence tagging problem),由此引入監督學習演算法來解決分詞問題。 1. HMM 首先,我們將簡要地介紹HMM(主要參考了李航老師的《

簡單上手用於中文模型

前段時間一直在看自然語言處理方面的知識,所以不可避免的接觸到了隱馬爾科夫模型和條件隨機場模型。這兩個模型可以說是自然語言處理方向的基礎模型了,所以自然而然對它們上心許多。它們之間也確實是有許多的異同,當時為了清晰地區分開它們,確實是花費了我好一陣子時間,而且到現在自己也還沒有完完全全把它們吃透,但還

演算法 模型 HMM

隱馬爾可夫模型 (Hidden Markov Model,HMM) 以下來源於_作者 :skyme 地址:http://www.cnblogs.com/skyme/p/4651331.html 隱馬爾可夫模型(Hidden Markov Model,HMM)是統計模型,它用來描述一

機器學習筆記18模型

【參考資料】 【1】《統計學習方法》 隱馬爾可夫模型(HMM)定義 隱馬爾可夫模型: 隱馬爾可夫模型是關於時序的模型,描述一個由隱藏的馬爾可夫鏈生成的不可觀測的狀態序列,再由各個狀態生成的觀測值所構成的一個觀測序列。 形式化定義HMM為λ=(A,B,π)\la

統計學習方法_模型HMM實現

這裡用到的資料集是三角波,使用長度20的序列訓練100次,生成長度為100的序列。HMM的初始化非常重要,這裡採用隨機初始化。 #!/usr/bin/env python3 # -*- coding: utf-8 -*- import csv import random

模型HMM(二)概率計算問題

摘自 1.李航的《統計學習方法》 2.http://www.cnblogs.com/pinard/p/6955871.html   一、概率計算問題 上一篇介紹了概率計算問題是給定了λ(A,B,π),計算一個觀測序列O出現的概率,即求P(O|λ)。 用三種方法,直接計演算法,前向演算法,

模型HMM---《統計學習方法》第十章

標註問題 標註問題的輸入是一個觀測序列,輸出是一個標記序列或狀態序列。標註問題的目的在於學習一個模型,使它能夠對觀測序列給出標記序列作為預測。 標註常用的統計學習方法有:隱馬爾可夫模型,條件隨機場。 舉例:給定一個由單片語成的句子,對這個句子中的每一個單詞

模型(HMM)

宣告:          1,本篇為個人對《2012.李航.統計學習方法.pdf》的學習總結,不得用作商用,歡迎轉載,但請註明出處(即:本帖地址)。          2,由於本人在學習初始時有很多數學知識都已忘記,所以為了弄懂其中的內容查閱了很多資料,所以裡面應該會有引用

詳解模型(HMM)中的維特比演算法

筆記轉載於GitHub專案:https://github.com/NLP-LOVE/Introduction-NLP 4. 隱馬爾可夫模型與序列標註 第3章的n元語法模型從詞語接續的流暢度出發,為全切分詞網中的二元接續打分,進而利用維特比演算法求解似然概率最大的路徑。這種詞語級別的模型無法應對 OOV(Out

中文二階模型2-HMM

在前一篇中介紹了用HMM做中文分詞,對於未登入詞(out-of-vocabulary, OOV)有良好的識別效果,但是缺點也十分明顯——對於詞典中的(in-vocabulary, IV)詞卻未能很好地識別。主要是因為,HMM本質上是一個Bigram的語法模型,未能深層次地考慮上下文(context)。對於此,

基於監督學習的模型(HMM)實現中文

因為語料是分好詞來訓練的,所以程式碼寫起來還算簡單,HMM的引數pi,A,B訓練只是做一個簡單的統計工作 反倒是寫維特比演算法時出了一些問題,因為之前都是紙上談兵,真正寫這個演算法才發現之前有的地方沒有搞明白!! 維特比的演算法大致如下: 注:下面[]中代表下標

轉:從頭開始編寫基於隱含模型HMM中文

lan reverse single trim 地址 note str rip resources http://blog.csdn.net/guixunlong/article/details/8925990 從頭開始編寫基於隱含馬爾可夫模型HMM的中文分詞器之一 - 資

模型HMM)和 jieba原始碼的理解

在理解隱馬爾可夫模型(HMM)時,看到的很好的部落格,記錄一下: 1. 隱馬爾可夫模型(HMM) - 1 - 基本概念:http://blog.csdn.net/xueyingxue001/article/details/51435728 2.隱馬爾可夫模型(HMM) - 2 -

統計學習方法-李航-筆記總結十、模型

本文是李航老師《統計學習方法》第十章的筆記,歡迎大佬巨佬們交流。 主要參考部落格: https://www.cnblogs.com/YongSun/p/4767667.html https://www.cnblogs.com/naonaoling/p/5701634.html htt

NLP揭祕模型神祕面紗系列文章(二)

作者:白寧超 2016年7月11日15:31:11 摘要:最早接觸馬爾可夫模型的定義源於吳軍先生《數學之美》一書,起初覺得深奧難懂且無什麼用場。直到學習自然語言處理時,才真正使用到隱馬爾可夫模型,並體會到此模型的妙用之處。馬爾可夫模型在處理序列分類時具體強大的功能,諸如解決:詞類標註、語音識別、句

NLP揭祕模型神祕面紗系列文章(一)

作者:白寧超 2016年7月10日20:34:20 摘要:最早接觸馬爾可夫模型的定義源於吳軍先生《數學之美》一書,起初覺得深奧難懂且無什麼用場。直到學習自然語言處理時,才真正使用到隱馬爾可夫模型,並體會到此模型的妙用之處。馬爾可夫模型在處理序列分類時具體強大的功能,諸如解決:詞類標註、語音識別、句

NLP揭祕模型神祕面紗系列文章(三)

作者:白寧超 2016年7月11日22:54:57 摘要:最早接觸馬爾可夫模型的定義源於吳軍先生《數學之美》一書,起初覺得深奧難懂且無什麼用場。直到學習自然語言處理時,才真正使用到隱馬爾可夫模型,並體會到此模型的妙用之處。馬爾可夫模型在處理序列分類時具體強大的功能,諸如解決:詞類標註、語音識別、句

NLP揭祕模型神祕面紗系列文章(五)

作者:白寧超 2016年7月12日14:28:10 摘要:最早接觸馬爾可夫模型的定義源於吳軍先生《數學之美》一書,起初覺得深奧難懂且無什麼用場。直到學習自然語言處理時,才真正使用到隱馬爾可夫模型,並體會到此模型的妙用之處。馬爾可夫模型在處理序列分類時具體強大的功能,諸如解決:詞類標註、語音識別、句

NLP揭祕模型神祕面紗系列文章(四)

作者:白寧超 2016年7月12日14:08:28 摘要:最早接觸馬爾可夫模型的定義源於吳軍先生《數學之美》一書,起初覺得深奧難懂且無什麼用場。直到學習自然語言處理時,才真正使用到隱馬爾可夫模型,並體會到此模型的妙用之處。馬爾可夫模型在處理序列分類時具體強大的功能,諸如解決:詞類標註、語音識別、句

中文 NLP(3) -- 四大概率演算法模型模型 HMM 和 維特比演算法 Viterbi

之前說過,基於NLP處理的演算法思想目前主要有兩大流派:統計論流派和深度學習流派。而在統計論中,常用的 4 大概率模型分別是 樸素貝葉斯模型,隱馬爾科夫模型,最大熵模型和條件隨機場模型。 對於樸素貝葉斯模型,前面已經多次打過交道,原理也相對簡單。這裡解析第二大模型 -- 隱