seqeval详解

部署运行你感兴趣的模型镜像

简介

seqeval 是一个用于评估序列标注任务(如命名实体识别 NER)的 Python 库。它提供了一种方便的方式来计算各种评价指标,如准确率(Precision)、召回率(Recall)、F1 分数等。seqeval 支持多种标签格式,并且可以处理多标签的情况。

其他知识点补充
  • IOB1
  • IOB2
  • IOE1
  • IOE2
  • IOBES
  • BILOU

以上几个是字体的标注格式,主要是给机器使用的,便于机器识别,这是一种规范。

IOB2:
  • I表示实体内部,O表示实体外部,B表示实体开始
  • B/I-XXX,XXX表示具体的类别
IOBES
  • I表示实体内部,O表示实体外部,B表示实体开始,E表示实体结束,S表示一个词单独形成一个命名实体
  • 有时也会使用M代替I,但本质是同一含义
    例子:
标记说明
B-Person人名开始
I-Person人名中间
B-Organization组织名开始
I-Organization组织名中间
O非命名实体

安装 seqeval

首先,您需要安装 seqeval 库。可以通过 pip 命令轻松安装:

pip install seqeval

基本用法

1. 导入库
from seqeval.metrics import precision_score, recall_score, f1_score, classification_report
2. 准备数据

假设您有两个列表,一个包含真实标签(ground truth),另一个包含模型预测的标签。

true_labels = [
    ['O', 'O', 'O', 'B-MISC', 'I-MISC', 'I-MISC', 'O'],
    ['B-PER', 'I-PER', 'O']
]

pred_labels = [
    ['O', 'O', 'B-MISC', 'I-MISC', 'I-MISC', 'I-MISC', 'O'],
    ['B-PER', 'I-PER', 'O']
]
3. 计算评价指标

精确率(Precision)

accuracy = accuracy_score(true_labels, pred_labels)
print(f'accuracy: {accuracy:.2f}')
precision = precision_score(true_labels, pred_labels)
print(f'Precision: {precision:.2f}')

召回率(Recall)

recall = recall_score(true_labels, pred_labels)
print(f'Recall: {recall:.2f}')

计算 F1 分数,也称为平衡 F 分数或 F 测量值。

f1 = f1_score(true_labels, pred_labels)
print(f'F1 Score: {f1:.2f}')

分类报告
classification_report 提供了更详细的报告,包括每个类别的精确率、召回率和 F1 分数。

report = classification_report(true_labels, pred_labels)
print(report)

输出示例
假设您运行了上述代码,输出可能如下所示:

Precision: 0.80
Recall: 0.80
F1 Score: 0.80
             precision    recall  f1-score   support

        B-MISC       1.00      1.00      1.00         1
        I-MISC       0.75      1.00      0.86         3
        B-PER       1.00      1.00      1.00         1
        I-PER       1.00      1.00      1.00         1
           O       1.00      1.00      1.00         3

    micro avg       0.80      0.80      0.80        10
    macro avg       0.95      1.00      0.95        10
 weighted avg       0.90      1.00      0.94        10

处理多标签情况
seqeval 也支持多标签的情况。假设每个 token 可以有多个标签:

true_labels = [
    ['O', 'O', 'O', ('B-MISC', 'B-PER'), 'I-MISC', 'I-MISC', 'O'],
    ['B-PER', 'I-PER', 'O']
]

pred_labels = [
    ['O', 'O', 'B-MISC', ('I-MISC', 'B-PER'), 'I-MISC', 'I-MISC', 'O'],
    ['B-PER', 'I-PER', 'O']
]

report = classification_report(true_labels, pred_labels)
print(report)

自定义标签格式
seqeval 默认使用 BIO 标签格式(B- 表示开始,I- 表示内部,O 表示非实体)。如果您使用的是其他标签格式,可以通过 suffix 参数进行配置。

from seqeval.scheme import IOB2

true_labels = [
    ['O', 'O', 'O', 'MISC', 'MISC', 'MISC', 'O'],
    ['PER', 'PER', 'O']
]

pred_labels = [
    ['O', 'O', 'MISC', 'MISC', 'MISC', 'MISC', 'O'],
    ['PER', 'PER', 'O']
]

report = classification_report(true_labels, pred_labels, scheme=IOB2)
print(report)

其他功能
seqeval 还提供了一些其他功能,例如:

  • accuracy_score:计算准确率。
  • performance_measure:返回一个字典,包含 TP(真阳性)、FP(假阳性)、FN(假阴性)和 TN(真阴性)的数量。

算法讲解

上面介绍了使用api获取准确率等数据,那么它算法是怎么实现的了

