hanlp的词典模式java
以前咱们看了hanlp的词性标注,如今咱们就要使用自定义词典与停用词功能了,首先关于HanLP的词性标注方式具体请看HanLP词性标注集。数组
其核心词典形式以下:缓存
自定义词典数据结构
自定义词典有多种添加模式,首先是展现的一个小例子,展现了词汇的动态增长与强行插入,删除等。更复杂的内容请参考后边的第二段代码。app
简单的例子编辑器
from pyhanlp import *函数
text = "攻城狮逆袭单身狗,迎娶白富美,走上人生巅峰" # 怎么可能噗哈哈!性能
print(HanLP.segment(text))编码
CustomDictionary = JClass("com.hankcs.hanlp.dictionary.CustomDictionary")spa
CustomDictionary.add("攻城狮") # 动态增长
CustomDictionary.insert("白富美", "nz 1024") # 强行插入
#CustomDictionary.remove("攻城狮"); # 删除词语(注释掉试试)
CustomDictionary.add("单身狗", "nz 1024 n 1")
# 展现该单词词典中的词频统计 展现分词
print(CustomDictionary.get("单身狗"))
print(HanLP.segment(text))
# 增长用户词典,对其余分词器一样有效
# 注意此处,CRF分词器将单身狗分为了n 即便单身狗:"nz 1024 n 1"
CRFnewSegment = HanLP.newSegment("crf")
print(CRFnewSegment.seg(text))
[攻城狮, 逆袭, 单身狗, ,, 迎娶, 白富美, ,, 走上, 人生, 巅峰]
nz 1024 n 1
[攻城狮, 逆袭, 单身狗, ,, 迎娶, 白富美, ,, 走上, 人生, 巅峰]
[攻城, 狮逆袭, 单身狗, ,, 迎娶, 白富美, ,, 走, 上, 人生, 巅峰]
复杂的例子
""" 演示自定义词性,以及往词典中插入自定义词性的词语
!!!因为采用了反射技术,用户需对本地环境的兼容性和稳定性负责!!!
TO-DO
若是使用了动态词性以后任何类使用了switch(nature)语句,必须注册每一个类
"""
# 对于系统中已有的词性,能够直接获取
Nature = JClass("com.hankcs.hanlp.corpus.tag.Nature")
pc_nature = Nature.fromString("n")
print(pc_nature)
# 此时系统中没有"电脑品牌"这个词性
pc_nature = Nature.fromString("电脑品牌")
print(pc_nature)
# 咱们能够动态添加一个
pc_nature = Nature.create("电脑品牌");
print(pc_nature)
# 能够将它赋予到某个词语
LexiconUtility = JClass("com.hankcs.hanlp.utility.LexiconUtility")
LexiconUtility.setAttribute("苹果电脑", pc_nature)
# 或者
LexiconUtility.setAttribute("苹果电脑", "电脑品牌 1000")
# 它们将在分词结果中生效
term_list = HanLP.segment("苹果电脑能够运行开源阿尔法狗代码吗")
print(term_list)
for term in term_list:
if term.nature == pc_nature:
print("找到了 [{}] : {}\n".format(pc_nature, term.word))
# 还能够直接插入到用户词典
CustomDictionary = JClass("com.hankcs.hanlp.dictionary.CustomDictionary")
CustomDictionary.insert("阿尔法狗", "科技名词 1024")
StandardTokenizer = JClass("com.hankcs.hanlp.tokenizer.StandardTokenizer")
StandardTokenizer.SEGMENT.enablePartOfSpeechTagging(True) # 依然支持隐马词性标注
term_list = HanLP.segment("苹果电脑能够运行开源阿尔法狗代码吗")
print(term_list)
n
None
电脑品牌
[苹果电脑/电脑品牌, 能够/v, 运行/vn, 开源/v, 阿尔法/nrf, 狗/n, 代码/n, 吗/y]
找到了 [电脑品牌] : 苹果电脑
[苹果电脑/电脑品牌, 能够/v, 运行/vn, 开源/v, 阿尔法狗/科技名词, 代码/n, 吗/y]
关于自定义词典的说明(原做者的原文)
说明
追加词典
词典格式
停用词
关于停用词,我一样先给出了一个简单的例子,你可使用这个例子来完成你所须要的功能。要注意的一点是,由于java中的类所返回的数据类型与Python不统一,因此当你使用不一样的函数的时候,必定要先检查输出结果在Python中的类型,否则可能会出现意想不到的问题。
假如你想了解更多,能够看第二个更复杂的例子。
简单的例子
# 使用停用词的简单例子
text = "小区居民有的反对喂养流浪猫"
CRFnewSegment = HanLP.newSegment("crf")
term_list = CRFnewSegment.seg(text)
# BasicTokenizer = SafeJClass("com.hankcs.hanlp.tokenizer.BasicTokenizer")
# term_list = BasicTokenizer.segment(text)
CoreStopWordDictionary = JClass("com.hankcs.hanlp.dictionary.stopword.CoreStopWordDictionary")
CoreStopWordDictionary.apply(term_list)
HanLP.Config.ShowTermNature = False
print(term_list)
print([i.word for i in term_list])
[小区, 居民, 反对, 养, 流, 浪, 猫]
['小区', '居民', '反对', '养', '流', '浪', '猫']
复杂的例子
# 停用词
# 在import pyhanlp以前编译本身的Java class,并放入pyhanlp/static中
import os
from pyhanlp.static import STATIC_ROOT, HANLP_JAR_PATH
java_code_path = os.path.join(STATIC_ROOT, 'MyFilter.java')
with open(java_code_path, 'w') as out:
java_code = """
import com.hankcs.hanlp.dictionary.stopword.CoreStopWordDictionary;
import com.hankcs.hanlp.dictionary.stopword.Filter;
import com.hankcs.hanlp.seg.common.Term;
public class MyFilter implements Filter
{
public boolean shouldInclude(Term term)
{
if (term.nature.startsWith('m')) return true; // 数词保留
return !CoreStopWordDictionary.contains(term.word); // 停用词过滤
}
}
"""
out.write(java_code)
os.system('javac -cp {} {} -d {}'.format(HANLP_JAR_PATH, java_code_path, STATIC_ROOT))
# 编译结束才能够启动hanlp
CoreStopWordDictionary = JClass("com.hankcs.hanlp.dictionary.stopword.CoreStopWordDictionary")
Filter = JClass("com.hankcs.hanlp.dictionary.stopword.Filter")
Term = JClass("com.hankcs.hanlp.seg.common.Term")
BasicTokenizer = JClass("com.hankcs.hanlp.tokenizer.BasicTokenizer")
NotionalTokenizer = JClass("com.hankcs.hanlp.tokenizer.NotionalTokenizer")
text = "小区居民有的反对喂养流浪猫,而有的居民却同意喂养这些小宝贝"
# 能够动态修改停用词词典
CoreStopWordDictionary.add("居民")
print(NotionalTokenizer.segment(text))
CoreStopWordDictionary.remove("居民")
print(NotionalTokenizer.segment(text))
# 能够对任意分词器的结果执行过滤
term_list = BasicTokenizer.segment(text)
print(term_list)
CoreStopWordDictionary.apply(term_list)
print(term_list)
# 还能够自定义过滤逻辑
MyFilter = JClass('MyFilter')
CoreStopWordDictionary.FILTER = MyFilter()
print(NotionalTokenizer.segment("数字123的保留")) # “的”位于stopwords.txt因此被过滤,数字获得保留
[小区/n, 反对/v, 喂养/v, 流浪猫/nz, 同意/v, 喂养/v, 小宝贝/nz]
[小区/n, 居民/n, 反对/v, 喂养/v, 流浪猫/nz, 居民/n, 同意/v, 喂养/v, 小宝贝/nz]
[小区/n, 居民/n, 有/vyou, 的/ude1, 反对/v, 喂养/v, 流浪猫/nz, ,/w, 而/cc, 有的/rz, 居民/n, 却/d, 同意/v, 喂养/v, 这些/rz, 小宝贝/nz]
[小区/n, 居民/n, 反对/v, 喂养/v, 流浪猫/nz, 居民/n, 同意/v, 喂养/v, 小宝贝/nz]
[数字/n, 123/m, 保留/v]
词典说明(原做者原文)
本章详细介绍HanLP中的词典格式,知足用户自定义的须要。HanLP中有许多词典,它们的格式都是类似的,形式都是文本文档,随时能够修改。
基本格式
词典分为词频词性词典和词频词典。
词频词性词典(如CoreNatureDictionary.txt)
词频词典(如CoreNatureDictionary.ngram.txt)
少数词典有本身的专用格式,好比同义词词典兼容《同义词词林扩展版》的文本格式,而转移矩阵词典则是一个csv表格。
下文主要介绍通用词典,如不注明,词典特指通用词典。
数据结构
Trie树(字典树)是HanLP中使用最多的数据结构,为此,我实现了通用的Trie树,支持泛型、遍历、储存、载入。
用户自定义词典采用AhoCorasickDoubleArrayTrie和二分Trie树储存,其余词典采用基于双数组Trie树(DoubleArrayTrie)实现的AC自动机AhoCorasickDoubleArrayTrie。关于一些经常使用数据结构的性能评估,请参考wiki。
储存形式
词典有两个形态:文本文件(filename.txt)和缓存文件(filename.txt.bin或filename.txt.trie.dat和filename.txt.trie.value)。
文本文件
缓存文件
修改方法
HanLP的核心词典训练自人民日报2014语料,语料不是完美的,总会存在一些错误。这些错误可能会致使分词出现奇怪的结果,这时请打开调试模式排查问题:(本文做者FontTian注:在本文动笔前,原词典一进变为了9970万版本的最大中文语料。可是词典说明中原做者没改)
HanLP.Config.enableDebug();
核心词性词频词典
核心二元文法词典
命名实体识别词典
文章来源 FonTIan 的博客