前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >探秘Transformers:用Hugging Face预训练模型实现命名实体识别!

探秘Transformers:用Hugging Face预训练模型实现命名实体识别!

作者头像
Tom2Code
发布于 2024-03-02 02:07:07
发布于 2024-03-02 02:07:07
1.5K00
代码可运行
举报
文章被收录于专栏:TomTom
运行总次数:0
代码可运行

命名实体识别(NER)是自然语言处理中的一项关键任务,旨在从文本中识别并提取出具有特定意义的实体,如人名、地名、组织机构名等。通过NER,计算机可以更好地理解文本,帮助我们从海量文本数据中快速获取有用信息,是许多NLP应用的基础,如信息提取、问答系统等。

我们可以从huggingface上看一个医学实体命名的例子:

输入框里的文字是我们的输入,

点击computer按钮:

这就是我们的结果,可以这个模型成功的从我们的文本中推断出来了很多实体。例如识别出来了age,年龄。还有性别,sex。还有一些医学上的一些专业名称也成功的区分出来了,这就是命名实体识别的一个demo

那我们今天要做的demo是基于中文的命名实体识别。

首先介绍一下数据集:

可以在huggingface上直接搜索:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
peoples_daily_ner

是一个报纸上的一些新闻的文字数据。

再介绍一下我们使用的预训练模型:

也是可以直接从huggingface上搜索:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
hfl/chinese-macbert-base

稍微介绍一下这个模型:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
MacBERT 是一种改进的 BERT,采用新颖的 MLM 作为校正预训练任务,从而减少了预训练和微调之间的差异。

在微调阶段,[MASK] 标记从未出现过,我们建议使用相似词来代替[MASK] 标记进行屏蔽。相似词通过同义词工具包(Wang 和 Hu,2017 年)获得,
该工具包基于 word2vec(Mikolov 等人,2013 年)相似性计算。
如果选择了一个 N-gram 作为掩码,我们将单独找出相似词。
在极少数情况下,如果没有相似词,我们将降级使用随机词替换。

然后就是从huggingface的镜像站上下载我们的模型:

具体的操作在上一篇我们已经介绍过:

点击图片即可进入上一篇文章

接下来废话不多说,直接开肝

1.首先是导包

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import evaluate
from datasets import load_dataset
from transformers import AutoTokenizer, AutoModelForTokenClassification, TrainingArguments, Trainer, DataCollatorForTokenClassification

2.加载数据集

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 如果加载失败 可以通过本地下载到磁盘然后再加载
ner_datasets = load_dataset("peoples_daily_ner", cache_dir="./data")

数据集截图:

随机打印1个数据集看看:

3.加载分词器

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
tokenizer = AutoTokenizer.from_pretrained("hfl/chinese-macbert-base")

还是一样,如果加载失败,可以通过先从镜像站下载到本地,然后再从本地加载分词器和模型

写一个函数,用来处理将原始文本数据中的标签(通常是实体名称或类型的标记)映射到经过标记化后的文本中的正确位置上,以便用于训练或评估模型。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def process_function(examples):
    tokenized_examples = tokenizer(examples["tokens"], max_length=128, truncation=True, is_split_into_words=True)
    labels = []
    for i, label in enumerate(examples["ner_tags"]):
        word_ids = tokenized_examples.word_ids(batch_index=i)
        label_ids = [-100 if word_id is None else label[word_id] for word_id in word_ids]
        labels.append(label_ids)
    tokenized_examples["labels"] = labels
    return tokenized_examples

这样数据就会变成我们想要的格式了:

4.创建模型

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
model = AutoModelForTokenClassification.from_pretrained("hfl/chinese-macbert-base", num_labels=len(label_list))

这里要制定我们的类别,使用list_labels来制定

5.创建评估函数

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
seqeval = evaluate.load("seqeval_metric.py")
seqeval

返回了很多用法

在写一个这次训练要用到的验证函数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import numpy as np
from seqeval.metrics import f1_score

def eval_metric(pred, label_list):
    predictions, labels = pred
    predictions = np.argmax(predictions, axis=-1)

    true_predictions = [
        [label_list[p] for p, l in zip(prediction, label) if l != -100]
        for prediction, label in zip(predictions, labels)
    ]

    true_labels = [
        [label_list[l] for p, l in zip(prediction, label) if l != -100]
        for prediction, label in zip(predictions, labels)
    ]

    return {"f1": f1_score(true_labels, true_predictions)}

