用CRF做命名实体识别——NER系列(三)
在上一篇文章《用隱馬爾可夫模型(HMM)做命名實體識別——NER系列(二)》中,我們使用HMM模型來做命名實體識別,將問題轉化為統計概率問題,進行求解。顯然,它的效果是非常有限的。
在深度學習技術火起來之前,主流的、最有效的方法,就是CRF(條件隨機場)模型。本文不對CRF模型進行展開講解,而是結合我之前參加的CCF BDCI的其中一個賽題,直接用CRF++工具進行實戰。下面直接進入正題。
1.賽題解讀
賽題介紹:https://www.datafountain.cn/competitions/269/details/rule
總結一下,這個題目要求我們對數據集中的每條記錄,提取出正文中的主要機構實體,判斷這些機構的風險等級(中性,正向或負向),并為每個實體生成相應的摘要和關鍵詞。
我接下來主要講提取實體這一部分,用的是CRF模型,訓練直接使用CRF++工具(http://taku910.github.io/crfpp/)(似乎被墻了?)。
2.算法流程圖
3.算法說明
3.1 定義實體標注集
為了確保最后的機構實體識別準確度,使用BMEWO標注集,各個標注的意義如下:
B:實體的開頭
M:實體的中間部分
E:實體的結束
W:單獨成實體
O:句子的其它成分
比如下面這個句子(已做分詞處理):
山西????? 相立????? 山泉????? 飲品????? 開發????? 有限公司???? 生產????? 的桶裝? 飲用水? 檢出????? 銅綠????? 假?? 單胞菌
背后的標注為:
山西/B? 相立/M 山泉/M 飲品/M 開發/M 有限公司/E? 生產/O? 的/O 桶裝/O???? 飲用水/O???? 檢出/O? 銅綠/O?? 假/O 單胞菌/O
3.2訓練文本、測試文本預處理
對訓練文本進行中文分詞、去除停用詞的處理,并根據上述的標注集進行標注。同時,除了詞本身,還引入了4個特征:
特征①:【詞性】,用jieba分詞識別出來的詞性
特征②:【是否是特征詞】,該詞是特征詞,標記1;不是特征詞,標記0。這里的特征詞是指“實體通常的結尾詞”,比如“有限公司”,“藥監局”,“超市”等等,這些特征詞來源于兩個地方:
特征③:【是否是地點】,該詞是地點,標記為isloc;該詞不是地點,標記為notloc。這里的地點信息我們是從jieba的分詞詞性標注功能中得到的,詞性標注為ns的一般是地點。
特征④:【是否是句子結束】,該詞是這個句子的結束詞,標記為isend;否則標記為notend。
訓練文本在經過預處理之后,格式如下:
寧夏????? ns?? 0???? isloc????? notend B
物美????? nz?? 0???? notloc? notend M
超市????? v???? 1???? notloc? notend M
有限公司??? n???? 1???? notloc? notend M
森林公園??? n???? 0???? notloc? notend M
店?? n???? 1???? notloc? isend??? E
其中,第一列為詞本身,第二列為特征①,第三列為特征②,第四列為特征③,第五列為特征④,第六列列為正確標注。
測試文本的預處理和上面的基本一樣,區別在于,測試文本沒有正確的實體標注,所以測試文本的預處理文件只有五列。最后我們要用CRF模型預測的是第六列—標注。
3.3訓練CRF模型
CRF模型的訓練,需要一個特征模板,以便能夠自動在訓練文本中提取特征函數,特征模板的定義直接決定了最后的識別效果。
針對此次的機構實體,我們定義了幾種特征模板,最終選擇了以下模板:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | # Unigram ? U01:%x[-2,0] ? U02:%x[-1,0] ? U03:%x[0,0] ? U04:%x[1,0] ? U05:%x[2,0] ? U06:%x[-2,0]/%x[-1,0]/%x[0,0] ? U07:%x[-1,0]/%x[0,0]/%x[1,0] ? U08:%x[0,0]/%x[1,0]/%x[2,0] ? U09:%x[-1,0]/%x[0,0] ? U10:%x[0,0]/%x[1,0] ? U11:%x[-1,1]/%x[0,1]/%x[1,1] ? U12:%x[-1,1]/%x[0,1] ? U13:%x[0,1]/%x[1,1] ? U14:%x[0,1]/%x[0,2] ? U15:%x[-1,1]/%x[0,2] ? U16:%x[-2,1]/%x[-1,1]/%x[0,2] ? U17:%x[-1,1]/%x[0,2]/%x[1,1] ? U18:%x[0,2]/%x[1,1]/%x[2,1] ? U19:%x[0,0]/%x[0,2] ? U20:%x[-1,0]/%x[0,2] ? U21:%x[-2,0]/%x[-1,0]/%x[0,2] ? U22:%x[-1,0]/%x[0,2]/%x[1,0] ? U23:%x[0,2]/%x[1,0]/%x[2,0] ? # Bigram ? B |
下面解釋一下上述特征模板:
①Unigram類型
每一行%x[#,#]生成一個CRFs中的點(state)函數: f(s, o), 其中s為t時刻的標簽(output),o為t時刻的上下文以及特征信息。
比如:U06:%x[-2,0]/%x[-1,0]/%x[0,0]
U06是指這個特征模板的編號,對于%x[-2,0]而言,%x是指找到的字符;[-2,0]是定位信息,其中中括號里面的-2是指當前詞的前兩個詞,0是指第0列。后面用/連接的是多個特征的組合。
對于以下的訓練文本:
寧夏???? ns?? 0???? isloc????? notend B
物美???? nz?? 0???? notloc? notend M
超市???? v???? 1???? notloc? notend M
有限公司?? n???? 1???? notloc? notend M
森林公園?? n???? 0???? notloc? notend M
店? n???? 1???? notloc? isend??? E
假如當前識別到第三行,則U06:%x[-2,0]/%x[-1,0]/%x[0,0]對應識別出來的文本為寧夏/物美/超市。
這就相當于我們在文本中找到的一條特征。
②Bigram類型
每一行%x[#,#]生成一個CRFs中的邊(Edge)函數:f(s’, s, o), 其中s’為t – 1時刻的標簽.也就是說,Bigram類型與Unigram大致機同,只是還要考慮到t – 1時刻的標簽.這里只寫一個B,默認生成f(s’, s).
有了特征模板以及訓練文本文件,就可以進行CRF模型訓練了,我們采用了CRF++這個開源工具包進行訓練,使用默認參數,最終模型識別出來的特征有11616755條。
3.4預測、生成實體
有了上述預處理測試文本和訓練生成的CRF模型,我們可以進行測試文本的標簽預測,生成crf_test_output.txt。
由于crf_test_output.txt里面預測的是每個詞背后的標注,我們還要做一個后處理工作才能把真正的實體提取出來。
用正則表達式B+M*E+或者W匹配文本,然后將其背后的文字提取出來,就是識別出來的機構實體。
3.4效果和缺點
在使用CRF模型之后,我們得到了不錯的效果。線下訓練文本的實體召回率可以達到91.3%,另外,識別出來的無效實體也少了很多。
和基于規則的實體識別相比,它有著以下優點:
- 通過特征模板,能夠最大限度的挖掘文本的特征,而不需要人工提取。
- 能夠考慮大量的上下文信息、特征。
- 考慮了相鄰詞的標注信息,這是傳統的最大熵算法所不具備的。
- 和神經網絡模型相比,CRF模型的可解釋性強,具體到每一個特征都有可以解釋的意義。因此調整起來比較容易。
當然,這個模型也不是完美的,比如,我們訓練的這個模型就比較“看重”機構特征詞。舉個例子,如果“下屬公司”單獨出現,則它也可能會被識別為機構名,需要我們人工定義一些規則將其去除。
CRF++工具的使用就沒有介紹了,訓練的過程只需要預處理語料以及模板文件,預處理語料格式和模板文件,在上文已經體現出來了,感興趣的朋友,缺少語料或者工具,可以找我要。
代碼和語料:
https://www.lookfor404.com/命名實體識別的語料和代碼/
?
https://www.lookfor404.com/%e7%94%a8crf%e5%81%9a%e5%91%bd%e5%90%8d%e5%ae%9e%e4%bd%93%e8%af%86%e5%88%ab-ner%e7%b3%bb%e5%88%97%ef%bc%88%e4%b8%89%ef%bc%89/
總結
以上是生活随笔為你收集整理的用CRF做命名实体识别——NER系列(三)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PHP服务Fcgi进程及PHP解析优化
- 下一篇: 【译】深入理解LSTM网络