写点什么

R 语言中的情感分析与机器学习

2016 年 2 月 03 日

利用机器学习可以很方便的做情感分析。本篇文章将介绍在 R 语言中如何利用机器学习方法来做情感分析。在 R 语言中,由 Timothy P.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 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 得到的结果是相同的( http://chengjun.github.io/en/2012/03/sentiment-analysi-with-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 的准确性跟朴素贝叶斯是一样的,其它方法的结果准确性更差。这是可以理解的,因为我们给的是一个非常小的数据集。扩大训练集后,利用更复杂的方法我们对推文做的情感分析可以得到一个更好的结果。示例演示如下:

推文情感分析

数据来自 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 之文本分类

原文转载自:雪晴数据网 http://www.xueqing.cc/cms/article/107

2016 年 2 月 03 日 20:417208

评论

发布
暂无评论
发现更多内容

打破垄断 上海发布自主研发树图区块链重大成果

CECBC区块链专委会

区块链

javascript中的内存管理

程序那些事

JavaScript nodejs 内存管理 程序那些事

2021年美团/字节跳动/腾讯面经总结:互联网工程师必备的面试1000题

比伯

Java 编程 程序员 架构 面试

关于搜商的一点记录「Day 9」

道伟

28天写作

如果重来,结果就会好吗?「Day 10」

道伟

28天写作

大厂动态规划面试汇总,教你如何修炼内功

Kevin

算法 动态规划 数据结构和算法 笔试

dubbo 源码 v2.7 分析:核心机制(一)

程序员架构进阶

架构 源码分析 dubbo 七日更 28天写作

产品经理训练营作业 04

KingSwim

java学习笔记(一)

陈皮

Java

面试系列二:精选大数据面试真题JVM专项-附答案详细解析

五分钟学大数据

大数据 28天写作 3月日更

手写一个LRU缓存淘汰算法

Simon郎

Java 大数据 缓存 LRU 数据结构与算法

Docker 常用命令,还有谁不会?

xcbeyond

Docker 常用命令 28天写作

谁才是一级方程式赛车中的最强车手?

亚马逊云科技 (Amazon Web Services)

肝了很久,冰河整理出这份4万字的SpringCloud与SpringCloudAlibaba学习笔记!!

冰河

微服务 高可用 高并发 冰河技术 SpringCloud Alibaba

代码从业者

ES_her0

28天写作 3月日更

星环科技Sophon Edge边缘计算平台持续赋能千家万业

星环科技

这个新春,你的云端安全守卫来咯 | 新服务上线

亚马逊云科技 (Amazon Web Services)

【管理笔记16】行销市场区隔化与目标市场

俊毅

Kubelet从入门到放弃:拓扑管理(上)

DCOS

Linux Kubernetes 云原生 kubelet

加快布局区块链技术发展,助力网络强国建设

CECBC区块链专委会

区块链

VR,正在上演一出“风月宝鉴”

脑极体

产品经理训练营 - 第四章作业 (二)

joelhy

产品经理训练营

敏捷, 是一种信仰

boshi

敏捷 七日更 28天写作

一篇读懂https的本质、证书验证过程以及数据加密

梁龙先森

前端 https 前端进阶

真实字节二面:什么是伪共享?

艾小仙

Java 程序员 字节跳动 面试 面试大厂

(28DW-S8-Day10) T型学习模式:迁移式学习

mtfelix

T型人才 28天写作 迁移学习 一万小时定律

「产品经理训练营」作业 05:知识星球加入星球流程图

狷介

产品经理训练营

翻译:《实用的Python编程》03_02_More_functions

codists

Python

SQL Server 多表数据增量获取和发布 2.1

happlyfox

28天写作 3月日更

第五周 继续文档的一些细节

Sicolas Flamel

产品经理 产品经理新人如何落地 产品经理训练营

第五次作业

Geek_79e938

演讲经验交流会|ArchSummit 上海站

演讲经验交流会|ArchSummit 上海站

R语言中的情感分析与机器学习-InfoQ