从规则到大模型:命名实体识别(NER)技术的进化之路

在自然语言处理(NLP)的浩瀚星空中,有一颗星辰始终璀璨夺目,那就是命名实体识别(Named Entity Recognition, 简称 NER)。作为信息抽取、知识图谱构建、机器翻译和智能问答等高级NLP任务的基石,NER 的目标非常明确:从非结构化的文本中识别出具有特定意义的实体,并对其进行分类(如人名、地名、机构名、时间表达式等)。

如果你在搜索引擎中输入“苹果公司今年发布了新款手机”,系统必须准确地识别出“苹果公司”是一个组织机构(ORG),而不是一种水果。这个看似人类瞬间就能完成的过程,在计算机视觉和语言处理的历史长河中,却经历了漫长而曲折的演进。

今天,我们就来深入扒一扒 NER 技术的发展底裤,看看它是如何从死板的“规则字典”,一步步进化到如今能够理解上下文语义的“大模型”的。本文不仅包含理论推演,还会穿插实战代码,带你全方位搞懂 NER。


目录

  1. 引言:什么是 NER?
  2. 远古时代:基于规则与词典的方法
  3. 统计机器学习时代:序列标注的曙光
  4. 深度学习时代:从 Word2Vec 到 BiLSTM-CRF
  5. 预训练时代:BERT 带来的降维打击
  6. 大模型(LLM)时代:生成式 NER 的降维打击
  7. 前沿挑战与未来展望
  8. 总结

1. 引言:什么是 NER?

在正式开始时间旅行之前,我们需要明确 NER 的数学和语言学定义。NER 在本质上是一个序列标注任务。

给定一段文本序列 X=(x1,x2,...,xn)X = (x_1, x_2, ..., x_n),NER 模型的目标是找到一个标签序列 Y=(y1,y2,...,yn)Y = (y_1, y_2, ..., y_n),使得条件概率 P(YX)P(Y|X) 最大化。

通常,我们会使用 BIO 标注法(Begin, Inside, Outside)或 BIOES 标注法(Begin, Inside, Outside, End, Single)来将实体抽取问题转化为分类问题。

例如:

输入文本:马斯克收购了推特。
BIO标签马斯/B-PER 克/I-PER 收/O 购/O 了/O 推/B-ORG 特/I-ORG 。/O

理解了这是一个“对号入座”的分类任务,我们就能更好地理解后续算法的演进逻辑。


2. 远古时代:基于规则与词典的方法

在计算资源匮乏、语料库匮乏的 20 世纪八九十年代,数据科学家们采用的是最朴素也最直接的方法:规则匹配字典查找

核心思想

研究人员依靠语言学专家编写大量的正则表达式,或者构建庞大的专有名词词典(如人名词典、地名辞典)。当文本中出现与词典中匹配的词,或者符合特定正则规则(如“Mr. 后面跟一个首字母大写的单词通常是人名”)时,就将其提取为实体。

致命痛点

  1. 泛化能力极差:规则和词典是“死”的,语言是“活”的。遇到未登录词,系统直接抓瞎。
  2. 维护成本高昂:随着新词不断涌现(如“元宇宙”、“奥密克戎”),需要不断更新词典,这在大规模应用中是不现实的。
  3. 歧义性无法解决:“朝阳区”既是地名,有时也代指某种文化现象;规则很难结合上下文消解歧义。

尽管现在已经很少单纯依靠规则做 NER,但在某些特定垂直领域(如医疗病历分析中提取特定的疾病名称),基于词典的方法依然作为基线模型或特征补充存在。


3. 统计机器学习时代:序列标注的曙光

随着语料库的建设,1990 年代末到 2000 年代初,统计机器学习方法开始登上历史舞台。NER 问题被正式建模为序列标注问题

这一时期诞生了三大神级模型:隐马尔可夫模型(HMM)最大熵马尔可夫模型(MEMM)条件随机场(CRF)

HMM:生成式的先驱

HMM 假设文本是由一个隐藏的标签序列生成的。它使用贝叶斯公式,通过最大化联合概率 P(X,Y)P(X, Y) 来求解标签。但 HMM 存在两个致命弱点:

  1. 它是生成式模型,直接建模联合概率,这对于标注任务来说多此一举。
  2. 它存在严格的输出独立性假设(当前观测只依赖当前状态),无法提取复杂的上下文特征。

CRF:机器学习时代的王者

2001 年,Lafferty 等人提出了 条件随机场,这可以说是 NER 发展史上的一个重要里程碑。

