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

相关文章

C++20管道运算符的实现示例

《C++20管道运算符的实现示例》本文简要介绍C++20管道运算符的使用与实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录标准库的管道运算符使用自己实现类似的管道运算符我们不打算介绍太多,因为它实际属于c++20最为重要的

MySQL中的索引结构和分类实战案例详解

《MySQL中的索引结构和分类实战案例详解》本文详解MySQL索引结构与分类,涵盖B树、B+树、哈希及全文索引,分析其原理与优劣势,并结合实战案例探讨创建、管理及优化技巧,助力提升查询性能,感兴趣的朋... 目录一、索引概述1.1 索引的定义与作用1.2 索引的基本原理二、索引结构详解2.1 B树索引2.2

Java实现自定义table宽高的示例代码

《Java实现自定义table宽高的示例代码》在桌面应用、管理系统乃至报表工具中,表格(JTable)作为最常用的数据展示组件,不仅承载对数据的增删改查,还需要配合布局与视觉需求,而JavaSwing... 目录一、项目背景详细介绍二、项目需求详细介绍三、相关技术详细介绍四、实现思路详细介绍五、完整实现代码

一文详解Java Stream的sorted自定义排序

《一文详解JavaStream的sorted自定义排序》Javastream中的sorted方法是用于对流中的元素进行排序的方法,它可以接受一个comparator参数,用于指定排序规则,sorte... 目录一、sorted 操作的基础原理二、自定义排序的实现方式1. Comparator 接口的 Lam

Python中图片与PDF识别文本(OCR)的全面指南

《Python中图片与PDF识别文本(OCR)的全面指南》在数据爆炸时代,80%的企业数据以非结构化形式存在,其中PDF和图像是最主要的载体,本文将深入探索Python中OCR技术如何将这些数字纸张转... 目录一、OCR技术核心原理二、python图像识别四大工具库1. Pytesseract - 经典O

苹果macOS 26 Tahoe主题功能大升级:可定制图标/高亮文本/文件夹颜色

《苹果macOS26Tahoe主题功能大升级:可定制图标/高亮文本/文件夹颜色》在整体系统设计方面,macOS26采用了全新的玻璃质感视觉风格,应用于Dock栏、应用图标以及桌面小部件等多个界面... 科技媒体 MACRumors 昨日(6 月 13 日)发布博文,报道称在 macOS 26 Tahoe 中

Python实现精准提取 PDF中的文本,表格与图片

《Python实现精准提取PDF中的文本,表格与图片》在实际的系统开发中,处理PDF文件不仅限于读取整页文本,还有提取文档中的表格数据,图片或特定区域的内容,下面我们来看看如何使用Python实... 目录安装 python 库提取 PDF 文本内容:获取整页文本与指定区域内容获取页面上的所有文本内容获取

如何自定义一个log适配器starter

《如何自定义一个log适配器starter》:本文主要介绍如何自定义一个log适配器starter的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录需求Starter 项目目录结构pom.XML 配置LogInitializer实现MDCInterceptor

详解如何使用Python从零开始构建文本统计模型

《详解如何使用Python从零开始构建文本统计模型》在自然语言处理领域,词汇表构建是文本预处理的关键环节,本文通过Python代码实践,演示如何从原始文本中提取多尺度特征,并通过动态调整机制构建更精确... 目录一、项目背景与核心思想二、核心代码解析1. 数据加载与预处理2. 多尺度字符统计3. 统计结果可

Linux基础命令@grep、wc、管道符的使用详解

《Linux基础命令@grep、wc、管道符的使用详解》:本文主要介绍Linux基础命令@grep、wc、管道符的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录grep概念语法作用演示一演示二演示三,带选项 -nwc概念语法作用wc,不带选项-c,统计字节数-