编者按:请参考2018年5月21日至24日在伦敦举行的Strata Data会议上的教学教程“使用spaCy和Spark NLP进行自然语言理解”。

本系列博客的目的是比较两个领先的产品级语言处理库,以处理真实的自然语言处理场景。这两个库都是开源的,都有商业许可。两人都在积极开发,经常发表,社区也在不断壮大。

希望能分析识别这两个库的优点,为数据科学家和开发人员找出两者的区别,找出哪一个使用起来更方便。这个分析希望在几个阶段做出客观的探索,加上一定量的主观决定。

虽然听起来很简单,但是比较两个不同的库并进行可比较的基准测试是非常具有挑战性的。请记住,您的应用程序将有不同的场景、数据管道、文本功能、硬件设置和一些非功能性需求。

我将假设读者已经熟悉NLP概念和编程。你可能没有这两个工具的知识,但我的目标是尽可能让代码自解释,以提高可读性,不让读者陷入太多的细节。这两个库都有公共文档,并且是完全开源的。所以,建议你先看看spaCy 101和Spark-NLP的快速入门文档。

关于这两个库

Spark-NLP于2017年10月开业。作为Spark库,它是Apache Spark的原生扩展。它以估计器和转换器的形式引入了一组Spark ML管道级来处理分布式数据集。Spark NLP标注器不仅包括分词、标准化、词性标注等基本功能,还包括高级情感分析、拼写检查、断言状态等其他高级功能。这些都是在Spark ML框架内工作的。Spark-NLP用Scala编写,在JVM中运行,利用Spark的优化和执行计划。该库目前为Scala和Python提供了API。

SpaCy是一个流行且易于使用的Python库,用于自然语言处理。它最近发布了2.0版,里面包含了神经网络、实体识别等很多模型。它提供了业界领先的准确性和速度,并拥有活跃的开源社区。SpaCy已经存在至少三年了,它在GitHub上的第一个版本可以追溯到2015年初。

Spark-NLP目前不包括一套预训练模型。SpaCy为七种语言提供预先训练好的模型,用户无需训练模型就可以快速注入目标语句并返回结果,包括分词、词条、POS、相似度、实体识别等。

这两个库都通过参数在某些级别提供定制,允许将经过训练的管道保存在磁盘上,并要求开发人员在特定用例中使用这些库开发程序。Spark NLP使得更容易嵌入NLP流水线作为Spark ML机器学习流水线的一部分。同时,Spark可以优化整个流水线执行过程,使得Spark NLP执行速度更快。

基准应用

我在这里写的程序会预测出原文中的POS标签。txt文件。大量的数据清理和准备工作是依次进行的。两个应用程序将使用相同的数据进行训练,并预测相同的数据,以实现最大可能的可比性。

我的目标是验证任何统计程序的两个支柱:

1.准确性,衡量程序能够正确预测语言特征的程度

2.性能,也就是说我要等多久才能达到这样的精度。以及在程序崩溃或者孙子长大之前,我可以向程序输入多少输入数据。

为了比较这些指标,我需要保证两个库有最大的可比性。我使用了以下配置:

1.以Linux Mint为操作系统的台式机。配备SSD硬盘和16GB内存,以及4核3.5 GHz英特尔i5-6600K处理器..

2.遵循NLTK POS格式的培训、测试和结果正确的数据。

3.Jupyter Python 3笔记本,安装spaCy 2.0.5。

安装了Spark-NLP 1.3.0和Apache Spark 2.1.1的Apache Zeppelin 0.7.3笔记本。

数据

用于训练、测试和比较的数据来自美国国家语料库。我在报纸部分使用了MASC 3.0.2的书面语料库。

我使用了语料库提供的工具来整理数据。虽然我可以使用CoNLL数据格式,但是它包含了大量的标签信息,比如条目、索引、实体识别等。但是我更喜欢使用NLTK数据格式,包括Penn POS标签。这足以满足我的目的。数据如下:

戴维森|NNP和CC都不是最|RBS其他|JJ RxP|NNP对手|NNS双| VBP | DT疗效| NN | IN药物| NNS。|.

如您所见,培训数据的内容有:

检测到的句子的边界(新一行,新的句子)分词的结果(用空格分隔)检测到的POS(用“|”分隔)

