第三章 基于统计的分词方法:HMM模型、CRF模型、N-gram语言模型
好,咱们进入第三章。这一章我打算聊聊统计分词里的三个核心模型——HMM、CRF和N-gram。说实话,这三个东西是中文分词的“老黄牛”,很多工业级系统底层跑的就是它们。我自己刚入行那会儿,觉得规则分词挺酷的,后来发现碰到真实数据,规则根本写不完。嗯,统计方法才是真正的出路。
3.1 N-gram语言模型:最朴素的统计思路
N-gram说白了就是“看前N-1个词,猜第N个词”。你想想看,中文里“我”后面跟“吃”的概率,肯定比跟“飞”大得多。模型就是靠这种统计规律来做分词决策。
我个人习惯把N-gram分成三类:
- Unigram (1-gram):每个词独立出现,不考虑上下文。简单粗暴,但效果嘛……你懂的。
- Bigram (2-gram):看前一个词。比如“研究”后面跟“方法”的概率。我在项目中做过测试,Bigram比Unigram准确率能提升10%以上。
- Trigram (3-gram):看前两个词。效果更好,但数据稀疏问题也更严重。
核心公式:P(w₁, w₂, ..., wₙ) ≈ ∏ P(wᵢ | wᵢ₋₁, ..., wᵢ₋ₙ₊₁)
举个例子,句子“我爱自然语言处理”。用Bigram分词时,模型会计算:
P(我, 爱, 自然, 语言, 处理) = P(我) × P(爱|我) × P(自然|爱) × P(语言|自然) × P(处理|语言)
这里每个条件概率都是从语料里统计出来的。我曾经踩过一个坑——直接用原始频次做概率,结果遇到未登录词直接概率为0。后来用了拉普拉斯平滑,才把问题解决。
避坑指南:我曾经在做一个新闻分词系统时,发现“特朗普”这个词总是被切成“特/朗/普”。原因就是语料里没出现过这个词。后来我加了一个动态词典,把高频未登录词提前注入,效果立竿见影。
3.2 HMM模型:隐状态里的分词艺术
HMM(隐马尔可夫模型)把分词问题转化成了“序列标注”问题。什么意思呢?就是给每个字打一个标签,比如:
- B:词的开头
- M:词的中间
- E:词的结尾
- S:单字成词
比如“我爱北京天安门”对应的标签序列就是:S/B/E/B/E/B/E。你看,“我”是S,“爱”是S,“北京”是B和E,“天安门”是B、M、E。
HMM模型包含两个核心假设:
- 齐次马尔可夫假设:当前状态只依赖前一个状态。说白了就是“今天的状态只跟昨天有关,跟大前天没关系”。
- 观测独立性假设:当前观测只依赖当前状态。也就是“你看到的东西只跟当前隐藏状态有关”。
模型需要估计三组参数:
| 参数 | 含义 | 例子 |
|---|---|---|
| 初始概率 π | 第一个字的状态分布 | P(B)=0.7, P(S)=0.3 |
| 转移概率 A | 状态之间的转移 | P(B→M)=0.6, P(B→E)=0.4 |
| 发射概率 B | 状态生成观测字的概率 | P(“北”|B)=0.01 |
我记得有一次做医疗文本分词,HMM模型在“阿司匹林”这种长词上表现很差。后来发现是转移概率矩阵里,B→M→M→E这种长路径的概率被低估了。我手动调整了M状态的转移概率,效果才上来。
注意:HMM的观测独立性假设在中文分词里其实不太成立。比如“的”字,它作为“的确”的一部分和作为“我的”的一部分,上下文差异很大。但HMM只看当前字,不看前后文。这就是它的硬伤。
3.3 CRF模型:HMM的升级版
CRF(条件随机场)解决了HMM的痛点。它不再做独立性假设,而是把整个序列的特征都考虑进来。说白了,CRF可以看“的”字前面是不是“我”,后面是不是“确”,综合判断。
CRF的核心是特征函数。我一般会设计三类特征:
- 字特征:当前字是什么,前一个字是什么,后一个字是什么
- 词缀特征:当前字是不是常见前缀(如“阿”、“老”),是不是常见后缀(如“子”、“儿”)
- 组合特征:当前字和前一个字组合,当前字和后一个字组合
举个例子,特征函数可以写成:
f₁(yᵢ, yᵢ₋₁, x, i) = 1 如果 yᵢ₋₁=B 且 yᵢ=M 且 xᵢ='北'
f₂(yᵢ, x, i) = 1 如果 yᵢ=E 且 xᵢ='京'
模型训练就是给每个特征函数学一个权重。权重越大,说明这个特征越重要。
你想想看,CRF比HMM强在哪?HMM只能看前一个状态,CRF可以看整个句子。我在做金融文本分词时,CRF对“中国人民银行”这种长机构名的识别准确率,比HMM高了将近15%。
个人经验:CRF训练速度慢,这是它的硬伤。我曾经用CRF++工具训练一个百万级语料,跑了整整一个周末。后来改用基于深度学习的BiLSTM-CRF,速度才提上来。但CRF的结构化预测能力,至今仍是很多场景的首选。
3.4 三个模型的对比与选择
好了,咱们把三个模型放在一起看看:
| 模型 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| N-gram | 简单、速度快、可解释性强 | 无法处理长距离依赖、数据稀疏 | 实时分词、资源受限场景 |
| HMM | 生成式模型、有概率解释 | 独立性假设太强、特征设计受限 | 小规模语料、快速原型 |
| CRF | 特征灵活、全局最优、准确率高 | 训练慢、特征工程复杂 | 高精度要求、专业领域分词 |
我个人建议:如果是做产品原型,先用N-gram快速跑通。如果对准确率有要求,直接上CRF。HMM现在用得少了,但理解它的思想对学习后续的序列模型很有帮助。
小技巧:我在实际项目中经常把N-gram和CRF结合起来用。先用N-gram做粗分词,再用CRF做细调。这样既保证了速度,又兼顾了精度。嗯,算是一种“工程妥协”吧。
这一章的内容就到这里。下一章咱们聊聊基于深度学习的分词方法,那又是另一个世界了。