中文分词≠自然语言处理!
中文分词只是第一步;HanLP从中文分词开始,覆盖词性标注、命名实体识别、句法分析、文本分类等常用任务,提供了丰富的API。
不同于一些简陋的分词类库,HanLP精心优化了内部数据结构和IO接口,做到了毫秒级的冷启动、千万字符每秒的处理速度,而内存最低仅需120MB。无论是移动设备还是大型集群,都能获得良好的体验。
不同于市面上的商业工具,HanLP提供训练模块,可以在用户的语料上训练模型并替换默认模型,以适应不同的领域。项目主页上提供了详细的文档,以及在一些开源语料上训练的模型。
HanLP希望兼顾学术界的精准与工业界的效率,在两者之间取一个平衡,真正将自然语言处理普及到生产环境中去。
支持中文分词(N-最短路分词、CRF分词、索引分词、用户自定义词典、词性标注),命名实体识别(中国人名、音译人名、日本人名、地名、实体机构名识别),关键词提取,自动摘要,短语提取,拼音转换,简繁转换,文本推荐,依存句法分析(MaxEnt依存句法分析、神经网络依存句法分析)。提供Lucene插件,兼容Solr和ElasticSearch。
HanLP已经被广泛用于Lucene、Solr、ElasticSearch、Hadoop、Android、Resin等平台,有大量开源作者开发各种插件与拓展,并且被包装或移植到Python、C#、R、JavaScript等语言上去。在线演示。
HanLP: Han Language Processing Fork HanLP 给HanLP点赞 关注HanLP
汉语言处理包
欢迎 fork HanLP! 为HanLP加star是最好的支持! Maven仓库最新版
HanLP是由一系列模型与算法组成的Java工具包,目标是促进自然语言处理在生产环境中的应用。HanLP具备功能完善、性能高效、架构清晰、语料时新、可自定义的特点。
HanLP提供下列功能:
中文分词
最短路分词
N-最短路分词
CRF分词
索引分词
极速词典分词
用户自定义词典
词性标注
命名实体识别
中国人名识别
音译人名识别
日本人名识别
地名识别
实体机构名识别
关键词提取
TextRank关键词提取
自动摘要
TextRank自动摘要
短语提取
基于互信息和左右信息熵的短语提取
拼音转换
多音字
声母
韵母
声调
简繁转换
繁体中文分词
简繁分歧词
文本推荐
语义推荐
拼音推荐
字词推荐
依存句法分析
基于神经网络的高性能依存句法分析器
MaxEnt依存句法分析
CRF依存句法分析
语料库工具
分词语料预处理
词频词性词典制作
BiGram统计
词共现统计
CoNLL语料预处理
CoNLL UA/LA/DA评测工具
在提供丰富功能的同时,HanLP内部模块坚持低耦合、模型坚持惰性加载、服务坚持静态提供、词典坚持明文发布,使用非常方便,同时自带一些语料处理工具,帮助用户训练自己的语料。
项目地址
HanLP项目主页:https://github.com/hankcs/HanLP Fork HanLP 给HanLP点赞 关注HanLP
HanLP下载地址:https://github.com/hankcs/HanLP/releases
Python接口:https://github.com/hankcs/pyhanlp
HanLP在线演示:http://hanlp.hankcs.com/
最新binary、文档都以项目主页为准。博客是一个相对容易编辑的地方,国内访问速度较快,所以用做文档备份。
技术问题请在Github上发issue ,大家一起讨论,也方便集中管理。博客留言、微博私信、邮件不受理任何HanLP相关的问题,谢谢合作!HanLP的GitHub主页是官方指定唯一交流途径,你可以找到最新的版本、最全的文档、最多的社区支持、最丰富的插件。
反馈问题的时候请一定附上版本号、触发代码、输入输出,否则无法处理。
内存要求
内存120MB以上(-Xms120m -Xmx120m -Xmn64m),标准数据包(35万核心词库+默认用户词典),分词测试正常。
全部词典和模型都是惰性加载的,如果你只用拼音转换的话,则只加载拼音词典,未加载的词典相当于不存在,不占内存。同理,模型也是如此。
更新日志
最新版请移步GitHub!
旧版本一览——
2015年7月12日 发布了1.2.4版。在长时间的思考后,决定将用户词典用于分词后的合并处理,使得用户词典中的长词更容易切分出来。
2015年5月11日 发布了1.2.2版。主要支持了并行化,优化了CRF分词,新增了TnT分词器,支持了数量词识别。数据包data-for-1.2.2.zip也做了小幅调整。其实最新的更新日志都可以在GitHub上看到,比博客详细多了,更新也勤快多了。
2015年5月02日 发布了1.1.5版。主要将ACDAT降级为DAT,内存占用减少了一半。所以需要删缓存重新构建,或者下载data-for-1.1.5.zip。另外,还发布了内置数据包的Portable版,可以通过maven直接引入,零配置!
2015年4月28日 发布了1.1.4版。这次训练了一个新的CRF分词模型,感觉效果要好很多(注:该模型与旧版本不兼容)。诸位可以评估一下,提出宝贵意见。
下载与配置
方式一、通过Maven的pom.xml
为了方便用户,特提供内置了数据包的Portable版,只需在pom.xml加入:
请将版本号替换为右图所示最新的版本号:Maven仓库最新版
零配置,即可使用基本功能(除CRF分词、依存句法分析外的全部功能)。连Maven都懒得用的话,可以直接下载portable版的jar。
如果用户有自定义的需求,可以参考方式二,使用hanlp.properties进行配置。
目前Portable体积仅仅5.7MB,作为代价,使用的是1998年的小词典,对现代汉语的支持有限;所以还是建议外挂下面的数据包比较好。
方式二、下载jar、data、hanlp.properties
HanLP将数据与程序分离,给予用户自定义的自由。
1、下载jar
hanlp.jar
2、下载data
数据包 功能 体积(MB)
data.zip 全部词典,全部模型 280(注:分词词典大约40MB,主要是句法分析模型占体积,可以自行删除。)
在GitHub的release页面Ctrl+F搜索data即可,下载后解压到任意目录,接下来通过配置文件告诉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即可,对于任何项目,都可以放到src目录或resources目录下,编译时IDE会自动将其复制到classpath中。
如果放置不当,HanLP会智能提示当前环境下的合适路径,并且尝试从项目根目录读取数据集。
调用方法
HanLP几乎所有的功能都可以通过工具类HanLP快捷调用,当你想不起来调用方法时,只需键入HanLP.,IDE应当会给出提示,并展示HanLP完善的文档。
推荐用户始终通过工具类HanLP调用,这么做的好处是,将来HanLP升级后,用户无需修改调用代码。
所有Demo都位于com.hankcs.demo下。
HanLP中有一系列“开箱即用”的静态分词器,以Tokenizer结尾,在接下来的例子中会继续介绍。
HanLP.segment其实是对StandardTokenizer.segment的包装。
分词结果包含词性,每个词性的意思请查阅《HanLP词性标注集》。
算法详解
《词图的生成》
NLP分词NLPTokenizer会执行全部命名实体识别和词性标注。
索引分词IndexTokenizer是面向搜索引擎的分词器,能够对长词全切分,另外通过term.offset可以获取单词在文本中的偏移量。
N最短路分词器NShortSegment比最短路分词器慢,但是效果稍微好一些,对命名实体识别能力更强。
一般场景下最短路分词的精度已经足够,而且速度比N最短路分词器快几倍,请酌情选择。
算法详解
《N最短路径的Java实现与分词应用》
CRF对新词有很好的识别能力,但是无法利用自定义词典。
算法详解
《CRF分词的纯Java实现》
《CRF++模型格式说明》
极速分词是词典最长分词,速度极其快,精度一般。
在i7上跑出了2000万字每秒的速度。
算法详解
《Aho Corasick自动机结合DoubleArrayTrie极速多模式匹配》
用户自定义词典
public class DemoCustomDictionary
{
public static void main(String[] args)
{
// 动态增加
CustomDictionary.add("攻城狮");
// 强行插入
CustomDictionary.insert("白富美", "nz 1024");
// 删除词语(注释掉试试)
// CustomDictionary.remove("攻城狮");
System.out.println(CustomDictionary.add("单身狗", "nz 1024 n 1"));
System.out.println(CustomDictionary.get("单身狗"));
String text = "攻城狮逆袭单身狗,迎娶白富美,走上人生巅峰"; // 怎么可能噗哈哈!
// DoubleArrayTrie分词
final char[] charArray = text.toCharArray();
CustomDictionary.parseText(charArray, new AhoCorasickDoubleArrayTrie.IHit()
{
@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));
// Note:动态增删不会影响词典文件
// 目前CustomDictionary使用DAT储存词典文件中的词语,用BinTrie储存动态加入的词语,前者性能高,后者性能低
// 之所以保留动态增删功能,一方面是历史遗留特性,另一方面是调试用;未来可能会去掉动态增删特性。
}
说明
CustomDictionary是一份全局的用户自定义词典,可以随时增删,影响全部分词器。
另外可以在任何分词器中关闭它。通过代码动态增删不会保存到词典文件。
追加词典
CustomDictionary主词典文本路径是data/dictionary/custom/CustomDictionary.txt,用户可以在此增加自己的词语(不推荐);也可以单独新建一个文本文件,通过配置文件CustomDictionaryPath=data/dictionary/custom/CustomDictionary.txt; 我的词典.txt;来追加词典(推荐)。
始终建议将相同词性的词语放到同一个词典文件里,便于维护和分享。
词典格式
每一行代表一个单词,格式遵从[单词] [词性A] [A的频次] [词性B] [B的频次] ... 如果不填词性则表示采用词典的默认词性。
词典的默认词性默认是名词n,可以通过配置文件修改:全国地名大全.txt ns;如果词典路径后面空格紧接着词性,则该词典默认是该词性。
关于用户词典的更多信息请参考词典说明一章。
算法详解
《Trie树分词》
《Aho Corasick自动机结合DoubleArrayTrie极速多模式匹配》
目前分词器基本上都默认开启了中国人名识别,比如HanLP.segment()接口中使用的分词器等等,用户不必手动开启;上面的代码只是为了强调。
有一定的误命中率,比如误命中关键年,则可以通过在data/dictionary/person/nr.txt加入一条关键年 A 1来排除关键年作为人名的可能性,也可以将关键年作为新词登记到自定义词典中。
如果你通过上述办法解决了问题,欢迎向我提交pull request,词典也是宝贵的财富。
算法详解
《实战HMM-Viterbi角色标注中国人名识别》
目前分词器基本上都默认开启了音译人名识别,用户不必手动开启;上面的代码只是为了强调。
算法详解
《层叠隐马模型下的音译人名和日本人名识别》
目前标准分词器默认关闭了日本人名识别,用户需要手动开启;这是因为日本人名的出现频率较低,但是又消耗性能。
算法详解
《层叠隐马模型下的音译人名和日本人名识别》
目前标准分词器都默认关闭了地名识别,用户需要手动开启;这是因为消耗性能,其实多数地名都收录在核心词典和用户自定义词典中。
在生产环境中,能靠词典解决的问题就靠词典解决,这是最高效稳定的方法。
算法详解
《实战HMM-Viterbi角色标注地名识别》
目前分词器默认关闭了机构名识别,用户需要手动开启;这是因为消耗性能,其实常用机构名都收录在核心词典和用户自定义词典中。
HanLP的目的不是演示动态识别,在生产环境中,能靠词典解决的问题就靠词典解决,这是最高效稳定的方法。
算法详解
《层叠HMM-Viterbi角色标注模型下的机构名识别》
内部采用TextRankKeyword实现,用户可以直接调用TextRankKeyword.getKeywordList(document, size)
算法详解
《TextRank算法提取关键词的Java实现》
内部采用TextRankSentence实现,用户可以直接调用TextRankSentence.getTopSentenceList(document, size)。
算法详解
《TextRank算法自动摘要的Java实现》
内部采用MutualInformationEntropyPhraseExtractor实现,用户可以直接调用MutualInformationEntropyPhraseExtractor..extractPhrase(text, size)。
算法详解
《基于互信息和左右信息熵的短语提取识别》
HanLP不仅支持基础的汉字转拼音,还支持声母、韵母、音调、音标和输入法首字母首声母功能。
HanLP能够识别多音字,也能给繁体中文注拼音。
最重要的是,HanLP采用的模式匹配升级到AhoCorasickDoubleArrayTrie,性能大幅提升,能够提供毫秒级的响应速度!
算法详解
《汉字转拼音与简繁转换的Java实现》
HanLP能够识别简繁分歧词,比如打印机=印表機。许多简繁转换工具不能区分“以后”“皇后”中的两个“后”字,HanLP可以。
算法详解
《汉字转拼音与简繁转换的Java实现》
在搜索引擎的输入框中,用户输入一个词,搜索引擎会联想出最合适的搜索词,HanLP实现了类似的功能。
可以动态调节每种识别器的权重
设想的应用场景是搜索引擎对词义的理解,词与词并不只存在“同义词”与“非同义词”的关系,就算是同义词,它们之间的意义也是有微妙的差别的。
算法
为每个词分配一个语义ID,词与词的距离通过语义ID的差得到。语义ID通过《同义词词林扩展版》计算而来。
内部采用NeuralNetworkDependencyParser实现,用户可以直接调用NeuralNetworkDependencyParser.compute(sentence)
也可以调用基于MaxEnt的依存句法分析器MaxEntDependencyParser.compute(sentence)
算法详解
《基于神经网络的高性能依存句法分析器》
《最大熵依存句法分析器的实现》
《基于CRF序列标注的中文依存句法分析器的Java实现》
词典说明
本章详细介绍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,这是我在代码库中保留明文词典的原因,众人拾柴火焰高!
版权
HanLP的初始版本于2014年初开发,原本是一个搜索项目期间的业余作品,在部分NLP开发者群中发布以后,得到了不少开发人员的鼓舞,包括上海林原公司的刘祥春先生也鼓励我把这个项目开源,随即我对HanLP项目做了进一步的完善,2015年3月HanLP终于最为一个开源项目在maven中央库以及Github上开源。
HanLP项目的初期得到了上海林原信息科技有限公司(以下简称:林原公司)的大力支持,并且林原公司还提供了HanLP项目的服务器空间,以及下载服务。因此HanLP v1.2.8及其以前的版本,我把版权授予了上海林原公司。
其后,我作为大快公司的自然语言处理项目的主要负责人,继续在自然语言处理方面从事研究和开发工作,研发了多个自然语言处理的子模块,集成在公司产品DKNLP中。不久以后,大快搜索便决定将DKNLP技术成果彻底开源,整体装入HanLP项目(由大快首席科学家汤连杰先生提议)。这让HanLP几乎脱胎换骨,使得每个模块都带来一次重大的提升,极大的丰富了其功能,HanLP的版本号也迅速提升到了v1.5.0。
因此,HanLP v1.2.8及其以前的版本经我授权,版权归上海林原公司,并在上海林源公司提供的空间上下载。
HanLP v1.3以后的版本为大快搜索主导,v1.5及其以后版本的项目说明以及下载,在大快搜索的服务器上(下载地址:hanlp.dksou.com)。HanLP项目的原始著作人和主要开发人员,始终是我,也始终遵循apache协议进行开源。感谢大家对HanLP的喜爱和支持。
Apache License Version 2.0
如不特殊注明,所有模块都以此协议授权使用。
上海林原信息科技有限公司
HanLP产品初始知识产权归上海林原信息科技有限公司所有,任何人和企业可以无偿使用,可以对产品、源代码进行任何形式的修改,可以打包在其他产品中进行销售。
任何使用了HanLP的全部或部分功能、词典、模型的项目、产品或文章等形式的成果必须显式注明HanLP及此项目主页。
其他版权方
1.5版由大快公司开源了多个模块,详见声明。
充分尊重所有版权方的贡献,本项目不占有这些新模块的版权。
鸣谢
感谢下列优秀开源项目:
darts-clone-java
aho-corasick
SharpICTCLAS
snownlp
ansj_seg
nlp-lang
感谢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爱好者多多关照,提出宝贵意见。
文章来源于网络
转载于:https://blog.51cto.com/13993767/2313915