CRF 是一种判别式概率无向图模型。与 HMM 不同,CRF 直接对条件概率 P(YX)P(Y|X) 进行建模。它不仅考虑了观测序列 XX 的特征(比如当前的词是什么),还考虑了标签序列 YY 之间的转移特征(比如 B-PER 后面大概率是 I-PER 而不能是 B-LOC)。

CRF 的核心优势在于全局最优解。它通过引入大量的特征模板(如 C1C_{-1}前一个词、C0C_0当前词、C1C_{1}后一个词、词性等),能够有效地捕捉长距离的上下文依赖。

在深度学习爆发前,手工特征工程 + CRF 是所有 NER 比赛刷榜的标配。然而,特征工程耗时耗力,且模型容量有限,人类无法穷尽所有的语言特征。


4. 深度学习时代:从 Word2Vec 到 BiLSTM-CRF

2013 年,Word2Vec 的横空出世开启了分布式表示的新纪元。深度学习开始接管 NLP,NER 也迎来了第一次真正意义上的“自动化”飞跃。

神经网络架构的演进

在这个阶段,NER 模型通常由三个部分组成:

  1. 输入层:将离散的词语转化为密集的词向量。
  2. 编码层:提取上下文特征。
  3. 解码层:输出标签序列。

最初,人们使用 CNN 来提取局部特征,但很快发现 RNN(循环神经网络)更适合处理变长序列。特别是 双向 LSTM(BiLSTM),它能完美地融合前向和后向的上下文信息。

为什么一定要加 CRF?(BiLSTM-CRF 模型解析)

如果你熟悉深度学习,你可能会问:既然 BiLSTM 已经输出了每个词对应各个标签的概率分布,我们直接在每个时间步取 argmax 不就行了吗?为什么还要在后面接一个繁琐的 CRF 层?

答案在于:标签的合法性约束。

假设我们只有三个标签:B-PER, I-PER, O。BiLSTM 可能会犯这样的低级错误:

  • 第 1 个词预测为:O
  • 第 2 个词预测为:I-PER(直接跳到了 Inside,缺少 Begin)

CRF 层可以学习到转移矩阵,它会强行惩罚那些不合法的标签转移路径(比如 OIPERO \rightarrow I-PER 的转移概率会被设为极小值),从而保证最终输出的整条标签路径是合理合法的。

代码实战:基于 PyTorch 的 BiLSTM-CRF 核心逻辑

为了让你直观感受其内部机制,我们用 PyTorch 写一段简化版的 BiLSTM-CRF 核心代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import torch
import torch.nn as nn

class BiLSTM_CRF(nn.Module):
def __init__(self, vocab_size, tag_to_ix, embedding_dim, hidden_dim):
super(BiLSTM_CRF, self).__init__()
self.embedding_dim = embedding_dim
self.hidden_dim = hidden_dim
self.vocab_size = vocab_size
self.tag_to_ix = tag_to_ix
self.tagset_size = len(tag_to_ix)

self.word_embeds = nn.Embedding(vocab_size, embedding_dim)
self.lstm = nn.LSTM(embedding_dim, hidden_dim // 2,
num_layers=1, bidirectional=True)

# 将 BiLSTM 的输出映射到标签空间
self.hidden2tag = nn.Linear(hidden_dim, self.tagset_size)

# CRF 层的核心:转移矩阵
# transitions[i,j] 表示从标签 j 转移到标签 i 的分数
self.transitions = nn.Parameter(
torch.randn(self.tagset_size, self.tagset_size)
)

def _get_lstm_features(self, sentence):
embeds = self.word_embeds(sentence).view(len(sentence), 1, -1)
lstm_out, _ = self.lstm(embeds)
lstm_out = lstm_out.view(len(sentence), self.hidden_dim)
lstm_feats = self.hidden2tag(lstm_out)
return lstm_feats

def _forward_alg(self, feats):
# 计算 log-sum-exp,即配分函数 (所有可能路径的总分)
# 这是 CRF 损失函数的核心部分:前向算法
# 此处省略具体实现,原理是动态规划计算所有路径概率的对数
pass

def neg_log_likelihood(self, sentence, tags):
# 损失函数 = 真实路径的分数 - 所有路径的总分
feats = self._get_lstm_features(sentence)
forward_score = self._forward_alg(feats)
gold_score = self._score_sentence(feats, tags)
return forward_score - gold_score

注:在著名的 PyTorch 官方教程中,BiLSTM-CRF 的前向算法和维特比解码是用 for 循环手写的。在现代框架中,通常可以直接调用 torchcrf 等第三方库来实现高效的矩阵化计算。

