TowardsDataScience 博客中文翻译 2019(五十五)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

使用 R (ggplot2)以商业分析师的心态分析泰坦尼克号

原文:https://towardsdatascience.com/analyzing-the-titanic-with-a-business-analyst-mindset-using-r-ggplot2-ee5355a4dab3?source=collection_archive---------12-----------------------

最近,我迷上了 R 编程软件Hadley Wickham 创造的奇妙的数据可视化包( ggplot2 )。我的职业是商业分析师,在电子支付行业有着丰富的经验,但我对数据分析、可视化和向利益相关者传达数据充满热情。

撰写这篇文章的动机

嗯,为什么是泰坦尼克号……有人可能会问?巧合的是,我决定再看一遍《泰坦尼克号》电影,但这一次是以商业分析师的心态,受到数据分析力量的启发。我第一次看这部电影时,脑海中有几个关于泰坦尼克号上发生的事情的问题,但当时没有找到答案。这一次,我受到数据分析的解决方案驱动本质的启发,决定通过在谷歌上获取无处不在的大型数据集来寻找我自己问题的答案。

我从几个关于泰坦尼克号沉船事件的探索性问题开始了我的分析(我问了很多问题,我猜你们都已经知道了:)。下面的可视化仪表板在我的分析过程中实现了。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Titanic Dashboard

探究问题

  1. 泰坦尼克号上的存活率是多少?
  2. 我如何用数据来形象化泰坦尼克号上的救援人员采用的妇女和儿童优先的方法?
  3. 泰坦尼克号上的年龄分布是怎样的(幸存者和遇难者)?
  4. 泰坦尼克号上按船票等级划分的幸存者年龄分布是怎样的?
  5. 一个多世纪以前,泰坦尼克号是最贵的船,那么所有船票等级的票价是如何比较的呢?

如果你看过这部电影,那么你就来对地方了,如果你没有,那么你就是我发现的目标。也许,你会决定马上看。现在,让我们开始吧。

加载包和浏览数据

让我们从加载包开始,我们将使用这些包来创建用于分析的可视化。Tidyverse 软件包将有助于数据处理和绘图。

加载相关库,将保存在电脑驱动器上的泰坦尼克号数据集导入 R 工作室

注意:源数据帧不包含机组人员的信息,但包含几乎 80%乘客的实际和估计年龄

library(tidyverse)titanic <- read.csv(file.choose())

检查数据集的结构(变量名和变量类型)。这一步对于确定变量是否适合绘图至关重要。

#Check out the structure of the dataset
summary(titanic)
str(titanic)
names(titanic)
head(titanic.df, n = 10)#Remove rows with NA
titanic.df <- filter(titanic, survived != "")

首先,清理数据集以移除或替换丢失的值。

数据集中的列如下所示:

  • Pclass: 票类(1 = 1 号,2 = 2 号;3=第三)
  • **幸存:**幸存 ( 0 =否;1 =是)
  • 姓名: 乘客姓名
  • **性别:**性别(男或女)
  • 年龄: 乘客 年龄
  • SibSp: 船上兄弟姐妹和/或配偶人数
  • Parch: 船上父母和/或子女的数量
  • 票号: 票号
  • 票价: 票价价格(英镑)
  • **座舱:**座舱座舱
  • 已装船 : 装船港(C =瑟堡:Q =皇后镇:S=南安普顿)
  • : 救生艇
  • 车身 : 车身识别号
  • home.dest : 乘客家或目的地的地址

下一步是我们需要决定我们需要什么样的变量和合适的比例来可视化我们的数据。我使用了下面的表格分类,

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

使用 ggplot2 进行可视化

来回答我们的第一个问题,泰坦尼克号上的存活率是多少?

按班级排列(*第一、第二和第三),幸存的女性比例分别为 97%、89%和 49%。

按等级(*第一、第二和第三)排列,男性存活率分别为 34%、15%(约 14.6%)和 15%(约 15.2%)。

运行 下面的代码生成相应的可视化效果:

ggplot(data = titanic.df) +
  aes(x = age, fill = survived) +
  geom_histogram(bin = 30, colour = "#1380A1") +
  #scale_fill_brewer(palette = "Accent") +
  labs(title = "Survival rate on the Titanic",
       y = "Survived",
       subtitle = "Distribution By Age, Gender and class of ticket",
      caption = "Author: etoma.egot") +
  theme_tomski() + # using a custom theme for my visualizations
#theme_bw()+ #Use the inbuilt ggplot2 them for your practice facet_grid(sex~pclass, scales = "free")#Proportion of 1st, 2nd and  3rd class women and men who survivedmf.survived <- titanic.df %>%
  filter(survived == 1)%>%
  group_by(pclass,sex)%>%
  summarise(Counts = n()
  )mf.died <- titanic.df %>%
  filter(survived != 1)%>%
  group_by(pclass,sex)%>%
  summarise(Counts = n()
  )mf.perc.survived <- mf.survived/(mf.survived + mf.died) * 100
select (mf.perc.survived, Counts)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Survival Rate on the Titanic

结果解读:

  • 该图有助于确定考虑到所有三个变量(年龄、性别、机票等级)的存活率模式。
  • 按班级排列(*第一、第二和第三),幸存的女性比例分别为 97%、89%和 49%。
  • 按等级(*第一、第二和第三)排列,男性存活率分别为 34%、15%(约 14.6%)和 15%(约 15.2%)。
  • 在一年级和二年级的学生中,除了一年级的一名女生外,所有的孩子都活了下来。三年级的孩子死亡率更高。

对于我们的第二个问题,我如何用数据来证实泰坦尼克号上的救援人员采用的妇女和儿童优先的方法?

救援人员首先考虑的是儿童和妇女,在所有级别中,优先考虑的是妇女、儿童和至少 60 岁的老年人。

运行代码以获得以下可视化效果:

titanic.df %>%
  filter(fare <= 300)%>%
  ggplot(mapping = aes(x = age, y = fare)) +
  geom_point(aes(colour = survived, size = fare, alpha = 0.7)) +
  geom_smooth(se = FALSE)+
  facet_grid(sex~pclass, scales = "free") +
  labs(title = "Priority and pattern of rescue on the Titanic",
       x = "Age (yrs)",
       y = "Fare(£)",
       subtitle = "Children and women in order of ticket class were\nconsidered first in the rescue plan with priority been\nwomen, children and older adults >= 60yrs", 

       caption = "Author: etoma.egot") +
  theme(
    plot.subtitle = element_text(colour = "#17c5c9",
                                     size=14))+
           theme_tomski()  #using a custom theme

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Priority and pattern of rescue on the Titanic

结果解读

  • 遵循上图中的分布结果。(票价与机票等级成正比)。抛开儿童这个事实(<=12) on the titanic were charged separate boarding fares. It seemed like the fares for children and teens seem unusually high when compared with average fares for non-children age groups. Let me know if you know why this is so.
  • Nonetheless,the bubble chart gives some other clues in regards to the pattern of rescue operations. Evidently, Women and Children first approach in order of ticket class was adopted in the rescue plans by rescuers with priority been women and children and older adults at least 60yrs across all classes.
  • Apparently little or no priority was given to male passengers by rescuers

##注意:我从气泡图中移除了异常票价(500)。支付这些费用的男性和女性无论如何都获救了。

我使用箱线图来可视化接下来的三个问题:

继续第三个问题,泰坦尼克号上的年龄分布是怎样的(幸存者和遇难者)?

总的来说,泰坦尼克号上的男性比女性平均大 3 岁。

titanic.df %>%
    ggplot(mapping =  aes(x = pclass, y = age)) +
  geom_point(colour = "#1380A1", size = 1) +
  geom_jitter(aes(colour = survived))+ #This generates multiple colours
  geom_boxplot(alpha = 0.7, outlier.colour = NA)+
  labs(title = "Age Distribution by Class on the Titanic",
       x = "Ticket Class",
       y = "Age(Yrs)",
       subtitle = "The males on the titanic were older than the females by an average of 3yrs across all ticket classes ",
       caption = "Author: etoma.egot") +
  theme_tomski() +   #using my own custom theme
  theme(plot.subtitle = element_text(
                                     size=18))+

  facet_wrap(.~sex)#Calculating Mean and median age by Class and Gender for adults
titanic.df %>%
    group_by(pclass, sex)%>%
  summarise(
    n = n(), #count of passengers
    Average.age = mean(age, na.rm = TRUE),
    Median.age  = median(age, na.rm = TRUE)
  )

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Age Distribution by Class on the Titanic

成绩解读

负偏态 —箱线图将显示更接近上四分位数的中位数
正偏态 —箱线图将显示更接近下四分位数的中位数

  • 大约 75%的女性(第一、第二、第三名)至少在 22 岁、20 岁和 17 岁之间。年龄中位数为 36 岁(正态分布)、28 岁(负偏态)和 22 岁(正偏态)

  • 大约 75%的男性年龄至少在 30 岁、24 岁和 20 岁之间。年龄中位数为 42 岁(负偏差)、30 岁(正偏差)和 25 岁(正偏差)

#概要:
一般来说,在所有船票等级中,泰坦尼克号上的男性比女性平均年长 3 岁。

随后,对于第 4 个问题,泰坦尼克号上按船票等级划分的幸存者年龄分布是怎样的?

第一类中男性和女性幸存者的平均年龄相同(36 岁)
-第二类中女性比男性大 1.5 倍
-第三类中男性比女性大 2 岁

titanic.df %>%
  filter(survived ==1)%>%
  ggplot(mapping =  aes(x = pclass, y = age)) +
  geom_point(size = 1) +
  geom_jitter(colour = "#1380A1")+ 
  geom_boxplot(alpha = 0.7, outlier.colour = NA)+
  labs(title = "Survivors Age Distribution by Class on the Titanic",
       x = "Ticket Class",
       y = "Age(Yrs)",
       subtitle = "The median age of male and female survivors in 1st class was the same(36 yrs)\nThe females in 2nd class were 1.5 times older than the males\nThe males in 3rd class were older than the females by 2yrs",
       caption = "Author: etoma.egot") +
  theme_tomski() +   #using my own custom theme
  theme(plot.subtitle = element_text(colour = "#1380A1",
                                     size=18))+
  facet_wrap(.~sex)#Calculating Mean and median age by Class and Gender for adults
titanic.df %>%
  filter(survived ==1)%>%
  group_by(pclass, sex)%>%
  summarise(
    n = n(), #count of passengers
    Average.age = mean(age, na.rm = TRUE),
    Median.age  = median(age, na.rm = TRUE)
  )

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Survivor age distribution by class on the Titanic

结果解释

女性
——年龄中位数为 36 岁(正态分布)、28 岁(负偏态)和 22 岁(正偏态)

男性
——年龄中位数为 36 岁(正偏)、19 岁(负偏)和 25 岁(负偏)

#总结:
-第一类男性和女性幸存者的平均年龄相同(36 岁)
-第二类女性比男性大 1.5 倍
-第三类男性比女性大 2 岁

最后,关于最后一个问题,泰坦尼克号是一个多世纪前最贵的船,那么所有船票等级的票价值如何比较?

头等票的价格大约是二等票的三倍,二等票的价值大约是三等票的两倍。

#Prepare Data, remove outliers in fare
titanic.df %>%
  filter(fare < 300)%>%
      ggplot(mapping =  aes(x = pclass, y = fare)) +
  #geom_point(colour = "#1380A1", size = 1) +
  #geom_jitter(aes(colour = survived))+
  geom_boxplot(colour = "#1380A1", outlier.colour = NA)+
  labs(title = "Fare Value by Class",
       x = "Ticket Class",
       y = "Ticket Fare (£)",
       subtitle = "1st class ticket was worth 3 times a 2nd class ticket\nand 2nd class ticket was worth almost twice that of 3rd class",
       caption = "Author: etoma.egot") +
  theme_tomski()+ #using my own custom theme 
  theme(plot.subtitle = element_text(colour = "#1380A1",size=18))+

  coord_cartesian(ylim = c(0,125))+
  coord_flip()#Calculating Mean and Median Fare by Class
titanic.df %>%
  filter(fare < 300)%>%
    group_by(pclass)%>%
  summarise(
    Average.fares = mean(fare, na.rm = TRUE),
    Median.fare  = median(fare, na.rm = TRUE)
  )#Calculating Mean and Median Fare by Class for children
titanic.df %>%
  filter(fare < 300, age <= 12)%>%
  group_by(pclass)%>%
  summarise(
    n = n(),
    Average.fares = mean(fare, na.rm = TRUE),
    Median.fare  = median(fare, na.rm = TRUE)
  )#Calculating Mean and Median Fare by Class for adults
titanic.df %>%
  filter(fare < 300, age >= 12)%>%
  group_by(pclass)%>%
  summarise(
    n = n(),
    Average.fare = mean(fare, na.rm = TRUE),
    Median.fare  = median(fare, na.rm = TRUE)
  )

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Fare Value By Class on the Titanic

结果解释

  • 方框图证实了机票价格与机票等级成正比。非常直观。
  • 分布向右倾斜。一等舱、二等舱和三等舱的票价中位数分别为 59.4 英镑、15 英镑和 8.05 英镑。一等舱、二等舱和三等舱的平均票价分别为 82.2 英镑、21.2 英镑和 13.3 英镑。(平均票价大于中间票价)。
  • 因此,这个分布的中心的更好的测量是中位数。因此,头等票的价格大约是二等票的三倍,而二等票的价值大约是三等票的两倍。
  • 与同一班级的成人相比,儿童的平均票价和中位票价更高。

注:
对于对称分布,均值在中间。因此,平均值是用于比较的适当度量。但是如果分布是偏斜的,那么平均值通常不在中间。因此,中位数是进行比较的适当标准
我对我在 TDS 上的第一篇文章感到非常兴奋,尽管如此,如果你做过类似的分析,我仍然需要澄清,在不同的年龄组中,儿童是否真的比一些成年人付出更多,正如我的可视化气泡图结果似乎所表明的那样。

感谢阅读!。

分析印度新当选总理的推特资料

原文:https://towardsdatascience.com/analyzing-the-twitter-profile-of-indias-newly-elected-pm-b61ae0edf6a5?source=collection_archive---------15-----------------------

一个简单的 Python 项目

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Source: Image by Author

免责声明:本博客与政治无关,只是出于学术兴趣而写。

很长一段时间以来,我想写一篇关于使用 Python 分析真实用户数据的博客,以重温我的概念并探索新的主题。

巧合的是,上周,6 亿印度人连续第二次投票选举纳伦德·莫迪为总理,莫迪是印度推特上关注最多的政治家,并有效地利用推特与选民沟通。因此,他的 Twitter 个人资料可能是一个成熟的分析数据的丰富来源。此外,分析一个政治家的声明是有趣的!

这就是为什么我决定为这个项目分析他的资料。这个博客对那些正在寻找基于真实数据的简单数据分析项目的人会有帮助。

在深入细节之前,这里是项目的关键部分:

  • 在 Twitter 上创建一个开发者账户
  • 使用 Tweepy 删除推文
  • 创建一个熊猫数据框架
  • 推文的统计分析
  • 情感分析
  • 词频分析
  • 主题建模

在 Twitter 上创建一个开发者账户

我只需要在 Twitter 开发者网站上注册并回答几个问题。Twitter 的批准大约在 2-3 小时后发出。

我们需要您的开发者帐户的以下信息:消费者密钥、消费者秘密、访问密钥和访问秘密。

使用 Tweepy 删除推文

Tweepy 是一个易于使用的 Python 库,用于访问 Twitter API。

首先,让我们导入我们将使用的所有库。

import tweepy 
import pandas as pd
import numpy as np from IPython.display 
import display 
import matplotlib.pyplot as plt
import seaborn as sns 
from textblob import TextBlob
import re
import warnings
warnings.filterwarnings('ignore') 
%matplotlib inline

接下来,让我们保存所有的 Twitter 凭证。很明显我藏了我的。创建一个单独的文件来存储凭证是个好主意,但是我在同一个文件中使用了。

#It's not a good pratice to include the keys in the same code, as we have to display. However, I am lazyconsumer_key = "XXXXXXXXXXXXXXXXX"
consumer_secret = "XXXXXXXXXXXXXXXX"
access_key = "XXXXXXXXXXXXXXXXXX"
access_secret = "XXXXXXXXXXXXXXXXXX"

接下来,我们迭代提取推文,一次删除 200 条推文。在做这个分析时,我从鲁道夫·费罗对特朗普推文的博客情绪分析中获得了灵感。

创建一个熊猫数据框架

让我们创建一个熊猫数据框架,这将有助于分析 Twitter 数据。我们还需要了解我们下载的数据的结构。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Source: Image by Author

接下来,我们将把这些相关参数添加到数据帧中。

推文的统计分析

这一段比较直截了当。我们希望得到简单的统计数据,比如推文的平均长度,最受欢迎的推文,以及多年来喜欢和转发的趋势。

接下来,让我们看看过去两年中赞和转发的趋势。我还没有探究 Twitter 对 API 的一般访问的限制,但我相信它限制在 3200 条 tweets。这就是为什么我们只有最近两年的数据。

为了绘制趋势,我们将创建熊猫系列,然后进行绘制。即使在这短暂的时间内,我们也可以观察到喜欢和转发的上升趋势。

让我们创建一些有趣的图表。

首先,我们将创建一个关联图来了解被喜欢和转发的推文的特征。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Source: Image by Author

