命名实体识别实践
学习目标
通过本课程,你将深入了解到spaCy库中的命名实体识别(NER)功能,包括如何自定义实体类型、训练模型以识别新的实体类型,以及如何评估模型的性能。通过本课程的学习,你将能够构建自己的命名实体识别模型,并应用于实际项目中。
相关知识点
- 命名实体识别
学习内容
1 命名实体识别
1.1 背景介绍
spaCy是一个用于处理和理解大量文本数据的工业级自然语言处理(NLP)库。它提供了多种预训练模型,支持多种语言,包括英语、德语、西班牙语等。spaCy的设计理念是高效、易用,同时保持高度的灵活性,使得开发者可以轻松地构建复杂的NLP应用。
在spaCy中,命名实体识别(NER)是通过nlp对象中的ner组件来实现的。这个组件可以识别文本中的实体,并将它们分类为预定义的类型,如人名(PERSON)、组织名(ORG)、地点(LOC)等。spaCy的NER模型是基于深度学习的,能够提供高精度的实体识别。
1.2 安装依赖
在开始之前,确保你的环境中已经安装了spaCy。可以通过以下命令安装:
!wget https://model-community-picture.obs.cn-north-4.myhuaweicloud.com/ascend-zone/notebook_datasets/2ccfb5f0309f11f0b66ffa163edcddae/en_core_web_sm-3.7.1.tar.gz --no-check-certificate
%pip install wheel==0.44.0
%pip install en_core_web_sm-3.7.1.tar.gz
1.3 加载预训练模型
spaCy提供了多种预训练模型,这些模型已经训练好了,可以直接用于实体识别。例如,加载英文的预训练模型可以使用以下代码:
import spacy
# 加载英文预训练模型
nlp = spacy.load("en_core_web_sm")
# 处理文本
text = "Apple is looking at buying U.K. startup for $1 billion"
doc = nlp(text)
# 打印识别的实体
for ent in doc.ents:
print(ent.text, ent.label_)
1.4 自定义命名实体类型与模型训练
虽然spaCy的预训练模型已经能够识别许多常见的实体类型,但在实际应用中,可能需要识别一些特定的实体类型,这些类型在预训练模型中并不存在。这时,需要自定义实体类型,并训练模型以识别这些新的实体类型。
- 创建训练数据
自定义实体类型的第一步是创建训练数据。训练数据通常是一个包含文本和实体标注的列表。每个实体标注包括实体的文本、起始位置和结束位置,以及实体类型。
# 创建训练数据
training_data = [
("Hugging Face is a company based in New York City", {"entities": [(0, 12, "ORG"), (35, 48, "LOC")]}),
("I love visiting the Tower in Paris", {"entities": [(20, 25, "LOC"), (29, 34, "LOC")]}),
("Bill Gates founded Microsoft in 1975", {"entities": [(0, 10, "PERSON"), (19, 28, "ORG")]}),
]
- 添加新的实体类型
在训练模型之前,需要确保新的实体类型已经被添加到模型的实体识别器中。
ORG:表示各种组织机构。LOC:表示地理位置。PERSON:表示人物。
可以通过以下代码实现:
# 加载预训练模型
nlp = spacy.load("en_core_web_sm")
# 获取实体识别器
ner = nlp.get_pipe("ner")
# 添加新的实体类型
ner.add_label("ORG")
ner.add_label("LOC")
ner.add_label("PERSON")
- 训练模型
训练模型的过程涉及多次迭代,每次迭代都会更新模型的参数,以提高其识别新实体类型的能力。以下是一个简单的训练循环示例:
from spacy.util import minibatch, compounding
from spacy.training import Example
import random
# 训练模型
n_iter = 10 # 迭代次数
for itn in range(n_iter):
random.shuffle(training_data)
batches = minibatch(training_data, size=compounding(4.0, 32.0, 1.001))
for batch in batches:
# 将(text, annotation)元组转换为Example对象
examples = []
for text, annotation in batch:
doc = nlp.make_doc(text)
example = Example.from_dict(doc, annotation)
examples.append(example)
# 使用Example对象更新模型
nlp.update(examples)
1.5 模型评估
训练模型后,需要评估其性能,以确保它能够准确地识别新的实体类型。评估通常包括计算精确度、召回率和F1分数等指标。
- 评估模型
评估模型的性能可以通过以下步骤实现:
- 准备测试数据:创建一个包含已标注实体的测试数据集。
- 预测实体:使用训练好的模型对测试数据进行预测。
- 计算指标:计算精确度、召回率和F1分数。
# 准备测试数据
test_data = [
("Hugging Face is a company based in New York City", {"entities": [(0, 12, "ORG"), (35, 48, "LOC")]}),
("I love visiting the Tower in Paris", {"entities": [(20, 25, "LOC"), (29, 34, "LOC")]}),
("Bill Gates founded Microsoft in 1975", {"entities": [(0, 10, "PERSON"), (19, 28, "ORG")]}),
]
# 预测实体
def predict_entities(text, nlp):
doc = nlp(text)
return [(ent.start_char,ent.end_char) for ent in doc.ents]
# 计算指标
from sklearn.metrics import precision_score, recall_score, f1_score
def evaluate_model(test_data, nlp):
true_entities = []
pred_entities = []
for text, annotations in test_data:
true_entities.extend([(ent[0], ent[1]) for ent in annotations["entities"]])
pred_entities.extend(predict_entities(text, nlp))
true_labels = [ent[1] for ent in true_entities]
pred_labels = [ent[1] for ent in pred_entities]
precision = precision_score(true_labels, pred_labels, average="weighted")
recall = recall_score(true_labels, pred_labels, average="weighted")
f1 = f1_score(true_labels, pred_labels, average="weighted")
return precision, recall, f1
# 评估模型
precision, recall, f1 = evaluate_model(test_data, nlp)
print(f"Precision: {precision:.2f}")
print(f"Recall: {recall:.2f}")
print(f"F1 Score: {f1:.2f}")
Precision: 1.00
Recall: 1.00
F1 Score: 1.00
1000

被折叠的 条评论
为什么被折叠?



