开源Hanlp自然语言处理Java实现(词法分析、关键词)

  • Hanlp自然语言
  • 介绍
  • 开源动态
  • Hanlp Java实现
  • 通过Maven的pom.xml
  • 结合Data数据包使用hanlp


Hanlp自然语言

介绍

HanLP是由一系列模型与算法组成的Java工具包,目标是促进自然语言处理在生产环境中的应用。HanLP具备功能完善、性能高效、架构清晰、语料时新、可自定义的特点。

开源动态

官网:https://www.hanlp.com/
码农场:http://www.hankcs.com/nlp/hanlp.html
github:https://github.com/hankcs/HanLP/releases

Hanlp Java实现

通过Maven的pom.xml

maven引入:为了方便用户,Hanlp特提供内置了数据包的Portable版,只需在pom.xml加入:(目前最新版为1.8.2)

<dependency>
  <groupId>com.hankcs</groupId>
  <artifactId>hanlp</artifactId>
  <version>portable-1.8.2</version>
</dependency>

portable版本零配置,即可使用基本功能(除CRF分词、依存句法分析外的全部功能),作为代价,使用的是1998年的小词典,对现代汉语的支持有限;所以不建议生产环境使用,建议结合Data数据包使用

结合Data数据包使用hanlp

1、下载Data数据包(hanlp1.7.5版)
https://file.hankcs.workers.dev/hanlp/data-for-1.7.5.zip2、配置文件:hanlp.properties(官方版)

#本配置文件中的路径的根目录,根目录+其他路径=完整路径(支持相对路径,请参考:https://github.com/hankcs/HanLP/pull/254)
#Windows用户请注意,路径分隔符统一使用/
root=E:/hanlp/data-for-1.7.5/

#好了,以上为唯一需要修改的部分,以下配置项按需反注释编辑。

#核心词典路径
#CoreDictionaryPath=data/dictionary/CoreNatureDictionary.txt
#2元语法词典路径
#BiGramDictionaryPath=data/dictionary/CoreNatureDictionary.ngram.txt
#自定义词典路径,用;隔开多个自定义词典,空格开头表示在同一个目录,使用“文件名 词性”形式则表示这个词典的词性默认是该词性。优先级递减。
#所有词典统一使用UTF-8编码,每一行代表一个单词,格式遵从[单词] [词性A] [A的频次] [词性B] [B的频次] ... 如果不填词性则表示采用词典的默认词性。
CustomDictionaryPath=data/dictionary/custom/CustomDictionary.txt; 现代汉语补充词库.txt; 全国地名大全.txt ns; 人名词典.txt; 机构名词典.txt; 上海地名.txt ns;data/dictionary/person/nrf.txt nrf;
#停用词词典路径
#CoreStopWordDictionaryPath=data/dictionary/stopwords.txt
#同义词词典路径
#CoreSynonymDictionaryDictionaryPath=data/dictionary/synonym/CoreSynonym.txt
#人名词典路径
#PersonDictionaryPath=data/dictionary/person/nr.txt
#人名词典转移矩阵路径
#PersonDictionaryTrPath=data/dictionary/person/nr.tr.txt
#繁简词典根目录
#tcDictionaryRoot=data/dictionary/tc
#HMM分词模型
#HMMSegmentModelPath=data/model/segment/HMMSegmentModel.bin
#分词结果是否展示词性
#ShowTermNature=true
#IO适配器,实现com.hankcs.hanlp.corpus.io.IIOAdapter接口以在不同的平台(Hadoop、Redis等)上运行HanLP
#默认的IO适配器如下,该适配器是基于普通文件系统的。
#IOAdapter=com.hankcs.hanlp.corpus.io.FileIOAdapter
#感知机词法分析器
#PerceptronCWSModelPath=data/model/perceptron/pku1998/cws.bin
#PerceptronPOSModelPath=data/model/perceptron/pku1998/pos.bin
#PerceptronNERModelPath=data/model/perceptron/pku1998/ner.bin
#CRF词法分析器
#CRFCWSModelPath=data/model/crf/pku199801/cws.txt
#CRFPOSModelPath=data/model/crf/pku199801/pos.txt
#CRFNERModelPath=data/model/crf/pku199801/ner.txt
#更多配置项请参考 https://github.com/hankcs/HanLP/blob/master/src/main/java/com/hankcs/hanlp/HanLP.java#L59 自行添加

将配置文件放入和jar包同一位置

3、Java使用
(1)第一个Demo

System.out.println(HanLP.segment("你好,欢迎使用HanLP汉语处理包!"));

结果:

hanlp教程 hanlp原理_List


(2)经典标准分词,Demo

List<Term> termList = StandardTokenizer.segment("商品和服务");
	System.out.println(termList);

结果:

hanlp教程 hanlp原理_List_02


说明:HanLP中有一系列“开箱即用”的静态分词器,以Tokenizer结尾,在接下来的例子中会继续介绍。

HanLP.segment其实是对StandardTokenizer.segment的包装。

分词结果包含词性,每个词性的意思请查阅《HanLP词性标注集》
(3)NLP分词,Demo

List<Term> termList = NLPTokenizer.segment("中国科学院计算技术研究所的宗成庆教授正在教授自然语言处理课程");
	System.out.println(termList);

结果:

hanlp教程 hanlp原理_java_03

说明:NLP分词NLPTokenizer会执行全部命名实体识别和词性标注。

(4)索引分词,Demo

List<Term> termList = IndexTokenizer.segment("主副食品");
    for (Term term : termList)
    {
        System.out.println(term + " [" + term.offset + ":" + (term.offset + term.word.length()) + "]");
    }

结果:

hanlp教程 hanlp原理_深度学习_04


说明:索引分词IndexTokenizer是面向搜索引擎的分词器,能够对长词全切分,另外通过term.offset可以获取单词在文本中的偏移量。

(5)N-最短路径分词,Demo

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));
    }

结果:

hanlp教程 hanlp原理_java_05


说明:N最短路分词器NShortSegment比最短路分词器慢,但是效果稍微好一些,对命名实体识别能力更强。

一般场景下最短路分词的精度已经足够,而且速度比N最短路分词器快几倍,请酌情选择。

(6)CRF分词,Demo

HanLP.Config.ShowTermNature = false;    // 关闭词性显示
    Segment segment = new CRFLexicalAnalyzer();//旧版本使用的是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);
    }

结果:

hanlp教程 hanlp原理_词性_06


说明:CRF对新词有很好的识别能力,但是无法利用自定义词典

(7)关键词提取,Demo

String content = "程序员(英文Programmer)是从事程序开发、维护的专业人员。一般将程序员分为程序设计人员和程序编码人员,但两者的界限并不非常清楚,特别是在中国。软件从业人员分为初级程序员、高级程序员、系统分析员和项目经理四大类。";
    List<String> keywordList = HanLP.extractKeyword(content, 5);
    System.out.println(keywordList);

结果:

hanlp教程 hanlp原理_List_07


说明:内部采用TextRankKeyword实现,用户可以直接调用TextRankKeyword.getKeywordList(document, size)

《TextRank算法提取关键词的Java实现》Demo结束

hanlp教程 hanlp原理_深度学习_08


hanlp结合了非常多的词法分析算法,在文字处理分析上基本满足通用需求,更多的Demo请到http://www.hankcs.com/nlp/hanlp.html和https://github.com/hankcs/HanLP/releases查看