数据挖掘入门与实战 公众号: datadw
利用机器学习可以很方便的做情感分析。本篇文章将介绍在R语言中如何利用机器学习方法来做情感分析。在R语言中,由Timothy P.Jurka开发的情感分析以及更一般的文本挖掘包已经得到了很好的发展。你可以查看下sentiment包以及梦幻般的RTextTools包。实际上,Timothy还写了一个针对低内存下多元Logistic回归(也称最大熵)的R包maxtent。
然而,RTextTools包中不包含朴素贝叶斯方法。e1071包可以很好的执行朴素贝叶斯方法。e1071是TU Wien(维也纳科技大学)统计系的一门课程。这个包的主要开发者是David Meyer。
我们仍然有必要了解文本分析方面的知识。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 specifyresponse 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")
可以看到,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"])
这里,我们也希望得到正式的测试结果。包括:
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。
数据挖掘入门与实战
搜索添加微信公众号:datadw
教你机器学习,教你数据挖掘
长按图片,识别二维码,点关注
公众号: weic2c
据分析入门与实战
长按图片,识别二维码,点关注