一、词法分析三件事
词法分析是 NLP 流水线的第一道工序,它把原始字符串加工成更有结构的语言单位,主要包含三个子任务:
英文等印欧语言天然有空格分词,词法处理主要是词干提取(stemming)与词形还原(lemmatization);而中文词与词之间没有显式边界,分词成了中文 NLP 的头号基础任务。
二、中文分词为何难
- 边界歧义:「结合成分子」可切为「结合/成/分子」或「结婚/成分/子」;「从小学电脑」→「从小/学/电脑」还是「从/小学/电脑」?
- 未登录词(OOV):新词层出不穷——「绝绝子」「二次元」「特种兵式旅游」,词典永远滞后于语言。
- 切分歧义与领域相关:同一句话在不同领域的正确切分可能不同,如医疗文本中的「肺炎/支原体」。
三、分词方法演进
1. 基于词典:最大匹配法
从句子一端开始,按词典中最长词进行贪婪匹配。正向最大匹配(FMM)从左向右,反向最大匹配(BMM)从右向左。
- 取当前位置开始、长度不超过词典最大词长(如 5)的子串;
- 查词典:命中则切出该词,指针前移该词长度;
- 未命中则切出单字,指针前移一位,循环直至句末。
优点是简单快速;缺点是严重依赖词典、无法处理歧义与新词。本章交互演示实现的就是 FMM。
2. 基于统计:HMM 与 CRF
把分词转化为字的序列标注问题:每个字标注 B(词首)、M(词中)、E(词尾)、S(单字成词)。
自 然 语 言 处 理 很 重 要
B M M E B E S B E
HMM(隐马尔可夫模型)用字的转移概率和发射概率做 Viterbi 解码;CRF(条件随机场)进一步加入任意特征、全局归一,是深度学习普及前工业界的王者。jieba 的「搜索引擎模式」之外,其未登录词识别正基于 HMM。
3. 基于深度学习
BiLSTM-CRF 用双向 LSTM 提取上下文特征、CRF 约束标签合法性;如今则普遍使用 BERT 类预训练模型 + 微调,在多个中文分词与 NER 基准上取得最佳成绩。
四、jieba 分词实战
jieba 支持三种分词模式:
- 精确模式:最精确地切开,适合文本分析;
- 全模式:把所有可能成词的词语都扫出来,速度快但有冗余;
- 搜索引擎模式:在精确模式基础上对长词再切分,提高召回率,适合倒排索引。
python · jieba_basic.pyimport jieba
sent = "他来到北京清华大学研究所参观自然语言处理实验室"
print(jieba.lcut(sent, cut_all=True))
# 全模式:['他', '来到', '北京', '清华', '清华大学', '华大', '大学', ...]
print(jieba.lcut(sent, cut_all=False))
# 精确模式:['他', '来到', '北京', '清华大学', '研究所', ...]
print(jieba.lcut_for_search(sent))
# 搜索引擎模式:长词会被二次切分
加载自定义词典,解决领域词
jieba.load_userdict("mydict.txt")
# 词典每行三列:词语 词频 词性,后两列可省略
# 生成式人工智能 100 n
# 大语言模型 100 n
# 也可在代码中动态增删
jieba.add_word("大语言模型")
jieba.del_word("自定义词")
五、词性标注
词性标注(Part-of-Speech Tagging)为每个词打上词类标记:名词 n、动词 v、形容词 a、副词 d、数词 m、量词 q……它能帮助过滤停用词(只保留名词、动词)、辅助句法分析。
python · 词性标注import jieba.posseg as pseg
for word, flag in pseg.cut("小明在北京大学学习自然语言处理"):
print(f"{word}/{flag}", end=" ")
# 小明/nr 在/p 北京大学/nt 学习/v 自然语言处理/l
常用词性标记(jieba 采用兼容 ICTCLAS 的标记集):
| 标记 | 含义 | 标记 | 含义 |
|---|---|---|---|
| n | 普通名词 | v | 动词 |
| nr | 人名 | a | 形容词 |
| ns | 地名 | d | 副词 |
| nt | 机构团体名 | m / q | 数词 / 量词 |
| nz | 其他专名 | p / u | 介词 / 助词 |
六、命名实体识别
命名实体识别(Named Entity Recognition, NER)抽取文本中的专有名词并归类,最常见的三大类是:
- PER 人名:小明、屠呦呦;
- LOC 地名:北京、长江;
- ORG 机构名:北京大学、联合国;
- 垂直领域还可扩展时间、日期、货币、药物名、手术名等。
NER 是问答机器人槽位抽取(如「订一张明天去上海的票」中识别时间与目的地)、知识图谱构建的前置技术。用 HanLP 只需几行:
python · HanLP 命名实体识别import hanlp
tagger = hanlp.load(hanlp.pretrained.ner.MSRA_NER_BERT_BASE_ZH)
print(tagger([["小明", "在", "北京", "学习", "人工智能"]]))
# [[('小明', 'PER', 0, 1), ('北京', 'LOC', 2, 3)]]
七、评价指标与交互演示
序列任务通常用精确率 Precision、召回率 Recall 与 F1 值评价(以词为单位统计预测与标准答案的边界是否一致):
Precision = 切对的词数 / 系统切出的词数
Recall = 切对的词数 / 标准答案中的词数
F1 = 2 × P × R / (P + R)
F1 是精确率与召回率的调和平均,是分词与 NER 的核心指标。
动手一试:正向最大匹配分词
下面演示使用与第三章方法一致的 FMM 算法(内置小型词典)。试试包含词典词的句子,再故意写一个新词,观察未登录词如何退化为单字: