【中文分词原理】从歧义问题到 jieba 算法

“我爱自然语言处理”——8 个字,几个词?对你来说不假思索,对计算机来说却是一道必须解决的难题。

一、背景:中文 NLP 为什么必须先过"分词"这一关?

1.1 中文 vs 英文:天然的差异

  • 英文有天然的分隔符—空格。"I love NLP" 三个词一目了然。
  • 中文是一种连续书写的语言,字与字之间没有显式边界。

​ 因此,计算机处理英文时,按空格切一刀就能拿到词。但面对中文,它看到的只是一串连续的字符流,从哪里断开,完全没有线索。
在这里插入图片描述

1.2 歧义:中文分词的核心难点

​ 即使知道"要切",切在哪里也不简单。

  • 同一段文字,切法不同,意思完全不同:

    • “自然语言处理”——是一个词,还是"自然语言"+“处理”?
    • “好好工作”——是"好好"+“工作”,还是"好"+“好工作”?
    • “南京市长江大桥”——是"南京市长/江大桥",还是"南京/市/长江大桥"?

    在这里插入图片描述

  • 这种歧义性是中文分词最本质的挑战。对人来说靠语感就能判断,但对计算机而言,需要专门的算法来解决。

1.3 为什么分词质量决定一切

​ 分词不是一个孤立的步骤,它是几乎所有中文 NLP 任务的第一道工序

下游任务对分词的依赖
词袋模型(BoW)需要先有"词",才能统计词频
词向量训练(Word2Vec)以词为单位输入,分词粒度决定向量质量
文本分类/情感分析每个词就是一个特征,分错词 = 特征错误
搜索引擎/信息检索倒排索引以词为 key,分词不准则召回不准

​ 分词质量直接决定了后续所有任务的天花板。 分错一个词,后面全错。这也是为什么中文 NLP工程中,分词往往是投入调优时间最多的环节之一。

二、基础知识:中文分词到底在做什么?

2.1 核心任务

​ 中文分词(Chinese Word Segmentation)的目标很明确:把连续的汉字序列切分成有意义的词语序列

输入: "研究生命的起源"
输出A: "研究 / 生命 / 的 / 起源"     ← 正确
输出B: "研究生 / 命 / 的 / 起源"     ← 错误(歧义)

​ 看起来简单,但中文分词面临三大挑战:

挑战说明示例
分词歧义同一段文字有多种合理切分“南京市长江大桥” → 南京市长/江大桥 or 南京/市/长江大桥
未登录词(OOV)新词、人名、品牌名不在词典中“ChatGPT”、“奥利给”
粒度选择切分粗细影响下游效果“人工智能” 整体 vs “人工”+“智能”

2.2 主流分词方法

​ 从技术路线上看,中文分词经历了三代演进:

方法原理优点缺点
词典匹配最大匹配法,查词典贪心切分快、简单无法处理歧义和未登录词
统计模型HMM / CRF,基于概率选择最优切分能处理歧义和新词需要标注语料训练
深度学习BiLSTM-CRF / BERT,序列标注精度最高计算成本高

​ jieba 采用的是 词典匹配 + HMM 统计模型 的混合方案:已知词靠词典查找,未登录词靠 HMM 模型利用 Viterbi 算法识别。这种设计让它在速度和精度之间取得了很好的平衡。

2.3 常用工具一览

工具特点典型用途
jieba轻量、易用、支持自定义词典情感分析、文本分类、快速原型
pkuseg精度高、可选择领域模型专业领域分词(新闻、医疗等)
thulac支持词性标注文本标注、语法分析
HanLP功能全面、高级 NLP 能力命名实体识别、依存分析

​ 其中 jieba 是 Python 生态中使用最广泛的中文分词库——GitHub 超过 30k star,几乎是中文 NLP 的默认选择。

三、技术原理:jieba 的分词算法

​ jieba 的核心策略是:“词典兜底,统计补刀”已知词靠查词典,未知词靠概率模型

​ 内部分两步走:

在这里插入图片描述

3.1 步骤一:DAG + 动态规划(处理已知词)

​ jieba 自带一个约 35万词的前缀词典,每个词都标注了词频。分词时,它先用这个词典对输入文本构建一个DAG(有向无环图)。 什么是 DAG?简单说,就是把一段文字所有可能的切分方式都画出来。

​ 以 “我爱北京天安门” 为例,DAG 中的边(每条边 = 词典中的一个词)。
在这里插入图片描述

