P with Spacy:自定义文本分类管道

2023-12-16 12:20

本文主要是介绍P with Spacy:自定义文本分类管道,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、说明

        Spacy 是一个功能强大的 NLP 库,其中许多 NLP 任务(如标记化、词干提取、词性标记和命名实体解析)均通过预训练模型提供开箱即用的功能。所有这些任务都由管道对象以及逐步应用于给定文本的不同函数的内部抽象来包装。该管道可以通过自编写的函数进行定制和扩展。

        在本文中,您将了解如何将文本分类添加到 Spacy 管道。给定带有文档和标签的训练数据,额外的分类任务可以学习预测其他文档的标签。您将了解如何构建训练数据、如何使用分类步骤扩展默认管道,以及如何添加您自己的分类实现。

        本文的技术背景是Python v3.11 和spacy v3.7.2。所有示例也应该适用于较新的库版本。

        本文最初出现在我的博客admantium.com。

二、自定义 Spacy 管道示例

注意:以下所有解释和代码片段均来自三个来源:官方 Rasa API 文档、关于 使用 Spacy 3.0 进行文本分类的博客文章,以及一篇关于构建生产级 Spacy 文本分类的博客文章。

添加文本分类任务可归结为以下步骤:

  1. 准备训练数据
  2. 将训练数据转换为 Spacy DocBin 对象
  3. 创建默认文本分类配置
  4. 训练模型
  5. 使用模型

以下部分详细介绍了这些步骤。

三、步骤一:准备训练数据

        训练数据需要是原始文本及其单标签或多标签类别。让我们通过使用 NLTK 库中包含的路透社新闻数据集来实现这一点。

以下代码片段显示了如何加载数据集,然后打印文本及其类别。


from nltk.corpus import reutersprint(len(reuters.fileids()))
# 10788print(reuters.raw(reuters.fileids()[42]))
# JAPAN GIVEN LITTLE HOPE OF AVOIDING U.S. SANCTIONS
#  A top U.S. Official said Japan has little
#  chance of persuading the U.S. to drop threatened trade
#  sanctions, despite the efforts of a Japanese team that left for
#  Washington today.print(reuters.categories(reuters.fileids()[42]))
# ['trade']

该数据集共有 90 个类别。此外,有些文章有多个标签。

print(len(reuters.categories()))
# 90print(reuters.categories())
# ['acq', 'alum', 'barley', 'bop', 'carcass', 'castor-oil', 'cocoa', 'coconut', 'coconut-oil', 'coffee', 'copper', 'copra-cake', 'corn', 'cotton', 'cotton-oil', 'cpi', 'cpu', 'crude', 'dfl', 'dlr', 'dmk', 'earn', 'fuel', 'gas', 'gnp', 'gold', 'grain', 'groundnut', 'groundnut-oil', 'heat', 'hog', 'housing', 'income', 'instal-debt', 'interest', 'ipi', 'iron-steel', 'jet', 'jobs', 'l-cattle', 'lead', 'lei', 'lin-oil', 'livestock', 'lumber', 'meal-feed', 'money-fx', 'money-supply', 'naphtha', 'nat-gas', 'nickel', 'nkr', 'nzdlr', 'oat', 'oilseed', 'orange', 'palladium', 'palm-oil', 'palmkernel', 'pet-chem', 'platinum', 'potato', 'propane', 'rand', 'rape-oil', 'rapeseed', 'reserves', 'retail', 'rice', 'rubber', 'rye', 'ship', 'silver', 'sorghum', 'soy-meal', 'soy-oil', 'soybean', 'strategic-metal', 'sugar', 'sun-meal', 'sun-oil', 'sunseed', 'tea', 'tin', 'trade', 'veg-oil', 'wheat', 'wpi', 'yen', 'zinc']

四、步骤 2:将训练数据转换为 Spacy DocBin 对象

        Spacy 要求其输入数据集使用附加的 属性来预处理 Doc 对象。类别应该是一个 对象,其中键是类别,值反映该类别是否适用于文章。这是一个整数值。catsdict

以下是如何转换路透社新闻数据集第一篇文章的示例:

nlp = spacy.load('en_core_web_lg')fileid = reuters.fileids()[42]
cat_dict = {cat: 0 for cat in reuters.categories()}doc1 = nlp.make_doc(reuters.raw(fileid))
for cat in reuters.categories(fileid):cat_dict[cat] = 1doc1.cats = cat_dictprint(doc1.cats)
# {'acq': 0, 'alum': 0, 'barley': 0, 'bop': 0, ..., 'trade': 1, ...}

