Spark NLP 中使用 BERT 的命名實體識別 (NER)

2022-01-01 機器AI學習 數據AI挖掘

關注公眾號,回復「spark nlp」獲取原始碼:

使用 Spark NLP 中的幾行代碼使用 BERT 訓練 NER 並獲得 SOTA 準確性.

NER 是信息提取的一個子任務,旨在將非結構化文本中提到的命名實體定位和分類為預定義的類別,例如人名、組織、位置、醫療代碼、時間表達式、數量、貨幣價值、百分比等。

NER 用於自然語言處理 (NLP) 的許多領域,它可以幫助回答許多現實世界的問題,例如:

新聞文章中提到了哪些公司?

哪些測試適用於患者(臨床報告)?

推文中是否提到了產品名稱?

                                Spark NLP 庫中的臨床 NER 模型

NER系統

NER 是 NLP 中的一個活躍話題,多年來研究工作不斷發展。我們可以在以下主題中總結這些努力:

經典方法(基於規則)

機器學習方法

3. 深度學習方法

雙向 LSTM-CRF

雙向 LSTM-CNN

雙向 LSTM-CNNS-CRF

預訓練語言模型(Elmo和BERT)

4.混合方法(DL + ML)

在 Spark NLP 中使用 BERT 的 NER

在 本文中,我們將嘗試向您展示如何使用Spark NLP 庫中的 BERT 構建最先進的 NER 模型。我們將要實現的模型的靈感來自於 NER 以前最先進的模型:Chiu 和 Nicols,使用雙向 LSTM-CNN 命名實體識別, 並且它已經嵌入到 Spark NLP NerDL Annotator 中。這是一種新穎的神經網絡架構,可使用混合雙向 LSTM 和 CNN 架構自動檢測單詞和字符級特徵,無需進行大多數特徵工程。

在開發該模型時,還沒有類似 BERT 的語言模型,原始論文中使用的是 Glove 詞嵌入。但在本文中,我們將用 BERT 替換 Glove。

在 Spark NLP 中,有三種不同的預訓練詞嵌入模型(及其變體),您可以根據使用情況即插即用。

為了簡單起見並節省您一些時間,我們將跳過安裝步驟。我們已經有另一篇文章詳細介紹了 Spark NLP。而且我們會在Colab 中完成所有工作,讓您直接跳入 Spark NLP。

讓我們開始吧!

我們首先下載訓練和測試集。我們將使用官方的 CoNLL2003 數據集,這是一個幾乎所有 NER 論文中都使用過的基準數據集。您可以在此處下載此數據集。

讓我們簡要解釋一下什麼是 CoNLL。「 Conference on Natural Language Learning」的縮寫, CoNLL 也是訓練集中用於訓練 NER 模型的注釋的標準格式。這是它的外觀。您可以在 CONLL 中注釋自己的數據,然後在 Spark NLP 中訓練自定義 NER。還有一些免費的注釋工具可用於標記自己的數據。

下面是我們要一一解釋的流程。

我們導入相關的包,然後開始編碼。

from pyspark.sql import SparkSession
from pyspark.ml import pipelinefrom sparknlp.annotator import *
from sparknlp.common import *
from sparknlp.base import *import sparknlp
spark = sparknlp.start()print("Spark NLP 版本:", sparknlp.version())
print("Apache Spark 版本:", spark.version)>> Spark NLP 版本:2.4.1
>> Apache Spark 版本:2.4.4

如果您想在 GPU 上訓練您的模型,您只需使用spark = sparknlp(gpu=True).

然後我們將 CoNLL 文件轉換為 Spark 數據幀,並生成所有附加欄位以供稍後使用。

from sparknlp.training import CoNLL
training_data = CoNLL().readDataset(spark, './eng.train')
training_data.show()

如您所見,輸入數據集只有行和標籤,現在我們這裡有幾列。我們在 Spark NLP 中的 CoNLL 助手類將數據集作為輸入並準備我們將要使用的 NER 算法所需的標記、POS(詞性)和句子。您需要做的就是準備或下載 CoNLL 格式的數據集。

(注意:儘管原始論文建議使用 POS,但在 Spark NLP 訓練時不會使用它。由於 POS 標籤是 CONLL 格式,因此 CoNLL 助手類從作為輸入給出的 CoNLL 文件中提取它們。因此,我們甚至可以在該源 CoNLL 文件中使用 -X- 而不是 POS 標籤。)

下一步是通過BERT得到詞嵌入。我們將使用名為BertEmbeddings().

bert = BertEmbeddings.pretrained('bert_base_cased', 'en') \ .setInputCols(["sentence",'token'])\
.setOutputCol("bert")\
.setCaseSensitive(False)\
.setPoolingLayer(0) # default 0

在 Spark NLP 中,我們有四個預訓練的 BERT 變體:bert_base_uncased、bert_base_cased、bert_large_uncased、bert_large_cased。使用哪一個取決於您的用例、訓練集以及您嘗試建模的任務的複雜性。

在上面的代碼片段中,我們基本上是bert_base_cased從 Spark NLP 公共資源中加載版本並指向sentence和token列setInputCols().簡而言之,BertEmbeddings()注釋器將獲取sentence和token列並在bert列中填充 Bert 嵌入。一般來說,每個詞都被翻譯成一個 768 維的向量。所述參數setPoolingLayer()可以被設置為0作為第一層和最快的,-1作為最後的層和-2作為second-to-last-hidden layer。

正如官方BERT 論文的作者所解釋的,不同的 BERT 層捕獲不同的信息。最後一層在預訓練過程中與目標函數(即掩碼語言模型和下一句預測)過於接近,因此可能會偏向那些目標。如果您無論如何都想使用最後一個隱藏層,請隨意設置pooling_layer=-1. 直覺上,pooling_layer=-1接近於訓練輸出,所以可能會偏向於訓練目標。如果您不對模型進行微調,則可能會導致不良表示。也就是說,這是模型準確性和您擁有的計算資源之間的權衡問題。

然後我們導入NerDLApproach()annotator,它是負責訓練 NER 模型的主要模塊。

nerTagger = NerDLApproach()\
.setInputCols(["sentence", "token", "bert"])\
.setLabelColumn("label")\
.setOutputCol("ner")\
.setMaxEpochs(1)\
.setRandomSeed(0) )\
.setVerbose(1)\
.setValidationSplit(0.2)\
.setEvaluationLogExtended(True)\
.setEnableOutputLogs(True)\
.setIncludeConfidence(True)\
.setTestDataset("test_withEmbeds.parquet")

讓我們解釋一下每個參數:

.setInputCols([「sentence」, 「token」, 「bert」]) : NER 模型將用於生成特徵的列。

.setLabelColumn(「label」) : 目標列

.setOutputCol(「ner」):預測將寫入ner列

.setMaxEpochs(1) : 訓練的時期數

.setVerbose(1) : 訓練時的日誌級別

.setValidationSplit(0.2):要在每個 Epoch 上針對模型進行驗證的訓練數據集的比例。該值應介於 0.0 和 1.0 之間,默認情況下為 0.0 和關閉。

.setEvaluationLogExtended(True):是否要擴展驗證日誌:它顯示每個標籤的時間和評估。默認值為假。

.setEnableOutputLogs(True): 是否輸出到日誌文件夾。設置為 True 時,日誌和訓練指標將寫入主文件夾中的文件夾。

.setIncludeConfidence(True) :是否在注釋元數據中包含置信度分數。

.setTestDataset(「test_withEmbeds.parquet」): 測試數據集的路徑。如果設置,則用於在訓練期間計算其統計信息。這也是 CoNLL 格式,但嵌入添加並像以前一樣保存到磁碟。如果您不需要在 Spark 中看不見的測試集上評估您的模型,則不必設置此項。

test_data = CoNLL().readDataset(spark, './eng.testa')
test_data = bert.transform(test_data)
test_data.write.parquet("test_withEmbeds.parquet")

您還可以設置學習率 ( setLr)、學習率衰減係數 ( setPo)setBatchSize和setDropout速率。有關整個列表,請參閱官方存儲庫。

現在我們可以將這兩個注釋器附加到管道中。

ner_pipeline = Pipeline(stages = [bert, nerTagger])ner_model = ner_pipeline.fit(training_data)

根據數據集大小和您設置的時期數完成擬合後,就可以使用了。讓我們看看僅 1 個時期後日誌的樣子(annotators_log在您的主文件夾中的文件夾內)。

您可以在Colab實例的根目錄中找到該文件夾。

總之,我們只需在 Spark NLP 中使用幾行代碼就可以在 SOTA 算法中訓練自定義 NER。


並在另一個pipeline中使用

訓練pipeline 並預測

text = "Peter Parker is a nice man and lives in New York"prediction_data = spark.createDataFrame([[text]]).toDF("text")prediction_model = custom_ner_pipeline.fit(prediction_data)preds = prediction_model.transform(prediction_data)preds.show()

我們還可以編寫一些 PySpark 函數,在 NerConverter 的幫助下使輸出更漂亮和有用ner_span。