BiLSTM-CRF 在 CoNLL-2003 等权威数据集上刷出了当时的 SOTA(State-of-the-Art)成绩。然而,LSTM 的串行计算特性使得它在处理长文本时训练速度缓慢,且 Word2Vec 是静态的词向量,无法解决“一词多义”的问题(比如 Bank 在河岸和银行中向量相同)。


5. 预训练时代:BERT 带来的降维打击

2017 年,Google 发表了神作《Attention is All You Need》,Transformer 架构取代了 RNN 成为主流。2018 年,同样来自 Google 的 BERT(Bidirectional Encoder Representations from Transformers) 模型横空出世,直接按下了 NLP 旧时代的暂停键。

动态词向量与注意力机制

BERT 通过 Masked Language Model (MLM) 任务在大规模无监督语料上进行了预训练。这使得它能够根据上下文动态地生成词向量,完美解决了多义词问题。

在 NER 任务中,基于 BERT 的模型架构变得异常简单:
BERT + Linear + Softmax/CRF

很多时候,研究人员甚至发现,仅仅在预训练好的 BERT 模型后面加上一个简单的线性分类层,就能在各大排行榜上超越曾经复杂的 BiLSTM-CRF。BERT 强大的表征能力使得特征工程和复杂的网络设计变得不再必要。

代码实战:使用 Hugging Face 实现 BERT-based NER

现代深度学习开发早已高度模块化。使用 transformers 库,只需几行代码就能完成强大的 NER 推理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
from transformers import AutoTokenizer, AutoModelForTokenClassification
from transformers import pipeline

# 加载在 CoNLL-2003 数据集上微调好的 BERT NER 模型
tokenizer = AutoTokenizer.from_pretrained("dslim/bert-base-NER")
model = AutoModelForTokenClassification.from_pretrained("dslim/bert-base-NER")

# 创建 NER pipeline
nlp_ner = pipeline("ner", model=model, tokenizer=tokenizer)

text = "Elon Musk is the CEO of Tesla, which is headquartered in Austin."

# 一键执行 NER
ner_results = nlp_ner(text)

for result in ner_results:
print(f"实体: {result['word']: <15} | 标签: {result['entity']: <10} | 置信度: {result['score']:.4f}")

"""
输出预期:
实体: Elon | 标签: B-PER | 置信度: 0.9988
实体: Musk | 标签: I-PER | 置信度: 0.9985
实体: Tesla | 标签: B-ORG | 置信度: 0.9979
实体: Austin | 标签: B-LOC | 置信度: 0.9976
"""

在这个时代,预训练 + 微调(Pre-train + Fine-tune) 成为了绝对的主流。但 BERT 也并非完美,它的词粒度是子词,容易将一个实体切成几个子词;同时,它依然需要针对特定的 NER 任务收集大量人工标注数据进行微调。


6. 大模型(LLM)时代:生成式 NER 的降维打击

当时间来到 2022 年底,ChatGPT 引爆了生成式 AI。NLP 的范式再次发生了颠覆性的变化:从“序列标注”转向了“Prompt 提示学习与指令微调”。

在传统 NER 中,我们需要定义一套死板的标签体系(如 BIOES)。而在大语言模型(LLM)时代,NER 被转化为一个文本生成任务

In-context Learning (上下文学习) 与 Zero-shot NER

大模型(如 GPT-4, Claude 3, Llama 3)在预训练阶段已经阅读了人类几乎所有的公开文本,它们已经具备了极强的“常识”。这使得我们在做 NER 时,甚至不需要训练模型!

我们只需要通过自然语言下达指令:

System Prompt: 你是一个专业的实体抽取专家。请从给定的文本中提取出人名、地名和组织机构,并以 JSON 格式返回。
User Input: 库克在苹果公司总部发布了最新的iPhone。
LLM Output:

1
2
3
4
5
{
"PER": ["库克"],
"ORG": ["苹果公司"],
"LOC": ["苹果公司总部"]
}

这种零样本或 Few-shot 的能力,使得 NER 的门槛降低到了冰点。只要你的 Prompt 写得够好,模型就能精准地抽取,甚至能推断出隐含的实体关系(比如“表盘上的劳力士” -> 抽取“劳力士”为品牌,而传统模型可能只会把它当普通名词)。

代码实战:利用 LangChain 与 LLM 进行生成式 NER

下面展示如何通过构建 Prompt 模板,调用大模型 API 进行实体抽取。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import os
from langchain_openai import ChatOpenAI
from langchain.prompts import ChatPromptTemplate

# 初始化 LLM (以 OpenAI 为例,也可替换为本地的开源大模型 API)
llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)

