4. 命名实体识别(NER)基础:从规则到深度学习

命名实体识别,说白了就是让机器从文本里把人名、地名、机构名、时间这些关键信息给揪出来。在金融领域,这活儿尤其重要——你想想看,一份财报里藏着多少公司名、产品名、高管名字?要是靠人工去标,那得累死。

我个人习惯把NER的发展分成三个阶段:规则驱动、统计学习、深度学习。这三个阶段不是替代关系,而是互补的。我在项目中遇到过不少场景,最后是混着用的。

4.1 基于规则的方法:最朴素,但有时最管用

规则方法,就是人工写一堆模式匹配规则。比如「XX公司」、「XX银行」、「XX证券」这种固定模式,用正则表达式就能搞定。

import re

def rule_based_ner(text):
    entities = []
    # 匹配公司名模式
    company_pattern = r'[\u4e00-\u9fa5]{2,}(?:公司|集团|银行|证券|基金)'
    for match in re.finditer(company_pattern, text):
        entities.append({
            'text': match.group(),
            'type': 'ORG',
            'start': match.start(),
            'end': match.end()
        })
    # 匹配金额模式
    money_pattern = r'\d+(?:\.\d+)?[万亿]?元'
    for match in re.finditer(money_pattern, text):
        entities.append({
            'text': match.group(),
            'type': 'MONEY',
            'start': match.start(),
            'end': match.end()
        })
    return entities
我的经验:规则方法在特定场景下效率极高。我曾经给一个券商做年报解析,他们财报里的公司名格式非常统一,用规则方法准确率直接干到95%以上。但遇到「阿里巴巴」这种不带后缀的,就抓瞎了。

规则方法的优点很明显:不需要标注数据,解释性强。缺点也致命:维护成本高,遇到新实体就得加新规则。说白了,规则是死的,语言是活的。

4.2 基于统计的方法:CRF,让模型自己学规律

CRF(条件随机场)是统计方法的代表。它不写死规则,而是从标注数据里学「转移特征」和「状态特征」。比如「B-ORG」后面大概率跟「I-ORG」,不太可能直接跳到「B-PER」。

为什么会这样?因为CRF本质上是在建模标签之间的依赖关系。你想想看,一个实体内部标签是连续的,跨实体之间标签会跳变,CRF就是学这个规律。

# 使用sklearn-crfsuite实现
import sklearn_crfsuite

def word2features(sent, i):
    word = sent[i][0]
    features = {
        'word': word,
        'word.isdigit': word.isdigit(),
        'word.isupper': word.isupper(),
        'word[-3:]': word[-3:],
        'word[-2:]': word[-2:],
        'word[:2]': word[:2],
    }
    # 上下文特征
    if i > 0:
        features['prev_word'] = sent[i-1][0]
    if i < len(sent)-1:
        features['next_word'] = sent[i+1][0]
    return features

# 训练CRF模型
crf = sklearn_crfsuite.CRF(
    algorithm='lbfgs',
    c1=0.1,  # L1正则化
    c2=0.1,  # L2正则化
    max_iterations=100
)
crf.fit(X_train, y_train)
避坑指南:我曾经在CRF的特征工程上栽过跟头。特征不是越多越好,有些特征反而会引入噪声。比如在金融文本里,「元」这个字本身不是实体,但「亿元」前面的数字大概率是金额。特征设计要结合领域知识。

CRF的优点在于:对序列标注任务天然适配,能利用全局信息做决策。缺点也很明显:特征工程太依赖人工经验,而且训练速度慢,数据量大了就跑不动。

4.3 基于深度学习的方法:BiLSTM-CRF,端到端的革命

深度学习的出现,让NER从「手工特征」进化到了「自动特征」。BiLSTM-CRF是经典组合——BiLSTM负责提取上下文特征,CRF负责解码标签序列。

