人工智能实践(语言智能)
第1讲:经典 NLP 任务

1.4 序列标注

NER、POS tagging、Chunking;BIO / BIOES 标注方案;HMM / CRF 与神经网络的结合;LLM 时代零样本 NER 的局限

从"整句分类"到"逐字打标签"

上一节讲的文本分类是把整段文本映射到一个标签。本节讲序列标注(Sequence Labeling)——给句子里的每一个 token 都分配一个标签。

这类任务在工业界极其重要但在大模型热潮下有些被遗忘:

  • 命名实体识别(NER, Named Entity Recognition):从一段文本中抽出"人名 / 地名 / 机构 / 时间 / 金额"等
  • 词性标注(POS Tagging, Part-of-Speech):为每个词打上"名词 / 动词 / 形容词"等
  • 组块分析(Chunking):把连续的词切成短语(名词短语、动词短语)
  • 事件抽取 / 关系抽取:NER 的延伸——不只是实体,还要抽取实体间的关系

信息抽取(IE)、知识图谱构建、医疗电子病历结构化、法律合同审查、RAG 系统的元数据提取——每一个落地场景背后都有 NER 在支撑。


核心问题:如何把"序列"变成"标签序列"?

给定句子:

北京  大学  位于  海淀区  中关村

NER 任务希望输出:

北京大学  → ORG
海淀区    → LOC
中关村    → LOC

模型需要同时解决两个子问题

  1. 边界识别:"北京" 和 "大学" 应该合并为一个机构名,而不是两个独立的地名
  2. 类型分类:识别出的片段属于哪一类实体

这里的难点:模型是逐 token 做预测的,如何让它输出"跨越多个 token 的实体"?这就是 BIO 标注方案要解决的事。


BIO 与 BIOES 标注

BIO 方案(最常用)

  • B-X:实体 X 的开始(Begin)
  • I-X:实体 X 的中间或末尾(Inside)
  • O:不属于任何实体(Outside)

上面例子在 BIO 下变成:

token北京大学位于海淀区中关村
BIO 标签B-ORGI-ORGOB-LOCB-LOC

这样,NER 就被转化为标准的 token 级分类问题——每个 token 在 KK 类标签(2N+1 类,N 为实体类型数)中选一个。

BIOES 方案(更精细)

BIOES 在 BIO 基础上加两个标签:

  • E-X:实体 X 的结束(End)
  • S-X:单 token 实体(Single)

好处:明确区分"实体末尾"与"实体中间",让模型的边界学习信号更强。代价:标签数翻倍,小数据集上反而容易过拟合。

BIO vs BIOES 的选择:学术 benchmark 上 BIOES 常略优,但差距通常 < 1%。工业界大多数用 BIO,简单且便于调试。关键是训练与评估使用的方案必须一致——混用会导致灾难。


建模演化:从 HMM 到 BERT + CRF

HMM 与 CRF 时代(2000-2015)

序列标注的核心特点:相邻标签之间有强约束B-PER 后面不可能直接跟 I-LOC,独立逐 token 预测会产生大量非法组合。

这就是条件随机场(CRF, Conditional Random Field)要解决的事。CRF 的决策目标不是独立最大化每个 token 的概率,而是最大化整条标签序列的联合概率:

P(yx)=1Z(x)exp(t=1Tkλkfk(yt1,yt,x,t))P(y | x) = \frac{1}{Z(x)} \exp\left(\sum_{t=1}^T \sum_k \lambda_k f_k(y_{t-1}, y_t, x, t)\right)

其中 fkf_k 是特征函数,λk\lambda_k 是学习到的权重。CRF 通过 Viterbi 算法在所有可能标签序列中找最优,天然排除非法的 BIO 跳转。

神经网络 + CRF 时代(2015-2018)

经典架构:BiLSTM + CRF。BiLSTM 学习每个 token 的上下文表示,CRF 层建模标签间的转移约束。在当时是 NER 的 SOTA。

BERT 时代(2018-)

BERT 级别的预训练表示已经极强,很多任务上 BERT + 线性头 就能达到 BERT + CRF 的水平,因为 BERT 的上下文信息足以让模型"自学"到标签约束。但在低资源、标注稀少的场景下,CRF 层提供的结构先验仍能带来 0.5-2 个点的提升。


评估:Entity-level F1

序列标注的评估不是 token 级的。考虑:

真实标签:  [B-ORG, I-ORG, I-ORG]  → 一个 3-token 的机构
模型预测:  [B-ORG, I-ORG, O]       → 只识别出 2 个 token

Token 级 F1 会说"你做对了 2/3",但业务上这个实体完全错了——边界错误导致下游不可用。

Entity-level F1 的定义:

  • TP:预测的实体与真实实体边界完全一致 且 类型一致
  • FP:预测出了一个实体,但边界或类型不对
  • FN:真实实体没有被预测到

然后按分类任务的 Precision / Recall / F1 公式聚合。这是 CoNLL、OntoNotes 等经典 NER benchmark 的标准评估方式,也是 seqeval 库的默认行为。

from seqeval.metrics import classification_report

y_true = [["B-ORG", "I-ORG", "O", "B-LOC"]]
y_pred = [["B-ORG", "I-ORG", "O", "B-LOC"]]

print(classification_report(y_true, y_pred, digits=4))

LLM 时代:零样本 NER 能取代标注吗?

一个现代研究生常问的问题:既然 GPT-4 / Claude 一句 prompt 就能做 NER,还需要标注数据微调吗?

现实比宣传复杂得多。

零样本 NER 能做什么

prompt = """
从下面文本中抽取所有"机构名"和"地名",以 JSON 返回:
"北京大学位于海淀区中关村"
"""
# GPT-4 大概率返回:
# {"机构名": ["北京大学"], "地名": ["海淀区", "中关村"]}

通用领域、实体类型明确的任务,LLM zero-shot NER 表现相当不错——可能达到 70-85 F1。

零样本 NER 做不好的事

零样本 NER 的五个致命弱点

  1. 专业领域:医学、法律、金融的实体边界和类型定义非常细(如 ICD-10 疾病代码)。通用 LLM 不懂你的体系,零样本得分可能跌到 40-60 F1。
  2. 边界一致性:同一个实体 "Dr. 张三" 可能有时包含职称、有时不包含,LLM 输出无法保持内部一致。
  3. 嵌套实体:真实数据中实体常嵌套("北京大学软件与微电子学院" 同时是 ORG 和包含地名"北京")。Prompt 很难明确指定嵌套规则。
  4. 规模化成本:处理 100 万篇文档,LLM API 调用成本比部署一个 BERT-NER 模型贵几个数量级,推理延迟也慢百倍。
  5. 可控性:业务要求"必须返回 JSON 格式",LLM 偶尔会飘出非法输出,下游系统崩溃。

现代工业实践

真实的 NER 系统往往采用分层架构

  • 基座:BERT-NER 或 LLM 蒸馏出的小模型,覆盖 95% 常见实体
  • LLM 补充:冷启动、新增实体类型、罕见实体用 LLM 兜底
  • 主动学习闭环:LLM 输出供人工审核 → 进入训练集 → 下一版 BERT-NER

序列标注这条线没有被大模型取代,而是被融合进了更复杂的数据飞轮


本节小结

概念要点
序列标注为每个 token 分配标签;NER / POS / Chunking 的共同形式
BIO 方案B-X 开始、I-X 内部、O 非实体;NER 的标准编码
BIOES 方案增加 E-X(结束)和 S-X(单 token);边界信号更强
CRF建模标签间转移约束,排除非法 BIO 跳转
BERT + 线性头大多数场景足够;低资源时加 CRF
Entity-level F1评估必须到实体级,不能只看 token 级
LLM 零样本 NER通用场景可用,专业领域、规模化、可控性上仍需传统 NER