hanlp分词
为什么要使用hanlp分词?
词典分词的精度并不是很好,分词在于速度而不是精度。hanlp在准确度相对精准的情况下能够做到速度也相对快
长短文本分词特性:
hanlp所有的分词器都是继承自Segment这个基类
如果是短文本优先考虑:DoubleArrayTrieSegment(DAT)
如果是长文本就考虑使用:AhoCorasickDoubleArrayTrieSegment(ACDAT)
建议就是如果需要对文本进行分词就可以直接使用DAT字典树,如果不需要对文本进行分词的化就可以直接进行敏感词过滤然后使用ACDAT
DoubleArrayTrieSegment
from pyhanlp import *
HanLP.Config.ShowTermNature = False
segment = DoubleArrayTrieSegment()
print(segment.seg('江西鄱阳湖干枯,中国最大淡水湖变成大草原'))
[江西, 鄱阳湖, 干枯, ,, 中国, 最大, 淡水湖, 变成, 大草原]
分词的时候是否显示词性
HanLP.Config.ShowTermNature = False
定义一个DAT分词模型
segment = DoubleArrayTrieSegment()
激活数字和字母识别
segment.enablePartOfSpeechTagging(True)
HanLP.Config.ShowTermNature = True
segment.enablePartOfSpeechTagging(True)
for term in segment.seg("上海市虹口区大连西路550号SISU"):
print("单词:%s 词性:%s"%(term.word,term.nature))
单词:上海市 词性:ns
单词:虹口区 词性:ns
单词:大连 词性:ns
单词:西路 词性:n
单词:550 词性:m
单词:号 词性:q
单词:SISU 词性:nx
AhoCorasickDoubleArrayTrieSegment
segment=JClass("com.hankcs.hanlp.seg.Other.AhoCorasickDoubleArrayTrieSegment")()
HanLP.Config.ShowTermNature = False
print(segment.seg("江西鄱阳湖干枯,中国最大淡水湖变成大草原"))
[江西, 鄱阳湖, 干枯, ,, 中国, 最大, 淡水湖, 变成, 大草原]
ACDAT的速度会比DAT速度慢一点但是处理长文本比DAT的准确率会高一些。这里这是因为这个文本本身比较短而已。
停用词
复杂方式
from jpype import JString
from pyhanlp import *
def load_from_file(path):
"""
从词典文件加载DoubleArrayTrie
:param path: 词典路径
:return: 双数组trie树
"""
map = JClass('java.util.TreeMap')() # 创建TreeMap实例
with open(path) as src:
for word in src:
word = word.strip() # 去掉Python读入的\n
map[word] = word
return JClass('com.hankcs.hanlp.collection.trie.DoubleArrayTrie')(map)
def load_from_words(*words):
"""
从词汇构造双数组trie树
:param words: 一系列词语
:return:
"""
map = JClass('java.util.TreeMap')() # 创建TreeMap实例
for word in words:
map[word] = word
return JClass('com.hankcs.hanlp.collection.trie.DoubleArrayTrie')(map)
def remove_stopwords_termlist(termlist, trie):
return [term.word for term in termlist if not trie.containsKey(term.word)]
def replace_stropwords_text(text, replacement, trie):
searcher = trie.getLongestSearcher(JString(text), 0)
offset = 0
result = ''
while searcher.next():
begin = searcher.begin
end = begin + searcher.length
if begin > offset:
result += text[offset: begin]
result += replacement
offset = end
if offset < len(text):
result += text[offset:]
return result
if __name__ == '__main__':
HanLP.Config.ShowTermNature = False
trie = load_from_file(HanLP.Config.CoreStopWordDictionaryPath)
text = "停用词的意义相对而言无关紧要吧。"
segment = DoubleArrayTrieSegment()
termlist = segment.seg(text)
print("分词结果:", termlist)
print("分词结果去除停用词:", remove_stopwords_termlist(termlist, trie))
trie = load_from_words("的", "相对而言", "吧")
print("不分词去掉停用词", replace_stropwords_text(text, "**", trie))
分词结果: [停用, 词, 的, 意义, 相对而言, 无关紧要, 吧, 。]
分词结果去除停用词: ['停用', '词', '意义', '无关紧要']
不分词去掉停用词 停用词**意义**无关紧要**。
简单方式
# 使用停用词的简单例子
text = "停用词的意义相对而言无关紧要吧"
CRFnewSegment = HanLP.newSegment("crf")
term_list = CRFnewSegment.seg(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])
[停用词, 意义, 相对]
['停用词', '意义', '相对']