此外,数据需要转换为Spacy自定义数据对象DocBin。预计数据需要分为训练和测试,以下方法创建多标签分类,其中 doc 对象处理每篇文章的原始文本,并包含 dict 所有适用类别的对象。

    
def convert_multi_label(dataset, filename):db = DocBin()nlp = spacy.load('en_core_web_lg')total = len(dataset)print(f'{time()}: start processing {filename} with {total} files')for index, fileid in enumerate(dataset):print(f'Processing {index+1}/{total}')cat_dict = {cat: 0 for cat in reuters.categories()}for cat in reuters.categories(fileid):cat_dict[cat] = 1doc = nlp(get_text(fileid))doc.cats = cat_dictdb.add(doc)print(f'{time()}: finish processing {filename}')db.to_disk(filename)#convert(training, 'reuters_training.spacy')convert_multi_label(training, 'reuters_training_multi_label.spacy')
# 1688400699.331844: start processing reuters_training_single_label.spacy with 7769 files
# Processing 1/7769
# Processing 2/7769
# ...

二进制文件的预览:

五、步骤 3:创建默认文本分类配置

Spacy 提供了一个方便的命令行界面来创建用于多种目的的默认配置文件。从 spacy init config 开始,可以添加额外的 pipeline 步骤。对于分类,两个可能的值是 textcat(针对单标签)和 textcat_multilabel(针对多标签分类)。此外,通过包含选项 --optimize accuracy,训练过程将使用预训练模型中的词向量来表示文本。

这些考虑因素导致以下命令:

> python -m spacy init config --pipeline textcat_multilabel --optimize accuracy spacy_categorization_pipeline.cfg2023-07-02 13:26:37.103543: I tensorflow/core/platform/cpu_feature_guard.cc:182] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations.
To enable the following instructions: AVX2 FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags.
ℹ Generated config template specific for your use case
- Language: en
- Pipeline: textcat
- Optimize for: efficiency
- Hardware: CPU
- Transformer: None
✔ Auto-filled config with all values
✔ Saved config
spacy_categorization_pipeline.cfg
You can now add your data and train your pipeline:
python -m spacy train spacy_categorization_pipeline.cfg --paths.train ./train.spacy --paths.dev ./dev.spacy

让我们看一下这个文件的某些部分:

[paths]
train = null
dev = null
vectors = "en_core_web_lg"
init_tok2vec = null#...
[nlp]
lang = "en"
pipeline = ["tok2vec","textcat_multilabel"]
batch_size = 1000
disabled = []
before_creation = null
after_creation = null
after_pipeline_creation = null
tokenizer = {"@tokenizers":"spacy.Tokenizer.v1"}[components]
[components.textcat_multilabel]
factory = "textcat_multilabel"
scorer = {"@scorers":"spacy.textcat_multilabel_scorer.v2"}
threshold = 0.5
[components.textcat_multilabel.model]
@architectures = "spacy.TextCatEnsemble.v2"
nO = null
[components.textcat_multilabel.model.tok2vec]
@architectures = "spacy.Tok2VecListener.v1"
width = ${components.tok2vec.model.encode.width}
upstream = "*"
[components.tok2vec]
factory = "tok2vec"
[components.tok2vec.model]
@architectures = "spacy.Tok2Vec.v2"
#...[training]
dev_corpus = "corpora.dev"
train_corpus = "corpora.train"
seed = ${system.seed}
gpu_allocator = ${system.gpu_allocator}
dropout = 0.1
accumulate_gradient = 1
patience = 1600
max_epochs = 0
max_steps = 20000
eval_frequency = 200
frozen_components = []
annotating_components = []
before_to_disk = null
before_update = null
#...[training.logger]
@loggers = "spacy.ConsoleLogger.v1"
progress_bar = false
[training.optimizer]
@optimizers = "Adam.v1"
beta1 = 0.9
beta2 = 0.999
L2_is_weight_decay = true
L2 = 0.01
grad_clip = 1.0
use_averages = false
eps = 0.00000001
learn_rate = 0.001

此配置公开了所有与训练相关的参数,从包含训练和测试数据的输入文件、使用的语料库、数据的记录和批量分离以及具有优化器和学习率的训练算法开始。对所有选项的详细讨论超出了本文的范围 - 目前,所有默认值均保持原样。

六、第 4 步:训练模型

首先,需要将数据分为训练数据集和测试数据集。方便的是,路透社的文章已经预先分割。以下代码片段划分数据并显示训练数据中的示例文章及其类别。

