编者注:文中超链接如果不能访问可以点击“阅读原文”访问本文原页面;可以参考2018年5月21-24日伦敦Strata数据会议上的教学辅导课《使用spaCy和Spark NLP进行自然语言理解》。
本系列博客的目地是通过使用两个领先的生产级语言处理库(John Snow Labs的Apache Spark NLP和Explosion AI的spaCy)来处理真实的自然语言处理(NLP)场景,从而对他们做一个比较。这两个库都是开源的,有商业使用许可证(分别是Apache 2.0和MIT)。两者的发展都很活跃,发布也很频繁,且社区不断增长。
我希望能分析和识别这两个库的优点,发现对数据科学家和开发人员而言它们有什么区别,以及在哪些情况下使用其中一种或另一种更方便。本次分析希望进行一次客观的探索,并在几个阶段加入一定量的主观决定(就像每个自然语言理解应用中那样)。
尽管听起来很简单,但比较两个不同的库,并做出可比较的基准测试是非常具有挑战性的。请记住,你的应用程序会与这里所做的有着不同的场景、数据管道、文本特性、硬件设置和一些非功能性要求。
我会假定读者已经熟悉NLP的概念和编程。你们可能没有这两个工具的相关知识,不过我的目标是使代码尽可能自我说明,提高读性,从而不会让读者陷入太多的细节里。这两个库都有公开的文档,并且是完全开源的。所以我建议你先看一下spaCy 101和Spark-NLP快速入门文档。
关于这两个库
Spark-NLP于2017年10月被开源。作为一个Spark库,它是Apache Spark的原生扩展。它以估计器(estimator)和转换器(transformer)的形式引入了一套Spark ML Pipeline 阶段(stage),用来处理分布式数据集。Spark NLP Annotators不仅包括如分词、标准化和词性标注等基本功能,还有诸如高级情感分析、拼写检查、断言状态等其他高级功能。这些都在工作在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机器学习管道(从数据加载、NLP、特征工程、模型训练、超参数调优以及评估)的一部分来嵌入其中更容易。同时由于Spark可以优化整个管道执行过程,从而使Spark NLP的执行速度更快。
基准应用
我在这里编写的程序将预测原始.txt文件中的POS标记。很多数据清理和准备工作都是按顺序进行的。两个应用程序都将使用相同的数据进行训练,并对同一数据进行预测,以实现最大可能的可比性。
我的目的是验证任何统计性程序的两大支柱:
1.准确性,衡量一个程序能够正确预测语言特征的程度
2.性能,这意味着我需要等待多长时间才能达到这样的准确度。以及在程序崩溃或我的孙子长大之前,我可以向程序输入多少输入数据。
为了比较这些指标,我需要确保两个库有最大的可比性。我用了以下配置:
1.一台台式机,操作系统是Linux Mint。带有SSD硬盘和16GB内存,以及4核3.5 GHz的英特尔i5-6600K处理器。
2.训练、测试和带正确结果的数据,这些数据遵循NLTK POS格式(见下文)。
3.安装了spaCy 2.0.5的Jupyter Python 3 Notebook。
4.安装了Spark-NLP 1.3.0和Apache Spark 2.1.1的Apache Zeppelin 0.7.3 Notebook。
数据
用于训练、测试和比对的数据来自 National American Corpus。我用了其中的报纸部分的MASC 3.0.2书面语料库。
我用语料库提供的工具(ANCtool)对数据进行了整理。虽然我可以使用CoNLL数据格式,其中包含很多标记信息,如词条、索引和实体识别。但我更喜欢使用NLTK数据格式,其中包括Penn POS标签。它足以满足我的目的。数据看起来像这样:
Neither|DT Davison|NNP nor|CC most|RBS other|JJ RxP|NNP opponents|NNSdoubt|VBP the|DT efficacy|NN of|IN medications|NNS .|.
如你所见,训练数据中的内容是:
检测到的句子的边界(新一行,新的句子)
分词的结果(用空格分隔)
检测到的POS(用“|”分隔)
<