用 Java 创建一个有序的 JSONObject
为什么创建有序 JSONObject 这么复杂?
米歇尔·亨德森在 Unsplash 上的照片
在 Java 中使用 JSONObject 时,您可能会注意到,当您打印出对象时,顺序并不完全是您所期望的。
我们要做的就是把它改成订购的,对吗?
嗯,事情比这要复杂一点,幸运的是,我已经找到了这个常见问题的迷人解决方案。
在这种情况下,我们进入幕后,操纵底层的数据结构,使之成为我们所需要的。
我将首先解释这个问题,然后给你提供一个解决方案。然后,我们将讨论您处理此问题的其他方式。
我们开始吧!
问题是
JSONObject 的底层数据结构是 HashMap。为什么?HashMap 允许快速检索键值对,使它们成为 JSON 对象的完美数据结构。
但是,正如我们在数据结构和算法课程中所记得的,默认情况下,HashMaps 是无序的,这意味着您的数据是随机分布在内存中的。
这意味着,如果我们想在日志、浏览器或电子邮件中打印 JSONObject,顺序可能会显得不规则。
这里有一个例子,我们用四个元素创建了一个 JSONObject。请注意我们向 JSONObject 添加对象的顺序:
现在看看这些对象在我们的日志中是如何显示的:
顺序应该是“一”、“二”、“三”、“四”。
如果我们以特定的顺序期待我们的结果,这是不好的。
解决方案
有几种方法可以处理这个问题,但是我将挖掘一个我非常感兴趣的解决方案。
我们将利用我以前只在单元测试中使用过的 API:反射。
反射是一个运行时 API,用于修改方法、接口和类的行为。这是一个很好的工具,我们可以用它来改变“幕后”的代码。
如果你看一下JSONObject.class
,你会看到这个构造函数:
这是创建 JSONObject 的默认构造函数。我们必须将底层数据结构(HashMap)改为有序的。对此的完美解决方案是 LinkedHashMap。
现在,让我们一行一行地检查这段代码:
- 第 14 行:我们仍然在创建之前使用过的 JSONObject。
- 第 15 行:我们需要处理这些方法抛出的异常(
IllegalAccessException
和NoSuchFieldException
)。因此,我们使用一个 try-catch 块。 - 第 16 行:Field 是我前面提到的反射 API 中的一个类。这有助于我们访问 JSONObject 类中声明的“map”字段。我们创造了一个“反射物体”
- 第 17 行:在上面 JSONObject.class 的截图中你可能已经注意到了,
nameValuePairs
变量是私有的。我们需要让它变得容易接近。 - 第 18 行:既然变量是可访问的,我们可以将
HashMap<>()
改为LinkedHashMap<>()
。 - 第 19 行:出于安全考虑,我们将把该变量的可访问性设置回 false。
将这个 JSONObject 记录到控制台后,您会看到输出现在是有序的:
大获成功!
替代解决方案
这肯定不是解决这个问题的唯一办法。这只是我感兴趣的一个解决方案,并且被证明是有效的。
还有其他库可以用来构建 JSON 对象,它们很可能提供对有序 JSON 的支持;然而,这是我使用org.json.JSONObject
的一个要求,所以我决定为这个 JSON 对象找到一个解决方案。
JSONArrays 可能会提供您正在寻找的解决方案,因为订单遵循一个索引。
一个可能的解决方案是实现您自己的 JSONObject。您可以使用 LinkedHashMap <>()或其他有序的数据结构,而不是使用 HashMap <>()来实现。
如何解决这个问题的机会是无限的,但是使用反射 API 是一个很棒的选择。
如果您有任何问题、意见或顾虑,请告诉我!
使用 Python 的 Matplotlib 创建和定制箱线图,以从数据中获得大量见解
箱线图被低估了。它们塞满了关于底层分布的见解,因为它们将大量关于数据的信息浓缩到一个小的可视化中。
在本文中,您将看到箱线图如何成为实现以下目标的强大工具:
- 了解数据的分布。
- 发现异常值。
- 比较分布,以及箱线图可视化中的小调整如何更容易发现分布之间的差异。
了解数据的分布
在探索性数据分析过程中,箱线图是直方图的一个很好的补充。
使用直方图,很容易看到分布的形状和趋势。因为直方图突出了每个数据点在分布中出现的频率。
箱线图不直接关注频率,而是关注分布中的值的范围。
直方图突出显示频率,而箱线图突出显示数据的范围。
我们习惯用频率和比较比例来思考。这就是为什么我们如此轻松地解释直方图的洞察力,在直方图中,我们可以发现大多数数据集中的值,我们可以看到分布的形状。
使用箱线图,我们可以获得与直方图相同的洞察力。虽然我们可以用直方图来显示分布的形状,但箱线图突出显示了给出分布形状的汇总指标。我们可以从箱线图中提取的汇总指标有:
- 分位数,特别是第一和第三分位数,对应于第 25 和第 75 个百分点。
- 中位数,分布的中间点,也对应于第 50 个百分位数。
- 四分位数范围(IQR) ,第三个和第一个分位数之间的宽度。用数学表达,我们有 IQR = Q3 — Q1。
- *最小值,*数据集中排除异常值的最小值,对应于 Q1-1.5 倍质量分数
- Max ,数据集中的最大值,不包括异常值,对应 Q3+ 1.5xIQR。
您可以从直方图和箱线图中提取的汇总指标。
斑点异常值
突出异常值的箱线图。
在方框图中显示异常值通常显示为圆圈。但是正如您将在下一节看到的,您可以定制离群值的表示方式😀
如果你的数据集有异常值,用箱线图很容易发现它们。有不同的方法来确定数据点是异常值。最广为人知的是 1.5xIQR 规则。
1.5xIQR 规则
异常值是数据集中的极端观察值。因此,判断一个数据点是否极端的经验法则是将其与四分位间距进行比较。
使用四分位距(IQR)来发现异常值是有意义的。IQR 是第一个和第三个四分位数之间的值范围,即第 25 个和第 75 个百分位数,因此它将包括数据集中的大多数数据点。
但是为什么是 1.5 倍的四分位间距呢?这与被称为68–95–99 规则的正态分布的一个重要特征有关。
68–95–99 法则,来源:【https://commons.wikimedia.org/wiki/File:Empirical_Rule.PNG
根据 68–95–99 规则,我们知道:
- 68%的数据在平均值之上或之下的一个标准偏差内,
- 95%的数据在平均值的两个标准偏差内,
- 99.7%的数据在平均值的三个标准偏差之内。
只有很少的数据点会超过平均值的三个标准偏差,更准确地说,只有 0.3%的数据点。所以任何超过三个标准差的数据点都被认为是极端的。
为了检查一个数据点是否是异常值,并检查它是否超出三个标准差,我们计算:
- Q1-1.5 倍
- Q3 + 1.5xIQR。
这些代表分布中不被认为是极端的区域的下限和上限。其最终大约是平均值的 3 个标准偏差。
乘数是 1.5,因为任何大于 1.5 的数字都会导致大于 3 倍标准差的范围。因此,数学家们选定了一个中间数。
箱线图和概率密度函数,来源:https://commons.wikimedia.org/wiki/File:Boxplot_vs_PDF.svg
任何低于下限或高于上限的数据点都是异常值;
- (数据点值)< Q1–1.5xIQR, then it’s an outlier.
- (data point value) > Q3 + 1.5xIQR,那么就是离群值。
自定义箱线图以比较分布
箱线图也是比较不同分布的好工具。
让我们比较一下虹膜数据集中花朵花瓣长度的分布。
比较虹膜数据集的花瓣长度。
以下是你如何创建这个情节。
import numpy as np
import pandas as pd
from sklearn import datasets
import matplotlib.pyplot as plt# Load Iris dataset
iris = datasets.load_iris()# Preparing Iris dataset
iris_data = pd.DataFrame(data=iris.data, columns=['sepal_length', 'sepal_width', 'petal_length', 'petal_width'])iris_target = pd.DataFrame(data=iris.target, columns=['species'])
iris_df = pd.concat([iris_data, iris_target], axis=1)# Add species name
iris_df['species_name'] = np.where(iris_df['species'] == 0, 'Setosa', None)iris_df['species_name'] = np.where(iris_df['species'] == 1, 'Versicolor', iris_df['species_name'])iris_df['species_name'] = np.where(iris_df['species'] == 2, 'Virginica', iris_df['species_name']) # Prepare petal length by species datasets
setosa_petal_length = iris_df[iris_df['species_name'] == 'Setosa']['petal_length']versicolor_petal_length = iris_df[iris_df['species_name'] == 'Versicolor']['petal_length']virginica_petal_length = iris_df[iris_df['species_name'] == 'Virginica']['petal_length'] # Visualize petal length distribution for all speciesfig, ax = plt.subplots(figsize=(12, 7))# Remove top and right border
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.spines['left'].set_visible(False)# Remove y-axis tick marks
ax.yaxis.set_ticks_position('none')# Add major gridlines in the y-axis
ax.grid(color='grey', axis='y', linestyle='-', linewidth=0.25, alpha=0.5)# Set plot title
ax.set_title('Distribution of petal length by species')# Set species names as labels for the boxplot
dataset = [setosa_petal_length, versicolor_petal_length, virginica_petal_length]labels = iris_df['species_name'].unique()
ax.boxplot(dataset, labels=labels)plt.show()
(再次)比较虹膜数据集的花瓣长度。
我们可以从这个情节中获得一些启示:
- 刚毛鸢尾的花瓣长度远小于杂色鸢尾和海滨鸢尾。它的范围从大约 1 到 2 厘米。
- 海滨鸢尾的花瓣长度范围大于刚毛鸢尾和杂色鸢尾的花瓣长度范围。我们可以从**的高度看出,与其他两个相比,海滨鸢尾的盒子是的。
- 鸢尾和 Veriscolor 都有异常值。
我们还可以通过查看每个分布的汇总指标来确认这些见解。
鸢尾属植物花瓣长度的综合度量。
下面是计算这些指标的方法。
*def get_summary_statistics(dataset):
mean = np.round(np.mean(dataset), 2)
median = np.round(np.median(dataset), 2)
min_value = np.round(dataset.min(), 2)
max_value = np.round(dataset.max(), 2) quartile_1 = np.round(dataset.quantile(0.25), 2)
quartile_3 = np.round(dataset.quantile(0.75), 2) # Interquartile range
iqr = np.round(quartile_3 - quartile_1, 2) print('Min: %s' % min_value)
print('Mean: %s' % mean)
print('Max: %s' % max_value)
print('25th percentile: %s' % quartile_1)
print('Median: %s' % median)
print('75th percentile: %s' % quartile_3)
print('Interquartile range (IQR): %s' % iqr)
print('Setosa summary statistics')print('\n\nSetosa summary statistics')
get_summary_statistics(setosa_petal_length)print('\n\nVersicolor summary statistics')
get_summary_statistics(versicolor_petal_length)print('\n\nVirginica summary statistics')
get_summary_statistics(virginica_petal_length)*
定制您的箱线图
乍一看,很难区分不同物种的箱线图。底部的标签是我们比较分布的唯一视觉线索。
我们可以使用 boxplot 的属性来定制每个框*。由于属性应用于所有数据,这些数据是给定 boxplot 方法的*,我们不能采用最后一个绘图的方法,并使用每个物种花瓣长度的数组作为输入。**
我们必须绘制每个物种的花瓣长度,并对每个物种应用属性。
我们将使用以下参数:
- 位置:箱线图在绘图区的位置。我们不想将每个物种的箱线图绘制在彼此之上,所以我们用它来设置每个箱线图在 x 轴上的位置。
- medianprops :应用于箱线图内中线的属性字典。
- whiskerprops :应用于胡须的属性字典。
- capprops :应用于胡须上帽子的属性字典。
- flierprops :应用于离群值的属性字典。
我们还可以自定义其他几个属性。在本例中,我将为每个箱线图添加不同的颜色,这样更容易看到我们在可视化不同的分布。
比较虹膜数据集的花瓣长度,为每个物种定制颜色。
*fig, ax = plt.subplots(figsize=(12, 7))# Remove top and right border
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.spines['left'].set_visible(False)# Remove y-axis tick marks
ax.yaxis.set_ticks_position('none') # Set plot title
ax.set_title('Distribution of petal length by species')# Add major gridlines in the y-axis
ax.grid(color='grey', axis='y', linestyle='-', linewidth=0.25, alpha=0.5)# Set species names as labels for the boxplot
dataset = [setosa_petal_length, versicolor_petal_length, virginica_petal_length]
labels = iris_df['species_name'].unique() # Set the colors for each distribution
colors = ['#73020C', '#426A8C', '#D94D1A']
colors_setosa = dict(color=colors[0])
colors_versicolor = dict(color=colors[1])
colors_virginica = dict(color=colors[2])# We want to apply different properties to each species, so we're going to plot one boxplot
# for each species and set their properties individually
# positions: position of the boxplot in the plot area
# medianprops: dictionary of properties applied to median line
# whiskerprops: dictionary of properties applied to the whiskers
# capprops: dictionary of properties applied to the caps on the whiskers
# flierprops: dictionary of properties applied to outliersax.boxplot(dataset[0], positions=[1], labels=[labels[0]], boxprops=colors_setosa, medianprops=colors_setosa, whiskerprops=colors_setosa, capprops=colors_setosa, flierprops=dict(markeredgecolor=colors[0]))ax.boxplot(dataset[1], positions=[2], labels=[labels[1]], boxprops=colors_versicolor, medianprops=colors_versicolor, whiskerprops=colors_versicolor, capprops=colors_versicolor, flierprops=dict(markeredgecolor=colors[1]))ax.boxplot(dataset[2], positions=[3], labels=[labels[2]], boxprops=colors_virginica, medianprops=colors_virginica, whiskerprops=colors_virginica, capprops=colors_virginica, flierprops=dict(markeredgecolor=colors[2]))plt.show()*
就是这样!您可以使用箱线图来探索您的数据和自定义您的可视化,以便更容易提取见解。
感谢阅读!
在 1 分钟内创建并共享交互式地图
使用 Google Sheet 创建交互式 Choropleth 地图的简单方法。
由 Puk Patrick 在 Unsplash 上拍摄的照片
在数据科学中,在你完成数据分析后,你可能需要用一些漂亮的交互式数据可视化工具来探索或展示结果。当然,这些工具中的一个将包括交互式地图,您可以将鼠标放在该区域并探索数据值。但是,这个过程需要花费很多时间去学习和实践。
本文将向您展示一种替代方法,让您在 1 分钟内使用 Google Sheets 从数据集创建交互式地图。作为一个例子,本文通过创建一个交互式地图来探索每个国家的新冠肺炎数据集,用户可以悬停在该地图上并查看已确认的新冠肺炎病例数。
互动地图显示截至 2020 年 10 月 21 日确诊的新冠肺炎病例。(作者)
我们开始吧!
第一步:把你的数据集放在谷歌表上。
在这第一步,你只需要打开谷歌表单(https://docs.google.com/spreadsheets)。然后,从 CSV、Excel、Html 等格式导入您的数据。或者你甚至可以将你的数据复制粘贴到谷歌工作表中。作为下面的例子,我使用了已确认的新冠肺炎案例数据集**。
使用 Google Sheet 创建地理图。(作者)
该数据集是使用 Google Big Query 从 JHU-CSSE 查询和汇总的新冠肺炎数据。如果你想知道它是如何做到的,请查看我的教程 这里 。
第二步:创建一个交互式地图。
要创建交互式地图,只需点击插入>图表。
使用 Google Sheet 创建地理图。(作者)
将图表导入工作表后,只需找到“地图”类别并选择“地理图表”图表类型。
使用 Google Sheet 创建地理图。(作者)
然后,您可以进行一些最终设置,如自定义地图风格,背景颜色,字体等。
在 Google Sheet 上定制地图样式。(作者)
祝贺你,现在你在谷歌工作表中有了一个漂亮的交互式地图!
第三步:分享地图。
地图制作完成后,您可以轻松地与同事分享 Google Sheet。或者,您也可以通过单击地图右上角的菜单,然后单击“发布图表”,将最终地图嵌入到您的网站中。
从 Google Sheet 发布图表。(作者)
差不多就是这样!我希望你喜欢这篇文章,并能够使用 Google Sheet 以有效的方式用地图可视化数据。 平安健康!
感谢阅读。👋😄
用 Python 创建自动更正!
nltk 包装笼简介
马库斯·斯皮斯克在 Unsplash 上的照片
T 他的文章将指导你用 python 创建一个简单的自动更正程序。这个项目是创建两个不同的拼写推荐器,它将能够接受用户的输入,并推荐一个正确拼写的单词。非常酷!
注意:测试输入:[‘cormulent ‘,’ incendenece ‘,’ validrate’]。
包装
这项工作将主要集中在 nltk 库的使用上。nltk 代表自然语言工具包,关于它能做什么的更多信息可以在这里找到。
具体来说,我们将使用单词、edit_distance、jaccard_distance 和 ngrams 对象。
edit_distance,jaccard_distance 指的是用于确定与用户输入最相似的单词的度量
一个 n-gram 是来自给定文本或语音样本的 n 个项目的连续序列。例如:“白宫”是一个二元结构,与“白宫”有着不同的含义。
此外,我们还将使用 pandas 来创建正确单词列表的索引系列。
words.words() 给出了一个拼写正确的单词列表,这些单词已经作为 word 对象包含在 nltk 库中。 spellings_series 是这些单词的索引序列,输出显示在代码块下面。
拼写 _ 系列输出
推荐者 1
度量:Jaccard 距离
这是一种衡量两组有多么不同的方法,我试图用简单的英语解释如下:
正在讨论的字符串将与 spellings_series 中的每个单词进行迭代比较。
对于每个比较实例,我们计算非唯一字母的总数以及两个集合之间共享字母的数量,作为总数和非唯一。然后,我们将非唯一除以总计,并乘以 100%以获得相似度百分比。这是 Jaccard 指数。
Jaccard 距离是对不同的两个集合如何的度量,并且可以作为 Jaccard 索引(即 Jaccard 距离= 100% - Jaccard 指数)
定义一个 Jaccard 函数来遍历可能的单词:
我们将使用一个空列表和一个 for 循环来迭代遍历 spellings_series 。
jaccard 函数将接受参数条目和 gram_number ,其中条目指的是有问题的单词,而 gram_number 设置要使用的 n-gram 的数量(为使用属于同一个 ngram 的单词列表的情况做准备)在这里可以找到关于 ngrams 的更多信息,我花了一些时间来完全理解它!
拼写将根据输入字符串的首字母创建一个可能的单词列表。这里假设第一个字母没有打错。
接下来,距离将使用内置的 jaccard_distance 函数迭代计算拼写中单词各自的 jaccard 距离。
最后,最接近的将通过距离上的最小函数给出最终的最佳匹配单词。这可以被附加到结果空列表中,该列表将被返回。
现在,通过我们令人惊叹的新 jaccard 函数,我们可以创建单词 recommender, JDreco 。默认情况下,该函数将接受字符串列表“cormulent”、“incidence”、“validrate”,并返回建议的单词列表。
恭喜,第一个推荐模型完成了!
推荐者 2
公制: 编辑距离 ,又名 Levenshtein 距离 。
这是一种基于将一个字符串转换成另一个字符串所需的最少操作数来评估两个字符串的不同程度的方法。类似于之前,该功能将默认地接受与推荐器 1 中相同的单词列表。
该函数将反复比较条目与正确单词列表,并获得它们各自的编辑距离。然后,具有最低距离的单词将被视为最佳匹配单词,附加到结果,并由函数返回。
第二款推荐车型完成!
用户输入
现在让我们把我们的模型投入工作。我们将尝试一个由三个单词组成的列表:一个拼错的“请说三个单词”——“threa woeds pleese”,让我们看看效果如何。下面的代码提示用户输入三个单词来创建一个列表 userinput 。
推荐人 1:
结果是“线程”,“悲哀”,“恳求”。
JDreco 输出
推荐者 2:
结果是“tarea”、“Moed”、“please”
editreco 输出
进一步的改进
结果和我预想的相差太远了!与 JDreco 相比,editreco 通过正确建议“请”似乎表现得更好。
这在很大程度上应该是因为算法目前过于“机械”,只根据单个字母判断单词。我相信这表明创建一个谷歌级别的自动更正肯定会花费大量的时间和精力。
我能看到的一些未来的改进将会是通过流行的机器学习使能器 Pytorch 考虑语法和词汇化。
感谢你的阅读!
请在这里找到代码。
通过这篇文章,我希望您已经**了解了 nltk 的基础知识,**尽管这个库非常庞大,我不可能在一篇文章中涵盖所有内容。我想说,如果付出适当的时间和努力,这将是一个对大多数人来说都很容易理解和编码的数据科学项目。
我通过由 Coursera 主办的密歇根大学 MOOC“Python 中的应用文本挖掘”学到了这一点。推荐!
如果你有问题或者想讨论在后新冠肺炎时代应用数据科学技术的想法,请随时联系我。
我希望我能够以这样或那样的方式帮助您学习数据科学方法!
这是另一篇数据科学文章!
了解岭回归模型背后的理论,如何通过 python 和 scikit-learn 对其进行编码和调优。
medium.com](https://medium.com/python-in-plain-english/ridge-regressions-on-easy-mode-9e7353a0e3f9)
使用 Python 创建漂亮的交互式和弦图
Python 中的数据可视化
一个简单的指南,使用一个简单的函数调用来创建一个令人敬畏的和弦图。
根据数据科学家的说法,当谈到什么是最好的语言时,R vs Python 是一场持续的争论。虽然每种语言都有它的长处,但在我看来,R 有一个难以超越的尖端技巧——R 拥有通过可视化交流结果的神奇工具。
本周,当我试图寻找一种吸引人的方式来可视化数据中各特征之间的相关性时,这一点引起了我的注意。我偶然发现了和弦图!(我们一会儿就会谈到这个)我见过几个使用 Circlize 生成和弦图的 R 示例,在这些示例中,您只需将形状合适的数据传递给 chordDiagram()函数和 ta-da!
你应该看到当我发现和弦图的 Python Plotly 实现时我脸上的表情。即使要得到一个基本的数字,也要付出很多努力。最终结果似乎根本不值得努力。当我在 pypi 上偶然发现和弦时,我几乎放弃了使用和弦图的想法。
好吧,什么是和弦图?
弦图表示一组不同项目之间的流程。这些被称为节点的项目显示在一个圆的周围,流显示为节点之间的连接,显示为弧。
如果这还没有解释清楚,让我们来看一个例子:
作者图片
上面的弦图直观地显示了两个实体(本例中为城市)在旅行者的旅程中同时出现的次数,它允许我们研究它们之间的流动。
如何用最少的努力创造出漂亮的和弦图?
让我带您了解数据准备的过程,然后创建和弦图。
安装:
假设已经安装了 Pandas,您需要从 pypi 安装 chord 包,使用—
pip install chord
数据准备:
我用的是波士顿房价数据集,可以从这里下载。
# importing Pandas libary
import pandas as pd# reading data from csv
df = pd.read_csv("housing.csv")
我的目标是可视化数据集中要素之间的相关性。因此,为了简洁起见,我将删除一些列。我将只剩下 6 个特征。(如果您愿意,可以跳过这一步)
# List of columns to delete and then dropping them.
delete = ['ZN', 'INDUS', 'CHAS', 'DIS','RAD','PTRATIO','B','LSTAT']df.drop(delete, axis=1, inplace=True)
现在让我们使用 Pandas corr()函数创建相关矩阵。
# Now, matrix contains a 6x6 matrix of the values.
matrix = df.corr()# Replacing negative values with 0’s, as features can be negatively correlated.
matrix[matrix < 0] = 0# Multiplying all values by 100 for clarity, since correlation values lie b/w 0 and 1.
matrix = matrix.multiply(100).astype(int)# Converting the DataFrame to a 2D List, as it is the required input format.
matrix = matrix.values.tolist()
这些数据现在非常适合我们的绘图!
绘制图表图:
绘制之前剩下的唯一一步是将实体的名称存储为一个列表。在我的例子中,这些是特性的名称。
# Names of the features.
names = ["Crime Rate","N-Oxide","Number of rooms","Older buildings","Property Tax","Median Price"]
现在,我们要做的就是导入这个包—
from chord import Chord
然后将矩阵和名称传递给 Chord()函数。
Chord(matrix, names).show()#Note: The show() function works only with Jupyter Labs.
# (Not Jupyter notebook)
这将是您的输出:
朱庇特实验室的输出。图片作者。
在我们进一步探索和弦库中可用的其他风格和输出设置之前,让我们看看输出代表什么。
如你所见,当你在犯罪率上徘徊时,你可以看到它与财产税、旧建筑和氮氧化物水平有关,但与中间价格或房间数量无关。现在,您可以将鼠标悬停在连接上,您将看到这些要素之间的相关值。
您可能会注意到,中间价格与其自身 100%相关,所有特性都是如此。这是因为当我们将一个特征与其自身进行比较时,我们得到了一个完美的相关值。如果您愿意,我们可以用一行代码来解决这个问题。
# Operate on the data before converting it into a 2D List# We are just converting all Perfect correlation 100's(Basically the 1’s) to 0 as well.
matrix[matrix == 100] = 0
matrix = matrix.values.tolist()
这是你的输出,一个更清晰的和弦图:
作者图片
将和弦图导出为 HTML:
因为这个包的核心使用了 d3-chord,所以它也给了我们一个选项来输出 ChordDiagram 作为一个完全可编辑的 HTML 文件!多酷啊。
同样,一个简单的方法调用就能帮你做到—
Chord(matrix, names).to_html()# This will create a file 'out.html' in your current directory.
您可以在浏览器中打开 HTML 来查找相同的交互式和弦图,也可以打开。html 并自定义页面的其余部分!
这是我的输出,
以 HTML 的形式输出。图片作者。
我所做的是极其基本的。关键是,HTML 格式的输出为使用和弦图提供了无数的可能性。
造型定制:
颜色:
您可以通过从 d3 分类调色板中传递任何颜色来更改和弦图的颜色。您可以在官方指南中找到输出样本。但这里有几个例子:
# Just add the colors parameter and pass the value.
Chord(matrix, names, colors="d3.schemeDark2").show()
作者图片
# Just add the colors parameter and pass the value.
Chord(matrix, names, colors="d3.schemeAccent").show()
作者图片
# Add all the colors to a list.
coloursList = ["#f50057", "#2196f3", "#00e676", "#ff5722", "#00000", "#ff9100"]# Pass the list to the colors parameter.
Chord(matrix, names, colors=coloursList).show()
作者图片
其他定制:
你也可以自定义标签和不透明度,查看官方指南。
结论:
创建可视化几乎总是数据科学家工作的一部分。部分是这里的关键词,因为这意味着你不能花太多时间来使它们成形,这就是为什么我们寻找提供简单但功能实现的选项。这就是我在本文中试图探索的,用最少的努力创建一个有效的和弦图。
这是我的第一部技术写作作品,我试图将我多年来从这个社区阅读优秀内容时遇到的最佳实践融入其中。我很感激对我工作的任何方面的反馈。
其他资源:
[1] 官方指南 —沙欣·罗斯塔米的博客(图书馆作者)
PyPi 上的[2] 和弦——你可以在这里下载这个包。
创建美观简单的 ML web 应用程序,只需几个步骤就可以大规模部署
本文将教你如何使用 Streamlit 和 AWS CDK 从头开始构建一个 ML 驱动的 web 应用,并从头到尾大规模部署到 AWS Fargate。
你可以看看这个回购的代码。
我们要建造什么?
我们将创建一个 web 应用程序,它可以为我们变魔术。这个技巧就是让某些东西从图像中“消失”。为此,我们将使用一种叫做图像修复的东西,或者说是一种处理过程,在这种过程中,你获取图像中丢失的部分,然后根据背景信息对其进行恢复。我们将研究关于该主题的最新研究论文之一,该论文将于 2020 年 CVPR 上发表,名为**“超高分辨率图像修复的上下文残差聚合”**。你可以阅读易等人【2020】在 arXiv 中的论文,并在本回购中看到其代码实现。
但在我们实际运行任何图像内画之前,我们需要生成一个遮罩图像,该图像将只在白色前景上显示黑色像素,而我们希望从照片中消失一些东西。您可以手动完成,也可以让计算机为您完成。如果您选择第二个选项,那么您的最佳选择是使用“语义分割”算法,该算法将进行最接近该对象形状的像素级分类。但是,因为我们想尽可能简单,我们将运行“对象检测”,在这些对象的顶部绘制边界框。结果不会那么好,但也足够好了。我们将使用 AWS Rekognition ,因为它使用简单,推理时间短。你总是可以从 GluonCV 网站或者其他一些非常好的框架中了解到关于这两个(以及更多)计算机视觉应用的更多信息。
以下是我们期望得到的结果。您可以在左边看到输入图像(见下面的作者信息),在右边看到输出图像。您可以在demo.ipynb
笔记本中找到获得该结果所需的所有步骤。
但是,如果我们想要构建一个更具交互性、动态性、易于调试、非常适合与非技术人员共享模型和结果的东西,该怎么办呢?有一些选项可以帮助你做到这一点,比如 Jupyter Voila 和 Plotly Dash,但它们都不能同时做到所有这些。就在那时,我开始关注 Streamlit ,这是一个开源应用程序框架,它运行在 Python 中,让你用很少的开发工作就能创建看起来很棒的 web 应用程序。我不会详细介绍什么是 Streamlit 以及它是如何工作的,但是您可以在这里看到许多示例和演示,在这里看到一些最佳实践。
入门指南
每个人都有自己处理这类项目的方式,但对我来说最有效的方式是遵循一种精益方法,在这种方法中,我可以快速设计/构建、度量和学习。这些是我通常会做的步骤:
- 创建一个演示笔记本,证明我可以做我希望做的事情,例如,拍摄一个输入图像并生成一个内画图像输出
- 创建一个 Streamlit 应用程序,它将包含与演示笔记本相同的步骤。
- 将所有东西安装到 AWS CDK 项目中,为部署做好准备。
我不会详细介绍第一步,但我会深入探讨如何构建一个 Streamlit 应用程序,以及一旦您知道它可以工作,如何让您的项目适合大规模部署。
要求
1)创建演示笔记本
转到您的终端并克隆这个存储库
$ git clone [https://github.com/nicolasmetallo/legendary-streamlit-demo](https://github.com/nicolasmetallo/legendary-streamlit-demo)
现在,cd
进入cdk/app
,你会发现demo.ipynb
。安装所有依赖项并在笔记本中运行代码。
$ cd cdk/app
$ pip install -r requirements.txt
2)创建您的 Streamlit 应用程序
项目结构
.
├── LICENSE
├── README.md
└── cdk
├── README.md
├── app
│ ├── Dockerfile
│ ├── app.py
│ ├── demo.ipynb
│ ├── helpers.py
│ ├── requirements.txt
│ ├── src
│ │ ├── input_img.png
│ │ ├── local_container.png
│ │ └── magic_trick.png
│ └── test_images
│ ├── image_1.jpg
│ ├── image_2.jpg
│ ├── image_3.jpg
│ ├── image_4.jpg
│ ├── image_5.jpg
│ └── image_6.jpg
├── app.py
├── cdk
│ ├── __init__.py
│ └── cdk_stack.py
├── cdk.json
├── requirements.txt
└── setup.py
您的 Streamlit 应用的主要部分
我们的应用程序将从不同的来源(URL、示例库、用户上传)读取一个输入图像,生成一个内画图像,最后将两者并排绘制在一起。
我们要做的第一件事是导入依赖项和帮助函数。彼得·鲍姆加特纳写了一篇关于重构和编写模块化代码的好文章,应该可以帮助你更好地组织你的代码。
助手函数(作为导入)
from helpers import InPainting
magic_trick = InPainting()
助手功能(在 app.py 中)
def show_images(input_img, output_img):
f = plt.figure(figsize=(20,20))
f.add_subplot(1,2,1)
plt.imshow(input_img)
f.add_subplot(1,2,2)
plt.imshow(output_img)
plt.show(block=True)
st.pyplot(bbox_inches='tight')
阅读您的输入图像
st.header('Read image')
st.image(
'src/input_img.png',
caption='Illustration by [https://blush.design/artists/vijay-verma'](https://blush.design/artists/vijay-verma'),
use_column_width=True,
)
options = st.radio('Please choose any of the following options',
(
'Choose example from library',
'Download image from URL',
'Upload your own image',
)
)input_image = None
if options == 'Choose example from library':
image_files = list(sorted([x for x in Path('test_images').rglob('*.jpg')]))
selected_file = st.selectbox(
'Select an image file from the list', image_files
)
st.write(f'You have selected `{selected_file}`')
input_image = Image.open(selected_file)
elif options == 'Download image from URL':
image_url = st.text_input('Image URL')
try:
r = requests.get(image_url)
input_image = Image.open(io.BytesIO(r.content))
except Exception:
st.error('There was an error downloading the image. Please check the URL again.')
elif options == 'Upload your own image':
uploaded_file = st.file_uploader("Choose file to upload")
if uploaded_file:
input_image = Image.open(io.BytesIO(uploaded_file.read()))
st.success('Image was successfully uploaded')if input_image:
st.image(input_image, use_column_width=True)
st.info('''
Image will be resized to fit within `(1024,1024)`
pixels for easier processing.
''')
else:
st.warning('There is no image loaded.')
在图像上运行您的模型推理
st.header('Run prediction')
st.write('')
prediction_checkbox = st.checkbox('Do a magic trick!')
if input_image and prediction_checkbox:
try:
with st.spinner():
output_image = magic_trick.run_main(input_image)
show_images(input_image, output_image)
except Exception as e:
st.error(e)
st.error('There was an error processing the input image')
帮助者. py
为了生成内画图像,我们需要输入图像和遮罩图像,其中除了我们的目标以外,每个像素都是白色的。如前所述,我们将使用 AWS Rekognition 来检测一个对象和一个自定义类,以根据该检测创建一个遮罩图像。
class Rekognition:
def __init__(self):
self.client = boto3.client(
'rekognition',
region_name = 'eu-west-2', # not needed
)def predict_labels(self, image_bytes, max_labels=10, min_conf=90):
response = self.client.detect_labels(
Image = {'Bytes': image_bytes},
MaxLabels = max_labels,
MinConfidence = min_conf,
)
return response['Labels']
def return_mask_img(self, image_bytes):
image = Image.open(io.BytesIO(image_bytes))
imgWidth, imgHeight = image.size
blank = Image.new('RGB', image.size, (255, 255, 255))
draw = ImageDraw.Draw(blank)
response = self.predict_labels(image_bytes)
for idx, label in enumerate(response):
name = label['Name']
instances = label['Instances']if len(instances) == 0: continue
for instance in instances:
confidence = instance['Confidence']
box = instance['BoundingBox']
left = imgWidth * box['Left']
top = imgHeight * box['Top']
width = imgWidth * box['Width']
height = imgHeight * box['Height']points = (
(left, top),
(left + width, top),
(left + width, top + height),
(left , top + height),
(left, top),
)# draw bounding box
draw.rectangle([left, top, left + width, top + height], fill='black')
return blank
一旦我们有了这两个图像,我们应该能够运行图像在绘画模型预测。
class InPainting:
def __init__(self):
self.rekognition = Rekognition()
self.multiple = 6
self.INPUT_SIZE = 512 # input image size for Generator
self.ATTENTION_SIZE = 32 # size of contextual attention
def PIL_to_cv2(self, pil_img):
np_img = np.array(pil_img.convert('RGB'))
return cv2.cvtColor(np_img, cv2.COLOR_RGB2BGR)
def PIL_to_image_bytes(self, img):
buffer = io.BytesIO()
img.save(buffer, format='JPEG')
return buffer.getvalue()
def cv2_to_PIL(self, cv2_im):
cv2_im = cv2.cvtColor(cv2_im, cv2.COLOR_BGR2RGB)
return Image.fromarray(cv2_im)
def run_main(self, input_image, max_size = (1024,1024)):
with tf.Graph().as_default():
with open('sample-imageinpainting-HiFill/GPU_CPU/pb/hifill.pb', "rb") as f:
output_graph_def = tf.GraphDef()
output_graph_def.ParseFromString(f.read())
tf.import_graph_def(output_graph_def, name="")with tf.Session() as sess:
init = tf.global_variables_initializer()
sess.run(init)
image_ph = sess.graph.get_tensor_by_name('img:0')
mask_ph = sess.graph.get_tensor_by_name('mask:0')
inpainted_512_node = sess.graph.get_tensor_by_name('inpainted:0')
attention_node = sess.graph.get_tensor_by_name('attention:0')
mask_512_node = sess.graph.get_tensor_by_name('mask_processed:0')
input_image.thumbnail(max_size)
image_bytes = self.PIL_to_image_bytes(input_image)
raw_mask = self.PIL_to_cv2(self.rekognition.return_mask_img(image_bytes))
raw_img = self.PIL_to_cv2(input_image)
inpainted = self.inpaint(
raw_img, raw_mask, sess, inpainted_512_node,
attention_node, mask_512_node, image_ph, mask_ph, self.multiple)
return self.cv2_to_PIL(inpainted)
创建 Dockerfile 文件
FROM python:3.7
EXPOSE 8501
WORKDIR /app
COPY requirements.txt ./requirements.txt
RUN pip3 install -r requirements.txt
RUN git clone [https://github.com/Atlas200dk/sample-imageinpainting-HiFill.git](https://github.com/Atlas200dk/sample-imageinpainting-HiFill.git) && \
cd sample-imageinpainting-HiFill && \
git checkout 1f7f769bd1ea225d4d5c8b094dd261ca9172927b
COPY . .
CMD streamlit run app.py \
--server.headless true \
--browser.serverAddress="0.0.0.0" \
--server.enableCORS false \
--browser.gatherUsageStats false
构建映像并在本地运行以进行调试
在您的终端中运行下面的命令来构建您的容器映像
$ docker build -t demo/magic-trick .
现在运行容器
$ docker run -it — rm -p ‘8501:8501’ demo/magic-trick
如果你打开浏览器,进入 http://localhost:8501 ,你应该能看到下面的… 成功!😃
3)使用 AWS CDK 将您的 Streamlit 应用程序部署到 AWS Fargate
快速介绍
AWS CDK 是一个软件开发框架,用于在代码中定义云基础设施,并通过 AWS CloudFormation 进行配置,使您能够:
- 可预测地重复创建和配置 AWS 基础设施部署。
- 利用 AWS 产品,如 Amazon EC2、Amazon Elastic Block Store、Amazon SNS、Elastic Load Balancing 和 Auto Scaling。
- 在云中构建高度可靠、高度可伸缩、经济高效的应用程序,而无需担心创建和配置底层 AWS 基础架构。
- 使用模板文件将资源集合作为一个单元(堆栈)一起创建和删除。
AWS Fargate 是亚马逊 ECS 和 EKS 的计算引擎,允许你运行容器,而不必管理服务器或集群。我们将使用这两种服务来轻松地大规模部署我们的容器。
如果你不理解所有这些,不要太担心,因为有一个很好的入门指南供你参考,还有官方 Python 参考文档供你查阅。我将按照官方的 ECS 示例列出您需要完成的每个步骤,但是因为这些步骤中的大部分已经在此 repo 中完成(例如,创建项目目录),所以在跳到下面的部署您的堆栈之前,请随意初始化 AWS CDK 并安装所有依赖项。
配置您的 AWS 凭据
如果您打算从本地机器部署您的栈,您应该确保您的 AWS 凭证在您的环境中被正确设置。你可以在文档中了解更多信息。
打开您的终端并运行以下命令。当询问时,添加您的访问密钥和密钥。
$ aws configure
另一方面,如果您打算从 AWS 实例(例如 EC2、SageMaker 等)部署您的堆栈。)然后,您的环境将采用您分配给该实例的凭证和角色,您不需要进行任何配置。你只需要仔细检查你的角色能不能做你想做的一切。
安装自动气象站 CDK
转到您的终端,使用以下命令安装 AWS CDK。
$ npm install -g aws-cdk
(可选)如果您需要更新 AWS CDK 版本,请运行
$ npm update -g aws-cdk
运行以下命令验证安装是否正确,并打印 AWS CDK 的版本号。
$ cdk — version
更新您的语言依赖
如果您收到一条错误消息,提示您的语言框架已过期,请使用以下命令之一来更新 AWS CDK 支持该语言所需的组件。
$ pip install — upgrade aws-cdk.core
创建您的项目目录并初始化 AWS CDK
让我们首先创建一个保存 AWS CDK 代码的目录,然后在该目录中创建一个 AWS CDK 应用程序。
$ mkdir cdk
$ cd cdk
$ cdk init — language python
$ source .env/bin/activate
$ pip install -r requirements.txt
您生成的cdk/cdk_stack.py
应该是这样的。
from aws_cdk import coreclass CdkStack(core.Stack):def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
super().__init__(scope, id, **kwargs)# The code that defines your stack goes here
构建并运行应用程序,并确认它创建了一个空堆栈。
$ cdk synth
您应该看到如下所示的堆栈,其中CDK-VERSION
是CDK
的版本,NODE-VERSION
是 Node.js 的版本。)
Resources:
CDKMetadata:
Type: AWS::CDK::Metadata
Properties:
Modules: aws-cdk=CDK-VERSION,[@aws](http://twitter.com/aws)-cdk/core=CDK-VERSION,[@aws](http://twitter.com/aws)-cdk/cx-api=CDK-VERSION,jsii-runtime=node.js/NODE-VERSION
添加 Amazon EC2 和 Amazon ECS 包
为 Amazon EC2 和 Amazon ECS 安装 AWS 构造库模块。
$ pip install aws_cdk.aws_ec2 aws_cdk.aws_ecs aws_cdk.aws_ecs_patterns
创建一个 Fargate 服务
使用 Amazon ECS 运行容器任务有两种不同的方式:
- 使用
Fargate
启动类型,Amazon ECS 为您管理运行容器的物理机器。 - 使用
EC2
启动类型,在这里进行管理,比如指定自动缩放。
对于本例,我们将创建一个运行在 ECS 集群上的 Fargate 服务,它由一个面向互联网的应用程序负载平衡器提供支持。在此基础上,我们将向该集群添加自动伸缩功能,并将策略附加到任务角色,以便容器能够使用 AWS Rekognition。
将以下 AWS 构造库模块导入添加到指定的文件中。
文件:cdk/cdk_stack.py
from aws_cdk import (
aws_ec2 as ec2,
aws_ecs as ecs,
aws_ecr as ecr,
aws_iam as iam,
aws_ecs_patterns as ecs_patterns,
core,
)
用下面的代码替换构造函数末尾的注释。
# Create a VPC
vpc = ec2.Vpc(
self, "WebDemoVPC",
max_azs = 2,
) # default is all AZs in region,
# but you can limit to avoid reaching resource quota# Create ECS cluster
cluster = ecs.Cluster(self, "WebDemoCluster", vpc=vpc)# Add an AutoScalingGroup with spot instances to the existing cluster
cluster.add_capacity("AsgSpot",
max_capacity=2,
min_capacity=1,
desired_capacity=2,
instance_type=ec2.InstanceType("c5.xlarge"),
spot_price="0.0735",
# Enable the Automated Spot Draining support for Amazon ECS
spot_instance_draining=True
)# Build Dockerfile from local folder and push to ECR
image = ecs.ContainerImage.from_asset('app')# Create Fargate service
fargate_service = ecs_patterns.ApplicationLoadBalancedFargateService(
self, "WebDemoService",
cluster=cluster, # Required
cpu=512, # Default is 256 (512 is 0.5 vCPU)
desired_count=1, # Default is 1
task_image_options=ecs_patterns.ApplicationLoadBalancedTaskImageOptions(
image=image,
container_port=8501,
),
memory_limit_mib=2048, # Default is 512
public_load_balancer=True) # Default is True# Add policies to task role
fargate_service.task_definition.add_to_task_role_policy(iam.PolicyStatement(
effect=iam.Effect.ALLOW,
actions = ["rekognition:*"],
resources = ["*"],
)
)# Setup task auto-scaling
scaling = fargate_service.service.auto_scale_task_count(
max_capacity=10
)
scaling.scale_on_cpu_utilization(
"CpuScaling",
target_utilization_percent=50,
scale_in_cooldown=core.Duration.seconds(60),
scale_out_cooldown=core.Duration.seconds(60),
)
设置 AWS CDK Python 脚本时需要考虑的一些事项
- CloudFormation 尚不支持 Fargate Spot 实例(截至 2020 年 5 月 31 日)
- 任务执行角色不同于任务角色。基本上,执行角色是执行 ECS 操作(如推和拉映像)的角色,任务角色是任务本身调用其他 AWS 服务(如 Rekognition、S3 等)所使用的角色。在 StackOverflow 问题中了解更多信息。
- 我们已经建立了一个 ECS 集群,它具有一个包含 spot 实例的自动扩展组,并且当 cpu 利用率增加到 50%以上时,可以启动多达 10 个新任务。你可以在这里阅读更多关于任务自动缩放的内容。
- 不要在每次想要部署项目时构建容器映像并将其推送到 ECR,您还可以从 ECR 存储库中提取一个现有的映像。你可以用
repository = ecr.Repository.from_repository_arn(
self, "{repository-name}",
"arn:aws:ecr:{region-name}:{account-id}:repository/{repository-name}")
image = ecs.ContainerImage.from_ecr_repository(repository=repository, tag="latest")
部署您的堆栈
当您的应用程序只有一个堆栈时,不需要指定堆栈名称,您可以运行
$ cdk deploy
如果您得到一个错误,如
This stack uses assets, so the toolkit stack must be deployed to the environment (Run “cdk bootstrap aws://unknown-account/unknown-region”)
然后,在运行cdk deploy
之前,您需要引导您的默认概要文件所使用的帐户。
$ cdk bootstrap
…
✅ Environment aws://{your-account-id}/{your-region-name} bootstrapped.
整个过程大约需要 10 到 20 分钟,因为我们也在将我们的容器映像推送到 ECR。一旦该过程成功结束,您应该会看到类似这样的内容:
✅ cdkOutputs:
cdk.WebDemoServiceLoadBalancerDNS******A5 = cdk-WebDemo-PV******KA7D-******197.eu-west-2.elb.amazonaws.com
cdk.WebDemoServiceServiceURL******7B = [http://cdk-WebDemo-PV******KA7D-******197.eu-west-2.elb.amazonaws.com](http://cdk-WebDemo-PV******KA7D-******197.eu-west-2.elb.amazonaws.com)Stack ARN:
arn:aws:cloudformation:eu-west-2:************:stack/cdk/c7f457f0-a34d-11ea-a167-******e602c
现在,当你打开浏览器,进入cdk.WebDemoServiceServiceURL
,你会看到你的应用程序。请注意,由于我们只为该任务分配了 0.5 个 vCPU,所以推断时间会很长,在 20 到 30 秒之间。但是您可以随时返回,更改这一点,并使用cdk deploy
重新部署。
恭喜你!您的应用程序现已上线😃
删除您的 AWS CDK 项目
如果你不再希望你的应用程序存在,你可能需要清除 AWS CDK 设置的所有东西,以避免招致任何意想不到的成本。
$ cdk destroy
参考
- 易,张,唐,张,徐,(2020)。超高分辨率图像修复的上下文残差聚合。arXiv 预印本 arXiv:2005.09704
图片包含在 **test_images**
文件夹中
image_1.jpg
,蒂姆·多弗勒,链接image_2.jpg
、巴特尔米·德·马泽诺德、链接image_3.jpg
、唐纳德·詹纳蒂、链接image_4.jpg
、韩亚库米、链接image_5.jpg
、纪尧姆·德·热尔曼、链接image_6.jpg
、帖木儿【罗马诺夫】、链接
用 Python 创建漂亮的架构图
实践教程
停止花费时间手动调整未对准的箭头
建立与代码从要点链接这里。
一些背景故事
本周早些时候,我偶然发现了一个 Python 库,它有一个非常吸引人的价值主张。这个库叫做图,正如它的名字一样,它创建图。这些生成的图表通常是我通过笨拙地将图像粘贴到 draw.io 或 Google 图表中而创建的,之后我会浪费几个小时来正确地对齐一切。除了那个令人疲惫的过程之外,当我后来需要更新这些图时,仅仅为了对架构的一些改变,就需要提升和移动超过一半的组件。在进一步研究了 library 之后,我发现它能够减轻我的痛苦。
开始使用您自己的图表
开始构建这些图的第一个要求是安装 Python 3.6 或更高版本。一旦是这种情况,你将需要安装 GraphViz,因为这是什么呈现的图表。Github 库实际上也有一个相当不错的“入门”部分,所以如果你需要帮助安装任何东西,请随意参考这里的。一旦用您最喜欢的 Python 包管理器安装了库“图表”,您就可以开始创建了。
对我来说,开始就像下面的命令一样简单,因为我满足了最初的要求。
组件类型
图形库为许多不同的提供者提供组件。以下可能是 14 个可用用例中最相关的。
- AWS/GCP/Azure —这些提供商公开了正式的云服务资产,您将在任何利用主要云提供商之一的图表中使用这些资产。我的团队主要在 GCP 工作,在偶然发现这个库之前,我会花几个小时手工构建这些图,所以当我发现这些节点资产唾手可得时,我有点兴奋。
- 通用和本地 —如果您希望以云不可知的方式说明底层技术,这些节点可能会一起使用。例如,通过显示 Google 数据流为一个架构提供一个 Beam 组件。
- 框架 —如果你想用编程语言说明一个节点,这些组件会很有用。
- SaaS——甚至有一个 SaaS 节点的集合,当你想显示你的架构有通知在 Slack 之类的地方着陆时,它会派上用场。
图表概念
图表 —图表是表示图表的主要对象。
节点——代表单个系统组件的抽象概念。
集群 —允许您将节点组织成组(或集群),而不是孤立的组件。
边 —表示节点之间的链接。
你的第一张图
现在你已经知道了基本概念,让我们按照我们学习这些概念的顺序,用代码构建一个极其简单的图表。我们将构建的示例图将是一个简单的 AWS 负载平衡网站,它使用 PostgreSQL 数据库和 Redis 缓存,因此我们可以使用多个组件提供者。
步骤 1:创建图表工作空间
这将简单地呈现一个带有指定标签的空白图,如下所示。
用 gist 链接的代码在这里构建。
步骤 2:添加节点
现在我们有了工作空间,是时候添加我们网站需要的节点了。我们要添加的节点来自两个不同的提供者。AWS 和 OnPrem 提供程序。如果你真的这样做,你可能会坚持使用 AWS,因为他们有 RDS 和 ElastiCache 等产品,你可能会与云提供商一起使用。
如您所见,我们不再有空白图表。我们的每一个节点都被描绘出来,这些是我们想要构建的架构的“成分”。接下来的步骤是将我们的一些节点组织成逻辑分组,然后用边连接每个节点。
用链接到这里的要点中的代码构建。
步骤 3:对节点进行分组(可选)
在本例中,我们将只对负载平衡的 web 服务器进行分组。在我过去创建的许多图表中,这并不总是必要的,但是随着您的体系结构的增长,将这些节点分组到集群中通常会增强可读性。
下面您可以看到,要做到这一点,我们只需要将节点的实例化移动到我们正在创建的集群的范围内。
如您所见,该图仍然只是一个节点列表,但是我们现在已经将适当的节点聚集到逻辑分组中。
用链接到这里的要点中的代码构建。
第四步:将所有内容联系在一起
在最后一步中,我们将不会链接我们刚刚安排在我们的体系结构中使用的节点。当我需要更新或者调整一个架构的时候,这个任务花费了我最长的时间。如果你看一下下面,它只是一个用双箭头定义流向每个节点的问题,你就完成了!在这个例子中,我们将只链接没有标签的节点,但是如果你看一下文档,将标签应用到你的链接是一个非常简单的任务。
生成的图像如下所示,您现在可以看到图中每个节点之间的逻辑流。通过更改定义节点的顺序,可以反转此流程。除了调整流程,你还可以改变很多东西,因为一个边缘对象包含三个属性:标签、颜色和样式。我们将不会涵盖如何在这里柚木这些。如果您有兴趣了解更多信息,本文末尾提供了文档链接,这些属性反映了相应的 graphviz edge 属性,如果您过去使用过该工具,这将使事情变得更容易。
用链接到这里的要点中的代码构建。
结论
现在你已经开始用代码构建一个漂亮的图表,当涉及到自动化的可能性时,利用这个工作流有很大的潜力,并且节省了架构图的一般维护的时间。
使用这个工具节省的时间会让我在将来使用这个方法。我当然不会错过手动调整图表、小心地将组件和箭头与我的架构的每一次迭代对齐所付出的努力。
我希望我钻研用代码构建图的经历是有趣的,并且对您未来的绘图工作可能有用。感谢阅读!
资源
用 Python 创建漂亮的交互式可视化
Plotly 和 Dash 入门
Plotly 是一个交互式的 Python 库,它提供了一个简单的界面,可以实现多种可视化。
Python 中有许多不同的可视化库。与 Matplotlib 相比,Plotly 与众不同的是其情节的交互性、可视化的丰富性和多样性、相对简单性,以及使用 Dash 模块将可视化部署为 web 应用的能力。
Plotly 工具套件有许多不同的部分,当我第一次开始使用它们时,我发现导航有点困难。在本文中,我想简单介绍一下 Plotly 的核心元素,包括标准绘图模块 Plotly express 和 Dash。除了一些简单的代码之外,还有让您快速使用这些工具的示例。
1.标准绘图
Plotly 可以 pip 安装。
pip install plotly
Plotly 可视化渲染为 HTML 文件。如果您在 Jupyter 笔记本上工作,并且想要直接渲染图像,您需要安装 ipywidgets 包。
pip install "notebook>=5.3" "ipywidgets>=7.2"
或者你用的是 JupyterLab。
pip install jupyterlab "ipywidgets>=7.5"
jupyter labextension install jupyterlab-plotly@4.9.0
Plotly 使用称为图形的数据结构,图形可以表示为字典,在这种情况下,您可以使用plotly.io
模块。或者作为通过plotly.graph_objects
模块呈现的图形对象。
图形对象通常被认为是比字典更好的选择,因为它们允许精确的数据验证,支持用于更新已经构建的图形的更高级的便利功能,并且图形对象的语法使得代码更紧凑。
让我们导入一个玩具数据集,并探索标准绘图的基本功能。下面的代码导入了波士顿房价数据集,这是一个流行的玩具数据集,用于 scikit-learn 库中的回归分析。
数据的前几行如下所示。
让我们使用图形对象模块来探索房价和房间数量之间的关系。你会注意到我正在使用我上面提到的助手功能来给可视化添加标题。
2.Plotly express
如果你需要创建一个定制的可视化,标准绘图模块是有用的。然而,如果你想创建一些非常标准的东西,比如上面显示的散点图,那么plotly.express
API 是最好的选择。
这个模块允许你在一行代码中为最常见的可视化创建完整的图形。它还能让你轻松控制颜色、风格和标签。
使用这个模块,我们只用一行代码就可以创建上面的散点图。颜色、标签和样式控制均可通过px.scatter
功能获得,轴标签会自动添加。
由plotly.express
提供的‘开箱即用’图表有大量不同的选项和控件,您可以在这里探索所有选项。
例如,下面的代码创建了一个直方图来显示 CHAS 变量的分布。我使用了histnorm
选项来应用标准化以更好地可视化分布,使用hover_data
选项来控制悬停时的交互。
3.破折号
Dash 也是 Plotly 工具套件的一部分,是一个用于开发数据分析仪表板的框架,所有 Plotly 可视化都可以轻松嵌入到应用程序中。
仪表板需要单独安装。
pip install dash
可以在 Jupyterlab 中显示 Dash 应用程序,但是您需要安装这个 JupyterDash 扩展。
pip install "jupyterlab>=1.0" jupyterlab-dash==0.1.0a3
jupyter labextension install jupyterlab-dash@0.1.0-alpha.3
或者,Dash 将在 localhost 上托管应用程序,当您运行代码时,该地址将显示在输出中。
无论何时fig.show
被用于显示可视化,使用 Plotly express 或标准绘图,你都可以将相同的绘图传递给 Dash。
Dash 应用程序的布局由app.layout
决定,它使用dash_core_components
和dash_html_components
的组合向仪表板添加图表、表格、交互性和文本。
下面显示的代码使用我们用plotly.express
创建的图表创建了一个基本的 Dash 应用程序。生成的仪表板如下所示。
Dash 应用程序最有用的一个方面是,您可以通过使用[callbacks](https://dash.plotly.com/basic-callbacks)
使您的仪表板具有交互性。核心组件模块包含各种不同的交互式组件,包括下拉菜单、滑块和文本框。
下面的代码向仪表板添加了一个下拉菜单,允许您过滤 RAD 特性以查看每个唯一值的分布。生成的仪表板显示在代码下方。
我最近发现自己开始使用 Plotly 作为我的首选可视化库,因为我发现你可以如此轻松地实现的分析质量是目前任何其他 Python 绘图库都无法比拟的。自从 Pandas 将 Plotly 添加为其绘图功能的可用后端后,情况就变得更加如此。
我以前写过这篇文章,概述了如何使用 Plotly 作为熊猫可视化的后端。如果您想将一些非常快速分析片段放在一起,这是非常有用的。
创建丰富的可视化和仪表板与熊猫绘图后端为 Plotly 和 Bokeh
towardsdatascience.com](/plotting-in-pandas-just-got-prettier-289d0e0fe5c0)
感谢阅读!
我每月都会发一份简讯,如果你想加入,请点击此链接注册。期待成为您学习旅程的一部分!
如何使用 Plotly、Python 创建二项式分布图
有时,Python 图表是您的论点或您试图构建的数据案例的必要元素。本教程是关于创建二项式或正态分布图。我们将从声明一个二项式分布的数字数组开始。我们只需从 scipy.stats 导入 binom 就可以做到这一点。
from scipy.stats import binom
n = 1024
size = 1000
prob = 0.1
y = binom.rvs(n, prob, size=size)
这段代码生成 1000 个数字,共 1024 次,成功概率为 0.1。一旦完成了这个,接下来我们要计算数组中数字的频率。我们可以通过将此作为数据帧并使用以下逻辑创建频率仓来实现这一点。
import numpy as np
import pandas as pd# Creating X array for numbers between the maximum and minimum values of y and making it a dataframe
x = np.arange(y.min(), y.max())
xx = pd.DataFrame(x)# Making y a dataframe and generating an empty array yy
d = pd.DataFrame(y, columns = ['Data'])
yy = []# Calculating frequency of all numbers between maxiumum and minimum values
for k in range(len(x)):
yy.append(d[d['Data'] == x[k]].count()[0])# Making frequency data frame and concatenating it with the xx
freq = pd.DataFrame(yy, columns=['Frequency'])
data = pd.concat([xx, freq], axis=1)
data.columns = ['Score', 'Frequency']
现在我们有了分数和频率箱。我们可以使用 plotly.graph 使用这些数据生成一个二项式图。
import plotly.graph_objects as go
fig = go.Figure( # Loading the data into the figur
data=[go.Scatter(x=data['Score'], y=data['Frequency'],
mode="lines",
line=dict(width=2, color="blue"))], # Setting the layout of the graph
layout=go.Layout(
xaxis=dict(range=[y.min(), y.max()], autorange=False),
yaxis=dict(range=[data['Frequency'].min(), data['Frequency'].max()], autorange=False),
title="Binomial Curve",
updatemenus=[dict(
type="buttons",
buttons=[dict(label="Play",
method="animate",
args=[None])])]
))
fig.show()
下图是使用上面的代码生成的。
正如我们所看到的,曲线展示了一个基本的二项式行为,有很多噪声,随机徘徊在预期路径的上方和下方。但是通过重复这个过程很多次并平均结果,它可以很容易地变成一个完整的二项式图。在我的例子中,我执行了 1500 次上述步骤。请查看下面的代码:
n = 1024
size = 1000
prob = p / 10
x = np.arange(70, 135)
yy = []
tt = []# Repeating the step 1500 times, rest code is same as above
for a in range(1500): y = binom.rvs(n, prob, size=size)
d = pd.DataFrame(y, columns = ['Data'])
for k in range(len(x)):
yy.append(d[d['Data'] == x[k]].count()[0])
tt.append(yy)
yy = []
y = []kk = pd.DataFrame(tt).T
y = kk.mean(axis=1)
N = len(y)
上面的代码生成了一个新的数组“y ”,它对数据中所有分数的频率进行了平均。我们可以使用下面的代码生成一个新的数据框并查看数据:
data = pd.DataFrame([x,y]).T
data.columns = ['Score', 'Frequency']
data.head()
使用 plotly 代码再次绘制这些数据,我们得到了一个好看的二项式图。
有了上面的图表,我们可以对数据做更多的处理,比如我们可以用 plotly 来制作图表的梯度或它在每一点的导数的动画。
任何一点的导数都可以用下面的公式进行数值计算。
我们可以使用 pandas 实现这个公式,计算所有相关点的梯度值。
# Declaring an empty array
deri = []# Setting first derivative to zero
fir = 0
deri.append(fir)# Calculating the derivative all points other than first and last points
for a in range(1,64):
diff = (data['Frequency'][a+1] - data['Frequency'][a-1])/2
deri.append(diff)# Setting last derivative to zero
end = 0
deri.append(end)der = pd.DataFrame(deri, columns = ['Derivatives'])
data = pd.concat([data, der], axis = 1)
请注意,我们特意将零作为数据中第一个和最后一个点的值。这样做是因为导数公式需要前值和后值。第一个值缺少前一个值,最后一个值缺少后一个值。此后,为了方便起见,两者都保持为零。
现在我们有了导数,我们需要计算我们需要在 plotly 上制作动画的渐变线的开始和结束坐标。
sx = []
sy = []
ex = []
ey = []
Gap = 3.5for b in range(0,65):
#Computing Start Coordinates
ssx =data['Score'][b] - Gap
sx.append(ssx)
ssy = data['Frequency'][b] - Gap * data['Derivatives'][b]
sy.append(ssy)
#Computing End Coordinates
eex = data['Score'][b] + Gap
ex.append(eex)
eey = data['Frequency'][b] + Gap * data['Derivatives'][b]
ey.append(eey)cord = pd.DataFrame([sx, sy, ex, ey]).T
cord.columns = ['XStart', 'YStart', 'XEnd', 'YEnd']
现在我们已经完成了,我们可以可视化产生的动画。
此外,如果我们想要在该图上标记区域并添加文本,我们可以使用下面的代码片段轻松完成。
fig.add_trace(go.Scatter(x=[70,85,85,70], y=[0,0,50,50], fill='toself', mode='lines', line_color='#FF5A5F', opacity = 0.3))
fig.add_trace(go.Scatter(x=[85,102,102,85], y=[0,0,50,50], fill='toself', mode='lines', line_color='#C81D25', opacity = 0.3))
fig.add_trace(go.Scatter(x=[102,119,119,102], y=[0,0,50,50], fill='toself', mode='lines', line_color='#0B3954', opacity = 0.3))
fig.add_trace(go.Scatter(x=[119,135,135,119], y=[0,0,50,50], fill='toself', mode='lines', line_color='#087E8B', opacity = 0.3))fig.add_trace(go.Scatter(
x=[77.5, 93.5, 110.5, 127],
y=[40, 40, 40, 40],
mode="text",
name="Regions",
text=["Low Risk", "High Risk", "Stabilization", "Recovery"],
textposition="top center",
textfont=dict(
family="sans serif",
size=20,
color="black"
)
))fig.show()
我们最终得到下图。
如果你仍然对我在做什么感到好奇,请看看我的下一个博客,在这里,所有这些技术都被用来可视化“新冠肺炎的全球地位”。敬请期待,干杯。
二项式曲线的完整 Jupyter 笔记本实现可以在这里找到。
通过使用 Python 抓取 Google Play 应用评论来创建用于情感分析的数据集
了解如何收集 Android 应用的评论,并使用这些信息建立一个用于情感分析的数据集
马库斯·温克勒的照片
TL;DR 了解如何通过收集 Android 应用程序的用户评论来创建用于情感分析的数据集。您需要将应用程序和检查信息转换为数据框,并将其保存为 CSV 文件。
“成功创造人工智能将是人类历史上最大的事件。不幸的是,这也可能是最后一次,除非…
leanpub.com](https://leanpub.com/getting-things-done-with-pytorch)
您将学习如何:
- 为数据集设置目标和包含标准
- 通过抓取 Google Play 获得真实世界的用户评论
- 使用 Pandas 将数据集转换并保存为 CSV 文件
设置
让我们安装所需的包并设置导入:
数据集的目标
你希望你的应用得到反馈。消极和积极都是好的。但是消极的一面可能会暴露出您的服务所缺少的关键特性或停机时间(当它更加频繁时)。
幸运的是,Google Play 有大量的应用程序、评论和分数。我们可以使用 google-play-scraper 包收集应用信息和评论。
你可以选择大量的应用程序进行分析。但是不同的应用类别包含不同的受众、特定领域的怪癖等等。我们从简单的开始。
我们想要已经存在一段时间的应用程序,因此可以有机地收集意见。我们希望尽可能减少广告策略。应用程序不断更新,因此审查的时间是一个重要因素。
理想情况下,您会希望收集所有可能的评论并加以利用。然而,在现实世界中,数据通常是有限的(太大、不可访问等)。所以,我们会尽力而为。
让我们从生产力类别中选择一些符合标准的应用。我们将使用 AppAnnie 选择一些美国顶级应用:
抓取应用程序信息
让我们收集每个应用程序的信息:
我们得到了所有 15 个应用程序的信息。让我们编写一个助手函数,它可以更好地打印 JSON 对象:
以下是列表中的应用程序信息示例:
这包含了许多信息,包括评级数量,评论数量和每个分数的评级数量(1 到 5)。让我们忽略所有这些,看看它们美丽的图标:
我们数据集中的应用图标
我们将通过将 JSON 对象转换成 Pandas 数据帧并将结果保存到 CSV 文件中来存储应用程序信息,以备后用:
抓取应用评论
在一个理想的世界里,我们会得到所有的评论。但是有很多,我们正在搜集数据。那不太礼貌。我们做什么呢
我们想要:
- 平衡数据集—每个分数的评论数量大致相同(1-5)
- 每个应用的代表性评论样本
我们可以通过使用刮包选项过滤复习分数来满足第一个要求。对于第二个问题,我们将根据评论的有用性对其进行排序,这是 Google Play 认为最重要的评论。为了以防万一,我们还会从最新的数据中获取一个子集:
请注意,我们将应用 id 和排序顺序添加到每个评论中。这里有一个例子:
repliedAt
和replyContent
包含开发人员对评审的回应。当然,他们可能会失踪。
我们获得了多少应用评论?
15750
让我们将评论保存到 CSV 文件中:
摘要
干得好!您现在拥有一个数据集,其中包含来自 15 个生产力应用程序的超过 15k 条用户评论。当然,你可以疯狂地得到更多。
“成功创造人工智能将是人类历史上最大的事件。不幸的是,这也可能是最后一次,除非…
leanpub.com](https://leanpub.com/getting-things-done-with-pytorch)
您学习了如何:
- 为数据集设定目标和期望值
- 抓取 Google Play 应用程序信息
- 收集 Google Play 应用的用户评论
- 将数据集保存到 CSV 文件
接下来,我们将使用这些评论对 BERT 进行情感分析。但是首先,我们必须做一些文本预处理!
参考
最初发表于https://www.curiousily.com。
使用 Python 的桌面通知应用程序只需 5 分钟
在本文中,您将学习使用 python 通过几个简单的步骤为您的 PC 创建一个定制的桌面通知程序。
照片由 Cookie 在 Unsplash 上的 Pom 拍摄
介绍
你有没有尝试过根据自己的需求创建一个桌面通知应用程序?您知道使用 python 只需几个简单的步骤就可以做到这一点吗?
不要担心,让我们从头开始,在本文中,我们将创建一个桌面通知应用程序,用于获取可怕的冠状病毒的每日统计数据。
你从这篇文章中学到了什么
- 安装所需的 python 包。
- 从网上读取冠状病毒数据。
- 创建桌面通知应用程序。
- 让你的程序在后台运行。
我们开始吧
安装需要的 python 包
我们需要为这个应用程序下载两个重要的包。
**注意:**如果您使用 Windows,您需要在命令提示符下键入这两个命令;如果您使用 Linux,您需要在终端上键入这两个命令
- 请求(从 web 获取数据)
**pip install requests**
2.plyer(用于在您的电脑上创建通知)
**pip install plyer**
从网络上读取冠状病毒数据
我们可以使用下面提供的 URL 获取冠状病毒数据,您可以自由地将国家名称替换为您自己的国家名称,对于此应用程序,我们将使用印度的冠状病毒数据。
**https://corona-rest-api.herokuapp.com/Api/india**
网站看起来像这样
图片由 Satya Ganesh 提供
创建桌面通知程序
到目前为止,我们已经获得了构建这个应用程序所需的所有工具,所以现在让我们编写这个应用程序的代码
注意:如果你在离线编译器中编写这个代码,会比在线编译器更容易,因为在本文的后面,我们会让这个应用程序在你的 PC 上作为后台进程运行,如果你在在线编译器中运行,那么你需要下载文件,而在离线编译器中这是不必要的。我会建议用 Visual Studio。
part1(导入库)
第二部分(从 web 上检索数据)
part3(创建自定义通知)
就这样,我们准备运行我们的应用程序,在实际运行我们的应用程序之前,您需要了解一些您可以进行的更改,以便根据您的需求定制您的应用程序。
超时—告知通知应该在桌面上显示多长时间
time.sleep ()—告知通知应在多长时间间隔后弹出
下面是您在运行应用程序后看到的通知。
图片由 Satya Ganesh 提供
让你的应用在后台运行
因此,您最终创建了一个 python 应用程序,当您运行它时,它运行良好。但是你不觉得这是一项繁琐的工作吗,每次运行你的应用程序都要得到一个通知?
这里有一个解决方案,你可以通过在你的电脑上运行你的应用程序作为后台进程来实现自动化。
如何让一个 python 应用在后台运行?
只需按照这个简单的命令让您的应用程序在后台运行,注意,如果您使用的是 Windows,您需要在命令提示符下键入这个命令;如果您使用的是 Linux,您需要在终端上键入这个命令。
注意: 用你的文件名替换<你的文件名
*pythonw.exe .\<your-file-name-here>example pythonw.exe .\desktopNotifier.py*
就这样,您的应用程序现在开始在后台运行
你如何确认你的应用在后台运行?
在你的电脑中打开任务管理器,你可以看到在后台进程中你可以看到 python 正在运行
图片由 Satya Ganesh 提供
如何停止接收通知?
很简单,在任务管理器中杀死名为 python 的进程。如果你觉得停止通知有任何困难,请在这篇文章的评论部分发表你的困难。
其他可以使用这种方法的领域
- 每日通知吃药。
- 每小时通知喝水。
更多的是,如何使用这个应用程序完全取决于你。
结论
我希望这篇文章引起了您创建自己的定制桌面通知应用程序的兴趣。这个应用程序适用于任何操作系统,无论是 Windows、Linux 还是 Mac。如果您想要一个更简单的桌面通知应用程序,请在本文的评论部分提问
感谢您的阅读😄过得愉快
创建哑铃图以直观显示 R 中的组差异
冠状病毒(也称为新冠肺炎)是一种疫情。截至本文撰写之时,已有近 6000 人死亡,另有 15 万人(T2)被感染。所有迹象似乎表明,病毒只是在增长。
但是一些团体不像其他团体那样担心新冠肺炎。昆尼皮亚克大学最近的民调显示,对冠状病毒的担忧与个人的党派身份、年龄和种族有关。
让我们想象一下,看看差异有多明显。我使用哑铃状点状图,因为它们是可视化两个群体(例如共和党和民主党)之间差异的一些最有力的工具。
政治派别
与民主党人相比,共和党人对冠状病毒的担忧要少得多。这在两个方面是正确的。首先,关于被感染的担忧:
当我们关注新冠肺炎会不会扰乱一个人的生活时,情况也是如此:
看第一个图,我们注意到共和党人说他们“根本不担心”冠状病毒感染他们或他们认识的人的可能性是民主党人的三倍。相比之下,民主党人说他们“非常担心”同样风险的可能性几乎是共和党人的三倍。
第二幅图向我们展示了对破坏的恐惧的类似趋势:四分之三的民主党人担心(非常或有点)新冠肺炎会破坏他们的日常生活,相比之下,只有 38%的共和党人担心。虽然 26%的民主党人不担心分裂,但 61%的共和党人也是如此。
年龄
年龄和对冠状病毒的恐惧也有关系。
这些图表显示,不同年龄的人在担忧方面存在显著差异,但对分裂的恐惧比对感染的恐惧更普遍。第一个情节表明每个年龄段的人都害怕新冠肺炎会打乱他们的日常生活;尽管年轻人表达这种情绪的频率较低。第二个情节大多数 50 岁以下的人并不担心新冠肺炎感染的可能性。年龄较大的受访者则相反;65 岁及以上的人更有可能受到感染风险的影响(62%对 37%)。
为什么是哑铃情节?
哑铃图是分组条形图的替代方法。像条形图一样,它们显示了人群之间的差异,并且更有力地代表了两个群体之间的 T2 距离。他们经常被调查研究公司使用,如皮尤研究中心,如这个例子所示:
虽然条形图需要八个条来可视化上面的每个数据点,但哑铃点图在四条线上显示八个点*,减少混乱并强调组之间的差异。*
这里有另一个例子,这次来自 Axios (可视化 2017 年 1 月至 10 月总统不支持率的变化):
这个伪哑铃情节(端点怪异的哑铃;别捡那一边!)有 50 个‘组’(美国各州),但只有两个结果(1 月和 10 月)。在这种情况下,哑铃图远远优于组合条形图,因为它强调两个时间段之间的差异,并且它使用的对象比条形图少(50 条线而不是 100 条线)。
从上面的例子中得到一个关键的教训:如果利益的比较是在两个群体之间(例如,共和党和民主党),或者如果利益的结果是双重的(例如,“关注”和“不关注”),点状图是可视化数据的一种更好的方式。
让我们在 R 中制造它!
现在是时候做自己的哑铃点状图了。我们将创建这个,即:
作为参考,我使用的数据如下所示:
很简单,对吧?顺便说一下,它来自这里。
这个过程依赖于 Bob Rudis 的ggalt
包和geom_dumbbell
函数,它们完成了大部分繁重的工作。本教程主要是在这里找到的 Rudis 的代码的一步一步的再创造。
为了方便起见,在开始之前,让我们先定义一些东西:
blue <- "#0171CE"
red <- "#DE4433"
除了颜色,我们还创建了一个 hack-y 函数,允许我们有选择地标记点(再次感谢 Bob Rudis 的这个):
percent_first <- function(x) {
x <- sprintf("%d%%", round(x*100))
x[2:length(x)] <- sub("%$", "", x[2:length(x)])
x
}
第一步:准系统
我们从一个基本的ggplot
对象开始。在geom_segment
中,我们定义了伪网格线(每个关注“级别”一条)。
library(ggplot2)
library(ggalt)
library(tidyverse)
ggplot() +
geom_segment(data=infected, aes(y=concerned, yend=concerned, x=0, xend=.5), color="#b2b2b2", size=0.15)
这里,geom_segment
创建了大小为 0.15 的灰色线条。线条的跨度从 0 到 0.5。这根据您的数据而变化;因为我们正在处理的最大数字是. 43(代表 43%的民主党人),所以我们右侧的界限可以是 0.5;这也为我们稍后创建的差异列留出了空间。
然后,geom_dumbbell
读入我们的数据并创建哑铃:我们指定每个哑铃的开头 ( x
)代表共和党,而结尾 ( xend
)对应民主党。其他规格影响伴随的线和点。
geom_dumbbell(data=infected, aes(y=concerned, x=rep, xend=dem),
size=1.5, color="#b2b2b2", size_x=3, size_xend = 3, colour_x = red, colour_xend = blue)
该代码创建了以下情节:
我们已经可以开始看到最终版本的框架:每个哑铃代表一个关注级别,并可视化共和党和民主党在该级别的比例。
第二步:标签
下一步是创建“共和党”和“民主党”标签(以防颜色不够,或者图像是黑白的!).
我们可以用下面的代码创建标签:
geom_text(data=filter(infected, concerned=="Very concerned"),
aes(x=dem, y=concerned, label="Democrats"),
color=blue, size=3, vjust=-1.5, fontface="bold", family="Lato") +
geom_text(data=filter(infected, concerned=="Very concerned"),
aes(x=rep, y=concerned, label="Republicans"),
color=red, size=3, vjust=-1.5, fontface="bold", family="Lato")
希望这段代码非常直观。因为我们只显示标签一次,所以我们在geom_text
的data
参数中指定一个过滤器。如果我们想只显示底层关注的标签,我们可以指定data=filter(infected, concerned=="Not concerned at all")
。
我们将每个点标上各自的政治归属,并根据点的颜色指定颜色。剩下的只是对文字的小美化。
我们还必须为值添加直接标签,以便每个组的确切百分比清晰可见:
geom_text(data=infected, aes(x=rep, y=concerned, label=percent_first(rep)),
color=red, size=2.75, vjust=2.5, family="Lato") +
geom_text(data=infected, color=blue, size=2.75, vjust=2.5, family="Lato",
aes(x=dem, y=concerned, label=percent_first(dem)))
在这里,我们利用我们之前定义的函数percent_first
,因为我们只希望百分比出现在第一个数字上(以减少混乱)。其余的标签只是代表百分比的数字。这里的语法是简单的语法,应该为ggplot
用户所熟悉。它会创建以下输出:
第三步:差异栏
最后,我们想帮助我们的观众看到民主党和共和党之间的差异到底有多明显。我们通过差异列来实现这一点。
geom_rect(data=infected, aes(xmin=.5, xmax=.6, ymin=-Inf, ymax=Inf), fill="grey") +
geom_text(data=infected, aes(label=paste0(diff*100, "%"), y=concerned, x=.55), fontface="bold", size=3, family="Lato") +
geom_text(data=filter(infected, concerned=="Very concerned"),
aes(x=.55, y=concerned, label="Difference"),
color="black", size=3.1, vjust=-2, fontface="bold", family="Lato") +
scale_x_continuous(expand=c(0,0), limits=c(0, .625)) +
scale_y_discrete(expand=c(0.2,0))
这里,我们首先创建一个带有geom_rect
的灰色矩形。它垂直跨越了整个图表,这就是为什么ymin
和ymax
的范围从负无穷大到正无穷大。接下来,我们根据差异列创建标签。我们根据关注程度(我们的 y 轴)对它们进行定位。最后,我们扩展了图表的边界,使它看起来更漂亮一些:
第四步:标题、标签和说明
最后,让我们添加标题、副标题、题注和轴标签:
labs(x=NULL, y=NULL, title="Republicans are less worried about COVID-19",
subtitle="How concerned are you that you or someone you know will be infected with the coronavirus?",
caption="Source: Quinnipiac University Poll, March 9, 2020\. Q27\n\nDesign: Connor Rothschild")
那是我们的阴谋!可惜它有点丑。让我们在最后一步解决这个问题。
步骤 5:美化
使用theme
参数进行美化。
theme_bw(base_family="Lato") +
theme(
panel.grid.major=element_blank(),
panel.grid.minor=element_blank(),
panel.border=element_blank(),
axis.ticks=element_blank(),
axis.text.x=element_blank(),
plot.title=element_text(size = 16, face="bold"),
plot.title.position = "plot",
plot.subtitle=element_text(face="italic", size=12, margin=margin(b=12)),
plot.caption=element_text(size=8, margin=margin(t=12), color="#7a7d7e")
)
在指定了我们的基本ggplot
主题theme_bw
之后,我们使用theme()
来指定一系列的参数。
为了简化,上面的代码:
- 删除网格线(
panel.grid.major
,panel.grid.minor
) - 移除面板边框(
panel.border
) - 删除轴记号和轴文本(
axis.ticks
、axis.text.x
) - 定位轴绘图、副标题和标题,并设置它们的样式(
plot.title
、plot.title.position
、plot.subtitle
、plot.caption
)。
我们的最终产出:
总结
我们的过程看起来像这样:
上述可视化的代码,以及底层数据集和输出,可以在这里找到。
感谢阅读!
康纳·罗斯柴尔德的最新推文(@CL_Rothschild)。数据科学和公共政策。使用内部字体系列…
twitter.com](https://twitter.com/CL_Rothschild)
原载于我的 博客 。
创建有效的比例数据可视化
在各种数据集规模下,查看个体对整体的贡献以及随时间变化的最佳方式—(包括简单、直观的演示、代码和数据)
比例的各种可视化
绘制整体的比例可能是数据可视化中最常见的任务之一。例子包括幸福度、经济指标或犯罪的地区差异,投票模式、收入或支出的人口统计学差异,或者企业各部分对其底线的贡献。通常,数据还描述了随时间的变化,时间可能是几个月、几个季度、几年或几十年。
尽管它们都与整体的比例有关,但通常没有一种放之四海而皆准的方法适用于所有情况。
在这篇文章中,我描述了我认为的交流整体比例的有效技巧,以及随着时间的推移对它们的改变。我还将探讨随着数据点或数据系列数量的变化,图表有效性的变化。
和往常一样,这篇文章还将包括一些例子,这样你就可以跟随并创建你自己的、有趣的数据可视化。
对于代码,我将使用著名的 Gapminder 数据集,以及上赛季多伦多猛龙队篮球投篮份额的一些数据。这些只是显示比例的数据集的例子,所以你不需要知道任何关于经济学或篮球的知识就能跟上。
在开始之前
数据
我将代码和数据包含在我的git lab repo here(viz _ proportions目录)中。所以请随意使用它/改进它。
包装
我假设您熟悉 python。即使你相对较新,这个教程也不应该太难。
你需要pandas
和plotly
。用一个简单的pip install [PACKAGE_NAME]
安装每一个(在你的虚拟环境中)。
想象简单的比例
加载和检查数据
很方便的是,plotly
包提供了一些玩具数据集供我们使用, Gapminder 数据集就是其中之一。我们可以加载:
import plotly.express as px
gap_df = px.data.gapminder()
用gap_df.info()
和gap_df.head()
检查数据,我们会看到它显示了每年多个国家的数据。
它包括人口和人均 GDP——所以让我们将两者相乘得到 GDP 数据。
gap_df = gap_df.assign(gdp=gap_df['pop'] * gap_df['gdpPercap'])
仅可视化一年的数据
对于第一次观想,让我们比较几种不同类型的图表。最初的数据包括 142 个国家 1952 年的数据。让我们简化数据,按大洲收集数据,并且只将最近一年的数据收集到cont_df
中。
year_df = gap_df[gap_df.year == max(gap_df.year)]
cont_df = year_df.groupby('continent').agg({'gdp': 'sum'})
cont_df.reset_index(inplace=True)
这里,数据帧按洲分组,并重置索引,因为在 Plotly Express 中处理“平面”数据帧更容易。
现在可以使用 Plotly Express 绘制数据。绘制这些基本图形的代码非常简单。我注意到,对于气泡图,我添加了一个名为dataType
的任意变量,这样它就可以用来在 Y 方向上对齐气泡。
# Pie chart
fig = px.pie(cont_df, values='gdp', names='continent')
fig.show()
# Bar chart
fig = px.bar(cont_df, color='continent', x='continent', y='gdp')
fig.show()
# Horizontal bar chart - stacked
fig = px.bar(cont_df, color='continent', x='gdp', orientation='h')
fig.show()
# Bubble chart
fig = px.scatter(cont_df.assign(dataType='GDP'), color='continent', x='continent', y='dataType', size='gdp', size_max=50)
fig.show()
我在这里收集了结果:
简单比例数据的图表类型比较
除了柱形图之外,所有的图表都不能很好地表明相对大小。
当数据点的大小接近时,如亚洲、美洲、欧洲的 GDP 数据,堆积条形图和饼图不允许数据点之间的简单比较,因为它们是从不同的参考开始的。
饼状图也有问题,因为众所周知,角度的差异很难准确感知,所以我们会忽略它们。
气泡图稍好一些,但是因为气泡的大小与数据集的大小有关,所以半径的差异变得比柱形图小(小一个平方根)。
当我们增加一个时间维度时会发生什么?
随着时间的推移可视化数据
对于这一部分,我们需要一个包含多年数据的数据框架。我们可以使用整个数据集,但让我们保持简单,只使用少量年份的数据。
数据集包含多个年份,但不是每个年份。我们可以使用gap_df.year.unique()
来查看哪些年份的数据可用,选择 1985 年以后的年份,这是五个不同的年份。
我们的汇总数据框架可以构建如下:
mul_yrs_df = gap_df[gap_df.year > 1985]
mul_yr_cont_df = mul_yrs_df.groupby(['continent', 'year']).agg({'gdp': 'sum'})
mul_yr_cont_df.reset_index(inplace=True)
groupby
方法将创建一个多索引数据帧,它可以被认为是(continent, year)
的嵌套索引(如果您想了解更多关于层次/多索引的知识,这是一个很好的资源)。然后,在我们绘制它们之前,指数再次变平。
# Bar chart
mul_yr_cont_df = mul_yr_cont_df.assign(yrstr=mul_yr_cont_df.year.astype(str))
fig = px.bar(mul_yr_cont_df, color='continent', y='gdp', x='yrstr', barmode='group')
fig.show()
# Horizontal bar chart - stacked
fig = px.bar(mul_yr_cont_df, color='continent', x='gdp', orientation='h', y='yrstr')
fig.show()
# Bubble chart
fig = px.scatter(mul_yr_cont_df, y='continent', x='yrstr', color='continent', size='gdp', size_max=50)
fig.show()
分组列
堆积条形图
泡泡图
有了这些,前面的属性仍然适用于在条形图中看到相对比例的容易程度。但是,通过在数据中增加另一个维度,可以进行新的观察。
虽然每个系列的大小仍然很难比较,但堆积条形图能够显示整体样本大小的变化,这一点很有价值。
就分组条形图而言,沿 x 轴分组变得很重要,因为不同组之间的比较变得更加困难,而同一组内的比较仍然很容易。尝试绘制和比较这两个:
fig = px.bar(mul_yr_cont_df, color='continent', y='gdp', x='yrstr', barmode='group')
fig.show()
fig = px.bar(mul_yr_cont_df, color='yrstr', y='gdp', x='continent', barmode='group')
fig.show()
对各大洲的比较进行优先排序
跨年度优先比较
在上图中,跨年度的比较优先于跨洲的比较,反之亦然。
对于跨两个轴的比较,气泡图将数据排列在网格中,这使得跨两个维度比较变化更加容易。
如果气泡图中的大小变化不够明显,条形图的网格(子图)可能会更好:
fig = px.bar(mul_yr_cont_df, color='continent', facet_col='continent', x='gdp', orientation='h', facet_row='yrstr')
fig.update_yaxes(showticklabels=False)
fig.show()
网格支线剧情
太好了。但是通常每个轴上有 5 个数据点。那么,如果级数增加会怎么样呢?
可视化更大的数据集
让我们针对 12 年数据集的所有数据重复这些图(为简洁起见,此处未显示代码—参见 git repo)。
在这里,我们已经开始看到分组条形图的一些空间限制。不同组之间的比较也变得越来越困难,因为单个条形在高耸的彩色条形森林中迷失了,相邻条形的相对变化欺骗了我们的大脑。
尽管这个数据集在视觉上随着规模相对很好地缩放,这得益于 GDP 随时间的增长,但很容易看出其局限性。
最后一点,让我们来看看一个更大的、有序度更低的数据集。
奖励剧情:篮球投篮股份(2019 多伦多猛龙)
在一个 NBA 赛季的 82,48 分钟的规定时间里,一支球队要投篮 7000 次。在多伦多猛龙队的情况下,他们有 14 名球员至少获得 1%的投篮命中率。由此产生的 15 名“球员”(14 + 1 名“其他人”)如下所示,分为每 2 分钟一段。
这个数据集也与上面略有不同,因为我将展示百分比的分布。
在上述每种情节类型中,它们看起来是什么样的?
分组条形图
堆积条形图
网格条支线剧情
泡泡图
随着数据点在两个维度上变得越来越多,并且随着最大值与最小值之比的增加,网格中的气泡图开始发挥作用。
在气泡图中,条形图中 1 到 25 的高度变化变成了 1 到 5 的半径变化。事实上,尺寸的变化转化为半径的变化有效地压缩了视觉差异,并有助于显示更大的范围。它(以及条形子图方法)还有一个额外的优势,即能够将第四个变量演示为颜色,因为空间位置指定了它的两个维度。
您可能会发现,随着数据集变大,尤其是数据集变大,我更喜欢这种类型的子图方法。但是正如你之前看到的,在其他情况下,其他类型的观想效果明显更好。
那么——选择什么呢?
你可能已经看到了这一点,但在我看来,没有“一刀切”的方法。我甚至还没有开始在视觉比例方面触及这个领域的表面——比例、使用颜色的不同方法、符号类型、利用整体分布形状和突出比例等。
但我希望这些例子至少对你了解不同类型的观想有用,以及它们的功效如何随着样本大小而变化。我发现没有什么比练习更能真正学习数据可视化并变得更好了。所以,选择一个数据集,然后去做——你对这个主题领域越熟悉越好。
如果你喜欢这个,比如说👋/在 twitter 上关注,或关注更新。我还写了这篇关于我最喜欢的数据可视化书籍的文章,如果你以前没有读过的话:
如果没有交流,好的分析没有什么意义。数据可视化会有所帮助。以下是我对…的建议
towardsdatascience.com](/create-impactful-data-visualizations-with-these-books-ca9fbfecfde5)
同样,这也是一个大众的最爱:
[## 如何用 Python 可视化数据中的隐藏关系 NBA 助攻分析
使用交互式快照、气泡图和桑基图操纵和可视化数据,使用 Plotly(代码和数据…
towardsdatascience.com](/how-to-visualize-hidden-relationships-in-data-with-python-analysing-nba-assists-e480de59db50)
下次见!
使用 Gretel.ai 和 Python 在您的云中创建高质量的合成数据
创建差异私有、合成版本的数据集;同时满足法规遵从性要求,将敏感数据保留在您批准的环境中。
无论您关注的是医疗保健行业的 HIPAA 、金融行业的 PCI ,还是保护消费者数据的 GDPR 或 CCPA ,能够在不需要与 SaaS 服务合作的数据处理协议 (DPA)的情况下开始构建,可以显著减少启动项目和开始创造价值所需的时间。今天,我们将通过一个示例,在本地(您的云或内部)配置中使用 Gretel.ai 来生成高质量的合成数据和模型。
来源:设计单元格,通过 iStockPhoto
设置您的本地环境
要开始,你只需要三样东西。
- 要以 CSV 或 Pandas 数据帧格式合成的数据集
- Gretel.ai API key(免费)
- 本地计算机/虚拟机/云实例
**推荐设置。**我们推荐以下硬件配置:CPU:合成记录生成推荐 8+ vCPU 核。GPU:建议培训使用支持 CUDA 10.x 的 Nvidia Tesla P4。RAM: 8GB+。操作系统:Ubuntu 18.04 支持 GPU,或 Mac OS X(Mac 不支持 GPU)。
GPU 加速参见 TensorFlow 优秀的设置指南。虽然 GPU 不是必需的,但在 GPU 上进行训练通常比在 CPU 上快至少 10 倍。或者在 CPU 上运行并获取一个☕.
生成 API 密钥
使用 API 密匙,您可以免费访问 Gretel 公共测试版的高级功能,这些功能增强了我们的开源库用于合成数据生成,具有改进的字段间相关性、自动化合成数据记录验证以及合成数据质量报告。
用 Github 或谷歌邮箱登录或创建一个免费账户到 Gretel.ai 。点击右上角的个人资料图标,然后点击 API 键。生成一个新的 API 令牌并复制到剪贴板。
在 https://console.gretel.cloud 生成 API 密钥
设置您的系统并安装依赖项
我们建议为您的运行时设置一个虚拟 Python 环境,以保持您的系统整洁,在这个示例中,我们将使用 Anaconda 包管理器,因为它对 Tensorflow 、GPU 加速和数千个数据科学包提供了强大的支持。你可以在这里下载并安装 Anacondahttps://www.anaconda.com/products/individual。
创建虚拟环境
conda install python=3.8
conda create --name synthetics python=3.8
conda activate synthetics # activate your virtual environment
conda install jupyter # set up notebook environment
jupyter notebook # launch notebook in browser
安装所需的 Python 包
将 gretel-synthetics 、Tensorflow、Pandas 和 Gretel helpers(需要 API 密钥)等依赖项安装到新的虚拟环境中。将下面的代码样本直接添加到您的笔记本中,或者从 Github 下载完整的合成笔记本。
训练模型并生成合成数据
将源文件从 CSV 加载到 Pandas 数据框架中,添加或删除任何列,配置训练参数,并训练模型。如果可能,我们建议至少有 5,000 行训练数据。
比较源数据集和合成数据集
使用 Gretel.ai 的报告功能来验证合成数据集是否包含与原始源数据相同的相关性和洞察力。
# Preview the synthetic Dataframe
bundle.synthetic_df()# Generate a synthetic data report
bundle.generate_report()# Save the synthetic dataset to CSV
bundle.synthetic_df().to_csv('synthetic-data.csv', index=False)
下载您的新合成数据集,探索合成数据报告中的相关性和见解!
比较源数据集和合成数据集之间的洞察力
想从头到尾贯穿一遍?
在 Github 上下载我们的漫游笔记本,将笔记本加载到您的本地笔记本服务器中,连接您的 API 密匙,并开始创建合成数据!
编辑描述
colab.research.google.com](https://colab.research.google.com/drive/1EcPshb2mrWMpZjs7rADOIJT0azhZu_Ye?usp=sharing)
结论
在 Gretel.ai ,我们对使用合成数据来增强训练集以创建 ML 和 ai 模型的可能性感到非常兴奋,这些模型可以更好地概括未知数据,并减少算法偏差。我们很乐意听到您的使用案例——欢迎在评论中联系我们进行更深入的讨论, twitter ,或 hi@gretel.ai 。比如gretel-synthetics
?给我们一个 Github 上的⭐!
用这些书创建有影响力的数据可视化
如果没有交流,好的分析没有什么意义。数据可视化会有所帮助。以下是我对 2020 年增强 dataViz 的建议。
罗伯特·阿纳奇在 Unsplash 上的照片
数据可视化可能是数据工作迷人的公众形象。
它们无所不在。我们都经常接触到我们最喜欢的网站、体育广播甚至广告上的图表和数据。
与数据科学的复杂性、数据挖掘的庞大数量以及数据新闻的冗长相比,数据可视化是简单、可访问和简短的。
数据可视化也吸引潜在的从业者;可能是因为 T4 看起来很容易。DataViz 输出看起来更像是我们可以创建的东西。我们都在 Excel 里画过图表,在 PowerPoint 里用过。会有多难呢?
但事实是,创建良好的数据可视化并不容易。要做到这一点,数据可视化必须准确,视觉冲击力强,有说服力。这是一个很高的标准(图表),需要很好地掌握多个领域,如统计学、视觉传达、编程,甚至人类的感知和偏见。
在这篇文章中,我整理了几本书,我认为这些书将有助于开始数据可视化。此外,我试图保持列表的多样性,涵盖每个相关主题领域的一些内容。
如果你认为我错过了什么,请在评论或推特上告诉我!
注:这些书有些是免费的(这个社区是不是很精彩?).其他人的亚马逊是附属链接,这意味着在你没有额外费用的情况下,我会得到一小笔佣金。
数据可视化—概述
数据可视化基础(克劳斯·威尔基)
如果你不知道从哪里开始,这是一个很好的地方。
威尔基的书是那种适合用作参考手册,但天生可读的稀有书籍之一。我发现自己只是一章接一章地阅读,因为我发现这种经历既愉快又有启发性。
我不应该感到惊讶的是,一本关于数据可视化的书编排得很好,并以经济的方式传达了它的思想,但威尔基做得很好。作为一个简单的例子,威尔基将观想例子标记为“丑陋”或“糟糕”,这看起来是一个如此简单、明显的想法,但却真正抓住了你的注意力,让你的思维转向“为什么”以及应该如何去做。
它没有杂乱,也没有成本(如果你愿意的话),因为威尔基已经将整个手稿作为一个精美的网站在线提供。
真实的艺术:用于交流的数据、图表和地图(阿尔贝托·开罗)
Alberto Cairo 几乎是数据可视化领域的名人。他有新闻记者和学术证书,他在社交媒体上相当活跃,经常称赞他人的良好工作,并领导反对错误信息的斗争。
在我看来,艾伯特·开罗关于数据或数据可视化的任何书籍都不会错。
如果要我选一个的话,我会选这个。他的第一本书更像是一本介绍性的书,倾向于在光谱的抽象部分多躺一会儿,他的最新的书是针对观想的消费者而不是创造者。这个对我来说可能是最合适的,因为它稍微更实用(在我看来),并且针对…数据可视化的供应方面。
在亚马逊上有售
用数据讲故事(科尔·努斯鲍默·克纳弗里克)
这本书的一切都很谦逊,从简单的标题到严肃的封面。
这是这本书魅力的一部分。《用数据讲故事》是为商业专业人士写的,是一本很好的通才书籍,不像其他一些书那么专业,或许也不那么吓人。
我会向那些没有太多统计或数据分析背景的人推荐这本书,但可能不会向那些在数据相关领域有经验的人推荐。
在亚马逊上有售
好的图表:制作更聪明、更有说服力的数据可视化的 HBR 指南(斯科特·伯里纳托)
不要让标题中的“HBR”这几个字让你失去兴趣。这不是一本关于数据可视化基础知识的普通、最低标准的书。
虽然毫无疑问,它是为门外汉编写的,但 Berinato 并没有忽略历史和力学,或者数据可视化科学。
由此产生的产品是一个有效的,美丽的书,为从业者,管理者,或外行。Berinato 专注于创建有助于决策的有目的的图表,这在他的工作中得到了体现。
我经常发现一本“以业务为中心”的技术书籍往往会简化它,但在这种情况下,它有助于将精力用于实现目标和帮助决策者。
在亚马逊上有售
数据可视化和编程
Python 数据科学手册(Jake VanderPlas)
对于大多数从事数据可视化工作的人来说,他们的工作很可能也包括争论数据。
Python 是我选择的数据科学和分析语言,这意味着我经常使用包numpy
和pandas
。
这本书很好地介绍了这两者——尽管标题有些吓人,涉及到“数据科学”,但如果你熟悉 Python 的话,这是关于这个主题的较容易的书籍之一。免费提供!
网络交互式数据可视化(斯考特·玛瑞)
D3.js 是可视化库,面向希望创建定制的交互式视觉效果的专业人员。
基于 JavaScript 的之上,它确实有一个陡峭的学习曲线。以至于许多更容易使用的高级库都在它的上面(比如 Vega Lite 或 Plotly)。**
如果你想或者需要使用 D3.js,这本书是一个很好的起点。Murray 引导你熟悉 D3.js 的旅程,尽管这是一个漫长的旅程,但他设法注入足够的幽默和小胜利来使它变得更容易。他还让这本书在网上免费提供,同时提供了要遵循的代码。
不,简单地说,这本书不会让你成为 D3.js 的大师,然而这是任何编程语言或库的真理。但这可能会节省你大量的时间和悲伤。
在这里可以免费在线购买 |也可以在亚马逊上购买
背景材料
赤裸裸的统计:从数据中剥离恐惧(查尔斯·惠兰)
我认为对统计学有良好的直觉理解在现代社会中是非常重要的。
在我看来,这对于任何一个“知识工作者”来说都是适用的,如果你做任何与数据有关的事情,对统计学的扎实掌握是必须的。
不幸的是,我也参加过一些统计学课程,我知道这些课程大多以最疏远的方式教授。所以当我看到这本书的时候,我一定要把它推荐给每个人。
对大多数人来说,统计学不应该是关于复杂的数学符号和 p 值的深奥讨论,或者哪种分布最适合。它是关于对我们观察世界的直观理解。反过来,它帮助我们剥去其他人试图通过扭曲统计数据来讲述的谎言,同时另一方面帮助我们讲述适合自己的故事。强烈推荐。
可从亚马逊购买
完整的色彩调和,潘通版(利阿特丽斯·艾斯曼)
如果你没有像我一样的设计背景,你对颜色的理解可能不会像你希望的那样好。
虽然我理解颜色背后的物理学,并对不同的颜色有一些初步的了解,但这本书帮助我理解了对颜色的情感感知。
一些描述可能看起来有点不准确,因为相当一部分框架和语言是情绪化的;然而,我认为她或多或少地捕捉到了人们对颜色的反应,以及为什么颜色会被这样使用。
可从亚马逊购买
奖金簿:数据相邻
毁灭计划:改变了我们想法的友谊(迈克尔·刘易斯)
在书店找到一本迈克尔·刘易斯的书对我来说是个坏消息。
主要是因为我不可避免地坐立不安,游离于我对刘易斯的书的热爱的本能记忆中,比如《闪电侠》和《短暂的时光从我身边流逝》。
我推荐这本书,因为简单地了解行为心理学是一种丰富的经历,还因为休斯顿火箭队总经理达里尔·莫雷的章节本身就值得入场费。
如果你对体育和数据感兴趣,读读那一章,想想如果有一个像莫雷这样的老板,他的任务是用最好的数据做出最好的决定,那该有多好。此外,刘易斯是我们这个时代最好的作家之一,能够将一个看似平凡的主题转化为叙事黄金。
在亚马逊上有售
显然,从几十本好书中挑选几本并不是一件容易的事情,但是我希望至少这些能帮助你开始。我打算不时更新这些,所以如果你认为我做了一些惊人的遗漏,请务必让我知道。