ner任务思路收集_基于规则匹配器

NER任务

概念:实体抽取,又称为命名实体识别(named entity recognition,NER),指的是从文本之中抽取出命名性实体,并把这些实体划分到指定的类别。

标注规则

IO | 简单,无边界表示, 会出现无法区分两个连续实体的问题(歧义性) 如 广州市天河区

BIO | 加入了开始边界(减少了实体边界识别的歧义,适合处理多个连续或相邻的实体),性能优秀

BIOES | 精确,性能优秀,灵活性强,复杂度高,标注成本高,计算开销大,存在样本类别不均衡问题

B代表Begin,表示实体名称的开头,I代表Inside,表示实体名称的中间或者末尾字符,E代表End,表示实体名称的结束字符,O代表Outside,表示不是实体名称的字符,S代表Single,表示单字为一个命名实体

文本序列 IO标注体系 BIO标注体系 BIOES标注模式
I-PER B-PER B-PER
I-PER I-PER E-PER
O O O
O O O
O O O
I-LOC B-LOC B-LOC
I-LOC I-LOC I-LOC
I-LOC I-LOC E-LOC

评价规则

Precision | T P T P + F P \frac{TP}{TP + FP} TP+FPTP

Recall | T P T P + F N \frac{TP}{TP + FN} TP+FNTP

F1_Score | 2 ∗ P ∗ R P + R \frac{2*P*R}{P + R} P+R2∗P∗R

Accuracy | T P + F N G T \frac{TP + FN}{GT} GTTP+FN

实现方法

基于规则的方法

实现思路: 词典 + 正则表达式

特点:简单暴力(甚至不需要人工标注数据),扩展性差

基于传统机器学习的方法

实现思路:CRF

特点:特征工程麻烦,速度还行

基于深度学习的方法

实现思路:

  • Bi-LSTM with CRF
  • Transformer with CRF
  • Transformer +Prompt with CRF

特点:不需要特征工程,可拓展性强


实战部分

任务与数据介绍 中文NLP地址要素解析

赛题描述[摘自源网页]

1.赛题背景

地址是日常生活中一种重要的文本信息,诸多场景需要登记地址,如电商购物、外卖配送、人口普查、水电气开户等。常见的地址一般包含以下几类信息:

properties 复制代码
行政区划信息,如省、市、县、乡镇信息;
路网信息,如路名,路号,道路设施等;
详细地址信息,如POI (兴趣点)、楼栋号、户室号等;
非地址信息,如补充说明,误输入等;

地址要素解析是将地址文本拆分成独立语义的要素,并对这些要素进行类型识别的过程。地址要素解析与地址相关性共同构成了中文地址处理两大核心任务,具有很大的商业价值。目前中文地址领域缺少标准的评测和数据集,这次我们将开放较大规模的标注语料,希望和社区共同推动地址文本处理领域的发展。

2.赛题描述

中文地址要素解析任务的目标即将一条地址分解为上述几个部分的详细标签,如:

markdown 复制代码
输入:浙江省杭州市余杭区五常街道文一西路969号淘宝城5号楼,放前台
输出:Province=浙江省 city=杭州市 district=余杭区 town=五常街道 road=文一西路road_number=969号 poi=淘宝城 house_number=5号楼 other=,放前台

数据情况(train.conll, dev.conll)

markdown 复制代码
# 样本之间使用\n隔开
上 B-district
城 I-district
区 E-district
望 B-road
江 I-road
东 I-road
路 E-road
0 B-roadno
0 I-roadno
0 I-roadno
号 E-roadno
望 B-poi
江 I-poi
国 I-poi
际 I-poi
中 I-poi
心 E-poi
0 B-houseno
栋 E-houseno
0 B-floorno
楼 E-floorno

数据标注规则 [见前面超链接中的 中文地址要素解析标注规范.pdf]


基于规则匹配的中文地址要素解析

代码转载自赛题提供的baseline

1- 加载数据集

python 复制代码
def load_conll_file(filename):
    """
    读取文件,返回一个生成器,每一句会生成一个字典,字典包含tokens和labels两个key
    按空行分割句子,返回包含tokens和labels的字典
    :param filename: 文件名
    :return: e.g {'tokens': ['浙','江'], 'labels': ['B-LOC','E-LOC']}
    """
    with open(filename, 'r', encoding='utf8') as f:
        tokens = []
        labels = []
        for line in f:
            if line == '' or line == '\n':
                if tokens:
                    yield {
                        'tokens': tokens,
                        'labels': labels
                    }
                    tokens = []
                    labels = []
            else:
                splits = line.rsplit(' ', 1)
                tokens.append(splits[0])
                labels.append(splits[-1].rstrip())
        if tokens:
            yield {
                'tokens': tokens,
                'labels': labels
            }