6.配置训练参数

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
args = TrainingArguments(
    output_dir="models_for_ner",
    per_device_train_batch_size=32,
    per_device_eval_batch_size=64,
    evaluation_strategy="epoch",
    save_strategy="epoch",
    metric_for_best_model="f1",
    load_best_model_at_end=True,
    logging_steps=50,
    num_train_epochs=1
)

7.创建训练器

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
trainer = Trainer(
    model=model,
    args=args,
    train_dataset=tokenized_datasets["train"],
    eval_dataset=tokenized_datasets["validation"],
    compute_metrics=eval_metric,
    data_collator=DataCollatorForTokenClassification(tokenizer=tokenizer)
)

8.模型训练

由于时间原因只训练了一个epoch

9.使用验证集来测试模型

可以看到f1值很高,从侧面也能代表模型的准确率不低。

最后就是我们再来验证一下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from transformers import pipeline
model.config.id2label = {idx: label for idx, label in enumerate(label_list)}
ner_pipe = pipeline("token-classification", model=model, tokenizer=tokenizer, device=0, aggregation_strategy="simple")

res = ner_pipe("汤姆在北京读研究生")
res

可以看到模型准确的识别出了两个实体

可以再分割一下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 根据start和end取实际的结果
ner_result = {}
x = "汤姆在北京读研究生"
for r in res:
    if r["entity_group"] not in ner_result:
        ner_result[r["entity_group"]] = []
    ner_result[r["entity_group"]].append(x[r["start"]: r["end"]])

ner_result

可以看到person是汤姆,location是北京,说明我们的模型还是很不错的。