training = [doc for doc in reuters.fileids() if doc.find('training') == 0]
testing = [doc for doc in reuters.fileids() if doc.find('test') == 0]print(len(training))
# 7769print(len(testing))
# 3019

训练过程再次通过命令行启动。需要传递配置文件的名称、训练和测试数据集文件名以及输出目录。这是一个例子:

run python -m spacy train spacy_multi_label_categorization_pipeline.cfg \
--paths.train reuters_training_multi_label.spacy \
--paths.dev reuters_testing_multi_label.spacy \
--output textcat_multilabel_model

输出日志显示进度...

=========================== Initializing pipeline ===========================
[2023-07-03 18:24:10,639] [INFO] Set up nlp object from config
[2023-07-03 18:24:10,656] [INFO] Pipeline: ['tok2vec', 'textcat_multilabel']
[2023-07-03 18:24:10,660] [INFO] Created vocabulary
[2023-07-03 18:24:12,365] [INFO] Added vectors: en_core_web_lg
[2023-07-03 18:24:12,365] [INFO] Finished initializing nlp object
[2023-07-03 18:24:31,806] [INFO] Initialized pipeline components: ['tok2vec', 'textcat_multilabel']
✔ Initialized pipeline============================= Training pipeline =============================
ℹ Pipeline: ['tok2vec', 'textcat_multilabel']
ℹ Initial learn rate: 0.001
# ...
✔ Saved pipeline to output directory
textcat_multilabel_model/model-last

…以及一个显示训练过程和几个指标的表格。

E    #       LOSS TOK2VEC  LOSS TEXTC...  CATS_SCORE  SCORE
---  ------  ------------  -------------  ----------  ------0       0          2.51           0.39       48.98    0.490     200         24.56           5.04       39.44    0.390     400          0.00           2.86       39.94    0.400     600          0.01           3.87       40.27    0.400     800          1.02           3.39       46.44    0.460    1000          0.00           3.60       46.68    0.470    1200          0.00           3.69       45.55    0.460    1400          0.00           3.79       45.18    0.450    1600          0.00           3.80       45.04    0.45

该表包含以下信息:

  • E:训练运行的纪元数
  • #:训练步数
  • LOSS TOK2VEC:用于向量化输入数据的松散函数
  • LOSS TEXTCAT 和 SCORE:分类的损失函数及其归一化值。

七、第 5 步:使用模型

        在训练过程中,创建的模型存储在给定的文件夹名称中。 Spacy 保留了最新且最好的模型,即 F1 分数最高的模型。要使用这些模型,您可以直接使用 Spacy 加载它们,然后处理任何文本并导出计算的类别。

以下是与上面使用的同一文章的示例:

import spacynlp = spacy.load('textcat_multilabel_model/model-best')
fileid = reuters.fileids()[1024]
text = reuters.raw(fileid)
doc = nlp(text)print(doc.cats)
# {'acq': 0.9506559371948242, 'alum': 0.3440687954425812, 'barley': 0.044086653739213943, #...

doc.cats 属性是一个 Dictionary 对象,其中包含概率的键值映射,其中最可能的类别是估计的标签。

让我们比较一下使用单标签模型的一些文章的预期标签和估计标签:

import spacynlp = spacy.load('textcat_singlelabel_model/model-best')def compare_labels(fileid):text = reuters.raw(fileid)expected_cat =  reuters.categories(fileid)doc = nlp(text)estimated_cats = sorted(doc.cats.items(), key=lambda i:float(i[1]), reverse=True)estimated_cat = estimated_cats[0]print(f'fileid {fileid} :: expected = {expected_cat} // estimated = {estimated_cat}')compare_labels(training[1024])
# fileid training/1158 :: expected = ['ipi'] // estimated = ('cpi', 0.39067542552948)compare_labels(training[2678])
# fileid training/2080 :: expected = ['acq'] // estimated = ('acq', 0.9778384566307068)compare_labels(testing[1024])
# fileid test/16630 :: expected = ['orange'] // estimated = ('orange', 0.40097832679748535)compare_labels(testing[2678])
# fileid test/20972 :: expected = ['earn'] // estimated = ('earn', 0.9994577765464783)

正如您所看到的,在三种情况下,估计的类别是匹配的。

八、比较多标签和单标签分类训练

为了让您对训练过程有一个印象,让我们比较一下多标签和单标签分类过程。

8.1 多标签分类

对 7769 个条目的完整训练集进行基线多标签分类大约需要 30 分钟。

这是日志输出:

