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

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

基于 Python 和 Dask 的分布式文本预处理

原文:https://towardsdatascience.com/distributed-text-preprocessing-with-python-and-dask-5312a4d26ae?source=collection_archive---------30-----------------------

用 Python 和 Dask 进行分布式机器学习

一种扩展您的数据争论任务的方法

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

照片由 Jelleke VanooteghemUnsplash 上拍摄

如果你已经组装了一个独立的集群,并且对Dask 如何在后台工作有了足够的了解,那么是时候学习一些实用的数据科学了。对了,你可以在我的 GitHub 账号里找到我所有的源代码和数据。

我们试图预测什么?

我想根据文本将亚马逊产品的评论分为正面或负面。显然,在将数据输入到 ML 训练管道之前,我需要对数据进行一些转换。

数据呢?

我使用的是亚马逊提供的公开数据集,有 300 万条评论和评级。这是一个 1.5 GB 的中型数据集,但是本文的目的是展示如何以及为什么使用 Dask 来处理更大的数据集。

加载集群

在进入我们的笔记本之前,我们需要几个快速命令来准备好我们的独立集群。如果您遇到问题,这篇文章将指导您创建一个好的独立集群。

首先,与您的每台机器建立一个 SSH 连接。让我们从您想要选择作为调度程序的机器开始。您只需要输入以下命令:

dask-scheduler

我的独立 Dask 集群有两个工人(机器)。如果要将这些节点与调度程序连接,需要在“Worker node”终端运行以下命令:

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

调度程序节点

现在,您必须将其他机器作为工作节点连接起来。为此,您需要在调度程序终端输入以下命令。在下面的例子中,调度器节点的 IP 是10.1.1.93,Dask 应该连接的端口是8786

# You should specify the IP and port of the scheduler node as below. dask-worker tcp://10.1.1.93:8786

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

将第一个工作线程连接到调度程序节点

我将再连接四台机器作为工作节点,这使得我的最终集群有一个调度器节点和五个工作节点。连接每个节点后,您应该会在调度程序终端中看到类似这样的内容:

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

连接五个工作节点后调度虚拟机

恭喜你。现在,您可以开始使用 Jupyter 笔记本了。

Dask 提供了一个漂亮的仪表板,您可以在其中看到正在运行的进程的所有指标。您可以使用以下命令让它运行:

# load the cluster
import dask 
from sklearn.externals import joblib
from dask.distributed import Client# IP of the scheduler node.c = dask.distributed.Client('tcp://10.1.1.93:8786')# call the cluster c 

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

单击 dashboard 链接,它应该会在您的浏览器中打开一个新选项卡。Dask 的仪表板可以让你实时看到每个工人正在做的所有计算。太棒了,对吧?

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

Dask 仪表板

Dask 数据帧

按照以下示例将数据加载到 Dask 数据帧中。

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

让我们看看 Dask 生成的数据帧:

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

Dask 数据帧

哇!它看起来和熊猫的数据帧很不一样,对吗?这是因为两个主要原因:

  • Dask 的read_csv函数将数据分成小熊猫分区,让我们可以处理大数据集。在我们的例子中,Dask 将 1.5 GB 的数据集分成 22 个分区,使我们有 68.18 MB 的分区。作为一般建议,当您处理较大的数据集时,您的数据块应该足够小,以便它们中的大部分可以一次放入一个工作者的可用内存中。当您选择 Dask 数据帧中的分区大小或 Dask 数组中的块大小时,您可以控制这一点。
  • Dask 使用惰性计算比如 Spark。Dask 是一个图形执行引擎,所以所有不同的任务都被延迟,这意味着在您点击函数.compute()之前,没有任何函数被实际执行。在上面的例子中,我们有 66 个延迟的任务。

让我们点击.compute(),看看会发生什么。

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

.compute函数将 22 个小分区组装成一个包含 300 万条评论的 pandas DataFrame。如果您的数据集很大,不要这样做,因为这样做会使您将数据集放入单台机器的本地内存中,这是 Dask 试图避免的。

缺少值

检查缺失值类似于在熊猫数据帧上执行.isnull() 功能。但是记住,如果你想看到结果,你必须点击.compute()

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

缺少值

好消息是,在我们的示例数据集中没有需要处理的缺失值。

描述统计学

让我们简要地看一下 table 中的前五行数据,这样我们就可以看到我们正在处理哪种类型的值。Dask dataframes 允许您使用 pandas 功能,如.head().groupby().loc().merge()等。

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

数据帧

我们有三个栏目:标题、评论和评分。我想知道我们是否正在处理数据中的不平衡,因此我将计算我的目标变量(评级)的值。

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

这看起来是一个非常好的“训练”数据集,因为这些类被平等地表示。我们不需要担心应用技术来解决不平衡的数据。

您肯定可以使用更复杂的 EDA 进行文本分析,如查找最常用的术语、LDA 主题检测、基于产品的聚类评论等,从而为您的训练数据集添加新功能。然而,这些主题超出了本文的范围。

到目前为止,我认为您已经明白了这一点——Dask 是 Python 用户的友好库,允许您使用大数据

数据争论

例如,如果我们要建立一个二元分类问题,我们需要将评论分为“正面”或“负面”。亚马逊用户将这些评论评为 1-5 星。为了转换这一点,我假设将从 1 到 3 颗星的评级分类为负面,并用值 0 标记它们,反之亦然。

请记住——Dask 以这样一种方式转换您的场景,即使您的数据很大,您也可以处理小块的 pandas 数据帧,因此这是迭代所有分区的最优雅和有效的方式。

让我们来看看数据帧“df2”:

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

df2

我们创建了一个包含 177 个任务的 DAG。记住,我们不会做任何计算,直到我们点击.compute()

让我们看看转换的输出。

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

新目标变量

我们已经成功地将这个问题转化为二进制文本分类。

在清除文本中的干扰之前,我还将“标题”和“评论”功能结合起来。根据这种情况,很明显,最重要的数据点存在于评论中,但有时,重要的数据点也存在于标题中。我想确保我两者都考虑到了。

管理内存

在继续之前,了解如何使用 Dask 管理 RAM 的使用是很重要的。

dask.distributed将任务的结果存储在工作节点的分布式内存中。中央调度程序节点跟踪集群上的所有数据,并确定何时应该释放数据。完成的结果通常会尽快从内存中清除,以便为更多的计算腾出空间。但是,如果您想将数据帧存储在 RAM 中,您应该使用函数persist

**compute** **persist** 有什么区别?

compute返回每个输入的单个输出,而persist返回每个块(或分区)的集合的副本,由单个输出代替。简而言之,使用 persist 在集群上保存一个完整的集合,当您想要一个小的结果作为离散输出时,使用 compute。

但是你可能会奇怪为什么我要用 **persist**

从 RAM 访问数据通常比从磁盘访问数据快得多。一旦您的数据集处于干净的状态,并且:

  1. 适合内存,而且
  2. 足够干净,你会想尝试许多不同的分析,

那么这就是把你的数据保存在内存中的好时机。

让我们看一个例子:

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

前一部分生成的 df3

让我们坚持 df3…

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

持续 df

所以基本上persist()为每个 Dask 任务返回一个副本,包括它们以前的懒惰计算,现在提交到集群上运行。否则,您可以选择将数据帧保存到本地(不推荐)或以拼花格式保存到集群。

将 df3 保存到拼花地板:

用于机器学习的干净文本

当我们对文本进行矢量化时,我们会将我们的语料库(评论)转换为所谓的“稀疏矩阵”。稀疏矩阵是主要由零值组成的矩阵。矩阵的稀疏性可以用分数来量化,分数是矩阵中零值的个数除以矩阵中元素的总数。这可能导致空间和时间复杂性方面的问题。因此,清除评论中的噪声对于提高训练和结果模型的性能变得至关重要。我附上了我的清理算法的一部分,但你会在我的 GitHub 上找到更多的部分。

清理数据

但是我们还需要一个步骤——我们需要对所有的分区应用 clean 函数。为此,使用 Dask 提供的map_partitons()函数,而不是 pandas 的map()

当你叫map_partitions(就像你在熊猫上叫.apply()一样。DataFrame),您尝试映射(或应用)的函数会将 dataframe 作为第一个参数。

dask.dataframe.map_partitions的情况下,第一个参数将是一个分区**,在pandas.DataFrame.apply的情况下,它将是一个完整的数据帧。这意味着您的函数必须接受 dataframe 分区作为第一个参数,您的代码可能如下所示:**

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

地图 _ 分区

让我们检查结果!

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

清洁 df

不错!!我们已经用 Dask 清理了我们的文本!下一部分将展示如何用 Dask 加速你的算法。

感谢大量阅读。

