前文传送门:
从零开始学自然语言处理(七)—— 句法结构分析
小编喜欢用 jieba 分词,是因为它操作简单,速度快,而且可以添加自定义词,从而让 jieba 分出你想要分出的词,特别适用于特定场景的中文分词任务。
然鹅,万事都有两面性,jieba 分词这么好用,也难免有缺陷。
第一大缺陷就是它占用内存太大了。jieba 分词自带了一套默认的字典文件dict.txt
,存放在xx/Lib/site-packages/jieba
路径下,文件大小接近 5M。5M 看起来不大,但是当 jieba 将其读入并生成字典树时,占用的内存差不多就上涨到 150M。当然了,150M 我们也能忍受,但是当我们需要把 jieba 部署到真正的生产环境,可能会使用多个 jieba 对象,这个时候内存占用率就会成倍的增加。那么如何减小 jieba 内存的占用呢?
结巴瘦身
既然 jieba 占据内存多的原因是字典树太大,那我们把dict.txt
文件瘦身一下不就好了?事实上,jieba 的作者也经常被吐槽说 jieba 内存占用率太高,所以他也在 github 上对此问题进行了反馈,并且上传了一份瘦身版的词典文件dict.txt.small
,大小为 1.5M。作者将一些低频词删除,整体上几乎没有对分词产生影响。
需要注意的是,我们使用 small 版本的字典时,没必要将原字典文件删除,在创建 jieba 对象时,给它指定好文件路径就可以了,具体操作为:
from jieba import Tokenizer
small_jieba = Tokenizer(‘xx/dict.txt.small’) #不传入任何参数,就使用默认的大字典文件
small_jieba.lcut(‘我喜欢结巴分词!’) #使用list(small_jieba.lcut())是一样的,但是看起来不专业
之前有同学问过,为什么import jieba
之后,jieba.cut()
会报错。这大概率是版本问题,使用上面的代码形式就可以了。此外,jieba.cut()
返回的是一个迭代器对象,list(jieba.cut())
的效果等同于 jieba.lcut()
。如果同学们觉得这个字典还是太大,那就自己手动创建一份更小的字典。
jieba 不能对包含符号的词切分?
有些包含符号的特殊词,比如中国银行(北京)
,即使你添加到自定义词典,并给予很大的权重,jieba 依旧是不能对其进行分词的,会得到[“中国银行”, “(”, ”北京”, “)”]
。怎么办呢?改源码!
在 jieba 的__init__.py
文件下,有一个名称为re_han_default
的变量,是一个编译过的正则表达式。
re_han_default = re.compile(“([\u4E00-\u9FD5a-zA-Z0-9+#&\._%]+)”, re.U)
学过正则的同学看到这行代码,就应该知道了,jieba 默认允许词中带有“#”,“&”,“.”,“_”和“%”,想让它支持更多符号,我们手动写进去就好了嘛。同样的,我们其实也不需要真的去改源码,只要在加载 jiaba 之后,动态对其进行修改即可。
import jieba
Jieba.re_han_default = re.compile(“([\u4E00-\u9FD5a-zA-Z0-9+#&\._%()\(\)]+)”, re.U)
这样就把中文括号和英文括号都添加进去了,当再次遇到“中国银行(北京)”时,就能将其当作一个整体的词切出来了。jieba 的作者在 github 上说
- “结巴”中文分词:做最好的 Python 中文分词组件
结巴在不断的版本更新和迭代上,逐渐优化了许多功能点,最近又增添了深度学习模式的切词。许多人也都在问,jieba 是否支持分句、命名实体识别。当前的版本是不支持的,但是相信不久的将来,如果这些需求很大,也不排除作者会添加这些功能的可能。
扫码下图关注我们不会让你失望!