TowardsDataScience 博客中文翻译 2020(一百一十八)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

计算机科学/工程领域高等院校性别差异分析

原文:https://towardsdatascience.com/analyzing-the-gender-disparity-among-higher-academia-in-computer-science-engineering-2d8cecefa76e?source=collection_archive---------47-----------------------

你不会疯狂地认为高等教育中男性明显更多——以下是数据

在学术和专业环境中,妇女在计算机科学/工程领域的代表性不足。这话我听过很多次了,但我一直在想,我们怎么才能做出这种说法。具体来说,有哪些数据支持这种说法,这些数据告诉我们这些领域代表性不足的情况是什么?在本文中,我将通过回答以下 3 个问题来探索和分析高等院校计算机科学/工程专业的性别差异:

  • 1。在美国,女性和男性在计算机科学教师职位上的比例相等吗?
  • 2。随着时间的推移,在美国获得计算机&信息科学(CIS)教师职位的女性比例发生了怎样的变化?
  • 3。随着时间的推移,美国学术界女性工程师的代表性发生了怎样的变化?

这是伯克利大学的一个更大项目的一部分

在 Ursatech Berkeley,我们通过在加州大学伯克利分校社区内提供无偿咨询服务以及将我们的专业知识借给大学附属团体来回馈我们的校园社区。

我们客户的主要目标是发现和减少阻碍少数群体在计算机科学/工程领域追求成功的学术和职业生涯的障碍。为了帮助实现这一目标,UrsaTech 将开展一个数据分析项目,该项目涉及搜集网络信息,以合并和识别大学人口数据中的模式。这将有助于我们确定学生在本科生、研究生课程和/或教师职位中如何通过计算机科学/工程课程取得进步。我这个项目的重点是性别。

问题 1:在美国,女性和男性在计算机科学教师职位上的比例相等吗?

大学第一次遇到女计算机科学家。她是我暑期实验室研究的教授!在此之前,我从未真正遇到过女性工程师或计算机科学家。随着我继续接受教育,我开始注意到在我大学的计算机科学/工程系中女教授的人数很少。如果我学校的系是这个样子,美国其他 CS 系是什么样子?具体来说,在美国,女性计算机科学教员和男性计算机科学教员的代表性相比如何?

我从下面 7 个不同的 CS 大学系收集了样本。

数据源:

如果重复,我会争取更大的样本量。

Web 报废

我写了下面的函数来从麻省理工学院、斯坦福大学和加州大学收集数据。其他学校的数据被我的队友废弃了。

我将性别列初始化为全是男性,然后针对每个学校相应地将其更改为女性。可能会有一些偏差,因为我是根据大学提供的照片人工确定这个人是男是女的。

from requests import get
from bs4 import BeautifulSoup
import re
import pandas as pd
import urllib.request
import numpy as npdef lst_data(website: str, tag: str, attrs_key: str, attrs_txt: str):
 response = get(website)
 html = BeautifulSoup(response.text, ‘html.parser’)
 name_data = html.find_all(tag, attrs={attrs_key: re.compile(attrs_txt)})
 return name_data#names = [first name, last name]
def index_values(names, name_data):
 lst = []
 for name in names:
 name_str = [str(x) for x in name_data]
 new_list = [name_str.index(x) for x in name_str if re.search(name, x)]
 lst.append(new_list[0])
 return lst#initialize all as male and change to female accordingly
def make_df(name_lst, school, female_lst):
 df = pd.DataFrame({‘Name’: name_lst, ‘School’: school, ‘Gender’: ‘male’})
 df.index = df[‘Name’]
 df.loc[female_lst, ‘Gender’] = ‘female’
 df = df.reset_index(drop=True)
 return df

以下是我如何从斯坦福大学取消教师姓名的一个例子。

