用最新NLP庫Flair做文字分類
介紹
文字分類是一種監督機器學習方法,用於將句子或文字文件歸類為一個或多個已定義好的類別。它是一個被廣泛應用的自然語言處理方法,在垃圾郵件過濾、情感分析、新聞稿件分類以及與許多其它業務相關的問題中發揮著重要作用。
目前絕大多數最先進的方法都依賴於一種被稱為文字嵌入的技術。它將文字轉換成高維空間中的數值表示方式。它可以將文件、語句、單詞、字元(取決於我們所嵌入的形式)表示為這個高維空間中的一個向量。
Flair之所以對NLP來說是一個令人興奮的訊息,是因為Zalando Research最近發表的一篇論文《Contextual String Embeddings for Sequence Labelling
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上只花幾分鐘就可以完成一個模型的訓練。
來自資料集中的標記為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——這比我們自己訓練的模型稍微好一點。
本文由北郵@愛可可-愛生活 老師推薦,阿里云云棲社群組織翻譯。
文章原標題《GANs as a loss function》
譯者:Mags,審校:袁虎。
文章為簡譯,更為詳細的內容,請檢視原文