作者 |Veysel Kocaman
编译 |VK
起源 |Towards Data Science
自然语言解决 (NLP) 是许多数据迷信零碎中必须了解或推理文本的要害组成部分。常见的用例包含文本分类、问答、释义或总结、情感剖析、自然语言 BI、语言建模和消歧。
NLP 在越来越多的人工智能利用中是越来越重要。如果你正在构建聊天机器人、搜寻专利数据库、将患者与临床试验相匹配、对客户服务或销售电话进行分级、从财务报告中提取摘要,你必须从文本中提取精确的信息。
文本分类 是古代自然语言解决的次要工作之一,它是为句子或文档指定一个适合的类别的工作。类别取决于所选的数据集,并且能够从主题开始。
每一个文本分类问题都遵循类似的步骤,并用不同的算法来解决。更不用说经典和风行的机器学习分类器,如随机森林或 Logistic 回归,有 150 多个深度学习框架提出了各种文本分类问题。
文本分类问题中应用了几个基准数据集,能够在 nlpprogress.com 上跟踪最新的基准。以下是对于这些数据集的根本统计数据。
简略的文本分类应用程序通常遵循以下步骤:
- 文本预处理和清理
- 特色工程(手动从文本创立特色)
- 特征向量化 (TfIDF、频数、编码) 或嵌入(word2vec、doc2vec、Bert、Elmo、句子嵌入等)
- 用 ML 和 DL 算法训练模型。
Spark-NLP 中的文本分类
在本文中,咱们将应用通用句子嵌入 (Universal Sentence Embeddings) 在 Spark NLP 中建设一个文本分类模型。而后咱们将与其余 ML 和 DL 办法以及文本向量化办法进行比拟。
Spark NLP 中有几个文本分类选项:
- Spark-NLP 中的文本预处理及基于 Spark-ML 的 ML 算法
- Spark-NLP 和 ML 算法中的文本预处理和单词嵌入(Glove,Bert,Elmo)
- Spark-NLP 和 ML 算法中的文本预处理和句子嵌入(
Universal Sentence Encoders
) - Spark-NLP 中的文本预处理和 ClassifierDL 模块(基于 TensorFlow)
正如咱们在对于 Spark NLP 的重要文章中所深刻探讨的,在 ClassifierDL 之前的所有这些文本处理步骤都能够在指定的管道序列中实现,并且每个阶段都是一个转换器或预计器。这些阶段按程序运行,输出数据帧在通过每个阶段时进行转换。也就是说,数据按程序通过各个管道。每个阶段的 transform()
办法更新数据集并将其传递到下一个阶段。借助于管道,咱们能够确保训练和测试数据通过雷同的特色解决步骤。
Universal Sentence Encoders
在自然语言解决 (NLP) 中,在建设任何深度学习模型之前,文本嵌入起着重要的作用。文本嵌入将文本 (单词或句子) 转换为向量。
基本上,文本嵌入办法在固定长度的向量中对单词和句子进行编码,以极大地改良文本数据的解决。这个想法很简略:呈现在雷同上下文中的单词往往有类似的含意。
像 Word2vec 和 Glove 这样的技术是通过将一个单词转换成向量来实现的。因而,对应的向量“猫”比“鹰”更靠近“狗”。然而,当嵌入一个句子时,整个句子的上下文须要被捕捉到这个向量中。这就是“Universal Sentence Encoders
”的性能了。
Universal Sentence Encoders
将文本编码成高维向量,可用于文本分类、语义相似性、聚类和其余自然语言工作。在 Tensorflow hub 中能够公开应用预训练的 Universal Sentence Encoders
。它有两种变体,一种是用 Transformer 编码器训练的,另一种是用深度均匀网络(DAN) 训练的。
Spark NLP 应用 Tensorflow hub 版本,该版本以一种在 Spark 环境中运行的形式包装。也就是说,你只需在 Spark NLP 中插入并播放此嵌入,而后以分布式形式训练模型。
为句子生成嵌入,无需进一步计算,因为咱们并不是均匀句子中每个单词的单词嵌入来取得句子嵌入。
Spark-NLP 中 ClassifierDL 和 USE 在文本分类的利用
在本文中,咱们将应用 AGNews 数据集 (文本分类工作中的基准数据集之一) 在 Spark NLP 中应用 USE 和 ClassifierDL 构建文本分类器,后者是 Spark NLP 2.4.4 版中增加的最新模块。
ClassifierDL
是 Spark NLP 中第一个多类文本分类器,它应用各种文本嵌入作为文本分类的输出。ClassifierDLAnnotator 应用了一个在 TensorFlow 外部构建的深度学习模型(DNN),它最多反对 50 个类。
也就是说,你能够用这个 classifirdl 在 Spark NLP 中用 Bert
、Elmo
、Glove
和Universal Sentence Encoders
构建一个文本分类器。
咱们开始写代码吧!
申明加载必要的包并启动一个 Spark 会话。
import sparknlp
spark = sparknlp.start()
# sparknlp.start(gpu=True) >> 在 GPU 上训练
from sparknlp.base import *
from sparknlp.annotator import *
from pyspark.ml import Pipeline
import pandas as pd
print("Spark NLP version", sparknlp.version())
print("Apache Spark version:", spark.version)
>> Spark NLP version 2.4.5
>> Apache Spark version: 2.4.4
而后咱们能够从 Github repo 下载 AGNews 数据集(https://github.com/JohnSnowLa…。
! wget https://raw.githubusercontent.com/JohnSnowLabs/spark-nlp-workshop/master/tutorials/Certification_Trainings/Public/data/news_category_train.csv
! wget https://raw.githubusercontent.com/JohnSnowLabs/spark-nlp-workshop/master/tutorials/Certification_Trainings/Public/data/news_category_test.csv
trainDataset = spark.read \
.option("header", True) \
.csv("news_category_train.csv")
trainDataset.show(10, truncate=50)
>>
+--------+--------------------------------------------------+
|category| description|
+--------+--------------------------------------------------+
|Business| Short sellers, Wall Street's dwindling band of...|
|Business| Private investment firm Carlyle Group, which h...|
|Business| Soaring crude prices plus worries about the ec...|
|Business| Authorities have halted oil export flows from ...|
|Business| Tearaway world oil prices, toppling records an...|
|Business| Stocks ended slightly higher on Friday but sta...|
|Business| Assets of the nation's retail money market mut...|
|Business| Retail sales bounced back a bit in July, and n...|
|Business|" After earning a PH.D. in Sociology, Danny Baz...|
|Business| Short sellers, Wall Street's dwindling band o...|
+--------+--------------------------------------------------+
only showing top 10 rows
AGNews 数据集有 4 个类:World、Sci/Tech、Sports、Business
from pyspark.sql.functions import col
trainDataset.groupBy("category") \
.count() \
.orderBy(col("count").desc()) \
.show()
>>
+--------+-----+
|category|count|
+--------+-----+
| World|30000|
|Sci/Tech|30000|
| Sports|30000|
|Business|30000|
+--------+-----+
testDataset = spark.read \
.option("header", True) \
.csv("news_category_test.csv")
testDataset.groupBy("category") \
.count() \
.orderBy(col("count").desc()) \
.show()
>>
+--------+-----+
|category|count|
+--------+-----+
|Sci/Tech| 1900|
| Sports| 1900|
| World| 1900|
|Business| 1900|
+--------+-----+
当初,咱们能够将这个数据提供给 Spark NLP DocumentAssembler,它是任何 Spark datagram 的 Spark NLP 的入口点。
# 理论内容在 description 列
document = DocumentAssembler()\
.setInputCol("description")\
.setOutputCol("document")
#咱们能够下载事后训练好的嵌入
use = UniversalSentenceEncoder.pretrained()\
.setInputCols(["document"])\
.setOutputCol("sentence_embeddings")
# classes/labels/categories 在 category 列
classsifierdl = ClassifierDLApproach()\
.setInputCols(["sentence_embeddings"])\
.setOutputCol("class")\
.setLabelColumn("category")\
.setMaxEpochs(5)\
.setEnableOutputLogs(True)
use_clf_pipeline = Pipeline(
stages = [
document,
use,
classsifierdl
])
以上,咱们获取数据集,输出,而后从应用中获取句子嵌入,而后在 ClassifierDL 中进行训练
当初咱们开始训练。咱们将应用 ClassiferDL
中的 .setMaxEpochs()
训练 5 个 epoch。在 Colab 环境下,这大概须要 10 分钟能力实现。
use_pipelineModel = use_clf_pipeline.fit(trainDataset)
运行此命令时,Spark NLP 会将训练日志写入主目录中的 annotator_logs 文件夹。上面是失去的日志。
如你所见,咱们在不到 10 分钟的工夫内就实现了 90% 以上的验证精度,而无需进行文本预处理,这通常是任何 NLP 建模中最耗时、最费劲的一步。
当初让咱们在最早的时候失去预测。咱们将应用下面下载的测试集。
上面是通过 sklearn 库中的 classification_report
取得测试后果。
咱们达到了 89.3% 的测试集精度!看起来不错!
基于 Bert 和 globe 嵌入的 Spark-NLP 文本预处理分类
与任何文本分类问题一样,有很多有用的文本预处理技术,包含词干、词干剖析、拼写检查和停用词删除,而且除了拼写查看之外,Python 中简直所有的 NLP 库都有利用这些技术的工具。目前,Spark NLP 库是惟一一个具备拼写查看性能的可用 NLP 库。
让咱们在 Spark NLP 管道中利用这些步骤,而后应用 glove 嵌入来训练文本分类器。咱们将首先利用几个文本预处理步骤(仅通过保留字母程序进行标准化,删除停用词字和词干化),而后获取每个标记的单词嵌入(标记的词干),而后均匀每个句子中的单词嵌入以取得每行的句子嵌入。
对于 Spark NLP 中的所有这些文本预处理工具以及更多内容,你能够在这个 Colab 笔记本中找到具体的阐明和代码示例(https://github.com/JohnSnowLa…。
那咱们就能够训练了。
clf_pipelineModel = clf_pipeline.fit(trainDataset)
失去测试后果。
当初咱们有 88% 的测试集精度!即便在所有这些文本清理步骤之后,咱们依然无奈击败 Universal Sentence Embeddings
+ClassifierDL
,这次要是因为USE
绝对于数据清理后的版本,它在原始文本上执行得更好。
为了训练与 BERT 雷同的分类器,咱们能够在下面构建的同一管道中用 BERT_embedding 替换 glove_embeddings。
word_embeddings = BertEmbeddings\
.pretrained('bert_base_cased', 'en') \
.setInputCols(["document",'lemma'])\
.setOutputCol("embeddings")\
.setPoolingLayer(-2) # default 0
咱们也能够应用 Elmo 嵌入。
word_embeddings = ElmoEmbeddings\
.pretrained('elmo', 'en')\
.setInputCols(["document",'lemma'])\
.setOutputCol("embeddings")
应用 LightPipeline 进行疾速推理
正如咱们在后面的一篇文章中深刻探讨的,LightPipelines 是 Spark NLP 特有的管道,相当于 Spark ML 管道,但其目标是解决大量的数据。它们在解决小数据集、调试后果或从服务一次性申请的 API 运行训练或预测时十分有用。
Spark NLP LightPipelines
是 Spark ML 管道转换成在独自的机器上,变成多线程的工作,对于较小的数据量 (较小的是绝对的,但 5 万个句子大抵最大值) 来说,速度快了 10 倍以上。要应用它们,咱们只需插入一个经过训练的管道,咱们甚至不须要将输出文本转换为 DataFrame,就能够将其输出到一个管道中,该管道首先承受 DataFrame 作为输出。当须要从经过训练的 ML 模型中取得几行文本的预测时,这个性能将十分有用。
LightPipelines 很容易创立,而且能够防止解决 Spark 数据集。它们的速度也十分快,当只在驱动节点上工作时,它们执行并行计算。让咱们看看它是如何实用于咱们下面形容的案例的:
light_model = LightPipeline(clf_pipelineModel)
text="Euro 2020 and the Copa America have both been moved to the summer of 2021 due to the coronavirus outbreak."
light_model.annotate(text)['class'][0]
>> "Sports"
你还能够将这个经过训练的模型保留到磁盘中,而后稍后在另一个 Spark 管道中与 ClassifierDLModel.load()
一起应用。
论断
本文在 Spark-NLP 中利用词嵌入和 Universal Sentence Encoders,
训练了一个多类文本分类模型,在不到 10min 的训练工夫内取得了较好的模型精度。整个代码都能够在这个 Github repo 中找到(Colab 兼容,https://github.com/JohnSnowLa…。咱们还筹备了另一个 Notebook,简直涵盖了 Spark NLP 和 Spark ML 中所有可能的文本分类组合(CV、TfIdf、Glove、Bert、Elmo、USE、LR、RF、ClassifierDL、DocClassifier):https://github.com/JohnSnowLa…。
咱们还开始为公共和企业 (医疗) 版本提供在线 Spark NLP 训练。这里是所有公共 Colab Notebook 的链接(https://github.com/JohnSnowLa…
John Snow 实验室将组织虚构 Spark NLP 训练,以下是下一次训练的链接:
https://events.johnsnowlabs.c…
以上代码截图
原文链接:https://towardsdatascience.co…
欢送关注磐创 AI 博客站:
http://panchuang.net/
sklearn 机器学习中文官网文档:
http://sklearn123.com/
欢送关注磐创博客资源汇总站:
http://docs.panchuang.net/