用最新NLP庫Flair作文本分類

摘要: Flair是一個基於PyTorch構建的NLP開發包,它在解決命名實體識別(NER)、部分語音標註(PoS)、語義消歧和文本分類等NLP問題達到了當前的最高水準。它是一個創建在PyTorch之上的NLP框架。本文將介紹如何使用已有的和構建自定義的文本分類器。html

a1a7ac947dc9545462907b18b489ba4d33cdfbf8

介紹python

文本分類是一種監督機器學習方法,用於將句子或文本文檔歸類爲一個或多個已定義好的類別。它是一個被普遍應用的天然語言處理方法,在垃圾郵件過濾、情感分析、新聞稿件分類以及與許多其它業務相關的問題中發揮着重要做用。git

目前絕大多數最早進的方法都依賴於一種被稱爲文本嵌入的技術。它將文本轉換成高維空間中的數值表示方式。它能夠將文檔、語句、單詞、字符(取決於咱們所嵌入的形式)表示爲這個高維空間中的一個向量。github

Flair之因此對NLP來講是一個使人興奮的消息,是由於Zalando Research最近發表的一篇論文《Contextual String Embeddings for Sequence Labelling(用於序列標註的上下文相關字符串的嵌入)》,其中涵蓋了一種始終優於之前最早進方案的方法。該算法在Flair中獲得了完整的支持和實現,能夠用來構建文本分類器。算法

1、準備網絡

安裝Flair須要Python 3.6,若是你尚未,請點擊這裏查看安裝嚮導。而後執行pip命令安裝便可:框架

pip install flair

上面的命令將安裝運行Flair所需的全部依賴包,固然也包括了PyTorch。機器學習

2、使用一個預訓練的分類模型函數

最新的0.4版本包含了兩個預訓練的模型,還有一個基於IMDB數據集上訓練的情感分析模型和「攻擊性語言檢測」模型(當前僅支持德語)。性能

使用、下載和存儲模型都被整合到了一個單一的方法中,這使得使用預訓練模型的整個過程都很是簡單。

要使用情感分析模型,只需執行如下代碼片斷:

fromflair.models import TextClassifier
from flair.data import Sentence

classifier = TextClassifier.load('en-sentiment')

sentence = Sentence('Flair is pretty neat!')
classifier.predict(sentence)

# print sentence with predicted labels
print('Sentence above is: ', sentence.labels)

 

當第一次運行時,Flair將下載情感分析模型,默認狀況下將其存儲到home目錄下的.flair子目錄中,這大概得須要幾分鐘。

上面的代碼首先加載必需的庫,而後將情感分析模型加載到內存中(必要時先進行下載),接下來能夠預測句子「Flair is pretty neat!」的情感數值,按0到1的區間賦值。最後命令的輸出結果是:

The sentence above is: [Positive (1.0)]

就是這麼簡單!例如,如今你能夠將上述代碼合併在一個REST API中,並提供一個與Google的雲天然語言API的情感分析相似的服務,當在有大量請求的生產環境中使用時,這種分析的成本將會很是的高。

3、訓練一個自定義文本分類器

要訓練一個自定義的文本分類器,咱們首先須要一個標註過的數據集。Flair的分類數據集格式基於Facebook的FastText格式。格式要求在每行的開頭定義一個或多個標籤,之前綴__label__開頭。格式以下:

__label__<class_1><text>
__label__<class_2><text>

在本文中,咱們將利用Kaggle的Spam Detection數據集經過Flair構建一個垃圾/非垃圾的分類器。這個數據集比較適合咱們的學習任務,由於它足夠小,而且僅包含5572行的數據,能夠在一個CPU上只花幾分鐘就能夠完成一個模型的訓練。

60323e2f8bcf600ecae6834203305036681c5deb

來自數據集中的標記爲spam(垃圾郵件)或ham(非垃圾郵件)的SMS信息

3.1 預處理-構建數據集

咱們首先從Kaggle上的這個連接下載數據集來得到spam.csv文件。而後,在與數據集相同的目錄中,咱們運行下面的預處理代碼片斷,該代碼將執行一些預處理,並將數據集拆分爲訓練集、開發集和測試集三個部分。

確保安裝了Pandas。若是尚未,請先運行命令:

pip install pandas

import pandas as pd
data = pd.read_csv("./spam.csv", encoding='latin-1').sample(frac=1).drop_duplicates()

data = data[['v1', 'v2']].rename(columns={"v1":"label", "v2":"text"})

data['label'] = '__label__' + data['label'].astype(str)

