使用Java-Hanlp训练CRF模型
文章目錄
- 一、CRF分詞
- 二、CRF模型訓練
- 1、語料庫準備
- 2、詞性標注
- 3、訓練
- 4、結果文件
- 5、BEMS標注
- 三、實驗結果
CRF是序列標注場景中常用的一種語言模型,與基于隱馬爾可夫模型(HMM)的最短路徑分詞、N-最短路徑分詞相比,基于條件隨機場(CRF)的分詞對未登錄詞有更好的支持。CRF的效果比感知機稍好一些,然而訓練速度較慢,也不支持在線學習。
一、CRF分詞
官網給出的CRF分詞方法如下:
public class DemoCRFSegment {public static void main(String[] args){HanLP.Config.ShowTermNature = false; // 關閉詞性顯示Segment segment = new CRFSegment();String[] sentenceArray = new String[]{"HanLP是由一系列模型與算法組成的Java工具包,目標是普及自然語言處理在生產環境中的應用。","鐵桿部隊憤怒情緒集結 馬英九腹背受敵", // 繁體無壓力"馬英九回應連勝文“丐幫說”:稱黨內同志談話應謹慎","高錳酸鉀,強氧化劑,紫紅色晶體,可溶于水,遇乙醇即被還原。常用作消毒劑、水凈化劑、氧化劑、漂白劑、毒氣吸收劑、二氧化碳精制劑等。", // 專業名詞有一定辨識能力"《夜晚的骰子》通過描述淺草的舞女在暗夜中扔骰子的情景,寄托了作者對庶民生活區的情感", // 非新聞語料"這個像是真的[委屈]前面那個打扮太江戶了,一點不上品...@hankcs", // 微博"鼎泰豐的小籠一點味道也沒有...每樣都淡淡的...淡淡的,哪有食堂2A的好次","克里斯蒂娜·克羅爾說:不,我不是虎媽。我全家都熱愛音樂,我也鼓勵他們這么做。","今日APPS:Sago Mini Toolbox培養孩子動手能力","財政部副部長王保安調任國家統計局黨組書記","2.34米男子娶1.53米女粉絲 稱夫妻生活沒問題","你看過穆赫蘭道嗎","樂視超級手機能否承載賈布斯的生態夢"};for (String sentence : sentenceArray){List<Term> termList = segment.seg(sentence);System.out.println(termList);}} }針對項目需求,主要對地址文本進行分詞,但是由于地址文本與一般文本相比,是具有空間結構和空間嵌套關系的字符串,尤其注重對地址元素的抽取和拆分。例如以`湖北省荊州市荊州區荊秘路266-1號`門牌號地址為例,在Hanlp原生訓練的CRF模型下,得到的分詞結果為:
該模型無法區分地址元素【荊州區】【荊秘路】,因此無法滿足實際需要。
本文對其做出的改進為,在默認語料庫添加地址語料庫進行自定義模型訓練。
二、CRF模型訓練
1、語料庫準備
hanlp提供了默認的訓練模型,默認模型訓練語料庫為 OpenCorpus/pku98/199801.txt,隨1.6.2以上版本發布。
語料庫格式為人民日報2014語料格式:
訓練時將滿足上述格式的語料以純文本txt導出到一個目錄下即可。OpenCorpus/pku98/199801.txt即為一個單文檔的例子,可供參考。
2、詞性標注
HanLP使用的HMM詞性標注模型訓練自2014年人民日報切分語料,隨后增加了少量98年人民日報中獨有的詞語。
本文所用到的詞性標注包括:
- ns 地名
- q 量詞
- m 數詞
其余詞性標注集如鏈接所示。
語料庫示例:
3、訓練
CRF模型訓練可以直接使用在hanlp Java API進行,使用CRFSegmenter.train,確定好語料庫和輸出文件路徑即可。
private static final String CWS_MODEL_PATH = "模型輸出路徑/文件名.txt"; public static void main(String[] args) throws IOException {CRFSegmenter segmenter = new CRFSegmenter(null);segmenter.train("語料庫路徑/文件名.txt", CWS_MODEL_PATH);}訓練過程為:
4、結果文件
生成結果文件為:
其中version說明了模型的版本,通過-c參數指定的cost-factor,maxid特征函數的最大id,xsize是特征維數,也就是訓練語料列數-1。
訓練時候用到的模板文件如下:
U0:%x[-1,0] U1:%x[0,0] U2:%x[1,0] U3:%x[-2,0]%x[-1,0] U4:%x[-1,0]%x[0,0] U5:%x[0,0]%x[1,0] U6:%x[1,0]%x[2,0] B后面部分為特征函數和依照id順序對應的特征函數權值:
5、BEMS標注
如果想采用CRF++的方法進行訓練,也可以將其轉換為CRF++支持的格式。CRF++是著名的條件隨機場開源工具,也是目前綜合性能最佳的CRF工具,有直接的工具包可以進行使用。CRF++工具包使用介紹
同時java-hanlp也提供了CRF++支持的語料庫格式轉換方法,該格式使用BEMS對文本進行標注。
public static void main(String[] args) throws IOException {CRFSegmenter segmenter = new CRFSegmenter(null);segmenter.convertCorpus("語料庫路徑/文件名.txt", "文件輸出路徑/文件名.tsv");}BEMS所說是中科院的提出一種標注,也有說BEIS的,hanlp用的是BEMS
B:開始
E:結束
M/I:中間
S:單獨成詞的位置
HMM模型就采用了狀態為(B,E,M,S)這四種狀態來標記中文詞語,比如北京可以標注為BE,即 北/B 京/E,表示“北”是開始位置,“京”是結束位置,“中華民族”可以標注為BMME,就是開始-中間-中間-結束。地址文本標注結果如下:
參考鏈接:CRF++模型格式說明
三、實驗結果
將訓練好的文本模型替換原語料庫的模型。在hanlp.properties中進行路徑設置,
若選擇模型替換,模型路徑參數直接缺省即可?;蛘呤褂肏anLP.Config.CRFCWSModelPath讀取新模型路徑。
以下兩種方式調用CRF分詞均可。
public static void main(String[] args) throws IOException {CRFLexicalAnalyzer segment = new CRFLexicalAnalyzer(HanLP.Config.CRFCWSModelPath);System.out.println(HanLP.Config.CRFCWSModelPath);segment.enablePartOfSpeechTagging(true);System.out.println(segment.seg("湖北省荊州市荊州區珞南街道金山路29-9號"));CRFSegmenter segmenter = new CRFSegmenter();List<String> wordList = segmenter.segment("湖北省荊州市荊州區荊秘路266-1號");System.out.println(wordList);}實驗結果如下,成功滿足項目需要。
總結
以上是生活随笔為你收集整理的使用Java-Hanlp训练CRF模型的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 水星MW300R无线路由器的设置方法
- 下一篇: 深入浅出学习Linux(基础知识一)