TowardsDataScience-博客中文翻译-2021-五十-

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

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

如何创建人们想要阅读的数据分析项目

原文:https://towardsdatascience.com/how-to-make-a-data-analytics-project-that-people-want-to-read-47caea306570?source=collection_archive---------17-----------------------

让你的工作引人注目的 8 个可行建议

(来源)

在一个领域建立自己的事业,最重要的部分是通过自己的工作为人所知。谈到数据分析,拥有令人印象深刻的项目来展示你的知识和专长胜过所有其他方法,包括认证和课程

那么,如何建立一个令人印象深刻的项目呢?更重要的是,是什么让一个分析项目令人印象深刻?

在这篇文章中,我向你展示了 8 个帮助我成为 Kaggle 笔记本专家的技巧,它们帮助我在不同的数据集上建立叙述。那么,事不宜迟,让我们开始吧。

提示 1:选择你的分析目标,而不是你想要使用的工具

“永远记住,你的关注点决定了你的现实”——乔治·卢卡斯

人们很容易迷失在不断进入我们思维的一套奇特的数据可视化软件包中。虽然学习新工具没有错,但是在从事一个项目时,必须有某种节制。

分析项目的最终目标不是炫耀新工具的知识,而是在提供的数据中发现有用的模式。因此,集中精力询问数据问题比担心必须使用哪种工具更有成效。

当然,有些情况下,由于项目的需求,你可能更喜欢一个库而不是另一个。在这些情况下,在决定要使用的库方面做一些工作是有意义的。但是请注意,不要让您选择的库或语言来指导您的分析!

技巧 2:准备好一套方法

“如果你不能把你在做的事情描述成一个过程,你就不知道你在做什么。”——w·爱德华兹·戴明

方法论本质上是指导研究的上下文框架。简单地说,在分析项目的环境中,它可以帮助你在进行项目时坚持一个过程。

拥有一个方法是很重要的,因为拥有一个方法可以确保你有一个清晰定义的途径来实现你的目标。此外,当你必须向他人解释你的项目时,一种方法会变得非常有效。

这是因为从数据采集阶段开始到结果沟通阶段,你完全控制你所采取的每一个步骤;以及其他所有中间步骤!

拥有方法论的一个鲜为人知的好处是它加深了你对项目的思考。例如,我在我的项目中加入了一个步骤“理解我的偏见”,在那里我分析了美国警察的种族暴力。这种包含帮助我确保我的发现不受我内在偏见的影响。

这一方法中的第二步和第三步是确保我的结果没有偏差的关键(鸣谢:作者,来源)

技巧 3:头脑风暴,就像你的生活依赖于它一样

“获得好想法的最好方法是获得大量的想法,把不好的扔掉。”——莱纳斯·鲍林

第一次尝试分析一个数据集总是会非常混乱。特别是如果它有很多实例和功能,如 Kaggle Survey Challenge 2020 数据集

这就是头脑风暴变得重要的地方。简单地说,头脑风暴是通过让这些想法从头脑中自由流动到物理(纸张)或数字(计算机)位置来产生新想法。

虽然头脑风暴的大多数定义称之为团队过程,但有研究支持个人头脑风暴比团队会议产生更高质量想法的论点

在为您的数据分析项目单独进行头脑风暴的背景下,有 3 个有用的步骤可以帮助您开始。

  1. 阅读数据集描述 —你认为收集数据的人最优先考虑的是什么?
  2. 阅读功能描述 —根据您的意见,哪些功能最符合步骤 1 中的主要优先级?
  3. 阅读以前的工作——如果有人在过去使用过相同或相似的数据,请查阅它们

在这之后,你将能够把你产生的所有想法写在一张纸上(或者一个数字记录,如果你不是像我一样的守旧派)。是的,头脑风暴就像你的生活取决于它。坚持写下你可以用来分析你的数据的想法,直到你头脑枯竭。

头脑风暴是你分析的支柱,因此必须彻底考虑。

提示 4:进行初步分析,以确定最有希望的叙述

“因为我们不认为我们知道一件事,直到我们熟悉它的主要条件或首要原则,并进行我们的分析,直到它的最简单的元素”——亚里士多德

在你的头脑风暴会议之后,你可能有多个想法想要作为你的分析的叙述。然而,如果你希望你的作品清晰有力,你应该只选择一个主要观点。

为了做出这个选择,快速启动您的系统并编写一些代码来执行初步分析会有所帮助。这可能是你的探索性数据分析的一部分,因此需要在聚焦于最有希望讲述的故事之前,将手头的数据可视化。

例如,在今年的 2020 年 Kaggle ML 和 DS 调查挑战中,我通过初步分析发现与调查中的其他任何一组受访者相比,21 岁以下的印度受访者增长最快。这帮助我为接下来的分析建立了我的案例。

技巧 5:使用故事板来构建你的叙述

“对我来说,故事板是预先想象整部电影的方式”——马丁·斯科塞斯

说到用数据讲故事,我个人认为 Cole Nussbaumer Knaflic 是该领域最有头脑的人之一。虽然她通过她的书籍多次演讲传播了大量的想法,但我发现其中一个想法非常足智多谋,那就是故事板制作过程

正如专业作家所说,一个好的故事有 5 个部分——阐述、上升动作、高潮、下降动作和结局。在您的数据分析项目的上下文中,您可以遵循类似的结构来制作您的故事板。

介绍你拥有的数据,进入你的分析或主要目标的“为什么”,分析你选择的子目标,报告洞察力,同时将它们与你的主要目标联系起来,最后结合你的所有发现,选择最重要的,并报告它们作为相关利益方可以采取的决定。

5 部分故事结构(鸣谢:作者,灵感来自来源)

我用于 Kaggle 2020 调查分析挑战的故事板(致谢:作者)

秘诀 6:这不是关于你,而是关于他们

“这不是关于你,这是关于他们”——克林特·伊斯特伍德

转到一个更哲学的观点,我敦促读者理解,我们进行的任何分析从来都不是只为我们的眼睛。分析工作的影响只与它对所涉及的利益相关者的有用程度相关。

因此,如果没有必要,就不要在报告中添加图表。仅仅因为你努力工作,并不意味着你需要炫耀它。如果它与你的整个分析不一致,它必须看到回收站的内部。

同样重要的是,确保您能够将您的结果与利益相关者可以实现的可操作目标联系起来。

此外,确保你永远不会用没有意义的视觉效果误导你的观众。

技巧 7:获得一些初步反馈

“反馈是冠军的早餐”——肯·布兰查德

你的分析的第一份完整草稿必须总是与那些对你正在讲述的故事的主题毫无概念的人分享。

这是有效的,原因很简单——如果一个没有主题 X 背景的人能够理解并欣赏你讲述的关于主题 X 的数据驱动的故事,那么这意味着你的叙述是连贯的、清晰的和引人入胜的。

如果这种情况没有发生,那么是时候回到绘图板,重新开始你的叙述了。重复,直到你达到目标!

请记住,反馈不是为了让你开心,而是为了改进。所以,如果你听到你不喜欢的东西,不要怀有敌意!

技巧 8:注意细节

“好东西和伟大东西的区别在于对细节的关注。”——查尔斯·r·斯温多尔

即使是很小的事情,比如你的情节主题,你在报告中使用的字体和颜色,都会对读者如何看待你的作品产生深刻的影响。

作者非常关注细节的最好的分析例子之一是安德拉达·奥尔特亚努的鸟鸣识别 EDA。甚至视觉效果也与鸟儿的配色方案相匹配!

一致性是分析报告的另一个非常重要的方面。你不需要华丽的报告。你需要一份极简的报告,讲述已经分析过的数据的故事。

对我有帮助的其他提示

以下链接包含了一些最好的数据分析师和故事讲述者的建议,他们对我的旅程产生了巨大的积极影响

  1. John Miller 的“分析报告的一些最佳实践”
  2. Rachael Tatman 的《通向更专业的数据科学代码的六个步骤》
  3. 本·威灵顿的《通过讲故事让数据更有意义》
  4. David McCandless 的《数据可视化之美》

希望这是一个有用的阅读!干杯:)

如何在 QGIS 中制作假彩色卫星影像

原文:https://towardsdatascience.com/how-to-make-a-false-color-satellite-image-in-qgis-ebaa07acad0e?source=collection_archive---------15-----------------------

艺术和数据一体化

所有图片均由作者提供

假彩色卫星图像对于直观分析不同的景观特征非常有用。它们看起来也很酷,用于制作非常艺术的地图和展示。

假彩色卫星图像是通过用不同的颜色显示不同的波段组合而生成的。例如,通过将来自*红外传感器的数据显示为红色,将来自红色传感器的数据显示为绿色,将来自绿色传感器的数据显示为蓝色,来创建彩色*红外图像。

彩色*红外通常用于显示植被覆盖的区域和被水覆盖的区域(见下图)。植物反射*红外(NIR)光,水吸收 NIR 和红光。这种波段和颜色的组合使得健康的绿色植被在影像中呈现出鲜红色,而被水覆盖的区域呈现出*乎黑色。

在 QGIS 中,通过改变红色、绿色和蓝色光显示的图像波段,从卫星图像中创建假彩色合成图像。这些更改是通过将图层的符号系统设置为多波段颜色并更改默认波段显示设置来实现的。

本教程将演示如何使用 Landsat 8 卫星影像在 QGIS 中创建假彩色合成影像。同样的步骤可用于使用任何多波段影像创建假彩色合成图像。视觉学习者可以通过视频观看演示。

创建多波段栅格图层

如果您的影像已经是多波段格式,您可以进入下一部分。否则,请按照下列步骤操作。

确定栅格图层中波段的数量

要检查影像中的波段数,请将其添加到 QGIS,然后转到图层属性。选择左侧的信息选项卡。该选项卡可能包含每个波段的统计数据。向下滚动,直到看到尺寸信息。您将看到栅格图层中的行数、列数和波段数。

将 Landsat 波段添加到 QGIS

在本教程中,我将使用 Landsat 8 分析就绪数据。下面的视频演示了如何免费获取这些数据。

如何下载 Landsat 8 图像?

每个 Landsat 波段将由一个单独的栅格文件(.tif)。波段 1-7(实际上是 2-7)是我们最感兴趣的。下面列出了带的描述。更多关于陆地卫星 8 号仪器的信息可以从美国地质调查局获得。

  • 1 级沿海大气土壤(0.43-0.45 米)30 米
  • 波段 2 蓝色(0.450-0.51 米)30 米
  • 带 3 绿色(0.53-0.59 米)30 米
  • 波段 4 红色(0.64–0.67 米)30 米
  • 波段 5 *红外(0.85–0.88 米)30 米
  • 波段 6 短波红外线(SWIR)1(1.57-1.65 米)30 米
  • 波段 7 SWIR 2(2.11-2.29 米)30 米

将 Landsat 8 波段 1–7 添加到 QGIS。确保波段以数字顺序出现在内容列表中。这对于确保每个波段对应于多波段栅格的正确图层非常重要。添加后,您的目录应该类似于下图。

添加了 Landsat 8 波段 1–7 的 QGIS 目录。

将多个波段合并到一个栅格中

现在是时候将所有 Landsat 波段合并成一个单一的多波段栅格了。为此,进入 QGIS 主菜单上的“栅格”下拉菜单。展开“杂项”并选择“构建虚拟光栅”(见下图)。

打开构建虚拟栅格工具。

在出现的构建虚拟栅格窗口中,您会注意到输入图层下的一条消息,显示“选择了 0 个输入”。点击省略号(三个点。。。)在输入图层旁边。这将打开一个新窗口,显示当前加载到 QGIS 项目中的所有栅格波段。选择所有 7 个 Landsat 8 波段(这些应该是项目中仅有的 7 个图层)。您可以使用“全选”按钮。然后单击“确定”。

选择所有 7 个 Landsat 波段。

最后一步是指定输出文件。您也可以保留默认设置来创建临时图层。如果这样做,关闭 QGIS 后临时图层将不可用。指定输出文件后,单击 Run。构建虚拟栅格完成运行后,一个新图层将被添加到 QGIS 内容列表中。

构建虚拟栅格。

创建真彩色卫星图像

创建多波段栅格并将其添加到 QGIS 界面后,您会注意到它可能会以一些奇怪的颜色显示。让我们从创建真彩色影像开始,了解显示和符号化多波段影像的基础知识。

打开多波段栅格的属性,然后转到符号系统选项卡。“渲染类型”应为“多波段颜色”。如果不是,从“渲染类型”下拉菜单中将其更改为“多波段颜色”。

多波段颜色渲染器显示用于调整红色、绿色和蓝色波段的选项。默认情况下,红色、绿色和蓝色波段可能会分别设置为波段 1、2 和 3。然而,与红色、绿色和蓝色相对应的 Landsat 波段是波段 5、波段 4 和波段 3。使用下拉菜单将适当的波段分配给适当的颜色。

使用这些波段分配以真彩色显示 Landsat 8 图像:

  • 红色波段:Landsat 8 波段 4
  • 绿色波段:Landsat 8 波段 3
  • 蓝色波段:Landsat 8 波段 2

您的符号系统窗口应该如下图所示。一旦完成,单击确定,多波段图像将以真彩色显示。

产生真彩色陆地卫星图像的波段分配

这是显示的陆地卫星 8 号真彩色图像的一部分。

基于 QGIS 的假彩色卫星图像

彩色红外线

正如本文前面提到的,彩色*红外(或彩色红外)图像以红色显示绿色健康的植被。这张图片很容易用我们正在使用的地球资源卫星数据制作。我们只需要重新分配哪些波段显示为红色、绿色和蓝色。在 QGIS 符号系统选项卡中,将波段分配更改为以下内容,以创建彩色*红外图像。

彩色*红外假彩色波段组合

  • 红色波段:陆地卫星 8 号波段 5
  • 绿色波段:Landsat 8 波段 4
  • 蓝色波段:陆地卫星 8 号波段 3

你会得到一个与下图颜色相似的图像。你可以看到山上和农田里的植被是鲜红色的,湖水几乎是黑色的。

由 Landsat 8 数据生成的彩色红外图像。

另一个 Landsat 8 波段组合

下一个组合将绿色植被显示为亮绿色。如果你认为我们可以简单地将*红外波段显示为绿色,那你就错了!我们将把 SWIR 分配到红色波段,把绿色分配到蓝色波段。

  • 红色波段:陆地卫星 8 号波段 7
  • 绿色波段:Landsat 8 波段 5
  • 蓝色波段:陆地卫星 8 号波段 3

这种波段组合可以帮助我们可视化植被、土地、雪和水。在下图中,你会再次注意到,水几乎是黑色的,植被是绿色的,裸露的地面是粉红色/紫色的。在这幅图像中没有雪,但是如果有雪的话,它会呈现亮蓝色(几乎是青色)。这种波段组合通常被称为“自然去除大气”。

从地球资源卫星数据创建的“去除大气影响的自然”图像。

制作自己的颜色组合

请随意尝试乐队组合。你会发现一些看起来和这里提到的相似。你会发现有些看起来真的很丑,有些看起来很奇怪。下面我举了一个有趣的例子。它不一定有特定的功能,但它确实为不同的功能呈现了一些有趣的颜色。

由地球资源卫星数据生成的有趣的假彩色图像。

结论

理解可见光如何表现不同地表的特征是遥感的基础。使用多波段影像并生成伪彩色合成影像有助于您了解影像不同波段之间的相互作用。拥有制作这些图像的技能还将提高您的数据可视化,并帮助您有效地显示相关信息。

观看视频

教程的视频演示。

最初发表于【https://opensourceoptions.com】

如何用 Fastai 制作一个艺术模型

原文:https://towardsdatascience.com/how-to-make-a-state-of-the-art-model-with-fastai-bd11e168b214?source=collection_archive---------39-----------------------

使用学习率查找器和渐进调整大小方法进行图像分类,以便在短时间内获得最佳结果。

Amy Hirschi 在 Unsplash 上的照片

当我第一次开始 fastai 的旅程时,我非常兴奋地建立和训练一个深度学习模型,它可以在短时间内给出惊人的结果。既然我们已经看到了 fastai 与一些 Pytorch 基本函数一起使用的一些幕后培训术语,现在是时候看看在构建模型方面多做一点努力会产生什么结果了。

在这篇文章的最后,我将链接我以前的文章,在这些文章中,我记录了我对 fastai 的学习。😃

获取数据

我们需要这些数据来开始。它来自 Kaggle 的石头剪子布数据集。这个任务变成了一个多类图像分类问题,有三个类(每个类有训练、有效、测试文件夹)包含大小为 300x300 的 RGB 彩色图像。

为 fastai vision 的所有内容指定导入函数,并设置 path 变量。

**from** **fastai.vision.all** **import** ***path = Path('/storage/RockPaperScissors/RockPaperScissors/data/')
path.ls()**Output:
(#4) [Path('/storage/RockPaperScissors/RockPaperScissors/data/test2'),Path('/storage/RockPaperScissors/RockPaperScissors/data/valid'),Path('/storage/RockPaperScissors/RockPaperScissors/data/.DS_Store'),Path('/storage/RockPaperScissors/RockPaperScissors/data/train')]# make sure to set that path to wherever you've kept your data either locally or online.

现在我们将定义一个数据块来从文件夹中获取数据。我们指定这些来确保我们的数据在编写最少的代码时对模型可用:

  1. 如何用 get_image_files 函数获取图像文件——这只是收集我们的火车和有效文件夹中的所有图像文件
  2. 获得带有 parent_label 的类,这确保我们获得直接的父文件夹名作为我们的类名,最后,
  3. 使用grand parent splitter进行训练和验证拆分,这将为我们提供单独的数据集,用于使用文件夹进行训练和验证,这些文件夹在层次结构中处于上一级,或者训练和有效文件夹。
**def** get_dls(bs, size):
    dblock = DataBlock(blocks = (ImageBlock, CategoryBlock),
                       get_items = get_image_files,
                       get_y = parent_label,
                       splitter = GrandparentSplitter(),
                       item_tfms = Resize(size)
                      )
    **return** dblock.dataloaders(path, bs = bs)

这将返回一个数据加载器,它将给出一个批量大小为 bs 和一个图像大小为 大小为 的图像。

什么是渐进式调整大小,我们如何应用它?

正如杰瑞米·霍华德在他的书中所说的那样:用小图片开始训练,用大图片结束训练。使用小图像进行大部分 epochs 训练有助于训练更快完成。使用大图像完成训练使得最终的准确度高得多。

这是一种实验性的技术,已经被证明是非常有用的,在获得更高的精确度方面,比在使用相同大小的图像时要有用得多。

现在让我们看看怎样才能训练出多种尺寸,好吗?

我们将得到的批量大小为 64,图像大小为更小的 128x128。

dls = get_dls(64, 128)

现在,让我们来计算一下这部分培训应该使用什么样的学习率。

找到合适的学习速度

首先,我们利用迁移学习建立一个模型,如下所示。

learn = cnn_learner(dls, resnet34, metrics=accuracy)

然后,我们绘制一个图表,看看如何找到学习率。

learn.lr_find()

输出看起来像这样,如果我们取学习率的一个特定值,我们的损失看起来会是什么样子。

学习率图

看起来采用 1e-3 左右的学习率将足以确保我们的损失随着训练而减少。我们会选择那个。

learn = cnn_learner(dls, resnet34, metrics=accuracy)
learn.fit_one_cycle(10, 1e-3)

我们在最初的几个时代里看到了相当显著的结果。

学习第 1 部分

注意:我在 GPU 上训练这个模型,这就是为什么每个历元只需要几秒钟。

如果你只在 CPU 上训练,这将花费更长的时间,有时甚至大约 10 分钟。

既然我们已经在较小的图像尺寸上训练了模型,我们可以进行训练的第二部分。

我们使用批量大小为 128,图像大小为 224,用于模型的下一次微调。

learn.dls = get_dls(128, 224)
learn.fine_tune(5, 1e-3)

学习第 2 部分

正如您可以推断的那样,这为我们的训练带来了几乎 95%的准确率,并且在 GPU 上训练只需要大约三分钟!

结束…

Fastai 使我们能够快速开发任何深度学习任务,正如我在前几周对它进行的实验一样,我发现自己越来越喜欢它超级简单的方法。如果您热衷于跟随我的旅程,请确保关注我的持续更新,因为我将使用这个神奇的库探索更多的深度学习任务。

正如我之前承诺的,这里是我为 fastai 写的其他文章。编码快乐!😁

  1. fastai 快速入门:FastAI 快速入门——我的经历
  2. 像素相似性方法—引擎盖下第 1 部分: Fastai —探索训练过程—像素相似性方法
  3. 随机梯度下降和从零开始训练—引擎盖下第 2 部分: Fastai —从零开始随机梯度下降的多类分类

此外,这里是 GitHub repo 链接,包含所有代码:

https://github.com/yashprakash13/RockPaperScissorsFastAI

你想每周或两周收到一封免费的、干净的电子邮件,里面包含我发表的最好的策划文章和教程吗?加入我的代码广播吧!

推特LinkedIn 上和我联系!

如何用你的(天文学)图像制作视频

原文:https://towardsdatascience.com/how-to-make-a-video-from-your-astronomy-images-957f1d40dea1?source=collection_archive---------16-----------------------

从静态图像制作您自己的视频

你想过如何用你的数据制作一个视频吗?不要再想了!

你可能已经知道如何制作一个视频效果,方法是制作许多手工绘制的小图,然后一张一张地翻转它们。我采用了类似的方法,通过制作小的剪贴画并一个接一个地展示它们,从一幅大的射电天文学图像中制作了一个视频。

在我的例子中,我使用了来自 LOFAR 射电望远镜的图像。这台望远镜在低频无线电频谱中观察天空。它获得的信息可以转换成颜色,这样我们就可以将无线电波转换成人类可以理解的图像。原来宇宙中有很多正在发射无线电波的物体,比如活动星系、星系团、恒星形成星系、来自行星的磁场等等!你可以在这里找到来自 LOFAR 的惊人图片。

LOFAR 站之一。来源:维基共享资源

让我们创造吧!

但是,我们如何用这些图像制作一部电影,这样我们就可以浏览它了?这就把我们带回了图纸的翻转。在这种情况下,我们只需要将大的无线电图像切割成(许多)较小的图像(帧),每次移动图像的中心一点点,并将它们连成一行,这样我们就可以获得移动效果。

那么,你是怎么做到的呢?我使用了 Python 和命令行工具 FFmpeg。我的完整代码可以在这里找到。这是一个更大项目的一部分,在这里你还可以制作海报和互动地图。现在,你只需要关注脚本 make_movie.py.

首先用以下内容克隆回购:

git clone  [https://github.com/jurjen93/advanced_astro_visualiziation.git](https://github.com/jurjen93/advanced_astro_visualiziation.git)

现在你可以运行:
python make_video.py
在这里你可以使用以下标志

  • -d →选择从互联网下载特定的 fits 文件。如果需要,使用1,否则留空。
  • -csv →给出一个包含源文件的特定 CSV 文件。
  • -N →要使用的信号源数量。
  • -fr →视频的帧率。建议用60让视频流畅。
  • -fi →适合文件使用。(如果您没有下载您的 fits 文件)

所以最后你用了类似
python make_video.py -csv catalogue/catalogue_lockman.csv -d 1 -N 2 -f 60的东西

要做到这一点,你需要有一个以资源为中心的目录。“目录”文件夹中有一个例子。
使用以下字段:

  • RA →物体的赤经(与经度相当)
  • DEC →物体的赤纬(与纬度相当)
  • imsize →图像尺寸(度)

结果

现在,代码将帮助您从数据中生成一些精彩的视频,例如:

您还可以修改代码,将多个分辨率或大图像一个接一个地堆叠起来,这样您就可以做出类似这样的东西:

请随意修改 make_movie.py 脚本,因为它应该很容易使用,并且您可以制作自己的精彩视频。如果你有任何改进的建议,请告诉我!玩得开心!

如何让敏捷真正为分析服务

原文:https://towardsdatascience.com/how-to-make-agile-actually-work-for-analytics-e8fb2290276e?source=collection_archive---------8-----------------------

行业笔记

在所有关于将敏捷引入分析的争论中,我们可能忽略了一点

2001 年,当 17 名开发人员聚集在犹他州的 Wasatch 山区,讨论如何改进他们构建软件产品的方式时,我怀疑他们没有想到 20 年后,一个既不是软件开发人员也不是产品构建人员的社区会如此热烈地讨论他们的工作。然而,事实就是如此,几乎每周都有文章slack 问题或更多文章讨论敏捷分析的理论和实践。

我们是否以及如何将敏捷思想应用于数据,这可能会引起很大的分歧,因为它似乎引出了更大的、更现实的问题,即我们作为数据从业者是谁:我们真正的角色是什么——回答问题还是让其他人自己回答?数据是一种产品,一种服务,还是别的什么?商业用户是我们的合作伙伴还是我们的用户?我们应该如何最好地与他们合作?

随着承诺改变我们的数据堆栈和工作方式的技术和理论(例如,度量层和最后一英里分析)的到来,这些问题变得更加紧迫。随着我们进入这个新时代,是时候决定我们带走哪些敏捷概念,留下哪些了。

敏捷:期望与现实

在过去的 20 年里,敏捷的名声已经从一个边缘运动发展成为一个创始人所说的“工业综合体”。更好的组织、协作和结果的承诺吸引了几乎每个行业的每个团队尝试敏捷方法。

2017 年,我在一家大型科技公司的数据团队终于加入了战斗,并过渡到一个“敏捷分析”团队。也就是说,我们开始使用:

  1. 跟踪所有分析项目的看板
  2. 每天站起来回顾团队内部的进展
  3. 任何工作开始前无情的需求收集过程

就个人而言,前两个对我的生活几乎没有影响,除了让我嫉妒团队中其他人正在做的更酷的项目。最终,我的工作是我和企业之间的事;对我来说,每天和他们交谈会更有用。

具有讽刺意味的是,正是敏捷的第三个实现,需求收集,使得这变得不可能。通过更彻底的范围界定过程,我们预先加载了与业务的所有交互,以尽量减少迭代和更改。这种清晰让我们觉得更有控制力,但实际上我们只是把自己和伴侣进一步分开了。

很大程度上,这是我看到的当今数据团队拥抱敏捷的方式。看板帮助团队保持组织性。用户故事提供了一个框架,将模糊的问题转化为全面的项目。虽然这些以及其他敏捷方法可以提高组织性和清晰性,但我们也必须承认这是有代价的:我们和我们的商业伙伴之间的鸿沟不断扩大。

这提出了两个问题:

  1. 这样真的敏捷吗?
  2. 这种工作方式将来会对我们有用吗?

敏捷的精神

陈虎Unsplash 上拍照

敏捷现在被工业化的过程和公司术语所识别,但是在开始的时候,它有一个简单的目标:更快地构建更好的软件。

实现这一愿景的四个关键是:

  1. 流程和工具上的个人和交互
  2. 工作软件综合文档
  3. 客户协作合同谈判
  4. 根据计划应对变化

敏捷的真正精神是与众不同的,而且比我们今天用来与它互动的过程更有说服力。

敏捷方法的核心是将产品制造过程中固有的令人沮丧的东西——快速变化的需求——转化为竞争优势。

你可以想象这些软件开发人员会多么容易地说"嘿,伙计们,当你告诉我们我们实际上需要这个特性而不是那个特性时,我们厌倦了我们的工作每个月都变得过时,所以从现在起,在我们进行任何开发之前,你必须无情地验证需求和范围。

但至关重要的是,他们认识到他们快速转移技术的能力是比你的竞争对手更快地开发出优秀产品的关键。因此,他们专注于创造一种工作方式,这种方式不仅能使他们的代码中枢化,还能更快地与产品团队和用户沟通。

这是敏捷的真正精神,它有更多的东西可以教我们如何在今天和未来使用数据。

分析类比

为了将敏捷的精神应用到数据环境中,我们必须首先考虑我们与软件开发人员的相似和不同之处。

产品问题

我们所做的和软件开发人员所做的最显著的区别在于我们的最终产品。在软件中,目标是得到最终用户喜欢的产品。在数据方面,我们的目标是帮助人们做出他们信任的决定,用户到达目的地的过程可能与最终结果一样重要。

最常见的是,我们用数据讲述故事的方式体现了这一点。我们使用笔记本来捕捉上下文和流程,使用演示文稿来引导用户理解。正是在这个过程中,我们建立了信任,将图表转化为见解,并使我们的数据变得有价值。

这也是我们工作中最大的难题之一背后的驱动因素:后续问题和特别请求。

这些问题和请求来自于好奇心,代表了一种渴望,那就是我们在精心制作的数据故事中获得的对数据的同样深入的理解。然而,在实践中,我们试图用前期需求收集的过程和没有为这种工作方式腾出空间的工具来消除这些问题。

忽视数据和软件产品之间的这一关键差异可能(并且已经)将我们引向通往敏捷分析的错误道路。

敏捷分析宣言 SFD

为了将敏捷精神应用到分析领域,我们应该问自己一个类似于 17 位敏捷创始人的问题:

如果我们将今天从事分析工作固有的令人沮丧的东西——来自业务的不断发展的问题——转化为优势,会怎么样?如果我们这样做是为了拉*我们与商业伙伴的距离,而不是疏远他们,会怎么样呢?

我当然不会假装知道所有的答案,但本着安妮·拉莫特的傻逼初稿想法的精神,我已经做出了回答这个问题可能需要的许多迭代中的第一个:

  • 仪表板上的决策:通过关注人们希望用数据做什么,我们可以越过他们问的第一组问题,关注有价值的迭代和后续问题,建立信任,培养好奇心并推动行动。
  • 对完美输出的功能分析:为了实现快速迭代,我们将不得不花费更少的时间来制作完美的输出,并专注于尽快从一个问题转移到下一个问题。
  • 共享数据超过把关数据:我们将不得不与我们的业务合作伙伴共同承担我们的数据和数据“产品”的责任。这将有助于建立信任,并让我们所有人都对培养伟大的数据产品和数据驱动的文化负责。
  • 个人和互动优于流程和工具:当有疑问时,我们需要依靠我们与企业建立的关系,而不是我们用来帮助指导这些关系的工具。

就像最初的敏捷 17 一样,我知道我不能指望自己解决这个问题,我们作为一个分析社区必须讨论这个问题,并一起找到解决方案。你可以在这里加入辩论,我希望在我们的 时事通讯上分享更多关于这个话题的想法。

如何建立有效的共指消解模型

原文:https://towardsdatascience.com/how-to-make-an-effective-coreference-resolution-model-55875d2b5f19?source=collection_archive---------15-----------------------

如何改进现成的共指消解库

作者 玛尔塔·马朗考斯卡 帕韦·米耶尼克祖克

Dariusz Sankowski 在 Unsplash 上拍摄的照片

介绍

在本文中,我们介绍了如何改进 AllenNLP 的共指消解模型,以实现更连贯的输出。我们还介绍了几个集成策略,以同时利用 Huggingface 和 AllenNLP 模型。

简而言之,共指消解(CR)是一个 NLP 任务,旨在替换句子中所有的歧义词,以便我们获得不需要任何额外上下文就可以理解的文本。如果您需要复习一些基本概念,请参考我们的介绍文章。

在这里,我们主要关注改进库如何解析发现的集群。如果你对 CR 最常见的库的详细解释感兴趣(例如什么是 AllenNLPHuggingface ),我们的动机可以随意查看。

现成可用但不完整

Huggingface 和 AllenNLP 共指消解模型对许多项目来说都是一个很好的补充。然而,我们发现了几个缺点(在前一篇文章中有详细描述),这让我们怀疑我们是否真的想在我们的系统中实现这些库。最大的问题不是无法找到可接受的聚类,而是整个过程的最后一步——解析共指以获得明确的文本。

这让我们想到,也许我们可以为此做些什么。我们决定对最终文本进行几处小改动,从而带来显著的改进。因为 AllenNLP 似乎找到了更多的集群,而这些集群往往更好,所以我们决定采用一种更侧重于这种模式的解决方案。

拟议改进概述

我们已经决定将 AllenNLP 作为我们的主要模型,并利用 Huggingface 作为更多的参考,同时主要将其用作对 AllenNLP 输出的改进。我们的解决方案包括:

  1. 基于模型已经获得的聚类,改进 AllenNLP 替换共参照的方法,
  2. 引入几种策略,将两种模型的输出(聚类)合并成一个增强的结果。

为了改进相互引用的替换,有几个有问题的区域可以稍微容易地改进:

  • 在一个集群中缺少一个有意义的提及,可能成为它的头
    (一个跨度,我们用它替换给定集群中的所有其他提及)
  • 将第一个区间视为一个簇的头(这对于下一个区间尤其成问题),
  • 各种复杂情况,以及由于嵌套提及而导致的无意义输出。

所有上述问题都在下面举例说明:

在聚类中缺少有意义的提及(例如名词短语)的文本。

有下指的文本—代词在名词短语之前。

具有嵌套相关提及的文本。

我们对这些问题提出以下解决办法:

  • 如果一个集群不包含任何名词短语,就不要考虑它
  • 将聚类中的第一个名词短语(不是第一次提到的)视为其标题
  • 仅解析嵌套的共同引用中的内部范围

在下一节中,将详细解释这些方法,包括 AllenNLP 改进和组合模型的策略。此外,无论你想更深入还是跳过细节,下一章的所有代码都可以在我们的 NeuroSYS GitHub 库中找到。

深入改进

由于 Huggingface 基于 spaCy,使用起来毫不费力,并提供了多种附加功能。然而,修改起来要复杂得多,因为 spaCy 提供了许多机制,禁止您访问或更改底层实现。

此外,除了与 Huggingface 相比,AllenNLP 获得了更多数量的有效聚类之外,我们还发现前者更容易修改。

为了修改 AllenNLP 的行为,我们关注于 coref_resolved(text) 方法。它遍历所有聚类,并用第一个找到的提及替换每个聚类中的所有跨度。我们的改进只涉及这个函数和其中的嵌套方法。

下面是一个简短文本的例子,它包含了我们试图解决的上述所有三个问题,我们现在将重点关注这些问题。

冗余集群

为了让我们的解决方案简单明了,我们决定将有意义的提及定义为任何名词短语。

对于每个聚类,我们获取包含名词短语的跨度的索引(我们在下面的改进中也使用它们)。验证一个标记是否是名词的最简单的方法是使用 spaCy!事实证明,AllenNLP 也使用 spaCy 语言模型,但只是对输入文本进行标记化。

这里最让我们感兴趣的嵌套方法是 replace_corefs(spacy_doc,clusters) 。它不仅利用了 spaCy Doc 对象,还包含了实现我们的改进所需的所有逻辑。它看起来像这样:

空间文档中,我们知道名词由两个词性(POS)标签表示:名词属性。我们需要检查集群中每个 span 的 POS 标签(实际上是每个 span 中的每个令牌)是否是这两者之一。

下面展示了这段代码如何改进共指替换。现在,我们主要关注第一个集群,因为它显示了当前的问题。

解决下指问题

许多共指消解模型,如 Huggingface,在检测下指时存在严重问题,因为这种情况很少发生。一方面,我们可能对解决这种引起更多问题的异常情况不感兴趣。另一方面,根据文本的不同,如果我们忽略了它们,我们可能会丢失或多或少的信息。

AllenNLP 检测下指,但由于它将聚类中的第一个提及作为其头部,因此会导致进一步的错误。这是因为先行词(例如代词)在后置词(例如名词短语)之前,所以一个无意义的跨度成为一个簇的头。

为了避免这种情况,我们建议将集群中的第一个名词短语(不仅仅是任何提及)作为它的头,用它替换所有前面和后面的部分。这个解决方案是琐碎的,虽然我们可以看到其他更复杂的想法的优点,但我们的解决方案似乎对大多数情况都足够有效。

让我们仔细看看 AllenNLP 的 replace_corefs 方法中的几个关键行。

为了让我们的解决方案起作用,我们需要重新定义reference _ span变量(集群的头),这样它就表示第一个找到的名词短语。为了实现这一点,我们使用了我们的noun _ indexes列表——它的第一个元素是我们想要的。

让我们看看它是如何提高输出的。这次我们关注第二个集群。现在没有信息丢失!然而,由于 AllenNLP 根据找到的聚类的顺序返回结果,所以在我们的版本中也有一个小错误。不过不要担心,我们将在下一节中修复它。

嵌套提及

最后一个改进涉及由多个提及组成的跨度。正如我们在上一篇文章中所展示的,有几种策略可以用来解决这个问题,但没有一种是完美的:

  1. 仅用外部跨度替换整个嵌套提及→我们会丢失信息
  2. 替换内部和外部 span →在许多情况下不起作用,根据找到的集群顺序会导致不同的结果
  3. 仅替换内部 span →适用于大多数文本,但是,一些替换会导致无意义的句子
  4. 省略嵌套提及;根本不替换跨度→我们没有获得共指消解模型首先应该提供给我们的信息,但是我们 100%确定文本在语法上是正确的

我们认为,第三种策略——仅替换内部跨度——是信息增益和最终文本中可能的错误数量之间的良好折衷。它还提供了一个额外的功能—现在,无论群集排序如何,输出都将始终相同。

要实现它,我们只需要检测外部跨度并忽略它们。为此,我们只需检查特定的跨度索引是否包含任何其他提及。

最后,我们获得了一个包含所有改进的文本。我们意识到这个问题本来可以解决得更好,但是我们发现在解决方案的简单性和解决文本的有效性之间的权衡恰到好处。

如上图所示,我们可以获得更好的结果,同时只增强找到的聚类的解析方式。

整体策略

在所有的改进之后,我们现在可以转移到交集策略——关于如何结合 AllenNLP 和 Huggingface 集群的想法。正如我们之前提到的,我们认为 AllenNLP 产生了明显更好的集群,但它并不完美。为了在没有任何微调的情况下获得关于最终聚类的最高可能置信度,我们提出了几种合并两个模型输出的方法:

  • 严格-仅保留那些在 Huggingface 和 AllenNLP 模型输出中完全相同的聚类(聚类的交集)
  • 部分-仅保留那些在 Huggingface 和 AllenNLP(跨距的交点)中完全相同的跨距
  • 模糊-保留 Huggingface 和 AllenNLP 中部分相同(重叠)的所有跨度,但优先考虑较短的跨度

由于 AllenNLP 通常更好,我们将其作为我们的基础,因此在可疑的情况下,我们仅根据其发现构建输出。由于代码不像讨论的改进那样短,我们给提供了一个详细的 Jupyter 笔记本,在这里只看一下策略的输出。

以下示例摘自 GAP 数据集,我们之前已经详细解释过。

为了有效地比较提议的交集策略,更容易将模型的输出视为聚类集,如下图所示。值得注意的是,AllenNLP 和 Huggingface 不仅发现了略微不同的提及,还发现了整个集群。

两个库都找到的集群— AllenNLP 和 Huggingface。

通过每个交集策略获得的聚类 AllenNLP 和 Huggingface 的集合。

我们大多倾向于模糊策略。它提供了比单一模型的输出更高的确定性,同时还提供了最大的信息增益。所有策略都各有利弊,因此最好进行试验,看看哪种策略最适合您的数据集。

让我们看看最终的结果——包含已解决的相互引用的示例,包括我们之前的改进:

尽管最终的文本听起来不太自然,但我们必须记住,共指消解的目的通常是为语言模型消除歧义。因此,他们可以更好地理解输入,并能够产生更合适的嵌入。在这种情况下,我们只缺少一条信息——他死于 1370 年——同时获得了许多正确的替换,并去掉了过长的提及。

摘要

在我们的文章中,我们解决了 NLP 中的一个主要问题——共指消解。我们解释了什么是 CR,介绍了最常见的库以及它们带来的问题,现在向展示了如何改进现有的解决方案

我们试图用多张图片和各种例子来阐明我们可能有的一切。基本用法和我们的修改都可以在我们的 NeuroSYS GitHub 上找到。

希望现在您已经熟悉了共指解决方案,并且可以轻松地将我们提出的解决方案应用到您的项目中!

如何让人工智能清晰地表达疑问

原文:https://towardsdatascience.com/how-to-make-artificial-intelligence-articulate-doubt-9c2885a9e541?source=collection_archive---------42-----------------------

影响人们生活的模特必须坦诚面对他们的疑虑。这种新方法给可解释的人工智能带来了*衡。

特征空间,我们已经发表了一个方法来解释深度网络中的模型不确定性。我们的方法可以理解模型认为不符合其预测类别的输入数据中的混杂模式。这允许我们部署诚实和透明的模型,为决策提供*衡和完整的证据,而不仅仅是管理支持决策的证据。

例如,在下图中,我们观察到包含在 CelebA 数据集中的三幅名人图像。在所有情况下,名人都被标记为“不笑”,这可以使用广泛可用的用于图像处理任务的深度分类模型来轻松预测,如 VGG16、ResNet50 或 EfficientNet。然而,模特们很难为这些照片中的一些提供自信的分类。在下面的例子中,我们提出的方法强调了导致模型不确定的各种特征(右栏)。我们很容易注意到微笑弧、上唇弯曲和口腔走廊的存在,这些通常与微笑和咧嘴笑有关。

:CelebA 数据集中预测类别标签为“没有笑容”的名人脸部图像。 :由我们的方法高亮显示的像素(红色)导致模型对该预测不确定。作者图片。

不确定性和贝叶斯深度学习

我们在贝叶斯神经网络(BNNs)的基础上建立了我们的不确定性归因方法。该框架彻底处理了预测中不确定性的所有来源,包括源于模型选择和训练数据限制的不确定性,其表现为每个神经细胞的拟合权重参数的不确定性。点击查看中的 BNNs 概述。总而言之:

  1. 神经元的每个拟合参数被捕获为一个概率分布,该概率分布表示在给定训练数据的情况下,我们对其最佳值缺乏确定性。
  2. 由于深度模型有大量参数,因此,我们在所有训练参数上有一个多元分布,称为后验分布。
  3. 当我们对一个新的数据点进行分类时,每个拟合参数值的合理组合都会给我们一个不同的分数!BNN 提供给我们的不是一个单一的分数,而是一种可能分数的分布,称为后验预测分布。
  4. bnn 通常返回后验预测分布的*均值作为它们对输出分数的估计。

这些计算通常是*似的,并在引擎盖下运行,例如,当您将脱落层添加到您的神经模型架构中时。重要的是,对于我们希望分类的每一幅图像、一段文本或金融交易,我们可以检索代表分数应该是多少的分布。MNIST 数字的一对示例分布如下所示。分布的*均值告诉我们分类有多确定,而方差告诉我们建模不确定性有多稳定。请注意,*均分数有时可能与由最可能的组模型参数产生的分数非常不同,这是非贝叶斯神经网络通常返回的分数。在第一个例子中,最可能模型与*均模型分数的偏差特别大。

两个 MNIST 数字的潜在类别患病率的后验预测分布,最可能类别的 BNN 概率相似。在顶部图像中,所示的分布(对于类别标签“8”)支持大范围的可能得分,事实上它是双峰的,有利于确定图像必须是“8”,或者确定它不可能是“8”。这意味着图像代表数据中的稀疏区域,在训练集中只有很少或没有样本。相反,底部图像中的分布在 0.5 附*达到峰值,并且相对较窄。这意味着训练集在特征空间的这一点上包含内在类别混合的证据——它已经看到了类似的例子,这些例子或者被标记为(不完整的)7,或者被标记为具有外围墨迹的杂散斑点的 1。作者图片。

解释模型不确定性

为了解释预测中的不确定性,我们的方法建立在积分梯度 (Sundararajan et al. 2017)的框架上,这是神经网络最广泛的解释技术之一。集成梯度通过对模型的输出倾向得分 p c (x) 的梯度进行集成来工作,对于类别 c. 它沿着基准起始点和被解释的点之间的特征空间中的路径执行该集成。对于不确定性的解释,我们不积分模型分数的梯度,而是积分预测熵的梯度

H(x)=-σc PC(x)。log pc(x)

该度量包含模型的总预测不确定性,包括源自后验预测分布的位置和宽度的分量。

我们在公共图像基准上测试了集成熵梯度,包括 MNIST 和 CelebA 人脸数据集。不幸的是,由普通的综合梯度产生的熵解释被证明是糟糕的、令人困惑的,而且是一种敌对的解释。这是可以理解的,积分梯度需要一个基准特征向量作为路径积分的原点,而普通算法使用空白图像作为其基准。这有合理的动机来解释为什么分数高,因为空白图像可能对所有类别具有大致相等的模型分数;然而,围绕黑色图像的不确定性通常非常高。

为了克服这个和其他问题(这些问题的细节在论文中),我们的方法结合了两个最*的想法来产生干净和有信息的熵属性——这两个方法都利用了潜在的空间学习表示,使用了变分自动编码器。

  • 综合反事实解释 ( 安托万等人 2021 )。对于我们的路径积分的源图像,我们希望图像具有与测试图像相同的预测类别,但是预测熵为零。合成的反事实解释图像提供了这样的源图像,同时具有吸引人的属性,即源图像与测试图像非常相似——也就是说,增量限于那些增加不确定性的概念。
  • 分布内路径积分 ( Jha 等人 2020 ) 积分梯度的一个问题是基准源和测试向量之间的路径可能偏离数据流形——通过不可能的图像探索轨迹。我们希望基准点和测试点之间的路径积分在数据流形内,即:两幅图像之间路径上的每个特征向量都代表了数据中可能合理出现的一些情况。

结合起来,这些想法产生了干净和相关的不确定性解释,即使是对困难的机器学习问题,如阅读人类表情。我们通过解释 CelebA 数据集中最不确定的图像来证明这一点,如微笑检测,拱形眉毛检测和眼袋检测。

与预测“拱形眉毛”(上面两行)和“没有拱形眉毛”(下面两行)的现有方法相比,我们的方法的不确定性解释。作者图片。

结论

新兴的可解释人工智能领域通常专注于收集证据,证明支持已经做出的决定,就像律师在法庭上陈述案件一样。然而,大多数人工智能模型的操作更像专家证人,而不是律师说服法官。这就明确了对更加*衡的解释方法的需求,这种方法提供了阐明模糊性、不确定性和怀疑的细致入微的解释。我们的方法所做的是用丰富而简洁的解释来补充传统的分数归因方法,解释为什么数据点的分类是不确定的。随着机器学习被更广泛地用于为对生活有重大影响的法律、金融或医疗决策提供信息,对自动化预测背后的证据权重进行诚实和公开的评估对于维护道德标准至关重要。

如何使用 matplotlib 制作带标签的条形图和 hbar 图

原文:https://towardsdatascience.com/how-to-make-bar-and-hbar-charts-with-labels-using-matplotlib-b701ce70ba9c?source=collection_archive---------12-----------------------

使用来自传奇联盟的数据的初级数据科学项目指南

露丝·齐默曼Unsplash 上拍摄的照片

简介

我第一次做条形图的时候,我不能马上 如何给条形图添加标签。尤其是水*条形图对我来说很麻烦。所以,如果你也不能让它工作,也不要担心。在这篇文章中,你将学习这是如何完成的,以及一些设计图表的技巧和诀窍。

N 注: 如果您只需要了解如何添加标签,您可以跳到以下部分:**创建带标签的条形图 。我已经包含了我为你写的所有代码,如果你想边读边打字的话,我可以把它们复制下来,同时还有关于代码如何工作的详细解释。

为了让我教你如何制作带标签的条形图,我需要一些数据。所以我决定从网游《英雄联盟》 中抓取一些游戏数据。这让该指南对游戏的粉丝来说更有趣,(包括我自己)。这篇文章的第一部分是为演示我如何清理数据使其成为我喜欢的格式。我鼓励你阅读这一部分以及,它教你一种方法将数据从 JSON 格式转换成 Pandas 数据帧。

该员额的结构如下:

准备数据(JSON 到 Pandas 数据框架)

我有一个 JSON 文件,里面包含了英雄联盟中所有冠军(可玩角色)的基础统计(特征)。* 你可以在这里访问数据文件。 数据看起来是这样的(见截图)😗

总共有 153 个冠军在他们的字典中包含相同的关键字。

最后,我们将制作一个条形图,显示冠军的开始 hp (生命值),以了解哪些冠军开始时最健康。如果你对其他统计数据感兴趣,你可以非常容易地改变条形图显示的内容,例如,你可能有兴趣看看哪些冠军拥有最多的 ad (攻击伤害)。

接下来,我想将这些数据从目前的 JSON 格式转换成一个 Pandas DataFrame

我鼓励你试着编码,因为这会给你最好的理解!边做边学你懂的。

*import pandas as pd
import matplotlib.pyplot as plt
import json*

我从导入我们将使用的必要库开始。Pandas 允许我们制作DataFrames,这是一个很好的数据科学结构。Matplotlib.pyplot将被用来制作图表。json将允许您将 JSON 文件中的数据加载到内存中,供我们使用。

*with open('champ_stats.json') as f:
  data = json.load(f)champion = data['Aatrox']
stat_names = list(champion.keys())
columns = ['champ'] + stat_names
df = pd.DataFrame()*

我打开数据文件并将其加载到名为data的变量中。接下来,我想有一个列表,其中包含所有不同的统计数据的名称,(冠军的统计数据/特征),因为这将是完成的数据帧的列名。统计列表包含在数据中所有的冠军字典中,因此我们只需要深入其中一个字典并从该字典中获取关键字。我们使用'Aatrox'键,因为这是数据的第一个冠军。这给了我们保存到champion变量的相应值。这个值是另一个字典,其中所有的键都是我们正在寻找的名字,因此我们使用.keys()函数来获取它的键,当在list()函数中调用该函数时,返回值被转换为一个列表。 如果这一步让你困惑,我已经写了另一个指南,解释了 如何访问 python 字典中的数据,你可以在这里找到

数据帧的列名将是第一列的'champ',它将包含所有冠军的名字,其他列将以stat_names中的项目命名。我们把它保存到变量columns中。最后,我们使用pd.DataFrame()创建一个空的数据帧,并保存到变量df中。

***for name, stats in data.items():
  values = [stats[x] for x in columns[1:]]
  row = pd.DataFrame([[name] + values], columns=columns)
  df = df.append(row)
df.head()***

在上一步中,我们有一个空的数据框架,现在是用数据行填充它的时候了,每一行代表一个冠军。我们现在为语句制作一个,该语句遍历数据字典中的所有键值对,(name是键,stats是值)。我们想要一个所有 stat 值的列表,为此我使用 list comprehension 并将结果列表保存到变量values。列表理解是这样工作的:对于columns[1:]中的每个名字(x),我们取这个名字,并把它作为从stats中访问相应值的键,这个值被添加到列表中。****

接下来,我们制作一个新的数据帧,保存到变量row 。这个数据帧用两个参数实例化。首先,一个列表中的列表,其中内部列表包含当前冠军的名字和所有值。其次,将形式属性columns=设置为我们的列表变量,也称为columns,这将按照我们的需要设置数据帧中的列名。
接下来,我们将row附加到我们称为df的主数据帧,这将返回一个新的数据帧,我们用它来覆盖之前的df

最后,我们调用df上的head()方法来显示 DataFrame 的第一行。如果您已经编写了代码,现在应该会得到以下输出:

数据现在已经很好地格式化为 DataFrame,下一步我们将最终创建条形图并添加标签。

创建带标签的条形图

***df_sorted_by_hp = df.sort_values('hp', ascending=False)
x = df_sorted_by_hp['champ'][:15]
y = df_sorted_by_hp['hp'][:15]***

为了改进图表,我选择了按'hp'值对数据帧中的行进行排序,而ascending=False按降序对值进行排序。之后,我们将冠军列保存到名为x的变量中,类似地,将 hp 保存到变量y中。为了确保图表不会太混乱,我选择只包括前 15 名冠军,这是用[:15]后缀完成的。**

***fig, ax = plt.subplots(figsize=(20,4))
bars = ax.bar(x, y, width=0.5)***

我们使用plt.subplots(figsize=(20,4))创建一个图形对象和一个轴对象,它们被保存到变量figax中。我们将图形尺寸设置为 20 乘 4 英寸,这可能不是绝对的最佳尺寸,但是您可以随意使用这些数字,直到找到最适合您的图表的尺寸。ax.bar(x, y, width=0.5)使用我们的xy值以及 0.5 的width值创建条形图,同样,您可以尝试 0 到 1 之间的不同宽度大小。我将返回的对象保存在变量bars中,我们很快就会用到这个变量。

代码将生成下面的图表,(只是其中的一部分,以便更好地适应媒体):**

…不是很酷

首先,条形的高度差非常难以区分,其次,不可能读出每个条形的精确高度。这就是标签有用的地方!
现在就让添加它们吧!

注意:将下面的代码片段追加到前面的代码片段中。

***for bar in bars:
  height = bar.get_height()
  label_x_pos = bar.get_x() + bar.get_width() / 2
  ax.text(label_x_pos, height, s=f'{height}', ha='center',
  va='bottom')***

我们可以循环通过bars变量来检查图表中的每一个条形。我们通过从bar.get_height()函数中获取每个条形的高度,将其保存到一个名为height的变量中。接下来,我们需要循环中当前条的标签的 x 位置。我们从bar.get_x()函数中获得这个位置,然后将条形的宽度除以 2,得到条形中心的 x 值。

最后,我们使用ax.text(label_x_pos, height, s=f'{height}', ha='center')来创建标签/文本。这个函数接受一个 x 位置的值和一个 y 位置的值,然后我们给它一个将要显示的字符串,在这个例子中是条形的高度。最后,ha='center'进一步帮助标签在酒吧的中心对齐,va='bottom'将标签放在酒吧的正上方。

这将产生下面的图表,(只是其中的一部分,以便更好地适应媒体):**

是啊!现在我们有了显示各自高度的条形标签!这显然更好,但仍可改进。

我认为由于尺寸的原因,条形下方的名称有点难读。此外,我想为图表的标题以及轴的描述。此外,让 y 轴从 0 开始是没有意义的。最后,我认为*这个图表可以用一些颜色来增加趣味!*******

注意:将下面的代码片段追加到前面的代码片段中。

***for tick in ax.xaxis.get_major_ticks():
  tick.label.set_fontsize(14)for bar in bars[::2]:
  bar.set_color('r')plt.title('The 15 champions with the most HP')
plt.xlabel('Champion name')
plt.ylabel('Starting hp')
plt.ylim([550,650])plt.show()***

您可以通过循环从ax.xaxis.get_major_ticks()返回的刻度来设置每个刻度的字体大小,并用tick.label.set_fontsize(14)提供字体大小。同样,您可以使用for bar in bars[::2]:访问每隔一个条,并使用bar.set_color('r')设置颜色。标题、x 标签和 y 标签可以用它们对应的功能来设置。最后,你可以用plt.ylim([550, 650])限制 y 轴(x 轴也一样)。我发现从 550 开始到 650 结束对这个图来说是可行的。

plt.show()将显示完成的条形图,(只是其中的一部分,以便更好地适应介质):**

我认为这是一个很大的进步!

要制作一个水*条形图,我们需要做的改动很少。因此,我将在单个代码片段中显示代码,并以粗体突出显示中的变化。此外,请记住,数据与之前相同,因此我们仍然拥有x变量中的所有名称和y变量中的所有 hp 值。**

***fig, ax = plt.subplots(figsize=(**4, 10**))
bars = **ax.barh**(x,y, 0.5)for bar in bars:
  **width = bar.get_width()** #Previously we got the height
  **label_y_pos = bar.get_y() + bar.get_height()** / 2
 **ax.text(width, label_y_pos, s=f'{width}', va='center'**)for tick in ax.**yaxis**.get_major_ticks():
  tick.label.set_fontsize(14)for bar in bars[::2]:
  bar.set_color('r')plt.title('The 15 champions with the most HP')
plt.**xlabel('Starting hp')**
plt.**ylabel('Champion name')**
plt.**xlim**([550, 650])plt.show()***

与之前一样,我们创建图形和轴对象并设置大小,但是,这一次大小为 (4,10) 效果更好,(高比宽)。为了制作水*条形图,我们使用* ax.bar**h**()而不是ax.bar()。接下来,我们得到的不是每个条形的高度,而是宽度。我们需要使用bar.get_y()而不是 x 位置来获得条形的 y 位置,并且我们添加条形的高度除以 2,(注意,与之前相比,这里的高度具有不同的含义)。***

我们再次用ax.text()设置条的标签,但是,我们用width表示 x 位置和要显示的字符串。此外,我们使用参数va='center',这有助于将标签放在条的中心。试着移除它,看看有什么不同。**

对于刻度,我们只需改变 y 刻度的大小,而不是 x 刻度的大小。最后,您必须切换轴的标签,并限制 x 轴相对于 y 轴。
结果:

瞧,你现在知道如何制作垂直和水*条形图,以及添加标签使它们更具可读性。

摘要

如果您遵循了整个指南,那么您现在已经创建了一个小项目,在这个项目中,您将 JSON 数据转换为 Pandas 数据框架,然后创建带有标签的条形图。

就我个人而言,我更喜欢水*条形图,因为我觉得这样更容易阅读
记住
如果你有兴趣可以进一步探索数据。尝试找出哪个冠军的血量最少,或者在你的图表上显示更多的冠军。****

如果你对这篇文章有任何问题、意见或建议,请随时联系我!

感谢你花时间阅读这篇文章,希望你学到了有用的东西!

坚持学习!
—雅各布·托夫加德·拉斯姆森

如何在 Python 中用 Click 制作漂亮的命令行界面

原文:https://towardsdatascience.com/how-to-make-beautiful-command-line-interfaces-in-python-with-click-d6d744aad3eb?source=collection_archive---------18-----------------------

使用 Python 的 Click 制作令人惊叹的命令行界面概述

(图片由 Pixabay 上的 OpenClipArtVectors 提供)

介绍

命令行界面,或 CLI,是程序员经常用来从终端或 REPL 控制他们的软件的一个重要工具。命令行界面的问题是,虽然它们并不特别难制作,但制作起来可能会有点乏味和烦人。此外,它们很难做得很好或完美。命令行界面经常会变得杂乱无章,这对于可能有用户也在与 CLI 交互的应用程序来说是个问题。不好看的东西只会更令人困惑,我们如此习惯于以一种方式消费内容、阅读或解释事物,以至于如果它们不符合那些规格,就会导致我们大脑中的小短路。

幸运的是,对于 Python 程序员来说,有一些非常棒的工具可以用来在 Python 内部创建增强的 CLI。这类工具的一个例子是名为 Click 的 Python 模块。我在另一篇关于 Python 中令人敬畏的装饰者的文章中列出了 Click,如果你也想阅读那篇文章,你可以在这里阅读:

</10-of-my-favorite-python-decorators-9f05c72d9e33>

Click 模块是一个用于 Python 的可组合命令行工具包,由 Pallets 团队开发。如果您想了解有关托盘团队和 Click apparatus 的更多信息,您可以在此处查看 Click Github 页面:

https://github.com/pallets/click

您可能不知道,但很可能您实际上也使用了托盘团队的另一个模块。他们还负责 Flask WSGI 模块,这是 Python 程序员的行业标准。不用说,这个团队对软件的贡献是显著的,我感谢他们对开源软件的承诺。

今天,我想浏览一下 click,看看该模块提供了什么。该模块功能齐全,非常健壮,所以这里需要解释一下。我们还将参与另一篇文章中的一个项目,以展示该包的功能。

开始一个项目

点击模块的应用可能适用于任何类型的用 Python 构建的应用。这是一件很棒的事情,因为在很多情况下,点击确实可以增加趣味。首先,我创建了一个漂亮的小目录来存储我们的 Python 项目。因为这里没有太多内容,而且我已经在 Python 的全局环境中安装了 click 模块,所以我不想为这个项目创建一个虚拟环境。

让我们编写文件的基础:

import click as clkdef main(): if __name__ == "main":
    main()

我们在这里所做的就是编写一个主函数,导入 click,然后做 if __name… Python 的事情来命名我们的主函数,因为我们可能会通过 CLI 调用这段代码。现在让我们来看看 click 模块实际包含了什么,这样我们就可以构建一些漂亮的命令行界面了!

为点击创造一些东西

为了利用 click,我们需要做的第一件事是制定一个明确的目标,并确定将通过 CLI 提供的用于控制该应用程序的参数。我想到了一个好主意

战斗模拟器

这将把随机性和力量考虑在内,并对战斗做出裁决。我认为这将是一个有趣的项目,因为可能会有很多这种类型的东西,也许我甚至可以为它开辟一个新的存储库,并在未来的文章中创建一些更酷的东西。假设我们正在创建一个战斗模拟器,我在这里要做的第一件事就是定义

"顶级的等级制度。"

听我说,朱莉娅程序员和所有人。我的意思是我们需要一个

“抽象类型…”

我们需要一个类,它将是其他类的父类。在这种时候,从一个范例到另一个范例真的会让你的大脑很难受。首先,让我们在我的游戏中加入一个视觉元素,一个 REPL 装订的印刷品和清晰的循环。我之所以要先这么做,是想看看这个想法是否行得通,这有助于我意识到自己是否需要一直贯彻下去。

我是说,这整件事毕竟是自发的。

我们的项目

虽然我不会详细介绍我是如何制作这个小游戏的,但您可能会在这篇文章中发现这一点:

在本文中,我们主要评估点击模块的应用。也就是说,为了更好地理解这个项目,我还会展示一些类,做一些基本的解释来揭示游戏是如何工作的。要全面、深入地了解这款游戏以及我对其组件的编程,我当然会建议阅读上面的文章!此外,这里还有一个我今天要使用的 Github 库分支的链接:

https://github.com/emmettgb/characterclash/tree/0.0.3-CLI

总之,这个程序的类结构是这样的:

  • play grid([players])
    play-grid 将获取一个玩家,并在上面打印一个玩家的网格。它接受玩家的完整列表,并管理视觉方面以及与环境中其他人物的交互。
  • 玩家(位置,

我想我应该写几篇文章来介绍这个整洁的小项目的创建,因为我创建了一个完整的东西来把 CLI 放入其中。在未来,我们将训练一个模型来控制我们的玩家角色,但现在我们只是简单地添加一些命令行参数并稍微改变这个项目的代码,以便接受这些新数据并对其做一些事情。鉴于这基本上是一个我们编写的基于角色的 2d 游戏引擎,有一些全局定义的变量,并且肯定有很多我们可能希望能够从命令行改变的变量。我希望能够改变的主要论点是

  • 网格宽度
  • 网格高度
  • 随机字符数
  • 在未来,我想考虑让最终用户来设置角色。

事不宜迟,让我们试着用点击模块来完成这些目标吧!

使用点击

首先,我将调用 click @click.option()装饰器。我们将把下面所有的装饰器放在我们的主函数之上。

# CLIS
@clk.command()
@clk.option('--width', default = 30, help = 'Width of the draw grid.')
@click.option('--height', default = 100, help =' Height of draw grid.')
@clk.option('--players', prompt='Number to simulate',
              help='The number of randomly generated players to include.')

这可以采用各种关键字参数,但是位置参数当然是最重要的,它只是一个参数名。接下来,提供帮助信息和这种性质的东西。我们还可以提示用户输入一些值。我还需要删除将全局定义这些别名的以下代码:

CHAR_W = 30
CHAR_H = 100
rplayers = 20

我们需要将这些作为变量填充到整个包中,这有点麻烦,但是真的不会那么糟糕。我们的主要功能现在看起来像这样:

click.command()
[@click](http://twitter.com/click).option('--width', default = 30, help = 'Width of the draw grid.')
[@click](http://twitter.com/click).option('--height', default = 100, help =' Height of draw grid.')
[@click](http://twitter.com/click).option('--players', prompt='Number to simulate',
              help='The number of randomly generated players to include.')
def main():
    players = []
    players.append(Player([11, 20], 0))
    players.append(Player([5, 6], 1))
    players.append(Player([20, 10], 2))
    players.append(Player([11, 20], 0))
    players.append(Player([11, 20], 0))
    players.append(Player([11, 20], 0))
    players.append(Player([11, 20], 0))
    players.append(Player([11, 20], 0))
    players.append(Player([11, 20], 0))
    game = PlayGrid(players)
    for i in range(1, 50):
        sleep(.5)
        game.update("".join(["Iteration: ", str(i)]))

带着我们的 CLI

这里需要的是一个全面的 while 循环,它开始游戏并继续循环,直到所有的玩家都死了。我将继续这样做,尽管我们专注于 CLI,因为这将是我们最后一次需要调整这些参数,此外还有一些我希望在未来进行的升级。我们需要将所有命令行参数作为参数添加到主函数中:

def main(players, width, height):

我要做的第一件事是去掉这个大的 players.append()函数,它将被提取到一个迭代循环中,而不是在一个我还没有定义的新函数中,

players = random_players(players)

现在 main()函数看起来有点像这样:

def main(players, width, height):
    players = random_players()
    game = PlayGrid(players)
    for i in range(1, 50):
        sleep(.5)
        game.update("".join(["Iteration: ", str(i)]))

我们将继续下去,去掉这个 for 循环,只关注初始化。我们还需要改变在 update()函数中处理宽度/高度的方式。下面是这个函数的一个例子:

def update(self, message):
        clear()
        self.empty_grid()
        self.draw_players(self.grid)
        self.make_moves()
        print(self.draw_grid())
        print("\n" + message)

我们可以在这里添加网格的宽度和高度,因为每次绘制网格时都会调用这个函数。然而,我想我会将网格尺寸定义为全局变量。这将意味着即使是玩家也可以知道网格的大小,这可能是保持工作的关键。另一个很好的方法可能是把它放在类中,但是如果是这样的话,那么每当调用播放器的任何方法时,类的初始化版本都需要作为 self 传递。这当然是有意义的,但是考虑到这更多的是关于网格是窗口的维度的讨论,保持这样的东西是全局的可能是一个好主意,这样我们总是知道它的大小。鉴于这些是 CLI,它们将先于我们是全球性的,因此我们可以忽略这些参数。

players = random_players()
    game = PlayGrid(players)
    for i in range(1, 50):
        sleep(.5)
        game.update("".join(["Iteration: ", str(i)]))

现在这三件事情中的两件已经处理好了,我们唯一要做的事情就是创建一个基本的 while 循环,它将在玩家> 1 时执行所有操作。这样游戏就不会结束,直到一个玩家消灭了所有其他人,顺便说一下,这还没有实现——所以我们将永远看着这些无意义的战斗。

永远。

round_counter = 0
    while len(players) > 1:
        round_counter += 1
        sleep(.5)
        game.update("".join(["Iteration: ", round_counter]))

现在我们只需要编写我们的随机玩家函数:

def random_players(n_p):
    players = []
    for p in range(0, n_p):
        pos = [random.randrange(1, width), random.randrange(1, height)]
        player = Player(pos, p)
        players.append(player)
    return(players)

Player()构造函数需要一个位置和一个 ID。ID 是它在玩家列表中的索引位置。

现在让我们试着运行这个:

players
    for p in range(0, n_p):
TypeError: 'str' object cannot be interpreted as an integer

我们可以通过在传递该类型时简单地添加一个整数转换来解决这个问题。

def main(players, width, height):
    players = random_players(int(players))

打字强很棒。

我还将 width 和 height 重命名为 w 和 h,这样我们可以独立于 CLI 调整全局定义。这是整个包装的外观:

import click as clk
import random
from time import sleep
from os import system, name
width = 30
height = 100
# CLIS
[@clk](http://twitter.com/clk).command()
[@clk](http://twitter.com/clk).option('--w', default = 30, help = 'Width of the draw grid.')
[@clk](http://twitter.com/clk).option('--h', default = 100, help =' Height of draw grid.')
[@clk](http://twitter.com/clk).option('--players', prompt='Number to simulate',
              help='The number of randomly generated players to include.')
def main(players, w, h):
    players = random_players(int(players))
    game = PlayGrid(players)
    round_counter = 0
    width = w
    height = h
    while len(players) > 1:
        round_counter += 1
        sleep(.5)
        game.update("".join(["Iteration: ", round_counter]))

好吧,让我们试试这个!:

[emmac@fedora CharacterClash]$ python3 character_clash.py.......yers
    current = list(grid[newpos[1]])
KeyError: 40
[emmac@fedora CharacterClash]$

对于为什么现在会发生这种情况,我的最佳猜测是我们的范围混合了 x 和 y 值。有趣的是,我遇到了一个大问题,因为它们被翻转到绘制网格的函数内部:

def empty_grid(self):
        self.grid = dict()
        str = ""
        for row in range(1, height):
            str = ""
            for i in range(1, width):
                str += "`"
            self.grid[row] = str

现在我得到另一个类似的错误:

File "/home/emmac/dev/CharacterClash/character_clash.py", line 55, in draw_players
    current[newpos[1]] = player.symbol[0]IndexError: list assignment index out of range

我认为这里的问题可能与我在这里做的索引有关。应该是 newpos[0]而不是 newpos[1]。这一次我们错误地调用了 x,而我们应该调用 y。请允许我用代码中的一点引用来更好地解释一下:

current = list(grid[newpos[1]])
current[newpos[0]] = player.symbol[0]
current[newpos[0] + modifier] = player.symbol[1]

在这个函数中,current 是该列字符串中的一组字符。我们通过用 y 值调用网格字典来选择该列。现在,我们调用当前索引中的 x 值,以便获得位置,并用我们的字符符号替换它,希望得到合适的结果。

最后一件事,我们时常会遇到这个关键错误:

File "/home/emmac/dev/CharacterClash/character_clash.py", line 54, in draw_players
    current = list(grid[newpos[1]])
KeyError: 0

这个关键错误可能会让人认为 draw_players 函数没有正常工作,但实际上数据的格式不适合该函数——没有我们需要的网格的 0 索引。我们只需要改变填充这个字典的 for 循环:

def empty_grid(self):
        self.grid = dict()
        str = ""
        for row in range(1, height):
            str = ""
            for i in range(1, width):
                str += "`"
            self.grid[row] = str

用 0 替换 1,

for row in range(0, height):
            str = ""
            for i in range(0, width):

我们还需要在高度上加+ 1,这样所有的网格都会被填充。每当一个位置通过球员移动函数出现时,我们都需要检查并确保它不在界内。然而,我认为一个正确的方法是编写一些冲突,因为我们现在可以测试我们的 CLI,我认为我们应该这样做。每当我们运行新文件时,都会得到以下结果:

[emmac@fedora core]$ python3 character_clash.py
Number to simulate:

我现在会尽我所能得到每个循环的截图。为了帮助我做到这一点,我将把 sleep()计时器设置为 2 秒。接下来是屏幕上播放的动画 GIF:

[emmac@fedora core]$ python3 character_clash.py
Number to simulate: 5

(图片由作者提供)

我们拥有的

到目前为止,所有这些工作的结果都很酷,正如你在上面的动画中看到的。此外,打电话时,我们有调整高度和宽度的选项:

[emmac@fedora core]$ python3 character_clash.py --help
Usage: character_clash.py [OPTIONS]Options:
  --w INTEGER     Width of the draw grid.
  --h INTEGER     Height of draw grid.
  --players TEXT  The number of randomly generated players to include.
  --help          Show this message and exit.
[emmac@fedora core]$

如果玩家参数没有提供给我们,我们会提示用户。这非常简单,输出非常简洁。显然,还有很多事情要做。翻转并不完全正确,并且在某些区域的某些协调是错误的。此外,目前还没有任何人工智能暴力,但我很快会带来关于这个项目的另一篇文章,我们将完成这一部分,之后会有更多关于这个有趣的小项目的文章。现在,让我们再多谈谈点击。

为什么不是 ArgParse 或其他选项?

Click 的伟大之处在于,它为您提供了一个完整的数据模板打印输出,它会根据您的论点数据发出回声。此外,Click 包括所有不同类型的参数,甚至支持各种不同的调用。当然,我们可以用一些输入来启动 main()函数,但是将它解析为传入的 CLI 要酷得多。

不仅如此,这个项目的实际点击部分非常容易使用。这是另一个在 Python 中散布装饰魔法的模块,这是我非常喜欢的。所以,是的,我相信 Click 更容易一些,并且包含了很多非常好的组件,它允许你写密码,提示参数,提供选择,各种各样的其他选项所没有的东西。也就是说,它也是来自托盘,他们的软件可能值得一试。

结论

这是一个非常酷的项目,我很高兴看到它继续发展。这可能不是世界上最简单的选择,但它非常有趣,我认为我的方法非常棒。在做这个项目的过程中,我一直在想,如果有一个基于 REPL 的小引擎来为你处理所有的显示,那么你就可以编写具有视觉反馈等功能的真正交互式的 REPL,那该有多酷。这似乎是一个非常好的主意,我确信也许以前有人尝试过。

然而,老实说,如果我要写这样的东西,我可能会使用更多的类型,也用 Julia 来写。有时候项目抓住了我,我觉得我应该试着让它们变得很棒。非常感谢你的阅读,它对我来说意味着整个世界!希望这篇文章有助于让您的 CLI 变得生动,并且通过这个基于真实项目的示例,可能对如何在一些软件中实现这个模块有更多的理解。快乐编程,

还有(差不多)新年快乐!

如何让聚类变得可解释

原文:https://towardsdatascience.com/how-to-make-clustering-explainable-1582390476cc?source=collection_archive---------8-----------------------

在本文中,我将解释如何使用 SHAP 值来更好地理解聚类

聚类总是一个黑箱

为了更好地理解不同类型的客户,业务案例中经常需要聚类。但这可能已经足够了。从业务的角度来看,仅仅知道我们有多少个集群以及谁属于哪个集群是不够的。我们需要知道到底是什么形成了这些不同的星团。换句话说,我们想要解释聚类的结果,不幸的是,它总是一个黑箱。我发现自己总是在这种情况下,我也很清楚一个人属于哪个群体,但我不确定他在这个群体中的原因以及他与其他群体成员的不同之处。

这似乎并不明显。回到监督学习,SHAP 值提供了一个通用框架,赋予机器学习可解释性,无论是玻璃盒模型还是黑盒模型。我不打算详细解释 SHAP 值,因为它已经做得很好了,我们几乎可以在互联网上的任何地方找到参考资料,例如https://christophm.github.io/interpretable-ml-book/shap.html。但不幸的是,SHAP 值的计算要求我们的数据有标签。事实上,SHAP 值被定义为样本的每个特征如何对输出标注的预测做出贡献。没有标签,SHAP 很难实施。

为了在聚类和 SHAP 值之间架起一座桥梁,我想使用数据聚类的标签,并在此基础上构建 SHAP 值。我将通过研究一个例子来解释我的想法。详细代码请找到[笔记本](http://Hello, sorry for the late reply. I was sick last month. Here is the link for the notebook: https://colab.research.google.com/drive/1BgJuRxRrEcreVwfbfwnFjoFeHonVriKc#scrollTo=eGie9OGPI-QE)的链接。

葡萄酒数据集聚类

葡萄酒数据集

我将在这里使用葡萄酒数据集:https://www . ka ggle . com/Harry Wang/wine-dataset-for-clustering。这些数据是对意大利同一地区种植的葡萄酒进行化学分析的结果。分析确定了研究葡萄酒中发现的 13 种成分的数量。让我们先快速看一下桌子的头。

作者图片:葡萄酒数据集表的头

这里我也展示了所有特征的直方图。

按作者分类的图像:葡萄酒数据集所有特征的直方图

数据准备

在聚类算法之前,我们必须对特征进行归一化。我用了 MinMaxScaler。

import pandas as pd
from sklearn import preprocessingwine_value = wine_df.copy().values
min_max_scaler = preprocessing.MinMaxScaler()
wine_scaled = min_max_scaler.fit_transform(wine_value)
wine_df_scaled = pd.DataFrame(wine_scaled, columns=wine_df.columns)

这是缩放前后酒精和灰分值的两个散点图。

作者图片:归一化前后两个特征的散点图

聚类算法

我们现在准备在这个葡萄酒数据集上实现聚类算法。我将使用 K 均值算法。我们可以很容易地对一系列聚类运行 K-Means,并将失真收集到一个列表中。

from sklearn.cluster import KMeans
distortions = []
K = range(1,10)
for k in K:
    kmeanModel = KMeans(n_clusters=k)
    kmeanModel.fit(scaled_wine_df)
    distortions.append(kmeanModel.inertia_)

绘制不同聚类值的失真,我们很清楚 3 是最合适的聚类数。

作者图片:不同聚类值的扭曲。

用 SHAP 值解释聚类结果

现在创建了 3 个集群。K-means 模型将简单地输出一个范围从 0 到 2 的数字,表示样本属于哪个聚类。仅此而已。由于数据集有 13 个特征,即使是完整的可视化也不是很明显。为了更好地解释聚类结果,下面是我要做的事情:拟合一个分类器模型,其输出正是由聚类提供的标签,并基于该分类器模型计算 SHAP 值。

我将使用随机森林分类器。最棒的是,在拟合 RandomForest 分类器之前不需要进行归一化,因此我们可以直接使用原始数据。由于分类器的目标是更好地理解聚类,并且不存在过度拟合的问题,所以我将使用所有数据集来进行拟合。

from sklearn.ensemble import RandomForestClassifier
from sklearn.preprocessing import label_binarize
kmeanModel = KMeans(n_clusters=3)
y=kmeanModel.fit(scaled_wine_df).labels_
y = label_binarize(y, classes=[0,1,2])
clf=RandomForestClassifier()
clf.fit(wine_df,y)

现在,SHAP 终于准备好履行自己的职责了。我将让 SHAP 解释葡萄酒数据集的特性。

import shap
explainer= shap.TreeExplainer(clf)
shap_values = explainer(wine_df).values

SHAP 告诉了我们什么?

以 0 组为例。让我们看看这两个标签的概要图。

该汇总图上的每个点都是样本特征的 Shapley 值。x 轴给出了 SHAP 值,而 y 轴由按重要性排序的要素决定。

作者图片:标签 0 的 SHAP 值

我们可以看到,OD280、黄酮类化合物和色调是对定义该集群具有最积极影响的特征。我们可以想象一种葡萄酒含有相对大量的 OD280、黄酮类化合物和色素。作为一个对酒非常无知的人,这个总结图确实让我对聚类结果有了更好的理解。

在这篇文章的最后,我想说的是,聚类是一种非常好的解读无标签数据的方式。但是如何解释聚类的结果一直是个问题。借助 SHAP 值,我们可以更好地理解聚类。

如何让深度学习模型更好的泛化

原文:https://towardsdatascience.com/how-to-make-deep-learning-models-to-generalize-better-3341a2c5400c?source=collection_archive---------19-----------------------

脸书人工智能研究团队开发的新技术。

不变风险最小化(IRM)是一种令人兴奋的新学习范式,有助于预测模型在训练数据之外进行归纳。它是由脸书的研究人员开发的,并在 2020 年的一篇论文中概述。该方法可以添加到几乎任何建模框架中,但是它最适合利用大量数据的黑盒模型,即神经网络及其多种风格。

事不宜迟,我们开始吧。

0.技术 TLDR

在高层次上,IRM 是一种学习范式,试图学习因果关系,而不是相关关系。通过开发训练 环境、结构化数据样本,我们可以最大限度地提高准确性,同时还能保证预测器的不变性。既能很好地拟合我们的数据又不随环境变化的预测值被用作最终模型的输出。

图 1:4 倍 CV 的理论性能(上)与不变风险最小化(IRM)(下)。这些值是从论文中的模拟推断出来的。图片由作者提供。

步骤 1:开发您的环境集。我们没有重新排列数据并假设它们是 IID,而是利用关于数据选择过程的知识来开发采样环境。例如,对于一个解析图像中文本的模型,我们的训练环境可以按照编写文本的人来分组。

第二步:最大限度地减少跨环境的损失。在我们开发了我们的环境之后,我们拟合*似不变的预测器,并优化我们跨环境的准确性。详见第 2.1 节。

第三步:更好地概括!风险不变最小化方法比传统的学习范例表现出更高的分布外(OOD)准确性。

1.但是实际上是怎么回事呢?

让我们慢一点,理解风险不变最小化实际上是如何工作的。

1.1 预测模型的目的是什么?

从第一步开始,预测模型的目的是概括,即在看不见的数据上表现良好。我们称看不见的数据为分布外(OOD)

为了模拟新数据,引入了多种方法,如交叉验证。尽管这种方法比简单的训练集要好,但我们仍然局限于观察到的数据。那么,你能确定模型会泛化吗?

嗯,通常你不能。

对于定义明确的问题,如果您对数据生成机制有很好的理解,我们可以确信我们的数据样本是总体的代表。然而,对于大多数应用,我们缺乏这种理解。

举一个论文中引用的例子。我们正在寻找解决决定一幅图像显示的是一头牛还是一头骆驼的难题。

为此,我们使用交叉验证来训练二元分类器,并在我们的测试数据上观察到高准确度。太好了!

然而,经过进一步挖掘,我们发现我们的分类器只是使用背景的颜色来确定奶牛骆驼的标签;当一头牛被放在沙色的背景中时,模型总是认为它是一头骆驼,反之亦然。

现在,我们可以假设在牧场上可以看到牛,在沙漠中可以看到骆驼吗?

大概不会。虽然这是一个微不足道的例子,但我们可以看到这一课如何推广到更复杂和更重要的模型。

1.2 为什么目前的方法不够充分?

在深入研究解决方案之前,让我们进一步了解为什么流行的培训/测试学习范例是不充分的。

经典的训练/测试范例在本文中被称为经验风险最小化(ERM) 。在 ERM 中,我们将数据汇集到训练/测试集中,在所有功能上训练我们的模型,使用我们的测试集进行验证,并返回具有最佳测试(样本外)准确性的拟合模型。一个例子是 50/50 训练测试分割。

现在,为了理解为什么 ERM 不能很好地概括,让我们看看它的三个主要假设,然后一次解决一个。很快,它们是:

  1. 我们的数据是独立且同分布的(IID)。
  2. 随着我们收集的数据越来越多,我们的样本大小 n 与重要特征数量之间的比率应该会降低。
  3. 完美的测试精度只有在有一个具有完美训练精度的可实现(可构建)模型时才会出现。

乍一看,这三个假设似乎都成立。然而,剧透警报他们往往不会。原因如下。

看看我们的第一个假设,我们的数据几乎从来都不是真正的 IID。实际上,必须收集数据,这几乎总是引入数据点之间的关系。例如,沙漠中骆驼的所有图像必须在世界的某些地方拍摄。

现在有许多数据“非常”IID 的情况,但重要的是要批判性地思考你的数据收集是否以及如何引入偏见。

假设#1:如果我们的数据不是 IID,第一个假设是无效的,我们不能随机打乱我们的数据。重要的是要考虑你的数据生成机制是否会引入偏差。

对于我们的第二个假设,如果我们正在建模偶然关系,我们会期望在一定数量的观察之后,重要特征的数量保持相当稳定。换句话说,随着我们收集更多高质量的数据,我们将能够获得真正的因果关系,并最终将它们完美地映射出来,因此更多的数据不会提高我们的准确性。

然而,在机构风险管理中,这种情况很少发生。由于我们无法确定一种关系是否是因果关系,更多的数据往往会导致更多虚假的相关性被拟合。这种现象被称为偏差-方差权衡

假设#2:当符合 ERM 时,随着样本量的增加,重要特征的数量可能会增加,从而使我们的第二个假设无效。

最后,我们的第三个假设简单地说,我们有能力建立一个“完美”的模型。如果我们缺乏数据或健壮的建模技术,这种假设就会失效。然而,除非我们知道这是错误的,否则我们总是假设它是正确的。

假设#3:我们假设最优模型对于足够大的数据集是可实现的,所以假设#3 成立。

现在本文讨论了一些非 ERM 方法,但由于种种原因,这些方法还存在不足。你明白了。

2.解决方案:不变风险最小化

提出的解决方案,称为不变风险最小化(IRM),克服了上面列出的所有问题。IRM 是一种学习范式,从多种训练环境中估计因果预测因子。而且,因为我们从不同的数据环境中学习,我们更有可能归纳出新的 OOD 数据。

我们如何做到这一点?我们利用因果关系依赖于不变性的概念。

回到我们的例子,假设奶牛和骆驼 95%的时间都出现在它们各自的草地和沙地栖息地,那么如果我们适应背景的颜色,我们将达到 95%的准确率。从表面上看,这是非常合适的。

然而,借用一个来自随机对照试验的核心概念,叫做反事实,如果我们看到一个假设的反例,我们已经证明它是错误的。因此,如果我们在多沙的环境中看到甚至一头牛,我们可以得出结论,多沙的背景不会导致骆驼。

虽然严格的反事实有点苛刻,但我们通过严厉惩罚我们的模型在给定环境中预测失误的情况,将这一概念构建到我们的损失函数中。

例如,考虑一组环境,每个环境对应一个国家。假设在 9/10 的环境中,奶牛生活在牧场,骆驼生活在沙漠,但在第 10 个环境中,这种模式发生了逆转。当我们在第 10 个环境上训练并观察许多反例时,模型了解到背景不能导致标签奶牛骆驼,因此它降低了该预测器的重要性。

2.1 方法

既然已经用英语理解了 IRM,让我们进入数学的世界,这样我们就能理解如何实现它。

图 2:最小化表达式— 来源

图 2 显示了我们的优化表达式。如总结所示,我们希望在所有培训环境中最大限度地降低总价值。

进一步分解,“a”项表示我们在给定训练环境下的预测准确性,其中 phi (𝛷)表示数据转换,如 log 或向更高维度的核转换。 R 表示给定环境下我们模型的风险函数 e 。请注意,风险函数只是损失函数的*均值。一个经典的例子是均方误差(MSE)。

“B”项只是一个正数,用来衡量我们的不变性项。还记得我们说过严格的反事实可能过于苛刻吗?这是我们可以衡量我们想要多苛刻的地方。如果 lambda ( λ )为 0,我们不关心不变性,单纯优化精度。如果 λ 很大,我们很在意不变性,相应地进行惩罚。

最后,“C”和“D”项表示我们的模型在训练环境中的不变性。我们不需要太深究项,简单来说,我们的“C”项是我们的线性分类器 w 的一个梯度向量,默认值为 1。“d”是线性分类器的风险乘以我们的数据转换(𝛷).整项是梯度向量距离的*方。

论文对这些术语进行了大量的详细描述,所以如果你有兴趣的话,可以看看第三部分。

综上所述,“A”是我们的模型精度,“B”是衡量我们有多在乎不变性的正数,“C”/“D”是我们模型的不变性。如果我们最小化这个表达式,我们应该找到一个模型,只适合在我们的训练环境中发现的因果效应。

2.2 IRM 的下一步措施

不幸的是,这里概述的 IRM 范式只适用于线性情况。将我们的数据转换到高维空间可以产生有效的线性模型,然而,一些关系从根本上来说是非线性的。作者把非线性的情况留给未来的工作。

如果你想跟踪研究,可以看看作者的作品:马丁·阿约夫斯基莱昂·布图伊桑·古尔拉贾尼戴维·洛佩斯-帕兹

这就是我们的方法。不算太坏,对吧?

3.实施说明

  • 这里有一个 PyTorch 包
  • IRM 最适合于未知的因果关系。如果有已知的关系,您应该在模型的结构中说明它们。一个著名的例子是卷积神经网络(CNN)的卷积。
  • IRM 在无监督模型和强化学习方面有很大潜力。模型公*也是一个有趣的应用。
  • 优化相当复杂,因为有两个最小化项。本文概述了一种使优化凸的变换,但仅在线性情况下。
  • IRM 对轻度模型错误设定是稳健的,因为它关于训练环境的协方差是可微的。因此,虽然“完美”模型是理想的,但最小化表达式对小的人为错误是有弹性的。

感谢阅读!我将再写 47 篇文章,将“学术”研究引入 DS 行业。查看我对 IRM 方法的链接/想法的评论。

如何在 Python 中少犯“错误”

原文:https://towardsdatascience.com/how-to-make-fewer-mistakes-in-python-6925619ce87e?source=collection_archive---------9-----------------------

stevepbPixabay 拍摄的照片

当可以使用枚举时,不要使用 Python 字符串

每种编程语言都必须使用字符串类型。当我们在程序中输入字符串时,错别字通常是不可避免的。如何才能消除编程时可能犯的这种错误?

枚举常用于大多数流行的编程语言中。当然,Python 也提供了灵活的枚举类。使用枚举是一种非常好的编程方式。它帮助我们将一组符号名与唯一的常量绑定在一起。因此,我们可以很容易地使用它来避免一些由错别字引起的运行时错误。

典型的定义

照片由 stevepbPixabay 上拍摄

现在让我们考虑一个极其简单的用例。我们有一本如下的字典。

user = {
    'name': 'Chris',
    'age': 33,
    'programming_language': 'Python'
}

然后,我们想测试用户是否喜欢 Python,并根据结果打印一些输出。

if user['programming_language'] == 'Python':
    print(f"{user['name']} can use Python!")
else:
    print(f"Python is not {user['name']}'s favourite programming language.")

好的。没问题。我觉得很简单,不需要解释代码:)现在,假设我们打了一个如下的错别字。这可能会导致难以定位的运行时错误。

这个 bug 会产生一个结果——没人喜欢 Python。我们知道那不是真的,当然,那是个错误:)

使用枚举的基本解决方案

照片由 stevepbPixabay 上拍摄

每个人都会犯错。如何使用枚举来避免这种错误?让我们从定义一个枚举开始。只需导入Enum类并定义枚举的成员。

from enum import Enumclass ProgrammingLanguage(Enum):
    PYTHON = 1
    JAVA = 2
    C = 3
    JAVASCRIPT = 4
    PHP = 5

然后,我们有一个特定成员的枚举。我们可以把它放在字典里如下。

user = {
    'name': 'Chris',
    'age': 33,
    'programming_language': ProgrammingLanguage.PYTHON
}

如果我们想要*等的测试,它可以是这样的。

if user['programming_language'] == ProgrammingLanguage.PYTHON:
    print(f"{user['name']} can use Python!")
else:
    print(f"Python is not {user['name']}'s favourite programming language.")

那么,使用枚举比较和普通字符串有什么区别呢?为什么它可以防止错别字运行时的错误?首先,枚举中定义的成员被视为类属性。换句话说,大多数 IDE 工具将提供自动完成功能。因此,我们出现打印错误的可能性就更小了。

最重要的是,如果我们犯了一个错误,Python 解释器会抛出一个错误。

因此,如果有错别字,代码将无法编译。运行时之前暴露的问题通常不是实际问题,而是编程的一部分:)

访问枚举的成员

图片由 Pixabay 上的 JESHOOTS-com 拍摄

好吧,如果你已经决定在必要的时候使用枚举,我猜你可能想了解更多。很高兴在本文中扩展这个主题。让我们首先讨论如何访问一个枚举的成员。

如果我们只是简单的打印成员,那么会打印原始的Class.Attribute,并不能提供太多的信息。

然而,如果我们使用repr()函数,它也会打印成员的值。

如果我们想得到成员的整数值,只需访问它的value属性。对于成员的键,我们可以使用name属性来访问它。

需要访问成员键的用例示例

访问成员键的用法提示是,我们可以从枚举成员中获取一个字符串以供进一步使用。例如,如果用户字典是从 JSON 文档中转储出来的呢?换句话说,“编程语言”的值必须是一个字符串。

user = {
    'name': 'Chris',
    'age': 33,
    'programming_language': 'Python'
}

因此,我们可以将字符串“Python”转换为大写,然后将其与枚举成员的键进行比较。

if user['programming_language'].upper() == ProgrammingLanguage.PYTHON.name:

你可能会问为什么成员键必须全部使用大写字母。简而言之,你不必这么做。但是,当我们定义一个“常量”时,建议使用全大写。枚举中的所有成员都被视为常数。遵循 PEP 标准是一种好的方式。

与数据结构集成

照片由照片 1图片栏上拍摄

你可能会意识到枚举是非常结构化和受限的。因此,它肯定可以集成不同类型的数据结构。这里我将展示 Python 列表和字典的两个例子。

将枚举转换为列表

我们可以使用 for 循环来迭代枚举。

for lang in ProgrammingLanguage:
    print(lang)

因此,我们可以很容易地使用列表理解将其转换为列表。

[lang.name for lang in ProgrammingLanguage]

事实上,还有另一种方法。这并不简单,但有助于理解枚举的结构。也就是说,我们可以使用一个神奇的属性来获取成员的所有细节。

ProgrammingLanguage.__members__

类型mappingproxy本质上是一个只读字典。因此,我们可以简单地通过调用它的keys()函数来获得键的列表。

list(ProgrammingLanguage.__members__.keys())

可用作字典关键字

枚举成员是可散列的,这意味着我们可以将它们用作有效的字典键。

popular_use_cases = {}
popular_use_cases[ProgrammingLanguage.PYTHON] = 'Data Science'
popular_use_cases[ProgrammingLanguage.JAVA] = 'Software Development'
popular_use_cases[ProgrammingLanguage.JAVASCRIPT] = 'Web Development'

这将是非常有用的,因为它也可以防止我们对字典键的错别字!当我们想从字典中的键获取值时,我们也将使用枚举成员。

popular_use_cases[ProgrammingLanguage.PYTHON]

用字符串值枚举

StockSnapPixabay 上拍摄的照片

到目前为止,上面所有的例子都使用整数作为枚举的值。事实上,我们可以使用字符串作为值。它在使用过程中提供了更多的灵活性。要获得基于字符串的枚举,只需用字符串定义成员。

class ProgrammingLanguage(Enum):
    PYTHON = 'Python'
    JAVA = 'Java'
    C = 'C'
    JAVASCRIPT = 'JavaScript'
    PHP = 'PHP'

因此,我们总是可以使用value属性来访问成员的字符串值。

print(ProgrammingLanguage.PYTHON.value)

请注意,我们仍然不能使用枚举成员来比较字符串,因为类型是不同的。结果永远是假的。

相反,我们需要使用成员的值。

定义枚举的最简单方法

照片由pix abay上的灵感来源

最后,定义枚举的最“Pythonic 化”的方法可能要容易得多。我们甚至不需要写一个枚举类。Enum类有一个构造函数,它可以接受两个参数并生成一个枚举。

ProgrammingLanguage = Enum('ProgrammingLanguage', 'PYTHON, JAVA, C, JAVASCRIPT, PHP')

在上面的代码行中,第一个参数定义了枚举类的名称。然后,第二个参数是一个字符串,包含所有由逗号、空格或两者分隔的成员键。

在这里,我们没有为每个成员显式分配一个整数,该成员将被自动分配一个从 1 开始自动递增的整数。

之后,我们得到了一个枚举,这与显式地编写一个类是一样的。

摘要

27707Pixabay 上拍摄的照片

在本文中,我介绍了 Python 中的 enumeration 类。我们可以用它将符号名绑定到唯一的常量值。通过这样做,我们可以利用大多数 ide 中都有的自动完成特性,并防止由输入错误引起的运行时错误。

Python 枚举还提供了其他一些有趣的特性,比如用作字典键。除此之外,我们可以使用“Enum”类构造函数轻松定义枚举,而无需显式编写类,多么“Pythonic 化”啊!

https://medium.com/@qiuyujx/membership

如果你觉得我的文章有帮助,请考虑加入 Medium 会员来支持我和成千上万的其他作者!(点击上面的链接)

如何制作虚构的数据

原文:https://towardsdatascience.com/how-to-make-fictional-data-7a79ce86a350?source=collection_archive---------25-----------------------

当您需要数据用于测试、培训、演示或其他目的时。自己做!

大约每周我都会收到(或在网上看到)一位数据科学家同事或有抱负的数据科学家提出的一个问题。我在哪里可以得到一个数据集来玩?或者,我正在寻找一个有趣的数据集来学习,有什么建议吗?

有大量有趣的数据被公布出来。但是为什么不自己做数据呢?当您需要数据进行测试或演示时,制作自己的虚构数据也是一项有用的技能。本文将向您展示如何生成虚构的数据(这是许多方法中的一种)。

在本文的底部是额外的资源,包括一个支持 GitHub 库的链接,还有一个 YouTube 视频也说明了这个主题。

设置

在图 1 中,我展示了两种鸟类的信息。有“西方”和“东方”之分。

图 1:提供了与鸟类品种相关的概述信息。有“西方”品种,也有“东方”品种。西方的鸟更轻更小。它们有黑色或黄色的羽毛。东方品种有时有白色特征。图片鸣谢:亚当·罗斯·尼尔森(作者)。

西方的鸟品种比东方的品种小。东方品种有时有白色羽毛。图 1 中的摘要信息是虚构的。下面的代码生成的虚构数据*似于图 1 所示的汇总统计数据。

代码

首先,有标准进口。

**import** **pandas** **as** **pd**
**import** **numpy** **as** **np
from** **random** **import** random
**import** **seaborn** **as** **sns**

西方品种数据

首先,我们将为西方品种制作数据。我们计划对每个品种进行 1000 次观察。

该代码将假设鸟类分散在它们的地理范围内。此代码还假设范围是矩形的。这是虚构的,我们可以随心所欲地决定。为了保持代码简单,这些是我们正在工作的假设。

*# Western variety Latitude & Longitude.* 
west_lat = np.random.uniform(81, 91, 1000) 
west_long = np.random.uniform(35, 42, 1000)

下一个代码块将为鸟的重量生成虚构的数据。我们将从均匀分布开始,然后通过添加以零为中心的正态分布来修改该分布。这种方法实现了与上面图 1 中指定的虚构场景相匹配的分布。

*# Specify weight.* 
west_weight = np.random.uniform(9, 19, 1000) 
west_weight = np.random.normal(0, 1.25, 1000) + west_weight

既然我们有了鸟的重量,我们就可以生成翼展数据。我们预计翼展与重量有关。随着重量的增加,翼展也随之增加。为了使数据更有趣,我们将随着重量增加翼展,但速度是递减的。下面的方程将*似重量和翼展之间的关系。

wing_span = 5.9 + 1.8 * weight + -.4 * weight * weight

下面的代码产生与上面给出的方程一致的翼展数据。通过使用以 5.9 为中心的随机正态分布,截距的标准偏差为 1,代码*似于自然的随机变化。

*# Specify wing-span.*
west_wing = np.random.normal(5.979, 1, 1000) + 1.871 * \
            west_weight + -.0396 * west_weight**2

生成的最后一个变量将是羽毛颜色。西方品种的新娘不是黑色就是黄色。第一步是生成一个由随机的 0 和 1 组成的熊猫系列。第二步是将 0 映射到黑色,将 1 映射到黄色。第三步是将数据指定为分类数据。

*# Specify the feather colors.* 
west_color = pd.Series(np.random.randint(0, 2, 1000))
west_color = west_color.map({0:'Black', 1:'Yellow'})
west_color = west_color.astype('category')

通过链接适用的方法,可以在一行代码中制作羽毛数据。然而,为了限制行宽并使代码更易于阅读,我用三行代码演示了代码。

复活节品种数据

为东方品种生成数据的代码与为西方品种生成数据的代码几乎相同。随机数生成器、翼展与重量的关系以及羽毛颜色贴图都有所不同。我在下面的 YouTube 视频中详细解释了这些差异。

*# Eastern variety Latitude & Longitude.*
east_lat = np.random.uniform(77, 89, 1000)
east_long = np.random.uniform(34, 39, 1000)*# Specify weight.*
east_weight = np.random.uniform(10.5, 24.5, 1000)
east_weight = np.random.normal(0, .66, 1000) + east_weight*# Specify wing-span.*
east_wing = np.random.normal(24.16, .75, 1000) + -.137 * \
            east_weight + .0119 * east_weight**2*# Specify the feather colors.* 
east_color = pd.Series(np.random.randint(0, 3, 1000))
east_color = east_color.map({0:'Black', 1:'Yellow', 2:'White'})
east_color = east_color.astype('category')

最后的结果

图二。虚构的鸟类数据。图片鸣谢:亚当·罗斯·尼尔森(作者)。

最终结果是一个数据帧,如图 2 所示。共有六列,包括lat(纬度)long(经度)weight(磅重)wing(翼展英寸)color(鸟羽颜色)variety(西方或东方)。

下图 3 显示的是一个配对图,说明了这些数据之间的关系。

图 3。图片鸣谢:亚当·罗斯·尼尔森(作者)。

https://adamrossnelson.medium.com/membership

结论

下次您需要数据集进行测试、培训或演示时,可以考虑生成自己的数据。使用本文中的技术来生成您自己的。当您开始生成虚构的数据时,我建议您提前绘制一份数据概要,如图 1 所示。

如果你想了解更多这方面的信息,我准备了一个 GitHub 库,我还准备了一个 YouTube 视频(如下所示)。一个伴随视频使用这个虚构的数据来显示 K 最*邻分类

视频鸣谢:亚当·罗斯·纳尔逊(作者)。

这是生成虚构数据的唯一方法吗?没有。还有其他选择吗?当然,是的。本文提供了一个起点。如果你使用这些技术来生成虚构的数据,请在评论中发布一个链接。

如果您有其他生成虚构数据的方法,请在评论中发布代码的链接。你可能还会发现另外三种方法让虚构的数据成为有用的读物。

感谢阅读

感谢阅读。把你的想法和主意发给我。你可以写信只是为了说声嗨。如果你真的需要告诉我是怎么错的,我期待着尽快和你聊天。Twitter:@ adamrossnelsonLinkedIn:Adam Ross Nelson 在 Twitter 和脸书: Adam Ross Nelson 在脸书

如何用 Plotly 制作多指标索引图

原文:https://towardsdatascience.com/how-to-make-multi-index-index-charts-with-plotly-4d3984cd7b09?source=collection_archive---------5-----------------------

包含更多见解的索引图表

在处理时间序列数据时,原始数据通常不能提供多少信息。如果你有多个大小不同的变量,较小值的变化很难看到。这个问题有一个简单的解决方案:使用索引数据的索引图表。

虽然常规索引图表工作良好,但通过使用简单的索引扩展,您可以显著改善您的视觉呈现,并帮助您的图表传达数据中的因果关系。这个扩展就是我所说的“多索引”——使用多个索引而不是一个。这让你可以从不同的角度分析数据。当您怀疑在特定时间点发生的事件对相关变量的增长有重大影响时,这种方法尤其有用。

对股票市场价格有重大影响的事件(图片由作者提供)

举个例子,如果你要比较一些股票从 1980 年到今天的股价,你会发现 1987 年的黑色星期一、2000 年的网络泡沫和 2008 年的股市崩盘都是对市场产生重大影响的事件,看起来很有趣。因此,你可以将它们添加到指数列表中,参考每个日期的数据,并比较价格相对于每个参考点的发展情况。以这种方式看价格会让你对每个事件的规模有一个更好的直觉,而不仅仅是一个单一的指数日期。

在本文中,我将向您介绍如何使用 Python Plotly 数据可视化库在时间序列图中实现多重索引。我将用完整的代码介绍三种方法,并详细解释它们,包括每种方法的优缺点以及何时使用哪种方法。为了跟上这篇文章,您应该熟悉 Python 和 Pandas,最好对 Plotly 有所了解。

如果您只关心我将要谈到的三个图表中的一个,请随意跳过其他的——这篇文章是以模块化的方式编写的,因此您不会错过任何东西。但是,请务必通读第 1 部分(设置和准备),因为它包含将在每个图表中使用的重要概念和功能定义。

你可以在这里找到这篇文章的全部内容。 ]

如果你喜欢这篇文章,请 关注我上媒

文章索引

  1. 设置和准备
  2. 有固定参考日期的指数图

作者图片

3.动态指数图

作者图片

4.JupyterLab 中可变指数的指数图

作者图片

1.设置和准备

1.1 获取和清理数据

如前所述,数据准备工作将由熊猫完成。大多数绘图将由 Plotly graph_objects模块处理。另外,对于一个绘图,我们将使用ipywidgets库,它提供了用于与 Jupyter Notebook 和 JupyterLab 中的绘图进行交互的小部件。对于时间序列数据,我们将使用 Yahoo!金融 API。有一个很棒的叫做[yfinance](https://pypi.org/project/yfinance/)的 Python 库,我们将用它来与 API 接口。

我们的目标是建立指数图表,使用户能够第一眼就比较选定股票相对于选定日期的发展。所以,我们挑几只股票来对比一下。我们将重点介绍脸书(Berkshire Hathaway)、亚马逊(Amazon)、杜邦(DowDupont)以及伯克希尔哈撒韦公司(Berkshire Hathaway)的 A 类股(BRK-A ),这是一只股票有史以来价格最高的股票。我有目的地从一个很宽的价格区间选择股票,以证明指数化的有效性。

作者图片

yf.download()的调用以给定的时间间隔下载给定时间段的数据,在我们的例子中是从今天开始,追溯到 3 年前,每周一次。结果存储在一个多索引的 Pandas 数据框架中。

设置group_by='column'指定数据将如何分组,是按价格类型(列)还是按报价机(报价机)。这转化为价格类型或报价器是否会成为我们数据框架的顶级索引。

该表包含五种不同的价格。简单来说,我们只看调整后的收盘价,其他的都不看。我们也将删除空值。

df = df.filter(regex="Adj Close")
df = df.dropna()
df.head(5)

作者图片

1.2 索引:为什么和如何

现在我们的数据已经准备好了,让我们先看一下这些值。

df.plot()

作者图片

绘制原始价值对比较股票帮助不大。由于 BRKa 股的价格高得多,其他股票的变化几乎看不见。也许对数标度数据会缓解这个问题?

df.plot(logy=True)

作者图片

即使在对数尺度上,数值差异也太大,我们无法对股票进行有意义的比较。很明显,我们需要索引。

指数化很简单:选择一个日期 D 作为指数,用每个日期的价格除以日期 D 的价值。现在,所有结果值都表示为它们与 D 处的值 V 的比值,并且可以很容易地相互比较。在我们的例子中,我们需要区分不同的股票,所以对于每只股票,我们将所有的值除以相应股票在日期 D 的值。我们可以很容易地在 Pandas 中做到这一点,因为我们有一个多索引的数据框架。对特定指数调用iloc会返回一个 Pandas 系列,其中包含该特定指数的所有股票的值。当我们用序列划分数据帧时,Pandas 用序列中相应的元素划分每一列。

我们还会添加一些化妆品。将新值乘以 100 将得到百分比值,使用起来更舒服。第二个可选的修饰是从结果中减去 100。这有效地将 100%设置为 0%,并将比率更改为相对差值。例如,下降到原始值的 30%现在将被解释为original value — 70 %。我个人认为这种解释更容易理解。

注意,我将索引日期称为参考日期,索引值称为参考值。这样做是为了避免与 dataframe 索引混淆。

# use the first date as index 
reference_value = df.iloc[0]# dividing by the series divides each column by the 
# corresponding element in the series
tmp_df = df.div(reference_value) * 100 - 100tmp_df.plot()prepared_df = df.copy()

作者图片

这个看起来好多了。股票价格趋势是立即可见和可比的。

我们将更多地使用索引,所以让我们为这项技术写一个通用函数create_indexed_columns()。该函数将采用以下参数:

  1. date -索引的参考日期
  2. df -要处理的数据框架
  3. top_level_name -(可选)规范化数据帧的顶层索引的名称

并返回具有规格化数据和新的顶层索引的新的数据帧。

一个重要的考虑是如何处理不在数据帧中的输入日期。幸运的是,dataframe indices 有一个非常有用的方法get_loc(),可以找到给定索引的整数索引。当我们将参数method=nearest传递给该方法时,Pandas 将搜索与所提供的输入最接*的索引。因为我们的索引是类型datetime,所以将匹配最接*所提供日期的日期。

在我们进入第一个 Plotly 指数图表之前,让我们回顾一下“多指数”图表的概念。正如我们所见,将数据索引到一个时间点非常有效。然而,查看多个参考点通常是有用的。这些可能是时间序列中对我们的数据有重大影响的特定事件。从多个点查看数据使用户能够容易地看到相关变量相对于不同的参考点是如何增长的。实现这一点的最佳方式是将该功能直接嵌入图表中。

1.3 非常短的 Plotly Crashcourse

这个快速介绍只是简单地触及了 Plotly 的基本概念。如果你以前和 Plotly 一起工作过,跳过它。

在一个图中有多个索引意味着它们需要动态切换,因此我们的图必须是交互式的。Plotly 是开箱即用的交互式,扩展交互性相对简单,这就是 Plotly 是首选库的原因。

在 Plotly 中,每个图形都是一个类似 JSON 的数据结构,有三个主要属性(称为属性):数据、布局和框架。前两个是不言自明的,而帧属性包含动画中使用的可选帧。您可以先使用 JSON 或 Python 字典编写整个人物结构,然后实例化人物对象,或者先创建人物对象,然后逐步更新人物属性。

作为热身,让我们重新创建默认的 matplotlib 图表,该图表是通过调用 Plotly 中的df.plot()生成的。

在上面的例子中,我们实例化了 Figure 对象,然后一个接一个地向该对象添加单独的轨迹。我们可以用更新属性的字典调用update_layout()来改变图形的布局。

对 Plotly 图形的所有更改都是这样完成的,将属性字典传递给图形。Plotly 支持“神奇的下划线符号”,这意味着我们不需要逐步深入对象来访问内部属性,而是能够直接访问内部属性。例如,我们可以简单地编写fig.update_layout(yaxis_type='log'),而不是访问yaxis属性的type属性——在许多情况下,这是一种可读性更好的方法。

既然我们都准备好了,我们可以开始我们的第一个图表了。

2.具有固定参考日期的索引图表

在这张图表中,我们将使用预先选定的股市衰退前后的日期,以及对我们正在分析的公司有影响的日期。下面列出的日期可能不完全准确,但它们大致在所列事件的时间范围内。

ref_dict = {
    "Cambridge Analytica scandal": "2018-03-28",
    "DowDuPont separation":        "2019-04-15",
    "Corona stock market drop":    "2020-02-14"
}

我们将根据每个日期对数据进行索引,并在图表中包含所有不同的索引数据。不同索引数据之间的切换将通过使用一个下拉菜单来完成,每个参考日期都有一个项目。Plotly 将此称为“按钮”。点击一个按钮将只显示由各自的参考日期索引的数据。为了实现这一点,我们需要将我们想要显示的轨迹的可见性切换到 on,并且对于剩余的轨迹将其关闭。

首先,让我们计算每个参考日期的值,并用结果数据填充我们的数据框架。我们将为每个参考日期创建一个新的数据框架,然后将它们合并成一个数据框架。我们还将存储最接*给定参考日期的日期,以防我们没有该参考日期的值。

现在我们的表已经转换,我们可以构建我们的 Plotly 对象。我们将创建一个新的图形,并为每个新计算的列添加一个跟踪。我们将为每个跟踪提供一个额外的meta属性。meta属性可以存储任意的 JSON 数据,有很多应用。我们将使用它来存储一个跟踪所属的参考日期。这将允许我们识别将同时切换到可见/不可见的一组轨迹。

那可是好多痕迹啊!我们只想显示属于一个参考日期的那些。就像以前一样,我们不会为我们的精确数据硬编码按钮。最好将我们的程序一般化,这样我们就能够处理一组不同的参考日期和代号。

要显示或隐藏痕迹,我们需要设置图形的visibility属性。因为这是图形的一个属性,而不是单个轨迹,所以默认情况下,对此属性的更改适用于所有轨迹。在内部,可见性表示为一个布尔值数组,其中特定索引处的值表示具有相同索引的跟踪的可见性。轨迹索引是轨迹在该阵列中的位置,并且因为轨迹是一个接一个地添加的,所以轨迹索引表示轨迹被添加到图中的顺序。

visibility 数组允许我们通过传递特定跟踪的索引或传递一个布尔值数组来定位单个跟踪,其中每个索引处的值指示是否将显示相应的跟踪。例如,对于 4 条轨迹,通过数组[True, False, True, False]将只显示第一条和第三条轨迹。

可以想象,依靠添加轨迹的顺序来创建永久按钮是一种脆弱的方法。如果您以不同的顺序添加跟踪或添加更多的跟踪,则必须手动检查和更新对可见性数组的每次提及。这就是为什么我们添加了meta属性——这样,我们就不需要依赖于轨迹的顺序来确定打开/关闭哪些轨迹。

一个简单的函数create_visibility_array将通过比较每个跟踪的元值和传入的值来创建可见性数组。

最后,我们将编写一个生成按钮的函数。

让我们澄清一下按钮描述。method指定按钮点击时调用的 Plotly 方法。restyle更新数据和绘图布局。args参数接受一个图表属性列表,该列表将通过单击按钮来更新,在我们的例子中是 visibility 属性。

最后,我们将按钮添加到图形中,并检查结果。

太好了,按钮正常工作。唯一的问题是很难看到实际的参考日期。我们可以通过在每个参考日期的 x 坐标上添加一条垂直线来解决这个问题。自然,我们需要能够用现有的按钮来切换这些参考线的可见性。

在 Plotly 中有两种方法可以做到这一点:标准方法是在图形中添加一个shape对象。在我们的例子中,我们只需通过调用figure.add_shape()并指定 x 和 y 坐标来添加一个线条形状。虽然这种方法看起来很简单,但是对于我们的情况来说有一些特殊的困难。因为形状不是轨迹,我们不能用现有的方法改变它们的可见性。相反,必须设置单个 shape 对象的 visibility 属性,这样做有些晦涩难懂(这个堆栈溢出问题说明了过程)。此外,似乎没有类似于 trace visibility 数组的简洁方法来一次改变多个形状的可见性。

添加参考线的第二种方法是添加将被绘制为垂直线的轨迹。为此,必须选择两个 y 坐标来设置线的边界。然而,我们需要确保该线在高度方向覆盖整个绘图,除此之外,参考线不得影响绘图的比例——这意味着我们不能简单地选择数据帧中最小值和最大值之下或之上的某个值作为边界,因为这会扭曲其余值的比例。解决方案是在绘图中添加一个不可见的辅助 y 轴,该轴独立于数据框中的值,并相对于自身缩放参考线。

虽然第二个 y 轴在一定程度上增加了图形的复杂性,但使用走线作为参考线有一个显著的好处:我们可以像处理所有其他走线一样切换参考线的可见性。因此,我们只需要添加参考线跟踪,并将其元参数设置为它所引用的参考日期。

如您所见,第二种方法更适合我们的情况,这就是我们为什么要使用它的原因。在添加参考线之前,让我们先将辅助 y 轴添加到绘图中。当我们这样做的时候,我们也可以给情节添加一些简单的样式。

属性指定了 hoverlabels 将如何在我们的绘图中显示。将此值设置为“x”将显示鼠标悬停在 x 值处的每个轨迹的值。我们将辅助 y 轴设置为固定范围。这样,该线将始终贯穿整个地块的高度。将overlaying属性设置为‘y’非常重要,因为这将迫使相对于第二 y 轴定义的轨迹表现得好像它们是在第一 y 轴上定义的一样——具体来说,该属性和fixedrange的组合正是允许我们看到参考线,同时使它们的比例独立于 y 轴。

现在图形已经准备好了,我们可以编写一个create_reference_line()函数来为我们生成参考线。需要注意的一点是,当我们为 y 坐标对称地指定两个值时,我们也需要提供一个包含两个 x 值的列表。

对我们之前的散点追踪定义的唯一补充是:

  • mode="lines" -指定仅将轨迹绘制为直线,而不标记其间的点
  • yaxis="y2" -指定将辅助 y 轴用作 y 轴
  • line -决定线条的样式

最后,最后一步包括将参考线轨迹添加到绘图中,并重新生成可见性按钮。搞定了。

3.动态索引图表

我们要看的第二个图表是一个动态指数图表。该图表允许用户在参考日期之间快速移动,创建一个视觉上吸引人的图表。

因为我们只使用 Plotly 图形库,所以这里最好的方法是为每个参考日期创建一个框架,然后使用 Plotly 滑块在它们之间移动。通过使用滑块,我们还可以为参考日期之间的过渡添加动画效果,这将使过渡更加*滑。

首先,我们需要将数据索引到每个日期,并为其创建跟踪。结果数据将被存储在一个框架中,这个框架只是一个带有识别名称的figure['data']字典。我们将使用create_indexed_columnscreate_reference_line函数创建轨迹,就像前面的例子一样。框架将由框架中的数据被索引到的日期来标识。函数create_traces_for_date将捆绑这个功能。

接下来,我们将创建一个滑块字典来定义我们的滑块。我们使用的一些重要属性是:

  • yanchorxanchor -指定滑块的位置
  • pad -滑块的填充
  • currentvalue -描述如何显示滑块的当前值,包括位置、字体大小和前缀。
  • len -描述滑块相对于图表的长度。1 表示与长度完全匹配,这就是我们想要的。
  • steps -是滑块将循环通过的步骤列表。我们会先将它留空,稍后再添加。

接下来要做的是创建步骤,我们将添加到我们的滑块。一个步骤由属性labelmethodargs描述。method指定当滑块值改变时将调用哪个 Plotly 函数。通过使用animate,我们将获得帧间的*滑过渡。args属性描述了将被传递到method中指定的 Plotly 函数的数据,包括一个帧列表和一个指定如何在它们之间转换的字典。实际上,您可以为每个滑块步骤指定多个帧,当滑块移动到该步骤时,这些帧将全部循环。在我们的例子中,我们只需要一个帧,并用它的名字来标识它。之后,我们描述转换属性:

  • frame - duration指定画面将显示的总时间,redraw图表是否应该在每一步之后重新绘制。
  • mode -指定对animate函数的新调用如何与当前动画交互。设置为“下一个”意味着当前运行帧将在切换到下一帧之前结束。
  • transition -指定总帧持续时间过渡部分的持续时间和使用的缓动功能

这里有一些重要的细节需要注意。首先,在我们的例子中,设置redraw=False提供了显著的性能优势,因为我们有数百个帧,每个帧有数百个点。如果没有这个设置,图表更新会明显滞后,您很快就会看到这一点。然而,禁用redraw也有一些缺点:例如,如果redraw被禁用,允许您设置视图范围的 rangeslider 将不会更新。另一个重要的缺点是 y 轴的范围不会自动更新,这有时可能不会显示图表上的所有点。在本文的第三部分,我们将看到如何结合两种实现的优点,即快速更新和图表重绘,代价是一些动态性和需要一个 Jupyter 笔记本。还有一种方法可以在不影响性能的情况下实现这一切(对于合理数量的数据点),但是这种解决方案需要 Dash 服务器,这超出了本文的范围。

另一件要记住的事情是,过渡持续时间是帧持续时间的一部分,因此将其设置为大于帧持续时间不会改变总持续时间。

此外,Plotly 将在滑块步长期间动画显示多个帧之间的过渡,以及两个相邻滑块步长的帧之间的过渡。

现在,所有的功能都设置好了,我们可以实际创建框架和步骤,并填充我们的图形。对于每个日期,我们将创建一个框架,其中包含索引到该日期的跟踪和该框架的滑块步骤。注意,我们将一个帧的名称设置为它所代表的日期的 iso 格式字符串,并立即将该字符串传递给我们的create_slider_step函数。这样做是因为滑块使用框架名称来确定要显示哪个框架。

最后,我们塑造我们的形象。我们简单地使用第一帧作为我们图形的data属性。我们使用style_plot功能配置辅助 y 轴,就完成了!

我已经警告过你要启用redraw,但是让我们实际看看它的运行情况。我们将创建与之前完全相同的索引图表,但是这次将redraw设置为 true。

如你所见,图表明显比以前慢了。就我个人而言,我觉得这种滞后是勉强可以接受的;然而,这是一个极限:如果你将数据点的数量增加到 5000 个以上,图表将会变得很慢,任何人都不会喜欢使用它。为了保持可接受的速度,您需要将数据点的数量保持在这个数字以下。

4.JupyterLab 中可变索引的索引图

第三个图表将允许用户选择自定义参考日期。如果您计划在 JupyterLab 中展示您的工作,不需要像动态索引图表中那样的花哨动画,但仍然希望用户能够选择任何日期作为参考日期,此图表正适合您。请注意,此图表仅适用于 JupyterLab,不适用于 Jupyter 笔记本!图表将通过使用小部件的ipywidgets库来实现。根据官方文件,微件是

在浏览器中具有表示形式的多事件 Python 对象,通常作为控制器,如滑块、文本框等。[..]你可以使用小部件为你的笔记本建立交互式图形用户界面。您还可以使用小部件在 Python 和 JavaScript 之间同步有状态和无状态信息。

( Source )这个想法是使用小部件通过 GUI 为我们的图表提供输入,并更新图表。这样,在选择了不同的参考日期后,图表数据将通过 Jupyter 回调而不是 Plotly 事件进行更新。

我们将使用两个不同的小部件构建两个版本的图表。一个是 DatePicker 小部件,另一个是 SelectionSlider 小部件。第二个版本将是第 2 部分中动态索引图的健壮实现。

首先,我们复制我们的初始数据帧并导入额外的库。Ipython.display用于渲染浏览器中的小部件。

from IPython.display import display
from ipywidgets import widgets as wgdfs = df.copy()

接下来,我们创建图表对象。因为我们希望我们的 Plotly 图表与 Jupyter 小部件兼容,所以我们的图表需要是一个 FigureWidget 对象,而不是一个 Figure 对象。

我们之前定义的样式函数也适用于 FigureWidget 对象,所以我们可以简单地将它应用到我们的绘图中。

在添加交互性之前,我们需要用初始数据填充图表。我们需要为图表提供一个初始状态。在我们的例子中,state 代表选定的参考日期。我们将使用起始日期作为初始状态,用create_indexed_columns将数据索引到该日期,并将包括黑色参考线在内的所有轨迹添加到绘图中。

我们有基础,我们的初始状态。下一步是编写update_chart函数,该函数将接收一个日期作为小部件的输入和属性,使用create_indexed_columns将我们的数据标准化为该日期,并用这些新值更新轨迹的 y 值。为了一次更新多个值,我们将使用[figure.batch_update()](https://www.kite.com/python/docs/plotly.basedatatypes.BaseFigure.batch_update)上下文管理器来执行更新。对布局和with figure.batch_update()块内的数据的每一个改变都将在一个消息中发送到图表,而不是像update那样的多个消息,从而防止中断。

现在我们开始实现日期选择器变体和滑块变体。我们从第一个开始。

还有四个步骤:

  1. 创建一个 DatePicker 小部件。
  2. 定义一个回调函数picker_response,它监听小部件中的变化并调用update_chart
  3. 将回调函数连接到小部件。
  4. 将小部件放入容器并显示所有内容。

第一步很简单。

对于第 2 步和第 3 步,带有签名handler(change)的特殊处理函数picker_response必须用于回调。change是一个保存变更信息的字典,比如旧值和新值,以及小部件已变更属性的名称。我们将使用new键获取更改时设置的新值。为了将处理程序绑定到小部件,我们使用小部件的observe方法。通过设置observenames参数,我们指定回调函数将在小部件的哪些属性上执行。在我们的例子中,我们需要设置names='value',因为我们想要将滑块的值,即选择的日期传递给处理程序。

在第 4 步中,我们简单地用一个垂直框小部件调用ipython.display函数,它包含日期选择器小部件(包装在一个水*框中)和数字小部件。这些框就像容器一样,类似于 HTML divs。就是这样!

作者图片

图表按预期工作。

现在让我们使用 slider 小部件重新实现带有滑块的动态索引图表。这里的过程在结构上与前面的图表相同。首先,我们定义一个选择滑块小部件,它存储一个选项值列表。对于我们的选项,我们将使用转换为字符串的索引中的日期。我们使用字符串,因为否则当前日期将被格式化为零小时,这不太好。

下面的部分将允许我们使这个图表成为动态索引图表的可靠替代:通过将小部件的continuous_update属性设置为 false,回调函数将只在发布事件时执行。这将产生一个不像动态索引图那样花哨的图表,但具有相同的日期选择界面和每次日期滑块改变时重新绘制的所有好处。如果您启用了continuous_update,图表的行为将与动态指数图表完全一样,速度相同(如果不是更慢的话)。

接下来,我们编写回调函数,用observe将其连接到滑块。最后,我们将所有东西包装到一个 VBox 小部件中,并调用display。瞧,图表准备好了!

作者图片

我希望这篇文章对你有用!我花了一段时间才发现如何实现多索引图表,我想让您免去这项工作。

我想问你一件事:如果你喜欢这篇文章,请 跟我上媒 。你的订阅将使媒体给我钱,我喜欢钱。谢谢😊

你可以在 GitHub 上找到整篇文章的源代码。

如何使团队的 Power BI 开发更容易

原文:https://towardsdatascience.com/how-to-make-power-bi-development-for-teams-easier-c58d388b5e73?source=collection_archive---------28-----------------------

当你试图在一个团队中开发 Power BI 解决方案时,你会遇到同步变化的重大问题。让我们看看这个问题可能的解决方案是什么。

马文·迈耶Unsplash 上拍摄的照片

介绍

我们都知道 Power BI 是一个单片软件,它创建一个包含解决方案所有数据的文件。这使得团队中的开发工作非常困难。

通常,你开始在一个文件中记录变更,有人负责将所有变更整合到一个“主文件”中。

这种方法效率不高,并且容易出错。

ALM 工具包是一个免费的工具,它承诺解决这些问题中的一些,如果不是全部的话。
它是一个独立的工具,用于在表格模型(Power BI 或 SSAS 模型)之间同步数据模型。

另一方面, BISM 规格化器是一个免费的 Visual Studio 扩展,因此只能用于 Analysis Services 数据模型。

让我们看看这些工具以及如何使用它们。

面向 Power BI 的 ALM 工具包

用于 Power BI 的 ALM 工具包可以比较和同步表格模型。

表格模型可以是:

  • 在 Power BI Desktop 中打开的 Power BI 文件
  • Power BI 服务中发布的数据集
  • model.bim 文件形式的表格模型
  • 分析服务的数据模型

当您启动 ALM 工具包时,您必须选择源和目标。

当您在 Power BI Desktop 实例中打开两个 Power BI 文件时,您可以在下拉选择器中选择它们:

图 1 —选择两个 Power BI 文件进行比较(图由作者提供)

点击 OK 按钮后,两个模型的比较开始。

一旦两个模型的比较完成,您就会收到所有对象的列表以及源模型和目标模型之间的差异。

当您从 Visual Studio 或表格编辑器中比较兼容级别高于 Analysis Services 服务器上的目标数据模型的 model.bim 文件时,系统会提示您将目标数据库的兼容级别升级到与源模型相同的级别:

图 2 —与 SSAS 目标比较时兼容性级别的升级(作者提供的图)

现在,您可以通过单击鼠标右键来选择不同之处,并选择工具必须执行的操作:

图 3 —差异和要执行的操作(作者提供的图)

如上图所示,您可以看到每个对象的不同之处。

要仅显示有差异的对象,您必须单击功能区中的“选择操作”按钮,然后选择“隐藏跳过具有相同定义的对象”。

如下图所示,ALM 工具包在模型比较过程中考虑了注释、格式字符串和关系:

图 4 —现有对象的差异(按作者分类)

一旦您为每个变更的物件标记了动作,如果更新可行,您就可以验证您的选择:

图 5 —验证结果(作者提供的图)

正如您在上面的图片中所看到的,该工具不能将所有的更改应用到目标模型。

以下更改不能应用于 Power BI 中的目标模型:

  • 计算列
  • 关系
  • 新表
    ,因为这需要在超级查询中添加一个表

当您单击“应用”按钮时,该工具会自动跳过此类更改。

将 model.bim 文件与 SSAS 上的数据模型进行比较时,可以更新计算列和关系。

使用 Power BI,您可以将更改应用到以下对象:

  • 措施
  • 计算组

不幸的是,我们不能使用这个工具来缩放我们的模型到 SSAS。

当我尝试将 Power BI 文件与 SSAS 模型文件进行比较时,我得到以下错误信息:

图 6 —与 SSAS 模型比较时的错误消息(作者提供的图片)

然后,我试图将 PBI 桌面上的一份 Power BI 报告与一份已发布的 PBI 服务报告进行比较。

事实证明,ALM 工具包访问 XMLA 端点,只有当您拥有每用户高级许可证或高级容量时,XMLA 端点才可用。您需要在激活高级功能的工作空间上发布报表。

当您有这些可能性之一时,您可以连接到您的工作区和报表:

图 7 —连接到 PowerBI 服务(图由作者提供)

您可以通过以下 URL 访问您的工作区:power bi://API . power bi . com/v 1.0/my org/

只要您输入 URL,该工具就会要求您提供 Power BI 凭据。

登录后,您可以从下拉列表中选择报告。

其余的过程与上面的例子相同。

BISM 规格化器

BISM 规格化器是 Visual Studio for Analysis Services 的免费扩展。

该工具覆盖了与 ALM 工具包相同的特性,并且可以以相同的方式使用。唯一的区别是 BISM 规格化器不是一个独立的工具,就像 ALM 工具包一样,而且 GUI 略有不同。

图 8——BISM 规格化器(红色)和 ALM 工具包(蓝色)之间的比较(图由作者提供)

像 ALM 工具包一样,可以比较日期模型,验证变更,为差异创建 Excel 报告,直接部署变更,或者为变更的部署生成修改脚本。

您可以在本文末尾找到 BISM 规格化器的文档。

但是,BISM 规格化器有一些很酷的特性,可以帮助开发过程。

显色法

正如本文开头所描述的,当多个开发人员在一个表格模型上工作时,我们面临着巨大的挑战。无论您在 Visual Studio 中使用表格编辑器还是 Power BI Desktop 修改数据模型,都没有什么不同。

上面显示的两种工具都可以帮助您的团队解决这些挑战。

当一个开发人员完成了模型中的一个新特性时,他可以开始比较并更新一个目标模型,包括开发管道下一阶段的更新。

因为您可以有选择地更新变更,所以您不需要一直部署所有的变更。

这种可能性可以简化你的方法,节省大量时间。

另一种方法是使用分析服务服务器来支持开发人员。

想象以下场景:

Power BI 数据集中有一个复杂的数据模型。多个开发人员正在对数据模型进行修改。并且您希望随时记录您的更改。

现在,您可以使用 Analysis Services 作为桥梁来并行开发和测试多个更改。

不幸的是,如果不对 model.bim 文件进行许多修改,就不可能将 Power BI 数据模型直接迁移到 Analysis Services。
但是,当您从一开始就使用 Analysis Services 时,您可以使用下面描述的流程来支持您的团队:

  1. 开发人员在 Visual Studio 中打开数据模型(model.bim 文件)的副本
  2. 他更改模型,并将修改后的数据模型部署到服务器,成为新的数据模型
  3. 测试人员可以使用 Excel 或 Power BI Desktop 来测试新特性
  4. 现在,您可以使用 BISM 规范器来更新 Power BI Desktop 中的目标数据模型
    您需要从 DAX Studio 获得正确的端口,以便从 BISM 规范器连接到 Power BI Desktop:

图 9 —将 BISM 归一化器连接到 Power BI Desktop)(作者提供的图片)

但是,为什么要用分析服务来管理 Power BI 的变化呢?

当您使用 Visual Studio 更新您的 Analysis Services 数据模型时,您可以保存 BISM 规范化器比较的结果,以便进行文档记录和版本控制。

正如您在 BISM 规范化器用户指南中所看到的,您可以将保存的比较文件添加到 Analysis Services 项目中。

当使用 ALM 工具包时,这种方法是不可能的。

如果您有 CI/CD 过程,那么您可以使用 BISMNormalizer.exe 来实现对您的数据模型的变更的自动部署。

不管您如何改变表格模型的开发过程,这两个工具都是对您的工具箱的一个有价值的补充,并且没有额外的成本。

结论

这两个工具都能以非常可靠的方式同步表格数据模型。

但是,您需要改变您的开发过程以及开发人员使用开发工具的方式,以便找到最有效的方式来使用您所掌握的工具。

据我所知,没有解决方案来同步电力查询代码或您的报告中的可视化。

当您想要在两个 Power BI 文件之间同步您的 Power Query 工作时,您必须手动将 M 代码从一个 Power BI 文件复制到另一个。

有趣的是,有一种方法可以在不打开 Power Query 的情况下从报告中提取整个 M 代码:

  1. 转到帮助功能区
  2. 点击关于
  3. 点击复制按钮:

图 10 —从 About 复制超级查询代码(作者提供的图)

当您将内容粘贴到文本编辑器时,您可以从所有表中获得完整的 M 代码。

为了观想;只要您有相同的数据模型,您就能够在 Power BI 报告之间复制/粘贴可视化效果。但是你也必须手动操作。

托尔加·乌尔坎在 Unsplash 上拍摄的照片

参考

这里是用于分析服务的模型比较和合并的 BISM 规范化器的用户指南的 URL:【Services.pdf 分析的 模型比较和合并

ALM 工具包网页的 URL:https://www.sqlbi.com/tools/alm-toolkit/

2021 年表格模型的开发工具关于 SQLBI 的文章

https://medium.com/@salvatorecagliari/membership

如何让实时机器学习为用户旅程服务

原文:https://towardsdatascience.com/how-to-make-real-time-machine-learning-work-for-user-journeys-5d41fa073005?source=collection_archive---------18-----------------------

为什么结合会话和历史行为是 B2C 组织的正确方法

阿伦视觉| Unsplash

现场用户体验是数字企业与其客户之间最重要的接触点。这就是为什么领先的 B2C 组织经常求助于动态决策策略来优化他们的用户旅程。由机器学习(ML)驱动的动态决策引擎可以帮助产品团队满足消费者日益增长的个性化需求,同时引导他们实现有意义的业务成果,如转化、参与等。

实时机器学习可以通过在每个用户的会话中自动适应新信息来增强动态决策。与批量推断相比,实时更新预测可以提供两个实质性的好处:(1)更准确的模型,以及(2)针对匿名和首次用户的能力。然而,有许多不同形式的实时 ML,并不是所有都非常适合优化用户的旅程。在这篇文章中,我们解释了为什么 B2C 组织希望最大化其动态用户体验的价值,应该利用一种特定形式的实时 ML:由历史数据和会话中数据的组合提供动力的实时推理。

实时推理的优势

一旦训练了机器学习模型,在大多数情况下,使用该模型进行预测是一个两步过程:

  1. 特征工程 —将原始数据处理成更具预测性和机器可读的变量,并对模型进行训练。特征的例子包括用户行为随时间的变化、人口统计信息和一天中的时间。
  2. 推理 —通过模型输入这些特征以生成预测。

例如,考虑一个机器学习管道,它被设计成预测促销折扣将如何影响每个用户转化为付费订阅的可能性。为此用例收集的原始数据可能包括行为事件—点击、登录、页面浏览量等。但是为了训练一个高质量的模型,这些事件必须首先被转换成更高层次的特征,例如:“用户在过去两周内登录了多少次?”,或者“用户的会话有百分之多少发生在移动设备上?”。一旦训练完成,这些相同的特征必须在推理期间提供给模型,以便进行预测。

大多数 ML 系统通过在循环时间表上进行离线批处理来进行特征工程和推理。然后,可以非常快速地存储和访问所得到的预测,以便进行现场动态决策,但是它们不会考虑自批处理运行以来积累的任何信息。更重要的是,批量预测不适用于没有先前行为历史的首次用户或匿名用户。由于第三方 cookies 的长期压力,实时数据的缺乏越来越成问题。

实时推理试图通过利用最新的可用信息来填补这些空白。在许多情况下,实时推理会为现有用户带来更好的预测(因为会话中的数据通常对良好的性能至关重要),并使企业能够瞄准更广泛的用户群(即匿名用户)。再加上动态决策引擎,这些优势可以转化为数字产品团队更多的转换和收入。

实现实时 ML:用户旅程的挑战

在理想情况下,特征工程和推理都是实时发生的。当用户浏览你的网站时,他们的行为会自动与历史事件结合成复杂的特征,这些特征会被用来进行最新的预测。然而,实际上,在(1)可以进行多少实时处理和(2)可以多快获得预测之间存在权衡。你越快需要返回结果,你就越不需要复杂的特性工程。

例如,考虑一个特征,该特征描述了在用户的一生中,在类别“新闻”上出现的用户文章的百分比。为了实时地重新计算这个特征,必须加载并查询用户的整个行为历史。现在考虑一个 ML 模型可能需要数千个相似的特性,很容易看出这种方法对于需要低延迟和客户端实现的用例来说是不可行的。由于这种权衡,许多成功部署实时 ML 的领域是那些直接从客户端收集做出准确预测所需的所有信息的领域。

例如,考虑保护当今许多智能手机的面部识别软件。一旦一个模型被训练来识别某些面部特征,预测一张给定的脸是否属于手机的主人仅仅依靠这张脸的照片。因为所有必要的输入数据都以机器可读的形式直接可用,并且不需要与其他数据源结合,所以可以非常快速地实时做出预测。下面列出了在独立环境中运行的实时 ML 的其他示例。

然而,对于消费者数据用例,仅仅依靠当前会话的信息通常是不够的。预测用户未来的行为通常需要对他们过去的行为有更全面的了解。但是,加载这些数据并将其整合到最新功能中通常非常缓慢。因此,B2C 产品团队有时被迫在两个不完美的解决方案之间做出选择:仅基于当前会话的数据使用实时推断,或者仅使用历史数据生成批量预测。

两全其美的解决方案

为了应对这一挑战,在消费者旅程中使用机器学习的组织应该采用混合方法。通过利用历史特征(批量预先计算)和会话中特征(实时计算)的组合,企业可以获得实时推理的好处,而不会牺牲过去数据的预测价值。

在这个框架中(我们称之为具有混合特征的实时推理),每个用户的整个行为历史在做出预测时都被考虑在内。但是,为了避免延迟问题,过去和现在的数据不会合并到任何单一功能中。相反,一组特征是基于用户的当前会话构建的,而另一组特征是使用来自先前会话的数据构建的。例如,不是计算诸如“在过去 7 天内,包括这次会话,用户点击了多少次?”一个混合特征系统将产生两个独立的特征,这两个特征合在一起捕获相同的信息

  1. "用户在过去的 6 天里点击了多少次?"(在服务器上批量计算)
  2. "今天用户在当前会话中有多少点击?"(在客户端实时计算)

这种方法为动态用户旅程提供了两全其美的优势——复杂的历史功能描绘了用户行为的全面图景,最新的行为信号促进了上下文定位和匿名用户预测,以及低延迟(约数百毫秒)以确保响应迅速的用户体验。

示例:动态订阅付费墙

为了说明这个框架在实践中是如何工作的,考虑一个媒体组织,其目标是通过动态付费墙系统来增加订阅量。该系统由一组 ML 预测驱动,这些预测表明如果显示硬付费墙而不是访问 3 个额外的免费内容,每个用户订阅的可能性将如何变化。

预测一个用户的行为会如何改变是一项困难的任务。为了实现高投资回报率,组织需要准确的 ML 预测。为了生成准确的预测,模型需要访问一组丰富的要素。为了构建这些功能,我们混合使用了历史信息和会话信息。

首先,考虑历史特征。这些可以使用前一天结束时收集的信息,按批处理时间表每天重新计算。例如,在 1 月 1 日午夜,可能会运行一个批处理进程,使用截至 12 月 31 日一天结束时收集的信息来重新计算数千个分析风格的特征(如下所示)。

现在让我们假设用户 X 在 1 月 1 日登录网站。为了确定用户应该获得哪种付费墙体验,我们请求生成一个新的预测。用户的批量要素从高可用性要素存储中获取,而一组会话中的要素在客户端中实时计算。两组特征都被提供给模型,以便做出可能的最佳预测。

结论

实时推理可以极大地提高动态决策策略的效率,但对于 B2C 组织来说,采用正确的实时实现以实现其好处是很重要的。通过利用来源于过去和现在数据的混合特性工程系统,这些组织可以为更多用户生成更好的预测,以优化现场体验并推动其业务的关键指标。

如何用 R 制作 REST APIs:水管工初学者指南

原文:https://towardsdatascience.com/how-to-make-rest-apis-with-r-a-beginners-guide-to-plumber-9be4cd8c8015?source=collection_archive---------39-----------------------

立即将 R 脚本转换成 REST APIs。

照片由史蒂夫·哈维Unsplash 上拍摄

REST APIs 在我们身边无处不在。软件工程师用它们来开发后端逻辑,数据科学家用它们来部署机器学习模型。今天你将学习如何用 R 和plumber包制作一个基本的 REST API。

这篇文章的结构如下:

  • REST APIs 简介
  • 用 R 和 Plumber 开发一个简单的 REST API
  • 结论

REST APIs 简介

REST 代表“代表性状态转移”。更简单地说,它代表了开发人员在创建 API 时遵循的一组规则。最常见的规则是,每当向特定 URL 发出请求时,都应该获得一段数据(响应)。

您的请求由四部分组成:

  • 端点 —您访问的 URL 的一部分。例如,URLhttps://example.com/predict的端点是 /predict
  • 方法 —您正在发送的一种请求,可以是 GET、POST、PUT、PATCH 和 DELETE。它们用于执行以下操作之一:创建、读取、更新、删除(CRUD)
  • 标头 —用于提供信息(例如,考虑认证凭证)。它们以键值对的形式提供
  • 正文 —发送给服务器的信息。仅在不发出 GET 请求时使用。

大多数情况下,发出请求后返回的响应是 JSON 格式的。另一种格式是 XML,但 JSON 更常见。你也可以返回其他对象,比如图片来代替。今天你将学会如何做。

r 允许你用plumber包开发 REST APIs。你可以在这里阅读官方文档

plumber可以很容易地将任何 R 脚本文件转换成 API,因为你只需要用注释来修饰你的函数。过一会儿你就会明白了。

用 R 和 Plumber 开发一个简单的 REST API

首先,创建一个空的 R 脚本文件。你需要几个包:

  • plumber–开发 API
  • dplyr–根据请求体(或 URL 参数)过滤数据集
  • ggplot2–用于数据可视化
  • gapminder–用于数据。这就是你将要使用的 API 的基础。

您可以放置两个类似于roxigen2的注释来指定 API 标题和描述。这两个不是强制性的,但是你不应该跳过它们。下面是整个代码片段(导入、名称和描述)的样子:

您现在已经准备好创建您的第一个端点。

端点 1—/国家

这个端点背后的想法是,在应用了几个过滤器之后,它应该返回国家和它们各自的数据。更准确地说,这个端点接受洲、预期寿命和人口的参数值。continent 的值必须精确,另外两个参数的值过滤数据,以便只返回具有较大值的行。

如果你想把事情做好,就需要很多评论,就像你之前看到的那样。写一个简短的描述、列出参数是一个很好的实践,并且必须指定请求类型和端点。

在注释下面,您将放置一个执行必要逻辑并返回结果的函数。

让我们考虑一下参数。你需要:

  • —列
  • 预期寿命 —列 lifeExp
  • 人口 —列人口

这三项都是强制性的,您可以使用dplyr包基于参数值进行过滤。该端点将只返回最*一年的数据,即 2007 年。

以下是/国家端点背后的完整逻辑:

如果您现在运行 API,您将看到以下内容:

图 1——API 文档页面(图片由作者提供)

图像底部的端点(蓝框)是可点击的。点击它会展开整个另一部分:

图 2——针对/countries 端点的文档(图片由作者提供)

您可以点击“试用”按钮,直接从浏览器发出请求。然后,您必须填写参数值;让我们这样说:

图 3 —测试国家/地区终点(图片由作者提供)

一旦您点击“执行”按钮,响应将显示如下。这种情况下看起来是这样的:

图 4—/国家/地区端点示例响应(图片由作者提供)

这就是你的第一个终点!它接收数据并返回数据。但是如果你想返回别的东西呢?例如,像一幅图像。接下来您将学习如何做到这一点。

端点 2—/图

这个终点会很不一样。现在的目标是返回图像而不是原始数据。该图像将包含一个用ggplot2制作的线形图,显示一段时间内的预期寿命。

两个参数是必需的——国家和图表标题——它们都是不言自明的。

如果你想用 R 从一个 API 返回一个图像,你必须加上下面的注释:#* @serializer contentType list(type='image/png')。其他的都差不多。

关于可视化,从仅包含指定国家的记录的原始数据集制作子集。然后从数据集制作一个简单的线条和标记图。

问题是——你不能返回一个ggplot2可视化。你必须用ggsave()功能保存图像,然后用readBin()功能返回。

以下是完整的片段:

如果您现在运行 API,一个新的端点会立即引起您的注意:

图像 5—/绘图端点(作者提供的图像)

下面是它的文档:

图像 6—/绘图终点文档(作者提供的图像)

您可以再次单击“试用”按钮来测试功能。让我们看看波兰人的预期寿命是如何随着时间的推移而变化的:

图 7 —测试/plot 终点的波兰预期寿命(图片由作者提供)

单击“执行”按钮后,您将看到以下画面:

图 8 —波兰人的预期寿命(图片由作者提供)

这就是你如何在 API 响应中返回图像。到目前为止,您只使用 GET 方法创建了端点。接下来,您将学习如何使用 POST。

端点 3—/计算国内生产总值

现在,您将学习如何使用 POST 方法(或任何其他在请求正文中发送数据的方法)。目标是创建另一个端点来计算指定国家最*一年(2007 年)的 GDP 总量。

您需要的唯一参数是国家。

一旦有了这个值,就可以使用dplyrsummarize()函数来计算 GDP 总量。以下是完整的代码片段:

如果您现在运行 API,您会立即看到一个新框,这次是绿色的,表示 POST 方法:

图片 9—/计算 gdp 终点(图片由作者提供)

您可以再次单击“试用”按钮来测试功能:

图 10 —测试/calculate_gdp 端点(图片由作者提供)

让我们看看 2007 年波兰的 GDP 总量是多少:

图 11 —测试波兰的/calculate_gdp 端点(图片由作者提供)

单击“执行”按钮后,您将看到以下响应:

图 12—2007 年波兰的国内生产总值(图片由作者提供)

GET 和 POST 之间的唯一区别是,您不能将参数及其值放在 POST 的 URL 中。参数和值作为 JSON 在请求体中传递。

您现在知道如何将 R 代码包装成一个简单的 REST API。接下来让我们总结一下。

结论

今天你已经学到了很多——什么是 REST API,plumber包有什么作用,以及如何使用它在 R 编程语言中构建基本的 API。

R 中的 API 通常是为公开机器学习模型的预测功能而开发的。当然,您还可以做其他事情(正如今天所演示的),但是 R 可能不是最好的语言。如果是这样的话,你可能更擅长 Java、Go 或 JavaScript。

喜欢这篇文章吗?成为 中等会员 继续无限制学习。如果你使用下面的链接,我会收到你的一部分会员费,不需要你额外付费。

https://medium.com/@radecicdario/membership

加入我的私人邮件列表,获取更多有用的见解。

原载于 2021 年 1 月 13 日 https://appsilon.comhttps://appsilon.com/r-rest-api/

如何用 Python 制作令人惊叹的雷达图——用 Matplotlib 和 Plotly 实现

原文:https://towardsdatascience.com/how-to-make-stunning-radar-charts-with-python-implemented-in-matplotlib-and-plotly-91e21801d8ca?source=collection_archive---------4-----------------------

使用雷达图轻松可视化第二维以上的数据——在 Matplotlib 和 Plotly 中实现

文章缩略图—作者图片

在大多数情况下,可视化二维以上的数据并不是一个好主意。这就是雷达图的用武之地,它使您能够直观地表示多个相同比例变量的一组或多组值。

今天,您将了解雷达图如何使用 Matplotlib 和 Plotly 在多个维度上可视化数据。您还将了解什么是雷达图以及使用它们的利弊。

这篇文章的结构如下:

  • 雷达图介绍
  • 雷达图的利与弊
  • 使用 Matplotlib 的雷达图
  • 用 Plotly 绘制雷达图
  • 结论

你可以在这里下载相应的笔记本

雷达图介绍

你很可能知道什么是雷达图。有时它们被称为蜘蛛图极坐标图,但这些术语代表相同的概念。雷达图的目标是直观地表示多个变量的一组或多组值。

例如,假设您想通过一些公共变量直观地表示餐馆,比如食物质量、食物种类、服务质量和其他变量(剧透提示:您稍后会这么做)。在这种情况下,雷达图应该是首选的可视化类型。

每个变量都有一个轴,轴围绕中心呈放射状排列。不用说,但是轴是等间距的。然后沿着每个轴绘制单个观察值,就像散点图一样,但是这些点然后被连接起来形成一个多边形。您可以重复使用相同的逻辑在同一个图表中绘制多个多边形。

这就是雷达图背后的基本思想。让我们在开始动手示例之前先分析一下利弊。

雷达图的利与弊

先说一下的利弊:

  1. 雷达图非常适合观察结果之间的可视化比较,您可以轻松地比较不同观察结果之间的多个属性,并查看它们是如何叠加的。例如,您可以使用雷达图根据一些常见变量来比较餐馆。
  2. 很容易看到整体“最佳表现者”-如果您要查看整体表现,多边形面积最大的观察结果应该是最佳的。

但是事情并不都是阳光和彩虹,正如你从下面的清单中看到的:

  1. 雷达图很快就会变得令人困惑——比较几个以上的观察结果会导致没人愿意看到的混乱局面。
  2. 如果变量太多,就很难找到最佳选择——想象一下,一张雷达图有 20 多个变量。没人想看一眼。上帝禁止解读它。
  3. 变量必须在相同的范围内——比较学生成绩(从 1 到 5)和对某些服务的满意度(从 0 到 100)是没有意义的。

你现在知道什么是雷达图,什么时候使用它们是有意义的。接下来您将学习如何用 Matplotlib 绘制它们。

使用 Matplotlib 的雷达图

Matplotlib 是 Python 事实上的标准数据可视化库,所以这就是我们首先关注它的原因。

目标是在以下类别中比较三家餐厅:食品质量、食品种类、服务质量、氛围和可负担性。所有类别的范围从 1 到 5,所以它们是雷达图可视化的完美候选。

下面的代码片段演示了如何指定数据和类别、标签位置以及可视化图表。有几件事你应该事先知道:

  • label_loc是以弧度表示标签位置的列表
  • plt.subplot(polar=True)必须用来制作雷达图
  • plt.thetagrids()用于在标签位置放置类别名称

这些一开始可能会令人困惑,但你很快就会明白要点。您可以使用以下代码片段进行可视化:

下图显示的是:

图片 1 —您的第一张雷达图(图片由作者提供)

快速看一下前面的数字就可以看出有问题。最后一个数据点没有连接到第一个数据点,您需要以某种方式解决这个问题。没有 100%直观的解决办法,但是你应该这么做:在类别和餐馆中添加一个与第一项相同的元素。

您可以手动这样做,但是如果您不知道第一个值是什么呢?您可以使用解包和索引操作来解决这个问题。方法如下:

正如您所看到的,每次都编写这个逻辑有点乏味(您可以用它来创建一个函数),但是现在雷达图看起来是这样的:

图 2-修复雷达图中的数据点连通性(图片由作者提供)

如你所见,好多了!

Matplotlib 的美观性没有得到广泛认可,所以接下来让我们看看如何用 Plotly 生成更好看的可视化效果。

用 Plotly 绘制雷达图

普洛特利是另一回事。使用几乎相同数量的代码,很容易制作高度可定制的、好看的和交互式的图表。雷达图也不例外。

这并不意味着他们对 Matplotlib 的问题免疫。您仍然需要手动“关闭”多边形,但结果是更好看的可视化。

下面的代码片段产生了之前用 Matplolib 创建的相同的可视化效果:

可视化如下所示:

图 3 —带 Plotly 的雷达图(图片由作者提供)

这就是全部了!Plotly 也使得填充多边形变得容易——只需指定fill='toself'。这里有一个例子:

可视化如下所示:

图 4-用 Plotly 填充的雷达图(图片由作者提供)

这就是用 Plotly 制作雷达图有多简单。接下来让我们总结一下。

结论

雷达图提供了一种很好的方法来可视化多个变量的一组或多组值。今天你已经学会了如何做到这一点——用完全虚构的餐厅满意度数据。

请记住雷达图的限制或缺点。如果你想可视化许多观察结果,它们不是最好的选择,所以最多坚持一个或几个。

喜欢这篇文章吗?成为 中等会员 继续无限制学习。如果你使用下面的链接,我会收到你的一部分会员费,不需要你额外付费。

https://medium.com/@radecicdario/membership

了解更多信息

保持联系

  • 关注我的媒体以获取更多类似的故事
  • 注册我的简讯
  • LinkedIn 上连接
  • 查看我的网站

原载于 2021 年 2 月 15 日【https://betterdatascience.com】

如何在没有筛子的情况下用小众研磨机制作 Sudo-Staccato 浓缩咖啡

原文:https://towardsdatascience.com/how-to-make-sudo-staccato-espresso-with-a-niche-grinder-without-a-sifter-7b4cdcd70231?source=collection_archive---------15-----------------------

咖啡数据科学

无筛分层

在使用了五年的韩国磨床之后,我最*把它升级成了 T2 磨床。我升级主要是因为时间。我花了 5 分钟磨了四次豆子,我不喜欢这种经历,尤其是计划什么时候磨对我的家人影响最小。我对质量很有把握,我想我可以节省一些升级的时间。

我花了一点时间来适应,因为我在拍摄准备中做了很多花哨的事情。然而,这导致了一个伟大的发现:0 设置的利基是非常好的。所以我筛选了它,我从 10 设置中筛选了一些咖啡渣,以了解更多关于粒子分布的信息。大多数 0 设置的大小小于 400 um。我认为这有可能做一个断奏镜头,让我们称之为 sudo-staccato espresso。

我喜欢断续镜头,但由于疫情和在家工作,我没有时间筛咖啡。我想过买一个更大的机械筛,但是我没有柜台空间。我在去年偶然开发了断奏夯实,我用我从 100 个断奏击球中获得的知识改进了这个过程。

地面容器

此外,我一直想让别人尝试断奏。大多数人没有筛子,也不会花时间去筛足够的咖啡来实验和完善这项技术。即使在筛选了许多磅咖啡后,我能得到的最好结果是每分钟 3 克,所以对于 18 克的镜头,需要 6 分钟的筛选。通常情况下,我不得不筛掉多余的咖啡渣,因为我无法得到每层咖啡渣的正确数量。通常,我会一次筛 45 克。

通过演示如何使用壁龛进行断奏,我还制作了一个食谱,任何拥有壁龛或类似研磨机的人都可以复制。关键是研磨设置可以很容易地调整,并有一个狭窄的咖啡粉分布。因此,任何具有单峰或接*单峰分布的零或低留着率研磨机都可以工作。

回顾中的断续浓缩咖啡

断续射击一开始是一个奇怪的实验。我对使用筛子来获得更好的咖啡颗粒大小感兴趣,但我对此并不感兴趣。我不想买新的筛子,因为我不相信我会长期使用它。如果我找到一个好价钱,我想我会去买它。这就是我买第一个的原因。

一开始,我买的 Kruve 筛子只有 400 微米和 800 微米的筛网。这并不是浓缩咖啡的最佳选择,但我总是有心情去尝试。所以我筛选了我的咖啡渣。800 微米以上的磨粒很少,但大于 400 微米和小于 400 微米的磨粒分布相当均匀。我设计了一些实验来确定我能做什么。

小于 400 微米的粉末会导致过滤器堵塞,产生不均匀的萃取,但就味道而言,它更甜,没有正常的苦味。大于 400 微米的粉末流动性更好,但味道不同。情况并没有变得更糟,但我开始理论化地认为,每种颗粒大小都代表了味道的不同组成部分。

自然地,这导致了一种结合,一种分层。

经过两个月的反复,我决定只使用 7 个度量标准的品味等级,即层的最佳排序和每层的权重。后来,我使用总溶解固体(TDS)和提取率(EY)来确认我用断续击球比正常击球获得了更高的提取率。

危机中诞生的断奏捣固

疫情来袭时,我突然在家工作。我还碰巧买了几磅咖啡,比我喜欢的烘焙咖啡颜色要深一些。然而,我仍然在寻找牛奶饮料。我讨厌把咖啡渣放进篮子里,让咖啡到处都是,即使在我捣实后,它会有足够的空间。结果我开始中间夯一次,最后夯一次。

我在测量这些镜头的提取率,我注意到我在增加提取率。这导致了断奏夯实技术的发展,该技术通过修改两层中的密度来*似断奏击球,从而利用从断奏击球中获得的经验。

在过去的几个月里,我花了更多的时间来观察咖啡的分布曲线,为了节省时间,我买了一个利基市场。然而,我确实注意到,最好的咖啡研磨机在中心颗粒尺寸周围给出了更紧密的分布。这让我想到,也许像壁龛这样的高端研磨机可以用来进行断奏或更接*断奏。据我估计,这个利基市场是高端研磨机的低价位。

如何分层与利基(或任何高端磨床)

当我第一次得到磨床,我试图拉一杆,但我需要在磨床拨号。因此,我决定筛选两种不同的研磨尺寸,以了解更大的研磨分布。分布存在于一些来源,但是没有人扫过研磨设置来看它是如何影响研磨分布的。这个小测试确实告诉我设置 1 非常好。我怀疑利基可以去 10 或更多的设置比我以前的磨床更好。

像大多数实验一样,我开始了这个实验:一个有根据的猜测。我认为 0 设置可以很好地替代精细层,设置 15 为中间层,设置 30 为粗糙层。我知道这些层在粒子分布上不会那么紧密,但也许我会找到一些有用的东西。

我的目的是看看我是否在正确的范围内。如果我是在棒球场,一些小的调整会让我一路。在球场上意味着我可以接*我的其他镜头的味道,并接*提取产量。

我想对研磨分布有更深入的了解,所以我研究了一种方法来产生粒子分布。主要目的是帮助修改这个 sudo-staccato 镜头。

一般来说,我会磨几杯,然后把粉末储存在冰箱的密封容器里(的数据显示这不会影响新鲜度)。

首先,我研磨咖啡。对于工作流程,我首先在最精细的设置上研磨咖啡豆,然后是中等设置,最后是粗糙设置。

精细(0 设置)、粗糙(30 设置)、中等(15 设置)

然后我预热机器,开始准备冰球。我用一个弯曲的回形针或定制的塑料片来分发咖啡渣。

有时会有更多的层,因为用豆子分裂了精细的层或者添加了一层罗布斯塔

我夯实每一层,但我发现夯实需要轻。对于细层,它会在压力下迅速压缩,因此较轻的夯实可以减少沟流。我通常的目标是每层 200 到 400 克夯实。我用一个标尺来测量压力。我还在底部以及精细和粗糙层之间使用了一个布过滤器来增加额外的复杂性。

左:精细层分布工具,使边缘密度更高,以避免甜甜圈。右图:带齿的扁*工具,用于*整粗糙层和中间层。

然后我开枪。我会做 30 或 40 秒左右的长时间预输注。通常,我拍摄照片,这样我就可以看到进展。如果注射无效,我会进行 1 分钟或 1.5 分钟的预输注。然后我压脉

我在 1:1 输出到输入和 1.5:1 之间结束拍摄(对于 18g in,我的目标输出范围是 18g 到 24g)。我让它凉了 4 分钟,然后搅拌,喝了它。

底部和中间有滤布。在上图中,冰球上下颠倒。底部的两个图像是中间/粗糙层

镜头分析

在观察总溶解固体(TDS)与提取率(EY)时,我的目标是下图中的红色区域。断奏仍然表现更好,所以我有一些工作,看看我是否可以调整研磨设置,以改善 Sudo 断奏。

在过去的几个月里,我一直在拉更多的断奏夯实镜头,从这些照片中,他们对 TDS 和 ey 的趋势相似:

断续地拨入

不像正常的拨入过程中调整研磨,我更喜欢先调整每层的数量。我也很小心夯压。我发现一个非常轻的夯锤(200 克到 400 克)更有效,因为颗粒尺寸范围已经很紧了,所以层压实得更好。这是假设更长时间的预输注对献血没有帮助。

断奏镜头对我来说一直是下一个水*,我还做了其他有趣的技巧,比如在底部以及精细和粗糙层之间用布(或纸)过滤。能够从我的工作流程中削减时间,但仍然能拍出令人惊叹的照片,这让我觉得利基市场是一个不可思议的购买。

磨工不一定是小众。你可以是任何高端磨床,给接*单峰分布。我怀疑*毛刺可能更适合,但我不知道,直到我得到一些数据的多重研磨设置。

如果你愿意,可以在 TwitterYouTube 上关注我,我会在那里发布不同机器上的浓缩咖啡照片和浓缩咖啡相关的视频。你也可以在 LinkedIn 上找到我。也可以在关注我。

我的进一步阅读:

浓缩咖啡系列文章

工作和学校故事集

个人故事和关注点

乐高故事启动页面

摄影飞溅页面

如何确保你的分析被实际使用

原文:https://towardsdatascience.com/how-to-make-sure-your-analysis-actually-gets-used-4295bac3073?source=collection_archive---------13-----------------------

将海盗拒之门外

奥斯丁·尼尔Unsplash 上拍摄的照片

小心海盗

最普遍的令人沮丧的经历之一就是看到你努力工作的成果没有被发现,没有被欣赏,没有被使用。在数据世界里,这是我们经常经历的事情。以下面的假设情况为例:

  1. Jim 向数据团队提交了一份请求,要求对下周的客户演示进行深入分析。
  2. 你和 Jim 花一周时间进行分析,密切合作以确保他有正确的视觉效果,并有信心展示调查结果。
  3. 展示的日子到了,但吉姆一句话也没说。太奇怪了。
  4. 当你最终找到他时,他告诉你他“最终还是没有使用图表。”“他们只会把他们弄糊涂,”他用安抚的语气补充道。
  5. 你生气了。浪费了整整一周。另一个没有数据支持的决定。他当初为什么要问?

我喜欢称这些请求者为海盗,因为他们偷走了我的时间。不幸的是,总会有海盗,但我们可以学会避免他们,或者至少应对他们的存在。这里有一个提示列表,根据我自己的经验、学术研究和行业最佳实践,可以确保你的分析得到应有的信任。

1.丢弃数据请求表单

我们必须是顾问,而不是雇工。

大多数数据团队都有一个请求门户,用于筛选和分配来自业务的数据请求。这些门户旨在使业务和数据团队更容易合作;业务用户准确地输入他们想要的,数据团队只是让它发生。

不幸的是,正如我们从吉姆那里看到的,事情没那么简单。许多业务用户来到数据团队时脑子里已经有了一个图表,包括图表上的数字应该显示什么。

在这一点上,我们已经注定了。如果数据与请求者想要的故事不匹配,或者有点细微差别,那么他们永远不会使用这个分析。我们需要知道他们试图解决的问题。

作为数据专业人员,我们比任何人都更了解数据和统计方法,并可以建议使用数据来回答手头问题的最佳方法。业务环境与我们的数据专业知识相结合,可以创建比我们单独生成的分析更有影响力的分析。

简而言之,我们必须是顾问,而不是雇工。

2.数字从不独行

单靠一张图表不可能传达所有信息,这种想法抑制了我们通过工作影响业务的能力。

通常,我们希望发送一个完整的图表或仪表板请求。如果没有一对一的解释,业务用户几乎不可能理解这些内容。

我们被告知数据可以自己说话;一张精心制作的图表可以独自传达所有的细微差别。这根本不是真的。单靠一张图表不可能传达所有信息,这种想法抑制了我们通过工作影响业务的能力。

不能只靠图表来传达见解。利用文字来解释你的工作。来源:从未获得冠军的最佳球员作者:【count.co】T2

在分享任何分析时,我会尽量包含以下信息:

  • 数据的时间段
  • 分析日期
  • 作者
  • TL;博士:背景和见解总结
  • 如何阅读图表的说明
  • 你是如何进行分析的(不是代码,而是外行的解释)
  • 局限性和后续步骤

这种上下文信息可能看起来令人头疼,但它会产生巨大的影响。我们不仅仅是发送了一个图表,孤立地看,它可能会带来无益的潜台词“搞清楚”。我们已经向他们发送了一份分析报告,提供了将图表转化为洞察力所需的一切,这是一个不会被忽视的小举动。

打破自己发送图表的习惯给了他们一个被理解并最终被使用的机会。

3.让它成为一种体验

要真正理解你的分析,你的用户需要戳戳它…让我们帮助他们实现这一点。

用上下文和解释围绕你的图表可以确保读者从我们的分析中了解到他们需要的一切。但是我们通过经验学习得最好。

因此,要真正理解你的分析,你的用户需要戳戳它。Kolb 的学习模型表明,他们需要对我们的分析进行实验,并花时间思考它在现实世界中的含义,然后才能正确理解它。让我们帮助他们到达那里。

大卫·库伯的体验式学习模式(ELM) [1]图片来源:作者

至少,这涉及到为您的分析设置交互元素。添加过滤器和参数,让用户开始查询数据。如果你有两倍的预算会怎么样?一半?

这种问答流程让用户信任分析,并理解它与他们的问题的关系,最终让他们有信心在董事会中运用这种分析。这种缺乏信心是你的图表没有进入幻灯片的首要原因,所以在这里要小心。

4.准备好演示文稿

在不牺牲分析复杂性的前提下,创建引人入胜、信息丰富的视觉效果,不会吓到观众。

不幸的是,我们不能指望有人花时间从演示文稿的分析中学习我们的商业伙伴(希望)到目前为止的做法。这意味着我们现在需要创建一个摘要图表,它可以反映我们分析的关键点,但细节要少得多。

理想情况下,一旦你就关键见解以及如何最好地将它们组成一个更大的决策或要解决的问题达成一致,这就是你分析的最后一步。然后,您可以利用数据可视化最佳实践[2]来创建引人入胜且信息丰富的视觉效果,而不会威胁到查看者,同时又不会牺牲您分析的复杂性。

5.分析万岁

请确保您的分析不仅限于这一个数据请求,并且可以反复使用。

这个过程中被严重忽视的一部分是将这种分析转化为可扩展知识的问题。你如何确保你刚刚回答的业务问题不只是与 Jim 或 Jim 的团队分享,而是与更广泛的公司分享?不仅仅是这个星期,而是在 6 个月内同样的问题再次出现时可以使用。答案显然不是仪表板,而是更微妙的东西。

AirBnB 的方法 [3]是实现一个知识源,该知识源采用我们刚刚概述的详细分析类型,并将其发布给整个公司。其结果是一个报告集合,所有用户都可以轻松理解,但仍然可以访问原始代码和注释,供分析师用作未来工作的起点。关键属性被记录下来,让每个人对他们所看到的有信心(何时发布,限制等)。).他们使这个知识数据库易于解析,这样人们在向数据团队提交请求之前,就可以快速找到与他们的问题相关的分析。

现在,您可以确保您的分析超越了这个单一的数据请求,并且可以一次又一次地使用。

每日时间

这种工作方式的好处是易于测试。下一次当你的一个更友好的商业用户(避免盗版)发出请求时,我建议试试这个方法。与其将他们要求的图表具体化,不如要求与他们会面,以更好地了解他们希望用这张图表做什么。它为哪些决策提供了信息?观众是谁?

当你们在这个分析中一起工作时,我建议使用一个数据笔记本来记录所需的元数据,并向你的业务伙伴解释你的工作。这让你可以灵活地将你的分析与代码和图像联系起来,这样你就不会试图在某个地方拼凑一个谷歌文档。

一旦你们都对分析和发现感到满意,然后一起完成最终的图表,看看它与最初的请求有多大的不同。我敢打赌他们完全不同。

计数笔记本示例。来源:谁是网球山羊?

将这种分析用于共享知识需要更多的深谋远虑。这些笔记本没有多少自然的去处;Github 对非开发人员来说不够用户友好,像 DropBox 或 Google Docs 这样的选项不够技术化,无法包含所需的代码。

如果你强迫我推荐一个工具,我会说,但是坦白地说,我确实帮助构建了它。Count 是一个数据笔记本,旨在使这种工作方式成为规范。您可以创建高质量的分析报告,在一个文档中包含完整的上下文、解释和定制的视觉效果,为您的工作提供所需的*台,使其能够经受住短暂的数据请求,并成为整个公司都可以从中受益的知识。

如果你尝试过这些方法,我很想在评论中听听效果如何!

参考

[1]Kolb,D. A. 体验式学习:经验作为学习和发展的源泉 。新泽西:普伦蒂斯-霍尔;1984.

[2]迈克尔·马奥尼。 数据可视化的艺术与科学 。走向数据科学;2019.

[3] Sharma,C. & Overgooer,Jan .Airbnb缩放知识。airbnben;2016.

如何用 Python 制作合成数据集:机器学习完全指南

原文:https://towardsdatascience.com/how-to-make-synthetic-datasets-with-python-a-complete-guide-for-machine-learning-376093b360ac?source=collection_archive---------33-----------------------

没有数据集?没问题。使用 Python 在几秒钟内创建您自己的。

照片由海登·邓塞尔Unsplash 上拍摄

好的数据集很难找到。另外,有时候你只是想表明自己的观点。对于这些情况,繁琐的加载和准备可能有点多。

今天,您将学习如何使用 Python 和 Scikit-Learn 制作合成数据集,Scikit-Learn 是一个出色的机器学习库。您还将学习如何处理噪声、类*衡和类分离。

这篇文章的结构如下:

  • 制作您的第一个合成数据集
  • 添加噪声
  • 调整职业*衡
  • 调整类分离
  • 结论

你可以在这里下载这篇文章的笔记本

制作您的第一个合成数据集

真实世界的数据集对于展示概念和想法来说往往太多了。假设你想直观地解释 SMOTE(一种处理类不*衡的技术)。你首先必须找到一个类别不*衡的数据集,并将其投影到 2-3 维,以便可视化工作。

有更好的方法。

Scikit-Learn 库附带了一个方便的make_classification()函数。它不是创建综合数据集的唯一工具,但今天您会大量使用它。它接受各种参数,让您控制数据集的外观和感觉,但稍后会详细介绍。

首先,您需要导入所需的库。请参考以下片段:

您已经准备好创建您的第一个数据集。它将有 1000 个样本分配到两个类(0 和 1)中,并达到完美的*衡(50:50)。属于每个类别的所有样本都集中在单个聚类周围。数据集只有两个特征,以使可视化更容易:

sample()的调用打印出五个随机数据点:

图片 1—5 行随机样本(图片由作者提供)

这并不能给你数据集背后的全貌。它是二维的,所以你可以为数据可视化声明一个函数。这里有一个你可以用的:

这是它的视觉效果:

图 2-合成数据集的可视化(图片由作者提供)

太快了!您现在有了一个简单的合成数据集,可以随意摆弄。接下来,您将学习如何添加一点噪声。

添加噪声

您可以使用make_classification()功能的flip_y参数添加噪声。

此参数表示随机分配类别的样本的分数。较大的值会在标注中引入噪声,使分类任务更加困难。请注意,默认设置 flip_y > 0 在某些情况下可能会导致 y 中少于 n _ classes[1]。

下面是如何在我们的数据集上使用它:

下面是相应的可视化:

图 3-添加了噪声的合成数据集的可视化(图片由作者提供)

你可以在蓝色星团中看到更多橙色点,反之亦然,至少与图 2 相比是这样。

这就是你添加噪音的方式。接下来把重点转移到阶级*衡上来。

调整职业*衡

在现实世界的数据集中,至少可以看到一点点的阶级不*衡。一些数据集遭受严重的类别不*衡。例如,1000 笔银行交易中有一笔可能是欺诈性的。这意味着余额比例为 1:1000。

你可以使用weights参数来控制职业*衡。它将列表视为具有 N–1 个值的值,其中 N 是要素的数量。我们只有 2 个,所以列表中只有一个值。

让我们看看如果将值指定为 0.95 会发生什么:

以下是数据集的视觉效果:

图 4-正类上存在类不*衡的合成数据集的可视化(图片由作者提供)

如您所见,只有 5%的数据集属于类 1。你可以轻松扭转局面。假设您想要类 0 中数据集的 5%:

下面是相应的可视化:

图 5-在负类上具有类不*衡的合成数据集的可视化(图片由作者提供)

这就是阶级*衡的全部。让我们通过调整类分离来结束。

调整类分离

默认情况下,存在一些重叠的数据点(类别 0 和类别 1)。您可以使用class_sep参数来控制类的分隔程度。默认值为 1。

让我们看看如果将值设置为 5 会发生什么:

以下是数据集的外观:

图 6-具有严重类别分离的合成数据集的可视化(图片由作者提供)

正如你所看到的,现在的班级更加分散了。更高的参数值会导致更好的类分离,反之亦然。

现在,您已经了解了制作用于分类的基本合成数据集的所有内容。接下来让我们总结一下。

结论

今天,您已经学习了如何使用 Python 和 Scikit-Learn 创建基本的综合分类数据集。当你想证明一个观点或者实现一些数据科学概念的时候,你可以使用它们。真实的数据集对于这个目的来说可能是多余的,因为它们通常需要严格的准备。

请随意浏览官方文档,了解其他有用的参数。

感谢阅读。

喜欢这篇文章吗?成为 中等会员 继续无限制学习。如果你使用下面的链接,我会收到你的一部分会员费,不需要你额外付费。

https://medium.com/@radecicdario/membership

加入我的私人邮件列表,获取更多有用的见解。

了解更多信息

参考

[1]https://sci kit-learn . org/stable/modules/generated/sk learn . datasets . make _ classification . html

原载于 2021 年 1 月 11 日 https://betterdatascience.com**T21

如何充分利用低代码/无代码开发*台?

原文:https://towardsdatascience.com/how-to-make-the-most-of-low-code-no-code-development-platform-1d1bd3768765?source=collection_archive---------9-----------------------

运行 3 个低代码黑客马拉松和几个概念验证后的经验教训

本·科尔德在 Unsplash 上的照片

在过去的一年里,我为企业客户提供了几次概念验证和黑客马拉松,现在我想分享一下我的经验。由于各种原因,许多企业放弃了 PoC 解决方案。本文可以帮助您评估解决方案的价值和有用性。

主题:

  • 挑战
  • 什么是无代码/低代码开发*台
  • 传统瀑布模型和手工编码与低代码/低代码开发*台的比较
  • 例子
  • 我的想法
  • 限制
  • 摘要

挑战

用户的业务需求

IT 专业人员有许多工作要做。根据凤凰计划,有业务项目、运营项目、变更和未计划的工作。如何对任务进行优先排序以及快速适应市场趋势可能具有挑战性。

缺乏解决问题的技能

用户最了解业务流程。在许多情况下,他们可以指出瓶颈,甚至提出解决问题的想法。然而,他们往往缺乏实现这一想法的 IT 技能。

遗留系统现代化

随着客户行为的改变,企业也改变了他们的规范和业务应用。您拥有不是为移动设备构建的传统系统。他们可能不是为网络而建的。例如,在疫情期间,现代工作空间和在家工作的想法变得流行起来。最重要的是,瀑布模型可能需要更长的时间来适应变化,因为流程是连续的。这种方法没有考虑到随着项目的进展,已定义需求的变化。

什么是无代码/低代码开发*台?

低代码/无代码开发*台是可视化软件开发环境的类型,允许公民开发人员拖放应用程序组件,连接它们并创建移动或 web 应用程序。这些*台减少了传统手工编码的数量,加快了业务应用程序的交付。随着技术转型的推进,云化已经大众化。基于云的低代码开发*台已经变得流行。

传统瀑布模型和手工编码与低代码/低代码开发*台的比较

在过去,应用程序开发有线性顺序阶段可循。以图书馆目录为例,整个过程是单向的,包括概念、启动、分析、设计、构建、测试、部署和维护等阶段。更不用说有时结果和期望可能不一致。即使使用更现代的开发方法,比如敏捷开发,在第一个最小可行产品(MVP)交付给用户之前,可能会经过相当长的时间。

低代码开发的开发体验是“所见即所得”,你可以在开发过程中很早就体验到实际工作的 app。通过这种方式,用户可以轻松地为他们的图书馆目录应用程序添加新功能,并确保概念和交付内容保持一致。

来源:电力应用和传统应用开发方法的区别

来源:电力应用和传统应用开发方法的区别

来源:电力应用和传统应用开发方法的区别

例子

我从不同的客户那里看到了很多很好的例子,其中大部分来自用户。我列出了一些适用于大多数公司的方法:

事实上,所有的用例都可以通过手工编码来实现。不同之处在于来自公民开发者的构思和实现。

**Feature:** Replace paperwork or information located in different systems**Business Impact:** Avoid data silo, collect more data, learn the insight, and optimize the business process**Scenario:** A customer survey app to replace social media such as LINE. An inspection app to replace paper documents and cameras, embedded video and audio features to collect different types of information.
**Feature:** Build a business process to instruct the user following the guideline**Business Impact:** Decrease loss and waste**Scenario:** work order, spare parts management, instrument management, inventory check
**Feature:** Build a project platform for announcement, notification, and follow-up**Business Impact:** Improve cross-team collaboration, communication, and efficiency**Scenario:** Projects, Order Tracking

思想

场景选择这是最重要的部分。在选择没有可靠商业价值的场景时要小心。我有一个客户对这个想法非常兴奋,希望实现一个午餐订购应用程序,这样办公室的管理员就不需要每天手动为同事记笔记了。我问客户:即使一切顺利,你认为公司批准这个预算的可能性有多大?企业使用诸如 ROI 和预算等语言。区分有形价值和无形价值很重要。假设应用程序在很短的时间内就准备好了,并且用户喜欢它,我们不能忽视商业价值应该是最重要的因素这一事实。

此外,我建议最好的场景是解决业务流程中的一个痛点,以便帮助组织实现最大的效率。例如,我正与一个客户合作,将低代码开发*台用于他们的 ERP 系统,通过移动应用程序和 API 使系统现代化。在引入该*台之前,该员工需要携带笔记本电脑和摄像机来定位和清点办公楼中的资产。拍完照片后,需要时间进行记录和存档。当工人了解到低代码开发*台的强大功能时,包括摄像机的内置连接器、ERP 系统和云存储,他实现了最后一英里的数据输入,简化了业务流程,最大限度地减少了人为错误。这个场景展示了重要性、复杂性以及商业价值,这使得这个案例更有说服力。

限制

信息安全

了解该*台提供的安全产品组合非常重要。例如,*台应该有一个管理中心来管理所有的流量。此外,对企业内的数据源和连接器进行分类,以避免数据丢失。建议建立一个卓越中心,不仅帮助企业实现*台的价值,还可以抵御数据和 It 系统的内部和外部威胁。

成本管理

不仅是财务成本,还有时间成本。在台湾,有大量的工程人才可供雇佣,因此管理层倾向于认为雇佣人才并自行开发和定制系统更具成本效益。与订阅模式相比,它不仅在短期内为公司节省了资金,还将资产保留在了组织内部。然而,如果组织可以让业务用户满足自己的需求,那会怎么样呢?这样,编码人员可以专注于处理更复杂的问题,解决更多的问题。另一方面,随着客户行为的改变,企业必须改变他们的业务应用程序,但是遗留系统不是为移动或 Web 而构建的。然后,是迁移到新系统还是重新开发遗留系统就成了一个难题。我曾与一位客户合作,他很久以前自己开发了电子邮件系统,为了满足业务需求,他别无选择,只能搬到 SaaS。迁移一个拥有成千上万用户的系统是一个巨大的挑战。在评估成本时,企业还应该考虑除金钱以外的成本类型。

配置

低代码开发*台的目标受众以前是公民开发人员,而不是专业开发人员。专业开发人员熟悉各种 IDE(集成开发环境)和命令行界面,可能不喜欢图形用户界面。在尝试了低代码开发*台后,我得到了用户的反馈,他们说“这种方式太慢了,我宁愿手工编码!”。另一方面,它降低了那些不熟悉编码工具的人的进入门槛,甚至鼓励他们创造更多的业务场景。当引入低代码开发*台时,企业有一个清晰的定位是很重要的,避免*台成为 It 专业人员维护的另一个麻烦系统。

结论

低代码开发*台鼓励公民开发者自己通过数字工具解决业务挑战。随着图形用户界面的进步,他们在日常工作中更加亲力亲为。我相信这个新概念有助于来自商业和 IT 组织的用户进行更多的对话,从而获得更多的理解。当他们开始说同一种语言并发现信息差距时,企业将走上成功之路。

最初发布于https://wanchunghuang . com/how-to-make-the-most-low-code-no-code-development-platform/2021。

保持联系

  • 关注我在媒体上的更多类似的故事
  • LinkedIn 上连接

如何使主题模型可解释:3 个新想法

原文:https://towardsdatascience.com/how-to-make-topic-models-interpretable-3-new-ideas-f594518c4b9c?source=collection_archive---------21-----------------------

实践教程

调整 LDA 主题模型输出的三种创新技术

主题建模是一种无监督的机器学习方法,它扫描一组文档,检测其中的单词和短语模式,并自动聚类单词组和最能表征一组文本响应(或文档)的类似表达。迄今为止,潜在狄利克雷分配(LDA)已经成为最流行的主题建模技术之一,广泛应用于不同的工业应用中。这里提供了对 LDA 的详细解释。LDA 是应用于一组单词的概率模型,它有两个关键输出:

I .来自文档集合的主题列表。每个主题都是单词(经常共存)的集合,其形式是每个主题的词汇的概率分布。

图片由 Divya Dwivedi [ 来源

二。每个文档的已识别主题的概率分布。

大样本的概率分布通常是包含数百万数字的巨大矩阵,这使得社会科学研究人员难以提取关键见解。在我的案例中,我分析了来自创新领导力中心数据库的开放式文本回复,该数据库包含 43,000 名领导者,历时 10 年,我们要求他们回答以下问题:你目前面临的 3 个最关键的领导力挑战是什么?*均而言,领导者在 3 个挑战中写了大约 100 个单词(Balakrishnan,Young,Leslie,McCauley,& Ruderman,2021)。

出于本博客的目的,我将使用来自高层管理人员(C-suite leaders)的挑战数据集的子集。我使用 LDA 并实现了不同的技术来更好地解决社会科学研究人员经常问的关于这些数据的问题。

本博客的主要目的是了解提取的主题之间的关系,评估亚组差异,并确定主题流行度是否以及如何随时间变化。下面提供了上述技术的一步一步的过程。

1.主题之间的相互关系(理解提取的主题之间的关系)

2.识别语料库中两个不同子集的主题比例之间有意义的和统计上显著的差异(评估子组差异)

3.科菲·费恩戈尔德·布罗姆伯格(CFB)衡量标准,以确定话题随时间的变化(话题流行率如何随时间变化?)

主题间的相互关联:

LDA 导出的主题可以相互关联。例如,关于遗传学主题的文档更可能是关于传染病主题,而不是天文学或政治。为了在我的数据集中确定这一点,我检查了主题之间的关系。重要的是要记住,文档中所有主题的*均主题概率分布总和必须为 100%。换句话说,如果一个文档在一个给定的主题中排名靠前,那么理论上它们在其他主题中的排名应该靠后。在这种情况下,可以以这样的方式应用二分法文档主题矩阵的机制,即将中值以上的主题概率转换为 1,将中值以下的概率转换为 0。可以为二分法矩阵计算主题之间的相关系数,以确定主题之间的相互相关性。

图 1:高层管理人员的主题相互关系。

上图是关于高层领导面临的挑战的主题之间相互关系的表示。如果领导者报告与“组织人才问题”相关的挑战,他们更有可能报告与“不确定性中的组织准备情况”相关的挑战,反之亦然。

主题之间的联系表示大于或等于. 16 的主题之间的相关性,节点的大小表示主题比例。0.16 是根据 Bosco 及其同事(2015 年)的相关基准选择的,该基准发现应用心理学文献中的场水*效应大小的中值为 0.16。

识别语料库中两个不同子集的主题比例之间有意义的和统计上显著的差异:

领导力挑战数据集包括来自 32 个不同行业的不同领导者。我的项目的目标之一是比较不同行业之间主题比例的差异(例如,制造业(184 名领导者)和金融业(211 名领导者)的高管之间的差异)。我进行了显著性测试和效应大小测试,以检查这种差异是否有意义和统计显著性。由于偏态和不*等的样本量,我选择了曼-惠特尼检验,以确定统计意义。为了确定实际意义,计算了 r 效应大小。根据 Cohen 的标准(Cohen,1988;1992).基于这一分析,6 个主题中有 3 个显示了教育和制造业领导者之间的显著差异。

表 1:教育与金融行业领导者的话题比例和统计数据

图 2:教育和金融服务领导者的话题概率

科菲·费恩戈尔德·布罗姆伯格(CFB)用于识别话题随时间变化的衡量标准:

CFB 分数是对一组加权比例的可变性的度量。分数范围从 0 到 1,数值越高表示可变性越高。形式上,科菲测度 C({p1,…,pn},{w1,…,wn})由以下公式给出:

其中{p1,…,pn}是一组比例,{w1,…,wn}是一组权重,{p1,…,pn}是一组在以下约束条件下产生最大方差的比例:

43,000 名领导者的挑战数据集是从 2010 年至 2020 年收集的。为了分析过去十年挑战数据集的主题变化,我计算了每个主题的 CFB 度量。下图显示了 2010 年至 2020 年挑战主题的 CFB 指标。

图 3:****CFB 2010 年至 2020 年高管

为了更好地理解为什么 CFB 高管级别的得分差异更大,我们按年研究了挑战。在领导组织层面,从 2014 年到 2018 年,在“动态商业环境”和“战略责任”挑战方面观察到了轻微的波动。尽管很难解释为什么会出现这种情况,但对于高管来说,这两种挑战一直都很大。

图 4:随着时间的推移,高管模型的*均主题比例%

Bovens、Chatkupt 和 Smead (2012 年)实施了 CFB 衡量标准,以计算欧盟寻求庇护者承认率的可变性。实现在 Mathematica (版本 8)中。点击此处查看 Mathematica 笔记本,其中包含用于计算 Bovens、Chatkupt 和 Smead (2012)中出现的科菲测度的函数。

主题建模是我最喜欢的探索文本数据主题的方法之一。在分析主题建模结果时,除了上述思路之外,还有不同的方法。上面解释的技术对我在 I/O 心理学领域的研究很有用。如果你有任何其他关于主题建模结果的有趣想法或提示,请在下面的评论中告诉我。

参考文献:

Balakrishnan,Young,s .,Leslie,j .,McCauley,c .,& Ruderman,M. (2021)。领导力挑战阶梯(LCL)技术报告。北卡罗来纳州格林斯博罗:创造性领导中心。

f .博斯科、h .阿吉尼、k .辛格、j .菲尔德和 c .皮尔斯(2015 年)。相关效应大小基准。《应用心理学杂志》,100 卷 2 期,431–449 页。

Bovens,l .,Chatkupt,c .和 Smead,L. (2012 年)衡量欧盟庇护结果数据中的共同标准和*等责任分担。欧盟政治

科菲,议员,费恩戈尔德,硕士和布罗姆伯格,J. (1988 年)。比例间可变性的赋范度量。计算统计&数据分析,7(2),127–141。

科恩,J. (1988)。行为科学的统计功效分析。新泽西州希尔斯代尔:劳伦斯·厄尔鲍姆联合公司。

科恩,J. (1992 年)。能量引丨爆丨器。《心理通报》,112 卷 1 期,第 155–159 页。

如何用 Python 制作不烂的词云

原文:https://towardsdatascience.com/how-to-make-word-clouds-in-python-that-dont-suck-86518cdcb61f?source=collection_archive---------4-----------------------

用 python 制作美丽而有意义的单词云的简短教程

张秀坤·施罗德在 Unsplash 上拍摄的照片

动机

在最*一次对总统就职演说的 NLP 分析中,我发现结果很有趣,但我意识到大多数人不会被这些演讲所强迫。我通常认为词云可能是可怕的,但我认为它们在这里是有意义的——为了让 TF-IDF 的结果更容易立即使用,我从 TF-IDF 对拜登、特朗普、奥巴马和布什的就职演讲的矢量化中创建了词云。

作为自然语言处理工作流工具的词云

本教程的重点是学习如何在视觉和基于内容的层面上制作不烂的单词云。网上有很多免费的工具供非程序员制作 word clouds,但是在 NLP 项目中迭代参数时可视化 python 管道中的数据是评估决策结果的一种有效方法,并且可以向非技术利益相关者展示您的过程。有了视觉设计背景,我发现开箱即用的单词云包有点可怕,所以我会提供一些调整,让你的单词云不那么糟糕。

如何在 Python 和 Jupyter 笔记本里做一个字云,一步一步来:

这是一个概述,但是我会随着您的继续深入下去。

  1. 安装 wordcloud 包。
  2. 将 wordcloud 和 matplotlib 导入笔记本。
  3. 使用 TF-IDF 值创建术语文档矩阵(可选步骤)
  4. 使用文本或矩阵运行 Word Cloud。
  5. 调整设置,让你的字云不吸。
  6. 包装在一个函数中并迭代。

开始了。

  1. 安装 wordcloud

如果您使用 anaconda,请在终端中键入以下内容:

conda install -c conda-forge wordcloud

备选方案此处

2。导入包

import matplotlib.pyplot as plt
from wordcloud import WordCloud

3。使用 TF-IDF 值创建术语-文档矩阵(可选步骤)

你绝对不需要一个 TF-IDF 矩阵来构建一个词云——你可以只使用你想要构建一个词云的文本。然而,让你的词云不糟糕的一个方法是使用更有意义的数据集——一个经过 TF-IDF 处理的数据集。使用 TF-IDF 矩阵的优势在于,您可以控制您在词云中查看的词的类型,而不是最常用的词,您可以查看最独特的词。甚至使用计数矢量器并在制作单词云之前调整设置也是一个有效的工作流程。创建 TF-IDF 矩阵的这一额外步骤使比较单词云更有意义,并且有助于解释调整 nlp 工作流中的设置的效果。

要了解如何生成 TF-IDF 矩阵,您可以在这里查看我以前的文章。:

基于我的 TF-IDF 矩阵,我想要一个数据帧,其中每一列是一个文档,每一行是一个单词及其每个文档的 TF-IDF 值。

# Prep TF-IDF Matrix for Word Cloudsdata = df.transpose()data.columns = ['document_bush_2001', 'document_obama_2009', 'document_trump_2017', 'document_biden_2021']data.head()

这是我想要使用的数据的形状:

4。运行文字云。

一旦你有了 TF-IDF 矩阵,你就可以使用 wordcloud 来生成频率,使用 matplotlib 来绘制。

wordcloud = WordCloud().generate_from_frequencies(data['document_biden_2021'])plt.imshow(wordcloud)

现成的结果如下所示:

除了大小和轴的包含,单词的颜色大多难以辨认,并且与数据集不相关。字的大小被调整了,这很好,但这并不好。

5。调整你的设置,让你的 WordCloud 不烂。

除了尺寸和移除轴之外,还有一些额外的考虑事项:

色彩——我是一个传统主义者,尽可能少用色彩来表达我的观点。对我来说,白色或灰色背景上的黑色文字效果很好。我不认为根据 TF-IDF 的一个数据集同时使用颜色和大小来区分单词是必要的。然而,如果你要用这种颜色来代表另一个有相同单词的数据集,那对我来说是可行的。例如,我会支持颜色的使用,如果在后面加上另外一个信息,比如术语频率或逆文档频率。

我喜欢绘画通常的工作方式,因为你第一眼就能理解图像的想法,但当你细想时,你会理解得更多。我认为文字云可以这样工作,所以我喜欢增加页面上的字数,因为它可以让人们第一眼就简单地理解文档,然后进一步深入并停留在文档的细节上。

font_path — 我讨厌现成的字体,如果有选择的话,我会坚持使用 arial 或 helvetica 字体,尤其是像 word cloud 这样看起来“现代”的可视化字体。

# change the value to black
def black_color_func(word, font_size, position,orientation,random_state=None, **kwargs):
    return("hsl(0,100%, 1%)")# set the wordcloud background color to white
# set max_words to 1000
# set width and height to higher quality, 3000 x 2000
wordcloud = WordCloud(font_path = '/Library/Fonts/Arial Unicode.ttf', background_color="white", width=3000, height=2000, max_words=500).generate_from_frequencies(data['document_biden_2021'])# set the word color to black
wordcloud.recolor(color_func = black_color_func)# set the figsize
plt.figure(figsize=[15,10])# plot the wordcloud
plt.imshow(wordcloud, interpolation="bilinear")# remove plot axes
plt.axis("off")# save the image
plt.savefig('biden_wc.png')

这里有一个不烂的词云:

有几件事我可以做,比如步长,但是我觉得对我的目的来说没有必要。你也可以看看 wordcloud 的例子库,在这里找到更多的。

6。包装在一个函数中并迭代。

一旦我有了我喜欢的设置,我就把它打包成一个函数。随着分析的进行,我可能会迭代我的词云来评估我的 TF-IDF 设置,比如 max 和 min tf,或者关注特定的词类——名词、形容词等。为了加速我的过程,我可能想在函数中改变输出的宽度和高度,但是这是一个很好的方法来感受你在 nlp 中所做的决定。

filenames = ['bush_2001_.png', 'obama_2009_.png', 'trump_2017_.png', 'biden_2021_.png']def word_cloud(data, filenames):
    def black_color_func(word, font_size, position, orientation, random_state=None, **kwargs):
        return("hsl(0,100%, 1%)")
    columns  = list(data)for i in range(4):
        wordcloud = WordCloud(font_path = '/Library/Fonts/Arial Unicode.ttf', background_color="white", width=3000, height=2000, max_words=500).generate_from_frequencies(data[columns[i]])
        wordcloud.recolor(color_func = black_color_func)
        plt.figure(figsize=[15,10])
        plt.imshow(wordcloud, interpolation="bilinear")
        plt.axis("off")
        plt.savefig(filenames[i])# plot the wordcloud
plt.imshow(wordcloud, interpolation="bilinear")# remove plot axes
plt.axis("off")# save the image
plt.savefig('biden_wc.png')

这里比较单词云:

拜登 2021 就职演说词云

特朗普 2017 年就职演说词云

奥巴马 2009 年就职演说词云

布什 2001 年就职演说词云

在这里打开这项研究的结果:

https://anupamagarla.medium.com/comparing-inaugural-addresses-democracy-is-to-dreams-as-biden-is-to-trump-8a1aaeba5f9c

如何让文字云让人不会讨厌

原文:https://towardsdatascience.com/how-to-make-word-clouds-people-wont-hate-9a465c1b63ab?source=collection_archive---------18-----------------------

讨厌的人会讨厌文字云。但它们仍然是有用的可视化,你可以让它们变得更好。

照片由NOAAUnsplash

单词云:它们听起来很轻,很蓬松,很有趣。它们是可视化文本数据中术语频率的一种流行方式。但数据评论员长期以来一直批评这些方便的图形,如“词云是蹩脚的】“词云:我们不能让它们消失,所以让我们改善它们”,以及颇具攻击性的标题“词云被认为是有害的。”哎哟。

这些人对词云有什么意见?如果使用不当,它们确实会有问题,但是有办法让它们变得更好。让我们来看看对 Word Cloud 的批评,看看我们如何绕过它们的潜在陷阱,特别是当您使用 Alteryx Designer 和 Alteryx Intelligence Suite 的文本挖掘调色板中的 Word Cloud 工具时。

图片经由 GIPHY

大多多云?对词云的批评

对词云有哪些常见的批评?这里有一个 TL;上面链接的文章的博士:

  • 词云通常共享不言自明或显而易见的信息。产品评论的文字云可能会以大字体显示产品名称,因为这些名称经常出现——但这对浏览者来说不是有用的洞察力。而且,如果不删除它们,停用词(英语中频繁出现的词,如“the”、“a”或“an”)也会使词云变得杂乱,从而难以看到重要的词。
  • 单词云通常孤立地显示单个单词,忽略了有价值的上下文和周围的叙述。它们将复杂的文本数据减少到最低限度——也许太简单了。观众必须弄清楚单词显示的意义,他们可能会得出错误的结论。
  • 字体大小不能清楚地表明单词的实际频率;更大的字体意味着一个单词出现的频率更高,但进行更细微的比较或排名是很困难的。

这些作者提出了一些很好的观点。我们可能都曾尝试创建过包含无用单词或不为数据提供故事的单词云。

那么,我们如何解决词云的这些缺点呢?考虑到它们有时是一种以视觉上引人入胜的方式总结文本数据的好方法。

图片经由 GIPHY

一连串的停用词

你可以使用一些策略来解决你的单词云的这些问题。让我们来看看其中的一些。我将使用一个我之前用来演示情感分析的数据集;它包含了对服装的评论。

首先,我们可以相当容易地处理自显和停止词的问题。在 Alteryx Designer 中,一定要在你的 Word Cloud 工具之前设置一个文本预处理工具。然后,在字云工具中,一定要选择原字段名后带有 _processed 的文本字段;我已经忘记这么做很多次了!在预处理步骤中,您可以删除数字、标点符号和停用词。

默认停用词来自 spaCy,该工具底层的 Python NLP 包。但是,您可以添加自己的停用词来删除一些明显的术语,这些术语不会帮助观众从词云中获得意义。

下面,我已经从单词 cloud 中删除了“top”和“shirt ”,因为这个单词 cloud 将只代表服装评论的“tops”类别。在单词 cloud 中突出显示“top”和“shirt”不会帮助我们理解人们对它们的看法。

作者图片

显然,您应该小心省略默认停用词之外的其他词,这样您就不会无意中歪曲您的数据,但我会为查看者提供上下文,以确保他们知道这个词云仅限于 tops 的评论。

图像通过 GIPHY

你觉得那朵云像什么?

在我们确保单词云中只包含有用的、相关的单词之后,我们如何确保观众提取出我们希望在可视化中分享的有意义的故事呢?看看下面的云这个词,它代表了所有包含“面料”这个词的负面服装评论的文字。这里有哪些关键的要点,甚至是一些有趣的观察结果需要跟进?很难说。

作者图片

根据你的词云的主题和你想要分享的故事,拥有多个词云可能更有意义。例如,如果我的目标是分享不同服装类别(例如,上衣、连衣裙、裤子)的主要客户反应,那么首先将我的数据集和评论文本划分到这些类别,然后创建单词 clouds 可能更有意义。或者,我可以按照主题(例如,面料、尺寸)和/或情感分析分数(即,正面或负面评论)来划分评论。

通过更小的相关词分组,浏览者可以集中在每个主题的关键点上,而不必研究所有的词并找出一个总体信息。正如一项调查研究所说,“最好将这些单词组织成有意义的区域,并通过空间或颜色分组,在视觉上以不同的组来显示这些区域。”

提及面料的负面评论词云,按服装类型分组(从左至右:连衣裙、上衣、夹克;图片作者)

如果我们把负面评论的文本按服装类型分类,如上所示,我们现在马上就能看到可能引人注目的差异。当顾客在负面评论中提到面料时,顾客也在评论尺码 XS 的连衣裙;有些上衣有些“奇怪”;夹克的颜色尤其引人注目。

不幸的是,大多数这种分组必须手动进行,或者至少是半手动进行。在 Designer 中,您可以使用公式和/或过滤工具来设置“主题”标准,以确定将哪些文本项输入到每个词云中。您还可以在 Word Cloud 工具中为不同的主题选择不同的配色方案,这样图像在视觉上就很明显。

您还可以使用主题建模来帮助识别关键主题,然后使用主题建模分数来划分您的文本数据。如果你想了解更多关于主题建模的内容,这里是我们系列教程的开始,一个使用它的 SFW 演示,还有一个也许是 NSFW 演示

图像通过 GIPHY

当云模糊时:频率和排名

词云可以变得更有用,但有时你可能想要一个不同的选择。例如,当查看者能够更详细地了解文本数据中不同单词的相对频率和/或排名非常重要时,单词云可能会让您失望。显示关键词的条形图可能是更好的选择。

例如,也许你想深入了解年龄在 18-34 岁的顾客的意见,尤其是他们对你的上衣的积极评价,这样你就能看出他们真正喜欢哪些特点。下面的条形图显示了一种查看他们最常用词排名的方法(一些明显的停用词——衬衫顶级爱情伟大——添加到默认列表中)。尺寸和合身似乎是快乐顾客讨论的流行标准;很容易看出,在这种格式中,尺寸和合身比“舒适”更常被提及。

作者图片

从你的文本中创建一个这样的条形图需要更多的步骤,正如你在这篇文章的原始版本所附的工作流程中看到的。“拆分为行”上设置的“文本到列”工具可以将文本审阅转换为单独的行;有了汇总工具和交互式图表工具,条形图可以很快地组合在一起。

本文还展示了一个用于可视化文本的热图的很酷的例子(查看第 2 项)。

天气监视:小心前进

虽然有些人可能不喜欢单词云,但明智地使用它们肯定是可能的。与任何数据可视化一样,我们的目标是将信息有效地传达给浏览者,因此当务之急是,您的天空应该是晴朗的!

Alteryx 数据科学博客 上找到本文引用的 Alteryx 工作流。

推荐资源

  • 阅读一些用于可视化文本数据的单词云替代方案
  • 上面提到的这篇文章,对词云进行了基于研究的批判,并对它们提出了深思熟虑的建议。
  • 本教程展示了如何使用 Python 构建单词云,这是一种可以用 Python 工具构建到 Alteryx 工作流中的方法。
  • 关于各种数据可视化的更多信息,请查看我们的 Data Science Mixer 播客,其中有 data viz 专家和作者 Alberto Cairo 我们有小插曲长插曲供你欣赏!

原载于 Alteryx 社区 数据科学博客

如何让你的电脑与 Python 对话

原文:https://towardsdatascience.com/how-to-make-your-computer-talk-with-python-63f6c6eb534a?source=collection_archive---------4-----------------------

你成为亿万富翁花花公子的第一步

你的机器人管家。图片由史蒂芬·米勒

如果你是《钢铁侠》等电影的粉丝,你可能会幻想拥有自己的贾维斯。在这篇文章中,我将向你展示如何开始制作你自己的电脑助手。我们将通过一点编程和一些智能 python 包在引擎盖下做数据科学来做到这一点。

现在,制作像超级智能人工智能这样复杂的东西是很难的,对我来说太难了,以至于我无法在一篇帖子中完成,甚至很可能是在一般情况下。然而,我们能做的是把这个问题分解成更小的部分,使问题看起来更简单。这是你应该在你的每一个项目中做的事情,这样才不会一下子陷入所有复杂的事情中。

从我对这个主题的简短思考中,我相信我们可以将一个超级智能的人工智能助手分成四个主要部分:

  1. 文本到语音转换(获得响应)
  2. 语音转文字(要东西)
  3. 一些计算来理解我们的问题并做出回应
  4. 将反应转化为现实世界中的行动

在今天的帖子中,我将重点介绍我们的计算机助手的文本到语音方面,它允许我们的计算机与我们交谈。如果一切顺利,我将在未来继续撰写这篇文章,让我们的助手变得更加复杂和有用。

查找文本到语音库

现在,用 python 做这样的事情的一个巨大的好处是,我们有大量的库可以用来快速完成工作。毕竟,如果我们从头开始开发每一点,我们会在这里呆很长时间,以至于我们永远也做不了任何事情。让我们站在巨人的肩膀上,使用 python 包。

对于文本到语音转换,有几个 python 包脱颖而出:

  • 谷歌文本到语音(gTTs),以及
  • pyttsx3(我不知道那到底代表什么)。

Google Text To Speech 是一个 Python 库,用于与 Google Translate 的 text to speech API 接口。它具有谷歌自己的文本到语音应用程序的性能,但需要使用互联网连接。

pyttsx3 ,另一方面,是一个文本到语音转换库,它寻找预装在你的*台上的文本到语音引擎并使用它们。因此,它离线工作。

以下是它在主要操作系统上使用的文本到语音转换引擎:

  1. Windows 上的 SAPI5

2.MacOSX 上的 NSSpeechSynthesizer

3.在每隔一个*台上讲话

看着这两者,我不希望我的助手依赖于谷歌或在线连接来工作。我更愿意使用 pyttsx3,让所有东西都在我自己的机器上运行。

设置项目

现在,在我们开始运行一切之前,让我们设置我们的项目。

我们将通过文本编辑器和终端做所有的事情。如果你不知道这是什么意思,那么我向入门者推荐的文本编辑器是 vscode ,终端通常内置在你的文本编辑器中(就像在 vscode 中一样),或者是你计算机上的一个叫做“终端”或“cmd”的程序。

现在,我希望您打开终端,将目录更改为保存项目的位置,例如

cd ~/projects

接下来,我们需要创建一个目录来存储我们的项目。这完全由你决定,但我希望我的助手叫罗伯特。因此,我正在创建一个名为“robert”的新目录,然后用

mkdir robertcd robert

你可以把名字改成你喜欢的任何名字,比如 Brandy 或者 Kumar 什么的。

接下来,我们需要让 python 开始运行。为此,我们需要安装 python 3。如果您没有安装,请参见https://www.python.org/获取安装说明。我们还需要创建一个 python 虚拟环境。如果你想了解更多,请看这里的我最*的一篇文章

假设您安装了 python,您可以在终端中用

python3 --version

现在,您应该能够使用以下命令在 robert 目录中创建 python 虚拟环境:

python3 -m venv venv

注意,如果你安装的 python 版本叫 python python3.7 或者 python3.9 或者别的什么,那就用那个

然后,您应该能够通过以下方式激活您的虚拟环境:

(在 MacOS 和 Linux 上)

source venv/bin/activate

或(Windows)

venv\Scripts\activate

我们现在需要安装我们需要的软件包。为此,我们将创建一个 requirements.txt 文件。打开你最喜欢的文本编辑器,例如 vscode,或者,如果你喜欢冒险,打开你的“robert”文件夹,现在就创建这个文件。

对于我们的项目,到目前为止,我们只需要 pyttsx3。简单。现在让我们将它添加到 requirements.txt 文件中,如下所示

接下来,让我们使用 pip 安装我们的需求

pip install -r requirements.txt

使用 pyttsx3

现在一切都安装好了,让我们开始使用 pyttsx3。为了了解该怎么做,我查阅了这里的文件。

然后,您可以通过创建一个名为speech.py的文件并添加以下代码来制作一个很好的示例:

我们首先导入 pyttsx3 来加载它的所有类和变量。然后我们初始化语音引擎,设置我们想要的声音,然后是我们想要说的文字。我们终于用engine.runAndWait()说话了。

然后,我们可以在终端中使用以下命令运行该文件:

python speech.py

摆弄这个,改变text_to_say变量。你应该想说什么就说什么。

很酷的调整

现在我们有了一些工作,让我们给我们的助手一些调整。Pyttsx3 可以让我们调整声音和速度。

在上面的例子中,您可以将 voice_num 更改为一个不同的数字来获得一个新的语音。根据我的测试,这似乎是*台相关的(可能取决于你的*台是否有 SAPI5NSSpeechSynthesizerespeak )。

我创建了这个巨大的文件(当很多机器人用奇怪的口音跟你说话时,你会明白为什么)来帮助你决定什么声音最适合你。一旦你找到你喜欢的声音号码,就用在voice_num变量中找到的号码替换掉。

后续步骤

祝贺你到达终点。如果你有任何问题或者只是想打个招呼,请在下面发表。

如果你想进一步阅读,并对即将发布的帖子有所了解,我建议你查看下面的链接。

在我的下一篇文章中,我将关注语音转文本,这样我们的助手就可以响应我们的命令了🤖。给我一个关注,以确保你不会错过它。

如何使您的数据目录成功

原文:https://towardsdatascience.com/how-to-make-your-data-catalog-successful-3df6894f1975?source=collection_archive---------22-----------------------

从数十家公司学习如何让您的数据目录成功

约书亚·索蒂诺在 UNSPLASH 上拍摄的照片

衡量数据目录的成功只有两个目标:1)采用,2)客户满意度。如果你搞定了这两个,你就成功了。

我是领先的开源数据目录 Amundsen 的共同创建者,该目录被 35 多家公司使用,包括 Instacart、Square、Brex、Asana 等等。在这篇文章中,我分享了从 Lyft、其他 Amundsen 采纳者和 Stemma 客户那里学到的关于数据目录安装成功的关键知识。

我们在 Stemma 中吸收了一些知识,但是这篇文章吸收了产品中还没有吸收的知识。这些学习侧重于如何推出产品,如何获得广泛采用,以及如何衡量成功。

1.区分人物角色及其用例的优先级

一个数据目录有许多用户角色和用例。成功的安装优先考虑首先关注哪些角色和用例。这是数据目录中最常见的角色和用例的简化视图。首先从哪个角色开始并不重要,重要的是从特定的目标用户群开始。

按作者分类的图片:数据目录中最常见的角色和用例

2.分阶段推出

在这一节中,我将深入探讨启动数据目录的最佳实践。

第一步:确定一小组表格来获得 alpha 用户的反馈。

  • 该集合可以是公司内最常用的表(通常称为“核心”表),也可以是公司内的一个领域,如营销、增长或财务等。
  • 更常见的是,我看到核心表是被选择的集合,部分原因是它们最有影响力,但也因为通常有一个中央数据团队负责维护它们。

步骤 2:在这些表上填充 MVP 元数据

  • 这是大多数数据目录失败的地方。为了让用户从他们身上获得价值,描述,标签,所有者等等。需要策划。然而,如果没有大量的数据管理员,这是不可持续的,而且这些文档很快就会过时。这是数据目录失败的最大原因。通过为大部分数据选择自动化的数据目录,并仅管理最有影响力的数据,可以避免这一缺陷。
  • 对于部落知识,在你必须的地方,与一群数据生产者和消费者进行“文档即兴会议”会有所帮助。你甚至可以为那些提交最多文档的人提供奖励(比如礼品卡)!

第三步:向 5-20 名 Alpha 用户发布

  • 阿尔法用户最好是超发声用户。这些将来自您之前选择的优先角色。当您向更广泛的受众发布时,这些用户将成为 data catalog 的忠实支持者。
  • 整合反馈和迭代。有些类型的反馈在这里非常有价值,比如有人说,“哦,我们已经在这个电子表格中有了这些元数据,我们应该把它们也放在这里。”

第四步:向优先角色的所有用户发布测试版。

  • 将你的测试版集中在你的优先用户(例如数据消费者)上是很重要的。一个常见的错误是通过向所有角色开放来淡化发布的焦点。这并不意味着你应该从数据目录中锁定其他的角色,这只是意味着你应该首先关注哪些角色。
  • 如果您能够达到成功指标目标,则升级到 GA。在后面衡量成功的章节中会有更多的介绍。

3.大量收养的土地

为了更好地被采用,这里有一些我见过的最佳实践:

  • 更新松弛频道标题,人们在那里互相提问。产品功能在这里非常有用,例如,如果您的目录具有松散集成,并且可以自动将这些对话链接到目录。
  • 嵌入新员工培训。标记每个领域的数据集(营销、增长等。)可以帮助新员工快速进入他们的领域。如果您已经接受过培训,请展示目录作为切入点。在 Lyft,我们让所有新入职的技术人员在入职时使用一个指标。他们使用 Lyft 的数据目录来发现和理解该任务的正确数据。
  • 与其他产品的联系。创建各种数据工具之间的链接。例如,自动填充填充表的气流 DAG 和数据目录中的表页面之间的链接(反之亦然)。另一个有效的链接是数据目录中的表页面和用于生成表的代码的链接。
  • 在小组或公司会议上展示产品目录。在面向角色用户的全体会议上做一个 5 分钟的简短演示。教育、回答问题、感谢你的 alpha 用户——通过创造更多的认知和学习的机会,这是非常有影响力的。

4.衡量成功

就像我前面说的,采用和客户满意度是唯一重要的两个目标。我进一步探讨了对每一个指标使用什么样的具体指标定义:

1。采用:

  • WAUs: 我建议从周活跃用户(WAUs)开始,而不是日活跃用户或月活跃用户。常见的使用频率是每周,而不是每天或每月。
  • 目标穿透率:80%。在你的目标人物中,高渗透率是 80%。

2。客户满意度(CSAT):

  • 定期进行带外测量。根据我的经验,定期(每 3 或 6 个月)测量的带外(非产品内)CSAT 反馈比在数据目录产品内获得反馈更好。我了解到,当在产品中衡量反馈时,最*的体验可能会玷污用户共享的反馈。

还有一些公司经常考虑的其他指标:文档质量、搜索质量等。然而,我的建议是一开始就坚持核心指标。随着您的数据目录逐渐成熟,并且随着时间的推移您将更多的元数据吸收到您的数据目录中,您可以使用这些特定的指标来跟踪这些不同改进的影响。

我希望本分步指南有助于您和您的团队了解如何导航数据目录安装,并使您的数据目录获得成功。正确的数据目录可以大大减少管理的开销。然而,无论您选择什么样的数据目录,上述步骤仍然对确保您的成功起着巨大的作用。

想了解更多关于 Stemma 的完全托管数据目录的信息吗?查看演示并开始使用 stemma.ai

为什么您需要为您的数据管道设置 SLA

原文:https://towardsdatascience.com/how-to-make-your-data-pipelines-more-reliable-with-slas-b5eec928e906?source=collection_archive---------12-----------------------

意见

如何设定贵公司对数据质量和可靠性的期望

图片由 Shutterstock 上的 Yevgenij_D 提供,可供拥有标准许可证的作者使用。

对于今天的数据工程团队来说,对实时、准确数据的需求从未像现在这样高,然而破损的管道和陈旧的仪表板却是一个司空见惯的现实。那么,如何才能打破这种恶性循环,做到数据可靠呢?

就像我们 20 年前的软件工程同行一样,21 世纪 20 年代初的数据团队面临着一个重大挑战:可靠性

与以往相比,公司正在吸收越来越多的运营数据和第三方数据。整个企业的员工都在数据生命周期的各个阶段与数据进行交互,包括非数据团队的员工。与此同时,数据源、管道和工作流变得越来越复杂。

虽然软件工程师已经用专业领域(如开发运维及站点可靠性工程)、框架(如服务水*协议、指标和目标)和大量首字母缩写词(分别为 SRE、SLA、SLIs 和 SLOs)解决了应用程序停机问题,但数据团队并没有以应有的努力处理 数据停机

现在是时候让数据团队做同样的事情了:区分优先级、标准化和度量 数据可靠性 。我预计在未来十年,数据质量或可靠性工程将发展成为自己的专业,负责这一关键的业务功能。

在此之前,让我们探索一下什么是数据可靠性 SLA,它们为什么重要,以及如何创建它们。

什么是 SLA?

Slack 的 SLA 保证 99.999 的服务正常运行时间。如果违约,他们会申请服务信用。图片由 Slack 提供。

简而言之,服务水*协议(SLA)是许多公司用来定义和衡量给定供应商、产品或内部团队将提供的服务水*的一种方法,以及如果他们未能提供的潜在补救措施。

例如, Slack 面向客户的 SLA 承诺每个财季 99.99%的正常运行时间,计划停机时间不超过 10 小时,适用于 Plus 计划及以上的客户。如果他们达不到要求,受影响的客户将在他们的帐户上获得服务积分以供将来使用。

客户使用 SLA 来确保他们从供应商那里得到他们所支付的东西:健壮、可靠的产品。对于许多软件团队来说,SLA 是为内部项目或用户开发的,而不仅仅是终端客户。

为什么 SLA 很重要?

让我们以内部软件工程 SLA 为例。如果没有客户向您施压,要求您在合同中承诺某些阈值,为什么还要经历编纂 SLA 的过程呢?为什么不指望每个人都尽力而为,争取尽可能接* 100%的正常运行时间呢?这不就是引入不必要的繁文缛节吗?

一点也不。定义、同意和度量构成可靠软件的关键属性的实践非常有用,并且为内部涉众设定了明确的期望。

SLA 可以帮助工程、产品和业务团队就他们的应用程序中最重要的事情达成一致,并对传入的请求进行优先级排序。有了 SLA,不同的软件工程团队和他们的涉众可以确信他们在说相同的语言,关心相同的度量标准,并且共享一个清晰记录的期望的承诺。

设定那些非 100%正常运行时间的期望值也为增长留下了空间。如果容忍零停机风险,就没有创新的空间。另外,这是不可行的。即使拥有世界上所有的最佳实践,系统也会偶尔崩溃。但是有了好的 SLA,当事情确实出错时,工程师将确切地知道何时以及如何进行干预。

为什么数据可靠性如此重要

图片由蒙特卡洛提供。

同样,对于数据团队及其数据消费者来说,在数据的整个生命周期中定义、测量和跟踪数据的可靠性已经成为一项关键需求。

设置数据可靠性 SLA 有助于在您的数据、您的数据团队和下游消费者(无论是您的客户还是您公司的跨职能团队)之间建立信任并加强关系。如果没有这些明确定义的指标,消费者可能会做出有缺陷的假设,或者依赖关于您的数据*台的可靠性和可信度的轶事证据。换句话说,数据 SLA 有助于您的组织更加“数据驱动”数据。

SLA 还将沟通形式化并简化,确保您的团队和您的利益相关者使用相同的语言并引用相同的指标。由于定义 SLA 的过程有助于您的数据团队更好地了解业务的优先级,他们将能够快速确定优先级,并在事件发生时加快响应速度。

如何创建数据可靠性 SLA

创建数据可靠性 SLA 并遵守它们是一项协作和专业的练习。

让我们先弄清楚一些词汇。根据 Google 的服务水*协议(SLA ),需要明确定义的服务水*指标(sli)、服务质量的量化衡量标准以及商定的服务水*目标(SLO ),即每个指标应达到的目标值或值范围。例如,许多工程团队将可用性作为站点可靠性的一个指标来衡量,并设定一个目标来保持至少 99%的可用性。

通常,对于数据团队来说,创建可靠性 SLA 的过程遵循三个关键步骤:定义、测量和跟踪。

步骤 1:用 SLA 定义数据可靠性

第一步是就可靠数据对您的组织意味着什么达成一致并明确定义。

我建议从设定基线开始。首先对您的数据进行清点,包括数据的使用方式和使用人。评估数据的历史性能,以获得可靠性的基准指标。

您还想从数据消费者那里获得关于他们眼中“可靠性”的反馈。即使对数据谱系有很好的理解,数据工程师也经常会被从他们同事的日常工作流程和用例中剔除。在与内部团队达成可靠性协议时,了解消费者实际上如何与数据交互、哪些数据最重要以及哪些潜在问题需要最严格、最直接的关注是至关重要的。

此外,您还需要确保相关利益相关方——所有对可靠性有既得利益的数据领导者或企业消费者——已经对您正在开发的可靠性定义进行了权衡和认可。

一旦您了解了(1)您正在处理哪些数据,(2)如何使用这些数据,以及(3)谁在使用这些数据,您就能够制定清晰、可行的 SLA。

(如果你仍然不确定这些 SLA 会是什么样子,我强烈推荐阅读这个关于设置数据仓库 SLA 的https://locallyoptimistic.com/post/data-warehouse-sla-p2/系列 。Brooklyn Data Co .的 Scott Breitenother 提供了一个非常强大的入门模板,以及与利益相关者沟通 SLA 的实用建议。

步骤 2:用 SLIs 测量数据可靠性

一旦您有了透彻的理解和基准,您就可以开始关注将成为可靠性的服务级别指标的关键指标。

根据经验,数据 sli 应该代表您在步骤 1 中定义的双方同意的数据状态,提供如何使用和不使用数据的界限,并具体描述数据停机时间是什么样子。这可能包括丢失、重复或过期数据等情况。

您的 SLIs 将取决于您的具体用例,但这里有一些用于 量化数据健康 的指标:

  • 特定数据资产的数据事件数量(N)。尽管这可能超出了您的控制范围,但考虑到您可能依赖外部数据源,它仍然是数据停机的一个重要驱动因素,并且通常值得衡量。
  • 检测时间(TTD):当问题出现时,此指标量化您的团队得到警报的速度。如果您没有适当的检测和警报方法,这可能需要几周甚至几个月的时间。由不良数据造成的“无声错误”会导致代价高昂的决策,对您的公司和客户都有影响。
  • 解决问题的时间(TTR):当您的团队收到问题警报时,这衡量您解决问题的速度。

步骤 3:使用 SLO 跟踪数据可靠性

在设置可靠性仪表板时,数据团队应该更加具体。图片由蒙特卡洛提供。

在确定了数据可靠性的关键指标(sli)后,您可以设定目标,即可接受的数据停机时间范围。

这些 SLO 应该是现实的,基于你的现实环境。例如,如果您决定将 TTD 作为一个度量标准,但是您不使用任何自动化的监控工具,那么您的 SLO 应该低于一个拥有全面的数据可观察性工具的成熟组织的范围。

就这些范围达成一致使您能够创建一个统一的框架,根据严重程度对事件进行评级,并在出现问题时简化沟通和快速响应。

一旦您设定了这些目标并将其合并到您的 SLA 中,您就可以创建一个仪表板来跟踪和报告进度。一些数据团队创建他们自己的专用仪表板,而另一些则使用专用的数据可观察性 解决方案。

实践中的数据可靠性

为数据设置 SLA、SLO 和 SLIs 只是难题的第一部分。当数据事件发生时,我们还需要一种方法来分类和管理事件,以免它们成为下游消费者的一大难题。

为此,我们可以再次向我们在 DevOps 的朋友寻求灵感。大多数工程组织会指派整个站点的可靠性团队来识别、解决和防止停机。在当今的现代数据组织中,当管道破裂和仪表板变得不稳定时,数据工程师往往首当其冲。

为了使事件解决过程更加简单和无缝,我们可以借鉴 SRE 手册,在数据问题出现时进行有效的沟通和分类。

例如,假设您的主管的一份重要报告中出现了陈旧的数据。从一开始,你不确定这条管道是如何断裂的,但是你需要告诉他们管道已经断裂,你的团队正在处理这件事。在您解决这个问题时,您不仅需要不断更新您的数据宕机侦探同事,还需要更新您的关键利益相关方对事件解决流程的了解。

以下是从一些最好的数据工程团队收集到的一些有用的表情符号及其相应的含义,便于交流:

图片由蒙特卡洛提供。

和一些图标来指示事件的严重性:

图片由蒙特卡洛提供

虽然获得可靠数据的手段最终取决于您的业务需求,但拥有一个良好的沟通策略将使您更容易执行 SLA。( Blinkist 分享了他们解决数据宕机的路线图,这里)。

入门指南

我们很兴奋地看到数据可靠性工程 这个专业领域是如何发展的。SLA、SLIs 和 SLOs 是一个很好的起点:它们为测量数据停机时间提供了一个有用的框架,并有助于在整个组织中建立一种信任、协作、数据驱动的文化。

就像 sre 通过自动化支持系统确保应用程序正常运行一样,数据团队也应该拥有自己的专业工具。最好的数据*台不仅会测量数据停机时间,还会通过 端到端的数据可观察性 ,最终帮助从一开始就防止数据停机,让您的团队达到最高的数据可靠性标准。

有兴趣学习如何设置自己的数据可靠性 SLA?伸出手去 巴尔摩西 和其余的 蒙特卡洛团队

如何通过设计使您的数据项目合乎道德

原文:https://towardsdatascience.com/how-to-make-your-data-project-ethical-by-design-99629dcd2443?source=collection_archive---------18-----------------------

一个简单的框架从今天的数据伦理开始

图片由 Riccardo AnnandaleUnsplash 上拍摄

数据是当今公司的命脉。日常运作不仅依赖于有关运营各个方面的持续数据,而且越来越清楚的是,有了足够的数据和正确的分析,以前难以解决的问题就可以得到解决,流程也可以得到改进。毫不奇怪,数据科学目前在 Glassdoor 的 2021 年美国最佳工作名单中排名第二(过去 6 年中有 4 年一直排名第一)。

但正如 2018 年脸书/剑桥分析政治丑闻向世界表明的那样,收集和分析大量数据的现代方法也可能引发伦理问题。丑闻爆发后,整个世界开始形成一种关于数据如何被使用和不被使用的观点,开启了可以被称为数据伦理的时代。

将这一点与旨在限制可以收集多少客户数据以及出于何种目的的现有和新兴立法结合起来,底线是:如果您的公司使用客户数据来做出面向客户的决策,则必须考虑做出这些决策所涉及的道德和法律问题。

培养伦理思维专家

在我的上一篇文章中,我描述了疏忽的数据使用可能导致的各种问题。我还提到了许多框架,数据科学家可以使用这些框架作为开始思考他们的工作可能带来的潜在问题的基础。但是,随着数据越来越成为整个组织决策的驱动力,数据道德意识需要扩展到数据科学团队之外。避免无意的陷阱意味着将每个数据用例的道德规范视为组织流程的一个组成部分。

我工作的公司积极帮助防止公司陷入道德数据陷阱。我们试图将数据使用的伦理注入我们的 DNA。我们公司的每一位顾问都接受过某种程度的数据安全和道德培训。我们最*还成立了一个包容性、多样性、公*和意识(IDEA)小组,面向热衷于思考道德和公*如何影响业务决策的人们。在进行数据项目时,IDEA group(多么有趣的缩写)的想法有助于确保我们的数据科学家了解利用客户数据的道德规范的最新趋势。

道德数据使用框架

通常,公司认为解决道德问题对业务不利,或者以某种方式“破坏”他们所做的事情。但是在我们的经验中,从来不是这样。在我的工作中,我以道德的方式帮助公司用数据达到他们的目标。

为此,我(和两位同事)创建了一个道德风险快速扫描,帮助客户快速评估他们的数据用例是否会导致道德风险。对于尚未设计解决方案的用例,很难评估风险和定义所需的度量,更不用说构建了。然而,道德风险是区分用例优先级和选择方法的关键标准。因此,我们开发了在用例选择和需求收集的早期阶段精确使用的快速扫描。它让我们对项目早期涉及的风险水*和领域有一个感觉,因此在哪些领域需要额外的关注。该框架帮助您将道德规范融入数据项目的设计中。

快速扫描如下所示:

作者为 IG & H 创建的框架

我们设计了快速扫描来提供潜在道德问题点的可视化表示。只需填写与您的案例细节相对应的点即可。

运行中的框架:出租车司机用例

下面是如何使用该框架的一个示例:想象一个出租车服务,它以数字方式监控出租车司机分配和执行的乘坐的许多方面。他们希望开发一种模型,根据这些数据对司机的表现进行评分,并相应地自动调整司机的工资。

让我们讨论一下这个用例在框架的每个维度上的得分:

  • 弱势人群受到冲击?受影响的人通常经济收入低于*均水*,有些人可能只能勉强度日。
  • 受影响的人数多吗?这是一个内部应用,对很多人没有影响(只有公司的出租车司机员工)。
  • ‘人生大事’受影响?该模型的决策将影响生活中的事情,因为它们将影响财务健康和工作保障。
  • 影响个人行为?该模型的决策可能会影响出租车司机的行为,因为它们可能会刺激出租车司机工作更长时间,或者接受往返于他们不舒服的地点。
  • 没有,或者说慢,反馈回路?模型决策的效果会很快显现(每周或每月),因此会有一个快速的反馈循环。
  • 没有人类参与?用例要求自主的绩效评分和薪酬调整,这意味着没有人参与。
  • 数据中的偏差?性能通常是一个主观的概念,因此模型训练所依据的数据可能会有偏差。
  • 使用的个人数据?最后,数据会涉及到细粒度的个人位置数据,被认为是个人数据。

下面是我如何根据这个特定的使用案例填写快速扫描:

作者为 IG & H 创建的框架

对于每个填有红点的区域,必须考虑或采取措施来缓解潜在问题。此外,建议特别注意填有“中等风险”点的区域。下表提供了这种情况下最大问题点的可能缓解措施示例。

快速浏览将注意力集中在项目开始前可以采取的措施和缓解措施上。一旦项目全面展开,随着实际的解决方案和数据需求变得越来越清晰,团队可以通过道德风险评估框架将其评估提升到下一个级别。这进一步从普遍接受的安全、公*、透明和隐私的道德准则方面检查了风险维度。我们从对 36 个著名的人工智能原则文档进行的元研究中提炼出了这些指导方针。

确保数据转换中的道德行为

在转型期间,我公司的数据科学家与行业专家一起工作,以确保数据、分析、技术和业务技能之间的无缝互动。同时,我们确保数据使用得到优化,以有效实现业务目标,而不会违反道德数据使用准则和法规。

在下一篇文章中,我打算使用我们的(更广泛的)道德风险评估框架,根据快速扫描结果阐明我们可以采取的行动类型。使用这些指南,我们可以消除和/或减少已识别的风险,并使人工智能的使用不仅可行,而且可行和可取。

这篇文章(和框架)是我和我的同事曼多·罗特曼和 Floor Komen 共同完成的。它也被发布到我们的 公司网站 ,在那里你也可以下载 pdf 格式的框架,这样你就可以自己使用了。

这篇文章也被发表到 IG & H 的网站上。这是三篇系列文章中的第二篇,你可以在这里找到:第一部分 第三部分

如何让你的数据科学简历脱颖而出

原文:https://towardsdatascience.com/how-to-make-your-data-science-cv-stand-out-9adad32f61cb?source=collection_archive---------48-----------------------

成功简历的 7 个屡试不爽的技巧

Bram Naus 在 Unsplash 上拍摄的照片

如果你有分析背景,吸引招聘人员的兴趣可能不会有太多困难。

对数据科学家的需求激增,但数据科学家的数量远远不足以满足需求:自 2015 年以来,人工智能相关的年度招聘增长了 74%,但预计到 2030 年,全球科技人才短缺将达到 8500 万人(来源:【https://quanthub.com/data-scientist-shortage-2020/】T4)。

考虑到蓬勃发展的就业市场,你可能会认为你不需要在简历上花太多精力。只要相关的东西在里面,人们就不会在意,我说的对吗?不对。

虽然让你的简历受到关注并通过第一个筛选阶段可能并不太难,但从它出现在招聘经理的办公桌上的那一刻起,你只有很短的时间来留下印象(你可能有超过 6 秒的时间,但不会太多)。他们可能每天都会收到几十份简历需要评估,并且会很快浏览一遍。

很长一段时间以来,我一直坐在候选人的位子上,幸福地不知道在我的简历中什么会或不会给人留下印象。随着时间的推移,我从导师那里得到了很好的建议,并学会了在阅读他们的简历时应该注意什么。这些事情可以带来很大的不同。

这里有七个小贴士可以让你的简历脱颖而出。

1.把你相关的工作经验放在最上面

当有人看你的简历时,他们显然是从上面开始的。这是您希望最相关的信息所在的位置。这几行字会让某人决定是继续阅读你的简历还是跳到下一页。所以,如果你有数据科学家的相关工作经验,就放在最上面。

2.首先列出你最*的角色

从当前或最*的工作经历开始列出你的工作经历是一个好主意。同样,人们只会在这一部分花几秒钟的时间,而且需要说明的是,你目前是一名数据科学家,或者不久前还是一名数据科学家。评论者不关心你五年前在做什么。人们会改变职业,在数据科学领域工作五年是一段漫长的时间。

3.简洁

时间很关键。如果你当前的角色描述是一个密集的 10 行段落,那么一个评论者不会阅读它。最多写两行来概括描述你的角色的职责,并用要点来指出具体的项目或成就。

4.要点是你的朋友

如果使用得当,要点可以成为强有力的工具。它们将复杂的信息分解,使其更容易阅读。但是,不要和他们一起疯;每一部分要有三到六个要点。如果你有更多的项目,试着把它们分成包含它们的单个项目,或者选择你认为最能展示你才华的项目。

5.量化你的成就

通过量化你的成就所带来的价值,以面向业务的方式展示你的成就。如果是实实在在的结果就更好了。例如,收入的增加、支出的节省或现有流程的改进。详细点。它将展示你理解业务需求并实现这些需求的能力。

6.选择你的技能

你可能想在你的简历中删减一些技能。清单中的 20 多项技能迫使读者筛选出对他们来说重要的技能。一个更好的主意是让工作描述中明确列出的技能更加突出——如果你有的话——或者只选择你最擅长的技能。关注那些阅读你简历的人会寻找的关键词。如果他们在寻找 NLP 专家,而你就是其中之一,那么让他们容易找到并清楚地陈述出来。

剩下的可以放在其他技能下。但不管怎样,你绝对需要把 X 列为技能吗?例如,如果你上一次用 C++编程是在十年前读研的时候,那么把 c++作为一项技能有多大用处呢?除非 C++是必备技能,不然不多。还有,有些技能是给定的,不需要叫出来。2021 年谁不知道怎么用 Office?

7.限制个人信息

事实是,除非你的爱好与你申请的工作有关,否则面试官并不在乎你是否喜欢旅游或在空闲时间玩 T4 五人制足球。例如,如果这个职位是一家博彩公司的,那么对体育的熟悉可能会让你比其他候选人更有优势。不过,这将是一个小优势,因为在数据科学中,技能是可以转移的,领域知识不是必需的。

然而,个人成就可能会有所不同,因为它们可能会告诉你一些事情。例如,如果你参加了马拉松训练,这可能会说明你的承诺或长期规划能力。

总的来说,不要低估一份好简历的重要性。这是你数据科学面试的第一步。保持更新,不要超过两页——或者三页,根据经验而定。然而,最重要的信息应该在第一页。你简历的第二页就像谷歌搜索结果中的第二页。几乎没有人去过那里。

上面的列表来自我自己的经验,并不详尽。如果你有什么建议想分享,请联系我们或在下面留言!

如何让你的建模过程更有效率

原文:https://towardsdatascience.com/how-to-make-your-modeling-process-more-efficient-89e70259839d?source=collection_archive---------43-----------------------

介绍一种用于数据集初始建模的省时方法

张杰Unsplash 上的照片

在这篇文章中,我将分享一些关于如何有效地开始初始建模的技巧。在花了很多时间测试哪些模型在我的特定数据集上表现最好之后,我想出了一个节省时间的方法,我用它来对我的所有数据集进行初始建模。一旦我能够找出在我的数据集上表现最好的模型,我就专注于这些模型,并开始调整它们的超参数,使它们在我优化的指标方面更好。

我下面描述的过程将有助于找到你的模型的一个好的起点。在这个例子中,我正在进行一个项目,该项目使用 CTG 信息将胎儿健康分为 3 类(1 为健康,2 为可疑,3 为病理)。请注意,在开始项目的建模阶段之前,我彻底清理了数据并执行了 EDA。

为了开始分类建模过程,我定义了 X 和 y 变量,并创建了训练、测试分割和缩放数据,如下图所示。一旦训练和测试数据被缩放,就该开始初始建模了。

X = df.drop(columns = ['fetal_health'])
y = df['fetal_health']X_train, X_test, y_train, y_test = train_test_split(X, y, stratify = y )ss = StandardScaler()
X_train_sc = ss.fit_transform(X_train)
X_test_sc = ss.transform(X_test)

我创建了一个函数来实例化并拟合训练数据上的指定模型,对测试数据进行预测,然后打印出训练和测试的准确度分数。下图显示了我如何设置这个简单而有效的函数。

def pipe(model): #instantiate model
    model = model() #fit to scaled data
    model.fit(X_train_sc, y_train)

    #make predictions
    predictions = model.predict(X_test_sc) #print accuracy scores for training and testing groups
    print(f'{model} training score: {model.score(X_train_sc, y_train)}')
    print(f'{model} testing score: {model.score(X_test_sc, y_test)}')return

接下来的部分是最有趣的部分!我能够通过我在笔记本中导入的函数传递任何模型。我能够很快地在 8 个不同的分类模型上重复这个函数,并打印出训练组和测试组的准确度分数。然后,我可以查看如下所示的 8 个模型的得分,并挑选出前两个模型来微调超参数,以进一步提高准确性。

pipe(LogisticRegression)
> LogisticRegression() training score: 0.8977415307402761
> LogisticRegression() testing score: 0.9078947368421053pipe(DecisionTreeClassifier)
> DecisionTreeClassifier() training score: 0.998745294855709
> DecisionTreeClassifier() testing score: 0.9116541353383458pipe(KNeighborsClassifier)
> KNeighborsClassifier() training score: 0.9316185696361355
> KNeighborsClassifier() testing score: 0.8984962406015038pipe(RandomForestClassifier)
> RandomForestClassifier() training score: 0.998745294855709
> RandomForestClassifier() testing score: 0.9454887218045113pipe(AdaBoostClassifier)
> AdaBoostClassifier() training score: 0.9084065244667503
> AdaBoostClassifier() testing score: 0.8853383458646616pipe(SVC)
> SVC() training score: 0.9240903387703889
> SVC() testing score: 0.9191729323308271pipe(GradientBoostingClassifier)
> GradientBoostingClassifier() training score: 0.9949811794228356
> GradientBoostingClassifier() testing score: 0.9492481203007519pipe(ExtraTreesClassifier)
> ExtraTreesClassifier() training score: 0.998745294855709
> ExtraTreesClassifier() testing score: 0.9342105263157895

在这种情况下,我选择继续研究梯度提升分类器和随机福里斯特分类器,因为它们在训练组和测试组之间具有最高和最一致的分数。在那里,我设置了网格搜索来测试每个模型中不同的超参数选项。网格搜索需要更多的时间来迭代,这就是为什么我只想在最高性能的模型上尝试。梯度增强分类器网格搜索如下所示。然而,我对这两个模型都做了这个过程,并确定了每个模型的最佳参数。

X = df.drop(columns = ['fetal_health'])
y = df['fetal_health']X_train, X_test, y_train, y_test = train_test_split(X, y, stratify = y )#pipeline to scale data and then grid search
pipe = Pipeline([
    ('ss', StandardScaler()),
    ('gbc' , GradientBoostingClassifier()) 
])#gbc parameters to grid search through
pipe_params = {
    'gbc__max_depth':[1, 2, 3, 4],
    'gbc__learning_rate'  :[0.1, 0.001, 1],
    'gbc__n_estimators' :[100, 300, 500],
    'gbc__min_samples_leaf' :[1, 2]
}#instantiate and fit grid search
gs = GridSearchCV(pipe, param_grid = pipe_params, cv = 5)
gs.fit(X_train, y_train)#print accuracy scores for training and testing groups
print(f'training score:  {gs.score(X_train, y_train)}')
print(f'testing score: {gs.score(X_test, y_test)}')> training score: 0.9887076537013801
> testing score: 0.9473684210526315#get best parameters from grid search
gs.best_params_> {'gbc__learning_rate': 0.1,
 'gbc__max_depth': 2,
 'gbc__min_samples_leaf': 2,
 'gbc__n_estimators': 500}

最后,为了评估用于生产的最佳模型,我对测试数据进行了预测,并查看了每个模型的准确性分数和召回分数。我希望优化召回分数,因为在处理胎儿健康数据时,假阴性的风险很高。我选择梯度提升分类器作为最佳模型,因为与随机森林分类器相比,它在准确性和召回率方面得分最高。参见下面的分类报告和混淆矩阵,其中第 3 组(病理组)的假阴性已降至最低。

#make predictions on testing data
preds = gs.predict(X_test)#print out classification report
print(classification_report(y_test,preds))> 
fetal health  precision    recall  f1-score   support

           1       0.96      0.97      0.97       414
           2       0.91      0.78      0.84        74
           3       0.86      0.98      0.91        44

    accuracy                           0.95       532
   macro avg       0.91      0.91      0.91       532
weighted avg       0.95      0.95      0.95       532#plot confusion matrix
cm = confusion_matrix(y_test, preds)
ConfusionMatrixDisplay(cm, display_labels = gs.classes_).plot(cmap = 'Blues');

作者照片

这整个过程可以在一天的工作中完成。我希望模型功能和网格搜索的结合也能帮助你的分类建模更有效!

如何成功管理人工智能团队

原文:https://towardsdatascience.com/how-to-manage-ai-teams-for-success-502c1f85ca96?source=collection_archive---------36-----------------------

隐藏的动力、目标和竞争矢量

Shutterstock.com瓦伦丁·瓦尔科夫 / 摄影

几个月前,我与多伦多一家知名人工智能公司的几位研究人员进行了一次对话,他们的公司理念是,每个人都应该编写生产级代码,甚至能够部署它。这让我想起了很多事情。关于我的团队,关于人工智能和管理软件工程的复杂性。人工智能团队特别有趣,因为他们同时需要至少两个学科:软件/硬件工程和科学发现。

那么,一个人如何走向成功,创建一个有凝聚力的团队,或者由研究人员和软件工程师组成的团队,他们一起工作,创造出伟大的产品呢?产品要么是企业试图在知识产权方面获得竞争优势的纯研究,要么是在给定垂直领域更适合商业产品的应用研究,要么是两者的混合。

这是我们三年前面临的挑战。作为一个团队,我们需要为我们的金融客户创建一个软件生态系统。它有几个不同的组件:基于 Kafka 的数据摄取系统,ETL 流程,特征工程,发现 ML/深度学习算法的核心流程,并最终将它们部署到生产中。这是一个既需要科学研究又需要创造商业产品的混合环境。观察新出现的团队内部模式很有趣,这让我想起了我以前与科学家和软件工程师的合作。我发现仔细检查人工智能研究和软件工程的交互中隐藏的假设,以及管理哲学如何影响这些交互,并最终影响一个组织的目标可以实现的程度,这很有趣。

竞争向量

想象你是一名软件/数据工程师,与一名人工智能研究人员一起工作,或者相反,这取决于你更喜欢哪种角色。作为一名软件工程师,你朝着消除设计中的错误和减少设计中的缺陷前进,如果你的系统中有未知的东西,在很大程度上你就暴露在风险之中。相反,作为一个人工智能研究者,你会走向一个新的发现,本质上你是在走向一个在发现之前未知的东西。它有多新颖并不重要,重要的是它以前不为任何人所知。换句话说:研究人员走向未知,而软件工程师走向消除未知,图 1。我把这种现象称为未知向量的竞争(CUV)。我一直在从三个维度思考 CUV:系统熵、奖励系统、集体与个人目标,并有兴趣看看这些向量可能在哪里收敛或发散。

图 1:未知向量的竞赛,a s 如果有两个向量,代表每个学科的努力,指向两个不同的搜索空间。作者图片。

系统熵

从系统熵的角度来看待未知会很有趣。人工智能研究中的发现过程,或任何与此相关的科学研究,似乎都伴随着所涉及的思维过程和潜在工作空间中熵的增加。类似于给思想的灯塔充能,把它送到高维空间,寻找新的发现。如果你的研究灯塔能量不高,你就不太可能接触到新奇的事物。似乎没有这种熵水*的内在增加,就无法进行研究。如果不在创造力的空间里进行高维度的搜索,一个人怎么能发现未知的新领域呢?另一方面,软件工程寻求在系统层次上减少熵。熵的起伏会在目标、支持系统、协议、数据管道和项目的运营预算等方面产生摩擦。

例如,在我们项目的早期,我们的研究人员正在构建新的模型,这些模型不断需要新的数据流、这些数据的新转换以及这些数据的新存储解决方案。他们的创造速度超过了数据*台所提供的开箱即用。在这种情况下,一家公司可能有两种选择,一种是将研究人员转化为兼职工程师,他们也可以创建自己的临时管道,在我看来,这是一种自我挑战的活动,因为它会导致团队的研究能力大幅下降。第二个选择是想出新的方法来支持研究人员。第二个选择最终是我们选择的道路,它帮助我们在不破产的情况下增加我们的研究能力(我将在下一篇文章中更详细地介绍我们如何扩大我们的团队)。我想在这里强调的一点是,这两个子系统,数据管道和不同机器学习模型的实验,在增加或减少系统熵方面是如何发生冲突的。除了数据管道,我们在其他子系统中也看到了熵上升和下降的相同模式,以及随之而来的摩擦,例如在编码、测试和设计 ML 模型的定制模拟中。

奖励系统

这两个领域的奖励制度可能大相径庭。在科学领域,一个人会因为有所发现而获得奖励,即揭开未知的秘密。例如,亚当优化器的发明是一项科学成就,它使得深度模型的训练更快。虽然,让我们说,创建一个高性能的数据流管道,实时填充功能商店也为生产模型提供数据,虽然非常复杂和非常有价值,但它更像是一项工程成就,而不是科学或 NeurIPS 有兴趣发表的东西。我认为奖励制度是公司需要投资澄清的主要话题之一,因为它影响了企业的最终目标,以及如何*衡人工智能研究人员和软件工程师的留用和工作满意度。

照片由航拍/Shutterstock.com拍摄

集体目标与个人目标

在商业人工智能公司中,目标不明确有许多方式,但似乎最常见的方式之一是试图简单地复制管理哲学和学术界的目标。如果考虑未知向量、奖励系统和系统熵的竞争,就可以更清楚为什么简单地复制学术界可能不是中小型企业的最佳主意。可以举出几个不同的例子来说明这种不适用性。

例如,学术界可以承受思维过程中几乎无限的熵(这是正确的,因为这是他们的设计目的,做出新的发现),而在商业企业中,无限的熵可能会破坏工程努力和团队内部的努力,从而破坏产品化的机会。

另一个例子可以是如何在人工智能公司中衡量进展。在我们项目的早期,我们在 finance+ml 杂志上看到了一篇很有前途的同行评议论文,它为解决我们现有的一些问题提供了理论依据。然而,令我们惊讶的是,我们无法重现该论文承诺的结果。为了解决这个问题,我们作为一个团队合作创建了一个模拟环境,以测试实现该论文承诺结果的可能性。通过这些概率模拟,我们发现实现那篇论文发表结果的几率只有 70%。对我们来说,这一过程是成功的,因为有两个原因,首先,它节省了我们在那份文件上花费的时间,其次,它揭示了那份文件中隐藏的风险远远超出了我们在任务关键型环境中所能容忍的程度。对我们来说,这里的成功不一定是写一篇新的科学论文,而是发现一个模型与项目的目标不一致。

第三个例子是检查学术界和企业所需的软件工程工作的规模和结构。在学术界,软件工程工作通常是在筒仓中完成的,有趣的是,这些筒仓老化得非常快,并且不期望它们相互连接和交换数据,因为根本不迫切需要它,因为目标不是公司范围的,而是基于个人的。在企业方面,要使这些孤岛相互通信、保持最新状态并服务于多个客户,需要在软件和数据工程方面进行大量投资。

思绪向前

我认为检查人工智能企业中存在的隐藏假设是有益的,无论它们更倾向于研究还是研究和产品的混合体。并且可能有助于提出具有深远影响的问题:团队是如何构建的,进展是如何衡量的,代码是如何产生的,敏捷迭代是如何完成的,谁支持谁以及支持到什么程度,以及成功的定义是什么:它发表了更多的论文吗?或者,作为一个例子,成为金融领域领先的人工智能提供商?或者两者都有?这就引出了这样一个问题:一个公司要取得预期的成功,需要什么样的结构、团队和脚手架。我也有兴趣了解你的经验和实地观察,无论是作为一名人工智能研究人员,一名软件工程师,还是一名经理,请随时通过评论或消息联系。

感谢阅读。

https://www.linkedin.com/in/atavakolie/
http://www . silka tech . ca

如何像老板一样管理配置

原文:https://towardsdatascience.com/how-to-manage-configurations-like-a-boss-34e224f3bb4?source=collection_archive---------4-----------------------

使用 Pydantic BaseSettings,你的生活会变得更容易

费伦茨·阿尔马西在 Unsplash 上的照片

介绍

每当您编写应用程序、算法或数据管道时,您很可能会有几个因环境或部署而异的变量。例如,与生产环境中的目标数据库相比,您在本地测试时连接到的数据库肯定是不同的。因此,数据库的名称或地址将是一个配置变量。

管理这样的配置变量至关重要;您肯定不希望在本地测试时意外地将垃圾写入生产数据库。为了获得良好的开发体验,添加和设置配置变量也应该是容易和轻松的。

尽管配置管理非常重要,但它并不被认为很有吸引力。在这篇文章中,我想改变这一点!具体地说,我想向您展示我认为在现代 Python 中管理配置的最性感的方式。你准备好了吗?我们开始吧!

问题是

正如在引言中已经提到的,每当你写一个更大的软件时,在某个时候,你将不得不管理配置变量。我所说的配置变量指的是不同环境之间的变量,或者可以决定应用程序行为的变量。典型的例子有数据库地址、日志级别、并发线程的最大数量或 API 令牌等等。

要设置这些变量,您有几个选项。三种最常见的是

  • 将它们作为常量存储在代码中。在这种情况下,您的优势在于,在运行您的应用程序或测试时,您不需要做任何事情,因为一切都是预先配置好的。最大的缺点是,当你把你的应用程序部署到不同的环境中时,它是非常不灵活和不适用的。实际上,这样做被认为是一种反模式,因为代码和配置是紧密耦合的。
  • 将它们存储在配置文件中。这里,您必须在应用程序启动时加载一个文件,并将值赋给各个变量。这种方法很灵活,因为不同的环境可以有不同的文件。不利的一面是,它可能需要大量样板代码来很好地设置一切。此外,当涉及到测试时,保留虚拟配置文件来设置您的测试可能会很烦人。
  • 存储在环境变量中。这里,您必须单独加载每个环境变量,并将加载的值分配给相应的代码变量。利弊与使用配置文件的描述相似。不过,使用环境变量可能会更灵活一些,但需要编写更多的代码。

如你所见,这三种选择都有利弊。问题是现在;我们能否利用它们的优点,同时避免或减轻它们的缺点?幸运的是,答案是

布雷特·乔丹在 Unsplash 上拍摄的照片

解决方案

当您使用伟大的 Pydantic 库时,在 Python 中管理配置就像是轻而易举的事情。Pydantic 附带了一个名为 BaseSettings 的类,它允许您创建定义明确、有类型提示的应用程序配置类。除了给你的配置一个清晰的结构和定义良好的接口,这个类自动从环境变量和配置文件中读取值。因此,加载您的配置不需要编写任何额外的代码。听起来是不是很棒?

最后,当您将配置定义为标准 Python 类时,您可以为变量分配合理的默认值。这意味着您不必在每个环境中显式地设置每个变量,但是如果您希望或者将来必须这样做,您可以做好准备。

基本示例

一小段话包含了很多信息。因此,让我们喘口气,看看一些示例代码,以进一步加深我们的理解

我在这里做了什么?首先,我创建了一个继承自BaseSettings的配置类MediumConfig。这个类有三个配置变量tier, log_level,user,它们都是字符串。Tier 和 log_level 分配了默认值,而用户变量必须显式设置。设置值最直接的方法是创建一个类的实例,如cfg = MediumConfig(user="hans.maulwurf", tier="stg")。到目前为止,没有什么非常壮观的,只是普通的 Python。

然而,真正方便的是使用环境变量设置变量的第二个选项。对于给定的示例,您可以通过设置与带有前缀medium_MediumConfig类中的环境变量同名的环境变量来实现,即medium_tiermedium_log_level。需要前缀,因为子类Config中的env_prefix变量被设置为前缀。如果你不想要那个,你可以不要它。一般来说,建议为 env 变量使用前缀,因为它允许您将特定于应用程序的变量与其他变量区分开来。

但是,可能有一些环境变量的名称您无法显式控制,也就是说,您不能只在它们的名称前添加前缀。尽管如此,您仍然希望能够自动加载这些变量。在这种情况下,您可以使用Field类。在这里,将 Field 的一个实例分配给一个变量,并将其 env 参数设置为相应的环境变量名。您可以从取自user_name环境变量的user变量中看到这一点。注意,这里使用的前缀是而不是

最后,您从示例中看到,您可以混合和匹配指定变量值的方式。如果一个变量以多种方式被指定,例如,一个值被传递给类初始化器并且相应的环境变量被设置,传递给类初始化器的值优先或者具有更高的优先级。这种优先顺序可以改变,甚至扩展。让我们在下一节看看如何做到这一点。

高级示例

到目前为止,我们已经看到了如何在代码中或者使用环境变量显式地设置我们的配置变量。我们还没有介绍的是如何使用配置文件做到这一点。为了了解它是如何工作的,让我们来看一些代码

这里发生了什么?我有

  • 增加了从 YAML 文件加载配置变量的可能性,
  • 更改了优先级顺序,使配置文件优先于环境变量,
  • 去掉了一种设置变量的方法,我在这里还没有讲到。

我是怎么做到的?只需从 Config 子类实现和扩展customise_sources classmethod。这个方法必须返回一个可调用元组,每个可调用元组实现一种加载配置变量的可能方式。从该函数返回可调用内容的顺序决定了从不同来源加载时的优先级。

具体地说,为了加载 YAML 配置文件,我实现了yml_config_setting函数。该函数加载名为 config.yml 的 YAML 文件,并将其反序列化到 Python 字典中。为了在 config 类中使用这个函数,我将它添加为customise_sources函数的返回值之一。为了给 YAML 配置文件比使用环境变量更高的优先级,我在返回值集合中把yml_config_setting放在了env_settings callable 之前。完成了。对我来说,这再简单不过了。

最后一点,加载配置变量不仅限于加载 YAML 文件。您可以将任何可以反序列化数据的东西添加到字典中。您甚至可以考虑添加一个函数,从 AWS SSM 这样的云参数存储中加载您的配置,但这超出了本文的范围。我相信你可以自己解决这个问题:)

照片由艾蒂安·吉拉尔代Unsplash 拍摄

包裹

在本文中,我向您展示了如何使用 Pydantic 和 BaseSettings 类来定义和管理应用程序配置。使用这种开箱即用的方法,不仅可以为您的配置提供一个定义更好、更清晰的界面,还需要您编写和维护更少的代码。此外,我还向您展示了一种超级简单灵活的方法,如何扩展 BaseSettings 实现,使其能够处理其他源,如配置文件。有了这个,你应该配备一个工具集,让你像老板一样管理你的配置。对我来说,所有的一切都很性感,不是吗:-)

感谢你关注这篇文章,我希望你喜欢它,并学到一些新东西。一如既往,欢迎随时联系 LinkedIn 或关注我,并在下面留下评论。

如何管理您的数据科学项目

原文:https://towardsdatascience.com/how-to-manage-data-science-projects-successfully-8fbcbdb3b5f7?source=collection_archive---------49-----------------------

数据科学项目的五个 P

蒂姆·斯万在 Unsplash 上的照片

在这篇短文中,我想为您提供什么是 5P 的答案,以及如何通过在您的数据科学项目中使用它们来从中受益。

目的

类似于经典的项目管理,目标或目的总是应该被制定。在大数据世界中,可能的目标包括:

  • 更好的商业洞察力
  • 欺诈预防/检测
  • 预言;预测;预告
  • 最大化问题等。

但是,如果没有明确的目标,就不应该做大数据或数据科学项目。不要因为每个人都在做某件事就去做它!

通常参与开发团队的人员的角色如下:

  • 开发商
  • 试验装置
  • 数据科学家
  • 领域专家

敏捷数据科学团队—作者图片

还有利益相关者和项目发起人,他们通过项目经理/产品负责人了解项目的进展,在双方之间进行调解,并承担建立适当团队、组织截止日期、创建项目计划或故事的任务。在这里阅读更多关于组建团队的。

处理

你必须考虑两种不同类型的过程。一方面组织流程和主题如:

  • 项目组织:经典与敏捷
  • 项目进度报告和项目营销(例如,我如何通知我的利益相关者?)
  • 变更流程(我如何让相关人员参与进来,并让他们成为合作者?)

另一方面,你将处理技术流程:

  • 我试图用 IT 和数据科学支持的业务流程是什么?
  • 数据集成过程和使用什么等问题——以 ETL 与 ELT 为例
  • 您希望选择什么样的数据分析和数据科学流程(例如 CRISP)

*台

影响您将用于分析和产品的*台的基本和战略性问题有:

  • 我的 IT 治理规定了什么?
  • 我追求哪些(IT)策略?
  • 以前的(IT)架构
  • 一两个速度呢?
  • 我的法规遵从性/安全性要求什么?

这导致了一些技术问题,如:

  • 数据集成应该如何实现?(通过 Java 手动操作,而不是使用 talend、Dataflow 等工具。)
  • 应该使用哪种云(AWS 对 Google 对 Azure 以及
    公共对私有对混合)
  • 我的技术要求是什么?
  • SLA(服务提供商和客户之间的合同)

本文中的描述了如何构建您的数据分析*台。

可编程序性

我使用哪些工具和编程语言?这一点当然也是由 IT 治理和战略以及对上述问题的回答所决定和影响的。

工具和编程语言可以是:

  • 像 SQL、Python、R
  • 像 Hadoop、谷歌云存储和大查询、AWS 红移和 S3 这样的大数据工具
  • Kafka、Spark、talend 等流媒体软件
  • 商务智能工具,如:Tableau,Qlik,谷歌数据工作室

结论

在从事数据科学项目甚至管理项目时,5P 将为您提供您应该考虑的五个主要主题。此外,他们会问你一些你在项目中可能会问自己的问题。要了解更多信息,您可以点击下面的链接。

资料来源和进一步阅读

如何在 SQL 中操作熊猫数据帧

原文:https://towardsdatascience.com/how-to-manipulate-a-pandas-dataframe-in-sql-7d1a1503f47?source=collection_archive---------13-----------------------

数据操作

这是一个现成的代码,包含一些使用 SQL 查询操作 Python Pandas 数据框架的技巧。

迈克尔·泽兹奇在 Unsplash 上拍摄的照片

在本教程中,我展示了一些使用 SQL 查询操作 Python Pandas 数据帧的技巧。具体来说,我涵盖以下主题:

  • 缺失值(移除和替换)
  • 数据帧排序
  • 删除重复项
  • 合并两个数据框架(并集和交集)

为了通过 SQL 查询来查询 Pandas 数据帧,我使用了sqldf Python 库,可以通过下面的命令安装这个库:pip install sqldf

加载数据集

我导入了pandas库并读取了一个简单的数据集,其中包含每个国家的首都和一个通用字段,称为 Value。

import pandas as pddf = pd.read_csv('../../Datasets/capitals1.csv')
df.head()

作者图片

现在我导入sqldf库。

import sqldf

缺少值

缺失值是数据集中不可用的值。例如,丢失的值可以表示为NULLNoneNaN。可以采用不同的策略来处理缺失的价值观。在本教程中,我演示了两种技术:

  • 删除缺少的值
  • 替换丢失的值。

删除缺少的值

删除缺失值包括删除某一列中缺失值的所有行。在我们的示例数据集中,索引为 3 的行缺少一个值。

作者图片

我定义了一个查询,它只选择Value列不为空的行:

query = """
SELECT *
FROM df
WHERE Value IS NOT NULL;
"""

现在我可以通过run()函数运行查询。

如果查询包含 **SELECT** 语句,则 **run()** 函数返回新的 dataframe。相反,如果查询包含一个 **UPDATE** 语句,则更新原始数据帧。

sqldf.run(query)

作者图片

替换丢失的值

处理缺失值的另一个策略是用固定值替换它们。例如,固定值可以是*均值。据我所知,sqldf库不支持嵌套查询,因此我必须运行两个独立的查询,一个检索*均值,另一个替换丢失的值。

首先,我计算列Value的*均值:

query = """
SELECT AVG(Value) as AVG
FROM df
"""avg = sqldf.run(query)['AVG'][0]

然后我更新数据集:

query = """
UPDATE df
SET Value = {}
WHERE Value IS NULL;
"""sqldf.run(query.format(avg))
df.head()

作者图片

订单数据框架

可能发生的情况是,为了建立一个最终的可视化,必须订购一个数据帧。因此,我可以利用 SQL 提供的ORDER BY语句:

query = """
SELECT *
FROM df
ORDER BY Value DESC;
"""sqldf.run(query)

作者图片

删除重复项

SQL 的强大功能也可以用来删除重复项。这可以通过构建查询来实现,该查询选择不同的列:

query = """
SELECT DISTINCT Country, Capital, Value
FROM df;
"""sqldf.run(query)

作者图片

合并两个数据帧

数据集合并包括合并两个数据帧。SQL 是一种非常强大的方法,可以毫无困难地合并数据集。

联盟

两个数据帧之间的联合操作的结果包含两个数据集的所有行。为了执行 union,我加载了一个额外的数据帧df2,称为capitals2.,它与前面的类似。附加数据帧df2仅包含一个与df重叠的行。

df2 = pd.read_csv('../../Datasets/capitals2.csv')
df2.head(len(df2))

作者图片

两个数据帧的联合可以通过以下查询实现:

query = """
SELECT Country, Capital, Value 
FROM df
UNION
SELECT Country, Capital, Value 
FROM df2
ORDER BY Value DESC
"""sqldf.run(query)

作者图片

请注意,union 操作已经删除了重复项。

交集

两个数据帧的交集只包含两个数据帧中包含的行。在 SQL 中,可以通过INNER JOIN操作进行交集:

query = """
SELECT *
FROM df
INNER JOIN df2
  ON df.Country = df2.Country AND df.Capital = df2.Capital;
"""sqldf.run(query)

作者图片

摘要

在本教程中,我展示了一些在 Pandas 数据帧上运行 SQL 查询的技巧。我只描述了一些查询的例子,但是你的幻想将比我的更有创造性!

本教程的完整代码可以从我的 Github 库下载。

如果你想了解我的研究和其他活动的最新情况,你可以在 TwitterYoutubeGithub 上关注我。

相关文章

https://medium.com/geekculture/the-top-25-python-libraries-for-data-science-71c0eb58723d

如何在几分钟内绘制出新冠肺炎在全球的传播图

原文:https://towardsdatascience.com/how-to-map-the-spread-of-covid-19-globally-in-minutes-baa2e18d25e5?source=collection_archive---------55-----------------------

使用 BigQuery GeoViz 在 20 分钟内实现数据可视化

使用 BigQuery GeoViz 快速可视化新冠肺炎感染的指南

Unsplash摄影拍摄的照片

介绍

一张图胜过千言万语。请原谅这里的陈词滥调,但是没有什么时候比当你试图向非技术观众阐述数据发现时更重要了。许多人不希望看到一页塞满了数字。简洁的数据视觉效果可能是让你的观点被理解的区别,也可能是让你的听众厌倦和茫然的凝视的区别。

在这篇文章中,我将向你展示如何使用 Google BigQuerie 的 GeoViz 工具来可视化新冠肺炎的全球传播。这种类型的可视化可以用多种方式来完成,我发现 GeoViz 既快又直观。

在这篇文章结束时,你将已经创建了一个地图,显示了过去 7 天全球新新冠肺炎感染情况。

数据

我们将使用通过 BigQuery 的公共数据集程序获得的新冠肺炎公共数据集。这些数据集可以免费使用,涵盖了从医疗保健到金融的各种行业。谷歌已经将新冠肺炎的数据在短时间内免费提供给 BigQuery 进行访问和分析,以帮助研究

先决条件!

在构建数据可视化之前,您需要做两件事…

  1. 你需要在谷歌云*台(GCP)上开一个账户。您可以从这里免费开始使用
  2. 您需要创建一个项目。你可以通过遵循这些指南来做到这一点。重要!请记下你的项目 ID,你将需要它来生成你的可视化。

好了,让我们开始吧!

步骤 1:设置您的 BigQuery GeoViz 环境

从 GCP 仪表板导航到 Google BigQuery ,打开 BigQuery 控制台。

作者图片

资源下,导航到big query-public-data>covid 19 _ open _ data _ eu,打开 covid19_open_data 。您将看到一个数据集,您可以通过按下预览进行浏览。

点击位于 BiGQuery 控制台右侧的导出,然后点击使用 GeoViz 进行浏览

这将在浏览器的新窗口中打开 GeoViz studio。点击授权按钮,按照步骤完成必要的权限授予。您需要这样做,以允许 GeoViz 在 Google BigQuery 中查看和管理您的数据。

一旦你这样做了,导航回 GeoViz 工作室。在查询下输入你的项目 ID。

第二步:产生你的观想

在您的项目 ID 下的空白处,输入以下 SQL 查询:

SELECT
    country_name,
    subregion1_name,
    subregion2_name,
    ST_GeogPoint(longitude, latitude) AS WKT,
    sum(new_confirmed) as  New_Confirmed_Cases
  FROM 
    `bigquery-public-data.covid19_open_data_eu.covid19_open_data` 
  WHERE 
    date BETWEEN DATE_ADD(CURRENT_DATE(), INTERVAL -7 DAY) AND CURRENT_DATE() AND
    new_confirmed IS NOT NULL AND
    subregion1_name IS NOT NULL AND
    subregion2_name IS NOT NULL
  GROUP BY 
   country_name, subregion1_name, subregion2_name, longitude, latitude

该查询汇总了自运行之日起最* 7 天内所有新确诊的新冠肺炎病例。它跨越由经度和纬度定义的空间点来实现这一点。输入查询后,点击运行。点击显示结果可以看到结果。

当你满意时,导航到样式来改变图上点的外观。您可以编辑样式,以便给定点反映它所代表的数据。例如,较大的点表示较高数量的新冠肺炎病例。

下面的图片是帮助你编辑风格的指南。摆弄设置,直到你找到你喜欢的东西。一旦你满意点击应用样式,你可能需要通过放大来调整你的地图的分辨率,但是你应该有一个工作的可视化。

作者图片

作者图片

如果我的指示已经很清楚了,你应该有一个类似这样的地图:

作者图片

这是我之前准备的。它是交互式的,所以你可以点击每一个点来深入了解新冠肺炎在任何地方的感染情况。

https://www.linkedin.com/in/john-adeojo/

如何大量识别重复出现的文本特征

原文:https://towardsdatascience.com/how-to-mass-identify-recurring-textual-features-e3e98c4b0309?source=collection_archive---------18-----------------------

当你为西班牙语、英语等培训一名 NER 模特时,要知道你真正在做什么。使用空间

图片作者。

假设你有一堆短信。文本中有人名、地名、组织、日期、职位等。我们称这些实体为一般实体。通过阅读,你可以知道哪些单词组(记号)代表了每个实体,但是你不希望自己去识别所有的单词,尤其是当你有成百上千的页面需要浏览的时候。这根本不是对你时间的有效利用。

命名实体识别(NER): 一种识别代表特定实体(如个人、组织、品牌、地点)的词组的方法。

你可以使用现成的模型,比如 spaCy ,它有一个优秀的英语 NER 模型,但是对于其他语言(在我的用例中是哥伦比亚西班牙语)并不十分准确。该模型未能识别我所关心的实体。如果您在寻找使用不太流行的语言的小众实体,可能会遇到同样的问题。

这篇文章是为你写的,如果你:

  • 有原始文本可以处理
  • 当前 NER 模型的精确度越来越低
  • 是一个完全的初学者与培训 ner 模型

这是我发现的改进 spaCy 现有 NER 模型的最省时、最有利于协作的方法。如果你正在和一个不是特别懂技术的人一起做一个数字人文(或任何)项目,这个工作流程会有所帮助。

在你们任何一个人开始模特训练冒险之前,我应该先回答你们脑海中的第一个问题:

这会有多难?

你要知道的第一件事是,训练一个模特是耗时又繁琐的。你投入的时间大约与你得到的准确度成正比。这就是为什么普通实体的英语模型更准确——它们有更多的训练数据。

简单地说,训练数据告诉模型什么定义了一个实体。你在一个文本块中标注了成百上千、上百万个实体,模型根据机器学习(ML)算法选择模式(关于这一点的更多信息,请参见另一篇文章)。您提供的训练数据的数量和种类越多,ML 算法就越能准确地识别这些模式。

给 1,069 个实体做标记花了我大约 4 个小时,因为我对西班牙语只有基本的了解,对哥伦比亚也不熟悉。这些数据够吗?这取决于:

  • 期望的精度水*(你愿意接受模型的什么样的误差水*?)
  • 你的模型的复杂性(你是在寻找特定的东西还是计算机难以识别的东西?)
  • 现有数据量(您是在优化模型还是从头开始训练模型?)
  • 你的训练数据的质量(是否有各种各样的文本?这些单词出现在不同的上下文中吗?)

最终,一个经验的测试方法是使用测试数据来验证你的结果,我将在下面解释。

第二件事是编码技巧。如果你对 Python 有一个的基本了解,我相信这个指南会被证明是容易理解的。老实说,如果您不习惯使用 terminal 和 spaCy,这需要一点时间来适应,但是花一个小时来做这个设置,只会变得更容易。让我们开始吧!

设置 NER 注释器

Arunmozhi 创造了我发现的最方便的 tagger。下载文件并将其解压缩到一个方便的位置,如 Documents 文件夹。

点击链接https://github.com/tecoholic/ner-annotator下载 zip。图片作者。

然后,我们将遵循 GitHub 上给出的说明,但我会提供更多考虑到使用终端的初级经验的详细指导。(一开始我真的很反对学习使用终端,但是几次之后,我发现它并没有那么糟糕!不要让这个影响你。)

  1. 打开命令提示符/终端
  2. 建立虚拟环境。使用cd Documents/ner-annotator-main导航至包含该程序的文件夹。cd代表更改目录,并告诉终端您希望它查找的位置。
  3. 使用python -m venv env在 Python 上创建虚拟环境。你应该在ner-annotator-main文件夹中看到一个名为env的文件夹。
  4. 激活虚拟环境。我们想导航到activate文件。根据您的操作系统,您需要查看env中的文件夹,看看它在哪里。例如,在使用 Windows 时,我在终端输入了env\Scripts\activate
  5. 下载依赖关系。这些都是程序需要的库和文件,写在主文件夹的文本文件中。在终端中键入pip install -r requirements.txt
  6. 运行你的后端服务器。键入python annotator/server.py进入端子。
  7. 打开另一个终端启动另一个服务器。导航到ui文件夹。你可以输入cd Documents\ner-annotator-main\ui
  8. yarn install将下载软件包管理器,它将处理 tagger 程序的前端。
  9. yarn serve将启动程序。
  10. 在浏览器中打开 http://localhost:8080 打开 tagger。

虚拟环境:电脑上的隔离空间,用于下载特定程序所需的所有文件,而不会与其他程序所需的文件发生冲突。

完成第 5 步后,您的终端应该是这样的。图片作者。

厉害!下次运行时,您只需执行步骤 4、6、7、9 和 10。

我们来列举一些实体吧!

上传完你的。txt 文件,您可以开始标记,但您应该等待一秒钟。首先,你需要确定你想要什么标签,以及加入每个标签俱乐部的标准。你不想回去重做所有的标签!

以下是一些你应该考虑的问题:

  1. 你有兴趣提取什么信息?
  2. 哪些令牌可能难以标记?例如,“联合国日内瓦会议”会被认为是属于“组织”或“地点”或“事件”的标签吗?记住:你不能双重标记一个实体!

完成后,您的注释将保存在一个. json 文件中。

标记单词的外观示例。图片来自 Arunmozhi

培训 NER 模型

将训练数据加载到 Python 中。

import json
with open('training_data.json', 'r') as f:
  DATA = json.load(f)["annotations"]

分离出 20%的数据作为你的测试数据,这样我们就可以验证更新后的 NER 模型有多准确。只要你有足够的数据进行测试,你可以随意改变百分比。

import numpy as np
N = len(DATA)# Randomly select 20% of the data for testing
test_idx = np.random.randint(N, size=N//5)
TEST_DATA = np.array(DATA)[test_idx].tolist()# Leave the remaining 80% as training data
train_idx = list(set(np.arange(N))-set(test_idx))
TRAIN_DATA = np.array(DATA)[train_idx].tolist()

我从 Shrivarsheni 的文章中学习了如何实现 spaCy 培训管道,所以请阅读它以了解更多细节!我确实纠正了他的一些不适合我的代码,所以希望这个补充对你有帮助。

本质上,下面的代码建立在 spaCy 的 NER 模型上,并更新了令牌的方式:

  1. trf_wordpiecer:已定义
  2. trf_tok2vec:转换成矢量(数值表示)
  3. ner:已标记

根据你的训练数据。

# Load pre-existing spacy model
pip install spacy # Download the package if you haven't
import spacy
nlp=spacy.load('en_core_web_sm') # Spanish

# Getting the pipeline component
ner=nlp.get_pipe("ner")# Disable pipeline components you dont need to change
pipe_exceptions = ["ner", "trf_wordpiecer", "trf_tok2vec"]
unaffected_pipes = [pipe for pipe in nlp.pipe_names if pipe not in pipe_exceptions]# Import requirements
import random
from spacy.util import minibatch, compounding
from pathlib import Path
from spacy.training.example import Example# TRAINING THE MODEL
with nlp.disable_pipes(*unaffected_pipes):
  # Training for 30 iterations
  for iteration in range(30):
    # shuffling examples  before every iteration
    random.shuffle(TRAIN_DATA)
    losses = {}
    # batch up the examples using spaCy's minibatch
    batches = minibatch(TRAIN_DATA, size=compounding(4.0, 32.0, 1.001))
    for batch in batches:
      for text, annotations in batch:
        # create Example
        doc = nlp.make_doc(text)
        example = Example.from_dict(doc, annotations)
        nlp.update(
                 [example],
                 drop=0.5, # dropout - make it harder to memorise data
                 losses=losses,
                 )
print("Losses", losses)

损失是底层神经网络用来确定模型在 NER 表现如何的指标。在另一篇文章中有更多关于这方面的内容!目前,最重要的是模型的目标是将损失最小化。

模型表现如何?

毕竟,我们希望 NER 模型可以帮助大规模识别所需的实体。这一步有助于确定我们对模型获得正确标签的能力有多大的信心。

from spacy.scorer import Scorer
from spacy.tokens import Docdef evaluate(ner_model, examples):
  scorer = Scorer()
  example = []
  for input_, annot in examples:
    pred = ner_model(input_)
    temp = Example.from_dict(pred, annot)
    example.append(temp)
    scores = scorer.score(example)
  return scoresresults = evaluate(nlp, TEST_DATA)
print(results)# Calculate sample size
from collections import Counter
ent = []
for x in TEST_DATA:
  ent += [i[-1] for i in x[1]['entities']]
print(Counter(ent))

我自己测试数据的结果。

精度显示所有标记的实体中有多少实体被正确标记。它显示了模型在辨别哪些实体属于某个标签时是多么敏感。回忆显示基于实际的标签,我们做了多少正确的。它显示了模型在挑选与标签相关的实体方面有多好。

例如,在带有“位置”标签的 60 个实体中,NER 模型正确地标记了其中的 84.2%(召回)。精确地说,在所有用“位置”标记的实体中,只有 43.2%的实体有“位置”标记。

如示例所示,在一项指标上得分极高,而在另一项上却没有,这是一个不好的迹象。该模型在“位置”标签的精确度上得分很低,因为它无法区分不同的标签,即使它有相对较高的召回分数。以此类推,由于模型发射了更多的子弹,更多的子弹可能会落在正确的目标上,即使许多子弹没有击中。

只有两个类别(标签)的 F-1 分数公式。

我们使用 F 分数来*衡这些指标,F 分数是在只有两种标签的情况下由上面的公式给出的。在多类分类中,如在 NER 模型中,分数根据大小对每个标签进行加权,并在所有标签中取*均值。当精度和召回率为零时,最低分为 0,这意味着所有东西都被错误标记。当精确度和召回率完美时,最高分是 1,这意味着一切都被正确标记。

总而言之,我的更新模型在确定所有“日期”方面做得非常好,但在所有其他标签方面做得很差,只捕捉到了大约一半。

使用模型

恭喜你!所有的努力都有了回报。现在您可以保存您的模型,并在您的下一个项目中使用它。

# Save the  model to directory
output_dir = Path('/content/')
nlp.to_disk(output_dir)# Use the model
output_dir = Path('/content/')
nlp = spacy.load(output_dir)

我们可以做得更好!!(改进模型)

对于不精通技术的人来说,设置 NER 注释器可能具有挑战性。这里有一个(尽管有点不完美)方法,通过使用 Google Sheets 的更多协作来添加更多的训练数据。

  1. 创建一个带有“实体”和“标签”列的谷歌表
  2. 将数据验证添加到“标签”列,这样所有标签将统一显示
  3. 按照这篇 TDS 文章中的说明访问电子表格数据。
  4. 当将table转换成熊猫数据帧时,使用train_df = pd.DataFrame(table[1:], columns=table[0])
  5. 然后用下面的代码将它添加到您的训练数据中。
# Add training data from Google Sheets
for i in train_df.index:
  TRAIN_DATA.append([
      train_df.ENTITY[i],
      {
        'entities': [
          [0, len(train_df.ENTITY[i]), train_df.TAG[i]]
        ]
      }])

现在,你可以与你的项目合作伙伴分享谷歌表单,以纠正他们在 NER 模型中看到的错误,并且你可以将正确的标记硬编码到模型中。

然而,这种强力方法的主要缺陷是它没有包含单词嵌入。该模型基于句子或段落中的上下文来确定哪个字符序列是标记,以及哪个标记属于哪个标签。当我们按原样将令牌输入到模型中时,它并不知道令牌在不同的上下文中会如何变化。

然而,我希望这篇文章已经给了你一个训练你自己的 NER 模型的起点!我还希望理解 NLP 模型令人眼花缭乱的背后的困难,能够更好地理解这些刻板模型中的工作。

如果你知道一个更省时和/或协作友好的方法来训练 NER 模型,我很乐意学习更多!

注意:这篇文章并没有深入到 spaCy 所做的所有酷的幕后工作。我想在另一篇文章中公正地阐述这些概念,所以请密切关注!

如何掌握熊猫进行数据科学

原文:https://towardsdatascience.com/how-to-master-pandas-for-data-science-b8ab0a9b1042?source=collection_archive---------0-----------------------

使用来自 envato elementsmir_design 的图像创建(经许可)。

入门

这是数据科学需要的基本熊猫

Pandas 是一个开源的 Python 库,允许处理表格数据(探索、清理和处理)。该术语源于计量经济学术语 panel data 并由此产生PAN(El)-DA(ta)-S

在高层次上,Pandas 在处理行和列时非常像一个电子表格(比如 Microsoft Excel 或 Google Sheets)。Pandas 是任何数据科学工作流的支柱库之一,因为它允许您执行数据的处理、争论和管理。这一点尤为重要,因为许多人认为数据预处理阶段占据了数据科学家 80%的时间。

在本文中,我们将探索掌握 Pandas 所需的基本知识,以便开始学习数据科学。正如您将看到的,Pandas 是一个功能丰富的库,甚至整个 Pandas 文档 都可能是一个挑战,因为它多达 3411 页(在撰写本文时)!

1.对数据争论的需求

George Fuechsel 在计算机科学和软件工程中经常使用的一个流行短语是:

“垃圾进,垃圾出。”

—乔治·富希塞尔,IBM 程序员

它明确指出,无论一个程序有多好,如果输入的质量很差,生成的输出将是不相关的。这在数据科学中有很好的通用性,因为模型只有在给出它的输入数据的情况下才是好的。因此,数据清理有助于以这样一种方式处理数据,即数据中没有丢失的值,数据结构和值具有一致性,等等。

简而言之,如果您正在处理表格数据,那么 Pandas 就是您处理数据所需的首选库。

2.我们为什么需要熊猫?

下图总结了数据科学生命周期的典型工作流程。

数据科学生命周期。作者绘制。

一旦收集了数据,它们可能会存储在单独的数据库中,并且必须检索来自异构数据源的这些数据的汇编,以便在数据科学项目中使用。数据科学项目中的大部分工作可能会花费在数据清理阶段以及探索性数据分析上,因为这两个阶段都有助于提供高质量的数据集(即,在密集的数据清理之后)并提供对数据的高级理解,这是制定假设的良好起点,随后可以通过探索性数据分析以及机器学习模型构建来验证假设。

Pandas 库具有大量功能,允许您执行从原始数据的第一次输入、清理和转换到最终整理形式的任务,以便产生高质量的数据(即,希望没有缺失值和错误),通过探索性数据分析和机器学习进行进一步的假设测试和验证。

3.熊猫基础知识

3.1.熊猫物品

熊猫允许我们使用表格数据集。让我们来看看熊猫的基本数据结构,它由以下三种类型组成(,前两种是数据结构,后者作为参考点):

  1. 系列
  2. 数据帧
  3. 索引

在下图中,我总结了熊猫数据结构的基本结构。简而言之,您将看到熊猫数据帧和熊猫系列被标记为数据(,即,它有行名和列名)。您还会看到,Pandas DataFrame 是 Pandas 系列的集合(单独的列和行)。

熊猫数据结构剖析。作者绘制。

3.2.系列

熊猫 系列 是一个一维数组,与 NumPy 数组非常相似,但具有标记功能(轴标签或也称为 索引 )。一个系列可以容纳一个整数、浮点数、字符串、python 对象等。在高层次上,可以将系列视为 Microsoft Excel 中的一列。

3.3.数据帧

一只熊猫 DataFrame 是一个二维数组。在高层次上,数据帧可以被认为是 Microsoft Excel 中的电子表格(M×N 矩阵,其中 M 表示行,N 表示列)。

3.4.索引

Pandas 中的 索引 是 Series 和 DataFrame 对象的固有属性,用作关于对哪些行和/或列执行操作(即对于 DataFrame)或对 Series 中的特定元素执行操作的参考点。默认情况下,Pandas 自动分配从 0 开始的索引号来表示行号或列号(如果没有明确定义)。

索引有两个主要特征:(1)是一个不可变的数组,(2)是一个有序的集合。

3.4.1。不变

简单地说,不可变意味着我们不能通过简单的赋值(像我们对数据帧的任何其他行所做的那样)来轻易地修改索引值,如下所示

index_value = pd.Index([0,1,2,3,4,5])
index_value[0] = 10

这将产生一个错误:

TypeError: Index does not support mutable operations

这样做的好处是,我们可以放心,索引将在编码过程中保持完整。然而,如果我们想给索引命名,可以通过pd.Index.rename()函数来完成。

3 . 4 . 2。数组

作为一个数组,我们可以通过执行简单的切片来检索索引中的特定值,如下所示:

index_value = pd.Index([0,1,2,3,4,5])
index_value[0]

这将提供:

0

3 . 4 . 3

Pandas 索引的工作方式非常类似于set数据结构,允许您对其应用集合操作。还记得我之前提到的索引可以作为你的系列和数据框架的参考点吗?

作为集合索引。作者绘制。

因此,您可以根据索引比较和连接(交集、并集、差集、对称差集、连接和追加)Pandas 系列和 DataFrame。

例如,您可以利用 Pandas index 来找出 2 个系列或 2 个数据帧之间哪些元素是相同的,哪些是不同的。还在迷茫?一个很好的例子是维恩图,它允许你检索前一句中提到的相同或不同的元素。

4.熊猫的使用案例

在这一节中,我们将从较高的层面来了解 Pandas 提供的一些功能,您可以将这些功能用于您的数据科学项目。

简而言之,这里列出了您可以使用 Pandas 执行的常见任务:

  • 创建数据对象
  • 加载和保存数据
  • 数据检查
  • 缺失数据
  • 索引、选择、添加、修改和删除数据
  • 数据过滤
  • 合并和联接数据
  • 重塑和透视数据
  • 分组数据
  • 排序数据
  • 汇总统计数据
  • 数据可视化
  • 时序数据
  • 字符串和分类数据

4.1.探索性数据分析的熊猫

现在让我们来看看熊猫在进行典型的探索性数据分析(EDA)。

本质上,EDA 让我们在被分析的数据集的高层次上有一个总体的理解。这可能有助于我们提出假设,以便在后续的统计分析和机器学习模型构建工作中进行探索(见下一节)。

  • 从 CSV 文件(pd.read_csv())加载数据。将其赋给一个变量,比如df
  • 通过df.shape查看数据的维度大小。
  • 通过df.head()df.tail()浏览数据的前几行或后几行,以获得数据的要点(我们有哪些变量及其数据类型,如分类或数值)。
  • 查找缺失值(,即pd.isna(df))。决定是删除缺失值还是估算缺失值(用 0 等任意值替换或用列的*均值或中值替换)。
  • 计算汇总统计(例如最小值、最大值、*均值、中值、标准差等)。)通过df.describe()对整个数据或分层数据(,即根据特定标准对数据进行分组,然后计算汇总统计数据;例如:通过如下所示的 groupby 函数,按类别标签对数据进行分组,并为每个类别计算汇总统计数据:df.groupby('name_of_variable_used_as_criteria').describe()
  • 创建一些基本的数据可视化(,如条形图,箱线图,热图,直方图等。)用于整个数据或通过df.plot.bar()功能用于分层数据。
  • 写一份报告,总结我们从这次 EDA 分析中获得的一些初步发现和见解。这也将帮助我们弄清楚正在分析的数据是否足够,或者我们是否需要收集额外的数据。

4.2.熊猫是统计分析和机器学习的先驱

如前所述,从 EDA 分析中获得的一些初步见解是一个很好的起点,可以帮助我们为更深入的统计分析和机器学习模型构建指明正确的方向。

统计分析可能需要对数据的不同子集进行比较,这些子集可能是先前通过经由 Pandas 执行 groupby 操作而获得的。Python 中一个流行的统计包是 statsmodels 库,还有一个新兴的非常健壮的库叫做 pingouin ,我在我的 YouTube 频道上的视频 中回顾了如何使用 Pengouin 库 在 Python 中轻松执行统计分析。

现在让我们来看看熊猫如何帮助我们建立机器学习模型。

  • 从 CSV 文件(pd.read_csv())加载数据。
  • 通过df.shape查看数据的维度大小。
  • 通过df.head()df.tail()功能检查第一行或最后几行来检查数据。
  • 寻找丢失的值(,即通过pd.isna(df))。决定是删除缺失值还是估算缺失值(用 0 等任意值替换或用列的*均值或中值替换)。
  • 将内容从df分配到XY变量,以便为通过 scikit-learn 库建立模型做准备。这可以按如下所示执行:
X = df.drop(['Y_variable'], axis=1)
Y = df['Y_variable]
  • 然后将XY变量用作 scikit-learn 库的输入数据,用于如下数据分割:
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2, random_state=42)
  • 然后,通过随机森林,在生成的训练和测试数据上训练机器学习模型,随后评估它们的模型性能度量,如下所示:
from sklearn.ensemble import RandomForestClassifier*# 1\. Define classifier*
rf = RandomForestClassifier(n_estimators=10)*# 2\. Train model* rf.fit(X_train, y_train)

*# 3\. Make predictions*
y_train_pred = rf.predict(X_train)
y_test_pred = rf.predict(X_test)

*# 4\. Training set performance**# 4.1\. Calculate Accuracy*
rf_train_accuracy = accuracy_score(y_train, y_train_pred) *# 4.2\. Calculate MCC*
rf_train_mcc = matthews_corrcoef(y_train, y_train_pred) *# 4.3\. Calculate F1-score*
rf_train_f1 = f1_score(y_train, y_train_pred, average='weighted') 

*# 5\. Test set performance**# 5.1\. Calculate Accuracy* rf_test_accuracy = accuracy_score(y_test, y_test_pred) *# 5.2\. Calculate MCC* rf_test_mcc = matthews_corrcoef(y_test, y_test_pred)*# Calculate F1-score* rf_test_f1 = f1_score(y_test, y_test_pred, average='weighted')

[## 如何用 Python 构建你的第一个机器学习模型

towardsdatascience.com](/how-to-build-your-first-machine-learning-model-in-python-e70fd1907cdd)

  • 也可以执行超参数调整,以便通过搜索最佳超参数集来提高模型性能。

5.学习资源

5.1.熊猫官方文件

正如在介绍性段落中简要提到的,整个熊猫文档由 3411 页组成。具体来说,文档由 4 部分组成:(1)https://pandas.pydata.org/docs/getting_started/index.html#getting-started,(2) 用户指南 ,(3) API 参考 ,(4) 开发者指南

官方的 Pandas 用户指南 提供了一个全面的文档,其中有大量的例子来解释每个功能是如何使用的。这些用户指南被方便地组合在一起,用于涵盖广泛主题的常见任务。如果你多少知道你想做什么,这是特别有用的。例如,如果你知道你想要更多关于如何在 Pandas 中选择数据的信息,那么你可以阅读关于 索引和选择数据 的指南。

如果你对一个特定的熊猫函数非常清楚,想要更多的信息,你可以深入到 API 文档中。如下图所示,您可以看到pd.concat()函数的所有输入参数,每个参数的含义以及如何使用它的例子。

显示感兴趣的特定函数的 API 文档的屏幕截图。

5.2.小抄

下面是一份官方的、伟大的熊猫小抄总结了熊猫的主要功能。这个熊猫小抄的灵感来自于 Rstudio 数据争论小抄。

普林斯顿顾问 Irv Lustig 制作的熊猫小抄。

DataQuest 制作的熊猫小抄有网页版和下载版。这些功能按任务方便地分组,如果您大致了解每个任务组或任务允许您做什么,这些功能将允许您快速实施。

由 DataQuest 制作的熊猫小抄

DataCamp 还创建了一个熊猫备忘单,总结了所有的功能,也是根据任务分组的。

DataCamp 制作的熊猫小抄。

Enthought 不仅在这个 Pandas cheat sheet 中对 Pandas 的功能进行了分组,而且他们还在这个长达 8 页的 cheat sheet 中提供了示意图来帮助理解 Pandas 的各种操作。

Enthought 制作的熊猫小抄

5.3.书

下面列出的所有书籍(除了杰克·范德普拉斯的《Python 数据科学手册》)都是关于熊猫的。

熊猫方面的书籍推荐。

结论

Pandas 是任何数据科学工作流程中的核心组件。对于一个初学者来说,学习使用熊猫似乎是一项艰巨的任务,因为有大量可用的熊猫功能。希望这篇文章可以作为读者在使用 Pandas 进行数据项目时可以参考的蓝图。

总之,我们对 Pandas 库进行了高层次的概述,考虑了数据争论的重要性,了解了 Pandas 中的基本数据结构,考虑了 Pandas 用于探索性数据分析和机器学习模型构建的用例,并探索了可用的学习资源以了解更多关于 Pandas 的信息。

公开

  • 作为一名亚马逊员工,我可能会从合格购买中获利,这将有助于未来内容的创作。

接下来读这些

✉️ 订阅我的邮件列表,获取我在数据科学方面的最佳更新(偶尔还有免费内容)!

关于我

我是泰国一所研究型大学的生物信息学副教授和数据挖掘和生物医学信息学负责人。在我下班后的时间里,我是一名 YouTuber(又名数据教授)制作关于数据科学的在线视频。在我做的所有教程视频中,我也在 GitHub 上分享 Jupyter 笔记本(数据教授 GitHub 页面)。

*https://www.youtube.com/dataprofessor

在社交网络上与我联系

✅YouTube:http://youtube.com/dataprofessor/
♇网站:http://dataprofessor.org/(在建)
♇LinkedIn:https://www.linkedin.com/company/dataprofessor/
♇Twitter:https://twitter.com/thedataprof/
♇Facebook:http://facebook.com/dataprofessor/
♇github:https://github.com/dataprofessor/
ϝinsta*

数据科学如何掌握 Python

原文:https://towardsdatascience.com/how-to-master-python-for-data-science-1fb8353718bf?source=collection_archive---------2-----------------------

envato elementsalexacrib 使用图像创建(经许可)。

入门

这是数据科学所需的基本 Python

那么你正在开始你的数据科学之旅,每个人都建议你从学习如何编码开始。您决定选择 Python,但现在却被大量可供您使用的学习资源弄得不知所措。也许你不知所措,由于分析瘫痪,你正在拖延学习如何用 Python 编码的第一步。

在本文中,我将作为您的向导,带您探索掌握 Python 所需的最基本的知识,以便开始学习数据科学。我会假设你以前没有编码经验,或者你可能来自非技术背景。但是,如果您有技术或计算机科学背景,并且了解以前的编程语言,并且希望过渡到 Python,那么您可以使用本文作为高级概述来熟悉 Python 语言的要点。无论哪种方式,本文的目的都是引导您了解 Python 语言与数据科学的交集,这将帮助您迅速入门。

1。为什么是 Python?

你可能会问的第一个(也是最著名的)问题是:

应该学什么编程语言?

在互联网上做了一些研究后,你可能会决定使用 Python,原因如下:

  • Python 是一种解释性的高级编程语言,具有可读性和易于理解的语法
  • Python 有丰富的学习资源
  • 根据 Python 软件基金会和 JetBrains 进行的 Python 开发者调查 2020 ,Python 具有很高的通用性和多种用例
  • Python 有大量用于执行各种操作和任务的库
  • Python 是一种流行语言根据 TIOBE 索引栈溢出开发者调查
  • Python 是雇主非常追捧的技能

2.Python 的用例

你可能有的另一个问题是:

Python 将如何帮助您的数据科学项目?

要回答这个问题,让我们考虑如下所示的数据生命周期。本质上有 5 个主要步骤,包括数据收集、数据清理、探索性数据分析、模型构建和模型部署。所有这些步骤都可以用 Python 实现,并且一旦编码,产生的代码是可重用的,因此可以重新用于其他相关项目。

数据科学生命周期。由作者绘制。

除了数据分析、数据科学和数据工程之外,Python 强大的多功能性允许它应用于无限的可能性,包括自动化、机器人、web 开发、web 抓取、游戏开发和软件开发。此外,Python 几乎被用于我们能想到的每个领域,包括但不限于航空航天、银行、商业、咨询、医疗保健、保险、零售和信息技术(参见 ActiveState 关于 十大 Python 用例 的数据表)。

3.学习 Python 的心态

3.1.你为什么学 Python?

弄清楚你为什么学习 Python 可能有助于你在生活遇到阻碍时保持动力。当然,坚持不懈和良好的习惯只能让你到此为止。有一个明确的学习理由可能有助于提高你的动力,引导你回到正轨。

3.2.不要害怕失败或犯错

学习任何新技能的一部分是深入学习方法。不要害怕失败或陷入困境,因为这些都是不可避免的。记住,如果你没有被卡住,你就没有在学习!我总是喜欢通过犯尽可能多的错误来学习新事物,积极的一面是学到了宝贵的经验教训,可以用于第二次解决它。

事实上,我已经从 Daniel Bourke 的一个博客中了解到 OODA 循环 ,我们越快迭代这个循环,我们就越能更好地实现预期目标。

OODA 环路示意图。由作者绘制。

OODA 环代表观察、定位、决策和行动,这最初是由美国空军上校约翰·伯伊德设计的用于战斗的军事战略。关键是速度,为了达到这个速度,循环中的迭代必须进行得更快。因此,当应用于实现编码项目时,我们迭代 OODA 循环的速度越快,我们学到的就越多。

3.3.学习如何学习

有大量的学习资源可用于学习 Python。根据与你共鸣的方法,选择那些最大化你学习潜力的方法。

3 . 3 . 1。阅读

如果阅读是你的事情,有几本很棒的书和书面教程可以让你学习 Python。
Python 基础知识:Python 实用入门 3
用 Python 自动化枯燥的东西:完全初学者实用编程
Python 速成班:基于项目的实用编程入门

在数据科学和机器学习的背景下使用 Python 的一些好书如下:
Python 数据科学手册:处理数据的基本工具
Python 用于数据分析:与 Pandas、NumPy 和 IPython 的数据争论使用 Scikit-Learn、Keras 和 TensorFlow 进行机器学习:概念、工具和技术

3 . 3 . 2。目测

也许你是一个视觉型的人,那么 YouTube 上有很多很棒的频道可以教授概念和实践教程。其中包括: freeCodeCamp数据教授编码教授CD 道场科里斯查费理工跟蒂姆Python 程序员数据学校

3 . 3 . 3。项目

什么也比不上边做边学。这也是将你的学习推向极限的最好方法。在 Kaggle 上可以获得大量数据集,这是获得启动自己项目的灵感的绝佳起点。Coursera指导项目也是在课程导师的指导下实施项目的另一种方式。如果您喜欢现场培训,Data Science Dojo 有一个介绍性的Python for Data Science程序,可以在一周内完成。

3.4.从跟随编码教程转向实现你自己的项目

能够成功地跟随教程和能够从头实现自己的项目是两码事。当然,对于前者,你可以成功地遵循教程中的每一个步骤,但是当你需要自己决定使用哪种方法或者使用哪种库/函数时,你可能会屈服于挑战并陷入困境。

那么,你如何才能从一个编码教程的追随者转变为真正能够实现自己的项目呢?在下一节中找出答案。

3.5.学习解决问题

答案很简单。你必须开始做项目。越多越好随着你从许多项目中积累经验,你将获得解决问题和构建问题框架的技能。

要开始,请遵循以下流程:

  1. 选择一个感兴趣的问题来解决。
  2. 理解问题。
  3. 把问题分解成最小的部分。
  4. 实现小部件。接下来,将这些部分的结果拼凑在一起,整体地看它们是否解决了问题。
  5. 冲洗并重复。

如果你对这个话题充满热情,或者它激起了你的兴趣,你也会发现这个项目更有吸引力。看看你的周围,你对什么话题感兴趣,想一想你想知道更多。例如,如果你是一个 YouTube 内容创建者,你可能会发现分析你的内容与它的性能(例如,浏览量、观看时间、观看时间、视频点击率等)的关系是很有趣的。).

3.6.不要多此一举

您应该熟悉使用 Python 函数来执行各种任务。简而言之, PyPIcondaGitHub 上的数千个 Python 库都预装了广泛的功能,开箱即可使用。

这些函数的本质是,它通常接受输入参数,用于在返回输出之前执行预定义的任务或任务集。运行函数时可以显式指定输入参数,但是如果没有指定,Python 会假设您使用的是一组默认参数。

在开始编写您自己的自定义函数之前,进行一些谷歌搜索,看看是否已经有一些库中的现有函数执行与您计划实现的功能相似的功能。可能已经有一个现成的函数,您只需要简单地导入并使用它。

3.7.学习新的库

应该注意的是,如果你熟悉一个库,你也有可能找到其他相关的库。例如,如果你已经熟悉使用matplotlib,使用seabornplotly应该很容易学习和实现,因为基础已经到位。类似于深度学习库(如tensorflowtorchfastaimxnet)。

3.8.调试和寻求帮助

当你为你的项目编码时,你的代码抛出了错误,因此你必须学会如何调试代码和解决问题。然而,如果错误超出了你的理解范围,你知道如何寻求帮助是非常重要的。

你应该问的第一个人是你自己。是的,我知道你可能想知道那将如何工作,因为你现在一无所知。问自己,我的意思是,在你向别人求助之前,你先试着自己解决问题。这很重要,因为它显示了你的性格和毅力。

那么你如何调试代码并解决问题呢?

  1. 请仔细阅读输出,因为错误原因已明确写在输出中。有时,即使是最简单的错误也可能会被我们遗忘,比如忘记安装一些库,或者忘记在使用变量之前先定义变量。
  2. 如果你仍然一无所知,现在是时候开始谷歌搜索了。因此,你现在必须学会如何掌握提出正确问题的艺术。如果你用不相关的关键词问谷歌,你可能在搜索结果中找不到任何有用的答案。最简单的方法是包含与问题相关的关键词。

在搜索查询中,我会使用以下内容作为关键字

<name of Python or R library> <copy and paste the error message>

对,基本就是这样。但是假设我想限制我的搜索,只搜索堆栈溢出,我会在搜索查询中添加site:stackoverflow.com作为附加语句。或者,您可以前往 Stack Overflow 并在那里执行搜索。

3.9 一致性和问责制

在任何学习旅程中,一个反复出现的主题是培养学习的习惯,这将有助于你在学习旅程中保持一致。坚持不懈地编码会让你的动力付诸行动,你用得越多,你就会变得越熟练。俗话说:

使用它或者失去它。

肯·吉发起的 66 天数据 计划是一个建立良好学习习惯、保持一致性和对学习负责的好方法。参与这项计划非常简单:

  1. 每天至少花 5 分钟编码或做数据科学
  2. TwitterLinkedin 上使用#66daysofdata 标签分享你的所作所为和所学。

4.Python 编码环境

4.1.集成开发环境

集成开发环境(IDE)可以被认为是存放代码的工作空间,不仅如此,它还提供了额外的便利和便利,可以增强您的编码过程。

IDE 的基本功能包括语法突出显示、代码折叠和括号匹配、项目中文件的路径感知以及运行选定代码块或整个文件的能力。更高级的特性可能包括代码建议/完成、调试工具以及对版本控制的支持。

Python 的流行 ide 包括:

  • VS Code —功能强大且高度可定制的 IDE。
  • PyCharm —另一个强大的 IDE,但可能需要付费订阅才能解锁 Pro 版本中的所有功能,除了社区版本提供了一个很好的标准 IDE。
  • Spyder — R 和 MATLAB 用户会发现这有一种 RStudio/MATLAB 的感觉。
  • Atom —一个初学者友好的界面,高度可定制。

4.2.Jupyter 笔记本

Jupyter 笔记本可以通过pipconda本地安装到您选择的任何操作系统(无论是 Windows、Linux 还是 Mac OSX)。Jupyter 的其他风格是 Jupyterlab,它也为更大更复杂的项目提供了工作区和类似 IDE 的环境。

Jupyter 笔记本的云变体已经成为所有有抱负和实践数据科学家的福音,因为它使每个人都能够访问强大的计算资源(CPU 和 GPU 计算)。

我在我的 YouTube 频道(Data Professor)的社区部分进行了一项调查,以了解哪些基于云的 Jupyter 笔记本在社区中最受欢迎。

从上面可以看出,五款受欢迎的 Jupyter 笔记本包括:

应该注意的是,所有这些笔记本电脑都提供免费层(可访问有限的计算资源)和专业层(可访问更强大的计算资源),这可能需要一些前期成本。可能还有更多,但以上是我经常听到的。

4.3.有用的插件

代码建议和完成插件,如Kite提供的插件,为加速编码过程提供了巨大的支持,因为它有助于建议代码行的完成。这很方便,尤其是当你必须长时间坐着写代码的时候。这里或那里节省的几秒钟可能会随着时间的推移而急剧累积。这种代码建议也可以兼作教育或强化工具(有时我们的思维会因为长时间的编码而停滞不前),因为它可以基于我们已经编写的代码的上下文来建议某些代码块。

5.Python 基础

在这一节中,我们将介绍开始使用 Python 所需要知道的最基本的知识。

  • 变量、数据类型和操作符——这是最重要的,因为你会在几乎所有的项目中经常用到。你可以认为这有点像字母表,是你用来拼写单词的积木。定义和使用 变量 允许您存储值以备后用,各种 数据类型 允许您灵活使用数据(无论是定量还是定性的数字或分类数据)。 操作符 将允许你使用过程和过滤数据。

  • 列出了理解和操作 —这对于预处理数据数组非常有用,因为数据集本质上是数值或分类值的集合。

  • 循环 —像forwhile这样的循环允许我们遍历数组、列表或数据帧中的每个元素来执行相同的任务。在高层次上,这允许我们自动处理数据。

  • 条件语句ifelifelse允许代码决定适当的路径来处理输入数据。如果满足某种条件,我们可以用它来执行某种任务。例如,我们可以用它来判断输入数据的数据类型是什么,如果是数字,我们执行处理任务 A,否则( else )我们执行处理任务 b。

  • 文件处理—读写文件;创建、移动和重命名文件夹。设置环境路径;在路径中导航等。

  • 错误和异常处理——错误是不可避免的,设计对这种错误的正确处理是防止代码停滞不前的一个好方法。

6.用于数据科学的 Python 库

  • 数据处理[pandas](https://pandas.pydata.org/)是处理常见数据格式的常用库,这些格式可以是一维Series ( 可以看作是DataFrame的一列)或二维DataFrames ( 常见于表格数据集)。
  • 统计分析[statsmodels](https://www.statsmodels.org/)是一个提供统计检验、统计模型以及建立线性回归模型功能的库。
  • 机器学习[scikit-learn](https://scikit-learn.org/)是构建机器学习模型的首选库。除了模型构建,该库还包含示例数据集、用于预处理数据集以及用于评估模型性能的实用函数。
  • 深度学习 —深度学习的热门库有 TensorFlow ( [tensorflow](https://www.tensorflow.org/))和 PyTorch ( [torch](https://pytorch.org/))。其他库包括[fastai](https://www.fast.ai/)[mxnet](https://mxnet.apache.org/)
  • 科学计算scipy是科学和技术计算的首选库,包括积分、插值、优化、线性代数、图像和信号处理等。
  • 数据可视化 —有几个用于数据可视化的库,最流行的是[matplotlib](https://matplotlib.org/),它允许生成各种各样的图。[seaborn](https://seaborn.pydata.org/)是一个替代库,从 matplotlib 中提取其功能,但结果图更加精炼和吸引人。[plotly](https://plotly.com/graphing-libraries/)允许生成交互式情节
  • web 应用[django](https://www.djangoproject.com/)[flask](https://flask.palletsprojects.com/en/2.0.x/)是 Web 开发以及部署机器学习模型的标准 Web 框架。*年来,最小且更轻量级的替代方案因其实施简单快捷而广受欢迎。其中一些包括[streamlit](https://streamlit.io/)[dash](https://plotly.com/dash/)[pywebio](https://pywebio.readthedocs.io/)

7.编写漂亮的 Python 代码

2001 年,吉多·范·罗苏姆、巴里·华沙和尼克·科格兰发布了一份文档,建立了一套编写 Python 代码的指导方针和最佳实践,名为pep 8。特别是,PEP 是 Python 增强提案的 acynoym,PEP8 只是发布的众多文档之一。PEP 8 的主要目的是提高 Python 代码的可读性和一致性。

正如吉多·范·罗苏姆所说:

“代码被阅读的次数比它被编写的次数多得多”

因此,编写可读的代码就像向前支付,因为它要么被你未来的自己阅读,要么被其他人阅读。我经常遇到的一个常见情况是我自己或我的同事编写的糟糕的代码,但幸运的是,这些年来我们已经有所改进。

8.记录您的代码

一写完代码就记录下来总是一个好主意,因为很有可能,久而久之,你可能已经忘记了为什么使用某种方法而不是另一种方法的一些原因。我还发现,将我的思路纳入某些代码块会有所帮助,你未来的自己可能会欣赏这一点,因为它很可能成为在未来某个时间点改进代码的良好起点(当你的大脑处于新的精神状态,想法可能会更好地流动)。

9.练习您新学到的 Python 技能

做填字游戏或数独是很好的精神锻炼,为什么不做同样的事情来测试你的 Python 技能呢。leet codehacker rank等*台帮助你学习和练习数据结构和算法,为技术面试做准备。数据科学领域的其他类似*台还有 面试查询StrataScratch

ka ggle是有志于数据科学家通过参加数据竞赛的方式学习数据科学的绝佳场所。除此之外,还有大量的数据集可以练习,还有大量的社区出版的笔记本可以从中汲取灵感。如果你热衷于成为顶尖的 Kaggler,Coursera 有一个关于如何赢得数据科学竞赛的课程:向顶尖 ka ggler 学习可以帮助你。

10.分享你的知识

因为程序员经常依赖橡皮鸭作为教学工具,在那里他们会试图解释他们的问题,这样做允许他们获得观点,并且经常找到这些问题的解决方案。

作为一名有抱负的数据科学家或正在学习新工具的数据科学家,最好的学习方法是将它教给其他人,这也是费曼学习技巧所陈述的。

费曼技术的示意图。由作者绘制。

那么具体怎么教呢?实际上有很多方法,我列举如下:

  • 教一个同事——也许你可以招待一个你可以教的实习生
  • 写博客 —博客是一种很好的教学方式,因为有大量的学习者希望通过博客来学习新的东西。技术博客的热门*台有 Medium 、Dev.to 和 Hashnode。
  • 制作一个 YouTube 视频 —你可以制作一个视频来解释你正在学习的一个概念,甚至是一个实用的教程视频,展示如何使用特定的库,如何建立一个机器学习模型,如何建立一个 web 应用程序,等等。

11.为开源项目做贡献

为开源项目做贡献有很多好处。首先,您将能够向该领域的其他专家学习,也能够从审查其他人的代码中学习(通过审查问题和拉式请求)。

GitHub 上 tensorflow 项目的 Pull requests 页面截图。

其次,你也将有机会在贡献你的代码时熟悉 Git 的使用(开源项目托管在 GitHub 以及 BitBucket、GitLab 等相关*台上。).

第三,随着你获得社区和同行的认可,你将能够与社区中的其他人建立联系。你也会对自己的编码能力更有信心。谁知道呢,也许你甚至会创建自己的开源项目!

第四,你要向前支付,因为开源项目依赖于开发者在志愿者的基础上做出贡献。为更大的利益做出贡献也会给你一种满足感,因为你对社区产生了影响。

第五,你还将获得为现实世界项目做贡献的宝贵经验,这可能有助于你在未来找到自己的实习生或工作。

贡献并不意味着你必须为项目创建一个大而复杂的增强。你可以从纠正你可能遇到的一个小错误开始,这应该会让势头滚滚而来。

一个额外的好处是,当你修改代码时,你也可以提高你的编码和文档技能(例如,编写可读和可维护的代码)。此外,由此带来的挑战和责任也可以帮助你继续从事编码工作。

结论

总之,本文探索了 Python 在数据科学中的应用前景。作为一名自学成才的程序员,我知道不仅要学习编码,还要应用它来解决数据问题是多么困难。这个旅程并不容易,但是如果你能坚持下去,你会惊奇地发现在你的数据科学之旅中你可以用 Python 做多少事情。

我希望这篇文章提供了一些起点,在您开始学习之旅时,您可以使用它们来适应新的环境。请发表评论,提出任何对你有用的观点!

公开

  • 作为此处提到的服务的亚马逊准会员和附属会员,我可能会从合格购买中获得收入,这些收入将用于帮助创建未来的内容。

接下来读这些

✉️ 订阅我的邮件列表,获取我在数据科学方面的最佳更新(偶尔还有免费赠品)!

关于我

我是泰国一所研究型大学的生物信息学副教授和数据挖掘和生物医学信息学负责人。在我下班后的时间里,我是一名 YouTuber(又名数据教授)制作关于数据科学的在线视频。在我做的所有教程视频中,我也在 GitHub 上分享 Jupyter 笔记本(数据教授 GitHub page )。

**https://www.youtube.com/dataprofessor

在社交网络上与我联系

YouTube: 【http://dataprofessor.org】【Under construction】

【LinkedIn:】https://www.linkedin.com/company/dataprofessor/

https://www.linkedin.com/thedataprof】

【HTTP://facebook.com/dataprofessor/】

【GitHub:【HTTPS://github.com/dataprofessor/】**

如何掌握 Scikit-学习数据科学

原文:https://towardsdatascience.com/how-to-master-scikit-learn-for-data-science-c29214ec25b0?source=collection_archive---------2-----------------------

使用 koctiaenvato elements 中创建的图像(经许可)。

入门

以下是数据科学所需的基本知识

Scikit-learn是许多专门研究机器学习的 scikits(即 SciPy 工具包的简称)之一。一个 scikit 代表一个过于专门化而不能包含在SciPy中的包,因此被打包成许多 sci kit 中的一个。另一个流行的 scikit 是scikit-image ( 图像处理算法集)。

[Scikit-learn](https://scikit-learn.org/stable/)是 Python 中机器学习的支柱之一,因为它允许您构建机器学习模型,并为数据准备、模型后分析和评估提供实用函数。

在本文中,我们将探索掌握数据科学入门的scikit-learn所需的最基本的知识。我尽最大努力通过使用关键概念的手绘插图以及您可以在自己的项目中使用的代码片段来提取 scikit-learn 库的精髓。

让我们开始吧!

1.scikit-learn 中的数据表示

让我们从基础开始,考虑一下scikit-learn中使用的数据表示,它本质上是一个表格数据集。

在高层次上,对于监督学习问题,表格数据集将由Xy变量组成,而非监督学习问题将仅由X变量组成。

在高层次上,X变量也称为自变量,它们可以是感兴趣样本的定量或定性描述,而y变量也称为因变量,它们本质上是构建预测模型进行预测的目标或响应变量。

下图是在scikit-learn中使用的典型表格数据的动画说明。

scikit-learn 中使用的表格数据。由作者绘制。

例如,如果我们建立一个预测模型来预测个人是否患有疾病,疾病/非疾病状态是y变量,而通过临床测试结果获得的健康指标被用作X变量。

2.通过 Pandas 从 CSV 文件加载数据

实际上,数据集的内容可以存储在 CSV 文件中,并且可以通过pd.read_csv()函数使用Pandas库读取。因此,加载数据的数据结构被称为熊猫数据帧。

让我们来看看实际情况。

如何读入 CSV 数据的截图。

之后,可使用各种 Pandas 函数对数据帧进行数据处理,用于处理缺失数据(删除缺失数据或用估算值填充缺失数据)、选择特定列或列范围、执行特征转换、数据的条件过滤等。

在下面的例子中,我们将数据帧分离为Xy变量,它们将很快用于模型构建。

执行数据拆分的屏幕截图。

这产生了以下X数据矩阵:

X 数据矩阵的屏幕截图。

和下面的y 变量:

y 变量的屏幕截图。

对于如何掌握数据科学的熊猫的高层次概述,也可以查看我以前写的博客帖子。

3.scikit-learn 中的实用函数

除了机器学习能力之外,scikit-learn的一大优点是它的效用函数。

3.1.创建人工数据集

例如,你可以使用scikit-learn创建人工数据集(如下所示),这些数据集可以用来尝试你可能已经设计的不同的机器学习工作流程。

用于创建人工数据集的代码片段的屏幕截图。

3.2.特征缩放

由于特征可能是具有几个量级差异的异质尺度,因此执行特征缩放是必要的。

常见的方法包括归一化(将要素缩放到 0 和 1 的统一范围)和标准化(缩放要素,使其具有居中的*均值和单位方差,即所有 X 要素的*均值为 0,标准差为 1)。

scikit-learn中,可以使用normalize()功能执行标准化,同时可以通过StandardScaler()功能执行标准化。

3.3.特征选择

我喜欢使用的一种常见特征选择方法是简单地丢弃具有低方差的特征,因为它们提供最小的信号(如果我们从信号和噪声的角度来考虑)。

用于移除低方差特征的代码片段的屏幕截图。

3.4.特征工程

通常情况下,所提供的特征可能不容易适合于模型构建。例如,分类特征要求我们将这些特征编码成与scikit-learn中的机器学习算法兼容的形式(即从字符串到整数或二进制数字形式)。

两种常见的分类特征包括:

  1. 名义特征 —特征的分类值没有逻辑顺序,彼此独立。例如,洛杉矶、尔湾和曼谷等城市的分类值是名义值。
  2. 序数特征 —特征的类别值具有逻辑顺序,并且相互关联。例如,遵循诸如低、中、高等标度的分类值具有逻辑顺序和关系,使得低<中<高。

这种特征编码可以使用本地 Python(数字映射)、Pandas ( get_dummies()函数和map()方法)以及从scikit-learn ( OneHotEncoder()OrdinalEncoder()LabelBinarizer()LabelEncoder()等内部执行。).

3.5.输入缺失数据

Scikit-learn还支持缺失值的插补,这是构建机器学习模型之前数据预处理的重要部分。用户可以通过sklearn.impute子模块的SimpleImputer()IterativeImputer()功能使用单变量或多变量插补方法。

3.6.数据分割

一个常用的功能必须是数据分离,为此我们可以将给定的输入Xy变量分离为训练和测试子集(X_trainy_trainX_testy_test)。

下面的代码片段利用train_test_split()来执行数据分割,其中它的输入参数是输入变量Xy,测试集的大小设置为 0.2(或 20%),随机种子数设置为 42(这样,如果代码块运行多次,将产生相同的数据分割)。

用于执行数据拆分的代码片段的屏幕截图。

3.7.使用管道创建工作流

顾名思义,我们可以利用Pipeline()函数来创建一个任务链或序列,这些任务链或序列涉及到机器学习模型的构建。例如,这可以是由特征插补、特征编码和模型训练组成的序列。

我们可以将管道视为一组模块化乐高积木的使用,用于构建机器学习工作流。

有关使用 scikit-learn 构建自己的机器学习管道的更多信息,来自 Machine Learning Mastery 的 Jason Brownlee 在以下教程中提供了详细的说明:

https://machinelearningmastery.com/modeling-pipeline-optimization-with-scikit-learn/

4.使用scikit-learn的高级概述

4.1.构建和评估模型的核心步骤

简而言之,如果我能在scikit-learn中总结使用学习算法的核心本质,它将由以下 5 个步骤组成:

from sklearn.modulename import EstimatorName      # 0\. Import
model = EstimatorName()                           # 1\. Instantiate
model.fit(X_train, y_train)                       # 2\. Fit
model.predict(X_test)                             # 3\. Predict
model.score(X_test, y_test)                       # 4\. Score

通过使用随机森林算法作为示例,将上述伪代码转换为实际模型(例如分类模型)的构造将产生以下代码块:

from sklearn.ensemble import RandomForestClassifier
rf = RandomForestClassifier(max_features=5, n_estimators=100)
rf.fit(X_train, y_train)
rf.predict(X_test)
rf.score(X_test, y_test)

下图显示了在scikit-learn中使用估算器(学习算法功能)的核心基本步骤。

卡通插图总结了模型建立的评估者的创造,训练和应用。由作者绘制。

步骤 0。scikit-learn的一个模块中导入估算函数。一个估计器用于参考学习算法,例如RandomForestClassifier,该学习算法用于在给定输入X值的情况下估计输出y值。

简而言之,这可以通过等式y = f(X)得到最好的总结,其中y可以通过已知的X值进行估计。

步骤 1。实例化估计器或模型。这是通过调用估计函数并简单地将它赋给一个变量来实现的。具体来说,我们可以将这个变量命名为modelclfrf ( 所用学习算法的缩写,随机森林)。

实例化的模型可以被认为是一个没有来自数据的训练知识的空盒子,因为还没有发生训练。

第二步。现在将允许实例化的模型在被称为模型构建模型训练的过程中从训练数据集学习。

训练是通过使用fit()函数启动的,其中训练数据被指定为rf.fit(X_train)中的fit()函数的输入参数,字面意思是允许实例化的rf估计器从X_train数据中学习。计算完成后,模型现在在训练集上进行训练。

步骤三。现在,通过使用predict()函数,训练好的模型将被应用于对新的和未知的数据(例如X_test)进行预测。

结果,生成预测的 y 值(y_test)(并且可以存储到变量中,例如y_test_pred,该变量稍后可以用于计算模型性能)。

步骤四。现在可以计算模型性能了。最简单快捷的方法是使用model.score(X_test, y_test)中的score()功能。

如果该函数用于分类模型,则score()函数产生精度值,而如果是回归模型,则score()函数计算 R2 值。

为了完整起见,我们可以扩展这个核心工作流,使其包含其他额外的步骤,进一步提高构建模型的健壮性和可用性。

我将在接下来的章节中分别讨论这些额外的步骤。

4.2.模型解释

一个模型只有在能够从中提取洞察力以推动决策过程时才有用。

在上面建立的随机森林模型的延续中,存储在实例化的rf模型中的重要特征可以提取如下:

# Model interpretationrf.feature_importances_

上述代码将为模型构建中使用的要素生成以下一组重要值:

然后,我们可以通过将表示与特征名称结合起来整理表示,以产生一个清晰的数据帧,如下所示:

最后,可以使用这些值创建如下所示的要素重要性图:

简而言之,顾名思义,要素重要性图提供了通过重要性值判断的要素的相对重要性,例如从随机森林模型产生的基尼系数中获得的重要性值。

4.3.超参数调谐

通常,在构建前几个模型时,我会使用默认的超参数。在最初的几次尝试中,目标是确保整个工作流同步工作,不会出现错误。

我的机器学习算法是随机森林,我用它作为基线模型。在许多情况下,它也被选为最终的学习算法,因为它提供了稳健性能和出色的模型可解释性之间的良好混合。

一旦工作流程就绪,下一个目标就是执行超参数调整,以实现最佳性能。

虽然随机森林可能开箱即用,但通过一些超参数调整,它可以实现略高的性能。对于支持向量机等学习算法,为了获得稳健的性能,进行超参数调整是必不可少的。

现在让我们通过使用GridSearchCV()功能来执行超参数调整。

  1. 首先,我们将创建一个人工数据集并执行数据拆分,然后这些数据将作为构建后续模型的数据。

2.其次,我们现在将执行实际的超参数调整

3.最后,我们可以以可视化的方式显示超参数调整的结果。

随机森林模型超参数空间的交互式 3D 等高线图。

你可以 下载完整的 Jupyter 笔记本 ,上面的代码片段就是从这里摘录的。如果您喜欢视频,我还创建了一个 YouTube 视频,展示如何使用 scikit-learn 执行超参数调优。

Python 中机器学习模型的超参数调优@ 数据教授 YouTube 频道

5。机器学习工作流程示例

在这一节中,我将提供一个示例工作流,您可以将它作为一个通用指南,并将其应用到您自己的项目中。请随意试验和调整这里提到的程序。

可使用Pandas执行前 6 个步骤,而使用scikit-learnPandas(在数据帧中显示结果)和matplotlib(显示模型性能图或特性重要性图)执行后续步骤。

  1. 以 Pandas DataFrame 的形式读入数据,并显示第一行和最后几行。
  2. 显示数据集维度(行数和列数)。
  3. 显示列的数据类型,并总结有多少列是分类数据类型和数字数据类型。
  4. 处理丢失的数据。首先检查是否有缺失数据。如果有,决定是丢弃缺失的数据还是填充缺失的数据。此外,准备好提供一个理由来证明你的决定。
  5. 执行探索性数据分析。将Pandas groupby 函数(针对分类变量)与 aggregate 函数一起使用,并创建图表来探索数据。
  6. 将自变量分配给X变量,将因变量分配给y变量
  7. 执行数据拆分(使用scikit-learn)以使用 80/20 拆分比将其分离为训练集和测试集(记得设置随机种子数)。
  8. 使用训练集建立一个使用随机森林算法的机器学习模型(使用scikit-learn)。
  9. 通过使用GridSearchCV()功能,执行超参数调整和交叉验证。
  10. 通过predict()功能,应用训练好的模型对测试集进行预测。
  11. 借助Pandas将获得的模型性能指标解释为汇总表(我喜欢将合并后的模型性能显示为数据帧)或借助matplotlib以可视化方式显示。
  12. 解释随机森林模型确定的重要特征

6.S 的资源cikit-learn

所有有抱负的数据科学从业者通常会发现有必要偶尔浏览一下 API 文档甚至备忘单,以快速找到精确的函数或scikit-learn中无数可用函数的输入参数。

因此,本节提供了一些惊人的资源、备忘单和书籍,可能会对您的数据科学项目有所帮助。

6.1.证明文件

对,没错!最好的资源之一就是scikit-learn网站上提供的 API 文档用户指南示例

我发现跳到 API 文档 上获得关于可用的输入参数和每个参数的作用的详细描述是非常有用和快捷的。 示例用户指南 也有助于为我们自己的数据科学项目提供思路和灵感。

6.2.备忘单

sci kit-学习

一个非常方便的备忘单是由scikit-learn提供的,通过回答几个关于你的数据的问题来帮助选择合适的机器学习算法。

Scikit-learn 备忘单选择正确的评估工具的屏幕截图。

需要注意的是,上图是 scikit-learn 算法备忘单的预览。要充分利用此备忘单(您可以单击算法查看感兴趣的算法的基础文档),请转到下面的链接进入备忘单:

https://scikit-learn.org/stable/tutorial/machine_learning_map/index.html

数据营

另一个有用的备忘单是来自 DataCamp 的,它提供了一个 PDF 格式的单页表格和一个 HTML 版本。

这个备忘单的伟大之处在于它提供了可以由scikit-learn执行的各种机器学习任务的代码片段。

下面提供了备忘单的预览:

来自 DataCamp 的 Scikit-learn cheat sheet 的截图。

以下链接提供了 PDF 和 HTML 版本的备忘单:

https://www . data camp . com/community/blog/sci kit-learn-cheat-sheet

6.3.书

没有什么比你办公桌上的一些好书更好的了,你可以偶尔阅读或浏览一下,为你的项目寻找想法和灵感。有时,我会从书中提供的例子中找到一种处理事情的新方法。

这里有一些关于scikit-learn用法的好书,我个人也有,而且觉得非常有用。

https://amzn.to/3xOmM1A

Aurélien Géron 的《机器学习实践》是经典书籍之一,它很好地涵盖了用 Python 实现机器学习和深度学习模型的概念和实践方面。还有一个附录部分提供了一些关于如何建立机器学习项目的实用建议,这些建议可能对有抱负的数据科学家也有帮助。

在这个链接中,作者还分享了 GitHub 上的书中提到的代码的 Jupyter 笔记本。

https://amzn.to/2VVxkit

Jake VanderPlas 的《Python 数据科学手册》也是一本很棒的书,它涵盖了一些用于实现数据科学项目的重要库。特别是,本书涵盖了如何使用 Jupyter 笔记本、NumPyPandasMatplotlibScikit-learn

这本书的免费在线版本也可以在这里获得。另一个亮点是书中提到的 Jupyter 笔记本,它在 GitHub 这里提供。

结论

祝贺您到达本文的结尾,这也标志着用scikit-learn探索数据科学的无数可能性的开始。

我希望这篇文章对您的数据科学之旅有所帮助,如果我在scikit-learn中遗漏了对您的数据科学之旅有帮助的任何方法或资源,请不吝赐教。

公开

  • 作为一名亚马逊员工,我可能会从合格购买中获利,这将有助于未来内容的创作。

接下来读这些

✉️ 订阅我的邮件列表,获取我在数据科学方面的最佳更新(偶尔还有免费赠品)!

关于我

我是泰国一所研究型大学的生物信息学副教授和数据挖掘和生物医学信息学负责人。在我下班后的时间里,我是一名 YouTuber(又名数据教授)制作关于数据科学的在线视频。在我做的所有教程视频里,我也分享 GitHub 上的 Jupyter 笔记本(数据教授 GitHub page )。

https://www.youtube.com/dataprofessor

在社交网络上与我联系

YouTube:【http://YouTube . com/data proper/
网站:【http://data proper . org/【正在建设】
LinkedIn:【https://www . LinkedIn . com/company/data proper/

使用开源软件免费开始使用 SQL

原文:https://towardsdatascience.com/how-to-master-sql-for-free-with-open-source-7eb03e1a0dd0?source=collection_archive---------53-----------------------

开源 MySQL 入门指南

Unsplash 上由 SwapnIl Dwivedi 拍摄

或者任何与数据打交道的人(我最*听说是所有人),SQL 是那些真正能移山倒海的技能之一。如果你的工作场所使用 SQL,学习它可以极大地改善你的职业生涯。

虽然它在任何地方都被使用,但是它也很贵。我工作过或合作过的许多公司都使用了以下方法之一:

  • 微软的 SQL 服务器
  • Oracle 数据库管理系统
  • IBM DB2

这些都不是开源的,而且都有很高的价格。幸运的是,如果您想(或需要)学习 SQL 的详细内容,有大量免费的开源选项可供选择。

其中之一就是 MySQL。MySQL 是一个开源设置,反映了大多数公司正在使用的许多 SQL 产品。因此,无论你是计划和改变日常任务、团队,甚至是工作,MySQL 都是一个完美的起点。

在本文中,我们将介绍 MySQL 的基础知识。当我们从安装转移到数据库查询和数据转换时,我们不做任何假设并解释一切。简而言之,我们涵盖:

**> MySQL Installation
**  - Running the Server**> Getting Started**
  - MySQL Workbench
  - Schemas, Databases, and Tables
  - Uploading Data**> Querying Data**
  - SELECT * FROM ...
  - WHERE
  - ORDER and GROUP

MySQL 安装

首先,我们需要安装 MySQL。Windows 和 Mac 的安装都可以在这里找到。确保下载完整版,而不是网络版。

一旦安装程序开始,我们需要选择开发者默认并继续完成安装程序接下来的几个步骤。

安装完成后,还需要几个配置步骤。这些应该是直截了当的(如果不是,请在这里或在 Twitter 上给我自己留言)。此外,请确保设置 root 用户密码。

运行服务器

一旦安装完毕,MySQL 服务器应该建立在端口 3306 上。这应该会自动运行,但是如果不能,我们通过打开一个命令提示窗口(CMD,Bash 等)来实例化它。)并键入mysqld

如果这个命令没有被识别,在运行mysqld之前导航到 MySQL 服务器/bin目录。在我的 Windows 计算机上,位于:

C:\Program Files\MySQL Server 8.0\bin

入门指南

MySQL 工作台

一旦 MySQL 安装完毕,我们就可以打开 MySQL 工作台了

工作台是 MySQL 的瑞士军刀。它涵盖了所有内容,解释完整的包需要很长时间——所以为了精确起见,以及解释完整工作台所需的荒谬的经验水*——我们将坚持从基础开始。

我们可以点击正面屏幕上的本地实例 MySQL80 磁贴。这建立了到这个特定 MySQL 实例的连接,并打开了一个图形界面,允许我们探索这个实例。

在左边,我们将在我们的服务器实例上找到一个树状结构的数据库和表。

模式、数据库和表

SQL Server 的高级结构和层次结构

这种树状结构代表了 SQL 中对象的层次结构。

在这个层次结构的顶端是我们的服务器实例。在服务器内部是模式(与数据库同义,我们在这里将互换使用这两个术语)。模式内部是 SQL 表本身。

我们的数据存储在这些表中。因此,在 Workbench 中,我们可以继续创建我们的第一个模式和表。

创建模式

在左侧窗口的服务器层次结构中,您会注意到我们的服务器中已经有了几个模式。这些都是默认设置的——但通常情况下,我们需要自己创建。

为此,我们有两个选择。第一种是用点击:

1。点击顶部栏中的创建模式(数据库)图标

2。给新模式起一个好记的名字(至少比我的名字好),然后点击 Apply

3。接下来,我们应用模式创建脚本(这里不需要更改默认设置)

4。我们有了新的模式!点击完成即可。我们现在将能够在我们的输出窗口中看到模式创建:

另一种选择是以编程方式创建我们的模式。也就是说,写一些 SQL 代码,而不是点击鼠标。我们可以通过以下方式做到这一点:

1。点击顶部工具栏的创建新的 SQL 选项卡,打开新的查询窗口

2。在新的查询窗口中输入CREATE SCHEMA ;

3。点击闪电图标(执行全部/选定代码)

4。我们又有了新的模式!我们可以再次在我们的输出窗口中看到模式创建:

太好了,这是创建 MySQL 模式的两种方式!现在让我们转向桌子。

创建表格

SQL 中的表可能稍微复杂一些。而对于模式,我们只需指定模式名,其他的什么都不用做——表需要结构和数据类型。

本例中的虚拟数据。

在本例中,我们将使用所示的虚拟数据。我们有三列;身份证,姓名和年龄。

这些列中的每一列都需要分配一个数据类型。

警告,这部分有点啰嗦——可以随意提前跳到 表创作

名称

在 SQL 中,我们调用 text VARCHAR ,在定义 VARCHAR 数据类型时,我们还需要将条目的最大长度(以字符为单位)传递给这个字段。

如果我们想定义一个长度在 1 到 8000 个字符之间的文本,我们应该写 VARCHAR(1–8000)。我们只需输入 VARCHAR(MAX)就可以超过 8000。

然而,我们不应该在不需要的地方使用 VARCHAR(MAX)——仅仅是因为它可能会使那些阅读您代码的人感到困惑,并且它被认为是一种不好的做法。

相反,在我们的 name 列中,我们希望分配一个范围,我们确信没有名字会超出这个范围。在我们的例子中,VARCHAR(2-20)数据类型可能满足所有可能的名称。

年龄

SQL 提供了许多不同的数字数据类型——数值型、浮点型、货币型、小数型等等。其中一种数据类型是 INT ,我们将在这里使用它。

INT 是 integer 的缩写,指的是一个整数(1、2 和 3,而不是 3.142、1.5 或任何其他非整数)。INT 涵盖了从-2.1B 到 2.1B 左右的任何整数[1]。

整数类型、它们的范围以及以字节为单位的大小。改编自[1]。

对于更小或更大的值,我们可以使用从 TINYINT (适合年龄)到 BIGINT 的各种其他整数变量。

TINYINT 非常适合用作我们的年龄数据类型。我们不希望看到一个负的年龄,因此我们可以使用从 0 到 255 的任何整数值,这比我们希望任何客户达到的年龄都要大得多。

在定义 TINYINT 数据类型时,我们必须向它传递一个数字。这个数字是我们可以显示的最大数字/字符数。因此,如果我们想显示 0-255,我们的最大位数是三(255)。

或者,如果我们想显示-128 —我们的最大位数是四位(-128)。对于年龄,我们只需要三位数,给我们TINYINT(3)

id

最后,我们来到我们的 ID 栏。我们用它来为我们的每个记录提供一个唯一的标识符。

这里我们使用左表的 customer_id 来连接使用右表的主键( id )的记录。

通常,这将用于匹配不同表中的相应记录。例如,我们可能有一个销售表,其中包含所有销售的列表。这可能包含一个 customer_id 列,它将客户表中的客户详细信息匹配到这个销售表中。

在我们的例子中,我们的 id 是数字,所以我们可以使用 SMALLINT、MEDIUMINT 或 INT。然而,值得注意的是,作为 ID 值,我们可以轻松地使用 VARCHAR——在许多情况下,这可能更合适。

所以我们可以使用 INT 或者 VARCHAR。在我们的例子中,我们希望自动分配 ID,每增加一条新记录就需要增加 1。我们可以使用AUTO_INCREMENT告诉 SQL,但是这要求我们使用 INT 数据类型。

总之,这将为我们提供类似于SMALLINT(6)的东西(如果我们不期望超过 999,999 条记录的话)。

表格创建

同样,创建我们的表有两种方法。点击,或以编程方式。点击方式是:

  1. 在左侧栏中,展开新数据库,右键单击表、并选择创建表

2.输入列名和数据类型。我们为 id 选择 PK、NN 和 AI 标志,因为它们分别表示 P rimary K ey、 N ot N ull 和AutoIN 增量。

3.在下一个屏幕上,我们将看到用于创建我们的表的 SQL 代码——我们可以继续并应用它。

我们完了。另一种方法是以编程方式对此进行编码。为此,我们打开一个查询窗口,输入上面第三步中的 SQL 代码,并执行它。

上传数据

我们创建了一个表,但是它没有数据!我们需要上传它,我们可以从各种来源上传。对于本例,我们将使用如下所示的 CSV:

sample.csv,其中包含我们的样本数据。

为了将数据上传到 SQL,我们回到 MySQL Workbench 并:

1。导航器中右键点击表格,选择表格数据导入向导

2。浏览并选择要上传的文件,点击下一步

3。选择是创建新表还是将数据追加到现有表中。我们已经创建了表格,所以我们选择使用现有表格

4。然后我们点击下一步,直到导入过程结束。回到我们的查询窗口,我们可以输入SELECT * FROM new_table来确认上传成功:

最后,我们可以使用INSERT INTO命令添加更多数据:

注意,我们没有指定id值。这是因为我们已经将id设置为 auto-increment,这意味着 SQL 会自动为新行分配一个值,该值是前一行的+1。

查询数据

从…中选择*

最容易识别的 SQL 代码片段— SELECT * FROM <table-name>允许您显示表格中的所有列和行。

在 MySQL 中,一个额外的隐藏参数被添加到查询中。这是LIMIT 1000。LIMIT 允许我们返回给定数量的行。因此,尽管我们的表中有四条记录,键入SELECT * FROM new_table LIMIT 2将返回两条:

SELECT * FROM 查询,具有两行的限制

如果这不起作用,尝试首先在导航窗口中双击模式以选择它,然后再次执行。

此外,我们可以通过单击上面屏幕截图右上角可见的下拉菜单(在查询窗口内)来更改默认限制值。

在哪里

如果我们想要查看满足给定条件(或一组条件)的数据,我们可以使用WHERE子句。

WHERE 添加在我们的SELECT * FROM ...之后,只允许我们显示给定条件为真的行。在较大的数据集上,我们可能希望搜索具有给定名称的所有客户:

SELECT * FROM new_table WHERE `name` = 'paul';

或者,我们可能希望筛选年龄超过 30 岁的客户:

SELECT * FROM … 带有一个 WHERE 子句,用于筛选 30 岁以上的客户。

订单和组

ORDER BYGROUP BY是 SQL 查询的两个更基本的方法。首先,让我们在表中再添加几条记录。

name,age
Laura,27
Illaria,34
Luke,39
Tristan,39
Yess,27

(将这些保存到一个 CSV 文件,并像我们之前做的那样导入——使用现有的表格)

我们可以按给定的列进行排序,比如年龄,像这样:

这里,我们所有的值都按照年龄列以升序排列(从小到大)。升序ASC是默认的,但是我们可以通过在查询末尾添加DESC来切换到降序:

我们的另一个子句允许我们对给定的列进行分组。但是,在使用该选项时,我们将无法像以前一样选择*。原因是,如果我们按列分组,就没有逻辑方法来显示该分组中的其他列(如名称)。

因此,为了避免这种情况,我们可以对列应用可聚合操作(如 COUNT 或 SUM ),或者简单地排除它们:

我们可能还想在同一个查询中同时使用 ORDER BYGROUP BY——在这种情况下,我们总是将 GROUP BY 放在 ORDER BY 之前。

在 GROUP BY 之前放置 ORDER BY 将产生语法错误。此外,这也不符合逻辑。如果我们先订购,我们一组合就失去了那个订单。

这就是开始使用 SQL 和 MySQL Workbench 所需要知道的一切。我们涵盖了很多内容,包括:

  • 安装和设置 MySQL
  • 如何使用 MySQL Workbench
  • 什么是模式/数据库和表,以及如何使用它们
  • VARCHAR 和 INT 数据类型
  • 使用表格数据导入向导上传数据
  • SELECT * FROM …
  • 使用过滤数据,其中
  • 通过按顺序、分组、计数组织和转换我们的数据

SQL 可能需要一些时间来适应,但幸运的是,它相当用户友好,并且与许多技术相比,不需要很长时间就能胜任。

易用性加上它在世界上几乎每一个行业和公司中的普及性,使它成为一个非常值得熟悉的工具。

我希望你喜欢这篇文章!如果你有任何问题,请通过 Twitter 告诉我,或者在下面的评论中告诉我。如果你想要更多这样的内容,我也会在 YouTube 上发布。

感谢阅读!

参考

[1] 整数类型,MySQL 文档

🤖《变形金刚》课程 NLP 的 70%折扣

*所有图片均由作者提供,除非另有说明

如何掌握训练和测试集生成的微妙艺术

原文:https://towardsdatascience.com/how-to-master-the-subtle-art-of-train-test-set-generation-7a8408bcd578?source=collection_archive---------20-----------------------

它不仅仅是一个普通的功能

照片由 玛丽泰勒 像素

介绍

可以说,你从 Scikit-learn 学到的第一个函数是train_test_split。它执行最基本也是最关键的任务:将数据分成训练集和测试集。将相关模型与训练集相匹配,并在测试集上测试其准确性。听起来很简单。但是让我告诉你,这并不简单。一点都不简单。

Scikit-learn 提供了大量的 15 种不同的函数来根据不同的用例分割你的数据。有些你从未听说过,有些是日常使用的。但是不要担心,我们不会在这里一一介绍。相反,我们将只关注从初学者到围棋大师的科学家们最常用和最重要的方法。

具体来说,您将学习分类任务的train_test_split的最重要参数,换句话说,即分层以及如何使用cross_validatecross_val_scoreStratifiedKFold进行交叉验证。

这篇文章的所有代码示例都可以在 this Kaggle 笔记本或者 this GitHub repo 上找到。

https://ibexorigin.medium.com/membership

获得由强大的 AI-Alpha 信号选择和总结的最佳和最新的 ML 和 AI 论文:

https://alphasignal.ai/?referrer=Bex

还需要为train_test_split澄清?

首先,让我详细说明一下train_test_split。假设我们想使用钻石的属性(如克拉数和尺寸长度)来预测钻石的价格。作为样本数据,我们将从 Seaborn 加载diamonds数据集:

diamonds = sns.load_dataset('diamonds')
diamonds

数据集有几个数值特征和三个分类特征。因为我们想要预测连续的值,我们可以选择任何回归算法,比如任务的RandomForestRegressor

对于所有的 ML 算法,都有一个单一的、明确定义的过程:将数据分为训练集和测试集,在训练集上拟合模型,在测试集上测试精度。模型不针对所有数据进行训练的原因是,我们最关心的是模型如何处理看不见的数据。而且几乎总是,你不会有足够的全新的,真实世界的数据来测试。所以,唯一的选择就是把一些可用的数据放在一边进行测试。点击阅读关于培训和测试流程的更多信息。

使用 Scikit-learn 的train_test_split函数可以完成拆分任务。下面,我们选择用于预测钻石价格的变量作为特征( X 数组),价格本身作为目标( y 数组):

功能是从sklearn.model_selection引进的。对于前两个参数,我们首先传递特性数组,然后传递目标数组。测试集的大小由test_size参数指定——这里我们留出 30%的数据用于测试。random_state是种子,所以我们每次使用相同的参数运行函数时都会得到一致的结果。

我们将输出分解成 4 个变量。我希望您注意输出的顺序,因为很容易混合它们。

接下来,我们将使用默认参数拟合一个RandomForestRegressor模型,并对其进行评分:

这就是train_test_split回归的基本用法。但是如果我们把范畴包括进来,事情会变得更有趣。

抽样偏误

在我解释如何将train_test_split用于分类特征之前,我必须简单提一下采样偏差。当选择的样本不能代表总体时,就会出现抽样偏倚。

例如,一家冰淇淋公司可能会打电话给 1000 个人,询问他们喜欢什么口味的冰淇淋。为了不造成抽样偏差,或者换句话说,为了选择一个有代表性的比例,调查者应该尊重特定地区或城市的男女比例。如果该地区有 54%的男性和 46%的女性,公司必须确保调查 540 名男性和 460 名女性以获得代表性样本。

当我们将数据分成训练集和测试集时,我们实际上是从总体中抽取样本。因此,每当涉及到分类变量时,我们应该以某种方式分割数据,以保持类别的基本比例相同或接*相同。

形式上,这种类型的抽样被称为分层抽样,每个独特的类别被称为阶层。接下来,我们将看到如何在代码中使用这个方法。

train_test_split分层分割

分层采样在 Scikit-learn 中超级简单,只需在函数中添加stratify=feature_name参数即可。为了证明这一点,让我们用普通分割和分层来分割钻石数据集。

这一次,我们只使用分类变量。让我们看看XX_train中的类别比例:

你可能会认为比例上的差异不是很大。但在预测时,即使是最微小的微小变化也会破坏模型。这里有一个明显的例子:

作者图片

上面是一个 kNN 分类器的模型复杂度曲线,它是在一个普通的 split 上训练和测试的。如你所见,几乎所有的测试分数都高于培训。以下是模型在分层拆分中重新训练后的结果:

作者图片

您可以看到分层是如何极大地改变模型的性能的。

一般来说,当你看到测试分数高于训练分数时,不要过于兴奋,因为你创造了一些特殊的东西。恰恰相反,在你犯错的过程中😁🤦‍♂️.

以下是如何通过对钻石切割进行分层来分割数据:

stratify设置为一个分类特征(或目标,如果你正在进行分类,即stratify=y)可以确保完成分割以保持通过的列中类别的比例。如您所见,比例保留到小数点后第四位。

cross_val_score交叉验证

不管你如何调整train_test_split来得到一个完美的分割,都有可能结果是有偏差的。例如,在无限多的训练/测试集的变体中,您可能最终得到非常不*衡的廉价和昂贵的菱形特征集。这种情况很少见,但可能会导致一个完全无用的模型。对于较小的数据集,这种情况变得更加罕见。

处理这个问题的一种方法是使用一种叫做 k-fold 交叉验证的技术:

来自 Scikit-learn 文档

想法是重复训练-测试-分割过程几次 k 并且每次使用不同的训练和测试集。例如,5 重交叉验证意味着将数据分成 5 个大小相等的块,称为。然后,在折叠 2–5 上训练模型作为训练集,并在第一次迭代中测试折叠 1 上的性能。在下一个中,使用折叠 1、3、4、5 作为训练数据,使用折叠 2 作为测试集。在最后的第五次迭代之后,我们选择的模型将在所有数据上被独立地训练和测试。

通过这种方式,我们完全消除了由于随机机会而产生有偏样本的可能性。Scikit-learn 提供了cross_val_scorecross_validate函数作为整个过程的包装器。让我们从一个更简单的开始——cross_val_score:

我们将使用来自 Kaggle 的墨尔本房产数据通过 7 重交叉验证来预测房价。在每次迭代中,我们将拟合一个RandomForestRegressor模型并返回𝑅2,决定系数:

为了简单起见,我去掉了空值,只选择 4 个特性:

对于cross_val_score,我们传递初始化的模型、特征和目标数组,并用cv指定折叠的数量。输出包含每次迭代的分数:

如你所见,分数相差很大。你可以很容易地得到 R2 0.64 的分裂。有了分数列表,您可以对模型的性能更有信心:

默认情况下,cross_val_score使用被传递模型的.score方法所使用的评分方法。如你所见,回归变量的默认得分是决定系数。要传递一个定制的成本函数,比如*均绝对误差(MAE),您必须将其名称作为字符串传递给scoring:

我知道这有点令人惊讶。Scikit-learn 的交叉验证函数期望效用函数(越大越好)而不是成本函数(越低越好)。所以,传递给scoring的函数与 MAE 相反(负的)。这就是为什么我用-score把它们转换成正值。要查看您可以传递给scoring的所有得分者的姓名,请运行sklearn.metrics.SCORERS.keys()

cross_validate交叉验证

cross_val_score的缺点是它的功能非常有限,也就是说,它只返回每次迭代的分数。一次只能使用一个计分器,所有训练好的模型在执行后都会丢失。如果您想要计算几个性能指标并选择最佳模型,该怎么办?这就是cross_validate的用武之地。

它是一个更加灵活的交叉验证包装器,允许在每次迭代中使用多个评分器,并能够返回训练好的模型:

在一个单独的列表中,定义您想要计算的所有性能指标,并将其传递给scoring。此外,将return_estimators设置为True,以便返回每个列车随机森林。现在,输出不是一个计分器列表:

它是一个字典,包含 fit time、score time、所有返回的估计值和所有以关键字test_为前缀的评分函数的键值对。每个键都是一个字符串,对应的值是每次拆分返回的值的列表。让我们看看决定系数:

看起来第四次分割的估计量表现最好,所以我们可以提取它:

对于cross_validate的其他功能,还有许多其他的小调整。一定要看看令人敬畏的文档

尽管交叉验证很棒,但这是有代价的——折叠越多,执行时间越长。这就是为什么建议对小数据集(< ~50k)使用交叉验证。你会问,大规模数据集怎么样?嗯,随着数据的规模越来越大,获得非代表性样本的机会就越来越小。换句话说,交叉验证对于更大的量来说并不是真正必要的。

使用StratifiedKFold进行分层交叉验证

如果你决定使用分层拆分并同时进行交叉验证,你必须求助于另一个函数:StratifiedKFold。我们将返回钻石数据集,并使用RandomForestClassifier预测钻石的切工。我们先来看看StratifiedKFold是怎么用的:

不像train_test_split,我们先初始化它。我们设置我们想要的分割数量,并将shuffle设置为True,这将在进行分割之前打乱数据(在第一次分割之前只打乱一次)。洗牌通常是一个好主意,因为数据可能像时间序列数据一样预先排序。

接下来,我们使用类'.split'函数传递特性和目标数组:

结果是一个生成器对象,它包含每个分割的训练和测试索引。这意味着我们必须在每次迭代中循环并安装一个分类器:

请注意,我们不必在StratifiedKFold中指定要分层的特征。我们不需要这样做,因为这个类的构建是为了尽可能地保持每个特性的底层分布。

最后一件事,如果我们使用 Scikit-learn 中的任何分类算法,并将其传递给cross_validatecross_val_score,这些类会自动使用StratifiedKFold来启用分层。因此,在这一点上,你可能会有点失望,我们不得不学习分层简历的StratifiedKFold,而cross_validate可以在我不提及的情况下完成这项工作。

当您想要在每个分割中执行自定义操作,而不是将自己局限于cross_validate参数所提供的内容时,StratifiedKFold非常有用。

不知道接下来要读什么?在这里,我为你挑选了一些东西:

如何衡量数据质量

原文:https://towardsdatascience.com/how-to-measure-data-quality-815076010b37?source=collection_archive---------21-----------------------

你应该跟踪的 13 个指标(但不要跟踪)

照片由 Pexels 的 Gabby K 拍摄——作者修改

您需要可靠的信息来对风险和业务成果做出决策。这些信息通常非常有价值,因此您可能会通过第三方数据提供商直接购买,以扩充您的内部数据。

然而,您多久考虑一次数据质量对您决策的影响?不良信息会对业务决策产生不利影响,进而影响您的业务绩效、创新和竞争力。事实上,根据 Gartner 的调查,由于数据质量差,40%的业务计划未能实现其目标收益。

将信息视为公司资产的组织应该像对待其传统资产一样进行相同的质量评估。这意味着持续监控和提高他们信息的质量和价值。

在这篇文章中,我们将探索一个评估和比较数据质量的实用框架。您可以将此应用于内部产生的数据,以及从第三方供应商购买的数据。

评估数据质量是衡量信息资产整体价值的一个小而重要的组成部分,我已经在后续文章中对进行了描述。

客观数据质量指标

您可以将最常见的数据质量指标分为以下几类:

  1. 准确性 —每个可用数据字段代表现实的准确性如何?这也就是通常所说的数据的有效性
  2. 覆盖率 —有记录的事件或感兴趣的对象的百分比是多少?例如,如果您只关心北美公司,那么北美公司在数据集中所占的百分比是多少?
  3. 完整性 —在所有提供的记录中,有多少百分比的可用字段有值?
  4. 完整性 —如果数据中存在关系,相关属性之间的期望值被违反的频率有多高?例如,公司筹集的资金总额应该始终等于该公司各个筹款事件的总和,或者外键应该始终指向已存在的记录(参照完整性)。
  5. 一致性 —数据集内和数据集之间的数据在格式和结构上有多一致?
  6. 重复 —所有记录中有百分之多少是重复的?
  7. 精度 —数据有多精确?文本或图像等非结构化数据的详细程度如何?所提供数据的交付频率是多少?
  8. 及时性 —在任何给定时间,数据代表真实值的概率是多少?请注意,我们对现实世界中发生的事件和数据集中出现的事件之间的时间差不感兴趣。实际上,这很难验证,企业通常更关心数据集是否与源同步,而不是时滞本身。
  9. 可访问性 —可以访问数据并从中受益的业务流程或人员的数量。

主观数据质量度量

并非数据质量的所有方面都可以孤立于它们与数据用户的关系来考虑。一些质量指标纯粹是主观的,但对数据资产的利用率有重大影响。这些指标通常通过用户调查来衡量。

  1. 可信度 —用户是否信任他们正在查看的数据,或者这些数据是否被规避或被类似信息的替代来源所替代?
  2. 可用性 —从数据中提取价值以执行某些业务功能的难易程度如何?
  3. 客观性 —用户眼中的数据来源有多公正?
  4. 可解释性——数据的可理解性如何?是否有足够的文件支持原始数据?

请注意,人们可能会用“质量”这个词来表示数据的价值,但这是一个深入的话题,将在下一篇博文中单独讨论。

在实践中衡量数据质量

数据质量度量有多种用途。一个这样的用途是管理人员产生的信息的质量。

你可能会觉得有趣的是,通过影响人们管理和使用数据的方式的变化,测量本身就可以导致数据质量的提高。

您还可以使用这些实践来比较第三方数据提供商,他们都声称在所有竞争对手中拥有最佳的数据质量。

在实践中,通过将这种测量方法应用到数据流最多的地方,您可能会从中获得最大的提升。这往往是在软件系统和分析数据管道之间。

事实上,如果您已经很好地装备了您的业务,来自第三方数据提供商和业务流程的大部分数据应该流入数据存储,在那里您可以集中进行质量监控。

实施数据质量监控

虽然通过调查来衡量主观数据质量相对简单,但客观指标可能难以实现。

在 9 个客观数据质量度量中,我认为只有完整性完整性精度可访问性度量有可能完全自动化。

您可以通过应用用 SQL、另一种编程语言或专用软件编写的数据测试来监控这些指标。

使用 SQL 监控数据质量的一种方法是构建 BI 仪表板来跟踪“数据质量视图”,它运行对坏数据的查询,返回任何与预期不符的行。

或者,这些数据测试可以作为您的转换管道的一部分或先决条件,在通用编排工作流中使用像dbt-expectationsfordbtgreat-expectations 库这样的工具。

自动化提示 对于自动化质量检查,您应该在移动和转换数据的每个数据处理节点之前和之后验证您的预期(成本允许)。

对于其他指标,您可以从让一个人参与进来提供基本事实开始,并使用随机抽样从统计测试提供的效率中获益。在某些情况下,您不仅可以利用自动化来度量,还可以修复其中的一些数据问题。

下面,我分解了一些示例策略,您可以使用这些策略来逐个字段地评估的数据质量指标。为了开发特定数据集的整体“健康得分”,如果需要,可以应用进一步的聚合。

准确(性)

字段准确性= [#具有准确字段信息的记录] / [字段中有值的记录数]

为了获得每个领域的准确性,你需要一些你认为是基本事实的“黄金记录”。您可以通过手动注释一组实体或使用替代的高度精确的数据源作为代理来获得这个基本事实。

新闻报道

字段覆盖率= [#数据集中的真实世界实体] / [#真实世界实体]

如果您的实体的“宇宙”是预先定义的或者容易估计的,那么您可能能够获得一个自动化的覆盖率度量。

如果不是这样,您可以使用“错过”事件的数量作为覆盖范围的代理。当您意识到遗漏了一些实体时,您可以在您的业务流程中捕捉到这一点。

字段未命中率= [#未命中的真实世界实体触摸系统] / [#真实世界实体触摸系统]

复制

重复率= [#检测到的重复] / [#数据集中的记录总数]

这个看似简单的指标非常难以衡量,因为重复记录很难检测。

你可以使用人类注释器和聪明的采样策略(,我已经写了关于)来*似你的数据集的整体重复率,但是这很难扩展。

鉴于你的最终目标是消除重复,你最好使用外部软件供应商。对于个人和公司实体来说,这主要是一个已解决的问题,通用的重复数据删除策略可用于不太常见的重复数据删除问题

在极少数情况下,记录匹配供应商不能满足您的需求,您必须从头开始进行记录重复数据删除过程(如果您希望我在博客上讨论这个话题,请告诉我)。

你能做的最好的事情是进行适当的验证,从一开始就防止重复数据进入你的系统,因为防止数据输入问题要比修复它们容易得多。

警告 请谨慎处理重复数据删除,因为有时重复记录实际上是重复事件或现实世界中的独立实体。理想情况下,重复数据消除不应是破坏性操作,并且应维护匹配和操作的审核日志。

及时

及时性= [#数据集中准确表示当前真实值的记录] / [#记录总数]

正如我之前解释的那样,真实世界的事件与其在数据集中出现的时间之间的差异很难测量。此外,它没有观察数据时值同步的概率重要。

为了衡量及时性,您可以从“黄金记录”中抽取一个小样本,并计算匹配值与记录总数之间的比率。

易接*

可访问性度量是高度依赖于上下文的。您可能会发现测量一段时间内访问数据的用户数量就足够了。

或者,您可能对数据可用的系统数量感兴趣,并将其与数据相关或适用的系统数量进行比较。

在上面的指标中,建议我们引入“人在循环中”来提供目标值的可靠注释并不少见。要在实践中实现这一点,你可以使用低代码和无代码*台,如重组泡泡,在几个小时内完成一个注释过程。

从抽样过程中得出的指标只能给出可能产生该结果的潜在值分布的*均值。您可能对量化采样过程引入的不确定性感兴趣。

您可以通过参数化 Beta 分布来计算观测值的 90%置信区间,如下所示:

公制~ 贝塔 (⍺ = 分子+ 1 ,β =分母—分子+ 1 )

考虑这个问题的一个简单方法是术语。“命中”和“未命中”

要使用 Excel 或 Google Sheets 获得指标的 90%置信区间界限,可以使用BETA.INV(probability, ⍺, β) 函数。

例如,如果您从 50 个的随机样本中检测到 1 个重复的样本,您将按如下方式计算边界:****

*Duplication Rate = [# duplicates detected] / [# total records in the dataset]***5% Lower Bound =>** BETA.INV(0.05, 1+1, 49+1) = 0.7%
**95% Upper Bound =>** BETA.INV(0.95, 1+1, 49+1) = 8.9%

这意味着我们有 90%的机会可以从 0.7%到 8.9%的总体重复率中获得我们所做的结果!

了解与您的指标相关的不确定性对于确定您的数据质量是否真的在变化,或者它是否只是与随机过程相关的波动的产物,肯定是有用的。

结论

我们探讨了数据质量的核心维度,以及如何衡量它们以减少由于不可靠的信息而导致的路径所产生的浪费。

13 个数据质量维度|作者图片

跟踪这些数据质量指标的目标不是得到一个完美的度量,而是确定我们是否在朝着正确的方向前进,最重要的是,根据这些信息采取行动来改进我们的流程。

在您尝试测量您企业中每个系统的数据质量之前,我想提醒您的是并非所有数据都具有相同的价值,测量也不是免费的。

您应该确定 20%的数据在您的决策和业务流程中驱动 80%的价值。然后,在更广泛地应用这些技术之前,您可以对高价值数据子集的数据质量度量和改进工作进行优先级排序。

但是,您如何准确地评估和测量数据的价值,以及我们如何利用这些知识来制定我们的数据策略呢?

接下来—如何衡量数据的价值

想进一步讨论这个吗?请在 Linkedin 上发表评论或与我联系。

📕这篇文章最初发表在向我展示数据的博客上,在那里我讨论了更多关于数据驱动业务的话题。

如何衡量变量之间的关系

原文:https://towardsdatascience.com/how-to-measure-relationship-between-variables-d0606df27fd8?source=collection_archive---------3-----------------------

试图用最简单的形式解释协方差和相关性。

(图片由作者提供)

一次分析和可视化一个变量是不够的。为了在执行探索性数据分析时做出各种结论和分析,我们需要了解数据集中的变量是如何相互作用的。有许多方法可以直观地分析这种关系,最常用的方法之一是使用流行的散点图。但是散点图有一定的局限性,我们将在后面的章节中看到。从数量上来说,协方差和相关性用于定义变量之间的关系。

散点图

散点图是最常见的视觉形式之一,它可以让你一目了然地理解变量之间的关系。在最简单的形式中,这只不过是变量 A 对变量 B 的绘图:一个绘制在 x 轴上,另一个绘制在 y 轴上

%matplotlib inline
import matplotlib.pyplot as plt
plt.style.use('seaborn-whitegrid')
import numpy as npdf = pd.read_csv('weight-height.csv')
df.head()plt.plot(df.Height, df.Weight,'o',markersize=2, color='brown')
plt.xlabel('Height')
plt.ylabel('Weight')

图 1:散点图高度与重量:正相关

在上图中,很容易看出两个变量之间似乎存在正相关关系,即一个变量增加,另一个变量也增加。具有负相关关系的散点图,即随着一个变量增加,另一个变量减少,可以采用图 2 的形式。

#Just for demonstration purposes I have taken 'a' and 'b'
import numpy as np
import random
import matplotlib.pyplot as plt
a = np.random.rand(100)*70
b = 100-a
plt.plot(a, b,'o',markersize=2, color='brown')
plt.xlabel('a')
plt.ylabel('b')

图 2:散点图 a 与 b:负相关

两个变量之间没有明显关系的散点图将采用图 3 的形式:

import numpy as np
import random
import matplotlib.pyplot as plt
a = np.random.rand(1000)*70
b = np.random.rand(1000)*100
plt.plot(a, b,'o',markersize=2, color='brown')
plt.xlabel('a')
plt.ylabel('b')

图 3:散点图 a 和 b:没有明显的关系

一般来说,散点图最适合分析两个连续变量。使用散点图可视化两个离散变量可能会导致数据点重叠。让我们看看离散变量情况下的散点图。

x = [1,1,1,1,2,2,2,2,3,3,3,3]
y = [10,15,15,15,16,16,20,20,20,25,25,25]plt.plot(x,y,'o',markersize=5, color='brown')
plt.xlabel('X')
plt.ylabel('Y')

图 4:散点图 X 与 Y:离散变量

在上图中,并非所有的点都是可见的。为了克服这一点,我们将随机噪声添加到数据中,称为“抖动”。这个过程自然地被称为抖动,以允许那些重叠点的稍微清晰的可视化。

def Jitter(values, jitter):
    n = len(values)
    return np.random.uniform(-jitter, +jitter, n) + values
y1 = Jitter(y,0.9)
plt.plot(x,y1,'o',markersize=4, color='brown')
plt.xlabel('X')
plt.ylabel('Y1')

图 5:散点图 X 与 Y1:添加抖动

如图 5 所示,现在可以看到更多的数据点。但是,抖动应该仅用于可视化目的,并且应该避免用于分析目的。

在连续变量的情况下,也可能存在数据重叠,重叠点可能隐藏在数据的密集部分,异常值可能被给予不相称的强调,如图 1 所示。这叫做饱和。

散点图有其自身的缺点,因为它不提供关于关系的定量测量,而只是显示定量变化的表达。我们也不能用散点图来显示两个以上变量之间的关系。协方差和相关性解决了这两个问题。

协方差

协方差衡量变量如何一起变化。正协方差意味着变量沿同一方向一起变化,负协方差意味着它们沿相反方向变化,而 0 协方差意味着变量不一起变化或者它们彼此独立。换句话说,如果有两个变量 X & Y,正协方差意味着 X 值越大,Y 值越大,负协方差意味着 X 值越大,Y 值越小。

数学上,Cov(x,y)由下式给出,其中 dxi = xi-xmean,dyi = yi -ymean。请注意,以下是计算样本协方差时,用 1/(n-1)代替 1/n 的总体协方差公式。为什么会这样,超出了本文的范围。

Let’s understand this with an example: 
Consider, 
x = [34,56,78,23] 
y = [20,45,91,16] 
=> xmean = 47.75 
=> ymean = 43 
=> Sum of (dxi*dyi) = (34–47.75)*(20–43) + (56–47.75)*(45–43) + (78–47.75)*(91–43) + (23–47.75)*(16–43) = 2453\. 
=> Cov(x,y) = 2453/4 = 613.25

在上面的例子中,我们可以清楚地看到,随着 x 增加,y 也增加,因此我们得到一个正协方差。现在,让我们考虑 x 和 y 有单位。x 是以“厘米”为单位的身高,y 是以“磅”为单位的体重。协方差的单位是厘米-磅。不管那是什么意思!

协方差实际上可以取任何可以使用-1 到 1 范围内的相关性来克服的数。所以协方差并不能准确地告诉我们这种关系有多强,而仅仅是关系的方向。由于这些原因,解释协方差也很困难。为了克服这些缺点,我们使用相关性。

相互关系

相关性再次提供了关于变量之间关系的定量信息。如果变量具有不同的单位,或者变量的数据分布互不相同,那么测量相关性会很有挑战性。计算相关性的两种方法可以帮助解决这些问题:1)皮尔逊相关性 2)斯皮尔曼等级相关性。

这两种计算相关性的方法都涉及到将被比较变量中的数据转换成某种标准的可比格式。让我们看看这两种方法都做了哪些转换。

皮尔逊相关

皮尔逊相关包括将变量中的每个值转换为标准分数或 Z 分数,即从*均值中找出每个值的标准偏差数,并计算标准分数的相应乘积之和。

z 得分=(Xi-Xmean)/适马,其中 Sigma 表示标准差

Suppose we have 2 variables 'x' and 'y' 
Z score of x i.e. Zx = (x-xmu)/Sx 
Where xmu is the mean, Sx is standard deviation
Translating this info to our understanding of Pearson Correlation  (p):  
=> pi = Zxi*Zyi 
=> pi = ((xi-xmean)*(yi-ymean))/Sx*Sy 
=> p = mean of pi values 
=> p = (sum of all values of pi)/n
=> p = (summation (xi-xmean)*(yi-ymean))/Sx*Sy*n 
As seen above: (summation (xi-xmean)*(yi-ymean))/n is actually Cov(x,y). 
So we can rewrite Pearson correlation (p) as Cov(x,y)/Sx*Sy
NOTE: Here, pi is not the same as mathematical constant Pi (22/7)

皮尔逊相关系数“p”将始终在-1 到 1 的范围内。“p”的正值表示随着“x”增加,“y”也增加,负值表示随着“x”增加,“y”减少,0 表示“x”和“y”之间没有明显的线性关系。注意,零皮尔逊相关并不意味着“没有关系”,它只是意味着“x”和“y”之间没有线性关系。

皮尔逊相关“p”= 1 表示完全正相关,然而,0.5 或 0.4 的值意味着存在正相关,但这种关系可能不那么强。皮尔逊相关的大小或值决定了关系的强度。

但是,皮尔逊相关也有一定的缺点。如果数据中存在异常值,这种关联方法就不太适用,因为它会受到异常值的影响。如果变量 x 相对于变量 y 的变化是线性的,即当变化以恒定的速率发生时,当 x 和 y 都有点正态分布时,或者当数据在区间尺度上时,皮尔逊相关性工作良好。

皮尔逊相关的这些缺点可以用斯皮尔曼等级相关来克服。

斯皮尔曼等级相关

在 Spearman 方法中,我们将两个变量中的每个值转换为给定变量中的相应等级,然后计算等级的 Pearson 相关性。

Consider x = [23,98,56,1,0,56,1999,12], 
Corresponding Rankx = [4,7,5,2,1,6,8,3] 
Similarly, for y = [5,92,88,45,2,54,90,1], 
Corresponding Ranky = [3,8,6,4,2,5,7,1]

看看 Rankx 和 Ranky,这种方法的优势似乎很明显。Rankx 和 Ranky 都不包含任何离群值,即使实际数据有任何离群值,离群值也会被转换成一个秩,这个秩只不过是数据集中数字的相对正。因此,这种方法对异常值是稳健的。这种方法也解决了数据分布的问题。等级的数据分布将总是均匀的。然后,我们使用“皮尔逊相关性”部分中的公式计算 Rankx 和 Ranky 的皮尔逊相关性。

但是斯皮尔曼等级法效果很好:

  1. 当 x 像 y 一样变化,但不一定以恒定的速率变化时,即当 x 和 y 之间存在非线性关系时
  2. 当 x 和 y 具有不同的数据分布或非正态分布时
  3. 如果您想避免离群值的影响
  4. 当数据是有序尺度时

当等级重叠时,应该避免使用矛兵。

还有许多其他方法可以用来确定变量之间的关系。这篇文章只是让你开始这个话题的入门。

如果你喜欢在 Twitter 上极客化,并对收到可消化的 tweet 格式的文章感兴趣,别忘了在https://twitter.com/TrishaChandra16关注我,看看下面的 tweet 主题:

参考

这个主题的编写受到了 Allen B. Downey 的《Thinkstats》一书以及大量令人惊叹的数据科学和统计学文章的极大影响。

如何度量两个相关矩阵之间的相似性

原文:https://towardsdatascience.com/how-to-measure-similarity-between-two-correlation-matrices-ce2ea13d8231?source=collection_archive---------11-----------------------

数据科学教程

关于度量矩阵间相似性时使用什么度量以及如何计算显著性的教程

相关矩阵。图由作者制作。

比较矩阵之间的相似性可以提供一种评估变量之间结构关系的方法,通常用于跨学科,如神经科学流行病学生态学

让我们假设你有关于人们在观看一小段 Youtube 视频时的反应的数据。这可以通过面部表情、心率或呼吸来测量。这些数据的主题相似性矩阵将代表每个人的情绪与其他主题的相似程度。矩阵中的高相似性值意味着这些个体的反应比其他个体更相似。

您可以将此反应相似性矩阵与其他因素(如人口统计、兴趣和/或偏好)的相似性进行比较。这允许您直接测试一个领域中的相似性(例如情绪反应)是否可以用另一个领域中的相似性来解释(例如人口统计/偏好相似性)。

本教程介绍了可用于度量相似性矩阵之间的相似性的不同度量,以及如何计算这些值的显著性。

步骤 0:准备数据

我们来模拟一些数据进行分析。我们创建一个随机数据m1_um2_u,它们通过添加的噪声量nr相关联。接下来,我们使用默认的 pandas 关联函数为每个底层数据创建一个关联矩阵。让我们假设相关矩阵m1代表每个受试者的反应与每个其他受试者的反应有多相似,而m2代表每个受试者的偏好彼此有多相似。

我们可以用下面的代码来模拟和可视化这些矩阵。

相关矩阵 m1 和 m2。图由作者制作。

现在让我们看看如何测试这两个矩阵的相似性。

步骤 1:测量两个相关矩阵之间的相似性。

为了测量两个相关矩阵之间的相似性,首先需要提取顶部或底部的三角形。它们是对称的,但我建议提取上面的三角形,因为当把上面的三角形重铸回一个矩阵时,它提供了与其他矩阵函数更多的一致性。

提取上三角的方法很简单。您可以使用下面的函数upper,它利用了 numpy 功能triu_indices。从下图我们可以看到,提取的上三角与原矩阵相匹配。

该图比较了从上部矩阵提取的值和矩阵的实际顶部。图由作者制作。

现在您已经有了简单向量形式的矩阵,您可以使用您需要的度量来度量相似性。您使用的精确指标将取决于您正在处理的数据的属性,但建议使用等级相关性,如斯皮尔曼的ρ肯德尔的τ 。好处是,您不需要假设相似性的增加是线性的,并且结果对于异常值也更加健壮。

在本例中,让我们使用 Spearman 相关性来衡量相似性。

这产生了斯皮尔曼ρ为 0.15 的以下结果。Spearman 函数也提供了 0.038 的 p 值,但是使用这个值是不准确的。我们的数据是非独立的,这意味着上层矩阵中的每个单元格的值都不能独立提取,否则会影响来自同一受试者的其他单元格(点击了解更多信息)。或者,我们可以使用步骤 2 中概述的排列测试方法。

相关矩阵 m1 和 m2 之间的 Spearman 秩相关。图由作者制作。

步骤 2:用排列测试重要性。

我们的上矩阵中的每个单元格的值都不是相互独立的。独立是在主体的层次上,这将是我们要置换的。

在下面函数的 for 循环的每次迭代中,我们从一个相关矩阵m1中打乱行和列的顺序。我们重新计算两个矩阵之间的相似性,计算次数是我们想要置换的次数(例如 5000 次)。之后,我们可以看到有多少值高于我们的估计值,以获得 p 值。

排列结果。红色虚线表示真实 rho。图由作者制作。

如上图所示,我们的置换 p 在 p = .042 时比我们之前在 p = .038 时得到的更保守。

最后的想法

比较相似性矩阵可以帮助识别跨模态数据中的共享潜在结构。本教程提供了一个评估相似性和计算显著性的非参数排列测试的基本方法。

这种方法可以以多种方式扩展。一个扩展是比较两个相关矩阵之间的*均相似度。您可以使用相同的方法提取上面的三角形并置换数据,以获得差异的显著性。不过,需要补充的一点是,您可能希望使用 Fisher 变换将皮尔逊 R 转换为 Z 分布,以使该分布接*正态分布。

另一个扩展是比较两个距离矩阵,例如地理距离、欧几里德距离马氏距离。你所要做的就是创建一个距离矩阵而不是相关矩阵。以下链接中的完整 Colab 笔记本中包含了一个真实世界的例子,其中的数据比较了城市之间的距离与*均温差之间的关系。

感谢您的阅读。如果你喜欢这篇文章,请考虑订阅并支持像我这样的作者,通过我的推荐链接加入 Medium,通过它我可以免费获得一点佣金。这里还有一些你可能会喜欢的文章:

https://medium.com/age-of-awareness/heres-what-you-should-do-when-you-can-t-decide-according-to-science-484026c1eeca

如何在谷歌分析中衡量用户互动

原文:https://towardsdatascience.com/how-to-measure-user-interactions-in-google-analytics-cc5f5a32b02b?source=collection_archive---------7-----------------------

实践教程

利用独特的维度组合进行报告,以推动产品增长。

T 他的文章将带你了解以下内容:

  • 什么是互动?
  • GA 中的事件度量有什么区别?
  • 什么时候应该使用唯一的维度组合?
  • 如何计算互动率?

如何在 GA 中衡量用户互动以推动产品增长克洛伊·摩根

什么是互动?

交互是网站上与元素的任何接触点。这些是由分析师或谷歌分析用户定义的,可以是点击、悬停、滚动等。

交互率是与某个元素进行交互(点击、悬停、点击)的人的百分比。

在产品分析领域,互动率是一个非常有用的指标,可以帮助分析师找到网站或应用中客户可能遇到问题的地方。

假设一个软件工程师通知我们,网站上的一些添加到购物车按钮停止工作,我们需要知道通常使用这个元素的会话的百分比,以便开发团队能够理解修复这个按钮有多紧急。

该指标还可用于洞察用户可能转换或不转换的原因,并可用作目标和目的的关键绩效指标。

需要了解信息

Google Analytics(通用)中有 3 个主要指标:总事件唯一事件、以及一个更复杂的指标唯一维度组合。

这些指标通常使用 3 个维度进行分析:事件类别、事件操作事件标签。

如果你不熟悉谷歌分析(通用),看看我的视频系列开始:

如何使用谷歌分析克洛伊摩根

事件指标之间有什么区别?

为了了解用户在网站和应用上做了什么,我们可以看看三个事件指标:总事件唯一事件、唯一维度组合、,但有什么区别呢?

我们来看一个例子,有一个袜子网站的数据。我们将着眼于与产品组件的交互。

如果用户点击添加到购物车按钮 4 次,事件将被发送或“触发”4 次到 Google Analytics,并且总事件指标将为 4。

互动&理解独特的维度组合克洛伊·摩根

如果另一个用户也点击了 4 次添加到购物车按钮,那么这个按钮的总事件将是 8。Google Analytics 根据追踪组合触发的次数增加总事件数。

跟踪组合:

事件类别:产品卡

事件操作:单击

事件标签:添加到购物车

克洛伊·摩根如何衡量互动

对于独特的交互,Google Analytics 在会话中使用这些维度值第一次触发事件时计数 1,并忽略任何具有相同值的其他事件。

因此,在我们的添加到购物车按钮的例子中,唯一事件将是 2,每个客户在一个会话中点击一次。每次发送值时,总事件数指标都会计数。

接下来我们有独特的尺寸组合。此指标计算报告中每个维度的唯一维度值组合的数量。在大多数情况下,该指标通常与唯一事件的值相*,但根据您使用的维度不同,可能会有所不同。

独特的尺寸组合允许您组合组尺寸 而无需更新或添加额外的跟踪。

例子一

这个例子包含来自谷歌分析演示帐户的数据,所以你可以跟着做。

由 Chloe mor gan解释事件指标

这里我们有一些来自谷歌商品商店的互动事件。对于黑色 Youtube Cap 我们可以看到该产品已经被快速浏览共计 1045 次。

Chloe mor gan解释事件指标

但是其中只有 121 次是独特的。

克洛伊·摩根解释事件指标

这里我们可以看到独特事件,场次和独特维度组合是一样的。这是因为类别、操作和标签维度是同时发送到 Google Analytics 的。

克洛伊·摩根解释事件指标

假设您的利益相关者想要开展一项促销活动,并希望了解美国每台设备上有多少人与产品进行了互动。

如果您构建了一个包含国家/地区、设备并针对事件类别= 增强型电子商务进行了过滤的报告,您会发现与以前不同的是,您拥有不同的唯一指标值。这是因为国家和设备事件在会话中发送到 Google Analytics 的时间不同于增强型电子商务事件发生的时间。

Chloe mor gan解释事件指标

在这种情况下,举办独特的活动会夸大利益相关者推广的受众规模。唯一维度组合查看在一个会话内触发这些事件的会话的唯一数量。这给了我们有这一组行动的总人数。

例子二

如果你在谷歌商品网站上点击主页上的一顶黑帽子,主页上的一顶红帽子,男士页面上的一顶黑帽子,女士页面上的一顶黄帽子,你在谷歌分析中的互动看起来就像下表。

对于您已经采取的 4 个唯一操作,唯一事件总数将为 4,唯一维度组合将为 4。****

克洛伊·摩根计算事件指标

如果您从报告中删除了事件标签,Google Analytics 现在会在主页上显示 2 个唯一事件和 1 个唯一维度组合,用于我们与快速查看元素的交互。

这是因为独特事件正在对我们在这一页上与黑色和红色帽子的两次互动的价值进行求和。

克洛伊·摩根计算事件指标

记得事件类别、动作和标签在同一时间向谷歌分析开火。在我们的快速查看交互的情况下,我们点击黑色的帽子,交互被发送到谷歌分析。然后,我们点击红色的帽子,互动被发送到谷歌分析在另一个事件。(如下图)

克洛伊·摩根组合事件指标

如果我们想从整体上理解快速查看元素的独特交互,我们需要在一个独特的层次上组合或分组这些动作类别的交互。

由 Chloe Morgan 组合事件指标

多用户示例

在我们有多个用户的情况下,用户一点击黑色帽子的快速视图,事件被发送到 google analytics。用户一然后快速看了一眼红色的帽子,这个互动在一个单独的事件中被发送到谷歌分析。

用户二走过来,快速看了一眼黑色、红色和黄色的帽子。这些事件将被单独发送到谷歌分析。

由 Chloe mor gan和 Pexels为多个用户解释事件指标

为了了解总体快速查看性能,我们需要在事件-操作级别组合或分组这些指标。

如果我们在一个表中查看这个,独特事件将显示 5。

  • 2 用于用户一
  • 3 用于用户二

解释事件指标,Chloe mor gan的独特事件,Pexels 的图片

这是因为唯一事件仍在查看图表开头的数据,并将用户二的事件计为 3 次唯一点击,将用户一的计为 2 次唯一点击。

唯一维度组合查看图表的组合级别,因此计数为 2。

Chloe Morgan 解释事件指标多用户、唯一维度组合

回到我们的利益相关者的问题——有多少人通过设备与产品进行交互,独特的维度组合会对点击多个产品的任何客户进行折扣,会统计一次。

Chloe Morgan 解释事件指标重点示例

什么时候应该使用唯一的维度组合?

了解事件如何在你的网站上引发将有助于你找出使用哪个指标。

Chloe mor gan解释事件指标差异

  • 如果事件同时发送到 Google Analytics,唯一事件将与唯一维度组合指标相匹配。
  • 如果事件在会话中的不同时间发送到 Google analytics,这些指标将会不匹配,并且唯一的事件将会被夸大。
  • 如果有疑问,请始终使用唯一的尺寸组合,因为这在两种情况下都是正确的。

如有疑问,使用克洛伊·摩根的独特维度组合,故事集插图

计算交互率

如果我们想了解有多少人与“添加到购物车”按钮进行了交互,我们首先要查看所有看过该元素所在页面的会话。在 Google Analytics 中,您可以为发生交互的页面创建一个片段,以找到会话数。

接下来,我们将找出在 Sock product 页面上为添加到购物车而触发的事件的事件类别、动作和标签有多少个唯一维度组合

使用页面、事件类别、事件操作、事件标签按唯一的维度组合创建自定义报告,以找到此编号。

在本例中,100 个会话看到了袜子产品页面,80 个唯一维度组合被发送到 GA,用于点击添加到购物车的交互。

克洛伊·摩根解释互动率

现在,我们可以用会话* 100 除唯一维度组合来计算交互率。我们示例的答案是 80%。

克洛伊·摩根计算互动率

另一个有用的度量是一个会话中一个元素被交互的*均次数。(*均点击量)这是用来了解痛点的。

如果一个只需要点击一次或两次的元素有很高的*均点击次数。点击这可能表明用户卡住了,或者是因为失望而点击。

克洛伊·摩根计算*均点击数

让我们回顾一下

什么是交互?

  • 使用网站上的标签捕捉行为事件的分析。

我在哪里可以在谷歌分析中找到事件

  • 在自定义报告中或存储在界面中的 Behaviour > Events 下。

主要指标

  • 事件总数
  • 独特事件
  • 唯一维度组合

什么是唯一维度组合,何时应该使用?

  • 与事件组合交互的会话的唯一数量。
  • 最佳实践—在衡量独特的互动时,始终使用。

快乐分析!

克洛伊👩🏽‍💻📈

推特:@the_numerist

Github: chloeanalyst

如何衡量您的数据工作室统计数据

原文:https://towardsdatascience.com/how-to-measure-your-data-studio-statistics-2d8d2d9f5edb?source=collection_archive---------24-----------------------

使用 Google Analytics 监控重要的仪表板指标

丽芙·布鲁斯在 Unsplash 上的照片

你可能也有使用 BigQuery 的 Google Cloud 作为数据仓库和前端数据工作室吗?作为 BI 或 IT 部门,了解您的报告是否真的被用户使用会很有趣,对吗?截至数据下载时间,哪些报告特别受欢迎。有了谷歌分析,你可以做到这一点。

步骤 1:设置谷歌分析

第一步是设置谷歌分析,如果你还没有。这里很酷的一点是,你只需要一个免费的谷歌账户。之后,只需点击开始测量

设置 Google Analytics 按作者分类的图片

谷歌分析检查,除其他外,访问者的来源,他们花在个人网页上的时间,以及搜索引擎的使用,从而更好地监控广告活动的成功。著名的 KPI 有[1]:

  • 会话持续时间
  • 跳出率(如果有人来到一个页面,没有互动就离开了)
  • 命令
  • 查看联系信息

还有很多。

步骤 2:建立数据流

下一步是创建数据流,并输入要监控的报告的 URL。

建立数据流-按作者分类的图像

我想测量的仪表板是一个简单的测试,我想分析爱荷华州人民的饮酒习惯。数据源是 BigQuery,这是一个公共数据源,Google 已经友好地向所有人开放。

我的简单仪表板—作者图片

步骤 3:在报告中存储测量 ID

下一步是将来自分析的度量 ID 添加到 Data Studio dashboard 的报告设置中[2]。在这里,您必须遵循下面提到的步骤:

文件→报告设置→粘贴测量 ID

第四步:我们来测试一下!

成功了!我看到了一个测试电话,甚至是用什么设备,还有这个人在哪里。

摘要

Google Data Studio 和 Analytics 之间的交互也是从 Data Studio 和 Analytics 的方向快速方便地集成。我发现这个特性非常有用,原因有几个。首先,作为提供报告的部门,知道谁以及有多少用户正在访问报告是非常有用的。通常,这些部门必须证明其存在的合理性。这将是一个生成数字和确定改进潜力的好工具。还可以从访问报告的位置和下载数据的时间进行进一步的分析。在这里,我看到了上面提到的所有安全监控方面。

资料来源和进一步阅读

[1]谷歌,营销*台 (2021)

[2]谷歌数据工作室的 Mylluks Kertzel,s . 307–309(2018)

如何衡量您团队的 A/B 测试影响

原文:https://towardsdatascience.com/how-to-measure-your-teams-a-b-testing-impact-f74c6f2b4660?source=collection_archive---------27-----------------------

Air BnB 估算试验影响的方法

在评估已实现功能的影响时,我们通常使用 A/B 测试提升来评估该功能。然而,《赢家的诅咒》使得我们的治疗提升了,*均来说,夸大了一个特征的真实影响。

下面概述的调整允许我们考虑这种偏差,并对功能影响进行更可靠的估计。Air BnB 的例子见图 1。

图 1:对 Air BnB 的偏置调整精度的测试,在 7 次实验中运行。注意这些数字改编自论文

从实现的角度来看,偏差调整只是从特征的观察到的提升中减去一项。它的计算效率和实现简单。然而,开发鲁棒的精度测量需要一个保持组,这很难设计。

偏差调整技术 TLDR

1)确定每个实验的启动标准。启动标准( b ),即决定一项实验是否会投入生产的规则,是我们参考分布中表示统计显著性的临界点。对于α为 0.05 的 t 检验, b 为 1.96。

图 2:δ是实验升力,σ是标准偏差(或标准误差),而 b 是我们参考分布的截止值。

2)计算每个实验的偏差。偏差被定义为由于我们的数据中的自然变化而观察到我们的实验寿命的“可能性”,取决于我们的选择标准。这种可能性由未标准化的 z 值表示。

图 3: φ是正态分布 pdf ,A 是我们选择启动的一组实验。

3)从每个实验中减去偏差项,并对结果求和。我们现在可以开发一个调整后的总实验升力估计值,该值考虑了赢家诅咒的偏差。

图 4:估计无偏升力。

很简单,对吧?

我想是的,但是偏差调整实际上是如何工作的呢?

胜利者的诅咒

好的,要理解调整在做什么,我们首先需要理解为什么需要调整。赢家的诅咒是一个借用自经济学的概念,认为拍卖的赢家总是出价过高。要理解这种现象,以及它与在线 A/B 测试的联系,我们来看一张图。

图 5:展示赢家诅咒的直方图。

这里我们看到一个代表拍卖中所有可能出价的钟形曲线。大多数人会出价接*物品的真实价值,即中间的红线。然而,有些人可能对这件物品不感兴趣,所以他们会支付不足,提前离开拍卖。其他人可能真的对这件物品感兴趣,所以他们会支付远远超过其真实价值的价格。最有积极偏见的人会出价最高,赢得拍卖。

在这种情况下,胜出的出价必须高于所有其他出价。让我们用一个条件来定义它,其中管道“|”的左边取决于右边的不等式。

Winning Bid := bid | bid > MAX(all other bids)

太好了。现在我们有了这个条件,让我们把它和在线实验联系起来。

与拍卖不同,当运行 A/B 测试时,我们不知道处理的真实 影响。相反,通过一些统计意义来支持我们的结论,我们使用获胜(观察到的)影响来估计真正的影响。因此,当我们选择将治疗方法投入生产时,我们是在挑选最好的解决方案。

现在,如果我们选择非常积极和消极的影响,我们的选择*均来说是无偏的,但因为我们只选择积极影响高的治疗,我们更有可能选择高估。

请注意,全球抵制组织(即不具备上述任何特征的组织)可以轻松克服赢家的诅咒。从那里,我们可以进行 A/B 测试,其中处理是所有功能都已实现,控制是所有功能都不是。然而,全球抵制带来了几个问题,其中一些是…

  1. 高工程升力,
  2. 处于这种维持状态的用户看不到改进的功能,而且
  3. 抵制不能被实施来隔离单个团队的影响。如果我们想分别比较产品和 ML 团队的实验影响,我们需要一个支持者。

赢家诅咒的数学

事实证明,我们可以从数学上证明,对于我们投入生产的实验,我们的真实实验效果*均小于我们观察到的实验效果。这句话的最后一部分是关键;如果我们没有选择要实施的实验,就不存在选择偏差,胜利者的诅咒也不适用。

虽然数学对于实现来说不是必需的,但是它非常简单,所以我们将快速回顾一下。

我们希望证明我们观察到的提升的期望值(*均值)大于真实的、不可测量的提升。

图 6:观察到的升力大于真实升力的情况。

这里, O 是观察到的实验升力之和, T 是我们假设的真实升力之和。注意第二个量是不可测量的。还要注意,这些金额受我们实施其治疗的标准的限制。我们将这个实现条件表示为 A

为了包括实施标准,我们将该等式转换为图 7 中的总和。

图 7:总的观察影响减去总的真实影响的期望值。

这里,

  • j 是我们的 n 总用户的迭代器,
  • i中每一个实验的一个,我们设定的实验要启动、
  • Oⱼ 是我们在 A/B 测试中观察到的效果,以及
  • Tⱼ是我们真实的(不可测量的)效果。

下一步相当疯狂。我们将参考分布的实验临界值定义为δ/σ>b,其中 b 是置信度为α的分布的临界值。在英语中,我们利用统计显著性标准,并将该标准代入等式。请注意, b 的典型值是 1.96,这是置信度为 0.05 时的 t 统计值(单侧)。

这种替换产生了下面的等式。请注意,我们也将期望值移到求和中。

图 8:替换了 stat sig 标准的图 7。

从这里,我们可以从不等式的两边减去 Tⱼ,得到图 9。

图 9:图 8 从不等式的两边减去了我们的 T_j。

最后,因为 Oⱼ 严格大于 bσ* (根据我们的实现标准),我们可以保证 E[O] > E[T] 。算出每个例子都很冗长,但是如果你好奇,可以查看 3.2 部分的完整步骤。

我不确定你的看法,但我认为不等式替换是相当疯狂的。

偏置调整

现在我们已经对我们的问题有了一些直觉,让我们来谈谈解决方案。

图 10:我们的调整组件的模拟。

我们的目标是考虑在选择要实施的实验时引入的偏差;因为我们只选择非常积极的治疗,我们更有可能选择高估。

为了调整我们的升力,我们减去这个观察值被高估的“可能性”。同样,这种可能性由 z 得分乘以我们的度量标准的标准差来表示,这将标准化单位转换为我们的度量单位。

图 11:我们的真实总影响无偏估计的公式。

在图 11 中,我们看到了完整的调整公式。重点关注的区域是 φ 里面的分子,我们的正态概率分布函数(PDF)。我们可以看到,随着我们观察到的升力(δ)变大(由于正常 pdf 中的负号),我们的调整项变小。*如果我们的 lift 比我们的实现标准( bσ ᵢ)大得多,那就更值得信赖,更不容易出现偏差。

而且,所有这些标准差())只是用来在标准化正态分布(【N(0,1)】)单位和我们的度量单位之间移动。从直觉的角度来看,它们并不重要;它们只是方便使用普通的 pdf, φ 。**

置信区间

既然我们能够估计由于赢家诅咒而产生的偏差,我们可能想要计算我们在这个估计中的置信度。本文讨论了 3 种置信区间的计算:天真,自助和无偏自助。如果你想计算置信区间,只需参考论文或任何其他关于这些方法的讨论。

这就是你要的。实验影响的无偏测量。

实施说明

  • 对于这个公式,我们假设实验影响是相加的,即它们是按顺序测试的。如果不是这种情况,您将不得不调整数学来处理乘法影响。
  • 如数学中所暗示的,我们还假设每个分级实验都有正的和统计上显著的升力,即升力大于 b 。如果不是这样,你必须做一些调整。如果您对调整有任何疑问,请随时联系我们。
  • 实施时,重要的是要批判性地思考你的数字意味着什么。例如,确保实验处理中的目标用户能够代表你的用户群体。如果实验的目标是新用户,那么在全球范围内实施时,一定要根据新用户的数量而不是用户总数进行扩展。
  • 如前所述,维持组是评估总体功能影响的最准确的方法。如果可能的话,在第一次实现时,对您的评估和坚持组一起运行 QA。

感谢你完成这篇文章!我将再写 49 篇文章,将“学术”研究引入 DS 行业。查看评论,了解有关调整实验影响的更多链接/想法。

如何将您的数据从红移迁移到雪花

原文:https://towardsdatascience.com/how-to-migrate-your-data-from-redshift-to-snowflake-81208ebb2686?source=collection_archive---------28-----------------------

借助开源数据集成,轻松将您的数据从 Redshift 中取出并放入雪花中

作者图片

几十年来,数据仓库解决方案一直是企业报告和商业智能的支柱。但是,*年来,像亚马逊红移和雪花这样的基于云的数据仓库变得非常流行。那么,为什么有人想要从一个基于云的数据仓库迁移到另一个呢?

答案很简单:更多规模和灵活性。借助雪花,用户可以通过自动添加节点,快速独立地横向扩展数据和计算资源。使用 VARIANT 数据类型,雪花还支持存储更丰富的数据,如对象、数组和 JSON 数据。正如红移用户所知,调试红移并不总是那么简单。有时,它超越了可能引发迁移欲望的特性差异。也许你的团队只是知道如何比红移更好地使用雪花,或者也许你的组织想要在一个特定的技术上标准化。

本食谱将解释使用 Airbyte 从红移迁移到雪花以最大化您的业务价值所需采取的步骤。‍

先决条件

1。你需要 Airbyte 来移动你的数据。要部署 Airbyte,请遵循我们文档中的简单说明这里

2。红移和雪花都是 SaaS 的服务,你需要在这些*台上有一个账户才能开始。

3。当您使用 Redshift 创建数据仓库集群时,默认情况下,它会在其中添加样本数据。我们的数据存储在我们在‘开发’数据库中创建的“红移-星团”中。创建的集群可以在仪表板上的' Amazon 红移>集群'下看到。要创建一个新的集群,请单击下面突出显示的图标,然后继续操作。

作者图片

4a) 对于目的地,您需要在 Snowflake 中创建一个空的数据库和仓库来托管您的数据。为此,单击导航栏中显示的数据库图标,点击“创建…”。

作者图片

为您的数据库提供一个名称。在下面的例子中,我们将数据库命名为“雪花 _ 目的地”。‍

4b) 建立数据库后,点击仓库图标‘创建’一个名为‘计算 _ WH’的仓库。在我们的例子中,我们使用了一个 X-Small 计算实例。但是,您可以使用更大的实例类型或添加更多实例来扩展计算实例。这可以通过几次简单的点击来实现,并将在后面的部分中演示,以说明迁移的商业价值。现在,您已经具备了开始迁移的所有先决条件。

作者图片

步骤 1:在 Airbyte 中设置红移源

在网络浏览器中导航到 http://localhost:8000 ,打开 Airbyte。 1b) 填写以下详细信息,继续设置信号源-

作者图片

‘设置源’‘airbyte 屏幕中,我们在本例中将源命名为‘红移 _ 源’,但是如果您愿意,您可以将其更改为其他名称。我们选择的源类型为'红移'。其余的信息可以从红移星团仪表盘中获得,如下图突出显示的部分所示。

作者图片

除此之外,还有一些设置需要在你的红移控制台中进行调整。例如,假设您在本地机器上运行 Airbyte 并连接到 Redshift。在这种情况下,您需要使您的集群能够通过互联网公开访问,以便 Airbyte 可以连接到它。您可以通过导航到红移控制台上的“操作”下拉菜单,单击“修改公共可访问设置”并将其更改为“启用”(如果尚未启用)。

作者图片

作者图片

接下来,转到 AWS 提供的 VPC 服务。您可以在搜索栏中搜索它,如下所示。

作者图片

然后导航到左侧的“安全组”选项卡,进入如下所示的页面,创建一个自定义的入站和出站规则。例如,您需要在端口 5439 上创建一个自定义 TCP 规则,允许来自本地 IP 地址的传入连接。保存规则后,它将在控制面板上以蓝色突出显示。

作者图片

自定义入站规则需要具有如下图所示的规范。 注意,出站规则也需要做同样的步骤,然后您的红移源将准备好与 Airbyte 连接。

作者图片

步骤 2:在 Airbyte 中设置雪花的目的地

配置源之后,进入 Airbyte 中的“设置目标”页面来配置目标。

与上一步类似,目的地名称是可定制的。在本例中,我们使用了“雪花 _ 目的地”。然后,我们选择目的地类型为雪花。有关其他必填字段的详细信息,请参考下图。

作者图片

可以从雪花仪表板中检索主机值。

注意:在这个例子中,我们在雪花中使用 SYSADMIN 角色,但是强烈建议在雪花中创建一个定制角色,并减少使用 Airbyte 的权限。默认情况下,Airbyte 使用 Snowflake 的默认模式来写数据,但是如果您愿意,可以将数据放在另一个模式中(就像我们的例子中的 REDSHIFT_SCHEMA)。当您希望将正在迁移的数据与现有数据分开时,拥有单独的模式会很有帮助。最后,用户名和密码应该与创建雪花帐户时设置的凭证一致。

点击“Setup the destination”按钮,如果一切顺利,您应该会看到一条消息,告诉您所有的连接测试都已通过。

步骤 3:建立连接

一旦设置了目的地,您将被引导至 Airbyte 中的“设置连接”屏幕。在这一步中,您会注意到 Airbyte 已经检测到了要迁移的表和模式。默认情况下,选择所有表进行迁移。但是,如果您只想迁移数据的子集,可以取消选择要跳过的表。在此步骤中,您还可以指定详细信息,例如源和目标之间的同步频率。如图所示,有几个时间间隔选项,从 5 分钟到每小时。同步操作的粒度也可以通过为您的使用案例选择正确的同步模式来设置。阅读 Airbyte 文档中的同步模式了解更多详情。

作者图片

指定所有定制后,我们可以单击'设置连接',开始从红移到雪花的数据迁移。一目了然,您将能够看到连接的上次同步状态以及上次同步发生的时间。

作者图片

这就是使用 Airbyte 将您的数据从红移移动到雪花有多容易。但是,如果您想验证迁移是否已经发生,请查看雪花中的目标数据库,您会注意到还存在额外的数据表。

作者图片

步骤 4:评估结果

成功迁移数据后,让我们来评估激发迁移的雪花的关键特性。在雪花中,计算能力和存储是解耦的,使得雪花的存储容量不依赖于集群大小。此外,与 Redshift 繁琐的过程相比,Snowflake 只需简单的三次点击就能扩展数据。‍

作者图片

如下图所示,Airbyte 使用 VARIANT 数据类型将 JSON 数据加载到雪花表中。使用 Snowflake 强大的 JSON 查询工具,您可以处理存储在表中的 JSON 数据和非 JSON 数据。另一方面,Redshift 对半结构化数据类型的支持有限,需要多个复杂的子表连接来生成报告视图。

作者图片

结束了。

总结一下,我们在这个食谱中做了以下工作:

1.配置了一个红移气源

2.配置了一个雪花 Airbyte 目的地

3.创建了一个 Airbyte 连接,可自动将数据从红移迁移到雪花

4.使用 VARIANT 数据类型探索了易于使用的伸缩特性和对雪花中 JSON 数据的支持

我们知道,在时间紧迫的快速发展项目中工作的开发和运营团队需要积极开发 Airbyte 的开发人员快速回答他们的问题。他们还希望与“亲身经历过”的有经验的社区成员分享他们的经验

加入 Airbyte 社区 Slack 频道的对话,与 1000 多名数据工程师分享您的想法,帮助每个人的项目取得成功。

有了 Airbyte,集成的可能性是无限的,我们迫不及待地想看看你要构建什么!

原载于 Airbyte

如何将您的 Python 机器学习模型迁移到其他语言

原文:https://towardsdatascience.com/how-to-migrate-your-python-machine-learning-model-to-other-languages-6212c9bc61f9?source=collection_archive---------8-----------------------

关于如何将你的 ML 模型移植到 Java、Go、C++或任何其他语言的 3 步教程。这比你想象的要容易。

Unsplash 上的位云拍摄的照片

我最*在做一个项目,我需要训练一个在边缘运行的机器学习模型——这意味着,处理和预测发生在收集数据的设备上。

像往常一样,我用 Python 做了我的机器学习部分,我还没有想太多如何将我的 ML 内容移植到 edge 设备,这是用 Java 编写的。

当建模部分接*尾声时,我开始研究如何用 Java 加载 LightGBM 模型。在此之前,我和一个同事讨论过,他推荐我用 XGBoost 模型重新训练模型,这个模型可以用 XGBoost4J 依赖关系在 Java 中加载。

LightGBM 和 XGBoost 都是梯度增强库,但有一些不同。如果我决定用 XGBoost 重新训练模型,我希望得到一个类似的模型,但是我不想重新运行所有的实验,因为必须有一个更好的方法。

幸运的是,我发现了一种简单的方法,可以将 Python 中的任何机器学习模型加载到任何其他语言中。

通过阅读这篇文章,你将学会:

  • 什么是 PMML?
  • 如何将 Python 模型保存为 PMML 格式?
  • 如何用 Java 加载 PMML 模型?
  • 如何在 Java 中使用 PMML 模型进行预测?

这里有几个你可能感兴趣的链接:

- [Complete your Python analyses 10x faster with Mito](https://trymito.io/) [Product]- [Free skill tests for Data Scientists & ML Engineers](https://aigents.co/skills) [Test]- [All New Self-Driving Car Engineer Nanodegree](https://imp.i115008.net/c/2402645/1116216/11298)[Course]

你愿意多看一些这样的文章吗?如果是这样,你可以点击上面的任何链接来支持我。其中一些是附属链接,但你不需要购买任何东西。

认识 PMML

Dom FouUnsplash 上拍摄的照片

来自维基百科:

预测模型标记语言 ( PMML )是一种基于 XML 的预测模型交换格式,由时任伊利诺伊大学芝加哥分校国家数据挖掘中心主任的罗伯特·李·格罗斯曼博士构想。PMML 为分析应用程序提供了一种描述和交换由数据挖掘和机器学习算法产生的预测模型的方法。

PMML 支持:

  • 神经网络
  • 支持向量机
  • 关联规则
  • 朴素贝叶斯分类器
  • 聚类模型
  • 文本模型
  • 决策树(随机森林)
  • 梯度增强(LightGBM 和 XGBoost)
  • 回归模型

PMML 使我们能够加载一个机器学习模型,这个模型是用 Python、 Java、Go lang、 C++Ruby 和其他语言训练的。

1.使用 PMML

照片由JESHOOTS.COMUnsplash 上拍摄

在了解了 PMML 之后,我的第一个想法是我需要从根本上重构代码,这将使得用 XGBoost 重新训练模型更加可行。

经过考虑,我决定给 PMML 一个尝试。它有一个维护良好的和清晰的说明——这总是一个好迹象。

您可以简单地安装 PMML 软件包:

pip install sklearn2pmml

将 Python 机器学习模型导出为 pmml 格式需要 sklearn2pmml 包。使用它很简单,我们只需要用 PMMLPipeline 类包装分类器。

为了方便起见,我编写了一个简单的要点,在 Iris 数据集上训练 LightGBM 模型,并将模型导出为 PMML 格式:

  1. 导入所需的 Python 包
  2. 加载虹膜数据集
  3. 将虹膜数据集分割为训练集和测试集
  4. 使用 PMML 支持训练 LightGBM 模型——这是您的代码中唯一需要的更改。
  5. 衡量模型的分类准确性。
  6. 最后,将模型保存为 PMML 格式。

在 Iris 数据集上训练 LightGBM 模型,并将其导出为 PMML 格式。

PMML 模型是什么样子的?

上面的代码创建了一个 PMML 文件,这是一个 XML 文件。XML 包含了所有的模型细节,如下图所示。

PMML 模型存储在一个 XML 文件中(图片由作者提供)。

2.如何用 Java 加载模型?

杰克·杨在 Unsplash 上的照片

我们用 Python 训练了模型,并将其导出为 PMML 格式,现在我们需要用 Java 加载它。

我在 Github 上创建了一个极简资源库 LoadPMMLModel ,它展示了如何用 Java 加载 PMML 模型。

第一步是向 pom.xml 添加 PMML 依赖项(我使用的是 maven dependency manager):

<dependency>
	<groupId>org.jpmml</groupId>
	<artifactId>pmml-evaluator</artifactId>
	<version>1.5.15</version>
</dependency

我将 PMML 文件保存到项目的 resources 文件夹中,以便编译器可以打包它。

PMML 文件在资源文件夹中(图片由作者提供)

然后我们需要指定模型的路径:

String modelFolder = LoadPMMLModel.class.getClassLoader().getResource("model").getPath();String modelName = "boosting_model.pmml";Path modelPath = Paths.get(modelFolder, modelName);

用 PMML 模型加载模型很简单(Java 中模型的变量是 Evaluator 类型):

Evaluator evaluator = new LoadingModelEvaluatorBuilder()
                .load(modelPath.toFile())
                .build();
evaluator.verify();

3.如何用 Java 做预测?

塔德乌什·拉科塔在 Unsplash 上拍摄的照片

现在让我们用加载的模型做一些预测。

在 Python 中,测试集中第一个样本的预测值是 1。

python 中的首次预测(图片由作者提供)。

让我们用 Python 和上面一样的例子,但是用 Java:

Map<String, Double> features = new HashMap<>();
features.put("sepal length (cm)", 6.1);
features.put("sepal width (cm)", 2.8);
features.put("petal length (cm)", 4.7);
features.put("petal width (cm)", 1.2);Map<FieldName, FieldValue> arguments = new LinkedHashMap<>();
for (InputField inputField : inputFields) {
            FieldName inputName = inputField.getName();
            Double value = features.get(inputName.toString());
            FieldValue inputValue = inputField.prepare(value);
            arguments.put(inputName, inputValue);
}

并在 Java 中查询模型进行预测:

Map<FieldName, ?> results = evaluator.evaluate(arguments);// Extracting prediction
Map<String, ?> resultRecord = EvaluatorUtil.decodeAll(results);Integer yPred = (Integer) resultRecord.get(targetName.toString());
System.out.printf("Prediction is %d\n", yPred);
System.out.printf("PMML output %s\n", resultRecord);

使用上面的代码,我们得到以下输出:

Java 中模型的输出(图片由作者提供)

结论

Johannes Plenio 在 Unsplash 上拍摄的照片

在我的机器学习项目中,我使用了回归助推模型。令我惊讶的是,导出的 PMML 模型产生的结果与 Python 中的模型一样精确到小数点后第五位。

我对 PMML 没有什么不好的,因为它在生产中工作可靠。

请记住,您不需要复制粘贴本文中的代码,因为我在 Github 上创建了 LoadPMMLModel 存储库。

请让我知道你对 PMML 的想法。

在你走之前

Twitter 上关注我,我经常在那里发关于数据科学和机器学习的微博。

凯利·西克玛在 Unsplash 上的照片

如何从小数据中获取洞察力

原文:https://towardsdatascience.com/how-to-milk-small-data-for-insights-1ae9c7000f8e?source=collection_archive---------19-----------------------

用手做,不要过度

一些背景:我开了一家公司。我们在 LinkedIn 上发布了 17 次,以测试社交媒体作为潜在客户生成渠道的能力。我想知道:我们能从这 17 个职位的表现中学到什么?

我心中的数据科学家自然会大声找借口。

这里没有 随机化 !这里有 每一种偏见 !我需要用一个 倾向模型 来权衡这个。但即使这样,我连 都没有重叠

但作为 Dataframe 的产品负责人,我杀死了自己的这个内在版本,并提出了我认为合理的小数据分析方法。我将在这里分享我的过程和学习。

⚒第一课:不要用手提钻钻孔。

✏️不知道如何收集数据?手动操作。

好吧,这只是为了举例说明。不要把它写在纸上——至少把它放在电子表格里。

最困难的部分总是寻找、获取和清理你的数据。为了具有可重复性,这应该包括像 Segment、Fivetran、数据仓库和 Dataframe 这样的工具的组合来组织这一切。但是对于一次性的项目,一个全功能的、自我更新的管道通常是多余的。

我研究了第三方服务来为我从 LinkedIn 收集数据,但很快意识到只需要大约 15 分钟就可以手动收集我们从 LinkedIn 获得的所有数据和我想要的精确维度。

所以我就这么做了。我只是手动将我们所有的统计数据放入一个 csv 文件中。

这可能感觉有点显而易见,但是在 ETL 和数据管道的世界里,它不适合我。手动数据收集可能感觉过时,但它工作得很好。如果某件事要花你不到三十分钟的时间去做,那么做起来可能会更便宜。考虑机会成本),而不是考虑并实现一个更具可扩展性的解决方案。

⭐️第二课:不要 p-hack。专注于你想回答的问题。

当你在做任何事情的时候,很容易进入兔子洞,但是当你在处理小数据的时候,这可能是特别危险的。您需要保持在 p-hacking 之上(测试太多的假设,并在此过程中发现假阳性)。一个奇妙的、节省时间的方法是只做你工作的 80/20。你在努力提高影响力,而不是证明你的工资是合理的。运用你最好的判断力,这应该足以让你朝着正确的方向前进。

📉随便编几个情节,继续前进。

这是我们为 LinkedIn 研究做的一个:

一段时间内不同帖子的 LinkedIn 印象图。图片作者。

是的,这是真实的数据,显示了一段时间内的印象。是的,它很丑(这是重点)。它只有几行代码,给了我们一些快速的洞察力:

  • 随着时间的推移,我们的印象越来越深刻!
  • 我们在页面上尝试了一系列纯音频的播客风格的帖子(线下的橙色块)。这些显然没有效果。
  • 我们最有效的、超越曲线的帖子是我们的发布帖和视频

这让我们确认了什么是有效的,什么是无效的。当然,这里的误差线可能很大,但这给了我们一些数据,虽然我们永远不会公布我们的发现,但有理由把这作为我们前进的零假设。

最有可能的情况总是你的数据反映了事实。📈

是的,是的,这是一个非常丰富的,容易被误解的声明。(不要杀我,统计学家。我是你们中的一员,我发誓!)不过一般都是真的。在没有更多数据的情况下,你的小数据结果可能是最接*事实的。

📜第三课:记录并分享你的学习成果。

小数据不适合机器学习模型。小数据不适合严格的实验。
小数据不适合稳健的效应大小估计。

🐭小数据对于方向性洞察很有用。

因此,与决策者分享你的成果更为重要。

在我们的例子中,作为 Dataframe 的首席数据官,我并不领导营销工作,而是我们的首席执行官约瑟夫·穆恩(Joseph Moon)领导。所以我对他放松了这一点,确保他读了它,然后在我们的会议上重复了一遍,这样他就能记住这一点。

简而言之,不要让缺乏数据阻止你寻找见解。🚀

只要你有一些数据,你就可以做一些事情。

由于来自数据量从来不是大问题的公司,我最初认为这种小数据工作是无用的(我认为这是大多数数据科学家和分析师的倾向)。但在一位数(甚至基点)涨幅的世界里生活了这么久之后,我忘记了一个重要的事实:

如果影响大小足够大,你不需要很多数据来找到站得住脚的见解。

当你刚刚创办一家公司时,每一个行动都有可能带来巨大的提升。当它发生时,确保你不会错过它。

推文@ imrobertyi/@ data frameapp 打招呼。👋**或者关注我们上LinkedIn。🙂 要了解更多我们在 Dataframe 所做的事情(并注册我们数据上下文*台的私有测试版),请访问data frame . ai

如何通过创建系综来减轻过度拟合

原文:https://towardsdatascience.com/how-to-mitigate-overfitting-by-creating-ensembles-77e9299b9ad0?source=collection_archive---------24-----------------------

解决过度拟合问题

解决过度拟合问题—第 4 部分

斯凯工作室Unsplash 拍摄的照片

如果我们总结一下到目前为止在“解决过度拟合问题”系列文章中所做的工作,我们已经讨论了三种可以用来减轻过度拟合的不同技术。正如你已经知道的,交叉验证(在第一部分中讨论过)、正则化(在第二部分中讨论过)和降维(在第三部分中讨论过)可以有效地减轻过拟合。在第 4 部分中,今天我们讨论另一个有用的技术,叫做创建合集

然而,这种技术仅限于基于树的模型。有人可以尝试构建决策树模型(步骤 1)而不限制树的增长(不提前停止或不做任何超参数调整)。他将得到一个明显过度合身的模型。然后,他可以通过限制树的增长(通过提前停止或超参数调整)来构建相同的模型(步骤 2)。这一次,模型不会像前一次那样过度拟合数据。如果他想进一步减轻过拟合,他可以建立一个集成模型(步骤 3),例如, 随机森林 即不相关决策树的集合。这是我们讨论今天内容所遵循的顺序。

与单个决策树模型相比,如果我们通过限制每个单独决策树的增长来构建随机森林模型,则随机森林模型不太可能过度拟合数据。请记住,与其他模型相比,随机森林模型可能仍然过拟合。

与其他模型相比,随机森林不太可能过度拟合数据,这背后的直觉是:

随机森林是通过组合多个不相关的决策树构建的(因此得名,森林)。当创建随机森林时,在选择特征和训练实例时将应用额外的随机性(因此得名,随机)。由于这些原因,当创建随机森林时,数据和特征被很好地表示(混合)。森林中的每棵树都生成不相关的结果,然后对这些结果进行*均,得到最终结果,这个结果足够强大,可以产生比任何单个决策树更准确和稳定的结果(更少的过拟合)——作者

现在,我们将进入包含在 3 个步骤中的编码部分。

(步骤 1):在不限制树增长的情况下构建决策树模型

为此,我们在“ 心脏病 ”数据集上创建决策树模型,而不限制树的增长(不提前停止或不进行任何超参数调整)。

创建决策树模型,而不限制树的增长

(图片由作者提供)

训练准确率 100%。测试精度远低于训练精度。因此,模型明显过拟合。这并不奇怪,因为我们没有限制树木的生长。

(步骤 2):通过限制树的增长来构建相同的决策树模型

这里,我们将通过设置 max_depth=3 来限制树的深度。

通过限制树的增长来创建相同的决策树模型

(图片由作者提供)

这个型号比早期的稍好一些。让我们看看是否可以通过创建一个随机森林(系综)——多个不相关的决策树的搭配——来进一步减轻过度拟合。

(步骤 3):构建随机森林

这里,我们将应用相同的限制标准, max_depth=3 来限制每棵树的深度,然后创建一个随机森林。

创建随机森林模型

(图片由作者提供)

这一次的模式比前两次好很多。它能够很好地概括新的看不见的数据。因此,我们能够通过创建决策树的集合来减轻过度拟合。

最后的想法

到目前为止,我们已经讨论了以下可用于减轻过度拟合的技术:

  • 交叉验证
  • 正规化
  • 降维
  • 创建合奏

要完成本系列文章,还有一项技术需要讨论。在应用任何技术之前,您应该首先意识到您的模型是过度拟合的。然后,根据您想要构建的数据和模型选择最佳技术。您可以尝试多种技术,看看模型的表现如何。在本系列的最后一部分(第 5 部分),我将添加详细的指导原则,帮助您选择最佳技术。同时,你可以练习到目前为止你所学的方法。记住“你知道的不去实践”等于“你不知道”!

更新(2021–10–05):第 5 部分现已推出!
[ 如何通过特征选择减轻过度拟合

今天的帖子到此结束。我的读者可以通过下面的链接注册成为会员,以获得我写的每个故事的全部信息,我将收到你的一部分会员费。

报名链接:https://rukshanpramoditha.medium.com/membership

非常感谢你一直以来的支持!下一个故事再见。祝大家学习愉快!

特别感谢 Unsplash 上的 Skye Studios ,为我提供了一张不错的封面图片(我对图片做了一些修改:添加了一些文字并删除了一些部分)。

鲁克山普拉莫迪塔
2021–09–30

如何通过降维来减轻过度拟合

原文:https://towardsdatascience.com/how-to-mitigate-overfitting-with-dimensionality-reduction-555b755b3d66?source=collection_archive---------22-----------------------

解决过度拟合问题

解决过度拟合问题—第 3 部分

Rene b hmer 在 Unsplash 上拍摄的照片

到目前为止,我们已经完成了文章系列的第 1 部分第 2 部分。你已经知道有很多方法可以解决过度拟合的问题。交叉验证正则化是我们已经讨论过的两种众所周知的技术。降维****【DR】是另一种可以用来减轻机器学习模型中过拟合的有用技术。请记住,除了减轻过度拟合,DR 还有许多其他用例。

当解决过度拟合时,DR 处理模型复杂性。当数据中有许多要素时,模型会变得更加复杂。复杂的模型往往会过度拟合数据。DR 通过减少数据中特征(维度)的数量来处理模型的复杂性。有两种方法可以减少数据的维数:

  • 查找包含不同于原始数据集中的值的一组新要素。应用变换。这就是我们今天讨论的方法。
  • 保留数据集中最重要的要素,移除冗余(不必要)的要素。数据集中的原始值保持不变,并且不应用任何变换。这种方法被称为特征选择,是一种 DR。这将在本系列的第 5 部分中讨论。

降维的技术非常多。在这里,我们使用主成分分析(PCA)** 来寻找一组包含不同值的新特征,同时尽可能多地保留原始数据集中的变化。**

****注:如果你想详细研究各种 DR 方法(尤其是 PCA)及其对 Python 的诅咒,点击下图可以看到我之前的内容列表:

**

(作者截图)**

不应用主成分分析建立模型

首先,我们在“ 心脏病 ”数据集上建立逻辑回归模型,并查看输出。

不应用主成分分析的逻辑回归模型

(图片由作者提供)

让我们看看我们可以做些什么来进一步提高模型的性能。

应用主成分分析后建立模型

现在,我们在相同的数据集上构建相同的模型,但是在应用 PCA 之后。原始数据集中有 13 个特征(用 X 表示)。PCA 将它们转换成一组新的 9 个变量。所有这些捕获了数据中总可变性的 85.03%。

应用主成分分析后的逻辑回归模型

(图片由作者提供)

模型的精度提高了 3%。因此,我们通过应用主成分分析进一步改进了模型。

见解和结论

当我们应用 PCA 时,我们丢失了原始数据中的一些可变性。这取决于我们在 n_components 中指定的特性数量。在我们的例子中,我们丢失了原始数据中大约 15%的可变性。我们损失的可变性越低,结果就越好。然而,主成分分析仍然能够提高模型的性能。这是因为 PCA 去除了数据中的噪声,只保留了数据集中最重要的特征。这将减轻数据的过度拟合,并提高模型的性能。我们得到一个简单而精确的模型。

****更新(2021–10–01):第 4 部分现已推出!
[ 如何通过创建集合来减轻过度拟合

今天的帖子到此结束。我的读者可以通过下面的链接注册成为会员,以获得我写的每个故事的全部信息,我将收到你的一部分会员费。

****报名链接:https://rukshanpramoditha.medium.com/membership

非常感谢你一直以来的支持!下一个故事再见。祝大家学习愉快!

特别要感谢 Unsplash 上的Rene b hmer,他为我提供了这篇文章的漂亮封面图片(我对图片做了一些修改:在上面添加了一些文字并删除了一些部分)。

鲁克山普拉莫迪塔
2021–09–27

如何通过特征选择减轻过度拟合

原文:https://towardsdatascience.com/how-to-mitigate-overfitting-with-feature-selection-164897c0c3db?source=collection_archive---------34-----------------------

解决过度拟合问题

解决过度拟合问题—第 5 部分

照片由 Unsplash 上的实体照片拍摄

这是【解决过度拟合问题】系列文章的最后一部分。今天,我们从第四部分继续。上次,在第 4 部分的第 3 步中,我们在" 心脏病 "数据集上构建了一个随机森林模型。在那里,我们使用了数据集的所有 13 个特征。今天,我们将通过仅考虑最重要的特性来修改该模型。

首先,我们通过使用 feature_importances_ 属性来可视化随机森林模型的特征重要性。

随机森林模型特征重要性的可视化

(图片由作者提供)

很明显,并不是所有的特征都对模型有贡献。有些特征对模型不重要,我们可以删除它们。

当我们从模型中移除最不重要的特征时,我们降低了模型的复杂性和数据中的一些噪声。这样做将有助于进一步减轻过度拟合——按作者

上图的 x 轴包含每个特性的特性重要性分数。我们可以为重要性分数指定一个阈值(这里,我们选择 0.025 ),这样分数低于该阈值的所有特征都将被消除。为此,我们可以使用 Scikit-learnselect from model类。

from sklearn.feature_selection import SelectFromModelselector = SelectFromModel(rfclf, threshold=0.025)
features_important = selector.fit_transform(X, y)

这将返回一个 2D-Numpy 数组,其中仅包含由阈值决定的重要特性的值。通过将其转换成熊猫数据帧,

pd.DataFrame(features_important).head()

我们可以获得下表:

数据帧 1(图片由作者提供)

如果我们也得到原始数据帧,

X.head()

数据帧 2(图片由作者提供)

我们已经移除了 4 个特征: fbsrestecgtrestbpschol 。这些特征对模型没有足够的贡献。将它们保留在模型中会增加模型的复杂性,并导致模型过度拟合数据。

移除特征的重要性分数的顺序是:

**fbs < restecg < trestbps < chol**

如果考虑特征【性】,其重要性值是【CHOL】的两倍以上。如果我们还删除了特征【性别】,模型将丢失一些重要数据。这将导致模型拟合不足。这就是为什么我们选择了 0.025 作为阈值来选择我们想要保留在模型中的特征。通过查看特征重要性图,可以很容易地确定阈值的值。

最后,我们可以使用移除了特征的修改后的数据帧(数据帧 1)来再次构建随机森林模型。这一次,我们只使用了 9 个特性。换句话说,我们可以说我们降低了数据的维度。但是,请记住,数据集中的原始值保持不变。您可以将其与本系列的第 3 部分进行比较,在第 3 部分中,我们讨论了一种降维方法,该方法可以找到一组新的要素,这些要素包含与原始数据集中不同的值。

我们今天讨论的特征选择方法可以应用于基于树的模型,如决策树、随机森林等。对于线性回归和逻辑回归模型,向后消除和向前选择是首选。如果你想详细了解它们,可以阅读我写的这篇文章。

今天的部分到此结束,也是“解决过度拟合问题”系列文章。我们在 5 篇文章中讨论了 5 种不同的技术来解决过度拟合的问题。作为附加内容,我将添加一些选择最佳技术的指南。

选择最佳技术的一些准则

到目前为止,我们已经讨论了以下可用于减轻过度拟合的技术:

  • 交叉验证
  • 正规化
  • 降维
  • 创作合奏
  • 功能选择

您不需要应用所有这些技术来减轻过度拟合。这里有一些指导方针可以帮助你选择最好的技术。

  • 首先,在应用任何技术之前,您需要意识到您的模型是过度拟合的。如果你得到一个较高的训练分数和相对较低的测试分数,你的模型会过度拟合数据。
  • 使用交叉验证来评估模型总是更好,交叉验证有助于您发现大量选项来减轻过度拟合。
  • 最好将交叉验证与超参数调整技术结合起来,如网格搜索或随机搜索,为定义的超参数找到一组最佳值。这将有助于你减轻过度拟合。任何型号都可以进行超参数调整。例如,我们可以用它来限制决策树的增长。这个过程是在第二部分中讨论的一种正规化。
  • 另一种类型的正则化是将正则化项添加到损失函数中。这适用于逻辑回归、线性回归等线性模型,也适用于 XGBoost 等基于树的模型。对于逻辑回归,在 Scikit-learn 中默认应用正则化的 L2 变量。L1 变种也可用。对于线性回归,没有在模型本身中指定正则化的选项。然而,Scikit-learn 为此提供了 3 个不同的选项。当我们将 L1 正则化应用于线性回归时,它被称为套索回归。当我们将 L2 正则化应用于线性回归时,它被称为回归。当我们同时将 L1 和 L2 变量应用于线性回归时,它被称为 ElasticNet 回归。
  • 降维技术可以应用于几乎任何数据集。最流行的 DR 技术是主成分分析(PCA)。除了解决过拟合问题之外,它还有许多优点。
  • 如果您想在数据中找到非线性模式,您可以使用集成技术,如随机森林和 XGBoost 模型,而不是使用单个决策树。
  • 您也可以将两种技术结合起来,以获得更好的效果。例如,您可以创建集合模型,同时应用正则化来限制单个树的增长。您可以在选择数据集中最重要的要素时创建集合模型。
  • 创建模型后,您可以识别最重要的要素并从数据集中移除不必要的要素,然后仅使用最重要的要素来重新构建模型。对于像随机森林 XGBoost 这样的集合模型,使用 feature_importances_ 属性可以很容易地做到这一点。对于线性回归和逻辑回归模型,可以使用单独的类进行向后消除和向前选择。

结论

现在,你将拥有应用 5 种不同技术解决过度拟合问题的实践经验。我建议您将它们应用于不同的数据集。您可以对数据集应用多种技术并查看输出,然后通过查看输出来选择最佳技术。

为了方便起见,我决定列出这个系列文章的所有部分和另一个有用的帖子。现在,您可以通过单击下图在一个位置访问所有这些内容。

本系列所有帖子列表(作者截图)

今天的帖子到此结束。我的读者可以通过下面的链接注册成为会员,以获得我写的每个故事的全部信息,我将收到你的一部分会员费。

报名链接:https://rukshanpramoditha.medium.com/membership

非常感谢你一直以来的支持!下一个故事再见。祝大家学习愉快!

特别感谢 Unsplash 上的实体照片,为我提供了这篇文章的封面图片(我对图片做了一些修改:添加了一些文字并删除了一些部分)。

鲁克山普拉莫迪塔
2021–10–04

如何用 K-Fold 交叉验证减轻过度拟合

原文:https://towardsdatascience.com/how-to-mitigate-overfitting-with-k-fold-cross-validation-518947ed7428?source=collection_archive---------12-----------------------

解决过度拟合问题

解决过度拟合问题—第 1 部分

约书亚·苏考夫在 Unsplash 上的照片

过度拟合几乎每次在我们构建机器学习模型时都会发生,尤其是基于树的模型,比如决策树。 完全避免 过拟合的问题是不可能的。然而,我们可以尝试一些标准技术来 减轻 过度拟合。有几个这样的技术要讨论。它们不可能在一个岗位上完成。所以,我决定一个一个讨论。这是第 1 部分,我们在其中讨论如何用 k 倍交叉验证 来减轻过拟合。这一部分也是讨论其他技术的基础。

我们的最终目标应该是建立一个对看不见的数据(测试数据)和训练数据都表现良好的模型。这种模式再好不过了。另一方面,当您的模型过度拟合数据时,它会在训练数据上给出高得多的性能分数(例如 100%的准确性),而在看不见的数据(测试数据)上给出较低的性能分数。在这种情况下, 无法针对新的未见过的数据(测试数据)推广 。当这种情况发生时,模型试图记住训练数据中的噪声,而不是试图学习数据中的重要模式。这相当于现实生活中的情况,即学生试图通过记住模拟考试的答案来面对期末考试,而不是应用从模拟考试中获得的知识。这个学生将无法在期末考试中取得好成绩!

无 k 倍交叉验证的训练

我们将在一个名为heart _ disease . CSV的数据集上建立一个决策树分类模型,而不需要做 k 重交叉验证。然后,我们用混淆矩阵得到训练和测试的准确度分数。通过查看这些输出,我们可以确定模型是否过度拟合。****

无 k 重交叉验证的决策树分类模型

(图片由作者提供)

这一次,我们的模型明显过度拟合。我们如何决定?该模型在训练集上表现得非常好(100%的训练准确率!)并且在测试数据上表现不佳(只有 71%的准确率)。

k 倍交叉验证训练

现在,我们将训练相同的决策树模型,但是这一次,使用 k 倍交叉验证。**

同一个 k 重交叉验证的决策树模型

(图片由作者提供)

这一次,我们的模型可能仍然是过度拟合。但是,精度(实际上是测试精度)提高了 6%。

洞察力

实际上,k 重交叉验证本身并不能减轻过度拟合。然而,它有助于我们检测大量选项(我们有增加模型准确性的空间)来减轻过度拟合。当将 k-fold 交叉验证与网格搜索等超参数调整技术相结合时,我们肯定可以减轻过度拟合。对于像决策树这样的基于树的模型,有一些特殊的技术可以减轻过度拟合。几种这样的技术是:预修剪、后修剪和创建集合。如果你想详细了解它们,请阅读我的文章:**

*****</4-useful-techniques-that-can-mitigate-overfitting-in-decision-trees-87380098bd3c> [## 4 种可以减轻决策树过度拟合的有用技术

towardsdatascience.com](/4-useful-techniques-that-can-mitigate-overfitting-in-decision-trees-87380098bd3c)

在应用 k 倍交叉验证后,准确度分数增加了 6%的原因是,交叉验证过程通过将数据集分成 10 个不同的折叠(指定为 cv=10 )*均出了 10 组准确度分数。这样,模型在每个训练阶段看到不同类型的实例(数据点)。因此,该模型有许多不同的数据来学习新的模式。因此,它将很好地推广新的看不见的数据(测试数据)。这就是为什么我们看到了准确性得分的增加。

在第一种情况下,我们构建了我们的模型而没有进行 k 重交叉验证,该模型只看到一重随机数据,指定为 random_state=0

如果你不明白最后几段,不要担心!你可以阅读下面这篇文章,在这篇文章中,我解释了几乎所有与 k-fold 交叉验证相关的内容:

用简单的英语解释 k 倍交叉验证

更新(2021–09–24):第 2 部分现已推出!
[ 如何通过正则化减轻过拟合*****

今天的帖子到此结束。我的读者可以通过下面的链接注册成为会员,以获得我写的每个故事的全部信息,我将收到你的一部分会员费。

*******报名链接:**【https://rukshanpramoditha.medium.com/membership *****

非常感谢你一直以来的支持!下一个故事再见。祝大家学习愉快!

特别要感谢 Unsplash 网站上的约书亚·苏考夫,为我提供了这篇文章的封面图片(我对图片做了一些修改:添加了一些文字,删除了一些部分)。****

鲁克山普拉莫迪塔
2021–09–21

如何通过正则化减轻过度拟合

原文:https://towardsdatascience.com/how-to-mitigate-overfitting-with-regularization-befcf4e41865?source=collection_archive---------26-----------------------

解决过度拟合问题

解决过度拟合问题—第 2 部分

Unsplash 上由kayan uda chia拍摄的照片

今天,我们继续“解决过度合身问题”系列文章的第 1 部分正则化是另一种有用的技术,可用于减轻机器学习模型中的过拟合。今天将更着重讨论正则化背后的直觉而不是讨论它的数学公式。通过这种方式,你可以清楚地了解将正则化应用于机器学习模型的效果。

一般来说,【规则化】的意思是限制 / 控制。在机器学习的背景下,正则化处理模型的复杂性。它限制了模型的复杂性或者限制了模型在训练阶段的学习过程。一般来说,我们更喜欢简单而准确的模型,因为复杂的模型更容易过度拟合。通过限制模型的复杂性,过度拟合试图使模型尽可能简单,同时这些模型仍能做出准确的预测。

有两种方法可以将正则化应用于机器学习模型:

  • 通过在损失函数中增加另一项,我们试图使其最小化。现在,目标函数由两部分组成:损失函数正则项:

(图片由作者提供)

  • 通过在培训阶段提前停止学习过程。这种方法的完美例子是在早期阶段停止决策树的生长。

我们将通过编写 Python 代码用例子来讨论每种方法。最后,您将获得将正则化应用于这里讨论的模型的实践经验。

方法 1:向损失函数添加一个正则化

这里,我们将在名为heart _ disease . CSV的数据集上建立一个逻辑回归模型。首先,我们在不添加正则项( penalty=none )的情况下构建模型,并查看输出。****

无任何正则化的逻辑回归模型

(图片由作者提供)

模型已经很好了。让我们看看是否可以通过增加一个正则项来进一步提高测试精度。这里,我们将 L2 正则化(罚=l2 )添加到模型中。

L2 正则化的 Logistic 回归模型

(图片由作者提供)

加入正则项后,测试精度提高了 3%。假阳性的数量也减少了。因此,该模型能够对新的未知数据(测试数据集)进行归纳。

方法 2:尽早停止学习过程

这里,我们将在同一个数据集上构建一个决策树分类模型。首先,我们将构建完整的决策树,而不限制树的增长(即,不应用正则化/不提前停止学习过程),并查看输出。

没有任何正则化(没有提前停止)的决策树模型

(图片由作者提供)

我们得到了非常高的训练精度和低的测试精度。因此,模型明显过拟合。这是正常的,因为我们允许树完全成长。现在,我们正试图限制这棵树的生长。这是通过设置最大 _ 深度最小 _ 样本 _ 叶最小 _ 样本 _ 分割超参数的最佳值来实现的(在上述模型中,这些值已被设置为默认值)。在机器学习中,限制树的生长在技术上叫做 修剪

带有正则化的决策树模型(带有提前停止/修剪)

(图片由作者提供)

模型得到了显著改进(测试准确率提高了 16%!).

注:寻找一组超参数的最佳值在技术上称为超参数调整超参数优化。如果你不知道这个程序,你可以通过阅读我写的下面两个帖子来了解:****

**** </4-useful-techniques-that-can-mitigate-overfitting-in-decision-trees-87380098bd3c> [## 4 种可以减轻决策树过度拟合的有用技术

towardsdatascience.com](/4-useful-techniques-that-can-mitigate-overfitting-in-decision-trees-87380098bd3c)

结论

过拟合经常发生在建模中。正则化是减轻过度拟合的另一种有用的技术。今天,我们通过例子讨论了两种正则化方法。请注意,通过为最大迭代次数指定较低的值,早期停止方法可以应用于逻辑回归、线性回归等算法。

不得混淆术语【正规化】【普遍化】。应用正则化来实现一般化。正则化模型将很好地概括看不见的数据。它 学习数据中的 重要模式,对看不见的数据做出准确预测,而不是 记忆 数据集中的噪音。

更新(2021–09–27):第 3 部分现已推出!
[ 如何通过降维来减轻过拟合

今天的帖子到此结束。我的读者可以通过下面的链接注册成为会员,以获得我写的每个故事的全部信息,我将收到你的一部分会员费。

报名链接:https://rukshanpramoditha.medium.com/membership

非常感谢你一直以来的支持!下一个故事再见。祝大家学习愉快!

特别感谢 Unsplash 网站上的 Kayaan Udachia ,为我提供了这篇文章的封面图片(我对图片做了一些修改:添加了一些文字并删除了一些部分)。

鲁克山普拉莫迪塔
2021–09–24****

如何模拟量子变量之间的任意关系

原文:https://towardsdatascience.com/how-to-model-arbitrary-relations-between-quantum-variables-d3b3ebc29e8c?source=collection_archive---------25-----------------------

实用量子数据科学

量子机器学习要不要入门?看看 动手量子机器学习用 Python

上周,我报道了我在伯努利变量上努力模拟正态分布变量的关系。

尽管我在创建允许我对线性关系建模的函数时,目标是灵活性,但我惊讶地发现这个函数实际上是如此灵活。例如,我们可以使用这个函数来模拟一个正态分布对一个伯努利变量的任意依赖性,只需稍加调整。

今天,我们深入研究这个函数,并进一步了解它是如何工作的。但是,让我们先回顾一下目前为止我们所学的内容。

在数据科学中,我们使用概率分布来描述人口的特征,例如人的身高。这些特征中有许多可以用正态分布来描述,如下图所示。

作者图片

正态分布符合许多自然现象,因为它在均值处达到峰值,而在端点处变*。换句话说,更有可能看到接**均值的值,而不是捕捉异常值。

当使用量子算法来解决数据科学或机器学习任务时,我们必须知道如何在量子电路中处理这样的分布。

IBM 的 quantum development SDK Qiskit 提供了一个创建正态分布的函数。这是NormalDistribution

作者图片

虽然 Qiskit 让我们可以快速创建一个正态分布,但它仍然需要对它的值做一些有意义的事情。例如,我们可以对正态分布的值(在上图中,值的范围从 000=0 到 111=7)和伯努利分布之间的关系进行建模。

我们用一个例子来说明一个人的身高对她必须闪开的概率的影响。

作者图片

首先,我们创建了一个线性关系的实例。接下来,我们创建了一个广义的 linear_dependency函数,它可以处理任意数量的量子位和任意斜率。最后,我们看了如何在正态分布和从属伯努利分布的值之间建立二次和 sigmoid 关系

作者图片

虽然我们展示了我们需要改变功能的哪一部分,但我们并没有深入解释。所以。让我们补上这个。

我们将我们的方法分为三个部分。

  1. 助手功能
  2. 可定制的功能—核心
  3. 主电路

像往常一样,我们从导入和助手函数开始。如果你读了我的一些帖子,你已经熟悉了prob_to_angle函数。测量量子位作为一个1需要一个概率,并返回相应的角度𝜃.详见本帖

此外,让我们创建plot_relation函数来绘制正态分布和相关伯努利变量之间的关系。通常,当我们绘制量子电路的结果时,我们会得到所有状态及其测量概率的概述。但是现在,我们不关心各个州。我们关心正态分布的值对因变量的影响。换句话说,给定正态分布的一个特定值,因变量为真或为假的比率是多少。

对于 sigmoid 依赖关系,输出是一个线形图,如上图所示。对于线性相关性,我们会有这样的预期:

作者图片

那么,plot_relation功能是如何工作的呢?

它使用三个参数:nd_qubitsdependencyget_key

  • nd_qubits表示我们想要用于正态分布的量子比特数。
  • dependency这一定是一个函数,我们稍后会详细讨论它。
  • get_key是另一个创建密钥的函数,我们可以用它来识别我们想要比较的状态。我们在选择子功能中使用它。例如,假设我们在正态分布中使用三个量子位。那么,我们需要比较的两个状态是 0111 和 1111。或者 0000 和 1000。或者 0101 和 1101。对于较低的三个量子位(从右边看),状态对共享相同的值,代表正态分布。然而,它们在因变量的值上有所不同(左边的上部量子位)。

我们之所以需要在plot_relation函数之外创建密钥,是因为这取决于我们使用的量子位的数量,我们也将它作为参数(nd_qubits)。

get_key的实现是

  • "{:d}{:01b}".format(a,b))对于由单个量子位组成的正态分布。
  • "{:d}{:02b}".format(a,b))对于由两个量子位组成的正态分布。
  • "{:d}{:03b}".format(a,b))对于由三个量子位组成的正态分布。
  • "{:d}{:04b}".format(a,b))对于由四个量子位组成的正态分布。
  • …等等。

接下来的故事很快就讲完了。首先,我们用比正态分布多一个量子位的量子电路。其次,我们创建并添加正态分布。目前,我们用固定的参数来做这件事。我们只关心正态分布的值和因变量之间的关系。我们不关心任何值的概率。事实上,我们甚至不在乎正态分布是正态分布。我们唯一关心的是对因变量的影响稳步增加。它只是意味着较高的正态分布值对因变量有较高(或相等)的影响。例如,高个子必须更频繁地低头。第三,我们使用custom_dependency函数创建并添加正态分布和因变量之间的关系。

最后,我们运行电路,并将结果关联起来绘制图表。

所以,现在让我们看看这篇文章的核心——custom_dependency功能。

功能比较短。但是从嵌套循环中可以看出,这并不容易理解。所以我在这篇文章的中提供了一些循环技术上的例子。

所以,现在让我们转而关注后果。

最重要的一点是,正态分布的值是有序的。上面我已经解释过了,但是我想在这里再强调一次。数值越高,对因变量的影响越显著。

这一点非常重要,因为我们将正态分布的值视为一个位串。位串只不过是数字——二进制数。所以我们可以把它们转换成十进制数值。我们可以把十进制数值转换成二进制数。

在我们都习惯使用的十进制格式中,我们有十个不同的数字。它们的范围从 0 到 9。当我们超过 9 时,我们返回到 0,但是我们将 1 向左移动—例如,09+01=10。

在二进制格式中,我们做同样的事情。唯一不同的是,我们只有两个数字,只有 0 和 1。所以,当我们超过 1 时,我们从 0 开始,将 1 向左移动。比如:01+01=10。

数字(无论哪种格式)的一个很好的特征是高位等于它们相对于基数的位置(从零开始计数)。所以,十进制的 10=10,100=10,1000=10,以此类推。而二进制 10=2,100=2,1000=2,以此类推。

因此,我们可以将任何数字重写为它们位置的和。例如,二进制 1101=2 +2 +2⁰.

我们可以看到,基础总是相同的。现在是两点。当我们想知道数字的总值时,我们只需要知道位置。对于给定的例子,我们只需要知道列表[0, 2, 3]。这些是为 1 的位的位置。

当我们将列表中的每个数字的值 2 相加时,我们得到相应的十进制数作为结果。

当你查看源代码时,我们使用参数函数dependency一次。我们用参数parts调用它,并将其结果传递给prob_to_angle函数。

你猜怎么着!parts是职位列表,比如[0, 2, 3]。它表示我们需要结果值的位置。给定正态分布有这个位置,得到的值就是我们要给因变量的概率。因此,我们只需将零件列表转换为线性关系的小数位置,然后乘以任意斜率。斜率越高,数值增加越快。

作者图片

所有的嵌套循环都准备了量子门,因此我们唯一需要做的就是提供一个函数来计算正态分布的每个可能值。

因此,如果我们想要创建二次依赖,我们需要做的就是改变提供的dependency函数。

作者图片

最后,我们还可以使用一个逻辑函数来生成一个 s 形。这是一条 S 形曲线,等式为

在哪里

  • x 是我们计算的值,
  • x_0 是图的中点(这里是我们的*均值),
  • k 是曲线的逻辑增长率或陡度,
  • L 是函数的最大值。

作者图片

结论

在这篇文章中,我们一步一步地剖析了我们在上一篇文章中开发的算法。此外,我们重构了代码以获取custom_dependency函数。这允许我们对多量子位变量(如正态分布)和从属伯努利变量之间的任何关系进行建模。你只需要实现相应的功能。

量子机器学习要不要入门?看看 动手用 Python 学习量子机器。

在这里免费获得前三章。

如何对经验重放、批量学习和目标网络进行建模

原文:https://towardsdatascience.com/how-to-model-experience-replay-batch-learning-and-target-networks-c1350db93172?source=collection_archive---------23-----------------------

使用 TensorFlow 2.0,快速学习稳定和成功的深度 Q 学习的三个基本技巧

照片由查德·沃顿Unsplash

如果你认为深度 Q 学习只是用一个神经网络代替一个查找表,你可能会有一个粗略的觉醒。虽然深度 Q 学习允许处理非常大的状态空间和复杂的非线性环境,但这些好处是以巨大的成本为代价的。

对于这篇文章,我假设你已经对 Q-learning深度 Q-learning 有所了解。下面的更新函数和损失函数将足以设置场景。在余下的部分,我将具体放大稳定性问题和三种常用技术来缓解这些问题:经验重放批量学习目标网络

(普通)Q-learning 的口语更新功能。

深度 Q 学习的均方误差损失函数。

(深度)Q 学习的稳定性

在某种程度上,稳定性是每个学习任务中的一个问题。然而,普通 Q-learning 相当稳定。当观察到对应于某个状态-动作对(s,a)的奖励时,只有对应的 Q 值Q(s,a)被更新。查找表中的所有其他 Q 值保持不变。

Q 表示例。对属于各个状态-动作对的 Q 值进行更新,从而得到稳定的表示。[图片由作者提供]

相比之下,Q 网络可以被视为一个参数化的函数f_θ:s →[Q(s,a)]_a∈A,将一个状态映射到一个 Q 值向量。这里的关键区别在于,对于每个状态-动作对,单次更新会改变所有 Q 值。这种影响是相当深远的,在某种程度上由于神经网络的非线性表示(对异常值的敏感性等)而加剧。)即使对于看似简单的问题,深度 Q 学习也经常受到稳定性问题的困扰。

Q 网络的例子。单次更新影响所有状态-动作对的 Q 值,因为所有输入使用相同的网络。[图片由作者提供]

体验回放

体验重放从重放缓冲区随机抽取一个观察值(一个 s,a,r,s '元组)。期望和目标是通过将 s 和 s’插入 Q 网络来确定的。[图片由作者提供]

强化学习需要做出连续的决策。这通常意味着后续状态密切相关(例如,迷宫中的一步,股票价格的一天更新),因此非常相似。因此,顺序观察往往高度相关,这可能导致网络过度拟合(例如,在迷宫的次优区域中)。

然而,即使经验是顺序获得的,也没有理由学习应该遵循相同的顺序。经验重放通过用过去的观察创建一个重放缓冲器来分离两个过程。具体来说,重放缓冲区存储我们遇到的每个s,a,r,s’元组。注意,相应的 Q 值是而不是存储的;我们在为更新目的对观察值进行采样时确定它们。具体来说,学习过程如下:

  • 从重放缓冲区中随机抽取s,a,r,s’元组。
  • 使用存储的动作a,将s输入 Q 网络以获得Q_t(s,a)
  • s’输入 Q 网络以获得Q_t+1(s’,a*),其中a*∈A是状态s’中的最优动作(根据主要的 Q 值)。回想一下 Q 学习是不符合策略的,所以我们不使用实际轨迹。
  • 使用Q_t(s,a)r_t+Q_t+1(s’,a*)之间的差值计算更新网络所需的损耗。

除了打破相关性和克服过度拟合之外,理论上的好处是数据现在更接* i.i.d .数据,这通常是在监督学习收敛证明中假设的。

Python 实现如下所示。请注意,我们所做的只是在经验收集阶段s,a,r,s’存储在缓冲器中,并在学习阶段对它们进行随机采样。对于后者,我们使用方便的random.choices功能。

**"""Experience replay implementation"""****# Initialize replay buffer**
replay_buffer = []...**# Experience collection phase**# Set state
state = next_state# Determine action (epsilon_greedy)
if epsilon<= 0.05:
    # Select random action
    action = np.random.choice(action_dim)
else:
    # Select action with highest q-value
    action = np.argmax(q_values[0])# Compute and store reward
reward = get_reward(state, action)# Determine next state
next_state = get_state(state, action)

# Store observation in replay buffer
observation = (state, action, reward, next_state)

replay_buffer.append(observation)...**# Learning phase**# Select random sample from replay buffer
if len(replay_buffer) >= min_buffer_size:
    observations = random.choices(replay_buffer, k=1)

存储所有过去的观察数据并完全随机取样可能并不理想。事实上,这一程序可以改进。有了优先重播,我们更经常地尝试我们期望从中学习更多的经验。另一种常见的技术是更新重放缓冲区,删除旧的观察结果。毕竟,你不希望停留在过去的观察上,这些观察来自于状态空间中我们从一开始就不应该访问的区域。自然,像这样的改进引入了额外的建模挑战。

批量学习

批量学习对单个网络更新的多个观察值进行采样,导致更具代表性的损失和更稳定的更新[图片由作者提供]

一次更新一个观测值的 Q 网络可能不是一个好的解决方案。在许多情况下,这样的观察可能不包含太多有用的信息——想想迷宫中的一步。更糟糕的是,观察结果可能是异常值,不能代表整个问题,然而更新可能会对未来的决策产生灾难性的影响。理想情况下,我们希望每次更新都能代表整个问题。

另一方面,我们可能会执行所有的训练迭代,并使用完整的一批观察值来拟合带有单个更新的 Q 网络。虽然这样的一批确实具有代表性,但是所有的观察都是在我们最初的(可能非常差的)策略下进行的,因此我们永远也不会知道与一个好的策略相对应的 Q 值。

因此,大批量也不是很有用。我们希望将观察和更新结合起来,逐步改进我们的政策。这并不意味着我们必须更新每一次观察的。显而易见的妥协是小批量,这意味着我们频繁地用相对较少的观测值更新我们的网络。与经验重放相结合,这是一种强大的技术,可以基于大量以前的观察获得稳定的更新。

作为基本经验回放的延伸,我们可能仍然很难获得有代表性的样本。主要的实施问题是更新频率(更新自然比单次观测花费更长时间)和小批量的大小

**"""Batch learning implementation"""**no_observations = 100
mini_batch_size = 10
loss_value = 0if len(replay_buffer) >= no_observations and 
   i % update_frequency == 0:
    **# Randomly sample k observations from buffer**
    observations = random.choices(replay_buffer, k=mini_batch_size) **# Loop over sampled observations**
    for observation in observations:
       # Determine Q-value at time t
       q_values = q_network(state)
       expected_value = q_values[0, action] # Determine Q-value at time t+1
       next_q_values = tf.stop_gradient(q_network(next_state))
       next_action = np.argmax(next_q_values[0])
       next_q_value = next_q_values[0, next_action] # Add direct reward to obtain target value
       target_value = reward + (gamma * next_q_value)

       # Compute loss value
       loss_value += mse_loss(expected_value, target_value)

**# Compute mean loss value**
loss_value /= batch_size

目标网络

目标网络(右)是原始 Q 网络(左)的周期性副本。目标网络用于确定 Q_t+1,降低期望与目标的相关性。[图片由作者提供]

通过从过去的观察中随机取样(经验回放),我们试图打破观察之间的相关性。然而,注意,观察元组包含两个密切相关的状态——ss’ ——它们被馈送到相同的 Q 网络以获得 Q 值。换句话说,期望和目标也是相互关联的。每次网络更新也会修改目标,即我们正在追逐一个移动的目标。

为了降低期望Q(s,a)和目标r+Q(s’,a’)之间的相关性,我们可以使用不同的网络来确定Q(s’,a’)。我们称之为目标网络——我们的目标基于Q^T(s’,a’)而不是Q(s’,a’)。我们可以用 TensorFlow 的clone_model命令复制原 Q 网的网络架构。请注意,该克隆程序不会而不是复制权重,为此我们使用了set_weights命令。使用get_weights,我们定期从 Q-网络获得最新的权重。

**"""Target network implementation"""****# Copy network architecture**
target_network = tf.keras.models.clone_model(q_network) **# Copy network weights**
target_network.set_weights(q_network.get_weights()) ...**# Periodically update target network**
if episode % update_frequency_target_network == 0:
    target_network.set_weights(q_network.get_weights())

关键的挑战是找到正确的更新频率。如果更新间隔很久,目标可能对应于过去表现不佳的政策。过于频繁,目标和期望之间的相关性仍然很高。与其他两种技术一样,该解决方案解决了一个问题,但也引入了额外的复杂性。

外卖食品

  • 经验重放将所有观察值— s,a,r,s’元组存储在一个缓冲区中,可以从中选择随机样本。这打破了连续观测中经常存在的相关性。
  • 批量学习基于多次观察执行网络更新。这种方法往往比单一观测产生更稳定的更新,因为损失更好地代表了整体问题。
  • 目标网络降低期望Q(s,a)和目标r+Q^T(s’,a’)之间的相关性。目标网络只不过是 Q 网络的周期性副本。
  • 每种技术都引入了新的建模挑战和要调整的参数。在某种程度上,这就是深度学习如此困难的原因;每个解决方案都会产生新的障碍,增加模型的复杂性。

对深度 Q-learning 感兴趣?你可能也会对下面的文章感兴趣:

想知道更多关于 Q-learning(和 SARSA)的基础知识吗?看看下面这篇文章:

参考

坦贝特·马蒂森(2015 年)。揭秘深度强化学习。计算神经科学实验室。从 neuro.cs.ut.ee/demystifying-deep-reinforcement-learning/取回

Mnih,v .,Kavukcuoglu,k .,Silver,d .,鲁苏,A. A .,Veness,j .,Bellemare,M. G .,… & Hassabis,D. (2015)。通过深度强化学习实现人类水*的控制。自然,518(7540),529–533。

如何监控数据质量——详细指南

原文:https://towardsdatascience.com/how-to-monitor-data-quality-a-detailed-guide-2e28b7d21f3?source=collection_archive---------38-----------------------

来源:沉积照片

防止数据收集中的错误比处理其后果更容易。你的商业决策是否明智取决于你的数据质量。在本文中,我们将告诉您如何在收集的所有阶段检查数据质量,从工作陈述到完成的报告。

测试在网络分析中的重要性

不幸的是,许多花费大量资源存储和处理数据的公司仍然根据直觉和他们自己的期望而不是数据来做出重要决策。

为什么会这样?当数据提供的答案与决策者的期望不一致时,对数据的不信任就会加剧。此外,如果有人过去在数据或报告中遇到过错误,他们倾向于支持直觉。这是可以理解的,因为根据不正确的数据做出的决定可能会让你倒退,而不是让你前进。

假设您有一个多币种项目。您的分析师以一种货币设置了 Google Analytics,而负责上下文广告的营销人员以另一种货币设置了成本导入 Google Analytics。因此,在你的广告活动报告中,你有一个不切实际的广告支出回报(ROAS)。如果你没有及时注意到这个错误,你可能会禁用盈利活动或增加亏损活动的预算。

此外,开发人员通常非常忙,实现 web 分析对他们来说是次要任务。在实现新功能时——例如,一个带有附件的单元的新设计——开发人员可能会忘记检查数据是否在 Google Analytics 中收集。结果,到了评估新设计有效性的时候,发现数据收集在两周前就被破坏了。惊喜吧。

纠正错误的成本

假设您在规范阶段犯了一个错误。如果你发现它并立即纠正它,修复会相对便宜。如果在实现之后,在构建报告时,甚至在做决策时发现了错误,那么修复它的成本将会非常高。

图片由作者提供

如何实现数据收集

数据收集通常由五个关键步骤组成:

  • 制定业务挑战。比方说,你需要评估一个算法的效率,以便在推荐模块中选择商品。
  • 负责数据收集的分析师或人员设计了一个要在现场跟踪的指标系统。
  • 此人设置谷歌分析和谷歌标签管理器。
  • 一种是发送开发人员执行的参考条款。
  • 在开发人员实现了度量标准并设置了数据收集之后,分析人员就可以使用报告了。

图片由作者提供

在几乎所有这些阶段,检查你的数据是非常重要的。有必要测试技术文档、谷歌分析和谷歌标签管理器设置,当然,还有在你的网站或手机应用上收集的数据的质量。

数据收集测试的特征

在进入每个步骤之前,让我们先来看看数据测试的一些要求:

  • 没有工具就无法测试。至少,您必须在浏览器中使用开发人员控制台。
  • 没有抽象的预期结果。你需要知道你最终会得到什么。我们总是有一组需要收集的参数,用于用户与网站的任何交互。我们知道这些参数应该取什么值。
  • 专业知识是必要的。至少,你需要熟悉你所使用的网络分析工具的文档,实践,以及市场参与者的经验。

网站数据收集的测试文档

正如我们已经提到的,如果您在规范中发现一个错误,那么更正它就容易得多。因此,检查文档早在收集数据之前就开始了。让我们弄清楚为什么我们需要检查您的文档。

测试文件的目的:

  • 不费吹灰之力修正错误。文档中的错误只是书面文本中的错误,因此您所要做的只是快速编辑。
  • 防止将来可能影响站点/应用程序架构的变更需求。
  • 保护分析师的声誉。一份在发展过程中有错误的文书可能会使起草人的能力受到质疑。

规格中最常见的错误:

  • 错别字。开发人员可以复制参数的名称,而无需读取它们。这与语法或拼写错误无关,而是与参数名或参数值不正确有关。
  • 跟踪事件时忽略字段。例如,如果表单没有成功提交,错误消息可能会被忽略。
  • 无效的域名和不匹配的增强型电子商务方案。数据层变量实现增强的电子商务需要清晰的文档。因此,在起草您的规范时,最好将所有字段检查两遍。
  • 您没有多货币网站的货币支持。这个问题与所有收入相关的报告都有关系。
  • 不考虑命中极限。例如,假设一个目录页面上可以有多达 30 种不同的产品。如果我们同时转移所有产品的视图信息,很可能 Google Analytics 中的点击不会被转移。

测试 Google Analytics 和 Google Tag Manager 设置

检查完技术文档后,下一步是检查您的 Google Analytics 和 Google Tag Manager 设置。

为什么要测试 Google Analytics 和 Google Tag Manager 设置?

  • 确保数据收集系统正确处理参数。Google Analytics 和 Google Tag Manager 可以与您网站上的指标实现并行配置。在分析师完成之前,这些数据不会出现在谷歌分析中。
  • 让测试嵌入网站的指标变得更加容易。你只需要专注于开发人员的部分工作。在 X 的最后阶段,你需要直接在网站上寻找错误的原因,而不是在*台设置中。
  • 维修成本低,因为不需要开发人员参与。

谷歌分析中最常见的错误:

  • 未创建自定义变量。这尤其与 Google Analytics 360 帐户相关,它可以有多达 200 个指标和 200 个参数。那样的话,很容易漏掉一个。
  • 指定的访问范围无效。在数据层检查阶段或通过检查您发送的 hit,您将无法捕捉到此错误,但是当您创建报告时,您会发现数据看起来并不像预期的那样。
  • 您将获得一个现有参数的副本。此错误不影响正在发送的数据,但在检查和构建报告时可能会导致问题。

谷歌标签管理器最常见的错误:

  • 没有添加任何参数,如通用分析标签或谷歌分析设置变量。
  • 标签中的索引与 Google Analytics 中的参数不匹配,这就产生了将值传递给错误参数的风险。例如,假设您为项目评级参数指定了 GTM 中用户数量参数的索引。在构建报告时,可能会立即发现这个错误,但是您将不再能够影响收集的数据。
  • 数据层中指定的变量名无效。创建数据层时,请确保指定变量在数据层数组中的名称。如果您键入或写入另一个值,此变量将永远不会从数据层中读取。
  • 增强型电子商务跟踪未启用。
  • 启动触发器配置不正确。例如,触发 X 的正则表达式写得不正确,或者事件名中有错误。

测试谷歌分析的实施

测试的最后阶段是直接在现场测试。这个阶段需要更多的技术知识,因为您需要观察代码,检查容器是如何安装的,并阅读日志。所以你需要精明,使用正确的工具。

为什么要测试嵌入式指标?

  • 检查实现的内容是否符合规范,并记录任何错误。
  • 检查要发送的值是否足够。验证参数正在传输要传输的值。例如,商品的类别不通过它的名称来代替。
  • 向开发人员反馈实现的质量。基于这些反馈,开发人员可以对网站进行修改。

最常见的错误:

  • 并没有涵盖所有场景。例如,假设一个商品可以添加到产品、目录、促销或主页上的购物车中,也就是说,可以添加到任何有该商品链接的地方。这么多切入点,可能会漏掉一些东西。
  • 该任务并未在所有页面上实现。也就是说,对于某些页面或某些分区/目录,根本不收集数据,或者只收集部分数据。为了防止这种情况,我们可以起草一份清单。在某些情况下,我们可以对一个函数进行多达 100 次检查。
  • 并非所有参数都已实现;也就是说,数据层只实现了一部分。
  • 增强型电子商务的数据层方案被打破。对于向购物车中添加商品、在结账步骤之间移动以及点击商品等事件来说尤其如此。实现增强型电子商务最常见的错误之一是在产品数组上缺少方括号。
  • 数据层使用空字符串而不是 null 或 undefined 将参数归零。在这种情况下,Google Analytics 报告包含空行。如果您使用 null 或 undefined,此选项甚至不会包含在您发送的 hit 中。

检查数据的工具

我们用来测试数据的工具:

  • 谷歌分析调试器 Chrome 扩展
  • GTM 调试器,可以用来在 Google 标签管理器中启用预览模式
  • 开发人员控制台中的数据层命令
  • 开发人员控制台中的网络选项卡
  • 谷歌标签助手 Chrome 扩展

让我们仔细看看这些工具。

谷歌分析调试器

若要开始,您需要在浏览器中安装并启用此扩展。然后打开页面 ID 并转到控制台选项卡。您看到的信息是由扩展提供的。

该屏幕显示与 hits 一起传输的参数以及为这些参数传输的值:

图片由作者提供

还有一个扩展的电子商务区块。您可以在控制台中找到它,名称为 ec :

图片由作者提供

此外,此处还会显示错误消息,例如超出命中大小限制的消息。

如果需要检查数据层的组成,最简单的方法是在控制台中键入 dataLayer 命令:

图片由作者提供

这是所有传输的参数。可以详细研究一下,验证一下。站点上的每个动作都反映在数据层中。假设你有七个对象。如果你点击一个空字段并再次调用数据层命令,第八个对象应该出现在控制台中。

谷歌标签管理器调试器

要访问 Google Tag Manager 调试器,请打开您的 Google Tag Manager 帐户并点击预览按钮:

图片由作者提供

然后打开您的站点并刷新页面。在下面的窗格中,应该会出现一个面板,显示该页面上运行的所有标签。

图片由作者提供

添加到数据层的事件显示在左侧。通过点击它们,您可以检查数据层的实时组成。

测试移动浏览器和移动应用程序

手机浏览器测试特点:

  • 在智能手机和*板电脑上,网站可以在自适应模式下启动,也可以有单独的移动版本。如果你在桌面上运行一个网站的移动版本,它将与你手机上的相同版本不同。
  • 一般来说,扩展不能安装在移动浏览器中。
  • 为了弥补这一点,您必须在网站的通用分析标签或谷歌分析跟踪代码中启用调试模式。

移动应用测试的特点:

  • 使用应用程序代码需要更多的技术知识。
  • 你需要一个本地代理服务器来拦截点击。为了跟踪设备发送的请求数量,您可以按应用程序的名称或请求发送到的主机来过滤请求。
  • 所有命中都以测量协议格式收集,并需要额外的处理。一旦收集并过滤了命中结果,就必须将它们复制并解析成参数。你可以使用任何方便的工具来做到这一点: Hit Builder ,Google Sheets 中的公式,或者 JavaScript 或 Python 应用程序。这完全取决于什么对你更方便。此外,您还需要了解测量协议参数,以识别发送的点击中的错误。

如何使用您的手机浏览器

  • 通过 USB 将移动设备连接到笔记本电脑。
  • 在你的设备上打开谷歌浏览器。
  • 在 Chrome 开发人员控制台中,打开远程设备报告:

图片由作者提供

  1. 点击对话框中的 Ok 确认与设备的连接。然后选择想要检查的标签,点击检查
  2. 现在,您可以在标准模式下使用开发人员控制台,就像在浏览器中一样。您将拥有所有熟悉的选项卡:控制台、网络和其他。

如何使用移动应用程序

  1. 要使用移动应用程序,您必须安装并运行代理服务器。我们推荐查尔斯。

2.安装代理服务器后,检查应用程序连接到哪个 IP 地址:

图片由作者提供

3.然后拿起您的设备,使用端口 8888 通过代理服务器配置 Wi-Fi 连接。这是 Charles 默认使用的端口。

4.之后,就是收集点击量的时候了。请注意,在应用程序中,命中不是发送到收集,而是发送到批处理。批处理是一个打包的请求,可以帮助您发送多个请求。首先,它节省了应用程序资源。第二,如果有网络问题,请求将存储在应用程序中,一旦网络连接重新建立,就会发送一个公共池。

图片由作者提供

5.最后,必须将收集的数据解析(分解)成参数,按顺序检查,并对照规范进行检查。

图片由作者提供

检查谷歌分析报告中的数据

这一步是最快最容易的。同时,它确保谷歌分析收集的数据是有意义的。在您的报告中,您可以检查数百个不同的场景,并根据设备、浏览器等查看指标。如果您发现数据中有任何异常,您可以在特定的设备上和特定的浏览器中播放该脚本。

您还可以使用 Google Analytics 报告来检查传输到数据层的数据的完整性。也就是说,取决于每个场景,变量被填充,是否有所有的参数在其中,参数是否取正确的值,等等。

最有用的报告

我们希望分享最有用的报告(在我们看来)。您可以将它们用作数据收集清单:

我们来看看这些报表在界面上是什么样子的,你需要先关注这些报表中的哪一个。

产品性能报告

这份报告中最有价值的标签是购物行为。它分析了增强型电子商务的每个阶段的数据收集的完整性。也就是说,我们可以看到 Google Analytics 是否转移了产品列表视图、点击、产品详细信息视图、向/从购物篮添加/删除产品以及购买本身。

图片由作者提供

这里要注意什么?首先,如果任何一列中的值为零,那就非常奇怪了。第二,如果某个阶段的值比前一个阶段多,那么收集数据可能会有问题。例如,假设某项商品的唯一购买次数大于结账次数。这很奇怪,值得注意。

您还可以在该报告中的其他参数之间切换,该报告也应发送到增强型电子商务。例如,如果您选择项目类别作为主要选项,您可能会看到某些类别的项目有销售,但没有这些项目的视图,没有添加到购物车,等等。

顶级事件报告

首先,有必要遍历传输到 Google Analytics 的所有参数,看看每个参数取什么值。通常情况下,一切是否正常很快就会一目了然。可以在自定义报告中对每个事件进行更详细的分析。

图片由作者提供

成本分析报告

另一个标准报告是成本分析,它对于检查将费用数据导入 Google Analytics 非常有用。

我们经常看到这样的报道,有一些资源或广告活动的费用,但没有会议。这可能是由 UTM 标签中的问题或错误引起的。或者,谷歌分析中的过滤器可能会排除来自特定来源的会话。这些报告需要不时检查。

自定义报告

我们想强调一下允许您跟踪重复交易的自定义报告。这很容易设置:参数必须是事务 ID,关键维度必须是事务。

请注意,当报告中有多个交易时,这意味着关于同一订单的信息被发送了多次。

图片由作者提供

如果您发现类似的问题,请阅读这些关于如何解决的详细说明

在这篇关于如何对网站分析进行审计的文章中,进一步了解配置 web analytics 时需要注意的事项以及使用哪些报告来验证数据质量。

自动电子邮件提醒

Google Analytics 有一个非常好的定制提醒工具,可以让你在不查看报告的情况下跟踪重要的变化。例如,如果您停止收集有关 Google Analytics 会话的信息,您会收到一封电子邮件通知。

图片由作者提供

我们建议您至少为以下四个指标设置通知:

  • 会话数量
  • 跳出率
  • 收入
  • 交易数量

要设置通知,请看这篇关于在谷歌分析中自动化报告的文章。

测试自动化

根据我们的经验,这是最困难和最耗时的任务——在这条狭窄的线上,错误是最常见的。

为了避免数据层实现出现问题,必须至少每周进行一次检查。一般来说,频率应该取决于您在站点上实现更改的频率。理想情况下,您需要在每次重大更改后测试数据层。手动完成这项工作非常耗时,因此我们决定自动化该过程。

为什么要自动化测试?

为了自动化测试,我们构建了一个基于云的解决方案,使我们能够:

  • 检查站点上的数据层变量是否与参考值匹配
  • 检查谷歌标签管理器代码的可用性和功能
  • 检查数据是否被发送到 Google Analytics 和 OWOX BI
  • 在 Google BigQuery 中收集错误报告

测试自动化的优势:

  • 显著提高测试速度。根据我们的经验,您可以在几个小时内测试数千个页面。
  • 获得更准确的结果,因为排除了人为因素。
  • 降低测试成本,因为您需要更少的专家。
  • 增加测试的频率,因为您可以在每次更改网站后运行测试。

我们使用的算法的简化方案:

图片由作者提供

当您登录我们的应用程序时,您需要指定要验证的页面。你可以通过上传一个 CSV 文件,指定一个到站点地图的链接,或者简单地指定一个站点 URL,在这种情况下,应用程序会自己找到站点地图。

然后,为每个要测试的场景指定数据层方案是很重要的:页面、事件、脚本(一系列动作,比如结帐)。然后,您可以使用正则表达式来指定页面类型与 URL 匹配。

在收到所有这些信息后,我们的应用程序按照计划运行所有页面和事件,检查每个脚本,并将测试结果上传到 Google BigQuery。基于这些数据,我们设置了电子邮件和延期通知。

如何使用 Elasticsearch、Filebeat 和 Metricbeat 监控 Docker 容器

原文:https://towardsdatascience.com/how-to-monitor-docker-containers-with-elasticsearch-filebeat-metricbeat-493b18681464?source=collection_archive---------11-----------------------

集装箱——摄影乔纳斯·史密斯Unsplash

使用弹性堆栈监控码头集装箱

H 避免多个容器分布在不同的节点上带来了跟踪容器健康状况、存储、CPU、内存利用率和网络负载的挑战。虽然您可以使用 Portainer 之类的工具来监控和跟踪您的 dockers,但是在生产环境中,Elastic stack 成为监控和维护这些工具的最佳工具(依我之见)。

Elastic 的趋势已经转向通过弹性代理进行集成,现在包括一个 Docker 集成,它可以从 Docker 容器中获取指标。它侧重于默认情况下启用的以下指标:

container
cpu
diskio
healthcheck
info
memory
network

弹性代理显然是集成到弹性堆栈的未来,是非常需要的无障碍配置,但在现实中,Metricbeat 和 Filebeats 仍然非常需要,因为它们提供了更多的灵活性。目前的情况是,即使服务器上安装了弹性代理,仍有一些用例没有集成到弹性代理中。

测试环境

  • Ubuntu 16.04 (Xenial Xerus) (其中一些是使用 Macbook 上运行的 Docker 上的弹性堆栈在本地执行和测试的)
  • Filebeat 7.16
  • Metricbeat 7.10

安装 Metricbeat

curl -L -O https://artifacts.elastic.co/downloads/beats/metricbeat/metricbeat-7.10.0-amd64.deb sudo dpkg -i metricbeat-7.10.0-amd64.deb

编辑配置:

output.elasticsearch:   
hosts: ["<es_url>"]   
username: "elastic"   
password: "<password>" 
setup.kibana:   
host: "<kibana_url>"

其中<password>elastic用户的密码,<es_url>是 Elasticsearch 的网址,<kibana_url>是 Kibana 的网址。

sudo metricbeat modules enable docker sudo metricbeat setup //This will load all the dashboards in Kibanasudo service metricbeat start

斯蒂芬·查彭达玛截图

Metricbeat 提供的是 CPU 使用率、磁盘空间和性能相关的统计数据。但是,如果您想深入了解容器内部的情况,该怎么办呢?不幸的是,Metricbeat 不提供这种功能。因此,试图理解为什么在凌晨 2 点出现峰值意味着我们需要更深入,这就是 Filebeat 的用武之地。

关键资源

如何安装 metric beat-by Elastic

容器里有什么?

要查看由容器本身生成的日志,我们需要安装 Filebeat 来直接查看特定路径中的容器。不幸的是,Metricbeat 没有提供这种详细程度的信息。

curl -L -O https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.10.0-amd64.deb sudo dpkg -i filebeat-7.10.0-amd64.deb

修改/etc/filebeat/filebeat.yml设置连接信息:

output.elasticsearch:   
hosts: ["<es_url>"]   
username: "elastic"   
password: "<password>" 
setup.kibana:   
host: "<kibana_url>"

其中<password>elastic用户的密码,<es_url>是 Elasticsearch 的网址,<kibana_url>是 Kibana 的网址。在/etc/filebeat/filebeat.yml中,我们还需要添加以下内容:

- type: container# Change to true to enable this input configuration.
  enabled: true# Paths that should be crawled and fetched. Glob based paths.
  paths:
    - /var/lib/docker/containers/*/*-json.log 

默认情况下,所有 docker 容器的标准输出(stdout)都被写入 JSON 文件。这些日志文件存储在运行 docker 引擎的主机上,可以在下面的路径/var/lib/docker/containers/{container-id}/{container-id}-json.log下找到。

一个常见的错误是没有将类型指定为 container,因此要确保指定希望 filebeat 输出容器日志。

sudo filebeat setup sudo service filebeat start

斯蒂芬·查彭达玛截图

值得注意的是 docker 日志的位置。上面提到的是 Ubuntu 服务器上的 docker 日志,但这在 MacOS 上会有所不同,就像在 Windows 上一样,所以请记住这一点。对于 Mac,这可能很难确定,因为这取决于您运行的 macOS 版本。

关键资源

Filebeat 文档

斯蒂芬·查彭达玛的帖子

如何使用 Google Data Studio 和 BigQuery 监控重复购买行为

原文:https://towardsdatascience.com/how-to-monitor-repeat-purchase-behavior-using-google-data-studio-and-bigquery-c2b5adbe8ebb?source=collection_archive---------9-----------------------

创建重复购买行为的自定义自动化可视化指南

Unsplash 上由 Austin Distel 拍摄的照片

监控重复购买行为对于确保零售或电子商务业务盈利至关重要。回头客通常每次购物花费更多,更有可能向其他顾客推荐商店或产品,从而增加新顾客的获得和收入

自动化报告仪表板有助于企业所有者和分析师实时了解重复购买水*。在这篇文章中,我将演示如何使用 Google Data Studio 和 BigQuery 来实现这一点。

如果你从事电子商务,你可能已经有了一个谷歌分析账户,并且能够在那里查看留存率。构建该仪表板的优势在于,您可以根据自己的需求定制视图,并添加对您的业务有独特帮助的指标。除此之外,如果您能够从调查或社交媒体中获得数据,您可以轻松地将仪表板与其他数据源集成。所有的洞察力都集中在一个地方,因此可以更快地做出决策。

这是在 Google Data Studio 中完成的重复购买和保留仪表板示例:

这篇文章以 Google Data Studio 和 Big Query 为特色,但是我将更侧重于创建分析和度量标准,而不是讲授这些工具的基础知识。对于初学者,我会在文章末尾放一些资源供你参考。

数据集

本演示使用的数据是来自 UCI 机器学习库的在线零售数据集。它是一个数据集,包含来自在线零售店的交易。您可以使用任何包含客户 id、订单 id、订单日期和销售额的事务数据来复制这个仪表板。

这些数据是从网站上下载的,然后手动上传到 Google BigQuery,这是一个可扩展的、具有成本效益的数据仓库。如果您的数据来自在线商店,可以设置集成,以便数据从商店流向第三方连接器,然后流向您的 BigQuery 仓库。如果您有这样的设置,数据将定期刷新,确保您获得关于您的业务的最新见解。

我不会详细介绍如何建立数据仓库,因为我打算更多地关注仪表板分析,但 BigQuery 有相当广泛的文档在这里,以供参考。

将 Data Studio 连接到 BigQuery 数据集

建立数据仓库后,下一步是在 Google Data Studio 中创建数据源。以下是执行此操作的步骤:

  1. 在 Data Studio 主页上,单击 Create。选择数据源。
  2. 会出现各种各样的谷歌连接器。选择 BigQuery。
  3. 为事务性数据选择 BigQuery 项目和数据集。
  4. 单击连接。
  5. 数据中的所有字段都将出现。检查数据格式是否正确,并在需要时添加自定义计算字段。对于这个仪表板,我添加了以下内容:
% Repeat Customers:
COUNT_DISTINCT(CASE WHEN RepeatPurchase = ‘Repeat Customer’ THEN CustomerID ELSE NULL END) / COUNT_DISTINCT(CustomerID)Average Order Value (AOV): SUM(Sales)/COUNT_DISTINCT(InvoiceNo)Purchase Frequency: COUNT_DISTINCT(InvoiceNo) / COUNT_DISTINCT(CustomerID)

6.单击创建报告。

现在,您将看到一个空白仪表板,您可以在其中放置所有需要的图表元素。

创建仪表板

让我们将仪表板组件分解为几个关键元素:

  • 页面过滤器
  • 关键指标的最高表现
  • 重复购买的月度趋势
  • 重复购买率(又名队列分析)
  • 重复购买者购买的产品

页面过滤器

作者图片

页面级过滤器通常是您在仪表板上部看到的过滤器。它提供了交互功能,因为它使用户能够深入了解特定组的表现。在我们的控制面板中,我们可以选择关注哪个国家(我默认选择了英国)、产品类型、重复购买群体(首次购买者与重复购买者)以及交易日期。

关键指标的最高表现

作者图片

仪表板的第一个元素应该包含要查看的最重要的业务指标。我更喜欢用简单的记分卡——不要花哨的图表,直接列出你需要看到的关于企业健康状况的数字。我也更喜欢使用紧凑的格式——四舍五入到最多 1 位小数,并加上千位(K)或百万位(M)标记,而不是显示精确的值。这使得图表不那么杂乱,同时不会丢失太多所需的信息。

积极和消极的增长指标(绿色和红色)是一个伟大的事情。无需使用任何额外的图表,您就可以看到企业在特定指标上的表现是超过还是低于前期。

代码:如何使用 BigQuery 创建回头客标志

我们的记分卡中强调的一个关键指标是回头客(之前已经从商店购买过的顾客)。这个指标不能在 Data Studio 中计算,但可以在 BigQuery 中用下面的代码轻松完成:

SELECT *,
CASE WHEN customer_seq > 1 THEN 'Repeat Customer'
ELSE 'New Customer'
END AS RepeatPurchase
FROM (
    SELECT  *,
    RANK() OVER (PARTITION BY CustomerID ORDER BY date) AS customer_seq
    FROM online_retail
)

新字段 RepeatPurchase 是一个字符串字段,指示客户是“回头客”还是“新客户”。

重复购买的月度趋势

作者图片

不用说,有必要在每月视图上查看重要指标。通过这样做,人们能够检查趋势和季节模式,并据此采取行动。

在这个仪表板中,我首先显示了重复购买客户的原始数量以及购买频率。第二张图表显示了回头客与首次买家的比例。从原始计数和百分比两方面来看,随着时间的推移,商店似乎有了更多的回头客,这是一个好迹象。

重复购买率(又名队列分析)

作者图片

该分析通过关注客户“群体”显示了详细的回购率。在这种情况下,我们将群组定义为在特定月份第一次购买的组客户。在示例中,第一个群组是 2011 年 1 月的群组。各栏代表参考月份,即 n 个月后,回购利率是多少?

从该表中可以看出,2011 年 1 月首次购买者中,24%的人会在一个月后从商店回购,3 个月后的回购率为 24.2%,10 个月后的回购率为 36.8%。

“总计”行代表*均回购率,不管我们看的是哪一组。整体来看,该店 1 个月复购率 23.7%,3 个月复购率 23.5%,10 个月复购率 36.8%。

代码:如何使用 BigQuery 执行群组分析

以下代码片段显示了如何计算群组表中的回购率:

仪表板还包含销售百分比的群组分析—为了简洁起见,这里没有显示代码,因为它本质上与上面的相同(不是计算客户,而是计算销售总额)。

重复购买者购买的产品

作者图片

仪表板的最后一部分更侧重于细节,即哪些产品对重复购买客户和销售贡献最大?仅仅一张简单的桌子就足够了。虽然这里没有涉及,但确定有利可图的产品组合的分析,如市场购物篮分析,可以为您的企业提供营销和促销见解。

摘要

在本文中,我介绍了重复购买仪表板在监控零售店绩效方面的价值:

  • 一眼看到背线表演
  • 可视化重复购买的每月趋势
  • 通过队列分析计算重复购买率

这个例子主要关注在线零售数据,但是也可以用于具有类似数据结构的其他销售数据源。任何包含客户 id、订单 id、订单日期和销售额的交易数据都可以用来复制这个仪表板。

我还强调了 Google Data Studio 生成这类报告的能力,以及 BigQuery 如何通过 SQL 语言增强它来进行更高级的分析。

本文中的所有代码都可以在我的 GitHub 上访问。快乐分析!

Google Data Studio 和 Big Query 的有用资源:

如何让您的数据科学解决方案进入放手状态

原文:https://towardsdatascience.com/how-to-move-your-data-science-solution-into-a-hands-off-state-b2a02b1df758?source=collection_archive---------26-----------------------

将数据科学解决方案投入生产的一些工具和技巧

Unsplash 上由 S Migaj 拍摄的照片

一旦您开发了一个数据科学解决方案,就很容易无限期地修补它:手动运行它,对输出进行小的更改,迭代模型。

这并不理想——一旦你有了一个满意的解决方案,理想情况下,你应该能够让它在你最少的投入下运行,除非有什么东西倒下了。

无论您是移交给支持团队,还是自己支持该工具,当您试图将您的解决方案转移到放手状态,或者将其投入生产时,这篇文章都会给出一些提示。

首先,你想要记录。日志记录是将代码输出打印到文件中的地方,以便您(或支持团队)可以在以后引用它。要将代码转移到放手状态,您需要将日志保存到一个文件中,以便在工具出现问题时可以检查这些日志。

照片由思想目录上的 Unsplash

你应该记录什么?工具可能出现的任何明显的问题,比如数据验证输入,或者工具无法连接到 web 服务,等等。应该标记为警告或错误并记录下来。

另一个好的经验法则是标记任何“交易”。我指的是像读取文件、连接数据库或调用 API 这样的事情。这些都是可能失败的事情,并且可以作为代码失败的地方和可能出错的地方的粗略指南。最好在日志的末尾有一个摘要,指出工具是否成功完成,如果失败了,是哪里出错了。日志摘要真的很受支持团队的欢迎。

另一个有用的工具是警报。这是您的工具在出错或失败时通知您(或支持团队)的地方。最有效的方法之一是让你的工具在 slack 或 MS 团队出错时给你发消息。

照片由西格蒙德Unsplash 上拍摄

使用 webhooks 很容易做到这一点。您也可以使用电子邮件进行此操作,例如使用 AWS SNS。当出现问题时,以及工具启动和完成时,通知您是一个好主意;如果没有这些警报,也会告诉您有问题。

伤检分类表是非常宝贵的,尤其是当你移交给一个支持团队或者有人在你离开时照看这个工具的时候。

分类表列出了该工具最容易出错的地方,以及应该联系哪个团队来解决这个问题。例如,如果您的工具依赖于由另一个团队管理的数据馈送;如果这种情况发生,您可以直接联系该团队请求支持。这样,问题就可以得到解决,而不需要你充当中间人,浪费每个人的时间。这样做的行为也迫使您仔细考虑您的工具以及应该有什么样的错误处理,以确保从日志中清楚地看到哪里出错了。

最后,你必须确保你心中有企业的最大利益。作为一名数据科学家,对模型进行不断的迭代,或者同意客户提出的每一个请求都很容易。但归根结底,你的工作是为企业提供尽可能多的价值。你希望一个模型是有效的,但是你不需要它是完美的,在某个点之后,你可能可以在不同的解决方案上提供更多的价值。

同样,倾听客户的需求也是必要的,但是在确保满足客户需求一段时间后,您可能能够通过为客户构建不同的工具来提供更好的价值。

原载于 2021 年 4 月 17 日【https://jackbakerds.com】

如何协商数据科学家的薪酬?

原文:https://towardsdatascience.com/how-to-negotiate-your-pay-for-a-data-scientist-role-b8e0bf3d25a7?source=collection_archive---------23-----------------------

提高 2021 年数据科学工作机会的 7 种方法

UnsplashNeONBRAND 拍摄的照片

在当今快速膨胀的数据世界中,数据科学家正以前所未有的速度被雇佣。随着技术的进步和残酷的竞争,在获得工作之前,候选人会经历许多战斗并取得胜利。尽管第一次给你机会时,你可能会迫不及待地接受,尤其是对于试图进入数据科学领域的人来说——这不是一个好主意!

无论你是数据科学领域的新员工还是有经验的求职者,通过这篇博客,我们将深入了解如何进行要约谈判。

谈论金钱将永远是一个令人不舒服、害怕的话题。利害攸关的时候,你不想低估或高估自己,也不想给人留下贪婪的印象,但公司会希望你带着筹码来!
永远谈判!

很快,我将从研究生院毕业,也将为数据科学职位进行谈判。预计到谈判和外围金钱谈判,我开始了一个研究项目——如何为数据科学角色进行谈判?到目前为止,我已经从我的导师、业内数据科学家、招聘人员和同行的见解中学到了一些东西——这是这篇博客的灵感。

1.在给这项工作定一个数字之前,先做一下调查

在你确定你应该得到的薪酬之前,第一步——调查相似公司或整个行业中相似职位的*均薪酬。

  1. 向你的大学校友、你现在公司的高层或者你认为是资源的人,以及同一领域的同行询问一个大概的薪酬范围
  2. 从导师那里寻求帮助,根据你的经验和角色,应该给你多少钱
  3. 使用工资比较工具在网站上查找*均工资,了解行业内的大致情况:

4.与你的关系网联系:与你周围在该领域比你更有经验的人交谈,评估他们可能拥有的经验

2.个人因素

对于任何一个承诺担任某个职位的候选人来说,在开始从事该职位之前,有许多因素需要考虑。你的薪酬决定也应该考虑个人因素。

当你研究职位的*均薪酬时,一定要记住你的个人财务义务。你的工资应该是你过上舒适生活所需的数额,而不仅仅是你希望挣的数额。

  1. 经验年限/资历水*(1-2 年经验 vs 10 年以上)
  2. 教育水*(训练营、统计学、硕士学位)
  3. 技能( SQL,TensorFlow,深度学习)
  4. 以前的薪资(期望下一个角色的薪资相同或更高)

3.公司因素

当你在寻找一些因素来决定你要求的最佳工资时,你需要确保看得更远,并考虑这份工作在你生活中更广泛的意义。

你的薪资期望将不可避免地高度依赖于你的个人偏好和你目前的生活状况。根据你的公司/雇主,你应该考虑一些更重要的因素:

  1. 地点(旧金山、芝加哥、纽约市、西雅图)
  2. 公司规模( 10,000 多名员工或初创公司)
  3. 行业(科技娱乐、保健、食品&饮料或其他)
  4. 位置类型(城市或农村)
  5. 团队中的其他数据科学家(一个限制因素是其他人的薪水)
  6. 职位名称(高级数据科学经理,初级机器学习工程师)

在出价时,生活成本是决定几千美元的一个关键因素。确保你评估了可能从一个州搬到另一个州的多个方面,并比较了你的工资和生活成本的差异 CNN 金钱计算器moveBuddha 应该可以帮助你做到这一点。

4.拥有无人能拒绝的技能

为谈判对话做准备,你能做的最好的事情就是提前知道你的市场价值。

准备好向你的雇主展示你是如何“完美地适合”这个职位和组织的。最终,一切不都是为了成为一个合适的人吗?为了向经理证明你的价值,并在你的最终报价中多拿几千美元,试着将你自己与公司的目标、使命和愿景联系起来。改进你的技能,展示你对团队的激情和热情。

  1. 分享你给团队和组织带来的独特价值
  2. 量化你的市场价值,这会影响你的薪酬
  3. 展示你的相对市场价值

5.分享你的期望

期望价值=你最希望得到的薪酬金额
保留价值=你愿意接受的最低薪酬金额(也称为“离职”薪酬)

如果你和你的雇主对你的最低工资期望意见不一致,准备好拒绝的邀请。未来加薪的承诺现在对你没有帮助。你的聘书里写的是你能得到的,之后的任何限制都是你如何做出决定的。

一位和我交谈过的有经验的谈判者说—

“不要成为第一个为工作设定数字的人。让你的雇主给你一份书面工作邀请,看看年底你到底能挣多少钱,然后在此基础上做出决定。”

我在某处读到的另一个评论有一个观点—

“如果你无法回避,就从说一些积极的、有效的关于这个职位的话开始,并提及你目前可能拥有的任何其他机会。如果你对这个报价满意,你可以随便找个理由要求更高的价格。如果没有,礼貌地感谢他们的考虑,并做出相应的决定。”

6.获得竞争性报价

"对其他大幅涨价的提议要诚实!"

如果你发现自己对 X 雇主提供的工作感到开心和满意,那么恭喜你!!

但是,如果你有一个诱人的、有竞争力的报价,你绝对处于有利的谈判地位——利用这一点!虽然在接受工作机会时,薪酬是一个有利可图的因素,但一定要好好想想——竞争的工作会挤掉你目前的工作机会吗?开车送你去工作会有足够的挑战性吗?

不管是哪种情况,你已经被录用了,即使有一份竞争性的工作,我们上面提到的所有工资谈判的标准规则仍然适用。确保你知道你的市场价值和传达你期望的好时机。

7.找其他员工福利去洽谈

虽然关于工作机会的任何事情都很紧张,但最重要的是要知道什么是可以谈判的。补偿金额,福利待遇,保险,工作条件,假期,工作天数和时间,工作弹性选项,头衔,遣散费,这些都是可以谈判的。

如果右边的路没有把你带到你想要的地址,考虑从左边走——一笔不错的收入。

如果你想成为一名更好的谈判者,有一本书是你应该读的,那就是"杰克·查普曼的《谈判你的薪水》

摘要

  1. 一旦你有了正式的书面工作机会,仔细看看所有的条款,工资,福利等。
  2. 重新审视你的薪资调查和个人财务义务
  3. 如果你对这份工作非常满意,打电话给雇主口头接受这份工作。否则,考虑协商一个更好的提议

这就是我的博客的结尾。感谢您的阅读!我希望你喜欢这篇文章。请务必让我知道什么帮助了你的谈判之旅,或者你打算利用它?

数据帐篷快乐!

免责声明:本文表达的观点仅代表我个人,不代表严格的观点。

了解你的作者

拉什是芝加哥伊利诺伊大学的研究生。她喜欢将数据可视化,并创造有见地的故事。当她不赶着赶学校的最后期限时,她喜欢喝一杯热巧克力,写一些关于技术、UX 等的东西。

面对数据科学面试的拒绝,如何不觉得自己是废物

原文:https://towardsdatascience.com/how-to-not-feel-like-crap-facing-rejections-from-data-science-interviews-89035129a466?source=collection_archive---------45-----------------------

照片由 Jakayla ToneyUnsplash 上拍摄

根据我 7 个月的求职经验

2020 年可能是求职最糟糕的一年,尤其是作为一名应届毕业生。与许多有经验的人才在同一个求职池中争夺有限的工作机会对我来说是一场噩梦。幸运的是,经过 7 个月的不断求职,我终于得到了一份让我超级兴奋和满意的工作。我要感谢我自己,即使面对一次又一次的拒绝,我总是有力量振作起来。如何处理失败是我从 2020 年学到的最重要的一课。在这篇文章中,我想讨论一下我的求职经历,希望能给当前压力大的求职者一些有益的建议。

回到 2020 年 8 月,由于加利福尼亚的野火,我从公寓里被疏散出来。在疏散过程中,我接到了面试了一个多月的公司招聘人员的电话。她打电话告诉我,我没有通过现场面试,在电话中我几乎无法控制自己的悲伤。当男朋友带我去 20 分钟车程外的城市买波霸奶茶时,我忍不住大声哭了出来,我发现奶茶的味道像狗屎一样。我仍然记得当时的复杂心情。它们包括因为被拒而对自己的怀疑,当建立起来的希望破灭时我感到的空虚,对再次经历面试过程的恐惧,以及对公寓被野火烧毁的担忧。那绝对是我 2020 年的最低点。尽管花了我几天时间,我最终还是振作起来,鼓励自己重新开始。这里有一些建议,如果你在找工作时也遇到拒绝的话。

即使在面试过程中也要申请

我在第一次被拒绝后学到的重要一课是永远不要停止求职。我对那家公司的面试过程很长。这是我参加的前几次面试,为了更好地准备,我停止了找工作,专注于复习面试材料。直接的结果是当我得到拒绝的时候,我没有其他公司的 offers 或面试机会,我不得不从头开始找工作。如果我知道我有其他公司的机会,即使这家公司拒绝了我,我会感觉好得多。即使你得到了一个报价,有其他竞争报价会给你更多的谈判力量。另外,面试的次数越多,你在面试时就越自在。*衡你准备面试和找工作的时间是非常重要的。

不断积累简历

很多时候,我们会立即遭到拒绝,或者永远得不到公司的回复。当第一轮被拒的频率太高时,你需要仔细检查你申请的职位是否匹配,并努力提高你的简历和职位的潜在匹配度。如果你申请的是不同的职位,量身定制简历以增加契合度是必不可少的。你可以有几个版本的简历来适应你通常申请的不同职位。另外,雇佣一个专业人士,和你感兴趣的职位的朋友交谈,或者去学校职业中心修改你的简历,如果你没有从各种工作申请中得到任何运气的话。你可能需要调整你的简历格式,在简历中加入更多相关的技能或经验,或者参与更多的项目来展示你的技能。你可以建立一个投资组合页面,并改进你的 LinkedIn 主页,以增加被招聘人员注意到的机会。

保持联系

人脉对于获得面试机会至关重要。既然大家都在申请,那你的简历要想在人群中脱颖而出就更难了。在 LinkedIn 或虚拟会议上建立一些关系网并寻求推荐比直接申请更有帮助。你可以联系校友或任何与你有共同之处的人。有些人会忽视或拒绝,但伸出手去问一下你是否礼貌地表达了这一点,总不会有什么坏处。网上也有写冷冰冰的电子邮件的模板,要求引荐,这对人际关系网很有帮助。如果你还没有这样做的话,把人际关系网作为你日常求职的一部分。

从每次面试中学习

找工作对我来说是一次宝贵的学习经历。准备各个公司的面试,帮助我复习和练习不同领域的硬技能。我最初开始在 Medium 写作,分享我为准备不同的面试而组织的学习材料。我写了一个名为“自信地搞定数据科学面试的系列文章,帮助我在每次面试前回顾重要的概念。当我不得不花很长时间在网上搜索教程寻找具体概念时,我自己写了一篇博文来整理我所学到的东西,希望能让其他有类似顾虑的人受益。

在不同的阶段和不同的公司进行各种面试也让我练习了软技能。我有机会练习沟通技巧,获得一些商业意识,并学习如何准确地回答问题。重要的是,事后自己或与有经验的朋友一起回顾面试,以了解下次你可以做得更好。

永远对自己有信心

找工作充满了不确定性和压力。我记得所有以检查电子邮件开始的早晨,希望得到招聘人员的联系,以及所有因焦虑而失眠的夜晚。在疫情期间被录用是非常困难的,所以当被拒绝后不要自责。不是因为你不够好。这只是因为它不是合适的匹配,无论是对你还是对公司。我记得在一次现场面试后,我收到了一封拒绝信,后来我发现他们已经找了半年多的候选人,已经拒绝了超过 14 位候选人。当收到拒绝时,如果可能的话,请公司提供一些反馈,并向有经验的朋友寻求建议。如果你有提高的空间,例如,你的编码能力,沟通技巧,努力提高硬技能和软技能。花点时间让自己振作起来,鼓励自己重新开始,希望下次能找到更好的搭配。永远不要怀疑自己,因为展现自信不仅在面试中很重要,在自我发展中也很重要。

找工作就像坐情感过山车。最重要的部分是从错误中学习,永不放弃。当遭到拒绝时,不要把它当成是针对你自己的,振作起来,自信地迎接下一次挑战。

感谢您的阅读。这是我所有博客帖子的列表。如果你感兴趣的话,可以去看看!

https://zzhu17.medium.com/my-blog-posts-gallery-ac6e01fe5cc3 https://zzhu17.medium.com/membership

如何聘用新的数据分析师

原文:https://towardsdatascience.com/how-to-onboard-new-data-analysts-45605f904ef9?source=collection_archive---------27-----------------------

更快增值的技巧

图片由摄影师 7Pixabay 拍摄

你是否曾经在一家新公司开始工作,入职过程并不理想?你的经理不清楚你应该从哪里开始,入职意味着边干边学。在担任过数据科学家和数据分析师之后,我发现这些帮助我更快地加入,并增加价值,即使我没有明确的指导。

了解公司业务

我的第一个入职项目是了解公司的商业模式,收入的主要来源,以及用于衡量成功的 KPI。这些知识帮助我在关于实验设计的 A/B 测试讨论中,决定用 KPI 来衡量成功。我还能够根据对影响收入的 KPI 的影响来确定请求的优先级,并向利益相关者解释为什么其他请求被取消优先级。

学习数据

我的下一项任务是了解数据库中有哪些数据。我回顾了表、字段值和 ETL 作业,以帮助我理解表之间的连接逻辑和用于计算 KPI 值的业务逻辑。我还查看了可用的数据字典和查找表,以了解特定于公司的字段值,如产品标识符和定价代码。

当我与利益相关者会面讨论请求时,尽早了解数据在许多方面都有帮助。首先,如果基于数据可用性的请求是可能的,我能够立即做出响应,而不是事后研究并返回给利益相关者。第二,我可以使用其他数据源提出替代方案,并在同一次会议中结束需求讨论,而不是因为我不知道答案而召开第二次会议。

见面打招呼

安排 30 分钟的见面和问候会议,与公司里你可能会接触到的人见面。如果你不确定该找谁,可以向你的经理或利益相关者索要一份他们推荐你见的人的名单。我发现这是和新公司的人打破僵局的好方法,也知道如果我对某个特定的问题有疑问该问谁。由于许多人目前都在远程工作,这是新数据分析师在入职过程中更有好处的一个方面。在面试过程中,我没有和所有利益相关者交谈,这些会议帮助我了解了他们在公司中的角色,以及我可以提供哪些见解来帮助他们实现目标。

不接受现状

作为一名新的数据分析师,您有着全新的视角,能够发现现有员工可能看不到的问题。仅仅因为公司总是以某种方式做事并不意味着没有改进的空间。询问您的利益相关者或同事正在经历的棘手问题,并找出任何可以改进的地方。

当我刚开始在当前公司担任数据分析师时,更新订阅仪表板的 ETL 被分成 4 个作业,如果作业失败,重新运行效率很低,因为我必须手动一个接一个地重新运行作业。如果任何一个任务失败了,这会导致利益相关者的报告延迟——这种情况经常发生。我将 ETL 重写为一个作业,减少了更新仪表板的运行时间,使我的生活更加轻松,因为如果出现故障,我只需手动重新运行一个作业,而不是 4 个。

结论

作为一名新公司的数据分析师,并不总是清楚应该从哪里开始。对于那些有入职计划的幸运儿,我祝贺你有了一条清晰的道路。对于像我一样不得不寻找出路的人来说,我希望这些建议能让你未来的入职过程变得更容易。

你可能也会喜欢…

https://medium.datadriveninvestor.com/4-habits-of-bad-data-analysts-731ec6b7c537

如何优化深度学习模型

原文:https://towardsdatascience.com/how-to-optimize-a-deep-learning-model-2e9ff8a4c5de?source=collection_archive---------10-----------------------

通过有效的超参数优化,让您的模型更加出色

约翰·巴克利在 Unsplash 上拍摄的照片

超参数优化是任何机器学习管道的关键部分。仅仅选择一个型号不足以实现卓越的性能。您还需要调整您的模型,以便更好地解决问题。

这篇文章将讨论深度学习架构的超参数调整。有代码块来重新创建所示的示例。

欢迎将这篇文章加入书签,复制代码来快速优化你的深度学习模型。

如果您正在开发不同的深度学习模型,请用您的特定模型替换函数“create_model”中的代码,并更新每个函数的相关超参数。其余的优化代码是独立于模型的。

使用 scikit-learn 开发模型时,超参数调整是一个相对简单的过程。随机搜索和网格搜索各有利弊。然而,被称为贝叶斯优化的第三种选择为超参数优化提供了一种实用、*衡的方法,可以产生更稳健的模型。

黑盒模型

机器学习中的优化通常遵循相同的格式。首先,定义一个代表损失的函数。然后,通过最小化这种损失,该模型被迫产生日益改善的性能。
选择损失函数有两个主要原因。首先,它们很好地代表了问题。

标准损失函数的第二个方面是梯度被很好地定义。通过定义明确的梯度,许多不同的优化技术变得可用。最常见的是依赖于函数梯度的梯度下降法。

但是当函数没有梯度时会发生什么呢?当您有一个黑盒模型时,这种情况正是如此。

萨姆·穆卡达姆在 Unsplash 上拍摄的照片

黑盒模型有一个输入和一个输出。但是盒子里发生了什么是未知的。该属性使模型成为黑盒模型。

当模型是黑箱时,优化问题就更加困难。

不幸的是,在建立深度学习模型时,黑盒是标准的,因此标准的优化方法性能不佳。

简要考虑为什么梯度下降等优化方法无法优化超参数。如果你想优化一个超参数,你需要确定这个超参数的导数。例如,想象一下对随机森林的估计数进行求导。不可能的。

然而,黑盒优化并不关心确定函数的导数。相反,目标是基于来自超参数空间的多个样本来选择函数。那么一旦这个函数紧密表示超参数空间,你就可以优化这个函数了。这种优化的结果产生了最佳的超参数配置,其应该在原始黑盒函数上表现良好。

贝叶斯优化

在上一篇文章中,我讨论了不同的超参数调优方法,并介绍了贝叶斯优化。有关其他可用调优方法的详细信息、它们的缺陷和优点,请参考我之前的帖子:

贝叶斯优化是从可能的超参数空间中采样,基于这些样本建模函数,然后优化该模型的过程

贝叶斯优化是从可能的超参数空间重复采样、基于这些样本建模函数、然后优化该模型的过程

与需要使用导数进行优化的梯度下降相反,贝叶斯优化创建了通过从超参数空间多次采样而生成的代表性函数。

这种多次采样和生成空间*似值的过程就是该方法是贝叶斯方法的原因。最后,使用来自重复采样的先验信息来调整代表性函数。

这个过程需要两件事,一个是从超参数空间采样的方法,另一个是优化产生的函数的方法。

从黑盒采样的方法需要对超参数空间进行采样,基于多个样本创建代表性函数,然后优化该函数。因此,输入成为超参数,输出是模型的性能。

利用来自超参数空间的足够数量的样本,生成该函数的良好*似。由此,该模型然后被优化用于超参数的最佳配置。

深度学习架构

深度学习模型需要大量的调整。当你手动调整你的深度学习模型时,这是非常耗时的。

用于定义深度学习模型的超参数数量众多。

通过反复手动更改网络中的参数,您可以有效地执行实际的网格搜索。

您可以定义想要分析的每个超参数的分布,而不是手动检查不同的网络配置。然后有了很多样本,你就能找到一个更优的模型,你就能清楚地了解每个超参数对你的模型整体的影响。

这种架构调整方法至少需要两个函数。首先,评估函数并存储最佳结果和函数以基于一组超参数生成深度学习模型的过程。

优化深度学习模型

在这篇文章中,我将重点关注优化一个具有脱落层的神经网络的架构。我将在 TensorFlow 中使用 Keras,因为它可以直接快速地生成不同的模型。

这里稍作停顿,向 Keras 和 TensorFlow 的负责人说声谢谢。如果你曾经从零开始创建过神经网络、CNN 或 LSTM,你就会知道这是极其乏味和复杂的。因此,我非常感激这些图书馆的存在,并向公众开放。

使用从每个定义的分布中采样的超参数来生成模型。这些值控制层的数量、每个层上的节点数量、脱层概率、学习速率、优化器、优化方法的学习衰减以及激活函数。这个模型是为分类而建立的。

可以将这些函数应用于不同的网络,例如卷积神经网络。然而,由于卷积层的性质,每个后续层都依赖于前一层。这一方面增加了模型创建功能的复杂性。CNN 优化将可能是未来文章的重点。然而,CNN 的一个简单解决方法是固定层数并优化其余参数。

第一步是导入一些包并初始化一些参数。在这里,我还初始化了我要测试的不同超参数的分布。您会注意到,我没有将所有的超参数都设置为分布,所以我不会测试所有可能的组合。

导入和数据加载

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
import tensorflow as tf
from tensorflow.keras import backend as K
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout
from tensorflow.keras.callbacks import TensorBoard
from tensorflow.keras.optimizers import Adam, SGD
from tensorflow.keras.models import load_model
from tensorflow.keras.callbacks import EarlyStopping
from tensorflow.keras.optimizers.schedules import ExponentialDecay
import skopt
from skopt.space import Real, Categorical, Integer
from skopt import gp_minimize, forest_minimize
from skopt.plots import plot_convergence, plot_objective, plot_evaluations
from skopt.utils import use_named_args
print( "Tensorflow version: ", tf.__version__)data = load_breast_cancer()
y = data.target.astype(float)
X = data.data
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.4, random_state=2)
X_validation, X_test, y_validation, y_test = train_test_split(X_test, y_test, test_size=0.4, random_state=2)

接下来,定义超参数的分布。这些分布可以是实连续值、整数值或分类值。此外,还为连续分布添加了分布类型。

例如,当您要测试的大部分值都落在对数均匀分布的子集中时,对数均匀分布可能更适合学习率衰减。超参数也需要默认值。这些默认值用于优化过程中构建的第一个模型。

超参数初始化

dim_optimization = Categorical(categories=['adam', 'SGD'],
name='optimization')
dim_learning_rate = Real(low=1e-3, high=1e-1, prior='log-uniform',
name='learning_rate')
dim_learning_decay = Real(low=0.9, high=0.999, prior='uniform',
name='learning_decay')
dim_num_layers = Integer(low=1, high=5, name='num_layers')
dim_num_dense_nodes = Integer(low=5, high=50, name='num_dense_nodes')
dim_dropout_prob = Real(low=0.5, high=0.99, prior='uniform',
name='dropout_prob')
dim_activation = Categorical(categories=['sigmoid', 'softmax', 'relu'],name='activation')dimensions = [
    dim_optimization, dim_learning_rate, dim_learning_decay,
    dim_num_layers, dim_num_dense_nodes, dim_dropout_prob, dim_activation
]NUM_LAYERS = 1
BATCH_SIZE = 128
LEARNING_RATE = 0.001
DECAY_STEPS = 1000
DENSE_UNITS = 20
DROPOUT_PROB = 0.8
ACTIVATION_FUNC = 'relu'
LOSS_FUNC = 'binary_crossentropy'
METRIC = 'accuracy'
LEARNING_DECAY = 0.9
OTIMIZATION_FUNC = 'adam'
ACQ_FUNC = 'EI' # Expected Improvement
best_score = 0
EPOCHS = 50
BATCH_SIZE = 256
N_CALLS = 1000default_parameters = [OTIMIZATION_FUNC, LEARNING_RATE, LEARNING_DECAY, NUM_LAYERS, DENSE_UNITS, DROPOUT_PROB, ACTIVATION_FUNC]

如果你想改变底层模型,这个函数就需要改变。根据超参数输入,一些模型参数可能以其他参数为条件。例如,在 CNN 中,过滤器尺寸影响下一层的输出形状。目前 skopt 不支持条件特性。

对于这个例子,我控制了每个密集层中的单元数量,然后添加了一个下降层。这个结构是一个相当简单的网络,但是这个代码可以很容易地修改,以包含您选择的不同模型。

下一个代码块基于来自样本的超参数生成深度神经网络。

深度学习模型生成

def create_model(optimization, learning_rate, learning_decay, num_layers, num_dense_nodes, dropout_prob, activation):
    model = Sequential()
    name = 'layer_{0}_dense_units'.format(0)
    model.add( Dense( num_dense_nodes, input_dim=X_train.shape[1],
        activation=activation, name=name)) for i in range(num_layers-1):
        name = 'layer_{0}_dense_units'.format(i+1) 
        model.add( Dense( num_dense_nodes, activation=activation, name=name))
        model.add( Dropout(dropout_prob)) model.add( Dense(1, activation=activation))
    lr_schedule = ExponentialDecay( initial_learning_rate=learning_rate,
        decay_steps=DECAY_STEPS, decay_rate=learning_decay)

    if optimization == 'adam':
        optimizer = Adam(learning_rate=lr_schedule)
    if optimization == 'SGD':
        optimizer = SGD(learning_rate=lr_schedule)
    model.compile(
        optimizer=optimizer, loss=LOSS_FUNC, metrics=[METRIC])
    return model

适应度是 skopt 将使用‘gp _ minimize’进行优化的函数,它将生成的高斯过程最小化以对超参数空间进行建模。该函数通过构造最小化。因此,最大化的分数变成了负分数的最小化。

适合的功能

@use_named_args(dimensions=dimensions)
def fitness(optimization, learning_rate, learning_decay, num_layers, num_dense_nodes, dropout_prob, activation):
    # Create the neural network
    model = create_model( optimization=optimization,
        learning_rate=learning_rate, learning_decay=learning_decay,
        num_layers=num_layers, num_dense_nodes=num_dense_nodes,
        dropout_prob=dropout_prob, activation=activation)
    # Save log for tensorboard
    callback_log = TensorBoard(
        log_dir =
"./21_logs/opt_{0}_lr_{1:.0e}_lr_decay_{2:.0e}_layers_{3}_nodes_{4}_dropout_{5}_activation_{5}/".format(
        optimization, learning_rate, learning_decay, num_layers,         num_dense_nodes, dropout_prob, activation),
        histogram_freq=0, write_graph=True, write_grads=False, write_images=False) # Train the model.
    history = model.fit(
        x= X_train,y= y_train,
        epochs=EPOCHS,batch_size=BATCH_SIZE,
        validation_data=(X_validation, y_validation),
        callbacks=[callback_log],verbose=0)
    # Get the final model performance.
    col = [x for x in list(history.history.keys()) if 'val_'+METRIC in x]
    score = history.history[col[0]][-1]
    print("--> Validation {0}: {1:.2%}".format(METRIC, score))
    global best_score
    # Track scores and save best model
    if score > best_score:
        model.save('Optimal-NN')
    best_score = score
    # Clear model to save space
    del model
    K.clear_session()

    # Skopt minimizes black-box functions, return the negative
    return -score

skopt 函数‘gp _ minimize’对黑盒模型运行贝叶斯优化,以确定最佳超参数配置。用于优化高斯过程的“acq_func”是优化的几个选项之一。

高斯过程最小化

search_result = gp_minimize(func=fitness,
    dimensions=dimensions,
    acq_func=ACQ_FUNC,
    n_calls=N_CALLS,
    x0=default_parameters)

模型解释

搜索完成后,找到的最佳模型将保存在本地。可以从这一点加载和使用这个模型,如果需要,还可以进一步训练。

搜索结果包含每次评估的超参数以及每个测试模型的性能。

要查看搜索如何随着时间的推移提高模型性能,请运行以下代码块:

plot_convergence(search_result)

优化期间最佳模型性能的收敛(作者提供照片)

然而,仅仅看到不同测试模型的改进并不是贝叶斯优化的最大好处。独立分析每个超参数的行为,以及它们如何与其他超参数相互作用。

_ = plot_objective(result=search_result)

贝叶斯优化的部分相关性和参数交互(作者提供图片)

从上图中可以看出,一些参数仍然存在一些不确定性。改变密集节点数量的结果差异很大。然而,学习率似乎被有效地建模了。您可以看到优化选择了大约 10e-2 的学习速率。类似地,sigmoid 激活和 adam 优化在所有生成的模型中表现最佳。

结论

当试图微调和优化计算量大的模型时,贝叶斯优化非常有用。此外,贝叶斯优化需要很少的样本,并迅速接*更优化的超参数配置,因此它是深度学习模型的理想选择。

对于神经网络和网络变体等深度学习模型,微调架构至关重要。但是,不要浪费时间手动调优您的模型。相反,使用贝叶斯优化来确定每个超参数对模型的作用。

如果你有兴趣阅读关于新颖的数据科学工具和理解机器学习算法的文章,可以考虑在 Medium 上关注我。

如果你对我的写作感兴趣,想直接支持我,请通过以下链接订阅。这个链接确保我会收到你的会员费的一部分。

https://zjwarnes.medium.com/membership

如何通过 A/B 测试优化促销回应

原文:https://towardsdatascience.com/how-to-optimize-a-promotion-response-through-a-b-testing-a1ad1f8005a3?source=collection_archive---------22-----------------------

A/B 测试已经达到必要的统计显著性,通过发送舞会门票来增加销售额。现在,通过瞄准正确的受众来优化它的潜力怎么样?

1.A/B 测试

你的一个朋友收到一张星巴克的促销券。你不知道。你会感到不安,尽管你本来就没打算用它。想知道发生了什么吗?

伊琳娜·巴比娜的照片

这很可能是该公司进行的客户细分的结果,目标是你的朋友是其中一员的一个特定群体,而你不是。 A/B 测试也可以按照这个目的进行。

当试图在一个新网站、新功能、甚至新的广告活动实际发布给更大的受众之前衡量它们的影响时,A/B 测试是常见的。这样,就有可能避免把钱花在一些不会按预期执行的战略上,甚至更糟的是,会破坏公司的形象。

简而言之,这些测试被设计为在 2 个(或更多)组上执行。考虑 2 组情况(A 和 B),一组称为对照组,另一组称为实验组。理想情况下,这两组之间唯一的区别是我们想要测试的变化

在一个网站的例子中,我们可能想改变一个按钮的设计,看看它是否能增加销售额。对照组将被分配到旧设计,而实验组将被分配到新设计

A/B 测试的另一个好处是收集数据,这些数据可以促进更好地理解与客户相关的具体特征,这些客户会对新事件做出更积极的反应。

当这个活动——送一张促销券——涉及的费用需要通过它的效果——增加销售额来弥补时,这一点尤其重要。在这种情况下,将促销券发送给正确的公众会使预期收益最优化,而将促销券发送给所有客户会导致金钱损失。

在这种情况下,A/B 测试可以回答促销活动是否会达到有效实施所需的 统计显著性 。一旦达到重要程度,就该针对目标受众进行优化了。

2.星巴克促销优化

尼尔斯·凯尔的照片

在本例中,我们使用的是星巴克的数据集,该数据集用于该公司求职者进行的技术测试。数据集已经分为训练集和测试集,它包含几个指示客户是被分配到控制组还是实验组、客户是否购买了商品的特征,以及代表客户特征的另外 7 个特征(V1 到 V7)。

训练集概览|作者图片

我们没有被告知这些特征实际上代表了什么,我们的工作是了解他们的行为,以有效地识别哪些客户更有可能对促销做出反应。

假设产品定价为 10 美元,并且公司发出每一次促销的成本为 0.15 美元,星巴克希望最佳策略能够最大化两个指标:增量响应率 ( IRR )和净增量收入 ( NIR )。

IRR 表示与未接受促销相比,通过促销购买产品的客户数量增加了多少。 NRR 代表发送促销信息会带来多少收益或损失。

为了更好地理解这一点的重要性,如果我们通过向所有客户端发送促销信息来对测试集运行一个测试函数,我们会得到以下结果:

测试结果-向所有客户端发送推广|作者图片

我们可以看到 0.0096 的 IRR 基本上是建议的 IRR 值的一半。更糟糕的是,我们会得到一个高负值的 NIR 指标,这意味着这个策略将代表金钱损失(可以通过这个 环节 按部就班的操作。)

2.1 分析特征

测试了不同的策略,以实现与之前提出的指标值相似的指标值:0.0188 的 IRR 和 189.45 的 NIR 。除非我们不深入了解这些功能,否则我们会一直给星巴克造成金钱损失。

当我们比较这些特征在不同群体中的表现时,神奇的事情发生了。在分析了控制组和实验组的https://en.wikipedia.org/wiki/Pearson_correlation_coefficientV1-V7 和购买特征之间的皮尔逊相关系数后,一些事情开始浮出水面。

重要的是要注意,计算分类数据之间的皮尔逊相关性是没有意义的,因为相关性代表“衡量”一个连续数值变量与另一个变量的行为相比是增加、减少还是保持不变。在这种情况下,一旦我们不知道这些变量意味着什么或代表什么,我们只是从不同的角度探索,看看我们是否可以获得一些见解。

例如,可以看出,在对照组(没有接受促销的那一组)中, V3 是与购买产品具有最高正相关性的特征,这意味着 V3 的较高值可能与购买产品、的较高倾向相关,而与任何促销无关。

相关矩阵-控制组|作者图片

当我们看这些相同的相关系数时,有趣的事情发生了,这次是在实验组。 V3 不仅作为最高相关值之一脱颖而出,而且这次是在相反方向上。它表明,促销活动一贯影响客户的行为时,观察这一具体特征。

相关矩阵-实验组|作者图片

在下一张图中,只选择了与控制组和实验组的购买特征相关的相关性,我们计算了它们从一组到另一组的百分比变化:****

相关系数的百分比变化|作者图片

为了更清楚,让我们观察一些特征的直方图,首先在对照组中,区分没有购买的人(红色的)和购买的人(蓝色的):**

V1-V4 直方图-对照组(红色:未购买;蓝色:已购买)|作者图片

当查看蓝色的 V3 分布时,我们可以看到与 V3 的更高价值相关的客户更有可能购买该产品,不管是否接受促销。另一个有趣的结论是, V2 似乎呈正态分布,这意味着大多数客户都与均值附*的 V2 值相关。**

让我们观察相同的直方图,这次是在实验组:

V1-V4 直方图-实验组(红色:没有购买;蓝色:已购买)|作者图片

当考虑到 V3 特性时,可以清楚地看到蓝色部分的情况是如何逆转的。它表明与 V3较低值相关的客户因促销而被鼓励购买该产品,而与 V3较高值相关的客户因促销而降低 其自然 购买率。**

如果我们想猜的话,我们可以说 V3 在某种程度上代表了参与者的收入。如果我们的猜测是正确的,我们可以说,高收入的客户倾向于定期购买产品。促销活动则相反:不仅他们可能不使用促销活动,而且他们中的一些人会停止购买该产品。

我们也可以说,由于促销,与低收入相关的客户有购买产品的动机,代表了实验组中购买者的最大比例。

根据特征分布,另一个可能的猜测是 V2 可以代表参与者的年龄。我们可以看到,一些年龄组对促销的反应更大。

2.2 建立战略

经过简短的分析和猜测,我们的策略是将这两个连续的数字变量( V2V3 )分成几个不同的类或组。

V3 分 6 组:

  • 第 1 组:低于-1.0 的值;
  • 第二组:介于-1.0 和-0.5 之间的值;
  • 第三组:介于-0.5 和 0.0 之间的值;
  • 第 4 组:0.0 到 0.5 之间的值;
  • 第 5 组:0.5 到 1.0 之间的值;
  • 第 6 组:大于 1.0 的值。

V2 也被分成不同的小组:

  • 第 1 组:小于 15 或大于 45 的值;
  • 第二组:15-25 或 35-45 之间的数值;
  • 第 3 组:数值在 25 到 35 之间。

首先,我们为每一个类分配了序列号。作为第二种方法,根据所做的分析,我们分配代表权重的值。例如,考虑到 V3 功能,组被分配到以下值:****

  • 第一组 : 5(方法 1) | 3(方法 2);
  • 第二组 : 4(方法 1) | 2(方法 2);
  • 第三组 : 3(方法 1) | 1(方法 2);
  • 第 4 组 : 2(方法 1) | -1(方法 2);
  • 第 5 组 : 1(方法 1) | -2(方法 2);
  • 第六组 : 0(接* 1) | -3(接* 2)。

V2 功能设置了相同的逻辑,首先将序列号分配给不同的组,然后在第二种方法中加权值。

加权值是在考虑特征分布的情况下定义的,接**均值的值会得到较高的“分数”(按比例更能反映促销),而远离*均值的值会得到较低的“分数”。

2.3 训练 XGBClassifier

使用序列号方法,使用 GridSearchCV 进行参数调整,训练一个 XGBClassifier 模型。所有特征 V1-V7 被用作独立变量,变换被应用于 V2V3**

结果是一个非常接*建议的优化:

测试结果-序列号|作者图片

应用加权序列号方法,同时使用同一个 XGBClassifier 结合 GridSearchCV 算法,我们得到了更好的结果:**

测试结果-加权序列号|作者图片

我们的 IRR 可以被认为等于提议的 IRR,而 NIR 指标增加了 10%以上。

在这两种情况下,模型仅使用实验组进行训练。在训练模型之前,我们使用了 SMOTE 技术来处理购买产品的群体和没有购买产品的群体之间的不*衡。**

3.结论

A/B 测试可以定义一个新事件是否应该发布,数据分析可以增加它的好处。

对于任何数据科学家来说,分析数据都是不可或缺的工具。理解业务问题,分析特性的行为方式以及它们之间的关系是获得好结果的基础。

我们能够有效优化指标的唯一方法是通过了解特性的行为以及它们可能代表什么**

不仅如此,如果我们考虑到这个练习是星巴克在选择其团队未来成员时提出的,我们可以想象这些分析技能对一家公司是多么有价值。**

在这个具体的例子中,我们能够:

  • 推断特征的含义;
  • 根据我们对功能的理解进行一些功能工程工作;
  • 针对正确的群体优化促销策略。

如果你到了这里,你就是赢家!感谢您加入我的分析之旅。

既然你可能会想到数据分析的重要性,那么刷新一些 统计概念 会对你接下来的分析有所帮助呢?**

笔记本呈现所有的分析和尝试可以在这里 看到 。完整的项目,包括数据集,可以在我的Github中找到。**

如何用 TensorFlow 优化学习速度——比你想象的要简单

原文:https://towardsdatascience.com/how-to-optimize-learning-rate-with-tensorflow-its-easier-than-you-think-164f980a7c7b?source=collection_archive---------4-----------------------

显著改进您的模型并不需要太多时间——以下是开始的方法

mahdis mousaviUnsplash 上拍摄的照片

调整神经网络模型不是闹着玩的。有如此多的超参数需要优化,使用网格搜索方法一次性优化所有这些参数可能需要几周甚至几个月的时间。学习率是一个超参数,只要你知道怎么做,你可以在几分钟内调整好。这篇文章将教你如何做。

学习率控制根据估计误差更新多少权重。选择太小的值,你的模型将永远训练,并可能卡住。选择过大的学习率,你的模型可能会在训练过程中跳过最优的一组权重。

您将需要安装 TensorFlow 2+、Numpy、Pandas、Matplotlib 和 Scikit-Learn 来跟进。

不想看书?请观看我的视频:

你可以在 GitHub 上下载源代码。

使用的数据集和数据预处理

我不打算在这里花太多时间。我们将使用与上一篇文章相同的数据集——来自 Kaggle 的葡萄酒质量数据集:

图片 1——来自 Kaggle 的葡萄酒质量数据集(图片由作者提供)

您可以使用以下代码将其导入 Python,并随机打印几行:

import os
import numpy as np
import pandas as pd
import warnings
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' 
warnings.filterwarnings('ignore')

df = pd.read_csv('data/winequalityN.csv')
df.sample(5)

我们忽略警告并更改默认的 TensorFlow 日志级别,这样我们就不会被输出淹没。

以下是数据集的外观:

图 2——葡萄酒质量数据集的随机样本(图片由作者提供)

数据集基本上是干净的,但默认情况下不是为二元分类(好酒/劣酒)而设计的。取而代之的是,葡萄酒是按等级来评定的。我们现在将解决这个问题,还有其他一些问题:

  • 删除缺失值 —它们为数不多,所以我们不会在插补上浪费时间。
  • 处理分类特征——唯一的一个是type,指示葡萄酒是白还是红。
  • 转换为二分分类任务——我们将宣布任何等级为 6 及以上的葡萄酒为,任何等级以下的为
  • 训练/测试分流——经典的 80:20 分流。
  • 缩放数据 —预测值之间的比例差异很大,因此我们将使用StandardScaler来拉*数值。

下面是完整的数据预处理代码片段:

from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

# Prepare the data
df = df.dropna()
df['is_white_wine'] = [
    1 if typ == 'white' else 0 for typ in df['type']
]
df['is_good_wine'] = [
    1 if quality >= 6 else 0 for quality in df['quality']
]
df.drop(['type', 'quality'], axis=1, inplace=True)

# Train/test split
X = df.drop('is_good_wine', axis=1)
y = df['is_good_wine']
X_train, X_test, y_train, y_test = train_test_split(
    X, y, 
    test_size=0.2, random_state=42
)

# Scaling
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

下面是前几个缩放行的样子:

图 3 —缩放的训练集(图片由作者提供)

同样,如果你想更详细地了解数据预处理背后的逻辑,请参考上一篇文章

说完这些,让我们看看如何优化学习率。

如何在 TensorFlow 中优化学习率

一旦你掌握了要点,优化学习速度就很容易了。我们的想法是从小处着手,比如说从 0.001 开始,然后在每个时期增加这个值。在训练模型时,你会得到可怕的准确性,但这是意料之中的。不要介意,因为我们只对当我们改变学习率时损失如何变化感兴趣。

让我们从导入 TensorFlow 并设置种子开始,这样您就可以重现结果:

import tensorflow as tf
tf.random.set_seed(42)

我们将训练 100 个时期的模型,以测试 100 种不同的损失/学习率组合。学习率值的范围如下:

图片 4-学习率值的范围(图片由作者提供)

比如说,0.001 的学习率是 Adam optimizer 的默认学习率,2.15 显然太大了。

接下来,让我们定义一个神经网络模型架构,编译该模型,并对其进行训练。这里唯一的新东西是LearningRateScheduler。它允许我们输入上面声明的方法来改变学习率作为一个 lambda 函数。

下面是完整的代码:

initial_model = tf.keras.Sequential([
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dense(256, activation='relu'),
    tf.keras.layers.Dense(256, activation='relu'),
    tf.keras.layers.Dense(1, activation='sigmoid')
])

initial_model.compile(
    loss=tf.keras.losses.binary_crossentropy,
    optimizer=tf.keras.optimizers.Adam(),
    metrics=[
        tf.keras.metrics.BinaryAccuracy(name='accuracy')
    ]
)

initial_history = initial_model.fit(
    X_train_scaled,
    y_train,
    epochs=100,
    **callbacks=[
        tf.keras.callbacks.LearningRateScheduler(
            lambda epoch: 1e-3 * 10 ** (epoch / 30)
        )
    ]**
)

训练将从现在开始,你会立即看到一个相当不错的准确率——大约 75%——但在 50 多岁之后,它会下降,因为学习率变得太大了。经过 100 个时代后,initial_model有了大约 60%的准确率:

图 5 —初始模型训练日志(图片由作者提供)

initial_history变量现在有关于损失、准确性和学习率的信息。让我们把它们都标出来:

import matplotlib.pyplot as plt
from matplotlib import rcParams
rcParams['figure.figsize'] = (18, 8)
rcParams['axes.spines.top'] = False
rcParams['axes.spines.right'] = False 

plt.plot(
    np.arange(1, 101), 
    initial_history.history['loss'], 
    label='Loss', lw=3
)
plt.plot(
    np.arange(1, 101), 
    initial_history.history['accuracy'], 
    label='Accuracy', lw=3
)
plt.plot(
    np.arange(1, 101), 
    initial_history.history['lr'], 
    label='Learning rate', color='#000', lw=3, linestyle='--'
)
plt.title('Evaluation metrics', size=20)
plt.xlabel('Epoch', size=14)
plt.legend();

这是图表:

图 6——损失与准确性和学习速度(图片由作者提供)

在开始进一步下降之前,精确度在时期 50 左右显著下降并*坦了一段时间。loss 发生了完全相反的情况,这是有道理的。

现在,您可以用对数标度绘制损失与学习率的关系图,显示损失最小的位置:

learning_rates = 1e-3 * (10 ** (np.arange(100) / 30))
plt.semilogx(
    learning_rates, 
    initial_history.history['loss'], 
    lw=3, color='#000'
)
plt.title('Learning rate vs. loss', size=20)
plt.xlabel('Learning rate', size=14)
plt.ylabel('Loss', size=14);

这是图表:

图 7——学习率与损失(作者图片)

一般来说,你会希望选择一个学习率来实现最低的损失,前提是它周围的值不会太不稳定。请记住,X 轴是对数刻度。最佳学习率在 0.007 左右:

图 8——最佳学习率(图片由作者提供)

因此,让我们用一个假定的最佳学习率来训练一个模型,看看我们是否能胜过默认的学习率。

以最佳学习速率训练模型

考虑到学习率为 0.007,我们再写一个神经网络模型。这次你不需要LearningRateScheduler:

model_optimized = tf.keras.Sequential([
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dense(256, activation='relu'),
    tf.keras.layers.Dense(256, activation='relu'),
    tf.keras.layers.Dense(1, activation='sigmoid')
])

model_optimized.compile(
    loss=tf.keras.losses.binary_crossentropy,
    optimizer=tf.keras.optimizers.Adam(learning_rate=0.007),
    metrics=[
        tf.keras.metrics.BinaryAccuracy(name='accuracy')
    ]
)

history_optimized = model_optimized.fit(
    X_train_scaled,
    y_train,
    epochs=100
)

上一篇文章中,我们用默认的学习率得到了 76%的准确率,所以看看学习率优化是否能提高它会很有趣。训练集上报告的准确性看起来好得令人难以置信,因此我们的模型很可能过度拟合:

图 9-优化的模型训练日志(图片由作者提供)

如果我们成功地提高了测试集的性能,这不会有太大的影响,但是您可以通过为更少的时期训练模型来节省一些时间。

下面是优化模型的精度与损耗的关系:

plt.plot(
    np.arange(1, 101), 
    history_optimized.history['loss'], 
    label='Loss', lw=3
)
plt.plot(
    np.arange(1, 101), 
    history_optimized.history['accuracy'], 
    label='Accuracy', lw=3
)
plt.title('Accuracy vs. Loss per epoch', size=20)
plt.xlabel('Epoch', size=14)
plt.legend()

图 10 —训练集的准确度与损失(图片由作者提供)

让我们最后计算预测,并根据测试集对它们进行评估。代码如下:

from sklearn.metrics import confusion_matrix
from sklearn.metrics import accuracy_score

predictions = model_optimized.predict(X_test_scaled)
prediction_classes = [1 if prob > 0.5 else 0 for prob in np.ravel(predictions)]

print(f'Accuracy on the test set: 
    {accuracy_score(y_test, prediction_classes):.2f}')
print()
print('Confusion matrix:')
print(confusion_matrix(y_test, prediction_classes))

这是输出结果:

图 11 —测试集评估指标(作者图片)

总之,仅优化学习率就设法在测试集上将模型准确度提高了 3%。这听起来可能不大,但对于所花的时间来说,这是一个很好的权衡。此外,这只是你可以对神经网络模型进行的许多优化中的第一步,它是你需要担心的一个更少的超参数。

请继续关注学习如何优化神经网络架构——帖子将在几天后发布。感谢阅读!

喜欢这篇文章吗?成为 中等会员 继续无限制学习。如果你使用下面的链接,我会收到你的一部分会员费,不需要你额外付费。

https://medium.com/@radecicdario/membership

保持联系

如何优化您的 Switchback A/B 测试配置

原文:https://towardsdatascience.com/how-to-optimize-your-switchback-a-b-test-configuration-791a28bee678?source=collection_archive---------16-----------------------

思想和理论

确定转回实验的最有效随机化点的算法。

2021 年 1 月,麻省理工学院和哈佛大学的研究人员开发了一篇论文,概述了优化分析和设计转回实验的理论框架。转回实验,也称为时间分割实验,采用对照/处理的顺序重排来消除某些数据固有的偏差。这些方法在双边市场中很流行,如优步和 Lyft,因为它们允许用有限的资源(司机、乘客等)对数据进行稳健的实验。).

论文中概述的算法利用了我们关于遗留效应(补充有限资源所需的时间)的知识,以最小化我们实验的方差。虽然该方法确实需要求解算法,如 minimax,但优化是在实验运行之前完成的,因此计算开销很低。

图 1:具有 30 分钟时间分割的 switchback 测试框架——图片由作者提供。

下面是该方法的工作原理…

0。技术 TLDR

0.1 确定结转影响订单的持续时间。遗留效应的顺序是在未来可以观察到治疗效果的时间段数。拼车市场的一个例子是司机可以再次乘车的时间间隔。

0.2 编码使风险函数最小化。下面我们有一个函数,当最小化时,它将为我们指定的残留效应顺序( m )和实验长度( K )提供最佳随机化点。

图 2:当最小化时,将产生具有最小方差的最佳随机化点的表达式— (等式 8)

0.3 制定优化的控制/处理顺序。使用求解器解决上述最小化问题。

0.4 运行实验并分析。在我们开发出最佳随机化配置并运行实验后,我们可以照常进行分析。唯一的区别是我们需要利用 bootstrap 风格的算法来确定我们的 p 值,这将在下面讨论。

1.但是,到底是怎么回事呢?

好了,让我们慢一点,为这个方法培养一些直觉。

1.1 我们何时使用转回实验?

当我们的用户群存在结构性偏差时,转回实验是最有用的。这些结构性偏见通常以共享有限资源或用户之间复杂交互的形式出现。

以数据科学家的自由职业网站为例。这是一个双边市场,意味着供求概念适用于自由职业者和雇主。如果我们运行一种治疗方法,帮助雇主找到具有机器学习(ML)技能的数据科学家,数据科学家的人才库将会枯竭,从而影响对照组中数据科学家的数量。我们还可以说,我们的兴趣指标是为 ML 工作(即转换)签署的合同数量。由于数据科学家的供应有限,我们的控制将会看到转化率的下降,这将高估我们的治疗效果。

如果处理影响了共享的资源池,控制组将受到影响,从而使我们的实验无效。

那么,我们怎么能相信治疗提升是我们 ML 功能成功的准确衡量标准呢?

1.2 转回实验的定义

转回实验(也称为时间分割实验)解决了这个问题。它们是 A/B 测试框架,100%的流量在处理和控制之间交替。

图 3:连续随机化期间的图解——作者提供的图片。

如图 3 所示,每 30 分钟我们随机抽取用户组 A 中的所有用户进行控制或治疗。这种方法可以应用于任何数量的处理实验。

现在,每个时间分割的持续时间是相当任意的,但是指导原则是持续时间应该足够短,以显示对我们数据的有效洞察,但不要短到计算成为问题。 Doordash 使用 30 分钟的窗口。

最后,为了测量我们的实验寿命,我们简单地取所有时间段的治疗寿命的*均值。请注意,更复杂的 lift 测量将用户在给定的时间戳视为随机化单元,但这超出了本文的范围。

1.3 更好的方法

虽然上面的简单转回实验框架有效,但它对可以持续很长时间的治疗效果不是很鲁棒,所以哈佛和麻省理工学院的研究人员开发了一种更好的方法。我们不是简单地在每个时间段进行随机化,而是利用关于遗留效应的知识来设计最佳配置。

首先,什么是结转效应?从我们上面的自由职业者的例子来看,当一个自由职业者被雇佣时,当他们完成项目时,他们会被从候选人名单中删除一段时间。候选人重新进入人才库所需的时间就是我们的延续时间

通常结转持续时间被表示为它所覆盖的时间分割数的倍数;这个值称为我们的结转效应顺序 ,用字母 m 表示。因此,对于 2 小时的结转持续时间,如果我们的时间间隔是 30 分钟,那么 m = 4。

第二,我们必须了解什么是好的/坏的配置。主要目标是开发一个随机化框架,该框架创建适当数量的 m+1 序列,用于公正控制或公正处理。从连续的一系列 m 处理中,我们可以观察到残留效应的混杂。相反,如果一行中有 m+1 个质控品,我们将“重置”我们的遗留物,并观察不受遗留物影响的处理。

我们的目标是在我们的用户群中交替我们的控制/治疗,以最小化我们的实验所产生的混淆。

酷毙了。准备好面对巨大的方程式了吗?

图 4:我们寻求最小化的表达式,以开发最佳随机化点。图 2 的副本— 来源(等式 8)

在图 4 中,

  • K 代表我们实验中的总时间周期数,
  • t_k 是第 k 个随机化指标,并且
  • m 是我们的结转效果订单。

这种最小化的输出将是随机化点的向量T **(T-star)。因此,例如,对于一个总时间分割为 K=12 且结转效应顺序为 m=2 的实验,我们会看到最优输出为 T={1,5,7,9}* 。这里,**表示我们在第 1、第 5、第 7 和第 9 时间间隔重组我们的对照组/治疗组。对于所有其他时间分割,我们不会重新调整我们的控制/治疗。

图 5 是一个表格,直观地表示了与任意设计相比的上述最佳设计。顶行是我们优化的框架,底行是任意的设计。最后,X 对应于一个随机点;如果有一个 X,我们就重新安排控制/治疗。

图 5:最佳配置(上排)和随机设计的折返(下排)的论文示例— 来源(表 1)

一个简单的技术提示——最小化是根据我们配置的风险函数改编的,并且对应于我们的升力的方差。我们越是最小化函数,我们观察到的方差就越低,我们对治疗效果的估计就变得越好。

论文中的数学非常酷,而且有据可查,所以如果你好奇,可以看看论文的第三部分。

1.4 方法背后的直觉

现在我们已经了解了发生了什么,让我们来了解一下它为什么会起作用。对于这一部分,让我们在索引 F={1,6,7,8,9} 处尝试随机化点。 t_n 对应我们的 F 向量的第 n 个索引,所以比如 t_0 = 1t_4 = 9

图 6:最小化表达式最左边的总和— 来源(等式 8)

从最左边的求和开始(图 6),我们可以看到,随着顺序随机化指数之间的差异变大,该项也会变大。

为了充分披露,让我们快速算出一个例子。如果 k = 0t_0 = 1t_(0+1) = 6 。两者相差 5,比较大;我们被罚了 25 个单位。对所有指数求和,我们的惩罚项是 112。

图 7:最小化表达式的第二左求和— 来源(等式 8)

接下来,让我们处理第二项(图 7)。该表达式来自论文中的引理 2,其陈述了第一个和最后一个随机化点都应该跟随有 m 个非随机化时间分割。如果随机化来得太早或太晚,我们都会受到惩罚。

用我们的向量处理这个表达式,表达式的值是 128。目前为止我们看起来不太好。

图 8:最小化表达式最右边的总和— (等式 8)

忽略下面两项,它们是数学上的假象,没有什么可解释的价值,让我们把注意力集中在最右边的求和上(图 8)。这个术语代表连续随机化点之间的间隙;如果在重新洗牌之间有太多的时间,我们会被扣分。请注意,()⁺只是我们的数字和 0 的最大值,即 max(x,0)

这一项的值为 16,如果我们将所有的值相加,包括我们在上一段中忽略的值,我们得到 112 + 128 + 192 - 16 + 16 = 432。

这就是我们的方法。很简单,对吧?

现在,我们所要做的就是使用一个解算器来找到使图 4 中的表达式最小化的随机化路径。

2.推理

有了第 1 节中确定的优化配置,不幸的是,我们不能使用传统的方法来评估我们的治疗成功,因为我们在随机化中引入了结构偏倚。

有两种建议的方法用于从以这种方式构造的实验中得出推论。第一个提供了一个“精确”的估计,第二个提供了一个渐*上限。

2.1 精确方法

确切的方法允许我们测试一个尖锐的零假设,即我们观察不到任何时间分割的影响。请参见下面的 pythonic 伪代码,了解这些步骤的概要…

*sampled_lifts = []# 0\. Calcualte lift using the Horvitz-Thompson esimtator for our full data
total_lift = hv_estimator(observed_assignment_path, observed_ys)# 1\. Iterate through a large number of samples
for i in range(num_samples): # 2\. Sample a new assignment path (w) according to the assignment mechanism
  w = sampled_assigment_path(dist)

  # 3\. estimate our lift (lift) using the Horvitz-Thompson esimtator
  lift = hv_estimator(w, observed_vals)
  lifts.append(lift)# 4\. Calcualte p_value as the proprtion of samples that have higher lift than the total_lift
p_val = avg(abs(lifts) > abs(lift))# 5\. Examine values of interest
print(total_lift, p_val)*

如果你不是伪代码的粉丝,英文版是我们从我们观察到的实验升力中反复取样,以获得其他理论升力的许多估计。请注意,这些样本必须遵循实验中使用的相同模式,即它们必须具有相同的随机化点。还要注意,理论升力是用霍洛维兹-汤普森估计量计算的,即每次升力的加权估计。

利用所有这些样本,我们观察它们比我们的真实生活更极端的时间比例。这个比例就是我们的 p 值。

2.2 渐*法

第二种方法使用我们的 Horovitz-Thompson 方差来计算 t 统计量。不幸的是,方差计算和证明相当冗长,所以它们被省略了,但是请随意查看论文的第 4 部分以获得关于这两种方法的完整注释。

相反,我们将只关注性能。渐*估计比精确方法更保守,然而它们对大升力表现出相似的性能。你选择哪种方法将由你的需要决定。

现在你知道了。最佳切回实验的从头至尾框架。

实施说明

  • 如果您错误地指定了遗留效应的顺序 m ,统计推断仍然有效。
  • 本文第 7.2 节概述了一种系统地确定 m 的方法。注意,这种方法需要实验数据。
  • 当选择时间分割周期的长度时,长度小于 m 很重要,这样结转效应可以表示为几个时间分割的倍数。然而,过小的时间分割会毫无理由地增加计算量。一个经验法则是(分裂数/ m) > 100* 并且偏于高估 m.*
  • 虽然扩展到一个多种治疗的框架没有在这篇文章中讨论,但是相同的随机化点将适用于任何数量的治疗的实验。

感谢阅读!我将再写 48 篇文章,将“学术”研究引入 DS 行业。查看评论中关于优化转回实验的链接/想法。

如何组织和开展远程数据科学实习

原文:https://towardsdatascience.com/how-to-organize-and-run-remote-data-science-internships-fb51ce21715?source=collection_archive---------33-----------------------

办公时间

照片由在 Unsplash 上拍摄

我们是一个科学家团队,研究生物数据分析的计算方法。我们的重点领域之一是将机器学习方法应用于基因组数据。今年,我们迎来了几位机器学习相关项目的实习生。由于疫情,我们不得不远程运行这些实习。然而,远程实习一点也不差,如果设置得当,甚至还有一些优势。远程工作的可能性为我们提供了一个更大的人才库,最终,我们有幸与来自 6 个国家的非常有才华的实习生一起工作。实习生都有机器学习相关的项目。一些人非常专注于与我们的 Arcas AI *台相关的深度学习项目,一些人专注于经典的机器学习方法,解决我们在实验室中工作的各种问题。下面是我们如何组织这些远程实习项目的总结,以及我们在这个过程中学到了什么。

1.提出结构良好的项目

这些项目应该足够小和容易,以便他们可以在几个月内完成。我们选择了与实验室中的一些深度学习或经典机器学习项目相关的项目。这些项目通常但不仅仅依赖于基因组数据,并具有临床应用。大多数任务都围绕着修改我们现有的方法来改进我们准备的基准数据集。

实际上,我们还提供了笔记本电脑,展示可能需要的常见数据管理任务的基本功能。此外,我们还设定了目标和实现这些目标的时间表。我们还做出了一个有意识的决定,即在项目过程中,所有代码都应该频繁地提交到我们的 GitHub 库,并使用基于 GitHub 的工作流进行代码开发。

2.选择具备适当技能的适当人员

由于项目是明确定义的,完成它们所需的技能是显而易见的。对于深度学习项目,我们需要深度学习经验,对于其他经典的机器学习项目,我们需要相关的经验。很难检查人们是否有最低要求的经验,所以只要可行,我们就向申请人发送数据分析挑战。最起码,我们要了一个 GitHub 的 URL 或者让他们给我们发相关的编码项目,来检验他们的经验水*。此外,我们有一个结构化的现场采访过程,我们试图通过一些问题来衡量他们的水*,例如:“你对实施论文中描述的方法感到舒服吗?”或者让他们用 PyTorch 或者 TensorFlow 之类的某个框架来描述自己的体验。

在所有的项目中,有版本控制系统的经验,最好是 git,是候选人想要的特征。然而,在某些情况下,我们放松了要求,这并没有很好地发挥作用。为这些项目分配的一些时间被用于学习 Git,这导致了时间的损失,而这些时间本可以用于改进项目的可交付性。给未来自己的提示:确保人们可以使用 Git。

3.提供预配置云计算环境

这是顺利开始的必要条件。我们使用 AWS SageMaker 为实习生提供云计算环境,但任何类似的东西都可以。实习生还可以访问一份关于云环境设置的“如何开始”文档,以及一个笔记本,该笔记本提供了如何在基因组数据集上使用我们基于深度学习的方法毛伊岛的教程。

有时我们没有提供这一功能,由于设置和测试本地计算环境花费了大量时间,这些项目需要更长时间才能启动。创建云计算环境对所有未来的远程实习项目至关重要。

4.组织一次介绍会

如果你有多个相关项目的实习生,把每个人互相介绍给对方总是一个好主意。如果你有太多的实习生,这可以被分成基于项目的实习生群。然而,10 人以下的小组在 zoom 上很容易管理,每个人都可以介绍自己,更重要的是,一般的项目结构和简短的入职培训可以通过这些介绍性会议来完成。

5.提供一个联系点和监督

我们组织实习的方式是,每个实习生都有一个从高级实验室成员中选出的直接主管。这些直接主管是日常联络点,提供急需的支持,尤其是在早期阶段。他们还定期与实习生会面,监督他们的进展,并在需要时提供帮助。

6.保持简单而有规律的交流

我们选择加入 slack 是为了有一个简单的沟通渠道。任何类似 slack 的作品,我们只是选择了它,因为我们已经在使用它。我们为一些较大的实习项目创建了一个特殊的工作空间。拥有一个专用的聊天应用程序可以方便地联系到主管。我们还在 Slack 不够快或者书面沟通不理想的情况下举行视频通话。有时打电话比在 slack 或其他地方写问题更快。此外,很多时候实习生集体想出了如何通过使用 slack 来解决问题,特别是如果是由于设置或您提供的数据而导致的一般问题。你不必提供所有的指导。如果实习生有一个交流的*台,他们也可以互相指导。

7.传达可交付成果和里程碑,保持高昂的积极性。

我们有目标和实现这些目标的最后期限,这些都传达给了实习生。对于较小的每周目标,最后期限要么由直接主管和实习生决定。或者它们与联席会议有关,在联席会议上必须介绍总体进展情况,这一点我们将在下面谈到。

截止日期等。可能会产生一些达到目标的压力。然而,它们提供的动力有限。我们看到实习生偶尔会失去动力,尤其是当任务看起来很复杂,或者当他们无法将任务与更大的目标联系起来时。 我们发现,对此最好的补救办法是反复解释“为什么”,即使没有直接问 。我们需要提醒实习生为什么他们所做的工作是重要的,以及这项工作的更大意义。在我们的重点领域,这并不十分困难。几乎我们所做的一切都与改进的诊断或对基因组生物学的更好理解有关,这可能会开辟新的领域或应用。这些含义以及它们如何与实习生的任务联系起来,应该清楚地定期交流。

8.召开联席会议,由所有实习生介绍进展和障碍

我们为所有参与相关项目的实习生举行了联席会议。通过这种方式,实习生可以更好地相互了解,并在会议期间相互学习。我们要求实习生展示他们的进展和障碍,这样我们就可以共同解决障碍并庆祝进展。展示结果的需要也为实习生思考和总结他们的工作创造了额外的动力。

9.调整你的期望。不管你做什么,不是每个人都能有效率

事情不会总是顺利的。尽管你尽了最大的努力去创建结构化的项目并挑选最有前途的实习生,一些实习生还是无法完成工作。虽然我们很幸运,大多数实习生都达到了他们的里程碑,但承认再多的筛选和计划也无法预见不可预见的事件,如医疗紧急情况或其他健康或家庭问题,这些都会影响生产力。

如何使用自适应 Softmax 层克服大词汇量瓶颈

原文:https://towardsdatascience.com/how-to-overcome-the-large-vocabulary-bottleneck-using-an-adaptive-softmax-layer-e965a534493d?source=collection_archive---------21-----------------------

理解大数据

一个简单的 GPU 优化层替换如何提供 2-10 倍的加速,而性能几乎没有损失的详细指南

Wolfgang HasselmannUnsplash 上拍摄的照片。像这只骆驼适应沙漠一样适应你的 softmax!

本文的目的是解释和提供自适应 softmax 的 TensorFlow 2.0+实现,如参考文献[1] ( 链接)所述:

只需将您的 softmax 切换到自适应 softmax,您就可以在训练和推理中轻松实现 2-10 倍的加速。在开始之前,这里是我们将要做的事情的概述:

  1. 大词汇量=瓶颈。我们分析了在大型词汇表上使用常规 softmax 的相关问题。
  2. 我们调查这个问题的其他解决方案,然后解释自适应 softmax 如何解决这些其他方法的缺点。
  3. 我们深入研究实际的实现细节。
  4. 我们以准备运行代码和实现建议结束。

对于 TensorFlow 2.0+中的实现,请在此和帖子底部查看以下链接

我们开始吧!

为什么大词汇量这么成问题?

语言模型的最终输出层通常是全连接的密集层,将最终隐藏层与词汇表中每个单词的概率联系起来。这是一个密集层,所以很明显,它是密集的,意味着它有很多参数。具体来说,让最终隐藏层的形状为 (B,d) (认为 B 为批量,d 为尺寸)。对于词汇大小 V ,最终的密集层+softmax 将是形状 (d,V)。对于 100k 令牌和隐藏维度 2048 的词汇表来说,仅在最后一层就有*十亿个参数。因为矩阵乘法在最坏的情况下是 O(BdV) 这需要大量的计算时间。

存在许多解决这个问题的方案。对于一些任务,可以简单地修改损失函数,以避免需要每个单词的输出概率。分层 softmax [2,3]就是这样一种方法。不是单独预测每个词汇,而是预测树中的节点(通常是二进制的)。通过降低树来恢复单个单词的概率,这减少了从 O(V) →O(ln V) 的计算。然而,这些方案没有考虑到它们的层次划分的实际计算成本。

另一类解决方案涉及采样方法[4,5,6]。当我们执行交叉熵损失时,我们实际上只关心预测指数的概率。我们可以通过抓取预期单词的概率,然后将其与其他一堆随机选择的单词的概率进行比较,来估算损失(称为负采样)。这样,我们不需要执行完整的输出计算。然而,在推理时,我们仍然需要做一个完整的 softmax,这可能会很慢。

最后,还有自归一化解决方案,其目的是学习一个输出概率分布,即归一化,从而避免计算所有输出概率然后归一化的需要。

介绍自适应 Softmax

adaptive softmax 是一种基于类的分层 softmax,旨在满足和解决上述所有方法的局限性。它是围绕实际 GPU 的矩阵乘法计算时间构建的。

在一个 CPU 上,我们可以运行一个快速的计时实验来确认最终密集层的时间复杂度与词汇量 V 成正比。

来源:现作者。矩阵乘法线性缩放。

在 GPU 上,时间复杂度稍微复杂一点。

第一部分(时间复杂度):

参考文献[1]的作者声称,运行矩阵乘法符合时间复杂度等式:

这是𝑔(𝑘函数的定义;𝐵).这里,当线性增加开始时,k0 是一些阈值参数(k0 大约是 50),并且批量大小 B 被视为参数而不是变量。主要观点:时间增加在词汇量上还是线性的。

第二部分(实际方法):

这是我们降低复杂性的方法。在开始之前,我们不仅要有语料库的词汇,还要有单字概率(我们有点不精确,但是这里假设单词和单字是同一个东西)。计算这些超出了本文的范围,但是,一个简单的解决方案是使用最大似然估计;统计每个单词的出现次数,并将其单字概率与频率相等。

这样一来,我们现在将词汇表分成 J+1 个簇

每个尺寸:

注意,这些簇的大小不同(即,不包含相同数量的单词)。我们现在执行以下操作:

  1. 按照大小递增的顺序对集群进行排序(例如 20、40、80、160 等)。
  2. 将整个词汇从最频繁到最不频繁排序(例如['the ',' of ',' a ',…,' platypus'])。
  3. V 拆分成大小为 k_0,…,k_J 的簇,规定为 k_0+…+k_J = V

预测步骤:这个想法是我们有一些目标数,比如说代表单词 w_m 的目标数。记住,我们是为了避免计算一个( dV )密集层的 softmax 惩罚。

我们试图预测的单词被称为标签。

因此,我们所做的是:如果标签在头簇 V_0 中,我们简单地使用密集层+softmax of size ( dk_0+J )直接计算它的概率,其中 m th 条目给出了我们的答案。由于最频繁出现的元素在第一个 bin 中,这在大多数情况下都会发生,我们已经将 softmax 输出大小从( dV )减少到( dk_0+J )!

隐藏→头部连接的图示如下:

来源:现作者。最终隐藏层到头部连接的图示。头集群字用蓝色表示,集群节点用绿色表示。有 k_0+J 个单词(蓝色方块),和 J 个集群节点(绿色方块)。每个聚类节点表示隐藏层表示该聚类中的单词的概率(即,它是 k_i 个可能单词中的一个)。

好吧,如果标签不在头簇里呢?嗯,这就是为什么我们添加了 J 输出到头集群。这些代表了概率 p(V_1| hidden) ,…, p(V_J | hidden) 我们的隐藏状态代表一个单词在 J 其他聚类中的一个。

我们现在可以描述如何计算不在头簇中的标签的概率。首先,我们仍然需要计算头簇上的 softmax。由此,我们提取标签的聚类的概率。接下来,我们在标签的聚类上计算 softmax,以获得其在其聚类内的概率。最后,总概率是乘积p(w _ m | V _ j)p(V _ j | hidden)我们的隐藏状态既属于正确的簇,又与那个簇中的正确单词相关联。

TLDR 计算单词在头簇中的概率,以及单词属于尾簇的概率。单词在尾部聚类中的概率是其仅在该聚类上的 softmax 乘以其开始时在该聚类中的概率(这从头部 softmax 中已知)。

我们仍然没有那么有效率。我们还能做一件事。这些额外的集群很少使用,我们不需要给它们很多参数(即大矩阵,即高容量),因为我们不期望它们需要适合复杂的模式。例如,一个更常见的单词如单词“where”被大量使用,并且可以基于上下文具有许多语法意义,因此我们预计它比像“platypus”这样很少使用的单词需要更复杂的隐藏状态。因此,让我们通过如下的投影步骤来减小输入到生僻字中的隐藏层的大小(见下图):

来源:现作者。投影过程的一个示例,用于减少表示不常见标记的聚类的输入维数。

对于每一个 J 尾簇,不要喂它完整的 d 维隐藏状态。相反,应用投影矩阵 P 使得新的隐藏状态h’= hP具有降低的维度。这是通过应用密集层来实现的,缩减系数通常是~4 倍,即dim h’=dim h/4。

第三部分(超参数):

上述排序和聚类方法可以作为减少 GPU 计算时间的最佳解决方案。我们跳过细节,展示如何使用部分推导来修正超参数 k_i

首先,我们根据经验修正 J 。论文注意到在 2 和 5 之间使用 J

有了固定的 J ,我们就可以通过动态规划来确定最优的 k_i 。目标是最小化成本

受制于概率约束

这里, p_{V_j} 是第 i 个字的簇 jp_i 的概率(记住,是假设我们知道这个概率。见第二部分),以及那个星团的大小。

第 IVa 部分(实施):

首先,我们讨论动态规划算法。我们希望找到一种最佳的方法来沿着一个长度为 V 的序列放置 k 个切割(单词按一元概率排序)。

  • 将所有的 p_i 从最大到最小排序(应该已经是了)。
  • 假设我们知道对由第一个 i 元素组成的数组进行 J 切割的最优成本和位置。将这些信息存储在字典 d[J]_i 中。现在,使用cost =**d[J+1]_ I = d[J]_ I+cost _ { V-I },搜索 cut J+1 的所有可能插入。也就是说,成本是将所有 J 个切削放在 I 之前的成本加上在位置 i. 的第( J+1) 个切削的成本之和

该算法将在 O(JV )* 时间内运行,这很慢,但嘿,你只需要运行一次。

代码如下:

第 IVb 部分(张量流):

该过程如下:

  • 建立密集层来计算头簇单词概率加上尾簇节点概率。
  • 对于这些尾部聚类中的每一个,为 1)低维投影和 2)聚类词概率定义密集层。
  • 直接计算损失函数(这是一种加速,因为我们不需要计算所有的逻辑)。首先,计算头部集群对数概率(我们需要使用对数概率来保证数值的稳定性),并保存一个“头部概率”数组,该数组表示输入位于头部集群中的概率,或者输入的尾部集群的概率。
  • 对于每个尾簇,执行以下操作:
  • a)如果需要,用其尾部聚类概率替换“头部概率”数组中的输入。
  • b)计算尾部聚类概率(如果输入不属于所选的尾部聚类,则为零)。
  • 最后,将尾簇概率加到头簇概率,以形成最终的输出分布。现在你可以像往常一样计算交叉熵损失了!

结论、提示和技巧:

在本文中,我们引入了 adapative softmax 作为大词汇量瓶颈问题的解决方案。瓶颈是网络的最终密集层的结果,它通常将一个较小的隐藏维度层映射到一个更大的层,该隐藏维度层的数量级为 O(10 ) ,其维度 V 由词汇大小给出,可以是 V ~ O(10⁵).最终的密集层既计算量大,又占用大量内存。

自适应 softmax 只是许多技术中的一种,这些技术旨在解决与通常的 softmax 相关联的计算和存储成本。与基于采样的方法、损失函数修改或自归一化层等现有技术相比,adaptive softmax 具有以下优势:

  1. 它是常规 softmax 的即插即用替代品。人们可以简单地用自适应的来替换最终的 softmax。
  2. 训练和推断之间没有矛盾。推理步骤的计算方式与训练步骤相同。
  3. 它针对计算成本进行了优化,特别是在 GPU 方面。
  4. 您可以调整参数以缩小正常的、未调整的 softmax,直到找到计算速度和模型精度的*衡。
  5. 您可以轻松获得 2-10 倍的速度提升,几乎不需要修改,性能几乎不会下降。

调整自适应 softmax 也相对简单,因为您只需要担心调整两个参数。这些是:

  1. 集群数量—2–5 之间的任何数量都足够了。超过这个数目就会导致收益递减。您应该根据您认为属于每个聚类的单词所需的准确度来选择数字。尾部较重的分布可能需要更多的聚类。
  2. 投影尺寸——我们建议设置一个投影因子,而不是手动设置投影尺寸。每个新集群减少 4 是一个很好的缺省值。同样,根据您认为隐藏层需要多大来保存最终 softmax 所需的信息来选择这些尺寸。在一个 512 维的向量中,10 个类可以很容易地唯一编码,但是 10⁶类可能很困难。*衡在于决定你愿意容忍的罕见类的不准确性水*。

有关完整的实现,请参见以下内容:

https://github.com/Jmkernes/PAR-Transformer-XL/blob/main/adaptive_softmax.py

谢谢,祝适应愉快!

*我们感谢 https://github.com/yangsaiyong/tf-adaptive-softmax-lstm-lm的奇妙仓库给我们带来的灵感。

参考

[1] Joulin,Armand,et al .GPU 的高效 softmax *似。机器学习国际会议。PMLR,2017。http://proceedings.mlr.press/v70/grave17a/grave17a.pdf

[2]莫兰、弗雷德里克、约舒阿·本吉奥。分层概率神经网络语言模型。ais stats。第五卷。2005.

[3] Goodman,Joshua T. 语言建模方面的一点进展。计算机语音&语言,2001b。

[4]米科洛夫、托马斯、陈、凯、科拉多、格雷格和迪安、杰弗里。向量空间中单词表示的有效估计。arXiv 预印本 arXiv:1301.3781,2013。

[5]纪、、维什瓦纳坦、、萨迪什、纳达图尔、安德森、迈克尔 J 和杜贝、。Blackout: 加速词汇量非常大的递归神经网络语言模型。 arXiv 预印本 arXiv:1511.06909,2015

[6] Jozefowicz,Rafal,Vinyals,Oriol,Schuster,Mike,Shazeer,Noam,以及吴,永辉.探索语言建模的极限。 arXiv 预印本 arXiv:1602.02410,2016

[7] Gutmann,Michael 和 Hyvarinen,Aapo。噪声对比估计:非规范化统计模型的一种新的估计原理。2010 年人工智能与统计国际会议。

[8] Mnih,Andriy 和 Teh,Yee Whye。一种快速简单的神经概率语言模型训练算法。 arXiv 预印本 arXiv:1206.6426,2012 年。

[9] Vaswani,Ashish,赵,Yinggong,Fossum,Victoria,和 Chiang,David .用大规模神经语言模型解码提高翻译。EMNLP,2013 年。

如何使用 SAS Studio 轻松地在地图上叠加数据

原文:https://towardsdatascience.com/how-to-overlay-data-on-maps-easily-using-sas-studio-3b85de998e5e?source=collection_archive---------29-----------------------

SAS Studio 中的地图非常简单

动机

每年,我的许多朋友都会问我最安全的纽约区,在那里他们可以为他们的孩子租一个地方。许多学生来纽约参加暑期培训或工作。我住在纽约,但不是纽约市。因此,我总是去寻找数据来回答这个问题,并在我的书《使用 SAS Studio学习数据科学》中添加了这个过程,该书于 2020 年由 Apress 出版。

地图

在地图上显示数据增加了新的视角。它可以自己讲述整个故事。SAS Studio 使在地图上显示数据变得容易。此外,使用颜色和气泡自定义地图会为您的数据添加新的维度。本节将使用现实生活中的数据引导您完成这一过程。它将逐步向您展示如何下载数据并准备在地图上显示。

气泡图

气泡图任务创建一个覆盖有气泡图的地图。对于这个例子,我们将使用纽约市的犯罪数据来创建一个气泡图,显示 2018 年纽约市不同行政区的犯罪率。这些数据可通过纽约市开放数据项目网站获得。

您将在“数据集”文件夹中找到该数据文件;文件命名为 NYPD _ 投诉 _ 数据 _ 当前 _ _ 年度 _ 截止日期. csv,或者,您可以从以下网址下载数据集:https://Data . cityofnewyork . us/Public-Safety/NYPD-投诉-数据-当前年度至今-/5uac-w243/data [1]。

要从链接下载数据集,如图 1 所示,单击 Export,然后单击 CSV。

图 1:符合 NYPD 标准的数据——NYC open Data(图片由作者提供)

数据集包含大量信息。利用这些数据可以进行大量的调查和分析。例如,每个区最普遍的犯罪类型是什么?犯罪最有可能发生的时间是什么时候?大多数犯罪发生在一周的哪一天?

对于这个例子,我们只对回答哪个区的犯罪率最高和哪个区的犯罪率最低感兴趣。要回答这个问题,我们需要以下三列:行政区、经度和纬度。因此,我们删除了所有其他列。然后,我们计算每个区的犯罪数量,用地图上的气泡来表示。

在清理和准备数据之后,我们得到了下表所示的数据集。

表:每个区的犯罪数量

行政区|犯罪数量|纬度|经度

布朗克斯| 50153 | 40.82452 | -73.8978

布鲁克林| 67489 | 40.82166 | -73.9189

曼哈顿| 56691 | 40.71332 | -73.9829

皇后区| 44137 | 40.74701 | -73.7936

斯塔滕岛| 10285 | 40.63204 | -74.1222

为了加载数据,我们在 SAS Studio 中编写清单 1。

清单 1:为每个区的犯罪数量创建数据集

data NYC_crime;
input Borough $13.;
datalines;
BRONX
BROOKLYN
MANHATTAN
QUEENS
STATEN ISLAND
;
run;data NYC_crime_dim;
set nyc_crime;
input count Latitude Longitude;
datalines;
50153 40.82451851 -73.897849
67489 40.82166423 -73.91885603
56691 40.71332365 -73.98288902
44137 40.74701026 -73.79358825
10285 40.63203653 -74.1222402
;
run;

在这个程序中,我们没有导入原始数据文件。我们在数据步骤中使用 DATALINES 关键字将表的值插入到代码中。在清单 1 中,我们有两个数据步骤。第一个叫 NYC_crime。第二行使用 INPUT 语句指定列的名称和类型。在这个表中,我们只定义了一列作为区名,它的类型是 character,因为我们使用了$。最大字符数为 13。然后,我们使用 DATALINES 语句插入实际值,并以分号结束。

第二个数据步骤创建另一个名为 NYC_crime_dim 的表,在每个表中插入行政区的维度和犯罪数量。该表由前面的表 nyc_crime 使用 SET 语句初始化。同样,我们使用 INPUT 语句来指定我们应该向 borough 中再添加三列。我们添加计数、纬度和经度。记住在列名之间留一个空格,不要使用逗号。同样,使用数据行插入实际值,并以分号结束。

运行清单 1 后,将在工作库中创建两个名为 NYC_crime 和 NYC_crime_dim 的新表。要查看输出表,请单击库➤工作;在它下面,你会找到 NYC_crime 和 NYC_crime_dim。如果没有,请刷新您的库。

现在,点击任务和工具➤任务➤地图➤气泡图,如图 2 所示。

图 2:创建气泡图(图片由作者提供)

如图 2 所示,选择数据集工作。数据字段中的 NYC_CRIME_DIM。在角色中,选择纬度和经度。在气泡大小中,选择计数,即犯罪的数量。最后,在“组”中,选择“区”列。

图 3:每个区的犯罪数量(图片由作者提供)

对于基本地图,选择 OpenStreetMap。在本章的后面,我们将尝试 Esri maps 来查看输出中的差异。保留其余的默认值,然后单击 Run。将显示图 4 中的气泡图。

图 4:每个区的犯罪数量(图片由作者提供)

从泡沫大小可以清楚地看出,布鲁克林的犯罪率最高,而斯塔滕岛的犯罪率最低。SAS Studio 会自动调整气泡的位置、大小和颜色。此外,它还在地图底部添加了一个图例,用于表示行政区的颜色代码。

现在,让我们增强气泡图的外观。我们可以给带有犯罪数量的气泡添加一个标签,并给地图添加一个标题。如图 5 所示,在 Appearance 选项卡的 Data Labels 中,从 Bubble label 的数据集中选择 count 列。然后,在“标签选项”中,选择“粗体”作为“字体粗细”。在标签位置,选择“居中”。最后,在标题和脚注中,输入“纽约市行政区的犯罪数量”

图 5:增强外观(图片由作者提供)

单击运行以检查新的更改。输出如图 6 所示。

图 6:纽约市各区的犯罪数量(图片由作者提供)

清单 2 显示了 SAS Studio 通过用户界面从我们的选项中自动生成的代码。

清单 2:为每个区的犯罪数量创建数据集

ods graphics / reset width=6.4in height=4.8in;
proc sgmap plotdata=WORK.NYC_CRIME_DIM;
openstreetmap;
title ‘Number of crimes in NYC Boroughs’;
bubble x=Longitude y=Latitude size=count/ group=Borough datalabel=count
datalabelpos=center
datalabelattrs = (color=CX0f0e0e size=7pt weight=bold)
name=”bubblePlot”;
keylegend “bubblePlot” / title = ‘Borough’ ;
run;
ods graphics / reset;
title;

SAS Studio 功能强大,因为它提供了两种类型的底图:OpenStreetMap 和 Esri maps。现在,让我们尝试另一种底图类型。如图 3–48 所示,返回数据选项卡,选择 Esri maps,然后单击运行。输出图如图 7 所示。

图 7:使用 Esri maps 的地图(图片由作者提供)

SAS Studio 将为这个 Esri 地图选项生成清单 3 中的代码。

清单 3:使用 Esri Map 生成地图

ods graphics / reset width=6.4in height=4.8in;
proc sgmap plotdata=WORK.NYC_CRIME_DIM;
esrimap url= ‘http://server.arcgisonline.com/arcgis/rest/services/
World_Street_Map/MapServer’;
title ‘Number of crimes in NYC Boroughs’;
bubble x=Longitude y=Latitude size=count / group=Borough
datalabel=count datalabelpos=center
datalabelattrs=(color=CX0f0e0e size=7pt weight=bold)
name=”bubblePlot”;
keylegend “bubblePlot” / title =’Borough’;
run;
ods graphics / reset;
title;

结论

如您所见,通过输入 SAS studio clean 数据集,您可以在地图上叠加数据,而无需编写任何代码。事实上,SAS Studio 会生成代码供您编辑,这太棒了。如果你试图用其他编程语言来完成同样的任务,那将会令人望而生畏。我强烈推荐数据科学新手使用 SAS Studio。

参考

[1] NYPD 投诉数据当前,https://Data . cityofnewyork . us/Public-Safety/NYPD-Complaint-Data-Current-Year-Date-/5uac-w243/Data,NYC 开放数据项目。(条款:【https://www1.nyc.gov/home/terms-of-use.page】T2)

如何在高分辨率地图上叠加多边形形状

原文:https://towardsdatascience.com/how-to-overlay-shapefile-data-on-pygmt-maps-3a2d84550780?source=collection_archive---------13-----------------------

我们将学习如何在 PyGMT 地图上使用 geopandas 绘制选定的 shapefile 数据。

Python 中的 PyGMT 库使绘制高分辨率地形图变得轻而易举。它带有海岸线、国界和地形数据。通常,我们需要使用可用的 shapefile (SHP)数据在地图上高亮显示任意选择的多边形形状或区域。

https://www.earthinversion.com/utilities/pygmt-high-resolution-topographic-map-in-python/

安德鲁·斯图特斯曼在 Unsplash 上的照片

在本帖中,我们将看到如何使用 geopandas 库将 shapefile 数据叠加在 PyGMT 地图上。例如,在这里,我获得了。来自data.gov.tw的 shp 格式,并叠加在台湾的高分辨率地图上。

导入库

我们将使用 geopandas 库来读取。shp 文件。

import pygmt
import os
import geopandas as gpd

shp数据

我从各县下载了shp数据,并将其保存在countiesData的工作目录中。countiesData中有多个文件,但我们只需要COUNTY_MOI_1090820.shp文件。其他的都是相关的扩展文件。

我们选择了两个县在地图上突出显示——台北市和台南市。

countiesShp = os.path.join("countiesData","COUNTY_MOI_1090820.shp")gdf = gpd.read_file(countiesShp)all_data = []
all_data.append(gdf[gdf["COUNTYENG"]=="Taipei City"])
all_data.append(gdf[gdf["COUNTYENG"]=="Tainan City"])

使用 PyGMT 绘制底图

现在,我们可以使用 PyGMT 绘制简单的底图。使用 PyGMT 的好处是我们不需要单独的海岸线和地形数据,并且输出是高分辨率的。

region = [119, 123, 21, 26]fig = pygmt.Figure()
fig.basemap(region=region, projection="M4i", frame=True)fig.coast( 
    water='skyblue', 
    shorelines=True)

覆盖各县

现在,我们可以覆盖所选的县,用绿色填充它们,然后用背景色(白色)填充所有其他的县。

for data_shp in all_data:
    fig.plot(data=data_shp,color="green")
fig.plot(data=countiesShp)

以栅格和矢量格式保存地图

现在,我们可以保存地图的光栅和矢量格式供以后使用。

fig.savefig('map1.png')
fig.savefig('map1.pdf')

简单的台湾县地图(图片由作者提供)

地形图

我们可以使用地形背景,而不是使用简单的白色作为背景(顺便说一句,我觉得这看起来很不错):

import pygmt
import os
import geopandas as gpdcountiesShp = os.path.join("countiesData","COUNTY_MOI_1090820.shp")gdf = gpd.read_file(countiesShp)all_data = []
all_data.append(gdf[gdf["COUNTYENG"]=="Taipei City"])
all_data.append(gdf[gdf["COUNTYENG"]=="Tainan City"])region = [119, 123, 21, 26]fig = pygmt.Figure()
fig.basemap(region=region, projection="M4i", frame=True)
fig.grdimage("[@srtm_relief_03s](http://twitter.com/srtm_relief_03s)", shading=True, cmap='geo')fig.coast( 
    water='skyblue', 
    shorelines=True)for data_shp in all_data:
    fig.plot(data=data_shp,color="white", pen=["0.02c", 'white'])
fig.plot(data=countiesShp, pen=["0.02c", 'white'])fig.savefig('map1.png')
fig.savefig('map1.pdf')

台湾各县地形图(图片由作者提供)

结论

我们已经看到了如何轻松地将 shapefile 数据添加到 PyGMT 地图上。我们在台湾的底图上绘制了各县的数据。此外,我们创建了一个覆盖了 shapefile 数据的高分辨率地形图。

https://www.earthinversion.com/utilities/how-to-overlay-shapefiles-on-pygmt-maps/

原载于 2021 年 7 月 17 日【https://www.earthinversion.com】

如何打包您的 Python 代码

原文:https://towardsdatascience.com/how-to-package-your-python-code-df5a7739ab2e?source=collection_archive---------0-----------------------

了解 Python 代码应该如何为 PyPI 打包

不法分子在 Unsplash 上抓拍的照片

Python 最强大的特性是它的社区。几乎每个用例都有一个专门为它构建的包。

需要发送手机/电子邮件提醒?pip install knockknock —构建 ML 应用?pip install streamlit —厌倦了你的终端?pip install colorama——太简单了!

我知道这是显而易见的,但那些库并没有神奇地出现。对于每一个包,都有一个人,或者许多人,积极地开发和部署这个包。

每一个都是。

全部 30 万以上。

这就是 Python 之所以是 Python 的原因,它的支持程度是惊人的— 令人兴奋

在本文中,我们将学习如何构建我们自己的包。并将它们添加到 Python 包索引(PyPI)中。之后,我们将能够使用pip install来安装我们的软件包!让我们开始吧。

建什么?

第一步是弄清楚我们应该建造什么。一旦我们有了想法,就去 PyPI 搜索相同的包,它存在吗?如果是的话,你的想法有什么新的或更好的吗?

一旦我们得到了一些独特的东西,我们需要再次检查我们的包名是否已经被占用。

在本文中,我们将构建一个名为aesthetic_ascii的包——它将产生随机的受 synthwave 启发的 ASCII 艺术。这是一个相当独特的想法,尽管可能不太有用。

目录设置

我们需要创建一个新的目录来包含我们的包,并作为我们的包名( aesthetic_ascii )。

在这个目录中,我们有我们的__init__.py文件,它将我们的目录初始化为一个 Python 模块——并成为该模块的顶层脚本。

我们可以通过在包目录中添加子目录并在这些子目录中添加__init__.py文件来添加子模块。

比如我们知道可以写from os import path。其目录结构如下所示:

os/
    LICENSE
    MANIFEST.in
    pyproject.toml
    README.md
    setup.cfg
    ...
    os/
        __init__.py
        ...
        path/
            __init.py__
            ...

我们很快会谈到这里的其他文件。但首先,我们需要了解__init__.py实际上在做什么。

init。巴拉圭

在其核心__init__.py,将一个目录标记为一个 Python 包。因此,我们包含了顶层的__init__.py文件,它将目录标记为我们的“包”。

然后我们将实际的代码文件(或模块)放在我们的__init__.py文件旁边。所以,如果我们有这样的结构:

**aesthetic_ascii/**
    *all config files*
 **aesthetic_ascii/**
        __init__.py
        synthesize.py

安装包后,我们将像这样导入synthesize模块:

from aesthetic_ascii import synthesize

我们将在整篇文章中使用这种结构。

配置文件

setup.cfg

除了代码文件,我们还需要几个配置文件。配置我们的包最重要的是setup.cfg文件。

这个文件很关键,它是我们的设置配置文件。在pip install期间,这个文件告诉 pip 如何安装我们的包。

为了声明我们正在使用 setuptools 来打包我们的项目,我们首先在我们的顶层目录中创建一个pyproject.toml文件,包含:

然后我们创建我们的setup.cfg文件。对于审美 _ascii ,看起来是这样的:

这里发生了很多事情,但是每一项都很有描述性,所以我不会一一描述,但是有几项不太清楚。

  • long_description —参数名告诉我们这是什么,我们可以在这里提供不同的文件格式。尽管许多软件包坚持降价,这也是我们将要使用的——正如long _ description _ content _ type中所指定的。
  • 分类器——PyPI 将用来对我们的包进行分类的一组标识符,我们可以在这里找到有效分类器的完整列表
  • —我们的包运行所需的依赖包列表。
  • python_requires —对库的 python 版本要求。
  • include _ package _ data——是否包含MANIFEST.in中定义的附加文件——稍后将详细介绍。

许可证

接下来是我们的许可证,这是软件包中非常重要的一部分——即使你不关心谁在使用它,他们为什么使用它,以及他们是否从中赚钱。

我们包含了一个许可证来消除软件包用户的任何疑虑。选择许可证非常简单,只需从这里复制并粘贴最合适的文本即可——并且记得更新任何自定义部分!

README.md

这个文件充当我们的包的long_description——我们在setup.cfg文件中设置了这个包。

此外,回到我们的setup.cfg——我们在long_description_content_type中指定了我们将使用一个text/markdown文件——因此,我们使用一个降价文本文件!

添加资源

我们已经设置了配置文件,但是我们缺少一样东西——我们的图像将在生成随机 ASCII 图片时使用。

这些图像可以是我们的包所依赖的任何类型的文件。从 Python 3.7 开始,我们通过使用importlib.resources模块来处理这个问题。

首先,我们需要将它导入到我们的代码中,并更新读取这些文件的代码部分,以使用importlib.resources:

这两个函数的第一个参数指的是存储文件的目录。此外,任何资源必须存储在包含__init__.py文件的目录中。

因此,在我们的例子中,我们需要将所有图像文件存储在aesthetic_ascii 子目录中:

审美 _ ascii/审美 _ascii 目录包括我们所有的图像文件和字体文件,以及 init。pysynthese . py模块

一旦一切就绪,我们必须确保我们的图像文件将包含在包中——我们通过MANIFEST.in文件来完成:

然后我们确保MANIFEST.in文件被添加到setup.cfg:

...
[options]
include_package_data = True
...

我们准备好了!

本地安装

在将我们的包上传到 PyPI 之前,我们可以确认我们的包可以通过pip install安装,方法是导航到我们的包目录并输入:

pip install .

这应该会像通过pip安装任何其他软件包一样安装我们的软件包:

本地 pip 安装的屏幕截图。测试

然后,我们可以像对待任何其他产品一样import包装我们的产品:

现已安装的 aesthetic_ascii 包的用法示例

建设

一旦我们编写了代码文件、设置了配置并测试了安装——我们就准备好构建我们的包发行版了。

构建过程创建了一个新目录dist,其中包含一个.tar.gz.whl文件——这是我们将包发布到 PyPI 所需要的。

为了构建我们的dist文件,我们创造性地使用了一个名为build的工具。首先,我们pip install build,然后,在我们的包目录中键入:

python -m build

一旦完成,我们应该在我们的包目录中找到一个新的/dist目录。

发布到 TestPyPI

最后,我们准备好发布我们的新 Python 包了!同样,我们使用另一个名为twine的包。我们安装该软件时使用了:

pip install twine

安装完成后,我们上传到TestPyPI——一个 PyPI 的“测试”版本,这样我们可以再次检查我们是否已经正确设置了所有内容。我们通过键入以下命令来实现:

python -m twine upload --repository testpypi dist/*

此时,我们需要登录 TestPyPI——如果您没有帐户,请在这里注册一个。如果一切设置正确,我们的包将被上传:

测试 PyPI 上审美 _ascii 的成功上传过程

现在,我们可以通过另一个pip install来测试我们的新包是否工作——但是这次是通过 TestPyPI:

pip install -i https://test.pypi.org/simple/ aesthetic-ascii

(如果发现包已经安装好了——就pip uninstall aesthetic-ascii)。

通过 TestPyPI 安装美学-ascii

PyPI

一旦我们确认这个包可以工作,我们就要进行最后一步,发布到 PyPI。同样,你需要在这里注册。

接下来,我们将我们的包上传到 PyPI,包含:

python -m twine upload --repository pypi dist/*

上传我们的包到 PyPI

我们完事了。

这是我们的第一个 Python 包部署——出乎意料的简单。我们可以继续和pip install aesthetic_ascii使用这个包。

我们的一些 ascii 杰作

包括设置/配置文件的完整代码可以在 GitHub 这里找到。

我希望你喜欢这篇文章。如果你有任何问题或建议,请通过推特或在下面的评论中告诉我。如果你对更多类似的内容感兴趣,我也会在 YouTube 上发布。

感谢阅读!

进一步阅读

如何打包你的 Python 代码,Python 打包

[打包项目](/*All images are by the author except where stated otherwise),Python 打包

风筝,把任何图像变成 ASCII 艺术!(易 Python PIL 教程),YouTube

页(page 的缩写)伯克,灰度图像的字符表示 (1997),paulbourke.net

🤖《变形金刚》NLP 课程 70%的折扣

*除另有说明外,所有图片均出自作者之手

如何使用 Pytest 参数化 Python 测试

原文:https://towardsdatascience.com/how-to-parameterize-python-tests-using-pytest-e8800bf288c5?source=collection_archive---------2-----------------------

向夹具和测试函数传递参数

Joshua Lawrence 在 Unsplash 上拍摄的照片

给不耐烦的人:

  1. 如何对 Pytest 夹具进行参数化
  2. 如何使用 Pytest 对测试函数进行参数化

介绍

软件开发的一个固有挑战是随着功能和范围的增长,保持对代码库的控制。一个软件变得越复杂,这种复杂性失控的威胁就越大。

自动化测试套件可以帮助开发人员处理这种复杂性。随着代码库的增长、发展和成熟,测试套件也在增长、发展和成熟,但是如何确保测试本身也是可管理的呢?

对 python 开发人员来说幸运的是,pytest 提供了重用测试函数和作为测试例程的一部分创建的对象的机制,这有助于保持所有测试逻辑的组织性和可维护性。

激励的例子

我正在开发一个实现单变量多项式的类,这是一个项和的数学表达式,其中每一项都是一个常数乘以变量的非负幂。

举个例子,

4x - 2x

是一个多项式表达式。这个多项式可以被建模为一个列表,其中每个元素是一个项,每个项本身是一个具有系数和指数的列表。上述多项式可以用以下方式建模:

[[4,3],[-2,1]]

使用我的多项式类,我可以通过以下方式创建相应的多项式对象:

随着多项式类功能的增加,我需要测试它。多项式的一个特征是指数是非负整数,所以我将编写一个测试来检查指数是否满足该条件。多项式的导数也是多项式,所以我也应该检查那些指数。此外,如果指数最大的系数是负的,那么我的多项式的字符串表示必须有一个前导负号,所以需要检查一下。

现在对于以上的 poly,我有 3 个测试:

  1. 所有指数都是非负整数吗?
  2. 导数的所有指数都是非负整数吗?
  3. 如果指数最高的项的系数为负,字符串表示是否有前导负号?

这里有一种非常直接的方式来编写这些测试:

这让我可以用那些特定的项来测试多项式对象的功能,但是如果我想用不同的项来测试一个多项式,那么我必须编写一个新的测试。

这可能适用于极少数的对象和边缘案例,但是随着更多的对象需要测试,每个对象需要检查更多的测试案例,它将很快变得势不可挡。

如何使用 Pytest 夹具

Fixtures 是返回可以被多个测试访问的对象的函数。在 fixture 函数上方用@pytest.fixture() decorator 声明一个 fixture。然后,将 fixture 函数名作为一个参数放入测试函数的定义中,测试函数现在可以使用 fixture,而无需显式实例化它返回的对象。使用 fixture,我可以如下重构我的测试:

现在,我想添加的任何测试函数都可以访问同一个多项式,测试本身只有测试所需的逻辑。理所应当!

不幸的是,我认为我定义的单个多项式不足以真正测试我的字符串表示。它甚至不需要前导负号。我可以添加另一个装置,但是我必须为每个装置添加测试:

如何参数化 Pytest 夹具

@pytest.fixture decorator 允许您向 fixture 传递一个参数列表。对于每一个请求这个 fixture 的测试,这个测试会为这个 fixture 的每一个参数化版本运行一次。例如:

现在,我可以简单地向 TERMS_LIST 添加额外的多项式项列表,每个请求 poly fixture 的测试将使用 TERMS_LIST 中每组项的多项式对象运行一次。

如果测试失败,pytest 将让您知道哪些参数导致了失败的测试:

上面的“test_str_leading_minus[poly0]”指的是 TERMS_LIST 中参数在 0 索引处的 poly fixture。

另一个激励的例子

正如我上面写的,多项式必须有非负指数。当我为我的多项式类实现接口时,我决定如果一个多项式试图用无效的指数创建,我要抛出一个异常。我可以尝试创建一个带有无效术语列表的参数化 fixture,

但这是行不通的!fixture 将尝试创建一个新的多项式对象,如果希望接口引发异常,那么任何引用该 fixture 的测试都不会完成。测试会因为异常而失败,但是失败是预期的结果,所以测试应该通过。那我该怎么办呢?

如何使用 Pytest 对测试函数进行参数化

@ py test . mark . parameterize()decorator 允许您独立于您创建的 fixtures 来参数化测试函数的参数。现在,我可以传递一个无效参数列表,并使用 pytest.raises(AssertionError)断言无效术语会导致预期的异常。

现在,只有当无效术语在对象初始化期间导致断言错误时,测试才会通过。此外,如果有我想定义为无效的其他术语列表,我可以简单地将它们添加到 INVALID_TERMS_LIST 中,而无需编写另一个测试。

摘要

您可以在 fixture decorator 中使用 params 关键字参数将参数传递给 fixture,也可以使用@ py test . mark . parameter ize decorator 将参数传递给单独测试的测试。

编码快乐!

如何使用 Python 解释文本

原文:https://towardsdatascience.com/how-to-paraphrase-text-using-python-73b40a8b7e66?source=collection_archive---------5-----------------------

envato elementsalexdndz 使用图像创建(经许可)。

数据科学 | 机器学习

使用人工智能进行内容创作的循序渐进教程

作为作家,我们经常寻找工具来帮助我们变得更有效率或更有成果。Grammarly 之类的工具可以帮助语言编辑。文本生成工具可以帮助快速生成原始内容,只需给人工智能一些关键字想法即可。

也许这可以帮助结束作家的阻滞?这是一个有争议的问题,最好留待以后解决。

转述内容也是另一种获取现有内容(无论是你自己的还是别人的)并加入你自己观点的好方法。如果我们可以自动解释文本,那不是很好吗?

在本文中,您将学习如何使用PARROT库在 Python 中免费套用文本。特别是,在引擎盖下,PARROT 的解释技术基于 T5 算法(文本到文本转换转换器的首字母缩写),该算法最初由 Google 开发(有关更多信息,请参考代码为的论文中的 T5 资源)。在高层次上,文本生成是自然语言处理(NLP)令人兴奋的领域的利基领域,当向普通观众解释时,通常被称为人工智能或 AI。

需要注意的是,一个附带的 YouTube 视频( 如何使用 PARROT 库套用 Python 中的文本(Ft。肯吉))此文如下所示。

如何使用 PARROT 库(Ft。肯吉)

1.推出 Google Colab 笔记本电脑

我们将使用 Google Colab 在云上执行文本解释,这是 Jupyter 笔记本的在线版本,允许您在云上运行 Python 代码。如果你是 Google Colab 的新手,你会想在入门笔记本中温习一下基础知识。

  1. 登录你的 Gmail 账户,然后进入 Google Colab
  2. 首先转到File > Open Notebook,然后点击Upload选项卡(最右边),启动教程笔记本。
  3. 在搜索框中输入dataprofessor/parrot
  4. 点击parrot.ipynb文件

加载鹦鹉教程笔记本截图。

2.安装 PARROT 库

PARROT 库可以通过 pip 安装,方法是在 code 单元格中键入以下内容:

! pip install git+[https://github.com/PrithivirajDamodaran/Parrot.git](https://github.com/PrithivirajDamodaran/Parrot.git)

库安装需要一点时间。

显示 PARROT Python 库安装的屏幕截图。

3.导入库

这里,我们将导入由parrottorchwarnings组成的 3 个 Python 库。您可以将以下内容键入(或复制粘贴)到代码单元格中,然后通过按下CTRL + Enter按钮(Windows 和 Linux)或CMD + Enter按钮(Mac OSX)来运行它。或者,也可以通过单击代码单元格左侧的播放按钮来运行代码单元格。

from parrot import Parrot
import torch
import warnings
warnings.filterwarnings("ignore")

允许代码单元运行的 play 按钮的屏幕截图。

parrot库包含预训练的文本解释模型,我们将使用它来执行解释任务。

在引擎盖下,预先训练的文本解释模型是使用 PyTorch ( torch)创建的,因此我们在这里导入它以便运行该模型。这款机型名为[parrot_paraphraser_on_T5](https://huggingface.co/prithivida/parrot_paraphraser_on_T5/tree/main),在抱脸网站上列出了。需要注意的是,拥抱脸是开发托管parrot_paraphraser_on_T5模型的transformer库的公司。

正如代码所暗示的,出现的警告将通过warnings库被忽略。

4.文本释义的再现性

为了允许文本释义的再现性,将设置随机种子号。这样做的目的是对相同的种子号产生相同的结果(即使重新运行多次)。

要为再现性设置随机种子数,请在代码单元格中输入以下代码块:

**def** random_state(seed):
  torch.manual_seed(seed)
  **if** torch.cuda.is_available():
    torch.cuda.manual_seed_all(seed)

random_state(1234)

5.加载文本解释模型

我们现在将加载并初始化 PARROT 模型,方法是在一个代码单元中输入以下内容并运行该单元。

parrot = Parrot(model_tag="prithivida/parrot_paraphraser_on_T5", use_gpu=False)

模型将按如下所示加载:

初始化模型的屏幕截图。

6.输入文本

本例中的输入文本What’s the most delicious papayas?将被分配给phrases变量,我们一会儿就会用到它。

要找到这个问题的答案,请务必观看随附的 YouTube 视频( 如何使用 PARROT 库在 Python 中解释文本(Ft。肯吉))。

phrases = ["What's the most delicious papayas?"]

7.生成释义文本

现在,到了使用 PARROT T5 模型生成释义文本的有趣部分。

7.1.代码

将以下代码块输入到代码单元格中,并运行该单元格。

for phrase in phrases:
  print("-"*100)
  print("Input_phrase: ", phrase)
  print("-"*100)
  para_phrases = parrot.augment(input_phrase=phrase)
  for para_phrase in para_phrases:
   print(para_phrase)

7.2.逐行解释

这里,我们将使用一个for循环来遍历phrases变量中的所有句子(在上面的例子中,我们只给这个变量分配了一个句子或一个短语)。

对于phrases变量中的每个phrase:

  • 打印 100 次-字符。
  • 打印"Input phrase: ",后跟被迭代的phrase的返回输出。
  • -字符打印 100 次。
  • 使用parrot.augment()函数执行解释,该函数将被迭代的phrase作为输入参数。生成的释义被分配给para_phrases变量。
  • para_phrases变量执行嵌套的for循环:
    —打印从para_phrases变量返回的重复输出,这些重复已经迭代生成(4 个重复的文本,我们将很快在下一节中看到)。

7.3.代码输出

此代码块生成以下输出:

在这里,我们可以看到 PARROT 产生了 4 个释义文本,您可以选择其中的任何一个进行进一步的使用。

8.下一步是什么?

恭喜你,你可以成功地使用人工智能产生转述文本!

如果你有兴趣更进一步的话。

这里有一些项目想法,您可以尝试并构建来扩展您自己的项目组合。说到投资组合,你可以从我最*写的这篇文章中免费学习如何建立一个投资组合网站:

[## 如何免费建立一个简单的作品集网站

towardsdatascience.com](/how-to-build-a-simple-portfolio-website-for-free-f49327675fd9)

项目创意 1

创建一个 Colab/Jupyter 笔记本,通过创建一个可以接受多个短语作为输入的版本来扩展这个示例(为单个输入短语生成解释文本)。例如,我们可以将一个由几个短语组成的段落分配给一个输入变量,然后代码使用它来生成解释文本。然后,对于每个短语的返回输出,随机选择单个输出来表示每个短语(即,每个输入短语将相应地具有 1 个释义文本)。把转述的短语组合成一个新段落。比较原始段落和新的转述段落。

项目创意 2

使用Streamlit(也可以查看 Streamlit 教程播放列表)或PyWebIO)将项目想法 1 扩展成一个 web 应用程序。特别是,web 应用程序会将一段短语作为输入,并应用代码来生成释义文本,并将它们作为输出返回到 web 应用程序的主面板中。

分享你的创作

我很想看看你的一些作品,所以请随意把它们贴在评论区。快乐创作!

信用

本文中使用的代码改编自 Parrot 创建者 Prithiviraj Damodaran 提供的示例。

订阅我的邮件列表,获取我在数据科学方面的最佳更新(偶尔还有免费内容)!

关于我

我是泰国一所研究型大学的生物信息学副教授和数据挖掘和生物医学信息学负责人。在我下班后的时间里,我是一名 YouTuber(又名数据教授)制作关于数据科学的在线视频。在我做的所有教程视频中,我也在 GitHub 上分享 Jupyter 笔记本(数据教授 GitHub 页面)。

https://www.youtube.com/dataprofessor

在社交网络上与我联系

YouTube:【http://YouTube . com/data proper/
网站:【http://data proper . org/【正在建设】
LinkedIn:【https://www . LinkedIn . com/company/data proper/

如何使用 Python 和 Selenium 解析数据

原文:https://towardsdatascience.com/how-to-parse-data-using-python-and-selenium-907a95239ee0?source=collection_archive---------14-----------------------

使用分页从网站解析数据

博伊图梅洛·菲特拉Unsplash 上的照片

以前我谈到过硒以及如何在 Ruby 中使用它。今天,我将向您展示如何在 Python 中使用 Selenium。如果你想了解硒的基本知识,可以看看下面的帖子。在那篇文章中,我简要介绍了什么是硒以及我们何时可以使用它。

通过这篇文章,您将了解如何使用 Python、Selenium 和 ChromeDriver 解析一些数据。

设置

对于这个设置,我们需要安装一个 Python ChromeDriver 。另外,确保你的机器上安装了 Python 。我用的是 macOS。您可以使用以下命令快速检查您运行的 Python 版本。

python --version

在我的例子中,我运行的是 Python 版本 3.8.8。现在,在您的终端中运行以下命令。这里我们使用pip(Python 的包安装程序)来安装这个包。

pip install selenium

安装 Selenium 之后,我们需要安装 ChromeDriver。我正在用自制软件安装驱动程序。

brew install chromedriver

如果您在驱动程序方面遇到任何问题,以下是 macOS 的一些基本故障诊断步骤。

解决纷争

  1. 无法打开 Chromedriver,因为无法验证开发者。
open /opt/homebrew/Caskroom/chromedriver

首先,在 finder 中打开 chromedriver 文件夹。之后,右键点击 chromedriver 文件,选择打开。这应该可以解决问题。

2.该版本 ChromeDriver 仅支持 Chrome 版本#当前浏览器版本为二进制路径的#

我们需要确保 ChromeDriver 和 Chrome 浏览器的版本是相同的。

brew upgrade --cask chromedriver

太好了,我们完成了初始设置。现在你可以从 GitHub 下载 Python 脚本。让我们来分解一下web_scraper.py文件的各个组成部分。

web_scraper.py

首先,我们添加了一个headless选项。然后我们用选项初始化一个 Chrome webdirver。现在,我们沿着页码导航 URL。之后,我们使用find_elements_by_class_name方法从页面中提取所有元素,最后,我们遍历所有元素,使用 find_element_by_class_name方法提取单个元素。现在,我们可以将页码增加 1,并重复相同的过程,直到没有数据需要解析。你可以从这里阅读所有可用的 WebDriver API。

如果你不提供headless选项,它将打开一个 chrome 浏览器并运行剩下的代码。如果这是您想要的行为,删除第 23、24 行,并修改第 25 行,如下所示。

driver = webdriver.Chrome()

我希望这篇文章能帮助你开始使用 Python、Selenium 和 ChromeDriver。如果你访问 toscrape 网站,你可以找到不同的浏览数据的方法。例如,我们可以使用无限滚动分页,而不是使用分页来导航页面。如果你有兴趣学习 Python,那么可以在 GitHub上查看我的 Python cheatsheet。编码快乐!

相关帖子

如何使用 Ruby 和 Selenium 解析数据

原文:https://towardsdatascience.com/how-to-parse-data-using-ruby-and-selenium-5cf11605340c?source=collection_archive---------19-----------------------

了解硒的基础知识

国立癌症研究所Unsplash 上拍摄的照片

人工测试可能效率低下且容易出错。但是,它可以通过自动化消除。Selenium 是一个自动化测试的开源自动化工具。例如,我们可以用它来测试 web 应用程序。

在本文中,我们将使用 Selenium ( RubyChrome 来解析数据。我们将使用一个名为selenium-webdriver的 ruby gem,它为 Selenium 和 ChromeDriver 提供 ruby 绑定来使用 Chrome web 浏览器。Selenium 拥有对 C#、Python、JavaScript 和 Java 的支持。而且支持的*台有 Firefox,Internet Explorer,Safari,Opera,Chrome,Edge。

设置

首先,我们需要安装一个 ruby gem 和 ChromeDriver。对于这个设置,我使用的是 macOS。如果你的机器上没有安装 Ruby,那么从这里获取。

在您的终端中运行以下命令。

gem install selenium-webdriver

现在,在您的终端中运行以下命令来安装 ChromeDriver。在这里,我使用自制软件来安装驱动程序。

brew install chromedriver

如果你在初始设置时遇到任何问题,看看我的 GitHub 或者使用错误信息来解决问题。好了,我们可以走了。你可以从 GitHub 下载以下代码。让我们来分解一下web_scraper.rb文件的各个成分。在这篇文章中,我们将从名为 toscrape 的网站收集数据。这是一个网页抓取沙盒。

首先,我们用一个无头的 chrome 浏览器初始化我们的 selenium WebDriver。

def init_selenium_webdriver
 options = Selenium::WebDriver::Chrome::Options.new
 options.add_argument('--headless')
 return Selenium::WebDriver.for :chrome, options: options
end

现在,我们有了将用来解析数据的 URL。这里,我们从第一页开始。在循环内部,我们使用驱动程序、URL 和页码来导航网页。

def main
 driver = init_selenium_webdriver
 url = "http://quotes.toscrape.com/page/"
 page_no = 1
 loop do
  navigate(driver, url, page_no)
  data = get_data(driver, {class_name: 'quote'})
  parse_data(data, {text: {class_name: 'text'}, author: {class_name: 'author'}})
  page_no += 1
  break unless has_data?(data)
 end
 driver.quit
end

navigate方法中,我们使用基本 URL 和页码构建最终的 URL。

def navigate(driver, url, page_no)
 driver.navigate.to URI.join(url, page_no.to_s)
end

我们使用get_data方法从navigate方法返回的数据中提取报价。find_elements方法将返回所有匹配给定参数的元素。

def get_data(driver, pattern)
 return driver.find_elements(pattern)
end

之后,我们遍历所有报价,使用parse_data方法在控制台中打印单个报价信息。find_element方法将返回匹配给定参数的第一个元素。你可以在这里阅读更多相关信息

def parse_data(data, pattern)
 data.each do |quote|
  text = quote.find_element(pattern[:text]).text
  author = quote.find_element(pattern[:author]).text
  puts "#{text} -- #{author}"
 end
end

完成此步骤后,我们将页码增加 1,并对页码 2 重复此过程。最后,我们将增加页码,直到没有需要解析的引号。

def has_data?(data)
 return data.size() > 0
end

太棒了,现在您知道如何使用 Selenium 解析数据了。继续尝试使用不同的导航技术解析数据,比如滚动。我希望你从这篇文章中学到了一些新的东西。如果你有兴趣了解 Ruby,那么可以在 GitHub 上查看我的 Ruby Cheatsheet。编码快乐!

看看我关于 Ruby 的其他帖子

</17-useful-ruby-string-methods-to-clean-and-format-your-data-9c9147ff87b9>

如何通过面试的数据展示部分

原文:https://towardsdatascience.com/how-to-pass-the-data-presentation-part-of-interviewing-e6b2e4274444?source=collection_archive---------8-----------------------

有时候越简单越好

杰森·古德曼在 Unsplash 上的照片

可怕的数据展示。这通常是面试过程中的一部分,候选人要么大放异彩,要么自掘坟墓。

一些候选人一旦发现他们实际上需要做一些分析并展示他们的发现,就会完全退出。你想让我做几个小时的工作!?你怎么敢问?

我个人认为这是过程中最能说明问题的部分。

首先,你可以看到有人愿意付出多少努力在你的数据中发现一些有趣的模式。

第二,它证明了候选人可以创造性地思考,并实际做好该职位要求他们每天做的技术工作。

如果你申请的是数据分析师的职位,而公司要求你使用他们的数据来制作演示文稿,你应该渴望完成它。你不是每天都能看到一家公司的真实数据,更不用说探索它来回答一些有趣的问题了。

如果你害怕陈述,也许这个角色或公司不适合你。作为数据人,我们会抓住任何机会查看来自真实用户和产品的真实数据。

因此,如果你愿意投入工作并对演示感到兴奋,为了成功,你需要确保做好以下几件事。

清理您的数据。

你会惊讶地发现,候选人经常连清理数据都不提。作为一个数据科学迷,我一次又一次地认识到拥有干净数据的重要性。这对我来说是非常重要的。

提及你做了什么来修复给你的数据集中的错误。你必须转换任何数据类型吗?剔除离群值?替换任何空值吗?简要概述你所采取的步骤。

垃圾数据输入等于垃圾数据输出。你的分析的准确性取决于你用来支持它的数据。

现在你不必在这里进行超深入的探讨,这取决于你申请的职位。如果你申请的是数据科学家的职位,这一点可能非常重要。然而,如果你申请的是数据分析师的职位,这可能是你想简单接触的。

超越自我。

我对候选人仅仅触及我们给他们的数据集表面的次数感到震惊。一直有人只提出了基本的计数和*均数,指望我们印象深刻。

计数和*均数在意料之中,并不令人印象深刻。确保你总是在做超出要求的事情。这些陈述的全部意义在于表明你是一个有创造力的思考者,并且能够执行你的想法。

集思广益有趣的假设,并使用数据来支持这些预感是否正确。我们希望看到战略思维。

在我的一次面试中,候选人只做了前五分钟的介绍。五分钟后,她完成了!她只给我们看了一些用 Excel 构建的基本图表,甚至没有看我们给她的整个数据集。

她做的绝对是最少的。如果你能这么说的话。如果你的演示不占会议时间的 75%,那它可能太短了。

虽然定量分析显然很重要,但定性分析也是你成功的重要部分。你需要说明为什么你认为这些数字是这样的。数据中会有季节性趋势吗?也许是收集收视率的后台问题?

与其说这些假设是正确的,不如说是你首先想到了它们。数据分析师做的很多事情都涉及实验和测试。证明你能以那种方式思考。

展示清晰的视觉效果。

如果你想恰当地传达你的发现,你的数据可视化需要强大和简洁。在我看来,这是一个人作为数据分析师最重要的一部分。

您工作的很大一部分是以业务团队,特别是非技术团队理解的方式可视化数据。你不希望这些形象化的东西容易被误解。

以下是我创建强大可视化效果的最佳技巧:

  • 按颜色分类。
  • 不要使用饼图。
  • 确保你给每个图表一个标题和轴标签。
  • 在整个演示文稿中,对相同的尺寸使用相同的配色方案。
  • 越简单越好。不要放入不必要的信息。

人们很容易陷入证明可以用图表做的所有很酷的事情。很酷的图表让人印象深刻!但是它们有用吗?不完全是。

总是从功能和讲故事的角度来思考独一无二的东西。不要仅仅为了炫耀而使用某些技能。这是可视化变得混乱和失去价值的时候。

不要超过时间限制。

这个让我抓狂。如果为您的演示安排的会议只有 30 分钟,请确保您的演示不超过 25 分钟。如果你的演示计划是一个小时,确保它不超过 45 分钟。

在给你面试的公司的人演示之前,你应该练习多次演示。给自己计时,确保你不会超过这些限制。

没有什么比浪费别人的时间更失礼的了。你的面试被安排在某个时间段是有原因的。尊重这一点,并保持在这些限制之内。

有一次,我在面试一位候选人,他的陈述超过了我们预定的时间 10 分钟。他还没有完成!这表明他并不像他试图表现出来的那样了解数据和他的工作。这让我感到恼火。采访你的人应该总是带着灵感和兴奋离开谈话。

超过这个时间限制说明你根本没有练习你的演示,你不尊重别人的时间。作为一名面试官,做一次又一次的数据展示已经相当累人了。你最不希望的就是有人超越你设定的界限。

最后留出 5 到 10 分钟时间供团队成员提问。总会有问题,所以,再一次,留点时间让你尊重别人设置的限制。

结论

记住,最重要的是你玩得开心,炫耀你能做什么!面试官想了解你的战略思维过程,以及你如何执行你的想法。

你不必为宏大的可视化而疯狂,只要确保你在定性和定量两个方面进行思考。确保你的可视化讲述一个故事,并清楚地传达你的想法。

当我面试目前的职位时,我遵循了上面列出的所有建议。我每天下班后花几个小时,周末也花几个小时做数据演示。我努力工作,结果显示出来了。面试官知道你是否投入了几个小时,而不是你所有的空闲时间。

如果你真的对公司和这个角色充满热情,你会喜欢这个过程。我坚信,当我们对正在做的工作感到兴奋时,成功就会自然而然地到来。

使用 Google Sheets 和 Tableau Public 获取和分析大量拍摄数据

原文:https://towardsdatascience.com/how-to-perform-a-data-analysis-of-mass-shootings-in-the-united-states-57a4290f9175?source=collection_archive---------28-----------------------

大规模枪击事件每天发生一次以上,不必要地摧毁生命。使用数据创建数据分析和数据科学解决方案,为决策提供信息并推动决策制定,从而降低其频率和规模。

音乐会观众和乐队音乐家在室外舞台上的照片。照片由 Julio ReynaldoUnsplash 上提供。

内容警告:枪支暴力,大规模枪击。

2017 年 10 月 1 日,数千名狂欢者在拉斯维加斯大道的91 号公路丰收音乐节上聆听现场音乐。晚上 10 点 05 分,斯蒂芬·帕多克(Stephen Paddock)从他位于曼德勒湾酒店 32 层的套房中用半自动步枪向下面的人群开火。在 10 分钟内,他发射了 1000 多发子弹。帕多克杀害了 60 人,打伤了 411 人。随之而来的恐慌使受伤人数上升到 867 人。

拉斯维加斯的大屠杀震惊了全国和世界。多年来,美国经常发生大规模枪击事件。但是拉斯维加斯枪击案是美国现代史上最血腥的单人大屠杀。尽管如此,大规模枪击事件仍以每年超过 400 起的速度继续发生。

如何利用数据分析来了解更多关于大规模枪击事件的信息?准备充分的数据数据分析仪表板能说服当选官员颁布将有所作为并拯救生命的法律和政策吗?

本文将向您展示如何获取大规模枪击事件数据,为分析做准备,并在 Tableau Public 中创建一个仪表板,以确定大规模枪击事件及其造成的死亡和伤害的趋势。

大规模拍摄问题概述

在美国,术语大规模枪击没有标准定义。枪支暴力档案 (GVA)将其定义为“至少有四名受害者被枪击,要么受伤要么死亡,不包括任何枪手……”的事件美国国会 2012 年《暴力犯罪调查援助法》将大规模杀戮定义为导致至少三名受害者的事件,不包括肇事者。

GVA 报告称,2019 年美国大规模枪击事件造成 417 人死亡。美国联邦调查局(FBI)报告称,2019 年美国发生了16425 起谋杀案。鉴于这些数据,大规模枪击案占当年美国所有凶杀案的 2.54%。

主数据源示例

很多机构都提供免费的海量拍摄文件。以下是几个例子。请注意,每个组织可能对大规模枪击事件有不同的定义。

GVACSV 文件包含 2014 年至 2019 年每起大规模枪击事件的数据。

大规模枪击事件追踪器(MST)JSON 文件包括 2013 年至 2021 年初每起大规模枪击事件的数据。

暴力项目Excel 文件包含 100 多个关于每次大规模枪击的变量。

从批量拍摄跟踪器复制和准备数据

我使用下面列出的步骤将 MST 网站上的大量拍摄数据转录到 Google Sheets 的电子表格中。

将数据从 MST 复制到 Google Sheets

对于我的海量拍摄数据分析项目,我选择了来自 MST 的数据。虽然我可以下载 JSON 格式的数据,但我直接从它的网页上复制数据,并将其粘贴到名为mass shooting tracker . site SourceGoogle Sheets 中的工作表中。

我通常通过下载文件来获取公共数据。当需要多次检索数据时,如果可能的话,我更喜欢从程序调用应用程序编程接口(API)来获取数据。虽然手动将网页上的数据转录到电子表格中不是我首选的数据获取方法,但从 MST 的网站上复制八年多的大规模拍摄数据只用了不到十分钟。电子表格格式比 JSON 格式更能满足我的需求。

大规模拍摄跟踪器—包含 2020 年数据的网页。作者捕获的图像。

准备工作表草稿

本节描述了我从 MST 准备数据以在 Tableau 公共可视化仪表板中使用的步骤。下面显示的 Google Sheets 工作表显示了从 MST 网页复制的数据和我创建的额外的临时列,以便为以后使用这些数据做准备。

Google Sheets 工作表,包含来自 MST 的大量拍摄数据和用于数据准备目的的新增列。图片由作者提供。

将 MST 网页中的数据转录到 Google Sheets 工作表中后,请遵循以下步骤(参考上面显示的工作表):

  1. 日期 列对工作表进行升序排序。
  2. 通过将单元格 A2 的值设置为 1 并将公式 =A2+1 粘贴到行号列的所有后续行中,从 1 到 n 计算行号列的值。
  3. 将原 # 列重命名为批量拍摄跟踪器#
  4. 使用此公式创建原始标准日期列:= TO _ TEXT(YEAR(F2))&"-"&TEXT(MONTH(F2)," 00") & "-" & TEXT(DAY(F2)," 00))
  5. 使用以下公式创建原始 ID 列: =CONCATENATE(C2,"-",TEXT(A2," 0000"))
  6. 接下来,仅将原始 ID 列的值复制到拍摄 ID 列。枪击 ID 是每个大规模枪击事件的唯一标识符。假设稍后将辅助数据源添加到数据分析项目中。在这种情况下,我会将拍摄 ID 添加到他们的记录中,以加入各种来源(例如,在关系数据库或 Tableau 这样的商业智能工具中)。
  7. 使用以下公式将位置列的值拆分到城市列: =SPLIT(G2,","

复制并简化最终工作表

完成上述准备步骤后,将数据复制粘贴到一个名为的新工作表中。但是请确保只粘贴没有公式的值。

创建新工作表后,删除除以下列之外的所有列:

  • 拍摄 ID
  • 日期
  • 死亡的
  • 受伤的
  • 射手
  • 新闻文章
  • 城市
  • 状态

大规模枪击案工作表应该如下所示。

Google Sheets 中完全准备好的大规模拍摄工作表,可用作 Tableau Public 中的数据源。图片由作者提供。

数据分析设计

虽然我对大规模拍摄数据有更雄心勃勃的计划,可能来自比 MST 报告的数据更多的来源,但我将演示如何用 Tableau Public 连接数据,为本文构建一个基本的仪表板。以下是我创建的图表和图形,用于查看数据随时间的变化趋势:

  • 按年份分列的死亡受害者
  • 按年份分列的受伤受害者
  • 按年份分列的受害者总数
  • 按年份分列的大规模枪击事件数量

仪表板还显示死亡的受害者,受伤的受害者,以及在地图上按州的事件数量。

最后,包括以下过滤器以允许数据的子集:

  • 年份范围
  • 死亡受害者范围
  • 受伤受害者范围
  • 状态
  • 城市和州

数据可视化仪表板

本节描述了 Tableau Public 中开发的大规模拍摄仪表盘。请随意下载仪表板,并将其作为您自己项目的起点。

Tableau 公共

对于这个项目和这篇文章,我使用了 Tableau Public ,一个流行的 Tableau 商业智能和数据可视化软件的免费版本。虽然它可以用来创建令人惊叹和有影响力的数据可视化,但与完整的 Tableau 桌面和服务器产品相比,它有一些局限性:

  • 仪表板和工作表只能保存到 Tableau 公共服务器,任何人都可以访问。因此,不要用它来展示机密、敏感或可能令人尴尬的信息。
  • 虽然完整的 Tableau 桌面应用程序可以使用各种数据,包括关系数据库,但 Tableau Public 可以使用相对较少的数据源。

要安装 Tableau Public,请在其主页上输入您的电子邮件地址,然后点击[下载应用程序]。

下载并安装 Tableau 公共商业智能和数据可视化软件。作者捕获的图像。

使用 Tableau Public 连接到 Google Sheets 中的数据

Tableau Public 可以连接到各种数据源,包括 Microsoft Excel、文本文件(包括 CSV 文件)、JSON 文件和 Google Sheets。它不能连接到数据库。

在本例中,当您打开 Tableau 公共应用程序时,将显示 连接 页面。

按照以下步骤连接到上一节中创建的 Google Sheets 电子表格:

  1. 在“发送到服务器”标题下,单击[更多…]。
  2. 点击【谷歌工作表】。
  3. 点击包含大量拍摄数据的谷歌电子表格的名称。在这个例子中,名字是 美国大规模枪击事件
  4. 时钟[连接]。

将 Tableau Public 连接到在 Google Sheets 中创建的大规模枪击电子表格。作者捕获的图像。

选择数据源

要选择在 Tableau 公共工作表和仪表板中使用的数据源,请单击屏幕左下角的[数据源]。然后,将 批量拍摄 表拖动到数据窗格。正如你在下面的截图中看到的,Tableau Public 显示了它从电子表格中导入的数据。

从 Google Sheets 电子表格中选择一张工作表,用作 mass shooting 仪表盘中的数据源。作者捕获的图像。

Tableau 工作表和仪表板

我用 Tableau Public 创建了美国的大规模枪击事件仪表盘,如下所示。虽然本文不是 Tableau 教程,也没有提供关于构建仪表板或其他设计的细节,但是您可以通过免费培训视频学习如何创建可视化和仪表板。

美国仪表盘中的大规模枪击事件描述了自 2019 年以来的大规模枪击事件、受伤的受害者和死亡的受害者。图片由作者提供。

其他感兴趣的数据点和潜在的改进

如下图所示, 大规模拍摄 仪表盘(如上图)包含这些工作表:

  • 受害者
  • 各州死亡人数-地图
  • 受伤的州-地图
  • 按州划分的事件—地图

Tableau Public 中的受害者工作表。此工作表是大规模枪击仪表板的一个组件。图片由作者提供。

来自大规模枪击仪表板的观察

虽然 Tableau 可视化中呈现的图表是初步的,包括有限的数据,但我使用它们得出了关于美国大规模枪击事件的以下结论:

  • 随着时间的推移,大规模枪击事件、死亡和受伤的人数持续增长。
  • 我听说在新冠肺炎疫情期间,大规模枪击事件减少了。根据给定的数据,相反的情况似乎是准确的。
  • 2020 年,每次事故的*均死亡人数减少,而事故数量增加。

其他感兴趣的潜在数据点和分析

上面描述和显示的基本图表说明了大规模枪击问题的趋势。但是,当增加额外的数据和设计良好的图表、图形和统计数据时,熟练的数据分析师或数据科学家可以创建丰富的信息源和决策工具。

以下是扩展和改进大量拍摄数据分析解决方案的一些想法。当然,并不是所有这些数据类型都能被公众轻易获得。

  • 受害者的人口统计数据(年龄、性别、种族、民族、国籍、宗教、其他群体)
  • 射击者的人口统计数据(年龄、性别、种族、民族、国籍、宗教、其他分组)
  • 枪手的动机
  • 射击运动员的心理健康
  • 枪手获得枪支(合法或合法)
  • 枪手的犯罪记录
  • 枪手和受害者的关系
  • 枪手与国际或国内恐怖组织的联系
  • 枪击地点(例如,教堂、学校、企业、农村或城市)
  • 枪手与枪击地点的关系(例如,枪击是否发生在前雇主的地点?)
  • 无论枪手是否在事件中死亡或受伤
  • 枪手死亡原因(自杀或被警察或其他人杀死)
  • 各州每 100,000 名居民的死亡和受伤人数
  • 各州枪支管理条例
  • 对幸存枪手的定罪和监禁

结论

虽然大规模枪击是摧毁生命的可怕罪行,但它们只占美国每年凶杀案的一小部分。尽管如此,像其他暴力犯罪一样,它们表明了严重的社会和个人问题。有了适当的数据和良好的演示,精心调整的分析可以更好地让公众了解问题。它们还可以为当选官员提供制定法律法规以拯救生命的工具。

关于作者

Randy Runtsch 是一名作家、数据工程师、数据分析师、程序员和摄影师。他和妻子住在美国明尼苏达州东南部。

Randy 讲述了如何利用公共数据集中的数据。有关如何在数据分析和数据科学项目中使用公共数据集的更多想法,请参见他最*的文章, 使用 Python 获取和分析天气和气候数据和 Tableau使用 Data.gov 上编目的公共数据集推动数据科学项目

什么是象限分析&如何用 Python 进行象限分析

原文:https://towardsdatascience.com/how-to-perform-a-quadrant-analysis-in-python-9f84d36f8a24?source=collection_archive---------10-----------------------

解释什么是象限分析以及在哪里使用它。关于如何使用 pandas、matplotlib 和 seaborn 库在 python 中实现的分步指南。

什么是象限分析?

象限分析图是一种非常常用的决策工具,尤其是在商业环境中。象限图在技术上是一个散点图,它被分成四个部分或象限,因此得名。在象限分析中,根据两个参数评估每个实体的绩效。根据实体在任一 KPI 下的表现,实体被分组到任一象限。
在确定实体属于哪个象限后,可以采取措施来提高相关 KPI 下的绩效。

在 Power BI 和 Tableau 等数据可视化工具中准备象限分析非常简单。然而,这个过程在 python 中并不那么简单。

我们将使用由联合国开发计划署发布的人类发展指数中的一些 KPI,完整的 kaggle 数据集可以在这里访问。

数据集的头部(图片由作者提供)

我们的数据集由以下数据组成:
一、国家:国家名称
二。hdi : 人类发展指数 三。life_ex : 出生时预期寿命 四。人均国民总收入

象限分析的组成部分

象限分析图有三个组成部分:

i .轴 在 X 轴和 Y 轴中定义了图表中绘制数据所基于的参数(KPI)。
我们将对 20 国集团在两个关键绩效指标方面的表现进行象限分析:
i 。人均国民总收入
。出生时预期寿命
X 轴代表人均国民总收入,Y 轴代表出生时预期寿命,数据将根据这两个指标绘制到相应的象限。

二。基准 X 轴和 Y 轴的阈值极限可定义为基准。
这将轴分成四个象限。当盈利、增长、改善等。都被认为是 y-o-y 基础,一般用‘0’作为客观基准。在一些需要相对比较的情况下,*均值或中间值也可以用作基准。
我们将使用 KPI 的*均值作为基准。

三世。分组 分组指定如何对 X 轴和 Y 轴上测量的数据进行分组。在我们的例子中,唯一可能的分组是国家级的。
如果其他数据可用,即洲级、语言级或其他特定类别,也可用于根据用例进行分组。

准备散点图

准备散点图,X 轴为人均国民总收入,Y 轴为出生时预期寿命 国家标签也被添加到散点图

你可以参考下面这篇关于如何给散点图添加标签的文章

plt.figure(figsize=(12,8))
sns.scatterplot(data=hdi_df, x='gni_pc', y='life_ex')plt.title(f"G 20 Countries : {abbr['gni_pc']} vs {abbr['life_ex']}")
plt.xlabel(abbr['gni_pc'])
plt.ylabel(abbr['life_ex'])

for i in range(hdi_df.shape[0]):
          plt.text(hdi_df.gni_pc[i], y=hdi_df.life_ex[i], s=hdi_df.Country[i], alpha=0.8)

plt.show()

散点图(图片由作者提供)

添加基准线

通过添加将图表分成 4 个象限的基准线,散点图可以转换为象限分析图。
标示为 Q1、Q2、Q3 和 Q4 的象限供以后参考。
散点图中增加了分别对应于 x 轴和 y 轴 KPI *均值的垂直线和水*线。

作者 GitHub 要点

分析

一旦数据被分组为 4 个象限,就可以根据用例对这些组进行分析。它可以用来寻找有利可图的产品,最有生产力的工人,落后的国家等。一旦确定了实体的象限,就可以采取具体的行动来将其 KPI 提高到期望的水*。

如上所示,G20 国家被分为 4 个象限。
水*虚线代表*均预期寿命,垂直虚线代表人均国民总收入。

Q1:人均国民总收入>*均值和预期寿命>*均值
Q2:人均国民总收入<*均值和预期寿命>*均值
Q3:人均国民总收入<*均值和预期寿命<*均值
Q4:人均国民总收入>*均值和预期寿命<*均值

在 bot KPI 下,Q1 的国家比其他国家表现更好。每个国家的目标都应该是到达 Q1。(这是我的假设 )
墨西哥,Q2 的预期寿命比*均值高,但是这个国家必须提高人均国民总收入。在这两个参数下,第三季度的国家都落后了,这些国家必须采取具体措施来提高到发达国家的标准。
第四季度沙特阿拉伯的人均收入很高,但人均寿命却低于*均水*。该国必须确定影响其公民预期寿命的因素,并解决这些因素,以达到 Q1。

资源:

这篇文章的笔记本可以在我的 Git Repo 中找到。

成为会员

我希望你喜欢这篇文章,我强烈推荐 注册中级会员 来阅读更多我写的文章或成千上万其他作者写的各种主题的故事。
你的会员费直接支持我和你看的其他作家。你还可以在 Medium 上看到所有的故事。

作者的其他文章:

</5-methods-to-check-for-nan-values-in-in-python-3f21ddd17eed> https://medium.datadriveninvestor.com/visualizing-option-trading-strategies-in-python-35bfa61151d9 https://medium.com/mlearning-ai/stock-market-data-visualization-using-mplfinance-1d35a8d48e4

你可以看看我的 EPL 预测系列中的下面这篇文章,在这篇文章中,我使用象限分析来比较基于 xG 得分和 xG 失球的足球队

Nicolas Solerieu 在 Unsplash 上拍摄的照片

如何用 PEGASUS 执行抽象概括

原文:https://towardsdatascience.com/how-to-perform-abstractive-summarization-with-pegasus-3dd74e48bafb?source=collection_archive---------8-----------------------

像马一样工作来完成抽象的摘要任务?不,我们可以骑在飞马上取得好成绩

作者提供的视频

注意:如果你喜欢看视频,请随意播放以上相同内容的视频。

面对冗长的文件,我们自然倾向于不读,或者至少浏览要点。所以做一个总结对节省我们的时间总是有好处的⏳和大脑处理能力。

然而,自动总结曾经是一项不可能完成的任务。具体来说,抽象概括非常具有挑战性。不同于提取摘要(从文档中提取重要的句子并组合它们以形成一个“摘要”),抽象摘要涉及释义单词,因此更困难,但可能给出更连贯和更精炼的摘要。

抽象与提取摘要的图解|作者图片

直到 seq2seq 学习和无监督语言模型(如 ELMo 和 BERT)等技术的发展,抽象摘要才变得更加可行。

在自然语言处理(NLP)领域早期突破的基础上,谷歌的 PEGASUS 进一步改进了抽象摘要的最新(SOTA)结果,特别是在资源较少的情况下。更具体地说,与以前的模型不同,PEGASUS 使我们能够通过 1,000 个例子,而不是数万个训练数据,获得接* SOTA 的结果。

在本文中,我们将着眼于 PEGASUS 的高级工作方式,以及它如何帮助我们完成总结任务。

代码为的论文摘要排行榜(截至 2021 年 2 月 4 日)

飞马是如何工作的

1.体系结构

PEGASUS 使用编码器-解码器模型|图片由作者提供

在高层次上,PEGASUS 使用编码器-解码器模型进行序列到序列的学习。在这种模型中,编码器将首先考虑整个输入文本的上下文,并将输入文本编码成称为上下文向量的东西,它基本上是输入文本的数字表示。这个数字表示然后将被馈送到解码器,其工作是解码上下文向量以产生摘要。

与最*的 SOTA NLP 模型一致,PEGASUS 也采用了 transformer 架构,如果你想了解更多关于什么是 transformer 的信息,我强烈建议你阅读这篇文章,标题是 Jay Alammar 的“图解 Transformer”

2.预培训

飞马座与以前的 SOTA 模型的区别在于预先训练。

作者(张等。艾尔。)假设预训练模型以输出重要的句子是合适的,因为它非常类似于抽象概括需要做的事情。使用一种称为 ROUGE1-F1 的度量标准,作者能够自动选择“重要”的句子,并在大型语料库上对模型进行预训练,即 3.5 亿个网页和 15 亿篇新闻文章。

有了预先训练好的模型,我们就可以在数量少得多的实际数据上对模型进行微调。事实上,对各种数据集的评估结果表明,仅用 1000 个训练数据,该模型就取得了与以前的 SOTA 模型相当的结果。这具有重要的实际意义,因为我们大多数人没有资源来收集成千上万的文档摘要对。

评价结果摘自 PEGASUS 的论文

如何使用飞马

看到 PEGASUS 的评估结果后,您可能想知道如何编写代码来使用该模型。幸运的是,拥抱脸🤗店内有 PEGASUS 模型,使我们很容易利用 PEGASUS。

1.推理

为了进行推理,我们可以遵循拥抱脸网站上提供的示例脚本。

拥抱脸上的示例代码截图

根据您的用例与用于微调的数据集的相似程度,您可以将 model_name 与此处列出的各种其他微调模型(除了 google/pegasus-large )进行交换。

抱脸上的飞马模特截图

2.微调

如果您想为您的用例定制一个模型,您可以在您的数据集上微调 google/pegasus-large 模型。

为此,请参考我们的 Github 代码,这是我们从 Hugging Face 的示例代码中改编而来的关于微调的

我们用于微调的 PyTorch 脚本截图

但是请注意,微调编码器和解码器可能会占用大量内存。如果你的本地计算机不幸不能胜任这个任务(像我的)😅),可以考虑使用谷歌云。由于谷歌云对新注册用户提供免费试用,你可以免费试用。😎

通过上面的指南,我们希望你现在能够适应并采用 PEGASUS 来完成你的抽象概括任务。打个比方,我们不再需要像马一样工作,而是可以骑在飞马上达到很高的高度😉。

感谢阅读,我希望这篇文章是有用的:)也请随时评论您可能有的任何问题或建议。

参考

如何使用隔离林算法执行异常检测

原文:https://towardsdatascience.com/how-to-perform-anomaly-detection-with-the-isolation-forest-algorithm-e8c8372520bc?source=collection_archive---------7-----------------------

如何使用这种基于树的算法来检测数据中的异常值

史蒂文·卡梅纳在 Unsplash 上拍摄的照片

异常检测是机器学习中经常被忽视的领域。它看起来不像深度学习或自然语言处理那样浮华,并且经常在机器学习课程中被完全跳过。

然而,异常检测仍然很重要,其应用范围从数据预处理到欺诈检测,甚至系统健康监控。有许多异常检测算法,但在撰写本文时,最快的算法是隔离林,也称为 iForest。

在本文中,我将简要解释隔离森林算法的工作原理,并演示如何在 Python 中使用该算法进行异常检测。

隔离林算法的工作原理

隔离林算法利用异常样本(通常称为异常值)的以下属性:

  • 少数 —异常样本是少数,在任何数据集中只有少数。
  • 不同 —异常样本的值/属性与正常样本的值/属性非常不同。

与正常点相比,这两个属性更容易将异常样本从其余数据中分离出来。

隔离异常点和正常点。图片由作者提供。

请注意,在上图中,我们只用一条线就可以将异常点从其余数据中隔离出来,而右边的正常点需要四条线才能完全隔离。

该算法

给定数据点 X的样本,隔离森林算法使用以下步骤构建隔离树(iTree)、 T

  1. 随机选择一个属性 q 和一个分割值 p.
  2. 使用规则 q < pX 分成两个子集。这些子集将对应于 T. 中的左子树和右子树
  3. 递归地重复步骤 1-2,直到当前节点只有一个样本或者当前节点的所有值都具有相同的值。

然后,该算法多次重复步骤 1–3,以创建几个隔离树,从而生成一个隔离林。基于隔离树是如何产生的以及异常点的属性,我们可以说大多数异常点将位于更靠*树的根的位置,因为与正常点相比,它们更容易被隔离。

从小型数据集创建的隔离树示例。图片由作者提供。

一旦我们有了一个隔离森林(隔离树的集合),给定数据点 x 和样本大小 m ,算法使用以下异常分数:

隔离林算法的异常分数。图片由作者提供。

在上式中, h(x) 表示给定隔离树中数据点 x i n 的路径长度。表达式 E(h(x))表示穿过所有隔离树的该路径长度的预期或“*均”值。表达式 c(m) 表示给定样本量 mh(x) 的*均值,并使用以下等式定义。

h(x)的*均值为样本大小 m。图像由作者提供。

上面的等式是从隔离树与二叉查找树具有相同结构的事实中推导出来的。就路径长度而言,隔离树中节点的终止类似于二叉查找树中的不成功搜索。一旦为给定点计算了异常分数 s(x,m) ,我们可以使用以下标准来检测异常:

  1. 如果 s(x,m) 接* 1,那么 x 极有可能是异常。
  2. 如果 s(x,m) 小于 0.5,则 x 可能是正常点。
  3. 如果 s(x,m) 对于数据集中的所有点都接* 0.5,那么数据可能不包含任何异常。

请记住,对于所有点来说,异常分数总是大于零但小于 1,因此它非常类似于概率分数。

在 Scikit-learn 中使用隔离森林算法

隔离森林算法是 Scikit-learn 中的一个模块。在本教程中,我将演示如何使用 Scikit-learn 通过该算法执行异常检测。你可以在 GitHub 上找到本教程的完整代码

导入库

在下面的代码中,我从 Scikit-learn 导入了一些常用的库以及隔离森林模块。

import numpy as np
import pandas as pd
from sklearn.ensemble import IsolationForest
import matplotlib.pyplot as plt
%matplotlib inline

构建数据集

为了创建一个数据集用于演示目的,我使用了 Scikit-learn 的 make_blobs 函数来创建一个集群,并在下面的代码中添加了一些随机离群值。整个数据集包含 500 个样本,在这 500 个样本中,只有 5%或 25 个样本实际上是异常的。

from sklearn.datasets import make_blobsn_samples = 500
outliers_fraction = 0.05
n_outliers = int(outliers_fraction * n_samples)
n_inliers = n_samples - n_outliersblobs_params = dict(random_state=0, n_samples=n_inliers, n_features=2)X = make_blobs(centers=[[0, 0], [0, 0]], 
               cluster_std=0.5,
               **blobs_params)[0]rng = np.random.RandomState(42)X = np.concatenate([X, rng.uniform(low=-6, high=6, size=(n_outliers, 2))], axis=0)

训练算法

使用 Scikit-learn 的 API 训练隔离林很容易,如下面的代码所示。注意,我在 n_estimators 参数中指定了 iTrees 的数量。还有另一个名为污染的参数,我们可以用它来指定包含异常的数据的百分比。然而,我决定省略这个参数并使用默认值,因为在实际的异常检测情况下,这些信息可能是未知的。

iForest = IsolationForest(n_estimators=20, verbose=2)
iForest.fit(X)

预测异常

预测异常很简单,如下面的代码所示。

pred = iForest.predict(X)

预测函数将为 x 中的每个样本赋值 1 或-1。值 1 表示一个点是正常点,而值-1 表示它是异常点。

可视化异常

现在我们已经为 X 中的每个样本预测了一些标签,我们可以用 Matplotlib 可视化结果,如下面的代码所示。

plt.scatter(X[:, 0], X[:, 1], c=pred, cmap='RdBu')

上面的代码产生了下面的可视化效果。

异常点显示为红色,正常点显示为蓝色。图片由作者提供。

在下图中,标记为异常的点显示为红色,正常的点显示为蓝色。该算法似乎在检测异常方面做得很好,尽管在中心的聚类边缘的一些点可能是被标记为异常的正常点。查看异常分数可能有助于我们更好地理解算法的性能。

可视化异常分数

我们可以使用 score_samples 函数生成简化的异常分数,如下所示。

pred_scores = -1*iForest.score_samples(X)

请注意, score_samples 函数返回的分数将全部为负,并且对应于本文前面定义的异常分数的负值。为了保持一致,我将这些分数乘以-1。

我们可以使用下面的代码来可视化分配给每一点的分数。

plt.scatter(X[:, 0], X[:, 1], c=pred_scores, cmap='RdBu')
plt.colorbar(label='Simplified Anomaly Score')
plt.show()

上面的代码给了我们以下有用的可视化。

异常分数的可视化。图片由作者提供。

当查看上面的可视化时,我们可以看到算法确实如预期的那样工作,因为靠*中间蓝色聚类的点具有较低的异常分数,而较远的点具有较高的异常分数。

摘要

隔离森林算法是一种快速的基于树的异常检测算法。该算法使用二分搜索法树中路径长度的概念来为数据集中的每个点分配异常分数。该算法不仅快速高效,而且由于 Scikit-learn 的实现,它还可以广泛使用。

像往常一样,你可以在 GitHub 上找到这篇文章的完整代码

加入我的邮件列表

你想在数据科学和机器学习方面变得更好吗?您想了解数据科学和机器学习社区的最新图书馆、开发和研究吗?

加入我的邮件列表,获取我的数据科学内容的更新。当你注册时,你还会得到我免费的解决机器学习问题的逐步指南!也可以在 Twitter 关注我,获取内容更新。

当你这么做的时候,考虑加入媒体社区,阅读成千上万其他作家的文章。

来源

  1. F.刘,丁国明,周志宏,隔离森林,(2008),2008 年第八届 IEEE 数据挖掘国际会议。
  2. F.Pedregosa 等,sci kit-learn:Python 中的机器学习,(2011),机器学习研究杂志。

如何在一行代码中执行*似的字符串匹配

原文:https://towardsdatascience.com/how-to-perform-approximate-string-matching-in-one-line-of-code-76fae5d7efc?source=collection_archive---------4-----------------------

使用 Python 对客户名称列表进行模糊字符串匹配(适用于所有人)

图片由来自 Unsplash 的托尔加·乌尔坎拍摄

您是否曾经尝试过使用不完全匹配的键或查找值来连接两个表?也许你在金融或市场部门工作,你必须匹配来自两个不同数据源的两个客户列表。虽然客户名称应该是相同的,但是他们的拼写不同,这对于 VLOOKUP 函数来说是一个不可克服的挑战。如果您要匹配不匹配的字符串列表(例如,客户名称、产品、交易、地址),请继续阅读——本文可能会节省您的工作时间。

文章首先介绍了用于执行*似匹配的科学方法,即 Levenshtein 距离。然后,通过一个案例研究,展示如何将数据从 Excel 导入 Python,在一行代码中执行匹配,并将 1:1 匹配和相似性得分的结果表导出到 Excel。

方法: Levenshtein 距离和 FuzzyWuzzy

模糊字符串匹配或*似字符串匹配是一种技术,给定一个目标字符串,它将从非精确匹配列表中找到其最接*的匹配。如果您尝试使用 Excel 的*似 VLOOKUP 来执行模糊匹配,您会知道它适用于数字的排序列表,但不适用于字符串。原因是 Excel 函数从查找范围中返回一个低于查找值的匹配项,并且其后继值大于查找值。Excel 逻辑很难应用于字符串,所以我们求助于 Levenshtein 距离来进行*似的字符串匹配。

Levenshtein 距离是两个序列之间的距离的稳健且有效的度量。该算法计算编辑距离,即单个单词序列匹配目标序列所需的最小编辑次数(插入、删除或替换)。自 1965 年发明以来,这一指标从未改进过,它有许多应用,包括不同物种基因组的比较。本文不提供算法的数学解释;希望你相信麻省理工学院的研究人员,他们认为是我们将得到的最好的编辑距离算法。

我们可以写一个计算 Levenshtein 距离的函数,但是 FuzzyWuzzy 包已经为我们做了。一旦安装完毕,该软件包将提供一系列方法,最终计算 Levenshtein 距离相似性比率。让我们来看一个案例研究,它将帮助您开始进行*似的字符串匹配。

案例研究:两个客户名称列表的*似匹配

问题陈述

假设我们的任务是匹配两个客户名称列表。客户名来自两个不同的来源:名单 A 是干净的,而名单 B 是被污染的。30 个客户名称应该是 1:1 匹配,但是列表 B 中的名称拼写错误。此外,列表 B 包含空白单元格、标点符号和重复名称(见下图)。虚拟数据集是通过从标准普尔 500 指数中随机选取公司名称生成的。

图片作者。虚构客户名称列表

解决这个任务的一个选择是手动执行匹配(Accenture:Accent llxure,Adobe:Addobbe 等)。).然而,如果列表太长或者任务需要重复,人们应该选择更有效的解决方案,通过 FuzzyWuzzy 包利用 Levenshtein 距离。

第一步:数据导入和数据清理

第一步是将 customer names 表从 Excel 导入 Python,并准备好匹配的客户列表。如果您已经知道如何做到这一点,请跳到步骤 2,但是要记住导入相关的包。

在导入 FuzzyWuzzy 包之前,我们必须安装它。我们可以在 Anaconda 提示符下使用命令行pip install fuzzywuzzy。为了将字符串匹配的速度提高 4-10 倍,我们建议安装 Levenshtein Python C(使用命令行pip install python-Levenshtein)。

现在,让我们导入相关的包:

# Import packages
import os
import pandas as pd
from fuzzywuzzy import fuzz

如果输入文件的位置与 Python 文件的位置不同,则需要更改目录。然后,我们使用pandas.read_excel()将客户列表导入到 pandas 数据框架中。使用列表理解,我们遍历列表 A 中的客户名称,删除列表底部的空白。类似地,我们使用列表理解来删除列表 B 中缺少的值,只保留唯一的客户名称。精简列表将减少模糊字符串匹配算法的工作量。

# Change directory
# os.chdir(r"Your file path")# Import the customers data
filename = "customers lists input.xlsx"
customers = pd.read_excel(filename)# Clean customers lists
A_cleaned = [customer for customer in customers["list_A"] if not(pd.isnull(customer))]
B_cleaned = [customer for customer in customers["list_B"].unique() if not(pd.isnull(customer))]

瞧,客户名称已经准备好匹配了。

第二步:用 FuzzyWuzzy 在一行中执行*似匹配

目标是在一行代码中从列表 B 中生成相似性得分和匹配字符串的元组列表。为此,我们使用嵌套列表理解,这被认为比嵌套 For 循环更“pythonic 化”。

Python 化描述了一种编码风格,利用 Python 独有的特性来编写可读性强且美观的代码
( 什么是 Python 化风格?| Udacity

从下面代码片段中的外部循环开始,对于 A_cleaned 中的每个客户名称,我们生成一个元组列表。每个元组由列表 B 中的客户名称及其相对于列表 A 中客户名称的相似性得分组成。列表 A_cleaned 计数 30 个客户名称,因此循环生成 30 个列表,每个列表由 31 个元组组成(在 B_cleaned 中有 31 个客户名称)。因为我们只对列表 B 中最匹配的客户名称感兴趣,所以我们将内部循环包装到内置函数max()中,从而将列表列表转换为元组列表。这样,列表 A 中的每个客户名称只被分配一个元组。

# Perform fuzzy string matching
tuples_list = [max([(fuzz.token_set_ratio(i,j),j) for j in B_cleaned]) for i in A_cleaned]

相似性得分由函数token_set_ratio()生成。在预处理字符串(标记化、小写和删除标点符号)之后,token_set_ratio()计算 Levenshtein 距离,控制两个字符串之间的交集。在比较不同长度的字符串时,FuzzyWuzzy 的token_set_ratio()是首选比率,就像我们的例子一样。

当打印元组列表时,部分输出类似于下面的代码片段:

图片作者。相似性得分和匹配字符串的元组列表

步骤 3:将输出导出到 Excel

最后一步是创建一个熊猫数据框架,并将其导出到 Excel。数据帧应该包括:
1)列表 A 中的客户名称
2)列表 B 中的匹配项
3)相似性得分
为了创建数据帧,我们将元组列表解包为两个列表。这可以通过用zip(*)解压缩元组并用内置函数map()将元组转换成列表来实现。

# Unpack list of tuples into two lists
similarity_score, fuzzy_match = map(list,zip(*tuples_list))# Create pandas DataFrame
df = pd.DataFrame({"list_A":A_cleaned, "fuzzy match": fuzzy_match, "similarity score":similarity_score})

创建数据框架后,我们将其导出到名为模糊字符串匹配的新 Excel 工作簿中:

# Export to Excel
df.to_excel("Fuzzy String Matching.xlsx", sheet_name="Fuzzy String Matching", index=False)

查看您保存 Jupyter 笔记本的文件夹,您会发现带有数据框的 Excel 工作簿。看起来所有的比赛都进行的很正确。工作表的一部分应该如下图所示:

图片作者。Excel 工作表输出

结论

在 Excel 中,尝试匹配两个不完全匹配的字符串列表是一项具有挑战性的任务。这篇文章展示了如何使用 Python 使*似字符串匹配这一艰巨任务变得简单。事实上,通过利用强大的软件包 FuzzyWuzzy 和 Python 的 list comprehensions,只需一行代码就可以完成匹配。

下面,您可以找到 Jupyter 笔记本,以便于复制。

关于我

我现在是诺维信公司的国际金融毕业生。此前,我在 Novo Holdings 担任初级分析师,同时在哥本哈根商学院完成了金融和投资硕士学位。我对金融数据科学充满热情📈🐍。

如果你对这篇文章有任何问题或建议,你可以写信给 lorenzotracanna@gmail.com 或通过 LinkedIn 联系我。

如何使用 Python 进行债券估值

原文:https://towardsdatascience.com/how-to-perform-bond-valuation-with-python-bbd0cf77417?source=collection_archive---------12-----------------------

Python 中通过贴现现金流分析进行债券估值的实用介绍。

照片由像素皮克斯拜拍摄

债券是一种固定收益证券,也总是被称为债券持有人和债券发行人之间的 I.O.U ,包括贷款及其支付的细节。债券就像一种“债务资产”,每天都可以在市场上买卖。

在本文中,我们将了解如何使用 Python 对债券进行估值。这将给我们一些关于“债务”如何变成资产的想法。我们将从理解债券过程开始,然后对债券的估值进行贴现现金流分析。

必备 Python 库

  1. 数字财政——https://numpy.org/numpy-financial/

开源代码库

本文中的原始完整源代码可以在我的 Github Repo 上获得。如果你想用它来关注我的文章,请随意下载(Bond _ evaluation . ipynb)。

粘合过程

债券支付固定金额的利息——以向债券持有人支付息票的形式。一旦债券发行过程开始,债券发行人将开始在特定的时间间隔向债券持有人支付利息(例如每年一次或每年两次等)。在到期日结束时,债券持有人还将获得贷款本金或面值。

作者准备的图像

债券持有人作为债券的所有者,有权在到期日之前收到所有的息票付款。这意味着债券持有人从支付给债券发行人的债券价格中获得利息,同时等待到期日结束以收回贷款本金。

债券价格的计算

我们购买债券时的价格是所有未来支付流的现值。

例如,有一种面值为 2000 美元的债券,每年支付 8%的票面利率。如果债券将在 5 年内到期,所有贷款期限的年复合利率为 6%,债券的价格是多少?

债券价格的计算过程如下:

作者准备的图像

从上面债券价格计算的图解中,我们可以看到价格是债券期限内 贴现现金流 的总和。利率越高,债券价格越低。这意味着债券价格与利率负相关。

我们可以很容易地使用 Python Numpy-Financial pv 函数将整个计算过程简化成几行脚本。

第 1–2 行:导入所需的库。

第 4–7 行:定义并给所有需要的参数赋值。

第 9 行:应用 Python Financial-Numpy pv 函数计算债券价格。

(注意:原始结果值将是负值,这就是我们将该值乘以-1 以将其变为正值的原因。)

第 10 行:显示结果。

作者准备的图像

如上面的脚本所示,所有繁琐的计算都被封装在 Numpy-Financial pv 函数中。我们需要做的就是将适当的参数应用到函数中。

到期收益率

债券收益率是衡量我们购买的债券投资回报的指标。最常见的债券收益率指标是到期收益率(YTM) 。YTM 是投资者持有债券至到期时的总预期回报,用年利率表示。YTM 也被认为是债券投资的内部收益率。

*似 YTM 的公式如下:

作者准备的图像

例如,我们支付 9000 美元购买面值为 10000 美元的债券。该债券的票面年利率为 5%,将于 4 年后到期。债券投资的 YTM 是多少?

第 1–4 行:定义并给所有需要的参数赋值。

第 6 行:应用公式*似 YTM。

第 7 行:显示结果

该债券的 YTM 约为 7.89%。由于债券票面利率(5%)低于其 YTM,债券被折价出售。另一方面,如果票面利率高于 YTM,债券溢价出售。

YTM 有助于投资者判断购买债券是否划算。因为所有债券的所有 YTM 都以相同的年期表示,所以它可以用来比较不同到期日和票面利率的债券。

结论

在本文中,我们已经完成了确定债券理论公允价值的过程,并估算了 YTM。值得注意的是,息票的支付频率可以是一年一次、半年一次、每季度一次或其他周期性间隔,尽管为了简单起见,我们只关注年度支付。无论支付频率如何,债券票面利率总是以年利率表示。

我希望你喜欢阅读这篇文章。

如果你喜欢我关于 Python for Finance 的文章,可以随意 订阅 Medium 。我会坚持不懈地不时发表相关文章。

参考

  1. https://www.investopedia.com/terms/b/bond-valuation.asp
  2. https://courses . lumen learning . com/unlimited-finance/chapter/validating-bonds/
  3. https://www.investopedia.com/terms/y/yieldtomaturity.asp
  4. https://financeformulas.net/Yield_to_Maturity.html
  5. https://scripbox . com/MF/yield-to-maturity/# yield-to-maturity-formula

如何在 Flask 和 Tornado 中执行多任务处理

原文:https://towardsdatascience.com/how-to-perform-multitasking-in-flask-and-tornado-3f00945f4510?source=collection_archive---------2-----------------------

提高阻塞和非阻塞 web 服务器的性能

马文·迈耶在 Unsplash 上的照片

M 多任务处理是指(几乎)同时执行多个任务或流程的能力。像 Flask、Django 和 Tornado 这样的现代 web 服务器都能够同时处理多个请求。由于多种解释,多任务的概念实际上非常模糊。您可以使用多重处理、多线程或异步来执行多任务处理。在本文中,我将解释这些概念之间的区别,以及如何在 Flask 和 Tornado 中执行多任务处理。如果你有使用这两个框架的经验,请告诉我们你什么时候更愿意使用其中一个。我挺好奇的:)

抢占式多任务 vs .协作式多任务

一个操作系统有两种多任务选择:抢占式和协作式。在抢占式多任务处理中,应用程序可以共享操作系统(OS)及其底层资源。换句话说,允许操作系统停止当前正在运行的进程,并切换到不受应用程序控制的另一个进程。这意味着操作系统必须优雅地切换上下文。进程的隔离确保了一个进程的无限循环不会阻塞其他进程,但是,当涉及到与其他进程交换数据时,它会带来更多的复杂性。

另一方面,在协同多任务中,一个应用只使用一个主机进程,应用中的任务共享这个单个主机进程的资源。当每个任务不再需要资源时,它必须将控制权让给宿主进程。因此,操作系统对应用程序的控制较少,因为它不允许执行上下文切换。这种方法在某种程度上获得了大部分 CPU,易于扩展,并且易于与其他任务交换数据。但是如果任何一个任务停滞不前(不放弃控制权),整个应用程序也会停滞不前。这就是 asyncio 的基本工作原理,我们将在后面详细讨论。

这张图表直观地显示了这两种类型之间的区别。

合作多任务 vs .抢先多任务,由创造

并行性与并发性

多任务处理是在同一时间内运行几项任务的能力。这并不一定意味着这些任务必须在完全相同的时刻开始。这两种场景有不同的名称:并行和并发。

并行是指任务实际上同时开始。这可能发生在多核处理器或多线程处理器上,其中每个核/线程可以独立地启动一个任务。并发是指任务在重叠的时间段内开始、运行和完成,这可能发生在单核服务器上。如果你熟悉 Python 中的全局解释器锁(GIL),你一定知道 Python 在一个进程中只允许一个线程控制解释器,也就是说一个单进程多线程程序最多可以达到 100%的 CPU 利用率。真正的 Python 已经给出了关于 GIL 的很好的教程。

https://realpython.com/python-gil/

在我看来,并行性相当于抢先式多任务处理,并发性相当于协作式多任务处理。

多重处理 vs .多线程 vs .异步

Python 中的多任务问题一般可以使用这些库之一来解决:multiprocessingthreadingasyncio。就使用哪个库而言,取决于用例,用例可以分为 CPU 受限或 I/O 受限。

CPU 绑定问题是指性能由 CPU 的能力决定的情况。CPU 越快或者 CPU 的内核越多,程序的性能就越高。例如处理图像、进行计算等。

I/O 受限问题是指性能由输入/输出操作完成的等待时间决定的情况。I/O 越快,我们获得的性能就越高。例如发出 HTTP 请求、读取文件等。

一个简单的规则是,multiprocessing适合 CPU 受限的问题,threadingasyncio适合 I/O 受限的问题。但是threadingasyncio有什么不同呢?如果用我们目前掌握的知识,threading解决抢占式多任务,asyncio解决协作式多任务。Python 维护一个线程池,当需要时,可以从池中检索新的线程。应该注意的是,所有线程共享相同的内存,因此需要锁定来确保一次只有一个线程可以写入内存中的相同对象。

asyncio中你不用担心这个,因为它在单个进程中使用单线程。但是,asyncio的缺点是你应该记得把控制权还给事件循环(通过yield),否则程序会被阻塞。此外,一旦你使用了asyncio,所有的内部函数/库也应该支持异步。这需要在编码方面付出更多的努力。

如果你想深入研究threadingasyncio,我也推荐以下来自《真实的 Python》的优秀文章。

https://realpython.com/intro-to-python-threading/ https://realpython.com/async-io-python/

我花了相当多的时间介绍多任务处理的问题和理论,我认为在进入代码之前了解这些是非常重要的。我希望你现在已经打好了基础。让我们进入有趣的部分吧!

烧瓶 vs .龙卷风

Flask 和 Tornado 都是 Python 世界中流行的 web 框架,目的不同。Flask 是一个基于 WSGI 的轻量级 web 框架,Tornado 是一个 web 框架,也是一个异步网络库。

如何处理并发请求?

这种不同的设置也意味着它们将以不同的方式处理并发请求。从 Flask 1.0 开始,默认情况下 flask server 是多线程的。每个新请求都在一个新线程中处理。

这是一个使用默认设置的简单烧瓶应用程序。出于演示目的,我在返回响应之前放置了sleep(1)。它能够在大约 2 秒钟内处理 10 个并发请求。

带螺纹的烧瓶应用程序=True

如果我禁用线程模式,您可以看到性能的巨大差异。是因为这个同步服务器现在只有一个线程,所以每个请求都是在前一个完成之后开始的。

带螺纹的烧瓶应用程序=假

现在,让我们来看看龙卷风。这也是一个响应中带有sleep(1)的简单例子。然而,处理 10 个并发请求需要 10 秒钟。嗯,这里出了什么问题?

带同步代码的 Tornado 应用

原因是 Tornado 是一个只有一个线程的异步服务器。这个例子实际上与第二个烧瓶例子的情况相同。为了使用异步服务器,阻塞代码time.sleep(1)(实际上是您可能有的所有阻塞代码)必须被非阻塞代码替换。这就是为什么我之前说过,我们需要更多地了解异步中的编码部分,因为任何隐藏的阻塞代码都可能阻塞整个应用程序,而且我们大多数人更习惯于编写同步代码而不是异步代码。

解决方案之一是使用异步版本的sleep,即tornado.gen.sleep。结果与第一个烧瓶示例相同。此外,完整功能与async/await关键字异步。

带有异步代码的 Tornado 应用程序

如何在请求过程中进行多任务处理?

我们讨论了如何在 Flask 和 Tornado 中处理并发任务,这是多任务处理的一种。另一种类型的多任务发生在请求的处理过程中。例如,在返回响应之前,服务器需要从 5 个不同的端点收集数据。如果服务器逐个执行请求,将会对性能产生巨大影响。

在这种背景下,我们不需要太依赖框架本身。这是如何在同步和异步应用程序中处理并发 web 请求的问题。由于是 I/O 操作,threadingasynciomultiprocessing要好。

下面是ThreadPoolExecutor在 Flask 中的实现。性能和前面的例子一样高。

Flask 中的并发请求

这就是你在龙卷风中可以做到的。请记住,在异步应用程序中,一切都应该是异步的。出于演示的目的,我使用了一个模拟函数,但是实际上,您应该使用一个类似于aiohttp的异步 HTTP 库。

Tornado 中的并发请求

如何运行后台任务?

最后但同样重要的是,我想向您展示如何在 Flask 和 Tornado 应用程序中运行后台任务。如果您想要调度作业或让某些东西连续运行而不干扰主进程,后台任务会非常有用。

一般来说,Tornado 更支持后台任务,但您也可以在 Flask 中实现这一点。

就像前两个场景一样,我们可以再次使用threading在 Flask 中实现这一点。需要注意的是,后台作业的启动要在 Flask app 启动之前完成。

烧瓶中的后台任务

查看这个博客,看看如何使用 uWSGI 在 Flask 中进行后台作业。

在这种情况下,Tornado 有两种不同的方式使用其本机功能来实现这一点:[spawn_callback](https://www.tornadoweb.org/en/stable/ioloop.html#tornado.ioloop.IOLoop.spawn_callback)[PeriodicCallback](https://www.tornadoweb.org/en/stable/ioloop.html#tornado.ioloop.PeriodicCallback)。它们的主要区别在于,spawn_callback是一个“一劳永逸”的功能,在启动作业后你没有任何控制权,而PeriodicCallback返回给你一个任务实例,你可以在以后启动和停止。

在龙卷风中使用 spawn_callback

这是一个周而复始的例子。在启动 web 服务器之前,不要忘记启动该任务。

在 Tornado 中使用 PeriodicCallback

结论

在本文中,我们从 3 个不同的角度讨论了如何在 Flask 和 Tornado 中执行多任务。在此之前,我们详细介绍了两种多任务模式以及多处理、多线程和异步之间的区别。

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

参考

https://leimao.github.io/blog/Python-Concurrency-High-Level/

如何在 PyTorch 中执行有序回归/分类

原文:https://towardsdatascience.com/how-to-perform-ordinal-regression-classification-in-pytorch-361a2a095a99?source=collection_archive---------4-----------------------

订购标签时提高模型性能的一个简单技巧。

由 vectorjuice 创建的抽象向量—www.freepik.com

当你有一个多类分类问题,并且这些类是有序的,这就是所谓的“有序回归”问题。一个例子可以是将学生的表现分类为 A > B > C > D > E。使用普通分类器解决这类问题的问题是,模型会假设将 A 误分类为 D 的错误与将 A 误分类为 B 的错误一样严重——这显然是不正确的,因为 AD 之间的差异要比它们之间的差异大得多有序回归的另一个名字是有序分类或者甚至排序学习;你可能已经猜到了,这些方法让模型知道类的顺序关系,让模型学习排序,而不是学习分类

这篇文章将展示一个使用自定义损失函数在 PyTorch 中执行有序回归的简单技巧。虽然我将针对一个特定的问题介绍这个技巧,但是你可以将它应用于任何顺序回归问题和任何其他框架。

一个序数问题的例子

让我们首先找到一个数据集进行测试。我最*写了一篇关于如何预测化学分子的性质的帖子——通常对于这类问题,预测分子性质是否在给定范围内是很有趣的,例如,我们可能在预测不同分子对于给定任务的效率,我们希望将这种效率分为高>中>低

为了测试,我从 GitHub 获取了一个“亲脂性”回归数据集,其中包含 2100 个分子及其相关的亲脂性测量值(在油中的溶解度)。我将数据集转换为多类有序分类问题,目标是将分子分为 5 类:最低<低<中<高<最高。

以下是序数问题的数据分布概述:

左)回归数据集中目标的原始分布。右)左边的数据集转换成五个大小相等的顺序标签,对应最低<低<中<高<最高。由作者策划。

基线模型:正常分类

正如我在上一篇文章中所展示的,很容易为我们的数据集快速训练一个标准分类模型,“标准”,这意味着它是用给定 5 个定义的类的正常交叉熵损失函数来训练的。作为最初的评估,我将数据集分为 50%的训练和 50%的测试,并在测试数据集上运行我的评估。结果如下:

用交叉熵损失训练的模型的混淆矩阵。由作者策划。

它的表现不太稳定;它在划分低等级和高等级方面相当不错,但是对于中等等级就不那么好了。

有序回归模型

现在让我们试着训练一个序数模型;我们使用的技巧是由程等人在 2008 年介绍的。我们的想法是将每个类转换成以下向量:

Lowest  -> [1,0,0,0,0]
Low     -> [1,1,0,0,0]
Medium  -> [1,1,1,0,0]
High    -> [1,1,1,1,0]
Highest -> [1,1,1,1,1]

这个简单编码(或类似的变体)的酷之处在于,类之间的差异遵循一个顺序尺度;即最低最高之差大于最低中等之差。

我们的网络的想法是为每个标签输出一个具有二进制分数的 5 维向量(例如,最终层上的 sigmoid 激活函数),并训练它来预测这些独一无二的嵌入。一旦我们对其进行了训练,我们就可以通过对我们的预测应用大于 0.5 的阈值,并从左到右计数预测中(即代码中)出现了多少个连续的True值,来将预测转换回目标标签:

显示如何将预测转换为目标标签的示例代码。作者代码。

为了训练网络,我们需要一个合适的损失函数。2008 年的论文指出,这可以是二元交叉熵损失,也可以是*方误差损失。要了解误差如何随着类间距离的增加而增加,请考虑以下*方误差函数的情况:

Lowest vs. Lowest: (1-1)²+0+0+0+0 = 0
Lowest vs. Low: (1-1)²+(0–1)²+0+0+0 = 1
Lowest vs. Medium: (1–1)²+(0–1)²+(0–1)²+0+0 = 2
Lowest vs. High: (1–1)²+(0–1)²+(0–1)²+(0–1)²+0 = 3
Lowest vs. Highest: (1–1)²+(0–1)²+(0–1)²+(0–1)²+(0–1)² = 4

损失函数应该以两个参数作为输入,即predictionstargets。在我们的设置中,predictions数组的输入维数是[batch_size × 5],而targets数组只是一个标签 id 列表。为了执行有序回归,我们需要根据我们之前的编码将targets列表扩展为[batch_size, num_labels]张量,并返回预测和扩展目标之间的均方误差损失:

损失函数的代码,它首先对目标标签进行编码,然后计算 MSE。作者代码。

如果我们用这个损失函数重新训练我们的模型,结果是:

用有序损失函数训练的模型的混淆矩阵。由作者策划。

显然,结果看起来比之前的分类运行更“斜”,这表明,事实上,我们更多地惩罚了在序数尺度上偏离几个标签的模型。我们能量化这种方法的效果吗?一种选择是查看标签指数的均方根误差(RMSE ),即我们的预测距离目标大约有多少个类别。在这个测试案例中,分类模型的 RMSE 是 1.06,而顺序模型的是 0.93,提高了 12%!

但是!这只是针对一个数据集的一个随机训练测试分割——为了完整起见,我使用 10 倍交叉验证(CV)对多个数据集和不同数量的标签进行了量化;这应该让我们更现实地了解这两种方法的优劣。折叠外的结果如下,其中我列出了 RMSE 误差的%改进:

顺序训练代替交叉熵训练对 RMSE 的改进。每一列都是一个独立的数据集,分为 3、5、10 或 20 个标签。

在大多数情况下,我们实现了改进,但是偶尔结果是相反的——性能随着顺序损失而降低。怎么会这样呢?除了数据集和我们正在建模的内容的根本差异之外,还有一些潜在的因素浮现在脑海中:

  • 数据集大小;如果我们有一个大的数据集,我们可能对每个标签有足够数量的样本来执行正常分类,交叉熵损失可能比有序损失函数表现得更好。为了测试这一点,我们可以运行相同的 CV,其中我们只从每个数据集挑选 500 个分子(明显少于完整的数据集)。结果(如下所示)好得多;但是,对于某些数据集组合,有序损失函数的性能仍然比多类模型差。天下没有免费的午餐,所以这种序数伎俩显然不能保证奏效。

在只有 500 个分子的数据集上,通过顺序训练而不是交叉熵训练来改善 RMSE。每一列都是一个独立的数据集,分为 3、5、10 或 20 个标签。

  • 排名不一致;如果我们的顺序预测输出[0.9, 0.9, 0.49, 0.72, 0.1]会怎么样。从左到右的迭代将导致预测标签为 2(因为 0.49 < 0.5),即使正确答案也可能是 4(因为 0.72 > 0.5)。我发现在任何预测中几乎没有等级不一致,所以这不是性能下降的原因。

结束语

使用有序目标类时,使用有序损失函数可以快速获得显著的性能提升。然而,没有免费的午餐,我们应该用不同的损失函数训练模型,看看什么对给定的数据集最有效

在 2020 年,Cao 等人在[2]中发表了一种方法,该方法使用神经网络的共享倒数第二层,对每个二进制输出使用单独的偏置单元,以秩一致的方式执行有序回归。他们在这个 Github 库中发布了他们的 Coral 方法。尽管本帖中提出的问题集中没有等级不一致,但我确实尝试在本帖中执行的 CV 测试中使用 Coral,但这些数据集的性能一直较差。这再次表明,没有免费的午餐,一个人应该总是尝试多种事情。

[1] 简麟程郑旺Gianluca Pollastri ,有序回归的神经网络方法(2008 年) IEEE 国际神经网络联合会议

[2]曹,瓦希德米尔贾利利,塞巴斯蒂安拉什卡,秩一致序贯回归神经网络及其在年龄估计中的应用(2020),模式识别字母

如何用 Top2Vec 进行主题建模

原文:https://towardsdatascience.com/how-to-perform-topic-modeling-with-top2vec-1ae9bb4e89dc?source=collection_archive---------3-----------------------

介绍一种更复杂的主题建模方法。

格伦·卡丽在 Unsplash 拍摄的照片

主题建模是自然语言处理中的一个问题,在现实世界中有许多应用。能够在大段文本中发现主题有助于我们更详细地理解文本数据。

多年来,潜在狄利克雷分配(LDA)一直是主题建模最常用的算法。该算法于 2003 年首次推出,将主题视为不同单词出现的概率分布。如果你想看看 LDA 的实际应用,你应该看看我下面的文章,我在假新闻分类数据集上执行了 LDA。

然而,随着 transformer 模型和嵌入算法(如 Doc2Vec)的引入,我们可以创建更复杂的主题模型来捕捉单词中的语义相似性。事实上,一种叫做 Top2Vec 的算法使得使用嵌入向量和聚类建立主题模型成为可能。在本文中,我将展示如何使用 Top2Vec 通过嵌入向量和聚类技术来执行无监督的主题建模。

Top2Vec 是如何工作的?

Top2Vec 是一种算法,它检测文本中存在的主题,并生成联合嵌入的主题、文档和单词向量。在高层次上,该算法执行以下步骤来发现文档列表中的主题。

  1. 为文档和文字生成嵌入向量。
  2. 使用 UMAP 等算法对向量进行降维。
  3. 使用聚类算法(如 HDBSCAN)对向量进行聚类。
  4. 给每个集群分配主题。

我在下面详细解释了每个步骤。

为文档和单词生成嵌入向量

嵌入向量是允许我们在多维空间中表示单词或文本文档的向量。嵌入向量背后的思想是相似的单词或文本文档将具有相似的向量。

一个句子的单词嵌入,每个单词有 5 维向量。图片由作者提供。

生成嵌入向量的算法有很多。Word2Vec 和 Doc2Vec 非常流行,但*年来,NLP 开发人员和研究人员已经开始使用转换器来生成嵌入向量。如果你有兴趣了解更多关于变形金刚的知识,可以看看我下面的文章。

为每个文档创建嵌入向量允许我们将每个文档视为多维空间中的一个点。Top2Vec 还创建了联合嵌入的单词向量,这使得我们可以在以后确定主题关键词。

联合嵌入的单词和文档向量。图片由作者提供。

一旦我们有了一组单词和文档向量,我们就可以进入下一步。

执行降维

在我们有了每个文档的向量之后,下一个自然的步骤是使用聚类算法将它们分成簇。然而,根据所使用的嵌入模型,从第一步生成的向量可以具有多达 512 个分量。

因此,执行某种降维算法来减少数据中的维数是有意义的。Top2Vec 使用一种称为 UMAP(均匀流形逼*和投影)的算法来为每个文档生成低维嵌入向量。

聚集向量

Top2Vec 使用 HDBSCAN(一种基于密度的分层聚类算法)来查找文档的密集区域。HDBSCAN 基本上只是 DBSCAN 算法的扩展,它将 DBSCAN 算法转换为层次聚类算法。使用 HDBSCAN 进行主题建模是有意义的,因为较大的主题可以由几个子主题组成。

聚类文档和单词向量。图片由作者提供。

为每个集群分配主题

一旦我们有了每个文档的集群,我们就可以简单地将每个文档集群视为主题模型中的一个单独的主题。每个主题可以被表示为主题向量,该主题向量实质上就是属于该主题聚类的原始文档的质心(*均点)。为了使用一组关键词来标记主题,我们可以计算与主题质心向量最*的 n 个单词。

主题群和关键词。图片由作者提供。

一旦我们有了每个主题的关键词,算法的工作就完成了,由我们人类来解释这些主题的真正含义。虽然 Top2Vec 比主题建模的标准 LDA 方法复杂得多,但它可能会给我们带来更好的结果,因为单词和文档的嵌入向量可以有效地捕捉单词和短语的含义。

安装 Top2Vec

您可以使用 pip 和以下命令安装 Top2Vec:

pip install top2vec

您还可以安装带有附加选项的 Top2Vec,如 Top2Vec GitHub 库中的 README 文档所示。

为了让 Top2Vec 安装本教程所需的预训练通用语句编码器,您应该运行以下命令。

pip install top2vec[sentence_encoders]

Top2Vec 教程

在本教程中,我将演示如何使用 Top2Vec 在 20 个新闻组文本数据集中发现主题。这个数据集包含大约 18000 个新闻组帖子,涉及 20 个主题。你可以在 GitHub 上访问本教程的完整代码

导入库

import numpy as np
import pandas as pd
from top2vec import Top2Vec

读取数据

对于本教程,我将使用 20 个新闻组文本数据集。这个数据集包含大约 18000 个新闻组帖子,涉及 20 个主题。我们可以通过 Scikit-learn 下载数据集,如下所示。

from sklearn.datasets import fetch_20newsgroupsnewsgroups = fetch_20newsgroups(subset='all', remove=('headers', 'footers', 'quotes'))

训练 Top2Vec 模型

训练 Top2Vec 模型非常容易,只需要一行代码,如下所示。

from top2vec import Top2Vecmodel = Top2Vec(articles_df['content'].values, embedding_model='universal-sentence-encoder')

注意,我使用了上面的通用句子编码器嵌入模型。如果您安装了带有句子编码器选项的 Top2Vec,那么您可以使用这个模型。否则,只需删除该参数,默认情况下,模型将使用 Doc2Vec 嵌入进行训练。

查看主题的数量

一旦 Top2Vec 模型根据数据进行了训练,我们就可以使用 model 对象来获取关于所提取主题的信息。例如,我们可以查看使用 get_num_topics 函数发现的主题数量,如下所示。

model.get_num_topics()

运行上面的代码会产生以下输出。

100

获取每个主题的关键词

Top2Vec 模型有一个名为 topic_words 的属性,它基本上只是一个 Numpy 数组,包含每个主题的单词列表。

model.topic_words

在 Jupyter 笔记本单元格中运行上面的代码会产生以下输出。

array([['recchi', 'potvin', 'nyr', ..., 'pittsburgh', 'binghamton',
        'pitt'],
       ['diagnosed', 'symptoms', 'diagnosis', ..., 'mfm', 'affected',
        'admitted'],
       ['spacecraft', 'jpl', 'orbiter', ..., 'scientist', 'convention',
        'comet'],
       ...,
       ['liefeld', 'wolverine', 'comics', ..., 'requests', 'tickets',
        'lemieux'],
       ['vice', 'pacific', 'bay', ..., 'projects', 'chapter', 'caps'],
       ['armenians', 'ankara', 'armenian', ..., 'discussed',
        'azerbaijani', 'whom']], dtype='<U15')

如果我们想看到特定主题的单词,我们可以简单地索引这个数组,如下所示。

model.topic_words[0]

上面的代码给出了主题 0 的单词列表。

array(['recchi', 'potvin', 'nyr', 'nyi', 'lemieux', 'lindros', 'nhl',
       'phillies', 'defenseman', 'mets', 'ahl', 'jagr', 'bruins',
       'sabres', 'cubs', 'gretzky', 'alomar', 'pitchers', 'pitching',
       'clemens', 'canucks', 'inning', 'henrik', 'innings', 'yankees',
       'oilers', 'utica', 'islanders', 'boswell', 'braves', 'hockey',
       'rangers', 'leafs', 'flyers', 'sox', 'playoffs', 'wpg', 'baseball',
       'dodgers', 'espn', 'goalie', 'fuhr', 'playoff', 'ulf', 'hawks',
       'batting', 'tampa', 'pittsburgh', 'binghamton', 'pitt'],
      dtype='<U15')

正如我们所看到的,这个话题似乎主要是关于体育,尤其是棒球和曲棍球,因为我们看到了流行的棒球队的名字以及曲棍球运动员的姓氏。

创建主题词云

我们可以轻松地为主题生成词云,以便更好地了解主题中关键词的频率。

model.generate_topic_wordcloud(0)

运行上面的代码会产生下面的单词 cloud。

话题 0 的词云。图片由作者提供。

上面的单词云很有用,因为它让我们直观地了解不同单词与主题的相对频率。我们可以看到“费城人”和“雷米尔”这样的词比“季后赛”或“坦帕”这样的词出现的频率更高。

访问主题向量

topic_vectors 属性允许我们访问每个主题的主题向量,如下所示。

model.topic_vectors

正如我们在下面的输出中看到的,Top2Vec 模型的主题向量存储为一个二维 Numpy 数组,其中每一行对应一个特定的主题向量。

array([[-9.1372393e-03, -8.8540517e-02, -5.1944017e-02, ...,
         2.0455582e-02, -1.1964893e-01, -1.1116098e-04],
       [-4.0708046e-02, -2.6885601e-02,  2.2835255e-02, ...,
         7.2831921e-02, -6.1708521e-02, -5.2916467e-02],
       [-3.2222651e-02, -4.7691587e-02, -2.9298926e-02, ...,
         4.8001394e-02, -4.6445496e-02, -3.5007432e-02],
       ...,
       [-4.3788709e-02, -6.5007553e-02,  5.3533200e-02, ...,
         2.7984662e-02,  6.5978311e-02, -4.4375043e-02],
       [ 1.2126865e-02, -4.5126071e-03, -4.6988029e-02, ...,
         3.7431438e-02, -1.2432544e-02, -5.3018846e-02],
       [-5.2520853e-02,  4.9585234e-02,  5.9694829e-03, ...,
         4.1887209e-02, -2.1055080e-02, -5.4151181e-02]], dtype=float32)

例如,如果我们想要访问任何主题的向量,我们可以简单地基于我们正在寻找的主题编号来索引 Numpy 数组。

使用模型的嵌入函数

我们还可以使用 Top2Vec 模型使用的嵌入模型来为文本的任何部分生成文档嵌入,如下所示。请注意,如果在训练 Top2Vec 模型时没有指定嵌入模型,这是不可能的。

embedding_vector = model.embed(["This is a fake news article."])
embedding_vector.shape

运行上面的函数会产生以下输出。

TensorShape([1, 512])

根据上面的输出,我们可以看到嵌入模型将文本转换为 Python 张量对象形式的 512 维向量。

使用关键词搜索主题

我们可以使用关键字搜索主题,如下所示。请注意,该函数返回搜索中找到的每个主题的主题关键字、单词分数、主题分数和主题编号的列表。

topic_words, word_scores, topic_scores, topic_nums = model.search_topics(keywords=["politics"], num_topics=3)

我们可以看看主题单词和主题分数,看看搜索返回了什么主题。

topic_words, topic_scores

上面的代码在 Jupyter 中产生以下输出。

([array(['clinton', 'bush', 'president', 'reagan', 'democratic',
         'republicans', 'elected', 'congress', 'wiretap', 'administration',
         'election', 'johnson', 'politically', 'politicians', 'politics',
         'political', 'executive', 'senate', 'bill', 'constitutional',
         'democracy', 'lib', 'government', 'gov', 'iraq', 'corrupt',
         'convention', 'rockefeller', 'nist', 'ford', 'grant',
         'libertarian', 'nuy', 'govt', 'feds', 'libertarians', 'decades',
         'recall', 'ws', 'bureau', 'bullshit', 'nsa', 'stephanopoulos',
         'weren', 'liar', 'koresh', 'affairs', 'barry', 'conservative',
         'secretary'], dtype='<U15'),
  array(['um', 'ci', 'oo', 'll', 'ye', 'hmm', 'un', 'uh', 'y_', 'wt', 'on',
         'uu', 'actually', 'an', 'eh', 'way', 'des', 'er', 'se', 'not',
         'has', 'huh', 'of', 'ya', 'so', 'it', 'in', 'le', 'upon', 'hm',
         'one', 'is', 'es', 'ne', 'at', 'what', 'no', 'au', 'est', 'shut',
         'mm', 'got', 'dont', 'lo', 'tu', 'en', 'the', 'have', 'am',
         'there'], dtype='<U15'),
  array(['libertarian', 'libertarians', 'govt', 'liberties', 'democracy',
         'democratic', 'government', 'conservative', 'gov', 'republicans',
         'governments', 'liberty', 'constitutional', 'opposed', 'communist',
         'politically', 'advocate', 'citizens', 'premise', 'opposition',
         'patents', 'fascist', 'opposing', 'compromise', 'feds', 'liberal',
         'politicians', 'independent', 'reform', 'johnson', 'philosophy',
         'ron', 'citizen', 'aclu', 'politics', 'frankly', 'xt', 'defend',
         'political', 'regulated', 'militia', 'republic', 'radical',
         'against', 'amendment', 'unified', 'argument', 'revolution',
         'senate', 'obey'], dtype='<U15')],
 array([0.23019153, 0.21416718, 0.19618901]))

我们可以看到题目也是按照题目分值来排序的。相似性得分最高的主题首先显示在上面的第一个列表中。

按主题搜索文档

通过search _ documents _ by _ topic功能,我们可以很容易地找到属于特定主题的文档。这个函数需要一个主题号和我们想要检索的文档数。

model.search_documents_by_topic(0, num_docs=1)

运行上面的函数会产生以下输出。

(array(['\nI think this guy is going to be just a little bit disappointed.  Lemieux\ntwo, Tocchet, Mullen, Tippett, and Jagr.  I buzzed my friend because I forgot\nwho had scored Mullen\'s goal.  I said, "Who scored?  Lemieux two, Tocchet,\nTippett, Jagr."  The funny part was I said the "Jagr" part non-chalantly as\nhe was in the process of scoring while I was asking this question!!! :-)\n\nAll in all ABC\'s coverage wasn\'t bad.  On a scale of 1-10, I give it about\nan 8\.  How were the games in the Chi/St. Louis/LA area???\n\n\nThat\'s stupid!!!  I\'d complain to the television network!  If I were to even\nsee a Pirates game on instead of a Penguins game at this time of the year, I\nand many other Pittsburghers would surely raise hell!!!\n\n\nTexas is off to a good start, they may pull it out this year.  Whoops!  That\nbelongs in rec.sport.baseball!!!'],
       dtype=object),
 array([0.75086796], dtype=float32),
 array([12405]))

我们可以看到上面的文章肯定是关于棒球的,这与我们对第一个话题的解读相吻合。

减少话题的数量

有时 Top2Vec 模型会发现许多小主题,很难处理这么多不同的主题。幸运的是,Top2Vec 允许我们执行分层主题缩减,它迭代地合并相似的主题,直到我们达到期望的主题数量。我们可以将模型中的主题数量从 100 个减少到 20 个,如下面的代码所示。

topic_mapping = model.hierarchical_topic_reduction(num_topics=20)

该函数返回的主题映射是一个嵌套列表,它解释了哪些主题已经合并在一起形成了 20 个更大的主题。

如果我们想查看 topic 1 中的原始主题,我们可以在 Jupyter 中运行以下代码。

topic_mapping[1]

上面的代码产生了下面的合并主题编号列表。

[52, 61, 75, 13, 37, 72, 14, 21, 19, 74, 65, 15]

然而,使用这种映射可能有点乏味,所以 Top2Vec 允许我们访问具有新属性的新主题的信息。例如,我们可以使用 topic_words_reduced 属性来访问新的主题关键字。

model.topic_words_reduced[1]

运行上面的代码为我们提供了以下主题 1 的关键字更新列表:

array(['irq', 'mhz', 'processor', 'sgi', 'motherboard', 'risc',
       'processors', 'ati', 'dma', 'scsi', 'cmos', 'powerbook', 'vms',
       'vga', 'cpu', 'packard', 'bsd', 'baud', 'maxtor', 'ansi',
       'hardware', 'ieee', 'xt', 'ibm', 'computer', 'workstation', 'vesa',
       'printers', 'deskjet', 'msdos', 'modems', 'intel', 'printer',
       'linux', 'floppies', 'computing', 'implementations',
       'workstations', 'hp', 'macs', 'monitor', 'vram', 'unix', 'telnet',
       'bios', 'pcs', 'specs', 'oscillator', 'cdrom', 'pc'], dtype='<U15')

基于上面的关键词,我们可以看到这个话题似乎大多是关于电脑硬件的。

关于 Top2Vec 中可用功能的更多细节,请查看 Top2Vec GitHub 库。我希望这篇教程对你有用。

摘要

Top2Vec 是最*开发的主题建模算法,可能在不久的将来取代 LDA。与 LDA 不同,Top2Vec 生成联合嵌入的单词和文档向量,并对这些向量进行聚类,以便在文本数据中找到主题。开源的 Top2Vec 库也非常容易使用,并允许开发人员在一行代码中训练复杂的主题模型。

像往常一样,你可以在 GitHub 上找到这篇文章的完整代码。

加入我的邮件列表

你想在数据科学和机器学习方面变得更好吗?您想了解数据科学和机器学习社区的最新图书馆、开发和研究吗?

加入我的邮件列表,获取我的数据科学内容的更新。当你注册的时候,你还会得到我免费的解决机器学习问题的逐步指南!你也可以在 Twitter 上关注我的内容更新。

当你这么做的时候,考虑加入媒体社区,阅读成千上万其他作家的文章。

来源

  1. D.M. Blei,A. Y. Ng,M. I. Jordan,潜在狄利克雷分配,(2003),机器学习研究杂志 3。
  2. D.arXiv.org,安杰洛夫, Top2Vec:主题的分布式表示,(2020)。
  3. 长度 arXiv.org,麦金尼斯,j .希利和 j .梅尔维尔, UMAP:一致流形*似和降维投影,(2020)。
  4. C.Malzer 和 M. Baum,(2021),arXiv.org。

如何在数据世界中选择合适的职业

原文:https://towardsdatascience.com/how-to-pick-the-right-career-in-the-data-world-1cec8a084767?source=collection_archive---------10-----------------------

科里·伍德沃在 Unsplash 上拍摄的照片

办公时间

数据科学家,数据分析师,还是数据工程师?你怎么知道哪个适合你呢?

众所周知,数据工程师、数据科学家和数据分析师是当今许多人关注并希望进入的热门角色。普华永道将这三个职位描述为“T6”美国最受欢迎的职位,而数据科学家和数据工程师在 LinkedIn 的 2020 年新兴工作报告中分别排名第 3 和第 8。

这些角色彼此关系非常密切;事实上,许多公司甚至可以互换使用这两个术语。因此,如果你正在考虑进入数据世界,选择正确的角色可能看起来是一项艰巨的任务,伴随着许多问题:没有博士学位,我能成为一名数据科学家吗?想做数据分析师需要懂 Python 或者 R 吗?作为一名曾经从事数据科学家工作,目前从事数据分析师工作,并且在这两项工作中都与许多数据工程师密切合作的人,我将尝试为您打破差异,并为您指出每项工作的正确资源。

概述—高层次的差异和重叠

如果我们粗略地将公司分为两个方面——工程方面和业务方面——我们可以使用下面的文氏图来说明角色与公司任何一方之间的关系和重叠。请注意,这种区别适用于大多数中型和大型公司;然而,在小型创业公司中,这些角色之间的界限变得模糊;很多时候,这些角色可能是所有三种角色的混合。

作者图片

数据工程师是三者中最接*典型工程师角色的,离业务端最远的。数据工程师将大部分时间花在设计、构造、构建和维护数据库上。大多数公司的数据来自很多不同的来源,内部的和外部的;数据工程师的工作是构建和维护数据仓库,使公司的其他部门能够轻松访问和使用数据。不同的数据表如何相互连接?每个表的主键应该是什么?这些是数据工程师在工作中做出的一些决策示例。数据工程师偶尔会与公司的业务部门合作定义表的结构,因为业务团队通常是数据工程师构建的许多表的最终用户。

数据科学家可能是这三个职位中最知名、被提及最多的一个。对这个角色的一个误解是,你必须拥有机器学习或类似领域的博士学位。对于专注于建模和算法的数据科学家来说,这是事实。这些数据科学家(在一家公司的所有数据科学家中约占 30%)通常来自非常强大和高度量化的学术背景,并在高级 ML 主题中具有丰富的理论知识和实践经验。然而,大部分(~70%)的数据科学家来自更加多样化的背景。他们花大部分时间进行与不同业务指标相关的 AB 测试和分析;他们建立的模型可能用于需求预测或特别分析,而不是强化学习或深度神经网络。本文在提到数据科学家时会提到后一类人。

数据分析师在许多公司中与数据科学家互换使用,因为这两个团队都与指标和特别分析密切相关。如果一定要进行区分,那可能是数据分析师更多地致力于业务解释和指标的可视化,而数据科学家则花费大量时间进行统计分析。

重叠在三个角色中很常见。从事数据科学项目的每个人都知道,通常大约 80%的时间花在数据清理上,而回归或分类最终只需要大约 20%,如果不是更少的话。这就是数据科学家和数据分析师与数据工程师密切合作如此重要的原因;他们可以通过在数据进入表格之前预先构建和清理数据,将任何人从坏数据中解救出来。

我对每个项目的数据工程师(GIF by GIPHY )

为了更好地说明这三个角色是如何协同工作的,想象一家公司想要为他们的应用程序的新功能推出 AB 测试;数据科学家将领导确定实验的规模,并决定如何划分对照组和测试组;数据工程师将在后台建立数据库,以确保当 AB 测试启动时,用户活动和事件被记录,并且数据以正确的格式和结构流入数据库。实验结束后,数据科学家和数据分析师将对 AB 测试的结果执行统计分析,深入研究他们关心的一些指标,并为报告目的构建可视化。

技术要求

某种程度的编码技能对这三者来说都是必须的,但是到底什么样的编程语言和什么样的分析*台对每一个都是必须的呢?

GIF by GIPHY

数据工程师是不同数据仓库和云计算*台,以及如何构建提取/转换/加载(ETL)数据管道的专家。他们在日常工作中使用 AWS、谷歌云、雪花和许多其他工具。数据工程师熟悉 SQL 和 Python,有的擅长 C++和 Java。

数据科学家拥有深厚的统计知识,对 SQL、R 和 Python 并不陌生。一个好的数据科学家也知道一些基本的理论上的机器学习算法,以及如何应用它们。

数据分析师是 SQL 方面的专家,拥有实用的统计知识。他们知道如何快速将业务问题转化为分析问题,并利用 Tableau 和 Looker 等工具来构建良好的可视化效果。

其他重要技能

知道如何使用谷歌。说真的,知道谷歌什么,怎么谷歌。你将不可避免地陷入困境,当你陷入困境时,谷歌和 StackOverflow 是你的朋友。

边工作边学习。这与最后一点有些联系。很多人在工作中通过谷歌搜索或与公司的同事交谈来学习。每个公司都有不同的数据库和工具、不同的数据文化(不总是完美的)、工作流和最佳实践;因此,对于公司数据组织中的任何人来说,保持开放并能够在工作中不断学习是至关重要的。

利益相关者管理。所有分析工作最终都将用于推动业务决策。因此,向业务利益相关者解释分析结果和概念,并将它们与业务成果联系起来,是数据人才工作描述的重要部分。优秀的数据人才拥有足够的分析知识,同时拥有商业头脑。

那么,你怎么知道该追求什么样的角色呢?

要回答这个问题,有两个独立的因素在起作用:1 .你想干嘛?第二。根据你目前的技能和经验,你有资格担任什么角色?

你想干嘛?

本文中讨论的三个角色对业务方面有不同程度的暴露,这意味着它们需要不同级别的涉众管理。或者更抽象地说,更多的人际互动和更大规模的会议,这是我们许多内向的分析者所害怕的。但另一方面,更多的商业曝光也意味着对决策者更有形/可见的影响和曝光。

也许这个心理实验会有帮助:回想一下我们的 AB 测试例子;如果你进行彻底的统计分析来解释测试控制组中的偏差或建立模型来避免网络效应污染 AB 测试结果,你会最满意吗(数据科学家)?或者当你花数周时间编写数据管道和调试,但最终像魔术师(数据工程师)一样看到数据流入结构整齐的数据库时?或者,当你密切关注你帮助企业定义的指标时,当你听到你的朋友谈论他们非常喜欢的应用程序新功能时,你知道你的可视化有助于推动决策(数据分析师)。

你能胜任哪个角色?

或者,你有时间为哪个角色培养技能?不考虑你无法改变或弥补的因素,比如多年的经验(幸运的是,大多数与数据相关的角色对背景或学校专业没有严格的要求),职位描述和简历之间的大部分差异可以通过在线课程和面试准备来弥补(我将很快就如何为这些角色准备面试写一篇单独的帖子,敬请关注!).几周的 SQL 和基本 R/Python 在线课程以及麦肯锡式的案例研究实践将帮助你通过面试的技术筛选和商业敏锐度部分,从而为你进入数据分析师职位迈出一步。但是,如果您想为数据工程师角色配备足够的编程和 ETL 知识,或者如果您想成为更高级的数据科学家角色的统计和建模领域的专家,可能需要几个月或几年的时间。

但是好消息是,大多数公司使不同数据角色之间的转换变得非常容易;由于数据技能集的可转移性,你几乎永远也不会陷入错误的职业道路。所以…如果你真的不知道你想要什么样的角色,从任何与数据相关的角色开始,尝试一下,像一个早期的创业公司一样。

试图找出我在数据世界中的位置,就像…(GIF 来自 GIPHY )

如何使用 Python 中的 Geopandas 绘制全球抗生素耐药性数据

原文:https://towardsdatascience.com/how-to-plot-worldwide-antibiotic-resistance-data-using-geopandas-in-python-3be4d03f28ef?source=collection_archive---------42-----------------------

制作信息丰富的 Geopandas 图

Stephen Fordham(作者)使用 Python 中的 Geopandas 库制作的图像

介绍

越来越多的细菌出现了抗生素耐药性。令人担忧的是,对最后手段抗生素的耐药性正在上升。在本教程中,我将演示如何使用 Python 中的 Geopandas 库作为工具来引起全球对抗生素耐药性的关注。为此,我使用了两个数据源:

  1. 抗性评分数据集,其中抗性评分 1 至 3 对应于细菌对最终抗生素的抗性增加。
  2. 来自 ArcGIS 的数据集,包含每个国家的地理坐标。

如何绘制阻力位

目标是获取世界上所有国家的几何信息,并将这些数据与另一个列出全球抗生素耐药性得分的数据源合并。最后,我将演示如何绘制全球抗生素耐药性地图,这将作为一个有用的汇总信息图,有助于检测高和低耐药性区域。此外,通过绘制包括没有可用信息的区域的整个地图,将暴露可能缺乏监控的区域(至少对于此处使用的数据集而言)。

我遵循以下工作流程:

  1. 读入数据集
  2. 代表性提取(消除偏倚)
  3. 数据清理
  4. 合并数据集
  5. 测绘

如果您想访问这里使用的 Jupyter 笔记本,可以在我的 Github 页面上找到。

1.解析数据集:世界各国和抗生素耐药性得分

首先,使用 geopandas read_file 函数读取来源于 rcG 的形状文件。该文件包含与每个国家相关的必要几何信息。生成的对象是一个 geopandas 数据帧,其行为类似于本地 pandas 数据帧。

接下来,我们将使用 pandas read_csv 函数读取阻力分数数据集。我们可以简单地检查数据帧的头部,以确认数据已经被正确解析。我们现在可以创建一个新的列,使用 lambda 函数提取分数,如代码片段所示。我还重命名了这些列,以更准确地反映它们的内容。

2.代表性国家抽样

理想情况下,阻力分数应尽可能提供更多信息。为了实现这一点,明智的做法是对有≥ 10 个分离株的国家进行代表性采样。这将有助于避免我们在以后绘图时引入偏差。这可以通过对 country 列执行 groupby 方法调用并对这个 groupby 对象调用 size 方法来实现。然后,我们可以根据没有应用大小筛选的 groupby 对象进行筛选,对值进行排序,并检索由≥ 10 个隔离区表示的所有国家/地区。下面的代码片段演示了如何实现这一步。

现在我们有了一个代表性国家的列表,我们可以过滤原始 res 数据框架以产生一个新的数据框架,该数据框架对*均耐药性得分进行*均,并且只包括≥ 10 个分离物的国家。

res 数据框架现在在国家和抗性分数之间有一个很好的连接关系。

3.数据清理

我们接下来需要执行一点数据清理。这是必需的,因为有时国家可能有不同的名称。合并时,我们需要一个通用名称,因此包括美国在内的国家信息不会出现在单独的行中,例如一行代表“美国”,另一行代表“美国”。为了识别共享国家和非共享国家,我创建了一个简单的 for 循环,遍历 resistance score 数据帧中的国家。对于不在 geopandas 数据框架 gdf 中的每个国家,它将被添加到名为 different_countries 的列表中。

这两份清单显示了 61 个共同的国家和 6 个在两个数据框架之间不同的国家。我们必须要么删除这些国家,要么重新命名。对于重命名,我们将使用 geopandas 数据框架中的国家名称作为正式名称。

我选择删除条目:“未知”、“加勒比”和“香港”。未知不能被合理地绘制出来,加勒比海不够精确,我选择不把香港和中国捆绑在一起,因为我希望看到 mainland China 单独的阻力分数。这些条目在 res 数据帧中标识,随后使用 pandas drop 方法删除。这可以在下面的结果数据帧中看到,特别是索引 61 和 62 处的行现在缺失。

现在需要更改国名,英国、坦桑尼亚和美国。这包括首先确认它们在 geopandas 数据帧 gdf 中的原始名称。我们可以在 res 数据帧中找到它们的原始名称,并使用 pandas at 方法轻松地更改它们。要使用这种方法,我们只需要与行相关的索引和列名。

4.合并数据帧

最后,我们只需要合并两个数据源,这样我们就有了一个包含每个国家的阻力分数和几何图形的数据框架。为此,我们从 res 数据框架中的国家中过滤 geopandas 数据框架。然后,我们可以将结果对象 data 与相似国家列上的 res 数据帧合并,现在我们有一个名为 res_df 的数据帧,其中包含阻力分数和几何信息。

我们可以在这里停下来,绘制 res_df 数据框架,但是最好包括所有国家,甚至那些没有记录监测数据的国家。

为此,我们使用波浪符号并过滤 geopandas 数据框架 gdf,以查找不在原始 res 数据框架中的国家。我们将这个新的数据帧标记为 others,并将其指定为 a 列,其中阻力分数列为 np.NaN。我们最后将 res_df 和 others 数据帧连接到公共对象 res_geo 中。下面的代码片段演示了这是如何实现的。

注意:可以画 np。在 Geopandas 对象上使用 plot 方法。

合并后的数据帧如下所示。然而,对象 res_geo 是一个 pandas 数据帧,需要转换为 geopandas 数据帧以便绘图。这可以通过实例化 GeoDataFrame 类的实例并将 res_geo 作为参数传递来实现。

5.测绘

我们可以绘制地图,指定图形大小、我们要用于绘制数据的列、颜色映射以及国家之间的边缘颜色和宽度。这产生了一个需要进一步优化的拼凑的情节。

我们已经做了艰苦的工作,创建了资源地理数据库作为数据框架。通过一些小的修改,我们可以极大地改善映射,使其更具吸引力和可解释性。为了改善这一点,我们可以添加一个图例,一个更生动配色方案,包括没有监测数据的国家,并给它们贴上这样的标签,并提供一个合理的标题。

这些变化显示为传递给方法图的参数。如果您对其他颜色映射选项感兴趣,Geopandas 构建所基于的库 matplotlib 有大量颜色字符串可供选择。

摘要

Geopandas 是支持地理绘图的有用工具。对于本教程,我创建了一个 conda 虚拟环境,并按照安装说明在这里通过 conda 安装 geopandas,并在 Jupyter 笔记本中进行在线绘图。如果你感兴趣,我已经创建了一个 Jupyter 笔记本,在我的 GitHub 页面上详细描述了所有这些步骤,在那里也可以找到这两个数据集。虽然这里给出的例子是专门针对抗生素耐药性的,但概述的过程可以作为支持任何其他地理空间绘图的指南。

如何在一个图表中预测和可视化数据

原文:https://towardsdatascience.com/how-to-predict-and-visualize-data-in-one-chart-62901cecbd70?source=collection_archive---------23-----------------------

蒂姆·波格丹诺夫在 Unsplash 上的照片

教程-预测-R

如何使用 R 和 ggplot2 以及线性回归的分步教程

在我最*的一个项目中,我被要求执行一个简单的线性回归来预测可能的价格发展。为了比较实际的价格发展,我们使用消费者价格指数作为基线。本文将向您展示我如何尝试使用不同的数据集来实现这一点——使用 ggplot2 进行绘图,使用线性回归进行预测。

1.设置

我将简要解释我的设置,包括我正在使用的数据和 R 包。

包装

一般来说,我总是使用 Tidyverse 包。它包括像 ggplot2 这样的软件包,以非常直观的方式创建美丽的图形, dplyr 使数据操作如此简单,等等。

此外,我使用了 ggthemes 包,为你的剧情提供了更多开箱即用的主题。

作者图片

啤酒节啤酒价格和通货膨胀指数数据

作为 focus 中的领先价格指数,我使用了世界上最大的啤酒节啤酒节的可用数据。该数据不仅包含啤酒价格信息,还包含游客数量、鸡肉价格和啤酒销量。

作者创建的表(限于三行)

我将使用德国消费者价格指数的可用信息来比较啤酒价格的发展。

消费者价格指数 ( CPI )是衡量经济中消费品服务的总体价格水*的一种方式。”—来源维基百科。

数据本身来自德国联邦统计局的数据库。请注意Verbraucherpreisindex(VPI)是德语的消费价格指数(CPI)。

以 1991 年为基准年的消费者价格指数与啤酒价格一致;作者创建的表(限于三行)

2.我预测和可视化价格发展的工作流程

加入啤酒价格和 VDI 数据

创建线性回归模型

啤酒价格预测;作者创建的表(限于三行)

消费价格预测;由作者创建的表(限于三行)

连接所有数据集

联合数据集(原始数据、预测数据);由作者创建的表(限于三行)

创建一个包括预测和置信水*的线形图

啤酒节啤酒价格的发展与预测:作者创造的形象

啤酒节啤酒价格的发展与预测:作者根据 ggplot2 结果创建的图像

结论

本文向您展示了我如何可视化价格发展,以及我如何使用线性回归模型整合价格预测。当我查看结果时,我看到了两个明显的局限性。

首先,我知道线性回归通常不是价格的最佳预测工具,尽管在这种情况下它可能是合理的(例如,预测每年啤酒节啤酒价格的变化)。尽管我在可视化中包括了误差幅度,但它并没有考虑未来每一年不确定性的增加。而这一点并没有在这个模型中体现出来。我认为有必要研究一下霍尔特-温特斯预测方法和时间序列来应对这个问题。霍尔特-温特斯也考虑到了季节性。

其次,通过包含文本注释来创建可再现的图表会使代码变得非常混乱,难以维护(甚至难以编写)。此外,我不确定情节本身是否不*衡,是否充斥着所有的文本注释。

你认为我可以做些什么来改进这个解决方案?

如有任何问题和意见,请随时联系我。谢谢你。在这里找到更多我的文章:

  1. 学习如何从你的个人资料中创造美丽的艺术作品
  2. 了解我如何获得和分析我的 Garmin 跑步数据
  3. 了解如何为您的 Python 代码设置日志记录
  4. 学习如何使用链接(或管道)在 Python 中编写干净的代码

如何从你的网站日志中预测客户流失

原文:https://towardsdatascience.com/how-to-predict-customer-churn-from-your-website-logs-bb02ea58385a?source=collection_archive---------14-----------------------

实践教程

大规模音乐流媒体服务流失分析和预测实用指南(PySpark 和 Plotly)

照片由布鲁斯·马尔斯Unsplash 上拍摄

简介
如何预测客户流失?
第一步:清理网站日志数据
第二步:将您的网站日志转换为用户日志数据集
第三步:探索两个用户群的数据(流失与停留)
第三步:使用 ML 算法预测客户流失
结论

介绍

许多在线公司从订阅模式中获得很大一部分收入,因此追踪有多少客户停止使用他们的产品或服务是非常重要的。客户流失定义为现有客户取消订阅。如果我们能建立一个模型来预测一个当前客户是否会流失(1)或者不会流失(0),那么公司就可以通过提供更多的促销或者改善服务来防止他们的用户流失。如果你想了解更多关于客户流失的信息,请查看这个博客

在许多面向客户的企业中,Spotify 等音乐流媒体服务可以利用其网站和应用程序上的庞大用户交互数据来预测客户流失。由于网站日志通常是“大数据”,因此使用 Spark 等大数据库来分析它们并预测大规模流失是非常必要的。在本文中,我将从一个高层次的角度来指导您的流失预测项目,并分享一些可视化和预测结果。如果想跳转到实用教程,请查看我的 Kaggle 帖子(复制我的笔记本可以在线玩笔记本)或者 Github 资源库 (fork 或者下载代码到你的本地系统)

你想先看看我的代码吗?请检查我的 Kaggle 笔记本或 Github 库。

https://www.kaggle.com/suhong/a-tutorial-of-customer-churn-analysis-prediction https://github.com/suhongkim/Churn-Prediciton-At-Scale.git

如何预测客户流失?

为了展示如何在实践中建立预测模型,我们将使用从虚拟音乐流媒体公司收集的虚构网站日志数据,该公司名为“Sparkify”,来自 Udacity 的数据科学 Nanodegree。首先,我们需要将这些疯狂的网站日志转换成一个干净的、聚合的用户日志数据集。然后,我们将使用 Plotly 可视化库分析数据集中与客户流失相关的要素。最后,我们将提取有意义的特征,并选择适当的机器学习算法来预测客户流失。让我们开始吧!

第一步:清理网站日志数据

让我们看看网站日志数据集的模式,并检查描述,以了解从网站收集了哪些类型的信息。请注意,粗体列名与客户流失有关,其他列名与网站日志信息有关。

| Column        | Type   | Description                           
|---------------|--------|---------------------------------------- 
| **ts**            | long   | the timestamp of user log                
| sessionId     | long   | an identifier for the current session   
| auth          | string | the authentification log                
| itemInSession | long   | the number of items in a single session 
| method        | string | HTTP request method (put/get)                                   
| status        | long   | http status 
| userAgent     | string | the name of HTTP user agent             
| **userId**        | string | the user Id                             
| **gender**        | string | the user gender (F/M)                         
| **location**      | string | the user location in US             
| firstName     | string | the user first name                     
| lastName      | string | the user last                           
| **registration**  | long   | the timestamp when user registered      
| **level**         | string | the subscription level (free, paid)                                  
| **artist**        | string | the name of the artist played by users 
| **song**          | string | the name of songs played by users
| length        | double | the length of a song in seconds  
| **page**          | string | the page name visited by users** the categories of **page**:  Home, Login, LogOut, Settings, Save Settings, about, NextSong, Thumbs Up, Thumbs Down, Add to Playlist, Add Friend, Roll Advert, Upgrade, Downgrade, help, Submit Downgrade, Cancel, **Cancellation Confrimation**

我删除了一些userId为空的记录,然后添加了一个目标列(churn)和三个额外的列,如下所示。

  • churn(整数):使用Cancellation Confirmation事件为付费和免费用户定义的流失状态(1:流失,0:停留)
  • ds(日期):时间戳数据转换成的日期戳ts
  • dsRestration(日期):从时间戳数据转换的日期戳registration
  • locCity(字符串):来自location数据的城市名称
Below is the sample of new columns
+------+-----+----------+--------------+--------------+
|userId|**churn**|        ds|dsRegistration|       locCity|
+------+-----+----------+--------------+--------------+
|100010|    0|2018-10-08|    2018-09-27|    Bridgeport|
|200002|    0|2018-10-01|    2018-09-06|       Chicago|
|   125|    1|2018-10-12|    2018-08-01|Corpus Christi|
+------+-----+----------+--------------+--------------+

网站日志数据集

第二步:将你的网站日志转换成用户日志数据集

为了预测用户的流失状态,需要为每个用户转换网站日志数据。首先,我们需要丢弃一些与客户流失事件无关的列,比如会话日志和用户名。然后,我们可以基于userId转换数据,有两种类型的数据:用户信息和用户活动。我们的数据中的用户信息列是churngenderlevellocCity,对于每个用户必须是相同的。

+------+-----+------+-----+--------------+
|userId|churn|gender|level|       locCity|
+------+-----+------+-----+--------------+
|100010|    0|     F| free|    Bridgeport|
|200002|    0|     M| free|       Chicago|
|   125|    1|     M| free|Corpus Christi|
+------+-----+------+-----+--------------+

对于用户活动数据,我们需要聚集日志数据来创建一些有意义的特性。我在下面列出了添加到用户日志数据集中的新列。

  • lifeTime (long):用户生存期是用户在网站上存在的时间,数字表示从注册日期到最后一次活动登录日期的天数
  • playTime (double):歌曲播放时间是指用户访问next song页面时,总播放歌曲的*均时间(秒)
  • numSongs (long):每个用户的歌曲名称总数
  • numArtists (long):每个用户的艺术家姓名总数
  • numPage_* (long):每个页面、每个用户的页面访问总数。请注意,CancellationConform cancellation页面不考虑用于特征组,因为它们用于生成churn标签。另外,LoginRegister在我们的数据集中对所有用户都没有计数,所以它们会被自动删除
+--------------+-----------------+--------+----------+-------------+
|lifeTime(days)|    PlayTime(sec)|numSongs|numArtists|    numPage_*|
+--------------+-----------------+--------+----------+-------------+
|            55|318224.4166666667|     269|       252|            1|
|            70|187044.0476190476|     378|       339|            3|
|            72|           1762.0|       8|         8|            0|
+--------------+-----------------+--------+----------+-------------+

用户日志数据集

在开始可视化之前,让我们用几个数字总结一下我们到目前为止所做的工作!

The shape of the raw data: (286500, 18)
The shape of the clean data: (278154, 18)
The shape of the website-log data: (278154, 22)
The shape of the User-Log data(df_user): (225, 26)The number of users (unique userId): 225
The count of churned users (1): 52
The count of Not-Churned users (0): 173The logging period: 2018-10-01 - 2018-12-03

第三步:探索两个用户群的数据(搅动与停留)

将与我们的目标价值相关的特征可视化非常重要,因为我们对客户流失事件背后的机制有更好的直觉。让我们从揭示每月被搅动的用户数量是如何变化的开始(这个小型数据集的记录周期是 2 个月长)

图片作者:苏红·金

总用户数从 10 月份的 213 人下降到 11 月份的 187 人。具体来说,停留用户数略微增加了 4 人,而流失用户数减少了一半以上(10 月份为 55 人,11 月份为 22 人),这表明 Sparkify 服务成功地留住了现有客户。如果我们有更多关于 Sparkify 业务和活动的数据,我们就可以从这一观察中分析什么样的因素会影响更少的客户流失。

图片作者:苏红·金

我们可以观察到男性用户倾向于搅拌更多。

免费订阅级别的用户在请求Submit Downgrade但未到达cancellation confirmation页面时可能处于流失状态—请注意,我们仅在用户访问取消确认页面时定义流失状态。因此,这一类别中的那些过去的订户可以成为营销人员为该网站留住更多用户的主要目标。

图片作者:苏红·金

你可以从上面的散点图中看到的流失率是每个城市中流失用户与人口的比例。由于该数据集是合成的,城市的流失率显示出许多极值,如 0%或 100% ,这导致我们需要为我们的预测模型排除该特征的结论。

到目前为止,我们已经探索了分类特征,如性别、订阅级别和位置(第一个图表“时间分析”只是为了了解被搅动的用户的趋势)。正如您在步骤 2 部分看到的,我们生成了新的数字特征来描述网站上的用户活动。让我们把它们形象化!

图片作者:苏红·金

搅动的用户倾向于比停留的用户具有更短的寿命和歌曲播放时间。

兴奋组倾向于选择种类稍少的歌曲和艺术家(两张图看起来相似,可能有很高的相关性)

图片作者:苏红·金

当我们从原始数据集中的页面列中创建 17 个不同的特征时,我选择了一些重要的特征来在上面的图表中可视化。其中,我注意到页面 **SubmitDowngrade** 与其他页面相比似乎具有离散分布,因此我决定将该特征从预测模型的数值变量更改为分类变量。

第三步:使用 ML 算法预测客户流失

通过可视化,我们最终可以通过修改用户日志数据集来为预测模型选择我们的特征,如下所示。

  • LocCity将从特征集中删除,因为它有许多极值
  • numSongsnumArts高度相关(0.99),因此numSongs将仅被选择用于特征集
  • numPage_SubmitDowngrade将被转换为只有两个值的分类特征page_SubmitDowngrade:已访问或无
  • page栏相关的特征相互之间有很多关联,所以我只选择了 7 个特征:numPage_AboutnumPage_ErrornumPage_RollAdvertnumPage_SaveSettingsnumPage_SubmitDowngradenumPage_ThumbsDownnumPage_Upgrade

图片作者:苏红·金

The schema of df_feat
 |-- userId: string, User Identification Info (not used for feature)
 |-- **label**: integer, the target(Churn) for the prediction model
 <Categorical Features>
 |-- gender: string ('F' or 'M')
 |-- level: string ('paid' or 'free')
 |-- page_SubmitDowngrade: string ('visited' or 'none')
 <Numerical Features> 
 |-- lifeTime: integer 
 |-- playTime: double 
 |-- numSongs: long 
 |-- numPage_About: long 
 |-- numPage_Error: long 
 |-- numPage_RollAdvert: long 
 |-- numPage_SaveSettings: long 
 |-- numPage_SubmitUpgrade: long 
 |-- numPage_ThumbsDown: long 
 |-- numPage_Upgrade: long 

让我们开始使用 Spark 中的 ML 库来构建预测模型的管道。为了更好的交叉验证,我将所有的特征转换和一个估计器合并到一个管道中,并将其送入CrossValidator。管道有三个主要部分。

  1. 特征转换:类别变量将被StringIndexerOneHotEncoder转换成一个热点编码向量。然后,使用VectorAssembler.将分类向量和数值变量组装成密集特征向量
  2. 特性重要性选择:我构建了一个定制的FeatureSelector类,使用一个基于树的评估器只提取重要的特性。这一步是可选的,所以我没有将它用于逻辑回归或 LinearSVC 模型。
  3. 估计器:最后一步是使用 ML 算法来估计每个用户的流失标签。

有了这个管道,我选择了五个不同的估值器来根据 F1 分数选择带有默认参数的最佳算法,因为我们的数据是不*衡的。作为下面的结果,我为我们的预测模型选择了RandomForestClassifier,它显示了最高的验证分数(0.78)。

<The result of the model selection>
--------------------
**LogisticRegressionModel**: numClasses=2, numFeatures=16
train_f1: 0.8275, test_f1: 0.7112
--------------------
**LinearSVCModel**: numClasses=2, numFeatures=16
train_f1: 0.8618, test_f1: 0.7472
--------------------
**DecisionTreeClassificationModel**: depth=5, numNodes=31, numFeatures=7
idx                name     score
0    0            lifeTime  0.439549
1    1            numSongs  0.207649
2    2  numPage_ThumbsDown  0.137043
3    3  numPage_RollAdvert  0.096274
4    4            playTime  0.062585
5    5       numPage_Error  0.045681
6    6       numPage_About  0.011218train_f1: 0.9373, test_f1: 0.7667
--------------------
**RandomForestClassificationModel**:numTrees=20, numFeatures=12
    idx                   name     score
0     0               lifeTime  0.315996
1     1               playTime  0.174795
2     2     numPage_ThumbsDown  0.101804
5     5               numSongs  0.089395
3     3     numPage_RollAdvert  0.080125
6     6        numPage_Upgrade  0.053891
4     4          numPage_About  0.053557
7     7          numPage_Error  0.051073
8     8   numPage_SaveSettings  0.033237
9     9  numPage_SubmitUpgrade  0.024314
11   11            genderVec_M  0.012589
10   10          levelVec_paid  0.009225train_f1: 0.9086, test_f1: 0.7788
--------------------
**GBTClassificationModel**: numTrees=20, numFeatures=11
    idx                   name     score
0     0     numPage_ThumbsDown  0.276418
1     1               lifeTime  0.191477
2     2               numSongs  0.104416
4     4     numPage_RollAdvert  0.080323
5     6          numPage_About  0.074554
9     5          levelVec_free  0.068573
3     3               playTime  0.067631
6     7        numPage_Upgrade  0.050553
7     8          numPage_Error  0.042485
10    9            genderVec_M  0.029921
8    10  numPage_SubmitUpgrade  0.013649train_f1: 1.0, test_f1: 0.7615

最后,我运行了交叉验证来调整RandomForestClassifier的超参数。由于我们的数据集非常小,您可以观察到几乎完美的训练分数,表明模型过度拟合。因此,我选择了一些交叉验证参数映射,以使该模型与我在上述模型选择中使用的默认模型(numTrees=20)相比不那么复杂。结果显示,具有 10 棵树和 16 个最大箱的模型具有稍好的性能,但是没有很好地克服过拟合问题。我假设这个问题可以通过增加更多的数据来解决。

**RandomForestClassificationModel**: numTrees=10, numFeatures=11
**Best parameters**:[('bootstrap', True), ('cacheNodeIds', False), ('checkpointInterval', 10), ('featureSubsetStrategy', 'auto'), **('impurity', 'gini'), ('maxBins', 16), ('maxDepth', 5), ('numTrees', 10)**, ('maxMemoryInMB', 256), ('minInfoGain', 0.0), ('minInstancesPerNode', 1), ('minWeightFractionPerNode', 0.0), ('seed', -5400988877677221036), ('subsamplingRate', 1.0)]
    idx                             name     score
0     0                         lifeTime  0.346846
1     1                         playTime  0.160187
2     2                         numSongs  0.104921
5     5               numPage_ThumbsDown  0.102716
6     6                    numPage_About  0.075681
4     4                  numPage_Upgrade  0.075326
3     3               numPage_RollAdvert  0.048552
7     7                    numPage_Error  0.044421
8     8             numPage_SaveSettings  0.028647
9     9                    levelVec_free  0.009174
10   10  page_SubmitDowngradeVec_visited  0.003529**train_f1: 0.9287, valid_f1: 0.7608 test_f1: 0.7255**

结论

在本文中,我们解决了最具挑战性和最常见的业务问题之一——如何预测客户流失。从令人讨厌的巨大网站日志中,我们提取了每个用户的几个有意义的特征,并基于两个用户组(搅动与停留)将它们可视化,以进行更多分析。最后,我们建立了包括特征变换和估计器的 ML 流水线,它被馈送到交叉验证器用于模型选择和超参数调整。最终模型显示了相当高的测试分数(f1 分数:0.73),但由于小数据集大小(128MB)的限制,它也存在过拟合问题。由于 Udacity 在 AWS cloud 上提供了完整的数据集(12GB ),我有一个计划来部署这个 Spark 集群,以便很快处理过拟合问题。

当然,在不考虑数据大小的情况下,我们可以做很多事情来改进这个模型。首先,不管时间因素如何,大多数特征都是聚合的。日志收集时间为 2 个月,因此最好使用不同的方法(如加权总和)强调最*的日志。此外,我们可以应用一些策略来处理数据不*衡(这个博客将帮助你得到一些想法)。此外,我们可以将这个问题建模为时间序列模型,因为流失率应该定期报告给业务利益相关者。

我希望这个项目能够为您提供一个教程,教您如何使用数据科学和机器学习技能来处理大数据,以解决现实世界中的一个问题。另外,使用 Spark 和 Plotly 库也是很好的练习。感谢您的阅读,并希望通过我的 LinkedIn 随时与您联系!

如何预测 NBA 两双

原文:https://towardsdatascience.com/how-to-predict-nba-double-doubles-f4c30be08ca0?source=collection_archive---------31-----------------------

实践教程

学习在 R 中建立一个逻辑回归模型,预测 NBA 全明星球员尼古拉·武切维奇是否会取得两双。

作者图片。2018 年 3 月 2 日,奥兰多魔术队主场比赛大屏幕上的武切维奇。

逻辑回归模型允许我们基于一个或多个称为预测变量的输入来估计分类响应变量的概率。传统上,响应是二进制真/假值,但也可以是其他组合,如通过/失败,甚至是分类小/中/大。

这篇文章将着重于创建一个模型来预测一个 NBA 球员尼古拉·武切维奇在一场 NBA 篮球赛中获得两双的概率。这将通过提供在 r 中构建逻辑回归模型的必要步骤来演示。

逻辑回归模型目标的一个例子是,在 95%的置信度下,我们可以根据预测变量 X、Y 和 z 在 80%的时间内预测响应变量的结果。百分比将根据测试规格和模型质量而变化。

尼古拉·武切维奇是奥兰多魔术队的全明星中锋。除了为我的家乡球队效力之外,他还是一名在同一支球队长期任职的稳定球员,这使得他的篮球统计非常适合数据科学项目。

在他 10 年的职业生涯中,武切维奇取得了超过 344 次两双。在 NBA,两双的定义是在得分、篮板、助攻、抢断或盖帽这两个类别中得到 10 分或更多。这通常是通过在一场比赛中得到 10 分或更多,10 次或更多的助攻,或者在一场比赛中得到 10 分或更多,10 个或更多的篮板来实现的。

导入数据

构建任何模型的第一步都是获取准确的数据集。Basketball-Reference 跟踪 NBA 球员的数据点,通常是建立预测模型的起点。从一个 玩家的页面获取游戏数据有两种方法。

  1. 使用像 rvest 这样的 R 包来抓取每个赛季的球员数据。
  2. 下载每个赛季的 CSV 文件然后上传到 r。

在 Vucevic 的例子中,你应该有 10 个数据集代表 2012 到 2021 赛季。

一旦游戏日志数据在 R 中,向每个数据集添加一个新列“Season ”,然后使用 rbind()将各个数据集合并成一个“Vucevic”数据集。

#Add Column to Indicate Season
Vucevic2021$Season <- 2021#Use rbind() to Combine Data Frames
Vucevic <- rbind(Vucevic2012, Vucevic2013, Vucevic2014, Vucevic2015, Vucevic2016,Vucevic2017, Vucevic2018, Vucevic2019, Vucevic2020, Vucevic2021)

清理数据

虽然高度准确,但是来自 Basketball-Reference 的数据需要进行一些清理,然后才能在我们的模型中使用它。特别是对于这个数据集,我们需要删除不代表所玩游戏的行,更新缺少的列名,并更新 Location 和 WinLoss 列中的数据值。

#Remove rows that do not correspond to a basketball game.
Vucevic <- Vucevic [!(Vucevic$GS == "Did Not Play" |
                      Vucevic$GS == "Did Not Dress" |
                      Vucevic$GS == "GS" |
                      Vucevic$GS == "Inactive" |
                      Vucevic$GS == “Not With Team”),]#Use the index method to add missing column names
colnames(Vucevic)[6] <-c("Location")
colnames(Vucevic)[8] <-c("WinLoss")

在位置栏中,一个“@”代表客场,空代表主场。稍后,通过将这些值转换为“Away”和“Home ”,我们可以将其转换为 factor 数据类型来测试我们的模型。

#Use an ifelse() to specify “Away” and “Home” games
Vucevic$Location <- ifelse(Vucevic$Location == "@", "Away", "Home")

类似地,WinLoss 列具有遵循“W (+6)”格式的字符值。虽然阅读统计行的人可以将“W (+6)”解释为游戏以 6 分获胜,但对于模型构建来说,WinLoss 列包含“W”或“L”更有用。

#Split the column using str_split_fixed()
Index <- str_split_fixed(Vucevic$WinLoss, " ", 2)#Add the new column to the Vucevic dataframe
Vucevic <- cbind(Vucevic, Index) #Add Matrix to DataFrame#Remove the previous WinLoss column
Vucevic <- Vucevic %>% select(-WinLoss)#Update the new WinLoss column
names(Vucevic)[names(Vucevic) == "1"] <- "WinLoss"#Remove the column containing (+6)
Vucevic <- Vucevic %>% select(-"2")

有些清洁步骤取决于个人喜好。这里我们将“Rk”和“G”变量改为更具描述性的“TeamGameSeason”和“PlayerGameSeason”。

#Update Column Names 
names(Vucevic)[names(Vucevic) == "Rk"] <- "TeamGameSeason"
names(Vucevic)[names(Vucevic) == "G"] <- "PlayerGameSeason"

数据转换

与数据清理密切相关的是数据转换,即将数据从一种数据类型转换为另一种数据类型。对数据建模时,整数、数字和因子数据类型很有帮助。为了理解为什么记住逻辑回归是一个数学公式很重要,其中:

*响应变量=截距+(斜率效率 1 变量 1) +误差

求解数学公式需要使用数字、整数或因子输入。虽然诸如“Home”和“Away”等因子值显示为文本标签,但在 R 中,因子存储为整数。

目前,Vucevic 数据框中的大多数变量都存储为字符文本值。要同时转换多个变量的数据类型,请使用 hablar 库和 tidyverse。

#View the column names in your dataset
colnames(Vucevic)#View the current datatype of an individual column variable
datatype(Vucevic$TeamGameSeason) #Convert variable datatypes 
Vucevic <- Vucevic %>% convert(
                   int("TeamGameSeason", "PlayerGameSeason", "FG",   
                       "FGA", "3P", "3PA", "FT", "FTA", "ORB", 
                       "DRB", "TRB", "AST", "STL", "BLK", "TOV", 
                       "PF", "PTS", "+/-", "PlayerGameCareer"),
                   num("FG%", "3P%", "FT%", "FG%", "FT%", "3P%", 
                       "GmSc"),
                   dte("Date"),
                   fct("Team", "Location", "Opponent", "WinLoss", 
                       "GameStarted"))

创建 Double-Double 响应变量

要预测武切维奇未来是否会取得两双,我们需要计算他过去有哪些比赛取得了两双。

如前所述,两双的定义是在得分、篮板、助攻、抢断或盖帽这两个方面得到 10 分或更多。

一个嵌套的 ifelse()可以用来计算武切维奇在之前的哪些比赛中取得了两双。创建新变量后,我们可以使用 ggplot2 来可视化结果。

#Create a variable that calculates DoubleDoubles
Vucevic$DoubleDouble <- 
                   ifelse(Vucevic$PTS>=10 & Vucevic$AST>=10,TRUE,
                   ifelse(Vucevic$PTS>=10 & Vucevic$TRB>=10,TRUE,
                   ifelse(Vucevic$PTS>=10 & Vucevic$BLK>=10,TRUE,
                   ifelse(Vucevic$PTS>=10 & Vucevic$STL>=10,TRUE,
                   ifelse(Vucevic$AST>=10 & Vucevic$TRB>=10,TRUE,
                   ifelse(Vucevic$AST>=10 & Vucevic$BLK>=10,TRUE,
                   ifelse(Vucevic$AST>=10 & Vucevic$STL>=10,TRUE,
                   ifelse(Vucevic$TRB>=10 & Vucevic$BLK>=10,TRUE,
                   ifelse(Vucevic$TRB>=10 & Vucevic$STL>=10,TRUE,
                   ifelse(Vucevic$BLK>=10 & Vucevic$STL>=10,TRUE,
                   FALSE))))))))))

(作者在 RStudio 中创建的图像)

将数据分成训练集和测试集

在运行我们的模型之前,我们需要将 Vucevic 数据集分成单独的训练和测试数据集。分割我们的数据允许我们使用一组数据来训练我们的模型,使用一组数据来测试模型的效果。

使用 rsample 包指定分层重新采样方法中使用的数据分割和变量。

这里的数据使用 70/30 分割成 VucevicTrain 和 VucevicTest 数据集。然后标识 DoubleDouble 以确保两个数据集中的真/假值比率相似。

#Identifying the split 
set.seed(123)
VucevicSplit <- initial_split(Vucevic, prob = 0.7, strata = "DoubleDouble")#Creating training dataset 
VucevicTrain <- training(VucevicSplit)#Creating testing dataset
VucevicTest <- testing(VucevicSplit)

准备多元逻辑回归

提高模型准确性的一种方法是在进行预测时合并多个变量。以下方法用于确定包括哪些变量:

  1. 确定左侧泄漏变量,并将其从 Vucevic 数据集中移除。
  2. 去掉赛后变量和其他意义不大的。
  3. 使用相关矩阵从 Vucevic 数据集中删除统计上相似的变量。
  4. 创造提供附加值的新变量。

左侧数据泄漏

在回归模型中,响应变量在左边,预测变量在右边。左侧泄漏是指输入到模型中的变量也用于计算响应变量的值。

当预测武切维奇是否会有两双时,我们需要确保预测不是基于任何用来计算两双的变量。

分,篮板,助攻,抢断,盖帽都和我们如何计算两双有直接关系,会被去掉。作为这 5 个变量组成部分的其他变量也需要删除。比如进攻篮板,罚球,罚球尝试。

#Removing left side leakage variables
Vucevic <- Vucevic %>% select(-FG, -FGA, -FT, -FTA, -ORB, -DRB, 
                              -TRB, -AST, -STL, -BLK, -PTS, -GmSc)#Any variable names that start with a number, or include % will need "" to remove
Vucevic <- Vucevic %>% select(-'FG%', -'3P', -'3PA', -'3P%', -'FT%')

移除赛后变量

我们模型的目标是 预测 武切维奇是否会拿下两双。虽然我们可以在比赛后统计失误和犯规次数时这样做,但我们更有可能在比赛开始前使用这个模型。为了说明这一点,我们去掉了所有在游戏结束后才可用的变量。

#Remove post-game variables 
Vucevic <- Vucevic %>% select(-TOV, -PF, -"+/-", -WinLoss)

移除任何其他不太可能影响模型的变量。在这里,分钟和秒非常类似于可变分钟,而年龄则类似于游戏玩家。球员变量从 Vucevic 数据集中删除,因为我们分析的唯一球员是 Vucevic。

#Remove additional variables 
Vucevic <- Vucevic %>% select(-Age, -MinsPlayed, -Player, -Seconds)

确定统计相似变量的相关矩阵

通过创建剩余变量的相关矩阵,我们可以确定是否有任何变量在统计上彼此相似。

(作者在 RStudio 中塑造的形象)

上图显示 TeamGameSeason 和 PlayerGameSeason 之间有很强的相关性,这由两个变量相交的深绿色和 0.97 值表示。

PlayerGameSeason 是以武切维奇一个赛季的出场次数来计算的,TeamGameSeason 是以他的球队一个赛季的出场次数来计算的。如果武切维奇长期或频繁受伤,这些计算将显示更多的变化。既然他们没有,我们可以摆脱任何一个。这里删除了变量 TeamGameSeason。

TeamPHI 和 TeamORL 都会影响多个其他变量。这很可能是因为武切维奇在新秀年只为费城打过球。作为一名新秀,他不太可能首发(GameStarted1),参加过更少的比赛(PlayerGameCareer),也不太可能拿下两双。

我们可以放心地去掉团队变量,因为其他变量将是更好的预测因素。

创建附加变量

现在只剩下四个变量,PlayerGameSeason、Location、GameStarted 和 PlayerGameCareer 来建立多元逻辑回归模型。

虽然我们的模型可能会使用这四个变量,但其他变量可能会提供更好的见解。

  • Back to Back: 使用 mutate()和 lag()创建,表示前一天晚上是否玩了游戏。
  • Conference: 使用东方或西方会议的嵌套 ifelse()创建。
  • ****时区:使用带有 or 运算符的嵌套 ifelse()创建。
#Create New Variable DaysSinceLastGame 
Vucevic <- Vucevic %>%
arrange(Vucevic$Date) %>%
mutate(DaysSinceLastGame = Vucevic$Date - lag(Vucevic$Date))#Create New Variable BackToBack
Vucevic$BackToBack <- ifelse(Vucevic$DaysSinceLastGame == 1, TRUE, FALSE)#Delete DaysSinceLastGame 
Vucevic <- Vucevic %>% select(-Date, -DaysSinceLastGame)

请注意,由于篇幅限制,创建会议和时区变量的代码被截断,仅显示亚特兰大和波士顿。

#Create New Variable Conference
Vucevic$Conference <-  ifelse(Vucevic$Opponent == "ATL", "Eastern",
                       ifelse(Vucevic$Opponent == "BOS", "Eastern",#Create New Variable TimeZone
Vucevic$TimeZone <- ifelse(Vucevic$Location == "Home", "Eastern",
                    ifelse(Vucevic$Location == "Away" &  
                           Vucevic$Opponent == "ATL", "Eastern",
                    ifelse(Vucevic$Location == "Away" &  
                           Vucevic$Opponent == "BOS", "Eastern",

运行多元逻辑回归模型

在测试了逻辑回归模型中七个剩余独立变量的多种组合后,由于独立变量的 p 值较低,选择了以下两个模型进行进一步检验。

#Logistic Regression Model 1
LogisticRegMultiple1 <- glm(DoubleDouble ~ BackToBack +GameStarted 
                           +PlayerGameSeason, family = "binomial", 
                           data = VucevicTrain)#Logistic Regression Model 2
LogisticRegMultiple2 <- glm(DoubleDouble ~ +GameStarted +BackToBack 
                           +PlayerGameSeason +PlayerGameCareer, 
                           family = "binomial", data = VucevicTrain) 

(图片由作者在 RStudio 中创建)

(图片由作者在 RStudio 中创建)

通过在评估阶段测试这些模型,我们可以进一步评估多个模型的准确性。

评估多元逻辑回归模型

由于我们的总数据集的样本大小只有 621 个游戏,基于测试数据集的 30%中的特定游戏,单个测试数据集的验证可能会有很大差异。

k 重交叉验证是一种重采样方法,将训练数据随机分为 k 组。它在 K-1 个折叠(也称为组)上拟合模型,然后被遗漏的组用于测试性能。这意味着它测试模型 K 次,*均 K 测试误差是交叉验证估计值。

#Convert response column to factor if necessary  
Vucevic$DoubleDouble <- as.factor(Vucevic$DoubleDouble)
class(Vucevic$DoubleDouble)#Example of K-fold Cross Validation Model 
set.seed(123)
cv_model3 <- train(
  DoubleDouble ~ TeamGameSeason +PlayerGameSeason +GameStarted +PlayerGameCareer +BackToBack, 
  data = Vucevic, 
  method = "glm",
  family = "binomial",
  trControl = trainControl(method = "cv", number = 10), 
  na.action = na.exclude)#Compare 3 Models 
summary(resamples(list(
      model1 = LogisticRegMultiple1, 
      model2 = LogisticRegMultiple2, 
      model3 = cv_model3)))$statistics$Accuracy

(图片由作者在 RStudio 中创建)

虽然 59%、60%和 59%的*均模型分数表示弱模型,但是可以使用混淆矩阵进一步评估这些模型。

从下面的矩阵中我们可以看到,当武切维奇拿下两双(参考正确)时,该模型预测武切维奇不会拿下两双(预测错误)的可能性几乎与他会拿下两双(预测正确)的可能性一样大。

虽然这个模型在预测武切维奇不会得到两双时更加准确,但它仍然只有 68%的准确率。

# predict class
pred_class <- predict(cv_model3, Vucevic, )# create confusion matrix
confusionMatrix(
  data = relevel(pred_class, ref = "TRUE"), 
  reference = relevel(Vucevic$DoubleDouble, ref = "TRUE"))

(作者在 RStudio 中创建的图片)

结论

在这里,最准确的逻辑回归模型只能预测武切维奇是否会在*均 61%的时间里拿下两双。

虽然这种模式并不是压倒性的,但统计数据仍然显示,与机会相比,它是成功的。在不使用任何信息的情况下,电脑猜对了武切维奇是否会有 54.74%的几率拿下两双。逻辑回归模型的准确率为 61.32%,比随机猜测的准确率提高了 6.5%。

虽然模型的准确性并不惊人,但通过观察 p 值,我们可以确定比这更极端的观察结果预计只会在 1000 万次试验中随机出现 5254 次。

因此,在 95%的信心下,我们可以预测尼古拉·武切维奇是否会在 61%的时间里获得两双,这是基于 TeamGameSeason,player gamesasonage,GameStarted,PlayerGameCareer 和 BackToBack 的预测变量。

未来分析

每位数据科学家将使用略有不同的变量和方法来创建模型。在这个例子中,我们创建了一个变量 BackToBack。如果您的数据集没有该变量,您的模型结果将会不同。

同样,每个 NBA 球员都有不同的比赛风格,受相同变量的影响也不同。有些人在主场或对阵前球队时表现明显更好。其他人在背靠背的第二个晚上或在特定时区表现不佳。这种变化意味着每个 NBA 球员都将有一个独特的逻辑回归模型来预测他们是否会得到两双。

为了提高准确性,我们可以从额外的数据集中整合其他变量,或者通过纳入其他参与者来扩大观察的数量。

扩大观察数量的一个例子是包括奥兰多魔术队任何现任成员参加的所有 4,555 场 NBA 常规赛。

然后在 95%的置信度下,我们可以根据预测变量 player、Season、PlayerGameSeason、GameStarted 和 PlayerGameCareer 来预测奥兰多魔术队的球员是否会在 90%的时间里获得两双。

如果你发现一个 NBA 球员或变量组合增加了逻辑回归模型的准确性,请在下面发表评论。

有关获取数据集的更多信息,请查看我的另一篇文章:

**https://medium.com/@ajpiter/web-scraping-nba-all-star-data-8788a7136727 **

如何预测没有数据的事物——还有盆景树

原文:https://towardsdatascience.com/how-to-predict-something-with-no-data-and-bonsai-trees-b6ebc6471da3?source=collection_archive---------22-----------------------

在日常生活中,我们经常不得不在没有数据的情况下做出预测。这里有一些更好的猜测方法。

托德·特拉帕尼在 Unsplash 上的照片

在生活中,你常常不得不用很少或没有数据来预测事情。或者只是你将知道人口的分布,仅此而已。例如,你在圣诞节收到的一棵盆景树出现在尴尬的家庭聚会上的概率有多大?

在本文中,我将简要讨论一些来自统计数据的深刻见解,这些见解将有助于您回答这些问题。我并不承诺预测未来,我只是要向你展示我们所拥有的最好的技术,尽管我们缺乏数据,但这些技术通常会产生令人惊讶的好结果。

以下灵感来自布莱恩·克里斯蒂安和汤姆·格里菲斯的《 算法靠 》中的一章。

预测盆景树的寿命——哥白尼原理

你的陌生叔叔送了你一棵盆景树,这显然是一份恐慌性购买的圣诞礼物。它甚至没有护理手册或说明书。他们显然对盆景树一无所知。你也不知道,但是你知道他们因为一件事而出名——死亡。

因此,就像一个优秀的(有点虐待狂的)数据科学家一样,你的思维会立即试图预测它的死亡。问题是,你只知道这棵树已经 4 岁了。你不知道盆景树能活多久,你也不知道它们决定放弃生存意志的原因。那么,你究竟是如何预测的呢?

在一个理想的大数据世界中,你将拥有数百万棵盆景树的海量数据集,你将拥有足够的盆景知识,能够从你自己的潜在自杀小朋友那里提取特征。然后,你可以运行一些机器学习模型,并很好地预测你的小家伙会活多久。但是,你没有丰富的数据。

那么你能做什么呢?

进入哥白尼和约翰·理查德·戈特三世。

天体物理学家理查德·戈特三世(Richard Gott III)在 1969 年站在那里凝视着柏林墙并思考它会持续多久时,第一次想到了他的“哥白尼方法”。戈特提出理论,认为哥白尼原理适用于一无所知的情况;除非他的访问有什么特别之处(他并不认为有),否则他有 50%的可能在生命的前半段之后看到长城,有 75%的可能在第一季度之后看到长城。

基于它在 1969 年的年龄(8 岁),Gott 离开长城时有 50%的信心认为它在 1993 年不会在那里(1969 + 8 (1.5/0.5))。

因此,我们可以将同样的逻辑应用于我们的盆景树。根据其年龄(2021 年为 4 岁),我们可以使用 Gott 逻辑得出类似的结果——(2021+4)*(1.5/0.5)。

因此,我们可以满怀信心地期待,我们的小朋友将会在 2033 年重返故土。

然而,50%置信区间不是很有用,是吗?那么,如果我们提高到 95%的标准置信度会发生什么呢?我们得到的结果表明,95%的人相信我们的盆景能够存活 0.1 至 36 年。

如何提高你的猜测能力

哥白尼原理实际上只是对 T4 贝叶斯法则的一种适应,即所谓的无信息先验(我们对盆景生命的潜在分布一无所知)。

显然,如果我们知道盆景预期寿命的潜在分布,我们可以做出更好的猜测。

盆景树遵循所谓的 幂律分布 幂律分布是一种允许多尺度的分布。盆景可以活一个月、一年、十年、一个世纪甚至几千年。当将贝叶斯定律应用于幂律分布时,适当的预测策略是乘法规则,其中您将经过的时间乘以一个常数因子。在哥白尼原理的例子中,这个常数将是 2。因此,如果您之前没有任何信息,也不知道它的分布,那么您应该猜测您的盆景应该一直活下去。

当应用贝叶斯定理时,许多其他分布具有不同的最佳预测策略。例如,正态分布需要一个*均值规则,如果盆景低于*均值,您应该预测*均值,如果盆景超过*均值,您应该预测稍长一点的时间。

对日常生活的影响

那么,这对日常生活意味着什么呢?事实证明,一般来说,人类非常擅长使用正确的预测规则。格里菲斯和特南鲍姆在一项实验中强调了这一点。他们将人类直觉与应用贝叶斯法则的真实世界数据进行比较,发现结果非常接*。

因此,在万不得已的情况下相信自己的直觉是有意义的——如果真的没有数据的话。可能没有任何数据,但是你的大脑已经通过潜移默化发展了自己对分布的理解。

“小数据是伪装的大数据”。

—布莱恩·克里斯蒂安和汤姆·格里菲斯

然而,你固有的前科是提供给你的信息的函数。因此,要想做出更好的预测,你只需在对世界的理解上消息灵通且不带偏见。

在算法向你提供你想看的耸人听闻的新闻的现代,让你的新闻输入多样化是有意义的,正如克里斯蒂安和格里菲斯所说,关掉新闻甚至可能是一个好主意。

如果你在圣诞节收到了一个盆景,只要谷歌一下如何照料它就行了。

感谢阅读,我希望你喜欢它。我的一些其他文章的链接可以在下面找到。

If I’ve inspired you to join medium I would be really grateful if you did it through this [link](https://jamesasher4994.medium.com/membership) — it will help to support me to write better content in the future.If you want to learn more about data science, become a certified data scientist, or land a job in data science, then checkout [365 data science](https://365datascience.pxf.io/c/3458822/791349/11148) through my [affiliate link.](https://365datascience.pxf.io/c/3458822/791349/11148)

干杯,

詹姆斯。

Python 中的时间序列预测

原文:https://towardsdatascience.com/how-to-predict-your-step-count-for-next-week-a16b7800b408?source=collection_archive---------8-----------------------

基于 ARIMA 模型的端到端时间序列预测

林赛·亨伍德在 Unsplash 上的照片

自从 Covid 和封锁开始以来,自由行走对包括我自己在内的许多人来说都是一种奢侈。就我个人而言,我每天都试图离开我的笔记本电脑,出去呼吸一些新鲜空气。每周,我都会从手机上查看我的步数,看看我是否做了足够的锻炼。

如果我们能准确预测下一周的步数,那该多好啊!

在本文中,我将使用基本的时间序列分析来观察自己的步数趋势,并使用历史步数预测未来。本文的主要目的是展示时间序列预测的主要思想,并使用我自己的步数作为实际的编码示例。

我们使用的数据

我正在使用从我的 iPhone 苹果健康下载的步数数据。如果您也使用 iPhone,您可以从 Apple Health application 个人资料页面下载健康数据,如下所示

截图来自苹果网站

下载的数据将是一个 XML 文件,包含 Apple Health 的多个部分,包括步数、心率、睡眠分析等。我利用链接中的脚本将 XML 文件转换成 CSV 格式进行分析。文件的输出将是多个 CSV 文件,您可以使用 Python 直接连接到 CSV 文件。它也是 一个有趣的数据源,供您使用自己的健康数据探索其他数据分析或数据可视化方式

数据探索

步数数据看起来像下面的截图,其中包含每次移动时的步数数值。它还包含开始日期、结束日期和创建日期。这里的创建日期是指该记录的创建日期和时间,因此我使用开始日期来记录时间。

步骤计数的原始数据

对于我的分析,我只需要“开始日期”和“值”两列。对我来说,第一步是将日期列转换成日期时间格式,然后将数据汇总成每周总和。这是因为许多 python 函数或时间序列包需要一个时间格式的列,如果我预测每天的数据,波动性会太高。

#read data from extracted csv
steps=pd.read_csv('apple_health_export/StepCount.csv')#convert start date into time format
steps['date']=pd.to_datetime(steps['startDate'].str[:19])#Aggregate data into weekly sum
sample=steps[['date','value']]
weekly=sample.resample('W', on='date').sum()#visualize weekly data
weekly.plot(figsize=(15, 6))
plt.show()

每周步数的可视化

从上面的可视化中,我们可以看到,即使是每周的步数数据也有很高的波动性。为了消除像每周 300k 步数或每周少于 2000 步这样的极值的影响,我使用 winsorization 使数据更正常。

Winsorization:通过将极值限制在某个界限内来消除异常值的影响,从而对数据进行转换。

我不直接在每周级别上 winsorize,而是限制在每天的步数级别上。例如,如果我一天走得太多,每天的步数将被降低到上限值,然后我将这些 winsorized 每天的步数再次汇总到每周的总数中。

我选择的边界限制是更高的 2%和更低的 2%(这个百分比值可以由我们根据数据的分布来确定)。我使用了‘winsorize’Python 包,在其中你可以直接指定百分比的上限和下限。

#remove the first part of data with no steps
sample=steps[steps['date']>'2015-09-01'][['date','value']]#aggregate data on daily level
daily=sample.resample('D',on='date').sum()#Winsorize daily data
daily['winsorized_value']=winsorize(daily['value'], limits=[0.02, 0.02])#Aggregate daily data into weekly data again
weekly=daily.resample('W').sum()
#visualize new weekly data
weekly.plot(figsize=(15, 6))
plt.show()

winsorized 步数的可视化

您可以从上面的可视化中看到,winsorized 数据具有较少的极值,因此为我们提供了一个更通用的部分。然而,有一点需要注意的是这个*滑步骤不是强制性的,因为大多数时间序列方法会有一些其他的*滑步骤。

您还可以通过使用 季节性 _ 分解 查看季节性模式和总体趋势。这里的趋势是由移动*均确定的,然后在从原始数据中去除趋势后提取季节性元素。

extract=train.set_index('date')
from pylab import rcParams
rcParams['figure.figsize'] = 18, 8
decomposition = sm.tsa.seasonal_decompose(extract, model='additive')
fig = decomposition.plot()
plt.show()

季节和趋势元素

从上图可以看出,步数中有一些轻微的季节性因素。总体趋势有一个强烈的变化,特别是从 covid 时期开始以来。

时间序列预测

研究完数据后,我们可以使用不同的时间序列预测方法开始预测。

问题陈述:根据历史步数数据预测下周步数有多准确?

数据准备:步骤与正常的机器学习训练-测试拆分略有不同。这是因为训练数据和测试数据是动态的取决于您预测的周(我们使用该周之前的所有历史数据作为训练数据)。我们使用 2021 年的步数作为基准来衡量我们模型的准确性。

#determine training and testing group
data=weekly.reset_index()
test=data[data['date']>'2021-01-01'][['date','value']]
train=data[['date','value']]

我们将使用*均误差(MAE)来衡量所有模型的准确性。您也可以选择“均方误差”、“均方根误差”或“*均误差百分比”进行测量。如果想了解更多关于度量回归或预测模型的内容,可以参考这里的。

方法 1:移动*均线

移动*均线仅仅意味着前 X 个周期的*均值,X 由你来决定。这是时间序列数据最常用的技术/概念之一。它可以帮助*滑数据趋势,从而给你一个更真实的结果*似值。

在我的例子中,我使用的是过去 10 个时间段的移动*均值,这意味着我认为步数主要受前 10 周的步数影响。您可以选择使用不同的号码。移动*均线中使用的常见时间段为 10、20、30、50、100 ,具体视场景而定。

#get rolling moving average for previous 10 weeks
data['SMA_10']=train['value'].rolling(window=10).mean().shift(1)#Measure the MAE for this measure
test=data[data['date']>'2020-12-31']
from sklearn.metrics import mean_absolute_error
print(mean_absolute_error(test['value'], test['SMA_10']))
#10415.972

方法 2:指数加权移动*均

方法 1 移动*均线是过去 10 周的简单*均值。你可能想说离预测日期越*的那一周应该有更大的权重,而不是简单的*均值。这时我们可以使用指数加权移动*均线。

指数加权移动*均给予较*的数据较大的权重,权重的分配遵循指数逻辑。让我们看看它与简单的移动*均线方法相比表现如何。

#Calculate ewm average value
data['ewma_10']=train['value'].ewm(span=10).mean().shift(1)test=data[data['date']>'2020-12-31']
from sklearn.metrics import mean_absolute_error
print(mean_absolute_error(test['value'], test['ewma_10']))
#9613.11

与简单移动*均相比,指数加权移动*均给出了更低*均误差的更好结果。

test_plot_data=test.set_index('date')[['SMA_10','ewma_10']]
train_plot=train[train['date']>'2020-01-01'].set_index('date')
plt.figure(figsize=(15,10))
plt.plot(train_plot,label='Actual Step')
plt.plot(test_plot_data['SMA_10'],label='sma_10')
plt.plot(test_plot_data['ewma_10'],label='ewma_10')
plt.legend(loc='Left corner')
plt.show()

简单移动*均线与指数加权移动*均线

如果绘制两个预测值与实际步数的关系图,可以看到两种移动*均法的预测值都比实际步数*滑得多。与简单移动*均线(红线)相比,指数加权移动*均线(黄线)更快地捕捉到趋势,并且更接*真实步数。

方法 3: SARIMA 模型—手动调谐

萨里玛模型是具有季节性趋势的 ARIMA 模型。ARIMA 模型的全称是自回归综合移动*均。在我开始介绍这个方法之前,让我们快速浏览一下 ARIMA 到底是什么,以及我们在建模时考虑了哪些因素。

快速总结:

自回归/AR: 输出预测依赖于先前的观测值/滞后观测值

Integrated/I: 数据不是*稳的,它需要一定阶的差分来实现*稳性

移动*均/移动*均:输出预测取决于之前的误差项/滞后误差

对于 SARIMA 模型,您需要指定 7 个不同的参数:

  • p:AR 项的滞后数
  • d :达到*稳所需的差分次数
  • q:MA 期限的滞后数
  • 季节性周期。指同一模式再次出现的时间周期数。
  • P,D,Q :与 P,D,Q 相同,但为季节性参数

网上有文章介绍我们如何根据对数据的观察来确定不同的参数。对于这个方法,我使用的是来自 statsmodel 的包。

对于您运行的每个模型,您可以有一个结果摘要和一个 AIC 值来衡量模型的样本内适合度。我对所有参数使用不同值的迭代,找出最低的 AIC 值 e(样本内数据的最佳拟合模型)。我是从这里的链接学到这个方法的。

# Define the p, d and q parameters for value between 0-2 and iterate for all the value in the range
p = d = q = range(0, 2)
pdq = list(itertools.product(p, d, q))# Generate all different combinations of seasonal p, q and q 
seasonal_pdq = [(x[0], x[1], x[2], 4) for x in list(itertools.product(p, d, q))]params=[]
seasonal=[]
aic=[]
for param in pdq:
    for param_seasonal in seasonal_pdq:
        mod = sm.tsa.statespace.SARIMAX(train_set,order=param,                                 seasonal_order=param_seasonal,                                    
enforce_stationarity=False,                                          enforce_invertibility=False)#append all the parameters and result AIC value
results = mod.fit()
        params.append(param)
        seasonal.append(param_seasonal)
        aic.append(results.aic)
parameter_options=pd.DataFrame({'params':params,'seasonal_params':seasonal,'AIC':aic})#sort the AIC value to find the best fitted model
parameter_options.sort_values(by='AIC')

ARIMA 模型参数和分类 AIC

从上面的结果中,我们可以看到性能最好的几个参数集。但是,这并不一定等于预测的最佳参数集,因为样本外精度可能与样本内精度有很大不同。你可以参考这个列表,试着找出最合适的型号。

data_updated=data.set_index('date')
train=data[data['date']<'2021-01-01']
prediction=[]
my_order = (0, 1, 1)
my_seasonal_order = (1, 0, 1, 4)
initial=len(train)initial_train=data_updated.iloc[:initial]
model = sm.tsa.statespace.SARIMAX(initial_train['value'], order=my_order, seasonal_order=my_seasonal_order)
results=model.fit()#Iteratively update the training data and predict following week
for i in range(initial,len(data)):
    updated_data=data_updated.iloc[i:i+1]['value']
    results=results.append(updated_data,refit=False)
    prediction.append(results.forecast()[0])from sklearn.metrics import mean_absolute_error
print(mean_absolute_error(test['value'], prediction))#8469.6746

该模型的性能比两个移动*均结果好得多,*均误差值减少了 15%。

方法 4:自动 ARIMA(自动调整参数)

方法 4 使用相同的 ARIMA 模型,但是具有提供自动调谐功能的不同的封装。我使用的是 pm.auto_arima 包,你可以通过链接了解更多关于这个包的功能。

和前面的方法一样,你需要确定所有参数的取值范围。您也可以在您的步进参数中指定是使用步进还是网格搜索。如果没有设置 stepwise=True,默认情况下它会使用网格搜索,这可能会很慢。

train_index=train.set_index('date')#Spesify the value range for parameters
model = pm.auto_arima(train_index['value'], 
                          start_p=0, start_q=0,d=1, max_p=5, 
                          max_q=5, start_P=0, D=None, start_Q=0, max_P=5, 
                          max_D=5, max_Q=5,stepwise=True,seasonal=True)prediction=[]#Recurrently predict following week and add the data into training model once we have predicted that week
for i in test['value']:
    predict=model.predict(n_periods=1)[0]
    prediction.append(predict)
    model.update(i)
from sklearn.metrics import mean_absolute_error
print(mean_absolute_error(test['value'], prediction))
#8863.74

该模型有一个更新功能,允许我使用动态的历史数据循环计算下一周的数据。有趣的是,最终结果比手动调优方法的错误数略高,这可能是由于分步方法或不同软件包之间的算法略有不同。

SARIMA 手动调谐与自动调谐

当我绘制这两种 SARIMA 方法的预测图时,我可以看出这两种方法比简单或指数加权移动*均方法更接*实际步数趋势。然而,SARIMA 模型也不能非常准确地捕捉波动。误差率范围在 20–30%之间。

结论或建议

  1. 在本例中,我对以下一周的值进行递归计算。但是,您很可能需要使用历史数据来预测接下来 N(N>1)周的值。这实际上要简单得多,因为一旦得到模型,您可以将 n_periods 指定为您想要预测的时间段的数量(不需要迭代地更新模型)
  2. 网上有文章介绍如何确定数据是*稳的,或者我们如何使用统计方法(如“扩展的 Dickey Fuller 测试”)来确定 AR 和 MA 项的值。这可以更好地确定数据的分布并防止过度拟合。
  3. 萨里玛或 ARIMA 方法通常比简单移动*均或指数加权移动*均方法更好,因为它考虑了误差项
  4. 需要注意的一件非常重要的事情是,我们应该始终记住使用我们预测的日期之前的数据作为训练数据,这对我们来说很难使用交叉验证。

最后,最后的结论是:在高精度水*上预测步数真的很难!

参考或推荐阅读

  1. https://www . digital ocean . com/community/tutorials/a-guide-to-time-series-forecasting-with-arima-in-python-3(如何使用最低 AIC 选择 ARIMA 参数)
  2. https://www . machine learning plus . com/time-series/ARIMA-model-time-series-forecasting-python/(如何统计确定参数值)
  3. https://github . com/markwk/QS _ ledger/blob/master/apple _ health/apple _ health _ extractor . ipynb。(从 Apple Health 提取数据的代码)
  4. https://towards data science . com/what-the-best-metrics-to-evaluate-your-regression-model-418 ca 481755 b(如何评估你的回归模型)
  5. https://www . stats models . org/dev/generated/stats models . TSA . statespace . sarimax . sarimax . html(SARIMA 模型包,手动调优)
  6. https://alkaline-ml . com/pmdarima/modules/generated/pmdarima . ARIMA . auto _ ARIMA . html(SARIMA 模型包,自动调优)

感谢阅读!如果你有任何问题或任何你想了解更多的话题,请把它们放在评论框里!

如何为信用风险建模准备数据

原文:https://towardsdatascience.com/how-to-prepare-data-for-credit-risk-modeling-5523641882f2?source=collection_archive---------6-----------------------

介绍使用房地美单户贷款级别数据集的违约概率和转移矩阵分析

艾萨克·史密斯在 Unsplash 上拍摄的照片

信贷风险衡量借款人无法偿还债务从而违约的概率。信用风险建模在银行业中被广泛用于多种应用:从承销、账户管理(如扩大信用额度)、信用备抵(GAAP 下的 CECLIFRS-9 )、压力测试( CCAR )和监管资本计算(巴塞尔 II )。

信用风险度量有两个关键组成部分:1)违约概率(PD),通常定义为一段时间内违约的可能性;2)违约损失(LGD),通常指借款人违约后无法收回的金额。这两个分量的乘积给出了预期损耗。

在本文中,我们将使用房地美单户贷款级别数据集作为示例,向您展示如何准备开发数据(包括目标变量和贷款级别特征)以应对任何信用风险建模练习。让我们开始吧。

数据下载

房地美提供公共访问(需要免费注册)该机构从 1999 年到 2020 年购买的单户抵押贷款的贷款级别数据集。数据集是按季度年份组织的。在每个年份中,它包括两个文件:

  1. 发起数据:包含发起时的贷款特征(如期限、利率、信用评分、贷款价值比、债务收入比等)。)
  2. 绩效数据:包含贷款级月度绩效(包括未偿余额、拖欠状态等。)从发起到最*一个季度。

由于数据集是一个“活的”文件,新的演奏会定期添加到每个 vintage 文件中,并且鉴于此数据集的庞大数量,您可能需要编写一个自动下载代码(如下例所示)来从网站检索数据:

#Specify login credentials
login = {
 ‘username’: ‘[y](mailto:xuzhangsusan@gmail.com)our login email’,
 ‘password’: ‘your password’
}#Define the vintage data to download (for this article, we will look into vintage from Q1 2014 to Q2 2019.
Period = ["Q12014","Q22014",...,"Q22019"]with requests.Session() as s:
   p =s.post('[https://freddiemac.embs.com/FLoan/Data/download2.php'](https://freddiemac.embs.com/FLoan/Data/download2.php')) for Qtr in Period:
        #File Names
        zip_file = "historical_data1_" + Qtr + ".zip"
        perf_file = "historical_data1_time_" + Qtr + ".txt"
        orig_file = "historical_data1_" + Qtr + ".txt"
        export_file = Qtr + ".csv"
        r = s.get(os.path.join(Download, zip_file))
        z = zipfile.ZipFile(io.BytesIO(r.content))
        z.extractall(Input_Data_Path)

了解贷款特点

由于许多贷款级别特征是信用损失预测的主要驱动因素(例如,低信用评分或低收入群体通常更容易受到经济状况的影响,从而导致违约),在下载 vintage 文件后,第一步是使用帐号作为唯一关键字合并原始数据和绩效数据。合并之后,现在我们可以看看投资组合概况和特征分布。

作者图片—房地美抵押贷款发放量(计数)

LTV 始发配送

按作者分类的图片——贷款发放时的 LTV 分布(2014 至 2019 年份)

始发时的 FICO 分数分布

按作者分类的图片—贷款发放时的 FICO 得分分布(2014 年至 2019 年)

创建默认标志

如果你是第一次进行信用分析,你可能会惊讶于“违约”的定义并不像你想象的那么明显。在大多数情况下,“违约”是无法直接观察到的。对于初学者来说,当谈到信用风险建模中的违约定义时,有两个最常见的误解:

违约是否相当于到期前 零余额

不,有许多原因可以导致贷款余额在到期日之前减少到零。自愿提前还款是最常见的一种,还有回购、REO 处置等。

默认是否等同于 销账

不,当债务不太可能收回时,贷款人可以从资产负债表中冲销债务金额。但是,在贷款严重拖欠(如 6 个月没有付款)后,可能会在更晚的日期进行注销。因此,将冲销作为违约无法捕捉实际的“违约”时间。也就是说,如果一笔贷款在没有拖欠的情况下被冲销(在一些罕见的情况下),人们仍应将其视为违约事件。

信用风险建模中最广泛采用的定义是将违约事件定义为 1)贷款首次严重拖欠的较早日期;或 2)贷款损失被确认。根据这一定义,导致投资组合损失的任何贷款都将包括在违约群体中,违约日期将与贷款特征恶化的迹象同时标记。

违约=(第一次严重拖欠)U(损失事件)

作者图片—房地美拖欠状况(2014 年至 2019 年)

根据这一定义,我将房地美贷款数据的违约定义为贷款拖欠 180 天或贷款余额因 a)第三方出售、b)卖空或冲销而降至零的最早日期;或 c) REO 性格。上图显示了每种拖欠状态下的贷款分布。从上面的分析中可以提取出两个直接的观察结果。首先,2017 年 8 月突然的“当前”利率下降是由飓风哈维引起的,随后它导致了拖欠状态的飙升。其次,我们可以注意到,除了处于“当前”状态的贷款百分比之外,自 2014 年起,拖欠和违约概率保持单调增加。这是由于整个抵押贷款生命周期的违约曲线的形状,其中违约率通常在贷款发放后不久增加,并在贷款年龄约为 3-5 年时达到峰值(如下图所示)。

来源 : 债券市场协会

此外,这种违约定义也被称为“首次违约”。“违约”贷款可能再次成为“再融资/流动”贷款,即被“治愈”,这种情况并不少见。我们将在下面的治愈率分析中讨论这种行为。

违约预警指标

除了直接对 PD 建模之外,您经常会看到信贷风险建模侧重于预测转换矩阵,将拖欠状态作为“状态”,特别是违约作为“吸收状态”。然后开发单独的子模型来预测从一个状态到另一个状态的转移概率。

为什么 跃迁概率 很重要?

让我们看看下面两个转移概率的比较:

第一个图表显示了“当前到逾期 30 天(DPD)”的转换和 PD 率之间有很强的相关性。事实上,2017 年飓风哈维导致的峰值几乎在大约 6 个月时间间隔的两条曲线中保持完全相同的形状。

按作者分类的图片—当前至 30DPD 与 PD

下面的第二张图显示了从“30DPD 到 60DPD”的转移概率,并将其与从“60 DPD 到 90DPD”的转移概率进行了比较。人们可以看到,这两个转变概率在时间上基本持*,贷款进入下一个拖欠阶段的概率几乎是 30DPD 到 60DPD 的三倍。

作者提供的图片—30DPD 至 60DPD 与 60DPD 至 90DPD 的对比

上面这两个图表告诉我们的是,为了预测 PD,还可以关注预测从电流到-30DPD 的转换概率,作为预警指标。因为一旦一笔贷款无法偿还,它的违约之路就变得更加确定,随着贷款违约越严重,确定性就越高。

治愈率分析

因为“首次违约”的定义,你可能想知道贷款违约后会发生什么?有三种典型的途径:1) 冲销:贷款在资产负债表上保留很长一段时间,直到银行决定将其冲销;2) 重组:银行与借款人一起制定还款计划;3) 再融资:借款人开始再次还款,在某一点上,贷款甚至可以再次成为流动贷款,即治愈

通常在信用风险建模中,治愈率由于其低概率而不被特别建模。如下图所示,随着贷款拖欠状况的恶化,其恢复到当前状态的几率从 50%急剧下降到 10%以下,预计“违约”后的治愈率会更低。

按作者分类的图像—所有过渡状态到当前状态

结论

总之,定义 PD(或转移矩阵)对于解决几乎所有信用风险建模问题都是至关重要的,对此没有固定的答案。与本文中介绍的过程类似,最佳实践是根据贷款级别特征、绩效数据分析以及银行的信贷政策来确定 PD 定义。

希望你喜欢这篇介绍违约概率和转移矩阵分析的文章。喜欢就在下面留下你的评论吧。以上分析的完整代码可以在 这里 找到。

脚注

[1] EAD:你可能也听说过违约时的第三个组成部分 EAD 敞口。对于定期贷款,如抵押贷款和汽车贷款,EAD 可与剩余余额互换使用,而对于分期贷款,如 HELOC 或信用卡,除了未偿余额外,EAD 还由借款人在违约时使用的未提取余额的百分比确定(也称为 LEQ-贷款等价风险)。本文不讨论 EAD 的细节。

物体检测如何准备数据?

原文:https://towardsdatascience.com/how-to-prepare-data-for-object-detection-34750c4d00da?source=collection_archive---------10-----------------------

为大型机器学习项目构建自定义对象检测模型的见解

构建可视化人工智能的图像标注。[ 来源

随着时间的推移,我们在 Ximilar 从事了许多具有挑战性的项目,其中包括对象检测。如今,仅模型的训练和部署就可以在几分钟内完成。您可以简单地上传您的数据并点击几个按钮来训练和部署您的模型作为一个 API。如今,检测模型训练越来越具有挑战性和难度的部分是数据,因为:

  • 物体检测需要比普通图像分类器大得多的数据集
  • 所有你想让人工智能检测到的物品,首先需要被适当地标注,这意味着它们以某种方式被标记了标签和边界框。
  • 数据注释是一个耗时且费力的过程,通常需要一个团队。
  • 当注释你的数据时,你需要绝对一致,注释的人必须训练有素,协调一致。

数据监管和 MLOps 非常重要

选择架构类型只会使整体精度上下移动几个百分点。遗憾的是,大多数机器学习研究都是关于架构设计、新的激活函数和层的。此外,这项研究大多是在相同的庞大数据集上完成的(ImageNET COCOGoogle Open Images)一遍又一遍。基本上,研究小组和大型科技公司在这部分研究上花费了数百万美元,但没有花费在数据监管过程上。

根据我们的经验,以数据为中心比谷歌开发的最新架构带来更好的结果。大多数机器学习项目都是从很少或没有数据开始的。在数据很少的情况下,最先进的模型往往会失败。

人工智能研究员 Andrew NG 敦促人工智能社区更加以数据为中心,我们完全同意。数据的增量改进和使数据集适当*衡是一个更好的方法。[ 来源如果你更注重数据而不是模型,你也可以节省很多培训时间。尝试不同的架构还需要调整许多超参数。

构建检测 MLOps 注释管道

在一个空白的机器学习项目中,我们从几个数据点开始。正如我们之前所说,更多的数据可能会带来更好的结果。然而,做注释(分配标签,创建边界框)的人应该重新检查其他人的数据。这样,我们可以交叉验证注释的正确性。

因此,如果我们希望更加以数据为中心,我们需要知道哪些数据已经被检查过。例如,我们正在开发一个能够分析时尚产品图像的时尚人工智能系统。这个项目的复杂性令人震惊。成千上万的图像,成千上万的类别,包括对象检测和分割。

每周,注释者都关注我们需要解决的不同类型的问题。解决一个问题最终会产生另一个问题,或者降低系统不同部分的准确性。这正是特斯拉 AI 开发者正在经历的问题。你需要非常小心正确的图像样本的适当*衡。

这就是为什么我们正在系统地改进我们的训练数据集。每周我们都会分析问题,并为注释者定义新的工作。他们的工作进度被保存下来,然后在下周进行分析。为时尚或自动驾驶等重大任务构建可靠的人工智能是一个永无止境的过程,因为世界也在变化。

注释作业及其进度。[ 来源

例如,在我们的注释工具中,您可以定义注释作业,并指定注释者应该查看图像的次数。然后,机器学习项目的项目经理可以看到工作的进展以及更多内容。

注记工具支持数据的验证和多种绘图工具,如矩形、多边形和经典标注。随着时间的推移,注释过程越来越快。这是因为您可以简单地在单击时训练对象检测模型,然后在不使用绘图工具的情况下做出所有预测。通过标注系统的 MLOps,您可以 A/B 测试在不同版本的数据集上训练的不同版本的模型

如何让物体检测更准确?

在一些项目中,我们需要检测看起来非常相似的不同类型的项目。这对于模型来说非常难学。因为如果我们有视觉上非常相似的不同类,目标检测的目标函数的损失将最终停留在第一个时期。例如,检测数百种鸟类可能非常困难。这同样适用于微控制器(Raspberry PI,Arduino,…),时尚产品(衬衫与 t 恤),产品缺陷…

Arduino 的产品之一。所有的 Arduino 产品看起来都非常相似。由萨汉德·巴巴里Unsplash 上拍摄的照片

想象一下在图像上检测微控制器 (Arduino)的问题。对象检测模型将很容易学会检测&区分 Arduino 和 Raspberry。然而,对于所有不同的 Arduino 和 Raspberry 微控制器来说,做到这一点是非常困难的。它们有几百种。

那么,有什么选项可以让对象检测在许多视觉上相似的类上工作呢?

我们可以划分问题,简单地创建一个对象检测模型,只有一个标签,名称为“微控制器”。然后创建一个图像分类器模型,它将告诉我们有哪种特定的 Arduino 产品。这种两步法将提高整个系统的整体精度。我们的注释系统能够做到这一点,创建一个对象并分配一个标签或一个复杂的标签分类(层次结构)。只需点击几下鼠标,预测系统就可以部署到 API 端点,只需通过流连接对象检测和图像分类器。

检测大量对象类型的问题可以分为两个步骤。首先检测对象,然后只对边界框的内容进行分类。[ 来源

还记得我提到的时尚或特斯拉用例吗?检测类别越多,需要的数据就越多。将问题分成更少的类是一种更有效的方法。它也不会破坏系统的另一部分,因为每个神经网络只看到我们所说的那部分数据。如果你有一个大的模型,那么你所有的图像必须有所有的边界框和所有的标签,并且要*衡,所以这个类不是主要的。

用于目标检测的数据扩充

数据扩充是多种训练样本的常用方法。为同一个图像创建许多不同的变体可以帮助提升你的模型。然而,你需要非常小心选择哪个增强。有时图像的水*或垂直翻转会破坏模型的性能(例如,检测交通标志可能会出现这种情况)。理想情况下,您应该能够在不同的增强设置上测试您的模型的性能。然后,您可以选择一个在您的测试数据和生产设置中更加健壮的模型。

如何扩大图像的多种方法?改变颜色,饱和度,缩放,删除部分图像。【来源

使用在线注释工具的好处

总之,注释图像应该可以帮助您建立高质量的数据集,用于训练精确的机器学习模型。整个过程应该是有效的,并且应该导致迭代开发,然后在生产中部署。在处理具有复杂分类的大型项目时,您应该首先考虑您的数据,并将您的问题分成子问题。

如果您想使用或阅读更多关于注释*台和所有功能的信息,请访问 Ximilar

如何准备行为/软技能面试?

原文:https://towardsdatascience.com/how-to-prepare-for-a-behavioral-soft-skills-interview-cheat-sheet-9347aaeaef82?source=collection_archive---------7-----------------------

照片由 Maranda VandergriffUnsplash 上拍摄

行为面试是工作过程中的一个重要部分。在这篇文章中,我们将讨论在行为面试中会遇到什么,以及如何准备。最后,我们提供了一份准备和处理行为面试的备忘单。

行为面试评估候选人在组织中互动、生存和成长的能力。大多数公司都在寻找潜在的候选人,他们不仅擅长技术专业知识,而且能够很好地适应公司文化,在团队中运作良好,管理团队,并能够在需要时做出决定。大多数时候,一个在行为面试中表现不佳的候选人,不管他或她在技术面试中表现如何,都无法继续申请。

大多数候选人在技术面试中都表现得很好。编码、机器学习、数据科学、系统设计、案例研究,所有这些对他们来说似乎都很熟悉,而且都在他们的舒适区内。然而,行为面试要求他们坐下来准备。没有正确或错误的答案,面试只是在寻找你有条理的思维,以及你是否能够展示出对公司真正重要的某些特质。

我们将这篇文章分为三个部分。在第一部分,我们将彻底了解如何准备行为面试。然后,我们将了解如何在面试中处理和回答行为问题。最后,文章的最后一部分包含了一些关于这个主题的有用资源。

第 1 部分:为行为面试做准备

为行为面试做准备并不需要像技术面试那样多的时间。*均 3-4 天,每天 1-2 小时,应该足以适应面试过程、示例问题和个性化故事。

但是如何着手准备这样的面试呢?从哪里开始?涵盖哪些问题?这可能会让人不知所措。遵循下面的 5 个步骤,这个过程会变得更加简单和有条理。

第一步:[1-2 小时]收集并理解关键词

需要做的第一件事是研究面试会提问的话题。行为问题可以有广泛的话题。最常见的问题是关于

  1. 领导力
  2. 协力
  3. 解决问题
  4. 决策
  5. 沟通
  6. 人际交往技能
  7. 冲突解决
  8. 谈判技巧
  9. 创造力
  10. 个人的优点和缺点
  11. 师徒制
  12. 表明立场
  13. 有期限地工作

在网上寻找在行为面试中被问到的问题,熟悉这些话题并记下来。这大约需要 1-2 个小时。

第二步:[3-4 小时]收集你的故事

一旦你熟悉了常见的关键词并记下了它们,你需要从你的个人生活中找到一些故事来反映那些突出你个人技能的话题。我发现有用的是记下我过去参加过的所有组织,比如学术、工作、实习、社团和俱乐部。然后,对于每一个这样的例子,我试图回忆我必须运用我的技能来解决潜在问题的事件。这些故事不必是专业的,也可以来自个人生活。如果你在回忆生活中的事件时有困难,看看第一步中的主题,试着回忆解释这些特定主题的事件。

第三步:[0.5 小时]给你的故事指定关键词

现在,一旦你从你的个人生活中收集了故事,仔细地浏览它们并指定关键词。同一个故事可以有多个相关联的标签/关键词。给他们指定关键词将有助于你在面试中更好地回答问题。

步骤 4: [0.5 小时]创建一个汇总表

我喜欢在每次行为面试前准备一份汇总表。这个个性化的表格记录了我的个人故事和相关的关键词。这有助于我为行为面试做准备。下面是这种表格的一个例子。

行为访谈汇总表——作者图片

模糊的文字是我的故事的标识符。

第五步:[2-3 小时]以星形形式解释故事

回答一个行为问题最重要的部分是它的组织和结构。每个行为问题的答案都必须遵循星形格式。使用以下四个步骤来回答这个问题。我们将使用下面的例子,并尝试应用星形格式。

示例问题:“告诉我们一次你不得不说服高管的经历”

1。情况:

当开始回答一个行为问题时,解释情况,并为你的故事提供必要的背景

举例:“2019 年夏天在 XYZ 公司实习。提供给我的项目细节是精心制作的。经过一些最初的头脑风暴和研究,我意识到可以修改项目方法,使其在底层 KPI 方面更有效。我决定和我的经理谈谈这件事。”

2.任务:

一旦你经历了这种情况,解释任务和你在这种情况下的责任。

示例:“我和我的经理通了一个小时的电话,向他详细解释了提议的方法以及它如何改进 KPI。我说服了他。他问我是否能够将我提议的方法提交给上级主管批准。我同意了。我在 ABC(城市)办公室工作,高管们需要从 XYZ(城市)办公室飞过来。”

3.行动:

下一步是回顾你为解决手头的问题而采取的一系列行动

例子:“我对高管们做了一个快速的背景调查,以更好地了解他们的专业领域,这样我就可以相应地说服他们。我准备了一份精心制作的 15 页幻灯片演示文稿,从解释他们的方法开始,接着介绍我提出的方法,最后比较他们的初步结果。”

4.结果:

最后,陈述你所采取的行动的结果,以及这些行动如何影响手头的问题

示例:“经过一番积极的讨论,我们发现提议的方法比最初的方法更好。高管们对我的方法提出了一些小的改变,并非常欣赏我的立场。实习结束时,我从 68 名实习生中脱颖而出,与公司的高级副总裁共进午餐。”

使用星形格式,你将能够有效地组织你的答案。

准备行为面试的五步流程总结如下。

为行为面试做准备——作者图片

第二部分:回答一个行为问题

行为问题通常是开放式的。他们可以涵盖非常广泛的范围,这是不可能的准备每一个问题都可以问。然而,有帮助的是将问题与你已经准备好的常见问题联系起来,并做出相应的回答。以下 5 个步骤将帮助你在面试中回答一个行为问题。

我们将使用下面的例子

示例问题:“告诉我们一次你不得不说服高管的经历”

1.明白;理解

当你面对一个行为问题时,首先要做的是仔细倾听并理解它。一个好的做法是用你自己的话重复这个问题,问面试官这是不是他或她的意思。如果有任何困惑,通过提出后续问题来澄清。一旦你理解了这个问题,用更简单的话问自己同样的问题

好的,他们想让我分享一个我说服我的前辈的故事。也许他们有什么想法,我有一个更好的方法,我试图说服他们。

2.提取

下一步是从问题中提取有用的关键词,帮助你筛选出你的故事。

举例:【令人信服】、【创意】、【领导力】

3.地图

一旦你有了你的关键词,列出你的摘要表中属于这些关键词的所有故事

示例:故事 1、故事 3、故事 6

4.挑选

从入围的故事中,挑选一个最能描述这个问题,并且迄今为止还没有在面试中使用过的故事。

举例:故事 3

5.应用

将 STAR 方法应用于入围的故事

例如:上一节的第 5 步

下面的备忘单总结了这些步骤。

第 3 部分:有用的资源

一些最常见的行为问题和示例答案可以在下面的链接中看到

  1. https://www . indeed . com/career-advice/interview/most-common-behavioral-interview-question-and-answers
  2. https://www . the balances careers . com/top-behavioral-interview-questions-2059618
  3. https://www . themartec . com/inside look/behavioral-interview-questions

总结:

行为面试有时会很棘手。在本文中,我们经历了一个有组织的、易于遵循的准备和回答行为问题的过程。

如果这篇文章对你有帮助,欢迎鼓掌、分享和回复。如果你想了解更多关于机器学习和数据科学的知识,请关注我@Aqeel an war或者在LinkedIn上与我联系。

作为数据科学家,如何准备业务案例面试问题

原文:https://towardsdatascience.com/how-to-prepare-for-business-case-interview-questions-as-a-data-scientist-1892ff019af6?source=collection_archive---------18-----------------------

办公时间

提高你的商业敏锐度和回答面试问题的指南

猎人比赛Unsplash 拍摄

为什么商业案例面试问题如此重要?

仅仅擅长统计测试、机器学习或编码是不够的。当然,这些技术技能对于擅长数据科学是必不可少的。但是有可能知道所有技术方面的东西,仍然被认为是一个糟糕的数据科学家。一个人还需要软技能和业务知识,以便能够跨职能地与他人有效合作,交流结果,并真正理解你试图解决的问题。拥有一些商业头脑会让你成为一名更有效的数据科学家。

你知道你的工作是如何与更大范围的业务联系在一起的吗?你了解公司的总体目标以及数据如何支持这些目标吗?你能在大大小小的问题上为公司做出切实可行的改变吗?这些是企业在向你提出业务案例面试问题时试图评估的东西。

既然你已经确信了为什么商业知识很重要,那我们就来谈谈如何获得这样的知识,以及如何准备面试的问题。知道如何学习这些类型的问题可能会感到困惑,因为它们非常开放,没有像概率问题那样的“正确”答案。如果你想更好地编码问题,你练习你的编码。但是如何实践“商业”呢?

1.建立基础

照片由 Arnold DogelisUnsplash 拍摄

从了解一些商业基础开始。以下是一些需要研究的东西:

  • 项目管理方法论:公司如何组织项目的完成?了解瀑布和 Scrum 等模型。不同方法的优缺点是什么?对于不同类型的项目,公司什么时候可以使用一种模型而不是另一种模型?
  • 组织角色:了解公司的不同角色将有助于你更好地理解工作是如何完成的。从高管级别的职位开始做起。然后向下移动到公司的其他典型角色,特别是数据科学家可能跨职能工作的角色,如软件工程师、产品设计师、产品经理等。对于特定的公司来说,这可能是一个特别有价值的练习。如果你已经安排好了面试,花点时间试着了解他们的组织是如何构建的,不同的团队是如何合作的——尤其是你的职位。参加面试时了解公司如何整合不同团队之间的工作将对你有很大帮助。
  • 商业案例:了解一个商业案例以及它是如何写的,将有助于你进入一个企业的思维框架。你可能永远也不会把写商业案例作为你工作的一部分,但是如果你不能用某种有意义的方式来组织数据,让企业明白它会有什么好处,那么有一个好的数据想法是不够的。熟悉商业案例是如何撰写的,将有助于你理解企业是如何做出决策的。
  • 度量和其他术语:记下你遇到的所有你不知道的缩写或术语。这些最常发生在度量上。像 ROI、KPI、CTR、转换率和客户流失率这样的东西非常常见,并且总是出现,所以要知道它们的含义和使用方法。如果你正在某个行业或利基市场找工作,那么花时间查找与该行业相关的不同指标或术语。例如,像 MAU(每月活跃用户)这样的东西对于社交媒体领域的公司来说是一个重要的指标,敏感性和特异性对于进行医学测试的公司来说是很重要的,等等。
  • 工具和技术:研究公司如何完成工作的常用工具。对于公司如何管理项目、版本代码或协作,有哪些选择?我发现查看特定的工具有助于理解实际的工作流程。在面试前研究一家公司是一件很棒的事情。

所有这些主题都可以进行一般性的研究,以更好地掌握商业知识和词汇,也可以针对特定的公司进行研究。任何时候你有一个面试,你都应该为那个公司仔细检查这些项目,作为你准备的一部分。或者,如果你的目标只是获得更多商业思维的基础,你也可以更广泛地研究这些。

2.公司细节

照片由菲尔在 Unsplash 上听到

现在你已经有了一些基本的知识,是时候深入了解更多的细节了。从现在开始,最好有一个明确的公司。如果你没有特别安排面试,只是想练习一下,那就想一个你想去工作的理想公司,假装你在为面试做准备。

以下是需要研究的内容:

  • 公司愿景和目标:花些时间了解这家公司。他们是怎么赚钱的?他们的客户是谁?他们的高层次目标是什么?他们是如何实现这些目标的?你认为数据如何符合这个等式?
  • 公司产品:有时识别公司产品会很奇怪,因为最明显的产品都是实物。但是产品可以是软件、服务、应用等。这些产品是如何组合在一起的?每个产品的客户是谁?每个产品试图解决什么问题?

有很多建议是在面试前调查一家公司,我认为大多数(好的)候选人都会照着做。但是,我到目前为止所概述的这一点,往往是人们止步不前,没有想到继续走下去的地方。

3.产品,产品,产品

桑德·克兰巴赫Unsplash 上拍摄

这是你将自己与普通候选人区分开来的地方。这一部分将会更深入地为你准备那些商业案例面试问题。流程是这样的:

  • 从一个公司的产品开始:上一节对产品进行了一些研究,但是要深入了解每个具体的产品。对于每种产品,提醒自己它是如何工作的,客户是谁,以及它正在解决的问题是什么。现在想想它有什么特点,它可能有什么缺点或问题,你认为公司收集了什么样的与产品相关的数据。
  • 想象你在开发这个产品的团队中:把你自己放在这个产品出现之前的工作人员的位置上。你认为他们面临什么样的问题?他们收集了什么样的数据?他们如何衡量成功?你认为他们认为护栏是什么样的指标?你觉得他们用的是什么样的统计实验?
  • 假设你是改进该产品的团队成员:随着时间的推移,该产品得到了哪些改进?想一想你将如何使用数据来确定需求。你会收集什么样的数据?你衡量成功的关键标准是什么?如果您认为该产品未来有什么改进,会是什么?你会设计什么样的实验来测试它?

对每种不同的产品重复这一过程。你对公司的产品和指标了解得越多,回答商业案例问题的准备就越充分。在精神上把自己放在公司数据科学家的角色将推动你真正想象业务的需求和挑战,以及你的工作将如何解决它们。

4.组织你的答案

康纳·鲍Unsplash 上拍摄

组织你的答案可能是回答好这些问题最棘手的部分。要做的最重要的事情是放弃有一个“正确的”方法来做这件事的想法。你应该把商业案例问题看得更像是一次谈话,这会让你很难保持一个固定的结构。在这种情况下,它们更类似于人力资源类型的问题,它们是开放式的,实际上只是取决于情况、问题、公司和你的经验。但就像 HR 类型的问题一样,你练习得越多,就越容易以逻辑的方式连贯地讨论答案。

我喜欢借用商业案例的思路来帮助我思考我的答案的各个部分。我建议寻找一些典型的问题,对着镜子自己回答,或者找一个朋友做你的面试官。这里有一个总体结构,我用它来帮助我开始更线性地思考这些问题。我希望这能帮助你开始以一种对你有意义的方式组织你的答案:

  • 澄清问题:像任何数据项目一样,你应该总是从一个清晰的目标或要解决的问题开始。假设你被问到这样的问题,“XYZ 的产品销量下降了 20%,你会怎么做?”一个重要的起点是澄清“首付 20%”是什么意思。这是指与去年同期相比的销售额吗?从上个月开始?下降是通过原始金额还是通过销售数量来衡量的?这种澄清将有助于您准确地确定问题是什么,以及要讨论什么指标/数据。请记住,您应该已经熟悉该公司使用的通用指标以及他们的产品。你想表现出你能逻辑地处理问题,并定义什么是需要解决的。在现实生活中,这是最重要的一步,因为如果你没有在正确的页面上,这将导致最大的痛苦。
  • 确定可能的原因和解决方案:现在你知道了问题是什么,目标是什么指标,你可以考虑一些可能的原因。公司通常希望看到你能提出多种想法,所以我建议你瞄准 2-3 个想法,这样你就能展示出你解决问题的能力,同时保持你的回答有条理。再一次,想想公司在你的工作方式中寻找什么——他们想要一个能带来想法的人。
  • 谈论实验:你会如何设计一个实验来测试你可能的原因/解决方案?你会如何取样?如果您看到指标增加或减少,您会提出什么样的假设?什么时候增加或减少指标可能具有欺骗性?有时,你可能会有面试官希望你在面试中获得更多信息或保持高水*,这是你必须从谈话中评估的事情。但总的来说,该公司正试图了解你将如何采取行动,将你的数据科学知识应用于现实世界的问题。
  • 确定利弊:一些指标会如何相互影响?解决方案会有多昂贵和复杂?不同解决方案的风险和好处是什么?在这个假设场景中,你会提出什么样的建议?面试官想判断你如何传达结果,评估缺点,并给出建议。

真正利用你的面试官进行讨论。如果他们没有给你很多关于你是否在正确的轨道上的反馈,那么你完全可以问你是否在正确的轨道上。如果你担心自己漫无边际,那么问问他们是否希望你继续沿着某条轨道走下去或者继续前进。记住,就像所有其他的面试问题一样,公司是想看看和你一起工作会是什么样子。回答问题时,请始终牢记展示你将如何增加价值的指导原则。

结论

希望这份指南能给你一些好的基础知识来学习和扩展。记住,商业案例问题没有正确的答案,而是双方都想看看你是否适合这份工作。出于这个原因,你应该一直努力寻找你的答案,尽你最大的努力展示你的想法以及如何与你共事。

祝你面试顺利。你会做得很好的!

如何准备您的开发环境以便在 Kaggle 上排名

原文:https://towardsdatascience.com/how-to-prepare-your-development-environment-to-rank-on-kaggle-1a0fa1032b84?source=collection_archive---------16-----------------------

插图照片由 PexelsMateusz Dach 拍摄。

这篇文章介绍了为 Kaggle 影像分类挑战配置定制开发环境的最佳实践。

在这个故事中,我将介绍如何为参加 Kaggle 挑战赛设置开发环境:
1)选择一个最*有趣的比赛,
2)在云中启动一个 JupyterLab 环境,
3)下载完整的数据集,
4)执行初始图像预处理。

初步选择:竞赛、深度学习框架、云*台

显示每个串联类别组合的样本图像和计数。

我们将使用最*的 Kaggle 植物病理学 2021 — FGVC8 来展示完整的数据科学周期。这场比赛的一个好的方面是,它非常简单,代表了 CIFAR 和 MNIST 以外的真实世界图像分类任务所面临的挑战。

我为这些比赛选择的框架是 PyTorch Lightning ,它允许我专注于迭代我的数据处理和模型架构,而不用担心训练循环和设备管理的繁重工程。关于为什么你应该查看下面的 PyTorch 闪电贴的更多信息。

https://devblog.pytorchlightning.ai/why-should-i-use-pytorch-lightning-488760847b8b ,它可以让我精确地指定我想要使用的机器,里面预装了 JupiterLab。作为奖励,Grid 使我能够用 Github 同步我所有的 Kaggle 代码。稍后,我将使用它来运行超参数搜索,为我的模型找到最佳配置。

完全公开——我目前在 Grid.ai
担任高级研究工程师。注意,还有其他替代方案可以用来利用这些最佳实践,例如 Kaggle 内核或 Colab,但 Grid 是我的首选*台,因为它使我能够使用云轻松地扩展训练我的模型。

本教程中包含的所有代码和可视化都可以在本报告中获得,您可以免费使用和贡献。

准备 Kaggle 开发环境

我选择 Grid.ai 作为我的开发环境,因为它提供了三个主要的构建模块:

  1. 数据存储(使我能够一次上传数据,并在任何地方使用;他们确保我们所有的原型和实验使用相同的数据,并且是可重复的)
  2. 会话(这使我能够专注于机器学习本身。我发现网格实例的 CPU/GPU/RAM 性能优于 Kaggle 和 Colab 内核)
  3. 运行(这使我能够扩大实验规模;我可以实时密切监控多个实验,及早停止次优配置,比较结果,并在一个地方为 Kaggle 导出最佳模型。

启动网格会话

在网格会话中启动 Jupyter 实验室。

首先用 GitHub 或者 Google 账号登录 Grid.ai 。然后您可以创建一个会话——配置您的实例类型并设置所需的存储大小(当您想要处理大型数据集时会很方便)。新的交互式会话实例带有一个内置的 JupyterLab。

为完整旅程创建网格会话的步骤点击此处

我可以轻松地启动 JupyterLab,并使用 cli 工具glasses来监控实时资源使用情况,这让我知道是否存在任何资源瓶颈,如预处理期间的 CPU 利用率或训练期间的 GPU 利用率,从而导致训练批量增加。

https://docs.grid.ai/products/sessions

设置 Kaggle CLI 并下载数据集

为了在我们的会话中获得植物病理学 2021 — FGVC8 数据集,我们使用由 Kaggle 直接提供的 Kaggle CLI,并在 PyPI 上进行索引。

pip install kaggle

对于任何使用 Kaggle CLI 的用户,您需要设置您的凭证——登录 Kaggle web 并创建您的个人密钥,该密钥将作为kaggle.json自动下载。

从个人 Kaggle 帐户下载凭证文件的步骤如下:(1)选择帐户,(2)向下滚动并“创建新的 API 令牌”。

当我们有了kaggle.json密钥后,我们可以使用 JupyterLab 将其上传到我们的会话(简单的拖放)并将其移动到 Kaggle CLI 的正确目的地,如下所示:

逐步如何设置 Kaggle CLI: (1)安装kaggle包,(2)拖放带有凭证的文件,(3)将其移动到预期的系统文件夹。

mv kaggle.json /home/jovyan/.kaggle/kaggle.json

现在,我们将数据集下载到我们的会话中。要下载的特定竞赛名称与 URL 名称相同。此外,每场比赛的数据部分都提供了确切的下载命令。大多数数据集以压缩的形式分发,我们需要将它解压缩到一个目的地文件夹(我通常将该文件夹命名为与竞争对手相同的文件夹)。因此,在我们的竞争中,我们调用以下命令:

# doanload dataset via Kaggle CLI
kaggle competitions download plant-pathology-2021-fgvc8
# unzip the dataset to a folder
unzip plant-pathology-2021-fgvc8.zip -d plant-pathology

数据集预处理

提取之后,我们可以对数据集进行预处理。原始数据集以 4K 分辨率分布,这对于大多数应用程序来说太大了,所以我们将图像缩小到大约 640px。在如何在排行榜上排名中描述了这种观察和推理。我们使用一个简单的 CLI 工具 ImageMagick

apt install imagemagick
# apply to all JPEG images in given folder
mogrify -resize 640 plant-pathology/train_images/*.jpg

最终,您可以编写自己的小脚本来探索 python 多处理并加速这种转换…

用于多处理图像缩放的简单脚本

这就是你需要知道的准备 Kaggle 开发环境和 Grid.ai 的一切。概括地说,我们选择了一个有趣的 Kaggle 竞赛,展示了如何开始交互式会话,以及如何为任何(本地或云)环境配置 Kaggle 凭证。

我将在未来的博客文章中继续探索这个下载的数据集,并准备一个基线计算机视觉模型来解决这个任务。我还将回顾一些帮助我在排行榜上排名的技巧,敬请关注。稍后,我们还将分享如何轻松地从离线内核提交内容。

敬请关注,并跟随我了解更多!

https://devblog.pytorchlightning.ai/best-practices-to-rank-on-kaggle-competition-with-pytorch-lightning-and-grid-ai-spot-instances-54aa5248aa8e

关于作者

Jirka boro vec已经在几家不同的 IT 公司从事机器学习和数据科学工作好几年了。特别是,他喜欢探索有趣的世界问题,并用最先进的技术解决它们。此外,他开发了几个开源 python 包,并积极参与其他知名项目。在 Grid.ai 工作,担任研究工程师,是pytorchlightning . ai的主要撰稿人。

如何向非技术人员展示机器学习结果

原文:https://towardsdatascience.com/how-to-present-machine-learning-results-to-non-technical-people-e096cc1b9f76?source=collection_archive---------18-----------------------

展示利益相关者能够理解的模型结果

照片由亚历山大·奈特派克斯拍摄

作为一名数据科学家,很难向非技术利益相关者解释机器学习的结果。经过反复试验,我想出了一种将模型结果转换成利益相关者能够理解的格式的方法。今天,我想和大家分享我的方法,我用它取得了巨大的成功。

方法 1

这种方法可以应用于生成 0 到 1 之间的概率分值的任何模型。

  1. 首先将你的模型分数从高到低排序,并对其进行十分制。十分位数 1 将包含最高分,十分位数 10 将包含最低分。
  2. 接下来计算每个十分位数的最小值、中值和最大值。
  3. 通过十分位数计算真阳性的数量,然后将真阳性的数量除以您的评分人群中的真阳性总数。

下面是在购买倾向模型得分样本集上使用此方法的输出示例。总购买量百分比栏中的百分比是用十分位数的购买量除以总购买量 31,197 计算出来的。

按十分位数购买——按作者分类的表格

这些是这张表上的关键要点。

  1. 第一和第二个十分位数分别预测了 33%和 32%,合计购买量的 65%。这表明该模型能够预测出购买了的大多数顾客位于前两个十分位数。
  2. 与上面的十分位数相比,每个十分位数在总购买量中所占的百分比较低。这是我们对一个好模型的预期趋势,因为大部分购买发生在最高的十分之一,而最低的十分之一包含很少的购买。请注意,十分位数 10 只包含 2%的购买量,而十分位数 1 包含 33%的购买量。
  3. 十分位数 3 的分数在 0.239 到 0.555 之间。十分位数 3 是模型变得不太可能准确预测客户购买的时候。

我见过数据科学演示,其模型结果超出了非技术人员的理解范围。

然而,如果你用一个表格来展示模型结果,显示前 20%的顾客获得了 65%的购买量,那么你的利益相关者就很容易理解了。

方法 2

第二种方法类似于第一种方法,也是一种让数据科学家更容易评估模型结果的视图。

  1. bin 模型在 0 到 1 之间以十分之一为增量进行评分,而不是十分之一。
  2. 计算每个条柱的最小值、中值和最大值。
  3. 计算每个箱子中真阳性的数量,然后将真阳性的数量除以真阳性的总数。

下面是使用同一组购买倾向得分样本的输出示例。

按分数范围列出的购买情况—按作者列出的表格

这些是使用此输出按分值分类的要点。

  1. 使用 0.5 作为映射到 true 的阈值,如果我们将突出显示的“总购买量的百分比”列中的百分比相加,该模型能够预测总购买量的 67%。
  2. 但是,得分在 0.1 到 0.19 之间的客户占总购买量的 20%。这表明可能有其他特征可以改进模型,并保证进一步的分析。如果我们没有看到 20%,而是看到了 2%,那么您可以更有信心该模型捕捉到了所有相关特征,以准确预测购买。

该输出向利益相关者显示,您的模型准确地捕获了 67%的购买。如果模型没有预测到真正的阳性结果,它还可以帮助您识别问题,并显示您可以进一步研究的领域,例如得分在 0.1 到 0.19 之间的客户。

结论

作为数据科学家,冲动是显示原始模型结果,但通常我们需要将输出转换成利益相关者可以理解的形式。现在你已经看到了我的方法,我希望你能更容易地表达你的模型结果,让每个人都能理解。

https://medium.com/swlh/how-i-used-a-machine-learning-model-to-generate-actionable-insights-3aa1dfe2ddfd

如何漂亮地打印熊猫数据帧和系列

原文:https://towardsdatascience.com/how-to-pretty-print-pandas-dataframes-and-series-b301fa78bb6c?source=collection_archive---------11-----------------------

如何在同一行显示熊猫数据框的所有列

斯通王Unsplash 上拍照

当我们必须处理可能有多列和多行的大熊猫数据帧时,能够以可读的格式显示数据帧是很重要的。这在调试代码时可能也很有用。

默认情况下,当数据帧被打印出来并且具有相当多的列时,只有一部分列被显示到标准输出中。显示的列甚至可以打印成多行。

在今天的文章中,我们将探讨如何配置所需的 pandas 选项,这将允许我们“漂亮地打印”pandas 数据帧。

问题是

假设我们有以下数据帧:

现在,如果列数超过显示选项display.max_rows的值,则输出数据帧可能不完整,如下所示。仅显示列的子集(column4column5缺失),而剩余的列以多行方式打印。

来源:作者

虽然输出仍然具有一定的可读性,但是忽略列或多行打印肯定是不理想的。

如何漂亮地打印熊猫数据帧

如果您的显示器足够宽,能够容纳更多的列,您可能需要调整一些显示选项。我将在下面使用的值可能不适合您的设置,因此请确保对它们进行相应的调整。就我个人而言,我使用超宽显示器,必要时可以打印出相当多的栏目。

如何在同一行打印所有列和

现在,为了显示所有的列(如果你的显示器能够容纳它们的话),并且在一行中,你所要做的就是将显示选项expand_frame_repr设置为False:

pd.set_option('expand_frame_repr', False)

来源:作者

[display.expand_frame_repr](https://pandas.pydata.org/pandas-docs/stable/user_guide/options.html)

默认:True

是否打印多行宽数据帧的完整数据帧报告,max_columns仍受关注,但如果其宽度超过display.width,输出将跨越多个“页面”

或者,您可以更改display.max_rows的值,而不是将expand_frame_repr设置为False:

pd.set_option(‘display.max_rows’, False)

注意,如果各栏仍打印在多页中,那么您可能也需要调整 **display.width**

如何打印所有行

现在,如果您的数据帧包含超过一定数量的行,将只显示少数记录(来自 df 的头部和尾部):

如果您想要显示更大范围(甚至所有)的行,您需要将display.max_rows设置为您想要输出的行数。如果要显示所有行,将其设置为None:

pd.set_option('display.max_rows', None)

使用上下文管理器

更好的方法是使用[option_context()](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.option_context.html),它是一个上下文管理器,可以用来临时设置with语句上下文中的特定选项。

其他有用的显示选项

有更多的显示选项,你可以调整和改变熊猫数据帧的显示方式。

  • display.max_colwidth : 这是为列名显示的最大字符数。如果某个列名溢出,将添加一个占位符()来代替。
pd.set_option('display.max_colwidth', None)
  • display.precision:这是将用于浮点的精度。它指定了小数点后的位数。
  • display.width:这是显示器的总字符数。如果您想显示更多的列,有时您可能还需要调整display.width

您可以使用describe_option()找到显示的完整列表:

pd.describe_option(‘display’) . 

Jupyter 用户注意事项

如果您正在使用 Jupyter 笔记本,只需使用[display(df)](https://ipython.readthedocs.io/en/stable/api/generated/IPython.display.html#IPython.display.display)而不是print(df),宽度将会相应调整。

结论

在今天的文章中,我们讨论了熊猫的几个显示选项,让你可以根据你想要显示的内容以及你使用的显示器来漂亮地打印数据帧。

熊猫配备了一个options系统,让用户调整和定制显示功能。我们只讨论了可用显示选项的一小部分。确保阅读官方文件的选项和设置部分。

如何确定分析工作的优先级—第 1 部分

原文:https://towardsdatascience.com/how-to-prioritize-analytical-work-part-1-ae91a6e71303?source=collection_archive---------8-----------------------

行业笔记

一般来说,分析工作分为四个阶段

作者图片

我将写一系列关于数据科学(或可互换分析)最佳实践的短文。我坚信,在大大小小的组织中拥有一个好的数据科学部门的主要挑战是拥有正确的流程;这在很多方面比数据或算法更重要。你可以拥有世界上最聪明的数据科学家,拥有最复杂的算法,但如果你用错了方法,那就没关系了

学习如何很好地确定分析工作的优先级是创建一个运转良好的数据科学部门所需的第一件基本事情。太多时候,优先排序是基于“谁问得最多?”或者“谁最后问?”当你以这种方式进行优先排序时,你就结束了“随机漫步”,经常变成“绕圈行走”,在解决基本问题或获得真正有价值的洞察力方面没有取得真正的进展。当你陷入随机漫步时,你会注意到一些症状:

  • 根本性的挑战没有解决;您在一次又一次地解决相同的问题(例如,数据难以访问,报告不能按时运行,指标经常失败,数据质量低且没有随着时间的推移而提高)
  • 即使是最琐碎的请求,您也必须与数据科学家或数据工程师互动,因为自动化程度很低,而且没有自助服务解决方案
  • 你有很多 1/2 完成的项目,但没有一个真正运作良好
  • 每个人都永远不快乐(讽刺的是,一旦你学会了分清主次,你就会有快乐的人和不快乐的人……稍后会有更多)
  • 永远不清楚数据科学家或数据工程师在做什么;优先级每隔一周甚至每周都会改变,这是一个主要的危险信号,因为在一个管理良好的组织中,大多数分析项目需要 2-4 周的时间,该组织具有创建文档并对分析工作应用适当的 QA 的文化

为了很好地对你的项目进行优先排序,你首先需要把它们放到一个小的桶里:

  1. 战略项目
  2. 临时/战术项目
  3. 维护
  4. 研究和实验

在本文中,我们将讨论每一个桶,并向您展示一个推荐的分配,我发现通过反复试验,这个分配很有效。在随后的文章中,我们将深入探讨如何在第一(即,战略项目)和第二(即,特别/战术项目)桶中对行项目进行优先级排序和执行。我们还将讨论使您能够避免线性扩展维护所需带宽的策略,以及如何有选择地选择“高价值”的研究和实验项目。后续文章将讨论进一步的支持机制,使您能够成功地对分析项目进行优先级排序,从而为您的业务释放价值。

战略项目

这些项目支持新功能、自动化流程和/或构建自助服务解决方案。这些是组织真正的“商业增值”项目。“新功能”的一个例子是为新产品构建报告基础设施(例如,在您的网站上推出新功能,新的零售产品)。“自动化”的一个例子是将所有正式的手动报告转移到 Tableau 中,这样从数据到报告都是完全自动化的。“自助式”解决方案的一个例子是使用 Tableau 创建应用程序,使业务用户能够灵活地探索自己的数据,而无需编写 SQL 查询或与分析师合作来获取新数据。这需要创建具有非常特殊的后端数据结构和经过仔细考虑的 UI/UX 的 Tableau 应用程序;还需要非常了解业务,以及可能会被问到哪些业务问题。“自助式”解决方案的另一个例子是创建一个工具,使业务用户能够自己将数据直接加载到您的数据库中(通过适当的控制),以消除让数据工程师为他们手动加载的需要。

临时/战术项目

这些都是小要求,你通常可以在 1-3 天内完成。例如,向数据库模式中添加一个新的数据表。或者向现有数据表添加新列。关键是它们是小请求,通常在整个组织中没有太多价值;它们不支持新功能或自动化任何东西,也不支持自助服务解决方案。通常,这些会分散团队的注意力,因为它们是单个人的宠物项目。您必须积极主动,不允许临时请求伪装成战略项目,但您确实需要为您的客户提供一条途径,让他们在小问题上获得帮助,从而阻止他们继续前进。

维护

你建造的东西,你必须维护。这是不言自明的。这是您必须投入的工作,以保持您构建的东西正常工作。这是一段不容讨价还价的时间,也是最高优先级;你首先要为此留出适当的时间,剩下的时间你可以分配给其他三(3)个桶。

研究和实验

这些是内部项目,目的是让你构建的东西比现在做得更好。它不涉及对你已经建立的东西的大规模改变或修改;相反,它通常是改变小部分,看看整个事情是否得到改善。这方面的一个例子是使用红移频谱,它使红移能够查询存储在 S3 的*面文件,就像它们是红移中的一个表一样,以将不太常用但较大的数据表移动到 S3,而不是将它们作为本地副本存储在红移中。以这种方式使用红移光谱可以在不影响性能的情况下显著降低总成本,但这取决于数据的模式和查询方式。因为性能很难提前预测,所以在完全投入使用之前,您应该先尝试一下这个解决方案。

推荐分配

没有客观的正确的时间来投资每一个桶,但我几乎总是使用下面的分布,这是我通过多年的试错经验得出的:

  1. 战略项目— 50%
  2. 临时/战术项目— 20%
  3. 维护— 20%
  4. 研究和实验——10%

根据您在分析过程中所处的阶段以及您的业务需求,适合您组织的分配可能会有所不同。然而,我的经验表明,有两条经验法则你应该遵循:1)超过战略项目的指数,因为那些应该是真正为你的组织增加价值的项目(即,给这个桶最大的分配);2)维护很可能至少占您团队带宽的 20%,因为少于 20%的维护通常会造成这样一种情况,即您团队创建的分析产品或解决方案会崩溃和/或不被业务部门完全采用。如果你对自己创造的分析产品没有足够的重视来支持它们,为什么企业中的其他人会采用它们呢?

作者图片

顺便说一下,这四个桶并不是相互独立的。在一个成熟的、运行良好的数据科学(或分析)团队中,他们将以分层的方式相互支持,作为任何分析职能部门的领导者,您的目标是确定如何利用分层结构来提供更大的商业价值。具体而言,维护对于鼓励组织采用分析产品至关重要。但是随着您生产越来越多的分析产品,您的维护负担将会增加,除非您采用良好的开发过程(我们将在单独的文章中讨论这一点)。确保您遵循的方法不会造成维护费用的线性增长是至关重要的,因为这将很快变得不可持续。但是你也不能“归零”或减少你在维护上的投资,因为没有什么比一个几乎不起作用的分析产品更快地扼杀采用。此外,研究和实验应该始终面向两个目标:1)改进您的战略项目(即,您的分析产品),以及 2)最小化执行特定/战术项目所需的复杂性、工作量和带宽,因为特定项目很少为组织带来“业务增值”。因此,你越能降低战术项目的成本,你就越能为战略项目分配更多的带宽。

因为时间是有限而有价值的商品,你必须明智地投资它。做到这一点的关键是要有纪律,不要偏离你想要的四个投资区间的投资分布(*均来说,你可以每周都有变化,但在很长一段时间内,要确保你*均分配)。你必须时刻保持警惕,而且说实话,有点难对付。原因是每个人都认为他们的项目是世界上最重要的事情。但是我很喜欢一句谚语:每件事对某人来说都很重要,但这并不意味着每件事都同样重要。

一旦您将您的工作映射到每个时段,并决定对您的业务有意义的分配,您可以使用多种支持机制来确定每个时段内的优先顺序,并确保您能够成功地坚持您的分配投资策略和优先顺序,而不会被随机化。我将在单独的文章中更深入地讨论这些机制,但作为预览,它们包括以下内容:

  1. 业务需求文档
  2. 2x2 矩阵
  3. 路线图
  4. 待命流程
  5. 通信(横向和纵向)
  6. 文件是不可协商的
  7. 需求——设计——实现——文档循环(以及分阶段或迭代敏捷方法的使用)

与此同时,您可以了解商业中三个最重要的统计测试、 A/B 测试实际测量什么良好分析数据仓库的基础知识、成功数据科学团队的支柱或关于自动化的四个重要工具的想法以最大限度地发挥您的数据科学的价值。

如何确定分析工作的优先级—第 2 部分

原文:https://towardsdatascience.com/how-to-prioritize-analytical-work-part-2-8a073546cede?source=collection_archive---------24-----------------------

撰写良好的业务需求文档

作者图片

在之前的一篇文章中,我讨论了将你团队的分析(或可互换的数据科学)工作分成四(4)个部分的重要性,以帮助你有效地确定的优先级。在那篇文章的最后,我提到了成功坚持你的分配投资策略和优先顺序而不被随机化的七(7)个关键机制。其中一个机制是坚持所有的战略项目都从一份写得很好的业务需求文档开始(BRD)。在这篇文章中,我将提供一个简短的例子来说明怎样才能写好 BRD。我坚持认为战略项目的 brd 只有三个基本问题:

  1. 你想要什么?
  2. 你问的商业价值是什么?
  3. 完成您的提问需要哪些高级步骤?

典型的 BRD 只有 3-4 页长;它们必须用散文来写,以使作者能够清楚地表达需求,并且它们应该在必要或可能的地方包括视觉效果来清楚地表达需求。

你想要什么?

一封写得好的 BRD 会以简单的英语开始解释你的要求。这个请求应该既经济又全面,清楚地展示出你所需要的大愿景。任何人都应该容易理解,并尽可能避免行话。我们来看一个(虚构的)例子,看看你在提出问题时应该写些什么。

【2019 年 4 月,我们将启动“胡迪尼计划”,让我们的客户能够在附*便利的实体零售店订购定制服装,这将补充我们的在线订购渠道。胡迪尼计划将会看到分布在华盛顿 DC 地区的 10 家商店的揭幕;该项目的目标是衡量顾客在实体零售环境中订购定制服装的需求,而不是传统的在线渠道。在接下来的六(6)个月里,胡迪尼项目需要回答以下业务问题:

1。有多少顾客光顾我们的零售店?有多少是全新客户?有多少人在去零售店之前曾在网上订购过?有多少人在逛完零售店后会在网上订购?有多少订单仅通过单一渠道(即网上、零售店)订购?

2。按渠道(即在线、零售店)下的订单数量和金额分布情况如何?对于只通过单一渠道订购的客户,分销渠道会发生变化吗?那些通过这两种渠道订购的人呢?

3。购买频率如何随渠道变化?

4。客户群(例如,小企业、婚礼、姐妹会等)的分布如何随着渠道而变化?

5。顾客要走多远才能在零售店购物?

6。根据渠道的不同,对定制设计的帮助需求会有怎样的变化?与在线订购的客户相比,光顾零售店的客户与我们的*面设计师接触的频率更高还是更低?

7。客户选择的毛坯(即预先定制的服装)类型如何随渠道变化?在零售店订购的顾客会转向质量更好的坯料吗?我们是否可以推断出“触摸和感受”坯料可以更好地向顾客传达好的、更好的和最好的坯料之间的区别?

8。开零售店是否会蚕食店铺周边的网上订单?或者开一家零售店会增加该地区的总需求吗?

这些业务问题应该可以使用一个专门为支持胡迪尼项目而构建的 Tableau 应用程序来回答。应用程序应提供数据的高级视图,以支持每周和每月的业务回顾;同样的应用程序还应该支持对业务问题的“深入”分析。业务用户应该能够选择每日、每周、每月和每年级别的数据聚合。Tableau 应用程序应该从单个零售店扩展到聚合在一起的多个零售店,并允许比较在线和零售订单以及客户行为。只要有可能,数据应该在地图上可见,以使业务用户能够从地理上理解客户行为。

这是一个写得很好的“你想要什么?”使数据工程师和商业智能工程师能够用简单的英语理解您需要回答的关键业务问题。当我们了解这些业务问题时,我们可以帮助您设计和计算正确的业务指标,并选择正确的可视化方式,使数据易于消化。请注意,对于这个问题,一个写得很好的答案缺少了什么:

  1. 它不是一个指标列表(例如,在零售店订购的客户百分比)
  2. 它不是一组图表(例如,基于 Excel 的示例说“在 Tableau 中精确构建此图表”)
  3. 这不是 10 页的需求

你问的商业价值是什么?

在解释了你的要求之后,一篇写得很好的 BRD 解释了投资建设你所要求的东西的商业价值是什么。商业价值应该是清楚的,精确的,诚实的,相对于假设的。它也应该集中在无聊的“螺母和螺栓”,为什么你的要求应该优先考虑和投资。

胡迪尼项目是在零售店将补充而不是蚕食网上订单的假设下获得批准和启动的;该项目假设零售店将吸引新客户,这些客户永远不会(或几乎永远不会)在网上订购定制服装,因为他们更喜欢在下单前与我们的产品“接触、感受和互动”。我们进一步假设,更喜欢在零售店(而不是网上)订购的顾客更喜欢亲临商店并与我们的商店员工互动的个人接触;我们相信,这些顾客在订购定制服装时,需要与人面对面交流,从而获得安全感。我们的估计是,项目 Houdini 将在零售店 15 英里范围内产生 10%的订单增长(具有相似的*均订单价值)(即,在零售店 15 英里范围内,每 100 个在线订单将产生 10 个零售订单)。如果我们的假设是正确的,零售商店网络将产生 3500 万美元的年增量收入(每家商店 350 万美元),并且假设投入 100 万美元的资本支出来开办一家普通的零售商店,则回收期为 3.5 个月。

我们所要求的 Tableau 应用程序将使我们能够很容易地理解胡迪尼项目的表现,并验证该项目的假设是正确的。如果我们不投资构建应用程序,将需要两(2)个人每周工作 40 小时来使用 Excel 手动构建报告。手动创建这些报告会降低数据的质量,并延迟我们对胡迪尼项目绩效的报告。使用 Tableau 应用程序,我们希望每周一下午与高级业务领导会面,回顾前一周的业绩;如果没有申请,我们至少要等到周四才能回顾前一周的表现。此外,Tableau 应用程序将使我们能够在周一下午的每周回顾中快速“深入”数据,回答回顾中提出的任何问题,而用 Excel 手动报告将迫使我们在每周业务回顾后再花一周时间提取数据,并返回前一周提出的问题的答案。

总之,使用 Excel 进行手动报告将导致理解 Houdini 项目绩效延迟 1-2 周,降低数据质量,并且需要两(2)人每周投入 40 小时的人工工作来准备数据和基于 Excel 的报告。对于一家年收入为 3.5 亿美元的公司来说,在 Houdini 项目上投资 1000 万美元并不是一笔小数目,因此最大限度地提高数据质量并最大限度地减少衡量和理解绩效的延迟非常重要,这样我们就可以迅速采取行动,使 Houdini 项目取得成功。

注意,这个例子用简单的英语清楚地表达了为什么这个项目应该被优先考虑和投资的所有假设和原因。它没有简单地说“这个项目将产生 3500 万美元的年收入”,而是解释了未能满足要求的“螺母和螺栓”的负面后果:1)测量性能的重大延迟;2)数据质量下降;以及 3)每周安排两(2)个人来构建基于 Excel 的可疑质量报告。它还描述了胡迪尼是一个多大的投资项目的业务,以及如何使其成功将影响整个业务。

完成您的提问需要哪些高级步骤?

这往往是 BRD 的作家最难回答的问题;在这一部分,数据工程师和/或分析师经常需要帮助作者。但是我非常谨慎地使用“帮助”这个词,因为写 BRD 自我是请求者的责任。数据工程师和/或分析师可以向作者解释需要做什么,但作者有责任接受足够的教育,以便他们可以在高层次上写下需要做什么。有时候有人问我“为什么不自己写,而不是强迫商业用户向你学习,然后写下来?”这有一个很好的理由:它迫使数据工程师和/或分析师与寻求帮助的业务用户之间进行对话。这种对话对双方都有价值:

  1. 对于数据工程师和/或分析师来说,这有助于他们理解 ask 的业务需求和业务价值;他们有机会提出澄清性的问题,这些问题可能是撰写 BRD 的人没有考虑到的
  2. 对于编写 BRD 的业务用户来说,这有助于他们了解他们所提问题的技术细节;数据工程师和/或分析师有机会解释需要做些什么来向业务用户提供他们所要求的东西

双向对话有助于双方更好地了解对方试图做什么,最重要的是,为什么。

要构建 Houdini 项目所需的 Tableau 应用程序,需要完成以下高级步骤:

1。将在线订购系统的交易数据库纳入我们的商业智能(BI)数据仓库

2。将零售订购系统的交易数据库导入我们的 BI 数据仓库

3。设计并构建一个数据模型,将两个事务数据库合并成一组标准化的、干净的数据对象(即星型架构),使我们能够回答业务问题

4。为数据模型和数据模型上的性能质量保证(QA)编写文档,以验证数据的正确性

5。定义回答胡迪尼项目业务问题的指标

6。设计并构建 Tableau 应用程序的后端数据结构

7。设计和构建 Tableau 应用程序 UI/UX

8。与业务用户利益相关方一起审查 Tableau 应用程序草案

9。整合来自业务用户利益相关方的反馈

10。编写 Tableau 应用程序的文档

11。启动 Tableau 应用程序

根据我的经验,几乎每个 BRD 都会有 8-12 个要点,列出满足要求需要执行的高级步骤。请注意,这个列表中有两个项目被明确提到,但几乎总是被遗忘:1)文档,和 2) QA。这些必须明确提及,在文档准备就绪之前,任何项目都不能被视为完成;事实上,在完成文档之前,我们从不“启动”任何战略项目,以避免直接进入下一个项目和偷工减料的诱惑。

所以,上面你有一个 BRD 的好例子。你会注意到它简洁,清晰,易于理解。对于一个分析项目来说,一个好的 BRD 并不需要大量的文字;我很少看到任何分析项目需要写超过 3-4 页的内容。

激烈辩论的话题

上面的示例 BRD 1)避免了提供度量列表,但是 2)它假设了问题的正确解决方案(例如,Tableau 应用程序)。这有道理吗?根据我的经验,这是一个激烈辩论的话题。我将解释为什么我坚持 BRD 避免列出所有的指标,以及为什么我同意 BRD 的作者假设一个解决方案。首先让我们讨论“度量”,然后讨论“解决方案的假设”。

根据定义,分析师和/或数据科学家是分析(和数据科学)方面的专家,不一定是编写 BRD 的业务用户。通过要求业务用户描述他们试图回答的业务问题,它使分析团队能够更好地了解业务以及业务领导者如何看待业务,并且它鼓励分析团队深入思考业务以及什么类型的分析可以回答业务问题。当 BRD 是一个指标列表时,这个过程就被缩短了,因为分析师或数据科学家倾向于简单地计算所要求的任何指标,即使这些指标不是回答业务问题的“最佳”指标。BRD 是一种迫使分析团队和业务团队之间进行对话的机制。这种对话使业务团队更有可能获得最佳的分析解决方案,也使分析团队的解决方案更有可能真正增加业务价值(即,较少以学术为导向)。

如果您的业务“抱怨您的分析或数据科学组织与业务脱节”,这种脱节的主要原因(以我的经验来看)是没有机制来强制分析和业务团队之间的对话(例如,像 BRD 那样避免列出要计算的指标)。您总是希望制定一些流程,鼓励业务用户向分析和/或数据科学团队解释业务(例如,关键业务问题)。这确保了分析团队紧密地整合到业务中,并以具体的方式思考业务。另一方面,您希望确保您的分析和/或数据科学团队充分利用他们的专业知识和技能来使业务受益。最大的商业价值将而不是来自于让昂贵的分析师或数据科学家计算由商业用户选择的指标;最大的商业价值将来自于让这些分析师部署他们花了 10 多年时间学习的全套数学思维和技术。这只有在他们持续接触业务的具体条款时才会发生。避免在 BRD 中列出度量标准是确保这一点的一种方法(我们将在未来讨论其他机制)。

在我的职业生涯中,有些人不同意 brd 对业务问题的“解决方案”做出任何假设。从哲学上来说,他们不同意 BRD 的说法,即“这些商业问题应该使用专门为支持胡迪尼项目而构建的 Tableau 应用程序来回答。”相反,他们更喜欢只讨论业务问题(以及他们希望在任何可能的解决方案中包含的功能),而将所有关于任何可能的解决方案的讨论都放在 BRD 之外。我有时同意那个观点,有时不同意。我犹豫不决,因为严格排除对解决方案的任何讨论(即使是概念上的)有时会让作者和读者难以理解,因为这会导致非常抽象的 brd。另一方面,对解决方案非常规范的 BRD 可能会产生我们讨论过的相同问题,当时我坚持认为 BRD 不(仅仅)包括要计算的指标列表:分析和/或数据科学团队“关闭他们的大脑”,简单地构建所要求的东西。如果所要求的解决方案不是“正确”或“最佳”的,这就会成为一个问题。

到目前为止,我的经验促使我采取一种比较中庸的方法来解决在 BRD 中假设解决方案的问题。我相信,允许业务用户在编写 BRD 时假设一个概念性的解决方案,对于让他们能够清楚地描述他们的业务问题和他们在寻找什么非常重要。另一方面,业务用户必须清楚,假设的解决方案是概念性的,实现的解决方案将来自 BRD 的评审(以及评审期间的来回对话)。分析团队将设计满足 BRD 中描述的要求的解决方案;并且该解决方案最终可能与假设的不同。

想了解更多?

为了提醒自己成功安排分析工作优先级的七(7)个关键机制,请看我的第一部分文章。如果你今天对统计学更感兴趣,试试这篇关于 A/B 测试的文章或者这篇关于三(3)个最重要的统计测试的文章。最后,如果你想在 1-2 分钟内快速阅读,请尝试这篇文章中的八(8)个技巧来改善数据科学和业务用户之间的交流。

如何在几秒钟内处理数百万行的数据帧

原文:https://towardsdatascience.com/how-to-process-a-dataframe-with-millions-of-rows-in-seconds-41c592ac8c4d?source=collection_archive---------2-----------------------

您应该知道的另一个用于数据分析的 Python 库——不,我不是在说 Spark 或 Dask

克里斯蒂安·恩格梅尔在 Unsplash 上拍摄的照片

Python 中的 ig 数据分析正在复兴。这一切都始于 NumPy,它也是我在本文中介绍的工具背后的构建块之一。

2006 年,大数据是一个慢慢受到关注的话题,尤其是随着 Hadoop 的发布。熊猫随后推出了它的数据框架。2014 年是大数据成为主流的一年,Apache Spark 也是在这一年发布的。2018 年,Dask 和其他用于 Python 数据分析的库问世。

每个月我都会发现一个新的数据分析工具,我渴望学习它。花一两个小时在教程上是值得的投资,因为从长远来看可以节省你很多时间。了解最新的技术也很重要。

虽然你可能认为这篇文章是关于 Dask 的,但你错了。我发现了另一个用于数据分析的 Python 库,您应该知道。

和 Python 一样,精通 SQL 也同样重要。如果你不熟悉它,并且你有一些闲钱,可以参加这个课程:掌握 SQL,大数据分析的核心语言

Python 中的大数据分析正在复兴

这里有几个你可能会感兴趣的链接:

- [Complete your Python analyses 10x faster with Mito](https://trymito.io/) [Product]- [Free skill tests for Data Scientists & ML Engineers](https://aigents.co/skills) [Test]- [All New Self-Driving Car Engineer Nanodegree](https://imp.i115008.net/c/2402645/1116216/11298)[Course]

你愿意多看一些这样的文章吗?如果是这样,你可以点击上面的任何链接来支持我。其中一些是附属链接,但你不需要购买任何东西。

认识 Vaex

照片由马修·施瓦茨Unsplash 拍摄

Vaex 是一个高性能的 Python 库,用于懒惰的核外数据帧(类似于 Pandas),以可视化和探索大型表格数据集。

它每秒可以计算超过 10 亿行的基本统计数据。它支持多种可视化,允许对大数据进行交互式探索。

Vaex 和 Dask 有什么区别?

照片由 Unsplash 上的静止不动

Vaex 与 Dask 不相似,但与 Dask 数据框架相似,后者建立在顶级熊猫数据框架之上。这意味着 Dask 继承了熊猫的问题,比如高内存使用率。这不是 Vaex 的情况。

Vaex 不复制数据帧,因此它可以在主存较少的机器上处理更大的数据帧。

Vaex 和 Dask 都使用延迟处理。唯一的区别是 Vaex 在需要时计算字段,而 Dask 需要显式地使用 compute 函数。

数据需要采用 HDF5 或 Apache Arrow 格式,以便充分利用 Vaex。

如何安装 Vaex?

安装 Vaex 就像安装任何其他 Python 包一样简单:

pip install vaex

我们带 Vaex 去试驾吧

尤金·希斯蒂科夫在 Unsplash 上的照片

让我们创建一个具有 100 万行和 1000 列的 pandas 数据帧,以创建一个大数据文件。

import vaex
import pandas as pd
import numpy as npn_rows = 1000000
n_cols = 1000
df = pd.DataFrame(np.random.randint(0, 100, size=(n_rows, n_cols)), columns=['col%d' % i for i in range(n_cols)])df.head()

熊猫数据帧的前几行(图片由作者制作)

这个数据帧使用多少主存?

df.info(memory_usage='deep')

我们把它保存到磁盘上,这样以后就可以用 Vaex 读取了。

file_path = 'big_file.csv'
df.to_csv(file_path, index=False)

用 Vaex 直接读取整个 CSV 不会有太大的收获,因为速度和熊猫差不多。在我的笔记本电脑上,两者都需要大约 85 秒。

我们需要将 CSV 转换为 HDF5(分层数据格式版本 5 ),以了解 Vaex 的优势。Vaex 有一个用于转换的功能,它甚至通过转换较小的块来支持比主存大的文件。

如果由于内存限制,你不能用 pandas 打开一个大文件,你可以把它转换到 HDF5 并用 Vaex 处理它。

dv = vaex.from_csv(file_path, convert=True, chunk_size=5_000_000)

该函数创建一个 HDF5 文件,并将其保存到磁盘上。

dv 的数据类型是什么?

type(dv)# output
vaex.hdf5.dataset.Hdf5MemoryMapped

现在,让我们用 Vaex 读取 7.5 GB 数据集—我们不需要再次读取它,因为我们已经在 dv 变量中有它了。这只是为了测试速度。

dv = vaex.open('big_file.csv.hdf5')

Vaex 执行上面的命令不到 1 秒钟。但是 Vaex 实际上并没有读取文件,因为懒加载,对吧?

让我们通过计算 col1 的和来强制读取它。

suma = dv.col1.sum()
suma# Output
# array(49486599)

这个真的让我很惊讶。Vaex 计算总和的时间不到 1 秒。这怎么可能呢?

无论磁盘上的文件大小如何,打开这样的数据都是即时的。Vaex 将只是对数据进行内存映射,而不是在内存中读取数据。这是处理大于可用 RAM 的大型数据集的最佳方式。

测绘

Vaex 在绘制数据时也很快。它有特殊的绘图功能 plot1d,plot2d 和 plot2d_contour。

dv.plot1d(dv.col2, figsize=(14, 7))

用 Vaex 绘图(图片由作者制作)

虚拟列

Vaex 在添加新列时会创建一个虚拟列,这是一个不占用主内存的列,因为它是动态计算的。

dv['col1_plus_col2'] = dv.col1 + dv.col2
dv['col1_plus_col2']

Vaex 中的虚拟列(图片由作者制作)

高效过滤

Vaex 在过滤数据时不会创建数据帧副本,这样内存效率更高。

dvv = dv[dv.col1 > 90]

聚集

聚合的工作方式与熊猫略有不同,但更重要的是,它们非常快。

让我们添加一个二进制虚拟列,其中 col1 ≥ 50。

dv['col1_50'] = dv.col1 >= 50

Vaex 在一个命令中结合了 group by 和 aggregation。下面的命令按“col1_50”列对数据进行分组,并计算 col3 列的总和。

dv_group = dv.groupby(dv['col1_50'], agg=vaex.agg.sum(dv['col3']))
dv_group

Vaex 中的聚合(图片由作者制作)

连接

Vaex 无需进行内存复制即可连接数据,从而节省了主内存。熊猫用户将熟悉加入功能:

dv_join = dv.join(dv_group, on=’col1_50')

结论

最后,你可能会问:我们应该简单地从熊猫转向 Vaex 吗?答案是一个大大的否定。

Pandas 仍然是 Python 中数据分析的最佳工具。它为最常见的数据分析任务提供了支持良好的功能。

谈到更大的文件,熊猫可能不是最快的工具。这是 Vaex 的绝佳切入点。

Vaex 是您应该添加到数据分析工具箱中的工具。

当处理 pandas 速度太慢或崩溃的分析任务时,从工具箱中取出 Vaex,过滤掉最重要的条目,然后继续对 pandas 进行分析。

在你走之前

Twitter 上关注我,在那里我定期发布关于数据科学和机器学习的

如何在几秒钟内处理一个数百万行的数据帧?

原文:https://towardsdatascience.com/how-to-process-a-dataframe-with-millions-of-rows-in-seconds-fe7065b8f986?source=collection_archive---------1-----------------------

TLDR;在云中使用新的 Python 数据处理引擎处理它。

杰森·黑眼在 Unsplash 上的照片

数据科学正在迎来它的复兴时刻。很难跟踪所有新的数据科学工具,这些工具有可能改变数据科学的工作方式。

我最*才在与一位同事的交谈中了解到这个新的数据处理引擎,他也是一名数据科学家。我们讨论了大数据处理,这是该领域创新的前沿,这个新工具突然出现了。

虽然 pandas 是 Python 中事实上的数据处理工具,但它不能很好地处理大数据。对于更大的数据集,您迟早会遇到内存不足的异常。

研究人员很久以前就面临这个问题,这促使了像 Dask 和 Spark 这样的工具的开发,这些工具试图通过将处理分配给多台机器来克服“单台机器”的限制。

这一活跃的创新领域也为我们带来了像 Vaex 这样的工具,它们试图通过提高单台机器的内存效率来解决这个问题。

这还没有结束。您应该了解另一种大数据处理工具…

遇见真理

弗兰克·麦肯纳在 Unsplash 上拍摄的照片

Terality 是一个无服务器的数据处理引擎,在云端处理数据。无需管理基础架构,因为 Terality 会负责扩展计算资源。它的目标受众是工程师和数据科学家。

我与 Terality 的团队交换了几封电子邮件,因为我对他们开发的工具感兴趣。他们迅速回答。这些是我向团队提出的问题:

我给 the Terality 团队的第 n 封邮件(作者截图)

用 Terality 处理数据的主要步骤是什么?

  1. Terality 附带了一个 Python 客户端,您可以将其导入到 Jupyter 笔记本中。
  2. 然后,您在“熊猫之路”中编写代码,Terality 安全地上传您的数据,并负责分布式处理(和扩展)以计算您的分析。
  3. 处理完成后,您可以将数据转换回常规的 pandas 数据框架,并继续进行本地分析。

幕后发生了什么?

Terality 团队开发了一个专有的数据处理引擎——它不是 Spark 或 Dask 的分支。

目标是避免 Dask 的不完美,它没有和 pandas 一样的语法,它是异步的,没有 pandas 的所有功能,也不支持自动缩放。

Terality 的数据处理引擎解决了这些问题。

Terality 可以免费使用吗?

Terality 有一个免费计划,你可以每月处理高达 500 GB 的数据。它还为有更高要求的公司和个人提供付费计划。

在本文中,我们将关注免费计划,因为它适用于许多数据科学家。

Terality 如何计算数据使用量?(来自 Terality 的文档)

考虑一个内存总大小为 15GB 的数据集,它将由操作 df.memory_usage(deep=True)返回。sum()
对该数据集运行一(1)个操作,如。总和或一个。sort_values 总共会消耗 15GB 的已处理数据。

仅当任务运行进入成功状态时,才会记录可计费使用量。

数据隐私呢?

当用户执行读取操作时,Terality 客户端会将数据集复制到亚马逊 S3 上 Terality 的安全云存储中。

Terality 对数据隐私和保护有严格的政策。他们保证不会安全地使用和处理这些数据。

Terality 不是存储解决方案。他们最多会在 Terality 的客户端会话关闭后 3 天内删除您的数据。

Terality 处理目前在法兰克福地区的 AWS 上进行。

有关更多信息,请参见安全章节。

数据需要公开吗?

不要!

用户需要在他的本地机器上访问数据集,Terality 将在后台处理上传过程。

上传操作也是并行的,因此速度更快。

Terality 能处理大数据吗?

此刻,2021 年 11 月, Terality 还在测试中。它针对高达 100–200 GB 的数据集进行了优化。

我问团队他们是否计划增加这一数量,他们计划很快开始针对 TB 进行优化。

让我们试驾一下吧

尤金·希斯蒂科夫在 Unsplash 上拍摄的照片

我很惊讶你可以简单地用 Terality 的包替换 pandas import 语句并重新运行你的分析。

注意,一旦导入了 Terality 的 python 客户端,数据处理就不再在本地机器上执行,而是通过 Terality 的数据处理引擎在云中执行。

现在,让我们安装 Terality 并在实践中试用它…

设置

您只需运行以下命令即可安装 Terality:

pip install --upgrade terality

然后你在 Terality 上创建一个免费账户,并生成一个 API 密匙:

Terality 上生成新的 API 密钥(作者截图)

最后一步是输入您的 API 密钥(也用您的电子邮件替换电子邮件):

terality account configure --email your@email.com

让我们从小处着手…

现在,我们已经安装了 Terality,我们可以运行一个小例子来熟悉它。

实践表明,在使用 Terality 和 pandas 时,您可以两全其美——一个用来聚集数据,另一个用来本地分析聚集数据

下面的命令创建了一个 terality。通过导入熊猫的数据帧。数据帧:

**import** **pandas** **as** **pd**
**import** **terality** **as** **te**df_pd = pd.DataFrame({"col1": [1, 2, 2], "col2": [4, 5, 6]})
df_te = te.DataFrame.from_pandas(df_pd)

现在,数据在 Terality 的云中,我们可以继续进行分析:

df_te.col1.value_counts()

运行过滤操作和其他熟悉的 pandas 操作:

df_te[(df_te["col1"] >= 2)]

一旦我们完成了分析,我们可以用以下方法将其转换回熊猫数据框架:

df_pd_roundtrip = df_te.to_pandas()

我们可以验证数据帧是否相等:

pd.testing.assert_frame_equal(df_pd, df_pd_roundtrip)

让我们去大…

我建议你查看一下 Terality 的快速入门 Jupyter 笔记本,它会带你分析 40 GB 的 Reddit 评论数据集。他们也有一个较小的 5 GB 数据集的教程。

我点击了 Terality 的 Jupyter 笔记本,处理了 40 GB 的数据集。它在 45 秒内读取数据,需要 35 秒进行排序。与另一个表的合并花费了 1 分 17 秒。感觉就像我在笔记本电脑上处理一个小得多的数据集。

然后,我尝试在我的笔记本电脑上加载同样的 40GB 数据集,其中有熊猫,内存为 16gb——它返回了一个内存不足的异常。

官方 Terality 教程带你分析一个带有 Reddit 注释的 5GB 文件。

结论

斯文·舍尔梅尔在 Unsplash 上的照片

我玩了相当多的 Terality,我的经验是没有大问题。这让我很惊讶,因为他们正式仍在测试中。一个很好的迹象是,他们的支持团队非常积极。

当您有一个无法在本地机器上处理的大数据集时,我看到了一个很好的 Terality 用例——可能是因为内存限制或处理速度。

使用 Dask(或 Spark)将需要启动一个集群,这比使用 Terality 来完成分析的成本要高得多。

此外,配置这样一个集群是一个繁琐的过程,而使用 Terality,您只需要更改 import 语句。

我喜欢的另一件事是,我可以在我的本地 JupyterLab 中使用它,因为我有许多扩展、配置、黑暗模式等。

我期待着团队在未来几个月里在 Terality 方面取得的进展。

照片由皮特·佩德罗萨Unsplash 上拍摄

如何使用 Python 在 Plotly 中制作动画柱状图

原文:https://towardsdatascience.com/how-to-produce-an-animated-bar-plot-in-plotly-using-python-2b5b360492f8?source=collection_archive---------16-----------------------

让您的原始数据集产生一个动画条形图

图片由作者斯蒂芬·福特汉姆提供

绘制美国各县的抗生素处方率

本教程详细介绍了如何使用 Python 中的 Plotly 库将原始数据转换成动画条形图。本教程中使用的数据集标题为:

从 2010 年开始,提供者所在县的儿童医疗补助参保者的潜在可避免抗生素处方观察率和风险调整率

数据集可以通过数据世界找到。具体来说,我们的目标是绘制 2010 年至 2016 年美国各县抗生素处方率/100 次就诊的动画柱状图。

准备数据

首先,我们首先导入 pandas 库和 plotly express。此外,在处理数据集时,查看所有行和列有时会很有用。为此,我们可以将“显示最大行数”和“显示最大列数”都设置为 None,如下所示。但是,重要的是要考虑到应用此设置时,较大的数据集将需要加载器来加载。最后,我们可以在我标记为“潜在可避免抗生素处方率. csv ”的数据集中阅读。

图 1:GitHub Gist;初始设置

每年的条目

我们可以首先确定数据集中县的数量。这将使我们能够破译每个县存在了多少年的信息。这里有 63 个不同的县,dataframe 总共有 441 行,这意味着每个县有 7 年的可用数据。

图 2:无序的数据格式

将数据放入动画条形图的正确形状中

为了绘制动画条形图,我们需要将数据配置为不同于当前的格式。我们需要在单个数据框架中按照年份顺序排列每个县。为了说明这一点,下面的 dataframe 图像片段显示了所需的格式。

简单明了的数据争论可以将格式从上面的图 2 变成下面的图 3。

图 3:正确格式化的数据。在单个数据框架中按年份顺序排列的县

数据争论

为了重新组织数据,我们首先使用 list comprehension 创建一个从 0 到 63 的键列表。然后,我们可以实例化一个空字典,遍历键列表和唯一的县列表。通过每次循环,我们为每个县创建一个新的数据框架,首先按最早年份排序。最后,我们可以将新的数据帧添加到 all_dataframes 字典中,该字典在每个循环中都被分配了一个唯一的键值。

然后,我们可以使用唯一键遍历所有数据帧,并添加到所有数据帧的列表中,称为 master_df。

使用 pandas 的 pd.concat 函数,所有这些数据帧最终可以连接成一个数据帧。这个函数调用的输出数据帧被命名为 df_all。

实现这些步骤的简明代码如下所示

绘制县的子选择

我们可以绘制所有 63 个县的数据,或者选择一个子选项进行绘制。在这里,我们将选取 10 个独特的县进行演示。

为此,我们选择包含县的列,并调用 sample 方法,将参数 replace 设置为布尔值 True。然后我们调用 values 属性,该属性在使用 tolist()方法转换为列表之前返回一个数组。我们现在可以看到 10 个独特的选定县的列表。

我们使用这 10 个县,通过熊猫 isin 方法过滤数据框架。这将返回 plot_df 数据帧。最后的步骤包括知道我们打算在 y 轴上绘制的列的最小值和最大值,在我们的例子中,是“每 100 次就诊的观察处方率”,我们将在我们的 figure 对象上使用它作为 range_y 参数。

动画条形图

格式正确的数据,加上我们的 10 个县,现在可以绘制出来了。我们首先将 dataframe 和 x、y 轴的列以及提供者县传递给 color 参数。我们将 animation_frame 设置为 year 列,将 animation_group 设置为 Provider County 列。然后,我们使用上面为 y 轴确定的范围来设置 y 轴的合理界限,并给该图一个信息性的标题。

现在我们有了 10 个县的动画情节!

如何以编程方式从 PubChem 获取化学数据

原文:https://towardsdatascience.com/how-to-programmatically-obtain-chemical-data-from-pubchem-59762810eb1?source=collection_archive---------14-----------------------

PUG-REST 与 PUG-VIEW:简介

你有没有想过在互联网不存在的时候,科学家们是如何交流的?我也没有想过这个问题,直到我从一位和我一起工作的教授那里听到这个故事。显然,有机化学家过去常常制造新的分子,但并没有努力告诉任何人。那时候,科学家的跨学科程度比现在低得多。因此,他偶然遇到了一个想制造特殊分子的生物化学家。这也是偶然的,这位教授制造了这种类型的分子。

现在,制药公司有意花费数十亿美元[1]来制造和测试寻找新药的化学物质。自然地,机器学习被用在这个过程的每一步[2]。当然,没有大量的好数据,机器学习方法是没有用的。这就是世界上最大的免费化学数据库 PubChem 的用武之地。在本教程中,我想回顾一下以编程方式获取 PubChem 数据的方法,以防您想尝试一下。

照片由卡琳·海斯留斯Unsplash 上拍摄

有两种方法可以通过编程从 PubChem 获取数据:PUG-REST [3]和 PUG-View [4]。选择哪一个取决于您想要的数据类型。下面是如何使用这两个服务的简短介绍。请参考底部的资源,以获得这些服务所能做的更详尽的列表。

目录:

帕格托

PUG-REST 提供了一种通过 URL 访问数据的方法,它看起来像这样(是“https://pub chem . NCBI . NLM . NIH . gov/REST/PUG”):

/ / /

您使用 <输入> 来告诉服务要寻找哪种化合物或物质。例如,如果我想查找阿司匹林,我可以像这样构造/:

<序言>/化合物/名称/阿司匹林

这里, <输入> 被分解成 3 个部分。首先,我告诉服务记录的类型,即“复合”然后,我想按“姓名”进行搜索这个名字就是“阿司匹林”这个链接给了我一个 XML 文件,其中包含了 PUG-REST 关于阿司匹林的所有信息。假设我只想要阿司匹林的分子量。我可以这样做:

<序言>/化合物/名称/阿司匹林/性质/分子量

这里的是研究阿司匹林的“属性”并检索“分子量”然后,假设我不喜欢 XML,我想用 JSON 来代替它:

/化合物/名称/阿司匹林/属性/分子量/json

PUG-VIEW

通过 PUG-View 检索数据的方式与 PUG-REST 非常相似。在本例中,序言是“https://pub chem . NCBI . NLM . NIH . gov/rest/pug _ view”。假设我想知道帕格-维尤对阿司匹林有什么看法:

<序言>/数据/复合/2244

在这里,2244 是阿司匹林的 CID,代表化合物 ID。这个链接给了我 PUG-View 所有关于阿司匹林的信息。为了缩小范围,我这样做

<序言>/数据/复合/2244?标题=熔点

询问阿司匹林的熔点。如果你看看这个链接,你会发现它不仅仅是一个数字,而是多个数字和注释。这就引出了我的下一点。

有什么区别?

首先,PUG-REST 检索由 PubChem 计算的信息,而 PUG-View 为您提供从其他来源收集的信息以及注释。这意味着如果你想要实验数据,你应该首先查看 PUG-View。有关允许标题的列表,请参见[5]。如果你点击“化学和物理属性”,然后点击“实验属性”,你会看到“熔点。”因此,使用上面的模板,你可以获得这个列表中关于阿司匹林(和其他化合物)的其他类型的信息,如沸点或密度。

第二,我没有使用“阿司匹林”这个名字在 PUG-View 中查找它的信息。这是因为,与 PUG-REST 不同,PUG-View 只将任务 CID 作为其输入。关于标识符的完整列表,您可以使用 PUG-REST,参见[3]。

第三,使用 PUG-REST,您可以检索多个标识符的信息。例如,我可以获得 cid 为 1 和 2 的化合物的信息,如下所示

https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/cid/1,2

另一方面,PUG-View 一次只允许一个标识符。

使用策略

PUG-REST 和 PUG-View 都不是为大量(数百万)请求设计的。PubChem 有以下限制:

  • 每秒不超过 5 个请求。
  • 每分钟不超过 400 个请求。
  • 每分钟运行时间不超过 300 秒。

如果你的要求超过了这些限制,你可以联系他们来解决。

请求&美味的汤

这里有一个关于如何与 PubChem 互动的 Google Colab 笔记本。我不能保证它对所有化学品都有效。我只在阿司匹林上试过。希望这有所帮助!

关于如何与 PubChem 互动的 Google Colab 笔记本

我的更多文章

</6-common-metrics-for-your-next-regression-project-4667cbc534a7>

来源

[1]https://www . biopharmadive . com/news/new-drug-cost-research-development-market-JAMA-study/573381/

[2]https://www.nature.com/articles/s41573-019-0024-5

[3]https://pubchemdocs.ncbi.nlm.nih.gov/pug-rest

https://pubchemdocs.ncbi.nlm.nih.gov/pug-view

https://pubchem.ncbi.nlm.nih.gov/classification/#hid=72

如何正确编写 Julia 代码

原文:https://towardsdatascience.com/how-to-properly-program-julia-code-e95efe9f0085?source=collection_archive---------13-----------------------

如何在 Julia 编程语言中使用函数式编程范式

(图片由作者提供)

ulia 是一种相当新的、开创性的编程语言,早在 2012 年就发布了。在从那时到 2020 年的短暂时间内,生态系统的规模和语言的构建绝对是爆炸性的。只要看看编程语言 Github stars 的受欢迎程度,就很容易看出这种语言在过去几年里取得了多大的成就。如果你想进一步了解我为什么如此热爱这门语言,我在这里写了一整篇关于我有多爱这门语言的文章:

(src =传说中的自己,病毒性沙阿(【https://twitter.com/Viral_B_Shah/status/1319764967760056320】T2))

朱莉娅的成功最终与科学生态系统普遍经历的快速机器学习增长相关联。有趣的是,这也是我开始写关于朱莉娅的文章的时候。作为时光倒流,这里有一篇我当时写的关于语言及其在机器学习中的未来的文章。

回顾过去是很棒的,因为这让我很高兴以这种方式通过分享信息、教学和演讲做出了贡献。所以作为开场白,我要感谢你给了我发言权。此外,他们已经放弃了我在文章中抱怨的口号,我觉得很好笑!

也就是说,我已经和朱莉娅一起工作了很长时间。在这门语言中有很多不同的做事方式,这就是魅力的一部分!Julia 编程语言的编译器有一些非常酷的属性,可以在构建任何语法范例的基础上进行大量优化。

还有一件事,

需要明确的是,本文是关于优化和编写有效的 Julia 代码,而不是关于如何学习 Julia 的教程。如果你对学习这门语言感兴趣,我现在正在做一套全面的 Julia 教程,它肯定会帮助你学习这门语言。除了这篇文章,还有一些视频可以播放,真正针对更多听觉、视觉和更常见的动觉学习者。我个人来说,我从文字学的很好,所以我是程序员是一件好事!以下是 Youtube 上完整播放列表的链接,以及我最*关于 TDS 的文章:

结构

到目前为止,我假设你对类型很熟悉。你可以在 Julia 中使用关键字" struct 创建一个类型。类型只是数据类型的容器,使数据可以被函数访问。当然,数据类型也是在。要记住的一件事是,有了计算机,很多东西都要分等级。Julia 喜欢像计算机一样思考,因为它是一种编程语言,所以对于 Julia 中的类型,我们也有这些类型的层次系统。这允许我们创建子类型并创建跨类型的继承——就像我们在具有子类的面向对象编程语言中为了有效而做的那样。下面是我们如何做类似的事情:

abstract type Model endmutable struct LinearRegression <: Model
    a
    b
end

我还有一整篇文章详细介绍了如何做到这一点,你可以在这里查看:

如果我们希望编译器知道这些类型,这将提高代码的效率,我们也可以在下面的代码中声明这些类型:

mutable struct LinearRegression <: Model
    a::Float64
    b::Float64
end

构造器

我们刚刚创建的代码,

mutable struct LinearRegression <: Model
    a::Float64
    b::Float64
end

Julia 编程中所谓的“外部构造函数”假设外部构造函数被称为“外部构造函数”,我们可以假设内部一定有另一个构造函数。这个假设是正确的。Julia 在这方面的不同之处在于,我们可以使用内部构造函数作为 dispatch 中不同数据类型的初始过程。请允许我演示:

mutable struct LinearRegression <: Model
    a::Float64
    b::Float64 function LinearRegression(Xtrain::Array{Any}, ytrain::Array{Any}) end
end

现在,这已经从一个需要从函数返回的类型,变成了一个需要运行初始方法的构造函数,可能是为了计算。此外,如果我们希望 Xtrain 包含多个特性,我们可以在 DataFrame 类型下创建另一个调度函数:

mutable struct LinearRegression <: Model
    a::Float64
    b::Float64 function LinearRegression(Xtrain::Array{Any}, ytrain::Array{Any})end function LinearRegression(Xtrain::DataFrame, ytrain::Array{Any}) end
end

此外,我们可以使用简单线性回归的公式计算内部构造函数中的 a 和 b。首先,让我们看看计算 a 的公式,a 是简单线性回归所需的值之一:

# a = ((∑y)(∑x^2)-(∑x)(∑xy)) / (n(∑x^2) - (∑x)^2)

非常简单,只是一些总结,这里有一些代码来计算:

# Get our Summations:
        Σx = sum(x)
        Σy = sum(y)
        # dot x and y
        xy = x .* y
        # ∑dot x and y
        Σxy = sum(xy)
        # dotsquare x
        x2 = x .^ 2
        # ∑ dotsquare x
        Σx2 = sum(x2)
        # n = sample size
        n = length(x)
        # Calculate a
        a = (((Σy) * (Σx2)) - ((Σx * (Σxy)))) / ((n * (Σx2))-(Σx^2))

然后我们会计算 B:

b = ((n*(Σxy)) - (Σx * Σy)) / ((n * (Σx2)) - (Σx ^ 2))

现在我们将这两个插入一个“新的表达式中以示回报:

return new(a, b)

现在让我们来看看实现的。我们不会对数据帧做同样的事情,因为这将涉及到编写一个多元线性回归算法,但看看我们现在如何将这种类型用于函数会很酷。

mutable struct LinearRegression <: Model
    a::Float64
    b::Float64function LinearRegression(Xtrain::Array{Any}, ytrain::Array{Any})           Σx = sum(x)
        Σy = sum(y)
        # dot x and y
        xy = x .* y
        # ∑dot x and y
        Σxy = sum(xy)
        # dotsquare x
        x2 = x .^ 2
        # ∑ dotsquare x
        Σx2 = sum(x2)
        # n = sample size
        n = length(x)
        # Calculate a
        a = (((Σy) * (Σx2)) - ((Σx * (Σxy)))) / ((n * (Σx2))-(Σx^2))
        return new(a, b)endfunction LinearRegression(Xtrain::DataFrame, ytrain::Array{Any})end
end

现在,如果我们用两个 float64s,a 和 b 调用 LinearRegression,我们将得到一个新的“LinearRegression”类型,它继承了任何模型类型所继承的调度。然而,如果我们用两个数组来调用它,内部构造函数将被调用并返回一个新的“LinearRegression”类型,该类型仍然从模型类型继承任何分派,但是使用从我们的 LinearRegression 函数的返回中计算出的 A 和 B 值。

现在,我们可以建立一种新的预测方法,它将采用 Xtrain 数组和线性回归模型:

predict(xt::Array{Any}, m::LinearRegression) = (xt = [i = a + (b * i) for i in xt])

当然,我们总是可以把我们的抽象类型做得更进一步,把分类发挥到极致!这绝对是让我着迷的事情!我们可以说,简单线性回归是一个线性模型,是一个回归变量,是一个连续模型,是一个机器学习模型…等等。

abstract type Model end
abstract type ContinuousModel <: Model endabstract type LinearModel <: ContinuousModel endmutable struct LinearRegression <: LinearModel
    a::Float64
    b::Float64function LinearRegression(Xtrain::Array{Any}, ytrain::Array{Any})           Σx = sum(x)
        Σy = sum(y)
        # dot x and y
        xy = x .* y
        # ∑dot x and y
        Σxy = sum(xy)
        # dotsquare x
        x2 = x .^ 2
        # ∑ dotsquare x
        Σx2 = sum(x2)
        # n = sample size
        n = length(x)
        # Calculate a
        a = (((Σy) * (Σx2)) - ((Σx * (Σxy)))) / ((n * (Σx2))-(Σx^2))
        return new(a, b)endfunction LinearRegression(Xtrain::DataFrame, ytrain::Array{Any})end
end

我们可以通过创建另一个也是线性模型的类型,然后使用这种继承将它们传递给同一个函数,从而使这变得更加有趣。对于这个例子,让我们使用线性最小二乘法:

struct LinearLeastSquare <: LinearModel
     a
     b function LinearLeastSquare(x,y)
        if length(x) != length(y)
            throw(ArgumentError("The array shape does not match!"))
        end
        xy = x .* y
        sxy = sum(xy)
        n = length(x)
        x2 = x .^ 2
        sx2 = sum(x2)
        sx = sum(x)
        sy = sum(y)
        # Calculate the slope:
        b = ((n*sxy) - (sx * sy)) / ((n * sx2) - (sx)^2)
     # Calculate the y intercept
        a = (sy - (a*sx)) / n return new(a, b)
end
end

由于所有线性模型都只是一个斜率值和一个 y 截距,因此可以安全地假设公式可能是 m * x + b,因此让我们创建一个预测方法来促进这些类型之间的共同属性:

predict(xt::Array{Any}, m::LinearModel) = (xt = [i = a + (b * i) for i in xt])

现在,我们可以通过相同的方法传递我们的两个模型,并获得我们需要的返回,而只需编写一个函数和四个构造函数—

什么?!

更进一步(面向对象编程)

正如我前面提到的,让编译器提前知道你想用什么类型,这当然是个好主意,我喜欢说尽快。但是,在编程中,有些情况下,在创建我们的新类型之前,您可能不一定知道正在使用的类型。幸运的是,我们可以对外部构造函数进行一些修改,以方便类型的改变。我们可以使用{}语法做到这一点。大量的 Julian 语法实际上被修改了,以使它们更专用于处理类型,请看:

struct LinearLeastSquare{P} <: LinearModel
     a::Float64
     b::Float64
     p::P

首先,它需要在内部构造函数中。我在括号中添加了一个表示类型的变量。要明确的是,这是 type of,不是 type。最后,我将把一个新的数据类型转换为 P 的类型。正如我所说的,P 是一个变量,可以被改变,我们可以通过获取任何东西的类型,然后将该类型添加到内部构造函数的语句中来使用它。我将使用 typeof()方法来实现这一点:

function LinearLeastSquare(x,y)
        if length(x) != length(y)
            throw(ArgumentError("The array shape does not match!"))
        end
        xy = x .* y
        sxy = sum(xy)
        n = length(x)
        x2 = x .^ 2
        sx2 = sum(x2)
        sx = sum(x)
        sy = sum(y)
        # Calculate the slope:
        b = ((n*sxy) - (sx * sy)) / ((n * sx2) - (sx)^2)
     # Calculate the y intercept
        a = (sy - (a*sx)) / n
        p = 5
        P = typeof(p)return new{P}(a, b, p)

很酷吧?

但是如果 P 不是一个随机的整数,而是一个函数,我们想用这个模型来预测呢?没错,我们也可以这么做。这也将防止我们需要为我们的新类型发出函数调用。看看我们的最终代码,其中 P 作为方法的类型传递:

abstract type Model end
abstract type ContinuousModel <: Model endabstract type LinearModel <: ContinuousModel endmutable struct LinearRegression{P} <: LinearModel
    a::Float64
    b::Float64
    p::Pfunction LinearRegression(Xtrain::Array{Any}, ytrain::Array{Any})           Σx = sum(x)
        Σy = sum(y)
        # dot x and y
        xy = x .* y
        # ∑dot x and y
        Σxy = sum(xy)
        # dotsquare x
        x2 = x .^ 2
        # ∑ dotsquare x
        Σx2 = sum(x2)
        # n = sample size
        n = length(x)
        # Calculate a
        a = (((Σy) * (Σx2)) - ((Σx * (Σxy)))) / ((n * (Σx2))-(Σx^2))
        predict(xt::Array) = (xt = [i = a + (b * i) for i in xt])
        P = typeof(predict)
        return new{P}(a, b, predict)endfunction LinearRegression(Xtrain::DataFrame, ytrain::Array{Any})end
end

如果你想了解更多关于 Julia 语言中面向对象编程的知识,我最*写了一篇关于它的很棒的文章,你可以在这里查看:

结论

太棒了。我真的希望这展示了 Julia 编程语言的一些酷的和令人兴奋的属性,一些人可能会对此感兴趣。我真的很喜欢这门语言,因为它有这些很棒的属性,以及令人难以置信的灵活性。我非常感谢有像你这样的人阅读我的文章,这对我意味着整个世界。我不仅对 Julia code 感到兴奋,我也很高兴能与你分享它。祝你今天休息愉快,希望我们都有美好的一年!

堆叠时如何正确验证模型

原文:https://towardsdatascience.com/how-to-properly-validate-a-model-when-stacking-ad2ee1b2b9c?source=collection_archive---------16-----------------------

嵌套交叉验证教程

堆叠是一种结合机器学习模型的方法。有了基础模型,人们就可以用它们的预测作为另一个模型的输入,这个模型叫做元模型。当准确性是给定任务的最重要因素之一时,它会被频繁使用,这就是为什么它在机器学习竞赛中非常受欢迎。然而,进行适当的验证并不容易,对数据泄漏非常谨慎也很重要。

嵌套交叉验证的想法是在褶皱子集上交叉验证基础模型,同时在所有褶皱上进行元模型的经典交叉验证。没有图像和方案理解方法论有点复杂,我会尽可能清晰地解释整个方法论。

折叠创建和基础模型预测

像通常的交叉验证一样,我们创建折叠,这意味着我们将数据集分成大小相等的部分。堆叠时,我们至少需要 3 次折叠,分别表示为 F0、F1 和 F2。我们首先在 F0 上训练基础模型,并在折叠 F1 上计算预测:

来源:作者

然后,我们在 F1 上训练基本模型,并在 F0 上预测:

来源:作者

元模型的验证

既然基础模型产生了对折叠 F0 和折叠 F1 的预测,我们可以在 F0 和 F1 上训练元模型,并使用 F2 进行验证:

来源:作者

这种方法的关键思想是我们在训练时从不使用两次折叠。沿着从输入到基础模型预测再到元模型预测的箭头,我们使用了两条路径:

  • F0 → F1 → F2
  • F1 → F0 → F2

这样,我们避免了数据泄漏,并且可以使用 F2 文件夹来验证元模型。

嵌套交叉验证

我们可以使用以下路径在 F0 和 F1 上重复整个验证过程:

  • F1 → F2 → F0
  • F2 → F1 → F0
  • F0 → F2 → F1
  • F2 → F0 → F1

该方法被称为嵌套交叉验证,因为人们可以在折叠的子集上验证基础模型:当使用路径 F0 → F1 → F2 和 F1 → F0 → F2 时,人们可以在 F0 和 F1 上交叉验证基础模型(或者,在一个折叠上训练,而在第二个折叠上验证)。然后,当我们在两个折叠上训练和在第三个折叠上验证时,元模型发生“外部”交叉验证,3 次。

推广到 k 倍

将数据集分成 k 层。对于 k-1 个褶皱的每个子集,交叉验证 k-1 个褶皱上的基础模型:对于 k-1 个褶皱中的每个 k-2 个褶皱,在最后一个褶皱上进行训练和预测。在对基础模型进行交叉验证后,预测最后一次折叠(尚未使用)。对 k-1 个折叠组合的 k 个选择重复该过程。

有 k(k-1)(k-2)/6 条可能的路径,并且需要 k(k-1)/2 个基本模型的训练和 k 个元模型的训练。这就是为什么通常使用 k=3 更容易。

最终推论

对于最终的推论,在每一步中,我们都要比训练时多使用一倍。为了产生基础模型预测,选择任意两个折叠输入,并产生最后一个折叠的基础模型预测。然后,使用基础模型预测的所有折叠来获得测试集的元模型预测。

来源:作者

如何将 Python 包发布到 PyPi

原文:https://towardsdatascience.com/how-to-publish-a-python-package-to-pypi-7be9dd5d6dcd?source=collection_archive---------4-----------------------

了解如何发布自己的 python 包

图片来自 Pexels

在本文中,让我们了解如何开发一个 python 包,然后将其发布到 PyPi 进行分发。这是一篇带有一些高级概念的技术文章,但我将花一些时间详细介绍每个概念,并提供一个执行所有步骤的演练。python 中的程序员经常会用到各种包,比如 Pandas,NumPy 等等。以使其更加健壮,并利用 SDK 的丰富功能。为了在您的代码中使用任何这样的包,您首先需要在您的机器上安装这些包,然后将其导入到您的代码中。

当我们谈到 python 中著名的包管理工具 PIP 时,这个想法可能看起来很熟悉。为了在 python 中安装任何包,我们使用 pip install并且包被安装在我们的机器上。然而,这些包保存在一个名为 PyPi 或 Python 包索引的中央存储库中。PyPi 是 python 包的官方第三方软件仓库。无论何时运行 pip install 命令,pip 工具都会在该存储库中搜索软件包,然后将其下载并安装到您的机器或虚拟环境中。

什么是 Python 包

当谈到用 python 开发包时,第一件事就是你应该知道什么是 python 中的包和模块。你用写的任何代码。py 文件在 python 中被称为模块。模块可以导入到另一个模块中。以任何特定动作为目标的多个模块的集合可以组合在一起形成一个包。包还可以包含组织到目录和子目录中的代码。你可以从官方文档中读到更多关于 python 模块和包的内容。

图 1 —用 python 导入模块的示例代码

发布 python 包的步骤非常简单,如下所示。

1.编写您的 python 模块,并将其保存在一个目录下。

2.使用必要的信息创建 setup.py 文件。

3.为您的项目选择一个许可证并提供一个自述文件。

4.在本地机器上生成分发档案。

5.尝试在本地机器上安装软件包。

6.将包发布到 TestPyPi 存储库中,检查是否一切正常。

7.最后,将包发布到 PyPi 存储库中。

现在让我们逐一执行上述步骤,将我们的包发布到 PyPi 存储库中。

创建 python 包和目录结构以及其他文件。

您应该首先决定包的名称,然后用包的名称创建目录名。假设我们要发布一个名为“ quicksample 的包,那么这个目录应该是同名的。在其下创建另一个名为“ src 的子目录,并在 src 子目录下放置一个 quicksample.py 文件。

此外,您还应该在项目的根目录下包含一个 setup.py 文件、一个 readme.md 文件和一个许可证文件。你可以从 GitHub 链接了解更多关于许可的信息。此时,您的项目结构应该如下所示。

图 2 —打包 python 应用程序的项目目录结构

为了简单起见,我们将在 quicksample.py 文件中编写一个简单的方法,在导入后调用。

现在,让我们开始编辑 setup.py 文件。您可以使用下面的代码片段来更新您的安装文件。

安装文件准备好之后,最后一步是添加 readme.md 文件。它只是一个 markdown 文件,你可以用它来记录你的包,当它被部署的时候,或者在你的项目的 GitHub 上。

在本地机器上生成分发档案。

现在 python 包的代码几乎已经完成,您可以开始构建发行版归档文件了。归档文件是压缩文件,有助于您的包跨多个*台部署,并使其独立于*台。为了生成分发归档文件,请从您的终端运行以下命令。

python -m pip 安装–-用户–-升级 setuptools 车轮

这将升级您机器上的 setuptools 库以使用最新版本。之后,您需要从您的包的根目录运行以下命令来生成分发文件。

python setup.py sdist bdist_wheel

一旦您运行了上面的命令,您可以看到发布包将会在目录下交付,这些目录是新创建的,如下所示。除此之外,您还可以看到 egg 文件信息也在项目源代码中得到了更新。

图 3 —项目中包含的构建文件

在本地机器上安装软件包。

现在我们已经准备好了发行版文件,我们可以继续安装并导入这个包来测试它是否工作正常。为了在本地计算机上安装软件包,请从根目录运行以下命令。

pip 安装-e。

图 4 —在本地安装 python 包

如上图所示,在第一步中,我们使用命令在本地安装软件包,一旦安装完毕,我们就启动 python shell 并导入它。然后我们调用 package 方法,它将消息打印到终端。

将包发布到 TestPyPi

一旦这个包被安装到本地并且运行良好,它现在就可以被发送到 TestPyPi 存储库了。这是一个测试存储库,用于测试所有 python 包,并查看所有代码是否工作正常,以及包代码中是否有问题。这使它与官方的 PyPi 存储库隔离开来,并确保只有经过全面测试的包才被部署到生产环境中。

导航到 https://test.pypi.org/的并注册成为用户。注册后,打开您的终端并运行以下命令。这将在您的机器上安装一个名为“ twine 的包,它将帮助您将 python 包发送到存储库。

python -m pip 安装—用户—升级 twine

你可以在这里阅读关于打包 python 应用程序的官方文档。在安装了 twine 包之后,首先运行下面的命令将代码发送到 TestPyPi。运行该命令时,将要求您提供在上一步中注册帐户时使用的相同凭据。

python -m twine 上传—存储库 testpypi dist/*

图 5 —将包发送到 TestPyPi

正如您在上图中看到的,python 包现在已经被发送到 TestPyPi 存储库,您可以从上面终端中的 URL 链接查看它。

为了从测试存储库中安装这个包,首先我们将卸载已经存在的包,然后运行下面的命令来安装它。

pip 卸载快速示例

pip install-Ihttps://test.pypi.org/quicksample/快速采样==0.0.1

这将从 TestPyPi 存储库在本地系统上安装这个包。

将包发布到 PyPi 存储库

既然我们的包运行良好,是时候将它发布到官方的 PyPi 存储库中了。按照相同的步骤注册一个帐户,然后运行下面的命令将包发送到官方存储库。

python -m twine 上传分布/*

现在,您可以使用标准命令安装该软件包。

结论

恭喜您,您已经成功发布了您的 python 包。代码示例可以在这里找到。

在这篇高级文章中,我们学习了什么是 python 包,以及如何用 python 开发一个简单的包。我们还了解了 python 的第三方官方库 PyPi,开发者可以在那里发布自己的包并重用代码。你可以将你的 python 代码编译成目录轮子文件,然后这些文件将被发布在 PyPi 上。本文中尚未涉及的一些其他主题是在 PyPi 上升级您的项目并维护多个活动版本。

如何使用诗歌将 Python 包发布到 PyPI

原文:https://towardsdatascience.com/how-to-publish-a-python-package-to-pypi-using-poetry-aa804533fc6f?source=collection_archive---------12-----------------------

公开部署 Python 包的简单方法

作者:爱德华·克鲁格迪伦·罗西

邪恶星期一 Unsplash

你是否曾想创建一个 python 包供全世界使用,但又觉得太难发布?诗歌可以减轻你的忧虑,因为它让这个过程变得如此简单。

一旦你创建了你的包,诗歌将会为你做出版工作。

注意:本文假设您已经构建了一个包含诗歌的 python 包,可以发布了。如果您还没有已经创建的包,请 下载我们的示例 并跟着做。

创建一个 PyPI 帐户

要将 python 包发布到 PyPI,您必须首先拥有一个 PyPI 帐户。

如果您还没有创建,请访问 PyPI 并点击注册链接。

他们会询问您的一般信息(电子邮件、用户名、密码)并注册您的帐户。

您应该还会收到他们的电子邮件,要求您确认您的帐户注册。

一旦您完全注册,登录并前往您的帐户页面。

创建 API 令牌

现在您需要创建一个 API 令牌来连接诗歌。这个令牌将允许 poems 知道在哪里发布您的包,并允许它发布到您的帐户。

在您的帐户页面中,单击左侧的“帐户设置”链接。

向下滚动,直到看到“API 令牌”部分,然后单击“添加 API 令牌”按钮。

然后,您将为您的令牌指定一个名称和范围。

对于本例,我们将标记命名为“poetrypackagetemplate”

您还将设置范围为“整个帐户(所有项目)”,但是在实践中,最好为每个项目选择一个令牌(这就是为什么它会用警告消息通知您)。

填写完毕后,单击“Add Token”按钮创建 API 令牌。

PyPI 将生成您的 API 令牌并显示在您的屏幕上,但只是现在,所以请务必复制它或让这个页面打开,直到我们将其连接到诗歌。

为您的 PyPI 凭证创建环境变量

现在您已经有了一个连接到 PyPI 帐户的 API 令牌,我们可以将这个令牌交给 poems,这样它就知道在哪里发布您的包了。我们可以通过创建保存您的凭证的环境变量来做到这一点,然后我们可以将凭证传递给 poems 的 publish 命令。

继续打开终端(Windows 上的 git-bash ),确保您在 python 包或我们的示例包的目录中。

然后在 macOS 或 Linux 上运行这些命令:

export PYPI_USERNAME=__token__export PYPI_PASSWORD=<Your API Token>

运行这些命令(在 Windows 上):

set PYPI_USERNAME=__token__set PYPI_PASSWORD=<Your API Token>

就是这样!poem 现在准备将您的 python 包发布到 PyPI。

用诗歌出版包裹

要完成出版物,您需要再运行一个命令。

poetry publish --build --username $PYPI_USERNAME --password $PYPI_PASSWORD

然后,poems 将开始构建您的 python 包并将其发布到 PyPI。

一旦完成,您的软件包将会在您的 PyPI 帐户上,并且可以通过 pip 安装!

结论

从这篇简短的文章中可以看出,将 python 包发布到 PyPI 是轻而易举的事情。

如果您愿意,您可以通过简单地运行

pip install <Your Package Name>

祝贺您发布 python 包!

如果你想了解更多关于诗歌的信息,请查阅克里斯托弗·西德博特姆的这篇文章:

如何使用 Julia 和 Genie 将您的数据科学项目发布为 Web 应用程序

原文:https://towardsdatascience.com/how-to-publish-your-data-science-or-machine-learning-project-as-a-web-app-using-julia-and-genie-e83d2733806d?source=collection_archive---------27-----------------------

沟通通常是数据科学项目不可或缺的一部分,整个业务都是围绕公开数据科学过程的结果而构建的。例如,像 wyscout 和 StatsBomb 这样的*台收集足球数据,并以网络应用的形式展示他们对数据的分析。

在本指南中,我简要介绍了如何开始使用编程语言 Julia 和 Julia web framework Genie 为您的数据科学项目构建 web 应用程序。来自一个研究项目的公开可用的玩家价值分析被用作一个示例用例。

声明:我写这篇文章是我自己学习茱莉亚和精灵过程的一部分。这两方面我都不是专家。

安装朱莉娅

要安装 Julia,请遵循https://julialang.org/downloads/platform/的说明。确保 Julia 可执行文件被添加到PATH中,这样您就可以从命令行使用julia命令。

设置您的项目

是时候建立项目了。首先,为项目创建一个目录,并在命令行中导航到该文件夹:

mkdir projectname
cd projectname

如果您愿意,现在也是为项目设置版本控制的好时机。例如,要将文件夹设置为一个 Git repostir,在命令行上执行git init

接下来,我们将为项目设置一个虚拟环境。您可能熟悉 Python 等其他编程语言的虚拟环境。虚拟环境是一种有用的工具,有助于保持不同项目所需的依赖关系是独立的,因为每个虚拟环境中的依赖关系都与同一台机器上任何其他虚拟环境中的依赖关系相隔离。Julia 中的虚拟环境是通过内置的包管理器Pkg创建的。

为了创建虚拟环境,

  1. 从命令行执行julia打开茱莉亚 REPL
  2. 在朱丽亚·REPL 中执行]进入Pkg REPL,并且
  3. Pkg REPL 内执行activate .

这将为您的项目创建并激活虚拟环境。此外,文件Project.tomlManifest.toml将被创建在projectname文件夹中。正如它们的扩展名所示,这些文件以 TOML 格式编写,用于管理您的项目依赖关系。有关Pkg的更多信息,请参见http://pkgdocs.julialang.org/v1/api/

创建精灵 Web 应用程序

本节主要是官方精灵教程的缩略版。如果你觉得 Genie 有趣,我推荐你看完整的教程,在这里可以找到。

安装精灵

现在是时候安装精灵了。简而言之,

Genie 是一个全栈 MVC web 框架,它促进了在 Julia 中开发现代 web 应用程序的简化和高效的工作流。——精灵

要安装 Genie,在激活项目虚拟环境的情况下,从Pkg REPL 中执行add Genie。如果你关闭了它,只需运行projectname目录中的julia --project <filepath>来打开茱莉亚 REPL,激活你的虚拟环境,并输入]进入Pkg REPL。

执行add Genie后,您可以通过使用退格键或CTRL+C退出Pkg REPL 并返回到朱莉娅·REPL 来验证安装。然后,尝试用using Genie导入精灵。如果没有返回错误,则说明 Genie 安装正确。

实例化一个精灵 Web 应用程序模板

现在我们已经安装了 Genie,是时候为项目设置 web 应用程序了。打开朱莉娅·REPL,导入精灵,执行

Genie.newapp_webservice("webapp")

这将在projectname目录中创建一个webapp文件夹,其中包含您的数据科学项目的简单框架 web 应用程序。

启动你的应用

你现在可以从朱莉娅·REPL 的网站上使用

using Genie
Genie.loadapp()
up()

并通过在浏览器中导航到 http://localhost:8000/ 找到它。您应该会在 web 应用程序的登录页面上看到一条股票欢迎消息。

发布您的数据科学项目

现在是时候发布你的数据科学项目了。作为一个示例项目,我将使用论文“行动比目标更响亮:重视足球运动员的行动”中的数据由 Tom Decroos、Lotte Bransen、Jan Van Haaren 和 Jesse Davis 通过 GitHub 知识库提供

评估球员在足球比赛中的影响的传统指标集中在进球等罕见的动作上。因此,研究论文提出了一种技术,用于为所有单独的足球动作赋值,包括那些没有进球的动作。出于本指南的目的,我们将仅利用 2018 年 FIFA 世界杯的数据。

这个小项目的目标是将 2018 年 FIFA 世界杯球员分析作为一个网络应用程序展示给所有人。

下载数据

webapp目录下创建一个data目录,并将文件player_stats.csv下载到该文件夹中。你可以在这里找到文件。文件的完整路径应该是projectname/webapp/data/player_stats.csv。我建议您浏览一下文件的内容,看看不同的列。

定义播放器数据结构

现在是时候将数据加载到程序中了。打开webapp目录下的routes.jl文件。当用户访问 web 应用程序的页面时,该文件负责执行正确的代码。它已经包含了一些代码,即,

using Genie.Routerroute("/") do
 serve_static_file("welcome.html")
end

这是在创建了框架 web 应用程序后负责向您显示欢迎使用 Genie 页面的代码。

现在是时候添加适当的数据结构来包含从player_stats.csv文件发布的信息了。添加以下struct:

struct Value
  total::Float64
  offensive::Float64
  defensive::Float64
endstruct Player
    name::String
    minutes_played::Int
    value_per_minute::Value
end

加载玩家数据

定义了Player数据结构后,是时候从player_stats.csv文件构建Player了。由于它是以 CSV 格式存储的,我们将使用CSV包来加载文件。要安装它,打开一个Pkg REPL 和add CSV

接下来,通过将using CSV添加到routes.jl的顶部来导入包。最后,通过添加列表理解从player_stats.csv加载数据

players = [
  Player(player.player_name, player.minutes_played, 
         Value(
           player.vaep_rating,
           player.offensive_rating,
           player.defensive_rating))
  for player in CSV.File("data/player_stats.csv")
]

下面是Player的定义。

展示数据

通过在文件顶部添加using Genie.Renderer.Html来导入Genie.Renderer.Html。然后,向/players子页面添加一条新路线

route("/players") do
  html(:players, :index, players=players)
end

routes.jl的底部。对html的调用将玩家列表作为输入,同时输入两个符号来指示呈现玩家的 HTML 模板的位置。作为输出,通过调用 Genie 的模板引擎填充模板,返回 HTML 格式的字符串。然而,要做到这一点,模板文件

  • webapp/app/layouts/app.jl.html,以及
  • webapp/app/resources/players/views/index.jl.html

必须被创造。

文件webapp/app/layouts/app.jl.html应该包含

并且webapp/app/resources/players/views/index.jl.html应该包含

两个模板文件都类似于 HTML,但是在<%%>标签之间嵌入了代码。这些是 Genie 模板引擎的命令。app.jl.html文件包含场地的总体布局。目前,我们最感兴趣的是负责渲染玩家名单的index.jl.html。在该文件中,嵌入代码在第 2–14 行的Player的输入列表上循环,循环体访问每个Player结构的字段,将数据插入到适当的 HTML 结构中,以便在浏览器中呈现。

一切就绪!

有了模板,网络应用程序可以再次从朱莉娅 REPL 与

using Genie
Genie.loadapp()
up()

如果你导航到 http://localhost:8000/players,你应该会看到页面上显示的玩家统计数据。

http://localhost:8000/players的页面应该是这样的。

下一步是什么?

如果您遵循了指南,那么您已经构建了一个简单的 web 应用程序来呈现分析结果。本指南并不是将数据科学项目发布为 web 应用的结束,而仅仅是开始。仍有很大的改进空间。

样式方面的改进可以是降低值的精度,减少空白空间的数量,以便更有效地利用屏幕空间。功能方面的改进可能包括排序或搜索,这将使数据导航更容易。最后,您可能希望从自己的数据科学项目中展示的数据可能要复杂得多,例如,包括层次结构。例如,分析每个球员的个人比赛。

你可以在 GitHub 上找到完整的项目

如何只用两个命令发布 Python 包

原文:https://towardsdatascience.com/how-to-publish-your-python-package-with-just-2-commands-39ea6a400285?source=collection_archive---------57-----------------------

大蟒

了解如何使用诗歌发布 Python 库。此外,学习如何在 TestPyPI 框架上测试您的打包。

*除非另有说明,所有使用的图片均为作者所有。

使用诗歌打包你的 Python 库从未如此简单。你可能有一个有益于他人的 Python 副业。你可以用诗歌来发表。这篇文章将向您展示如何构建自己的 Python 库,并将其发布在最流行的 Python 包存储库 PyPI 上。

我将使用我最*的一个 Python 项目, PyPocket :一个用于 Pocket 的 Python 库(包装器)(以前称为 Read It Later)。

先决条件

1.项目环境

您需要在 poem 中管理您的项目环境,因为我们将使用pyproject.toml文件来构建我们的包并发布它。

你可以查看我在 上的帖子如何使用 Conda 和 poem设置你的 Python 环境。如果你没有使用 Conda,你可以按照我在帖子中提供的步骤,而是使用其他环境管理系统,如 PipenvVirtualenv

2.包存储库

我们需要一个包存储库来存放 Python 包;最受欢迎的是 PyPI 。因此,如果您想在 PyPI 上发布您的库,您需要首先在 PyPI 上创建一个帐户。

包装说明

步骤 1:构建您的包

准备好要发布的 Python 包后,首先需要在包含pyproject.toml文件的目录中使用以下命令构建包:

poetry build

诗歌创作的输出

上面的命令将在dist(发行版)目录下创建两个文件。如果没有dist文件夹,则会创建一个文件夹。

首先,创建一个源代码发行版(通常称为 sdist ),它是基于当前*台的包的归档文件(对于 Unix 系统为.tar.gz,对于 Windows 系统为.zip)[1]。

除了 sdist,poetry build还创建了一个 Python wheel ( .whl)文件。简而言之,与源代码发行版不同,Python wheel 是一种现成的安装格式,允许您跳过构建阶段。车轮文件名通常采用以下格式[2]:

{pkg-name}-{pkg-version}(-{build}?)-{python-implementation}-{application binary interface}-{platform}.whl

从上图来看,我构建的包名为 pypocket ,版本为 0.2.0Python 3 中,即非 OS 专用(非 ABI),适合 任何 处理器架构上运行。

步骤 2:发布您的包

一旦构建了包,就可以在 PyPI(或其他包存储库)上发布它。

一个注意点:一旦你把你的包发布到 PyPI,你将无法发布一个相同的版本(你可以删除这个包,但是当你试图用相同的版本重新发布时,你会得到一个错误!我去过)。因此,建议在将包推送到 PyPI 之前对其进行测试。

在 TestPyPI 上测试您的包

首先使用 TestPyPI 框架发布您的包是一个好主意。这样,如果发布的包有问题,您可以修复它,然后在 PyPI 上发布它。TestPyPI 拥有与 PyPI 相同的设置和用户界面,但它是一个独立的框架。因此,您也需要在 TestPyPI 上创建一个帐户。

现在,让我们在 TestPyPI 上发布我们的包。首先,使用下面的命令添加 TestPyPI 作为替代的包存储库。

*poetry config repositories.testpypi [https://test.pypi.org/legacy/](https://test.pypi.org/legacy/)*

您可以将您的包发布到 TestPyPI,如下所示:

*poetry publish -r testpypi*

诗歌出版产量

poetry publish将询问您的用户名和密码(您也可以使用令牌代替,稍后将详细介绍)。请注意,源代码发行版(.tar.gz)和 Python wheel 都被上传了。一旦发布了这个包,您应该会在 TestPyPI 上看到如下内容。

你可以在这里查看https://test.pypi.org/project/pypocket/

从上面的截图可以看出,可以安装包pip install -i https://test.pypi.org/simple/ pypocket并进行测试。

在 PyPI 上发布包

一旦您对 Python 库满意了,就可以使用下面的命令将其发布到 PyPI 上:

*poetry publish*

注意,默认情况下,poems 会将一个包发布到 PyPI。因此,您不需要执行poetry config或者向poetry publish传递任何参数。

关于使用 API 令牌代替用户名和密码的一点

您可能会注意到,我在尝试发布包时使用了我的用户名和密码。我建议使用代币代替。您的 PyPI 帐户中可能有多个项目,您可以为每个项目(包)生成一个 API 令牌。如果您希望自动化 python 打包,以便在自动化部署期间不使用您的用户名和密码,这一点尤其重要。使用 API 令牌的另一个优点是,您可以轻松地删除一个令牌,甚至为一个项目生成多个令牌。

您可以通过进入您的 PyPI(或 TestPyPI)帐户的帐户设置来生成一个 API 令牌,然后在 API 令牌部分下添加一个 API 令牌。然后会提示您为您的令牌选择一个范围(将令牌用于一个特定的项目或您的所有 PyPI 项目)。在这个阶段还将提供使用令牌的指令。

结论

在这篇文章中,我们看到了如何通过两个简单的命令使用诗歌构建和发布 Python 包:poetry buildpoetry publish。为了在 PyPI 上发布 Python 包之前测试它,我们还浏览了 TestPyPI 框架。

感谢阅读。

加入我的邮件列表接收类似帖子 。也可以关注我的 LinkedIn推特

参考

[1] Python 文档,创建源代码分发

[2]布拉德·所罗门(2020),什么是 Python 轮子,为什么要关心?,真正的蟒蛇

有用的链接

* *

最初发表于【https://www.ealizadeh.com】

如何在 Python 中查询数据库连接

原文:https://towardsdatascience.com/how-to-query-database-connections-in-python-f76fb955f7a?source=collection_archive---------20-----------------------

使用 pandas.real_sql

为了便于浏览,下面是用于从雪花中查询数据的最终代码。在下面的文章中,我将分析每个步骤的原因,以及如何以同样的方式查询 MySQL 和 PostgreSQL 数据库。

导入详细信息

我选择从一个单独的文件中导入连接详细信息的原因是,我可以将该文件添加到.gitignore中,以确保没有信息被提交给在线回购。这样,即使回购变得公开,私有连接细节也保持隐藏。

请注意,这些键的命名与snowflake.connector.connect函数所需的参数完全相同。

这从例如 yaml 文件创建了一个 python 字典。

user: anthony
account: account.region
authenticator: externalbrowser
warehouse: DEV
database: DEV

对于 json 文件,上面的要点将改为使用:

import jsonwith open("snowflake_details.json", 'r') as stream:
     snowflake_details = json.load(stream)

创建连接器

照片由以色列总统府Unsplash 上拍摄

在创建snowflake_connection连接器对象时,通过使用**字典解包操作符,细节被用作函数参数。卸载的细节的键值必须与函数的参数相匹配(例如,对于 MySQL 连接,将需要host参数)。

对于 MySQL 连接,上面的要点将改为使用:

import pymysqlmysql_connection = pymysql.connect(host='', user='', password='',
                                   db='' port='')

或者对于 PostgreSQL 连接:

import psycopg2postgresql_connection = psycopg2.connect(host='', user='',
                                        password='', db='', port='')

查询数据库

为了便于阅读,为我们想要运行的查询创建一个字符串变量通常更容易。对于更大的查询,使用三个双引号"""query"""而不仅仅是双引号"query”,使得查询能够像上面的要点一样整齐地跨越多行。

现在我们可以使用[pd.read_sql](https://pandas.pydata.org/docs/reference/api/pandas.read_sql.html)从一个查询和一个连接中立即创建一个熊猫数据帧。

df = pd.read_sql(query, connection)

这比首先使用游标获取数据,然后使用该信息构建 pandas 数据框架的方法要干净得多,后者只需要更多的步骤。

with connection.cursor() as cursor:
	sql = """
              select * 
              from table 1 
              limit 10
              """
	cursor.execute(sql)
	result = cursor.fetchall()
	fieldnames = [i[0] for i in cursor.description]
connection.close()df = pd.DataFrame(list(result), columns=field_names)

最后的想法

我写这篇文章的主要原因是,了解了pd.read_sql之后,用 Python 查询数据库连接对我来说变得容易多了。我希望除了像三个双引号和**操作符这样的技巧之外,这篇文章也能帮助其他人。

如何查询你的熊猫数据框架

原文:https://towardsdatascience.com/how-to-query-your-pandas-dataframe-c6f7d64164bc?source=collection_archive---------19-----------------------

数据科学家对类似 SQL 的 Python 函数的看法

布鲁斯洪Unsplash【1】上拍照。

目录

  1. 介绍
  2. 多重条件
  3. 在多个特定列上合并
  4. 摘要
  5. 参考

介绍

无论您是从数据工程师/数据分析师转型,还是想成为更高效的数据科学家,查询数据框架都是返回所需特定行的非常有用的方法。需要注意的是,熊猫有一个特定的查询函数,名为query。然而,我将讨论模拟查询、过滤和合并数据的其他方法。我们将介绍一些常见的场景或问题,您可能会对您的数据提出这些问题,而不是 SQL,我们将用 Python 来完成。在下面的段落中,我将概述一些使用 Python 编程语言为 pandas 数据帧查询行的简单方法。

多重条件

样本数据。截图来自作者[2]。

作为数据科学家或数据分析师,我们希望返回特定的数据行。其中一个场景是您希望在同一行代码中应用多个条件。为了展示我的例子,我创建了一些名和姓的假样本数据,以及它们各自的性别和出生日期。这个数据显示在上面的截图中。

多个条件的例子本质上回答了一个特定的问题,就像使用 SQL 一样。问题是,在我们的数据中,出生于 2010 年至 2021 年间的人有百分之多少是男性。

下面是解决这个问题的代码(回答这个问题有几种方法,但这里是我的具体做法):

print(“Percent of data who are Males OR were born between 2010 and 2021:”,
 100*round(df[(df[‘Gender’] == ‘M’) | (df[‘Birthdate’] >= ‘2010–01–01’) & 
 (df[‘Birthdate’] <= ‘2021–01–01’)][‘Gender’].count()/df.shape
 [0],4), “%”)

为了更好地形象化这段代码,我还附上了上面这段代码的截图,以及输出/结果。您还可以应用这些条件来返回实际的行,而不是从全部行中获取行的分数或百分比。

条件代码。作者截图[3]。

以下是我们执行命令的顺序:

  • 返回带有男性Gender的行
  • 包括功能|
  • 返回Birthdate > 2010 和 2021 的行
  • 将所有这些组合起来,然后除以总行数

如您所见,这段代码类似于您在 SQL 中看到的内容。我个人认为这在 pandas 中更容易,因为它可以减少代码,同时还可以在一个容易的地方直观地看到所有代码,而不必上下滚动(但这种格式只是我的偏好)。

在多个特定列上合并

合并数据帧结果。作者截图[4]。

我们可能已经在其他教程中看到了如何将数据帧合并在一起,所以我想添加一种我还没有真正看到过的独特方法,即对多个特定列进行合并。在这个场景中,我们希望连接两个数据帧,其中两个字段在它们之间共享。可以看出,如果有更多的列,这种方法可能会更有用。

我们有了第一个数据帧 df,然后我们在第二个数据帧 df2 上合并我们的列。下面是实现我们预期结果代码:

merged_df = df.merge(df2, how=’inner’, 
 left_on=cols, 
 right_on=cols
 )

为了更好地可视化这种合并和编码,我展示了下面的截图。您可以看到下面第二个数据帧的样子,带有名称FirstLast,就像它们在第一个数据帧中一样,但是有一个新的列Numeric。然后,我们列出了想要合并的特定列,同时返回列GenderBirthdate,以及新的Numeric列。列是列的列表,命名为cols

正在合并数据帧。作者截图[5]。

如您所见,这种合并数据帧的方式是一种简单的方法,可以获得与 SQL 查询相同的结果。

摘要

在本教程中,我们看到了两个您将在 SQL 中执行的常见问题或查询,但它们是用 Python 中的 pandas 数据帧来执行的。

总结一下,下面是我们处理过的两个场景:

* Returning the percent of rows out of the total dataset from multiple conditions* Merging on multiple, specific columns to return a final datafarme with a new column

我希望你觉得我的文章既有趣又有用。如果你同意或不同意这些方法,请在下面随意评论。为什么或为什么不?这些当然可以进一步澄清,但我希望我能够阐明一些使用 pandas 和 Python 代替 SQL 的方法。感谢您的阅读!

请随时查看我的个人资料、 Matt Przybyla 和其他文章,也可以在 LinkedIn 上联系我。

我与这些公司没有关系。

参考

[1]图片由 Bruce HongUnsplash(2018)上拍摄

[2] M. Przybyla,样本数据截图,(2021 年)

[3] M. Przybyla,条件代码截图,(2021 年)

[4] M. Przybyla,合并数据框架结果截图,(2021 年)

[5] M. Przybyla,合并数据框架截图,(2021 年)

如何快速成为数据科学家

原文:https://towardsdatascience.com/how-to-quickly-become-a-data-scientist-40ec00408eba?source=collection_archive---------1-----------------------

意见

将 X 年的工作压缩到 X 个月

照片由 Trace HudsonPexels 经作者修改

正如古老的阿拉伯语所说,时光飞逝:

"时间就像一把剑:你不砍它,它就砍你。"—阿拉伯谚语

我父亲仍然对不欣赏技术的人感到生气。他解释说,当他在 20 世纪 60 年代学习时,他会花一整天在图书馆查找一条信息。今天,我们将需要整整一分钟来达到这一点。

学分当然是去网上了。

但是数据科学是一匹不同颜色的马。

数据科学是无限的。就我而言,从来没有人设法完成数据科学。然而,许多人已经成功成为数据科学家。

坦率地说,成为一名数据科学家很容易。

这很简单,因为数据科学家只不过是一个数据杂耍者。这不需要火箭科学家——尤其是有 Python 这样的助手。

事实上,看到像“成为数据科学家很棘手”、“机器学习很难”这样的东西困扰着互联网,令人沮丧。

相信我;无论您的数据科学之旅带您到哪里,您最终都会越过“数据科学家”的终点线。唯一的变数是时间

成为一名数据科学家需要多久?

其实快速成为数据科学家只有两种方法。第一种方法是使用时间机器。第二个是用这篇文章。如果你知道第三个,告诉我。

不管怎样,如果你能使用第一种方法,你就没有必要继续阅读了。如果你对第二种方式感兴趣,请继续关注我。

既然你还在这里,我想你一定很好奇。那么,事不宜迟,我们开始吧。

从数学开始

我知道,我知道。学习数学需要时间,因为它被吹捧为很难,尽管我不认为它很难。

不要误解我。我不是要你成为数学家或者创造下一个数学公式。你需要做的就是和数字交朋友,并且更加有条理。

数学将帮助你做到这一点。这是因为计算机只能理解数字。而编码需要关键性。

例如,条件语句完全基于逻辑数学。不幸的是,我反复看到这些声明被自称数据科学家的人滥用,这让我畏缩不前。

我畏缩是因为逻辑可以归结为这两个简单的真值表:

(p 或 q)表格—来源(维基百科)

(p 和 q)表—来源(维基百科)

大多数人一旦看到∧和∨这样的符号,就会感到害怕,这两个符号分别是和、或的简单写法。

如果你问我机器学习,我会说你不需要这种水*的数学。Python 的库已经为您处理了这部分。您只需要导入这些库,就可以部署您的第一个模型了。

没有附带条件。

请记住,如果你喜欢数学,它也会喜欢你。反之亦然。

尽快开始编码

拖延编码是一个巨大的错误。

我将重新表述这一点,让它变得非常清楚:

你需要尽快用代码弄脏你的手。

新人拖延编码是因为他们不知道编码什么或者如何编码。让我们来分析一下。

一方面,“什么”的问题不在于稀缺,而在于质量。换句话说,你需要编写一些能让你更快达到最终目标的代码。

要做到这一点,你需要坐下来,想想作为一名数据科学家,你想从事的行业。

例如,如果你对金融感兴趣,你可以从事欺诈检测、贷款审批或市场预测项目。这将增加你在银行、投资银行公司、保险公司等机构成为数据科学家的机会。

另一方面,如果你不知道如何编码,你需要复习基础知识,不要偏离主题:

基本要素是:

  • 变量和数据结构
  • 条件分支
  • 模块导入
  • 面向对象编程
  • 功能

非基础的有:

  • 装修工
  • 多态性
  • 递归

有了数学知识,你应该能够在编写干净代码的基础上打下基础。

你可能会说,数学和干净的代码有什么关系?

答案还是逻辑和结构化思维。数学在整理思路方面还是挺不错的。

除此之外,您应该习惯于在 web 上搜索代码解决方案。无论你面临什么样的挑战,把它贴在谷歌上,很可能没有人面临过和你一样的挑战。

这样做会节省你奋斗的时间。

不用说,我们在这里讨论的是 Python。

停止收集数据科学证书

在科技时代,当一个新手选择数据科学作为职业道路时,他们会做什么?

他们不停地堆数据科学证书,在 LinkedIn 上分享。

考不上那些证书的概率有多大?

接*于零。

就我个人而言,我一直想知道为什么人们一直吹嘘他们的数据科学成就。我从来没有做过那件事,而且我也没有打算在*期内做。

数据科学证书就像毒品一样。有些人会跳过视频课程,在不知道代码解决方案是关于什么的情况下运行代码解决方案,以获得最终好看的、可共享的证书。那是浪费时间。

然而,数据科学课程的重点是帮助你试水,知道从这个领域可以期待什么,以及除了金钱上的吸引力之外,这是否是你正确的职业道路。

如果你想为了钱成为一名数据科学家,你最好把门槛提高一点,努力成为一名医生。他们的收入是数据科学家的两倍。

现在,为了充分利用数据科学证书,您应该明智地选择课程。

例如,几年前,我参加了 IBM 在 Coursera 上开设的一门名为“人工智能(AI)入门”的课程。老实说,这完全是浪费时间。课程长达 8 小时。内容基本上围绕着回答一个问题:人工智能的优势是什么。一些你可以花 10 分钟或者更少时间去做的事情。

但是,最终,我从这次经历中学到了重要的一课。那就是当我看到一门课程没有问题要解决或者没有代码的时候,我能跑多远就跑多远。这是至关重要的。

成为一名卡格勒

Kaggle 是数据科学家的大本营。

首先,Kaggle 拥有大量最新的数据集,让你免去了搜索原始数据或收集原始数据的麻烦。

收集数据并不像听起来那么简单。一些网站,如脸书和 LinkedIn,对数据抓取和数据抓取有严格的政策。如果他们破产了,你应该准备好和他们的账户说再见。

其次,你应该知道,数据训练是数据科学管道中必不可少的一部分,需要巨大的计算能力。

Kaggle 正是通过他们的服务器提供对最先进机器的访问来提供这种服务的。这意味着您不需要一台高端计算机来运行您的模型,为您节省了大量的时间和资源。

第三,Kaggle 有一个面向数据科学的充满活力和支持的社区。每当你有一个数据科学的问题,前往讨论区,看看已经存在的线程,或者你可以开始自己的。

最重要的是,Kaggle 通过向最优秀的数据科学家提供金钱奖励,向其成员灌输竞争精神。

那么为什么要等呢?

加入 Kaggle,开始播种和收获知识。

写代码日记

互联网的一个显著特征是,你经常开始寻找一些东西,结果却在这个过程中发现了一些隐藏的宝石。

当我开始编码的时候,这是一个巨大的浪费。

你看,当我过去陷入实现一个代码特性时,我经常查找解决方案的一部分,很少查找整个解决方案。我会犯的愚蠢的错误是在路上遇到一个引人注目的特征,欣赏它,然后继续前进,好像什么都没发生过。

后来,我面临一个需要实现几乎相同特性的问题。我的记忆会让我记不住密码和信息来源。在那里,我迷失在斯达克弗洛、卡格尔和诸如此类的作品中很久了。

为了避免再次陷入同样的陷阱,我用 OneNote 创建了一个“有趣的代码”日记。日记的每一页都被分成三栏:

  • 特征
  • 密码
  • 代码注释

在我的数据科学之旅中,这种实践是一个重要的时间助推器。

不要忘记 SQL

尽管 SQL 在数据科学中至关重要,但它并没有得到应有的重视。不幸的是,Python 抢尽了风头。

然而,有趣的是,每个人都在谈论按摩数据、训练数据、可视化数据等等。然而,他们忘记了数据最重要的一点:检索数据——SQL的功能。

一个不知道如何获取数据的数据科学家就像一个不知道如何发动引擎的司机。SQL 知识的缺乏扼杀了数据科学家

除非公司将其数据存储在区块链,否则数据库是数据的唯一归属。而 SQL 是检索或更专业地说是查询这些数据的唯一媒介。

幸运的是,SQL 是最容易也是最快速学习的语言之一。如果你真的在一个周末认真对待它,你可以积累成为一名数据科学家所需的一切。

我所说的“您需要的”是指选择、更新、插入和删除查询。

外卖食品

到目前为止,我们已经讨论了一些有效而快速的实践,这些实践可能会帮助您成功获得“数据科学家”的称号。

如果我有一台时光机回到我爱上数据科学的那一天,我会接受这篇文章中概述的实践。

值得注意的是,我故意没有触及与数据科学相关的技能,比如统计、可视化、深度学习等等。这是因为所有这些技能都源于前面已经提到的。

例如,如果你擅长数学,害怕不是统计。或者,如果您发现寻找代码解决方案很容易,那么定位想要的可视化也应该不难。

最后,你不需要马上发明什么东西。作为一名数据科学家,你可以稍后再做。

现在,在我离开之前,我想向你保证,也许与你通常听到的相反,成为一名数据科学家是很容易实现的。

事实上,它可以比你预期的更快实现。你只需要聪明地投资每一分钟,而不是勤奋地投资。

这是不公*的,但这就是世界的运作方式。

如何在 Github 中快速构建自述文件

原文:https://towardsdatascience.com/how-to-quickly-build-a-readme-file-in-github-8886b98ef95a?source=collection_archive---------20-----------------------

环境设置

快速浏览 readme.so 在线工具,快速构建 Github 自述文件。

图片来自 PixabayPrettysleepy

当你开始一个新项目时,你开始编写和测试你的代码。但是,相关的文档可能仍然过时,因为没有时间更新

在这里,我提出一个简单的在线工具,叫做 readme.so ,它被特别认为可以非常快速地构建一个 readme 文件。

readme.so 概述

Readme.so 可从以下链接获得:

https://readme.so/it

它是完全免费的,只需要几分钟就可以理解它是如何工作的。Readme.so 支持多种语言,包括意大利语、法语、西班牙语和许多其他语言。

这个工具是由 Katherine Peterson 实现的,在它发布后,Github 联系了她并雇佣了她。她接受了,现在在 Github 工作。

开始新的自述文件

当您打开 readme.so 在线工具时,会出现以下屏幕:

作者图片

在左边部分有一个菜单,允许添加元素到你的自述文件,在中间部分有一个在线编辑器,在屏幕的右边部分有预览。

在左侧菜单的顶部,有一个已添加部分的列表(如下图中的红框所示)。

要添加一个元素,您可以点击左侧菜单底部的相应按钮。选定的元素会自动添加到截面列表中。你甚至可以上下移动部分。

例如,您可以按以下顺序添加元素:

  • 标志;徽标
  • 标题和描述
  • 作者
  • 装置
  • 用法/示例
  • 许可证
  • 常见问题解答
  • 致谢。

编辑元素

一旦定义了自述文件的框架,就可以开始编写每个元素的内容。如果你点击左侧菜单的一个元素,一个可编辑文本会出现在屏幕的中央,同时在屏幕的右侧会出现一个预览。

可编辑文本是用标记语言编写的,并且是用默认值预编译的。例如,默认标题如下所示:

作者图片

您可以编辑左侧部分,并根据您的项目进行定制,如下例所示:

作者图片

您在编辑器中编写的代码会实时更新,因此您可以清楚地看到自述文件的外观。

导出最终自述文件

完成自述文件后,只需点击右上角的按钮下载即可下载。

现在您已经准备好将下载的 Readme 上传到您的 Github 项目中了。😃

摘要

在这篇简短的教程中,我展示了如何通过 readme.so 在线工具快速构建 Github Readme 文件。

该工具直观且非常简单,但也允许构建复杂的自述文件。

如果您仍然需要有关 readme.so 工具用法的帮助,您可以在以下链接中找到教程:

如果你想了解我的研究和其他活动的最新情况,你可以在 TwitterYoutubeGithub 上关注我。

相关文章

https://medium.com/geekculture/the-top-25-python-libraries-for-data-science-71c0eb58723d [## 如何在 Android 设备上安装 Python 和 Jupyter Notebook

towardsdatascience.com](/how-to-install-python-and-jupyter-notebook-onto-an-android-device-900009df743f)

如何快速改变 Python 中字符串的大小写

原文:https://towardsdatascience.com/how-to-quickly-change-the-case-of-strings-in-python-a1565e383371?source=collection_archive---------12-----------------------

大写字母、小写字母、交换字母等等

戈兰·艾沃斯在 Unsplash 上的照片

字符串在我们的日常编程生活中非常常见。我们可能需要做的一个常见任务是从一个案例切换到另一个案例。

当然,在吉拉这不应该是一个独立的任务。相反,它可能只是更大任务的一小部分。

因为您的时间是宝贵的,您可以将时间投入到更有用的事情中,所以值得知道的是,您可以在 Python 中使用内置函数快速进行这种切换,而无需您执行任何实现。

让我们跳进来。

上部()

正如您所猜测的,这个方法将字符串转换成大写字符。

让我们来看看它的实际应用:

下部()

这与前一个类似:它将字符串转换成小写字符。

让我们看一个例子:

大写()

此函数仅将字符串的第一个字符转换为大写字母,并将其余所有字符转换为小写字母:

标题()

这是我不时用来准备文章标题的方法。

它主要用于将每个单词的第一个字符转换为大写,其余的字符转换为小写,并返回一个新字符串。

交换情况()

此方法用于将大小写从大写转换为小写,反之亦然。

差不多就是这样。

还有许多其他方法可以用于字符串,但是让我们把它们留到另一篇文章中。

希望这篇文章对你有用。

如何阅读蜡烛图

原文:https://towardsdatascience.com/how-to-read-a-candlestick-chart-5b6f60d6c3ea?source=collection_archive---------22-----------------------

学习如何阅读比特币图表

unsplash.com上 Austin Distel 的照片

蜡烛图可能是交易时最常用的图表之一,用于分析决策洞察力。通常交易者更喜欢蜡烛图,而不是其他形式,如条形图,因为前者提供了一个更好更清晰的时间窗口内的价格变化的视觉感知。

由于加密货币和股票交易越来越受欢迎,蜡烛图几乎随处可见。在这篇文章中,我们将探讨蜡烛图的关键组成部分,以及它们的含义。此外,我们还将讨论如何阅读这些图表,以及如何利用这些信息为自己谋利。

什么是蜡烛图?

蜡烛图通常用于表示货币、证券和衍生品的价格变动。对这些图表的分析可以帮助交易者揭示交易模式,通过分析这些模式可以做出决策。

蜡烛图有四个数据点。最高价和最低价描绘指定时间范围内的最高价和最低价。开盘价和收盘价分别表示第一个和最后一个价格。

烛台的元素

现在上图的宽框叫做主体,它代表开盘价和收盘价之间的价格 区间。如果后者高于前者开盘价,则主体为空(左边烛台)。如果开盘价高于收盘价,正文被填充。细线代表价格的高低,称为上下阴影。你会在网上看到一个影子,通常也被称为灯芯

在大多数交易工具中,使用着色更为常见。因此,我们用绿色(或蓝色)来表示收盘价高于开盘价,而不是用实心或空心的物体来表示价格的运动和方向。另一方面,我们通常用红色来表示资产价格在指定的时间窗口内下跌。

彩色烛台

如何阅读蜡烛图?

尽管前面的图展示了具有均匀长度的主体和阴影的烛台,但通常情况下并非如此。这些组成部分的长度表示特定的信息,可以帮助读者识别模式,并将其作为进入或退出市场的指标。

短身体对长身体

正如我们已经指出的,烛台的主体说明了收盘价和开盘价之间的价格范围。

绿色(或空的)烛台越长,收盘价和开盘价之间的差异就越大。从本质上说,这表明存在强大的购买压力,价格大幅上涨。同样,一个长的红色(或填充的)烛台主体表明有抛售压力。车身越长,价格下降幅度越大。

长烛台和短烛台

短阴影对长阴影

像烛台主体一样,阴影的长度也可以根据资产在指定时间框架内的完整价格范围而变化。回想一下,上下阴影分别表示货币的最高价和最低价。

影子的长度表明最高价或最低价与开盘价或收盘价之间的差异有多大。准确地说,(上影)的长度被定义为交易时段的最高价与开盘价和收盘价的最大值之差(取决于主体的颜色)。同样,(下影线)是最低价和最低收盘价与开盘价之差。

结论

在这篇文章中,我们探讨了蜡烛图的组成部分,以及如何阅读和分析它,以推断价格运动和模式的见解,可以利用。

如果你将资金投资于股票和加密货币,了解如何阅读烛台非常重要,因为这将有助于你在交易时做出更好的决定。烛台可能是最能提供信息的图表之一,你可以用它来做决策。

一根蜡烛线有四个不同的数据点:最高价和最低价以及收盘价和开盘价。此外,还有一些组件可以帮助我们获取有用的信息。这些是图表的主体和阴影。通过观察单个烛台,人们可以推断出感兴趣的资产的方向和价格范围。

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

如何阅读数据科学论文

原文:https://towardsdatascience.com/how-to-read-a-data-science-paper-ca6771bcfa20?source=collection_archive---------22-----------------------

学习数据科学概念的一些提示和技巧。

在我撰写关于数据科学的 52 篇文章的过程中,我意识到我不知道如何阅读一篇论文。这些是我的笔记…

迈赫迪Unsplash 上拍摄的照片

互联网怎么看?

写完我的第 5 贴,我意识到我花了太多时间看论文。承认这一点我并不是超级自豪,但我花了~8 个小时才理解了这个方法。所以,周末我做了一些关于如何阅读科学论文的研究。

最常见的建议是,你不应该直线阅读论文,即从开始到结束。相反,你应该从高层次开始,只阅读摘要、引言和结论。在这里,你只是想对这篇论文及其贡献有一个总体的了解。有些人建议先看看这一关的数字。其他人建议也包括方法一节。

有一个非常全面的策略叫做三步法。它是由斯坦福大学的一名研究人员开发的,被广泛用于有效地了解论文的内容。

正如你可能已经猜到的,三遍阅读法包括三遍阅读,阅读深度递增:

  1. 第一遍你要仔细阅读标题、摘要和引言。也浏览标题和结论。这一步需要 5-10 分钟。
  2. 在第二遍中,你深入研究表格和数字。试着把你的时间限制在 1 小时以内。
  3. 在第三遍中,你设身处地地为作者着想,试图在精神上(或字面上)再现他们的作品。如果涉及代码,运行一些代码并检查它们的结果。如果是物理实验,了解一下使用的工具。对于新手来说,这可能需要 5 个小时以上,对于有经验的人来说,可能需要 1 个小时左右。

我的想法

在浏览了大量网页、论坛,甚至一些科学论文之后,我非常不满意。大多数建议过于笼统,因此效率很低。

提示 1——定制你的阅读风格

想清楚你想从报纸上得到什么。是的,这是更多的前期工作,但它会节省你大量的时间,特别是如果你正在阅读许多文件。

  1. 我只想要高层次的知识。如果是这种情况,大概最好还是坚持三过法中的第一关。就我而言,当我需要讨论一个话题时,我会先做第一遍,然后用一句话总结这个方法。这简化了我的沟通和对主题的理解。为你遇到的新概念开发一个一行程序也没有坏处。
  2. 我想深入了解,因为我感兴趣。仅仅因为你对材料感兴趣并不意味着它是一帆风顺的。当我喜欢一个题目的时候,真的很容易掉进兔子洞。因此,为了避免在某件事情上浪费太多时间,我首先通读了整篇文章,并列出我不知道的与相关的单词/概念。第二,我简单查一下所有概念。第三,我快速重读并总结我的发现。摘要可以是一个段落,也可以是几个项目符号,但这确实将概念联系在一起,有助于心理组块。
  3. 我想要深入的理解,因为我将要(也许)实现它。在研究前沿课题时,最好的资源往往是学术论文。所以为了了解情况,我喜欢用一句话总结一篇论文,并在下面列出利弊。看了足够多的论文,希望有几个方法能脱颖而出。从那以后,我可以专注于构建工具。

尽管如此,我们都有不同的目标、思维方式和专业水*。如果你要阅读一大堆论文,制定你自己的策略真的很有用,这三条对我来说很有效。

提示 2——动机是愚蠢的;了解你的原因

大多数人可以勉强读完一篇论文,但是深入阅读许多论文是很费力的。所以,与其“保持动力”,我试着分解动力,瞄准我心灵的关键区域。我也越来越超出了我的信誉范围,所以我还是坚持对我有用的东西:

  • 利用骄傲和自我形象。我正在写每周帖子,我不会错过一周。当事情变得艰难时,我知道我已经设定了这个目标(内部和公开),我真的不想错过它。所以我不会。
  • 激发好奇心和探索精神。我正在做的东西很酷。可能只是我,但我的学习节奏是控制我是否关心一门学科的主要因素。如果我放慢速度,让自己探索自己想要的东西,任务就会从压力变成乐趣。
  • 利用自我意识。我试着尊重自己的极限。当我的大脑塞满新的话题时,我的效率越来越低。虽然每天的“大脑容量”可以随着时间的推移而增加,但有时投资回报并不存在,最好停止。
  • 利用低期望值。有些日子会很糟糕。有些日子会很棒。当我情绪低落的时候,我只是试着继续前进。

提示 3——哪里可以找到论文

在开博客之前,我四处打听,看了一堆论坛,上面列出了 DS 论文的最佳站点。尽管有这些最初的探索,我最终还是用一个来源写了我所有的帖子——arxiv.org。一切都是免费的,而且有很多非常好的作品。该网站按概念组织,因此很容易探索与您的兴趣相关的标签,但这里有一些与 DS 相关的标签:数据库数据分析MLStats

我也曾有机地接触过其他论文,比如通过博客帖子或我正在阅读的论文的部分引用的作品。但是除非你有学术执照,否则它们很少是免费的。

摘要

现在你知道了——到目前为止对我帮助最大的三件事:

  1. 知道你想从论文中得到什么,并相应地改变你的阅读方式。
  2. 利用你的特质来保持动力。
  3. 使用arxiv.org

但是在你离开之前,这里有一些杂七杂八的建议,可能真的很有帮助。

最终快速击球手

  • 休息/小睡——利用间隔重复。
  • 对于对理解一个主题不重要的数学和算法,把它们想象成一个黑盒。通常,仅仅理解输入和输出就足以向前推进。
  • 学习新话题的一个 80/20 的好方法是看 3 个来源。有了三个来源,你通常会得到不同的观点/角度,这真的有助于理解。
  • 使用出版地点作为该论文声誉的标志。此外,在投入大量时间之前,确保这篇论文与你相关。
  • 在学习一个概念时,用一句话总结方法是最困难的,也可以说是最有价值的行动——它让你也能在心里把概念分块。
  • 我读的“学术”作品越多,我就越能适应“学术”语言。同样,我对一个主题读得越多,就越容易读懂这个主题。在这个博客系列中,该系列的前几篇论文很粗糙。但是在大约 5 篇论文之后,我开始读得更快了。

感谢阅读!我希望围绕如何有效阅读 DS 相关论文展开一些讨论。如果你有想法/技巧/窍门/问题,请留下评论!它有助于我和你的读者们一起学习。而且,它可能对你也有帮助。

如何更快地阅读和理解 Python 代码

原文:https://towardsdatascience.com/how-to-read-and-understand-python-code-faster-180ba1ba9445?source=collection_archive---------12-----------------------

如何更快地为数据科学和人工智能解释 Python 代码的快速指南

Marc-Olivier Jodoin 在 Unsplash 上拍摄的照片

“我们并不总是需要做得更多,而是需要关注得更少。”— 内森·w·莫里斯

你是否曾经想要了解关于某个特定主题或模块的更多信息,然后打开一些关于这个概念的笔记或文档。然后,你看了一眼,觉得不知所措,立马关机?

不要担心,因为你不是一个人!

当您试图学习一个关于 Python 的主题时,您通常会发现冗长的文档,其中包含简明的细节,以及您需要了解的关于该特定领域的每个概念的几乎所有内容。

找到一份写得很好的文档、高质量的研究论文和包含代码的好内容一定感觉像是天堂,但事实并非总是如此。

尽管找到了很棒的资源,但如果你不能充分利用这些可供选择的资源,那就没有意义了。这就像你发现了一本辉煌的历史古董书,可以揭示这么多的秘密,但不幸的是,你不懂语言。

虽然 Python 是一门简单的编程语言,但在学习更复杂的概念时经常会出现问题。然而,学习更快地阅读和理解 Python 文档和代码的能力是一门艺术。

在这篇文章中,让我们看看一些主要的方法,这些方法将帮助我们客观地更快地学习如何快速阅读代码,特别是对于数据科学和人工智能。我们开始吧!

快速浏览一下目录

照片由杰米街Unsplash 拍摄

“预读是游戏规则的改变者。它改变了我的生活…每个人在看过这些材料后都会变得更聪明。你也会的。”— 彼得·罗杰斯医学博士

假设您偶然发现了一个有用的资源,它将使您能够学习更多与编码相关的知识。诀窍是快速浏览代码或文档的大部分行。

一旦你看完了大部分代码行,你要么会因为什么都不懂而恐慌,要么会因为至少懂了一些东西而高兴。

不管你躺在什么谱上,都完全没问题。这一步的目标是获得对未来内容的基本直觉。一旦你阅读了代码,你的大脑就有更大的机会与特定的主题联系起来。

因此,养成浏览以下代码块或代码行的好习惯。虽然一开始你可能不明白所有的事情,但你仍然会对未来的事情有一个简要的了解。

理解有用的内容

你不需要记下整个代码块或文档。

因为你已经浏览完了内容,你甚至对你可以客观处理的许多概念有了一个简单的概念。

你猜怎么着?你不需要学习完整的代码或者阅读完整的官方模块文档。

你所要做的就是对那些代码块或文档中提到的基本内容有一个直观的理解。考虑一个 Python 中列表的简单例子。在这个数据结构中有大量的函数可用,但是您只需要知道其中的一些就可以处理 Python 中的大多数常见任务。

因此,使用您的批判性和分析性思维来找出哪些主题或哪些代码块对于您试图实现的特定任务或项目是最重要的。一旦你发现了这一步,你的生活会变得更容易。

使用引用

你不需要成为独狼主角,因为你有愿意帮助你的酷朋友。

使用 Python 代码和与数据科学和人工智能相关的项目的最大好处是,您可以获得大量精彩的资源。你需要充分利用这些资源,这样你就可以发展和积累更多的技能。

假设你必须学习一个特定的 scikit-learn 代码用于机器学习,或者一个复杂的 TensorFlow 代码用于深度学习。使用这些代码的最大好处是,你不需要浪费宝贵的时间一遍又一遍地严格学习同样的东西,却不理解它。

互联网上有这么多有用的内容,你可以利用它们来提高理解这些代码块的可信度,并更快地理解它们背后的直觉。尽可能充分利用指南、参考资料和视频教程来开发并更直观地理解编码块和文档。

请随意查看我之前关于十大免费网站的文章,通过下面提供的链接了解更多关于数据科学和机器学习的信息。

</10-best-free-websites-to-learn-more-about-data-science-and-machine-learning-f2c6d7387b8d>

保持联系

我怎么强调这个因素都不为过。

如果你不保持与编码的联系,或者你长时间停止练习,很有可能你会忘记一些东西或者不能更快地解决问题。

因此,让坚持练习一些代码成为一种日常习惯。此外,如果您正在处理特定的库模块,请确保您继续学习这些主题的更多内容,不要留下间隔。这样做有助于你保持参与度,更快地完成概念。

如果你能做些笔记供以后参考,对你将来也会有很大帮助。一旦你记下你所理解的内容,过一个月左右再回头看,你仍然可以非常快地重温这个话题。

为了理解每日编码的更多优点,我强烈推荐你们大家去看看我以前写的关于这个主题的文章。

</5-reasons-why-you-should-code-daily-as-a-data-scientist-fa7fc6dc92c4>

结论:

照片由卡勒姆·肖Unsplash 上拍摄

在本文中,我们讨论了在学习代码的过程中,根据自己的风格实施一些技巧和游戏计划会如何影响和改变理解代码的结果。

为了总结我们所学的内容,快速浏览一下代码块,这会让你对将要发生的事情有一个简单的概念。之后,你可以有选择地找出最有用的内容,把注意力集中在那些话题上。

在参考资料、指南和视频的帮助下,您可以简化工作量。最后,不断练习,让自己更快地学习这些代码!

将这些策略运用到你的日常习惯中可能需要时间来抑制,这完全没问题。一旦你投入精力在这些方法上,你将自动获得不仅更快地阅读和学习代码的能力,而且发展理解你正在处理的概念背后的简单直觉的能力。

如果你对这篇文章中提到的各点有任何疑问,请在下面的评论中告诉我。我会尽快给你回复。

看看我的其他一些文章,你可能会喜欢读!

</11-crucial-mistakes-to-avoid-as-a-data-scientist-71c29aef028>

谢谢你们坚持到最后。我希望你们喜欢阅读这篇文章。我希望你们都有美好的一天!

如何轻松阅读机器学习论文

原文:https://towardsdatascience.com/how-to-read-machine-learning-papers-easily-2555deb78d80?source=collection_archive---------12-----------------------

阅读技术论文的循序渐进法

好吧,我不会试图说服你为什么需要阅读技术和研究论文。您在日常生活中使用的几乎所有算法都来自技术文献,但以教程或更简单的演练的形式无处不在。总有一天,你很有可能会遇到一些非常深奥和简洁的问题,并且没有任何标准的教科书式的解决方案,这时解析密集的技术文献的技能就派上用场了。

图片来源: Unsplash

阅读技术文献的一些其他可靠理由是:

  1. 让自己跟上人工智能/人工智能领域的发展。这里每年发表 33000 篇新论文;其中一些肯定会提供很多信息。
  2. 想更多地了解你感兴趣的特定主题,最*的发现是什么,到目前为止已经做了什么研究,还有什么问题需要回答。
  3. 让你感到卑微的是,有很多东西我们不知道,也能完全理解。

我不会称自己为阅读论文的大师,但经过这些年的尝试和错误,我已经有了一点进步。从“怎么会有人用如此复杂的语言写作”到“嗯……这很难,但人们可以理解主要思想”的过程充满挑战,有时令人愤怒,但却是有益的。

来源:吉菲

重要的事情先来

在拿到这张纸之前,你需要知道两件事:

  1. 主题的主题是什么,例如推荐系统、计算机视觉、自然语言处理、音频处理等
  2. 你的目标是什么?你想达到什么目标?你是想对某个话题了解更多,还是想看看一篇论文是否能帮你解决你一直困扰的问题?

一旦你对这两个问题进行了排序,那么就只合成一个阅读策略。

来源?

到目前为止,您一定已经接触了许多来源,从这些来源您可以搜索到您所在领域的技术文献。有很多帖子和列表给你提供了足够多的信息,所以我不会这样做,但会提到我下载大多数论文的地方。

  1. arxiv.orgT2论文不错,但是浏览这个网站就像在一个每棵树看起来都一样的森林中迷路。更好的选择是arxiv-保持理智 ,它在浏览 arxiv 上的无数论文时保持理智。它给你一个论文的预览和摘要,也让你找到与当前论文相似的其他论文(基于 TF-IDF 排名)。安德烈·卡帕西万岁!!!
  2. 实现 —代码为的论文为您提供论文的编程实现和 Github repos。你可以尝试分叉回购,重新运行代码,以更好地理解论文的数学方面。
  3. 视频两分钟论文 是 YouTube 的一个频道,它提供了一篇论文的实践方面和相关含义的快速概述。 扬尼克·基尔彻 是另一个我有时在午餐或晚餐时观看的 YouTube 频道。
  4. 简讯 我就提一下进口 AI 对素材的干脆连贯的呈现。他们有一小部分科技故事,只是科幻故事,读起来很整洁。
  5. 播客——我会把线性题外话、会说话的机器和数据怀疑论者作为音频来源(Spotify、苹果),听起来很有趣。他们不仅谈论最新趋势,还谈论实际应用,并与行业领袖和首席数据科学家一起主持脱口秀。

来源:吉菲

怎么做的部分

现在你手里或屏幕上有一篇论文,并且有一个明确的目标,你将能够轻松地浏览它,并以更好的方式理解这篇论文。你不需要一开始就阅读高度复杂和数学繁重的论文来培养这个习惯。

Kesav Srinivasan[1]在本文中讨论了这种方法(查看参考资料),但是不同的人有适合他们的版本。

随着时间的推移,我也有了一种三步走的方法,这种方法似乎卓有成效。

三遍方法

分三次反复阅读论文。每一次迭代都有不同的目标,但是总的来说,它们都是为了更好地理解手头的文献。

第一次迭代

第一遍的目的是对文章有个大概的了解。

阅读作者姓名、标题、摘要、简介、小节标题,并阅读结论。不要读任何数学部分。查看论文中提到的参考文献。

第一遍不要花超过 15 分钟,到最后,你应该知道解决了什么问题,得出了什么结论,最重要的是,这篇论文写得好不好,是否足够中肯,让你花更多的时间。

第二次迭代

在这个阶段,你必须更加批判性地阅读论文。在翻阅纸张时做笔记和画草图,因为有了钢笔/铅笔/记号笔,这是一种积极的追求。

你仍然不必阅读任何深奥的数学方程,只需粗略地浏览一下。阅读所有的英文部分,看看你是否能给出一个粗略的算法或论文中描述的过程。

检查一下报纸上是否有任何图表。试着去理解它们,因为它们包含了大量的信息,通常是直接结果的关键。

在第二遍之后,检查是否有任何 GitHub repo 或教程出现在论文中,并尝试重新运行它以复制结果。

这一阶段需要 50 到 90 分钟。

如果你对论文的内容感到满意,并且总体上认为它会帮助你实现目标,那么,也只有这样,你才能进行第三次迭代。

在第二阶段结束时要做的一件卓有成效的事情是写一段 150 字的你所学的东西来明确你的理解。您可以稍后使用此摘要与您的小组或在线论坛进行讨论。

第三次迭代

这是承诺阶段,因为你会花很多时间在纸上,试图理解它的每一个字。

如果你的目标只是让自己熟悉一种新的方法,那么第二遍可能就足够了,但是如果你手头有一个特定的任务,你正在试图找到它的解决方案,那么继续进行第三次迭代。

在第三遍中,你将彻底阅读数学部分。你将使用一支笔和一张纸来把方程式分解到基本的层次,你将从外部资源中寻找对你来说陌生的术语和概念。

从本质上说,你是在重新创作论文,并理解论文中各种元素的本质。

最初,这一阶段可能需要几个小时,但随着你掌握技能,时间会急剧减少。

纪念

使用荧光笔或批注工具,不要打印所有的文件(出于环境原因),而是那些你觉得有必要拿在手中的文件。

这些论文是用如此复杂的语言写成的,因为读者通常是其他研究人员和从业者,他们非常熟悉技术术语、背景和上下文,因此可以很容易地解析。

你有时会感到沮丧和愤怒,因为没有什么比阅读科学期刊文章更让你感到愚蠢的了 —亚当·鲁本

对自己要有耐心。这是一项类似于骑自行车的技能,最初保持*衡似乎是一项艰巨的任务,但随着时间的推移,你会变得更好,并且会知道自行车在道路上的表现以及你必须避免的颠簸和坑洞。

尽管困难重重,但获取知识是一种高尚的追求,所以要坚持下去。人工智能的民主化不仅与 MOOCs 和可支配的更高计算能力有关,还与学术和工业研究以及相关文献的精读有关。

有时你会带着半生不熟的知识离开,但这不应该让你气馁,这意味着你需要提升自己的技能,达到你可以理解这篇论文的水*。你可以阅读一些旧的论文,为新的研究打下基础,这为你提供了很好的背景。

给作者发电子邮件,问一些有见地的问题,他们可能会花很长时间回复,但他们也在想办法用尽可能简单的语言解释他们的作品。

提醒一句

你不必每次都把报纸上的结论当成福音。这就是为什么论文的来源和作者在这里是一个重要的方面。有时候,方法和理论组织得非常好,但报告的结果是基于有偏差的数据集。这就是为什么重新实施论文,看看你是否可以复制结果是一项重要的任务。

最后

这是可选的,但我从 YouTube 系列 5 级中学到的一件有趣的事情是,我将如何按照难度递增的 5 个级别解释我刚刚从论文中学到的内容,即用 4 或 5 句话向一个孩子、青少年、大学生、研究生和专家解释。

我不知道这些论文,但它有助于向非技术观众解释概念。

参考资料:

[1]K·斯里尼瓦桑—如何阅读论文—【http://ccr.sigcomm.org/online/files/p83-keshavA.pdf

—— — —快乐阅读,保持好奇心

来源: Giphy

如果只看到几个像素,如何重建图像

原文:https://towardsdatascience.com/how-to-reconstruct-an-image-if-you-see-only-a-few-pixels-e3899d038bf9?source=collection_archive---------31-----------------------

实践教程

压缩传感快速介绍

所有可能的 2 乘 2 图像的集合,使用单个位对颜色进行编码。图片由作者提供。

图像空间是巨大的,难以置信的巨大,却又如此之小。想一想。通过考虑一个 8 乘 8 黑白像素的网格,您可以创建 18 446 744 073 709 551 616 个不同的图像。然而,在这 18 万亿张图片中,很少对人类有意义。大多数图像基本上都像二维码。那些对人类有意义的属于我们可以称之为自然图像的集合。它们代表 8x8 像素图像空间的一小部分。如果我们现在考虑百万像素的图像,自然图像覆盖的部分会变得更小,几乎无穷小,但它包含了你能想到的每一张图像。那么是什么让这些自然图像如此特别呢?你如何利用这种根本的不同来获得优势呢?

光谱空间来了

考虑下面的两张图片。两者都是 512 乘 512 像素。如果要计算像素值的直方图,他们会意识到这些分布是相同的。他们确实是。左图和右图一样,像素随机打乱。然而,它们之间有一个根本的区别。一张看起来像旧电视显示器上的静态噪音,而另一张是人脸。

左图:随机图像。右图:深色头发女性的经典测试图像。两个图像都属于 512 乘 512 图像的空间。图片由作者提供。

为了理解这些图像之间的根本区别,我们需要放弃像素空间,进入频域的领域。在数学上,傅立叶变换是从图像的像素表示到其表示为二维振荡的正弦和余弦之和的线性映射。我们现在不是用每个像素的值来描述图像,而是用每个二维正弦和余弦的振幅来描述图像。

这两幅图像在傅立叶空间中的表示如下所示。对数标度用于显示傅立叶系数的大小。这两幅图像之间的差异现在很明显。一个比另一个有更多的非零傅立叶系数。在数学术语中,我们说自然图像在傅立叶基中是稀疏的。这种稀疏性正是自然图像与随机图像的区别。因此,让我们利用这一差异为我们带来优势!

两幅图像的傅立叶变换的幅度。使用对数标度。图片由作者提供。

从少量像素中重建图像,这是一个非常不确定的问题

实际上只记录了 10%的像素。图片由作者提供。

考虑以下情况。由于某种未知的原因,你相机的大部分感光元件都有缺陷。将你刚刚拍摄的妻子(或母亲或朋友)的照片传输到你的电脑上后,照片看起来就像左图所示。你有可能恢复图像吗?

我们将假设您准确地知道哪些光电传感器在工作。用 x ∊ ℝⁿ表示未知图像(其中 n 是像素的总数,我们假设它被表示为一个向量),用 y ∊ ℝᵐ表示传感器记录的非零像素强度,我们可以写出

这里, C 是 m× n 稀疏测量矩阵。对应于有缺陷的光电传感器的所有条目都是零,并且只有 m 个非零条目与工作的条目相关联。因此,我们的目标是推断原始图像 x 给出了什么,我们只观察了它的几个像素。

从数学上讲,这是一个严重欠定的问题。我们的未知数比方程式多得多。这个问题有无数种解决方法。那么问题就归结为,在这个无限集合中,哪一个解是我们要寻找的?解决这种问题的自然方法是考虑具有最小ℓ₂范数的解。这可以形式化为以下优化问题

其解决方案简单地由下式给出

矩阵 C 对应单像素测量,其行从 n × n 单位矩阵中提取。在这种情况下,解决优化问题不会有很大帮助,因为它只会返回损坏的图像(右边的矩阵乘积减少到 C ᵀ).显然,那不行。那么,我们能做得比这更好吗?

利用光谱空间的稀疏性

当讨论自然图像的区别特征时,我们已经看到它们在傅立叶空间中是稀疏的,所以让我们利用这一点。由ψ表示从傅立叶空间到像素空间的 n × n 矩阵映射,我们的测量方程变成

其中 sx 的傅里叶变换(即x=ψs)。这仍然是一个很大程度上未确定的问题,但我们现在有了更多关于我们正在寻找的解决方案的信息。我们知道它需要稀疏。引入 s 的ℓ₀伪范数(即其非零元素的数量),我们可以将下面的优化问题公式化

不幸的是,这是一个很难解决的组合问题。为了找到解决方案,需要测试所有可能的组合。幸运的是,坎蒂斯等人。已经在他们 2006 年的开创性工作中表明,在合理的假设下,上面问题的解决方案可以通过解决下面更简单的问题来获得(具有高概率)

这里,ℓ₁范数是向量 s 的绝对值之和。现在众所周知,除了使这个优化问题凸,ℓ₁范数的使用往往有利于稀疏解。虽然这个问题是凸的,但在标准计算机上解决它仍然很有挑战性。在其余部分,我们将使用一个稍微宽松的版本,由

其中,λ是用户定义的参数,用于控制满足约束条件和所需的解稀疏度之间的权衡。这个优化问题被称为基追踪去噪。使用*似算子,可以非常快速地解决这个问题。下面是在 Julia 中使用structured optimization . JL的实现。

此外,我们可以利用这样一个事实,即对于频谱变换,矩阵矢量积ψs可以在 O(n log n)运算中计算,而不是使用快速傅立叶变换算法的 O(n)运算。

尽管到目前为止我们假设ψ是傅立叶变换,但在这段代码中,我们考虑了余弦变换,这是一种更有效的图像变换。我们现在已经配备了我们需要的一切,所以让我们回到我们最初的问题。下图比较了地面真实图像与其ℓ₁重建图像。

左:地面真实图像。右图:使用压缩感知仅使用 10%的像素重建的图像。图片由作者提供。

即使你的相机只有 10%的光电传感器正常工作,在压缩感知的框架内制定这个图像恢复问题,使我们能够恢复你实际拍摄的原始图像的相当准确的估计!显然,它仍然有点粗糙,但是,考虑到图像空间的浩瀚和我们问题的无数解决方案,你不得不承认它仍然是相当了不起的!

结论

压缩检测彻底改变了信号处理领域。如果你事先知道你正在处理的信号在给定的基础上是稀疏的,压缩感知使得从比奈奎斯特-香农采样定理所建议的少得多的样本中恢复它成为可能。此外,它允许您在采集阶段直接大规模压缩数据,从而减少所需的存储量。它还催生了令人惊讶的新技术,如莱斯大学开发的单像素相机或医学领域磁共振成像的新处理技术。我不怀疑,你也不应该怀疑,在接下来的几年里我们会看到大量的新应用。

压缩感知是一个比这篇介绍性文章所能让你想到的更深入的数学领域。有很多内容我们没有涉及,例如

  • 你实际需要的最小测量数是多少?
  • 有些测量值比其他测量值更能提供信息吗?
  • 给定基础ψ,我该如何选择这些测量值?
  • 有没有更适合图片的其他规范?

回答这些问题可能需要更多的数学知识,而这些知识在《走向数据科学》杂志上是无法合理呈现的。如果你想知道更多,我强烈建议你阅读我在这篇文章末尾链接的原始论文。你还可以查看由 Gabriel Peyré 撰写的精彩的数字之旅网站或者由 Brunton & Kutz ( 数据驱动的科学与工程 )以及相关的 YouTube 频道(此处此处)。

想要阅读更多此类内容?查看我关于低秩结构和数据驱动建模的其他文章,或者只是我的机器学习基础

如何使用代理度量来减少测试持续时间

原文:https://towardsdatascience.com/how-to-reduce-a-b-testing-duration-using-surrogate-metrics-3631c6295039?source=collection_archive---------13-----------------------

LinkedIn 开发的一种*似长期指标的方法

当运行 A/B 测试时,我们经常试图改进长期指标。然而,要正确测量长期指标的影响,需要长时间的实验。

为了解决这个问题,LinkedIn 的研究人员发表了一篇 2019 论文,概述了一种使用短期协变量的预测来取代长期指标的方法。

预测方法留给用户,但是本文概述了确保统计有效性的要求。相对于本系列中涉及的其他方法,替代指标是相当劳动密集型的,因为您必须开发一个健壮的预测模型。也就是说,努力工作是有回报的——代理度量是使用长期度量运行 A/B 测试的最健壮的选项之一。

它是这样工作的…

技术 TLDR

  1. 定义你的北极星度量标准。北极星指标定义了实验的成功/失败。
  2. 通过预测我们的北极星来开发一个替代指标。我们预测的北极星的特征必须在我们的实验时间范围内可以观察到。
  3. 在我们的实验中使用我们的替代指标。请注意,在计算统计显著性时,我们必须调整方差,以说明模型中的预测误差。

但是,到底是怎么回事呢?

让我们稍微慢下来,试着理解代理指标实际上是如何工作的。

我们什么时候应该使用替代指标?

当我们的北极星度量是需要很长时间来测量的东西时,替代度量是非常有用的。例如,让我们看看终身价值(LTV),这是我们期望从用户一生中获得的总收入。

现在,一些企业的用户生命周期非常短,但在大多数情况下,用户的生命周期是一个非常长的实验持续时间。因此,我们转向替代指标。

如何计算替代指标?

如上所述,替代度量是使用在我们的实验中观察到的预测器对北极星度量的预测。

图 1:预测的替代指标和 LTV 总和之间时间需求差异的图示。图片作者。

如图 1 所示,通过简单地使用左边的特征(蓝色),我们可以预测 LTV 的*似值。预测方法取决于创建者,但是与大多数基本预测不同,小的预测间隔非常有用。

嗯,在进行实验时,我们希望使用我们的度量方差来确定“可接受”的值范围。如果我们观察到的治疗超出了这个范围,我们拒绝零假设,并得出结论,我们的治疗有统计学意义的影响。

我们的预测误差越大,我们的“可接受”范围就越大,从而导致低功效测试。简而言之,预测区间中的较小变化增加了我们检测统计显著变化的能力。

因此,在实现替代指标时,尽量使用预测方差置信区间低的特性集和算法。

您应该如何创建代理指标?

简而言之,有代理指标,但是要讨论模型的需求以及一些最佳实践。

为了有一个静态“正确”的替代度量,该度量必须是确定北极星度量所需的唯一信息。换句话说,在我们的模型中不能有可以提高拟合度的缺失信息。

这一要求被称为普伦蒂斯标准,其数学定义如下:

图 2: Prentice 标准公式。图片作者。

这里, Y 是我们的预测值, y 是真实值。左边的概率代表我们对 y 的预测值是正确的可能性,取决于我们的替代指标 SS和处理 W 。右边的概率代表同样的情况,但排除了我们对治疗的条件。

所以如果这个等式成立, y 与用户是在治疗还是在控制无关。如果是这种情况,代理度量是预测 y 唯一需要的东西。

在实践中,几乎不可能达到这个标准,然而,我们越接**等,统计结果就越有效。

挑选指标的 3 个技巧

除了 Prentice 标准之外,还有其他三个关键概念可以产生有效的替代指标:

首先,很好地预测代理指标很重要。LinkedIn 的研究人员引用 0.69 的 R 值为有效,但好的预测的定义取决于你的用例。

图 3:有效预测的图示。图片作者。

第二,如上所述,精确的替代指标比不精确的更有效。因此,我们不仅关心高精度,还关心我们的估计有多精确。精确度可以通过我们预测区间的宽度来证明——越小越好。

图 4:宽预测区间与窄预测区间的对比图。图片作者。

第三,我们的估计最好是可以解释的。实验是用来为商业决策提供信息的,所以如果我们不能理解某些东西为什么会起作用,就很难做出那个决定,也很难形成相关的想法。

如果你能够大致满足 Prentice 标准,并遵循以上三个提示,你应该能够开发一个有效的替代指标。

改善结果的调整

现在我们知道了代理度量模型的需求,让我们理解如何使用这个度量。LinkedIn 的研究人员建议进行两项调整。

第一次调整增加了我们统计显著性计算中使用的方差,以说明预测误差引起的方差:

图 5:使用替代度量标准的北极星调整方差公式。图片作者。

在计算统计显著性时,这种调整后的方差会发挥作用。下面,我们使用 t 统计公式中的校正方差:

图 6:使用代理度量的北极星度量的 t 统计公式。图片作者。

在图 6 中,分子是我们的替代指标的*均提升,即我们的治疗和对照中的替代指标之间的差异。分母是调整后方差的*方根。Var(μs)是*均值的方差,σe是我们预测中误差的方差。注意下划线(_)表示下标。

请注意,如果我们使用的是完美的替代指标预测,即没有错误,则该等式简化为 t 统计公式。

第二个调整是可选的,但是强烈推荐。在上面的调整中,我们通过增加度量的方差极大地增加了我们的“接受”范围。因此,为了获得统计优势并消除这种差异,建议您采用一种差异缩减技术。

方差减少有多种形式,但本文引用的方法被称为 CUPED 。在一条线上,CUPED 使用实验前数据来解释数据中的自然变化并消除它,从而减少我们的方差。

LinkedIn 案例研究

LinkedIn 在预测一项功能是否有助于人们找到工作时也面临着类似的问题——工作渠道可能会持续数月。他们实现了一个替代指标,利用应用程序数据来预测用户是否会获得工作。预测值和真实值的相关系数为 0.69。

在校正方差之前,他们发现 203 次实验中有 30 次具有统计学意义。校正方差后,只有 2 个是 stat。签名。然而,使用 CUPED 方差减少技术,他们能够找到 10 个统计值。签名。实验。

实施说明

  • 作者没有研究实验的长度如何提高预测的准确性/精确度。你会期望更多的数据带来更好的预测,但这些改进高度依赖于手头的主题。
  • CUPED 对于该方法之外的方差减少是有效的,并且被 Google、网飞和 Air BnB 引用。
  • 这种方法的有效性取决于你能否预测北极星度量。如果你能开发出一个准确而精确的模型,这种方法会很有效。如果没有,那就无效了。
  • 作者指出,为不同的用户群和*台开发替代指标预测通常很有帮助。因为我们预测中的方差是特别有害的,所以有时最简单的方法是将我们的数据分组,然后分别查看

感谢阅读!我将再写 42 篇文章,将“学术”研究引入 DS 行业。查看我对开发替代指标的链接/想法的评论。

如何减少货运对环境的影响

原文:https://towardsdatascience.com/how-to-reduce-the-environmental-impact-of-freight-692f505a681b?source=collection_archive---------24-----------------------

构建一个应用程序,通过多式联运网络提供二氧化碳优化路线

维克多·哈纳切克在 picjumbo 上拍摄的照片

背景

如今,高效地运输货物和原材料对任何公司来说都是必须的。这种依赖伴随着一个重大挑战:货运约占美国温室气体排放总量的 8%。

美国排放的温室气体。来自 EPA 和 BTS 的数据[1,2]。作者图。

那么,托运人如何减少货物的碳足迹呢?权衡会是什么?

第一个问题的答案相对简单:通过使用碳密集度较低的运输方式来优化运输。第二个问题的答案更加微妙,但总的来说,使用更环保的物流解决方案将花费更少的时间到达目的地

为了演示这些答案,我构建了一个简化的模型,该模型根据出发地点、目的地位置和一些要优化的参数提供了一个优化的多式联运(铁路和公路)路线。在这篇文章中,我将带你了解这个项目,因为我希望能激励你去做一些重要的事情。

用 Dash 构建一个简化的多模态网络模拟器

我喜欢首先构建一个简化版本来开始我的项目。这有助于:

  • 快速行动,不要停留在细节上。
  • 记录在构建最终模型时需要特别注意的细节。
  • 获得瞬间的满足。
  • 与社区共享项目的非机密版本。

对于这个项目的简化版本,我用 Python 建立了一个仪表板应用程序,用户可以在其中交互式地探索一些多式联运优化路线,并了解货车运输的权衡。

数据

生成的多式联运网络。绿线是铁路段,蓝线是高速公路,红点是联运终点站。作者图。

任何使用过道路网络的人都知道这些文件在整个大陆范围内会变得有多大。因为目标是使仪表板尽可能简单,所以道路网络已经*似为公路网络。高速公路网和铁路网都可以在 BTS 数据库中找到[3]。这两个数据集已经使用 OSMnx 软件包[4]进行了清理和简化。这种简化是至关重要的,因为图相对较重,并且它包含许多带有两条可以收缩的边的节点。

优化参数

为了理解绿色运输的权衡,用户可以选择要优化的特性:CO2 排放、成本或持续时间。

二氧化碳数据基于 USLCI 数据库[5],持续时间根据轨道速度限制计算,成本通过汇总历史数据计算。

路由算法

为了找到给定参数的最佳路径,已经测试了三种简单的路由算法:Dijkstra、双向 Dijkstra 和 Astar (A*)。如果你想使用 Python,使用更高级的路径搜索算法,比如收缩层次,不是很有用,因为这种语言相对较慢。下面的 gif 展示了这些算法如何迭代寻找最优路径。由于是目标导向的,它将通过最少的迭代运行。

网络探索,寻找从夏洛特到丹佛的污染最小的路径。作者 GIF。

然而,对于每个新节点,Astar 都必须计算启发式规则,这需要时间。此外,由于大多数查询的路线将是中长途的,所以在图搜索期间经常到达图的边界,从而限制了无目标定向方法的运行时间。由于这些原因,对于这个特定的图,*均来说,最快的解决方案是双向 Dijkstra 搜索。

简单化

由于缺乏开源可用数据,必须进行简化和抽象:

  • 成本在这个项目的简化版本中具有有限的准确性,因为它们不依赖于时间,并且粒度较低。
  • 铁路路线组合可能不相关,因为假设所有组合都是可行的。事实上,铁路公司并不与所有同行合作:它们有特定的合作关系。因此,该模型提供的一些路线将不适用于现实情况,但它给出了最终模型将如何工作的良好感觉。

Dash 应用

为了让应用程序具有交互性,我使用了 Dash。Plotly 社区开发的一个方便易用的仪表板[6]。构建应用程序时最大的挑战是让它尽可能快地做出响应,以提供流畅的用户体验。因为这个应用程序是基于一个重图的,所以运行时的瓶颈在于加载图。下面是我用来减少这个瓶颈的两个简单方法:

  1. 避免为每个新请求加载整个图:不是为每个请求重新加载或重建图,而是根据选择的 rail 操作符删除边。然后在查询结束时将它们添加回去。
  2. 减少图形的内存使用:将图形简化为一个无向图,并改变变量 dtypes(即浮点到整数)

应用的部署是用 Heroku [7]完成的。你可以在这个链接上试试。请耐心等待,即使进行了上述优化,运行时间也不是一流的😅

Dash 应用。作者 GIF。

结果

在大多数情况下,多式联运排放的二氧化碳少得多,成本也低,但耗时比卡车运输长。因此,运输时间不太紧张的公司可以使用多式联运解决方案,以支付更少的费用,而且更加环保。

最终模型

在 Loadsmart,我们希望成为货运市场的第一名。我们希望为托运人提供优化和定制的解决方案,以满足他们的物流需求。为此,这个项目的最终模型将提出具有实时定价和调度的优化多式联运,通过使供应链更加绿色来帮助托运人减少运营中的碳排放。

最终模型将基于 CSA 算法[8]的修改版本,使用多标准 Pareto 集优化和模糊逻辑排序。如果社区对此感兴趣,我可以写一篇关于这个模型的文章。

感谢

除了成本数据,这个项目的简化版本完全是从开源数据、模型、服务和参考资料中构建的。

感谢整个社区分享了这么多。让我们用这些知识来为更大的目标制造工具。

你可以看看这个 Github repo 上的代码。我非常乐意收到任何反馈/问题。

笔记

[1]美国环境保护署。“美国温室气体排放和吸收汇清单”(2018)。链接

[2]运输统计局。特定货运模式的能源消耗(2018 年)。链接

[3]运输统计局|国家运输地图集数据库。链接

[4] Boeing,g .(2017)OS mnx:获取、构建、分析和可视化复杂街道网络的新方法链接

[5]美国生命周期清单数据库(USLCI)。链接

[6]阴谋破折号。链接

[7]赫罗库。链接

[8] Julian Dibbelt 等人(2013) " 有趣的简单快速的公交路线。链接

如何在 Python 中减小熊猫数据帧的大小

原文:https://towardsdatascience.com/how-to-reduce-the-size-of-a-pandas-dataframe-in-python-7ed6e4269f88?source=collection_archive---------9-----------------------

减小数据的大小有时会很棘手。在这个快速教程中,我们将演示如何通过向下转换将数据帧的大小减少一半,让您事半功倍。

Guillaume de Germain 在 Unsplash 上拍摄的照片

背景

无论您是为业余爱好项目还是为工作目的构建模型,您的第一次尝试都可能包括打开 jupyter 笔记本并读取一些数据。最终,你的笔记本肯定会遇到内存问题。在开始删除行或尝试复杂的采样技术来减小数据大小之前,应该检查数据的结构。

了解我们数据的规模

为了探索如何减少数据集的大小,我们需要一些样本数据。对于本教程,我使用的是我为 Kaggle 上的未来销售预测竞赛创建的旧数据集(这里是我关于预处理数据的文章)。完全连接和功能工程化后,数据集有 58 列和 11,128,050 条记录。对于一台小型笔记本电脑来说,这是很大的数据量。我们需要一个减少数据量的解决方案。

在我们开始之前,我们应该检查了解更多的数据。熊猫库中的 df.info()是一个非常有用的函数。

df.info(memory_usage = "deep")

这段代码 snippit 返回以下输出:

<class 'pandas.core.frame.DataFrame'>
Int64Index: 11128050 entries, 0 to 11128049
Data columns (total 58 columns):
 #   Column                                            Dtype         
---  ------                                            -----         
 0   date_block_num                                    int64         
 1   item_id                                           int64         
 2   shop_id                                           int64         
 3   target                                            float64       
 4   item_name                                         object        
 5   item_category_id                                  int64         
 6   Category_type                                     object        
 7   City                                              object        
 8   Month_End_Date                                    datetime64[ns]
 9   Number_of_Mondays                                 int64         
 10  Number_of_Tuesdays                                int64         
 11  Number_of_Wednesdays                              int64         
 12  Number_of_Thursdays                               int64         
 13  Number_of_Fridays                                 int64         
 14  Number_of_Saturdays                               int64         
 15  Number_of_Sundays                                 int64         
 16  Year                                              int64         
 17  Month                                             int64         
 18  Days_in_Month                                     int64         
 19  min_item_sale_date_block_num                      int64         
 20  Months_Since_Item_First_Sold                      int64         
 21  avg_first_months_sales_by_item_category_id        float64       
 22  avg_first_months_sales_by_item_category_and_shop  float64       
 23  target_lag_1                                      float64       
 24  target_lag_2                                      float64       
 25  target_lag_3                                      float64       
 26  target_lag_4                                      float64       
 27  target_lag_5                                      float64       
 28  target_lag_6                                      float64       
 29  target_lag_12                                     float64       
 30  avg_monthly_by_item_lag_1                         float64       
 31  avg_monthly_by_item_lag_2                         float64       
 32  avg_monthly_by_item_lag_3                         float64       
 33  avg_monthly_by_item_lag_6                         float64       
 34  avg_monthly_by_item_lag_12                        float64       
 35  avg_monthly_by_shop_lag_1                         float64       
 36  avg_monthly_by_shop_lag_2                         float64       
 37  avg_monthly_by_shop_lag_3                         float64       
 38  avg_monthly_by_shop_lag_6                         float64       
 39  avg_monthly_by_shop_lag_12                        float64       
 40  avg_monthly_by_category_lag_1                     float64       
 41  avg_monthly_by_category_lag_2                     float64       
 42  avg_monthly_by_category_lag_3                     float64       
 43  avg_monthly_by_category_lag_6                     float64       
 44  avg_monthly_by_category_lag_12                    float64       
 45  avg_monthly_by_city_lag_1                         float64       
 46  avg_monthly_by_city_lag_2                         float64       
 47  avg_monthly_by_city_lag_3                         float64       
 48  avg_monthly_by_city_lag_6                         float64       
 49  avg_monthly_by_city_lag_12                        float64       
 50  item_price_lag_1                                  float64       
 51  item_price_lag_2                                  float64       
 52  item_price_lag_3                                  float64       
 53  item_price_lag_4                                  float64       
 54  item_price_lag_5                                  float64       
 55  item_price_lag_6                                  float64       
 56  target_3_month_avg                                float64       
 57  target_6_month_avg                                float64       
dtypes: datetime64[ns](1), float64(38), int64(16), object(3)
memory usage: 7.6 GB

使用 df.info,我们可以获得以下信息:

  • 行数或条目数
  • 列数
  • 每列的索引和名称
  • 每列的数据类型
  • 数据帧的总内存使用量
  • 每种数据类型有多少列

仔细观察这个表,我们可以看到每个数据类型后面的数字说明了它们使用的位数。

由于其中许多被列为 int64 或 float64,我们可能会将它们减少到更小的空间数据类型,如 int16 或 float8。向下转换意味着我们将每个特性的数据类型减少到最低可能的类型。

## downcasting loop
for column in df:
 if df[column].dtype == ‘float64’:
 df[column]=pd.to_numeric(df[column], downcast=’float’)
 if df[column].dtype == ‘int64’:
 df[column]=pd.to_numeric(all_data[column], downcast=’integer’)## dropping an unused column
df = df.drop('item_name',axis =1)

我们可以再次检查数据帧的大小。

<class 'pandas.core.frame.DataFrame'>
Int64Index: 11128050 entries, 0 to 11128049
Data columns (total 57 columns):
 #   Column                                            Dtype         
---  ------                                            -----         
 0   date_block_num                                    int8          
 1   item_id                                           int16         
 2   shop_id                                           int8          
 3   target                                            float32       
 4   item_category_id                                  int8          
 5   Category_type                                     object        
 6   City                                              object        
 7   Month_End_Date                                    datetime64[ns]
 8   Number_of_Mondays                                 int8          
 9   Number_of_Tuesdays                                int8          
 10  Number_of_Wednesdays                              int8          
 11  Number_of_Thursdays                               int8          
 12  Number_of_Fridays                                 int8          
 13  Number_of_Saturdays                               int8          
 14  Number_of_Sundays                                 int8          
 15  Year                                              int16         
 16  Month                                             int8          
 17  Days_in_Month                                     int8          
 18  min_item_sale_date_block_num                      int8          
 19  Months_Since_Item_First_Sold                      int8          
 20  avg_first_months_sales_by_item_category_id        float32       
 21  avg_first_months_sales_by_item_category_and_shop  float32       
 22  target_lag_1                                      float32       
 23  target_lag_2                                      float32       
 24  target_lag_3                                      float32       
 25  target_lag_4                                      float32       
 26  target_lag_5                                      float32       
 27  target_lag_6                                      float32       
 28  target_lag_12                                     float32       
 29  avg_monthly_by_item_lag_1                         float32       
 30  avg_monthly_by_item_lag_2                         float32       
 31  avg_monthly_by_item_lag_3                         float32       
 32  avg_monthly_by_item_lag_6                         float32       
 33  avg_monthly_by_item_lag_12                        float32       
 34  avg_monthly_by_shop_lag_1                         float32       
 35  avg_monthly_by_shop_lag_2                         float32       
 36  avg_monthly_by_shop_lag_3                         float32       
 37  avg_monthly_by_shop_lag_6                         float32       
 38  avg_monthly_by_shop_lag_12                        float32       
 39  avg_monthly_by_category_lag_1                     float32       
 40  avg_monthly_by_category_lag_2                     float32       
 41  avg_monthly_by_category_lag_3                     float32       
 42  avg_monthly_by_category_lag_6                     float32       
 43  avg_monthly_by_category_lag_12                    float32       
 44  avg_monthly_by_city_lag_1                         float32       
 45  avg_monthly_by_city_lag_2                         float32       
 46  avg_monthly_by_city_lag_3                         float32       
 47  avg_monthly_by_city_lag_6                         float32       
 48  avg_monthly_by_city_lag_12                        float32       
 49  item_price_lag_1                                  float32       
 50  item_price_lag_2                                  float32       
 51  item_price_lag_3                                  float32       
 52  item_price_lag_4                                  float32       
 53  item_price_lag_5                                  float32       
 54  item_price_lag_6                                  float32       
 55  target_3_month_avg                                float32       
 56  target_6_month_avg                                float32       
dtypes: datetime64[ns](1), float32(38), int16(2), int8(14), object(2)
memory usage: 3.2 GB

我们看到现在有几个 8、16 和 32 位的列,通过简单地更改数据类型,我们已经有效地将数据帧的大小减半。

更有趣的是,dataframe 的内存使用量下降到了 3.2gb。这大约是我们刚开始时 7.6gb 的一半。通过这种类型的内存减少,我们可以将更多的数据加载到更小的机器上,最终降低成本。

结论

在本教程中,我们将 1100 万条记录数据集加载到熊猫数据帧中。我们学习了如何通过使用?pandas 中的 info()函数。这为我们提供了有用的信息,如行数和列数、数据帧的大小和内存使用情况以及每列的数据类型。

我们学习了向下转换,我们用它将数据帧的大小减半,这样我们可以使用更少的内存,对数据做更多的事情。

如何使用 BigQuery 分区表降低分析成本

原文:https://towardsdatascience.com/how-to-reduce-your-analytics-costs-with-bigquery-partitioned-tables-9298c274bf7d?source=collection_archive---------31-----------------------

一个有“大”结果的简单解决方案。

大查询困境

BigQuery 是当今市场上最受欢迎的数据仓库之一,但是如果你不小心的话,你可以很容易地积累一个令人虚弱的账单。如果 BigQuery 支持您的分析堆栈,那么分区表可能是降低成本的一个显而易见的解决方案。

什么是分区表?

分区表是通常按日期划分成更小的表的表。

按比赛年份划分的网球数据示例。(图片由作者提供)

分区表并不是 BigQuery 所独有的。它们最常见的是那些带有长后缀的恶名昭彰的表(如 sessions_2017_01_01,sessions_2017_01_02)。对于负责维护这些独立表的数据工程师和试图查询它们的分析师来说,这种划分总是令人痛苦的。

但是因为 BigQuery 在幕后进行分区,所以它实际上变得更加整洁,并且是工程师和分析师都想要的解决方案。

分区方式:

在 BigQuery 中,有 3 种方法可以对表进行分区:

1.按摄入时间

当新数据到达时,表将被自动分区。如果您每天都将前一天的数据转储到数据库中,那么您可能会使用这种方法。

2.按日期/时间列

表将根据指定的日期/时间列进行分区。如果摄入日期不像另一个日期/时间列(如首次购买日期)那样相关,您可以使用此选项。

3.按整数列

这可能是最不常用的方法,它允许您基于一个整数列(例如客户号)创建一个分区。

注意:对于分类列上的分区(例如客户细分),请查看聚集表。

为什么使用它们?

使用分区表有两个主要好处:

1.他们会解决你的“阻塞表”问题。

数据工程师必须解决的首要挑战之一是如何在不阻止其他用户同时提取数据的情况下更新表。分区表是实现这一点的一种方式。如果每天都向表中插入数据,这些数据将作为自己的分区添加,而不会阻止人们访问其他分区。得分。

2.他们效率更高(翻译:更便宜)。

BigQuery 对查询返回的数据收费。也就是说,你的查询效率越高,你支付的费用就越少。

如果你问我的话,这足以成为尝试分区表的理由。

为了证明分区表的效率到底有多高,我用杰夫·萨克曼的网球数据进行了一些测试(谢谢杰夫🙏),它拥有从 20 世纪 40 年代至今几乎所有 ATP 和 WTA 网球比赛的比赛统计数据。

数据预览

数据是 92.15 MB,有 373,436 行和 51 列。

我对一个非分区表(诗意地命名为 matches_not_partitioned)和一个按比赛日期年份分区的表(matches_partitioned)运行了一些查询。让我们看看他们做得如何…

你可以在这里看到完整的结果

这个测试是针对相对较小的数据进行的,但是您可以看到,随着数据集越来越大,节省越来越显著。就像我说的,没脑子。

如何充分利用它们:超越数据思考

有大量的文章深入探讨了如何在 BigQuery 中对表进行分区,所以我在这里不重复这些信息。

然而,这些教程中缺少了一点:您如何确保实现所有这些节省?

如果人们不编写利用分区表的查询,那么您绝对不会从分区表中获得任何好处。

例如,如果我想获取 Serena William 的所有匹配,我会得到以下结果:

这意味着,为了真正实现分区表带来的节省,您需要(气喘吁吁地)与编写查询的人一起工作。实际上,这意味着两件事:

1.了解您的业务需求

在分区表的情况下,了解人们如何使用数据是很重要的。如果数据工程团队决定基于客户获取日期进行分区,但是没有人使用它作为过滤器,那么这一切都是徒劳的,您每次都将查询整个表。

花时间了解哪些分区会为业务增加最大价值。这可能不是你仅仅通过查看数据所期望的。

2.有办法“鼓励”高效的查询

一旦您有了有意义的分区表,您就只能祈祷人们编写的查询能够真正利用它们。在这里限制访问,将被允许查询数据的人限制在选定的、可信任的少数人,可能很有诱惑力。忍住这种冲动!

有了合适的工具,您仍然可以让用户访问数据,同时鼓励更高效的查询(无需对他们进行 SQL 培训)。

对于交互式 BI 工具,如 Count,这意味着利用用户控件和查询参数化。

在我根据划分的网球数据创建的这个交互式报告中,我在笔记本顶部添加了数据控件,鼓励最终用户查看更小的时间块。这些参数直接链接到生成的 SQL 查询,然后在数据库上运行,从而产生比我让它们自由处理数据更有效的查询。

具有链接到分区数据的内置筛选器的交互式报表。

这种防护栏方法仍然允许最终用户有足够的灵活性来获得他们需要的答案,而不会面临过高的查询成本。

您可以在此查看整个笔记本:

谁是网球山羊?

点击了解更多关于伯爵的信息。

后续步骤

要开始对表进行分区(并节省一些钱),我建议从最常用的表和查询开始。在这里,您可以找出用户在分析过程中对数据进行分区的常见方式,并相应地调整您的表分区。这可能是:

  • 根据社交媒体或网站流量分析的摄取日期进行划分
  • 按客户收购日期进行分组,用于群组分析
  • 按邮政编码分区进行区域销售分析

至关重要的是,一旦这些新的分区表就位,就要抵制限制查询访问的冲动!对您现有的 BI 基础设施进行合理的控制,鼓励人们使用这些新的分区列进行查询,确保您的工作转化为实实在在的节约。

但这仅仅是开始。BigQuery 还有其他几个特性,可以帮助您减少账单和洞察时间。当数据工程与企业紧密合作,了解如何最好地存储和操作这些表以获得企业需要的答案时,这些机会就能得到最好的实现。

有用的链接

如何将您的 Power BI 型号尺寸缩小 90%!

原文:https://towardsdatascience.com/how-to-reduce-your-power-bi-model-size-by-90-76d7c4377f2d?source=collection_archive---------0-----------------------

您有没有想过是什么让 Power BI 在性能方面如此快速和强大?学习关于数据模型优化和简化数据模型的一般规则的真实例子

https://www . pexels . com/photo/aperture-blur-downtown-focus-339379/

你有没有想过是什么让 Power BI 在性能方面如此快速和强大?如此强大,以至于它可以在一瞬间对数百万行进行复杂的计算。

在本文中,我们将深入挖掘 Power BI 的“内幕”,了解您的数据是如何被存储、压缩、查询以及最终返回到您的报告中的。一旦您完成阅读,我希望您能更好地理解后台发生的艰苦工作,并理解创建最佳数据模型以从 Power BI 引擎获得最大性能的重要性。

首先看看引擎盖下——公式引擎和存储引擎

首先,我想让你们认识一下 VertiPaq 引擎,它不仅是 Power BI,还有 SSAS 表格和 Excel Power Pivot 背后的系统“大脑和肌肉”。说实话,VertiPaq 只是表格模型中存储引擎的一部分,除了 DirectQuery,我们将在下一篇文章中讨论。

当您发送查询以获取 Power BI 报告的数据时,会发生以下情况:

  • 公式引擎(FE) 接受请求,处理它,生成查询计划,最后执行它
  • 存储引擎(SE) 从表格模型中提取数据,以满足公式引擎生成的查询中发出的请求

为了检索请求的数据,存储引擎以两种不同的方式工作: VertiPaq 将数据的快照保存在内存中。该快照可以从原始数据源中不时刷新。

相反, DirectQuery 不存储任何数据。对于每个请求,它只是将查询直接转发给数据源。

https://unsplash.com/photos/2EHRBs1gefY

表格模型中的数据通常存储为内存快照(VertiPaq)或 DirectQuery 模式。然而,也有可能实现一个混合的复合模型,它同时依赖于这两种体系结构。

公式引擎 Power BI 的“大脑”

正如我已经强调过的,Formula Engine 接受查询,并且由于它能够“理解”DAX(和 MDX,但这超出了本系列的范围),它将 DAX“翻译”成一个特定的查询计划,该计划由需要执行以返回结果的物理操作组成。

这些物理操作可以是多个表之间的连接、筛选或聚合。知道公式引擎以单线程方式工作很重要,这意味着对存储引擎的请求总是按顺序发送。

存储引擎 Power BI 的“肌肉”

一旦公式引擎生成并执行了查询,存储引擎就会出现。它物理地遍历存储在表格模型(VertiPaq)中的数据,或者直接转到不同的数据源(例如 SQL Server,如果 DirectQuery 存储模式已经就绪)。

在为表指定存储引擎时,有三个选项可供选择:

  • 导入模式 —基于 VertiPaq。表数据作为快照存储在内存中。数据可以定期刷新
  • 直接查询模式 —在查询时从数据源中检索数据。在查询执行之前、期间和之后,数据都驻留在其原始源中
  • 双模 —前两个选项的组合。表中的数据被加载到内存中,但是在查询时也可以直接从源中检索

与不支持并行性的公式引擎相反,存储引擎可以异步工作。

认识 VertiPaq 存储引擎

由于我们之前已经绘制了一幅大图,让我更详细地解释 VertiPaq 在后台做了什么来提高我们的 Power BI 报告的性能。

当我们为 Power BI 表选择导入模式时,VertiPaq 会执行以下操作:

  • 读取数据源,将数据转换为列结构,在每个列中编码和压缩数据
  • 为每一列建立字典和索引
  • 准备并建立关系
  • 计算所有计算列和计算表并压缩它们

VertiPaq 的两个主要特征是:

  1. VertiPaq 是一个柱状数据库
  2. VertiPaq 是一个内存数据库

作者图片

如上图所示,列数据库存储和压缩数据的方式不同于传统的行存储数据库。列数据库针对垂直数据扫描进行了优化,这意味着每一列都以自己的方式构造,并且在物理上与其他列分离!

不深入分析行存储与列存储数据库之间的优缺点,因为这需要一个单独的系列文章,让我只指出几个关键的性能差异。

对于列数据库,单列访问既快速又有效。一旦计算开始涉及多个列,事情就会变得更加复杂,因为中间步骤的结果需要以某种方式临时存储。

简单地说,列数据库更消耗 CPU,而行存储数据库增加了 I/O,因为扫描了许多无用数据。

到目前为止,我们描绘了一幅架构的大图,它使 Power BI 作为一个终极 BI 工具充分发挥作用。现在,我们准备更深入地研究具体的架构解决方案,并利用这些知识充分利用我们的 Power BI 报告,方法是调整我们的数据模型,从底层引擎中提取最大价值。

Power BI 中的 Inside VertiPaq 为成功而压缩!

www . pexels . com/photo/crop-man-crushing-plastic-bottle-4498091/

您可能还记得,在本文的前一部分中,我们只简单介绍了 VertiPaq,这是一个强大的存储引擎,它“负责”您的大多数 Power BI 报告的超快的性能(无论您何时使用导入模式或复合模型)。

三,二,一…系好安全带!

VertiPaq 的一个关键特征是它是一个列数据库。我们了解到,列数据库存储针对垂直扫描优化的数据,这意味着每一列都有自己的结构,并且在物理上与其他列分离。

这一事实使得 VertiPaq 能够独立地对每一列应用不同类型的压缩,根据特定列中的值选择最佳的压缩算法。

压缩是通过对列中的值进行编码来实现的。但是,在我们深入研究编码技术的详细概述之前,请记住,这种架构并不仅仅与 Power BI 相关——在背景中是一个表格模型,它也在 SSAS 表格和 Excel Power Pivot 的“引擎盖”之下。

值编码

这是最理想的值编码类型,因为它专门处理整数,因此比处理文本值需要更少的内存。

这在现实中看起来如何?假设我们有一个包含每天电话数量的列,该列中的值从 4.000 到 5.000 不等。VertiPaq 要做的是找到这个范围内的最小值(4.000)作为起点,然后计算这个值与该列中所有其他值之间的差值,将这个差值存储为一个新值。

作者图片

乍一看,每个值 3 位可能看起来不像是显著的节省,但是将它乘以数百万甚至数十亿行,您将会发现节省了大量内存。

正如我已经强调的,值编码专门应用于整数数据类型列(货币数据类型也存储为整数)。

哈希编码(字典编码)

这可能是 VertiPaq 使用最多的压缩类型。使用散列编码,VertiPaq 在一列中创建一个不同值的字典,然后用字典中的索引值替换“真实”值。

下面是一个让事情更清楚的例子:

作者图片

正如您可能注意到的,VertiPaq 在 Subjects 列中标识了不同的值,通过为这些值分配索引构建了一个字典,最后将索引值存储为指向“真实”值的指针。我假设你知道整数值比文本需要更少的内存空间,所以这就是这种数据压缩背后的逻辑。

此外,由于能够为任何数据类型构建字典,VertiPaq 实际上是独立于数据类型的!

这将我们带到另一个关键的接管:无论你的列是 text、bigint 还是 float 数据类型——从 VertiPaq 的角度来看都是一样的——它需要为这些列中的每一个创建一个字典,这意味着所有这些列都将提供相同的性能,在速度和分配的内存空间方面!当然,假设这些列之间的字典大小没有大的差异。

因此,认为列的数据类型会影响它在数据模型中的大小是无稽之谈。相反,列中不同值的数量,即所谓的 、基数 ,主要影响列内存消耗。

RLE(游程编码)

第三种算法(RLE)创建一种映射表,包含重复值的范围,避免单独存储每个单个(重复)值。

同样,看一个例子将有助于更好地理解这个概念:

作者图片

在现实生活中,VertiPaq 不存储起始值,因为它可以通过对以前的计数值求和来快速计算下一个节点的起始位置。

乍看之下,RLE 算法非常强大,它高度依赖于列内的排序。如果数据是按照你在上面的例子中看到的方式存储的,RLE 将会执行得很好。但是,如果您的数据存储桶更小且轮换更频繁,那么 RLE 就不是最佳解决方案。

关于 RLE,还有一点需要记住:实际上,VertiPaq 并不像上图所示那样存储数据。首先,它执行哈希编码并创建主题字典,然后应用 RLE 算法,因此最终的逻辑,以最简单的方式,应该是这样的:

作者图片

因此,当 VertiPaq“认为”额外压缩数据有意义时(当数据以这种方式排序时,RLE 将实现更好的压缩),RLE 发生在值或哈希编码之后。

重新编码注意事项

不管 VertiPaq 有多“聪明”,它也会基于不正确的假设做出一些糟糕的决定。在解释重新编码的工作原理之前,让我简单地重复一下特定列的数据压缩过程:

  • VertiPaq 从列中扫描行的样本
  • 如果列数据类型不是整数,它将不再查找并使用哈希编码
  • 如果该列是整数数据类型,则评估一些附加参数:如果样本中的数字线性增加,VertiPaq 假定它可能是主键,并选择值编码
  • 如果列中的数字彼此相当接*(数字范围不是很宽,就像上面每天 4.000-5.000 个电话呼叫的例子),VertiPaq 将使用值编码。相反,当值在该范围内大幅波动时(例如在 1.000 和 1.000.000 之间),值编码没有意义,VertiPaq 将应用哈希算法

但是,有时 VertiPaq 会根据样本数据决定使用哪种算法,但随后会出现一些异常值,需要从头开始对列重新编码。

让我们使用前面的电话数量示例:VertiPaq 扫描样本并选择应用值编码。然后,在处理了 1000 万行之后,它突然发现了一个 500.000 的值(这可能是一个错误,或者其他什么)。现在,VertiPaq 重新评估这个选择,它可以决定使用散列算法对列重新编码。当然,就后处理所需的时间而言,这将影响整个过程。

最后,这里是 VertiPaq 在选择使用哪种算法时考虑的参数列表(按重要性排序):

  • 列中不同值的数量(基数)
  • 列中的数据分布-与包含频繁变化的值的列相比,包含许多重复值的列可以得到更好的压缩(可以应用 RLE)
  • 表格中的行数
  • 列数据类型-仅影响字典大小

将数据模型大小减少 90% —真实的故事!

在我们为理解 VertiPaq 存储引擎背后的架构以及它使用哪种类型的压缩来优化您的 Power BI 数据模型奠定了理论基础之后,现在正是动手实践并在实际案例中应用我们的知识的时候!

起点= 777 MB

我们的数据模型非常简单,但是内存耗尽。我们有一个事实表(factChat ),其中包含有关实时支持聊天的数据,还有一个维度表(dimProduct ),它与一个事实表相关。我们的事实表大约有 900 万行,这对 Power BI 来说不算什么,但是该表是按原样导入的,没有任何额外的优化或转换。

作者图片

现在,这个 pbix 文件消耗了 777 MB!!!你不能相信吗?看一看:

作者图片

只要记住这张图!当然,我不需要告诉你这个报告需要多少时间来加载或刷新,以及我们的计算如何由于文件大小而变慢。

…更糟糕的是!

此外,不仅仅是 777 MBs 占用我们的内存,因为计算内存消耗时会考虑以下因素:

  • PBIX 文件
  • 字典(你已经在这篇文章中了解了字典)
  • 列层次结构
  • 用户定义的层次结构
  • 关系

现在,如果我打开任务管理器,转到“详细信息”选项卡并找到 msmdsrv.exe 进程,我会看到它消耗了超过 1 GB 的内存!

作者图片

哦,伙计,那真的很痛!而且我们连报道都没互动过!那么,让我们看看我们可以做些什么来优化我们的模型…

规则#1 —只导入那些您真正需要的列

第一条也是最重要的一条规则是: 在您的数据模型中只保留那些您真正需要用于报告的列!

也就是说,我真的需要 chatID 列(一个代理键)和 sourceID 列(一个来自源系统的主键)吗?这两个值都是唯一的,所以即使我需要计算聊天的总数,我也可以只使用其中一个。

作者图片

让我检查一下文件现在的样子:

作者图片

通过删除一个不必要的列,我们节省了 100 多 MB!!!让我们在不深入研究的情况下进一步检查哪些内容可以删除(我保证,我们将在后面讨论这一点)。

我们真的需要聊天的原始开始时间和 UTC 时间吗,一个存储为日期/时间/时区类型,另一个存储为日期/时间,并且都要达到第二精度??!!

让我去掉原来的开始时间列,只保留 UTC 值。

作者图片

又浪费了 100 MB 的空间!通过删除我们不需要的两列,我们将文件大小减少了 30%!

现在,这还没有考虑内存消耗的更多细节。现在让我们打开 DAX Studio ,这是我最喜欢的一款解决电力 BI 报告问题的工具。正如我已经强调过几次的,如果你打算认真使用 Power BI,这个工具是必须的——而且它是完全免费的!

DAX Studio 中的一个功能是一个 VertiPaq 分析器,这是一个非常有用的工具,由来自 sqlbi.com 的 Marco Russo 和 Alberto Ferrari 制作。当我用 DAX Studio 连接到我的 pbix 文件时,下面是与我的数据模型大小相关的数字:

作者图片

我可以在这里看到我的数据模型中最昂贵的列,并决定我是否可以丢弃它们中的一些,或者我是否需要保留它们。

乍一看,我没有几个要删除的候选列— sessionReferrerreferrer 列具有很高的基数,因此不能进行优化压缩。此外,因为这些是文本列,需要使用哈希算法进行编码,所以可以看到它们的字典非常大!如果您仔细观察,您会注意到这两列几乎占了我的表大小的 40%!

作者图片

在向我的报告用户询问他们是否需要这些列中的任何一列,或者可能只需要其中的一列后,我得到了一个确认,他们没有对这些列执行任何分析。那么,我们究竟为什么要用它们来膨胀我们的数据模型呢??!!

另一个很可能被删除的列是 LastEditDate 列。该列仅显示记录在数据仓库中最后一次编辑的日期和时间。再次询问报告用户,他们甚至不知道这个栏目的存在!

我删除了这三列,结果是:

作者图片

哦,天哪,我们通过删除一些不必要的列,将数据模型的大小减半了。

说实话,还有一些列可以从数据模型中删除,但是现在让我们把重点放在数据模型优化的其他技术上。

规则 2 —减少列基数!

您可能还记得我以前的文章,经验法则是:列的基数越高,VertiPaq 就越难优化数据压缩。特别是,如果我们不处理整数值。

让我们更深入地了解一下 VertiPaq 分析器的结果:

作者图片

如您所见,即使 chatID 列的基数比 datetmStartUTC 列高,它占用的内存也要少 8 倍!由于它是一个代理键整数值,VertiPaq 应用值编码,并且字典的大小无关紧要。另一方面,散列编码被应用于具有高基数的日期/时间数据类型的列,因此字典的大小要大得多。

有多种技术可以减少列基数,比如拆分列。这里有几个使用这种技术的例子。

对于整数列,可以使用除法和模运算将它们分成两个偶数列。在我们的例子中,应该是:

选择 chatID/1000 作为 chatID_div
,chatID % 1000 作为 chatID_mod……

这种优化技术必须在源端执行(在本例中是通过编写 T-SQL 语句)。如果我们使用计算列,没有任何好处,因为原始列必须首先存储在数据模型中。

当列中有小数值时,类似的技术可以带来显著的节省。你可以简单地拆分小数点前后的值,如本文中的所述。

因为我们没有任何十进制值,所以让我们专注于我们的问题—优化 datetmStartUTC 列。有多个有效选项可以优化该列。首先是检查您的用户是否需要比日级别更高的粒度(换句话说,您能否从数据中删除小时、分钟和秒)。

让我们看看该解决方案会带来哪些节约:

作者图片

我们注意到的第一件事是,我们的文件现在是 255 MB,是我们开始时的 1/3。VertiPaq Analyzer 的结果显示,这个列现在几乎得到了完美的优化,从占我们的数据模型的 62%到略高于 2.5%!那是 huuuuge!

作者图片

然而,似乎日级别的颗粒不够精细,我的用户需要分析小时级别的数字。好的,我们至少可以去掉分和秒,这样也会降低列的基数。

所以,我导入了每小时四舍五入的值:

SELECT chatID
                ,dateadd(hour, datediff(hour, 0, datetmStartUTC), 0) AS datetmStartUTC
                ,customerID
                ,userID
                ,ipAddressID
                ,productID
                ,countryID
                ,userStatus
                ,isUnansweredChat
                ,totalMsgsOp
                ,totalMsgsUser
                ,userTimezone
                ,waitTimeSec
                ,waitTimeoutSec
                ,chatDurationSec
                ,sourceSystem
                ,subject
                ,usaccept
                ,transferUserID
                ,languageID
                ,waitFirstClick
            FROM factChat

我的用户似乎也不需要 chatVariables 列来进行分析,所以我也从数据模型中删除了它。

最后,在禁用数据加载选项中的自动日期/时间之后,我的数据模型大小大约为 220 MB!然而,有一件事仍然困扰着我:chatID 列仍然占据了我的表的将* 1/3。这只是一个代理键,在我的数据模型中的任何关系中都没有用到它。

作者图片

因此,我在这里研究了两种不同的解决方案:第一种是简单地删除这个列,并合计聊天次数,使用 GROUP BY 子句对它们进行计数:

SELECT count(chatID) chatID
                ,dateadd(hour, datediff(hour, 0, datetmStartUTC), 0) datetmStartUTC
                ,customerID
                ,userID
                ,ipAddressID
                ,productID
                ,countryID
                ,userStatus
                ,isUnansweredChat
                ,totalMsgsOp
                ,totalMsgsUser
                ,userTimezone
                ,waitTimeSec
                ,waitTimeoutSec
                ,chatDurationSec
                ,sourceSystem
                ,subject
                ,usaccept
                ,transferUserID
                ,languageID
                ,waitFirstClick
            FROM factChat
            GROUP BY dateadd(hour, datediff(hour, 0, datetmStartUTC), 0) 
                ,customerID
                ,userID
                ,ipAddressID
                ,productID
                ,countryID
                ,userStatus
                ,isUnansweredChat
                ,totalMsgsOp
                ,totalMsgsUser
                ,userTimezone
                ,waitTimeSec
                ,waitTimeoutSec
                ,chatDurationSec
                ,sourceSystem
                ,subject
                ,usaccept
                ,transferUserID
                ,languageID
                ,waitFirstClick

该解决方案还将减少行数,因为它将聚合按定义的属性分组的聊天,但主要优势是它将大大减少 chatID 列的基数,如下图所示:

作者图片

因此,我们从“900 万或更多”基数下降到只有 13!!!而这个专栏的内存消耗现在已经不值一提了。显然,这也反映在我们的 pbix 文件大小上:

作者图片

此外,保留 chatID 列也没有任何好处,因为在我们的数据模型中没有使用它。一旦我将它从模型中移除,我们就节省了额外的 3 MB,但是保留了表的原始粒度!

最后一次,让我们检查 pbix 文件的大小:

作者图片

请回忆一下我们开始时的数字:777 MB! 因此,我设法将我的数据模型大小减少了* 90% ,应用了一些简单的技术,使 VertiPaq 存储引擎能够执行更优化的数据压缩。

这是一个真实的用例,是我去年面对的!

减少数据模型大小的一般规则

最后,下面是在尝试减小数据模型大小时应该记住的一般规则列表:

  • 在报告中只保留用户需要的那些列!我向你保证,只要坚持这一条规则,你就会节省出难以置信的空间
  • 尽可能优化列基数。这里的黄金法则是:测试,测试,测试…如果有显著的好处,例如,将一列分成两列,或者用两个整数列代替小数列,那么就去做吧!但是,也请记住,为了显示预期的结果,您的度量需要被重写以处理那些结构性的变化。因此,如果您的表不大,或者如果您必须重写数百个度量值,则可能不值得拆分列。正如我所说的,这取决于您的具体场景,您应该仔细评估哪个解决方案更有意义
  • 与列一样,只保留那些需要的行:例如,也许您不需要导入过去 10 年的数据,但只需要导入 5 年!这也将减少您的数据模型大小。在盲目地将所有东西放入你的数据模型之前,与你的用户交谈,询问他们真正需要什么
  • 尽可能聚合您的数据!这意味着——更少的行,更低的基数,所以所有美好的事情都是你的目标!如果您不需要小时、分钟或秒级别的粒度,就不要导入它们!Power BI 中的聚合(以及一般的表格模型)是一个非常重要且广泛的主题,超出了本系列的范围,但是我强烈建议您查看 Phil Seamark 的博客和他关于创造性聚合用法的系列文章
  • 尽可能避免使用计算列,因为它们没有得到最佳压缩。相反,尝试将所有计算推送到一个数据源(例如 SQL 数据库),或者使用超级查询编辑器来执行它们
  • 使用适当的数据类型(例如,如果您的数据粒度是天级别的,就没有必要使用日期/时间数据类型。日期数据类型就足够了)
  • 禁用数据加载的自动日期/时间选项(这将删除后台自动创建的大量日期表格)

结论

在您学习了 VertiPaq 存储引擎的基础知识以及它用于数据压缩的不同技术之后,我想在本文的结尾向您展示一个真实的例子,展示我们如何“帮助”VertiPaq(以及随之而来的 Power BI)获得最佳的报表性能和最佳的资源消耗。

感谢阅读,希望你喜欢这篇文章!

成为会员,阅读媒体上的每一个故事!

订阅这里获取更多有见地的数据文章!

如何使用 Python 移除多重共线性

原文:https://towardsdatascience.com/how-to-remove-multicollinearity-using-python-4da8d9d8abb2?source=collection_archive---------6-----------------------

它可能不会提高性能,但对于可解释性来说是必不可少的。

Jr Korpa 在 Unsplash 上拍摄的照片

介绍

机器学习是一种解决无法显式编码的问题的方法,例如分类问题。机器学习模型会从数据中学习一个模式,所以我们可以用它来确定数据属于哪个类。因此,我们可以以最佳性能完成分类任务。

但是有一个问题。模型是如何工作的?有几个人无法接受一个性能很好的模型,因为它无法被解读。这些人关心可解释性,因为他们想确保模型以合理的方式预测数据。

在我们能够解释 ML 模型之前,去除多重共线性是一个必要的步骤。多重共线性是一种预测变量与另一个预测变量相关的情况。虽然多重共线性不会影响模型的性能,但它会影响可解释性。如果我们不消除多重共线性,我们将永远不会知道一个变量对结果的贡献有多大。因此,我们必须消除多重共线性。

本文将向您展示如何使用 Python 消除多重共线性。没有进一步,让我们开始吧!

履行

数据源

为了进行演示,我们将使用一个名为澳大利亚雨水的数据集。它描述了不同日期和地点的天气特征。这个数据集也是一个监督学习问题,我们可以使用这些数据来预测明天是否下雨。这个数据集可以在 Kaggle 上找到,你可以在这里 访问它

作者捕捉到的。

以下是加载数据集的代码和预览:

预处理数据

加载数据后,下一步是预处理数据。在这种情况下,我们将不使用分类列,并删除至少有一个缺失值的行。下面是实现这一点的代码:

计算 VIF 值

有了清晰的数据后,让我们来计算方差通胀因子(VIF)值。什么是 VIF?

VIF 是一个确定变量是否具有多重共线性的数字。这个数字也代表了一个变量由于与其他变量的线性相关性而被夸大了多少。

VIF 值从 1 开始,没有上限。如果数字变大,这意味着变量有很大的多重共线性。

为了计算 VIF,我们将对每个变量进行线性回归,该变量将成为目标变量。完成这个过程后,我们计算 R *方。最后,我们用这个公式计算 VIF 值:

由作者创作。

在 Python 中,我们可以使用 statsmodels 库中名为 variance_inflation_factor 的函数来计算 VIF。下面是这样做的代码及其结果:

从上面可以看出,几乎所有变量的 VIF 值都在 5 以上。甚至压力变量也有超过 40 万的 VIF 值。这是一个巨大的因素!

因此,我们需要清除数据中的多重共线性。

移除多重共线性

要消除多重共线性,我们可以做两件事。我们可以创建新要素或从数据中删除它们。

最初不建议删除功能。原因是因为我们移除了该功能,所以有可能丢失信息。因此,我们将首先生成新特征。

从数据中,我们可以看到有一些特征是成对的。比如' Temp9am '带' Temp3pm ',' Pressure9am '带' Pressure3pm ',' Cloud9am '带' Cloud3pm ',等等。

根据这些特征,我们可以生成新的。新要素将包含这些对之间的差值。创建这些要素后,我们可以安全地将它们从数据中移除。

下面是这样做的代码及其结果:

现在,让我们看看我们的数据的 VIF 值是什么样的:

正如你从上面看到的,我们仍然有一个巨大的 VIF 值的变量。但是,我们仍然从生成新的特性中得到了很好的结果。

现在让我们移除 VIF 值大于 5 的要素。下面是这样做的代码及其结果:

不错!现在我们有了所有 VIF 值小于 5 的变量。有了这些变量,现在我们可以解释结果了。但首先,让我们建立我们的机器学习模型。

建立模型

在这种情况下,我们将使用支持向量机(SVM)算法来建模我们的数据。简而言之,SVM 是一个模型,它将创建一个超*面,可以最大限度地分离不同标签的数据。

因为我们的数据属于分类任务,所以我们将使用 scikit-learn 中的 SVC 对象来创建模型。下面是实现这一点的代码:

使用排列特征重要性的解释

理论上,SVM 模型是不可解释的。这是因为我们不能仅仅通过参数来解释结果。但幸运的是,我们可以用几种方法来解释这个模型。我们可以使用的方法之一是置换特征重要性。

置换特征重要性通过查看改变特征值后误差增加多少来测量特征的重要性。如果其值的改变增加了模型的误差,则该特征是重要的。

为了实现这个方法,我们可以使用 scikit-learn 库中的一个名为 permutation_importance 的函数来计算特性的重要性。根据结果,我们将创建一个箱线图来可视化特性的重要性。

下面是这样做的代码及其结果:

从上面可以看出,HumanityDiff 特性是对最终结果有巨大贡献的最重要的特性。然后,降雨特征成为第二重要的特征。之后,分别以风速、蒸发量、风速差、气压差和云差为最重要的特征。

结束语

干得好!现在,您已经了解了如何使用 Python 移除数据集中的多重共线性。我希望这篇文章能帮助你如何消除多重共线性,以及如何解释机器学习模型。

如果你对我的文章感兴趣,你可以关注我的媒体以获得更多类似的文章。还有,如果你有什么问题或者想打个招呼,你可以在 LinkedIn 上关注我。

谢谢你看我的文章!

参考

[1]【https://etav.github.io/python/vif_factor_python.html
【2】https://statisticalhorizons.com/multicollinearity
【3】https://www . analyticsvidhya . com/blog/2020/03/what-is-multicollism/

如何消除时间序列预测中的非*稳性

原文:https://towardsdatascience.com/how-to-remove-non-stationarity-in-time-series-forecasting-563c05c4bfc7?source=collection_archive---------2-----------------------

算法不能处理非*稳。他们需要静态关系。

照片由Jonathan piel Mayer上的 Unsplash。 除特别注明外,所有图片均为作者所有。

介绍

与普通的机器学习问题不同,时间序列预测需要额外的预处理步骤。

在正态假设之上,大多数 ML 算法期望输入特征和输出之间有一个静态关系

静态关系要求输入和输出具有常数参数,如*均值、中值和方差。换句话说,当输入和输出静止时,算法表现最佳。

在时间序列预测中,情况并非如此。随时间变化的分布可能具有独特的属性,如季节性和趋势性。反过来,这些又会导致序列的均值和方差波动,从而很难对它们的行为进行建模。

因此,在时间序列预测中,使分布*稳是一个严格的要求。在本文中,我们将探讨几种检测非*稳分布并将其转换为*稳数据的技术。

你可以从这里访问这个时间序列预测系列的所有文章。

https://ibexorigin.medium.com/membership

获得由强大的 AI-Alpha 信号选择和总结的最佳和最新的 ML 和 AI 论文:

https://alphasignal.ai/?referrer=Bex

为什么*稳性很重要?

如果分布不是稳定的,那么建模就变得很困难。算法通过估计基本分布的核心参数来建立输入和输出之间的关系。

当这些参数都依赖于时间时,算法将在每个时间点面对不同的值。如果时间序列足够精细(例如分钟或秒钟频率),模型甚至可能最终拥有比实际数据更多的参数。

输入和输出之间的这种可变关系将严重损害任何模型的决策功能。如果这种关系随着时间不断变化,模型最终会使用过时的关系或对预测能力没有贡献的关系。

因此,您必须在工作流程中花费一定的时间来检测非*稳性并消除其影响。

我们将在接下来的章节中看到这样的例子。

非*稳序列的例子

看看这些图,试着猜猜哪条线代表一个*稳序列:

形象由https://otexts.com/fpp2/【1】组成。免费在线书籍。

既然*稳序列有恒定方差,我们可以排除 a,c,e,f,i 。这些图显示了明显的上升或下降趋势或变化水*,如 f 所示。

同样,由于 dh 显示了季节模式,我们也可以排除它们。

但是怎么样?看起来像是季节性的。

g猞猁种群增长的曲线图。当食物变得稀缺时,它们停止繁殖,导致种群数量骤降。当食物来源补充时,它们又开始繁殖,使种群增长。

这种周期性行为与季节性不同。当季节性存在时,你确切地知道一段时间后会发生什么。相比之下,猞猁种群增长的周期性行为是不可预测的。你不能猜测食物循环的时间,这使得这个系列是固定的。

所以,唯一的固定系列是 bg

d,f,h 这样复杂的分布会让你质疑视觉识别非*稳数据是否是最佳选择。正如你所观察到的,很容易将季节性与随机周期混淆,或者将趋势与白噪声混淆。

因此,下一节将讨论检测非*稳时间序列的统计方法。

统计检测非*稳性

在统计世界里,有几个测试打着 的标签,单元根测试 。增强的 Dickey-Fuller 测试可能是最流行的一种,我们已经在我的上一篇文章中看到了如何使用它来检测随机游走。

在这里,我们将看到如何使用它来检查一个序列是否*稳。

简单地说,下面是这个测试的无效假设和可选假设:

  • ****零假设:分布是非*稳的,依赖于时间的(它有一个单位根)。
  • ****替代假设:分布是*稳的,不依赖于时间(不能用单位根来表示)。

p 值决定了测试的结果。如果它小于 0.05 或 0.01 的临界阈值,我们拒绝零假设,并得出序列是*稳的结论。否则,我们无法拒绝零,并得出序列是非*稳的结论。

完整测试可方便地作为statsmodels下的adfuller功能实现。首先,让我们在一个我们知道是*稳的分布上使用它,并熟悉它的输出:

我们看 p 值,差不多是 0。这意味着我们可以很容易地拒绝零,并认为分布是*稳的。

现在,让我们从 Kaggle 加载 TPS 七月操场数据集,并检查目标一氧化碳是否是稳定的:

令人惊讶的是,发现一氧化碳是稳定的。这可能是因为数据是在短时间内记录的,这减少了时间成分的影响。事实上,数据中的所有其他变量都是完全静止的。

现在,让我们加载一些更有可能是非*稳的财务数据:

由于发布政策,一些数据集已被匿名化。但是你可以在这里查看原始版本的 Kaggle 笔记本。注意,这种匿名不会妨碍你对内容的理解。

如你所见,该系列呈现出明显的上升趋势。让我们进行迪基-富勒测试:

我们得到完美的 p 值 1,这是 100%的非*稳时间序列数据。让我们对另一个分布进行最后的测试,我们将继续讨论处理这类数据的不同技术:

p 值接* 1。不需要解释。

变换非*稳序列使其*稳

转换最简单的非*稳数据的一种方法是差分。这个过程包括连续观察的差异。熊猫有一个diff功能来做到这一点:

上面的输出显示了一阶、二阶和三阶差分的结果。

对于简单分布,取一阶差分就足以使其*稳。让我们通过使用diff_1上的adfuller功能来检查这一点(一阶差分ts2):

当我们对原始分布ts2运行adfuller时,p 值接* 1。差分后,p 值为 0,表明我们拒绝了空值,并得出序列现在是*稳的结论。

然而,有些发行版可能不那么容易处理。考虑一下我们之前看到的这个:

在计算差值之前,我们必须考虑这种明显的非线性趋势。否则,序列仍然是非*稳的。

为了消除非线性,我们将使用对数函数np.log,然后取一阶差分:

如您所见,变换前返回完美 p 值的分布现在完全稳定。

以下是澳大利亚每月抗生素销售额的图表:

正如你所看到的,该系列显示了上升趋势和很强的季节性。我们将再次应用对数变换,这一次,采用年度差异(365 天或 12 个月)来消除季节性。

下面是每个步骤的样子:

我们可以用adfuller确认*稳性:

p 值极小,证明改造步骤已经显现效果。

一般来说,每个发行版都是不同的,为了实现稳定性,您可能最终会改变多个操作。其中大部分涉及取对数、一阶/二阶或季节差异。

摘要

这个时间序列预测系列的另一个主题已经完成!

我们已经谈了很多,尽管我们还没有谈到实际的预测部分。现在,您应该能够:

  • 像专业人士一样使用熊猫(链接)操作时间序列数据。
  • 将任何时间序列分解成核心部分,如季节性和趋势(链接)。
  • 利用自相关(链接)分析时间序列信号。
  • 确定您想要预测的目标是白噪声还是随机游走(链接)。

最后,你学会了如何从任何时间序列中去除非*稳的影响。所有这些都是必须知道的话题,也是预测的重要组成部分。下一个帖子是关于时序特征工程不要错过

您可能也会感兴趣…

参考

[1]: Hyndman,R.J .,& Athanasopoulos,G. (2018) 预测:原理与实践,第二版,OTexts:澳大利亚墨尔本。OTexts.com/fpp2. 2021 年 7 月 15 日接入

如何重命名 Pandas 中的列—快速指南

原文:https://towardsdatascience.com/how-to-rename-columns-in-pandas-a-quick-guide-a934aa977bd5?source=collection_archive---------8-----------------------

关于在 pandas 数据框架中重命名列的多种选项的简短指南

照片由朱利奥·加布里埃里Unsplash 拍摄

确保 dataframe 列的名称正确对于理解其中包含的数据是至关重要的,尤其是当我们将数据传递给其他人时。在这篇短文中,我们将介绍在一个 pandas dataframe 中重命名列的多种方法。

但是首先,熊猫是什么?Pandas 是一个强大、快速、常用的 python 库,用于执行数据分析。熊猫的名字本身代表“Python 数据分析库”。根据维基百科,该名称来源于“面板数据”一词。它允许从多种文件格式(CSV、XLS、XLSX、Pickle 等)加载数据。)并存储在类似表格的结构中。这些表格(数据框)可以使用 pandas 中的各种功能进行操作、分析和可视化

库导入和数据创建

第一步包括导入 pandas 库并创建一些虚拟数据,我们可以用它们来说明列重命名的过程。

import pandas as pd

我们将创建一些虚拟数据来说明各种技术。我们可以通过调用.DataFrame()来做到这一点,这里我们将创建三列,分别命名为 A、B 和 c。

df = pd.DataFrame({'A':[1,2,3,4,5], 
                   'B':[101,102,103,104,105],
                  'C':[42,42,42,42,42]})

开始使用 pd 创建数据帧。数据帧()

加载数据时重命名列

创建数据帧的另一种方法是从现有文件(如 csv 或 xlsx 文件)中加载数据。当我们加载数据时,我们可以使用 names 参数来更改列的名称。当我们这样做时,我们需要确保使用header=0删除现有的标题行。

df = pd.read_csv('data.csv', 
                     names=['ColA', 'ColB', 'ColC'],
                     header=0)

在加载 csv 文件的过程中,重命名列后的 Pandas dataframe。

使用.rename()重命名所有列

我们要看的第一个方法是[.rename()](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.rename.html?highlight=rename#pandas.DataFrame.rename)函数。在这里,我们可以向关键字参数columns传递一个字典。字典允许我们提供旧列名和我们想要的新列名之间的映射。

我们还将把inplace参数设置为 True,这样我们就可以直接对数据帧 df 进行修改,而不是复制它。

df.rename(columns= {'A':'Z', 'B':'Y', 'C':'X' }, inplace=True)

另一种方法是指定轴,但是,与使用 columns 参数相比,这种方法可读性较差,并且可能不清楚该参数的作用。

df.rename({'A':'Z', 'B':'Y', 'C':'X' }, inplace=True, axis=1)

当我们调用 df 时,我们现在看到我们的列已经分别从 A、B 和 C 重命名为 Z、Y 和 X。

使用 df.rename()重命名列后,显示 dataframe。

使用.rename()重命名特定列

如果我们想要重命名特定的列,我们可以再次使用重命名功能。我们可以使用df.columns并通过在方括号中提供列索引位置来选择列,而不是为字符串映射提供一个字符串。然后,我们将它映射到一个新的列名字符串。

df.rename(columns={df.columns[0]:'New Name'}, inplace=True)

使用 df.rename()后,Pandas dataframe 带有重命名的列。

我们还可以指定现有列名和新列名之间的映射。

df.rename(columns= {'X':'XX' }, inplace=True)

使用 df.rename()后,Pandas dataframe 带有一个重命名的列。

使用Set_axis()重命名列

下一个方法是[set_axis()](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.set_axis.html),用于设置数据帧的轴(列:轴=1 或行:轴=0)。

我们可以使用这个方法来重命名列,首先定义我们想要替换列的名称列表,并设置axis=1axis='columns'。请注意,这里名称的数量需要等于列的总数。

df.set_axis(['Column A', 'Column B', 'Column C'], 
            axis='columns', 
            inplace=True)

在使用。set_axis()

使用。columns()来分配新的名称列表

我们可以通过分配一个新的列表来直接重命名列,该列表包含我们想要重命名的列的名称。这是使用数据帧的[df.columns](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.columns.html?highlight=columns#pandas.DataFrame.columns)属性实现的。

该方法要求新的名称列表的长度与数据帧中的列数相同。因此,如果我们只想重命名一两列,这可能不是最佳方法。

df.columns = ['1', '2', '3']

使用列表替换 df.columns 后的 Dataframe

使用 columns.str.replace()

我们要看的最后一种方法是使用str.replace(),它可以用来替换特定的字符或整个列名。

在本例中,我们将用字母 z 替换第 1 列。

df.columns = df.columns.str.replace('1', 'Z')

使用 df.columns 和 str.replace 重命名列后的 Dataframe。

摘要

熊猫数据帧中的列有多种重命名方法,包括 pd.read_csv。set_axisdf.renamedf.columns 。这说明了在 pandas python 库中可用的巨大灵活性,并且使得确保数据帧中的列被适当地标记变得容易。

感谢阅读!

如果您觉得这篇文章很有用,请随意查看我的其他文章,这些文章探讨了 Python 和测井数据的各个方面。你也可以在GitHub找到我在这篇文章和其他文章中使用的代码。

如果你想联系我,你可以在 LinkedIn 或我的网站上找到我。

有兴趣了解更多关于 python、岩石物理学或测井数据岩石物理学的知识吗?在媒体YouTube 上关注我。

如何重命名 Pandas 中的列

原文:https://towardsdatascience.com/how-to-rename-columns-in-pandas-d35d13262c4f?source=collection_archive---------23-----------------------

重命名熊猫数据框架中的列

照片由夏羽·亚伊奇Unsplash 上拍摄

介绍

重命名 dataframe 列是一种常见的做法,尤其是当我们希望与其他人和团队分享一些见解时。这意味着我们可能希望使列名更有意义,以便读者更容易将它们与特定的上下文联系起来。

在这篇短文中,我们将看看在重命名熊猫数据帧的列时有哪些选择。具体来说,我们将了解如何重命名列:

  • 使用rename()方法
  • 通过更新DataFrame.columns属性
  • 并且使用set_axis()的方法

首先,让我们创建一个示例数据框架,它将在本指南中引用,以展示所需的 pandas 功能。

import pandas as pddf = pd.DataFrame({
    'colA':[1, 2, 3], 
    'colB': ['a', 'b', 'c'],
})print(df)
#    colA colB
# 0     1    a
# 1     2    b
# 2     3    c

使用。重命名()

[**pandas.DataFrame.rename()**](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.rename.html) 可用于改变列名或索引名

改变坐标轴标签。

函数/字典值必须是唯一的(一对一)。未包含在dict / Series中的标签将保持原样。

为了使用rename()方法重命名列,我们需要提供一个映射(即字典),其中键是旧的列名,值是新的列名。此外,我们必须指定axis=1来表示我们希望重命名列而不是索引:

**df = df.rename({'colA': 'A', 'colB': 'B'}, axis=1)**print(df)
#    A  B
# 0  1  a
# 1  2  b
# 2  3  c

更新 df.columns 属性

pandas 数据帧带有[pandas.DataFrames.columns](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.columns.html)属性,该属性是包含数据帧的列标签的Index c

我们可以通过重新分配该特定属性来重命名 DataFrame 列,如下所示:

**df.columns = ['column_A', 'column_B']**print(df)
#    column_A column_B
# 0         1        a
# 1         2        b
# 2         3        c

使用 set_axis()

[pandas.DataFrame.set_axis()](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.set_axis.html)方法可用于为列或索引轴分配所需的索引。为了重命名列名,请确保提供如下所示的axis=1:

**df = df.set_axis(['AA', 'BB'], axis=1, inplace=False)**print(df)
#    AA BB
# 0   1  a
# 1   2  b
# 2   3  c

请注意,在前面讨论的所有示例中,您甚至可以使用axis='columns'代替axis=1来表示操作应该在列级别有效。例如,

df = df.rename({'colA': 'A', 'colB': 'B'}, axis='columns')
df = df.set_axis(['AA', 'BB'], axis='columns')

最后的想法

在今天的简短指南中,我们讨论了如何以几种不同的方式重命名熊猫数据帧的列。

您可能还有兴趣了解如何更改熊猫数据框架特定列的数据类型。

此外,下面的文章讨论了如何根据具体情况进行适当的行选择。

如何使用 PyTorch3D 渲染 3D 网格并将其转换为 2D 图像

原文:https://towardsdatascience.com/how-to-render-3d-files-using-pytorch3d-ef9de72483f8?source=collection_archive---------5-----------------------

实践教程

使用 Python 代码渲染 3D 的实践指南。使用 PyTorch3D API 的 obj 文件(多边形网格)

图 1:如何渲染 3D 文件。自己塑造的形象;来源: Behance

3D 理解在从自动驾驶汽车和自主机器人到虚拟现实和增强现实的众多应用中发挥着关键作用。在过去的一年里, PyTorch3D 已经成为一个越来越受欢迎的开源框架,用于使用 Python 进行 3D 深度学习。令人感激的是,PyTorch3D 库背后的人们已经完成了实现几个常见的 3D 操作符、损失函数、可区分渲染 API** 的跑腿工作,使得 PyTorch3D 更容易访问,并且更容易开始使用【1】。PyTorch3D 的一些关键组件包括:**

  • 数据结构用于存储和操作三角形网格
  • 三角形网格上的高效操作
  • 可区分网格渲染 API

渲染是计算机图形管道中的重要组成部分,它将 3D 表示转换为 2D 图像,无论是网格( **.obj** )还是点云( **.ply** )。

在这篇文章中,我们将建立如何从不同角度渲染 3D **.obj** 文件以创建 2D 图像的背景知识。我们还将使用 Python 中的 PyTorch3D 构建一个基本的 3D 渲染管道,组件如下所示。

图 2: PyTorch3D 渲染管道。来源:用 PyTorch3D 进行 3D 深度学习

这篇文章假设只有 3D 文件表示的基本知识,所以希望每个人都可以访问:)然而,如果你想阅读更多关于 3D 重建的内容,那么请查看这个精彩的最新资源列表【2】或斯坦福 cs 231 a【3】和 cs 468【4】课程的课程笔记。

在本文结束时,您将知道如何:

  • 使用 .obj .mtl 文件加载一个 3D 网格
  • 创建渲染器
  • 渲染网格
  • 可选:使用批处理属性从不同的角度高效渲染网格

只想要代码?在这个 GitHub 资源库【5】中可以找到全部代码。

准备好了吗?开始吧!🎉

步骤# 1:导入库并初始化参数

我们从导入先决条件库开始,比如torchnumpy,以及来自pytorch3d库的各种实用函数和结构。

图 3:导入库和实用程序模块。代码片段托管在 GitHub 上,使用 Carbon 创建。

最后,第 43 行从utils.py导入类参数,它从配置文件加载重要的超参数。通常,将所有参数写在一个文件中并从这个特定的文件中加载它们是一个很好的做法。这允许您跟踪正在测试的超参数,并检查哪些超参数导致了最佳性能。在我们的例子中,超参数存储在params_demo.json中:

图 4:看着 params_demo.json

如果有些超参数没有意义,不要担心;我将在本教程的后面解释它们!

通过以下方式加载超参数:

params = Params(“params_demo.json”)
# Access batch size parameter
print(params.elevation)

一旦你的params对象被初始化,你也可以使用params.update("your_other_params.json")方法用另一个.json文件更新它。

好了,现在我们导入了库并声明了参数,我们可以加载网格了。🎉

步骤 2:加载三维网格

有几种方法来表示 3D 数据,如点云、网格、体素【6】在本教程中,我们将关注 3D 网格,尽管 PyTorch3D 中的相同过程也适用于点云【7】

关于 3D 纹理网格的信息通常存储在以下文件中:

  • .obj文件,存储顶点和面
  • .mtl文件,存储材料属性
  • .jpg.png纹理图像

在本教程中,我们将使用一个 3D 胶囊对象,它存储在data/capsule文件夹中。示例文件是从这里托管的公共存储库中获得的【8】。为了可视化我们正在处理的网格,我们可以使用 Blender:

图 5:在搅拌机中观察胶囊网格。自己创作的截图。

PyTorch3D 包含了几个加载.obj文件的函数,比如load_obj或者load_objs_as_meshes。我们将使用第一个,并使用以下语法加载.obj文件:

verts, faces, aux = load_obj(filename)

这里,verts是顶点的(V,3)-张量,faces.verts_idx是每个面角的索引的(F,3)-张量,aux存储关于网格的辅助信息,例如 uv 坐标、材质颜色或纹理。然后,我们将这些vertsfaces.verts_idxaux结构传递给网格构造器,该构造器创建一个名为capsule_mesh的对象:

图 6:加载网格。代码片段托管在 GitHub 上。

最后,第 33 行检查胶囊网格中的面数和顶点数。这将返回:

We have 5252 vertices and 10200 faces.

这就是我们通过检查.obj文件结构所期望的。

如果你想了解更多,网格对象的官方文档可以在这里找到。

步骤 3:创建一个渲染器

这可能是最重要的一步。现在我们成功地读取了胶囊网格,我们需要使用MeshRenderer类创建一个渲染器。查看MeshRenderer文档【10】,我们看到它由两部分组成:

  • 光栅化器
  • 着色器

所以,让我们把这个任务分成两个步骤,最后,我们把它们放在一起。

步骤 3a:创建一个光栅化器

光栅化是指采用多边形或三角形描述的图像表示(。obj 文件)并将其转换为以像素描述的光栅图像(。png 或者。jpg 文件)。

我们的光栅化器是通过使用一个叫做MeshRasterizer的类创建的,这个类也有几个子组件,比如camerasraster_settings参数。基本上,cameras负责将 3D 坐标从世界空间转换到屏幕空间。为了初始化相机,我们需要 3 个重要的参数。它们是: 1)距离,2)方位角,3)仰角。如果这听起来很多,不要担心;我将一步一步地介绍它们。

距离是指相机与物体之间的距离。

仰角是指物体到相机的矢量与水*面 y=0(*面 xz)的夹角。仰角基本上告诉我们从多高的地方看物体。

方位角指从物体到摄像机的矢量投影到水*面 y = 0。方位角是投影向量与参考*面(水*面)上(0,0,1)处的参考向量之间的角度。方位角的取值范围为 0 到 360 度。它基本上告诉我们从哪一侧(例如,左侧尺寸、右侧、前视图、后视图等。)我们在看对象。在这里查看更多信息【11】【12】

在我们的params.json文件(图 2)中,我们声明距离是 3,仰角是 0,方位角是 90,所以如果我们渲染这个网格,我们应该直接从 3 个单位的距离看它。

关于光栅设置,最重要的参数是生成的 2D 图像的大小。尺寸越小,图像的像素化程度越高。

图 7:创建光栅化器。

步骤# 3b:创建一个着色器

PyTorch3D 提供了多种类型的着色器,包括SoftPhongShaderHardPhongShader。这里我们将使用一个预定义的SoftPhongShader,并传入相机和设备来初始化默认参数。

最后但同样重要的是,我们将光栅化器和着色器结合在一起:

图 8:创建渲染器。

步骤 4:渲染网格

这是一个非常简单的步骤,因为我们只需要在网格对象上调用renderer方法。让我们渲染胶囊网格并绘制结果:

图 9:渲染网格。

图 10:渲染后的胶囊网格,看起来非常类似于图 5 中的结果。

渲染结果看起来与图 5 中的 Blender 可视化非常相似,这是一个好现象!😃

可选:步骤# 5:使用批处理属性

如果你想从多个视点渲染网格,使用批处理属性可能 潜在地 有用。在我们深入研究代码之前,有必要了解一下当前的批处理实现是如何工作的。当前的实现依赖于单个参数,即批处理大小该批量然后将仰角和方位角空间分成 n 个相等的增量。所以,如果你的批量是 4,那么你的仰角和方位角空间是torch.linspace(0, 360, 4)也就是tensor([0, 120, 240, 360])在每一批中,索引沿着仰角和方位角列表移动,并且一旦所有元素用尽就停止。结果,我们只得到 4 张渲染图:a)两个 elev 都有。和方位角= 0,b)与两个 elev。和方位角= 120 °, c)。方位角= 240 °, d)两个仰角。方位角= 360°。

这类似于 Python map()函数,其中传递两个可迭代的参数——您也不会从这两个参数的所有成对组合中获得结果。因此,如果你希望得到仰角和方位角的所有成对组合,那么列表理解是一种方法。

好吧,好吧,好吧,回到批处理属性...我们将批处理大小设置为 4,这表示我们想要渲染网格的视点的数量。我们使用这个批量来扩展我们的网格,仰角矢量和方位角矢量。在图像被渲染后,结果张量具有形状[4, 256, 256, 4]

图 11:使用批处理渲染从多个视点渲染网格。

图 12:从多个视点得到的渲染图像。

恭喜你!🎉你现在已经了解了如何从单个和多个视点渲染 3D 网格的细节。

以下是我们所经历的:

  • 我们已经看到 PyTorch3D 的安装
  • 我们已经从 ***.obj*** ***.mtl*** 文件 中加载了网格和纹理
  • 我们已经创建了一个渲染器来渲染网格

我已经帮助您探索了 PyTorch3D 的一些基本属性,但是请不要就此止步。这只是一个开始,这一旅程将带你去哪里取决于你自己!

在你走之前

喜欢教程并有什么意见或建议?我错过了什么吗?我很想听听你的想法:)给我发消息或者在 GitHub 上关注我!

参考

[1]https://pytorch3d.org/

[2]https://github.com/timzhang642/3D-Machine-Learning

[3]https://web.stanford.edu/class/cs231a/syllabus.html

[4]https://graphics . Stanford . edu/courses/cs 468-17-spring/schedule . html

https://github.com/adelekuzmiakova/pytorch3d-render

[6]https://towards data science . com/how-to-re presentation-3d-data-66 a0f 6376 AFB

[7]https://github . com/Facebook research/pytorch 3d/blob/master/docs/tutorials/render _ colored _ points . ipynb

http://paulbourke.net/dataformats/obj/minobj.html

[9]https://github . com/Facebook research/pytorch 3d/blob/master/pytorch 3d/structures/meshes . py

【10】https://medium.com/r?URL = https % 3A % 2F % 2f github . com % 2f Facebook research % 2f pytorch 3d % 2f blob % 2f master % 2f pytorch 3d % 2f renderer % 2f mesh % 2f renderer . py

[11]https://PVP MC . Sandia . gov/modeling-steps/1-weather-design-inputs/sun-position/

[12]https://www . celestis . com/resources/FAQ/what-the-azimuth-and-elevation-of-a-satellite/

如何替换 Spark 数据帧中的空值

原文:https://towardsdatascience.com/how-to-replace-null-values-in-spark-dataframes-ab183945b57d?source=collection_archive---------6-----------------------

讨论如何使用 fillna()和 fill()替换 PySpark 中的空值

Kelly SikkemaUnsplash 上拍摄的照片

介绍

替换 PySpark 数据帧中的空值是最常见的操作之一。这可以通过使用DataFrame.fillna()DataFrameNaFunctions.fill()方法来实现。在今天的文章中,我们将讨论这两个函数之间的主要区别。

为什么我们需要替换空值

在处理 Spark 数据帧时,我们通常对它们执行的许多操作可能会在某些记录中返回空值。从那时起,如果观察到 null/空值,一些其他操作可能会导致错误,因此我们必须以某种方式替换这些值,以便继续处理数据帧。

此外,当报告表格时(例如,当将它们输出到csv文件中时),避免包含空值是很常见的。例如,如果为创建计数而执行的操作返回空值,那么用0替换这些值会更好。

在开始讨论如何在 PySpark 中替换空值以及探索fill()fillNa()之间的区别之前,让我们创建一个示例数据帧,作为整篇文章的参考。

from pyspark.sql import SparkSession spark_session = SparkSession.builder \
    .master('local[1]') \
    .appName('Example') \
    .getOrCreate() df = spark_session.createDataFrame(
    [
       (1, 'UK', 'London', None),
       (2, 'US', 'New York', 8000000),
       (3, 'US', 'Washington DC', None),
       (4, 'UK', 'Manchester', 550000),
    ],
    ['id', 'country', 'city', 'population']
)df.show()+---+---------+--------------+-----------+
| id|  country|         city | population|
+---+---------+--------------+-----------+
|  1|       UK|        London|       null|
|  2|       US|      New York|    8000000|
|  3|       US| Washington DC|       null|
|  4|       UK|    Manchester|     550000|
+---+---------+--------------+-----------+

菲尔娜

[pyspark.sql.DataFrame.fillna()](https://spark.apache.org/docs/latest/api/python/reference/api/pyspark.sql.DataFrame.fillna.html#pyspark.sql.DataFrame.fillna)函数在 Spark 版本1.3.1中引入,用于将空值替换为另一个指定值。它接受两个参数,即valuesubset

  • value对应于您想要替换空值的所需值。如果value是一个dict对象,那么它应该是一个映射,其中键对应于列名,值对应于替换值,替换值必须是intfloatboolstr
  • subset对应于替换空值时要考虑的列名列表。如果value参数是一个dict,那么该参数将被忽略。

现在,如果我们想要替换一个数据帧中的所有空值,我们可以简单地只提供value参数: `df.na.fill(value=0).show()

Replace Replace 0 for null on only population column

df.na.fill(value=0,subset=["population"]).show()`

df.fillna(value=0).show()+---+---------+--------------+-----------+
| id|  country|         city | population|
+---+---------+--------------+-----------+
|  1|       UK|        London|          0|
|  2|       US|      New York|    8000000|
|  3|       US| Washington DC|          0|
|  4|       UK|    Manchester|     550000|
+---+---------+--------------+-----------+

上述操作将用0的值替换整数列中的所有空值。

我们甚至可以使用subset参数显式指定列名:

df.fillna(value=0, subset=['population']).show()+---+---------+--------------+-----------+
| id|  country|         city | population|
+---+---------+--------------+-----------+
|  1|       UK|        London|          0|
|  2|       US|      New York|    8000000|
|  3|       US| Washington DC|          0|
|  4|       UK|    Manchester|     550000|
+---+---------+--------------+-----------+

填充()

现在[pyspark.sql.DataFrameNaFunctions.fill()](https://spark.apache.org/docs/latest/api/python/reference/api/pyspark.sql.DataFrameNaFunctions.fill.html#pyspark.sql.DataFrameNaFunctions.fill)(在版本1.3.1中再次引入)是[pyspark.sql.DataFrame.fillna()](https://spark.apache.org/docs/latest/api/python/reference/api/pyspark.sql.DataFrame.fillna.html#pyspark.sql.DataFrame.fillna)的别名,两种方法将导致完全相同的结果。

正如我们在下面看到的,na.fill()的结果与[pyspark.sql.DataFrame.fillna()](https://spark.apache.org/docs/latest/api/python/reference/api/pyspark.sql.DataFrame.fillna.html#pyspark.sql.DataFrame.fillna)应用于数据帧时观察到的结果相同。

df.na.fill(value=0).show()+---+---------+--------------+-----------+
| id|  country|         city | population|
+---+---------+--------------+-----------+
|  1|       UK|        London|          0|
|  2|       US|      New York|    8000000|
|  3|       US| Washington DC|          0|
|  4|       UK|    Manchester|     550000|
+---+---------+--------------+-----------+

上述操作将用0的值替换整数列中的所有空值。类似地,我们可以使用subset参数显式指定列名:

df.na.fill(value=0, subset=['population']).show()+---+---------+--------------+-----------+
| id|  country|         city | population|
+---+---------+--------------+-----------+
|  1|       UK|        London|          0|
|  2|       US|      New York|    8000000|
|  3|       US| Washington DC|          0|
|  4|       UK|    Manchester|     550000|
+---+---------+--------------+-----------+

最后的想法

在今天的文章中,我们讨论了为什么在 Spark 数据帧中替换空值有时很重要。此外,我们还讨论了如何使用fillna()fill()来实现这一点,它们实际上是彼此的别名。

你可以在下面找到更多 Spark 相关的文章。

[## Spark 中的 sort()与 orderBy()

towardsdatascience.com](/sort-vs-orderby-in-spark-8a912475390)

如何替换熊猫中的价值观

原文:https://towardsdatascience.com/how-to-replace-values-in-pandas-609ba7a031c9?source=collection_archive---------18-----------------------

了解如何在 Pandas 数据框架中使用值替换方法

照片由 Klára VernarcováUnsplash 上拍摄

介绍

替换值是探索性数据分析(EDA)过程中的一项常见任务。如果您经常浏览数据,那么您可能不止一次遇到过需要替换某些值、创建某种分类或者只是替换需要以其他方式显示的值的情况。

有几种方法可以做到这一点,对于 Python 来说通常就是这样。就编码而言,有些比其他的好。

由于我打算创建一个简短的帖子,我将直接进入代码片段。

我将在示例中使用的数据集是 seaborn 的taxies

# Dataframe
import seaborn as sns
df = sns.load_dataset('taxis')# Type to datetime
df.pickup = pd.to_datetime(df.pickup)# Create column pickup hour
df['pickup_hour'] = df.pickup.dt.hour

出租车数据集。图片由作者提供。

熊猫取代了

熊猫是一个很好的方法,它会让你很快变戏法。你要做的就是用一本带{current value: replacement value}的字典。

注意,我可以使用整个数据集中的值,而不是单个列上的值。如果您希望更改是永久性的,不要忘记使用参数inplace=True

# Replace "cash" and "credit card" from payment and "Manhattan" from pickup_borough
df.replace({'cash':0, 'credit card': 1, 'Manhattan': 'island'})

付款和提货区列中的替换。作者图片

也可以只替换一列。该方法还接受列表或嵌套字典,以防您想要指定必须进行更改的列,或者您可以使用 Pandas 系列的df.col.replace()

# Replace with nested dictionaries
df.replace({ 'payment': {'cash':0, 'credit card': 1}, 
             'pickup_borough': {'Manhattan': 'island'} }) # Replace with lists.
# Lists must be same lengthold_values = ['credit card', 'cash']
new_values = [1, 0]df.payment.replace(old_values, new_values)

熊猫在哪里

熊猫where()是另一种帮助你替换值的方法,但是这种方法从 1.3.0 版本开始就被否决了,它有它的局限性。这些更改是基于逻辑条件执行的。所以,我们讨论的是,如果某个条件满足,那么值保持不变,否则就变了。

参见下面的例子,我将小于 18 小时的值(又名 6pm )更改为“day”。

# Replace with where
df.pickup_hour.where(df.pickup_hour > 18, other='day')**[OUT]:**
0        20 
1       day 
2       day 
3       day 
4       day        
...  
6428    day 
6429    day 
6430     22 
6431    day 
Name: pickup_hour, Length: 6433, dtype: object

数字选择

select()函数与 Pandas replace()方法非常相似。额外的好处是这个方法允许你使用条件。

它得到一个条件列表和一个长度相同的值列表,并相应地替换它们。我相信这里的主要区别是np.select不会让你看到没有实现的变化,就像如果你不使用inplace=True的话,用 replace 方法是可能的。

# Replace with numpy selectconditions = [df.pickup_hour <= 12,
              df.pickup_hour.between(13, 18, inclusive=True),
              df.pickup_hour > 18]values = ['day', 'afternoon', 'night']# New column added
df['period'] = np.select(conditions, values)

np.select()实现了 3 个条件。图片由作者提供。

在你走之前

在这篇简短的文章中,您看到了可以使用不同的方法来替换 Pandas DataFrame 对象中的值。我知道还有其他人,但我只是认为这里解释的那些会让你已经处于良好的状态。

在:

  • df.replace({'old':'new'})对于整个数据集中的变化
  • df.col.replace({'old':'new'})针对特定列上的更改
  • df.replace({ 'col A': {'old':'new'} })针对特定列上的更改
  • df.replace([ list old vals ], [list new vals])使用列表进行更改
  • df[‘new col’] = np.select(conditions_list, values_list)因情况变化而变化。

参考

Numpy 选择文档。

熊猫代替文档。

熊猫在哪里文献。 【自 1.3.0 版起已弃用】

如果这些内容对你有用,请关注我的博客。

https://medium.com/gustavorsantos

如何重塑熊猫数据框架

原文:https://towardsdatascience.com/how-to-reshape-a-pandas-dataframe-98b42c428a8?source=collection_archive---------4-----------------------

照片由 ☀️Shine_ 拍摄Unsplash

入门指南

了解操作数据的基本方法

我记得小时候经常玩黏土和砖块模型。

我最喜欢的不是玩具本身,而是用小零件建造和塑造东西的乐趣。

让我着迷的是,只有把两块砖放在正确的位置上,它们才能组合在一起。

从那里,你可以构建任何你想要的东西。

作为一名成年的数据科学家,我发现与数据打交道有某种魔力。

你可以有很多特征供你分析。但是只有当你把它们放入正确的格式中时,你才会发现你正在寻找的模式。

andas 是一个开源库,允许数据科学家使用高性能、易于使用的数据结构和 Python 中的数据分析工具。它的核心数据结构是 DataFrame ,其中数据以表格形式表示,带有标记的行和列。

数据帧的结构。作者图片

数据可能以不同的格式组织,我们稍后会提到。并不是所有的都适合我们想要进行的分析。

幸运的是,Pandas 允许我们以多种方式改变数据帧的结构。但首先,在解释这些变化是如何发生的之前,我们需要理解形状的概念。

形状是指数据集如何组织成行和列。

为了澄清这一点,让我们使用一个包含关于 Playstation 4 视频游戏销售 的特征的数据集。

当我们检查它的形状时,我们可以看到它包含 825 行和 9 列。为什么知道数据帧的形状很重要?因为数据既可以是长格式,也可以是宽格式

让我们仔细看看这个数据框架。

我们可以观察到以下情况:

  • 每个功能都在单独的列中
  • 每一行包含同一个玩家的许多特征
  • 有缺失的值

宽格式的特征。作者图片

这些是宽格式的显著特征。这种格式适用于简单的统计,如计算*均值、输入缺失值、演示列之间的关系或对变量进行时间序列运算。

现在,我们来看看相同的数据集,但格式不同。

我们可以看到:

  • 每行代表一个特征
  • 每个游戏多行。每个特性一个。
  • 一列,即Game列,通过记录识别相同的游戏。
  • 没有缺失值。如果某个特定游戏的某个特性没有值,那么就没有对应的行。

长格式的特征。作者图片

这些是通常被视为整齐数据集标准的长格式的典型特征。这通常是首选格式,因为它可以更好地汇总数据。它具有键-值对结构,许多高级图形和分析技术都需要这种格式的数据。

作为一名数据科学家,您的分析的某些部分将需要长格式的数据,但其他部分将只处理宽数据。

要决定使用长格式还是宽格式,要考虑哪一种是分析的单位。对于长格式,你总是对一个游戏的每个特点感兴趣。对于宽格式,你对每个游戏都感兴趣。

重塑数据可以定义为将数据从宽格式转换为长格式,反之亦然。

那么,我们如何从宽格式转换到长格式,或者从长格式转换到宽格式呢?让我们来看看熊猫中可用的一些工具。

1 获得一个数据帧是很有用的,其中一列或多列是标识符变量,而其他列不与行轴关联,只留下两个非标识符列,缺省情况下名为variablevalue

让我们想象一下,我们想要在一个箱线图中绘制 PS4 游戏在不同地区的销售情况。此任务要求数据采用长格式。但是我们的数据是以一种广泛的格式存储的。那么我们如何使用融化来重塑它呢?

该函数的语法如下所示:

融化功能。作者图片

我们可以观察到,当使用.melt()时,我们需要首先传递数据帧。要设置的下一个参数是id_vars。该参数将列名用作标识符变量。在我们的例子中,我们希望用作标识符的值是列 Game

value_vars 参数接受我们想要融合的列的名称。这可以只是一列,也可以是许多列的列表。我们希望将不同地区的销售数据列作为融化列(北美欧洲日本世界其他地区)。

var_name参数接受用于列变量的名称。在我们的例子中,我们将它命名为区域。最后,参数value_name采用了用于列的名称。我们希望它被命名为销售

现在,我们可以将融化应用到我们的数据帧上,然后绘制出我们想要的图形。

作者图片

2 宽转长 : [.wide_to_long()](https://pandas.pydata.org/docs/reference/api/pandas.wide_to_long.html)是另一个可以帮助我们将数据由宽转长的函数。该功能没有熔化灵活,但更加用户友好。

这个函数有一个特点:它期望找到一组或多组格式为A-后缀 1,A-后缀 2,B-后缀 1,B-后缀 2 等的列。

所以让我们看看它的运行,这样我们可以更深入地分析它的语法。为了充分利用该功能,我们将重命名一些列。

我们可以看到,现在有些栏目的名称以销售字样开头。这些是不同地区的销售数据。

所以我们准备应用wide_to_long()功能。该函数有几个参数:

宽到长函数。作者图片

第一个参数是我们要转换的数据帧。stubnames参数用于指定 前缀 ,这是宽列名称的开始。

j参数告诉 pandas 我们希望如何命名包含后缀或宽列末尾的列。然后,i参数接受我们将用作唯一标识符的列或列列表。该列将是长数据帧的索引。

Pandas 假设前缀后面紧跟一个数字后缀。为了克服这个问题,sep参数用于指定哪个分隔符元素。

此外,suffix参数接受一个正则表达式,向 Pandas 指示列如何结束,以防后缀不是数字。如果后缀以单词结尾,我们需要使用 \w+

现在,我们可以将宽到长的函数应用于我们的数据帧,并查看结果。

请注意数据帧中所有剩余的列(出版商和流派)是如何保持不变的。

3Pivot:[.pivot()](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.pivot.html#pandas.DataFrame.pivot)方法允许我们将数据从长格式重塑为宽格式。它返回由给定的唯一索引或列值组织的整形数据帧。

为了应用这种方法,让我们使用一个长格式版本的 PS4 游戏销售数据集:

pivot 方法有三个参数:

枢纽法。作者图片

注意这是一个 DataFrame 方法,而不是 Pandas 函数。

index参数将我们想要的列的名称作为新的透视数据帧中的索引。

columns参数将我们想要的列名作为新数据帧中的每一列。

最后,values参数采用我们想要填充到新的透视数据帧中的列的名称。这是一个可选参数。如果我们指定它,它将只旋转指定的列。如果没有通过,它将旋转所有列。

因此,pivot 方法会将每个值从原始数据帧传输到新数据帧,其中它的行和列与原始数据帧的索引和列相匹配。

让我们旋转长数据框并查看输出:

请注意,这些列现在有了一个分层索引。

因为该方法在原始数据帧中找不到与组合 Call of Duty: Black Ops 3/europe 匹配的行和列,所以它将该单元格值设置为缺失值。

pivot 方法不支持数据聚合。当有任何索引/列组合具有多个值时,该方法将引发一个错误,如下例所示:

我们在这里讨论的函数和方法只是 Pandas 中可用于重塑数据的一些工具。

学习如何使用它们将在许多情况下为您提供帮助,因为对于任何数据科学项目来说,为您将要执行的每个分析准备适当的格式化和整洁的数据集都是关键的一步。

如果你想了解更多关于如何用熊猫重塑数据的知识,可以看看我的课程。

如何用 Python 揭示令人印象深刻的数据故事

原文:https://towardsdatascience.com/how-to-reveal-impressive-data-stories-with-python-848a2611bfb3?source=collection_archive---------23-----------------------

通过数据驱动的故事讲述为交互式 DataViz 创造数字化思维

伊斯坦布尔的标志之一,作者照片

我要告诉你什么?

正如我在上一篇文章中提到的,可视化是数据科学领域的一个关键点。任何数据科学项目的首要目标都是创造价值。无论在哪个领域,数据科学团队都在某种程度上触及了业务的核心,并在做出的每个决策中发挥着重要作用。如果你不能将项目的结果形象化,你就不能以正确的方式传达项目的价值。数据科学家负责项目内容中的哪些技术与哪些结构一起安装。作为一名数据科学家,在与利益相关者或其他部门的会议中,您需要引导项目的结果,而不是技术细节。来自数据的见解将有助于引导会议。本文将通过使用现成的数据集来提供关于您的可视化项目应该如何的信息。

这篇文章是为基于分析需求的可视化项目而写的,而不是为将要投入生产的项目的可视化机制而写的。我将解释基本图表类型的可视化,但不会涉及太多细节。制作复杂的数据视觉效果并不意味着创造一个好的故事。用尽可能简单的情节揭示数据中需要解释的模式将有助于项目的流畅性。

共同的方法

最基本的方法是保存 Jupyter 笔记本中的代码,这是数据爱好者的主要选择。Jupyter 采用笔记本形式并逐单元运行被认为是有利的。代码都在那里,并且很难在你不规则编写的代码中找到你将呈现的可视化。由于“时间不够”或其他原因,通常不可能清洁正在使用的 Jupyter 笔记本。如果您在会议期间向任何利益相关者或任何其他部门展示可视化的数据,这将是不友好的。使通用方法可持续的唯一解决方案是从 Jupyter 笔记本中获取要呈现的可视化效果,并通过任何呈现工具进行叙述。其实这是一个变通的程序,已经开始了你的懒惰。我只建议在紧急情况下这样做。举一个现实生活中的例子,在我之前的公司,我们的地图系统出现了一些问题。这些问题与快速做出的新业务决策有关。在后端,许可的制图服务在一周内被一个名为 OSRM 的开源路由服务所取代,并被要求提供一些关于两种服务比较的统计数据。如果您处于这种情况,并且只有几个小时的时间,在 Jupyter 中完成可视化后,您可以在任何演示工具(或同一笔记本)中演示您的结果。

使第一种方法快速的另一个重要特征是创建的可视化通常是静态的。造成这种情况的主要原因是可视化时首选熊猫、matplotlib、seaborn 等非常易用的包下的函数。

下面我举例说明了一些用我提到的通用方法绘制的图表类型。前两个图是静态的,而最后两个地图可视化是交互式传单地图。您可以从回购中名为IMM _ free _ wifi _ locs的 python 文件中访问交互的代码。在下面的可视化中,我使用了来自 IMM 数据门户的一个数据集,我将在文章中对此进行大量讨论。以下数据集包含伊斯坦布尔某些地区免费 WiFi 服务的新注册用户数量。

折线图上每月订阅数的变化

条形图上基于县的订阅计数的指示

除了以点的形式显示 IMM 的免费 wifi 位置外,它们还以六边形的形式显示,下面是它们的订阅数量。

顺便说一下,我们来谈谈'数据面板'。 Datapane 是一个应用程序编程接口,在分析数据后,可以很容易地与他人分享数据结果。这是世界上最受欢迎的分享 Python 数据科学见解的方式。通过使用这个非常易于使用的 Python 库,您可以制作出色的报告和仪表板。

整体方法

第二种方法是对代码进行项目设计。为此我用了 Jetbrains 的 PyCharm 产品。在 designed data visualization study 中,除了保持代码有组织之外,您还可以通过在本地使用不同的库(如 Streamlit)呈现项目的输出来提供更好的会议体验。这种系统方法的下一步是通过确定的日期计划将结果实时呈现给相关团队。在这篇文章中,我将通过给出第二种方式的细节来给出关于项目应该如何结束的信息。我还将展示一些我使用' plotly '库在伊斯坦堡市 (IMM)数据集上制作的基本可视化输出的例子。

区别第二种方式和第一种方式的最重要的特征之一是可视化通常是动态的和交互式的。您可以使用自动出现在代码生成的图中的工具栏来处理图或将图保存为图像。

Plotly 工具栏

IMM 开放数据门户

伊斯坦布尔政府两年前开始的积极变革提高了向该市人民提供的服务质量。在朝着正确方向采取透明步骤的框架内,人们决定,作为世界上最美丽的城市之一,伊斯坦布尔应该有一个开放的数据*台。2020 年 1 月发布的 IMM 开放数据提供了对 IMM 及其子公司提供的数据的访问。不管你的意图是什么,这些数据都是可以自由访问的。在 10 个不同的类别下有 171 个数据集。门户中数据集的数量与日俱增。同时,你可以根据你的学习领域、兴趣或任何需要提出数据集请求。对于任何对数据可视化感兴趣的人来说,IMM 开放数据门户是一个很好的资源。我建议你通过从门户中选择一些数据集来进行数据可视化工作。

拥有数据集的类别

在本文中,我使用了来自治理、人员、环境和移动性的各种数据集。您可以从下图中看到类别下有多少个数据集

来源

勒克斯

在图形之前,我想谈谈莱克丝。 Lux 是一个应用程序编程接口(API ),您可以在其中用一行代码检查任何数据的一般可视化,以及一个 Python 库,它通过自动化数据探索过程来简化数据科学的初步步骤。在开始工作之前,只需导入库。使用 Lux 创建的可视化效果,您可以创建数据集的整体视图,规划数据的预处理步骤,并通过将可视化效果保存为“html”与其他人共享。关于 Lux-API 的详细信息,可以查看 Ismael Araujo文章

下面你可以看到日 IMM wifi 新用户数据的 Lux 输出。

相关图

分类列的出现频率图

使用的数据集

  • 每日 IMM WiFi 新用户数据
  • 伊斯坦堡大坝占用率
  • 每小时公共交通数据集
  • 每小时交通密度数据集
  • 运输管理中心交通公告数据

每日 IMM WiFi 新用户数据

第一个数据集,其图表我们将对其进行检查,包括受益于伊斯坦布尔市政当局提供的 Wi-Fi 服务的国内外用户的数据。

该折线图显示了注册免费无线互联网服务的用户总数的月度分布。订阅数量在 2020 年 11 月达到最高。注册用户数已超过 1.8 万。

在柱状图中,可以看到各区的订阅数量。图表数据包含哪些地区有多少订阅。根据图表,Fatih 是注册人数最多的地区。原因之一可能是许多旅游建筑位于该地区。从下面的堆积条形图可以看出,外国用户的数量在该地区也占了最高的百分比。

伊斯坦布尔大坝占用率

下一个数据数据集,包括伊斯坦布尔大坝占用率的每日变化。除了大坝占用率,还有一个包含大坝预留水量的列。如果包括大坝崩溃,这将是一个很好的数据集。7 年后的 2007 年、2008 年、2014 年,2021 年入住率再次跌破 20%

自然与大坝占用率呈正相关的备用水量月线图如下。

我从秋、冬、夏三季中随机选择几个月,画了一个条形图。值得注意的是,除了上面我们检测到的干旱年份,七月份的*均入住率很高。

过去 15 年每月的*均条形图如下。春季的高失业率是意料之中的现象。

每小时公共交通数据集

我们的第三个数据集是公交数据,这是我在门户上最喜欢的数据集。这个数据集包含了伊斯坦布尔公共交通每小时的乘客和旅程数据。在项目内部,我一般会比较 2020 年和 2021 年 1 月和 2 月的统计数据。通过这种方式,我们将能够了解并比较疫情疫情爆发前和 2021 年新冠肺炎时期的公共交通统计数据。作为一个脚注,一些交通工具,如铁路系统,晚上不工作。

上图和下图包括每天的*均乘客人数和通票数。

在下面的柱状图中,给出了公路、铁路和水路旅客总数的比例。当然,疫情的爆发是导致 2021 年下降的有效原因。

下面的条形图包含上面的图表在一条线上的细分。2020 年 1 月,超过 1 亿的乘客中约有 60% 更喜欢使用公私合营的公交车。如果我们看看铁路细节,伊斯坦布尔最常用的 4 条线路没有变化;Aksaray-Airport、kaba tas-BAC lar、Marmaray 和 tak sim-4 . levent。2 月份早高峰期间选择这四条线路的乘客*均人数如下图所示。在海上,可以看到摩托艇比城市航线更受欢迎。然而,2021 年 1 月使用这两条线路的乘客数量相互接*。

从下面的折线图中可以看出,最明显的是,在疫情期间,绝大多数白领员工都是在家工作的。原因是 Taksim-4 的变化。莱文特线。这条线路通常由 Mecidiyekö、Gayrettepe 和 Levent 区的白领员工使用。总体而言,由于疫情,2021 年特定线路的*均乘客人数已降至 2 万以下。

i̇tü-阿亚扎阿站,Taksim-4。Levent Line,2014 年 7 月,作者照片

在这一部分下面的最后一个图表中,伊斯坦布尔最受欢迎的交通工具(开玩笑)的每小时*均乘客人数是一月份的。在疫情之前的一个月,大约有 8 万人在晚上高峰时间选择这种交通方式。你可以在下面的照片中看到人群的一部分。

Zincirlikuyu 地铁站,2020 年 1 月,作者拍摄

每小时交通密度数据集

下一个 数据集包含每小时的伊斯坦布尔位置密度和交通信息。下面的热图显示了每天和每小时的*均车辆数量。

您可以在下面的可视化图中详细查看晚间高峰时间的热图。由于疫情的条件,开车外出的人并没有大幅度减少。可以推断,人们更喜欢使用他们的私人车辆,而不是公共交通工具。只是由于夜间和周末宵禁,这些日子和时间有所减少。

在伊斯坦布尔地图上,密度地图可视化如下。

运输管理中心交通公告数据

我们的最新数据集数据集,包含运输管理中心(TMC)自 2018 年以来基于位置发布的即时公告。我为公告制作图表,而不是基于位置的可视化图。在我们的第一张图中,您可以找到显示公告总数分布的交互图。

从下面的柱状图可以查看 2019 年和 2020 年伊斯坦布尔事故公告的月度分布。2020 年事故数量增加,2020 年 10 月达到 5500 起。

下一张图以条形图的形式展示了两年半时间内 3 月、7 月和 10 月的车辆故障*均数。

文章的最后一个图在散点图上显示了在公告的开始和结束时间之间*均经过了多少分钟。

关于项目和图表

在本文中,为了确保交互性,只有项目的某些图表被选中并通过 Datapane 呈现。在这个项目中,所有图表的代码都是尽可能参数化地编写的,通过选择所需的变量和时间选项,可以很容易地复制所需的图表。你可以在我的 Github 页面找到所有代码,包括文章中的图表。

imm_dataviz/
|-- config.py
|-- dam_occupancy_rates_daily.py
|-- Dockerfile
|-- environment.yml
|-- LICENSE
|-- public_transport_hourly.py
|-- README.md
|-- requirements.txt
|-- traffic_announcements_instant.py
|-- traffic_density_hourly.py
|-- utils.py
|-- wifi_new_user_daily.py

每个 python 文件都基于以下三个基本函数。

if __name__ == "__main__":
    # main()
    putting_into_streamlit()
    # putting_into_datapane()

main 功能允许您在本地逐个查看所有图表。另一方面,put _ into _ streamlit函数使用 Streamlit 库来帮助您在一个地方收集所有图像,并使比较可视化更加容易。同时,如果你要做什么可视化工作或者项目,我强烈推荐你使用 Streamlitput _ into _ datapane函数使用了我更喜欢在文章中交互呈现图像的 data pane 库。

项目说明&下一步是什么?

  • 门户下的数据落后 45 天,每天更新。
  • Streamlit 将自动选择您的操作系统主题(亮或暗)并随操作系统改变颜色。运行代码后,从右上角选择灯光主题。
  • 我故意避免编写公共(util)函数,以便可以很容易地将每个 py 文件作为一个单独的单元。
  • 因为这个项目是尽可能模块化地编写的,所以可以通过更改配置文件中的参数来绘制不同的图表。
  • 该项目在日志记录和例外尝试机制方面比较薄弱。可以通过使用 logger 库来添加日志,异常和错误处理机制可以放在代码中。
  • 对于内容端;

—通过将气象数据与大坝占用率或每小时公共交通数据相结合,可以生成新的图表。

—可以通过组合公共交通登机牌的数量和票价来产生新的可视化。

—可以在交通公告数据中实现基于位置的可视化。

  • 不要犹豫贡献自己的力量,因为可视化项目是完全开源的。

结论

我展示了一个小规模的样本可视化引擎,在我从 IMM 开放数据门户选择的一些数据集上使用了 Plotly、Streamlit 和 Datapane 等库,该门户于 2020 年 1 月提供服务。多亏了我用 Python 创建的交互式数据可视化,我们对伊斯坦布尔的数据有了更深入的了解。我试图向您展示如何用简单而有效的代码展示数据科学领域的任何可视化项目。我告诉基于分析的可视化项目应该用什么技术呈现给利益相关者或其他部门,并且我通过 IMM DataViz 项目提供了关于使用最新库的详细信息。

我以前的文章

链接

参考资料和有用的资源

posted @ 2024-10-18 09:26  绝不原创的飞龙  阅读(182)  评论(0)    收藏  举报