本文通过使用Python解析从 Twitter 获取的推文来介绍任何主题的情绪分析。
什么是情感分析?
情感分析是“计算”确定一篇文章是正面、负面还是中性的过程。它也被称为意见挖掘,可以得出演讲者的意见或态度。
为什么要进行情感分析?
- 业务:在营销领域,公司使用它来制定战略,了解客户对产品或品牌的感受,人们对他们的活动或产品发布的反应,以及消费者不购买的原因
产品。 - 政治:在政治领域,它用于跟踪政治观点,检测政府层面的声明和行动之间的一致性和不一致。它也可以用来预测选举结果!
- 公共行为:情绪分析还用于监控和分析社会现象,以发现潜在的危险情况并确定博客圈的总体情绪。
安装:
- Tweepy: tweepy 是官方 Twitter API 的Python客户端。
使用以下 pip 命令安装它:pip install tweepy
- TextBlob: textblob 是用于处理文本数据的Python库。
使用以下 pip 命令安装它:pip install textblob
此外,我们需要使用以下命令安装一些 NLTK 语料库:
python -m textblob.download_corpora
(语料库只不过是一个庞大而结构化的文本集。)
验证:
为了通过 Twitter API 获取推文,需要通过他们的 Twitter 帐户注册一个应用程序。请按照以下步骤操作:
- 打开此链接并单击按钮:“创建新应用程序”
- 填写申请详情。您可以将回调 url 字段留空。
- 创建应用程序后,您将被重定向到应用程序页面。
- 打开“密钥和访问令牌”选项卡。
- 复制“消费者密钥”、“消费者秘密”、“访问令牌”和“访问令牌秘密”。
执行:
import re
import tweepy
from tweepy import OAuthHandler
from textblob import TextBlob
class TwitterClient(object):
'''
Generic Twitter Class for sentiment analysis.
'''
def __init__(self):
'''
Class constructor or initialization method.
'''
# keys and tokens from the Twitter Dev Console
consumer_key = 'XXXXXXXXXXXXXXXXXXXXXXXX'
consumer_secret = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXX'
access_token = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXX'
access_token_secret = 'XXXXXXXXXXXXXXXXXXXXXXXXX'
# attempt authentication
try:
# create OAuthHandler object
self.auth = OAuthHandler(consumer_key, consumer_secret)
# set access token and secret
self.auth.set_access_token(access_token, access_token_secret)
# create tweepy API object to fetch tweets
self.api = tweepy.API(self.auth)
except:
print("Error: Authentication Failed")
def clean_tweet(self, tweet):
'''
Utility function to clean tweet text by removing links, special characters
using simple regex statements.
'''
return ' '.join(re.sub("(@[A-Za-z0-9]+)|([^0-9A-Za-z \t])
|(\w+:\/\/\S+)", " ", tweet).split())
def get_tweet_sentiment(self, tweet):
'''
Utility function to classify sentiment of passed tweet
using textblob's sentiment method
'''
# create TextBlob object of passed tweet text
analysis = TextBlob(self.clean_tweet(tweet))
# set sentiment
if analysis.sentiment.polarity > 0:
return 'positive'
elif analysis.sentiment.polarity == 0:
return 'neutral'
else:
return 'negative'
def get_tweets(self, query, count = 10):
'''
Main function to fetch tweets and parse them.
'''
# empty list to store parsed tweets
tweets = []
try:
# call twitter api to fetch tweets
fetched_tweets = self.api.search(q = query, count = count)
# parsing tweets one by one
for tweet in fetched_tweets:
# empty dictionary to store required params of a tweet
parsed_tweet = {}
# saving text of tweet
parsed_tweet['text'] = tweet.text
# saving sentiment of tweet
parsed_tweet['sentiment'] = self.get_tweet_sentiment(tweet.text)
# appending parsed tweet to tweets list
if tweet.retweet_count > 0:
# if tweet has retweets, ensure that it is appended only once
if parsed_tweet not in tweets:
tweets.append(parsed_tweet)
else:
tweets.append(parsed_tweet)
# return parsed tweets
return tweets
except tweepy.TweepError as e:
# print error (if any)
print("Error : " + str(e))
def main():
# creating object of TwitterClient Class
api = TwitterClient()
# calling function to get tweets
tweets = api.get_tweets(query = 'Donald Trump', count = 200)
# picking positive tweets from tweets
ptweets = [tweet for tweet in tweets if tweet['sentiment'] == 'positive']
# percentage of positive tweets
print("Positive tweets percentage: {} %".format(100*len(ptweets)/len(tweets)))
# picking negative tweets from tweets
ntweets = [tweet for tweet in tweets if tweet['sentiment'] == 'negative']
# percentage of negative tweets
print("Negative tweets percentage: {} %".format(100*len(ntweets)/len(tweets)))
# percentage of neutral tweets
print("Neutral tweets percentage: {} % \
".format(100*(len(tweets) -(len( ntweets )+len( ptweets)))/len(tweets)))
# printing first 5 positive tweets
print("\n\nPositive tweets:")
for tweet in ptweets[:10]:
print(tweet['text'])
# printing first 5 negative tweets
print("\n\nNegative tweets:")
for tweet in ntweets[:10]:
print(tweet['text'])
if __name__ == "__main__":
# calling main function
main()
以下是运行上述程序时示例输出的样子:
Positive tweets percentage: 22 %
Negative tweets percentage: 15 %
Positive tweets:
RT @JohnGGalt: Amazing—after years of attacking Donald Trump the media managed
to turn #InaugurationDay into all about themselves.
#MakeAme…
RT @vooda1: CNN Declines to Air White House Press Conference Live YES!
THANK YOU @CNN FOR NOT LEGITIMI…
RT @Muheeb_Shawwa: Donald J. Trump's speech sounded eerily familiar...
POTUS plans new deal for UK as Theresa May to be first foreign leader to meet new
president since inauguration
.@realdonaldtrump #Syria #Mexico #Russia & now #Afghanistan.
Another #DearDonaldTrump Letter worth a read @AJEnglish
Negative tweets:
RT @Slate: Donald Trump’s administration: “Government by the worst men.”
RT @RVAwonk: Trump, Sean Spicer, et al. lie for a reason.
Their lies are not just lies. Their lies are authoritarian propaganda.
RT @KomptonMusic: Me: I hate corn
Donald Trump: I hate corn too
Me: https://t.co/GPgy8R8HB5
It's ridiculous that people are more annoyed at this than Donald Trump's sexism.
RT @tony_broach: Chris Wallace on Fox news right now talking crap
about Donald Trump news conference it seems he can't face the truth eithe…
RT @fravel: With False Claims, Donald Trump Attacks Media on Crowd Turnout
Aziz Ansari Just Hit Donald Trump Hard In An Epic Saturday NIght Live Monologue
我们在计划中遵循以下 3 个主要步骤:
- 授权推特 API 客户端。
- 向 Twitter API 发出 GET 请求以获取特定查询的推文。
- 解析推文。将每条推文分类为正面、负面或中立。
现在,让我们试着理解上面这段代码:
- 首先,我们创建一个TwitterClient类。此类包含与 Twitter API 交互和解析推文的所有方法。我们使用__init__函数来处理 API 客户端的身份验证。
- 在get_tweets函数,我们使用:
fetched_tweets = self.api.search(q = query, count = count)
调用 Twitter API 来获取推文。
- 在get_tweet_sentiment 中,我们使用 textblob 模块。
analysis = TextBlob(self.clean_tweet(tweet))
TextBlob 实际上是一个建立在 NLTK 库之上的高级库。首先,我们调用clean_tweet方法使用一些简单的正则表达式从推文中删除链接、特殊字符等。
然后,当我们通过tweet创建一个TextBlob对象时,textblob 库对文本进行以下处理:- 标记推文,即从文本正文中拆分单词。
- 从标记中删除停用词。(停用词是在文本分析中不相关的常用词,如 I、am、you、are 等)
- 对标记进行 POS(词性)标记,并仅选择重要的特征/标记,如形容词、副词等。
- 将标记传递给情感分类器,该分类器通过为其分配 -1.0 到 1.0 之间的极性将推文情感分类为正面、负面或中性。
以下是情感分类器的创建方式:
- TextBlob使用电影评论数据集,其中评论已被标记为正面或负面。
- 分别从每个正面和负面评论中提取正面和负面特征。
- 训练数据现在由标记的正面和负面特征组成。这些数据是在朴素贝叶斯分类器上训练的。
然后,我们使用TextBlob类的sentiment.polarity方法来获取-1 到1 之间的tweet 极性。
然后,我们将极性分类为:if analysis.sentiment.polarity > 0: return 'positive' elif analysis.sentiment.polarity == 0: return 'neutral' else: return 'negative'
- 最后,返回解析的推文。然后,我们可以对推文进行各种类型的统计分析。例如,在上面的程序中,我们试图找出有关查询的正面、负面和中性推文的百分比。
参考:
- http://www.ijcaonline.org/research/volume125/number3/dandrea-2015-ijca-905866.pdf
- https://textblob.readthedocs.io/en/dev/quickstart.html#sentiment-analysis
- textblob.readthedocs.io/en/dev/_modules/textblob/en/sentiments.html