1:簡介
FastText是Facebook開發的一款快速文本分類器,提供簡單而高效的文本分類和表征學習的方法。
本文素材來源於https://pypi.org/project/fasttext/,增加一些個人理解。
2:安裝要求
只可以安裝在Mac OS和Linux系統上,依賴於C++11編譯器,同時需要python版本2.7或者3.4及以上,以及numpy&scipy&pybind11。
pip install fasttext即可,https://fasttext.cc/docs/en/support.html中所述安裝方法在106機器上會有c編譯的錯誤
3: Word representation
NLP中一個很流行的方法是詞向量化,這些詞語經過向量化,可以高效的捕捉每個詞語的相似詞及其語義信息,這也有助於提高文本分類的准確性。
教程給的倆個數據集https://dumps.wikimedia.org/enwiki/latest/enwiki-latest-pages-articles.xml.bz2、http://mattmahoney.net/dc/enwik9.zip,第一個12G,過大,
enwik9.zip 954M,
import fasttext # 使用默認的參數訓練詞向量 model = fasttext.train_unsupervised('data/fil9') # 降序返回語料庫中的所有單詞 model.words # 獲取某一個單詞的詞向量 model.get_word_vector("the") # 保存模型 model.save_model("result/fil9.bin") # reload模型 model = fasttext.load_model("result/fil9.bin")
3.1: 模型 skipgram VS cbow(continuous-bag-of-words)
skipgram模型輸入是目標詞的詞向量,而輸出是目標詞的上下文詞向量,而cbow利用目標詞匯的上下文進行預測目標側,上下文是指“目標詞匯左右若干個詞,不包含目標詞匯”
# 使用cbow模型 model = fasttext.train_unsupervised('data/fil9', "cbow") # 控制詞向量維度的參數dim(默認100),控制subword長度范圍的參數minn,maxn(默認3,6) model = fasttext.train_unsupervised('data/fil9', minn=2, maxn=5, dim=300) # 模型在數據集中遍歷的次數epoch(默認5),學習率lr(默認0.05),線程數量threads(默認12) model = fasttext.train_unsupervised('data/fil9', epoch=1, lr=0.5,threads=4)
利用上文文生成詞向量,可以帶來的一個好處是,即使某個詞沒有出現在語料庫里,但是只要該詞的片段曾經出現過,模型依舊可以給出其向量化的表示,
另外,還可以查詢某個詞的最近鄰向量(通過倆個詞之前的向量夾角的余弦來判斷):
# 獲取某個未在語料庫中出現過的單詞(拼錯的單詞)的詞向量 model.get_word_vector("enviroment") # 默認查詢輸入詞的10個最近鄰向量 model.get_nearest_neighbors('asparagus') # 用類推的方法尋找同義詞:berlin之於germany,則france之於"巴黎" model.get_analogies("berlin", "germany", "france") # 如果不利用上下文生成詞向量,則上述方法會失效,返回一些無關的詞 model_without_subwords = fasttext.train_unsupervised('data/fil9', maxn=0)
4:Text classification
文本分類工作,在垃圾郵件檢測,情感分析和智能回復中都是一項重要的技術。其目標是為一段文本分配一個或者多個類別,這些類別可能是對一段文本的評分,也可能是指該文本的語言類別。如今,主流的文本分類器運用了機器學習的算法,利用有標簽的數據來構建這樣的一個分類器。
經常使用的一個方法是train_supervised,返回的模型可以利用test和predict方法。
這里的示例使用的數據是一個烹飪問答網站中有關於烹飪的語料。
每一行文件都由標簽和對應的語句組成,每個標簽的前綴都是“__label__”,這是fastText約定俗稱的區分標簽和語句的符號。
該語料庫共有15404條數據,將前12404條數據划分為訓練數據集cooking.train,后3000條數據為驗證數據集cooking.valid。
# 使用默認參數進行監督學習,epoch=5 model = fasttext.train_supervised(input="cooking.train") # 使用模型對語句的標簽進行預測 model.predict("Which baking dish is best to bake a banana bread ?") # 在驗證集上的表現,輸出三個參數:驗證集的數據量,以及在驗證集上的精確率和召回率 model.test("cooking.valid") # 在驗證集上的top-5精確率和召回率 model.test("cooking.valid", k=5)
4.1 文本預處理
教程中只是簡單的將文本統統換為小寫: tr "[:upper:]" "[:lower:]"
4.2 超參調整
# 調整epoch,學習率lr,wordNgrams model = fasttext.train_supervised(input="cooking.train", epoch=25,lr=1.0) # word n-grams model = fasttext.train_supervised(input="cooking.train", lr=1.0, epoch=25, wordNgrams=2)
4.3 損失函數
https://www.cnblogs.com/xiaoxiaomajinjiebiji/p/14077212.html
5:參數自動調優
# 在實現模型參數的自動調優的時候,需要提供autotuneValidationFile參數指定模型的驗證集,最終模型會返回在驗證集上F1 score值最高的參數,默認情況下,在驗證集上的搜索耗時5min,如果想要進行調整,可以通過autotuneDuration參數,單位為秒,如果在訓練過程中想提早停止,可以直接ctrl-c結束當前訓練,使用目前找到的最佳參數再訓練. model = fasttext.train_supervised(input='cooking.train', autotuneValidationFile='cooking.valid', autotuneDuration=600) # autotuneModelSize參數限制模型大小,fastText可以實現模型的壓縮和量化,同時也有相應的參數來調整所保存的模型精度和大小,而該參數可以實現這些參數的自動調優 model = fasttext.train_supervised(input='cooking.train', autotuneValidationFile='cooking.valid', autotuneModelSize="2M") # 輸出模型大小 os.stat("model_cooking.ftz").st_size # 相比較autotuneValidationFile,fastText也可以實現在特定標簽上模型的優化,此時利用的參數為:autotuneMetric,還可以同時在多個標簽上實現對模型的調優,此時利用的參數為:autotunePredictions model = fasttext.train_supervised(input='cooking.train', autotuneValidationFile='cooking.valid', autotuneMetric="f1:__label__baking")
6:一些坑
a:數據預處理
標簽以"__label__"開頭,中文需要先進行分詞,分詞后,每個詞之間用空格分隔,每一行以\n結尾,標簽和語句之間可以用空格分隔,也可以用“\t”或者“,”等分隔,因為,“\t”等同於4個空格,用“,”分隔,則語料庫中會多一個“,”,從實驗結果來看,並沒有很大的影響,猜測是因為每條語料都加的話,基本可以消除影響。訓練數據必須是utf-8編碼。
model.get_line(text)函數可以獲取一條文本的標簽和語句,可以加以驗證。
b:多標簽分類
多標簽分類損失函數:各個類別的交叉熵之和
https://github.com/facebookresearch/fastText/commit/8850c51b972ed68642a15c17fbcd4dd58766291d
c:精確率和召回率的計算方式
model.test_label(valid_data_fpath,k=1)可以返回1個結果的時候,各個類別的精確率和召回率以及f1score
model.test(valid_data_fpath,k=1)可以返回1個結果的時候,整個驗證數據集上的精確率和召回率以及f1score
詳細:類別a在語料中出現的次數即為TP+FN,FP是指預測錯誤的數據量(在整個驗證集上遍歷預測結果,預測結果為a,但標簽不是a的總量),TP是指預測正確的數據量,由此可以計算類別a的精確率和召回率以及f1score
而整個數據集的計算方式采取的是micro的方式,詳情見:https://zhuanlan.zhihu.com/p/59862986