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)
相关推荐
FF-Studio20 小时前
【硬核数学】3. AI如何应对不确定性?概率论为模型注入“灵魂”《从零构建机器学习、深度学习到LLM的数学认知》
大数据·人工智能·深度学习·机器学习·数学建模·自然语言处理·概率论
羊小猪~~1 天前
【NLP入门系列四】评论文本分类入门案例
人工智能·自然语言处理·分类
一ge科研小菜鸡1 天前
云原生环境下部署大语言模型服务:以 DeepSeek 为例的实战教程
人工智能·语言模型·自然语言处理
zeroporn11 天前
以玄幻小说方式打开深度学习词嵌入算法!! 使用Skip-gram来完成 Word2Vec 词嵌入(Embedding)
人工智能·深度学习·算法·自然语言处理·embedding·word2vec·skip-gram
Zhijun.li@Studio11 天前
【LLaMA-Factory 实战系列】二、WebUI 篇 - Qwen2.5-VL 多模态模型 LoRA 微调保姆级教程
人工智能·自然语言处理·llama·多模态大模型
lgbisha11 天前
华为云Flexus+DeepSeek征文|体验华为云ModelArts快速搭建Dify-LLM应用开发平台并创建自己的AI写作神器
人工智能·ai·语言模型·自然语言处理·华为云·ai写作
大模型最新论文速读11 天前
Agent成本降低46%:缓存规划器的思路模板
人工智能·深度学习·机器学习·缓存·语言模型·自然语言处理
unityのkiven11 天前
Happy-LLM task2 第一章 NLP 基础概念(2天)
人工智能·自然语言处理
东临碣石8211 天前
【AI论文】扩展大型语言模型(LLM)智能体在测试时的计算量
人工智能·语言模型·自然语言处理
H4ppyD0g11 天前
预训练语言模型基础知识概述
人工智能·语言模型·自然语言处理