2- 获取训练集和验证集中的实体要素

python 复制代码
def get_entities(tokens, labels):
    """
    获取实体列表
    :param tokens: e.g ['浙','江']
    :param labels: e.g ['B-LOC','E-LOC']
    :return: e.g
    """
    entities = []
    cur_entity = {}
    for token, label in zip(tokens, labels):
        if label[0] in 'OBS' and cur_entity:
            entities.append(cur_entity)
            cur_entity = {}
        if label[0] in 'BS':
            cur_entity = {
                'text': token,
                'type': label[2:]
            }
        elif label[0] in 'IE':
            cur_entity['text'] += token
    if cur_entity:
        entities.append(cur_entity)
    return entities

3 - 定义规则匹配器

python 复制代码
from spacy.lang.zh import Chinese
class RuleBasedTagger:
   def __init__(self, entity_counter, threshold=1):
       nlp = Chinese()
       ruler = nlp.add_pipe('entity_ruler')
       patterns = [{'label': e[0][1], 'pattern': e[0][0]} for e in entity_counter.most_common() if e[1] >= threshold]
       with nlp.select_pipes(enable='tagger'):
           ruler.add_patterns(patterns)
       self.nlp = nlp

   def __call__(self, sentence):
       doc = self.nlp(sentence)
       # (start,end) 包左不包右
       return [{
           'text': span.text,
           'label': span.label_,
           'start': span.start,
           'end': span.end
       } for span in doc.ents]

def format_entities(entities, length):
   labels = ['O'] * length
   for e in entities:
       start, end, label = e['start'], e['end'], e['label']
       if start + 1 == end:
           labels[start] = 'S-' + label
       else:
           labels[start] = 'B-' + label
           for i in range(start + 1, end - 1):
               labels[i] = 'I-' + label
           labels[end - 1] = 'E-' + label
   return ' '.join(labels)

4 - 主函数

python 复制代码
if __name__ == '__main__':
    # load datasets and count entities
    train_dataset = list(load_conll_file('../data/train.conll'))
    dev_dataset = list(load_conll_file('../data/dev.conll'))

    # print(len(train_dataset))
    # print(len(dev_dataset))

    from collections import Counter

    entity_counter = Counter()
    for example in train_dataset + dev_dataset:
        entities = get_entities(example['tokens'], example['labels'])
        entity_counter.update([(e['text'], e['type']) for e in entities])

    # print(entity_counter.most_common())

    tagger = RuleBasedTagger(entity_counter)

    # print(tagger('浙江杭州阿里'))

    # process test file and get predictions
    with open('../data/final_test.txt', 'r', encoding='utf8') as fin, \
            open('outputs/baseline1.pred.txt', 'w', encoding='utf8') as fout:
        for line in fin:
            guid, sentence = line.strip().split('\u0001')
            predicted_entities = tagger(sentence)
            formatted_pred = format_entities(predicted_entities, len(sentence))
            print(guid, sentence, formatted_pred, sep='\t', file=fout)
相关推荐
Flash Bomb42231 分钟前
自然语言处理(20:(第五章5.)进一步改进RNNLM)
人工智能·rnn·语言模型·自然语言处理·lstm
Watermelo6174 小时前
Manus使用的MCP协议是什么?人工智能知识分享的“万能插头”
人工智能·深度学习·神经网络·机器学习·语言模型·自然语言处理·数据挖掘
Chaos_Wang_11 小时前
NLP高频面试题(二十三)对抗训练的发展脉络,原理,演化路径
人工智能·自然语言处理
风吹草地现牛羊的马14 小时前
mac m1/m2/m3 pyaudio的安装
深度学习·macos·自然语言处理·#pyaudio
紫雾凌寒19 小时前
自然语言处理|人工智能如何革新作文批改:技术全解析
人工智能·深度学习·自然语言处理·easyui·长文本处理·语义理解·ai批改作文
静心问道19 小时前
CPM:大规模生成式中文预训练语言模型
人工智能·语言模型·自然语言处理
Listennnn21 小时前
NLP语言模型训练里的特殊向量
人工智能·语言模型·自然语言处理
Flash Bomb42221 小时前
自然语言处理(21:(第六章1.)基于RNN生成文本)
人工智能·rnn·深度学习·神经网络·自然语言处理
pen-ai1 天前
【NLP】14. NLP推理方法详解 --- beam search 束搜索 以及 graph search 图搜索
人工智能·自然语言处理
p186848058101 天前
ICFEEIE 2025 WS4:计算机视觉和自然语言处理中的深度学习模型和算法
深度学习·计算机视觉·自然语言处理