http://www.hankcs.com/nlp/ner/place-names-to-identify-actual-hmm-viterbi-role-labeling.html
命名實體識別(Named Entity Recognition)也是自然語言處理中的一個難關,特別是中文這樣沒有大小寫等固定形態的語言。上次介紹過《實戰HMM-Viterbi角色標注中國人名識別》,這次基于類似的原理,為HanLP實現中文地址地名(NS)的自動識別。
原理
訓練
對熟語料自動角色標注,統計單詞的角色頻次、角色的轉移概率等,訓練出一個模型,同時總結一些可用的模式串。
識別
根據上述模型,利用HMM-Viterbi算法標注陌生文本的粗分結果,利用Aho-Corasick算法模式匹配,匹配出可能的地址,將其送入第二層隱馬爾可夫模型中。
實戰
訓練
自動角色標注
《基于層疊隱馬爾可夫模型的中文命名實體識別.pdf》中使用如下地名識別角色:
我在此基礎上拓充了CDE分別為三字地名的三個字位,H為中國地名的后綴,G為整個地址,這樣一般最多可以識別6字地名(CDE地名+三字后綴),比論文有所改進。
通過少量的代碼即可自動對熟語料進行角色標注,比如對于這一句人民日報2014切分語料中的句子:
1 | 王先東/nr?來自/v?湖北/ns?荊門/ns?,/w?在/p?佛山市/ns?[南海區/ns?大瀝鎮/ns]/nz?某/rz?物業公司/nis?做/v?保安/b |
逐步處理得到
1 2 3 4 5 6 7 | 原始語料?[未##人/nr,?來自/v,?湖北/ns,?的/ude1,?荊門/ns,?,/w,?在/p,?烏魯木齊市/ns,?[南海區/ns?大瀝鎮/ns]/ns,?某/rz,?物業公司/nis,?做/v,?保安/b] 添加首尾?[始##始/S,?未##人/nr,?來自/v,?湖北/ns,?的/ude1,?荊門/ns,?,/w,?在/p,?烏魯木齊市/ns,?[南海區/ns?大瀝鎮/ns]/ns,?某/rz,?物業公司/nis,?做/v,?保安/b,?末##末/Z] 標注上文?[始##始/S,?未##人/nr,?來自/A,?湖北/ns,?的/A,?荊門/ns,?,/w,?在/A,?烏魯木齊市/ns,?[南海區/ns?大瀝鎮/ns]/ns,?某/rz,?物業公司/nis,?做/v,?保安/b,?末##末/Z] 標注下文?[始##始/S,?未##人/nr,?來自/A,?湖北/ns,?的/B,?荊門/ns,?,/B,?在/A,?烏魯木齊市/ns,?[南海區/ns?大瀝鎮/ns]/ns,?某/B,?物業公司/nis,?做/v,?保安/b,?末##末/Z] 標注中間?[始##始/S,?未##人/nr,?來自/A,?湖北/ns,?的/X,?荊門/ns,?,/B,?在/A,?烏魯木齊市/ns,?[南海區/ns?大瀝鎮/ns]/ns,?某/B,?物業公司/nis,?做/v,?保安/b,?末##末/Z] 拆分地名?[始##始/S,?未##人/nr,?來自/A,?湖北/ns,?的/X,?荊門/ns,?,/B,?在/A,?烏魯木齊市/ns,?南海區/ns,?大瀝鎮/ns,?某/B,?物業公司/nis,?做/v,?保安/b,?末##末/Z] 處理整個?[始##始/S,?未##人/Z,?來自/A,?湖北/G,?的/X,?荊/C,?門/H,?,/B,?在/A,?烏魯木齊/G,?市/H,?南/C,?海/D,?區/H,?大/C,?瀝/D,?鎮/H,?某/B,?物業公司/Z,?做/Z,?保安/Z,?末##末/Z] |
統計詞頻
在對所有熟語料句子執行自動標注后,即可統計每一個非Z詞語的詞頻,得到一個角色詞典:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 位于?A?1660?X?93?B?33 位列?B?17?A?13?X?1 位居?B?25?A?14?X?1 位次?B?1 位置?B?5?A?1 低?B?9 低于?A?18?B?2 低產田?B?1 低價?B?1 低估?A?5 低保?B?3 低保戶?B?3 低效?B?1 低溫?B?3 低熱值?B?1 低碳?B?27 低空?B?2 低調?B?5 低速?B?3 低階煤?B?1 住?A?81?B?53 住友?B?1 住在?A?271?B?1 |
統計轉移矩陣
轉移矩陣指的是從一個角色標簽轉移到另一個角色的頻次,利用它和角色詞頻可以計算出HMM中的初始概率、轉移概率、發射概率,進而完成求解。關于維特比算法和實現請參考《通用維特比算法的Java實現》。
這里對人民日報2014切分語料訓練出如下轉移矩陣:
?
?
識別
例子
以“南翔向寧夏固原市彭陽縣紅河鎮黑牛溝村捐贈了挖掘機”為例,不進行地名識別時,會得出下列輸出:
1 | [南翔/ns,?向/p,?寧夏/ns,?固原市/ns,?彭/nz,?陽/ag,?縣/n,?紅/a,?河鎮/ns,?黑/a,?牛/n,?溝/n,?村/n,?捐贈/v,?了/ule,?挖掘機/n] |
上例中“寧夏”“固原市”等屬于常用地名,因此被收錄到核心詞典中,此處表現出正確的分詞結果。但是像“彭陽縣”“紅河鎮”“黑牛溝村”等地名屬于非常小的地方,沒有被詞典收錄,自然也沒法得出正確的分詞結果。
角色標注
1 2 | 地名角色觀察:[??Z?41339414?][南翔?H?1000?][向?A?1076?B?115?X?70?C?49?D?5?][寧夏?H?1000?][固原市?H?1000?][彭?C?85?][陽?D?1255?C?81?B?1?][縣?H?6878?B?25?A?23?D?19?X?3?C?2?][紅?C?1000?B?46?A?3?][河鎮?H?1000?][黑?C?960?B?25?][牛?D?24?C?8?B?7?][溝?H?107?D?90?E?36?C?27?B?14?A?3?][村?H?4467?D?68?B?28?A?8?C?3?][捐贈?B?10?A?1?][了?A?4115?B?97?][挖掘機?B?1?][??Z?41339414?] 地名角色標注:[?/Z?,南翔/H?,向/B?,寧夏/H?,固原市/H?,彭/C?,陽/D?,縣/H?,紅/C?,河鎮/H?,黑/C?,牛/D?,溝/E?,村/H?,捐贈/B?,了/A?,挖掘機/B?,?/Z] |
模式匹配
利用Aho-Corasick算法模式匹配如下模式串:
1 2 3 4 | ???????? CH ???????? CDH ???????? CDEH ???????? GH |
得到如下地名:
1 2 3 | 識別出地名:彭陽縣?CDH 識別出地名:紅河鎮?CH 識別出地名:黑牛溝村?CDEH |
第二層隱馬模型細分
其實這應該算是第三層隱馬模型,因為地名識別中也用到了一次HMM,并且那次的輸出是這次的輸入。細分之后得出最終的結果:
1 | [南翔/ns,?向/p,?寧夏/ns,?固原市/ns,?彭陽縣/ns,?紅河鎮/ns,?黑牛溝村/ns,?捐贈/v,?了/ule,?挖掘機/n] |
總結
HMM模型可以解決很多問題,將多個HMM模型層疊起來,可以發揮出更加精準的效果。
不過2元文法依然會有誤命中的情況,事實上,一些高頻地名已經收錄到核心詞典和用戶自定義詞典中。所以HanLP的默認配置關閉了地名識別,僅僅在一些極端情況下(專門提取縣級地址)交由用戶打開。
目錄
- 原理
- 訓練
- 識別
- 實戰
- 訓練
- 自動角色標注
- 統計詞頻
- 統計轉移矩陣
- 識別
- 角色標注
- 模式匹配
- 第二層隱馬模型細分
- 總結
轉載請注明:碼農場???實戰HMM-Viterbi角色標注地名識別