R語言中的情感分析與機器學習

子華發表於2016-01-11

利用機器學習可以很方便的做情感分析。本篇文章將介紹在R語言中如何利用機器學習方法來做情感分析。在R語言中,由Timothy P.Jurka開發的情感分析以及更一般的文字挖掘包已經得到了很好的發展。你可以檢視下sentiment包以及夢幻般的RTextTools包。實際上,Timothy還寫了一個針對低記憶體下多元Logistic迴歸(也稱最大熵)的R包maxtent。

然而,RTextTools包中不包含樸素貝葉斯方法。e1071包可以很好的執行樸素貝葉斯方法。e1071是TU Wien(維也納科技大學)統計系的一門課程。這個包的主要開發者是David Meyer。

我們仍然有必要了解文字分析方面的知識。用R語言來處理文字分析已經是公認的事實(詳見R語言中的自然語言處理)。tm包算是其中成功的一部分:它是R語言在文字挖掘應用中的一個框架。它在文字清洗(詞幹提取,刪除停用詞等)以及將文字轉換為詞條-文件矩陣(dtm)方面做得很好。這裡是對它的一個介紹。文字分析最重要的部分就是得到每個文件的特徵向量,其中詞語特徵最重要的。當然,你也可以將單個詞語特徵擴充套件為雙片語,三連詞,n-連詞等。在本篇文章,我們以單個詞語特徵為例做演示。

注意,在R中用ngram包來處理n-連詞。在過去,Rweka包提供了函式來處理它,感興趣的可以檢視這個案例。現在,你可以設定RTextTools包中create_matrix函式的引數ngramLength來實現它。

第一步是讀取資料: library(RTextTools) library(e1071)

pos_tweets = rbind( c('I love this car', 'positive'), c('This view is amazing', 'positive'), c('I feel great this morning', 'positive'), c('I am so excited about the concert', 'positive'), c('He is my best friend', 'positive') )

neg_tweets = rbind( c('I do not like this car', 'negative'), c('This view is horrible', 'negative'), c('I feel tired this morning', 'negative'), c('I am not looking forward to the concert', 'negative'), c('He is my enemy', 'negative') )

test_tweets = rbind( c('feel happy this morning', 'positive'), c('larry friend', 'positive'), c('not like that man', 'negative'), c('house not great', 'negative'), c('your song annoying', 'negative') )

tweets = rbind(pos_tweets, neg_tweets, test_tweets) 建立詞條-文件矩陣: # build dtm matrix= create_matrix(tweets[,1], language="english", removeStopwords=FALSE, removeNumbers=TRUE, stemWords=FALSE)
現在,我們可以用這個資料集來訓練樸素貝葉斯模型。注意,e1071要求響應變數是數值型或因子型的。我們用下面的方法將字串型資料轉換成因子型: # train the model mat = as.matrix(matrix) classifier = naiveBayes(mat[1:10,], as.factor(tweets[1:10,2]) ) 測試結果準確度: # test the validity predicted = predict(classifier, mat[11:15,]); predicted table(tweets[11:15, 2], predicted) recall_accuracy(tweets[11:15, 2], predicted) 顯然,這個結果跟python得到的結果是相同的(這篇文章是用python得到的結果)。

其它機器學習方法怎樣呢?

下面我們使用RTextTools包來處理它。

首先,指定相應的資料: # build the data to specify response variable, training set, testing set. container = create_container(matrix, as.numeric(as.factor(tweets[,2])), trainSize=1:10, testSize=11:15,virgin=FALSE) 其次,用多種機器學習演算法訓練模型: models = train_models(container, algorithms=c("MAXENT" , "SVM", "RF", "BAGGING", "TREE")) 現在,我們可以使用訓練過的模型做測試集分類: results = classify_models(container, models) 準確性如何呢? # accuracy table table(as.numeric(as.factor(tweets[11:15, 2])), results[,"FORESTS_LABEL"]) table(as.numeric(as.factor(tweets[11:15, 2])), results[,"MAXENTROPY_LABEL"])

recall accuracy

