Twitter 政治罗盘机器:自然语言处理方法与分析
如何使用 Twitter 和机器学习模型评估政治家的党派关系并监控政治分歧
随着 2020 年大选的进行,了解一个政治家的从属关系比以往任何时候都更重要。今天,我将教你如何建立一个机器学习模型,根据他们的推文预测政党归属。
数据争论
为了收集数据/推文,我们将使用 Twitter API。所有参议员的 Twitter 句柄都在这里:(https://www . sbh4all . org/WP-content/uploads/2019/04/116 th-Congress-Twitter-handles . pdf)
我还生成了一个两党领袖的列表,我们将使用它来训练我们的模型。
民主党:乔·拜登(总统候选人),卡玛拉·哈里斯(副总统候选人),伯尼·桑德斯,伊丽莎白·沃伦
共和党人:唐纳德·川普(总统),迈克·彭斯(副总统),米奇·麦康奈尔,特德·克鲁兹
数据/特色工程
为了收集有用的特征,我们必须将推文转换成某种向量。在下图中,我将展示我们将在该模型中使用的 3 个主要特性以及如何获得它们。
作者图片
现在我将详细解释为什么我选择这些特性,为什么我认为它们是必不可少的。
可读性分数
可读性分数表明一个人的写作水平,并将他或她的写作转化为评估一个人教育水平的数字。可读性是至关重要的,因为大量的报告显示,研究生或大学毕业生更有可能保持自由的观点。因此,政治家可能会迎合他们的基础,我们希望捕捉到这一点。
下面是我们用来增加可读性分数的代码;我们使用 textstat 包,把句子变成数字。(请参考他们的网站了解这种转换的细节/科学)。在这里,我们必须删除超链接和转发,因为超链接是一个名词,而不是一个名词,算法不会识别,转发,虽然可能分享他们的情绪,但不是他们的词。
import textstatdate2_df[‘retweet’] = date2_df[‘tweet’].str.contains(‘RT’)
date2_df[‘tweet_web_r’] = date2_df.tweet.str.replace(r’http\S+’,’’)
date2_df[‘TS’] = date2_df.tweet_web_r.apply(lambda x:textstat.text_standard(x,float_output =True))
date2_df = date2_df[date2_df[‘retweet’] == False]
date2_df = date2_df.reset_index(drop=True)
情感得分
我相信我们都听说过“让美国再次伟大!”。你大概可以猜到这句话有积极的情绪。情感是我们在写作中的感受。找到对一个特定主题的情感组合,将会给我们一个政治家可能保持的党派关系的概念。
例如:
**‘让美国再次伟大’**具体来说,可能是共和党人或川普会说的话(对美国的积极情绪)。
“昨晚,乔·拜登说,没有一个拥有私人保险的人在奥巴马医改下失去了他们的计划。”大概是共和党人会说的话。(对奥巴马医改的负面情绪)。
昨晚川普说我们正在疫情“度过难关”。“真的吗,”可能是民主党人会说的话(对特朗普的负面情绪)。
假设我们来看看政治领袖的推文百分比是如何分类的。(如下图)非常有趣的是,在这段时间里,大多数共和党领导人的推文都是正面的,而民主党人的推文大多是负面的。如果非要我猜的话,民主党人可能是在批评共和党人,或者在反思疫情带来的危险。这种区别应该有助于我们的模型。
作者图片
下面是我们用来给每条推文添加情感复合得分的代码。我们使用 VADER(化合价感知词典和情感推理机)包来做这件事。关于他们算法的细节,请参考他们的网站。此外,在得到分数之前,我们删除了超链接和转发。
from nltk.sentiment.vader import SentimentIntensityAnalyzerdate2_df[‘sentiment_score’] = date2_df[‘tweet_web_r’].apply(analyser.polarity_scores)
compound_score = []
sentiment_score = list(date2_df[‘sentiment_score’])for i in range(len(date2_df[‘sentiment_score’])):
compound_score.append(sentiment_score[i][‘compound’])
date2_df[‘sentiment_score’] = compound_score
TF-IDF(术语频率逆文档频率)向量
最后,也是最关键的,功能是将一条推文的文字转化为 TF-IDF 向量。为了做到这一点,我们将共和党和民主党领导人的所有推文结合起来,并将其转化为一个语料库/文档。TF-IDF 的中心概念是我们将一个语料库转换成一个单词包向量(一个单词出现了多少次!)考虑到语料库的长度。如果你想了解更多细节,请参考 TF-IDF 维基百科页面。在这种情况下,当我们对政党领导人的话语使用频率进行矢量化,并查看其他参议员是否使用领导人正在使用的相同词语时,就可以想到这一点。
为了生成这些 TF-IDF 向量,我们必须删除超链接和转发,将所有单词转换为小写,标记化,删除停用词,并对之前的单词进行旅顺。一旦句子被清理干净,我们就可以将语料库放入 Sklearn 包中的 TF-IDF 矢量器。下面是清理操作的目的,下面是我的代码!
- 降低大小写—防止因大小写不同而重复计算单词
- 把单词的变体变成一个单词。例如:“cover”“covering”“covered”都将被视为同一个词
- 去掉无用的词——去掉无意义的词,比如命题
rep_Tfidf = TfidfVectorizer(stop_words=stop_words, ngram_range=(1,3))
rep_Tfidf.fit_transform(df[df[‘politican’].isin(rep_leaders)].len_sentence)dem_Tfidf = TfidfVectorizer(stop_words=stop_words, ngram_range=(1,3))
dem_Tfidf.fit_transform(df[df[‘politican’].isin(dem_leaders)].len_sentence )
# Put the result into a dataframe
rep_vectorize = pd.DataFrame(rep_Tfidf.transform(date2_df[‘len_sentence’]).toarray(), columns= rep_Tfidf.get_feature_names())#.sum(axis = 1)
dem_vectorize = pd.DataFrame(dem_Tfidf.transform(date2_df[‘len_sentence’]).toarray(), columns= dem_Tfidf.get_feature_names())rep_vectorize[‘politican’] = date2_df.politican
dem_vectorize[‘politican’] = date2_df.politicanrep_vectorize[‘Party’] = date2_df.Party
dem_vectorize[‘Party’] = date2_df.Party# Add in the tf-idf vectors to the sentiment score and readability score
date2_df_final = date2_df[[‘politican’,’Party’,’TS’,’sentiment_score’]]rep_vectorize = rep_vectorize.drop([‘politican’,’Party’],axis =1)
dem_vectorize = dem_vectorize.drop([‘politican’,’Party’], axis = 1)
date2_df_final = pd.concat([date2_df_final,rep_vectorize,dem_vectorize ], axis = 1 )
为了证明 TF-IDF 的重要性,以下是领导们最常用的词语。正如你在这里看到的,唐纳德·特朗普大量使用 MAGA 和 great。难怪他的很多推文都有积极的情绪。相反的趋势和用词反映了民主党人的负面情绪。他们使用“covid”、“疫情”和“火灾”(这些都是自然灾害)的次数明显多于共和党人。也许这就是为什么他们的推文中有如此多的负面情绪。
作者图片
建模
在这一点上,你可能已经注意到,我们将训练我们的模型只使用党的领导人。这背后的原因是
- 我们想用这个模型来衡量党内的不和谐。
- 如果我们使用所有的参议员,我们的模型将不堪重负,因为推特的数量太多了。
我们选择的模型是随机森林分类器。下面是我们进行训练测试分割并使用交叉验证来生成模型的代码。
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import RandomizedSearchCV
from sklearn.metrics import plot_confusion_matrix
import seaborn as sns
# Change Party code to 0 and 1
party_code = {‘R’:1, ‘D’:0}
date2_df[‘Party’] = date2_df[‘Party’].replace(party_code)date2_df_leaders = date2_df[date2_df[‘politican’].isin(leaders) == True]
date2_df_nonleaders = df[df[‘politican’].isin(leaders) == False]# Split data into train and test set
X = date2_df_leaders.drop([‘politican’,’Party’], axis = 1)
y = date2_df_leaders.PartyX_train, X_test, y_train, y_test = train_test_split(X,y , train_size = 0.75, test_size = 0.25)# Scale the data
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)param_grid = {‘n_estimators’:stats.randint(100,400), ‘criterion’:[‘entropy’]
, ‘min_samples_leaf’:stats.randint(1,6), ‘max_depth’: stats.randint(100,400)}
# Make the model with 5 fold cross validation
RF_model = RandomForestClassifier()
RF_model_cv = RandomizedSearchCV(RF_model, param_grid, cv = 5, n_iter = 60, n_jobs = 4, scoring = ‘accuracy’)
RF_model_cv.fit(X_train, y_train)
y_pred = RF_model_cv.predict(X_test)
print(plot_confusion_matrix(RF_model_cv,y_test, y_pred))
作者图片
根据我们的混淆矩阵,你可以看到我们的模型在根据他们的推文猜测领导人的政党归属方面的准确率高达 90%,这非常好。
我们现在将使用这个模型来预测我们的参议员发出的所有推文,并单独汇总他们的得分。一旦我们收集了分数,我们将在散点图的 xy 轴上绘制类似共和党的推文数量和类似民主党的推文数量
作者图片
在这里你可以看到两党之间的明显分歧。你现在可以使用同样的代码,删除你选择的一个政治家,看看他/她在这个图上的位置。这将会给你一个政治家的从属关系的定量评估,并允许你监控任何党内的不和谐。恭喜你,你刚刚建立了你自己的推特政治指南针机器。
关于我如何构建机器、我所做的数据探索以及这个模型如何处理另一个日期的数据的更多细节。请参考我的 GitHub ,直接在 minglwu427@gmail.com 给我发邮件,或者在 LinkedIn 联系我。
Twitter 情感分析:流处理的故事
如果我们可以通过人们在 Twitter 上留下的面包屑来了解他们的情绪,会怎么样?
在这篇文章中,我们将着手构建一个微服务架构,包括建立一个流处理管道,从 Twitter 的公共 API 获取推文,将其排队到一个 Kafka 主题中,并用自然语言处理对其进行消化,以获得每条推文的极性。最终的结果将在一个仪表板上可视化,上面有我能想到的所有花哨的图表;-)
快速访问链接
- 仪表板:grafana.redouaneachouri.com。
- 完整的源代码可以在 GitHub 上找到:推特-情绪-分析。
- 预处理、特征提取和模型化在本笔记本中有详细说明。
技术总结
- **概念:**自然语言处理,流处理,数据可视化。
- 技术: Python v3.8,Kafka,InfluxDB,Grafana。
- 部署平台:谷歌云平台。
目录
- 介绍
- 创建一个 Twitter 开发者帐户来访问 API
- 微服务架构:
1。Twitter API
2。制作人
3。动物园管理员&卡夫卡
4。消费者。时间序列数据库。Grafana 仪表板 - 深入研究预处理和特征提取
1。记号化
2。正常化
3。去噪或降噪
4。确定数据集中的单词密度 - 数据建模
- 结论
- 参考
介绍
witter 是一个人们分享他们对现实趋势的想法和情感的地方。这也是各种营销活动发生的战略场所,包括公司和公众人物在内的品牌可以通过分析人们在推特上发布的关于他们的信息,获得对受众看法的深刻见解。
通过情感分析,我们可以检测出一段文字传达的是积极的 T2 信息还是消极的 T4 信息。它被称为极性,当涉及到在短时间内从大量数据中收集消费者反馈时,这是一个游戏规则的改变者。
分析情绪有助于获得反馈,发现企业各方面的优势和弱点— 来源
要了解更多关于情感分析及其应用的信息,请查看这篇关于 MonkeyLearn 的优秀文章。
没有进一步的到期,让我们深入到技术细节!
GitHub 上有完整源代码:Twitter-情操-分析 。
创建一个 Twitter 开发者帐户来访问 API
为了开始收集所有这些推文,我们需要一个 Twitter 开发者账户。在这里,我将简要描述从创建帐户到为我们的第一个应用程序获得 OAuth2 载体令牌所采取的步骤。
- 前往 Twitter 开发者页面和申请开发者账户。标准 API 已经足够好了。请随意使用您的实际 Twitter 帐户(如果有的话),或者创建一个新帐户。
- 我们的下一步是进入 Twitter 实验室——所有有趣的事情都发生在这里。为此,我们需要注册一个开发环境并创建一个应用程序。我们的应用程序将有一组名为 API key 和 API secret 的凭证,我们必须严格保密,因为它们用于授权访问与我们的开发人员帐户相关的应用程序。
- 一旦获准进入开发人员实验室,我们就可以开始使用采样流端点
https://api.twitter.com/labs/1/tweets/stream/sample
:
采样流端点通过流连接实时提供所有 Tweet 数据的大约 1%的随机样本。
4.官方 API 样本流文档提供了一个坚实的基础来学习如何认证,并提供样本代码片段来开始获取实时推文流。
微服务架构
这个项目的架构,从左到右。
这个项目的架构非常简单,从 Twitter API 到 Grafana 仪表板,经过 Kafka 管道和生产者/消费者对。
所有架构都有其弱点,包括这一个,这包括网络故障、内存问题、错误、文本格式错误……我试图通过采取以下措施使主要组件(如生产者和消费者)尽可能地适应故障来解决这些问题:
- 启动时,在几秒钟的间隔内持续轮询 Kafka 代理的连接,直到代理可用。
- 在 infite
while True
循环中运行主程序,该循环捕捉异常,执行日志记录或尝试重新连接,并优雅地继续程序。
注意:实时部署在 GCP计算引擎—谷歌云平台中的虚拟机上完成。
以下是每个组件的描述:
Twitter API
- **描述:**这是 Twitter 免费提供的一个 API 端点,目的是获取全球约 1%的实时推文。访问细节请参考前面的部分“创建 Twitter 开发者账号访问 API”。
- 端点:
https://api.twitter.com/labs/1/tweets/stream/sample
- **先决条件:**一个 API 密钥和 API 秘密,将用于从 Twitter OAuth2 认证端点
[https://api.twitter.com/oauth2/token](https://api.twitter.com/oauth2/token.)
获取访问令牌。 - 示例:这是一条基本推文及其元数据的样子。对我们来说最重要的部分是
id
、lang
(语言)、和text
:
{
"data": {"attachments": {"media_keys": ["xxx"]},
"author_id": "xxx",
"context_annotations": [{"domain": {"description": "xxx",
"id": "123",
"name": "xxx"},
"entity": {"id": "xxx",
"name": "xxx"}}],
"created_at": "1970-01-01T00:00:00.000Z",
"entities": {"mentions": [{"end": 42,
"start": 123,
"username": "xxx"}],
"urls": [{"end": 42,
"start": 123,
"url": "https://t.co/xxx"}]},
"format": "detailed",
"id": "123456789",
"lang": "en",
"possibly_sensitive": False,
"referenced_tweets": [{"id": "123",
"type": "retweeted"}],
"source": "<a href='http://twitter.com/download/android' rel='nofollow'>Twitter for Android</a>",
"stats": {"like_count": 0,
"quote_count": 0,
"reply_count": 0,
"retweet_count": 0},
"text": "here comes the tweet !!!"}
}
生产者
- **描述:**生产者或发布者从 Twitter API 获取推文,并将推文的
id
和text
(只有英语,没有元数据)发送到 Kafka 主题,然后由消费者消费。此外,我们将每条推文的id
和语言lang
存储在一个时间序列数据库中,用于可视化目的(见下面的 Grafana 仪表板)。 - **语言:**Python(3.8 版本)。
- **实现细节:**我们创建一个继承自 Kafka-python 类
KafkaProducer
的类TweetsProducer
,以方便与我们的 Kafka broker 的连接和交互。这个类将与 Twitter API 建立一个永久的连接,以获取连续的 tweets 流。
动物园管理员&卡夫卡
- **描述:**使用 Kafka 的目的是拥有一个队列,在等待消费者处理消息(tweets)时,消息可以安全地存储在这个队列中,因为处理部分可能比从 Twitter 的 API 获取相对较慢。它充当 FIFO —先进先出— 数据存储。Zookeeper 用于管理大型分布式系统的状态和配置,但在我们的例子中,它不需要太多关注,因为我们的集群中只有一个 Kafka 实例。
- **需求:**Docker images forZookeeper:3 . 4 . 6和 Kafka:2.4.0 (基于 Scala 版本 2.12)。
- **实例化细节:在尝试启动和运行我的第一个dockeredKafka 实例时,这似乎不是一件容易的事情,因为它需要一些内部和外部容器网络配置,并且通过对官方 Kafka 文档和 Wurstmeister 的 Kafka 文档的一些搜索,我发现下面的配置最适合这个项目:
KAFKA_ZOOKEEPER_CONNECT
:Zookeeper 的地址和端口。由于 Zookeeper 和 Kafka 在同一个 Docker 网络上,我们可以将其设置为 Zookeeper 服务名和默认端口“zookeeper:2181”。
KAFKA_LISTENERS
:地址列表( 0.0.0.0:9093 和 0.0.0.0:9092 )及其关联的侦听器名称(内的和外的),Kafka 代理将在这些地址上侦听传入的连接。内的表示与我们的 Kafka 实例在同一个 Docker 网络内的所有客户端,例如生产者和消费者,而外的表示主机上的所有客户端,例如 Kafka 的 CLI 工具。
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP
:监听器名称和安全协议之间的映射。我们用“内:明文,外:明文”来保持简单。KAFKA_ADVERTISED_LISTENERS
:指向 Kafka 代理的可用地址列表(将发送给客户端进行初始连接)。我们将其设置为“内://kafka:9093,外://localhost:9092 ”。
KAFKA_INTER_BROKER_LISTENER_NAME
:经纪人之间通信使用的监听器名称。
卡夫卡的完整配置可以在这个项目的docker-compose . YAML文件中找到。
消费者
- *描述:消费者简单地从 Kafka 一条接一条地加载推文,执行预处理和特征提取步骤,然后推断每条推文的极性——正或负。这种极性存储在时间序列数据库中,与推文的 ID 一起,用于可视化目的(也可以进一步处理,或用于检测趋势……)。
推断或预测步骤中使用的机器学习模型被生成并存储在二进制文件中。事先腌制*格式。 - **预处理和特征提取:**请参考下面深入预处理和特征提取部分的详细描述。
- **语言:**Python(3.8 版本)。
- **实现细节:**我们创建一个继承自 Kafka-python 类
KafkaConsumer
的类TweetsConsumer
,以方便与我们的 Kafka broker 的连接和交互。
获取 tweets 之后是预处理步骤和分类。一旦获得每条推文的极性,我们就将其存储到我们的时间序列数据库中,用于可视化目的。
时间序列数据库
- **描述:**时序数据库是一个使用时间戳来索引记录的数据存储。这意味着对于每个新记录,DB 引擎都会关联一个时间戳,这是从 Unixepoch—1970 年 1 月 1 日 00:00:00 UTC 开始的以纳秒为单位的时间量。 这对于手头的问题来说再好不过了,这个问题就是存储高速到来的依赖于时间的序列数据,并且还需要作为时间序列进行快速检索。
Grafana 将访问该数据库,以输入我们的分析仪表板。 - **技术:**我们使用的是InfluxDB这是一个开源的时间序列数据库,在过去的几年里已经成为了行业标准。
Grafana 仪表板
- 链接:【grafana.redouaneachouri.com】T42。
- 描述: Grafana 被全球各种规模的公司用来监控任何可能随时间变化的事物:)从计算机基础设施到大气测量,经过工厂和仓库库存。
我们用它来创建一个仪表板,以便分析推文的极性及其随时间的变化。我们还想分析推文的其他方面,如一天或一年中不同时段的语言分布。 - ***使用细节:*为了创建我们的仪表板,我们需要将 Grafana 插入一个数据源,在我们的例子中是 InfluxDB ,我们的时间序列数据库。一旦连接上,我们就可以根据需要开始添加面板,并且为每个面板定义一个查询来获取将要显示的数据。
极性的分布。随着时间的推移,我们可以看到一个对称的趋势。
这个架构的完整描述可以在项目的docker-compose . YAML文件中找到。
深入研究预处理和特征提取
为减少数据中的维数、复杂性和噪声而采取的步骤。这是必需的,因为推文 1)是连续的多行文本,不能由简单的模型处理,2)包含不相关的信息,如连接单词和 URL,这会增加复杂性,并可能使模型产生偏差
有关实施细节,请点击查看笔记本。
标记化
文本是由空格和标点符号分隔的字符序列,其含义可以被人脑理解,但对计算机来说毫无意义。然而,我们可以根据空格和标点符号分隔符将文本分割成更小的字符串或单词,称为记号*。*
我们使用 Punkt 包中提供的预先训练好的 NLTK 模型,该模型考虑了诸如 Dr 和 Mr 这样的头衔,以及诸如 J.Doe 这样的名字中的句点。
正常化
文本中的单词可以有不同的形式。动词可以变化——“出现”、“出现”、“出现”,名词可以设置为阴性和复数——“作者”、“女作家”、“作者”、“女作家”。因此,规范化有助于将具有相同含义的单词组合在一起,使它们达到规范形式。
有两种流行的标准化类型:
- ***词干提取:*最简单的形式是从单词中去掉词缀,并在查找表中找到词干。
- 词汇化:**这是一个更高级的过程,因为它试图通过从句子的上下文中推断词义来找到单词的词汇,或字典形式——例如,“meeting”在“我正在准备与客户的一个重要的会议*”和“我明天将与客户的会议”中可能有不同的含义。*
变元化比词干化慢,但更准确,而且由于这种慢对我们的实时处理不是一个大的障碍,我们可以使用变元化进行规范化。
然而在使用 lemmatizer 之前,我们需要确定文本中每个单词的上下文,为此我们使用了一个词性标注器。点击此链接查看可能标签的完整列表。
去噪或降噪
噪音是所有不增加信息,但消耗时间和资源,并可能增加模型偏差的数据。以下是本项目中我们认为的噪音:
- ***停用词:*一种语言中最常见的词,如“a”、“the”、“it”,一般不传达一个意思,除非另有说明。
- 超链接: Twitter 使用t.co来缩短超链接,这不会在转换为 URL 的信息中留下任何值。
- ***提到:*以
@
开头的用户名和页面。 - ***标点:*它增加了上下文和意义,但使文本处理起来更复杂。为简单起见,我们将删除所有标点符号。
我们使用英语的正则表达式和停用词和标点的字典来执行过滤。
确定数据集中的单词密度
通过快速绕道,我们可以找到在我们的推文中哪些词与积极或消极情绪最相关:
- ***正面:*表情符号:)和:),感谢,感谢,追随,爱,和好的。
- ***否定:*表情符号:(和:-(,去,得到,请,要,和错过。
N.B. 单词密度是我们的建模算法隐式计算的,所以我们不需要将此作为预处理的一部分包含进来。
数据建模
有关实施细节,请点击查看笔记本。
接下来的部分,我们建立了一个监督学习模型,可以将推文分类为正面或负面*,这是我们对数据的两个标签。*
为了简单起见,对于我们所拥有的有限数量的数据(10k 条记录),我们将使用一个朴素贝叶斯分类器。**
这里是培训和测试指标(准确性),以及 10 个最具信息性的特性的表格。每行代表一个单词在正面和负面推文中出现的比率。
*Training Accuracy: 0.99957
Testing Accuracy: 0.995Most Informative Features
:( Negati : Positi = 2081.8 : 1.0
:) Positi : Negati = 1656.3 : 1.0
sad Negati : Positi = 23.6 : 1.0
sick Negati : Positi = 19.2 : 1.0
arrive Positi : Negati = 18.8 : 1.0
poor Negati : Positi = 15.9 : 1.0
community Positi : Negati = 15.5 : 1.0
x15 Negati : Positi = 13.2 : 1.0
idk Negati : Positi = 12.5 : 1.0
unfortunately Negati : Positi = 12.5 : 1.0*
改进建议
通过在定制推特上测试我们的模型,我们可以看到它未能对讽刺进行分类,因为它认为这是一种积极情绪,而不是消极情绪。* 这是因为我们的模型缺乏识别更多进化情感的数据复杂性,因此我们可以通过使用更高级的分类算法来处理这方面的工作,该算法可以处理包含进化情感的数据集的复杂性,例如*快乐、兴奋、悲伤、和恐惧。**
结论
在这篇文章中,我就如何设计和创建一个微服务架构向您提供了我的 2 美分,该架构可以从 Twitter 的实时 API 获取连续的推文流,然后通过 Kafka 进行处理,然后提取每条推文的极性。然后我们看到了如何将结果存储在一个时间序列数据库中,以便进一步分析和可视化。
我们还看到了如何在建立分类模型以推断每条推文的极性之前,对数据进行预处理并提取特征。
作为最终结果,我们得出结论,为了能够区分更多进化的情绪,如喜悦和讽刺*,我们需要一个更复杂的数据集和一个能够处理这种复杂性的分类算法。*
如果你觉得这个教程很有用,并且你想支持高质量文章的创作,考虑给我买杯咖啡吧!
你可以点击“关注”按钮来获取我的最新文章和帖子!
参考
- 情感分析及其应用— MokeyLearn
- Twitter API 文档— Twitter 开发者门户
- Kafka 概念和文档— 阿帕奇 Kafka
- 词干— 维基百科
- 引理满足— 维基百科
- 用 Python NLTK 进行情感分析— 数字海洋
- 图片来源在各自的标题中。
使用 R 的 Twitter 情感分析和可视化
如何衡量 Twitter 用户对任何特定话题的感受
图片来源:unsplash.com
对于除了 Python 或 SQL 之外已经开始进入 R 领域的数据科学家(像我一样),我们很欣赏通过许多内置包快速分析和可视化数据的容易程度。然而,当我开始寻找从外部来源提取数据的有效方法时,我了解到了与 RFacebook(脸书)、rtweet (Twitter)和 Rblpapi(彭博)等主要平台交互的 R 包。虽然用 Python 完成同样的任务是可能的,但 RStudio 的可视化界面和绘图工具已经赢得了加分。
如果您使用的是 RStudio,您可以快速连接并提取公开可用的数据。在 Twitter 的例子中,你可以获得用户列表、不同地区的热门话题以及关注者列表。这种类型的评估将证明对企业分析师、政界人士或我们这些只是对某些数据科学工具的范围感到好奇的人很有帮助。有无数种方法可以分析这种类型的数据(比如箱线图、直方图和文本挖掘等等!).
在通过 Twitter API 认证后,我想知道如何评估和可视化社交媒体网站的用户对给定主题的看法,不仅是说的话,还可能是 T2 的感觉。作为这项工作的一部分,我随机选择了两个国家(加拿大和苏格兰),然后从每个地区抽取了 100 条推文。我记录了我连接 Twitter 的 API、搜索推文、使用 Bing 进行情感分析,然后绘制结果的步骤。
**第一步:**在 RStudio 中加载需要的包(包括 rtweet)
步骤 2: 通过创建一个访问令牌,使用您的凭证对 Twitter 的 API 进行认证。获取 Twitter 访问令牌的步骤:
https://cran . r-project . org/web/packages/rtweet/vignettes/auth . html
**第三步:**根据自己选择的话题搜索推文;减少你认为合适的推文数量,并决定是否包括转发。我决定包括加拿大和苏格兰各 100 条推文,并决定不包括转发,以避免重复推文影响评估。
**第四步:**将每组推文处理成整齐的文本或语料库对象。
**第五步:**使用预处理文本转换清理推文;这包括词干词。词干提取的一个例子是将单词“计算机”、“计算的”和“计算”滚动到词根“comput”。
额外的预处理包括将所有单词转换为小写字母、删除网页链接(http 元素)以及删除标点符号和停用词。tidytext 包包含超过 1000 个英语停用词的列表,这些停用词对确定文本主体的整体情感没有帮助;这些是“我”、“我自己”、“他们自己”、“存在”和“拥有”等词。我们使用带有反连接的 tidytext 包从 tweets 中删除在步骤 3 中提取的停用词。
**第六步:**找出两国推特集合中最常用的 10 个词;这将使人们全面了解他们最关心的问题,以及他们参与这些问题的程度。
下面的输出显示了加拿大和苏格兰的前 10 个单词。
如您所见,Scotland 的输出返回的单词远不止 10 个,因为这些顶级单词中的许多都出现了相同的次数。
步骤 7: 使用 Bing lexicon 和 tidytext 包中的 get _ opinions 函数进行情感分析。R 中有许多库、字典和软件包可以用来评估文本中普遍存在的情感。tidytext 和 textdata 包就有这样的词到情感的评估库。三个通用词典是 Bing、AFINN 和 nrc(来自 textdata 包)。
要查看每个包包含的内容,您可以在 R 中运行以下命令:
get _ opinions 函数返回一个 tibble,因此要查看哪些是“积极的”和“消极的”情绪,您需要进行相应的过滤。因为我想大致了解一下,所以我不需要提取整个数据集,但是根据您的需要,您可能需要这样做。
与 Bing 相反,AFINN 词典为其词典中的每个单词分配一个“肯定”或“否定”的分数;然后,进一步的情感分析将把情感分数加起来,以确定整体表达。大于零的分数表示积极的情绪,而小于零的分数意味着消极的整体情绪。计算得分为零表示中性情绪(既不积极也不消极)。
为了使用 Bing 对加拿大的 tweets 执行情感分析,我运行了以下命令,它返回一个 tibble。
然后,为了直观地描述字数,您可以过滤并并排绘制单词,以比较积极情绪和消极情绪。
在下面的例子中,你会看到“trump”被标注为阳性。鉴于这些推文可能指的是现任美国总统,你可能希望仔细看看这个词在这些推文中实际上是如何使用的。
您可以对苏格兰的推文进行类似的分析;为了避免重复的 R 代码,我没有在这里包括这些。
**第 8 步:**获取每条推文的情感得分(您可以为此创建一个函数,如下所示)。
将该函数应用于两组推文:
以下是我们收集的加拿大第 91 条推文的正面情感评分示例。单词“帮助”和“快乐”的得分为 2。
这里我们创建了一个 tibble,它指定了国家、分数和类型:
最后,我们可以看看每组情绪的一些特征。这是两组推文情绪的并列直方图,以及一些关键的汇总统计数据。
正如您在下面看到的,我们收集的推文中的观点总体上是中立的,最高观点得分为“0”。
希望上面关于从 Twitter API 收集数据、使用 tidytext 进行情感分析以及使用 ggplot 可视化您的发现的步骤能够帮助您踏上数据科学之旅!
新冠肺炎期间基于新闻话题的推特情感分析
—网络公众如何回应疫情
距离美国首例新冠肺炎病例已经过去了 100 多天,距离加州最早的封锁令也已经过去了 45 天,在这段特殊的时间里,你感觉如何?你知道其他人对疫情的反应吗?
engin akyurt 在 Unsplash 上拍摄的照片
冠状病毒确实危及我们的身体健康,但同时,社交距离也对我们的情绪稳定性构成威胁。因此,理解新冠肺炎治下的公众情绪至关重要。
为了分析这些,我们组成了一个四人小组( Willa Yu 、 Nora Luo 、星璇张、李艾杰)参加了加州大学戴维斯分校的新冠肺炎挑战赛。我们在推特上部署了情感分析,在新闻上部署了主题建模,以帮助理解情感趋势。基于这些,我们构建了仪表板作为日常情绪监控产品来展示结果。
目录
- 分析处理
- 数据源
- 总体看:推特上发生了什么
- 进一步分析:提取多维情感
- 话题分析:当我们谈论新冠肺炎时,我们谈论什么
- 进一步的步骤和结论
分析处理
为了研究公众情绪,我们选择 Twitter 作为我们的目标领域。作为世界上最大的社交网络平台之一,Twitter 拥有大量用户生成的帖子,这些帖子以低延迟的方式密切反映了公众对这一疫情的反应。通过在其上部署自然语言处理(NLP)方法,我们能够提取并量化一段时间内的公众情绪。我们使用的工具是 TextBlob、IBM Watson Tone Analyzer、BERT 和 Mallet。
起初,我们使用 TextBlob 来探索公众情绪,这显示了一种稳步变得更加积极的上升趋势。
图一。产生 5 种情感的过程。
然后,我们以多维的方式在更详细的层次上分析情绪,以更全面地揭示趋势。我们使用 IBM Watson Tone analyzer 和手动标签来标记具有 5 种情绪的采样推文,然后使用 BERT 建立分类模型来分类具有 5 种情绪的所有推文。有了这个,我们能够:1)识别推文中更微妙的情绪;2)定义一个度量情感密度,它可以代表推文情感的复杂性。
图二。产生新闻话题的过程。
为了进一步了解情感的趋势,我们决定引入使用 Mallet 的新闻主题建模,为情感添加一层上下文。通过构建一个仪表板来比较每个主题的情绪,我们可以更具体地了解趋势。
数据源
这项分析使用的两个主要数据源是从 1 月 20 日到 4 月 26 日每天的推文和新闻。我们还从约翰霍普金斯 CSSE 医院获得了确诊病例的统计数据,以补充情绪和主题的上下文。下面是我们所用数据的概览:
表 1。数据源
总体看:推特上发生了什么
自 2020 年 1 月报告首例确诊病例以来,#新冠肺炎和其他类似标签一直在推特上流行。收集了 130 多万条与新冠肺炎相关的推文(每天大约 1 万多条),我们想知道人们在 Twitter 上对这些推文的反应。首先,我们探索了一些推文的参与度指标,如赞数。下图显示了每天每条推文的平均点赞/回复/转发次数:
图 3。一段时间内每条推文的平均赞数/回复数/转发数。对于一些数字异常高的日子,我们检索了收到最多赞/回复/转发的推文内容。
从图表中,我们可以看出,从 1 月到 3 月的几天里(例如 1 月 29 日、2 月 26 日和 3 月 9 日),人们对一些#新冠肺炎推文的反应很激烈。获得最多赞/回复/转发的推文内容从中国的科罗纳啤酒和新冠肺炎变成了美国的新冠肺炎和政府的行动。在 3 月下旬和 4 月份,每条推文的平均赞数/回复数/转发数趋于持平,这表明 Twitter 上的人们对新冠肺炎推文的反应或参与比以前少了。
Twitter 不仅是一个让人们回复他人微博的地方,也是一个发布你的微博和分享你的感受的平台。因此,除了喜欢/回复/转发,我们还挖掘了新冠肺炎相关推文的内容,以了解人们的感受和表达如何随着时间的推移而变化。在 Python 中的情感分析库 TextBlob 的帮助下,我们提取了每条推文的主观/客观(主观 ) 内容是怎样的,内容是正面还是负面(极性 ) 。平均主观性和极性的数字如下所示:
图 4。新冠肺炎相关推文的主观性(客观[0–1]主观)和极性(消极[-1 — +1]积极)如何随时间变化。虚线代表平均主观性和平均极性的简单线性回归。
根据上面的图表,随着新冠肺炎的发展,相关推文的表达平均变得更加主观(从大约 0.33 到大约 0.35),人们的感受平均变得更加积极(从大约 0.04 到大约 0.06)。为什么会这样?为什么随着越来越多的人感染冠状病毒,相关推文的情绪走向积极?带着这样的问题,我们深入研究了推文反映的实际情绪,以及人们在提到这种疾病时谈论的话题。
进一步分析:提取多维情感
我们利用伯特模型进行了进一步的分析。BERT 是谷歌预先训练的模型,可以针对广泛的 NLP 任务进行微调(了解更多)。在我们的例子中,它与 IBM 的 Watson Tone Analyzer ( 了解更多)结合使用,用 5 种情感类型来标记推文。下面是我们如何生成它们的:
第一步 :我们准备了一个训练数据集供模型学习,我们利用 Watson Tone Analyzer 为每条推文标注 5 种情绪。数据看起来像什么:
表二。推文如何被标记的例子。
第二步 :之后引入了 BERT Base 无壳模型,并进行了微调。我们的实现深受 Chris McCormick [1]的启发。在每个情感类型下建立了一个二元分类模型,然后用于为未标记的推文产生 1/0 标签。下面是我们提取的五个情感类别以及它们下面的典型推文。
图 5。典型的推文及其观点。
第三步 :标签就位后,我们定义了一些指标来帮助进一步理解公众情绪的变化。我们首先提出了一个称为情绪水平的指标,使用具有特定情绪的推文占一天总推文的比例。由于一条推文可以拥有多种情绪,我们还计算了情绪密度,以显示一条推文在一天内平均有多少种不同的情绪。这个数字会给我们一个直观的印象,那就是一天中有多少推文“充满”了不同的情绪。然后,我们计算这些指标的每日变化,并形成增量指标。下表总结了我们的指标。
表 3。指标定义和公式。
调查的结果
在将我们的模型结果放回到疫情背景下的时间线(我们使用累计确诊病例数的增长率来反映疾病的传播)后,我们总结了一些有趣的发现。
情绪等级:
图 6。情感等级的定义和 5 种情感的趋势。
●在美国首例确诊病例被报道之前(1 月 21 日),情绪“分析型”在推特中被发现最多,其他情绪水平仍然较低。
在报道第一个病例后,出现了复杂的情绪,这表明社会对疫情的认识不断提高。
●“Sad”波动较大,但在 1 月份上升后仍相对较高。
●2 月下旬,不同的情绪趋于分化,“自信”增加,“恐惧”下降。信息超载似乎让人们变得不那么敏感了。
情绪密度:
图 7。按天定义情感密度和趋势。
●通过上图中情绪密度的总体趋势,我们可以推断,从 2 月下旬到 3 月中旬,人们的情绪最密集,尤其是负面情绪,其次是 1 月下旬到 2 月中旬。
●4 月份情绪密度降低,停留在较低位置,但仍高于年初。
当我们谈论新冠肺炎时,我们谈论什么
在研究了调查期间情绪的总体趋势后,我们想添加另一层信息来剖析总体趋势。我们打算提取一些人们在谈论新冠肺炎时讨论的热门话题,以及每个话题下的极性(积极/消极)如何变化,所以我们首先从新冠肺炎相关新闻中提取几个话题,然后利用这些话题中的关键词对推文进行分类。
使用新闻文本而不是推文进行主题建模的优势在于,推文很短、不正式且高度感性,这对于主题模型来说很难处理,而新闻文本将以正式和中立的方式捕捉新冠肺炎统治下的重要事件。
提取新闻话题
我们利用自然语言处理工具包 Mallet 进行潜在狄利克雷分配(LDA)主题建模【2】,总结了 8 个主题。我们通过总结模型返回的主题关键词来命名这些主题,它们如下(按频率降序排列):新冠肺炎期间的生活,中国新冠肺炎,封锁令,医学测试&分析,政府行为,游戏季节,经济影响,医疗供应。配备了 TextBlob 的情感分析,这些主题随时间的趋势如下:
不同的主题涵盖了不同的时期,而且大多数都与事实相符。例如,在 3 月份之前,只有少数像中国新冠肺炎这样的话题出现在冠状病毒相关新闻中。三月之后,由于新冠肺炎的广泛传播,相关新闻的数量开始激增,尤其是像医学测试这样的话题。一个有趣的发现是,随着自 3 月中旬以来封锁令的执行,关于新冠肺炎期间生活的新闻达到顶峰,成为大多数平均极性得分最高的新闻。
对于新闻中这些话题的情绪来说,在新冠肺炎期间的生活无疑是所有话题中最积极也是最客观的话题,其次是游戏赛季、医疗供应和医疗测试与分析。然而,另一方面,中国的新冠肺炎这个话题得到了最负面和主观的描述。
推文中的新闻话题
根据新闻话题建模总结出的话题,使用相应的关键词对推文进行分类。按关键词过滤推文(如图所示)后,由 8 个话题提示,话题趋势如下:
图 9。8 个主题下的推文数量如何随时间变化。用于主题分类的关键词显示在底部。
同样的新闻话题趋势也适用于此,因为在中国提到新冠肺炎的推文趋势在 3 月前达到顶峰,自美国出现首例病例后开始下降。如图所示,随着时间的推移,公众越来越关注政府的行为。医疗相关、经济影响和 COVID 期间的生活主题缓慢增加。至于游戏季、面具和呆在家里的话题并没有随着时间的推移呈现出明显的上升趋势。
图 10。每个话题的情绪如何随时间变化(蓝线)。绿色背景显示了每个主题下推文的放大趋势。
当分析情绪时,我们可以看到大多数话题的积极性都在增加。
●积极度最高的话题仍然是关于新冠肺炎时期的生活。乐观情绪增长最快的一个趋势是对呆在家里的看法,这与上面提到的人们在隔离期间变得不那么敏感的观点相呼应。
●对于关于口罩和呆在家里的辩论话题,我们可以看到,在新冠肺炎疫情爆发之初,极性首先下降,但在 3 月份晚些时候上升。
●谈论政府相关问题的推文倾向于具有非常波动的情绪趋势线,极性整体上下降。
●最近,越来越多的推文谈论经济影响,如裁员和失业,但整体情绪趋向积极。
●对于游戏赛季,由于冠状病毒,许多游戏被取消,所以那些推文的情绪不是很积极。
●最后,随着时间的推移,提到“中国”的推文变得更加负面。
进一步的步骤
我们的分析显示了确诊病例的增长与情绪趋势之间的一些关系。有了地理数据、人口统计信息等更细粒度的数据,就可以产生进一步的洞察,比如监测受灾最严重地区的公众情绪。有了更具体的目标,分析将对机构或政府采取行动更有价值。
结论
在这个项目中,我们用几种方法分析了新冠肺炎相关推文的情绪。总体趋势表明,随着时间的推移,公众变得更加乐观。深入多维度的情绪分析,我们发现随着时间的推移,情绪“自信”上升,“恐惧”下降。此外,情绪密度表明,公众原来是不那么情绪化的。最后,情绪背后的话题展现了更多的细节。
抗击冠状病毒不仅需要政府的指导,还需要公众的积极态度。我们的分析提供了一种潜在的方法来揭示公众的情绪状态,并帮助机构及时做出反应。
最后但并不是最不重要的
我们真诚地感谢加州大学戴维斯分校 MSBA 项目的教师和学生行政助理为推动新冠肺炎挑战赛所做的努力。此外,我们非常感谢 Ashwin Aravindakshan 教授和 rn Boehnke 教授提出的宝贵建议。
也请查看我们创建的 GitHub 页面和 Tableau 仪表盘,以获得更具交互性的视图和更多细节。
参考文献:
[1]麦考密克、克里斯和尼克·瑞安。2019.“伯特微调教程与 Pytorch 克里斯麦考密克”。【Mccormickml.Com】T4。https://mccormickml.com/2019/07/22/BERT-fine-tuning/.
[2]普拉巴卡兰,塞尔瓦。2018.“用 Gensim (Python)进行主题建模”。机器学习加。https://www . machine learning plus . com/NLP/topic-modeling-gensim-python/。
Python 中的 Twitter 情感分析
计算 Twitter 账户的主观性和极性得分
卢克·切瑟在 Unsplash 上的照片
情感分析是数据科学和人工智能中最常见的任务之一。在本文中,我们将使用 Python、Tweepy 和 TextBlob,使用 Twitter API 和自然语言处理对选定的 Twitter 帐户进行情感分析。
介绍
我们将使用 Twitter 对书面文本进行情感分析。在这个例子中,我们将使用 Twitter,但这也可以用于商业环境中,以分析不同的社交媒体账户、对贵公司的评论、对贵公司产品和服务的评论,分析支持票、电子邮件或来自调查的自由文本,从而了解在线参与贵公司业务的人们的情绪。
你会学到什么?
您将学习如何使用 TextBlob 进行基本的情绪分析;用于 Python 的强大的自然语言处理库。我们还将使用 WordCloud 库来可视化我们的一些发现,我们还将使用 Twitter API 。熟悉 API 对于数据科学家来说是一项有用的技能。这是从互联网上获取数据的一种非常常见的方法。
问题定义
我们的任务是根据主观性和极性来分析个人推特账户的推文。我们会将每条推文区分为正面、负面和中性,并计算正面推文的百分比。我们将使用 WordCloud 库来展示来自推文中最积极的词汇。
逐步解决方案
创建虚拟环境
我们希望将特定于 Twitter 的 Python 库与我们计算机上的其他库分开。这就是为什么我们将为此项目创建一个虚拟环境。
您的计算机上应该有一个文件夹,用于存储所有虚拟环境。这个文件夹中应该没有其他东西,没有项目文件等。,只是虚拟环境不同。您可以将该文件夹称为“虚拟环境”。
有了该文件夹后,创建您的虚拟环境:
$ virtualenv twitter_venv
然后激活它:
$ source twitter_venv/bin/activate
然后安装 Tweepy 等库:
(twitter_venv) $ conda install tweepy(twitter_venv) $ conda install textblob(twitter_venv) $ conda install wordcloud
成功安装库后,您可以停用它:
(twitter_venv) $ deactivate
然后,您需要将这个虚拟环境添加到您的 jupyter 笔记本电脑配置中:
$ python -m ipykernel install — user — name=twitter_venv
一旦你完成了这一步,你就可以继续这个项目了。
创建项目文件夹
在你的电脑上为一个名为“推特-情绪-分析”的项目创建一个文件夹:
$ mkdir “Twitter-Sentiment-Analysis”
创建 Twitter 应用密钥
对于这个项目,我们将使用 Twitter API 从 Twitter 获取信息。为了做到这一点,我们需要一个 Twitter 开发者账户。
Twitter 为开发者引入了一些新的要求,完成这个过程需要几个步骤。
首先,你需要去 developer.twitter.com。如果您没有标准的 Twitter 帐户,您需要创建一个并登录。
标准 Twitter 账户将允许你登录,但不允许你做任何其他事情,你需要通过访问这个地址developer.twitter.com/en/apply-for-access并点击申请开发者账户来申请开发者访问。
你必须回答几个问题。出于使用 Twitter 开发者工具的原因,您可以选择探索 API 。
你还需要回答几个关于如何使用 Twitter API 的问题。您可以解释说,您将学习数据科学,不打算使用 API 构建任何产品(主题:您只是出于本练习的目的创建一个 Twitter 开发人员帐户,如果您打算将 Twitter 开发人员帐户用于任何其他用途,您需要提供更多详细信息)。
最后,你必须同意开发商协议和政策,你可以提交你的申请。
提交申请后,您需要点击 Twitter 发送给您的链接来确认您的电子邮件地址。确认您的电子邮件地址后,您的 Twitter 开发人员帐户的访问权限应该会立即被授予。如果你从 Twitter 上收到一封邮件,询问关于你的申请的更多信息或澄清,你需要提供所有必要的信息。
一旦你的访问权限被授予,进入这个网址https://developer.twitter.com/en/apps和创建一个应用。
你必须提供一个名称,描述,网址和你创建应用程序的原因。
一旦创建了您的应用程序,请转至密钥和令牌选项卡。这里已经创建了 API 密钥和 API 秘密密钥,您需要生成一个访问令牌和访问令牌秘密。点击生成按钮即可。你的 Twitter 情感分析项目需要这四个值。现在把它们都复制下来,放在文件中安全的地方。我们稍后会用到它们。
开始新的笔记本
通过在终端/命令提示符下键入命令,进入项目文件夹并启动 Jupyter Notebook:
$ cd “Twitter-Sentiment-Analysis”
然后
$ jupyter notebook
点击右上角的新建,选择 twitter_venv 虚拟环境。
作者图片
这将在您的浏览器中打开一个新的 jupyter 笔记本。将未命名的项目名称重命名为您的项目名称,您就可以开始了。
作者图片
如果你正在使用 Google Colab ,打开一个新的笔记本。
装载库
正在导入 Tweepy、TextBlob、WordCloud、Pandas、Numpy 和 Matplotlib。
让我们加载配置文件(确保编辑配置文件并输入简介中描述的 Twitter API 细节)。
配置文件 config.csv 的格式如下:
twitterApiKey,twitterApiSecret,twitterApiAccessToken,twitterApiAccessTokenSecret
enter-your-value,enter-your-value,enter-your-value,enter-your-value
你可以在这里找到一个例子。
现在我们需要设置 Tweepy 认证所需的所有 Twitter API 配置值。这些值将从 config.csv 文件读取到 Python 变量中。
我们正在使用 Tweepy 进行身份验证调用,这样我们就可以调用一个函数来从指定的 Twitter 帐户中检索最新的 tweets。
我们使用 elonmusk Twitter 账户作为例子,但可以随意将 Tweeter 账户更改为不同的账户;甚至是你自己的推特账号。
现在我们将从指定的 Twitter 账户中检索最后的 50 条推文&回复。
我们将从它创建熊猫数据帧。
我们通过调用 head() 函数来看看数据帧里有什么。
作者图片
在我们开始情绪分析之前,最好先清理掉每条推文中不必要的数据。
我们将创建一个clean up weet函数,它将:
- 删除提及
- 移除标签
- 删除转发
- 删除 URL
现在,我们将把它应用到熊猫数据框中的所有推文中。
我们还将使用 TextBlob 构建几个函数来计算我们推文的主观性和极性。
现在,我们将这些函数应用到我们的数据框架中,并在数据框架中创建两个新特征主观性和极性。
现在,让我们看看我们的数据框现在是什么样子。
作者图片
我们这里有一些空行,所以在进一步处理之前,让我们删除它们。
下面的命令将删除 Tweet 列等于""的所有行。
作者图片
我们可以看到,我们已经为数据框架中的主观性和极性计算了分数。
现在让我们建立一个函数,将我们的推文分为负面、中性和正面。
应用这个函数,在我们的数据框中创建另一个名为 Score 的特征。
这是我们的数据框架,包含我们所有推文的主观性、极性和得分。
作者图片
现在让我们取所有正面推文,并计算我们的数据框架中所有推文中正面推文的百分比。
57.446808510638306 % of positive tweets
我们现在可以使用 Matplotlib 可视化正面、负面和中性的推文。
作者图片
我们可以看到负面、中立和正面的推文是如何在这个账号上传播的。
我们也可以通过在图表上显示主观性和极性的精确值来可视化相同的信息。
我们还可以计算客观推文的百分比。
27.659574468085108 % of objective tweets
最后,我们还可以生成一个词云来查看我们正在分析的推文中使用的主题和最常用的词。
作者图片
对推文进行情感分析使我们能够计算主观性和极性的数值。
这可以帮助我们更好地理解这个 Twitter 账户所使用的语言。
从营销的角度来看,将这一点与关于喜欢和评论的额外信息结合起来非常有用,可以让我们发现主观性、极性和特定 Twitter 账户用户参与度之间的一些相关性。
我们鼓励你对这个例子进行更多的实验,并想出更多关于如何在实践中使用它的想法。
如果你想了解更多并尝试 Python 和数据科学,你可以看看我的另一篇文章用 Python 分析药品销售数据、用 MNIST 介绍计算机视觉和用 Python 进行图像人脸识别。
为了巩固您的知识,请考虑从头开始再次完成任务,不要查看代码示例,看看您会得到什么结果。这是巩固你的知识的一件极好的事情。
Jupyter 笔记本的完整 Python 代码可在 GitHub 上获得:
https://GitHub . com/pj online/Basic-Data-Science-Projects/tree/master/8-Twitter-情操分析
编码快乐!
还没有订阅媒体?考虑报名成为中等会员。每月只需 5 美元,你就可以无限制地阅读媒体上的所有报道。订阅 Medium 支持我和其他作家在 Medium 上。
Kaggle Twitter 情感分析:自然语言处理和文本分析
使用 Python 中的计数向量器和支持向量分类器对微博是否与仇恨相关进行分类
你好 Medium 和 TDS 家族!
在这篇文章中,我将谈论如何使用 Python 中的 CountVectorizer 来分类推文是否是种族主义/性别歧视相关的推文。在本教程中,我将使用 Google Colab 进行编程。
查看视频版这里:https://youtu.be/DgTG2Qg-x0k
你可以在这里找到我的完整代码:https://github.com/importdata/Twitter-Sentiment-Analysis
数据收集
我们将使用 Kaggle.com 来查找数据集。使用下面的链接访问 Kaggle 上的数据集。
检测仇恨推文,由分析 Vidhya 提供
www.kaggle.com](https://www.kaggle.com/arkhoshghalb/twitter-sentiment-analysis-hatred-speech)
1。了解数据集
让我们阅读数据集的上下文来理解问题陈述。
在训练数据中,如果推文与种族主义或性别歧视情绪相关联,则推文被标记为“1”。否则,推文将被标记为“0”。
2.下载数据集
现在您已经了解了数据集,接下来下载两个 csv 文件——训练和测试数据。只需点击“下载(5MB)”
下载数据集后,确保解压文件。
现在让我们转到 Google Colab!
数据探索(探索性数据分析)
让我们看看训练和测试数据是什么样的。
检查训练和测试数据
注意这里有一些特殊的字符,比如@、#、!,等等。我们将在稍后的数据清理步骤中删除这些字符。
检查是否有任何缺失值。训练和测试数据都没有缺失值。
检查训练数据的缺失值
检查测试数据的缺失值
数据清理
我们将使用 tweet 预处理器库清理数据。下面是链接:https://pypi.org/project/tweet-preprocessor/
这个库删除网址,标签,提及,保留字(RT,FAV),表情符号和表情符号。
我们还将使用正则表达式库来删除 tweet-preprocessor 库没有的其他特殊情况。
数据清理功能
比较原始推文和清理过的推文
测试和训练分离
现在我们已经清理了数据,我们将使用 train_test_split 函数进行测试和训练分割。
我们将使用 70%的数据作为训练数据,剩余的 30%作为测试数据。
使用 CountVectorizer 对推文进行矢量化
现在,我们将把文本转换成数字形式,因为我们的模型不能理解人类语言。我们将使用 CountVectorizer 对推文进行矢量化。CountVectorizer 提供了一种简单的方法来标记一组文本文档并构建已知单词的词汇表。
例如,假设我们有一个如下所示的文本文档列表。
计数矢量器示例
CountVectorizer 组合所有文档并对它们进行标记。然后计算每个文档中出现的次数。结果如下所示。
计数矢量器示例结果
模型结构
现在我们已经对所有的推文进行了矢量化,我们将建立一个模型来对测试数据进行分类。
我们将使用监督学习算法,支持向量分类器(SVC)。它广泛用于二元分类和多类分类。
您可以在 scikit-learn 文档页面上找到更多解释:https://sci kit-learn . org/stable/modules/generated/sk learn . SVM . SVC . html
准确(性)
开始了。准确率竟然是 95%!
SVC 准确度分数
关于原钻的推文分析
原钻的推特情感分析:去除假阴性
*《原钻》*是一部犯罪/惊悚片,由亚当·桑德勒、茱莉亚·福克斯、勒凯斯·斯坦菲尔德和前 NBA 球员凯文·加内特主演。由乔希和本尼·萨夫迪编剧和导演的《原钻》是一部历时十年制作的电影。故事情节讲述了一个纽约珠宝商和赌博成瘾的人,他必须找回一颗在埃塞俄比亚开采的黑欧泊未切割宝石,以便出售和偿还债务。这部电影是 A24 迄今为止票房最高的电影,在撰写本文时票房收入为 4000 万美元。
以我个人的经验来看,抛开专业影评人对这部电影的好评如潮不谈,我的同行对这部电影的评价褒贬不一。这启发了我对关于原钻的推文进行情感分析。在本文中,我们将使用 python Twitter API 包装器 Tweepy 来检索关于电影的推文,然后使用另一个名为 textblob 的 python 库对这些推文进行情感分析。
我们开始吧!
首先,你需要申请一个 Twitter 开发者账户:
在您的开发人员帐户获得批准后,您需要创建一个 Twitter 应用程序:
申请 Twitter 开发者账户和创建 Twitter 应用程序的步骤在这里有所概述。
为了访问 Twitter API,我们将使用免费的 python 库 tweepy。tweepy 的文档可以在这里找到。
- 安装
首先,确保您已经安装了 tweepy。打开命令行并键入:
pip install tweepy
2.导入库
接下来,打开您最喜欢的编辑器,导入 tweepy 和 pandas 库:
import tweepy
import pandas as pd
3.认证
接下来,我们需要我们的消费者密钥和访问令牌:
请注意,该网站建议您保持您的密钥和令牌私有!这里我们定义了一个假的密钥和令牌,但是在创建 Twitter 应用程序时,您应该使用真正的密钥和令牌,如上所示:
consumer_key = '5GBi0dCerYpy2jJtkkU3UwqYtgJpRd'
consumer_secret = 'Q88B4BDDAX0dCerYy2jJtkkU3UpwqY'
access_token = 'X0dCerYpwi0dCerYpwy2jJtkkU3U'
access_token_secret = 'kly2pwi0dCerYpjJtdCerYkkU3Um'
下一步是创建 OAuthHandler 实例。我们传递上面定义的消费者密钥和访问令牌:
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)
接下来,我们将 OAuthHandler 实例传递给 API 方法:
api = tweepy.API(auth)
- TWITTER API 请求
接下来,我们为我们有兴趣分析的字段初始化列表。现在,我们可以查看推文字符串、用户和推文时间。接下来,我们在一个 tweepy“Cursor”对象上编写一个 for 循环。在“Cursor”对象中,我们传递“api.search”方法,为我们想要搜索的内容设置查询字符串,并设置“count”= 1000,这样我们就不会超过 Twitter 的速率限制。在这里,我们将搜索关于“星球大战”的推文。我们还使用“item()”方法将“Cursor”对象转换为 iterable。
为了简化查询,我们可以删除转发,只包含英文推文。为了了解该请求返回的内容,我们还可以打印附加到每个列表的值:
twitter_users = []
tweet_time = []
tweet_string = []
for tweet in tweepy.Cursor(api.search,q='Uncut Gems', count=1000).items(1000):
if (not tweet.retweeted) and ('RT @' not in tweet.text):
if tweet.lang == "en":
twitter_users.append(tweet.user.name)
tweet_time.append(tweet.created_at)
tweet_string.append(tweet.text)
print([tweet.user.name,tweet.created_at,tweet.text])
为了实现可重用性,我们可以将它封装在一个函数中,该函数将关键字作为输入。我们还可以将结果存储在数据帧中并返回值:
def get_related_tweets(key_word):twitter_users = []
tweet_time = []
tweet_string = []
for tweet in tweepy.Cursor(api.search,q=key_word, count=1000).items(1000):
if (not tweet.retweeted) and ('RT @' not in tweet.text):
if tweet.lang == "en":
twitter_users.append(tweet.user.name)
tweet_time.append(tweet.created_at)
tweet_string.append(tweet.text)
print([tweet.user.name,tweet.created_at,tweet.text])
df = pd.DataFrame({'name':twitter_users, 'time': tweet_time, 'tweet': tweet_string})
return df
当我们可以用关键字“原钻”调用函数时:
get_related_tweets('Uncut Gems')
我们也可以传入关键字“亚当·桑德勒”:
get_related_tweets('Adam Sandler')
我们也可以传入关键字“Julia Fox”:
get_related_tweets('Julia Fox')
还有《萨夫迪兄弟》:
get_related_tweets('Safdie Brothers')
为了获得情感分数,我们需要导入一个名为 textblob 的 python 包。textblob 的文档可以在这里找到。要安装 textblob,请打开命令行并键入:
pip install textblob
下次导入 textblob:
from textblob import TextBlob
我们将使用极性得分作为积极或消极情绪的衡量标准。极性得分是一个从-1 到+1 的浮点数。
例如,如果我们定义一个 textblob 对象并传入句子“原钻是最好的!”:
sentiment_score = TextBlob("Uncut Gems is the best!").sentiment.polarity
print("Sentiment Polarity Score:", sentiment_score)
我们也可以试试“亚当·桑德勒太棒了!”:
sentiment_score = TextBlob("Adam Sandler is amazing!").sentiment.polarity
print("Sentiment Polarity Score:", sentiment_score)
我在使用 textblob 时注意到的一个缺陷是,尽管存在积极的形容词,但它对消极单词的存在给予了更大的权重,这可能会夸大错误的否定。电影标题中出现“未剪辑”一词会显著降低情感值。例如,考虑“这部电影太棒了”vs“原钻太棒了!”:
sentiment_score = TextBlob(“This movie is amazing”).sentiment.polarity
print("Sentiment Polarity Score:", sentiment_score)
sentiment_score = TextBlob(“Uncut Gems is amazing!”).sentiment.polarity
print("Sentiment Polarity Score:", sentiment_score)
我们可以看到,对于“原钻太棒了!”,在情绪依然积极的同时,明显低于前一句“这部电影太棒了”时两者应该价值接近或相等。我们解决这个问题的方法(作为一个快速解决方案)是,我们将从 tweet 中删除单词“Uncut ”,并从结果中生成情感评分。
让我们获得关于“原钻”的推文的情感极性分数,并将它们存储在一个数据框中(在删除单词“未切割”之前):
df = get_related_tweets("Tesla Cybertruck")
df['sentiment'] = df['tweet'].apply(lambda tweet: TextBlob(tweet).sentiment.polarity)
print(df.head())
我们也可以计算积极和消极情绪的数量:
df_pos = df[df['sentiment'] > 0.0]
df_neg = df[df['sentiment'] < 0.0]
print("Number of Positive Tweets", len(df_pos))
print("Number of Negative Tweets", len(df_neg))
正如我们所看到的,关于“原钻”的负面推文明显多于正面推文,但这可能是因为电影名称中出现了“未剪辑”这个词,这可能给了我们错误的否定。
让我们修改数据框架,从推文中删除“未剪切”一词:
df['tweet'] = df['tweet'].str.replace('Uncut', '')
df['tweet'] = df['tweet'].str.replace('uncut', '')
df['tweet'] = df['tweet'].str.replace('UNCUT', '')
df['sentiment'] = df['tweet'].apply(lambda tweet: TextBlob(tweet).sentiment.polarity)
print(df.head())
df_pos = df[df['sentiment'] > 0.0]
df_neg = df[df['sentiment'] < 0.0]
print("Number of Positive Tweets", len(df_pos))
print("Number of Negative Tweets", len(df_neg))
我们可以看到,当我们删除“未切割”这个词时,积极的推文明显更多。
对于代码重用,我们可以将其全部封装在一个函数中:
def get_sentiment(key_word):
df = get_related_tweets(key_word)
df['tweet'] = df['tweet'].str.replace('Uncut', '')
df['tweet'] = df['tweet'].str.replace('uncut', '')
df['tweet'] = df['tweet'].str.replace('UNCUT', '')
df['sentiment'] = df['tweet'].apply(lambda tweet: TextBlob(tweet).sentiment.polarity)
df_pos = df[df['sentiment'] > 0.0]
df_neg = df[df['sentiment'] < 0.0]
print("Number of Positive Tweets about {}".format(key_word), len(df_pos))
print("Number of Negative Tweets about {}".format(key_word), len(df_neg))
如果我们用“原钻”调用这个函数,我们得到:
get_sentiment(“Uncut Gems”)
如果我们能以编程方式可视化这些结果,那将会很方便。让我们导入 seaborn 和 matplotlib 并修改我们的 get _ 情操函数:
import seaborn as sns
import matplotlib.pyplot as pltdef get_sentiment(key_word):
df = get_related_tweets(key_word)
df['tweet'] = df['tweet'].str.replace('Uncut', '')
df['tweet'] = df['tweet'].str.replace('uncut', '')
df['tweet'] = df['tweet'].str.replace('UNCUT', '')
df['sentiment'] = df['tweet'].apply(lambda tweet: TextBlob(tweet).sentiment.polarity)
df_pos = df[df['sentiment'] > 0.0]
df_neg = df[df['sentiment'] < 0.0]
print("Number of Positive Tweets about {}".format(key_word), len(df_pos))
print("Number of Negative Tweets about {}".format(key_word), len(df_neg))
sns.set()
labels = ['Postive', 'Negative']
heights = [len(df_pos), len(df_neg)]
plt.bar(labels, heights, color = 'navy')
plt.title(key_word)
get_sentiment("Uncut Gems")
我们也可以用“亚当·桑德勒”来调用函数:
get_sentiment( “Adam Sandler”)
和“朱莉娅·福克斯”:
get_sentiment(“Julia Fox”)
还有“凯文·加内特”:
get_sentiment(“Kevin Garnett”)
还有《勒凯斯·斯坦菲尔德》:
get_sentiment(“Lakeith Stanfield”)
正如你所见,关于《原钻》及其主演的推文正面情绪多于负面情绪。
概括地说,在这篇文章中,我们讨论了如何使用 python twitter API wrapper (Tweepy)从 Twitter 中提取推文。我们还回顾了 python 情感分析包 textblob,以及如何使用它从推文中生成情感得分。最后,我们展示了如何通过删除“未剪切”这个词来修改推文,这个词会人为地降低情感分数。收集几天的数据来观察情绪如何随时间变化会很有趣。也许我会把它留到以后的文章里。
感谢您的阅读。这篇文章的代码可以在 GitHub 上找到。
如果你喜欢这篇文章,你可以在我的 patreon 链接这里做一点贡献。
祝好运,机器学习快乐!
对新型冠状病毒(新冠肺炎)的推特情感分析
自从围绕冠状病毒的阴谋论爆发以来,脸书、推特和 Instagram 等社交媒体平台一直在积极进行审查和事实核查,以打击错误信息。随着更多可靠的消息来源被放大,Twitter 变得比疫情爆发初期更支持。我认为听到真正的公众声音和发现关于冠状病毒的真实情绪会更有趣。
不要被“刮擦”这个词吓倒。如果你能浏览网页,即使你是个新手,你也能像专业人士一样进行网页抓取。所以请容忍我。
了解态度的最简单方法是收集所有包含冠状病毒这个词的推文。我甚至通过将语言设置为英语和美国境内的地形来缩小研究范围。这将确保样本数据集与搜索主题保持一致,并提高预测的准确性。
研究范围定下来之后,现在就可以开始刮了。我更喜欢使用 八分解析 说到挑选最好的网页抓取工具,它有自动检测功能,这为我节省了很多手工挑选和选择数据的时间。
Twitter 更加动态,因为它有无限的滚动,这意味着一旦我们继续向下滚动页面,推文就会显示出来。为了获得尽可能多的 tweets,我构建了一个循环列表来维护获取信息时的滚动动作。这确保了刮擦工作流保持一致,不会中断。
接下来,我创建一个提取操作。Octoparse 在我们输入搜索 URL 时呈现网页。它会将网页结构分解成子组件,这样我就可以轻松地点击目标元素来设置命令,并告诉机器人——帮我获取信息。当我点击其中一条推文时,提示面板会弹出,建议选择子元素。
在那里!相应的事件会自动添加到工作流中。它还会找到其他推文。遵循提示指南,并单击“全选”命令。最终的工作流程应该是这样的:
八解析工作流
逻辑很简单:刮刀将首先访问页面。然后,它开始提取推文,直到完成循环中的所有推文。它将重复滚动动作来定位另一组推文,并再次继续提取,直到所有信息都被成功提取。
这是我得到的最终结果:
决赛成绩
用于情感分析的自然语言处理:
NLP 是自然语言处理的缩写。它被广泛用于分析文本的情感。这个想法是建立一个分类器模型来计算单词,并理解单词所代表的含义。例如,如果我输入一条推文,它应该会告诉我句子是肯定的还是否定的。显然,更细粒度的情感分类是一项更具挑战性的任务。
我已经有了一个训练有素的模型,所以我只是使用 FastText 来预测这种情况下的推文。我得到的结果是这样的,
情感分析
正如你所看到的,这些推文被分为两组——正面的和负面的。也有概率得分。得分越高,预测就越准确。至于 0.5 左右的分数,则表现出不积极也不消极的中性情绪。
我过滤掉得分低于 0.7 的推文,做个图:
使用 Tableau 可视化
如图所示,42.2%的推文对新型冠状病毒持肯定态度,而 57.8%的推文持否定态度。获得最多回复的推文往往更积极。然而,最受欢迎的推文似乎更加负面。这一结果显示了一种具有讽刺意味的情况,因为一般公众的态度显示出一种二分法而不是统一性。这解释了为什么有人一方面抗议经济重新开放,另一方面却担心医疗工作队的解散。我们正处于矛盾或不确定的境地。
新闻媒体总是用最响亮的声音告知公众。但我们知道,大多数主要参与者持有对我们的决策有深远影响的政治观点。尤其是当阴谋论搅进来,把一切都搅得水泄不通的时候——这是危机期间的典型现象。
除了战胜疾病,我们都应该尽自己的一份力量来遏制恐惧和厌恶的蔓延。如何保持头脑清醒?不要只看故事的一面,要多听一些声音。当我们阅读新闻时,我们应该采取批判性的做法和更负责任的态度,这样我们就永远不会在数百万人面前犯类似于"围巾比口罩更好"的错误。最重要的是,我们不会指责而是团结起来共同治愈。
原载于 2020 年 6 月 12 日http://www . data extraction . io。
使用 Tensorflow.js 进行 Twitter 情感分析
使用 NLP 技术来了解人们是如何谈论你的品牌的
来源:bensonruan.com
情感分析是分析一篇在线文章(社交媒体帖子、评论)是正面、负面还是中性的过程。在过去的几年中,情感分析领域取得了重大进展,这种技术已经广泛应用于商业和政治领域。
在本文中,我们将连接到 Twitter API,通过 hashtag 收集推文,计算每条推文的情感,并构建一个实时仪表板来显示结果。下面是这个应用程序的最终结果,你可以键入你的品牌名称或你感兴趣的东西,看看人们在 Twitter 上是如何谈论它的。
点击下面的链接亲自尝试一下:
[## 使用 Tensorflow.js - Benson 技术进行 Twitter 情感分析
情感分析是分析一篇在线文章(社交媒体帖子、评论)是否积极的过程…
bensonruan.com](https://bensonruan.com/twitter-sentiment-analysis-with-tensorflowjs)
履行
这个工具对于企业监控和理解他们的品牌、产品或服务的社会情绪非常有用。我用 Tensorflow.js 情感模型制作了这个演示。如果你对它是如何建造的感到好奇,请跟随我,我会一步一步地告诉你。
#第一步:创建一个 Twitter 应用
由于我们希望从 Twitter 中提取推文来分析情绪,因此,我们需要在 Twitter 的开发者平台中创建一个应用程序。
- 登录/注册一个 Twitter 账户
- 去 https://developer.twitter.com/en/apps
- 单击创建应用程序
- 填写应用信息表单并创建
- 创建应用程序后,导航到密钥和令牌选项卡
- 生成消费者 API 密钥和访问令牌&访问令牌秘密
Twitter API 密钥和令牌
#第二步:从 Twitter 上获取推文
一旦您创建了 Twitter 应用程序并生成了 API 密钥和令牌,就该利用 Twitter 的搜索 API 来下拉一些与您正在搜索的标签相匹配的推文了。
PHP
为了使事情更简单,这里我引用了 Twitter API v1.1 调用的 PHP 包装器 twitter-api-php 。从上面的库下载 TwitterAPIExchange.php,用下面的代码创建一个 queryTwitter.php,确保用步骤 1 中生成的代码替换 Twitter API 键和令牌。
Javascript
然后我们编写一个 javascript 函数向上面的 php 页面传递一个请求,并检索 tweets。
每条 tweet 都是一个对象,具有 id、created_at、user…等属性,我们感兴趣的是"full_text"
属性
#第三步:加载情感模型
只需在 html 文件的<头>部分包含tfjs
和<的脚本。
<html>
<head>
<script src="[https://cdn.jsdelivr.net/npm/@tensorflow/tfjs](https://cdn.jsdelivr.net/npm/@tensorflow/tfjs)"></script>
</head>
或者您可以通过 npm 安装它,以便在 TypeScript / ES6 项目中使用
npm install @tensorflow/tfjs
为了进行情感分析,我们首先需要通过调用tf.loadLayersModel(url)
的 API 来加载预先训练好的情感模型和元数据。
该模型在 IMDB 的 25000 条电影评论上进行训练,这些评论被标记为积极或消极情绪。这个数据集是由 Python Keras 提供的,模型也是基于 imdb_cnn 示例在 Keras 中训练的。
#第四步:情绪分析推文
对于每条推文,我们调用 Tensorflow.js 中的model.predict(input)
API。这将对每条推文文本执行情感分析,返回 0 到 1 之间的存储,这表明它是中性的、积极的还是消极的。
#步骤 5:在表格和图表中显示结果
现在我们有了推文的情感结果,为了让它看起来更好,更容易捕捉信息,我们把它放在一个表格和一个饼状图中。
现在我们有了推文的情感结果,为了让它看起来更好,更容易捕捉信息,我们把它放在一个表格和一个饼状图中。
对于饼图,我使用的是 jquery 图表库 canvasjs
当按下回车键或点击搜索按钮时,上述函数被调用
这就是代码,恭喜你,你已经建立了你的 Twitter 情绪分析应用。
GitHub 知识库
您可以通过下面的链接下载上述演示的完整代码:
使用 npm 情绪模块的 Twitter 情绪分析连接到 Twitter API,通过标签收集推文,计算…
github.com](https://github.com/bensonruan/Sentiment-Analysis)
在 Unsplash 上由 Carlos Muza 拍摄的照片
结论
仅使用 Tensorflow.js 情感 CNN 模型,这是一种简单的情感分析方法,但无法达到高准确率,约 70%。为了提高准确性,您可以研究更复杂的模型,如 LSTM。但是,我仍然认为这是一个很好的和方便的模型,并且在某种程度上表明了情绪是积极的还是消极的。
感谢您的阅读。如果你喜欢这篇文章,请在脸书或推特上分享。如果你有任何问题,请在评论中告诉我。在 GitHub 和 Linkedin 上关注我。
R 中的 Twitter 文本分析
实践教程
帮助通信从业者通过 Twitter 等开放数据源获得可操作的见解
开放数据源是数据科学家或分析师的最佳礼物之一,因为它们允许他们免费获得有价值的见解,而不必担心数据许可证。Twitter 是世界上最受欢迎的社交媒体应用之一,因为它是免费的,并且允许用户就他们想到的任何话题发表推文。本文将关注我们如何通过 R 编程使用 Twitter 来提取有价值的见解,并使用 Tableau 将这些发现传达给相关的利益相关者。
问题陈述
“我们如何帮助传播从业者从 Twitter 获得可行的见解,以便他们能够创造更有效的沟通,满足公众的需求和关注”
本问题陈述选择的目标用户是军事通信从业者,他们渴望了解公众对新加坡军队(即国民兵役)的担忧。
Twitter 数据源的特征
对于每个数据源,我们可以用大数据的四个 V做一个简单的表示,主要是量、速度、多样性和准确性,以便对该数据源有一个总体的了解。
- 体积 —数据的规模
- 速度 —流数据分析
- 多样性 —不同形式的数据
- 准确性 —数据的不确定性
按作者分类的图片 Twitter 数据中的 4 个 V
连接到 Twitter API
我们可以在 R 编程中使用twitteR
库包来访问 Twitter API。请注意,我们需要注册一个 Twitter 开发者账户来访问 API,因为每个用户都将获得一组唯一的消费者密钥、消费者密钥、访问令牌和访问密钥。一旦我们建立了与 Twitter API 的连接,我们将通过说明搜索词(即"国服")、最大推文数量(即 n = 1000 )、搜索半径为英里的新加坡经纬度(即地理编码= '1.3521,103.8198,279 米’)和语言(即【T11
# import necessary library for Twitter API, data manipulation and text cleaning
library("twitteR")
library("ROAuth")
library("dplyr")
library("tidytext")# Set up Twitter Connection
consumer_key <- '' # removed due to confidentiality
consumer_secret<- '' # removed due to confidentiality
access_token <- '' # removed due to confidentiality
access_secret <- '' # removed due to confidentiality
setup_twitter_oauth(consumer_key ,consumer_secret,access_token ,access_secret)# extract english tweets using 'National Service' tweeted in Singapore, with retweets removed
tweets <- strip_retweets(searchTwitter('National Service',n=1000, geocode='1.3521,103.8198,279mi',lang='en'))# print length of tweets
length(tweets)
请注意,对于 Twitter 公共 API 的免费版本,我们只能请求过去 7 天的推文。结果,我们的请求中只有 17 条推文。
数据清理
当我们通过 Twitter API 提取推文时,结果不会很清晰,因为推文可能使用多种语言,还包含像表情符号这样不可读的单词。看下面的截图,要采取的明显的数据清理步骤是删除 Twitter 用户名,删除表情符号(由表示),并删除推文的 URL 链接(以蓝色突出显示)。
作者图片——通过 Twitter API 在 R
正如在上面的数据特征部分提到的,返回的 tweets 是 JSON 格式的,我们必须先将其转换成 R 格式的数据帧,然后才能使用像dplyr
这样的通用数据处理库。在我们的分析中,我们不希望任何标点符号、数字或长度小于 2 的单词。因此,在我们的文本清理代码中,我们将删除它们。
# convert tweets to df
df <- twListToDF(tweets)# text cleaning
df$text <- as.character(df$text)
df$text <- gsub("\\$", "", df$text)
df$text <- gsub("@\\w+", "", df$text)
df$text <- gsub("[[:punct:]]","", df$text)
df$text <- gsub("http\\w+", "", df$text)
df$text <- gsub("[ |\t]{2,}", "", df$text)
df$text <- gsub("^ ", "", df$text)
df$text <- gsub(" $", "", df$text)
df$text <- gsub("RT","",df$text)
df$text <- gsub("href", "", df$text)
df$text <- gsub("([0-9])","", df$text)
字频率
在每个文本分析问题中,将大块文本分解成单个单词(或标记)本质上是要采取的第一步,我们称之为标记化,可以使用tidytext
库来完成。对于我们的分析,一旦我们将文本分解成单独的令牌,我们将合计每个唯一单词的计数,以便我们可以知道用户在推特上发布的一些常见单词。
# split the text into individual tokens, remove stopwords,'National Service', sort by descending count
tokens <- data_frame(text = df$text) %>%
unnest_tokens(word, text) %>%
anti_join(stop_words) %>%
count(word, sort = TRUE)# output to csv for further usage
write.csv(tokens, './bukitmerah.csv',row.names = FALSE)
按作者分类的图像—标记及其频率的 csv 输出
如上所述,我们已经在一个 CSV 文件中输出了包含单个单词/单词及其频率的结果,稍后我们将把这些结果加载到 Tableau 中以实现可视化。
情感分析
我们可以对推文进行的另一种可能的分析是情绪分析,即对数据中的情绪进行解释和分类。这种情绪分析可以在 R 中使用nrc
词典来容易地进行,该词典将每个单词/标记分类为 10 种情绪类别中的一种,主要是愤怒、期待、厌恶、恐惧、快乐、消极、积极、悲伤、惊讶、信任。然后会进行汇总,对积极情绪和所有消极情绪进行分类。每一个正面单词将被加上分数 +1 ,每一个负面单词将被加上分数 -1 。一旦完成,每条推文的情感得分将被合并,如果得分高于 0 的**,该推文将被归类为正面。如果是低于 0** 的**,则为负。如果分数正好为 0 ,则中立。**
# get sentiment score for each tweets by using the sentiment lexicon "nrc"
text_df <- data_frame(id=df$id, text = df$text) %>%
unnest_tokens(word, text) %>%
anti_join(stop_words) %>%
inner_join(get_sentiments("nrc")) %>%
mutate(score = ifelse(sentiment=='positive',1,ifelse(sentiment=='joy',1,ifelse(sentiment=='anticipation',1,ifelse(sentiment=='trust',1,ifelse(sentiment=='surprise',1,-1)))))) %>%
group_by(id) %>%
summarise(total_score = sum(score)) %>%
mutate(sentiment = ifelse(total_score>0,'positive',ifelse(total_score<0,'negative','neutral')))# get the dataframe which contains tweet message, id and it's sentiment
sentiments <- df %>% inner_join(text_df, by='id') %>% select('text','id','created','sentiment')
# output to csv for further usage
write.csv(sentiments, './sentiments.csv',row.names = FALSE)
按作者分类的图片—推文及其观点的 csv 输出
如上所述,我们已经在一个 CSV 文件中输出了包含整个 tweet 及其情感评分(即正面/负面/中性)的结果,我们稍后会将该结果加载到 Tableau 中以供可视化之用。
调查的结果
在前面的章节中,我们已经将两个文件输出为 CSV 格式,我们将把它们加载到 Tableau 中,通过数据可视化来发现可能的见解。
使用包含单个单词/令牌的第一个文件以及所有用户在其推文中的推文频率,我们可以在 Tableau 中绘制一个单词云,单词越大表示频率越高。
按作者分类的图片—词频的 Tableau 词云
从单词 cloud 中,我们可以识别出一些常用词,如*、【线程】、【强制】、【志愿者】、【二月】、、【美国军团】、,这些词在军事背景下没有太多含义。*
让我们看看是否可以通过包含推文及其情感评分的第二个 CSV 文件发现更多有用的见解。由于正在发推文的时间也被捕获,我们可以绘制一个随时间变化的条形图,以查看一周内人们对国家服务的情绪(请记住,Twitter 公共 API 只允许长达 7 天的数据请求)。
按作者分类的图片-情绪分析的 Tableau 条形图
在 17 条相关推文中,10 条是正面的,5 条是负面的,2 条是中性的。我们还观察到,情绪在一周内朝着消极的一面发展。
缺点和限制
在使用 Twitter 公共 API 从普通公众收集关于国家服务的见解的分析中,可以发现三个主要缺点。
- Twitter API
免费帐户仅允许从 API 中提取过去 7 天的推文
超过 7 天的数据不能提供公众对国民兵役观点的全面分析
无法提供对用户人口统计数据的深入分析
2。情感分析的准确性
应该进行更深入的情感分析,因为当前的软件不考虑整个推文的情感,导致推文根据几个词被归类为错误的情感
不恰当的词语或言论无法过滤
3。无关的推文
在其他国家的“国家服务”上无关的推文可能会被捕获,因为 Twitter 对每个人开放,无论他们在哪里,都可以发布任何推文
摘要
在本文中,我们讨论了如何使用 Twitter 这样的开放数据源,从公众那里收集特定利益相关者感兴趣的任何问题的宝贵见解,在我们的案例中,这些利益相关者是军队/国家服务的通信从业者。我们还讨论了使用 R 中内置的情感分析包来解释文本中包含的情感。在数据科学领域的大部分时间里,数据科学家经常构建他们的情感分析模型,因为每个问题都需要不同的模型来获得更合适和准确的情感。希望你们现在有一个想法,我们可以考虑如何使用 Twitter API 和内置的情感分析库来启动你的文本挖掘问题!
Twitter 主题建模
使用机器学习( Gensim 线性判别分析 — LDA)来探索你的追随者最关注的话题是什么。
经过 24 轮超参数调整后,从 LDA 基本模型到模型 6.3
我是一个机器学习极客,我想把机器学习应用到我能做的一切事情上,只是为了看看结果。另一方面,我在 SoMe(社交媒体管理平台)开始了一个新的角色,在数据科学团队中,我们不断围绕使用机器学习来为我们的用户创造更多价值,并帮助他们扩大粉丝群。我们想了很久,想出了最好的主意,在这个过程中,我们意识到第一步是让用户对他们的粉丝群有一个整体的了解。
有许多数据科学和机器学习技术可以用来更好地了解你的粉丝,从在 Instagram 上应用 CNN(卷积神经网络)到在 Twitter、Linkedin 或任何其他基于文本的数据上应用自然语言处理技术。我们的大多数用户使用 SoMe 来排序和安排他们未来在 Twitter 上的帖子,所以作为第一步,我们决定向我们的用户提供关于他们的 Twitter 追随者最关注的话题的见解。要做到这一点,我们首先必须定义和记录追随者的参与度。经过长时间的讨论,我们将关注者参与度定义和评分为“当一个关注者与用户发布的内容互动 1。转发(5/5) — 2。转发评论(4/5) — 3。喜欢(3/5) —4。评论(2/5) — 5。提及(1/5)”。
下一步实际上是从 Twitter api 获取数据,我将在未来的帖子中写申请 Twitter api 并使用 Tweepy 和其他工具来提取数据和提炼数据,以获得您需要的 api 数据。您可以对任何类型的文本数据使用以下技术,并找出数据集中讨论的最重要的主题。
加载所需的包
根据您选择的 python notebook,您将需要安装和加载以下包来执行主题建模。在一些数据科学团队中,我们使用各种笔记本电脑选项,从 Azure 到 Jupyter labs 和 notebook。然而,我个人最喜欢的是 Google Colab。我建议在 Google Colab 或 Jupyter notebook 上运行以下所有代码片段。我还将链接到这个项目的 Github 库,以及一个链接到我们用于参考的最终笔记本。
数据清理
在从 Twitter api 中提取和提炼数据并导入所需的包之后,我们必须从表情符号和 URL 中清理数据,以便我们可以在接下来的步骤中对其进行标记。您可以在下面的代码片段中找到我们使用的清理语法:
正如您在下表中看到的,在进行令牌化之前,您需要删除大量表情符号和 URL。数据清理对于最终提供准确的结果至关重要,我们不希望来自网站或表情符号的单词出现在我们的主题建模结果中,因为它们在弄清楚一袋单词的一般主题方面几乎没有价值。
数据预处理
我们在数据预处理阶段的目标是将句子转换为单词,将单词转换为其词根,并删除过于常见或与主题建模项目的目的无关的单词。我们使用了以下技术来实现我们的目标,我将分享代码并带您经历每个阶段:
- 分词:将文本拆分成句子,再将句子拆分成单词。将单词小写,去掉标点符号。
- 少于 3 个字符的单词将被删除。
- 所有的停用词都被移除。
- 单词被词条化和词干化——第三人称的单词被改成第一人称,过去时态和将来时态的动词被改成现在时态,并被还原成它们的词根形式。
符号化
标记化永远是我们做任何文本数据处理之前的第一步。这意味着 spaCy 将通过对每种语言应用特定的规则来将句子分割成单词、标点符号、符号等。Spacy 是一个预先训练的自然语言处理模型,能够计算出单词之间的关系。你可以在这里了解更多关于 Spacy 的信息。
词汇化
词汇化是我们将单词转换成其词根的过程。比如:‘学习’变成了’学习’,‘见面’变成了’见面’,‘更好’,‘最好’变成了’好’。这样做的好处是,我们可以减少字典中唯一单词的总数。因此,文档-单词矩阵中的列数将随着列数的减少而增加。引理化的最终目的是帮助 LDA 模型最终产生更好的主题。
主题建模
基础模型
我们首先生成一个基础模型,用于在我们经历超参数调整阶段时跟踪我们的进展。LDA 主题模型算法需要文档单词矩阵和字典作为主要输入。对于运行 LDA 模型之前要采取的前几个步骤,我们创建了一个字典,过滤了极端情况,并创建了一个语料库对象,它是 LDA 模型需要作为主要输入的文档矩阵。
我们准备了训练 LDA 模型所需的一切。除了语料库和词典,我们还需要提供主题的数量。我们选择 5 作为基本模型。在超参数调整阶段,我们将达到要使用的主题的最佳数量。
通过打印出 LDA 模型产生的主题,我们可以粗略地猜测与每袋单词相关的主题。值得一提的是,这个单词包是按照与每个主题最相关到最不相关的顺序排列的。
模型困惑和主题连贯性提供了一个方便的衡量标准来判断一个给定的主题模型有多好。以我的经验来看,话题连贯性评分尤其有用。
我们的一致性得分为 0.17,这对于几乎所有 LDA 模型来说都是非常低的分数,但请记住这只是基础模型,我们将对其进行大幅改进。
既然构建了 LDA 模型,下一步就是检查生成的主题和相关的关键字。没有比 pyLDAvis package 的交互式图表更好的工具了,它的设计可以很好地与 Google Colab 和 Jupyter 笔记本配合使用。
那么如何推断 pyLDAvis 的输出呢?
左侧图中的每个气泡代表一个主题。泡沫越大,这个话题就越流行。一个好的主题模型会有相当大的、不重叠的气泡分散在整个图表中,而不是聚集在一个象限中。一个有太多主题的模型,通常会有许多重叠,小气泡聚集在图表的一个区域。
好的,如果我们将光标移到其中一个气泡上,右边的单词和条将会更新。这些词是构成所选主题的突出关键词。我们已经成功地构建了一个好看的主题模型。接下来,我们将通过使用 Scikit-learn 的网格搜索来改进该模型(超参数调整),然后我们将关注如何在 LDA 模型中获得主题和其他变量的最佳数量。
超参数调谐
网格搜索
LDA 模型最重要的调整参数是 n_components(主题数)。此外,我们还将搜索 learning_decay(控制学习速率)。除此之外,其他可能的搜索参数可以是 learning_offset(降低早期迭代的权重)。应该> 1)和 max_iter。如果你有足够的时间和计算资源,这些都是值得尝试的。
注意,网格搜索为 param_grid 字典中参数值的所有可能组合构建多个 LDA 模型。所以,这个过程会消耗大量的时间和资源。
我们知道主题的数量很有可能远远超过 10,但是通过网格搜索,我们发现 10 个主题比其他数量的主题表现得更好。这让我们对结果进行了深入思考,我们发现 Scikit-learn 的网格搜索跟踪的是困惑而不是一致性值,对于我们的用例,一致性值提供了最好的结果。下一步,我们将获得最佳数量的主题。
最佳主题数量
我们寻找最佳主题数量的方法是建立许多具有不同主题数量值的 LDA 模型,并选择一个给出最高一致性值的模型。
选择一些标志着话题连贯性快速增长结束的话题通常会提供有意义和可解释的话题。选择更高的值有时可以提供更细粒度的子主题。如果你看到相同的关键词在多个主题中重复出现,这可能是“主题数量”太大的信号。通过遵循这些原则,我们选择了 68 个主题作为我们用例的最佳主题数量。
最佳通过次数
Passes、chunksize 和 update_every 是具有 EM/variable 关系的参数。我们不打算在这里深入 EM/variable Bayes 的细节,但如果你好奇,可以看看这个谷歌论坛帖子和它引用的论文这里。对于我们的用例,考虑到 chuncksize 不是实质性的,update_every 在最终结果中不会有太大变化,超参数调整次数就足够了。
我们尝试了许多遍,20 遍似乎能产生最好的结果。虽然不是很大,只有几个小数点。
阿尔法类型
α是狄利克雷先验的超参数。狄利克雷先验是我们从中得出θ的分布。θ成为决定主题分布形状的参数。所以本质上,alpha 影响了我们绘制主题分布的方式。这就是为什么我们要尝试超参数调整,以选择最佳的阿尔法类型,给你一个更好的主题分布。
在我们的用例中,对称 alpha 提供了一个更好的结果,不是很好,但是我们将为我们的 LDA 模型使用对称 alpha。
衰退
学习衰减控制模型的学习速率。由于您只能选择 0.5、0.7 和 0.9,我们将尝试所有三个选项,看看哪个选项能提供最佳的一致性值。
在我们的使用案例中,0.5 衰减提供了最佳的相干值。事实上,在我们的用例中,衰减和一致性值似乎是负相关的。
最佳迭代次数
迭代在某种程度上是技术性的,但本质上它控制了我们对每个文档重复特定循环的频率。将“迭代”次数设置得足够高是很重要的。
在我们的用例中,我们尝试了 50 到 100 次迭代,但是因为我们想防止模型过度拟合,所以我们选择了 70 次,这表明一致性分数有了相当大的提高。
最小概率
该超参数忽略分配概率低于分配概率的主题。不能低于 0.01,也不能高于 0.1。
我们尝试了 0.01 到 0.1 的整个范围,coherence 值在整个范围内保持不变,因此我们将其保留为默认值 0.01,以获得尽可能多的主题。
进度跟踪表
从一开始就跟踪你的进步总是一个好习惯。我们已经通过 24 次模型超参数调整迭代跟踪了我们的进展,我们的最佳模型提供了 0.47 的一致性值,考虑到用户追随者群体中可以讨论的广泛主题,这是一个非常好的数字。
最终模型和结果
我们终于完成了我们的最终模型。我们目前使用下面片段中的模型在 SoMe 向我们的用户提供他们的追随者互动最多的话题。
如果我们仔细看看最终模型产生的主题,我们可以以很高的准确度猜测每个主题是什么。现在我们必须记住,它们是按重要性从高到低排序的。例如,如果我们看第一个主题,我们认为它是关于新冠肺炎危机的,因为前三个词是“防病毒封锁”,而不是关于“黄金”,因为“黄金”是单词包中第四个没有反映高概率的单词。
正如我们之前所介绍的,一个好的主题模型将为每个主题提供非重叠的、相当大的 blob,如果我们根据用例增加主题的数量,我们将拥有更小的 blob,并且在某些情况下会有一些重叠,但总的来说,我们可以在最终的模型中看到,分布和重叠有了显著的改善。这里好像是这样的。所以,我们没事了。
结论
在这篇文章中,我们讨论了一些前沿的主题建模方法。我们不断努力为用户构建新功能,并利用机器学习的力量为用户提供更好的体验。为了改进这个模型,你可以通过使用 gensim LDA Mallet 来探索修改它,这在某些情况下会提供更准确的结果。对于那些在构建主题模型时关心时间、内存消耗和主题多样性的人,请查看 LDA 上的 gensim 教程。
最后,我必须感谢数据科学团队的其他成员,尤其是雅各布·帕吉特和劳伦斯·金姆西。在某些情况下,我们坚信开源软件,您可以在这里找到我们所有的分析模型笔记本。
使用 Python 进行 Twitter 趋势分析
让我们尝试使用 Python 和 twitter API 来理解世界各地的 Twitter 趋势。
使用 Canva 设计
Twitter 于 2006 年推出,是当今最受欢迎的社交媒体平台之一。它有助于洞察流行趋势和重要的文化和政治时刻。在数据科学行业,twitter 分析可以用于市场营销或产品分析等任务。Twitter 数据已被用来分析政治极化和抗议运动的蔓延。在本文中,我们将了解收集 twitter 数据、处理 twitter 文本和绘制 twitter 数据地理地图的过程。我们将处理包含关键字 #python 和 #javascript 的数据子集。
收集数据
在收集数据时,我们受到两方面的限制。
1。无法收集过去(一年前等)的数据。)
2。Twitter 只免费提供其数据样本(比如其数据的 1%)。
然而,1%的数据样本相当于每天几百万条推文。许多社交媒体公司都有可供第三方开发者和研究人员使用的 API。Twitter 有许多可用的 API。
根据 tweepy docs,twitter 流 API 用于实时下载 Twitter 消息。这对于获取大量的 tweets,或者使用站点流或用户流创建实时提要非常有用。它有两个端点过滤器和样本。使用过滤器端点,用户可以使用几百个关键字、几千个用户名和 25 个位置范围请求数据。使用样本端点,twitter 将返回所有 twitter 数据的 1 %。为了从流式 API 收集数据,我们将使用一个名为tweepy
的包,它抽象了建立稳定的流式 API 连接的工作。我们需要有自己的 twitter 账户和 API 密钥进行认证。
tweepy
需要一个名为 SListener 的对象,告诉它如何处理传入的数据。这个 SListener 对象打开一个新的时间戳文件来存储 tweets,并带有一个可选的 API 参数。下面的代码将一直运行,直到显式停止(执行时间越长,文件中 Twitter JSON 对象的数量就越多)。本文中的数据集由 685 条 tweets(Twitter JSON 对象)组成,这些 tweet 是从 IST 时间晚上 7:39 到 IST 时间晚上 7:44 获取的。
现在一个名为tweets.json
的文件将包含 JSON 对象。JSON 对象的数量取决于上述连接的打开和关闭。
了解 Twitter JSON
数据格式是一种特殊的数据格式,便于人们阅读,并且易于在机器之间传输。它是字典和列表的结合。每个 JSON 对象都有许多子对象。在我们的例子中,主 JSON 对象描述了主 tweet、favourites_count、retweet_count 等。并且具有描述用户、位置等的嵌套字典。
处理数据
为了大规模分析推文,最好将这些推文存储在熊猫数据帧中。这使我们能够跨行和列应用分析方法。然而,对于嵌套字典,JSON 对象是复杂的。为了克服这个问题,我们将把 JSON 对象扁平化(将所有属性保持在一个层次上,而不是嵌套)。
让我们将 tweets 列表加载到一个数据帧中。
df_tweet = pd.DataFrame(tweets)
现在让我们比较一下拥有#python 和#javascript 的推文数量。让我们编写一个函数,它将检查所有文本列中给定的 hashtag,并返回一系列布尔值,指示每一行是否有该关键字。
我们可以注意到, #python 略微领先于 #javascript 。现在,让我们试着了解一下上述两个关键词的提及率是如何随时间变化的。关于产品和公司的推文变化很大。让我们试着捕捉随时间的变化。当数据标有日期和时间时,它被称为时间序列数据。
首先让我们将created_at
列转换为 DateTime 类型。我们需要创建一个可以随时间变化的指标。让我们创建由布尔值组成的两列python
和js
。
现在让我们创建两个标签每分钟的平均提及次数,并绘制它们的时间图。我们将使用一系列方法resample()
,这将允许我们在我们选择的时间窗口内进行汇总,并对其应用聚合函数。
resample(“1 min”).mean()
将按分钟对数据进行分组,并对分组后的数据应用均值函数。
正如我已经提到的,我们从下午 7:39 到 7:44 获取数据,我们可以注意到分钟轴的值从 39 到 44,我们可以注意到频率如何随时间变化。
情感分析
情感分析是一种从文本中获取意义的方法。它是一种自然语言处理方法,用来判断一个单词、句子、段落、文档是肯定的还是否定的。基于正面和负面单词的数量,给每个文档一个正面或负面的分数。这可以用来分析对产品、公司等的反应。
我们将使用自然语言工具包或nltk
中包含的VADER感知语义分析器。这对于分析短文档特别是推文很有用。也考虑表情符号和单词的大小写。
来自 VADER 分析器的每个情感分数提供 4 个值。阴性、阳性、中性和复合。前 3 个是不言自明的,范围在 0 到 1 之间,而复合值的范围在-1 到 1 之间。越接近 1 表示正,越接近-1 表示负。我们将再次对每分钟的数据进行重新采样,并找到每分钟的情感分数。
我们可以注意到,在我们拥有的一小部分数据中,没有负面的推文,而与 python 相比,javascript 有更多正面的推文。
根据我们收集的数据,我们可以按天、按月对数据进行采样,并执行类似的分析,以获得更多的见解。
完整的代码可以在这里找到。
结论
在本文中,我们学习了如何从 API 获取信息,还学习了如何处理 JSON 数据并对其进行时序分析。我没有把重点放在情感分析的内部解释上,这将在我以后的文章中讨论。作为即将到来的网络分析系列的一部分,我将使用图数据结构来说明 Twitter 数据的网络分析。
感谢阅读,并随时分享反馈!呆在家里,注意安全。
Twitter 美国航空公司情绪分析
用 Lightgbm 分类器进行反馈分析。
Szabo Viktor 在 Unsplash 上拍摄的照片
这里的目标是分析旅行者如何在 2015 年 2 月在 Twitter 上提及他们的感受。对于航空公司来说,利用这些免费数据为客户提供更好的服务将是非常有趣的。这个数据集可以从这里下载。
怎么分析呢?
我已经用 Python 上传了保存在本地目录中的数据:
tweets = pd.read_csv('Tweets.csv')
让我们看看数据集中包含的要素:
tweets.head()
我们在这里寻找的是名为“航空公司情绪”的列,以及我们如何根据旅行者的推文预测它。这叫做情感分析。
为了更好地了解观察结果和特征,我们可以运行以下命令,它将为我们提供每个特征的特征。
tweets.info()
让我们把表达出来的感觉想象成消极的、中性的和积极的。
plt.figure(figsize=(3,5))
sns.countplot(tweets['airline_sentiment'], order =tweets.airline_sentiment.value_counts().index,palette= 'plasma')
plt.show()
大多数人持否定态度,如果航空公司能提供适当的回应,这将是一个很好的/免费的反馈。我们还可以展示对每家航空公司的看法。
g = sns.FacetGrid(tweets, col=”airline”, col_wrap=3, height=5, aspect =0.7) g = g.map(sns.countplot, “airline_sentiment”,order =tweets.airline_sentiment.value_counts().index, palette=’plasma’) plt.show()
为了进行情感分析,我们需要导入一些库。由于这是一个分类问题,所以我使用 LGBMClassifier。
**from** **lightgbm** **import** LGBMClassifier
我们需要将这些推文(文本)转换成令牌计数矩阵。
**from** **sklearn.feature_extraction.text** **import** CountVectorizer
下一步是使用 tf-idf 表示来规范化计数矩阵。
**from** **sklearn.feature_extraction.text** **import** TfidfTransformer
我使用管道功能来完成所有步骤。
twitter_sentiment = Pipeline([('CVec', CountVectorizer(CountVectorizer(stop_words='english'))),
('Tfidf', TfidfTransformer()),
('norm', Normalizer()),
('tSVD', TruncatedSVD(n_components=100)),
('lgb', LGBMClassifier(n_jobs=-1))])
最后,CROSS_VALIDATE 与 ROC_AUC 指标一起使用。
%%time
cv_pred = cross_validate(twitter_sentiment,
tweets[‘text’],
tweets[‘airline_sentiment’],
cv=5,
scoring=(‘roc_auc_ovr’))
我们使用 ROC_AUS 测量的结果如下。
完整的代码可以通过这个链接访问。
展示项目成果的两个令人惊叹的图表(静态与交互)
在 Unsplash 上由 Adeolu Eletu 拍摄的照片
分享你的项目成果总是令人兴奋的,但更令人兴奋的是看到突出你成就的结果。选择正确的图表来展示您的项目结果可能会很棘手。可视化应该简单、全面、切中要点,当然,最好是用一种新的设计来替代条形图、饼图、折线图和散点图。
使用 Tableau 或 Power BI 软件,创建可视化的过程不需要编码来生成各种图形。但是,如果你没有这两个工具,你有什么选择?另一种选择是使用免费资源。
在非营利部门工作多年后,我发现 ggplot2 和 plotly 可以成为有用的工具。我经常要向捐赠者展示结果,我发现斜率和哑铃图非常有效。这些图表显示了两个时间段之间以及组内的比较。
这里有一个例子来说明它是如何工作的。我正在使用 希望之翼 项目的成果,该项目旨在消除处于危险中的妇女遭受的暴力。该项目为制定安全计划提供了干预措施,随后是前后测量。
我在用哑铃图可视化项目干预前后的数据。我的目的是展示服务价格在项目开始和结束时的不同。首先,我将创建一个数据集,然后使用 geom_dumbell 函数来绘制我的结果。在我的数据集中,我有以下服务名称(法律服务、HIV/STD 咨询、心理健康、自助团体和宗教咨询)、显示项目受益人使用这些类型服务频率的基线调查结果(14、5、15、7、37),以及关于这些数字如何变化的 3 个月跟踪调查结果(29、13、29、16、31)。我还计划添加关于差异的列,因为我也想在图中使用它们。要理解 geom _ dumbling 函数的逻辑,我建议你查阅一下关于 ggalt 包 的文档。
这是我得到的情节。它具有之前/之后的比较,并且在右侧,它以百分比的形式说明了变化。
用同样的数据,我正在用 plotly 制作交互式哑铃图。
单击下面的输出,在单独的窗口中打开它:
[## 希望之翼:服务利用率|阿普加切夫制作的折线图| plotly
阿普加切夫的“希望之翼:服务利用率”的交互图和数据是一个折线图,显示了之前与…
chart-studio.plotly.com](https://chart-studio.plotly.com/~apugachev/7.embed)
斜率表可以作为哑铃的替代品。显示两个时间点之间的变化方向令人印象深刻。我再次使用希望之翼项目的成果,但现在我的意图也是为了表明方向。我想展示我的项目指标是如何变化的。在我的例子中,我指的是暴力程度,暴力程度的降低证明了项目的有效性。首先,我将创建数据集并使用允许我用线连接两点的 geom_segment 函数。在我的情况下,两点将代表基线和 3 个月的随访。
通过使用 ggplotly 函数,还有一种方法可以将 ggplot2 输出更改为 plotly 输出。请注意,这并不适用于所有图表。
单击下面的输出,在单独的窗口中打开它:
[## 亲密伴侣暴力(IPV)和基于性别的暴力(GBV)的发生率|由…制作的折线图
阿普加切夫关于“亲密伴侣暴力(IPV)和基于性别的暴力(GBV)的流行程度”的互动图表和数据…
chart-studio.plotly.com](https://chart-studio.plotly.com/~apugachev/9.embed)
总而言之,如果你的目标是展示项目的影响,考虑斜率或哑铃图是值得的。上面的例子展示了如何使用 ggplot2 和 plotly 从头开始创建静态和交互式可视化。这些图表可以为您关于项目影响的讨论增加价值。它们是不言自明的,并且准确地展示了观众需要了解的内容。
[1]希望之翼项目,吉尔吉斯斯坦,2014–2016 年
[2]鲍勃·鲁迪斯(2017 年 2 月 15 日),包“gg alt”【https://cran.r-project.org/web/packages/ggalt/ggalt.pdf】T2
[3]Hadley Wickham,线段与曲线https://gg plot 2 . tidy verse . org/reference/geom _ segment . html # details
K-均值聚类的两个挑战
如何“明智地”选择 k 和初始质心
K-means 聚类算法旨在将数据划分为 k 个聚类,使得同一聚类中的数据点相似,而不同聚类中的数据点相距较远。两点的相似性是由它们之间的距离决定的。在这篇文章中,我将讨论在使用 k-means 聚类时需要记住的两个关键点。如果您不熟悉 k-means 聚类,您可能希望先阅读 k-means 算法的详细说明。
详细的理论解释和 scikit-learn 实现
towardsdatascience.com](/k-means-clustering-explained-4528df86a120)
为了充分利用 k-means 聚类算法,需要明智地应对两个挑战:
- 定义聚类的数量
- 确定初始质心
定义集群数量
在运行 k-means 聚类算法之前,我们需要声明聚类的数量。它不能确定聚类的最佳数量。K-means 将数据集划分为我们预先确定的聚类数。对于我们来说,找到最佳的集群数量也是一项具有挑战性的任务。我们不能只看数据集就找出我们应该有多少分区。
K-means 聚类试图最小化聚类内的距离。该距离被定义为聚类内距离和(WCSS)。
让我们看看 WCSS 随着不同的集群数量而变化。假设我们有以下非常简单的数据集:
让我们现实一点,有一个集群:
如果我们有一个集群,质心将是红色方块。WCSS 计算如下:
每个数据点和平均值之间的平方距离之和(红色方块)。随着聚类数量的增加,数据点和质心之间的平均距离减小,因此 WCSS 减小。
让我们看看两个集群的情况:
正如你所看到的,数据点和质心之间的平均距离减小了。请记住,距离的数量与集群的数量无关。无论存在多少个聚类,我们都将计算 n 个距离,其中 n 是数据点的数量。所以只能着眼于平均距离。
WCSS 在 3 个集群中进一步下降:
到目前为止,我们已经看到了 1、2 和 3 簇的 WCSS,其计算如下:
- k=1 > WCSS = 35,16 单位
- k=2 > WCSS = 20,91 单位
- k=3 > WCSS = 2,95 单位
WCSS 还会下降多远?嗯,最终会是零。我们可以拥有的最大聚类数等于数据点的数量。虽然没有用,但是我们可以为每个数据点建立一个单独的集群。那么数据点和它的质心之间的距离变为零,因为数据点的质心就是它本身。
那么,为什么不对每个数据点进行聚类,并使 WCSS 为零呢?因为,在这种情况下,我们将有一个更大的问题,即过度拟合。过了一段时间后,我们将通过增加集群的数量来获得一点点 WCSS。下图显示了 WCSS 随着集群数量的增加而发生的变化。
正如你所看到的,在某一点之后,WCSS 并没有减少多少。我们应该寻找斜率急剧变化锐边。红色方块标记的边是我们的最佳聚类数。
如果我们选择大于该点的 k,WCSS 仍会降低,但不值得冒过度拟合的风险。
确定初始质心
K-means 是一个迭代过程。它建立在期望最大化算法的基础上。确定集群数量后,它通过执行以下步骤来工作:
- 为每个簇随机选择质心(簇的中心)。
- 计算所有数据点到质心的距离。
- 将数据点分配给最近的聚类。
- 通过取聚类中所有数据点的平均值,找到每个聚类的新质心。
- 重复步骤 2、3 和 4,直到所有点收敛并且聚类中心停止移动。
我们现在专注于第一步。根据数据集的底层结构,不同的初始质心可能最终形成不同的聚类。除此之外,完全随机选择质心可能会增加运行时间,因此算法需要更多的时间来收敛。
我们可能想寻找一种聪明的方法,而不是以完全随机的方式选择初始质心。那个聪明的办法就是 k-means++ 。
K-means++确保了一种更智能的方式来初始化集群。如维基百科所述,
k -means++ 是一种为 k -means 聚类算法选择初始值(或“种子”)的算法。
k-means 和 k-means++的区别只是选择初始质心。剩下的步骤完全相同。K-means++从数据集中的数据点随机均匀地选择第一个质心。每个随后的质心从剩余的数据点中选择,其概率与其到该点最近的现有质心的距离的平方成比例。
幸运的是,在 scikit-learn 中实现了 k-means++。由 sklearn.cluster.KMean s 的“ init 参数指定,默认值为 k-means++。init 参数的另一个选项是“random ”,它随机初始化质心。
感谢您的阅读。如果您有任何反馈,请告诉我。
参考文献
偏差和方差:改进每个模型的两个重要的机器学习概念
克里斯蒂娜·特里普科维奇在 Unsplash 上的照片
了解偏差和方差如何提高模型的准确性
如果你不明白自己做得对或错,那么训练任何新模型都是困难的。大多数时候,模型是黑匣子,它吸入数据,吐出精确的数字。理解为什么你的模型表现不佳是知道你如何改进它的关键。
- 通过识别偏差和方差,了解为什么你的模型表现不佳。
- 了解如何通过减少偏差和方差来改进您的模型。
识别偏差和差异
先说误差。误差是你的模型在测试数据上有多不准确。
如果你的模型在测试集上达到 86%的准确率,那么就有 14%的误差。这种误差一部分是偏差,一部分是方差。
上图两个要点:
1。偏差是训练集
2 的误差。方差是训练和测试准确度之间的差距
偏见
偏差描述了模型从训练数据中学习的能力。较大的偏差意味着模型很难从训练数据中学习。
如果模型对训练数据有 90%的准确度,那么模型有 10%的偏差。这种偏见有些是可以避免的,有些是不可避免的。
不可避免与可避免的偏差
不可避免的偏差被称为最优误差率。这是模型性能的上限。它认识到,一些任务,如字幕或股票预测,是不可能 100%准确预测的,即使对人类来说也是如此。因此,我们可以预期,即使在一个完美的世界中,我们的模型至少在某些时候是错误的。
如果你决定你的模型至少有 4%的时间是错误的,那么这个模型就有 4%不可避免的偏差。
可避免偏差是最优错误率与训练误差之差。这是我们可以尝试减少的误差,以实现最佳误差率。
差异
方差描述了您的模型对其尚未见过的数据的泛化能力。我们将方差定义为训练精度和测试精度之间的差异。
偏差与方差的权衡
大多数用来减少偏差或方差的方法都是以牺牲一个为代价来减少另一个。有一些例外,但是大多数时候构建最佳模型意味着最小化偏差和方差。
减少偏差和差异
减少可避免的偏差
- 增加模型尺寸 增加模型尺寸是减少可避免偏差的一种方法。
模型越大,需要调整的参数越多。更多的参数允许模型学习更复杂的关系。您可以通过向模型添加更多的层或节点来增加模型的大小。模型从数据中学习得越好,就越接近最佳错误率。
- 减少规则 减少模型的规则允许模型更好地拟合训练数据。然而,较少的正则化意味着您的模型不会同样概化,从而增加了方差。这是偏倚与方差权衡的经典例子。
- 更改模型架构 更改模型架构可以帮助它更好地适应数据集。这类似于增加模型的大小,但是有更多的自由度。您可以更改以下任何内容,但要谨慎。
- 这些技术可以改变偏差和方差。
1。层激活函数(tanh,relu,sigmoid,…)
2。模型正在学习什么(安,CNN,RNN,KNN…)
3。模型是如何学习的(Adam,SGD,RMSprop,…)
4。更改其他超参数(学习率、图像大小等)
- 添加新特征 向训练数据添加新特征可以向模型提供更多信息,模型可以利用这些信息进行学习。这可以通过称为特征工程的过程来完成。在此过程中,您还可以将在开发早期剪切的功能添加回去。
减少差异
- 添加更多的数据 添加更多的数据是最简单的方法,几乎总是,增加你的模型的性能。添加更多数据的效果可以在 Andrej Karpathy 的文章Un reasonable Effectiveness of Data中看到。此通常不会影响偏差,因此是减少方差的首选方法。
- 增加正则化 增加正则化可以防止模型在数据上过度拟合。虽然这减少了方差,但总会增加偏差。除了减少方差之外,加入正则化还可以产生显著的积极影响。我最喜欢的是使用 drop out 来实现蒙特卡罗辍学。
- 减小模型尺寸 减小模型尺寸有助于减少训练数据的过度拟合。尽管这种技术是最简单的,但它降低了模型学习数据集复杂模式的能力。通过添加正则化通常可以看到相同的结果,因此该方法是更优选的。
- 特征选择 通过删除不需要的特征来减少数据集的维数是减少模型方差的一个好方法。你可以用主成分分析(PCA) 过滤掉特征或者组合成几个主成分。
完整的画面
将所有这些放在一起,你应该能够识别偏差和方差,并知道如何减少它。
摘要备忘单
减少偏差
- 增加模型尺寸
- 减少正规化
- 改变模型架构
- 添加功能
减少方差
- 添加更多数据
- 减小模型尺寸
- 添加正规化
- 功能选择
资源
所有这些概念以及更多内容都包含在吴恩达的《机器学习的渴望》一书中。它可以免费阅读、打印和分发。我强烈建议你去看看。
所有的图表都是作者创作的:
阅读米基安·穆瑟在媒体上的文章。数据科学家 https://mm909.github.io/Mikian/.·天天、米基安·穆塞尔和…
medium.com](https://medium.com/@mikianmusser)
为了在 Python 中轻松操作数据,您必须知道两个熊猫函数
掌握这些 pandas 函数(和方法)可以缩短代码,提高性能,避免麻烦。
熊猫——其中一只与众不同(右上图由斯坦·w .在 Unsplash 上拍摄)
我做大量的数据工作——一些 it 数据科学,一些 it 数据可视化,一些 it 数据邻近——比如摆弄体育分析。所有这些都是用 Python 完成的,而且几乎所有的数据操作都会用到 Pandas。
我喜欢认为在这段时间里,我学到了一两件关于使用熊猫的事情。我使用熊猫的方式与几年前我刚开始涉足熊猫时大不相同。我使用 Pandas 越多,我发现自己越少走出它进行数据操作。我的印象是,我的代码变得更加简洁,结果节省了大量时间。
所以在这篇文章中,我想和你们分享一些我现在离不开的功能——我相信你会发现它们和我一样有用。
是呆在室内的时候了,所以今天我使用来自 Kaggle 的网飞电影数据集。如果没有别的,你可能已经发现了一些值得看的东西:)。
在开始之前
Packages
我假设您熟悉 python。即使你相对较新,这个教程也不应该太难。
你需要pandas
和plotly
。用一个简单的pip install [PACKAGE_NAME]
安装每一个(在您的虚拟环境中)。
内容,内容无处不在
使用以下命令将网飞csv
数据文件加载到熊猫数据帧中:
nf_df = pd.read_csv('srcdata/netflix_titles.csv')
让我们用.head()
方法检查数据帧。
实际上,这引出了我的第一个建议。
在熊猫中设定显示选项
如果你像我一样,不使用 Jupyter notebook 或其变体,你可能会对 Python 外壳中熊猫有限的显示宽度感到沮丧。
这是运行nf_df.head()
时输出的样子。
这并不能告诉你太多…
没那么有用。但是等等!Pandas 有一个.set_option
功能,您可以使用它来调整要显示的列数,以及显示的总宽度。将您的参数设置为如下所示:
pd.set_option('display.max_columns', desired_cols)
pd.set_option('display.width', desired_width)
现在您的 shell 将输出更有用的东西。
更有用的输出
还有其他可以通过.set_option
功能设置的选项——如果您有兴趣,可以在这里查看文档。
。分配
你曾经看到过这条信息吗?
<input>:1: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
如果这从未发生在你身上,你比我更好——你可能已经通过文件或一本书正确地了解了熊猫。
而熊猫官方的解释可以在这里找到;但是 TL;dr 版本是,Pandas 警告您,无法确定您是否正在操作数据帧的副本(在这种情况下,您可能不会更改任何值)。
这也是使用.assign
的原因之一。使用.assign
,返回一个新对象,以避免由于SettingWithCopyWarning
而导致的潜在混乱,不管实际问题是否存在,该问题经常被提出。
接下来,一个更明显的原因是创建一个新的数据帧,现有的数据帧由于某种原因被保留。正如我提到的,.assign
返回一个新的对象,所以我们可以避免类似这样的问题:
第一个例子打印 13,因为我们不小心修改了原始数据帧(nf_df
),而在第二个例子中,原始数据帧保持不变,有 12 列。
现在,让我们继续讨论.apply
——这可能是熊猫最被低估的功能之一:)。
。应用
如果你和我一样,你可能尝试过在一个循环中操作熊猫数据——可能会做类似这样的事情:
for i in range(len(nf_df)):
nf_df.iloc[i, 1] = ...some function here
停下来。没必要这样。
这就是.apply
方法的作用。它沿着数据帧的轴对每个元素应用一个函数。让我们来看一些例子。
示例 1 —按发布年份统计的内容数量
我们的数据框架包括一个发布年份的列(release_year
)。分布可以绘制如下,如下所示:
fig = px.histogram(nf_df, x='release_year')
fig.show()
按年份划分的网飞图书发行数据直方图
如果我们想看十年的数据呢?简单—创建一个新列‘decade’
,如下所示:
nf_df['decade'] = nf_df.release_year.apply(lambda x: str(x)[:3]+'0s')
这里,我们通过nf_df.release_year
获取release_year
列数据,并应用 lambda 函数lambda x: str(x)[:3]+’0s’
。
Lambda 函数看起来令人困惑,但是一旦你习惯了,它就非常简单。在这里,它抓取每个元素(x
),首先应用转换str(x)[:3]
获得年份字符串的前 3 个字母,并在末尾添加’0s’
。
所以,看看我们新十年专栏的柱状图:
fig = px.histogram(nf_df, x='decade', category_orders={'decade': np.sort(nf_df.decade.unique())})
fig.show()
按十年划分的网飞图书发行数据直方图
看到这有多简单了吗?
另外,你可能已经注意到我使用了.unique()
方法。这是一个非常有用的方法,它将返回该列中唯一实体的数组——不要错过它!
好吧。我们再来看一个使用.apply
的例子。
示例 2 —按来源国统计的内容数量
DataFrame 还包括一个列(“country
”),该列(据我所知)包括内容的来源。
快速看了一下数据(nf_df[‘country’].nunique()
)发现有 555 个(!)唯一实体在country
列中。这是怎么回事?
事实证明,许多列表包含多个国家名称(例如’United States, India, South Korea, China
') —因此,让我们保留前 20 个名称,并将所有剩余的名称更改为“其他”。
用.apply
很容易做到。为了清楚起见,我将使用两行代码,但也可能只用一行。准备好了吗?
top_countries = nf_df.groupby('country')['title'].count().sort_values().index
nf_df['country'] = nf_df.country.apply(lambda x: 'Others' if (x not in top_countries[-20:]) else x)
就是这样!再次运行nf_df[‘country’].nunique()
,我们看到现在只有 21 个“国家”。
这里的 lambda 函数是一个简单的 if… else 语句,根据具有最高计数的列表检查’country
’实体。
假设每个列还包括内容类型列,我们可以通过按内容类型给每个栏着色来可视化内容数据的细分。
fig = px.histogram(nf_df, x='country', color='type', category_orders={'country': top_countries},
color_discrete_sequence=px.colors.qualitative.Safe, template='plotly_white')
fig.show()
按来源国家和类型划分的网飞标题直方图
那不是很容易吗?想象一下用一些疯狂的循环函数来做这件事——通过.loc
或.iloc
索引器找到正确的索引器行/列号。不了,谢谢你。
整洁,对不对?
仅仅通过这两个简短的函数,您就可以完成以前可能需要一行又一行代码才能完成的事情。尝试一下——我敢打赌你会感到惊喜,并提高你的工作效率。
如果你喜欢这个,比如说👋/关注 twitter ,或点击此处获取更新。ICYMI:我还写了这篇关于用 Plotly Dash 构建 web 数据仪表板的文章。
[## 使用 Python 在几分钟内构建一个 web 数据仪表板
通过将您的数据可视化转换为基于 web 的仪表板,以指数方式提高功能和可访问性…
towardsdatascience.com](/build-a-web-data-dashboard-in-just-minutes-with-python-d722076aee2b)
这篇文章也是关于将数据可视化来讲故事的:
使用 Python 和 Plotly 构建清晰易读的时序数据可视化,以支持您的叙述。
towardsdatascience.com](/effectively-visualize-data-across-time-to-tell-better-stories-2a2c276e031e)