4、实体识别技术:从规则到深度学习的演进之路
实体识别,说白了就是让机器能从文本里把「人名、地名、机构名、时间、金额」这些关键信息给揪出来。我做了这么多年投研系统,最深的体会就是——实体识别搞不好,后面的知识图谱就是空中楼阁。
今天咱们聊聊三种主流方案:基于规则、基于统计、基于深度学习。每种我都踩过坑,也都有心得。
4.1 基于规则的实体识别:最朴素但最可控
规则方法,就是你自己写一堆模式匹配规则。比如「张某某 出任 某某公司 CEO」,这种句式里「张某某」大概率是人名。
我早期做金融公告解析时,就用正则表达式写规则。效果嘛,在特定场景下其实不错。
核心思路:利用词典 + 正则 + 句法模式,硬匹配。
# 一个简单的规则示例(伪代码)
if "出任" in sentence and "CEO" in sentence:
extract_person_before("出任")
extract_company_after("出任")
优点:
- 可解释性强——你知道它为什么这么识别
- 不需要标注数据——写规则就行
- 在垂直领域(比如财报、公告)效果稳定
缺点:
- 维护成本高——规则多了会打架
- 泛化能力差——换个领域规则基本废掉
- 遇到「张三 出任 李四公司 CEO」这种歧义句,容易翻车
我曾经踩过的坑:给某券商做研报解析,写了300多条规则。结果遇到一篇「XX公司拟收购YY公司100%股权」,规则死活识别不出「XX公司」和「YY公司」哪个是收购方。后来我加了一条「收购方通常在动词前」的规则,才算搞定。但你看,这种规则越加越多,最后成了屎山。
4.2 基于统计的实体识别:CRF 与 HMM
统计方法,说白了就是让模型从标注数据里学「规律」。这里最经典的两个模型:HMM(隐马尔可夫模型)和CRF(条件随机场)。
4.2.1 HMM:简单但有限
HMM 假设每个词的状态(B-PER、I-PER、O 等)只跟前一个状态有关。嗯,这个假设其实挺强的,实际文本哪有这么简单?
# HMM 的典型状态转移
B-PER → I-PER → I-PER → O
# 表示:人名开始 → 人名中间 → 人名中间 → 非实体
我个人的习惯是:HMM 适合做快速原型验证,但正式项目我基本不用它。为什么?因为它没法利用「上下文特征」。比如「北京」这个词,在「北京是首都」里是地名,在「北京烤鸭」里是修饰语,HMM 区分不了。
4.2.2 CRF:统计方法的扛把子
CRF 比 HMM 强在哪?它不假设状态独立,而是把整个序列的特征都考虑进来。你想想看,这就像你看一句话时,会看前后文来判断某个词是不是实体。
CRF 的核心优势:可以自定义特征模板。比如「当前词是否大写」「前一个词是不是介词」「当前词是否在词典中」等。
# CRF 特征模板示例(CRF++ 格式)
# 当前词本身
U00:%x[0,0]
# 前一个词
U01:%x[-1,0]
# 后一个词
U02:%x[1,0]
# 当前词是否以大写字母开头
U03:%x[0,0].isupper
我在做投研实体识别时,CRF 是主力模型之一。效果稳定,训练快,而且可解释性比深度学习好。但有个问题——特征工程太累了。你要不断试特征,加一个特征跑一次实验,很磨人。
| 模型 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| HMM | 简单、训练快 | 特征能力弱、假设强 | 快速原型、小规模数据 |
| CRF | 特征灵活、全局最优 | 特征工程繁琐 | 垂直领域、中等规模数据 |
4.3 基于深度学习的实体识别:BiLSTM-CRF 与 BERT
深度学习时代,实体识别基本被神经网络统治了。这里我重点讲两个架构:BiLSTM-CRF 和 BERT。
4.3.1 BiLSTM-CRF:经典组合
BiLSTM 负责捕捉上下文信息,CRF 负责做序列标注的约束。说白了,BiLSTM 给出每个词属于各类别的「分数」,CRF 再把这些分数串起来,找到最合理的标签序列。
# BiLSTM-CRF 的典型结构
输入: "张三 出任 腾讯 CEO"
↓
词嵌入层 → BiLSTM → 每个词的标签分数
↓
CRF层 → 输出最优标签序列: B-PER I-PER O B-ORG I-ORG
我记得第一次用 BiLSTM-CRF 做投研实体识别时,效果比 CRF 好了 5 个点。但有个问题——训练慢,而且需要大量标注数据。我那时候标注了 2 万条研报,才勉强够用。
我的经验:如果你数据量少于 5000 条,别急着上 BiLSTM-CRF。先用 CRF 跑基线,等数据够了再换深度学习。否则容易过拟合。
4.3.2 BERT:预训练模型的降维打击
BERT 出来以后,实体识别基本被它统治了。为什么?因为它在大规模语料上预训练过,对语义的理解远超传统模型。
你想想看,BERT 知道「苹果」在「苹果公司」里是机构名,在「吃苹果」里是水果。这种能力,CRF 和 BiLSTM 都做不到。
# BERT 做实体识别的典型流程
1. 加载预训练 BERT 模型
2. 在标注数据上微调(fine-tune)
3. 输出每个 token 的标签
# 伪代码
from transformers import BertForTokenClassification
model = BertForTokenClassification.from_pretrained('bert-base-chinese', num_labels=7)
我在项目中用 BERT 替换 BiLSTM-CRF 后,F1 值从 88% 提到了 94%。但代价是什么?显存占用大,推理速度慢。如果你做实时解析,BERT 可能扛不住。
我曾经踩过的坑:用 BERT 做投研公告的实体识别,模型效果很好,但上线后发现推理延迟太高——每篇公告要 2 秒。后来我改用蒸馏版 BERT(比如 TinyBERT),延迟降到 200ms,效果只掉了 1 个点。嗯,工程上要学会取舍。
4.4 三种方案的对比与选择
说了这么多,到底该用哪种?我个人的建议是:
- 数据量少(<1000条):用规则 + 词典,快速出活
- 数据量中等(1000-10000条):用 CRF,特征工程做扎实
- 数据量大(>10000条):用 BERT 或 BiLSTM-CRF,效果最好
- 实时性要求高:用 CRF 或蒸馏版 BERT
核心原则:没有银弹。投研场景里,实体类型多、上下文复杂,我通常的做法是「规则兜底 + BERT 主力 + CRF 备用」。三层架构,互相补充。
4.5 知识图谱视角下的实体识别
最后说一句。实体识别不是终点,它是知识图谱的入口。你识别出「张三」「腾讯」「CEO」还不够,你得知道它们之间的关系——「张三 任职 腾讯 担任 CEO」。
所以,做实体识别时,我建议你提前想好:
- 实体类型怎么定义?太粗了没意义,太细了模型学不好
- 嵌套实体怎么处理?比如「北京大学」既是机构名,又包含地名「北京」
- 实体链接怎么做?识别出「腾讯」后,得链接到知识图谱里的唯一节点
这些,都是后面章节要聊的内容。今天先到这里。
一句话总结:实体识别没有银弹。规则快但死板,CRF稳但累,BERT强但贵。我个人的做法是——先跑规则基线,再用CRF提点,最后用BERT冲刺。每一步都清楚自己在干什么。