【Spark NLP】第 1 章:入门

  🔎大家好,我是Sonhhxg_柒,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流🔎

📝个人主页-Sonhhxg_柒的博客_CSDN博客 📃

🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝​

📣系列专栏 - 机器学习【ML】 自然语言处理【NLP】  深度学习【DL】

 🖍foreword

✔说明⇢本人讲解主要包括Python、机器学习(ML)、深度学习(DL)、自然语言处理(NLP)等内容。

如果你对这个系列感兴趣的话,可以关注订阅哟👋

文章目录

其他工具

设置您的环境

先决条件

启动 Apache Spark

签出代码

熟悉 Apache Spark

使用 Spark NLP 启动 Apache Spark

在 Apache Spark 中加载和查看数据

使用 Spark NLP 的 Hello World


这本书是关于使用 Spark NLP 构建自然语言处理 (NLP)应用程序的。Spark NLP 是一个建立在 Apache Spark 之上的 NLP 库。在本书中,我将介绍如何使用 Spark NLP,以及基本的自然语言处理主题。希望在本书的最后,您将拥有一个使用自然语言和 Spark NLP 的新软件工具,以及一套技术,并了解这些技术为何起作用。

让我们先谈谈这本书的结构。在第一部分,我们将回顾在本书中我们将与 Spark NLP 一起使用的技术和技巧。之后,我们将讨论 NLP 的构建块。最后,我们将讨论 NLP 应用程序和系统。

在开发需要 NLP 的应用程序时,您应该牢记三个观点:软件开发人员的观点、语言学家的观点和数据科学家的观点。软件开发人员的观点侧重于您的应用程序需要做什么;这为您想要创建的产品奠定了基础。语言学家的观点侧重于您要提取的数据中的内容。数据科学家的观点侧重于如何从数据中提取所需的信息。

以下是本书的更详细概述。

第一部分,基础

  • 第 1 章介绍了如何设置环境,以便您可以按照书中的示例和练习进行操作。
  • 第 2 章,自然语言基础是对一些语言学概念的综述,这些概念有助于理解 NLP 技术为何有效,以及如何使用 NLP 技术从语言中获取所需信息。
  • 第 3 章, Apache Spark 上的NLP是对 Apache Spark 以及最密切相关的 Spark NLP 库的介绍。
  • 第 4 章,深度学习基础是对我们将在本书中使用的一些深度学习概念的综述。本书不是深度学习教程,但我们会在必要时尝试解释这些技术。

第二部分,构建块

  • 第 5 章,处理词涵盖了经典的文本处理技术。由于 NLP 应用程序通常需要一系列转换,因此必须很好地理解早期步骤。
  • 第 6 章,信息检索涵盖了搜索引擎的基本概念。这不仅是使用文本的应用程序的经典示例,而且在其他类型的应用程序中使用的许多 NLP 技术最终都来自信息检索。
  • 第 7 章,分类和回归介绍了一些使用文本特征进行分类和回归任务的成熟技术。
  • 第 8 章,使用 Keras 进行序列建模 介绍了将自然语言文本数据建模为序列的技术。由于自然语言是一个序列,因此这些技术是基本的。
  • 第 9 章,信息提取展示了我们如何从文本中提取事实和关系。
  • 第 10 章,主题建模演示了在文档中查找主题的技术。主题建模是探索文本的好方法。
  • 第 11 章,词嵌入讨论了从文本创建特征的最流行的现代技术之一。

第三部分,应用

  • 第 12 章,情绪分析和情绪检测涵盖了一些需要识别文本作者情绪的基本应用程序——例如,电影评论是正面的还是负面的。
  • 第 13 章,构建知识库探讨了从语料库创建本体,即以图形方式组织的事实和关系的集合。
  • 第 14 章,搜索引擎深入探讨了可以做些什么来改进搜索引擎。提高不仅仅是提高排名;它还旨在通过诸如构面之类的功能为用户提供便利。
  • 第 15 章,聊天机器人演示了如何创建聊天机器人——这是一个有趣且有趣的应用程序。这种应用程序越来越受欢迎。
  • 第 16 章,对象字符识别介绍了将存储为图像的文本转换为文本数据。并非所有文本都存储为文本数据。手写和旧文本是我们可能收到的图像文本示例。有时,我们还必须处理存储在 PDF 图像和打印文档扫描等图像中的非手写文本。

第四部分,构建 NLP 系统

  • 第 17 章,支持多种语言探讨了应用程序创建者在准备使用多种语言时应考虑的主题。
  • 第 18 章,人类标签介绍了使用人类收集文本数据的方法。能够有效地使用人类来增强数据可以使原本不可能的项目变得可行。
  • 第 19 章,生产化 NLP 应用程序包括创建模型、Spark NLP 管道和 TensorFlow 图,并发布它们以用于生产;开发人员在设计使用文本的系统时应牢记的一些性能问题;以及 NLP 应用程序特有的质量和监控问题。

其他工具

除了 Spark NLP、Apache Spark 和 TensorFlow,我们还将使用许多其他工具:

  • Python是最重要的之一数据科学中使用的流行编程语言。虽然 Spark NLP 是在 Scala 中实现的,但我们将通过 Python 演示它的使用。
  • Anaconda是一个开放的Python(和我们没有使用的 R)的源代码分发。它由 Anaconda, Inc. 维护,该公司还提供企业平台和培训课程。我们将使用 Anaconda 包管理器conda来创建我们的环境。
  • Jupyter Notebook是一个工具用于在浏览器中执行代码。Jupyter Notebook 还允许您在浏览器中编写 Markdown 和显示可视化。事实上,这本书在转换为可发布格式之前是作为 Jupyter 笔记本编写的。Jupyter Notebook 由 Project Jupyter 维护,这是一个致力于支持交互式数据科学工具的非营利组织。
  • Docker是一个工具用于轻松创建虚拟机,通常称为容器。我们将使用 Docker 作为设置 Anaconda 的替代安装工具。它由 Docker, Inc. 维护。

设置您的环境

在本书中,几乎每一章都有练习,因此在开始时确保环境正常工作很有用。我们将在本书中使用 Jupyter 笔记本,我们将使用的内核是基线 Python 3.6 内核。此处的说明使用 Continuum 的 Anaconda 设置 Python 虚拟环境。

您还可以将docker 映像用于必要的环境。

这些说明是根据 Ubuntu 的设置过程创建的。在项目的 GitHub 页面上有其他在线设置说明。

先决条件

  1. python
    • 要设置 Anaconda,请按照说明进行操作。
  2. Apache Spark
    • 要设置 Apache Spark,请按照说明进行操作。
    • 确保将SPARK_HOME其设置为 Apache Spark安装的位置。

      • 如果你在 Linux 或 macOS 上,你可以把export SPARK_HOME="/path/to/spark"
      • 如果你在 Windows 上,你可以使用系统属性来设置一个名为的环境SPARK_HOME变量 "/path/to/spark"
    • 这是在 Apache Spark 2.4 上编写的

可选:为您的 Jupyter 笔记本服务器设置密码。

启动 Apache Spark