** [## PabloSalvadorLopez10 -概述

在 GitHub 上注册你自己的个人资料,这是托管代码、管理项目和构建软件的最佳地方…

github.com](https://github.com/PabloSalvadorLopez10)

链接

https://docs.dask.org/en/latest/best-practices.html

https://docs.dask.org/en/latest/dataframe.html**

tf.keras 中带权重和偏差的分布式培训

原文:https://towardsdatascience.com/distributed-training-in-tf-keras-with-w-b-ccf021f9322e?source=collection_archive---------44-----------------------

生产中的机器学习

探索以最少的代码更改来分配您的培训工作量的方法,并使用权重和偏差(W&B)来分析系统指标。

查看关于体重和偏见的交互式仪表盘

介绍

在这份报告中,我将向您展示如何无缝集成[tf.distribute.MirroredStrategy](https://www.tensorflow.org/api_docs/python/tf/distribute/MirroredStrategy),以便针对tf.keras型号在多个 GPU 之间分配您的培训工作负载。当您拥有非常大的数据集,并且需要调整培训成本时,分布式培训会非常有用。仅在单个硬件加速器(在这种情况下是 GPU)上执行训练变得不现实,因此需要执行分布式训练。

查看 GitHub 库上的代码。

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

查看关于重量和偏差的交互式仪表盘

在报告的结尾,我们将看到两种方法可以使分布式训练非常有效——a .预取数据,以便模型在完成一个时期后就可以使用这些数据,b .调整批量大小。

非常感谢 Google 的 Martin Gorner(ka ggle 团队的 ML 产品经理)为我准备这份报告提供了指导。

TensorFlow 的分布式策略使我们能够极其轻松地在多个硬件加速器之间无缝扩展我们繁重的训练工作量,无论是 GPU 还是 TPU。也就是说,分布式训练长期以来一直是一个挑战,尤其是在神经网络训练方面。分布式培训程序带来的主要挑战如下:

  • 我们如何在不同的设备上分配模型参数?
  • 我们如何在反向传播过程中累积梯度?
  • 模型参数将如何更新?

如果您从头到尾考虑培训过程,所有这些听起来可能非常令人生畏。幸运的是,像 TensorFlow 这样的库给了我们非常容易地合并分布式训练的自由——无论是经典的fitcompile范式的tf.keras模型,还是定制的训练循环。然而,本报告只涉及前者。如果您有兴趣了解更多关于定制培训循环的分布式培训,请务必查看本教程。

在本报告的前半部分,当我在 GCP 虚拟机上进行实验时,我们将讨论在谷歌云平台(用于分布式培训)上选择虚拟机时需要记住的一些要点。但是这些指针也应该适用于您选择的任何平台。然后,我们将看到在单个机器中的多个 GPU 之间分配tf.keras型号的培训工作负载所需的步骤。最后,我们将通过分析这个[wandb](https://app.wandb.ai/sayakpaul/tensorflow-multi-gpu-dist/) 运行概要中的系统指标来得出结论。

系统设置、成本等

我们主要有两个选择来执行 GCP 的分布式训练-

  • 计算引擎
  • 人工智能平台笔记本

计算引擎允许您创建具有许多不同软件和硬件配置的虚拟机,这些虚拟机可能适用于各种任务,而不仅仅是训练深度学习模型。另一方面, AI 平台笔记本为我们提供了预配置的 Jupyter Lab 笔记本实例,具有定制的灵活性。

根据我的经验,我发现建立一个计算引擎实例的过程比构建一个人工智能平台笔记本实例更复杂。让我们从成本的角度来看看它们有什么不同。

以下是我的系统配置:

  • n1-标准-4 个 vcpu-15 GB
  • 4 辆特斯拉 K80s
  • 100 GB 标准永久磁盘
  • 预配置映像: TensorFlow 2.1 (采用英特尔 MKL-DNN/MKL 和 CUDA 10.1)

计算引擎,为了以上,将花费我-

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

在 GCE 上计算我们虚拟机的成本

而且,人工智能平台笔记本电脑会让我付出以下代价-

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

人工智能平台笔记本电脑上虚拟机的成本计算

正如你所看到的,两者的成本是不同的,但后者(人工智能平台笔记本)只是一个点击就走的东西。作为一名从业者,我希望我的时间花在与我的专业知识相关的事情上,我不想在不需要的时候重新发明轮子。因此,我选择了人工智能平台笔记本电脑。关于设置和使用人工智能平台笔记本的更全面的报道,请参考本指南

为了能够在一个 AI 平台笔记本实例中使用多个 GPU,您首先需要申请配额增加。你可以看看这个帖子来了解更多。

给我看看代码

默认情况下,使用 all-reduce 算法在同步模式下进行参数更新。但是,TensorFlow 2.x 也支持异步模式下的参数更新。解释它们的细节超出了本报告的范围。如果您有兴趣了解更多,这里有一些非常好的资源:

好了,回到代码!

作为起点,我们先在单个 K80 GPU 上训练一个区分猫和狗的图像分类器。我们将使用 MobileNetV2 网络(在 ImageNet 上进行了预培训)作为我们的基础架构,在它的顶部,我们将添加分类头。所以,在代码中,它看起来像这样-

训练这家伙 10 个纪元给了我们一个好结果-

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

训练进度图 I(在此处与图互动)

请注意,我们正在对这个网络进行微调,而不仅仅是预先计算瓶颈,然后将其提供给分类顶部。因此,EXTRACTOR.trainable = True就是这样设定的。当trainable参数设置为False时,它只是一个带有不可训练特征提取器的浅层网络。在这种情况下,我们不太可能看到分布式培训的任何优势,因为它会变成一个非常肤浅的网络。

我们已经在验证集上获得了大约 94%的准确率。但这不是我们关心的问题。我们希望能够通过使用分布式训练来加速模型训练。

训练大约需要2090 秒 。关于这个特定实验的所有重要统计数据都可以在一个格式良好的表格中找到(你可以在这里看到)

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

不同 W&B 运行的集合一起称为运行集

当微调网络时,使用一个带有加速的学习速率表是一个很好的实践。这里的想法是从一个低的学习率开始,这样基础网络的预训练权重就不会被破坏。然后我们提高学习率,再降低学习率。时间表应该是这样的-

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

带有斜坡的学习率(LR)时间表

使用 LR 调度进行微调(单个 GPU)

现在让我们看看学习计划对培训是否有任何影响。

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

训练进度图 II(在此处与图互动)

虽然这次网络中有一点过度拟合的行为,但你也可以看到性能的改善( ~98%的验证准确率)。模型训练时间也不受此影响( ~ 2080 秒)。通过在开始时使用较低的学习速率,同时使用学习速率时间表,可以进一步减轻过拟合。

将模型移植到多个 GPU

现在,为了在四个 GPU 之间分配这种训练,我们首先需要定义MirroredStrategy范围,并在范围上下文中编译我们的模型

get_training_model包括如上所示的模型定义以及编译步骤。所以,我们正在做的是在MirroredStrategy的范围内创建和编译模型。这之后绝对一样——你叫model.fit。我们的学习率计划也将有所改变,因为我们现在将在四个 GPU 上分配模型参数(注意 Y 值)。

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

多 GPU 的 LR 调度

从下图中可以看出,性能变化不大(至少在准确性和损失方面)

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

训练进度图三(在此处与图互动)

正如你所看到的精度(在这种情况下,我们有 ~98% )和损耗仍然与上面的图有些相同。如果我们从较低的学习率开始,左边图中的尖峰可以变平。

不过,模型训练时间减少了——1046 秒。哇哦。惊人的 2 倍加速。这还可以进一步改进,我们稍后会看到如何改进。但首先,让我们对 GPU 指标做一些分析。

分析 GPU 指标

相对而言,GPU 不如其他商用硬件便宜。因此,确保 GPU 利用率尽可能高非常重要。让我们快速看看我们在那里做得怎么样。下面是 GPU 利用率和 GPU 访问内存以获取数据所用时间的图表(单个 GPU)。正如我们所见,大多数时候 GPU 利用率都很高,这很好。

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

单 GPU 指标

作为一名深度学习实践者,你的目标应该是最大化GPU 利用率,同时减少GPU 访问内存以获取数据所花费的时间。因此,减少 GPU 获取数据所花费时间的一个显而易见的解决方案是在一个时期完成时预取数据

当我们使用多个 GPU 时,我们会得到-

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

多 GPU 指标 I

(您会看到多行,因为这里有四个计算指标的 GPU)

正如我们所看到的,四个 GPU 的平均 GPU 利用率远远低于预期,但内存访问时间已经大大减少,因为它现在分布在多个 GPU 上。至于利用率,这是因为数据集的容量相对较低。有了更大的数据集,我们可以期待看到 GPU 性能的更多提高。在下一节中,我们将讨论两种常用技术来进一步提高利用率。

我们还可以看到上面两个图的线条有些平滑,这表明所有的 GPU 都在相同的负载下运行。可以肯定地说,在多 GPU 环境下运行时,这种平滑度是意料之中的。如果您看到奇怪的峰值,这可能是一个迹象,表明 GPU 没有在相同的负载下运行,您可能希望使之均匀。

进一步提高性能的两种方法

方法#1

TensorFlow 的数据 API 提供了许多东西来进一步改善输入数据流成为瓶颈的模型训练。例如,理想情况下,当模型正在训练时,下一个时期的数据应该已经准备好,因此模型不需要等待。如果它需要等待,那么它会在总训练时间方面引入一些瓶颈。

[prefetch](https://www.tensorflow.org/api_docs/python/tf/data/Dataset)允许我们指示 TensorFlow 在模型完成当前时期后立即准备好下一批数据。它甚至允许我们预先指定系统应该获取的样本数量。但是,如果我们希望系统根据系统进程和硬件的带宽为我们做出决定,那该怎么办呢?我们可以用tf.data.experimental.AUTOTUNE来指定

方法二

我们可以做的第二件事是调整批量大小。由于我们使用同步参数更新方案的多个 GPU,每个 GPU 将接收一部分数据,并在此基础上进行训练。因此,如果我们使用过高的批处理大小,GPU 可能很难在彼此之间正确分配。另一方面,如果我们使用的批量太小,GPU 可能会利用不足。所以,我们需要找到最佳点。这里有一些一般性的建议(这些来自马丁·戈纳的笔记本)

  • 从 16 开始,作为每个 GPU 的本地批量大小。
  • 然后,全局批量大小变为— local_batch_size * number_of_GPUs

请注意,我们现在使用的批量更大,在之前的实验中,我们使用的批量为 16。

Martin 的上述笔记本包含许多使用分布式培训时优化模型性能的提示和技巧,其中包括:

本指南中也提供了许多建议。

好了,说够了!现在是时候把上面讨论的方法结合起来看看结果了

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

训练进度图四(在这里与图互动)

批量越大,性能受到的影响越大,但另一方面,训练时间进一步减少到了 887 秒。

在同样的批量 32 的情况下,我们得到-

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

多 GPU 指标 II

虽然 GPU 利用率和内存访问时间的提高非常微小,但它仍然存在。

LR 调度+批量 16 +预取

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

训练进度剧情五(在此与剧情互动)

正如你所看到的,我们能够保持同样的性能,并且还稍微减少了模型训练时间( ~ 6 秒)。

就 GPU 指标而言-

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

多 GPU 指标 III

如上图所示,GPU 指标几乎没有变化。当使用多个 GPU 时,通常数据越多,利用率就越高。同样重要的是要记住,在这些情况下使用较大的批量可能会损害模型性能,正如我们在上面看到的那样。

我们鼓励您查看下面为两个不同的 Kaggle 竞赛提供的两个惊人的基准:

它还提供了许多不同硬件配置之间的成本权衡。这将有助于您根据您的成本预算做出最佳决策。

结论和下一步措施

重要的是要记住,在使用分布式培训时,数据集越大,加速器的利用率就越高。无论是 TPU 还是多个 GPU,这一逻辑都是正确的。

当使用多个 GPU 时(无论是在单个还是多个机器/集群中),注意多个加速器之间协调所需的同步时间的相关成本非常重要。本视频讲解了与此相关的一些取舍。

我希望您已经意识到为您的tf.keras模型分配培训工作量是多么容易。作为下一步,您可能想尝试本报告和我提到的参考资料中分享的不同技巧和诀窍。如果你更喜欢定制训练循环,你也可以尝试混合精度训练和分布式训练。

如果你有任何反馈要与我分享,你可以通过推文这里这样做。我真的很感激。

建立一个分类算法来预测国会选区翻转并确定因果关系

原文:https://towardsdatascience.com/district-flip-forecasts-in-congressional-elections-47324c71e7ab?source=collection_archive---------39-----------------------

预测国会选区的政党变动。

METIS 数据科学沉浸式解决分类算法项目 5 之 3。你可以在我的 Github 上看看这个项目的文件。

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

根据维基媒体知识共享许可授权的美国国旗

我一直想当然地认为,地区派对的转变是特定地区人口或文化变化(或不公正选区划分)的结果,这种现象通常被称为空间排序——由比尔·毕晓普在《大排序》中推广开来。我用这个项目来评估这个假设。

目标

  • 预测国会选区的政党变动。
  • 确定派对狂欢的最大促成因素

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

在过去的 45 年里,平均不到 9%的地区改变了党派。图片由 Anupama Garla 提供

当您预测的类别(翻转/非翻转)相等时,分类算法往往会做得更好。这意味着这个项目可能是一个分类问题的挑战,也许可以更好地用异常检测算法进行评估。然而,我想先尝试更简单的分类工具。为了解决班级不平衡的问题,我计划在训练算法时,对我的少数民族班级——翻转的地区——进行上采样。

方法学

区级数据:

  • 从麻省理工学院选举实验室提取的 1973–2016 年累积翻转历史并转化为目标(翻转与否),以及量化先前翻转的 4 个特征。
  • 人口统计和相对城市化来源于 Daily Kos 对美国人口普查和美国社区调查的分析,涵盖教育、种族和大都市人口的 20 个特征
  • 财务来源于 SEC,涵盖候选人资金和支出的 10 个特征

型号选择:

支持向量机是在测试了其他传统分类模型之后选择的:高斯朴素贝叶斯、K-最近邻、CART 模型和逻辑回归。

指标:

回想一下之所以被选中,是因为该指标优先考虑捕捉尽可能多的翻转案例。精确度和 F1 分数也被参考,以确保模型不会指示太多不会翻转的地区。还参考了 AUC 然而,由于类别不平衡和翻转的相对可预测性,在这方面模型之间没有重大差异。

结果:

76%召回

63%的 F1 分数,48%的精确度,94%的 AUC

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

Anupama Garla 的模型限制

测试集的表现不如训练集准确的一个可能原因是包含 2012-2016 年地区变化的训练集和由 2018 年地区变化组成的测试集之间的数据划分。在翻转的次数和方向方面,训练测试组有所不同。一些额外的差异可以通过包括更多的功能来捕捉,如库克的党派投票指数和民意调查结果等。然而,考虑到从训练集中的上采样数据到测试集中的类不平衡的转变,该模型做得相当好。

Anupama Garla 的交互式 Tableau 仪表板,国会选区 Hex 地图来自 Daily Kos 的 Daniel Donner,可在此处获得。

上面的视频显示了根据分类模型的地区翻转可能性,以及映射到 Daily Kos 制作的美国修改地图上的 2018 年实际地区翻转。该地图也是可点击的,因此您可以看到每个地区的相关特征。

该地图将每个国会选区的大小绘制为具有相同的面积,表示根据美国人口普查,每个选区由大约相同数量的人口组成。这使我们能够看到更准确的结果分布,尽管在美国西部人口较少的地区产生了差距。

洞察力

还实施了一个决策树模型,以获得最有影响力的功能的排名,前 7 名如下:

预测特征排名

  1. $$$ —财务

2.翻转的历史

3.中等收入

4.第二大城市:人口的%

5.状态

6.最大的地铁站的人口比例

7.人口统计超参数—捕捉城市+多样化与农村+同质的比率

如果我们深入研究财务特征,我们可以看到它们的主要预测特征:

金融特征排名

  1. 业务开支
  2. 党委贡献
  3. 个人单位化贡献
  4. 总支出
  5. 总作用

结论

竞选活动的运营支出是决定一个选区是否会翻转的最大因素。人口统计和地理因素也有影响,尽管没有专家让我们想的那么大。

仔细观察财务特征,他们的排名显示个人和党委的贡献确实有影响——但是党的贡献排名更高。在这项研究之后,我不得不同意伯尼·桑德斯“让公司资金远离政治”的运动。

翻转的第二大指标是历史上有争议的地区。这是有道理的,因为如果一个特定的地区是高度分裂的,这样或那样的一些投票可能导致翻转。如果一个地区的历史周转率很高,某一年没有发生变化,第二年很可能会发生变化——特别是如果更多的竞选资金投入到这个特定的地区。

翻转的跟踪指标都与人口统计和地理有关,中等收入和居住在第二大城市的人口比例超过了这些预测特征。后者很有趣,因为这意味着第二大城市的选民具有政治多样性,可以以某种方式被说服——第二大城市人口组成的选区越大——就越容易改变立场。然而,由该州人口最多的城市或人口第三多的城市组成的地区,其政治联系更加紧密。

该模型的预测特征排名为进一步的竞选策略提供了信息,而该模型本身在预测国会选区翻转的概率方面表现良好。一些超参数和附加功能的微调可能会带来更多的见解。

附录:探索性数据分析

这一部分深入到我开始这个项目时使用的数据集——翻转、人口统计和地理数据的累积历史。在这个项目的早期阶段,我研究了这些数据集的细微差别,以改进模型并更好地理解数据和我的结果。

下面是一张地图,显示了每个地区的整个累积翻转历史。一个地区最大的翻转次数是 7 次。

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

第二强预测因子:Anupama Garla 的累积翻转史

将上面的历史翻转图与下面的 2018 翻转图进行比较,我们可以直观地看到翻转与翻转历史之间的相关性。

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

阿努帕马·加拉的 2018 年国会选区翻转

上面的地图——2018 翻转——组成了我的坚持测试集。下面的地图(2010 年至 2016 年)组成了我的训练集。我们可以观察到,地区变化的数量以及变化的方向每年都有很大的差异。2018 年与 2016 年截然不同,之前的选举要追溯到 2010 年。我认为,如果我们再往后看,我们会看到成交量和方向的周期性。

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

2016 年,2014 年国会选区翻转

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

2012 年,2010 年国会选区翻转

对于这些数据集——翻转历史和人口/地理——我的模型表现极差,召回率约为 30%。检查我的配对图和我的模型特征重要性,我可以看到人口统计/地理特征根本没有通知我的模型。

基于我最初的假设,即地区翻转主要是由于该地区的人口统计和地理状况,我认为如果我尝试一种多类分类模型,将类分为 3 类(无翻转|向右翻转|向左翻转),而不是 2 类(无翻转|翻转),我的模型会表现得更好。在多类分类模型中,分数必须以不同的方式计算——我创建了一个自定义函数来计算召回率和精确度——并且 AUC-roc 在这里不能被引用。当我将数据集分成三类时,我的配对图显示了这三类之间的更多差异,所以我认为这是一个有希望的方向。我深入我的人口统计和地理特征来设计一些超参数。我在 tableau 中可视化了一些结对图发现,如下所示:

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

由 Anupama Garla 绘制的配对图

上面的图标识了向左翻转和向右翻转的两个集群。蓝色的左翻转群集通常有较高比例的亚洲人和较高比例的有单身汉的白人。右边红色区域的亚裔比例较低,有单身汉的白人比例也较低。这强化了受过教育的多样化人口向左倾斜和受教育程度较低的同质人口向右倾斜之间的二分法。

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

Anupama Garla 的配对图

在左边的图中,你可以看到一个主要由向右转的人组成的集群,他们通常比向左转的地区受教育程度低,收入也少。在右边的图中,我们可以看到一个主要由向右转的地区组成的集群,与向左转的地区相比,它的多样性和城市化程度较低。

这些图加强了我在项目开始时所做的假设。由于这个 EDA,我设计了超参数,这些超参数基本上捕捉了多样化的、受过教育的城市人口与同质的、受教育较少的农村人口的比率。然而,当我运行基于这种多类划分的模型时,我的结果并没有显著提高。我只是需要一个更有影响力的特征来捕捉数据集中的差异。我那精通政治的兄弟——他建议增加竞选财务数据——将模型提高了 33 个百分点。永远不要低估领域知识!

这个多类切线,虽然很有趣,也很有知识性,最后还是走进了死胡同,但是给我提供了宝贵的一课。对项目方法和设计的深入和反复思考对于获得有意义的结果是非常重要的。做到这一点的最好方法是走出你的头脑,与有知识的利益相关者交谈,或者甚至看看那些前人的工作——比如我的英雄,FiveThirtyEight 的 Nate Silver。

丢弃数据库

原文:https://towardsdatascience.com/ditch-the-database-20a5a0a1fb72?source=collection_archive---------13-----------------------

如何使用自动气象站 S3 选择查询更智能,也许更便宜

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

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

亚马逊 S3 精选是亚马逊 S3 的一项功能,于 2018 年 4 月正式上市。通过使用亚马逊 S3 精选,可以在没有“经典”数据库的情况下运行应用程序,从而简化应用程序架构。

任何处理数据的人都可能在其数据管道的某个点上使用过基于云的存储解决方案。就个人而言,亚马逊 S3 是我的首选,因为它使用相对简单,易于扩展,与其他 AWS 服务相结合,并且存储几乎任何文件类型的对象。

虽然亚马逊 S3 在存储数据集方面很棒,但像其他传统的基于云的对象存储解决方案一样,它不允许检索数据集的子集(即必须检索整个数据集)。例如,如果您需要 100 万行数据集中的前 1000 行,您必须检索整个数据集并进行本地过滤。这使得使用亚马逊 S3 作为应用程序的唯一数据库变得不切实际,特别是那些经常需要检索更大数据集的子集的应用程序(例如检索客户记录的 web 应用程序)。

输入亚马逊 S3 精选🙌

概述—亚马逊 S3 精选

亚马逊 S3 选择允许您使用简单的 SQL 表达式从亚马逊 S3 对象中提取您需要的数据。这是巨大的!!!

使用 S3 选择,您不再需要为了保留几行而检索整个数据集。相反,您可以使用经典的 SQL 表达式就地查询数据,并只检索一个子集,例如两个日期之间或高于某个价格的数据。目前,亚马逊 S3 精选支持 CSV、JSON 和 Apache Parquet 格式的对象。

通过减少您的应用程序必须加载和处理的数据量,S3 精选可以将大多数频繁从 S3 访问数据的应用程序的性能提高多达 400% 。—亚马逊网络服务

使用亚马逊 S3 精选进行简化

亚马逊 S3 精选最好的部分是它如何简化应用程序结构。在亚马逊 S3 精选之前,web 应用程序的典型结构可能如下所示。

  • 将数据存储在经典 SQL(即 MySQL 或 PostgreSQL)或 NoSQL(即 DynamoDB)数据库中,以便进行查询。
  • 在持久对象存储器(即亚马逊 S3)中保存数据的备份副本
  • 将新数据转移到亚马逊 S3,然后添加到数据库。

使用亚马逊 S3 选择 web 应用程序的结构如下所示。

  • 将数据存储在亚马逊 S3,以便查询。

好多了!现在你可以只使用亚马逊 S3 来构建一个端到端的应用程序。它速度快,价格便宜,界面简单!👍

示例—亚马逊 S3 精选

最近我构建并部署了一个 web 应用程序,让下载和可视化加拿大历史天气数据变得更加容易和快捷。这是我构建的第一个 web 应用程序,其中我没有使用经典数据库,而是直接从亚马逊 S3 存储和查询静态和动态数据。使用亚马逊 S3 选择,我能够快速方便地从我的动态仪表板中获取用户输入,将它们传递到选择表达式中,并只查询和检索请求的数据。

下面是一些示例数据和一个在亚马逊 S3 查询 CSV 并返回可以读入熊猫数据帧的 CSV 格式的函数。CSV 的亚马逊 S3 SQL 语法可能有点复杂。您可以使用列名或列索引进行查询,根据您选择的列名或列索引,SQL 表达式会有所不同。

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

示例“test.csv”

用于在亚马逊 S3 查询 CSV 并将数据解包为 CSV 格式的函数

如何按列名查询?

让我们使用列名在两个日期之间查询上面的数据集,并只返回日期、风速和风向的相应列。

使用列名在亚马逊 S3 查询 CSV

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

查询结果

如何按列索引查询?

让我们使用列索引查询上面的数据集,当温度高于 20 摄氏度时,只返回日期和温度的对应列。

请注意,在 S3 选择中,索引从 1 开始(即 s._1 ),而 Python 的索引是 0。通过使用“cast”命令将一种数据类型转换为另一种数据类型,确保您正在比较 SQL 表达式中的常见数据类型。如果我的温度数据是字符串格式,我将需要*" cast(s . 4 as float)>20 "*。

使用列索引在亚马逊 S3 查询 CSV

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

查询结果

如何查询表头名称?

让我们只查询上面数据集中的标题名称,这样我们就可以使用它们来追加到其他查询结果中,或者作为动态仪表板下拉列表的输入。在这种情况下,我将 use_header 设置为 False ,以便在第一行返回列名,并且使用 S3 选择限制特性将返回的行数限制为 1。

在亚马逊 S3 查询列标题 CSV

#  query result
['Date/Time', 'Longitude', 'Latitude', 'Temperature', 'Wind Speed', 'Wind Direction']

亚马逊 S3 精选的成本

亚马逊 S3 精选很便宜!以下是我的应用程序的启动成本明细(截至 2020 年 6 月)。

  • 亚马逊 S3 对象存储—每 GB 0.023 美元(前 50tb/月)
  • 亚马逊 S3 选择——每 1000 条选择命令 0.0004 美元
  • 亚马逊 S3 数据传输—每 GB 0.01 美元(S3 →美国东部地区)

我在 S3 存储了大约 37 GB 的数据,每月执行近 100,000 条 SELECT 命令,每月从 S3 传输大约 50 GB 的数据。这使我每月的估计费用达到…1.39 美元!

结论

虽然亚马逊 S3 精选已经推出两年多了(在代码年,这是一个千年😆)这是一个简化应用程序的好工具,尤其是微服务框架。

查询愉快!

抛弃 AWS GUI 控制台

原文:https://towardsdatascience.com/ditching-the-aws-gui-console-ac77f46a05fa?source=collection_archive---------60-----------------------

通过 AWS CloudFormation 将无服务器基础设施作为代码

GitHub 回购/源代码在此!

2020–09–10

背景故事:

当我在时代广场的一家数据分析公司工作时,我经常在美丽的布莱恩特公园草坪上享用午餐。我可以查看 https://bryantpark.org/的草坪目前是否开放,但是 org 页面加载有点慢;里面全是我不在乎的图像。

因为这个原因(以及学习 AWS 的愿望),我从一个 ec2 盒子上创建了一个愚蠢的单一服务网站,它只显示草坪是否开放。你会去 是布莱恩特公园的草坪开点 com 然后看这个:

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

http://hasthelargehadroncolliderdestroyedtheworldyet.com/的启发

在科维德·疫情的萎靡不振中,我的简陋的网站已经失修,这提供了进行一些翻新的机会。上一次我做这个的时候,我非常依赖于在 AWS GUI 控制台方法**、中的点击——这是我想要摆脱的行为。**

目标:

今天,我将着手重新设计这种(异想天开,可以说是“愚蠢”或“没人要求的”)服务,将其作为基于 AWS 的无服务器基础设施——利用 SAM CLI,使用 CloudFormation 进行配置,并依靠各种其他代码和基础工具。我想在不接触 GUI AWS 控制台的情况下做到这一点: CLI 和脚本全程!

架构流程图:

这里有一个我认为我会需要的服务的小地图:它都围绕着一个小数据库,一个 s3 bucket 网站,和一些 AWS Lambda 函数。

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

在我看来。以普莱狄卡为蓝本

如何使用每项服务:

云的形成:

  • YAML 模板中一次性提供以下所有服务
  • 在版本控制中被跟踪;be 基础设施符合规范
  • 学习良好的 DevOps 实践(这个男孩在找新工作)

RDS 数据库:

  • 仓库我们的开放/封闭二进制草坪数据,加上最少的元数据
  • 位于私有子网中,只有 Lambda 函数可以访问,从而不受公众影响
  • 拥有大约 35,040 个数据点后,丢弃旧行。(任意…2 年)

S3 水桶:

桶是对象存储容器。他们可以存储文件,也可以服务静态网站。我需要水桶来做以下事情:

路线 53:

  • 至少给我们愚蠢的网站一个自定义域名

EventBridge(前身为 CloudWatch):

λ函数(I)至(V):

为了完成一些计算,无服务器功能即服务绕过了调试云服务器的成本开销。你可以让 AWS 管理服务器基础设施,并且只在你的代码实际运行时计费,由一些事件时间表触发。以下是我需要的函数:

I)刮刀:

  • 每半个小时,旋转一个无头浏览器,从 Bryant park . org 网站上获取一个原始的草坪状态字符串(和 F 数据,为什么不呢)
  • 将收集的原始数据传递给后续的解析器函数

II)解析器:

  • 接受来自刮刀功能的原始数据
  • 将原始草坪状态字符串解析为二进制变量
  • 生成其他有趣的元数据,如星期几和小时
  • 将解析后的数据传递给 RDS 编写器

III) RDS 编写器:

  • 从解析器函数接受干净的解析数据。
  • 将新行写入 RDS 数据库

IV)基本状态更新器:

  • 每半小时,读取 RDS 数据库的最后几行
  • 如果草坪状态已经改变(这种情况将避免不必要的频繁 S3 推杆),然后更新 S3 水桶网站的索引页面