说白了,BiLSTM就是双向看上下文。比如「工商银行」这个词,从左往右看「工商」是前缀,「银行」是核心;从右往左看「银行」确认了机构属性。双向信息一结合,准确率就上去了。

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().__init__()
        self.embedding = nn.Embedding(vocab_size, embedding_dim)
        self.lstm = nn.LSTM(embedding_dim, hidden_dim // 2,
                           num_layers=2, bidirectional=True)
        self.hidden2tag = nn.Linear(hidden_dim, len(tag_to_ix))
        self.crf = CRF(len(tag_to_ix), batch_first=True)

    def forward(self, sentence, tags=None):
        embeds = self.embedding(sentence)
        lstm_out, _ = self.lstm(embeds)
        emissions = self.hidden2tag(lstm_out)
        if tags is not None:
            loss = -self.crf(emissions, tags)
            return loss
        else:
            return self.crf.decode(emissions)

核心要点:BiLSTM-CRF相比纯CRF,最大的优势是不用手工设计特征。词向量(如Word2Vec、GloVe)已经包含了语义信息,模型自己就能学到「银行」和「证券」在语义空间里是相近的。

我在项目中实测过,BiLSTM-CRF在金融NER任务上,F1值比传统CRF高出5-8个百分点。但代价是:需要大量标注数据,而且训练时间翻了好几倍。

4.4 BERT时代:预训练+微调,NER的终极形态?

BERT的出现,让NER又上了一个台阶。它用海量无标注文本做预训练,学到的语言表示比词向量丰富得多。你只需要在BERT后面接一个CRF层,微调一下就能用。

嗯,这里要注意:BERT不是万能的。我遇到过的情况是,BERT对长文本处理吃力,而且模型太大,推理速度慢。在实时性要求高的场景里,反而BiLSTM-CRF更实用。

from transformers import BertTokenizer, BertForTokenClassification
import torch

# 加载预训练模型
tokenizer = BertTokenizer.from_pretrained('bert-base-chinese')
model = BertForTokenClassification.from_pretrained(
    'bert-base-chinese',
    num_labels=len(label_list)
)

# 推理示例
text = "阿里巴巴集团在杭州召开股东大会"
inputs = tokenizer(text, return_tensors="pt")
outputs = model(**inputs)
predictions = torch.argmax(outputs.logits, dim=2)
我的建议:在实际项目中,我通常这样选型:
- 标注数据少(<1000条):用规则+CRF
- 标注数据中等(1000-10000条):用BiLSTM-CRF
- 标注数据充足(>10000条):用BERT-CRF
- 对实时性要求高:用BiLSTM-CRF或蒸馏后的BERT

4.5 四种方法对比:没有银弹

方法 准确率 标注数据需求 训练速度 推理速度 可解释性
规则方法 中(特定场景高) 极快 极高
CRF 中高 中等
BiLSTM-CRF 较慢 中等
BERT-CRF 极高 很多 很慢 极低

你看这个表格就明白了:没有哪个方法能通吃所有场景。我个人的经验是,先评估你的数据量和实时性要求,再决定用哪种。别一上来就上BERT,杀鸡用牛刀。

4.6 本章知识体系

下面这张图,是我梳理的NER方法演进路线。从规则到深度学习,每一步都有它的适用场景。

命名实体识别(NER)方法演进 规则方法 CRF BiLSTM-CRF BERT-CRF 手工特征 手工特征+统计 自动特征 预训练+微调 适用场景对比 数据量:无 准确率:中 速度:极快 数据量:中等 准确率:中高 速度:快 数据量:多 准确率:高 速度:中等 数据量:很多 准确率:极高 速度:慢 选型建议 数据少+规则明确 → 规则方法 数据中等+特征清晰 → CRF 数据充足+追求准确 → BiLSTM-CRF / BERT-CRF

最后说一句:别迷信某个方法。我在金融项目里,经常是规则方法打底,CRF做兜底,深度学习模型做主力。三层架构,各司其职,效果反而最好。


公众号:蓝海资料掘金营,微信deep3321