一些不足为奇的发现是——RTs 和 Likes 高度相关。一些更有见地的学习包括:

  • 中等长度的推文会给莫迪带来更多的转发和点赞
  • 这是有争议的。带有负面情绪的莫迪的推文通常会获得更多的 RTs 和赞。然而,它可能与表达对不幸事件的遗憾有关。

其次,让我们在散点图上绘制情感、喜欢和 RTs,以重新检查我们的假设。

这再次表明,带有负面情绪的推文获得了更多的即时战略和喜欢。然而,我们没有进行广泛的清理,印度英语(使用印地语)可能会影响这些结果。

情感分析

对于情感分析,我们将使用 TextBlob。这是一个 Python 库,提供简单的 API 访问来执行基本的自然语言处理任务。

TextBlob 的工作方式就像 Python 字符串一样,因此可以类似地用于转换数据。

exampleText=TextBlog("Ajitesh")
exampleText[1:3]

输出→ TextBlob("ji ")

exampleText.upper()

Output- TextBlob("AJITESH ")

我们将分三步进行情感分析——清理 Tweet 的文本、标记化和情感分析。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Source: Image by Author

在分析这些推文时,我们只想局限于莫迪发布的推文。尽管我们无法识别莫迪先生转发的推文。我们有一条捷径。我们可以忽略零赞的推文,因为 Twitter 不会给转发推文的用户指定“赞”。此外,莫迪的任何推文都不太可能没有“赞”。

让我们从数据清理步骤开始。

接下来,我们将做标记化和情感分析。

词频分析

对我来说,莫迪先生最令人难忘的倡议之一是“Swachh Bharat”,一项保持印度清洁的倡议。让我们看看他在这些推文中提到了多少次“Swachh Bharat”。

我们先创建一个词云来可视化不同词的相对使用频率。我已经创建了一个简单的单词云,但是你可以想象一下,创建一个图像颜色的单词云

有趣的是,西孟加拉邦和奥迪萨被提及的频率更高,莫迪的政党在这两个地方取得了惊人的进展。

我还用旧的 python 方式创建了一个频率表:

  • 创建映射单词和频率的词典
  • 然后,将单词及其频率作为元组存储在列表中
  • 最后,对列表进行排序并打印结果

主题建模

假设你有圣雄甘地所有的文本形式的演讲。你可以使用主题模型来描绘这些演讲中的关键主题。

我在 PyTexas 看到了 Christine Doig 关于主题建模的精彩演讲,并尝试在我们的案例中实现。

本质上,在主题建模中,我们使用统计模型来发现大量无组织文本中出现的抽象主题。这是一种无监督的学习方法。下图解释了我们通过主题建模想要达到的目标。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Source: Christine Doig Slides (Image by Author)

有两种方法进行主题建模——LSA(潜在语义分析)和概率推理方法,如 LDA(潜在狄利克雷分配)。下面是 LSA 和 LDA 之间差异的图示。在我们的例子中,我们将使用 LDA。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Source — Topic Modelling by Jordan Boyd-Graber (Image by Author)

让我们实现 LDA 来分析推文中的主题。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

source — Image by Author

输出是一个交互式图形,我不知道如何嵌入。然而,您可以在这里找到带有输出的完整代码

我可以看到两个清晰的主题——政治和感恩——分别用 4 和 1 来表示。然而,主题建模在这里没有多大用处。我可能会把这些应用到一系列的演讲中。

我这边就这样。我知道我们可以在这里做更多的分析。请评论让我知道我还可以探索什么。

分析特朗普的推特强迫症

原文:https://towardsdatascience.com/analyzing-trumps-twitter-compulsion-3c6a61ba8354?source=collection_archive---------16-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Image via Unsplash

从来没有一位美国总统如此频繁地使用 Twitter,令人不安。从一位许多人认为精神崩溃的总统的短信中,我们能收集到什么隐藏的见解?

我从特朗普推特档案复制了特朗普的推文数据,选择分析他总统任期顶部 2017 年 1 月 20 日开始的推文。将文本数据保存为 csv 文件后,我使用 Pandas 库将该文件导入到 Jupyter 笔记本中。

作为熨斗学校的数据科学学生,我一直在研究统计分布和概率。泊松分布是有趣的,因为它允许我们通过检查在特定时间范围内发生的事件的平均数来计算给定事件发生的概率。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

image from Slideplayer.com

利用 Twitter 上的信息,我想确定特朗普在接下来的一个小时内至少撰写 2 次推文的概率。这看起来很简单,但为了进行这种计算,我需要确定他在某个时间段内发推文的频率。

我从数据中寻找答案,相信他每天使用 Twitter 肯定有一种模式。当然,总统繁忙的日程安排会限制他在白天或晚上的特定时间使用智能手机。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

唉,似乎一天中没有一个小时是不发推特的,尽管特朗普很少在早上 5 点至 10 点之间发推特。他的公开日程安排显示,特朗普在一个典型的日子里从早上 8 点左右到上午 11 点都在椭圆形办公室,因此我们可以看到,他很可能已经发了 800 多次推特,同时可能做出影响世界各地数百万人生活的重要行政决策。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我不知道这些推文实际上是来自特朗普本人,还是由他的工作人员发送的。他的一些推文肯定是在他出国旅行或穿越美国时发出的,但存档的推特数据只给了我们东部标准时间戳。

Factbase】已经创建了一个详细的日历,它从多个公共来源汇总信息,并提供位置和会议数据。他们已经确定,特朗普在任的 879 天中有 705 天是在白宫度过的,这意味着这些推文的 80%是准确的。

也许他一周中的推文频率会给我们更好的洞察力。互联网和应用程序的使用显示了可预测的流量和行为模式。根据 Sprout Social 的说法,在 Twitter 上发帖的最佳时间是周二和周三。周一至周五上午 8 点到下午 4 点也有稳定的流量,周六 twitter 的参与度会下降。

下面是特朗普一周每天的推文频率图。一般来说,周三和周五是他最忙的日子。这可能与新闻周期或 Twitter 流量高峰期有关吗?或者说,发推特主要是一种冲动行为,如果是这样的话,它打断了什么更重要的工作?

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

看看每天的平均推文,特朗普的推文频率逐年增加。虽然这不是一个完整的年同比比较,因为我们距离 2019 年还不到一半——但他每天的平均推文率在周末几乎翻了一番。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

那么,特朗普在接下来的一个小时内发两条推特的可能性有多大?鉴于目前是 2019 年的周二,他平均每天发 12 条左右的推文,并且他报告说每天只睡 5 个小时左右,这种概率相当低——只有 11%。

如果时间不是特朗普发推特需求的最佳指标,还能是什么?

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我从 Axios 下载了一份特朗普泄露的私人日程,并将其转换为 csv 文件,然后我将该文件与他的推文数据合并。我们现在可以看到特朗普在发推文时应该在做什么以及他在哪里-2018 年 11 月 7 日至 2019 年 2 月 1 日。看起来大多数(166 条推文)是在他被安排在椭圆形办公室的时候发出的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

有 50 条推文丢失了位置数据,但它们大多是在假期期间发出的。我们知道特朗普在 Mar a Lago 过感恩节,由于政府关门,他在华盛顿特区过圣诞节。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

那么,特朗普在椭圆形办公室发推文时的日程安排是什么?毫不奇怪,这主要被归类为执行时间,,但他也在几次会议和午餐期间发推特。缩小范围,我们可以查看特朗普日程表上的所有活动类别,无论位置如何,以找到每个活动期间的推文频率。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们没有得到任何关于执行时间的额外信息,但是我们可以得到关于他的会议和午餐的额外细节。下面是归类为会议的活动的频率图。看起来,在政策讨论、情报简报和与他的幕僚长开会时,他最容易被 Twitter 分心,基本上是在进行他工作中一些最重要的方面。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

特朗普的午餐推特大多是在私人午餐期间发出的,当它是工作午餐时,频率会下降。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作为一名布鲁克林居民,我有点惊讶地看到他正在与纽约州长安德鲁·科莫一起吃饭和发推特。11 月 28 日午餐期间,他发了 5 条微博,4 条被转发,1 条是这样的

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

总之,分析特朗普的推文出人意料地容易。预测他是否会在某个时间段发微博是一个愚蠢的练习,但它不可避免地揭示了他日常活动的有趣信息。虽然已经对他的推文的内容和影响进行了几次调查,但我们也可以分析他的习惯造成的破坏和风险。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

使用 NLP 分析与 Pokemon 相关的#BringBackNationalDex 标签的推文

原文:https://towardsdatascience.com/analyzing-tweets-from-the-polemical-pokemon-related-bringbacknationaldex-tag-with-spacy-and-gcloud-661ec0a08a4c?source=collection_archive---------26-----------------------

使用 spaCy 和 Google Cloud 发现顶级词类术语、情感和提到的口袋妖怪

突发新闻:口袋妖怪社区一片哗然。上周,游戏狂,主要口袋妖怪游戏的开发商,宣布即将推出的游戏,口袋妖怪剑与盾,将不会拥有口袋妖怪的完整库。这个图书馆被称为国家口袋妖怪——因此这个运动被命名为# BringBackNationalPokedex——目前由 809 个口袋妖怪组成。除了仅仅是一个神奇生物的列表,完整的 Pokedex 代表了这个系列的进化和成长,这个系列自诞生以来已经征服了数百万人的心。就我个人而言,我觉得这有点令人难过,因为我认为这个声明违背了口袋妖怪的本质和定义:必须抓住他们

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Border Control. By Wooden Plank Studios (https://www.woodenplankstudios.com/comic/galar-border-patrol/)

作为该系列的长期粉丝,作为一个好奇的数据人,我想快速看看社区在#BringBackNationalPokedex 标签下发布了什么。使用 Tweepy ,一个用于访问 Twitter API 的 Python 库,我快速编写了一个脚本,并让它运行几个小时来收集数据。然后,使用 Python 的自然语言处理(NLP)库 spaCy ,和 Google 的云自然语言 API ,我对上述数据进行了分析。

在这篇文章中,我将展示我的发现。

我这个实验的目标是学习推特圈分享的热门名词、动词形容词副词以及标签。此外,我还想看看哪些命名的实体,也就是说,一个*“被赋予名称的真实世界的对象——例如,一个人、一个国家、一个产品或一本书的标题”,如 spaCy 所定义的*。因为没有情绪分析,任何推文分析都是不完整的,所以我通过这个情绪模型运行推文,以了解人们对这个决定有多高兴或愤怒。最后,出于好奇,我很想知道哪些是被提及最多的口袋妖怪。

数据和准备步骤

本实验中使用的数据集由 2019 年 6 月 13 日和 6 月 14 日收集的 2724 条推文组成,其中包括标签#BringBackNationalDex。为了清理它,我删除了提到的转发,例如,“RT @account_name ”,将“神奇宝贝”的实例改为“口袋妖怪”,删除了所有特殊字符(问号、逗号等),以及包含图像的推文中的 https 地址。我没有做的事情是将推文小写,因为这样做,我可能会丢失一些实体和专有名词,否则 spaCy 不会检测到它们。

顶级名词、动词、形容词、副词和实体

spaCy 最强大的功能之一是词性 (POS)标记,它为每个文档的术语分配一个预测标签,如名词和动词。利用这一点,我可以发现所获得的推文的主要思想或背景。

在小学,我们学到了一个句子中最基本的部分是名词。这些必要的词存在的唯一用途是命名事物;就是这样,地点,人,想法,感觉。因为名词是如此重要,所以我想用它们来打开这篇文章。因此,对于第一个情节,我将展示来自 tweet 语料库的前 30 个名词。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在排名第一的位置上,我们有术语*“游戏”,这一点也不奇怪,因为整个问题是关于即将到来的口袋妖怪游戏。接下来是术语“动画”,指的是声称为什么不是所有的口袋妖怪都将出现的主要原因是开发者没有足够的劳动力来制作所有口袋妖怪的动画。然后在第三个位置,是单词“口袋妖怪”*。

The only Pokemon that appear on this list is Wingull, and that is because there was a tweet featuring a Wingull animation that went viral and was retweeted several times. Other important nouns from the list are “time”, most probably because of those who think the game needs more time before being released, the Japanese word “互換切り” or “Compatibility Switch”, which honestly I don’t understand the context (can someone corroborate this translation?), and lastly the proper noun “Galar”, which is the name of the new Pokemon region.

我要介绍的第二个词性是动词。有了名词,我们学习了用户谈论的主要内容,现在有了动词,我们将发现补充这些名词的动作。下图显示了前 30 个动词。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

第一个术语是互联网在这些情况下想要什么的明显例子:想要*“知道】,要求信息或要求解释。下面的术语,“发现”,指的是人们希望他们最喜欢的口袋妖怪找到进入游戏的方法。然后我们有“感觉”,主要来自用户陈述他们的观点,“舒适”,这是上面提到的 Wingull tweet 的一部分,以及“需要”,可能因为类似于“知道”的原因*

为了给所呈现的术语添加进一步的上下文和精炼,我计算了形容词和副词;这两个语法概念分别用来描述和修饰名词和动词。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

上图是关于顶级形容词的。图中的第一个词,“旧的”,涉及一条转发,说了一些类似于的话,“即使话题【Pokedex 问题】变旧了,我也会继续谈论它。”然后,在第二个位置的是单词“新的”,,在大多数情况下,这个形容词出现在抨击游戏的一些新功能的推文中,或者出现在另一条关于一些新视频的转发推文中,这些视频讨论了争议。列表中的第三个形容词是*“最喜欢的”,,它出现在用户谈论他们最喜欢的口袋妖怪以及可能遗漏它们的推文中。其他引起我注意的术语还有、【胜任】、、【增田俊一】、*谁是游戏背后的导演。然而,将这个名字标在形容词下面可能是 spaCy 的一个假阳性预测。既然我们知道了名词是如何修饰的,让我们来看看副词。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

最受欢迎的副词是*“不”,,它出现在暗示负面情绪(我们很快会看到更多)或不同意的推文中。比如“…做* 信任游戏怪胎“我会 买游戏”,或者“游戏会 有全国 Pokedex。”然后,我们有“完全”,来自 Wingull 的推文,在它之后,副词“以前”,主要用于推文,比较即将到来的游戏和几年前发布的游戏。其他有趣的副词还有:“后来”、“T47”、“불완전한”(韩语中的“不完全”)、“最终”**

现在,让我们将注意力从语法和部分句子转移到语料库的实体,就是这样,人们在推文中讨论的特定和现有的事情。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

主导实体是“口袋妖怪”。然后,我们就有了*【one】,“用来指代“这一款游戏”,或者,“这一款”【口袋妖怪】一代”“游戏怪胎”,争议的中心开发者。此外,其他经常出现的实体还有美国任天堂的推特账号、“Nintendo America”“剑与盾”“增田俊一”等名字。*

情感分析

通常,在这种互联网变得有点愤怒和紧张的争议事件中,事情往往会有点失控。可悲的是,当这种情况发生时,人们选择以消极甚至仇恨的方式做出反应和评论。为了测试这个假设,我通过情绪分析引擎运行了这些推文,以量化其内容的*“积极”“消极”*。我使用的情感模型是由谷歌云的自然语言 API 提供的,主要是因为我喜欢它如何将语料库分割成句子来计算每个句子的情感,因为它是一个 API,这意味着你不必安装、训练或下载模型。

总的来说,谷歌传递了它检测到的 5501 个句子的情感。每一个情感输出都包含两个值:*“分数”“量级”。*前者是一个介于 -11 之间的值,其中 -1 表示负面情绪, 1 表示正面情绪,而 magnitude(我在此不使用)则指定 “文档中存在多少情绪内容。” 下面的直方图显示了情绪值的分布。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

令人惊讶的是,情绪几乎完全平衡;平均值为 -0.045 ,标准差为 0.27 。直方图中心的峰值表明大多数推文根本没有情感,在人工检查推文和值后,我发现这些零值推文只是由标签组成的,所以根本没有情感。关于分布的两端,我们可以看到高度负面的推文比高度正面的多。一些例子是:“他们毁了传奇!”、 *“口袋妖怪粉丝:抵制任天堂和游戏狂”,“那个游戏太英国化了,他们甚至不让其他地区的 Pokemon 进来。”*从更积极的角度来看,我们有一些充满希望的评论,比如: " 【原文】我仍然会得到它,但是【原文】我非常担心我的团队不会在游戏中,而且【原文】我真的【原文】不喜欢那个#BringBackNationalDex," “看到口袋妖怪社区对游戏的热情真是太棒了,# bringgbndex

提到口袋妖怪

在我结束之前,我想展示一下在推文中出现最多的口袋妖怪。除了 Wingull,由于许多转发,它在 tweets 语料库中出现了 160 次,我发现很奇怪的是,没有多少提到口袋妖怪。还有,你会看到,皮卡丘不是顶级的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

第五代传奇口袋妖怪捷克罗姆名列榜首。紧随其后的是首发口袋妖怪——辛达奎尔布拉齐肯沼泽——然后在第五个位置上我们有皮卡丘

结论

Twitter 不浪费任何时间。当社区决定反对或支持某件事时,他们会聚集在一个标签下,让自己的声音被听到。在这篇文章中,我分享了我在调查一个包含#BringBackNationalDex 标签的推特样本后发现的发现,该标签是在宣布即将推出的口袋妖怪游戏不会以完整的生物名单为特色后创建的。

在我调查的第一部分,我使用了 NLP 库 spaCy,来发现与 tweets 一起使用的热门名词、动词、形容词和副词。在这里,我发现推文背后的整体意义是对答案的需求,失望感,甚至是对他们最喜欢的口袋妖怪可能无法穿越边境到 Galar 的消息的悲伤。此外,为了了解推文的整体感觉,我使用谷歌云的自然语言 API 计算了他们的情绪,并得出结论,虽然有些人很愤怒,但其他人充满了希望。最后,捷克罗姆,而不是皮卡丘,是语料库中被提及最多的口袋妖怪。

感谢阅读:)

