分別使用sk-learn和mllib進行文本情感分類

總體思路

  1. 文本預處理
  2. 提取特徵
  3. 特徵選擇
  4. 選擇分類算法
  5. 訓練和評估

預處理

包括分句、分詞和詞幹化,使用nltk可以實現。

實現分兩個版本:1. scikit-learn版本 2. MLLIB版本
主要是因爲運行效率的問題,基於spark的mllib採用分佈式的訓練算法,速度快很多。

特徵提取

tf-idf是基本的文本分類特徵提取方法,它是詞袋模型的一個信息量衡量方式,也是常用的基準方法。本文就是用tf-idf來構建文本特徵,後面會提到使用word2vec進行改進。

scikit-learn特徵提取

sklearn庫提供tf-idf類,很方便就可以將文本轉爲向量,還可以定義許多參數,如ngram、最小df、停用詞、分詞器等

stopword_list = ["it", "this"] # example
vectorizer = TfidfVectorizer(min_df=2, ngram_range=(12),
                                 stop_words=stopword_list)
X = vectorizer.fit_transform(corpus).toarray()

mllib特徵提取

mllib上許多api都仿照sklearn,所以對sklearn熟悉的人都很容易上手。在這裏,我們使用Python語言進行Spark(1.4.1)代碼的編寫。

from pyspark import SparkContext
from pyspark.mllib.feature import HashingTF

sc = SparkContext()

# Load documents (one per line).
documents = sc.textFile("...").map(lambda line: line.split(" "))

hashingTF = HashingTF()
tf = hashingTF.transform(documents)
from pyspark.mllib.feature import IDF

tf.cache()
idf = IDF(minDocFreq=2).fit(tf)
tfidf = idf.transform(tf)

特徵選擇

好的特徵選擇方式能夠減少特徵的數量,提高訓練的效率和分類效果。
對於文本向量來說,未進行特徵選擇的向量維度爲V ,一般爲數萬維,這對於一些分類器來說,無疑是災難,訓練時間久又不見得效果好。

常用的特徵選擇方法有(可參考sklearn的model_selection模塊):
1. 卡方檢驗
2. 刪除變化小的特徵
3. L1正則
4. 基於樹的模型

具體實現方法可以瀏覽sklearn官網。
這裏就是用卡方檢驗方法:
sklearn:

from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2
X_new = SelectKBest(chi2, k=5000).fit_transform(X, y)

mllib:

selector = ChiSqSelector(numTopFeatures=1, featuresCol="features",  
                         outputCol="features2", labelCol="label")   
result = selector.fit(df).transform(df)  

選擇分類算法

這裏選擇LR和Native Bayes,也可以用其他,只是做個例子。

sklearn:

from sklearn.linear_model import LogisticRegression
from sklearn.naive_bayes import MultinomialNB
LR = LogisticRegression(C=1.0, penalty="l2")
nb = MultinomialNB()

mllib:

from pyspark.mllib.classification import LogisticRegressionWithLBFGS
from pyspark.mllib.regression import LabeledPoint
from numpy import array

# Build the model
model = LogisticRegressionWithLBFGS.train(parsedData)

訓練和評估

sklearn:

scores = cross_val_score(LR, features, targets, cv=5, scoring="f1")
print scores
print "F1: %0.2f (+/- %0.2f)" % (scores.mean(), scores.std() * 2)

scores = cross_val_score(nb, features, targets, cv=5, scoring="f1")
print scores
print "F1: %0.2f (+/- %0.2f)" % (scores.mean(), scores.std() * 2)

mllib:

labelsAndPreds = parsedData.map(lambda p: (p.label, model.predict(p.features)))
trainErr = labelsAndPreds.filter(lambda (v, p): v != p).count() / float(parsedData.count())
print("Training Error = " + str(trainErr))

Reference

http://scikit-learn.org/stable/index.html
http://spark.apache.org/docs/1.4.1/mllib-guide.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章