您的位置:首页 > 其它

基于R语言对用户评论进行情感分析

2017-08-18 16:29 1051 查看
利用机器学习可以很方便的做情感分析。本篇文章将介绍在R语言中如何利用机器学习方法来做情感分析。在R语言中,由TimothyP.Jurka开发的情感分析以及更一般的文本挖掘包已经得到了很好的发展。你可以查看下sentiment包以及梦幻般的RTextTools包。实际上,Timothy还写了一个针对低内存下多元Logistic回归(也称最大熵)的R包maxtent

然而,RTextTools包中不包含朴素贝叶斯方法。e1071包可以很好的执行朴素贝叶斯方法。e1071是TU Wien(维也纳科技大学)统计系的一门课程。这个包的主要开发者是David Meyer

我们仍然有必要了解文本分析方面的知识。用R语言来处理文本分析已经是公认的事实(详见“R语言中的自然语言处理”)。tm包算是其中成功的一部分:它是R语言在文本挖掘应用中的一个框架。它在文本清洗(词干提取,删除停用词等)以及将文本转换为词条-文档矩阵(dtm)方面做得很好。http://www.jstatsoft.org/v25/i05/paper是对它的一个介绍。文本分析最重要的部分就是得到每个文档的特征向量,其中词语特征最重要的。当然,你也可以将Unigram扩展为Bi-gram,Tri-gram,N-gram等。在本篇文章,我们以单个词语特征为例做演示。

注意,在R中用ngram包来处理N-gram。在过去,Rweka包提供了函数来处理它,感兴趣的可以查看这个案例:http://stackoverflow.com/questions/8161167/what-algorithm-i-need-to-find-n-grams。现在,你可以设置RTextTools包中create_matrix函数的参数ngramLength来实现它。

使用R语言来训练朴素贝叶斯模型

读取数据:

library(RTextTools)

library(e1071)

 

pos_tweets = rbind(

  c('I love thiscar', 'positive'),

  c('This view isamazing', 'positive'),

  c('I feel greatthis morning', 'positive'),

  c('I am soexcited about the concert', 'positive'),

  c('He is my bestfriend', 'positive')

)

 

neg_tweets = rbind(

  c('I do not likethis car', 'negative'),

  c('This view ishorrible', 'negative'),

  c('I feel tiredthis morning', 'negative'),

  c('I am notlooking forward to the concert', 'negative'),

  c('He is myenemy', 'negative')

)

 

test_tweets = rbind(

  c('feel happythis morning', 'positive'),

  c('larry friend','positive'),

  c('not like thatman', 'negative'),

  c('house notgreat', 'negative'),

  c('your songannoying', '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得到的结果是相同的(http://chengjun.github.io/en/2012/03/sentiment-analysi-with-python/这篇文章是用python得到的结果)。

其它机器学习方法怎样呢?

下面我们使用RTextTools包来处理它。

首先,指定相应的数据:

# build the data to specify response variable, trainingset, 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的准确性跟朴素贝叶斯是一样的,其它方法的结果准确性更差。这是可以理解的,因为我们给的是一个非常小的数据集。扩大训练集后,利用更复杂的方法我们对推文做的情感分析可以得到一个更好的结果。示例演示如下:

推文情感分析

数据来自victorneo。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"])

这里,我们也希望得到正式的测试结果。包括:

analytics@algorithm_summary:包括精确度,召回率,准确率,F-scores的摘要

analytics@label_summary:类标签摘要

analytics@document_summary:所有数据和得分的原摘要

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之文本分类
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