中文分詞之HMM模型詳解

文章轉載自: http://yanyiwu.com/work/2014/04/07/hmm-segment-xiangjie.html

HMM(Hidden Markov Model): 隱式馬爾科夫模型。

HMM模型可以應用在很多領域,所以它的模型參數描述一般都比較抽象,以下篇幅針對HMM的模型參數介紹直接使用它在中文分詞中的實際含義來講:

HMM的典型介紹就是這個模型是一個五元組:

  • StatusSet: 狀態值集合
  • ObservedSet: 觀察值集合
  • TransProbMatrix: 轉移概率矩陣
  • EmitProbMatrix: 發射概率矩陣
  • InitStatus: 初始狀態分布

HMM模型可以用來解決三種問題:

  1. 參數(StatusSet, TransProbMatrix, EmitRobMatrix, InitStatus)已知的情況下,求解觀察值序列。(Forward-backward算法)
  2. 參數(ObservedSet, TransProbMatrix, EmitRobMatrix, InitStatus)已知的情況下,求解狀態值序列。(viterbi算法)
  3. 參數(ObservedSet)已知的情況下,求解(TransProbMatrix, EmitRobMatrix, InitStatus)。(Baum-Welch算法)

其中,第三種問題最玄乎也最不常用,第二種問題最常用,【中文分詞】,【語音識別】, 【新詞發現】, 【詞性標注】 都有它的一席之地。所以本文主要介紹第二種問題,即【viterbi算法求解狀態值序列】的方法。

五元組參數在中文分詞中的具體含義

接下來我們講實的,不講虛的,針對中文分詞應用,直接給五元組參數賦予具體含義:

StatusSet & ObservedSet

狀態值集合為(B, M, E, S): {B:begin, M:middle, E:end, S:single}。分別代表每個狀態代表的是該字在詞語中的位置,B代表該字是詞語中的起始字,M代表是詞語中的中間字,E代表是詞語中的結束字,S則代表是單字成詞。

觀察值集合為就是所有漢字(東南西北你我他…),甚至包括標點符號所組成的集合。

狀態值也就是我們要求的值,在HMM模型中文分詞中,我們的輸入是一個句子(也就是觀察值序列),輸出是這個句子中每個字的狀態值。比如:

小明碩士畢業于中國科學院計算所

輸出的狀態序列為

BEBEBMEBEBMEBES

根據這個狀態序列我們可以進行切詞:

BE/BE/BME/BE/BME/BE/S

所以切詞結果如下:

小明/碩士/畢業于/中國/科學院/計算/所

同時我們可以注意到:

B后面只可能接(M or E),不可能接(B or S)。而M后面也只可能接(M or E),不可能接(B, S)

沒錯,就是這么簡單,現在輸入輸出都明確了,下文講講輸入和輸出之間的具體過程,里面究竟發生了什么不可告人的秘密,請看下文:

上文只介紹了五元組中的兩元【StatusSet, ObservedSet】,下文介紹剩下的三元【InitStatus, TransProbMatrix, EmitProbMatrix】。

這五元的關系是通過一個叫Viterbi的算法串接起來,ObservedSet序列值是Viterbi的輸入,而StatusSet序列值是Viterbi的輸出,輸入和輸出之間Viterbi算法還需要借助三個模型參數,分別是InitStatus, TransProbMatrix, EmitProbMatrix,接下來一一講解:

InitStatus

初始狀態概率分布是最好理解的,可以示例如下:

#B
-0.26268660809250016
#E
-3.14e+100
#M
-3.14e+100
#S
-1.4652633398537678

示例數值是對概率值取對數之后的結果(可以讓概率相乘的計算變成對數相加),其中-3.14e+100作為負無窮,也就是對應的概率值是0。下同。

也就是句子的第一個字屬于{B,E,M,S}這四種狀態的概率,如上可以看出,E和M的概率都是0,這和實際相符合,開頭的第一個字只可能是詞語的首字(B),或者是單字成詞(S)。

TransProbMatrix

