Hugging Face实战-系列教程5:NER上(命名实体识别/文本标注/Doccano工具使用/关键信息抽取/Token分类/源码解读/代码逐行解读/文本BIO处理/文本分类/序列标注)

本文介绍了命名实体识别(NER)的概念和流程,包括数据收集、标注、特征提取、模型训练和评估。通过Doccano工具进行文本标注,并讲解了BIO处理方法。此外,文章还涉及到使用HuggingFace的分词器对数据进行预处理,为模型训练做好准备。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 🚩🚩🚩Hugging Face 实战系列 总目录

有任何问题欢迎在下面留言

本篇文章的代码运行界面均在Pycharm中进行

本篇文章配套的代码资源已经上传

中篇内容:

NLP实战-系列教程6:NER中篇(命名实体识别/文本标注/Doccano工具使用/关键信息抽取/Token分类/源码解读/代码逐行解读/文本BIO处理/文本分类/序列标注)_机器学习杨卓越的博客-CSDN博客

下篇内容:

NLP实战-系列教程7:NER下篇(命名实体识别/文本标注/Doccano工具使用/关键信息抽取/Token分类/源码解读/代码逐行解读/文本BIO处理/文本分类/序列标注)_机器学习杨卓越的博客-CSDN博客

1 NER概念

1.1 NER概念解释

命名实体识别(Named Entity Recognition,NER)是自然语言处理领域的一项关键任务,旨在从文本中识别和分类特定的命名实体,如人名、地名、组织机构名等。NER的目标是标记文本中的实体,并将其归类到预定义的实体类型中。

NER通常使用机器学习和深度学习技术来完成任务。以下是一种常见的NER流程:

  1. 数据收集和标注:收集包含命名实体的文本数据,并为每个实体标注相应的标签(实体类型)。

  2. 特征提取:从文本数据中提取有用的特征,如词性、词形、上下文等。这些特征将作为输入提供给模型。

  3. 模型训练:使用标注好的数据和提取的特征来训练NER模型。常用的模型包括条件随机场(CRF)、循环神经网络(RNN)、长短期记忆网络(LSTM)、卷积神经网络(CNN)和注意力机制(Attention)等。

  4. 模型评估和调优:使用评估数据集来评估训练得到的模型性能,并进行调优以提高准确性和召回率。

  5. 实体识别:使用训练好的NER模型对新的文本进行实体识别。模型将识别并标记文本中的命名实体,使其易于提取和理解。

NER在许多应用中起着重要作用,例如信息抽取、问答系统、文本摘要、机器翻译等。它可以帮助自动化处理大量文本数据,并提供有关实体的结构化信息,为后续的分析和应用提供基础。

1.2 NER任务

对这句话进行一个词的抽取:今天晚上我吃了一只鸭

  • 今天 是一个时间
  • 我 是一个人
  • 鸭 是一个动物

我想对一个文本数据中抽取出一个关键知识

我现在将(时间,人,动物)构建一个三元组行分类,最终定为几类是你在任务中自己定义的,这里的三分类只是举例而已。

分别表示(什么时间,谁,对谁),进行关键信息抽取,那我们解决这个任务的模型就需要知道哪些词是关键信息。那今天这个词是一个时间还是人还是动物就是一个三分类,然后后面的每个词晚上吃了一只都需要进行三分类。所以虽然是叫NER,但是实际上就是一个对Token的分类任务。

Token可以这么理解,在NLP中,拿到一句话无论做什么预处理的工作,第一件事都需要做分词。

那前面那句话举例:

今天晚上我吃了一只鸭

1今天    2晚上    3我    4吃了    5一只    6鸭

这句话进行分词处理就应该是这个结果。对Token进行分类就是把每个词对应的类别是什么做一个映射。Token分类就是对每一个词都进行类别标注,这个过程就叫做一个命名体识别。

所以文本的分类需要人工进行标注。

其实大部分的文本标注工具都自己搭建一个在线的或者离线的,我们今天用一个开源的工具。

2 Doccano工具安装

Doccano是一个标签标注的工具,标注完成后的数据再经过模型设计、调用、训练,安装教程我专门放在了我的这篇文章:

Doccano工具安装教程/文本标注工具/文本标注自己的项目/NLP分词器工具/自然语言处理必备工具/如何使用文本标注工具_会害羞的杨卓越的博客-CSDN博客

3 Doccano工具使用

安装好Doccano工具后,可以创建项目,对自己的数据集进行标注,标注的教程我放在了这篇文章:

Doccano工具使用教程:(NLP实战/命名实体识别/文本标注/Doccano工具使用/关键信息抽取/Token分类/源码解读/代码逐行解读/文本BIO处理/文本分类/序列标注)_会害羞的杨卓越的博客-CSDN博客

4 BIO处理

4.1 BIO

在第3部分中,我们已经拿到了已经标注了3个标签的数据。

打开下载后的文件:

前面是数据,后面是标签,记录的是标签的起始位置信息和对应的标签名。

在文本标注中,我们一般使用BIO的处理流程,B表示开始,I表示中间和结尾,O代表没有标注的内容

比如拿我们刚刚的时间标签举例:

08年考研暑期英语复习全指南

0表示为B-time,8表示为I-time,年表示为I-time,后面其他的词全部表示为O。如果标签就只有时间的这个任务,那就是一个三分类。分别为时间的开头、时间的中间和结尾、其他。如果是刚刚标注三个标签的那个任务,就是3*2+1=7,一个7分类。

所以我们刚刚那个三个标签的任务还没完,还需要把O标出来。在本篇文章中的资源,我们给出了脚本,自动帮你完成这个工作。所以创建了三个标签的任务是一个7分类的任务。 