data.iloc[0:int(len(data)*0.8)].to_csv('train.csv', sep='\t', index = False, header = False)
data.iloc[int(len(data)*0.8):int(len(data)*0.9)].to_csv('test.csv', sep='\t', index = False, header = False)
data.iloc[int(len(data)*0.9):].to_csv('dev.csv', sep='\t', index = False, header = False);

 

上面的代碼將從數據集中刪除一些重複數據,並對其進行無序處理(隨機化行),並按照80/10/10的比例將數據拆分爲訓練集、開發集和測試集。

若是運行成功,你將會獲得FastText格式的三個數據文件:train.csv、test.csv和dev.csv,它們能夠與Flair一塊兒使用。

3.2 訓練自定義文本分類模型

請在生成數據集的目錄中運行如下代碼片斷用以訓練模型:

fromflair.data_fetcher import NLPTaskDataFetcher
from flair.embeddings import WordEmbeddings, FlairEmbeddings, DocumentLSTMEmbeddings
from flair.models import TextClassifier
from flair.trainers import ModelTrainer
from pathlib import Path

corpus = NLPTaskDataFetcher.load_classification_corpus(Path('./'), test_file='test.csv', dev_file='dev.csv', train_file='train.csv')

word_embeddings = [WordEmbeddings('glove'), FlairEmbeddings('news-forward-fast'), FlairEmbeddings('news-backward-fast')]

document_embeddings = DocumentLSTMEmbeddings(word_embeddings, hidden_size=512, reproject_words=True, reproject_words_dimension=256)

classifier = TextClassifier(document_embeddings, label_dictionary=corpus.make_label_dictionary(), multi_label=False)

trainer = ModelTrainer(classifier, corpus)

trainer.train('./', max_epochs=10)

 

第一次運行上述代碼時,Flair將會自動下載須要的全部嵌入模型,這可能須要幾分鐘,而後接下來的整個培訓過程還須要大約5分鐘。

程序首先將所需的庫和數據集加載到一個corpus對象中。

接下來,咱們建立一個嵌入列表,包含兩個Flair上下文的字符串嵌入和一個GloVe單詞嵌入。而後將此列表做爲文檔嵌入對象的輸入。堆疊和文檔嵌入是Flair中最有趣的概念之一,提供了將不一樣的嵌入整合在一塊兒的方法。你能夠同時使用傳統的單詞嵌入(如GloVe, word2vec, ELMo)和Flair上下文的字符串嵌入。在上面的例子中,咱們使用了一種基於LSTM(Long Short-Term Memory,長短時間記憶網絡)的方法,將單詞和上下文的字符串嵌入結合起來以生成文檔嵌入。想要了解更多,請點擊這裏

最後,上述代碼進行模型訓練並生成了final-model.pt和best-model.pt兩個文件,它們表示咱們存儲的訓練模型。

3.3 用訓練過的模型進行預測

咱們如今能夠從同一目錄經過運行如下代碼,使用導出的模型來生成預測結果:

fromflair.models import TextClassifier
from flair.data import Sentence

classifier = TextClassifier.load_from_file('./best-model.pt')

sentence = Sentence('Hi. Yes mum, I will...')

classifier.predict(sentence)

print(sentence.labels)

 

這段代碼會輸出「[ham(1.0)]」,這意味着該模型100%肯定咱們的示例消息不是垃圾郵件。

與其它框架相比表現如何?

與Facebook的FastText甚至谷歌的AutoML天然語言平臺不一樣,使用Flair進行文本分類仍然是一項底層的工做。咱們能夠經過設置諸如學習率、批量大小、退火因子(anneal factor)、損失函數、優化選擇等參數來徹底控制文本嵌入和訓練的方式…爲了得到最佳表現,須要調整這些超參數。Flair爲咱們提供了一個有名的超參數調優庫Hyperopt的封裝器,咱們可使用它來對超參數進行調優以得到最佳的性能。

在本文中,爲了簡單起見,咱們使用了默認的超參數。在大多數默認參數下,咱們的Flair模型在10個訓練週期後得到了0.973的f1-score。

爲了進行對比,咱們使用FastText和AutoML天然語言平臺訓練了一個文本分類模型。首先咱們使用默認參數運行FastText,並得到了0.883的f1-score,這意味着模型在很大程度上優於FastText。然而,FastText只須要幾秒鐘的訓練時間,而咱們訓練的Flair模型則須要5分鐘。

咱們將結果與在谷歌的AutoML天然語言平臺上得到的結果進行了比較。平臺首先須要20分鐘來解析數據集。以後,咱們開始了訓練過程,這幾乎花了3個小時完成,但卻得到了99.211的f1-score——這比咱們本身訓練的模型稍微好一點。

原文連接

相關文章
相關標籤/搜索