轉移概率是馬爾科夫鏈很重要的一個知識點,大學里面學過概率論的人都知道,馬爾科夫鏈最大的特點就是當前T=i時刻的狀態Status(i),只和T=i時刻之前的n個狀態有關。也就是:

{Status(i-1), Status(i-2), Status(i-3), ... Status(i - n)}

更進一步的說,HMM模型有三個基本假設(具體哪三個請看文末備注)作為模型的前提,其中有個【有限歷史性假設】,也就是馬爾科夫鏈的n=1。即Status(i)只和Status(i-1)相關,這個假設能大大簡化問題。

回過頭看TransProbMatrix,其實就是一個4x4(4就是狀態值集合的大小)的二維矩陣,示例如下:

矩陣的橫坐標和縱坐標順序是BEMS x BEMS。(數值是概率求對數后的值,別忘了。)

-3.14e+100 -0.510825623765990 -0.916290731874155 -3.14e+100
-0.5897149736854513 -3.14e+100 -3.14e+100 -0.8085250474669937
-3.14e+100 -0.33344856811948514 -1.2603623820268226 -3.14e+100
-0.7211965654669841 -3.14e+100 -3.14e+100 -0.6658631448798212

比如TransProbMatrix[0][0]代表的含義就是從狀態B轉移到狀態B的概率,由

TransProbMatrix[0][0] = -3.14e+100

可知,這個轉移概率是0,這符合常理。由狀態各自的含義可知,狀態B的下一個狀態只可能是ME,不可能是BS,所以不可能的轉移對應的概率都是0,也就是對數值負無窮,在此記為-3.14e+100

由上TransProbMatrix矩陣可知,對于各個狀態可能轉移的下一狀態,且轉移概率對應如下:

#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

EmitProbMatrix

這里的發射概率(EmitProb)其實也是一個條件概率而已,根據HMM模型三個基本假設(哪三個請看文末備注)里的【觀察值獨立性假設】,觀察值只取決于當前狀態值,也就是:

P(Observed[i], Status[j]) = P(Status[j]) * P(Observed[i]|Status[j])

其中P(Observed[i]|Status[j])這個值就是從EmitProbMatrix中獲取。

EmitProbMatrix示例如下:

#B
耀:-10.460283,涉:-8.766406,談:-8.039065,伊:-7.682602,洞:-8.668696,...
#E
耀:-9.266706,涉:-9.096474,談:-8.435707,伊:-10.223786,洞:-8.366213,...
#M
耀:-8.47651,涉:-10.560093,談:-8.345223,伊:-8.021847,洞:-9.547990,....
#S:-10.005820,涉:-10.523076,唎:-15.269250,禑:-17.215160,洞:-8.369527...

雖然EmitProbMatrix也稱為矩陣,這個矩陣太稀疏了,實際工程中一般是將上面四行發射轉移概率存儲為4個Map,詳見代碼HMMSegment。

到此,已經介紹完HMM模型的五元參數,假設現在手頭上已經有這些參數的具體概率值,并且已經加載進來,(也就是有該模型的字典了,詳見HMMDict里面的hmm_model.utf8),那么我們只剩下Viterbi這個算法函數,這個模型就算可以開始使用了。所以接下來講講Viterbi算法。

HMM中文分詞之Viterbi算法

輸入樣例:

小明碩士畢業于中國科學院計算所

Viterbi算法計算過程如下:

定義變量

二維數組 weight[4][15],4是狀態數(0:B,1:E,2:M,3:S),15是輸入句子的字數。比如 weight[0][2] 代表 狀態B的條件下,出現'碩'這個字的可能性。

二維數組 path[4][15],4是狀態數(0:B,1:E,2:M,3:S),15是輸入句子的字數。比如 path[0][2] 代表 weight[0][2]取到最大時,前一個字的狀態,比如 path[0][2] = 1, 則代表 weight[0][2]取到最大時,前一個字(也就是)的狀態是E。記錄前一個字的狀態是為了使用viterbi算法計算完整個 weight[4][15] 之后,能對輸入句子從右向左地回溯回來,找出對應的狀態序列。