V) Viz 生成器:

  • 每天两次,将整个表加载到内存中,并运行一些聚合
  • 用聚合数据生成 Plotly HTML 可视化
  • 将这些图表推送到简单的 S3 网站的“统计”页面

通过云信息配置 VPC/数据库

是时候开始构建我们的云形成堆栈了。yml!这是我们通过 CloudFormation CLI 提交的文档,以完美协调的方式一次提供我们需要的所有资源。我一直在研究 AWS 上的云信息文档,想弄清楚这应该是什么样子:

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

节选自我的第一个云形成模板

# Excerpts from the .yml, provisioning more resources...lawnDBsubnetGroup: # RDS DB needs a subnet group. This is it
    Type: AWS::RDS::DBSubnetGroup
    Properties: 
      DBSubnetGroupDescription: The two private subnets
      DBSubnetGroupName: lawn-DB-subnet-Group
      SubnetIds: 
        - !Ref lawnSubnetPrivateA
        - !Ref lawnSubnetPrivateB

我今天还没有机会测试和调试,但我已经开始为这个应用程序声明我的云基础设施(网络配置,安全规则,数据库实例)。建立我的网络的一个至关重要的资源是这个关于保持你的 RDS 实例私有,同时仍然给 Lambda RDS 访问,不牺牲 Lambda 的网络访问。

这其中的难点(私有子网 RDS +带 web 访问的 Lambdas)是建立一个廉价的 NAT 实例(通过 ec2 AMI 的硬手动方式)而不是简单地在 CloudFormation 中提供一个昂贵的预烤 NAT 网关。过去,走捷径让我付出了代价,以美元计。

2020 年 9 月 11 日:部署试验和错误

我在反复构建这个云层结构。yml 模板(目前)只有一个新的 VPC、一些子网、安全组/子网组和一个 RDS DB——还没有 Lambda 函数或 S3 桶站点。

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

在自动气象站云形成设计器中绘制

部署此堆栈的初始尝试。yml 会导致错误,因为我不可能第一次就做对:

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

通过查看控制台以 GUI 方式检查错误,这有点作弊

好了,我们得到了一些合理的错误,例如,对于“lawnDB”资源(我的 RDS 数据库),它没有启动,因为我得到了Value of property VPCSecurityGroups must be of type **List of** String。最初,我只给了它一个字符串,而不是字符串列表,这是我的错误。我将递归地纠正这些错误,并继续尝试验证/部署。我现在也很好奇 CloudFormation 中的!ref功能…

原来,[**!ref**](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-ref.html)函数 是云生成中必不可少的例如,如果您提供一个 VPC 和一个子网进入其中,子网可能需要!RefVPC 的逻辑名称(您在 YAML 中为其指定的名称)才能属于该 VPC。我的意思是:

# Inside the CF stack .yml:
# See bolded text for relevant bitsResources:
  **lawnVPC**: # The whole big sandbox. Contains all infra for this app
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      Tags:
      - Key: Name
        Value: !Join ['', [!Ref "AWS::StackName", "-VPC" ]] lawnSubnetPublicA: # 1 of 2 public subnets
    Type: AWS::EC2::Subnet
    Properties: 
      AvailabilityZone: us-east-1b
      CidrBlock: 10.0.0.0/24
 **VpcId: !Ref lawnVPC**
      Tags:
        - Key: Name
          Value: lawn-Subnet-Public-A

在掌握了 CloudFormation 模板之后,看起来我已经有了一个基础设施的雏形,只是一些网络组织垃圾和一个数据库:

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

绿色的刻度让我的心在歌唱

这个。yml 已经变得很长了!有没有办法让我把它分开?显然,是的。我们可以在带有输出的栈之间嵌套 CF 栈或输入/输出值。我会的:

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

检查堆栈输出。其他堆栈现在可以引用这些值。

模块化 CloudFormation 模板感觉很好,就像我们将不祥的大 Python 模块分成几个一样。

接下来,我将尝试组装上面提到的 Lambda 函数。这是我第一次尝试通过 SAM CLI(和 docker)在本地调试 Lambda 函数的地方!

2020 年 9 月 16 日:λ和云的形成

Lambda 到底如何适应这种云计算基础设施即代码模型?我将把它们放入它们自己的“堆栈”中,并给它们分配 IAM 角色,允许它们做像写 RDS 和相互调用这样的事情。回想起来,嵌套堆栈可能是一种更好的方法,因为现在我在这个 CloudFormation 区域中混淆了导出的变量名称空间。

功能一:刮刀

我发现了一个方便的 repo,它生成一个 lambda 函数,可以用一个无头的 selenium 浏览器抓取网页。谢谢克里斯托弗。现在将它应用到我自己的 scraper 函数中,收集关于公园草坪的信息:

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

使用 AWS 的 SAM(无服务器应用程序模型)CLI,我能够快速重用和调试这段代码,从。org 网站。是我的新果酱。

功能二:解析器

这是将从。org 网站转换成二进制变量。我有一种感觉,这是我的“应用程序”中最不耐用的部分,因为我不知道这个粗糙的文本字段可能存在的值的范围。目前我只看到“草坪开放”和“草坪关闭”当新的可能值出现时,我会不断更新这个函数。好的方面是它有自己的 lambda 函数,有自己的日志和故障率。也许我以后会用 AWS SNS 设置短信故障通知。

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

一个单独的 lambda 函数来解析原始字符串

顺便说一下,所有的原始代码都在 GitHub 上公开,如果你之前没有注意到的话!

功能三:RDS 写入器

最终,我决定让 RDS writer 函数按计划运行,并通过 boto3 同步调用子函数 I (scraper)和 II (parser ):

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

在 lambda 函数中调用 lambda 函数

这个 lambda 函数有权限来调用其他 Lambda 函数,并修改我们在 CloudFormation 模板中提供的 RDS 数据库。它最终负责获取新数据并将其写入数据库。我在某处读到过,确保父 Lambda 函数在其子函数完成工作之前不会超时是个好主意。

功能四:站点更新器

这个函数从数据库中读取数据,从两个可能的 HTML 文档中选择一个(基于二进制的“打开”或“关闭”状态),并将该文档推送到为我们的站点提供服务的 s3 存储桶:

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

2020 年 9 月 21 日:网站备份

现在,我们正在抓取数据,将数据存储到数据库中,并引用该数据库向静态的 S3 网站编写 HTML 我们拥有了一个活生生的 web 服务!

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

一个朋友让我注意到了 TerraForm,因为我一直陷在 AWS 粉丝的泡泡里,所以我不知道它的存在。对于任何对“基础设施即代码”感兴趣的人来说,TerraForm 似乎是下一个自然要学的东西(例如,在 AWS CloudFormation 或 Google Cloud Deployment Manager 之后)。

功能五:图形统计生成器

这个想法是建立一个小 Plotly 仪表板页面,显示按星期几和一天中的小时数汇总的草坪开放历史数据。

在我可以构建一个汇总统计页面之前,我会让我的 lambda 函数将大约一周的数据刮到 RDS 数据库中,同时我会申请工作、烹饪千层面和各种丰盛的汤,并玩《野性的呼吸》。

我将在 2020 年 9 月 28 日左右回到这个话题。

2020 年 9 月 28 日:统计页面

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

现在起来了!

简单的统计页面正在工作!目前,这只是一张根据我的 2x/小时采样显示布莱恩特公园草坪在一天和一周不同时间的历史平均开放度的热图。

为了添加这个页面,首先我编写了一个 lambda 函数,将我的 RDS SQL DB/table 完整地导出到 S3 桶中的一个. csv 文件中,这样我就可以下载它,并在 Jupyter 笔记本中对它进行试验。有时尽可能多地在本地调试真的很有帮助,因此在这个小项目中尝试 SAM。

然后,我修改了 Jupyter 生成的工作 viz 生成器代码,使其返回到 Lambda 函数(V)中,该函数每 12 小时更新一次新的“stats”页面

让我困扰的是再加一个。我的 s3 存储桶站点的 HTML 页面没有自动使该页面在浏览器中“可加载”。当我在调试时,我的浏览器一直试图下载。HTML 文档到我的本地驱动器,而不只是呈现它。烦人!

起初,我认为这是因为 S3 网站不支持服务器端脚本,也许我不小心包含了一些服务器负责的代码…?但是没有。网络搜索让我意识到,我只需要确保在上传(put)时包含 s3 对象的“内容类型”,以便它能被正确地服务:

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

包括 boto3 AWS Python API 中的 ContentType 标记,用于网页渲染

结论

有了这些,我觉得我已经准备好去做一个不那么俗气的项目了!在未来,我想研究一下:嵌套的 CloudFormation 堆栈,远离 HTML/CSS/ES6 (TypeScript?节点?反应?),并在我未来的更多项目中利用一些机器学习(回归/分类),这是我已经非常熟悉的东西。我也很好奇卡夫卡/SQS、DynamoDB,以及管理用户凭证和会话;在写这本书的时候,我对这些东西知之甚少。

我最兴奋的是有机会解决一些现实世界的问题!如果你认为我可以开发一些软件,让你的生活(重复的、烦人的部分)变得更容易,或者如果你自己正在构建一些东西(开发团队?)你认为我能帮上忙。

从数据角度看炉石

原文:https://towardsdatascience.com/dive-in-hearthstone-from-a-data-perspective-e3c0b2851686?source=collection_archive---------39-----------------------

从牌组和卡片的棱镜看炉石

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

你好,在这篇文章中,我将详细介绍几周前我在炉石游戏上建立的一个数据集。

炉石科扎科!?

炉石是由暴雪在 2013 年制作的一款在线卡牌游戏,也就是说使用了暴雪在 1994 年开始的专营权魔兽的传说。我就不详细挖掘这个游戏的起源了,但是我会邀请你来看这个电竞一言以蔽之的视频。

这个游戏的原理相当简单;你从 9 个可用英雄中挑选一个开始;每个英雄都有一个特殊的能力,并且可以使用一些特殊的卡片。

如果你想了解更多,你可以在这里找到更多关于英雄们的细节。

在选择英雄之后,玩家必须遵守一些规则来建立他的牌组:

  • 从三个类别(仆从、能力和武器)中选择 30 张牌
  • 它不能包含两次以上相同的卡
  • 它不能包括专属于另一个英雄的卡片

在那之后,当一场炉石比赛开始时,每个对手都有 30 个生命指示物,要使用你在每回合结束时或使用某些特定牌时获得的法力来出牌。

我不想输入太多比赛进程的细节,但我会邀请你观看这个解释炉石原理的视频。

我喜欢这个游戏,我在 2013 年它发布时开始玩它,我觉得它很有趣。我认为我在炉石游戏中更像是一个休闲玩家,因为我只是在几周内的暴雪会后定期重启游戏,重启总是很痛苦,因为游戏的元数据改变了,等等。

几年前,我发现了这个关于炉石的 Kaggle 数据集,一些卡牌是在一个叫 HearthPwn 的网站上刮出来的。

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

这是一个围绕游戏(卡牌、卡片、比赛)分享的社区,我强烈推荐你去看一下。

所以就数据而言,Kaggle 上的数据集包含大约 360000 副牌。尽管如此,它还是老了,所以我决定建立一个系统来收集 Hearthpwn 的数据(与我的 CrossFit 文章中的过程相同,提醒一下,当你在刮的时候,不要做傻事,不要让服务器过载等等)。).

我收集了大约 800000 副牌和牌上的所有信息(我不分享数据集,因为我不是所有者)。

卡片和副牌概述

这个数据集中有趣的一点是在网站上制作了一些套牌的用户(贡献者)的数量以及他们正在制作多少套牌。在这个箱线图中,有贡献者建造的甲板数的四分位数(不包括传单)。

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

大多数用户只生产一个甲板(0-50%),其中 25%的用户生产 1-3 个甲板,在最后一个四分位数,他们生产 3-6 个甲板。我根据每个玩家建造的甲板数量做了一些分类。

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

现在让我们来看看每周发行的套牌。

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

大部分重要的内容发布之后是一批 Hearthpwn 上的新甲板(感谢明显船长)。

从英雄的角度来看,一些偏好正在浮现。下图是英雄内置函数的套数。

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

前三名的英雄似乎是牧师、法师和圣骑士,而且没有一个非常有统治力的。

从副牌中的牌的角度来看,我对副牌中的牌的类型做了一个简单的评估。

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

该图可能不清楚,但其目的是说明一副牌中的牌的重新分配,该图显示,例如,50%的牌具有:

  • 0 件武器
  • 0 到 10 个咒语
  • 0 到 17 个小黄人

正如我们所看到的,大部分的卡牌都没有使用武器,而且拥有更多的小喽啰似乎是比法术更好的计划。

现在让我们来看一下更高级的数据分析。

英雄 VS 套牌 VS 卡片

从卡片的角度来看,英雄们在相关卡片的重新分配上有一点不同。

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

大多数武器都与战士/盗贼/猎人/萨满和圣骑士有关,每个英雄都有大约 150 张卡片。现在让我们从一个奴才的角度来看一下对套牌内容的评价。

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

术士似乎是那种需要比普通玩家拥有更多的爪牙的英雄。让我们从法术的角度来看。

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

术士是从群众中崛起的(不是跟着跟班潮流)。最后,让我们看看武器方面。

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

在最后两个图表中,我们展示了在卡中拥有武器的特定英雄身上武器的用法。

我将花一些时间来分析与特定英雄相关的卡片的更多详细信息。先来分析一下卡的成本。

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

我们可以看到,费用上的第一个四分位数对于所有的英雄都是一样的,费用值是 2(快速发挥)。除了德鲁伊,第二个四分位数的牌的成本在 2 到 3 之间。在第三个四分位数中,英雄身上发生了一些分裂:

  • 成本 5(术士/牧师/战士/猎人/圣骑士/法师)
  • 费用 4(盗贼/萨满)
  • 成本 6(德鲁伊)

从一般的角度来看,这个分析说明了基于英雄能力的游戏性的不同。现在让我们来看看卡牌的宠物一面的攻击/生命值。

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

在小黄人(生命值/攻击值)方面,英雄之间的 boxplot 没有显著差异。

现在让我们看看取决于英雄的总费用/攻击/生命值。

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

从成本角度来看,我们可以看到,术士的价值范围很广,从 20 到 220 左右。大约在第三个四分位数,所有的英雄都有接近 100 马纳斯的中间值(也许对于建造一副牌来说是个不错的选择)。现在让我们看看牌组的攻击点。

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

从攻击的角度来看,德鲁伊拥有最广泛的价值范围(0-122 左右),但是一副牌的总攻击中值似乎在 50 点左右。让我们看看甲板的健康状况。

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

在这种情况下,对于所有的英雄来说,生命值的范围是相当大的,但是我要说的是中间值大约是 70 点。

这种分析是非常高层次的数据集,并且似乎一般在 Hearthpwn deck 上构建:

  • 大多数包含少于 17 个爪牙/ 10 个法术/ 0 件武器
  • 这副牌的平均成本大约是 100 法力值
  • 副牌的攻击中值约为 50 点
  • 甲板健康的中位数大约是 70 分。

除了这些发现,所有这些数据给了我一些想法。

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

为什么不建立一个卡片推荐系统?

如何建立一个(简单!)炉石卡牌推荐

老实说,这不会是我要做的最疯狂的推荐系统,但是让我们从小处着手。对我来说,最直接的推荐系统是“最受欢迎的商品”推荐系统。

每个英雄(以及所有套牌中)的卡片使用是这个推荐器的核心。在下表中,我为每个英雄制作了前 25 张卡片(但是你可以在这个谷歌电子表格上找到所有卡片的排名)。

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

我计划使用这个数据集作为推荐系统的文章来源。就过程/算法而言,机器学习领域令人兴奋,关于这个主题的一本好书是 P 金·福尔克的实用推荐系统。

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

老实说,这是一本关于这个主题的极好的书,我想我会把它作为我未来文章的框架。

敬请关注,不要犹豫,给一些反馈。

最初发布于 2020 年 1 月 15 日 http://the-odd-dataguy.com

深入研究 Python 中的队列模块——它不仅仅是 FIFO

原文:https://towardsdatascience.com/dive-into-queue-module-in-python-its-more-than-fifo-ce86c40944ef?source=collection_archive---------14-----------------------

多线程的良好候选

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

micha Parzuchowski 在 Unsplash 上拍摄的照片

队列是一种非常实用的数据结构。通常与数组链表、线性数据结构相比较。线性结构与其他结构的不同之处在于添加和删除发生的位置。

队列数据结构有三种类型: FIFO、LIFO优先级队列。Python 中的队列模块实现了所有这些类型。此外,它在线程编程中也非常有用,这使得这个模块更加闪亮。

在本文中,我将首先帮助您更新关于数据结构的知识,并学习如何使用模块queue。然后我将向您展示如何使用queue来解决 2 个不同的多线程问题。最后我会说说这个模块的利弊。

数据结构

在讨论一些高级特性之前,让我们先来讨论一下队列数据结构,并学习如何使用该模块来创建一个“简单”的队列。

先进先出——先进先出

这是队列的基本类型。首先插入的元素将首先被删除,这类似于现实世界中的等待列表。越早加入名单,你就能越早得到音乐会的门票。

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

先进先出()

Python 模块提供了实现 FIFO 队列的queue.Queue()queue.SimpleQueue()queue.SimpleQueue()是 Python 3.7 中的新特性。它们之间有两个不同之处:

  1. SimpleQueue()线程编程中不做任务跟踪。线程编程将在后面讨论。
  2. SimpleQueue()是一个无界 FIFO 队列,而Queue()可以有一个上限。在这两个类中,如果队列为空,get()操作将被阻塞,直到新元素被插入。在Queue()中,如果队列已满,put()操作也将被阻塞,直到元素被移除。这种情况绝不会发生在SimpleQueue()身上。根据 Python 文档,可以在get()put()中使用block=False来禁用该块,然后你会立即收到一个queue.Fullqueue.Empty异常。

queue-fifo.py

后进先出法

LIFO 队列还有一个名字:Stack。最后插入的元素将首先被移除。这就像超市的货架一样。人们通常会拿第一排最近添加的项目。

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

后进先出()

这在queue.LifoQueue()类中实现。除了移除元素的顺序之外,界面与queue.Queue()相同。如果您将结果与之前的结果进行比较,您应该会看到打印结果的差异。

queue-lifo.py

优先级队列

顾名思义,优先级队列赋予队列中的每个元素一个优先级。它首先弹出优先级最高的元素。在下图中,元素 5 具有最高优先级,因此它将是情况 2 和 3 中弹出的第一个元素。

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

优先队列()

现在的问题是 Python 如何决定优先级?在队列模块中, 最低值的条目首先被检索 。该值越低,其优先级越高。那么在前面的例子中,2 实际上比 5 具有更高的优先级。这是因为 Python 优先级队列内部使用了 最小堆队列算法 。最小堆的一个特性是最小的元素是第一个元素。

堆实际上是一棵二叉树,其中节点的值小于其子节点的值。当一个新节点被推送到树中时,树将被再次排序。根节点总是下一个要检索的元素。push()pop()操作的时间复杂度分别为 O(log n)和 O(1)。

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

闵堆()

queue-priority-simple . py

优先级队列不仅适用于数字,也适用于复杂的数据类型,如元组或定制类,只要对象是可比较的。为了使一个类对象具有可比性,你需要实现几个丰富的比较方法。更简单的方法是使用[@dataclass](/understand-how-to-use-namedtuple-and-dataclass-in-python-e82e535c3691),dataclass 可以用 config [order=True](https://docs.python.org/3/library/dataclasses.html#module-level-decorators-classes-and-functions)为你实现这些方法。

在本例中,对象首先按排序,然后按排序。

queue-priority-advanced . py

线程编程

队列数据结构有很多应用。一个众所周知的用例必须是消息队列,其中我们有一个生产者和一个消费者。生产者和消费者通常位于不同的线程中。幸运的是,Queue()类有一个线程安全的实现,带有所有需要的锁定机制。因此,来自不同线程的生产者和消费者可以安全方便地使用同一个队列实例。

本质上,队列存储了许多要完成的“任务”,线程可以将任务插入队列,并在任务可用时从队列中取出任务,然后完成任务并返回进行下一个任务。

如果你是 Python 线程的新手,我强烈推荐你阅读 Real Python 的Python 线程介绍。这是一篇非常好的文章。

[## Python 线程介绍——真正的 Python

立即观看本教程有一个由真正的 Python 团队创建的相关视频课程。和书面的一起看…

realpython.com](https://realpython.com/intro-to-python-threading/)

好的,我假设你已经阅读了这篇文章,并且很好地理解了threading模块在 Python 中是如何工作的。让我们把它与Queue()课结合起来。我在这里举了两个例子。它们是略有不同的用例。

例 1 :创建一个图片 URL 队列,用多线程“并行”下载那些图片。(如果你不明白我为什么在这里加引号,请阅读上面的文章)

我将在这个例子中使用save_image函数。

def save_image(id, url):
    with open(f'pic{id}.jpg','wb') as image:
        response = requests.get(url, stream=True)
        for block in response.iter_content(1024):
            if not block:
                break
            image.write(block)

每个Thread对象都有启动线程的start()方法,还有通知主线程等待直到线程 x 完成运行的join()方法。我们可以这样解决问题:

download-images-1.py

由于Queue()是为多线程设计的,它还提供了 2 个方法,支持任务跟踪:Queue.task_done()Queue.join()Queue.task_done()表示队列中的一个任务已经被处理,通常在get()之后调用。Queue.join()类似于Thread.join(),它将阻塞主线程,直到队列中的所有任务都被处理完。但是你不必创建一个工人列表workers并在最后做一个循环来加入每个线程,只需做一个单独的queue.join()。让我们检查一下代码。

下载-图片-2.py

例 2 :创建一个消息队列,一个生产者,一个消费者。来自不同线程的生产者和消费者能够与同一个队列实例进行交互。生产者将发送一个警告消息告诉消费者停止这个过程。

在示例 1 中,我们让 10 个不同的线程执行相同的功能。但是在这个例子中,两个线程正在做完全不同的工作。由于 Python 线程中没有真正的“并行处理”,所以一个线程将首先完成这项工作。在这种情况下,首先触发生产者线程,然后触发消费者线程。您也可以在结果中看到这种行为。

如果我取消第 9 行的注释,结果会是什么?想想吧!😄

生产者-消费者-队列. py

如果我在每个put()操作之前暂停生产者线程,那么我们将更清楚地看到生产者和消费者之间的交互。

Insert element 0
Retrieve element 0
Insert element 1
Retrieve element 1
Insert element 2
Retrieve element 2
Insert element 3
Retrieve element 3
Insert element 4
Insert sentinel
Retrieve element 4
Receive SENTINEL, the consumer will be closed.

结论

**queue**的一个明显优势就是它的线程安全特性。但我们不能把这种便利视为理所当然。如果我们没有线程安全queue会发生什么?如果我想在多个线程之间共享一个字典或者一个定制的类对象怎么办?

对于初学者来说,他们可能会遇到比赛条件的问题。同样,同一篇文章有一个关于竞态条件的非常直观的例子。基本上,相同的值不会在线程间同步。一个解决方法是使用threading.Lock()。但是它需要一些额外的代码和额外的注意力来控制线程。

另一个优势是避免潜在的内存爆炸。如果生产者的工作速度比消费者快得多,那么任务将被存储在“管道”中,直到到达内存边界。在这种情况下,maxsize属性可以避免这个问题。

****queue** **也有助于程序减少繁忙的等待。程序不需要一直试图从“管道”中拉东西,但是线程会被阻塞,直到数据可用。

同时,我们也应该理解queue的局限性。queue使用多线程,所以程序不会因此运行得更快。另外,maxsize指的是队列中的项目数,而不是内存大小。所以,还是有可能达到极限的。

我希望你喜欢这篇文章!如果你有任何想法,请在下面留下你的评论。

参考资料:

**[## 队列——一个同步的队列类——Python 3 . 8 . 3 文档

源代码:Lib/queue.py 该模块实现了多生产者、多消费者队列。它在…方面特别有用

docs.python.org](https://docs.python.org/3/library/queue.html)** **[## heapq -堆队列算法- Python 3.8.3 文档

源代码:Lib/heapq.py 这个模块提供了堆队列算法的实现,也称为…

docs.python.org](https://docs.python.org/3/library/heapq.html)**

背离棒线,为什么&如何

原文:https://towardsdatascience.com/diverging-bars-why-how-3e3ecc066dce?source=collection_archive---------18-----------------------

用分歧讲故事

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

图片来自 Unsplash

术语 divergent 来自拉丁语,表示分离或不同。它是意见的不一致、不一致、差异、交叉和争论的同义词。它意味着对某一特定问题的不同意见或分歧。它还用于表示这些问题之间的差异正在增加。自然,必须有一些视觉表现来显示这一方面是人类的特征。分叉棒线是最适合此目的的图表。

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

图 1:发散堆积条形图,SD:强烈不同意;d:不同意;n:没意见;答:同意;山:非常同意。图片作者。

为什么:发散条形图是为了方便多个类别的比较。它的特殊设计有助于对比特定类别中的数值。它的主要应用是正确显示问卷或调查的结果,尤其是那些使用 Likert 量表的结果。它能让我们快速想象出那些不利的、不想要的或消极的积极的、想要的或正面的反应。

如何操作:传统的变体由两个水平条组合而成,其中一条从右到左,另一条从左到右,两者都从一个公共的垂直基线开始,通常位于图表的中心。与所有条形图不同的是,每个条形的长度与其要显示的数值成比例。每个条形代表一个类别,它们之间通常留有一些空间。

发散条的最佳编码是当只有两个备选项需要比较时。L. Verde Arregoitia 使用该图“代表峡谷不同斜坡上的两个平行植被横断面,其中在五个采样点记录了本地植物和外来植物”(#1)。这张图表清楚地显示了引进植物和本地植物在物种数量上的对比。这些类型的图表也被称为双边,对立,滑动,或双向条形图。

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

图 L. Verde Arregoitia 使用的分叉棒线,来源:(#1)。

通常的做法是使用不同的颜色和不同的颜色强度来区分向左的线条和指向另一侧的线条。基线左侧的值不一定表示负值,但通常是不需要的或不令人满意的响应。还可以方便地将条形按升序或降序排列,以便于讲故事。

最普遍的变体是发散堆积条形图(图 1)。它们是水平堆叠条形图的延伸,增加了一条垂直基线。每个条形被分成一个接一个堆叠的水平矩形段。由线段指示的数值可以是绝对值或百分比(相当于单个堆积条形图与 100%堆积条形图,#2)。

发散堆积条形图广泛用于显示通过李克特量表分析的调查结果。当被不同的人口统计类别分开时,他们可以比较受访者的回答。显示有利或有利结果的线段通常显示在基线的右侧,而代表不利或不利结果的线段则放在中心线的左侧。在某种类型的中性反应的情况下,它位于中心基线之上。

李克特量表是社会心理学家伦西斯·利克特在 1932 年的博士论文中提出的。当调查的参与者被咨询以对他们对咨询项目的同意程度进行分类时,使用它。最常用的量表包括以下五种回答备选:**强烈不同意、不同意、中立、同意、强烈同意。**虽然 5 点李克特量表是最常见的,但其他作者包括了具有不同数量响应的其他量表(图 4),甚至还有仅包含两个选项(如有趣和不有趣)的语义差异量表。视觉标度和表情符号也被用作指示备选方案的非文本方式(图 3)。

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

图 3:李克特量表的表情符号,来源:(#3)。

下图显示了 2016 年总统大选前在美国进行的一项调查结果(#4)。该调查涉及不同人口类别对选举进程之外的政治的态度:年龄、性别、政党、教育水平和种族。有四种可能的回答:两种赞成永久参与政治,两种不愿意。可以看出,与婴儿潮一代和老年人相比,年轻人对政治持不情愿的态度。受教育程度也是如此:51%拥有大学或更高学位的人大部分时间都对政治感兴趣,而最不感兴趣的是那些没有完成高中学业的人。发散堆积条形图无疑是一种非常有效的可视化策略,可以在相对较小的空间内显示大量信息,便于比较、对比和讲述故事。观察到颜色和颜色强度的适当使用来区分四个备选方案。

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

图 4:由分叉条表示的调查响应。来源:#4。

理查德·黑贝格(Richard Heibegger)和内奥米·罗宾斯(Naomi Robbins)在他们 2011 年的论文《绘制李克特和其他评级量表》(Plotting Likert and Other Rating Scales)中热情地为背离的堆叠条形图辩护。作者举例说明,回顾和评论了一些在研究中使用的图表技术,如李克特量表。他们将背离的棒线与标准的、分组的、堆叠的和多重的棒线图进行比较。他们还将它们与表格、雷达图、带状图和华夫饼图表进行比较。他们总是得出这样的结论:发散堆积条形图最适合用于比较人口统计、职业和其他类别的调查结果。

发散堆叠棒线遇到了与标准堆叠棒线相同的困难:随着分段数量的增加,观众可能会感到困惑,讲故事变得更加困难。基于这个原因,的分段数不应该超过五个。有利于发散棒线的一个区别是,通过有一个中心基线,这些线段中的两个与该基线接触,这使得比较它们更容易。

Python 没有绘制分叉棒线的特定功能。最常见的策略之一是使用堆叠的水平条*(barh(stacked = True))*后跟一条*axvline*指令,在图的中心画一条垂直线。你也可以使用*hlines*,一个绘制水平线的函数,用某个值*linewidth*来模拟那些线,实际上,是水平的线条。这两种策略都需要一些预先编码来确定将要水平堆叠的段的长度和顺序。Tableau、Power Bi、Excel 和其他复杂的可视化工具也需要一些前期工作才能获得专业水平的结果。

蝶形图非常类似于发散条形图,每个类别或变量有两个水平条。在蝴蝶图中,只有两组数据可以使用两个带有中心基线的水平条进行比较,类似于蝴蝶的翅膀。蝶形图通常在条形之间留有空间,用来放置被比较变量的名称(图 5)。一些可视化工具将蝴蝶图与龙卷风图相匹配。然而,后者通常仅用于根据选定输入变量的变化对输出变量进行不确定性和敏感性分析(#7)。

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

图 5:蝴蝶图。资料来源:#8。

不要将堆积条形图与人口金字塔混淆,这一点非常重要。人口金字塔是两个水平条形图的组合,代表给定人口中男性和女性人口的年龄结构。按照惯例,男性表示在左边,女性表示在右边。

这种图表代表一个国家、地区或洲的居民分布,按年龄和性别划分。纵轴显示年龄(以年度或五年为一组,称为组群),横轴显示每个组群中男性和女性的总数或百分比。通常显示一对人口金字塔,每一个都代表某个时间或地点,以检测所研究人口的变化或趋势。

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

图 6:人口金字塔。图片作者。

结论:

发散条形图允许不同项目或类别之间的比较。它主要应用于使用李克特量表开发的调查或问卷的可视化分析。然而,人们应该始终考虑实际实现所需的额外工作是否在视觉上合理。

如果你对这篇文章感兴趣,请阅读我以前的(https://medium.com/@dar.wtz):

Mekko 图表,为什么和如何

[## Mekko 图表

为什么和如何

towardsdatascience.com](/mekko-charts-f38311c576e2)

仪表图和项目符号图,为什么和如何,用仪表讲故事

[## 仪表图和项目符号图

为什么&如何,用量表讲故事

towardsdatascience.com](/gauge-bullet-charts-cfe171ca3094)

参考文献:

【1:【https://luisdva.github.io/rstats/Diverging-bar-plots/】

#2:韦茨、达里奥,《堆积条形图,为什么&如何,讲故事&警告》,https://towardsdatascience . com/Stacked-Bar-Graphs-Why-How-f1 b 68 a 7454 b 7

3:https://www . vision metrics . net/en/blog/research/Likert-scale-overview/

**# 4:http://thebarchartguy . blogspot . com/2015/01/divergent-stacked-bars-survey-data . html

**# 5:http://www . asa SRMs . org/Proceedings/y 2011/Files/300784 _ 64164 . pdf

**# 6:https://www . Montana . edu/msse/Data _ analysis/Likert % 20 survey % 20g raphs . pdf

**# 7:【http://wiki.analytica.com/Tornado_charts】

# 8:https://www . slide team . net/butterfly-chart-tornado-chart-for-price-comparison-PowerPoint-slide . html

多样性是我们所需要的。

原文:https://towardsdatascience.com/diversity-is-what-we-need-98b5f09287c1?source=collection_archive---------36-----------------------

现在思考人工智能的未来。

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

照片:V.A. Merzmensch

你有没有想过所有的狗?随着 Google Deep Dream 的发布,AI 识别并放大了所有照片中的狗脸。到处,每个角落:狗,除了狗什么都没有。

这个谜团的答案很简单——但令人担忧:

在 Deep Dream 的案例中,数据集来自 ImageNet,这是一个由斯坦福大学和普林斯顿大学的研究人员创建的数据库,他们建立了一个包含 1400 万张人类标记图像的数据库。但是谷歌没有使用整个数据库。相反,他们使用了 2012 年发布的 ImageNet 数据库的一个较小的子集,用于一场比赛…这个子集包含“120 个狗子类的精细分类” (来源:fast company)

人工智能的 Pareidolia只能检测它所训练的模式和物体。数据集才是最重要的。它们越大,质量越好。

但是还有一个方面:贴标签。

你还记得比根那个令人兴奋的时代吗,你可以在历史上第一次把一只狗和一架航天飞机混在一起。

我发现了一个奇怪的现象。如果你想用 BigGAN ( 笔记本)生成一个乐器,你就得到一个音乐家。

法国号:

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

比根,566)圆号,法国号

萨克斯:

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

比根:776)萨克斯,萨克斯管

口琴

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

比根:593)口琴,口风琴,竖琴,口琴

唯一的解释是:给图片贴标签的人没有做好他的工作。它不是仅仅给一个乐器贴上标签,而是用一个乐器,包括一个演奏者,给整个形象贴上标签。正确的做法应该是给一张带有萨克斯管的图片贴上“萨克斯管”的标签,而不添加任何其他元素或特征。

如果你让一个在这个数据集上训练的人工智能驱动的机器人给你带来一个萨克斯管,它会给你带来一个萨克斯管演奏家,你不应该责怪机器。它使它的工作变得完美。这是关于我们,谁是错误的。

正如我们将看到的,不准确的贴错标签会导致可怕的后果。

另一个实验,我报道的关于的实验,已经显示了围绕标签不足而产生的问题:

凯特·克劳福德特雷弗·帕格伦用他们的 ImageNet-Roulette ( 现在离线)演示了贴错标签的危险。

你可以上传你的照片——砰!——你被系统描述了。该描述来自 ImageNet 中的标签,而这些标签是由人类书写的。不准确。带来毁灭性的后果。

对我来说,这或多或少是无害的(我上传了一张自己为萨沃米尔·mrożek):的舞台剧《卡罗尔》表演的照片

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

照片:v .佩雷尔曼

我被检测为不吸烟者(“不吸烟的人”)。我手中的巨大来复枪被艾瞄上了。

不过,也有其他案例,比如给某人贴上“强奸嫌疑犯”的标签:

一次性标签被曝光在 ImageNet 中贴错标签。这个项目和由两位艺术家举办的相关展览“训练人类”对 ImageNet 产生了影响:

ImageNet 背后的研究人员宣布,他们将删除数据集“人物”类别中 120 万张图片中的一半以上。(来源)

推特事件

你可能在最近几天偶然发现了这样的推文:

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

https://twitter.com/NotAFile/status/1307337294249103361

或者这个:

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

https://twitter.com/bascule/status/1307440596668182528

或者:

此外:

我在想,那里发生了什么事。如果你上传一张更大的图片到 Twitter,它会将你时间轴中的预览裁剪到图片的相关部分。如果您打开在此处裁剪的整个图像,您将看到以下内容:

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

人们对面部图像进行了实验,发现了一种可以被描述为“推特的种族主义”的现象,因为白人占了上风,被选为“相关部分”,与有色人种相反。

尽管如此,在奥巴马与猫的对比中,奥巴马是赢家:

推特上出现了一波可以理解的警告。

但是正如我们所看到的——问题仍然在标签上。我怀疑推特被训练成隐藏非裔美国人的种族主义意图,并被白人面孔所控制。或者被男人。

最有可能的问题是:数据集。他们缺少足够的多样性。他们都是白人。他们有偏见。人为因素。

我们需要更多的多样性。而不是作为“好心”搬东西的托辞。而不是“好吧,如果你幸运的话,这里有一些多样性”。

而是多样性作为一种基本的、不可或缺的、必要的、强制性的思维方式。

所以,亲爱的人工智能社区,亲爱的编码者,亲爱的贴标签者,亲爱的人工智能研究者,大家。

这不是演习。我们才刚刚开始培育和训练我们的人工智能系统。如果我们不站在一个角度思考,如果我们忽略了未来的思考,我们的 AI 就会有偏差。

万一 AI 会伤害人类,那是我们人类的错。

用动态填充和统一长度批处理将拥抱面部变形器训练时间除以 2 或更多

原文:https://towardsdatascience.com/divide-hugging-face-transformers-training-time-by-2-or-more-21bf7129db9q-21bf7129db9e?source=collection_archive---------10-----------------------

机器学习工程

减少训练时间有助于在固定的预算时间内进行更多的迭代,从而达到更好的效果。

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

上面的照片是由这个(免费用于非商业用途)和那个 (Pexel 许可,免费用于任何用途)制作的

2020 年 6 月 4 日更新:根据一项建议,在报告中增加了对口味卡门贝干酪进行的实验。TL;DR:训练时间从 4 小时减少到 1 小时 30 分。

我在 Lefebvre Sarrut 出版社工作,这是一家出版公司,是欧洲法律行业的主要参与者。正如前面的文章中所解释的,我们的需求要求我们在非常大的文本数据集上应用深度学习(法律案件匿名化、文档分类等)。),这就是为什么我们对让我们所有的(机器学习)工具变得更快如此感兴趣。

本着一篇先例文章的精神,这篇文章的目的是探索两个非常简单的优化,它们可以显著减少变形金刚库的训练时间,而不会对准确性产生负面影响。我们在一个大型的知名 NLP 数据集(X-NLI 的法国部分)上运行了 21 个实验+ 12 个再现性实验,我们表明,对于模型的基础风格,通过简单地使用现成的法国 BERT 模型( CamemBERT )、默认参数、单个消费级 GPU 和这些优化,我们可以达到最大令牌长度为 128 的**、最大令牌长度为 16 分钟的 比没有任何优化的 56 分钟训练获得的分数高出 0.5 分,比 CamemBERT 模型作者为此任务报告的分数高出 0.3 分。 在相同的模型上,对于 493 最大令牌长度,增益甚至更令人印象深刻,其中训练时间从没有任何优化的 4h38 减少到有所有优化的 1h01,仍然达到相同的分数。 大型 型号达到了类似的训练时间缩减(从 4h 到 1h30 为 128 令牌长度)。**

重现实验的源代码可从那里获得。

这些优化不是特定于任务/模型/语言的,但前提是下面的代码是为 Pytorch 编写的。

如果你对这个话题感兴趣,在推特上关注我:https://twitter.com/pommedeterre33

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

查看报告,看看权重&偏差是一个你不知道自己需要的强大工具

此外,我们记录了所有关于重量&偏差的实验,这是一种范围更大的在线张量板,所以你可以自己分析我们的实验结果,这里是的报道

(注意“等长配料”在报告上被命名为“智能配料”)

**“动态/可变长度填充”是 NLP 在 2017-2018 年的事情,但现在单个神经网络架构使得任何 GPU 所有者都能够在几乎任何任务上达到 SOTA 分数,似乎 NLP 社区已经将重点从寻找最佳批量大小转移到在神奇的架构上构建东西。“统一长度批处理”**是一个天真的想法,进一步推动我们想要检查的动态填充增益。

在撰写本文时,对于大多数常见任务来说,这两个工具在 Transformers 库上都不是现成的。

您只能在文本生成/语言建模任务中找到动态填充。有希望的是,我们将看到这两种技术都很容易在普通任务(分类等)的用户端实现。)并且我们认为大多数 NLP 从业者应该测试/使用它们。

在过去的一年里,来自拥抱脸的变形金刚库成为使用大型预训练语言 NLP 模型的标准方式。它附带了大量的功能,涵盖了大多数 NLP 用例,并且有一个完美的 API,直到你开始期望它是完美的。自从版本 2.9 带给我们训练器类以来,这种感觉更加强烈,这是一个精心设计的 William Falcon 的 Pytorch Lightning 训练 API 适应特定的变压器要求,它将用户从大多数工程方面的训练中解放出来(张量板测井、混合精度、梯度累积、多 GPU 设置等)。)因此是微调模型的新的默认方式。

在一切都如此完美的情况下,你倾向于相信一切都被优化到了极致。不要忘记,这个库还很年轻,团队同时在几条战线上工作(最近的例子是与来自 Azure DevOps 的吴合作,利用 ONNX 和在一些设置中减少推理时间。当你深入图书馆时,你可能仍然会发现一些有趣的低挂水果。

我们进行了实验,总结了我们在下面和那里的发现。

如果你还不是“填充/注意力面具”专家,你可能想再读一遍这篇为《老式 RNN》写的优秀的文章(摘自威廉·法尔肯 …!).简而言之,在一批序列上训练神经网络要求它们具有完全相同的长度,以构建批矩阵表示。由于现实生活中的 NLP 数据集总是由可变长度的文本组成,我们经常需要通过截断它们来缩短一些序列,并通过在末尾添加一个重复的假标记(称为“填充”标记)来延长一些序列。因为填充令牌不代表真实的单词/子单词/信号,所以当大多数计算完成时,在计算损失之前,我们通过注意力屏蔽矩阵将填充令牌信号乘以 0 来擦除它。

这两种优化背后的主要思想是尽可能避免不使用的计算:

  • 动态填充:我们限制添加填充令牌的数量,以达到每个小批量的最长序列的长度,而不是为整个列车组设置一个固定值。因为添加的令牌的数量在小批之间变化,所以我们称之为"动态"填充;
  • 统一长度批处理:我们通过生成由相似长度序列组成的批处理来进一步推动逻辑,因此我们避免了极端情况,即迷你批处理中的大多数序列都很短,我们需要为每个序列添加大量填充标记,因为同一迷你批处理的 1 个序列非常长。

此外,我们检查了第三种选择的好处,混合精度,它单独使用或与上述两种技术结合使用的价值。

设置

为了检查这些优化是否与基于 transformer 的语言模型配合良好,我们在 X-NLI 的法语部分运行了 14 个不同设置的实验。

如果你不知道 X-NLI,它基本上是一个句子对分类任务,其中模型需要猜测第二个句子与第一个句子相比是否需要/矛盾/中性(3 类)。X-NLI 训练集是大型英语数据集的机器翻译,测试集由来自同一英语数据集的 15 种语言(包括法语)的 5K 对人工翻译组成。

用于实验的模型是卡门贝塔建筑,由脸书费尔和 Inria 实验室用法语文本训练而成。存在几种口味,下面的数字与已经发布的第一种相关,在变形金刚中称为卡门贝干酪基(在 130 Gb 数据上训练的 110 万个参数)。camembert-large实验报告中均有。

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

Camembert 论文作者在 10 epoch s 中达到了 81.2%的准确率,提前停止,1e-5 学习率,512 个令牌的序列长度以及其他一些东西

对于每个实验,我们将训练限制在 1 个时期,因为我们只能使用单个 GPU 来运行所有实验。所有运行都使用相同的种子(不同种子的“再现性”实验除外,如下所述)。除非另有说明,超参数保持默认值,因为我们没有资源对每个实验进行网格搜索。正如我们将看到的,在大多数实验中,我们在 X-NLI 上击败了作者报告的分数,所以默认设置可能已经足够好了。

X-NLI 主要由短句对组成:当短句对的两个部分连接成一个序列时,超过 97%的短句对长度小于 128 个标记。这种长度分布对减少培训时间的机会有很大影响。简而言之,在这个数据集上,即使在消费级 GPU 上,也可以在 128 个令牌处截断序列来构建“大型”批处理。在一个更平衡的数据集上,比如 T2 的马可女士,你需要 512 个单词的限制才能接近 SOTA 的平均倒数排名。在这两种情况下,这里介绍的两种技术带来了大量的训练时间减少(2 倍或更多),但出于不同的原因,我们将在下面进行分析。在我们对私有数据集使用这些优化时,无论数据集的特征如何,我们总是对训练时间产生显著影响。

时间和精度是在单个 Nvidia 2080 TI GPU 上测量的。3 个优化选项的每个组合已经运行了 2 次,一次是将一批 64 个序列截短为 128 个记号,第二次是将一批 16 个序列(2 步 8 个序列和单个梯度累积)截短为 493 个记号。493 是字符数最长序列中的 Camembert 子词标记数,可能是训练集中标记数最长的标记序列之一。步长已被设置为该 GPU 在内存中可以占用的最大值。

计时包括中间评估(在我们的例子中是每 500 个小批量),因为在现实生活中,大多数 NLP 从业者都是这样进行培训的。

结果

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

每个组合随时间变化的精确度,报告中的交互式图表此处

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

TL;博士:

定时

  • 单独使用动态填充可以显著减少训练时间,这可以通过使用统一大小批处理和混合精度来增强;
  • 在一些设置中(小批量+短序列),混合精度可以产生更长的训练时间,在其他情况下,它是游戏改变者(大批量和/或长序列)。

精度

  • 在 14 次运行中,有 11 次在单个时期内获得了 81.18%以上的分数(Camembert 论文中报道的 10 个时期的分数,并提前停止);
  • 当我们比较成对的运行(相同的设置,在 128 处截断与在 493 处截断)时,不出所料,截断平均具有(小的)准确性成本,即使只有 3%的数据集与 128 令牌截断有关。

通过使用优化和混合精度,我们在 16mn 训练中击败了 4h38 训练的分数!

基础模型的发现与大型模型相同,额外 12 个实验的测量结果在报告中。

优化机会

当你要抛出结果时,避免计算

如上所述,pad 令牌信号通过应用注意屏蔽来消除。序列末尾的填充标记越多,执行的未使用的计算就越多。

在训练器类中,您定义了一个(固定的)序列长度,训练集的所有序列都被填充/截断以达到该长度,没有任何例外。在 X-NLI 上,最短的序列是 10 个记号长,如果你提供 128 个记号长,你将把 118 个填充记号加到这 10 个记号序列上,然后在这 118 个有噪声的记号上执行计算。

最差,如原伯特回购自述“…注意是序列长度的平方。换句话说,一批 64 个长度为 512 的序列比一批 256 个长度为 128 的序列要贵得多。”

小批量由从数据集中取样的少量序列组成。即使在 X-NLI 中随机选择,小批量中的最长序列也有可能比整个训练集的最大序列长度短。因为学习/梯度下降是在小批量水平执行的,所以我们有机会限制填充效应,更准确地说,我们可以首先在小批量中搜索最长的序列长度,然后相应地填充其他序列。

这些操作可以在 collate_fn 功能中执行。该函数的用途在 Pytorch 文档中有所描述,基本上它采用数据集返回的单个示例,并将它们合并以构建张量矩阵,并将其发送至模型。

动态填充

如上所述,这个想法是在小批量水平而不是数据集水平调整序列长度。这样我们可以限制未使用的计算。该工作在 Pytorch 数据加载器内进行。让我们提醒一下它是如何工作的:

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

Pytorch 数据加载器内部

组件:

  • Dataset() 是访问原始文本数据的砖块,是一个简单的字符串列表或类似数据库连接器的东西;
  • Sampler() 生成索引,指向数据集中的一个数据点。它遵循一种策略,例如顺序生成(对于测试集)或随机生成(对于训练集)。
  • collate_fn() :对于每个小批量,它接收由采样器选择的数据点(来自数据集)并将它们分组到一个张量中(理论上它可以是其他东西,但通常这是您期望的数据加载器输出/模型输入)。

collate_fn 是执行动态填充的最佳位置。幸运的是,Pytorch Dataloader 在其构造函数中有一个参数来提供我们自己的实现,不需要覆盖任何东西。变形金刚库中的训练师类在其构造函数中有一个类似的参数,我们将使用它。它不是一个函数,而是等待一个“整理器”(一个特定于 Transformers 的类)的实例,它只有一个目的,包装 collate 方法。

在下面找到一个可能的排序器类的实现。

*# ...*def **pad_seq**(seq: List[int], max_batch_len: int, pad_value: int) -> List[int]:
 *# IRL, use pad_sequence
    #* [*https://pytorch.org/docs/master/generated/torch.nn.utils.rnn.pad_sequence.html*](https://pytorch.org/docs/master/generated/torch.nn.utils.rnn.pad_sequence.html)
    return seq + (max_batch_len - len(seq)) * [pad_value][@dataclass](http://twitter.com/dataclass)
class **SmartCollator**(DataCollator):
    pad_token_id: int def **collate_batch**(self, batch: List[Features]) -> Dict[str, torch.Tensor]:
        batch_inputs = list()
        batch_attention_masks = list()
        labels = list()
        *# find the max length of the mini batch*
        max_size = max([len(ex.input_ids) for ex in batch])
        for item in batch:
            *# apply padding at the mini batch level*
            batch_inputs += [pad_seq(item.input_ids, max_size, self.pad_token_id)]
            batch_attention_masks += [pad_seq(item.attention_mask, max_size, 0)]
            labels.append(item.label)
        *# expected Transformers input format (dict of Tensors)*
        return {"input_ids": torch.tensor(batch_inputs, dtype=torch.long),
                "attention_mask": torch.tensor(batch_attention_masks, dtype=torch.long),
                "labels": torch.tensor(labels, dtype=torch.long)
                }

动态填充有助于减少训练时间吗?

我们运行了 4 个实验,按每批大小进行分组,对于每组,我们比较了使用和不使用动态填充的情况。当为以下情况启用时:

  • 16 批未截短的序列,时间从 4h39 减少到 0h 59(-79%);
  • 64 个序列的批次被截短为 128 个标记,计时从 0h56 减少到 0h48 (-15%)。

在这两种情况下,计时减少都是显著的,并且对于长序列是 4 倍强。这是有意义的,在训练集中,97%的例子短于 128 个令牌,所以对于大多数例子,我们为拥有 493 个最大序列大小而缴税。通过使用优化,我们只为有用的计算付费。

对于 128 个记号的截断,仍然有增益,因为大多数序列仍然比 128 个记号小得多,并且 BERT 复杂度关于其输入长度是二次的,避免的计算成本低得多,并且训练时间减少“仅仅”15%。

会影响准确性吗?

我们运行了 4 个实验,按每批大小进行分组,对于每组,我们比较了使用和不使用动态填充的情况。当为以下情况启用时:

  • 16 批未截短序列,准确率从 81.42%提高到 82.0%;
  • 一批 64 个序列被截短为 128 个标记,准确率从 81.0%提高到 82.0%。

在这两种情况下,动态填充都可以提高精度。

均匀尺寸配料

统一批量生产由简单地构建由相似长度序列制成的批次组成。目的是在与动态填充结合使用时尽可能减少填充。

有许多方法可以实现它,我们遵循的方法是:

  • 在一个简单的 Python 列表中按长度对示例进行排序,
  • 随机选择一个索引,
  • 提取示例和后面的 n 个示例( n 为批次/步长),
  • 从列表中删除提取的示例,
  • 重复此操作,直到列表中不再有示例。

这样,每一批都是由相似长度的序列组成的,但是后面的几批是不同长度的。

天真(简单易懂/不干净)的实现可能看起来像这样:

统一大小批量真的能减少训练时间吗?

为了减少时间,我们之前已经展示了动态填充带来了大量的训练时间减少,让我们比较使用动态填充和不使用统一大小批处理以及启用两种优化的训练时间。用于:

  • 批 16 个未截短的序列,训练时间从 1h01 减少到 0h 52(-15%);
  • 一批 64 个序列被截短为 128 个标记,训练时间从 0h48 减少到 0h30 (-38%)。

所以在这两种情况下,我们天真的想法似乎带来了另一个显著的训练时间减少。

统一尺寸配料是否会以任何方式影响精确度?

通常,神经网络是在随机排序的数据点上训练的。均匀尺寸配料限制了这种随机性,因此引入了一种偏差,这种偏差在理论上可能会影响精度。

我们将只比较有和没有统一尺寸配料的设置:

  • 对于一批 16 个样品,当激活统一长度配料时,准确度从 81.4%增加到 81.6%;
  • 对于一批 64 个样品,当激活统一尺寸配料时,准确度从 81.0%提高到 81.7%。

在这两种情况下,都有改进,我们可以得出结论,对准确性没有负面影响。

然而,我们结合多种选择进行了许多实验,根据权重&偏差仪表盘,使用统一尺寸配料与准确性呈负相关。手动检查实验对后(有/没有选项),这种效果不明显。

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

(如果您想深入了解,请随时查看报告)

混合精度

通过 Nvidia apex 库,Pytorch 上的混合精度是可能的。简而言之,在其最常见的模式中,混合精度包括以半精度执行大多数操作,并以全精度累加结果(更多信息请参见 apex 文档)。

Apex 以在某些场景中带来改进而闻名,有时它也会带来一些不稳定性(例如,训练期间的损失幅度比没有混合精度时更大),并且很少避免模型收敛。换句话说,它不是一个银弹,而是一个有趣的工具来测试你的情况。

好消息是 Trainer class 实现了开箱即用,要利用它,您只需要在命令行中添加正确的标志(“— fp16”)。

关于 16 个长序列的小批量的训练时间,情况是不寻常的。用于:

  • 单独的混合精度通过将训练时间从 4h38 减少到 2h50 而使事情变得更好;
  • 混合精度结合动态填充和统一大小批处理,使得训练变慢,从 0h52 到 1h01!

原因可能是在第二种情况下,它增加了开销,并且没有多大帮助,因为大多数批处理只由短序列组成。混合精度对大型矩阵运算帮助最大。

当应用于 64 个短序列的小批量时,事情如预期的那样:

  • 单独使用时,时间训练从 0h56 减少到 0h26
  • 结合其他两个选项,时间从 0 时 30 分减少到 0 时 17 分

这一次,即使步长由短序列组成,每个包含 64 个序列,使得矩阵足够大,可以从混合精度中受益。

关于准确性,没有明确的模式。你可以通过查看权重&偏差 报告来自己拿主意。

重复的结果

所有的实验都是使用相同的种子进行的。可能我们很幸运,我们的方法达到了精度,但不是用这个种子和这个数据集。

我们在启用所有优化设置的情况下用不同的种子重新运行 16 分钟的训练 5 次,并且再现了准确度/计时。

对大模型也进行了同样的复制实验。结果是一样的。

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

还是那句话,想要互动图?-> 报告<—

一个结论?

我们已经证明,这两种技术都能在不降低准确性的情况下持续大幅缩短时间。此外,我们了解到,在具有小批量的数据集上,应该小心混合精度,因为如果没有足够的计算来执行,它可能会导致意外的训练变慢。

我们确信这两种技术都是唾手可得的,应该被变形金刚用户广泛使用。

总结一个更一般的想法,我们对这些简单的想法所获得的结果感到惊喜。只是为了这个故事,在另一个不相关的实验中,我们注意到 X-NLI 的法语训练集(它是英语数据集的机器翻译)质量很低(许多例子在法语中是绝对无意义的),我们想知道翻译质量更好的它是否会提高测试集(这是人工翻译)的准确性。这对我们来说是一个重要的机会,因为如果它成功了,就意味着有大量的法语数据集可以使用。我们在 DeepL 上花了几块钱,翻译好了很多……而且准确度也没变(我们甚至觉得我们的度量有 bug)。并非所有简单的想法都是平等的!

将数据科学视为预言

原文:https://towardsdatascience.com/divination-and-data-science-1ddda913b812?source=collection_archive---------49-----------------------

为什么占卜实际上与数据科学密切相关

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

Shreyas shah 在 Unsplash 上拍摄的照片

我从小就对文化和神话感兴趣。这项研究中让我感兴趣的一部分是占卜的艺术。出于这个原因,在我被监禁的这段时间里,我决定参加哈佛大学提供的关于占卜和他们的系统的在线课程。

据我所知,每种文化都有自己的方式来预测未来会发生什么,以及如何通过占卜师收集的数据来预测。没错,占卜其实和数据息息相关,和数据科学本身。在这篇文章中,我将尝试以简洁直观的方式解释占卜如何与数据科学相关联。

这篇文章只是纯粹的自以为是和知识的目的。没有任何其他方式贬低任何长期存在的做法已经存在。

占卜预测系统

根据维基百科的说法,占卜试图通过神秘的、标准化的过程或仪式来洞察一个问题或情况。简单来说,这意味着通过仪式过程了解未来。

根据他们的输入,占卜本身可以分为四个更广泛的类别,包括:

  • 随机;其中输入来自随机过程,有时也被称为**“自发的”**例如,罗马鸟预兆我们需要等待鸟儿自发行动后再做预测。
  • 随机化;其中输入是人类发起的以产生随机结果。比如掷骰子。
  • 人类;直接来自占卜者的输入或者除了占卜者之外任何人都不能解释的输入;例如,着魔的人。
  • 非随机;其中输入来自对任何一致的、可重复的、可预测的和可知的过程的观察;例如,测量行星的位置。

在某种程度上,上面使用的术语在数据科学领域非常熟悉。有一个输入,取决于我们有什么输入;产生预测的仪式类型也会不同。

这个仪式可以被想象成一个预测系统或者是一个用于预测的“算法”。在这个“算法”中,我们可以说,如果我们把“A”输入到“算法”,预测“B”;例如,如果木星在 273.87 度的位置,预测未来的浪漫生活。就像数据科学中的任何预测模型一样;“算法”没那么简单。

占卜系统中有意思的是,系统本身有时候有点不为外界所知;因为其中涉及到神秘主义,或者系统本身过于复杂,甚至因为它在历史上消失了。在数据科学预测模型中,就把这个想象成一个深度学习模型。它涉及到很多统计方法,系统真的很复杂,而且经过训练,由于它们的随机性,我们不知道里面发生了什么。我们只要有深度学习模型,我们输入观察到的数据,预测就出来了。太棒了。

以上只是一个有点勉强的例子,说明占卜类似于预测模型。如果我们一步一步地使用系统预测的例子,会感觉更自然。

占卜框架

1.观察

任何预言或数据科学领域的第一步总是观察数据。这是我们输入到“算法”中产生预测的输入。就像我们把数据输入机器学习模型一样。理论上,我们的观察越多,预测就越强。

2。预测

观察数据后,我们有了预测。预测的清晰程度因系统而异。虽然很少有预测是严格的,比如行星的位置;许多预测系统包含歧义,有意或无意的,不同的解释。

在数据科学中,以无监督学习中的聚类分析为例;我们将最终得到系统预测它们应该聚集在一起的聚类结果。作为数据科学家,我们如何解释这个结果将取决于我们。

3.评估准确性并做出更改

这个预测正确吗?就像在任何数据科学过程中一样,这是一个简单的问题,但实际上评估它是一个复杂得多的问题。看起来很奇怪,占卜需要评估他们的预测准确性,但这正在发生,尽管并不总是如此。事实上,许多占卜系统本身可以进化得更准确,但大多数时候我们不知道,因为历史已经湮没在时间中。

以古代美索不达米亚时期的春辣为例。haruhiscid 是一种仪式,他们牺牲一只羊并提取肝脏来获得预言。由于预测不可能产生 100%肯定或否定的结果,占卜者可能会进行另一种仪式来减少不确定性。在这种情况下,占卜者就像现代科学家一样,通过进行额外的实验来获取数据。

基于该方法的准确性,可以对系统进行一些改变。就像我们数据科学家玩超参数一样,系统中的一些变化肯定会发生。虽然,正如我之前提到的;大多数时候我们不知道预测系统中发生了什么变化,因为它在时间中丢失了。

数据科学中占卜的重要性

我已经在上面的文章中向你解释了占卜和数据科学在某些方面是相似的。事实上,很多占卜都是以数据为基础的。塔罗牌、占星术、罗马鸟占卜术等。它们都是基于发生的数据和模式。

占卜看似不科学,但却是人类的需要。占卜告诉我们未来会发生什么,或者解释过去和现在发生了什么。今天发生的事情与昨天不同,明天也会不同,因此,占卜师在帮助你理解社区的性质,社会的性质,正在发生的事件,当然,如何处理这些事件方面的重要性。

在现代,我们当然会消除由这种不科学的方法产生的任何意见。基于骰子或羊肝的预测会被认为是假的,不会被认真对待。出于这个原因,我们人类需要更多的理由来相信我们的预测是有根据的。在这里,我们发展了许多科学理由,只是为了确保将要发生的事情在某种意义上是可预测的。数据科学家只是碰巧做到这一点的角色之一。**我们尝试分析并创建一个基于数据的模型,根据输入数据预测会发生什么。**就像占卜一样。

不同于我们为个人日常生活而咨询的占卜师,数据科学家的需求来自于人类很久以前就想知道未来会发生什么的好奇心。因此,我们作为数据科学家所做的就离占卜者不远了。

结论

这篇文章纯粹是我的观点,以及我作为一名数据科学家如何看待占卜。作为人类,我们想知道模式和未来会发生什么的好奇心从未改变;只是我们获取知识的方式不同。

如果您喜欢我的内容,并希望获得更多关于数据或数据科学家日常生活的深入知识,请考虑在此订阅我的简讯。

如果您没有订阅为中等会员,请考虑通过我的介绍订阅。

深入探究 AWS Lambda

原文:https://towardsdatascience.com/diving-deeper-into-aws-lambda-a52b22866767?source=collection_archive---------13-----------------------

了解 Lambda 的基本基础设施,如何运行可执行文件和解析 CloudWatch 日志

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

杰里米·毕晓普在 Unsplash 上的照片

1.介绍

Amazon Lambda 已经成为云基础设施开发中必不可少的无服务器服务。to focus(功能即服务)背后的理念是让程序员专注于编码,提高他们的生产力和基于微服务的现代系统的灵活性。

在另一篇文章中,我介绍了 AWS Lambda 的基本概念,如何用 Python 设置你的第一个函数,使用外部库(Lambda 层)以及使用 boto3 调用函数。

在本文中,我们将探索其他特性,并扩展 AWS Lambda 函数的可用性。

  1. AWS Lambda 背后的基础设施
  2. 在 AWS Lambda 中运行可执行文件
  3. cloud watch 中的监控日志

本文中的大部分信息摘自 AWS 白皮书,以及参考资料会议中引用的文章。

2.AWS Lambda 背后的基础设施

根据 AWS:

Lambda 是一种基于功能的大规模、免配置的无服务器计算产品。它为您的应用程序提供云逻辑层。Lambda 函数可以由 AWS 或支持第三方服务上发生的各种事件触发。

这可能不是最好的定义,因为它过于依赖模糊、抽象的概念,并且没有定义 Lambda 中的元素。即使你以前运行过一些 AWS Lambda 函数,并且熟悉这个接口,当你调用你的函数时,后面发生的事情对你来说仍然是一个谜。

那么,AWS Lambda 的背后到底是什么?

从基础设施的角度来看,每个 AWS Lambda 都是运行 Amazon Linux 的容器的一部分(称为功能容器)。您为 AWS Lambda 创建的代码文件和资产被称为功能代码包,存储在由 AWS 管理的 S3 存储桶中。每当 Lambda 函数被触发时,函数代码包就从 S3 桶下载到函数容器,并安装在它的 **Lambda 运行时环境中。**这个过程很容易扩展,AWS 基础设施可以毫不费力地执行对特定 Lambda 函数的多次调用。

Lambda 函数代码包的大小限制是:压缩后 50MB,解压缩后 250MB,这可能与每次调用函数时需要从 S3 加载到函数容器有关。如果功能代码包大于当前限制,加载过程的效率可能会受到影响。

冷启动与暖容器

当您调用 Lambda 函数时,它会遵循上述步骤并执行代码。执行完成后,Lambda 容器在被终止前会保持可用几分钟。这叫做 冷启动

如果您调用同一个函数,并且 Lambda 容器仍然可用(还没有被终止),AWS 使用这个容器来执行您的新调用。这个使用活动函数容器的过程被称为热容器,它提高了 Lambda 的响应速度(图 2)。

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

图二。AWS Lambda 冷启动与热启动(“带 AWS Lambda 的无服务器架构”)

无状态与有状态

AWS Lambda 的另一个重要方面是它是一个无状态服务,这意味着“你的代码不能对状态做出假设”。即使使用暖容器,新调用也不能使用上一次调用生成的状态和数据,这意味着每次新调用都要重新启动容器。Lambda 处理这些限制的一种方法是使用来自有状态服务的数据,如 S3、DynamoDB、RDS 等。因此,在设计云基础设施时,请记住这一点。

3.运行可执行文件

AWS 提供了各种各样的运行时(语言),如 Ruby、Python、Node.js、Java、Go 和。您还可以运行您在部署包中上传的任何代码或包。这意味着您可以使用运行上述语言的 Lambda 函数,但有时您需要使用通过命令行运行的工具来执行您的函数,比如 bash 文件。由于 AWS Lambda 背后的基础设施是不透明的,实现它可能很棘手,因为您不能简单地调用存储在 Lambda 部署包中的可执行文件。

在 AWS Lambda 上运行可执行文件的关键是:

  1. 将其打包到您的部署包中;
  2. 将可执行文件复制到 Lambda/tmp/folder;
  3. 给它适当的权限;
  4. 最后,执行它。

为了说明这个过程,我们将使用一个名为maft Aligner的 bash 命令行工具,这是一个用于执行序列比对的生物信息工具。我们可以下载便携包来在我们机器的任何文件夹中运行它。我们将运行以下命令来执行它:

# 1) Unzip the package
tar -xvf mafft-7.450-linux.tar# 2) Execute the .bat file inside the extracted folder
./mafft-linux64/mafft.bat

要使用 AWS Lambda 复制此流程,我们将使用以下代码:

前两个函数,load_file_from_S3upload_file_to_S3,用于获取存储在 S3 上的文件,并将 Mafft 工具的输出保存回 S3,以便我们以后访问它(记住,Lambda 是无状态的,因此当函数终止时,所有内容都将从环境中删除)。一个重要的细节是,您只能使用 Lambda 的临时文件夹来保存文件,因此第 10 行和第 18 行明确了/tmp/的路径。

lambda_handler函数(第 22 行)包含了使用 Mafft 工具加载、执行和保存文件的所有必要命令。第 25 到 28 行指定了变量(输入、输出文件和 S3 桶的名称)。Mafft 的可执行文件从功能代码包复制到/tmp/文件夹(第 40 和 41 行),并授权使用chmod执行(第 43 和 44 行)。最后,使用os.system()(第 47 行)通过命令行执行该工具,并将输出文件上传到 S3 存储桶(第 50 行)。

通过使用这里介绍的相同逻辑,您可以通过打包用不同语言编码的可执行文件来扩展 Lambda 函数的功能。

4.通过 CloudWatch 监控日志

每次运行 AWS Lambda 时,函数日志都会存储在 CloudWatch 上,这样更容易监控执行情况。对于每个函数容器,CloudWatch 都会生成一个日志流。所以当你在跟踪冷启动调用时,你会有一个一个调用一个日志关系。当你有暖容器时,问题就开始了,活动容器的日志流会有关于多个 Lambda 调用的信息,这使得解析信息有点棘手。

Boto3 是一个不可思议的库,它使用 Python 集成了 AWS 上托管的管道和系统,使得一些流程更容易执行。为了处理暖容器日志的问题,我使用 boto3 开发了一个代码来处理来自 CloudWatch 的日志数据。要运行它,您需要提供与每个 Lambda 调用相关的 3 个重要变量的信息:

**A)日志组:**是 CloudWatch 为你的 Lambda 函数生成的名字。惯例是aws/lambda/your_lambda_name

**B)流名称:**这是为每个执行的 Lambda 函数容器创建的日志的名称。如果使用暖容器执行 Lambda 函数,则当前和过去执行的日志将具有相同的流名称,它们将属于同一个日志。

C)请求 ID: 这是为每个 Lambda 执行生成的唯一标识符。

您可以通过访问lamdbda_handler函数中的 Lambda 上下文对象来找到这些值。

# Accessing values from Lambda Context object
def lambda_handler(event, context):
    RequestId = context.aws_request_id
    GroupName = context.log_group_name
    StreamName = context.log_stream_name

接下来,您可以使用这些值运行函数parsing_lambda_logs,只提取与特定 RequestId 相关的日志行。

上面的代码还返回了lambda_status,它会告诉您在 Lambda 调用的执行过程中,对于特定的 RequestId 是否有错误。因此,您可以将 Lambda 调用与该函数集成,以监控您的系统是否正常工作。

5.结束语

正如简介中提到的,本文的目的是提供更多关于 AWS Lambda 如何工作以及如何执行一些重要过程的细节,以便在设计云基础设施时为您提供更多资源。我希望 AWS Lambda 现在不再是一个“黑箱”,你可以探索它更多的可能性和功能。

非常感谢你阅读我的文章!

  • 你可以在我的个人资料页面 找到我的其他文章🔬
  • 如果你喜欢并且想成为中级会员,你可以使用我的 推荐链接 来支持我👍

资源

[## 无服务器:比 FaaS 多得多

也就是数据、逻辑和基础设施——它们是如何结合在一起的?

medium.com](https://medium.com/@PaulDJohnston/serverless-its-much-much-more-than-faas-a342541b982e) [## 使用 Python3 介绍 Amazon Lambda、Layers 和 boto3

面向数据科学家的无服务器方法

towardsdatascience.com](/introduction-to-amazon-lambda-layers-and-boto3-using-python3-39bd390add17) [## AWS 白皮书和指南

通过 AWS 和 AWS 社区创作的 AWS 技术内容扩展您的云知识,包括…

aws.amazon.com](https://aws.amazon.com/whitepapers/?nc1=h_ls&whitepapers-main.sort-by=item.additionalFields.sortDate&whitepapers-main.sort-order=desc) [## 恐怕你对 AWS Lambda 冷启动的想法完全错了

当我在 API Gateway 的上下文中与人们讨论 AWS Lambda 冷启动时,我经常得到这样的回答…

medium.com](https://medium.com/hackernoon/im-afraid-you-re-thinking-about-aws-lambda-cold-starts-all-wrong-7d907f278a4f) [## 语言、内存、封装尺寸如何影响 AWS Lambda 的冷启动?

比较使用不同语言、内存分配和部署规模的 AWS Lambda 的冷启动时间…

read.acloud.guru](https://read.acloud.guru/does-coding-language-memory-or-package-size-affect-cold-starts-of-aws-lambda-a15e26d12c76) [## 以下是如何让您的云基础架构稳定、安全且可扩展。

启动 DevOps 很难

medium.com](https://medium.com/free-code-camp/heres-how-to-make-your-cloud-infrastructure-stable-secure-and-scalable-f9f4749697d6) [## 了解微服务:从想法到起跑线

在过去的两个月里,我花了大部分的空闲时间来学习什么是…

medium.com](https://medium.com/free-code-camp/microservices-from-idea-to-starting-line-ae5317a6ff02)

深入线性回归

原文:https://towardsdatascience.com/diving-deeper-into-linear-regression-81adaa7b79e5?source=collection_archive---------18-----------------------

OLS,山脊,拉索和超越…

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

Artem VerboUnsplash 上拍摄的照片

W 当我提到“线性回归”时,大多数人都会想到传统的普通最小二乘法 (OLS)回归。如果你不熟悉这个术语,这些等式可能会有帮助…

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

β_1、β_2:权重;β_0:偏倚;J(β):成本函数

你也想到 OLS 了吗?如果是,那么你就在正确的轨道上。但是线性回归不仅仅是 OLS!首先,让我们更仔细地看看 OLS。

内源性阿片样物质

这种技术的名字来自于成本函数。在这里,我们取误差平方和(基础事实和预测之间的差异),并试图将其最小化。通过最小化成本函数,我们获得了向量β(包含偏差和权重)的最优值。在下图中,显示了成本函数的等高线(同心椭圆)。最小化后,我们得到β作为中心点。

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

内源性阿片样物质

起初,OLS 似乎足以解决任何回归问题。但是随着我们增加特征的数量和数据的复杂性,OLS 倾向于过度拟合训练数据。过度拟合的概念非常广泛,值得单独写一篇文章(你可以找到很多这样的例子),所以我会给你一个简要的介绍。过度拟合意味着模型已经很好地学习了训练数据,以至于无法进行概括。换句话说,该模型已经学习了训练数据中即使是小规模(不显著)的变化,因此它不能对看不见的(验证和测试)数据产生良好的预测。为了解决过度拟合的问题,我们可以使用许多技术。在我们的成本函数中增加一个正则化项就是这样一种技术。但是我们应该用什么术语呢?我们一般使用以下两种方法之一。

山脉

在这种情况下,我们将权重的平方之和添加到我们的最小平方成本函数中。所以现在看起来像这样…

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

m:β的 1+维;λ:正则化参数

但是这个术语如何防止过度拟合呢?增加这一项相当于对β的可能值增加了一个额外的约束。因为要达到最小成本,β _j 的总和一定不能超过某个值(比如 r)。这种技术可以防止模型对某些特征赋予比其他特征更大的权重,从而解决过度拟合问题。数学上,

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

换句话说,β应该位于以原点为圆心,半径为√r 的圆内(或上)。这是可视化效果…

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

山脉

请注意,由于存在约束(红色圆圈),β的最终值比在 OLS 中更接近原点。

套索

山脊和套索之间的唯一区别是正则化项。这里,我们将权重的绝对值的和添加到我们的最小二乘成本函数中。所以成本函数变成了…

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

在这种情况下,约束可以写成…

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

现在我们可以把约束想象成正方形而不是圆形。

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

套索

值得注意的是,如果轮廓碰到正方形的一个角,则一个特征被完全忽略(权重变为 0)。对于高维特征空间,我们可以用这个技巧减少特征的数量

注意:在正则化项中,我们不使用偏差(β_0 ),因为只有对应于特征的非常大的权重(β_i,对于 i>0)对过拟合有贡献。偏差项只是一个截距,因此与过拟合没有太大关系。

唷…这是很多关于正规化。上述方法的共同点是:它们的成本函数中都有残差/误差(地面真实预测)。这些误差平行于 y 轴。我们也可以考虑沿 x 轴的误差,并以类似方式进行。见下图。

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

y 误差和 x 误差

如果我们使用一种不同的误差呢?

主轴(正交)回归

在这种情况下,我们考虑两个方向 (x 轴和 y 轴)的误差。观察数据点和预测线之间的垂直距离的平方和将被最小化。让我们通过仅取一个特征来形象化这一点。

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

(X_i,Y_i):从最佳拟合线上的(x_i,y_i)绘制的垂线的脚

让我们的模型

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

然后通过最小化可以获得回归系数

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

在约束下

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

简化长轴回归

这与上面的方法非常相似,只是略有变化。这里,我们最小化由(X_i,Y_i)和(x_i,y_i)形成的矩形的面积之和。

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

缩减长轴

由 n 个数据点扩展的总面积是,

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

这里的约束条件与正交回归相同。

什么时候应该使用正交回归?

当研究变量(y)和解释变量(x)都存在不确定性时,应该选择正交和简化的主轴回归。

正交回归中有趣的一点是,它会产生对称的 y 误差和 x 误差。但是在 OLS,我们没有得到对称,因为我们要么最小化 y 误差,要么最小化 x 误差,而不是两者都最小化。

还好奇?看一个我最近做的视频…

我希望你喜欢阅读。下次见…学习愉快!

深入探究 Unity-ML 代理

原文:https://towardsdatascience.com/diving-deeper-into-unity-ml-agents-e1667f869dc3?source=collection_archive---------11-----------------------

Unity-ML 代理课程

训练一个好奇的特工去摧毁金字塔。

我们推出了新的免费、更新、 深度强化学习课程从初学者到专家,用拥抱面对🤗

👉新版教程:https://huggingface.co/deep-rl-course/unit0/introduction

下面的章节是以前的版本,新版本在这里👉https://huggingface.co/deep-rl-course/unit5/introduction?fw=pt

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

unity ML-代理

我们推出了新的免费、更新、 从初学者到专家的深度强化学习课程,用拥抱面对🤗

👉新版教程:https://huggingface.co/deep-rl-course/unit0/introduction

下面的章节是以前的版本,新版本在这里👉https://huggingface.co/deep-rl-course/unit5/introduction?fw=pt

上一次,我们学习了 Unity ML-Agents 的工作原理,并训练了一个学会翻墙的代理。

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

这是一个很好的体验,但是我们想创造能够解决更复杂任务的代理。所以今天我们将训练一个更聪明的机器人,它需要按下一个按钮来生成一个金字塔,然后导航到金字塔,撞倒它,并移动到顶部的金砖。

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

为了训练这个寻找按钮然后摧毁金字塔新代理人,我们将使用两种奖励的组合,一种是环境给予的外在奖励。也是一种内在的好奇心。这一秒会促使我们的代理好奇,或者换句话说,更好地探索它的环境。

因此,今天我们将了解深度强化学习中好奇心这一强大想法背后的理论,并且我们将训练这一好奇代理。

我们开始吧!

深度 RL 中的好奇心是什么?

我已经在另外两篇文章中详细介绍了好奇心,如果你想深入研究数学和实现细节的话。

现代逆向物流中的两大问题

为了理解什么是好奇心,我们需要首先理解 RL 的两个主要问题:

首先是稀疏奖励问题**:也就是说,大多数奖励不包含信息,因此被设置为零。**

请记住,RL 是基于奖励假设,即每个目标都可以被描述为奖励的最大化。因此,奖励是对 RL 代理的反馈,如果他们没有收到任何反馈,他们对哪种行为是适当的(或不适当的)的知识不会改变。

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

由于奖励,我们的代理人知道在那个状态下的这个行动是好的

例如,在 Vizdoom“末日之家”中,你的代理只有在找到防弹衣时才会得到奖励。但是,马甲离你的起点很远,所以你的大部分奖励会是零。因此,如果我们的代理没有收到有用的反馈(密集的奖励),它将需要更长的时间来学习一个最优策略,并且可能会花时间转来转去而找不到目标。

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

非常感谢 Felix Steger 的这个插图

第二个大问题是外在的奖励函数是手工的,也就是说,在每个环境中,一个人必须实现一个奖励函数**。但是我们如何在大而复杂的环境中扩展它呢?**

那么什么是好奇心呢?

因此,解决这些问题的一个方法是开发一个奖励函数,该函数是代理固有的,即*,*由代理自身生成。代理将充当自学者,因为它既是学生,也是自己的反馈主人。

这种内在的奖励机制被称为好奇心,因为这种奖励推动探索新奇/不熟悉的状态。为了实现这一目标,我们的代理人在探索新的轨迹时将获得高额报酬。

这种奖励实际上是根据人类的行为设计的,我们天生就有探索环境和发现新事物的本能欲望。

有不同的方法来计算这种内在奖励,Unity ML-Agents 通过下一状态预测方法使用好奇心。****

基于预测的惊奇(或下一状态预测)引发的好奇心

我已经介绍过这个方法 这里 如果你想深入到数学的细节。

所以我们刚才说,在不熟悉/新奇的状态下,好奇心很高。但是我们如何计算这种“不熟悉”?****

给定当前状态和采取的行动,我们可以将好奇心计算为我们的代理预测下一个状态的误差。更正式地说,我们可以将此定义为:

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

为什么?因为好奇心的想法是鼓励我们的代理人执行减少代理人预测其自身行为后果能力的不确定性的行为**(在代理人花费较少时间的区域,或者在具有复杂动态的区域,不确定性会更高)。**

如果代理在这些状态上花费很多时间,那么预测下一个状态(低好奇心)将是好的,另一方面,如果是一个未探索的新状态,那么预测下一个状态(高好奇心)将是不好的。

让我们进一步分解一下。假设你玩超级马里奥兄弟:

  • 如果你在游戏开始的时候花了很多时间(这并不新鲜),那么代理就能准确预测到下一个状态会是什么**,那么奖励就会**低。****
  • 另一方面,如果你发现一个新房间,我们的代理将非常不擅长预测下一个状态,所以代理将被推动去探索这个房间。

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

使用好奇号将促使我们的智能体倾向于预测误差较高的转换(在智能体花费时间较少的区域或具有复杂动态的区域,预测误差较高)从而更好地探索我们的环境。

但是因为我们不能通过预测下一帧来预测下一个状态(太复杂了,无法直接预测像素),我们使用了更好的特征表示,它将只保留可以由我们的代理控制或影响我们的代理的元素。

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

而为了计算好奇心,我们将使用文中介绍的一个模块,好奇心驱动的自我监督预测探索 称为内在好奇心模块。

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

如果你想知道它的工作原理, 查看我们的详细文章

训练一名特工摧毁金字塔

现在,我们通过下一个状态预测了解了什么是好奇心,以及它是如何工作的,让我们来训练这个新的代理。

我们在 github 上发布了我们训练过的模型,你可以在这里下载

金字塔环境

这个环境的目标是训练我们的代理人获得金字塔顶端的金砖。为了做到这一点,他需要按一个按钮来产生一个金字塔,然后导航到金字塔,撞倒它,并移动到顶部的金砖。****

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

奖励制度是:

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

在观察方面,我们使用的是 raycast 版本。有 148 个光线投射,但是探测开关、砖块、金砖和墙壁。

我们还使用一个布尔变量来表示开关状态。

动作空间是离散的,有 4 个可能的动作:

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

我们的目标是达到平均回报为 1.75 的基准。

让我们摧毁一些金字塔!

首先我们打开 UnitySDK 项目。

在示例中搜索金字塔并打开场景。

就像 WallJump,你可以在场景中看到很多代理,他们每个人都来自同一个预置,他们都共享同一个大脑(策略)。****

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

同一个代理预置的多个副本。

事实上,正如我们在经典的深度强化学习中所做的那样,当我们启动一个游戏的多个实例(例如 128 个并行环境)时,我们在此复制并粘贴代理,以便有更多不同的状态。

所以,首先,因为我们想从头开始训练我们的代理,我们需要从代理预置中移除大脑。我们需要去预置文件夹并打开预置。

现在在预设层级中,选择代理并进入检查器。

行为参数中,我们需要移除模型。如果你有一些图形处理器,你可以改变推理设备从 CPU 到 GPU。

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

对于第一次训练,我们将只修改总训练步骤,因为它太高了,我们只能在 500k 的训练步骤中达到基准。为此,我们转到config/trainer _ config . YAML,您将这些修改为 max_steps 到 5.0e5 以用于金字塔情况:

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

为了训练这个代理,我们将使用 PPO(近似策略优化),如果你不知道或者你需要更新你的知识,查看我的文章

我们看到,为了训练这个代理,我们需要使用 Python API 调用我们的外部通信器。这个外部通讯器会要求学院启动代理。****

所以,你需要打开你的终端,到 ml-agents-master 所在的地方,输入这个。

ml agents-learn config/trainer _ config . YAML-run-id = " Pyramids _ first train "-train

它会要求你运行 Unity 场景,

按下编辑器顶部的▶️按钮。

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

您可以使用以下命令启动 Tensorboard 来监控您的训练:

tensor board—logdir = summaries

看着你的特工翻墙

你可以在训练的时候通过查看游戏窗口来观察你的经纪人。

培训结束后,您需要将保存在 ml-agents-master/models 中的模型文件移动到 unity SDK/Assets/ML-Agents/Examples/Pyramids/TF models。

再次打开 Unity 编辑器,选择金字塔场景。

选择金字塔预设对象并打开它。

选择代理

代理行为参数中,拖动金字塔. nn 文件到模型占位符。

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

然后,按下编辑器顶部的▶️按钮。

是时候做些实验了

我们刚刚训练我们的特工学会了翻墙。既然我们有了好的结果,我们可以尝试一些实验。

记住,最好的学习方法是通过实验保持活跃。所以你应该试着做一些假设并验证它们。

顺便说一下,有一个关于如何通过沉浸式限制超参数调谐金字塔环境的惊人视频,你一定要看。

将时间跨度增加到 256

文档中所解释的,时间范围是每个代理在将经验放入经验缓冲区之前要收集的经验步数。这在长期范围(偏差较小,但方差估计较高)和短期范围(偏差较大,但方差估计较小)之间进行权衡。

在这次体验中,我们将时间跨度从 128 增加到了 256 。增加它允许我们的代理在他的行动序列中捕获比以前更多的重要行为。****

然而,这并没有影响我们新代理的培训。事实上,他们分享了完全相同的结果。

我们在 github 上发布了我们训练过的模型,你可以在这里下载

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

今天就到这里吧!

你刚刚训练了一个比上次更聪明的特工。你也学到了深度强化学习中的好奇心。太棒了。

现在我们已经完成了,你可能想更深入地了解 Unity ML-Agents** 。不要担心,下一次我们将创建我们自己的环境,下一篇文章我们将创建我们自己的强化学习实现。**

因此在下一篇文章中,我们将从头开始创建我们的第一个环境。这个环境会是怎样的?我不想破坏现在的一切,但我给你一个提示:

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

向培根先生问好🐽

下次见!

如果你有任何想法,评论,问题,欢迎在下面评论或者发邮件给我:hello@simoninithomas.com,或者发推特给我 @ThomasSimonini

不断学习,保持牛逼!

第三章:玛雅奇遇

深入自动化 API 测试

原文:https://towardsdatascience.com/diving-into-automated-api-tests-e08510c72e7?source=collection_archive---------21-----------------------

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

来源

想到自动化,你会想到什么?机器人制造机器人,大型工厂生产产品,车辆自动驾驶,或者其他一些遥远的未来?嗯,自动化已经远远不止这些了。

自动化意味着我们让某种机器在最少的人工协助下完成工作。大多数人可能想到的最常见的自动化的例子是工厂。其中多台机器以同步方式工作,大量传送带环绕整个设施。

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

来源

这个形象让很多人相信,很快所有的工厂都会这样运行。然而,自动化远比这种狭隘的视野更广阔。最重要的自动化每天都在我们的生活中发生,而我们甚至没有太注意它。

什么是 API,我们为什么需要它?

让我们举一个社交媒体应用程序的例子。你可能在社交媒体帖子里看到过地名。当我们点击它们时,它们会把我们带到一张地图上,给我们指出一个特定的地方。现在,这家社交媒体公司可能有了自己的地图服务。然而,更多的时候,它会使用第三方地图服务。

该第三方地图服务可能正在向许多其他应用程序提供服务。如果它允许所有应用程序使用它的原始数据库,至少会导致数据损坏。最坏的情况是数据完全毁坏(伴随着一些严重的诉讼)。因此,允许任何应用程序不受任何限制地使用其数据库是一种非常糟糕和不切实际的方法。

该服务提供商也不可能向所有应用程序发送数据副本,因为每个应用程序可能只需要非常小的数据子集。此外,数据必须尽快更新。此外,定期发送如此多的数据需要天文带宽的问题。

我们如何克服这些问题,以便地图服务可以将数据发送到社交媒体应用程序?

怎么样-地图服务提供了一组功能、工具和规则,用于通过适当的文档与社交媒体应用程序进行通信。使用这些服务,社交媒体应用程序可以获得所需的数据,而不会危及地图服务提供商的安全(当然,必须需要一些认证系统)。

这个由功能、工具和规则组成的包被称为 API 或应用程序编程接口 ,因为它提供了与应用程序交互的接口。

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

来源

我喜欢把 API 想象成一台复杂机器上的一组按钮(比如一台带键盘的电脑:)。你可能希望这台机器为你做一些事情。你要做的就是用那些按钮来指挥它做你的工作。

例如,让机器包含一个地图数据库。现在,我们可以要求机器向我们提供关于某个特定坐标的信息,它会把这些信息悄悄告诉我们,而不需要我们关心它的内部工作情况或它有什么其他数据。这是与机器通信的相对安全的方式。

除了提供上述优势和服务之外,API 通常是跨平台的,可以与许多编程语言一起使用。这一点很重要,因为不止一个应用程序可能从一个服务请求数据。

例如,让我们再次考虑我们的地图服务。假设另一个应用程序想要使用它的数据。然而,这个应用程序使用的语言和平台与我们的社交媒体应用程序不同。它如何使用来自地图服务提供商的数据?

这里又出现了一个 API。API 应该能够与多种语言和平台一起工作,因此它应该有助于克服这个问题。

为什么要测试 API?

API 在我们的日常活动中非常有用。如果您正在使用任何类型的计算机设备,您可能会在不知不觉中使用 API。大多数应用程序和软件通过 API 进行通信。甚至软件的不同部分也通过 API 进行通信。

现在,如果您如此频繁地使用 API,一个自然的问题可能会出现。我如何知道哪个 API 最适合我?或者我如何确保我正在使用的 API 是安全的,并且按照预期工作。或者也许因为大多数软件都在使用 API,它们甚至是安全的吗?他们重视我的隐私吗?是否有任何漏洞可以被利用来访问我的数据。

API 为我们提供了一条通向公司数据库的通道。如您所料,如果 API 构建不当,它们可能会被用来窃取或破坏数据。因此,彻底测试我们的 API 是极其重要的。

然而,安全性并不是测试我们的 API 的唯一问题。我们还需要确保所有提供的功能都按预期工作。并且 API 可以处理它所声明的任意多的用户。我们还应该测试它在被拉伸到极限时是否有效。我们可能还需要考虑一些极限情况。

提供 API 的公司可能会使用人类来完成这项任务。但是可用的 API 的数量和人类执行这些测试所需的技能的数量会使它变得不可行。再加上应用程序与人工测试人员相比节省的时间,你会同意应用程序测试 API 比人工测试更好。

有许多可用的 API 测试工具。其中最受欢迎的是 JMeter,邮递员,放心休息。我发现了一个很棒的视频,它用例子解释了 REST API。我推荐你观看这个视频来获得更多关于 API 的信息。观看这个视频会让你感受到应用程序是如何被用来测试 API 的。我也强烈推荐这篇博文

到目前为止,我们已经确定了自动化的有用性。以及它在节约成本和效率方面的优越性。我们应该更深入地了解测试,以理解如何实现自动化,以及为什么自动化是一个合理的选择。

为什么我们应该自动化测试?

浏览网页时,您可能会看到类似“404 网站未找到”或“200 OK”的消息。这些消息对于理解我们的请求状态非常重要。例如,假设我们向服务器发送一个网页请求。它可能没有该网页,并可能返回特定代码。或者它可能拥有该网站或文件,并可能返回特定代码。

我们可以检查代码并获得关于我们请求的信息。因为我们知道发送什么请求和我们期望什么。我们可以将这些信息放在一个自动化工具中,让它在所有服务器上查询网站或文件。这将使测试自动化并帮助我们。

让我们考虑另一个例子。假设我们有大量代码的软件。如果你以前写过代码,你可能会遇到这个问题——你改变了一些小的东西,它破坏了整个代码。因此,如果开发人员改变代码中的一些小东西,就有可能破坏整个软件。

为了确保这种情况不会发生,我们进行了一系列测试。我们将这些上传到测试工具,每当我们对软件进行任何更改时,我们都会运行这些测试。如果发现一些问题,我们会在将代码提交到软件的源代码之前重新检查代码。这有可能为我们节省几个小时的头痛时间。

有许多 API 测试工具可供使用。我一直在用的是 Loadmill ,一个我觉得很有帮助的免费工具。让我们仔细看看这个工具,了解它在做什么,以及它如何帮助您的测试过程。

首先,我们必须选择我们想要运行的测试(或者进行我们自己的测试)。然后我们进行测试。最终结果可能是这样的:

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

来源:loadmill 的自动测试

你可以看到它运行了许多测试,这些测试可以被输入其中。这些测试可以在多个网站上运行。在这里,它运行 9 个测试,并报告所用的时间以及测试是失败还是通过。这里有 8 个测试已经通过,只有一个测试失败。

单击这些测试中的任何一个都会显示关于测试的更多信息,包括为什么测试通过或失败,或者哪里出错了。

最后的话

我希望我已经让你相信自动化确实非常有帮助,我们正在日常生活中使用它,甚至没有注意到它的效率或称赞它在使我们的生活更简单和更有成效方面的作用。

自动化并不是什么新鲜事。人类一直在寻找聪明的方法来自动化事情,以便他们可以专注于其他工作。我会考虑一个轮子作为自动化来解决走太多的问题。或者中世纪时用风车碾小麦。或者使用引擎来驱动汽车。

然而,最近越来越多的人认为自动化的兴起是一件消极的事情,会使人类变得无用。这种想法与事实相去甚远。自动化从一开始就已经存在,并且应该一直存在到后来。我们总能让事情变得更有效率。

对自动化持否定态度的人没有意识到,当发动机出现时,它们也取代了许多工作,但随着时间的推移,新的工作也创造出来了,总的来说,人类只是在进步。

即使现代技术已经走了很远,它仍然有很长的路要走,在每一步,都有许多人维护所有的工具,并努力使它们越来越好。此外,即使我们开发了一个程序来自动完成一项工作,我们也需要一些开发人员来维护这个程序。

我认为随着我们获取越来越多的数据,技术变得越来越好,将会有越来越多的任务被自动化。更明智的方法是找到可以自动化的任务,并尝试自动化它们,然后继续下一个任务。一旦一切完成,让我们集中精力去火星!

用深度 Q 学习潜入深度强化学习

原文:https://towardsdatascience.com/diving-into-deep-reinforcement-learning-with-deep-q-learning-376e588bb803?source=collection_archive---------55-----------------------

从表格方法到函数逼近的过渡

在本文中,我们将了解如何开始深度强化学习。经常可以看到,列表 RL 方法比函数逼近方法更容易理解。很多人发现很难从 q 学习过渡到深度 q 学习。所以在这篇文章中,我们将仔细研究深度 Q 学习背后的思想。

什么是深度强化学习

我们先来了解一下什么是深度强化学习。深度强化学习由基于函数逼近的算法组成,即有一些函数逼近动作的 Q 值。这里,我们不是维护一个 Q 值表,而是使用像神经网络这样的函数来预测特定状态下的动作的 Q 值。

为什么要深度强化学习

你可能想知道,当我们可以简单地使用 Q 值的表格时,为什么我们需要神经网络。答案很简单,将每个 Q 值存储在一个表中会增加内存的使用,这对于具有大的状态空间和动作空间的环境是不可行的,我们的代理可能不会遇到一个状态甚至两次。使用神经网络可以让我们学习网络的权重,而不是学习单个的 Q 值。

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

表格法与函数逼近。图片由 阿灵古塔https://www.geeksforgeeks.org/deep-q-learning/

深度 Q 学习理念

让我们了解一下 Q 学习的概念和优化技巧。

  1. 重放记忆:当我们的智能体在环境中行动并探索世界时,我们不会在旅途中训练神经网络。相反,我们将代理的所有经验存储在一个缓冲空间中,并通过随机抽取一批经验或优先化的经验来训练我们的模型。这背后的想法是,神经网络可以找到创建的 b/w 状态,并且可能倾向于过度拟合,并且在新状态下可能无法正常工作。
  2. 目标网络:深度 Q 学习使用的不是一个而是两个神经网络。这不是强制性的,但是具有两个网络可以优化性能,并且还可以解决移动目标的问题。当智能体使用相同的神经网络估计 Q 值和目标值时,出现移动目标。因此,为了避免移动目标,我们使用另一个具有固定参数的神经网络(目标网络),并且目标网络定期更新。
  3. 堆叠的帧:如果你使用一个图像作为一个状态,那么一堆多个图像可以用来代表一个状态。这种堆叠的图像给代理一种运动感,从而有助于采取正确的行动。
  4. 行动选择:许多行动选择技术可以用于探索,如 epsilon greedy,softmax。在这些技术中,Softmax 动作选择要好得多,因为它会在一段时间后自动停止探索。在本文中,我们将使用 greedy。

算法:

深度 Q 学习的步骤如下:

  1. 代理观察环境的当前状态。如果随机数小于或等于ε,则代理将采取随机行动,否则 DQN 预测 Q 值,并采取最大 Q 值的行动。
  2. 下一个状态、奖励和一个终端变量存储在重放内存中。
  3. 经过一段时间,当记忆中有足够的例子时,代理通过抽样一批经验来训练 DQN。当前状态集被视为特征,标签是目标值,计算为[Traget = set _ of _ reward+gamma * numpy . max(target _ net . predict(set of next _ state))* set _ of _ done]。这里的 done 是这里使用的终端变量,因此终端状态的值为零。
  4. 目标网络定期更新主网络。

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

图片 via dnddnjs.gitbooks.io

你可以在这里找到代码。我将在下一篇文章中解释代码

感谢你阅读我的文章,希望你喜欢并且能够理解我想要解释的东西。希望你阅读我即将发表的文章。哈里奥姆…🙏

参考资料:

[## 强化学习

由阿尔伯塔大学提供。强化学习专业化包括 4 门课程探索权力…

www.coursera.org](https://www.coursera.org/specializations/reinforcement-learning)

https://MIT press . MIT . edu/books/reinforcement-learning-second-edition

深入 Azure Cosmos DB 中的 Gremlin 查询

原文:https://towardsdatascience.com/diving-into-gremlin-queries-in-azure-cosmos-db-83eb1d7c6350?source=collection_archive---------15-----------------------

使用 Azure Cosmos DB Gremlin API 执行图形查询的简单介绍

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

感谢 Azure Cosmos DB 提供的 Gremlin API,我们可以构建全球分布式数据库来存储和操作图形数据。我们可以使用 Gremlin 查询语言在 Cosmos DB 中执行图形查询。

在本文中,我将向您展示如何设置一个支持 Gremlin API 的 Cosmos DB 帐户,以及如何在该帐户中执行一些简单的图形查询。

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

小妖精吉祥物挺可爱的 IMO:)

如果你想跟进,你需要设置 Azure 订阅。看看这个链接如何做到这一点。要不,我们开始吧!

设置我们的图形数据库

让我们从创建图形数据库开始。进入你的 Azure 门户,点击“创建新资源”。搜索 Azure Cosmos DB 并点击“‘创建新的”。

为了创建我们的图形数据库,我们需要提供一些基本信息:

  • 订阅 —本质上是将向您的 Cosmos DB 帐户收费的订阅。
  • 资源组 —资源组对于管理 Azure 资源集合非常有用。在本教程结束时,我们可以删除一个组中的所有资源,而不是逐个删除资源。您可以将您的 Cosmos DB 帐户分配给预先存在的资源组,或者为其创建一个新的资源组。我决定在本教程中创建一个新的。
  • API —我们可以创建不同种类的 Cosmos DB 数据存储库,具体取决于我们分配给它的 API。在本例中,我们正在创建一个图形数据库,因此我们将选择 Gremlin (Graph) API。
  • 笔记本 —爱 Jupyter 笔记本?Cosmos DB 支持这一点!这超出了本教程的范围,所以我不打算启用它。
  • 位置 — Cosmos DB 是 Azure 中的一项基础服务,这意味着它在所有 Azure 地区都可用。选择一个离你最近的地区。在我的例子中,我位于新西兰的奥克兰,所以我将我的数据库部署在澳大利亚东部。
  • 账户类型 —这是新的?!我以前从未经历过这种事。悬停在工具提示上,看起来它与 UI 体验的工作方式有关。我将不得不对此做更多的调查,但现在,我只是把它投入生产。你可以改变它,它不会影响引擎。
  • 地理冗余和多区域写入 —我现在已经禁用了这个。

请看下面的截图示例:

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

点击审查+创建,你将被重定向到一个验证页面。我们暂时不需要担心网络或标签。如果您的配置有效,您将看到一条成功消息,您可以单击“ Create ”来提供您的图形数据库!

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

在本教程中,我们将使用 Cosmos DB 为所有新的 graph 帐户提供的示例图。为此,点击快速启动。您将被要求选择一个平台来创建一个示例应用程序,但是我们在这里所做的只是用一些示例数据创建一个容器。

Cosmos DB 团队有一个我们可以使用的 Persons 容器,所以单击 Create ’ Persons '容器就足够了。

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

点击“数据浏览器”导航至您的图表。

这是新的吗?他们改变了数据浏览器的工作方式!看起来我们必须将当前的 IP 地址添加到防火墙规则中才能看到我们的数据?(非常 Azure SQL,如果你之前用过 Azure SQL 的话)。

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

单击通知,您将被重定向到防火墙设置选项卡。您的 IP 地址应该已预先填入下面的防火墙部分,因此只需单击“**保存”**即可将您的 IP 地址添加到允许访问列表中。几分钟后你应该可以走了。

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

一旦这些都完成了,导航回数据浏览器,我们应该在我们的 Cosmos DB 帐户中看到我们的新人员图表。

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

好了,这就是我们需要做的所有管理设置,让我们开始深入一些令人敬畏的图形查询!

在我们的图形数据库中执行查询

让我们从在 Persons 图表中插入几个项目开始。打开您的数据浏览器,您应该会看到一个允许我们执行 Gremlin 查询的文本框。

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

让我们从在图表中添加 5 个人开始。键入以下 Gremlin 查询:

# Add Will Velida
g.addV('person').property('firstName', 'Will').property('lastName', 'Velida').property('age', 28).property('hairColor', 'blonde').property('userId', 1).property('pk', 'pk')g.addV('person').property('firstName', 'Alex').property('lastName', 'Smith').property('age', 22).property('hairColor', 'brown').property('userId', 2).property('pk', 'pk')g.addV('person').property('firstName', 'Mike').property('lastName', 'Jones').property('hairColor', 'black').property('userId', 2).property('pk', 'pk')g.addV('person').property('firstName', 'Sarah').property('lastName', 'Smith').property('hairColor', 'blonde').property('userId', 4).property('pk', 'pk')g.addV('person').property('firstName', 'Debbie').property('lastName', 'Stevens').property('hairColor', 'black').property('age', 57).property('userId', 5).property('pk', 'pk')

我们在这里做的是添加 5 个人的顶点。在我们的图中,顶点是离散的实体。在这个例子中,我们使用人作为顶点,但是他们也可以是地点或事件。

让我们更深入地了解一下每个 Gremlin 命令在做什么:

  • addV() —这为我们的图形添加了一个顶点(我们的离散实体)。
  • 属性() —这为我们的垂直市场增加了一个属性

现在让我们添加一些顶点之间的关系。这些在图形数据库中被称为边。让我们编写以下查询:

g.V().hasLabel('person').has('firstName', 'Will').addE('knows').to(g.V().hasLabel('person').has('firstName', 'Alex'))g.V().hasLabel('person').has('firstName', 'Alex').addE('knows').to(g.V().hasLabel('person').has('firstName', 'Mike'))

让我们检查一下新的 Gremlin 查询:

  • add()—两个顶点之间有一条边(关系)。
  • has()hasLabel() —用于过滤属性、顶点和边。在本例中,我们根据’first name’属性进行筛选。

我们可以用这样的命令更新我们的顶点:

g.V().hasLabel('person').has('firstName', 'Mike').property('userId', 3)

让我们尝试过滤我们的人员集合。让我们检索年龄小于 30 的所有顶点:

g.V().hasLabel('person').has('age', lt(30))

在这里,我们得到两个结果:

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

我们可以进一步细化这个查询,只返回名称属性:

g.V().hasLabel('person').has('age', lt(30)).values('firstName')

这将返回以下结果:

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

最后,让我们在图中执行一个简单的遍历,找出 Alex 认识的所有人:

g.V().hasLabel('person').has('firstName', 'Alex').outE('knows').inV().hasLabel('person')

我们可以看到,他认识一个人,迈克·琼斯:

[
  {
    "id": "c2260feb-207b-403b-82cb-30cd47006912",
    "label": "person",
    "type": "vertex"
    "properties": 
    "firstName": [
    {
      "id": "1a383c60-82ce-414b-a610-8c2b9ab08759",
      "value": "Mike"
    }
    ]
    "lastName": [
    {
      "id": "1a1a762a-dace-4912-aa16-e87f4327d1a7",
      "value": "Jones"
    }
    ],
    "hairColor": [
    {
      "id": "5f71ca42-1cf0-4da4-93a9-c24693975e56",
      "value": "black"
    }
    ],
    "userId": [
    {
      "id": "9e06cf3a-e58a-494f-aaf2-e0f1e2940cce",
      "value": 3
    }
    ],
    "pk": [
    {
      "id": "4f27fd02-1861-480a-8887-4b40c8c7d6c6",
      "value": "pk"
    }
    ]
    }
  }
]

评估图形查询的性能

这是非常酷的东西,但是我已经听到你们中的一些人说‘我如何测量这些查询的性能?’。

Gremlin 查询语言有一个名为 executionProfile() 的方法,它允许我们查看查询执行情况的指标。让我们将这个方法附加到前面的查询中,看看它是如何执行的:

g.V().hasLabel('person').has('firstName', 'Alex').outE('knows').inV().hasLabel('person').executionProfile()

这是我们得到的回应:

让我们来看看以下属性:

  • gremlin —被执行的语句。
  • 总时间 —操作所用的时间,以毫秒为单位
  • 指标 —在我们的 gremlin 查询中执行的每个步骤的指标。这些分为 GetVertices (获取我们的属性) GetEdges (查看我们的顶点之间的关系是什么)和get neighborhood vertices(查看哪些顶点有什么关系)。这些指标包括执行查询所用的时间(以毫秒计)、总查询执行时间的百分比时间、返回的结果数量、计数和大小。

结论

在本文中,我们建立了一个新的 Cosmos DB 图形数据库,并在其中执行了一些基本查询。我们还研究了如何评估这些查询的性能。如果您已经完成了这个图形数据库,请随意删除它。否则,为什么不添加更多的属性,看看 Cosmos DB Graph 文档,看看还能用 Gremlin 查询做些什么。

在以后的文章中,我将讨论如何为图形数据库建模数据,并查看一些最佳实践。我还将讨论我们如何在为 Azure Cosmos DB 开发应用程序的上下文中应用这些概念。

如果你有任何问题,请在下面的评论区提问。

下次见!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值