在原文文件中,一切都是混杂的,混乱的,没有标准的边界。

以下是我们将运行的基准的关键指标。

基准测试数据集

在本文中,我们将使用两个基准数据集。第一个非常小,用于交互式调试和实验:

训练数据:36个.txt文件,总共77 KB测试数据:14个.txt文件,共114 KB需要预测21362个词

第二组数据仍然不是“大数据”,而是一个相对较大的数据集,用于评估典型的独立应用场景:

训练数据:72个.txt文件,总共150 KB两个测试数据集:9225个.txt文件,75 MB; 1125个文件,15 MB需要预测1千3百万个词

需要注意的是,我们这里没有对“大数据”数据集进行评估。这是因为虽然spaCy可以利用多核CPU,但它不能像Spark NLP一样本机使用集群。因此,在使用集群的TB数据集上,Spark NLP比spaCy快几个数量级。同样,大型机上的数据库性能将超过本地安装的MySQL数据库。我的目标是在一台机器上评估这两个库,并使用它们的多核功能。这是开发中常见的情况,也适用于不需要处理大数据集的应用。

开始吧。

那我们开始吧。首先,我们必须导入相关的库并启动它们。

宽大的

导入操作系统

导入io

导入时间

进口re

随机导入

将熊猫作为pd导入

进口空间

nlp_model = spacy.load

nlp_blank = spacy.blank

我禁用了spaCy中的一些管道,以避免不必要的解析器使其过于臃肿。我还用了一个nlp_model作为参考,这是spaCy提供的一个预先训练好的nlp模型。但是我会用nlp_blank,会更有代表性,而且会是我自己的训练模式。

火花-NLP

import org . Apache . spark . SQL . expressions . window

import org . Apache . spark . ml . pipeline

import . com . johnsnowlabs . NLP _

import . com . johnsnowlabs . NLP . annoters . _

import . com . johnsnowlabs . NLP . annotors . pos . perceptor . _

import . com . johnsnowlabs . NLP . annotors . sbd .务实. _

import . com . johnsnowlabs . NLP . util . io . resource helper

import . com . johnsnowlabs . util . benchmark

我面临的第一个挑战是,我必须处理三个完全不同的分词结果,这将很难确定一个单词是否匹配分词和POS标签:

1.spaCy的分词器采用了基于规则的方法,已经包含了一个词汇表,其中保存了很多常用的缩略语进行分词。

2.SparkNLP有自己的分词规则。

3.我的训练和测试数据。这些数据根据ANC标准进行分段。在许多情况下,它以与这两个库中的分词器完全不同的方式来划分单词。

所以为了克服这个问题,我需要决定如何比较一组完全不同的标签的POS标签。对于Spark-NLP,我会保持原样。其默认规则基本匹配ANC开放标准分词格式。对于spaCy,我需要放宽中缀规则,通过不使用“-”来增加分词的匹配准确率。

宽大的

DummyTokenMatch类:

def __init__:

self . start =λ:0

self.end = lambda : len

def do_nothing:

返回

model _ token izer = NLP _ model . token izer

NLP _ blank . tokenizer = spacy . tokenizer . tokenizer

请注意:我给nlp_blank传递了一个vocab对象,所以nlp_blank不是true 空。这个vocab词汇对象包含了英语语言规则和策略,可以帮助我们的空白色模型标记POS,分割英语单词。所以spaCy一开始有一点点优势,而Spark-NLP并没有提前“理解”英语。

培训管道

现在进入训练阶段。在spaCy中,我需要提供一个指定的训练数据格式,如下所示:

列车_数据=

在Spark-NLP中,我必须提供一个文件夹,其中包含。“分隔符|标记”格式的txt数据文件,看起来像ANC训练数据。因此,我只需要将文件夹路径传递给POS标记。

让我们加载spaCy训练数据。在下面的代码中,我必须添加一些手动生成的异常、规则和一些字符,因为spaCy的训练集需要干净的数据。

宽大的

start = time.time

train_path = "。/target/training/"

train _ files = sortedif OS . path . is file)])

TRAIN_DATA =

对于train _ files中的文件:

fo = io.open

for line in fo.readlines:

line = line.strip

如果line == ":

继续

line _ word =

line_tags =

对于re.split行中的对:

tag = pair.strip。拆分

