在大数据环境中执行情感分析

情感分析

情感分析是利用文本分析来挖掘各种观点的数据来源的过程。通常情况下,情感分析是在从互联网和各种社交媒体平台收集的数据上执行的。政治家和政府经常利用情感分析来了解人们如何看待他们和他们的政策。
随着社交媒体的出现,人们可以从各种不同来源(比如移动设备和 Web 浏览器)捕获数据,并用不同的数据格式存储这些数据。由于社交媒体内容对于传统存储系统(比如 RDBMS、关系数据库管理系统)是非结构化的,所以我们需要一些可以处理和分析各种不同数据的工具。不过,大数据技术旨在处理不同来源、不同格式的结构化和非结构化数据。在本文中,我将介绍如何利用大数据工具来捕获数据,以便存储和处理用于情感分析的数据。

处理大数据

无论何时从采用多种格式(结构化、半结构化或非结构化的)的多个来源收集数据,都需要考虑建立一个 Hadoop 集群和一个 Hadoop 分布式文件系统(HDFS)来存储数据。HDFS 提供了一种管理大数据的灵活方式:

  • 可以将您的一些分析数据移动到现有的关系数据库管理系统(RDBMS)中,比如 Oracle 或 MySQL,这样您就可以利用现有的 BI 和报告工具。
  • 可以将数据存储在 HDFS 中,供将来分析使用,例如,通过执行像 ANOVA.T 这样的测试来比较旧数据与新数据。
  • 如果只需要分析数据的影响,那么可以删除这些数据。
    要了解如何设置 Hadoop 集群,请将数据导入 HDFS,然后在您的 Hadoop 环境中分析这些数据,请参阅我的其他 developerWorks 文章, “将 Hadoop 与现有的 RDBMS 相集成“。

    检索数据并将数据存储在 HDFS 中

    最好的情感分析包括来自多个来源的数据。在本文中,我将介绍如何从这些来源中检索数据:
  • Twitter 提要
  • RSS 提要
  • 移动应用程序
    我还将解释如何将来自不同来源的数据存储在 HDFS 中(存储在您的 Hadoop 集群中)。

    从 Twitter 提要中检索数据

    Twitter(一种流行的微博网站)有一组 API,它们使得我们能够检索和操作 tweet。但是首先,我们需要实现 Twitter 的 OAuth 框架。简单地讲,有了这个框架,应用程序就可以代表您登录到 Twitter,无需您登录到 Twitter 网站。查看 Twitter 开发人员站点的设置过程,其中解释了如何指派实现此操作的应用程序。在这个过程中,会为您分配一个密钥和一个密钥令牌,您的应用程序将使用它们来代表您执行身份验证。在您的应用程序完成身份验证后,您就可以使用 Twitter API 来获取 tweet。
    您可以通过使用 R 或通过使用 Jaql 获取来自 Twitter 提要的数据。因为 Jaql 被设计用于处理 JSON 数据,所以它是适用于 tweet 的默认数据格式,使用 Jaql 可能更简单一些。有人可能会决定使用 R,这样做可能纯粹是因为他们自己的 R 技能。

    通过使用 Jaql 检索来自 Twitter 的数据

    在您的应用程序完成身份验证后,我们就可以使用 Twitter API 来获取 tweet。
    因为我们想要在流化模式下,所以我们的 Twitter URL 是:
    url = “https://stream.twitter.com/1.1/statuses/filter.json?track=governmentTopic“;
    使用我们正在挖掘的政府主题的名称来替换 governmentTopic。通过使用与以下代码类似的代码,我们可以用一个变量来获取 tweet:
    1
    2
    jsonResultTweets = read(http(url));
    jsonResultTweets;

在运行 Jaql 脚本时,它会提取与政府主题相关的 tweet。这些 tweet 是以 JSON 格式返回的。
如果我们想通过位置知道关于我们的政府主题的讨论范围,可以使用下面的代码片段来获取 tweet:

1
2
3
governmentTopicDiscussionByLocation = jsonResultTweets -> transform
{location: $.location,user_id: $.from_user_id_str,date_created:
$.created_at,comment:$text} -> group by key = $.location

然后,我们可以使用下面的代码片段将此信息存储到您的 HDFS 中:

