HanLP 是一系列模型与算法组成的 NLP 工具包,目标是普及自然语言处理在生产环境中的应用。HanLP 具备功能完善、性能高效、架构清晰、语料时新、可自定义的特点。内部算法经过工业界和学术界考验,配套书籍《自然语言处理入门》已经出版。

目前,基于深度学习的 HanLP 2.0 正处于 alpha 测试阶段,未来将实现知识图谱、问答系统、自动摘要、文本语义相似度、指代消解、三元组抽取、实体链接等功能。

支持功能

在介绍 HanLP 的功能之前,首先要明确的是 HanLP 的分析输入是线程安全。

HanLP 的设计思路是所有分析输入数据的接口(分词、句法、文本分类等等)都是线程安全的。因为设计上将中间结果保存在参数栈上,保证了不修改分析器的状态。而配置接口恰好需要修改分析器的状态,所以不是线程安全的。在多线程场景下,一般不需要额外注意。如果需要动态配置分析器,则需要给分析器加锁。当然,大部分时候都是启动时配置好,之后不再更改,这样效率最高。

HanLP 提供下列功能:

  • 中文分词
    • HMM-Bigram(速度与精度最佳平衡;一百兆内存)
      • 最短路分词、N-最短路分词
    • 由字构词(侧重精度,全世界最大语料库,可识别新词;适合 NLP 任务)
      • 感知机分词、CRF 分词
    • 词典分词(侧重速度,每秒数千万字符;省内存)
      • 极速词典分词
    • 所有分词器都支持:
      • 索引全切分模式
      • 用户自定义词典
      • 兼容繁体中文
      • 训练用户自己的领域模型
  • 词性标注
    • HMM 词性标注(速度快)
    • 感知机词性标注、CRF 词性标注(精度高)
  • 命名实体识别
    • 基于 HMM 角色标注的命名实体识别 (速度快)
      • 中国人名识别、音译人名识别、日本人名识别、地名识别、实体机构名识别
    • 基于线性模型的命名实体识别(精度高)
      • 感知机命名实体识别、CRF 命名实体识别
  • 关键词提取
    • TextRank 关键词提取
  • 自动摘要
    • TextRank 自动摘要
  • 短语提取
    • 基于互信息和左右信息熵的短语提取
  • 拼音转换
    • 多音字、声母、韵母、声调
  • 简繁转换
    • 简繁分歧词(简体、繁体、臺灣正體、香港繁體)
  • 文本推荐
    • 语义推荐、拼音推荐、字词推荐
  • 依存句法分析
    • 基于神经网络的高性能依存句法分析器
    • 基于 ArcEager 转移系统的柱搜索依存句法分析器
  • 文本分类
    • 情感分析
  • 文本聚类
    • KMeans、Repeated Bisection、自动推断聚类数目 k
  • word2vec
    • 词向量训练、加载、词语相似度计算、语义运算、查询、KMeans 聚类
    • 文档语义相似度计算
  • 语料库工具

在提供丰富功能的同时,HanLP 内部模块坚持低耦合、模型坚持惰性加载、服务坚持静态提供、词典坚持明文发布,使用非常方便。默认模型训练自全世界最大规模的中文语料库,同时自带一些语料处理工具,帮助用户训练自己的模型。

下载与配置

方式一、Maven/Gradle 等

为了方便用户,特提供内置了数据包的 Portable 版。

对于 Maven 只需在 pom.xml 加入如下坐标即可:

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

若 gradle 的项目管理方式,示例如下:

compile group: 'com.hankcs', name: 'hanlp', version: 'portable-1.7.6'

具体不同版本可以到 maven repository 的相关网站去查看 https://mvnrepository.com/artifact/com.hankcs/hanlp。

像如上这种方式一直接到导入使用的,都是零配置,即可使用基本功能(除由字构词、依存句法分析外的全部功能)。如果用户有自定义的需求,可以参考方式二,使用 hanlp.properties 进行配置(portable 版同样支持 hanlp.properties)。

方式二、下载 jar、data、hanlp.properties

HanLP 将数据与程序分离,给予用户自定义的自由。

1、下载:data.zip

下载后解压到任意目录,接下来通过配置文件告诉 HanLP 数据包的位置。

HanLP 中的数据分为词典模型,其中词典是词法分析必需的模型是句法分析必需的

data
│
├─dictionary
└─model

用户可以自行增删替换,如果不需要句法分析等功能的话,随时可以删除 model 文件夹。

  • 模型跟词典没有绝对的区别,隐马模型被做成人人都可以编辑的词典形式,不代表它不是模型。
  • GitHub 代码库中已经包含了 data.zip 中的词典,直接编译运行自动缓存即可;模型则需要额外下载。

2、下载jar和配置文件:hanlp-release.zip

配置文件的作用是告诉 HanLP 数据包的位置,一般只需修改第一行:

root=D:/JavaProjects/HanLP/

为 data 的父目录即可,比如 data 目录是 /Users/hankcs/Documents/data,那么 root=/Users/hankcs/Documents/。

