【從傳統方法到深度學習】情感分析


為了記錄在競賽中入門深度學習的過程,我開了一個新系列【從傳統方法到深度學習】。

1. 問題

Kaggle競賽Bag of Words Meets Bags of Popcorn是電影評論(review)的情感分析,可以視作為短文本的二分類問題(正向、負向)。標注數據集長這樣:

id	sentiment	review
"2381_9"	1	"\"The Classic War of the Worlds\" by Timothy Hines is a very entertaining film that obviously goes to great effort and lengths to faithfully recreate H. G. Wells' classic book. Mr. Hines succeeds in doing so. ..."
"2486_3"	0	"What happens when an army of wetbacks, towelheads, and Godless Eastern European commies gather their forces south of the border? Gary Busey kicks their butts, of course. Another laughable example of Reagan-era cultural fallout, Bulletproof wastes a decent supporting cast headed by L Q Jones and Thalmus Rasulala."

評價指標是AUC。因此,在測試數據集上應該給出概率而不是類別;即為predict_proba而不是predict

# random frorest
result = forest.predict_proba(test_data_features)[:, 1]
# not `predict`
result = forest.predict(test_data_features)

采用BoW特征、RF (random forest)分類器,預測類別的AUC為0.84436,預測概率的AUC則為0.92154。

2. 分析

傳統方法

傳統方法一般會使用到兩種特征:BoW (bag of words),n-gram。BoW忽略了詞序,只是單純對詞計數;而n-gram則是考慮到了詞序,比如bigram詞對"dog run"、"run dog"是兩個不同的特征。BoW可以用CountVectorizer向量化:

from sklearn.feature_extraction.text import CountVectorizer

vectorizer = CountVectorizer(analyzer="word", tokenizer=None, preprocessor=None,
                             stop_words=None, max_features=5000)
train_data_features = vectorizer.fit_transform(clean_train_reviews)

在一個句子中,不同的詞重要性是不同的;需要用TFIDF來給詞加權重。n-gram特征則可以用TfidfVectorizer向量化:

from sklearn.feature_extraction.text import TfidfVectorizer

vectorizer = TfidfVectorizer(max_features=40000, ngram_range=(1, 3), sublinear_tf=True)
train_x = vectorizer.fit_transform(clean_train_reviews)

使用unigram、bigram、trigram特征 + RF分類器,AUC為0.93058;如果改成LR分類器,則AUC為0.96330。

深度學習

競賽tutorial給出用word2vec詞向量特征來做分類,並兩個生成特征思路:

  • 對每一條評論的所有詞向量求平均,將其平均值作為改評論的特征;
  • 對訓練的詞向量做聚類,然后對評論中的詞類別進行計數,把這種bag-of-centroids作為特征。

把生成這種特征喂給分類器,進行分類。但是,這種方法的AUC不是太理想(在0.91左右)。無論是做平均還是聚類,一方面丟失了詞向量的特征,另一方面忽略了詞序還有詞的重要性。因此,分類效果不如tfidf化的n-gram。

大神Mikolov在推出word2vec之后,又鼓搗出了doc2vec(gensim有實現)。簡單地說,就是可以把一段文本變成一個向量。與word2vec不同的是,參數除了doc對應的詞列表外,還有類別(TaggedDocument)。結果證明doc2vec的效果還不如word2vec生成特征,AUC只有0.87915。

doc2vec = Doc2Vec(sentences, workers=8, size=300, min_count=40,
                window=10, sample=1e-4)

pangolulu嘗試把BoW與doc2vec做ensemble,采用stacking的思路——L1層BoW特征做LR分類、doc2vec特征做RBF-SVM分類,L2層將L1層的預測概率組合成一個新特征,喂給LR分類器;多次迭代后求平均。ensemble結構圖如下:

以上所有方法的AUC對比如下:

特征 分類 AUC
BoW RF 0.92154
(1,3) gram, tfidf LR 0.96330
(1,3) gram, tfidf RF 0.93058
word2vec + avg RF 0.90798
word2vec + cluster RF 0.91485
doc2vec RF 0.87915
doc2vec LR 0.90573
BoW, doc2vec ensemble 0.93926

3. 參考資料

[1] Zygmunt Z., Classifying text with bag-of-words: a tutorial.

[2] Michael Czerny, Modern Methods for Sentiment Analysis.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM