1. 程式人生 > >乾貨:基於Spark Mllib的SparkNLP庫。

乾貨:基於Spark Mllib的SparkNLP庫。

640?wx_fmt=png&wxfrom=5&wx_lazy=1

引言

這是來自John Snow Labs工程團隊的社群部落格和工作,解釋了他們對開源Apache Spark自然語言處理(NLP)庫的貢獻。

Apache Spark是一個通用的叢集計算框架,它支援分散式SQL,流式處理,圖處理和機器學習。現在,Spark生態系統還有一個Spark Natural Language Processing庫。

John Snow Labs NLP庫是在Scala編寫的Apache 2.0以上,不依賴於其他NLP或ML庫。它本地擴充套件了Spark ML管道API。該框架提供了註釋器的概念,並帶出了以下內容:

  • 標記生成器

  • 規範化

  • 詞幹提取

  • Lemmatizer

  • 實體提取器

  • 日期提取器

  • Part of Speech Tagger

  • 命名實體識別

  • 句子邊界檢測

  • 情感分析

  • 拼寫檢查器

另外,由於與Spark ML的緊密整合,在構建NLP管道時,您可以直接使用Spark的更多功能。這包括詞語嵌入,主題建模,停用詞移除,各種特徵工程功能(tf-idf,n-gram,相似性度量等)以及在機器學習工作流中使用NLP註釋作為特徵。如果您不熟悉這些術語,那麼理解NLP任務的指南是一個好的開始。

0?wx_fmt=png

Spark ML提供了一套機器學習應用程式,它的邏輯由兩個主要元件組成:估計器(Estimators)和 變換器(Transformers)。首先,有一個稱為fit()的方法,將一段資料儲存並傳遞給這樣的應用程式,Transformer(一般是擬合過程的結果)將更改應用於目標資料集。這些元件已嵌入到適用於Spark NLP。 管道是允許單個工作流程中包含多個估計器和變換器的機制,允許沿機器學習任務進行多個連結轉換。

註釋(Annotation)

註釋是Spark-NLP操作結果的基本形式。它的結構是由:

  • annotatorType: 哪個註釋器生成了這個註釋

  • begin: 匹配的內容相對於原始文字的開始。

  • end: 匹配的內容相對於原始文字的結尾

  • metadata: 匹配結果的內容和附加資訊

該物件在轉換處理結束後由註釋器自動生成。不需要手動參與。但為了有效地使用它,必須按照順序理解。

註解器(Annotators)

註解器是SparkNLP中NLP功能的先鋒。有兩種形式的註釋器

  • 註解器方法:代表Spark ML Estimator並需要一個訓練stage。他們有一個稱為fit(data)的函式,它根據一些資料來訓練一個模型。他們生產第二種型別的註釋器,它是一個註釋器模型或轉換器(transformer)。

  • Annotator模型:它們是spark模型或轉換器(transformer),意味著它們具有一個transform(data)函式,它接受一個數據集並新增一個帶有這個標註結果的列。所有轉換器(transformer)都是附加的,這意味著它們附加到當前資料,決不會替換或刪除以前的資訊。

這兩種形式的註釋器都可以包含在Pipeline中,並且會自動按照提供的順序遍歷所有階段並相應地轉換資料。在fit()階段之後,Pipeline變成了PipelineModel。無論是之前還是之後,可以隨時儲存到磁碟並重新從磁碟載入。

公共函式

setInputCols(column_names):獲取此註釋器所需的註釋列名稱

setOutputCol( column_name):定義包含此註釋器結果的列的名稱。使用此名稱作為其他註釋器的輸入,需要註釋這個註釋器。

例子分析

1 註釋器型別

每個註釋器都有一個型別。這些共享型別的註釋器可以互換使用,這意味著您可以在需要時使用它們中的任何一個。例如,當另一個註釋器(如情感分析註釋器)需要令牌型別註釋器時,可以提供標normalized token或lemma,因為兩者都是型別標記。

2 使用spark讀入資料

我們例子測試採用的是spark-shell的方式,spark-2.1.1版本以上,本文采用的是spark2.1.2,scala版本2.11.8,啟動:

spark-shell --jars /opt/jars/spark-nlp-1.2.3.jar

3 載入資料並測試,

0?wx_fmt=png

我們這裡是先把資料賦值為名為data的變數

val data = spark.read.parquet("file:///opt/datas/*")

0?wx_fmt=png

4 DocumentAssembler:獲取資料

為何貫穿NLP處理過程,我們需要將原始資料進行標註。有一個特殊的transformer為我們做這件事情:DocumentAssembler,它會建立第一個型別為Document的註釋,該註釋會被以後的註解器使用。

importcom.johnsnowlabs.nlp._

importcom.johnsnowlabs.nlp.annotators._

importorg.apache.spark.ml.Pipeline

valdocumentAssembler = new DocumentAssembler()

.setInputCol("text")

.setOutputCol("document")

5 句子檢測及分詞

在這個快速的例子中,我們現在開始在每個文件行中標識句子。SentenceDetectorModel需要一個由DocumentAssembler輸出提供的Document註釋,它本身是一個Document型別標記。RegexTokenizer需要一個Document註釋型別,這意味著它與DocumentAssemblerSentenceDetector輸出一起工作,在這裡,我們使用句子輸出。

importcom.johnsnowlabs.nlp.annotators.sbd.pragmatic.SentenceDetectorModel

valsentenceDetector= new SentenceDetectorModel()

.setInputCols(Array("document"))

.setOutputCol("sentence")

valregexTokenizer= new RegexTokenizer()

.setInputCols(Array("sentence"))

.setOutputCol("token")

6 使用管道(pipeline)

現在我們要把所有這些放在一起並檢索結果,我們使用Pipeline來做到這一點。我們還包含另一個特殊的變形器,稱為“ Finisher”,以人類語言顯示標記

val finisher = new Finisher()

.setInputCols("token")

.setCleanAnnotations(false)

val pipeline = new Pipeline()

.setStages(Array(

documentAssembler,

sentenceDetector,

regexTokenizer,

       finisher

))

pipeline

.fit(data)

.transform(data)

.show()

0?wx_fmt=png

也可以按照spark的輸出檔案的格式儲存結果,比如:

pipeline.fit(data).transform(data).toJSON.write.text("file:///opt/output")

7 輸出為

0?wx_fmt=png

推薦閱讀:

關注公眾號。輸入:nlp,即可獲得本文設計的專案工程和jar及本文中的案例程式碼。

640.png

關於Spark高階玩法

kafkahbasespark,Flink等入門到深入源碼,spark機器學習,大資料安全,大資料運維,請關注浪尖公眾號,看高質量文章。

640.jpeg

更多文章,敬請期待