jieba是我们最常用的分词包,其分词效率远高于其他基于神经网络的工具。
jieba带有词典功能,但对于一些特殊的词,配置进词典却不起作用......
问题
看下面这个例子,添加带有·和 的词进分词词典,却不能正确分词。
jieba.__version__ = '0.42.1'
import jieba
jieba.add_word("鲁路修·兰佩路基")
res = jieba.lcut("鲁路修·兰佩路基")
print(res)
jieba.add_word("鲁路修 兰佩路基")
res = jieba.lcut("鲁路修 兰佩路基")
print(res)
['鲁路', '修', '·', '兰佩', '路基']
['鲁路', '修', ' ', '兰佩', '路基']
解决方案
添加两行代码即可
import jieba
import re
jieba.re_han_default = re.compile("([\u4E00-\u9FD5a-zA-Z0-9+#&\._%\-· ]+)", re.U)
jieba.add_word("鲁路修·兰佩路基")
res = jieba.lcut("鲁路修·兰佩路基")
print(res)
jieba.add_word("鲁路修 兰佩路基")
res = jieba.lcut("鲁路修 兰佩路基")
print(res)
['鲁路修·兰佩路基']
['鲁路修 兰佩路基']
原理
首先看一下jieba分词的逻辑,仅截取相关部分
re_han_default = re.compile("([\u4E00-\u9FD5a-zA-Z0-9+#&._%-]+)", re.U)
re_han = re_han_default
blocks = re_han.split(sentence)
for blk in blocks:
if re_han.match(blk):
for word in cut_block(blk):
yield word
jieba首先将输入进行分块,分块的依据是re_han_default里定义的字符。可以看到,字符中不包含测试使用到的·和 ,所以在这步,输入的鲁路修·兰佩路基已经被切成['', '鲁路修', '·', '兰佩路基', ''],在接下来对每块进行分词中,并没有包含在词典中的词了,所以未能正确分词。
因此,为了避免包含·和 的词被切分,将blocks划分的正则中添加这些字符,即可解决问题,如解决方案部分所呈现。