recall_accuracy(as.numeric(as.factor(tweets[11:15, 2])), results[,"FORESTS_LABEL"]) recall_accuracy(as.numeric(as.factor(tweets[11:15, 2])), results[,"MAXENTROPY_LABEL"]) recall_accuracy(as.numeric(as.factor(tweets[11:15, 2])), results[,"TREE_LABEL"]) recall_accuracy(as.numeric(as.factor(tweets[11:15, 2])), results[,"BAGGING_LABEL"]) recall_accuracy(as.numeric(as.factor(tweets[11:15, 2])), results[,"SVM_LABEL"]) 得到模型的結果摘要(特別是結果的有效性): # model summary analytics = create_analytics(container, results) summary(analytics) head(analytics@document_summary) analytics@ensemble_summar 結果的交叉驗證: N=4 set.seed(2014) cross_validate(container,N,"MAXENT") cross_validate(container,N,"TREE") cross_validate(container,N,"SVM") cross_validate(container,N,"RF") 結果可在我的Rpub頁面找到。可以看到,maxent的準確性跟樸素貝葉斯是一樣的,其它方法的結果準確性更差。這是可以理解的,因為我們給的是一個非常小的資料集。擴大訓練集後,利用更復雜的方法我們對推文做的情感分析可以得到一個更好的結果。示例演示如下:

推文情感分析

資料來自victornep。victorneo展示的是用python對推文做情感分析。這裡,我們用R來處理它:

讀取資料: ################### "load data"

#

setwd("D:/Twitter-Sentimental-Analysis-master/") happy = readLines("./happy.txt") sad = readLines("./sad.txt") happy_test = readLines("./happy_test.txt") sad_test = readLines("./sad_test.txt")

tweet = c(happy, sad) tweet_test= c(happy_test, sad_test) tweet_all = c(tweet, tweet_test) sentiment = c(rep("happy", length(happy) ), rep("sad", length(sad))) sentiment_test = c(rep("happy", length(happy_test) ), rep("sad", length(sad_test))) sentiment_all = as.factor(c(sentiment, sentiment_test))

library(RTextTools) 首先,嘗試下樸素貝葉斯 # naive bayes mat= create_matrix(tweet_all, language="english", removeStopwords=FALSE, removeNumbers=TRUE, stemWords=FALSE, tm::weightTfIdf)

mat = as.matrix(mat)

classifier = naiveBayes(mat[1:160,], as.factor(sentiment_all[1:160])) predicted = predict(classifier, mat[161:180,]); predicted

table(sentiment_test, predicted) recall_accuracy(sentiment_test, predicted) 然後,嘗試其他方法: # the other methods mat= create_matrix(tweet_all, language="english", removeStopwords=FALSE, removeNumbers=TRUE, stemWords=FALSE, tm::weightTfIdf)

container = create_container(mat, as.numeric(sentiment_all), trainSize=1:160, testSize=161:180,virgin=FALSE) #可以設定removeSparseTerms

models = train_models(container, algorithms=c("MAXENT", "SVM", #"GLMNET", "BOOSTING", "SLDA","BAGGING", "RF", # "NNET", "TREE" ))

test the model

results = classify_models(container, models) table(as.numeric(as.numeric(sentiment_all[161:180])), results[,"FORESTS_LABEL"]) recall_accuracy(as.numeric(as.numeric(sentiment_all[161:180])), results[,"FORESTS_LABEL"]) 這裡,我們也希望得到正式的測試結果。包括: 1.analytics@algorithm_summary:包括精確度,召回率,準確率,F-scores的摘要 2.analytics@label_summary:類標籤摘要 3.analytics@document_summary:所有資料和得分的原摘要 4.analytics@ensemble_summary:所有 精確度/覆蓋度 比值的摘要

現在讓我們看看結果: # formal tests analytics = create_analytics(container, results) summary(analytics)

head(analytics@algorithm_summary) head(analytics@label_summary) head(analytics@document_summary) analytics@ensemble_summary # Ensemble Agreement

Cross Validation

N=3 cross_SVM = cross_validate(container,N,"SVM") cross_GLMNET = cross_validate(container,N,"GLMNET") cross_MAXENT = cross_validate(container,N,"MAXENT") 與樸素貝葉斯方法相比,其它演算法的結果更好,召回精度高於0.95。結果可在Rpub檢視

注:對上述得到的四個測試結果所代表的意義可以參考這篇文章R之文字分類

本文由雪晴資料網負責翻譯整理,原文請參考Sentiment analysis with machine learning in R作者Chen-Jun Wang。轉載請註明原文連結http://www.xueqing.cc/cms/article/107

相關文章