最后将 hanlp.properties 放入 classpath 即可,对于多数项目,都可以放到 src 或 resources 目录下,编译时 IDE 会自动将其复制到 classpath 中。除了配置文件外,还可以使用环境变量 HANLP_ROOT 来设置 root。

具体的 hanlp.properties 内容如下:

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

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

# 核心词典路径
# 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 自行添加

HanLP 词性标注集

HanLP 使用的 HMM 词性标注模型训练自 2014 年人民日报切分语料,随后增加了少量 98 年人民日报中独有的词语。所以,HanLP 词性标注集兼容《ICTPOS 3.0 汉语词性标记集》,并且兼容《现代汉语语料库加工规范——词语切分与词性标注》。

HanLP 词性标注集
标注符 词性说明 标注符 词性说明 标注符 词性说明
a 形容词 nmc 化学品名 udeng 等 等等 云云
ad 副形词 nn 工作相关名词 udh 的话
ag 形容词性语素 nnd 职业 ug
al 形容词性惯用语 nnt 职务职称 uguo
an 名形词 nr 人名 uj 助词
b 区别词 nr1 复姓 ul 连词
begin 仅用于始##始 nr2 蒙古姓名 ule 了 喽
bg 区别语素 nrf 音译人名 ulian 连 (“连小学生都会”)
bl 区别词性惯用语 nrj 日语人名 uls 来讲 来说 而言 说来
c 连词 ns 地名 usuo
cc 并列连词 nsf 音译地名 uv 连词
d 副词 nt 机构团体名 uyy 一样 一般 似的 般
dg 辄,俱,复之类的副词 ntc 公司名 uz
dl 连语 ntcb 银行 uzhe
e 叹词 ntcf 工厂 uzhi
end 仅用于终##终 ntch 酒店宾馆 v 动词
f 方位词 nth 医院 vd 副动词
g 学术词汇 nto 政府机构 vf 趋向动词
gb 生物相关词汇 nts 中小学 vg 动词性语素
gbc 生物类别 ntu 大学 vi 不及物动词(内动词)
gc 化学相关词汇 nx 字母专名 vl 动词性惯用语
gg 地理地质相关词汇 nz 其他专名 vn 名动词
gi 计算机相关词汇 o 拟声词 vshi 动词“是”
gm 数学相关词汇 p 介词 vx 形式动词
gp 物理相关词汇 pba 介词“把” vyou 动词“有”
h 前缀 pbei 介词“被” w 标点符号
i 成语 q 量词 wb 百分号千分号,全角:% ‰   半角:%
j 简称略语 qg 量词语素 wd 逗号,全角:, 半角:,
k 后缀 qt 时量词 wf 分号,全角:; 半角: ;
l 习用语 qv 动量词 wh 单位符号,全角:¥ $ £  °  ℃  半角:$
m 数词 r 代词 wj 句号,全角:。
mg 数语素 rg 代词性语素 wky 右括号,全角:) 〕  ] } 》  】 〗 〉 半角: ) ] { >
Mg 甲乙丙丁之类的数词 Rg 古汉语代词性语素 wkz 左括号,全角:( 〔  [  {  《 【  〖 〈   半角:( [ { <
mq 数量词 rr 人称代词 wm 冒号,全角:: 半角: :
n 名词 ry 疑问代词 wn 顿号,全角:、
nb 生物名 rys 处所疑问代词 wp 破折号,全角:——   --   ——-   半角:—  —-
nba 动物名 ryt 时间疑问代词 ws 省略号,全角:……  …
nbc 动物纲目 ryv 谓词性疑问代词 wt 叹号,全角:!
nbp 植物名 rz 指示代词 ww 问号,全角:?
nf 食品,比如“薯片” rzs 处所指示代词 wyy 右引号,全角:” ’ 』
ng 名词性语素 rzt 时间指示代词 wyz 左引号,全角:“ ‘ 『
nh 医药疾病等健康相关名词 rzv 谓词性指示代词 x 字符串
nhd 疾病 s 处所词 xu 网址 URL
nhm 药品 t 时间词 xx 非语素字
ni 机构相关(不是独立机构名) tg 时间词性语素 y 语气词(delete yg)
nic 下属机构 u 助词 yg 语气语素
nis 机构后缀 ud 助词 z 状态词
nit 教育相关机构 ude1 的 底 zg 状态词
nl 名词性惯用语 ude2    
nm 物品名 ude3    

分词

HanLP 分词有多种形式的,有基于双数组字典树(DAT)的,有基于隐马尔可夫模型(HMM)的,还有基于感知机(Perceptron)的,还有基于条件随机场(CRF)模型的。

极速词典分词

极速分词,基于双数组字典树(Double Array Trie)实现的词典分词,适用于“高吞吐量”“精度一般”的场合。

public class SpeedSegmentDemo {

    public static void main(String[] args) {

        String text = "五四广场位于山东省青岛市市南区东海西路,北依青岛市人民政府办公大楼,南临浮山湾,总占地面积10公顷。";
        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-6700K 上跑出了 4500 万字每秒的速度。
  • 算法详解