阶段1
|
NLP传统 · 第2课/共30课
📖 第02课:分词(jieba/HanLP)
🎯 课程目标
中文分词是中文NLP的基石。与英文不同,中文没有天然的词边界(空格),分词质量直接影响所有下游任务。
- 理解中文分词的核心挑战
- 掌握jieba分词的三种模式及适用场景
- 学会使用自定义词典解决未登录词问题
- 了解不同分词算法的原理与权衡
📐 核心原理
中文分词三大流派
- 基于词典(规则):最大匹配、最短路径 → 速度快,但无法处理未登录词
- 基于统计(HMM):jieba的HMM层 → 可以发现新词,但可能过度切分
- 基于深度学习:BiLSTM-CRF等 → 精度最高,但速度慢、资源消耗大
💡 jieba的混合策略:先基于词典构建有向无环图(DAG),用动态规划找最大概率路径,剩余未登录词用HMM处理。这是工程上的精妙平衡。
🔬 jieba分词实战
jieba三种分词模式
import jieba
import jieba.analyse
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))
jieba.add_word("自然语言处理")
jieba.add_word("皇冠上的明珠")
seg_list = jieba.cut(text)
print("\n添加自定义词典后:", "/ ".join(seg_list))
import jieba.posseg as pseg
words = pseg.cut("小明在北京大学学习自然语言处理")
print("\n词性标注:")
for word, flag in words:
print(f" {word}: {flag}")
精确模式: 自然语言/ 处理/ 是/ 人工智能/ 的/ 皇冠/ 上/ 的/ 明珠
全模式: 自然/ 自然语言/ 语言/ 处理/ 是/ 人工/ 人工智能/ 智能/ 的/ 皇冠/ 上/ 的/ 明珠
搜索引擎模式: 自然/ 语言/ 自然语言/ 处理/ 是/ 人工/ 智能/ 人工智能/ 的/ 皇冠/ 上/ 的/ 明珠
添加自定义词典后: 自然语言处理/ 是/ 人工智能/ 的/ 皇冠上的明珠
词性标注:
小明: nr
在: p
北京大学: nt
学习: v
自然语言处理: x
✅ 验证通过:代码实机运行结果如上
🔧 深入:分词质量分析
分词粒度的艺术
"自然语言处理"可以切分为:
- 细粒度:自然/语言/处理 → 适合搜索引擎索引
- 粗粒度:自然语言处理 → 适合语义理解
- 混合粒度:同时保留两种 → jieba的搜索引擎模式
词频统计与关键词提取
import jieba
import jieba.analyse
from collections import Counter
article = "自然语言处理是计算机科学领域与人工智能领域中的一个重要方向。它研究能有效地实现自然语言通信的计算机系统。自然语言处理是一门融语言学、计算机科学、数学于一体的科学。"
words = jieba.cut(article)
word_list = [w for w in words if len(w.strip()) > 0]
word_freq = Counter(word_list)
print("=== 词频统计 Top 10 ===")
for word, freq in word_freq.most_common(10):
print(f" {word}: {freq}")
keywords = jieba.analyse.extract_tags(article, topK=8, withWeight=True)
print("\n=== TF-IDF 关键词 ===")
for word, weight in keywords:
print(f" {word}: {weight:.4f}")
keywords2 = jieba.analyse.textrank(article, topK=8, withWeight=True)
print("\n=== TextRank 关键词 ===")
for word, weight in keywords2:
print(f" {word}: {weight:.4f}")
test_text = "鸿蒙操作系统是基于微内核的分布式操作系统"
print(f"\n=== 未登录词测试 ===")
print(f"默认分词: {'/ '.join(jieba.cut(test_text))}")
jieba.add_word("鸿蒙操作系统")
print(f"添加词典后: {'/ '.join(jieba.cut(test_text))}")
=== 词频统计 Top 10 ===
自然语言: 3
的: 3
。: 3
处理: 2
是: 2
计算机科学: 2
领域: 2
、: 2
与: 1
人工智能: 1
=== TF-IDF 关键词 ===
自然语言: 1.3611
计算机科学: 0.8485
领域: 0.4706
处理: 0.4705
人工智能: 0.4112
计算机系统: 0.3962
语言学: 0.3895
一体: 0.3207
=== TextRank 关键词 ===
计算机科学: 1.0000
领域: 0.9477
处理: 0.6462
数学: 0.6345
研究: 0.6220
实现: 0.5407
一体: 0.4845
语言学: 0.4728
=== 未登录词测试 ===
默认分词: 鸿蒙/ 操作系统/ 是/ 基于/ 微内核/ 的/ 分布式/ 操作系统
添加词典后: 鸿蒙操作系统/ 是/ 基于/ 微内核/ 的/ 分布式/ 操作系统
✅ 验证通过:代码实机运行结果如上
📊 分词算法对比
| 算法 | 速度 | 精度 | 未登录词 | 适用场景 |
| 正向最大匹配 | ★★★ | ★★ | ❌ | 简单快速分词 |
| 逆向最大匹配 | ★★★ | ★★☆ | ❌ | 略优于正向 |
| 双向最大匹配 | ★★☆ | ★★★ | ❌ | 规则方法最优 |
| jieba(词典+HMM) | ★★☆ | ★★★☆ | ✅ | 通用场景首选 |
| BiLSTM-CRF | ★ | ★★★★ | ✅ | 高精度需求 |
📝 练习
动手练习
- 用jieba对一篇新闻文章分词,统计词频并绘制词云
- 实现正向最大匹配算法,与jieba结果对比
- 收集领域专有名词,构建自定义词典,观察分词改善
✂️
🏆 成就解锁:分词匠人
掌握了中文NLP最基础的分词技术,理解了词典、统计、深度学习三种分词哲学。
🧪 扩展:最大匹配分词算法实现
理解jieba之前,我们先实现最基础的正向最大匹配算法,感受规则分词的局限。
正向最大匹配(FMM)
- 从左到右取最长匹配词
- 匹配失败则减一字继续匹配
- 单字无法匹配则作为未登录词输出
逆向最大匹配(BMM)
- 从右到左取最长匹配词
- 中文习惯上BMM效果略优于FMM
- 双向最大匹配取两者中词数更少的
jieba分词调优技巧
- 自定义词典:用jieba.load_userdict()加载领域词典,优先级高于默认词典
- 调节词频:自定义词典中可指定词频,影响分词结果
- 关闭HMM:jieba.cut(text, HMM=False)关闭新词发现,结果更可控
- 并行分词:jieba.enable_parallel()开启多进程,大文本加速2-3倍
📚 扩展阅读:中文分词研究史
从规则到深度学习
中文分词研究经历了三个阶段:
- 1990s-规则时代:最大匹配法,词表驱动,精度约90%
- 2000s-统计时代:HMM/CRF序列标注,精度95%+
- 2010s-深度时代:BiLSTM-CRF/BERT,精度97%+
有趣的是,jieba作为"统计时代"的产物,在日常应用中仍然足够好。这就是工程和研究的区别——最好的方法不一定是性价比最高的。
分词粒度与下游任务
| 下游任务 | 推荐粒度 | 原因 |
| 搜索引擎 | 细粒度 | 召回优先,宁可多切 |
| 机器翻译 | 粗粒度 | 翻译单元通常是短语 |
| 情感分析 | 中等 | "不好"应保留为整体 |
| 知识图谱 | 粗粒度 | 实体名不宜切分 |
🔬 扩展实践:最大匹配分词算法
正向最大匹配(FMM)实现思路
最大匹配算法是最直观的分词方法:从左到右,每次取最长匹配词。
- 设置最大词长MAX_LEN(通常5-8)
- 从文本左侧取MAX_LEN个字,在词典中查找
- 若找到,输出该词,指针后移
- 若未找到,去掉最后一个字,继续查找
- 单字仍未找到则作为未登录词输出
jieba核心源码解析
jieba的分词流程:
- 构建DAG:根据词典构建有向无环图,每个节点代表一个可能的词切分
- 动态规划:在DAG上找最大概率路径,词频越高概率越大
- HMM新词发现:对于DAG中没有路径的片段,用HMM判断是否为新词
这种混合策略兼顾了词典的精确性和HMM的泛化能力,是工程上的经典平衡。
分词工具对比
| 工具 | 速度 | 精度 | 特色 |
| jieba | 快 | 中等 | 社区活跃,使用最广 |
| pkuseg | 中 | 高 | 领域自适应 |
| LAC | 快 | 高 | 百度出品,联合分词+词性 |
| hanlp | 中 | 高 | 功能全面,多任务 |
| spacy | 快 | 中 | 英文为主,工业级 |
🧪 扩展:最大匹配分词算法实现
正向最大匹配(FMM)步骤
- 设最大词长MAX_LEN=5
- 从文本左侧取MAX_LEN个字,在词典中查找
- 若找到,输出该词,指针后移该词长度
- 若未找到,去掉最后一个字,继续查找
- 单字仍未找到则作为未登录词输出
逆向最大匹配(BMM)
从右向左匹配,中文习惯上BMM效果略优于FMM。双向最大匹配取两者中词数更少的。
jieba核心源码解析
jieba的分词流程:
- 构建DAG:根据词典构建有向无环图,每个节点代表一个可能的词切分位置
- 动态规划:在DAG上找最大概率路径,词频越高概率越大
- HMM新词发现:对于DAG中没有路径的片段,用HMM判断是否为新词
分词工具对比
| 工具 | 速度 | 精度 | 特色 |
| jieba | 快 | 中等 | 社区活跃,使用最广 |
| pkuseg | 中 | 高 | 领域自适应 |
| LAC | 快 | 高 | 百度出品,联合分词+词性 |
| hanlp | 中 | 高 | 功能全面,多任务 |
📚 参考文献
推荐阅读
- Jurafsky & Martin. Speech and Language Processing (3rd ed). 第2课相关章节
- Manning, Raghavan & Schutze. Introduction to Information Retrieval
- Goodfellow, Bengio & Courville. Deep Learning. 自然语言处理章节
在线资源
- NLTK文档: https://www.nltk.org/
- spaCy文档: https://spacy.io/
- gensim文档: https://radimrehurek.com/gensim/
- sklearn文本处理: https://scikit-learn.org/stable/modules/feature_extraction.html
分词 - 关键概念速查
| 概念 | 定义 | 应用 |
| Pipeline | 处理流水线,各步骤串行执行 | 文本处理系统 |
| Tokenization | 将文本切分为词/子词单元 | 分词、子词分割 |
| Embedding | 将离散符号映射到连续向量空间 | 词向量、句向量 |
| Feature Engineering | 从原始数据提取有效数值特征 | 传统ML模型输入 |
| Fine-tuning | 在预训练模型基础上微调 | BERT等模型适配 |
本课要点回顾
- 分词是NLP技术栈的重要组件
- 理解原理比调用API更重要——知道为什么比知道怎么做更有价值
- 代码验证是学习的好方法——动手跑一遍胜过读十遍
- 从简单方法开始,逐步过渡到复杂方法——简单方法的基线作用不可替代
- 实践出真知——用自己的数据跑一遍,发现课本上没写的问题