我們還可以將此管道轉換為 LightPipeline 以擺脫 Spark 開銷並進行閃電般的速度推理。將任何擬合的管道轉換為 LightPipeline 後,您可以輕鬆地更快地獲得字符串或字符串列表的預測。您可以在此處找到有關 LightPipelines 的更多詳細信息。

所有代碼都可以在Github 上找到。在我們通過 Github 分享的筆記本中,您甚至會看到其他各種嵌入的實現,以及如何準備自己的 CoNLL 文件來訓練自定義 NER 模型。

結論

目前為止就這樣了。在本文中,我們討論了如何使用 NLP 鎮上最酷的孩子 BERT 在 Spark NLP 中訓練最先進的 NER 模型。我希望你喜歡!

相關焦點

  • NLP 詳解教程:使用 Spacy 和 Python 實現命名實體識別 (NER)
    本文的目的是介紹NLP中的一項關鍵任務,即命名實體識別(NER)。目的是能夠提取文本語料庫中的公共實體。例如,在給定的文本(例如電子郵件或文檔)中檢測人員,地點,藥品,日期等。在這篇hand-on文章中,我們將使用Spacy庫訓練基於神經網絡的深度學習模型,以從文本數據中檢測實體。我們還將展示的一件事是如何標記數據,並且在許多文章中經常被忽略。我們還將使用更強力的模式匹配將深度學習進行比較。
  • NLP入門(四)命名實體識別(NER)
    本文將會簡單介紹自然語言處理(NLP)中的命名實體識別(NER)。  命名實體識別(Named Entity Recognition,簡稱NER)是信息提取、問答系統、句法分析、機器翻譯等應用領域的重要基礎工具,在自然語言處理技術走向實用化的過程中佔有重要地位。
  • 【NLP】流水的NLP鐵打的NER:命名實體識別實踐與探索
    作者:王嶽王院長知乎:https://www.zhihu.com/people/wang-yue-40-21github: https://github.com/wavewangyue編輯:yuquanle前言最近在做命名實體識別(Named Entity Recognition
  • 命名實體識別的兩種方法
    ——命名實體識別的兩種方法。總結 一 、什麼是命名實體識別?命名實體識別(Named Entity Recognition,簡稱NER),又稱作「專名識別」,是指識別文本中具有特定意義的實體,主要包括人名、地名、機構名、專有名詞等。
  • 流水的NLP鐵打的NER:命名實體識別實踐與探索
    21github: https://github.com/wavewangyue編輯:yuquanle前言最近在做命名實體識別就這樣還是先放結論命名實體識別雖然是一個歷史悠久的老任務了,但是自從2015年有人使用了BI-LSTM-CRF模型之後,這個模型和這個任務簡直是郎才女貌,天造地設,輪不到任何妖怪來反對。直到後來出現了BERT。在這裡放兩個問題:2015-2019年,BERT出現之前4年的時間,命名實體識別就只有 BI-LSTM-CRF 了嗎?
  • 中文命名實體識別工具(NER)哪家強?
    ,例如輸入 「中文分詞 我愛自然語言處理」,「詞性標註 我愛NLP」,「情感分析 自然語言處理愛我","Stanza 52nlp" 等,具體可參考下述文章:史丹福大學NLP組Python深度學習自然語言處理工具Stanza試用既然中文分詞、詞性標註已經有了,那下一步很自然想到的是命名實體識別(NER,Named-entity recognition)工具了,不過根據我目前了解到的情況
  • 初學者|一文讀懂命名實體識別
    命名實體識別(Named Entity Recognition,簡稱NER),又稱作「專名識別」,是指識別文本中具有特定意義的實體,主要包括人名、地名、機構名、專有名詞等。簡單的講,就是識別自然文本中的實體指稱的邊界和類別。
  • 基於Bert和通用句子編碼的Spark-NLP文本分類
    文本分類問題中使用了幾個基準數據集,可以在nlpprogress.com上跟蹤最新的基準。以下是關於這些數據集的基本統計數據。Spark-NLP中ClassifierDL和USE在文本分類的應用在本文中,我們將使用AGNews數據集(文本分類任務中的基準數據集之一)在Spark NLP中使用USE和ClassifierDL構建文本分類器,後者是Spark NLP 2.4.4版中添加的最新模塊。
  • 用Spark-NLP建立文本分類模型
    雖然這些轉換器和提取器足以構建基本的NLP管道,但是要構建一個更全面和生產級的管道,我們需要更先進的技術,如詞幹分析、詞法化、詞性標記和命名實體識別。Spark NLP提供了各種注釋器來執行高級NLP任務。
  • 【NLP基礎】信息抽取(Information Extraction:NER(命名實體識別),關係抽取)
    抽取文本數據中的名詞短語、人名、地名等都是文本信息抽取,當然,文本信息抽取技術所抽取的信息可以是各種類型的信息。本文介紹從文本中提取有限種類語義內容的技術。此信息提取過程(IE)將嵌入文本中的非結構化信息轉換為結構化數據,例如用於填充關係資料庫以支持進一步處理。命名實體識別(NER)的任務是找到文本中提到的每個命名實體,並標記其類型。
  • NLP入門從入門到實戰 實體命名識別 +中文預處理之繁簡體轉換及獲取拼音
    號稱最全的中文詞庫分析5:pyltp哈工大的語料分析庫,最近常用,效果還行,安裝較難,對環境考驗較大6:paddlehub百度的paddlehub封裝了例如LAC這樣的實體命名識別模型,使用起來速度特別快,效果也很棒!
  • 【NLP-NER】命名實體識別中最常用的兩種深度學習模型
    命名實體識別(Named Entity Recognition,NER)是NLP中一項非常基礎的任務。NER是信息提取、問答系統、句法分析、機器翻譯等眾多NLP任務的重要基礎工具。上一期我們介紹了NER的基本概念,大致介紹了NER常用的模型。本期我們詳細介紹目前NER最常用的兩種深度學習模型,LSTM+CRF和Dilated-CNN。
  • 2018年的一篇NER綜述筆記
    文章關鍵點筆記1 introduction命名實體識別的中的核心,命名實體(Named Entity)概念的出現其實並不久遠,1996年。時至今日,處理NER問題的主要有四種:基於規則的方法。無監督學習方法。基於特徵的機器學習方法。深度學習方法。我們其實可以看到,得益於機器學習方法,NER問題被更好的解決。
  • 【NLP】一文了解命名實體識別
    命名實體是命名實體識別的研究主體,而命名實體識別通常認為是從原始文本中識別有意義的實體或實體指代項的過程,即在文本中標識命名實體並劃分到相應的實體類型中,通常實體類型包括人名、地名、組織機構名、日期等。舉例說明,「當地時間 14 日下午,敘利亞一架軍用直升機在阿勒坡西部鄉村被一枚惡意飛彈擊中。」
  • 開源NLP項目推薦:Awesome-Chinese-NLP
    將提供中文分詞、詞性標註、命名實體識別、情感分析、知識圖譜關係抽取、關鍵詞抽取、文本摘要、新詞發現等常用自然語言處理功能。 使用預訓練語言模型BERT做中文NERInformation-Extraction-Chinese Chinese Named Entity Recognition with IDCNN/biLSTM+CRF, and Relation Extraction with biGRU+2ATT 中文實體識別與關係提取Familia 百度出品的 A Toolkit for Industrial
  • NLP入門篇:命名實體識別
    命名實體識別命名實體識別(Named Entity Recognition,NER)是 NLP 中一項非常基礎的任務。NER 是信息提取、問答系統、句法分析、機器翻譯等眾多 NLP 任務的重要基礎工具。命名實體識別是什麼要了解 NER ,首先要先明白,什麼是實體。
  • 用膨脹卷積進行命名實體識別 NER
    BiLSTM+CRF 是命名實體識別中最為流行的模型,但是 LSTM 需要按順序處理輸入的序列,速度比較慢。而採用 CNN 可以更高效的處理輸入序列,本文介紹一種使用膨脹卷積進行命名實體識別的方法 IDCNN,通過膨脹卷積可以使模型接收更長的上下文信息。
  • 當RNN神經網絡遇上NER(命名實體識別):雙向LSTM,條件隨機場(CRF),層疊Stack LSTM, 字母嵌入
    作者:David9地址:http://nooverfit.com/命名實體識別 (NER) 是語義理解中的一個重要課題
  • 近期做NER的反思
    往期回顧:NLP中有很多任務,但我其實花的集中時間最多的還是ner,也就是命名實體識別,希望這塊能成為自己最能拿出手的技能,慢慢成長吧。近期NER自己嘗試做很多提升開發效率和準招提升的調研,速度上是能有所提升,但是總會出現各種問題,這裡總結一下,這些問題估計在其他任務中也會經常出現,也供大家一起思考和進步。
  • 復旦邱錫鵬團隊最新成果fastHan:基於BERT的中文NLP集成工具
    其內核為基於 BERT 的聯合模型,其在 13 個語料庫中進行訓練,可處理中文分詞、詞性標註、依存句法分析、命名實體識別四項任務。fastHan 共有 base 與 large 兩個版本,分別利用 BERT 的前四層與前八層。base 版本在總參數量 150MB 的情況下各項任務均有不錯表現,large 版本則接近甚至超越 SOTA 模型。