官網:http://hanlp.linrunsoft.com/
1、中文分詞:http://hanlp.linrunsoft.com/doc/_build/html/segment.html
2、摘要關鍵字:http://hanlp.linrunsoft.com/doc/_build/html/extract.html
3、智能推薦:http://hanlp.linrunsoft.com/doc/_build/html/auto_suggest.html
4、簡繁拼音轉換:http://hanlp.linrunsoft.com/doc/_build/html/util.html
5、solr hanlp分詞插件下載:https://github.com/hankcs/hanlp-lucene-plugin/releases
6、hanlp分詞包下載地址:https://github.com/hankcs/HanLP/releases
Maven配置:
<dependency>
<groupId>com.hankcs</groupId>
<artifactId>hanlp</artifactId>
<version>portable-1.5.3</version>
</dependency>
<dependency>
<groupId>com.hankcs.nlp</groupId>
<artifactId>hanlp-lucene-plugin</artifactId>
<version>1.1.2</version>
</dependency>
分詞Java代碼:
import com.hankcs.hanlp.HanLP;
import com.hankcs.hanlp.corpus.tag.Nature;
import com.hankcs.hanlp.dependency.CRFDependencyParser;
import com.hankcs.hanlp.dictionary.py.Pinyin;
import com.hankcs.hanlp.seg.CRF.CRFSegment;
import com.hankcs.hanlp.seg.NShort.NShortSegment;
import com.hankcs.hanlp.seg.Segment;
import com.hankcs.hanlp.seg.Viterbi.ViterbiSegment;
import com.hankcs.hanlp.seg.common.Term;
import com.hankcs.hanlp.suggest.Suggester;
import com.hankcs.hanlp.tokenizer.IndexTokenizer;
import com.hankcs.hanlp.tokenizer.NLPTokenizer;
import com.hankcs.hanlp.tokenizer.SpeedTokenizer;
import com.hankcs.hanlp.tokenizer.TraditionalChineseTokenizer;
import java.util.ArrayList;
import java.util.List;
/**
* @Author:sks
* @Description:
* @Date:Created in 16:00 2018/1/19
* @Modified by:
**/
public class hanlp_test {
public static void main(String[] args){
// Participle();
// extractKeyword();
// extractSummary();
// extractPhrase();
// suggest_test();
// converto();
// nameRecognize();
analysebysyntax();
}
/**
* @Author:sks
* @Description:測試各種分詞
* @Date:
*/
private static void Participle(){
//標準分詞
//HanLP.segment 其實是對 StandardTokenizer.segment 的包裝。
//HanLP中有一系列「開箱即用」的靜態分詞器,以 Tokenizer 結尾
List<Term> stermList = HanLP.segment("商品和服務");
System.out.println(stermList);
//[商品/n, 和/c, 服務/vn]
//NLP分詞
//NLP分詞 NLPTokenizer 會執行全部命名實體識別和詞性標註。
//所以速度比標準分詞慢,並且有誤識別的情況。
List<Term> nlptermList = NLPTokenizer.segment("中國科學院計算技術研究所的宗成慶教授正在教授自然語言處理課程");
System.out.println(nlptermList);
//輸出:[中國科學院/n, 計算/v, 技術/n, 研究所/n, 的/uj, 宗成慶/nr, 教授/n, 正在/d, 教授/n, 自然/d, 語言/n, 處理/v, 課程/n]
//索引分詞
//索引分詞 IndexTokenizer 是面向搜尋引擎的分詞器,能夠對長詞全切分,另外通過 term.offset 可以獲取單詞在文本中的偏移量
List<Term> termList = IndexTokenizer.segment("主副食品");
for (Term term : termList)
{
System.out.println(term + " [" + term.offset + ":" + (term.offset + term.word.length()) + "]");
}
//主副食品/n [0:4]
//主副食/j [0:3]
//副食品/n [1:4]
//副食/n [1:3]
//食品/n [2:4]
//繁體分詞
List<Term> fttermList = TraditionalChineseTokenizer.segment("大衛貝克漢不僅僅是名著名球員,球場以外,其妻為前辣妹合唱團成員維多利亞·貝克漢," +
"亦由於他擁有突出外表、百變髮型及正面的形象,以至自己品牌的男士香水等商品,及長期擔任動品牌Adidas的代言人," +
"因此對大眾傳播媒介和時尚界等方面都具很大的影響力,在足球圈外所獲得的認受程度可謂前所未見。");
System.out.println(fttermList);
//[大衛貝克漢/nrf, 不僅僅/d, 是/v, 名著/n, 名/q, 球員/n, ,/w, 球場/n, 以外/f, ,/w, 其/r, 妻/ng, 為/p, 前/f, 辣妹/nz, 合唱團/n, 成員/n, 維多利亞/ns,
// ·/w, 碧/ag, 鹹/ng, ,/w, 亦/d, 由於/c, 他/r, 擁有/v, 突出/a, 外表/n, 、/w, 百變/nz, 髮型/n, 及/c, 正面/d, 的/uj, 形象/n, ,/w,
// 以至/c, 自己/r, 品牌/n, 的/uj, 男士/n, 香水/n, 等/u, 商品/n, ,/w, 及/c, 長期/d, 擔任/v, 動/n, 品牌/n, Adidas/nx, 的/uj, 代言人/n,
// ,/w, 因此/c, 對/p, 大眾/n, 傳播/vn, 媒介/n, 和/c, 時尚界/nz, 等/u, 方面/n, 都/d, 具/vg, 很大/d, 的/uj, 影響力/n, ,/w,
// 在/p, 足球/n, 圈外/nz, 所/u, 獲得/v, 的/uj, 認/v, 受/v, 程度/n, 可/v, 謂/vg, 前所未見/l, 。/w]
//極速詞典分詞
//極速分詞是詞典最長分詞,速度極其快,精度一般。調用方法如下:
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);
//N-最短路徑分詞
//N最短路分詞器 NShortSegment 比最短路分詞器( DijkstraSegment )慢,但是效果稍微好一些,對命名實體識別能力更強
//一般場景下最短路分詞的精度已經足夠,而且速度比N最短路分詞器快幾倍
Segment nShortSegment = new NShortSegment().enableCustomDictionary(false).enablePlaceRecognize(true).enableOrganizationRecognize(true);
Segment shortestSegment = new ViterbiSegment().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));
}
//CRF分詞
//基於CRF模型和BEMS標註訓練得到的分詞器
//CRF對新詞有很好的識別能力,但是無法利用自定義詞典。
//也不支持命名實體識別,應用場景僅限於新詞識別。
Segment segment = new CRFSegment();
segment.enablePartOfSpeechTagging(true);
List<Term> crftermList = segment.seg("你看過穆赫蘭道嗎");
System.out.println(crftermList);
for (Term term : crftermList)
{
if (term.nature == null)
{
System.out.println("識別到新詞:" + term.word);
}
}
}
/**
* 這裡使用HanLP進行分詞 ,只獲取名稱和動名稱
* @param text
* @return
*/
/**
* @Author:sks
* @Description:抽取關鍵字
* @Date:
*/
private static List<String> hanLPSegment(String text){
List<String> wordList = new ArrayList<String>();
List<Term> words= HanLP.segment(text);
for(Term tm:words){
if(tm.nature== Nature.n||tm.nature== Nature.vn){
wordList.add(tm.word);
}
}
return wordList;
}
private static void extractKeyword(){
String content = "程式設計師(英文Programmer)是從事程序開發、維護的專業人員。一般將程式設計師分為程序設計人員和程序編碼人員,但兩者的界限並不非常清楚,特別是在中國。軟體從業人員分為初級程式設計師、高級程式設計師、系統分析員和項目經理四大類。";
//返回頻次最高的5個關鍵詞
List<String> keywordList = HanLP.extractKeyword(content, 5);
System.out.println(keywordList);
}
/**
* @Author:sks
* @Description:提取摘要
* @Date:
*/
private static void extractSummary(){
//同樣是一句話調用,第一個參數指定文本,第二個參數指定需要提取幾個句子:
String document = "算法可大致分為基本算法、數據結構的算法、數論算法、計算幾何的算法、圖的算法、動態規劃以及數值分析、加密算法、排序算法、檢索算法、隨機化算法、並行算法、厄米變形模型、隨機森林算法。\n" +
"算法可以寬泛的分為三類,\n" +
"一,有限的確定性算法,這類算法在有限的一段時間內終止。他們可能要花很長時間來執行指定的任務,但仍將在一定的時間內終止。這類算法得出的結果常取決於輸入值。\n" +
"二,有限的非確定算法,這類算法在有限的時間內終止。然而,對於一個(或一些)給定的數值,算法的結果並不是唯一的或確定的。\n" +
"三,無限的算法,是那些由於沒有定義終止定義條件,或定義的條件無法由輸入的數據滿足而不終止運行的算法。通常,無限算法的產生是由於未能確定的定義終止條件。";
List<String> sentenceList = HanLP.extractSummary(document, 3);//3:返回的句子數
System.out.println(sentenceList);
String summary = HanLP.getSummary(document,50);//返回的摘要長度
System.out.println(summary);
}
private static void extractPhrase(){
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, 10);
System.out.println(phraseList);
}
/**
* @Author:sks
* @Description:智能提示
* @Date:
*/
private static void suggest_test(){
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)); // 拼音
}
/**
* @Author:sks
* @Description:簡繁轉換
* @Date:
*/
private static void converto(){
//簡繁轉換
System.out.println(HanLP.convertToTraditionalChinese("「以後等你當上皇后,就能買草莓慶祝了」"));
System.out.println(HanLP.convertToSimplifiedChinese("用筆記簿型電腦寫程式HelloWorld"));
//拼音轉換
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();
}
/**
* @Author:sks
* @Description:中國人姓名識別
* @Date:
*/
private static void nameRecognize(){
//目前分詞器基本上都默認開啟了中國人名識別,比如HanLP.segment()接口中使用的分詞器等等,用戶不必手動開啟;上面的代碼只是為了強調。
String[] testCase = new String[]{
"籤約儀式前,秦光榮、李紀恆、仇和等一同會見了參加籤約的企業家。",
"王國強、高峰、汪洋、張朝陽光著頭、韓寒、小四",
"張浩和胡健康復員回家了",
"王總和小麗結婚了",
"編劇邵鈞林和稽道青說",
"這裡有關天培的有關事跡",
"龔學平等領導,鄧穎超生前",
};
Segment segment = HanLP.newSegment().enableNameRecognize(true);
for (String sentence : testCase)
{
List<Term> termList = segment.seg(sentence);
System.out.println(termList);
}
//音譯人名識別
//目前分詞器基本上都默認開啟了音譯人名識別,用戶不必手動開啟;上面的代碼只是為了強調。
String[] testCase1 = new String[]{
"一桶冰水當頭倒下,微軟的比爾蓋茨、Facebook的扎克伯格跟桑德博格、亞馬遜的貝索斯、蘋果的庫克全都不惜溼身入鏡,這些矽谷的科技人,飛蛾撲火似地犧牲演出,其實全為了慈善。",
"世界上最長的姓名是簡森·喬伊·亞歷山大·比基·卡利斯勒·達夫·埃利奧特·福克斯·伊維魯莫·馬爾尼·梅爾斯·帕特森·湯普森·華萊士·普雷斯頓。",
};
Segment segment1 = HanLP.newSegment().enableTranslatedNameRecognize(true);
for (String sentence : testCase1)
{
List<Term> termList = segment1.seg(sentence);
System.out.println(termList);
}
//地名識別
//可以自動識別地名,標註為ns:
//目前標準分詞器都默認關閉了地名識別,用戶需要手動開啟;這是因為消耗性能,其實多數地名都收錄在核心詞典和用戶自定義詞典中。
//在生產環境中,能靠詞典解決的問題就靠詞典解決,這是最高效穩定的方法
String[] areaCase = new String[]{
"武勝縣新學鄉政府大樓門前鑼鼓喧天",
"藍翔給寧夏固原市彭陽縣紅河鎮黑牛溝村捐贈了挖掘機",
};
Segment areasegment = HanLP.newSegment().enablePlaceRecognize(true);
for (String sentence : areaCase)
{
List<Term> termList = areasegment.seg(sentence);
System.out.println(termList);
}
//機構名識別
//可以自動識別地名,標註為ns:
//目前分詞器默認關閉了機構名識別,用戶需要手動開啟;這是因為消耗性能,其實常用機構名都收錄在核心詞典和用戶自定義詞典中。
//HanLP的目的不是演示動態識別,在生產環境中,能靠詞典解決的問題就靠詞典解決,這是最高效穩定的方法。
String[] jgCase = new String[]{
"我在上海林原科技有限公司兼職工作,",
"同時在上海外國語大學日本文化經濟學院學習經濟與外語。",
"我經常在臺川喜宴餐廳吃飯,",
"偶爾去地中海影城看電影。",
};
Segment jgsegment = HanLP.newSegment().enableOrganizationRecognize(true);
for (String sentence : jgCase)
{
List<Term> termList = jgsegment.seg(sentence);
System.out.println(termList);
}
}
private static void analysebysyntax(){
// System.out.println(HanLP.parseDependency("把市場經濟奉行的等價交換原則引入黨的生活和國家機關政務活動中"));
// System.out.println(CRFDependencyParser.compute("把市場經濟奉行的等價交換原則引入黨的生活和國家機關政務活動中"));
}
}