4.2 BIO处理脚本

在本文配套的资源中,这是我们专门处理的脚本,具体的文件位置是ner/ner-labels/convert.py

 简单介绍一个ner-labels这个文件夹的内容:

  • admin.json:Doccano处理后的数据
  • convert.py:当前提到的脚本
  • train.txt:原始数据
  • train_BIO.txt:脚本处理后的数据
  • unknow.jsonl:原始数据中没有参与标注的文本

4.3 BIO解读

我们删除项目中原有的train_BIO.txt,执行一遍脚本后,就会生成train_BIO.txt

打开这个train_BIO.txt看看:

现在的文件竟然包含567行了,每一个字都对应一个标签。 

这个是我们这个任务我们定义这样的做法,实际上没有一个确定的做法,最后都是要进行分词的处理。你想怎么做标签都是可以的,只要能达到最终的任务。

5、数据读取

在我们的文件中data文件夹有三个数据,我这里就直接偷懒了,训练、验证、测试全都是一样的数据,都和BIO脚本的处理产生的文件相同:

 看我们的train.py的代码,首先指定一下数据的位置:

data_dir = '.\data'

将训练、验证、测试的数据集的数据都读进来:

train_texts, train_tags = read_data(data_dir + '\\train.txt')
test_texts, test_tags = read_data(data_dir + '\\val.txt')
val_texts, val_tags = read_data(data_dir + '\\test.txt')

这里有一个专门读数据的函数read_data,进入到这个函数中,首先是将数据读取进来:

file_path = Path(file_path)
raw_text = file_path.read_text(encoding='UTF-8').strip()
raw_docs = re.split(r'\n\t?\n', raw_text)

这里解释一下,在我们的数据中,我们用空行为间隔将每一行的样本隔开。然后我们开始遍历样本:

token_docs = []
tag_docs = []
for doc in raw_docs:
    tokens = []
    tags = []
    for line in doc.split('\n'):
        token, tag = line.split(' ')
        tokens.append(token)
        tags.append(tag)
    token_docs.append(tokens)
    tag_docs.append(tags)

第一个for循环是遍历每一个样本,第二个for循环是遍历每一个样本的每一个字。最后的返回值:

return token_docs, tag_docs
  • token_docs存的是所有的数据
  • tag_docs存的是所有的标签

6、encoding

训练、测试、验证三个数据集都进行了read_data函数的处理,现在将处理的数据进行封装:

unique_tags = set(tag for doc in train_tags for tag in doc)
tag2id = {tag: id for id, tag in enumerate(unique_tags)}
id2tag = {id: tag for tag, id in tag2id.items()}
label_list = list(unique_tags)

所有的标签是什么存在了unique_tags 

  • unique_tags :整个标签
  • tag2id:标签名字对应的id
  • id2tag: id对应的标签名字(预测的时候,预测0-6的数字,再用这个字典转换成标签名字)
  • label_list :将所有的标签转换成list

此时我们已经完成了分词了,后面做tokenizer只需要记住对应的id就行了

from transformers import AutoTokenizer, BertTokenizerFast #is_split_into_words表示已经分词好了
tokenizer = BertTokenizerFast.from_pretrained('bert-base-chinese')
train_encodings = tokenizer(train_texts, is_split_into_words=True, return_offsets_mapping=True, padding=True, truncation=True,max_length=512)
val_encodings = tokenizer(val_texts, is_split_into_words=True, return_offsets_mapping=True, padding=True, truncation=True,max_length=512)
  • 第一行:导入Hugging Face提供的自动分词器的包、词嵌入向量的预训练模型包
  • 第二行:导入一个中文的预训练的词嵌入模型
  • 第三行:对训练集进行词嵌入操作
  • 第四行:对验证集集进行词嵌入操作

tokenizer参数解析:

tokenizer(train_texts, is_split_into_words=True, return_offsets_mapping=True, padding=True, truncation=True,max_length=512)
  • train_texts:训练数据变量名
  • is_split_into_words:当前输入文本是否已经完成了分词,tokenizer只需要完成id的映射
  • return_offsets_mapping:返回一个offset,后面会解释我们为什么需要一个偏移的offset
  • padding:补长
  • truncation:截断
  • max_length:bert定义的最大长度

如果你对这些参数都完全不明白的话,你应该先阅读一下这篇文章:

Hugging Face实战(NLP实战/Transformer实战/预训练模型/分词器/模型微调/模型自动选择/PyTorch版本/代码逐行解析)上篇之模型调用_会害羞的杨卓越的博客-CSDN博客

现在我们有很多变量,进入pycharm的debug界面,看看有哪些变量,都是什么意思:

我们的每一个样本都会转换成input_ids

这个token_type是什么意思?就是当前的词属于那句话

我们的这个任务,每个文本都是一句话,所以全是0

而这个attention_mask是我们在做self_attention的时候,是记录那些话需要计算attention的

1表示是一个实际的词,为0的表示加的padding。

offset_mapping是偏移量是表示标签应该如何对应的,这个很有用,但是我们还是先不解释,后面会解释。

这几行代码就是把文本转换成对应的id,等下要输入模型的东西。

中篇内容:

NLP实战-系列教程6:NER中篇(命名实体识别/文本标注/Doccano工具使用/关键信息抽取/Token分类/源码解读/代码逐行解读/文本BIO处理/文本分类/序列标注)_机器学习杨卓越的博客-CSDN博客

下篇内容:

NLP实战-系列教程7:NER下篇(命名实体识别/文本标注/Doccano工具使用/关键信息抽取/Token分类/源码解读/代码逐行解读/文本BIO处理/文本分类/序列标注)_机器学习杨卓越的博客-CSDN博客

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Xayah0416

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值