Flair是一個基於PyTorch構建的NLP開發包,它在解決命名實體識別(NER)、語句標註(POS)、文本分類等NLP問題時達到了當前的頂尖水準。本文將介紹如何使用Flair構建定製的文本分類器。git
文本分類是一種用來將語句或文檔納入一個或多個分類的有監督機器學習方法,被普遍應用於垃圾郵件過濾、情感分析、新文章歸類等衆多業務領域。github
當前絕大多數領先的文本分類方法都依賴於文本嵌入技術,它將文本轉換爲高維空間的數值表示,能夠將文檔、句子、單次或字符表示爲這個高維空間的一個向量。算法
Flair基於Zalando Research的論文「用於串行標準的上下文相關字符串嵌入」,論文算法表現能夠斃掉以前的最好方案,該算法在Flair中獲得完整實現,能夠用來構建文本分類器。框架
Flair安裝須要Python 3.6,執行pip安裝便可:機器學習
~$ pip install flair
上面的命令將安裝運行Flair所須要的依賴包,固然也包括了PyTorch。函數
最新的Flair 0.4版本包含有兩個預先訓練好的模型。一個基於IMDB數據集訓練的情感分析模型和一個攻擊性語言探測模型(當前僅支持德語)。性能
只需一個命令就能夠下載、存儲並使用模型,這使得預置模型的使用過程異常簡單。例如,下面的代碼將使用情感分析模型:學習
from flair.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)
當第一次運行上述代碼時,Flari將下載情感分析模型,默認狀況下會保存到本地用戶主目錄的.flair子目錄,下載可能須要幾分鐘。測試
上面的代碼首先載入必要的庫,而後載入情感分析模型到內存中(必要時先下載),接下來 就能夠預測「Flair is pretty neat!」的情感分值了(0~1之間)。最後的命令輸入結果爲:fetch
The sentence above is: [Positive (1.0)].
就是這麼簡單!如今你能夠將上述代碼整合爲一個REST API,提供相似於google雲端情感分析API的功能了!
要訓練一個自定義的文本分類器,首先須要一個標註文本集。Flair的分類數據集格式基於Facebook的FastText格式,要求在每一行的開始使用**label**前綴定義一個或多個標籤。格式以下:
__label__<class_1> <text> __label__<class_2> <text>
在這篇文章中咱們將使用Kaggle的SMS垃圾信息檢測數據集來用Flair構建一個垃圾/非垃圾分類器。這個數據集很適合咱們的學習任務,由於它很小,只有5572行數據,能夠在單個CPU上只花幾分鐘就完成模型的訓練。
首先下載Kaggle上的數據集,獲得spam.csv;而後再數據集目錄下,運行咱們的處理腳本,獲得訓練集、開發集和測試集:
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、dev.csv和test.csv。
用下面的腳本訓練模型:
from flair.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='train.csv', dev_file='dev.csv', train_file='test.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=20)
第一次運行上面這個腳本時,Flair會自動下載所須要的嵌入模型,這可能須要幾分鐘,而後接下來的整個訓練過程還須要大約5分鐘。
腳本首先載入須要的庫和數據集,獲得一個corpus對象。
接下來,咱們建立一個嵌入列表,包含兩個Flair上下文字符串嵌入和一個GloVe單詞嵌入,這個列表接下來將做爲咱們文檔嵌入對象的輸入。堆疊和文本嵌入是Flair中最有趣的感念之一,它們提供了將不一樣的嵌入整合在一塊兒的手段,你能夠同時使用傳統的單詞嵌入(例如GloVe、word2vector、ELMo)和Flair的上下文字符串嵌入。在上面的示例中咱們使用一個基於LSTM的方法來生成文檔嵌入,關於該方法的詳細描述能夠參考這裏。
最後,上面的代碼訓練模型並生成兩個模型文件:final-model.pt和best-model.pt。
如今咱們可使用導出的模型進行預測了。腳本以下:
from flair.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或者Google的AutoML平臺不一樣,用Flair進行文本分類仍是相對底層的任務。咱們能夠徹底控制文本如何嵌入,也能夠設置訓練的參數例如學習速率、批大小、損失函數、優化器選擇策略等,這些超參數是要實現最優性能所必須進行調整的。Flair提供了著名的超參數調整庫Hyperopt的一個封裝。
在這篇文章中,出於簡化考慮咱們使用了默認的超參數,獲得的Flair模型的f1-score在20個epoch以後達到了0.973。
爲了對比,咱們使用FastText和AutoML訓練了一個文本分類器。咱們首先使用默認參數運行 FastText,獲得的f1-score爲0.883,這意味着咱們的Flair模型遠遠優於FastText模型,不過FastText的訓練很快,只須要幾秒鐘。
而後咱們也與AutoML天然語言平臺上獲得的結果進行了對比。平臺首先須要20分鐘來 解析數據集,而後咱們啓動訓練過程,這大約花了3個小時才完成,可是f1-score達到了 99.211,要稍好於咱們本身訓練的Flair模型。
原文連接:用Flair進行文本分類 - 匯智網