算法介绍:
  • 准确率: accuracy = 预测对的元素个数/总的元素个数
  • 查准率:precision = 预测正确的实体个数 / 预测的实体总个数
  • 召回率:recall = 预测正确的实体个数 / 标注的实体总个数
  • F1值:F1 = 2 *准确率 * 召回率 / (准确率 + 召回率)

预测对的元素个数、总的元素个数、预测正确的实体个数、预测的实体总个数,这些数值是如何获取的了
例子:

y_true = [‘O’, ‘O’, ‘O’, ‘B-MISC’, ‘I-MISC’, ‘I-MISC’, ‘O’, ‘B-PER’, ‘I-PER’] 真实结果
y_pred = [‘O’, ‘O’, ‘B-MISC’, ‘I-MISC’, ‘B-MISC’, ‘I-MISC’, ‘O’, ‘B-PER’, ‘I-PER’] 预测结果

y_true和y_pred列表中都是有9个元素,其中预测对的元素个数为6个,那么准确率为2/3。标注的实体总个数为2个(MISC,PER),预测的实体总个数为3个(‘I-MISC’, ‘B-PER’, ‘I-PER),预测正确的实体个数为1个(‘B-PER’, ‘I-PER),那么precision=1/3, recall=1/2, F1=0.4。

总结
seqeval 是一个非常实用的库,特别适合评估序列标注任务的性能。通过简单的 API,您可以轻松计算各种评价指标,并生成详细的分类报告。希望这些信息对您有所帮助!如果有任何具体问题或需要进一步的帮助,请随时提问。

您可能感兴趣的与本文相关的镜像

Python3.10

Python3.10

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