1
2
3
governmentTopicDiscussionByLocation Cnt ->
write(del("/user/governmentTopics/governmentTopic_1Tweets.del", schema =
schema { list_of_comma_seperated_json_fields}

其中的 list_of_comma_seperated_json_fields 是一些逗号分隔的字段:location、from_user_id_str 和 created_at。
这样就可以通过 Oozie 工作流来运行整个 Jaql 脚本,代码可能类似于以下代码示例:

1
2
3
4
5
6
7
8
9
10
url = "https://stream.twitter.com/1.1/statuses/filter.json?track=governmentTopic"; 
jsonResultTweets = read(http(url));
jsonResultTweets;
governmentTopicDiscussionByLocation = jsonResultTweets ->
transform {location: $.location,user_id: $.from_user_id_str,user_name:
$.user.name,user_location: $.user.location,date_created: $.created_at,comment: $.text} ->
group by key = $.location
governmentTopicDiscussionByLocation ->
write(del("/user/governmentTopics/governmentTopic_1Tweets.del",
schema = schema {location,user_id,user_name,user_location,date_created,comment}

transform 方法将会清除数据,而 write 方法会将数据保存到 HDFS。要处理流数据或动态数据,需要将此脚本与 Flume 整合,Flume 是 Apache Hadoop 生态系统中的另一个大数据工具。(您可以通过阅读了解有关此 developerWorks 文章中的 Flume 的更多信息,”使用 Flume 部署和管理可扩展的 Web 服务”。)
通过使用 R 从 Twitter 中检索数据
要使用 R 检索 tweet,需要在您的系统上安装某些软件包。虽然我们可以使用 RStudio,但下面这些步骤显示了如何设置和使用 R 控制台。
在 Ubuntu 电脑上,我完成了下面这些步骤来安装必要的 R 软件包:
安装这些软件包:

1
2
3
4
5
libcurl4-gnutls-dev 
libcurl4-nss-dev
libcurl4-openssl-dev
r-base r-base-dev
r-cran-rjson

打开 R 控制台,并运行这些命令来安装这些包来访问 Twitter:

1
2
3
install.packages(“twitteR”)
install.packages(“ROAuth”)
install.packages(“RCurl”)

将这些库加载到您的 R 工作区中:

1
2
3
4
rm(list=ls())
library(twitteR)
library(ROAuth)
library(RCurl)

现在,我们可以用下面的 R 脚本对 Twitter 进行身份验证:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
download.file(url="http://curl.haxx.se/ca/cacert.pem",destfile="cacert.pem")
requestURL <- "https://api.twitter.com/oauth/request_token"
accessURL <- "https://api.twitter.com/oauth/access_token"
authURL <- "https://api.twitter.com/oauth/authorize"
consumerKey <- myConsumerKeyFromTwitter
consumerSecret <- myConsumerSeccretFromTwitter
myCred <- OAuthFactory$new(consumerKey=consumerKey,
consumerSecret=consumerSecret,
requestURL=requestURL,
accessURL=accessURL,
authURL=authURL)

accessToken <- myAccessTokenFromTwitter
accessSecret <- myAccessSecretFromTwitter

setup_twitter_oauth(consumerKey,consumerSecret,accessToken,accessSecret)

然后,我们可以使用下面的代码片段来获取 tweet:
govt_sentiment_data <- searchTwitter(“#keyWord”,since={last_date_pulled}
keyWord 是您要分析的政府主题,last_date_pulled 是您最后一次获取 tweet 的日期。
如果您想要按固定时间间隔自动流化 Twitter 数据和拉取数据,可以使用以下代码片段替换前面的代码:

1
2
govt_sentiment_data <- filterStream( file="tweets_rstats.json",
track="#keyWord", timeout=3600, oauth=myCred)

我们可以用下面的 R 脚本来清理数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
govt_sentiment_data_txt = govt_sentiment_data$text
# remove retweet entities
govt_sentiment_data_txt = gsub(“(RT|via)((?:\\b\\W*@\\w+)+)”, “”, tweet_txt)
# remove at people
govt_sentiment_data_txt = gsub(“@\\w+”, “”, tweet_txt)
# remove punctuation
govt_sentiment_data_txt = gsub(“[[:punct:]]”, “”, tweet_txt)
# remove numbers
govt_sentiment_data_txt = gsub(“[[:digit:]]”, “”, tweet_txt)
# remove html links
govt_sentiment_data_txt = gsub(“http\\w+”, “”, tweet_txt)
# remove unnecessary spaces
govt_sentiment_data_txt = gsub(“[ \t]{2,}”, “”, tweet_txt)
govt_sentiment_data_txt = gsub(“^\\s+|\\s+$”, “”, tweet_txt)
govt_sentiment_data_txt=gsub(“[^0-9a-zA-Z ,./?><:;’~`!@#&*’]”,””, tweet_txt)

最后,要将已清理的数据保存到您的 HDFS,可以使用下面的代码片段:

1
2
3
4
hdfsFile <- hdfs.file("/tmp/govt_sentiment_data.txt", "w")
hdfs.write(govt_sentiment_data_txt, hdfsFile)
hdfs.close(hdfsFile)
write(govt_sentiment_data, "govt_sentiment_data.txt")

从 RSS 提要检索数据
除了 tweet 之外,我们还想从新闻文章中收集个人意见或观点。对于这种类型的数据,建议您组合使用 Java 和 Rome 工具从 RSS 提要中获取数据。Rome 是一个 Java 库,用于访问和操纵网络上的新闻提要。
在本示例中,我们获得了有关新闻文章的以下信息:标题、链接和描述。然后,我们从这些数据点提取我们所需的信息。
要确定将要使用的新闻提要,需要使用某种形式的网页排名 技术。该技术被用在搜索算法中,用于确定某一事项在其引用和普及方面的相关性。基本原理是,被外部实体点击或引用的几率越高,优先级就越高,因此就会出现在搜索结果的顶部。
下面的 Java 代码标识了一些新闻提要和使用网页排名,以确定它们与我们的数据相关:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
private static void getFeeds(String newsFeedUrlLink){

File f = new File(“newsFeeds.txt”);
boolean ok = false;
try {
URL feedUrl = new URL(newsFeedUrlLink);
SyndFeedInput input = new SyndFeedInput();
InputSource source = new InputSource(feedUrl.openStream());
SyndFeed feed = input.build(source);
for (Iterator i = feed.getEntries().iterator(); i.hasNext();) {
SyndEntry entry = (SyndEntry) i.next();
writeToFile(f,entry);
}
ok = true;

}
catch (Exception ex) {
ex.printStackTrace();
System.out.println("ERROR: "+ex.getMessage());

}
if (!ok) {
System.out.println();
System.out.println("FeedReader reads and prints any RSS/Atom feed type.");
System.out.println("The first parameter must be the URL of the feed to read.");
System.out.println();

}

}

private static void writeToFile(File f, SyndEntry entry) throws IOException {
FileWriter fw = new FileWriter(f.getName(),true);
BufferedWriter bw = new BufferedWriter(fw);
bw.write(entry.getTitle()+”\n”);
bw.close();

}

接下来,我们可以使用下面的代码片段将数据存储在我们使用 Twitter 数据创建的 HDFS 文件中。要将此数据添加到我们使用 Twitter 数据创建的 HDFS 文件中,必须修改 hdfs-site.xml 文件中的 dfs.support.append 属性值,因为 HDFS 默认情况下不允许将数据添加到文件。

1
2
3
4
5
6
7
8
9
mydata <- readLines("newsFeeds.txt")
myfile <- hdfs.file("/tmp/govt_sentiment_data.txt", "r")
dfserialized <- hdfs.read(myfile)
df <- unserialize(dfserialized)
hdfs.close(myfile)

//write(mydata, file = "/tmp/govt_sentiment_data.txt",append = TRUE)
hdfs.write(mydata, file = "/tmp/govt_sentiment_data.txt",append = TRUE)
government_sentiment_data <- read.hdfs(“/tmp/govt_sentiment_data.txt”)

从移动应用程序中检索数据
除了 Twitter 数据和 RSS 提要数据之外,我们还可以从包含个人意见和观点的移动应用程序中收集数据。在本示例中,我假设您创建了一个简单的移动应用程序,该应用程序已安装在允许用户提供关于政府主题或政策的意见的移动设备上。可以将 J2ME 应用程序上传到某个 WAP 服务器,移动设备(甚至是像诺基亚 3310 这样的老款设备)可以从该服务器下载和安装应用程序。用户提供的信息被发送回一个 RDBMS 并进行储存,以供将来分析使用。
您可以使用 Sqoop 将数据从 RDBMS 服务器移动到我们的 Hadoop 集群。在 Hadoop 集群上运行 sqoop 脚本的以下行:

1
2
sqoop import --options-file dbCredentials.txt --connect
jdbc:mysql://217.8.156.117/govt_policy_app --table opinions –-target-dir /tmp \ --append

–append 标记告诉 Sqoop 将导入的数据添加到我们已经从以前的数据来源获得的数据集中,该数据集通过 –target-dir 标记来指示。
将已收集的数据合并成一个数据源
在收集了来自 Twitter 的数据(通过使用 Jaql 或 R)、来自 RSS 提要的数据(通过使用 Java)和来自移动应用程序的数据(通过使用 Sqoop)后,我们会将数据添加到单个 HDFS 文件中。可以通过实现了 Oozie 工作流引擎来自动化这些脚本,并设置命令来按照某个时间间隔运行脚本,或者作为触发事件发生的结果。有关如何设置 Sqoop 和 Oozie 的更多信息,请参阅我的其他 developerWorks 文章,”将 Hadoop 与现有的 RDBMS 相集成”。
您可以增强您的 Oozie 工作流程,以便实现减少重复数据的限制,重复数据是整合来自不同来源的数据所导致的。例如,您可能会限制每个话题一个 Twitter 句柄,在您的数据集中,每个观点一个移动号码。
在组合数据上执行情感分析
在组合数据之后,我们就可以在单个数据源上完成情感分析,这使我们可以获得分析的统一性、一致性和准确性。您可以使用 R、Jaql、Pig 或 Hive 来执行这些分析。Pig 和 Hive 是具有类似 SQL 的语法的语言,运行在 Hadoop 平台上。本例中,我决定用 R 来分析检索数据,因为 R 具有用于图形表示的丰富的内置模型函数和库,比如 ggplot2。
要完成情感分析,需要有一个词典或单词列表。字典包括一组描述某一范围内的积极词和消极词的标准单词。词典确定了社交媒体中常常使用的嘲讽词、影射词、俚语、新词汇、字符和表情。这些词汇列表可从互联网上获得,定期更新,并整合到我们的情感分析逻辑中。
以下代码利用了检索到的数据,并将它们与我们的单词列表相匹配,以获得积极词和消极词的数量。积极词和消极词的总数差距为我们提供了一个得分,该得分指示了我们的数据对于我们要分析的政府主题是积极的还是消极的。

1
2
3
4
sentiment.pos=scan('/Users/charles/Downloads/r/positive-words.txt',what='character',comment.char=';')
sentiment.neg=scan('/Users/charles/Downloads/r/negative-words.txt',what='character',comment.char=';')
pos.words=c(sentiment.pos,'good','reelect','accountable','stable')
neg.words=c(sentiment.neg,'bad','corrupt','greedy','unstable')

此外,以下代码表示了情感评分算法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
require(plyr)
require(stringr)
score.sentiment = function(sentences, pos.words, neg.words, .progress='none')
{
sentence = tolower(sentence)
word.list = str_split(sentence, '\\s+')
words = unlist(word.list)
pos.matches = match(words, pos.words)
neg.matches = match(words, neg.words)
pos.matches = !is.na(pos.matches)
neg.matches = !is.na(neg.matches)
score = sum(pos.matches) - sum(neg.matches)
return(score)
}, pos.words, neg.words, .progress=.progress )
scores.df = data.frame(score=scores, text=sentences)
return(scores.df)
}

然后,我们可以通过使用下面的代码片段,调用情感得分算法函数来计算数据的得分:

1
2
require(plyr)
opinion.score <- score.sentiment(opinion.txt,pos.words,neg.words,progress='text')

最后,我们可以通过使用 R 的内置图表和图形功能,对得分数据执行进一步分析,并通过使用下面的代码片段,绘制一幅图表来显示分数条:

1
2
3
library("ggplot2")
hist(opinion.scores$score)
qplot(opinion.scores$score)

您可以通过使用 BigSheets 进一步地分析数据,BigSheets 由 IBM InfoSphere BigInsights 提供。该工具使得非技术用户可以进行各种分析,并用图表查看数据。有关如何使用 BigSheets 工具的更多信息,请阅读 developerWorks 文章 “适用于普通人的 BigSheets”。
结束语
大数据工具可以根据来自任何来源或空间的数据,提供不带偏见的洞察,从而制定正确的、准确的决策,并实施这些决策。通过采用大数据工具,比如本文中所描述的那些工具,您可以轻松地实现自己的投资回报。

0%