=========================== Initializing pipeline ===========================
[2023-07-03 18:24:10,639] [INFO] Set up nlp object from config
[2023-07-03 18:24:10,656] [INFO] Pipeline: ['tok2vec', 'textcat_multilabel']
[2023-07-03 18:24:10,660] [INFO] Created vocabulary
[2023-07-03 18:24:12,365] [INFO] Added vectors: en_core_web_lg
[2023-07-03 18:24:12,365] [INFO] Finished initializing nlp object
[2023-07-03 18:24:31,806] [INFO] Initialized pipeline components: ['tok2vec', 'textcat_multilabel']
✔ Initialized pipeline============================= Training pipeline =============================
ℹ Pipeline: ['tok2vec', 'textcat_multilabel']
ℹ Initial learn rate: 0.001
E    #       LOSS TOK2VEC  LOSS TEXTC...  CATS_SCORE  SCORE
---  ------  ------------  -------------  ----------  ------0       0          2.51           0.39       48.98    0.490     200         24.56           5.04       39.44    0.390     400          0.00           2.86       39.94    0.400     600          0.01           3.87       40.27    0.400     800          1.02           3.39       46.44    0.460    1000          0.00           3.60       46.68    0.470    1200          0.00           3.69       45.55    0.460    1400          0.00           3.79       45.18    0.450    1600          0.00           3.80       45.04    0.45
✔ Saved pipeline to output directory
textcat_multilabel_model/model-last

8.2 单标签分类

7769 个条目的完整训练集的基线单标签分类需要超过 3 小时 30 分钟。两个训练步骤本身都比较慢,并且训练会持续几个 epoch,因为 F1 分数增加非常缓慢。

要使用单一类别标签,我们首先需要更改提供训练和测试数据的方法。在与文章相关的所有类别中,仅使用第一个:

def convert_single_label(dataset, filename):db = DocBin()# ...for index, fileid in enumerate(dataset):cat_dict = {cat: 0 for cat in reuters.categories()}cat_dict[reuters.categories(fileid).pop()] = 1# ...

对于训练运行,使用特殊的单标签配置文件。

python -m spacy train spacy_single_label_categorization_pipeline.cfg \--paths.train reuters_training_single_label.spacy \--paths.dev reuters_testing_single_label.spacy \--output textcat_singlelabel_model

以下是训练结果:

To enable the following instructions: AVX2 FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags.
✔ Created output directory: textcat_singlelabel_model
ℹ Saving to output directory: textcat_singlelabel_model
ℹ Using CPU=========================== Initializing pipeline ===========================
[2023-07-04 16:38:34,515] [INFO] Set up nlp object from config
[2023-07-04 16:38:34,529] [INFO] Pipeline: ['tok2vec', 'textcat']
[2023-07-04 16:38:34,532] [INFO] Created vocabulary
[2023-07-04 16:38:37,277] [INFO] Added vectors: en_core_web_lg
[2023-07-04 16:38:37,278] [INFO] Finished initializing nlp object
[2023-07-04 16:39:02,505] [INFO] Initialized pipeline components: ['tok2vec', 'textcat']
✔ Initialized pipeline
============================= Training pipeline =============================
ℹ Pipeline: ['tok2vec', 'textcat']
ℹ Initial learn rate: 0.001
E    #       LOSS TOK2VEC  LOSS TEXTCAT  CATS_SCORE  SCORE
---  ------  ------------  ------------  ----------  ------0       0          0.00          0.01        0.09    0.000     200         31.16          2.00        1.29    0.010     400         34.35          1.92        1.51    0.020     600         41.41          1.76        2.27    0.020     800         56.29          1.76        2.12    0.020    1000        124.84          1.73        2.07    0.020    1200         45.42          1.75        2.42    0.020    1400         58.10          1.51        3.93    0.040    1600         90.27          1.51        2.10    0.020    1800         93.87          1.57        3.22    0.030    2000        172.70          1.48        3.64    0.040    2200        215.72          1.42        4.30    0.040    2400        177.34          1.30        4.72    0.050    2600        866.50          1.22        5.47    0.050    2800       1877.17          1.16        5.09    0.050    3000       4186.50          1.02        6.94    0.071    3200       4118.06          1.05        5.33    0.051    3400       6050.67          0.96        8.27    0.081    3600       7368.26          0.82        6.07    0.061    3800       9302.68          1.03        8.25    0.081    4000      12089.54          0.98        7.82    0.081    4200      10829.92          0.99        6.49    0.061    4400      10462.12          0.91        7.15    0.072    4600      13104.09          0.96        9.11    0.092    4800      14439.08          0.87       10.31    0.102    5000      12240.43          0.86        9.27    0.09

        尽管训练需要更长的时间,但估计的类别与预期的类别更加匹配。

