3、中文分词技术:分词原理、jieba分词库详解

各位同学好,我是你们这门课的主讲。今天咱们聊聊中文分词——说白了,就是怎么让机器看懂中文句子里的「词」。

英文天然有空格隔开单词,中文可没这好事。「我爱自然语言处理」这句话,机器第一眼看到的就是一堆汉字堆在一起。怎么切?切错了意思就全变了。我当年刚入行时,就因为在分词上栽过跟头,后面模型效果怎么调都不对。

3.1 分词到底在解决什么问题?

分词,就是把连续的汉字序列,按照一定的规范切分成一个个独立的词。

举个例子:

输入: "武汉市长江大桥"
正确分词: "武汉市 / 长江大桥"
错误分词: "武汉 / 市长 / 江大桥"  (这就闹笑话了)

为什么会这样?因为中文里词和词之间没有边界。你想想看,一个句子可能有多种切分方式,机器得选出最合理的那一种。

我在项目中遇到过最典型的案例:用户评论「这个手机屏幕很大」,如果分词错了,情感分析的结果可能完全跑偏。所以分词是文本挖掘的第一步,也是地基。

3.2 主流的三种分词方法

目前业界常用的分词方法,我归纳为三大流派:

方法 原理 优缺点
基于词典的匹配 拿着词典去文本里「对号入座」 速度快,但对新词无力
基于统计的模型 用大量语料训练,算词与词之间的概率 能识别新词,但需要数据
基于深度学习 用LSTM、BERT等模型做序列标注 精度高,但计算量大

我个人习惯,在实际项目中先用基于词典的方法快速跑通,再用统计模型做优化。别一上来就上深度学习,很多时候杀鸡用牛刀。

3.3 jieba分词库详解

说到分词工具,jieba 绝对是 Python 生态里最亲民的一个。它结合了词典匹配和统计模型,轻量又好用。

安装就一句话:

pip install jieba

3.3.1 三种分词模式

jieba 提供了三种模式,我分别给你演示一下:

精确模式——最常用,力求最精确的切分:

import jieba

text = "我来到北京清华大学"
seg_list = jieba.cut(text, cut_all=False)
print("精确模式: " + "/ ".join(seg_list))
# 输出: 我/ 来到/ 北京/ 清华大学

嗯,这里要注意,精确模式不会把「清华大学」再拆成「清华」和「大学」,因为它认为这是一个完整的词。

全模式——把所有可能的词都列出来:

seg_list = jieba.cut(text, cut_all=True)
print("全模式: " + "/ ".join(seg_list))
# 输出: 我/ 来到/ 北京/ 清华/ 清华大学/ 华大/ 大学

你看,全模式会输出所有可能的切分结果。我一般只在做关键词提取时用这个模式,因为它不会漏掉任何潜在的关键词。

搜索引擎模式——在精确模式基础上,对长词再切分:

seg_list = jieba.cut_for_search(text)
print("搜索引擎模式: " + "/ ".join(seg_list))
# 输出: 我/ 来到/ 北京/ 清华/ 华大/ 大学/ 清华大学

这个模式适合做搜索引擎的索引构建。我记得有一次做电商搜索优化,就是用这个模式把商品标题切碎,召回率提升了不少。

我的建议:日常文本分析用精确模式;做关键词提取或搜索引擎用全模式或搜索引擎模式。

3.3.2 自定义词典

jieba 自带的词典覆盖了大部分常用词,但遇到专业领域或新词就抓瞎了。比如「区块链」、「碳中和」这些词,早期版本里就没有。

这时候就需要自定义词典上场了。

词典文件格式很简单,每行三个字段:词、词频(可省略)、词性(可省略)。

# my_dict.txt
区块链 5 n
碳中和 3 n
自然语言处理 10 n

加载方式:

jieba.load_userdict("my_dict.txt")
text = "区块链技术推动了碳中和的发展"
seg_list = jieba.cut(text)
print("/ ".join(seg_list))
# 输出: 区块链/ 技术/ 推动/ 了/ 碳中和/ 的/ 发展

小技巧:词频设置越高,这个词越容易被保留。我一般设 5-10 就够用了。

3.3.3 动态调整词典

有时候你不想单独建文件,可以直接在代码里加词:

jieba.add_word("奥利给")
jieba.del_word("某些不想要的词")

我曾经在做一个弹幕分析项目时,弹幕里全是「yyds」、「绝绝子」这种网络新词。不加词典的话,jieba 会把「yyds」切成「yy」和「ds」,那分析结果就没法看了。

避坑指南:自定义词典的词频不要设得太高,否则会影响其他词的切分。我曾经把某个专业词的词频设到 100,结果整段文本里所有类似的字都被强行合并成这个词,反而出错了。

3.4 实战:给一段评论做分词

咱们来个小练习。假设你拿到一段用户评论:

text = "这家店的奶茶真的绝绝子,yyds,下次还要来!"

直接分词效果肯定不好。我们加上自定义词典:

import jieba

jieba.add_word("绝绝子")
jieba.add_word("yyds")

words = jieba.lcut(text)  # lcut 返回列表
print(words)
# 输出: ['这家', '店', '的', '奶茶', '真的', '绝绝子', ',', 'yyds', ',', '下次', '还要', '来', '!']

你看,加上词典后,「绝绝子」和「yyds」都被正确识别了。这就是自定义词典的威力。

3.5 小结

分词是文本挖掘的第一步,也是最重要的一步。jieba 作为入门级工具,足够应对大部分场景。记住三点:

  • 精确模式最常用,全模式适合关键词提取
  • 遇到专业词汇或网络新词,一定要加自定义词典
  • 词频设置要合理,别贪多

下一章咱们聊聊词性标注和命名实体识别,这些东西在情感分析里特别有用。到时候我会分享一个我踩过的坑——因为没做词性过滤,把一堆形容词当成了情感词,结果模型全乱了。到时候细说。