使用InitStatus對weight二維數組進行初始化

已知InitStatus如下:

#B
-0.26268660809250016
#E
-3.14e+100
#M
-3.14e+100
#S
-1.4652633398537678

且由EmitProbMatrix可以得出

Status(B) -> Observed(小)  :  -5.79545
Status(E) -> Observed(小)  :  -7.36797
Status(M) -> Observed(小)  :  -5.09518
Status(S) -> Observed(小)  :  -6.2475

所以可以初始化 weight[i][0] 的值如下:

weight[0][0] = -0.26268660809250016 + -5.79545 = -6.05814
weight[1][0] = -3.14e+100 + -7.36797 = -3.14e+100
weight[2][0] = -3.14e+100 + -5.09518 = -3.14e+100
weight[3][0] = -1.4652633398537678 + -6.2475 = -7.71276

注意上式計算的時候是相加而不是相乘,因為之前取過對數的原因。

遍歷句子計算整個weight二維數組

//遍歷句子,下標i從1開始是因為剛才初始化的時候已經對0初始化結束了
for(size_t i = 1; i < 15; i++)
{// 遍歷可能的狀態for(size_t j = 0; j < 4; j++) {weight[j][i] = MIN_DOUBLE;path[j][i] = -1;//遍歷前一個字可能的狀態for(size_t k = 0; k < 4; k++){double tmp = weight[k][i-1] + _transProb[k][j] + _emitProb[j][sentence[i]];if(tmp > weight[j][i]) // 找出最大的weight[j][i]值{weight[j][i] = tmp;path[j][i] = k;}}}
}

如此遍歷下來,weight[4][15]path[4][15] 就都計算完畢。

確定邊界條件和路徑回溯

邊界條件如下:

對于每個句子,最后一個字的狀態只可能是 E 或者 S,不可能是 M 或者 B。

所以在本文的例子中我們只需要比較 weight[1(E)][14]weight[3(S)][14] 的大小即可。

在本例中:

weight[1][14] = -102.492;
weight[3][14] = -101.632;

所以 S > E,也就是對于路徑回溯的起點是 path[3][14]

回溯的路徑是:

SEBEMBEBEMBEBEB

倒序一下就是:

BE/BE/BME/BE/BME/BE/S

所以切詞結果就是:

小明/碩士/畢業于/中國/科學院/計算/所

到此,一個HMM模型中文分詞算法過程就闡述完畢了。

也就是給定我們一個模型,我們對模型進行載入完畢之后,只要運行一遍Viterbi算法,就可以找出每個字對應的狀態,根據狀態也就可以對句子進行分詞。

模型的訓練問題

以上講的前提是基于模型來進行切詞,也就是假設我們手頭上的HMM模型已經是被訓練好了的(也就是InitStatus, TransProbMatrix, EmitProbMatrix這三個模型的關鍵參數都是已知的),沒有涉及到這三個參數是如何得到的。這三個參數其實也是基于已分詞完畢的語料進行統計計算,計算出相應的頻率和條件概率就可以算出這三個參數。具體在此就不講了。

備注

HMM模型的三個基本假設如下:

  • 有限歷史性假設:
P(Status[i]|Status[i-1],Status[i-2],... Status[1]) = P(Status[i]|Status[i-1])
  • 齊次性假設(狀態和當前時刻無關):
P(Status[i]|Status[i-1]) = P(Status[j]|Status[j-1])
  • 觀察值獨立性假設(觀察值只取決于當前狀態值):
P(Observed[i]|Status[i],Status[i-1],...,Status[1]) = P(Observed[i]|Status[i])

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/284405.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/284405.shtml
英文地址,請注明出處:http://en.pswp.cn/news/284405.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【ArcGIS微課1000例】0035:地圖面狀符號設計教程

地圖符號是表示地圖內容的基本手段,它由形狀不同、大小不一、色彩有別的圖形和文字組成。 地圖符號是地圖的語言,是一種圖形語言。它與文字語言相比較,最大的特點是形象直觀,一目了然。 本文講解ArcGIS中面狀符號設計方法。 文章目錄 一、新建符號樣式二、面狀符號設計1. 斜…