line _ word . append. ',' 1 ',标记。替换。替换。替换

line_tags.append

TRAIN_DATA.append。join{ ' tags ':line _ tags }))

fo.close

“该公司表示,一次性准备金将基本上消除该部门未来的所有损失。”,{'tags': })

n_iter=5

tagger = NLP _ blank . create _ pipe

tagger.add_label

tagger.add_label

tagger.add_label')

tagger.add_label

tagger . add _ label

tagger.add_label

nlp_blank.add_pipe

optimizer = NLP _ blank . begin _ training

对于范围内的I:

随机洗牌

损失= {}

对于文本,列车数据中的注释:

nlp_blank.update

打印

打印–开始)

运行时间

{'tagger': 5.773235303101046}

{'tagger': 1.138113870966123}

{'tagger': 0.46656132966405683}

{'tagger': 0.5513760568314119}

{'tagger': 0.2541630900934435}

跑步时间:122.11359786987305秒

我不得不做一些额外的工作来绕过一些坑。SpaCy不让我用我的断字器,因为里面有一些难看的字。例如,spaCy不训练标有“大屏幕”或“否”的句子,除非它们存在于vocab标签中。我必须将这些字符添加到vocab列表中,以便spaCy可以在培训期间找到它们。

现在,我们来看看如何在Spark-NLP中构建管道。

火花-NLP

val document assembler = new document assembler

。setInputCol

。setOutputCol

val标记器=新标记器

。设置输入工具

。setOutputCol

。setPrefixPattern")

。addinFixppattern*)")

val后标记=新感知方法

。设置输入工具

。setOutputCol

。setCorpusPath

。设置

val分页装订器=新分页装订器

。设置输入工具

。setOutputAsArray

阀门管道=新管道

。设置阶段)

价值模型=基准时间{

pipeline.fit

}

可以看到,构建管道是一个非常线性的过程:设置文档组装器,使目标文本列成为后续标注器的目标;然后感知方法是位置模型,它接收文档文本和符号形式作为输入。

我必须更新前缀模式,并添加一个新的中缀模式,以与ANC相同的方式匹配日期和数字。如您所见,管道的每个组件都在用户的控制之下;vocab或英语没有隐性知识,和spaCy不一样。

来自感知方法的路径被传递到包含管道分隔文本文件的文件夹。整理器标注器将POS和分词的结果包装起来,供下一步使用。正如SetOutputAsArray的名字所表示的,它会返回一个数组而不是一个拼接的字符串,但是这在处理上会有一定的计算成本。

传递给fit的数据并不重要,因为唯一经过训练的NLP注释器是感知方法。而且这个标注器是由外部的POS语料库训练出来的。

运行时间

训练模型的时间:3.167619593sec

请注意,可以将SentenceDetector或拼写检查器注入管道。因此,在某些情况下,它可以通过让模型知道句子的结尾来帮助提高POS的准确性。

接下来怎么办?

到目前为止,我们已经初始化了库,加载了数据,并用这两个库训练了一个分词模型。需要注意的是spaCy自带一个预先训练好的分词器,所以如果你的文本数据来自spaCy训练好的语言和字段,这一步可能就没必要了。然而,为了将生成的符号与我们的ANC语料库相匹配,修改分词的中缀是非常重要的。经过5次迭代,Spark-NLP的训练速度比spaCy快38倍。

在本系列的下一篇文章中,我们将通过使用刚刚训练好的模型运行NLP管道来介绍代码、准确性和性能。

Saif Addin Ellafi

Saif Addin Ellafi是一名软件开发人员、分析师、数据科学家,一直是一名学生。他也是极限运动和游戏的爱好者。他在银行和金融行业的数据领域有丰富的问题解决和测试经验。他现在在约翰·斯诺实验室,是火花-自然语言处理项目的主要贡献者。

1.《spacy 比较两个生产级NLP库:训练Spark-NLP和spaCy的管道》援引自互联网,旨在传递更多网络信息知识,仅代表作者本人观点,与本网站无关,侵删请联系页脚下方联系方式。

2.《spacy 比较两个生产级NLP库:训练Spark-NLP和spaCy的管道》仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证。

3.文章转载时请保留本站内容来源地址,https://www.lu-xu.com/guonei/1702738.html