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-CRFBERT

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」。

所以,做实体识别时,我建议你提前想好:

  • 实体类型怎么定义?太粗了没意义,太细了模型学不好
  • 嵌套实体怎么处理?比如「北京大学」既是机构名,又包含地名「北京」
  • 实体链接怎么做?识别出「腾讯」后,得链接到知识图谱里的唯一节点

这些,都是后面章节要聊的内容。今天先到这里。

实体识别技术演进路线 基于规则 正则 + 词典 + 句法模式 基于统计 HMM → CRF 基于深度学习 BiLSTM-CRF → BERT 特征工程:规则(人工)→ CRF(模板)→ 深度学习(自动学习) 数据需求:规则(0标注)→ CRF(千级)→ 深度学习(万级) 效果上限:规则(70%)→ CRF(85%)→ BERT(95%+) 投研场景推荐:规则兜底 + BERT主力 + CRF备用(三层架构) 数据量少用规则,数据量中等用CRF,数据量大用BERT

一句话总结:实体识别没有银弹。规则快但死板,CRF稳但累,BERT强但贵。我个人的做法是——先跑规则基线,再用CRF提点,最后用BERT冲刺。每一步都清楚自己在干什么。

专注资料整理