1 大綱概述html
文本分類這個系列將會有十篇左右,包括基於word2vec預訓練的文本分類,與及基於最新的預訓練模型(ELMo,BERT等)的文本分類。總共有如下系列:git
word2vec預訓練詞向量github
charCNN 模型app
RCNN 模型ui
全部代碼均在textClassifier倉庫中。
2 數據集
數據集爲IMDB 電影影評,總共有三個數據文件,在/data/rawData目錄下,包括unlabeledTrainData.tsv,labeledTrainData.tsv,testData.tsv。在進行文本分類時須要有標籤的數據(labeledTrainData),可是在訓練word2vec詞向量模型(無監督學習)時能夠將無標籤的數據一塊兒用上。
3 數據預處理
IMDB 電影影評屬於英文文本,本序列主要是文本分類的模型介紹,所以數據預處理比較簡單,只去除了各類標點符號,HTML標籤,小寫化等。代碼以下:
import pandas as pd from bs4 import BeautifulSoup with open("/data4T/share/jiangxinyang848/textClassifier/data/unlabeledTrainData.tsv", "r") as f: unlabeledTrain = [line.strip().split("\t") for line in f.readlines() if len(line.strip().split("\t")) == 2] with open("/data4T/share/jiangxinyang848/textClassifier/data/labeledTrainData.tsv", "r") as f: labeledTrain = [line.strip().split("\t") for line in f.readlines() if len(line.strip().split("\t")) == 3] unlabel = pd.DataFrame(unlabeledTrain[1: ], columns=unlabeledTrain[0]) label = pd.DataFrame(labeledTrain[1: ], columns=labeledTrain[0]) def cleanReview(subject):
# 數據處理函數 beau = BeautifulSoup(subject) newSubject = beau.get_text() newSubject = newSubject.replace("\\", "").replace("\'", "").replace('/', '').replace('"', '').replace(',', '').replace('.', '').replace('?', '').replace('(', '').replace(')', '') newSubject = newSubject.strip().split(" ") newSubject = [word.lower() for word in newSubject] newSubject = " ".join(newSubject) return newSubject unlabel["review"] = unlabel["review"].apply(cleanReview) label["review"] = label["review"].apply(cleanReview)
# 將有標籤的數據和無標籤的數據合併 newDf = pd.concat([unlabel["review"], label["review"]], axis=0) # 保存成txt文件 newDf.to_csv("/data4T/share/jiangxinyang848/textClassifier/data/preProcess/wordEmbdiing.txt", index=False)
咱們使用pandas直接處理數據,建議使用apply方法,處理速度比較快,數據處理完以後將有標籤和無標籤的數據合併,並保存成txt文件。
4 預訓練word2vec模型
關於word2vec模型的介紹見這篇。咱們使用gensim中的word2vec API來訓練模型。
官方API介紹以下:
class gensim.models.word2vec.Word2Vec(sentences=None, corpus_file=None, size=100, alpha=0.025, window=5, min_count=5, max_vocab_size=None, sample=0.001, seed=1, workers=3, min_alpha=0.0001, sg=0, hs=0, negative=5, ns_exponent=0.75, cbow_mean=1, hashfxn=<built-in function hash>, iter=5, null_word=0, trim_rule=None, sorted_vocab=1, batch_words=10000, compute_loss=False, callbacks=(), max_final_vocab=None)
主要參數介紹以下:
1) sentences:咱們要分析的語料,能夠是一個列表,或者從文件中遍歷讀出(word2vec.LineSentence(filename) )。
2) size:詞向量的維度,默認值是100。這個維度的取值通常與咱們的語料的大小相關,若是是不大的語料,好比小於100M的文本語料,則使用默認值通常就能夠了。若是是超大的語料,建議增大維度。
3) window:即詞向量上下文最大距離,window越大,則和某一詞較遠的詞也會產生上下文關係。默認值爲5,在實際使用中,能夠根據實際的需求來動態調整這個window的大小。
若是是小語料則這個值能夠設的更小。對於通常的語料這個值推薦在[5;10]之間。
4) sg:即咱們的word2vec兩個模型的選擇了。若是是0, 則是CBOW模型;是1則是Skip-Gram模型;默認是0即CBOW模型。
5) hs:即咱們的word2vec兩個解法的選擇了。若是是0, 則是Negative Sampling;是1的話而且負採樣個數negative大於0, 則是Hierarchical Softmax。默認是0即Negative Sampling。
6) negative:即便用Negative Sampling時負採樣的個數,默認是5。推薦在[3,10]之間。這個參數在咱們的算法原理篇中標記爲neg。
7) cbow_mean:僅用於CBOW在作投影的時候,爲0,則算法中的xw爲上下文的詞向量之和,爲1則爲上下文的詞向量的平均值。在咱們的原理篇中,是按照詞向量的平均值來描述的。我的比較喜歡用平均值來表示xw,默認值也是1,不推薦修改默認值。
8) min_count:須要計算詞向量的最小詞頻。這個值能夠去掉一些很生僻的低頻詞,默認是5。若是是小語料,能夠調低這個值。
9) iter:隨機梯度降低法中迭代的最大次數,默認是5。對於大語料,能夠增大這個值。
10) alpha:在隨機梯度降低法中迭代的初始步長。算法原理篇中標記爲η,默認是0.025。
11) min_alpha: 因爲算法支持在迭代的過程當中逐漸減少步長,min_alpha給出了最小的迭代步。
訓練模型的代碼以下:
import logging import gensim from gensim.models import word2vec
# 設置輸出日誌 logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
# 直接用gemsim提供的API去讀取txt文件,讀取文件的API有LineSentence 和 Text8Corpus, PathLineSentences等。 sentences = word2vec.LineSentence("/data4T/share/jiangxinyang848/textClassifier/data/preProcess/wordEmbdiing.txt")
# 訓練模型,詞向量的長度設置爲200, 迭代次數爲8,採用skip-gram模型,模型保存爲bin格式 model = gensim.models.Word2Vec(sentences, size=200, sg=1, iter=8) model.wv.save_word2vec_format("./word2Vec" + ".bin", binary=True)
# 加載bin格式的模型 wordVec = gensim.models.KeyedVectors.load_word2vec_format("word2Vec.bin", binary=True)