本项目使用的代码和数据集可从以下网址获得:

[## juandes/带回 pokedex-nlp

在 GitHub 上创建一个帐户,为 juandes/bring-back-pokedex-nlp 开发做贡献。

github.com](https://github.com/juandes/bring-back-pokedex-nlp)

使用 Spark、Optimus 和 Twint 在几分钟内使用 NLP 分析推文

原文:https://towardsdatascience.com/analyzing-tweets-with-nlp-in-minutes-with-spark-optimus-and-twint-a0c96084995f?source=collection_archive---------4-----------------------

社交媒体一直是研究人们沟通和行为方式的黄金,在本文中,我将向您展示在没有 Twitter API 的情况下分析推文的最简单方法,并可扩展用于大数据。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

介绍

如果你在这里,很可能你对分析推文(或类似的东西)感兴趣,你有很多推文,或者可以得到它们。最烦人的事情之一就是获得一个 Twitter 应用程序,获得认证和所有这些。如果你用的是熊猫,那就没办法衡量了。

那么,一个不需要 Twitter API 认证的系统怎么样,它可以获得无限量(几乎是无限量)的推文和分析它们的能力,以及 NLP 等等。好吧,你一定会喜欢的,因为这正是我现在要给你看的。

获得项目和回购

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

https://matrixds.com/

你可以很容易地理解我将要向你展示的一切。只是铲车这个 MatrixDS 项目:

[## MatrixDS |数据项目工作台

MatrixDS 是一个构建、共享和管理任何规模的数据项目的地方。

community.platform.matrixds.com](https://community.platform.matrixds.com/community/project/5ccc9c4b3175e0603c394444/files) 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

还有一个 GitHub repo,里面什么都有:

[## FavioVazquez/Twitter _ Optimus _ twint

用 Twint,Optimus 和 Apache Spark 分析推文。-FavioVazquez/Twitter _ Optimus _ twint

github.com](https://github.com/FavioVazquez/twitter_optimus_twint)

使用 MatrixDS,您可以免费运行笔记本、获取数据和运行分析,因此如果您想了解更多信息,请这么做。

得到 Twint 和擎天柱

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Twint 利用 Twitter 的搜索运营商让你抓取特定用户的推文,抓取与某些主题、标签和趋势相关的推文,或者从推文中挑选出敏感的信息,如电子邮件和电话号码。

通过我共同创建的库 Optimus,你可以清理数据,准备数据,分析数据,创建剖面图和图表,执行机器学习和深度学习,所有这些都以分布式的方式进行,因为在后端我们有 Spark,TensorFlow,Sparkling Water 和 Keras。

因此,让我们首先安装您需要的所有东西,因为当您在 Matrix 项目中时,请转到分析 Tweets 笔记本并运行(您也可以从 JupyterLab 终端执行此操作):

!pip install --user -r requirements.txt

之后,我们需要安装 Twint,运行:

!pip install --upgrade --user -e git+[https://github.com/twintproject/twint.git@origin/master#egg=twint](https://github.com/twintproject/twint.git@origin/master#egg=twint)

这将下载一个 scr/文件夹,因此我们需要做一些配置:

!mv src/twint .
!rm -r src

然后导入我们需要运行的 Twint:

%load_ext autoreload
%autoreload 2import sys
sys.path.append("twint/")

最后:

import twint

Optimus 是在第一步安装的,所以我们就开始吧(这会为你启动一个 Spark 集群):

from optimus import Optimus
op = Optimus()

设置 Twint 以删除推文

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

https://www.theverge.com/2015/11/3/9661180/twitter-vine-favorite-fav-likes-hearts

# Set up TWINT config
c = twint.Config()

如果您在笔记本电脑上运行,您还需要运行:

# Solve compatibility issues with notebooks and RunTime errors.
import nest_asyncio
nest_asyncio.apply()

搜索数据科学推文

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我将开始我们的分析,废弃关于数据科学的推文,你可以把它改成你想要的任何东西。

为此,我们只需运行以下命令:

c.Search = "data science"
# Custom output format
c.Format = "Username: {username} |  Tweet: {tweet}"
c.Limit = 1
c.Pandas = Truetwint.run.Search(c)

让我给你解释一下这段代码。在我们运行代码的最后一部分:

c = twint.Config()

我们开始了新的 Twint 配置。之后,我们需要通过不同的选项,我们想刮推文。以下是配置选项的完整列表:

Variable             Type       Description
--------------------------------------------
Username             (string) - Twitter user's username
User_id              (string) - Twitter user's user_id
Search               (string) - Search terms
Geo                  (string) - Geo coordinates (lat,lon,km/mi.)
Location             (bool)   - Set to True to attempt to grab a Twitter user's location (slow).
Near                 (string) - Near a certain City (Example: london)
Lang                 (string) - Compatible language codes: https://github.com/twintproject/twint/wiki/Langauge-codes
Output               (string) - Name of the output file.
Elasticsearch        (string) - Elasticsearch instance
Timedelta            (int)    - Time interval for every request (days)
Year                 (string) - Filter Tweets before the specified year.
Since                (string) - Filter Tweets sent since date (Example: 2017-12-27).
Until                (string) - Filter Tweets sent until date (Example: 2017-12-27).
Email                (bool)   - Set to True to show Tweets that _might_ contain emails.
Phone                (bool)   - Set to True to show Tweets that _might_ contain phone numbers.
Verified             (bool)   - Set to True to only show Tweets by _verified_ users
Store_csv            (bool)   - Set to True to write as a csv file.
Store_json           (bool)   - Set to True to write as a json file.
Custom               (dict)   - Custom csv/json formatting (see below).
Show_hashtags        (bool)   - Set to True to show hashtags in the terminal output.
Limit                (int)    - Number of Tweets to pull (Increments of 20).
Count                (bool)   - Count the total number of Tweets fetched.
Stats                (bool)   - Set to True to show Tweet stats in the terminal output.
Database             (string) - Store Tweets in a sqlite3 database. Set this to the DB. (Example: twitter.db)
To                   (string) - Display Tweets tweeted _to_ the specified user.
All                  (string) - Display all Tweets associated with the mentioned user.
Debug                (bool)   - Store information in debug logs.
Format               (string) - Custom terminal output formatting.
Essid                (string) - Elasticsearch session ID.
User_full            (bool)   - Set to True to display full user information. By default, only usernames are shown.
Profile_full         (bool)   - Set to True to use a slow, but effective method to enumerate a user's Timeline.
Store_object         (bool)   - Store tweets/user infos/usernames in JSON objects.
Store_pandas         (bool)   - Save Tweets in a DataFrame (Pandas) file.
Pandas_type          (string) - Specify HDF5 or Pickle (HDF5 as default).
Pandas               (bool)   - Enable Pandas integration.
Index_tweets         (string) - Custom Elasticsearch Index name for Tweets (default: twinttweets).
Index_follow         (string) - Custom Elasticsearch Index name for Follows (default: twintgraph).
Index_users          (string) - Custom Elasticsearch Index name for Users (default: twintuser).
Index_type           (string) - Custom Elasticsearch Document type (default: items).
Retries_count        (int)    - Number of retries of requests (default: 10).
Resume               (int)    - Resume from a specific tweet id (**currently broken, January 11, 2019**).
Images               (bool)   - Display only Tweets with images.
Videos               (bool)   - Display only Tweets with videos.
Media                (bool)   - Display Tweets with only images or videos.
Replies              (bool)   - Display replies to a subject.
Pandas_clean         (bool)   - Automatically clean Pandas dataframe at every scrape.
Lowercase            (bool)   - Automatically convert uppercases in lowercases.
Pandas_au            (bool)   - Automatically update the Pandas dataframe at every scrape.
Proxy_host           (string) - Proxy hostname or IP.
Proxy_port           (int)    - Proxy port.
Proxy_type           (string) - Proxy type.
Tor_control_port     (int) - Tor control port.
Tor_control_password (string) - Tor control password (not hashed).
Retweets             (bool)   - Display replies to a subject.
Hide_output          (bool)   - Hide output.
Get_replies          (bool)   - All replies to the tweet.

所以在这段代码中:

c.Search = "data science"
# Custom output format
c.Format = "Username: {username} |  Tweet: {tweet}"
c.Limit = 1
c.Pandas = True

我们设置搜索词,然后格式化响应(只是为了检查),只获得 20 条 tweets,限制=1(它们以 20 为增量),最后使结果与 Pandas 兼容。

然后当我们跑的时候:

twint.run.Search(c)

我们正在展开搜索。结果是:

Username: tmj_phl_pharm |  Tweet: If you're looking for work in Spring House, PA, check out this Biotech/Clinical/R&D/Science job via the link in our bio: KellyOCG Exclusive: Data Access Analyst in Spring House, PA- Direct Hire at Kelly Services #KellyJobs #KellyServices
Username: DataSci_Plow |  Tweet: Bring your Jupyter Notebook to life with interactive widgets  https://www.plow.io/post/bring-your-jupyter-notebook-to-life-with-interactive-widgets?utm_source=Twitter&utm_campaign=Data_science … +1 Hal2000Bot #data #science
Username: ottofwagner |  Tweet: Top 7 R Packages for Data Science and AI   https://noeliagorod.com/2019/03/07/top-7-r-packages-for-data-science-and-ai/ … #DataScience #rstats #MachineLearning
Username: semigoose1 |  Tweet: ëäSujy #crypto #bitcoin #java #competition #influencer #datascience #fintech #science #EU  https://vk.com/id15800296  https://semigreeth.wordpress.com/2019/05/03/easujy-crypto-bitcoin-java-competition-influencer-datascience-fintech-science-eu- https-vk-com-id15800296/ …
Username: Datascience__ |  Tweet: Introduction to Data Analytics for Business  http://zpy.io/c736cf9f  #datascience #ad
Username: Datascience__ |  Tweet: How Entrepreneurs in Emerging Markets can master the Blockchain Technology  http://zpy.io/f5fad501  #datascience #ad
Username: viktor_spas |  Tweet: [Перевод] Почему Data Science командам нужны универсалы, а не специалисты  https://habr.com/ru/post/450420/?utm_source=dlvr.it&utm_medium=twitter&utm_campaign=450420 … pic.twitter.com/i98frTwPSE
Username: gp_pulipaka |  Tweet: Orchestra is a #RPA for Orchestrating Project Teams. #BigData #Analytics #DataScience #AI #MachineLearning #Robotics #IoT #IIoT #PyTorch #Python #RStats #TensorFlow #JavaScript #ReactJS #GoLang #CloudComputing #Serverless #DataScientist #Linux @lruettimann  http://bit.ly/2Hn6qYd  pic.twitter.com/kXizChP59U
Username: amruthasuri |  Tweet: "Here's a typical example of a day in the life of a RagingFX trader. Yesterday I received these two signals at 10am EST. Here's what I did... My other activities have kept me so busy that ...  http://bit.ly/2Jm9WT1  #Learning #DataScience #bigdata #Fintech pic.twitter.com/Jbes6ro1lY
Username: PapersTrending |  Tweet: [1/10] Real numbers, data science and chaos: How to fit any dataset with a single parameter - 192 stars - pdf:  https://arxiv.org/pdf/1904.12320v1.pdf … - github: https://github.com/Ranlot/single-parameter-fit …
Username: webAnalyste |  Tweet: Building Data Science Capabilities Means Playing the Long Game  http://dlvr.it/R41k3t  pic.twitter.com/Et5CskR2h4
Username: DataSci_Plow |  Tweet: Building Data Science Capabilities Means Playing the Long Game  https://www.plow.io/post/building-data-science-capabilities-means-playing-the-long-game?utm_source=Twitter&utm_campaign=Data_science … +1 Hal2000Bot #data #science
Username: webAnalyste |  Tweet: Towards Well Being, with Data Science (part 2)  http://dlvr.it/R41k1K  pic.twitter.com/4VbljUcsLh
Username: DataSci_Plow |  Tweet: Understanding when Simple and Multiple Linear Regression give Different Results  https://www.plow.io/post/understanding-when-simple-and-multiple-linear-regression-give-different-results?utm_source=Twitter&utm_campaign=Data_science … +1 Hal2000Bot #data #science
Username: DataSci_Plow |  Tweet: Artificial Curiosity  https://www.plow.io/post/artificial-curiosity?utm_source=Twitter&utm_campaign=Data_science … +1 Hal2000Bot #data #science
Username: gp_pulipaka |  Tweet: Synchronizing the Digital #SCM using AI for Supply Chain Planning. #BigData #Analytics #DataScience #AI #RPA #MachineLearning #IoT #IIoT #Python #RStats #TensorFlow #JavaScript #ReactJS #GoLang #CloudComputing #Serverless #DataScientist #Linux @lruettimann  http://bit.ly/2KX8vrt  pic.twitter.com/tftxwilkQf
Username: DataSci_Plow |  Tweet: Extreme Rare Event Classification using Autoencoders in Keras  https://www.plow.io/post/extreme-rare-event-classification-using-autoencoders-in-keras?utm_source=Twitter&utm_campaign=Data_science … +1 Hal2000Bot #data #science
Username: DataSci_Plow |  Tweet: Five Methods to Debug your Neural Network  https://www.plow.io/post/five-methods-to-debug-your-neural-network?utm_source=Twitter&utm_campaign=Data_science … +1 Hal2000Bot #data #science
Username: iamjony94 |  Tweet: 26 Mobile and Desktop Tools for Marketers  http://bit.ly/2LkL3cN  #socialmedia #digitalmarketing #contentmarketing #growthhacking #startup #SEO #ecommerce #marketing #influencermarketing #blogging #infographic #deeplearning #ai #machinelearning #bigdata #datascience #fintech pic.twitter.com/mxHiY4eNXR
Username: TDWI |  Tweet: #ATL #DataPros: Our #analyst, @prussom is headed your way to speak @ the #FDSRoadTour on Wed, 5/8! Register to attend for free, learn about Modern #DataManagement in the Age of #Cloud & #DataScience: Trends, Challenges & Opportunities.  https://bit.ly/2WlYOJb  #Atlanta #freeevent

看起来不太好,但我们得到了我们想要的。推文!

将结果保存到熊猫中

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

遗憾的是 Twint 和 Spark 之间没有直接联系,但是我们可以用熊猫来做,然后将结果传递给 Optimus。

我创建了一些简单的函数,你可以在实际项目中看到,这些函数帮助你处理熊猫和这个部分的奇怪的 Twint API。所以当我们运行这个时:

available_columns()

你会看到:

Index(['conversation_id', 'created_at', 'date', 'day', 'hashtags', 'hour','id', 'link', 'location', 'name', 'near', 'nlikes', 'nreplies','nretweets', 'place', 'profile_image_url', 'quote_url', 'retweet','search', 'timezone', 'tweet', 'user_id', 'user_id_str', 'username'],dtype='object')

这些是我们刚刚查询得到的列。有很多不同的东西可以用来处理这些数据,但是对于本文,我将只使用其中的一部分。因此,为了将 Twint 的结果转换为 Pandas,我们运行:

df_pd = twint_to_pandas(["date", "username", "tweet", "hashtags", "nlikes"])

你会看到这只熊猫:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

好多了不是吗?

情感分析(简单的方法)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们将使用 Optimus 和 TextBlob 对一些推文进行情感分析。我们需要做的第一件事是清理这些推文,因为擎天柱是最好的选择。

为了将数据保存为 Optimus (Spark) DF,我们需要运行:

df = op.create.data_frame(pdf= df_pd)

我们将使用 Optimus 删除重音符号和特殊字符(对于真实的工作场景,您需要做的远不止这些,如删除链接、图像和停用词),为此:

clean_tweets = df.cols.remove_accents("tweet") \
                 .cols.remove_special_chars("tweet")

然后,我们需要从 Spark 收集这些推文,将它们放在 Python 列表中,为此:

tweets = clean_tweets.select("tweet").rdd.flatMap(lambda x: x).collect()

然后,为了分析这些推文的情绪,我们将使用 TextBlob 情绪函数:

from textblob import TextBlob
from IPython.display import Markdown, display# Pretty printing the result
def printmd(string, color=None):
    colorstr = "<span style='color:{}'>{}</span>".format(color, string)
    display(Markdown(colorstr))for tweet in tweets:
    print(tweet)
    analysis = TextBlob(tweet)
    print(analysis.sentiment)
    if analysis.sentiment[0]>0:
        printmd('Positive', color="green")
    elif analysis.sentiment[0]<0:
        printmd('Negative', color="red")
    else:
        printmd("No result", color="grey")
        print("")

这将给我们:

IAM Platform Curated Retweet  Via  httpstwittercomarmaninspace  ArtificialIntelligence AI What About The User Experience  httpswwwforbescomsitestomtaulli20190427artificialintelligenceaiwhatabouttheuserexperience  AI DataScience MachineLearning BigData DeepLearning Robots IoT ML DL IAMPlatform TopInfluence ArtificialIntelligence
Sentiment(polarity=0.0, subjectivity=0.0)

中立的

Seattle Data Science Career Advice Landing a Job in The Emerald City Tips from Metis Seattle Career Advisor Marybeth Redmond –  httpsbitly2IYjzaj  pictwittercom98hMYZVxsu
Sentiment(polarity=0.0, subjectivity=0.0)

中立的

This webinarworkshop is designed for business leaders data science managers and decision makers who want to build effective AI and data science capabilities for their organization Register here  httpsbitly2GDQeQT  pictwittercomxENQ0Dtv1X
Sentiment(polarity=0.6, subjectivity=0.8)

积极的

Contoh yang menarik dari sport science kali ini dari sisi statistik dan pemetaan lapangan Dengan makin gencarnya scientific method masuk di sport maka pengolahan data seperti ini akan semakin menjadi hal biasa  httpslnkdinfQHqgjh 
Sentiment(polarity=0.0, subjectivity=0.0)

中立的

Complete handson machine learning tutorial with data science Tensorflow artificial intelligence and neural networks  Machine Learning Data Science and Deep Learning with Python   httpsmedia4yousocialcareerdevelopmenthtmlmachinelearning  python machine learning online data science udemy elearning pictwittercomqgGVzRUFAM
Sentiment(polarity=-0.16666666666666666, subjectivity=0.6)

否定的;消极的;负面的;负的

We share criminal data bases have science and medical collaoarations Freedom of movement means we can live and work in EU countries with no hassle at all much easier if youre from a poorer background We have Erasmus loads more good things
Sentiment(polarity=0.18939393939393936, subjectivity=0.39166666666666666)

积极的

Value of Manufacturers Shipments for Durable Goods BigData DataScience housing rstats ggplot pictwittercomXy0UIQtNHy
Sentiment(polarity=0.0, subjectivity=0.0)

中立的

Top DataScience and MachineLearning Methods Used in 2018 2019 AI MoRebaie TMounaged AINow6 JulezNorton  httpswwwkdnuggetscom201904topdatasciencemachinelearningmethods20182019html 
Sentiment(polarity=0.5, subjectivity=0.5)

积极的

Come check out the Santa Monica Data Science  Artificial Intelligence meetup to learn about In PersonComplete Handson Machine Learning Tutorial with Data Science  httpbitly2IRh0GU 
Sentiment(polarity=-0.6, subjectivity=1.0)

否定的;消极的;负面的;负的

Great talks about the future of multimodality clinical translation and data science Very inspiring 1stPETMRIsymposium unitue PETMRI molecularimaging AI pictwittercomO542P9PKXF
Sentiment(polarity=0.4833333333333334, subjectivity=0.625)

积极的

Did engineering now into data science last 5 years and doing MSC in data science this year
Sentiment(polarity=0.0, subjectivity=0.06666666666666667)

中立的

Program Officer – Data Science  httpbitly2PV3ROF 
Sentiment(polarity=0.0, subjectivity=0.0)

中立。

诸如此类。

这非常容易,但它不会扩展,因为最终我们从 Spark 收集数据,所以驱动程序的 RAM 是极限。让我们做得更好一点。

将情感直接添加到 Spark 数据框架中

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

将这些代码转换成 Spark 代码很简单。这段代码也可以帮助您转换其他代码。因此,让我们开始从 Spark 导入用户定义的功能模块:

from pyspark.sql.functions import udf

然后我们将把上面的代码转换成一个函数:

def apply_blob(sentence):
    temp = TextBlob(sentence).sentiment[0]
    if temp == 0.0:
        return 0.0 # Neutral
    elif temp >= 0.0:
        return 1.0 # Positive
    else:
        return 2.0 # Negative

此后,我们将把该函数注册为火花 UDF:

sentiment = udf(apply_blob)

然后,为了将该函数应用于整个数据帧,我们需要编写:

clean_tweets.withColumn("sentiment", sentiment(clean_tweets['tweet'])).show()

我们会看到:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

情感分析,程序员的好方法(使代码模块化)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这实际上不是质量代码。让我们把它转换成函数来反复使用。

第一部分是设置一切:

%load_ext autoreload
%autoreload 2# Import twint
import sys
sys.path.append("twint/")# Set up TWINT config
import twint
c = twint.Config()# Other imports
import seaborn as sns
import os
from optimus import Optimus
op = Optimus()# Solve compatibility issues with notebooks and RunTime errors.
import nest_asyncio
nest_asyncio.apply()# Disable annoying printingclass HiddenPrints:
    def __enter__(self):
        self._original_stdout = sys.stdout
        sys.stdout = open(os.devnull, 'w') def __exit__(self, exc_type, exc_val, exc_tb):
        sys.stdout.close()
        sys.stdout = self._original_stdout

最后一部分是一个类,它将删除 Twint 的自动打印,所以我们只看到数据帧。

以上所有的东西都可以用这些函数来概括:

from textblob import TextBlob
from pyspark.sql.functions import udf
from pyspark.sql.types import DoubleType# Function to get sentiment 
def apply_blob(sentence):
    temp = TextBlob(sentence).sentiment[0]
    if temp == 0.0:
        return 0.0 # Neutral
    elif temp >= 0.0:
        return 1.0 # Positive
    else:
        return 2.0 # Negative# UDF to write sentiment on DF
sentiment = udf(apply_blob, DoubleType())# Transform result to pandas
def twint_to_pandas(columns):
    return twint.output.panda.Tweets_df[columns]def tweets_sentiment(search, limit=1):
    c.Search = search
    # Custom output format
    c.Format = "Username: {username} |  Tweet: {tweet}"
    c.Limit = limit
    c.Pandas = True
    with HiddenPrints():
        print(twint.run.Search(c))

    # Transform tweets to pandas DF
    df_pd = twint_to_pandas(["date", "username", "tweet", "hashtags", "nlikes"])

    # Transform Pandas DF to Optimus/Spark DF
    df = op.create.data_frame(pdf= df_pd)

    # Clean tweets
    clean_tweets = df.cols.remove_accents("tweet") \
                 .cols.remove_special_chars("tweet")

    # Add sentiment to final DF
    return clean_tweets.withColumn("sentiment",    sentiment(clean_tweets['tweet']))

因此,为了获取推文并添加情感,我们使用:

df_result = tweets_sentiment("data science", limit=1)df_result.show()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

就这样:)

让我们看看情绪的分布:

df_res_pandas = df_result.toPandas()
sns.distplot(df_res_pandas['sentiment'])
sns.set(rc={'figure.figsize':(11.7,8.27)})

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

利用 Twint 做更多事情

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

To see how to do this check: https://amueller.github.io/word_cloud/auto_examples/masked.html

我们可以做更多的事情,这里我将向你展示如何创建一个简单的函数来获取 tweets,以及如何从它们构建一个单词云。

所以通过简单的搜索就能得到推文:

def get_tweets(search, limit=100):
    c = twint.Config()
    c.Search = search
    c.Limit = limit
    c.Pandas = True
    c.Pandas_clean = Truewith HiddenPrints():
        print(twint.run.Search(c))
    return twint.output.panda.Tweets_df[["username","tweet"]]

有了这个,我们可以很容易地获得成千上万条推文:

tweets = get_tweets("data science", limit=10000)tweets.count() # 10003

要生成单词云,我们需要做的就是:

from wordcloud import WordCloud, STOPWORDS, ImageColorGenerator
import matplotlib.pyplot as plt
%matplotlib inlinetext = tweets.tweet.values# adding movie script specific stopwords
stopwords = set(STOPWORDS)
stopwords.add("https")
stopwords.add("xa0")
stopwords.add("xa0'")
stopwords.add("bitly")
stopwords.add("bit")
stopwords.add("ly")
stopwords.add("twitter")
stopwords.add("pic")wordcloud = WordCloud(
    background_color = 'black',
    width = 1000,
    height = 500,
    stopwords = stopwords).generate(str(text))

我添加了一些与分析无关的常用词。为了说明这一点,我们使用:

plt.imshow(wordcloud, interpolation=’bilinear’)
plt.axis(“off”)
plt.rcParams[‘figure.figsize’] = [10, 10]

您将获得:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

很漂亮,但没那么漂亮。如果我们想要好的代码,我们需要模块,那么让我们把它转换成一个函数:

def generate_word_cloud(tweets):

    # Getting the text out of the tweets
    text = tweets.tweet.values

    # adding movie script specific stopwords
    stopwords = set(STOPWORDS)
    stopwords.add("https")
    stopwords.add("xa0")
    stopwords.add("xa0'")
    stopwords.add("bitly")
    stopwords.add("bit")
    stopwords.add("ly")
    stopwords.add("twitter")
    stopwords.add("pic")wordcloud = WordCloud(
        background_color = 'black',
        width = 1000,
        height = 500,
        stopwords = stopwords).generate(str(text))

    plt.imshow(wordcloud, interpolation='bilinear')
    plt.axis("off")
    plt.rcParams['figure.figsize'] = [10, 10]

然后我们就跑:

tweets = get_tweets("artificial intelligence", limit=1000)
generate_word_cloud(tweets)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

你自己试试

你可以利用图书馆做更多的事情。其他一些功能:

  • twint.run.Search() -使用搜索过滤器获取推文(正常);
  • twint.run.Followers()——获取一个 Twitter 用户的关注者;
  • twint.run.Following() -获取关注推特用户的人;
  • twint.run.Favorites() -获取 Twitter 用户喜欢的推文;
  • twint.run.Profile() -从用户的个人资料中获取推文(包括转发);
  • twint.run.Lookup() -从用户档案中获取信息(简历、位置等)。).

实际上,您可以从终端使用它。对于刚才运行:

pip3 install --upgrade -e git+https://github.com/twintproject/twint.git@origin/master#egg=twint

然后只需运行转到 twint 文件夹:

cd src/twint

最后你可以运行例如:

twint -u TDataScience --since 2019-01-01 --o TDS.csv --csv

在这里,我得到了本年度 TDS 团队的所有推文(迄今为止有 845 条)。如果你想要的话,下面是 CSV 文件:

[## FavioVazquez/Twitter _ Optimus _ twint

用 Twint,Optimus 和 Apache Spark 分析推文。-FavioVazquez/Twitter _ Optimus _ twint

github.com](https://github.com/FavioVazquez/twitter_optimus_twint/blob/master/TDS.csv)

奖金(缩放结果)

让我们获得 10k 条推文,并获得他们的情绪,因为为什么不。为此:

df_result = tweets_sentiment("data science", limit=100000)df_result.show()

这实际上花了将近 10 分钟,所以要做好预防措施。从 CLI 获取 tweets,然后应用该函数可能会更快。让我们看看有多少条推文:

df_results.count()

我们有 10.031 条带有情绪的推文!你也可以用它们来训练其他模型。

感谢您阅读本文,希望它能对您目前的工作和对数据科学的理解有所帮助。如果你想了解我更多,请在 twitter 上关注我:

[## 法维奥·巴斯克斯(@法维奥·巴斯克斯)|推特

Favio Vázquez 的最新推文(@FavioVaz)。数据科学家。物理学家和计算工程师。我有一个…

推特通讯](https://twitter.com/faviovaz)

通过自然语言处理技术分析 Twitter 领域

原文:https://towardsdatascience.com/analyzing-twitter-spheres-through-nlp-techniques-748b0df10b6c?source=collection_archive---------14-----------------------

使用情感分析、词云和递归神经网络探索 8 个类别 x 10 个账户 x 10000 条推文的数据集

由 Sejal Dua 和 Camille Bowman 创作

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

介绍

Twitter 是一个用于各种交流的平台:淋浴的想法、有趣的遭遇、严肃的新闻等等。我们很好奇不同类型的账户如何使用 Twitter。我们研究了 8 个类别的 10 个大客户:快餐、航空公司、体育联盟、大学、科技公司、流媒体服务、新闻媒体和名人。使用他们的推文,我们通过情感分析、词云、网络和递归神经网络检查了账户使用的词的模式。

数据收集

最初,我们的计划是使用 Twitter API 和 tweepy 库来获得一个数据集,该数据集主要由流行的标签和与这些标签的使用相对应的地理位置数据组成。然而,我们很快发现,使用我们的免费开发者帐户,Twitter REST API 将只允许我们挖掘过去 7 天的推文,即使我们付费,我们每天也只能获得 100 条推文。在做了更多的研究后,我们了解到有一些变通办法。例如,有一个页面滚动条可以超过我们的 API 查询的速度限制。但是,一旦我们开始收集热门推文数据,我们就面临另一个问题。Twitter 是一个平台,用户可以在这个平台上充分接触到无穷无尽的内容和庞大的用户网络,而不必提供任何位置数据。人们可以自愿入住一个地点,但这个地点往往是一些令人难以置信的模糊和古怪的东西(如“地球”)。我们评估了所有这些因素,并确定鉴于我们项目的时间表和整个首要目的,前面的障碍太难克服:收集数据,并使用强大的技术从中获得洞察力。从那时起,我们知道我们必须找到一种替代的数据收集方法,我们还必须重新定义我们的研究问题,使其不涉及在地图上可视化地理位置数据。

我们浏览了互联网和 GitHub,寻找 StackOverflow 上那些绝对的传奇人物,他们总是在你准备放弃和改变的时候拯救你。幸运的是,我们找到了继续这个 Twitter 项目所需要的东西。优化和修改的 GetOldTweets3 库(OMGOT) 可用于大量挖掘旧的和回溯的推文。我们使用这个 Python 库从特定用户那里提取了过去五年中发布的多达 10,000 条推文。如果你正在寻找 Twitter 上的公共账户,这个库比 Twitter API 简单得多(没有速率限制!),并且不需要 API 键。

鉴于我们的新刮刀的能力,我们认为进行我们的项目的最佳途径是进入分类分析的领域。我们选择了下面的 8 个类别,因为我们相信它们共同代表了 Twitter 作为一个与其他人、整个社区以及我们触手可及的更大世界进行互动的平台的独特用途。我们通过找到经常发微博并且在“推特世界”之外很受欢迎的用户,为每个类别选择了 10 个账户。我们选择的客户显示在下面的徽标图中:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

categories = {fast food, airlines, sports leagues, colleges, tech giants, streaming platforms, news, celebrities}

我们不得不删除一些我们最初选择的账户,因为它们的推文太少了。最初,我们有一个歌手和演员类别,但我们决定将这两个类别合并成一个更加多样化的名人类别。这使得我们能够包括像艾米·舒默和克莉茜·泰根这样的人(两人都在 Twitter 上非常活跃),并淘汰了许多我们选择的在 Twitter 上更为分散的演员。

数据清理

一旦我们收集了数据,我们必须对其进行预处理,以便为我们的情感分析和词云创建构建一个语料库。我们执行了以下清洁措施:

  • 将所有推文改为小写
  • 删除所有停用词(由 nltk 定义)
  • 删除提及、链接和标签
  • 删除所有标点和括号
  • 删除所有单字符单词

这些清洗技术旨在去除在我们的分析中会导致无关信息或混淆信息的字符和单词。我们希望确保所有相同的单词看起来都一样——因此,小写和删除标点符号——我们还希望语料库中的所有单词都有意义,从而证明我们为什么删除特殊字符。如果你愿意,我们的清理,或者说去除谷壳,是为了让我们以后的分析更有信息和帮助。

方法 1:情绪分析

对于我们探索性数据分析的第一阶段,我们认为按类别查看推文的负面或正面程度,以及不同账户的平均负面或正面程度会很有趣。我们使用 affin 库来计算情感得分,并根据清理后的推文长度进行标准化。然后我们绘制了每个账户的平均情绪得分,按类别细分。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

category-level subplots of average sentiment score for each Twitter account

新闻是所有账户中唯一平均情绪得分为负的类别。这是有道理的,因为大多数公司都在回应投诉(并试图保持一切积极的态度),名人也在努力维护自己的品牌。然而,新闻来源不断报道世界范围内的悲剧、战争和各种其他负面事件。我们确实期望看到更保守的新闻来源(福克斯、the Blaze 和《华尔街日报》)和更自由的新闻来源(华盛顿邮报、纽约时报和赫芬顿邮报)之间的差异。然而,新闻来源的积极性和它们在政治光谱中的位置之间没有明显的差异。《赫芬顿邮报》和《华尔街日报》是最不负面的两家推特,而 NBC 和 Blaze 是最负面的两家。

我们还分析了给定类别中所有推文的情绪直方图,没有考虑不同账户之间的情绪差异。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

histogram subplots of average sentiment scores by category

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

preview of interactive Bokeh plot for sentiment score vs. category

如果你想和我们上面的散景直方图互动(强烈推荐),请访问我们的 GitHub repo 。不幸的是,目前你不能将散景图嵌入到媒体中(真的很遗憾,散景和 Codepen 应该合作,给人们他们想要的东西)。正如我们在前面的图表中观察到的,新闻比其他的要负面得多。这是唯一一个中位数小于 0 的类别,而其他类别都倾向于情绪谱的积极一面。也就是说,所有图表都以 0 为中心(在 0 处有一个巨大的峰值),因此这意味着账户发送的许多 tweets 都由均等分布的正面和负面单词组成。

我们发现有趣的是,航空公司和快餐公司为糟糕的服务或客户问题道歉的所有推文并没有更负面地扭曲结果,因为这些推文充满了像“不”和“对不起”这样的词。我们假设,这可能是因为这些推文经常包含许多其他中性和积极的词,例如“请”、“帮助”和“更好”,这些词抵消了更多的负面词。

尽管我们的发现很有趣,但总的来说,这些类别和许多账户都是中性的。我们想对按类别和按账户使用的词做更深入的探索,这样我们就能更好地了解他们真正在推特上谈论什么。

方法二:词频

就量化任何给定文本样本的情感负荷而言,情感分析可能非常有价值,但情感得分的可视化往往令人印象深刻,我们了解到,从高度集中在 0 附近的直方图中只能获得这么多见解。此外,当试图描述具有类似“快餐”的类别标签的数据集时,情感分析完全忽略了可能看起来很有趣的名词的高流行率。出于这个原因,我们决定转向并深入一种不同类型的分析:词频。我们假设,通过以词云的形式可视化语料库,我们将能够识别扩大的高频词,这些词对于它们来自的类别来说很有意义。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

word cloud GIF with 1 custom-shaped word cloud per category

我们的假设在很多方面都是正确的。正如你在上面的 GIF 中看到的,单词云似乎反映了你在查看 8 个类别的推文时可能观察到的单词内容。

以下是通过视觉观察单词 clouds 得出的一些观察结果:

快餐 : us,please,thank,sorry,dm,contact,info,hear,phone
航空公司 : please,thank,dm,us,hi,sorry,hear,flight,number
联赛:游戏,比赛,pt,跑步,进球,获胜,观看,领先,团队,球员,运动
院校:学生,新生,年,美国,via,杜克,研究,学习,世界
科技巨头【T13 感谢、使用、爱、现在、听、确认、宣传片、内容
新闻:川普、新、总统、人、年、说、美国、弹劾
名人:爱、感谢、今晚、快乐、人、朋友、时间、乐趣、年

令人着迷的是,仅仅记下一列出现在人眼中的单词,我们就能够在某种程度上隐含地综合这些数据。一些跨多个类别的常用词包括“请”、“谢谢”。“我们”、“新”、“年”等。有趣的是,从客户服务的角度来看,快餐连锁店和航空公司似乎都在使用 Twitter,并向经常对产品不满的特定用户提供大量回复推文。这种直觉可能解释了为什么这两个类别共享“请”、“谢谢”、“dm”、“我们”、“抱歉”和“听到”等词。一家快餐公司可以索要顾客的联系信息,并以一顿免费餐来“弥补”,而一家航空公司却不能提供这样的友好姿态。只是精神食粮!

新闻和名人是有趣的类别,因为推文选择在本质上是如此多样化。每个单独的新闻提供者关注的是时事新闻,因此我们观察不到多少纵向趋势来阐明某个集中的主题。以类似的方式,名人在推特上发布与他们的生活和他们自己的生活相关的内容。瑞安·雷诺兹经常提到“死侍”,但毫不奇怪,数据集中的其他名人都没有提到这部电影。这里的要点是,由于语料库中充满了如此多的罕见名词,高频词的数量似乎减少了。我们看到高度通用的词,如“新”、“年”、“说”和“我们”,然后用最大的字体,我们看到“特朗普”、“总统”和“弹劾”。说够了…

单词 clouds 作为一个很好的刺激来收集每个类别的语料库的初步印象,但是我们渴望数字和数据!不仅如此,单词 clouds 还让我们好奇,我们如何通过账户获得每个类别中最常见单词的洞察力,而不仅仅是一般的分类比较。因此,我们进一步研究了词频数据,提取了每个账户中最常见的 10 个词,并按类别显示出来。结果可以在下面的 GIF 中看到。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

top 10 words per account for each category and their occurrences

快餐、航空和科技 Twitter 账户说了很多“请”、“对不起”和“联系”(IHOP 的客户服务热线是他们第三常用的词)。正如我们前面提到的,这些账户的大多数推文都是发给不满意的客户的,帮助他们解决问题。这意味着他们的热门词汇都有令人难以置信的高计数,并且在某个点上有一些下降,因为他们的许多推文都有类似的前提(处理客户投诉)。

星巴克、特斯拉和 Snapchat 似乎是这些账户中唯一主要使用它做广告的账户,它们的每个词的计数要低得多,可能是因为对客户的重复回复最少。星巴克的前两个词是“啜饮”和“快乐”,特斯拉的是“增压器”和“模型”,Snapchat 的是“介绍”和“见面”。所有这些高频词都是非通用的,它们也不是对公司名称或产品的明确引用。人们可以看看这些词频见解,并声称这三家科技公司正在有效或最佳地使用 Twitter 平台,因为它们在太多直接回复用户和太多推广内容之间取得了完美的平衡。然而,相对于竞争对手,Snapchat 并不是一个特别活跃的 Twitter 用户:它的第七到第十热门词汇都只被使用了 5 次。也许他们应该分配更少的时间来开发新的变声和面部变形过滤器,而应该分配更多的时间来破坏人们的 Twitter 时间轴!也许他们在 Twitter 上的存在对他们作为一个年轻公司实现目标没有起到任何重要作用。谁知道呢?

体育联盟的推特使用了许多适合他们运动的行话,许多词指向用于广告游戏的推特(像“今晚”、“观看”和“游戏”这样的词很常见)。

看起来,大学的推特们喜欢谈论他们自己。除了普林斯顿和 UMiami,所有的账户都把他们的大学名称(以某种形式)作为他们最常用的词。其他常见的词是“学生”、“研究”和“校园”,表明他们的推特经常被用来谈论各自大学发生的事情。大多数科技公司和一些流媒体公司的名字都出现在他们的常用词汇列表中。这在其他类别中相当少见。

流媒体网站似乎大多使用他们的 Twitters 来推广新的发布,因为“首映”、“推广”、“新闻”和“今晚”都是跨帐户的常用词。与其他一些面向客户的类别不同,很少有词暗示了与快餐、科技和航空公司同等水平的解决客户问题的能力。

由于 9/10 的新闻推特是美国网站,许多词与美国政治和时事密切相关,如“总统”、“特朗普”和“弹劾”。有趣的是,BBC(唯一的国际新闻来源)的列表中也有“特朗普”和“总统”。唯一一个明显与非美国时事有关的词是“洪”,这是《华尔街日报》排名第十的最常用词。我们打赌他们第 11 个最常用的词是“孔”。有人要吗?

名人账户似乎主要是为了感谢他们的粉丝。“爱”、“感谢”和“快乐”都是流行词汇。不同名人的推特账户之间似乎也有明显的重叠。尽管类别内和类别间的字数差异很大,但名人的最高字数往往要少得多。与许多一天发多次推特、处理投诉和提及各种商品或销售的公司不同,名人的推特量要小得多。这导致热门词的使用更少,推文内容的变化更多。

我们还想看看前 10 个词在类别上的重叠情况。因为我们认为 10 路维恩图会有点忙乱,所以我们选择使用网络。较大的橙色节点代表类别,较小的蓝色节点代表单词,连接表示单词在该类别的前 10 名中。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

network visualization of top 10 words per category

我们发现有趣的是,体育是唯一一个与其他类别完全没有重叠的类别。在 55 个不同的单词中,有 13 个至少被两个类别共享:“我们”、“请”、“dm”、“对不起”、“你”、“谢谢”、“喜欢”、“嗨”、“谢谢”、“我们很好”、“新的”、“爱”和“一”。单词节点的平均度为 1.45,这意味着平均排名靠前的单词通常是不止一个类别的常用单词。当只看跨多个类别共享的常用词时,平均程度为 2.92(大幅增加)。许多这样的共享词反映了消费者在 Twitter 上寻求帮助解决他们的问题或负面经历的流行,以及公司发出解决这些问题的推文数量。许多只用于一个类别的单词对该类别来说更加具体,比如所有的体育行话,“飞行”、“教授”和“特朗普”。

总之,本节中的自然语言处理技术帮助我们熟悉了来自不同账户和 Twitter 领域的推文内容。令人惊讶的是,我们随机选择了一些类别和账户,以为我们正在构建一个足够多样化的数据集来发现一些有趣的东西,而我们实际上确实收集了数据驱动的见解。现在我们知道我们的研究范围足够丰富,可以进一步研究,这就像我们已经验证了我们的概念设计证明,我们可以细化我们的研究问题,使其更窄,更有价值。

方法 3:递归神经网络(RNNs)

如果你已经做到了这一步,把这一步想象成喝完一碗可可脆饼后喝巧克力牛奶。这与我们开始这个项目的最初原因没有太大关系,但它无疑增加了我们的体验。

你可能想知道,为什么在过去的 10 分钟里,我们一直在不停地谈论 NLP 技术,如情感分析、词云可视化和词频分解,而我们现在提出了 RNNs。或者你可能想知道 RNN 是什么?这是完全正确的。

我们决定包括这一部分,因为,让我们面对现实吧,了解到吉米·法伦在他过去 5 年的推文中使用了 1303 次“今晚”这个词,这很酷,也很准确,但是你和我应该怎么处理这些信息呢?我们如何以最大限度地提供信息的方式来检测模式。好吧,你猜怎么着。答案就在我们心中。人类特别擅长综合信息。我们的神经元有点像野生的。但是,即使我们擅长综合信息,我们表达我们观察到的模式的能力也是相当糟糕的。

那么,我们为什么不训练一个神经网络模型来从数据中学习东西,就像人类会做的那样?对于这种类型的应用,RNNs 是神经网络的一种非常有用的变体。与依赖于两个连续输入相互独立的假设的普通神经网络不同,试图推断与基于语言的数据相关的模式需要某种“记忆”。网络必须捕捉、保留和积累信息。必须考虑对先前观测的依赖。

建筑

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

RNN model architecture

代码

stripped down, uncommented RNN code in case you want to borrow it for your own usage

运行中的网络

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

video of our celebrities RNN training and generating sample tweets with varying diversities

我们重新利用了在丹麦留学学院(DIS)学习的“人工神经网络和深度学习”课程的代码,以便训练四个不同的神经网络,每个网络都适合一个独特类别的数据。我们训练了 50 个纪元,获得了 60%的准确率。我们还生成了具有不同多样性(0.2、0.5 和 1.0)的 tweet 样本。在下面的四个部分中,我们将嵌入一些使用 0.2 多样性生成的样本 tweets,我们将比较网络在早期和后期学到了多少。

快餐——生成的 Tweet 样本

epoch 1/50: accuracy = 44.18%, "to make it right? Very mysterious!"

去弥补吗?非常神秘!重要的事情。你能告诉我们具体的决定吗?你能告诉我们怎么想吗?你能告诉我们具体的决定吗?你能告诉我们怎么想吗?你能告诉我们如何思考吗?你能不能不要介意?你能给我们讲讲吗

在训练的第一个时期,我们的 RNN 模型开始生成一条 tweet (280 个字符),带有一个起始种子(40 个字符),内容是“让它正确?很神秘!”。当它开始偏离输入序列时,显然是非常混乱的。由于短语“你能给我们发短信吗”在数据集中的流行度很高,它反复尝试以该表达开始构建句子,但无法产生超出该表达的真实英语单词。

epoch 50/50: accuracy = 84.27%, "Please send us a DM if you're interested"

安吉拉,如果你对辣鸡块感兴趣,请给我们发一封 DM!请告诉我们餐厅的位置和你的电话号码,这样我们就能解决这个问题了。谢谢!那不行!请告诉我们餐厅的位置和你的电话号码,这样我们就能解决这个问题了。谢谢!那不行!

在精确度提高了近一倍后,神经网络的表现好了很多。我们看到连贯的英语句子,甚至可以发现这条推文中提到的快餐领域的“辣块”,这正是我们希望看到的内容类型。我们还看到网络试图加入一些标签。诚然,没有必要在推文中说#so,但它知道“#”字符在数据集中出现的频率很高,并且它积极地试图与时俱进,这一事实足以成为值得骄傲的理由。我们的神经网络总是把客户放在第一位,反复承诺“把这件事做好”,反复说“那不行!”。这表明它已经理解并能够反刍它从训练数据中观察到的语言模式。

联赛——生成的推文样本

epoch: 3/50, accuracy = 51.7, "ty @Jamal_Carter6! What him scrape by t"

ty @Jamal_Carter6!看着他从第一名到第一名,从第一名到第一名,从第一名到第一名,从第一名到第一名,从第一名到第一名,从第一名到第一名,从第一名到第一名

虽然,就像快餐一样,网络似乎陷入了一个无限循环,试图一遍又一遍地使用短语“第一”,但它发现了体育推特的一些重要方面。它试图提及一名球员和一支球队,并使用了“损失”一词。

epoch: 50/50, accuracy = 62.46%, "professionals for their impact on the game"

职业球员因其对@ national 比赛的影响而在@ LAClippers # PGA champ | @ BKoepka(22 分,6 次 REB,11 次 AST)和@SheffieldUnited 中的@Lakers 和@ ConnecticutSun 赢得@ national:# NFL 100 最伟大的球队@NFLNetwork №1: 1997 @NCAADII 女子高尔夫和 the

这条最大准确度的推文不如它的快餐同行好(可能是因为不同账户之间的同质化程度较低),但它提到了真实的团队,并使用了真实的标签。“@BKoepka”是 Brooks Koepka 的真实 Twitter 句柄,“(22 PT,6 REB,11 AST)”是一个篮球运动员的合法统计报告,但当这两个部分在推文中相邻放置时没有意义。虽然国家队(一支棒球队)永远不会出现在 PGA 村(高尔夫球员),但我们可以看到体育推特的一些重要方面:胜利公告、球员统计数据和提及次数。这意味着许多体育推特包含关于即将发生的比赛和过去比赛结果的信息。

新闻-生成的推文样本

epoch: 3/50, accuracy = 51.40%, "dispatcher is being lauded for recognizi"

调度员因为在弹劾调查中认识到了比总统更多的东西而受到称赞,学生们认为各州和各州的总统和检察官是市长,这将是一场竞争。

再说一遍,虽然这条推文没有太多意义。它采用了我们在频率分析中注意到的一些流行语,比如“总统”和“弹劾”。尽管它的结构很荒谬,但它能够复述新闻媒体经常使用的词汇。

epoch: 46/50, accuracy = 58.74%, "Sen. Warren on Bloomberg entering the ra"

参议员沃伦对彭博进入比赛的呼吁法院为国家的法院的总统的情况下。这个州使得一个派了一个媒体被一个接收到的州去看弹劾案的听证会,他们已经想站在竞选的那一边了

这条推文比第一时代更接近真实的新闻推文。它能够提取推文中常见的信息(如“弹劾听证会”和“竞选”),我们可以推断新闻机构的许多推文目前正在讨论美国政治的两个最大方面:特朗普的弹劾听证会和即将到来的总统选举。

名人—生成的推文样本

epoch: 2/50, accuracy = 42.48%, "/Bv13d8lFHjc/?utm_source=ig_twitter_shar"

/Bv13d8lFHjc/?UTM _ source = ig _ Twitter _ share&igshid = 1 ric 6 ctn 7 ZZ UX #不负责任# TheMich # the good # hustle hart # the miller # Fallon tonight 感谢你们的演出感谢过去的演出感谢工作感谢看演出的眼神最美好的演出最美好的未来和最美好的父亲

这条推文的标签比任何其他类别都多,并且来自各种不同的账户。我们可以再次看到,频率分析中的前 10 个词中的一些被纳入进来,因为最后一部分使用了大量的“谢谢”、“展示”和“最好的”——我们认为这些语言意味着名人感谢他们的粉丝。

epoch: 47/50, accuracy = 56.88%, "nstagram.com/p/BopWlA6lP_e/?utm_source=i"

nstagram.com/p/BopWlA6lP_e/?UTM _ source = ig _ Twitter _ share&igshid = 1 zdttsjz 2 poo #今晚的法伦之夜:@ NBC world DOF dance #法伦之夜感谢@ HobbsAndShaw # TheNextLevel #法伦之夜感谢@ RealHughJannyMario&@ NBC world DOF dance #法伦之夜:@ NBC world DOF dance #法伦之夜感谢@TheEllenShow 今晚

这条推文包含一连串的提及和标签。由此,我们可以假设,比起体育账户,名人更热衷于给别人贴标签和包含标签。这最有可能提高他们推文的受欢迎程度,促进他们正在进行的各种项目,希望他们使用的一些标签能够爆炸,成为 Twitter 的趋势。这条特定的 RNN 生成的推文包含“今晚”、“谢谢”和“#FallonTonight”,这向我们表明,这个特定的 RNN 可能已经过度了,因为吉米·法伦在演出后发出了大量的“谢谢”(他需要冷静下来,不要歪曲我们的数据集)。

我们相信我们训练的四个 rnn 以一种真正有价值的方式帮助我们观察语言模式。不一定有生成推文的需求,因为大多数 Twitter 用户不难拿出仅 280 个字符的内容与世界分享,但这些递归神经网络能够合成大量推文并返回一些揭示原始数据特征的内容,这一事实非常酷!

未来方向

这个项目将来可以向许多潜在的方向扩展。由于 GetOldTweets3 使收集 Twitter 数据变得如此容易,我们很乐意检查更多的类别和每个类别的更多帐户,看看是否会出现更多的模式。同样,我们希望有时间在所有类别上训练一个递归神经网络,以便从数据中提取更多的模式。这将有助于我们进一步分析每一类 Twitter 讨论的一般话题,并更好地理解不同帐户组之间的一些趋势。

此外,引入一些不同类型的图表会非常有趣。我们的数据看起来是这样的,因为我们采用了最多 10,000 条推文,GetOldTweets3 是按时间倒序排列的,我们的数据集并没有完全设置为查看一段时间内的推文量。如果我们有时间,我们会取消我们的推文数量限制,重新搜索每个帐户,以获得过去 5 年的所有推文,然后我们会按类别绘制推文的时间序列分析。我们很想知道在过去的五年中是否有任何趋势,特别是在相对于时间的推文内容方面。我们可以设想这种时间序列分析启动另一个关于使用 NLP 和 ML 技术预测新闻趋势的大数据项目。

如果有时间,我们最想做的一件事就是创建一个机器学习模型,来预测给定推文的标签会有多流行。我们认为这是可行的,因为 Twitter API 和 UI 搜索字段使得查询带有趋势标签的推文变得非常容易,并且我们在整个项目中调查的所有账户都很受欢迎并且得到了验证。我们很想研究给定推文中使用的标签与该推文的病毒传播程度之间的关系,这可以通过赞数和转发数来量化。这个模型有可能被用来帮助公司决定他们应该利用哪些趋势,哪些趋势不值得花费精力。能够在一定程度上准确预测一条给定推文的成功将是一个有用和有趣的工具,尤其是在这个互联网营销的时代。

代码库

如果这个项目以任何方式、形状或形式让你感兴趣,我们强烈建议你使用我们的代码。采用我们在本文中使用的一种技术,用它来构建一些很酷的东西。然后写一个故事,让大家跟你学习,跟你一起学习。

[## sejaldua/Twitter-sphere

使用 8 x 10 x 10000 的推特数据集和大数据技术对推特内容进行分类分析…

github.com](https://github.com/sejaldua/twitter-spheres)

承认

感谢我们的 Lucian Leahu 教授,感谢他对这个项目的帮助,感谢他教给我们这么多关于大数据领域的知识。感谢 Ulf Aslak Jensen 创建了这个课程和练习,帮助我们学习一些基本技能,我们现在可以用这些技能来处理令人敬畏的项目。感谢 GetOldTweets3,与 Twitter 的 API 相比,它就像是一个大大的拥抱。像往常一样,向开源社区和 StackOverflow 大声欢呼,感谢他们一路上帮助我们解决所有有趣的问题。还有像你这样的读者,激励你不断创造,不断用数据讲述故事!

参考

[## Twitter 数据挖掘:挖掘没有 API 键的 Twitter 数据。

使用一行命令获取旧的 Twitter 大数据进行分析。

medium.com](https://medium.com/@IrekponorVictor/twitter-data-mining-mining-twitter-data-without-api-keys-a2a2bd3f11c) [## 用 python 创建单词云

在最近的一个 NLP 项目中,我发现单词云可以用遮罩来创建。在本文中,我将介绍如何…

towardsdatascience.com](/creating-word-clouds-with-python-f2077c8de5cc) [## netwulf

Python 中简单的交互式网络可视化。网络可视化是一个不可或缺的工具,探索…

pypi.org](https://pypi.org/project/netwulf/) [## 理解神经网络。从神经元到 RNN、CNN 和深度学习

神经网络是目前最流行的机器学习算法之一。它已经被决定性地证明了…

towardsdatascience.com](/understanding-neural-networks-from-neuron-to-rnn-cnn-and-deep-learning-cd88e90e0a90)

分析 R 中的视频游戏数据

原文:https://towardsdatascience.com/analyzing-video-games-data-in-r-1afad7122aab?source=collection_archive---------13-----------------------

作为一名游戏玩家,我从分析这个数据集中获得了很多乐趣。实际上,这个数据集是由两个不同的数据集合并而成的: TidytuesdayKaggle 。使用两个数据集的原因是因为 Tidytuesday 数据集没有足够的信息来进行有趣的分析。这就是为什么我合并了这两者,以便从中获得更多有趣的数据和见解。这也是我第一篇使用 Tidymodels 元包应用一些机器学习的文章。

***Loading Libraries***library(tidyverse) ## For data wrangling and visualization
library(lubridate) ## To work with dates
library(ggpubr)    ## Extra visualizations and themes
library(patchwork) ## Patch visualizations together
library(hrbrthemes)## Extra themes and formatting
library(ggalt)     ## Extra visualizations
library(vapoRwave) ## Retro themes
library(extrafont) ## Exta fonts***Loading Data*****video_games** <- read_csv("[https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2019/2019-07-30/video_games.csv](https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2019/2019-07-30/video_games.csv)") %>%
  mutate(release_date = as.Date(release_date, "%b %d, %Y")) %>%
  distinct(game, developer, publisher, .keep_all = TRUE)**metacritic_games** <- read_csv("C:\\Users\\ACER\\Downloads\\metacritic-games-stats-20112019\\metacritic_games.csv",trim_ws = TRUE) **Cleaning and mergin the datasets together**games_final <- metacritic_games %>%
  filter(platform=="PS4") %>% 
  inner_join(video_games,by = "game") %>%
  mutate(owners=parse_number(owners,trim_ws = TRUE)) %>%
  mutate(publisher = case_when(str_detect(publisher,pattern = "Warner Bros|WB")~"Warner Brothers",TRUE~publisher)) %>% 
  select(-c(release_date.x,developer.y,number_players,number,metascore.y))
  • 在读入 video_games 数据后,我使用 mutate 函数将 release_date 列转换为日期类型
  • 由于一些游戏有多个开发者和流派,我使用了 distinct 函数来获得每行的唯一游戏
  • 对于这个分析,我只对 PS4 游戏感兴趣。这就是为什么我在对 video_games 数据集进行 inner_join 之前,将 metacritic_games 数据集过滤为仅 PS4 游戏
  • 使用 parse 函数从 owners 列中获取每个游戏的数值上限
  • 由于有多家华纳兄弟出版社,我使用了 case_when 函数将它们合二为一
  • 最后,我取消选择了重复的列

进一步修整

经过一些调查,我意识到数据中有太多的垃圾,为了在游戏层面上做一个有见地的分析,我决定只根据拥有他们游戏的总人数来看前 50 名发行商

**Calculating top 50 publishers**top_50_publishers <- games_final %>% 
  group_by(publisher) %>% 
  summarise(Owners=sum(owners)) %>% 
  top_n(50)Filtering **games_final** based on top 50 publisherstop_50_filtered <- games_final %>% 
  semi_join(top_50_publishers)
  • 首先,我在 games_final 数据集中按发行商分组,以获得每个发行商的所有者总数,然后使用 top_n 函数获得基于所有者的前 50 名发行商
  • 然后我在 games_finaltop_50_publishers 数据集之间使用 semi_join 函数。它的作用是根据前 50 名发行商中的前 50 名发行商过滤出游戏 _ 决赛数据
  • 这个数据集比原来的小很多,但它允许我只看主流游戏
  • 请注意,这个过滤后的数据只到 2018 年,以防你想知道为什么你最喜欢的游戏没有在 2019 年上市,如战神蜘蛛侠红色死亡救赎 2

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

This is what the final dataset looks like

前 50 名出版商是谁?

top_50_filtered %>%
  filter(!is.na(publisher)) %>% 
  group_by(publisher) %>% 
  summarise(owners=sum(owners)) %>% 
  ggplot(aes(reorder(publisher,owners),owners))+
  geom_bar(fill="#8B2E8B",stat = "identity",color="black")+
  coord_flip()+
  geom_text(aes(label=paste0(round(owners/1000000,digits = 1)," ","M")),color="white",fontface="bold",hjust=1)+
  new_retro()+
  scale_color_hotlineBling()+
  labs(x=" ")+
  scale_y_comma()+
  theme(legend.position = "none",axis.text.y = element_text(colour = "white",family = "SF Alien Encounters")) 
  • 从删除 NA 发布者开始
  • 执行相同的 group by 函数来获得每个发布者的所有者总数
  • 使用 ggplotgeom_bar 制作标准条形图,并使用 coord_flip 功能翻转轴。注意:ggplot 中的重新排序功能允许绘制从最大值到最小值的排序柱状图
  • 由于 owners 变量是以百万为单位的,所以我将它除以一百万,并在末尾连接一个“M ”,使用 paste0 来标记每个发布者的所有者总数,而不会影响美观

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 那里有很多熟悉的面孔,比如育碧、摇滚明星游戏等等,但是老实说,我不知道数字极端公司 T21——坐在最上面
  • 他们实际上是一款非常受欢迎的在线免费角色扮演射击游戏的负责人,这款游戏名为 Warframe ,于 2013 年问世

用户评分和 Metascore 有什么关系?

top_50_filtered %>% 
  ggplot(aes(user_score,metascore.x))+
  geom_point(color="green")+
  geom_text(aes(label=game),check_overlap = TRUE,color="turquoise",size=3)+
  vapoRwave::new_retro()+
  scale_color_newRetro()+
  labs(title = "Relationship between Userscore and Metascore",x="USERSCORE",y="METASCORE")

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 用户评分Metascore 之间有大致趋势。像《巫师 3》、《GTA V》、《雷曼传奇》、《火箭联盟》(《T30》、《T31 》)这样的游戏在这两方面都获得了高分,这是理所应当的
  • 圈出的游戏是那些被大肆宣传但未能达到预期的游戏。虽然我很惊讶战争阴影的用户评分这么低,但是那个游戏有病啊!
  • 一个引起我注意的游戏是疯狂的麦克斯。评论家对它的评价不冷不热,但用户喜欢它。因为前者,我实际上从来没有玩过,但这可能会改变我的想法

用户得分排名前 30 的游戏

top_50_filtered %>%
  top_n(30,user_score) %>% 
  ggplot(aes(reorder(game,user_score),user_score))+
    geom_lollipop(color="white")+
  coord_flip()+
  geom_text(aes(label=user_score),color="white",hjust=-1)+
  new_retro()+
  scale_y_continuous(limits = c(0,100))+
  labs(x=" ",title = "Top 30 Games by User Score")
  • 使用 top_n 函数根据 user_score 筛选出前 30 个游戏
  • 重新排序 ggplot 中的功能,从最大值到最小值对图形进行排序
  • geom_lollipop 制作棒棒糖图

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 毫不奇怪看到巫师 3 在顶端。这场比赛是一个杰作
  • 虽然我很惊讶地看到内邪 2 排在第二位**。这是一个非常好的游戏,但我没有意识到它会获得如此高的分数,超过了像《GTA V》这样的游戏**
  • 因此,**的续集《战争阴影,中土世界:魔多阴影》**在用户中获得了更好的分数。我个人更喜欢前传,但两者都是不错的游戏
  • 我很惊讶地看到蝙蝠侠:阿卡姆骑士低于预期。这是我在 PS4 上最喜欢的游戏之一,也是我认为蝙蝠侠阿卡姆三部曲中最好的。我认为低分可能是因为人们被蝙蝠战车的机制和乏味的老板战斗所激怒

Metascore 的 op 30 游戏

top_50_filtered %>%
  top_n(30,metascore.x) %>% 
  ggplot(aes(reorder(game,metascore.x),metascore.x))+
    geom_lollipop(color="light blue")+
  coord_flip()+
   geom_text(aes(label=metascore.x),color="light blue",hjust=-1)+
  new_retro()+
  scale_y_continuous(limits = c(0,100))+
  labs(x=" ",y=" ",title = "Top 30 Games by Meta Score")
  • 和以前一样的代码。刚刚用 metascore 替换了用户分数

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 你可以清楚地看到,当我们从用户分数转移到 Metascore 时,许多游戏都发生了变化。使用 anti_join 函数,我们可以看到哪些游戏出现在用户分数排名前 30 的游戏中,而没有出现在元分数排名前 30 的游戏中
top_50_filtered %>%
  top_n(30,user_score) %>%
  anti_join(top_50_filtered %>% 
              top_n(30,metascore.x))
  • 这里的 anti_join 函数自动检测两个数据框之间的公共列— 游戏,并显示 metascore 排名前 30 的游戏中没有的前 30 个用户游戏

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 除了邪恶 2疯狂的麦克斯之外,这些游戏中的大多数在用户评分和 Metascore 之间没有太大的区别

按发布者的用户分数分布

top_50_filtered %>%
  filter(!is.na(publisher)) %>% 
  ggplot(aes(reorder(publisher,user_score,FUN = mean),user_score))+
  geom_boxplot(color="purple")+
  geom_hline(yintercept = 80,color="white")+
  coord_flip()+
  new_retro()+
  labs(x=" ")
  • 绘制箱线图以可视化前 50 名出版商的用户分数分布
  • 使用重新排序功能根据平均用户分数对箱线图进行排序
  • 在 80 处增加了一条垂直线,作为一个伟大游戏的门槛

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 我明白为什么育碧在这里得分这么低了。他们最近在《孤岛惊魂》和《刺客信条》系列中的游戏表现平平
  • 摇滚明星从不让人失望。他们制作的每一款游戏都是杰作
  • 动视遍地都是。也许人们终于厌倦了使命召唤系列
  • Capcom 真的很低。这很可能是由于发布了一款不完整的街霸 V 游戏并对其收取全价。但是 2019 年对卡普空来说是令人惊讶的一年,像怪物猎人、生化危机 2:翻拍和鬼泣 5 这样的游戏对他们来说都是巨大的成功

发布者的 Metascore 分发

top_50_filtered %>%
  filter(!is.na(publisher)) %>% 
  ggplot(aes(reorder(publisher,metascore.x,FUN = mean),metascore.x))+
  geom_boxplot(color="green")+
  geom_hline(yintercept = 80,color="white")+
  coord_flip()+
  new_retro()+
  labs(x=" ",y="Metascore")

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

似乎出版商在 Metascore 方面比他们的用户得分做得更好

平均游戏时间最长的游戏

top_50_filtered %>%
  top_n(30,average_playtime) %>% ggplot(aes(reorder(game,average_playtime/60),average_playtime/60))+
  geom_lollipop(color="purple")+
  coord_flip()+
  geom_text(aes(label= round(average_playtime/60)),color="white",hjust=-1)+
  vapoRwave::new_retro()+
  scale_y_continuous(limits = c(0,40))+
  labs(x=" ",y="Average playtime in 2 weeks -  (hrs)")
  • 每款游戏的平均游戏时间(T47)以分钟为单位来衡量用户两周平均玩游戏的时间
  • 使用 top_n 函数只查看前 30 个最长的游戏
  • 绘图时,将 average_playtime 除以 60,换算成小时
  • geom_text 以小时为单位标注平均播放时间

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 排名靠前的最长游戏大多是开放世界的比如正义事业 4、孤岛惊魂 5、疯狂的麦克斯、刺客信条、GTA V、巫师 3
  • 惊讶地看着号猎物号。我没有玩,但我不认为这是开放世界

用户正面评价的百分比

top_50_filtered **%>%**  **mutate**(percentage_positive_users=positive_users/(positive_users+negative_users+neutral_users),
         percentage_positive_critics =positive_critics/(positive_critics+negative_critics+neutral_critics)) **%>%**
  **filter**(positive_users>=10,percentage_positive_users>=0.5) **%>%**
  **top_n**(30,percentage_positive_users) **%>% ** **ggplot**(aes(**reorder**(game,percentage_positive_users),percentage_positive_users))+
  **geom_lollipop**(color="white")+
  **coord_flip**()+
  **labs**(x=" ")+
 ** new_retro**()
  • 使用 mutate 函数创建两个新列:percentage _ positive _ userspercentage _ positive _ critics
  • 由于有些游戏获得的总分很少,我使用了过滤器功能,只显示那些至少有 10 个正面用户分数,并且正面用户总百分比≥ 50%的游戏
  • Rest 与我们在之前的棒棒糖图表中使用的代码相同

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 哇!看到 GTA V 这么低很惊讶吧
  • 《疯狂的麦克斯》和《死亡之光》是其中一款非常好但却不为人知的游戏
  • 《剑术在线》收到了来自评论家的可怕评论,但是看起来用户们喜欢它

评论家的正面评论百分比

top_50_filtered **%>%**  **mutate**(percentage_positive_users=positive_users/(positive_users+negative_users+neutral_users),
         percentage_positive_critics =positive_critics/(positive_critics+negative_critics+neutral_critics)) **%>%**
  **filter**(positive_critics>=10,percentage_positive_critics>=0.5) **%>%**
  **top_n**(30,percentage_positive_critics) **%>% ** **ggplot**(aes(**reorder**(game,percentage_positive_critics),percentage_positive_critics))+
  **geom_lollipop**(color="white")+
  **coord_flip**()+
  **labs**(x=" ")+
 ** new_retro**()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • NBA 2k16 和 NBA 2k17 得到了评论家的好评,但用户的评分很低

老实说,我没有听说过排名前四的游戏,但由于它们的规模小,所以不被认为是 AAA 级游戏

预测分析

预测元得分是不实际的,因为它是基于数据集中提供的所有数值变量的公式计算的。预测用户评分更有意思。为此,我将使用 Tidymodels 元包。它是一个软件包的集合,允许您创建一个无缝的数据管道,从预处理您的数据、调整您的模型、建模您的数据、做出预测和测量您的模型性能,同时遵守 Tidyverse 的“整洁”原则

数据准备

**library(tidymodels)**ratings_data <- top_50_filtered %>% 
  **mutate**(percentage_positive_users=positive_users/(positive_users+negative_users+neutral_users),
         percentage_negative_users =negative_users/(positive_users+negative_users+neutral_users),
         percentage_positive_critics =positive_critics/(positive_critics+negative_critics+neutral_critics),
         percentage_negative_critics =negative_critics/(positive_critics+negative_critics+neutral_critics)) %>% 
  **drop_na()****Splitting the data**split <- initial_split(ratings_data,prop = 0.6,)train_games <- split %>% training() %>%
test_games <- split %>% testing()
  • 使用 mutate 函数创建新变量,这些变量将用作 user_score 的预测值
  • 删除任何缺少的值
  • 使用 rsample 库中的 intial_split 函数为我们的训练和测试分割创建一个分割参数
  • 将它与来自 rsample训练测试函数链接起来,创建我们的训练和测试数据集

创建预处理管道

**Creating Recipe**norm_recipe <-
  **recipe**(user_score~percentage_positive_critics+percentage_negative_critics+percentage_positive_users+
           percentage_negative_users+price+genre+rating+publisher,data = train_games) %>%
  **step_naomit**(all_numeric(),all_nominal()) %>%
  **step_dummy**(all_nominal(),,one_hot = TRUE) %>% 
  **step_normalize**(all_predictors(),na_rm = TRUE) %>%
 ** step_corr**(all_predictors()) %>%
  **prep**()**Applying Recipe on Train and Test sets**train_prepped <- juice(norm_recipe)
test_prepped <- norm_recipe %>% bake(test_game)
  • 使用配方包,我正在创建一个“配方”,它基本上是我想要如何处理我的数据中的变量的管道
  • 我们从定义因变量和自变量之间的关系开始
  • “步进”功能是数据转换功能
  • step_naomit 删除名义变量和数值变量中的缺失值
  • step_dummy 对所有分类变量进行一次性编码
  • step_normalize 归一化所有数值预测值
  • step_corr 删除任何彼此高度相关的独立变量
  • 准备功能基本完成并准备配方
  • juice 函数,应用于 norm_recipe,给出了训练集的转换版本
  • 烘焙函数与定额 _ 配方链接在一起,应用于测试数据,给出了转换后的版本

建模

ranger <- rand_forest(trees = 100,mode = "regression") %>% 
  set_engine("ranger") %>% 
  fit(user_score~.,data=train_prepped)
  • 为了定义我们的模型,我们使用了 Parsnip 包来定义一个 randomforest 回归模型
  • 将发动机设置到档位
  • 使用拟合函数来定义我们的公式,并提供转换后的训练数据

预测

**Converting NAs to 0**test_prepped <- test_prepped %>% 
  mutate_all(~replace(.,is.na(.),0)) **Making predictions**ranger %>% 
  predict(test_prepped) %>% 
   bind_cols(test_games) %>% 
   select(game,.pred,user_score)**Measuring Model Accuracy**ranger %>% 
  predict(test_prepped) %>%
  bind_cols(test_games) %>% 
  metrics(truth=user_score,estimate=.pred)
  • 在对准备好的测试集应用预测之前,我必须将一些 NAs 转换为 0,否则 randomforest 模型将抛出错误
  • 最后,我们使用 ranger 模型对我们准备好的测试集进行预测,并将预测与原始测试数据结合起来,以查看每个游戏的预测和实际用户分数

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Sample of predicted vs actual user scores

  • 一旦我们做出了预测,我使用标尺包中的度量函数,通过提供实际和预测的用户分数来计算模型的准确性

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • rsq 衡量因变量 user_score 的变化在多大程度上可以由数据集中的自变量来解释。在我们的案例中,考虑到我们拥有的数据类型,这还不算太糟糕,而且它是一个非常小的数据集
  • 它可以通过超参数调优和交叉验证来改进,但这超出了本文的范围。此外,这些功能目前仍在 Tidymodels 中开发,在我们的分析中还没有无缝集成它们

结论

我在对这些数据进行端到端分析时获得了很多乐趣,并且能够使用 Tidymodels 包应用一些基本的机器学习是很好的实践。尽管如此,重要的是要注意不要从这些数据中得出任何重要的结论,因为我们只查看了原始数据源的一个非常小的子集。我认为,如果我们收集更多关于所有不同视频游戏的数据,这种分析会变得更加有趣。

使用 Python 中的自然语言工具包分析葡萄酒描述

原文:https://towardsdatascience.com/analyzing-wine-descriptions-using-the-natural-language-toolkit-in-python-497ac1e228d5?source=collection_archive---------23-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

为外行描述葡萄酒

几个月前,我创建了一个 web 应用,它允许用户输入一个查询,并根据语义相似度返回葡萄酒推荐。它是使用 Tensorflow 实验室通用句子编码器构建的。当我将该工具投入生产时,我添加了将用户输入写入数据库的代码,这样我就可以分析人们用来寻找葡萄酒的词语。根据我对目前记录的内容的分析,似乎大多数人都和我一样:我几乎没有评论葡萄酒的经验,我不知道在搜索葡萄酒时应该使用哪些词。我记录的大多数查询都是两三个简单的词,比如“容易喝”为了帮助我自己和我的用户,我正在钻研葡萄酒描述,看看我能从描述葡萄酒的语言中学到什么。滚动到文章底部,查看完整的代码。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

数据和依赖关系

原始数据可以在 Kaggle 上找到;然而,本文中的例子使用了我的工程数据。对于那些感兴趣的人,我在我的原始文章中讨论了一些数据工程。为了分析文本,我使用了 WordCloudnltk(自然语言工具包) python 包。我从加载依赖项和检查数据开始:

#dependencies
import pandas as pd
import sqlite3
from sqlite3 import Error
import refrom wordcloud import WordCloud
import matplotlib.pyplot as pltimport nltk
from nltk.tokenize import RegexpTokenizer
from nltk.stem.snowball import SnowballStemmer
#nltk.download('wordnet')
from nltk.stem.wordnet import WordNetLemmatizer#nltk.download('stopwords')
from nltk.corpus import stopwordsfrom sklearn.feature_extraction.text import CountVectorizer#force output to display the full description
pd.set_option('display.max_colwidth', -1)#create connection to database
conn = sqlite3.connect('db\wine_data.sqlite')
c = conn.cursor()#create the pandas data frame
wine_df = pd.read_sql('Select title, description, rating, price, color from wine_data', conn)#display the top 3 records from the data frame
wine_df.head(3)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Top 3 results from wine_df

字数和分布

从关于数据的一些基本信息开始,很容易向数据框添加一个字数统计列,并使用 pandas 的 describe 方法来处理一些基本统计数据:

#inline function to produce word count, splitting on spaces
wine_df['word_count'] = wine_df['description'].apply(lambda x: len(str(x).split(" ")))wine_df.word_count.describe()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

wine_df.word_count.describe()

使用 matplotlib 中的图可以很容易地直观显示字数的分布:

#set x for the histogram and set bins based on max
x = wine_df['word_count']
n_bins = 140#plot histogram
plt.hist(x, bins=n_bins)
plt.show()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Distribution of description word count

停用词和频率

在依赖项中,我导入了 NLTK 库中包含的停用词列表。停用字词是最常见的字词列表,如“the”和“of”将它们从描述中移除可以突出更相关的常用词。我通过词频来判断是否应该将额外的词添加到停用词表中。在计算字数之前,我使用正则表达式清除描述,删除标点符号、标签和特殊字符:

stop_words = set(stopwords.words("english"))#show how many words are in the list of stop words
print(len(stop_words))
#179#loops through descriptions and cleans them
clean_desc = []
for w in range(len(wine_df.description)):
    desc = wine_df['description'][w].lower()

    #remove punctuation
    desc = re.sub('[^a-zA-Z]', ' ', desc)

    #remove tags
    desc=re.sub("&lt;/?.*?&gt;"," &lt;&gt; ",desc)

    #remove digits and special chars
    desc=re.sub("(\\d|\\W)+"," ",desc)

    clean_desc.append(desc)#assign the cleaned descriptions to the data frame
wine_df['clean_desc'] = clean_desc#calculate the frequency
word_frequency = pd.Series(' '.join(wine_df['clean_desc']).split()).value_counts()[:30]
word_frequency

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

25 most frequent words

查看最常用单词的列表,我决定将“葡萄酒”和“饮料”添加到停用单词列表中,这样它们就不会显示在单词云中。

#add single word to stoplist
#stop_words.add("wine")#add list of words to stoplist
add_stopwords = ["wine", "drink"]
stop_words = stop_words.union(add_stopwords)print(len(stop_words))
#181

词干化还是词干化?

两者都是规范化语言的技术,但是变元化和词干化之间的主要区别在于变元化将单词简化为词根形式,同时保持它是一个真实的单词。词干化通过去除后缀将单词还原为词根形式,并将其转化为真实单词的表示形式。例如,词干“body”和“body”都会导致“bodi”我相信共识是,引理满足优于一些词干算法;然而,词干仍然是一项需要理解的重要技术。比较这两个词云:第一个用词干处理,第二个用词条解释:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Stemming (left) v.s. Lemmatisation (right)

尽管大体相似,但请注意词干是如何影响单词后缀的。你可以看到包括“dri”、“complex”和“medium bodi”在内的几个词之间的明显区别

stem_desc = []
for w in range(len(wine_df['clean_desc'])):split_text = wine_df['clean_desc'][w].split()

    ##Stemming
#     stm = SnowballStemmer("english")
#     split_text = [stm.stem(word) for word in split_text if not word in stop_words] 
#     split_text = " ".join(split_text)
#     stem_desc.append(split_text)

    #Lemmatisation
    lem = WordNetLemmatizer()
    split_text = [lem.lemmatize(word) for word in split_text if not word in stop_words] 
    split_text = " ".join(split_text)
    stem_desc.append(split_text)
stem_desc

生成单词云

词云是可视化文本数据的一种有用方式,因为它们使理解词频变得更容易。在葡萄酒描述中出现频率更高的词在云中会显得更大。这是一种提取和可视化关键词的方法。

#set the word cloud parameters
wordcloud = WordCloud(width = 800, height = 800, background_color = 'black', stopwords = stop_words, max_words = 1000,                  min_font_size = 20).generate(str(stem_desc)) #plot the word cloud
fig = plt.figure(figsize = (8,8), facecolor = None)
plt.imshow(wordcloud)
plt.axis('off')
plt.show()
#fig.savefig("wordcloud.png")

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Word Cloud

分析 n 元语法

观察排名靠前的单词序列有助于理解描述葡萄酒的语言。三元模型分析三个单词的组合,可以让我们深入了解描述葡萄酒的常见方式,因为它保持了单词的顺序。通常,n-gram 模型用于帮助预测序列中的下一个项目,并帮助在文本分析期间维护上下文。

因为目的是分析如何描述葡萄酒,所以我需要基于频率分析创建一个新的停用词列表。我使用 scikit-learn CountVectorizer 创建一个函数来生成三元模型,然后将它们放入一个数据框中,看看我的停用词列表是否需要调整。

def get_trigrams(descriptions, n=None):

    vec = CountVectorizer(ngram_range = (3,3), max_features = 20000).fit(descriptions)
    bag_of_words = vec.transform(descriptions)
    sum_words = bag_of_words.sum(axis = 0) 
    words_freq = [(word, sum_words[0, i]) for word, i in vec.vocabulary_.items()]
    words_freq =sorted(words_freq, key = lambda x: x[1], reverse = True)

    return words_freq[:n]#run the function on the processed descriptions
trigrams = get_trigrams(clean_desc, n=15)#create a trigram data frame
trigram_df = pd.DataFrame(trigrams)
trigram_df.columns=["Trigram", "Freq"]#output top 15 rows
trigram_df.head(15)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

top 15 trigrams

在分析了顶级三元模型之后,我决定使用一个定制的停用词表。我去掉了“葡萄酒”和“饮料”以及几个顶级品种,所以我只剩下 n_grams 来帮助我理解如何描述葡萄酒。

stops = ['wine','the', 'drink', 'an', 'cabernet', 'sauvignon', 'black', 'cherry']stem_desc = []
for w in range(len(wine_df['clean_desc'])):split_text = wine_df['clean_desc'][w].split()

    #Lemmatisation
    #lem = WordNetLemmatizer()
    split_text = [lem.lemmatize(word) for word in split_text if not word in stops] 
    split_text = " ".join(split_text)
    stem_desc.append(split_text)trigrams = get_trigrams(clean_desc, n=15)#create a trigram data frame
trigram_df = pd.DataFrame(trigrams)
trigram_df.columns=["Trigram", "Freq"]#output top 15 rows
trigram_df.head(15)

可以使用条形图来可视化三元模型。

fig = sns.set(rc = {'figure.figsize':(12,8)})
bp = sns.barplot(x = "Trigram", y = "Freq", data = trigram_df)
bp.set_xticklabels(bp.get_xticklabels(), rotation = 75)
plt.show()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Top 15 trigrams

通过查看三元模型,我可以深入了解应该如何查询葡萄酒。例如,我可以看到描述中包含像“带有暗示”和“有点”这样的描述符是很常见的结合“云”这个词,我现在对关键词、顶级品种和用于描述葡萄酒的语言有了更好的理解。以下是所有代码:

#dependencies
import pandas as pd
import sqlite3
from sqlite3 import Error
import re
from wordcloud import WordCloud
import matplotlib.pyplot as plt
import nltk
from nltk.tokenize import RegexpTokenizer
from nltk.stem.snowball import SnowballStemmer
#nltk.download('wordnet')
from nltk.stem.wordnet import WordNetLemmatizer
#nltk.download('stopwords')
from nltk.corpus import stopwords
from sklearn.feature_extraction.text import CountVectorizer
#force output to display the full description
pd.set_option('display.max_colwidth', -1)
#create connection to database
conn = sqlite3.connect('db\wine_data.sqlite')
c = conn.cursor()#create the pandas data frame
wine_df = pd.read_sql('Select title, description, rating, price, color from wine_data', conn)#display the top 3 records from the data frame
wine_df.head(3)#inline function to produce word count, splitting on spaces
wine_df['word_count'] = wine_df['description'].apply(lambda x: len(str(x).split(" ")))wine_df.word_count.describe()#set x for the histogram and set bins based on max
x = wine_df['word_count']
n_bins = 140#plot histogram
plt.hist(x, bins=n_bins)
plt.show()stop_words = set(stopwords.words("english"))#show how many words are in the list of stop words
print(len(stop_words))
#179#loops through descriptions and cleans them
clean_desc = []
for w in range(len(wine_df.description)):
    desc = wine_df['description'][w].lower()

    #remove punctuation
    desc = re.sub('[^a-zA-Z]', ' ', desc)

    #remove tags
    desc=re.sub("&lt;/?.*?&gt;"," &lt;&gt; ",desc)

    #remove digits and special chars
    desc=re.sub("(\\d|\\W)+"," ",desc)

    clean_desc.append(desc)#assign the cleaned descriptions to the data frame
wine_df['clean_desc'] = clean_desc#calculate the frequency
word_frequency = pd.Series(' '.join(wine_df['clean_desc']).split()).value_counts()[:30]
word_frequency#add single word to stoplist
#stop_words.add("wine")#add list of words to stoplist
add_stopwords = ["wine", "drink"]
stop_words = stop_words.union(add_stopwords)print(len(stop_words))
#181stem_desc = []
for w in range(len(wine_df['clean_desc'])):
split_text = wine_df['clean_desc'][w].split()

    ##Stemming
#     stm = SnowballStemmer("english")
#     split_text = [stm.stem(word) for word in split_text if not word in stop_words] 
#     split_text = " ".join(split_text)
#     stem_desc.append(split_text)

    #Lemmatisation
    lem = WordNetLemmatizer()
    split_text = [lem.lemmatize(word) for word in split_text if not word in stop_words] 
    split_text = " ".join(split_text)
    stem_desc.append(split_text)
stem_desc#set the word cloud parameters
wordcloud = WordCloud(width = 800, height = 800, background_color = 'black', stopwords = stop_words, max_words = 1000, min_font_size = 20).generate(str(stem_desc))#plot the word cloud
fig = plt.figure(figsize = (8,8), facecolor = None)
plt.imshow(wordcloud)
plt.axis('off')
plt.show()
#fig.savefig("wordcloud.png")def get_trigrams(descriptions, n=None):

    vec = CountVectorizer(ngram_range = (3,3), max_features = 20000).fit(descriptions)
    bag_of_words = vec.transform(descriptions)
    sum_words = bag_of_words.sum(axis = 0) 
    words_freq = [(word, sum_words[0, i]) for word, i in vec.vocabulary_.items()]
    words_freq =sorted(words_freq, key = lambda x: x[1], reverse = True)

    return words_freq[:n]stops = ['wine','the', 'drink', 'an', 'cabernet', 'sauvignon', 'black', 'cherry']
stem_desc = []for w in range(len(wine_df['clean_desc'])):
split_text = wine_df['clean_desc'][w].split()

    #Lemmatisation
    lem = WordNetLemmatizer()
    split_text = [lem.lemmatize(word) for word in split_text if not word in stops] 
    split_text = " ".join(split_text)
    stem_desc.append(split_text)trigrams = get_trigrams(clean_desc, n=15)#create a trigram data frame
trigram_df = pd.DataFrame(trigrams)
trigram_df.columns=["Trigram", "Freq"]#output top 15 rows
trigram_df.head(15)fig = sns.set(rc = {'figure.figsize':(12,8)})
bp = sns.barplot(x = "Trigram", y = "Freq", data = trigram_df)
bp.set_xticklabels(bp.get_xticklabels(), rotation = 75)
plt.show()

谢谢大家!

—埃里克·克莱本

有关分析文本和自然语言处理的更多信息,请查看以下链接:

[## 自然语言工具包- NLTK 3.4.5 文档

NLTK 是构建 Python 程序来处理人类语言数据的领先平台。它提供了易于使用的…

www.nltk.org](https://www.nltk.org/) [## NLTK 图书

Steven Bird、Ewan Klein 和 Edward Loper 这本书的 NLTK 版本针对 Python 3 和 NLTK 3 进行了更新。第一个…

www.nltk.org](http://www.nltk.org/book/) [## 使用自然语言处理从文章中自动提取关键词

背景

medium.com](https://medium.com/analytics-vidhya/automated-keyword-extraction-from-articles-using-nlp-bfd864f41b34)

robotsdodream.com

利用散点文本空间分析 Yelp 数据集

原文:https://towardsdatascience.com/analyzing-yelp-dataset-with-scattertext-spacy-82ea8bb7a60e?source=collection_archive---------20-----------------------

使用 NLP 对文本数据进行探索性数据分析和可视化

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Scattertext spaCy

文本挖掘领域最关键的工作之一是可视化地呈现文本数据的内容。使用自然语言处理(NLP),数据科学家可以总结文档,创建主题,从不同角度和细节范围探索内容的故事情节。

这篇文章将探索 Yelp 数据集,然后使用散点图来可视化和分析文本数据。

什么是分散文本?

Scattertext 是一种工具,旨在可视化哪些单词和短语比其他单词和短语更具类别特征。

数据源

对于这个例子,我们将关注 Yelp 数据集中与 RV 相关的类别。完整的 Yelp 数据集包含 1000 多个类别和 600 万条评论。我们编辑过的 CSV 文件可以在我的 GitHub repo 中找到,还有关于我如何将 Yelp 数据集 JSON 文件转换成 CSV 文件的 Jupyter 笔记本。一篇媒体文章也贴出来了,对转换过程给出了更详尽的解释。

这个编辑过的 csv 由 Yelp 数据集中的 5 个类别组成:
RV Repair``RV Dealers``RV Rental``RV Parks``Campgrounds

加载并清理数据集

import pandas as pddf = pd.read_csv('yelp_reviews_RV_categories.csv')

在开始之前,我们想知道如何对评级进行分组。通过使用 seaborn distplot,我们可以检查评级在该数据集中的分布情况。

import seaborn as sns
sns.distplot(df['review_stars']);

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

A seaborn distplot plots a univariate distribution of observations

该图显示大多数评论被评为 1 星或 5 星,而我们只能比较 5 星和 1 星之间的评论,这将忽略 2-4 星的评论。相反,让我们将评级合并为高或低。

df['rating'] = df['review_stars'].replace(
               {1:'Low Rating', 2:'Low Rating', 3:'Low Rating',
                4:'High Rating', 5:'High Rating'})

因为我们知道这个数据集有 5 个不同的类别,我们可以进一步将相似的类别组合在一起。让我们只使用RV parksCampgrounds,暂时忽略RV RepairRV DealersRV Rental

df_Parks_Camp = df[df['categories'].str.contains(
                'RV Parks|Campgrounds', na=False)]

NLP 分析—使用散点图和空间

既然我们已经预处理了数据集,我们可以开始一些分析了。确保你已经在你的内核中下载了一个空间英语模型。

en_core_web_sm 是一个在书面网络文本(博客、新闻、评论)上训练的小型英语模型,包括词汇、向量、句法和实体。

import spacy
import scattertextnlp = spacy.load('en_core_web_sm')

如果没有,可以下载!

!python -m spacy download en_core_web_sm

接下来,我们将使用下面的函数来:

  • 建立我们的语料库,从数据集中收集文本
  • 获取术语频率和比例 f 值
  • High Rating & Low Rating按降序创建数据帧
Parks_Camp_high, Parks_Camp_low = term_freq(df_Parks_Camp)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Left — Sorted by High Rating. Right — Sorted by Low Rating

了解评分系统

Scattertext 使用缩放的 f-score ,它考虑了类别特定的精度和术语频率。虽然一个术语可能在两个类别中频繁出现(HighLow评级),但是缩放的 f 分数确定该术语是否比其他术语更具有类别特征(HighLow评级)。

例如,虽然术语parkHighLow评级中出现频率很高,但缩放后的 f 分数得出的结论是parkHigh 0.90 的关联度高于Low 0.10 的评级。因此,当评论包含术语park时,它更具有High评级类别的特征。

停止言语

请注意,有些术语不在列表中,如in theof theto theit was,这些是可以删除的停用词**、**的一些示例。

在进行自然语言处理时,停用词是一些非常常见的词,这些词在帮助选择文档时似乎没有什么价值,它们被完全排除在词汇表之外,例如thethemthey

remove_terms(nlp.Defaults.stop_words, ignore_absences=True)

spaCy 有 326 个默认停用词,我们已经使用上面的代码从语料库中删除了这些词,但我们可以添加更多。

我们可以从自然语言工具包(NLTK)中添加更多的停用词。

from nltk.corpus import stopwords
stopWords = set(stopwords.words('english'))
nlp.Defaults.stop_words |= stopWords

我们也可以通过创建一个stopwords.txt文件来设置我们自己的停用词。
将文本文件中的任何内容(包括符号、数字、术语)作为停用词从语料库中删除。
随意使用我的 GitHub repo 里面的stopwords.txt文件。

with open('stopwords.txt', 'r') as f:
    str_f = f.read()
    set_stopwords = set(str_f.split('\n'))
nlp.Defaults.stop_words |= set_stopwords

每当我们完成文本文件的更新时,记得通过运行上面的代码来保存它,以便它更新到原始的停用词集。

一旦添加了更多的停用词,我们可以再次运行term_freq功能。

Parks_Camp_high, Parks_Camp_low = term_freq(df_Parks_Camp)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Term frequency and score after removing more stop words.

分散文本可视化

数据表很好,但是可视化更好!
我们可以创建一个散点图,直观显示 Yelp 数据集中评论的高评分和低评分之间的术语关联。

corpus_dataframe = df_Park_Camp
html = scattertext.produce_scattertext_explorer(
                   corpus,
                   category='Low Rating',
                   category_name='Low Rating',
                   not_category_name='High Rating',
                   width_in_pixels=1000,
                   metadata=corpus_dataframe['name'])

交互式 HTML

https://gyhou . com/RV-Parks-Campgrounds-Yelp-Reviews-scattertext . html

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Searching for a term will show the name of the business and reviews.

理解散点图

在散点图的右侧,我们有一个评级最高的术语的概述和一个无序的术语列表(在特征下)。如果我们点击该术语,它将向我们显示数据集中的特定评论,显示为LowHigh评级。我们也可以在左下角手动搜索一个术语。

从散点图中,我们可以快速浏览一下评论中使用的术语。图右侧的红点表示与High评级更相关的术语,而左侧的蓝点表示与Low评级更相关的术语。

有了这个散点图,我们可以很容易地搜索可能对 Yelp 业务有用的术语。我们不仅可以看到一个术语是否与正面或负面评价更密切相关,还可以阅读每个单独的评论。

保存并共享为 HTML 文件

我们现在可以将它保存为 HTML 文件,以便在浏览器上查看和共享!

html_file_name = "RV-Parks-Campgrounds-Yelp-Review-Scattertext.html"
open(html_file_name, 'wb').write(html.encode('utf-8'))

感谢阅读!我很乐意听到你的想法,在这里评论或给我发消息。用于此的代码位于我的 GitHub 库中。

数据科学面试剖析

原文:https://towardsdatascience.com/anatomy-of-data-science-interview-fa9ff7caa37d?source=collection_archive---------18-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在数据科学行业拥有近十年的经验,我经常扮演面试双方的角色。在这篇文章中,我的意图是展示典型数据科学面试的一般结构,以及如何接近这个过程以取得成功。

免责声明:这是基于我的个人经验,可能与你的有有限的重叠,让我们看看我们的经验和重叠程度有多相似吧!!!!!!!!!!!!

在文章的最后,我列出了一些给寻找数据科学工作的新生的特别提示。

破冰:

在一次典型的面试中,在进入任何技术性/非技术性的讨论之前,首先你应该让自己对这个过程感到舒服。介绍部分给你一个与面试官建立融洽关系并展示你的沟通技巧的机会,千万不要错过!!!

你可以对面试官说一句非常简单的话“嗨,x 先生/女士,你好吗”?有许多你可以使用的班轮,这是一个候选线开始。随着我们的发展,我将解释如何处理*“谈谈你自己”*这个问题!!

面试结构:

根据我的观察,我觉得数据科学面试的各个部分及其权重可以大致通过下面的饼图来表示

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

让我们分别讨论每一部分。

项目-30%

简历中提到的项目是你在面试中成功的关键。参加面试的人应该对这些项目有很好的掌握。在解释项目时,确保你很好地解释了整个流程,并强调了你声称已经完成的部分。预期问题如下

  • 你为什么用兰登森林,而不是 SVM?
  • 为什么你认为精度不能进一步提高?
  • 请解释您遇到的一两个实时问题,以及您是如何解决的?
  • 这个模型对商业有什么用处(你应该用美元数量来回答这个问题)?

等等。等等。

一般来说,除了人力资源面试,项目讨论将是所有面试的一部分。一些回合可能只是项目的表面概述,而一些回合可能对项目进行深入讨论。除了接受资深数据科学家的采访,有时你可能需要与非常资深的人进行项目讨论,如董事、分析主管等。对你的期望很简单,你应该亲自动手,而不仅仅是“训练有素”的人,你应该了解数据科学项目如何通过向业务/客户交付价值来工作。

总结:对你的项目有很好的掌控力。

机器学习——20%

有一句名言,大致意思是“你的知识和面试官的知识重叠度越大,你在面试中被选中的几率就越高”。

话虽如此,在我的职业生涯中,我还没有见过任何一位数据科学家研究过所有领域/算法。有人对“自然语言处理”有很好的了解,但在“回归模型”方面做了有限的工作。有人擅长“时间序列预测”,但不擅长“无监督学习技术”。这些都是完全可以接受的场景。你不需要主宰一切。如果你的简历上说你做过《随机森林》,那你应该对随机森林有很好的了解。然而,这里有一些机器学习讨论的通用要点。擅长这些:

  • 线性回归和逻辑回归(深入理解这两种技术、分类与回归、假设、系数含义、β值和截距的商业解释、误差类型、对数似然函数、损失函数、套索和岭回归等)
  • 决策树和随机森林(什么和为什么,偏差方差权衡,修剪,过拟合和欠拟合,模型预测能力与模型解释能力,装袋,提升概念等。)
  • 主成分分析、线性判别分析、监督与非监督学习、变量缩减技术、多重共线性、方差膨胀因子、模型性能测量等。
  • 对 K 近邻、K 均值聚类、推荐引擎、支持向量机、神经网络、朴素贝叶斯等的高级理解。

带走——对重要的技术有高层次的理解,对简历中提到的技术有深入的理解。

统计-20%

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

非统计背景的人害怕从事数据科学职业的一个原因——是吗??😃

在我看来,在统计部分只会对你的一项技能进行评估——“你知道解决一个数据科学问题需要什么吗”??

统计学本身是一个巨大的知识和研究领域,有很多东西需要了解和理解,但是如果你擅长以下几点,你会被认为足够优秀!

  • 变量:名词性/分类性/序数
  • 取样技术——什么、为什么和什么时候
  • 集中趋势的测量——均值、中值、众数、绞合偏差、方差、百分位数、对盒须图和其他图的理解
  • 正态、泊松、均匀等概率分布及其在数据中的意义
  • 降维——需求和方法
  • 估计技术和假设检验

拿走——如果你是这个领域的新手,我的建议是不要打破一切关于统计的东西。知道需要什么就行了。

编程-10%:

“非编程背景”的人开始他们的数据科学之旅的另一个恐惧的原因。

需要多少编程技能?简单回答“多多益善”。然而,从面试的角度来看,我们将评估你是否能够将你的知识应用到给定的数据科学问题上。要做到这一点,需要编码。它可能不是非常高效、智能、高端的编码,但它应该服务于这个目的。换句话说,你知道统计学,你知道机器学习技术,你面前有数据。当且仅当你知道如何编码,你将苹果应用你的知识给定的数据。关于编码的几个要点:

  • SQL——这必须有技巧——无处可逃
  • 了解数据类型和结构,如变量、常数、字符串、数组、数据帧、数据表、矩阵、列表等。
  • 理解条件语句和循环,如 if else、嵌套 if else、while do while、switch、for loop、break、continue 语句等。
  • R 语言特有的 —安装和加载包、旋转表、聚合、汇总、过滤、合并、rbind、cbind、RDS、R 环境、dplyr、tidyr、caret、data.table、sqldf、ggplot2、googleVis 等包
  • Python 特有的 语言—pandas、NumPy、scikit-learn、matplotlib、seaborn 等包的功能和用法。元组、集合、字典、列表、列表理解、范围函数、可变与不可变、何时使用哪种数据类型、聚合、汇总、过滤、合并、内存管理等。

现在,很少有组织在数据科学面试中进行书面编程测试。它可以是选择题测试或要编写的代码片段。为了通过这一轮,你应该对代码很在行。

拿走——让你的手弄脏编码——没有其他的选择会有很大的帮助。

逻辑思维——10%

无论是数据科学面试还是 java 面试,逻辑思维都是有经验的面试官在讨论中试图触及的问题之一。期望也是直截了当的——“在一个给定的情况下/关于一个给定的问题陈述,你能有多逻辑地思考”。从数据科学的角度来看,它可以细分为以下两个部分:

  • 基于场景的 —基于场景的评估将通过给你一个假想的情况或问题陈述,并检查你的思考过程来进行。举个例子——如果我正在面试一个人 A,我会问他/她类似这样的问题—“我们的一个消费品(CPG)客户 ABC 希望我们建议他们在下一季度增加 5%收入的方法” 你将如何处理这个问题陈述。我希望 A 的回答是 “为了增加收入,他们应该卖得更多,他们能为卖得更多做些什么?他们能做交叉销售/追加销售吗?他们能做联合采矿吗?
  • 谜题 —面试官可以向你抛谜题,检验你的逻辑思维能力。这里提到了一些著名的

带走——不断提高自己的分析思维能力。

行为-5%:

几年前,我有这样的印象,如果你在上面提到的方面做得好,那么你肯定会被录用。然而,我最近的一次经历迫使我也给行为 5%的权重。

我的求职面试经历——在人力资源部将我的资料列入候选名单,并邀请我参加第一轮面试时,她在邮件中给我发了 YouTube 视频链接。在该视频中,该组织的首席执行官谈到了组织价值观、文化和宗旨等。我没有太在意,参加了面试。这是一个“很难破解”的面试,但我设法通过了多轮。贴那个,资深 HR 来讨论,她问我为什么要加入这个组织,对这个组织了解多少?我对这个组织了解不多,因此不能很好地回答。我不知道这将成为一个大问题!招聘 HR 给我打电话,她很不高兴我没有去过她分享过的 you-tube 视频。在进行了一次很好的技术面试后,我必须再进行两轮行为测试,在测试中我必须让他们相信我了解他们的组织、文化和价值观,并且我会融入其中。

从上述经历中学到的是——“了解你要去面试的地方”,并期待类似于“你为什么想加入我们”、“你能适应我们的文化/价值观吗”、“我们做什么工作”、“我们的 CEO/年收入”等问题。

带走——对你将要参加面试的组织进行调查。

简历/CV-5%:

这基本上是“告诉我关于你自己的情况”部分,你应该在简历中浏览一下。没有硬性规定它可以怎样,应该怎样。这又是一个展示你的沟通技巧和额外成就的好机会。尽量涵盖事情的广度,不要在项目或任何领域走得太深,而是给出概况。试着强调你独特的技能、奉献和成就。

举几个例子,在你的专业总结之后,加上这样的句子

  • 我入选了国家级数学奥林匹克第二名
  • 我是州足球队的一员
  • 我在图像编辑软件上的博客有 5 万次阅读

您还可以添加一些有趣的事实,让环境变得不那么酷:):

  • 我害怕……
  • 我爱……
  • 我隐藏的才能是………
  • 我罪恶的快乐是……

带走——正常地展示自己,保持舒适,因为这通常是讨论的第一个问题。

新生特别提示:

  • 展示你的学习能力——很有可能你会错过一些问题、场景,或者在被问到时你会对一些概念感到困惑。在这些情况下,保持冷静,不要紧张。只要专注于展示一种学习的能力。你可以很简单地说“我没有机会做这件事,如果有机会,我会学着去做”
  • 不要把事情看得太重——有时面试官可能会为了测试你的反应而把你推到不舒服的地方。记住,他或她与你没有任何私人恩怨。这只是对你态度的测试。有些面试官可能很有礼貌,有些可能很难相处。试着和两组人都保持平稳。
  • 学习行业语言— 这是我观察到的 60–70%的大一新生的问题之一。我给他们的建议是努力学习工业语言,你不能粗鲁,现在就忘记你的大学语言。我想分享的一条黄金法则是——“记住名字”。这是我经历过的最神奇的事情之一。假设你是大卫,我打电话给你说**“你好”而另一个人打电话给你说“你好大卫”哪个更好听?你有答案了!!它适用于我们所有人。任何时候你接到招聘公司/咨询公司/人力资源部等的电话。,他们会提名字,认真听,马上用。A 先生,你好,我是 ABC 公司的丹尼尔。你的回答应该是“你好丹尼尔”而不是“你好”**。这可能听起来很简单,但相信我,它在各个方面都很神奇。做了就明白了。这个概念也适用于电子邮件通信。
  • 带着微笑——我们都希望身边有快乐的环境。好人,有趣的人都喜欢,谁不喜欢微笑呢:)

带走——冷静、沉着、切题、舒适。你将成为雇佣你的组织的一笔财富。 牢记这一点,自信满满。

总结:

感谢您的阅读。我很高兴与你分享我的经验,并祝你一切顺利。我的意图是看到你马上得到一份工作,如果你获得正确的技能并遵循正确的道路,这是可能的。

您还可以在此阅读从零开始成为数据科学家的途径

请随意评论你对这篇文章的看法,或者你想让我更详细讨论的任何事情。

在 Quora 上关注我,获取关于数据科学的常规答案这里

加入我们的数据科学社区脸书TwitterInstagramLinkedIn

谢谢你

Aman(amanrai77@gmail.com)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值