# 1. 定义 Prompt 模板
prompt = ChatPromptTemplate.from_messages([
("system", "你是一个高级文本分析机器人。你的任务是从用户的文本中提取实体。"),
("human", """请从以下文本中提取实体,并按照指定的格式输出。

文本:{text}

要求提取的实体类型:
1. 疾病名称
2. 药物名称
3. 医疗器械

请以严格的 JSON 格式输出,如果没有找到相应的实体,则对应值为空列表。只输出 JSON,不要包含其他说明文字。
示例输出格式:
{{
"diseases": [],
"medications": [],
"devices": []
}}
"""),
])

# 2. 构建处理链
chain = prompt | llm

# 3. 执行抽取
medical_text = "患者被确诊为2型糖尿病,医生建议注射胰岛素,并购买了罗氏血糖仪进行日常监测。"
response = chain.invoke({"text": medical_text})

print(response.content)

"""
预期输出:
{
"diseases": ["2型糖尿病"],
"medications": ["胰岛素"],
"devices": ["罗氏血糖仪"]
}
"""

LLM 时代 NER 的优缺点

优点:

  • 零代码/少代码: 降低了算法落地的门槛,非技术人员也能用自然语言调整抽取逻辑。
  • 极强的泛化性: 能够处理复杂的嵌套实体(如“北京大学人民医院”既是组织机构又包含地名),这是传统扁平化 BIO 标注难以做到的。
  • 无需标注数据: 真正实现了低资源场景下的快速冷启动。

缺点:

  • 幻觉问题: 模型可能会无中生有,或者把不是实体的词强行抽取。
  • 速度与成本: LLM 的推理延迟远高于专用的 TinyBERT,且调用 API 的成本较高。在千万级的日志处理场景中,用 LLM 做 NER 是一场灾难。

7. 前沿挑战与未来展望

虽然 NER 技术看似已经被大模型“卷”到了终点,但在工业界,NER 依然面临着许多未解之题:

  1. 嵌套实体与不连续实体识别
    例如:“他患有胃底溃疡和十二指肠溃疡”。这里包含了两个疾病实体,且“溃疡”被共享。传统序列标注无法解决这种重叠问题。当前的研究趋势是将其转化为机器阅读理解(MRC)任务或生成式 Seq2Seq 任务。

  2. 低资源多语言 NER
    世界上有几千种语言,很多小语种根本没有任何标注数据。如何利用英语的强大模型,通过跨语言预训练(如 XLM-R)或知识蒸馏,实现小语种的零样本文本抽取,是极具社会价值的方向。

  3. 多模态 NER
    随着短视频和社交媒体的兴起,纯文本 NER 力不从心。比如推文中写着“Love this!”,配图是一台特斯拉。模型需要结合视觉信息(图像中的车标)和文本,才能准确抽取实体。结合视觉大模型(如 GPT-4V)进行多模态实体抽取正在成为学术界的新宠。

  4. 专有领域与 LLM 的结合
    在医疗、法律、金融等专业领域,LLM 往往缺乏足够的深度领域知识,且容易泄露隐私。未来的工业界主流范式很可能是:用 LLM 生成大量高质量的垂直领域伪标签数据 -> 使用这些数据微调一个小巧的专用模型(如基于 DistilBERT 的 NER 模型)部署到生产环境。


8. 总结

回顾 NER 技术长达数十年的演进史,我们可以清晰地看到一条从“规则束缚”走向“自由生成”的轨迹:

  • 基于规则/字典:死板但高准,犹如拿着一本黄页翻找。
  • 传统机器学习 (HMM/CRF):引入了概率统计,依赖繁杂的特征工程,犹如给机器配发了一本语法手册。
  • 深度学习 (BiLSTM-CRF):实现了端到端的自动特征提取,是深度学习在 NLP 的第一次伟大胜利。
  • 预训练时代:用海量的参数和注意力机制暴力美学地碾压了一切,确立了“预训练+微调”的范式。
  • 大模型时代 (LLM):将序列标注转化为文本生成,用极度丰满的庞大参数换取了惊人的泛化能力和零样本抽取能力。

NER 技术的进化史,本质上就是人类教机器理解世界知识的一段缩影。虽然今天我们可以用几行代码调用大模型秒杀曾经困扰学术界数年的难题,但那些隐藏在 CRF 里的转移矩阵、BiLSTM 里的门控机制,依然是人类在探索智能道路上留下的璀璨智慧。

技术在不断迭代,但解决问题、寻找最优解的工程思维永远熠熠生辉。不管未来大模型会进化到何种地步,深入理解这些底层逻辑,都将是我们每一个技术人在 AI 浪潮中站稳脚跟的最大底气。