MySQL奪命15問,你能堅持到第幾問?

前言 MySQL在面試中經常被問到&#xff0c;本文總結了面試中的經典問題。 1. 數據庫三大范式是什么&#xff1f; 第一范式&#xff1a;每個列都不可以再拆分。 第二范式&#xff1a;在第一范式的基礎上&#xff0c;非主鍵列完全依賴于主鍵&#xff0c;而不能是依賴于主鍵的一部…

ios元素定位

原文地址http://www.cnblogs.com/meitian/p/7373460.html 第一種&#xff1a;通過Appium1.6的Inspector來查看 具體安裝方式前面的隨筆已經介紹了&#xff1a;http://www.cnblogs.com/meitian/p/7360017.html可以通過定位找到元素xpath或name個人不推薦用這個方法&#xff0c;實…

分治法——循環賽日程表

1、問題描述&#xff1a;有n2^k個遠動員選手&#xff0c;設計比賽日程表實現&#xff1a;&#xff08;1&#xff09;每個選手必須與n-1個選手比賽&#xff08;2&#xff09;每個選手一天只比賽一場&#xff08;3&#xff09;比賽共進行n-1天輸入&#xff1a;n人輸出&#xff1a…

使用 LSM-Tree 思想基于.NET 6.0 C# 寫個 KV 數據庫(案例版)

文章有點長&#xff0c;耐心看完應該可以懂實際原理到底是啥子。這是一個KV數據庫的C#實現&#xff0c;目前用.NET 6.0實現的&#xff0c;目前算是屬于雛形&#xff0c;骨架都已經完備&#xff0c;畢竟剛完工不到一星期。當然&#xff0c;這個其實也算是NoSQL的雛形&#xff0c…

35.使用攔截器實現權限驗證

轉自&#xff1a;https://wenku.baidu.com/view/84fa86ae360cba1aa911da02.html 為了說明此問題&#xff0c;我們建立struts2auth項目&#xff0c;流程圖如下&#xff1a; 簡短說明&#xff1a;當我們訪問main.jsp頁面&#xff0c;并試圖通過此頁面中的鏈接地址&#xff1a;not…

如何保證緩存和數據庫的一致性?

1. 問題分析 2. Cache-Aside 2.1 讀緩存 2.2 寫緩存 2.3 延遲雙刪 2.4 如何確保原子性 3. Read-Through/Write-Through 3.1 Read-Through 3.2 Write-Through 4. Write Behind 很多小伙伴在面試的時候&#xff0c;應該都遇到過類似的問題&#xff0c;如何確保緩存和數據庫…

Pressed狀態和clickable,duplicateParentState的關系

做Android開發的人都用過Selector,可以方便的實現View在不同狀態下的背景。不過&#xff0c;相信大部分開發者遇到過和我一樣的問題&#xff0c;本文會從源碼角度&#xff0c;解釋這些問題。 首先&#xff0c;這里簡單描述一下&#xff0c;我遇到的問題&#xff1a; 界面上有個…

Hbase筆記4 java操作Hbase

暫無轉載于:https://www.cnblogs.com/mrxiaohe/p/6512481.html

【招聘(南京)】 慧咨環球南京研發中心 .NET和Blazor 前端

主要的亮點快速增長的、產品導向型的全球性科技公司設計和開發市場領先的軟件解決方案WLB — 工作生活相平衡澳洲排名前五的軟件公司混合辦公 — 3天在家辦公&#xff0c;2天在辦公室辦公在C#和.NET開發&#xff0c;企業級系統研發&#xff0c;軟件工程方面有長期的優秀實踐和技…

用Python+Django在Eclipse環境下開發web網站【轉】

一、創建一個項目如果這是你第一次使用Django&#xff0c;那么你必須進行一些初始設置。也就是通過自動生成代碼來建立一個Django項目--一個Django項目的設置集&#xff0c;包含了數據庫配置、Django詳細選項設置和應用 特性配置&#xff0c;具體操作步驟如下所示。 1.新建Djan…

