自然語言處理:HanLP
HanLP是由一系列模型與算法組成的Java工具包,目標是促進自然語言處理在生產環境中的應用。HanLP具備功能完善、性能高效、架構清晰、語料時新、可自定義的特點。
HanLP提供下列功能:
中文分詞
最短路分詞
N-最短路分詞
CRF分詞
索引分詞
極速詞典分詞
用戶自定義詞典
詞性標注
命名實體識別
中國人名識別
音譯人名識別
日本人名識別
地名識別
實體機構名識別
關鍵詞提取
TextRank關鍵詞提取
自動摘要
TextRank自動摘要
短語提取
基于互信息和左右信息熵的短語提取
拼音轉換
多音字
聲母
韻母
聲調
簡繁轉換
繁體中文分詞
簡繁分歧詞
文本推薦
語義推薦
拼音推薦
字詞推薦
依存句法分析
MaxEnt依存句法分析
CRF依存句法分析
語料庫工具
分詞語料預處理
詞頻詞性詞典制作
BiGram統計
詞共現統計
CoNLL語料預處理
CoNLL UA/LA/DA評測工具
在提供豐富功能的同時,HanLP內部模塊堅持低耦合、模型堅持惰性加載、服務堅持靜態提供、詞典堅持明文發布,使用非常方便,同時自帶一些語料處理工具,幫助用戶訓練自己的語料。
項目地址
HanLP項目主頁:http://hanlp.linrunsoft.com/
HanLP下載地址:http://hanlp.linrunsoft.com/services.html
HanLP完整文檔:http://hanlp.linrunsoft.com/doc/_build/html/index.html
HanLP開源地址:https://github.com/hankcs/HanLP
最新binary、文檔都以項目主頁為準。
下載與配置
HanLP將數據與程序分離,給予用戶自定義的自由。
1、下載jar
2、下載data
任選一個數據包
數據包 | 功能 | 體積(MB) |
---|---|---|
data.full.zip | 全部 | 255 |
data.standard.zip | 全部詞典,不含模型 | 47 |
data.mini.zip | 小體積詞典,不含模型 | 22 |
下載后解壓到任意目錄,接下來通過配置文件告訴HanLP數據包的位置。
HanLP中的數據分為詞典和模型,其中詞典是詞法分析必需的,模型是句法分析必需的。
data │ ├─dictionary └─model
用戶可以自行增刪替換,如果不需要句法分析功能的話,隨時可以刪除model文件夾。
3、配置文件
示例配置文件:hanlp.properties
配置文件的作用是告訴HanLP數據包的位置,只需修改第一行
root=usr/home/HanLP/
為data的父目錄即可,比如data目錄是/Users/hankcs/Documents/data,那么root=/Users/hankcs/Documents/。
-
如果選用mini數據包的話,則需要修改配置文件:
CoreDictionaryPath=data/dictionary/CoreNatureDictionary.mini.txt
BiGramDictionaryPath=data/dictionary/CoreNatureDictionary.ngram.mini.txt
最后將HanLP.properties放入classpath即可,對于Eclipse,一般是:
$Project/bin
Web項目的話可以放在如下位置:
$Project/WEB-INF/classes
對于任何項目,都可以放到src目錄下,編譯時IDE會自動將其復制到classpath中。
如果放置不當,HanLP會智能提示當前環境下的合適路徑,并且嘗試從項目根目錄讀取數據集。
調用方法
HanLP幾乎所有的功能都可以通過工具類HanLP快捷調用,當你想不起來調用方法時,只需鍵入HanLP.,IDE應當會給出提示,并展示HanLP完善的文檔。
推薦用戶始終通過工具類HanLP調用,這么做的好處是,將來HanLP升級后,用戶無需修改調用代碼。
所有Demo都位于com.hankcs.demo下。
1. 第一個Demo
System.out.println(HanLP.segment("你好,歡迎使用HanLP漢語處理包!"));
2. 標準分詞
List<Term> termList = StandardTokenizer.segment("商品和服務"); System.out.println(termList);
-
說明
-
HanLP中有一系列“開箱即用”的靜態分詞器,以Tokenizer結尾,在接下來的例子中會繼續介紹。
-
HanLP.segment其實是對StandardTokenizer.segment的包裝。
-
算法詳解
3. NLP分詞
List<Term> termList = NLPTokenizer.segment("中國科學院計算技術研究所的宗成慶教授正在教授自然語言處理課程"); System.out.println(termList);
-
說明
-
NLP分詞NLPTokenizer會執行全部命名實體識別和詞性標注。
4. 索引分詞
List<Term> termList = IndexTokenizer.segment("主副食品"); for (Term term : termList) { System.out.println(term + " [" + term.offset + ":" + (term.offset + term.word.length()) + "]"); }
-
說明
-
索引分詞IndexTokenizer是面向搜索引擎的分詞器,能夠對長詞全切分,另外通過term.offset可以獲取單詞在文本中的偏移量。
5. N-最短路徑分詞
Segment nShortSegment = new NShortSegment().enableCustomDictionary(false).enablePlaceRecognize(true).enableOrganizationRecognize(true); Segment shortestSegment = new DijkstraSegment().enableCustomDictionary(false).enablePlaceRecognize(true).enableOrganizationRecognize(true); String[] testCase = new String[]{ "今天,劉志軍案的關鍵人物,山西女商人丁書苗在市二中院出庭受審。", "劉喜杰石國祥會見吳亞琴先進事跡報告團成員", }; for (String sentence : testCase) { System.out.println("N-最短分詞:" + nShortSegment.seg(sentence) + "\n最短路分詞:" + shortestSegment.seg(sentence)); }
-
說明
-
N最短路分詞器NShortSegment比最短路分詞器慢,但是效果稍微好一些,對命名實體識別能力更強。
-
一般場景下最短路分詞的精度已經足夠,而且速度比N最短路分詞器快幾倍,請酌情選擇。
-
算法詳解
6. CRF分詞
Segment segment = new CRFSegment(); segment.enablePartOfSpeechTagging(true); List<Term> termList = segment.seg("你看過穆赫蘭道嗎"); System.out.println(termList); for (Term term : termList) { if (term.nature == null) { System.out.println("識別到新詞:" + term.word); } }
-
說明
-
CRF對新詞有很好的識別能力,但是無法利用自定義詞典。
-
算法詳解
7. 極速詞典分詞
/** * 演示極速分詞,基于AhoCorasickDoubleArrayTrie實現的詞典分詞,適用于“高吞吐量”“精度一般”的場合 * @author hankcs */ public class DemoHighSpeedSegment { public static void main(String[] args) { String text = "江西鄱陽湖干枯,中國最大淡水湖變成大草原"; System.out.println(SpeedTokenizer.segment(text)); long start = System.currentTimeMillis(); int pressure = 1000000; for (int i = 0; i < pressure; ++i) { SpeedTokenizer.segment(text); } double costTime = (System.currentTimeMillis() - start) / (double)1000; System.out.printf("分詞速度:%.2f字每秒", text.length() * pressure / costTime); } }
-
說明
-
極速分詞是詞典最長分詞,速度極其快,精度一般。
-
在i7上跑出了2000萬字每秒的速度。
-
算法詳解
8. 用戶自定義詞典
/** * 演示用戶詞典的動態增刪 * * @author hankcs */ public class DemoCustomDictionary { public static void main(String[] args) { // 動態增加 CustomDictionary.add("孔雀女"); // 強行插入 CustomDictionary.insert("碼農", "nz 1024"); // 刪除詞語(注釋掉試試) // CustomDictionary.remove("碼農"); System.out.println(CustomDictionary.add("裸婚", "v 2 nz 1")); System.out.println(CustomDictionary.get("裸婚")); String text = "碼農和孔雀女裸婚了"; // 怎么可能噗哈哈! // AhoCorasickDoubleArrayTrie自動機分詞 final char[] charArray = text.toCharArray(); CoreDictionary.trie.parseText(charArray, new AhoCorasickDoubleArrayTrie.IHit<CoreDictionary.Attribute>() { @Override public void hit(int begin, int end, CoreDictionary.Attribute value) { System.out.printf("[%d:%d]=%s %s\n", begin, end, new String(charArray, begin, end - begin), value); } }); // trie樹分詞 BaseSearcher searcher = CustomDictionary.getSearcher(text); Map.Entry entry; while ((entry = searcher.next()) != null) { System.out.println(entry); } // 標準分詞 System.out.println(HanLP.segment(text)); } }
-
說明
-
CustomDictionary是一份全局的用戶自定義詞典,可以隨時增刪,影響全部分詞器。
-
另外可以在任何分詞器中關閉它。通過代碼動態增刪不會保存到詞典文件。
-
追加詞典
-
CustomDictionary主詞典文本路徑是data/dictionary/custom/CustomDictionary.txt,用戶可以在此增加自己的詞語(不推薦);也可以單獨新建一個文本文件,通過配置文件CustomDictionaryPath=data/dictionary/custom/CustomDictionary.txt; 我的詞典.txt;來追加詞典(推薦)。
-
始終建議將相同詞性的詞語放到同一個詞典文件里,便于維護和分享。
-
詞典格式
-
每一行代表一個單詞,格式遵從[單詞] [詞性A] [A的頻次] [詞性B] [B的頻次] ...如果不填詞性則表示采用詞典的默認詞性。
-
詞典的默認詞性默認是名詞n,可以通過配置文件修改:全國地名大全.txt ns;如果詞典路徑后面空格緊接著詞性,則該詞典默認是該詞性。
-
關于用戶詞典的更多信息請參考詞典說明一章。
-
算法詳解
9. 中國人名識別
String[] testCase = new String[]{ "簽約儀式前,秦光榮、李紀恒、仇和等一同會見了參加簽約的企業家。", "王國強、高峰、汪洋、張朝陽光著頭、韓寒、小四", "張浩和胡健康復員回家了", "王總和小麗結婚了", "編劇邵鈞林和稽道青說", "這里有關天培的有關事跡", "龔學平等領導,鄧穎超生前", }; Segment segment = HanLP.newSegment().enableNameRecognize(true); for (String sentence : testCase) { List<Term> termList = segment.seg(sentence); System.out.println(termList); }
-
說明
-
目前分詞器基本上都默認開啟了中國人名識別,比如HanLP.segment()接口中使用的分詞器等等,用戶不必手動開啟;上面的代碼只是為了強調。
-
有一定的誤命中率,比如誤命中關鍵年,則可以通過在data/dictionary/person/nr.txt加入一條關鍵年 A 1來排除關鍵年作為人名的可能性,也可以將關鍵年作為新詞登記到自定義詞典中。
-
如果你通過上述辦法解決了問題,歡迎向我提交pull request,詞典也是寶貴的財富。
-
算法詳解
9. 音譯人名識別
String[] testCase = new String[]{ "一桶冰水當頭倒下,微軟的比爾蓋茨、非死book的扎克伯格跟桑德博格、亞馬遜的貝索斯、蘋果的庫克全都不惜濕身入鏡,這些硅谷的科技人,飛蛾撲火似地犧牲演出,其實全為了慈善。", "世界上最長的姓名是簡森·喬伊·亞歷山大·比基·卡利斯勒·達夫·埃利奧特·福克斯·伊維魯莫·馬爾尼·梅爾斯·帕特森·湯普森·華萊士·普雷斯頓。", }; Segment segment = HanLP.newSegment().enableTranslatedNameRecognize(true); for (String sentence : testCase) { List<Term> termList = segment.seg(sentence); System.out.println(termList); }
-
說明
-
目前分詞器基本上都默認開啟了音譯人名識別,用戶不必手動開啟;上面的代碼只是為了強調。
-
算法詳解
11. 日本人名識別
String[] testCase = new String[]{ "北川景子參演了林詣彬導演的《速度與激情3》", "林志玲亮相網友:確定不是波多野結衣?", }; Segment segment = HanLP.newSegment().enableJapaneseNameRecognize(true); for (String sentence : testCase) { List<Term> termList = segment.seg(sentence); System.out.println(termList); }
-
說明
-
目前標準分詞器默認關閉了日本人名識別,用戶需要手動開啟;這是因為日本人名的出現頻率較低,但是又消耗性能。
-
算法詳解
12. 地名識別
String[] testCase = new String[]{ "武勝縣新學鄉政府大樓門前鑼鼓喧天", "藍翔給寧夏固原市彭陽縣紅河鎮黑牛溝村捐贈了挖掘機", }; Segment segment = HanLP.newSegment().enablePlaceRecognize(true); for (String sentence : testCase) { List<Term> termList = segment.seg(sentence); System.out.println(termList); }
-
說明
-
目前標準分詞器都默認關閉了地名識別,用戶需要手動開啟;這是因為消耗性能,其實多數地名都收錄在核心詞典和用戶自定義詞典中。
-
在生產環境中,能靠詞典解決的問題就靠詞典解決,這是最高效穩定的方法。
-
算法詳解
13. 機構名識別
String[] testCase = new String[]{ "我在上海林原科技有限公司兼職工作,", "同時在上海外國語大學日本文化經濟學院學習經濟與外語。", "我經常在榮祥餐廳吃飯,", "濟南楊銘宇餐飲管理有限公司是由楊先生創辦的餐飲企業。", }; Segment segment = HanLP.newSegment().enableOrganizationRecognize(true); for (String sentence : testCase) { List<Term> termList = segment.seg(sentence); System.out.println(termList); }
-
說明
-
目前分詞器默認關閉了機構名識別,用戶需要手動開啟;這是因為消耗性能,其實常用機構名都收錄在核心詞典和用戶自定義詞典中。
-
HanLP的目的不是演示動態識別,在生產環境中,能靠詞典解決的問題就靠詞典解決,這是最高效穩定的方法。
-
算法詳解
14. 關鍵詞提取
String content = "程序員(英文Programmer)是從事程序開發、維護的專業人員。一般將程序員分為程序設計人員和程序編碼人員,但兩者的界限并不非常清楚,特別是在中國。軟件從業人員分為初級程序員、高級程序員、系統分析員和項目經理四大類。"; List<String> keywordList = HanLP.extractKeyword(content, 5); System.out.println(keywordList);
-
說明
-
內部采用TextRankKeyword實現,用戶可以直接調用TextRankKeyword.getKeywordList(document, size)
-
算法詳解
15. 自動摘要
String document = "算法可大致分為基本算法、數據結構的算法、數論算法、計算幾何的算法、圖的算法、動態規劃以及數值分析、加密算法、排序算法、檢索算法、隨機化算法、并行算法、厄米變形模型、隨機森林算法。\n" + "算法可以寬泛的分為三類,\n" + "一,有限的確定性算法,這類算法在有限的一段時間內終止。他們可能要花很長時間來執行指定的任務,但仍將在一定的時間內終止。這類算法得出的結果常取決于輸入值。\n" + "二,有限的非確定算法,這類算法在有限的時間內終止。然而,對于一個(或一些)給定的數值,算法的結果并不是唯一的或確定的。\n" + "三,無限的算法,是那些由于沒有定義終止定義條件,或定義的條件無法由輸入的數據滿足而不終止運行的算法。通常,無限算法的產生是由于未能確定的定義終止條件。"; List<String> sentenceList = HanLP.extractSummary(document, 3); System.out.println(sentenceList);
-
說明
-
內部采用TextRankSentence實現,用戶可以直接調用TextRankSentence.getTopSentenceList(document, size)。
-
算法詳解
16. 短語提取
String text = "算法工程師\n" + "算法(Algorithm)是一系列解決問題的清晰指令,也就是說,能夠對一定規范的輸入,在有限時間內獲得所要求的輸出。" + "如果一個算法有缺陷,或不適合于某個問題,執行這個算法將不會解決這個問題。不同的算法可能用不同的時間、" + "空間或效率來完成同樣的任務。一個算法的優劣可以用空間復雜度與時間復雜度來衡量。算法工程師就是利用算法處理事物的人。\n" + "\n" + "1職位簡介\n" + "算法工程師是一個非常高端的職位;\n" + "專業要求:計算機、電子、通信、數學等相關專業;\n" + "學歷要求:本科及其以上的學歷,大多數是碩士學歷及其以上;\n" + "語言要求:英語要求是熟練,基本上能閱讀國外專業書刊;\n" + "必須掌握計算機相關知識,熟練使用仿真工具MATLAB等,必須會一門編程語言。\n" + "\n" + "2研究方向\n" + "視頻算法工程師、圖像處理算法工程師、音頻算法工程師 通信基帶算法工程師\n" + "\n" + "3目前國內外狀況\n" + "目前國內從事算法研究的工程師不少,但是高級算法工程師卻很少,是一個非常緊缺的專業工程師。" + "算法工程師根據研究領域來分主要有音頻/視頻算法處理、圖像技術方面的二維信息算法處理和通信物理層、" + "雷達信號處理、生物醫學信號處理等領域的一維信息算法處理。\n" + "在計算機音視頻和圖形圖像技術等二維信息算法處理方面目前比較先進的視頻處理算法:機器視覺成為此類算法研究的核心;" + "另外還有2D轉3D算法(2D-to-3D conversion),去隔行算法(de-interlacing),運動估計運動補償算法" + "(Motion estimation/Motion Compensation),去噪算法(Noise Reduction),縮放算法(scaling)," + "銳化處理算法(Sharpness),超分辨率算法(Super Resolution),手勢識別(gesture recognition),人臉識別(face recognition)。\n" + "在通信物理層等一維信息領域目前常用的算法:無線領域的RRM、RTT,傳送領域的調制解調、信道均衡、信號檢測、網絡優化、信號分解等。\n" + "另外數據挖掘、互聯網搜索算法也成為當今的熱門方向。\n" + "算法工程師逐漸往人工智能方向發展。"; List<String> phraseList = HanLP.extractPhrase(text, 5); System.out.println(phraseList);
-
說明
-
內部采用MutualInformationEntropyPhraseExtractor實現,用戶可以直接調用MutualInformationEntropyPhraseExtractor..extractPhrase(text, size)。
-
算法詳解
17. 拼音轉換
/** * 漢字轉拼音 * @author hankcs */ public class DemoPinyin { public static void main(String[] args) { String text = "重載不是重任"; List<Pinyin> pinyinList = HanLP.convertToPinyinList(text); System.out.print("原文,"); for (char c : text.toCharArray()) { System.out.printf("%c,", c); } System.out.println(); System.out.print("拼音(數字音調),"); for (Pinyin pinyin : pinyinList) { System.out.printf("%s,", pinyin); } System.out.println(); System.out.print("拼音(符號音調),"); for (Pinyin pinyin : pinyinList) { System.out.printf("%s,", pinyin.getPinyinWithToneMark()); } System.out.println(); System.out.print("拼音(無音調),"); for (Pinyin pinyin : pinyinList) { System.out.printf("%s,", pinyin.getPinyinWithoutTone()); } System.out.println(); System.out.print("聲調,"); for (Pinyin pinyin : pinyinList) { System.out.printf("%s,", pinyin.getTone()); } System.out.println(); System.out.print("聲母,"); for (Pinyin pinyin : pinyinList) { System.out.printf("%s,", pinyin.getShengmu()); } System.out.println(); System.out.print("韻母,"); for (Pinyin pinyin : pinyinList) { System.out.printf("%s,", pinyin.getYunmu()); } System.out.println(); System.out.print("輸入法頭,"); for (Pinyin pinyin : pinyinList) { System.out.printf("%s,", pinyin.getHead()); } System.out.println(); } }
-
說明
-
HanLP不僅支持基礎的漢字轉拼音,還支持聲母、韻母、音調、音標和輸入法首字母首聲母功能。
-
HanLP能夠識別多音字,也能給繁體中文注拼音。
-
最重要的是,HanLP采用的模式匹配升級到AhoCorasickDoubleArrayTrie,性能大幅提升,能夠提供毫秒級的響應速度!
-
算法詳解
18. 簡繁轉換
/** * 簡繁轉換 * @author hankcs */ public class DemoTraditionalChinese2SimplifiedChinese { public static void main(String[] args) { System.out.println(HanLP.convertToTraditionalChinese("用筆記本電腦寫程序")); System.out.println(HanLP.convertToSimplifiedChinese("「以後等妳當上皇后,就能買士多啤梨慶祝了」")); } }
-
說明
-
HanLP能夠識別簡繁分歧詞,比如打印機=印表機。許多簡繁轉換工具不能區分“以后”“皇后”中的兩個“后”字,HanLP可以。
-
算法詳解
19. 文本推薦
/** * 文本推薦(句子級別,從一系列句子中挑出與輸入句子最相似的那一個) * @author hankcs */ public class DemoSuggester { public static void main(String[] args) { Suggester suggester = new Suggester(); String[] titleArray = ( "威廉王子發表演說 呼吁保護野生動物\n" + "《時代》年度人物最終入圍名單出爐 普京馬云入選\n" + "“黑格比”橫掃菲:菲吸取“海燕”經驗及早疏散\n" + "日本保密法將正式生效 日媒指其損害國民知情權\n" + "英報告說空氣污染帶來“公共健康危機”" ).split("\\n"); for (String title : titleArray) { suggester.addSentence(title); } System.out.println(suggester.suggest("發言", 1)); // 語義 System.out.println(suggester.suggest("危機公共", 1)); // 字符 System.out.println(suggester.suggest("mayun", 1)); // 拼音 } }
-
說明
-
在搜索引擎的輸入框中,用戶輸入一個詞,搜索引擎會聯想出最合適的搜索詞,HanLP實現了類似的功能。
-
可以動態調節每種識別器的權重
20. 語義距離
/** * 語義距離 * @author hankcs */ public class DemoWordDistance { public static void main(String[] args) { String[] wordArray = new String[] { "香蕉", "蘋果", "白菜", "水果", "蔬菜", "自行車", "公交車", "飛機", "買", "賣", "購入", "新年", "春節", "丟失", "補辦", "辦理", "送給", "尋找", "孩子", "教室", "教師", "會計", }; for (String a : wordArray) { for (String b : wordArray) { System.out.println(a + "\t" + b + "\t之間的距離是\t" + CoreSynonymDictionary.distance(a, b)); } } } }
-
說明
-
設想的應用場景是搜索引擎對詞義的理解,詞與詞并不只存在“同義詞”與“非同義詞”的關系,就算是同義詞,它們之間的意義也是有微妙的差別的。
-
算法
-
為每個詞分配一個語義ID,詞與詞的距離通過語義ID的差得到。語義ID通過《同義詞詞林擴展版》計算而來。
21. 依存句法解析
/** * 依存句法解析 * @author hankcs */ public class DemoDependencyParser { public static void main(String[] args) { System.out.println(HanLP.parseDependency("把市場經濟奉行的等價交換原則引入黨的生活和國家機關政務活動中")); } }
-
說明
-
內部采用MaxEntDependencyParser實現,用戶可以直接調用MaxEntDependencyParser.compute(sentence)
-
也可以調用基于隨機條件場的依存句法分析器CRFDependencyParser.compute(sentence)
-
在封閉測試集上準確率有90%以上,但在開放測試集上則不理想。
-
算法詳解
詞典說明
本章詳細介紹HanLP中的詞典格式,滿足用戶自定義的需要。HanLP中有許多詞典,它們的格式都是相似的,形式都是文本文檔,隨時可以修改。
基本格式
詞典分為詞頻詞性詞典和詞頻詞典。
-
詞頻詞性詞典
-
每一行代表一個單詞,格式遵從[單詞] [詞性A] [A的頻次] [詞性B] [B的頻次] ...。
-
詞頻詞典
-
每一行代表一個單詞,格式遵從[單詞] [單詞的頻次]。
-
每一行的分隔符為空格符或制表符
少數詞典有自己的專用格式,比如同義詞詞典兼容《同義詞詞林擴展版》的文本格式,而轉移矩陣詞典則是一個csv表格。
下文主要介紹通用詞典,如不注明,詞典特指通用詞典。
數據結構
Trie樹(字典樹)是HanLP中使用最多的數據結構,為此,我實現了通用的Trie樹,支持泛型、遍歷、儲存、載入。
用戶自定義詞典采用AhoCorasickDoubleArrayTrie和二分Trie樹儲存,其他詞典采用基于雙數組Trie樹(DoubleArrayTrie)實現的AC自動機AhoCorasickDoubleArrayTrie。
儲存形式
詞典有兩個形態:文本文件(filename.txt)和緩存文件(filename.txt.bin或filename.txt.trie.dat和filename.txt.trie.value)。
-
文本文件
-
采用明文儲存,UTF-8編碼,CRLF換行符。
-
緩存文件
-
就是一些二進制文件,通常在文本文件的文件名后面加上.bin表示。有時候是.trie.dat和.trie.value。后者是歷史遺留產物,分別代表trie樹的數組和值。
-
如果你修改了任何詞典,只有刪除緩存才能生效。
修改方法
HanLP的核心詞典訓練自人民日報2014語料,語料不是完美的,總會存在一些錯誤。這些錯誤可能會導致分詞出現奇怪的結果,這時請打開調試模式排查問題:
HanLP.Config.enableDebug();
-
核心詞性詞頻詞典
-
比如你在data/dictionary/CoreNatureDictionary.txt中發現了一個不是詞的詞,或者詞性標注得明顯不對,那么你可以修改它,然后刪除緩存文件使其生效。
-
核心二元文法詞典
-
二元文法詞典data/dictionary/CoreNatureDictionary.ngram.txt儲存的是兩個詞的接續,如果你發現不可能存在這種接續時,刪掉即可。
-
你也可以添加你認為合理的接續,但是這兩個詞必須同時在核心詞典中才會生效。
-
命名實體識別詞典
-
基于角色標注的命名實體識別比較依賴詞典,所以詞典的質量大幅影響識別質量。
-
這些詞典的格式與原理都是類似的,請閱讀相應的文章或代碼修改它。
如果問題解決了,歡迎向我提交一個pull request,這是我在代碼庫中保留明文詞典的原因,眾人拾柴火焰高!
版權
上海林原信息科技有限公司
-
Apache License Version 2.0
-
HanLP產品初始知識產權歸上海林原信息科技有限公司所有,任何人和企業可以無償使用,可以對產品、源代碼進行任何形式的修改,可以打包在其他產品中進行銷售。
-
任何使用了HanLP的全部或部分功能、詞典、模型的項目、產品或文章等形式的成果必須顯式注明HanLP及此項目主頁。
鳴謝
感謝下列優秀開源項目:
感謝NLP界各位學者老師的著作:
-
《基于角色標注的中國人名自動識別研究》張華平 劉群
-
《基于層疊隱馬爾可夫模型的中文命名實體識別》俞鴻魁 張華平 劉群 呂學強 施水才
-
《基于角色標注的中文機構名識別》俞鴻魁 張華平 劉群
-
《基于最大熵的依存句法分析》 辛霄 范士喜 王軒 王曉龍
-
An Efficient Implementation of Trie Structures, JUN-ICHI AOE AND KATSUSHI MORIMOTO
-
TextRank: Bringing Order into Texts, Rada Mihalcea and Paul Tarau
感謝上海林原信息科技有限公司的劉先生,允許我利用工作時間開發HanLP,提供服務器和域名,并且促成了開源。感謝諸位用戶的關注和使用,HanLP并不完善,未來還懇求各位NLP愛好者多多關照,提出寶貴意見。
作者 @hankcs
2014年12月16日