九、结论

        本文介绍了如何向 Spacy 项目添加文本分类任务。使用默认模型,Spacy 可以执行多项基本和高级 NLP 任务,例如标记化、词形还原、词性标记和命名实体解析。要添加文本分类,需要执行以下步骤:a) 准备训练数据,b) 将训练数据转换为 DocBin 格式,以便预处理 Doc 对象提供带有字典属性 cats c) 生成和自定义 Spacy 训练配置,d) 使用 cli 命令训练模型。因此,特别是训练配置是高度可定制的,暴露了学习率和损失函数等细节。训练完成后,可以通过 Spacy 加载生成的模型,并且所有解析的文档现在都将具有估计的类别。

这篇关于P with Spacy:自定义文本分类管道的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/500455

相关文章

SpringBoot 自定义消息转换器使用详解

《SpringBoot自定义消息转换器使用详解》本文详细介绍了SpringBoot消息转换器的知识,并通过案例操作演示了如何进行自定义消息转换器的定制开发和使用,感兴趣的朋友一起看看吧... 目录一、前言二、SpringBoot 内容协商介绍2.1 什么是内容协商2.2 内容协商机制深入理解2.2.1 内容

Java操作xls替换文本或图片的功能实现

《Java操作xls替换文本或图片的功能实现》这篇文章主要给大家介绍了关于Java操作xls替换文本或图片功能实现的相关资料,文中通过示例代码讲解了文件上传、文件处理和Excel文件生成,需要的朋友可... 目录准备xls模板文件:template.xls准备需要替换的图片和数据功能实现包声明与导入类声明与

python解析HTML并提取span标签中的文本

《python解析HTML并提取span标签中的文本》在网页开发和数据抓取过程中,我们经常需要从HTML页面中提取信息,尤其是span元素中的文本,span标签是一个行内元素,通常用于包装一小段文本或... 目录一、安装相关依赖二、html 页面结构三、使用 BeautifulSoup javascript

基于人工智能的图像分类系统

目录 引言项目背景环境准备 硬件要求软件安装与配置系统设计 系统架构关键技术代码示例 数据预处理模型训练模型预测应用场景结论 1. 引言 图像分类是计算机视觉中的一个重要任务,目标是自动识别图像中的对象类别。通过卷积神经网络(CNN)等深度学习技术,我们可以构建高效的图像分类系统,广泛应用于自动驾驶、医疗影像诊断、监控分析等领域。本文将介绍如何构建一个基于人工智能的图像分类系统,包括环境

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

认识、理解、分类——acm之搜索

普通搜索方法有两种:1、广度优先搜索;2、深度优先搜索; 更多搜索方法: 3、双向广度优先搜索; 4、启发式搜索(包括A*算法等); 搜索通常会用到的知识点:状态压缩(位压缩,利用hash思想压缩)。

自定义类型:结构体(续)

目录 一. 结构体的内存对齐 1.1 为什么存在内存对齐? 1.2 修改默认对齐数 二. 结构体传参 三. 结构体实现位段 一. 结构体的内存对齐 在前面的文章里我们已经讲过一部分的内存对齐的知识,并举出了两个例子,我们再举出两个例子继续说明: struct S3{double a;int b;char c;};int mian(){printf("%zd\n",s

Spring 源码解读:自定义实现Bean定义的注册与解析

引言 在Spring框架中,Bean的注册与解析是整个依赖注入流程的核心步骤。通过Bean定义,Spring容器知道如何创建、配置和管理每个Bean实例。本篇文章将通过实现一个简化版的Bean定义注册与解析机制,帮助你理解Spring框架背后的设计逻辑。我们还将对比Spring中的BeanDefinition和BeanDefinitionRegistry,以全面掌握Bean注册和解析的核心原理。

Oracle type (自定义类型的使用)

oracle - type   type定义: oracle中自定义数据类型 oracle中有基本的数据类型,如number,varchar2,date,numeric,float....但有时候我们需要特殊的格式, 如将name定义为(firstname,lastname)的形式,我们想把这个作为一个表的一列看待,这时候就要我们自己定义一个数据类型 格式 :create or repla

HTML5自定义属性对象Dataset

原文转自HTML5自定义属性对象Dataset简介 一、html5 自定义属性介绍 之前翻译的“你必须知道的28个HTML5特征、窍门和技术”一文中对于HTML5中自定义合法属性data-已经做过些介绍,就是在HTML5中我们可以使用data-前缀设置我们需要的自定义属性,来进行一些数据的存放,例如我们要在一个文字按钮上存放相对应的id: <a href="javascript:" d