​ DAG 建好后,jieba 用 动态规划,从右往左计算每个位置的最大概率路径。高频词组合的路径概率最大,自然就选出了:我 / 爱 / 北京 / 天安门,而不是"北 / 京 / 天 / 安 / 门" 这种逐字切分。因为后者的联合概率远低于前者。

​ 因此,DAG 负责"穷举所有可能",动态规划负责"选出最优解"。

3.2 步骤二:HMM + Viterbi(识别未登录词)

​ 词典再大也不可能覆盖所有词。人名"令狐冲"、新词"内卷"、专业术语等,这些词不在词典里,DAG 会把它们拆成单字。

​ 这时 jieba 启动第二道防线:HMM(隐马尔可夫模型)。

  • 核心思想是给每个字标注一个位置状态:

    状态含义示例
    B (Begin)词的开头
    M (Middle)词的中间
    E (End)词的结尾
    S (Single)单字成词

    在这里插入图片描述

  • jieba 用预训练好的 HMM 参数(状态转移概率 + 发射概率),通过 Viterbi 算法计算最优状态序列:

    在这里插入图片描述

    ​ Viterbi 发现 “令→狐” 的 B→M 转移概率远高于 B→B,说明"狐"更可能是一个词的中间而非另一个词的开头,于是把"令狐冲"识别为一个完整的词。

  • 因此,HMM 通过字的位置概率,把词典"不认识"的词重新拼回来。

3.2 两步协作

​ 实际分词时,两步是协作的关系:

DAG + 动态规划HMM + Viterbi
处理对象词典中的已知词词典外的未登录词
优势快速、准确能识别新词、人名
局限遇到新词就“不认识”速度稍慢,偶有误判
触发条件默认执行仅对连续单字片段启用

​ jieba 先用 DAG 切出一个初步结果,如果其中出现连续的单字序列(说明词典没能识别),就对这段启用 HMM进行二次识别。两者配合,既保证了已知词的速度和准确性,又兜住了未登录词的识别能力。

四、 三种分词模式

​ 理解了底层原理,再看 jieba 的三种模式就很清晰了:

模式调用方式原理输出示例(“我爱自然语言处理”)适用场景
精确模式jieba.lcut(text)DAG 最大概率路径,无冗余[‘我’, ‘爱’, ‘自然语言’, ‘处理’]文本分析、模型训练
全模式jieba.lcut(text, cut_all=True)扫描 DAG 所有可能的词,有重叠[‘我’, ‘爱’, ‘自然’, ‘自然语言’, ‘语言’, ‘处理’]速度优先、不怕冗余
搜索引擎模式jieba.lcut_for_search(text)精确模式 + 对长词再切分[‘我’, ‘爱’, ‘自然’, ‘语言’, ‘自然语言’, ‘处理’]倒排索引、提高召回率

4.1 精确模式

​ 默认方式,最精确的切分,适合文本分析。

import jieba

text = "我爱自然语言处理"

print("精确模式:", jieba.lcut(text))

​ 输出:

精确模式: ['我', '爱', '自然语言', '处理']

4.2 全模式

​ 扫描所有可能的词,速度快但是有冗余。

print("全模式:", jieba.lcut(text, cut_all=True))

​ 输出:

全模式: ['我', '爱', '自然', '自然语言', '语言', '处理']

4.3 搜索引擎模式

​ 在搜索场景中,用户的查询目标往往并不明确。搜索引擎模式正是基于这一现实需求,在精确模式的基础上,对长词进行再次切分,以提升检索系统的召回能力。

(1) 分词结果与倒排索引
  • 搜索引擎的核心数据结构是倒排索引(Inverted Index),其组织方式与我们日常阅读文档的直觉正好相反:

    • 正排索引:给定一篇文档,列出它包含哪些词
    • 倒排索引:给定一个词,找出哪些文档包含它

    分词的结果,正是倒排索引中“词项”的直接来源

倒排索引(词 → 文档):
深度学习   → [文档1]
自然语言   → [文档1, 文档3]
自然      → [文档2]
模型      → [文档1, 文档2, 文档3]

​ 当用户输入查询词时,搜索引擎只需在倒排索引中查找对应词项,即可快速返回所有相关文档。

(2) 查询粒度不确定性带来的问题
  • 问题在于:用户的搜索词粒度是不可预期的

    • 文档中可能写的是 “自然语言处理”
    • 用户却可能搜索:
      • “自然语言”
      • “自然”
      • 甚至更短的片段
  • 不同的分词策略,会直接影响倒排索引中词项的构成,从而显著改变搜索系统的召回能力与索引质量

    分词模式索引中的词用户搜“自然”能命中吗说明
    精确模式自然语言、处理不能只保留语义完整的词,索引干净,但对短查询不友好
    全模式自然、语言、自然语言、处理 + 可能的噪声片段能,但索引有噪声穷举所有可能的词片段,召回率高,但容易引入大量噪声
    搜索引擎模式自然、语言、自然语言、处理能,且索引干净在精确分词的基础上,额外保留有意义的长词子词,在召回率与索引质量之间取得平衡

    ​ 因此可以将搜索引擎模式概括为:搜索引擎模式 = 精确模式的准确性 + 长词子词级别的召回能力,这也正是其命名的由来。