name_data = lst_data(‘[https://cs.stanford.edu/directory/faculty'](https://cs.stanford.edu/directory/faculty'), ‘a’, ‘href’, ‘^http’)# Returns index values [8,67]. Use to index name_data
index_values([‘Maneesh Agrawala’, ‘Matei Zaharia’], name_data)lst = []
for faculty in name_data[8:68]: 
 lst.append(faculty.text) #female faculty names
female_lst = [‘Jeannette Bohg’, ‘Emma Brunskill’, ‘Chelsea Finn’, ‘Monica Lam’, ‘Karen Liu’, ‘Dorsa Sadigh’, \
 ‘Caroline Trippel’, ‘Jennifer Widom’, ‘Mary Wootters’]stanford_df = make_df(lst, ‘Stanford’, female_lst)

在收集和整理了适当的数据后,我发现了每个学校计算机科学系中女性教员的比例。处理数据的其余代码链接在本文末尾的我的 github 中。

假设检验:1 样本 T 检验

  • **为什么选择 1 个样本进行 T 检验:**样本量< 30 因为只有 7 所学校,并且我们有一个未知的总体标准差
  • **样本:**各学校计算机科学系中女性教员的比例(图 1)

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

图 1——相关大学中女性计算机科学教师的比例

  • 零假设: p = 0.5,因为我们正在测试计算机系女性教员的百分比是否等于计算机系男性教员的百分比,所以计算机系女性教员= 50%
  • 显著性水平(alpha): 5%,当零假设实际上为真时,我们拒绝零假设的概率是 5%
from scipy.stats import ttest_1samptset, pval = ttest_1samp(x, 0.5) #x = sample 
print(‘t-statistic:’, tset)
print(‘pval:’, pval)if pval < 0.05: # alpha value is 0.05 or 5%
 print(“Reject”)
else:
 print(“Accept”)

使用 5%的显著性水平,我们从假设检验中得到 2.82e-07 的 p 值。假设零假设为真,观察到样本数据(图 1)的概率为 0.0000282%。由于 p 值小于显著性水平,我们拒绝零假设。测试表明,女性在计算机科学教师职位中的比例与男性在这些职位中的比例不相等。

这是为什么呢?cs 教师职位合格候选人的性别统计数据是什么样的?

2.在美国,获得计算机与信息科学(CIS)博士学位的女性在教师职位中的比例随着时间的推移发生了怎样的变化?

在美国,计算机科学系的女性人数比男性少得多。CS 教授职位的合格女性是否明显较少?随着时间的推移,在 CIS 获得博士学位并有资格获得 CS 教师职位的女性比例如何?

  • **数据来源:**数据来自美国国家科学与工程统计中心(NCSES)。他们提供了关于人口统计特征、财政支持来源和博士获得者教育历史的数据表。他们的数据是通过调查收集的。
    链接:https://ncses.nsf.gov/pubs/nsf20301/data-tables/#group3一旦打开链接,点击“博士获得者,按性别和主要研究领域:2009-18”
  • **数据处理:**数据集由特定研究领域的所有博士学位获得者(男性获得者和女性获得者)精心组织。我把 NCSES 数据表下载成 Excel 文件,然后转换成 csv 文件。表 2 显示了导入的 csv 文件/数据的前五行。
    我过滤了数据框,只包括男性和女性“计算机和信息科学”收件人。处理和分析数据的其余代码在下面我的 GitHub 中。

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

表 2:“2009-2018 年按性别和主要研究领域分列的博士获得者”,由国家社会经济研究中心提供

  • 调查结果:

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

作者根据国家社会经济普查数据提供的数字

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

作者根据国家社会经济普查数据提供的数字

值得注意的是,从 2009 年到 2018 年,计算机与信息科学(CIS)博士学位获得者的比例相对保持不变,男性占 80%,女性占 20%。数据趋势表明,自 2009 年以来,独联体博士学位获得者中的女性比例没有增加。

这让我进一步质疑,随着你在学术界的地位越来越高,女性在工程领域的总体代表性。

注意:没有专门针对计算机科学人口统计的数据集,所以我主要关注工程学。

3。随着时间的推移,美国学术界女性工程师的代表性发生了怎样的变化?

如果获得计算机和信息科学博士学位的女性比例较小,那么从本科到研究生的工程项目中女性的比例如何变化?

  • **数据来源:**数据来自美国国家科学与工程统计中心(NCSES)。他们提供了关于人口统计特征、财政支持来源和博士获得者教育历史的数据表。他们的数据是通过调查收集的。
    链接:https://ncsesdata . NSF . gov/grad postdoc/2018/html/GSS 18-dt-tab 001-2c . html
  • **数据处理:**来自 NCSES 的原始数据表如下表 3 所示。该表包含 1977 年至 2018 年研究生、博士后和持有博士学位的非学术研究人员的数量和百分比。然而,为了保持一致性,我删除了任何具有 na 值的行,并以 1979-2018 年的数据结束。处理和分析数据的其余代码在下面我的 github 中。

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

表 NCSES 的“工程领域研究生、博士后和持有博士学位的非学术研究人员的性别:1977-2018”

  • 基于数量/计数视角的调查结果:

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

作者根据国家社会经济普查数据提供的数字

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

作者根据国家社会经济普查数据提供的数字

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

作者根据国家社会经济普查数据提供的数字

  • 基于比例视角的调查结果:

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

作者根据国家社会经济普查数据提供的数字

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

作者根据国家社会经济普查数据提供的数字

自 1979 年以来,高等院校中男女工程师的比例一直在下降。然而,在高等学术机构中,女工程师和男工程师的人数仍有很大差距。 学术界职位越高,工程领域的男女比例差距越大。

调查结果摘要和重要性

注:以下分析仅针对美国人口

麻省理工学院、斯坦福大学、加州大学伯克利分校、康奈尔大学、卡耐基梅隆大学、普林斯顿大学和耶鲁大学的女性计算机科学教师比例样本表明,在美国,女性和男性在计算机科学院系中的比例并不平等。经过仔细观察,合格的计算机和信息科学(CIS)男性和女性博士之间有很大的差距。从 2009 年到 2018 年,独联体博士学位获得者的比例相对保持不变,男性占 80%,女性占 20%。数据趋势表明,自 2009 年以来,独联体博士学位获得者中的女性比例几乎没有增加。另一方面,自 1979 年以来,学术界男女工程师的比例一直在下降。然而,在高等学术机构中,女性和男性工程师的人数仍有很大差距。学术界职位越高,工程领域的男女比例差距越大。

大学是让我们的下一代接触充满机遇的世界的时候!直到大学的时候,我遇到了一位女性计算机科学家,我才开始尝试编码。对我来说,看到女性代表很重要。对许多其他人来说,大学可能是他们第一次在他们想从事的职业中看到与他们相似的人。我注意到我的研究中的一个限制是我寻求更多的数据。至于下一步,我想扩大视角/收集更多数据,并研究其他因素,如种族、年龄、居住地、健康状况等。此外,我希望调查是什么阻碍了更多女性进入高等院校的计算机科学/工程专业。

这个项目的完整代码可以在我的 github 中找到。
如果你喜欢阅读或者学到了新的东西,请随时给我一个👏
考虑分享这个来开始对话!🤔

用 nasapy 分析未来十年的近地天体

原文:https://towardsdatascience.com/analyzing-the-next-decade-of-earth-close-approaching-objects-with-nasapy-8a6194c4a493?source=collection_archive---------40-----------------------

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

昆廷·凯梅尔在 Unsplash 上的照片

在这个例子中,我们将通过提取美国宇航局喷气推进实验室的小天体数据库确定的未来 10 年接近地球的物体,来遍历nasapy库的一个可能的用例。

在开始之前,导入我们将用来提取和分析数据的包。数据分析库 pandas 将用于获取数据,而 seaborn 用于绘制数据。加载神奇命令[%matplotlib inline](https://ipython.readthedocs.io/en/stable/interactive/plotting.html#id1)以显示生成的图形。

**import** **nasapy**
**import** **pandas** **as** **pd**
**import** **numpy** **as** **np**
**import** **matplotlib.pyplot** **as** **plt**
**import** **seaborn** **as** **sns**

%**matplotlib** inline

nasapy库的close_approach方法允许人们访问 JPL SBDB 以提取与地球附近已知流星体和小行星相关的数据。设置参数return_df=True会自动将返回的 JSON 数据强制转换成 pandas 数据帧。提取数据后,我们将几个变量转换成float类型。

ca = nasapy.close_approach(date_min='2020-01-01', 
date_max='2029-12-31', return_df=**True**)

ca['dist'] = ca['dist'].astype(float)
ca['dist_min'] = ca['dist_min'].astype(float)
ca['dist_max'] = ca['dist_max'].astype(float)

返回数据的dist栏以天文单位(AU)描述了物体的标称接近距离。一个天文单位或 AU 大致是地球到太阳的距离,约为 92,955,807 英里或 149,598,000 公里。使用[.describe](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.describe.html)方法,我们可以显示总结数据的描述性统计数据。

ca['dist'].describe()count    729.000000
mean       0.030775
std        0.012718
min        0.000252
25%        0.021520
50%        0.031960
75%        0.041442
max        0.049983
Name: dist, dtype: float64

我们看到澳大利亚的平均进近距离约为 0.031,我们可以将其转换为英里数:

au_miles = 92955807.26743
ca['dist'].describe()['mean'] * au_miles2860693.219664113

因此,在未来十年中,接近地球的物体的平均距离约为 286 万英里,是地球到月球距离(238,900 英里)的 10 倍以上。

未来十年内最接近地球的物体会怎样?使用[.loc](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.loc.html)方法,我们可以找到距离最近的物体。

ca.loc[ca['dist'] == ca['dist'].min()]

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

最近的已知天体预计将在 2029 年 4 月 13 日接近地球,距离地球 0.00023 天文单位。将天文单位转换成英里,我们可以更好地了解物体的接近距离。

print('Distance: ' + str(au_miles * ca['dist'].min()))
print('Minimum Distance: ' + str(au_miles * ca['dist_min'].min()))
print('Maximum Distance: ' + str(au_miles * ca['dist_max'].min()))Distance: 23440.92769543333
Minimum Distance: 644.2481158331191
Maximum Distance: 23874.510393069424

我的天啊。看起来这个物体会比较接近地球,大约 23000 英里,在 64423874 英里的范围内。作为比较,最大距离大约是地球到月球距离的 1/10。

让我们对未来十年每年接近地球的物体数量有个大概的了解。首先,我们使用[.apply](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.apply.html)[to_datetime](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.to_datetime.html)的组合将临近日期的年份提取到一个新列approach_year中。

ca['approach_year'] = ca['cd'].apply(**lambda** x: pd.to_datetime(x).year)

使用[.groupby](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html)方法,我们创建一个新的数据帧,其中包含每年接近物体的总数。

approaches_by_year = ca.groupby('approach_year').count().reset_index()

我们可以使用 seaborn 的柱状图函数来绘制每年接近物体的数量。

plt.figure(figsize=(10, 6))
p = sns.barplot(x='approach_year', y='h', data=approaches_by_year)
plt.axhline(approaches_by_year['h'].mean(), color='r', linestyle='--')
p = p.set_xticklabels(approaches_by_year['approach_year'], rotation=45, ha='right', fontsize=12)

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

每年接近地球的物体数量

有趣的是,今年(2020 年)将有最多的活动,然后在接下来的几年里会有所下降,直到十年结束。平均来说,这十年中每年有不到 80 个接近地球的物体。

作为最后一个例子,让我们使用 seaborn 的[.kdeplot](https://seaborn.pydata.org/generated/seaborn.kdeplot.html)绘制接近物体距离的分布,它创建了一个内核命运图。我们也可以像上面那样添加一条距离的中线。

plt.figure(figsize=(14, 6))
plt.axvline(ca['dist'].astype(float).mean(), color='r', linestyle='--')
sns.kdeplot(ca['dist'], shade=**True**)

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

地球近距离物体距离的分布

正如我们上面提到的,平均接近距离略大于 0.03,我们可以在上面的密度图中看到。最后,我们可以使用 numpy.random.normal 绘制距离分布的正态分布图,以快速比较实际分布和正态分布。

plt.figure(figsize=(14, 6))

x = np.random.normal(size=len(ca['dist']), 
                     scale=ca['dist'].std(), 
                     loc=ca['dist'].mean())

plt.axvline(ca['dist'].mean(), color='r', linestyle='--')

sns.kdeplot(ca['dist'], shade=**True**)
sns.kdeplot(x, shade=**True**)

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

与正态分布相比的地球近距离接近物体距离的分布

我们看到距离的分布不太正常。肯定有更复杂的技术来分析数据集的分布,但这将留到将来可能的练习中。

机器学习中分类模型的性能分析

原文:https://towardsdatascience.com/analyzing-the-performance-of-the-classification-models-in-machine-learning-ad8fb962e857?source=collection_archive---------46-----------------------

探索混淆矩阵、ROC-AUC 曲线和机器学习中分类的成本函数的基础。

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

萨法尔·萨法罗夫在 Unsplash 上拍摄的照片

混淆矩阵

混淆矩阵(也称为误差矩阵)用于分析分类模型(如逻辑回归、决策树分类器等)的好坏。)执行。我们为什么要分析模型的性能?分析模型的性能有助于我们发现并消除偏差和方差问题(如果存在),也有助于我们微调模型,使模型产生更准确的结果。混淆矩阵通常用于二分类问题,但也可以扩展到多分类问题。

混淆矩阵的术语

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

二元分类的混淆矩阵。图片来源

用例子来说明概念会更好理解,所以让我们考虑一个例子。让我们假设一个家庭去检测 COVID19。

真阳性(TP): 真阳性是被预测为阳性的病例,他们确实患有该疾病。

假阳性(FP): 假阳性是已经被预测为阳性但他们并没有那种疾病的病例。

真阴性(TN): 真阴性是被预测为阴性的病例,他们确实没有患那种疾病。

假阴性(FN): 假阴性是已经被预测为阴性,但是他们患有该疾病的病例。

敏感度:敏感度又称为召回率和真阳性率。敏感度是实际阳性中被正确预测为阳性的比例。换句话说,敏感度是真阳性与真阳性和假阴性之和的比率。

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

PC:作者

特异性:特异性也叫真阴性率。特异性是被正确预测为阴性的实际阴性的比例。换句话说,特异性是真阴性与真阴性和假阳性之和的比率。

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

PC:作者

**精度:**精度是被正确预测为阳性的预测阳性的比例。换句话说,精度是真阳性与真阳性和假阳性之和的比率。

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

PC:作者

F1 得分: F1 得分定义为精度和召回率的调和平均值。F1 分数从 0 到 1,0 为最差分数,1 为最高分数。当数据遭受类别不平衡时,可以使用 F1 分数,因为它同时考虑了假阳性和假阴性。

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

PC:作者

**准确度:**模型的准确度被定义为真阳性和真阴性之和与预测总数的比率。精确度范围从 0 到 100。当必须获得真阳性和真阴性时,可以使用准确性。

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

PC:作者

ROC 曲线

ROC-AUC 曲线(接收操作者特征-曲线下面积)有助于分析不同阈值设置下的分类性能。类别的高真阳性率(TPR/灵敏度)描述了该模型在分类该特定类别时表现良好。可以比较各种模型的 ROC-AUC 曲线,具有高 AUC(曲线下面积)的模型被认为表现良好。换句话说,该模型在各种阈值设置下表现得非常好,产生了高 TPR(真阳性率)。

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

PC:作者

分类的成本函数

成本函数通过考虑实际值和预测值来帮助衡量模型的性能。

交叉熵损失

交叉熵损失也称为对数损失。对数损失可以应用于目标是二进制的二进制分类问题,也可以应用于多类分类问题。让我们考虑 C 是目标变量中类的数量。

如果 C = 2(二进制分类),对数损失或二进制交叉熵损失计算如下,

  • 当实际值 y = 0 时,应用[(1-y) * log(1- 𝑦̂)]其中𝑦̂是 y 的预测值
  • 当实际值 y = 1 时,应用[y *log(𝑦̂]]𝑦̂是 y 的预测值

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

PC:作者

曲线图为-y * log(𝑦̂)当 y = 1 时(y 是实际值)

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

PC:作者。用完了德斯莫斯

图为-[(1- y) * log(1- 𝑦̂)]当 y = 0 时

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

PC:作者。用完了德斯莫斯

如果 C > 2(多类分类)log 损失或 多类交叉熵损失 计算如下,

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

PC:作者

多类交叉熵损失是针对单个数据实例定义的,而多类交叉熵误差是针对整组数据实例定义的。

稀疏多类交叉熵损失

稀疏多类交叉熵损失非常类似于多类交叉熵损失,除了不同于多类交叉熵损失的真实标签的表示。

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

PC:作者

在多类交叉熵损失中,真实标签被一热编码,而在稀疏多类交叉熵损失中,真实标签被原样保留,从而减少了计算时间。

多类交叉熵损失中真实标签 y 的表示,

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

PC:作者

多类稀疏交叉熵损失中真实标签 y 的表示,

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

PC:作者

摘要

  • 当数据集不平衡时,可以使用 F1 分数。当一个类的样本数多于另一个类的样本数时,数据集被称为不平衡的。
  • ROC-AUC 曲线使用不同阈值设置下的真阳性率和假阳性率绘制。ROC-AUC 曲线有助于找到分类的最佳阈值。
  • 交叉熵损失可以应用于二元和多类分类问题。
  • 稀疏多类交叉熵损失在计算上比多类交叉熵损失更快。

参考

[1] Jason Brownlee,训练深度学习神经网络时如何选择损失函数

[2] Scikit-learn,接收操作员特征

[3] ML- cheatsheet,损失函数-ML 术语文档

LinkedInTwitter上与我联系!

快乐的机器学习!

谢谢大家!

分析超级碗历史数据集(1967-2020)

原文:https://towardsdatascience.com/analyzing-the-superbowl-history-dataset-1967-2020-fdee01a760c9?source=collection_archive---------33-----------------------

历史超级碗数据的探索性数据分析

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

Jean-Daniel Francoeur 在 Pexels 上拍摄的照片

超级碗是一年一度的比赛,决定了美国国家橄榄球联盟(NFL)的冠军。这是世界上最受关注的年度体育赛事之一,拥有大量的国内观众。平均每年美国有超过 1 亿人收看超级碗比赛。

在本帖中,我们将分析超级碗历史数据集(1967–2020)。我们将为获胜球队、体育场、获胜点数和最有价值球员等信息生成汇总统计数据和数据可视化。我们将使用的数据可以在这里找到。

让我们开始吧。

首先,让我们使用 pandas 导入数据:

import pandas as pd
df = pd.read_csv("superbowl.csv")

接下来,我们可以打印列的列表:

print(df.columns)

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

如你所见,有 10 列。让我们打印前五行:

print(df.head())

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

我们可以看到有几个分类列。让我们定义一个将数据框、列名和限制作为输入的函数。当被调用时,它打印分类值的字典以及它们出现的频率:

def return_counter(data_frame, column_name, limit):
   from collections import Counter    print(dict(Counter(data_frame[column_name].values).most_common(limit)))

让我们将我们的函数应用到最有价值球员(“MVP”)一栏,并将我们的结果限制在五个最常见的值:

return_counter(df, 'MVP', 5)

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

我们看到汤姆·布拉迪拥有最多的 MVP 记录,其次是乔·蒙塔纳。

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

来源

让我们将函数应用于“Stadium”列:

return_counter(df, 'Stadium', 5)

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

路易斯安那州的 Superdome、Rose Bowl 和 Orange Bowl 在数据集中出现了五次。

让我们试试“获胜者”栏,它对应于获胜的团队:

return_counter(df, 'Winner', 5)

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

新英格兰爱国者队和匹兹堡钢人队并列六胜。

我鼓励您将此函数应用于剩余的分类列,如“州”、“城市”和“失败者”。

正如您所看到的,这是一个有用的快速测试,可以查看数据中是否有任何明显的不平衡,这通常是建模时需要处理的一个关键问题。

接下来,从数字列(如“Winner Pts ”,即获胜团队获得的分数)中生成汇总统计数据会很有用。让我们定义一个采用数据框、分类列和数字列的函数。每个类别的数字列的平均值和标准偏差存储在数据框中,并且数据框根据平均值以降序排序。如果您想要快速查看特定类别对于特定数字列是否具有更高或更低的平均值和/或标准偏差值,这将非常有用。

def return_statistics(data_frame, categorical_column, numerical_column):
    mean = []
    std = []
    field = []
    for i in set(list(data_frame[categorical_column].values)):
        new_data = data_frame[data_frame[categorical_column] == i]
        field.append(i)
        mean.append(new_data[numerical_column].mean())
        std.append(new_data[numerical_column].std())
    df = pd.DataFrame({'{}'.format(categorical_column): field, 'mean {}'.format(numerical_column): mean, 'std in {}'.format(numerical_column): std})
    df.sort_values('mean {}'.format(numerical_column), inplace = True, ascending = False)
    df.dropna(inplace = True)
    return df

我们可以查看“获胜者”和“获胜者分数”的汇总统计数据:

stats = return_statistics(df, 'Winner', 'Winner Pts')
print(stats.head(15))

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

旧金山 49 人队的平均“赢家分数”和“赢家分数”的标准差最高。

接下来,我们将使用箱线图来显示基于最小值、最大值、中值、第一个四分位数和第三个四分位数的数值分布。如果您对它们不熟悉,可以看看文章了解 Boxplots

与汇总统计函数类似,此函数采用数据框、分类列和数值列,并根据限制显示最常见类别的箱线图:

def get_boxplot_of_categories(data_frame, categorical_column, numerical_column, limit):
    import seaborn as sns
    from collections import Counter
    keys = []
    for i in dict(Counter(df[categorical_column].values).most_common(limit)):
        keys.append(i)
    print(keys)
    df_new = df[df[categorical_column].isin(keys)]
    sns.set()
    sns.boxplot(x = df_new[categorical_column], y =      df_new[numerical_column])

让我们为 5 个最常见的获胜团队的“获胜者分数”生成箱线图:

get_boxplot_of_categories(df, 'Winner', 'Winner Pts', 5)

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

我们还可以定义一个函数来显示获胜点的时间序列图。首先,让我们将“日期”转换成日期时间对象:

df['Date'] = pd.to_datetime(df['Date'])

接下来,让我们定义一个函数,该函数将数据框和数字列作为输入,并显示“Winner Pts”的时间序列图:

def get_time_series(data_frame, numerical_column):
    import matplotlib.pyplot as plt
    df_new = data_frame
    plt.scatter(df_new['Date'], df_new[numerical_column])
    plt.xlabel('Date')
    plt.ylabel(numerical_column)

让我们用数据帧和“赢家 Pts”调用函数:

get_time_series(df, 'Winner Pts')

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

最后,让我们定义一个函数,它将一个数据框和一个数字列作为输入,并显示一个直方图:

def get_histogram(data_frame, numerical_column):
    df_new = data_frame
    df_new[numerical_column].hist(bins=100)

让我们使用数据框调用函数,并生成优胜点直方图:

get_histogram(df, 'Winner Pts')

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

我就讲到这里,但是请随意处理数据并自己编码。

概括地说,我回顾了几种分析*超级碗历史数据集的方法。*这包括定义生成汇总统计数据的函数,如平均值、标准差和分类值的计数。我们还定义了用箱线图、直方图和时间序列图来可视化数据的函数。我希望这篇文章有趣。这篇文章的代码可以在 GitHub 上找到。感谢您的阅读!

用 R .分析乌克兰战争

原文:https://towardsdatascience.com/analyzing-the-war-in-ukraine-using-r-39d0c3379938?source=collection_archive---------42-----------------------

使用 tidyverse 和地图对冲突进行探索性分析!

2014 年,乌克兰顿涅茨克州和卢甘斯克州的俄罗斯分裂分子宣布独立。自行宣布成立的顿涅茨克和卢甘斯克人民共和国与乌克兰政府之间爆发了冲突。这一冲突非常复杂,涉及无数变数。人们写了关于这场冲突的书籍、文章和各种观点。我很好奇数据显示了什么。

经过一番努力,我偶然发现了人道主义数据交换:https://data.humdata.org/。那里有很多非常有趣的数据。对我来说幸运的是,有一个关于乌克兰冲突的非常好而且相当精细的数据集。数据集中的每一行代表一个动力学事件。数据跨度从 2014 年的亲欧盟示威革命到 2018 年。我将数据读入 R 中,并通过删除一些我不感兴趣的列(我在下面的代码中省略了这一部分)对其进行了修改。我们将从检查 na 的数据开始(确保您加载了 tidyverse!):

# read in the data 
conflict <- read_csv('conflict_data_ukr - Raw.csv')# make.names on the columns
colnames(conflict) <- make.names(colnames(conflict))# check for NA's in the column adm_1
sum(is.na(conflict$adm_1))#119
conflict[is.na(conflict$adm_1),]#   all of the NAs in adm_1 are for the donets basin area which 
#   isn't contained in one oblast.# replace NA's in adm_1 w/ 'Donets Basin Area'
conflict$adm_1 <- conflict$adm_1 %>% replace_na('Donets Basin Area')
any(is.na(conflict)) # FALSE

“adm_1”变量包含事件发生在哪个州的信息(想象一个像美国大县一样的州)。我担心的是那一栏中的 na。第一行代码告诉我那里有 119 个 na。我能够对第二行代码中的数据进行子集划分,并根据“where_coordinates”列中的信息了解到所有 na 都是“Donets Basin Area”中的事件。我将 adm_1 列中的 na 替换为“Donets Basin Area ”,然后重命名了一些列:

# rename some columns 
conflict <- conflict %>% rename(gov.forces = side_a
                                , op.forces = side_b
                                , kia = deaths_a
                                , ekia = deaths_b
                                , civcas = deaths_civilians
                                , region = adm_1)

出于本分析的目的,KIA =乌克兰军队被杀,EKIA =分离势力被杀。其余的变量非常简单。我首先想探究乌克兰在一个事件中损失最多的是什么:

# what was the maximum number of KIA in an event
max(conflict$kia)
[1] 366

哇哦。在一次事件中,政府军损失了 366 名军人。让我们进一步探讨这个问题。

# subset for the information regarding the mass casualty event
conflict[conflict$kia == 366,]

这行代码为我提供了该特定事件的所有数据。事情发生在 2014 年 9 月 2 日,顿涅茨克州的伊洛瓦伊斯克。伊洛瓦伊斯克战役意义重大,因为据称这是俄罗斯正规军首次越过边境参与冲突。继续,我们来看看起亚的分布。

hist(conflict$kia, breaks = 100
     , xlab = "KIA"
     , main = "Ukrainian KIA\n2014-2018")

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

数据分布非常不对称。像伊洛瓦伊斯克战役这种大量死亡的事件正在创造一条向右的长尾。让我们把数据标准化。

# histogram of KIA normalized
hist(log10(conflict$kia)
     , xlab = "Number of KIA (Normalized)"
     , main = "Ukrainian KIA\n2014-2018")

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

我决定采用这个概念,为起亚和 EKIA 绘制密度图:

# initialize the plot space
par(mfrow = c(2,1))
par(bty = 'n')# density plot for kia (Ukrainian Government Forces)
a <- density(log10(conflict$kia))
plot(a
     , xlab = 'Number of Deaths (normalized)'
     , ylab = 'Frequency'
     , main = "Distribution of Ukranian Forces Killed-In-Action per Engagement\n
     2014-2018")
polygon(a, col = '#7E8777', border = "black")# density plot for ekia (Russian Separatist Forces)
b <- density(log10(conflict$ekia))
plot(b
     , xlab = 'Number of Deaths (normalized)'
     , ylab = 'Frequency'
     , main = "Disribution of Enemy Forces Killed-In-Action per Engagement\n
     2014-2018")
polygon(b, col = '#DA291C', border = 'black')

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

这些图表明的是,大多数事件的双方都有一个或更少的伤亡。然而,也有一些导致重大损失的重大交战。这就是为什么我们有长尾巴。

接下来的问题是,战斗集中在哪里?让我们创建一个柱状图来提供一些背景信息:

#----------------------------------------------------------
# barplot for deaths by region
#----------------------------------------------------------
df <- aggregate(conflict$best, list(conflict$region), sum)
df <- as_tibble(df) 
df <- df %>% rename(Region = Group.1
                    , no.ofDeaths = x) 
df <- df %>% arrange(no.ofDeaths)par(mar = c(5,13,5,1), bty = 'n')barplot(df$no.ofDeaths 
        , names.arg = df$Region
        , horiz = T
        , las = 1 
        , col = '#DA291C'
        , border = NA
        , xlab = "Total Number of Deaths"
        , main = 'Deaths by Region in the Ukrainian Conflict\nNote: "Donets Basin Area" includes both Luhansk and Donetsk Oblasts\nYears: 2014-2018')

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

看起来顿涅茨克州是战斗最激烈的地方。然而,目前还不清楚有多少打着“顿涅茨克盆地地区”标签的战斗实际上发生在顿涅茨克州或卢甘斯克州。我认为理解这些数据的更好的方法是用 R!

# load some packages
library(pacman)
p_load(maps, mapproj, rnaturalearth, scales, ggplot2)# load the data
ukr <- read_csv('conflict_data_ukr - Raw.csv')# Calculate area of a circle based on deaths per event
radius <- sqrt( ukr$best/pi )# Plot the map
ykr <- raster::getData('GADM', country = "UKR", level = 1)map(ykr)# add the points
points(ukr$longitude, ukr$latitude
       , cex = rescale(radius, c(0, 12))
       , col = 'red'
       , pch = 21)

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

这样更好,不是吗?圆圈区域表示每个事件的死亡人数(包括 KIA、EKIA 和平民死亡人数)。你可以看到在交战双方多次交战的区域周围形成了同心圆。地图中心附近环绕基辅的圆圈代表亲欧盟示威运动革命。底部附近还有一个小圆圈,代表亲欧盟示威运动革命期间发生在敖德萨的事件。让我们仔细看看顿涅茨克州和卢甘斯克州(俗称顿巴斯)。

# plot the Donbass
map(ykr, namefield = 'NAME_1', region = c("Donets'k", "Luhans'k"))# add the points
points(ukr$longitude, ukr$latitude
       , cex = rescale(radius, c(0, 12))
       , col = 'red'
       , pch = 21)

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

在上图中,顿涅茨克州在左边,卢甘斯克州在右边。如你所见,大部分战斗发生在顿涅茨克或边境。地图上最大的圆圈表示伊洛瓦伊斯克战役,前面提到过。

冲突是社会中令人讨厌的现实,但它产生了一些有趣的数据供探索。希望这篇文章能帮助你找到一些代码,或者对你理解东欧地缘政治有所启发。我很喜欢这篇文章的一些反馈,所以如果你愿意,请留下评论!

分析“倾斜”赢得更多游戏(英雄联盟)

原文:https://towardsdatascience.com/analyzing-tilt-to-win-more-games-league-of-legends-347de832a5b1?source=collection_archive---------23-----------------------

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

来源

“一种精神或情感混乱或沮丧的状态,玩家采用了非最佳策略,通常导致玩家变得过于激进”

—倾斜的定义(维基百科)

倾斜的。扑克玩家中常用的一个术语,尽管它也被更广泛的游戏社区完全采用。据说,它的起源来自机械弹球机,如果玩家试图倾斜机器,它会冻结脚蹼,有时甚至会显示警告:“倾斜”。

现在它被用来形容一个人由于某种极端情绪(通常是愤怒)而做出不理智的行为。在扑克游戏中,这可能是连败后在弱牌上全押。在游戏中,这可能是在敌人在聊天中奚落你之后向他们冲锋。然而,它也可以应用于任何数量的“现实生活”场景。当他们过了糟糕的一天,谁没有对他们所爱的人发过脾气?这是倾斜。当情绪高涨的时候你的行为是不理智的

现在,那些玩过任何竞争性团队游戏的人无疑会成为他们的同伴玩家的倾斜诱导行为的受害者。这一点在热门网游《英雄联盟》中尤其成问题。该游戏既有激烈的形式(激烈的 5 对 5 场比赛)和梯形排名系统,使其成为一种情感的努力。最近我自己经历过(非常不幸的 13 连败),我决定看看是否有任何方法可以在游戏数据中识别它。

注: 所有收集的数据都是使用 Riot Data API,运行超过 10 万场。GitHub:https://GitHub . com/JackWillz/Projects/blob/master/Data % 20 analysis % 20 and % 20 API % 20-% 20 ol % 20 tilt/tilt _ trend . ipynb

我想回答的第一个问题很简单。输了之后,你更有可能输吗?答案并不令人惊讶,如下所示:

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

基于玩家先前游戏结果的胜率。

注: 我稍微调整了一下基线,因为我取样的选手胜率都在平均水平以上。

这意味着最近输了 2 场比赛的玩家(根据图表,2 连败)将有 48.8%的机会赢得下一场比赛。然而,我们不能在这里结案,宣布 tilt 已经被证实。据统计,最近输了 2 场比赛的玩家比最近赢了 2 场比赛的玩家更有可能成为糟糕的玩家!玩家可能没有“倾斜”,他们可能只是比平均水平差。

在这种情况下,我们如何更好地理解 tilt,而不陷入这个将坏玩家与好玩家进行比较的陷阱?为此,我们利用了倾斜是一种暂时情绪状态的事实,这种情绪状态随着时间迅速衰减。有没有对某人发脾气却很快又后悔的经历?这同样适用于这里。

知道了这一点,我们可以看看这些失败玩家的胜率,除了这一次他们在玩下一个游戏之前等待了多长时间。为此,我们研究了排名在“金牌”(前 24%的玩家)的人,他们已经输掉了前 2 场比赛。然后我们发现了他们上一次游戏结束和下一次游戏开始之间的时间差。其结果可以在下面找到:

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

黄金的胜率对玩家的连败进行排名,这取决于他们在玩下一个游戏之前等待的时间。

那些在两连败后采取不休息的人,到目前为止胜率最低!根据我们对 tilt 的了解,我们可以认为,那些带着因失败而积累的情绪包袱参加下一场比赛的人会导致他们在下一场比赛中表现不佳,从而大大影响他们球队的机会。

然而,有趣的是,那些只短暂休息的人不仅胜率有所提高,而且与平均水平(刚刚输了两场比赛的金牌玩家)相比,胜率超过了 3%。有几个理论,我已经为此辩论过,但我更喜欢的是,输了 2 场比赛并休息一段时间的球员既“热身”,又没有情感债务。如果你有任何替代的想法,请让他们被听到!最后,那些长时间休息(平均 3-4 个小时,但可能是几天)的人,他们的胜率会回到接近 2 场比赛输球的平均水平。

关于这个话题,我感兴趣的最后一个问题是,不管玩家的技能等级如何,这种关系是否成立。为了测试这个理论,我对“钻石 I”玩家(前 1%)重新进行了实验。结果出乎意料…

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

Diamond I 的胜率对玩家连败进行排名,取决于他们在玩下一个游戏之前等待的时间。

虽然长时间休息的玩家以同样的方式回归均值,但是“立即”和“短时间休息”之间的关系已经被翻转了!那些排名第一梯队的玩家实际上会发现,如果他们在失败后定期短暂休息,他们的胜率会大幅下降,而立即玩的玩家会发现,与普通玩家相比,他们的胜率会有小幅提高

对此我有两种流行的理论:在这个竞争激烈的环境中(许多玩家每天投入超过 8 个小时),他们已经习惯了处理倾斜,否则,他们永远不会走到这一步。其次,在这个层面上,已经变成了数字游戏。竞争的程度如此之高,以至于真正起作用的是你投入的时间。这个级别的英雄联盟一场比赛平均 27 分钟长。一个不休息的球员比一个输球后坐 20 分钟来恢复的球员一天能挤出更多的比赛。

但是,这些都是理论。我相信有一个与游戏相关的心理行为科学的更大的世界相对来说还没有被开发。如果有什么不同的话,我希望这篇文章能让你简短地思考一下可能性——至少在你准备好面对下一场比赛之前。

你已经看到文章的结尾了!我叫 Jack J,是一名将人工智能应用于竞技游戏和电子竞技的专业数据科学家。我是 iTero 的创始人。GGjung.gg 。你可以在 推特 上关注我,加入 iTero Discord 或者给我发邮件 jack@itero.gg 。下一场见。

最初发表于:https://itero.gg/blog

使用 Wordcloud 分析热门 Kickstarter 活动

原文:https://towardsdatascience.com/analyzing-top-kickstarter-campaigns-with-wordcloud-2541cd3f05c8?source=collection_archive---------52-----------------------

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

照片致谢

自从开始数据科学之旅,我就迷上了文字云。词云(或标签云)是一种独特的数据可视化工具,用于通过词频或意义来探索文本数据。当您有大量的文本数据,并且想要获得分布的基本概念时,这非常方便。

作为一名数据科学家,经过几个月的发展,我终于在上周厌倦了。我想学习如何制作我见过的(但从未忘记的)超级酷的单词云!!!所以,我找到了一个有用的数据营教程,读了一点文档,我准备实践我的新知识。

实践新的可视化类型的第一步是找到适合该可视化的数据集。鉴于我们正在尝试练习一个单词云,我们可能会找到一些包含文本的数据。有许多很好的选择可以实践,比如客户评论、推文或 Youtube 视频字幕,但我在 Kaggle 上找到了一个关于 Kickstarter 项目的数据集,我认为它非常适合这种情况。

import numpy as np
import pandas as pd
from PIL import Image
from wordcloud import WordCloud, STOPWORDSimport matplotlib.pyplot as plt 
%matplotlib inline df = pd.read_csv('ks-projects-201801.csv') 
df.head()

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

根据数据集在 Kaggle 上的文档,usd_pledge_real 和 usd_goal_real 列是由 Fixer.io API 生成的以美元为单位的真实转换,因此我们应该使用它们并删除所有其他与货币相关的列。

此外,因为 Kickstarter 的目的是筹集尽可能多的资金来启动你的业务,所以一个恰当定义成功的栏是承诺给每个活动的资金量。让我们使用 usd _ pledged _ real 列根据承诺金额检索排名前 500 的 Kickstarter 活动。

# Rename columns and drop unneeded ones 
df['usd_pledged'] = df.usd_pledged_real
df['usd_goal'] = df.usd_goal_realdf_ks = df.drop(columns=['goal', 'usd pledged', 'usd_pledged_real', 'usd_goal_real'])# Get the top 50 Kickstarter campaigns by $ pledgeddf_sorted = df_ks.sort_values(by='usd_pledged', ascending=False)
df_top = df_sorted.head(500)

现在,有趣的部分来了。我们可以利用之前导入的 wordcloud 库,构建一个包含 Kickstarter 前 500 名活动名称的 wordcloud。

WordCloud 对象有一个方法。generate()将从一个字符串生成一个 wordcloud。我们可以使用列表理解来构建一个巨大的字符串,其中包含 Kickstarter 活动的所有名称。

请注意,我们还从 wordcloud 库中导入了停用词。这是一组内置的词,通常不会给文本分析增加太多价值(比如 it,they 等)。).我们可以用 stopwords 参数传入这组单词,以确保排除那些不需要的单词。

有关如何正确设置插值参数的更多信息,请查看 matplotlib 的文档,但现在,它被设置为双线性。

# Join all names and separate them with whitespace
text = " ".join(str(name) for name in df_top.name) # Create stopword list:
stopwords = set(STOPWORDS) # Generate a word cloud image
wordcloud = WordCloud(stopwords=stopwords).generate(text)# Display the generated image:
# the matplotlib way:
plt.imshow(wordcloud, interpolation='bilinear')
plt.axis("off")
plt.show()

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

只要几行代码,我们就有了单词云!一张小小的照片,这里有很多东西,我们来做一些改进吧。

让我们把背景改成白色,这样更容易阅读。让我们把最小字体变大一点。最后,让我们排除“第一”和“聪明”这两个词,这样我们就可以看到其他词的出现。

# Create stopword list:
stopwords = set(STOPWORDS)# This time, add in your own words to ignore stopwords.update(["First", "Smart"])# Generate a word cloud image
wordcloud = WordCloud(stopwords=stopwords, background_color="white", min_font_size=8).generate(text)# Display the generated image:
# But make it a little larger this time..
plt.figure(figsize=(9,6))
plt.imshow(wordcloud, interpolation='bilinear')
plt.axis("off")
plt.show()

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

很有意思。以下是我们使用 word cloud 进行分析的一些要点:

  • 每个人都喜欢说自己是第一,和聪明…这似乎很有效,因为他们在这个数据集中做了前 500 个 Kickstarter 活动。
  • 好像和技术有关的战役很多:电动耳机相机3D 打印机等。
  • 这里提到的游戏也比我想象的多…谁知道 Kickstarter 这么有趣?

你已经正式创建了一个单词云!恭喜你!如果您仍然渴望更多的分析,您可以构建更多的词云来研究这些主题:

  • Kickstarter 数据附带了一个类别列,其中包含诗歌和音乐等值。不同类别是否有某些词比较常见?
  • 该数据还有一个包含日期的“已启动”列。旧的活动和新的活动有明显不同的词频吗?

原载于 2020 年 4 月 30 日https://data dreamer . io

在没有 API 的情况下用 Python 分析 Twitter 关系

原文:https://towardsdatascience.com/analyzing-twitter-relationships-in-python-without-an-api-a35b5b502cb?source=collection_archive---------14-----------------------

使用一些著名的 Twitter 账户进行关系分析的简单方法。

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

社交媒体分析是数据科学的热门话题之一。人们喜欢这些分析,并对它们感兴趣,因为每个人都熟悉这个世界。我们大部分时间都花在了推特、Instagram、脸书和其他一些社交媒体应用上。

作为一名数据爱好者,这个话题引起我的注意并不奇怪。然而,访问官方的 Twitter API 是非常具有挑战性的。于是,我搜索了另一种解决方案,找到了 twint 。这是一个 python 库,使你能够在没有 API 访问的情况下废弃 twitter 数据。

在本文中,我将简要介绍如何借助 twint 收集 twitter 数据,并基于一组 Twitter 用户之间的关注和提及来分析一些关系。

初始化 Python 代码

我们需要 twint 库来抓取数据,需要pandas来创建 dataframes,需要 集合 来获取列表中的分组值计数。

import twint
import pandas as pd
from collections import Counter

然后我们开始创建一个包含 twitter 账户的用户列表。我们的分析将包括这些用户的关系。由于代码运行时间较长,我不建议将拥有超过 5K 追随者的用户添加到此列表中。类似地,一个很长的列表可能也会出现同样的问题。

我选择了一些大家都知道的热门 Twitter 用户,让我们的分析更有趣。

users = [
 **'shakira',
    'KimKardashian',
    'rihanna',
    'jtimberlake',
    'KingJames',
    'neymarjr',**
]

跟踪关系分析

让我们从关系分析开始,并为此编写一个名为get _ followers的函数,用用户名向 twint 库发送请求。该函数将返回我们的输入用户关注的用户列表。

def get_followings(username):

    c = twint.Config()
    c.Username = username
    c.Pandas = True

    twint.run.Following(c)
    list_of_followings = twint.storage.panda.Follow_df

    return list_of_followings['following'][username]

使用 get_followings 函数,我们将为用户列表中的每个人获取不同的列表,并将结果存储到一个字典( followings )和一个列表( following_list )。following_list 是所有 following 的联合版本,我们将在下一节使用它来计算最受关注的 Twitter 帐户。

下面的 for 循环创建了这两个变量。有时 Twitter 不响应我们的请求,在这种情况下,我们会得到一个索引错误。对于这种情况,我在代码中添加了一个例外来跳过这些用户。****

followings = {}
following_list = []
for person in users:
    print('#####\nStarting: ' + person + '\n#####')
    try:
        followings[person] = get_followings(person)
        following_list = following_list + followings[person]
    except KeyError:
        print('IndexError')

我们的用户关注最多的是谁?

在获得以下所有列表后,我们可以简单地计算 following_list 变量中最常见的值,以获得用户中最受欢迎的帐户。为了获得最受关注的 10 个账户,我们将使用收藏库中的计数器函数。

Counter(following_list).most_common(10)

该函数的结果如下所示。蕾哈娜似乎被所有其他人追随,在我们的用户群中,她绝对是最受欢迎的一个。

**[('rihanna', 5),
 ('RyanSeacrest', 3),
 ('BarackObama', 3),
 ('Oprah', 3),
 ('TheEllenShow', 3),
 ('kendricklamar', 3),
 ('KDTrey5', 3),
 ('Drake', 3),
 ('Nike', 3),
 ('NBA', 3)]**

遵循用户之间的关系

如果我们想知道我们的用户组中谁在关注谁呢?为了研究这个问题,我编写了一个 for 循环来检查用户中是否有人在另一个人的列表中。因此,它创建了一个列表字典,显示由真和假表示的以下状态。

follow_relations ={}
for following_user in followings.keys():
    follow_relation_list = []
    for followed_user in followings.keys():
        if followed_user in followings[following_user]:
            follow_relation_list.append(True)
        else:
            follow_relation_list.append(False)
    follow_relations[following_user] = follow_relation_list

在下面的代码中,结果字典被转换成一个 pandas 数据帧,以实现更加用户友好的可视化。数据帧的行显示跟随的用户,而列指示被跟随的用户。

following_df = pd.DataFrame.from_dict(follow_relations, orient='index', columns=followings.keys())

您可以在下面看到分析的输出。我们再次确认蕾哈娜在这张表中的受欢迎程度。所有其他人都跟着她。但是,对于金·卡戴珊**,我们不能用类似的方式说话,根据分析,我们的用户群中只有贾斯汀·汀布莱克追随她。**

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

以下关系表

提及次数分析

提及次数是 Twitter 用户之间的另一个强有力的关系指标。下面的函数(get _ note _ count)就是为此而编写的,它返回两个用户之间的单向提及次数。我们应该将提到的用户名放在提词中,在函数中,为了更精确地分离提词,在它的开头添加了一个“ @ ”字符。

def get_mention_count(user, mention_word):

    c = twint.Config()
    c.Username = user
    c.Search = '@' + mention_word
    c.Store_object = True

    twint.run.Search(c)
    tweets = twint.output.tweets_list
    mention_count = len(tweets)
    tweets.clear()

    return mention_count

在分析中,我们将使用两个嵌套的 for 循环来检索每个用户对我们组中所有其他用户的提及次数。因此,我们将得到提 _ 关系字典。

mention_relations = {}
for mentioning_user in users:
    print('#####\nStarting: ' + mentioning_user + '\n#####')
    mention_count_list = []
    for mentioned_user in users:
        mention_count = get_mention_count(mentioning_user, mentioned_user)
        mention_count_list.append(mention_count)
    mention_relations[mentioning_user] = mention_count_list

最后,我们把这本字典转换成一个熊猫的数据框架,它变成了一个可理解的和更容易解释的表格。

mention_df = pd.DataFrame.from_dict(mention_relations, orient='index', columns=mention_relations.keys())

我们可以看到下面提到次数表的输出。同样,行显示提到的用户,列显示提到的用户。对角线值显示了用户提到自己的次数,这些是由转发引起的。如果我们忽略这些值,我们会看到勒布朗·詹姆斯被小组中的每个人提及,而蕾哈娜看起来被除了内马尔之外的每个人提及。另一方面,这个团体中没有人在他们的推文中提到过内马尔。另一个有趣的推论可能是,夏奇拉在她的推文中提到蕾哈娜 52 次,然而蕾哈娜只提到她 7 次。

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

提及次数表

结论

我试着在著名的 Twitter 用户上解释一些基本的社交媒体分析,只是为了好玩,同时也是为了在不复杂的 python 代码的帮助下做好准备。我希望它们对你有所帮助。最后,可以肯定的是,这些分析有待改进,如果您对本文有任何建议或补充,请不要犹豫,与我们分享。

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

使用机器学习分析英国大选结果

原文:https://towardsdatascience.com/analyzing-uk-general-election-results-using-machine-learning-137d130634b1?source=collection_archive---------23-----------------------

英格兰各地选区的聚类和分类。

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

介绍

2019 年 12 月 12 日 22:00,出口民调是英国大选结果的第一个指标。这项民意调查对英格兰、苏格兰和威尔士 144 个选区的 2 万多人进行了调查,准确预测了选举结果。这篇文章使用机器学习来展示英格兰每个选区的选举结果和社会经济条件之间的关系。这是出于对英国地缘政治格局的兴趣,特别是出于进一步了解社会和经济因素如何影响投票方向的愿望。

本文使用 8 个不同的社会经济类别对英格兰 533 个威斯敏斯特议会选区进行聚类和分类(只选择了英格兰选区,因为英国其他民族的数据更少)。相似性传播用于聚类数据,然后随机森林和 AdaBoost 技术用于分类和预测投票方向。

本报告中使用的大部分数据来自下议院网站,除了关于英国退出欧盟公投的数据是由 Hanretty 汇编的估计值(因为英国退出欧盟公投的结果没有按选区统计)。

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

数据

本文中使用的数据和包含代码清单的 Juypter 笔记本可以从这里下载。

  • 房价中位数:该数据记录于 2019 年 3 月,范围在利物浦、沃尔顿的 72,500 英镑至肯辛顿的 1,450,000 英镑之间。
  • 周工资中位数:该数据记录于 2019 年 4 月,范围从莱斯特东部的 420 到温布尔登的 890。
  • 在英国出生的居民比例:该数据记录在 2011 年人口普查中,从布伦特北部的 41%到霍顿和桑德兰南部的 98%不等。
  • 住房使用权:对拥有自己住房的人的百分比的一种衡量。这一数据是在 2011 年人口普查中收集的,从哈克尼南部和肖尔迪奇的 20%到塞夫顿中部的 97%不等。
  • GCSE 成绩:2018 年 GCSE 成绩达到 5 A*到 C 的学生比例已有记录,从 Knowsley 的 38%到 Altrincham 和 Sale West 的 85%不等。
  • 年龄分布:这一类别将选区居民人口划分为 9 个年龄组(0-9 岁、10-19 岁等,直到 80 岁以上),并已作为一个社会指标包括在内。这一数据是在 2011 年人口普查中收集的。
  • 英国退出欧盟立场:对每个选区投票脱离欧盟的居民百分比的估计。这一数据是从 2016 年英国退出欧盟公投结果中推断出来的,范围从哈克尼北部和斯托克纽因顿的 20%到波斯顿和斯开格内斯的 76%不等。

测绘

这些地块是使用 Geopandas 库结合来自 UK-GeoJson 站点的边界形状数据创建的。

使聚集

相似性传播(AP)是一种基于通信的聚类算法,由 Frey 和 Dueck 于 2007 年首次提出。该算法将数据点描述为网络中的一个节点,该节点通过经由图的边彼此发送信号来传达它们的聚类偏好。该通信用于定位最佳范例节点(代表它们自己的集群的最佳数据点)并将最合适的数据点分配给该集群。用于确定信号幅度的主要度量是相似性得分,其被计算为两个数据点之间的负欧几里得平方距离。使用相似性传播,首先识别和标记最小和最离散的聚类。这解释了当你离开伦敦市中心时,从暗到亮的颜色渐变,如图 1 所示。

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

图 1:英格兰选区使用相似性传播聚类成 32 个组。

使用 Davis Bouldin 指数,聚类的最佳数量被确定为 6。新的选区聚类如图 2 所示(使用 K-means)。伦敦市中心形成了自己独特的集群,这在英格兰其他地方是看不到的。这可能是由极高的房价推动的。

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

图 2:英格兰选区使用 K 均值聚类成 6 组。

分类

我用随机森林和 Adaboost 技术预测了每个选区的投票方向。随机森林产生的分类如下图 3 所示。

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

图 3: 2019 选举结果预测 vs 现实使用随机森林。使用 Photoshop 对图像进行色彩校正。

决策树分类器和随机森林在训练数据上始终达到 100%的准确率,在测试数据上达到 80-90%的准确率(当训练 2017 年和 2019 年的选举结果时)。每个属性的预测能力都是从随机森林中提取的,如图 4 所示。引入一个随机变量作为参考。任期被证明提供了关于投票方向的最多信息。对此的一种解释是,在城市里有更多的租房者,城市席位往往被工党赢得(特别是在伦敦)。

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

图 4:分别使用 2017 年选举和 2019 年选举结果的每个属性的预测能力。

AdaBoost 的表现相对较差,经常使用不合逻辑的属性组合来进行糟糕的分类。这是因为 AdaBoost 不能很好地处理外围数据:它会陷入尝试对错误数据点进行分类的循环中。属于众议院议长、绿党和潜在的自由民主党的席位可能会在这里引发问题。

结论

使用相似性传播和 K-means 聚类算法,有可能将英语选区分解成逻辑组,这些逻辑组已被绘制以便于可视化。相似性传播提供了关于哪些选区最相似以及哪些聚类最离散的信息;这最终产生了一种从伦敦市中心向外延伸的颜色渐变,这种渐变基于标签被分配的顺序。

使用随机森林可以提取每个属性的预测能力,并证明它们都为决策过程提供了有意义的贡献。分类的准确率在 80-90%之间,但是除了工党和保守党之外,没有其他席位被预测到。任期被证明是两次选举的主导因素,在 2019 年贡献了大约 19%的预测力。你可以看到 2017 年至 2019 年间英国退出欧盟立场的预测能力有了有趣的增长,这可能是由于工党席位数十年来首次转向保守党,因为他们希望看到英国退出欧盟完成。

参考

[1]汉莱蒂,克里斯。“面积插值和英国的欧盟成员资格公投.”《选举、舆论与政党杂志》27.4(2017):466–483。

[2]弗雷、布伦丹·j 和德尔伯特·杜克。"通过在数据点之间传递消息进行聚类."科学 315.5814(2007):972–976。

分析和可视化亚马逊红移数据—教程

原文:https://towardsdatascience.com/analyzing-visualizing-amazon-redshift-data-tutorial-239aa6443d43?source=collection_archive---------58-----------------------

学习使用 Knowi 分析和可视化亚马逊红移数据

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

活动发起人Unsplash 上的照片

目录

介绍

亚马逊红移是亚马逊基于云的关系数据库管理系统(RBDMS)。像亚马逊的大多数产品一样,亚马逊红移非常受欢迎,这是有原因的:它不仅是目前最快的云数据仓库,而且每年都在变得更快。

在 Knowi,我们为分析和报告提供与亚马逊红移的广泛原生集成。这使我们的用户能够不受任何限制地利用 Redshift 的速度和可扩展性,并快速分析来自 Redshift 的数据,形成有价值的见解。如果您有兴趣学习如何使用 Knowi 来分析来自 Amazon Redshift 的数据,那么您来对地方了。

设置您的 Amazon 红移数据源

登录到你的 Knowi 试用账户后,你要做的第一件事就是连接到 Amazon Redshift 数据源,并确认你的连接成功。这是怎么回事:

1.在屏幕左侧的面板上找到“数据源”并点击它。

2.前往“数据仓库”,点击亚马逊红移。

3.我们不需要改变这里的任何参数;我会自动为我们输入所有信息。只需点击屏幕底部的“测试连接”。

4.确认连接成功后,单击“保存”

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

您的数据源现在已经设置好了。干得好!

从数据源中查询数据

您的数据源现在已经设置好了,这意味着是时候开始查询数据了。下面是如何做到这一点:

1.保存数据源后,您应该会在页面顶部收到一个警告,提示“Datasource Added”。配置查询。点击单词查询。(否则,您可以返回到屏幕左侧的面板,转到“数据源”下方,然后单击“查询”。然后从右上角选择“新查询+”。)

2.在屏幕左上方的“报告名称*”中为您的报告命名。我们将在这里分析一个电子邮件活动,所以我们称之为“电子邮件活动”

3.在查询构建器中,单击“表”栏内部。向下滚动到“public.demo_sent”并点击它。这将自动设置一个红移查询,返回该表中的数据。

4.前往屏幕的左下方,点击蓝色的“预览”按钮,预览数据。您应该看到电子邮件活动的结果,其中包括各种数据,如发送、打开和点击的电子邮件数量,以及消息类型和客户。

5.查看完数据后,滚动到屏幕右下角,点击绿色的“保存并立即运行”按钮。

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

一旦您的查询成功完成,Knowi 会自动将您的查询结果保存为虚拟数据集,然后将该查询的结果作为数据集存储在其弹性数据仓库中。每次运行查询时,我都会这样做。

分析和可视化您的数据

尽管你花了一点时间查看你的数据,但是你不太可能从它的格式中学到任何东西。利用我们的数据,我们可以发现很多事情,但假设我们必须回答一个紧迫的问题:发送给某些客户的电子邮件有更高的转化率吗?Knowi 允许我们有效地回答这个问题,然后通过以下步骤可视化我们的结果:

1.前往屏幕左侧面板的顶部,点击“仪表板”单击橙色加号图标并命名您的仪表板。我们称之为“电子邮件可视化”

2.回到面板,就在“仪表板”下面,点击“小部件”选择您刚刚创建的“电子邮件活动”小部件,并将其拖到您的控制面板上。

3.现在,你看到的可视化只是一个数据网格。我们将把它改成对眼睛稍微好一点的东西,但是首先我们必须添加我们正在寻找的度量。为此,请滚动到小部件的右上角。单击 3 点图标,然后向下滚动到“分析”并单击它。

4.前往屏幕的左上角,找到“+添加功能”我们要创建的函数非常简单:它叫做“转化率”,计算方法是将“转化率”除以“发送量”为了进行计算,点击“+添加函数”,然后将“名称”设置为转换率,将“操作”设置为(转换率/发送数)*100。

5.现在,我们看到的只是每个电子邮件活动的转换率。我们希望看到的是按客户分组的所有电子邮件活动的转换率,我们还希望我们的数据按转换率排序。首先,我们需要将“customer”栏从屏幕左侧拖动到“Grouping/Dimensions:”框中,然后放开。

6.现在,我们只需将新的“转换率”指标从“字段/指标:”拖动到“排序方式:”并将方向改为降序,以便从最高转换率到最低转换率对数据进行排序。如你所见,脸书邮件的转化率刚刚超过 1%,而网飞邮件的转化率不到 0.5%。

7.现在是时候想象一切了。回到屏幕顶部,点击“可视化”将可视化类型从“数据网格”更改为“列”

8.现在你可以看到每个客户的电子邮件转化率排名。前往屏幕的右上角,点击看起来像两张纸的“克隆”图标。将此命名为“电子邮件活动—转化率”,然后单击橙色的“添加到仪表板”按钮。

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

就这样,您将原始数据转化为包含有价值信息的可视化数据。脸书的转换率大约是网飞的两倍半,这一事实可能会在未来的决策中得到考虑。

向可视化添加明细

改进我们的可视化的下一步是通过添加钻取使它更具交互性和可导航性。向下钻取是 Knowi 中的一个强大功能,允许用户只需点击一下鼠标,就可以更深入地钻取原始数据的过滤部分。下面是我们如何向小部件添加明细:

1.单击新部件右上角的 3 点图标,向下滚动到“明细”并单击它。

2.将您的钻取类型设置为“Widget”,设置为在单击“Customer”时钻取“Email Campaign”,并在可选的钻取过滤器中设置 customer = customer。单击明细弹出窗口右下角的橙色“保存”按钮。

3.点击转化率最高的客户脸书进行测试。如您所见,这将返回脸书作为客户的所有活动。然后回到你最初的可视化,回到你的部件的右上角,点击那个角中间的左箭头图标。

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

使用基于搜索的分析查询您的数据

您的仪表板已经设置好,这意味着您已经做好充分准备,可以使用基于搜索的分析来查询您的数据。这意味着您可以与任何讲英语的人分享您的仪表板和数据,即使他们不熟悉 Knowi。以下是如何使用基于搜索的分析来查询您的数据:

1.前往你原来的“电子邮件活动”部件的右上角,点击 3 点图标。向下滚动并点击“分析”

2.假设您想要按月监控电子邮件活动,以查看不同月份的情况是否有所不同。为了做到这一点,在你的屏幕顶部的搜索栏中输入“发送总量,打开总量,点击总量,按月转换总量”,然后点击回车。Knowi 的自然语言处理会很快给你提供你想要的东西。

3.现在是时候可视化这些数据了。回到“可视化”,将可视化类型设置为“区域”这将显示我们发送的电子邮件总数,以及每月的转换总数。转化率如此之低,以至于我们肉眼很难看到数字的任何变化,但这没关系。

4.回到右上角,再次点击“克隆”图标。将此小部件命名为“发送和转换—区域”,克隆它,然后将其添加到您的仪表板。

5.最后,回到你的仪表板。将新的“电子邮件活动—区域可视化”小部件拖到仪表板的顶部,这将使原来的“电子邮件活动”小部件位于底部。

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

这些数据传达了另一个有价值的见解:这些电子邮件活动收到的打开和点击数量很低,他们发送的每封电子邮件的转换数量也非常低。虽然这些数字每月都保持在较低水平,但它们似乎确实随着发送的电子邮件总数的增加而增加。

同样重要的是要记住,我们不需要丰富的编码知识或 Knowi 经验来做我们刚刚做的事情。这里的低使用门槛使得任何好奇的英语使用者都可以使用 Knowi 的仪表盘。

摘要

总之,我们连接到一个 Amazon Redshift 数据源,并对我们的新数据源进行查询。这将我们的查询结果存储在 Knowi 的弹性数据仓库中。然后,我们分析并可视化我们的数据,并向我们的可视化添加钻取信息,使用户能够钻取原始数据中他们希望了解更多信息的过滤部分。最后,我们使用基于搜索的分析来回答另一个问题,并将我们的答案可视化。

分析和可视化 Couchbase 数据—教程

原文:https://towardsdatascience.com/analyzing-visualizing-couchbase-data-tutorial-15e518b98881?source=collection_archive---------47-----------------------

使用 Knowi 连接到 Couchbase,运行查询,分析和可视化您的查询结果,并通过基于搜索的分析提出问题。

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

科琳·库兹在 Unsplash 上的照片

目录

介绍

Couchbase 是一个强大的 NoSQL 数据库,使企业能够存储和查询大量非结构化数据。Couchbase 的可伸缩性、灵活的数据模型和性能比率使其成为当今市场上最好的 NoSQL 数据库之一。

目前,大多数现有的商业智能和分析平台需要定制编码或繁琐的 ETL 过程,才能使用来自 Couchbase 的非结构化 NoSQL 数据。幸运的是, Knowi 是为数不多的提供 Couchbase 原生集成的商业智能平台之一,这使得我们的用户能够利用 Couchbase 的优势。

在本教程中,您将学习如何使用 Knowi 来分析和可视化来自 Couchbase 的数据。

连接到沙发底座

一旦你登录到你的 Knowi 试用账户,你需要按照以下步骤连接到一个 Couchbase 数据源:

  1. 前往屏幕左侧的面板,选择“数据源”
  2. 转到 NoSQL 数据源的右上角,选择 Couchbase。
  3. 选择屏幕底部的“测试连接”。
  4. 确保连接成功后,选择“保存”

作者图片

查询 Couchbase 数据

当您保存数据源时,您应该会在屏幕顶部收到一个警告,提示“Datasource Added”。配置查询。按照以下步骤开始设置您的第一个查询:

  1. 点击“查询”开始当您这样做时,您将被带到一个查询构建器,并且屏幕顶部的警告将变为“获取存储桶”这意味着 Knowi 正在从您刚刚连接到的 Couchbase 数据源中自动索引“桶”(或数据集)。这将需要几秒钟的时间来完成,所以在您等待的时候,请将您的报告命名为“Queens Bakeries”(如果报告名称没有泄露,我们将分析纽约皇后区面包店的数据。)
  2. 当您的警报变为“已检索存储桶”后,悬停在“存储桶/数据集”上。使用查询生成器部分来发现和构建报告/查询。点击工具条内部,您将看到存储在您的 Couchbase 数据库中的每个存储桶。选择“restaurant”并知道我将自动生成 N1QL 查询,该查询查询餐馆数据集的前 10,000 行中的所有列。
  3. 选择屏幕左下角的“预览”。向下滚动以查看预览。如您所见,“地址”和“成绩”列都在嵌套的 JSON 中。我们的目标是分析地址字段中的特定信息,所以我们需要扩展它;Cloud9QL,Knowi 的 SQL 风格语法,让这变得轻而易举。只需向上滚动到您最初索引您的存储桶的区域,并在“Cloud9QL Query”下,键入“select * expand(address)”并再次预览您的查询。

作者图片

这一次,您会注意到预览数据已经扩展为包括几个新列:zipcode、coord、street 和 building。更重要的是,因为新的“coord”字段包含这些餐馆的坐标,Knowi 自动将您的预览图表可视化类型转换为地理聚类/自定义地图可视化。

使用基于搜索的分析完成您的查询

我们的查询还没有完成;我们甚至还没有拯救它,更不用说回到皇后区的面包店了,这是我们最初的目标。为了做这些事情,我们将从 Knowi 的基于搜索的分析功能中获得一点帮助,该功能允许我们用简单的英语查询我们的数据,并实时接收结果。为了使用基于搜索的分析来完成您的查询,请遵循以下步骤:

  1. 前往预览数据顶部的搜索栏,键入“显示皇后区的每家面包店”如您所见,Knowi 将自动过滤数据,只包含 cuisine 等于 Bakery,borough 等于 Queens 的行。
  2. 向下滚动到预览图表。如您所见,数据现在包括了更小的餐馆子集,而且只包括皇后区内的餐馆。这是我们从一开始的目标。选择屏幕右下角的“保存并立即运行”以保存此查询。

运行查询后,Knowi 将结果作为数据集存储在其弹性数据仓库中。每次成功运行查询时,Knowi 都会这样做。

分析和可视化您的数据

除了将查询结果作为数据集存储在 Knowi 的弹性数据仓库中,Knowi 还会在您运行查询时将预览图表可视化保存为一个小部件。现在,您的第一个微件已经创建完毕,是时候通过创建一个仪表盘来放置它,并通过以下步骤进一步可视化数据集中的数据了:

  1. 前往屏幕左侧面板的顶部,选择“仪表板”选择“+”图标创建一个新仪表板,将其命名为“Queens Bakery Dashboard”,然后单击“OK”
  2. 回到屏幕左侧的面板,在“仪表板”的正下方,点击“Widgets”在这里,您将看到刚刚创建的“Queens Bakeries”小部件。将它拖到您的仪表板上进行添加。
  3. 现在,您已经将微件添加到了仪表板中,您可以进一步分析您的数据并创建新的可视化效果。单击小部件右上角的 elipses 图标,然后选择“分析”这将引导您找到驱动您的小部件的原始数据。
  4. 如果你看看屏幕左侧的栏,你会注意到在“坐标”和“成绩”旁边有一个加号图标。这意味着这些字段仍然是嵌套的 JSON 格式,因为我们在最初的查询中没有扩展它们。没关系;我们也可以在这里扩展它们。为此,请单击等级旁边的加号图标,然后单击[*]旁边的加号图标。
  5. 我们感兴趣的字段是“等级”字段。我们知道每个面包店都被给定了一个等级,我们想分析这些等级的分布,以找出每个等级的真正含义;饼状图应该可以做到这一点。为了设置您的饼图,将“等级”拖到“分组/维度:”上,然后将“等级”拖到“字段/指标:”上,并将“操作”从“无”更改为“计数”这将显示每个等级在我们的数据中出现的次数。
  6. 如你所见,我们有 A 级、B 级、C 级,还有……P 级和 Z 级?还有一些被标为“尚未分级”P 级和 Z 级是相当罕见的,我们不知道它们意味着什么,所以我们最好摆脱它们。为此,请拖动您的“分数[*]。将“指标”改为“排序依据”,并将方向改为“降序”如你所见,最常见的成绩是 A、B 和 c。因为这是我们唯一感兴趣的 3 个成绩,所以请转到“Limit:”并输入 3。这将把我们的数据限制在 3 个最常见的等级。
  7. 现在,转向“可视化”,将“可视化类型”改为“饼图”我们不希望保存和覆盖我们的地理聚类图,而是希望我们的饼图与其并排放置,因此,请前往屏幕的右上角,单击克隆图标,该图标类似于两张叠放在一起的纸。将您的小部件命名为“皇后面包店-等级分布”,然后单击“克隆”然后,点按“添加到仪表板”

作者图片

正如你从我们的饼状图中看到的,皇后区的面包店获得 A 级非常普遍,如果没有,他们几乎肯定会获得 B 级。这种等级的 C 级在这里就像在罗德学者的成绩单上一样罕见,所以我们可以得出结论,C 级可能是一个危险信号,而不是表明质量差,而不是平均或平庸的质量。这是非常有用的信息。

摘要

回顾一下,我们通过连接到 Couchbase 数据库并使用 Knowi 的基于搜索的分析功能查询我们数据库中的餐馆数据集来开始本教程,以使查询更容易。成功运行该查询将查询结果作为数据集存储在 Knowi 的弹性数据仓库中,并将预览图表作为小部件存储在 Knowi 帐户中。然后,我们创建了一个新的仪表板来存储我们的新部件,并创建了另一个部件来进一步分析我们的数据集并回答一个重要的问题。

探索 WhatsApp 数据

原文:https://towardsdatascience.com/analyzing-whatsapp-chats-with-python-20d62ce7fe2d?source=collection_archive---------16-----------------------

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

来自 Unsplash莫兰的照片

使用 Python 分析您的 WhatsApp 聊天数据

分析数据可能会很吸引人,很有趣,并且能够给出关于某个主题的非常有趣的见解。当这些数据与我们或我们的环境联系在一起时,分析这些数据就变得更加有趣,因为这些信息总是近在眼前,但却从来没有从分析的角度来看待过。

为此,我们通过社交网络与他人的互动是一个很好的数据来源。如今,我们每天都使用社交网络和互联网来工作或休闲。事实证明,这些方法真的很有帮助,让一些过程变得更有效率,甚至缓解了异地恋。它们影响了我们交流的方式,甚至重塑了我们的社交行为。社交网络注册,现在比以往任何时候都更需要我们如何什么交流。

在这方面, WhatsApp 已经成为最广泛使用的与他人聊天的应用之一【1】。在这篇文章中,我将尝试展示我们如何使用 python 从 WhatsApp 聊天中轻松提取和分析数据。

概述

这篇文章的概要如下

  • 从手机中导出 WhatsApp 聊天
  • 使用 python 库 whatstk
  • 结论

从手机中导出 WhatsApp 聊天

从手机导出聊天内容的过程相当简单。但是,它会根据您的移动操作系统而变化(参见下面的剪辑)。

导出聊天时,确保选择无媒体的选项。一旦生成,您可以通过邮件发送给自己,并下载/保存到您的计算机上。

Android 上,可能会导出几个文件。我们只对文本文件感兴趣(即txt扩展名文件)。在 iOS 上,聊天被导出为zip。一旦你把它下载到你的电脑上,解压它以获得txt

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

左: Android 9,WhatsApp 2.20.123(自带源码,录屏);右:iOS 12,WhatsApp 2.20.31(自带源码,好友 塞尔吉的 )

使用 python 库 whatstk

whatstk 是一个 GPLv3 许可的 python 库,它是我帮助开发的,提供了探索、分析和可视化 WhatsApp 聊天的工具。它支持多种聊天格式,并分别使用 pandasplotly 来处理和可视化数据。

写这篇帖子的时候,最后一个稳定版本是 0.4.1 。要安装它,只需使用画中画。

$ pip install whatstk

要求至少 Python 3.7。

加载聊天

我们将从使用类WhatsAppChat及其方法from_source将聊天加载到 python 开始。对于这个演示,我将使用我使用库工具随机生成的聊天。以下是摘录:

[2019-04-16 02:09] +1 123 456 789: Et labore proident laboris do labore ex. 
[2019-04-16 03:01] Mary: Reprehenderit id aute consectetur aliquip nostrud culpa, fugiat ex deserunt magna, nostrud officia id aliquip in fugiat. 🇩🇰
[2019-04-17 12:56] John: Amet magna officia ullamco pariatur ipsum cupidatat, laborum sint nostrud adipiscing sit. ✈
[2019-04-17 13:30] Mary: Cillum aute et cupidatat ipsum, occaecat lorem sint tempor ullamco elit. 🏊🏻
[2019-04-17 15:09] John: Eiusmod irure laboris dolore anim, velit velit proident qui commodo. 
[2019-04-17 17:55] Mary: Aute sed quis deserunt, veniam non veniam qui ipsum velit, aliqua sunt eu incididunt incididunt duis. 🤨

在您的情况下,更改参数filepath的值,使其指向您导出的聊天。聊天被自动解析,加载为数据帧并存储为类属性df

注意:如果您无法以这种方式加载您的聊天,您可能需要使用 hformat 输入参数手动指定您的聊天标题的格式。对于我们的聊天,应该是这样的:

首次数据概述

首先,我们将获得一些关于聊天活动的基本信息。

我们可以获得第一个和最后一个发送消息的时间戳,这给了我们一个初始的时间上下文。接下来,我们获取每个用户发送的消息数量,以及聊天活动期间每天发送的消息量。为了完成这个,我们利用了 pandas 提供的工具,特别是它的 groupby 方法。

我们注意到记录的聊天开始于 2019 年 4 月 16 日,结束于 2020 年 6 月 13 日。此外,朱塞佩和 2019 年 7 月 1 日似乎相当活跃!

谁说的最多?

现在,让我们仔细看看每个用户发送的消息数量。为此,我们使用类FigureBuilder,它简化了生成和显示基于绘图的可视化的过程。

我们使用累积计数,这意味着对于给定的一天 D ,我们对之前每个用户的所有干预进行计数。

虽然一个用户发送了很多消息,但这并不一定意味着他们发送了更多的字符。为了找出谁发送了最多的字符,我们可以使用函数的参数msg_len=False

用户消息长度

我们现在将看看每个用户发送的消息的长度,因为一些用户倾向于发送更少但更长的消息,而另一些用户发送几条短消息(那就是我)。

Mary 似乎有更高的中位数,这可能表明与聊天中的其他用户相比,他们倾向于发送更长的消息。使用平均值可能会产生误导,因为它会受到离群值(即长消息)的严重影响

用户交互

最后,最后一幅图展示了用户之间是如何互动的。具体来说,它显示了一个矩阵,该矩阵计算了从用户 A 发送到用户b的响应数量。库做出假设消息 n 总是对前一消息 n-1 的响应。虽然这可能与事实相去甚远,但它仍然设法捕捉到了某种现实。

在这个随机生成的聊天中,我们观察到最大的消息流是从 Giuseppe 到+1 123 456 789。

结论

在这篇文章中,我们看到了如何用 python 加载 WhatsApp 聊天作为数据帧,并使用 plotly 可视化相关见解。可视化效果是使用工具生成的,但是,一旦聊天被加载,可能性是无限的。

我个人觉得这真的很有趣,因为每次我探索和分析 WhatsApp 聊天时,我最终都会使用一个独特的、动态的、可访问的数据集。

你可以在这里查看这篇文章的代码。

变更日志

  • 2020 年 7 月 30 日:文章发表。whatstk版本 v0.3.1
  • 2021 年 5 月 27 日:修复断开的链接。whatstk版本 0.4.1

参考

[1] Birgit Bucher, WhatsApp,微信和 Facebook Messenger 应用——全球 Messenger 使用、渗透和统计,Messenger People 2020,博客文章

分析#WhenTrumpIsOutOfOffice 推文

原文:https://towardsdatascience.com/analyzing-whentrumpisoutofoffice-tweets-7169b3e5ca35?source=collection_archive---------45-----------------------

R 中清理和分析 tweets 的分步指南

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

达伦·霍尔斯特德Unsplash 上拍摄的照片

随着美国下届总统大选的临近,我想知道人们对被提名人的看法。现任总统会继续留在白宫,还是我们会看到一位不那么愤怒的推特咆哮的新美国总统?

获取数据集

我用 R 包rtweet下载了标签为# WhenTrumpIsOutOfOffice 在 2020 年 3 月发的推文。结果,我找到了 6000 多条带有标签的推文。

library(rtweet)**# create token named "twitter_token"**
twitter_token <- create_token(
  app = appname,
  consumer_key = consumer_key,
  consumer_secret = consumer_secret,
  access_token = access_token,
  access_secret = access_secret)**#download tweets into csv files**
tweets <- search_tweets(
  "#WhenTrumpIsOutOfOffice", n = 18000, include_rts = FALSE)df <- apply(tweets,2,as.character)
write.csv(df,"csv file path" )**#read the csv file**
text <- read.csv("csv file path", stringsAsFactors = FALSE)

清理数据集

像任何其他数据科学项目一样,数据清理是必不可少的。在本文中,我从 tweet 文本中删除了 URL、标签和常用的停用词。

**#data pre-processing**
remove_reg <- "&amp;|&lt;|&gt;"
text <- text %>%
  mutate(text = str_remove_all(text, remove_reg)) %>%
  mutate(text = tolower(text)) %>%
  mutate(text = str_replace_all(text, regex("@\\w+"),"" )) %>%
  mutate(text = str_replace_all(text, regex("http\\w+"),"" )) %>%
  mutate(text = str_replace_all(text, regex("://t.co/\\w+"),"" ))%>%
  mutate(text = str_replace_all(text, regex("<\\w+"),"" )) %>%
  mutate(text = str_replace_all(text, regex("/+[a-zA-Z0-9<>]+"),"")) %>%
  mutate(text = str_replace_all(text, regex("fa[a-zA-Z0-9+<>]+"),"" )) %>%
  mutate(text = str_replace_all(text, regex("#[a-zA-Z0-9<>]+"),"" ))

接下来,我使用 R 包udpipe来注释我们下载的 tweets。

library(udpipe)**#download and load the pre-trained models**
udmodel <- udpipe_download_model(language = "english")
udmodel <- udpipe_load_model(file = udmodel$file_model)**#annotate the data frame with uipipe model**
tidy_text <- udpipe_annotate(udmodel, x = text$text)
tidy_text <- as.data.frame(tidy_text)

注释完数据集后,我们可以从数据集中删除停用词。

**#Remove stop words**
my_stop_words <- tibble(
  word = c("#whentrumpisoutofoffice", "[@realdonaldtrump](http://twitter.com/realdonaldtrump)", "trump","ill"))**#Prepare stop words tibble**
all_stop_words <- stop_words %>%
  bind_rows(my_stop_words)tidy_tweets <- text %>%
  anti_join(all_stop_words, by = "word")**#To check how many words removed after stop word anti join, deleted** 
tibble(
  total_words = nrow(text),
  after_cleanup = nrow(tidy_tweets))

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

数据清理前后的字数

数据分析

在本文中,您将发现四种不同的文本挖掘技术应用于推文:

1\. Most frequent words in the tweets
2\. Keyword extraction
3\. Sentiment analysis
4\. Word association network graphs

转发次数最多的文本

两条推文的转发量超过了一千条:

当特朗普下台时,这些无法无天、腐败、肆无忌惮的白痴将和他一起消失。 — 1216 转推

我会不由自主地被投票让糟糕的政客下台所吸引。我刚刚开始投票;它就像一块磁铁。投票吧。我都不等了。当它是民主的时候,他们让你做它。# when trumpisoutofoffice***—1101 转发***

单字和双字的词频

流行的文本挖掘技术之一是找出一个单词在一个或多个文档中出现的频率。在这篇文章中,我们将看看单字和双字的词频。虽然单个词让我们对文档中最常用的词有所了解,但双词通常能给读者更好的洞察力。

从下面的条形图中,我们可以做出一些假设:

  • 特朗普卸任时,将是 2025 年 1 月
  • 当特朗普不在办公室时,人们会去参加派对(“派对”在推文中出现了 165 次)

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

词频条形图

**#Unigram bar chart**
tidy_tweets %>%
  count(word, sort = TRUE) %>%
  mutate(word = reorder(word, n)) %>%
  filter(n > 150) %>%
  ggplot(aes(word, n)) +
  geom_col(fill = "red") +
  xlab(NULL) +
  coord_flip() +
  ggtitle("#WhenTrumpIsOutOfOffice - 1-Word Frequency") +
  geom_text(aes(x = word, label = n), vjust = 0, hjust = -0.3, size = 4)**#Bigram bar chart (showing codes for the bar chart only)** ...
bigrams_united %>%
  count(bigram, sort = TRUE) %>%
  mutate(bigram = reorder(bigram, n)) %>%
  filter(n > 20) %>%
  ggplot(aes(bigram, n)) +
  geom_col(fill = "blue") +
  xlab(NULL) +
  coord_flip() +
  ggtitle("#WhenTrumpIsOutOfOffice - 2-Word Frequency") +
  geom_text(aes(x = bigram, label = n), vjust = 0, hjust = -0.3, size = 4)

除了找出词频,我们还可以使用预先构建的算法/包快速提取关键词。在我们的例子中,我使用 RAKE 方法(快速自动关键字提取)提取关键字,该方法在 udpipe R 包中可用。

根据下面的 RAKE 关键字条形图,我们可以得出以下结论:

  • 得分最高的两个关键词是“白宫”和“新总统”。人们担心特朗普是否会继续他第二个任期,或者被新总统取代。
  • 与词频的结果类似,人们计划在特朗普离任时举办最大的派对
  • 有趣的是,“更好的地方”也在 RAKE 关键字列表的顶部

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

RAKE 方法确定的关键字条形图

**#Keywords identified by RAKE method bar chart**
stats <- keywords_rake(x = tidy_text, term = "lemma", group = "doc_id", 
                       relevant = tidy_text$upos %in% c("NOUN", "ADJ"))
stats$key <- factor(stats$keyword, levels = rev(stats$keyword))stats %>%
  **#filter data**
  filter(freq > 10 & ngram > 1) %>%
  **# set value for x, y, and fill**
  ggplot(aes(x = reorder(keyword, rake), y =  rake  )) +
  **# show in bars**
  geom_col(fill = "red") +
  **# flip the bars to be horizontal**
  coord_flip() +
  **# show value labe**l
  geom_text(aes(label = round(rake, digits = 2), vjust = 0, hjust = -0.3 )) +
  **# change y-axis name**
  xlab("keywords")+
  **# add title**
  ggtitle("Keywords identified by RAKE method") +
  **# hide legend**
  theme(legend.position = "none")

另一个有趣的文本挖掘技术是给每个单词一个语法标记,称为词性标记(POS)。在这种情况下,我们指定从 tweets 中提取名词短语。

POS 标记条形图的一些要点:

  • 当特朗普不在办公室时,与乔·拜登相比,迈克·彭斯/彭斯总统是被频繁提及的短语
  • 当特朗普离开办公室时,人们松了一口气

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

由词类标签识别的关键字—简单名词短语条形图

**#Keywords identified by POS tags - Simple noun phrases bar chart**
tidy_text$phrase_tag <- as_phrasemachine(tidy_text$upos, type = "upos")
stats <- keywords_phrases(x = tidy_text$phrase_tag, term = tolower(tidy_text$token), 
                          pattern =  "(A|N)*N(P+D*(A|N)*N)*", 
                          is_regex = TRUE, detailed = FALSE)
stats <- subset(stats, ngram > 1 & freq > 100)
stats$key <- factor(stats$keyword, levels = rev(stats$keyword))stats %>%
 **#data**
  #filter(freq > 100 & ngram > 1  ) %>%
 **# set value for x, y, and fill**
  ggplot(aes(x = reorder(keyword, freq), y =  freq  )) +
 **# show in bars**
  geom_col(fill = "red") +
 **# flip the bars to be horizontal**
  coord_flip() +
 **# show value label**
  geom_text(aes(label = freq, vjust = 0, hjust = -0.3 )) +
 **# change y-axis name**
  xlab("keywords")+
 **# add title**
  ggtitle("Keywords identified by POS tags - Simple noun phrases") +
 **# hide legend**
  theme(legend.position = "none")

情感分析

情感分析是自然语言处理(NLP)中的一个领域,它试图识别文本数据中的情感。舆情分析可以让我们快速了解公众对特定话题或个人的情绪。因此,Twitter 是文本挖掘的绝佳数据源,在那里你可以找到大量公开表达的观点。

#WhenTrumpIsOutOfOffice 的总体喜好度

使用“NRC”词典,我们可以将单词标记为 8 种基本情绪(信任、期待、恐惧等)。)和两种情绪(正面和负面)。

在我们的例子中,我们看到推文中正面和负面词汇的分布几乎相等。请注意“信任”在其他情绪中所占的比例最高,而“惊讶”所占的比例最少。在下一节中,我们将详细了解与情感和情绪相关的词汇。

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

情感排名列表

**#Sentiment ranking list**
nrc_words <- tidy_tweets %>%
  inner_join(get_sentiments("nrc"), by = "word")**#Rank of sentiments**
sentiments_rank <- nrc_words %>%
  group_by(sentiment) %>%
  tally %>%
  arrange(desc(n))**#Find percentage**
sentiments_rank %>%
  mutate(percent = (n/8169)*100)

我们也可以用饼状图的形式来显示情感排名:

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

按情感分类的词频饼图

**#Word frequency pie chart categorized by sentiments**
sentiments_rank_clean <- sentiments_rank %>%
  filter(sentiment != "positive") %>%
  filter(sentiment != "negative")**# Create bar chart first**
bp<- ggplot(sentiments_rank_clean, aes(x=reorder(sentiment, -n), y=n, fill=sentiment))+
  geom_bar(width = 1, stat = "identity")**#Turn bar chart into a pie chart** pie <- bp + coord_polar("x", start=0) +
  ggtitle("#WhenTrumpIsOutOfOffice - Sentiment pie chart") +
  xlab("Word frequency - Sentiment")

基于情感的词频

让我们看看出现在“信任”类别中的单词,它的词频最高。请注意,“总统”这个词出现了 400 多次。

其他有趣的见解:

  • “地狱”一词是愤怒、恐惧和悲伤情绪类别的首选。
  • “终于”这个词是另一个排在厌恶、喜悦和惊讶榜首的词。
  • 如果你仔细看看负面情绪下面的单词,你会发现大多数单词都与仇恨、监狱等有关。而不是与悲伤或失望相关的词语。

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

基于情绪的词频

**#Word frequencies based on emotions**
nrc_words %>%
 **# Count by word and sentiment**
  count(word, sentiment) %>%
 **# Group by sentiment**
  group_by(sentiment) %>%
 **# Take the top 10 words for each sentiment**
  top_n(10) %>%
  ungroup() %>%
  mutate(word = reorder(word, n)) %>%
 **# Set up the plot with aes()**
  ggplot(aes(word, n, fill = sentiment)) +
  geom_col(show.legend = FALSE) +
  facet_wrap(~ sentiment, scales = "free") +
  coord_flip() +
  ggtitle("Word frequency based on emotion")

阳性词云

我们还可以提取与积极和消极情绪相关的单词,并将它们绘制成单词云。

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

标签# WhenTrumpIsOutOfOffice 的肯定性词云

**#Positivity word cloud for the hashtag: #WhenTrumpIsOutOfOffice**
positivity_wordcloud <- tidy_tweets %>%
  inner_join(get_sentiments("bing"), by = c("word" = "word")) %>%
  count(word, sentiment, sort = TRUE) %>%
  acast(word ~ sentiment, value.var = "n", fill = 0) %>%
  comparison.cloud(colors = c( "#A32D39","#177255"),  title.size = 1.8,
                   max.words = 50,scale=c(2,0.7))

#WhenTrumpIsOutOfOffice 的词关联图

最后,我们还可以看到一条 tweet 和整个 tweet 文档中的单词是如何相互关联的。

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

#WhenTrumpIsOutOfOffice 的词联想网络图

左边的网络图标题为“句内共现”,显示了在一个句子中经常一起使用的短语。在网络图中,节点代表年度字母中使用的单词,边(链接)的阴影反映每个单词之间的紧密程度。如果术语关系密切,边缘的色调就越暗。两对单词在图表中脱颖而出,这是“长期”和“利润少”的单词组合。

至于右边的网络图,该图向我们显示了在一个文档中彼此“相邻”的单词。在这个图表中,我们可以看到“Pence”和“female/ woman”与单词“president”密切相关

**#Cooccurrences within sentence network graph**
**#how many times nouns and adjectives are used in the same sentence**
cooc <- cooccurrence(x = subset(tidy_text, upos %in% c("NOUN", "ADJ")), 
                     term = "lemma", 
                     group = c("doc_id", "paragraph_id", "sentence_id"))library(igraph)
library(ggraph)
library(ggplot2)wordnetwork <- head(cooc, 50)
wordnetwork <- graph_from_data_frame(wordnetwork)
ggraph(wordnetwork, layout = "fr") +
  geom_edge_link(aes(edge_alpha = cooc), edge_colour = "red") +
  geom_node_point(color = "red", size = 1) +
  geom_node_text(aes(label = name), col = "blue", size = 5, repel = TRUE) +
  theme_graph(base_family = "Arial") +
  theme(legend.position = "none") +
  labs(title = "Cooccurrences within sentence", subtitle = "Nouns & Adjective")**#Words following one another network graph**
cooc <- cooccurrence(tidy_text$lemma, relevant = tidy_text$upos %in% c("NOUN", "ADJ"), skipgram = 1)
dev.off()
head(cooc)
wordnetwork <- head(cooc, 50)
wordnetwork <- graph_from_data_frame(wordnetwork)
ggraph(wordnetwork, layout = "fr") +
  geom_edge_link(aes( edge_alpha = cooc),edge_colour = "blue") +
  geom_node_point(color = "red", size = 1) +
  geom_node_text(aes(label = name), col = "red", size = 5,  repel = TRUE) +
  theme_graph(base_family = "Arial") +
  labs(title = "Words following one another", subtitle = "Nouns & Adjective") +
  theme(legend.position = "none")

结论

总的来说,我们已经导出了几个关键词,从整体上探索了单词与#WhenTrumpIsOutOfOffice 的关系,并能够做出以下假设:

  • 人们担心特朗普卸任后,谁将成为下一任美国总统。总统会继续他的第二个任期,还是他的副总统会取代他?或者我们最终会看到这个国家的第一位女总统吗?
  • 总的来说,积极情绪与解脱和庆祝有关,而消极情绪与伤害和“坐牢”有关。

用 Python 分析世界股票指数的表现

原文:https://towardsdatascience.com/analyzing-world-stock-indices-performance-in-python-610df6a578f?source=collection_archive---------8-----------------------

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

马库斯·斯皮斯克在 Unsplash 上的照片

来自《走向数据科学》编辑的提示: 虽然我们允许独立作者根据我们的 规则和指导方针 发表文章,但我们并不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语

股票指数是选定公司的列表,其平均价格(或加权平均)反映了股票市场。股票指数也可以反映它们所涵盖的某个行业或地区。它们也经常被称为衡量基金业绩的基准。与当前价格相比,股票指数更重要的部分是某个确定时刻的表现或价格变化,无论是前一天还是前三个月。

本文的后半部分将介绍如何用 Python 评估股票指数的表现。

如何获取数据

与股票指数相关的数据可以从 Yahoo!金融。在 Python 中,有一个流行的模块可以更容易地从 Yahoo!金融。如果它还没有安装,您可以通过输入这段代码,然后导入所需的库/模块进行处理,将它安装到您的 Jupyter 笔记本中。

那么,我们如何获取股票数据呢?因为这篇文章是分析世界主要指数的表现,下一步要做的是从 Yahoo!财经网站。

现在,这是从网站上摘下的列表的标题/开头内容:

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

我们可以看到,对于每个股票指数,每行都有名称和符号。这些符号对于检索数据非常重要。现在,是时候为这些股票指数收集历史数据了。

为了收集每个股票指数的历史数据,首先,我们需要用 symbol 的参数调用 Ticker 模块。例如,如果我们想获得标准普尔 500 的历史数据,我们可以键入:

我们还需要定义数据检索的周期。应该获取日数据还是周数据?必须在“周期”参数中输入。还必须定义开始和结束日期。

在这里,将从 2020 年 1 月 1 日开始每天(“1d”)检索数据,直到 2020 年 9 月 30 日。参数中指定的结束日期将不包括在检索到的数据中(因此,只检索到前一天)

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

S&P 历史股票数据—左:数据的头/开始,右:数据的尾/结束

现在是时候收集所有股指的历史数据了。

获取股票指数的历史数据

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

世界主要股票指数历史数据—左:数据的开头/开头,右:数据的结尾/结尾

一些预处理和数据分析

在前面的部分中,我们已经成功收集了从 2010 年 1 月到 2020 年 9 月 30 日的世界主要股票指数的历史股票数据。现在,是时候为分析做一些预处理了。

我想做的第一步是按地区对每个指数进行分类。以下是我对该地区的定义:

区域索引

现在,为该区域创建一个新列。

def getRegion(ticker):
    for k in region_idx.keys():
        if ticker in region_idx[k]:
            return k
msi['region']= msi.ticker.apply(lambda x: getRegion(x))

自 2010 年初以来的价格变化

由于股票价格是以不同的货币表示的,因此要想全面了解业绩,最好以相同的单位或指标来查看。现在,让我们来看看这些指数自 2010 年 1 月 4 日以来十年间的价格变化。变化将以百分比(%)表示。价格变化使用当天的收盘价(“收盘”)。

在上面的代码块中,定义了一个新函数来计算价格变化。然后,对于主数据集中的每一行,调用该函数来输出价格变化。

现在,为了简化流程,让我们将数据集转换为 tickers 作为列,将行作为每个日期的价格变化。

现在,价格变化的新数据框架将如下所示:

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

每个股票指数的价格变动至 2010 年 1 月 4 日

是时候绘制这些价格变化了。对于这一部分,地块将在区域中。

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

基于 2010 年 1 月 4 日的价格变化

从上面的图中可以看出,自 2016 年以来,美国的股票指数增长迅速。自 2010 年以来,纳斯达克股票价格已经上涨了 5 倍。其他美国股票指数,如标准普尔 500、罗素 2000 指数和道琼斯 30 指数也上涨了股价,但表现不如纳斯达克。

其他地区的一些指数价格也上涨了 1-2.5 倍。日经 225 指数(日本)、S&P/新西兰 50 指数(新西兰)、S&P BSE SENSEX 指数(印度)和德国 DAX 指数(德国)是各自地区指数中最赚钱的股票指数(如果你自 2010 年 1 月以来以某种方式投资了它们或一些反映它们的基金)。

我们也不能不提所有这些股票指数都受到了新冠肺炎的影响。它们都在 2020 年初左右显著下降,但总体而言,大多数都在此后不断攀升。

短期至长期价格变化/回报

当我们谈论股票时,通常我们会将当前价格与前几个月或前几年的历史价格进行比较。对于这一部分,我们将分析短期到长期的价格变化。

为了清楚和详细,我们比较的是同一天的数据,而不是之前的数据。所以,2020 年 9 月 30 日的 6M(六个月)是指 2020 年 9 月 30 日前 6 个月的那一天,也就是 2020 年 3 月 30 日。同一天的 1Y(一年)表示 2019 年 9 月 30 日,以此类推。

首先,我们将数据集划分到 2020 年 9 月 30 日。

现在,要得到历史价格,有点棘手。我们想要引用的日期(过去的日期)可能不是工作日。除此之外,每个国家的工作日也不尽相同。因此,为了解决这个问题,我们选择过去日期之前的最后一个工作日。

现在,让我们来看看之前一些决定性时刻的价格变化。

让我们画出这些股票指数的价格变化/回报。

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

世界主要股票指数的短期至长期回报/价格变化

参照上面的图表,所有主要股票指数在 6 个月的时间里都表现良好(价格上涨)。另一方面,在其他时期,这些指数的表现参差不齐。10 年来,大多数股票指数都是盈利的,除了 STI 指数(但只是略有下降)。

总之,参考相同的图,一般来说,最持续盈利的股票指数是:

  • 标准普尔 500(美国)
  • 道琼斯 300 指数(美国)
  • 纳斯达克(美国)
  • 日经 225(日本)
  • 深证成分指数(中国)
  • S&P/新西兰 50 总指数(新西兰)
  • TSEC 加权指数(台湾)

请检查以下链接中的代码以供进一步参考:

[## 库存/库存指数分析

此时您不能执行该操作。您已使用另一个标签页或窗口登录。您已在另一个选项卡中注销,或者…

github.com](https://github.com/intandeay/StockIndicesAnalysis)

用 Python 和 Foursquare API 分析全球美食

原文:https://towardsdatascience.com/analyzing-worldwide-cuisines-with-python-and-foursquare-api-e63455c14246?source=collection_archive---------34-----------------------

分析世界上最大的城市最受欢迎的美食

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

照片由瑞秋·帕克Unsplash

世界上有很多著名的菜系,像中国菜、日本菜、墨西哥菜、西班牙菜……很明显,墨西哥是品尝墨西哥菜的最佳地点,泰国是品尝泰国菜的最佳地点,等等,但是去这么多国家品尝每一种不同的菜系是非常乏味的。然而,在世界上的每一个大城市,你都可以找到许多国际餐馆,在那里你可以尝试新的美食。但是体验会足够好吗?

今天,我将与你分享我最近参加的一个数据科学课程的最终项目,在那里我创建了一个 Jupyter 笔记本,用于使用 Foursquare API 探索纽约、东京、香港、悉尼、巴塞罗那、巴黎、莫斯科、布宜诺斯艾利斯和墨西哥 DF 的城市,并猜猜哪个城市最适合尝试每种美食

定义数据

对于这个项目,将使用 Foursquare API 。作为用户,您需要一个免费的开发人员帐户,以便获得认证您的 HTTP 请求的凭证。对于上面提到的每个城市,我们将一个接一个地为每种国际美食的餐馆请求 API,并将结果存储在一个Pandasdata framedata frame中,以便稍后处理它们并执行一些有趣的分析。

  • 待探索城市 : 纽约、东京、香港、悉尼、巴塞罗那、巴黎、莫斯科、布宜诺斯艾利斯、墨西哥 DF
  • 要查询的美食(列表摘自 Foursquare API 文档 ): 阿富汗、非洲、美国、缅甸、柬埔寨、中国、菲律宾、喜马拉雅、印度尼西亚、日本、韩国、马来、蒙古、泰国、西藏、越南、澳大利亚、奥地利、孟加拉、比利时、加勒比海、高加索、捷克、荷兰、白俄罗斯、波斯尼亚、保加利亚、罗马尼亚、鞑靼、英语、法语、德语、希腊、夏威夷、匈牙利、印度、意大利、萨尔瓦多、阿根廷、巴西、巴西

在开始使用 API 之前,需要提取一些信息,比如每种美食的categoryId,或者每个探索城市的当地美食。首先,场馆类别的完整列表可在网站 https://developer . four square . com/docs/build-with four square/categories/获得。从这里,我们将手动提取food下对应于国家美食的类别(西班牙、印度、泰国)…),以便能够只通过国籍来过滤餐馆,而不是其他不相关的标准,如素食主义者、清真、汉堡店…

对于上面提到的每个城市,我们将询问每个菜系的餐馆的 API:https://api.foursquare.com/v2/venues/explore?&near={city}&categoryId={category_id}。对于每个城市和菜系,餐馆的数量(['response']['totalResults'])将保存在一个 熊猫数据框 中。

所以直到现在,我们的笔记本看起来像这样:

检索数据

我们已经知道我们想要获得什么数据,以及在哪里和如何获得它。然后,下一步是编写一个循环,向 Foursquare API 询问每个城市中每种定义的美食有多少家餐馆,并将其存储到 Pandas 数据帧中。

转换数据

在生成的数据帧中,每一行将代表特定菜系和城市的餐馆数量,因此我们将有 NxM 行,其中 N 是定义的菜系数量, M 是城市数量。

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

下载数据的数据帧

这种格式不适合我们的需要,所以我们不得不将它转换成一个新的数据框架,其中每行代表一个城市,每列代表该城市中每种菜肴的餐馆百分比。转换将包括执行一次性编码,按城市对结果进行分组,最后按行对结果进行规范化。

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

转换后的数据帧

分析数据

现在,数据已经准备好进行分析,让我们定义四个洞察,并看看如何获得它们并在图中可视化它们:

  • 每个城市的十大美食
  • 各种美食的热门城市
  • 各城市本地美食的受欢迎程度
  • 世界上最受欢迎的美食

在展示结果之前,我想先观察一下。在这个项目中,我们将与 Foursquare 中的 65 种不同类型的美食合作。由于此处显示的结果是百分比(超过 100),在一个公平的划分中,1.54%对应于每种菜肴。我认为这是一个重要的澄清,因为如果没有它,某些城市的某些菜肴 20%的百分比可能看起来不算多,但实际上这是一个非常高的百分比。

每个城市的十大美食

对于每个城市,我们将绘制一个条形图,显示 10 种最受欢迎的美食,按照该城市餐馆的百分比排序。每个城市的当地美食将用红色标出。

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

每个城市十大美食的评选结果

在大多数城市,当地美食是赢家。然而,在一些地方,比如巴塞罗那或布宜诺斯艾利斯,当地美食和第二受欢迎的美食之间的差异比在巴黎或纽约要大得多。

在一些城市,我们可以看到最受欢迎的美食是如何来自邻近国家的:例如,在墨西哥,美国餐馆非常受欢迎;在香港,泰国菜和越南菜似乎也很受欢迎,或者在悉尼,来自中国、日本、越南或韩国等东亚国家的食物非常有名。然而,纽约和巴塞罗那的情况不同,纽约第一名和第十名之间的差距不到 3%,巴塞罗那排在西班牙菜和意大利菜之后,接下来的三种最受欢迎的美食是日本菜、中国菜和墨西哥菜,这些国家离西欧很远。

各种美食的热门城市

或许你可以在东京找到最好的寿司或者在巴塞罗那找到最好的玉米饼,但是看看上面的结果,看起来本地美食并不总是最受欢迎的。现在出现的问题和之前正好相反,每种美食排名靠前的城市是哪些。在这里,我们将为所分析城市的每种当地美食绘制一个条形图,对于每种美食,我们将看到在哪里可以找到该美食的更多餐厅。

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

每种美食最受欢迎城市的结果

显而易见,从分析的城市来看,拥有更多美式餐厅的城市是纽约、日本、东京等等。然而,令人惊讶的是,它并不总是这样。

  • 中国、澳大利亚、西班牙、俄罗斯、阿根廷和墨西哥菜肴在各自的城市比在世界其他地方更受欢迎。澳大利亚人和俄罗斯人的差异尤其大。
  • 美国、日本和法国的菜肴在一些外国城市更受欢迎,比如墨西哥城或布宜诺斯艾利斯,而不是在他们国家的首都。

每个城市当地美食的受欢迎程度

正如我们之前看到的,在一些城市,当地美食并不是最受欢迎的。在这里,我们将检查每个被分析城市的当地美食有多受欢迎。同样,通过条形图,我们可以看到每个城市本地美食餐厅的百分比。

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

当地美食在每个城市的受欢迎程度

从这个情节来看,似乎很明显,在巴塞罗那,布宜诺斯艾利斯,墨西哥 DF,或者香港,当地的美食真的很受欢迎,而在纽约或悉尼这样的城市,美食种类更丰富。

世界上最受欢迎的美食

前面的观察结果是否意味着西班牙、阿根廷、中国和墨西哥菜肴是世界上最受喜爱和最受欢迎的?在最后一部分,我们将在条形图中绘制每种美食的平均百分比,以检查全球前 10 大美食(基于 9 个分析的城市)。

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

全球各种美食的平均百分比结果

看起来世界上最受欢迎的菜系是中国、日本、法国、意大利和西班牙。我们看到香港的中国菜或巴塞罗那的西班牙菜非常受欢迎,而在巴黎或东京,当地菜肴的受欢迎程度与外国菜肴相当接近。

排名第一(中国,8%)和第十(越南,4%)的最受欢迎的菜肴之间没有太大的区别。从这前 10 名中,中国、日本、法国、西班牙、美国和墨西哥是一些被分析城市的地方美食。当我们分析每个城市最受欢迎的美食时,我们可以看到,对于巴塞罗那(西班牙)、中国香港、法国巴黎、美国纽约和墨西哥 DF,最受欢迎的美食是当地美食,而对于东京,日本料理排在第二位,非常接近第一位(意大利)。

意大利美食似乎很受欢迎,但我们没有分析任何一个意大利城市,所以我们无法判断它在国内是否也如此受欢迎。

未来建议

这个项目的结果非常有趣,尤其是对那些对旅游和美食感兴趣的人来说。然而,为了做更深入的研究,应该探索更多的城市。将一些意大利城市,如罗马、费伦泽或那不勒斯,以及伊斯坦布尔、曼谷和河内添加到列表中会非常有趣,因为意大利、土耳其、泰国和越南美食非常受欢迎,这样就有可能检查它们在各自的城市是否也受欢迎。

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

我们绝对应该包括一座意大利城市——照片由里卡多·戈麦斯·安吉尔拍摄

对于顶级美食,根据这个项目的结果是中国、日本、法国、意大利和西班牙,这将是一个好主意包括每个国家的更多城市。例如,在西班牙,巴塞罗那代表了该国 11%的人口,因此添加像马德里、巴伦西亚、毕尔巴鄂、塞维利亚或圣地亚哥德孔波斯特拉这样的城市不仅会提供该国更好的样本,而且还包括不同种类的西班牙美食,如加泰罗尼亚、巴斯克或加利西亚美食。

另一个建议是考虑餐馆的评级,因为这里所有的结果来自于场地的数量,而不是它们的质量。Foursquare API 提供了对场馆评级的访问,即使这会使 API 查询循环慢很多。

当然,我的 GitHub 库里有完整的笔记本。

参考

异常检测:检测异常值的技术

原文:https://towardsdatascience.com/anamoly-detection-techniques-to-detect-outliers-fea92047a222?source=collection_archive---------31-----------------------

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

阿里·哈坚Unsplash 上的照片

异常检测是对罕见项目、事件或观察结果的识别,这些项目、事件或观察结果通过与大多数数据显著不同而引起怀疑。通常,异常项目会转化为某种问题,如信用卡欺诈、网络入侵、医疗诊断、系统健康监控。

异常检测基于两个基本前提

  • 数据中很少出现异常。
  • 他们的特征明显不同于正常情况。

异常检测技术

四分位数间距(IQR)

识别数据中不规则性的最简单方法是标记偏离分布的常见统计属性的数据点,包括平均值、中值、众数和四分位数。

最流行的方法之一是四分位数间距(IQR)。 IQR 是统计学中的一个概念,通过将数据集分成四分位数来衡量统计离差和数据可变性。

简而言之,任何数据集或任何一组观察值都根据数据的值以及它们与整个数据集的比较情况被划分为四个定义的区间。四分位数将数据分为三个点和四个区间。

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

图片来源:维基百科

四分位距(IQR)很重要,因为它用于定义异常值。它是第三个四分位数和第一个四分位数的差值(IQR = Q3 -Q1)。在这种情况下,异常值被定义为低于(Q1 1.5 倍 IQR)或高于(Q3+1.5 倍 IQR)的观测值

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

图片来源:维基百科

履行

np.percentile是 Python 中的烘焙功能

q75, q25 = np.percentile(x, [75 ,25]) iqr = q75 - q25

缺点

IQR 技术在以下情况下不起作用

  1. 该模式基于季节性。这涉及到更复杂的方法,例如将数据分解成多个趋势,以确定季节性的变化。

2.随着恶意对手不断调整自己,异常或正常的定义可能会频繁改变

基于聚类的异常检测

聚类是无监督学习领域中最流行的概念之一。潜在的前提是相似的数据点倾向于属于相似的组或聚类,这是由它们与局部质心的距离决定的。

K-means 是一种广泛使用的聚类算法。它创建了“k”个相似的数据点聚类。不属于这些组的数据实例可能会被标记为异常。其他聚类算法,如层次聚类和数据库扫描,也可以用来检测异常值。

K-means 算法的工作方式如下:

  1. 指定簇的数量 K
  2. 通过首先改组数据集,然后为质心随机选择 K 个数据点来初始化质心,而无需替换。
  3. 计算质心和数据点之间的距离。
  4. 继续迭代,直到质心没有变化。也就是说,数据点到聚类的分配没有改变。

履行

  1. 初始化随机质心

你从三个(我们决定 K 为 3)随机点(以(x,y)的形式)开始这个过程。这些点被称为质心,这只是一个用来表示中心的花哨名称。我们先把这三个点命名为 **C1、**和 C3 ,这样你以后就可以参考了。

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

K-Means 中的步骤 1:随机质心

2。计算质心和数据点之间的距离

接下来,测量数据点与这三个随机选择的点之间的距离。一个非常流行的距离测量函数的选择,在本例中,是

简而言之,如果 2D 空间上有 n 个点(如上图所示),并且它们的坐标由(x_i,y_i)表示,那么该空间上任意两点( (x1,y1)(x2,y2) )之间的欧几里德距离由下式给出:

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

假设 C1、C2、C3 的坐标分别为— (-1,4)(-0.2,1.5)(2,2.5) 。现在让我们写几行 Python 代码,它将计算数据点和这些随机选择的质心之间的欧几里德距离。我们从初始化质心开始。

# Initialize the centroids
c1 = (-1, 4)
c2 = (-0.2, 1.5)
c3 = (2, 2.5)

接下来,我们编写一个小的辅助函数来计算数据点和质心之间的欧几里德距离。

# A helper function to calculate the Euclidean distance between the data points and the centroidsdef calculate_distance(centroid, X, Y):
    distances = []

    # Unpack the x and y coordinates of the centroid
    c_x, c_y = centroid

    # Iterate over the data points and calculate the distance using the           # given formula
    for x, y in list(zip(X, Y)):
        root_diff_x = (x - c_x) ** 2
        root_diff_y = (y - c_y) ** 2
        distance = np.sqrt(root_diff_x + root_diff_y)
        distances.append(distance)

    return distances

我们现在可以将该函数应用于数据点,并相应地分配结果。

# Calculate the distance and assign them to the DataFrame accordingly
data['C1_Distance'] = calculate_distance(c1, data.X_value, data.Y_value)
data['C2_Distance'] = calculate_distance(c2, data.X_value, data.Y_value)
data['C3_Distance'] = calculate_distance(c3, data.X_value, data.Y_value)# Preview the data
print(data.head())

3。比较、分配、平均和重复

这基本上是 K-Means 聚类算法的最后一步。一旦你有了数据点和质心之间的距离,你就可以比较这些距离并取最小的一个。特定数据点到质心的距离最小,该质心被指定为该特定数据点的聚类。

让我们以编程的方式来做这件事。

# Get the minimum distance centroids
    data['Cluster'] = data[['C1_Distance', 'C2_Distance', 'C3_Distance']].apply(np.argmin, axis =1)

# Map the centroids accordingly and rename them
    data['Cluster'] = data['Cluster'].map({'C1_Distance': 'C1', 'C2_Distance': 'C2', 'C3_Distance': 'C3'})

# Get a preview of the data
    print(data.head(10))

现在最有趣的部分来了,*通过确定数据点坐标的平均值来更新质心*(这些数据点现在应该属于某个质心)。因此得名K-意为**。平均值计算看起来是这样的:**

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

K-Means 中的均值更新(n 表示属于一个聚类的数据点的数量)

下面几行代码可以帮您做到这一点:

# Calculate the coordinates of the new centroid from cluster 1
x_new_centroid1 = data[data['Cluster']=='C1']['X_value'].mean()
y_new_centroid1 = data[data['Cluster']=='C1']['Y_value'].mean()# Calculate the coordinates of the new centroid from cluster 2
x_new_centroid2 = data[data['Cluster']=='C3']['X_value'].mean()
y_new_centroid2 = data[data['Cluster']=='C3']['Y_value'].mean()# Print the coordinates of the new centroids
print('Centroid 1 ({}, {})'.format(x_new_centroid1, y_new_centroid1))
print('Centroid 2 ({}, {})'.format(x_new_centroid2, y_new_centroid2))

重复这个过程,直到质心的坐标不再更新。

缺点

K-means 算法是一种流行的算法,被广泛应用于图像压缩、文档分类等领域。K-mean 的目标是将数据点分组到不同的非重叠子组中。当集群具有一种球形形状时,它做得非常好。然而,当团簇的几何形状偏离球形时,它会受到影响。此外,它也不会从数据中学习聚类数,而是需要预先定义。

隔离森林

隔离森林是一种无监督学习算法,属于集成决策树家族。这种方法不同于所有以前的方法。所有以前的方法都是试图找到数据的正常区域,然后将这个定义区域之外的任何东西识别为异常值或异常值。这种方法的工作原理不同。它通过给每个数据点分配一个分数来明确隔离异常,而不是描绘和构建正常点和区域。它利用了这样一个事实,即异常是少数数据点,并且它们具有与正常情况下非常不同的属性值。

隔离森林通过随机选择一个特征,然后随机选择所选特征的最大值和最小值之间的分割值来“隔离”观察值。

由于递归分割可以用树结构表示,分离样本所需的分裂次数等于从根节点到终止节点的路径长度。

这种路径长度在这种随机树的森林中平均,是常态的度量和我们的决策函数。

随机分区会为异常产生明显更短的路径。因此,当随机树的森林共同产生特定样本的较短路径长度时,它们极有可能是异常。

这种算法在处理非常高维的数据集时非常有效,并且被证明是一种非常有效的异常检测方法。

这篇论文涵盖了隔离林如何工作的全部细节。

履行

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

**import** **numpy** **as** **np**
**import** **matplotlib.pyplot** **as** **plt**
**from** **sklearn.ensemble** **import** [IsolationForest](https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.IsolationForest.html#sklearn.ensemble.IsolationForest)rng = np.random.RandomState(42)*# Generate train data*
X = 0.3 * rng.randn(100, 2)
X_train = [np.r_](https://docs.scipy.org/doc/numpy/reference/generated/numpy.r_.html#numpy.r_)[X + 2, X - 2]
*# Generate some regular novel observations*
X = 0.3 * rng.randn(20, 2)
X_test = [np.r_](https://docs.scipy.org/doc/numpy/reference/generated/numpy.r_.html#numpy.r_)[X + 2, X - 2]
*# Generate some abnormal novel observations*
X_outliers = rng.uniform(low=-4, high=4, size=(20, 2))*# fit the model*
clf = [IsolationForest](https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.IsolationForest.html#sklearn.ensemble.IsolationForest)(max_samples=100, random_state=rng)
clf.fit(X_train)
y_pred_train = clf.predict(X_train)
y_pred_test = clf.predict(X_test)
y_pred_outliers = clf.predict(X_outliers)*# plot the line, the samples, and the nearest vectors to the plane*
xx, yy = [np.meshgrid](https://docs.scipy.org/doc/numpy/reference/generated/numpy.meshgrid.html#numpy.meshgrid)([np.linspace](https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html#numpy.linspace)(-5, 5, 50), [np.linspace](https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html#numpy.linspace)(-5, 5, 50))
Z = clf.decision_function([np.c_](https://docs.scipy.org/doc/numpy/reference/generated/numpy.c_.html#numpy.c_)[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)[plt.title](https://matplotlib.org/api/_as_gen/matplotlib.pyplot.title.html#matplotlib.pyplot.title)("IsolationForest")
[plt.contourf](https://matplotlib.org/api/_as_gen/matplotlib.pyplot.contourf.html#matplotlib.pyplot.contourf)(xx, yy, Z, cmap=plt.cm.Blues_r)b1 = [plt.scatter](https://matplotlib.org/api/_as_gen/matplotlib.pyplot.scatter.html#matplotlib.pyplot.scatter)(X_train[:, 0], X_train[:, 1], c='white',
                 s=20, edgecolor='k')
b2 = [plt.scatter](https://matplotlib.org/api/_as_gen/matplotlib.pyplot.scatter.html#matplotlib.pyplot.scatter)(X_test[:, 0], X_test[:, 1], c='green',
                 s=20, edgecolor='k')
c = [plt.scatter](https://matplotlib.org/api/_as_gen/matplotlib.pyplot.scatter.html#matplotlib.pyplot.scatter)(X_outliers[:, 0], X_outliers[:, 1], c='red',
                s=20, edgecolor='k')
[plt.axis](https://matplotlib.org/api/_as_gen/matplotlib.pyplot.axis.html#matplotlib.pyplot.axis)('tight')
[plt.xlim](https://matplotlib.org/api/_as_gen/matplotlib.pyplot.xlim.html#matplotlib.pyplot.xlim)((-5, 5))
[plt.ylim](https://matplotlib.org/api/_as_gen/matplotlib.pyplot.ylim.html#matplotlib.pyplot.ylim)((-5, 5))
[plt.legend](https://matplotlib.org/api/_as_gen/matplotlib.pyplot.legend.html#matplotlib.pyplot.legend)([b1, b2, c],
           ["training observations",
            "new regular observations", "new abnormal observations"],
           loc="upper left")
[plt.show](https://matplotlib.org/api/_as_gen/matplotlib.pyplot.show.html#matplotlib.pyplot.show)()

资料来源:scikit-learn.org

结论

这篇文章概述了检测数据异常的不同技术。它的范围从使用简单的统计方法,如标准差,到无监督的学习算法,如隔离森林。每种方法都有其优点和缺点。例如,四分位间距(IQR)不适用于季节模式,K 均值聚类擅长将数据分组到不同的非重叠子组中。当集群具有一种球形形状时,它做得非常好。隔离森林提供了一种反向方法来检测异常。它利用了这样一个事实,即异常是少数数据点,并且它们具有与正常情况下非常不同的属性值。作为一个好的实践者,了解算法/方法背后的假设是很好的,这样你就会对每种方法的优缺点有一个很好的想法。这将有助于您决定何时以及在何种情况下使用每种方法。

起锚!更多你希望知道的 Python 正则表达式概念

原文:https://towardsdatascience.com/anchors-away-more-python-regular-expressions-you-wish-you-knew-8a7780ac54e9?source=collection_archive---------32-----------------------

教程| Python |正则表达式(Regex)

使用 Python 中的高级正则表达式工具处理文本的秘密

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

作者图片

所以你已经知道了 Python 中正则表达式的基础。像如何使用字符集、元字符、量词和捕获组这样的东西是基本的构建模块,但是你是一个超级用户,永远不会满足于仅仅是基础。你的文本争论问题比你希望用这些工具解决的要复杂得多。幸运的是,Python 中有更多的正则表达式概念需要学习。这是更多文本辩论工具的锚!

不确定基本的?查看我关于 Python 中正则表达式(regex)构建块的文章。

[## Python 正则表达式的简明介绍

正则表达式是数据科学家对付非结构化文本最强大的武器

towardsdatascience.com](/a-gentle-introduction-to-regular-expressions-with-python-4f3fce46dcb4)

(正文)起锚了!

在我们开始 SS 正则表达式之前,我们需要讨论锚。更具体地说,文本锚。文本锚表示在字符串的开头或结尾查找匹配。在 Python 中,有两种类型的锚点:

  • ^:匹配字符串开头的以下正则表达式
  • $:匹配字符串末尾的前一个正则表达式

提醒一下,要在 Python 中使用 regex,需要导入re模块。在尝试新的正则表达式主题(比如锚点)时,re.findall()函数特别有用。它将返回一个包含字符串中匹配项实际值的向量的列表。开始之前,请确保加载了re模块。

import re

起锚,^起锚

要起航,我们必须在旅行开始时起锚。当处理文本数据时,您可能需要匹配一个正则表达式模式,但前提是它出现在字符串中的第一项。为此,我们还使用了一个锚点,具体来说就是^

为了演示,我们的目标是找到单词“the”,但前提是它出现在字符串的开头。

anchor = 'The ship set sail on the ocean'
anchor_n = 'Ships set sail on the ocean to go places'

anchor开始,当我们使用^锚查找“the”时,我们只返回了它的一个实例。

anchor01 = re.findall('^[Tt]he', anchor)
print(anchor01)['The']

我们知道这是第一个实例,因为字符串开头的“the”是大写的。现在用anchor_n,不返回任何结果。正则表达式通常匹配句子中的“The ”,但是使用^定位符时,它只检查句子的开头。

anchor02 = re.findall('^[Tt]he', anchor_n)
print(anchor02)[]

抛锚,$

在我们的正则表达式之旅结束时,我们需要放下锚。有时,只有当正则表达式出现在字符串末尾时,才需要匹配它。这是通过$锚完成的。

让我们再来看一下anchor字符串,这次是在字符串的末尾寻找“海洋”。我们会有一个结果,“海洋。”

anchor03 = re.findall('ocean$', anchor)
print(anchor03)['ocean']

同样,如果我们查看anchor_n,这次使用$或结束锚,我们将得不到匹配,即使“海洋”出现在字符串中。如果它不在绳子的末端,$号锚就不会把它捡起来。

anchor04 = re.findall('ocean$', anchor_n)
print(anchor04)[]

正则表达式否定(避免冰山)

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

安妮·斯普拉特在 Unsplash 上的照片

现在我们知道了如何在字符串的开头和结尾匹配字符串(提升和降低 SS 正则表达式的锚点),我们可以继续下一个概念:告诉 regex 匹配什么不匹配

想象一下,你是一艘大船的船长,这是一艘船的处女航。让我们称这艘船为泰坦尼克号。作为这艘船的船长,你可能更关注于而不是撞上冰山,而不是其他任何具体的事情。

在字符串中,您可能希望指定某些模式来避免。要做到这一点,使用否定。这些将匹配除了您指定的内容之外的任何内容。在 Python 中有两种主要的方法来处理它们:

  • 大写元字符:元字符匹配一组字符。一个大写的元字符通常会匹配除该字符集之外的所有内容
  • ^和字符集:使用一个^和一个字符集将匹配除了在字符集中指定的以外的所有内容

大写元字符

在我上一篇关于 Python 中正则表达式的文章中,我们介绍了三种不同的元字符:\s\w\d。作为复习,它们匹配字符串中的一组字符:\s匹配空白字符(空格、制表符和换行符),\w匹配字母数字字符(字母和数字),而\d匹配任何数字(数字)。

当您大写这些元字符中的任何一个时,它将匹配除了正常匹配之外的所有内容。要查看它们的运行情况,让我们创建一个包含空格、数字、字母和标点符号的新字符串:

negation = 'I sail my 3 ships on the 7 seas.'

现在,当我们看一看我们的大写元字符时,我们将看到它们的输出是如何变化的。

  • 这将匹配除空格之外的任何内容。我们在输出中看到来自negation字符串的所有字母、数字和标点符号
negation01 = re.findall('\S', negation)
print(negation01)['I', 's', 'a', 'i', 'l', 'm', 'y', '3', 's', 'h', 'i', 'p', 's', 'o', 'n', 't', 'h', 'e', '7', 's', 'e', 'a', 's', '.']
  • \W:这将匹配除了字母和数字以外的任何内容。我们这里的输出是每个空格和句尾的句号
negation02 = re.findall('\W', negation)
print(negation02)[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '.']
  • \D:这将匹配除数字以外的任何内容。您可能已经猜到,输出中有字母、空格和标点符号
negation03 = re.findall('\D', negation)
print(negation03)['I', ' ', 's', 'a', 'i', 'l', ' ', 'm', 'y', ' ', ' ', 's', 'h', 'i', 'p', 's', ' ', 'o', 'n', ' ', 't', 'h', 'e', ' ', ' ', 's', 'e', 'a', 's', '.']

^和字符集

一些用例需要比元字符更灵活的否定。让我们看一个例子:

  • 匹配给定字符串中的所有辅音

我们来分解一下这个问题。字母表里有 21 个辅音,我们想要全部。它们是不连续的,所以我们不能仅仅使用字符集中的一系列字母来得到它们。我们确实知道元音和辅音是互斥的,而且只有 5 个元音。如果我们能找到所有的元音,我们应该能通过否定得到所有的辅音。让我们从复习如何用字符集查找元音开始。

negation04 = re.findall('[AEIOUaeiou]', negation)['I', 'a', 'i', 'i', 'o', 'e', 'e', 'a']

括号内的字符定义了字符集。在这种情况下,任何元音都匹配。要获得除元音以外的所有内容,我们可以使用^。这将否定字符集内的所有内容。

negation05 = re.findall('[^AEIOUaeiou]', negation)[' ', 's', 'l', ' ', 'm', 'y', ' ', '3', ' ', 's', 'h', 'p', 's', ' ', 'n', ' ', 't', 'h', ' ', '7', ' ', 's', 's', '.']

…但那不是辅音。还有一点工作要做。我们的结果中有空格、数字和标点符号。由于捕获组中的所有内容都被否定,所以我们只需在结果中匹配所有不想要的内容。\s负责空格,\d负责数字,\.负责句点。\.不是元字符,是逃期。

negation06 = re.findall('[^AEIOUaeiou\s\d\.]', negation)['s', 'l', 'm', 'y', 's', 'h', 'p', 's', 'n', 't', 'h', 's', 's']

在所有的字符之后,我们需要以辅音结尾,也许这并不比键入 21 个不同的辅音更快,但它确实演示了我们如何将所有的字符加在一起,并使用正则表达式来得到我们想要的东西。

环顾四周(观赏野生动物)

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

马丁·韦特斯坦在 Unsplash 上拍摄的照片

出海时,我们可能会留意一些东西。看到一些野生动物将会是一次更有趣的旅行。我们寻找野生动物,这样我们就可以找到一个靠近它的地方来停泊我们的船。作为一名经验丰富的船长,我们并不真正关心野生动物本身,只关心附近的安全空间,以便驾驶船只。

类似于我们想通过野生动物寻找一个停车的地方,我们可能想在一些文本中寻找我们真正想要的信息。如果您现在还没有弄明白,正则表达式可以轻松地处理这个问题。为此,我们使用了一种叫做环视的方法。Look arounds 在字符串中搜索特定的匹配项,然后返回它之前或之后的某个值。这给我们留下了两种主要的环视方式:向前看和向后看。

让我们用下面的字符串作为例子来说明这两者是如何工作的。

lookaround = 'A penguin costs 2.99, a whale costs 5.99, I only have 3.50 left.'

对于我们想从这个字符串中提取什么信息,我们有两个场景。

  1. 每只动物的成本是多少?
  2. 卖什么动物?

起初,你可能会想为什么我们需要环顾四周才能做到这一点。你可以简单地寻找一个数字,句号,和另外两个数字。大概是这样的:

lookaround01 = re.findall('\d\.\d{2}', lookaround)

这是一个不错的开始,但是这一行代码的输出会给出三种价格。

print(lookaround01)[[1]]
[1] "2.99" "5.99" "3.50"

只有两种动物价格,最后一种是不相关的。环顾四周将有助于我们删除最后一个,并把一切都很好地纳入一个数据框架。

向后看

查看lookaround字符串,我们看到每种动物的价格前面都有单词“costs”我们将在后面用一个来看看。这将匹配我们通常匹配的任何内容,但前提是它之前有其他内容的匹配。前瞻的通用公式是"(?<=if preceded by this)match_this"。在我们的例子中,这将翻译如下(\s被添加以说明单词和数字之间的空间):

# Look behind
look_behind = re.findall('(?<=costs)\s\d\.\d{2}', lookaround)

现在我们有了每只动物的价格,不包括我在绳子上剩下的钱。

print(look_behind)[' 2.99', ' 5.99']

如果你仔细看,你会注意到琴弦上有空隙。现在不要担心这些,当我们建立一个数据框架来保存我们的价目表时,我们会处理这些问题。

向前看

现在,我们已经从字符串中获得了动物的价格,我们希望为价格列表数据框获取动物的名称。

为此,我们现在需要匹配单词“成本”前面的单词。为此,我们将使用前瞻。前瞻的基本公式如下:"match this(?=if followed by this)"。要从我们的字符串中获取动物名称,应该是这样的:

# Look Ahead
look_ahead = re.findall('\w+\s(?=costs)', lookaround)

就这样,我们抓住了单词 costs 之前的每个单词。在我们的字符串中是所有动物的名字。

print(look_ahead)['penguin ', 'whale ']

创建动物价格数据框

为了创建动物价格的数据框架,我们已经拥有了大部分我们需要的东西。我们只是用来自animalsprices的向量作为列创建一个数据帧。当然,要在 Python 中做到这一点,我们需要首先导入pandas模块作为pd

import pandas as pdanimal_prices = {'animals': look_ahead, 'prices': look_behind}
animal_prices_df = pd.DataFrame(animal_prices)

如果你忘了,当我们使用re.findall()时,它返回一个字符串列表。这可以很容易地用于创建字典和数据框。

我们的下一步是解决这些多余的空间。我们将使用.strip()方法。它移除字符串开头或结尾的空格。我们将使用列表理解在一行代码中为每一列完成这项工作。

animal_prices_df['animals'] = [animal.strip() for animal in animal_prices_df['animals']]
animal_prices_df['prices'] = [price.strip() for price in animal_prices_df['prices']]

生成的数据框如下所示:

 animals prices
0  penguin   2.99
1    whale   5.99

结论和进一步学习

就这样,你在 SS 正则表达式上的巡航结束了。你学到了:

  1. 如何匹配出现在字符串开头或结尾的字符串
  2. 如何用否定来寻找除了某物以外的任何东西
  3. 如何使用 look arounds 来匹配后面或前面的事物

以下是与 Python 中的正则表达式相关的一些其他资源,可能对您有所帮助:

  • 官方 [re](https://docs.python.org/3/library/re.html) 文档:虽然文档看起来令人生畏,但学习如何阅读它只会在你编程时对你有所帮助
  • w3schools 参考资料:庞大的编码和脚本语言参考资料知识库,包括 python。他们的许多例子都可以通过点击“自己尝试”按钮直接在浏览器上运行
  • Datacamp 课程(付费链接):一个致力于数据科学、机器学习和数据可视化的在线学习社区。查看他们的课程“Python 中的正则表达式”网站上每门课程的第一章都是免费的!

[## 通过我的推荐链接加入 Medium-Drew Seewald

作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…

realdrewdata.medium.com](https://realdrewdata.medium.com/membership)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值