完,文章对您有用可以点个赞

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-02-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Tom的小院 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
浅谈ext4文件系统初始化
调试环境 $ modprobe -v ext4 $ dd if=/dev/zero of=/tmp/disk1 count=30 bs=1M $ losetup --show -f /tmp/disk1 /dev/loop0 $ mkfs.ext4 /dev/loop0 $ mount /tmp/disk1 /mnt/disk1 关于超级快基本知识 当使用者适应mkfs.ext4 /dev/sdb时候,系统按照ext4内部的布局规则写入写入先关数据。mount时候按照内置的布局规则读取这些信息
用户4700054
2022/08/17
1.6K0
浅谈ext4文件系统初始化
文件系统专栏 | 之ext4文件系统结构
上次讲了VFS层,这次说说文件系统层,文件系统层将不同的文件系统实现了VFS的这些函数,通过指针注册到VFS里面。所以,用户的操作通过VFS转到各种文件系统,linux用到最多的是ext4文件系统,我们就说这个吧。EXT4是第四代扩展文件系统(英语:Fourth extended filesystem,缩写为 ext4)是Linux系统下的日志文件系统,是ext2和ext3文件系统的后继版本。 ext4文件系统布局 一个Ext4文件系统被分成一系列块组。为减少磁盘碎片产生的性能瓶颈,块分配器尽量保持每个文件
刘盼
2022/08/29
3.6K0
文件系统专栏 | 之ext4文件系统结构
Linux ext4无法使用超过16T磁盘的解决办法
系统环境:Centos6.7 x86_64 己updte 磁盘:12*4T raid5 +hot 说明:操作系统与归档都使用同一个raid5 应用环境:邮局系统【文件大小从1K到100K不等,除附件】 一、查看分区 【fdisk -l】 [root@localhost sysadmin]# fdisk -l WARNING: GPT (GUID Partition Table) detected on '/dev/sda'! The util fdisk doesn't support GPT. Use G
小小科
2018/05/03
2.2K0
Linux文件/磁盘统计df与du命令输出结果不同的原因研究
标准GNU工具coreutils中有俩程序df / du,他们都可以查看磁盘的使用情况。通常情况下他们的统计结果并不会相同,这是因为统计信息来源的差异。所以问题来了:在ext4文件系统下,有哪些可能的因素会带来统计信息的差异?
Linux阅码场
2019/08/23
3.5K0
Linux文件/磁盘统计df与du命令输出结果不同的原因研究
ext3grep恢复ext3文件系统下误
df -h Filesystem Size Used Avail Use% Mounted on /dev/mapper/VolGroup00-LogVol00                        13G 4.7G 7.5G 39% / /dev/hda1 99M 18M 77M 19% /boot tmpfs 107M 0 107M 0% /dev/shm /home/store/file 49M 4.9M 42M 11% /mnt
py3study
2020/01/06
6100
Linux Ext系列文件系统(看这一篇就够了!)
硬盘是典型的"块"设备, 操作系统读取硬盘数据的时候, 其实是不会一个个扇区地读取, 这样效率太低, 而是一次性连续读取多个扇区, 即一次性取⼀个”块”(block)。
用户11317877
2025/02/17
1060
Linux Ext系列文件系统(看这一篇就够了!)
【linux学习指南】】Ext系列文件系统(三)ext2 文件系统的认识与构成
所有的准备⼯作都已经做完,是时候认识下⽂件系统了。我们想要在硬盘上储⽂件,必须先把硬盘格式化为某种格式的⽂件系统,才能存储⽂件。⽂件系统的⽬的就是组织和管理硬盘中的⽂件。在Linux 系统中,最常⻅的是ext2系列的⽂件系统。其早期版本为ext2,后来⼜发展出ext3和ext4。ext3 和ext4虽然对ext2进⾏了增强,但是其核⼼设计并没有发⽣变化,我们仍是以较⽼的ext2作为演⽰对象。
学习起来吧
2025/01/01
1210
【linux学习指南】】Ext系列文件系统(三)ext2 文件系统的认识与构成
Centos7笔记 | 硬盘、Parted 分区、mount命令、Swap分区的扩展、、文件系统详解、
硬盘设备是由大量的扇区组成,每个扇区容量512字节,第一扇区最为重要,保存主引导记录和分区表信息。分别是主引导记录占用446,分区表占用64字节,结束符2字节,其中分区表中每记录一个信息占用16字节,最多只有四个分区,为了解决分区数不够,衍生出扩展分区。扩展分区可以用来创建逻辑分区,逻辑分区最多128个。
网络技术联盟站
2019/08/21
4.7K0
Centos7笔记 | 硬盘、Parted 分区、mount命令、Swap分区的扩展、、文件系统详解、
磁盘文件系统三
VFS采用了面向对象的设计思路,将一系列概念抽象出来作为对象而存在,它们包含数据的同时也包含了操作这些数据的方法。当然,这些对象都只能用数据结构来表示,而不可能超出C语言的范畴,不过即使在C++里面数据结构和类的区别也仅仅在于类的成员默认私有,数据结构的成员默认公有。VFS主要有如下4个对象类型。
没有故事的陈师傅
2021/06/24
9090
磁盘文件系统三
聊聊ext4文件create和truncat实现
下面是ext4创建文件的实现,第一步是经由vfs层的vfs_create函数,最后进入实际文件系统的ext4_create来创建文件,文件的创建核心过程基本分为2步,第一步是新文件的inode申请,第二步是读取新文件的父目录的inode,在这个inode对应的数据块添加新文件的目录项,这个过程是采用事务的方式进行。
用户4700054
2022/08/17
1.3K0
聊聊ext4文件create和truncat实现
从青铜到王者系列:深入浅出理解DeepSeek 3FS (2)从内核到用户态文件系统的设计之路
从青铜到王者系列:深入浅出理解DeepSeek 3FS (2)从内核到用户态文件系统的设计之路
早起的鸟儿有虫吃
2025/04/11
1300
从青铜到王者系列:深入浅出理解DeepSeek 3FS (2)从内核到用户态文件系统的设计之路
磁盘文件系统二
但是,如果一个文件比较大,inode的块号不足以标识所有的数据块,就会使用间接块。文件系统会在硬盘上分配一个数据块,不存储文件数据,专门用来存储块号。该块被称为间接块。inode的长度是固定的。间接块占用的空间对于大文件来说是必要的。但是对于小文件不会带来额外的开销。当我们用到 i_block[12]的时候,就不能直接放数据块的位置了,要不然 i_block 很快就会用完了。这该怎么办呢?我们需要想个办法。我们可以让 i_block[12]指向间接块。也就是说,我们在 i_block[12]里面放间接块的位置,通过 i_block[12]找到间接块后,间接块里面放数据块的位置,通过间接块可以找到数据块。如果文件再大一些,i_block[13]会指向一个块,我们可以用二次间接块。二次间接块里面存放了间接块的位置,间接块里面存放了数据块的位置,数据块里面存放的是真正的数据。如果文件再大一些,i_block[14]会指向三次间接块。
没有故事的陈师傅
2021/06/24
1.1K0
磁盘文件系统二
干货!大话EXT4文件系统完整版
我们知道SSD是一场存储革命,设计和制造一个好的SSD固然重要,但如何正确使用以充分发挥SSD性能同样重要。SSD内在的并行性和先擦再写的特性决定了它不同于机械硬盘简单的LBA和存储块一一对应,要充分挖掘SSD的并行性,提升性能,延长寿命,缩短延迟,就必须在上层应用做出改动。很多SSD的使用大户都作出了这种尝试,从国外的Google,Microsoft,Facebook,到国内的Baidu,Alibaba等,本站就曾经介绍过百度的软件定义闪存,把对象存储和SSD内部结构统一起来使用。但对大部分企业来讲,这种结构还是太独特了,我们还是要关注通用的架构,首先来了解离硬盘最近的软件:文件系统。本系列文章将以Linux系统最常见的EXT4文件系统为例,从SSD爱好者的角度来揭开文件系统的庐山真面目。
Linux阅码场
2019/12/10
5.9K0
干货!大话EXT4文件系统完整版
ext2文件系统详解[接<磁盘与文件系统(简单)>]
在大文件系统下, 单一inode表将会变得非常臃肿, 难以管理, 因此 ext2采用多个区块群组(group block), 每个区块群组均具有其 superblock, inode, block
buiu
2021/10/27
8480
漫谈Linux标准的文件系统(Ext2/Ext3/Ext4)
全称Linux extended file system, extfs,即Linux扩展文件系统,Ext2就代表第二代文件扩展系统,Ext3/Ext4以此类推,它们都是Ext2的升级版,只不过为了快速恢复文件系统,减少一致性检查的时间,增加了日志功能,所以Ext2被称为索引式文件系统,而Ext3/Ext4被称为日志式文件系统。
justmine
2019/02/15
2.1K0
Linux下误删除后的恢复操作(ext3/ext4)
Linux是作为一个多用户、多任务的操作系统,文件一旦被删除是难以恢复的。尽管删除命令只是在文件节点中作删除标记,并不真正清除文件内容,但是其他用户和一些有写盘动作的进程会很快覆盖这些数据。在日常工程中,谁也说不准永远不犯错误,万一哪天不小心误操作删除了一些重要文件,该怎么办呢?? 莫慌!这里介绍一款神器extundelete,这是针对ext4文件格式下文件删除后的恢复工具,十分强大!! 废话不多说,下面开始介绍这款神器的使用: 1)下载并安装软件 extundelete主页:http://extundel
洗尽了浮华
2018/01/23
3.4K0
ext3文件系统反删除利器ext3gre
国外一份非常著名的Linux系统管理员守则中有这么一条“慎用 rm –rf 命令,除非你知道此命令将带来什么后果”,可见,这个命令对系统管理员的重要性。在实际的工作中,由此命令带来的误删除数据案例屡见不鲜,很多系统管理员都遇到过或者犯过这样的错误。由于开发人员对命令的不熟悉,或者粗心大意、疏于管理,执行了此命令,数据在一瞬间就被清空了。Linux不具备类似回收站的功能,这就意味着数据丢失。虽然Linux自身提供了恢复数据的机制,但是这个功能基本没用,要恢复数据,通过常规手段是无法完成的,此时,只有找专业的数据恢复公司来恢复数据,这样无疑要付出很大的成本和费用,造成无法估量的的损失。
py3study
2020/01/06
6890
dumpe2fs 命令的使用,转储 ext2/ext3/ext4 文件系统信息
使用man 命令可以查看 dumpe2fs 命令具体的使用的方法: NAME dumpe2fs - dump ext2/ext3/ext4 filesystem information SYNOPSIS dumpe2fs [ -bfghixV ] [ -o superblock=superblock ] [ -o blocksize=blocksize ] device DESCRIPTION dumpe2fs prints the super block an
西湖醋鱼
2020/12/30
9670
[操作系统] Ext系列文件系统
其实硬盘是典型的“块”设备,操作系统读取硬盘数据的时候,其实是不会⼀个个扇区地读取,这样效率太低,⽽是⼀次性连续读取多个扇区,即⼀次性读取⼀个块(block)。
DevKevin
2025/02/23
870
[操作系统] Ext系列文件系统
【Linux篇】深入理解文件系统:从基础概念到 ext2 文件系统的应用与解析
打开的文件被内存管理着,实际是进程通过相关数据结构将每个对象进行关联;而未被打开的文件被保存在磁盘上,一般是未被打开的文件占据最多。
熬夜学编程的小王
2025/04/14
2410
【Linux篇】深入理解文件系统:从基础概念到 ext2 文件系统的应用与解析
推荐阅读
相关推荐
浅谈ext4文件系统初始化
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验