(3) 使用示例

​ 在 jieba 中,搜索引擎模式正是围绕上述设计目标实现的:

print("搜索模式:", jieba.lcut_for_search(text))

​ 输出:

搜索模式: ['我', '爱', '自然', '语言', '自然语言', '处理']

​ 可以看到,长词被保留的同时,其关键子词也被纳入索引范围,这使得搜索系统在面对不同粒度的用户查询时,能够获得更稳定的召回效果。

4.4 对比分析

​ 下图直观展示了三种模式对同一句话的切分差异:

在这里插入图片描述

  • 精确模式:每个位置只保留最优切分,词与词之间没有重叠,结果最干净
  • 全模式:把所有可能的词都列出来,“自然”、“语言”、"自然语言"同时出现,存在冗余重叠
  • 搜索引擎模式:先按精确模式切分,再对"自然语言"这类长词做二次拆分,兼顾精确性和召回率

选择建议:绝大多数场景用精确模式;做搜索或信息检索用搜索引擎模式;全模式很少直接用。

五、自定义词典:让分词更懂你的领域

jieba 的默认词典主要覆盖通用语言场景,在面对专业术语、业务新词或固定搭配时,往往会出现过度切分的问题。

​ 相比频繁更换分词工具,引入一份贴合业务的自定义词典,通常是成本最低、收益最高的优化手段

5.1 词典格式

​ 自定义词典采用纯文本格式,每行表示一个词条,可选地指定词频词性

深度学习
好好工作
大语言模型 5 n
Transformer 5 eng
  • 字段说明如下:

    • 词条:希望被整体识别的词
    • 词频(可选):值越大,分词时被优先选中的概率越高
    • 词性(可选):用于词性标注场景,对分词本身影响较小
  • 在大多数业务中,仅提供词条本身就已经能显著改善分词效果。

5.2 自定义词典的使用

​ 加载自定义词典前后,对比分词结果如下:

import jieba

text = "喜欢深度学习,要努力好好工作~"

# 不使用自定义词典
print("精确模式: ", jieba.lcut(text))

# 加载自定义词典
jieba.load_userdict("custom_dict.txt")
# ['喜欢', '深度学习', ',', '要', '努力', '好好工作', '~']

​ 输出结果为:

精确模式:  ['喜欢', '深度', '学习', ',', '要', '努力', '好好', '工作', '~']
使用自定义词典的精确模式:  ['喜欢', '深度学习', ',', '要', '努力', '好好工作', '~']
  • 可以看到,在加载自定义词典后:

    • “深度学习” 被识别为一个完整术语
    • “好好工作” 作为固定搭配不再被错误拆分
  • 分词结果明显更符合语义与业务预期。

5.3 小结

在实际项目中,维护一份领域词典往往比更换分词工具更有效。

  • 原因在于:

    • 分词错误多来自领域知识缺失,而非算法能力不足
    • 自定义词典可控、可迭代,能快速适配业务变化
    • 对搜索、召回、统计分析等下游任务影响立竿见影
  • 这也是为什么在搜索引擎、推荐系统、日志分析等场景中,“词典建设”本身就是一项长期工程资产

六、总结

6.1 本篇要点

  1. 中文没有天然词边界,分词是中文 NLP 的第一道门槛,质量直接决定所有下游任务的天花板。
  2. 分词面临三大挑战:歧义切分、未登录词、粒度选择。
  3. jieba = DAG 动态规划 + HMM Viterbi,词典处理已知词,HMM 识别新词,两步协作覆盖绝大多数场景。
  4. 三种模式各有定位:精确模式用于分析,搜索引擎模式用于检索,全模式用于穷举。
  5. 自定义词典是最低成本的精度提升方式,比换工具更实际。

6.2 分词工具选型速查

需求推荐工具理由
快速原型 / 通用场景jieba生态好、上手快、自定义词典方便
专业领域高精度pkuseg支持领域模型切换
需要词性标注thulac / HanLP内置词性标注能力
深度学习 pipelineBERT WordPiece / SentencePiece与模型分词器一致,避免 tokenization mismatch
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

未收敛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值