$ echo 
$ SPARK_HOME
/path/to/your/spark/installation
$ spark-shell
Using Spark's default log4j profile: org/apache/spark/log4j-defaults.prope
rties
Setting default log level to "WARN".
To adjust logging level use sc.setLogLevel(newLevel). For SparkR, use setL
ogLevel(newLevel).
...
Spark context Web UI available at localhost:4040
Spark context available as 'sc' (master = local[*], app id = ...).
Spark session available as 'spark'.
Welcome to
      ____              __
     / __/__  ___ _____/ /__
    _\ \/ _ \/ _ `/ __/  '_/
   /___/ .__/\_,_/_/ /_/\_\   version 2.3.2
      /_/

Using Scala version 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0
_102)
Type in expressions to have them evaluated.
Type :help for more information.

scala>

签出代码

  1. 转到此项目的GitHub 存储库
  2. 查看代码,并在终端中运行以下代码示例:
    1. 克隆仓库
      git clone https://github.com/alexander-n-thomas/spark-nlp-book.git
    2. 创建 Anaconda 环境——这需要一段时间
      conda env create -f environment.yml
    3. 激活新环境
      source activate spark-nlp-book
    4. 为这个环境创建内核
      ipython kernel install --user --name = sparknlpbook
    5. 启动笔记本服务器
      jupyter notebook
    6. 在 localhost:8888 转到您的笔记本页面

熟悉 Apache Spark

现在我们都设置好了,让我们开始使用 Spark NLP!我们将使用来自加州大学欧文分校机器学习存储库的20 个新闻组数据集。对于第一个示例,我们使用mini_newsgroups 数据集。下载 TAR 文件并将其解压缩到该项目的数据文件夹中。

!ls ./data/mini_newsgroups
alt.atheism rec.autos sci.space 
comp.graphics rec.motorcycles soc.religion.christian 
comp.os.ms-windows.misc rec.sport.baseball talk.politics.guns 
comp.sys.ibm.pc.hardware rec. sport.hockey talk.politics.mideast 
comp.sys.mac.hardware sci.crypt talk.politics.misc 
comp.windows.x sci.electronics talk.religion.misc 
misc.forsale sci.me

使用 Spark NLP 启动 Apache Spark

我们可以通过多种方式从 Jupyter 笔记本中使用 Apache Spark。我们可以使用专门的内核,但我通常更喜欢使用简单的内核。幸运的是,Spark NLP 为我们提供了一种简单的启动方式。

import sparknlp

import pyspark
from pyspark import SparkConf
from pyspark.sql import SparkSession
from pyspark.sql import functions as fun
from pyspark.sql.types import *

%matplotlib inline
import matplotlib.pyplot as plt

packages = ','.join([
    "JohnSnowLabs:spark-nlp:1.6.3",
])

spark_conf = SparkConf()
spark_conf = spark_conf.setAppName('spark-nlp-book-p1c1')
spark_conf = spark_conf.setAppName('master[*]')
spark_conf = spark_conf.set("spark.jars.packages", packages)
spark = SparkSession.builder.config(conf=spark_conf).getOrCreate()

在 Apache Spark 中加载和查看数据

让我们看看如何使用 Apache Spark 加载数据,然后通过某些方式查看数据。

import os
mini_newsgroups_path = os.path.join('data', 'mini_newsgroups', '*')

texts = spark.sparkContext.wholeTextFiles(mini_newsgroups_path)

schema = StructType([
    StructField('filename', StringType()),
    StructField('text', StringType()),
])
texts_df = spark.createDataFrame(texts, schema)

texts_df.show()
+--------------------+--------------------+
|            filename|                text|
+--------------------+--------------------+
|file:/home/alext/...|Path: cantaloupe....|
|file:/home/alext/...|Newsgroups: sci.e...|
|file:/home/alext/...|Newsgroups: sci.e...|
|file:/home/alext/...|Newsgroups: sci.e...|
|file:/home/alext/...|Xref: cantaloupe....|
|file:/home/alext/...|Path: cantaloupe....|
|file:/home/alext/...|Xref: cantaloupe....|
|file:/home/alext/...|Newsgroups: sci.e...|
|file:/home/alext/...|Newsgroups: sci.e...|
|file:/home/alext/...|Xref: cantaloupe....|
|file:/home/alext/...|Path: cantaloupe....|
|file:/home/alext/...|Newsgroups: sci.e...|
|file:/home/alext/...|Path: cantaloupe....|
|file:/home/alext/...|Path: cantaloupe....|
|file:/home/alext/...|Path: cantaloupe....|
|file:/home/alext/...|Xref: cantaloupe....|
|file:/home/alext/...|Path: cantaloupe....|
|file:/home/alext/...|Newsgroups: sci.e...|
|file:/home/alext/...|Newsgroups: sci.e...|
|file:/home/alext/...|Newsgroups: sci.e...|
+--------------------+--------------------+
only showing top 20 rows

在任何数据科学项目中,查看数据都很重要。在处理结构化数据,尤其是数值数据时,通常会使用聚合来探索数据。这是必要的,因为数据集很大,并且查看少量示例很容易导致数据的错误表示。自然语言数据使这一点变得复杂。一方面,人类真的很擅长解释语言;另一方面,人类也非常擅长草率下结论和草率概括。因此,我们仍然存在为大型数据集创建具有代表性的摘要的问题。我们将在第10章和 第11章讨论一些技术来做到这一点。

现在,让我们谈谈我们可以查看 s 中的少量数据的方法DataFrame正如您在前面的代码示例中看到的,我们可以显示DataFrameusing的输出.show()

让我们看看论据:

  1. n:要显示的行数。
  2. truncate: 如果设置为 True,则默认截断长度超过 20 个字符的字符串。如果设置为大于一的数字,则将长字符串截断为长度truncate并右对齐单元格。
  3. vertical:如果设置为 True,则垂直打印输出行(每列值一行)。

让我们尝试使用其中一些参数:

texts_df.show(n=5, truncate=100, vertical=True)
-RECORD 0--------------------------------------------------------------------------------------------------------
 filename | file:/home/alext/projects/spark-nlp-book/data/mini_newsgroups/sci.electronics/54165                  
 text     | Path: cantaloupe.srv.cs.cmu.edu!magnesium.club.cc.cmu.edu!news.sei.cmu.edu!cis.ohio-state.edu!zap... 
-RECORD 1--------------------------------------------------------------------------------------------------------
 filename | file:/home/alext/projects/spark-nlp-book/data/mini_newsgroups/sci.electronics/54057                  
 text     | Newsgroups: sci.electronics
Path: cantaloupe.srv.cs.cmu.edu!magnesium.club.cc.cmu.edu!news.sei.cm... 
-RECORD 2--------------------------------------------------------------------------------------------------------
 filename | file:/home/alext/projects/spark-nlp-book/data/mini_newsgroups/sci.electronics/53712                  
 text     | Newsgroups: sci.electronics
Path: cantaloupe.srv.cs.cmu.edu!das-news.harvard.edu!noc.near.net!how... 
-RECORD 3--------------------------------------------------------------------------------------------------------
 filename | file:/home/alext/projects/spark-nlp-book/data/mini_newsgroups/sci.electronics/53529                  
 text     | Newsgroups: sci.electronics
Path: cantaloupe.srv.cs.cmu.edu!crabapple.srv.cs.cmu.edu!bb3.andrew.c... 
-RECORD 4--------------------------------------------------------------------------------------------------------
 filename | file:/home/alext/projects/spark-nlp-book/data/mini_newsgroups/sci.electronics/54042                  
 text     | Xref: cantaloupe.srv.cs.cmu.edu comp.os.msdos.programmer:23292 alt.msdos.programmer:6797 sci.elec... 
only showing top 5 rows 

.show()方法适用于快速查看数据,但如果数据复杂,则效果不佳。在 Jupyter 环境中,与 pandas 有一些特殊的集成,pandasDataFrame的显示更好一些。表 1-1是一个示例。

texts_df.limit(5).toPandas()

表 1-1。Jupyter 笔记本中的 pandas DataFrame 输出

filenametext
0file:/home/alext/projects/spark-nlp-book/data...Path: cantaloupe.srv.cs.cmu.edu!magne...
1file:/home/alext/projects/spark-nlp-book/data...Newsgroups: sci.electronics\nPath: cant...
2file:/home/alext/projects/spark-nlp-book/data...Newsgroups: sci.electronics\nPath: cant...
3file:/home/alext/projects/spark-nlp-book/data...Newsgroups: sci.electronics\nPath: cant...
4file:/home/alext/projects/spark-nlp-book/data...Xref: cantaloupe.srv.cs.cmu.edu comp.o...

注意使用.limit(). 该.toPandas()方法将 Spark 拉DataFrame入内存以创建 pandas DataFrame。转换为 pandas 对于使用 Python 中可用的工具也很有用,因为 PandasDataFrame 在 Python 生态系统中得到广泛支持。

对于其他类型的可视化,我们将主要使用 Python 库 matplotlib 和 seaborn。为了使用这些库,我们需要创建 pandas DataFrame,因此我们将聚合或采样 SparkDataFrame到一个可管理的尺寸.

使用 Spark NLP 的 Hello World

我们有一些数据,所以让我们使用 Spark NLP 来处理它。首先,让我们从文件名中提取新闻组名称。我们可以将新闻组视为文件名中的最后一个文件夹。表 1-2显示了结果。

texts_df = texts_df.withColumn(
    'newsgroup', 
    fun.split('filename', '/').getItem(7)
)


texts_df.limit(5).toPandas()

 表 1-2。带有新闻组列的表

filenametextnewsgroup
0file:/home/alext/projects/spark...Path: cantaloupe.srv.cs.cmu.edu!mag...sci.electronics
1file:/home/alext/projects/spark...Newsgroups: sci.electronics\nPath: ca...sci.electronics
2file:/home/alext/projects/spark...Newsgroups: sci.electronics\nPath: ca...sci.electronics
3file:/home/alext/projects/spark...Newsgroups: sci.electronics\nPath: ca...sci.electronics
4file:/home/alext/projects/spark...Xref: cantaloupe.srv.cs.cmu.edu comp...sci.electronics

让我们看看每个新闻组中有多少文档。图 1-1显示了条形图。 

newsgroup_counts = texts_df.groupBy('newsgroup').count().toPandas()


newsgroup_counts.plot(kind='bar', figsize=(10, 5)) 
plt.xticks( 
    ticks=range(len(newsgroup_counts)), 
    labels=newsgroup_counts['newsgroup'] 
) 
plt.show()

 因为 mini_newsgroups 数据集是二十个新闻组数据集的子集,所以我们在每个新闻组中拥有相同数量的文档。现在,让我们使用Explain Document ML

from sparknlp.pretrained import PretrainedPipeline

explain_document_ml是一个预训练的管道,我们可以使用它通过一个执行基本处理步骤的简单管道来处理文本。为了了解它在explain_document_ml做什么,有必要简要描述注释器是什么。注释器是特定 NLP 技术的表示。当我们进入第 3 章时,我们会更深入地进行讨论。

注释器处理文档,即文本、相关元数据和任何先前发现的注释。这种设计有助于注释者重用以前的注释者的工作。缺点是它比 NLTK 等库更复杂,NLTK 是 NLP 函数的非耦合集合。

explain_document_ml一个Transformer和六个注释器:

DocumentAssembler :ATransformer创建包含文档的列。

Sentence Segmenter :产生文档句子的注释器。

Tokenizer :产生句子标记的注释器。

SpellChecker :产生拼写更正标记的注释器。

Stemmer :生成标记词干的注释器。

Lemmatizer :产生标记的引理的注释器。

POS Tagger :产生相关标记的词性的注释器。

这里介绍了一些新术语,我们将在接下来的章节中进行更多讨论:

pipeline = PretrainedPipeline('explain_document_ml', lang='en')

.annotate()方法BasicPipeline可用于注释单数字符串,也可用于DataFrames。让我们看看它产生了什么。

pipeline.annotate('Hellu wrold!')
{'document': ['Hellu wrold!'],
'spell': ['Hello', 'world', '!'],
'pos': ['UH', 'NN', '.'],
'lemmas': ['Hello', 'world', '!'],
'token': ['Hellu', 'wrold', '!'],
'stems': ['hello', 'world', '!'],
'sentence': ['Hellu wrold!']}

这是大量的附加信息,它带来了一些你需要记住的东西——注释可以产生很多额外的数据。

让我们看一下原始数据的架构。

texts_df.printSchema()
root
 |-- filename: string (nullable = true)
 |-- text: string (nullable = true)
 |-- newsgroup: string (nullable = true)

现在,让我们注释我们的DataFrame并查看新模式。

procd_texts_df = basic_pipeline.annotate(texts_df, 'text')

procd_texts_df.printSchema()
root
 |-- filename: string (nullable = true)
 |-- text: string (nullable = true)
 |-- newsgroup: string (nullable = true)
 |-- document: array (nullable = true)
 |    |-- element: struct (containsNull = true)
 |    |    |-- annotatorType: string (nullable = true)
 |    |    |-- begin: integer (nullable = false)
 |    |    |-- end: integer (nullable = false)
 |    |    |-- result: string (nullable = true)
 |    |    |-- metadata: map (nullable = true)
 |    |    |    |-- key: string
 |    |    |    |-- value: string (valueContainsNull = true)
 |    |    |-- embeddings: array (nullable = true)
 |    |    |    |-- element: float (containsNull = false)
 |    |    |-- sentence_embeddings: array (nullable = true)
 |    |    |    |-- element: float (containsNull = false)
 |-- sentence: array (nullable = true)
 |    |-- element: struct (containsNull = true)
 |    |    |-- annotatorType: string (nullable = true)
...

该架构非常复杂!为了分解它,让我们看一下令牌列。它有一个Array类型列,每个元素都是一个Struct. 每个元素具有以下内容:

annotatorType :注释的类型。

begin :注释的起始字符位置。

end :注释结束后的字符位置。

result :注释器的输出。

metadata :一个MapStringString包含关于注释的附加的、可能有用的信息。

让我们看一些使用.show().

procd_texts_df.show(n=2)
+--------------------+--------------------+---------------+---------
-----------+--------------------+--------------------+--------------
------+--------------------+--------------------+-------------------
-+
|            filename|                text|      newsgroup|         
   document|            sentence|               token|              
 spell|              lemmas|               stems|                 po
s|
+--------------------+--------------------+---------------+---------
-----------+--------------------+--------------------+--------------
------+--------------------+--------------------+-------------------
-+
|file:/home/alext/...|Path: cantaloupe....|sci.electronics|[[documen
t, 0, 90...|[[document, 0, 46...|[[token, 0, 3, Pa...|[[token, 0, 3,
 Pa...|[[token, 0, 3, Pa...|[[token, 0, 3, pa...|[[pos, 0, 3, NNP,..
.|
|file:/home/alext/...|Newsgroups: sci.e...|sci.electronics|[[documen
t, 0, 19...|[[document, 0, 40...|[[token, 0, 9, Ne...|[[token, 0, 9,
 Ne...|[[token, 0, 9, Ne...|[[token, 0, 9, ne...|[[pos, 0, 9, NNP,..
.|
+--------------------+--------------------+---------------+---------
-----------+--------------------+--------------------+--------------
------+--------------------+--------------------+-------------------
-+
only showing top 2 rows

这不是很可读。不仅自动格式化对这些数据表现不佳,而且我们几乎看不到我们的注释。让我们尝试使用其他一些参数。

procd_texts_df.show(n=2, truncate=100, vertical=True)
-RECORD 0-----------------------------------------------------------
----------------------------------------------
 filename  | file:/home/alext/projects/spark-nlp-book/data/mini_news
groups/sci.electronics/54165                  
 text      | Path: cantaloupe.srv.cs.cmu.edu!magnesium.club.cc.cmu.e
du!news.sei.cmu.edu!cis.ohio-state.edu!zap... 
 newsgroup | sci.electronics                                        
                                              
 document  | [[document, 0, 903, Path: cantaloupe.srv.cs.cmu.edu!mag
nesium.club.cc.cmu.edu!news.sei.cmu.edu!ci... 
 sentence  | [[document, 0, 468, Path: cantaloupe.srv.cs.cmu.edu!mag
nesium.club.cc.cmu.edu!news.sei.cmu.edu!ci... 
 token     | [[token, 0, 3, Path, [sentence -> 0], [], []], [token, 
4, 4, :, [sentence -> 0], [], []], [token,... 
 spell     | [[token, 0, 3, Path, [sentence -> 0], [], []], [token, 
4, 4, :, [sentence -> 0], [], []], [token,... 
 lemmas    | [[token, 0, 3, Path, [sentence -> 0], [], []], [token, 
4, 4, :, [sentence -> 0], [], []], [token,... 
 stems     | [[token, 0, 3, path, [sentence -> 0], [], []], [token, 
4, 4, :, [sentence -> 0], [], []], [token,... 
 pos       | [[pos, 0, 3, NNP, [word -> Path], [], []], [pos, 4, 4, 
:, [word -> :], [], []], [pos, 6, 157, JJ,... 
-RECORD 1-----------------------------------------------------------
----------------------------------------------
 filename  | file:/home/alext/projects/spark-nlp-book/data/mini_news
groups/sci.electronics/54057                  
 text      | Newsgroups: sci.electronics
Path: cantaloupe.srv.cs.cmu.edu!magnesium.club.cc.cmu.edu!news.sei.c
m... 
 newsgroup | sci.electronics                                        
                                              
 document  | [[document, 0, 1944, Newsgroups: sci.electronics Path: 
cantaloupe.srv.cs.cmu.edu!magnesium.club.c... 
 sentence  | [[document, 0, 408, Newsgroups: sci.electronics Path: c
antaloupe.srv.cs.cmu.edu!magnesium.club.cc... 
 token     | [[token, 0, 9, Newsgroups, [sentence -> 0], [], []], [t
oken, 10, 10, :, [sentence -> 0], [], []],... 
 spell     | [[token, 0, 9, Newsgroups, [sentence -> 0], [], []], [t
oken, 10, 10, :, [sentence -> 0], [], []],... 
 lemmas    | [[token, 0, 9, Newsgroups, [sentence -> 0], [], []], [t
oken, 10, 10, :, [sentence -> 0], [], []],... 
 stems     | [[token, 0, 9, newsgroup, [sentence -> 0], [], []], [to
ken, 10, 10, :, [sentence -> 0], [], []], ... 
 pos       | [[pos, 0, 9, NNP, [word -> Newsgroups], [], []], [pos, 
10, 10, :, [word -> :], [], []], [pos, 12,... 
only showing top 2 rows

更好,但这对于我们的语料库的一般理解仍然没有用。我们至少可以看到我们的管道在做什么。

现在,我们需要提取我们可能希望在其他流程中使用的信息——这就是为什么存在Finisher Transformer.Finisher接受注释并提取我们将在下游流程中使用的数据片段。这允许我们在通用 Spark 中使用 NLP 管道的结果。现在,让我们拉出所有的引理并将它们放入 aString中,用空格分隔。

from sparknlp import Finisher

finisher = Finisher()
finisher = finisher
# 取引理列
finisher = finisher.setInputCols(['lemmas'])
# 用一个空格分隔引理
finisher = finisher.setAnnotationSplitSymbol(' ')

finished_texts_df = finisher.transform(procd_texts_df)

finished_texts_df.show(n=1, truncate=100, vertical=True)
-RECORD 0-----------------------------------------------------------
----------------------------------------------------
filename        | file:/home/alext/projects/spark-nlp-book/data/mini
_newsgroups/sci.electronics/54165                  
text            | Path: cantaloupe.srv.cs.cmu.edu!magnesium.club.cc.
cmu.edu!news.sei.cmu.edu!cis.ohio-state.edu!zap...
newsgroup       | sci.electronics                                   
                                                   
finished_lemmas | [Path, :, cantaloupe.srv.cs.cmu.edu!magnesium.club
.cc.cmu.edu!news.sei.cmu.edu!cis.ohio-state.edu...
only showing top 1 row

通常,我们将使用该.setOutputAsArray(True)选项,以便输出是 aArray而不是 a String

让我们看看第一个文档的最终结果。

finished_texts_df.select('finished_lemmas').take(1)
[Row(finished_lemmas=['Path', ':', 'cantaloupe.srv.cs.cmu.edu!magnes
ium.club.cc.cmu.edu!news.sei.cmu.edu!cis.ohio-state.edu!zaphod.mps.o
hio-state.edu!news.acns.nwu.edu!uicvm.uic.edu!u19250', 'Organization
', ':', 'University', 'of', 'Illinois', 'at', 'Chicago', ',', 'acade
mic', 'Computer', 'Center', 'Date', ':', 'Sat', ',', '24', 'Apr', '1
993', '14:28:35', 'CDT', 'From', ':', '<U19250@uicvm.uic.edu>', 'Mes
sage-ID', ':', '<93114.142835U19250@uicvm.uic.edu>', 'Newsgroups', '
:', 'sci.electronics', 'Subject', ':', 'multiple', 'input', 'for', '
PC', 'Lines', ':', '8', 'Can', 'anyone', 'offer', 'a', 'suggestion',
 'on', 'a', 'problem', 'I', 'be', 'have', '?', 'I', 'have', 'several
', 'board', 'whose', 'sole', 'purpose', 'be', 'to', 'decode', 'DTMF'
, 'tone', 'and', 'send', 'the', 'resultant', 'in', 'ASCII', 'to', 'a
', 'PC', '.', 'These', 'board', 'run', 'on', 'the', 'serial', 'inter
face', '.', 'I', 'need', 'to', 'run', '*', 'of', 'the', 'board', 'so
mewhat', 'simultaneously', '.', 'I', 'need', 'to', 'be', 'able', 'to
', 'ho', 'ok', 'they', 'up', 'to', 'a', 'PC', '>', 'The', 'problem',
 'be', ',', 'how', 'do', 'I', 'hook', 'up', '8', '+', 'serial', 'dev
ice', 'to', 'one', 'PC', 'inexpensively', ',', 'so', 'that', 'all', 
'can', 'send', 'data', 'simultaneously', '(', 'or', 'close', 'to', '
it', ')', '?', 'Any', 'help', 'would', 'be', 'greatly', 'appreciate'
, '!', 'Achin', 'Single'])]

看起来这里没有做太多事情,但仍有很多事情要解开。在下一章中,我们将解释一些语言学的基础知识,这将有助于我们理解这些注释器在做什么。

  • 7
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值