[轉]數據結構KMP算法配圖詳解(超詳細)

KMP算法配圖詳解 前言 KMP算法是我們數據結構串中最難也是最重要的算法。難是因為KMP算法的代碼很優美簡潔干練&#xff0c;但里面包含著非常深的思維。真正理解代碼的人可以說對KMP算法的了解已經相當深入了。而且這個算法的不少東西的確不容易講懂&#xff0c;很多正規的書本…

BGP-MED-2

BGP-MED-2如圖&#xff1a;當AS100去往AS300的60、10的網絡時&#xff0c;60走R3&#xff0c;10走R1!使用MED屬性影響選路&#xff01; R2的配置 bgp 200peer 1.1.1.1 as-number 100 peer 1.1.1.1 ebgp-max-hop 255 peer 1.1.1.1 connect-interface LoopBack0peer 4.4.4.4 as-n…

WPF 實現 Gitee 氣泡菜單(一)

WPF 實現 Gitee 氣泡菜單&#xff08;一&#xff09;氣泡菜單&#xff08;一&#xff09;作者&#xff1a;WPFDevelopersOrg原文鏈接&#xff1a; https://github.com/WPFDevelopersOrg/WPFDevelopers框架使用大于等于.NET40&#xff1b;Visual Studio 2022;項目使用 MIT 開…

[轉]LVS負載均衡(LVS簡介、三種工作模式、十種調度算法)

一、LVS簡介 LVS&#xff08;Linux Virtual Server&#xff09;即Linux虛擬服務器&#xff0c;是由章文嵩博士主導的開源負載均衡項目&#xff0c;目前LVS已經被集成到Linux內核模塊中。該項目在Linux內核中實現了基于IP的數據請求負載均衡調度方案&#xff0c;其體系結構如圖1…

一張圖看懂微軟Power BI系列組件

一、Power BI簡介 Power BI是微軟最新的商業智能&#xff08;BI&#xff09;概念&#xff0c;它包含了一系列的組件和工具。話不多說&#xff0c;直接上圖吧&#xff1a; Power BI的核心理念就是讓我們用戶不需要強大的技術背景&#xff0c;只需要掌握Excel這樣簡單的工具就能快…

互聯網項目總結

2019獨角獸企業重金招聘Python工程師標準>>> 從去年年底開始專門被分配到互聯網小組做項目&#xff0c;一直想做個總結&#xff0c;但是苦于太貪玩。好吧&#xff0c;借著小組技術交流來一發。這里只對自己新學習的技術或者一些小技巧做簡要概述&#xff0c;不做深究…

【ArcGIS微課1000例】0036:分式標注案例教程

【拓展閱讀】:【ArcGIS Pro微課1000例】0015:ArcGIS Pro中屬性字段分式標注案例教程 文章目錄 1. 符號化2. 分式標注1. 符號化 右鍵數據圖層→符號系統,打開符號系統對話框,住符號系統選擇【唯一值】,字段1選擇NAME。 唯一值標注效果: 2. 分式標注 雙擊打開圖層屬性,切…

【轉】 ConstraintLayout 完全解析 快來優化你的布局吧

轉自&#xff1a; http://blog.csdn.net/lmj623565791/article/details/78011599 本文出自張鴻洋的博客 一、概述 ConstraintLayout出現有一段時間了&#xff0c;不過一直沒有特別去關注&#xff0c;也多多少少看了一些文字介紹&#xff0c;多數都是對使用可視化布局拖拽&#…

IoTDB 的C# 客戶端發布 0.13.0.7

IoTDB C# Client 0.13.0.7 已經發布&#xff0c; 此版本更新的內容為筆者為Apache-IoTDB-Client-CSharp實現了Ado.Net的兼容層&#xff0c;降低了對IoTDB的使用門檻。于此同時&#xff0c; IoTSharp也開始支持了IoTDB的數據入庫&#xff0c;隨著晚些時候IoTSharp 2.7 版本的發布…