HanLP分詞工具中的ViterbiSegment分詞流程
本篇文章將重點講解 HanLP的ViterbiSegment分詞器類,而不涉及感知機和條件隨機場分詞器,也不涉及基於字的分詞器 。 因為這些分詞器都不是我們在實踐中常用的,而且 ViterbiSegment也是作者直接封裝到HanLP類中的分詞器,作者也推薦使用該分詞器,同時文字分類包以及其他一些自然語言處理任務包中的分詞器也都間接使用了ViterbiSegment分詞器。
今天的文章還會介紹各分詞詞典檔案的使用位置以及作用,相信小夥伴們看了今天的文章應該不會再在 github上提出干預自定義不生效的問題了 。 進入正題, 本篇 的內容比較多,建議收藏後再細讀。
1. 分詞器配置變數
分詞器的相關配置定義在 Config.java類中,這裡我們將分詞相關的所有配置變數列於下表
這種配置類什麼時候例項化呢,不用想肯定是分詞開始前就會例項化,拿 HanLP類中的ViterbiSegment分詞類舉例。該類的繼承關係用如下圖所示:
由繼承關係圖可以看到,只要例項化 ViterbiSegment則首先會執行Segment()初始化,在該方法中例項化分詞器配置物件config。這些配置變數都是公有變數,因此可以在ViterbiSegment類例項化為物件後直接在外部修改。那麼什麼時候來使用這些配置變數呢,當然是在分詞的時候,具體是哪個類的哪個方法呢,當然是ViterbiSegment類的List<Term> segSentence(char[] sentence)方法。
另外請注意上邊的 3個類,所有ViterbiSegment的分詞方法都集中在這3個類中。
2. 詞典的使用條件和先後順序(也介紹分詞流程)
我們知道了詞典配置變數使用的位置後,就可以確定每個詞典的使用條件了以及每個詞典的使用順序
1. 詞語粗分
( 1)構建詞圖
對應方法為 void generateWordNet(final WordNet wordNetStorage),在此方法中系統使用CoreNatureDictionary.txt檔案切分出所有可能的分詞路徑。此時如果配置變數useCustomDictionary為true,則將CustomDictionary.txt中的詞也考慮進來,說明CustomDictionary.txt優先順序會高。另外大家可以看到CoreNatureDictionary.txt實際上也充當了隱馬詞性標註的發射矩陣,裡邊某些多詞性詞也列出了詞性序列以及各詞性對應的頻次。
( 2)使用者定製詞典干預
如果配置變數 useCustomDictionary為true,即需要使用CustomDictionary.txt進行干預,則執行下邊對應的方法,否則跳過該步驟。使用者詞典干預根據是否進行全切分有兩種不同方法:當配置變數indexMode>0時,即系統處於全切分模式時,對應方法為
List<Vertex> combineByCustomDictionary(List<Vertex> vertexList, DoubleArrayTrie<CoreDictionary.Attribute> dat, final WordNet wordNetAll),
如果 indexMode=0,即系統處於普通分詞模式,對應方法為
List<Vertex> combineByCustomDictionary(List<Vertex> vertexList, DoubleArrayTrie<CoreDictionary.Attribute> dat)。
從呼叫的方法我們不難看出,全切分時系統會根據 CustomDictionary.txt新增分詞路徑。而普通切分時,系統會根據CustomDictionary.txt合併路徑。這也就是為什麼有的時候明明已經在CustomDictionary.txt中新增了新詞卻不生效的原因,因為一旦根據CoreNatureDictionary.txt構建了詞圖就不會再有新的路徑插到已有分詞路徑中間,此時就去查詢並修改CoreNatureDictionary.txt中的相關字或詞吧。
( 3)維特比選擇最優路徑
對應方法為 List<Vertex> viterbi(WordNet wordNet),至此就得到了一個粗分的分詞結果。需要注意HanLP的Viterbi分詞只是用viterbi方法求解最優路徑,並不是隱馬。
3. 數字識別
如果配置變數 numberQuantifierRecognize為true,則在粗分結果的基礎上進行數字合併操作,否則直接跳過該步。對應方法為
void mergeNumberQuantifier(List<Vertex> termList, WordNet wordNetAll, Config config)。
4. 實體識別
配置變數 ner為true時,則需要進行各種實體的識別,繼續向下執行。需要注意該變數受其他實體識別變數影響,只要其他任意實體配置變數為true,則ner就會為true。如果ner為false,則跳過下邊各項實體識別繼續詞性標註環節。
( 1)中國人名識別
執行此步,配置變數 nameRecognize必須為true。呼叫方法為
PersonRecognition.recognition(vertexList, wordNetOptimum, wordNetAll)。人名使用隱馬,因此有轉移矩陣nr.tr.txt和發射矩陣nr.txt。由於HanLP不提供訓練語料,我們自己也很難得到有角色標註的語料,因此我們一般只修改nr.txt檔案,刪除nr.txt.bin檔案後生效。
( 2)音譯人名識別
執行此步,配置變數 translatedNameRecognize必須為true。呼叫方法為
TranslatedPersonRecognition.recognition(vertexList, wordNetOptimum, wordNetAll)。需要注意音譯人名的識別沒有用隱馬,就是匹配分詞法。涉及到的詞典為nrf.txt,如果使用者修改該詞典,則需要刪除nrf.txt.trie.dat使其生效。
( 3)日本人名識別
執行此步,配置變數 japaneseNameRecognize必須為true。呼叫方法為
JapanesePersonRecognition.recognition(vertexList, wordNetOptimum, wordNetAll)。需要注意日本人名的識別沒有用隱馬,就是匹配分詞法。涉及到的詞典為nrj.txt,如果使用者修改該詞典,則需要刪除nrj.txt.trie.dat和nrj.txt.value.dat使其生效。
( 4)地名識別
執行此步,配置變數 placeRecognize必須為true。呼叫方法為
PlaceRecognition.recognition(vertexList, wordNetOptimum, wordNetAll)。地名使用隱馬,因此有轉移矩陣ns.tr.txt和發射矩陣ns.txt。由於HanLP不提供訓練語料,我們自己也很難得到有角色標註的語料,因此我們一般只修改ns.txt檔案,刪除ns.txt.bin檔案後生效。
( 5)機構名識別
執行此步,配置變數 organizationRecognize必須為true。呼叫方法為
OrganizationRecognition.recognition(vertexList, wordNetOptimum, wordNetAll)。注意這裡在呼叫機構名識別之前先進行了一次識別,也就是層疊隱馬,而人名和地名的識別就是普通的隱馬。機構名的識別使用層疊隱馬,涉及的檔案有轉移矩陣nt.tr.txt和發射矩陣nt.txt。由於HanLP不提供訓練語料,我們自己也很難得到有角色標註的語料,因此我們一般只修改nt.txt檔案,刪除ns.txt.bin檔案後生效。機構名的識別需要人名地名識別具有較高準確率。
至此,分詞流程已全部介紹了。
還需要注意下邊的內容
其他沒有在系統中使用的詞典有
機構名詞典 .txt
全國地名大全 .txt
人名詞典 .txt
上海地名 .txt
現代漢語補充詞庫 .txt
這些詞典是對系統中的詞典的更新記錄,如果你新增了新的人名、地名、機構名可以在這裡新增儲存。
另外,如果需要新增人名、地名、機構名可以直接在 CoreNatureDictionary.txt中新增,最好是3字以上實體,
如果要去掉錯誤識別的命名實體可以直接在相應的 nr.txt,ns.txt,nt.txt中新增。
3. 多執行緒分詞
HanLP的ViterbiSegment分詞器類是支援多執行緒的,執行緒數量由配置變數threadNumber決定的,該變數預設為1。HanLP作者說ViterbiSegmet分詞效率最高的原因肯定也有ViterbiSegment分詞器支援多執行緒分詞這個因素。另外由於ViterbiSegment分詞器內部所具有的相關命名實體功能,因此這些命名實體識別的效率也會很高。在哪裡實現的多執行緒分詞呢,在Segment類的List<Term> seg(String text)這個方法中實現的,需要注意HanLP的多執行緒分詞指的是一次輸入了一個長文字,而不是一次處理多個輸入文字。
本文分享自 baiziyu 的專欄,正文內容已經做了部分修改,便於大家閱讀,歡迎一起交流學習!
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31524777/viewspace-2652671/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 分詞工具Hanlp基於感知機的中文分詞框架HanLP中文分詞框架
- java分詞工具hanlp介紹Java分詞HanLP
- Ansj與hanlp分詞工具對比HanLP分詞
- HanLP-實詞分詞器詳解HanLP分詞
- Elasticsearch整合HanLP分詞器ElasticsearchHanLP分詞
- HanLP程式碼與詞典分離方案與流程HanLP
- HanLP分類模組的分詞器介紹HanLP分詞
- HanLP中文分詞Lucene外掛HanLP中文分詞
- Spring MVCD框架中呼叫HanLP分詞的方法SpringMVC框架HanLP分詞
- Hanlp在java中文分詞中的使用介紹HanLPJava中文分詞
- Hanlp分詞之CRF中文詞法分析詳解HanLP分詞CRF詞法分析
- 中文分詞演算法工具hanlp原始碼解析中文分詞演算法HanLP原始碼
- 基於hanlp的es分詞外掛HanLP分詞
- 基於 HanLP 的 ES 中文分詞外掛HanLP中文分詞
- NLP自然語言處理中的hanlp分詞例項自然語言處理HanLP分詞
- HanLP分詞命名實體提取詳解HanLP分詞
- python呼叫hanlp分詞包手記PythonHanLP分詞
- 中文分詞工具之基於字標註法的分詞中文分詞
- Spark中分散式使用HanLP(1.7.0)分詞示例Spark分散式HanLP分詞
- Hanlp中使用純JAVA實現CRF分詞HanLPJavaCRF分詞
- 自然語言處理工具HanLP-N最短路徑分詞自然語言處理HanLP分詞
- 分詞分詞
- 開源自然語言處理工具包hanlp中CRF分詞實現詳解自然語言處理HanLPCRF分詞
- MapReduce實現與自定義詞典檔案基於hanLP的中文分詞詳解HanLP中文分詞
- 部分常用分詞工具使用整理分詞
- #Elasticsearch中文分詞器 #IK分詞器 @FDDLCElasticsearch中文分詞
- 分詞-1分詞
- NLP入門學習中關於分詞庫HanLP匯入使用教程分詞HanLP
- hanlp中文智慧分詞自動識別文字提取例項HanLP分詞
- Hanlp分詞例項:Java實現TFIDF演算法HanLP分詞Java演算法
- hanlp原始碼解析之中文分詞演算法詳解HanLP原始碼中文分詞演算法
- Python分詞模組推薦:jieba中文分詞PythonJieba中文分詞
- 大資料語義分析:靈玖中文分詞的分詞處理大資料中文分詞
- 史上最全中文分詞工具整理中文分詞
- Hanlp等七種優秀的開源中文分詞庫推薦HanLP中文分詞
- Elasticsearch 分詞器Elasticsearch分詞
- IKAnalyzer 中文分詞的不同版本切詞方式中文分詞
- 自然語言處理工具pyhanlp分詞與詞性標註自然語言處理HanLP分詞詞性標註