<think>好的,我现在需要帮用户介绍如何使用BERT和Trainer进行NER微调。首先,我得回忆一下NER(命名实体识别)的基本概念,以及BERT在其中的应用。NER属于序列标注任务,通常需要为每个token分配标签,比如人名、地名等。BERT作为预训练模型,通过微调可以在特定数据集上适应这类任务。 接下来要考虑的是用户可能的背景。他们可能已经对BERT和深度学习有一定了解,但需要具体的操作步骤。用户提到了使用Trainer,可能指的是Hugging Face的Transformers库中的Trainer类,这样可以简化训练过程,不需要手动写训练循环。 首先,我应该介绍需要的工具和库,比如Transformers、Datasets、以及可能的评估指标如seqeval。然后,数据预处理部分,需要将数据转换成BERT接受的格式,比如添加特殊标记、分词、对齐标签等。这里需要注意BERT的分词器可能会将单词分成子词,因此标签也需要相应调整,比如使用“B-PER”、“I-PER”等,并在分词后对标签进行扩展。 然后是模型加载,用户需要从预训练的BERT模型基础上添加一个分类层,用于预测每个token的实体标签。这里要提到AutoModelForTokenClassification类,并说明如何设置标签数量。 接下来是训练参数设置,比如学习率、批次大小、训练轮数等。使用Trainer类时,需要定义TrainingArguments,并传入模型、数据集、评估函数等。可能需要自定义数据整理函数,因为不同样本的长度可能不同,需要动态填充。 评估部分,用户可能希望了解如何计算精确率、召回率、F1值,这里可以引入compute_metrics函数,使用seqeval库来处理评估,因为传统的accuracy可能不太适合NER任务,需要考虑实体级别的匹配。 最后是训练和保存模型,以及可能的推理示例,展示如何使用微调后的模型进行预测。 需要提醒用户注意的地方包括标签与分词的对齐,评估指标的选择,以及超参数的调整。可能还需要提到使用GPU加速训练,以及处理数据时的常见问题,比如标签溢出或长度限制。 现在检查是否有遗漏的步骤:数据加载、预处理、模型设置、训练配置、评估、保存和推理示例。可能用户还需要知道如何准备自己的数据集,比如CoNLL-2003的格式,或者如何处理自定义数据。此外,可能需要解释为什么选择BERT而不是其他模型,比如其双向上下文理解能力适合NER任务。 需要确保代码示例正确,比如Tokenizer的使用,标签扩展的方式,以及处理数据时的注意事项。例如,当分词后产生多个子词,只有第一个子词保留原标签,其余可能标记为-100,以便在计算损失时被忽略。 总结起来,回答的结构应该是步骤化的,先介绍必要概念,然后逐步展开代码实现,强调关键点,并提供示例代码和解释。同时,要指出常见陷阱和解决方法,帮助用户顺利微调模型。</think>以下是使用BERT和Hugging Face的`Trainer`类进行命名实体识别(NER)微调的步骤详解: --- ### **1. 环境准备** 安装必要的库: ```bash pip install transformers datasets seqeval torch ``` --- ### **2. 数据准备** #### **数据格式** - 数据应为 `token` 和 `label` 的序列,格式如下: ```python {"tokens": ["John", "lives", "in", "New", "York"], "labels": [1, 0, 0, 2, 2]} # 1=B-PER, 2=B-LOC ``` - 常用数据集(如CoNLL-2003)可通过`datasets`库直接加载: ```python from datasets import load_dataset dataset = load_dataset("conll2003") ``` --- ### **3. 数据预处理** #### **关键步骤:** 1. **分词与标签对齐** BERT的分词器会将单词拆分为子词(如"York"→["York"]),需扩展标签使其与子词对齐: ```python from transformers import AutoTokenizer tokenizer = AutoTokenizer.from_pretrained("bert-base-cased") def tokenize_and_align_labels(examples): tokenized_inputs = tokenizer(examples["tokens"], truncation=True, is_split_into_words=True) labels = [] for i, label in enumerate(examples["ner_tags"]): word_ids = tokenized_inputs.word_ids(batch_index=i) previous_word_idx = None label_ids = [] for word_idx in word_ids: if word_idx is None: # 特殊标记([CLS], [SEP]) label_ids.append(-100) elif word_idx != previous_word_idx: # 新单词的第一个子词 label_ids.append(label[word_idx]) else: # 同一单词的后续子词 label_ids.append(-100) # 忽略损失计算 previous_word_idx = word_idx labels.append(label_ids) tokenized_inputs["labels"] = labels return tokenized_inputs tokenized_dataset = dataset.map(tokenize_and_align_labels, batched=True) ``` 2. **数据格式转换** 使用`DataCollatorForTokenClassification`动态填充批次: ```python from transformers import DataCollatorForTokenClassification data_collator = DataCollatorForTokenClassification(tokenizer) ``` --- ### **4. 模型加载** 加载预训练BERT并添加分类头: ```python from transformers import AutoModelForTokenClassification model = AutoModelForTokenClassification.from_pretrained( "bert-base-cased", num_labels=len(label_list), # 标签类别数(如B-PER, I-PER, O等) id2label={i: label for i, label in enumerate(label_list)}, label2id={label: i for i, label in enumerate(label_list)} ) ``` --- ### **5. 训练配置** #### **定义训练参数** ```python from transformers import TrainingArguments training_args = TrainingArguments( output_dir="./results", evaluation_strategy="epoch", learning_rate=2e-5, per_device_train_batch_size=16, per_device_eval_batch_size=16, num_train_epochs=3, weight_decay=0.01, logging_dir="./logs", ) ``` #### **评估指标** 使用`seqeval`计算实体级别的F1: ```python import numpy as np from datasets import load_metric metric = load_metric("seqeval") def compute_metrics(p): predictions, labels = p.predictions, p.label_ids predictions = np.argmax(predictions, axis=2) true_labels = [[label_list[l] for l in label if l != -100] for label in labels] true_predictions = [ [label_list[p] for (p, l) in zip(prediction, label) if l != -100] for prediction, label in zip(predictions, labels) ] results = metric.compute(predictions=true_predictions, references=true_labels) return { "precision": results["overall_precision"], "recall": results["overall_recall"], "f1": results["overall_f1"], } ``` --- ### **6. 训练模型** 使用`Trainer`启动训练: ```python from transformers import Trainer trainer = Trainer( model=model, args=training_args, train_dataset=tokenized_dataset["train"], eval_dataset=tokenized_dataset["validation"], data_collator=data_collator, compute_metrics=compute_metrics, tokenizer=tokenizer, ) trainer.train() ``` --- ### **7. 模型保存与推理** #### **保存模型** ```python model.save_pretrained("./ner_model") tokenizer.save_pretrained("./ner_model") ``` #### **推理示例** ```python from transformers import pipeline ner_pipeline = pipeline("ner", model=model, tokenizer=tokenizer) text = "John lives in New York." results = ner_pipeline(text) print(results) # 输出示例:[{"entity": "B-PER", "word": "John"}, {"entity": "B-LOC", "word": "New York"}] ``` --- ### **关键注意事项** 1. **标签对齐**:确保子词的标签正确扩展,避免标签错位。 2. **评估指标**:NER注重实体完整性,需使用`seqeval`而非简单准确率。 3. **超参数调优**:可调整学习率、批次大小等提升效果。 4. **GPU加速**:使用`device="cuda"`加速训练。 通过以上步骤,可快速微调BERT模型适应特定领域的NER任务。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值