TowardsDataScience-博客中文翻译-2020-六十七-

TowardsDataScience 博客中文翻译 2020(六十七)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

如何将 D3js 与 WebComponents 一起使用

原文:https://towardsdatascience.com/how-to-use-d3js-with-webcomponents-a75ae4f980de?source=collection_archive---------30-----------------------

卢克·切瑟在 Unsplash上的照片

用 D3js 和模板制作强大的图形

D3 是一个非常棒的用于数据可视化的开源库,最初由 Mike Bostock 开发。它提供了各种各样的工具,允许从零开始或使用预建的模板制作罕见的图形。D3 提供的可能性是无限的,你只需要看看他们的画廊

如果你已经使用过 D3,你会知道除了得到惊人的图形之外,你还会得到一堆脚本,用于格式化数据、迭代 SVG 元素、与服务器通信的服务、模型等等..所有这些,很可能,在一个与图表本身联系不紧密的项目中,真是一团糟!

幸运的是, Web 组件的世界比以往任何时候都更容易接*,它是创建自己的图形中枢以及封装的可重用的的完美工具。在任何地方的自定义元素上,您都可以检查 Web 组件是否与您首选的开发框架兼容。

StencilJS

Stencil 是一个 web 组件,或者更确切地说是自定义元素,一个使用了大多数已知 Web 开发框架的主要功能的编译器。

这个工具是由ionic framework开发的,旨在让兼容多种 web 开发框架的组件变得更加容易,朝着一个不可知的框架思想发展。

因此,在一个基于 Web 组件 ( 定制组件)标准的项目中使用 D3,使用 StencilJS 是一个优雅且容易实现的解决方案,如果你想要一个可重用的图形项目的话。

第一步:创建模具项目

首先使用npm安装最新版本的 StencilJS 并初始化基础项目:

*npm install @stencil/core@latest --save-exact
npm init stencil*

用箭头键选择component选项,并设置项目名称。Stencil 的 CLI 将创建一个项目文件夹,您会在其中找到包含默认生成的第一个组件my-componentsrc文件夹。组件文件夹的.tsx文件是包含其主要逻辑的文件。

生成组件的脚手架

现在,通过在控制台的根项目文件夹中键入start命令,检查一切是否正常。

*npm run start*

应该会打开一个新的浏览器窗口,显示 HelloWorld!模版,老实说有点钝。**

步骤 2:导入 D3 并创建一个图表

启动项目后,代码中的任何更新都将呈现在浏览器上。现在,我们只需要将 D3 导入到组件的代码中。首先,我们需要使用npm来安装它:

*npm install d3 --save*

通常,当我们在 Javascript 代码中使用 d3 时,我们一次导入 D3 别名上所有引用,如下所示:import * from ‘d3.js'。然而,从上一版本开始,使用打字稿,我们将不得不单独导入不同的模块。这有点乏味,但它会帮助我们使应用程序轻量级。在本例中,我们使用的是饼图,因此我们将导入以下模块:

*import { select } from 'd3-selection'
import { pie, arc } from 'd3-shape';import { scaleOrdinal } from 'd3-scale';
import { quantize } from 'd3-interpolate';
import { interpolateCool } from 'd3-scale-chromatic';*
  • select操作符允许获取我们想要使用或修改的html元素的引用。
  • pie操作员负责生成数据结构,而arc是一个工具,允许我们生成绘制图表所需的角度值和比率。
  • scaleOrdinalquantizeinterpolateCool运算符帮助我们根据图表各部分的值生成多种颜色。

这样,我们就设置好了,我们只需要知道在哪里放置 D3 代码。该组件的基本结构如下所示:

Stencil API 提供了许多装饰器和方法,允许我们与组件及其生命周期进行交互。

道具()

这个装饰器允许从组件的外部世界获取输入。在我们的例子中,这些将是图表数据。这些输入是在 html 中使用我们的组件时提供的。

事实上,如果我们查看项目文件,src/index.html包含生成的组件(在本例中只有一个),我们可以看到组件的实例化是这样完成的:

*<my-component data='myData'></my-component>*

其中myData是提供给我们的组件的数据结构,因此它可以迭代它并绘制图表。

渲染()

该函数在组件被实例化或修改后被调用,负责生成最终将由浏览器呈现的html标签。这里我们生成组件的html模式,并且我们将包含 SVG 元素,我们将使用它来生成所有的饼状图元素。

componentDidLoad()

一旦元素被完全加载,这个方法就被调用,防止我们得到组件的 html 元素的空引用。

与 D3 相关的逻辑用于重新生成数据结构和图形元素,必须在这个方法中设置,这样我们可以保证我们可以引用最终的 html。

元素()

这个装饰器允许我们访问主组件,从而迭代其子元素html。特别是,这是我们使用 D3 的select函数并获取 SVG 的参考,我们将在 SVG 中膨胀我们的图表。由于模板的封装,我们必须通过shadowRoot访问:

*select(this.element.shadowRoot.querySelectorAll(".chart")[0]);*

用于上下文隔离的组件封装

一旦我们得到了 SVG 元素的引用,我们可能会忘记所有关于模板的事情,开始专门考虑 D3。所以我们添加脚本来生成饼图(或其他),这就是了,我们将准备好我们的 webcomponent :

使用前面的代码,我们将得到如下图表:

圆形分格统计图表

你可以在 GitHub 链接中找到完整的代码示例。

最后:导出并随处重用

一旦我们准备好发布我们的图表,我们只需要建立它,并在我们可能有的任何其他项目中使用它。幸运的是,这个过程非常简单,只需检查package.json文件来设置项目名称、版本号、许可证、描述等..并发射build命令:

*npm run build*

这将在www/build文件夹中生成准备分发的 WebComponent。要在任何其他项目中使用它,您只需将其发布到您的 npm 帐户中,即可享受其所有功能:

*npm login
npm publish*

结论

模板*允许创建一个模块化的工作环境,可导出和访问**主 web 开发框架。这是一个很好的机会来统一多个项目的所有图形元素,并标准化它们的使用,代码回收,html,css 等..*

如果你在一个与 UX/UI 部门持续接触的开发团队中工作,那么模板是开发一个可持续的 设计系统 的完美地方,它可以一劳永逸地让每个人都轻松。

如何在绩效改进中使用数据分析

原文:https://towardsdatascience.com/how-to-use-data-analysis-in-performance-improvement-119cfad6414?source=collection_archive---------16-----------------------

我关于数据分析如何在实际场景中帮助性能优化的经验,以及我们能从中学到什么。

塞巴斯蒂安·赫尔曼在 Unsplash 上的照片

想象一下,你需要做一个银行交易,但是网站太慢了。页面加载时间太长,你只能看到一个蓝色的圆圈。

或者想象一下,你正在向关键利益相关者展示一些重要的东西,但是你的屏幕卡住了。你等了几秒钟,又等了几秒钟,但运气不佳。这会非常令人沮丧。

系统性能问题是一个现实。我们时常会面对它。

如此多的思想和时间投入到设计一个软件应用程序来增强用户体验。围绕布局、外观和感觉以及可用性特征的每一个细节都会被给予如此多的关注。同样重要的是设计最佳系统性能。

系统应该运行得很快。用户期望在点击一个按钮时,页面应该被加载或者事务应该被处理。体验应该是无缝的。不应该有任何等待时间。否则,你可能会失去一个客户。

尽管进行了精心的设计、开发、测试和实施,但有时软件应用程序会因为各种原因表现不佳——业务可能会发生变化,设计不是最佳的或可扩展的,存在未考虑周全的未知因素,等等。

我们如何实现性能优化?数据分析为什么以及如何帮助提高性能?我们能有一个框架来预测和预防性能问题吗?

我遇到过几个这样的场景,在这篇文章中,我将分享对这些问题的一些看法。

如何实现系统性能优化?—从发现问题开始。

当出现系统性能问题时,每个人都会知道存在性能问题,但大多数时候,他们不知道确切的问题。

服务台会收到一些用户投诉,沮丧的最终用户会直接发来电子邮件,严重的情况下还可能会上报给高级管理层。

在这样一个阶段,一个普遍的趋势是想出一个快速解决方案来尽快解决问题。虽然这是当时的需要,有时可能会奏效很多次,但那不会奏效。

这需要找出真正的问题所在,而这很难。业务部门可能对问题有不同的看法,IT 开发人员和后端管理员可能有不同的看法,管理层可能有完全不同的看法。

性能专家、数据库管理员、应用程序开发人员和功能顾问、业务用户—大多数时候都需要协作才能找到问题的根源。

像下面这样的问题会得到一些启发。

  • 性能问题到底是什么?它影响哪个业务场景?
  • 有业绩基准吗?预期的性能是什么,现在是什么?偏差是什么?
  • 是所有最终用户都发现了该问题,还是特定的业务用户发现了该问题?如果应用程序是全球性的,该问题是特定于任何地理区域还是适用于任何地方?
  • 系统性能是否在一天或一周的特定时间降级?有什么模式吗?
  • 用户如何访问软件应用程序?通过办公室互联网?通过 VPN?还是家庭网络?可能有几种变化。
  • 它会影响哪些顶级场景?有影响的场景重要吗?有时候,没有关联。
  • 该问题是否可重现?

可能会有很多这样的问题。有了正确的问题集,你就能洞察如何找到真正的问题。

数据分析有什么帮助?

一旦我们从用户、IT 开发人员、支持人员和管理人员那里收集了信息,我们就会比以前更好地了解问题。然而,在大多数情况下,我们并不真正知道确切的问题。

是因为软件设计不好还是编码不好?系统资源是否过低?交易量的大幅增长是否导致了该问题?企业是否通过遵循不应该做的情景和行为导致了问题?仍然会有许多这样的问题,我们仍然需要找到答案。

这是由多种原因造成的。我见过没有人有一个完整的图片的情况。每个利益相关者都从他们的有利角度来看待问题,这可能是也可能不是正确的观点。但我们确实意识到了问题的严重性,并打算继续前进。

这就是数据分析大有帮助的地方。数据不会说谎。如果订单处理缓慢,数据会显示—对于特定的订单,一天中的什么时间、什么时间等等,您可以深入查看并找到大量关于问题何时开始、发生了什么变化等等的信息。

我将用一个例子来说明这一点。

我曾在一个为业务运营实施了 Oracle 电子商务套件 ERP 和 Oracle 移动现场服务(MFS)应用程序的环境中工作过。

Oracle EBS 数据库将拥有企业所需的所有数据。现场工作人员会定期将他们的服务请求信息同步到他们的笔记本电脑上,以便为他们的客户提供服务。这个同步过程将在 Oracle MFS 和 Oracle EBS 之间后台运行。

这些数据需要是实时的,最大滞后时间为 5-10 分钟,不能超过这个时间。同步过程需要非常好地执行,否则现场工作人员将无法获得必要的数据来为客户服务。

在这种情况下,该系统表现不佳。现场工作人员多次抱怨同步过程缓慢。他们很沮丧。

大多数用户在全球范围内报告了这个问题。他们说,有时他们不得不等几分钟,有时甚至几个小时。这不仅影响了他们的工作,甚至影响了他们的个人生活。

每个人都有自己的想法和解决问题的方法。甚至像查询调优、增加基础设施资源(如 CPU、内存等)这样的短期修复。没有一件事长久有效。

我们需要的是后退一步,理解到底是什么问题,并永远解决它。这就是数据分析发挥作用的地方。

作为数据分析结果的模型。在那之前,没有数据模型来显示性能问题。在集成场景中达到这一点有点棘手,但是下面这个简单的视图帮助了所有的利益相关者,如下所示。

样本性能数据分析汇总

正如您在上面看到的,对于数据同步,业务的可接受限制是不到 2 分钟,即使对于较大的数据集,也不会超过 10 分钟,但实际上,73%的数据同步花费的时间超过 10 分钟。需要进行大规模的改进。

在那之前,没有人知道这个数据。每个人都有自己的看法!

业务用户认为问题比这更糟糕,而 IT 开发人员认为情况比这更好,真正的问题在两者之间。

虽然这看起来可能是一个简单的结果,但在实际场景中,很难得出一个简单的视图。保持事情简单是困难的。连这种简单的观点都没有人有过!

下一步,我们在与利益相关方的讨论中明确提出了目标— 90%的数据同步在不到 2 分钟内完成,6%在 2 到 5 分钟内完成,4%在 5 到 10 分钟内完成。

令人惊讶的是,这样的数据分析甚至在纯粹的技术问题上帮助了各种利益相关者。我在 IT 开发人员级别、业务用户社区级别,甚至在程序委员会会议上都看到了这一点。

我们是否应该继续向其他全球地区推广?这可能需要多长时间来修复?我们能否在商定的 SLA 内为客户提供服务?数据分析和趋势可以回答很多问题。

一旦建立了这种关系,就可以用通俗易懂的语言分享和交流现状和目标,这样即使是非技术人员也可以很容易理解。

一旦确定了问题,就成功了一半。

非常重要的是,要清楚地识别、陈述和沟通问题,将所有利益相关者聚集在一起,避免含糊不清。这就产生了朝着目标努力的积极性。

在这种情况下,有许多解决方案可以实现,这超出了本文的范围,但是简单地说,架构师、开发人员、业务分析人员和用户都参与了这项工作。

确定执行时间超过 15 分钟的消耗时间最多的前 10 个 SQL 查询,通过重写它们、通过索引优化执行或者改变执行计划和整体性能调优来调优它们。

另一种方法是分批处理。将整体执行从串行处理拆分为并行处理,创建线程。提高每个线程的执行时间。另一个解决方案是减少由于数据量造成的网络延迟。

这些解决方案的组合有助于解决问题并提高这方面的性能。上述数据分析也有助于验证优化后的结果是否令人满意。

性能分析的预测模型

我在生产环境中遇到过各种性能问题。有时,一个 SQL 查询表现不佳会影响整个系统。发生这种情况是因为一次夜间收集统计数据批处理程序运行改变了查询的执行计划。

在另一个例子中,订单发货过程严重滞后,影响了仓库的员工。尽管采取了措施,我们还是经常面临这种情况。

性能专家可以通过应用更好的执行计划、SQL 概要文件等,快速识别并修复这种情况。

我发现有用的是有一个用于性能监控和预先预防潜在问题的仪表板。

这很棘手,但是在这个方向上的努力对构建性能最好的应用程序大有帮助。该系统可以具有基于过去数据和趋势的智能和预测能力,以预测性能问题。

比方说,该系统可以预测比平常高得多的流入数据量,我们可以建立智能来警告下游的潜在性能问题,并可能修复它们。

构建数据分析框架和仪表板非常重要,这样我们就可以定期进行分析,根据需要提醒管理员、架构师和企业。模拟数据量增长,制定归档和清除策略,选项非常多。

最终想法

绩效改进的整个过程没有固定的模式。成功解决一种问题的方法可能不适合另一种问题,尽管它可能看起来像一个类似的问题。

正如系统性能问题是一个设计和技术问题一样,解决方案需要更多的人类参与以及对期望和情绪的管理。我们需要在实际的环境中与真实的人一起工作。

这个练*一部分是软件工程,一部分需要广泛的技能,这些技能是艺术、交流、人文以及技术的结合。

数据分析不仅有助于确定问题的根源,而且有必要让所有利益相关者达成共识,管理预期并交付结果。因此,当我们着手改进性能时,我们必须给予这一点适当的时间和关注。

(如果你发现上面的文章有用,你可能会发现下面的也很有用 如何解决复杂问题的方法)

如何使用数据扩充将图像数据集扩大 10 倍

原文:https://towardsdatascience.com/how-to-use-data-augmentation-to-10x-your-image-datasets-dab42858be55?source=collection_archive---------34-----------------------

图像数据扩充:基本数据操作、GANs 和元学*

众所周知,机器学*模型需要数据来训练。没有训练数据,再复杂的算法本质上也没用。那么当你没有足够的数据时,你会怎么做呢?

多年来,研究人员开发了各种巧妙的解决方案。数据扩充是这些解决方案之一。我们没有试图寻找和标记更多的数据点,而是根据现有的数据构建新的数据点

等等?我们能做到吗?我们当然可以。尽管这并不总是容易的,也不一定能产生最好的结果,但它仍然是一个可行的选择。

使用数据扩充方法扩展数据集不仅有助于应对有限数据的挑战。它还可以减少过度拟合并提高我们模型的泛化能力,因为它增加了我们训练集的多样性。

所以让我们切入正题:我们如何执行数据增强?

我认为下面的图片说明了一切。在本文中,我们将关注图像增强,因为它是当前最活跃的研究领域,但这些技术中的大多数可以应用于所有类型的数据。

来源:https://link.springer.com/article/10.1186/s40537-019-0197-0

基本图像操作

要做的第一件简单的事情是对图像执行几何变换。你可能会认为机器学*可以很容易地区分两个相同的不同旋转的图像,但它不能。

来源:相册:快速灵活的图像增强

图像翻转、裁剪、旋转和平移是一些显而易见的第一步。我们还可以使用对比度、锐化、白平衡、色彩抖动、随机色彩处理和许多其他技术(称为光度变换)来改变图像的色彩空间。如果你曾经使用过 Instagram 滤镜或 Snapseed,那么你就会明白我在说什么。你可以随心所欲地发挥创造力。

此外,你可以将图像混合在一起,随机擦除图像的片段,当然,也可以以各种方式将以上所有内容结合起来。

使用机器学*的数据扩充

除了基本的图像处理,越来越多的工程师开始使用机器和深度学*技术来增加他们的数据。可以这么想:我们可以用机器学*模型产生更多的数据来训练更多的机器学*模型。一些最有前途的作品如下:

特征空间增强和自动编码器

在上面的例子中,我们在输入空间上变换图像。我们还可以在特征空间中应用变换。

通过神经网络,我们可以非常有效地将高维输入(如图像)映射到低维表示(称为特征或潜在空间)中。可以把它想象成把一个三维张量编码成一个 1D 向量,而不会丢失太多信息。在几个维度上进行图像编码使得执行增强更加容易。

许多有趣的论文提出了不同的方法,例如将 k 个最*的邻居连接在一起,添加噪声,插值等等。

自动编码器已经证明是提取特征空间表示的最佳选择。自动编码器是一种特殊类型的神经网络,它试图重建输入。它们由两个网络组成,一个编码器和一个解码器。编码器接收输入,并将其编码为低维向量(特征空间)。解码器获取该向量,并尝试重建原始输入。

通过这样做,中间的潜在向量包含了关于数据集的所有信息,可以提取出来做各种事情,包括数据扩充。

基于 GAN 的数据增强

生成建模是目前最令人兴奋的技术之一,因为它可以生成全新的图像。生成模型可以在数据中生成新的模式,因为它们学*数据的分布,而不是它们之间的边界(这在大多数机器学*模型中很常见)。

在那个方向,【生成对抗网络(GAN) 已经成为业界和研究的标准。GANs 由两个网络组成,即发生器和鉴别器。生成器的工作是产生除了噪声以外没有任何输入的假数据。第二个模型,鉴别器,接收真实图像和伪图像(由生成器产生)作为输入,并学*识别图像是伪图像还是真实图像。

随着这些网络相互竞争,同时训练它们(在一个称为对抗训练的过程中),魔法开始了:

生成器在图像生成方面变得越来越好,因为它的最终目标是欺骗鉴别器。反过来,鉴别器在辨别真假图像方面变得越来越好,因为它的目标是不被愚弄。结果是来自发生器的难以置信的真实的假数据。

GANs 制作了一些我们见过的最真实的图像和视频。还记得深度假货吗?那都是甘斯的工作。那么,为什么不把它们用于数据增强,而不是在《闪灵》中用金凯瑞取代杰克·尼克尔森呢?

元学*

最后但同样重要的是,我们有元学*。元学*是一个相对较新的领域,在这个领域中,我们使用神经网络来优化其他神经网络,方法是调整它们的超参数、改进它们的布局等等。在数据扩充方面,事情变得有点复杂。

简单来说,我们使用分类网络来调整增强网络,以生成更好的图像。

看看下面的图像:通过向增强网络(很可能是 GAN)输入随机图像,它将生成增强图像。增强图像和原始图像都被传递到第二个网络,该网络对它们进行比较,并告诉我们增强图像有多好。重复这个过程后,增强网络在生成新图像方面变得越来越好。

来源:使用深度学*的图像分类中数据增强的有效性

当然,这种方法不是唯一可用的方法,但它是该领域不同研究论文的一个很好的起点。

结论

数据扩充绝非易事。已经有不少有趣的作品(这里是其中的一个集合,但是仍然有很大的改进空间。例如,我们仍然可以提高 GANs 样本的质量,找到使用元学*的新方法,也许还可以建立不同增强技术的分类法。

当然,我们仍然可以发现在其他形式的数据中使用这些技术的新方法,比如文本、表格数据、图表数据等等。为什么不扩大范围呢?强化学*怎么样?还是搜索算法?舞台是你的。

最初发布于lionbridge . ai—一家为许多世界上最大的公司和成功的初创公司提供数据注释和收集服务的提供商

如何使用。来自 UCI 的数据文件

原文:https://towardsdatascience.com/how-to-use-data-files-from-uci-68b740b4719d?source=collection_archive---------11-----------------------

不要被恐惧吓倒。数据后缀,这比你想象的要简单!

梅勒妮·德雷维克在 Unsplash 上的照片

你将学*如何使用来自 UCI 的的数据集。数据文件类型在这篇短文中。

哪里可以找到数据?

Kaggle.com是寻找用于数据科学项目的数据的绝佳选择。该网站充满了有趣的数据集、其他科学家的笔记本和教程。我在 Kaggle 上遇到的所有数据集都已经。csv 文件,这个和熊猫一起工作的时候很方便。

你可能会想知道(至少我是这样想的)Kaggle 是不是唯一可以找到数据的地方。

提示:其实不是!

你还会在 UCI 机器学*知识库上找到令人惊叹的数据集。一个有趣数据集的例子是 乳腺癌威斯康星(原始)数据集

我最*想使用这个精确的数据集来练*我的分类技能。然而,我很快遇到了一些麻烦(至少我是这么认为的)。我下载的数据包含在一个中。数据文件…

显示数据集的名称和文件扩展名的 Windows 资源管理器屏幕截图。

你是如何处理这件事的?
我当然不知道。

因为我只和合作过。csv 文件(我是一个相对较新的数据科学家)我所知道的是如何使用 pandas read_csv() 函数将我的数据集导入到数据框架中。

下载数据首先点击数据文件夹,这将带你进入第二页(下图的下半部分),在这里你点击你想要下载的文件。

如何从 UCI 下载数据

。数据文件可用 Microsoft Excel记事本打开。 我试着做了后者:

记事本打开的数据文件

可以看到所有的数据点都是用逗号分隔的!

很自然地,我尝试在 Google Colab 中实现数据。我很好奇它是否会起作用。

如您所见,使用 read_csv() 将数据读入数据帧没有任何问题。

这真的说明了我觉得熊猫有多厉害!

我认为还缺少一件小事。列名。所以让我们加上这些。

截图来自 UCI 乳腺癌-威斯康辛州-原文

在 UCI 的一个数据集的页面上向下滚动一点,你会找到的属性信息。这为相应数据集中的特征提供了名称。现在,我们可以将它们添加到我们的数据框架中。

使用将列名添加到数据框架中。DataFrame 上的 columns 属性。
看一看:

带有列名的数据框架的屏幕截图

如果您想亲自尝试,以下是来自 Google Colab 的所有代码(您必须从 UCI 下载数据并上传到 Colab 文档):

import pandas as pd

dataset = pd.read_csv('breast-cancer-wisconsin.data')

dataset.columns = ['Id', 'Clump_thickness', 'Uniformity_cell_size', 'Uniformity_cell_shape', 'Marginal_adhesion', 'Single_e_cell_size', 'Bare_nuclei', 'Bland_chromatin', 'Normal_nucleoli', 'Mitoses', 'Class']

dataset.head()

你知道吗?
这个。数据文件类型实际上是文本文件。它被一个名为 analysis studio、的数据挖掘软件所使用,然而该程序已经不再被开发(来源:Fileinfo,访问时间:2020 年 8 月 15 日)

我希望这篇短文对你有用。我很高兴我现在知道我可以使用。来自 UCI 的数据文件没有问题!

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

可以在股市中使用数据科学吗?

原文:https://towardsdatascience.com/how-to-use-data-science-on-the-stock-market-9d97a4d348d6?source=collection_archive---------7-----------------------

通过关注金融市场来解释数据科学概念

M. B. M.Unsplash 上拍摄的照片

数据科学是当今的热门学科。每个人都是数据。它能做什么以及如何提供帮助。很多时候,数据被表示为数字,这些数字可以表示许多不同的东西。这些数字可能是销售额、库存量、消费者数量,以及最后但绝对不是最不重要的——现金

这就把我们带到了金融数据,或者更具体地说是股票市场。谈到交易,股票、商品、证券等等都非常相似。我们买进,卖出,持有。这一切都是为了盈利。问题是:

当在股票市场上进行这些交易时,数据科学如何帮助我们?

在这里注册一个中级会员,可以无限制地访问和支持像我这样的内容!在你的支持下,我赚了一小部分会费。谢谢!

股票市场的数据科学概念

谈到数据科学,有许多词汇和短语或行话是很多人不知道的。我们是来解决所有这些问题的。本质上,数据科学涉及统计、数学和编程知识。如果你对了解这些概念感兴趣,我会在整篇文章中链接一些资源。

现在让我们直接进入我们都想知道的问题——使用数据科学对市场进行分析。通过分析,我们可以确定哪些股票值得投资。我们来解释一些以金融和股市为中心的数据科学概念。

算法

Franck V.Unsplash 上拍摄的照片

在数据科学和编程中,算法被广泛使用。算法是为了执行特定任务的一组规则。你可能听说过算法交易在股票市场很流行。算法交易使用交易算法,这些算法包括一些规则,例如只在股票当天下跌 5%后买入,或者在股票首次买入时价值下跌 10%后卖出

这些算法都能够在没有人工干预的情况下运行。他们经常被称为交易机器人,因为他们的交易方法基本上是机械的,他们的交易不带感情。

如果你想看一个创建交易算法的例子,那么看看下面的文章:

* [## 我用 Python 编写了一个简单的交易算法,你也可以

用 Python 实现算法交易和自动化

medium.com](https://medium.com/swlh/coding-your-way-to-wall-street-bf21a500376f)

培养

照片由梅根·霍尔姆斯Unsplash 拍摄

这不是你的典型训练。对于数据科学和机器学*,训练涉及使用选定的数据或数据的一部分来“训练”机器学*模型。整个数据集通常分为两个不同的部分,用于训练和测试。这种分割通常是 80/20 ,整个数据集的 80%用于训练。该数据被称为训练数据训练集。为了让机器学*模型准确地做出预测,它们需要从过去的数据(训练集)中学*。

如果我们试图使用机器学*模型来预测精选股票的未来价格,那么我们会给模型提供过去一年左右的股票价格来预测下个月的价格。

测试

本·穆林斯在 Unsplash 拍摄的照片

在用训练集训练了一个模型之后,我们想要知道我们的模型执行得有多好。这就是另外 20%的数据的来源。这些数据通常被称为测试数据测试集。为了验证模型的性能,我们将模型的预测与测试集进行比较。

例如,假设我们根据一年的股票价格数据训练一个模型。我们将使用 1 月到 10 月的价格作为我们的训练集,11 月和 12 月将作为我们的测试集(这是拆分年度数据的一个非常简单的例子,由于季节性等原因通常不应该使用)。在根据 1 月至 10 月的价格训练我们的模型后,我们将让它预测未来两个月的价格。这些预测将与 11 月 22 日至 12 月的实际价格进行比较。预测和真实数据之间的误差是我们在修改模型时想要减少的。

功能和目标

照片由 Unsplash 上的 NeONBRAND 拍摄

在数据科学中,数据通常以表格格式显示,如 Excel 表或数据框。这些数据点可以代表任何东西。柱子起着重要的作用。假设我们在一列中有股票价格,在另一列中有市净率、交易量和其他财务数据。

在这种情况下,股票价格将是我们的目标。其余的列将是特征。在数据科学和统计学中,目标变量被称为因变量。这些特征被称为独立变量。目标是我们想要预测的未来值,而特征是机器学*模型用来进行这些预测的。*

建模:时间序列

大卫·科恩Unsplash 拍摄的照片

数据科学大量使用的一个东西是一个叫做“ 建模的概念。建模通常使用数学方法来考虑过去的行为,以预测未来的结果。当涉及到股票市场的金融数据时,这个模型通常是一个时间序列模型但什么是时间序列?**

时间序列是一系列数据,在我们的例子中,这是股票的价格值,按时间顺序排列,可以是每月、每天、每小时甚至每分钟。大多数股票图表和数据是时间序列。因此,在对这些股票价格建模时,数据科学家通常会实施一个时间序列模型。

创建时间序列模型涉及使用机器学*或深度学*模型来获取价格数据。然后对这些数据进行分析并拟合到模型中。该模型将使我们能够预测未来一段时间内的股票价格。如果你想看到这一点,那么看看下面的文章,详细介绍了预测比特币价格的机器学*和深度学*方法:

** [## 我试图用机器学*来预测比特币的价格

利用时间序列模型预测加密货币价格

towardsdatascience.com](/predicting-prices-of-bitcoin-with-machine-learning-3e83bb4dd35f) [## 我尝试了深度学*模型来预测比特币价格

使用神经网络预测比特币价格

towardsdatascience.com](/predicting-bitcoin-prices-with-deep-learning-438bc3cf9a6f)

建模:分类

Shane Aldendorff 在 Unsplash 上拍摄的照片

机器学*和数据科学中的另一种模型被称为分类模型。使用分类的模型被给予特定的数据点,然后预测或分类这些数据点所代表的内容。

对于股市或股票,我们可以给机器学*模型不同的财务数据,如市盈率,每日交易量,总债务等,以确定股票从根本上来说是否是一个好的投资。该模型可能会根据我们给出的财务状况将该股票分类为买入、持有或卖出。

如果你想看股票分类模型的例子,可以看看下面的文章:

[## 我建立了一个机器学*模型,像沃伦·巴菲特一样交易股票(第一部分)

medium.com](https://medium.com/swlh/teaching-a-machine-to-trade-stocks-like-warren-buffett-part-i-445849b208c6) [## 我建立了一个机器学*模型,像沃伦·巴菲特一样交易股票(第二部分)

medium.com](https://medium.com/@marcosan93/teaching-a-machine-to-trade-stocks-like-warren-buffett-part-ii-5d06427b13f7)

过度拟合和欠拟合

Photo by 青 晨 on Unsplash

在评估一款车型的性能时,在寻找恰到好处的时候,误差有时会达到“太热或者“太冷”的地步。 过度拟合发生在模型预测过于复杂,以至于错过了目标变量和特征之间的关系。欠拟合发生在模型与数据拟合不够,预测过于简单的时候。

这些是数据科学家在评估他们的模型时需要注意的问题。用金融术语来说,过度拟合是指模型不能跟上股市趋势,也不能适应未来。欠拟合是指模型基本上开始预测整个股票历史的简单平均价格。换句话说,适应不足和适应过度都会导致糟糕的未来价格预测。

关闭

我们涵盖的主题是常见的关键数据科学和机器学*概念。这些主题和概念对于学*数据科学非常重要。还有更多的概念需要讨论。如果你熟悉股票市场,并且对数据科学感兴趣,我们希望这些描述和例子是有用的和可以理解的。

不是中等会员?点击这里支持他们和我!

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

如何使用数据科学原理来提高您的搜索引擎优化工作

原文:https://towardsdatascience.com/how-to-use-data-science-principles-to-improve-your-search-engine-optimisation-efforts-927712ed0b12?source=collection_archive---------18-----------------------

已经有一些关于这方面的文章了,其中很多文章提到了“是什么”和“为什么”,但是在“如何”方面有一个缺口。以下是我对这个问题的尝试。

斯蒂芬·菲利普斯-Hostreviews.co.uk 在 Unsplash 上拍摄的照片

搜索引擎优化(SEO)是一门学科,它使用围绕搜索引擎如何工作而获得的知识来构建网站和发布内容,这些内容可以在正确的时间由正确的人在搜索引擎上找到。

有些人说你并不真的需要 SEO,他们采取了一种梦想的领域‘建立它,他们就会来’的方法。到 2020 年底,SEO 行业的规模预计将达到 800 亿美元。至少有一些人喜欢两面下注。

一个经常被引用的统计数据是,谷歌的排名算法包含超过 200 个用于网页排名的因素,SEO 经常被视为其从业者和搜索引擎之间的“军备竞赛”。随着人们寻找下一个“大事件”并将自己纳入部落(白帽黑帽灰帽)。

SEO 活动及其过多的工具产生了大量的数据。作为背景,行业标准的爬行工具尖叫青蛙有 26 个不同的报告,充满了你甚至认为不重要(但却重要)的事情的网页指标。这对芒格来说是一个很大的数据,从中可以找到有趣的见解。

SEO 思维模式也很好地适应了数据科学的理想,即管理数据,使用统计和算法来获得见解和讲述故事。20 年来,SEO 从业者一直在研究所有这些数据,试图找出下一个最好的方法,并向客户展示价值。

尽管可以访问所有这些数据,在 SEO 中仍然有很多猜测,虽然一些人和机构测试不同的想法以查看什么表现良好,但很多时候它归结为团队中具有最佳跟踪记录和整体经验的人的意见。

在我的职业生涯中,我发现自己经常处于这种位置,这是我现在想要解决的问题,因为我自己已经获得了一些数据科学技能。在这篇文章中,我会给你提供一些资源,让你在 SEO 工作中采用更多的数据导向方法。

SEO 测试

SEO 中最常被问到的一个问题是“我们已经在客户的网站上实现了这些改变,但是它们有效果吗?”。这经常导致一种想法,如果网站流量上升了,那就是“有效的”,如果流量下降了,那就是“季节性的”。这不是一个严谨的方法。

更好的方法是将一些数学和统计学放在后面,用数据科学的方法进行分析。数据科学概念背后的许多数学和统计学可能很难,但幸运的是,有许多工具可以提供帮助,我想介绍一个由谷歌开发的工具,名为因果影响

因果影响包原本是一个 R 包,然而,有一个 Python 版本,如果那是你的毒药,那就是我将在这篇文章中经历的。要使用 Pipenv 在 Python 环境中安装它,请使用以下命令:

pipenv install pycausalimpact

如果你想了解更多关于 Pipenv 的知识,可以看我写的一篇文章这里,否则,Pip 也可以工作得很好:

pip install pycausalimpact

什么是因果影响?

Causal Impact 是一个库,用于在发生“干预”时对时间序列数据(如网络流量)进行预测,这种“干预”可能是宣传活动、新产品发布或已经到位的 SEO 优化。

您将两个时间序列作为数据提供给工具,一个时间序列可能是经历了干预的网站部分在一段时间内的点击量。另一个时间序列作为对照,在这个例子中,它是没有经历干预的网站的一部分在一段时间内的点击量。

当干预发生时,您还向工具提供数据,它所做的是根据数据训练一个模型,称为贝叶斯结构时间序列模型。这个模型使用对照组作为基线,试图建立一个预测,如果干预没有发生,干预组会是什么样子。

关于其背后的数学的原始论文在这里,然而,我推荐看下面这个由谷歌的一个家伙制作的视频,它更容易理解:

在 Python 中实现因果影响

在如上所述将库安装到您的环境中之后,使用 Python 的因果影响非常简单,正如在下面由保罗·夏皮罗写的笔记本中可以看到的:

Python 的因果影响

在引入包含对照组数据、干预组数据的 CSV 并定义前/后周期后,您可以通过调用以下命令来训练模型:

ci = CausalImpact(data[data.columns[1:3]], pre_period, post_period)

这将训练模型并运行预测。如果您运行该命令:

ci.plot()

您将会看到一个类似这样的图表:

训练因果影响模型后的输出

这里有三个面板,第一个面板显示了干预组和对没有干预会发生什么的预测。

第二个面板显示了逐点效应,这意味着发生的事情和模型做出的预测之间的差异。

最后一个面板显示了模型预测的干预的累积效果。

另一个需要知道的有用命令是:

print(ci.summary('report'))

这将打印出一份完整的报告,易于阅读,非常适合汇总并放入客户幻灯片中:

因果影响的报告输出

选择控制组

建立你的控制组的最好方法是使用一种叫做分层随机抽样的方法随机挑选不受干预影响的页面。

Etsy 发表了一篇关于他们如何使用因果影响进行 SEO 分割测试的文章,他们推荐使用这种方法。随机分层抽样顾名思义就是从人群中随机抽取样本。但是,如果我们抽样的东西以某种方式被分割,我们会尽量保持样本中的比例与这些部分在总体中的比例相同:

图片由 Etsy 提供

分层抽样分割网页的理想方法是使用会话作为度量。如果您将页面数据作为数据框加载到 Pandas 中,您可以使用 lambda 函数来标记每个页面:

df["label"] =``df["Sessions"].apply(lambda``x:"Less than 50"``if``x<=50``else``("Less than 100"``if``x<=100``else``("Less than 500"``if``x<=500``else``("Less than 1000"``if``x<=1000``else``("Less than 5000"``if``x<=5000``else

从那里,您可以在 sklearn 中使用 test_train_split 来构建您的控制和测试组:

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(selectedPages["URL"],selectedPages["label"], test_size=0.01, stratify=selectedPages["label"])

注意分层已经设置好了,如果你已经有了想要测试的页面列表,那么你的样本页面应该和你想要测试的页面数量相等。此外,样本中的页面越多,模型就越好。如果使用的页面太少,模型就越不精确。

值得注意的是,JC Chouinard 提供了关于如何使用类似于 Etsy 的方法在 Python 中完成所有这些工作的良好背景:

[## 使用 Python+causal impact+Tag Manager-JC choui nard 进行 SEO 分割测试

在本指南中,我将为您提供用 Python、R、…

www.jcchouinard.com](https://www.jcchouinard.com/seo-ab-test-python-causalimpact-tag-manager/)

结论

有一些不同的用例可以使用这种类型的测试。第一种是使用分割测试来测试正在进行的改进,这类似于上面 Etsy 使用的方法。

第二个是测试作为正在进行的工作的一部分在现场进行的改进。这类似于在这篇文章中概述的方法,但是使用这种方法,你需要确保你的样本量足够大,否则你的预测将会非常不准确。所以请记住这一点。

这两种方法都是进行 SEO 测试的有效方法,前者是一种正在进行的优化的 A/B 分割测试,后者是对已经实现的东西的测试。

我希望这能让你对如何将数据科学原理应用到你的 SEO 工作中有所了解。请务必阅读这些有趣的主题,并尝试想出其他方法来使用这个库来验证您的努力。如果你需要这篇文章中使用的 Python 的背景,我推荐这个课程

如何有效地使用 DBSCAN

原文:https://towardsdatascience.com/how-to-use-dbscan-effectively-ed212c02e62?source=collection_archive---------3-----------------------

有效使用最常引用的聚类算法的完整指南

DBSCAN 是一个极其强大的聚类算法。首字母缩写代表带噪声应用的基于密度的空间聚类。顾名思义,该算法使用密度来聚集空间中的点以形成簇。该算法一旦被正确实现就可以非常快。然而,在本文中,我们更愿意讨论优化 DBSCAN 的参数,以获得比算法实现本身更好的效用。(DBSCAN 的实现非常简单。更难的部分,如果有的话,将是为邻居查找结构化数据。)

在我们开始之前,确保你手头有这些包裹。

numpy
sklearn
matplotlib # for visualization
seabron # for pretty visualizations
kneed # for our computations

连续的例子

让我们首先创建一组数据,它可以复制一组适合我们分析的数据点。Python 对它的类库非常慷慨。为了生成数据,我们将使用 sci-kit learn 库的 make blobs 函数。

from sklearn.datasets import make_blobs
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as npcenters = [[1, 0.5], [2, 2], [1, -1]]
stds = [0.1, 0.4, 0.3]
X, labels_true = make_blobs(n_samples=1000, centers=centers, cluster_std=stds, random_state=0)fig = plt.figure(figsize=(10, 10))
sns.scatterplot(X[:,0], X[:,1], hue=["cluster-{}".format(x) for x in labels_true])

在这里,我创建了 3 个数据块。我们可以看到这些数据块的可视化,如图 1 所示。在这个例子中,我故意创建了 3 个不同密度的集群来增加集群的难度。

图一。原始集群的可视化

DBSCAN 及其参数

DBSCAN 有几个参数,其中有两个非常重要。第一个是 eps 参数,另一个是min _ points(min _ samples)。后者指的是将一个点视为密集区域或有效聚类所需的相邻点的数量。通常,我们将其设置为对数据集和数据中存在的维度数量有意义的值。这将决定被识别的异常值的数量。不过这个参数没有 eps 那么关键。

DBSCAN 的ε参数

DBSCAN 最重要的参数可以确定为 eps 。这是一个点选择其邻居的最远距离。因此,直觉上这将决定一个点将发现多少个邻居。虽然我们可以为 min_points/min_samples 提供一个默认值,但我们不能为 eps 提供默认值。这将取决于数据本身的分布。让我们用数据集的一些猜测值进行 DBSCAN。代码和可视化(图 2 中)如下所示。

db = DBSCAN(eps=0.5, min_samples=10).fit(X)
labels = db.labels_fig = plt.figure(figsize=(10, 10))
sns.scatterplot(X[:,0], X[:,1], hue=["cluster-{}".format(x) for x in labels])

图二。eps=0.5 时的 DBSCAN

调整 EPS 参数

从上一张图中我们可以清楚地看到,两个集群已经合并在一起。这很糟糕。这种情况会降低真实集群应用程序的召回率。我们再来试试变 eps 集群。代码和可视化效果(如图 3 所示)如下所示。

import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.cluster import DBSCANfig = plt.figure(figsize=(20, 10))
fig.subplots_adjust(hspace=.5, wspace=.2)
i = 1for x in range(10, 0, -1):
    eps = 1/(11-x)
    db = DBSCAN(eps=eps, min_samples=10).fit(X)
    core_samples_mask = np.zeros_like(db.labels_, dtype=bool)
    core_samples_mask[db.core_sample_indices_] = True
    labels = db.labels_

    print(eps)
    ax = fig.add_subplot(2, 5, i)
    ax.text(1, 4, "eps = {}".format(round(eps, 1)), fontsize=25, ha="center")
    sns.scatterplot(X[:,0], X[:,1], hue=["cluster-{}".format(x) for x in labels])

    i += 1

图三。不同 eps 值下的 DBSCAN

可以看到我们在 eps=0.1eps=0.3 之间打了一个甜蜜点。 eps 小于该值的值有太多噪声或异常值(以绿色显示)。请注意,在图像中,我通过将代码中的分母从 10 增加到 1 来减少 eps 。我们怎样才能自动做到这一点?

调整每股收益值的系统方法

由于 eps 数字与预期发现的邻居数量成正比,我们可以使用最*邻居来对 eps 达成一个公平的估计。让我们计算一下最*的邻居。

from sklearn.neighbors import NearestNeighborsnearest_neighbors = NearestNeighbors(n_neighbors=11)
neighbors = nearest_neighbors.fit(X)
distances, indices = neighbors.kneighbors(X)distances = np.sort(distances[:,10], axis=0)fig = plt.figure(figsize=(5, 5))
plt.plot(distances)
plt.xlabel("Points")
plt.ylabel("Distance")plt.savefig("Distance_curve.png", dpi=300)

第 10 个邻居的距离变化

请注意,在最*邻计算中,点本身将作为第一个最*邻出现。所以我们寻找 11 个最*的邻居。我们对到第 10 个最*邻居的距离进行排序,并绘制距离变化。我们可以看到,肘点出现在0.3 之间的某处。这正是我们所期待的,不是吗?考虑到我挑选 10 作为用于聚类的 min_samples 值,我选择第 10 个邻居。希望到目前为止有意义。**

检测肘点的膝盖定位器

Ville Satopaa 等人在 2011 年提交了论文“ 大海捞针:检测系统行为中的拐点 ”。在本文中,出于检测 肘点 (或 膝点 )的目的,我将使用他们的 python 库kneed。我们可以使用下面的代码来查找和绘制拐点。

*from kneed import KneeLocatori = np.arange(len(distances))
knee = KneeLocator(i, distances, S=1, curve='convex', direction='increasing', interp_method='polynomial')fig = plt.figure(figsize=(5, 5))knee.plot_knee()
plt.xlabel("Points")
plt.ylabel("Distance")

print(distances[knee.knee])*

拐点图

我们可以看到通过这种方法检测到的拐点在距离 0.178 处。现在我们可以用这个值作为我们的 eps 来看看我们新的集群看起来会是什么样子。

带自动检测 Eps 的 DBSCAN

我们可以看到,我们对实际的聚类有一个合理的估计。这对于研究工作来说通常已经足够了。如果不存在离群点是该场景的直观假设,则可以简单地使用计算出的最*邻居来将离群点(称为cluster--1)重新分配给检测到的聚类。

限制

这种方法有几个隐含的假设。

  1. 所有集群的密度都是相同的。
  2. 聚类大小或标准差是相同的。

当我们考虑用于膝部计算的相同邻居级别时,这些假设是隐含的。但是,在原始数据中,我们可以清楚地看到密度并不相同。这就是我们观察到一些异常值的主要原因,即使我们在创建斑点时使用固定的标准偏差来分布这些点。此外,修复这些问题超出了本文的范围。

最后的想法

我附上了一个 jupyter 笔记本,上面有本文中的例子使用的完整代码。您可以通过下面的链接访问该笔记本。

我希望你喜欢阅读我的文章,就像我喜欢写作一样。请在您的研究工作中尝试这些方法。这对我帮助很大。

感谢阅读!

干杯!😊

举例说明如何在 Python 中使用装饰器

原文:https://towardsdatascience.com/how-to-use-decorators-in-python-by-example-b398328163b?source=collection_archive---------1-----------------------

图片由王思然·哈德逊通过 Unsplash 提供

Python 中的装饰者

Python 中的装饰器是一个函数,它将另一个函数作为其参数,并返回另一个函数。装饰器非常有用,因为它们允许对现有函数进行扩展,而无需对原始函数源代码进行任何修改。

考虑下面的例子:

1.相加函数

简单的 add_together 函数将 2 个整数作为参数,并返回传递的 2 个整数值的总和。

1.1.用装饰器扩展 add _ 的功能

让我们提出下面的场景。我们希望 add_together 能够将 2 个元素元组的列表作为其参数,并返回一个整数列表,该列表表示它们的值的总和。我们可以通过使用装饰器来实现这一点。

首先,我们给装饰者一个明智的名字,暗示它的预期目的是什么。这里的 decorator,称为 decorator_list,只是一个将另一个函数作为参数的函数。这个函数在 decorator_list 的参数列表中被命名为‘fnc’。

在 decoratored 函数中,我们定义了一个名为 inner 的局部函数。inner 函数将一个 2 元素元组列表作为其参数。内部函数循环遍历这个 2 个元素元组的列表,并对每个元组应用原始函数 add_together,其中元组的索引位置 0 是 add_together 中 a 的参数,索引位置 1 是 add_together 中 b 的参数。内部函数返回这些值的汇总列表。decorator_list 函数最后返回内部函数。

现在,让我们应用这个逻辑,看看装饰函数是如何工作的。

为了应用装饰器,我们使用语法@,后面是装饰器的函数名,位于正在装饰的函数的上方。这在语法上与以下内容相同:

从语法上来说,@decorator_list 等同于将函数 add_together 传递给 decorator_list,并重新赋值给 add_together

这里,我们将函数 add_together 传递给 decorator_list 函数,该函数返回内部函数,我们将该函数赋给变量名 add_together。由于 add_together 现在指向内部函数,该函数需要一个包含 2 个元素元组的列表,因此我们可以调用 add_together,并将一个元组列表作为参数。

控制台的标准输出显示,我们现在已经扩展了原始 add_together 函数的功能,因此它现在可以接受一个元组列表。

修饰函数的完整源代码可从以下网址获得:

2.可以自己接受参数的装饰者

装饰者自己获取参数也可能是有用的。在这里稍微修改的例子中,我们将一个整数参数传递给装饰器。元组中的两个值相加后,该整数值用作指数。这里,值 2 对每个值进行平方,因此对于第一个元组,返回 16(即 1 + 3 的平方)。

为了在装饰器中使用参数,我们只需要定义一个装饰器本身。在下面的例子中,2 是传递给 meta_decorator 的参数。这个 meta_decorator 函数返回 decorator_list 函数,2 作为参数传递给 power。然后,这个 decorator_list decorator 以普通方式使用,即,它接受 add_together 函数并返回 inner,然后我们可以用元组列表调用它。

现在我们有了一个返回的元组列表,它们被加在一起并平方。对于立方或四倍,我们只需在 meta_decorator 的参数中添加 3 或 4。

当我们想要创建接受参数本身的 decorators 时,就增加了一个额外的函数层。

该示例的源代码如下所示:

3.装饰器中的默认参数

现在我们已经看到,我们可以为装饰器指定参数,也可以不为装饰器指定参数,这样就会设置一个默认值。

如果我们不向装饰器传递任何参数,就像我们对@meta_decorator 所做的那样,args 就被认为是一个函数。

由于传递了函数的内置可调用函数将返回布尔值 True,因此 power 被赋值为 2,我们可以立即直接调用将返回 inner 的 decorated_list 函数。

如果 arg 不是一个函数,而是一个整数,那么它是不可调用的(就像被注释掉的代码中会发生的那样)。然后我们转到 else 语句,该语句执行相应的块。无论我们传递哪个值,都会分配给 Power,然后我们创建 decorator_list 函数,该函数最终返回 inner。

该代码片段的源代码如下所示:

4.摘要

装饰器是一种优雅的方式来扩展我们的原始函数的功能,而不改变它们的源代码。此外,我们定义的装饰器可以接受参数,或者返回到一组预定义的默认参数。这篇文章展示了装饰者的基本知识,以及如何将它们整合到我们的功能设计中。

如何使用深度学*进行时间序列预测

原文:https://towardsdatascience.com/how-to-use-deep-learning-for-time-series-forecasting-3f8a399cf205?source=collection_archive---------6-----------------------

资料来源:研究结果——由作者计算

RNN 家族的一个应用

介绍

很长一段时间,我听说时间序列的问题只能用统计方法来逼*(AR[1],AM[2],ARMA[3],ARIMA[4])。这些技术通常由数学家使用,他们试图不断改进这些技术来约束平稳和非平稳的时间序列。

几个月前,我的一个朋友(数学家、统计学教授、非平稳时间序列专家)邀请我去验证和改进重建恒星光变曲线的技术。事实上,开普勒卫星[11]像许多其他卫星一样,无法持续测量附*恒星的光通量强度。开普勒卫星在 2009 年至 2016 年期间致力于搜索太阳系以外的行星,称为太阳系外行星或系外行星。

如你所知,我们将比我们的地球走得更远一点,深入到一次银河之旅中,机器学*将是我们的船只。如你所知,天体物理学一直是我的强烈爱好。

Github 上有笔记本:这里

RNN,LSTM,GRU,双向,CNN-x

那么我们将乘坐哪艘船来完成这项研究呢?我们将使用递归神经网络(RNN[5]),模型。我们将使用 LSTM[6],GRU[7],堆叠 LSTM,堆叠 GRU,双向[8] LSTM,双向 GRU,还有 CNN-LSTM[9]。对于那些热衷于树家族的人,你可以在这里找到杰森·布朗利写的一篇关于 XGBoost 和时间序列的文章。github 上有一个关于时间序列的很好的知识库。

对于那些不熟悉 RNN 家族的人来说,把他们看作是具有记忆效应和遗忘能力的学*方法。双向术语来自体系结构,它是关于两个 RNN,它们将在一个方向(从左到右)和另一个方向(从右到左)上“读取”数据,以便能够获得长期依赖关系的最佳表示。

数据

正如前面介绍中所说,这些数据对应于几颗恒星的通量测量。事实上,在每一个时间增量(小时),卫星都会测量来自附*恒星的通量。这种通量或强度,即光强度,随着时间的推移而变化。这有几个原因,卫星的适当运动、旋转、视角等。会有所不同。因此,测量到的光子数量会发生变化,恒星是一个熔化材料球(氢氦聚变),它有自己的运动,因此光子的发射取决于它的运动。这对应于光强度的波动。

但是,也可能有行星,系外行星,扰乱恒星,甚至在恒星和卫星的视线之间通过(凌日法[12])。这条通道遮蔽了恒星,卫星接收到的光子更少,因为它们被从它面前经过的行星阻挡了(一个具体的例子是由于月亮引起的日食)。

这组通量测量值称为光变曲线。光线曲线是什么样的?以下是一些例子:

恒星与恒星之间的通量差别很大。有些非常吵,而另一些非常稳定。尽管如此,通量还是呈现出异常。在光变曲线中可以看到洞或缺少测量。目标是看看是否有可能在没有测量的情况下预测光曲线的行为。

数据整理

为了能够使用模型中的数据,有必要进行数据简化。这里将介绍两种,移动平均线窗口法

均线:

移动平均包括取 X 个连续的点并计算它们的平均值。这种方法允许减少可变性并消除噪声。这也减少了点数,是一种缩减采样方法。

下面的函数允许我们通过给出一个用于计算点的平均值和标准偏差的数字来计算一系列点的移动平均值。

您可以看到该函数在输入中有 3 个参数。 时间通量 是时间序列的 xy滞后 是控制点数的参数,用于计算时间和通量的平均值以及通量的标准偏差。

现在,我们可以看看如何使用这个函数和转换得到的结果。

***# import the packages needed for the study***
matplotlib inline
import scipy
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import sklearn
import tensorflow as tf
***# let's see the progress bar***
from tqdm import tqdm
tqdm().pandas()

现在我们需要导入数据。文件kep_lightcurves.csv包含了 13 颗恒星的数据。每个星形有 4 列,原始通量(“…_orig”)、重定标通量是原始通量减去平均通量(“…_rscl”)、差值(“…_diff”)和残差(“…_res”)。所以,总共 52 列。

# reduce the number of points with the mean on 20 points
x, y, y_err  = moving_mean(df.index,df["001724719_rscl"], 20)

df.index 对应于时间序列的时间
df["001724719_rscl"]重新标度的恒星通量(" 001724719")
lag=20 是将计算平均值和标准差的点数

前 3 条光线曲线的结果:

前 3 颗恒星的光变曲线,移动平均值显示 25,000 到 30,000 个测量值之间的点

窗口方法:

第二种方法是窗口法,它是如何工作的?

你需要取一些点,在前面的例子中是 20,计算平均值(与前面的方法没有区别),这个点是新的时间序列的开始,它在位置 20(移动 19 个点)。但是,不是移动到接下来的 20 个点,而是将窗口移动一个点,计算前 20 个点的平均值,并通过向前移动一步来一次又一次地移动。这不是一种下采样方法,而是一种清理方法,因为效果是平滑数据点。

让我们看看它的代码:

您可以像这样轻松地使用它:

# reduce the number of points with the mean on 20 points
x, y, y_err  = mean_sliding_windows(df.index,df["001724719_rscl"], 40)

df.index对应于时间序列的时间
df[“001724719_rscl”]【001724719】
lag=40是将计算平均值和标准差的点的数量

现在,看看结果:

使用窗口方法显示 25,000 和 30,000 测量值之间的点的前 3 颗恒星的光变曲线

嗯,还不错。将滞后设置为 40 允许在小孔中“预测”或扩展新的时间序列。但是,如果你仔细观察,你会发现在红线的起点和终点有一个分歧。可以改进该函数以避免这些伪像。

在研究的其余部分,我们将使用移动平均法获得的时间序列。

将 x 轴从数值改为日期:

如果需要,您可以更改日期轴。开普勒任务开始于 2009 年 3 月 7 日,结束于 2017 年。 熊猫 有一个叫pd.data_range()的函数,这个函数允许你从一个不断递增的列表中创建日期。

df.index = pd.date_range(‘2009–03–07’, periods=len(df.index), freq=’h’)

这一行代码将创建一个新的索引,频率为几个小时。如果你打印结果(如下),你会发现一个合适的实际时间表。

$ df.index
DatetimeIndex(['2009-03-07 00:00:00', '2009-03-07 01:00:00',
               '2009-03-07 02:00:00', '2009-03-07 03:00:00',
               '2009-03-07 04:00:00', '2009-03-07 05:00:00',
               '2009-03-07 06:00:00', '2009-03-07 07:00:00',
               '2009-03-07 08:00:00', '2009-03-07 09:00:00',
               ...
               '2017-04-29 17:00:00', '2017-04-29 18:00:00',
               '2017-04-29 19:00:00', '2017-04-29 20:00:00',
               '2017-04-29 21:00:00', '2017-04-29 22:00:00',
               '2017-04-29 23:00:00', '2017-04-30 00:00:00',
               '2017-04-30 01:00:00', '2017-04-30 02:00:00'],
              dtype='datetime64[ns]', length=71427, freq='H')

您现在已经有了原始时间序列的良好时间刻度。

生成数据集

因此,现在已经创建了数据归约函数,我们可以将它们合并到另一个函数中(如下所示),该函数将考虑初始数据集和数据集中存在的恒星名称(这一部分可以在函数中完成)。

要生成新的数据框,请执行以下操作:

stars = df.columns
stars = list(set([i.split("_")[0] for i in stars]))
print(f"The number of stars available is: {len(stars)}")
> The number of stars available is: 13

我们有 4 种数据类型的 13 颗星,对应于 52 列。

df_mean, df_slide = reduced_data(df,stars)

很好,在这一点上,您有两个新的数据集,其中包含通过移动平均和窗口方法减少的数据。

方法

准备数据:

为了使用机器学*算法来预测时间序列,必须相应地准备数据。数据不能仅仅设置在(x,y)数据点。数据必须采用序列[x1,x2,x3,…,xn]和预测值 y 的形式。

下面的函数向您展示了如何设置数据集:

开始前有两件重要的事情。

1-数据需要重标度
深度学*算法在数据在[0,1]范围内预测时间序列时效果更好。简单来说,[scikit-learn](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.MinMaxScaler.html)提供了函数[MinMaxScaler](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.MinMaxScaler.html)()。您可以配置feature_range参数,但默认情况下需要(0, 1)。并清除 nan 值的数据(如果你不删除 nan 值,你的损失函数将输出 nan)。

***# normalize the dataset*** 
num = 2 ***# choose the third star in the dataset***
values = df_model[stars[num]+"_rscl_y"].values ***# extract the list of values***
scaler = MinMaxScaler(feature_range=(0, 1)) ***# make an instance of MinMaxScaler***
dataset = scaler.fit_transform(values[~np.isnan(values)].reshape(-1, 1)) ***# the data will be clean of nan values, rescaled and reshape***

2-数据需要转换成 x 列表和 y 列表 现在,我们将通过create_values()函数来为模型生成数据。但是,在此之前,我更喜欢通过以下方式保存原始数据:

df_model = df_mean.save()

****# split into train and test sets***
train_size = int(len(dataset) * 0.8)   ***# make 80% data train***
train = dataset[:train_size] ***# set the train data***
test  = dataset[train_size:] ***# set the test data*** 
***# reshape into X=t and Y=t+1*** look_back = 20
trainX, trainY = create_dataset(train, look_back)
testX, testY = create_dataset(test, look_back)
***# reshape input to be [samples, time steps, features]***
trainX = np.reshape(trainX, (trainX.shape[0], trainX.shape[1], 1))
testX = np.reshape(testX, (testX.shape[0], testX.shape[1], 1))*

看一看结果:

*trainX[0]
> array([[0.7414906],
       [0.76628096],
       [0.79901113],
       [0.62779976],
       [0.64012722],
       [0.64934765],
       [0.68549234],
       [0.64054092],
       [0.68075644],
       [0.73782449],
       [0.68319294],
       [0.64330245],
       [0.61339268],
       [0.62758265],
       [0.61779702],
       [0.69994317],
       [0.64737128],
       [0.64122564],
       [0.62016833],
       [0.47867125]]) ***# 20 values in the first value of x train data*** trainY[0]
>array([0.46174275]) ***# the corresponding y value****

指标

我们用什么标准来预测时间序列?我们可以使用平均绝对误差和均方误差。它们由函数给出:

您需要首先导入函数:

*from sklearn.metrics import mean_absolute_error, mean_squared_error*

RNNs:

你可以用几行代码轻松实现带有 Keras 的 RNN 家族。在这里,您可以使用此功能来配置您的 RNN。您需要首先从 Keras 导入不同的模型,例如:

****# import some packages***
import tensorflow as tf
from keras.layers import SimpleRNN, LSTM, GRU, Bidirectional, Conv1D, MaxPooling1D, Dropout*

现在,我们有从 Keras 进口的模型。下面的函数可以生成一个简单的模型(SimpleRNNLSTMGRU)。或者,两个模型(相同的)可以堆叠,或用于Bidirectional或两个双向模型的堆叠。还可以用MaxPooling1Ddropout加上 CNN 部分(Conv1D)。

该函数计算训练部分和测试部分的度量,并在数据帧中返回结果。看你如何用五个例子。

LSTM:

****# train the model and compute the metrics***
> x_train_predict_lstm, y_train_lstm,x_test_predict_lstm, y_test_lstm, res= **time_series_deep_learning**(train_x, train_y, test_x, test_y, model_dl=**LSTM** ,  unit=12, look_back=20)
***# plot the resuts of the prediction***
> plotting_predictions(dataset, look_back, x_train_predict_lstm,  x_test_predict_lstm)
***# save the metrics per model in the dataframe df_results***
> df_results = df_results.append(res)*

GRU:

****# train the model and compute the metrics***
> x_train_predict_lstm, y_train_lstm,x_test_predict_lstm, y_test_lstm, res= **time_series_deep_learning**(train_x, train_y, test_x, test_y, model_dl=**GRU**,  unit=12, look_back=20)*

堆栈 LSTM:

****# train the model and compute the metrics***
> x_train_predict_lstm, y_train_lstm,x_test_predict_lstm, y_test_lstm, res= **time_series_deep_learning**(train_x, train_y, test_x, test_y, model_dl=**LSTM** ,  unit=12, look_back=20, **stacked=True**)*

双向 LSTM:

****# train the model and compute the metrics***
> x_train_predict_lstm, y_train_lstm,x_test_predict_lstm, y_test_lstm, res= **time_series_deep_learning**(train_x, train_y, test_x, test_y, model_dl=**LSTM** ,  unit=12, look_back=20, **bidirection=True**)*

美国有线电视新闻网 LSTM 报道:

****# train the model and compute the metrics***
> x_train_predict_lstm, y_train_lstm,x_test_predict_lstm, y_test_lstm, res= **time_series_deep_learning**(train_x, train_y, test_x, test_y, model_dl=**LSTM** ,  unit=12, look_back=20, **cnn=True**)*

结果

考虑到数据,这个结果相当不错。我们可以看到,深度学* RNN 可以再现具有良好准确性的数据。下图显示了 LSTM 模型的预测结果。

LSTM 预言

表 1:不同 RNN 模型的结果,显示了 MAE 和 MSE 指标

 *Name    | MAE Train | MSE Train | MAE Test | MSE Test
--------------------------------------------------------------------
            GRU |   4.24    |   34.11   |   4.15   |   31.47 
           LSTM |   4.26    |   34.54   |   4.16   |   31.64 
      Stack_GRU |   4.19    |   33.89   |   4.17   |   32.01
      SimpleRNN |   4.21    |   34.07   |   4.18   |   32.41
           LSTM |   4.28    |   35.1    |   4.21   |   31.9
         Bi_GRU |   4.21    |   34.34   |   4.22   |   32.54
  Stack_Bi_LSTM |   4.45    |   36.83   |   4.24   |   32.22
        Bi_LSTM |   4.31    |   35.37   |   4.27   |   32.4
Stack_SimpleRNN |   4.4     |   35.62   |   4.27   |   33.94
      SimpleRNN |   4.44    |   35.94   |   4.31   |   34.37 
     Stack_LSTM |   4.51    |   36.78   |   4.4    |   34.28
 Stacked_Bi_GRU |   4.56    |   37.32   |   4.45   |   35.34
       CNN_LSTM |   5.01    |   45.85   |   4.55   |   36.29
        CNN_GRU |   5.05    |   46.25   |   4.66   |   37.17 
  CNN_Stack_GRU |   5.07    |   45.92   |   4.7    |   38.64*

表 1 显示了 RNN 家族的训练集和测试集的平均绝对误差(MAE)和均方误差(MSE)。GRU 在测试集上显示出最好的结果,MAE 为 4.15,MSE 为 31.47。

讨论

结果很好,重现了不同恒星的光变曲线(见笔记本)。然而,波动并没有完全再现,峰值没有相同的强度,通量略有偏移。可以通过注意机制(变形金刚[10])进行潜在的纠正。另一种方法是调整模型、层数(堆栈)、单元数(单元)、不同 RNN 算法的组合、新的损失函数或激活函数等。

结论

本文展示了将所谓的人工智能方法与时间序列相结合的可能性。记忆算法的力量(RNN、LSTM、GRU)使得精确重现事件的零星波动成为可能。在我们的例子中,恒星通量表现出相当强烈和显著的波动,这些方法已经能够捕捉到。

这项研究表明,时间序列不再保留给统计方法,如 ARIMA[4]模型。

参考

[1] 自回归模型,维基百科
【2】移动平均模型,维基百科
【3】彼得·惠特尔,1950。
时间序列分析中的假设检验。论文
【4】阿尔贝托·卢塞诺&丹尼尔·培尼亚,2008。
自回归综合移动平均(ARIMA)建模。威利在线图书馆。https://doi.org/10.1002/9780470061572.eqr276
【5】鲁梅尔哈特,戴维 E. 等著,1986 年。
通过反向传播误差学*表征性质。323(6088):533–536。自然杂志..533R
[6]hoch Reiter,Sepp&schmid Huber,于尔根,1997 年。
长短期记忆神经计算9(8):1735–1780。土井:10.1162/neco . 1997 . 9 . 8 . 1735
【7】Cho,KyungHyun 等人,2014。
门控递归神经网络对序列建模的经验评估arXiv:1412.3555
【8】m .舒斯特& K.K .帕利瓦尔,1997 年。
双向递归神经网络。IEEE 信号处理汇刊,第 45 卷,第 11 期,第 2673-2681 页。DOI:10.1109/78.650093
【9】塔拉·n·塞纳特
等人,2014。卷积、长短期记忆、全连接深度神经网络https://static . Google user content . com/media/research . Google . com/fr//pubs/archive/43455 . pdf
【10】阿希什·瓦斯瓦尼
等人,2017。你需要的只是关注。https://arxiv.org/abs/1706.03762
【11】开普勒任务,美国宇航局

如何用深度学*把鸽子从阳台上赶走

原文:https://towardsdatascience.com/how-to-use-deep-learning-to-shoo-pigeons-from-the-balcony-31a2704f2160?source=collection_archive---------38-----------------------

鸽子回避系统

基于 Keras 的迁移学*和树莓 Pi 的生产部署

免责声明:你正在阅读的第三部分是关于如何训练鸽子识别模型的。 第 1 部分 提供了架构概述, 第 2 部分 描述了技术设置。

我在鸽子回避系统实施后喝着早晨的咖啡

在这一部分,我详细介绍了训练鸽子分类模型的过程。本文由四个部分组成:

  1. 塑造数据集
  2. 模特培训
  3. 推理
  4. 观点

塑造数据集

前一部分我在阳台上搭了个树莓派,开始采集图像。与此同时,我正在用鸽子 Tinder 给图片贴标签,这是一个自制的网络应用程序,它可以帮助我将图片分类到指定的类别文件夹中:“鸽子”、“人类”和“什么都没有”。显然,我拍了很多没有鸽子的照片。这是因为传感器是由树枝的运动和光线变化触发的。在风平浪静、阳光明媚的日子,我得到的图像通常比阴天和刮风的日子要少。鸽子每天都停在我的阳台上,总共在那里呆 5-10 分钟。这导致了我的数据集中高度不平衡的类。我正在通过增加鸽子和人类的职业来解决这个问题。遗憾的是,我不能应用很多不同的增强技术,因为垂直或水平翻转鸽子没有意义,因为阳台的布局是恒定的,鸽子很少倒着落在上面。这同样适用于随机裁剪,因为鸽子经常出现在图像的边缘,因此将它们裁剪掉的风险很高。这给我留下了一些增强技术,处理模糊和清晰。我使用以下代码进行数据扩充:

数据扩充类

仅增加训练数据是至关重要的。另一个重要方面是时间因素。当我第一次训练模型时,我通过从标签照片的桶中随机(没有替换)挑选图像来生成训练和测试数据集。我很快在验证和训练数据上获得了 100%的准确性,这些数据看起来已经很可疑了,但是当我将模型投入生产时,它的表现并不好。分类看起来非常随意。然后,我决定按照时间戳分割数据,并在前十天的数据上训练模型,在接下来的三天进行验证,在最后两天进行测试。这产生了一个更健壮的模型,并且防止了如果我们随机分割数据所发生的数据泄露。在训练数据集中,我总共有 200 张鸽子图像。应用数据增强后,我把它增加到 600。我还将增强应用到人类图片以达到 600 张,并且大多数“无”类包含 600 张没有人类或鸽子的图片。在验证数据集中,每个类有 50/50/50 个图像,在测试中有 30/30/30 个图像。正如我们将在后面看到的,通过利用迁移学*的力量,每个班级只需要 200 幅图像就足以训练一个非常准确的模型。

模特培训

由于训练神经网络是一项计算量很大的任务,所以我没有在 Raspberry 上执行它。目前,我在本地培训模型,但考虑在不久的将来切换到云解决方案之一。

Keras 是我几年来深度学*的默认选择,主要是针对 LSTMs。然而,完成这个项目后,我现在认为 PyTorch 可能是迁移学*的更好选择,原因如下。最初,我想在预训练的 ResNet50 上使用迁移学*,因为它在图像分类任务上一直显示出非常好的结果。然而,Keras 在 ResNet 架构中有一个非常有线的 BatchNormalisation 层实现。在微调过程中,批量归一化图层被冻结,并使用原始 imagnet 数据集的平均值和标准偏差进行训练。然而,imagenet 的平均值和标准偏差不同于用于微调和推断的新数据集。有多种解决方法,如在微调过程中解冻批量规范化层,以及在训练和推断过程中操作 lerning_phase 标志。然而,我不能仅仅为了应用一个最先进的模型而证明这些变通方法的使用是正确的。因此,我选择了 VGG19 ,仅仅经过 30 个时期,它就为我提供了 98%的测试数据集准确率。

现在让我们看看建模部分。首先,我们需要加载数据。我使用 Keras 的 ImageDataGenerator 类来逐步加载图像。它为当前的小批量加载足够的图像到内存中。ImageDataGenerator 类的另一个好处是,它还可以自动缩放像素值,并进行图像预处理,如归一化。

配置图像数据生成器

我将训练和测试数据生成器分开保存,以便将来我可以只对训练数据执行数据扩充。注意,我们对两个数据集应用相同的预处理函数,它执行预训练 VGG19 所期望的数据预处理。

接下来,为了逐步加载数据,我们需要创建一个迭代器。这需要调用 flow_from_directory()方法并指定数据集目录,例如训练、测试或验证目录。该方法允许我们配置多个参数,如 class_mode、target_size 等。

加载并迭代数据集

我们需要为训练和验证迭代器设置每个时期的步骤参数,以便指定有多少批图像定义一个时期。它通常计算为数据集的长度除以批处理大小,但是,它可以设置为一个较小的数字,以允许更频繁的回调。

计算每个时期的步数

现在让我们定义模型架构。使用 Keras 进行迁移学*的步骤顺序是:

  1. 加载没有顶层的预训练模型。为此,将 include_top 参数设置为 False。
  2. 冻结网络,因为我们假设它在之前的训练中学*的基本概念(过滤图)对于广泛的图像分类问题保持不变。
  3. 添加新的可训练层,其中可能包括:展平层,如果您注意到模型过拟合,则删除层,以及带有要预测的类数量的密集输出层。

指定模型架构

请注意,我在这个任务中使用了相对较小的学*率。这通常适用于所有迁移学*问题。由于我们只是微调顶层,我们应该保持较低,以避免梯度下降跳跃。

我们去训练循环。为了避免模型过度拟合,我应用了早期停止,并在训练时定期保存模型检查点。

训练分类模型

在我的鸽子识别问题上运行指定的模型架构 30 个时期,在测试数据集上给了我 98%准确度的预测,这意味着我错误地分类了两幅图像。在这两张照片中,鸽子用尾巴面对镜头,站在一个非常不幸的角度。连我都认不出这团毛绒绒的东西里有一只鸽子。

分类错误的鸽子

推理

如前所述,我在本地机器上执行训练,在 Raspberry Pi 上执行推理。由于我使用深度学*进行分类模型,我需要首先安装 TensorFlow。显然,它不像以前在我的本地机器上那样微不足道。Raspberry Pi 上的原子库存在一些问题。因此,我需要经历很多步骤,这里的都有很好的描述。我将在这里复制主安装脚本,只是为了避免它丢失。但这完全归功于最初推出安装教程的 Q-engineering:

TensorFlow 安装脚本

在这之后,我们只需要安装 Keras 通常会顺利进行。

一切准备就绪后,我们就可以开始实现推理管道了。我们将在本地训练的模型转移到 Raspberry Pi 进行推理。然后我们加载它以备将来使用。

负载预训练模型

在 Raspberry 上加载模型大约需要 2 分钟,所以我们只在启动主管道后做一次。然后,我们需要读取检测到运动后拍摄的图像。

加载要分类的图像

之后,我们将其提供给预测方法。请注意,我们应用 tensor flow . keras . applications . vgg 19 中的 preprocess_input 方法,该方法以与训练期间相同的方式预处理图像。

将图像分类

最后,我们将预测的类提供给主管道,并通过在末尾添加类名来重命名原始图像。重命名部分是未来评估所必需的。

保存图像

现在,当我们在 Raspberry 上运行我们的模型时,我们可以检查它在速度和准确性方面的性能。正如我前面提到的,加载模型需要 2 分钟,加载保存的图像需要 0.2 秒,对图像进行分类需要 2 秒。这速度足以吓跑鸽子。然而,模型在生产环境中运行几天后,我开始面临的问题是数据漂移。现实总是比一个阶段性的实验更复杂。现实是狂野的,以前从未发生过的事情会突然发生。我们无法预见它,我们只需要对我们实验室取得的成绩持怀疑态度,并足够灵活地适应不断变化的环境。我所说的是鸽子行为的变化。他们开始在我阳台前的树上筑巢。为什么这是个问题?因为它们开始出现在我的阳台上,嘴里叼着棍子。这是模型还没有准备好处理的事情,因为它从来没有见过一只鸽子拿着一根棍子。因此它断定它不是一只鸽子。

拿着棍子的鸽子

接下来的几天,拿着棍子的鸽子成了我阳台上的常客,这让我收集到了新的数据。我重新训练了这个模型,并且已经在庆祝成功了,看着鸽子在着陆后仅仅三秒钟就飞离了我的阳台。然而,我的庆祝太早了。一天,我决定清理阳台上鸽子掉落的树枝,因为它们对我的鸽子回避系统感到惊讶。现在,我惊讶地意识到,系统识别出我是一只鸽子,只是因为我手里拿着棍子。

我被归类为鸽子取决于我手里拿着什么

在左边的照片上,我手里拿着棍子,我被归类为一只鸽子。在右边的照片中,同样的手,但是没有棍子,被归类为人类。

过滤网络第一层的地图

当我们从神经网络的第一层检索激活时,我们可以在右下角观察到手和棍子激活的过滤图。这样,我们可以对如何做出分类决策建立一些直觉。

我的下一步是收集棍子的图像,我拿着棍子,有棍子和没有棍子的鸽子。然后我根据新数据重新训练了模型。这让我在测试数据集上再次获得了大约 98%的准确率,在生产数据集上也是如此,但只是在接下来的 5 天内。之后,我不得不根据新收集的数据重新训练模型。这让我们了解到这个项目的主要内容:

为了开发强大的机器学*产品,数据科学家应该采取端到端的所有权。这不仅意味着在 jupyter 笔记本上培训模型,还意味着生产部署和产品的进一步支持和开发。

不得不说,经过“模型备份→数据采集→数据标注→模型评估→模型再训练→生产部署”几个圈子,模型开始概化图像好了很多。最后,它学会了“鸟”的概念,鸽子回避系统开始从我的阳台上赶走各种各样的鸟,不仅仅是鸽子。

最后,这就是系统在生产中的工作方式:

一只鸽子落在阳台上,但几乎立即飞走了,因为它受到了运动的干扰

观点

正如我们已经看到的,数据漂移对于在生产中运行的机器学*解决方案来说是一个严重的问题。因此,我希望自动化模型备份→数据收集→数据标记→模型评估→模型培训→生产部署的循环。为此,我计划使用云解决方案。这可能是未来文章的主题。

保持更新,如果你对这个项目有任何问题,请随时通过 LinkedIn 联系我。

如何使用 Docker 在 AWS 上部署仪表板应用程序

原文:https://towardsdatascience.com/how-to-use-docker-to-deploy-a-dashboard-app-on-aws-8df5fb322708?source=collection_archive---------3-----------------------

卡洛斯·穆扎Unsplash 上拍摄

如何与更广泛的受众分享您的分析仪表板的分步指南

仪表板是探索数据和模型行为的绝佳方式。它们也是与技术和非技术涉众沟通的不可或缺的工具。我假设你不需要任何说服——你已经花了很多时间精心打磨你的 R ShinyPython Dash web 应用程序!你为自己创造的东西感到自豪…但是仪表板只在你的笔记本电脑上工作。您如何允许其他人访问您的仪表板?

“我们大多数人需要听音乐才能理解它有多美。但这通常不是我们展示统计数据的方式:我们只展示音符,不播放音乐。”— 汉斯·罗斯林

本指南假设您已经准备好部署仪表板应用程序。如果不是这样,您可以通过克隆这个 Github repo 来完成。不了解 Docker 或 AWS。本次回购中的仪表板应用程序使用联合分析来分析用户对电动汽车的偏好。你可以在这里了解这个应用的更多信息。然而,您不需要理解这个仪表板做什么来遵循这个指南。仪表板的预览如下所示:

用于联合分析的仪表板应用程序

应用程序的文件结构如下所示:

图一。Python Dash web 应用程序的代码

在上面的 web 应用程序中,dashboard.py包含了应用程序代码。当用户与仪表板交互时,联合分析由dashboard.py中的函数触发,这些函数随后调用analyze.py中的相关联合函数来对DataPrecomputed Data文件夹运行计算。README.md是唯一依赖于Figures文件夹的文件。

Docker 如何帮助在云上部署?

Docker 使您能够部署一个包含所有所需部分(即库、依赖项)的应用程序,并将其作为一个单独的映像发布。我们可以在任何安装了 Docker 的主机上运行这些映像(即在任何 Docker 引擎上),而不考虑架构或操作系统。这些运行的实例被称为容器。如果该映像在您的笔记本电脑上成功运行,您可以保证它可以在任何 Docker 引擎上运行。由于许多云平台支持 Docker 映像的运行,我们可以很容易地在云中部署仪表板应用程序。

现在我们对 web 应用程序和 docker 有了更多的了解,我们可以继续在 AWS 上部署它。

步骤 0:先决条件

要完成这项工作,您需要在系统上安装 Docker 以及一个 AWS 帐户。

子步骤 0a:在系统上安装 Docker

在您的系统上安装 Docker 的说明可从这里获得。如果你想在 Windows 或 OSx 上运行 Docker,你需要安装 Docker Desktop。由于 Docker 最初是为 Linux 构建的,Docker Desktop 将运行一个 Linux 虚拟机,该虚拟机随后启动基于 Linux 的映像。

子步骤 0b:注册 AWS 帐户

你可以在这个链接注册免费使用 AWS 服务一年。

子步骤 0c:安装 AWS 命令行界面

命令行界面(CLI)允许您从命令行调用 AWS 服务。您可以按照这里的说明安装 AWS CLI。

以下说明假设您已经安装了 CLI 版本 1。

步骤 1:为容器化准备仪表板应用程序

您的本地系统和 docker 容器之间有两个差异,可能会导致部署中的问题:

  1. 网络配置
  2. 文件系统

网络配置

Python Dash 的情况下,默认是让 app 在localhost运行。但是,在这种情况下,您只能从本地计算机访问服务器。该应用通常使用以下样板文件在本地部署:

if __name__ == '__main__':
    .
    .
    app.run_server(debug=True)

上面的代码不允许您从 Docker 引擎访问 dashboard 应用程序,因为该应用程序只能由容器访问。我们需要在dashboard.py中明确指定主机,以便从容器外部访问仪表板应用程序。

if __name__ == '__main__':
    .
    .
    app.run_server(host='0.0.0.0', port=8050, debug=True)

如上图修改dashboard.py并保存。一旦构建并运行了 docker 映像,我们就可以在[http://0.0.0.0:8050](http://0.0.0.0:8050)通过 web 浏览器访问仪表板。在 R 闪亮的情况下,只要我们在步骤 2 中露出适当的端口,仪表板就应该可以从[http://127.0.0.1:<port](http://127.0.0.1:8001)>处接*。我们可以在 R Shiny 应用程序代码中指定要使用的端口:

options(shiny.port = 8100)

文件系统

docker 容器的文件系统反映了 Linux 系统的文件系统。其根目录下包含binetcmntsrvsys等文件夹。如果构建一个 Python Dash app,通常的做法是将 app 的源代码存储在根目录下的app文件夹中。在闪亮的情况下,我们可以在srv文件夹里面创建一个子文件夹shiny-server来存储源代码。

因此,当应用程序被容器化时,我们在源代码中指定的任何相对路径几乎肯定不起作用,因为容器将当前路径作为其根目录(默认)。最简单的解决方案是将容器的当前目录改为指向源代码的位置。我们将在步骤 2 中看到如何做到这一点。

另一个(次优)解决方案是修改源代码,这样我们就可以给出绝对路径。例如,在dashboard.py中,我们可以将第 16 行和第 17 行修改为:

folderStr = "/app/Data/"  # old version was "./Data"
destFolder = "/app/Precomputed Data/"

这种方法带来的问题是仪表板应用程序变得更难维护。让我们在dashboard.py中保持文件路径不变。相反,我们将在步骤 2 中明确更改工作目录。

第二步:从你的 dashboard 应用程序构建一个 Docker 图像

我们创建一个文件夹DashboardImage,我们将在其中填充 Docker 图像的原始内容。最终,任何 Docker 引擎都可以使用这个 Docker 映像来运行 dashboard 应用程序。让我们在DashboardImage中创建以下文件结构:

图二。仪表板图像的内容

让我们更仔细地看看这个目录的内容:

  • app文件夹:除了README.mdFigures文件夹,我们将 Dashboard app 内容(如图 1 所示)复制到这个文件夹中。
  • Figures文件夹:将仪表盘 app 的Figures文件夹复制到这里。这个文件夹只有README.md需要。
  • README.md:将README.mdapp文件夹移到这里。
  • Dockerfile:用于创建满足仪表板应用程序要求的图像的指南。
  • requirements.txt:只有当你的仪表板是用 Python 写的时候才需要。它列出了运行 Dashboard 应用程序所需的库。通过在这里指定所需的 Python 包,我们使Dockerfile更具可读性。有了闪亮的,我们省略这个文件,在Dockerfile中显式安装所需的包。

子步骤 2a:编写 requirements.txt 文件

requirements.txt文件应该包含您的仪表板需要的所有库。它可能看起来像这样:

dash
dash-renderer
dash-core-components
dash-html-components
dash-table
plotly
numpy
pandas
scipy
matplotlib
seaborn

仪表板需要前六个库才能正确呈现。analyze.py需要剩余的库来执行联合分析。

子步骤 2b:编写 Dockerfile 文件

Dockerfile包含设置仪表板应用程序的说明。Dockerfile分层构建图像。每行都有格式:<指令>自变量>。让我们创建以下Dockerfile:

FROM continuumio/miniconda3COPY requirements.txt /tmp/
COPY ./app /app
WORKDIR "/app"RUN conda install --file /tmp/requirements.txtENTRYPOINT [ "python3" ]
CMD [ "dashboard.py" ]

第一行从 Dockerhub(一个公共的容器库)中提取一个基本映像。基本映像包含 Miniconda,它位于基本 Ubuntu 发行版之上。如果你想部署一个闪亮的应用程序,你可以选择rocker/shiny图片。

第二行和第三行将requirements.txt文件和app文件夹从主机上的应用程序文件夹复制到 Docker 容器根目录下的tmp文件夹和app文件夹。如果这些文件夹不存在,则会自动创建。第四行将工作目录设置为app文件夹。这一行是适应容器文件结构的首选解决方案,因为它只需要对Dockerfile进行更改。

第五行安装requirements.txt中指定的每个包。对于一个闪亮的应用程序,你需要明确指定你想要安装的每个包。例如:

RUN R -e "install.packages(c('package1', 'package2', 'package3'))"

我们还想为闪亮的应用程序公开正确的端口。因此,我们将在Dockerfile中包含以下行:

EXPOSE <PORT NUMBER>

ENTRYPOINT指定当图像作为容器运行时将执行的命令。如果我们在运行 docker 映像时没有指定参数,Docker 将使用CMD行中显示的默认参数来执行,这将使 Python 运行 dashboard 应用程序。注意,我们不需要指定应用程序的绝对路径,即/app/dashboard.py,因为我们已经将工作目录更改为/app。在 R 中,我们使用CMD来执行闪亮的服务器。

第三步:建立你的码头工人形象

一旦创建了内容,我们就可以构建一个 docker 映像。为了创建图像conjoint_dashboard,进入DashboardImage文件夹并运行以下程序:

docker build -t conjoint_dashboard .

Docker 通过Dockerfile一行一行地构建软件层。

要确认关于图像的一些基本细节,运行docker images

REPOSITORY             TAG     IMAGE ID       CREATED        SIZEconjoint_dashboard     latest  b50b2d7a61cc   6 seconds ago  2.32GBcontinuumio/miniconda3 latest  406f2b43ea59   4 months ago   430MB

您还可以通过运行以下命令来检查映像是否构建正确:docker run conjoint_dashboard。回想一下在步骤 1 中,我们修改了dashboard.py以使主机可以在[http://0.0.0.0:8050](http://0.0.0.0:8050)访问。从 docker 机器(即您的计算机)上,在上述地址打开一个 web 浏览器,检查仪表板是否按预期工作。

第四步:上传你的 Docker 图片到 Amazon 注册

我们需要确保我们的图像在 AWS 中可用。为此,我们需要执行以下步骤:

  • 在 ECR(AWS 弹性容器注册中心)中创建一个存储库dashboard我们特意给 AWS 存储库取了一个与我们构建的映像不同的名称,这样我们就可以很容易地区分这两者。
  • 为您的 AWS 帐户创建访问密钥
  • 使 Docker 客户端能够向 AWS 注册中心进行身份验证
  • conjoint_dashboard推入dashboard仓库

子步骤 4a:在 ECR 中创建存储库

登录 AWS 管理控制台。您的首次登录将使用您的 root 帐户。登录后,搜索“ECR”。弹性容器注册中心(ECR)是一个完全托管的 Docker 容器注册中心。一个注册中心是一个储存库的集合。点击开始创建新的存储库。我们将存储库命名为dashboard,并单击创建存储库

子步骤 4b:创建访问密钥

我们将为 root 帐户创建一个访问密钥。避免使用 root 帐户是一个很好的做法,因为它提供了对 AWS 资源的无限制访问。然而,为了简化过程,我们将使用 root 帐户部署应用程序。

要创建访问密钥,请单击您的帐户名,然后单击我的安全凭证。

在新屏幕中,打开访问密钥(访问密钥 ID 和秘密访问密钥)下拉菜单,点击创建新的访问密钥。创建密钥后,您将收到以下消息。

下载凭据并将其存储在安全的地方。

子步骤 4c:使 Docker 客户端能够通过 AWS 进行身份验证

使用您新创建的访问密钥,您将需要在终端中使用以下命令配置您的aws_access_key_idaws_secret_access_key:

aws configure set aws_access_key_id <YOUR_ACCESS_KEY>
aws configure set aws_secret_access_key <YOUR_SECRET_KEY>

我们还需要设置区域和输出格式。您所在的地区可以从 AWS 管理控制台中找到。

然后,我们可以在终端中运行以下命令:

aws configure set default.region <YOUR_REGION>
aws configure set default.output json

我们现在可以尝试登录 ECR:

$(aws ecr get-login --no-include-email --region <YOUR REGION>)

您应该会收到一条登录成功的消息。

子步骤 4d:将构建的仪表板推入 AWS 存储库

我们首先用新创建的仪表板存储库的 URI 来标记conjoint_dashboard。您可以通过点击dashboard存储库在 AWS 管理控制台中找到 URI:

我们通过在终端中运行以下命令,用上面的 URI 标记图像conjoint_dashboard:

docker tag conjoint_dashboard <ACCOUNT NUM>.dkr.ecr.<REGION>.amazonaws.com/dashboard

我们现在可以将图像推送到存储库。

docker push <ACCOUNT NUM>.dkr.ecr.<REGION>.amazonaws.com/dashboard

conjoint_dashboard图像上传到注册表所需的时间取决于您的互联网连接。图片推送后,点击 ECR 中的dashboard即可找到图片。

您将需要图像 URI 来部署仪表板应用程序。图像标签latest显示在 URI 的末尾(冒号后),表示仪表板的版本。

步骤 5:使用 ECS 部署 Docker 容器

弹性容器服务(ECS)运行和管理 Docker 容器。它是高度可伸缩的,允许自动部署更多的容器来满足需求。返回 AWS 管理控制台的主页,搜索“ECS”。

进入 ECS 后,让我们单击开始按钮。您将被带到步骤 1:容器和任务。容器定义描述了容器的需求以及系统应该如何运行容器。通过点击配置按钮,我们可以配置容器来容纳仪表板应用程序。

我们只需要填充前两个字段。我们将容器命名为conjoint_dashboard,并用在步骤 4 结束时给出的图像 URI 填充第二个字段。点击更新

向下滚动到任务定义并点击编辑。在这里,我们可以指定容器的硬件要求。我们如下填充这些字段,然后保存

当我们点击下一个的时,我们将被带到服务定义页面。这些字段是预先填充的,因此单击下一个进入集群定义。我们需要做的就是将集群命名为“联合”,然后点击下一步。然后您可以查看配置并点击创建

这个过程需要几分钟。完成后,点击查看服务

步骤 6:访问仪表板服务

默认情况下,该服务只允许端口 80 上的流量。这是一个问题,因为 Docker 容器只能在端口 8050 上访问。因此,我们需要改变安全组的规则。点击安全组标识符。

页面加载后,点击入站规则选项卡和编辑规则按钮。

点击保存规则前,按如下方式重新填充字段。

我们可以通过单击 ECS 侧栏中的集群并单击conjoint来检查服务是否正在运行。页面加载后,点击任务选项卡,然后点击任务标识符。

将显示任务配置。

我们可以看到任务正在运行,并且可以在地址[http://13.239.27.169:8050](http://13.239.27.169:8050.)访问。当然,你的 IP 会不一样。用您的 IP 地址代替上面的 IP 地址,您应该可以访问您的仪表板。为了快速浏览这个应用程序,你可以观看这个链接

访问 AWS 上的仪表板

结论

你有它!通过仔细遵循这些步骤,您将成功地在 AWS 上部署了一个仪表板应用程序。通过在步骤 5 中正确配置 ECS 设置,还可以使服务可扩展,随着需求的增加自动部署新任务。

感谢阅读!如果你觉得这些材料有用,你可能也会觉得我最*写的一篇文章很有趣:不,深度学*是不够的

如何在 BigQuery 中使用动态 SQL

原文:https://towardsdatascience.com/how-to-use-dynamic-sql-in-bigquery-8c04dcc0f0de?source=collection_archive---------2-----------------------

格式化字符串,并使用立即执行

比方说,我们想要查找过去 3 天加拿大各省确诊的 COVID 病例数。有一个 BigQuery 公共数据集,里面有 Johns Hopkins 发布的信息,我们可以如下查询:

SELECT 
 *   
FROM `bigquery-public-data`.covid19_jhu_csse.confirmed_cases
WHERE country_region LIKE 'Canada'

我们得到:

每个日期都有一栏

呀!每个日期都有一栏。我们如何找到最*三天的数据?

BigQuery 中的动态 SQL!图片由来自 PixabayJim Semonik 拍摄

获取列的信息模式

我们可以使用 INFORMATION_SCHEMA 来获取列的列表,并使用以下命令来查找最*三天:

SELECT 
   column_name, 
    parse_date('_%m_%d_%y', column_name) AS date
FROM 
  `bigquery-public-data`.covid19_jhu_csse.INFORMATION_SCHEMA.COLUMNS
WHERE 
    table_name = 'confirmed_cases' AND 
    STARTS_WITH(column_name, '_')
ORDER BY date DESC LIMIT 3

这将返回:

表中的最*天数

创建动态 SQL 语句

您可以使用 EXECUTE IMMEDIATE 运行动态 SQL 语句。例如,假设我们有一个列名为 _5_18_20 的变量,这就是如何使用它来执行 SELECT 语句:

DECLARE col_0 STRING;
SET col_0 = '_5_18_20';**EXECUTE IMMEDIATE** **format**("""
  SELECT 
     country_region, province_state, 
    ** %s** AS cases_day0
  FROM `bigquery-public-data`.covid19_jhu_csse.confirmed_cases
  WHERE country_region LIKE 'Canada'
  ORDER BY cases_day0 DESC
""", **col_0);**

仔细看看上面的查询。首先,因为我声明了一个变量,等等。,这是一个 BigQuery 脚本,其中每个语句都以分号结束。

然后,我使用 BigQuery 的字符串格式函数来创建我想要运行的语句。因为我要传入一个字符串,所以我在格式字符串中指定了%s,并传入 col_0。

结果包括两个阶段:

第二阶段的结果是:

编写过去 3 天的脚本

我们可以结合以上三个想法——INFORMATION _ SCHEMA、脚本和立即执行来获得过去 3 天的数据。

DECLARE columns ARRAY<STRUCT<column_name STRING, date DATE>>;SET columns = (
  WITH all_date_columns AS (
    SELECT column_name, parse_date('_%m_%d_%y', column_name) AS date
    FROM `bigquery-public-data`.covid19_jhu_csse.INFORMATION_SCHEMA.COLUMNS
    WHERE table_name = 'confirmed_cases' AND STARTS_WITH(column_name, '_')
  )
  SELECT ARRAY_AGG(STRUCT(column_name, date) ORDER BY date DESC LIMIT 3) AS columns
  FROM all_date_columns
);EXECUTE IMMEDIATE format("""
  SELECT 
     country_region, province_state, 
     %s AS cases_day0, '%t' AS date_day0,
     %s AS cases_day1, '%t' AS date_day1,
     %s AS cases_day2, '%t' AS date_day2
  FROM `bigquery-public-data`.covid19_jhu_csse.confirmed_cases
  WHERE country_region LIKE 'Canada'
  ORDER BY cases_day0 DESC
""", 
columns[OFFSET(0)].column_name, columns[OFFSET(0)].date,
columns[OFFSET(1)].column_name, columns[OFFSET(1)].date,
columns[OFFSET(2)].column_name, columns[OFFSET(2)].date
);

步骤:

  • 将列声明为一个数组变量,该变量将存储最* 3 天的列名和日期
  • 将列设置为获取 3 天的查询结果。请注意,我正在使用 ARRAY_AGG,这样我就可以将完整的结果集存储在一个变量中。
  • 格式化查询。请注意,我使用`%t '来表示时间戳(有关详细信息,请参见字符串格式文档),并传入了六个参数。

结果是:

使用立即执行

除了使用字符串格式,您还可以使用如下命名变量:

EXECUTE IMMEDIATE """
  SELECT country_region, province_state, _5_18_20 AS cases 
  FROM `bigquery-public-data`.covid19_jhu_csse.confirmed_cases 
  WHERE country_region LIKE [**@country**](http://twitter.com/country)
  ORDER BY cases DESC LIMIT 3
"""
**USING 'Canada' AS country;**

您也可以使用问号来处理位置变量:

EXECUTE IMMEDIATE """
  SELECT country_region, province_state, _5_18_20 AS cases 
  FROM `bigquery-public-data`.covid19_jhu_csse.confirmed_cases 
  WHERE country_region **LIKE ?**
  ORDER BY cases DESC **LIMIT ?**
"""
**USING 'Canada', 3;**

USING 子句在某些情况下很棘手。例如,以下内容不起作用:

*EXECUTE IMMEDIATE """
  SELECT country_region, province_state, ? AS cases -- PROBLEM!!!
  FROM `bigquery-public-data`.covid19_jhu_csse.confirmed_cases 
  WHERE country_region LIKE ?
  ORDER BY cases DESC LIMIT ?
"""
USING '_5_18_20', 'Canada', 3; -- DOESNT WORK!!!!*

这是因为第一个参数被解释为:

*'_5_18_20' AS cases*

因此,不能通过使用。因此,我推荐使用 String FORMAT()来创建立即执行的查询,因为它没有这些问题。

下一步是什么?PIVOT(),就是这样!

动态 SQL 特性是在 big query 10 岁生日的时候发布的。这里有一个视频,一些 BigQuery 的朋友祝它生日快乐:

来自 10 年前的第一个用户线程对在几秒钟内处理 60B 记录赞不绝口,并对*乎实时的查询(事情越变越多……)深思熟虑。在同一个线程中是第一个功能请求…枢轴:

动态 SQL 最终使这成为可能, Felipe Hoffa 承诺他将编写一个函数,最终能够在 BigQuery 中使用 PIVOT()——敬请期待。

尽情享受吧!

感谢我的同事Jagan r . Athreya对使用格式的有益讨论和建议,并感谢feli PE Hoffa的怀旧之旅。

中的 DynamoDB 流和 AWS Lambda 入门。网络核心

原文:https://towardsdatascience.com/how-to-use-dynamodb-streams-with-aws-lambda-and-net-core-62db43ae98c1?source=collection_archive---------14-----------------------

使用 AWS Lambda 在 C#中使用 DynamoDB 流的分步教程

事件驱动编程在当今的软件世界中非常流行。用松散耦合的、可独立部署的、易于扩展的组件来构建一个系统有很多优点。可以利用无服务器工具来创建其中的一些组件;一个 AWS,这通常意味着使用 DynamoDB 和 Lambda。在本文中,我们将构建一个小型的事件驱动系统,其中 DynamoDB 是我们的事件源,Lambda 函数被调用来响应这些事件。为此,我们将使用一个名为 DynamoDB Streams 的特性。

在一个表上启用 DynamoDB 流后,对该表的所有修改都会被记录下来,并按顺序推送到流中。AWS 没有指定流的内部,但是它们非常类似于 Kinesis 流(并且可能在幕后使用它们)。)有多种方法来使用流,包括使用 Kinesis 客户端库(AWS 提供的 SDK),但最简单的方法之一是将流配置为 Lambda 函数的触发器。

现在,让我们浏览启用 DynamoDB 流的过程,编写一个简短的 Lambda 函数来使用流中的事件,并将 DynamoDB 流配置为 Lambda 函数的触发器。我们将一步一步来,但如果你想跳到最后,检查源代码和 Terraform,直接去我的 GitHub repo 。如果你需要复* DynamoDB 的基础知识,可以看看我写的关于开始使用 DynamoDB 的文章。

先决条件

为了准确地遵循这个指南,你需要安装 Visual Studio 2019 和 AWS 工具包。我在这里使用这种设置是因为它与 Lambda 紧密集成;只需点击一下,即可将您的代码发布到 AWS。

我包含了一个 Terraform 文件来创建 DynamoDB 表(包括它的索引和流)。如果你以前没有使用过 Terraform,这是一个很棒的工具,可以让你把基础设施写成代码。或者,您可以使用 AWS 管理控制台手动创建和配置 DynamoDB 表。

创建 DynamoDB 表和流

我们先来看一下 Terraform 文件 main.tf 。该文件只包含一个资源(基础设施对象)——我们的 DynamoDB 表。在这个资源中,定义了表的每个属性和索引(在的前一篇文章中概述了全局和辅助索引)。)

启用流所需的两个参数是 stream_enabled(布尔)
和 stream_view_type(枚举)。steam_view_type 允许您选择将多少数据推送到流中。您可以从四个选项中进行选择:

  • KEYS_ONLY —仅修改记录的分区和排序键
  • NEW _ IMAGE 更新记录的所有属性
  • OLD_IMAGE —修改前记录的所有属性
  • 新图像和旧图像-修改前后的所有属性

在我们的示例中,我们将选择 NEW_AND_OLD_IMAGES,这样我们可以获得尽可能多的信息。一般来说,您会希望在使用最少数据量的同时选择满足您需求的选项。

如果您想使用 Terraform 在 AWS 中运行这个数据库,唯一需要的先决条件是您的机器上已经存储了共享 AWS 凭证(如果您曾经使用过 AWS CLI,那么您已经准备好了。)下载 Terraform 并添加到你的路径中。编辑 main.tf 文件,并将“profile”更改为您自己的 AWS 概要文件的名称。然后在包含。tf 文件并运行以下两个命令:

Terraform 将执行生成基础设施所需的所有 AWS APIs。如果您对 terraform 文件进行了更改,您可以再次运行“terraform 应用”来执行更新。当你用完后,执行“terraform destroy”将从你的 AWS 环境中删除你的所有更改。

创建一个 Lambda 来使用该流

有了我们的表,让我们为 Lambda 函数编写代码来使用它。打开 Visual Studio 201 并创建一个新的 AWS Lambda 项目(。NET Core c#);一旦安装了 AWS Toolkit for Visual Studio,就可以使用这个模板。当提示选择蓝图时,选择“空函数”,因为我们要从头开始。

看看我们项目的 NuGet 依赖项。模板已经添加了基本 Lambda 函数所需的包。

我们需要再添加一个依赖项。从管理 Nuget 包窗口,搜索并安装 Amazon.Lambda.DynamoDBEvents。看一看它,然后我们将讨论它:

在顶部附*,我们为 Amazon 添加了一个 using 指令。Lambda.DynamoDBEvents 命名空间。然后我们转到模板提供的 Lambda 函数(FunctionHandler),它接受一个字符串和一个 ILambdaContext 作为参数。ILambdaContext 包含关于 Lambda 函数的有用信息,比如内存限制、剩余执行时间和日志访问,所以我们将保留这些信息。我们用 DynamoDBEvent 替换了 string 参数;此对象包含 DynamodbStreamRecord 对象的列表。每个 DynamodbStreamRecord 都是对 DynamoDB 表的单个数据修改的描述。

当我们配置 Lambda 来监听 DynamoDB 流时,我们将选择一个最大批处理大小和一个收集该批处理的时间窗口。因此,我们的函数需要能够在每次被调用时处理多个 DynamodbStreamRecord。所以我们添加了一个循环来遍历 DynamoDBEvent 中的每一项并执行一些操作。在我们的示例中,操作是使用 ILambdaContext。Logger 将关于事件的信息写入 CloudWatch,但是您可以修改函数的内容以适应您的用例。

代码准备就绪后,我们可以通过在解决方案资源管理器中右键单击项目并选择“发布到 AWS Lambda”来将函数发布到 AWS。"为您的新 Lambda 函数选择一个名称和一个 AWS 区域。

下一个屏幕将询问关于 Lambda 的更多细节。我们将对默认值进行的唯一更改是选择一个 IAM 角色;这指定了 Lambda 在执行期间必须与其他 AWS 服务交互的特权。基于 AWSLambdaDynamoDBEecutionRole 创建一个新角色—这允许对 DynamoDB 流的列表和读取访问,以及对 CloudWatch 日志的写入访问。然后继续把你的函数上传到云端。

Lambda 配置— AWS 控制台

最后一步,导航到 AWS 控制台的 Lambda 部分,选择我们刚刚发布的函数。

我们将添加一个触发器,以便每当记录被添加到 DynamoDB 流中时启动 Lambda 函数。从功能配置屏幕中选择“添加触发器”并选择 DynamodDB。您将看到下面的屏幕,为我们的事件源编写详细信息。

确保选择了所需的 DynamoDB 表,然后查看其他选项。批处理大小是每次执行时发送给我们的函数的 DynamodbStreamRecords 的最大数量。批处理窗口决定了流从表中读取事件并调用 Lambda 函数的步调,以秒为单位。对于这个例子,默认的选择就足够了,但是在现实世界中,您会希望根据您的用例来定制这些选择。较短的批处理窗口对于需要接*实时地对更新做出反应的应用程序来说是有意义的,而较长的窗口(和较大的批处理大小)在处理单个项目是快速操作并且可以在批处理过程之间暂停的情况下可能更具成本效益。

测试和验证

是时候试试我们创造的东西了。前往 AWS 控制台中的 DynamoDB 表,并开始进行更改。添加一些新记录。修改现有记录。我们如何知道我们的流和 Lambda 是否在工作?嗯,由于我们的 Lambda 写入 CloudWatch,我们必须检查日志。在 AWS 控制台中导航到 CloudWatch,并从侧栏中选择 log groups。

您应该会看到一个与 Lambda 函数同名的组。打开它,你会发现一个日志流列表。Lambda 函数的每个执行上下文将创建一个流。作为参考,第一次调用函数时,会创建一个执行上下文(函数的临时运行时环境)。连续调用你的函数会遇到相同的上下文,直到十分钟后你的函数才执行。冷却期过后,再次调用 Lambda 将导致函数被加载到一个新的执行上下文中(这就是所谓的冷启动。)对函数的多次同时调用也可能导致创建新的执行上下文,因为一个执行上下文一次只能处理一个请求。

无论如何,您应该看到至少一个日志流。如果没有,请尝试刷新页面;有时日志需要一段时间来传播。如果你仍然运气不好,检查你为 Lambda 配置的触发器,确保它被设置到正确的 DynamoDB 表。此外,如果您的批处理窗口大小被设置为大于零的任何值,那么您必须等到它到期时,流才会收集所有的表修改。当您点击流时,您应该会看到类似如下的日志:

您还可以进入 CloudWatch 指标,显示有关您的功能的更多信息。下面你会发现一个令人兴奋的函数调用图;你可以看到我们在 2:25 从 0 到 1。

概述

流允许有趣的用例,否则在 DynamoDB 中很难支持这些用例。每当一个用户超过他当前的最高分,我们就可以给他发电子邮件。我们还可以聚合数据并将其写入另一个表中;也许我们会跟踪某个游戏的高分在某个时间窗口内改变了多少次。流还支持数据复制;这在我们希望在更适合这类活动的数据库(如 SQL Server 或 Redshift)中运行分析查询的情况下非常有用。)花几分钟时间试用它们,看看它们是否适合您未来应用程序中的用例。

如何在 Javascript 中使用 Generator 和 yield

原文:https://towardsdatascience.com/how-to-use-generator-and-yield-in-javascript-d1771bf698cd?source=collection_archive---------49-----------------------

更好的编程

你知道 JavaScript 里有个叫“生成器”的东西吗?

Thomas re abourgUnsplash 拍摄的照片

前段时间我写了一篇文章解释了生成器的概念以及如何在 Python 中使用它们,但是你知道 JavaScript 也有自己版本的生成器吗?这其实是一个很多开发 JavaScript 应用的人都不知道它存在的概念,所以今天我们要介绍的是 JavaScript 中的生成器。

什么是发电机?

在 ES6 中,我们引入了伟大的新功能,如箭头函数扩展操作符和生成器等等,但是什么是生成器呢?生成器是一个与普通函数相反的函数,它允许函数退出并在以后重新进入,并在重新进入时保留其上下文(变量绑定)。

让我们把它分解开来,一步一步地研究发电机,这样我们都可以理解它们是如何工作的。当我们执行一个常规函数时,解释器会将所有代码运行到那个函数中,直到函数完成(或者抛出一个错误)。这就是所谓的运行至完成模型。

让我们以一个非常简单的函数为例:

function regularFunction() {
    console.log("I'm a regular function")
    console.log("Surprise surprice")
    console.log("This is the end")
}regularFunction()-----------------
Output
-----------------
I'm a regular function
Surprise surprice
This is the end

还没有什么新奇的东西,正如你所期望的,这是一个常规函数,它会一直执行到最后或者返回值。但是如果我们只想在任意点停止函数来返回值,然后继续呢?这时,发电机就出现了。

我的第一个生成器函数

function* generatorFunction() {
    yield "This is the first return"
    console.log("First log!")
    yield "This is the second return"
    console.log("Second log!")
    return "Done!"
}

在我们执行这个函数之前,你可能会想知道一些事情,首先什么是function*?这就是我们用来将函数声明为生成器的语法。而yield呢?与 return 不同的是,yield将通过保存函数的所有状态来暂停函数,并在随后的调用中从该点继续。在这两种情况下,表达式都将返回给调用方执行。

我们的功能到底发生了什么?让我们通过调用函数来找出答案:

generatorFunction()-----------------
Output
-----------------
generatorFunction {<suspended>} {
    __proto__: Generator
    [[GeneratorLocation]]: VM272:1
    [[GeneratorStatus]]: "suspended"
    [[GeneratorFunction]]: ƒ* generatorFunction()
    [[GeneratorReceiver]]: Window
    [[Scopes]]: Scopes[3]
}

等等,什么?当我们调用一个生成器函数时,这个函数不会被自动触发,而是返回一个迭代器对象。这个对象的特别之处在于,当调用方法 next()时,生成器函数的主体被执行,直到第一个yieldreturn表达式。让我们来看看它的实际应用:

const myGenerator = generatorFunction()
myGenerator.next()-----------------
Output
-----------------
{value: "This is the first return", done: false}

如前所述,生成器一直运行到第一条yield语句,并生成一个包含value属性和done属性的对象。

{ value: ..., done: ... }
  • value属性等于我们产生的值
  • done属性是一个布尔值,它只在生成器函数返回值时设置为true。(未屈服)

让我们再次调用next(),看看我们会得到什么

myGenerator.next()-----------------
Output
-----------------
First log!
{value: "This is the second return", done: false}

这次我们首先看到我们的生成器主体中的console.log被执行并打印First log!,以及第二个生成的对象。我们可以继续这样做:

myGenerator.next()-----------------
Output
-----------------
Second log!
{value: "Done!", done: true}

现在第二个console.log语句被执行,我们得到一个新的返回对象,但是这次属性done被设置为true

属性的值不仅仅是一个标志,它是一个非常重要的标志,因为我们只能迭代一个生成器对象一次!。不相信我?尝试再次呼叫next():

myGenerator.next()-----------------
Output
-----------------
{value: undefined, done: true}

还好它没有崩溃,但是我们只是得到了未定义的结果,因为valuedone属性仍然设置为 true。

产生迭代器

在我们进入一些场景之前,yield 操作符还有一个特殊性,那就是yield*。让我们通过创建一个函数来解释它,这个函数允许我们迭代一个数组,我们可以天真地想到这样做:

function* yieldArray(arr) {
    yield arr
}const myArrayGenerator1 = yieldArray([1, 2, 3])
myArrayGenerator1.next()-----------------
Output
-----------------
{value: Array(3), done: false}

但这并不是我们想要的,我们想要产生数组中的每个元素,所以我们可以尝试这样做:

function* yieldArray(arr) {
    for (element of arr) {
        yield element
    }
}const myArrayGenerator2 = yieldArray([1, 2, 3])
myArrayGenerator2.next()
myArrayGenerator2.next()
myArrayGenerator2.next()-----------------
Output
-----------------
{value: 1, done: false}
{value: 2, done: false}
{value: 3, done: false}

现在我们得到了想要的结果,但是我们能做得更好吗?是的,我们可以:

function* yieldArray(arr) {
    yield* arr
}const myArrayGenerator3 = yieldArray([1, 2, 3])
myArrayGenerator3.next()
myArrayGenerator3.next()
myArrayGenerator3.next()-----------------
Output
-----------------
{value: 1, done: false}
{value: 2, done: false}
{value: 3, done: false}

太棒了,通过使用 yield* expression,我们可以迭代操作数,并产生它返回的每个值。这适用于其他生成器,数组,字符串,任何可迭代的对象。

既然您已经了解了 JavaScript 中的所有生成器,那么它们有什么用处呢?

发电机的使用

关于生成器的伟大之处在于它们是惰性计算的,这意味着在调用next()方法后返回的值,只有在我们明确请求后才被计算。这使得生成器成为解决多种场景(如下所示)的好选择。

生成一个无限序列

正如我们在 Python 文章中看到的,生成器适合生成无限序列,这可以是从质数到简单计数的任何东西:

function* infiniteSequence() {
    let num = 0
    while (true) {
        yield num
        num += 1
    }
}for(i of infiniteSequence()) {
    if (i >= 10) {
        break
    }
    console.log(i)
}-----------------
Output
-----------------
0
1
2
3
4
5
6
7
8
9

注意,在这种情况下,我在i >= 10时退出循环,否则,它将永远运行(或者直到手动停止)。

实现 iterables

当你需要实现一个迭代器时,你必须用一个next()方法手工创建一个对象。此外,您必须手动保存状态。

假设我们想创建一个只返回Iamiterable的 iterable。如果不使用发电机,我们将不得不做这样的事情:

const iterableObj = {
  [Symbol.iterator]() {
    let step = 0;
    return {
      next() {
        step++;
        if (step === 1) {
          return { value: 'I', done: false};
        } else if (step === 2) {
          return { value: 'am', done: false};
        } else if (step === 3) {
          return { value: 'iterable.', done: false};
        }
        return { value: '', done: true };
      }
    }
  },
}
for (const val of iterableObj) {
  console.log(val);
}-----------------
Output
-----------------
I
am
iterable.

有了发电机,这就简单多了:

function* iterableObj() {
    yield 'I'
    yield 'am'
    yield 'iterable.'
}for (const val of iterableObj()) {
  console.log(val);
}-----------------
Output
-----------------
I
am
iterable.

更好的异步?

一些人认为生成器有助于改进承诺和回调的使用,尽管我更喜欢简单地使用 await/async。

警告

当我们使用发电机时,并不是所有的东西都闪闪发光。设计有一些限制,有两个非常重要的考虑因素:

  • 生成器对象只能一次性访问。一旦用完,就不能再迭代了。为此,您必须创建一个新的生成器对象。
  • 生成器对象尽可能不允许随机访问,例如数组。由于值是一个接一个生成的,您无法获得特定索引的值,您将不得不手动调用所有的next()函数,直到您到达所需的位置,但是之后,您将无法访问先前生成的元素。

结论

生成器函数对于优化我们的应用程序的性能非常有用,并且有助于简化构建迭代器所需的代码。

我希望您现在已经很好地理解了 JavaScript 中的生成器,并且可以在您的下一个项目中使用它们。

感谢阅读!

Jupyter 笔记本如何使用 Git / GitHub

原文:https://towardsdatascience.com/how-to-use-git-github-with-jupyter-notebook-7144d6577b44?source=collection_archive---------1-----------------------

这是一个针对 Jupyter 笔记本用户的综合性 Git 教程。如果你已经熟悉某一部分,可以随意跳过。最后你将能够-

  • 将您的笔记本推送到 GitHub 存储库
  • 开始版本化您的笔记本
  • 在 GitHub 上查看笔记本拉取请求
  • 了解如何恢复到特定版本
  • 获得反馈并与您的同事讨论笔记本电脑的变化
  • 轻松共享您的笔记本供他人查看

创建 GitHub 帐户

如果您没有 GitHub 帐户,请在这里创建一个。

在本地设置 Git

  • 下载并安装Git 的最新版本。
  • 通过在终端上运行以下命令,在 git 中设置您的姓名和电子邮件
>> git config --global user.name "Mona Lisa"
>> git config --global user.email "email@example.com"

创建新存储库

GitHub 存储库就像你在云中的超级文件夹。您可以存储文件(笔记本、数据、源代码),查看这些文件的历史更改,打开问题,讨论更改等等。人们通常为每个项目创建一个存储库。

让我们继续在 GitHub 上创建一个存储库。创建后,您将看到如下页面,复制突出显示的存储库 URL。

克隆存储库

让我们通过在终端上运行以下命令,在我们的机器上克隆 GitHub 存储库。它将在我们的机器上创建 projectA 目录,该目录链接到 GitHub 上的 amit1rrr/projectA 存储库。将[https://github.com/amit1rrr/projectA.git](https://github.com/amit1rrr/projectA.git)替换为上一步中您自己的存储库 URL

>> git clone https://github.com/amit1rrr/projectA.git
   Cloning into 'projectA'...
   warning: You appear to have cloned an empty repository.

将笔记本推送到 GitHub

我们的存储库现在是空的,让我们把一些笔记本推到它。我们将两个笔记本复制到我们克隆项目的目录下,

>> cp /some/path/analysis1.ipynb /path/of/projectA/
>> cp /some/path/scratch.ipynb /path/of/projectA/

假设我们要将[analysis1.ipynb](https://github.com/amit1rrr/projectA.git)推送到 GitHub。我们首先需要告诉本地 git 客户端开始跟踪文件—

>> git add analysis1.ipynb

您可以检查哪些文件正在被 git 状态跟踪,

您可以看到[analysis1.ipynb](https://github.com/amit1rrr/projectA.git) 在“待提交的变更下,因此它被我们的本地 git 客户端跟踪。现在让我们提交更改—

# -m flag provides a human friendly message describing the change
>> git commit -m "Adds customer data analysis notebook"

提交只是创建一个您可以随时恢复的检查点。现在最后把这个提交给 GitHub —

>> git push

现在你可以访问 GitHub 上的库页面查看你的提交

在分支中发展

假设您正在进行一个跨越多天的大型项目,但是您需要定期提交正在进行的工作作为备份。方法是创建一个特征分支。

每个存储库都有一个默认的分支(通常是“或“”),存储已完成工作的最新版本。团队中的每个成员都可以创建自己的功能分支来存储他们的 WIP 提交。当他们在一个特征分支中的工作准备好被共享时,他们可以创建一个 pull 请求供同行评审&随后将特征分支合并到 master 中。让我们用具体的步骤来解决这个问题。

假设我即将开始一个分析客户数据的新项目。首先,我将创建一个新的分支,

>> git checkout -b customer_data_insights

然后,我将创建/编辑一些笔记本和其他文件来进行实际的分析。当我准备好提交我的 WIP 时,我将执行通常的 git add,git commit,git push。在 git 推送时,您会看到以下错误,因为 GitHub 上还不存在这个分支。

简单地通过复制错误中显示的命令首先推动分支,

>> git push --set-upstream origin customer_data_insights

然后使用 git push 将您的提交推送到这个新创建的分支。

创建拉式请求

假设您已经在 feature branch 上工作了一段时间,它已经准备好进入黄金时间了。最有可能的是,你想先与你的同事分享它,在合并到主分支之前得到他们的反馈。这就是拉请求的作用。

您可以从 GitHub UI 创建拉请求。转到您的项目页面->拉式请求选项卡->单击“新建拉式请求”。

选择要合并到主控形状的分支。验证提交和更改的文件列表。点击“创建拉式请求”。

在下一页上,提供标题并简要描述您的更改,单击“创建拉动式请求”。

查看笔记本提取请求

GitHub pull 请求对于同行评审来说非常棒,因为它们可以让您并排看到更改并对其进行评论。但是在 Jupyter 的例子中,GitHub 显示了 JSON 的差异,这些差异真的很难理解(见下文)。

GitHub 上的笔记本差异

您可以使用 ReviewNB 来解决笔记本差异问题。它向您展示了丰富的差异&让您可以对任何笔记本单元格进行评论,以便与您的团队讨论变化。

丰富的差异和评论

一旦你的更改被队友批准,你就可以从 GitHub UI 合并它们。

或者从命令行运行 git merge + git push,

恢复到特定的笔记本版本

如果您想暂时回到提交,签出文件,然后回到您所在的位置,那么您可以简单地签出所需的提交。最后运行“git check out master”返回到当前状态。

如果你真的想回到一个旧的状态,并在那里做一些改变,你可以从那个提交开始一个新的分支—

>> git checkout -b old-state <some-commit-id>

你也可以在 GitHub 上浏览旧的提交,方法是进入你的项目页面->提交。打开所需的提交,点击“查看文件,查看提交时的笔记本状态。

分享你笔记本的只读链接

当你在 GitHub 上浏览存储库中的笔记本时,它会将它们呈现为 HTML 格式。所以像这种分享笔记本的只读链接非常方便。如果它是一个私有的存储库,与你共享链接的人需要有一个 GitHub 帐户,并且有权限访问你的存储库。

出于安全考虑,GitHub 不会在笔记本中运行任何 Javascript。如果您的笔记本电脑包含交互式小工具,您可以使用 nbviewerReviewNB

结论

如果您是 Git 的新手,可能需要一些时间来适应所有的命令。但是这是一种在软件项目中得到证实的合作方式&在数据科学工作中也被广泛使用。您可以将其与 ReviewNB 结合使用,以消除工作流程中的一些问题。

黑客快乐!

非技术性的 Google Colab

原文:https://towardsdatascience.com/how-to-use-google-colab-for-data-science-for-free-49c3353624e?source=collection_archive---------45-----------------------

当我们寻求执行分析时,有多种方式来运行分析或训练模型。最流行的方法是在您的计算机上下载 Anaconda 框架,并在 Jupyter 笔记本(以前称为 Python 笔记本)上工作。

数据科学中的笔记本是什么?

很简单,我们在大学里用笔记本做什么?我们做笔记,记下问题,解决问题,并试图整理我们的想法。数据科学或与之相当的编码通过 Jupyter 笔记本电脑实现。我们本地的这些笔记本使用我们计算机的硬件。

我本地机器上的 Jupyter 笔记本(图片由作者提供)

当我们想要训练更复杂的模型或使用更多的数据时,我们的局部可能是不够的。购买和维护硬件的成本可能很高。相反,如果您的硬件与您的数据科学不兼容,并且您有一台装有互联网浏览器的 PC,您可以免费做同样的事情!

为了训练更复杂的模型,我们希望利用并行处理来训练模型。我们可以在 Google Colab 上免费使用 GPU 来实现这一点。(记住,我们笔记本电脑上的 CPU,云上的 CPU 和 GPU)。

人们可以利用多种框架来尝试数据科学,Google Colab 是设置时间最少、速度最快的框架之一。这篇文章是为想尝试一下的非技术人员准备的。如果有任何问题,请随时通过 LinkedIn 或电子邮件联系我,我很乐意帮忙。欢迎在下面评论你想了解的更多信息(技术或其他方面)。接下来,我可以通过电子邮件快速回复。

照片由安朵斯瓦斯Unsplash 上拍摄

让我们深入了解一下云:Google Colab Edition。

[## 谷歌云平台基础(GCP)

云是一个复杂的空间。这并不像大多数人想象的那样简单。让我们简化一下…

towardsdatascience.com](/the-cloud-google-cloud-platform-gcp-made-easy-anish-mahapatra-3d0aed3fe7fa)

运行 Google Colab 笔记本

前往 Google Drive 并登录您的 Google 帐户。

点击新建图标(图片由作者

从这里,点击更多并选择谷歌合作实验室。

点击谷歌合作实验室,如图所示(图片由作者提供)

这将在 Google Colab 上打开一个新的 Python 笔记本。或者你可以去 Google Colab 打开一个新的笔记本。

Google Colab 中的新笔记本(图片由作者提供)

尝试进口熊猫,以确保它是有效的。

示例代码(图片由作者提供)

你现在有一个功能齐全的谷歌 Colab 笔记本。

在 Google Colab 上打开一个现有的 Jupyter 笔记本

假设您已经在本地 Jupyter 笔记本上做了一些工作——您可以直接复制代码,也可以通过文件菜单选项下的上传笔记本选项上传笔记本。

上传笔记本的选项(图片由作者提供)

如何将数据接收到 Colab 笔记本中

转到 Google Drive,创建一个新文件夹来存储您的数据。使用上传文件选项上传您的数据集和驱动器中的其他资料。

上传你需要的文件(图片由作者提供)

您现在应该有文件(。csv ),你需要在你的谷歌驱动器。接下来,我们将在 Google Colab 上安装 Google Drive。为此,我们需要允许 Google Colab 访问 Google Drive。

我会保持简单,我会给你一个方法,使用它。

# Since this notebook is from Google Colab, mounting Google Drive for authentication tokenfrom google.colab import drivedrive.mount('/content/drive')

一旦运行它,您应该会看到类似这样的内容:

(图片由作者提供)

点击该链接,您将进入另一个页面,在 Google Colab 上验证您的 Google Drive。

点击允许认证你的账户(图片由作者提供)

现在将生成一个唯一的代码,将其复制并粘贴到 Google Colab 的文本框中。

输入唯一的代码并点击回车(图片由作者提供)

您现在应该会看到类似下面的消息。

(图片由作者提供)

干得好!现在,您已经将 Google Drive 安装到了 Google Colab 上。这意味着你现在可以在 Google Colab 上访问 Google Drive 中的信息。

如何读取. csv 文件作为熊猫数据帧

这很简单。想象 Google Drive 是您的本地设备,并相应地加载数据——下面是一个示例

摄取一个. csv 文件作为熊猫数据帧(图片由作者提供)

别忘了进口熊猫套餐!

你现在可以在 Google Colab 上运行你的代码了。这就是你在云上度过大部分时间的方式。

如何使用 GPU 进行模型训练

  1. 您可以通过将鼠标悬停在图标上来查看 RAM 和磁盘的使用情况,如下所示。

(图片由作者提供)

2.转到运行时选项

(图片由作者提供)

3.当您要训练模型时,请选择 GPU 作为选项

(图片由作者提供)

4.然后,运行所有细胞

(图片由作者提供)

好了,你现在是 Google Colab 的中级用户了。

[## Jupyter 笔记本崩溃了,所以我在 15 分钟内就把我的数据科学项目部署到了云中(对于…

你可以用一个很老很老的系统免费进行奇特的数据科学研究——只要动动脑筋,从这个博客中获得帮助。

medium.com](https://medium.com/datadriveninvestor/jupyter-notebook-crashed-so-i-deployed-my-data-science-project-in-the-cloud-in-15-minutes-for-56edc0ac4d0d)

奖金

黑暗模式!

进入设置->网站,选择黑暗。

(图片由作者)

在上面编码感觉更舒服

黑暗模式(图片来自作者

使用这些新发现的知识开始学*数据科学。请随意通过 mu Github 获取一些灵感。或者进入 Kaggle 开始。

[## anishmahapatra01 —概述

每天尝试新事物—专业数据科学家追求数据硕士…

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

neptune.ai 我偶然发现的一个很棒的附加资源,可以帮助你进一步了解如何在 Google Colab 中处理文件。

[## 如何在 Google Colab 中处理文件:你需要知道的一切- neptune.ai

谷歌合作实验室是一个免费的 Jupyter 笔记本环境,运行在谷歌的云服务器上,让用户…

海王星. ai](https://neptune.ai/blog/google-colab-dealing-with-files)

干得好!所以,关于我的一点点。我是一家顶级数据科学公司的数据科学家,目前正在攻读数据科学硕士学位。我花很多时间学*和工作。如果你喜欢这个,给我点爱!😄我也写关于千禧一代的生活方式咨询聊天机器人金融!如果您对此有任何问题或建议,请随时通过 LinkedIn联系我或关注我这里,我很想听听您的想法!

[## Anish Mahapatra —数据科学家— Mu 适马公司| LinkedIn

我正在努力理解数学、商业和技术如何帮助我们在未来做出更好的决策…

www.linkedin.com](https://www.linkedin.com/in/anishmahapatra/)

作为本系列后续步骤的一部分,我将发布更多关于我们如何在现实世界中利用云的用例。欢迎关注我并与我联系了解更多信息!

[## Anish Mahapatra —中等

阅读 Anish Mahapatra 在媒体上的文章。专业数据科学家攻读数据科学硕士学位。在…工作

medium.com](https://medium.com/@anishmahapatra)

如何在 pandas 中使用 groupby()和聚合函数进行快速数据分析

原文:https://towardsdatascience.com/how-to-use-groupby-and-aggregate-functions-in-pandas-for-quick-data-analysis-c19e7ea76367?source=collection_archive---------22-----------------------

初学者指南使用这个强大的组合在熊猫

图片来自 Pixabay

简介

当您开始学* pandas 中的数据分析时,您应该学*的第一个函数是如何使用 groupby()函数以及如何将其结果与聚合函数相结合。这相对来说比较简单,可以让你快速地做一些强大而有效的分析。

在本文中,我们将解释:

什么是 groupby()函数,它是如何工作的?

什么是聚合函数,它们是如何工作的?

如何一起使用 groupby 和 aggregate 函数

在本文结束时,您应该能够应用这些知识来分析您选择的数据集。

让我们开始吧。我们将在这里使用虹膜数据集,所以让我们开始加载它在熊猫。

加载虹膜数据集

您可以使用下面的代码加载 iris 数据集并检查它的前几行:

from sklearn import datasets
import pandas as pddata = datasets.load_iris()
df = pd.DataFrame(data.data,columns=data.feature_names)
df['target'] = pd.Series(data.target)
df.head()

通过目测数据集,您可以看到我们拥有的唯一分类变量是目标。您可以使用 unique()函数来检查它取什么值:

df.target.unique()
array([0, 1, 2])

我们可以看到它有三个值:0、1 和 2。

使用 groupby()

既然您已经检查了目标列是分类的以及它取什么值,那么您可以尝试使用 groupby()函数。顾名思义,它应该将你的数据分组。在这种情况下,它将把它分成代表不同花卉种类的三组(我们的目标值)。

df.groupby(df.target)<pandas.core.groupby.generic.DataFrameGroupBy object at 0x1150a5150>

如您所见,groupby()函数返回一个 DataFrameGroupBy 对象。乍一看不是很有用。这就是你需要集合函数的原因。

什么是聚合函数?

聚合函数是接受一系列条目并返回一个以某种方式汇总它们的值的函数。

好的例子有:

count(),

max(),

min(),

均值(),

std(),

描述()

正如我提到的,你可以在一系列的条目中使用它们。让我们将它应用于数据集的其中一列:

df['sepal length (cm)'].mean()5.843333333333334

我们可以看到萼片长度列的平均值是 5.84。

现在让我们使用 describe()函数,它将给出更多的汇总统计数据。

df['sepal length (cm)'].describe()count    150.000000
mean       5.843333
std        0.828066
min        4.300000
25%        5.100000
50%        5.800000
75%        6.400000
max        7.900000
Name: sepal length (cm), dtype: float64

您可以看到,它给出了与前一个函数相同的平均值和一些附加信息:计数、最小值、最大值、标准值和四分位数范围。

同时使用 groupby()和聚合函数

现在是时候把你学到的东西结合在一起了。好消息是,您可以在 groupby 对象上调用聚合函数,这样您将获得每个组的结果。

让我们用 iris 数据集再次证明这一点:

df.groupby(df.target).mean()

如你所见,我们的索引列没有给出组名(在我们的例子中是 0、1 和 2)以及每列和每组的平均值。

你可以看到,第 0 组的平均花瓣长度(1.46 厘米)比其他两组的平均花瓣长度(1 (4.26 厘米)和 2(5.52 厘米)小得多。看起来这可能是被分析的花卉之间的一个重要差异。

您还可以对 group by 对象使用 describe()来获取我们组的所有描述性统计信息:

df.groupby(df.target).describe()

如您所见,该表为您提供了所有组和所有列的描述性统计数据。如果很难读懂,你也可以一次只看一栏:

df.groupby(df.target)['sepal length (cm)'].describe()

正如您在这些例子中看到的,将 groupby 和 aggregate 函数一起使用非常简单明了。

规则是首先使用 groupby 函数创建 groupby 对象,然后调用聚合函数计算每个组的信息。

总结

在本文中,您了解了 groupby 函数,以及如何在 pandas 中将它与聚合函数结合使用。

我希望你能够应用你所学的知识,对你选择的数据集进行快速分析。

原载于 aboutdatablog.com: 如何在 pandas 中使用 groupby()和 aggregate 函数进行快速数据分析2020 年 5 月 6 日。

PS:我正在 Medium 和aboutdatablog.com上写文章,深入浅出地解释基本的数据科学概念。你可以订阅我的 邮件列表 在我每次写新文章的时候得到通知。如果你还不是中等会员,你可以在这里加入

下面还有一些你可能喜欢的帖子

* [## 对熊猫中的数据框进行排序

如何快速有效地排序数据帧

towardsdatascience.com](/sorting-data-frames-in-pandas-a5a3af6f346a) [## 当你开始与图书馆合作时,7 个实用的熊猫提示

解释一些乍一看不那么明显的东西…

towardsdatascience.com](/7-practical-pandas-tips-when-you-start-working-with-the-library-e4a9205eb443) [## Jupyter 笔记本自动完成

数据科学家的最佳生产力工具,如果您还没有使用它,您应该使用它…

towardsdatascience.com](/jupyter-notebook-autocompletion-f291008c66c)*

如何将本地存储与 AWS 前哨一起用于人工智能工作负载

原文:https://towardsdatascience.com/how-to-use-high-performance-local-storage-for-ai-workloads-on-aws-outposts-3203b2853cc4?source=collection_archive---------42-----------------------

一起更好:内部云计算+共享数据

米歇尔在 Unsplash 上的照片

从无人驾驶汽车和金融交易到交通系统,许多用例需要*实时和本地处理数据的能力。事情正在发生,我们需要尽快做出决定。没有时间将所有数据传输回公共云。

因此,许多组织选择将其公共云项目扩展到私有的本地位置,构建混合云解决方案。

AWS 前哨是采用云优先计划的组织满足本地数据处理或低延迟要求的方式之一。借助前哨机架,您可以在数据中心部署 AWS 计算硬件。

这篇文章介绍了混合云人工智能工作流,并描述了如何将本地存储与 AWS 前哨配对。在本文中,我使用 Pure Storage FlashBlade 作为示例存储服务器,因为它支持来自同一设备的文件和对象存储。

人工智能部署的混合云模型

随着数据科学团队将其模型投入生产,他们必须支持更大规模的数据接收和数据处理,作为推理的一部分。

通常,将大型数据集转移到公共云中的性能损失(或成本)令人望而却步。或者,从边缘到公共云的连接可能不可靠。由于这些限制,拥有大量数据摄取的团队正在将人工智能推理从公共云迁移到边缘数据中心。

注意:在这种情况下,我们使用“边缘”来表示分布式计算模型,其中服务交付在多个边缘站点执行,例如主机托管设施。

团队可以在公共云中集中模型开发,然后将最终模型部署到边缘数据中心进行推理。团队可以在边缘执行初始分析,以识别异常或有趣的数据点,并将其发送回公共云进行进一步分析或重新培训。

混合云部署示例。(图片由作者提供)

例如,一家自动驾驶汽车公司可能有一个车队,每天每辆车都会产生 2TB 的数据日志。然而,他们的计算机视觉训练数据集可能没有足够的特定路标变体样本(汽车可能会遇到的其他东西)。因此,该公司的数据科学家可能会在边缘位置执行推理,以提取具有这些高价值异常的数据点,然后将这些数据点输入到模型再训练中。

完整的数据集被摄取到本地服务器中,AWS 前哨——甚至可能是一个 GPU 前哨配置——可以用作推理的边缘计算。

从前哨 EC2 实例访问本地服务器上的数据

亚马逊的高级解决方案架构师 Josh Coen 写了一篇很棒的文章,强调了前哨站和相邻存储设备之间联网路径的简单性。

建立连接后,很容易开始使用这些外部数据集。在这一节中,我将演示前哨站中的 EC2 实例如何与本地文件和对象数据进行交互。

先决条件

  • 前哨站配置:在前哨站中启动一个 EC2 实例(通过 AWS 前哨站控制台)。验证该实例可以 ping 通本地网络上的设备。
  • FlashBlade 配置:为文件测试创建一个子网、一个数据 VIP 和一个文件系统。为对象测试创建一个对象存储用户和一个存储桶。

连接到文件存储器

使用 data vip 将文件系统挂载到实例内部的一个目录中。示例:

mkdir -p /mnt/datasets
mount -t nfs 10.21.239.11:/datasets /mnt/datasets

就是这样!

通过ls确认 EC2 实例中挂载的文件系统的内容是否如预期的那样出现。

注意:为了通过每个挂载点的多个 TCP 连接提高性能,请使用 nconnect 挂载选项。了解更多: 使用 nconnect 轻松提升 NFS 性能

连接到对象存储器

与区域内实例的流程一样,具有 S3 访问权限的 IAM 角色必须与实例关联,用户才能访问 S3。(更多信息,请参考 AWS 命令行界面用户指南。)

使用aws configure命令为 FlashBlade 对象存储用户添加访问密钥 ID秘密访问密钥

就是这样!

使用aws s3 ls命令验证 EC2 实例可以访问 FlashBlade 上的存储桶。因为系统使用自定义端点而不是默认的 AWS S3,所以使用之前在 FlashBlade 上创建的数据 VIP 指定一个--endpoint-url

aws --endpoint-url http://10.21.239.11 s3 ls

此时,Outpost EC2 实例已准备好使用存储在 FlashBlade 上的文件和对象数据。

访问前哨站内 EMR 集群的本地数据集

通常,仅从边缘的原始数据直接进行推断是不够的。组织经常选择在运行推理之前对数据进行预处理或操作。你可以使用像 AWS EMR 这样的服务在哨站内部执行预处理步骤。

内部推理管道示例。支持文件和对象协议工作负载。(图片由作者提供)

为了简化基础架构,组织可以在整个边缘分析管道中使用相同的共享存储。

部署

一旦运行了集群实例,集群工作负载就可以很容易地访问本地存储服务器上的数据。

关于启动集群的说明,请参见我的帖子:在 AWS 前哨站上创建 Amazon EMR 集群

要从该群集访问 FlashBlade S3 上的对象,请提交包含 FlashBlade 端点和凭据的作业。示例:

spark-submit --conf spark.hadoop.fs.s3a.endpoint=http://10.21.239.11 \
             --conf "spark.hadoop.fs.s3a.access.key=####" \
             --conf "spark.hadoop.fs.s3a.secret.key=####" \
             --master yarn \
             --deploy-mode cluster \
             wordcount.py \
             s3a://emily-outpost-bucket/sample.txt

或者,在 spark-defaults.conf 文件中记录 FlashBlade 规格,以便在默认情况下自动使用它们。

vi /etc/spark/conf.dist/spark-defaults.conf

将以下几行添加到文件的底部:

spark.hadoop.fs.s3a.endpoint 10.21.239.11  # YOUR DATA VIP
spark.hadoop.fs.s3a.access.key=####
spark.hadoop.fs.s3a.secret.key=##### Suggested tuning for FlashBlade performance 
performance.spark.hadoop.fs.s3a.fast.upload true
spark.hadoop.fs.s3a.connection.ssl.enabled false
spark.hadoop.mapreduce.fileoutputcommitter.algorithm.version 2
spark.hadoop.mapreduce.input.fileinputformat.split.minsize 541073408

现在,您可以提交作业,而无需在线指定 FlashBlade 规格:

spark-submit --master yarn \
             --deploy-mode cluster \
             wordcount.py \
             s3a://emily-outpost-bucket/sample.txt

外卖食品

混合云部署变得越来越普遍,尤其是为了支持边缘分析。使用 FlashBlade 作为示例存储服务器,我们演示了通过 AWS outbound EC2 实例使用本地文件和对象存储的快速步骤。这使得数据科学家能够部署边缘推理管道,这些管道可以使用大型数据集并在本地执行分析。

使用带有前哨的高性能本地存储有助于消除向公共云发送分析查询的延迟,并有助于防止将所有边缘数据推送到公共云所带来的传输时间(甚至可能有助于遵守数据治理要求)。通过将易于管理的计算和存储基础架构配对,混合云部署变得更加容易。

有关导航前哨的信息,另请参见:

[## 在 AWS 前哨上启动 EC2 实例

视觉向导

medium.com](https://medium.com/@emwatz/launch-ec2-instances-on-aws-outposts-fc4a0e12bd27) [## 在 AWS 前哨站上创建 Amazon EMR 集群

视觉向导

medium.com](https://medium.com/@emwatz/create-amazon-emr-clusters-on-aws-outposts-bec702ec3bae)

如何在 Google Colab 中使用 Kaggle 数据集

原文:https://towardsdatascience.com/how-to-use-kaggle-datasets-in-google-colab-bca5e452a676?source=collection_archive---------27-----------------------

使用 kaggle API 将数据集直接下载到 colab。

照片由尼克·费因斯Unsplash 拍摄

Kaggle 是数据科学领域非常受欢迎的平台。它的名气来自比赛,但也有许多数据集,我们可以在实践中工作。在这篇文章中,我们将看到如何将数据集从 Kaggle 直接导入到 google colab 笔记本中。

我们首先转到 Kaggle 上的帐户页面来生成一个 API 令牌。在帐户页面上,我们向下滚动到 API 部分。

如果有以前生成的 API 令牌,我们应该通过单击“使 API 令牌过期”来使其过期。如果没有,我们可以单击“创建新的 API 令牌”直接生成令牌。点击后,会下载一个名为 kaggle.json 的文件。

然后,我们在 colab 中打开一个新的笔记本,并运行以下命令。

!pip install -q kaggle

然后我们需要上传 kaggle.json 文件。

from google.colab import filesfiles.upload()

选择从 kaggle 下载的“kaggle.json”。我们需要将这个文件保存到一个名为 kaggle 的目录中。运行以下命令来完成此任务:

!mkdir ~/.kaggle!cp kaggle.json ~/.kaggle/

我们现在使用以下命令更改文件的权限:

!chmod 600 ~/.kaggle/kaggle.json

我们现在可以在 kaggle 上看到数据集:

!kaggle datasets list

要下载特定的一个:

!kaggle datasets download -d "name_of_the_dataset"

例如:

!kaggle datasets download -d ruchi798/tv-shows-on-netflix-prime-video-hulu-and-disney

我们现在在 colab 中有可用的数据:

让我们把它读入熊猫的数据帧:

import numpy as np
import pandas as pddf = pd.read_csv("/content/tv-shows-on-netflix-prime-video-hulu-and-disney.zip")df.head()

我们不必每次都经历所有这些步骤。一旦完成这些步骤,下次我们只需将 kaggle.json 上传到 colab,然后下载数据集。

!kaggle datasets download -d kianwee/agricultural-raw-material-prices-19902020

我们总是可以用!kaggle datasets list来检查可用的数据集

我认为 kaggle 和 google colab 是数据科学领域的两个主要参与者。两者都对社区做出了贡献,从而推动了数据科学的发展。在两者之间建立联系是件好事。

感谢您的阅读。如果您有任何反馈,请告诉我。

如何使用 Lambda 获得高效的 Python 代码

原文:https://towardsdatascience.com/how-to-use-lambda-for-efficient-python-code-ff950dc8d259?source=collection_archive---------13-----------------------

使用 lambda 对元组进行排序并为您的数据科学创意创建复杂函数的技巧

检索自 Gideon Pyzer

动机

这张图让你想起了什么?波的振幅放大?这个怎么做?你仔细看看图表,发现了一些有趣的事情。看起来像是随着 x 的增加,y 轴上的值先下降到-1,然后上升到 1,再下降到-2,然后上升到 2,依此类推。这给了你一个想法,图表可以用这样的列表来制作

[0, -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7, -8, 8, -9, 9]

如果您将上述列表中的matplotlib用作参数,您应该得到与上图接*的图形:

这看起来很容易。一旦您理解了如何使用列表创建图形,您就可以轻松地重新创建波形图。但是如果你想创建一个更酷的图表,需要一个更大的列表,像这样呢?

你肯定不想手动写上面的单子,单子上有 200 个数字。因此,您必须弄清楚如何使用 Python 来创建编号范围为(n,m)的列表

但是从 0 开始,按-1,1,-2,2,…n 进行。

如果我们认识到按元素|0|、|-1|、|1|、|-2|、|2|的绝对值排序的列表,..,n .所以有排序和绝对值的东西会起作用?答对了。我将向你展示如何用lambda在一行代码中轻松创建这种功能。

顺便问一下,Lambda 是什么?

嘿,很高兴你这么问。Python 中的lambda关键字提供了声明小型匿名函数的快捷方式。它的行为就像常规函数一样。它们可以作为函数对象的替代。让我们举一个如何用 lambdas 代替 function 的小例子:

def mult(x,y):
  return x*ymult(2,6)

结果:12

我们可以用lambda让上面的代码更短

mult = lambda x, y: x*y
mult(2,6)

但是我们需要定义乘法的名称吗?毕竟,我们只是想创建一个可以将两个数相乘的函数,对吗?我们可以将上面的函数简化为更简单的代码:

(lambda x, y: x*y)(2, 6)

那看起来更短。但是为什么你要费心去学*lambda,只是为了节省几行代码呢?因为lambda可以帮助你轻松创造更复杂的东西。比如根据字母表对元组列表进行排序:

tuples = [(1, 'd'), (2, 'b'), (4, 'a'), (3, 'c')]sorted(tuples, key=lambda x: x[1])

结果:

[(4, 'a'), (2, 'b'), (3, 'c'), (1, 'd')]

这给了你一个如何使用lambda创建上面的图表的提示。准备好了吗?这是:

import matplotlib.pyplot as pltnums = plt.plot(sorted(range(-100, 101), key=lambda x: x * x))plt.plot(nums)

给我们图表:

何时使用lambda的其他启示:

想创建一个函数来计算一个数的另一个数的幂吗?我们可以使用嵌套函数和lambda的组合:

def power(n):
  return lambda x: x**npower_3 = power(3)list(map(power_3,[2,3,4,5]))

结果:

[8, 27, 64, 125]

或者使用lambda来操作pandas数据帧

import pandas as pd
df = pd.DataFrame([[1,2,3],[4,5,6]], columns=['a','b','c'])

#Create the 4th column that is the sum of the other 3 columnsdf['d'] = df.apply(lambda row: row['a']+row['b']+row['c'],axis=1)

结论

恭喜你!现在你知道如何使用lambda作为函数的快捷方式。当你想在短时间内创建一个无名函数时,我鼓励你使用lambda。你也可以像上面一样把它作为一个高阶函数的参数,或者和像filter()map()apply()这样的函数一起使用。

我希望这篇教程能给你一些动机和理由来用lambda切换你的一些 Python 代码。随着您越来越多地为您的数据科学项目引入更复杂的代码,代码中的一个小变化可以在时间和效率上给您带来巨大的回报。

这个 Github repo 中,您可以随意派生和使用本文的代码。

我喜欢写一些基本的数据科学概念,并尝试不同的算法和数据科学工具。你可以在 LinkedIn 和 Twitter 上与我联系。

如果你想查看我写的所有文章的代码,请点击这里。在 Medium 上关注我,了解我的最新数据科学文章,例如:

[## 高效 Python 代码的计时

如何比较列表、集合和其他方法的性能

towardsdatascience.com](/timing-the-performance-to-choose-the-right-python-object-for-your-data-science-project-670db6f11b8e) [## 使用 Python 最大化您的生产力

你创建了一个待办事项清单来提高效率,但最终却把时间浪费在了不重要的任务上。如果你能创造…

towardsdatascience.com](/maximize-your-productivity-with-python-6110004b45f7) [## cy thon——Python 函数的加速工具

当调整你的算法得到小的改进时,你可能想用 Cython 获得额外的速度,一个…

towardsdatascience.com](/cython-a-speed-up-tool-for-your-python-function-9bab64364bfd) [## 如何从头开始构建矩阵模块

如果您一直在为矩阵运算导入 Numpy,但不知道该模块是如何构建的,本文将展示…

towardsdatascience.com](/how-to-build-a-matrix-module-from-scratch-a4f35ec28b56)

如何将机器学*用于药物发现

原文:https://towardsdatascience.com/how-to-use-machine-learning-for-drug-discovery-1ccb5fdf81ad?source=collection_archive---------15-----------------------

wowomnomEnvato 元素上定制一个图形(带许可证)

数据科学

一步一步的实用生物信息学教程

1.介绍

我们可能已经看到机器学*以这样或那样的形式应用。例如,机器学*已经与计算机视觉一起用于自动驾驶汽车和自助结账便利店,用于零售市场购物篮分析(即找到通常一起购买的产品),用于推荐系统的娱乐,等等。

这代表了 生物信息学教程 系列的第一篇文章(感谢 Jaemin Lee 关于将我的文章发展成系列的建议!).在本文中,我将探索机器学*如何用于药物发现,特别是通过一步一步地向您展示如何在 Python 中建立一个简单的回归模型来预测分子的溶解度(对数值)。需要注意的是,药物的溶解度是药物发现、设计和开发中一个重要的理化性质。在此,我们将转载一篇名为“ESOL:从分子结构直接估算水溶性” 的研究文章,作者是 John S. Delaney。

这款笔记本的灵感来自 Pat Walters 在 【预测水溶性——比看起来更难】 上的精彩博文,他在博文中重现了线性回归模型,其性能与 Delaney 的相似。这个例子在 Walters 合著的书生命科学的深度学*:将深度学*应用于基因组学、显微镜学、药物发现等】中也有简要描述。

YouTube 视频 “使用 Python 进行计算药物发现的数据科学” 中提供了展示本文所述实施的教程视频:

目录

1.introduction
2。材料
2.1Computing environmen t
2.2 Installing prerequisite Python librar y
2.3。 Datase t
3方法
3.1 Datase t
3.1.1 读取数据集
3.1.2。Examining the SMILES data
3.2。 Working with SMILES strin g
3.2.1。convertit a molecule from the SMILES string to an rdkit object
3.2.2。Working with the rdkit object
3.2.3。Convert list of molecules to rdkit object
3.3 转换分子列表到 rdkit 对象。计算分子描述符s
3.3.1。Calculating LogP, MW and RB descriptors
3.3.2。计算芳香比例(T33) 3.3.2.1。芳香原子数(T34)3.3.2.2。重原子数(T35)3.3.2.3 计算芳香比例(AP)描述符
3.4。数据集准备
3.4.1Creating the X Matrix
3.4.2。首页 〉外文书 〉文学 〉西洋文学 〉Creating the Y Matrix (T41) 3.5数据分割
3.6 线性回归模型(T46)(T47) 结果
4.1(T51)线性回归模型(T52)(T53) 4.1.1 预测 X_train 数据的 LogS 值
4.1.2。预测 X_test 数据的 LogS 值
4.2。(T56) 比较线性回归方程(T57) Deriving the Linear Regression Equatio n
4.3.1 基于列车集
4.3.2。基于完整数据集(用于比较)(T63) 4.4。 Scatter plot of experimental vs. predicted Log S
4.4.1。Vertical Plot
4.4.2。横向 Plot

2.材料

从学术背景来看,检索关于如何进行实验的信息的研究论文的最重要部分之一必须是材料和方法部分,因为它将基本上告诉我们需要什么材料以及做了什么和如何做。因此,在这一部分,我将讨论您需要开始做些什么。

2.1.计算环境

首先,决定你是想在本地计算机上工作还是在云上工作。如果你决定在本地计算机上工作,那么任何可以安装 Python 和 Jupyter notebook 的计算机(我推荐安装 condaAnaconda )就足够了。如果你决定在云上工作,那就去谷歌实验室吧。

2.2.安装必备 Python 库

rdkit 库是一个 Python 库,它允许我们处理化学结构和计算它们的分子属性(用于量化每个分子的分子特征,我们可以随后在机器学*模型的开发中使用)。

我们现在将安装 rdkit 库,启动一个新笔记本,并确保创建一个包含以下文本的文本单元格:

**# Install rdkit**

在这个文本单元格的正下方,您想要创建一个新的代码单元格,并用以下代码块填充它:

**! wget https://repo.anaconda.com/miniconda/Miniconda3-py37_4.8.2-Linux-x86_64.sh 
! chmod +x Miniconda3-py37_4.8.2-Linux-x86_64.sh 
! bash ./Miniconda3-py37_4.8.2-Linux-x86_64.sh -b -f -p /usr/local 
! conda install -c rdkit rdkit -y 
import sys 
sys.path.append('/usr/local/lib/python3.7/site-packages/')**

上面的 2 个单元格应该看起来像下面的截图:

以上 2 个单元格(文本和代码单元格)的渲染。

2.3.数据集

我们现在将下载 Delaney 溶解度数据集,该数据集作为论文 ESOL:直接从分子结构中的补充文件提供。

下载数据集
下载到 Jupyter 笔记本如下:

**! wget https://raw.githubusercontent.com/dataprofessor/data/master/delaney.csv**

3.方法

3.1.资料组

3.1.1。读入数据集
读入我们从上述单元格下载的 CSV 数据。将数据分配到sol数据框中。

**import pandas as pd
sol = pd.read_csv('delaney.csv')**

显示sol数据帧给我们提供了以下信息:

sol 数据框的内容。

3.1.2。检验 SMILES 数据
化学结构由一串称为 SMILES 符号的文本编码,这是简化分子输入行输入系统的首字母缩写。让我们看看sol数据帧中微笑列的内容。

**sol.SMILES**

运行上面的单元将为我们提供:

溶胶含量。SMILES(sol 数据框架中的 SMILES 列)。

每条线代表一种独特的分子。要选择第一个分子(第一行),键入sol.SMILES[0],我们将看到的输出是ClCC(Cl)(Cl)Cl

3.2.使用微笑字符串

3 . 2 . 1。将一个分子从 SMILES 字符串转换成一个 rdkit 对象
让我们从导入必要的库函数开始:

**from rdkit import Chem**

现在,应用MolFromSmiles()函数将 SMILES 字符串转换为 rdkit 分子对象:

**Chem.MolFromSmiles(sol.SMILES[0])**

这将产生以下输出:

<rdkit.Chem.rdchem.Mol at 0x7f66f2e3e800>

3.2.2。使用 rdkit 对象
让我们对查询 SMILES 字符串执行一个简单的原子计数,我们首先将它转换成一个 rdkit 对象,然后应用GetNumAtoms()函数。

**m = Chem.MolFromSmiles('ClCC(Cl)(Cl)Cl')
m.GetNumAtoms()**

这会产生以下输出:

6

3 . 2 . 3。将分子列表转换为 rdkit 对象 但是在我们进行任何描述符计算之前,我们必须先将 SMILES 字符串转换为 rdkit 对象,如 3.2 节所述。这里我们将做和上面描述的一样的事情,但是我们将利用 for 循环来遍历微笑字符串列表。

**from rdkit import Chem****mol_list= []
for element in sol.SMILES:
  mol = Chem.MolFromSmiles(element)
  mol_list.append(mol)**

接下来,我们将检查新的 rdkit 对象是否正在填充 mol_list 变量。

**len(mol_list)**

上面的行返回:

1144

这相当于 1144 个分子。现在,我们将看看变量的内容。

**mol_list[:5]**

这会产生以下输出:

[<rdkit.Chem.rdchem.Mol at 0x7f66edb6d670>,
 <rdkit.Chem.rdchem.Mol at 0x7f66edb6d620>,
 <rdkit.Chem.rdchem.Mol at 0x7f66edb6d530>,
 <rdkit.Chem.rdchem.Mol at 0x7f66edb6d6c0>,
 <rdkit.Chem.rdchem.Mol at 0x7f66edb6d710>]

3.3.计算分子描述符

我们现在将通过一组用于建模的分子描述符来表示数据集中的每个分子。

为了预测对数(水溶性对数),Delaney 的研究使用了 4 个分子描述符:

  1. cLogP (辛醇-水分配系数)
  2. MW (分子量)
  3. RB(可旋转债券数量)
  4. AP (芳香比例=芳香原子数/重原子数)

不幸的是,rdkit 很容易计算前 3 个。至于 AP 描述符,我们将通过手动计算 rdkit 可以计算的芳香原子数与重原子数的比率来计算。

3 . 3 . 1。计算 LogP、MW 和 RB 描述符 我们现在将创建一个名为generate()的自定义函数,用于计算 3 个描述符 LogP、MW 和 RB。

**import numpy as np
from rdkit.Chem import Descriptors*****# Inspired by: https://codeocean.com/explore/capsules?query=tag:data-curation*

def generate(smiles, verbose=False):

    moldata= []
    for elem in smiles:
        mol=Chem.MolFromSmiles(elem) 
        moldata.append(mol)

    baseData= np.arange(1,1)
    i=0  
    for mol in moldata:        

        desc_MolLogP = Descriptors.MolLogP(mol)
        desc_MolWt = Descriptors.MolWt(mol)
        desc_NumRotatableBonds = Descriptors.NumRotatableBonds(mol)

        row = np.array([desc_MolLogP,
                        desc_MolWt,
                        desc_NumRotatableBonds])   

        if(i==0):
            baseData=row
        else:
            baseData=np.vstack([baseData, row])
        i=i+1      

    columnNames=["MolLogP","MolWt","NumRotatableBonds"]   
    descriptors = pd.DataFrame(data=baseData,columns=columnNames)

    return descriptors**

让我们应用generate()函数对sol.SMILES(来自df数据帧的微笑列)执行实际的描述符计算,并将描述符输出分配给df变量。

df = generate(sol.SMILES)
df

df数据帧的输出如下所示。

测向数据帧的内容。

3 . 3 . 2。计算芳香比例 如上所述,计算芳香比例的方程式是用芳香原子数除以重原子数得到的。

3.3.2.1。芳香原子数
这里我们将创建一个自定义函数来计算芳香原子数。有了这个描述符,我们可以用它来计算 AP 描述符。

计算单个分子中芳香原子数的例子。

**SMILES = 'COc1cccc2cc(C(=O)NCCCCN3CCN(c4cccc5nccnc54)CC3)oc21'****m = Chem.MolFromSmiles(SMILES)****aromatic_atoms = [m.GetAtomWithIdx(i).GetIsAromatic() for i in range(m.GetNumAtoms())]****aromatic_atoms**

这给出了以下输出。

[False,  False,  True,  True,  True,  True,  True,  True,  True,  False,  False,  False,  False,  False,  False,  False,  False,  False,  False,  False,  True,  True,  True,  True,  True,  True,  True,  True,  True,  True,  False,  False,  True,  True]

现在让我们创建一个名为AromaticAtoms()的自定义函数。

**def AromaticAtoms(m):
  aromatic_atoms = [m.GetAtomWithIdx(i).GetIsAromatic() for i in range(m.GetNumAtoms())]
  aa_count = []
  for i in aromatic_atoms:
    if i==True:
      aa_count.append(1)
  sum_aa_count = sum(aa_count)
  return sum_aa_count**

现在,应用AromaticAtoms()函数来计算查询 SMILES 字符串的芳香原子数。

**AromaticAtoms(m)**

输出是:

19

这意味着有 19 个芳香原子(即有 19 个原子是芳香环的一部分)。

现在让我们扩大规模,并将其应用于整个微笑列表。

**desc_AromaticAtoms = [AromaticAtoms(element) for element in mol_list]****desc_AromaticAtoms**

现在,打印出结果。

[0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 0, 6, 0, 0, 0, 0, 6, 6, 0, 6, 6, 6, 6, 6, 0, 6, 6, 0, 0, 6, 10, 6, 6, 0, 6, 6, 6, 6, 10, 6, 0, 10, 0, 14, 0, 0, 14, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, ...]

恭喜你!我们现在已经计算了整个数据集的芳香原子数。

3.3.2.2。重原子数
这里,我们将使用 rdkit 库中的一个现有函数来计算重原子数。

计算单个分子重原子数的例子。

**SMILES = 'COc1cccc2cc(C(=O)NCCCCN3CCN(c4cccc5nccnc54)CC3)oc21'
m = Chem.MolFromSmiles(SMILES)
Descriptors.HeavyAtomCount(m)**

这将产生以下输出。

34

让我们扩大到整个微笑列表。

**desc_HeavyAtomCount = [Descriptors.HeavyAtomCount(element) for element in mol_list]
desc_HeavyAtomCount**

现在,打印出结果。

[6, 5, 6, 5, 8, 4, 4, 8, 10, 10, 10, 9, 9, 10, 10, 10, 9, 9, 9, 8, 8, 4, 8, 4, 5, 8, 8, 10, 12, 4, 9, 9, 9, 15, 8, 4, 8, 8, 5, 8, 8, 12, 12, 8, 6, 8, 8, 10, 8, 12, 12, 5, 12, 6, 14, 11, 22, 15, 5, ...]

3.3.2.3。计算芳香比例(AP)描述符
现在让我们把芳香原子数和重原子数结合在一起。

计算单个分子的例子。

**SMILES = 'COc1cccc2cc(C(=O)NCCCCN3CCN(c4cccc5nccnc54)CC3)oc21'
m = Chem.MolFromSmiles(SMILES)
AromaticAtoms(m)/Descriptors.HeavyAtomCount(m)**

输出是:

0.5588235294117647

让我们放大并计算整个微笑列表。

**desc_AromaticProportion = [AromaticAtoms(element)/Descriptors.HeavyAtomCount(element) for element in mol_list]
desc_AromaticProportion**

这给出了输出:

[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.6, 0.6, 0.6, 0.6666666666666666, 0.6666666666666666, 0.6, 0.6, 0.6, 0.6666666666666666, 0.6666666666666666, 0.6666666666666666, 0.75, 0.75, 0.0, 0.75, 0.0, 0.0, 0.0, 0.0, 0.6, 0.5, 0.0, 0.6666666666666666, 0.6666666666666666, 0.6666666666666666, 0.4, 0.75, 0.0, 0.75, 0.75, 0.0, 0.0, 0.75, 0.8333333333333334, 0.5, 0.75, 0.0, 0.75, 0.75, 0.6, 0.75, 0.8333333333333334, 0.5, ...]

现在让我们把这个新计算的芳烃比例描述符放到一个数据帧中。

芳烃比例描述符数据帧的内容。

3.4.数据集准备

3.4.1。创建 X 矩阵 让我们将 2 个数据帧中的所有计算描述符合并到 1 个数据帧中。在此之前,让我们先来看看我们将要组合的两个数据帧(dfdf_desc_AromaticProportion)以及组合后的数据帧将会是什么样子,如下图所示。

组合两个包含描述符的数据帧以形成 X 矩阵的图示。

让我们实际上结合 2 个数据帧来产生 X 矩阵。

**X = pd.concat([df,df_desc_AromaticProportion], axis=1)
X**

通过组合两个数据帧创建的 X 矩阵数据帧的内容。

3 . 4 . 2。创建 Y 矩阵 Y 矩阵将从我们在本教程中要预测的 1 列中创建,这是对数值。在sol数据框中,日志值包含在measured log(solubility:mol/L)栏中。

让我们再看一下sol数据框。

sol.head()

突出显示日志列的 sol 数据框架的内容。

对应于测得溶解度值(对数)的第二列(指数为 1)将用作 Y 矩阵。因此,我们将选择第二列(在上图中以蓝色突出显示)。

Y = sol.iloc[:,1]
Y

Y 矩阵的内容(对数列)。

3.5.数据分割

我们现在将继续使用 80/20 的拆分比率来执行数据拆分(我们通过将test_size参数指定为 0.2 来完成此操作),由此初始数据集的 80%将用作训练集,而数据集的剩余 20%将用作测试集。

**from sklearn.model_selection import train_test_split****X_train, X_test, Y_train, Y_test = train_test_split(X, Y,
                                                    test_size=0.2)**

3.6.线性回归模型

由于 Delaney 的最初研究和 Walters 的调查使用线性回归进行建模,因此为了便于比较,我们也将使用线性回归。

**from sklearn import linear_model
from sklearn.metrics import mean_squared_error, r2_score****model = linear_model.LinearRegression()
model.fit(X_train, Y_train)**

在运行上面的代码块时,我们将看到下面的输出,它基本上打印出了用于模型构建的参数。

LinearRegression(copy_X=True, fit_intercept=True, n_jobs=None, normalize=False)

4.结果

4.1.线性回归模型

4.1.1。预测 X_train 数据的对数值 来自第 3.6 节的训练模型将应用于此,以预测训练集中所有样本(分子)的对数值(X_train)。

**Y_pred_train = model.predict(X_train)****print('Coefficients:', model.coef_)
print('Intercept:', model.intercept_)
print('Mean squared error (MSE): %.2f'
      % mean_squared_error(Y_train, Y_pred_train))
print('Coefficient of determination (R^2): %.2f'
      % r2_score(Y_train, Y_pred_train))**

这将生成以下预测结果。

Coefficients: [-0.7282008  -0.00691046  0.01625003 -0.35627645]
Intercept: 0.26284383753800666
Mean squared error (MSE): 0.99
Coefficient of determination (R^2): 0.77

让我们逐行分析上面的输出:

  • 在第一行,Coefficients列出了每个独立变量的回归系数值(即由 LogP、MW、RB 和 AP 组成的 4 个分子描述符)
  • 在第二行中,Intercept实际上是 X = 0 时回归线经过的 y 截距值。
  • 在第三行中,Mean squared error (MSE)用作误差测量值(越低越好)。
  • 在第四行中,Coefficient of determination (R²)是皮尔逊相关系数值的平方值,并用作线性回归模型的拟合优度的度量(越高越好)

4 . 1 . 2。预测 X_test 数据的对数值 接下来,来自 3.6 节的训练模型也将应用于此,以预测训练集中所有样本(分子)的对数值(X_train)。

我们将打印出如下预测性能:

**Y_pred_test = model.predict(X_test)****print('Coefficients:', model.coef_)
print('Intercept:', model.intercept_)
print('Mean squared error (MSE): %.2f'
      % mean_squared_error(Y_test, Y_pred_test))
print('Coefficient of determination (R^2): %.2f'
      % r2_score(Y_test, Y_pred_test))**

上述代码块产生以下预测结果。

Coefficients: [-0.7282008  -0.00691046  0.01625003 -0.35627645]
Intercept: 0.26284383753800666
Mean squared error (MSE): 1.11
Coefficient of determination (R^2): 0.75

4.2.比较线性回归方程

德莱尼的工作提供了以下线性回归方程:

LogS = 0.16 - 0.63 cLogP - 0.0062 MW + 0.066 RB - 0.74 AP

由 Pat Walters制作的复制品提供了以下内容:

LogS = 0.26 - 0.74 LogP - 0.0066 MW + 0.0034 RB - 0.42 AP

本教程的复制给出了以下等式:

  • 基于列车组(如下文第 4.3.1 节所示)
LogS =  0.26 - 0.73 LogP - 0.0069 MW 0.0163 RB - 0.36 AP
  • 基于完整的数据集(如下文第 4.3.2 节所示)
LogS =  0.26 - 0.74 LogP - 0.0066 MW + 0.0032 RB - 0.42 AP

4.3.推导线性回归方程

4 . 3 . 1。基于以下代码块中的训练集
,我们将使用第 3.6 节中构建的线性回归模型,其中训练集用于模型构建。为了便于参考,我将代码放在这里:

**from sklearn import linear_model
from sklearn.metrics import mean_squared_error, r2_score****model = linear_model.LinearRegression()
model.fit(X_train, Y_train)**

因此,我们只需直接从包含在model变量中的先前构建的模型中打印出方程(,通过调用模型变量的各个列)。

**yintercept = '%.2f' % model.intercept_
LogP = '%.2f LogP' % model.coef_[0]
MW = '%.4f MW' % model.coef_[1]
RB = '%.4f RB' % model.coef_[2]
AP = '%.2f AP' % model.coef_[3]****print('LogS = ' + 
      ' ' + 
      yintercept + 
      ' ' + 
      LogP + 
      ' ' + 
      MW + 
      ' ' + 
      RB + 
      ' ' + 
      AP)**

运行上述代码块会得到以下等式输出:

LogS =  0.26 -0.73 LogP -0.0069 MW 0.0163 RB -0.36 AP

4 . 3 . 2。基于完整的数据集(用于比较)
这里我们将使用整个数据集来训练一个线性回归模型。fit()功能允许使用 X 和 Y 数据矩阵作为输入参数来训练full ( 线性回归模型)中定义的模型。

**full = linear_model.LinearRegression()
full.fit(X, Y)**

这会产生以下输出:

LinearRegression(copy_X=True, fit_intercept=True, n_jobs=None, normalize=False)

我们现在将打印出预测性能。

**full_pred = model.predict(X)****print('Coefficients:', full.coef_)
print('Intercept:', full.intercept_)
print('Mean squared error (MSE): %.2f'
      % mean_squared_error(Y, full_pred))
print('Coefficient of determination (R^2): %.2f'
      % r2_score(Y, full_pred))**

这将生成以下输出:

Coefficients: [-0.74173609 -0.00659927  0.00320051 -0.42316387]
Intercept: 0.2565006830997185
Mean squared error (MSE): 1.01
Coefficient of determination (R^2): 0.77

最后,我们将打印出线性回归方程。

**full_yintercept = '%.2f' % full.intercept_
full_LogP = '%.2f LogP' % full.coef_[0]
full_MW = '%.4f MW' % full.coef_[1]
full_RB = '+ %.4f RB' % full.coef_[2]
full_AP = '%.2f AP' % full.coef_[3]****print('LogS = ' + 
      ' ' + 
      full_yintercept + 
      ' ' + 
      full_LogP + 
      ' ' + 
      full_MW + 
      ' ' + 
      full_RB + 
      ' ' + 
      full_AP)**

这将产生以下输出。

LogS =  0.26 -0.74 LogP -0.0066 MW + 0.0032 RB -0.42 AP

4.4.实验测井与预测测井的散点图

在开始之前,让我们快速检查一下训练集和测试集的可变维度。

这里我们正在检查列车组的尺寸。

**Y_train.shape, Y_pred_train.shape**

这会产生以下尺寸输出:

((915,), (915,))

这里我们检查测试集的维度。

**Y_test.shape, Y_pred_test.shape**

这会产生以下尺寸输出:

((229,), (229,))

4.4.1。垂直曲线图 现在让我们通过散点图来可视化实验对数值与预测对数值的相关性。我们将在两个散点图中分别显示测井曲线的实验值和预测值。在第一个版本中,我们将垂直堆叠两个散点图。

**import** **matplotlib.pyplot** **as** **plt****plt.figure(figsize=(5,11))

*# 2 row, 1 column, plot 1*
plt.subplot(2, 1, 1)
plt.scatter(x=Y_train, y=Y_pred_train, c="#7CAE00", alpha=0.3)

*# Add trendline*
*# https://stackoverflow.com/questions/26447191/how-to-add-trendline-in-python-matplotlib-dot-scatter-graphs*
z = np.polyfit(Y_train, Y_pred_train, 1)
p = np.poly1d(z)
plt.plot(Y_test,p(Y_test),"#F8766D")

plt.ylabel('Predicted LogS')

*# 2 row, 1 column, plot 2*
plt.subplot(2, 1, 2)
plt.scatter(x=Y_test, y=Y_pred_test, c="#619CFF", alpha=0.3)

z = np.polyfit(Y_test, Y_pred_test, 1)
p = np.poly1d(z)
plt.plot(Y_test,p(Y_test),"#F8766D")

plt.ylabel('Predicted LogS')
plt.xlabel('Experimental LogS')

plt.savefig('plot_vertical_logS.png')
plt.savefig('plot_vertical_logS.pdf')
plt.show()**

预测值与实验值的散点图(显示为垂直图)。

4.4.2。水平图 在第二个版本中,我们将水平放置两个散点图,如下面的代码块所示。

**import** **matplotlib.pyplot** **as** **plt****plt.figure(figsize=(11,5))

*# 1 row, 2 column, plot 1*
plt.subplot(1, 2, 1)
plt.scatter(x=Y_train, y=Y_pred_train, c="#7CAE00", alpha=0.3)

z = np.polyfit(Y_train, Y_pred_train, 1)
p = np.poly1d(z)
plt.plot(Y_test,p(Y_test),"#F8766D")

plt.ylabel('Predicted LogS')
plt.xlabel('Experimental LogS')

*# 1 row, 2 column, plot 2*
plt.subplot(1, 2, 2)
plt.scatter(x=Y_test, y=Y_pred_test, c="#619CFF", alpha=0.3)

z = np.polyfit(Y_test, Y_pred_test, 1)
p = np.poly1d(z)
plt.plot(Y_test,p(Y_test),"#F8766D")

plt.xlabel('Experimental LogS')

plt.savefig('plot_horizontal_logS.png')
plt.savefig('plot_horizontal_logS.pdf')
plt.show()**

预测值与实验值的散点图(显示为水平图)。

订阅我的邮件列表,获取我在数据科学方面的最佳更新(偶尔还有免费内容)!

关于我

我是泰国一所研究型大学的生物信息学副教授和数据挖掘和生物医学信息学负责人。在我下班后的时间里,我是一名 YouTuber(又名数据教授)制作关于数据科学的在线视频。在我做的所有教程视频中,我也在 GitHub 上分享 Jupyter 笔记本(数据教授 GitHub page )。

[## 数据教授

数据科学、机器学*、生物信息学、研究和教学是我的激情所在。数据教授 YouTube…

www.youtube.com](https://www.youtube.com/dataprofessor?sub_confirmation=1)

在社交网络上与我联系

✅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 gram:https://www.instagram.com/data.professor/【t19

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

如何利用机器学*在 Reddit 上做预测:多元逻辑回归

原文:https://towardsdatascience.com/how-to-use-machine-learning-to-make-predictions-on-reddit-part-i-44cd210ec427?source=collection_archive---------22-----------------------

这是来自四个不同市场的四个屏幕截图。共同的元素?卖家评分。

评级来自 Amazon.com,Google.com,Facebook.com 和 Ebay.com

卖家评级是每个好市场的要求。评级系统是帮助买家做出决策的重要工具,允许他们分享自己的感受,最重要的是,向他们保证交易的合法性。当然,永远不可能保证交易安全,但良好的卖家评级确实能激发信心。

考虑到评级系统的重要性,每个市场都有一个内置的交易促进系统来对卖家进行评级。但是那些不是用来买卖的平台呢?比如: Reddit

Reddit:论坛变成市场

Reddit.com 是美国访问量排名第六的网站,它是一个论坛集合,人们在这里发布和评论链接、图片和讨论话题。Reddit 中的各个论坛或社区被称为子编辑,有超过 100 万个这样的子编辑。Reddit 的成员被称为“Redditors”,他们将内容提交给子编辑,其他成员可以“投赞成票”或“投反对票”。正如你所想象的,Reddit(它的名字是对“阅读”这个词的一个游戏)本来是一个讨论的地方,尽管它在很大程度上仍然是,一些社区已经变成了市场。还有很多这样的例子。

这里列出了 Reddit 上一些受欢迎的市场,以及在撰写本文时订阅每个市场的会员数量。

仅仅 8 个社区就有将* 65 万人!

我相信 Reddit 上的市场很受欢迎,因为 Reddit 的社区意识通常会带来合理的价格和成功的交易。然而,由于 Reddit 最初不是为此目的而设计的,与易贝等传统市场相比,它的界面存在许多问题。

例如,下面是一个典型的用户帖子:

Reddit.com 的纱帽

邮报是提供一个 BNIB 海盗船 SF750 白金 PSU(电源设备)为 150 美元以上的航运。但是,没有度量标准来确定该用户在该子编辑中是否有任何事务历史,也没有任何方法来确定该用户是否合法。此外,在这篇文章中,作者写了原始价格,但在其他情况下,潜在的买家需要自己研究产品,以确定其原始零售价格。

使用机器学*解决 Reddit 的“无评级”问题

看着 Reddit 市场的工作方式,我构建了一个算法来帮助解决缺乏专用评级系统带来的问题。

我认为这将是一个应用机器学*和 Python 自动化的有趣问题。这个项目的目标是看看我是否能收集到足够的数据,以确定与任何给定的 Reddit 用户进行交易的风险有多大。为了收集这些数据,我查看了参与成功交易的 Reddit 用户,然后确定了被发现实施欺诈的用户。本质上,我比较了两组 Redditors:骗子和非骗子。我比较的一些属性是:

●账户的年龄

●因果报应(票数上升)

●经过验证的电子邮件地址

●黄金(如果是付费账户)

●评论(使用自然语言处理进行分析)

●版主(任何子编辑)

●访问的子街道

●奖杯

Reddit.com 的纱帽

通过观察这两个组的用户活动,我试图确定某个账户是高风险还是低风险。

为了使项目的范围易于管理,我将重点放在了子编辑r/硬件交换上。HardwareSwap 是一个由超过 170,000 名成员组成的社区,他们相互交换与计算机相关的硬件。在这个 Subreddit 中,你可以找到从显卡和 CPU 到 PlayStations 和计算机外设的所有东西。

探索性数据分析

当处理我正在调查的关于 Reddit 用户和市场的问题时,第一步是做一个探索性数据分析。在此分析中,我将使用或研究:

● PRAW (Python Reddit API 包装器)

●交易

●参与交易的用户

●交易方向(买与卖)

●交易的估计价格

PRAW (Python Reddit API 包装器)

为了访问 r/hardware WAP 数据,我注册了一个 Reddit API 密匙。你可以在这里找到 PRAW 的快速入门指南和其他文档。首先,我需要在 Reddit、上注册一个应用程序,然后我收到一个 Reddit 客户端 ID 和客户端密码。

Reddit 应用程序注册表单的屏幕截图。Reddit.com 的纱帽

收集用于探索性数据分析(EDA)的硬件应用程序数据

现在我有了我的 Reddit API 密钥,我可以开始收集我需要的数据:交易的细节、用户、方向和估计的交易价格。因为我这个项目的主要目标是比较两组 redditor——合法用户和骗子(以及如何识别他们?)—我将从收集这些群体的数据开始。

交易

subreddit r/HardwareSwap 有一个确认线程,用户每个月都会在这个线程中确认他们成功的交易。这使得为 Reddit 用户收集交易细节成为可能。

下面是【2019 年 12 月确认线程的截图,让你对其格式有个概念:

示例确认线程。Reddit.com 的纱帽

我首先收集了我想要调查的时间段(72 个月)的所有每月确认线程 URL。为了做到这一点,我用 PRAW 写了一个函数,在 r/hardware swap subredit 中搜索标题中带有“已确认贸易线索”字样的所有帖子。

Github 链接到上述功能。

参与交易的用户

这个搜索产生了过去 72 个已确认交易线索的 URL 列表,代表了大约 6 年的数据。然后,我使用 Reddit API 从 72 个已确认的交易线索中提取相关的特定数据。我的主要目标是收集以下信息:

●参与交易者的用户名

●谁与谁交易的数据(买方和卖方)

●购买/出售的数据

为了收集这些数据,我编写了另一个函数来完成以下任务:

●从 confirm_urls 函数中获取 URL 列表(在上面的截图中以亮蓝色文字书写)。

●查看所有父评论并收集

1)评论者的用户名

2)父注释的文本

3)文本和天赋(已确认交易的数量)。

●添加(使用 Python 字典)注释的作者作为键,添加列表的列表作为值,其中存储了注释的正文和与进行交易的用户的信息。

每个结果数据点如下所示:

示例字典键、值对

如上所述,Python 字典中的键就是这样创建的:通过附加用户名(child.group()[2:])和 body_text,如上面的代码所示。如果字典中的用户有不止一个事务(这是常见的情况),那么该函数会向值中存储的列表添加另一个条目。

交易方向

最后,我想检测每个交易的方向:也就是说,它是被描述为买入还是卖出。然而,在我第一次浏览代码的过程中,我发现还有第三个类别:“交易”,这发生在两个用户互相交易物品但没有交换货币的情况下。

为了确定每笔交易的方向,我在评论中寻找常用词——例如,“买”、“买”、“卖”或“交易”——并将它们放入一个列表,然后与一串文本进行比较。如果这些常用词出现在给定的字符串中,那么我就知道交易的方向。最后,我为我的功能无法确定方向的事务添加了一个“模糊”类别。下面的代码记录了每笔交易的方向:

Github 链接到上面的函数

注意:使用 PRAW 提取所有这些数据需要大约 18 个小时。所以,如果你想自己尝试一下,我建议你通宵运行这个程序。

最后,埃达!

现在,到探索性数据分析组件。r/HardwareSwap 这个子字段的总价值和活动是我的风险分析非常需要的。使用我在上面描述的数据集合,我创建了一个 Pandas 数据框架,其中包括每个交易的用户、交易者、方向和产品的数据。

交易数据帧的前 5 行

上面的截图是交易数据帧的前 5 行。方向指示用户是购买还是出售产品。例如,在第 0 行中,用户 orevilo 销售给 veigs。

我得到的结果令人印象深刻。使用这个图表,我发现在过去的 6 年中,这个子 reddit 上至少有 134,013 个事务。

以下是按类型分列的交易明细:

这四个值加起来有 134,013 笔交易。对于一个细分市场来说,这是一个令人印象深刻的大数字。

预计成交价格

当我看到这些数字时,我想知道一笔交易的平均价格,从而了解有多少价值通过 r/hardware WAP 流动。虽然得到的值是*似值,但这是一个有趣的度量。为了估计平均交易价格,我构建了一个函数,它查看过去 1,000 个交易提交,并选择 link_flair_css_class 关闭的提交,这意味着已经进行了交易。

在下图中,你可以看到不同的提交标志:(卖出,买入和平仓)

link_flair_css_class 卖出(蓝色),买入(绿色),成交(红色)。Reddit.com 的纱帽

然后,该函数检查提交的主体中卖方列出的价格;我使用正则表达式并寻找$符号后面的数字。此外,该函数返回一个包含价格、日期和 URL 的 Pandas 数据框,以便我可以检查*似值是否正确。

平均价格 258

这种方法得出 2019 年 12 月 12 日至 2019 年 12 月 15 日期间的平均样本交易价格为 258 美元。如果我们将这个数字乘以 134,000 笔记录的交易,过去 6 年中在 r/HardwareSwap 上交易的产品总价值估计约为 34,500,000 美元。虽然这是一个极端的估计,但即使是这一数额的四分之一,也仍然是一笔巨款。

多元逻辑回归

该项目的目标是创建一个指标来确定与一个给定的 Reddit 用户交易的风险水平。Reddit 上的欺诈活动并不多,但确实存在。这个项目旨在发现与合法 Redditors 的活动相关的模式,与欺诈用户(骗子)的活动形成对比。

考虑到 Reddit 不保留交易历史或收集任何有关其用户的真实身份信息,解决与欺诈相关的问题是一个相当困难的问题,因为与传统的信用指标和社交平台相比,Reddit 提供的指标并不典型地用于衡量风险。Reddit 不会收集创建特定于每个成员的信息记录所需的详细个人信息,因此,成员具有高度的匿名性。

鉴于这个问题,知道是否可以使用机器学*和 Reddit 允许用户从中提取的信息进行准确的预测将是非常有趣的。在这个项目中,我试图根据用户的 Reddit 活动来衡量他或她的风险水平。我首先想到的是使用多元逻辑回归模型,一种用于预测因变量结果的统计分析。在这个领域,它可以被称为机器学*模型。我将利用这个模型,因为只有有限数量的功能可供使用。多重逻辑回归模型将允许我确定与预测 Reddit 用户风险水平最相关的特征。

首先,我将确定项目中正在研究的两(2)组。这些是:

1.Reddit 用户/Redditors: 这些人在 Reddit 上做过真正的交易。他们已经完成了交易。

  1. Reddit 骗子:这些是 Reddit 上的骗子,参与过各种诈骗活动。

Reddit 骗子数据集是从 r/hardwareswap 的封禁列表通用封禁列表中收集的。这些都是被版主发现有欺诈行为的用户名单。因为这是任何市场分支提供的唯一系统,我不得不相信所有这些用户都是骗子。

现在我将使用 Reddit API 来收集 Reddit 用户和 Reddit 骗子的相关特性的数据。之后,我会查看数据,看看是什么将这两组分开。

对于第一个模型,我将研究的相关特性如下:

1.已验证的电子邮件地址(用户是否有)

2.用户是否是任何子编辑的版主

3.Reddit Gold

4.因果报应的数量

5.帐龄

6.最*的评论(最多 100 条)

利用这 6 个特征,我希望发现 Redditor 和 Scammer 群体之间的不同模式。

注意:您可能想在https://praw . readthe docs . io/en/latest/code _ overview/models/redditor . html查看可用的 PRAW 属性(查看 Redditor 对象属性的完整列表)。

评估 6 个特性

  1. 帐龄

Praw 属性。https://praw.readthedocs.io 中的屏幕帽

PRAW 属性

任何用户帐户的 PRAW 属性之一是“created_utc”,它指的是帐户的创建日期。为了将这变成一个有用的特性,我决定创建一个名为“ age”的变量age 变量获取 created_utc 属性中指示的日期,并从用户最后一次评论的时间中减去该日期。通常,骗子被抓后,他们的账户会休眠。因此,为了确定他们的账户在诈骗发生时的年龄,我查看了从每个账户创建日期到最*一次评论日期的时间长度。

上图比较了骗子(橙色)和 Redditors(蓝色)。从图表中可以明显看出,骗子有更高比例的帐户年龄为 1 年或更短,而 Redditors 的帐户平均年龄要大得多。这是有道理的,因为我认为打算诈骗的人不会使用他们已经联系了很长一段时间的 Reddit 账户;然而,也有大量超过 4 年的骗子账户。我不得不认为,这是由于一些被标记为骗子的 Redditors 陷入了某种纠纷,而调解人无法解决,最终买方/卖方都被标记为骗子。也有可能是一些骗子被抓了,但就是不在乎,继续用自己的账号。

2。 因缘

Praw 属性。来自的屏幕帽 https://praw.readthedocs.io

PRAW 属性

“因果报应”指的是用户提交的内容被投票支持时得到的分数。

因果报应的分布显示,骗子拥有 30 或更少因果报应点数的帐户比例要高得多。另一方面,Redditors 的分布更为正常。

3。 电子邮件地址

Praw 属性。来自https://praw . readthedocs . io的屏幕盖

与骗子相比,Redditors 拥有经过验证的电子邮件地址的比例要高得多。

4。REDDIT GOLD

Praw 属性。来自https://praw . readthedocs . io的屏幕盖

Reddit Gold 表示用户拥有付费的 Reddit 帐户(Premium)。看到有骗子有 Reddit 黄金,我很惊讶;当 Reddit 大部分是免费的时候,一些骗子为他们用来诈骗的账户付费,这似乎很可疑。这一事实可能是真实用户被错误地标记为骗子的结果。

5。 主持人

Praw 属性。来自https://praw . readthedocs . io的屏幕盖

更大比例的 reddits 是 Subreddits 的版主。这是我所期待的,因为骗子可能不会使用他们诈骗某人时使用的相同帐户来努力调节 Subreddits。

6。备注

你可以看到评论少于 10 条的骗子数量激增。这是我想在未来重新审视的一个变量。Reddit API 允许每个用户最多 1000 条评论,但我只选取了最后 100 条作为案例研究。

我仔细研究这些个体变量的原因是为了在 Redditors 和 scammers 的活动中找到一个明显的差异。我已经能够使用机器学*来实现这一点。对于每个变量,两组之间活动分布的差异都有明确的定义。我坚信,如果我们认识到所有 6 个特征,那么我们将能够对 Reddit 账户及其风险水平做出准确的预测。

多元逻辑回归模型

在这个项目中,我对使用我上面讨论的变量预测定性结果感兴趣。这可以称为对观察结果进行分类,因为它涉及将观察到的数据分配到特定类别,在这种情况下,该类别可以是 Redditor 或 Scammer。具体来说,对于这个分类项目,我打算使用多元逻辑回归模型来预测一个观察的概率。几乎不可能肯定地说某个 Reddit 用户是骗子,但他/她的活动与欺诈用户的活动相匹配的概率是一个更现实的指标。

一个多重逻辑回归方程,其中 X = (X1,X2,…..,Xp)是 p,预测因子,看起来是这样的:

数据分布

包装:

  • Numpy —支持大型多维数组和矩阵
  • 熊猫—数据处理和分析
  • Sklearn —机器学*库
  • Statsmodel —探索数据,估计统计模型,并执行统计测试

执行回归

对于这个模型,预测变量将是电子邮件、版主、黄金、因果、年龄和评论,而目标变量将是用户名。目标变量中的数字“0”代表 Redditor,而数字“1”代表 scammer。

以黄色突出显示的岭回归参数

L2 正则化—岭回归

正则化可用于训练模型,通过防止算法过度拟合训练数据集,可以更好地对看不见的数据进行归纳。岭回归通过引入一条带有少量偏差的新的最佳拟合线来做到这一点,作为回报,它得到了方差的显著下降。随着新数据被引入模型,这有助于更好地进行长期预测。

L2 方程

wikipedia.com 的纱帽

除 y 轴截距之外的每个参数都按脊线缩放。

现在我已经做了一些模型调优,是时候使用 Sklearn 运行模型了。

下面是模型在分析测试变量数据后给出的结果总结。

总的来说,多重逻辑回归模型做得很好,预测远远超过随机的 50/50 猜测。该模型的准确度(显示在黄色矩形中)为 83%。然而,在继续这个模型之前,我想看一下 p 值,以确保所有的变量都是显著的。我将利用 Statsmodel 库来解释我得到的结果,因为这个库给出了比 Sklearn 好得多的 p 值汇总。

在上面的结果中(显示在红色矩形中),变量“Karma”具有非常高的 p 值,这意味着它在这个模型中是无关紧要的。这有点令人惊讶,因为 EDA 已经表明因果报应是区分这两个组的相关特征。然而,在这里,我将删除变量“Karma ”,并重新运行模型以查看其响应。

模型,版本 2 (去除预测变量 Karma 后)

具有特征因果报应

没有 Karma(更高的精度水平在下面的结果中突出显示,显示了改进):

没有特征因果报应

精密:

这指的是实际上是正确的肯定识别的比例。

其中 TP =真阳性,FP =假阳性。

在该模型预测的 310 个骗子中,有 253 个是正确的,其准确率为 82%。

回忆:

这是指被正确识别的实际阳性的比例。

其中 TP =真阳性,FN =假阴性。

在测试数据中,有 491 个骗子,253 个被正确识别,这产生了 52%的召回分数。

当涉及到这个项目的实际应用时,在这个过程之前确定一个 Reddit 用户是否是骗子是非常困难的。有可能一个 Redditor 显示了一个骗子的活动,但却有着良好的意图。另一方面,用户可能已经成功进行了 5 次交易,然后决定不继续进行第 6 次交易。

为了全面评估模型的效率,我考察了精确度和召回率。通过给预测的概率增加一个阈值,就给模型增加了很多价值。在下图中,您可以看到该模型根据预测的概率来预测 Reddit 用户是真实用户还是骗子,该模型对两组用户都使用了大于 0.5 的基本阈值。例如,如果用户是骗子的概率是> . 5%,那么模型将为该用户预测骗子。

这是一个示例输出,模型做出了 10 个预测:

模型做出的 10 个预测

在上图中,你可以看到模型做出的 10 个预测。概率是根据电子邮件、mod、gold、评论和年龄计算的。在行 0 中,模型预测用户与骗子具有 0.697%的相似性,这最终是正确的,因为真实结果列显示用户 0 是骗子。

不同概率下检查概率阈值的代码:

在对测试数据应用不同的阈值之后。通过在预测骗子时将阈值提高到 60%,假阳性的数量减少了,从而将精确度提高到 92%。

使用模型—应用程序使用

查找没有确认交易的用户的提交

Reddit.com 的纱帽

典型提交,但用户有 0 笔确认交易

将用户名输入一个函数,该函数从 reddit API 中提取必要的数据。然后将数据输入多元逻辑回归模型,并返回一个评级。为了使应用程序更加用户友好,低于 40 的等级显示为危险,高于 60 的等级显示为安全。

正如你所看到的,这个用户得到了 38.2 的评分,这是相当低的。暗示找别人买可能更好。

使用模型-确认用户

找到已确认交易的用户

Reddit.com 的纱帽

拥有 7 笔已确认交易的用户

因为用户有 7 笔已确认的交易,所以它们很可能是真实的。为了创建一种类型的用户评级,该函数输出以前的交易。

结论

基于这些阈值和结果,可以有把握地说,如果一个 Reddit 用户的预测骗子概率高于 0 . 6 的,那么最好找其他人与交易。因此,通过寻找 6 个特征/变量年龄、主持人、因果关系、电子邮件、黄金、评论并预测除因果关系之外的所有这些特征/变量的概率,可以预测与 Reddit 用户交易时的风险水平。

如果你想查看我的Github库中的所有代码。

如何在 Julia 中使用模块

原文:https://towardsdatascience.com/how-to-use-modules-in-julia-a27e31974b9c?source=collection_archive---------30-----------------------

朱莉娅综合教程

关于 Julia 语言中模块和导入如何工作的快速课程

(图片由作者提供)

本文视频:

Github:

[## emmettgb/JuliaLessons

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

github.com](https://github.com/emmettgb/JuliaLessons/tree/master/6)

介绍

而我们在过去的朱莉娅教程中已经讲过的东西;函数、构造函数和类型当然是有价值的,一个程序员不可能从零开始构建一个完整的生态系统。也就是说,程序员经常使用包来执行他们的包不一定针对但需要的算法。包是代码的储存库,可以作为其他包迭代和构建的依赖项重用。

我们已经对 Pkg 以及如何使用它来安装 Julia 编程语言的包进行了概述。今天我们将使用一个名为 Compose.jl 的模块来练*用 Julia 编程。我选择这个库是因为它是一个函数式的声明性库,遵循我们在这些教程中介绍的相同的编程方法和原则。此外,作为一个图形包意味着人们可以在非常直观的输出中看到他们代码的直接结果——这对一个新的程序员来说很方便。如果您想了解更多关于该模块的信息,您可以访问 Juliahub:

[## JuliaHub

编辑描述

juliahub.com](https://juliahub.com/ui/Packages/Compose/sbiEw/0.9.1)

包装——基础

为了在 Julia 中添加一个包,我们将使用 Pkg。您可以通过使用将 Pkg 导入到 Julia 中,或者只使用 Pkg REPL,可以通过在 Julia REPL 中按]来访问它。添加相对简单,可以使用 Pkg.add()方法或 Pkg REPL 中的 add 命令来完成。当然,今天我们将使用 Compose.jl,所以您可能想继续添加它:

julia> ]
pkg> add Compose

这将把 Compose 添加到我们的全局包环境中。一些 Julia 开发者强烈反对这样做,但是我不同意——我认为在你的机器上有依赖是完全没问题的,只要它们是经常使用的依赖。此外,用户总是可以使用 rm 命令删除他们的包。

julia> ]
pkg> rm Compose

如果你想了解更多关于 Pkg 酷的原因,你可以看看我不久前写的一篇文章!:

[## 朱莉娅的包装经理棒极了

为什么 Julia 的 Pkg 是我用过的最好的软件包管理器。

towardsdatascience.com](/julias-package-manager-is-awesome-23b9c02e3a0b)

为了让一个模块进入我们的 Julia 运行时环境,我们有一系列不同的选项来导入它。首要的是使用。使用 just 意味着该包将被预编译并从运行时内部调用,并且不会在运行时内部发生变化。我们可以使用 Compose 包

using Compose

在 Julia 语言中,使用导出的函数和结构是很常见的。这意味着这些函数不需要通过它们的父类来调用,而是可以在导入模块时直接调用。我们可以通过直接导入我们想要在 Julia 中使用的类型或函数来避免使用导出:

using Compose: compose

直接导入将加载我们的目标代码,而不包括包内的所有其他成分。直接导入也可以节省编译时间,在注册的软件中,对于只有一两个不同类型或函数要在你的软件中使用的依赖项,这是绝对推荐的。

除了使用之外,在 Julia 语言中,我们还可以访问 import 关键字。导入代码与使用代码正好相反,并且允许扩展包。通常情况下,除非需要扩展,否则不需要显式导入。

import Compose
# Direct explicit import:
import Compose: compose

作曲!

了解了使用 Julia 中模块的基础知识后,我们现在可以看看我们今天要学*的模块:

Compose.jl

Compose 是一个用 pure Julia 编写的声明性矢量图形库,它使得只使用几个参数和节点就可以非常容易地绘制图形。您可以在此处查看 Juliahub 上的撰写文档:

[## Home Compose.jl

Compose 是一个用 Julia 编写的声明性矢量图形系统。它旨在简化复杂的创建…

juliahub.com](https://juliahub.com/docs/Compose/sbiEw/0.9.1/)

说到这里,如果你是 Julia 的新手,并且正在使用 Julia 模块,那么看看 JuliaHub 肯定是值得的。JuliaHub 是 Julia 程序员的一体化软件包目的地,其中的文档很容易包含并自动集成到网站中。如果你想了解更多,我有一整篇关于它有多酷的文章!:

[## JuliaHub:将包和文档放在一起的最好方法

JuliaHub 如何自动化所有程序员讨厌做的事情。

towardsdatascience.com](/juliahub-the-greatest-approach-to-putting-together-packages-and-documentation-707688a472d2)

直接从 Compose 文档中提取,我们的第一个例子很简单,但是可以理解要点:

composition = compose(context(), rectangle(), fill("tomato"))

(图片由作者提供)

更深入地研究这个语句,compose()方法负责返回一个组合并接受参数。这些参数是称为组合表单和节点的类型。在方法调用内部,我们看到的参数是 context()、rectangle()和 fill()。Context 是根节点,所以在这个特定的实例中,它基本上可以被忽略。接下来的参数是矩形。这当然是在渲染图像中显示的类型。最后一个参数是 fill(),它接受一个字符串,表示整个上下文所需颜色的标题()。

幸运的是,我们可以使用?()方法,以了解有关这些参数的更多信息。让我们创建更多的矩形!我们将从查看在创建类型时可以提供什么类型的数据开始:

矩形既可以接受 0 个参数,也可以接受 4 个参数。这方面的四个参数是位置参数,窗体的 x 位置,窗体的 y 位置,然后是宽度和高度。有了这个新发现的信息,让我们修改我们的旧代码来改变矩形的大小:

composition = compose(context(), rectangle(.5, .5, 5px, 5px), fill("tomato"))

(图片由作者提供)

并添加更多的矩形:

composition = compose(context(), rectangle(.5, .5, 20px, 20px),
    rectangle(.5, .2, 20px, 20px),
    rectangle(.5, .8, 20px, 20px),
    fill("tomato")
)

(图片由作者提供)

使用与导入

一个可能令人混淆的概念是使用 import 和使用将模块导入 Julia。这是可以理解的,因为许多语言通常不包含这个特性;并且大多数使用 using 将类和函数从名称空间中取出。也就是说,普通的 Julia 程序员可以感觉到的使用和导入之间最明显的区别是扩展模块的能力。这在本文前面已经提到过,但是用代码详细说明一下,分派一个矩形只接受两个位置参数而不是一个或两个是不可能的,如下所示:

using Compose: rectangle
rectangle(x::Float64, y::Float64) = rectangle(x, y, 30px, 30px)

但是,如果我们使用 import 而不是使用:

import Compose: rectangle
rectangle(x::Float64, y::Float64) = rectangle(x, y, 30px, 30px)

结论

没有一个程序员能够写出整个世界的软件,幸运的是他们不需要这么做。这是因为数以百万计的开源开发者正在开发每个程序员都可以使用的奇妙模块。在 Julia 中,我们可以使用 Pkg 添加一些这样的包。从今天开始,关于模块最重要的事情是:

  • 那个?()方法
  • JuliaHub 文档
  • 添加包
  • 导入和使用的区别

掌握这些概念会让你成为一个真正的茱莉亚语言大师,你已经在路上了!

如何在 Pandas 中使用 MultiIndex 来提升您的分析

原文:https://towardsdatascience.com/how-to-use-multiindex-in-pandas-to-level-up-your-analysis-aeac7f451fce?source=collection_archive---------0-----------------------

大蟒

复杂数据分析中数据帧的层次索引介绍

小姐姐创造的形象

如果您的数据框架的索引中有不止一列,会怎么样?

Pandas 中的多级索引功能允许您这样做。一个常规的 Pandas 数据帧有一个单独的列,作为唯一的行标识符,或者换句话说,一个“索引”。这些索引值可以是从 0 到无穷大的数字。它们也可以更详细,比如将“菜名”作为麦当劳特许经营店所有食物的索引值。

但是,如果你拥有两家麦当劳连锁店,并且想比较两家连锁店中一道菜的销售额,该怎么办呢?

虽然 Pandas 中的groupby()函数可以工作,但这个案例也是一个多索引可以派上用场的例子。

MultiIndex ,也称为多级索引或层次索引,允许您将多个列作为行标识符,同时通过父/子关系将每个索引列与另一个索引列相关联。

在本文结束时,我们将通过创建和选择具有分层索引的数据帧来回答以下问题:

  • 《指环王》第一章有哪些人物说话?(用.loc回答)
  • 在《指环王》中最先开口的三个精灵是谁?(用.loc回答)
  • 《双塔奇谋》中甘道夫和萨鲁曼谈了多少?(用.loc回答)
  • 在所有电影中,埃西铎说了多少?(用.xs回答)
  • 在每部电影以及三部电影中,哪些霍比特人说得最多?(用透视表和.loc回答)

你可以在这里找到这篇文章中用到的数据。我们将使用“指环王”电影中的数据,特别是数据集中的“WordsByCharacter.csv”文件。这个文件将有每个角色在每部电影的每个场景中所说的话的数量。

和往常一样,在尝试任何代码之前,不要忘记导入熊猫。

import pandas as pd# load data
df = pd.read_csv('WordsByCharacter.csv')

来自 WordsByCharacter.csv 的原始数据帧

让我们深入了解如何使用多级索引进行数据分析。

多索引快速介绍

分层索引意味着您的数据帧将有两个或多个维度,可用于标识每一行。

要获得原始数据帧的索引标签,我们可以使用以下代码:

df.index.names

原始数据帧索引名的冻结列表

这将输出一个“FrozenList”,这只是一个 Pandas 特有的构造,用于显示数据帧的索引标签。这里,我们看到值是“None”,因为这是数据帧索引的默认值。

要用我们的原始数据框架创建一个多索引,我们需要做的就是将一列列表传递到 **.set_index()** Pandas 函数中,如下所示:

multi = df.set_index(['Film', 'Chapter', 'Race', 'Character'])

一列多索引数据框架(单词)

在这里,我们已经可以看到名为“multi”的新数据帧已经过组织,现在有四列组成索引。我们可以通过再次查看索引名称来检查这一点:

multi.index.names

多级索引数据帧的索引名称的冻结列表

我们现在看到前面的值“None”已经被我们指定为新索引的四个列的名称所取代。

常规的、未改变的数据帧中的每个索引值只是一个从 0 到 730 的数字(因为数据帧有 731 行)。为了向您展示我们新创建的 MultiIndex 中的每个索引值,我们可以使用这行代码:

multi.index.values

多索引数据帧的索引值数组

现在,我们看到“单词”列中的每一行值都可以通过它来自哪部电影、它指的是哪一章、说这个单词的角色是什么种族以及该角色的名字来标识。

在我们深入分析之前,有一点需要注意,那就是.sort_index() Pandas 函数。创建具有多索引的数据帧时,请确保将其附加到代码行的末尾,如下所示:

multi = df.set_index([‘Film’, ‘Chapter’, ‘Race’, ‘Character’]).sort_index()

熊猫文档上有这样的注释:

即使数据没有排序,索引也可以工作,但是效率会很低(并显示一个性能警告)。它还将返回数据的副本,而不是视图。

同样值得注意的是,你可以简单地通过将.reset_index()传递给你的数据帧来删除层次索引,就像这样:

multi.reset_index()

这将只返回原始数据帧,而不返回多个索引列上的父/子关系。

现在我们准备执行一些分析!

用熊猫多重索引功能回答指环王的琐事问题

《魔戒相交》第一章有哪些人物说话?

这里,我们将使用可靠的.loc Pandas 函数。如果你以前没有用过它,请随意查看这个关于矢量化熊猫函数的快速指南。

这里,我们感兴趣的是索引的两个组成部分,即“电影”和“章节”。在我们的.loc选择器中,我们编写了以下内容:

multi.loc[('The Fellowship Of The Ring', '01: Prologue'), :]

简单的输出。多索引数据帧上的锁定选择器

您可以通过将数据帧的 MultiIndex 的每个部分传递到一个 tuple 中来选择所需的值。在我们刚刚编写的选择器的第一部分中,我们传递了元组(“环的友谊”,“01: Prologue”)。我们不需要传递“种族”或“性格”的值,因为我们还不知道谁在第一章中说话。

请注意,“电影”和“章节”索引列不再出现在视图中。这是因为我们已经为“电影”和“01: Prologue”输入了“The Fellowship Of The Ring”作为元组中的值,所以输出不需要在视图中重复这些值。

另外,:作为最后一个参数被插入到.loc选择器中,表示我们希望显示所有的列。在我们的例子中,DataFrame 只有一个名为“Words”的列,因为 DataFrame 中的每隔一列都被转换为索引列。但是,如果您的数据框架中有多个列,并且只想查看一个子集,那么您应该使用列名而不是:

现在,我们知道埃尔隆德、凯兰崔尔、咕鲁和比尔博在第一部电影的第一个场景中说话了。让我们来看一个稍微复杂一点的例子。

《指环王》中最先开口的三个精灵是谁?

这里,我们仍将使用.loc,但是现在我们将使用一些语法,在从多索引值中进行选择时,这些语法将为我们提供一些灵活性。

为了回答这个问题,我们对“电影”和“种族”索引列感兴趣。这一次,我们“跳过”一个索引栏,因为“章节”位于“电影”和“种族”之间。我们还不知道精灵们首先在哪个“章节”说话,所以我们需要把那个留白。

为此,我们将使用这行代码:

multi.loc[(‘The Fellowship Of The Ring’,slice(None),’Elf’), :].head(3)

的输出。在多索引数据帧上使用切片(无)锁定选择器

同样,我们传递一个带有我们想要的索引值的元组,但是我们传递的不是“Chapter”的值,而是slice(None)。这是 Pandas 中默认的 slice 命令,用于选择多索引级别的所有内容。所以在这里,我们选择所有可能的“章节”值。

现在,我们知道埃尔隆德、凯兰崔尔和阿尔温是第一部书中最先说话的三个精灵。但到目前为止,我们所做的只是将每个索引列的一个值传递给.loc选择器。如果我们想获得多个值呢?

在《双塔奇谋》的每一章中,甘道夫和萨鲁曼谈了多少?

在这个问题中,我们对第二部“电影”的所有“章节”都感兴趣,这两部电影我们都已经知道如何选择。但是这一次,我们感兴趣的是“字符”索引的两个值。

为了得到答案,我们写下这行代码:

multi.loc[('The Two Towers',slice(None),slice(None),['Gandalf','Saruman']), :]

多个条件的输出。多索引数据帧上的锁定选择器

我们在这里需要做的就是将我们想要的索引值列表传递给我们插入到.loc中的元组。由于我们不知道要获得哪个“章节”或“比赛”,所以在获得“字符”之前,我们为这两个索引值传递slice(None)

到目前为止,我们在选择中已经有了多个条件,这就是为什么使用.loc很方便。但是如果我们只想指定一个级别的索引呢?写三遍slice(None)会很累,所以我们会转向另一种方法。

在所有电影中,埃西铎说了多少话?

要回答这个问题,我们只需要为“字符”指定一个索引级别值。我们将在 Pandas 中使用xs()(横截面)方法,它允许您指定想要搜索多索引的哪个部分。

我们使用以下代码:

multi.xs('Isildur', level='Character').sum()

basic 的输出。多索引数据框架上的 xs 选择器

最基本的是,xs()需要输入您想要查找的索引值和您想要搜索的级别。在这种情况下,我们需要“字符”级别,所以我们将它传递到level=,我们希望“字符”的值是“埃西铎”。然后,为了聚合所有的值,我们将.sum()添加到行尾。

我做了一点小手脚,以便验证数据的准确性,因为我知道这个问题的答案(埃西铎在整个三部曲中说的一个词是“不”)。但是您也可以使用这一行代码来查找任何角色说了多少话,只需将他们的名字作为参数代入xs()中。

哪几个霍比特人在每部电影和三部电影中都说得最多?

要回答这个问题,如果我们有一个表,其中汇总了每部电影中每个角色的“单词”值,那就太好了。这是创建数据透视表的好地方!

我们将使用 Pandas 的.pivot_table()函数,但是您将看到我们将一个列表传递到index=参数设置中,以再次创建一个 MultiIndex。我们创建数据透视表的代码如下所示:

pivoted = df.pivot_table(index = ['Race','Character'],
                         columns = 'Film',
                         aggfunc = 'sum',
                         margins = True, # total column
                         margins_name = 'All Films',
                         fill_value = 0).sort_index()order = [('Words', 'The Fellowship Of The Ring'),
         ('Words', 'The Two Towers'),
         ('Words', 'The Return Of The King'), 
         ('Words', 'All Films')]pivoted = pivoted.sort_values(by=('Words', 'All Films'), ascending=False)
pivoted = pivoted.reindex(order, axis=1)

具有多索引的基本数据透视表

这里,我们的多级索引有两个组件,而不是上一个示例中的四个组件。这是因为我们希望“Film”值也是一个列,而不是一个索引。我们也不需要查看“章节”值,因此将其排除在外。因为我们对单词总数感兴趣,所以我们希望我们的aggfunc(聚合函数)参数是“sum”。

Pandas 还有一个内置的用于.pivot_table()函数的 total 列。您所需要做的就是通过margins=True来启用它,并可选地在margins_name参数中设置总计列的名称。

因为我们希望看到中每个“角色”的总字数,这个“角色”的“种族”值为“霍比特人”,所以我们可以通过一个非常简单的应用.loc来选择这个条件。

pivoted.loc['Hobbit']

的输出。锁定多索引数据透视表

嘣!

现在我们有了一个表格,根据这个表格,霍比特人在所有电影中说得最多。我们还可以看到每部电影中每个角色说了多少话。一些有用的见解包括比尔博在《双塔奇谋》中根本没有说话,但仍然比皮聘和梅里有更多的总对话,他们在所有三部电影中都说话。

拥有这个表的好处在于,我们可以对" Elf "、" Men "、" Ainur "以及《指环王》中的其他种族进行同样的分析,只需在上面的.loc函数中代入一个参数。

我希望这篇关于 Pandas 中层次索引的介绍对您有用!我发现在 DataFrame 索引中有多个级别意味着我可以快速地将我的数据分组到特定的级别,而不必编写多个groupby()函数。

和往常一样,查看官方文档,更深入地了解如何在分析中使用多指数特性。

我喜欢参与数据收集和分析,这就是为什么我使用那篇文章中讨论的一种快速简单的方法来收集样本数据。如果你想在网上获取一些你自己的测试数据来测试这段代码,你可以在上查看这篇文章,从一个有熊猫的网站获取表格。

祝你的多级索引冒险好运!

如何在你的算法交易策略中使用多个时间框架

原文:https://towardsdatascience.com/how-to-use-multiple-timeframes-in-your-algotrading-strategy-8be026a890e2?source=collection_archive---------51-----------------------

你把钱放在桌子上而不使用它们

照片由 Katerina Limpitsouni 拍摄

在本教程中,我将看一个例子,说明如何在你的策略中使用多个时间框架。在之前的文章中,我们学*了如何进口蜡烛,写一个简单的盈利策略,定义路线,以及执行回溯测试。如果您还没有阅读我之前的文章,请在继续之前阅读

我将从上一篇文章停止的地方继续。这是我最后得出的完整策略:

这是从2019-01-012020-05-014h时间框架回溯测试的结果:

从 2019 年 1 月 1 日到 2020 年 5 月 1 日的回溯测试结果,没有锚定时间框架

在您的策略中定义多个时间框架

这一次,我将使用多个时间框架,看看我是否能改善结果。有经验的交易者在手动交易中使用的一个技巧是观察更大时间框架的趋势(或者他们称之为时间框架)。这个简单的技巧经常会以减少进场信号的数量为代价来增加你的胜率。

你可能会问,我怎么知道哪个时间框架是锚定时间框架?通常的公式是你交易时间的 4 到 6 倍。例如,在我的例子中,4h的锚定时间范围是:

6 * 4h = 24h ("1D" in jesse's terms)

Jesse 提供了一个实用助手来帮你计算,这就是我要用的。

让我们添加一个新的返回大趋势的属性方法。我会返回1表示上升趋势,返回-1表示下降趋势:

如你所见,这次我用了 self.get_candles 而不是 self.candles 。我还使用了一些其他内置属性,而不是使用硬编码的字符串:

这样,当我改变我的路线去尝试其他的交换、符号和时间框架时,我不必改变我的策略代码。

现在我更新了我的参赛规则,加入了anchor_trend:

修改您的路线

现在,我再次执行回溯测试,看看这一更改会如何影响回溯测试结果,但我得到了以下错误:

Uncaught Exception: RouteNotFound: Bellow route is required but missing in your routes: ('Bitfinex', 'BTCUSD', '1D')

错误是明显的。如果我在另一个时间段使用蜡烛,我也应该把它添加到我的routes.py文件中。我的交易路线必须保持不变,因为我交易的是单一头寸,所以我使用的任何其他时间框架都被视为额外的蜡烛线。

这是我的routes.py现在的样子:

这个错误告诉我,在我的路线中我遗漏了('Bitfinex', 'BTCUSD', '1D');所以我们把它加到extra_candles列表里吧。这就是我的routes.py应该变成的样子:

这一次回溯测试进展顺利。结果如下:

从 2019 年 1 月 1 日到 2020 年 5 月 1 日的回溯测试结果,具有锚定时间框架

在我使用锚定时间框架来检测市场的更大趋势后,回溯测试结果中有一些值得注意的变化:

  • 总净利润从 31.44%增加到 48.42%,这意味着更多的钱!
  • 总平仓交易减少了,这意味着我得到的进场信号减少了,这是意料之中的,因为我在进场规则中增加了另一个进场条件。
  • 夏普比率从 0.62 增加到 0.86。
  • 胜率从 47%提高到 50%。

前瞻偏见

在 algo 策略中使用多个时间框架时,前瞻偏差是一个严重的问题。简而言之,这意味着使用未来的数据。

你们中的一些人可能对此很熟悉,并想知道前瞻偏差是否在我们刚刚观察到的结果提升中起了作用。放心,不会的。Jesse 框架在幕后处理前瞻性偏见。

结论

我们刚刚看到了我的策略指标的显著提升,这是使用锚定时间框架来确定市场更大趋势的结果。

当然,你不会每次在策略中使用多个时间框架时都得到同样的提升。但在我看来,至少尝试一下是有意义的。

这个想法可以延伸。例如,如果你在交易以太网,你可能想利用比特币的锚趋势,因为很明显比特币是加密货币市场的国王,对其他硬币的价格有着巨大的影响。

为了获得我未来的作品和产品,请务必订阅杰西的时事通讯,并查看论坛与像你我这样的量化分析师讨论算法交易

最初发表于【https://jesse-ai.com】

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

如何使用 n 元模型检测数据集中的格式错误

原文:https://towardsdatascience.com/how-to-use-n-gram-models-to-detect-format-errors-in-datasets-bb2171842499?source=collection_archive---------48-----------------------

关于语言模型如何扩展和用于不同目的的代码优先方法。

图片由 RonilePixabay 拍摄

格式错误,在最好的情况下,会破坏自动数据处理管道。在最坏的情况下,它们会在难以调试的下游分析任务中引入逻辑错误。发现这样的错误是一项单调而低效的工作,会降低工作效率。此外,这种手动过程可能引入不同类型的错误。那么,我们能自动检测损坏的值吗?

例如,考虑一个数据集D,它有数百万行,包含一个Date列。让我们假设这个列中的值符合一个特定的模式:mm.dd.yyyy。假设某处存在一个无效的单元格,由于输入错误,日期遵循不同的格式:01.15–2019。在自动化管道中,解析器将尝试读取该特性,并可能抛出异常。试图在管道执行之前找到错误几乎是不可能的。但是如果我们能让计算机检测到它呢?

在这个故事中,我们使用 n-grams,一种语言模型,来自动化错误检测。我们简要讨论 n 元语法以及 NLP 工程师如何使用它们来生成语言,并研究我们如何利用它们的属性来识别数据集中可能损坏的值。

学*率是为那些对 AI 和 MLOps 的世界感到好奇的人准备的时事通讯。你会在每周五收到我关于最新人工智能新闻和文章的更新和想法。在这里订阅!

关于 n-grams

n-gram 是一个概率模型,简单来说,它试图预测序列中的下一个单词。像 n-grams 这样的概率模型总是通过例子来更好地理解。因此,请考虑下面这段摘自艾米莉·狄金森的诗:

在巨大的痛苦之后,一种正式的感觉来了——
神经像坟墓一样隆重地坐着——
僵硬的心会问‘是他吗,令人厌烦的’,
和‘昨天,还是几个世纪以前’?

首先,我们想知道每个句子从哪里开始,什么时候结束。为此,让我们用特殊字符<s>表示起点,用</s>指出终点位置。

巨大的痛苦之后,一种正式的感觉来了——
神经顿然,如同坟墓——
s那颗僵硬的心质问‘是他,那个生了,< /s >
< s >和‘昨天,还是几个世纪以前’?< /s >

要创建一个 n 元模型,首先我们必须为n超参数设置一个特定的数字。因此,让n = 2,在这种情况下,n-gram 模型转换为双-gram 模型。现在,我们可以计算两个连续单词的概率。例如,这段摘录中的句子通常以the一词开头。

使用这些概率,并给定一个新单词作为种子,我们可以预测序列中的下一个单词。显然,数据集越大,结果越好。同样,根据问题的不同,3-grams 可能更好,但是 **n** 的值越大,引入的稀疏性就越多。

泛化树和泛化语言

为了使用 n-grams 来检测表中的格式错误,我们需要一种方法来将原始值归纳为模式。我们也可以用原始值训练一个 n 元模型,但是这种方法的复杂性引入了太多的自由度,导致高度稀疏。

例如,假设v₁是一个表示邮政编码的原始数字序列:15122。然后,让v₂,v₃表示两种不同的代码:345a747592。显然,v₂是错误的,但是如果我们在 n 元模型中传递原始值,我们将不会得到有价值的信息;看那个p(a|5) = p(1|5),这样我们要么漏掉错误,要么产生假阳性。但是如果我们能把一个原始值归纳成一个模式,我们就能得到更有意义的表示。

为此,我们使用了泛化树泛化语言的概念。泛化树是一个类似下图的层次结构,将原始值映射到不同的表示形式。

从那棵树上,我们可以派生出许多语言。下面给出一个例子。

使用L₁,我们可以将v₁,v₂,v₃转换成DDDDD,DDDLD,DDDDD。我们也可以将模式压缩为v₁ = D(5), v₂ = D(3)L(1),D(1), v₃ = D(5)。有了这个表示和足够大的数据集来训练一个 n 元模型,我们可以得到邮政编码格式的字母L出现的概率非常低。简而言之,这就是泛化树和语言的思想。如果需要更详细的介绍,请看下面的故事。

[## 如何自动检测数据集中的错误

引入泛化树和泛化语言来自动检测结构化数据集中的损坏值。

towardsdatascience.com](/how-to-auto-detect-format-errors-in-a-dataset-6609a9e9aacc)

实施和评估

现在是我们动手的时候了。对于这个例子,我们使用一个包含 100 行三个特征的合成数据集:电子邮件、日期、邮政编码。因此,让我们使用pandas加载数据,看看是什么样的。

这一次,我们使用了zip_code列,其中我们引入了一些错误。因此,我们指定我们将使用的泛化语言。它严格遵循L₁中定义的规则。

例如,2899.8的图案是d(4)s(1)d(1),而03754的图案是d(5)。现在,让我们将每个邮政编码转换成它的模式。

我们使用流行的 python 库nltk,创建 3-grams 并构建最大似然估计模型(MLE)。

首先,我们填充序列,正如我们在这个故事的第一部分看到的。接下来,我们为每个填充序列(即,每个填充的邮政编码模式)构建一组 3-gram。最后,我们使用 3-grams 来拟合 MLE 模型。

为了评估一个邮政编码并检测任何错误,我们需要一个 score 函数。因此,下面我们定义这样一个函数。

这个函数获取一个原始值,相应地将其归纳为一个模式,填充它并计算每个 3-gram 的分数。最后,它返回最不可能的计算值。这是因为我们只需要一个 3-gram 就可以确信我们有错误。这是对这个玩具例子的一个简单的解释,但是如果你想了解如何聚合许多泛化语言的结果,请阅读下面的故事。

[## 如何使用泛化语言自动检测数据集中的错误

使用远程监督和汇总预测结果生成验证数据,就像大海捞针一样。

towardsdatascience.com](/how-to-auto-detect-errors-in-a-dataset-part-ii-683b114865be)

现在,如果我们将一个有效的邮政编码值传递给score方法,得到的概率很高:score('15378') = 0.951。另一方面,如果有任何包含字母、符号或五个以上数字的值,概率就会下降。例如,第一个邮政编码243x2的得分为0.0098

结论

在这个故事中,我们使用一个玩具示例来展示语言模型(n-grams)如何用于表格数据集中的格式错误检测。我们简要解释了什么是 n 元语法,以及如何使用泛化树和语言来解决稀疏性问题。最后,我们实现了一个简单的解决方案,利用 n-grams 的能力结合泛化语言来检测合成数据集中的错误。

我叫 Dimitris Poulopoulos,是希腊比雷埃夫斯大学BigDataStack的机器学*研究员和博士(c)。我曾为欧洲委员会、欧盟统计局、国际货币基金组织、欧洲中央银行、经合组织和宜家等主要客户设计和实施人工智能和软件解决方案。如果你有兴趣阅读更多关于机器学*、深度学*和数据科学的帖子,请在 twitter 上关注我的**LinkedIn@ james2pl******

如何在 Python 中使用 NLP:一个实用的分步示例

原文:https://towardsdatascience.com/how-to-use-nlp-in-python-a-practical-step-by-step-example-bd82ca2d2e1e?source=collection_archive---------0-----------------------

找出 NLTK 数据科学家需要的技能

在这篇文章中,我们展示了一个关于招聘信息的分步 NLP 应用。

这是对上一篇文章的技术解释,在这篇文章中,我们总结了数据科学家的热门技能。我们提供雇主最常要求的顶级工具、技能和最低限度的教育。

如果你想看一个用 Python 代码使用自然语言工具包 (NLTK)包的实际例子,这篇文章就是为你准备的。

让我们开始吧。

来源:突发

准备:收集数据

我们搜集了 8 个不同城市的“数据科学家”的招聘信息。抓取后,我们将数据下载到每个城市的单独文件中。

该分析中包含的 8 个城市是波士顿、芝加哥、洛杉矶、蒙特利尔、纽约、旧金山、多伦多和温哥华。变量是职位、公司、地点和职位描述

在本文中,我们不会详细讨论这个过程。

我们准备好进行真正的分析了!我们将从这些数据中总结出雇主要求的流行工具、技能和最低学历。

步骤#1:加载和清理数据

首先,我们将 8 个城市的数据文件加载并组合到 Python 中。

我们删除具有相同职位名称职位描述城市特征的重复行/职位发布。

现在我们有一个包含 5 个要素和 2,681 行的数据集。

相关文章:Python 中的数据清洗:终极指南(2020)

步骤 2:形成关键词列表

在搜索职位描述之前,我们需要代表工具/技能/学位的关键词列表。

对于这个分析,我们使用一个简单的方法来形成列表。这些名单是基于我们的判断和招聘信息的内容。如果任务比这更复杂,你可以使用更高级的方法。

对于工具的关键词列表,我们最初是根据我们的数据科学知识得出一个列表。我们知道数据科学家常用的工具包括 Python、R、Hadoop、Spark 等等。我们对这个领域有相当的了解。因此,这份初步清单很好地涵盖了招聘启事中提到的许多工具。

然后我们查看随机的招聘信息,并添加列表中没有的工具。通常这些新的关键词会提醒我们添加其他相关的工具。

在这个过程之后,我们有了一个关键词列表,它涵盖了招聘信息中提到的大多数工具。

接下来,我们将关键字分为单单词列表和多单词列表。我们需要以不同的方式将这两个关键字列表与职位描述相匹配。

通过简单的字符串匹配,多词关键字通常是唯一的,很容易在工作描述中识别。

单个单词的关键字,比如“C ”,在我们的文章中是指 C 编程语言。但“c”也是一个常见的字母,用在许多单词中,包括“can”、“clustering”。我们需要进一步处理它们(通过标记化),以便仅在职位描述中有单个字母“c”时进行匹配。

以下是我们用 Python 编写的工具的关键词列表。

通过遵循与工具相似的过程,我们得到了技能的关键词列表。

对于的教育水平,我们使用不同的程序。

因为我们正在寻找最低要求的教育水平,我们需要一个数值来排列教育程度。比如我们用 1 代表“学士”或“本科生”,用 2 代表“硕士”或“研究生”,等等。

这样,我们就有了从 1 到 4 的学位排名。数字越高,受教育程度越高。

步骤 3:使用 NLP 技术简化工作描述

在这一步中,我们简化了工作描述文本。我们通过计算机程序使课文更容易理解;从而更有效地将文本与关键词列表进行匹配。

我们数据集中的 job_description 要素如下所示。

标记工作描述

记号化是将文本字符串解析成不同部分(记号)的过程。这是必要的,因为计算机程序能更好地理解标记化的文本。

我们必须用空格(" ")等分隔符将工作描述文本字符串显式地分割成不同的标记(单词)。我们使用 word_tokenize 函数来处理这个任务。

在这个过程之后,工作描述文本串被分割成如下的标记(单词)。计算机可以更容易地读取和处理这些令牌。

例如,单个单词的关键字“c”只能与标记(单词)“c”匹配,而不能与其他单词“can”或“clustering”匹配。

请继续阅读 Python 代码。我们将标记化与接下来的几个过程结合在一起。

词性标注职位描述

工作描述通常很长。我们希望保留对我们的分析有用的单词,同时过滤掉其他单词。我们使用词性标注来实现这一点。

词性标注是一种标注单词是名词、形容词还是动词等的自然语言处理方法。维基百科解释得很好:

词性标注 是将文本(语料库)中的单词标记为对应于特定词性的过程,基于其定义和上下文,即其与短语、句子或段落中相邻和相关单词的关系。这种方法的一种简化形式通常是教学龄儿童识别名词、动词、形容词、副词等。

多亏了 NLTK,我们可以在 Python 中使用这个标记器。

将这种技术应用于关键字列表,我们可以找到与我们的分析相关的标签。

下面,我们用 POS 标签工具的关键字列表作为演示。

字母的不同组合代表标签。例如,NN 代表名词和单数词,如“python”,JJ 代表形容词,如“big”。完整的陈述列表在这里

正如我们所见,标签并不完美。例如,“sql”被标记为“JJ”——形容词。但它仍然足以帮助我们筛选有用的单词。

我们使用所有关键字的标签列表作为工作描述的过滤器。我们只保留工作描述中具有相同关键字标签的单词。例如,我们将保留工作描述中带有标签“NN”和“JJ”的单词。通过这样做,我们可以从工作描述中过滤掉那些对我们的分析没有帮助的词,比如“the”、“then”。

在这个阶段,我们已经精简了工作描述,这些描述被符号化和缩短了。

保持耐心!我们只需要稍微多处理一下。

第四步:关键词和工作描述的最终处理

在这一步,我们进一步处理关键字列表和工作描述。

词干分析

词干化 是将屈折(或有时派生)的单词简化为其词干、词根或词根形式(通常是书面单词形式)的过程。

词干处理允许计算机程序识别同一个词干的单词,尽管它们看起来不同。这样,我们就可以匹配单词,只要它们有相同的词干。例如,单词“模型”、“建模”都有相同的词干“模型”。

我们列出了关键字和精简的工作描述。

小写单词

最后,我们通过小写来规范所有的单词。我们只将工作描述小写,因为关键字列表是小写的。

如前几节所述,前面过程中使用的 Python 代码如下。

现在,只有与我们的分析相关的工作描述中的单词(记号)保留了下来。下面是最终工作描述的一个例子。

终于了,我们准备好关键词匹配了!

第五步:匹配关键词和工作描述

为了查看职位描述是否提到了特定的关键字,我们将关键字列表与最终精简的职位描述进行匹配。

工具/技能

您可能还记得,我们构建了两种类型的关键词列表——单词列表和多词列表。对于单字关键词,我们通过集合交集函数将每个关键词与职位描述进行匹配。对于多词关键字,我们检查它们是否是工作描述的子字符串。

教育

对于教育程度,我们使用与工具/技能相同的方法来匹配关键词。然而,我们只记录最低水平。

例如,当“学士”和“硕士”这两个关键词同时出现在一份工作描述中时,学士学位就是这份工作所需的最低学历。

更详细的 Python 代码如下。

步骤 6:可视化结果

我们用柱状图总结结果。

对于工具/技能/教育水平的每个特定关键词,我们会计算与之匹配的职位描述的数量。我们也计算他们在所有工作描述中的百分比。

对于工具和技能列表,我们只列出了最受欢迎的前 50 个。对于学历层次,我们按照最低要求的层次来总结。

详细的 Python 代码如下。

最受欢迎的工具

数据科学家的 50 大工具

热门技能需求

数据科学家的 50 大技能

最低教育要求

数据科学家的最低教育水平

我们做到了了!

我们希望这篇文章对您有所帮助。留下评论让我们知道你的想法。

同样,如果你想看到详细的结果,请阅读2020 年数据科学家需要哪些技能

如果你有兴趣阅读更多这样的文章,请在 推特关注我们。

更多来自 Lianne & Justin 的数据科学文章:

[## Python 中的数据清理:最终指南(2020)

清洁什么和如何清洁的技巧。

towardsdatascience.com](/data-cleaning-in-python-the-ultimate-guide-2020-c63b88bf0a0d) [## 如何提高体育博彩赔率 Python 中的分步指南

我用数据科学策略在体育上赌了 20,000 美元。

towardsdatascience.com](/how-to-improve-sports-betting-odds-step-by-step-guide-in-python-94626b852f45) [## 如何像老板一样在 Python 中操纵日期和时间

常用的日期时间函数及示例

towardsdatascience.com](/how-to-manipulate-date-and-time-in-python-like-a-boss-ddea677c6a4d)

如何使用 NLP 找到技术工作并赢得黑客马拉松

原文:https://towardsdatascience.com/how-to-use-nlp-to-find-a-tech-job-and-win-a-hackathon-7aa270ec608d?source=collection_archive---------16-----------------------

使用网络抓取、NLP 和 Flask 创建一个技术工作搜索网络应用程序

我和我的前端 web 开发人员 Brandon Franks 最*在一次 30 人团队、30 小时的黑客马拉松中赢得了“解决的最有趣的数据科学问题”奖。我们的获奖作品是一款 Web 应用程序,它从 Indeed.com 收集职位列表,使用自然语言处理(NLP)进行处理,并提供美国前 20 大科技城市的四大科技职位的职位总数、平均工资范围和前 10 大技术技能的汇总

这四个宽泛的技术职位——数据科学家、网络开发人员、UX 设计人员和 iOS 开发人员——包括了与该职位相关的所有职位。因此,网页开发人员包括网页开发人员、前端工程师、PHP 开发人员和许多其他被 Indeed.com 认为是网页开发人员相关的职位。

前 20 大科技城市是根据计算机和数学职业的最高平均工资计算美国前 20 大都会区(MSA)而确定的。Indeed.com 搜索以城市为半径 25 英里,因此搜索结果包括城市的周边地区。

首先,让我们看看成品:

点击此处查看科技求职网应用

虽然 Web 应用程序使用起来非常简单,但它需要大量的幕后数据科学来构建汇总结果。让我们一步一步地完成网页抓取、NLP 和应用程序构建的过程,以便在黑客马拉松 30 小时的时限内将网站变得生动起来。

关于代码的一句话

该项目的所有代码、数据和相关文件都可以在 my GitHub 访问。自述文件提供了 repo 目录和文件的详细信息。网页抓取和自然语言处理使用 Jupyter 笔记本。

网页抓取

Web 抓取代码使用 BeautifulSoup 从 Indeed.com 站点定位并抓取数据。在抓取之前,请务必检查 robots.txt 文件,以确保所抓取的数据是允许的。我们收集的初始数据:

1.职位名称
2。公司
3。位置
4。工资
5。职位描述
6。作业计数

让我们用一段代码来演示这个基本过程。

def extract_job_title(soup):
    jobs = []
    for div in soup.find_all(name="div", attrs={"class":"row"}):
        for a in div.find_all(name="a", attrs={"data-tn-element":"jobTitle"}):
            jobs.append(a["title"])
    return(jobs)city_url = "[https://www.indeed.com/jobs?q=](https://www.indeed.com/jobs?q=)" + title_name + \
           "&l=" + city_name + "%2C+" + st_name + \
           "&start=" + str(start)
page = requests.get(city_url)
soup = BeautifulSoup(page.text, "html.parser")job_title_list.extend(extract_job_title(soup))

在上面的代码中, city_url 是使用职位、城市和州构建的。然后 html 页面被检索并存储在页面变量中。然后,BeautifulSoup 将页面解析成 html 组件,并将它们存储在 Beautiful soup 对象 soup (一个嵌套的数据结构)中。

然后调用 extract_job_title 函数,并将其传递给 soup 对象。 soup.find_all 方法定位适当的 html 并导航到与该值相关联的唯一 html 组件。在这种情况下,职位被发现为子组件in

。你的浏览器检查成为一个必不可少的工具时,网页抓取!

刮擦是费时的。在 4 个职位和 20 个城市的 80 种排列中,每种排列大约需要 3 个小时才能获得 100 个职位。因此,Web 应用程序不是实时的,需要对数据进行预处理并以某种形式存储。因此,从抓取创建的结果数据帧被下载到一个. csv 文件和一个 sqlite DB 表中。的。csv 文件因其易用性和速度最终被应用程序使用。

为每个数据元素创建了类似的函数,并保存到下面的原始数据数据框中:

事实上 _df 数据帧—原始刮擦数据

刮刀的完整代码 scraper.ipynb 可以在这里找到。

自然语言处理

我们现在有了来自网络搜集的原始数据,但我们仍然需要为每个宽泛的职位确定顶级技术术语。职位描述是一大块文本,因此自然语言处理是从每个职位描述中提取关键技术术语的理想方法。一般步骤如下:

  1. 标记化 —获取原始文本,并将其简化为不含非字母数字字符(标记)的小写单词列表。
  2. 去掉停用词——去掉我们可以忽略的常用词(如“我”、“和”、“the”等)。).
  3. 引理化 —将记号转换成它们的基本形式,称为引理(例如,游程、running 和 ran 都是引理游程的形式)。
  4. 减少 —通过大约 100 个技术术语的技术术语字典运行基本令牌,以减少基本令牌的数量。
  5. 计数和排名 —计数基本科技令牌,对其进行排名,并将其作为列表存储在数据帧中。

标记化、删除停用词并词条化

令牌化过程需要两个步骤。清理文本的预处理步骤和实际的标记化步骤。

以下代码片段中的文本清理使用了 BeautifulSoup、replace、regex、sub 和 lower 等方法的组合,将文本转换为小写字母数字单词。

# Clean the text
def clean_text(text):
    text = text.replace('\n', ' ')                # remove newline
    text = BeautifulSoup(text, "lxml").get_text() # remove html
    text = text.replace('/', ' ')                 # remove forward slashes
    text = re.sub(r'[^a-zA-Z ^0-9]', '', text)    # letters and numbers only
    text = text.lower()                           # lower case
    text = re.sub(r'(x.[0-9])', '', text)         # remove special characters
    return textdf['description'] = df.apply(lambda x: clean_text(x['description']), axis=1)

然后使用 spacy 分词器对文本进行分词。Spacy 是用于高级 NLP 的免费开源库。在下面的代码片段中,spacy 记号赋予器用英语语言模型(大号)初始化,并添加任何额外的停用词。在这种情况下,只有“year”被添加到停用字词中,因为我们将在代码的后面删除许多其他字词。

初始化后,使用 tokenizer.pipe 将文本从描述列读入文档。对于每个文档, token.lemma_ 被附加到一个列表中。这为数据帧的每一行产生了一个词条列表。最终的列表随后被添加为名为令牌的列。

# Initialize the tokenizer
nlp = spacy.load("en_core_web_lg")
tokenizer = Tokenizer(nlp.vocab)
STOP_WORDS = nlp.Defaults.stop_words.union(['year'])# Tokenizer pipe removing stop words and blank words and lemmatizing
tokens = []for doc in tokenizer.pipe(df['description'], batch_size=500):

    doc_tokens = []
    for token in doc:
        if (token.lemma_ not in STOP_WORDS) & (token.text != ' '):
            doc_tokens.append(token.lemma_)tokens.append(doc_tokens)df['tokens'] = tokens

将令牌简化为关键技术术语

为了过滤掉尽可能多的“噪音”,创建了一个大约 100 个技术术语的列表,并通过该列表过滤令牌。这将为每个工作列表生成一个技术术语标记列表。

# Tech terms list
tech_terms = ['python', 'r', 'sql', 'hadoop', 'spark', 'java', 'sas', 'tableau',
              'hive', 'scala', 'aws', 'c', 'c++', 'matlab', 'tensorflow', 'excel',
              'nosql', 'linux', 'azure', 'scikit', 'machine learning', 'statistic',
              'analysis', 'computer science', 'visual', 'ai', 'deep learning',
              'nlp', 'natural language processing', 'neural network', 'mathematic',
              'database', 'oop', 'blockchain',
              'html', 'css', 'javascript', 'jquery', 'git', 'photoshop', 'illustrator',
              'word press', 'seo', 'responsive design', 'php', 'mobile', 'design', 'react',
              'security', 'ruby', 'fireworks', 'json', 'node', 'express', 'redux', 'ajax',
              'java', 'api', 'state management',
              'wireframe', 'ui prototype', 'ux writing', 'interactive design',
              'metric', 'analytic', 'ux research', 'empathy', 'collaborate', 'mockup', 
              'prototype', 'test', 'ideate', 'usability', 'high-fidelity design',
              'framework',
              'swift', 'xcode', 'spatial reasoning', 'human interface', 'core data',
              'grand central', 'network', 'objective-c', 'foundation', 'uikit', 
              'cocoatouch', 'spritekit', 'scenekit', 'opengl', 'metal', 'api', 'iot',
              'karma']

df['tokens_filtered'] = df.apply(lambda x: list(set(x['tokens']) & set(tech_terms)), axis=1)

计数和排名

对于每一个职位和城市,科技词汇都会被计算和排名。然后,在数据帧的列表中按排名顺序放置前十个术语。按职位和城市 final_df 汇总的最终数据框架如下:

final_df 数据帧 Web 应用程序中使用的数据

该数据帧被下载到一个. csv 文件中,并提供我们将在 Web 应用程序中使用的数据。

NLP 的完整代码,nlp.ipynb,可以在找到。

烧瓶 App

Flask 是一个简单的 Python Web 开发框架,非常适合像这样的小型项目。本文将不讨论使用 Flask 的细节,但是将提供代码的概述。

代码的基本布局如下:

烧瓶布局

pip 文件为应用程序提供环境和依赖关系。 init。py 文件保存初始化代码,静态目录包含图像、css、javascript 等静态内容,模板目录包含 html 文件。烧瓶应用程序的主要代码包含在 app.py 中,如下所示:

# Import Flask packagefrom flask import Flask, request, render_template
import pandas as pd
import re
import stringdef create_app():
    # Create Flask web server, makes the application
    app = Flask(__name__)# Routes determine location
    [@app](http://twitter.com/app).route("/")
    def home():
        return render_template('index.html')[@app](http://twitter.com/app).route("/search", methods=['GET'])
    def input():
        return render_template('search.html')[@app](http://twitter.com/app).route("/output", methods=['POST'])
    def output():
        df = pd.read_csv('[https://raw.githubusercontent.com/JimKing100/techsearch/master/data/scrape_results1.csv'](https://raw.githubusercontent.com/JimKing100/techsearch/master/data/scrape_results1.csv'))
        df = df.drop(df.columns[0], axis=1)title = request.values['title']
        city = request.values['city']
        result_df = df.loc[(df['job'] == title) & (df['city'] == city)]
        r_title = result_df['job'].iloc[0]
        r_city = result_df['city'].iloc[0]
        r_count = result_df['counts'].iloc[0]
        r_lsalary = result_df['low_salary'].iloc[0]
        r_hsalary = result_df['high_salary'].iloc[0]r_skills = re.sub('['+string.punctuation+']', '', result_df['skills'].iloc[0]).split()return render_template('response.html',
                               title='Search Results',
                               r_title=r_title,
                               r_city=r_city,
                               r_count=r_count,
                               r_lsalary=r_lsalary,
                               r_hsalary=r_hsalary,
                               r_skills=r_skills
                               )[@app](http://twitter.com/app).route("/about")
    def about():
        return render_template('about.html')return app

Flask 使用 routes 为函数分配 URL。因此“/”路由呈现索引或主页,“/about”路由呈现 about 页面,依此类推。当用户从搜索页面的下拉列表中选择一个职位和城市并点击搜索按钮时,POST 方法调用“/output”路径,执行实际的搜索并呈现结果页面。

Python 代码相当简单。加载包含抓取和 NLP 的最终结果的数据帧,请求职务和城市的值,提取基于职务和城市的数据子集,并将结果传递给页面呈现器。

这总结了创建一个获胜的黑客马拉松项目的整个过程!

我欢迎建设性的批评和反馈,请随时给我发私信。

在推特上关注我

这篇文章最初出现在我的 GitHub 页面网站上

【Indeed.com】科技工作数据来源

如何在 Colab 上配合 GPU 使用 OpenCV?

原文:https://towardsdatascience.com/how-to-use-opencv-with-gpu-on-colab-25594379945f?source=collection_archive---------15-----------------------

使用其 NVIDIA GPU 在 Google Colab 上运行 OpenCV 的“dnn”

照片由娜娜杜瓦Unsplash 上拍摄

OpenCV 的‘深度神经网络’(dnn)模块是一个方便的计算机视觉工具,它非常容易应用一些技术,如 Yolo 和 OpenPose。然而,OpenCV 的主要缺点是缺乏 GPU 支持,导致推理速度缓慢。幸好从 OpenCV 4.2 开始,支持 NVIDIA GPU/CUDA。

它仍然需要一些作品使用 GPU,你可以查看 Pyimagesearch 的文章这里,他们演示了如何建立一个 Ubuntu 机器。

如果你和我一样没有带 GPU 的机器,可以考虑用 Google Colab ,这是一个免费的服务,有强大的 NVIDIA GPU。它也更容易设置,大部分的要求已经得到满足。在这篇文章中,我将分享我如何用几行代码为 OpenCV 的dnn设置 Colab 环境。你也可以在这里查看,我根据回答做了细微的改动。

dnn分配给 GPU 的代码很简单:

import cv2
net = cv2.dnn.readNetFromCaffe(protoFile, weightsFile)
net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA)
net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA)

但是,如果您直接在 Colab 上运行该单元格,您将看到以下错误:

所以我们需要做点什么。

如果你在 Colab 上检查预装 OpenCV 的版本,你会看到这个:

我们需要自己安装 cv2。

首先,运行这个单元:

%cd /content!git clone https://github.com/opencv/opencv!git clone https://github.com/opencv/opencv_contrib!mkdir /content/build%cd /content/build!cmake -DOPENCV_EXTRA_MODULES_PATH=/content/opencv_contrib/modules  -DBUILD_SHARED_LIBS=OFF  -DBUILD_TESTS=OFF  -DBUILD_PERF_TESTS=OFF -DBUILD_EXAMPLES=OFF -DWITH_OPENEXR=OFF -DWITH_CUDA=ON -DWITH_CUBLAS=ON -DWITH_CUDNN=ON -DOPENCV_DNN_CUDA=ON /content/opencv!make -j8 install

您将看到类似这样的内容:

这需要一段时间,完成后你可以检查 OpenCV 的版本。

就这样吧!现在你应该能够正确无误地将dnn设置为 CUDA 了。

net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA)
net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA)

但是第一步要花很多时间,每次启动笔记本都需要做。这样很费时间,也不理想。

这里你可以做的一件事是将第一步的结果保存到你的 Google Drive(你必须挂载它)。

!mkdir  "/content/gdrive/My Drive/cv2_gpu"!cp  /content/build/lib/python3/cv2.cpython-36m-x86_64-linux-gnu.so   "/content/gdrive/My Drive/cv2_gpu"

然后在下次启动笔记本时将其复制到您的工作目录中。

!cp "/content/gdrive/My Drive/cv2_gpu/cv2.cpython-36m-x86_64-linux-gnu.so" .

并检查版本以确保完成。

如果你不想安装你的 Google Drive,你可以把它上传到云中的某个地方,然后用!wget把它下载到你的工作目录。

就是这样。感谢阅读。享受 GPU 带来的乐趣。

为什么我使用 Plotly 进行数据可视化

原文:https://towardsdatascience.com/how-to-use-plotly-for-data-visualization-f3d62bbcfd92?source=collection_archive---------27-----------------------

了解商业图表和图形的 Plotly

卢克·切瑟在 Unsplash 上的照片

世界上的数据量每秒都在增长。从发送文本到点击链接,你都在创造数据点供公司使用。从这些数据收集中获得的见解可能非常有价值。每个企业都有自己需要检查的数据存储。完成这种检查的最重要的方法之一是可视化数据。

为什么要可视化数据?

简单来说——“一图抵千言”。在整个商业历史中,数据可视化一直是一个必要的组成部分。它如此必要的原因最终是因为我们是视觉动物。除此之外,你认为为什么我们大多数人更喜欢看改编自一本书的电影,而不是阅读这本书本身?在商业演示方面,销售数据的图表可能比纯文本更有洞察力。从视觉媒介而不是 word 文档中获取洞察力是很容易的。

通过可视化数据,您可以让更广泛的受众更容易访问这些数据。这有助于获得更多的洞察力,因为其他人可能会有一两个你可能从未想过的洞察力。越多的人看到你的视觉化图像,就越有可能获得更多的洞察力。

奥斯汀·迪斯特尔Unsplash 上拍摄的照片

在向董事会成员或股东等关键决策者展示时,可视化也发挥着关键作用。当你构建大量的图表来突出关键数据点时,你决定制作的视觉效果可以帮助这些决策者向一个或另一个方向前进。如果在展示数据视觉效果时考虑了一个精选的叙述,那么这些决策者会倾向于根据你的展示做出具体的决定。

在这里注册一个中级会员,可以无限制地访问和支持像我这样的内容!在你的支持下,我赚了一小部分会费。谢谢!

数据可视化工具

饼图、条形图、折线图等等都是展示数据时的有效视觉效果。这些视觉效果是经过检验的真实的数据呈现形式,我们使创建它们变得更加容易。我们过去用手做的事情现在在电脑上点击几下就可以完成了。

如今,我们可以使用多种程序来构建漂亮的图表。这些工具从更基于技术的可视化应用,如 Python 的 MatplotlibPlotly 到更用户友好的应用,如 Tableau微软 Power BI 。数据可视化工具现在比以往任何时候都更容易使用。

照片由凯蒂·罗德里格斯Unsplash 上拍摄

在 Python 编程领域,有许多不同的库可以用来制作数据可视化。这些库包括但不限于牛郎星海本Plotly 。没有更好的 Python 库,因为这完全取决于你喜欢什么,以及你试图可视化的问题或数据。

学*如何使用 Plotly

我们之前提到的一个工具叫做 Plotly 。Plotly 是一个类似于 Matplotlib 的 Python 图形和绘图库。两者的区别在于,Plotly 可以动态地创建交互式图表和图形。

一个简单的商业问题

要开始使用 Plotly,我们首先需要数据来绘制图表或绘图。比方说,你在一家销售服装的公司工作。他们希望您绘制他们的衬衫和牛仔裤在一年中的销售图表,并为此向您提供了数据。这个问题将帮助我们开始与 Plotly 合作。

安装 Plotly

为了开始,我们必须首先在您的终端中使用以下命令安装 Plotly:

$ pip install plotly

或者如果您安装了 Anaconda :

$ conda install -c plotly plotly

Plotly 导入

现在您已经安装了 Plotly,让我们打开一个新文件,并开始为我们的数据可视化示例导入必要的库:

import plotly.express as px
import calendar as cal
import random
import pandas as pd

这里我们使用的是plotly.express,它是 Plotly 中的一个模块,可以为我们快速创建图形和图表。

创建数据

由于我们实际上没有得到真实的数据,我们将不得不创建自己的数据:

data = {'Months': [cal.month_name[i] for i in range(1,13)],
        'Shirts': [round(random.gauss(100, 15)) for _ in range(12)],
        'Jeans': [round(random.gauss(50, 20)) for _ in range(12)]}

Plotly 与 Pandas 数据框架配合得非常好,因此我们将把新创建的数据存储到 DF:

df = pd.DataFrame(data)

这个新的 DF 看起来像这样:

我们对 Plotly 的 DF

普罗特利条形图

现在我们已经准备好了 DF,我们可以开始制作条形图了:

fig = px.bar(df, 
             x='Months', 
             y=['Shirts','Jeans'])fig.show()

这里我们使用.bar()方法,输入我们数据的 DF,并指定 xy 轴。我们正在制作一个堆叠条形图,为列列表:'Shirts'和'Jeans'。我们将通过调用fig.show()来显示它。

成功!这很简单。这个 Plotly 图表很酷的一点是,你可以通过放大、平移等方式开始与它互动。但是就整个图表而言,我们想要改变一些东西,使这个图表更具描述性,例如添加标题和重命名一些标签。

fig = px.bar(df, 
             x='Months', 
             y=['Shirts','Jeans'],
             title='Total Monthly Item Sales',
             labels={'variable': 'Item',
                     'value': 'Quantity Sold (in thousands)'})fig.show()

这段代码与之前代码的不同之处在于增加了title=labels={}参数。有了这些新的参数,我们为图表添加了一个标题,在labels下面,我们基本上使用了一个字典来替换当前的两个标签。

更新了带有正确标签和标题的条形图

现在条形图已经被正确标记,我们基本上已经完成了对这些数据使用 Plotly。但是,如果我们想要制作其他类型的图表或图形,以便查看数据的不同方面,该怎么办呢?

普洛特利线图

Plotly 也允许我们创建其他类型的可视化。我们可以使用之前的代码轻松创建一个线图,只需更改一点:

fig = px.line(df, 
              x='Months', 
              y=['Shirts','Jeans'],
              title='Monthly Item Sales',
              labels={'variable': 'Item',
                      'value': 'Quantity Sold (in thousands)'})fig.show()

我们在这里所做的只是将px.bar改为px.line。这会显示以下内容:

具有相同数据的折线图

现在我们有了一个线图!但是等等,还有更多…

普罗特利饼图

假设我们想比较全年卖出了多少件衬衫和多少条牛仔裤。

首先,我们必须更改数据以显示衬衫和牛仔裤的总销售额:

pie_df = df[['Shirts','Jeans']].sum()

这里我们只是从 DF 中得到ShirtsJeans的和。然后,我们将需要使用px.pie()使用我们新总结的 DF。

fig = px.pie(values=pie_df.values, 
             names=pie_df.index, 
             title="Sales Percentage in a Year")fig.show()

参数values用于确定饼图每个部分的大小。names是每个部分的标签。

我们的数据饼状图

厉害!现在我们已经为我们的数据创建了三种不同类型的可视化。但是你不必停下来——如果你觉得有必要继续尝试 Plotly,还有更多选项可用( 查看这里了解更多 )。

数据洞察和结论

在可视化我们的数据之后,我们需要根据视觉效果得出某种见解或结论。根据这些图表,你能看出什么?有没有一些显而易见的结论可以得出?一些不那么明显的呢?

无论如何,见解和结论更容易看到而不是阅读。如果你仍然想知道可视化的重要性,那么就回头看看我们创建的 DF,并将其与我们用 Plotly 创建的任何视觉效果进行比较。有时候看资料不如看资料。

如何使用 Plotly.js 进行数据可视化

原文:https://towardsdatascience.com/how-to-use-plotly-js-for-data-visualization-46933e1bbd29?source=collection_archive---------24-----------------------

从 40 多种图表类型中选择

卢克·切瑟在 Unsplash上的照片

在*年来,数据可视化已经成为医疗保健、非营利组织和许多其他部门决策的主要工具之一。通过使用数据可视化,如图表和地图,我们可以用图形表示数据。它帮助人们根据趋势和模式做出快速判断。

互联网上有许多数据可视化工具。在这些工具的广泛列表中, plotly.js 就是其中之一。这是一个基于 d3.jsstack.gl 构建的 JavaScript 开源图形库。这个库提供了各种各样的图表类型,包括 3D 图表、图形和 SVG 地图。

我已经使用 plotly.js 创建了仪表板,通过其丰富的图形库中的交互式图表来可视化数据。与其他库相比,我更喜欢 Plotly.js,因为它易于使用,并且有健壮的文档。从这篇文章中,你将学到一些 plotly.js 的基本概念和命令,它们将教会你如何可视化数据。

设置

首先,我们需要在 HTML 文件中添加 plotly.js。你可以下载文件或者使用 CDN 链接。这里,为了方便起见,我们将使用 CDN 链接。之后,我们需要一个名为 test 的空 DIV 来附加图表。最后,我们需要添加一些 JavaScript 代码来绘制图表。现在将下面的代码保存在一个 HTML 文件中,比如test.html

通过在您的浏览器上加载这个文件,您可以看到一个如下图所示的线形图。如果您看不到任何内容,请尝试打开浏览器的开发人员控制台。它将帮助您调试问题。

折线图

现在让我们将脚本标签分解成单独的部分。首先,我们有包含散列的data数组。在散列中,我们有两个键值对xy,分别代表x-axisy-axis的值。接下来是一个layout散列,这里我们定义了图表的字体大小。config散列用于向图表添加额外的配置。因为我们希望图表具有响应性,所以我们将 responsive 设置为 true。您可以在此找到关于配置的更多信息。现在我们需要将图表添加到 HTML 元素中。在这种情况下,它是一个DIV with id test。最后,我们可以使用Plotly.newPlot方法创建图表,方法是将 DIV DOM 元素、数据数组、布局和配置散列作为参数传递。

我们再来看几个例子。

地图

首先,我们需要定义数据 URL。Plotly.d3.json方法可以从提供的 URL 读取 JSON 数据。我们可以在data数组的散列中使用type键来配置图表类型。散列还接受latitudelongitudehoverinfo数据。hoverinfo用于当悬停在地图坐标上时显示信息。这里我们显示的是纬度和经度信息。你可以在这里找到更多选项。在layout散列中,我们有mapboxmarginmapbox的选项不言自明。如果您正在寻找更多的边距设置,请查看此处的config散列包含mapboxAccessTokenresponsive密钥。你可以在这里从获取令牌值,我们已经讲过了responsive key 的使用。

通过在浏览器上运行上面的代码,我们可以看到如下图所示的地图。

地震数据

饼图

为了创建饼图,我们可以在data数组的散列中使用type键来配置图表类型。我们还需要定义每个切片的值。为此,我们需要使用valueslabels作为键。

通过在浏览器上运行上面的代码,我们可以看到一个类似下面的饼状图。

学生成绩

条形图

为了创建条形图,我们可以在data数组的散列中使用type键来配置图表类型。我们还需要定义每个条形的值。为此,我们需要使用xy作为键。

通过在浏览器上运行上述代码,我们可以看到如下所示的条形图。

学生成绩

气泡图

为了创建气泡图,我们可以在data数组的散列中使用mode键来配置模式类型。我们还需要定义每个圆的中心值。为此,我们需要使用xy作为键。使用size键设置圆圈的大小。如您所见,最后一个圆不可见,因为我们没有提供大小。

通过在浏览器上运行上面的代码,我们可以看到一个类似下图的气泡图。

包裹

数据分析是许多企业的重要组成部分。当处理数据变得更容易时,我们可以改善我们的判断和决策,当我们有一种有效的方法来显示数据时,这是可能的。Plotly.js 是实现商业的一个很好的工具。它可以帮助您发现隐藏的见解,否则使用传统方法很难发现。我希望这篇文章能帮助你开始使用 plotly.js。

如何将 Pyspark 用于您的机器学*项目

原文:https://towardsdatascience.com/how-to-use-pyspark-for-your-machine-learning-project-19aa138e96ec?source=collection_archive---------24-----------------------

使用 Pyspark 进行数据清理、EDA、特征工程和机器学*

来源:https://unsplash.com/photos/Q1p7bh3SHj8

Pyspark 是一个支持 Apache Spark 的 Python API,Apache Spark 是一个用于处理大数据分析的分布式框架。当您处理大型数据集时,这是一个令人惊叹的框架,它正在成为任何数据科学家的必备技能。

在本教程中,我将介绍如何使用 Pyspark 来做你*惯在 Kaggle 笔记本上看到的事情(清洁、EDA、特征工程和构建模型)。

我为一家电信公司使用了一个包含客户信息的数据库。目标是预测未来三个月哪些客户会离开(流失)。包含数据的 CSV 文件包含超过 800,000 行和 8 个特征,以及一个二进制变动变量。

这里的目标不是找到最佳解决方案。而是向您展示如何使用 Pyspark。在这个过程中,我将尝试展示许多可用于您机器学*项目所有阶段的功能!

让我们首先创建一个 SparkSession,这是任何 Spark 功能的入口点。

import pyspark
from pyspark.sql import SparkSessionspark = SparkSession.builder.master("local[4]")\
       .appName("test").getOrCreate()

获取数据

以下是如何使用 Pyspark 读取 CSV 文件。

df=spark.read.csv('train.csv',header=True,sep= ",",inferSchema=True)

这是数据帧的样子。

清理数据

Pyspark.sql 模块允许您在 Pyspark 中做几乎任何可以用 sql 做的事情。

例如,让我们先清理一下数据。首先,如上图所示,我们有一些空值。我将删除所有包含空值的行。

df = df.na.drop()

然后,when/otherwise 函数允许您过滤一列,并根据每行中找到的内容分配一个新值。举个例子,我用 0 和 1 代替男性和女性作为性别变量。

from pyspark.sql.functions import when
df = df.withColumn("gender",when(df["gender"]=='M',0).otherwise(1))

探索性数据分析

一旦数据全部清理完毕,许多类似 SQL 的函数可以帮助分析数据。

例如,groupBy函数允许您对值进行分组,并为每个类别返回 count、sum 或其他值。让我们看看有多少数据点属于流失变量的每个类。

df.groupBy('churnIn3Month').count().show()

我们这里有不平衡的班级。虽然我不会在本教程中做任何事情,但在接下来的一个教程中,我将向您展示如何使用 Pyspark 处理不平衡的类,如欠采样、过采样和 SMOTE。

另一件有趣的事情是观察两组(离开的客户和没有离开的客户)之间某些特征的不同。我发现了一个有趣的结果。

**from** pyspark.sql.functions **import** avg
df.select("phoneBalance","churnIn3Month").\
          groupBy("ChurnIn3Month").agg(avg("phoneBalance"))

我们看到,离开的客户平均手机余额少得多,这意味着他们的手机更接*完全支付(这当然使他们更容易离开电话公司)。

现在,让我们来看一个相关矩阵。我使用 Pyspark 中的correlation函数创建了它。我也做了一点手脚,在这里用了熊猫,只是为了更容易地创造一些视觉上的东西。

from pyspark.ml.stat import Correlationx=df.columns[2:11]
corr_plot = pd.DataFrame()for i in x:
    corr=[]
    for j in x:
        corr.append(round(df.stat.corr(i,j),2))
    corr_plot = pd.concat([corr_plot,pd.Series(corr)],axis=1)corr_plot.columns=x
corr_plot.insert(0,'',x)
corr_plot.set_index('')

同样,phoneBalance与客户流失变量的相关性最强。

特征工程

考虑到上面的结果,我决定创建一个新变量,它将是phoneBalance变量的平方。下面是如何用 Pyspark 做到这一点。

from pyspark.sql.functions import col, pow
df = df.withColumn('phoneBalance2',pow(col('phoneBalance'),2))

withColumn函数允许您向 pyspark 数据框架添加列。超级有用!

机器学*

Pyspark 中的机器学*库肯定还没有达到 Scikit Learn 的标准。也就是说,你仍然可以用它做很多事情。

然而,你要做的第一件事是创建一个包含你所有特征的矢量。我们将使用的所有方法都需要它。

from pyspark.ml.feature import VectorAssemblerignore=['churnIn3Month', 'ID','_c0']
vectorAssembler = VectorAssembler(inputCols=[x for x in df.columns  
                  if x not in ignore], outputCol = 'features')new_df = vectorAssembler.transform(df)
new_df = new_df.select(['features', 'churnIn3Month'])

然后,让我们将数据分成训练集和验证集。

train, test = new_df.randomSplit([0.75, 0.25], seed = 12345)

好了,现在让我们建立一些模型。我将只展示几个模型,只是为了让您了解如何使用 Pyspark。

1.逻辑回归

from pyspark.ml.classification import LogisticRegressionlr = LogisticRegression(featuresCol = 'features', 
                         labelCol='churnIn3Month')
lr_model = lr.fit(train)

我们可以看看模型的 ROC 曲线。提醒一下,AUC(曲线下面积)越接* 1,模型就越能区分不同的类别。

import matplotlib.pyplot as pltplt.plot(lr_model.summary.roc.select('FPR').collect(),
         lr_model.summary.roc.select('TPR').collect())
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.show()lr_model.summary.areaUnderROC

2.随机森林分类器

让我们再做一个模型,展示一旦数据以 Pyspark 的正确格式,即向量,拟合模型是多么容易。下面是如何创建一个随机森林模型。

from pyspark.ml.classification import RandomForestClassifierrf = RandomForestClassifier(featuresCol = 'features', labelCol = 
                            'churnIn3Month')
rf_model = rf.fit(train)

下面是如何获得模型的 AUC:

from pyspark.ml.evaluation import BinaryClassificationEvaluatorpredictions = rf_model.transform(test)
auc = BinaryClassificationEvaluator().setLabelCol('churnIn3Month')
print('AUC of the model:' + str(auc.evaluate(predictions)))

这两个模型非常相似,但结果表明,在我们的情况下,逻辑回归模型略好。

结论

Scikit Learn 非常棒,只要您不处理太多数据,它的表现就会令人钦佩。可悲的是,你的项目越大,你就越有可能需要 Spark。幸运的是,正如您在这里看到的,开始使用 Pyspark 的学*曲线并不太陡,尤其是如果您熟悉 Python 和 SQL 的话。在我看来,Pyspark 的主要弱点是数据可视化,但希望随着时间的推移,这种情况会有所改变!

这就是了。对于想用 Pyspark 进行机器学*的人来说,这篇文章应该是一个很好的起点。我希望你喜欢它,并感谢阅读!

如何使用 Python 和 MissForest 算法估算缺失数据

原文:https://towardsdatascience.com/how-to-use-python-and-missforest-algorithm-to-impute-missing-data-ed45eb47cb9a?source=collection_archive---------6-----------------------

使用随机森林处理丢失数据的分步指南

缺失值填补是数据科学和机器学*中的一个古老问题。技术从简单的均值/中值插补发展到基于机器学*的更复杂的方法。方法选择对最终结果有多大影响?事实证明,很多

岩田良治Unsplash 上拍摄的照片

如果你更喜欢视频,这里也有适合你的东西:

缺失森林视频的缺失数据填补

让我们弄清楚一些事情——缺失值插补通常是特定于域的。例如,由于客户没有使用某些服务,数据集可能包含缺失值,因此插补是错误的做法。

此外,像均值/中值/众数插补这样的简单技术通常效果不佳。原因很容易解释。极值会影响数据集中的平均值,尤其是平均值。此外,用相同的值填充 10%或更多的数据听起来不太妙,至少对于连续变量来说是这样。

这篇文章的结构如下:

  • KNN 插补的问题
  • 什么是 MissForest?
  • 实践中的失误
  • 错误森林评估
  • 结论

KNN 插补的问题

甚至一些基于机器学*的插补技术也有问题。例如,KNN 插补法是简单平均插补法的一个很好的开端,但也带来了一些问题:

  • 您需要为 K 选择一个值——这对于小型数据集来说不成问题
  • 对异常值很敏感,因为它使用表面下的欧几里得距离
  • 不能应用于分类数据,因为需要某种形式的数字表示转换
  • 可能计算量很大,但这取决于数据集的大小

不要误解我的意思,我会选择 KNN 估算法,而不是简单的平均值,但仍然有更好的方法。如果你想了解更多关于这个话题的信息,这里有我最*的一篇文章:

[## 如何用 Python 和 KNN 处理缺失数据

使用机器学*算法处理缺失数据

towardsdatascience.com](/missing-value-imputation-with-python-and-k-nearest-neighbors-308e7abd273d)

什么是 MissForest?

MissForest 是一种基于机器学*的插补技术。它使用随机森林算法来完成任务。它基于迭代方法,并且在每次迭代中生成的预测更好。你可以在下面阅读更多关于算法的理论,因为 Andre Ye 做了很好的解释和漂亮的视觉效果:

[## MissForest:最佳缺失数据插补算法?

告别 KNN-估算

towardsdatascience.com](/missforest-the-best-missing-data-imputation-algorithm-4d01182aed3)

这篇文章更多的是针对的实际应用,所以我们不会过多的钻研理论。总的来说,误盗非常好,因为:

  • 不需要大量的数据准备,因为随机森林算法可以确定哪些特征是重要的
  • 不需要任何调整—就像 K-最*邻中的 K
  • 不关心分类数据类型—随机森林知道如何处理它们

接下来,我们将深入研究一个实际的例子。

实践中的失误

我们将使用虹膜数据集进行实践部分。数据集不包含任何缺失值,但这是关键所在。我们将随机产生缺失值,因此我们可以稍后评估 MissForest 算法的性能。

在我忘记之前,请从终端执行pip install missingpy来安装所需的库。

太好了!接下来,让我们导入 Numpy 和 Pandas,并读入提到的 Iris 数据集。我们还将制作数据集的副本,以便稍后我们可以使用真实值进行评估:

代码片段 1 —导入和数据集加载

作者图片

好了,现在让我们制作两个唯一随机数列表,范围从零到虹膜数据集的长度。通过一些熊猫操作,我们将根据随机生成的索引位置,用 NaNs 替换sepal_lengthpetal_width的值:

代码片段 2 —缺失数据生成

作者图片

如您所见,petal_width只包含 14 个缺失值。这是因为随机化过程产生了两个相同的随机数。这不会给我们带来任何问题,因为最终缺失值的数量是任意的。

下一步是,嗯,进行插补。我们还必须从图片中移除目标变量。方法如下:

代码片段 3—缺失数据插补

就是这样—缺失值现在被估算!

但是我们如何评价这该死的东西呢?这是我们接下来要回答的问题。

错误森林评估

为了执行评估,我们将使用我们拷贝的、未接触的数据集。我们将添加两个额外的列,表示来自 MissForest 算法的估算列——都用于sepal_lengthpetal_width

然后我们将创建一个新的数据集,只包含这两列——原始状态和估算状态。最后,我们将计算绝对误差,以便进一步检查。

代码如下:

代码片段 4 — MissForest 评估

如您所见,代码的最后一行只选择了进行插补的行。让我们来看看:

作者图片

所有的绝对误差都很小,在原始平均值的一个标准偏差之内。如果不考虑增加的小数位,估算值看起来很自然。如果需要,可以很容易地修复。

离别赠言

这是一篇关于用机器学*方法进行缺失值插补的简短扼要的文章。你已经了解了为什么机器学*在这个领域优于简单的平均水平,以及为什么 MissForest 优于 KNN imputr。

我希望这对你来说是一本好书。保重。

喜欢这篇文章吗?成为 中等会员 继续无限制学*。如果你使用下面的链接,我会收到你的一部分会员费,不需要你额外付费。

[## 通过我的推荐链接加入 Medium-Dario rade ci

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

medium.com](https://medium.com/@radecicdario/membership)

原载于 2020 年 11 月 5 日 https://betterdatascience.com

如何有效地使用 Python 类

原文:https://towardsdatascience.com/how-to-use-python-classes-effectively-10b42db8d7bd?source=collection_archive---------5-----------------------

当一堆功能对你来说是更好的选择时

做事的方式应该只有一种。但是上课的时候会很混乱。照片由妮可·沃尔夫Unsplash 拍摄

“T“T这里应该只有一种——最好只有一种——显而易见的方法”,Python 的禅如是说。然而,在有些领域,即使是经验丰富的程序员也在争论什么是正确或错误的做事方式。

其中一个领域是 Python 类。从面向对象编程中借鉴来的,它们是非常漂亮的构造,可以在编码时扩展和修改。

最大的问题是,类会使你的代码比必要的更复杂,更难阅读和维护。那么什么时候应该使用类,什么时候应该使用标准函数呢?

这个故事是对这个问题的更深入的探究。所以如果你很急,你可以跳过下面的两个部分,直接向下滚动到第部分,什么时候使用类部分,当类不是一个好主意的时候。

Python 类:非常基础

类是允许您将数据结构和过程分组到一个地方的对象。例如,假设您正在编写一段代码来组织服装店的库存。

您可以创建一个类,获取商店中的每件衣服,并存储关键数量,如衣服的类型、颜色和尺寸。我们还将添加一个选项来添加价格。

class Clothing(object):
    def __init__(self, type, color, size, price=None):
        self.type = type
        self.color = color
        self.size = size
        self.price = price

现在,我们可以定义该类的各种实例,并将它们组织起来:

bluejeans = Clothing("jeans", "blue", 12)
redtshirt = Clothing("t-shirt", "red", 10, 10)

我们将在类的定义之后添加这两行没有缩进的内容。这段代码将会运行,但是它不会做太多。我们可以在类定义中的__init__函数下直接添加一个设置价格的方法:

 def set_price(self, price):
 *"""Set the price of an item of clothing."""*        self.price = price
        print(f"Setting the price of the {self.color} {self.type} to ${price}.")

我们还可以添加一些例程来告诉我们价格,或者通过降低价格来促销商品:

 def get_price(self):
 *"""Get the price of an item of clothing, if price is set."""*        try:
            print(f"The {self.color} {self.type} costs ${self.price}.")
        except:
            print(f"The price of the {self.color} {self.type} hasn't been set yet!") def promote(self, percentage):
 *"""Lower the price, if initial price is set."""*        try:
            self.price = self.price * (1-percentage/100)
            print(f"The price of the {self.color} {self.type} has been reduced by {percentage} percent! It now only costs ${self.price:.0f}.")
        except:
            print(f"Oops. Set an initial price first!")

现在,我们可以在初始化该类实例的行之后添加一些方法调用:

print("blue jeans -------------------")
bluejeans.promote(20)
bluejeans.set_price(30)
bluejeans.get_price()print("red t-shirt ------------------")
redtshirt.get_price()
redtshirt.promote(20)

如果运行该脚本,输出将如下所示:

blue jeans -------------------
Oops. Set an initial price first!
Setting the price of the blue jeans to $30.
The blue jeans costs $30.
red t-shirt ------------------
The red t-shirt costs $10.
The price of the red t-shirt has been reduced by 20 percent! It now only costs $8.

如果你需要添加更多的例程,你可以把它们放在类定义中。

最棒的是,你可以添加和删除任意多的对象。删除属性的过程如下:

del redtshirt.price 

如果你想删除整个对象,你可以这样做:

del redtshirt

所有这些都是整洁、简单和可扩展的。试着用标准函数来实现,你可能会遇到更多的麻烦。

从理论的角度来看,有更多的理由说明 Python 类在许多情况下是一个美丽的概念。

正确使用时,类是强大的概念。Muhannad Ajjan 在 Unsplash 上拍摄的照片

理论上来说,课堂是很神奇的

关注点分离:给每个类分配自己的工作

如果你参加过计算机科学的讲座,很可能你已经偶然发现了“关注点分离”的原则。这基本上意味着你把你的程序分成不同的部分来处理不同的信息。

从本质上来说,类允许你遵守这个原则。换句话说,当你开始写一个程序,并且你在考虑类的时候,你可能在构建一个好的架构,因为你确保了每个问题都有自己的位置。

解耦:使维护更容易

在类中思考不仅有助于保持特性的分离,还能使它们相互独立。这不仅能保持物品的整洁;维护起来也方便了很多。

假设您在一个类中发现了一个 bug:您可以修复这个 bug,而不用担心其他类,因为它们之间没有联系。同样,你可以添加新的特性,而不用担心会与软件的其他部分纠缠在一起。

实现隐藏:定义程序员能使用什么,不能使用什么

通过使用类,您可以确保方法只用于一组数据。这增加了代码的安全性,因为您不太可能在不属于它们的地方使用函数。

封装:改变代码,但不改变用户体验

将数据结构和方法存储在一起也称为封装。由于所有这些对最终用户都是隐藏的,这允许您修改数据结构和方法,而不会损害用户体验。

例如,您可能需要构建一个非常复杂的方法。封装的优点是用户不需要理解任何复杂性,因为他们可以像使用黑盒一样使用它。

不使用类来构建黑盒函数是完全可能的。然而,对于类,这种类型的功能实际上是可以保证的。

继承:编写数据结构的 DNA

有了类,你只需要定义一个数据结构一次。当定义一个类的实例时,该实例自动继承给定的结构。

此外,继承使得删除或修改实例或整个类变得非常容易。这使得整个结构更加灵活。

[## 编写更好的 Python 代码的终极指南

让你的软件更快、更易读和更易维护并不需要这么难

towardsdatascience.com](/the-ultimate-guide-to-writing-better-python-code-1362a1209e5a)

何时使用类

有了这么多的优点,用一个类来做任何事情都很有诱惑力。然而,在实践中,有些情况下使用类非常有意义,而有些情况下则没有意义。

将数据和方法组合在一起

根据经验,当您有一组具有特定结构的数据,并且希望对其执行特定的方法时,请使用类。然而,只有在代码中使用多种数据结构时,这才是有效的。

如果你的整个代码不会处理一个以上的结构。如果你只有一种数据结构,那就真的要看手头的问题了。你可以通过有没有上课勾画出你的程序来得到一个大概的想法;通常你会很快发现哪个解决方案更简单。

当心全局变量

另一个经验法则是这个:如果你想使用全局变量来访问数据,定义一个类并构建一个方法来访问每一段数据可能更容易。

上课并不总是一个好主意。照片由克里斯蒂娜@ wocintechchat.comUnsplash 上拍摄

当上课不是个好主意时

对堆使用 heapq

与堆栈不同,是一种更灵活的存储数据的方式,因为它有无限的内存大小,并允许您调整变量的大小。另一方面,使用堆访问变量速度较慢,并且您必须自己管理内存。

如果一个堆更适合你的目的,你不需要定义一个类。Python 的内置heapq,或者堆队列算法,为你做了工作

考虑使用 functools.partial()

您可能很想使用一个类,因为您经常用相同的参数调用一个函数。在大多数情况下,用functools.partial()来代替会更好。

实现起来相当简单。假设您有一个将两个值相乘的函数,但是您一直使用它来将两个值加倍。为了避免重复代码,您可以这样写:

from functools import partialdef multiply(x,y):
    return x * ydoubling = partial(multiply,2)
print(doubling(4))

比定义一个新类简单多了!

“面向未来”的课程

一些程序员痴迷于类,因为它们是如此的灵活和可扩展。这就是为什么,即使在声誉良好的公司和经验丰富的开发人员中,您也可能会遇到这样的代码:

class newclass:
    """defining a new class to do something awesome"""
    pass

其背后的思想是,随着代码的增长,无论新的数据结构和方法是什么,都可能需要这个类。但这不是好*惯!

猜猜这三行代码是做什么的?完全没有。这些行并不难编码。如果你认为你以后还需要另一门课,并且你真的认为你将来会忘记它,你可以留下这样的评论:

# initiate a new class here if needed for purpose XY

尽管你想让你的代码具有可扩展性和不傻,初始化一个什么都不做的类通常不是一个好主意。

[## 程序员精疲力竭的 7 个原因

和 7 种解决方法

towardsdatascience.com](/7-reasons-why-programmers-burn-out-44a40bf8948d)

底线是:Python 类是一把双刃剑

毫无疑问,阶级是一个强大的概念。正确使用,它们可以使你的代码更整洁,更可读和可维护。

但是它们被过度使用了。如果使用不当,它们会污染你的代码,直到你什么都不懂。

有时,特别是在简单的程序中,你可以使用一个类或一组通用函数,代码在长度和复杂性上非常相似。随着程序变得越来越复杂,差异变得越来越突出。

从这个意义上来说,Python 的禅坚持了它的结论:大多数时候,确实只有一种好的做事方式,不管有没有类。然而,这并不总是完全显而易见的。困难的部分是认识到哪条路是好的。

如果你有其他关于 Python 或其他编程语言的问题,请在评论中告诉我!感谢 卢卡斯·苏亚雷斯 询问何时使用类,何时不使用类的技巧。

如何在 iPad 上使用 Python

原文:https://towardsdatascience.com/how-to-use-python-on-ipad-9a9bd97c40?source=collection_archive---------3-----------------------

了解如何使用 iPad 创建 Python 脚本

对于那些一直在阅读我的关于 Python 金融的博客和观看我的视频的 T2 的人,我想与你们分享如何使用 iPad 用 Python 编程。

照片由 bongkarn thanyakijPexels

为什么 iPad 要用 Python?

你们中的一些人可能会问,为什么我要把笔记本电脑换成 iPad 来编码呢?从我的角度来看,我不认为 iPad 会取代笔记本电脑进行编码。至少短期内不会。然而,在编码方面,它可以作为笔记本电脑的一个很好的补充。

例如,想象一下,你要去湖边的某个地方度周末,而你不想带着电脑和充电器。在这种情况下,如果你想在周末假期继续写代码,唯一的选择就是带上 iPad。

如何在 iPad 上使用 Python 编码?

根据我的经验,到目前为止,我发现在 iPad 上使用 Python 的最好方式是通过 Google Colab 。这是一个免费工具,所有拥有 Gmail/Google 账户的人都可以使用。

Google Colab 提供与 Jupyter notebook 相同的功能。 Colab 允许您在浏览器中编写和执行 Python,主要优势是:

  • 不需要预先设置。它预装了大量的软件包。即 Pandas、Numpy、TensorFlow、Scikit-learn、Matplotlib 等众多。我们可以简单地通过导入包来使用它们。
  • 脚本在所有设备中都可用。也就是说,可以在笔记本电脑和 iPad 上访问和编辑相同的脚本。
  • 免费访问 GPU。
  • 代码和脚本可以很容易地与他人分享。创建的脚本可以上传到 Github,也可以作为下载到本地磁盘。py 扩展名。
  • 最棒的是,它完全免费,让我们可以在 iPad 上用 Python 编程。

总而言之,我认为 Google Colab 是一个很好的工具,可以用来进行金融分析或任何其他数据科学项目。我在 Medium 上发布的所有文章都是使用 Google Colab 或 Jupyter Notebook 完成的。这意味着它们都可以用 iPad 复制。

如何设置 Google Colab?

为了开始在 iPad 上使用 Python,我们需要有一个 Google drive 帐户。 Google Drive 提供免费云存储供个人使用。你可以在这里创建一个免费账户

创建帐户后,要在 iPad 中开始编码,需要遵循以下步骤:

  1. 使用浏览器登录 iPad 中的 Google Drive。然后,通过点击 New 创建一个新的 Colab 文档:

2.选择更多谷歌联合实验室。如果您在列表中没有看到 Google 协同实验室,请点击连接更多应用将其安装到您的 Google Drive 中。

3.一个新的 Google Colab 文档将会打开,我们可以在其中添加代码或文本:

4.以下是文件的主要部分。单击 1 重命名文档。2 和 3 允许您为编码或简单文本编辑添加新的单元格。4 是我们可以输入 Python 代码的单元格。一旦脚本准备就绪,单击 5 运行该单元格中的代码。最后,使用工具栏(6)保存或下载您的代码。

5.开始输入您的代码。下面以一个简单的例子来创建一个熊猫数据框架:

6.点击播放按钮,运行单元格以执行代码。结果显示在单元格下方:

包扎

正如我们所看到的,在 iPad 上开始使用 Python 是非常容易的。然而,出于两个原因,我不认为我的 iPad 会取代我的笔记本电脑来完成我的 Python 项目。:

  • 首先,也是最重要的,对我来说,用 iPad 屏幕键盘写代码效率非常低。与使用普通键盘相比,我的速度更慢,也更容易出错。如果使用 iPad Magic Keyboard 的体验有所改善,我会在以后的帖子中分享我的体验。
  • 第二个原因是,与我的笔记本电脑或台式电脑相比,我的 iPad 屏幕较小。

然而,有时,特别是当我不得不旅行时,我用我的 iPad 进行 Python 编码,它的工作就像我在计算机中编码一样。请随意发表您的评论,分享您使用 iPad 编码的经验,以及您使用的是哪一款应用程序。

我还有一个 Youtube 视频短片,是关于如何用 iPad 用 Python 编程的:

如何使用 iPad 编写 Python 代码

原载于 2020 年 5 月 24 日 https://codingandfun.com**T21

如何使用 Python Seaborn 进行探索性数据分析

原文:https://towardsdatascience.com/how-to-use-python-seaborn-for-exploratory-data-analysis-1a4850f48f14?source=collection_archive---------17-----------------------

通过直方图、热图、散点图、条形图等浏览示例数据集

来源: Unsplash

这是一个使用 Pythonseaborn 库进行探索性数据分析(EDA) 的教程。

EDA 是数据分析(或机器学*/统计建模)中除了Python 中的数据清洗:终极指南(2020) 之外的另一个关键过程。

在本指南中,您将发现(通过示例):

  • 如何使用 seaborn Python 包生成有用且漂亮的可视化效果,包括直方图、条形图、散点图、箱线图和热图。
  • 如何用不同的图探索单变量、多变量数值和分类变量
  • 如何发现多个变量之间的关系
  • 更多。

我们开始吧!

什么是探索性数据分析(EDA),为什么?

探索性数据分析 ( EDA )是一种分析数据集以总结其主要特征的方法,通常采用可视化方法。

可以使用或不使用统计模型,但 EDA 主要是为了查看数据可以告诉我们什么,而不仅仅是正式的建模或假设测试任务。

维基百科

在进一步分析或建模之前探索数据是很重要的。在这个过程中,我们可以从数据集获得洞察的概览;我们可以发现不明显的趋势、模式和关系。

什么是 seaborn?

统计数据可视化是一个流行的 Python 库,用于执行 EDA。

它基于 matplotlib 并提供了一个高级接口,用于绘制有吸引力且信息丰富的统计图形。

在这篇文章中,我们将使用一个清理过的 YouTube 数据集作为例子。

在我们之前的文章如何利用机器学*技术获得更多的 YouTube 浏览量中,我们就如何基于同一数据集获得更多的浏览量提出了建议。

在探索之前,让我们将数据读入 Python 作为数据集 df

df 包含 729 行和 60 个变量。它为悉尼的 YouTube 频道内的每个视频录制不同的功能,例如:

  • 浏览量:视频的浏览量
  • 时长:视频/健身程序的时长,以分钟为单位
  • 卡路里:视频中健身过程中消耗的卡路里数
  • days_since_posted :视频发布到现在的天数
  • 日期:视频/锻炼发布的日期
    悉尼几乎每天都会发布一个视频/锻炼
  • 健身程序类型:视频关注的健身程序类型

同样,你可以在如何利用机器学*技术获得更多 YouTube 浏览量中找到更多细节。我们在这里只使用这个数据集。

单变量分析:数值变量

首先,让我们来探讨数值单变量。

我们创建 df_numeric 只是为了包含 7 个数字特征。

直方图:单一变量

直方图是我们最喜欢的图形之一。

直方图是数字数据分布的*似表示。

要构建直方图,第一步是“分格”(或“存储桶”)值的范围,即将整个值范围分成一系列区间,然后计算每个区间内有多少个值。

维基百科

Seaborn 的函数 distplot 有以下选项:

  • :箱设置
    用不同的箱设置绘制变量以发现模式很有用。如果我们不设置这个值,库会为我们找到一个有用的默认值。
  • kde :是否绘制高斯核密度估计
    这有助于估计连续随机变量的概率密度函数的形状。更多细节可以在 seaborn 的页面上找到。
  • 地毯:是否在支撑轴
    上绘制地毯图这将在每个观察点绘制一个小的垂直勾。它有助于了解变量值的确切位置。

让我们先来看一个变量:length,它代表视频的长度。

我们可以在下面的图中看到 kde 线和地毯贴。

悉尼频道的视频通常长度为 30、40 或 50 分钟,呈现多模态模式。

直方图:多个变量

通常,我们希望将多个数值变量可视化并一起查看。

我们构建下面的函数 plot_multiple_histograms 来绘制特定变量组的直方图。

我们可以看到,不同的变量表现出不同形状的分布,异常值,偏度等。

单变量分析:分类变量

接下来,让我们看看分类单变量。

条形图:单变量

条形图(或 seaborn 的计数图)是分类变量版本的直方图。

条形图条形图是一种图表或图形,用矩形条表示分类数据,矩形条的高度或长度与它们所代表的值成比例。

条形图显示离散类别之间的比较。

维基百科

首先,让我们选择分类(非数字)变量。

我们绘制了可变区域的条形图,该区域代表健身程序视频关注的身体区域。

这些视频针对了许多领域。不放大就很难阅读。尽管如此,我们可以看到这些视频中超过一半(超过 400 个)集中在“完整”的身体部位;第二个最受关注的领域是“ab”。

条形图:多个变量

此外,我们创建一个函数plot _ multiple _ count plots来一次绘制多个变量的条形图。

我们用它来绘制一些指标变量如下。

is _ { } _ 区域是不同身体区域的指示变量。例如,当锻炼集中在臀部时,is_butt_area == True,否则为 False。

is _ { } _ 健身程序是不同健身程序类型的指示变量。例如,当锻炼侧重于力量时,is_strength_workout == True,否则为 False。

多变量分析

在逐一探究了变量之后,让我们一起来看看多个变量。

不同的图可以用来探索不同变量组合之间的关系。

在最后一节中,您还可以找到一种用于测试多个变量之间关系的建模方法。

散点图:两个数值变量

首先,让我们看看如何发现两个数值变量之间的关系。

如果我们想知道锻炼时间如何影响观看次数,该怎么办?

我们可以用散点图( relplot )来回答这个问题。

散点图使用笛卡尔坐标来显示一组数据的典型的两个变量的值。如果点被编码(颜色/形状/大小),可以显示一个额外的变量。

数据显示为点的集合,每个点的一个变量的值决定水平轴上的位置,另一个变量的值决定垂直轴上的位置。

维基百科

我们可以看到,更受欢迎的视频长度往往在 30 到 40 分钟之间。

条形图:两个分类变量

如果我们想知道两个分类变量之间的关系呢?

让我们来看看视频中最常见的 6 个区域(区域 2 )和最常见的 4 种健身程序类型(workout_type2)。

我们可以看到,视频中最常见的是“全面”的身体“力量”训练。

箱线图:数值和分类变量

盒状图是比较类别组时有用的可视化工具。

盒图 ( 盒须图)是一种基于五个数字汇总显示数据集的标准化方式:最小值、最大值、样本中值、第一个和第三个四分位数。

维基百科

我们可以使用并排箱线图来比较分类变量类别中的数值变量。

悉尼的视频在一周的特定日子里会有更多的浏览量吗?

让我们画出星期几和视图。

这很有趣,但由于离群值的原因很难看到。让我们移除它们。

我们可以看到,周一的视频往往比其他日子有更多的浏览量。而周日视频的浏览量最少。

群集图:数值和分类变量

看待同一个问题的另一种方式是群体图。

一个群集图是一个分类散点图,其中的点被调整(仅沿分类轴)以使它们不重叠。

这更好地表示了值的分布。

seaborn 文档

当我们想要显示所有的观察结果以及一些基本分布的表示时,群图是对盒图的很好的补充。

对于较大的数据集来说,群集图会有太多的点,但对于较小的数据集来说,这样做很好。

箱线图组:数值和分类变量

对于某些锻炼类型,一周中某些天的观看率会更高吗?

要回答这个问题,需要两个分类变量(锻炼类型、星期几)和一个数字变量(视图)。

让我们看看如何将这个问题的答案形象化。

我们可以使用面板箱线图( catplot )将三个变量一起可视化。

catplot 有助于使用几种可视化表示中的一种来显示数值变量与一个或多个分类变量之间的关系。

这是相当混乱的太多种类的锻炼类型。

根据锻炼类型的分布,我们将除“力量”、“hiit”、“伸展”、“有氧运动”之外的其他类别归为“其他”。

此外,我们删除了离群值,使图形更加清晰。

我们可以注意到这样的事情:

  • “伸展”训练仅在周日发布。
  • “hiit”锻炼似乎在周一有更多的观点。

热图:数字和分类变量

我们还可以使用数据透视表和热图来可视化多个变量。

热图是一种数据可视化技术,以二维颜色显示现象的大小。

颜色的变化可能是色调或强度的变化,给读者提供了明显的视觉线索,表明现象是如何聚集或随空间变化的。

维基百科

例如,下面的热图以区域健身 _ 类型类别为轴;色标代表每个单元格中的视图。

(高级)关系检验和散点图:数值和分类变量

我们如何自动发现多个变量之间的关系?

让我们看看下面最关键的特征,看看我们如何找到有趣的关系。

我们有 4 个数字变量和 3 个分类变量。

他们之间可能有许多复杂的关系!

在本节中,我们使用与如何使用机器学*技术获得更多 YouTube 浏览量中相同的方法来测试它们之间的关系(包括多重共线性)。

在高层次上,我们使用 K 倍交叉验证来实现这一点。

首先,我们转换分类变量。由于我们将使用 5 重交叉验证,我们需要确保每个类别级别至少有 5 次观察。

接下来,我们遍历每个变量,并使用其他变量拟合一个模型来预测它。我们使用一个简单的模型梯度推进模型(GBM) 和 K 倍验证。

根据目标变量是数值型还是分类型,我们应用不同的模型和分数(模型预测能力评估指标)。

当目标为数值时,我们使用梯度推进回归器模型和均方根误差(RMSE);当目标是分类的时,我们使用梯度推进分类器模型和精确度

对于每个目标,我们打印出 K 倍验证分数(分数的平均值)和最重要的 5 个预测值。

我们还添加了三个由随机数组成的特征 rand0rand1rand2 。它们在比较变量之间的关系时充当锚。如果一个预测因子与这些随机变量相比不太重要或相似,那么它就不是目标变量的重要预测因子。

从上面的结果中,我们可以看到每个目标变量以及它们与预测值的关系。

同样,可以在如何使用机器学*技术获得更多 YouTube 浏览量中的多重共线性测试部分找到该测试的分步程序。

我们可以看到长度和卡路里之间有很强的关系。

让我们用散点图来形象化它们:x 轴表示长度,y 轴表示卡路里,而点的大小表示视图。

我们可以看到,视频越长,消耗的热量越多,很直观。我们还可以看到,观看次数越多的视频长度越短。

相关文章:

[## 如何用机器学*技术获得更多的 YouTube 浏览量——仅仅是数据

在这篇文章中,我们用 Python 对 YouTube 数据应用了机器学*算法。我们将包括端到端流程…

www.justintodata.com](https://www.justintodata.com/get-more-youtube-views-with-machine-learning/)

上一篇文章使用了相同的数据集。它包含了我们如何抓取和转换原始数据集的细节。

[## Python 中的数据清理:终极指南(2020)——只进入数据

我们用 Python 创建了这个新的完整的分步指南。你将学*如何寻找和清理的技巧:丢失…

www.justintodata.com](https://www.justintodata.com/data-cleaning-python-ultimate-guide/)

本文涵盖了清理的内容以及清理缺失数据、异常值、重复数据、不一致数据等的技术。

感谢您的阅读。

如果你有任何问题,请留言。我们会尽力回答。

离开之前,别忘了 报名参加刚刚进入数据快讯的 !或者在推特脸书上与我们联系。
因此,您不会错过我们的任何新数据科学文章!

原载于 2020 年 4 月 10 日 https://www.justintodata.com

* [## 如何在线学*数据科学:你需要知道的一切——进入数据

这是利用在线资源进入数据科学的完整路线图/课程。你是否想学*…

www.justintodata.com](https://www.justintodata.com/how-to-learn-data-science-online-all-you-need-to-know/) [## 如何利用深度学*进行情感分析(LSTM·克拉斯)——只分析数据

这是利用在线资源进入数据科学的完整路线图/课程。你是否想学*…

www.justintodata.com](https://www.justintodata.com/sentiment-analysis-with-deep-learning-lstm-keras-python/) [## 预测时间序列的三个步骤:LSTM 与 TensorFlow Keras -只是进入数据

这是利用在线资源进入数据科学的完整路线图/课程。你是否想学*…

www.justintodata.com](https://www.justintodata.com/forecast-time-series-lstm-with-tensorflow-keras/)*

如何使用 Python 购买 Robinhood 的期权

原文:https://towardsdatascience.com/how-to-use-python-to-buy-options-from-robinhood-8022bbcf3ddf?source=collection_archive---------13-----------------------

奥斯汀·迪斯特尔Unsplash 上拍摄的照片

只是真的想测试我的编程技能,以搞乱股票。

那么什么是交易中的期权呢?它们是给予你在一段时间内以一定价格购买或出售资产的权利的合同。有些人将期权视为某种彩票,但我认为它就像 21 点,你可以采取某些策略来降低风险。

在本文中,我将创建 Python 代码来查看股票并购买它。为了做到这一点,让我们看看如何选择看起来像。这是一个期权标准报价的例子。

美国广播公司 2020 年 2 月 14 日 69 美元电话,4.20 美元

我们来分析一下。 ABC 是期权所基于的股票,通常代表该股票的 100 股。2020 年 2 月 14 日 代表期权即将到期的月份。 69 是股票的执行价格。 会是其中的一个选项类型,这里也可以填入选项。4.20 美元是股票的溢价。

所以到目前为止,在期权交易中,微软的股票对我来说非常好。到目前为止,我已经获得了大量的。你可以在这里看到我的得失。我们将利用微软购买罗宾汉的期权。

我用来从 Robinhood 中提取数据的叫做 robin_stocks 。我有一篇文章展示了如何设置它。

* [## 使用 Python 获取罗宾汉数据

让我们自动化一些股票,可以用来建造一个交易机器人。

towardsdatascience.com](/using-python-to-get-robinhood-data-2c95c6e4edc8)

因此,我对微软股票的交易策略是,我通常在当前日期前 30 天买入期权看涨期权,然后选择高于当前股价的执行价格。

robin_stocks使它变得简单,我们已经可以拉可用的股票期权,我们可以使用find_tradable_options_for_stock.发送给他们,我已经设置了它,它已经拉了下面的调用。

r.options.find_tradable_options_for_stock(‘MSFT’, optionType=’call’)

我喜欢在数据框中查看结果,所以我会将所有这些数据转移过来。结果将如下所示:

既然我们知道了有效日期,我们现在可以发送一个包含正确信息的期权订单。我们将使用这行代码在robin_stocks.orders.order_buy_option_limit(*price*, *symbol*, *quantity*, *expirationDate*, *strike*, *optionType='both'*, *timeInForce='gfd'*)中发送订单

对于价格,我们可以只填写当前的期权价格。对于符号,我们将使用MSFT。数量我们将只购买 1 个合同订单。对于日期,我们将使用从今天(2020 年 2 月 13 日)起的 30 天。因此,我们将尝试选择一个接* 30 天的日期(2020 年 3 月 13 日)。我们将选择一个最接*且高于当前股价的价格。我们想要一个电话。生效时间对一天有利(gfd)。所以我们的代码看起来会像这样,它在 Robinhood 中的翻译是:

robin_stocks.orders.order_buy_option_limit(4.20, 'MSFT*'*, 1, 2020-03-13, 185.00, *optionType='call'*, *timeInForce='gfd'*)

MSFT 2020 年 3 月 13 日 185 电话 4.20 美元

如果我们用 Python 运行这段代码,订单将被发送。然而,这并不一定是命令的执行。下面是完整的代码:*

访问我的微软得失这里

我这里还有家教和职业指导!

如果你们有任何问题、评论或顾虑,请不要忘记通过 LinkedIn 与我联系!

如何在 Google Colab 中使用 R

原文:https://towardsdatascience.com/how-to-use-r-in-google-colab-b6e02d736497?source=collection_archive---------1-----------------------

GOOGLE COLAB | RSTATS |笔记本

并使用来自您的驱动器和 BigQuery 的数据

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

Colab,或 Colaboratory 是 Google(主要)提供的一个交互式笔记本,用于通过浏览器编写和运行 Python。我们可以在 Colab 中执行数据分析,创建模型,评估这些模型。这个过程是在谷歌拥有的云中服务器上完成的。我们只需要一个浏览器和一个相当稳定的互联网连接。

无论是作为学生、专业人士还是研究人员,Colab 都是促进我们工作的一个很好的替代工具。

虽然 Colab 主要用于 Python 中的编码,但显然我们也可以将其用于 R ( #Rstats )。

这篇文章将告诉你如何在 Google Colab 中运行 R,以及如何在 R 笔记本中挂载 Google Drive 或访问 BigQuery。

在 Colab 中运行 R 有两种方法

  • 第一种方法是在 Python 运行时使用 rpy2 包。这个方法允许您一起执行 R 和 Python 语法。
  • 第二种方式是实际上在 R 运行时启动笔记本。

如何在 Colab 中一起使用 R 和 Python

  1. 打开你最喜欢的浏览器。
  2. 创建新笔记本:https://colab.research.google.com/#create=true
  3. 通过执行该命令%load_ext rpy2.ipython运行 rmagic
  4. 之后每次要用 R 的时候,在每个单元格的开头加%%R

通过在单元格中执行以下命令来启动 rmagic :

%load_ext rpy2.ipython

使用%%R执行细胞魔法。如果您希望在 r 中执行单元格中的所有语法,请使用此选项。注意,它必须放在单元格的开头。

%%R
x <- seq(0, 2*pi, length.out=50)
x

这些行将返回一个变量 x ,并将其显示在单元输出上:

图片作者,x

Use 【 to execute 线魔。如果您希望单元格中的一行在 r 中执行,请使用此选项。

下面是如何使用这一行魔法将 R 变量复制到 Python 中:

x = %R x

作者的图像,通过使用 line magic 在 R 和 Python 之间传递变量,并在 Python 中显示 x

如何在 Colab 中使用 R

要直接用 R 使用笔记本:

  1. 打开你最喜欢的浏览器。
  2. 转到这个网址:【https://colab.research.google.com/#create=true】T2&language = r,或者这个短网址【https://colab.to/r】T4

访问 URL 后,您将被带到一个新的 Colab 笔记本,默认标题为 Unitled.ipynb

乍一看,使用 Python 和 R 运行时的笔记本没有区别。然而,如果我们转到“运行时”设置,并选择“更改运行时类型”,我们将得到一个对话框,确认我们已经在 R 运行时。

作者、运行时->更改运行时类型的图像

您还可以通过尝试将您的驱动器安装到笔记本上来确认您处于 R 运行时环境中。这样做,你会得到这样一个不幸的消息:

作者图片,啊哦,我们不能安装我们的谷歌驱动器!

消息“挂载您的 Google Drive 仅在托管 Python 运行时上可用。”明确表示你不是在 Python 运行时。

恭喜你,你现在已经成功地在 Colab 中运行 R 了。可以通过输入R.version.string打印出 R 版本来查看 R 版本。

这里,已经有几个对数据处理和数据可视化有用的包。可以通过运行print(installed.packages())来检查。

如果你在安装软件包时遇到问题,这篇文章可能会帮助你:

[## 如何在 R Google Colab 中安装包

一些限制以及如何克服其中一些限制

towardsdatascience.com](/how-to-install-packages-in-r-google-colab-423e8928cd2e)

如何在 Colab R 运行时挂载 Google Drive

这应该很容易做到。我们只需要安装“googledrive”包并执行认证过程。

install.packages("googledrive")
library("googledrive")

安装包之后,我们需要对 googledrive 包进行认证和授权。您可以在此处阅读软件包文档:

[## Google Drive 的界面

大多数函数都以前缀 drive_ 开头。自动完成是你的朋友。目标是让驾驶人员感觉…

googledrive.tidyverse.org](https://googledrive.tidyverse.org/)

# authorize google drivedrive_auth(
  email = gargle::[gargle_oauth_email](https://gargle.r-lib.org/reference/gargle_options.html)(),
  path = NULL,
  scopes = "https://www.googleapis.com/auth/drive",
  cache = gargle::[gargle_oauth_cache](https://gargle.r-lib.org/reference/gargle_options.html)(),
  use_oob = gargle::[gargle_oob_default](https://gargle.r-lib.org/reference/gargle_options.html)(),
  token = NULL
)

不幸的是,在尝试认证时,过程并不顺利。相反,我们面对的是这样一条错误消息:

图片作者,错误:无法获得谷歌证书。

显然,错误的发生是因为 httr 包中的交互函数无法执行。

这里有一个我们可以使用的变通办法,由 jobdiogene 的提供:https://gist . github . com/jobdiogenes/235620928 c84 e 604 C6 e 56211 CCF 681 f 0

# Check if is running in Colab and redefine is_interactive()
if (file.exists("/usr/local/lib/python3.6/dist-packages/google/colab/_ipython.py")) {
  install.packages("R.utils")
  library("R.utils")
  library("httr")
  my_check <- function() {return(TRUE)}
  reassignInPackage("is_interactive", pkgName = "httr", my_check) 
  options(rlang_interactive=TRUE)
}

运行完那行代码后,我们可以再次尝试验证 Google Drive,现在它可以工作了!

drive_auth(use_oob = TRUE, cache = TRUE)

按作者分类的图像,交互式验证对话框

您需要点击链接并授予包访问您的 Google Drive 的权限。在此之后,您应该能够将授权代码粘贴到代码字段中。

图片由作者提供,授予许可

如何在 Colab R 运行时使用 BigQuery

对于业务人员,或者更*惯使用 R 的研究人员,也许我们需要从公司拥有的 BigQuery 或公开可用的数据集检索数据。

现在我们有了解决方法,授权 BigQuery 并从那里检索数据就很简单了:

install.packages("bigrquery")
library("bigrquery")
bq_auth(use_oob = TRUE, cache = FALSE)

使用自定义查询从 BigQuery 提取数据:

# Store the project id
projectid = "your-project-id"# Set the query
sql <- "SELECT * FROM your_table"# Run the query
project_query <- bq_project_query(projectid, sql, use_legacy_sql = FALSE)# Download result to dataframe
df <- bq_table_download(project_query)

结论

这是我认为我能为数据社区做出的贡献。正如我前面提到的,除了 Kaggle 和 RStudio Cloud 之外,Google Colab 为我们提供了学*或使用 R 的另一种选择。它们都是很好的平台,尤其是用于学*的时候;可以缩短初始设置(下载和安装 R,以及安装包)的时间。尽管在 Google Colab 中使用 R 的方式有点混乱,并且还没有与 Python 运行时相同的服务,但最终,它仍然工作得很好。

感谢阅读!

如果您有任何问题,请拨打 Showwcase 联系我!

如何使用 R Shiny 进行 EDA 和预测

原文:https://towardsdatascience.com/how-to-use-r-shiny-for-eda-and-prediction-72e6ef842240?source=collection_archive---------6-----------------------

奥比·奥尼耶德在 Unsplash 上拍摄的照片

R Shiny 分析、探索和预测自行车共享注册的简单指南

本文的目的是提供一个简单的指南,介绍如何开发一个出色的应用程序来分析、探索和预测数据集中的变量。

文章的第一部分涵盖了 R 闪亮的基础知识,比如对其功能的解释。此外,我将开发一个交互式图表形式的自行车共享数据的探索性数据分析。然后,我将创建一个预测模型,通过考虑天气条件和一年中的特定日子来帮助应用程序的用户预测系统中自行车注册的总数。

此外,我将在数据集包含的信息的上下文中描述要获取的数据。为了使 web 应用程序有一个目的,在数据理解部分,我将创建几个业务问题,我将通过这些问题来构建 R Shiny。

然后,通过使用 R,我将按照正确的格式排列数据,以构建机器学*模型和闪亮的应用程序。最后,我将展示代码并解释如何创建一个 R Shiny 应用程序的步骤。

内容

  1. 什么是 R 闪亮?
  2. 数据理解
  3. 数据准备
  4. 建模
  5. 埃达在 R 闪亮
  6. R 闪亮中的预测

什么是 R 闪亮?

R Shiny 是一个 R 包,它能够直接从 R 构建交互式 web 页面应用程序,而无需使用任何 web 应用程序语言,如 HTML、CSS 或 JavaScript 知识。

Shiny 的一个重要特性是,这些应用程序在某种程度上是“活的”,因为网页的输出会随着用户修改输入而改变,而无需重新加载浏览器。

Shiny 包含两个基本参数,UI 和服务器。用户界面(UI)包含描述页面布局的所有文本代码、任何附加文本、图像和我们想要包含的其他 HTML 元素,以便用户可以进行交互并理解如何使用网页。另一方面,服务器是闪亮应用程序的后端。该参数创建一个 web 服务器,专门用于在受控环境中托管闪亮的应用程序。

数据理解

用于开发 R Shiny 应用程序的数据集名为 自行车共享数据集 (具体来说就是“hour.csv”文件),取自 UCI 机器学*资源库

我收集的数据来自名为“ Capital Bikeshare ”的自行车共享系统。该系统由位于 DC 华盛顿州六个不同辖区的一组自行车组成。自行车被锁在停靠站的整个网络中,供用户进行日常运输。用户可以通过应用程序解锁自行车,并在完成骑行后,将它们归还到任何其他可用的坞站。

该数据集包含 2011 年至 2012 年间每小时的自行车注册数,考虑了天气条件和季节信息。它包含 16 个属性和 17,379 个观察值,其中每一行数据代表从 2011 年 1 月 1 日开始的一天中的一个特定小时;直到 2012 年 12 月 31 日。

共有 9 个分类变量,如下所示:

  1. 日期:日期
  2. 季节:季节(1 =冬天,2 =春天,3 =夏天,4 =秋天)
  3. 年:年(0 = 2011 年,1 = 2012 年)
  4. 月:月(1 至 12)
  5. 小时:小时(0 到 23)
  6. 假日:天气日是否为假日(0 =否,1 =是)
  7. 工作日:一周中的某一天
  8. 工作日:天气日是否为工作日(如果该日既不是周末也不是节假日,则为 1,否则为 0)
  9. 天气状况(1 =晴朗,少云,部分多云,部分多云;2 =薄雾+多云,薄雾+碎云,薄雾+少云,薄雾;3 =小雪、小雨+雷雨+散云、小雨+散云;4 =暴雨+冰托盘+雷暴+薄雾、雪+雾)

此外,数据有 7 个数值变量:

  1. temp:以摄氏度为单位的标准化温度(这些值是通过(t-t_min)/(t_max-t_min),t_min=-8,t_max=+39 得出的)
  2. atemp:以摄氏度为单位的标准化感觉温度(该值通过(t-t_min)/(t_max-t_min)得出,t_min=-16,t_max=+50)
  3. 嗡嗡声:标准化湿度(数值分为 100(最大))
  4. 风速:标准化风速(数值分为 67(最大值)
  5. 临时:特定小时内使用自行车共享系统的临时用户数
  6. 已注册:特定小时内注册使用自行车共享系统的新用户数
  7. 计数:特定小时内租赁自行车总数(包括临时自行车和注册自行车)

商业问题

一旦我理解了这些数据,我就开发了一些我将在本文中回答的业务问题,以展示如何在现实世界中使用 R Shiny 应用程序。

  1. 数据集中新注册和临时注册的数量是否有显著差异?
  2. 在这两年中,骑自行车时最主要的天气条件是什么?
  3. 2012 年,自行车共享系统的新用户注册数量最多的月份是哪个月?
  4. 在 2012 年的“良好”天气条件下,哪个季节的临时用户和新用户注册数量最多?
  5. 该公司希望预测 2020 年 5 月 14 日(工作日)下午 3 点的自行车注册数量;提供以下天气信息:
  • 将会有 35%的湿度。
  • 温度 17 摄氏度,感觉温度 15 摄氏度。
  • 每小时 10 英里的风速。
  • 和“晴朗”天气类型。

数据准备

为了将数据以正确的格式输入到 R Shiny 应用程序中,首先,我准备了数据。为此,我将数据集加载到 RStudio 中,并检查每个属性的数据类型。

## Bike-sharing initial analysis
#Import the dataset
data <- read.csv('hour.csv')[,-1]
str(data)

有必要注意数据集的第一列是行索引,它不包含任何预测值。因此,我决定加载数据,排除原始数据集的第一列。

来自 str() 函数的结果

现在,一旦加载了变量,检查它们拥有正确的数据类型是绝对重要的。可视化结果,我们可以看到九个分类变量中的八个具有不正确的数据类型。为此,我将数据类型从 int (整数)改为 factor 。此外,我将编号值更改为它们各自的类别名称,以使它们的操作更容易理解。

有必要提及的是,我遵循了一个不同的标准来标记天气状况。通过分析天气的每一个输出,我决定把它们标上从“好”到“非常坏”的等级;其中 1 代表好天气,4 代表非常糟糕的天气。

#Data preparation
  #Arranging values and changing the data type
data$yr <- as.factor(ifelse(data$yr == 0, '2011', '2012'))data$mnth <- as.factor(months(as.Date(data$dteday), 
                              abbreviate = TRUE))data$hr <- factor(data$hr)data$weekday <- as.factor(weekdays(as.Date(data$dteday)))data$season <- as.factor(ifelse(data$season == 1, 'Spring',
                                ifelse(data$season == 2, 'Summer',
                                       ifelse(data$season == 3, 
                                              'Fall', 'Winter'))))data$weathersit <- as.factor(ifelse(data$weathersit == 1, 'Good',
                                    ifelse(data$weathersit == 2, 
                                           'Fair',
                                           ifelse(data$weathersit == 
                                                    3, 'Bad', 
                                                  'Very Bad'))))data$holiday<-as.factor(ifelse(data$holiday == 0, 'No', 'Yes'))data$workingday<-as.factor(ifelse(data$workingday == 0, 'No', 
                                  'Yes'))

此外,我继续将“注册”和“cnt”列分别更改为“新”和“总计”。

这种变化不是必需的,但它将允许我区分新的和注册总数。

 #Changing columns names
names(data)[names(data) == "registered"] <- "new"
names(data)[names(data) == "cnt"] <- "total"

最后,对于数据准备的最后一步,我将变量“temp”、“atemp”、“hum”和“windspeed”的值反规格化;以便以后我可以在探索性数据分析和预测模型中分析真实的观察结果。

 #Denormalizing the values
    #Temperature
for (i in 1:nrow(data)){
  tn = data[i, 10]
  t = (tn * (39 - (-8))) + (-8)
  data[i, 10] <- t
} #Feeling temperature
for (i in 1:nrow(data)){
  tn = data[i, 11]
  t = (tn * (50 - (-16))) + (-16)
  data[i, 11] <- t
} #Humidity
data$hum <- data$hum * 100 #Wind speed
data$windspeed <- data$windspeed * 67

对于最终的安排,我删除了数据集的第一列,因为它对于研究来说并不重要。一旦我有了正确类型的所有变量和所需格式的所有值,我就用当前排列的数据编写一个新文件。

此外,我将使用这个新文件来构建 R Shiny 应用程序的图形。

#Write the new file
data <- data[-1]
write.csv(data, "bike_sharing.csv", row.names = FALSE)

建模

对于该模型,我想预测在考虑时间框架(月、小时和星期几)和天气条件的情况下,一天中可能发生的注册总数。对于这个问题,第一步是删除不属于模型的列。

“季节”和“工作日”列被删除,因为变量“月份”和“工作日”可以提供相同的信息。通过指示月份,我们知道一年中的哪个季节相对应。此外,通过提供关于一周中某一天的信息,我们可以确定这一天是否是工作日。

由于预测模型承认天气状况和某一天的特定信息,可变年份不提供模型所需的任何基本信息。对于这个问题,我从数据框架中删除了变量“yr”。同样,模型中不包括列“casual”和“new ”,因为模型的目的是预测注册总数。

#Modeling
  #Dropping columns
data <- data[c(-1,-2,-7,-13,-14)]

拆分数据

既然数据已经为建模做好了准备,我继续将数据分成训练集和测试集。此外,为了将数据用于 R Shiny 应用程序,我将这些数据集保存到一个新文件中。我使用了 0.8 的分割比率,这意味着训练数据将包含总观察值的 80%,而测试将包含剩余的 20%。

 #Splitting data
library(caTools)set.seed(123)
split = sample.split(data$total, SplitRatio = 0.8)
train_set = subset(data, split == TRUE)
test_set = subset(data, split == FALSE) #Write new files for the train and test sets
write.csv(train_set, "bike_train.csv", row.names = FALSE)
write.csv(test_set, "bike_test.csv", row.names = FALSE)

模型

此外,我继续选择模型进行预测。由于因变量是数字(总注册数),这意味着我们正在进行回归任务。为此,我预先选择了多重线性回归、决策树和随机森林模型来预测因变量的结果。

下一步,我用训练数据创建了回归模型。然后,我通过计算平均绝对误差(MAE)和均方根误差(RMSE)来评估它的性能。

 #Multilinear regression
multi = lm(formula = total ~ ., data = train_set) #Predicting the test values
y_pred_m = predict(multi, newdata = test_set) #Performance metrics
library(Metrics)mae_m = mae(test_set[[10]], y_pred_m)
rmse_m = rmse(test_set[[10]], y_pred_m)
mae_m
rmse_m

多重线性回归梅伊和 RMSE 结果

 #Decision tree
library(rpart)dt = rpart(formula = total ~ ., data = train_set,
           control = rpart.control(minsplit = 3)) #Predicting the test values
y_pred_dt = predict(dt, newdata = test_set) #Performance metrics
mae_dt = mae(test_set[[10]], y_pred_dt)
rmse_dt = rmse(test_set[[10]], y_pred_dt)
mae_dt
rmse_dt

决策树回归梅和 RMSE 结果

 #Random forest
library(randomForest)set.seed(123)
rf = randomForest(formula = total ~ ., data = train_set,
                  ntree = 100) #Predicting the test values
y_pred_rf = predict(rf, newdata = test_set) #Performance metrics
mae_rf = mae(test_set[[10]], y_pred_rf)
rmse_rf = rmse(test_set[[10]], y_pred_rf)
mae_rf
rmse_rf

随机森林回归梅和 RMSE 结果

一旦我有了所有模型的性能指标,我就继续分析它们,以最终选择最佳模型。众所周知,平均绝对误差(MAE)和均方根误差(RMSE)是衡量回归模型准确性的两个最常见的指标。

由于 MAE 提供预测误差的平均值,因此最好选择 MAE 值较小的模型。换句话说,在 MAE 较低的情况下,预测中的误差幅度很小,使得预测更接*真实值。根据这些标准,我选择了随机森林模型,它的 MAE 等于 47.11。

此外,我继续分析 RMSE。该指标还通过计算预测值和实际观测值之间的平均平方差的平方根来测量误差的平均大小,这意味着它会对较大的误差给予较高的权重。换句话说,使用较小的 RMSE,我们可以在模型中捕获较少的错误。也就是说,随机森林是正确的选择。此外,随机森林的 MAE 和 RMSE 之间的差异很小,这意味着个体误差的方差较低。

现在我知道了随机森林模型是最好的模型,需要将该模型保存在一个文件中,以便在 Shiny 应用程序中使用。

#Saving the model
saveRDS(rf, file = "./rf.rda")

埃达在 R 闪亮

在项目的这一步,我构建了一个 R Shiny 应用程序,可以在其中对数字和分类自变量进行单变量分析。此外,我开发了一个交互式仪表板来回答本文开头提出的业务问题。

在一个新的 R 文档中,我开始创建 R 闪亮的应用程序。首先,我加载了在整个闪亮应用程序和数据集中使用的必要库。

#Load libraries
library(shiny)
library(shinydashboard)
library(ggplot2)
library(dplyr)#Importing datasets
bike <- read.csv('bike_sharing.csv')
bike$yr <- as.factor(bike$yr)
bike$mnth <- factor(bike$mnth, levels = c('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))
bike$weekday <- factor(bike$weekday, levels = c('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'))
bike$season <- factor(bike$season, levels = c('Spring', 'Summer', 'Fall', 'Winter'))

r 闪亮的 UI

首先,我创建了 web 页面(UI ),它将显示探索性数据分析的所有信息和可视化。

UI 将是一个变量,包含关于元素的信息,如标题、侧栏和仪表板的主体。要用所有必要的组件构建一个新的仪表板页面,请遵循下面的代码。

ui <- dashboardPage(dashboardHeader(), 
                    dashboardSidebar(),
                    dashboardBody())

此外,我继续设计标题,创建侧边栏选项卡,并指明正文信息。

为了更好地理解代码,我将把它分成几个独立的部分。但是,有必要知道,为了让应用程序正常工作,我们必须一起运行所有的部分。

对于仪表板标题,我指定了闪亮应用程序的标题名称,并安排了标题显示的空间宽度。

#R Shiny ui
ui <- dashboardPage(

  #Dashboard title
  dashboardHeader(title = 'BIKE SHARING EXPLORER', 
                  titleWidth = 290),

然后,我定义了侧边栏布局,设置了侧边栏的宽度。然后,用 sidebarMenu() 函数,我指定了侧边栏菜单的标签数量和标签名称。为了设置选项卡,我使用了 menuItem() 函数,其中我提供了选项卡的实际名称(应用程序中显示的名称)、引用选项卡名称(用于在整个代码中调用选项卡的别名),并定义了我想要附加到实际名称的图标或图形。

对于 EDA,我创建了两个名为 Plots 和 Dashboard 的选项卡。在第一个选项卡中,我显示了所有变量的单变量分析。另一个选项卡显示特定变量的双变量分析,以回答业务问题。

 #Sidebar layout
  dashboardSidebar(width = 290,
                   sidebarMenu(menuItem("Plots", tabName = "plots", icon = icon('poll')),
                               menuItem("Dashboard", tabName = "dash", icon = icon('tachometer-alt')))),

此外,在仪表板正文中,我描述了创建的每个选项卡的内容和布局。

首先,我使用了一个 CSS 组件,它是一种可以在 HTML 文档中使用的样式语言,将标题更改为粗体。此外,在 tabItems(),中,我设置了上面创建的每个选项卡的内容。使用 tabItem() 函数,我定义了引用标签名,然后描述了它将包含的不同元素。

一旦我确定了引用标签名(' plots '),我就通过使用 box() 函数找到四个不同的空格来显示信息。使用这个函数,我定义了框的样式(状态)、标题、添加可选的页脚、控件和绘图输出。

在这段代码中,首先,我定义了四个盒子。其中两个框包含一个小部件,另外两个框显示稍后在服务器中创建的图。使用的控件小部件是 selectInput(),,这是一个下拉菜单,有不同的选项可供选择。在同一个函数中,我描述了小部件的引用名、实际名称以及将出现在菜单上的选项列表。另一方面,我用了最后两个方框来揭示剧情的输出。为此,我定义了函数 plotOutput() 并指明了它的引用名。

#Tabs layout
  dashboardBody(tags$head(tags$style(HTML('.main-header .logo {font-weight: bold;}'))),
                tabItems(
                         #Plots tab content
                         tabItem('plots', 
                                 #Histogram filter
                                 box(status = 'primary', title = 'Filter for the histogram plot', 
                                     selectInput('num', "Numerical variables:", c('Temperature', 'Feeling temperature', 'Humidity', 'Wind speed', 'Casual', 'New', 'Total')),
                                     footer = 'Histogram plot for numerical variables'),
                                 #Frecuency plot filter
                                 box(status = 'primary', title = 'Filter for the frequency plot',
                                     selectInput('cat', 'Categorical variables:', c('Season', 'Year', 'Month', 'Hour', 'Holiday', 'Weekday', 'Working day', 'Weather')),
                                     footer = 'Frequency plot for categorical variables'),
                                 #Boxes to display the plots
                                 box(plotOutput('histPlot')),
                                 box(plotOutput('freqPlot'))),

对于下一个选项卡项目(“破折号”),我使用了与上面代码类似的设计。选项卡的布局包含三个框。第一个框拥有过滤器,其余的框拥有绘图空间。

在过滤框中,我使用了 splitLayout() 函数将框的布局分成三个不同的列。对于这些过滤器,我使用了一个名为 radioButtons(),的控件小部件,其中我指出了引用名、实际名称以及我们将在应用程序中使用的选项列表。

然后,在仪表板的其他框中,我指出了它的内容,比如图表,并声明了引用名称。同样,对于最后一个框,我输入了函数 column() ,在这里我指出了它的宽度。此外,我创建了两个不同的列,通过使用 helpText() 函数,我在其中描述了每个天气条件过滤器的含义。

 #Dashboard tab content
                         tabItem('dash',
                                 #Dashboard filters
                                 box(title = 'Filters', status = 'primary', width = 12,
                                     splitLayout(cellWidths = c('4%', '42%', '40%'),
                                                 div(),
                                                 radioButtons( 'year', 'Year:', c('2011 and 2012', '2011', '2012')),
                                                 radioButtons( 'regis', 'Registrations:', c('Total', 'New', 'Casual')),
                                                 radioButtons( 'weather', 'Weather choice:', c('All', 'Good', 'Fair', 'Bad', 'Very Bad')))),
                                 #Boxes to display the plots
                                 box(plotOutput('linePlot')),
                                 box(plotOutput('barPlot'), 
                                     height = 550, 
                                     h4('Weather interpretation:'),
                                     column(6, 
                                            helpText('- Good: clear, few clouds, partly cloudy.'),
                                            helpText('- Fair: mist, cloudy, broken clouds.')),
                                     helpText('- Bad: light snow, light rain, thunderstorm, scattered clouds.'),
                                     helpText('- Very Bad: heavy rain, ice pallets, thunderstorm, mist, snow, fog.')))))
)

最后,我创建了一个空服务器来运行代码,并可视化这个闪亮应用程序的进度。

# R Shiny server
server <- shinyServer(function(input, output) {})shinyApp(ui, server)

绘图选项卡

仪表板选项卡

由于我在服务器上没有输出,应用程序将显示空白空间,稍后我将在那里放置绘图。

r 闪亮服务器

此外,在服务器变量中,我继续创建为分析而构建的图,以回答业务问题。

我创建的第一个图是直方图。通过使用输出$histPlot 向量,我访问了 UI 中指示的直方图绘图框,我继续将它分配给 renderPlot({}) 反应函数。这个函数将从 UI 中获取数据,并将其实现到服务器中。

而且,我创建了一个名为“num_val”的新变量。此变量将存储数据集中引用数值变量筛选器的列的名称。现在,有了这个新变量,我开始构建直方图。

# R Shiny server
server <- shinyServer(function(input, output) {

  #Univariate analysis
  output$histPlot <- renderPlot({ #Column name variable
    num_val = ifelse(input$num == 'Temperature', 'temp',
                     ifelse(input$num == 'Feeling temperature', 'atemp',
                            ifelse(input$num == 'Humidity', 'hum',
                                   ifelse(input$num == 'Wind speed', 'windspeed',
                                          ifelse(input$num == 'Casual', 'casual',
                                                 ifelse(input$num == 'New', 'new', 'total'))))))

    #Histogram plot
    ggplot(data = bike, aes(x = bike[[num_val]]))+ 
      geom_histogram(stat = "bin", fill = 'steelblue3', 
                     color = 'lightgrey')+
      theme(axis.text = element_text(size = 12),
            axis.title = element_text(size = 14),
            plot.title = element_text(size = 16, face = 'bold'))+
      labs(title = sprintf('Histogram plot of the variable %s', num_val),
           x = sprintf('%s', input$num),y = 'Frequency')+
      stat_bin(geom = 'text', 
               aes(label = ifelse(..count.. == max(..count..), as.character(max(..count..)), '')),
      vjust = -0.6)
  })

接下来,我绘制了分类变量的频率图。执行与前面相同的步骤,我调用了 output$freqPlot 向量来使用 renderPlot({}) 反应函数绘制图形。同样,我生成了一个新变量来存储与过滤器上选择的值相关的数据集的列名。然后,使用新的变量,我建立了频率图。

output$freqPlot <- renderPlot({#Column name variable
    cat_val = ifelse(input$cat == 'Season', 'season',
                     ifelse(input$cat == 'Year', 'yr',
                            ifelse(input$cat == 'Month', 'mnth',
                                   ifelse(input$cat == 'Hour', 'hr',
                                          ifelse(input$cat == 'Holiday', 'holiday',
                                                 ifelse(input$cat == 'Weekday', 'weekday',
                                                    ifelse(input$cat == 'Working day', 'workingday', 'weathersit')))))))

    #Frecuency plot
    ggplot(data = bike, aes(x = bike[[cat_val]]))+
      geom_bar(stat = 'count', fill = 'mediumseagreen', 
               width = 0.5)+
      stat_count(geom = 'text', size = 4,
                 aes(label = ..count..),
                 position = position_stack(vjust = 1.03))+
      theme(axis.text.y = element_blank(),
            axis.ticks.y = element_blank(),
            axis.text = element_text(size = 12),
            axis.title = element_text(size = 14),
            plot.title = element_text(size = 16, face="bold"))+
      labs(title = sprintf('Frecuency plot of the variable %s', cat_val),
           x = sprintf('%s', input$cat), y = 'Count')

  })

现在,我继续为 dashboard 选项卡构建图表。为了回答第三个业务问题,我创建了一个线形图来显示每月的注册数量。此外,我将能够按年份和注册类型过滤图表。

首先,我指出了输出向量和反应函数。然后,我开发了一个表,通过遵循特定的条件,该表将包含绘图中使用的必要列。

后来,考虑到用户在过滤器上选择的注册类型,我生成了一个新变量(“regis_val”)来存储数据集的列名。最后,我建立了线条图。

#Dashboard analysis
  output$linePlot <- renderPlot({

    if(input$year != '2011 and 2012'){

      #Creating a table filter by year for the line plot
      counts <- bike %>% group_by(mnth) %>% filter(yr == input$year) %>% summarise(new = sum(new), casual = sum(casual), total = sum(total))} else{

      #Creating a table for the line plot
      counts <- bike %>% group_by(mnth) %>% summarise(new = sum(new), casual = sum(casual), total = sum(total))}#Column name variable
    regis_val = ifelse(input$regis == 'Total', 'total',
                       ifelse(input$regis == 'New', 'new','casual'))

    #Line plot
    ggplot(counts, aes(x = mnth, y = counts[[regis_val]],
                       group = 1))+
      geom_line(size = 1.25)+
      geom_point(size = 2.25,
                 color = ifelse(counts[[regis_val]] == max(counts[[regis_val]]), 'red','black'))+
      labs(title = sprintf('%s bike sharing registrations by month', input$regis),
           subtitle = sprintf('Throughout the year %s \nMaximum value for %s registrations: %s \nTotal amount of %s registrations: %s', input$year, regis_val, max(counts[[regis_val]]), regis_val, sum(counts[[regis_val]])),
           x = 'Month', 
           y = sprintf('Count of %s registrations', regis_val))+
      theme(axis.text = element_text(size = 12),
            axis.title = element_text(size = 14),
            plot.title = element_text(size = 16, face = 'bold'),
            plot.subtitle = element_text(size = 14))+
      ylim(NA, max(counts[[regis_val]])+7000)+
      geom_text(aes(label = ifelse(counts[[regis_val]] == max(counts[[regis_val]]), as.character(counts[[regis_val]]),'')),
                col ='red',hjust = 0.5, vjust = -0.7) })

此外,我继续开发条形图来回答业务问题 4。我遵循了与上面代码相似的步骤。首先,我创建了一些限制来创建用于不同过滤器的表,该表将考虑年份和天气条件。然后,我创建了一个变量,它存储了在过滤器上选择的注册类型的列名。最后,构建条形频率图,按年份、注册类型和天气条件显示注册计数。

 output$barPlot <- renderPlot({

    if(input$year != '2011 and 2012'){

      if(input$weather != 'All'){

        #Creating a table filter by year and weathersit for the bar plot
        weather <- bike %>% group_by(season, weathersit) %>% filter(yr == input$year) %>%  summarise(new = sum(new), casual = sum(casual), total = sum(total))

        weather <- weather %>% filter(weathersit == input$weather)} else{

        #Creating a table filter by year for the bar plot
        weather <- bike %>% group_by(season, weathersit) %>% filter(yr == input$year) %>%  summarise(new = sum(new), casual = sum(casual), total = sum(total))

      }

    } else{

      if(input$weather != 'All'){

        #Creating a table filter by weathersit for the bar plot
        weather <- bike %>% group_by(season, weathersit) %>% filter(weathersit == input$weather) %>%  summarise(new = sum(new), casual = sum(casual), total = sum(total))

      } else{

        #Creating a table for the bar plot
        weather <- bike %>% group_by(season, weathersit) %>%  summarise(new = sum(new), casual = sum(casual), total = sum(total))

      }
    }

    #Column name variable
    regis_val = ifelse(input$regis == 'Total', 'total', 
                       ifelse(input$regis == 'New', 'new','casual'))

    #Bar plot
    ggplot(weather, aes(x = season, y = weather[[regis_val]], 
                        fill = weathersit))+
      geom_bar(stat = 'identity', position=position_dodge())+
      geom_text(aes(label = weather[[regis_val]]),
                vjust = -0.3, position = position_dodge(0.9), 
                size = 4)+
      theme(axis.text.y = element_blank(),
            axis.ticks.y = element_blank(),
            axis.text = element_text(size = 12),
            axis.title = element_text(size = 14),
            plot.title = element_text(size = 16, face = 'bold'),
            plot.subtitle = element_text(size = 14),
            legend.text = element_text(size = 12))+
      labs(title = sprintf('%s bike sharing registrations by season and weather', input$regis),
           subtitle = sprintf('Throughout the year %s', input$year),
           x = 'Season', 
           y = sprintf(Count of %s registrations', regis_val))+
      scale_fill_manual(values = c('Bad' = 'salmon2', 'Fair' = 'steelblue3', 'Good' = 'mediumseagreen', 'Very Bad' = 'tomato4'),
                        name = 'Weather')

  })

现在我已经在服务器中创建了图表,我继续运行代码来可视化这个闪亮的应用程序。

带有图的图选项卡

带有绘图的仪表板选项卡

结论

最后,我继续通过分析展示业务问题的答案。

  • 数据集中新注册和临时注册的数量是否有显著差异?

我继续展示图表来回答第一个问题。

新登记类型变量的直方图

可变临时登记类型的直方图

在分析“新”变量时,我指出,在整个数据集中,最少有 0 个新注册,最多大约有 875 个。另一方面,有一个最低的休闲注册 0 和粗略的最高 350。

正如我们所看到的,两个图都向右倾斜,这意味着每天记录的大多数注册分别低于新注册和临时注册类型的 250 和 100。

最后,为了回答第一个商业问题,我得出结论,新注册和临时注册的数量之间存在显著差异。该数据集显示,在 1500 多次观察中,用户每天进行的新注册不到 125 次。然而,在 1000 多次情况下,该系统每天捕获的临时登记不到 50 次。

换句话说,该系统在 2011 年和 2012 年,比使用该系统的临时用户有更多的新用户注册到首都自行车共享。造成这种现象的原因之一是系统的启动。自 2010 年启动该业务以来,在随后的几年里,新用户仍在注册。

  • 在这两年中,骑自行车时最主要的天气条件是什么?

为了回答这个问题,我展示了所需的情节。

变量 weathersit 的频率图

通过观察图表,我得出结论,2011 年和 2012 年最常见的天气状况属于“良好”类型。该图显示,数据集中的 11,413 个观测值捕捉到了“好”天气,这意味着这两年的天气大多是晴朗的,很少有云,或部分多云。

  • 2012 年,自行车共享系统的新用户注册数量最多的月份是哪个月?

为了回答这个问题,我继续点击 dashboard 选项卡并显示下面的图。

2012 年新注册数量的时间序列图

一旦我按年份和注册类型过滤了图,我就获得了上面显示的结果。我们可以想象,新用户注册量最高的月份是在 9 月。新增用户约为 170,000 的原因之一是,9 月是秋季的开始,气温正在下降。换句话说,热量更少,天气更适合人们骑自行车上下班。

  • 2012 年,在“良好”天气条件下,哪个季节的休闲和新注册人数最多?

对于下面的问题,我继续从仪表板选项卡显示两个不同的图。

根据年份和天气条件过滤的绘图季节与临时注册数

根据年份和天气条件筛选的绘图季节与新注册数

正如我们从之前的分析中所知,自行车共享系统中的新注册量远高于临时注册量。对于这个问题,新的注册地块将显示更高的注册用户数,而不管季节。

此外,我指出,在这两种类型的注册中,最高数量的注册发生在秋季,其次是夏季。正如我之前提到的,秋季是人们骑自行车上下班的理想天气。此外,夏季也呈现出相当高的注册数量,因为这是人们度假和使用自行车系统共享进行观光和旅游的季节。

R 闪亮中的预测

为了回答最后一个问题,我开始部署模型。在这一步中,我在 R Shiny 应用程序中创建了一个新的选项卡。在该选项卡中,用户将能够输入每个变量的单个值,并获得注册总数和预测结果的值范围。

为了更好地理解代码,我将类型字符设置为“bold ”,以表示添加到 R Shiny 中的新文本。

在闪亮的应用程序文档中,我继续添加新的库并导入预测所需的数据集。训练和测试数据都被引入到应用程序中以安排分类级别。此外,我加载了随机森林模型来收集平均绝对误差值。

#Load libraries
library(shiny)
library(shinydashboard)
library(ggplot2)
library(dplyr)
**library(randomForest)
library(Metrics)**#Importing datasets
bike <- read.csv('bike_sharing.csv')
bike$yr <- as.factor(bike$yr)
bike$mnth <- factor(bike$mnth, levels = c('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))
bike$weekday <- factor(bike$weekday, levels = c('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'))
bike$season <- factor(bike$season, levels = c('Spring', 'Summer', 'Fall', 'Winter'))**train_set <- read.csv('bike_train.csv')
train_set$hr <- as.factor(train_set$hr)****test_set <- read.csv('bike_test.csv')
test_set$hr <- as.factor(test_set$hr)****levels(test_set$mnth) <- levels(train_set$mnth)
levels(test_set$hr) <- levels(train_set$hr)
levels(test_set$holiday) <- levels(train_set$holiday)
levels(test_set$weekday) <- levels(train_set$weekday)
levels(test_set$weathersit) <- levels(train_set$weathersit)****#Importing model
model_rf <- readRDS(file = './rf.rda')
y_pred = predict(model_rf, newdata = test_set)
mae_rf = mae(test_set[[10]], y_pred)
rmse_rf = rmse(test_set[[10]], y_pred)**

r 闪亮的 UI

现在,我在 UI 中加入了新的文本代码。我在 dashboardSidebar()dashboardBody() 函数的末尾添加了新的代码行。

对于侧边栏,我添加了一个名为“pred”的新菜单项,表示闪亮应用程序中的新标签。

#R Shiny ui
ui <- dashboardPage(

  #Dashboard title
  dashboardHeader(title = 'BIKE SHARING EXPLORER', titleWidth = 290),

  #Sidebar layout
  dashboardSidebar(width = 290,
                   sidebarMenu(menuItem("Plots", tabName = "plots", icon = icon('poll')),
                               menuItem("Dashboard", tabName = "dash", icon = icon('tachometer-alt')),
                               **menuItem("Prediction", tabName = "pred", icon = icon('search'))**)),

然后,在仪表板正文中,我继续描述上面创建的新选项卡的内容。该选项卡有四个框。前两个框将包含控件小部件,用户可以在其中输入模型中每个变量的值。第一个框将包含所有的分类变量,其中我实现了四个选择输入()和一个单选按钮()小部件。

第二个框包含数字变量。为了输入湿度值,我使用了 sliderInput() 小部件从 0%到 100%的范围内选择湿度的百分比。这个小部件接受引用名称、实际名称、最小值、最大值和默认值作为参数。此外,对于剩余的变量,我使用了 numericInput() ,用户可以在这里输入变量的值。这个小部件的参数是引用名称、实际名称和默认值。

此外,我构建了下面的框来显示单个预测的结果。为了显示预测的结果和预测值的范围,我使用了一个名为 verbatimTextOutput() 的控件小部件,在这里我定义了引用名并将其标记为值的占位符。此外,我添加了一个带有 actionButton() 小部件的按钮,以便在用户输入所有值后计算结果。对于这个控件小部件,我将引用名称、实际名称和图标标识为参数。

最后,最后一个框的功能是传递信息,解释我选择的模型。

 #Tabs layout
  dashboardBody(tags$head(tags$style(HTML('.main-header .logo {font-weight: bold;}'))),
                        #Plots tab content
                tabItems(tabItem('plots', 
                                 #Histogram filter
                                 box(status = 'primary', title = 'Filter for the histogram plot',
                                     selectInput('num', "Numerical variables:", c('Temperature', 'Feeling temperature', 'Humidity', 'Wind speed', 'Casual', 'New', 'Total')),
                                     footer = 'Histogram plot for numerical variables'),
                                 #Frecuency plot filter
                                 box(status = 'primary', title = 'Filter for the frequency plot',
                                     selectInput('cat', 'Categorical variables:', c('Season', 'Year', 'Month', 'Hour', 'Holiday', 'Weekday', 'Working day', 'Weather')),
                                     footer = 'Frequency plot for categorical variables'),
                                 #Boxes to display the plots
                                 box(plotOutput('histPlot')),
                                 box(plotOutput('freqPlot'))), #Dashboard tab content
                         tabItem('dash',
                                 #Dashboard filters
                                 box(title = 'Filters', 
                                     status = 'primary', width = 12,
                                     splitLayout(cellWidths = c('4%', '42%', '40%'),
                                                 div(),
                                                 radioButtons( 'year', 'Year:', c('2011 and 2012', '2011', '2012')),
                                                 radioButtons( 'regis', 'Registrations:', c('Total', 'New', 'Casual')),
                                                 radioButtons( 'weather', 'Weather choice:', c('All', 'Good', 'Fair', 'Bad', 'Very Bad')))),
                                 #Boxes to display the plots
                                 box(plotOutput('linePlot')),
                                 box(plotOutput('barPlot'), 
                                     height = 550, 
                                     h4('Weather interpretation:'),
                                     column(6, 
                                            helpText('- Good: clear, few clouds, partly cloudy.'),
                                            helpText('- Fair: mist, cloudy, broken clouds.')),
                                     helpText('- Bad: light snow, light rain, thunderstorm, scattered clouds.'),
                                     helpText('- Very Bad: heavy rain, ice pallets, thunderstorm, mist, snow, fog.'))),**#Prediction tab content
                         tabItem('pred',
                                 #Filters for categorical variables
                                 box(title = 'Categorical variables', 
                                     status = 'primary', width = 12, 
                                     splitLayout(
                                  tags$head(tags$style(HTML(".shiny-split-layout > div {overflow: visible;}"))),
                                                 cellWidths = c('0%', '19%', '4%', '19%', '4%', '19%', '4%', '19%', '4%', '8%'),
                                                 selectInput( 'p_mnth', 'Month', c("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul","Aug", "Sep", "Oct", "Nov", "Dec")),
                                                 div(),
                                                 selectInput('p_hr', 'Hour', c('0', '1', '2', '3', '4', '5', '6', '7', '8','9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23')),
                                                 div(),
                                                 selectInput( 'p_weekd', 'Weekday', c('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday')),
                                                 div(),
                                                 selectInput( 'p_weather', 'Weather', c('Good', 'Fair', 'Bad', 'Very Bad')),
                                                 div(),
                                                 radioButtons( 'p_holid', 'Holiday', c('Yes', 'No')))),
                                 #Filters for numeric variables
                                 box(title = 'Numerical variables',
                                     status = 'primary', width = 12,
                                     splitLayout(cellWidths = c('22%', '4%','21%', '4%', '21%', '4%', '21%'),
                                                 sliderInput( 'p_hum', 'Humidity (%)', min = 0, max = 100, value = 0),
                                                 div(),
                                                 numericInput( 'p_temp', 'Temperature (Celsius)', 0),
                                                 div(),
                                                 numericInput( 'p_ftemp', 'Feeling temperature (Celsius)', 0),
                                                 div(),
                                                 numericInput( 'p_wind', 'Wind speed (mph)', 0))),
                                 #Box to display the prediction results
                                 box(title = 'Prediction result',
                                     status = 'success', 
                                     solidHeader = TRUE, 
                                     width = 4, height = 260,
                                     div(h5('Total number of registrations:')),
                                     verbatimTextOutput("value", placeholder = TRUE),
                                     div(h5('Range of number of registrations:')),
                                     verbatimTextOutput("range", placeholder = TRUE),
                                     actionButton('cal','Calculate', icon = icon('calculator'))),
                                 #Box to display information about the model
                                 box(title = 'Model explanation',
                                     status = 'success', 
                                     width = 8, height = 260,
                                     helpText('The following model will predict the total number of bikes rented on a specific day of the week, hour, and weather conditions.'),
                                     helpText('The name of the dataset used to train the model is "Bike Sharing Dataset Data Set", taken from the UCI Machine Learning Repository website. The data contains 17,379 observations and 16 attributes related to time and weather conditions.'),
                                     helpText(sprintf('The prediction is based on a random forest supervised machine learning model. Furthermore, the models deliver a mean absolute error (MAE) of %s total number of registrations, and a root mean squared error (RMSE) of %s total number of registrations.', round(mae_rf, digits = 0), round(rmse_rf, digits = 0)))))**
                         )
                )
  )

添加 UI 代码后,我运行应用程序来可视化布局。

带有默认值和模型说明的预测选项卡

r 闪亮服务器

接下来,我继续添加服务器文本代码,它将使用模型计算单个预测。

首先,对于单个预测结果,我定义了一个 reactiveValues() 函数,其中我设置了一个默认值 NULL。当用户按下“计算”按钮时,该值将做出反应。

接下来,我使用了 observeEvent() 函数来执行预测的计算。这个函数将在闪亮的应用程序后面执行计算,并在用户调用函数开头提到的按钮时显示结果(输入\(cal* )。因为在结果和上面创建的反应值之间有一个链接,所以除非用户点击“计算”按钮,否则不会显示结果。现在,我继续调用*输出\)value ,它是单个预测结果的占位符,通过使用函数 renderText({}) 在应用程序中显示结果。有必要提到的是,这个函数只提供字符串类型的结果。

最后,通过调用占位符显示范围结果(输出\(range* )使用函数 *renderText({}),*并调用函数中的活动按钮(*输入\) cal);闪亮的应用程序将在指定位置显示范围结果。

此外,由于“单变量分析”和“仪表板分析”部分的代码有许多行文本,为了更好地理解,我决定用符号“…”代替它。

# R Shiny server
server <- shinyServer(function(input, output) {

  #Univariate analysis
  output$histPlot <- renderPlot({...})
  output$freqPlot <- renderPlot({...}) #Dashboard analysis
  output$linePlot <- renderPlot({...})
  output$barPlot <- renderPlot({...})**#Prediction model
    #React value when using the action button
  a <- reactiveValues(result = NULL)

  observeEvent(input$cal, {
    #Copy of the test data without the dependent variable
    test_pred <- test_set[-10]

    #Dataframe for the single prediction
    values = data.frame(mnth = input$p_mnth, 
                        hr = input$p_hr,
                        weekday = input$p_weekd,
                        weathersit = input$p_weather,
                        holiday = input$p_holid,
                        hum = as.integer(input$p_hum),
                        temp = input$p_temp, 
                        atemp = input$p_ftemp, 
                        windspeed = input$p_wind)

    #Include the values into the new data
    test_pred <- rbind(test_pred,values)

    #Single preiction using the randomforest model
    a$result <-  round(predict(model_rf, 
                               newdata = test_pred[nrow(test_pred),]), 
                       digits = 0)
  })

  output$value <- renderText({
    #Display the prediction value
    paste(a$result)
  })

  output$range <- renderText({
    #Display the range of prediction value using the MAE value
    input$cal
    isolate(sprintf('(%s) - (%s)', 
                    round(a$result - mae_rf, digits = 0),
                    round(a$result + mae_rf, digits = 0)))
  })**

})

shinyApp(ui, server)

结论

此外,我继续使用应用程序来回答最后一个业务问题。

  • 该公司希望预测某一天和天气条件下的自行车注册数量。

参数:

  1. 日期:2020 年 5 月 14 日星期四(是工作日),下午 3 点。
  2. 天气条件:35%的湿度,17 摄氏度的温度,15 摄氏度的感觉温度,10 英里/小时的风速,以及“晴朗”的天气类型。

最后,为了回答最后一个业务问题,我继续输入问题中显示的日期和天气值,然后单击“计算”按钮获得结果。

单一预测结果

从预测中获得的结果是该特定日期和天气条件下的注册总数为 228。此外,预测还揭示了预测值的变化范围。结果显示,该公司预计注册总数在 181 到 275 之间。

旁注

要找到所有的 R 代码和数据集,请访问我的 GitHub 库。另外,在我的 ShinnyApp 中可以找到 R shiny 应用。

如何有效使用随机种子

原文:https://towardsdatascience.com/how-to-use-random-seeds-effectively-54a4cd855a79?source=collection_archive---------3-----------------------

机器学*过程中经常被忽视的部分的最佳实践

图片来自 PixabayPezibear

建立预测模型是一个复杂的过程。你需要获得正确的数据,清理它,创建有用的特征,测试不同的算法,最后验证你的模型的性能。然而,这篇文章涵盖了模型构建过程中通常不会引起太多关注的一个方面:随机种子。

❓什么是随机种子?

随机种子用于确保结果是可重复的。换句话说,使用这个参数可以确保任何人重新运行您的代码都会得到完全相同的输出。在数据科学和其他领域,再现性是一个极其重要的概念。很多人已经写了很多关于这个话题的文章,所以我不会在这篇文章中进一步讨论。

根据您的具体项目,您甚至可能不需要随机种子。但是,有两个常见的任务会用到它们:

1.将数据分成训练集/验证集/测试集:随机种子确保每次运行代码时数据都以相同的方式划分

2.模型训练:诸如随机森林和梯度推进之类的算法是不确定的(对于给定的输入,输出并不总是相同的),因此需要随机种子参数来获得可重复的结果

除了再现性,随机种子对于基准测试结果也很重要。如果您正在测试一个算法的多个版本,那么所有版本使用相同的数据并且尽可能相似(除了您正在测试的参数之外)是非常重要的。

随机种子通常是如何设定的

尽管它们很重要,随机种子通常不需要太多的努力就能被设定。我对此感到内疚。我通常使用我正在工作的任何一天的日期(因此在 2020 年 3 月 1 日,我将使用 seed 20200301)。有的人每次都用同一个种子,有的人随机生成。

总的来说,随机种子通常被视为建模过程中的事后想法。这可能会有问题,因为正如我们将在接下来的几节中看到的,该参数的选择会显著影响结果。

🚢泰坦尼克号数据

现在,我将展示随机种子的选择会产生多大的影响。我将使用众所周知的泰坦尼克号数据集来做这件事(下载链接在下面)。

[## 泰坦尼克号:机器从灾难中学*

从这里开始!预测泰坦尼克号上的生存并熟悉 ML 基础知识

www.kaggle.com](https://www.kaggle.com/c/titanic/data)

以下代码和图是用 Python 创建的,但我在 r 中发现了类似的结果。与本文相关的完整代码可以在下面的 GitHub 资源库中找到:

[## jai-bans al/random-seed-blog-post

这个存储库包含支持关于随机种子最佳实践的博客文章的代码。这篇博文可以在这里找到…

github.com](https://github.com/jai-bansal/random-seed-blog-post)

首先,让我们看几行数据:

import pandas as pd
train_all = pd.read_csv('train.csv') # Show selected columns 
train_all.drop(['PassengerId', 'Parch', 'Ticket', 'Embarked', 'Cabin'], axis = 1).head()

泰坦尼克号数据集样本

泰坦尼克号的数据已经被分成了训练集和测试集。该数据集的一个经典任务是预测乘客存活率(编码在Survived列中)。测试数据没有附带Survived列的标签,所以我将执行以下操作:

1.保留部分训练数据作为验证集

2.根据剩余的训练数据训练模型以预测存活率,并根据步骤 1 中创建的验证集评估该模型

拆分数据

让我们先来看看Survived栏目的整体分布情况。

In [19]: train_all.Survived.value_counts() / train_all.shape[0] 
Out[19]:
0    0.616162 
1    0.383838 
Name: Survived, dtype: float64

在建模时,我们希望我们的训练、验证和测试数据尽可能相似,这样我们的模型就可以在与评估数据相同的数据上进行训练。请注意,这并不意味着而不是这三个数据集应该重叠!他们不应该。但是我们希望每一份报告中的观察结果具有广泛的可比性。现在,我将使用不同的随机种子分割数据,并比较训练集和验证集的Survived分布。

from sklearn.model_selection import train_test_split# Create data frames for dependent and independent variables 
X = train_all.drop('Survived', axis = 1) 
y = train_all.Survived # Split 1 
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size = 0.2, random_state = 135153) In [41]: y_train.value_counts() / len(y_train) 
Out[41]:  
0    0.655899 
1    0.344101 
Name: Survived, dtype: float64 In [42]: y_val.value_counts() / len(y_val) 
Out[42]:  
0    0.458101 
1    0.541899 
Name: Survived, dtype: float64

在这种情况下,训练集中幸存者的比例远低于验证集中幸存者的比例。

# Split 2 
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size = 0.2, random_state = 163035) In [44]: y_train.value_counts() / len(y_train) 
Out[44]:  
0    0.577247 
1    0.422753 
Name: Survived, dtype: float64 In [45]: y_val.value_counts() / len(y_val) 
Out[45]:  
0    0.77095 
1    0.22905 Name: Survived, dtype: float64

这里,在训练集中幸存者的比例比在验证集中高得多。

完全公开,这些例子是我在循环通过 200K 随机种子后发现的最极端的例子。不管怎样,这些结果有几个问题。首先,在这两种情况下,训练集和验证集之间的存活率分布有很大不同。这可能会对模型训练产生负面影响。第二,这些输出彼此非常不同。如果像大多数人一样,任意设置一个随机种子,那么根据您的选择,最终的数据分割可能会有很大的不同。

我将在文章的最后讨论最佳实践。接下来,我想展示我测试的所有 20 万个随机种子的训练和验证Survival分布是如何变化的。

一些数据拆分在训练集和验证集存活率%之间有很大差异。

约 23%的数据分割导致了训练集和验证集之间至少 5%的存活率差异。超过 1%的分裂导致至少 10%的存活率差异。最大存活百分比差异约为 20%。这里的要点是,使用任意随机种子会导致训练集和验证集分布之间的巨大差异。这些差异可能会在建模过程中产生意想不到的下游后果。

📈模特培训

上一节展示了随机种子如何影响数据分割。在这一节中,在之后,我使用不同的随机种子来训练一个模型,数据已经被分成训练集和验证集(下一节将详细介绍我是如何做到这一点的)。

提醒一下,我正在尝试预测Survived列。我将构建一个随机森林分类模型。因为随机森林算法是不确定的,所以需要一个随机种子来实现可再现性。我将在下面展示模型准确性的结果,但是我发现使用 precision 和 recall 也有类似的结果。

首先,我将创建一个训练和验证集。

X = X[['Pclass', 'Sex', 'SibSp', 'Fare']]  # These will be my predictors # The “Sex” variable is a string and needs to be one-hot encoded 
X['gender_dummy'] = pd.get_dummies(X.Sex)['female'] 
X = X.drop(['Sex'], axis = 1) # Divide data into training and validation sets 
# I’ll discuss exactly why I divide the data this way in the next section 
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size = 0.2, random_state = 20200226, stratify = y)

现在,我将训练几个模型,并评估验证集的准确性。

# Model 1 from sklearn.ensemble import RandomForestClassifier 
from sklearn.metrics import accuracy_score # Create and fit model 
clf = RandomForestClassifier(n_estimators = 50, random_state = 11850) 
clf = clf.fit(X_train, y_train)  
preds = clf.predict(X_val)  # Get predictions In [74]: round(accuracy_score(y_true = y_val, y_pred = preds), 3) Out[74]: 0.765 # Model 2# Create and fit model 
clf = RandomForestClassifier(n_estimators = 50, random_state = 2298)
clf = clf.fit(X_train, y_train)
preds = clf.predict(X_val)  # Get predictionsIn [78]: round(accuracy_score(y_true = y_val, y_pred = preds), 3)
Out[78]: 0.827

为了找到这些结果,我测试了 25K 个随机种子,但是准确度变化> 6%绝对值得注意!同样,这两个模型是相同的,除了随机种子。

下图显示了我测试的所有随机种子的模型精确度是如何变化的。

模型精度因随机种子而异。

虽然大多数模型达到了约 80%的准确率,但有相当数量的模型得分在 79%-82%之间,少数模型得分超出了该范围。根据具体的用例,这些差异大到足以产生影响。因此,在与利益相关者交流结果时,应考虑随机种子选择导致的模型性能差异。

最佳实践

既然我们已经看到了随机种子的选择会影响结果的几个方面,我想提出一些最佳实践。

对于数据分割,我认为应该使用分层样本,以便因变量(本文中的Survived)在训练、验证和测试集中的比例相似。这将消除上述变化的存活率分布,并允许根据可比数据训练和评估模型。

train_test_split函数可以用 1 个附加参数实现分层抽样。请注意,如果稍后根据具有不同因变量分布的数据评估模型,性能可能会与预期不同。然而,我认为按因变量分层仍然是分割数据的首选方式。

下面是分层抽样在代码中的样子。

# Overall distribution of “Survived” column 
In [19]: train_all.Survived.value_counts() / train_all.shape[0] 
Out[19]:  
0    0.616162 
1    0.383838 
Name: Survived, dtype: float64 # Stratified sampling (see last argument) 
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size = 0.2, random_state = 20200226, stratify = y) In [10]: y_train.value_counts() / len(y_train) 
Out[10]:  
0    0.616573 
1    0.383427 
Name: Survived, dtype: float64 In [11]: y_val.value_counts() / len(y_val) 
Out[11]:  
0    0.614525 
1    0.385475 
Name: Survived, dtype: float64

使用stratify参数,Survived的比例在训练集和验证集中是相似的。我仍然使用随机种子,因为我仍然想要可重复的结果。然而,我认为在这种情况下,具体的随机种子值并不重要。

这解决了数据分割的最佳实践,但是模型训练呢?在测试不同的模型规格时,应该使用随机种子进行公平的比较,但我不认为特定的种子有太大的关系。

然而,在向利益相关者报告绩效指标之前,最终模型应该用 2-3 个额外的种子进行训练和评估,以了解结果中可能的差异。这种做法可以更准确地传达模型性能。对于在生产环境中运行的关键模型,值得考虑使用多个种子运行该模型,并对结果进行平均(尽管这可能是一篇单独的博客文章的主题)。

🏁结论

希望我已经说服您注意一下经常被忽略的随机种子参数。如果您想查看本文中使用的完整代码,或者对随机 seed 最佳实践有其他想法,请随时联系我们!

如果你喜欢这篇文章,看看我下面的其他作品吧!

[## 洛杉矶交通数据分析🚗:第一部分

使用公开来源数据分析洛杉矶的碰撞模式

towardsdatascience.com](/la-traffic-data-analysis-part-1-53f24e21067d) [## 为您的组织开发技术培训的 7 个技巧

将你的下一个培训课程想法变成现实的技巧

medium.com](https://medium.com/@jai_bansal/7-tips-for-developing-technical-trainings-for-your-organization-928cf7744d44)

如何使用残差图进行回归模型验证?

原文:https://towardsdatascience.com/how-to-use-residual-plots-for-regression-model-validation-c3c70e8ab378?source=collection_archive---------4-----------------------

使用残差图验证您的回归模型

概述

任何数据科学/ML 项目最重要的部分之一是模型验证。这和你之前的工作一样重要。这是欢呼之前的最后一个障碍!

对于回归,有许多方法可以评估你的拟合度,即模型与数据的拟合程度。r 值就是这样一种度量。但它们并不总是最能让我们对自己的模型充满信心。

图片来自 Un flash

犯错是人之常情,随机犯错在统计学上是神圣的

这就是剩余图出现的原因。我们来谈谈什么是剩余图,以及你如何分析它们来解释你的结果。

残差

残差是一个点与回归线垂直距离的度量。简单来说就是预测值和观察到的实际值之间的误差。

残差方程

图 1 是如何根据最佳拟合线可视化残差的示例。垂直线是残差。

图 1 [ StackOverflow

残差图

典型的残差图在 Y 轴上有残差值,在 x 轴上有独立变量。下面的图 2 是典型残差图的一个很好的例子。

图 2 [ 信用

剩余剧情分析

线性回归模型最重要的假设是 误差是独立且正态分布的。

让我们来看看这个假设意味着什么。

每个回归模型本质上都有一定程度的误差,因为你永远不可能 100%准确地预测某件事。更重要的是,随机性和不可预测性总是回归模型的一部分。因此,回归模型可以解释为:

模型中确定性的部分是我们试图用回归模型捕捉的。理想情况下,我们的线性方程模型应该准确地捕捉预测信息。本质上,这意味着如果我们获得了所有的预测信息,那么剩下的所有信息(残差)应该是完全随机的&不可预测的,即随机的。因此,我们希望残差服从正态分布。这正是我们在剩余图中寻找的。那么一个好坏残积的特点是什么呢?

良好残差图的特征

一个好的残差图的几个特征如下:

  1. 靠*原点的点密度高,远离原点的点密度低
  2. 它关于原点是对称的

为了解释为什么图 3 是基于上述特征的良好残差图,我们将所有残差投影到 y 轴上。如图 3b 所示,我们最终得到一条正态分布的曲线;满足残差正态性的假设。

图 3:良好的残差图

图 3b:投影到 y 轴上

最后,这是一个好的残差图的另一个原因是,独立于自变量(x 轴)的值,残差以相同的方式*似分布。换句话说,当我们沿着 x 轴移动时,我们看不到残差值的任何模式。

因此,这满足了我们早先的假设,即回归模型残差是独立的,并且是正态分布的。

利用上述特征,我们可以看出为什么图 4 是一个差的残差图。这个图远离原点密度高,靠*原点密度低。此外,当我们将残差投影到 y 轴上时,我们可以看到分布曲线不是正态的。

图 4:不良残差图示例

图 4b:投影到 y 轴上

重要的是要理解,这些图表明我们还没有完全捕捉到模型中数据的预测信息,这就是为什么“会渗入到我们的残差中。一个好的模型在使用预测信息后应该总是只剩下随机误差(回想一下确定性的&随机成分)

总结

要验证回归模型,必须使用残差图来直观地确认模型的有效性。绘制所有自变量的所有残差值可能有点复杂,在这种情况下,您可以生成单独的图,也可以使用其他验证统计数据,如调整后的 R 或 MAPE 分数。

关于作者

Usman Gohar 是一名数据科学家,明尼阿波利斯数据科学的共同组织者,也是一名技术演讲人。他非常热衷于最新的数据科学研究,机器学*,并通过帮助和赋权年轻人在数据科学领域取得成功而蓬勃发展,特别是女性。您可以在 LinkedInTwitterMedium&follow onGithub上与 Usman 联系。

如何在 Python 中使用 Riot API

原文:https://towardsdatascience.com/how-to-use-riot-api-with-python-b93be82dbbd6?source=collection_archive---------0-----------------------

在本教程中,我将使用 Riot API 来展示如何构建一个像 op.gg 这样的应用程序。

照片由弗洛里安·奥利佛Unsplash 上拍摄

我建议在你开始做任何事情之前,阅读他们的文档以了解他们 API 的最新变化。

什么是 Riot Games API?

Riot Games API 是一个 REST API,它向开发者提供数据,用于构建我们自己的应用程序或网站。目前,所有英雄联盟 API 都是版本 4(2020 年 3 月 19 日更新)。从这个版本开始,他们不再在 API 路径中包含次要版本。

以下是您可以从 Riot Games API 获得的一些数据:

  • 服务状态。
  • 召唤师详细信息:姓名,级别,个人资料图标,帐户 id。
  • 通过召唤师名字匹配历史和匹配细节和时间线。
  • 某人当前的游戏信息,如果有人在游戏中。
  • 其他信息,查看 API 文档

Riot API 密钥入门

你总是需要一把钥匙来访问 Riot Games API。我们将讨论如何获得 API 密钥。

首先,使用您的 Riot 帐户登录 Riot 开发者门户。就是你每次玩英雄联盟用的账号。

在你的Dashboard里,有一个DEVELOPMENT API KEY。请记住,密钥将在 24 小时后过期。不要与任何人共享您的 API 密钥。如果你从 Riot API 得到一个“403”响应,你可能只需要刷新你的密钥。

此外,您可以注册一个个人防暴产品,那么你就不需要每 24 小时刷新您的密钥。通常情况下,个人申请需要两周时间审核。

请记住您提出的请求数量,因为开发 API 密钥和个人产品密钥有上限:

  • 每秒 20 个请求
  • 每两分钟 100 个请求

如果你注册了一个生产 API 密匙,那就更难注册了。上限是:

  • 每 10 秒钟有 3000 个请求
  • 每 10 分钟 18 万次请求

完成上述所有要求后,现在您应该获得一个开发 API 密钥。让我们试着看看 Doublelift Riot 账户。使用您的 API 密钥通过 access 在 Riot API 上进行测试:

[https://na1.api.riotgames.com/lol/summoner/v4/summoners/by-name/Doublelift?api_key=RGAPI-YOUR-API-KEY](https://na1.api.riotgames.com/lol/summoner/v4/summoners/by-name/Doublelift?api_key=RGAPI-YOUR-API-KEY)

结果应该是这样的:

请记住,Riot API 是区域化的,您需要选择您的区域。还有,账号详情,只有召唤师的名字容易获取,不加密。其他账户 id 信息是加密的。

还有,召唤师和账号 id 只在每个地区是唯一的,PUUIDs 是全球唯一的。

安装暴动监视器

如果你在谷歌上搜索riot api 或者league of legends api,有很多库可以使用。这里有一个 Riot API 库的列表。他们中的许多人都没有得到很好的维护,正如你所知,Riot 已经将他们的 API 版本升级到 V4,并取消了所有旧版本。

这里我使用了一个名为的 Python 库。首先,你可以轻松地运行

pip3 install riotwatcher

要查看这样的帐户信息,我们只需尝试从 URL:

访问等级信息

我们还可以使用一行代码获得排名信息:

访问匹配数据

例如,我们想获取最后的游戏信息。

然后对比 op.gg 数据。我们得到了一些准确的数据,但很难读懂。我们需要访问 Champion 和其他静态数据。

截图自 op.gg

存取数据龙

现在我们只得到每个冠军的 id。为了更好的理解,我们需要知道每一个的名字。

从 Data Dragon 可以获得《英雄联盟》的所有静态信息数据。

运行代码后,我们得到了类似这样的结果。

此外,法术,符文和物品信息将从数据龙获得。现在,您几乎已经获得了构建 op.gg 这样的应用程序所需的所有数据。

确定冠军位置

如果你刊登最新的比赛细节。你可能会注意到位置信息和我们从 op.gg 得到的有点不同。

‘role’: ‘DUO_CARRY’,‘lane’: ‘BOTTOM’

你可以建立一个地图来确定每个冠军的位置。

  • (中路,独奏):中路
  • (TOP_LANE,SOLO): TOP
  • (丛林,无):丛林
  • (BOT_LANE,DUO_CARRY):底部
  • (BOT_LANE,DUO_SUPPORT):实用程序

下一步是什么

现在,您已经了解了什么是 Riot Games API,并且已经成功地使用 python 从 API 中检索了第一批数据。而这些几乎都是构建 op.gg 的数据。

Riot API 还提供对实时客户端数据和重放数据的访问。我打算谈谈如何构建一个基本的实时客户端脚本,为您提供有关您当前游戏的信息。如果你有任何问题,请在下面提问。

了解更多信息

如何使用 Scala 模式匹配

原文:https://towardsdatascience.com/how-to-use-scalas-pattern-matching-362a01aa32ca?source=collection_archive---------52-----------------------

当 if-else 语句太长时,就该考虑模式匹配了。

Andrew Ridley 在 Unsplash 上拍摄的照片

概观

模式匹配是 Scala 语言提供的最强大的工具之一。类似于 Kotlin 中的when语句和 Java 中的switch语句。

本质上,它将一个输入与我们想要匹配的所有可能的情况进行比较。在我看来,这是使用多行if-else语句的一种优雅的替代方式,当有许多案例需要比较时,可读性更好。

在本教程中,我们将通过几个不同的场景来学*如何在 Scala 中使用模式匹配。

对科特林的when说法感兴趣的,可以去看看这个教程

Scala 模式匹配剖析

Scala 模式匹配的剖析如下。

objectToMatch match {
  case object1 => println("You match object1.")
  case object2 => println("You match object2.")
  case _ => println("You match neither object1 nor object2.")
}

objectToMatch是你试图模式匹配的 Scala 对象的可能值。

case object1case object2是你所知道的可能与objectToMatch匹配的两种模式。

case _是 everything else 子句,它本质上意味着objectToMatchobject1object2都不匹配。

基本用法

既然我们已经理解了模式匹配的结构,让我们看一个简单的例子。

假设我们买了一袋混合水果,我们知道它通常含有苹果、香蕉、草莓或蓝莓。现在,我们有了一台能够对水果进行分类的扫描仪。如果我们使用 Scala 的模式匹配来编写程序,它会是这样的。

fruit match {
  case "apple" => println("received an apple.")
  case "banana" => println("received a banana.")
  case "strawberry" => println("received a strawberry.")
  case "blueberry" => println("received a blueberry.")
  case _ => println("unable to classify this fruit. is it really a fruit?")
}

如果您有一个名为fruit的变量,并且分配给它的值是apple,那么上面的模式匹配语句将把received an apple.打印到您的控制台。诸如此类。

fruit的值既不是applebananastrawberry也不是blueberry时,语句会将unable to classify this fruit. is it really a fruit?打印到控制台。

现在,如果你要为此写一个if-else语句,它会是这样的。

if (fruit == "apple") *println*("received an apple.")
else if (fruit == "banana") *println*("received a banana.")
else if (fruit == "strawberry") *println*("received a strawberry.")
else if (fruit == "blueberry") *println*("received a blueberry.")
else *println*("unable to classify this fruit. is it really a fruit?")

在我看来,模式匹配表达式比if-else更具可读性,但是,嘿,这真的取决于你的偏好。归根结底,上述两种说法做的是同样的事情。

与案例类匹配

除了匹配对象本身的值,我们还可以匹配可能的类型(或case class)。

假设我们正在为一家超市的新鲜农产品部的计算机扫描仪编写一个分类程序。扫描仪将根据物品的类型给物品贴上标签,例如水果或蔬菜。我想这就是我们如何定义我们的特征和案例类。

trait GroceryItem

case class Fruit(name: String) extends GroceryItem

case class Vegetable(name: String) extends GroceryItem

现在,我们将编写一个函数,它将一个GroceryItem对象作为其输入,并对它是Fruit还是Vegetable进行分类。这是它最简单的写法。

def classifyGroceryItem(item: GroceryItem): Unit =
  item match {
    case _: Fruit => *println*("label item as fruit.")
    case _: Vegetable => *println*("label item as vegetable.")
    case _ => *println*("unable to label the item. this seems to be an item for other department.")
  }

注意语法_: Fruit。当我们想要对它的实例类型进行模式匹配时,我们应该这样写我们的case。此外,该表达式实际上并不查看字段case class的值(例如name)。

如果我们还想匹配 case 类的字段,我们可以这样做(看第一个case表达式)。

def classifyGroceryItem(item: GroceryItem): Unit =
  item match {
    case *Fruit*(name) if name == "apple" => *println*("item is a fruit and it's an apple.") 
    case _: Fruit => *println*("label item as fruit.")
    case _: Vegetable => *println*("label item as vegetable.")
    case _ => *println*("unable to label the item. this seems to be an item for other department.")
  }

请注意,case 表达式的顺序很重要。在上面的例子中,如果附加的case Fruit(name)表达式放在case _: Fruit之后,代码将永远不会到达它,因为它将立即匹配case _: Fruit

从这个例子中,我们还了解到我们可以在case语句上添加一个if语句。我发现这在某些情况下很有用。

与选项匹配

在 Scala 中,我们可能有一个Option类型的对象,这仅仅意味着我们可能有也可能没有值。

假设我们有一个函数,它根据商品的名称扫描超市的库存,如果找到了商品,就返回数量。

val inventory: Map[String, Int] = *Map*(
  "apple" -> 10,
  "banana" -> 15,
  "strawberry" -> 10,
  "spinach" -> 30,
  "capsicum" -> 25
)

def findItemAndReturnQuantity(itemName: String): Option[Int] = {
  inventory.get(itemName)
}

findItemAndReturnQuantity("sugar") // res1: Option[Int] = None
findItemAndReturnQuantity("spinach") // res2: Option[Int] = Some(30)

我们可以使用模式匹配来处理一个Option对象。让我们编写一个函数来处理findItemAndReturnQuantity函数的输出。

def handleOptionItemQuantity(quantity: Option[Int]) =
  quantity match {
    case Some(value) => *println*(s"quantity is **$**value.")
    case None => *println*("item is not available.")
  }

综合起来看:

handleOptionItemQuantity(findItemAndReturnQuantity("strawberry"))
// quantity is 10.

太好了。🙂

在我们结束这一部分之前,我想向您展示一个简单的提示。在某些情况下,比如这个Option对象,编译器知道可能的结果是什么。因此,当您键入模式匹配表达式时,应该会看到下面的建议。

匹配(详尽)

如果您选择match (exhaustive),它将自动填充值存在和不存在的情况。

def handleOptionItemQuantity(quantity: Option[Int]) =
  quantity match {
    case Some(value) => 
    case None =>
  }

记住,如果需要的话,我们还可以在上面的表达式中添加if语句。例如,当某个商品的库存量不足时,我们希望通知我们的员工。

def handleOptionItemQuantity(quantity: Option[Int]) =
  quantity match {
    case Some(value) if value < 10 => *println*(s"low stock - quantity is **$**value.")
    case Some(value) => *println*(s"quantity is **$**value.")
    case None => *println*("item is not available.")
  }

就是这样。😃

包裹

当你读到这一节的时候,你已经学会了 Scala 模式匹配的基础知识。您现在应该能够在您的代码中使用它,或者替换一些现有的多行语句if-else

如果你也像我一样用 Kotlin 编程,你可能想看看这篇关于 Kotlin 的 when 语句的教程。它本质上相当于 Scala 对 Kotlin 的模式匹配。

当你不知道将要发生什么的时候,如何用科学来决定

原文:https://towardsdatascience.com/how-to-use-science-to-decide-when-you-dont-know-what-s-going-to-happen-3271eef061de?source=collection_archive---------56-----------------------

用不精确的概率做决策是一件有风险的事情

媒体倾向于指出重新开放经济相对于保持封锁的风险或好处。很少看到任何新闻媒体采取系统的方法,这是我们希望决策者正在做的。我们知道统计爱好者。随着大部分经济现在重新开放,我们抱着最好的希望,但在不确定的时期,我们能确定什么呢?数学可能有答案。

维基百科用户 Alinaderi158 CCA-SA 4.0 的照片。

在我对传感器、机器学*和协作机器人的研究中,理解当你不知道将要发生什么时如何做出决定是我一直在处理的事情。数学可以告诉我们一些我们面临的事情,即使有很多我们不知道的事情。

我们做的每一个决定都有一定的风险。我买本田还是丰田?或者我应该省下那笔钱去坐公交车?去杂货店安全吗?还是我应该呆在家里叫外卖?在工作变得更安全之前,我能靠失业救济金生活下去吗?还是我应该现在就回去?

这些决定伴随着风险。它们也伴随着不确定性。

你可以把风险想象成人生的“已知的未知”,不确定性想象成人生的“未知的未知”。

我们现在都在应对的一大未知是冠状病毒。我向你保证,在 2019 年底和 2020 年初,数以千计的风险评估会议在无数的董事会会议室举行,没有提到全球疫情和全球封锁。它能被解释吗?可能比以前好,但不是完全好。

十几岁时,我是艾萨克·阿西莫夫的超级粉丝。阿西莫夫最出名的有两件事:他的机器人规则和虚构的心理史学,预测未来的数学,他在他的基金会系列中扮演了一个关键角色。从根本上说,阿西莫夫的心理史学是关于在不确定性下的决策,相信大规模的政治运动是可以预测的,或者至少是可以管理的。

混沌理论告诉我们,我们不能做阿西莫夫想要的事情。有太多不可预测的事件会产生巨大的影响。用数学术语来说,它们对初始条件很敏感。即使是像单个病毒的单个 RNA 链的单个变化这样微小而无足轻重的事情,也能对人类事件产生巨大的影响。“蝴蝶效应”意味着没有人能够预测遥远未来的全球性事件。

然而,假设有一个完全理性的负责人,他可以在考虑所有因素的情况下做出决策,并以最小的成本实现利益最大化。知道任何结果的概率都是未知的,某些行动的好处也是未知的,那么即使是超级人工智能也能做出正确的选择吗?这种生物可以依赖哪种数学?这样的人会选择什么样的策略呢?

在协作机器人中,我们不会告诉机器人具体要做什么。我们也不会让他们自己想办法。他们是团队的一部分,团队需要知道如何一起工作。我们使用战术手册。剧本是在很长一段时间内开发出来的,很多游戏,看看什么可行,什么不可行。这也需要一个有经验的教练根据情况选择正确的打法。

任何决策者在做出任何政策决定之前,手中都应该有一个剧本。边走边编是一个灾难的处方。这个剧本需要由手头的主题和政策制定方面的专家来编写,这样他们就知道什么样的决策是可行的。剧本必须包含决策者愿意做出的所有决策。

然而,我们如何利用数据从剧本中做出选择呢?如果你的专家中有一位是数学家,他们可能会建议一些数学方法来用不精确的概率做决策。

不确定性(我们称之为不精确概率)下的决策数学关注的是在你不知道最糟糕的事情会发生或者发生的可能性有多大的情况下做出最佳决策。数学家将最佳决策定义为带来最高收益的决策,这是一个衡量做出给定决策的总体收益的数字。

没有不确定性,做出任何选择的收益都很容易计算,即使结果是随机的。例如,假设你给我一个有六个面的骰子,告诉我如果我掷出 6,你会给我 10 美元,但如果我掷出其他任何东西,我必须付给你 x 美元。x 应该是多少才能让我接受你的提议?事实证明,有一个精确的数学答案,它来自于对“期望值”的计算,而“期望值”就是一个结果的成本或收益乘以它的概率。如果你把所有可能结果的期望值相加,就得到总期望值。如果期望值为正,总的来说,你会受益。如果是负数,总的来说,你会输。赌场知道这一点,因此操纵他们所有的游戏,以预期价值使赌场受益。

在骰子的情况下,掷出 6 的概率是 1/6。滚动其他任何东西的概率是 5/6。10 乘以 1/6 等于 10/6。x 乘以 5/6 等于 5x/6。两者相减,10/6 减去 5x/6,得到(10–5x)/6 或 5(2-x)/6。做一点数学计算,你会发现,如果 x 小于 2 美元,我会受益。如果 x 大于 2 美元,你就会获利。现在,对于一次掷骰,即使 x 很大,我仍可能获得收益。同样地,即使 x 很小,你也可能获得收益。但是在很多很多次的掷骰中,平均来说,具有最高期望值的人获胜的几率更大。

如果你想在任何碰运气的游戏中获胜,你所要做的就是计算出期望值是多少,并确保你能连续玩很多很多次。这就是为什么赌场和彩票中的大多数机会游戏都被操纵,以至于“庄家总是赢”。另一方面,股票市场通常有一个正的期望值。只要你把赌注压在很多很多股票上,就像投资股市指数基金一样,从长远来看,你就不会出错。

您可以将期望值应用于金融、物理、化学、生物等许多领域。数十亿年来,通过反复试验,进化已经确定了许多行为和解剖结构的预期值,并导致我们的形态和功能发展,因为它必须最大化我们的生存机会。

那么为什么不在决策中使用期望值呢?你可以,但是期望值只有在你知道期望什么时才起作用。如果没有呢?与进化不同,我们没有数不清的岁月和数十亿条生命来牺牲,来寻找合适的时机。计算机模型可能对此有所帮助,但是模型也依赖于知道会发生什么;你还能怎么造一个?

数学家们也研究了这个问题,并制定了一些策略。如果你无知,你所拥有的只是你对现实的信念来做决定。然而,这些都不是信仰的飞跃。相反,它们更像是猜测。对于每一个决策,你都要对该决策的最小预期收益或“效用”进行猜测。同样,你对不做这个决定的最大预期成本进行了猜测。

为什么我们关心最小的收益和最大的成本?原因是因为我们想限制我们的预期收益,这样我们就知道它会超过我们的猜测。

例如,假设我想在一次不能保证公平的掷硬币游戏中下注。它抬头的几率在 0.2 到 0.7 之间。我有五美元,我可以用任何方式把它分成正面和反面。我的增益是代表除法的可能结果的函数。最好的划分是什么?

把 h 股放在正面,把 T 股放在反面的预期效用是这些中最小的:

高 x 0.2-高 x 0.8

T x 0.3-H x 0.7

例如,如果我把 2 美元放在正面,3 美元放在反面,那么我的预期效用要么是 2 美元的损失,要么是 1.90 美元的损失,所以预期效用是负 2 美元。

如果我想找出最佳赌注是什么,我需要找出每个赌注的这些函数的最小值的最大值是多少。在 H+T=5 的约束下,这很简单,它就是两个函数相等的地方,或者两条线相交的地方。

最上面一行是最大期望值解。底线是每组赌注的最小期望值解。由作者用 Mathematica 创建。

那个点在 H=$2.75,T=$2.25。它当然还是会输。

这种决策方式被称为“马希民”,因为我们追求最小收益的最大化。它也被称为“最坏情况优化”决策,因为它是如此悲观[1]。几十年来,国际象棋程序一直利用这一点来战胜人类棋手。

也可以尝试优化最大增益。这就是所谓的“最佳情况优化”。那个点是两条线中任何一条的最高点。在这种情况下,最好的情况是把你所有的钱都押在反面,不要押在正面。这给了你大约 1.50 美元的估计收益。

然而,假设我想有一系列好的选择,而不是让这些算法为我挑选一个?如果我真的不确定概率,那么我可能只想过滤掉不好的概率。

有几种方法可以做到这一点。一个观察是,如果做出特定决策 D 的收益总是与所有其他决策一样好,但只对一个 E 更好,那么你应该扔掉 E,因为它永远不会击败 D。这被称为通过“逐点优势”选择最优集合。

一旦你这样做了,你就可以比较每一对决定。你减去他们的收益,然后计算两个决策的最坏情况期望值。这就像看着你的决定选择一个决定而不是另一个决定,看看你会失去什么。那些输给所有其他决定的人,你会丢掉。这种决策方法被称为“最大化”,因为你只是在寻找一个比其他人更好的“最大”决策集。

另一个选择是,只看某个给定决策的“最佳情况”和“最坏情况”之间的期望值都比另一个的期望值好的情况。换句话说,如果我锁定的最佳情况增益是 5,最差情况增益是-7,但我什么都不做的最佳情况增益是-8,那么即使锁定不是我最喜欢的选择,我也必须放弃什么都不做。这种方法被称为“区间支配”,是另一种摆脱糟糕选择的好方法。

我们的最后一个选择叫做电子证据可采性。在这种情况下,我们选择最大化至少一个预期效用情景的决策。也就是说,如果我看每一个可能的决策的预期效用,对于我提出的每一组概率,只有那些在保留方案中最好的才会被保留。这就像想象许多可能的场景,并抛弃那些在任何一个场景中都不尽如人意的决策。剩下的是那些有机会成为最佳选择的。

哪种方法最好?一般来说,如果你很不确定,你就不要选择 maximax 或马希民,因为不管你知道的有多少,你只会得到一个答案。然而,电子容许性、区间优势和极大性将会给你一些与你的不确定性成比例的好决策。少一些确定,多一些答案。就像柴郡猫说的,“如果你不知道你要去哪里,任何道路都可以。”

不考虑最大值和马希民,区间优势倾向于给你留下许多决策。如果你想要的只是摆脱那些完全糟糕的决定,那没问题。否则,最好选择 E-admissive 或 maximality。当你只有两个选择时,这些结果是一样的。一般来说,电子可接受性比最大性稍强。它考虑到了每一种可能的情况,但如果你过于乐观,它可能会被滥用,因为与 maximality 不同,它不仅仅关注最悲观的情况。

在任何情况下,无论你选择什么,都不能保证你不犯错误。你能保证的就是你做了你能做的最好的选择。

[1]特罗法,马蒂亚斯厘米。"使用不精确的概率在不确定的情况下做出决策."《国际*似推理杂志》第 45 期,第 1 号(2007):17–29。

如何使用 Scikit-Learn 数据集进行机器学*

原文:https://towardsdatascience.com/how-to-use-scikit-learn-datasets-for-machine-learning-d6493b38eca3?source=collection_archive---------6-----------------------

我们将探索乳腺癌数据集,并创建一个肿瘤分类模型

国立癌症研究所Unsplash 上拍摄的照片

Scikit-Learn 提供干净的数据集供您在构建 ML 模型时使用。当我说清洁时,我指的是准备好用于训练 ML 模型的清洁类型。最精彩的部分?这些数据集与 Scikit-Learn 包本身一起提供。你不需要下载任何东西。只需几行代码,您就可以处理数据。

拥有现成的数据集是一项巨大的资产,因为您可以直接创建模型,而不必花费时间来获取、清理和转换数据,而这正是数据科学家花费大量时间的事情。

即使所有的基础工作都已完成,您可能会发现使用 Scikit-Learn 数据集一开始会有点混乱。不要担心,几分钟后你将确切地知道如何使用数据集,并在探索人工智能世界的道路上前进。本文假设您已经安装了 python、scikit-learn、pandas 和 Jupyter Notebook(或者您可以使用 Google Collab)。我们开始吧。

Scikit-Learn 数据集简介

Scikit-Learn 提供了七个数据集,他们称之为玩具数据集。不要被“玩具”这个词所迷惑。这些数据集非常强大,可以作为学* ML 的一个强有力的起点。以下是一些数据集以及如何使用 ML:

  • 波士顿房价-使用 ML 根据该城镇的房间数量、犯罪率等属性来预测房价
  • 乳腺癌威斯康星州(诊断)数据集-使用 ML 将癌症扫描诊断为良性(不会扩散到身体其他部位)或恶性(扩散到身体其他部位)
  • 葡萄酒识别—使用 ML 根据化学特征识别葡萄酒的类型

在本文中,我们将使用“威斯康星州乳腺癌”数据集。我们将导入数据并理解如何读取它。作为奖励,我们将建立一个简单的 ML 模型,能够将癌症扫描分类为恶性或良性。要阅读更多关于数据集的信息,请点击这里获取 Scikit-Learn 的文档。

我如何导入数据集?

数据集可以在sklearn.datasets.让我们导入数据中找到。我们首先导入保存所有七个数据集的datasets

from sklearn import datasets

每个数据集都有一个用于加载数据集的相应函数。这些函数遵循相同的格式:“load_DATASET()”,其中 DATASET 是指数据集的名称。对于乳腺癌数据集,我们使用load_breast_cancer()。类似地,对于葡萄酒数据集,我们将使用load_wine()。让我们加载数据集,并将其存储到一个名为 data 的变量中。

data = datasets.load_breast_cancer()

到目前为止,一切顺利。这些加载函数(如load_breast_cancer())不会以我们期望的表格格式返回数据。他们返回一个Bunch对象。不知道什么是Bunch?别担心。

把一个**Bunch object** 想象成 Scikit-Learn 对一本字典的别出心裁的名字

照片由 Edho PratamaUnsplash 上拍摄

让我们快速回忆一下字典。字典是一种将数据存储为键和值的数据结构。把字典想象成你所熟悉的那本字典。您搜索单词(关键字),并获得它们的定义(值)。在编程中,你可以选择任意的键和值(单词,数字等等。).例如,为了存储电话簿,键可以是姓名,值可以是电话号码。所以你看,Python 中的字典不仅仅局限于你熟悉的典型字典,而是可以应用于你喜欢的任何东西。

我们的字典里有什么(Bunch)?

Scikit 的字典还是Bunch真的很厉害。让我们从看它的检索表开始。

print(data.keys())

我们得到以下密钥:

  • data是所有的特征数据(帮助我们识别肿瘤是恶性还是良性的扫描的属性,如半径、面积等。)在 NumPy 数组中
  • target是 NumPy 数组中的目标数据(要预测的变量,在本例中为肿瘤是恶性还是良性),

这两个键是实际数据。其余的键(如下)用于描述目的。值得注意的是,所有的 Scikit-Learn 数据集都分为datatargetdata表示特征,这些特征是帮助模型学*如何预测的变量。target 包括实际标签。在我们的例子中,目标数据是将肿瘤分类为 0 表示恶性或 1 表示良性的一列。

  • feature_names是特征变量的名称,换句话说就是data中列的名称
  • target_names是目标变量的名称,换句话说就是target列的名称
  • DESCR,DESCRIPTION 的简称,是对数据集的描述
  • filename是 CSV 格式数据的实际文件的路径。

要查看一个键的值,您可以键入data.KEYNAME,其中 KEYNAME 表示键。所以如果我们想看数据集的描述,

print(data.DESCR) 

以下是输出的预览(完整描述太长,无法包含):

Scikit-Learn 乳腺癌数据集描述

您也可以通过访问 Scikit-Learn 的文档来查看数据集信息。他们的文档可读性更好,也更整洁。

使用数据集

现在我们已经了解了 load 函数返回的内容,让我们看看如何在 ML 模型中使用数据集。首先,如果您想探索数据集,可以使用pandas来完成。方法如下:

# Import pandas
import pandas as pd# Read the DataFrame, first using the feature data
df = pd.DataFrame(data.data, columns=data.feature_names)# Add a target column, and fill it with the target data
df['target'] = data.target# Show the first five rows
df.head()

数据框的裁剪视图(不包括所有列)

你应该感到骄傲。您已经将一个数据集加载到一个 Pandas 数据框架中,该数据框架已准备好供探索和使用。要真正看到这个数据集的价值,运行

df.info()

df.info()输出—注意没有丢失值

有几件事需要注意:

  • 没有任何缺失值,所有列都有 569 个值。这为我们节省了计算缺失值的时间。
  • 所有的数据类型都是数字。这很重要,因为 Scikit-Learn 模型不接受分类变量。在现实世界中,当我们得到分类变量时,我们将它们转换成数值变量。Scikit-Learn 的数据集没有分类变量。

因此,Scikit-Learn 负责数据清理工作。他们的数据集非常有价值。通过使用它们,你将从学* ML 中受益。

让我们做一些人工智能

最后,激动人心的部分。让我们建立一个模型,将癌症肿瘤分为恶性(扩散)或良性(非扩散)。这将向您展示如何将数据用于您自己的模型。我们将构建一个简单的 K *邻模型。

首先,让我们将数据集一分为二,一个用于训练模型,为其提供学*数据,另一个用于测试模型,查看模型对以前从未见过的数据(扫描)的执行情况。

# Store the feature data
X = data.data# store the target data
y = data.target# split the data using Scikit-Learn's train_test_splitfrom sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y)

这给了我们两个数据集——一个用于训练,一个用于测试。让我们开始训练模型。

from sklearn.neighbors import KNeighborsClassifier
logreg = KNeighborsClassifier(n_neighbors=6)logreg.fit(X_train, y_train)
logreg.score(X_test, y_test)

有没有得到 0.909 的输出?这意味着模型有 91%的准确性!是不是很神奇?在短短几分钟内,你就建立了一个对癌症扫描进行分类的模型,准确率高达 90%。当然,在现实世界中要比这复杂得多,但是你已经有了一个很好的开始。通过尝试使用 Scikit-Learn 的数据集建立模型,您将学到很多东西。如果有疑问,就用谷歌搜索你的任何问题。有一个巨大的机器学*社区,很可能你的问题以前被问过。快乐 AI 学*!

如何使用 Selenium 进行网页抓取并举例说明

原文:https://towardsdatascience.com/how-to-use-selenium-to-web-scrape-with-example-80f9b23a843a?source=collection_archive---------2-----------------------

使用 Selenium 从 Hoopshype.com 收集 NBA 球员的姓名和薪水

照片由 JC GellidonUnsplash

Selenium 是一个 Python 库和工具,用于自动化 web 浏览器来完成许多任务。其中之一是网络搜集,以提取有用的数据和信息,否则可能无法获得。这里有一个如何使用 Selenium 的分步指南,以从 https://hoopshype.com/salaries/players/网站提取 NBA 球员工资数据为例。

步骤 1 —安装和导入

pip install selenium

安装完成后,就可以开始导入了。

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import pandas as pd

步骤 2 —安装并访问网络驱动程序

网络驱动是这一过程的重要组成部分。它实际上会自动打开你的浏览器来访问你选择的网站。根据您使用哪种浏览器浏览互联网,此步骤会有所不同。我正好用谷歌 Chrome。有人说 Chrome 与 Selenium 配合使用效果最好,尽管它也支持 Internet Explorer、Firefox、Safari 和 Opera。对于 chrome,你首先需要在 https://chromedriver.chromium.org/downloads下载网络驱动。根据您的 Chrome 版本,有几种不同的下载选项。要找到你的 Chrome 版本,点击浏览器窗口右上角的 3 个垂直点,向下滚动帮助,选择“关于谷歌 Chrome”。在那里你会看到你的版本。我的版本是 80.0.3987.149,如下图所示。

现在,您需要知道您在本地计算机上保存 webdriver 下载的位置。我的只是保存在我默认的下载文件夹中。现在,您可以使用下载的 webdriver 的直接路径来创建一个驱动程序变量。

driver = webdriver.Chrome('/Users/MyUsername/Downloads/chromedriver')

步骤 3-通过 Python 访问网站

非常简单但非常重要的一步。你需要你的代码来打开你试图抓取的网站。

driver.get('[https://hoopshype.com/salaries/players/](https://hoopshype.com/salaries/players/)')

运行时,该代码片段将打开浏览器访问您想要的网站。

第 4 步—找到您正在搜集的特定信息

为了提取您想要搜集的信息,您需要定位元素的 XPath。XPath 是一种用于查找网页上任何元素的语法。要定位元素的 XPath,突出显示您要查找的列表中的第一个元素,右键单击并选择 inspect 这打开了开发者工具。对于我的例子,我首先想定位 NBA 球员的名字,所以我首先选择斯蒂芬·库里。

在开发者工具中,我们现在看到元素“斯蒂芬·库里”就是这样出现的。

斯蒂芬·库里< /a > < /td >

这个元素可以很容易地转换成它的 XPath,但是首先,我们需要记住,我们不只是试图定位这个元素,而是所有玩家的名字。使用相同的过程,我找到了列表中的下一个元素,拉塞尔·维斯特布鲁克。

拉塞尔·维斯特布鲁克< /a > < /td >

这两个(以及所有其他玩家名字)之间的共同点是<td class=”name”>,所以我们将使用它来创建一个包含所有玩家名字的列表。翻译成 XPath 看起来像//td[@class=”name”]。分解一下,所有的 XPaths 前面都有一个双斜线,我们希望它出现在一个 td 标签中,在那个 td 标签中的每个需要对应于【name】。我们现在可以用这个 Selenium 函数创建球员姓名列表。

players = driver.find_elements_by_xpath('//td[[@class](http://twitter.com/class)="name"]')

现在,为了将每个玩家的名字放入一个列表中,我们编写了这个函数。

players_list = []
for p in range(len(players)):
    players_list.append(players[p].text)

按照同样的过程来获得球员的薪水…

斯蒂芬·库里 2019/20 工资

40231758 美元

拉塞尔·威斯布鲁克 2019/20 赛季薪资

38,506,482 美元

在检查这些元素并转换成 XPath 时,我们可以忽略样式和数据值,只关心类。

salaries = driver.find_elements_by_xpath('//td[[@class](http://twitter.com/class)="hh-salaries-sorted"]')

和工资清单文本…

salaries_list = []
for s in range(len(salaries)):
    salaries_list.append(salaries[s].text)

第五步——申请每一年,把所有的事情联系起来

通常,在使用 Selenium 时,您会试图检索位于同一网站的多个不同页面上的数据。在我的例子中,hoopshype.com 有追溯到 1990/91 赛季的 NBA 薪资数据。

正如你所看到的,每个季节的 URL 之间的差异只是被包含在最后的年份的问题。所以 2018/19 赛季的网址是https://hoopshype.com/salaries/players/2018-2019/,1990/91 赛季的网址是https://hoopshype.com/salaries/players/1990-1991/。这样,我们可以创建一个函数,循环遍历每一年,分别访问每个 URL,然后将我们之前展示的每一年的所有步骤放在一起。我还将每个球员与他们在该赛季的工资配对在一起,放入一个临时数据帧中,将年份添加到该临时数据帧中,然后将该临时数据帧添加到一个主数据帧中,该主数据帧包含了我们获得的所有数据。最后的代码在下面!

如何在熊猫中使用 SQL

原文:https://towardsdatascience.com/how-to-use-sql-in-pandas-62d8a0f6341?source=collection_archive---------5-----------------------

将另一项关系数据库技能添加到您的数据科学工具包中

https://images . unsplash . com/photo-1489875347897-49 f 64 b 51 C1 f 8?IX lib = r b-1 . 2 . 1&ixid = eyjhchbfawqiojeymdd 9&auto = format&fit = crop&w = 800&q = 60

如果您考虑熊猫数据帧的结构和来自 SQL 数据库的表的结构,它们的结构非常相似。它们都由数据点或值组成,每一行都有唯一的索引,每一列都有唯一的名称。因此,SQL 允许您快速访问您正在处理的任何项目所需的特定信息。但是,非常相似的查询可以使用熊猫!在这篇博文中,我将向您展示如何做到这一点,并解释您需要哪个库来实现它。

。查询()

使用 SQL 时,获取我们需要的信息叫做查询数据。在 Pandas 中,有一个内置的查询方法可以让您做完全相同的事情,它被称为。查询()。这既节省了时间,又使您的查询在代码中更加连贯,因为您不必使用切片语法。例如,一个使用查询 Pandas 中数据的简单示例。query() 方法会是:

query_df **=** df.query("Col_1 > Col_2")

否则,如果您不使用此方法获取数据,而是使用切片语法,它看起来会像这样:

query_df **=** df[df[df['Col_1'] **>** df['Col_2']]]

就像我说的,。query() 方法让你的代码看起来更专业,更高效。我想注意的一件重要的事情是,如果/当你决定在你的 Pandas 查询中使用“and”或“or”时,你实际上不能使用单词“and”或“or”——你必须使用符号“and”(&)和“or”(|)。下面是一个使用“&”帮助澄清的示例:

query_df **=** df.query("Col_1 > Col_2 & Col_2 <= Col_3")

pandasql 库

众所周知,使用 SQL 和/或其所有变体的能力是数据科学家在市场上最需要的工作技能之一,即使是在疫情时期。幸运的是,现在 Python 中有一个名为 pandasql 的库,它允许您编写 sql 风格的语法来从 Pandas DataFrames 中收集数据!这对于希望练* SQL 技能的有抱负的数据科学家和*惯于使用 SQL 风格的语法收集数据的有经验的数据科学家来说都是非常好的。要将它安装到您的计算机上,只需使用!pip 安装:

!pip install pandasql

然后,要将它导入到您的笔记本中,您需要从 pandasql: 中导入一个 sqldf 对象

**from** pandasql **import** sqldf

导入所有内容后,编写一个快速的 lambda 函数是一个好主意,它可以使编写查询更容易。这样做的原因是,每次使用一个对象时,不必传入全局变量。下面是我所学的 lambda 函数,我用它取得了成功:

pysqldf **=** **lambda** q: sqldf(q, globals())

现在,每当你向 pysqldf 传递一个查询时,全局变量将在 lambda 中传递,这样你就不必为每个使用的对象一遍又一遍地做这些了。

现在您已经做好了一切准备,可以使用与 SQL 相同的语法查询数据帧中的数据了!下面是一个例子—这个查询将从一个 df 中返回前 10 个名字:

q = """SELECT Name 
       FROM df 
       LIMIT 10;"""

names = pysqldf(q)
names

查询的复杂性取决于您的需求和您作为数据科学家的技能。因此,如果你*惯使用 SQL 风格的语法,或者希望提高你的 SQL 语法技能,使用 pandasql 可以是一个继续组织你的数据&练*你的技能的好方法。感谢您的阅读!

领英

我如何使用 Streamlit 构建 Web 应用程序

原文:https://towardsdatascience.com/how-to-use-streamlit-to-create-web-applications-218af44064f5?source=collection_archive---------8-----------------------

用于构建 Web 应用的 Streamlit 和 Python

威廉·艾文在 Unsplash 上的照片

W 说到网站设计,整体架构和建设是由前端开发人员负责的。这些开发人员接受想法和图像,并将其翻译成代码,以便这些想法和图像能够适当地显示在网站上。数据科学家通常不处理前端开发,更专注于应用程序或网站的内部功能。他们更专注于开发的后端。因此,许多数据科学家可能对开发前端应用程序来显示他们的数据科学项目的概念感到不舒服。但是,有一个简单的解决方案可以使前端开发的编码更加简单。

那个解决方案就是一个叫做— Streamlit 的 Python 库!

Streamlit 是一个开源的 Python 库,它使得 web 应用程序的开发变得更加简单,也更加美观。像许多其他 Python 库一样,这个库使复杂的技术性任务对数据科学家来说变得更加容易。为数据科学项目编写前端代码的过程不再像以前那样耗时耗力。

在这里注册一个中级会员,可以无限制地访问和支持像我这样的内容!在你的支持下,我赚了一小部分会费。谢谢!

在项目中使用 Streamlit

为了演示 Streamlit 的使用流程,我们将从一个数据科学项目开始:

人工智能媒人

并转换项目中的代码,使其具有交互性和视觉吸引力。

项目:人工智能媒人

作为这个项目的一点背景,主要思想是实现无监督的机器学*,将约会简档聚集在一起,然后在它们各自的簇内匹配它们。这将潜在地减少不兼容的匹配,并增加兼容的简档找到彼此的可能性。要了解有关该项目的编码和开发的更多信息,请单击下面的文章:

[## 我用机器学*和人工智能做了一个约会算法

为约会应用程序利用无监督机器学*

towardsdatascience.com](/dating-algorithms-using-machine-learning-and-ai-814b68ecd75e)

本文更深入地研究了所使用的聚类算法,以及用我们自己定制的约会资料数据集来创建和编码这些算法的过程。

与项目互动

这个项目的性质只是乞求用户的互动。如果我们有一个只是演示的约会算法,那有什么用呢?为了展示这个项目的全部范围和使用机器学*进行约会配置匹配的能力,我们必须能够与算法进行交互,并从用户输入数据。

在这里我们可以实现 Streamlit 来创建一个任何人都可以与之交互的简单用户界面。

创建 Streamlit 应用程序

为了运行 streamlit,我们必须先 安装 Streamlit 库 。安装完成后,创建一个空的.py文件,我们将使用它来编写应用程序正常运行所需的所有代码。您可以随意使用任何 IDE。

导入库

让我们从导入我们将使用的库和数据集开始。

在这里,我们正在加载我们的应用程序运行所需的所有库。数据集存储在.pkl文件中。本文介绍了这些数据集的来源:

[## 我为数据科学制作了 1000 份假的约会资料

我如何使用 Python Web Scraping 创建约会档案

towardsdatascience.com](/generating-fake-dating-profiles-for-data-science-cd3b929972bc)

但是,我们改进了这个过程,以接受实际的标签或类别,而不是之前的数值,这可以在下面的 Github 链接中看到:

[## Marcos an 93/人工智能媒婆

github.com](https://github.com/marcosan93/AI-Matchmaker/blob/master/Refining-Profile-Data.ipynb)

我们导入的下一个东西是用于用户输入数据的分类模型。如果你觉得有必要了解我们是如何对新用户数据进行分类的,那么看看这篇文章:

[## 约会应用如何处理新的个人资料?(第二部分)

使用无监督的机器学*用于新的约会简档

medium.com](https://medium.com/swlh/how-a-dating-app-handles-new-profiles-part-2-fca4f13b5205)

助手功能和类别

为了组织我们的脚本,当我们在 Streamlit 中运行我们的脚本时,我们必须创建一些助手函数来简化这个过程。我们稍后将使用这些函数。

让我们解释一下这些功能的作用:

  • string_convert()函数处理我们的原始数据。由于我们的数据集中的一些行和新的用户数据包含列表,因此该函数将这些列表转换为字符串数据类型,以便进行矢量化。
  • vectorization()函数创建每一列中使用的单词数组,然后删除相应的列。这为每行创建了一个包含字向量的大数据帧。该函数还对新用户输入的单词进行矢量化处理。
  • scaling()函数缩放矢量化的 DF 以及新的用户数据。
  • top_ten()函数组织 DF,并找出每个配置文件之间的相关性。然后,它根据新用户数据对相关数据进行排序。然后,它缩小到与新用户数据相关的前 10 个相似简档,然后返回这些简档的 DF。
  • example_bios()函数主要是为 streamlit app 创建的,通过显示数据集中的随机 bios。其目的是让用户在撰写自己的简历时作为参考。

类别和概率

这里使用的类别是每个配置文件可供选择的选项。它也是供用户在他们自己的约会简档中输入的选择列表。

为了准确地表示每个虚假简介的选择,每个选择的概率是基于每个选择的受欢迎程度而建立的。当随机选择时,这些概率将被考虑在内。

当一个新用户与应用程序交互时,他们会看到上面为他们的约会档案中的每个类别所做的选择。

编码 Streamlit 部分

现在,这就是 streamlit 库的用武之地。在这里,我们将开始使用 streamlit 函数,以便我们的应用程序能够顺利运行。点击此处查找以下所有功能的文档

标题和页眉

# Creating the Titles and Image
st.title("AI-MatchMaker")st.header("Finding a Date with Artificial Intelligence")
st.write("Using Machine Learning to Find the Top Dating Profiles for you")image = Image.open('robot_matchmaker.jpg')st.image(image, use_column_width=True)

上面的代码告诉 streamlit 显示 web 应用程序的标题、标题和图像。这将是用户在看到页面时首先看到的东西之一。

上面的代码显示了什么

输入新用户简介

# Instantiating a new DF row to classify later
new_profile = pd.DataFrame(columns=df.columns, 
                           index=[df.index[-1]+1])# Asking for new profile data
new_profile['Bios'] = st.text_input("Enter a Bio for yourself: ")# Printing out some example bios for the user        
example_bios()# Checking if the user wants random bios instead
random_vals = st.checkbox("Check here if you would like 
                           random values for yourself instead")

在这里,我们正在接受新的数据,算法将使用这些数据来查找前 10 个最相似的配置文件。这些信息将被储存在熊猫数据库中。我们也使用我们的example_bios()功能来显示随机的 bios 示例供用户参考。我们正在使用 Streamlit 的功能来接受文本输入,以及一个可选的复选框,如果他们选择这样做,将随机选择类别。

使用上面的 streamlit 代码时会看到什么

输入新的用户选择

接下来,我们将让用户做出选择,如果他们选择不随机化他们的选择。

这里我们做一个检查,看看用户是否勾选了要求随机值的复选框。如果他们选择了随机值,那么新的用户配置文件将包含为他们选择的随机值。但是,如果他们选择为自己选择值,那么他们将能够为自己选择值。

通过使用 streamlit 的multiselect()函数,我们可以让用户为指定的类别选择尽可能多的选项。slider()功能将允许用户通过与滑块小部件交互来选择他们的年龄。除了用户只能选择一个选项之外,selectbox()功能的作用类似于多选。

选择数据后,第一个格式化过程开始,将从multiselect()函数给出的列表转换成字符串和数据集的其余部分。这个过程是通过在循环中实现我们的string_convert()函数来完成的。

在这里,用户可以为呈现的每个类别进行选择

新的用户配置文件

在用户选择了类别并输入了自己的个人资料后,他们将会看到基于以下代码的约会资料:

# Displaying the User's Profile 
st.write("-"*1000)
st.write("Your profile:")
st.table(new_profile)# Push to start the matchmaking process
button = st.button("Click to find your Top 10!")

新用户的约会档案

从这里,用户可以更新他们的个人资料,如果他们希望改变他们的一些选择,或者他们可以通过单击突出显示的按钮继续找到他们的前 10 个约会资料。

寻找前 10 名

if button:    
    with st.spinner('Finding your Top 10 Matches...'):
        # Vectorizing the New Data
        df_v, input_df = vectorization(df, df.columns, new_profile)

        # Scaling the New Data
        new_df = scaling(df_v, input_df)

        # Predicting/Classifying the new data
        cluster = model.predict(new_df)

        # Finding the top 10 related profiles
        top_10_df = top_ten(cluster, vect_df, new_df)

        # Success message   
        st.success("Found your Top 10 Most Similar Profiles!")    
        st.balloons() # Displaying the Top 10 similar profiles
        st.table(top_10_df)

单击按钮时,将执行以下代码。点击后,由于with st.spinner(): streamlit 动画,将弹出加载或进度通知。这个进度条将一直显示,直到它下面的所有代码都执行完毕。

在 spinner 函数的下面,我们之前定义的 helper 函数将被执行,以根据我们新的用户配置文件数据找到前 10 个配置文件。找到前 10 个配置文件后,将执行 streamlit 的success() ( 显示成功通知)和balloons() ( 用动画庆祝气球短暂覆盖页面)函数。这些功能并不是完全必要的,但是它们可以使这个过程在视觉上更吸引人。

该过程完成后,将显示前 10 个相似的配置文件:

用户的前 10 名(需要向下滚动查看更多)

结论

我们已经成功地为我们的约会算法编写了一个 streamlit 应用程序!但是为了查看该应用程序的所有优点,您需要在命令终端中运行该应用程序。( 点击此处了解更多信息 )。一旦我们在终端中运行了应用程序,我们就可以随心所欲地与它进行交互。

现在可能有一些潜在的方法来改进整个项目和演示,所以可以随意修改代码。另一个大大改进这个项目的方法是,只要给他们一个应用程序的链接,任何人都可以使用这个应用程序。这需要通过使用 AWS 或 Heroku 将应用程序托管在云上。请关注下一篇文章,它将深入研究在云上部署应用程序!

查看后续文章,我们开发了一个网站来托管我们的 Streamlit 应用程序:

[## 我如何用 Python 和 AWS 制作一个网站

一步一步的教程

towardsdatascience.com](/creating-a-website-to-host-your-python-web-application-f06f694a87e8)

在 Twitter 上关注我:@Marco_Santos

资源

[## Marcos an 93/人工智能媒婆

使用无监督机器学*和 NLP - marcosan93/AI-Matchmaker 的匹配简档

github.com](https://github.com/marcosan93/AI-Matchmaker) [## 我用机器学*和人工智能做了一个约会算法

为约会应用程序利用无监督机器学*

towardsdatascience.com](/dating-algorithms-using-machine-learning-and-ai-814b68ecd75e) [## 我为数据科学制作了 1000 份假的约会资料

我如何使用 Python Web Scraping 创建约会档案

towardsdatascience.com](/generating-fake-dating-profiles-for-data-science-cd3b929972bc) [## 约会应用如何处理新的个人资料?(第二部分)

使用无监督的机器学*用于新的约会简档

medium.com](https://medium.com/swlh/how-a-dating-app-handles-new-profiles-part-2-fca4f13b5205)

如何使用 Streamlit 部署包装在漂亮的 Web 应用程序中的 ML 模型

原文:https://towardsdatascience.com/how-to-use-streamlit-to-deploy-your-ml-models-wrapped-in-beautiful-web-apps-66e07c3dd525?source=collection_archive---------20-----------------------

简化快速简单的机器学* Web 应用程序

不要浪费时间去学 Django 或者 Flask!

不要把时间浪费在学* Django 或者 Flask 上,多关注机器学*部分!

加州房价预测——Streamlit Web 应用程序(图片由作者提供)

如果你像我或任何其他机器学*爱好者一样,对你来说最糟糕的噩梦,显然不是 Cuda 错误,必须在其他地方部署模型,以在互联网上向你的朋友和网络展示你的工作。有许多方法可以解决这一问题,但在本文中,我将与您分享为什么我认为 Streamlit 是 it 的首选解决方案。

为了使这篇文章有条理并易于参考,让我们把它分成几个部分,这样你就可以直接跳到对你来说重要的部分。

  • 有哪些选择?
  • 为什么要简化?
  • 如何用现有的 ML 代码制作一个 Streamlit Web 应用程序?
  • 如何部署 Streamlit Web App?
  • 结论

可供选择的事物

还有一些其他的方法来部署 ML web 应用程序,但是它们都有一些缺点,最明显的一个缺点是没有什么比 Streamlit 更简单快捷了。

Tensor flow . js是 TensorFlow 官方使用 Javascript 部署 ML 模型的方式。这是一种将简单的 ML 模型快速部署到 Web 上的非常棒的方式,但是当涉及到复杂的模型时,许多模型还不被这个库支持,并且不是所有在 Python 中工作的模型都能保证在 Javascript 中以相同的方式工作。

*即使我说的是快速,它仍然需要比 Streamlit 更多的工作和时间!

[## 面向 Javascript 开发人员的机器学*

在浏览器、Node.js 或 Google 云平台中训练和部署模型。TensorFlow.js 是开源的 ML 平台…

www.tensorflow.org](https://www.tensorflow.org/js)

lask 是 python 中的一个小框架,它允许你使用你的 Python 技能来开发和部署 web 应用。如果你把它和 Streamlit 相比,你将需要更多的时间来编码和设计一个像样的 web 应用。

[## 欢迎使用 Flask — Flask 文档(1.1.x)

欢迎阅读 Flask 的文档。开始安装,然后了解快速入门概述。有…

flask.palletsprojects.com](https://flask.palletsprojects.com/en/1.1.x/)

D 是一个基于 Python 的 web 开发框架。使用这个框架来部署你的 ML 模型是一个很好的方法,它被包装在一个 web 应用程序中,但是这将需要大量的时间和对框架的理解。

[## 姜戈

Django 软件基金会非常重视我们开发人员、用户和社区的多样性。我们心烦意乱…

www.djangoproject.com](https://www.djangoproject.com/)

为什么选择 STREAMLIT?

机器学*爱好者不应该浪费时间学* web 开发,这样他们就可以专注于他们的目标,即构建更好的模型!

这正是 Streamlit 帮助我们的方式。这是构建 web 应用程序的最简单快捷的方法,它可以使用令人敬畏的 UI 元素和 Markdown 吸引人地呈现您的 ML 模型和数据。

[## Streamlit —创建数据应用程序的最快方式

Streamlit 是一个面向机器学*和数据科学团队的开源应用框架。在…中创建漂亮的数据应用程序

www.streamlit.io](https://www.streamlit.io/)

现在,在多次称赞 Streamlit 使用简单快捷之后,我这么说是什么意思呢?为了理解这一点,让我和你们分享一下我是如何偶然发现这个惊人的框架的。

我对生成对抗网络感兴趣,目前,我正在探索和构建一些使用不同种类的 GANs 的项目。为了分享我的探索之旅并记录我的项目,我开始撰写 GANs 系列,这是一系列关于 GANs 及其实现的文章。

我遇到的最大障碍是无法部署一个将黑白草图图像转换为彩色图像的条件 GAN 模型。我在生成器模型中使用的模型架构是一个 U-Net 模型,它有相当多的跳跃连接。你可以从这篇文章中浏览详细的解释,用一步一步的代码块来训练模型。

U-NET 模型架构—(图片来源:https://en.wikipedia.org/wiki/U-Net)

我尝试了前面讨论的 web 部署的所有替代方案。这个模型在 TensorFlow.js 中似乎没有预期的效果,我花了将*一周的时间学*和尝试 Django 框架。

这是我偶然看到Adrien Treuille的这篇优秀文章的时候,他展示了他如何使用 Streamlit 在13 行 Streamlit 代码下为一个 TL-GAN 制作了一个令人印象深刻的具有出色 UI 的 web 应用程序!

我花了大约 15 分钟在网站上浏览他们的基本文档,当我试图为我的模型实现它时,Adrien 没有夸大其词,我只花了 12 行 Streamlit 代码来加载经过训练的模型,将其包装在下面显示的 UI 中,并为部署做好准备。

使用条件 GAN 生成草图到彩色图像— Streamlit Web 应用程序(图片由作者提供)

用现有的 ML 代码制作 WEB 应用程序

是的,你没看错,
你只需在现有的 Python 文件中添加几个 Streamlit 函数调用,而无需任何 HTML、CSS 或 JAVASCRIPT 代码来设计你的 Web 应用!

您所要做的就是从 pip 安装 Streamlit 包,并在现有的 python 文件中添加一些 Streamlit 函数。要安装 Streamlit 只需使用以下命令:

pip install streamlit

要检查安装是否成功,并在他们的 hello world 应用中探索,只需使用命令:

streamlit hello

一旦您安装了您的 Streamlit 并根据您的需求进行了必要的更改,您只需使用一个命令在本地运行 web 应用程序

streamlit run file_name.py

它有各种很酷很有用的功能,比如:

  • 保存文件时实时修改
  • 只需按下键盘上的 R 键即可重新运行应用
  • 只需按键盘上的 C 键 即可清除缓存
  • 录制 web app 并在本地保存一个视频文件与大家分享
  • …还有更多

我在下面添加了一个 GitHub 要点,向您展示我是如何将 Streamlit 函数调用添加到草图到颜色图像生成模型的现有 python 代码中,使其成为一个功能齐全的 web 应用程序,如上图所示。

我在添加 Streamlit 代码之前的代码被注释掉,以便更容易看到需要做什么更改。如果您希望看到草图到彩色图像生成模型的代码,您可以浏览此处链接的文章

就是这样!如果包括导入语句和我实现的其他条件,实际上有 13 行额外代码。

部署 STREAMLIT WEB 应用程序

有各种选项可供您部署使用 Streamlit 构建的 web 应用程序。

H eroku 是一种可靠的方式来部署这些 web 应用程序,而不需要使用任何其他云服务并在其上设置虚拟实例。Heroku 为我们打理一切。但 Heroku 的一个缺点是,它在 dynos 的免费版本中只允许 512MB 的大小,TensorFlow 2.2.0 需要更多的空间来安装。如果您的代码不会中断,您可以使用任何低于 2.0.0 的版本。

Amazon Web Services是部署 Streamlit 应用程序的另一个好地方,而且比您想象的要简单。只需用 Ubuntu 18.04 或更高版本启动一个新的 EC2 实例,安装依赖项并运行streamlit run file_name.py命令。你将获得一个公共网址,你可以与你的朋友和网络在线分享,这样他们就可以通过你的出色的网络应用程序。

itHub repository 是为 Streamlit web 应用程序托管代码的另一种很酷的方式。这不能算作一个完整的部署方法,但 Streamlite 的一个优秀特性是它允许链接到 streamlit run 命令中的代码。因此,如果用户在他们的系统上安装了所有依赖项以及 Streamlit 包,他们可以通过提供到。py 文件。例如,您可以使用以下命令在您的系统上本地运行 my Streamlit web app:

streamlit run [https://raw.githubusercontent.com/tejasmorkar/housing_price_prediction_aws/master/CaliforniaHousingPrices.py](https://raw.githubusercontent.com/tejasmorkar/housing_price_prediction_aws/master/CaliforniaHousingPrices.py)

treamlit 仍然是一个新的框架,并致力于为其用户带来新的和酷的特性。其中一些将在他们的路线图中讨论。我期待的最激动人心的功能之一是一键轻松部署 Streamlit Web 应用程序。在论坛中阅读更多信息。

这是一个简单的 Web 应用程序的视频,我已经用 Ubuntu 18.04 在 AWS EC2 实例上部署了它。

加州房价预测演练视频— Streamlit Web 应用程序

结论

所以,这就是为什么我觉得 Streamlit 是一个如此令人印象深刻的框架,可以帮助每个人专注于机器学*开发的重要部分,并释放部署部分所需的压力。

少关注部署,多关注解决 Cuda 错误!

要开始使用 Streamlit,只需在链接上跳转到他们提供的官方文档—https://docs.streamlit.io/en/stable/

*如果您对从入门到部署 Streamlit web 应用程序的任何内容有任何疑问,您可以在论坛上搜索或提出新问题。您将找到社区成员和 Streamlit 团队回答的几乎所有问题的解决方案—【https://discuss.streamlit.io/ *

如果您有任何疑问、建议、错误或反馈,请随时通过任何最适合您的方式联系我!

我的联系信息:

邮箱:tejasmorkar@gmail.comLinkedIn:https://www.linkedin.com/in/tejasmorkar/ GitHub:https://github.com/tejasmorkar
Twitter:https://twitter.com/TejasMorka**

如何在 Julia 中使用语法表达式和调度

原文:https://towardsdatascience.com/how-to-use-syntactical-expressions-and-dispatch-in-julia-67ce155e4af9?source=collection_archive---------37-----------------------

朱莉娅综合教程

朱莉娅的面包和黄油:句法表达和多重调度

(图片作者:)

本文视频

今日回购:

[## emmettgb/JuliaLessons

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

github.com](https://github.com/emmettgb/JuliaLessons/tree/master/4)

介绍

在过去的几个教程中,我们已经学*了一些相对基础的编程概念,比如类型、循环和函数。所有这些基本技能最终都消失了——这意味着你可以实际练*和学*有趣的东西了!虽然你可能确实需要一些练*来达到这个目标,而且如果你打算认真对待它的话,这将是一个很大的工作量和终生学*的承诺,你正在成为一个伟大的 Julian 开发者!

虽然之前我们没有讨论任何特定于 Julia 语言的内容,但是今天将会有所改变。对于以前编程过的人来说,这是一个理想的地方——但实际上不是在 Julia 中。这意味着很快我们将会使用真正的软件包和解决真正的问题,这将会使这些教程变得更加有用和有趣!

不要惊慌

当然,仅仅通过观看一些视频来成为一名程序员是很困难的。幸运的是,我们将重复使用并反复复*我们在这些视频中学到的所有技能。如果你当时没有给予足够的关注,某些事情似乎很容易被掩盖——但是不要担心,你会明白的!

句法表达

在 Julia 中,语法表达式是一个奇妙的工具,它使得编写新函数来执行算术变得非常科学和容易。通常,我们可以使用这些表达式将原本需要十到二十行的代码压缩成一两行。在大多数语言中,您会像这样编写一个函数来计算平均值:

function mean(x)
    return(sum(x) / length(x))
end

在 Julia 中,我们甚至可以更快地完成像这样的小操作:

mean(x) = sum(x) / length(x)

虽然保存两行代码可能不会令人难以置信地改变生活,但是下一个例子是一个更大的代码压缩!:

function Normalize(array)
    q = std(array)
    avg = mean(array)
    [i = (i-avg) / q for i in array]
end

此标准化函数获取平均值和标准偏差,并将其放入公式中,以便对数据进行标准化。这在统计学中被称为数据的“正态分布”对于这样的函数来说,四行代码当然是合理的,但是,使用 Julia,我们可以使用 dispatch 将整个代码块压缩成一行。我们所要做的就是将我们的计算放入一行 for 循环中,并设置一个语法表达式将其连接到一个方法,如下所示:

normalize(x) = [i = (i-mean(x)) / std(x) for i in x]

与后者相比,使用这种方法的唯一缺点是,每次运行这个循环时,都要计算平均值和标准偏差。这意味着在每个节拍,处理器移动数据要做的第一件事是计算平均值,然后从当前迭代中减去它。这也是判断的一个很好的例子——什么时候需要保存性能,当我们改变循环时性能会损失多少?

如果使用得当,语法表达式是一个非常有用的工具。此外,它们可以允许您分派类型,并将这些分派函数作为数据使用——从而使范例更加灵活。

多重调度

多重分派是 Julia 编程语言的最大特点。它甚至在朱莉娅的网站上写着,

"朱莉娅使用多重分派作为范例."

在这种情况下,Julia 解决多态性技术问题的方法成为一种通用的工具,允许该语言在它想要的任何范式中工作。dispatch 实际上可以应用于很多事情。Dispatch 甚至可以像孩子一样用方法创建对象,让 Julia 一下子变成了面向对象的编程语言。

虽然我们今天不会处理弯曲范式为所欲为的问题,但我们将研究如何以最基本的形式使用调度来改善你的生活。这两个函数也许能够以相同的类型运行,但是让我们假设运行 string()将一个字符串的类型更改为 string 会破坏我们的性能,或者使计算机爆炸,或者类似的事情。

function print_symbol(symb)
    symb = string(symb)
    for char in symb
        println(char)
    end
endfunction print_string(str::String)
    for char in str
        println(char)
    end
end

所以我们有两个函数,一个会导致我们的计算机崩溃,如果我们传递一个字符串,另一个会返回一个错误,如果我们试图传递一个符号。在大多数其他应用程序中,在这种情况下唯一的选择是单独调用这些函数——或者,如果这些是自定义对象,我们可以使用 decorators。不管怎样,朱莉娅很好地解决了这个问题。使用 dispatch,我们可以创建两行代码来识别正在使用的类型,然后为该类型调用正确的函数。

prints(symb::Symbol) = print_symbol(symb)
prints(symb::String) = print_string(symb)

现在我们可以打印这两种类型:

(图片由作者提供)

很酷,对吧?

结论

Julia 编程语言将许多解决编程问题的有趣方法带到了一个非常高级和优雅的解决方案版本中。如果你以前没有使用过许多其他编程语言,这是这种语言很难让人钦佩的伟大之处之一。

多才多艺是一个很好的词。

真正令人兴奋的是教程的进度!您可以正式将调度添加到您已经学*的内容列表中——或者至少从这些教程中变得熟悉!非常感谢您的阅读、观看和反馈!在下一个教程中,我们将回顾我们已经完成的内容,并添加我们的第一个模块!

如何在 react.js 中使用 tensorflow.js 情感分析

原文:https://towardsdatascience.com/how-to-use-tensorflow-js-in-react-js-sentimental-analysis-59c538c07256?source=collection_archive---------13-----------------------

与 TENSORFLOW 反应。射流研究…

了解如何在 react web 应用程序中实现情感分析

克里斯里德在 Unsplash 上的照片

2018 年 3 月,谷歌宣布tensor flow . js 1.0 版本,该版本使开发者能够直接在浏览器中或通过 JavaScript 在 Node.js 中使用机器学*(ML)模型。

从那以后,我总是想在我的项目中使用 google 发布的那些花哨的预训练模型,如对象检测、姿态估计等等。然而,这些例子和演示是用纯 JavaScript 显示,关于如何在 react 应用程序中使用它的指导很少。

灵感来自 Tensorflow.js 社区中的本森鲁阿代码【展示&讲述。我决定写一些关于使用 create-react-app + tensorflow.js 的东西,以鼓励更多的人加入这个社区:

本教程的最终目的是创建一个情感分析计算器,它可以计算书面句子的积极(1)或消极(0)。当你需要发现和防止应用程序中的负面评论时,这是非常有用的。

计算值接*零(否定句)

试玩 app 此处

1.0 设置您的创建-反应-应用程序

通过终端中的以下命令创建一个 Create-React-App :

npx create-react-app tfjs-sentiment
cd tfjs-sentiment

按如下方式安装 tensorflow.js:

npm install @tensorflow/tfjs 

并启动应用程序

npm start

2.0 理论和了解您的模型

我们在这里将使用的模型是 tensorflow.js 情感分析示例中的卷积神经网络(CNN)模型。它根据来自 IMDB 数据集的 25000 条电影评论进行训练,这些评论被标记为积极或消极情绪。

模型在这里可用,元数据在这里可用。在我们开始编码之前看一下。

基本上,这个模型是一个经过训练的神经网络,它是一种“特殊的算法”,可以将你输入的句子分为肯定(1)和否定(0)两类。

我们必须将正确的输入放入模型中,以使我们的模型能够顺利工作。你必须知道的第一件事是,模型工作是作为一种数学逻辑,使用数学输入进行训练,它不理解字面上的“单词”或“英语”。我们必须把我们的句子转换成某种数学输入,以便使它起作用。接下来是元数据,元数据将文字输入转换为数字输入,例如:

book >>> 274
cutely >>> 68327

注意:由于本教程关注的是如何在 react 中使用,这些模型背后的理论可以参考 word2vec 或其他 NLP 理论

通过将每个单词分割成数字记号,将句子编码成这些数字输入:

this is a book >>> 14,9,6,274

然后,数字记号被改变为固定长度(100)的序列,以便改变为 2d 张量

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,9,6,274

2D 张量

最后,这个序列被转换成一个 2D 张量(基本上是一个矩阵)输入到模型中,神奇的事情发生了,模型会自动将句子分类成肯定或否定的陈述。

3.0 编码

如果你理解了上面的逻辑,就很容易将其转化为行动。

3.1 加载模型和元数据

import * as tf from '@tensorflow/tfjs';//Model and metadata URL
const url = {
model: 'https://storage.googleapis.com/tfjs-models/tfjs/sentiment_cnn_v1/model.json',
metadata: 'https://storage.googleapis.com/tfjs-models/tfjs/sentiment_cnn_v1/metadata.json'
};async function loadModel(url) {
try {
const model = await tf.loadLayersModel(url.model);
setModel(model);} catch (err) {
console.log(err);
}}async function loadMetadata(url) {
try {
const metadataJson = await fetch(url.metadata);
const metadata = await metadataJson.json();
setMetadata(metadata);} catch (err) {
console.log(err);
}} //React Hook
const [metadata, setMetadata] = useState();
const [model, setModel] = useState();useEffect(()=>{
tf.ready().then(()=>{
loadModel(url)
loadMetadata(url)
});
},[])

3.2 将句子转换为张量输入:

这里,我们将根据上述理论设置一个函数来逐个函数地处理输入文本:

标记句子中的每个单词:

const inputText = text.trim().toLowerCase().replace(/(\.|\,|\!)/g, '').split(' ');

使用元数据将字母标记转换为数字标记:

//Convert the alphabetical token to numerical token using metadata
const OOV_INDEX = 2;const sequence = inputText.map(word => {
let wordIndex = metadata.word_index[word] + metadata.index_from;
if (wordIndex > metadata.vocabulary_size) {
wordIndex = OOV_INDEX;
}
return wordIndex;
});

通过 padSequences 函数将序列固定为固定长度(截断和填充)

const PAD_INDEX = 0;const padSequences = (sequences, maxLen, padding = 'pre', truncating = 'pre', value = PAD_INDEX) => {
return sequences.map(seq => {
if (seq.length > maxLen) {
if (truncating === 'pre') {
seq.splice(0, seq.length - maxLen);
} else {
seq.splice(maxLen, seq.length - maxLen);
}
}if (seq.length < maxLen) {
const pad = [];
for (let i = 0; i < maxLen - seq.length; ++i) {
pad.push(value);
}
if (padding === 'pre') {
seq = pad.concat(seq);
} else {
seq = seq.concat(pad);
}
}return seq;});}const paddedSequence = padSequences([sequence], metadata.max_len);

最后,将填充的序列转换成我们的张量 2D 矩阵

const input = tf.tensor2d(paddedSequence, [1, metadata.max_len]);

3.3 将 tensor2D 加载到模型中

当你得到所有正确的输入后,最后一个简单的步骤就是使用 model.predict 对你的输入进行分类。

const predictOut = model.predict(input);
const score = predictOut.dataSync()[0];
predictOut.dispose();
setScore(score)
return score;

3.4 设置文本字段和按钮

通过 npm 安装材料界面

npm install @material-ui/core

然后把下面的代码输入到你的 react 应用程序中,一个文本框将会出现,你可以愉快地玩这个模型了!

import {
TextField,
Button
} from '@material-ui/core'const [testText, setText] = useState("");<TextField
id="standard-read-only-input"
label="Type your sentences here"
onChange={(e)=> setText(e.target.value)}
defaultValue=""
value={testText}
multiline
rows={4}
variant="outlined"
/>
{testText !== "" ?
<Button style={{width:"20vh", height:"5vh"}} variant= "outlined" onClick={()=>getSentimentScore(testText)}>Calculate</Button>
: <></>}

4.0 最后的话:

作为一名 react 前端开发人员和一名数据科学学生,我正在积极寻求一种将我的数据科学知识和 react 技能结合在一起的解决方案。

TF.js 提供了在 react 中集成深度学*模型的便利,其优势是一切都可以在前端完成,我们不需要后端服务器(例如 fastAPI,flask)或无服务器功能(例如 AWS lambda)来集成我们基于 python 的模型,我们可以利用当前的免费主机提供商,如 netlify 和 vercel。

使用 TF.js 的缺点是没有服务器,所有深度学*的模型都必须下载才能使用,有些模型价值超过 100Mb,与服务器中预装的模型相比,这对用户来说是糟糕的体验。

最后,开发者应该根据需要选择合适的深度学*模型的实现。

谢谢你的阅读,希望你喜欢它。

源代码可在这里获得

我的 TF.js + React.js 文章:

[## 使用 React 和 Tensorflow.js 进行自定义对象检测

让我们用 Azure 自定义视觉在 30 分钟内制作一个实时自定义对象检测器

towardsdatascience.com](/custom-object-detection-using-react-with-tensorflow-js-7f79adee9cd4) [## 使用 react.js 将模型加载到 tensorflow.js

立即在 react.js 中使用您的 python Tensorflow 模型

towardsdatascience.com](/loading-models-into-tensorflow-js-using-react-js-f3e118ee4a59) [## 如何在 react.js 中使用 tensorflow.js 对象检测

使用 COCO-SSD 模型定位和识别单个图像中的多个对象

towardsdatascience.com](/how-to-use-tensorflow-js-in-react-js-object-detection-98b3782f08c2)

如何使用 Aito 引擎预测动物

原文:https://towardsdatascience.com/how-to-use-the-aito-engine-to-predict-animals-6853672eac7e?source=collection_archive---------62-----------------------

利用自动机器学*预测的逐步指南

今天,谈论数据不可能不提到人工智能、机器学*和数据工程等话题。事实上,虽然人工智能从 50 年代就开始被研究和讨论,但只是在过去几年里它才被大肆宣传并成为商业词汇的一部分。

有时很难看到所有流行词汇背后的东西,但在过去几年中,数据和人工智能确实处于新的突破性商业模式和社会创新的最前沿。商业和技术领导者是时候利用人工智能提供的优势了。

自动机器学*和智能预测

在机器学*中,一个从数据中学*规则的算法和技术工具箱,预测值一直是一个受欢迎的用例。通常,数据科学家使用回归算法(如线性或逻辑)来估计从属值之间的关系,从而使他们能够预测值。

这些众所周知的机器学*例子,如预测,结合算法和云技术的成熟,导致自动机器学*(AutoML)服务和平台的诞生。

通过 AutoML,我们可以使用简单的 API 请求对数据进行智能预测。这使得任何人,如果没有事先的数据科学知识,只需利用这些预先训练的机器学* API,就可以获得人工智能的好处。

最*的研究告诉我们,大多数人工智能项目的失败是由于缺乏熟练的员工和不切实际的期望。组织需要开始以不同的方式看待他们处理数据科学项目的方式。自动化机器学*是开始用真实数据进行实验的一种很好的方式,门槛低,可以转化为即时的商业价值。

智能预测引擎 Aito 简介

Aito 是一个智能预测引擎,使开发人员和专家能够获得机器学*能力。作为一个平台,它结合了数据库引擎和自动机器学*功能,如预测、相似性等。

传统的数据库平台通常专注于搜索和过滤已知信息。反过来,Aito 在此基础上增加了通过分析和索引你上传的数据的模式和特征来预测未知信息的能力。

Aito 可用于实现智能自动化,例如改善输入和预测数据、匹配系统之间的记录或自动化重复性决策。

使用案例和可能性是无穷无尽的,但 Aito 特别擅长的一个领域是机器人过程自动化(RPA)。借助 Aito,组织可以将智能添加到现有 RPA 工作流中,这有助于他们降低成本,并使现有团队能够增加更多业务价值。

使用 Aito 预测动物类型的步骤

由加州大学欧文分校提供的动物园数据集在 OpenML 中可用,它是不同动物布尔属性的一个非常简单的数据集合。这为我们提供了一个很好的基线数据集,我们可以使用它来根据动物的一些属性(如腿、尾巴、捕食者等)预测动物的类型(如鸟、鱼、哺乳动物)。

我们真的很容易预测这个动物园里的动物类型吗?通过自动机器学*和 Aito 引擎,我们可以快速回答这个问题。在几个实际步骤中,我们将向您展示如何使用 Aito 和进行预测查询。

创建 Aito 实例

如果你是 Aito 的新手,你可以从注册开始,创建一个新的实例。

创建过程非常简单,只需给它一个名称并选择所需的实例类型。沙盒类型是完全免费的,它给你足够的能力去尝试动物园的例子。

Aito 控制台中的实例创建面板

提交实例请求后,只需等待团队的确认。您的 Aito 实例详细信息将在 web 控制台中可见。

Aito 实例详细信息

记下仪表板中的 API url 和键。我们将使用这些参数与实例进行交互。

配置您的本地环境

虽然可以通过 web 控制台上传数据,但您需要使用 Aito CLI 和 Python SDKREST API 来适当利用引擎功能。

  1. 首先,使用以下命令将数据集下载到您的计算机上:
curl -O [https://www.openml.org/data/get_csv/52352/openml_phpZNNasq](https://www.openml.org/data/get_csv/52352/openml_phpZNNasq)

2.创建一个 python 虚拟环境,并使用命令 pip install aitoai 安装 Aito CLI

下载动物园数据集并安装 Aito CLI

3.通过将环境配置到 Aito 实例来完成设置。您可以通过设置 AITO _ 实例 _URL 和 AITO_API_KEY 环境变量来定义这一点。

为 Aito 实例配置环境

使用 Aito CLI 输入数据

安装 Aito CLI 并准备好使用后,让我们从从 zoo 数据集推断数据模式开始。因为在其核心,Aito 引擎表现为一个数据库,这是描述我们的数据看起来如何的必要步骤。幸运的是,这可以不费吹灰之力完成。

输入数据的最快方式是使用 Aito UI 拖放功能或 CLI quick-add-table 命令。这两个选项都将模式推断和数据上传捆绑到一个操作中,并从用户那里抽象出内部细节。但是,在下面的示例中,我们采用了更长的路线,将摄取步骤分解为单独的单个操作。这给了我们完全的控制权,也让我们对 Aito 的工作方式有了更好的理解。

  1. 使用 infer-table-schema 命令自动分析数据集,并将模式提取到 JSON 文件中。这个特性还使您能够在将数据提供给 Aito 之前,根据需要修改模式文件(在这个用例中不是这样)。
aito infer-table-schema csv < openml_phpZNNasq > inferredSchema.json 

自动模式推理

2.根据我们在上一步中推断的数据模式,在 Aito 实例中创建一个表(例如 myzoo)。使用以下命令:

aito database create-table myzoo inferredSchema.json

3.将动物园数据集文件从 CSV 转换为适合文件上传的格式(压缩的 NDJSON)。使用以下命令:

aito convert csv < openml_phpZNNasq > zoo-dataset.ndjson gzip zoo-dataset.ndjson

4.使用以下命令用数据填充 Aito 表(例如 myzoo ):

aito database upload-file myzoo zoo-dataset.ndjson.gz

正在将动物园数据集上传到 Aito 实例

5.数据集现在可以使用了,并准备好与 Aito API 功能一起使用。

使用 Aito 预测 API

从一开始,我们的目标是根据某些属性(例如腿、尾巴、捕食者等)预测动物的类型(例如鸟、鱼、哺乳动物)。通过在 Aito 中填充数据,我们获得了开箱即用的预测功能,只需查询 API 就可以访问这些功能。

1.首先准备一个 JSON 查询语句,描述我们想要使用什么属性以及我们想要预测什么。如果您想要查询在空中飞行、产卵、有羽毛和两条腿的动物类型,该语句可能是这样的:

{
  "from": "myzoo",
  "where": {
            "airborne": true,
            "eggs": true,
            "feathers": true,
            "legs": 2
  },
  "predict": "type"
}

2.将 JSON 查询语句保存到本地环境中的一个文件(例如 myquery.json)中。

JSON 查询文件

3.使用 curl 等工具将查询提交给 Aito 实例预测 API 端点。使用以下命令作为示例(填入您的实例 url 和 API 密钥):

curl -X POST “https://<YOUR_INSTANCE_URL>/api/v1/_predict” \> -H “accept: application/json” \
> -H “Content-Type: application/json” \
> -H “x-api-key: <YOUR_API_KEY>” \
> -d @myquery.json

Aito 预测 API 的查询

4.预测 API 响应将返回具有不同关联分数的多种动物类型。在这种情况下,我们的查询结果显示,我们正在寻找的动物类型有大约 96%的概率是鸟,其他动物类型的得分不到 1%。

进一步探索

您可以使用任何其他动物属性(检查推断的模式)来查询数据,但是从这个简单的示例用例中,我们可以看到使用 Aito 这样的服务进行数据分析有着巨大的潜力。

自动机器学*工具,如 Aito 引擎,可以简化日常操作,并通过简单的 API 请求带来真正的业务洞察力。

预测功能只是 Aito API 中 7 个以上功能中的一个。查看 API 文档并了解其他特性,如搜索、推荐、相似性等等。

如果你需要额外的灵感,看看 Aito 陈列柜,了解更多关于预测缺失输入值领导资格,甚至如何将门与宜家厨房框架搭配。

我希望这篇文章对你有用。请分享您的反馈和想法,并随时联系 TwitterLinkedin

布鲁诺

如何在 React.js 中使用带有自定义样式的 Google Maps API

原文:https://towardsdatascience.com/how-to-use-the-google-maps-api-with-custom-styling-in-react-js-f6e7e59273df?source=collection_archive---------8-----------------------

前端

在 React 项目中集成漂亮的谷歌地图

照片由像素皮克斯拜拍摄

当我的朋友尝试一个新发型时,我问他“你为什么剪成这样?”他说他想成为一名出色的模特。因此,我明白了人们喜欢独特而美丽地展示它们。

当我开发个人 react 应用程序时,我想实现 google map API。我在谷歌上搜索了很多例子,最后,我找到了一个简单的解决方案。在这里,我将简要说明我如何使用该应用程序,以及我们可以添加到谷歌地图的自定义样式。这里我们将从头开始看。你可以在这里看到演示。这是我在 Medium 的第 29 篇文章。

首先

如果你没有谷歌地图 API 令牌注册谷歌地图 API 并获得令牌使用!要获得令牌,您必须输入信用卡号码。然而,谷歌表示,如果你不亲自更新服务,他们不会向你的账户收费。做你的决定吧。一旦你有了 API 密匙,就开始开发你的应用吧!

要创建 react 应用程序,请在您的 shell/终端的特定文件夹(例如,desktop)中运行以下命令

npx create-react-app google-map

将创建一个新文件夹,并将其命名为 google-map。从这一步开始,用 Create React App 引导您的应用程序。有关更多信息,请单击链接。然后在 IDE 中打开该项目。我使用的是 VS 代码集成开发环境。

来自突发妮可·德·霍斯的照片

着手工作

如果您打开 react 应用程序,那么您需要删除不需要的文件。因此,您需要转到 src 文件夹,删除 Logo.svg、App.css、index.css 和 App.test.js 文件。并在名为 components,assets and helpers 的 src 文件夹中创建以下文件夹,然后将 serviceWorker.js 移动到助手的文件夹中,将 App.js 文件移动到 Components 文件夹中。然后打开 index.js 文件,删除 index.js 文件中的以下代码片段。

*import* ‘./index.css’;

然后修改 index.js 导入中的 App.js 和 serviceWorker.js 文件路径,如下所示。

*import* App *from* ‘./components/App’;
*import* * *as* serviceWorker *from* ‘./helpers/serviceWorker’;

转到 Components 文件夹,打开 App.js,删除 App 函数的返回部分。

您需要安装一个依赖项来将谷歌地图作为一个组件。为此,使用下面的命令来安装依赖项。

npm install --save google-maps-react

布鲁诺·纳西门托Unsplash 上拍照

完全(或彻底)地

在你的组件 app 里面新建一个文件,命名为 Map.js,然后你需要导入google-maps-rect。为此,在 Map.js 中添加以下代码片段。

import { Map, GoogleApiWrapper } from 'google-maps-react';

现在您需要呈现Map组件。因此,添加Map组件到你的渲染函数中。

在上面的代码中,我添加了普通的样式。我在 render 方法中使用了常量变量。

const mapStyles = {
  width: '100%',
  height: '100%',
};

您需要在 Maps.js 文件中添加 export default 语句,如下所示

export default GoogleApiWrapper({
  apiKey: 'TOKEN HERE'
})(MapContainer);

确保在这里输入您的 API 密钥!

来自爆炸克里斯蒂安·穆里略的照片

在 App.js 文件中导入Maps组件。所以你的 App.js 应该是这样的。

当你使用npm start启动你的开发服务器时,你会看到下面的结果。

嘣!你做到了,但是使用谷歌地图有什么意义呢?但是,合理地说,使用没有任何标记的谷歌地图有什么意义。因此,我们来添加一个标记。为此,更新您的Map组件以包含Marker组件。这里我使用了不同的纬度和经度,你可以使用任何你需要的纬度和经度。

import { Map, GoogleApiWrapper, Marker } from 'google-maps-react';

太好了!你在地图上添加了标记。

美好的事物永远是一种快乐

现在,您已经进入了本文最有趣的部分。现在,让我们来看看自定义样式。它只是一个 JSON 对象。您将在 GoogleMapStyles.js 文件中存储自定义样式 JSON。我使用的主题来自样式向导:谷歌地图 API。如果你需要更漂亮的样式,那么试试时髦地图的样式,或者通过定制 JSON 对象建立你自己独特的地图样式。您的 GoogleMapStyles.js 文件将如下所示。

现在你需要在你的Maps组件中导入这个样式的 JSON。

*import* googleMapStyles *from* “./GoogelMapStyle”;

导入样式 JSON 后,可以将样式 JSON 设置为Maps组件的defaultProps。这可以通过在类体之外的组件类本身上定义defaultProps来实现,如下面的代码片段所示:

Maps.defaultProps = googleMapStyles;

然后,您需要将这个属性传递给Map组件的样式属性,如下面的代码片段所示:

<Map
  *google*={*this*.props.google}
  *zoom*={15}
  *styles*={*this*.props.mapStyle}
  *initialCenter*={{ lat: 9.761927, lng: 79.95244 }}
/>;

现在你的Maps组件将如下面的文件所示。

把你的脚抬起来

在 react 中实现谷歌地图很容易。有很多 npm 包可以帮助 React 实现谷歌地图。对我来说,google-maps-react很容易使用,它是一个比其他更小的包。你可以从这个链接克隆回购。

快乐编码😊!!!

如何使用管道的魔力

原文:https://towardsdatascience.com/how-to-use-the-magic-of-pipelines-6e98d7e5c9b7?source=collection_archive---------46-----------------------

使用 ETL 拯救世界

斯文·库契尼奇在 Unsplash 上的照片

您肯定听说过管道或 ETL(提取转换负载),或者见过库中的一些方法,甚至听说过任何创建管道的工具。但是,您还没有使用它。所以,让我向你介绍管道的奇妙世界。

在了解如何使用它们之前,我们必须了解它是什么。

管道是一种包装和自动化流程的方式,这意味着流程将始终以相同的方式执行,具有相同的功能和参数,并且结果将始终符合预定的标准。

因此,正如您可能猜到的,目标是在每个开发阶段应用管道,以试图保证设计的过程不会与理想化的过程不同。

Kapwin g 制成

管道在数据科学中有两个特别的用途,要么是在生产中,要么是在建模/勘探过程中,这两个用途都非常重要。此外,它使我们的生活更容易。

第一个是数据 ETL。在制作过程中,分支要大得多,因此,花费在其中的细节层次也大得多,但是,可以总结为:

e(提取)—我如何收集数据?如果我要从一个或几个网站,一个或多个数据库,甚至一个简单的熊猫 csv 来收集它们。我们可以把这个阶段看作是数据读取阶段。

t(转换)—要使数据变得可用,我需要做些什么?这可以被认为是探索性数据分析的结论,这意味着在我们知道如何处理数据(移除特征、将分类变量转换为二进制数据、清理字符串等)之后。),我们将其全部编译在一个函数中,该函数保证清理总是以相同的方式进行。

l(加载)—这只是将数据保存为所需的格式(csv、数据库等)。)某处,要么云端,要么本地,随时随地使用。

这个过程的创建非常简单,只需拿起探索性数据分析笔记本,将 pandas read_csv 放入一个函数中;编写几个函数来准备数据并在一个函数中编译它们;最后创建一个函数保存前一个函数的结果。

有了这些,我们就可以在 python 文件中创建 main 函数,并且用一行代码执行创建的 ETL,而不用冒任何更改的风险。更不用说在一个地方改变/更新所有东西的好处了。

第二个,可能是最有利的管道,有助于解决机器学*中最常见的问题之一:参数化。

我们多少次面临这些问题:选择哪种模式?我应该使用规范化还是标准化?

“作者捕获的屏幕截图”

scikit-learn 等库为我们提供了流水线方法,我们可以将几个模型及其各自的参数方差放入其中,添加归一化、标准化甚至自定义流程等预处理,甚至在最后添加交叉验证。之后,将测试所有可能性,并返回结果,或者甚至只返回最佳结果,如下面的代码所示:

def build_model(X,y):                          
 pipeline = Pipeline([
        ('vect',CountVectorizer(tokenizer=tokenize)),
        ('tfidf', TfidfTransformer()),
        ('clf', MultiOutputClassifier(estimator=RandomForestClassifier()))                           ])# specify parameters for grid search                           parameters = { 
    # 'vect__ngram_range': ((1, 1), (1, 2)),  
    # 'vect__max_df': (0.5, 0.75, 1.0),                                
    # 'vect__max_features': (None, 5000, 10000),
    # 'tfidf__use_idf': (True, False),
    # 'clf__estimator__n_estimators': [50,100,150,200],
    # 'clf__estimator__max_depth': [20,50,100,200],
    # 'clf__estimator__random_state': [42]                                                   } 

# create grid search object                          
cv = GridSearchCV(pipeline, param_grid=parameters, verbose=1)                                                   return cv

在这个阶段,天空是极限!管道内部没有参数限制。然而,根据数据库和所选参数的不同,可能需要很长时间才能完成。即便如此,这也是一个非常好的研究工具。

我们可以添加一个函数来读取来自数据 ETL 的数据,并添加另一个函数来保存创建的模型,这样我们就有了模型 ETL,结束了这个阶段。

尽管我们谈论了所有的事情,创建管道的最大优点是代码的可复制性和可维护性,这是指数级提高的。

那么,开始创建管道还等什么呢?

这方面的一个例子可以在这个项目中找到。

如何在您的 Azure web 应用中使用 Microsoft 身份平台

原文:https://towardsdatascience.com/how-to-use-the-microsoft-identity-platform-in-your-azure-web-app-fcb3839a44e5?source=collection_archive---------26-----------------------

通过身份、角色和权限管理对应用的访问

介绍

微软身份平台是安全访问您的网络应用的关键。用户可以使用他们的 Azure AD 身份或社交帐户对你的应用进行身份验证。授权模型可用于向您的后端应用程序或标准 API(如 Microsoft Graph)授予权限。在这篇博客中,我们讨论了一个 web 应用程序,它具有以下功能:

  • 1.具有用户角色的 Azure AD 登录:基本或用户角色:高级
  • 2.使用已登录用户的委托权限访问 MS 图表
  • 3.使用应用程序权限和应用程序角色访问后端

项目的代码可以在这里找到,架构可以在下面找到。

项目架构,作者图片

重点是提供一个使用微软身份平台的工作示例,并“弄脏你的手”。重点不是解释 OAuth 2.0 和 Azure AD 的内部工作方式。在本博客的剩余部分,将讨论以下内容。

  • 步骤 0:准备工作—设置前端和后端
  • 步骤 1:访问前端— Azure AD 登录,添加用户角色
  • 步骤 2:访问图表-委托权限检索用户详细信息
  • 步骤 3:访问后端—应用程序检索数据的权限
  • 杂项:配置项目的其他可能性
  • 结论

要了解如何使用授权或应用程序权限访问 Azure SQL 数据库,请参见我之前的博客。注意,两个博客共享同一个 git repo,所以这个项目可以配置为访问 Azure SQL,而不是后端应用程序。

步骤 0。准备工作—设置前端和后端

这个示例展示了如何使用 Flask 和 MSAL Python 构建 Python 前端 web 应用程序,以及如何使用 Azure 函数构建后端应用程序。在该步骤中,执行以下子步骤:

  • 0.1:创建前端 web 应用程序
  • 0.2:创建和配置前端应用程序注册
  • 0.3.创建后端 Azure 功能
  • 0.4:配置 python webapp 项目
  • 0.5:运行示例
  • 0.6:(可选)将前端 web 应用部署到 Azure

0.1:创建前端 web 应用程序

若要运行此示例,您需要在本地安装它:

  • Python 2.7+Python 3+
  • Azure 活动目录(Azure AD)租户。有关如何获得 Azure AD 租户的更多信息,请参见如何获得 Azure AD 租户。
  • Git 克隆下面的项目:git clone https://github.com/rebremer/ms-identity-python-webapp-backend.git或者下载并解压存储库。zip 文件。

0.2:创建和配置应用程序注册

创建和配置应用程序注册,如下所示:

  • 使用此链接中的步骤创建应用注册以创建应用注册。两个备注:
  • 使用http://localhost/getAToken作为回复网址。如果您在创建过程中没有这样做,可以使用应用程序注册的验证选项卡添加它
  • 转到认证并启用隐式授权中的选项 ID 令牌
  • 转到证书&秘密创建一个秘密。复制客户端 id 和客户端密码

0.3:创建后端 Azure 函数

在这一部分,将部署 Azure 功能。这是按如下方式完成的:

  • 使用这个快速入门在 python 中创建一个 Azure 函数。
  • git repo 更新 blog-webappaad-backend 文件夹中的requirement.txt__init__.py,再次发布功能
  • 在此快速入门之后,使用快速设置在您的 Azure 功能中启用身份验证/授权。

0.4:配置 pythonwebapp 项目

  1. 打开app_config.py文件,改变下面的变量。
  2. 在步骤 1.2 中创建应用程序注册时,找到文本<<Enter_the_Client_Secret_here>> ,并将其替换为您的应用程序密码。
  3. 找到文本<<Enter_the_Tenant_Name_Here>>并用您的 Azure AD 租户名称替换现有值。
  4. 找到文本<<Enter_the_Application_Id_here>>并用步骤 1.2 中应用程序注册的应用程序 ID (clientId)替换现有值。
  5. 查找文本<<your Azure Function>><<your secret>>用步骤 1.3 中创建的 Azure 函数替换现有值。

0.5:运行示例

您需要使用 pip 安装依赖项,如下所示:

$ pip install -r requirements.txt

使用以下命令从 shell 或命令行运行 app.py:

flask run --host localhost --port 5000

当 app 在本地运行时,可以通过 localhost:5000(不是 127.0.0.1:5000)访问。步骤 1 之后,用户可以使用他们的 Azure AD 凭据登录,并从后端检索数据。

0.6:(可选)将前端 web 应用部署到 Azure

最后,请看这个链接如何在 Azure web 应用中部署你的前端 flask 应用。部署代码的最简单方法是从放置 app.py 的目录中运行以下命令:

az webapp up -n <<your unique webapp>> --sku F1

确保将https://<<your uniquewebapp>>.azurewebsites.net/getAToken添加为回复 URL。当您登录并点击链接从 backed 中检索数据时,应显示以下屏幕:

0.6.从后端成功检索到数据

然而,为了能够执行本教程的剩余步骤,也可以使用 localhost。

步骤 1:访问前端— AAD 登录,添加角色

在此步骤中,将为用户分配一个角色,以指示其是基本用户还是高级用户。执行以下子步骤:

  • 1.1:在应用配置中设置配置
  • 1.2:向清单添加角色
  • 1.3:为用户分配高级角色

步骤 1 关注架构的以下部分。

1.Azure 广告登录,配置用户角色,按作者分类的图片

1.1:在应用配置中设置配置

索赔验证是一个可选步骤,可以使用app_config.py文件中的以下设置启用:AAD_ROLE_CHECK = True

1.2:向清单添加角色

按照本教程中的步骤,向步骤 1.2 中创建的应用程序注册添加角色。显然,应使用以下方法:

"appRoles": [
  {
    "allowedMemberTypes": ["User"],
    "description": "Basic user, read product data from backend",
    "displayName": "basic_user_access",
    "id": "a8161423-2e8e-46c4-9997-f984faccb625",
    "isEnabled": true,
    "value": "basic_user_access"
  },
  {
    "allowedMemberTypes": ["User"],
    "description": "Premium user, read all data from backend",
    "displayName": "premium_user_access",
    "id": "b8161423-2e8e-46c4-9997-f984faccb625",
    "isEnabled": true,
    "value": "premium_user_access"
  }
],

1.3:将用户分配给角色

链接中解释了用户的分配。作为测试,可以创建两个用户。用户 1 被分配了basic_user_access,而用户 2 获得了premium_user_access角色,另请参见下面的屏幕截图,其中 admin、student2 被分配了高级角色,而 student 1 只有基本角色。

1.3a .分配给用户的角色

如果学生点击客户链接,对后端的访问将被前端拒绝,另请参见下面的消息。

1.3b .角色为“基本拒绝访问”的用户

在下一步中,使用 Microsoft Graph API 检索用户数据。

第二步。对图表的访问-委托权限

用户是 Azure 广告公司或学校用户帐户或 Microsoft Graph 中的 Microsoft 帐户的表示。在这个步骤中,使用users.read范围,使用登录用户的委托权限来检索自己的数据。执行以下子步骤:

  • 2.1:验证应用注册中的权限
  • 2.2:检索数据

第 2 步关注架构的后续部分。

2.委托权限,按作者获取图表数据、图像

2.1:验证应用注册中的权限

应用程序注册需要同意从 Microsoft Graph 读取用户数据。根据 Azure AD 配置,以下类型的同意是可能的:

  • 管理员同意:管理员已经同意应用程序可以代表登录的用户读取用户的数据。这种同意可以事先在应用程序注册权限中完成,也可以在管理员首次登录 web 应用程序时完成。
  • 用户同意:An uses 本人已经同意 app 可以代表登录用户读取用户的数据。一旦用户第一次登录应用程序,这种同意就完成了

在这种情况下,使用事先完成的管理员许可。请参阅下面的 users.read 权限是在应用程序注册中授予的:

2.1a .用户。读入应用程序注册管理员同意书

随后,在 app 注册的附着企业应用中验证 App 可以代表用户读取用户的数据。

2.1b .用户。读入应用程序注册管理员同意书

注意那个用户。只读允许用户检索他自己的数据,而不是其他人的数据(只有有权限的用户才能这样做。Read.All)

2.2:检索图形数据

一旦应用程序获得用户同意或管理员同意检索数据,只需登录并单击链接调用 Microsoft Graph API,用户自己的数据就会返回,也见下文。

2.2.图形调用返回用户数据

第三步。访问后端—应用程序权限

在步骤 1 中,已经从后端检索了数据。然而,不仅前端可以从后端检索数据,同一 Azure AD 租户内的所有身份都可以检索数据。使用应用程序权限和用户分配,确保只有前端可以访问后端。

执行以下子步骤:

  • 3.1:向后端和前端添加应用程序权限
  • 3.2:在后端启用用户分配

第 3 步关注架构的后续部分。

3.应用程序权限,配置应用程序角色,按作者分类的图像

3.1:向后端和前端添加应用程序权限

转到后端应用程序注册清单,并将以下应用程序角色添加到清单中。

"appRoles": [
  {
    "allowedMemberTypes": ["Application"],
    "description": "frontend_app_access",
    "displayName": "frontend_app_access",
    "id": "f8161423-2e8e-46c4-9997-f984faccb625",
    "isEnabled": true,
    "value": "frontend_app_access"
  },

随后,进入前端的应用注册,点击 API 权限,将这些权限授予你的前端应用,也见下文。

3.1a .在前端授予应用程序权限

随后,授予管理员权限,以便前端可以使用应用程序角色 front_end_access 访问后端。要验证前端是否具有应用程序角色 front_end_access,请转到后端应用程序注册、企业应用程序并查找用户/组,另请参见下文。

3.1b .后端的应用程序角色

请注意,角色 front_end_access 没有明确显示,但在 3.2 中将会显示该角色。

3.2:在后端启用用户分配

转到您的后端应用程序注册,企业应用程序,并寻找属性和启用用户分配,也见下文。

3.2a .后端中的应用程序角色

启用此属性时,前端是唯一可以从后端检索数据的应用程序,另请参见下面显示角色的位置

3.2b .显示的前端应用访问角色

多方面的

属于这个项目的 git repo 有额外的配置选项,讨论如下:

  • 通过在 appconfig 中设置DAEMON_ENABLED=True,可以将应用程序配置为守护程序应用程序。用户不必再登录来检索数据。
  • 通过在 appconfig 中设置Option 2b. Database,Azure SQL 数据库可以用作后端,而不是 Azure 函数。详见这篇博客。
  • 在应用程序配置中使用Option 3b. Delegated user is used to authenticate to backend,委托权限用于对后端而不是应用程序权限进行认证。
  • 这篇博客中的第 3 步可以通过调整这个 git repo 中的 Power Shell 脚本来实现自动化。

结论

Microsoft identity platform 可以帮助您保护对应用程序的访问。在这篇博客中,提供了一个具体的例子,它使用 Azure AD 以“基本”或“高级”用户角色登录用户。随后,登录用户的委托权限用于检索 Microsoft Graph 数据,应用程序权限用于访问后端,另请参见下面的架构。

项目架构,作者图片

如何使用 Google Sheets 中臭名昭著的 VLOOKUP 功能?

原文:https://towardsdatascience.com/how-to-use-the-notorious-vlookup-function-in-google-sheets-3dd6f825d4fe?source=collection_archive---------45-----------------------

电子表格/虚拟桌面

以及如何克服它带来的各种挑战。

照片由布鲁斯·马尔斯Unsplash 拍摄

Google Sheets(或 Microsoft Excel)最神奇(也最令人困惑)的功能之一是 VLOOKUP 。尽管从任何意义上来说都不完美,但它确实提供了强大的功能来连接两个不同的表,或者将一个表的值附加到另一个表中。

什么是 VLOOKUP?

VLOOKUP 是电子表格中的一个功能,它允许用户在两个表格之间建立关系。让我们试着用一个例子来理解它。

假设您是一家即将成立的游戏工作室的分析师,他们希望您创建一个 2002 年最畅销游戏的数据库。幸运的是,您发现了一个包含所有信息的惊人数据集,它是这样的:

它包含两个独立表格中的信息:

  • 一个表格包含游戏名称和发布平台的信息。
  • 第二个表包含游戏名称和北美和欧洲的销售额(以百万计)。

有关上述数据集的更多信息,您可以访问 Kaggle

我们如何合并两个表?我们可以简单地将值从一个复制粘贴到另一个。但是仔细看,两个表中的名字不是同一个顺序!嗯,我们可以一个一个复制粘贴。但是任务太多了!为什么不让电子表格来帮我们做呢?听起来像个计划!这就是全能的 VLOOKUP 函数出现的地方!

如何使用 VLOOKUP?

下面是 VLOOKUP 函数的样子:

=VLOOKUP(search_key, range, index, [is_sorted])

函数中需要的 3 个强制参数。以下是它们是什么以及它们是如何工作的:

VLOOKUP 函数的作用

  • 搜索关键字:选择您想要查找其值的单元格。在这个例子中,我们想要找到单元格 A2 中提到的游戏标题的NA_Sales数字。所以搜索关键字是 A2。
  • 范围 : 你想要的数值在哪里?在我们的例子中,它位于表中 D2 到 F16 的某个位置。因此,我们选择要从中复制值的整个表。请注意我们是如何添加许多$符号的。一旦你选择了表格范围,要做到这一点,只需按下键盘上的 F4,你会有相同的格式。

关于为什么使用$ signs 的一个小注意:一旦你创建了你的函数,下一个自然的步骤是向下拖动该函数并将其应用于下面的所有单元格。如果你没有按下 F4,随着拖动公式中的搜索键,你就是也在拖动你所选择的范围。这将意味着,为了找到对应于 A4 的值,您实际上是在范围 D3:F17 中搜索,而不是您原来的 D2:F16。所以如果你的 A4 值在 D2,你的函数不会读取它并抛出一个错误。这就是$符号出现的地方。按下 F4 一次,你就冻结了选定的范围,这样一旦你把公式拖到下面的单元格中,它就不会改变范围,而只会改变搜索关键字。

  • Index :在您刚刚选择的范围内,您要抓取的列是哪一列?在我们的例子中,它是NA_Sales列,这是 D2 到 F16 的选定范围中的第二列。请注意,索引号从步骤 2 中所选范围的第一列开始。
  • 已排序:这是一个可选的字段。出于所有实际目的,将其设置为零或假。就我个人而言,我从未遇到过将该字段设置为其他方式的情况。

然后按回车键!这个函数现在在您提到的的范围内,在您的搜索关键字中找到值,一旦找到匹配,它就会抓取提到的索引列并给出结果。在这种情况下,它将打印值 8.41,因为这是提到的第一个游戏在北美地区的销售额。以下是最终的解决方案:

成功实现 VLOOKUP 后的最终结果

常见陷阱以及如何避免它们

以下是应用 VLOOKUP 时需要记住的几个要点:

  1. 查找函数如何知道在提到的范围内匹配什么?请始终记住,查找函数只会匹配公式中指定范围的第一列中提到的值。在我们的例子中,我们提到的产品系列是 D2:F16。搜索关键字将只与 D2:F16 范围的 D 列中的值匹配。通常,搜索范围的第一列应该是搜索关键字所在的列。
  2. 查找函数将总是提供它得到的第一个结果
    例如,如果在销售表中多次提到一个游戏,它会获取第一个匹配的值并相应地提供结果。
    如果你有同一个搜索关键字的多个实例,VLOOKUP 是而不是要走的路!
  3. 您需要确保在范围中找到的搜索关键字完全匹配。不应该有多余的空格。字符串大小写应该是一样的。如果不是,它将与值不匹配,您将得不到想要的结果。
  4. 当 VLOOKUP 在该范围内没有找到您要寻找的值时,它通常会抛出一个 #N/A 错误。这仅仅意味着该值不存在于所提到的范围内,或者该范围存在一些额外的空格或大小写问题(如上所述)。

VLOOKUP 还有另一个变种,叫做 HLOOKUP。VLOOKUP 垂直匹配值,HLOOKUP 水平匹配值。该功能的工作方式完全相同。

VLOOKUP 并不是连接两个表的完美解决方案。但是在大多数情况下,小心执行并记住常见陷阱,你可以在很多场景中使用 VLOOKUP。还有另一种更强大的方法来解决连接两个表的问题,这种方法通常被称为索引匹配函数,在下一篇文章中会详细介绍。

同时,继续分析!

作为一名数据科学家,如何利用“为什么”的力量实现自己的目标

原文:https://towardsdatascience.com/how-to-use-the-power-of-why-to-achieve-what-you-want-65fdbde71ea3?source=collection_archive---------29-----------------------

(来源)

成为一名数据科学家很难。

成为一名 伟大的 数据科学家更难。

作为一名伟大的数据科学家,我的意思是对你所做的事情有热情和信念以及用数据解决问题的能力推动行动

现在…我这么说是什么意思?

数据科学讲解

你看。如果你对业务领域、技术能力(编码、数学、统计等)有很好的理解,解决数据问题是很容易的。)以及与同事的协作。

任何人都可以解决问题,只要他们有知道做什么和如何做的技能。

然而,我相信有两个重要的因素需要认真地成为一个伟大的数据科学家来实现你想要的。

在这篇文章结束时,我希望你能理解拥有“为什么”的重要性,以及如何利用“为什么”的力量成为一名伟大的数据科学家,实现你想要的东西,无论是工作还是生活。

我们开始吧!

1.有激情,相信你所做的事情

数据科学之路并不容易。

如果你是一名数据科学家,正在阅读这篇文章。你会明白我的意思。

很艰难。这是一个不断变化的领域。它是动态的。它移动得很快。

换句话说,你需要快速学*和适应,以跟上行业的最新趋势和技术。

你现在使用的工具或语言可能会在几周或几个月后过时。

如果你对自己的工作没有热情,作为一名数据科学家,你如何确保自己能够坚持不懈地学*和提高?

更糟糕的是,如果你甚至不相信你正在做的事情,你很可能不会在这个领域呆很久。

这听起来可能有点刺耳,但却是千真万确的。

换句话说,这一切都归结为一个问题,“你为什么做你所做的事情?”

句号。

如果你一开始就不知道为什么要做你要做的事情,你就不会有动力每天早上醒来去做你喜欢的事情。

作为一名数据科学家,当你在整个旅程中遇到困难时,你不会有动力继续努力。

对我来说,我的“为什么”很简单。

我想让每个人都能接触到数据科学。

这才是我热爱的。

这是我所信仰的。

作为一名数据科学家,这就是我的工作。

现在你的问题是,“你的原因是什么?”

请在下面的评论中告诉我。😊

2.用你的“为什么”推动行动

Simon Sinek —从为什么开始

人们不买你做什么,他们买你为什么做。

—西蒙·西内克

如果你没有看过西蒙·西内克的 TED 演讲,那就看看吧。

几秒后你就知道为什么重要了。

那么,作为一名数据科学家,为什么推动行动对我们如此重要呢?

你看。

想象一下,你非常擅长建立预测准确度很高的机器学*模型。

酷毙了。你做得很好。

这一天到来了,你需要向你的老板和其他利益相关者展示你的预测结果。

你展示了该模型高达 95%的惊人预测准确率,这太棒了。

现在坐在桌子对面的老板问了这个问题,“结果很好。那么我们下一步能对结果做什么呢?”

你惊呆了。

你以为你刚刚解决了一个问题,但是你忘了回答问题的核心问题。

作为一名数据科学家,我认为我们总是需要提供可操作的见解,而不仅仅是展示结果。

通过可操作的见解,我的意思是用结果说服人们,并根据结果推荐接下来的步骤。最重要的是,我们需要告诉人们“为什么”结果和推荐的步骤是至关重要的

因为当你告诉他们原因时,人们很可能会跟随你的做法。

这就是你如何通过说出“为什么”来说服你的利益相关者,从而推动行动。

最后的想法

(来源)

感谢您的阅读。

这个话题是我一直想分享的。

我希望现在你已经更好地理解了“为什么”的重要性,以及如何利用它成为一名伟大的数据科学家,以实现你想要的东西,无论是工作还是生活。

在一天结束的时候,知道“为什么”会让人们(包括你自己)在更深的层次上参与进来,从而激励人们去做。

一如既往,如果您有任何问题或意见,请随时在下面留下您的反馈,或者您可以随时通过我的网站LinkedIn 联系我。在那之前,下一篇文章再见!😄

关于作者

Admond Lee 目前是Staq的联合创始人/首席技术官,该平台是东南亚首屈一指的商业银行应用编程接口平台。

想要获得免费的每周数据科学和创业见解吗?

加入 Admond 的电子邮件简讯——Hustle Hub,每周他都会在那里分享可行的数据科学职业技巧、错误&以及从创建他的初创公司 Staq 中学到的东西。

你可以在 LinkedInMediumTwitter脸书上和他联系。

[## 阿德蒙德·李

让每个人都能接触到数据科学。Admond 正在通过先进的社交分析和机器学*,利用可操作的见解帮助公司和数字营销机构实现营销投资回报。

www.admondlee.com](https://www.admondlee.com/)

如何用 Python 在机器学*中使用 SimpleImputer 类

原文:https://towardsdatascience.com/how-to-use-the-simpleimputer-class-in-machine-learning-with-python-10b321c94861?source=collection_archive---------30-----------------------

简单地使用简单估算器

图片由罗斯·斯奈登 Unsplash 提供

缺失值插补

数据集经常有缺失值,这可能会给机器学*算法带来问题。在执行预测建模之前,识别并替换数据集每一列中缺失的值被认为是一种良好的做法。这种缺失数据替换的方法被称为数据插补。

数据集中的缺失值可能是由多种原因造成的。这些通常包括但不限于:测量设备故障、不一致数据集的整理以及实验期间数据收集的变化。

缺失数据插补的一个方便策略是用一列中其他值计算出的统计值替换所有缺失值。这种策略通常可以带来令人印象深刻的结果,并避免在构建机器学*算法时丢弃有意义的数据。常用的统计包括计算列的平均值、中值和众数,并为缺失值输入该值。此外,可以输入一个常数值来补充上述方法。

本教程旨在演示简单估算类在统计估算中的用法。

数据集和缺失数据评估

本教程中使用的数据集是“逻辑回归预测心脏病数据集,可通过这里的 kaggle 或我的 github 页面获得。

该数据集来自一项正在进行的对马萨诸塞州弗雷明汉镇居民的心血管研究。分类目标是预测患者是否有未来冠心病(CHD)的 10 年风险。数据集提供了患者的信息。它包括 4000 多条记录和 15 个属性。这些属性可以通过 kaggle 找到。我在这里的主要目的不是深入研究这个数据集,而是展示一个使用 SimpleImputer 类进行预测建模的用例。

首先导入所需的库,并执行一些探索性数据分析(EDA)。

dataframe 上调用的 dataframe 和 columns 属性的头显示了所有 15 个数据属性。

为了计算缺失值的数量以及它们相对于列的百分比,我首先对列进行迭代。对于每一列,我使用 isna()方法调用来评估 NaN 值的数量,并通过方法链接对这些值求和。

然后,我计算总行数中缺失值的数量,得到每列缺失值的百分比,并打印出这些数据。

虽然这是信息性的,但需要一些阅读来完全解释结果。确定缺失结果的更好方法可能是使用 seaborn 热图制作一个有用的图形。

我们首先传入 dataframe.isna(),如果缺少值,它将返回 True。然后,我们可以将 cbar 和 ytickslabels 都设置为 False,选择一个颜色映射(这里是字符串 viridis),并可视化结果。

现在我们有了一个快速参考图,它可以有效地告诉我们,哪些列缺少数据。在这里,我们可以看到葡萄糖列丢失的数据值最多。

简单估算类的统计估算

sci-kit learn 机器学*库提供了实现统计插补的 SimpleImputer 类。

要使用 SimpleImputer,首先导入该类,然后用传递给策略参数的字符串参数实例化该类。为了清楚起见,我在这里包含了‘mean ’,这是默认的,因此没有必要显式包含。

我通过调用 dataframe 上的值将 dataframe 转换成一个 numpy 数组(不必要),但这是我喜欢的*惯。然后我选择我的特征并把它们赋给变量 X,选择我的目标变量并把它赋给变量 y。

估算值适合数据集,用于计算每列的统计数据。然后将拟合估算值应用于数据集,以创建数据集的副本,其中每列的所有缺失值都用计算出的均值统计数据替换。

为了确认数据插补有效,我们可以评估应用和不应用数据转换的数据集上缺失值的数量。当应用数据转换时,已经估算了 645 个列值。

模型评估

模型评估最好使用重复的 k- 折叠交叉验证。要求首先在训练数据集上计算每列的计算统计量,然后应用于数据集中每个折叠的训练集和测试集。

为了实现这一点,我们可以创建一个建模管道,其中第一步是统计插补,第二步是模型本身。

以下管道使用均值策略进行统计插补,并使用 RandomForestClassifier 进行模型预测。

我们达到了 84.7%的准确率,标准偏差为 0.007。这是一个合理的结果,但了解哪种插补策略最适合预测建模性能会很有用。

测试插补策略

为了测试不同的插补策略,我们可以遍历这些策略。对于每个管道,我们可以构建一个新的策略,计算交叉值分数,并将它们添加到结果列表中。

我们可以使用结果列表中的数组和策略类型来生成一个盒须图,以解读哪种数据插补策略是最佳的。我已经决定检查每种策略类型的平均分数和最高分数。

盒状图和须状图表明使用常数(0)插补策略获得了最佳准确度分数。

对样品进行测试

现在可以使用最佳插补策略进行预测。根据所有可用数据定义和拟合管道。

我们可以获取数组中的第一行,对其进行整形,将其赋给变量名 sample,并将其作为参数传递给管道上调用的 predict 方法调用。

为了确认这是正确的结果,我们可以检查第一个 y 目标变量标签。我们的模型预测了一个 0 类,而这个类实际上也是一个 0 类。

摘要

简单估算类是使用计算统计数据估算缺失值的有效方法。通过使用 k -fold 交叉验证,我们可以快速确定传递给 SimpleImputer 类的哪个策略给出了最佳的预测建模性能。

链接到完整的 Jupyter 笔记本

这个教程的完整 Jupyter 笔记本的链接可以在这里找到。

如何使用时间旅行来调试你的 ML 管道

原文:https://towardsdatascience.com/how-to-use-time-travel-to-debug-your-ml-pipelines-efb5263372c0?source=collection_archive---------39-----------------------

让你的管道步骤透明化,探索它们的状态,住在 Jupyter。

丹尼尔·利维斯·佩鲁西在 Unsplash 上的照片

机器学*项目由几个不同的步骤组成:数据获取、数据验证、数据处理、模型训练、模型评估等。每一步都接受定义明确的输入,并产生特定的输出。

如果我们能回到过去,在熟悉的 Jupyter 环境中探索跑步的状态,那就太好了

如果传入的数据有问题,该步骤可能会失败,甚至会破坏下游的分析任务。后者可能会引入不太容易调试的重影问题:例如,数据泄漏(即,当训练数据集之外的信息用于创建模型时)可能会影响模型的泛化能力,但它不会在训练期间引发异常。

为了避免这种错误,我们应该能够窥视管道并尽早发现它们。因此,数据科学家最终会检查日志,打印原始指标并创建可视化,如学*曲线和混淆矩阵。

虽然这些工具为构建更健壮的模型提供了有价值的见解,但是如果我们能够回到过去并探索正在运行的步骤的状态,那就太好了。在这个故事中,我们探索如何在 Kubeflow 管道中做到这一点。

学*率是为那些对 AI 和 MLOps 的世界感到好奇的人准备的时事通讯。你会在每周五收到我关于最新人工智能新闻和文章的更新和想法。在这里订阅!

安装 Kubeflow

首先,我们需要一个工作站。设置 Kubeflow 不是一件容易的事情,尤其是如果你没有使用 Kubernetes 的经验。但这不应该阻止你;我们可以在谷歌云平台(GCP)上使用 MiniKF 在 10 分钟内构建一个单节点集群。

  1. 访问 GCP 页面上的 MiniKF
  2. 选择启动,设置虚拟机配置并点击部署

为了获得最佳性能,建议保留默认的虚拟机配置

MiniKF 部署—作者图片

就是这样!部署最多需要十分钟,您可以按照屏幕上的说明观看进度;ssh 进入机器,在终端上运行minikf,等待直到您的端点和凭证准备好。

MiniKF 的提供已完成—图片由作者提供

现在,我们准备访问 Kubeflow 仪表板。点击网址,输入你的凭证,你就可以开始了!

Kubeflow 仪表板—按作者分类的图像

有关部署过程以及如何启动 Jupyter 服务器的更多详细信息,请阅读下面的故事:

[## 有了 MiniKF,Kubeflow 比以往任何时候都更容易访问

10 分钟入门 Kubernetes 最好的机器学*平台。

towardsdatascience.com](/kubeflow-is-more-accessible-than-ever-with-minikf-33484d9cb26b)

调试 Kubeflow 管道

为了演示如何在某个时间点返回并探索管道步骤的状态,我们需要管道本身。无需编写一行代码,就可以轻松地从 Jupyter 笔记本上创建 Kubeflow 管道。你可以在下面的故事中看到。

[## Jupyter 准备生产;原样

无需编写一行代码,即可将您的笔记本草稿转化为生产就绪的 Kubeflow 管道。

towardsdatascience.com](/jupyter-is-ready-for-production-as-is-b36f1d1ca8f8)

对于这个例子,我们假设您已经成功地运行了一个管道。如果你想了解前面提到的故事,我们使用众所周知的泰坦尼克号数据集来训练五个不同的分类器。最后,您的管道应该类似于下面这样:

泰坦尼克号管道——作者图片

所以,假设我们对 SVM 算法的结果不满意。我们想回到这一步,在训练算法和探索我们生活在笔记本中的世界的状态之前。为此,我们求助于韩国

韩国快照

Rok 是一个数据管理产品,允许您对您的完整环境及其数据进行快照、版本化、打包、分发和克隆。它作为其支持的平台之一与 Kubernetes 进行了本机集成,并在几分钟内部署到现有的集群、本地或云上。

它预装在 MiniKF 中,所以让我们使用它:

  1. 点击smv步骤并选择Visualizations选项卡
  2. 跟随Rok autosnapshot卡内的链接
  3. 复制页面顶部的韩国网址
  4. 创建一个新的笔记本服务器,并在顶部粘贴复制的网址
  5. 配置虚拟机资源,并为工作区指定一个有效的名称
  6. 点击LAUNCH按钮

与韩国同行——作者图片

当笔记本电脑服务器准备就绪后,连接到它,一个新的 JupyterLab 环境将在您请求的位置准确地打开。到目前为止的所有单元格都已为您执行。您可以从该单元格继续工作;探索变量状态、数据集和您的模型。

继续你的 JupyterLab 状态——作者图片

现在,您有了一种调试错误的方法,即探索在特定时间点管道中发生了什么。这当然比原始日志更有价值,也比静态可视化更强大。

结论

在这个故事中,我们看到了如何使用 Rok,一种数据管理服务,在 Jupyter 笔记本中进行时间旅行,并实时探索管道步骤的状态。这给了我们调试 ML 管道的能力,也给了他们版本。如果您关心版本控制,可以看看下面的文章。

[## 你控制 ML 项目版本的方式是错误的

当您可以拥有更多时,是否在寻找一种类似 git 的数据版本控制方法?是时候跳出框框思考了

towardsdatascience.com](/the-way-you-version-control-your-ml-projects-is-wrong-42910cba9bd9)

关于作者

我叫迪米特里斯·波罗普洛斯,我是一名为阿里克托工作的机器学*工程师。我曾为欧洲委员会、欧盟统计局、国际货币基金组织、欧洲中央银行、经合组织和宜家等主要客户设计和实施人工智能和软件解决方案。

如果你有兴趣阅读更多关于机器学*、深度学*、数据科学和数据操作的帖子,请在 twitter 上关注我的 MediumLinkedIn@james2pl

所表达的观点仅代表我个人,并不代表我的雇主的观点或意见。

如何利用 Spotify 的 API 并在 Streamlit 中创建用户界面

原文:https://towardsdatascience.com/how-to-utilize-spotifys-api-and-create-a-user-interface-in-streamlit-5d8820db95d5?source=collection_archive---------18-----------------------

实践教程

关于如何从 API 提取数据并在交互式图表中显示用户确定的结果的演练

首先,我们必须进入下面的 Spotify 开发者页面。

[## 我的仪表板|面向开发者的 Spotify

我们和我们的合作伙伴使用 cookies 来提供我们的服务,并根据您的兴趣向您显示广告。通过使用我们的…

developer.spotify.com](https://developer.spotify.com/dashboard/)

您将使用您的 Spotify 帐户凭据登录。登录后,您可以选择“创建应用程序”。

作者照片

一旦你创建了一个应用程序,你会看到你的客户 ID 和客户密码。我们将需要这些来生成一个访问令牌,我们将使用它从 API 获取数据。

我们将把代码分成三个独立的脚本。一个将是访问 API 的 API 客户端,一个将调用客户端并在 Streamlit 中生成接口,一个将用于帮助改善 Streamlit 接口的外观。

构建 API 客户端脚本

我们的目标是创建一个允许我们轻松进行 API 调用的类。

为了帮助指导我们构建类,我们将遵循 Spotify 开发者页面上的授权指南。

https://developer . Spotify . com/documentation/general/guides/authorization-guide/

首先,我们将导入所有必需的库。

然后,我们可以开始在类中声明一些我们需要的变量以及一个初始化函数。

应该注意,访问令牌在 3600 秒后过期,因此我们将实现一些代码来检查令牌的过期时间。令牌 URL 可以在 Spotipy 文档的授权指南中找到。

https://developer . Spotify . com/documentation/general/guides/authorization-guide/

作者照片

然后,我们需要使用我们的客户端 ID 和客户端密码为我们的客户端凭证创建一个 base64 编码的字符串。将我们的凭证编码成 base64 字符串使它更加安全。

我们现在可以使用 get_client_credentials 函数,并在另一个函数中调用它来生成一个令牌头,我们将需要它来进行授权。

作者照片

我们还将构建一个 get_token_data 函数。

有了函数和变量之后,我们现在将编写一个函数来执行身份验证,给出函数的输出和变量的值。

有了验证我们凭证的代码,我们现在可以创建一个函数来生成令牌。下面的代码确保凭据验证正确,并将生成一个令牌。

接下来,我们将生成一个请求所需的头。您将会看到,在这个函数中,我们需要使用一个“承载”认证器,而不是我们之前使用的“基本”认证器。“载体”认证器用于令牌,而“基本”认证器与 ID 和秘密一起使用。

作者照片

一切就绪后,我们现在可以编写一些函数来获取数据。我们将使用对应于 Web API 文档中“搜索”引用的端点。

https://developer . Spotify . com/documentation/we b-API/reference/search/search/

作者照片

下面的代码将允许我们进行查询搜索,而不必在每次我们想要进行不同的搜索时复制和粘贴函数。它允许我们搜索的方式是传入一个字典,然后用冒号{k}:{v}将字典分成一个键值对。最终,这允许我们将字典转换成字符串,这是我们需要搜索的格式。

现在,我们可以将所有内容放在一起,并将其保存为 python 文件。我将该文件命名为 spotipy_client.py,您可以随意命名,但是请记住这个名称,因为我们需要将它导入到另一个脚本中。

Streamlit 界面 CSS 文件

接下来,我们将创建一个 CSS 文件,用于定制我们的 Streamlit 界面。

下面的代码将允许自定义背景颜色以及自定义搜索按钮。

我们可以将这个脚本保存为 CSS 文件。与客户端脚本类似,记住名称,因为我们也需要导入这个文件。

构建界面的脚本

在构建界面脚本之前,我们需要做的最后一件事是创建一个虚拟环境来下载成功运行最终脚本所需的包。我用 conda 为这个项目创建了我的虚拟环境。您可以通过打开 Anaconda 提示符并运行以下代码来完成同样的工作。

创建虚拟环境的原因是我们可以为特定的项目下载特定的包。这也比将包直接下载到机器的基本实例更安全。

一旦我们有了我们的环境,我们将需要激活它来下载包,然后最终运行我们的脚本。

您可以使用以下命令激活环境。

我们需要在虚拟环境中安装 Streamlit。你可以和皮普一起做这个。

最后,我们可以开始构建允许我们创建 streamlit 接口的脚本。

首先,我们将利用我们的 CSS 代码来定制我们将要生成的页面的外观。

接下来,我们将创建 streamlit 变量,该变量将允许用户向我们的 python 代码传递数据,这些代码将利用我们的 spotipy_client.py 脚本。

上面的代码创建了一个搜索栏,供用户搜索艺术家,一个下拉菜单,提供不同的功能供用户选择,还有一个按钮,供用户选择后运行代码。我们将使用所做的选择在脚本中进一步传递相应的变量。

接下来,我们将把所需的参数传递给 SpotifyAPI 类。您需要确保您的 spotipy_client.py 文件位于您当前工作的目录中,否则,它将不会加载到我们当前的脚本中。

将 client_id 和 client_secret 传递给我们的类后,我们现在就可以查询我们想要的数据了。

我们的目标是使用通过 Streamlit 接口生成的变量 Name_of_Artist 来搜索特定艺术家的曲目。您会注意到,这会以 JSON 格式返回数据。为了在我们的脚本中使用它,我们需要解析 JSON 数据并提取我们想要传递到 dataframe 中的值。在下面的代码中,“artist”是键,“Name_of_Artist”是值。

我们现在有一个数据帧,它包括一些与艺术家的音轨相关的字段。

对于我们的项目,我们还需要引入音轨的特定音频特征。我们可以通过文档了解我们具体需要将什么传递到查找 URL 中。

https://developer . Spotify . com/documentation/we b-API/reference/tracks/

作者照片

正如我们所看到的,我们需要传入一个音轨 id 来获取我们正在寻找的音频特征数据。在我们现有的数据框架中,我们在列名“Id”下有该信息。我们一次只能查找一个“Id ”,因此我们将创建一个循环,进入我们的数据帧并将每个“Id”值传递给它。每个输出都是一行,我们可以将它附加到数据帧中,将数据转换成表格格式。

有了音轨信息的数据帧和音频特征的数据帧,我们可以将两者合并成一个组合表,并提取我们希望在界面中显示的字段。Name_of_Feat 将根据用户的选择传入。

最后,有了数据框架,我们可以构建图表和表格来显示。

我们将使用 Altair 图表,允许用户将鼠标悬停在不同的数据点上,以查看歌曲的不同方面,如流行度、音频功能、歌曲名称和专辑名称。

最后要补充的是如何测量不同音频特性的描述。我在屏幕底部添加了这个,以便我们的潜在用户在查看数据时查看。这些描述来自 Spotify 开发者网站上的音频功能文档。

[## 获取音轨的音频功能|面向开发者的 Spotify

需要路径参数授权。来自 Spotify 帐户服务的有效访问令牌:参见 Web API…

developer.spotify.com](https://developer.spotify.com/documentation/web-api/reference/tracks/get-audio-features/)

在测试我们的脚本之前,我们将把上面所有的代码放在一起,保存为一个 python 文件。

一切就绪后,我们可以测试我们的最终产品了。在您的终端中,您将运行以下命令。我将最终的 python 文件命名为 streamlit_audio_features.py,但是您可以随意命名。记得在终端中激活你的虚拟环境。此命令将在您的浏览器中打开一个新标签,并显示我们的界面。

下面展示了我们界面的一些快照。要查看界面的运行情况,您可以点击下面的 youtube 视频链接,或者自己运行代码。

作者照片

作者照片

https://www.youtube.com/watch?v=BuVZ07DNWj0

这些代码文件的完整脚本也可以在 Github 上找到。

[## jjevans25/Spotipy 图表

使用 Spotipy API 在 Streamlit 中创建交互式散点图。为了成功运行,您将…

github.com](https://github.com/jjevans25/Spotipy-Chart)

我希望这给了你一些关于如何使用 Python、API 和 Streamlit 的见解,以及你对项目的任何潜在想法。

spotipy_client.py 脚本修改自

麻省理工学院许可证(MIT)

面向企业家的版权 2020 编码

如何利用迁移学*和最新的深度学*模型对图像进行分类

原文:https://towardsdatascience.com/how-to-utilize-transfer-learning-to-classify-images-with-state-of-the-art-deep-learning-models-d8e5d5bb35d4?source=collection_archive---------59-----------------------

在这篇文章中,我将展示如何使用一个预先训练好的最先进的图像分类模型来对自定义数据进行分类。我展示了如何在 Keras 中使用谷歌的 efficientnet 模型来应用迁移学*,对来自斯坦福汽车数据集的汽车图像进行分类。完整的 jupyter 笔记本可以在我的 github 库中找到。

效率网

从最初简单的卷积神经网络(CNN)开始,通常可以通过任意缩放网络维度(如宽度、深度和分辨率)来逐步进一步提高模型的精度和效率。增加使用的层数或使用更高分辨率的图像来训练模型通常需要大量的人工工作。来自谷歌人工智能的研究人员发布了 EfficientNet,这是一种基于一组固定缩放系数和 AutoML 及其他技术进展的缩放方法(例如深度可分离卷积swish 激活drop-connect )。EfficientNet 不再像以前那样独立优化单个网络维度,而是寻求一种跨所有网络维度的平衡扩展流程。

借助 EfficientNet,参数数量大幅减少,同时在 ImageNet(此类应用的基准)上实现了最先进的结果。

迁移学*

虽然 EfficientNet 减少了参数的数量,但卷积网络的训练仍然是一项耗时的任务。为了进一步减少培训时间,我们可以利用迁移学*技术。

迁移学*意味着我们使用预先训练的模型,并根据新数据对模型进行微调。在图像分类中,我们可以考虑将模型分为两部分。模型的一部分负责从图像中提取关键特征,如边缘、常见模式等。一部分是使用这些特征进行实际分类。

通常,CNN 由堆叠的卷积块组成,减少了图像大小,同时增加了可学*特征(滤波器)的数量,最终所有内容都被放入一个完全连接的层中,该层进行分类。迁移学*的思想是使第一部分可以转移,这样通过只替换完全连接的层(通常只是称为“顶层”)就可以用于不同的任务。

履行

这款 keras Efficientnet 实施(pip install efficientnet)带有适用于所有尺寸(B0-B7)的预训练模型,我们只需添加自定义分类层“top”即可。用weights='imagenet'我们得到一个预训练的模型。这个片段大致展示了它是如何工作的(完整的例子见 jupyter 笔记本):

base_model = EfficientNetB5(include_top=False, weights='imagenet')
x = base_model.output
x = GlobalAveragePooling2D()(x)
predictions = Dense(num_classes, activation='softmax')(x)
model = Model(inputs=base_model.input, outputs=predictions)# fix the feature extraction part of the model
for layer in base_model.layers:
    layer.trainable = Falsemodel.summary()
--------Total params: 28,615,970
Trainable params: 102,450
Non-trainable params: 28,513,520

我们只有 10 万个可训练参数,而整个网络有 2800 万个。有了这组减少的自由参数,我们可以在自定义数据上训练最后一层,而特征提取层使用来自 imageNet 的权重。

训练模型后,我们可能会看到以下结果:

训练数据集的损失(蓝色)看起来不错,但是测试数据的损失(橙色)看起来很奇怪。通常,这种损耗曲线是过度拟合的指标。

模型精度也是如此。虽然训练数据的准确性看起来还可以,但是测试的准确性却完全不行。

批量标准化的怪异之处

这种怪异的行为来自 BatchNormalization 层。好像有个 bug ,在使用 keras (2.2.4)和 tensorflow 1.x 的时候,问题好像是冻结的批量归一化层确实也冻结了归一化参数。(点击阅读更多关于不同标准化层的信息)。要解决这个问题,我们可以使 BatchNormalization 层可训练:

for layer in base_model.layers:
    if isinstance(layer, BatchNormalization):
        layer.trainable = True
    else:
        layer.trainable = False

不幸的是,我们失去了使用更大 batch_size 的能力,当我们使 BatchNormaliation 可训练时,keras 似乎需要更多的内存来存储模型。

或者,我们可以忽略上面的奇怪分数,因为我们的层仍在学*,正如我们在训练损失/准确性中看到的,随后我们以 BatchNormalization 可训练的方式训练整个网络。然而,以下是 BN 可训练时模型的得分:

训练数据集(蓝色)和测试数据(橙色)的损失现在看起来很完美。

还有准确性

当只训练最后一层时,我们仍然有好处。例如,我们有较少的可训练参数,这意味着更快的计算时间。在大型数据集上,我宁愿忽略验证分数,并通过完全冻结基本模型(包括 BN)来利用较大的 batch_size。

释放网络的全部能量

在训练过程中的某个点,模型没有进一步改进,是时候打开网络的其余部分来微调特征提取部分了。因此,我们使所有的层可训练,并再次适应模型。现在,我们有超过 2800 万个参数,训练需要更长的时间,但由于我们已经训练了最后一层,我们有一个更好的起点。

for layer in model.layers:
    layer.trainable = True
model.summary()
--------Total params: 28,615,970
Trainable params: 28,443,234
Non-trainable params: 172,736

注意:避免模型的早期过度拟合是很重要的,因为模型可能很难逃脱局部最小值,因此我们确保在全面训练之前和之后更好地打开网络。另外,不要忘记调整 batch_size,否则我们会运行 OOM。要估计模型所需的内存,请看这里( stackoverflow )。我也建议利用早停

第二次调用 fit()后,我们得到了一个更好的模型:

第二训练阶段的损失仍然减少,因此模型得到改进

对于训练和测试数据,模型的准确性也提高了

最后,我们在自定义数据上训练了一个最先进的 efficientnet 模型。为了使这个模型生产就绪,还有一些工作要做。如果你对如何部署这样一个模型感兴趣,你可以查看这篇文章。

这篇文章最初发表在我的个人博客这里

如何验证进化优化算法的正确性

原文:https://towardsdatascience.com/how-to-validate-the-correctness-of-an-evolutionary-optimization-algorithm-570c8b71b6d7?source=collection_archive---------36-----------------------

检查已实现的元启发式多目标优化算法的正确性和准确性的可能方法。

f = Y . * sin(X)-X . * cos(Y)的 3D 空间

目录

  1. 简介
  2. 正确性验证
  3. 浅谈绩效考核
  4. 结论
  5. 参考文献
  6. 一些相关的中帖

1.介绍

进化和元启发式优化算法被认为是人工智能(AI)的子集。这些算法试图模仿自然机制并解决优化问题。例如,遗传算法(GA)使用受启发的生物机制,如繁殖、交叉、选择、突变和重组,来寻找优化问题的最佳解决方案。另一个例子是帝国主义竞争算法(ICA ),在这种算法中,统治、革命和殖民化等社会机制被用来寻找解决方案[1]。进化算法通常在复杂的优化问题中表现良好,而使用经典方法在数学上是困难的。他们可以轻松处理非线性问题,而不会陷入局部极小值。

为了用进化优化算法优化一个问题,可以使用认证的工具箱。然而,对于某些算法,要么没有可用的认证工具箱,要么可能更喜欢用任何编程语言来实现他/她自己的代码。在这种情况下,最重要的问题是——我们如何信任编写的代码?我们如何验证我们实现的进化或元启发式代码的正确性?

在这篇文章中,一些现有的检查和验证已实现的进化优化算法的正确性的方法已经得到了简要的阐述。此外,使用 Ackley 函数的例子,讨论优化算法的性能评估。

2。正确性验证

有不同的方法来检查所实现的元启发式多目标优化算法(例如,遗传算法(GA)或差分进化(DE))的正确性和准确性。下面的方法可以简单地用来检查所实现的优化算法的正确性:

A) 与经典方法的比较:在一些问题中,可以同时运行经典方法和多变量遗传算法,以确保结果正确和准确。然而,在大多数情况下,由于数学的复杂性,使用经典方法进行比较是不可能的。

B) 使用众所周知的基准:代码的正确性也可以通过现有的基准来证明。所使用的算法可以通过众所周知的基准进行验证[2–6]。

C) 使用专家思想:系统的专家可以检查结果及其合理性。他们应该都同意最后的结果是合乎逻辑的。如果一个问题需要精确的最小成本值,那么使用专家的想法是没有说服力的。

D) 收敛性:通过成本与迭代的关系图,可以容易地观察到所实现的多目标遗传算法的收敛性。还有其他因素,如舍入误差和局部极值,也有相同的观点。

[7]中的收敛图示例(适应度与迭代次数)

E) 支配因子:NSGA-II、NSGA-III、MOPSO 等新一代优化算法通常具有将支配结果与非支配结果分离的功能。因此,所有的最终结果都应该是占优势的,并且有了适当的初始种群,很少会陷入局部极小值。然而,不能保证他们找到系统的全局最小值。有关支配的更多信息,请查看[8]。

3。浅谈绩效评估

下图显示了 Ackley 函数,其中 a 等于 20, b 等于 0.2, c 等于 2【9】。这个函数是用于进化或元启发式优化的众所周知的基准之一。它有一个唯一的全局最小值和几个局部最小值。

a = 20,b = 0.2,c = 2 的阿克利函数。

使用下面的 MATLAB 代码可以很容易地生成上图:

通过将 b 的值增加到 1000,可以得到下图。正如在这个函数中可以看到的,有许多局部最小值和一个狭窄的唯一全局最小值。

a = 20,b = 1000,c = 2 的阿克利函数。

也可以使 c 等于零,并移除所有局部最小值。然后可以得到下图。作为全局最小值的具有窄而深的孔的平面。在这种情况下,适应度与迭代次数的关系图是没有用的。

a = 20,b = 1000,c = 0 的阿克利函数。

为了了解优化算法的性能,让我们简化这个问题。首先,我们可以离散化区域。假设 X 和 Y 的范围为-5 到 5,步长为 1,点 x = 0,y = 0 是全局最小值。所以,X 和 y 会有 121 种可能的组合,随机找到最优值的概率应该是 1/121。在最坏的情况下,找到最优值的概率是多少?

答案应该是新生成值的总数(考虑所有算法部分,如初始种群、变异、交叉、重组等)。)除以输入(基因)的总可能组合。在这种情况下,只有新生成值的数量和离散化的精度才能提高性能。下面的表达式可以用作这个例子的误差概率。

上述表达式不仅可用作最坏情况下的误差概率上限,还可用于任何其他情况。该表达式还可以证明,当离散化中的步长足够小时(N → ∞),并且迭代次数是无限的(需要巨大的计算能力),那么误差概率应该为零。

应该注意的是,给出最坏的情况是因为问题的本质很容易被绕过或减少进化算法中策略的影响。换句话说,在这个例子中,进化优化算法的策略对性能和准确性的影响很小。

寻找进化优化的性能和准确性仍然是一个没有答案的研究问题。在许多情况下,算法的策略会影响性能。例如,Arnold,D. V .等人[10]提出了一种方法来测量步长对进化优化算法输出性能的影响。但这项研究不能被视为进化优化算法的准确性和性能评估的一般解决方案。

4。结论

与迭代次数、初始群体和内部函数评估相关的计算工作,这些可能与元启发式算法的性能或准确性相关。因此,计算优化算法的大 O 是有用的。

问题维度包括目标的数量、约束、输入基因的范围和数量以及优化算法的结构可以与性能相关[11]。

进化优化算法的正确性可以通过不同的方法来验证,概括如下:

检查进化或元启发式算法正确性的可能方法

5.参考

[1]阿塔什帕斯-加尔加里等人和卢卡斯等人(2007 年)。帝国主义竞争算法:一种受帝国主义竞争启发的优化算法。在 IEEE 进化计算大会(第 4661-4667 页)。

[2]姚,谢,刘,杨,林等(1999).进化编程变得更快。进化计算汇刊,3(2),82–102。

[3]迪加拉基斯和玛格丽特(2001 年)。关于遗传算法的基准函数。国际计算机数学杂志,77(4),481–506。

[4]m .莫尔加和 c .斯穆特尼基(2005 年)。优化需求的测试函数。优化需求的测试函数,101。

[5]杨晓生(2010)。最优化中的测试问题。arXiv 预印本 arXiv:1008.0549。

[6]s .米尔贾利利和 a .刘易斯(2013 年)。二进制粒子群优化的 s 形和 V 形传递函数。群体和进化计算,9,1–14。

[7]陈,陈,杨,江,魏(2016)。基于遗传粒子群优化的甚高分辨率遥感影像目标变化检测特征选择。传感器16 (8)、1204。

[8] Elarbi,m .,Bechikh,s .,Gupta,a .,Said,L. B .,和 Ong,Y. S. (2017 年)。一种新的基于分解的多目标优化 NSGAⅱ。IEEE 系统、人和控制论汇刊:系统,48(7),1191–1210。

[9]埃克利博士(2012 年)。基因爬山的联结主义机器(第 28 卷)。斯普林格科学&商业媒体。

[10]d . v . Arnold 和 h . g . Beyer(2004 年)。累积步长自适应进化优化的性能分析。 IEEE 自动控制汇刊49 (4),617–622。

[11]网址:https://www . research gate . net/post/How _ to _ assesse _ the _ performance _ of _ an _ optimization _ algorithm

6.一些相关的中等职位

[## 揭开机器学*优化的神秘面纱

优化是机器学*算法配方中最重要的成分。它从定义开始…

towardsdatascience.com](/demystifying-optimizations-for-machine-learning-c6c6405d3eea) [## 了解 RMSprop —更快的神经网络学*

免责声明:我假定关于神经网络优化算法的基本知识。特别是关于 SGD 的知识…

towardsdatascience.com](/understanding-rmsprop-faster-neural-network-learning-62e116fcf29a) [## 自适应元启发式智能粒子(AMI-P)

AMI 粒子

towardsdatascience.com](/adaptive-meta-heuristically-intelligent-particle-ami-p-4badd123b3a2) [## 进化策略简介

在这篇文章中,我们将学*使用 Python 中的进化策略(es)来训练一个没有反向传播的神经网络…

towardsdatascience.com](/introduction-to-evolution-strategy-1b78b9d48385)

注: 写这篇文章的想法是在我们得到下面这篇文章的评论时开始的:

阿赫拉吉,杨,巴迭埃,a,赵,x,阿斯兰塞法特,k,肖,x,什图,s .,&马,X. (2020)。使用数字双胞胎对最新露点冷却器进行约束多目标进化优化。能量转换与管理211 、112772。https://doi.org/10.1016/j.enconman.2020.112772

如何对自然语言处理任务的数据帧中的文本进行矢量化——3 种简单的技术

原文:https://towardsdatascience.com/how-to-vectorize-text-in-dataframes-for-nlp-tasks-3-simple-techniques-82925a5600db?source=collection_archive---------6-----------------------

使用 Texthero、Gensim 和 Tensorflow 的简单代码示例

Justin Luebke 在 Unsplash 上的照片

今天就开始学* NLP 吧!

你可能听说过自然语言处理(NLP)是十年来最具 T4 变革性的技术之一。现在是进入 NLP 的绝佳时机,因为新的库已经抽象掉了许多复杂性,允许用户通过很少的模型训练和很少的代码获得最先进的结果。

虽然计算机实际上很擅长寻找模式和总结文档,但它必须先将单词转换成数字,然后才能理解它们。不同于像我过去所做的那样在单词级别对文本进行矢量化,我将探索以下技术在句子、段落或文档级别对数据帧中的文本进行矢量化:

text hero:TF-IDF
Gensim:doc 2 vec
tensor flow 2:通用语句编码器 4

作为奖励,我也将使用 t-SNE 可视化矢量!完整代码朝向底部!

下载数据集

我将不再从我最喜欢的来源中收集数据,而是从游戏《魔法:聚会中寻找卡片。我几乎一生都在玩纸牌游戏,并在 90 年代中期大约在二年级的时候开始玩魔法:聚会(MTG) 。如果你有兴趣尝试一下,你可以在线免费玩

魔法:聚会 法律

我很高兴发现所有卡片的免费数据集。要了解示例,请从MTGJSON.com下载 AllPrintings SQLITE 文件

MTGJSON 是一个开源项目,它将所有魔术编目:以可移植的格式收集卡片。

导入依赖项和数据

很容易将数据连接并加载到 dataframe 中,因为它已经是一个 sqlite 文件。按照三个步骤加载库、数据和数据框架!

1.导入 pandas 和 sqlite3 库
2。连接到 sqlite 文件
3。将数据加载到熊猫数据框架中。

#*Import dependencies*
import pandas as pd
import sqlite3*#Establish connection to sqlite database*
conn = sqlite3.connect("AllPrintings.sqlite")*#load the data into a pandas DataFrame*
df = pd.read_sql("select * from cards", conn)

注意,我使用 pandas read_sql 函数来生成一个使用原始 sql 的数据帧。我可以看到数据集中有 73 列和 54033 行。

我将减少列数和行数,因为我只关心不同的卡片。在游戏魔法:聚会中,有 5 种核心颜色:黑色、蓝色、绿色、红色和白色。

我将探索我最喜欢的颜色,绿色

df = pd.read_sql("select distinct name, text, convertedManaCost, power, toughness, keywords from cards where borderColor ='black' and colorIdentity = 'G'", conn)

注意,我用 SELECT DISTINCT 开始 SQL 查询,以排除重复的卡。这是必要的,因为一些卡片多年来已经被重印了多套。

df.shape 返回数据帧的形状

删除重复项并将数据集限制为绿卡,这样我就有了 3085 行 6 列。

清理数据

为了清理数据并为矢量化做准备,我将使用 Texthero 库 ,因为它简化了数据帧中文本的清理。要应用默认的文本清理脚本,运行 hero.clean(pandas。系列)。

使用 clean() 时,默认运行以下七个功能:

  1. fillna(s)用空格替换未赋值的值。
  2. lowercase(s)小写所有文本。
  3. remove_digits()去掉所有的数字块。
  4. remove_punctuation()删除所有字符串.标点(!" #$% & '()*+,-。/:;< = >?@[]^_`{|}~).
  5. remove_diacritics()去除琴弦上的所有重音。
  6. 删除所有停用词。
  7. remove_whitespace()删除单词之间的所有空格。

定制清洗管道

我将构建自己的管道,而不是使用默认的 clean 函数。使用我自己的管道,我可以保留尽可能多的卡片上下文以实现相似性:

import texthero as hero
from texthero import preprocessingcustom_pipeline = [preprocessing.fillna,
                   #preprocessing.lowercase,
                   preprocessing.remove_whitespace,
                   preprocessing.remove_diacritics
                   #preprocessing.remove_brackets
                  ]df['clean_text'] = hero.clean(df['text'], custom_pipeline)
df['clean_text'] = [n.replace('{','') for n in df['clean_text']]
df['clean_text'] = [n.replace('}','') for n in df['clean_text']]
df['clean_text'] = [n.replace('(','') for n in df['clean_text']]
df['clean_text'] = [n.replace(')','') for n in df['clean_text']]

注意我用了 fillna ,因为有些卡片没有文字。
注意我决定从管道中排除移除括号。这是因为 Texthero 也会删除括号中的数据!

熊猫数据帧的前两行

使用 TF-IDF 生成矢量

TF-IDF 代表词频-逆文档频。是一种经典的对单词值进行加权而不是简单计数的方法。它用于确定一个单词对集合文档中的文本有多重要。

TF-IDF 是文本的一个词包(BoW) 表示,描述文本语料库中的出现。它不能解释单词的顺序。我将在下一节详细讨论这些限制…

TextHero 使得将 TF-IDF 应用到 dataframe 中的文本变得很容易。

df['tfidf'] = (hero.tfidf(df['clean_text'], max_features=3000))

将值添加到 dataframe 实际上只有一行代码!我建议探索不同数量的 max_features ,看看它如何影响向量。

df.head(2)显示 dataframe 中新的 tfidf 列

TF-IDF 生成一个稀疏矩阵,其中包含许多 0,因为卡片上有各种各样的单词。

使用 Doc2Vec 生成矢量

虽然 TF-IDF 是使用经典矢量化技术建立基线的良好起点,但它有很大的局限性。由于它是一个单词包表示法,所以它没有保持单词的顺序,也没有说明太多的语义。作为稀疏矩阵,它也可能是资源密集型的。

Word2Vec 革命

为了解决语义关系和稀疏矩阵的问题,创建了像 Word2Vec 这样的模型。以前我写过关于使用 Gensim 库在文本数据上应用 Word2Vec 模型的文章。

[## 用 Python 实现自然语言处理中单词嵌入的简单方法

使用 Gensim 和 Plotly 探索单词嵌入

towardsdatascience.com](/the-simple-approach-to-word-embedding-for-natural-language-processing-using-python-ae028c8dbfd2)

Word2Vec 模型为每个单词生成向量,但是为了计算整个文档的向量,我可以对文档中每个单词的向量进行平均。相反,我会使用更简单的路线: Doc2Vec

使用 Doc2Vec

2014 年推出的 Doc2Vec 是一款表示 文档 s,段落或句子作为 向量 。Doc2Vec 通常优于 Word2Vec 向量的简单平均,因此值得探索!

在基本层面上,Doc2Vec 算法为文档提供了另一个类似浮动单词的向量,称为 doc-vector。它有助于所有的训练预测,并像其他词向量一样被更新。查看乐和米科洛夫的全文,了解技术方面的内容。

Doc2Vec 需要训练。为了训练模型,标签/编号需要与训练的每个文档相关联。使用 doc2vec 可以轻松完成标记。标签文档()。

from gensim.models.doc2vec import Doc2Vec, TaggedDocument*#tokenize and tag the card text*
card_docs = [TaggedDocument(doc.split(' '), [i]) 
             for i, doc in enumerate(df.clean_text)]#display the tagged docs
card_docs

注意,我使用做了简单的标记化。拆分(' ')在清洗过的卡片文字上。

标记和令牌化的卡文本

接下来,实例化一个 Doc2Vec 模型

设置向量大小以确定将包括多少个维度。设置训练时期以确定它将迭代训练数据的次数。

model = Doc2Vec(vector_size=64, min_count=1, epochs = 20)

当设置纪元时,考虑高的数字倾向于达到递减的回报。试验超参数!查看文档,获取所有模型参数的完整列表

在实例化模型后构建一个词汇表,然后训练模型。

*#instantiate model*
model = Doc2Vec(vector_size=64, window=2, min_count=1, workers=8, epochs = 40)*#build vocab*
model.build_vocab(card_docs)*#train model*
model.train(card_docs, total_examples=model.corpus_count
            , epochs=model.epochs)

构建词汇表创建了一个字典(可通过model.wv.vocab访问),包含从训练中提取的所有独特单词以及计数。

现在模型已经训练好了,使用 model.infer_vector 将标记化的文本传递给模型以生成向量。

*#generate vectors*
card2vec = [model.infer_vector((df['clean_text'][i].split(' '))) 
            for i in range(0,len(df['clean_text']))]card2vec

矢量化卡片文本

注意数据输出为 numpy 数组。要将向量添加到数据帧中,使用 numpy.array()。【tolist().这将把它们保存为列表列表。然后,它们可以作为一列添加到数据帧中。

import numpy as np*#Create a list of lists*
dtv= np.array(card2vec).tolist()*#set list to dataframe column*
df['card2vec'] = dtvdf.head(2)

带有 Doc2Vec 向量的数据帧

注意 card2vec 列包含 Doc2Vec 向量。将向量添加到数据帧是存储它们的一种便捷方式。

虽然 Doc2Vec 方法只用了几行代码就完成了,而不是训练一个 Doc2Vec 模型,但是有一些预训练的选项甚至需要更少的代码!

使用通用语句编码器生成向量

比使用 Doc2Vec 更简单的是,托管在 Tensorflow-hub (tfhub)上的通用句子编码器 (USE)是一个预先训练好的模型,它将文本编码成 512 维向量。它在各种各样的文本资源上被训练。

通用句子编码器将文本编码成高维向量,这些向量可用于文本分类、语义相似性、聚类和其他自然语言任务。— 文档

使用模型的最新迭代使用 TensorFlow2。我过去曾使用 Tensorflow 1 模型来生成葡萄酒推荐,这些新模型使用起来更简单,应用起来也更快。

模型需要从 tfhub 下载。

!pip install --upgrade tensorflow_hubimport tensorflow_hub as hub*#download the model*
embed = hub.load("[https://tfhub.dev/google/universal-sentence-encoder-large/5](https://tfhub.dev/google/universal-sentence-encoder-large/5)")

接下来,通过模型运行 cleaned_text 来生成向量。使用 Doc2Vec 示例中的相同技术,将 numpy 数组中的向量转换为 list 列表。

由此,很容易将向量添加到数据帧中。就是这么简单!

*#generate embeddings*
embeddings = embed(df['clean_text'])*#create list from np arrays*
use= np.array(embeddings).tolist()*#add lists as dataframe column*
df['use'] = use*#check dataframe*
df.head(2)

通用句子编码器向量

恭喜你!您刚刚学*了 3 种快速简单的方法来矢量化数据帧中大于单词长度的文本!

可视化矢量

既然我费了这么大的劲来生成向量,我还不如探索一下!使用 Texthero 库,很容易应用 t-SNE 算法来降低向量的维度,并在 2D 空间中可视化它们。

t-SNE(t-distributed random neighbor embedding)是一种用于可视化高维数据的机器学*算法。t-SNE 技术应用了非线性维度缩减。

df['tsnetfidf'] = hero.tsne(df['tfidf'])
df['tsnec2v'] = hero.tsne(df['card2vec'])
df['tsneuse'] = hero.tsne(df['use'])

算法很复杂,可能需要一点时间才能完成!

显示 t-SNE 结果的数据框

接下来,使用 Texthero 构建 t-sne 列的散点图。Texthero 在引擎盖下使用 Plotly,因此图形是交互式的。

*#create scatter plot of tfidf*
hero.scatterplot(df, col='tsnetfidf', color='convertedManaCost'
                 , title="TF-IDF", hover_data = ['name','text'])*#create scatter plot of doc2vec*
hero.scatterplot(df, col='tsnec2v', color='convertedManaCost'
                 , title="Doc2Vec", hover_data = ['name','text'])*#create scatter plot of uni. sent. enc.*
hero.scatterplot(df, col='tsneuse', color='convertedManaCost'
                 , title="U.S.E", hover_data = 'name','text'])

注意我将 hover_data 设置为 nametext 。将鼠标悬停在某个点上将显示卡片名称和卡片文本。这样就很容易比较各种技术如何将相似的卡片聚集在一起。

文本向量散点图

每种技术产生不同的情节,但是把相似的卡片聚集在一起。举例来说,我发现有践踏,或加+1/+1,或横置以加魔法力的牌丛。

最后的想法和完整的代码

自然语言处理可能是一个复杂的话题,但是这些技术应该给你一个跳板,让你可以更深入地研究这个领域。我介绍了三种在段落、句子或文档级别对文本进行矢量化的简单方法:

text hero:TF-IDF
Gensim:doc 2 vec
tensor flow 2:通用语句编码器 4

从文本创建向量为机器学*任务做准备,如文本分类、语义相似性和聚类。在我的其他文章中了解关于自然语言处理和数据科学的更多信息:

** [## 如何使用 Python 和 Dash 创建控制股市的仪表板

自由期权订单流、价格、基本面、聊天集于一身

medium.com](https://medium.com/swlh/how-to-create-a-dashboard-to-dominate-the-stock-market-using-python-and-dash-c35a12108c93) [## 使用 Python 学*自然语言处理的 3 个超级简单的项目

单词云、垃圾邮件检测和情感分析的简单代码示例

towardsdatascience.com](/3-super-simple-projects-to-learn-natural-language-processing-using-python-8ef74c757cd9)

完全码

这里是完整的代码或在我的 github 上找到它!

[## bendgame/Medium_doc2vec

GitHub 是超过 5000 万开发人员的家园,他们一起工作来托管和审查代码、管理项目和构建…

github.com](https://github.com/bendgame/Medium_doc2vec)

#Import dependencies
import pandas as pd
import sqlite3
import texthero as hero
from texthero import preprocessing
from gensim.models.doc2vec import Doc2Vec, TaggedDocument
import numpy as np
import tensorflow_hub as hub#Establish connection to sqlite database
conn = sqlite3.connect("AllPrintings.sqlite")
#load the data into a pandas DataFrame
df = pd.read_sql("select * from cards", conn)df = pd.read_sql("select distinct name, text, convertedManaCost, power, toughness, keywords from cards where borderColor ='black' and colorIdentity = 'G'", conn)custom_pipeline = [preprocessing.fillna,
                   #preprocessing.lowercase,
                   preprocessing.remove_whitespace,
                   preprocessing.remove_diacritics
                   #preprocessing.remove_brackets
                  ]
df['clean_text'] = hero.clean(df['text'], custom_pipeline)
df['clean_text'] = [n.replace('{','') for n in df['clean_text']]
df['clean_text'] = [n.replace('}','') for n in df['clean_text']]
df['clean_text'] = [n.replace('(','') for n in df['clean_text']]
df['clean_text'] = [n.replace(')','') for n in df['clean_text']]df['tfidf'] = (hero.tfidf(df['clean_text'], max_features=3000))#tokenize and tag the card text
card_docs = [TaggedDocument(doc.split(' '), [i]) 
             for i, doc in enumerate(df.clean_text)]
card_docsmodel = Doc2Vec(vector_size=64, min_count=1, epochs = 20)#instantiate model
model = Doc2Vec(vector_size=64, window=2, min_count=1, workers=8, epochs = 40)#build vocab
model.build_vocab(card_docs)#train model
model.train(card_docs, total_examples=model.corpus_count
            , epochs=model.epochs)#generate vectors
card2vec = [model.infer_vector((df['clean_text'][i].split(' '))) 
            for i in range(0,len(df['clean_text']))]
card2vec#Create a list of lists
dtv= np.array(card2vec).tolist()#set list to dataframe column
df['card2vec'] = dtvdf.head(2)#download the model
embed = hub.load("[https://tfhub.dev/google/universal-sentence-encoder-large/5](https://tfhub.dev/google/universal-sentence-encoder-large/5)")#generate embeddings
embeddings = embed(df['clean_text'])#create list from np arrays
use= np.array(embeddings).tolist()#add lists as dataframe column
df['use'] = [v for v in use]#check dataframe
df.head(2)df['tsnetfidf'] = hero.tsne(df['tfidf'])
df['tsnec2v'] = hero.tsne(df['card2vec'])
df['tsneuse'] = hero.tsne(df['use'])#create scatter plot of tfidf
hero.scatterplot(df, col='tsnetfidf', color='convertedManaCost'
                 , title="TF-IDF", hover_data = ['name','text'])
#create scatter plot of doc2vec
hero.scatterplot(df, col='tsnec2v', color='convertedManaCost'
                 , title="Doc2Vec", hover_data = ['name','text'])
#create scatter plot of uni. sent. enc.
hero.scatterplot(df, col='tsneuse', color='convertedManaCost'
                 , title="U.S.E", hover_data = 'name','text'])

[## 使用这些查询优化技巧成为 SQL 向导

如何对 SQL Server 查询进行性能优化

medium.com](https://medium.com/swlh/become-a-sql-wizard-using-these-query-optimization-tips-a932d18c762f)

谢谢大家!

—埃里克·克莱本**

如何使用 Q-Q 图验证数据的分布?

原文:https://towardsdatascience.com/how-to-verify-the-distribution-of-data-using-q-q-plots-acdb7ca2d576?source=collection_archive---------13-----------------------

艾萨克·史密斯在 Unsplash 上拍摄的照片

统计数字

理解 Q-Q 图并在 Python 中实现它

Q-Q 图,或分位数-分位数图,是一种验证任何随机变量(如正态、指数、对数正态等)分布的图形方法。这是一种观察任何分布性质的统计方法。

例如,如果给定一个分布,需要验证它是否是正态分布,我们运行统计分析,并将未知分布与已知正态分布进行比较。然后通过观察 Q-Q 图的结果,就可以确认给定的分布是否正态分布。

绘制 Q-Q 图的步骤:

  1. 给定一个未知的随机变量。
  2. 找到每个整数百分位值或 100 个 z 值。
  3. 生成一个已知的随机分布,并对该分布执行步骤 1–2。
  4. 绘制 Q-Q 图

给定一个随机分布,需要验证它是否是正态/高斯分布。为了便于理解,我们将这个未知分布命名为 X、,已知的正态分布命名为 Y.

生成未知分布 X:

X = np.random.normal(loc=50, scale=25, size=1000)

我们正在生成具有 1000 个值的正态分布,平均值=50,标准差=25。

(图片由作者提供),X 的前 20 个随机值

查找 100%的值:

X_100 = []
for i in range(1,101):
    X_100.append(np.percentile(X, i))

计算每个整数百分位数(1%,2%,3%,。。。,99%,100%)X 随机分布的值并存储在 X_100 中。

(图片由作者提供),左:X 的分布,右:X _ 100 的分布

生成已知的随机分布 Y 及其百分位值:

Y = np.random.normal(loc=0, scale=1, size=1000)

生成具有 1000 个值的正态分布,平均值=0,标准偏差=1,这些值需要与未知分布 X 进行比较,以验证 X 分布是否正态分布。

Y_100 = []
for i in range(101):
    Y_100.append(np.percentile(Y, i))

计算每个整数百分位数(1%,2%,3%,。。。,99%,100%)的值,并将其存储在 Y_100 中。

绘图:

为上面获得的未知分布到正态分布的 100%值绘制散点图。

(图片由作者提供), Q-Q 剧情

这里 X-是与 Y-正态分布相比较的未知分布。

对于 Q-Q 图,如果图中的分散点位于一条直线上,那么两个随机变量具有相同的分布,否则它们具有不同的分布。

从上面的 Q-Q 图,可以观察到 X 是正态分布的。

如果两个分布不一样呢?

如果 X 不是正态分布,它有一些其他的分布,那么如果 Q-Q 图绘制在 X 和正态分布之间,分散点将不会位于一条直线上。

(图片由作者提供), Q-Q 剧情

这里,X 分布是对数正态分布,与正态分布相比,因此 Q-Q 图中的散点不在一条直线上。

让我们有更多的观察:

这是 X 和 Y 分布的 4 种不同条件下的 4 个 Q-Q 图。

(图片由作者提供),左上:对数正态分布与正态分布的 QQ 图,右上:正态分布与指数分布的 QQ 图,左下:指数分布与指数分布的 QQ 图,右下:logistic 分布与 logistic 分布的 QQ 图

实施:

(作者代码)

结论:

Q-Q 图可用于比较任何两个分布,也可用于通过与已知分布比较来验证未知分布。这种方法有一个主要的限制,即需要大量的数据点,因为推断较少的数据不是一个明智的决定。通过观察 Q-Q 图,可以预测两个分布是否相同。

感谢您的阅读

如何控制 Jupyter 笔记本的版本

原文:https://towardsdatascience.com/how-to-version-control-jupyter-notebooks-ccf0be144319?source=collection_archive---------14-----------------------

根据 Shutterstock.com 的许可使用图像

Jupyter 笔记本在许多方面都很棒,但使用它们进行协作并不容易。在这篇文章中,我们将看看你可以利用的所有工具,让笔记本与现代版本控制系统(如 git)很好地配合!

为什么 Jupyter 版本控制这么难?

软件世界已经将 git 作为版本控制工具的首选。Git 主要用于人类可读的文本文件。而 Jupyter 是一个丰富的 JSON 文档,它将源代码、markdown、HTML、图像都整合到一个。ipynb 文件。

Git 不能很好地处理像笔记本这样的富文档。例如,对于长嵌套 JSON 文档的 git 合并是不可能的,对于二进制图像字符串的 git diff 是可怕的(如下所示)。

对笔记本版本控制有什么要求?

这是我们从现代版本控制系统中需要的-

  • 创建检查点/提交的能力
  • 快速检查任何过去的笔记本版本
  • 查看从一个版本到另一个版本的变化(笔记本电脑的视觉差异
  • 多人可以在一个笔记本上工作,轻松解决合并冲突
  • 能够就特定的笔记本电池提供反馈并提出问题

这是我们的愿望清单!这篇博客将向你介绍所有能帮助你实现这些目标的重要工具。

免责声明:我是下面列出的两个工具的作者(ReviewNB & GitPlus ),但这是对该领域所有有用工具的公正评论。

nbdime

nbdime 是一个用于本地区分和合并笔记本的开源库。您可以将其设置为与本地 git 客户端一起工作,以便git diff & git merge命令使用 nbdime。ipynb 文件。有了 nbdime,你可以—

  • 在提交之前,运行git diff来查看笔记本发生了什么变化
  • 轻松将远程更改与本地编辑的笔记本合并

JupyterLab Git 扩展

以下 JupyterLab 扩展对笔记本版本控制很有用。你可以在你本地的 JupyterLab 上安装这些。

  • jupyterlab-git 可用于浏览 GitHub 库,查看已更改文件的视觉差异,并推送您的提交
  • GitPlus 可用于直接从 JupyterLab UI 在 GitHub 上推送提交和创建拉取请求

AWS SageMaker

SageMaker 是 AWS 提供的托管服务,让您可以访问托管的 JupyterLab。它与 GitHub 存储库集成,因此您可以将您的公共/私有存储库克隆到 SageMaker 实例中。它使用了 jupyterlab-git 扩展,因此你可以将你的笔记本提交到 GitHub。

使用 SageMaker,您只需点击几下鼠标,就可以构建一个强大的 EC2 实例来训练您的模型。缺点是您总是使用昂贵的云计算,即使是那些可以在本地机器上轻松完成的任务,例如浏览数据、编辑笔记本。对于大多数人来说,本地 Jupyter 会话与稀疏 SageMaker 使用(当您真正需要强大的云计算时)的健康平衡是理想的。

谷歌联合实验室

另一个受欢迎的选择是谷歌 Colab。他们有体面的 GitHub 集成,你可以在 GitHub 库中打开一个特定的笔记本。您还可以将任何更改提交回存储库。

Colab 提供有限的免费 GPU,您可以升级到 Colab Pro 以获得更高的使用限制。一些限制是,

  • Colab pro 是一个付费产品,但不提供任何 GPU 时间和类型方面的资源保证。
  • 一切都以单个笔记本文件为中心,您不需要克隆整个存储库或访问本地文件系统。Colab 似乎建议使用 Google Drive 作为你的虚拟文件系统。这将影响训练的速度(通过网络调用获取数据文件,而不是在磁盘上本地获取)。

评论 NB

ReviewNB 是一个 GitHub 应用程序,显示任何笔记本提交或拉取请求的视觉差异。您可以在特定的笔记本单元格上写下评论,以便向您的队友提供反馈或提出问题。

它对开源库是免费的,但对私有库需要付费计划。ReviewNB 应用程序已通过 GitHub &验证,获准在 GitHub marketplace 上销售。

结论

当谈到 Jupyter 笔记本版本控制和协作时,没有一个工具适合所有情况。但是,您的团队可以利用以下专门构建的工具来创建可靠的笔记本工作流-

暂时就这样吧!黑客快乐!

原载于 2020 年 8 月 27 日 https://blog.reviewnb.com

如何使用 Matplotlib 可视化悉尼的温度变化

原文:https://towardsdatascience.com/how-to-visualise-sydneys-temperature-change-from-1859-to-2019-using-matplotlib-79b2dc7308c2?source=collection_archive---------31-----------------------

matplotlib 的动画情节

制作动画情节的详细指南

我相信你读过的主要时事之一一定是澳大利亚森林大火危机。这场毁灭性的灾难影响了超过 1000 万公顷的土地,这与葡萄牙的土地面积相当,估计有 10 亿只野生哺乳动物、鸟类和爬行动物被杀害(来源此处)。越来越多的证据表明气候变化/全球变暖与今年的森林大火之间的联系,例如极端温度(高于平均温度 1.5 摄氏度)和长期干旱(来源此处)。孤立地阅读这些数字,你可能看不到气候变化是如何随着时间的推移而演变的。从数据可视化的角度来看,使用时间序列图可能更有吸引力和信息量,而不是使用单个值来描述变化范围,时间序列图可以显示变量在大范围时间段内的动态趋势。因此,我借此机会利用悉尼的长期气温数据在matplotlib中练*ax.xxx()方法。如果你想知道matplotlib中的ax.xxx()方法是什么,请看一下我的上一篇帖子。这将有助于你理解这个职位,并进一步了解matplotlib

在这篇文章中,我将向你展示我是如何制作悉尼 160 年间年最高气温的动画时间序列图(如本文开头所示)的。在我们深入研究代码之前,这里有一些要点:

  1. 1920 年前后,年最高气温超过 40°C 的年数从 13%增加到 30%。
  2. 悉尼有史以来最高的日最高气温是 2013 年的 45.8 摄氏度。
  3. 在 1920 年前后,经历长时间高温天气(定义为一年中日最高温度超过 30°C 的总天数)的几率分别为 12%和 24%。
  4. 2019 年,与所有其他有记录的年份相比,我们经历了最多的高温日数(34 天)。

情节的结构和主题

图 1,静态版本

作为一个独立的图形(图 1),它至少应该包含三个部分,即标题、情节和脚注。前两部分很容易理解。至于脚注,通常用来表示该图的数据来源和特别说明。

剧情无疑是整个人物最重要的部分。在这种情况下,我用两个不同的 y 轴分别表示温度,它们共用同一个 x 轴,即年。 matplotlib提供了创建轴:ax.twinx() / ax.twiny()的简单方法。具体来说,ax.twinx()创建一个新的axes,它与ax共享 x 轴,但可以有不同的 y 轴。同样,ax.twiny()返回一个共享 y 轴的axes,但是使用不同的 x 轴。在构建了人物框架后,我设置了一个未来色彩主题,灵感来自 Tron Legancy 。在matplotlib中,我们可以通过plt.rc()轻松配置体形样式。rc代表 C 启动时自动 R un 的配置文件。

使用 plt.rc()的 Tron 主题

创建用于静态绘图的函数

我们来看看matplotlib中创建动画剧情的 lite 函数。

animation.FuncAnimation(*fig*, *func*, *frames=None*)

从本质上来说,动画fig只是func用不同的值(frames)获得的静态axes的集合。这非常像动画书动画。以我为例,axes(从 1859 年到 2019 年,即range(1859, 2020, 1))总共有 160 帧。解决了这个问题后,我创建了一个可以普遍应用于不同year值的函数。

这个函数的原理是一层一层的绘制元素(或者我也可以说是matplotlib绘图中的原理)。我来一节一节的解释一下上面的函数。

  • ax.clear()ax2.clear(),之前的axes应该在绘制新的之前被擦除,否则axes中的旧内容仍会留在fig上并记录在动画中。这也是为什么我没有把fig, ax = plt.subplots(figsize=(12,4), dpi=300)ax2 = ax.twinx()包含在函数体中,而是在animation.FuncAnimation()之前分别调用。绘图空间(即figaxax2)只需设置一次,就像一个可重复使用的白板。
  • df_tmp=df_sydney.loc[df_sydney[‘Year’] <= Num_Year],标绘输入应为数据。新的axes应该包含当前年度及其所有以前年度的数据(即<=)。因此,当animation.FuncAnimation在任一给定年份使用Num_Year调用draw_linechart时,静态图中的线应该从开始(即 1859 年)跨越到被调用的年份(图 2)。

图 2,一个静态图形

  • ax.plot(df_sydney.Year, df_sydney.max_tmp_year*0, label=’_1', color=’#222222', zorder=1),这是第一行剧情。注意,这里使用的数据不是df_tmp而是完整的数据帧df_sydney。本节将为每个df_tmpaxes创建一个从起始年(1859)到结束年(2020)的框架。这保证了每个axes的 x 轴具有相同的年份范围(即 1860–2020),而不是随着df_tmp的年份范围(即 1860- Num_Year)而变化。此外,我只需要框架和线应该隐藏这一层,所以我为 y 轴的每个值(df_sydney.max_tmp_year)计时 0。您可能会注意到分配给label的值包含一个下划线,这是为了防止该层被稍后的自动图例元素选择(ax.legend())显示。这里用的另一个自变量是zorder,可以认为是沿 z 轴的层序列,1 表示底层。
  • ax.plot()ax2.plot(),这些增加了两条水平线,方便观众估算每年最高气温和累计天数的数值。
  • ax.plot()ax.text()这是fig中绘制大部分元素(线条、头点、带头点的文字)的部分。这很容易理解。我唯一想再次强调的是ax.xxx()的威力,它让每个axes的操作变得足够简单。

设置好draw_linechart函数后,我们通过输入具体年份来画一个静态图。如果一切顺利,您将看到图 2。

# run one frame to test the function
fig, ax = plt.subplots(figsize=(12,4), dpi=300)
ax2 = ax.twinx()
draw_linechart(1987)

动画图形摘要

运行下面的代码将生成所有的帧并将它们分配给对象animator。然后这个对象就可以通过animator.save()保存成你想要的任何格式。我个人的偏好是另存为mp4。最后要注意的是fig背景颜色要用savefig_kwargs={‘facecolor’:’#222222'}指定,否则会保存为白色,与Tron legancy主题不一致。

import matplotlib.animation as animationfig, ax = plt.subplots(figsize=(12,4), dpi=300)
ax2 = ax.twinx()animator = animation.FuncAnimation(fig, draw_linechart, 
                                   frames=np.arange(df_sydney.Year.values.min(),df_sydney.Year.values.max(),1), interval=300)animator.save('./animation5.mp4', savefig_kwargs={'facecolor':'#222222'}) 

在这里,我从设计到代码演示了如何使用matplotlib创建一个动画图表,这有助于我们更好地理解悉尼 160 年来的温度变化。你可以从我的 Github 下载数据、动画、图表和 jupyter 笔记本。

和往常一样,我欢迎反馈、建设性的批评以及听到关于您的数据科学项目的信息。你可以在 Linkedin 上找到我,现在也可以在我的网站上找到我。

如何使用 Geoviews 在 Python 中创建 Choropleth 地图

原文:https://towardsdatascience.com/how-to-visualize-data-on-top-of-a-map-in-python-using-the-geoviews-library-part-2-e61a48ee6c3d?source=collection_archive---------13-----------------------

使用 Python 和 Geoviews 多边形绘制交互式 Choropleth 地图

在另一篇文章中,我们学*了如何使用geoviews.Points方法创建一个代表地图上特定坐标的点的绘图。我们还使用了geoviews.tile_sources来获得一张地图,我们可以使用它作为我们的基础图层来绘制点。由于我没有找到使用 Geoviews 进行 choropleth 绘图的指南,所以我决定写这个简短的教程。

最终结果会是这样的。

出于本教程的目的,我们将使用 Geoviews 库通过 choropleth 地图绘制一个图表来可视化欧洲国家的经济自由度指数

你可以在探索标签下下载你自己选择的任何地区和年份的数据集。

首先,我们需要导入将要使用的库和方法。

import pandas as pd
import geopandas as gpd
import geoviews as gv
import geoviews.tile_sources as gvts
from geoviews import opts
gv.extension('bokeh')

如果我们阅读从遗产网站得到的 T2 文件,我们会看到这样的内容。

为了理解我们所看到的,数字越高,一个国家在自由方面的得分越高。如你所见,每个类别都有一个分数,这些分数加起来就是overall score。因此,没有必要进入每个类别的细节,所以我们将在本教程中只使用overall score

从现在开始,我们将该数据帧称为ef_df。数据框几乎是完美的。为了更好地理解和解决我发现的一些字符串的问题,我将只添加两行代码。

ef_df = ef_df.rename(columns={'name':'country'})
ef_df['country'] = ef_df['country'].apply(lambda x: x.strip())

现在我们准备继续下一个元素,创建一个 choropleth 地图。那是一个形状文件 ( )。shp ),包含我们感兴趣的国家的边界(实际上是形状)。

我真的不知道是否有更好的 shapefiles,但你可以在网上自由搜索和找到它们。我要用的那个可以从 NaturalEarthData 网站下载。

我们可以使用Geopandas读取 shapefile,并将该数据帧命名为shapes_df

shapes_df = gpd.read_file('C:/.../your_directory/ne_50m_admin_0_countries.shp', driver='ESRI Shapefile')

shapes_df出发,我们只需要 3 列:ADMINTYPEgeometry
geometry列非常重要,因为它包含地理信息,即国家形状。因此,我们将运行下面的代码行。

shapes_df = shapes_df[['ADMIN', 'TYPE', 'geometry']]

现在shapes_df会是这个样子。

正如我所说的,我不知道网上是否有更好的 shapefile,但在这一个中,我们还必须运行以下行来更正一些国家名称,以便与ef_df数据帧上的国家名称相匹配。

shapes_df = shapes_df.replace({'Czechia': 'Czech Republic',
                               'Republic of Serbia':'Serbia'})

现在我们终于可以将这两个数据帧合并成一个了。从ef_df开始,我们将仅保留countryindex yearoverall score列,并且仅针对index year = 2019。

merged_df = gpd.GeoDataFrame(\
            pd.merge(\
            ef_df[ef_df['index year']==2019][['country','index
                year', 'overall score']], shapes_df,
                left_on='country', right_on='ADMIN'))

merged_df会是这样的。

在我们继续之前,请运行类似的程序,确保geometry数据类型是多边形或多多边形。

merged_df['geometry'].geom_type.value_counts()

只是为了确保

现在,我们准备使用geoviews.Polygons方法绘制我们的 choropleth 图。首先,让我们将底图分配给poly``gv.Polygonscarto

polys = gv.Polygons(merged_df, vdims=['country', 'overall score']).\
   opts(color='overall score', cmap='reds_r', colorbar=True,\
      width=1000, height=600, tools=['hover', 'tap'], alpha=0.7,\
      hover_line_color='black',line_color='black',\
      hover_fill_color=None, hover_fill_alpha=0.5,\
      xaxis=None,yaxis=None)carto = gvts.CartoDark.opts(alpha=0.6)

现在如果我们一起运行它们:

polys * carto

我们得到了我们的地图:

我们可以清楚地看到哪些国家在经济上被认为是更自由的(浅色),哪些不是(深色)。

好处:使用 Geoviews 我们可以将更多的地块合并成一个。

为了向您展示这一点,我将使用一个包含国家首都及其各自地理位置(即纬度和经度)的数据集。我在这里找到了数据集。我将称之为capitals_df.

经过一些清理和合并,我们得到了这个样子。

现在,我们可以使用在之前的帖子中看到的gv.Points方法,并将其分配给points.

points = gv.Points(capitals_df, ['longitude', 'latitude'],\
    ['capital']).opts(
        opts.Points(width=1000, height=600, alpha=0.8,\
            tools='hover'],\
            xaxis=None, yaxis=None, color='white',\
            size=7))

最后,我们将运行下面的命令。

polys * carto * points

我们会得到合并后的图。

今天到此为止。希望你觉得有用。下次见!

你可以通过点击这里在 LinkedIn 上找到我。

如何使用 Power BI 可视化数据?

原文:https://towardsdatascience.com/how-to-visualize-data-using-power-bi-9ec1413e976e?source=collection_archive---------11-----------------------

使用 Microsoft Power BI 获得商业智能洞察。

卢卡斯·布拉塞克在 Unsplash 上的照片

什么是数据可视化?

随着技术革命,数据从昂贵、难以查找和收集到丰富、廉价但难以理解。使用传统软件存储、理解和分析越来越大的数据量非常困难。然而,作为个人或组织,所有这些数据的好坏取决于我们能从中获得什么。这就是大数据发挥作用的地方。大数据用于预测分析、分析用户行为或其他数据分析流程,以给数据带来价值。然而,由于缺乏知识,这方面的原始细节仍然不确定。数据可视化有助于解决这个问题。

数据可视化是将数据转换为图表、图像、图形甚至视频的过程,这些数据可以解释数字,并让我们从中获得洞察力。

来自 giphy的托尼·巴贝尔

它使信息更加连贯,帮助我们从中创造价值,发现新模式,发现趋势。让我们举个例子:你如何向你的老板或客户解释 excel 电子表格中的大量数据行和列?创建相同数据的图表,如条形图、折线图、散点图等。这为原始数据赋予了意义和目的,现在您有了一个可视化的表示,您可以开始分析它并将其集成到您的业务中。这为许多企业和用户提供了清晰、可操作的计划洞察,让您始终保持领先地位。

什么是权力 BI?

Microsoft Power BI 是一个数据可视化工具,允许您快速连接数据,准备数据,并根据自己的喜好对数据建模。它使您能够将所有数据转换为实时交互式视觉效果,创建定制的实时业务视图仪表板,从而提取业务智能以增强决策。您可以可视化数据并分享见解。该工具允许您将自定义可视化嵌入到您的应用程序或网站中,连接到数百个数据源,如 excel、google analytics、实时数据的物联网设备等。它将一切与您现有的专业环境方便地融合在一起,使您能够获得分析和报告功能。您可以发布这些报告,因此允许所有用户利用最新的信息。

你可以在这里阅读更多关于 Power BI 的内容。

现在,让我们使用 Power BI 并创建数据的基本可视化。

安装和设置

下面列出了几种安装 Power BI 的方法:

  1. 打开 Microsoft store,搜索 Power BI,然后单击 get 按钮安装它。
  2. 您可以访问 Power BI 桌面下载页面并选择免费下载选项。
  3. 或者,您也可以通过登录并点击屏幕右上角的下载按钮,从 Power BI service 网站免费下载 Power BI Desktop。

安装 Power BI Desktop 后,您现在可以访问 Power BI 服务网站并登录您的帐户。如果您还没有注册,您可以向下滚动,使用您的学生或工作电子邮件地址免费注册。

作者图片

或者,如果您没有学生或工作电子邮件地址,您可以通过点击此处注册一个微软试用帐户。

安装 Power BI Desktop 后,让我们启动应用程序并探索应用程序的主要组件。

作者图片

字段:您可以在这里查看导入的数据及其字段。

可视化:此窗格由不同的视觉效果组成,您可以利用这些视觉效果来显示数据的独特可视化效果。

发布:使您能够将您的数据模型发布到您的 Power BI 工作区。

获取数据:允许您以 excel 文件、text/csv、xml 等格式导入数据。我们也可以从微软 Azure 或其他在线服务如谷歌分析、GitHub 等获取数据。

准备数据

如前所述,“获取数据”选项允许您从不同的平台导入各种大小的数据。你可以从 这里 下载本教程的所有必要材料。

打开名为“SalesData.xlsx”的 excel 文件,从窗口左侧选择库存数据表,然后单击转换数据。这将把您带到超级查询编辑器。超级查询编辑器允许您浏览和转换数据。

太好了!现在我们已经加载了数据,让我们开始清理它。

作者图片

当我们查看库存数据文件时,我们注意到的第一件事是文件中的第一行以及第 9 列和第 10 列有空值。这样的值会降低我们模型的整体性能,所以让我们来清理一下。您可以通过分别选择“删除行”和“删除列”选项来删除行和列。

作者图片

一旦我们这样做了,我们可能会注意到数据的第一行实际上由我们的列名组成。因此,让我们通过选择“使用第一行作为标题选项”来改变这一点。

在超级查询编辑器中,单击“主页”部分左上角的“关闭并应用”,以确保我们的更改得到应用。

您甚至可以通过单击窗口左侧的数据视图图标来轻松更改列的数据类型。

清理我们的数据可能是一个漫长而乏味的过程。上面提到的是处理有一些明显异常的数据的一些基本方法,但是还有更多。在本教程的最后,你会发现我用来理解和学* Power BI 及其功能的参考资料。

为了这个教程,我上传了一个“随时可用”的文件,名为“PowerBI Tutorial.pbix”。请参考上面的链接。一旦加载完毕,我们就可以开始有趣的部分了——可视化我们的数据。

创建报告

在本教程中,我们将学*创建一些图表,并了解如何分析数据。

可视化:

条形图: 现在我们的数据已经加载,我们可以在屏幕右侧的字段窗格中查看它。我们可以从 visualization 窗格中选择所需的可视化,然后返回到 fields 窗格选择我们想要分析的数据。让我们从分析我们库存中的产品及其销售开始。选择平均现有库存(\()、销售额(\))和类别字段。

祝贺您在 Power BI 中创建了第一个图表!

此条形图比较了每个类别的平均库存总额和销售总额。然而,研究这个问题的一个合理的方法是比较我们库存的平均值和每个类别的平均销售额。我们可以通过在可视化窗格中将它的值从 Sum 改为 Average 来实现这一点。

使用相同的逻辑和字段,您可以从 visualization 窗格中拖放不同类型的条形图,并以堆积条形图、堆积柱形图、簇状条形图等形式显示数据,如下所示。

作者图片

折线图: 让我们用折线图来可视化我们的数据。从“可视化”窗格中选择折线图,并从“字段”窗格中的地理数据中选择“销售”字段。将周 ID 拖放到可视化窗格的轴部分,如下面的视频所示。这向我们显示了相对于周 ID 的销售额。此外,我们还可以通过比较库存和销售额来了解产品的可用性。为此,请将“平均库存”字段拖放到可视化字段中的次轴部分。您也可以单击图表,然后从可视化窗格将其更改为面积图或堆叠面积图。

饼图/圆环图: 饼图是众所周知的,但是当显示大量数据时,建议不要使用饼图,因为很难识别类别之间的微小差异。例如:清楚地确定哪个类别占用更多的面积。

作者图片

要创建饼图/圆环图,请选择饼图/圆环图可视化和适当的类别来显示数据,如下所示。

地图: 你还可以用一张地图查看你在不同地方的销售情况。从可视化窗格中选择地球仪图标。现在选择所需的类别,即州 ID 和销售额。在分析一些类别时,图例非常有用。使用图例,我们还可以通过将类别字段拖放到图例部分来查看该州每个类别的销售额,如下所示。

关键绩效指标: 关键绩效指标(KPI)是衡量公司绩效并评估其成功与否的指标。我们可以使用 visualization 窗格中的 card 或 gauge 选项在 Power BI 中显示这一点。使用 KPI 选项时,我们需要将周 ID 拖动到可视化窗格中的趋势轴上,以便查看 KPI 值背后的每周趋势。

删除图表:要删除图表,只需点击并按 delete 键。

添加新页面:要添加新页面,点击窗口底部的“+”图标。

作者图片

现在我们已经学会了如何可视化我们的数据,我们可以整合一切,并制作一个仪表板。

创建仪表板

要制作仪表板,请将我们到目前为止创建的所有可视化效果复制粘贴到同一个页面上,如下所示。

作者图片

这基本上就是我们的仪表板。要创建此仪表板的移动视图,请单击“视图”按钮并选择“移动布局”。一旦你做到了这一点,你就可以随心所欲地将你的可视化效果拖放到手机屏幕上。

定制

现在我们的仪表板已经准备好了,我们可以通过浏览 visualization 窗格的 Format 部分中的各种可用选项来配置我们的可视化。

Power BI 中的 r 和 Python

在 Power BI 中包含 Python 和 R 是微软所做的最伟大的事情之一。Power BI 现在是使用不同库和机器学*包进行数据可视化的一站式平台。它允许您在不修改基础工具的情况下重塑数据。

用功率 BI 积分 R

r 是一种用于统计计算和图形的语言和环境。我们可以使用 Power BI 中的 R 来分析我们的数据,以获得所需的结果。

需求:你需要在你的系统中安装 RR studio 以及其他必要的包和库。

作者图片

设置:点击 Power BI 窗口左上角的文件,选择“选项和设置”。转到 Options 下的 R scripting 选项,确保列出了包含 R 的文件夹的正确路径,并且检测到了 R studio IDE,如下图所示

使用 R 脚本可视化数据: R 为数据分析和可视化提供了一个惊人的平台。它允许您甚至在开始数据分析之前就将数据可视化。下面是一个数据可视化的例子,通过使用 R 脚本显示我们的销售频率。

集成 Python 和 Power BI

Python 经常使用 matplotlib、Seaborn、Gleam、Plotly 等库进行数据可视化。Power BI 是一个我们可以集成和增强 Python 可视化的平台。

需求: 安装 Python 以及您将在系统中需要的其他必要的库和包

设置:点击 Power BI 桌面左上角的文件,进入选项和设置部分的选项下的 Python 脚本。确保 Python 主目录设置为 Python 在系统中的安装位置,如下图所示。

使用 Python 脚本可视化数据: Python 已经被用于数据可视化很多年了。像 matplotlib 这样的库有助于理解数据。虽然,当谈到快速方便地创建美观的图表时,Python 不是很有用。然而,当我们集成 Python 和 Power BI 时,我们获得了出版物质量的图表。下面的视频向我们展示了一个使用 Python 显示与周 ID 相关的销售额的实例。

保存和发布

让我们回到我们的仪表板。现在我们已经有了一个可以发布的仪表板。

  • 保存你的工作:进入 Power BI 桌面窗口左上角的“文件”,点击保存。您也可以使用“Ctrl + S”快捷键来保存您的工作。您还可以将您的作品导出为 PDF 或 Power BI 模板。
  • 发布:进入 Power BI 桌面窗口左上角文件下的发布部分,点击“发布到 Power BI”。选择您的工作空间。点击“在 PowerBI 中打开 PowerBI Tutorial.pbix ”,在工作区查看您的报告。现在,您可以与其他人共享您的报告,也可以在您的工作区中编辑它。

结论

恭喜你完成了本教程!现在,您已经学*了 Power BI 中数据可视化的基础知识。在本教程中,我只介绍了几种类型的可视化,但是在 Power BI 中还有更多类型的可视化可供您探索。发挥创造力,以自己的方式可视化您的数据。

感谢你阅读我的文章,希望你喜欢。

参考文献:

[1] Udemy,“微软认证:数据分析师助理 Power BI”:https://www.udemy.com/share/1035gaBEISdFxVQ3s=/

[2]微软的 Power BI 文档:https://docs . Microsoft . com/en-us/Power-BI/fundamentals/desktop-getting-started

如何用 Python 可视化数据中的隐藏关系 NBA 助攻分析

原文:https://towardsdatascience.com/how-to-visualize-hidden-relationships-in-data-with-python-analysing-nba-assists-e480de59db50?source=collection_archive---------8-----------------------

使用交互式快照、气泡图和桑基图操纵和可视化数据,通过 Plotly 获得洞察力(代码和数据在我的 GitLab repo 中)

数据分析的一个非常基本的目标是理解数据中的关系。从简单的 Excel 图表到从事机器学*的数据科学家,这在每个分析层面都是如此。无论是预测一个值(回归)还是识别一个类型(分类),目标都是发现输入和输出之间关系的本质。

正如你们中的一些人所知,我一直在修补篮球数据分析。我一直在研究的一个问题是,一个特定的统计数据,一个“辅助”,总体上表明了一个团队的什么。在这篇文章中,我分享了我的一些分析和输出,用来深入了解这种辅助其他绩效指标之间的关系。

尽管这个例子是专门针对篮球的,但一般的过程和可视化应该适用于其他领域,适用于他们自己的数据集。关于篮球的讨论也只是有限的,只是在解读结果的背景下,所以不要让领域知识的匮乏太让你担心。

我在我的git lab repo here(basketball _ assists目录)中包含了这个的代码,所以请随意下载并使用它/对它进行改进。

在开始之前

数据

我将代码和数据包含在我的 repo 中,所以如果您愿意,您应该能够通过下载/克隆 repo 来轻松地跟进。

包装

我假设您熟悉 python。即使你相对较新,这个教程也不应该太难。

你需要pandasplotlystatsmodels。用一个简单的pip install [PACKAGE_NAME]安装每一个(在您的虚拟环境中)。

问题:助攻…有帮助吗?

在篮球比赛中,如果队友的一次传球导致得分。因此,从定义上来说,助攻只是抓住了球员得分的机会。

所以,我想回答的问题是这样的:助攻好不好?

助攻能捕捉到一个球队获得好的得分机会的频率吗?数据告诉了我们什么?(注:有些 现代统计学 已经开始捕捉‘潜在’助攻只是为了这个目的,对于这个讨论忽略它。)

让我们开始吧。我首先回顾了投篮命中率与助攻的关系。在我们开始之前,也许简单回顾一下背景会更方便。

概述

在之前的文章中,我讨论了使用 Plotly 生成拍摄图。在其中,我们生成了图表,利用球场上的彩色六边形来显示射门位置、频率和准确度。

在该图中,标记位置显示了击球位置、与频率相对应的大小以及与该区域的击球准确度相对应的颜色(球场被划分为区块或“区域”以消除差异)。

我做了一些小的改动,但是在这里包含了代码和底层函数,所以您不必重新创建它们。(一如既往,我还包括了本文中使用的所有数据文件。)

我们能在地板上绘制类似的辅助率吗?

制图辅助费率

令人欣慰的是,这可以很容易地完成,同时循环大部分代码,并用由assisted_shots / total_made_shots计算的辅助百分比来代替投篮命中率。

我已经预先计算过了,所以您可以简单地加载数据并运行以下程序:

这会产生:

NBA 投篮排行榜——由助攻率着色

真有意思!助攻率在角落最高(大约 95%),在篮筐周围相当低,特别是当我们开始远离篮筐时,助攻率下降到大约 40%。

但这并不能真正说明相关性。事实上,并排观察会发现这些比率是反比相关的(请看下文)。具有最高精度的区域实际上具有最低的绘制辅助率。这是因果关系吗?助攻对球队不好吗?

这是否说明了逆相关?还是我们忽略了其他因素?

无论从直觉上还是逻辑上,这似乎都不成立。视觉效果有误导性。原因是这些精度比辅助率更能影响射击位置。如果我们不看联盟范围的数据,而是看单个球队的数据,看看助攻率的变化对球队投篮命中率有什么影响?

散点图有助于理解精确度与辅助率的关系

为了进行这种分析,我们需要来自各个团队的数据。Basketball-reference.com 通过收集球队、球员和比赛的统计数据让这变得非常容易。由于我们将处理 18-19 赛季的投篮数据,我从篮球参考这里收集了球队数据。

2018/2019 赛季球队每 100 分统计(basketball-reference.com)

在使用统计数据时,重要的是针对给定的目标或背景使用正确的数据。我在这里使用了每 100 分的控球统计数据来标准化球队速度的影响,这可能会稍微扭曲我们的数据(虽然不是真的,因为我们在看比率)。

散点图很简单,在我看来,它仍然是获得数据和任何相关性的最好方法之一。让我们就这么做吧,标绘准确性(投篮命中率%)对每 100 次助攻,这捕捉到了以助攻结束的控球率的%。

提醒一下,我们使用 Plotly Express 中的 scatter function,其中的语法基本上是传递一个数据帧,各种参数作为与该数据帧中的列名匹配的字符串传递。

所以px.scatter(per100_df, x=’AST’, y=’FG%’让 Plotly 知道 X 数据应该来自‘AST’列,Y 来自‘FG %’列。其余的就不言自明了。

我们还使用 Plotly 在这里添加了一条趋势线。(这就是statsmodels包装的目的。),有一条简单的线性趋势线(点击这里了解更多信息)。

可视化精确度和辅助之间的相互关系

哇,这看起来像是助攻/100 和投篮命中率之间的一个很好的关联图。从直觉上看,这也是明智的。因为球的移动速度比防守者快,好的传球能更好地找到当时防守不严密的球员。所以,一个记录更多助攻的球队提供更多好机会是有道理的。

(如果你想知道表示 100 分的颜色,那是因为离群值(you 印第安纳)比其他人投了更多/更少的 3 分。)

如果我们进一步深入细节,查看数据,在法庭上分成不同的区域,会怎么样?

将数据细分为区域

还记得我们说过法庭被分成了几个区域吗?在这个分析中,我们使用简化的区域,这些区域主要基于距离,忽略了方向。

所以,法庭被分成七个区域,或者说地带,就像这样:

我的分析中定义的射击区域

通过将每一次投篮分配到这些区域中的一个,可以进行与上面相同的分析,以查看助攻在每个区域中的影响。由于团队数据不容易提供这个集合,我们将操纵数据框架并自己创建它。

从单个镜头的数据库开始,我已经用一个区域对每个镜头进行了编码,我们创建了一个数据帧,其中每行对每个队的一个区域的信息进行编码。

在这里,我循环遍历每个团队名称,按区域整理它们的数据,并通过在区域名称内再次循环,将每个区域的每个数据分配给一个新条目。每个条目都作为一个字典对象保存到一个列表中,然后被转换成一个数据帧。(如果你不确定发生了什么,这里有 熊猫的文档。groupby 方法,以及 熊猫。DataFrame 功能。)

这些数据现在可以绘制出来了——这是我之前准备的,使用了:fig = px.scatter(flat_summary_df, x=’assist_pct’, y=’shots_pct’, color=’zone_name’, hover_name=’teamname’)和一点格式。

投篮命中率与助攻,按区域。

每组彩笔包括 30 个图形,每个队一个。你自己看看吧。这些标记中的许多组并没有表现出太多的相关性,但是一些明显地表现出相关性。其他一些事情也很突出/

我们现在称之为“中距离”投篮的红色和绿色轨迹显示,他们的助攻百分比最低。这可能是因为它们相对不受欢迎,因此犯罪不是为这里设计的,因此它们通常是后备选项。

紫色角落的 3 分是最理想的投篮之一,所以他们有很高的助攻率是有道理的。

底部一组 30 多英尺的照片非常分散——但考虑到它们来自最远的距离,它不会显得太不协调。由于这些投篮的低命中率,我们预计结果会有更大的差异,而且这些球队中的一些平均起来会更频繁地远距离投球。

但是从内部拍摄的照片显示了很好的线性度,可能在弯道 3 也是如此。为了更好看。实际上,让我们把它们都分离出来,单独看一下。

此外,我们将根据球队名称给他们上色,并根据每个区域的射门频率来调整大小。这样,我们也可以看到一个队从每个区域投篮的频率。

到目前为止,您(希望)已经熟悉了 Plotly Express 的'scatter'功能。由于使用了 facet 特性并进行修改,所以这有一点不同,所以让我们一步步来。

参数facet_col指定应该使用哪个类别变量来分隔这些图形,以及facet_col_wrap一列中有多少子情节。

通常,在这些图形中,您会为子图形使用相同的轴范围,以允许图形之间更公平的比较,因为改变比例会导致视觉上的误解。

然而,我们已经从整体上看了上面的数据。此外,我发现缩放通过将数据聚集在一起模糊了对数据的理解。

因此引入了update_xaxisupdate_yaxis方法来取消轴对齐。当我们这样做时,我要确保每个轴都显示在图上,以避免误解。生成的图表如下所示(对图表进行调整,但请记住,在轴不共享但可能被误解的情况下,您应该小心对齐图表):

射击精度与助攻,由支线剧情中的区域。

显然,一些区域在助攻百分比和投篮命中率之间显示出比其他区域更好的相关性。这可能说明了几件事:

一个是助攻可以帮助创造好的投篮,第二个是当我们离篮筐越远,射手的能力就成为更大的因素。

在篮筐周围,简单地创造好机会可以让球员轻松上篮和扣篮。这种影响随着距离的增加而减小,但是我们可以看到在 3 秒角时增加辅助速度的影响。

然而,当我们看到规则 3s 时,这种影响是微小的,长 3s 分布看起来像一个经典的随机分布,这里显示的是零相关。

维基百科关于分布形状&相关系数的入门

我们能回到过去,看看篮球场上的数据吗?是的,我们可以。

通过拍摄图表进行关联

请记住,我们不能获得一个伟大的想法之间的投篮命中率和助攻以上。这是因为我们只是在观察绝对值,而不是一个变化对另一个变化的影响。

如果我们针对一些球队在球场上的相对助攻率和联盟平均值绘制相对准确度的图表会怎么样?

在我以前的文章中,我们看到了如何通过从相对值(球队数据)中减去基础值(联盟数据)来绘制相对准确度。在这里,我们简单地对‘ass_perc_by_hex’做同样的事情。为了避免重复,我在这里省略了代码——如果你想看完整版,可以看看我的 git repo。

绘制相对于助攻率的准确性图表,作为相对于联盟平均水平的相对值,我们为勇士和骑士生成了以下图表:

相对精度与辅助率,GSW 18-19

相对精度与辅助率,CLE 18-19

看一下内部的统计数据,和弯角,我们在上面看到了相关性相对较好。在这里仍然如此。

离篮筐越远,随机性的作用越大,球员能力的影响也越大,而不仅仅是在正确的地点和正确的情况下得到球。因此,这种相关性较弱,尽管它似乎仍然存在。

(为了让外线投篮更加稳定,必须对球员的能力进行标准化处理。)

最后,我想想象一下这些帮助来自哪里。我们将深入研究一些(喜欢 Plotly )所谓的平行类别图,这类似于流量图,或桑基图。

ParCat / Sankey 图

这些图最初被设计用来显示流动,例如液体或材料的流动。因此,他们很擅长展示关系。每一个篮筐都与投篮的球员、协助比赛的球员(有时甚至没有)以及投篮的位置有关。

使用 Plotly 很容易生成人造镜头的平行类别图:

teamname = 'HOU'
team_df = shots_df[shots_df.team == teamname]# Simple ParCat plot
fig = px.parallel_categories(team_df[team_df.shot_made == 1], dimensions=['player', 'shot_zone', 'assist'],
                color_continuous_scale=px.colors.sequential.Inferno,
                labels={'player':'Shooter', 'shot_zone':'Shot location', 'assist':'Assist (if any)'})
fig.show()

我的第一个平行分类图

这看起来令人印象深刻,但很难看出发生了什么。也许我们应该通过计数来组织左侧和右侧,并根据射门是否被辅助来给条形着色。

要按计数对数据帧进行排序,我们可以使用 pandas 的pd.factorize函数,提取计数,按计数排序,然后根据行顺序创建一个新的数据帧。

i, r = pd.factorize(makes_df['assist'])
a = np.argsort(np.bincount(i)[i], kind='mergesort')
makes_df = makes_df.iloc[a]

颜色可以用任何一种 Plotly Express 来分配,虽然我是用常规的plotly.graph_objects来分配。

除了格式化对象之外,代码的主要部分如下(完整函数& call 见 repo):

现在为几个玩家绘制这些,作为例子:

克林特·卡佩拉在 2018-19 赛季的投篮

詹姆斯·哈登在 2018-19 赛季的投篮

克莱·汤普森在 2018-19 赛季的投篮

我们可以立即看到球员的投篮有多少被助攻,他们喜欢从哪里投篮,他们在每个区域的投篮有多少被助攻,以及他们最有成效的合作伙伴在哪里。

上面的图表立即向你展示了卡佩拉的投篮有多少被助攻,以及哈登在卡佩拉的得分中发挥了多大的作用。

接下来的两张图表显示,尽管哈登和克莱·汤普森都是不可思议的射手,但他们的得分风格却大相径庭。汤普森的大部分投篮来自传球,而哈登几乎所有的投篮都是绝对创造的。

该图表可以扩展到显示整个团队:

休斯顿火箭队在 2018-19 赛季的所有投篮

在 18-19 的火箭队,哈登和克里斯·保罗(在某种程度上还有奥斯汀·里弗斯)是唯一一个创造自己投篮机会的人。火箭队的大多数中距离投篮都是独立完成的,即使在这种复杂的布局下,卡佩拉-哈登的联系也是显而易见的。

正如你所看到的,我们已经在几个图表中发现了很多 NBA 各种统计数据之间的关系。作为一个额外的好处,Plotly 的交互性意味着您可以简单地悬停在数据点上并获得进一步的见解,这可能不容易获得,或者需要创建额外的图表或注释。

尽管这个例子与篮球数据有关,但我毫不怀疑这些例子同样适用于其他运动或任何其他数据集。这里的重点是调查各种数据列之间的关系的性质,这些图表使我们能够做到这一点,而无需构建或训练复杂的模型。

请下载数据和代码,玩一玩,用你自己的数据集构建类似的东西。我很想听听你的经历或评论!

如果你喜欢这个,比如说👋/在 twitter 上关注,或关注更新。我还写了一篇关于用 Plotly 可视化篮球数据的文章,如果你以前没有读过,这可能对本文有所帮助。

[## 用 Plotly 实现交互式篮球数据可视化

用 hexbin shot 图表分析体育数据,用 Plotly 和 Plotly Express 分析气泡图(源代码&我自己的数据…

towardsdatascience.com](/interactive-basketball-data-visualizations-with-plotly-8c6916aaa59e)

这是我最喜欢的数据可视化书籍:

[## 用这些书创建有影响力的数据可视化

如果没有交流,好的分析没有什么意义。数据可视化会有所帮助。以下是我对…的建议

towardsdatascience.com](/create-impactful-data-visualizations-with-these-books-ca9fbfecfde5)

如何使用 Plotly 和 R 可视化高频金融数据

原文:https://towardsdatascience.com/how-to-visualize-high-frequency-financial-data-using-plotly-and-r-97171ae84be1?source=collection_archive---------36-----------------------

照片由尼克·钟Unsplash 拍摄

关于如何使用 Plotly 软件包从真实资产数据创建烛台图表的分步指南。

在本文中,我将展示如何使用 Plotly 软件包,通过 r 可视化高频率的金融数据。为了执行分析和开发交易算法,有必要以非常高的频率获取数据,以便能够采取快速而准确的行动,最大限度地提高交易中获得的利润。

今天,在美国证券交易所进行的超过 40%的操作是由机器人进行的,这些机器人被编程来分析市场,并根据市场指标进行买卖。今天我们将学*如何从被日内交易者广泛使用的名为“迷你指数”的巴西资产数据中创建蜡烛图。

收集数据

有几种方法可以从交易所收集高频数据。但是今天,由于我们不会实时分析数据,我们将使用 Metatrader 收集数据,这是一个用于进行自由交易的工具,可以进行资产的购买和出售。

第一步是打开工具并选择我们想要从中收集数据的资产。在我们的例子中,现在是 6 月,该月的迷你指数资产是 WINM20。

Metatrader 快照—按作者分类的图片

选择资产后,我们选择图表的时间框架。请选择一分钟的时间,以便我们可以在几秒钟内收集数据。

Metatrader 快照上的时间范围—按作者分类的图像

之后,点击文件并保存。资产数据将保存在中。csv 格式。
准备就绪,数据采集完成!我们去数据处理吧!

导入和分析数据

我使用 R,一种强大的免费统计编程语言,以及一些图形库来执行我的分析。打开 RStudio 后,我创建了一个. RScript 文件。

我们从导入必要的库开始

library(plotly) #para plotar os gráficos
library(xts) #para trabalhar com dados de séries temporais
library(tidyverse) #jeito magnífico de trabalhar com dados

然后,我们导入名为“WINM20M1.csv”的资产数据

data <- read.csv("WINM20M1.csv", header = FALSE, sep = ",", fileEncoding = "UTF-16LE", dec = ".")head(data)

快照—数据。框架—作者提供的图像

我们看到七个还没有名字的变量。因此,我们使用 OHLC 标准(开盘、盘高、盘低、收盘)创建一个带有变量名称的向量,并将该向量赋给 data.frame 列的名称。

colnames_ <- c("Date", "Open", "High", "Low", "Close", "Tick", "Volume")

colnames(data) <- colnames_head(data)

快照-数据帧-作者提供的图像

既然我们已经对数据进行了适当的重命名,我们需要将变量 Date 的类型改为 Date。但是在改变它之前,我们必须改变字符串来替换“.”按照“-”号。

data$Date <- gsub("\\.", "-", data$Date)data$Date <- as.POSIXct(data$Date)head(data)

快照-数据帧-作者提供的图像

好了,现在是数据可视化。

可视化数据

最后,为了可视化数据,我们使用了 Plotly 库,它非常适合这种类型的任务。首先,我们创建一个 fig 变量来存储我们的图表。我将只用最后 20 分钟,这样视觉效果不会太密集

fig <- tail(data, 20) %>%
  plot_ly(x = ~Date, type = "candlestick",
          open = ~Open, close = ~Close,
          high = ~High, low = ~Low)
fig <- fig %>% layout(title = "Candles de Mini Ídice")fig

瞧啊。

plotly-R-股票市场-快照-作者图片

问题或意见,请联系!抱抱!不要忘记订阅我们的时事通讯,接收有关数据科学、数学和金融的每周内容。

如何用 Python Plotly 可视化交互式 3D 网络

原文:https://towardsdatascience.com/how-to-visualize-interactive-3d-network-with-python-plotly-4ef6989d83cc?source=collection_archive---------26-----------------------

关于 Google Colab — 2020 更新版

照片由 JJ 英Unsplash

在这个数据的黄金时代,数据素养是最受欢迎的技能之一。每家公司都在试图收集更多的数据,数据集现在很容易(而且越来越容易)在线提供给公众,各种软件正在以巨大的速度产生数据。

由于这种现象,可视化和理解所有这些数据的能力(数据素养)现在是一种无价的技能。根据《哈佛商业评论》的焦点小组研究,人们缺乏的两项技能是:

-创建易于理解的可视化效果,以便领导了解结果

-讲述一个故事,帮助决策者看到全局,并根据分析结果采取行动

在本指南中,我将使用 Google Colab 演示如何从头开始设置和创建您自己的 Python 脚本,以便您可以可视化您自己的 3D 网络。如果你对 Plotly 提供的内容有兴趣,请查看这些链接——链接链接

本指南改编自 Plotly 的官方指南。我对该指南所做的更改:

  • 修正了一些给我错误的代码
  • 从指南中删除了一些不必要的冗长代码,以便于理解

这些就是我认为写一个新的 2020 更新版本可能会有帮助的原因(这里是 Google Colab 链接)。这是最终的可视化效果:

Les Mis 数据集来自链接,Gif 由作者创建

我强烈建议查看数据集,这样我们就知道 json 数据是什么样子的。在数据科学项目中,您可能会遇到的最常见的错误/缺陷之一是在处理数据之前没有将数据整理成正确的形状或形式。

如果你想写一些快速脚本,我强烈推荐使用 Google Collab。已经安装了许多公共库,所以您可以直接导入它们。对于需要安装的库/包,只需使用!pip 命令并运行它来获得这些库,如下所示:

!pip install python-igraph!pip install chart_studio

成功安装后,我们现在将导入库,然后查看导入的数据:

第 13-15 行与他们的官方指南略有不同,因为当我试图遵循他们的指南时,我得到了错误,所以我使用了 urllib.request.urlopen。

print(data.keys()) //returns dict_keys([‘nodes’, ‘links’])

我们将打印数据键,只是为了显示数据对象的键是什么样子。

print(N) //returns 77
...
print(data['nodes'][0]) //returns {‘name’: ‘Myriel’, ‘group’: 1}

有 77 个节点,我们将打印第一个节点,看看它是什么样子。

数据集的快速解释—因此每个节点都有一个“名称”标签,并属于某个“组”(不同的组用不同的颜色表示)。链接就像从“源”到“目标”的每个节点之间的边,具有特定的值。

接下来,我们将使用 kk 布局创建图形,然后准备 Xn、Yn、Zn 和 Xe、Ye、Ze。

印刷品:

IGRAPH U--- 77 254 -- 
+ edges:  
  0 --  1  2  3  4  5  6  7  8  9 11  
  1 --  0  
  2 --  0  3 11  
  3 --  0  2 11
...

注意:写…是为了替换剩余节点的长列表

[[-0.547629032126533, 3.63383245493983, 2.9142413409773], [0.9167084013128767, 4.0198261702945475, 4.588913666431853], [-0.6094374124799637, 3.772671804410202, 1.7708885944486699]] 
[(1, 0), (2, 0), (3, 0)] 
['Myriel', 'Napoleon', 'Mlle.Baptistine'] [1, 1, 1] [0.9167084013128767, -0.547629032126533, None] 
[4.0198261702945475, 3.63383245493983, None] 
[4.588913666431853, 2.9142413409773, None]

我花了一段时间才弄明白为什么我们必须在第 31–33 行的边上添加 None。事实证明,这是因为如果我们不传递 None,Plotly 将在其他两个轨迹之间连接第三个轨迹(线)。要了解更多,请查看这个链接

最后,我们绘制节点和边的散点图,然后显示下图:

结果如下:

Les Mis 数据集来自链接,Gif 由作者创建

本教程到此为止,感谢您的阅读和…

快乐的数据可视化!ʕ•́ᴥ•̀ʔっ

如何可视化 KPI 进度—包含 3 个衡量指标的项目符号图

原文:https://towardsdatascience.com/how-to-visualize-kpi-progress-bullet-graph-with-3-measures-ed40598643e7?source=collection_archive---------16-----------------------

Tableau 分步指南

Kiril Yunakov 的公共画面页面。

答几个月前,我受命为我的团队创建一个新的仪表板,目的是查看几个关键绩效指标与我们的计划和预测相比的状况。这就是我如何找到项目符号图表类型,并为我们的业务案例做了一些修改。我相信,特别是如果你是一个 Tableau 的新用户,通过这篇教程你将能够学*和理解 Tableau 的基本原理,以及如何快速调整你的可视化效果。

为什么这个项目符号图有点特别?

简而言之,因为它允许您从 3 个角度(3 种不同的度量)比较特定的维度:

  • 实际表现(你已经完成了多少)
  • 计划/目标绩效(你需要完成多少)
  • 预测

此外,在 Tableau 中,默认情况下您可以 而不是 从预定义的选项中构建这样一个图表,因为它们只允许您使用 2 个指标,而在我们的示例中,我们需要 3 个指标(实际、计划&预测绩效)。

从 Tableau 的“演示”菜单中。

使用此自定义项目符号图,您可以回答一些业务问题:

  1. 到今天为止,根据计划,我们进展如何?
  2. 如果我们保持同样的速度,月底我们会在哪里结束?

Kiril Yunakov 的公共画面页面。

步骤 1: 数据角力

这可能是关于教程最关键的一步。根据您的数据,您可能需要首先透视您的数据集。这是一个重要的步骤,因为它将允许您对您的每个 KPI(营业额/新客户/成本)使用所有 3 个衡量指标(实际/计划/预测),并基本上将其应用于项目符号图。以下是我将使用的数据集示例:

样本数据集

2.将数据导入 Tableau

只需打开 Tableau 并连接到您的数据源。在我的例子中,它是一个简单的 csv 文件,如上所示。

3.添加测量和尺寸

选择 #actual 尺寸,并通过拖放将其放置到柱架上。对#预测和重复同样的操作,对【ABC】测量名称进行操作,但对行货架进行操作。

4.创建一个双轴图形

选择列架上的任何药丸(在我的情况下为 #forecast ),并从下拉菜单中选择双轴选项。

5.将图表类型更改为条形图

从“标记”卡的“全部”下,选择“酒吧”。这将把图形的类型变成条形图。

6.切换#实际药丸和#预测药丸

通过这一步,您将看到列/行货架上药丸的顺序有多重要。目前,#预测测量显示在#实际测量上方。这是因为它在#实际药丸的右边。为了反转它们,我们只需将# 实际的药丸拖放到列架的右侧。当你看到一个橙色的小三角形后,把它放在那里。

7.更改条形大小

我们现在有了#实际测量值和#预测值,但是为了查看它,我们需要改变条形的大小。从标记卡中选择总和(实际)字段,并从尺寸选项中向左拖动滑块。

8.同步轴

右键单击任意轴(在我的例子中是#预测)并选择同步轴

9.添加#plan measure 作为参考行

#plan measure 从数据窗格中拖放到 SUM(actual) 的标记卡中,并放入 Detail 选项中。这使您可以在不直接影响项目符号图视图的情况下使用这种方法。

从分析窗格中,将参考线选项拖放到条形图视图上,并确保将其放置在每个单元格的字段上,每个总和(实际)。

然后,将出现一个窗口,并从选项中选择:

  • 值—选择总和(计划),计算总和
  • 线条——将颜色改为黑色,并使其更粗一点。

10.创建计算字段—#实际到计划

从分析菜单中选择创建一个计算字段(或右键单击数据窗格并从中选择)。给它一个合适的名字,并使用截图所示的计算。通过该字段,我们现在可以看到作为一个比率,我们完成了多少计划。

然后在标签选项的总和(实际)下拉菜单下,将#实际到计划测量拖放到标记卡

11.创建计算字段—#预测至计划

与上一步相同,唯一不同的是您需要在详细信息选项的总和(预测)下拉菜单下的标记卡中拖放新字段。

12.创建计算字段—状态

通过这一步,您可以更容易地确定哪个 KPI 已经步入正轨,哪个 KPI 需要更多关注。右键单击数据窗格,创建计算字段并使用以下代码:

IF [forecast to plan] > 1.2 then “Over Plan”
ELSEIF [forecast to plan] < 0.8 then “Behind Plan”
ELSE “On Plan”
END

创建后,您可以将字段拖放到总和(预测)下拉菜单中的标记卡上的颜色选项中。我们稍后会调整颜色。

13.添加摘要框

为了添加汇总框,您需要在标记卡的总和(预测)下拉菜单中添加一些指标。拖拽#实际#计划。

然后右键单击视图中的任意预测条,并选择注释 > 标记…

只保留实际计划预测到计划的措施。对所有其他度量名称(成本/新客户)重复相同的步骤。

14.格式化

  • 右键点击两个轴,取消显示标题
  • 右键单击标题工作表 1 ,并将其重命名为 KPIs 进度。
  • 右击测量名称并选择隐藏行的字段标签。
  • 右击#实际到计划测量,默认属性,格式数字- >百分比带 0 位小数。重复#预测到计划测量的步骤。
  • 标记卡中选择总和(实际),并选择标签选项。从字体选项中设置校准中间和颜色为白色。
  • 标记卡中选择 SUM(forecast) ,并选择 Color 选项,为不同的状态应用合适的颜色。
  • 右击其中一个摘要框,选择格式,将底纹改为。对其他盒子重复该步骤。

最终可视化。基里尔·尤纳科夫的公开画面页面。

要下载最终的 Tableau 工作簿,请访问我的公共 Tableau 页面。

如果你觉得这篇文章有用,你不同意其中的一些观点,有问题或建议,请不要犹豫,在下面给我留言。非常感谢您的反馈!

LinkedIn:圭纳科夫

如何用图论可视化社交网络

原文:https://towardsdatascience.com/how-to-visualize-social-network-with-graph-theory-4b2dc0c8a99f?source=collection_archive---------15-----------------------

找出《权力的游戏》中的影响者

动机

读完 G. R. R .马丁的《冰之歌与被解雇》系列的书,作为《权力的游戏》的忠实粉丝,你可能会好奇谁是维斯特洛最有影响力的人。或者你知道艾德·史塔克和蓝道·塔利是有联系的,但不太清楚它们到底是如何联系的。他们是由第三人还是第四人联系在一起的?如果能把网络形象化,是不是很棒?

照片由威廉·克劳斯Unsplash 上拍摄

作为数据爱好者,您决定搜索相关数据进行分析。幸运的是,你找到了乔治·r·r·马丁《冰与火之歌》的人物互动网络数据。这是多么令人兴奋啊!但是数据包含节点和边的列表。它们到底是什么意思,你应该从哪里开始?别担心。我支持你。让我们来理解什么是图,以及图如何帮助我们理解社交网络。

什么是图?

图是包含个顶点(或节点)和的结构,每一对相关的顶点称为一条边。这些边可以是有向的或无向的。定向意味着一个方向。人 A 可能喜欢人 B,但是人 B 可能不喜欢人 A。如果 A 和 B 握手,那也意味着 B 和 A 握手

有六个顶点和七条边的图。检索自维基百科

有了图的结构,它可以用来有效地可视化社会网络。想知道团队中成员的影响者?我们可以立即看到拥有最多连接(边)的人(节点)是影响者。

微软检索

太好了!我们知道为什么图表在可视化网络方面是有用的。让我们看看如何创建图表,并使用它来可视化《权力的游戏》中的角色网络!

探索数据

我把几本书的多个数据合并成两个文件:节点数据‘ASOIAF_nodes.csv’,和边数据‘ASOIAF_edges.csv’.你可以在这里找到数据

import pandas as pdnodes = pd.read_csv('ASOIAF_nodes.csv')
nodes = nodes['Id']
num_nodes = nodes.shape[0]
nodes

酷!所以我们在变量node.中有一个字符列表,总共有 276 个节点(字符)。现在让我们探索边缘。在‘ASOIAF_edges.csv’文件中,还有关于权重(交互次数)和图的种类(无向)的信息。但是因为我们只关心连接,所以我们使用前两列

edges = pd.read_csv('ASOIAF_edges.csv',usecols=[0,1] )
edges

总共有 683 个连接!哇哦。在整个系列中建立了许多联系。但是我们如何把这些数据做成图表呢?我们可以认为:

  • 每个字符作为一个顶点
  • 两个相连的顶点作为一条边

现在我们已经准备好可视化网络了!

用 Graphviz 可视化图形

Graphviz 是一个用于绘制图形的 Python 接口。要安装它,请运行

$ pip install graphviz

通过实例化一个新的Digraph对象来创建一个图

from graphviz import Digraphdot = Digraph(comment='VIP graph')

让我们想象前十个节点

nodes_G = []
for node in edges[:10]['Source']:
    if node not in nodes_G:
        nodes_G.append(node)
for node in edges[:10]['Target']:
    if node not in nodes_G:
        nodes_G.append(node)

向图中添加节点和边

dot = Digraph(comment='VIP graph')for i in range(len(nodes_G)):
    dot.node(nodes_G[i])for i in range(len(edges[:10])):
    edge = edges.iloc[i]
    dot.edge(edge['Source'], edge['Target'])

视觉化:

dot.render('VIP-graph_10.gv', view=True)

不错!我们可以在图表中清楚地看到角色之间的互动。但是把整个网络可视化怎么样?当然,我们可以这样做。但是我们应该预料到这个系列的 5 章中的角色网络将会是巨大的

dot = Digraph(comment='VIP graph')for i in range(num_nodes):
    dot.node(nodes[i])for i in range(len(edges)):
    edge = edges.iloc[i]
    dot.edge(edge['Source'], edge['Target'])dot.render('VIP-graph.gv', view=True)

表演时间到了!

在这里找到这张 Gif 图片

酷!有了图,我们可以有效地将网络形象化。但是我们能创建自己的图形类吗?

创建图表

首先创建顶点(节点)类。我们希望顶点类有什么属性和方法?嗯。添加连接(addNeighbor),知道当前节点与哪些节点连接(getConnections),找出节点名称(getId,连接强度如何(getWeight)

用图形的一些基本方法创建一个图形类:

结论

恭喜你!在本文中,您已经学*了什么是图,以及如何使用图来可视化社交网络。那么你能用这些知识做什么呢?也许查阅本文中的数据创作的人物图你很好奇去分析他们的关系

或者,如果你根本不是《权力的游戏》的粉丝,你可以分析你关心的其他社交网络的数据,如 Twitter、脸书,以分析你和你的朋友或粉丝之间的网络。你将练*使用图表以及理解你和你朋友的关系。你是直接认识他们还是通过与他人的联系认识他们的?这将是如此迷人的知道!

你可以在我的 Github 里找到这篇文章的代码。在我的笔记本上,我还讲述了如何用深度优先搜索遍历断开的节点,用广度优先搜索找到两个字符之间的距离

我喜欢写一些基本的数据科学概念,并尝试不同的算法和数据科学工具。你可以在 LinkedIn 和 Twitter 上与我联系。

如果你想查看我写的所有文章的代码,请点击这里。在 Medium 上关注我,了解我的最新数据科学文章,例如:

[## 凸包:包装数据的创新方法

如何利用包装算法实现数据可视化

towardsdatascience.com](/convex-hull-an-innovative-approach-to-gift-wrap-your-data-899992881efc) [## 如何用 Altair 创建交互式剧情

在 5 行简单的 Python 代码中利用您的数据分析

towardsdatascience.com](/how-to-create-interactive-and-elegant-plot-with-altair-8dd87a890f2a) [## 什么是卓越的图形以及如何创建它

作为一名数据科学家,了解如何制作重要的图表至关重要

towardsdatascience.com](/what-graphical-excellence-is-and-how-to-create-it-db02043e0b37) [## 当生活不给你喘息的机会,如何学*数据科学

我努力为数据科学贡献时间。但是发现新的策略使我能够提高我的学*速度和…

towardsdatascience.com](/how-to-learn-data-science-when-life-does-not-give-you-a-break-a26a6ea328fd)

如何在 Scala 中可视化 Spark 数据帧

原文:https://towardsdatascience.com/how-to-visualize-spark-dataframe-in-scala-b793265b6c6b?source=collection_archive---------26-----------------------

您只需要 Scala 的更好的可视化体验

Scala 中的数据可视化火花(作者)

数据集的可视化是探索数据并向最终用户提供有意义信息的一种令人信服的方式。借助 Spark DataFrame,大规模数据处理从未像当前堆栈那样自然。对于用 Python 写代码的人来说,有很多可视化选项可以选择;PySpark 工程师可能不关心数据可视化。然而,对于用 Scala 编写 Spark 的人来说,没有多少开源选项可用。

对于 Scala 数据框架可视化中的 Spark,如果你在谷歌上搜索“Spark In Scala data frame Visualization”,一个选项列表与供应商或商业解决方案密切相关。如果你正在使用数据块,函数display很方便。如果您使用的是 HDInsight Spark,则可以使用内置可视化功能。如果你正在使用 Zeppelin(开源),可视化按钮可以使它变得简单。但是,如果你没有上面提到的任何一个环境,还想使用 Jupyter Notebook 这样的开源,那么数据可视化在这里也不是不可能完成的任务。幸运的是,有定制的函数,库可以使这个过程变得简单。在这篇文章中,我们将只为 Scala 探索更好的可视化体验。

Jupyter 笔记本更好的“展示”体验

在 Spark 中,控制台中的一个简单可视化是 显示功能show 函数将 DataFrame 中的一些记录(默认为 20 行)显示为表格形式。 show 功能的默认行为是启用截断,如果长度超过 20 个字符,则不会显示值。通过这种方式,您可以让所有内容都显示正确。有时,您可能希望禁用截断以查看单元格中的更多内容。那么你的数据显示可能会很混乱,因为它不会排队,它变得难以阅读。

下面的例子中我们有一个名为extremely_long_str的列,我们故意设置它来观察单元格内扩展内容的行为。在这种情况下,show 函数的格式不会很好。

import spark.implicits._
val columns = Seq(“language”,”users_count”, “extremely_long_str”)val data = Seq((“Java”, “20000”,”Short Text”), (“Python”, “100000”,”Medium Text, Medium Text, Medium Text”), (“Scala”, “3000”,”Extremely Long Text, Extremely Long Text, Extremely Long Text, Extremely Long Text, Extremely Long Text,Extremely Long Text,Extremely Long Text, Extremely Long Text, Extremely Long Text, Extremely Long Text, Extremely Long Text, Extremely Long Text,Extremely Long Text,Extremely Long Text”))val rdd = spark.sparkContext.parallelize(data)
val df = spark.createDataFrame(rdd).toDF(columns:_*)df.show(false)

一旦您执行了下面的代码,它将显示下面几行。我们可以认识到一个超长的记录不适合一行。如果你有几百行,阅读起来会很困难,因为一个单元格内的上下文会分成多行。随着 turncate 的关闭,长上下文破坏了格式良好的 show 函数。你可能会注意到阅读起来很麻烦,如果你有像这样的多列布局,那就更麻烦了。

默认显示不截断(按作者)

在 Jupyter 笔记本中,修复对齐问题。我们可以应用 HTML 来显示内容,而不是使用 show 函数。HTML 在这里会灵活得多,它可以管理单元格合并,这样它在多行中会显示得更漂亮,这里的输出读起来更舒服。

showHTML()函数(作者)

要完成这项工作,你只需要安装一个 Jupyter 笔记本内核,名为杏仁(Jupyter 的一个 Scala 内核),并实现一个定制的功能。要在 Jupyter 笔记本中安装杏仁内核,可以按照的说明进行操作。

Aivean 为此在 Github 上发布了一个很有用的函数,一旦添加了 helper 函数,就可以调用df.showHTML(10, 300)函数,该函数生成一个包含 DataFrame 结果的 HTML 代码块 wrap,并显示十行,每个单元格 300 个字符。它现在在 Jupyter 笔记本上看起来好多了,如上图所示。要添加的函数如下所示:

// Credit to Aiveanimplicit class RichDF(val ds:DataFrame) {
    def showHTML(limit:Int = 20, truncate: Int = 20) = {
        import xml.Utility.escape
        val data = ds.take(limit)
        val header = ds.schema.fieldNames.toSeq        
        val rows: Seq[Seq[String]] = data.map { row =>
          row.toSeq.map { cell =>
            val str = cell match {
              case null => "null"
              case binary: Array[Byte] => binary.map("%02X".format(_)).mkString("[", " ", "]")
              case array: Array[_] => array.mkString("[", ", ", "]")
              case seq: Seq[_] => seq.mkString("[", ", ", "]")
              case _ => cell.toString
            }
            if (truncate > 0 && str.length > truncate) {
              // do not show ellipses for strings shorter than 4 characters.
              if (truncate < 4) str.substring(0, truncate)
              else str.substring(0, truncate - 3) + "..."
            } else {
              str
            }
          }: Seq[String]
        }publish.html(s""" <table>
                <tr>
                 ${header.map(h => s"<th>${escape(h)}</th>").mkString}
                </tr>
                ${rows.map { row =>
                  s"<tr>${row.map{c => s"<td>${escape(c)}</td>" }.mkString}</tr>"
                }.mkString}
            </table>
        """)        
    }
}

在 Scala-Vegas(VEGA+Scala)中制作漂亮的剧情

Vegas 是一个用于声明性统计数据可视化的 Scala API。它与 Scala 以及 Apache Spark 和 Apache Flink 等现代数据框架集成得很好。因为 Vegas 是声明性的,所以我们需要做的就是定义数据源并传递关于如何显示图表的参数,而不需要显式地写下更多的额外代码。

首先,您需要添加以下两个依赖项

import $ivy.`org.vegas-viz:vegas_2.11:0.3.11`
import $ivy.`org.vegas-viz:vegas-spark_2.11:0.3.11`

因为我们有一个之前定义的 Spark 数据帧,所以我们可以重用它。一旦定义了数据帧,剩下的就是将withDataFrame指向 Spark 数据帧,因此 Vegas 知道如何将 Spark 数据帧解析为数据源。为了美观地展示图表,您可能希望对 x 轴进行排序,否则绘图将按语言名称进行排序和显示,这是默认行为。

import vegas._
import vegas.render.WindowRenderer._
import vegas.sparkExt._Vegas(“Language Usage”)
 .withDataFrame(df)
 .mark(Bar) // Change to .mark(Area)
 .encodeX(“language”, Nom, sortField=Sort(“users_count”, AggOps.Mean))
 .encodeY(“users_count”, Quant)
 .show

拉斯维加斯酒吧阴谋(作者)

维加斯地区图(作者)

使用 Plotly 作为替代

Vegas 是一个非常好用的库,它可以与 Scala 和 Spark 无缝协作。虽然拉斯维加斯的情节看起来很酷,但你可能不仅仅局限于一个可视化选项。此外,您可能希望有一个更具交互性的图表模式。 Plotly 在这里可能是正确的选择。Plotly 是另一个出色的数据可视化框架,它已经在 Python 和 JavaScript 中得到了广泛应用。为了让 Plotly 与 Scala 和 Spark 一起工作,我们需要更多地重塑我们的数据,因为 Plotly 目前不直接支持 Spark 数据帧。

首先,你需要为 Jupyter 实验室安装 plotly-scala

jupyter labextension install @jupyterlab/plotly-extension

然后,您需要将 DataFrame 更改为 RDD 并收集,以强制将数据收集到驱动程序节点。为了避免向驱动程序接收太多的数据,在 Spark driver 上收集数据之前,您需要过滤或聚合接*最终结果的数据集,并且不要依赖可视化框架来执行数据转换。

val (x, y) = df.collect.map(r=>(r(0).toString, r(1).toString.toInt)).toList.unzip
Bar(x, y).plot()

Plotly 的一个更精致的特性是它的图表比 Vegas 创建的图表更具交互性。您可以悬停在条形图上并查看数据值,或者选择右上角的选项,如放大/缩小,以满足您的要求。

用 Scala 编程(作者)

最终想法

尽管 Scala 中有一些数据可视化选项,但仍然有可能构建令人印象深刻且富有创意的图表来通过数据交流信息。对于用 Scala 为 Spark 编写代码的人来说,通过额外的转换,我们仍然可以利用一些开源库来可视化 Scala 中的数据。希望这篇文章能介绍一些如何在 Scala 中可视化 Spark DataFrame 的思路,帮助你获得更好的 Scala 可视化体验。

希望这个故事对你有帮助。本文是我的工程&数据科学系列的部分,目前包括以下内容:

Chengzhi Zhao

赵承志

数据工程和数据科学故事

View list47 stories

你也可以 订阅我的新文章 或者成为 推荐媒介会员 可以无限制访问媒介上的所有故事。

如果有问题/评论,请不要犹豫,写下这个故事的评论或者通过 LinkedinTwitter 直接联系我

如何直观地解释任何基于 CNN 的模型

原文:https://towardsdatascience.com/how-to-visually-explain-any-cnn-based-models-80e0975ce57?source=collection_archive---------12-----------------------

理解并实现引导 Grad CAM,为任何基于 CNN 的模型直观地解释类别区分可视化

CNN 深度学*模型——它为什么解释它所解释的东西?

深度学*模型现在能够给出非常高的准确度。在图像分类、对象检测、语义分割、图像字幕或视觉问答中大规模采用计算机视觉算法的最关键部分是理解 CNN 模型为什么解释它们所解释的内容。

CNN 模型的可解释性或可解释性是建立信任和采用信任的关键

只有当我们理解了为什么模型不能识别一个类或一个对象时,我们才能集中精力解决模型的失败。更好的可解释或可解释的深度学*模型将帮助人类建立信任,并导致更高的采用率。

一个好的可解释或可理解的模型应该突出图像中的细粒度细节,以直观地解释为什么模型预测了一个类。

有几种方法可以解释 CNN 模型,比如

  • 导向反向传播 可视化图像中的精细细节。它的前提是:神经元就像特定图像特征的检测器,所以当反向传播时,梯度、负梯度被设置为零以突出图像中重要的像素。
  • 类别激活图(CAM)是类别鉴别的,它定位图像的类别或类别。CAM 要求要素地图直接位于预测图层之前。 CAM 因此适用于在预测层之前对卷积映射执行全局平均池的 CNN 架构,因此不适用于其他计算机视觉算法。
  • Grad CAM 可视化具有类区分性并定位相关图像区域,但不会像导向反向传播一样突出精细像素的重要性;然而,与 CAM 不同的是, Grad CAM 适用于任何 CNN 架构。

引导式 Grad CAM 结合了 Grad CAM 和引导式反向传播的优点,Grad CAM 具有类别区分能力,可定位相关图像区域,而引导式反向传播可将负梯度设置为零的图像的梯度可视化,从而在通过 ReLU 层反向传播时突出显示图像中的导入像素。

由作者生成的代码:比较不同的技术来解释 CNN

导向梯度加权类激活图(导向梯度凸轮)具有类区分性,并突出显示图像的细粒度重要区域,用于任何 CNN 架构的高分辨率预测。

制导 Grad CAM 高级工作

图像通过 CNN 网络前向传播,生成特征图,然后应用特定于任务的网络来获得类别的分数。

不同类型的任务可以是图像分类、图像字幕、物体检测、视觉问答等。

所需类别的梯度设置为 1,所有其他类别的梯度设置为零。这样做是为了获得类别区分定位图。

关于激活的梯度被反向传播,直到最后的卷积层;这抓住了重要的特征。前向激活图和反向传播梯度的加权组合后跟随一个 ReLU,以获得梯度凸轮定位(蓝色热图),该定位解释了模型为做出特定决策而查看的特征。

应用引导反向传播来计算梯度,然后将负梯度和反向传播归零。

最后一步,将 Grad CAM 热图与导向反向传播进行逐点相乘,以获得导向 Grad-CAM 可视化这些可视化现在具有类别区分性,并以高分辨率定位相关图像区域。

梯度凸轮、导向反向传播和导向梯度凸轮在 TensorFlow 中的实现

在下面的代码中,我们将通过 VGG19 模型的 Conv 层向前传播图像。

非负梯度被反向传播到感兴趣的校正卷积特征图。然后,将这些梯度组合起来计算粗略的 Grad-CAM 定位,表示图像中的特征,模型在图像中寻找这些特征以做出特定的决定。

最后,我们应用梯度 CAM 热图与引导反向传播的逐点乘法来获得引导梯度 CAM 可视化,其既是高分辨率的又是概念特定的或类别判别式的。

# Import the required libraraies
**import cv2
import tensorflow as tf
import tensorflow.keras.backend as K
import numpy as np
from skimage.transform import resize
import matplotlib.pyplot as plt
%matplotlib inline**#Setting the image apth and the last conv layer for VGG19
**IMAGE_PATH = 'cat_and_dog1.jpg'
LAYER_NAME='block5_conv4'**#Load the image
**img = tf.keras.preprocessing.image.load_img(IMAGE_PATH, target_size=(224, 224))**# Displaying the original image
**plt.axis("off")
plt.imshow(img)
plt.show()** # Preprocess the image using vgg19 preprocess function
**img =  tf.keras.preprocessing.image.img_to_array(img)
x = np.expand_dims(img, axis=0)
preprocessed_input = tf.keras.applications.vgg19.preprocess_input(x)**

原象

我们在 Imagenet 数据集上使用 VGG19 迁移学*模型。

#Create the transfer learned model
**model = tf.keras.applications.vgg19.VGG19(weights='imagenet', include_top=True)**

我们从 VGG19 传输学*模型直到最后一个卷积层创建一个模型。Conv 层保留了当我们在深度学* CNN 模型中应用全连接层时丢失的空间信息。

'''create a model till  last convolutional layers to have the best compromise between high-level semantics and detailed spatial
information'''
**gb_model = tf.keras.models.Model(
    inputs = [model.inputs],    
    outputs = [model.get_layer(LAYER_NAME).output]
)**
**layer_dict = [layer for layer in gb_model.layers[1:] if hasattr(layer,'activation')]**

通过应用 @tf 覆盖 ReLU 的渐变。custom_gradient 允许对梯度进行细粒度控制,以便反向传播非负梯度,从而获得更有效或数值稳定的梯度。

[**@tf**](http://twitter.com/tf)**.custom_gradient
def guidedRelu(x):
  def grad(dy):
    return tf.cast(dy>0,"float32") * tf.cast(x>0, "float32") * dy
  return tf.nn.relu(x), grad**

将引导式 ReLU 应用于所有重新激活的 Conv 图层

**for layer in layer_dict:
  if layer.activation == tf.keras.activations.relu:
    layer.activation = guidedRelu**

使用梯度带记录前向传递的预处理输入图像,这将有助于计算后向传递的梯度。使用 GradientTape 对象捕捉最后一个 Conv 图层上的渐变。

这里,我们找到了目标类分数相对于最后一个卷积层的特征图的梯度

**with tf.GradientTape() as tape:
 inputs = tf.cast(preprocessed_input, tf.float32)
 tape.watch(inputs)
 outputs = gb_model(inputs)[0]****grads = tape.gradient(outputs,inputs)[0]**

Grad 分类激活图(Grad CAM)

对梯度进行空间平均,其中每个条目是特定要素地图通道上梯度的平均强度。根据梯度重要性建立一个有权重的过滤器图。结果是最终的类别区分显著图。

**weights = tf.reduce_mean(grads, axis=(0, 1))
grad_cam = np.ones(outputs.shape[0: 2], dtype = np.float32)
for i, w in enumerate(weights):
    grad_cam += w * outputs[:, :, i]**

用最大强度值
除热图的每个强度值,以标准化热图,使所有值落在 0 和 1 之间,并在图像上绘制渐变类别激活图

**grad_cam_img = cv2.resize(grad_cam.numpy(), (224, 224))
grad_cam_img = np.maximum(grad_cam_img, 0)
heatmap = (grad_cam_img - grad_cam_img.min()) / (grad_cam_img.max() - grad_cam_img.min())****grad_cam_img = cv2.applyColorMap(np.uint8(255*heatmap), cv2.COLORMAP_JET)****output_image = cv2.addWeighted(cv2.cvtColor(img.astype('uint8'), cv2.COLOR_RGB2BGR), 0.5, grad_cam_img, 1, 0)** **plt.imshow(output_image)
plt.axis("off");
plt.show()**

Grad CAM

导向反向传播

使用引导反向传播来捕捉神经元检测到的像素,而不是抑制神经元的像素。导向反向传播计算目标输出相对于输入的梯度,其中负梯度在通过 ReLU 层反向传播时被抑制

#Visualizing the guided back prop
**guided_back_prop =grads****gb_viz = np.dstack((
            guided_back_prop[:, :, 0],
            guided_back_prop[:, :, 1],
            guided_back_prop[:, :, 2],
        ))       
gb_viz -= np.min(gb_viz)
gb_viz /= gb_viz.max()

imgplot = plt.imshow(gb_viz)
plt.axis("off")
plt.show()**

导向反向传播

导向梯度类激活图(导向梯度凸轮)

导向梯度 CAM 通过逐元素乘法结合了梯度 CAM 和导向反向传播的最佳方面。制导 Grad CAM 的可视化既具有高分辨率,又具有类别区分能力

**guided_cam = np.maximum(grad_cam, 0)
guided_cam = guided_cam / np.max(guided_cam) # scale 0 to 1.0
guided_cam = resize(guided_cam, (224,224), preserve_range=True)**#pointwise multiplcation of guided backprop and grad CAM **
gd_gb = np.dstack((
        guided_back_prop[:, :, 0] * guided_cam,
        guided_back_prop[:, :, 1] * guided_cam,
        guided_back_prop[:, :, 2] * guided_cam,
    ))****imgplot = plt.imshow(gd_gb)
plt.axis("off")
plt.show()**

制导 Grad CAM

可视化突出显示了耳朵、鼻子、狗的身体和它的爪子的像素,模型看起来要对狗和猫的特征进行预测,但没有突出显示。

结论:

制导 Grad CAM 具有类别识别能力,在突出显示精细像素细节的同时定位相关图像区域。使用引导 Grad CAM 的可视化有助于解释 CNN 模型在进行预测时看什么,从而解释为什么模型解释它所解释的内容,从而明确建立对深度学*模型的信任。

参考资料:

Grad-CAM:通过基于梯度的定位来自深度网络的视觉解释

https://www . si cara . ai/blog/2019-08-28-可解释性-深度学*-tensorflow

如何在酒吧琐事的最后一题下注

原文:https://towardsdatascience.com/how-to-wager-at-the-final-questions-in-bar-trivia-594a1d746bb2?source=collection_archive---------34-----------------------

什么时候下大注,什么时候下小注

乔治·巴科斯在 Unsplash 上的图片

几周前,我和我的朋友在镇上我们最喜欢的酒吧玩酒吧琐事。对于那些不知道的人来说,酒吧琐事是一种比赛,团队试图回答越来越难的琐事问题以获得分数。最后得分最多的队获胜。在游戏的最后一个问题中,各队在听到问题后可以下注 2、4、6、8 或 10 分。如果他们答对了,他们会把他们下注的点数加到他们的分数上。如果他们做错了,他们会损失一半。

到了最后一题,我和朋友们落后第一名队伍 5 分。我想我们已经想出了正确的答案,所以我想赌最多 10 分,但我的队友想更谨慎,而不是赌 8 分。第一名的队伍和我们正确地回答了问题,但是因为第一名的队伍下注 4 分,我们以一分之差结束了比赛!我突然想到,如果我们赌 10 分,我们就会赢一分。我想知道是否有一种方法可以证明下注 10 点是我们这种情况下的最佳赌注。

在这篇文章中,我将推导出一个酒吧琐事团队的最佳赌注,条件是他们与第一名团队之间的积分差异。在这个过程中,我们还会看到第一名队伍的最佳赌注是什么。在这个分析中,我将最优赌注定义为最大化团队获胜机会的赌注。我假设所有的团队都试图最大化这个概率。领先的团队是团队 2,假设他们答对问题的概率是 p2。另一个团队是团队 1,假设他们答对问题的概率是 p1。

有 5 种情况需要考虑,让我们开始吧!

第一组:第二组领先了 5-11 分

对于两个团队可以进行的每种下注组合,我已经计算了团队 1 获胜的概率,并且我已经在之前的表格中列出了它们。我应该说,这个特定的表格是针对第二组正好领先五个点的情况,但是我们在这种情况下得出的最优策略对于 6-11 的值是相同的。

例如,假设第二队在最后一个问题中下注 2 分。如果团队 1 下注 6 分,如果他们答对了问题而团队答错了,他们就能赢。这以概率 p1 * (1 — p2)发生。这解释了左上角表格第三行中的条目。如果团队 1 下注 8 分,如果他们答对了,团队 2 答错了,或者两个团队都答对了,他们就能赢。这意味着获胜的总概率是 p1 * (1-p2) + p1 * p2 = p1。

查看表格,我们可以看到,无论团队 2 下注多少,团队 1 都通过下注 10 分来最大化他们的获胜概率。相反,团队 2 通过下注 6、8 或 10 分来最大化他们获胜的机会。

策略:第一队要赌 10 分。如果两个队都答对了,第二队应该下注第二队获胜所需的最少点数。在领先 5 个百分点的情况下,这将是 6 个百分点。

案例 2:第二队领先 4 分

在这种情况下,我重新计算了概率,并以与前一种情况相同的表格格式展示出来。与前一种情况类似,P1 *(1–p2)的值意味着团队 1 如果做对了就赢,团队 2 做错了就赢。p1 值意味着如果团队 1 答对了,团队 2 答错了,或者两个团队都答对了,那么团队 1 就赢了。我想解释一下(1–p2)的值,我们在前面的例子中没有看到。这对应于团队 1 做对的概率和团队 2 做错的概率以及两个团队都做错的概率:p1 * (1-p2) + (1-p1) * (1-p2) = (1-p2)。

策略:在这种情况下没有优势策略。除了团队 2 下注 10 分之外,团队 1 在所有情况下都下注 10 分,以最大化他们获胜的机会。然而,当团队 2 下注 10 时下注 10 是次优的,仅仅因为团队 1 在他们弄错问题的情况下不能赢。如果第一组认为它能答对这个问题,它可能会下 10 英镑的赌注。

案例 3:第二队领先 3 分

就像案例 2 一样,这种情况有点棘手,因为团队 1 没有单一的策略可以用来最大化他们的获胜机会。如果团队 2 下注 2、4 或 6 分,那么团队 1 总是通过下注 10 分来最大化他们的机会。如果团队 2 下注 8 或 10 点,团队 1 总是通过下注 2 点来最大化他们的机会。

显然,团队 1 不能查看团队 2 的赌注,因此这不是一个可以在实践中使用的策略。也就是说,我认为团队 1 可以使用一个经验法则来提出一个好的赌注。这里的关键是要认识到,无论如何,如果团队 1 做对了,团队 2 做错了,团队 1 就会赢。换句话说,表格中的每个单元格都有 p1 * (1-p2)值。只是值为 p1 的单元格中多了一个 p1 * p2 项。带有(1-p2)的单元格中有一个额外的(1-p1) * (1-p2)项。

策略:团队 1 需要评估 p1 是否> (1-p1),即他们是否更有可能答对问题。如果他们认为他们能答对这个问题,他们应该下注 10 分,因为这样可以通过答对这个问题最大化他们获胜的机会。如果他们认为他们会错,他们应该赌 2 分。同样的经验法则也适用于团队 2。

案例 4:第二队领先 2 分

与前一种情况类似,对于团队 1 来说,不存在对团队 2 的所有下注都是最优的策略。我们可以看到,如果 p1 > (1-p2),那么下注 10 点对于所有情况都是最优的,除了当团队 2 下注 10 点时。如果(1-p2) > p1,那么下注 2 点对于所有情况都是最佳的,除了当团队 2 下注 2 或 4 时。由于团队 1 不知道 p2 或团队 2 的赌注,这不是一个可以在实践中使用的策略。然而,他们可以用 p1 的值来*似 p2 的值——毕竟,团队非常接*,所以他们有相似的琐事知识。通过这样做,我们恢复了与前一个案例相同的经验法则。

策略:如果 p1 > (1-p1),他们应该赌 10 点。否则,他们应该赌 2 分。同样的经验法则也适用于团队 2。

案例 5:第二队领先 1 分

策略:这种情况和“涨 2”的情况非常相似。如果 p1 > (1-p1),他们应该赌 10 点。否则,他们应该赌 2 分。同样的经验法则也适用于团队 2。

外卖食品

我认为最重要的一点是,你几乎应该总是下注最少或最多的点数。唯一不应该的情况是当你的球队领先至少 4 分的时候。当第一队仅领先 3 分或更少时,我们看到不可能为另一队所有可能的赌注提出一个占优势的策略。在这种情况下,团队应该评估他们是否有可能答对问题。如果是这样,他们应该下注最大点数。如果没有,它们应该是最小值。

这个结论表明,我的团队应该在几周前我们落后 5 分的时候下注 10 分。我迫不及待地想向我的团队展示这一点,并提高我们未来的机会!

如何在 8 分钟内完成网页抓取

原文:https://towardsdatascience.com/how-to-web-scrape-in-8-minutes-4a100a672397?source=collection_archive---------9-----------------------

我将向你展示如何在 8 分钟内成为一名 Python 网页抓取者

克里斯托弗·高尔摄于 Unsplash

你知道你现在读的是什么数据吗?对你来说,这可能只是几个词,但在后端,你在网上读到的一切都是可以被提取、分离和操作的数据。这就是 Web Scraper,我将向你展示如何在 8 分钟内成为一名 Web Scraper。

世界计量仪

Wordometers 是一个提供生活世界统计数据的网站,也是我们要刮的网站。具体来说,我们将收集表格中的世界人口数据(如下所示)。从表格中抓取数据是最常用的网络抓取形式之一,因为通常我们在表格中需要的数据是不可下载的。因此,我们让计算机在几秒钟内完成,而不是手动获取数据。

美味的汤

我知道这是一个奇怪的名字,但 Beautiful Soup 是最强大的网络抓取库之一,在我看来也是最容易学*的,这就是为什么我们要使用它。但是首先我们必须安装它。

要在您的计算机上安装 Beautiful Soup,请进入您的 Anaconda 控制台(只需在任务栏中搜索),并分别键入每一行代码。

pip install beautifulsoup4 
pip install lxml
pip install requests

如果事情最终出错了,这里有一个文档的链接,它会告诉你问题是什么以及如何解决:美汤文档

Python 代码

现在我们已经完成了设置,我们终于可以开始编写代码来清理表格了。

我们首先导入刚刚安装的库和其他一些需要的库。

import requests
from bs4 import BeautifulSoup
import pandas as pd

然后,我们希望获得我们正在抓取数据的网站,为此,我们使用一个名为 requests.get() 的函数,当输入一个 url 时,我们就可以访问网站上的数据。

url = 'https://www.worldometers.info/world-population/'
requests.get(url)
page = requests.get(url)

要查看请求是否成功,在使用适当的 url 运行代码后,应该会弹出这个窗口。

Response [200]

相反,如果它说响应[404],这意味着它不能给你访问该网站,你不能抓取数据。

现在我们已经可以访问网站的数据,我们实际上必须去获取数据。为了做到这一点,我们使用了一个解析器,它将遍历网站的 HTML 代码,并给出网站上的所有数据。

解析器将抓取与网站上看到的所有数据相对应的后端数据

突出显示的蓝线是与网站上看到的人口文本相对应的 HTML 代码

这是我们将使用 Beautiful Soup 的地方,因为我们将使用它的“lxml”解析器。

soup = BeautifulSoup(page.text, 'lxml')

这个 soup 变量现在拥有了来自网站的所有数据。如果你输入 print(soup) 就可以看到这一点,因为会弹出这样的行。

目前我们在网站上有所有的数据,只是 HTML 格式的。所以现在我们必须分离 HTML 来得到我们想要的数据,也就是表中的数据。

超文本标记语言

要理解代码的下一部分,你必须对 HTML 格式有一个简单的了解。

HTML 使用标签来保存信息并确定它在站点上的位置。

例如,顶部的紫色文本表示 table 是一个标记,它下面的所有内容都是包含表内数据的其他标记。

要真正看到哪段 HTML 代码对应于页面上的一段特定数据,一个技巧是在站点的任何地方单击鼠标右键,然后按 inspect。

这将打开网站的 HTML,在右边可以看到。

这项功能只在谷歌浏览器中有效,但是在弹出的 HTML 框的左上角有一个类似这样的图标。

当图标被按下时,你可以点击网站上的任何一条信息,与该条信息相对应的 HTML 将以蓝色突出显示,如下所示。

返回代码

现在我们对 HTML 格式有了一个简单的了解,我们将使用它来获取表中的标签。我们通过使用一个名为 find()的函数来做到这一点。 Find 将遍历 HTML,只返回您想要查找的 HTML。不言自明。

看上面的照片,我们看到我们想要的表对应于那个表标签和那个唯一的类名(每个表都有一个唯一的类名以区别于其他表)。为了获得 HTML 和表中的数据,我们编写…

table_data = soup.find('table', class_ = 'table table-striped table-bordered table-hover table-condensed table-list')

我们使用 soup.find,因为如果你还记得我们在 soup 变量中从站点中获取的所有 HTML。

现在,我们只有我们想要的 HTML 和数据,我们可以开始获取数据,并把它放在一个漂亮干净的数据框架中,类似于网站上的那个。

头球

首先,我们将编写一段代码来获取表格的列标题。这些标题有一个标签“th ”,你可以通过点击左上角的小图标看到它,就像我上面展示的那样,然后点击任何一个标题。

因为所有的头都有相同的标签,我们将遍历每个头,并把它添加到一个列表中。为此,我们将使用 find_all() 函数。就像 find()函数一样,它会找到你要找的东西,但现在它会返回它的所有情况。

这段代码看起来像这样…

headers = []
for i in table_data.find_all('th'):
    title = i.text
    headers.append(title)

headers 变量首先是一个空列表,我们将把它添加到。下一行是一个 for 循环,它将遍历所有带有“th”标签的数据。在这种情况下,只有标题具有“th”标签。这段数据将存储在 I 变量中,我们使用 i.text 将头转换成 python 中的字符串。最后,我们将标题添加到标题列表中。

最后,我们有了所有标题的列表,我们将开始通过编写来创建数据帧

df = pd.DataFrame(columns = headers)

这将创建一个空的 dataframe,用我们的标题列表作为列名。

身体

最后一步是获取表体。用于此目的的代码类似于获取头的代码。表格中的每一行对应一个“tr”标签。我们将再次使用 find_all()函数来获取表中所有的“tr”标记和行。这里的区别是我们将再次使用 find_all()函数。这是因为我们不能一次抓取整行。在“tr”标记内是“td”标记,它们实际上对应于行中的特定数据。这是我们需要得到的。

因此,我们将在“td”标签上使用 find_all()函数来获取一行中的所有数据。

for j in table_data.find_all('tr'):
        row_data = j.find_all('td')

现在我们已经有了行中的数据,我们只需要把它放入一个列表中,下面的行将为我们完成这项工作。

row = [tr.text for tr in row_data]

最后,我们只需将行添加到数据帧中,就完成了。

length = len(df)
df.loc[length] = row

最后,我们创建了一个与网站上的表格完全相同的表格。

站点表:

Web 抓取的表格:

最终代码:

Python A-Z Bootcamp 2023 中的网页抓取

如果你觉得这篇文章很有用,并且对学*网页抓取感兴趣,我有一个课程教你如何从完全的初学者到高级的网页抓取者,课程教你一步一步如何用它赚钱。

请点击下面的链接查看!

[## Python 课程中的网络抓取

介绍你准备好学*当今就业市场最受欢迎的技术技能之一了吗?这个 15 小时的训练营…

christopher-zita-24ef.mykajabi.com](https://christopher-zita-24ef.mykajabi.com/web-scraping-in-python-course)

如何赢得黑客马拉松 Tensorflow Lite 中的实时移动野火检测。

原文:https://towardsdatascience.com/how-to-win-a-hackathon-real-time-mobile-wildfire-detection-in-tensorflow-lite-b0ee838a4c18?source=collection_archive---------22-----------------------

深度学*的好处。

介绍

自 2010 年以来,黑客马拉松作为编码社区中的一种文化现象,已经获得了越来越多的关注。除了学生主导的活动,脸书、谷歌和微软等行业领袖都认识到了这类活动的效用,赞助或举办了自己的黑客马拉松。黑客马拉松将密集的编码和演示项目与除臭剂、零食和睡袋组成的网络相结合,为学生提供了在高度紧张的条件下评估他们解决方案构建能力的绝佳机会。

你甚至会学到处理压力的新方法。

从本质上来说,黑客马拉松是发展一家初创公司的流水线过程的一个缩影:你自己做研究,建立 MVP,并在长达 48 小时的过程中向观众进行推介。你会经历一些情绪波动,睡眠不足,但会学到很多在压力、逆境下工作的能力,以及实现想法的能力。特别是,这种挑战的团队导向是对一个人团队合作能力的有效测试:事实上,虽然专业黑客马拉松“团队”很常见,但学*与新队友合作是对企业工程环境的更现实的模拟。

但是考虑到黑客马拉松中可能有大量的团队,我们如何脱颖而出并创建一个获奖的参赛项目呢?当然,总有运气的成分在里面,但是我们确实可以控制一些关键的方面:

  • 新颖性 —你的解决方案的独创性水平。以前做过一千次吗?请注意,新颖性同样适用于应用程序和方法——在新的应用程序领域中经过实践检验的方法仍然可以是原创的解决方案。
  • 特异性 —您的解决方案如何应对挑战陈述?例如,喷水的人工智能机器人可能不是解决投资银行问题的最佳方案。
  • 执行——你的解决方案交付得如何?这包括演示以及演示和投球方面,后两者通常在较短的比赛中更为重要。记住,执行得好的坏主意总是胜过执行得不好的好主意。

为了在实践中说明这些观点,我们将回顾我们的获奖作品,即 48 小时新加坡 2018 年美国宇航局太空应用挑战赛的环境主题——Sammuta,一种野火管理的多模式早期检测解决方案。

请注意,由于我们之前已经在 GradientCrescent 的一篇独立文章中介绍过投球和演示,我们在这里不会花太多时间。我们也不会讨论团队建设和其他人际交往技巧,而是将本文的重点放在解决方案本身。

用于早期野火检测的深度学*

在过去的一年里,澳大利亚 T4 的野火吸引了全世界的关注。超过 1500 万英亩的土地被烧焦,超过 100 种物种现在恐怕已经灭绝,这一事件悲惨地提醒人们人为气候变化的影响。

虽然本季火灾的确切原因仍有争议,但气候变化导致野火发生率加快,气温升高和大量干燥易燃物导致火药桶点火。加利福尼亚州是众所周知的野火中心,现在已经超越了“火灾季节”,成为一种全年现象,以前安全的地区,如瑞典,现在也开始出现野火。从 2017 年到 2018 年,已有超过 2330 亿美元用于野火相关活动。这些都是你应该在演讲中利用的事实,因为用情感背景来框定问题是让听众理解你的信息的关键。 这在我们之前关于投球的文章中已经详细讨论过了。

萨姆塔的开场幻灯片

我们对此问题的解决方案包括一个早期多模式野火检测模型,该模型包含三个关键部分:

  • 具有传输能力的廉价传感器网格充当粗略的热探测图。
  • 一种可编程的空中无人驾驶飞机,最小提升能力为 2 公斤,航程足以到达网格空间的任何一点。
  • 基于视觉的反应灵敏的野火探测系统。

这直观地呈现在下面:

所有这些组件都可以从市场上购买,从而形成一个经济高效、可快速实施的解决方案。通过为每个社区使用一次性、坚固、廉价的检测地图,我们可以确保有效覆盖,同时保持经济和节能。对空中观察无人机进行编程,使其飞向跳闸传感器的特定坐标是很容易的,之前已经为搜索和救援服务 s 进行了演示。

然而,为了竞赛的目的,缩小有效演示组件的范围是很重要的。我们认为基于视觉的移动检测系统是最可行、最引人注目的解决方案。鉴于黑客马拉松的时间和资源限制,任何解决方案都必须满足以下标准:

  • 计算量小且响应迅速
  • 在一系列模拟野火上的高准确度(> 80%)
  • 易于实施,最好在 12 小时内。
  • 易于培训,便于维护和更新
  • 未来更新可能的在线学*兼容性

为了满足这些要求,我们决定利用迁移学*和 Tensorflow Lite 为 Android 设备训练一个实时移动 wildfire 分类器。

实施

我们最终针对 Android 设备的 Tensorflow Lite 实现,以及训练所需的 Python 脚本,可以在GradientCrescent 资源库 中找到。 您需要将 Tensorflow (1.9 或更高版本)与 TOCO 转换器一起安装到您的工作空间中,以尝试重新训练过程。您还需要 Android Studio 来编译和构建最终版本。apk 文件,尽管我们在存储库中提供了一个副本。

Tensorflow Lite 是一种压缩技术,旨在将标准 Tensorflow 图形模型改编为轻量级、高响应的包,适合在轻量级上实现快速性能。这些应用包括适合半一次性应用的低端移动设备。它允许使用量化转换技术,其中模型的参数可以转换为 8 位格式,显示出在减少模型大小的同时改善了延迟。在推断时,这种数据被重新转换回其原始格式,从而对分类准确性产生最小的影响。

我们已经在之前的文章的中讨论过迁移学*。本质上,迁移学*是指在新的数据集上对预先训练好的神经网络进行微调。这里的原则是旧类和新数据类中的特性是共享的,因此可以应用于新的目标类。虽然使用 Tensorflow 库重新训练预训练的 MobileNetV1 网络是一个简单的过程,我们可以通过脚本直接从终端执行迁移学*。

首先,我们定义了一些类,以便进行再训练过程。出于演示的目的,我们进行了 Google 图片搜索,获得了大约 250 张关于野火、森林和三明治的图片(毕竟幽默不会伤害任何提交的图片)。我们的再训练脚本可以在脚本 "retrain.py ",由官方 Tensorflow 资源库修改而来。这个脚本可以从终端调用,对于初学者来说非常友好,因为不需要额外的脚本。

我们的最终模型采用了预训练的 MobileNetV1 架构,用于 224 x 224 分辨率的输入图像,具有 75%的量化。在此之前,我们对各种架构进行了广泛的测试,以便在毫秒级响应时间和分类准确性之间取得平衡。通常,体系结构越复杂,量化级别越低,模型的执行速度就越慢。

然后,我们用终端命令调用我们的再训练脚本,指定训练时间、特定的预训练模型架构、预处理参数以及我们的输入和输出目录:

python retrain.py --image_dir=C:\tensorflow_work\Firepics --output_graph=retrained_graph.pb --output_labels=retrained_labels.txt --bottleneck_dir=bottlenecks --learning_rate=0.0005 --testing_percentage=10 --validation_percentage=10 --train_batch_size=32 --validation_batch_size=-1 --flip_left_right True --random_scale=30 --random_brightness=30 --eval_step_interval=100 --how_many_training_steps=4000 --tfhub_module [https://tfhub.dev/google/imagenet/mobilenet_v1_075_224/quantops/feature_vector/1](https://tfhub.dev/google/imagenet/mobilenet_v1_075_224/quantops/feature_vector/1)

我们这里的重新训练模型是重新训练的图形输出,但是这还不是 Android 兼容的 Tensorflow Lite。tflite)文件。为了便于转换,我们必须首先使用 "freeze.py" 脚本冻结我们的图形文件,然后利用 TOCO 转换器通过另一个终端命令转换我们的文件:

python freeze_graph.py — input_graph=retrained_graph.pb — input_checkpoint=mobilenet_v1_0.5_224.ckpt.data-00000-of-00001 — input_binary=true — output_graph=/tmp/frozen_retrained_graph.pb — output_node_names=MobileNetV1/Predictions/Reshape_1tflite_convert — output_file=retrainedlite.tflite — graph_def_file=retrained_graph.pb — inference_type=QUANTIZED_UINT8 — input_arrays=input — output_arrays=MobilenetV1/Predictions/Reshape_1 \ — mean_values=224 — std_dev_values=127

转换完成后,我们将模型转移到 Android studio 中的 Android 平台。为了节省时间,我们在 Tensorflow 存储库中可用的演示应用程序的基础上构建了我们的解决方案。请注意,对应用程序、Android Studio 或 Java 的所有元素的解释超出了本教程的范围——我们将专注于构建我们的演示功能。

在一个简单的过程中,我们移动我们的 Tensorflow Lite 解决方案,包括标签和。tflite 模型文件,放入 Android Studio 项目中的“assets”资源目录。

最终模型,与标签和旧模型一起位于资产资源文件夹中。

然后,我们在 java 文件中指定模型和标签的名称。

@Override
protectedString getModelPath() {
  *// you can download this file from
  // https://storage.googleapis.com/download.tensorflow.org/models/tflite/mobilenet_v1_224_android_quant_2017_11_08.zip* return "retrained_graph.tflite";
}

@Override
protected String getLabelPath() {
  return "retrained_labels.txt";
}

然后,我们通过修改 camerafragment.xml 布局文件为我们的应用程序构建了一个新的外观布局:

最后,我们可以为我们的分类器创建一个阈值,我们在这里使用它来启动可视化祝酒词,但也可以用于最终产品中的通信应用程序。

public void splitCheck(String entry){
  String components[]  =entry.split(":");
  String mostlikely = components[0];
  String mostlikelyprob = components[1];
  resultString = mostlikely;
  resultProb = mostlikelyprob.substring(3,5);
  *//TODO managed to implement check every x seconds, DONE. Only choose the last two numbers, cast as int* if (Integer.*parseInt*(resultProb)>=65){
    match = mostlikely+ " detected";
    itemForCount = mostlikely;

  }else{
    match = "No match";
  }

然后,我们可以编译我们的解决方案并构建我们的。apk 文件,并将其传输到我们的 Android 设备上。

这是我们最终解决方案的现场演示。

凭借我们的演示和幻灯片,我们能够与一个由不同背景的陌生人组成的团队一起,经过大约 12 个小时的工作,在 NASA SpaceApps 挑战赛上获得第一名。您可以在下面观看我们的全球总决赛演示视频:

这就把这一小段总结成了 Tensorflow Lite。在我们的下一篇文章中,我们将通过展示强化学*在一个厄运健身房环境中的效用,来重新探索强化学*。

我们希望你喜欢这篇文章,也希望你看看其他许多涵盖人工智能应用和理论方面的文章。为了保持对 GradientCrescent 的最新更新,请考虑关注该出版物并关注我们的 Github 资源库。

如何在家工作—开发者版

原文:https://towardsdatascience.com/how-to-work-from-home-developers-edition-5bb4078cc6a3?source=collection_archive---------17-----------------------

面向开发人员的 5 种远程工作效率技巧

根据你所在的位置,在过去的几周/几个月里,政府建议/实施远程工作政策,试图减缓新冠肺炎的传播。虽然开发人员有一个在家工作的独特优势(WFH),因为远程工作是任何软件工程职位的额外津贴之一,但没有人预料到如此突然的疫情驱动的转变。加上拥挤的房子、即兴的家庭学校、各种干扰和相互竞争的要求,每个人都在努力提高效率,人们并没有像他们认为的那样做好准备。

对于许多技术专业人士来说,以前偶尔去 WFH 的奢侈已经变成了一种不确定性:

—这种情况会持续多久?
——我们要花多少时间、精力和金钱来建立一个永久性的家庭办公室?
—我们如何保持工作效率,尤其是在不得不应对社会剧变的时候?
——有限的办公室见面时间将如何影响我们的职业生涯?

是我们都会问的一些问题。

我将这些作为 WFH 开发人员多年来学到的 5 个关键策略以及任何开发人员的工具箱中都应该有的一系列生产力工具放在一起,以帮助您轻松过渡到远程工作,并在这些困难时期茁壮成长!

礼貌: Instagram

➊:明智地选择你的办公室

这是你经常读到的,你应该努力争取的是一个独立的办公室(不受外界干扰),有大的桌面空间,可调节的皮椅,巨大的高清显示器,充足的自然光,有符合你个性风格的氛围。现实检查:

除非你住在豪宅里,否则这是不可能发生的!

但是,您仍然可以在设计家庭办公室时考虑提高工作效率和目标。

指定工作区

如果可能的话,尽量远离交通繁忙的生活区,在家里找一个安静的地方。不管你是住在一室公寓还是五居室的房子里——你的家不是为你的工作而建的,所以只要你创造了一个适合你的空间,它就是完美的!自从搬到东京后,我不得不放弃我时尚的家庭办公室,不得不求助于我们卧室的一个角落来摆放我的新桌子。然而,这感觉和我们公寓的其他地方不一样,当我关上门时,我的丈夫和 4 岁的女儿知道我不能被打扰。

这里要记住的一个重要方面是工作与生活的分离:我应对这一挑战的方法是只在工作时间使用我的办公桌——尽管我承认工作时间比我应该工作的时间长,但当我完成一天的工作时,我真的完成了!

“显示器-键盘-鼠标”三合一

如果你在笔记本电脑上工作,一定要有一个外接显示器,这样你就有了一个更大的屏幕(或者使用你的电视)。不用再眯着眼睛,笔记本电脑显示屏可以变成第二个屏幕,专门用来显示电子邮件、Slack 或吉拉,让您专注于完成工作。防眩光屏幕可以大大提高您的满意度,结合外部键盘和鼠标,您的新办公室设置可以真正接*模拟实际的桌面计算机体验。

人类工程学

用一把你可以一天坐 8 个多小时的椅子,让你的工作空间变得舒适。我只能说,我应该早 10 年做这件事!!!相信我,当你总是紧张地看着你的电脑屏幕或者揉着你疼痛的背时,成为一个专注且高效的开发人员真的很难。如果你不能及时得到一个,你可以考虑使用一个腰部支撑枕头,作为一个快速解决办法。

永远不要忽视你的姿势——当你看着你的电脑时,你的眼睛应该几乎与屏幕的顶部保持水平。如果显示器太低,你最终会伸长脖子或弯腰驼背。你也希望显示器离你的椅子有一臂之遥。

📌 **Pro Tips**:
⟶ Get control of your posture with [**this gadget**](https://www.uprightpose.com/en-gb/);
⟶ If your eyes suffer, [**f.lux**](https://justgetflux.com) makes the colour of your computer's display adapt to the time of day: warm at night and like sunlight during the day.

技术故障

没有什么比网络中断更让我害怕的了。依赖稳定的互联网连接是必不可少的,但在锁定期间,如果家中同时有多个互联网用户,连接会变得缓慢。使用检查它的速度,不要对任何不符合你需要的东西妥协。在我的情况下,速度很好,但必须得到一个中继器,以提高信号到我们的卧室。

为了内心的平静,有一个备份计划是谨慎的:一个移动热点设备,或允许网络共享的手机计划可以“救命”。当一切都失败时,拥有一个没有互联网连接也能完成的任务库将变得很方便:)

环境变化

如果可以的话,靠*窗户工作;它将真正改变你的办公环境。自然光的变化已被证明对健康有益,能够保持对户外的视线将使你保持警觉,促进你的创造性思维,并将成为灵感的来源。如果你有室内植物,把它们放在你的工作区或附*——这是一个把户外引入室内的好方法,肯定会增加你的创造力,减少压力。最后但同样重要的是,即使是最简单的触摸(想一想,一张镶框的照片)也能让你保持踏实和专注。
表白:我曾经对这些 ⬆️ 的想法嗤之以鼻,但它们真的有所作为!

礼貌: GQ 日本

➋:管理分心

每个工作环境都有它的干扰。毫无疑问,每当你的注意力从手头的任务上转移开时,它可能会提高你的压力水平,使你保持生产力的能力更加困难。但是既然你已经找到了一种方法,可以不去理会那个声音很烦人的同事,你就能找到一种方法来克服你的新家带来的干扰。

沉默是金,是吗?

背景噪音是一个非常主观的话题,一些人喜欢绝对的安静来集中注意力,而另一些人发现安静会妨碍他们的工作效率,喜欢一点环境噪音。

当我进入创造性模式时,我不介意背景噪音的水平,但当我试图找到一个错误,理解复杂的技术概念或执行任何其他涉及深入思考的任务时,我根本不能容忍任何噪音。

随着声音级别的提高,您可以执行的任务的复杂性通常会降低。

以下是我的应对技巧:

****——从源头上最小化:我丈夫和我对噪音的容忍度有不同的“接受标准”,所以我们创造了一个家庭办公室礼仪:早上我们分享我们的时间表,我们让彼此知道什么时候我们不被打扰。通过这种方式,80%的情况下噪音在源头被最小化🙃。对于剩下的 20%,如果有一个简单的解决方案就好了...

****—降噪:降噪耳机试图用声音对抗声音,用“大小相等、方向相反”的波形阻挡不想要的声音。花钱买一双像样的,你不会后悔的!我有这些索尼的——质量很好,戴起来非常舒服,即使戴很长时间也是如此!

****—噪音屏蔽:当噪音无法从源头上被阻止,或者无法用耳机消除时,我会求助于用其他不那么令人分心的声音来屏蔽它。虽然这是一个次优的解决方案,但它远比忍受假装忽视它的压力和分心要好。这些是我赖以生存的工具:

  • Focus@Will :他们提供经过科学设计的音乐,以增强你的注意力。它是基于订阅的,但你也可以在 Spotify、 Apple Music 或 YouTube 上找到它们。
  • :选择几个简单的环境,包括森林、雷雨、海浪、咖啡馆和火车轨道,打造你自己的声景。这是我默认的权宜应用,因为它对我有即时的舒缓作用。****
  • 双耳节拍:你可以在谷歌上随意搜索这个术语,这样你就能理解它是如何工作的,但基本上它就是两种频率略有不同的音调同时在不同的耳朵里播放的音乐。只需在您喜欢的音乐流媒体服务上寻找一个不错的播放列表。我喜欢这个
  • 流态 :混搭这个每日快讯推荐器乐专辑和当代古典、环境或电子音乐。

数字娱乐

电子邮件、吉拉通知、垃圾弹出窗口、日历提醒、虚拟会议、电话只是我们每天都会遇到的一些干扰。它们增强了上下文切换,并且扼杀了我们的性能。为了重新控制我的时间,我练*通知排毒……
你可以这样做:

  • 禁用所有桌面通知;
  • 如果不可行,根据 VIP 名单(如你的老板)或聊天室类型(如生产支持)对通知类型进行分类;
  • 在深入钻研一项复杂任务之前,使用“请勿打扰”模式;
  • 当你休息时,浏览阅读通知,只回复重要的请求,因为你可能会丢失当前任务的上下文。

媒体封锁

当我浏览互联网的时候,另一个让我不感兴趣的话题是广告。除了打扰和令人毛骨悚然,他们杂乱的屏幕,降低网络性能和转移我的注意力,大时间。 幽灵特工 在消灭他们方面做得很好。
当广告屏蔽还不够时,我会使用 文本模式 ,删除页面中的任何视觉内容(图片、视频等),让我专注于重要的内容:文本!

真正的问题不一定是注意力分散本身,而是注意力分散后的阶段——注意力分散会让你的精神进程脱轨长达 20 多分钟。即使你一天只分心几次,当你努力回到快乐的工作环境时,你损失的时间也是巨大的!

这很好地把我带到了下一部分…

礼貌:爱德华多·弗洛里斯

专注成就➌:

流行的博客充斥着“改变游戏规则”的生产力技巧: 【番茄工作法】把事情做好帕累托原则 等等。我已经尝试了其中的一些,但是主要的问题是当你做一些像编程这样有创造性的事情时,它们并不完全适用。****

我将分享那些对我最有效的技巧,从保持专注到战胜拖延症和更好的时间管理:

纳普奇诺

是的——听起来确实是这样!我第一次接触这个术语是在伦敦参加一个研讨会的时候,丹尼尔·平克正在那里宣传他的新书《何时:完美时机的科学秘密》。我想试一试,结果是 a.m.a.z.i.n.g!事情是这样的:

当你觉得有点昏昏欲睡时(通常在午饭后),喝一杯咖啡,把闹钟调到 25 分钟,小睡一会儿。当闹钟响起时,咖啡因开始起作用,帮助你清醒地醒来;它“重置”你的生物钟,提高你的认知能力。听起来事与愿违,对吧?不是的!事后你真的会觉得更警醒!

****☕️⏰💤 You can download the full guide [**here**](https://www.danpink.com/wp-content/uploads/2017/12/nappuccino.pdf)!****

如果它很重要,就安排它

我用待办事项列表来保持条理,但对我个人来说,使用日历更有效。待办事项清单设定了不灵活的限制,并给出了“选择的悖论”,而日历通过不断提醒我截止日期来让我掌握工作。所以我所做的就是把我的待办事项列表作为一个待办事项列表,并把我的每日选择转移到日历中。一旦一项任务被列入日程表,它就是正式的——我承诺完成它。

我喜欢这种方法的原因是,它激励我将每天的日程安排建立在真实因素和时间限制的基础上。毕竟一天有 24 个小时……所以如果我的待办事项清单有一英里长,那就不可能完成所有的任务,它很快就会变得令人不知所措。

请记住以下几点:

  • 一旦你排满了日程,你需要诚实地说出你需要多少时间,然后根据你的空闲时间来安排时间。也使用一些缓冲/应急措施。
  • 为高度集中的活动,如编程或架构设计,增加延长的时间。
  • 划分主动和被动时间段。主动型的是你需要关注的重要任务(项目工作),而被动型的是为请求和打断留出时间,例如即兴会议/电话。
  • 第 30-60 分钟完成一些管理任务或回复邮件,例如,收集一份你需要完成的小任务清单,然后一次完成,这样你就不会打断一天中深入的工作。

一个额外的好处是,你不用把你的日历作为一张空白的石板留给别人填写,你可以控制什么时候完成工作!

如果你不优先考虑你的生活,别人会的!—格雷格·麦克欧文

时间管理洞察

跟踪你花在各种编程活动上的时间是很重要的。 Clockify 主要是一个工作时间追踪器,帮助你追踪你在项目上花费的时间,并收集显示你工作效率的数据。在吉拉很容易记录准确的时间,所以你的经理很高兴,可以根据你的速度更好地计划。当你认识到一项任务所花费的实际时间时,你还可以洞察你的生产力,并有助于提高你的评估技能。

有序的桌面

作为开发人员,研究一个主题是我们工作的一部分。我通常会在浏览器的几个窗口上打开几个选项卡,其中包含我的工作进展资源。随着 Outlook、WebEx、Visual Studio、Excel、SourceTree(还有很多)的出现,我的桌面变得太忙、太快了。为了让我的工作空间井然有序,我最喜欢的两个应用是 HazeOverMagnet 。如果你在 Mac 上工作,一定要看看它们!Windows 也有类似的功能。

最容易的方法

每击退一次诱惑,都要花费一些意志力点。简而言之:积极抵制吃巧克力棒的冲动比完全不吃巧克力更难。因此,你没有抵制诱惑,而是将它们从你的周围完全移走;没有诱惑,没有意志力的浪费。我的雇主在屏蔽大多数社交媒体网站方面做得很好,但我倾向于沉迷于科技新闻网站和媒体。我用的是 Chrome 的扩展软件 Timewarp ,它可以让你设置不同的重定向,以防你在工作期间访问一个没有效率的网站。你可以让这个插件把你重定向到一个更有效率的网站,给你看一句激励性的话,或者显示你在上面花的时间。

正确的方法可以让你每天都开心。诀窍是对你需要达到的目标要有意识!

礼貌用语:安德里亚·尤奇尼

➍:报销您的通勤费用

在家工作的最大好处之一是你不必处理长时间的通勤。但是,除了被动的媒体消费或打盹到 8:59,像以前一样早地开始一天并专注于自我发展是非常有益的:你不仅可以保持良好的心理健康,还可以扩展你的知识并释放新的潜力。再说,“ 伟大的开发者从来不会停止学* ”!请参考我那篇广受欢迎的文章,从中获得灵感和可操作的想法,来培养你卓越的专业技能:

****** [## 伟大的开发人员从不停止学*

it 专业人员培养持续学*心态的 7 种方法

towardsdatascience.com](/great-developers-never-stop-learning-77b9ce867eac)

**📌 Bonus Tip**: As a result of the prolonged remote working you may consider investing the substantial commuting cost saving to purchasing the pricey subscription of your favourite self-development site!

⛔️ 重要提示:你的通勤时间应该转化为你的“休息”时间,即脱离工作,拥有一些“你”的时间!尽管关注你的自我发展是至关重要的,但是当你需要睡到 8:59 的时候,不要感到内疚!******

➎:不要隐身

大多数开发人员喜欢减少与同事的接触,但这可能不利于团队凝聚力,并影响生产率和职业发展。应该从一开始就采用并遵循一个沟通策略,该策略规定团队应该多长时间检查一次,以及他们将如何相互传达任何变更或阻碍。定期召开会议(音频或视频)有助于弥合旧的/同处一地的工作方式和新的/远程的工作方式之间的差距,并使所有员工成为团队的一部分。

状态更新

让你的同事知道你什么时候不工作,这样当他们需要联系的时候就不会被晾在一边。礼貌的“马上回来”或“下班”状态更新可以设置正确的期望值,并有助于团队的工作流程。

例行的

当你在一家遵循每日例会(如晨会)和核心工作时间节奏的公司工作时,将你的日常工作与团队的日常工作同步以实现*乎无缝的协作是很好的。

会面时间

如果你想在办公室与同事面对面交谈,不要默认使用电子邮件或 Slack 拿起电话或进行视频通话。这将减少误解,打破在家工作可能带来的社会隔离。

****📌 **Pro Tips**: With video calling becoming the norm now, making sure that people can hear you and see you well is important.
⟶ Use high quality USB microphone (check [**this bad boy**](https://www.amazon.co.uk/Blue-Microphones-Snowball-Ice-Microphone/dp/B006DIA77E) out!);
⟶ Use headphones to prevent echo;
⟶ Sit facing a light source;
⟶ Wi-Fi is the mortal enemy of video calls - make sure your internet connection is decent and also close other competing applications.****

交流-交流-交流

在远程工作环境中,人们通常根据我们产出的数量、质量和及时性来评判我们。作为开发人员,我们的提交、拉请求或吉拉转换(开放、进行中、完成)都在为我们的工作说话,并提供了良好的透明度。但是你如何向你的开发负责人解释那个花了两个小时才发现的讨厌的错误,而且是一个…打印错误?—我们都去过!

  • 确保您与您的经理保持沟通渠道畅通;如果你曾经有定期的一对一,一定要坚持保持。如果你没有,那就马上安排吧。不仅仅是在办公室,并不是放松与老板关系的借口。他们持续的信任和宝贵的反馈对你的职业发展至关重要。****
  • 定期与你的直接下属沟通,但不要把这与微观管理混为一谈。检查实际上只是确保正在取得进展,并且每个人都有他们需要的资源!****

顺利度过长期远程工作的关键是清晰的沟通!

******A step too far?**
A friend of mine, who works in a technology startup, and his team are holding “mute” video gatherings, to simulate an office environment.They simply start a Zoom video call, put the audio on mute and get on with their work. They can all see each other and quickly judge if a colleague looks deep in thoughts (and hence make a judgement if they are interruptible) or away from their desk or in a call or even peek at their toddler who has come for a cuddle!I ❤️ this idea, but surely it is company culture dependent.****

文件

远程工作时,无法访问信息是最令人沮丧的因素之一,有时会成为完成工作的一大障碍。文档在这里非常重要——使用你公司的 wiki(例如 Confluence)来创建指导性文章,记录你的新杰作的技术设计,或者任何你认为你的团队会喜欢的东西。

礼遇:基亚拉·吉利亚扎

甜蜜的家…工作!

尽管新冠肺炎加快了这一进程,但远程工作在过去几年一直呈上升趋势。我希望读完这个指南后,你会成为一名成功的远程开发者!

感谢阅读!

我定期在媒体上撰写关于领导力、技术&的数据——如果您想阅读我未来的帖子,请‘关注’我

如何在 Pandas 中使用 Excel 文件

原文:https://towardsdatascience.com/how-to-work-with-excel-files-in-pandas-c584abb67bfb?source=collection_archive---------0-----------------------

当您拥有 Excel 格式的数据时,需要知道一些有用的事情

背景图片由bongkarn thanyakij来自 像素

就我目前所见,CSV 似乎是数据科学家中最流行的存储数据的格式。这是可以理解的,它完成了工作,并且是一种非常简单的格式;在 Python 中,即使没有任何库,也可以用不到 10 行代码构建一个简单的 CSV 解析器。

但是您可能并不总能找到 CSV 格式的数据。有时,唯一可用的格式可能是 Excel 文件。比如,这个关于 ons.gov.uk 犯罪的数据集,只有 xlsx 格式;我将在下面的例子中使用的数据集。

读取 Excel 文件

将 Excel 文件读入 pandas 数据框的最简单方法是使用下面的函数(假设您使用了import pandas as pd):

df = pd.read_excel(‘path_to_excel_file’, sheet_name=’…’)

其中sheet_name可以是我们要读取的工作表的名称,它是索引,或者是我们要读取的所有工作表的列表;列表的元素可以混合:工作表名称或索引。如果我们想要所有的表,我们可以使用sheet_name=None。在我们希望读取更多工作表的情况下,它们将作为数据帧的字典返回。这种字典的关键字将是一个工作表的索引或名称,这取决于我们在sheet_name中如何指定;在sheet_name=None的情况下,键将是工作表名称。

现在,如果我们用它来读取我们的 Excel 文件,我们会得到:

没错,一个错误!事实证明,pandas 本身无法读取 Excel 文件,因此我们需要安装另一个 python 包来完成这项工作。

我们有两种选择:xlrdopenpyxl。包xlrd可以同时打开 Excel 2003(。xls)和 Excel 2007+(。xlsx)文件,而openpyxl只能打开 Excel 2007+(。xlsx)文件。因此,我们将安装xlrd,因为它可以打开两种格式:

pip install xlrd

现在,如果我们再次尝试读取相同的数据:

有用!

但是 Excel 文件可能会有点混乱。除了数据之外,在第一行和/或最后两行,他们可能有其他注释/解释。

要告诉 pandas 从特定的行开始读取 Excel 表,可以使用参数 header = 0-索引行从哪里开始读取。默认情况下,header=0,第一行用于给出数据框列的名称。

若要跳过工作表末尾的行,请使用 skipfooter =要跳过的行数。

例如:

这个稍微好一点。仍然有一些特定于该数据的问题。根据我们想要实现的目标,我们可能还需要以另一种方式重新排列数据值。但是在本文中,我们将只关注数据帧的读写。

除了上面的方法,另一种读取 Excel 文件的方法是使用一个pd.ExcelFile对象。这样的对象可以通过使用pd.ExcelFile(‘excel_file_path’)构造函数来构造。一个ExcelFile对象有几种用法。首先,它有一个.sheet_names属性,是打开的 Excel 文件中所有工作表名称的列表。

然后,这个ExcelFile对象也有一个.parse()方法,可以用来从文件中解析一个工作表并返回一个数据帧。这个方法的第一个参数可以是我们想要解析的工作表的索引或者它的名字。其余参数与pd.read_excel()功能中的相同。

解析第二个工作表(索引 1)的示例:

…这里我们使用名称而不是索引来解析同一个工作表:

ExcelFile s 也可以用在with … as …语句中,如果您想做一些更复杂的事情,比如只解析名称中有两个单词的工作表,您可以这样做:

同样的事情你可以用pd.read_excel()代替.parse()的方法来做,就像这样:

…或者,如果您只是想要所有的纸张,您可以:

编写 Excel 文件

现在我们知道了如何读取 excel 文件,下一步我们还可以将数据框写入 excel 文件。我们可以通过使用数据帧方法.to_excel(‘path_to_excel_file’, sheet_name=’…’)来实现。

让我们首先创建一个用于写入 excel 文件的简单数据框:

现在我们想把它写到一个 excel 文件中:

…我们得到了一个错误。

还是那句话,熊猫不能自己写 excel 文件;我们需要另外一个包装。我们的主要选择是:

  • xlwt —仅适用于 Excel 2003(.xls)文件;不支持追加模式
  • xlsxwriter —仅适用于 Excel 2007+(。xlsx)文件;不支持追加模式
  • openpyxl —仅适用于 Excel 2007+(。xlsx)文件;支持追加模式

如果我们想给老人写信。xls 格式,我们应该安装xlwt,因为它是唯一处理这些文件的。因为。xlsx 文件,我们将选择openpyxl,因为它也支持追加模式。

pip install xlwt openpyxl

现在,如果我们再次运行上面的代码,它的工作;创建了一个 excel 文件:

默认情况下,pandas 还会将索引列与我们的列一起写入。要消除它,使用下面代码中的index=False:

索引列现在不在那里:

如果我们想写更多的表呢?如果我们想在前面的文件中添加第二页,你认为下面的代码可行吗?

答案是。它只会用一张纸覆盖文件:sheet2。

要将更多的工作表写入 Excel 文件,我们需要使用如下所示的pd.ExcelWriter对象。首先,我们为 sheet2 创建另一个数据框,然后我们打开一个 Excel 文件作为ExcelWriter对象,我们在其中写入 2 个数据框:

现在我们的 Excel 文件应该有 2 张。如果我们想在其中添加另一个工作表,我们需要在 append 模式下打开该文件,并运行与前面类似的代码。例如:

我们的 Excel 文件现在有 3 张表,如下所示:

使用 Excel 公式

此时,您可能对 Excel 公式感到疑惑。他们怎么了?如何从有公式的文件中读取?怎么把它们写到 Excel 文件里?

嗯……好消息。这很容易。将公式写入 Excel 文件就像只写公式的字符串一样简单,这些字符串会被 Excel 自动解释为公式。

举个例子:

上面的代码生成的 Excel 文件是:

现在,如果我们想读取一个包含公式的 Excel 文件,pandas 会将这些公式的结果读入数据框。

例如,让我们读取我们之前创建的文件:

有时,您需要手动保存 Excel 文件,这样才能工作,并且不会得到零而不是公式的结果(在执行上面的代码之前按 CTRL+S)。

下面是 Jupyter 笔记本的代码:

我希望这些信息对您有用,感谢您的阅读!

这篇文章也贴在我自己的网站这里。随便看看吧!

关于数据来源的一切

原文:https://towardsdatascience.com/how-to-work-with-someone-elses-data-6c45d467d7a2?source=collection_archive---------8-----------------------

非结构化数据、继承的数据、耗尽的数据、混淆的数据和其他小精灵

如果你正准备加入公民数据科学家的行列(一头扎进新冠肺炎的数据,也许?)关于数据来源,您应该知道一些事情…

数据出处:“谁收集的,为什么?”

社会被关于数据的扭曲预期所困扰,充斥着像“数字不会说谎”**“在你给我看数据之前,这只是你的看法”(不,仍然是你的看法)和“我看了数据,所以现在我是知情的。”

在每个孩子的一生中,总会有那么一段时间,他们必须认识到:牙仙不是真的。事情不会因为你有一些数字就奇迹般地解决。这些数字从何而来真的很重要。(有些孩子比这个发展里程碑晚了几十年。)

任何人都可以把一些电子涂鸦放在一个表格里,称之为数据。从你与科学联系的意义上来说,这并不意味着它是好的/真实的/有用的/有价值的。

即使数据集被仔细地收集,你确定你知道它在到达你的途中发生了什么吗?恶棍不会从你的梦数据集中删除不方便的行的唯一原因(“对你隐藏数据?我绝不会。这些都是离群值。”)或者在与你分享数据之前,以扭曲信息的方式聚集东西,这太容易了。(自重的小人更喜欢挑战。)

对来源进行推理的能力是数据素养的基本要求之一,所以让我们做一些区分:

  • 主要数据与继承(次要)数据
  • 采集数据对比排气数据
  • 结构化数据与非结构化数据
  • 原始数据对加工数据

然后总结它们的相对优点来完成这篇文章。

初级与次级

如果你(或你所在的团队)直接从现实世界中收集了的观察数据,你就在使用 原始数据 。换句话说,您可以控制如何记录和存储这些测量结果。

相反的是什么? 继承(次级)数据 是那些你从别人那里获得的数据。(例如,您可以在这里获得超过 2000 万个数据集。)

继承的数据集就像继承的牙刷:使用它们是一种绝望的行为。如果可能的话,你总是更喜欢使用自己的数据集,因为二手数据集充满了陷阱。不幸的是,你可能没有这个选择。

如果你对我对继承数据集的深入研究感兴趣——包括如何使用它们的建议——在这里绕一个小弯。

捕获与排放

捕获数据 是为了特定的分析目的而有意创建的,而排气数据是数字化/在线活动的副产品。 耗尽数据 通常发生在网站出于调试或数据收集等目的而非特定分析目的存储活动日志时。

捕获的数据是为数据科学专业人员用于特定目的而创建的,而排气数据则不是。

尾气数据可能是分析的宝库,但却是统计推断的噩梦。(我关于统计学和分析学的区别的文章是这里。)如果您正在进行谨慎的数据驱动的决策,如果可以选择,您会更喜欢捕获的数据。另一方面,如果你在寻找惊喜或希望激发原创想法的灵感,你可能想将目光投向捕捉到的数据集之外。

如果你*惯于处理为分析而创建的数据,你可能会觉得在这个乱七八糟的数据仙境中有些东西不太对劲…但你又不能确切地指出它。如果您*惯的所有惯例都被忽略,并且日志记录选择感觉有点古怪,原因很简单:这些数据集不是为您的眼球设计的。因此,如果尾气数据感觉像是需要额外清理和处理的垃圾,你也不应该感到惊讶。深呼吸,分配额外的时间给你的争吵。

结构化与非结构化

与此相关的是,我很难接受“非结构化数据”这个新名字,直到我意识到这只是商业世界重新发现一个非常古老的概念:一团糟。

你称之为非结构化数据的东西只是需要你把它结构化的数据。

如果我们迂腐的话,就没有非结构化数据这种东西(因为通过存储,它们必然被迫具有某种结构),但是让我大方一点。以下是该定义想要表达的意思:

  • 结构化数据被整齐地格式化,准备进行分析。
  • 非结构化数据 不是你想要的格式,它们强迫你把自己的结构放在上面。(想想巨魔留下的图片、邮件、音乐、视频、文字评论。)

你称之为非结构化数据的东西只是需要你把它结构化的数据。迷因:来源

例如,您可能希望以漂亮的表格格式处理图像数据,但是您却发现一个文件夹中充满了各种不同扩展名和格式的图片。雪上加霜的是,你发现了一个文本文件,里面有各种网站上更多图片的链接。恶心恶心。

把东西存放得如此混乱需要一种特殊的天赋,这就是为什么你通常会发现背后的罪魁祸首是人类。至少像日志文件这样的机器生成的尾气数据有某种标准化的格式(即使是愚蠢的格式),这就是为什么我们称那些东西为半结构化数据。

一个分析师的垃圾是另一个分析师的财富。

把结构化数据想象成整洁的图书馆,把非结构化数据想象成混乱的阁楼,这不会伤害你。和数据一样,世界上图书馆的数量远远少于乱七八糟的藏书。(我可以从我的桌子上看到一个。)当然,旁观者清。您可能会发现图像数据从定义上来说是杂乱的,而我可能只会在它们以上述方式到达时才发现它们是杂乱的。一个分析师的垃圾是另一个分析师的宝藏。

非结构化数据“革命”背后的观点是,您对非标准数据格式的耐心可能会获得丰厚的回报。

对于非结构化数据,你唯一能做的就是分析。为了将它用于统计推断ML/AI ,你必须对它进行结构化。当您的数据从非结构化转向结构化时,您通常会侵蚀其中的一些信息,就像您在准备沙拉时扔掉洋葱的薄片一样。

由于非结构化数据在您使用它们时就变得结构化了,因此它们的真正“优势”是您一开始就拥有它们。如果企业必须让他们所有的数据都符合你的口味,他们可能会对所涉及的努力嗤之以鼻,懒得存储那么多数据。结果,你能接触到的数据挖掘的来源就少多了。

生的与加工的

说到清理, 原始数据 是采集后未被改动的数据,而 处理后的数据 是被清理和/或转换的数据。换句话说,原始数据以原始形式到达,没有被陌生人篡改。原始数据几乎总是需要一点爱(阅读:清洁工的工作)才能变得有用。

你可能认为这意味着处理过的数据优于原始数据…但这是一个陷阱!因为数据科学专业人员编写代码来处理他们的数据(参见“非破坏性编辑”),真正优越的选择是原始数据和处理代码。如果您正在共享数据,这是最好的方法(除非有法律/隐私原因需要在处理过程中隐藏一些数据,或者原始数据集非常庞大)。

真正优越的选择是伴随处理代码的原始数据。

让自己脱离电子表格并编写代码来为自己做数据工作,可以确保在清理过程中不会破坏任何信息,并允许您改变主意,比如说,像剪掉一些有问题的代码一样容易地去除离群值或进行类别聚合。

如果我们要细化,那么让我们命名一些种类的处理过的数据:

  • 转换后的数据 —信息被改变,从而无法重建
  • 聚合数据 —原始的信息内容在观察值上折叠
  • 混淆数据 —信息被有意隐藏(例如通过删除或噪声注入)
  • 礼貌数据 —嗯?

最后一个是我喜欢做的半开玩笑的区分。只要在转换/聚合过程中没有丢失任何信息,我不反对接收一个格式良好的原始数据集的礼貌版本(具有良好的文档和有意义的变量名)。例如,如果你要给我发送数据,并且你知道我喜欢用千克而不是磅,那么用我觉得更容易使用的 weight_kg 列替换你那令人困惑的 wlb 列是礼貌的;这比给我发送原始数据稍微好一点。但是如果你用二进制列替换 wlb 是超重的,你将向我发送不礼貌的处理过的数据。那是因为你不必要地破坏了原始数据中的一些信息…谁说我会同意你对超重的定义?

选择数据集

原始数据至高无上…如果你负担得起的话。如果你要使用其他人的数据,最好使用原始的/礼貌的数据,除非他们的领域专长远远超过你。如果你问的问题与最初的收集者感兴趣的问题相同,那么捕获的数据更有优势。如果你想从尚未有人想到的方向中获得灵感,排气数据可能是一个更好的选择(因为捕获的数据更有可能给你留下与原始收集者相似的结论)。快速总结:

主要数据优势:对质量的控制。
次要数据优势:省时省钱。

抓取数据优势:统计推断和决策。
穷尽数据优势:激发原创想法。

结构化数据优势:需要清理的少。
非结构化数据优势:有些东西不会以其他方式存储。

Raw 数据优势:几乎一切。
处理过的数据优势:应对海量原始数据集。

使用他人数据的建议

在这里继续阅读第 2 部分…

感谢阅读!人工智能课程怎么样?

如果你在这里玩得开心,并且你正在寻找一个为初学者和专家设计的有趣的应用人工智能课程,这里有一个我为你制作的娱乐课程:

在这里欣赏整个课程播放列表:bit.ly/machinefriend

与凯西·科兹尔科夫联系

让我们做朋友吧!你可以在 TwitterYouTubeLinkedIn 上找到我。有兴趣让我在你的活动上发言吗?用这个表格联系。

如何使用他人的数据

原文:https://towardsdatascience.com/how-to-work-with-someone-elses-data-f33485d79ed4?source=collection_archive---------18-----------------------

处理继承数据指南

定义

如果你(或你所在的团队)直接从现实世界中收集了的观察结果,那么你就在使用的原始数据。换句话说,您可以控制如何记录和存储这些测量结果。

相反的是什么? 继承(次级)数据 是你从别人那里获得的那些数据。(例如,您可以在这里获得超过 2000 万个数据集。)

想要其他相关术语的定义吗?在我的主文 上找到它们的数据出处 。(你正在读第二部分。)

买家当心

继承的数据集就像继承的牙刷:使用它们是一种绝望的行为。如果可能的话,你总是喜欢用你自己的。不幸的是,你可能没有这个选择。收集原始数据可能非常昂贵。

收集自己的数据是一种奢侈,不是每个人都能负担得起的。

虽然原始数据带有一股让人想起手工奶酪的优越感,但任何坚持认为你没有利用继承数据的价值的人都应该检查一下他们的特权。个人(以及没有强大数据传统的公司或某个领域的新来者)可能没有资源独自收集数据,特别是当项目需要非常大的数据集或专业技能/设备时。例如,不是每个人都能负担得起在生物安全等级高的实验室环境中进行病原体测量。

有时候你唯一的选择就是尽量利用别人的数据。

但是,如果你被迫使用其他人的数据,如果事情没有像你希望的那样发展,不要感到惊讶。不能保证继承的数据能满足你的需求……(而且,牙仙也不是真的。)

购买者请注意:不能保证继承的数据能满足您的需求。

仅仅因为有人卖给你一个标有“晚餐用品”的包装,并不意味着你可以用它做一顿美味的晚餐。如果里面只装了一堆卫生纸呢?小心使用继承的数据;它可能不适合你的需要。

下面是我喜欢的 R.A .费舍尔的一句话:

“在一个实验完成后咨询统计学家往往只是要求他进行一次事后检查。他也许可以说实验死于什么。”

这也适用于您继承的数据集——它的收集在您到达现场之前就已完成,因此它不是为满足您的需求而设计的。就你的预期目的而言,它可能已经过时了,你最多只能从中挤出一次尸检。我希望你已经绕着太阳走了足够多的路程,不要让这个激怒你。

继承的数据更容易获得,但更难信任。

如果你正处于抗议的边缘,认为有一些数据总比没有数据好,那就用“噪音”/谎言/干扰”来代替“数据,然后再试试你的句子。质量就是一切,如果您没有自己收集数据集,您就无法控制测量的内容和(可能更重要的)遗漏的内容。有些数据只比没有数据好倍。

当您被迫处理继承的数据时,您有五个主要问题需要担心:

  • 目的 —收集数据集的目的是否与您的目的相似?
  • 能力 —你相信收集数据的团队能够胜任测量工作吗?
  • 议程 —你相信数据集不会被其作者的偏见和议程所污染吗?(不要太快相信!)
  • 清晰 —是否有清晰的文档来防止你误解数据集的内容?
  • 处理 —你确定数据集没有被转换、扭曲或篡改吗?

使用他人数据的建议

您应该如何处理继承的数据?就像你接触到的任何数据集一样,你的第一个动作,*惯——本能!—应该是 SYDD 。(“拆分你那该死的数据。”将任何未指定用于探索的数据放在安全的地方。**

证明文件

接下来,寻找关于继承数据集如何产生的文档是至关重要的。如果可能的话,试着找出并联系负责数据收集的罪犯,诶,项目成员,找出他们到底做了什么,并问他们澄清问题。如果与最初的团队协商是不可能的(或者如果他们忘记了他们做了什么),你将被迫依赖书面文档。(看到了吗?这也是为什么好的文档如此重要的另一个理由。)

如果你是一名分析师(不做统计推断),你可以采取一种轻量级的方法:找出有多少文档存在,有多详细,对数据质量是否值得你的时间投入进行一次直觉检查,然后只在你通常的探索性数据分析需要时使用文档( EDA )。然而,如果你认为你发现了足以激励决策者的东西,彻底检查文档,以确保你没有陷入明显的红鲱鱼。

如果你正在做 ML/AI ,你可以采取类似的方法,在粗略浏览文档之后,使用继承的数据进行训练,但是——看在上帝的份上!— 仔细验证根据您自己的原始数据测试您的模型。如果你没有彻底检查原始数据的表现,那就不算数。你对自己和他人都是一种威胁。请不要发射。

统计学家不会轻易放过任何事情。如果您正在从事一个数据驱动的决策项目,那么在处理继承的数据之前,您必须彻底了解文档。这听起来非常无聊,但这是你为了安全地使用不是你自己创建的数据而必须付出的代价。具体来说,确保您编写了自己的文档,详细说明了您对采样过程、潜在偏差以及生成您所继承的数据的实际操作的理解。

数据质量

当您研读文档时,请查找变量名的确切含义,并请一位分析师朋友帮助您做一些 EDA 工作,以确保数据不会完全混乱。例如,应该为正的事物没有负值,没有无差异的列,没有重复,没有矛盾,等等。如果你不确定要注意什么,你可能想从标准健康检查中查找一些关于数据质量的关键词:

是否涵盖了正确的主题?

  • 目的
  • 有用
  • 关联
  • 相似性
  • 综合性

是否存在准入障碍?

  • 有效性
  • 易接*
  • 清楚
  • 储存;储备

你能相信消息来源吗?

  • 能力
  • 可靠性
  • 可靠性
  • 议程
  • 偏见

你能相信你所看到的吗?

  • 准确(性)
  • 一致性
  • 有效期
  • 独特性
  • 处理

你能相信你看不见的东西吗?

  • 完全
  • 一致性
  • 及时
  • 潜伏

假设和警告

非常重要的一点是,你不要做出过早的假设——仅仅因为某样东西被称为“重量”并不意味着它就是你所认为的那样。它可以是 SI 单位或重要性权重或其他任何东西——人们将最糟糕的标签放在他们的数据集中,特别是如果他们在创建这些标签时没有考虑到其他数据科学家。

不要做不成熟的假设。

另外,不要相信任何人!即使文档中说“重量”是指以千克为单位的重量,也要记住抄写错误和其他测量错误是一回事。例如,如果该列声称包含权重,您可能会问自己:是否使用了秤?(或者只是眼球?我哪里知道?)尺度有多精确?有不止一个音阶吗?它们被仔细校准了吗?测量人员训练有素吗?**

我自己量一下,谢谢。图片:来源

当您在文档中回答这些问题时,您会惊讶地发现“这是什么#$%@呢?”“这在现实生活中是如何实现的?”你能得到好的、精确的答案的问题。

这意味着你必须放弃吗?你可以继续……保持适当的谨慎和谦逊。

这意味着你必须放弃吗?不。你可以继续…带着适当的谨慎和谦逊。每次你发现一个问题,你都会义不容辞地对你被迫做出的关于在数据收集过程中到底发生了什么的猜测大加赞赏。

你会在以下事情上花费大量无聊的时间:

  • 陈述你被迫做出的假设。
  • 写下要包括在你最终报告附录中的警告注释。
  • 写下注意事项,警告决策者(和你的其他读者)由于潜在的数据问题,研究的结论需要降级。

你欠读者和决策者的道歉程度取决于你对类似数据的经验和专业知识。

简单地说:你对收集数据的真实环境了解得越多,你的假设就越不可信,你就越不需要在听众面前卑躬屈膝。

如果你是该领域的专家——例如,如果你是一名与流行病学家一起工作的经验丰富的生物统计学家,你比我更有资格对新冠肺炎数据集收集过程中发生的事情做出合理的假设。如果我厚颜无耻地在没有经验丰富的主题专家支持的情况下钻研这些数据,我将欠我自己和我的观众一份对我的无知的评估(以书面形式!)之后再继续。

“由于我们的项目团队没有参与规划研究或数据收集,我们可能遗漏了关键的背景,从而导致我们的结论无效。”

除了写下软化结论的笔记,每个有自尊的作者都应该记得附上这样一个总括性的继承数据警告:“由于我们的项目团队没有参与规划研究或数据收集,我们有可能遗漏了关键的上下文,从而导致我们的结论无效。”**

这与完美主义无关。试图用数据稍微增加你(不完美的)理解是完全合理的。只是不要忘记承认你有多少不知道的。

这与完美主义无关。试图用数据稍微增加你(不完美的)理解是完全合理的。请记住,多学一点并不等于什么都知道…不要忘记承认你有多少不知道。如果你做不到这一点,你会把任何信任你的人直接带下悬崖。

谦逊可能是媒体断奶的注意力持续时间的罗嗦,但过度自信的替代方案更糟糕。

感谢阅读!人工智能课程怎么样?

如果你在这里玩得开心,并且你正在寻找一个为初学者和专家设计的有趣的应用人工智能课程,这里有一个我为你制作的娱乐课程:

在这里欣赏整个课程播放列表:bit.ly/machinefriend

喜欢作者?与凯西·科兹尔科夫联系

让我们做朋友吧!你可以在 TwitterYouTubeSubstackLinkedIn 上找到我。有兴趣让我在你的活动上发言吗?使用表格取得联系。

如何理解 Spark NLP

原文:https://towardsdatascience.com/how-to-wrap-your-head-around-spark-nlp-a6f6a968b7e8?source=collection_archive---------36-----------------------

跟进“如何在两周内开始 SparkNLP 第一部分”*

摄影:Pixabay

欢迎阅读 Spark NLP 文章的第二部分。在第一部分中,目标是为 NLP 从业者提供一个破冰的平台,并让他们对 Spark NLP 有所了解。对任何基于 Spark 的库的最大偏见来自于这样一种思想流派“Spark 代码与常规 Python 脚本有点不同”。为了消除这种偏见,我们分享了学*策略,如果你遵循了这些策略,你就为下一阶段做好了准备。

在本文的这一部分,我们将比较 spaCy 和 Spark NLP,并深入探讨 Spark NLP 模块和管道。我创建了一个笔记本,使用 spaCy 和 Spark NLP 来做同样的事情,进行完美的图片比较。SpaCy 表现不错,但是在速度、内存消耗、精度方面 Spark NLP 胜过它。因此,就易用性而言,一旦 Spark 的初始摩擦被克服,我发现它至少与 spaCy 不相上下,这要归功于管道带来的便利。

由 Spark NLP 创建者准备的 smart、comprehensive notebook的使用,提供了大量真实场景的示例,以及我为实践而创建的 repo 强烈建议在所需的技能集方面表现出色。

第 8/9 天:了解 Spark NLP 中的注释器/转换程序和使用 Spark 的 文本预处理

Spark NLP 库原生构建于 Apache Spark 和 TensorFlow 之上,为机器学*管道提供了简单、高效且准确的 NLP 符号,可在分布式环境中轻松扩展。这个库重用了 Spark ML 管道以及集成的 NLP 功能。

该库涵盖了许多常见的 NLP 任务,包括标记化、词干化、词汇化、词性标注、情感分析、拼写检查、命名实体识别,所有这些都是开源的,可以由训练模型使用您的数据。Spark NLP 的注释器利用基于规则的算法、机器学*和一些在引擎盖下运行的 Tensorflow 来支持特定的深度学*实现。

在 Spark NLP 中,所有的标注器要么是估算器,要么是变换器,就像 Spark ML 一样,由两种类型组成:标注器方法标注器模型。任何在数据帧上产生模型的标注器训练都是标注器方法。那些通过一些模型将一个数据帧转换成另一个数据帧的是注释者模型(例如 WordEmbeddingsModel )。通常,如果注释器在转换数据帧时不依赖于预先训练的注释器(例如标记器),它就不会使用模型后缀。下面是注释器及其描述的列表:****

Spark NLP 提供的注释器列表,来源:Spark NLP 介绍—基础和基本组件

为了完成自然语言处理过程,我们需要对原始数据进行预处理。除了 SQL 过滤器、转换和用户定义的函数之外,Spark NLP 还附带了用于该任务的强大工具。Document assembler是一个特殊的转换器,它创建文档类型的第一个注释,这个注释可能会被管道中的后续注释器使用。

Doc2Chunk 将文档类型注释转换为带有块 Col 内容的块类型,而 Chunk2Doc 将块类型列转换回文档。在尝试对块结果进行重新标记或进一步分析时非常有用。

修整器 将注释值输出到一个字符串中,以方便使用。一旦我们的 NLP 管道准备就绪,我们可能希望在其他实际可用的地方使用注释结果。

如前所述,管道被指定为一系列阶段,每个阶段要么是转换器,要么是估计器。这些阶段按顺序运行,输入数据帧在通过每个阶段时会发生转换。

下面是这条管道在 Spark NLP 中的编码方式。

**from pyspark.ml import Pipelinedocument_assembler = DocumentAssembler()\
 .setInputCol(“text”)\
 .setOutputCol(“document”)sentenceDetector = SentenceDetector()\
 .setInputCols([“document”])\
 .setOutputCol(“sentences”)tokenizer = Tokenizer() \
 .setInputCols([“sentences”]) \
 .setOutputCol(“token”)normalizer = Normalizer()\
 .setInputCols([“token”])\
 .setOutputCol(“normal”)word_embeddings=WordEmbeddingsModel.pretrained()\
 .setInputCols([“document”,”normal”])\
 .setOutputCol(“embeddings”)nlpPipeline = Pipeline(stages=[
 document_assembler, 
 sentenceDetector,
 tokenizer,
 normalizer,
 word_embeddings,
 ])pipelineModel = nlpPipeline.fit(df)**

当我们在具有 Spark 数据帧(df)的管道上fit()时,它的文本列首先被送入DocumentAssembler()转换器,然后在文档类型(注释者类型)中创建一个新列“文档”。如前所述,这个转换器是任何 Spark 数据帧的 Spark NLP 的初始入口点。然后将它的文档列送入SentenceDetector() ( 注释者方法)中,将文本拆分成一个句子数组,并在文档类型中创建一个新列“句子”。然后将“句子”列输入到Tokenizer() ( 注释器模型)中,对每个句子进行标记化,并在标记类型中创建新列“*标记”。诸如此类。请参考 Spark NLP workshop 预处理笔记本my repo 查看注释器和转换器的工作情况。*****

第 10 天:Regex
正则表达式本质上是一种嵌入在 Python 中的微小的、高度专门化的编程语言,并通过 [*re module*](https://docs.python.org/3/library/re.html#module-re) 可用。 使用这个小语言,你为你想要匹配的可能字符串集合指定规则;这个集合可能包含英语句子,或者电子邮件地址,临床实体,或者任何你喜欢的东西。您还可以使用正则表达式来修改字符串或以各种方式拆分它。

Regex 是 NLP 的主要构件之一,我们不仅将使用它进行预处理,还将它作为 Spark NLP 管道中RegexMatcher的一部分。由于有时可能相当复杂,我推荐 Maria Eugenia Inzaugarat 的这个课程,以便快速掌握高级主题,请参考官方 python 文档以及精彩的 python regex how to 教程。我用来掌握 regex 的另一个关键组件是 Regex101 ,这是一个非常强大的 API,可以让你在文本块上测试几乎任何正则表达式。

大多数时候正则表达式被忽略了。相信我:你会需要它,你会使用它。你知道的越多越好。

第 11 天:预训练模型

前面提到过,经过训练的标注器被称为标注器模型,这里的目标是通过指定的模型(经过训练的标注器)将一个数据帧转换成另一个数据帧。Spark NLP 提供多种语言的预训练模型,您需要做的就是加载预训练模型并相应地配置其参数。当您可以通过一种transform()方法直接应用预先训练好的 SOTA 算法时,为什么还要担心从头开始训练新模型呢?在官方文档中,您可以找到关于如何使用哪些算法和数据集来训练这些模型的详细信息。笔记本样本可在此处找到**

**MODEL_NAME='sentimentdl_use_twitter'documentAssembler = DocumentAssembler()\
    .setInputCol("text")\
    .setOutputCol("document")use = UniversalSentenceEncoder.pretrained(name="tfhub_use", lang="en")\
 .setInputCols(["document"])\
 .setOutputCol("sentence_embeddings")sentimentdl = SentimentDLModel.pretrained(name=MODEL_NAME, lang="en")\
    .setInputCols(["sentence_embeddings"])\
    .setOutputCol("pr_sentiment")nlpPipeline = Pipeline(
      stages = [
          documentAssembler,
          use,
          sentimentdl
      ])empty_df = spark.createDataFrame([['']]).toDF("text")pipelineModel = nlpPipeline.fit(empty_df)result = pipelineModel.transform(spark_df1)**

第 12/13 天:文本分类

Spark NLP 中有几个文本分类选项:

  • Spark NLP 中的文本预处理和使用来自 Spark ML 的 ML 算法
  • Spark ML 的 Spark NLP 和 ML 算法中的文本预处理和单词嵌入(Glove、Bert、Elmo)
  • Spark ML 的 Spark NLP 和 ML 算法中的文本预处理和句子嵌入(通用句子编码器)
  • Spark 自然语言处理中的文本预处理和分类器

正如在关于 Spark NLP 的文章中所讨论的,在ClassifierDL之前的所有这些文本处理步骤都可以在一个流水线中实现,这个流水线被指定为一系列阶段,每个阶段要么是一个转换器,要么是一个估计器。这些阶段按顺序运行,输入数据帧在通过每个阶段时会发生转换。也就是说,数据按顺序通过拟合的管道。每个阶段的transform() 方法更新数据集并将其传递给下一个阶段。在Pipelines的帮助下,我们可以确保训练和测试数据经过相同的特征处理步骤。

你可以用这个ClassiferDL在 Spark NLP 中构建一个包含BertElmoGloveUniversal Sentence Encoders的文本分类器。样本分类器笔记本可以在这里这里找到。

**document_assembler = DocumentAssembler() \
    .setInputCol("comment_text") \
    .setOutputCol("document")\
    .setCleanupMode('shrink')tokenizer = Tokenizer() \
  .setInputCols(["document"]) \
  .setOutputCol("token")

normalizer = Normalizer() \
    .setInputCols(["token"]) \
    .setOutputCol("normalized")\
    .setLowercase(True)stopwords_cleaner = StopWordsCleaner()\
      .setInputCols("normalized")\
      .setOutputCol("cleanTokens")\
      .setCaseSensitive(False)lemma = LemmatizerModel.pretrained('lemma_antbnc') \
    .setInputCols(["cleanTokens"]) \
    .setOutputCol("lemma")bert = BertEmbeddings.pretrained('bert_base_uncased', 'en') \
      .setInputCols("document", "lemma") \
      .setOutputCol("embeddings")\
      .setPoolingLayer(0) # default 0embeddingsSentence = SentenceEmbeddings() \
      .setInputCols(["document", "embeddings"]) \
      .setOutputCol("sentence_embeddings") \
      .setPoolingStrategy("AVERAGE")classsifierdl = ClassifierDLApproach()\
  .setInputCols(["sentence_embeddings"])\
  .setOutputCol("prediction")\
  .setLabelColumn("toxic")\
  .setMaxEpochs(5)\
  .setEnableOutputLogs(True)\
  .setBatchSize(32)\
  .setValidationSplit(0.1)\
  .setDropout(0.75)\
  .setLr(0.0035)\
  #.setOutputLogsPath('logs')clf_pipeline = Pipeline(
    stages=[document_assembler, 
            tokenizer,
            normalizer,
            stopwords_cleaner, 
            lemma, 
            bert,
            embeddingsSentence,
            classsifierdl
           ])clf_pipelineModel = clf_pipeline.fit(sdf)**

第 13–14 天:SpaCy 或 Spark NLP —基准比较

在本节中,我们将获得大量的练*编码!我们将使用从 Gutenberg.org 下载的七部不同经典著作组成的图书馆。该语料库包括大约 490 万个字符和 9.7 万个句子。我们将使用 spaCy 和 Spark NLP 的类似过程构建相同的输出数据帧,然后比较结果。

Spacy 是我见过的记录最好的图书馆之一,我惊喜地发现现在他们包括了一门免费课程,我以前上过。如果需要的话,这是一个提升你技能的好机会。

比较的整个笔记本和语料数据可以在我的 GitHub repo 中找到。让我们从检查空间方式开始。

**### 2.1 Clean Tabs and Whitespace
clean_shrink = lambda text : text.replace(r'\n|\t|\s+',' ').replace('\s+',' ').strip()
df.loc[:,'document']=df.text.map(clean_shrink)### 2.2 Tokenizer
sentence_tokenizer = lambda sent : [token for token in nlp(sent)]
df.loc[:,'token']=df.document.map(sentence_tokenizer)### 2.3 Normalizer
normalizer = lambda tokens : [re.sub(punct,'',token.text)  for token in tokens if re.sub(punct,'',token.text) != '']
df.loc[:,'normalized']=df.token.map(normalizer)### 2.4 Remove Stop Words
normalizer_and_stop = lambda tokens : [re.sub(punct,'',token.text)  for token in tokens if re.sub(punct,'',token.text) != '' and not token.is_stop]
df.loc[:,'cleanTokens']=df.token.map(normalizer_and_stop)### 2.5 Lemmatize
normalizer_and_stop_lemma = lambda tokens : [re.sub(punct,'',token.lemma_)  for token in tokens if re.sub(punct,'',token.text) != '' and not token.is_stop]
df.loc[:,'lemma']=df.token.map(normalizer_and_stop_lemma)### 2.6 Stemmer
stemmer = PorterStemmer()
stems = lambda tokens : [stemmer.stem(token.text) if len(tokens)>0 else [] for token in tokens]
df.loc[:,'stem']=df.token.map(stems)### 2.7 Part of Speech Tagging
normalizer_and_stop_pos = lambda tokens : [re.sub(punct,'',token.pos_)  for token in tokens if re.sub(punct,'',token.text) != '' and not token.is_stop]
df.loc[:,'pos']=df.cleanTokens.map(normalizer_and_stop_pos)### 2.8 Token Assembler
token_assembler = lambda tokens : " ".join(tokens)
df.loc[:,'clean_text']=df.cleanTokens.map(token_assembler)### 2.9 Tagger
tagger = lambda text : [(ent.text, ent.label_) for ent in nlp(text).ents]
df.loc[:,'ner_chunks']=df.loc[:,'document'].map(tagger)### 2.10 Regex Parser
noun_chunker = lambda text : [(chnk,(chnk[0].pos_,chnk[1].pos_,chnk[2].tag_ ))for chnk in nlp(text).noun_chunks if len(chnk.text.split())==3\
                              and  chnk.text.replace(' ','').isalpha()   and chnk[0].pos_ == 'DET'and chnk[1].pos_ == 'ADJ' and chnk[2].tag_ in ['NN','NNP']
                             ]
df.loc[:,'RegexpParser'] =df.loc[:,'document'].map(noun_chunker)**

让我们暂停一下,观察正则表达式解析器的输出。我们要求名词组块器返回由一个限定词、一个形容词和一个名词(专有、单数或复数)组成的组块。

**[chunk for chunk in df.RegexpParser.values if chunk!=[]]**

结果看起来相当不错。

**[[(My dear Robinson, ('DET', 'ADJ', 'NNP'))],
 [(this accidental souvenir, ('DET', 'ADJ', 'NN'))],
 [(a great deal, ('DET', 'ADJ', 'NN'))],
 [(a great amount, ('DET', 'ADJ', 'NN'))],
 [(the local hunt, ('DET', 'ADJ', 'NN')),
  (some surgical assistance, ('DET', 'ADJ', 'NN'))],
 [(a remarkable power, ('DET', 'ADJ', 'NN'))],
 [(a good deal, ('DET', 'ADJ', 'NN'))],
 [(a fresh basis, ('DET', 'ADJ', 'NN')),
  (this unknown visitor, ('DET', 'ADJ', 'NN'))],
 [(the obvious conclusion, ('DET', 'ADJ', 'NN'))],
 [(their good will, ('DET', 'ADJ', 'NN'))],
 [(my dear Watson, ('DET', 'ADJ', 'NNP')),
  (a young fellow, ('DET', 'ADJ', 'NN'))],
 [(a favourite dog, ('DET', 'ADJ', 'NN'))],
 [(the latter part, ('DET', 'ADJ', 'NN'))],
 [(that local hunt, ('DET', 'ADJ', 'NN'))],
 [(a heavy stick, ('DET', 'ADJ', 'NN'))],
 [(a professional brother, ('DET', 'ADJ', 'NN'))],
 [(the dramatic moment, ('DET', 'ADJ', 'NN'))],
 [(a long nose, ('DET', 'ADJ', 'NN'))],
................**

让我们继续搭积木吧。

**### 2.11 N-Gram Generator
ngram_generator = lambda input_list: [*zip(*[input_list[i:] for i in range(n)])]
n=3
df.loc[:,'triGrams'] = df.loc[:,'token'].map(ngram_generator)### 2.12 Word2Vec Embeddings
vector = lambda tokens: [(token.text, token.has_vector, token.vector, token.is_oov) for token in tokens]
df.loc[:,'vectors'] = df.loc[:,'token'].map(vector)### 2.13 Regex Matcher
rules = r'''\b[A-Z]\w+ly\b|Stephen\s(?!Proto|Cardinal)[A-Z]\w+|Simon\s[A-Z]\w+'''
regex_matchers = lambda text : re.findall(rules,text)
df.loc[:,'Regex_matches'] =df.loc[:,'document'].map(regex_matchers)**

让我们来看看正则表达式匹配

**df.Regex_matches[df.Regex_matches.map(len)>1]**

结果如下:

**13123                      [Polly, Polly]
25669                      [Sally, Sally]
27262                      [Sally, Sally]
27273                      [Polly, Sally]
27340                      [Polly, Sally]
28311                      [Pelly, Dolly]
42016                      [Feely, Feely]
49802                    [Finally, Emily]
52129                    [Lively, Lively]
58295                      [Silly, Milly]
62141                      [Silly, Milly]
64811                       [Only, Molly]
71650                        [Hely, Daly]
74427                      [Healy, Dolly]
77404                      [Molly, Milly]
77437                      [Milly, Molly]
81557                     [Molly, Reilly]
84023          [Szombathely, Szombathely]
89594                       [Healy, Joly]
92206    [Simon Dedalus, Stephen Dedalus]
92980      [Firstly, Nelly, Nelly, Nelly]
93046               [Szombathely, Karoly]
94402       [Reilly, Simon Dedalus, Hely]
94489    [Stephen Dedalus, Simon Dedalus]**

让我们冒险进入角色…

既然我们有了一个包含许多要素的数据集,我们就有了大量的选项可供选择。让我们检查一下书中的人物……让我们找到带有“人”标签的 NER 语块,由两个单词组成。

**flatlist = lambda l : [re.sub("[^a-zA-Z\s\']","",item[0]).title().strip()  for sublist in l for item in sublist if item[1]=='PERSON' and len(item[0].split())==2]
ner_chunks = df.ner_chunks.to_list()
names=(flatlist(ner_chunks))
len(sorted(names))**

上面的代码返回了 4832 个名字,这看起来有点可疑,因为这个数字很高。让我们检查一下Counter对象的结果:

**('St Clare', 306),
 ('Buck Mulligan', 96),
 ('Aunt Chloe', 76),
 ('Martin Cunningham', 74),
 ('Masr George', 45),
 ('Ned Lambert', 44),
 ('Solomon Northup', 43),
 ('Tom Sawyer', 42),
 ('Aunt Sally', 37),
 ('Uncle Tom', 37),
 ('Ben Dollard', 36),
 ('Myles Crawford', 35),
 ('Blazes Boylan', 28),
 ('Uncle Abram', 24),
 ('J J', 22),
...... 
 ('L L', 5),
 ('Mark Twain', 5),
 ("Tom Sawyer'S", 5),
 ('Chapter Xi', 5),
 ('Chapter Xix', 5),
 ('Dey Wuz', 5),
 ('George Jackson', 5),
 ('Levi Bell', 5),
 ('King Lear', 5),
 ('Simon Legree', 5),
 ('Garrett Deasy', 5),
 ('A E', 5),
 ('S D', 5),
 ('Josie Powell', 5),
 ('Mrs Purefoy', 5),
 ('Ben Howth', 5),
 ('Bald Pat', 5),
 ('Barney Kiernan', 5),
 ('Michael Gunn', 5),
 ('C C', 5),**

不幸的是,许多标签是不准确的。请注意一些章节标题以及大写首字母被错误地返回为PER标签。

在编写上面的代码时,使用了映射来确保快速调整,并且模拟了下面将要实现的 Spark NLP 管道。一旦我们在 Spark NLP 中运行类似的代码,我们将在内存使用、速度和准确性方面比较结果。

是时候用 NLP 的方式做事了!

**documentAssembler = DocumentAssembler()\
.setInputCol(“text”)\
.setOutputCol(“document”)\
.setCleanupMode(“shrink”)sentenceDetector = SentenceDetector().\
    setInputCols(['document']).\
    setOutputCol('sentences')tokenizer = Tokenizer() \
    .setInputCols(["sentences"]) \
    .setOutputCol("token")ngrams = NGramGenerator() \
            .setInputCols(["token"]) \
            .setOutputCol("ngrams") \
            .setN(3) \
            .setEnableCumulative(False)\
            .setDelimiter("_") # Default is spacenormalizer = Normalizer() \
    .setInputCols(["token"]) \
    .setOutputCol("normalized")\
    .setLowercase(False)\
    .setCleanupPatterns(["[^\w\d\s\.\!\?]"])stopwords_cleaner = StopWordsCleaner()\
      .setInputCols("normalized")\
      .setOutputCol("cleanTokens")\
      .setCaseSensitive(False)\lemma = LemmatizerModel.pretrained('lemma_antbnc') \
    .setInputCols(["cleanTokens"]) \
    .setOutputCol("lemma")stemmer = Stemmer() \
    .setInputCols(["token"]) \
    .setOutputCol("stem")pos = PerceptronModel.pretrained("pos_anc", 'en')\
      .setInputCols("clean_text", "cleanTokens")\
      .setOutputCol("pos")chunker = Chunker()\
    .setInputCols(["sentences", "pos"])\
    .setOutputCol("chunk")\
    .setRegexParsers(["<DT>+<JJ>*<NN>"])  ## Determiner - adjective - singular nountokenassembler = TokenAssembler()\
    .setInputCols(["sentences", "cleanTokens"]) \
    .setOutputCol("clean_text")\tokenizer2 = Tokenizer() \
    .setInputCols(["clean_text"]) \
    .setOutputCol("token2")glove_embeddings = WordEmbeddingsModel.pretrained('glove_100d')\
          .setInputCols(["document", "lemma"])\
          .setOutputCol("embeddings")\
          .setCaseSensitive(False)onto_ner = NerDLModel.pretrained("onto_100", 'en') \
          .setInputCols(["document", "token", "embeddings"]) \
          .setOutputCol("ner")ner_converter = NerConverter() \
  .setInputCols(["sentences", "token", "ner"]) \
  .setOutputCol("ner_chunk")rules = r'''
\b[A-Z]\w+ly\b, starting with a capital letter ending with 'ly'
Stephen\s(?!Proto|Cardinal)[A-Z]\w+, followed by "Stephen"
Simon\s[A-Z]\w+, followed by "Simon"
'''with open('ulyses_regex_rules.txt', 'w') as f:

    f.write(rules)regex_matcher = RegexMatcher()\
    .setInputCols('sentences')\
    .setStrategy("MATCH_ALL")\
    .setOutputCol("regex_matches")\
    .setExternalRules(path='./ulyses_regex_rules.txt', delimiter=',')**

既然我们的零件都准备好了,让我们来定义装配线。

**nlpPipeline = Pipeline(stages=[
 documentAssembler,
 sentenceDetector,
 tokenizer,
 ngrams,
 normalizer,
 stopwords_cleaner,
 lemma,
 stemmer,
 tokenassembler,
 tokenizer2,
 pos,
 chunker,
 glove_embeddings,
 onto_ner,
 ner_converter,
 regex_matcher

 ])empty_df = spark.createDataFrame([[‘’]]).toDF(“text”)pipelineModel = nlpPipeline.fit(empty_df)lib_result = pipelineModel.transform(library)**

****让我们根据我们的搜索标准检查 regex 匹配:
-以大写字母开头并以' ly '结尾的整个单词,

  • 'Stephen '后面没有' Cardinal '或' Proto ',但后面有以大写字母开头的单词。--“Simon”后面是一个以大写字母开头的单词。我们希望每个句子中至少出现两次…****
**match_df.filter(F.size('finished_regex_matches')>1).show(truncate = 50)**

让我们来看看结果…

我们管道中的 chunker 注释器将返回由限定词、形容词和单数名词组成的组块。

**lib_result.withColumn(
    "tmp", 
    F.explode("chunk")) \
    .select("tmp.*").select("begin","end","result","metadata.sentence").show(20,truncate = 100)**

以下是 chunker 结果的前 20 行。

让我们冒险进入角色…火花 NLP 方式。

在这里,我们检查书中的角色…这一次我们将使用 Spark NLP 机制。请注意准确性与空间的差异。

**l = result_ner.filter(result_ner.ner_label == "PERSON").select(F.expr("ner_chunk")).collect()names = list([re.sub("[^a-zA-Z\s\']","",l_[0]).title() for l_ in l if l_[0].replace(' ','').isalpha() and len(l_[0].strip().split())==2 and "’" not in l_[0]])len(set(names))**

这一次,我们的字符数被限制在 1284。让我们来看看最常见的 350 个名字。

**('Buck Mulligan', 93),
 ('Aunt Chloe', 82),
 ('Martin Cunningham', 71),
 ('Bayou Boeuf', 48),
 ('Aunt Sally', 39),
 ('Ned Lambert', 39),
 ('Mary Jane', 38),
 ('Solomon Northup', 36),
 ('John Thornton', 34),
 ('Myles Crawford', 33),
 ('Ben Dollard', 31),
 ('Sherlock Holmes', 30),
 ('Tom Sawyer', 30),
 ('John Eglinton', 29),
 ('Nosey Flynn', 28),
 ('Corny Kelleher', 27),
 ('Mrs Breen', 27),
 ('Father Conmee', 26),
 ('Uncle Tom', 25),
 ('John Wyse', 24),
 ('Henry Baskerville', 23),
 ('Uncle Abram', 22),
 ('Blazes Boylan', 19),
 ('Bob Doran', 18),
 ('Davy Byrne', 18),
 ('Coombe Tracey', 17),
 ('Aunt Phebe', 17),
 ('Simon Dedalus', 17),
........................
 ('Sandy Hill', 8),
 ('Theophilus Freeman', 8),
 ('Father Cowley', 8),
 ('Gregory B', 7),
 ('George Harris', 7),
 ('Rachel Halliday', 7),
 ('George Shelby', 7),
 ('Anne Hampton', 7),
 ('Peter Tanner', 7),
 ('Almidano Artifoni', 7),
 ('Hugo Baskerville', 6),
 ('Laura Lyons', 6),
 ('Aunt Polly', 6),
 ('Peter Wilks', 6),
.........................**

名单看起来更准确。难怪 Spark NLP 是企业首选!

SpaCy 不错,但是 Spark NLP 更好…

我们来谈谈资源消耗:
本次研究使用的系统是一个 8 核英特尔酷睿 i7–9700k CPU @ 3.60 GHz,32820MB 内存。操作系统是 Ubuntu 20.04。

与 spaCy 相比,Spark NLP 使用的内存更少,运行速度是 spaCy 的两倍。这个事实,再加上 Spark NLP 更高的准确性,为掌握这个库提供了很好的理由!

目前就这些。本文的主要目的是给中级水平的从业者一个如何使用 Spark 在 NLP 领域实现目标的指南。一些 Spark NLP 概念在开始时可能很难学*,但是,本文中介绍的文章、课程和示例笔记本将提供一个很好的起点。spaCy-Spark NLP 的初始开销可能很高,但比较显示了差异。掌握 Spark NLP 并不容易,但也不太难…如果你的目标是企业领域,这绝对是一项让你在简历上大放异彩的技能!

请点击链接进入文章的第一部分。

如何用 Python 编写一个数字系统计算器

原文:https://towardsdatascience.com/how-to-write-a-number-systems-calculator-in-python-b172557cb705?source=collection_archive---------8-----------------------

二进制,十进制或十六进制,冲我来,兄弟!

照片由来自 Pexels安德里亚·皮亚卡迪奥拍摄

在本文中,我们将构建一个计算器,可以用来将任意基数的任意数字转换成任意基数的任意数字。在数字系统中,“基数”告诉我们你有多少个可用的数字。二进制有 2,八进制有 8,十进制有 10 等等。

我们将要编写的程序可以处理我们扔给它的任何numberbase。当我们搞清楚背后的数学,就很容易成立了。

我们将创造什么:

但是首先,数学

这个计算器是以数学为基础的(不都是吗?).我们可能需要刷新我们对碱基转换理论的记忆(或者学*一些新的东西。)

如果你在学校学过科学驱动的数学,或者学过任何级别的计算机,你很可能已经从一种数字系统转换到另一种了。你可能还记得二进制表或者谈论过的"十进制"*,八进制"十六进制"*。**

十进制(以 10 为基数)是我们日常计数时使用的。0, 1, 2, 3, 4, 5, 6, 7, 8, 9.当我们用完了数字,我们在左边再加一个位置→ 10,11,12,13,14,15,16,17,18,19,20,21…等等。当我们再次用完数字时,我们添加一个新的位置→ 100,101,102…118,119,120。

是的,是的…我记得小学…

我们不会去想它,因为我们在 2-3 岁的时候就知道了。告诉一个孩子用八进制(8 进制)数数,他们很可能会看你几秒钟,然后再回到他们的 iPad 上做作业。这个理论很简单,与十进制相同,只是我们不*惯。

在八进制系统中计数看起来像这样:

0,1,2,3,4,5,6,7 → 10,11,12,13,14,15,16,17 → 20,21…

从一个碱基转换到另一个碱基

我们应该看的第一个转换是从任意基数(基数为 N)到十进制系统(基数为 10)。从十进制转换成任何其他基数都很容易。因此,了解十进制是很有价值的。

如果我们继续使用十进制的和八进制的作为例子,我们可以将八进制的转换成十进制的。让我们选一个随机数。

256(基数-8) →???(十进制)

(我保证,256 实际上是随机的)

  • 我们有三个位置 2(一百)、5(十)和 6(一)。正如您在简介中所记得的,这些位置可以包含 0-7(8 个数字)。
  • 我们需要将所有位置的每个数字都转换成十进制。十进制系统可以容纳 0–9(10 个数字)

我们这样做的方法是,我们取每一个数,并把它乘以以位置索引为幂的基数(num * (base^position)).如果我们从最右边的数字开始,我们用 8⁰乘 6,用 8 乘 5,用 8 乘 2。

这里有一个例子可以让你更容易理解:

从基数为 8 的 256 到基数为 10 的 174

当我们有了十进制(以 10 为基数)的数字,就很容易进入任何系统。让我们从 174(基数为 10)回到 256(基数为 8)

我们找到另一个基数的方法是用它除以这个基数,并保留余数。剩下的人会在另一个基地给我们建号码。当我们得到余数时,我们从最不重要的数字到最重要的数字来读这个数,意思是从下到上。你的新号码出现在你的新底座上了!‍

174/2 等于 21.75。注意 21 是红色的,0.75 是绿色的。我们把 21 送到下一行,处理 0.75。如果我们用 0.75 乘以基数,就剩下余数(这是我们要找的数)。这个数字以蓝色发送到最右边。

当我们达到 0 时,我们就正式完成了,可以在我们的新基地用一个漂亮的数字打包我们的行李了。

从基数 10 的 174 到基数 8 的 256

这不仅意味着我们可以从十进制到八进制,反之亦然。我们可以从 X 基到 y 基。任何我们想要的基。

感觉大概是这样的:

照片由来自 PexelsMarcin Dampc 拍摄

如果你仍然不确定这是如何工作的,我建议查看“有机化学导师”。他的视频是我所知道的关于这个主题的最好的:

* [## 有机化学导师

该频道主要提供有机化学、普通化学、物理、代数等方面的教学视频

www.youtube.com](https://www.youtube.com/channel/UCEWpbFLzoYGPfuWUMFPSaoA)

代码

是时候深入研究代码了!

注意:我的大部分编程都是手工完成的。这意味着我不使用太多的库,因为我想尽可能多地学*。在这段代码中,我使用了之类的标准 python 函数,因为我想向您展示这是可能的,但我认为手动编写相同的函数比使用hex()更有趣。在生产环境中,您可能希望保持简短,并使用能够解决您的问题的库,而不是从头开始编写代码

这个程序只是一个包含所有代码的文件。如果你愿意,你可以随意扩展。一节数字课?当然,为什么不呢?GUI?这也是我们应该研究的。

我建议在编码时使用一个基本的在线转换器计算器,仔细检查代码输出的值是否正确。

要点如下:

完整的要点代码。

代码背后的逻辑是我们向函数convert_number_system():传递三个参数

  • input_number是我们要转换的数字。
  • input_base是我们希望转换的基础。
  • output_base是我们希望皈依的基地。

定义菜单()

我以前没有使用多行字符串来打印菜单,但是创建这样的菜单是很有意义的。

该函数返回整个菜单字符串,因此我们可以在任何需要的地方使用它。我们也不用担心换行符。

return (
    '''
----------------------------------------------------------
Welcome to the Number Base converter!
The system will ask you for:
- The Number to convert
- What base you want to convert FROM
- What base you want to convert TO** REMEMBER: All numbers must be integers!(unless HEX) **
----------------------------------------------------------
    ''')

验证器

我不想在转换器函数中检查用户输入,而是想创建函数形式的验证器。通过这样做,我们创建了可重用的代码。

def validate_bin(检查编号):

这个函数只是检查数字是否是有效的二进制数。

我们不想检查同一个数字出现了几次的长字符串。如果我们把它转换成一个集合,我们删除重复。集合不能包含一个项目的多个实例。我们使用 list comprehension 将输入转换为 int,并对照[0,1]进行检查

[int(item) for item in set(list(check_number))]

我选择传递来自用户交互的字符串,并在需要时创建输入的整数。int(item)确保所有的数字都是整数(如果我们愿意,我们也可以对照一个字符串来检查一个字符串(‘0’ , ‘1’)。

这是它在幕后的样子:

‘10010011’[‘1’,’0',’0',’1',’0',’0',’1',’1'][0,1]

如果 0 在[0,1]中,则检查结果正常,如果 1 在[0,1]中,则检查结果也正常。如果你有一个像 23 这样的数字,两个数字都会失败,函数会返回False

定义验证输入(检查编号):

这里没有什么特别的…代码检查输入是否包含定义的合法字符。我们使用数字0–9,因为我们支持十六进制,所以我们也将a-f作为有效输入。

定义验证器(输入编号,输入基础,输出基础):

这个函数利用其他验证器来验证所有的输入,这样我们就知道是否有必要继续进行转换。

  • 首先,它检查我们是否输入了一个数字或十六进制值。
  • 然后我们检查基地。如果 input_base 是 2,那么我们正在转换一个二进制数。因此,input_number 只能是数字,如果是,它必须是 0 或 1。
  • 如果输入既是数字又是字母,则它是一个十六进制数字。如果 input_base 不是 16,那么我们就不能转换。十六进制以 16 为基数,任何其他基数都不会正确计算。我们可以考虑在交互过程中,当有人键入十六进制数时,制作一个预填充的输入库。
  • 最后,我们检查用户是否试图转换为基数 1。这是不可能的,所以我们不想让程序崩溃,而是想返回一个错误。*

转变

现在,该是代码的主要部分了。这是我们将利用我们的数学技能的地方。这个函数执行我们之前看到的匹配,它有几个安全步骤来确保我们正确输出

def convert _ number _ system(input _ number,…):

转换 _ 数字 _ 系统要点

保存我们要返回的数字。如果你记得数学,你应该立刻认出关键字余数。

sum_base_10。我们想用十进制作为中间步骤。我们将初始值设置为 0,然后将我们计算的任何值添加到这个变量中。

输出二进制:

*if output_base == 2:
    return (bin(input_number)[2:])*

如果用户想要二进制输出,我们可以使用内置函数 bin()。我们不需要这样做,因为无论我们通过了什么,数学都是一样的,但是尝试是很有趣的。

bin()返回0b和二进制。0b告诉我们它是一个二进制数。我们想返回实际的数字。这就是[2:]的作用。如果您在终端中运行此命令,您可以看到不同之处:

*>>> check_number = 23
>>> print(bin(check_number))
0b10111
>>> print(bin(check_number)[2:])
10111*

它将从索引 2 开始打印。

注意,我在代码中保留了 hex()版本,但是注释掉了。你想用就用吧。

基数不是 10: 如果基数不是 10,我们通过我们的中间步骤。首先,我们反转列表(你不必这样做,但是之后你需要在循环中翻转索引。我发现翻转列表更容易。)用这个神奇的内置代码[::-1]可以在 Python 中反转列表

*reversed_input_number = input_number[::-1]*

hex_helper_dict 帮助我们处理 9 以上的数字,如果用户发送一个十六进制输入。如果你还记得我们的公式,我们将每个位置的数字乘以由位置决定的基本指数。

这里又是 256 从八进制十进制:**

2(8²) + 5(8¹) + 6(8⁰) = 174*

如果数字是十六进制的,比如 23e,它实际上是 2,3,14

2(16²) + 3(16¹) + 14(16⁰) = 574*

这个循环帮助我们完成了所有这些工作:

*for index, number in enumerate(reversed_input_number):
    for key,value in hex_helper_dict.items():
        if str(number).lower() == key:
            number = value sum_base_10 += (int(number)*(int(input_base)**index))*

如果你看看上面的代码,你会发现我们同时使用了枚举和。items()来确保我们可以访问执行操作所需的所有内容。

通过使用枚举,我们可以访问变量的值和索引。当我们循环变量时,我们检查数字(例如。e)等于字典中的任意一个键。在 23e 的情况下,它是,我们想将数字设置为 14,这样我们可以使用它进行实际计算。

*sum_base_10 += (int(number)*(int(input_base)**index))*

既然我们已经确定没有数字是真正的字母,我们就可以遍历这些数字(还是 256)并进行运算。对于我们循环遍历的每个数字,我们都要做之前讨论过的乘法。

(int(number)(int(input _ base)* * index))
6 (8 * * 0)

我们最终得到的值被加到 sum_base_10。

基数是 10: 太棒了,继续。我们只是将输入数赋给 sum_base_10:

*elif input_base == 10:
    sum_base_10 = int(input_number)*

做数学运算 现在我们有了以 10 为基数的值,我们可以做除法来找出余数并找到我们的新数。

*while sum_base_10 > 0:
    divided = sum_base_10// int(output_base)
    remainder_list.append(str(sum_base_10 % int(output_base))
    sum_base_10 = divided*

我们需要除法,直到我们达到 0。while 循环确保了这一点。

通过使用底数除法//我们将数除,剩下的是商的整数部分。这意味着我们只保留整数(21)而不保留点(75)之后的内容,这是基于我们在 intro (174/8= 21.75 )中的例子

通过将这个数分配给 divided,我们还可以将这个值发送给 sum_base_10,以便最终进行下一次迭代。

通过使用模,%,我们将得到余数。这被附加到 remainder_list 中,这样我们可以在以后输出它。

这是一个 while 循环,一直持续到我们点击0

如果输出基数是 16 如果 output_base 是 16,这意味着用户想要一个十六进制输出。我们需要将任何大于 9 的数字转换成字母。

正如我们之前所做的,我们创建了一个字典来帮助转换。如果我们找到一个匹配,我们把数字转换成一个字母,并把它附加到列表中。

最后:

*return ''.join(remainder_list[::-1])*

这反转并把我们的列表变成一个我们可以返回的字符串。如果要返回一个 int,可以使用 int()。如果用户要求 16 进制输出,请确保您考虑了十六进制数。

def 执行转换器():

唷!我们的大部分代码已经完成。

拼图的最后一块是与用户互动。这是一个直接的 while 循环,用户输入数字,我们验证它们,如果验证通过,就运行转换器。用户可以选择他/她想要做多少次就做多少次。

我喜欢用基于变量状态的 while 循环来创建用户交互;就像我们这里的proceed。这样,只要用户愿意,我们就可以一直进行下去。

它有两个层次。第一个 while 根据proceed.lower() == ‘y’.启动主循环

第二个声明valid_input=False,因为我们希望在将输入传递给convert_number_system()之前验证所有的输入。只要输入是False,我们就需要新的输入。在用户给我们他/她的输入之后,它运行验证器。如果通过,我们可以启动convert_number_system()

最后,我们询问用户是否想再去一次。如果用户输入‘y’,我们再次运行代码。如果他/她再输入任何东西,我们就退出程序。

另一种方法是要求用户键入他/她想要转换的号码或退出。在number_input变量中。

最后

照片由黑冰派克斯拍摄

这个程序涵盖了编程的几个方面。首先,我们需要找到问题。问题是手动转换所有的数字要花很多时间。

然后我们找到/学*数学来解决问题,找到共同点。事实证明,我们可以用相同的公式将任何东西转换成任何东西。我们只需要处理二进制和十六进制输入,我们需要确保我们不会试图计算基数为 1。这意味着我们可以使用函数来处理我们的代码。

一切都包装在一个菜单里,一个用户交互,底层执行代码潜伏在后台。

我希望你通过阅读这篇文章学到了一些东西。如果你发现任何问题的代码或有其他想法,请让我知道。请随意获取代码,并继续为您自己的项目开发它。

-M

如何和杰西一起写 algotrading 比特币的盈利策略

原文:https://towardsdatascience.com/how-to-write-a-profitable-strategy-for-algotrading-bitcoin-with-jesse-6c7064b22f1f?source=collection_archive---------41-----------------------

开始使用算法交易并不难

照片由 Katerina Limpitsouni 拍摄

在这个教程里,我要写一个和杰西交易比特币的策略。本教程的重点是让你开始使用 Jesse,这样你就可以编写自己的策略。我还会教你几个技巧,这些技巧是我多年来学到的,可以帮助我写出有利可图的策略。这大概会是一系列的文章。

本教程的重点不是给你一个牛逼的策略;这是让你开始写一个。在第一部分中,我将涵盖从:

  • 如何使用技术分析
  • 如何进入交易
  • 如何退出交易
  • 如何管理风险

首先,确保您已经安装了 Jesse。如果没有,那就去做吧。接下来,确定你进口了蜡烛。我们现在就开始吧,因为这需要几分钟才能完成,这很好,因为我们将编写策略:

jesse import-candles Bitfinex BTCUSD 2016-01-01

创建策略

我们把这个策略命名为SampleTrendFollowingcd进入您的 Jesse 项目并运行:

jesse make-strategy SampleTrendFollowing

现在打开位于strategies/SampleTrendFollowing/__init__.pySampleTrendFollowing。这是 Jesse 生成的代码:

使用技术分析

我们将使用均线指标来检测市场趋势的方向。让我们用两条周期为 50 的均线代表慢速均线,周期为 21 的均线代表快速均线。

注意,我用@property关键字将它们定义为类属性。这允许我将它们用作self.long而不是self.long(),在我看来这更容易一些。

让我们也定义一下 ATR 指标,这是我最喜欢的设定止损价格的工具:

进入规则

我们的进场规则很简单:当快速均线突破慢速均线时做多,反之亦然。

管理风险

每个策略的一个关键部分是头寸规模。一个简单的组合头寸规模将使你受益匪浅。例如,让我们每次交易都拿总资本的 3%来冒险。

我们还需要指定我们的入门价格。简单来说,让我们用市价单建仓。

注意,我在止损和止盈目标中都使用了ATR指标。

虽然动态退出趋势跟踪策略是一个很好的实践,但是我在开仓的时候设置了退出点。我这样做是为了保持本教程简单。

路线

现在我们需要告诉 Jesse 在执行回溯测试命令时交易SampleTrendFollowing策略。我们还需要选择一个时间框架,和一个交易的符号。我选择了6h时间框架和BTCUSD作为我的标志。您的routes.py文件应该如下所示:

运行回溯测试

让我们看看它的表现如何:

jesse backtest 2019-01-01 2020-01-01

结果如下:

你看那个,居然有利可图!嗯,至少在 2019 年是这样。对于在6h时间框架内的趋势跟踪策略交易来说,这样的回溯测试足够了吗?你说了算,但如果我有数据,我会更进一步。在这种情况下,我回到 2017 年,直到今年的 5 月 3 日:

结论

本教程的目的是让你开始和 Jesse 一起编写策略。我将写更多这样的文章,探索 Jesse 的更多特性,比如使用多个时间框架、过滤器、事件等等。

为了获得我未来的作品和产品,请务必订阅杰西的时事通讯,并查看论坛,与你我这样的量化者讨论算法交易。

更新【5 月 26 日】:下一篇文章继续这篇文章的结尾:
如何在你的算法交易策略中使用多个时间框架

原载于https://jesse-ai.com

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

如何写一份成功的目标陈述

原文:https://towardsdatascience.com/how-to-write-a-successful-statement-of-purpose-to-study-ai-fda2d3e3d579?source=collection_archive---------3-----------------------

帮助我被卡内基梅隆大学、斯坦福大学、加州大学伯克利分校的计算机科学研究生课程录取的 8 个技巧和例子

https://unsplash.com/photos/s9CC2SKySJM

大约在去年的这个时候,我开始准备美国大学的研究生申请,以攻读涉及人工智能的硕士项目。从法国一个全新的学士项目的第一批毕业生中毕业,我几乎没有研究或行业经验,也没有发表过论文,但我比以往任何时候都更有决心写一份目标陈述(SoP ),这将有助于我从优秀的申请者中脱颖而出。

几个月后,我很高兴收到了我所有首选的录取通知书!虽然一开始我不知道 SoP 是什么,但我肯定做了一些正确的事情,说服了所有这些名牌大学的人。为了回馈社区,我想分享一些我在 SoP 写作过程中学到或发现有用的技巧:)

对于那些感兴趣的人,我也会在这篇文章的最后附上我在申请期间的统计数据,我被接受的项目,我被拒绝的项目,以及我选择的项目。

免责声明:我只是一个喜欢机器学*和博客的应届毕业生,我绝对没有资格教你如何写论文。以下建议仅仅反映了我申请美国计算机硕士学位的个人经验,并不总是通用的。

1.不要拖延这篇文章

是的,我很清楚一个学生在最后一分钟完成一篇论文时的超人生产力。但是相信我,我强烈建议你在申请截止日期之前就开始考虑你的 SoP。

以下是我的时间表:

九月开始——我在谷歌上搜索“如何写目标陈述”并创建了我的 SoP.docx 文件

十月开始——我准备好了第一份草稿,请其他人校对

11 月开始——我修改了我的第一稿,让其他人再次校对

11 月底——我准备好了一份“通用”SoP,但我仍需对我考虑的每个项目进行“微调”

12 月-1 月——对于每个项目,我在提交申请前都敲定了每个 SoP

2 月 3 日 —我收到了我的第一个回复:被我的梦想计划录取了!

对我来说,花了 3 个月来计划和写我的 SoP。有些可能需要更多或更少的时间。我的观点是,这不是一篇可以或应该仓促完成的文章,给自己时间思考你想说的话,从别人那里得到的反馈,再重写几次就好了。

如果你不知道如何开始,我的建议是无论如何都要创建文档,记下你的任何想法,即使是愚蠢的想法。从那里,你将能够开始把这些想法串成一串文本,或者在你没有预料到的时候想出新的想法。

2.目的陈述≠个人陈述

与我本科申请的个人陈述不同,大多数研究生院不会给出明确的提示或你需要回答的问题。一个常见的错误是认为毕业生 SoP 就像是“有更多经验的个人陈述”。

个人陈述是个人,你应该写你是谁

另一方面,目标陈述应该围绕你计划实现的目标。

一般来说,您应该在 SoP 中回答的重要问题有:

  1. 你的兴趣动机目标是什么?是什么激发了他们?
  2. 你在有什么相关经验?你学到了什么让你为研究生学*做好准备?
  3. 这个研究生项目如何帮助你实现目标?在这个项目中你打算做什么?

请记住,审稿人实际上是在你的论文中寻找成为成功研究生的潜力,所以你的主要目标是让你相信自己有能力、有动力去完成研究生学业。

3.保持结构化

你希望你的 SoP 能让你的评审者愉快地阅读。重要的是,你的想法是有结构的,流畅的,这样评审者就不需要猜测你想表达什么或者在想法之间跳跃。

我是这样组织我的文章的:

  • 在陈述我的总体目标之前,抓住读者的注意力
  • 描述我以前实现这个目标的经历
  • 陈述我学到了什么和使我成功的品质
  • 重申目标,但提供更多细节
  • 解释我还需要学*什么,以及该计划将如何帮助我成长
  • 以热情、积极的语气结束:)

你的可能看起来不像我的,但总的来说就是每个段落/部分都有一个清晰的 信息/目的

4.保持简洁、相关、专注

一个好的经验法则是将你的文章控制在两页以内。尽管你可能有很多话要说,但对你想要包含的细节进行选择是很重要的,因为评论者可能有数百篇文章要看。

对我起作用的是,一开始写下我想要的一切,然后改写冗长的短语,省略不必要的细节。确保你说的每一句话都是一个关键细节,说明你为什么是理想的研究生候选人。

同样,问问你自己“我想用这个传达什么信息?”对于每一句话。不要只是描述你在项目中做了什么,一定要陈述你从中学到了什么,这个证明了关于你的什么:

在我的第一个编程项目中,我带领一个 8 人团队用 C++为音乐创作构建了一个 LSTM 神经网络。在项目开始时,我没有机器学*经验,在 4 个月内,我吸收了建立和训练神经网络所需的技术技能和机器学*概念。我还学会了设计一个机器学*项目,从数据检索和嵌入到模型演示的用户界面,并在团队中有效地分配这些任务。

5.从一开始就引人注目

理想的文章从一开始就能抓住读者的注意力,并引导他们理解你的想法,直到最后。不要泛泛而谈,要有创意!

不要以“我的目标是研究人工智能和开发帮助人们的技术”——这不会让你的介绍令人难忘或迷人——开始你的文章,而是想一件轶事,一个参考,甚至一个笑话,帮助你轻松进入你的主要信息。

在继续解释我的研究目标之前,下面是我如何开始的:

我妈妈刚开始用智能手机的时候,只用来打电话。她不会使用其他功能,例如查找方向,直到我教她口头询问虚拟助理她需要什么。这让我相信自然语言处理将会在人类和现代技术之间架起一座桥梁。

6.秀,不要说

招生人员正在寻找证据,证明你最适合他们的项目。任何人都可以说“我很有决心,工作努力,而且我学东西很快”,但这不会让你出类拔萃。

一个更强烈的信息是一个例子,无论是在工作中、课堂上还是在外面,展示了你声称拥有的品质。例如,下面是我说的话,而不是“我很有决心,很努力”:

在人工智能方面的经验很少的情况下,我参加了 4 次社交活动,分发了 50 份简历,参加了 10 次面试,从而获得了 NLP 实*机会。

7.具体说明你所在的领域和你的项目

与本科学*不同,研究生招生寻找的是在项目学*领域与他们密切合作的学生。你是他们潜在的研究助理,助教,博士生…

你需要向他们展示你知道他们在做什么样的工作,并且你拥有适合他们专业领域的 T2 特有的技能。在描述你的经历时,不要犹豫使用专业术语!

在熟悉了语言建模和自我关注之后,我在最*的研究基础上使用完形填空翻译来合成问题回答数据。我还学会了在 PyTorch 中编写 BiDAF 和 BERT 模型,并执行云计算。

此外,跟踪你项目中的一些教员和活动也很好,并表明这不仅仅是的任何项目,而是你想要的这个特定的项目。你可以引用你感兴趣的论文或你想学的课程:

我特别决定加入[大学 NLP 实验室],在[真酷教授#1]、多语言语言分析工具和阅读理解的指导下,与[真酷教授#2]一起研究 NLP,为社会造福。我还想将[非常酷的教授#3]在[非常酷的论文]中的工作整合到我对健壮的无监督问答系统的对抗训练的无监督问答的研究中。

我通常为我所有的申请保留相同的前 1.5 页,并为每个特定的项目提供后 0.5 页。

8.写,校对,再写

对我来说,SoP 写作的一个重要步骤是从不同的人那里获得反馈,并一遍又一遍地修改我的文章。

你可以要求阅读你的文章的人的例子有:

  • 你的学术顾问/咨询团队:他们通常在校对标准操作程序和给出写作建议方面最有经验
  • 你的推荐信作者:他们可能拥有相关领域的专业知识来完全理解你的论文,他们也可能有审查入学标准程序的经验。我的计算机系教授甚至纠正了我的一个技术细节!
  • 你的朋友:要么他们以前写过标准操作程序,要么他们和你处境相同,可以分享个人建议
  • 你的家人:我的父亲可能不是最有帮助的校对者,他把我送回了“我确信没有进一步的评论。”我的初稿和终稿几乎毫无共同之处。但是你的家人仍然会很高兴阅读你的文章,并给你许多鼓励!

我花了大部分时间编辑我文章的每个细节,直到我没有别的东西可以修改了。此外,我的初稿看起来一点也不像我的终稿。这就是为什么我强烈建议尽快开始制定你的 SoP,以便给其他人留出时间阅读并给你多方面的反馈:)

结尾注释

SoP 一开始可能看起来令人生畏,它确实花费了大量的工作,但是我仍然从编写我的 SoP 中获得了很多乐趣!这是一次很好的锻炼,可以让我明确自己的兴趣,组织自己的经历,并从中吸取经验教训。

这也迫使我精确地反思我的动机,甚至帮助我理解我在研究生学*中真正寻找的是什么。我甚至准备申请一些项目,在那里我甚至获得了推荐信,但是在写我的 SoP 时,我意识到这不是我想要的,我最终放弃了我的申请。

统计(应用时):

  • 学校:理工学院
  • 学位:理学学士,数学-计算机科学双学位
  • 平均绩点: 4.09/4.0 以上
  • GRE: 定量 170/170,口语 169/170,分析写作 5.5/6
  • 工作经历: 1 暑期在一家初创企业实*
  • 研究经历:撰写或发表论文 0 篇
  • 课外活动:很多

接受:

  • 卡内基梅隆大学(机器学*理学硕士、语言技术硕士)
  • 斯坦福大学(计算机科学理学硕士)
  • 加州大学柏克莱分校(EECS 工程硕士)
  • 哥伦比亚大学(计算机科学硕士)
  • 马萨诸塞大学阿姆赫斯特分校(计算机科学硕士)

拒绝:

  • 伊利诺伊大学厄巴纳-香槟分校(计算机科学硕士)
  • 南加州大学(计算机科学理学硕士)(列入候选名单后被拒)

我有很好的学*成绩,但我主要是因为缺乏工作/研究经验而感到害怕。我认为我的 SoP 和我的推荐信帮助我克服了这个困难,因为它们显示了我对研究生学*的潜力和热情!

如果我错过了任何提示,请告诉我,如果您有任何问题,欢迎联系 TwitterLinkedIn )

附注:我承诺攻读卡内基梅隆大学的语言技术硕士学位,在那里我将从事多语言 NLP 研究!

如何撰写一份成功的数据科学简历

原文:https://towardsdatascience.com/how-to-write-a-winning-data-science-resume-aa8a60698456?source=collection_archive---------15-----------------------

…吸引脸书、谷歌、苹果和微软等公司。

亚历克斯·哈尼在Unsplash【1】上的照片。

目录

  1. 介绍
  2. 美学的
  3. 目标
  4. 经历
  5. 技能
  6. 教育/课外活动
  7. 摘要
  8. 参考

介绍

吸引顶级科技公司不仅极其困难,而且令人生畏。然而,我在这里告诉你,你确实可以做到,你可以抓住“ FAAMG ”的眼睛——那就是脸书、亚马逊、苹果、微软和谷歌。这并不是说你改进后的简历不会吸引其他科技公司和创业公司。

这篇文章的主题不是围绕你需要改变你的未来,而是你需要做些什么来更好地推销你的过去。就业市场上有很多合格的数据科学家,有些人可能根本不适合这些公司的职位,因为他们不知所措,不相信自己的工作,更重要的是,不相信自己。对于生活中的大多数事情,自信是关键。更重要的是,提升自信的技能。然而,就你的简历而言,你需要以一种简短而详细的方式来阐述你的技能。当你提到你的过去时,很容易假设雇主会知道你一直在做什么,但你需要专注于你在任何公司都做了什么。

下面,我会给你五种方法来改善你的简历,这样你就可以吸引顶级科技公司。

美学的

让我们从简历的非技术性改进开始。虽然这一点对于你吸引公司关注你的简历来说似乎可以忽略不计,但事实恰恰相反。可以这么说,大多数人点击一篇文章或博客是因为它的主要图片、标题,或者点击一个有着诱人但神秘的缩略图的 YouTube 视频。

简历中你工作的视觉表现不应该被忽视,这是有原因的。

听起来很老套,不合群,脱颖而出。想象一下,你是一名技术招聘人员,你每天会看到几百次同样平淡无奇的黑白墨水简历。什么会先吸引你?这将是你简历的美感、布局和独特之处。就像形成自己的数据科学品牌一样,你应该专注于品牌化你的简历。作为一名雇主,你可以考虑聘用那些在专业但有创意的简历中投入工作的人,而不是其他人,因为这将是他们对你的第一印象。

让我们看看我的。

像这样在网上发布我自己的简历是脆弱和可怕的,我相信它会向你展示你不需要成为一名 UX/用户界面设计师就能获得创造性的成功,但是比别人多一点创造性总是好的——任何人都可以这样做,只需要一点重新安排和组织(或者你可以使用预制的模板——但我更喜欢自制的版本——你的自制版本)。好的,是的,我的这个版本有一点改动(具体来说,就是最*角色的文本和他们各自的公司名称)。然而,它的布局和我最初的简历是一样的,还有标题、主要部分的标题、日期、目标和技能。下面来看看吧。

作者截图和文档[2]。

那么这份简历有什么了不起的呢?了解原因的最简单的方法是它很突出。它可能不是最好的或最有创意的,但它是我创造的符合我个性的东西。你想在符合你个性的公司找到一份工作。如果一家公司因为你的简历是蓝色的而不高兴,那么他们可能不适合你——反之亦然,也可以反过来说。当我在 LinkedIn 上发布这份简历,并在他们的网站上申请工作时,我感到紧张、脆弱和与众不同。在提交之前,我问了几个朋友他们的想法,有些人喜欢,有些人不喜欢。

没有完美的简历,但有更好的方式展示你的工作。

我相信我的直觉,想展示我的独创性。就像我的朋友一样,一些公司不喜欢我不拘一格的简历。然而,一些公司喜欢它,并指出(这些公司大多是 FAAMG 公司),以及其他知名的大型科技公司。对我来说,这是值得一提的——这些成功的公司有很多数据科学家想去工作,欣赏创造力和个性——它得到了回报。

有争议的是,我的简历有两页。我已经听过很多次“一页长”的规则,但是只有 1%的雇主会询问简历的长度。如果你拥有它,炫耀它。向雇主展示你为达到这一步付出了多少难以置信的努力。如果他们会看你一整页的简历,他们很可能也会看你 1.68 页的简历。如果没有,那么他们很可能不会给你机会。如果你认为简历需要两页纸,那就写两页。

总而言之,简历的美感在申请过程中会有很大的影响。当然,选择最终取决于你如何设计你的布局和外观。

以下是关于你简历美感的关键提示

* find something unique about you and apply it to your resume* organize the layout in a way that lets the reader focus on each section separately* group your thoughts and work into sections: goal, experiences, skills, education, and extracurricular/awards. * give some breaks between sections so that the eyes can rest (just like how I made these points with a dark background)* tell a story with your layout: what do you want? what have you done? how did you get there?

目标

事实上,我收到了一位前脸书员工的一些建议,每当我更新我的简历或让别人知道他们的简历应该先写什么时,这位员工就一直跟着我。该部分是“目标部分。改善你的简历的一个好方法是包括这个目标部分,因为它向雇主展示了你在寻找什么,几乎回答了面试官经常问的“你希望在五年内做什么”的问题。这表明你在提前思考,有计划。此外,这会让招聘人员和/或雇主马上知道你是否合适。

目标部分应该包括你正在寻找的角色,你可以在这里具体说明。所以在我的博客里,我写的是数据科学家,但是你可以写“寻找数据科学中的自然语言处理角色。确保包括你为什么从事数据科学,以及你想用它做什么。您还可以包含一些重要的链接或用户名,这些链接或用户名指向数据科学中常用的平台。比如我链接了我的 GitHub 和博客用户名。令人惊讶的是,许多雇主指出,很高兴看到他们可以在哪里获得更多与数据科学相关的信息。

以下是改进这一目标部分的主要方法:

  • 你想找什么样的角色?
  • 你想要什么样的角色?
  • 在企业中,你将如何处理这个角色?
  • 关于您的数据科学知识的其他链接或信息

经历

简历中最重要的部分是经历部分。当然,尽量避免段落重叠。但是,在必要的地方加入更长的句子。如果你太短,对于第一次看这个项目的人来说,它可能没有那么大的吸引力——额外的几句话就可以了。

当我在简历上的每个公司的经历部分写下要点时,我总是坚持同样的规则。这条规则包括三个简单明了的要点。第一点是概述你使用的工具或编程语言。第二点是突出你实际做了什么。最后,第三点是阐明你所做的结果。那么,总的来说,你用什么来完成这个项目,它的结果是什么?例如,“利用 Jupyter 笔记本中的 Python 创建决策树分类器,帮助将手动分类过程自动化 50% ”。我真的认为这种解释你在每个主要项目中的经历的方法是吸引雇主的最好方法。它会以最快的方式向雇主、潜在的同事和利益相关者展示你对商业问题的影响。这是数据科学的基础;通过使用独特的工具解决复杂的问题来帮助业务。

你应该确保在你的经历部分包含的其他信息是公司、职位和日期。例如,'【2018 年 8 月至今在谷歌的数据科学家。

以下是总结的提升你的经验的关键方法部分:

  • 你用了什么?
  • 你做了什么?
  • 结果如何?

技能

又短又甜。这一部分是显而易见的。您将简单地列出您在数据科学中使用的所有最常用的技能。请记住,您可能希望包括像 Microsoft Office 这样的简单技能,因为,尽管这对您来说似乎是隐含的,但您不应该假设招聘人员已经了解这些知识。同样,根据你想成为的数据科学家的类型,有些技能应该比其他技能更突出。例如,如果你想专注于商业智能和产品管理数据科学,你会突出 SQL、吉拉和 Confluence。相反,如果你想吸引更多的机器学*数据科学,突出像 GCP,气流和 Kubernetes 这样的技能。此外,如果你想更突出一点,确保你的技能看起来很好,有一些模式。

以下是总结的提高技能的关键方法部分:

  • 适用于数据科学类型的技能
  • 包括非常具体的
  • 而且还有一些非常通用的技能

教育/课外活动

与技能部分一样,教育部分不需要很长。包括你的大学本科学位和研究生学位,以及他们的日期,如专业,辅修专业和专业。如果你是一名初级的数据科学家,你可能需要附上你的 GPA。

除了教育,还有课外活动。在这个部分,你还可以包含你的 GitHub 信息或类似的项目共享站点。您还可以概述您的专业、职业数据科学经验之外的关键项目。

如果你没有任何正式的、专业的数据科学经验,那么在“经验”部分列出那些相同的外部数据科学项目。

这些项目的例子包括完成教程、证书、训练营或在线课程(如 Kaggle 数据科学课程)。

以下是总结出的提高你的学历/课外活动的主要方法

  • 包括本科和研究生学位(如果适用)
  • 保持简洁明了
  • 突出你所完成的独特项目和证书

摘要

paweczerwińskiUnsplash 上拍摄的照片。

如果您在本文中已经讲到这里,谢谢您。我想给数据科学家最适用、最简单的建议,让他们能在自己梦想的公司找到工作。我在你的简历中加入了美学、目标、经历、技能和教育/课外活动方面的改进。虽然我不能保证找到工作,但我确实认为你会改善你的简历,并有希望吸引你的梦想工作。

再一次,有保留地接受我的建议。我这篇文章的目的不仅是给你简历中这些主要部分的建议,也是给你灵感和动力,让你自己想出新点子。总而言之,你应该专注于做你自己,突出你职业生涯中最自豪的成就(因为你的面试官会挑选你要面试的项目,所以要充分了解它们),找到一些独特和有创意的东西,让你的简历脱颖而出。

我可以证明我的简历截图是我的,并且已经得到了谷歌、苹果、脸书和微软等顶级公司的关注。请记住,还有其他优秀的公司。仅仅因为一家公司不是这些更大的科技公司之一,并不意味着它的价值更低,一家不同的公司可能会更有趣,更有益于体验。最终,在吸引公司之后的下一步是面试。我已经写了几篇关于数据科学和面试过程的文章,如果你想看看,现在就链接一篇,它指的是数据科学和数据分析面试过程中的共同相似之处和不同之处[4]:

[## 数据科学家 vs 数据分析师面试。区别就在这里。

面试指南。

towardsdatascience.com](/data-scientist-vs-data-analyst-interview-heres-the-difference-4315f8306ad3)

我希望你觉得我的文章有趣且有用。祝你简历之旅和数据科学事业好运。欢迎在下面评论。感谢您的阅读!

参考

[1]Alex Haney 在 Unsplash 上拍摄的照片,(2019)

[2] M.Przybyla,简历截图,(2020)

[3]2018 年paweczerwi324skiUnsplash 上拍摄的照片

[4] M.Przybyla,数据科学家 vs 数据分析师访谈。区别就在这里。(2020 年)

如何用 Pandas 编写所有的 SQL 查询

原文:https://towardsdatascience.com/how-to-write-all-of-your-sql-queries-in-pandas-449dd8b2c94e?source=collection_archive---------24-----------------------

一个全面的 SQL 到熊猫字典

伊洛娜·弗罗利希在 Unsplash 上的照片

介绍

SQL 之所以如此神奇,是因为它太容易学了——之所以这么容易学,是因为代码语法太直观了。

另一方面,Pandas 就不那么直观了,尤其是如果你像我一样先从 SQL 开始。

就个人而言,我发现真正有帮助的是思考如何在 SQL 中操作我的数据,然后在 Pandas 中复制它。所以,如果你想更精通熊猫,我强烈建议你也采用这种方法。

因此,这篇文章作为一个备忘单,字典,指南,无论你怎么称呼它,以便你在使用熊猫时可以参考。

说到这里,让我们开始吧!

目录

  1. 选择行
  2. 组合表格
  3. 过滤表格
  4. 排序值
  5. 聚合函数

1.选择行

SELECT * FROM

如果您想选择整个表格,只需调用表格的名称:

**# SQL**
SELECT * FROM table_df**# Pandas**
table_df

从中选择 a、b

如果要从表格中选择特定的列,请在双括号中列出所需的列:

**# SQL**
SELECT column_a, column_b FROM table_df**# Pandas**
table_df[['column_a', 'column_b']]

选择不同

简单地使用。drop_duplicates() 获取不同的值:

**# SQL**
SELECT DISTINCT column_a FROM table_df**# Pandas**
table_df['column_a'].drop_duplicates()

选择 a 作为 b

如果你想重命名一个列,使用。rename() :

**# SQL**
SELECT column_a as Apple, column_b as Banana FROM table_df**# Pandas**
table_df[['column_a', 'column_b']].rename(columns={'column_a':
'Apple', 'column_b':'Banana'})

选择案例时间

对于 SELECT CASE WHEN 的等效项,可以使用 np.select(),首先指定您的选择以及每个选择的值。

如果您想在每个选项中包含多个条件,请查看本文。

**# SQL**
SELECT CASE WHEN column_a > 30 THEN "Large"
            WHEN column_a <= 30 THEN "Small"
            END AS Size
FROM table_df**# Pandas**
conditions = [table_df['column_a']>30, table_df['column_b']<=30]
choices = ['Large', 'Small']
table_df['Size'] = np.select(conditions, choices)

2.组合表格

内/左/右连接

简单用。merge() 要连接表,可以使用“how”参数指定是左连接、右连接、内连接还是外连接。

**# SQL**
SELECT * FROM table_1 t1
         LEFT JOIN table_2 t1 on t1.lkey = t2.rkey **# Pandas** table_1.merge(table_2, left_on='lkey', right_on='rkey', how='left')

联合所有

只需使用 pd.concat() :

**# SQL** SELECT * FROM table_1UNION ALLSELECT * FROM table_2**# Pandas** final_table = pd.concat([table_1, table_2])

3.过滤表格

选择位置

当像在 SQL 中使用 WHERE 子句一样过滤数据帧时,只需在方括号中定义标准:

**# SQL** SELECT * FROM table_df WHERE column_a = 1**# Pandas** table_df[table_df['column_a'] == 1]

SELECT column_a WHERE column_b

当您想要从表中选择某一列并使用不同的列对其进行过滤时,请遵循以下格式(如果您想要了解更多信息,请查看此链接):

**# SQL** SELECT column_a FROM table_df WHERE column_b = 1**# Pandas** table_df[table_df['column_b']==1]['column_a']

选择地点和

如果要按多个条件进行筛选,只需将每个条件用括号括起来,并用' & '分隔每个条件。更多的变化,请查看这个链接

**# SQL** SELECT * FROM table_df WHERE column_a = 1 AND column_b = 2**# Pandas** table_df[(table_df['column_a']==1) & (table_df['column_b']==2)]

选择喜欢的地方

SQL 中 LIKE 的对等词是 .str.contains() 。如果您想应用不区分大小写,只需在参数中添加 case=False(参见这里的)。

**# SQL** SELECT * FROM table_df WHERE column_a LIKE '%ball%'**# Pandas** table_df[table_df['column_a'].str.contains('ball')]

在()中选择 WHERE 列

SQL 中 IN()的对等词是。isin()

**# SQL** SELECT * FROM table_df WHERE column_a IN('Canada', 'USA')**# Pandas** table_df[table_df['column_a'].isin(['Canada', 'USA'])]

4.排序值

按一列排序

SQL 中 ORDER BY 的对等词是。sort_values() 。使用' ascending '参数指定是要按升序还是降序对值进行排序,默认情况下是像 SQL 一样按升序排序。

**# SQL** SELECT * FROM table_df ORDER BY column_a DESC**# Pandas** table_df.sort_values('column_a', ascending=False)

按多列排序

如果要按多列排序,请在括号中列出列,并在括号中的“升序”参数中指定排序方向。请确保遵循您列出的各个列的顺序。

**# SQL** SELECT * FROM table_df ORDER BY column_a DESC, column_b ASC**# Pandas** table_df.sort_values(['column_a', 'column_b'], ascending=[False, True])

5.聚合函数

非重复计数

您会注意到聚合函数的一个常见模式。

要复制 COUNT DISTINCT,只需使用。groupby()和。努尼克()。更多信息请参见此处的:

**# SQL** SELECT column_a, COUNT DISTINCT(ID) 
FROM table_df
GROUP BY column_a**# Pandas** table_df.groupby('column_a')['ID'].nunique()

总和

**# SQL** SELECT column_a, SUM(revenue) 
FROM table_df
GROUP BY column_a **# Pandas** table_df.groupby(['column_a', 'revenue']).sum()

AVG

**# SQL** SELECT column_a, AVG(revenue) 
FROM table_df
GROUP BY column_a**# Pandas** table_df.groupby('column_a')['revenue'].mean()

感谢阅读!

希望这可以作为使用 Pandas 操作数据的有用指南。也不要觉得你必须记住所有这些!当我和熊猫一起工作时,这是我经常想起的事情。

最终,通过足够的练*,你会对熊猫感到更加舒适,并且会充分理解其中的基本机制,而不需要依赖像这样的小抄。

一如既往,我祝你在努力中一切顺利!😃

不确定接下来要读什么?我为你挑选了另一篇文章:

[## 完整的熊猫数据科学术语表

学*熊猫基础知识的最佳资源

towardsdatascience.com](/a-complete-pandas-glossary-for-data-science-a3bdd37febeb)

特伦斯·申

如何为 algotrade 比特币编写高级趋势跟踪策略

原文:https://towardsdatascience.com/how-to-write-an-advanced-trend-following-strategy-to-algotrade-bitcoin-a38e47443ddc?source=collection_archive---------47-----------------------

趋势跟踪不再困难

照片由 Katerina Limpitsouni 拍摄

无论是开始算法交易还是盈利,趋势跟踪都是最容易的。在上一篇文章中,我写了一个趋势跟踪策略,通过使用更大的时间框架来确定趋势,甚至提高了它的性能。但这是一个简单的立即进入和立即退出的策略。

本教程的重点是让你从 Jesse 的一些特性开始,这些特性可以帮助你写出你会发现的大多数趋势跟踪策略。这些特征中很少是:

  • 分两点退出交易,一点是固定价格,另一点是动态价格。
  • 退出一半仓位后将止损更新为盈亏平衡。
  • 过滤盈亏比不好的交易。
  • 利用事件与交易的生命周期挂钩。

首先,我用make-strategy命令创建一个新策略:

jesse make-strategy TrendFollowingStrategy

我编辑我的routes.py文件来使用这个策略,我把时间范围设置为4h:

然后我打开新创建的策略文件,它看起来像这样:

进入规则

我想去很久,当:

  • 我们处于上升趋势中(反之亦然)
  • 收盘(当前)蜡烛线触及 50 均线

他们说一张图片抵得上 1000 个单词,所以这里有一张图片显示了我认为的上升趋势:

这就是我所说的当前蜡烛碰到 50 均线的意思(橙色线是 50 均线):

现在让我们为current_candle_touches_long_ematrend写代码:

我用三根均线来确定趋势方向。我返回1表示上涨趋势,返回-1表示下跌趋势。current_candle_touches_long_ema很简单,我只要确保当前蜡烛线的高价大于long_ema线(周期为 50 的均线)并且当前蜡烛线的低价低于long_ema线。

设置进场价格和仓位大小

对于多头交易,进场价格将是当前蜡烛线的最高点。止损价格将是当前 ATR 的 3 倍,距离我的进场价格。

在这个策略中,我想一次进场交易,但在两点出场。我将在趋势的前一个高点退出我的前半部分头寸。这里是我所说的上升趋势的高点(蓝线是我的目标):

为了对此进行编码,我首先选择最后 20 根蜡烛线的最高价格。然后返回其中的最大值。

对于头寸规模,我想在每笔交易中用我总资本的 5%来冒险。为了计算qty,我使用了risk_to_qty实用程序。

当然,短线交易的情况正好相反。代码如下:

将止损转为盈亏平衡

正如你所看到的,我只是以获利价格退出了我一半的仓位。换句话说,在我的仓位降低后,我想移动我的止损价格以达到盈亏平衡。为了在 Jesse 中编写代码,我将使用内置的 on_reduced_position 方法。

更新self.stop_loss是我告诉杰西更新我的止损单所需要做的。Jesse 自动选择它,取消之前的止损单,并提交新的止损单。这再简单不过了!

要了解关于事件的更多信息并查看 Jesse 中所有可用事件方法的列表,请务必阅读其文档

动态退出我交易的后半部分

对于这个策略,我打算在动态的情况下退出我的后半部分头寸。这种情况背后的想法是,当价格高度超买,即将进行严重的修正时退出。用 quant 的语言来说,我想在 RSI 指标达到 80 以上的时候退出。

首先,我将使用内置的update_position()方法来编写我的逻辑。只有当我们有一个未结头寸时,这个方法才会在每根新蜡烛线后执行。因此,它用于更新位置。也就是说我们不需要检查这个职位是否空缺。

这里要考虑的下一件事是,我只想退出我的后半部分头寸。换句话说,我想平仓,如果它已经减少。检查我的头寸是否已经减少的最简单的方法是使用内置的 is_reduced 属性和清算()方法。

使用过滤器

到目前为止,我的策略看起来不错,让我们进行一次回溯测试,看看效果如何:

jesse backtest 2019-01-01 2020-05-01

经过大约 4%的回溯测试后,我得到一个错误:

Uncaught Exception: InvalidStrategy: take-profit(3601.6) must be below entry-price(3601.6) in a short position

错误是试图告诉我们,在某一点上,我们的策略的获利和进场价格相等(3601.6 美元),这是不可接受的。这是一个很难调试的问题,但是在编写了最初的几个策略之后,你会很擅长和 Jesse 一起调试。

为了解释为什么会出现这个问题,我们需要再看一下获利和进场交易:

这个错误告诉我们,进场和获利在某些时候是相同的。这意味着,在这一点上,当前的蜡烛线是过去 20 根棒线中最高的。这不是我们在这个策略中想要的交易类型。

我们可以通过在我们的should_long方法中使用一些肮脏的 if-else 语句,或者通过使用一个专为这类情况设计的过滤器来防止这种情况发生。

过滤器只是一个返回布尔值的函数。通过返回一个True值来传递一个过滤器,反之亦然。我定义了一个过滤器,并命名为reward_to_risk_filter。这个名字可以是任何东西,但是用单词filter开始或结束一个过滤方法的名字通常是一个好的*惯。这个过滤器的工作是确保我们试图进入的交易是值得的。

在这一点上,杰西仍然不知道reward_to_risk_filter()是一个过滤器。为了让它识别我的过滤器,我需要将它添加到filters()方法中,这是一个返回 Python 列表的内置方法:

现在我将把reward_to_risk_filter作为一个变量添加到返回列表中。这意味着它的末尾不能有括号:

现在让我们再执行一次回溯测试:

jesse backtest 2019-01-01 2020-05-01

这次一切顺利。

结论

你的策略越简单,就越容易调试它们,甚至随着时间的推移改进它们。

和杰西一起写策略就像手动交易你的策略一样简单。所以下一次你在交易书上或者交易大师那里发现一个策略时,就写下代码,并进行回溯测试。

为了获得我未来的作品和产品,请务必订阅杰西的时事通讯,并查看论坛与像你我这样的量化分析师讨论算法交易。

原载于https://jesse-ai.com

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

如何写一篇精彩的自述

原文:https://towardsdatascience.com/how-to-write-an-awesome-readme-68bf4be91f8b?source=collection_archive---------24-----------------------

一个全面的指南写自述,脱颖而出,使人去哇!

照片由 Pixabay 拍摄

如果你很急,只想让模板跳到底部(不酷)。

其余的人准备好迈出成为自述大师的第一步吧!(绝对不是 clickbait)。

你刚刚创建了这个很棒的项目,并在 GitHub 上分享了它。你认为现在你可以坐以待毙,等着世界告诉你你的项目有多酷。毕竟,在过去的一个月里,你在这个极具挑战性的项目上不知疲倦地工作,对吗?

好吧,让我们后退一步,从检查你的项目的开发者或用户的角度来看。尽管你知道你的项目有多酷,知道它将如何解决一个尚未解决的紧迫问题(直到你出现),但这个人会看着你的项目,想知道你到底做了什么。

如果没有人不知道如何使用你的软件,那一定是发生了非常糟糕的事情。

照片来自 imgflip

如果人们不知道你的软件是做什么的,那么他们不会使用它或为它做贡献,他们很可能会在开源软件的海洋中找到更清晰和简洁的东西。

这就是自述文件的用武之地!

一份好的自述文件就像是你项目的门面。这是人们在你的项目中看到的第一样东西,它给他们一个非常简短的对你的软件的介绍。

自述开始来自我的NSFW滤镜项目

一个好看且有帮助的自述文件可以使您的项目脱颖而出,并吸引开发人员社区的注意。

这将有助于他们理解你的项目,他们如何让项目运转起来,以及为什么他们应该做出贡献。

“哇,老兄!说得好!如果你知道这么多东西,为什么不告诉我们怎么写呢…”

嘿,我不能告诉你有一套具体的规则,你应该遵守这些规则,不要为了一个好的自述而摇摆不定。

那样工作。

我将分享我如何为我的开源项目写自述文件,以及你在为你的项目写自述文件时应该考虑的事情,你将(希望)能够获得一些见解。

还有,记住你不会一天就成为自述大师。像所有的事情一样,需要练*

我为开源做贡献已经有一段时间了,我注意到所有伟大的项目都有一个棒极了的自述文件。

您进入了项目页面,几分钟后您就可以启动并运行您的项目版本。

有许多贡献者,许多请求更新版本被频繁发布,它们都有一个令人敬畏的自述文件的共同因素。

一个新的开发者将能够找到所有的细节开始像安装说明贡献指南

一个新用户将能够通过信息截图演示找到这个项目是如何被使用的。

“我没时间说这个,给我看看自述文件吧!”

好吧,好吧,好吧(抱歉我走得有点麦康纳)。

这里是我的项目 NSFW 滤镜自述文件。我认为这是我写的最好的自述。

[## 纳文杜-波特卡特/nsfw-过滤器

从网站过滤 NSFW 图片的网络扩展。它使用 TensorFlow JS-一个机器学*框架-来…

github.com](https://github.com/navendu-pottekkat/nsfw-filter)

我将浏览自述文件的不同部分,我认为对每个自述文件都是必不可少的。

这里是本例中使用的自述文件的链接。您还可以找到一个 模板自述文件,您可以直接将其复制并粘贴到您的项目中。

[## navendu-pottekkat/awesome-readme

项目标题应该不言自明,尽量不要弄得拗口。(尽管存在例外情况……

github.com](https://github.com/navendu-pottekkat/awesome-readme/blob/master/README.md)

好吧,那就结束了。

我用这些来自自述老师 ( 新推特手柄预警)的临别赠言(智慧)告别我的蚂蚱!)。

照片来自 imgflip

如何撰写和发表研究论文

原文:https://towardsdatascience.com/how-to-write-and-publish-a-research-paper-3692550a5c5d?source=collection_archive---------31-----------------------

我希望在写和发表我的研究论文之前阅读的文章

你目前正在攻读博士学位。或者将来有兴趣做。你可能即将发表一篇科学论文,或者只是对发表你的作品感到好奇。

在这个博客里,我写了我写论文的经历。我与你分享我在科研生涯中学到的技巧和经验。我在顶级 IEEE 会议和期刊上写了+7 篇文章(IEEE Transaction on Image Processing)(EUS ipco,WOSSPA,GRETSI,GDR-ISIS,…)。我还撰写了一篇发表在天文学&天体物理学的期刊论文。你可以在我的谷歌学术个人资料或 ResearchGate 个人资料中找到我的出版物列表。

我把这个博客分成两个不同的类别,没有特定的顺序:

  • 与出版物需要做的事情相关的非技术部分
  • 与研究相关的技术部分

🅛🅔🅣’🅢 🅖🅞

非技术部分

📝正确的纸张格式

你需要为你的论文选择合适的格式。出版物有很多种,如会议或期刊、信件、评论、会议或期刊文章。根据您的研究阶段或您正在展示的信息水平,其中一个可能比另一个更适合您的工作,以评估您想要传达的信息并选择您的格式。

🔎选择会议

如果你想提交一份会议论文,你需要选择哪一种信心,要知道这是一个你必须参加的活动。有很多会议,取决于你的研究领域,每个会议都有自己的地点和日期。所以一定要了解你所在领域的顶级会议,这很重要。如果你是博士生,不要犹豫和你的导师交流,他们通常已经有了入围的会议名单。

细节很重要

一旦你选择了会议,你需要注意并阅读关于截止日期、地点、作者指南、电话和提交指南以及价格的所有细节。

⚠️Yes,你必须付费才能在同行评议的期刊/会议上发表你的作品。有一个免费的出版物平台(像 Medium),或者像 arXiv 这样的开源平台,但是没有同行评审。当然,如果是会议论文,不要忘记支付出版费和注册费+酒店。

⏳最后期限

关于截止日期的重要几点,首先,你不想错过!。其次,很明显,你想在截止日期前提交。通常情况下,作者会对提交的论文进行修改,这种情况经常发生,或者更新内容。知道你有可能在提交截止日期前对提交的版本进行修改。

💡你越早提交论文越好,给自己一些安慰,不要等到最后一天才提交,以免出现意外。

纸质 PDF 模板套件

大多数会议和期刊都提供模板工具包来生成最终的 PDF 论文。它通常以两种格式提出:Latex 的 Microsoft word。下载模板工具包并开始编辑内容。我确保你尊重格式的规则(大小,字体,警察,引文,表格,…)。

编辑工具

我真的推荐使用 latex,尽管与 Microsoft word 相比它很痛苦,但是相信我,使用 latex 生成的 PDF 质量非常好。

💡我建议用 TexStudio 来编辑你的论文,在我看来这是最好的之一。

TexStudio

要准备的其他材料

被接受的会议论文必须在会议当天提交。一般来说,有两种方式来展示你的作品:

1-展示海报

或者在观众面前演讲

在这两种情况下,你都必须准备一份额外的材料来总结你的工作,可以是海报或幻灯片,这是会议委员会所做的决定。

期刊论文除外

关于期刊论文,程序略有不同。一般来说,没有事件发生,所以没有截止日期,也没有事件日期。你可以随时提交期刊论文。只要确保你的研究没有过时。

技术部分

🚀开始写作之前

写作前问一些问题会帮助你理解你的工作,并更好地向他人解释,例如

  • 这是一个重要的问题吗?
  • 收集和分析的数据对更广泛的社区有意义吗?
  • 过去做了什么?
  • 解释为什么解决它很重要?

首先,你需要选择一个你想解决的问题。你一定是具体的,不然干嘛还要费神去读博。!严肃地说,不要在别人已经解决的特定问题上工作。

📎文献综述

了解其他研究人员为解决你想要解决的问题做了什么是关键。以前的方法有什么优势和局限性,这在你的步骤中非常重要和关键,因为对另一个人来说,你的研究是相关的,你需要向读者或负责你工作的大学委员会展示和说服你的贡献是值得的,你正在提议可变的研究

⚠️为了这一步,拖延症将试图成为你最亲密的朋友。只是意识到这一点,不接受它作为朋友。

💡我建议用门德利来管理你的推荐人。简单易用,您可以在手机、PC 或浏览器上使用它。

门德利

这一步将定义你工作的基础,所以你将从实施一些方法开始,并了解已经做了什么,有什么限制,正如我之前所说的,从那时起你将发现还没有做什么,有时在其他研究中, 研究人员强调了他们想做什么和他们不能做什么。也许这会给你一个想法,从经验中开始,那些掌握了这一步的人会很容易进入下一步,那些没有掌握的人会很困难,我们将不得不在他们论文的结尾做这项工作。

🔧发展手稿:结果和写论文哪个更重要?

从写论文到出结果

你可以从写论文开始,随着研究的深入,在空白处填入内容。在这种情况下,这篇论文将推动你的研究,推动你的工作向前发展,这是一种以英语为母语的方法。

填空让你思考题目,问自己一些问题,比如我想说的题目是什么?以前做过什么?我应该提出哪种策略或方法?诸如此类。

从结果到写论文

或者你可以遵循法语的方法,这种方法包括首先关注结果,然后写论文。这种方法最适用于已经了解主题并且问题已经解决的人。一旦有了结果,他就可以开始写论文了。下一个任务将是证明一个论点,并试图融入文献中的研究。

这里没有好的或错误的策略,它们都非常有效,只需选择一种方法并坚持下去。

💡如果你是博士。学生,不要犹豫和你的导师讨论这个问题。他们会指导你,带你完成博士学位。

📌从哪里开始写?

科技文章通常遵循以下格式:

  • 摘要
  • 简介
  • 之前的研究
  • 问题公式化
  • 模型或方法和结果
  • 结论
  • 参考文献
  • 致谢

你论文的每一部分在向读者解释为什么你的研究提出了一个新的重要问题,以前已经做了什么,以及你的研究如何实质性地推进你的领域中扮演着不同的角色。

💡我建议你按照这个顺序:先把问题公式化,然后写你用来解决问题的方法,接着是结果。接下来,你回到引言,然后是你的结论。摘要应该写在最后。

在你起草完所有的章节后,你应该重温你的标题和作者列表,以确保它准确地代表了你的最终作品。致谢和参考文献可以在文章写完后完成。

🗣投稿& 同行评审

与你的合作者一起重复修改和更正。迭代越多越好。随着时间的推移,你会收敛到论文的最终版本。此外,让你的朋友或同事审阅论文。可能会有一些你看不到的错误。你擅长提交论文。

💡记住,在提交论文之前,一定要和你的合作者反复讨论。你必须得到他们的同意,以避免可能发生的误解或混乱。

结论和带走

从我的个人经验来看,我可以告诉你,在写作时凌乱是正常的,知道那是可以的,那是不可避免的。不要不知所措。保持一致,不要忘记给自己一个喘息的机会🙂。你需要在你的写作程序中建立足够的秩序,以便能够向前推进。

好了,我希望你能从这篇博客中获得一些价值,并在你的下一篇论文中受益。💯

不溅

下一步做什么

  • 请在评论区告诉我你的想法,或者直接在 LinkedIn 上给我发消息。
  • 你采取了什么方法?
  • 什么对你最有效?

如何在介质上编写和渲染 LaTeX 数学公式

原文:https://towardsdatascience.com/how-to-write-and-render-latex-math-formulas-on-medium-7165c2dcc54c?source=collection_archive---------23-----------------------

在这篇文章中,我们列出了一些在介质上书写和可视化数学公式的方法:LaTeX 到 image,unicode 转换,浏览器插件等。

安托万·道特里在 Unsplash 上拍摄的照片

每天,许多从业者通过在媒体上创建内容来分享技术教程和发现。然而,张贴带有数学公式的文章(例如用 LaTeX 写的方程式)是一件困难的事情,因为它在媒体上不受支持。最常见的解决方法是将你的公式转换成图片并添加到文章中。你可以对一个渲染的 PDF 文件进行截图,或者使用在线 LaTeX 编辑器,比如 CodeCogs

图片作者。在线 LaTeX 编辑器。

包含本文所附公式的图像将显示为:

这是在 Medium 上发布时添加数学公式的最简单的策略,但它不灵活,并且不适用于内嵌方程。

类似的方法包括使用数学公式创建 Jupyter 笔记本降价,并将笔记本上传到GitHub Gist

图片作者。GitHub Gist 包含一个准备嵌入介质的乳胶配方。

然后,复制介质上的共享链接,结果是:

作者笔记。包含 LaTeX 公式的嵌入式 GitHub gist 示例。

老实说,这不是很花哨。

另一种在介质上添加乳胶配方的方法是使用 TeX 到 Unicode Chrome Addon 到转换乳胶代码到 Unicode 。一旦安装了插件,只需选择你想转换的 LaTeX 代码,例如

\alpha : \mathbb{R} \to \mathbb{R}

按 Alt+W(您可以在配置中更改快捷键),您应该会得到等式的 unicode 版本:

α : ℝ → ℝ

这种方法不依赖于图像或嵌入对象,它可以内联工作,但在字符和布局转换方面也有限制。例如,上面的例子

(\cos x + \sin x)^2 =
    \underbrace{\cos^2 x + \sin^2 x}_{1} +
    \overbrace{2 \sin x \cos x}^{\sin 2x}

被转换成

(\cos x + \sin x)² =
    \underbrace{\cos² x + \sin² x}₁ +
    \overbrace{2 \sin x \cos x}^{\sin 2x}

当公式有点复杂时不是很有用。

最后一种在媒体上呈现数学公式的方法需要在创作者和读者的浏览器上都安装一个 Chome addon 。该插件被称为数学无处不在,它应该渲染任何页面上的每一个 MathML/LaTeX 公式,也在媒体之外。在编辑过程中,你只需要把你的公式放在适当的分隔符中,如美元符号(插件应该关闭),在阅读过程中,一旦激活插件,方程将被转换。

公式

应正确呈现:

(cosx+sinx)2=cos2x+sin2x+2sinxcosx(cos⁡x+sin⁡x)2=cos2⁡x+sin2⁡x+2sin⁡xcos⁡x(\cos x+\辛 x)2=\cos2 x+\sin^2 x+2 \辛 x \科斯 x

像α:R→Rα:R→R \ alpha:\ mathbb { R } \ to \ mathbb { R }这样的内联公式也应该可以工作。这种方法的缺点是需要读者安装插件(只有第一次)。当然,我们可以像这样在帖子的开头插入一个善意的提醒:

这个帖子包含乳胶公式。为了正确渲染它们,安装数学任意位置插件并激活它。

你知道在介质上添加数学公式的其他方法吗?请在评论中告诉我!

参考资料:

如何在介质上写数学
如何在介质上使用数学公式

联系人:LinkedIn|Twitter

如何像软件工程师一样写文章

原文:https://towardsdatascience.com/how-to-write-articles-like-a-software-engineer-d7a1857de81?source=collection_archive---------38-----------------------

有效和高效写作的缺失手册

阿里安·达尔维什在 Unsplash 上拍摄的照片

写一篇有效、高效的文章意味着什么?根据剑桥词典有两个定义:

1。高效:充分利用时间、材料或能源等资源,不浪费任何资源。

2。有效的:产生预期的结果,或(指人)有技能或有能力做好某事。

换句话说,写一篇有效的文章意味着用正确的方式写出正确的文章。鉴于我有计算机科学的背景,这听起来对我来说很熟悉。

这些定义听起来类似于您在软件工程领域经常听到的两个术语,即:

1.验证:对一个系统的测试,以证明它满足其开发的特定阶段的所有规定要求。

2.验证:确保最终产品利益相关者的真实需求和期望得到满足的活动。

简单来说,验证是关于以正确的方式构建产品,而验证是关于构建正确的产品。

我越想这些相似之处,就越想构建一个软件和写一篇文章之间的其他相似之处。

计算机科学只不过是处理和解决问题的科学。算法只不过是一个配方。这个提示列表可以被看作是一个简单的算法,用来写出有效且高效的文章。或者,如果你想从软件工程师的角度来看,只需要一个清单来验证你的文章。

本质上,这篇文章只是一个微弱的尝试,来帮助自己成为一个更好的作家。帮助我自己处理混乱的过程,不要迷失在细节中而忽略了大局。这是一个非详尽的通用提示列表,您不必一步一步地遵循。你甚至不需要同意他们所有人的观点!只拿你需要的。

虽然我写这篇文章只是为了自己,但我希望其他人也能从中受益。

1.有主意了

Unsplash 上由 Majharul Islam 拍摄的照片

"玫瑰始于花蕾,鸟儿始于蛋,森林始于种子。"马特肖纳·德里瓦约

一切从一个想法开始。不管它有多小,也不管它是关于什么的。只要你觉得值得分享。它可以是一个教程,一个个人故事,一篇书评,或者任何你喜欢写的东西。不管是什么,你应该有一种强烈的冲动把它从你的胸中拿出来。

我通常一周有几十个想法,但只有几个能坚持下来。如果某个想法在我的脑海中反复出现,我知道我必须采取行动。

你不知道吗?那你希望看到的目前不存在的是什么呢?或者你的朋友或家人有什么样的问题你可以解决?对开发软件有效的问题同样适用于写文章。只要你的想法解决了某人的问题,你就在正确的轨道上。哪怕只是你自己的问题。

以这篇文章为例。它的存在仅仅是因为我想有一种指南或清单,可以用于我未来的文章。然后我想其他人也可以从中获利。这就是了。

2.做你的研究

照片由莎拉·基利安Unsplash 拍摄

“从别人的错误中吸取教训。你不可能活得足够长,让它们都是你自己做的。”―埃莉诺·罗斯福

每当一个特定的想法打动我时,我都很兴奋,并认为世界上还没有人写过这个特定的主题。或者曾经写过这样的软件。

我最*有了一个想法,用 Python 为不同种类的媒体类型编写一个并行的 web scraper。在快速的网络搜索之后,我发现我的想法已经被很多人关注了。可能比我聪明得多的人。如果你曾经遇到过类似的情况,那么你可能也会感到气馁。

但你不应该,因为这并不意味着它的结束。这种情况一直都在发生。只能说明你遇到了现实世界的问题。一个值得已经尝试解决它的人花时间去解决的问题。这并不意味着他们的解决方案有任何好处。

脸书逐渐取代了 MySpace,尽管他们都面临着同样的问题。

根据维基百科

市场营销和战略管理中的竞争对手分析是对当前和潜在竞争对手的优势和劣势的评估。

把你的想法拿出来,看看其他人是否已经尝试过解决它。他们的解决方案好吗?从他们的错误中吸取教训,并使之变得更好。汇总他们的发现,对你最初的想法有新的见解。也许你最初的想法会演变成不同的东西。更好的东西。

用一个快速的研究会议来验证你的想法。你花在早期研究阶段的时间是一项伟大的投资,因为建造一个没人想要的东西是世界上最糟糕的感觉。

打造一个人们愿意为之付费的产品。在中等文章的具体情况下,人们不是直接用他们的钱而是用他们的阅读时间支付给你。人们想要有价值的信息作为回报。

3.创造价值

莎伦·麦卡琴Unsplash 上拍摄的照片

“努力不要成为一个成功的人,而是成为一个有价值的人。看看周围的人是如何想从生活中获得比他们投入更多的东西。一个有价值的人给予的会比他得到的多。”——阿尔伯特·爱因斯坦

不管你的想法是独一无二的还是其他人已经有了相同的想法。重要的是你的产品为用户创造价值。

当谈到媒体文章时,你必须问自己这样一个问题:有人真的会通过阅读这篇文章有所收获吗?

不要模仿别人,但也不要重新发明轮子。汇总你的研究成果,并以此为基础。让它变得更好!

读者应该渴望读到你的文章,直到最后。和他们一起玩 FOMO(害怕错过)。得到一些好的报价。人们喜欢学*新的东西。如果他们能在下一次家庭聚会上使用这些新知识来传播一些智慧,那就更好了。我在这篇文章中也是这样做的。

在增加价值的方式上要有创造性。以第 2 点中的并行 web scraper 为例。大部分提到的网页抓取库都只是命令行工具。然而,当我使用这些库来实现一个更大的、对最终客户来说易于使用的在线平台时,我突然创造了额外的价值。试着在你的文章中做同样的事情,要有创造性。

此外,想想你的产品的寿命。一个月后会过时还是一年后仍有价值?

4.第一个原型

狮式战斗机·珀奇克Unsplash 上拍摄的照片

“好故事不是写出来的。它们被重写了。” —菲利斯·惠特尼

第一个原型类似于草稿,可以用于许多目的。这可能类似于产品设计中的探索性原型设计,在创造东西的同时发现新的想法。这可能是一个概念的证明,或者是一个最低可行的产品,让你自己看看当你的想法实现时,它是否仍然有意义。

对于其他人来说,这只是为了看到他们的想法写在一个地方,以获得更清晰的画面。写下一些东西会激活不同的神经通路,而不仅仅是思考。

不管它是什么,大多数时候它都是一堆没人需要看到的脏东西。这很好。一个制陶师不是从一个成品花瓶开始,而是从一堆乱七八糟的粘土开始。你也应该这样做。允许自己写非常糟糕的内容。

每当我有一个无法摆脱的应用程序的想法时,我通常会创建一个 Github 库,并创建一个非常小的原型和一些注释。我写糟糕的代码,只是试图让它以某种方式工作。

对于一篇文章,我通常会做一些笔记,或者只是在草稿模式下写一篇中等大小的文章,然后开始写作。我的第一个笔记包括要点,例句,标题和副标题,如何组织文章,我的文章的目标是什么。这是一个烂摊子。

你可以自己选择如何完成初稿。有些人喜欢用演绎的方式来处理它,这意味着你要从更一般的到更具体的。其他人更喜欢以归纳的方式工作,这是相反的方式。你从细节转移到更一般的东西。或者两者的混合。你觉得怎样都行。

我喜欢用一个 25 分钟的番茄时段来写我的初稿,因为这让我有时间压力。在时间压力下工作支持两个重要的法则。

帕金森定律 陈述如下:

“工作扩大以填补完成它的时间”——西里尔·诺斯古德·帕金森

另一方面, 帕累托法则 (也称为 80/20 法则)指出:

"对许多事件来说,大约 80%的结果来自 20%的原因."—维尔弗雷多·帕累托

遵循这两条定律意味着我只有 25 分钟的时间来想出有价值的内容。因为我只有 25 分钟的时间,所以我更有可能只写下重要的 20%的想法,而这些想法可能对最终的产品有 80%的贡献。

此外,我不太可能走神,因为时间紧迫,我心中有一个明确的目标。

5.设定 SMART 目标

亚历山大·席默克在 Unsplash 上拍摄的照片

“如果你不能衡量它,你就不能改善它。” —彼得·德鲁克

目标很重要。这没什么新鲜的。一个目标可以是:

“我想更好地学*编程!”

这是一个很好的目标,但它相当宽泛和不明确。你想怎么变好?需要多长时间?具体想改善什么?你想学*更多关于数据结构的知识吗?你应该有智能目标SMART 是项目管理领域经常使用的缩写词,代表:

  • 具体的:你的目标不应该太笼统。不然你想怎么确定你达到目标的点呢?你的目标应该是具体的,你应该选择一个具体的衡量标准,告诉你什么时候你真正达到了目标。
  • 可衡量的:你应该能够跟踪和量化你目标的进展。这也增加了动力,因为你现在有了一个工具来反馈自己的进展。
  • 可实现的:评估你自己目前的能力,检查你是否能以目前的技能达到你的目标。尽量现实一点。少做多做是一个原则,这个原则对许多人来说是有效的,可以一步一步实现小目标。
  • 相关:你的目标有助于更高的目标吗?是不是一个更大问题的子解决方案?它在多大程度上帮助了你?会带来更多收入吗?
  • 有时间限制的:有时间限制的目标有助于你按计划进行。给自己设定一个截止日期可以帮助你以更有效的方式实现目标。达到一个目标是伟大的,但如果花的时间太长就不是了。

你每设定一个目标,它都应该具备这五个特征。使用任何你认为合适的工具。用一张纸写下 SMART 目标的五个栏目。你甚至可以使用 Scrum看板板,如 Trello 来帮助你。在开始写文章或软件产品之前,写下 SMART 目标。从长远来看,这对你有好处。

快速达成目标是好事。快速达到正确的目标更好。

6.结构

Jason AbdillaUnsplash 上拍摄的照片

“给我六个小时砍树,我会用前四个小时磨利斧头。”—亚伯拉罕·林肯

不管你想创作的是一篇文章还是一个软件产品,它们都应该有一个合适的结构和基础。这几乎就像盖房子一样。你从地基开始,而不是屋顶。

以我的人体素描为例。如你所见,我不是专业艺术家,但这有助于解释我所追求的类比。

我自己的男性人体素描

素描在早期绘画阶段很重要。素描有助于获得正确的比例。你可以添加尽可能多的细节,试图掩盖潜在的错误,但所有的细节都无法弥补糟糕的比例。

同样的原则也适用于软件开发。你可以实现一个看起来很棒的软件,但是如果功能不正确,你不能用闪亮的按钮来弥补。

写作也不例外,在添加细节之前,先弄清楚结构和基础,可以节省你大量的时间。你的想法应该符合逻辑。一步接一步。一点一点地积累,并有一个要点要传达。

通过介绍问题或理解文章所必需的任何东西来提供一些背景。之后,提供一个问题的解决方案或主要内容。牵着读者的手,做一个引路人。

我通常根据章节和标题来考虑文章结构。我创建章节,直到我认为我的文章的每个方面都涵盖了。所有部分的总和应该产生一个连贯的乘积。只有在那之后,我才试着用细节来填充这些部分。

7.了解你的目标受众

埃尔蒂·梅绍在 Unsplash 上拍摄的照片

“总是尽可能让观众痛苦。”—阿尔弗雷德·希区柯克

你不必照字面理解希区柯克的建议,吓跑你的用户和读者。除非这就是他们想要的。这是这里的主要信息。

买阿尔弗雷德·希区柯克或斯蒂芬·金的书的人脑子里都有某些假设。他们想通过害怕来娱乐。他们想要恐怖片、惊悚片或两者兼而有之,而不是爱情片。

你必须为合适的人制造合适的产品。为了制造合适的产品,你必须了解客户的需求和问题。你必须了解你的观众。你为谁写作?这是一个类似于软件验证的概念,定义如下:

"确保最终产品利益相关者的真正需求和期望得到满足的活动."

软件验证试图回答这个问题:我正在构建正确的产品吗?

当你开始写文章时,你可以问自己几个关于目标读者的问题,比如:

  • 他们想要艰难、无聊的事实,还是情感的过山车?
  • 我写作的目的是什么?
  • 根据我的听众的技能,内容是否合适?是不是太技术化了?是不是技术不够?
  • 我这篇文章的要点是什么?这对我的观众有多大帮助?

试着从读者的角度看问题。孙子的一句名言说:

“知己知彼,百战不殆。如果你了解自己但不了解敌人,那么每一次胜利都会让你遭受失败。不知己知彼,百战不殆。”——孙子

虽然读者和用户不是你的敌人…在大多数情况下…你可以从这句话中学到很多。

当你为一个不知名的观众写一些你自己都不相信自己的东西时,你肯定注定会失败。当你写了一些伟大的东西,但你不知道是为了谁,这只是一个赌博,如果你的文章会成为一个成功。最后,当你为合适的人写好内容时,你会极大地增加你的机会。

再说一次,建造没人想要的东西是世界上最糟糕的感觉。

8.紫色的母牛

照片由 Unsplash 上的 Stijn te Strake 拍摄

“成功的关键是找到一种脱颖而出的方法——成为单色荷斯坦奶牛中的紫色奶牛。”——塞思·戈丁

想象一下,你开着车,经过一片满是奶牛的田野。它们可能大小不同,可能有不同的黑白图案。这是一个常见的景象,你甚至不会给他们太多的注意力。他们中没有一个是鹤立鸡群的。然而,那是你想要实现的。鹤立鸡群。你想成为每个人都立即注意到的紫色奶牛。

紫牛的例子是一个常见的商业类比。针对媒体,有不同的方法来解决引起注意的问题,例如:

  • 引人入胜的标题和副标题
  • “踢球者”
  • 为搜索引擎优化定制标题和副标题
  • UnsplashPexelsBurstThe StocksPixabay 等网站免费获取你的精选图片。

用户通常只需要一秒钟来决定他们是否要点击你的文章。一个好的标题和特色图片当然会有所帮助。

同样的原则也适用于 App-store 中的应用。你必须想出有创意的方法来脱颖而出。做紫牛。

9.分步解决

卡洛斯·伊瓦涅斯在 Unsplash 上的照片

“分而治之。”—朱利叶斯·凯撒

Julius Caesar 的这句名言也适用于计算机科学领域。分而治之可以作为一种算法设计范例

该算法的工作原理是递归地将一个问题分解成两个或更多相同或相关类型的子问题,直到这些子问题变得足够简单,可以直接解决。然后将子问题的解决方案组合起来,给出原问题的解决方案。

如果你把一篇文章当成一个你想要解决的更大的问题,那么把文章分成更小的子问题是有意义的。

一方面,这为你自己创造了动力和动力,因为你现在有了小而容易的子问题,而不是一个大的、整体的问题。你可以将每个子问题与你想要达到的里程碑联系起来,这样你就创造了一种衡量你进步的方式。

另一方面,将文章分成更小的子问题也可以意味着为读者在视觉上划分文章。大多数情况下,如果读者发现文章中间没有什么停顿,他们会觉得读起来更容易。你可以使用链接、图片、视频或任何你喜欢的东西。

以这篇文章为例。我用图片把文章分成了每一部分。

10.整体情况

Lukasz Szmigiel 在 Unsplash 上拍摄的照片

“如果你花一生的时间去分析每一次遭遇,你只会看到树,而看不到森林。”香农·阿尔德

你是否迷失在细节中?你在一个句子上写了将*十分钟吗?你难道看不见森林吗?

你必须不时后退一步,从整体上看待这个问题。如果细节无助于大局,即主要问题,那么细节就毫无意义。

休息一会儿,想一想你真正想用你的产品达到什么目的。你目前的活动对产品的贡献有多大?值得吗?

11.不要做一个完美主义者

布雷特·乔丹在 Unsplash 上的照片

“从根本上说,完美主义并不是对一丝不苟的热爱。是关于恐惧。害怕犯错。怕让别人失望。害怕失败。怕成功。”迈克尔·劳

有一个关于陶瓷班的好故事,证明了数量重于质量。

最高质量的作品都是由被评定数量的小组制作的。看起来,当“数量”组忙于大量的工作,并从他们的错误中学*时,“质量”组却坐在那里理论完美,最终他们的努力只剩下浮夸的理论和一堆死粘土。

不要试图想出一个完美的产品,也不要浪费太多时间对你的产品进行理论化。熟能生巧。大师失败的次数比初学者尝试的次数还要多。

写下最少的内容来表达你的观点。你可以创建一个临时附录部分,附加内容可能是也可能不是你最终文章的一部分。

记住技巧 4 中的帕累托原则:

"对许多事件来说,大约 80%的结果来自 20%的原因."—维尔弗雷多·帕累托

当你认为你的文章差不多准备好了,就发表吧。不要浪费太多时间润色,因为你可能会花 80%的时间把文章的最后 20%写得恰到好处。你仍然可以在以后改正小错误,并采纳读者的反馈。

完成比完美更好。

12.让它成为一次愉快的经历

米 PHAMUnsplash 上拍照

他们可能会忘记你说过的话,但他们不会忘记你带给他们的感受卡尔·布埃希纳

人类是有情感的生物。不可否认。你的文章内容也应该传达情感,使之成为一种愉快的体验。

许多软件公司都有人负责用户体验(UX) :

用户体验 ( UX )是一个人对使用某个特定产品系统或服务的情绪和态度。它包括人机交互和产品所有权的实用、体验、情感、有意义和有价值的方面。

关于如何获得愉快的用户体验,没有固定的规则。这可能是一个快速的加载时间,令人鼓舞的消息,漂亮的视觉效果。你的想象力是极限。

对于中型文章,您可以尝试使用 Medium 提供的几种格式化选项。使用文体特征,看看它们是否能让你的文章更有趣。

在我的一篇关于如何阅读科学论文的文章中,我试着非常鼓励你,因为我知道面对你的第一篇研究论文是多么困难和令人畏惧。

要有创造性,把读者想象成一个你想以善意的方式接*的好朋友。

13.简单点,笨蛋

照片由蒂姆·莫斯霍尔德Unsplash 上拍摄

"一切都应该尽可能简单,但不能更简单。"——阿尔伯特·爱因斯坦

接吻原则是“保持简单,笨蛋”的首字母缩写。KISS 原则不仅适用于软件设计,也适用于写作。尽量使用简单的句子,让你的内容容易消化。不要把事情复杂化。乔希·考夫曼曾经说过:

“系统越复杂,运行时间越长,就越有可能出现重大故障。”

如果你写的句子过于复杂,并且包含大量重复,你的读者会失去兴趣。要精确。

14.工具

Cesar Carlevarino Aragon 在 Unsplash 拍摄的照片

“这可能不是问题所在。相反,问题可能是我用来尝试解决问题的工具。”克雷格·劳恩斯布鲁

没有她/他的工具,程序员什么都不是。程序员使用 ide 让他们的生活变得更简单,他们喜欢自动化。而且,大部分程序员都很懒。我也不例外。

一个作家也可以受益于各种工具,以提高效率。你可以使用像这样的拼写检查器。你可以在文章中添加视觉辅助来支持你的内容。添加图像或视频,但要确保你没有侵犯任何版权。

15.给予,它就会给你

"因为我们正是在给予中获得的。"—弗朗西斯(阿西西的)

存在这样一个奇怪的普遍规律:慷慨付出的人得到的更多。我在这篇文章中遵循了这个原则,链接了我认为有帮助的其他文章。我使用推荐人,并在该表扬的地方给予表扬。

说到编程,同样的原则也适用于开源项目。乍一看,你似乎是免费工作的,但是你从社区获得了关于你的编程技能的有价值的反馈,从长远来看,这可能对你有更大的帮助。

与他人建立联系,你不会后悔。

16.首先,让它工作,然后让它变得更好

照片由亚历克斯·科特利亚斯基Unsplash 上拍摄

“让它工作,让它正确,让它快。”—肯特·贝克

这条建议和你的初稿的建议是相辅相成的。用最少的句子来表达你的观点。稍后添加细节。首先,让它发挥作用。

拥有极简主义者的心态,以迭代和渐进的方式解决问题。迭代意味着你循环工作,迭代解决问题。增量意味着你在目前已经取得的成果的基础上继续努力。使用演绎或归纳的方法,但首先要让它起作用。

17.不要试图推销

莎伦·麦卡琴在 Unsplash 上的照片

“带着帮助客户解决问题或实现目标的想法接*他们,而不是销售产品或服务。”—布莱恩·特雷西

假设你购买了一款手机应用。你第一次启动它,只是为了看看它仍然包含恼人的弹出窗口和广告。你可能觉得被骗了。

中等文章也是如此。如果你在付费墙后发表文章,那么读者已经支付了费用,可以免费阅读这些文章。他们想要产品,仅此而已。不要因为包含附属链接和重复行动号召(CTA)而失去读者的信任。不要滥用你的文章以销售产品为主要目的。

只要努力解决他们的问题,销售就会随之而来。

18.把问题留在第二天解决

照片由凯特·斯通·马西森Unsplash 上拍摄

“熟能生巧。只有练*,再加上一夜的睡眠,才能达到完美。”—马修·沃克

乔希·考夫曼在他的书《前 20 小时:如何快速学*》中谈到了睡眠的重要性。他解释说,大多数学*过程不是在你练*的时候发生的,而是在你睡觉的时候。当你临睡前练*时,你会达到最好的效果。你的潜意识会处理剩下的。

即使你不在睡觉前写文章,当你被卡住的时候,在一个问题上睡觉几乎总是一个好主意。写作和编程都是创造性的工作,有时你就是无法推动它。

睡了一夜好觉后,你常常能想出一个简单的办法来解决一个看似困难的问题。

19.重构

照片由叶戈尔·维克列夫Unsplash 上拍摄

“一个直观的定义是,安全重构是不会破坏程序的重构。因为重构的目的是在不改变程序行为的情况下重构程序,所以程序在重构后的表现应该和重构前一样。”—马丁·福勒

重构是软件工程师最常听到的一个术语。重构使代码更容易阅读,而功能保持不变。你可以把同样的原则应用于一般写作。

你可能以前听过这句话:“如果读起来容易,那么写起来就很难!”。但是几乎没有人第一次就写出优雅的句子。这是一个反复修改你的作品的过程,直到它易于阅读而不丢失主要信息。

有勇气去掉句子。让你的产品精益。

20.营销和分销

简·侯伯Unsplash 上拍照

“如果一棵树倒在森林里,周围没有人听到,它会发出声音吗?—乔治·贝克莱

上面的引用很好地类比了写文章或创造任何类型的产品。你可能花了一些时间写你的文章。然而,如果一开始就没有人注意到它的存在,那该有多可悲?你所有的努力都会白费。

我最*写了一篇关于如何备份 WordPress 的文章。我在上面花了几天时间,但它没有被策划,也没有在任何地方发行。不要犯和我一样的错误。你正在阅读的这篇文章源于对我的 WordPress 文章的不满。

营销和分销几乎和产品本身一样重要。也许更重要。问问你自己:我怎样才能让尽可能多的人对我的产品感兴趣?

Medium 为此提供了不同的解决方案:

  • 为你的文章使用合适的标签。如果你的文章得到了策划,那么它将会出现在它所策划的主题中。你文章的策展叫做“分发”。媒体有一定的指导方针来获得策划
  • 将你的文章提交给出版物。大部分都有写作指南。在提交文章之前,阅读它们并应用到你的文章中。
  • 查找最活跃的媒体出版物,看看其中是否有合适的。

除了 Medium 的内置分发功能之外,您还可以在其他任何地方提交您的文章。搜索可能对你的内容感兴趣的在线社区,如 Reddit、论坛、脸书、Instagram。选择权在你。

最后的话

我希望你喜欢这篇文章。你可以根据自己的需要随意调整这个列表。如果您对本文有任何问题或评论,请在下面留下您的评论。

你对我的文章或项目的更新感兴趣吗?我的简讯每月一次让你了解最新消息!

如果你想支持我,并且你还不是一个中等会员,那么请考虑通过我的推荐页面注册:https://medium.com/@christoph.schmidl/membership

如何用 Python 编写 ETL 操作

原文:https://towardsdatascience.com/how-to-write-etl-operations-in-python-baffbceeadf4?source=collection_archive---------7-----------------------

使用 Python 清理原始数据并将其转换为可接受的格式

来源: Unsplash

在本文中,您将学*如何在 Python 环境中处理 Excel/CSV 文件,以清理原始数据并将其转换为更易于接受的格式。这对数据集成非常有用。

本例将涉及到许多常见的 ETL 操作,如过滤减少、展平

笔记

这些例子的代码可以在 GitHub 这里上公开获得,还有我将带你浏览的镜像信息的描述。

这些示例依赖于两个开源 Python 包:

  • pandas: 一个广泛使用的开源数据分析和操作工具。更多关于他们网站 PyPi 的信息。
  • gluestick: 一个小型开源 Python 包,包含由 hotglue 团队维护的用于 ETL 的 util 函数。更多关于 PyPiGitHub 的信息。

事不宜迟,我们开始吧!

介绍

这个例子利用了来自 Quickbooks 沙盒环境的样本 Quickbooks 数据,并且最初是在一个 hotglue 环境中创建的——一个用于初创公司的轻量级数据集成工具。

请随时关注下面 GitHub 上的 Jupyter 笔记本!

[## hotgluexyz/食谱

用 Python 编写 ETL 转换脚本的简单示例

github.com](https://github.com/hotgluexyz/recipes/blob/master/src/basic.ipynb)

第一步:读取数据

让我们从读取数据开始。

这个例子建立在 hotglue 环境上,数据来自 Quickbooks。在 hotglue 中,数据以 CSV 格式放在本地的sync-output文件夹中。我们将使用 gluestick 包通过read_csv_folder函数将输入文件夹中的原始数据读入熊猫数据帧字典。

通过指定index_cols={'Invoice': 'DocNumber'},Invoices数据帧将使用DocNumber列作为索引。通过指定转换器,我们可以使用ast来解析LineCustomField列中的 JSON 数据。

偷看一眼

让我们看看我们正在处理哪些数据。为了简单起见,我选择了我想要使用的列,并将其保存到input_df。通常在 hotglue 中,你可以使用一个字段映射来配置它,但是我在这里是手动完成的。

步骤 2:重命名列

让我们通过将列重命名为更易读的名称来清理数据。

CustomerRef__value -> CustomerId
CustomerRef__name -> Customer
MetaData_LastUpdatedTime -> LastUpdated
MetaData_CreateTime -> CreatedOn
CurrencyRef__name -> Currency
CurrencyRef__value -> CurrencyCode

第三步:提取信息

Line列实际上是 Quickbooks 提供的一个序列化的 JSON 对象,其中有几个有用的元素。我们需要从展平JSON 开始,然后分解成唯一的列,这样我们就可以处理数据了。

同样,我们将使用 gluestick 包来完成这个任务。explode_json_to_rows函数在一个步骤中处理展平和分解。为了避免分解这个对象的太多层次,我们将指定max_level=1

下面是其中的一个片段,可以让你有所了解。

[{
    'Id': '1',
    'LineNum': '1',
    'Amount': 275.0,
    'DetailType': 'SalesItemLineDetail',
    'SalesItemLineDetail': {
        'ItemRef': {
            'value': '5',
            'name': 'Rock Fountain'
        },
        'ItemAccountRef': {
            'value': '79',
            'name': 'Sales of Product Income'
        },
        'TaxCodeRef': {
            'value': 'TAX',
            'name': None
        }
    },
    'SubTotalLineDetail': None,
    'DiscountLineDetail': None
}]

步骤 4:筛选行

出于我们的目的,我们只想处理带有Line.DetailTypeSalesItemLineDetail的行(我们不需要小计行)。这是一个常见的 ETL 操作,称为过滤,使用 pandas 很容易完成

第五步:更多爆炸

看看我们展开的Line列中的一些条目。您会注意到它们是 JSON 中的名称值对。

让我们再次使用胶棒通过json_tuple_to_cols功能将这些分解成新的列。我们需要指定lookup_keys——在我们的例子中,是key_prop=namevalue_prop=value

第六步:更多爆炸

看一下CustomField栏。下面是一个条目示例

[{'DefinitionId': '1', 'Name': 'Crew #', 'Type': 'StringType', 'StringValue': '102'}]

您可以看到这是 JSON 编码的数据,指定了一个定制字段:Crew #,值为102

为了分解这个,我们需要减少这个,因为我们只关心NameStringValue。我们可以使用 gluestick 的explode_json_to_cols功能和array_to_dict_reducer来完成这个任务。

结论

我们的最终数据如下所示。在这个示例中,我们使用一个真实世界的例子,使用基本的 Python 工具完成了几个基本的 ETL 操作。

将来,你可以随意查看开源的热熔胶配方以获得更多的样本。感谢阅读!

如何写好科技文章

原文:https://towardsdatascience.com/how-to-write-hit-articles-for-tech-9a6911ff907a?source=collection_archive---------42-----------------------

回顾:这不是关于神经衰弱

没有成功的秘诀。但是有些事情是有帮助的。布鲁斯·马斯在 Unsplash 上的照片

当我开始写作时,我没有想到我的文章会被翻译成几种语言,获得数百万的浏览量和数千美元的收入。那不是我开始时的目标。但是我不能抱怨。

成功没有唯一的秘诀。如果有的话,那么每个人都会在他们的游艇上放松,在夕阳下啜饮鸡尾酒。

但有几件事我从一开始就明白了。这不是关于精心制作一个完美的标题或获得正确的搜索引擎优化。造成这种差异的更多的是我在这背后的总体心态。在培养基上经历了六个月的巨大成长后,这就是我的工作。

1.想办法

我开始在媒体上写作,因为我不想在周日工作,但我需要做一些有意义的事情。但是我没有写任何东西,而是思考我是谁,我想代表什么。

我正在攻读物理学博士学位,所以写关于科学和研究的文章似乎是一个显而易见的选择。我也是同性恋,所以我想我可以分享我作为一个边缘人在科学方面的经历。但是我发现写我的个人生活真的很难,所以我没有写太多关于 LGBTQIA 的问题。

当你现在看我写的文章时,你会注意到我甚至没有写很多关于科学的东西——更多的是关于数据科学和编程语言。我没有像奴隶一样坚持我的计划。这更像是我灵媒之旅的起点。

这就是计划的作用。无论你的计划有多好,它都可能撑不过你写作的第一个月。但是它让你思考什么对你重要,你想写什么。它给你一个最初的方向,可以而且应该随着时间的推移而发展。

2.保持一致

你的第一篇文章不会是杰作。你的第二个也不会。即使你的十分之一也不会传播开来。

如果你的梦想是写一部轰动一时的作品,一夜之间成为百万富翁,请三思。媒体上最成功的作家多年来一直在大量创作作品。有些是每天,有些是隔天,有些是每周。但是你可以打赌,他们会在这个星期,下个星期,再下个星期出版。

我最初的目标是每周发布一个故事。我从 12 月份开始,我坚持每周一次的计划,度过了圣诞节的喧嚣和生活中所有其他令人分心的事情。

你一定要出现。每一次。

时不时休息一下没关系——我自己也休息过几次,因为冠状病毒危机中的生活充满挑战。如果你需要休息,不要因为休息而责备自己。但是请记住,如果你想成功,写作应该在你的优先事项清单上保持首要位置。

3.看看什么能打动你的观众

在我开始写作大约一个月后,我意识到大多数读者喜欢关于人工智能的东西。所以我写了更多关于这个的东西。

然后我意识到阅读我的东西的人是程序员和数据科学家,所以我开始写这方面的东西。那时我制作了我的第一批热门歌曲:

你的小众可能不一样,你的受众也可能不一样。我想我应该为各行各业碰巧对科学感兴趣的人写作。但是我是为程序员写的。

看看你的统计数据,看看哪些故事起飞。如果你想要大量的读者,这给了你很多关于为谁写的线索。

也就是说,只写你真正热爱的东西。如果你的目标是用你不在乎的东西取悦每个人,人们会看穿的。

表达你的观点,即使很尖锐。承担风险。永远忠于自己。有趣的是,从长远来看,这会让你更成功。

你的观众喜欢什么?照片由尼古拉斯·格林Unsplash 上拍摄

4.明智地选择你的 KPI

看看你获得了多少浏览量或者一个故事获得了多少掌声是很好的。你可以从中了解很多关于你的听众的情况。

但是不要纠结于你的数据。选择几个关键的绩效指标,剩下的留给你有时间时的额外见解。

我的 KPI 是合作伙伴计划收入和关注者数量。追随你的人是经常性读者,因此对未来的成功来说,比你目前获得的观点更重要。收入——嗯,我想我喜欢赚钱。

我保存了一个漂亮的小电子表格,记录了每周的关注人数。我每天都记下当月的收入。这不仅让我对是什么带来了金钱有了一些很好的见解——早上醒来,意识到你刚刚在一夜之间赚了几百美元,这也是一种很好的感觉。

5.对机会说“是”

写作一个月后,我开始接触媒体上的出版物。将你的作品添加到出版物中不需要花费任何成本,并且让你的作品受到很多新的关注。所以我答应了。

又过了一个月,其他平台开始联系我,问我他们能否将我的文章翻译成其他语言,并在他们的网站上展示。这不花我一分钱,我还可以免费曝光。所以我答应了。

在我成为作家的四个月里,其他平台开始联系我,希望从我这里获得独家内容。这次我并不总是同意——如果我在 Medium 上发表一篇可以赚几千美元的文章,那么我要么想要同样多的钱,要么想接触一些了不起的人。

根据经验,无论你遇到什么,我都会答应。你永远不知道这会给你带来什么。如果你不喜欢它,因为人们很差劲,或者因为它不够赚钱,你以后仍然可以放弃它。

感激出现在你面前的人和机会。戴安娜·西姆潘德在 Unsplash 上的照片

6.忠于你的人际网络

如果没有其他作者、平台编辑和媒体内外其他人的支持,我的成功是不可能的。

这包括 Ludovic Benistant,他首先发现了我的作品,并邀请我为数据科学的 T2 撰写文章。这包括安妮·邦纳,她是 TDS 上一名出色的编辑。这包括叮当(洪静),她作为编辑和作家都很可爱。以及更多的人。

我确保定期检查他们的工作,并进一步推荐。我给他们掌声和关注,因为他们值得,并在媒体和其他社交媒体上交换意见。

无论你在职业生涯的哪个阶段,回馈都不会太早。让人们知道他们对你很重要。试着帮助他们追求目标,就像他们帮助你一样。你的关系网就是你的净资产。

7.不要把仇恨者看得太重

一旦你获得了一些关注,很有可能你会得到一堆负面的评论。这确实取决于你写的内容和你是否具有煽动性(哎呀,我对此感到内疚)。

看看我最受欢迎的两篇文章的评论部分:

他们充满了仇恨!我可以把它们藏起来,但我更喜欢让人们自己做决定。

而且看那些评论很伤人。不管你有多冷酷,那也不会让你心情愉快。

我不建议你完全远离评论区。你的读者是你作为一个作家存在的理由,所以你应该更加认真地对待他们。他们确实提供了建设性的批评,新的想法,和各种令人敬畏的东西。

但是也有一些人喜欢在他们阅读的所有东西下面写一些充满仇恨的东西。我喜欢认为我的故事对他们来说一定很重要,因为他们花了五分钟写了一篇评论。

感受你的感受,然后继续前进。不要让那些人打击你。

没有必要重新发明这些!乔恩·卡塔赫纳在 Unsplash 上拍摄的照片

8.不要多此一举

当写作时间来临时,我经常有很多想法要写些什么。我从我的生活、我当前的项目、与周围人的对话等等中收集了它们。

但是有时候我不知道该写些什么。我收集的所有材料似乎都不够鼓舞人心或及时,我坐在一个空白的屏幕前,不知道该做什么。

有趣的是,我在这样的时刻——或者几个小时之后——发表了我最受欢迎的故事。我通常花 30 分钟左右的时间来尝试自己想出一些东西。

但是如果我什么都没找到,我就在我的故事的评论中梳理,并通过 Twitter 和 StackOverflow 进行检查。那里有很多东西。

之后,我用谷歌搜索我的标题,看看它是否填补了一个空白。如果这是一个还没有人写过的利基市场,那太好了!但是如果有很多关于这个话题的文章,那也没关系。

你不需要每次都重新发明轮子。只要确保你给你的同行作家应有的尊重,并链接到他们的文章。

9.看别人的东西

如果你想飞黄腾达,就向最伟大的人学*。Medium 上有一些非常棒的东西,你可以从中学*一些东西。

你可以学*如何写能引起共鸣的文章,震撼人心的标题,形成自己的风格。可以了解当下流行什么,读者想听什么。你可以了解你的利基或完全不同的东西。

你看看我突出拍手的是什么,都是各种东西。大部分甚至不是面向技术的。尽管我出于个人兴趣阅读了这些故事中的大部分,但我总能从它们中找到提高我写作水平的教训。

我写关于技术的文章,但我不想听起来像个书呆子。我想听起来像我一样。阅读各种主题是关键。

如果你读了很棒的东西,那会以这样或那样的方式给你的写作增加价值。要么你从内容中学到东西。或者你从风格中学到一些东西。

永远不要停止学*。摄粘土堤的 Unsplash

10.不断学*

在写建议方面,永远不要停止学*。你不需要阅读建议文章——只需要从你阅读和喜欢的东西中吸取教训。

以下是我在媒体上写作时学到的一些重要经验:

  • 话题就是一切。如果你就一个不相关的话题写了一篇漂亮的文章,没人会看。
  • 如果你太努力去写人们喜欢的东西,没人会看的。在这种情况下,写下与他们想听到的相反的内容。我迄今为止最受欢迎的文章——关于为什么 Python 不是永远的——奏效了,因为人们爱上了 Python。
  • 短句总是胜过长句。
  • 比起大段大段的文字,更喜欢小段落。一句俏皮话没问题。
  • 副词烂。你认为他们强化了你的观点,但他们却弱化了它。尽可能把副词踢出去。
  • 如果使用得当,f-bomb 和其他脏话是没问题的。
  • 只要它们不是无脑的,就没问题。但是不要只写列表条。
  • 你不需要成为每个人的宠儿。你的敌人暗地里爱着你,只是他们不承认罢了。

只要我还是一个有大脑的人,这个清单就会越来越长,因为人类的大脑喜欢学*。你可以通过有意识的学*来最大化你的学*成果。

[## 如何撰写和发表引人注目的文章

创建内容的简单技巧,易于查找,阅读起来令人兴奋

medium.com](https://medium.com/swlh/how-to-write-and-publish-articles-that-get-noticed-60e9701daed4)

最后一句话:耐心点

大多数时候,我醒来发现自己一夜之间又赚了几百美元。但这并不是一夜之间发生的,听起来很矛盾。

2019 年 12 月,赚了 55 美分。2020 年 1 月,我得到了 20 美元。二月份是 120 美元。从三月份开始,我就收到了一张四位数的支票和 50 万的月浏览量。

当然,我为此很努力,但我想我也很幸运。我在正确的时间开始,在正确的出版物上发表,接触到正确的读者。媒介对我来说是一个完美的机会。

你的成功将取决于你写了什么,你有什么样的风格,以及你是否与你的 sh*t 保持一致。一开始,当你的故事得到 20 个观众时,你会很高兴。许多个月后,你会想,当一个故事只有 2k 时,哪里出了问题。

无论你在旅途中的什么地方,成功都会到来,因为你每天起床,全身心地投入到你热爱的事情中。很有可能,其他人也会喜欢这些东西。在媒体上,在生活中的任何地方。所以快下来写吧。

如何用 AI 写影评

原文:https://towardsdatascience.com/how-to-write-movie-reviews-with-ai-d17f758f2ed5?source=collection_archive---------24-----------------------

微调 GPT-2 的短篇小说

费利克斯·穆纳拉姆在 Unsplash 拍摄的照片

想象一下,与一个人工智能合作撰写一篇中等文章,这个人工智能已经阅读了你写过的每一个单词——一个语言模型,它从你的帖子、文章、口述笔记、初稿、扫描的日记条目、研究文件、最喜欢的引用以及其他使你的写作独一无二的思想碎片中学*。

你的人工智能写作伙伴可以对你的文章进行巧妙的评论,并就如何改进你的论点提出建议。它可能会出现一些鼓舞人心的引语,你可以把它们包括进去,并提醒你提及三年前在车管所排队时你保存在智能手机上的一个奇怪想法。

人工智能不会取代作家。它将增强你的写作过程,给你一个定制的读者和编辑精确校准,以改善你的风格,声音和主题。

我等不及这个世界的到来。我自学了足够多的编码来用人工智能工具生成小说,但在我内心深处,我是一名记者——一名非虚构的讲故事者。

我想看看人工智能现在如何帮助我的非小说写作。因此,利用超级语言模型 GPT-2,我训练了一个人工智能来为电影《威胁》杂志生成电影评论。

这个简短的非小说类实验让我对未来的写作工具有了一个初步的了解,我们有一天会在写作中使用这些工具。

未来的电影评论

当 OpenAI 去年推出 GPT-2 语言模型时,开发者担心糟糕的演员会滥用这个工具。该公司慢慢发布了其模型的不同强度版本,仔细观察 GPT-2 的滥用权力。

他们担心它可能被用来:

“生成误导性新闻文章
在线冒充他人
自动制作滥用或伪造内容并发布到社交媒体上
自动制作垃圾邮件/网络钓鱼内容”

一年后,GPT-2 完全可供平民使用,为惊人的游戏,创意写作实验,以及配方生成提供动力。到目前为止,我们还没有看到大规模的假非虚构文学的产生。

我相信 GPT-2 最有趣的(也是潜在危险的)应用将来自短篇小说。亚马逊评论、书籍简介和电影反应已经消耗了我们太多的在线注意力,有时还会左右人们对某个产品或艺术作品的看法。

在开始这个项目时,我选择电影评论作为我的基础材料,因为网上有大量用户生成的评论——其中一些收集在公开可用的数据集中。你可以很容易地用书评、新闻文章、体育报道或你的非小说作品建立一个数据集。

去年,我与电影威胁的编辑团队一起工作,开始开发一个能够写电影评论的人工智能。我们一起发表了一些作品,我想分享一下我们是如何训练我们的模型的。

伊利亚·安东内尔在 Unsplash 上拍摄的照片

认识人工智能评论者

该项目开始很简单,在我接触到能够微调 GPT-2 的工具之前。即便如此,常规模式对于电影评论来说还是很管用的。

电影威胁第一篇文章中,我开始用与变形金刚对话生成感人的评论。这个网站让你可以立即进入 GPT-2。你所要做的就是输入一个关于电影的问题,然后点击“完成”无需编码!

我问了 GPT-2 一个引导性的问题:“谁是第一个写影评的人工智能?”我们得到了这个最棒的计算机生成的回复(完全未经编辑):

“Artificial Intelligence Reviewer. It’s the robot you can pay $15 for to watch your movie while you finish making your dinner at home.”

GPT-2 给了我电脑生成的影评人的名字。使用这个名字和一些引导性的问题,我用这个简单的界面生成了足够的材料来写一整篇关于电影威胁的文章。

但是我想做一些更复杂的东西。在下一篇文章中,我升级了人工智能评论器——制作了一个能够产生无尽电影评论的语言模型。按需提供。

微调 GPT-2 来回顾电影

使用一种称为“微调”的机器学*技术,我重新训练了 GPT-2 语言模型,该模型用一个大规模的电影评论数据集为人工智能评论者提供了动力。我给饥饿机器人提供了一个巨大的电影评论数据集,给了人工智能评论者一个全新的评论电影的词汇。

你可以在我的第二篇电影威胁文章中阅读结果,将读者最喜欢的电影与计算机生成的评论进行匹配。

以下是我如何训练电影威胁的人工智能…

1.下载数据集

首先,你需要找到你的非虚构作品的样本——书评、亚马逊用户反馈、脚注、Twitter 帖子,或者任何你想用电脑生成的简短形式的非虚构作品。网上有很多电影评论数据集。这是我在斯坦福人工智能实验室网站上找到的一个数据集:

“这是一个用于二元情感分类的数据集,包含的数据比以前的基准数据集多得多。我们提供一组 25,000 条高度极性的电影评论用于训练,25,000 条用于测试。”

2.微调你的 GPT-2 语言模型。

微调我的两个语言模型花了几天时间。马克斯·伍尔夫创造了一个令人惊叹的谷歌实验室笔记本,让这一步变得不痛不痒、自由自在。我用的是中等大小的 355M 版本的 GPT 2,因为它足够大,可以处理我的数据集,但又足够小,可以在 Google Colab 的云服务器上运行。我把我的模型训练了 23000 步。

我将训练序列分成三个较小的部分,因为 Google Colab 不会运行超过 12,000 步。

3.使用微调后的 GPT-2 模型生成文本。

一旦我的语言模型得到训练,我就开始生成数百条通用的电影评论。这些很有趣,但有点不集中。对于每次运行,我设置长度为 200 个字符,温度为 0 . 7,输出为 10 个样本。

4.尝试简单的前缀。

当您开始向模型中加载新的前缀时,真正的奇迹就发生了。它可以像给一部电影命名一样简单。这是我尝试过的第一个测试:

我们立即在《星球大战》的评论中测试了我们的超级人工智能。在几秒钟内,人工智能评论者已经生成了几条如下的精彩评论:

“The film’s heart is in the right place, but its arteries are seriously clogged up with syrupy clichés.”

但随后,AI Reviewer 跟进了对星球大战的滔滔不绝的评论,像这样:

“A big, bright, adrenaline-fueled summer entertainment that offers a lot of action and excitement, but never wastes a minute of our time.”

我一遍又一遍地点击“运行”,直到我用成千上万条评论填满了一个空白文档。从这些可能永无止境的《星球大战》评论中找出最好的评论需要大量的人工阅读。

5.试试复杂的前缀。

一旦我有了一些关注单个片名前缀的有趣材料,我就开始关注不同的导演和演员,以获得更具体的电影评论。这是事情开始变得有趣的地方,当你开始玩模型的限制。

下面是一个前缀示例:

这个前缀让我们对 2019 年我最喜欢的外语电影之一进行了疯狂的评论。电影类型的最终融合仍然让我发笑。

"Pain & Glory, a movie by Spanish director Pedro Almodóvar that is filled with beautiful moments and some of the most intense, beautiful scenes I've seen in a long time. The last act is nearly non-stop action and big explosions. It's epic, awesome, and bloody awesome. Feels like a cross between the Matrix, The Matrix Reloaded and Indiana Jones & The Temple Of Doom."

随着颁奖季的临*,我还在前缀中加入了一些新的动词,比如“赢”和“输”。

这些前缀会给你带来一大堆奥斯卡预测!像这样:

"Little Women will win the Academy Award for Best Picture. I have a hard time believing the real-life story that is Perry Mason's Fresh Outta Compton. The movie is a good mix of true crime and urban legend."

6.通读你所有的输出。

人工智能产生的非虚构作品总是需要人类编辑。为了找到一篇好的电影评论,我不得不阅读成百上千页无聊、奇怪甚至听起来很正常的散文。工作量很大。但我从来没说过 AI 会取代作家。这只会帮助我们写得更好。

朱利叶斯·德罗斯特在 Unsplash 上拍摄的照片

Twitter 和超越

就像我可以构建人工智能评论器来制作搞笑和奇怪的电影评论一样,我可以用我收集的所有数字作品来训练我的 GPT-2 写作伙伴。我有至少十年的电子文本,包括笔记、研究、草稿和电子书阅读的集锦。我可以成为一个真正的写作伙伴,每当我需要创作灵感时,就重塑和刷新我的想法。

马克斯·伍尔夫(Max Woolf)的工作一直激励着我,他最*的一篇文章《如何用 GPT-2 构建一个生成 Twitter 文本的人工智能机器人》(How To Build a Twitter Text Generating AI Bot),向我们展示了这些接受过简写非小说训练的语言模型如何在网上度过一生。

他还对数据集的大小提出了一些警告。如果您想要使用较小的数据集生成唯一的文本,您需要遵循以下建议:

请注意,如果没有大量的 tweet,模型可能很容易过度拟合并逐字输出现有的 tweet;如果是这种情况,你可能想训练更少的步数(例如 200-500)。此外,我建议只使用 124 米的“小型”和 355 米的“中型”GPT-2 型号;较大的 GPT-2 模型在小文本文档和少量输入数据上表现不佳。

仅凭这个工具,你就可以创建一个 Twitter 机器人来为你发帖,或者创建一个新的机器人来发布你喜欢的话题。随着新 GPT 协议和其他语言模型被放入新的框架中,谁知道今年年底还会有哪些工具可用呢?

作家兼创意程序员大流士·卡泽米曾经将这些语言模型的进步比作图形艺术家早期的 Photoshop:

“如果你对写作的未来感兴趣,这绝对值得关注。这就像是 Photoshop 问世时的摄影师,因为它可能会改变媒体的游戏规则。”

我希望有一天,这些工具会帮助我们创作我们甚至还无法想象的新故事。

CS 优等生如何解决问题

原文:https://towardsdatascience.com/how-top-cs-students-problem-solve-17ae2c90fb96?source=collection_archive---------6-----------------------

加州大学伯克利分校 CS188:人工智能的尖子生给我留下了怎样的印象。

今天的尖子生赢得了从顶级公司招聘的热潮——他们展示了持续的方法来超越创新问题和创造价值。

领先一步

讲课时,我注意到最优秀的学生总是在我介绍 之前问我们要去哪里。支撑下两个部分的是构建概念图的清晰能力。我知道我是一个相当以思想为中心的讲师,这些学生不会错过任何一个节拍。原始计算能力令人印象深刻。

我将用一个运行中的多智能体学*竞赛来讲述这个故事,在这个竞赛中,我们希望以最佳方式解决新的 Pac-man 难题。这是为优等生设计的少量额外学分,但它最终让我们对顶尖人才的所作所为有了更深刻的了解。评分如下:

ai.berkeley.edu 来源

  • 每个小球+10
  • 收集所有小球+500
  • -每采取一项行动得 0.4 分
  • -1000 x(以秒为单位计算时间)

阿罗哈湖。来源—作者。

蛮力

我听说过很多关于加州大学伯克利分校的本科生如何努力工作的故事,但如果没有例子,很难知道这意味着什么或如何转化为实际生产力。

一名在 Pac-man 竞赛中获得第二名的学生最终运行了一个暴力 bash 脚本,在随机种子上创建了一个反馈循环,并将新的解决方案上传到我们试图(很差地)隐藏的测试用例中。这名学生没有被取消资格的原因是:他记录了他的方法,而我们没有为此制定规则。竞赛的一个新特点是对多个种子进行平均(对科学家来说很明显,是的),这样从竞赛中返回的信号就不会那么直接。

哇,样本条目

下面是“ wow ”竞赛提交的摘要,看起来学生可能使用了一些可疑的做法来硬编码解决方案(硬编码将消除分数上的计算时间惩罚),但他们设立了一个次要的类竞赛作为一个严重的工程问题。以下是他自己的一些话:

  1. 将我在一个项目中的答案复制到迷你竞赛中— 645 积分。
  2. 制作一个工具,从自动评分员那里获得关于竞赛分数的反馈,包括每个谜题的个人分数(* 这是一个巨大的进步,因为它向黑盒测试案例添加了反馈)。
  3. 给每个吃豆人添加一个“目标数据”——通过规划和执行轨迹来减少计算(不要重新规划每一步)。
  4. 为 Pac-men 添加共享数据,这样,如果一个 Pac-man 以点 A 为目标,其他 Pac-men 就会决定忽略点 A。这鼓励了每个 Pac-man 走不同的路线-1185 点。
  5. Pac-man 决定将目标点视为一面墙,而不是忽略点 A。这进一步鼓励每个 Pac-man 采取不同的路径,例如,如果两个最*的点在另一个 Pac-man 的路径上(* ),这是对智能状态空间缩减如何帮助搜索问题的一个很好的洞察。)。
  6. 硬编码初始状态信息,以便我可以决定使用哪个 AI。然后用扫配种子。
  7. 修改 pacman.py 的报告功能,以便在成功运行后,它将采取的操作复制到一个文本文件中,每个布局有一个唯一的文本文件。如果一个文本文件已经存在,那么它将该文件的分数与新建议的路径进行比较,并且只选择最佳选项。
  8. 制作一个程序,将所有的人工智能结合到一个字典结构中,这样我就可以快速地复制/粘贴它。
  9. 在我最好的人工智能上运行第 8 步,修改我的人工智能,如果当前布局与我的硬编码布局完全相同,它决定遵循硬编码路径;否则,它使用在步骤 4 中找到的 AI—1226点。
  10. 在我的 AI 的大约 3 个变体上运行一次步骤 8,组合最佳结果,并更新硬编码路径— 1252 点。
  11. 修改 pacman.py,以便在一轮成功后,它分析生成的移动序列,并确定每个 Pac-man 试图到达的球,以及以什么顺序到达。(* 至关重要的工程步骤)。
  12. 运行步骤 9 一次,将新的 ai 合并到我的文件中— 1255 点。
  13. 修改我的代码,使它自动从文件中下载更好的 AI,并自我更新,这样我的 AI 就可以在没有人工干预的情况下进行改进。然后我创建了一个 bash 文件,反复运行修改后的自动分类器,从而自动改进路径。(* 第二个关键工程步骤
  14. 运行步骤 11 1 小时,并将新的 ai 合并到我的文件中。这对应的是我第六次投稿,得了 1261 分。
  15. 通宵运行 bash 脚本。总训练时间约为 8 小时,但大部分进步都是在第一个小时内完成的——1266分。这个学生完成了。

从步骤 15 提交。

在这个过程中有一些严肃的见解,加上完成它的意志和动力。因此,要成为顶尖计算机科学大学的尖子生,需要的是能力和意志,让自己通过这种严格的实施过程。我不会说我有那种微调水平——也许这就是为什么我是研究生而不是软件工程师。

不要建立在盒子里——打破盒子

蛮力解决方案是关于建立一个更好的工具包,但最终学生输给了一个聪明的解决方案,这是一个天才的一击。

获奖作品。

在一个有 900 名学生的班级中,得分最高的人是对问题设置进行了改变的人,这使得他们的得分高得多(10%的幅度)。在一个惩罚额外行为的游戏中,这个学生让 3 个代理不采取行动,并用一个搜索代理解决了游戏。

分数——1327。

这是蛮力工程等式的另一半。这是看似简单的事后诸葛亮,但很少有人拥有

来源—作者。

最优秀的学生找到了获胜的方法,并经常导致未来的规则。作为课程工作人员,细节令人印象深刻。这是一种将产品推出门外的努力,我强烈袖手旁观这些学生的分数。拥有这些努力和洞察力并不是成功的必要条件,但它们会带你走得很远。

我选择以我的表现来定义我自己的成功,所以我不担心试图复制任何像这样疯狂的胜利。通过的一致性的享受,你可以拥有伟大的职业生涯,但看到一些最优秀的头脑如何分解问题也很有趣。

大约 3 年前,我在康奈尔大学完成了本科学业,大约 6 年后,我才真正试图在我的第一堂竞争性工程课中成名。我不确定是不是只是换个角度,但我已经被学生们打动了。我相信他们的努力会得到回报的。

更多关于演讲的想法可以在这里找到。

更多?订阅我关于机器人、人工智能和社会的时事通讯!

[## 自动化大众化

一个关于机器人和人工智能的博客,让它们对每个人都有益,以及即将到来的自动化浪潮…

robotic.substack.com](https://robotic.substack.com/)

迁移学*是如何工作的

原文:https://towardsdatascience.com/how-transfer-learning-works-a90bc4d93b5e?source=collection_archive---------33-----------------------

“迁移学*将是 ML 成功的下一个驱动力”——吴恩达。

Unsplash 上的 Element5 数码拍摄

迁移学*是采用预训练的神经网络,并通过迁移或重新调整已学*的特征来使神经网络适应新的不同数据集的过程。例如,我们采用在 ImageNet 上训练的模型,并使用该模型中学*到的权重来初始化全新数据集的训练和分类。例如,在 Sebastrian Thrun 和他的团队发表的研究工作中,使用预先训练的模型对 129,450 张临床皮肤癌图像进行了分类,并取得了优异的结果。该方法在两个任务上与来自专家的结果达到相同水平的性能:皮肤癌识别和最致命皮肤癌任务的识别。这只是一个例子,它向我们表明,人工智能确实能够以堪比皮肤科医生的能力水平对皮肤癌进行分类。DeepMind 的 CEO 对迁移学*有这样的看法:

“我认为迁移学*是一般智力的关键。我认为进行迁移学*的关键是获得概念性知识,这些知识是从你从哪里学到的感性细节中抽象出来的。”——戴密斯·哈萨比斯(DeepMind 首席执行官)

迁移学*对于有限的计算资源也特别有用。在某些情况下,即使是在功能强大的 GPU 机器上进行训练,许多最先进的模型也需要几天甚至几周的时间来训练。因此,为了不在长时间内重复相同的过程,迁移学*允许我们利用预先训练的权重作为起点。

从零开始学*很难做到,并且很难达到迁移学*方法中的相同性能水平。客观地说,我使用了一个 AlexNe t 架构来从头开始训练一个狗品种分类器,并在 200 个时期后达到了 10%的准确率。在 ImageNet 上预先训练的同一个 AlexNet 在与冻结重量一起使用时,在 50 个时期内实现了 69%的准确性。

迁移学*通常包括在第一层中获取预训练的权重,这些权重通常是许多数据集的通用权重,并随机初始化最后几层,然后训练它们以用于分类目的。因此,在迁移学*方法中,学*或反向传播只发生在用随机权重初始化的最后几层。同时,有几种迁移学*的方法,我们使用的方法取决于我们想要根据预训练模型的数据集进行分类的新数据集的性质。迁移学*有四种主要情景或案例。

转移学*场景

  1. 与原始训练数据集相似的小型新数据集
  2. 小但不同于原始训练数据集的新数据集
  3. 与原始训练数据集相似的大型新数据集
  4. 新数据集很大,但新数据不同于原始训练数据。

我们说的相似数据集是什么意思?

如果图像共享相似的特征,则它们是相似的。例如,猫和狗的图像会被认为是相似的,因为它们包含相似的特征,如眼睛、脸、毛发、腿等。植物的数据集将不同于动物图像的数据集,并且不会被认为是相似的。

大型数据集的频率高达一百万次。小型数据集通常在几千个的范围内

AlexNet 架构

我会用一个 AlexNet 来演示这个程序。AlexNet 的架构如下图所示

案例 1:小型相似数据集

如果新数据集很小并且与原始训练数据相似:

  • 移除完全连接的神经网络的末端
  • 添加一个新的全连接图层,其输出维度等于新数据集中的类数。
  • 随机化新的全连接层的权重;
  • 冻结预训练网络的所有权重
  • 训练网络以更新新的全连接层的权重

预训练模型的整个 CNN 层保持不变,即冻结,因为图像是相似的,并且它们将包含更高级别的特征。然而,这种方法有过度适应我们的小数据集的趋势。因此,原始预训练模型的权重保持不变,并且不被重新训练。

这种方法的可视化如下:

小规模相似数据集的迁移学*方法

这种方法的代码演示如下:

上面的第 3 行使我们能够冻结我们的权重,这样没有学*发生,权重保持不变。

上面的第 6 行使我们能够改变完全连接的层的输出形状。如果我们将其与原始 AlexNet 架构进行比较,我们会观察到输出大小为 1000,但在这种情况下,我们的新数据集的输出大小为 133。

案例 2:小而不同的数据集

如果新数据集很小并且不同于原始训练数据,则方法如下:

  • 我们去掉全连接神经网络的末端和网络末端的一些 CNN 层。
  • 添加一个新的全连接图层,其输出维度等于新数据集中的类数。
  • 随机化新的全连接层的权重;
  • 冻结剩余预训练 CNN 网络的所有权重
  • 训练网络以更新新的全连接层的权重

在这种情况下,我们注意到数据集很小,但有所不同。因为我们的数据集是图像,所以我们离开网络的起点,并移除在完全连接的层之前提取更高特征的 CNN 层。然而,这种方法也有过度适应我们的小数据集的趋势。因此,原始预训练模型的权重保持不变,并且不被重新训练。

这种方法的可视化如下:

案例 3:大型相似数据集

如果新数据集很大并且与原始训练数据相似,则方法如下:

  • 移除完全连接的神经网络的末端
  • 添加一个新的全连接图层,其输出维度等于新数据集中的类数。
  • 随机化新的全连接层的权重;
  • 初始化预训练网络的权重
  • 训练网络以更新新的全连接层的权重

由于新数据集与原始训练数据相似,因此不会从预训练网络中移除较高层要素。过度拟合不是一个潜在的问题;因此,我们可以重新训练所有的重量。

以下是如何将这种方法形象化:

大数据集和小数据集的迁移学*方法

上面的第 3 行允许我们将全连接层的输出权重从 1000 修改为 133。网络用预先训练的权重初始化,并且学*发生在网络的所有层上。

我们不需要在这里指定 requires_grad 为 False。默认值为真,因此新网络将仅使用预训练的权重作为训练过程的起点。

案例 4:大型且不同的数据集

如果新数据集很大并且不同于原始训练数据,则方法如下:

  • 移除完全连接的神经网络的末端,并添加一个新的完全连接的层,其输出维度等于新数据集中的类的数量。
  • 随机化新的全连接层的权重,并用随机权重初始化权重
  • 训练网络以更新新的全连接层的权重

在这种情况下,CNN 层大部分是从零开始重新训练的。但是我们也可以用预先训练好的权重来初始化它。

以下是如何将这种方法形象化:

面向大规模不同数据集的迁移学*方法

在这种情况下,当加载我们的模型时,我们简单地指定我们不需要预训练的重量,这更多的是从零开始训练。尽管如此,最好还是不要从完全随机的权重开始。从预先训练的重量开始在实践和文献中更常见。或者,我们用类似于 Xavier 初始化、均匀分布初始化或仅仅是恒定值初始化的方法来开始或初始化我们的权重。

因此,每当你有很多图像要分类时,为什么不先尝试进行迁移学*,然后开始考虑如何调整模型,应用不同的转换技术来提高模型的性能。

感谢您一直以来的阅读。

一些有用的资源

  1. 模型动物园:这个网站包含了很多预先训练好的模型,你可以下载并用于你的数据集。这个 github 页面是另一个有用的资源,它收集了预先训练好的模型。
  2. 这个包含了我用迁移学*做的狗品种分类器项目。
  3. PyTorch 关于迁移学*的教程可以在这里找到
  4. 关于迁移学*的 Tensorflow 教程可以在这里找到
  5. 关于迁移学*的 Keras 教程可以在这里找到。

参考

  1. Esteva、Andre、Brett Kuprel、Roberto A. Novoa、Justin Ko、Susan M. Swetter、Helen M. Blau 和巴斯蒂安·特龙。"用深度神经网络对皮肤癌进行皮肤科医生级别的分类."性质 542,7639 号(2017):115–118。
  2. 克里日夫斯基、亚历克斯、伊利亚·苏茨基弗和杰弗里·e·辛顿。"使用深度卷积神经网络的图像网络分类."在神经信息处理系统进展中,第 1097–1105 页。2012.
  3. https://www . deep learning wizard . com/deep _ learning/boosting _ models _ py torch/weight _ initial ization _ activation _ functions/

变压器如何工作

原文:https://towardsdatascience.com/how-transformers-work-6cb4629506df?source=collection_archive---------10-----------------------

理解前沿自然语言处理的直观可视化指南

Johannes Plenio 在 Unsplash 上拍摄的照片

G PT-3、BERT、XLNet,所有这些都是自然语言处理(NLP)的当前艺术状态——并且它们都使用一种称为转换器的特殊架构组件。

毫无疑问,《变形金刚》是过去十年人工智能领域最大的发展之一——让我们越来越接*人类不可想象的未来。

尽管如此,尽管它们很受欢迎,但变形金刚一开始看起来可能会令人困惑。部分原因似乎是因为许多对 transformer 的“介绍”忽略了与理解 transformer 模型架构本身同样重要的上下文。

如果不先了解注意力和注意力从何而来,怎么能指望任何人掌握变形金刚的概念呢?这是不可能的。

这就是我写这篇文章的动机。我们将通过变压器模型直观地探索信息流,直观地掌握这些系统的机制——触及魔法背后的数学。

我们将涵盖:

**Attention**
- Attention vs Recurrence**Positional Encoding****Self-Attention****Multi-Head Attention**

注意力

注意机制早于变形金刚,最初用于增强 NLP 中以前的尖端技术——递归神经网络(RNNs)。

最初,这些 rnn 通过单点联系共享信息,这意味着大多数输入和输出单元之间没有直接连接,从而导致信息瓶颈和远程依赖性的有限性能。

注意编解码器 LSTMs。

添加了两层简单、紧密连接的神经网络,一层用于消耗所有输入值的编码器,另一层用于解码器,解码器会将当前时间步长的隐藏状态传递给注意力操作[1]。

注意操作产生一个“对齐”分数,该分数连接到解码器隐藏状态,并且执行 softmax 操作以产生输出概率。

信息通过查询、键和值张量在 rnn 和编码器-解码器之间传递。查询是从解码器隐藏状态传递的,而键值张量是从编码器隐藏状态传递的。

英法翻译任务中编码和解码神经元间的注意。图像源[1]。

当单词表征被发现具有高相似性(对齐)时,注意力操作会分配一个高分,而那些具有低相似性的单词表征会分配一个低分。

这种机制产生了一种被称为注意力的行为,即输出层中的单元可以关注输入层中特定的相关单元。

注意力与复发

在变形金刚和注意力之前,我们有 RNNs。由于它们的重现,这些网络非常适合语言任务。

这种循环允许神经网络记录一个单词是否出现在序列中,并考虑它周围的单词——甚至是它之前或之后很久的单词。正因为如此,人类语言的细微差别才能得到更好的体现。

注意力的架构就是你所需要的变压器。改编自同一篇论文。

然而,这种新的注意力机制被证明非常强大。强大到足以让 2017 年一篇名为的论文【注意力是你所需要的全部】推出一个没有复发的模型,用注意力完全取代它【2】——第一个变形金刚模型。

三种机制使注意力工作而不需要重现——(1)位置编码,(2)多头注意,和(3)自我注意。

位置编码

正如我们提到的,在《变形金刚》之前,NLP 的前沿是 rnn——特别是使用长短期记忆(LSTM)单元的 rnn。

LSTM 单元的状态作为输入传递给下一个单元。

信息可以通过单元状态(顶行)以较少的转换传递更远的距离。

本质上,这些网络能够通过将一个单元的输出状态(在 t-1 )传递给下一个单元的输入状态(在 t )来考虑单词的顺序。

Transformer 模型不像 rnn 那样是顺序的,因此需要一种新的方法来保存现在缺失的顺序语义,这种语义以前允许我们考虑单词的顺序,而不仅仅是它们的存在。

为了保持单词的位置信息,在进入注意机制之前,将位置编码添加到单词嵌入中。

《注意力就是你所需要的》一文中采用的方法是为嵌入维中的每一维生成不同的正弦函数。

还记得我们之前说过 word2vec 引入了用 50 到 100 维的向量来表示单词的概念吗?这里,在 Vaswani 等人的论文中,他们使用了相同的概念,但表示一个单词的位置。

交替位置编码值。使用字位置 pos ,嵌入尺寸 i ,嵌入尺寸数量 d_model

但是,这次不是使用 ML 模型计算矢量值,而是使用修改后的正弦函数计算矢量值。

正弦之后是余弦函数。这种正弦-余弦-正弦的交替模式对于嵌入索引中的每个增量持续。

每个向量索引被分配一个交替的正弦-余弦-正弦函数(索引 0 是正弦;索引 1 是余弦)。接下来,随着索引值从零向 d(嵌入维数)增加,正弦函数频率降低。

使用总嵌入维数为 20 的前五个嵌入指数的正弦函数。嵌入索引位置显示在图例中。

这样做的最终效果就像一个有很多指针的时钟。我们输入的每一个令牌都是向前一个时间步长。第一根指针(索引 0,正弦)开始指向 12,并在 100 个时间步长内围绕时钟旋转八次,以到达序列的终点。

下一个指针(索引 1,余弦)开始指向 6,并在 100 个时间步长内绕时钟旋转略少于 8 次(比如 7.98 次)。

这种旋转(频率)随着我们增加嵌入维数的指数而减少。在到达最终指针时(A. Vaswani 等人论文中的第 512 次),指针将在 100 个时间步长内从 12 点移动到 12 点过 0.001 秒。

将所有 512 个时钟指针绘制成正弦曲线,如下所示:

如果我们将时钟停在任何一个时间步长,位置 20,我们对该时间步长的位置编码是时钟指针指向的所有值的向量。

我们可以将上面同样难以控制的正弦曲线绘制到更容易理解的热图上:

我们可以在较低的嵌入维度中看到较高的频率(左侧),随着嵌入维度的增加而降低。在第 24 维附*,频率降低了很多,以至于我们在剩余的(交替的)正弦余弦波中不再看到任何变化。

最后,这些位置编码被添加到单词嵌入中。

要将这两个向量相加,它们需要有相等的维数。Vaswani 等人对单词和位置嵌入都使用了 512-嵌入向量[2]。

自我关注

以前,我们使用模型输入和输出层来计算注意力——自我注意力只允许我们使用其中的一个。

LSTM 编解码器模型中的原始注意机制(左)和自我注意机制(右)。

因此,之前从输入编码器中提取的 K ey 和Vvalue 以及从输出隐藏状态中提取的Query——我们现在从单个输入嵌入数组中获得所有三个值。

自我注意允许输入相互作用——这意味着我们可以对同一输入中单词之间的“对齐”进行编码。例如:

用两个略有不同的短语自我关注。来源[3]。

第一张图片(左)显示,当最后一个单词是“累”时,单词“它”的注意力集中在“动物”上。当最后一个字改成‘宽’的时候,‘它’的注意力就把焦点转移到了‘街’上。

当通过自我注意单元时,单词之间的这种关系被编码到张量中。

英法翻译任务中编码和解码神经元间的注意。图像源[1]。

正常注意力只会在输入和输出序列之间执行这种操作——如上面的热图所示。

多头注意力

多头关注是第一个变形金刚成功的关键因素。没有它,结果显示它的表现比它的重复出现的前辈更差。

多头注意是指并行处理多个注意‘头’。这些多个头的输出被连接在一起。

在我们产生了我们的位置编码单词嵌入张量之后——我们将它们传递给多头注意力单元。“多头”部分意味着我们实际上是在并行运行多个自我关注单元。

一旦多个注意力单元并行处理了我们的张量,结果就会连接在一起,通过线性单元调整大小,并传递到下一步。

两个头(左)和八个头(右)的多头注意力示例[5]。

现在,使用多头注意力的力量来自于同时包含几个代表子空间。这允许一个子空间识别出 it之间的关系,以及另一个子空间识别出 it之间的关系。

变压器模型中不需要多头关注。BERT 是世界上最强大的 NLP 模型之一,它将单头注意力单元和前馈单元串联起来,但没有利用多头注意力[4]。

关于变形金刚的介绍就到此为止。我们涵盖了:

  • RNNs 和编码器-解码器机制
  • 注意编码器-解码器
  • 注意和变形金刚
  • 位置编码
  • 多头注意力
  • 自我关注

所有这些都是非常抽象的概念,很难让我们理解。然而,它们构成了 NLP 中现代标准的基础,并产生了真正的下一级结果,因此值得花时间去研究。

我希望这篇文章能够帮助您更好地理解这些概念,以及它们如何在 Transformer 中结合在一起。如果你想了解更多,我在 YouTube 上发布了编程/ML 教程

如果你有任何问题、想法或建议——通过 Twitter 或在下面的评论中联系。

感谢阅读!

参考

[1] D. Bahdanau 等人,联合学*对齐和翻译的神经机器翻译 (2015),ICLR

[2] A. Vaswani 等人,注意力是你所需要的全部 (2017),NeurIPS

[3] J. Uszkoreit, Transformer:一种新颖的用于语言理解的神经网络架构 (2017),谷歌 AI 博客

[4] J. Devlin 等人, BERT:用于语言理解的深度双向转换器的预训练 (2019),ACL

[5] J .阿拉玛,《图解变形金刚》 (2018),GitHub

[6] I. Sutskever 等人,用神经网络进行序列间学* (2014),NeurIPS

[7] K. Cho 等人,使用用于统计机器翻译的 RNN 编码器-解码器学*短语表示 (2014),EMNLP

🤖《变形金刚》课程 NLP 的 70%折扣

如果你想更好地理解过去十年 NLP 中变形金刚的起源,我会在本文中详细介绍:

[## 自然语言处理的发展

对过去十年自然语言处理的直观视觉解释

towardsdatascience.com](/evolution-of-natural-language-processing-8e4532211cfe)

*所有图片均由作者提供,除非另有说明

推特的形象选择是如何偏颇的

原文:https://towardsdatascience.com/how-twitters-image-choice-is-biased-8d3f0ba63379?source=collection_archive---------47-----------------------

但这不一定是种族歧视

Ravi Sharma 在 Unsplash 上拍摄的照片

Twitter 显示共享图片的预览图片。如果长宽比不是想要的,图像需要被裁剪用于预览。

种植的方式应该不是随机的。人们似乎认为它是“聪明的”,因为它选择了图像中有趣或合理的部分。也许选择了一种点击量最大的作物。

到目前为止,一切顺利。但是现在有了这个:

你可能看不到它,但是有两个图像:一个是参议员麦康奈尔,一个是前总统奥巴马。Twitter 选择在两张图片上都显示麦康奈尔。

德国喜剧演员 Abdelkarim 指着推特说,最好是金发碧眼的人:

像这样的 推文还有很多。对许多人来说,这种对某些图片的偏见似乎是种族歧视。

推特预览中白人比黑人出现的次数多吗?

后续推文肯定非常有趣,表明可能存在问题。从局外人的角度来看,这很难说。Twitter 当然会收到成千上万的图片,并为它们创建预览。一个公司的合理目标是最大化点击量。例如,Twitter 可以简单地根据用户改变预览图像。这意味着 Twitter 试图估计哪些用户更频繁地点击哪些类型的图片。如果用户更频繁地点击白人,那么它会更频繁地显示白人。

我不是说这是会发生的事情,但它可能会发生。

我们假设不是。让我们假设每个人在所有情况下都看到相同的预览图像。那么你仍然可以对点击率进行全局优化。如果推特用户更频繁地点击白人,推特用户就会看到白人。

有偏见的数据导致有偏见的结果

2016 年,《卫报》发表了一篇非常相关的文章,内容是一个 AI 评判美貌并偏爱白人:

[## 一场选美比赛由人工智能评判,机器人不喜欢黑皮肤

第一次由“机器”评判的国际选美比赛本应使用面部等客观因素…

www.theguardian.com](https://www.theguardian.com/technology/2016/sep/08/artificial-intelligence-beauty-contest-doesnt-like-black-people)

这篇文章中有一个关键要点:

机器学*系统需要数据。如果数据有问题,机器学*系统就有问题。

这个人工智能是在一个几乎没有黑人的数据集上训练的。机器学*算法从中得出的概括是,黑人与赢得这场比赛没有很好的关联。这是正确的。它成问题的地方在于它被用来判断“客观”的美。它是一台机器,不能有偏见。对吗?

偏见和种族主义

这肯定是有趣的琐事,但它有更大的影响吗?推特上曝光少的效果甚至是负面的吗?

肯定很奇怪,肯定应该修好。不过,我不认为这是种族歧视。在我看来,一些 Twitter 开发者不太可能有邪恶的总体计划来伤害黑人,他们宁愿展示白人,以防两种图像作物是可能的。称这是种族歧视分散了我们对过去几个月里看到的许多种族歧视案例的注意力。人们知道行动者意识到他们的行动可能产生的影响的事件。导致死亡的事件。

一个软件开发人员编写一个比随机裁剪更智能的图像裁剪算法并不是种族歧视。如果下面的说法是正确的,那简直就是草率的工作。

我自己也试过上传四个天线宝宝的图片。你现在可能会因为它显示的是一个只有白色的图像而感到愤怒,或者只是得出结论说这个算法相当糟糕:

针对有偏见的 AI 产品,我们能做些什么?

算法可能有偏差的一个简单原因是类别不平衡。与生产数据相比,这还可能与训练数据的不匹配相结合。一个类只是在训练数据集中更频繁地出现。处理较频繁类别的一种技术是对不太频繁的类别进行过采样,或者对较频繁的类别进行欠采样。这意味着该算法可以更频繁地查看代表性不足的类的训练数据。

通常,还可以找到特定应用的解决方案。例如,Twitter 可以干脆不显示预览图片。或者显示随机的作物。让用户选择作物也是一种选择。当谷歌面临机器学*产品的偏见问题时,他们也选择了一个激烈的选择:

[## 谷歌对意外算法种族主义的解决方案:禁止大猩猩

2015 年,谷歌因一种图像识别算法将黑人照片自动标记为…

www.theguardian.com](https://www.theguardian.com/technology/2018/jan/12/google-racism-ban-gorilla-black-people)

后处理是另一种选择。如果你注意到两个收成好的候选人都有脸,抛硬币决定哪一个脸会出现。你也可以尝试变得超级聪明,识别名人,并根据他们在过去 24 小时内的标签/提及量对他们进行排名。

有更多的事情要考虑。如果你感兴趣,我鼓励你阅读下面的文章。

请参见

优步如何通过 ML 提供卓越的客户体验

原文:https://towardsdatascience.com/how-uber-delivers-exceptional-customer-experience-with-ml-c208887a616f?source=collection_archive---------30-----------------------

在全球范围内提供卓越的客户体验

照片由丹金Unsplash 上拍摄

全球各地的品牌,无论大小,都竭尽全力为顾客服务。他们知道他们的生意和他们最不满意的顾客一样成功。

我们之前在一篇文章中介绍了优步案例研究的一部分,该文章讲述了数字时代客户体验的转变,以及全球品牌用来让客户脸上露出笑容的方法。

数字时代带来了技术,使我们能够获得大量关于客户偏好、行为和痛点的数据,使用人工智能和人工智能分析这些数据,并获得关于如何相应地塑造我们的产品和服务的超级具体的见解。

照片由 Kon KarampelasUnsplash 上拍摄

优步知道如何利用机器学*来取悦他们的客户。

在接受 Hyperight 采访时,优步的技术主管 Ritesh Agrawal 强调了优步的基于 ML 的功能,这些功能有助于增强骑手的体验:

  • 基于乘车历史和经常旅行的目的地的个性化目的地建议。
  • 一键式聊天——一个智能回复系统,让乘客和司机可以通过应用内消息轻松沟通。该系统使用机器学*和 NLP 来预测对常客问题的回答。司机只需点击一个按钮就可以回复。
  • 弥合供需差距——优步的系统预测时间段和区域的需求将会增加,并相应地提醒司机。满足提货时间的需求有助于优步保持客户满意度并提高客户保留率。

但是,人工智能和机器学*在优步的一个关键应用是检测和解决用户体验事件,以确保他们的应用程序在任何时候都是正常运行和可靠的。

Hyperight AB 在数据创新峰会上的照片 /版权所有

推出像《速度与激情》这样的改变

在 2019 年的 数据创新峰会 上,Ritesh Agrawal 和阿南朵·森讲述了他们的故事,讲述了优步如何在一个非常分散的市场中快速而安全地扩展,以及他们遇到的挑战和他们为让司机和乘客都满意而做出的不断变化。

阿南朵强调,每天都有成千上万的人依靠优步去工作、通勤或开车去优步谋生。这就是为什么优步认真对待他们的工作,检测用户问题并尽快修复,同时尽可能以最安全的方式进行。

Hyperight AB 在数据创新峰会上的照片/版权所有

每个月,优步都会进行 1200 次代码更改和 22000 次配置更改,这使得该应用程序可以针对其运行的每个城市进行调整。然而,以极快的速度对应用程序、分布式系统和基础设施进行变更会导致可靠性问题。

为了衡量这款应用是否始终可靠,优步衡量了三个关键绩效指标:

  • 可用性——乘客是否能够叫到车并完成旅程。
  • 等待时间——完成整个叫车流程、系统流程、屏幕转换、标签功能所需的时间。
  • 信息、地图、价格、折扣的准确性。

阿南朵指出,向用户交付变更的速度和他们的整体服务可靠性之间有很强的相关性。

跟踪面向用户的事件

这种关联最重要的一点是,优步能够检测面向用户的事件,并将其归因于他们的代码或配置,让人们修复它们,并快速推出缓解措施。

“检测和解决事故的时间应该是主要公司的关键绩效指标之一”,阿南朵建议。然而,仅仅认识到这个问题是不够的。

他解释说,如果他们在数据管道的开端就发现问题,成本几乎是不存在的。当在推广阶段发现问题时,成本开始上升。这就是为什么快速移动、检测和解决以减少用户糟糕体验的爆炸半径至关重要,而不是影响 100 万用户,而是影响 10,000 个用户。

图片由freestocks.orgPexels.com

从数据科学家的角度来看,Ritesh 专注于将这样一个模糊的问题(作为一个事件)转化为具体的、可操作的项目。

当他们仔细查看事件报告,试图了解错误的来源时,他们发现 40%的事件是与代码相关的更改,但 20%是与配置相关的更改。问题在于构建代码和配置的人与应用配置变更的城市运营团队之间的脱节。

视频由hyperlight AB——向全球分布式市场传递变革——优步的里泰什·阿格拉瓦尔和优步的阿南朵·森

由于在超过 64 个城市运营,优步应用程序根据不同的位置定制了不同的产品选择。例如,旧金山的车辆选择是电动自行车,而在德里,应用程序提供自动。每个城市的产品选择由配置决定。此外,每个城市的促销和地图都可以通过配置来实现。

正如 Ritesh 解释的那样,配置的最大好处是它允许创建一个全球应用程序,但针对本地城市性能进行优化。最重要的是,它提供了实验能力。

然而,它并非没有挑战。Ritesh 说,配置很难审查,因为它们是立即推出的。配置中的每一项更改都适用于全球所有应用程序用户。因此,如果配置有错误,它将随更新一起推出。

为了取得控制权,他们开始考虑构建一个 ML 解决方案,通过检查来自配置的信号来自动检测应用程序是否有任何问题。它们将这些信号与配置前的信号进行比较,并执行 A/B 测试,以确认是否发生了错误。

图片由奥斯丁·迪斯特尔Unsplash 上拍摄

从利用 ML 和数据科学交付快速和激情的用户体验中学到的东西

Ritesh 强调,对于像优步这样的全球广泛使用的应用程序,定制是必要的,但与此同时,他们必须关注可靠性。

事故总是会发生,但关键是要尽快发现它们。检测和解决关键绩效指标的时间有助于优步处理这些事件。

此外,在基础设施层面部署 ML 解决方案时,Ritesh 建议不要从一个全新的系统开始。相反,他们利用他们的开发人员和工程师正在使用的系统,并对其应用自动化。工程师应该能够理解 ML 模型并将错误与实际代码联系起来。

最终从商业角度来看,阿南朵得出结论,投资回报率真的很重要。应对 ML 解决方案、基础设施、培训和部署的投资与检测到的事故数量和爆炸半径的减小进行权衡。每一个成功的数据科学和基于机器学*的努力都应该建立在双向道路上,投资与投资回报挂钩,这样才能长期持续。

本文原载于 Hyperight.com

优步如何利用合成数据加快训练速度

原文:https://towardsdatascience.com/how-uber-uses-synthetic-data-to-speed-up-training-cc989c23ded4?source=collection_archive---------24-----------------------

优步人工智能实验室最新成果综述

照片由freestocks.org像素上拍摄

最*,优步人工智能实验室发表了一篇题为生成式教学网络:通过学*生成合成训练数据来加速神经架构搜索的论文。在这篇论文中,作者概述了一种新的学*算法,用于自动生成数据、学*环境和课程,以帮助 AI 智能体快速学*。论文可以在这里找到。

动机

什么时候使用合成训练数据比使用所有可用的真实数据更有帮助?

人工智能研究的专家们正慢慢开始放弃数据越多越好的想法。通过对训练数据的子集进行智能采样而生成的替代数据集可以产生可比较的测试性能和较少的训练工作。在深度学*的背景下,这相当于有效地搜索最佳神经网络架构。智能子采样大大减少了训练工作量,因为在全数据集上训练成千上万的候选神经网络结构通常是昂贵的。

相关工作

可以通过对训练数据的子集进行智能采样来创建替代数据集。这种替代物能够以较少的训练努力实现有竞争力的测试性能。

文献中有几个应用替代训练数据的例子,包括课程学*、主动学*和核心集选择:

课程学*

Graves 等人介绍了一种自动选择路径或教学大纲的方法,神经网络通过课程遵循该方法,以最大化学*效率。

主动学*

科纽什科娃等人。艾尔。,提出了一种新的数据驱动的主动学*(AL)方法,其中他们训练了一个回归器,该回归器预测特定学*状态下候选样本的预期误差减少。

核心集选择

塞内尔等人。艾尔。,将主动学*定义为核心集选择。核心集选择通过选择一组点来工作,使得在所选子集上训练的模型对于剩余的数据点是有竞争力的。

优步论文的关键观点是,替代数据不需要来自原始数据分布。他们举的一个例子是,人们通过阅读一本书来学*一项新技能,或者通过练*传球或运球来准备像足球这样的团队比赛。

本文的目的是研究一个数据生成神经网络是否能够产生合成数据,从而有效地向学*者教授目标任务。

生成式教学网络

在他们的论文中,优步人工智能实验室提出了生成教学网络(GTNs):一种可扩展的,新颖的元学*方法,用于生成合成数据。

如前所述,GTNs 的任务是产生一个数据生成神经网络。在生成 GTN 时,神经网络学*器在由 GTN 生成的数据上被训练。GTN 和学*者网络合作(与竞争的 GANs 相反),以便在目标任务中快速产生高准确度。

结果

在这项研究中,作者证明了 GTNs 可以生成一个合成的训练集,与在完整数据集上的训练相比,它可以在两个监督学*域 MNIST 和 CIFAR10 中加速学*。

MNIST

MNIST 数据集包含手写数字(从 0 到 9),通常用于训练图像处理系统。这种情况下的学*任务是手写数字的分类。

从 MNIST 结果中得到的关键信息是,GTN 方法比在真实数据和真实数据的子样本上训练收敛得更快,迭代次数更少。虽然收敛的误差在量级上比基于真实数据训练的模型大,但是它离真实数据的收敛值不远,即使它花费了较少的迭代。

CIFAR10

CIFAR10 数据集包含 10 类不同的图像,包括汽车、鸟类、猫、鹿、狗、青蛙、马、船只和卡车。它还通常用于训练图像处理系统,用于图像分类。

类似于 MNIST 的例子,GTN 差错率的平稳期比真实数据差错率的平稳期快得多,在真实数据的情况下,真实数据在 120 次内环迭代之后还没有达到收敛。

结论

在这篇文章中,我们回顾了优步人工智能实验室为加速学*生成合成数据的新方法。gtn 基本上与 GANs 相反,在 GANs 中,两个网络合作以最小化学*者的错误率。当在 MNIST 和 CIFAR10 数据上训练时,GTN 方法加速了图像分类任务中的误差收敛。可能的进一步应用包括使用强化学*来产生促进学*的新任务。另一个可能的应用是开发方法,可以用来哄 gtn 产生虚拟世界,供我们学*、玩耍或探索。

我希望你觉得这篇文章很有趣!

新冠肺炎监督测试的可信度有多高?

原文:https://towardsdatascience.com/how-un-trustworthy-are-the-covid-19-surveillance-tests-3e5ab9134944?source=collection_archive---------53-----------------------

测试结果的贝叶斯推断

Graham Ruttan 在 Unsplash 上拍摄的照片

随着新冠肺炎疫情的延长,重新开放经济的需要日益强烈。为了做好准备,最*进行了一些调查,试图确定这种疾病的流行程度。截至 2020 年 4 月 25 日,美国进行了三项新冠肺炎抗体监测试验:

  1. 加州圣克拉拉县调查于 4 月 3~4 日进行。估计有 2.49%~4.16%的人已被感染。
  2. 加州洛杉矶县调查于 4 月 10~11 日进行。据估计,该县 2.8%~5.6%的成年人口已被感染。
  3. 纽约州在四月下旬进行了调查。据估计,纽约市有 21%的人被感染,全州各县有 3%~17%的人被感染。

这些数字令人震惊。他们翻译成我们大多数人应该已经有几十个直接的熟人被新冠肺炎感染了。这可能是真的吗?

让我们深入了解一下。圣克拉拉县调查预印本的第一作者 Eran Bendavid 是斯坦福大学的医学副教授。洛杉矶县调查是由南加州大学进行的。两家都相当有声望。然而,截至 2020 年 4 月 25 日,圣克拉拉县调查没有经过同行评审,洛杉矶县调查也没有预印本。纽约调查的信息甚至更少。我们知道科学关乎事实,而不是名声。那么如何快速判断这些数字的可信度呢?

让我们首先浏览一下圣克拉拉县调查的主要内容。

该调查测试了 3300 人,其中 50 人结果呈阳性(粗患病率 50/3300 = 1.5%)。在对更能代表该县人口的邮政编码、种族和性别进行调整后,他们估计患病率为 2.49%~4.16%。然后他们将这个数字乘以圣克拉拉县的人口数(大约 190 万),得出结论:

这些流行率估计数表明,截至 4 月初,圣克拉拉县有 48,000 至 81,000 人感染,比确诊病例数多 50-85 倍。

现在你可以看到预印本基本上把测试阳性当作被感染(真正的阳性)。尽管这看起来很直观,但实际上是正确的吗?让我们正式地说,

假设一个人被检测为阳性,这个人是真正阳性的概率是多少?

一旦我们框定了关键问题,使用贝叶斯规则就很简单了(“P”表示正面,“N”表示负面,如下所示):

因为灵敏度、特异性和先验被定义为:

我们可以用全概率定律展开分母,代入上面三项,然后就有了后验估计:

在预印本中,敏感性估计为 80.3%(95 可信区间为 76.0–88.4%),特异性估计为 99.5%(95 可信区间为 99.2–99.7%)。

对于先验,我们可以使用人口患病率作为起点。4/3~4/4 圣克拉拉县累计确诊病例约 1100 例 。除以全县人口 190 万,可以得到 0.05%左右的先验。

将这些数字代入等式(1),我们将得到

这意味着,即使一个人被检测为阳性,这个人仍然很可能是阴性的

这个结果起初看起来似乎是反直觉的,难道我们不应该期待一个阳性结果表明一个感染者吗?

这是钥匙。我们平时在新闻中遇到的确诊计数,是通过一种基于 RNA 的“诊断检测”来确定的,而不是基于抗体的“监测检测”。除了在灵敏度、特异性和许多其他方面的差异,一个主要的差异是在测试参与者中——诊断测试通常需要一些原因来怀疑一个人被感染,而监测测试的参与者是普通公众。用数学术语来说,测试参与者的先验是不同的。

例如,以下是伊利诺伊州公共卫生部网站上的诊断测试指南(截至 2020 年 4 月 26 日):

只要想想你的许多直接朋友满足了这些要求,你就可以估计出这些诊断测试参与者中被感染的先验概率可能比普通大众高 100 倍。因此,来自诊断测试参与者的阳性测试结果确实最有可能指示真正的阳性(病毒的存在)。

有人可能会说,上述 0.05%的先验概率太低了,因为许多真正的感染者没有去检测。这是一个合理的考虑,所以我们可以用不同的方法来估计先验。例如,测试阳性率(给定有症状的人)通常来自 10%~30%⁴.如果我们认为一个有症状的人被感染的可能性是 50-100 倍,那么我们可以得出 0.2%-0.5%的先验。但是,即使有 0.5%的先验,给出肯定结果的后验概率也只有 45%,或者和掷硬币差不多。

下面是在不同的先验和特异性水平下,给定阳性检测结果,成为真正阳性的概率图。来自圣克拉拉公众的先验在左边是虚线,来自诊断测试参与者的先验在右边的某处。因此,来自不同参与者的积极结果具有非常不同的含义。

现在很清楚,即使圣克拉拉调查的样本代表了人口,其患病率估计也可能被夸大了约 10 倍。难怪这份预印本招致了专家们对 T4 的大量批评。正如哥伦比亚大学统计学和政治学教授 Andrew Gelman 在他的博客中写道:

“我认为上述论文的作者应该向我们所有人道歉……我们浪费了时间和精力来讨论这篇论文,因为它的主要卖点是一些数据,而这些数据本质上是统计错误的产物。”

对于洛杉矶县和纽约州的另外两项调查,信息的缺乏阻碍了详细的讨论。但是从结果来看,他们看起来和圣克拉拉县的研究相似。因此,在进一步的信息披露之前,我们应该怀疑这些结果。

进一步讨论:

有人可能会想,给定一个阳性监测测试结果,如果那个人真的呈阳性的几率如此之低,那么这个结果告诉我们什么?

我的回答可以分为两个方面:

  1. 为了计算抗体流行率,这类阳性病例不应计算在内(或必须适当扣除)。提高后验概率的一种方法是进行独立的随访测试。并且后续检测必须再次显示阳性,才能确认抗体的存在(不同于病毒的存在)。
  2. 然而,出于预防的目的,态度是不同的。即使一个人仍然最有可能是消极的,他积极的机会也比普通大众高得多。因此,他应该进行诊断测试,检查病毒是否仍然存在,或者他的主要接触者应该采取措施加以保护。

参考资料:

  1. 加州圣克拉拉县新冠肺炎抗体血清阳性率:https://www . medrxiv . org/content/10.1101/2020 . 04 . 14 . 20062463 v1

2.南加州大学洛杉矶县研究:抗体检测的早期结果显示新冠肺炎感染人数远超
洛杉矶县确诊病例数:https://content . gov delivery . com/accounts/cala County/bulletins/2877402?reqfrom =份额

3.约翰霍普金斯大学新冠肺炎数据来源:https://github.com/CSSEGISandData/COVID-19

4.加州的测试数据不可靠。我采取了圣克拉拉项目前 2 周的数据(3/22 ~ 4/4)。从执行的大约 101k 次总测试中,阳性总数为 10.7k。所以阳性率~10.6%。伊利诺伊州的检测数据稍微可靠一点,其阳性率在那段时间内波动在 20%左右。

如何利用冠状病毒危机启动你的数据科学职业生涯

原文:https://towardsdatascience.com/how-use-the-coronavirus-crisis-to-kickstart-your-data-science-career-5dd0453549a0?source=collection_archive---------29-----------------------

随着全球经济衰退,谷歌、亚马逊等公司正在大举招聘

从招聘潮中获利,找到你的理想工作。布鲁克·卡吉尔在 Unsplash 上的照片

T T 数据科学的伟大之处在于你可以在家完美地完成它。也就是说,如果全球疫情没有在外面肆虐,你没有孩子在家上学,没有老人需要照顾,你也不会面临导致数百万人失业的经济衰退——可能包括你。

如果这让你觉得你在往下看,你并不孤单。为了度过危机,数百家科技公司正在进行大规模裁员,其中包括硅谷的数十家初创公司。

这对你来说是个千载难逢的机会。

随着大多数公司解雇他们心爱的员工,其他公司也开始大肆招聘。想想亚马逊脸书苹果谷歌

[## 脸书数据科学家访谈

脸书数据科学家的职位是科技界最令人垂涎的职位之一。Jay Feng 解释了如何着陆。

towardsdatascience.com](/the-facebook-data-scientist-interview-38556739e872)

理论很简单:以前在其他地方工作的数千名有才华的数据科学家突然变得有空了。这意味着就业市场的高供给和低竞争。

因此,从一家大型科技公司的角度来看,他们可以以较低的收购成本雇佣大量员工——此外,这些人甚至可以接受比通常提供的更低的工资和更少的福利。因为这总比失业好。

如果你想在你梦想的公司得到一份数据科学的工作,现在正是时候。但你不能坐视不管,任其自然发展。你必须努力让自己受到关注。展示你有才华,愿意并且能够抓住机会。以下是方法。

1.给你的 LinkedIn 拉皮条

这是一个求职平台。当然,你也可以推销你的其他社交媒体——你应该这样做。但是你的首要任务是在 LinkedIn 上找到一个杀手级的平台。

尽管这个平台的设计非常直观,我还是建议遵循 LinkedIn 的指南来做好一切。

尝试填写每个个人资料部分。添加一张背景照片,添加一些技能,关注你所在行业的名人。也加入一些相关的团体。

此外,没有办法添加个人资料照片。是的,你在照片上看起来总是很蠢。在角落里看到自己的影像感觉很尴尬。我明白了。但还是要做。一张你看起来很丑的糟糕照片总比没有照片好。一旦有了更好的照片,你可以随时更换。

试着用你的个人资料讲一个故事。想想一个很酷的标题:“XYZ 公司的数据科学家”很无聊。这个怎么样:“为 XYZ 公司解开数据的秘密”。好多了!尽量想出标题和描述,不要反映你做什么,而是你是谁。

[## 2020 年改善 LinkedIn 档案的 20 个步骤

如何利用 LinkedIn 打造你的个人品牌,由 LinkedIn 自己讲解。

business.linkedin.com](https://business.linkedin.com/en-uk/marketing-solutions/blog/posts/content-marketing/2017/17-steps-to-a-better-LinkedIn-profile-in-2017)

2.修改你的简历

招聘人员平均在你的简历上花7 秒。是的,你没听错。七个。

所以要珍惜这七秒钟。另一个人在七秒钟内会看到什么?在那个时候,你的简历能传达什么信息?

我用大量的视觉元素、颜色对比和清晰的信息来突出我的作品。我想让招聘人员知道我花了一些心思,我很勇敢,我知道我是谁。这是我最*的一份简历:

一个可能的科学合作的作者最*的简历。出于隐私考虑,省略了一些联系方式。

请注意,我使用了一些带有星星、其他符号和时间线的视觉语言。我还添加了我在任何地方都使用的同一张个人资料照片——这就是个人品牌 101。你可以随意模仿我的任何技巧。

当然,你很难用一个标准的 word 文件得到这样的设计。我用 Adobe Illustrator 做了这个简历。你也可以使用 Figma,它非常好用,而且花费更少。您将花几个小时摆弄图形细节,但这是值得的。真的。

3.定期发送申请

发出申请往好了说是耗时,往坏了说是令人焦虑。但是现在你已经做了一份很棒的简历,是时候向世界展示你的实力了!

不管你是担心自己会失业,还是已经失业了——当你刚刚寄出 24 份申请,然后又担心两个星期都得不到一个答复时,那就太可怕了。我去过那里。

但是掌握一项不舒服的活动的最好方法是有规律地做。即使你有一份稳定的工作,发出申请也没有坏处。你可以随时撤回。即使在这种情况下,你也可以在未来几年建立有价值的联系。

如果你的工作不那么稳定,你会失去什么呢?目前,计划每周发出五份申请。或者你需要多少。不过,要注重质量。也可以申请那些你认为不是百分百合格的工作。你能得到的最糟糕的答案是不。

这实际上也行得通。照片由 chuttersnapUnsplash 上拍摄

4.去虚拟聚会

你的人脉就是你的净资产。

想想你是怎么找到上一份工作的。是冷冰冰的申请和几次面试吗?或者你认识一个人,而这个人又认识另外一个人,这个人给了你一个很好的介绍给你现在的雇主?

如果是后者,欢迎来到大多数人找工作的方式。尤其是好工作。这是关系网,伙计!

如果你想得到一份好工作,你需要认识一些人。你怎么找到他们的?通过活动、聚会、会议等等。

但是现在我们都被困在家里,看不到现实生活中的事情。坏消息?这是一个好消息,因为这意味着你可以节省大量的旅行费用!改为在虚拟聚会上链接。

当然,与演讲者和其他参与者面对面的会后自助餐式的闲聊是不可能的。但是你可以通过提出聪明的问题或者自己做出贡献来让自己受到关注。

像在 Zoom 或 Skype 上一样,向您感兴趣的发言人或任何参与者发送私人消息。告诉他们你有多重视他们的谈话或个人资料。

一开始可能会显得很尴尬,你会想知道他们是怎么看你的。所以不要发垃圾邮件,要尊重。如果你照着做,会有比你想象的更多的人回应你。

5.做演出

不管你有没有工作,不管你银行里有没有足够的现金,都要去演出!

即使他们报酬很低或者根本没有钱。即使你只是偶然在 Upwork 或 Fiverr 上得到它们。即使你的妈妈或邻居只是请你帮忙。

这样做的目的是不要让自己被工作压得喘不过气来。相反,音乐会是一个与新朋友联系和展示你工作的绝佳机会。

在我找到现在的职位之前,我免费工作了整整两年。然后我又实*了整整一年,工资还不够我一半的开销。为了收支平衡,我到处做其他的演出。这并不容易,但它让我走到了今天。

即使现在我有一个相当安全的位置,我继续做演出。付不付没多大关系。每次我都把它视为一个机会,让人们加入到一个在某个时候可以防弹的网络中。

演出的目的是了解人们。你认识的人越多,有人给你薪水的机会就越大。把你推荐给其他人,他们会给你一个更大的。

给人跑腿。他们会将你添加到他们的网络中。在 Unsplash 上由 Austin Distel 拍摄的照片

6.开始写博客(或者推特风暴,如果你觉得懒的话)

不要等着别人来问你的意见。给他们。

写作也许是建立你个人品牌的最好机会。人们会了解你如何表达自己,你如何思考,什么对你来说是重要的。

此外,一堆漂亮的文章会让人们浏览你的作品集,并深入你的世界。还记得人们花在你简历上的 7 秒钟吗?试着写出足够多——足够好——的内容,让招聘人员愿意花七个小时在你的个人资料上。

我选择 Medium 作为平台不仅是因为它是付费的,还因为我喜欢这个社区。每次我点击发布,都会有很棒的事情发生。有人留下了非常鼓舞人心的评论。一个有着惊人个人资料的陌生人在 LinkedIn 上与我联系。一位名人加入了我在 Twitter 上人数不多但越来越多的粉丝。每次我点击发布,我就扩大了我的关系网。

你的人脉就是你的净资产。你写的每一个字都会让它成长一点。

也许你对自己的写作技巧没有印象。当我开始使用 Medium 时,我对我的并不满意。没关系!

你可以从小步开始。如果你不喜欢全文写作,也许你喜欢发微博。目标是每天发两条你感兴趣的微博。

你的目标是一致性,而不是完美。你不会在一天之内写出一部精彩的小说或一条流行的微博。你也不会在一天之内与比尔·盖茨或勒布朗·詹姆斯联系起来。你可能一辈子都不会。

但是如果你坚持下去,你会建立联系并产生你真正引以为豪的作品。最棒的是,这给了你一份工作。

[## 数据科学入门终极指南

我是如何在不到 6 个月的时间里获得数据科学工作机会的

towardsdatascience.com](/the-ultimate-guide-to-getting-started-in-data-science-234149684ef7)

你的时间到了

世界正在分崩离析,但这不是世界末日。

没人说这会很容易。但是,尽管有这么多的痛苦和悲剧,这场前所未有的危机中蕴藏着前所未有的机遇。

四大正在大肆招聘,就像其他有能力的公司一样。

无论你已经失业,或者你认为你可能会失业,或者你有一份稳定的工作,但认为你可能需要升级——这些公司正在寻找你。所以,让自己受到关注吧!

投票分类器如何工作!

原文:https://towardsdatascience.com/how-voting-classifiers-work-f1c8e41d30ff?source=collection_archive---------19-----------------------

图片来源:我

用于增强分类的 scikit-learn 功能

分类是一种重要的机器学*技术,通常用于预测分类标签。对于进行二元预测或预测离散值,这是一种非常实用的方法。分类器是分类模型的另一个名称,可能用于预测某人是否适合某项工作,或者用于对商店中多个对象的图像进行分类。

分类和其他机器学*技术一样,使用数据集。数据集是来自不同变量的多个值的组合。在获得最佳数据集之后,它被分成两部分:训练集和测试集。训练集通常占数据集的较大比例。它可能会占用数据集的 70%到 90%。

训练集被插入到机器学*算法中,以创建一个预测模型,并增加了一个称为交叉验证的步骤。交叉验证是一种很好的方法,可以确保构建的模型不会过度适应训练集,并且还可以优化模型的通用性。然后,该模型可以用于预测测试集中的标签。通过诸如混淆矩阵、精确度分数、召回分数、F1 分数、roc auc 分数的度量,将预测的标签进一步与实际测试集标签进行比较。

一旦分类模型的构建完成,就可以将数据点的值插入到算法中,并且算法通过基于变量的输入将特定标签归属于该数据点来做出决定。

现在想象一下,如果要求不同的分类方法根据数据实例的输入做出决策。肯定会有不同的答案。这就是投票分类器发挥作用的地方。

什么是投票分类器?

投票分类器是一种使用多个分类器进行预测的分类方法。当数据科学家或机器学*工程师对使用哪种分类方法感到困惑时,它非常适用。因此,使用来自多个分类器的预测,投票分类器基于最频繁的一个进行预测。

在现实生活中,数据科学家可能会对使用随机森林分类器还是逻辑回归器来根据花朵的尺寸预测花朵的类型感到困惑。

使用上面的提示,下面创建了一个分步指南,介绍如何通过 Jupyter 笔记本使用 python 来构建投票分类器。

从下面的代码开始,可以使用 scikit-learn 导入分类器。

**from** **sklearn.ensemble** **import** RandomForestClassifier 
**from** **sklearn.linear_model** **import** LogisticRegression 
**from** **sklearn.neighbors** **import** KNeighborsClassifier
**from** **sklearn.ensemble** **import** VotingClassifier

通过 Jupyter 笔记本使用 python,可以访问 scikit-learn 的集成功能,并导入投票分类器。在上面的代码中有三个其他分类器:随机森林分类器、逻辑回归器和 KNearest 邻居分类器。这三个将归因于如下所示的对象:

log_clf = LogisticRegression()
rnd_clf = RandomForestClassifier()
knn_clf = KNeighborsClassifier()

然后,为投票分类器创建一个对象。投票分类器有两个基本的超参数:估计器和投票。估计器超参数为上述三个分类器的对象创建一个列表,同时为它们指定名称。投票超参数设置为硬或软。

如果设置为硬,投票分类器将根据出现最多的预测做出判断。否则,如果设置为软,它将使用加权方法来做出决定。我建议在使用偶数个分类器时将其设置为软,因为它采用了加权方法;在使用奇数个分类器时,将其设置为硬,因为它采用了“多数人投票”方法。

vot_clf = VotingClassifier(estimators = [('lr', log_clf), ('rnd', rnd_clf), ('knn', knn_clf)], voting = 'hard')

像任何其他机器学*算法一样,投票分类器用于将训练数据集的自变量与因变量进行拟合

**from sklearn.datasets import** load_iris 
**from sklearn.model_selection import** train_test_splitiris = load_iris()
x, y = iris['data'], iris['target']
x_train, x_test, y_train, y_test = train_test_split(X, y, random_state = 42, train_size = 0.85)vot_clf.fit(x_train, y_train)

拟合后,它可用于进行预测,并测量其预测的准确性。

pred = vot_clf.predict(x_test)
accuracy_score(y_test, pred)

下图显示了投票分类器如何用作数据集的预测模型,并与其他分类器进行了比较。代码最初是从 Aurelion Geron 的书中获得的,用 Scikit-Learn 和 TensorFlow 的概念、工具和技术构建智能系统的实践机器学*,我在 Jupyter 笔记本上运行了它们。

显示用于创建投票分类器的代码单元的图像

结论

投票分类器是一种出色的分类方法,因为其方法利用多个分类器的集体判断来预测数据点。我建议其他有抱负的数据科学家和机器学*狂热者尝试一下。

感谢您的阅读!

美国“伟大”的时候税收怎么样?

原文:https://towardsdatascience.com/how-was-taxation-when-america-was-great-24836359aae7?source=collection_archive---------41-----------------------

供图纽约公共图书馆公共领域收藏

了解税收和历史

记得有个人说他要“让美国再次成为伟大的 T2”。那么,美国以前什么时候伟大过?已经澄清了。那是 20 世纪 40 年代末和 50 年代。不管人们是否同意这一评价,这就是他所指的时代。我们就这样吧。所以,如果我们要谈论美国的“伟大”,我们也需要考虑美国政府是如何运作的,有一件事与今天非常不同,那就是所得税的结构。现在,税收对于“让美国再次伟大”的人群来说是一件大事,正如我们所知,所以看看当他们认为美国“伟大”时税收是什么样的会很有用。

是的,这是分析数据的另一个原因。别拿你的呕吐袋。这是其中一次,我将向你们展示如何用非常简单的方法得出有趣的结论。我还展示了如何根据如何对相同的起始数据应用简单的方法来得出非常不同的结论。这是有趣的部分。我认为,任何涉及政治或政治话题的公开文件(以及大多数未公开文件)都有一个议程。数字通常只是用来支持议程的。这并不意味着这些数字是谎言,而是意味着你必须思考才能知道这些数字是否合理。

恰好税收基金会的人公布了 1913 年至 2013 年的所有美国税级,2014 年至 2019 年的可以从多个来源查找。所以,我可以公布每年的最高税率,然后就到此为止!

呜哇呜哇!看那个。喔喔喔!该死。他们的税在很久以前就已经很高了!结案了,该死!

号码

在美国评估的总所得税是而不是最高税级。相反,我们增加了税收。例如:第一笔 10,000 美元的税率为零的税收制度。50,000 美元以下按 5%的税率征税,50,000 美元以上按 10%的税率征税。10 万美元要交多少税?是一万美元吗?没有。就是 0 美元(10%×10,000 美元)加上 2000 美元(5%×(50,000 美元—10,000 美元))加上 5,000 美元(10%×(100,000 美元— %50,000 美元))= 7,000 美元。这比仅将最高税率应用于总收入要少 30%。只引用最高边际税率是愚蠢的——或者不诚实的。

所以,要了解 T2 实际的税收评估,你需要收入。我下载了表 F-1。美国人口普查中五分之一和前 5%家庭的收入限制。这张表总结了从 1947 年到 2019 年(到目前为止)美国家庭收入的每五分之一和最高 5%的最低收入的界限。我希望我可以使用“家庭收入”而不是“家庭”,但我所能获得的信息并不能追溯到那么远的家庭。为什么是家庭?“家庭”的人口普查定义排除了相当多的人。但我不得不尽我所能。

然后,我计算了那一年按各个收入水平评估的联邦所得税总额,包括标准化免税。我使用的税率和免税额度是已婚夫妇每年共同申请的,没有孩子。如果有人想支付我的咨询费,我很乐意把它变得更复杂。鉴于缺乏具体的可用数据(我可以找到),我不得不接受和承认一个严重的过度。

无论如何,当我做所有这些简单的计算(使用 Excel)时,我对 1947-2019 年的税收评估得到了什么?

漂亮的颜色!这些线条显示的是每一个收入五分位的界限。WTF 是收入五分位数?这就是工作原理。根据最接*的收入水平,将美国家庭分成五个同等大小的群体。五:金特,明白了吗?第三个五分位数是非常重要的五分位数。包含中位数的是五分位数。什么是中位数?中等收入是指处于中间的收入——一半的美国家庭收入较低,一半的家庭收入较高。因此,第三个五分位数是对“美国家庭平均收入”的最佳估计,还有一点回旋的余地。

因此,显而易见的是,税收一直在上涨,偶尔还会小幅下跌,结案,码头和垃圾,干草叉,20 世纪 50 年代是包裹在独角兽冰棒棒上的税收天堂。

号码

这个图表是不诚实的骗子使用的诡计,被白痴所相信。1955 年的一美元比 2019 年的一美元值钱得多,所以对一美元征税意味着拿走更多的价值。幸运的是,随着时间的推移,有很多方法可以调整每美元的价值变化,例如消费者价格指数。就拿“当时的美元”乘以(2019 年的 CPI)/(无论何时的 CPI)。“实际美元”或“调整后美元”税收变成:

嗯,嗯,那么,好吧,所以它没有看起来那么糟糕,但仍然,那些“生产者”的税收仍然较低,对不对?什么事?

号码

事情是这样的,即使是“通货膨胀调整”也不能说明一个完整的故事。即使是经通胀调整的收入也随着时间发生了变化。如果你处理的是人口,那么每个五分之一人口的构成可能会以与通货膨胀率不匹配的方式变化。此外,CPI 是一个估计值,所以它有任何估计固有的问题,与估计收入水平相混合。还有什么合理的方式来表示所得税的影响呢?

我提名收入的百分之。只要计算一下税单,除以税前总收入,你就得到:你收入的部分被申报。这与通货膨胀和类似的时间效应无关。这也很容易理解:如果一件事需要你收入的十分之一,我们都可以理解十分之一,无论是时代、单位还是价值。当然,这个百分比是否计算得当是另一回事。因为我不是不道德的,我试着公开我是如何做的,并应用适当的方法(见上文)。

那么,我们看到了什么?首先,如果我们看看第一至第四个五分位数(因为第五个五分位数可以一直达到理论上的无限收入),那么“美国伟大的时代”也是所有美国人的最高有效净税率,而不仅仅是最富有的人!针刮擦声,酒馆安静下来,钢琴演奏者合上键盘藏了起来。自那以后的一个巨大变化是,自 20 世纪 50 年代以来,美国最贫穷和最富有的人之间的有效净税率已经扩大。因此,显而易见,随着税收的变化,遭受最大“痛苦”的人是最富有的人。对于 80%的美国人来说,没有什么能达到 20 世纪 50 年代的高点。这就是我对美国伟大时期所得税的看法。

那么,在解决了这个问题(请假装我解决了)之后,我们还能从这个图表中得到什么呢?让我们补充一些历史笔记:

这将“税务事件”叠加在前面的图表上。名字是我自己想出来的。杜鲁门混乱时期是杜鲁门的第一个当选任期,试图将国家的税收制度恢复到和平时期的水平。事情发展到这一步,最终征收了更高的税。艾森豪威尔改革指的是降低一些人的税收,但提高另一些人的税收的改革,主要是因为标准扣除额的计算方式发生了变化。

最终,这一体系变得非常不受欢迎,以至于 JFK 在 1963 年提议减税,并由 LBJ 在 1964 年签署,因此有了肯尼迪/约翰逊减税计划。没有什么比成功更成功的了,所以尼克松又一次减税。然而,尼克松也提出了一个永远不受欢迎的替代最低税。

正如已经注意到的,如果按照五分位数来看,联邦所得税要求的收入百分比往往会在两次削减之间攀升。有时,这可能是由于随着时间的推移税率的内在变化。其他时候,这是由于五分之一人口随着时间的推移变得更加富裕。无论哪种方式,都有潜移默化,人们会注意到。因此,一项减税措施接踵而至。

在下一个案例中,我们看到(按申报收入的百分比)有史以来最大的联邦所得税削减——福特减税,我们几乎从未听说过——人们肯定想知道为什么。这一削减特别有利于收入最低的五分之一至第三个五分之一。这(几乎)是美国的一个大免税期。卡特很快实施了系统性的增税,几年后情况变得更糟。福特-卡特事件可能是美国经济史上一个最古怪时代的产物。可能没人能做对。无论如何,卡特仍然对 80%的美国人提出了最低的实际净所得税要求。

随后是里根著名的“减税”。看着它。它得到了如此多的播放和赞扬,而且是最小的减税。与所有其他减税措施相比,这是微不足道的。此外,里根接着说出了他最肮脏的秘密:里根增税是二战结束以来美国历史上最大的增税。这可能是乔治·布什在选举中失败的一个重要原因。

直到 2001 年,情况一直相当稳定。如果说有什么不同的话,那就是第三个五分之一人口的收入范围扩大了。现在,某些养尊处优的贵宾犬和他们的比特犬走狗制造了大量的噪音,关于所得税是如何失去控制的,或者一些这样的废话,但事实是,就声称的收入百分比而言,80%的美国家庭的情况相当稳定。

因此,我们得到了 JW·布什的又一次减税。它基本上让人们回到了里根当选前的支付水平(按收入百分比计算)。这似乎已经为四届总统任期带来了稳定的结果。

尽管如此,尽管 80%的美国家庭的税收负担比 20 世纪 80 年代末和 90 年代经济繁荣时期要小得多,但再次减税被认为是必要的,因此特朗普在 2018 年实施了减税。从那以后,除了直接的影响,还没有时间看到更多的影响,但 2019 年声称的收入百分比的上升奇怪地让人想起了税收的“卡特反弹”——只是说。

如果你注意到了,税收干预的时间似乎变得更长了。从 1947 年到 1986 年,这段时间大约是 1-2 个总统任期。从 1986 年开始,总统可能更愿意与前任的税级合作,除非税改是总统的一个具体理论要点。

分析方法

我的方法非常简单。我只是用了算术,冗长乏味的算术。然后我用 Excel 把它标出来,用 PowerPoint 把标出来,就这样了。如果你想追踪我的意大利面 Excel,我已经把文件放在这里了。

我们如何构建一个科技落后的世界

原文:https://towardsdatascience.com/how-we-are-constructing-a-world-of-ill-technology-90f5e0ac907e?source=collection_archive---------56-----------------------

我们能从历史中学到什么来为一个更公平的社会发展技术。

来源:德尔菲娜·莱昂

今天的技术几乎完全脱离了任何政治或道德委员会和规则,然而,它们是操纵和强化我们现代世界偏见的弱点。

机器学*很容易使用,但很难掌握。

在学*电子工程的时候,我不断地“偶然”遇到有偏见的技术。例如,每当不代表已经有偏见的 数据被扔进机器学*算法,而没有特别检查它是否有偏见的结构时,就会发生这种情况。结果将只是这种偏见的一种反映,并强化我们这个有偏见的社会。

例如,一个用偏倚数据训练的应用程序是亚马逊内部招聘工具,它正在解雇女性候选人,因为它是根据历史招聘决策训练的。

非代表性数据的一个例子是,当我用机器学*训练一个人脸识别应用程序,并主要给它输入白人的照片。结果将是白人比其他人更容易被认出来。不幸的是,市场上大多数人脸识别工具都有偏见,正如国家标准与技术研究所(NIST)公布的 2019 。正如 NIST 的研究表明的那样,大多数工具在有色人种和女性中的假阳性率(错误识别)明显高于白人男性,从 10 到 100 倍不等。当这种工具被出售给像警察部门这样的机构并导致更多的不平等时,这就变得特别成问题。

这些例子无一例外,而是数字化和自动化的常见伴随物。现在想象一下我们的未来,我们已经在自动化房地产代理、贷款、招聘、新闻、风险评估等等,使用之前提到的有偏见的算法。

然而,仅仅远离这种新技术并不能解决问题,因为这只会产生更多的误解,从而创造更糟糕的技术,而且最重要的是,它会使我们受到外部技术的操纵。

因此,这个问题需要进一步关注,任何人都必须考虑和理解,尤其是参与技术开发的人。

但是这个问题更深层

当一个少数群体存在于一个主要资产较少的社会中时,他们就进入了种族主义的恶性循环。以美国 PoC(有色人种)的历史为例,这一切都始于一段压迫和暴政的漫长历史,并导致了至今仍然存在的根深蒂固的系统性种族主义。

“个体的意图并不是系统性邪恶的必要条件。”—杰米·阿平-里奇

简单地说,这是因为压迫结束后,有色人种几乎没有资本或住房等资产,并被排除在权力职位之外。政治忽视了完全不公平的事件,如红线,房地产转向,或对 GI 法案的特权待遇,该法案只支持白人积累财富,并允许将其传递给下一代。因此,几十年来出现了巨大的财富差距,最灾难性的问题是人们倾向于颠倒因果关系。因此,有色人种在被捕时被无意识地视为更有犯罪倾向,在申请工作时更不合适,在贷款时更不可靠,这些都已被大量研究揭示。

Rehavi 和 Starr 在 2014 年发布了《进一步包括刑事司法中的种族差异》,其中黑人获得的刑期比因相同罪行被捕的可比白人多* 10%[1]。
Bertrand & Mullainathan 在 2004 年指出,白人名字比非裔美国人多 50%的面试机会。最后,Rugh 等人(2015 年)披露,他们样本中的黑人借款人每月支付额外的 5-11%以上[3]。

修复种族主义制度的解决方案极其复杂,因此,应该彻底检查制度是否存在任何歧视性基础。

我们最年轻的考试机构

没有从历史中学到建立一个没有偏见和歧视的机构是多么重要,我们已经在一遍又一遍地犯同样的错误,很少有人解决这个问题。

“如果数字化转型做得好,就像毛毛虫变成蝴蝶,但如果做得不好,你得到的只是一只非常快的毛毛虫。”乔治·维斯特曼,麻省理工学院斯隆数字经济项目负责人

技术影响着我们的生活,影响着我们做出的决定,影响着我们购买的产品,影响着我们计划的旅行,甚至影响着我们的心态和政治观点。

Epstein [4]的研究表明,在选举前,搜索引擎对犹豫不决的选民的影响高达 20%,在某些人口统计群体中甚至更高。总之,这些工具允许滥用来决定选举的结果,这给搜索引擎和它们的算法带来了巨大的力量,因此从道德的角度来看不应该被忽视。

此外,我们这一代人从 YouTube、Instagram、Twitter、抖音或网飞等平台上消费大量信息,这些平台上的算法定义并推荐内容。虽然还没有达成一致,如果推荐系统正在创造或相反打破“过滤泡沫”,很明显他们拥有显著的影响。过滤气泡描述了这样一个问题,即用户只看到与他们先前存在的信念一致的内容[5]。然而,这种现象在没有这些系统的情况下就已经存在,因为寻找证实而不是反证是人类本性的一部分,因此推荐系统准确地拾取了这种愿望。尽管如此,现在完全取决于开发商如何处理这一困境,而这是一个伦理和社会学问题。

现在怎么办?

如果你是因为不知情而在开发有偏见的技术,那也没关系。无知再也不能成为借口了!这个话题对我们的未来至关重要,不容忽视,这意味着我们都必须为之努力。

种族主义遗留法律和现代种族主义做法都是同一个系统的一部分,现在需要改变―达珊·斯托克斯

如果你参与了技术的发展,你必须经常批判性地检查你的系统,并意识到它在道德标准方面的普遍弱点。你要为你的贡献负责,意识不到它所造成的影响是致命的。

然而,对于不道德的实施没有管辖权,这就是为什么工程师和科学家不承担责任,特别是因为它经常与生产力和竞争力相冲突。这种权衡相当复杂,难以平衡,因此我们需要工程师、科学家和社会学家与政治家共同努力,积极开发适当的基础设施。最*欧洲委员会提出了一份白皮书,其中包含未来处理人工智能的指导方针,值得一读。然而,它没有引起人们的注意,也没有找到保持生产力和技术进步的解决方案。最终,这可能会成为成功和失败的转折点:在进步和意义之间找到平衡。

每个人都可以并且应该为此做出贡献的一件事是提高意识和提供知识,而不是无知或被动。

最后,如果我们照顾好我们的发明,其结果甚至可以成为解决方案的一部分,将我们的社会从非种族主义者重新定义为反种族主义者。

参考

[1]马里特·雷哈维;Starr,Sonja B. (2014 年):联邦刑事判决中的种族差异。摘自:《政治经济学杂志》第 122 卷第 6 期,第 1320-1354 页。DOI: 10.1086/677255。

[2] Bertrand,Marianne Mullainathan,send hil Emily 和 Greg 比 Lakisha 和 Jamal 更适合工作吗?劳动力市场歧视的实地实验美国经济评论 94 4 991–1013 2004 10.1257/0002828042002561https://www.aeaweb.org/articles?id=10.1257/0002828042002561

[3] Rugh JS,Albright L,Massey DS .种族、空间和累积劣势:次级贷款崩溃的案例研究。 Soc Probl 。2015;62(2):186–218.doi:10.1093

[4] R. Epstein 和 R. E. Robertson,“搜索引擎操纵 effect (seme)及其对选举结果的可能影响”,第 112 卷,第 33 期,第 e 4512-e 4521 页,2015 年。

[5] Pariser,e,《过滤泡沫:新的个性化网络如何改变我们的阅读方式和思维方式》。企鹅,纽约,2011。

我们如何在 Kubernetes 上构建无服务器 Spark 平台——数据机制视频之旅

原文:https://towardsdatascience.com/how-we-built-a-serverless-spark-platform-video-tour-of-data-mechanics-583d1b9f6cb0?source=collection_archive---------41-----------------------

我们在 Data Mechanics 的使命是让数据工程师和科学家能够轻松地在大型数据集上构建管道和模型。

我们在 Data Mechanics 的使命是让数据工程师和数据科学家能够在大型数据集上构建管道和模型,只需在他们的笔记本电脑上运行脚本即可。让他们专注于他们的数据,而我们处理基础架构管理的机制。

因此,我们建立了一个无服务器的 Spark 平台,一个更易于使用和更高性能的替代服务,如亚马逊 EMR、谷歌 Dataproc、Azure HDInsight、Databricks、Qubole、Cloudera 和 Hortonworks。

在本视频中,我们将向您介绍我们平台的产品及其一些核心特性:

  1. 如何将 Jupyter 笔记本连接到平台,与 Spark 互动
  2. 如何使用我们的 API 或气流集成以编程方式提交应用程序
  3. 如何从我们的控制面板监控 Spark 应用的日志和指标
  4. 如何随着时间的推移跟踪工作的成本、稳定性和性能(重复性应用)

Spark 和产品之旅的数据力学介绍

是什么让数据力学成为一个无服务器的 Spark 平台?

我们的自动驾驶功能

我们的平台动态地、持续地优化您的每个 Spark 应用的基础设施参数和 Spark 配置,使它们保持稳定和高性能。以下是我们调整的一些参数:

  • 容器大小(内存、CPU) —保持应用程序稳定(避免内存不足错误),优化节点上容器的二进制打包,并通过解决应用程序的瓶颈(内存限制、CPU 限制、I/O 限制)来提升应用程序的性能
  • Spark 用来提高其并行度的默认分区数量。
  • 磁盘大小、随机存取和 I/O 配置,以确保数据传输阶段以最佳速度运行。

我们的自动调优功能是在一个循环应用程序的过去运行中训练出来的。它会自动对代码或输入数据的变化做出反应,这样您的应用程序就可以随着时间的推移保持稳定和高性能,而无需您的手动操作。

来源:我们 2019 Spark 峰会关于如何为 Apache Spark 自动化性能调优的演示

除了自动调整,我们的第二个自动驾驶功能是自动缩放。我们支持两种级别的自动缩放:

  • 在应用程序级别:每个 Spark 应用程序根据负载动态调整其执行器数量(动态分配)
  • 在集群级别:Kubernetes 集群自动向云提供商添加和删除节点

这种模式让每个应用程序完全独立工作(拥有自己的 Spark 版本、依赖项和资源),同时始终保持基础设施的成本效益。

我们的云原生容器化

数据机制部署在我们客户的云账户中的 Kubernetes 集群上(而大多数其他平台仍然在 Hadoop 的调度器 YARN 上运行 Spark)。

这种部署模式具有以下主要优势:

  • 无懈可击的安全模式:我们客户的敏感数据保存在他们的云账户和 VPC 中。
  • 原生 docker 支持:我们的客户可以为 Apache Spark ( 更新:截至 2021 年 4 月这些映像现已在 DockerHub 上公开,或者他们可以构建自己的 Docker 映像,以可靠的方式打包他们的依赖关系。进一步了解由此产生的基于 Docker 的开发人员工作流的优势。
  • 与 Kubernetes 生态系统的丰富工具集成。
  • 与云无关:数据机制在 AWS、GCP 和 Azure 上可用。

来源:在 Kubernetes 上运行 Apache Spark 的利与弊(而不是 YARN)

我们的无服务器定价模式

竞争数据平台的定价模型基于服务器的正常运行时间。对于每种类型的实例,他们都会按小时收费,不管这个实例是否真的用于运行 Spark 应用。这给 Spark 开发人员带来了负担,他们需要高效地管理他们的集群,并确保他们不会因为过度供应或并行性问题而浪费资源。

相反,数据力学费是基于所有 Spark 任务的持续时间总和(Spark 分配的工作单位,以毫秒精度报告)。这意味着我们的平台只有在用户真正工作的时候才能赚钱。我们不赚钱:

  • 当一个应用程序完全空闲时(因为您从笔记本电脑上休息了一会儿,忘记缩减您的集群)
  • 当您的大多数应用程序资源都在等待一个落后的任务完成时
  • 当运行 Spark 驱动程序专用操作时(纯 scala 或 python 代码)

因此,数据机制会在您的应用闲置时积极缩减其规模,以便我们降低您的云成本(而不影响我们的收入)。事实上,我们在您的云成本上节省的成本将覆盖或通常超过我们收取的服务费。

我想试试这个,我如何开始?

太好了!第一步是向我们的团队预订一个演示,这样我们可以更多地了解您的使用案例。在初次聊天后,我们将邀请您加入共享的 slack 频道——我们使用 Slack 来提供支持,我们在那里非常积极。我们将向您发送如何授予我们对您选择的 AWS、GCP 或 Azure 帐户的权限的说明,一旦我们获得这些权限,我们将部署数据机制,您将准备好开始使用我们的文档

还有一些我们在这篇文章中没有涉及的功能,比如我们对 spot/preemptable 节点的支持,我们对私有集群(与互联网断开)的支持,我们的 Spark UI 替换项目,我们与 CI/CD 工具和机器学*模型跟踪和服务工具的集成。所以,如果你想了解更多,请继续关注并联系

我们如何用迁移学*构建一个易于使用的图像分割工具

原文:https://towardsdatascience.com/how-we-built-an-easy-to-use-image-segmentation-tool-with-transfer-learning-546efb6ae98?source=collection_archive---------5-----------------------

标记图像,预测新图像,可视化神经网络,所有这些都在一个 Jupyter 笔记本中(并使用 Docker Hub 共享所有内容!)

作者:黄珍妮伊恩·亨特-伊萨克威廉·帕恩

GitHub 回购

简介

在新图像上训练图像分割模型可能会令人望而生畏,尤其是当您需要标记自己的数据时。为了使这项任务更容易和更快,我们建立了一个用户友好的工具,让您在一个 Jupyter 笔记本上建立整个过程。在以下部分,我们将向您展示我们的工具如何让您:

  1. 手动标记您自己的图像
  2. 通过迁移学*建立有效的细分模型
  3. 可视化模型及其结果
  4. 将您的项目共享为 Docker 图像

该工具的主要优势是易于使用全在一个平台,以及与现有数据科学工作流程完美集成。通过交互式小部件和命令提示符,我们建立了一种用户友好的方式来标记图像和训练模型。最重要的是,所有的东西都可以在一个 Jupyter 笔记本上运行,这样就可以快速轻松地构建模型,而不需要太多的开销。最后,通过在 Python 环境中工作并使用 Tensorflow 和 Matplotlib 等标准库,该工具可以很好地集成到现有的数据科学工作流中,使其成为科学研究等用途的理想选择。

例如,在微生物学中,分割细胞的显微图像可能非常有用。然而,随着时间的推移跟踪细胞很容易导致需要分割数百张图像,这对于手动操作来说非常困难。在本文中,我们将使用酵母细胞的显微图像作为我们的数据集,并展示我们如何构建我们的工具来区分背景、母细胞和子细胞。

1。标签

有许多现有的工具可以为图像创建带标签的遮罩,包括 LabelmeImageJ ,甚至还有图形编辑器 GIMP 。虽然这些都是很棒的工具,但它们不能集成到 Jupyter 笔记本中,这使得它们更难与许多现有的工作流一起使用。幸运的是, Jupyter Widgets 让我们可以轻松地制作交互式组件,并将它们与 Python 代码的其余部分连接起来。

要在笔记本中创建训练遮罩,我们需要解决两个问题:

  1. 用鼠标选择图像的一部分
  2. 轻松切换图像并选择要标记的类别

为了解决第一个问题,我们使用了 Matplotlib 小部件后端和内置的 LassoSelector 。LassoSelector 处理绘制一条线来显示您所选择的内容,但是我们需要一点自定义代码来将遮罩绘制为覆盖图:

类来管理 Jupyter 笔记本中 Matplotlib 的套索选择器

对于第二个问题,我们使用 ipywidgets 添加了好看的按钮和其他控件:

我们结合了这些元素(以及像滚动缩放这样的改进)来制作一个标签控制器对象。现在我们可以拍摄酵母的显微图像并分割母细胞和子细胞:

套索选择图像标签演示

您可以检查整个对象,这使您可以滚动缩放,右键单击平移,并在此选择多个类别。

现在我们可以在笔记本上标注少量图片,保存到正确的文件夹结构中,开始训练 CNN!

2。模特培训

型号

U-net 是一种卷积神经网络,最初设计用于分割生物医学图像,但已成功用于许多其他类型的图像。它建立在现有的卷积网络上,可以更好地处理很少的训练图像,并进行更精确的分割。这是一个最先进的模型,使用[segmentation_models](https://github.com/qubvel/segmentation_models)库也很容易实现。

图片来自 https://arxiv.org/pdf/1505.04597.pdf

U-net 是独特的,因为它使用交叉连接(上图中的灰色箭头)将编码器和解码器结合在一起。这些跳过连接从下采样路径中相同大小的部分交叉到上采样路径。当您向上采样时,这将创建输入到模型中的原始像素的意识,这已被证明可以提高分割任务的性能。

尽管 U-net 很棒,但如果我们不给它足够的训练例子,它就不会很好地工作。考虑到手动分割图像是多么乏味,我们只手动标记了 13 幅图像。这么少的训练样本,似乎不可能训练出一个有几百万参数的神经网络。为了克服这一点,我们需要数据增强迁移学*

数据增强

当然,如果您的模型有很多参数,您将需要相应数量的训练示例来获得良好的性能。使用我们的小数据集的图像和面具,我们可以创建新的图像,这将是深刻的和有用的我们的模型作为我们的原始图像。

我们如何做到这一点?我们可以翻转图像,以一定角度旋转它,向内或向外缩放它,裁剪它,平移它,甚至通过添加噪声来模糊图像,但最重要的是,我们可以对这些操作进行组合来创建许多新的训练示例。

增强图像的例子

与分类相比,图像数据扩充在分割方面还有一个复杂性。对于分类,您只需要扩大图像,因为标签将保持不变(0 或 1 或 2……)。然而,对于分割,标签(它是一个遮罩)也需要与图像同步变换。为此,我们使用了带有自定义数据生成器的[albumentations](https://albumentations.readthedocs.io/en/latest/)库,因为据我们所知,Keras ImageDataGenerator 目前不支持“图像+蒙版”的组合。

使用白蛋白进行图像分割的定制数据生成器

迁移学*

即使我们现在已经创建了 100 个或更多的图像,这仍然不够,因为 U-net 模型有超过 600 万个参数。这就是迁移学*发挥作用的地方。

转移学*让你把一个在一个任务上训练过的模型,重新用于另一个类似的任务。它大大减少了你的训练时间,更重要的是,它可以产生有效的模型,即使是像我们这样的小规模训练。例如,像 MobileNet、Inception 和 DeepNet 这样的神经网络通过对大量图像进行训练来学*特征空间、形状、颜色、纹理等。然后我们可以通过获取这些模型权重并稍微修改它们以激活我们自己的训练图像中的模式来转移所学的

现在我们如何用 U-net 使用迁移学*?我们使用了segmentation_models库来完成这项工作。我们使用您选择的深度神经网络的层(MobileNet、Inception、ResNet)和图像分类的参数发现训练(ImageNet ),并将它们用作您的 U-net 的前半部分(编码器)。然后,使用您自己的扩充数据集训练解码器层。

组装在一起

我们将所有这些放在一个分段模型类中,您可以在这里找到。创建模型对象时,您会得到一个交互式命令提示符,您可以在其中自定义 U-net 的各个方面,如损失函数、主干等:

细分模型定制演示

经过 30 个周期的训练,我们达到了 95%的准确率。注意,选择一个好的损失函数是很重要的。我们首先尝试了交叉熵损失,但该模型无法区分外观相似的母细胞和子细胞,并且由于看到的非酵母像素比酵母像素多得多的类别不平衡,该模型的性能很差。我们发现使用骰子损失给了我们更好的结果。骰子损失与联合分数的交集(IOU)相关联,并且通常更适合于分段任务,因为它提供了最大化预测和基础真实掩码之间的重叠的激励。

我们的模型预测的例子与真实的面具相比较

3。可视化

现在我们的模型已经训练好了,让我们使用一些可视化技术来看看它是如何工作的。我们按照 Ankit Paliwal 的教程来做。你可以在他对应的 GitHub 库中找到实现。在本节中,我们将在我们的酵母细胞分割模型上可视化他的两种技术,中间层激活和类激活的热图。

中间层激活

第一种技术在测试图像上显示了网络前向传递中中间层的输出。这让我们可以看到输入图像的哪些特征在每一层都被突出显示。输入测试图像后,我们可视化了网络中某些卷积层的前几个输出:

某些编码器层的输出

某些解码器层的输出

在编码器层中,靠*输入的滤波器检测更多的细节,而靠*模型输出的滤波器检测更多的一般特征,这是可以预料的。在解码器层,我们看到相反的模式,从抽象到更具体的细节,这也是可以预期的。

课程激活热图

接下来,我们看看类激活图。这些热图可让您了解影像的每个位置对于预测输出类别的重要性。在这里,我们可视化了酵母细胞模型的最后一层,因为类别预测标签将在很大程度上依赖于它。

一些样本图像上的类激活热图

我们从热图中看到,细胞位置和部分图像边界被正确激活,这有点令人惊讶。

我们还查看了教程中的最后一项技术,它显示了每个卷积滤波器最大限度地响应哪些图像,但可视化对于我们特定的酵母细胞模型来说并不太有用。

4。制作和共享 Docker 图像

找到一个很棒的模型并试图运行它,却发现它由于神秘的依赖问题而无法在您的环境中工作,这是非常令人沮丧的。我们通过为我们的工具创建一个 Docker 映像来解决这个问题。这允许我们完全定义代码运行的环境,一直到操作系统。对于这个项目,我们基于 Jupyter Docker 栈中的jupyter/tensorflow-notebook图像制作 Docker 图像。然后我们添加了几行代码来安装我们需要的库,并将 GitHub 库的内容复制到 Docker 映像中。如果你好奇,你可以在这里看到我们的最终文档。最后,我们将该图像推送到 Docker Hub,以便于分发。您可以通过运行以下命令来尝试一下:

sudo docker run -p 8888:8888 ianhuntisaak/ac295-final-project:v3 \
-e JUPYTER_LAB_ENABLE=yes

结论和未来工作

该工具让您能够以用户友好的方式轻松地在新图像上训练分割模型。虽然它可以工作,但在可用性、定制和模型性能方面仍有改进的空间。未来,我们希望:

  1. 通过使用 html5 画布构建自定义 Jupyter 小部件来改进套索工具,以减少手动分段时的滞后
  2. 探索新的损失函数和模型(如在宽核数据集 上预先训练的)U-net)作为迁移学*的基础
  3. 使解释可视化更容易,并向用户建议改善结果的方法

致谢

我们要感谢我们的 Pavlos Protopapas 教授和哈佛应用计算 295 课程教学人员的指导和支持。

我们如何建立一个廉价的、可扩展的架构来卡通化这个世界!

原文:https://towardsdatascience.com/how-we-built-an-inexpensive-scalable-architecture-to-cartoonize-the-world-8610050f90a0?source=collection_archive---------22-----------------------

并在生产中大规模部署耗电的深度学*模型。

很多人都对 漫画家 背后的建筑感兴趣。所以 Tejas 和我(Niraj)试着解释我们所采用的让它工作的过程。Algorithmia 为我们的视频推理管道提供了动力。😇

AI 卡通化形象!由杜凡Unsplash 上拍摄的原始照片

在当今快节奏的世界中,ML 专家被期望在 ML 工作流程中扮演多重角色。工作流中的一个关键任务是为生产中的模型服务!管道中这一看似重要的部分往往会被忽视,从而无法为客户提供价值。

没有(数据)科学家的工作,工程学科显然无法存在——MLE(机器学*工程)是建立在数据科学的工作基础上的——但工程是科学应用于世界的方式。
--迦凯泽

本文将解释我们的尝试,不仅仅是为生产中的计算密集型 GAN 模型提供廉价的服务,而且还要对其进行水平扩展。

ML 灾难😅

如果你熟悉托管 REST API,它保证这些基本的东西-

  1. 烧瓶中的快速原型
  2. 设置环境
  • GCP 或 AWS 实例
  • 系统依赖性以及 python 特定依赖性(pip)
  • 代理服务系统
  • 多个工作人员进行横向扩展

作为一名 ML 工程师,第二点是乏味的,在可伸缩性和服务器成本方面不太令人满意。维护服务器的责任落在您肩上的日子已经一去不复返了!我说的是外包和自动化的第二点完全。输入谷歌云运行!

跑云跑!

在我介绍这个架构的工作原理之前,我想给你一些用户统计数据,让你感受一下我们可以用最少的成本满足的流量。

我们收到的流量😮

自从我们在 7 月 26 日推出我们的演示网络应用以来,在不到 3 周的时间里,我们已经拥有了大约 12,000 名用户!在最初的 4 天中有 6000——大部分流量来自我们的 Reddit 帖子TheNextWeb 文章,这些文章随后也被不同国家的其他博客转载。

在这个高峰时间的任何时候,我们都有大约 50 多个用户请求我们的图像和视频服务。

超过两周的用户

我们准备好的交通💪

开箱即用,Cloud Run 允许我们基于传入流量生成 1000 个实例。默认情况下,每个容器实例最多有 80 个请求。因此理想情况下我们可以满足每秒 80,000 个请求!

但是由于卡通化过程已经很繁重了,我们将程序限制在每个实例 8 个工人。这意味着一个实例被限制为 8 个并发请求。如果有的话,第 9 个请求将被路由到第二个实例。因此,我们基本上可以满足每秒 8000 个请求的需求!

视频处理在 CPU 还是 GPU 上?🎥

我们的独特卖点是构建一个架构,让我们能够以最低的成本提供视频和图像。视频只不过是图像(帧)的集合,我们必须将每一帧都卡通化。

以每秒 30 帧的速度卡通化,分辨率为 720p

在 8 核 i7 CPU 上,卡通化 1080p 分辨率的图像大约需要 1 秒钟。不幸的是,Google Cloud Run 最多只提供 2 个 vCPUs,这使得时间增加到了 3 秒/图像!你可以想象在那种计算机上处理视频有多恐怖!每秒 30 帧(fps)的 10 秒视频将花费 15 分钟!😱

我们采用了两种技术来降低视频推理时间。

  • 将图像的分辨率降低到 480p :这实质上减少了每帧的负荷,而质量没有任何明显的变化。这帮助我们达到了 1 秒/图像的推断时间。
  • 降低视频的帧速率:我们将其从 30 fps 降低到 15 fps,这大大减少了我们的视频计算时间。

我们尝试使用 tensorflow lite 进行权重量化,以加速推理管道,但我们面临着为动态输入图像大小提供模型的问题。虽然它适用于固定的图像大小,但我们没有发现延迟和计算权衡的结果是合理的。

即使通过降低分辨率和减少每秒帧数,视频卡通化也要花费 2.5 分钟来制作一个 10 秒的视频。考虑到用户体验,这个价格还是太高了。因此,将视频转换成卡通需要一些额外的大炮。

GPU 上的速度优势⏩

使用 GPU 将图像速度提高了 10 倍。推断时间归结为 50 毫秒/图像。这意味着我们可以卡通化并在 7 秒内提供 10 秒的视频!现在我们开始做生意了。😉

至少我们是这么认为的。有两个问题困扰着我们-

  1. 我们如何扩展 GPU 服务以跟上类似云运行的扩展?
  2. 我们如何能有效地做到这一点?

一种方法是将模型作为 API 部署在 Google 计算引擎实例上,但这违背了云运行扩展的目的。所有的并发请求将会排队,GPU 将会成为我们管道中的瓶颈。此外,全天候运行一个实例并不便宜💰

如何使用 GPU 进行扩展(廉价)?

作为托管无状态容器服务的云运行无法提供 GPU 支持。因此,我们将 GPU 计算外包给一个名为 Algorithmia 的服务,而不是出租昂贵的谷歌计算引擎服务器。原因是双重的-

  1. 首先,它拥有在生产中大规模部署深度学*模型的能力!每个 GPU 计算实例可以处理 24 个并发请求。此外,它可以在任何给定的时间点自动扩展到 80 个实例。
  2. 因为我们把它建成了一个周末版,所以我们想证明我们投入的时间是值得的;在这里,Algorithmia 惊讶地发现了一个非常灵活的平台,可以轻松地部署具有 GPU 支持和配置环境的 ML 模型,而无需知道 GPU 驱动程序和 tensorflow 版本是否兼容,如果你明白我的意思。😛

这意味着我们可以同时满足大约 1500+个视频请求,而且相对便宜!

学*

一个实例上有 80 个请求!🤔

我们的 Flask API 被编码为通过使用 Gunicorn 生成 8 个 workers 来处理 8 个并发请求,但是我们没有改变云运行中每个实例 80 个请求的默认设置。

这意味着整个过程中只产生了一个实例,也许用户请求在我们的 Flask 服务器上排队。缺点是用户必须等待更长时间才能得到他们的卡通图像和视频☹️

好的一面是我们只为一个实例付费。每个实例的请求数量越少,产生的实例数量就越多,从而增加了可计费的实例时间。但是将请求重新路由到不同的实例意味着更好更快的用户满意度。😉

每秒最大请求数(每秒 2 个请求)

未来范围

我们设想这将被用于以下方面—

  • 为动画、卡通和游戏制作快速原型或精灵
  • 因为它概括了面部特征和信息,所以可以用来生成最小艺术
  • 游戏可以非常容易地导入简短的过场动画****而无需使用动作捕捉
  • 可以作为平面设计师或动画师的助手。

如果你有什么有趣的东西要展示,请联系我们!

webapp 演示的代码可在 Github 上获得!试试这里的演示!

我们如何将数据集成管道商品化

原文:https://towardsdatascience.com/how-we-can-commoditize-data-integration-pipelines-68af48ce7d7e?source=collection_archive---------52-----------------------

图片由伯纳德·赫曼特像素上拍摄

大多数工程师在职业生涯中都必须处理数据集成。在过去的几年中,一些公司如 Fivetran 和 StitchData 已经出现在基于批处理的集成中,而 Segment 则出现在基于事件的集成中。但这些公司都没有解决数据集成的问题,随着公司使用的 B2B 工具越来越多,数据集成变得越来越复杂。

我们认为他们永远无法解决数据整合问题。你可能会认为这是因为它们是基于云的、闭源的。但从根本上说,我们认为这归结于一个事实,即他们并不渴望数据集成成为一种商品。

然而,如果你问工程师,他们大多数人认为数据集成管道将在未来 5 年内成为一种商品(这也是我们在 Airbyte 的愿景)。

但在我们告诉你这将如何发生之前,让我们回顾一下当前提供的限制(Fivetran、StitchData 等)。

为什么数据集成还没有商品化?

1.数量有限的预建免维护连接器

当您是闭源时,您需要自己构建和维护所有的集成连接器。问题是这需要大量的工作。Fivetran 花了 6 年时间才达到每天必须维护的 150 个连接器。当你想到 marktech 行业有 5000 多种工具时,你就会明白它们永远无法独自覆盖长尾。

那么会发生什么呢?自从我们开始这个项目以来,我们已经采访了 40 家不同的公司,包括许多 Fivetran 和 StitchData 的客户。他们中的大部分人不得不自己构建一些集成(可能是与气流的集成)来覆盖他们需要的并且那些工具不支持的连接器。

最后,您仍然有数据工程团队在构建和维护集成管道上做大量工作,而他们的专业知识可以在其他地方得到最好的利用。

2.基于云的解决方案的定价基于数量

现有解决方案的另一个重要问题是,它们的定价是根据传输的数据量来确定的。因此,团队需要小心使用连接器。有一个解决方案可以满足您的集成需求,但是由于价格的原因,无法按照您需要的方式使用它来使您的生活变得更加轻松,这是一件非常令人沮丧的事情。这与商品的本来面目是相反的。

3.企业世界中的数据安全和隐私

有两件事你可以肯定会在未来几十年保持增长。

  1. 公司将利用越来越多的数据。
  2. 公司将需要考虑越来越多的数据安全和隐私,尤其是对企业而言。

出于安全原因,许多企业已经停止使用第三方基于云的解决方案。那些仍然使用它们的人都需要一个漫长的安全和隐私合规过程,这个过程将持续至少 4 个月。这削弱了内部团队,使他们无法前进。商品应该是容易获得的,但目前情况并非如此。

商品化数据集成意味着什么?

这是我们在 Airbyte 设想的五年后的世界:

  • 连接器的长尾效应应该得到充分解决。
  • 建立一个新的连接器应该是非常容易的。
  • 对于所有使用的连接器,应该有内置的调度、编排和监控。
  • 应该有一个连接器的自动升级机制,这样它们对于数据工程团队来说是免维护的。
  • 连接器应该直接在你自己的云中,让公司完全控制他们的数据。连接器可以是您自己的数据基础设施的扩展,因为一些可移植性具有超级能力。
  • 不应该有任何与通过连接器传输的数据量相关的成本(除了 CPU 和出口)。

只有这样,我们才能将数据集成管道视为一个已解决的问题和一种商品。

我们如何实现这一愿景?

1.使用非常开放的许可证开源所有数据集成管道

如前所述,数据集成管道需要大量的维护工作。每个工具都会偶尔看到模式的变化。覆盖连接器长尾的唯一方法是拥有一个大型的维护者社区。但是除非你为一家产品是集成管道的公司工作,否则你只需要维护你所使用的东西。这就是为什么唯一的方法是通过一个非常开放的许可证(像麻省理工学院)开源这些连接器。

2.使得构建新的集成变得简单

如果说使用开源项目构建一个新的集成不比自己构建简单多少的话,那么这个项目将很难找到贡献者。这种愿景是有缺陷的。

开发人员的体验需要非常简单。如果新的集成可以在几乎没有代码的情况下构建,那将是理想的。但是除了在大多数集成中发现的一些公共抽象之外,除了那些集成之外,每个团队还需要一些模块。

3.内置的调度、编排、监控和升级

几乎所有的团队都需要在他们的集成之上进行调度和编排。但是,为了在整个存储库中很好地维护连接器,还需要另外两件事情:监控和良好的升级体验。

监控需要为您提供数据复制期间任何错误的详细日志,以便您可以轻松地自行调试或向社区报告问题,以便其他贡献者可以为您解决问题。

考虑到所有工具都有大量的模式更新,团队需要经常升级到最新版本的存储库,以确保他们获得更新的模式。

4.与生态系统很好地集成—转型、BI…

如果这个项目能够与 DBT 就转型以及其他用例(如分析、商业智能等)的其他领先项目进行良好的连接,它将从生态系统中受益。这也将使项目能够专注于他们最擅长的事情(提取-加载)。如果项目想以这样或那样的方式解决不同的极端情况,它需要关注。

5.通过隐私合规性和角色管理满足企业需求

最后但同样重要的是,该项目还需要解决企业的需求。这包括:

  • 安全性和隐私合规性功能
  • 数据质量监控功能
  • 角色和用户访问管理

没有这些,企业将更难接受开源技术。这是我们认为将在源代码可用的企业版中销售的部分。

6.好处:扩展到所有类型的集成

我们只讨论了从第三方工具和数据库到仓库的批量数据复制。但没有什么能阻止这个项目在不久的将来将数据同步从仓库扩展到其他目的地。例如,如果您的营销团队希望将数据发送回您的广告平台,那么它可以更好地优化活动。另一个用例可能是将整合的数据同步回您的 CRM。

随后,项目可以处理基于事件的数据集成,这是一个 la 部分。事实上,该技术将非常接*我们已经与社区建立的连接器。这将使公司毫不费力地完全控制他们的数据。

有这样的项目吗?

好吧,如果你喜欢到目前为止你所读到的,你可能有兴趣了解一下气媒

我们今天才刚刚开始我们的愿景。明年我们将把重点放在将批量数据复制固定到仓库上。我们希望到 2020 年底至少有 50 个连接器,并在 2021 年 Q2 奥运会前与 Fivetran 持平。但是我们只有在社区的帮助下才能实现。

现在,你可以派生出我们的 GitHub 项目并自己托管它。我们建立了一个 UI,允许任何人定义他们的连接,并在几分钟内开始整合数据,就像 Fivetran 和 StitchData 一样。

作者图片

旋转一下:https://github.com/airbytehq/airbyte/。让我们知道您的想法,如果您喜欢我们的数据集成管道商品化的愿景,请不要犹豫开始该项目!

原载于https://airbyte . io

我们如何从大脑中学*来了解大脑是如何学*的

原文:https://towardsdatascience.com/how-we-can-learn-from-the-brain-to-learn-how-the-brain-learns-2b81286a1a7b?source=collection_archive---------21-----------------------

来自地球上最古老的数据科学家的教训

内森·杜姆劳在 Unsplash 上的照片

数据科学是查看数据并从中提取有用知识的艺术。数据无处不在。数据意味着图像、音频、文本、股票市场趋势。 数据是我们探究世界时,世界呈现给我们的方式。无论是为了物种的生存还是为了公司的生存,拥有有用的知识比没有有用的知识更有优势。

因此,数据科学家的探索与生命地球本身一样古老:所有生命形式都在以这样或那样的方式从来自环境的数据流中提取知识,以服务于它们的生存目标。有些持续了几亿年,甚至几十亿年。

大脑已经率先以最复杂的方式完成了这项工作。

科学探究

德文·罗杰斯在 Unsplash 上拍摄的照片

对科学的追求同样是从世界中获取知识,尽管是在一个更加刻意的过程中。,它大致分为两个部分:建立世界模型,并将这些模型与数据进行比较。

更抽象地说,这两个步骤类似于生成模型的两个部分,如自动编码器(我在这里写了更多关于生成模型背后的核心思想)。

1。编码器:数据→型号

在第一阶段,可以称为编码器阶段,我们从数据中提取某种表示/模型,我们希望以某种方式反映一些真实的(因果/概率等。)数据背后的结构。

2。解码器:模型→预测(新数据)

第二阶段通过预测世界来解码模型,并在实验中与观察结果进行比较。

模型反演

纳丁·沙巴纳在 Unsplash 上拍摄的照片

但是我们还需要采取另一个步骤。如果我们只有很少的信息或者我们的预测是错误的(信息不确定性),我们如何建立和改变我们的模型?如果我们的模型不再足够好,因为建立模型的世界发生了变化或包含了某种内在的不确定性(环境不确定性),会发生什么?物理定律可能永远不变,但如果我们代之以建模像另一个人的行为一样变化无常和不确定的东西会怎样?

因此,我们需要另一个阶段,将对世界的预测与真实世界进行比较,并调整模型以适应预测误差。

3。模型反演:预测数据与输入数据→改进模型

你如何利用数据最有效地改进你的模型?你如何同时转动一个复杂模型的许多螺丝而不把它搞砸?

正如我在开头提到的,大脑真的很擅长从数据中提取相关知识。重要的是,他们是杰出的直觉科学家(尽管他们有数百种偏见,正如我在我关于人工智能和认知偏见之间的联系的文章中所述)。他们不断地建立世界的模型,根据这些模型做出预测,如果他们的预测是错误的,就反转并改进它们。这就是为什么进化一开始就把它们放在我们的脑袋里。

大脑在各种任务中都是高效的学*者。它们往往比我们当前的机器学*算法概括得更好,学*更灵活,这也意味着快速适应不断变化的环境。

他们对极其复杂的过程做出预测,例如 “我几分钟前遇到的这个人接下来会做什么?” ,这意味着我们的大脑为我们遇到的每一个人建立一个模型,将这个模型整合到预先存在的一个人的模型中,进一步整合几个数据模态(这个人看起来/说话/闻起来/移动起来如何?)来微调模型,然后使用这个人的新的*似模型来对他或她的行为进行实时预测,或者将他们快速分类为朋友或敌人。

如果这个人的行为与我们的预测相冲突,我们的大脑会无缝地更新它的模型,而我们大多数时候不会注意到它。但正如机器学*和人工智能领域的当前标准所示,用计算机做这些事情需要更长的时间,花费更多的资源,需要更多的数据。

向大脑学*向大脑学*

功能磁共振成像数据。来源:德国维基百科上的 M . r . w . hh[公共领域]

神经科学家研究大脑已经有一百多年了。但是大脑是一块难啃的骨头。我们从中收集的数据通常是杂乱的,难以解释。有时候放弃是很诱人的。但是大脑每天都面临着类似的情况。而且脑子也经不起找借口。如果我们的大脑只是听天由命,说“这个世界太复杂了,不可能从中学到任何有用的东西”,我们早就灭绝了。

因此,与其放弃,我们如何才能学*好的大脑模型,即使我们没有大量干净的数据可用?

在一个极其单调的循环中,我们可以从我们研究的主题本身寻找指导:我们可以从大脑中了解大脑如何学*, 找到如何改进和构建我们算法的灵感,这些算法反过来帮助我们更好地分析和建模大脑数据和行为数据 (我将很快给出一个更具体的例子)。

大脑中的层次模型

Edvard Alexander lvaagUnsplash 上拍摄的照片

大脑可以有效地推断和改进它不断变化的世界模型。

层次模型 是对此进行概念化的一种方式。正如我在我的关于智力的文章中所详述的那样(在这里阅读),认知可以被认为是有层次结构的(这也适用于思维本身,参见我的关于思维几何学)的文章。

层次模型是逐步建立越来越复杂的对象表示的好工具。它们可以捕捉数据背后深刻而重要的结构和概率分布,并可用于有效地生成预测(有关更多技术介绍和分层模型的示例,请阅读 Penny 和 Henson 的介绍,此处为)。

它们的潜力激发了神经科学家去寻找大脑中的层次模型。作为卡尔·弗里斯顿的著名且有争议的 T4 贝叶斯大脑假说的一部分,他和他的同事们提出,层级模型可以在人类大脑皮层中实施,我们可以在功能性核磁共振成像数据中观察它们是如何在人类的实时行为实验中更新的。

我们在一个由不确定性塑造的世界中度过了一生,有一些证据表明,大脑可能在使用大脑 中概率分布的隐式 表示,这可以解释这种不确定性。关于这些如何在神经元水平上构建到大脑中有一些理论(见这里对大脑中的概率有一个很好的概述)。

这些世界概率模型的不同层(正如我们将看到的)可能分布在不同的大脑区域和前额皮质的不同层,因此我们的世界模型同样会在物理上分布在大脑上。

高斯滤波器模型

作为一个简单的分层模型,它可以以某种形式在大脑中实现。提出分层高斯滤波器。

感知总是包含一定程度的对环境隐藏状态的不确定性。有没有一种方法可以直接模拟这种不确定性?

高斯滤波器的目的是了解可以随时间变化的 隐藏变量 x 的概率结构。这个 隐藏变量可以代表你能想到的任何种类的数据 ,无论是股票可能如何变化,还是你最好朋友的决策。

该模型代表了代理关于该变量如何随时间变化的信念,并提供了一个可以对该变量进行预测的生成模型。

一个 高斯滤波器模型 由几个相互堆叠的高斯随机分布构成。每一个高斯都有各自的 均值方差 ,它的逆很直观地叫做,因为如果高斯的方差很高,它生成的估计值 就不会很精确

这些高斯分布随时间进行离散化的随机游走,这意味着每个高斯分布在时间 t 的新均值是通过从时间 t-1 的相同高斯分布中抽取来确定的。

为了使用该模型进行预测,我们从顶部开始,并从高斯值中提取值,该高斯值位于 N 个高斯等级的最高处,并且具有固定的精度。由高斯函数给出的值通过一些函数决定了下一层高斯函数的精度,然后我们从这一层开始绘制。这个高斯反过来决定了下面高斯的相应协方差。

冲洗,洗涤,重复,直到我们到达底层。

我们试图预测的 隐藏变量 x 连接到高斯层次的底层。在变量是二进制的情况下(在决策过程中采用布尔值,如“是”或“否”),底部高斯可以连接到一个函数,如 单位正方形。 如果 x 本身被假设为高斯,则底部高斯直接 模型 随机变量 x 的概率分布。

到目前为止,这可能看起来有点抽象(同样参见原始论文中的数字),所以让我们对这里发生的事情有一些直觉。

用高斯滤波器模型学*行为

两条路在树林中分岔。我们如何建模一个代理将采取哪一个?照片由延斯·勒列Unsplash 上拍摄

高斯滤波器模型不仅被提出是在大脑 中以某种方式实现的 ,而且可以被“转过来”分析来自行为实验的数据, 模拟真实大脑在现实生活中如何学*

让我们来看一个最简单的例子,两个高斯函数堆叠在一起,通过一个单位平方 sigmoid 函数连接到一个布尔变量/decision。

比方说,我们希望弄清楚代理是选择“是”还是“否”,这是由一些 隐藏状态 决定的。这些我们可以认为是我们正在观察的代理的内部过程,就像他的 思想和动机 。当然,它们会随着时间的推移而发生变化(我假设你曾经对某件事说了“是”,但后来在你的世界模式改变后,你又深深后悔说了“是”)。

底层的高斯编码了主体倾向于“是”或“否”的倾向。上一层的第二个高斯现在对底部高斯 的 波动进行建模:代理人对是或否的倾向随时间变化的强烈程度,以及我们对代理人将说是或否的预测的信心程度?

如果我们在现有的两个高斯模型上叠加额外的高斯模型,它们将模拟波动率 的 波动率,以此类推,允许模型捕捉代理中隐藏状态的越来越复杂的概率分布。

分层模型中的模型反演

我们还没完。正如我在开始时所说,每个模型的第三步也是关键的一步是 模型反演。

神经网络通常通过反向传播来训练。你取损失函数的梯度(在某种意义上,它只不过是一个预测误差)并调整网络的参数,以便使损失更小。

高斯滤波器模型中的模型反演在结构上有些类似。在做出预测之后,通过传播预测误差,最小化变分自由能(在上的下限,在 贝叶斯大脑假设 的语言中)来更新它的层,由逆精度加权,向上通过模型的层。****

通过进行平均场*似(假设分布保持高斯分布并且独立更新),该方案相对简单并且计算有效,并且可以以试验方式实时执行。

基于相应的预测误差来调整参数。事实上,您是从底层开始,这与反向传播的逻辑完全相同,也是从连接到输出的网络层开始。

根据预测误差 的大小更新高斯均值和精度。可以这样想:如果预测真的很好(几乎完美地匹配了观察值),那么传播的误差就很小,并且一旦你向上移动层次,误差就会变得越来越小。

如果预测很差,但是猜测的精度非常低,首先(这意味着模型在这个级别上对其预测高度不确定),模型也不会调整得太强,因为它已经假设其预测是不确定的,并且可能是错误的。

学*了解大脑如何学*

这个模型真的向我们展示了大脑是如何学*的吗?答案仍然是不确定的(问题是我们的大脑如何对这种不确定性进行建模),我们可以成功地使用模型来学*行为的事实并不表明大脑真的是这样实现的。

然而伊格莱西亚斯等人。Al 声称已经从神经成像研究中找到了证据,证明它可以做到这一点,根据预测误差的大小,观察预测误差传播到不同的大脑区域/层次,并反过来将它们与不同的神经递质联系起来,如参与奖励预测的多巴胺。

弗里斯顿进一步提出,基于芒福德的想法,这个模型可以与神经解剖学联系起来:例如,预测可能会通过深层锥体细胞,而预测错误会被编码。,由 浅锥体细胞 组成。**

但仍有许多未解决的问题,如如何在解剖学上实现模型的高斯分布,如何根据来自锥体细胞的信号更新它们的均值和协方差,如何计算预测误差等。

我们不仅可以通过用大脑启发的模型预测大脑的行为来了解大脑是如何了解世界的。

但在更普遍的意义上,分层模型在许多深度学*和数据科学应用中是有用的工具,因为它们在构建推理网络方面的能力(例如用于动态系统摊销推理的、自然语言处理中的或用于学*变分自动编码器中更好的*似后验概率的)并且可以帮助使它们更具可解释性。由于我们对世界的感知是分层次的,拥有层次模型可以轻松地将它们与我们的直觉和日常语言联系起来。

正如我在关于循环神经网络的文章中解释的那样,建立更结构化的大脑模型是理解大脑如何组织自身的关键一步,这可以帮助我们从 fMRI、EEG 等大脑测量数据中获得更多 意义..

学* 数据的无监督生成模型 看起来是 AI 发展的重要一步。我认为,分层次的方法是更有前途的思考方式之一。

我们如何创建一个开源的新冠肺炎聊天机器人

原文:https://towardsdatascience.com/how-we-created-an-open-source-covid-19-chatbot-c5c900b382df?source=collection_archive---------7-----------------------

深入探讨人工智能和自然语言处理,带你一起踏上开发这个 Corona-chatbot 的旅程

图片由三重安妮·海吉科普拍摄

冠状病毒的爆发对全球社会产生了重大影响。人们理所当然地感到关切,并有许多迫切的问题。世界卫生组织在其网站上提供了关于冠状病毒的常见问题的答案( 链接 )。然而,你可能需要搜索一段时间才能找到你的问题的正确答案。让人们充分了解当前的措施是至关重要的。这样我们可以有效地限制大规模传播。聊天机器人可以很好的帮助你!

在这篇博文中,我们将创建一个聊天机器人来回答关于冠状病毒的问题。这将基于人工智能(AI)和自然语言处理(NLP)。首先,我们将进一步了解这个聊天机器人使用的 AI 和 NLP。此后,将基于所讨论的技术演示聊天机器人的实现。源代码和数据集也可以从相应的 GitHub 页面下载(链接)。

这篇博客是为技术领域的公司写的,这些公司希望帮助阻止冠状病毒,并在这个过程中了解一点人工智能和 NLP。*年来,在人工智能和自然语言处理领域有很多创新。因此,首先,深入了解并学*更多关于如何制作最先进的聊天机器人是有好处的。

对于对实现聊天机器人比较感兴趣,想跳过理论部分的读者,我推荐从: 实现使用和聊天机器人对数据的新冠肺炎 继续阅读

目录

什么是聊天机器人?

在 2020 年,聊天机器人不再被称为一种特殊的奢侈品。我可以肯定地说,几乎每个人,不管是有意识的还是无意识的,都接触过聊天机器人。例如,您可能会向数字客户服务或其他在线聊天服务提出问题。在这样的对话中,聊天机器人知道如何回答你的问题,提出问题,或者可能向你推荐一个可以回答你的问题的网站。聊天机器人也可以在网站和即时通讯程序中找到(包括 Skype、Facebook Messenger 和 Slack)。

在过去,聊天机器人完全基于预编程的规则,因此与人工智能(AI)无关。然而,今天,由于自然语言处理(NLP)的巨大发展,人工智能越来越多地用于实现聊天机器人。这种发展是必不可少的,因为聊天机器人要有一定程度的“智能”,就必须对语言有一定的理解。但是我们如何教计算机理解语言,聊天机器人如何应用这种语言理解呢?

通过这篇博客,你将深入了解基于人工智能的聊天机器人的理论和技术背景。我将解释我们如何使用通用句子编码器(USE)来学*计算机语言,这是一种最先进的“深度学*模型”。我还将展示如何使用 Python 在一个数据集上构建一个聊天机器人,该数据集上有关于冠状病毒的常见问题(来自世卫组织)。简而言之,如果实现聊天机器人在你的项目清单上,这个博客将提供一个强大的基础。

聊天机器人的好处

使用聊天机器人对消费者和生产者都有很多好处。

首先,对消费者的好处。

  • 主动 : 聊天机器人可以根据消费者在网站上花费的时间来开始与他/她对话。有可能消费者已经在一个网站上呆了很长时间,却找不到他/她想要的东西,这时一个询问你是否需要帮助的聊天机器人就可以派上用场了。
  • 直接回答: 聊天机器人几秒内生成答案,而电话客服或邮件往往等待时间更长。
  • 全天候可用: 聊天机器人不必睡觉或休息,这意味着一天中的任何时间都有可用的服务。
  • 相关信息: 聊天机器人可以直接引导消费者,帮助查找相关信息。例如,您可以通过向聊天机器人寻求管理来避免在一个大范围的网站上进行长时间的搜索。
  • 聊天机器人可以在对话过程中展示吸引人的图片、视频、gif,刺激消费者更多地参与对话。

现在是制作人的收益:

  • 降低成本: 聊天机器人最强大的好处之一就是节省成本(前提是机器人运行良好)。它提供了便宜快捷的客户服务,避免了长时间的等待。这意味着公司可以腾出时间来处理更复杂的问题,并且可能需要更少的人力来为客户服务。
  • 满意的消费者: 基于前面提到的对消费者的好处,你可以假设消费者满意度提高了(前提是 bot 运行良好)。这反过来为实现聊天机器人的组织提供了优势。
  • 反馈: 聊天机器人可以在每次对话结束时要求反馈。要么以开放式问题的形式,要么以选择题的形式。这提供了一个可以处理附加反馈并直接分析它的平台。
  • 在工作场所: 员工可以向聊天机器人询问有关公司内部业务方面的问题。例如,我如何更改我的密码,我应该联系谁来解决某个问题。这确保了公司内部的效率。

聊天机器人是如何工作的?

现在我们知道了聊天机器人是什么,它能用来做什么,以及对消费者和生产者都有什么好处。但是聊天机器人到底是如何工作的,聊天机器人是如何理解语言的?我们现在将从语言理解这个主题开始,一步一步地讨论这个问题。

自然语言处理

正如我前面提到的,NLP 是聊天机器人最重要的组成部分之一。NLP 是用来教计算机“理解”人类语言的技术。这项技术被认为是人工智能的一个难题,因为人类语言的逻辑很难翻译成代码。拿一句讽刺的评论或者一个笑话来说,你怎么教一台计算机理解这个?

首先,有必要有一个计算机可以解释的文本表示(编码)。为了获得这样的表示,使用一种策略将“字符串”转换成数字,也称为文本的矢量化。重要的是,这些向量包含关于句子之间的交互/语义关系的信息,因为这对语言理解很重要。例如,以下面的句子“我有点感冒,这可能是新型冠状病毒吗?”以及“恐怕我得了新冠肺炎,因为我感冒了。”这两个句子意思相同,但表述方式不同。重要的是,尽管存在差异,但计算机理解这些句子具有语义相似的意思。

计算机可以通过“句子编码”来学*理解这一点,这是 NLP 中常用的方法。总的想法是,我们给具有相同语义的句子(如前面的例句)一个相似(但不完全相同)的编码。所以,这些编码实际上是一种句子意义的“条形码”。要看两个句子意思是否相等,我们只需要看这些条形码是不是差不多。这使得计算机能够学*识别语言中的模式,从而解释短语之间的相似性,如“我有点感冒,这可能是新的冠状病毒吗?”以及“恐怕我得了新冠肺炎,因为我感冒了。”。

在博客的后面,我们将深入探究计算机最终是如何学*这些编码的。目前,重要的是要记住,这是在大量可用文本数据(如维基百科、新闻提要等)的基础上完成的。).

我们知道:如果编码差不多,它们的意思也差不多。但是,我们实际上如何衡量什么时候“大约相等”呢?我将使用下图(左)来解释这一点。句子编码,如果这些编码发生在三维空间,我们可以看到这个球体上的点(对于对“为什么是球体”这个问题感兴趣的读者来说;这是因为编码总是长度为 1 的向量。可以计算出这些点之间的一定距离。但是我们用什么距离来表示呢?从线性代数中我们经常使用“余弦相似性”。这是从球体中心观察时两个点所成的角度。从红点看,蓝点从中心看角度最小,所以我们可以说与蓝点相关的句子最像红点。如果你想进一步了解余弦相似度,我可以推荐这个博客(链接)。

**

左图由杨等人,(2019) 。右图由三联

正如我刚才提到的,我们计算这些点(编码)之间的角度(余弦),以比较句子在语义上是否相等。由于每个编码的长度已经是 1,我们只需要计算内积。内积计算红点和蓝点之间角度的余弦,得到一个值。该值代表两点(编码)之间的一致程度。余弦越高,角度越小,所以语义相似度越高。上图(右图)可能会提供更好的见解。方框的蓝色越深,角度越小(因此余弦值越高)。

简单回顾一下。我们现在明白,通过句子编码,我们能够确定语义关系,从而大大提高了计算机对自然语言的理解。我们还知道如何使用“余弦相似度”来确定句子之间的关系。但是我们到底是如何得到这些句子编码的呢?

句子编码由神经网络生成。有不同类型的神经网络,其中通用句子编码器(USE)是目前最好的一种。为了理解其用途及其相关的变压器架构,首先需要了解神经网络的基本知识。对于已经熟悉神经网络的读者,我建议跳过下一个标题“神经网络”。

神经网络

神经网络有时被比作人脑,但这是否完全合理是有争议的。然而,与人脑的比较为神经网络如何工作提供了一个稍微简化的初步指示。人类神经元接收来自其他神经元的电信号。当达到某个阈值时,神经元开始放电。电脉冲通过轴突到达一个或多个其他神经元。来自神经网络的神经元也接收输入信号(例如图像的黑色和白色像素),并且当达到某个阈值时将被激活。然而,人类神经元和非人类神经元之间还有一个巨大而重要的区别。这种差异在于,迄今为止,我们并不确切知道人类神经元是如何工作和学*的;我们确实从神经网络中了解了神经元。我现在将简要解释一个简单的神经网络是如何工作和学*的。

神经网络基本上由三种类型的“层”组成(见图)。第一层总是包含输入变量,这是神经网络的初始数据。第二层由隐藏层组成,这是执行计算的层。在第三层中,应用了引入非线性的激活函数

图由艾玛·施勒鲁斯拍摄(2020)

如前所述,我们并不知道人类神经元是如何学*的。幸运的是,神经网络的学*过程是可以解释的。神经网络即通过最小化成本函数来“学*”。该成本函数提供了模型性能的度量,该模型性能在于其正确估计输入和输出变量之间的关系的能力。如上图右侧所示,成本函数计算预测结果变量和真实结果变量之间的差异。我们希望最小化这种差异,因为我们希望模型能够准确预测真实的结果。梯度下降进场。梯度下降是一种搜索成本函数的局部或全局最小值的优化算法。你可以把这比作在山区寻找一个山谷。在这个山谷中,预测和真实结果变量之间的差异的“成本”是最小的。换句话说,这里我们的模型最好地预测了真实的结果。但是我们如何确定朝哪个方向走才能到达这个山谷呢?我们通过反向传播做到这一点。它计算成本函数的所谓“梯度”。这个坡度决定了我们到达山谷必须走的方向。反向传播使用“链式法则”计算该梯度,这计算了成本函数相对于权重的导数。然后梯度下降更新神经网络的权重和偏差(这些是参数),使得成本函数最小化(预测结果更接*真实结果)。这是神经网络学*过程的基础和简短步骤(见图片)。有许多大胆的术语,如果你不能根据这个简短的解释一下子全部理解,这些术语是有意义的。如果你想了解更多这方面的知识,我推荐你观看 YouTube 上的 3blue1brown ( link )。

现在你已经对句子编码和神经网络有了基本的了解。现在两者之间的联系还有待建立。因此,是时候开始指定用于学*聊天机器人的句子编码的神经网络模型了。

通用语句编码器(使用)

正如我前面提到的,这是目前最好的句子编码器之一。该用法有多个版本,其中一个版本特别适合创建聊天机器人。这个基于变压器架构,使用注意力。这些新术语的含义将在以下段落中解释。在“注意力是你所需要的全部”这篇文章中,你可以找到额外的详细解释(链接)。

首先,变压器架构。transformer 架构提供了一种创新方法,使用一个编码器和一个解码器将一个序列转换为另一个序列,见图。与其他常用的句子编码器不同,该转换器不使用递归网络。迄今为止,递归网络一直是确定序列间依赖关系的最佳方式,但这种情况即将改变。谷歌人工智能提出了一个没有递归网络的架构,只有关注。该模型在各种 NLP 任务(翻译、问答和情感分析)上取得了最先进的结果。请参见下图中的模型架构。

图由 Vaswani 等人提供,(2017)

一下子,这些都是很多新的术语,对于更有经验的读者和该领域的新手来说,很难马上理解。因此,我将更详细地解释所有粗体术语。从序列和编码器/解码器架构开始。

序列对序列学*(seq2seq)顾名思义就是将一个元素序列转化为另一个元素序列的神经网络。Seq2seq 在翻译任务上表现非常好,在翻译任务中,一个单词序列被翻译成另一种语言的单词序列。Seq2seq 模型由所谓的编码器-解码器结构组成。编码器处理输入序列,并将其转换为 n 维向量(句子编码)。这个抽象向量被输入解码器,解码器将它转换成输出序列。例如,这个输出序列可以是不同的语言。你可以把 n 维向量理解为一种通用语言。假设你给编码器输入一个荷兰语句子,这个句子必须在解码器中被翻译成法语,那么这个 n 维向量就充当了一个中间语言,这个中间语言对于荷兰语编码器和法语解码器来说都是可以理解的。然而,编码器和解码器最初都不会流利地使用这种通用语言。所以,他们都需要接受大量例子的训练,稍后会有更多的例子。

现在我们了解了 seq2seq 和编码器-解码器结构。然而,在变压器架构的描述中,我也谈到了循环网络。要了解这些,了解什么是前馈网络(变压器使用的网络)也很重要。我现在解释一下。

前馈网络实际上与前面在标题“神经网络”下描述的神经网络相同。前馈网络的一个例子是基于先前手动分类的数据将图片分类为猫和非猫。然后,网络将通过梯度下降和反向传播来最小化成本函数。然而,前馈网络也有一个严重的缺点,因为它们不能感知时间的顺序。这是因为前馈网络只考虑它直接暴露于什么。另一方面,除了接收到的当前输入,循环网络还能够记住过去的输入。一个循环网络有时被比作一个人,因为它有一个在决策中起作用的记忆。因此,循环网络非常有用,经常使用。然而,变压器架构不使用循环网络。这使得它无法记住输入是何时以及如何输入到模型中的。这是必要的,因为句子中的每个单词都有相对于句子中其他元素的位置。因此,转换器使用位置编码,这些位置被添加到每个单词的 n 维向量中。

最后,注意力的重要性和用途。注意是一种机制,它查看编码器中的输入序列,并确定序列的哪些部分是最重要的。换句话说,注意力像人一样,除了关注当前单词之外,还会记住句子中的关键词。我们这样做是为了理解一个句子或故事的上下文。因此,注意力能够忽略句子中的噪音,专注于相关信息。此外,注意力能够记住出现在句子或文件开头的相关单词。

下图更清晰地展示了注意力。红色单词是当前正在读取/处理的单词,蓝色单词是记忆。记忆的颜色越深,那一刻的记忆就越强烈。起初,注意力被用来增加循环网络,但我们现在发现,注意力本身就可以达到最先进的效果。如果你想了解更多关于注意力的知识,我推荐你阅读这篇博客(链接)。

图由瓦斯瓦尼等人提供,(2017)

到目前为止,您可能想知道如何使用这个 transformer 架构来创建句子编码。这是这样的:一个大的神经网络在各种语言相关的任务上被训练(多任务网络)。一个普通的编码器用于此,见下图。常见的编码器(见图中红色部分)是带有相关转换器架构的使用编码器。这种多任务神经网络在大量数据上接受训练,“学*”对所有这些任务通用的句子编码。当训练完成时,公共编码器被断开。这个编码器可以用于其他特定的任务,如聊天机器人!

图由奇丹巴拉姆等人(2019)

使用多语言句子编码器的原因是多任务神经网络中增加了翻译任务。剩下的三项任务(会话反应、快速思考和 NLI)都是用同一种语言训练的。另一方面,翻译任务是在两种语言上训练的。因此,它使得编码器创建对于翻译任务中添加的语言可解释的句子编码。总共有 16 种语言的使用培训。

简而言之,我们现在已经了解了什么是句子编码,它们是如何学*的,什么是神经网络,以及用法是如何构造的。因此,是时候展示如何在 Python 中将这种用法应用到您自己的数据集了。

数据新冠肺炎的实现使用和聊天机器人

现在是时候展示如何使用它来构建我们自己的聊天机器人了。使用的编码是预先训练好的,该模型可在谷歌的 TensorFlow Hub ( 链接)中获得。

首先,简单描述一下数据集。关于这些不幸的日冕时代,我们选择了一个相关的数据集。即一名来自世界卫生组织(世卫组织)。正如我前面提到的,世卫组织网站上有一个网页提供了关于冠状病毒的常见问题的答案。这正是适合聊天机器人的数据类型。我们收集的数据集包含关于冠状病毒的各种主题的 86 个可能的答案(包括“什么是冠状病毒”和“新冠肺炎的症状是什么”)。相关数据集和代码可在相应的 GitHub 页面(链接)获得。

现在是时候对创建的数据集进行应用了。首先,我们加载包含使用模型的模块,并加载必要的包,参见下面的代码。您还会看到数据框的顶行,其中包含 chatbot 的所有答案选项以及答案选项的上下文。

我们希望使用刚刚加载的这个模块来创建“响应编码”。冠状病毒相关主题的所有可能答案都可以在上面的数据集中找到。这些用于创建响应编码。使用模型还提供了围绕可能的答案提供上下文的机会。上下文也可以在上面的数据集中找到。在下面的代码中,您可以看到如何基于数据集的答案和上下文创建响应编码。

现在我们有了响应编码,我们可以问一个关于冠状病毒的问题,并立即得到答案!但是,对于这个问题,我们也使用模块(提醒一下,这个包含使用)。您提出的每个问题都有一个问题编码。基于这个问题编码,算法现在可以搜索相应的响应编码。这实际上是这个聊天机器人的本质。语义上最相似的响应是使用内积找到的,如先前在“自然语言处理”下所解释的。下面的代码显示了一些测试问题,问题编码也被创建,内积被用来寻找在语义上与问题最相似的答案。

这个聊天机器人给出了上述所有测试问题的正确答案。所以这是非常好的消息!!然而,我们遇到了一些缺点。我现在将讨论这些。

缺点

第一,模型的缺点。在测试聊天机器人时,可以注意到每个包含“新冠肺炎”的问题都有一个奇怪的答案。这可以解释为所有句子编码都是预先训练好的。由于新冠肺炎病毒是一种新病毒(因此也是一个新词),在编码训练期间还没有引入这种用法。因此,这表明了该模型的缺点,因为它不能很好地处理“未知”单词。我们现在已经解决了这个问题,将“新冠肺炎”一词替换为“冠状病毒”。该算法还会对每个问题自动执行此操作。因此,在提问时没有必要考虑这一点。

此外,当数据集中有长于三句话的答案选项时,聊天机器人会给出奇怪的答案。这种用法主要适用于单句或短文本(最多。三句话)。TensorFlow 上的用户指南中也提到,该用法在一些句子上表现更好。然而,为了给出关于冠状病毒的问题的完全信息性的答案,长的答案有时是必要的。因此,这个问题的解决方案是非常有价值的。

最后,聊天机器人的缺点。目前为冠状病毒相关问题创建的聊天机器人是基于一个有点小的数据集。这意味着这个聊天机器人不能回答每个问题。为了使这个聊天机器人变得更好,可以从世卫组织收集更多的数据,数据集应该保持最新,因为经常有关于冠状病毒的更新。正如我之前提到的,如果聊天机器人能够支持更长的答案,它也会更好。不幸的是,这在使用模型中是不可能的。

一锤定音

谁知道呢,读完这篇博客后,你可能会变得热情起来,想要从相应的 GitHub 页面上可用的数据集和代码开始。这篇博文中使用的 USE 算法是可以用来构建聊天机器人的众多构件之一。因此,也有其他选择来建立聊天机器人。如果这个博客对你来说太专业了,Triple 也提供了一个替代品,Wozzbot。这是一个应用程序,提供了一个非技术性的方法来建立一个或多个聊天机器人。有关信息,请访问www.wozzbot.com并联系位于info@wozzbot.com的团队。

关于冠状病毒,为了限制进一步传播,人们尽可能通知自己是非常重要的。聊天机器人可以为此做出巨大贡献。例如,人们可以通过应用程序输入一个紧急问题,他们可以立即得到答案。简而言之,我们可以用这个做更多的事情!!

我们如何通过预测风能获利

原文:https://towardsdatascience.com/how-we-made-profits-forecasting-wind-energy-production-levels-b93bd3a7f1ed?source=collection_archive---------48-----------------------

作者插图。

比赛:ai4 impact data thon 2020
合作: Isabelle Lim,刘天伟

文章大纲

  1. 挑战
  2. 数据探索和分析
  3. 数据预处理
  4. 要优化的两个指标
  5. 特征工程
  6. 模特们
  7. 局限性和未来的改进

1.挑战

作为一名风能交易商,创建准确的预测是当务之急。管理特定区域能源网的电网运营商根据预测向风能生产商购买能源。

游戏规则如下:

  1. 我们(风能交易商)有 10,000,000 英镑作为现金储备,以防超额预测。
  2. 预测的每千瓦时风能以 10 英镑出售。
  3. 预测不足:如果产生的风能比预测的多,多余的就浪费了(我们没有从中获利)。
  4. 超额预测:如果风能发电量低于预测,我们将不得不从现货市场购买能源,每千瓦时的成本为 20 美元,以弥补不足。如果我们手头的现金少于弥补差额所需的金额,我们将因无法购买的金额而被处以每千瓦时 100 美元的罚款。这种负现金(债务)是累积的。

在这项挑战中,我们的任务是通过使用人工神经网络(ANN)对 2020 年 7 月 23 日至 2020 年 7 月 29 日交易窗口期间产生的风能进行准确的 T+18 小时预测,从而实现利润最大化。

在本文中,我们将详细介绍从原始数据到用于预测风能的最终模型的过程。

2.数据探索和分析

我们有两个数据集可以使用:

  1. 2017 年 1 月 1 日至今 RTE 的风能发电量这是我们试图预测的值。使用之前的插值和 72 小时的窗口,将 15 分钟的时间刻度数据插值为 1 小时的时间刻度。
  2. 法兰西岛地区 8 个地点的风速和风向预测,每个地点代表该地区的一个主要风电场。风速以米/秒为单位测量,方向以北纬度为单位测量。类似地,这些预测也使用之前的插值和 72 小时窗口进行插值,以适应风能生产水平的每小时时间尺度。****

此外,对风速和风向的预测来自两个不同的模型(每个模型覆盖相同的 8 个风电场位置)。这使得数据集中的列总数:

8 个位置* 2 个特征(速度和方向)* 2 个模型= 32 列

2.1 风能生产水平

风能生产水平。作者插图。

查看原始数据,我们发现风能生产水平看起来有很强的季节性。风电厂的性能在冬季和秋季往往较高,在春季和夏季较低。我们还可以看到这些年来产生的能量逐渐上升的趋势。这可能是由于多年来运行中的风力发电场数量的增加导致了发电量的增加

2.2 风速预测

2.3 风向预测

从两个预测模型中可视化风向。作者插图。

我们从两个预报模型中看到,风通常吹向东北和西南方向。

3.数据预处理

对于预处理,我们将空间平均归一化应用于风速和风向。

假设我们有 32 列数据,仅用于两个基本特征(风速和风向),平均风速和风向可以帮助减少我们数据输入的维度,潜在地使数据噪音更少,并且计算成本更低

由于风能水平、速度和方向都是以不同的单位测量的,因此标准化也是必要的,以确保所有这些值共享一个共同的标度,而不会扭曲它们各自值范围的差异。

3.1 预处理风速

从上面看风速预测图,我们看到每个模型对 8 个地点的预测看起来非常相似。因此,在 8 个地点取一个简单的平均值是有意义的。对两种预测模型都这样做可以将风速的列数从 16 列减少到 2 列。

使用下面的公式对风速进行归一化是很简单的,我们对风能生产水平也是如此。这样,我们将分布风速和发电量水平集中在 0 左右,它们现在共享相同的标度,即大多数值在[ -1,1 ]之间的标准偏差数。

标准化公式。作者插图。

3.2 预处理风向

因为方向是以北纬度来测量的,平均化和归一化风向是一个稍微不那么直接的问题,因此也是一个有趣的问题。

简单地将所有 8 个位置的方向之和除以 8 是不准确的(注意,这在平均风速时是可以接受的,认为 50 公里/小时是 40 公里/小时和 60 公里/小时的平均值)。取 359 和 1 之间的平均值,(359 +1 )/2,会得出平均值 180,这与 359 和 1 的方向完全相反!因此,我们需要另一种平均方向数据的方法。

取 359 和 1 的平均值,给我们一个方向,指向几乎完全相反的方向。作者插图。

因为弧度通过使用它所描绘的弧的长度来测量角度[1],我们可以通过首先将角度转换为弧度来解决这个问题,归一化,然后最后在 8 个位置上求平均值。请注意,我们必须在取平均值之前进行归一化,否则我们仍然会面临上述相同的问题。

为了归一化以弧度度量的方向,我们必须取它们的正弦和余弦来将方向压缩到[ -1,1 ]的范围内。我们必须同时取正弦和余弦,因为忽略任何一个函数都无法判断原始角度来自哪个象限。下图说明了这个数学问题。只有 sin(x) = ( 2)/2 给我们两个可能的值 x = {(1/4)π,(3/4)π}。只有 cos(x) = ( 2)/2 也给了我们两个可能的值 x = {(1/4)π,(7/4)π}。但是,知道了 sin(x) = cos(x) = ( 2)/2 就告诉我们,x = (1/4)π。

使用正弦和余弦函数来归一化方向。作者插图。

在平均和标准化之后,我们设法将原始的 33 列数据压缩到 7 列,而没有丢失太多信息。

数据预处理的可视化概要。作者插图。

4.要优化的两个指标

在探索特征工程和我们的模型之前,我们必须理解在优化我们的特征和模型时作为我们衡量标准的两个标准。它们是:

  1. MAE 试验损失——最小化。
  2. 美元利润占总可能利润的百分比(利润比率)——最大化。

请注意,MAE 的持久性损失为 0.6483,这是我们选择的功能和模型要克服的损失。此外,第 7 节“限制”将解释为什么使用 MAE 试验损失。

5.特征工程

平均和归一化帮助我们预处理原始数据集。从这个预处理过的数据集中,我们可以使用特征工程来准备我们的模型将要学*的实际输入数据集。特征工程是关于从我们现有的输入特征(预处理的原始数据集)中创建新的输入特征。

一般来说,你可以把数据清理看成是一个减法的过程,把特征工程看成是一个加法的过程。[2]

5.1 进行切割的特征

我们的特征工程在很大程度上是一个迭代过程,伴随着我们的模型构建过程(我们将在下一节深入探讨)。我们经历了许多功能,丢弃了我们(错误地)认为是好的原始功能,并添加了我们从未想过会起作用的新功能。经过一系列的试验和错误,这些是最终的特点,使削减。

我们最终的工程特征。

对于我们的窗口选择,我们分别从 0:-5 和 18:0 的小天真窗口开始,因为从太大的窗口开始会导致较差的学*。然后,我们慢慢增加窗口大小,因为小窗口可能会排除数据中的重要信息。我们发现,发电量的窗口为 0:-54(预测窗口的三倍),风速和风向的窗口分别为 18:-18(预测窗口的两倍)时,模型性能最佳。

5.2 未被切割的特征

我们试验过的其他功能包括:

  • 风速的立方值:我们试图使用风力发电方程来注入领域知识,其中风速是一个立方变量。然而,在测试中,我们发现使用立方风速比使用原始风速在利润和测试损失方面表现更差。

风力发电方程式。作者插图。

  • 捕捉风速和风向之间的相互作用:我们认为风能高度依赖于风速和风向是很直观的。根据我们外行人的直觉,如果我们的风吹向正确的方向,但速度很低(或速度很高,但方向错误),这将导致产生的能量水平很低。反过来看起来也是一个合理的论点。因此,我们试图通过乘以风速和风向来捕捉这种相互作用。然而,我们发现这些特征并没有帮助改善模型的测试损失或利润。
  • 差异、动量和力:我们对 2、6、9 和 18 的差异、动量和力项进行了实验,发现模型几乎没有改进。在某些情况下,该模型甚至表现更差。
  • 原始风速和风向窗口:我们使用风速和风向窗口作为输入进行测试。数据窗口可以捕捉趋势和模式等重要信息。然而,需要注意的是,具有相似速度和方向的窗口可以被映射到彼此非常不同的向量(即较差的聚类)。我们的测试表明,使用从移动窗口得到的特征集合的模型(表示标准偏差最大值最小值一阶微分平均二阶微分)始终优于使用原始速度和方向的移动窗口的模型。

6.模特们

有了经过预处理的原始数据和一系列工程功能,我们现在完全有能力开始试验我们神经网络的架构调整其超参数评估其性能,以便决定部署最合适的模型。

在我们运行的无数模型中,我们从实验的 3 个阶段中的每一个阶段记录了一个关键模型,该模型捕捉了我们的意图和模型的结果。

6.1 模型 V0 —基线基准

模型 V0 的架构。作者插图。

我们从最基本的神经网络和最基本的特征开始,如图所示。在保持⅔减少层间节点数量的同时,我们对第 1 层的节点数量进行了试验。如下所列,我们试验了第 1 层中节点数量的不同配置、损失函数的类型和反向传播算法的类型。第 1 层中的【32】、用于反向传播的【MAE】损失函数和【Adam】的配置(下面加粗)产生了 0.7306 的最小测试损失和 0.4218 的利润比率。

这个模型设置了基线基准,我们的目标是在后续的模型迭代中超越它。

  • 网络:⅔归约 4 层,从第 1 层的 16 / [ 32 ] / 64 个节点开始。
  • 输入特征:T0 时的风能值,T18 时每个模型的平均风速和风向(余弦和正弦)(7 列)
  • 损失函数: RMSE / 【梅】/ 非对称*
  • 反向传播算法:****【Adam】/SGD
  • 最小。测试损失: 0.7306
  • 利润/最大值。可能利润: 0.4218

6.2 模型—试验我们的工程特性

模仿 V1 的建筑。作者插图。

一旦我们确定了神经网络的粗略结构,我们就开始用 4.1 节中提到的工程特征进行实验。使用我们设计的所有特征,第 1 层中的【128】****【MAE】损失函数和用于反向传播的【Adam】的配置产生(下面加粗)0.4829 的最小测试损失和 0.5804 的利润。这种配置是 V0 车型基准测试的最大改进。

  • 网络:⅔归约的 4 层,从第 1 层的 32/64/【128】节点开始。
  • 输入特性:第 4.1 节中提到的所有工程特性(313 列)
  • 损失函数: RMSE / 【美】 /不对称
  • 反向传播算法:****【Adam】/SGD
  • 最小。测试损失: 0.4829
  • 利润/最大。可能利润: 0.5804

6.3 模拟 V2 —体验复杂的网络功能

模仿 V2 的建筑。作者插图。

我们从使用 V1 模型的实验中了解到,与基准测试相比,我们的工程特性始终提供更低的测试损失和更高的利润。在这最后一轮实验中,我们因此坚持使用我们所有的工程功能,并试验了更复杂的网络功能,如输入缩放、退出和 L2 正则化。这一次,从输入缩放【无】箝位、【128】第一层节点、【0.1】丢失概率、【0.001】L2 正则化权重衰减、【MAE】损失函数和【Adam】反向传播(下面加粗)开始的配置产生了最低的测试损失 0.4794。

  • 网络: 4 层带⅔归约,从第 1 层的 32/64/【128】节点开始。
  • 输入缩放:带/ 【不带】箝位
  • 退出概率:[0.1] / 0.2 / 0.25
  • L2 正规化重量衰减:[0.001]/0.0001/0.00001/0.000001
  • 输入特性:第 4.1 节中提到的所有工程特性(313 列)
  • 损失函数:RMSE/【MAE】/不对称
  • 反向传播算法: 【亚当】/ SGD
  • 最小。测试损失: 0.4794
  • 利润/最大值。可能的利润: 0.5912

6.4 其他实验/模型:

在上面列出的三种主要类型的实验中,这些是我们实验的其他修改,它们没有针对我们的两个指标优化我们的模型:

  • 添加第五层:由于我们的训练数据集相对较大,我们想看看我们的模型是否会随着额外的复杂性而改进,因此用第五层对其进行了测试。然而,这增加了我们的测试损失,反而导致更多的过度拟合。
  • 瓶颈尺寸为 1.5、2、4 和 8 的自动编码器:由于我们的神经网络正在处理大尺寸输入(> 300),我们希望使用自动编码器来降低尺寸。然而,这反而使我们的测试损失和利润更糟。
  • 平方感知器:平方感知器作为普通感知器的替代物,可能有助于模型比普通感知器学*得更好,但在我们的模型中,没有平方感知器的模型表现更好。
  • 动量和力损失:动量和力损失通常是为了帮助减少滞后,但在我们的情况下,我们的滞后相关性已经达到峰值 0。不管怎样,我们对这些损失进行了试验,正如所预料的那样,有动量和力损失的模型最终会有更严重的试验损失,因为求差通常会导致更大的噪声。

7.局限性和未来的改进

7.1 H 测试损耗高,培训与测试损耗差距仍然很大

这表明该模型对看不见的数据概括得不够好,可能是网络可能正在记忆训练数据的警告信号。即使有了功能工程,微调现有功能的窗口,在 V2 模型中添加辍学和体重调整,这些变化也只是略微改善了训练和测试损失之间的差距。相对较高的测试损失和较大的差距的两个可能原因是:(1)数据本身非常嘈杂,以及(2)所提供的数据不能真正预测风能生产。

解决非预测性数据问题的一个潜在方法是获取更多预测性数据。在预测风能生产的情况下,我们可以考虑包括空气密度、风电场的效率系数和转子叶片长度(所有这些都属于风力发电方程的术语)的外部数据源。这可能会提高我们拥有的预测数据的数量,从而提高神经网络的概括能力。

7.2 一致的预测不足

从“实际与测试预测”图中,我们看到在我们的模型中,大部分绘制点倾向于低于 45 度线。这意味着我们的模型总是低估风能产量。这在“测试预测”图中也可以看到,我们在上部区域看到更多的蓝色,表明上部值经常预测不足。

预测不足的一个可能原因是我们用来训练模型的数据集。在用于训练模型的原始数据集中,我们有从 2017 年 1 月 1 日至今所有 8 个位置的风速和风向预测。虽然每个位置代表了法兰西岛地区一个主要风电场的位置,但 Boissy-la-Rivière 仅从 2017 年 8 月开始运行,而 Angerville 1 和 Angerville 2 (Les Pointes)仅从 2019 年 7 月 2 日开始运行。对于给定的风力预测,这可能会影响该地区的总发电量(即,相同的平均风速可能会导致 2019 年下半年的风能发电量高于 2017 年上半年)。这可能会在数据中引入噪声——不是由于我们的模型输入的变化而导致的风能产量的变化。

因此,我们在 3 个数据集上测试了我们的 V2 模型:

  1. 从 2017 年 1 月 1 日至今的原始数据集
  2. 一个加权数据集,将 2017 年 8 月 1 日之前的能源实际值乘以 50%,将 2017 年 8 月 1 日至 2019 年 7 月 2 日之间的能源实际值乘以 80%,将 2019 年 7 月 2 日之后的能源实际值乘以 100%。根据以下公式估算各持续时间的权重: %运行中的风能发电量=当前运行中的风电场的总估算标称功率输出8 个主要风电场的总估算标称功率输出。
  3. 一个截断数据集,仅包含 2019 年 7 月 2 日之后的数据,基于所有 8 个风电场都在运行且风能生产能力从该点起没有显著变化的假设。

以下是结果对比:

原始数据集、加权数据集和截断数据集之间的 MAE 测试损失比较→原始数据集优于其他数据集。

尽管在截断数据集上训练的模型导致最低的测试损失 0.38,但在原始数据集上训练的模型导致最高的实际利润与总可能利润比率。在加权数据集上训练的模型在这两个指标方面表现最差,甚至导致了大量的美元损失。最后,我们决定坚持使用原始数据集,因为我们的目标是最大化利润,而不是最小化测试损失

假设法兰西岛地区的风能发电量不变,当 2019 年 7 月 2 日之后有大量数据可用时,使用截断数据集可能是一种可行的方法,可以改善我们未来的测试损失和利润。

7.3 MAE 测试损失可能与利润最大化目标不一致

我们采用的 MAE 测试损失对每个预测不足和预测过度的单元进行相同程度的惩罚。然而,从挑战的设置中,我们知道 1 千瓦时的过度预测的成本是 1 千瓦时的两倍,而 1 千瓦时的预测不足。因此,MAE 测试损失不是我们预测误差相对成本的真实反映,因此可能不是用于优化我们模型的最佳指标。

因此,我们定义了自己的损失函数:

我们定制的损失函数——不对称损失,对过度预测的惩罚大于对不足预测的惩罚。

通过这种方式,我们能够更准确地反映我们的挑战设置,并对过度预测进行两倍于不足预测的惩罚。

我们在原始数据集上测试了我们的模型性能,但是使用了两个不同的损失函数:

MAE(左)和 ASYM(右)损失的实际与测试预测图。

比较 MAE 和 ASYM 损失函数的利润率→ MAE 优于 ASYM。

我们看到,在“实际与测试预测”图中,与使用 MAE 损失函数相比,使用 ASYM 损失函数减少了过度预测的数量,增加了预测不足的数量。这是意料之中的,因为我们对过度预测的惩罚比对预测不足的多。

然而,当我们比较实际利润和总可能利润时,我们发现使用 MAE 测试损失比 ASYM 测试损失帮助我们的模型获得更多利润。因此,最终,我们选择使用 MAE 测试损失。

使用 ASYM 没有提高我们的利润的一个原因,即使它更能反映挑战设置,可能是由于我们的模型中已经存在更普遍的预测不足的问题(见限制 7.2)。我们的模型已经显示出预测不足而不是预测过度的趋势,因此使用 ASYM 将使我们模型中的预测不足问题更加严重,而对我们的预测过度仅做出适度的改进,因此导致我们在潜在利润上损失更多。因此,只有当 7.2 的限制得到解决,我们得到更好的数据时,不对称损失函数才可能是一个更可行的解决方案。

谢谢你

如果你已经读完了这篇文章,我希望你喜欢这篇文章。如果这篇文章给你自己的项目带来了一些启发、价值和帮助,请随意与你的社区分享。此外,任何建设性的问题,反馈或讨论都是绝对受欢迎的,所以请随时在下面评论或通过 Twitter 联系我,地址是 @CleonW_。

参考

[1]https://better explained . com/articles/intuitive-guide-to-angles-degrees-and-radians/

[2]https://elitedatascience.com/feature-engineering

我们如何用强化学*训练蚂蚁

原文:https://towardsdatascience.com/how-we-trained-ants-using-reinforcement-learning-7ec651c08cc0?source=collection_archive---------43-----------------------

一个模拟蚂蚁的项目。深度强化学*和多智能体系统的混合。

编剧:安东宁·杜瓦尔和托马斯·拉姆森

图片:ALLGORD/ISTOCKPHOTO

如果你曾经观察过一群蚂蚁,你可能会注意到它们看起来是多么有组织。为了采集食物和抵御威胁,平均 250,000 只蚂蚁需要合作和自我组织。通过使用特定的角色和一种强大的工具——信息素——成千上万只有些受限的蚂蚁可以合作实现更大的目标。

我们感兴趣的是探索这种行为在模拟环境中的出现。给一些“蚂蚁”正确的工具使用和探索的环境,我们会看到这些现象从无到有吗?

在多智能体理论和强化学*的交叉路口,我们设计了一个系统,让一群非常简单的蚂蚁制定聪明的策略来优化它们的食物供应。

为了引起您的注意,并让您更好地理解我们在这里尝试做的事情,请看一下我们美丽的随机代理的这个快速视频。

50 只蚂蚁的随机智能体模拟

它做的不多,但你会看到我们将如何改善我们的蚂蚁,让他们一起工作!我们将在下面进一步解释环境如何工作以及代理如何与之交互。

钻研手头的问题

假设

为了让我们训练的蚂蚁的行为接*真正的蚂蚁,我们首先以一种聪明的方式设计它们的环境是很重要的。所以,让我们来看看我们做实验的主要假设。

第一个也是最重要的假设是药剂的完全隔离。这是多代理范例的主要假设之一:代理没有任何不通过环境本身的直接通信方式。

第二个假设是感知的相对性。重要的是我们的特工不知道他们在世界上的位置和方位。总的来说,他们只是从个人的角度看世界。

环境

对于任何 RL 应用程序,环境的定义是项目的核心。

我们蚂蚁的环境截图

  1. 墙壁:那些是程序生成的岩石,禁止蚂蚁通过。
  2. 蚂蚁:我们代理商的代表是这些小黑蚂蚁。
  3. 蚁丘:中间的蓝色圆圈是每个蚂蚁来的地方,也是每个蚂蚁带食物回来的地方。
  4. 食物:那些绿色的圆圈,也是程序生成的,是食物来源。蚂蚁可以把它们捡起来,去掉一个像素,然后把它丢进蚁丘。
  5. 信息素:我们给蚂蚁两种信息素。一个红色的和一个蓝色的。两者都是自己下面的蚂蚁沉淀下来的,随着时间的推移慢慢淡去。
  6. 探索地图:我们的蚂蚁完全看不到,这个黄色的可视化区域代表了地图上被所有蚁群探索过的区域。

生成环境的代码尽可能简单,以便任何人都可以尝试不同的地图配置。通过使用不同的程序生成器,你可以生成不同密度的墙,许多或一些食物源,远离或不远离蚁丘,等等。最后,如果必要的话,可以指定一个种子来确保生成的环境是受控的,这对于在同一个地图上评估我们不同的代理是有用的。

代理人

你已经在上面的图片中看到他们了,但是让我们给出更多关于我们的代理的细节:蚂蚁。正如假设中所解释的,我们的代理完全相互独立,不共享任何直接信息。他们的内部定义随着我们实现的不同模型而变化,但是他们对世界的感知和对世界的行为方式是相同的。

你可以看到当一只蚂蚁捡起一些食物时:它的下颚间有一个绿点。是不是很可爱?

感觉

他们能看到前方一定半径范围内的情况。这是一个代表他们感知形状的图像,用 2D 网格中的离散槽来表示。首先,我们通过应用相对于它们当前位置的平移和旋转来计算每个感知槽的浮点坐标,然后我们对这些坐标进行舍入以获得它们感知的真实 2D 网格槽。它有时会给出奇怪的结果,但是我们认为我们的蚂蚁就像真正的蚂蚁一样:非常不善于观察事物!然而,他们应该能够很容易地发现他们面前的信息素,墙壁,食物或其他蚂蚁。

蚂蚁在我们的模拟中所能看到的视觉表现

用数学术语来说,他们的感知总是一个 7x7 的正方形矩阵,用一个面具使它更圆,用尽可能多的层来代表他们视觉的每个“通道”。在我们的例子中,世界上每一种类型的物体(蚁丘、其他蚂蚁、食物、墙壁、信息素等。)表现在不同的感知层面上。这给出了非常有规律的感觉,这种感觉很容易在以后反馈给神经网络。

行动

蚂蚁可以执行两种类型的动作:

  1. 好转
  2. 存放选定类型的信息素

当它们的下颚空了,地板上有食物时,它们会自动捡起食物,如果它们在蚁丘里,它们会扔掉食物。我们也可以让他们学*这些动作,但是我们认为这些简单的规则并不复杂,所以我们节省了一些学*时间并手动实现了它们。

最终,我们的蚂蚁不得不控制它们的航向朝着正确的方向前进,并且释放信息素与其他蚂蚁进行长期交流。正如我们将看到的,这已经很困难了。

如何激励蚂蚁

在这个阶段,我们有功能,但完全空的蚂蚁壳。现在是赋予他们生命并让他们实际行动的时候了。

如果你以前听说过强化学*,你就知道学*最优策略的关键要素之一是拥有一个设计良好的奖励函数。这就是我们将如何教我们的代理执行某些类型的行为。在这里,我们的蚂蚁只有一个目标:坚持不懈地为蚁丘提供食物。这个简单的任务需要长期规划和社会合作。因此,我们把它分成一系列不同的子目标:较小的奖励,我们将用来告诉我们的蚂蚁“是的,你做得很好,继续这样!”。

这是我们如何编写奖励函数的:

  • 当一只蚂蚁在地图上找到美味的沙拉(绿色像素)时,食物奖励就是一个分数。
  • 由于蚂蚁没有全球定位系统,它们不知道自己在哪里。他们必须找到一种前进的方式,而不会被堵在墙上,也不会回到蚂蚁之前所在的地方。当他们探索地图的新部分时,我们会给他们奖励。
  • 就像一个晚上喝了太多酒,手机没有电池,我们的蚂蚁很难找到回家的路。他们需要一点帮助,但我们没有直接给他们:我们设计了一个奖励,只要他们携带一些食物,减少他们的位置和蚁丘之间的距离,就给他们一个好点。
  • 最后的奖励,也是最重要的。在长途跋涉之后,是时候把食物放进蚁丘了。蚂蚁每成功一次,我们就给它一分。

这里,ω1、ω2、ω3 和ω4 是在训练开始时设置的任意因子。这些都是超参数,我们必须非常小心地调整,因为它们完全改变了我们蚂蚁的学*和行为方式。

用 DQN 教蚂蚁

这篇帖子的目标不是详细解释什么是深度 Q 学*算法( Mnih 等人,通过深度强化学*的人类级控制(2015) [1])。如果你对此不熟悉,我们邀请你阅读这篇伟大的文章 [2],它解释了你需要知道的关于强化学*的一切!

由于蚂蚁可以同时执行两个动作(移动和存放信息素),我们需要为每个动作输出 2 组 Q 值。怎么做呢?论文分支 Q-learning A. Tavakoli,2019【3】给出了一个共享的决策模块,后面跟着几个网络分支,每个行动维度一个。最后,我们有两个独立的网络头预测独立动作的 Q 值。为了决定要执行的动作,我们只需选择每个分支的最大值,这就给出了一个动作组合!

由于我们没有办法确保我们走在正确的方向上(嗯,理论上它可以工作,但这很容易说),我们决定在一个更简单的问题上迈出第一步:教蚂蚁探索地图。

我们设定ω1 = 1,ω2 = ω3 = ω4 = 0,用 20 只蚂蚁展开了 50 个纪元的训练。下面是结果!

代理人被训练探索 50 个时代的地图。

此回放是在评估模式下从随机地图中截取的。从这个回放中,我们可以得到两个主要的感悟:

  1. 代理学会去没有信息素的地方,因为它更有可能是地图上尚未被探索的部分。
  2. 特工们学会了用一种有趣的方式使用这两种信息素。他们在探索时使用红色的,当他们通过已经看到的领域时使用蓝色的。那是什么意思?我们不知道。但也许他们有。

太好了,我们的模型成功了!然而,让我们试着更像严谨的科学家,通过展示每一次训练的平均回报和平均损失的图表,向你证明我们的蚂蚁有所提高:

越来越多的损失?嗯,这在强化学*中还不错。在我们的例子中,它主要是增加的,因为我们的代理人得到的回报越来越高,我们也增加了网络在预测这些 Q 值时产生的误差范围。我们真正感兴趣的是蓝色曲线,从中我们可以清楚地看到勘探从随机基线开始增加(它只擅长勘探)。

有记忆的特工

我们成功训练了一名探险特工。现在,让我们深吸一口气,深入真正的任务:让蚂蚁捡起食物并带回蚁丘。

为此,我们决定改变我们网络的架构,并从 LSTM 网络中获得灵感。我们添加了一个分支来创建某种内存信息,它将从当前状态传递到下一个状态。此外,我们在中添加了一个遗忘门,这是一个由一系列层组成的堆栈,之后是一个 sigmoid 激活,这样网络就可以在记忆的时候学*,在记忆什么。下图给出了完整的架构。

我们网络的架构

我们称“内部状态”为两条在感知矩阵中不直接可见的信息:蚂蚁目前持有多少食物,以及一个随机种子,它给每只蚂蚁区分自己的机会(种子在整个事件中对给定的蚂蚁保持不变)。

最后,记忆作为任何观察信息存储在重放记忆中,使每只蚂蚁都有能力被训练正确地记住事情。

训练时间!

现在我们有了更强的网络,一个好的奖励功能,我们只需要开始加热机器,开始训练!但是等等…仍然有一些重要的超参数需要选择。

这种多智能体系统的好处是,我们可以让它与任意数量的蚂蚁一起工作。然而,由于像现实生活中那样用 250,000 只蚂蚁进行训练对地球和我们可怜的计算机来说似乎不太合理,我们决定只用 20 只蚂蚁进行训练。

历元数该参数根据经验选择。因为环境是用 Python 编码的,所以引擎相当慢。因此,我们不得不将纪元的数量限制在 150–200,以限制训练时间。如果我们与其他强化学*应用程序相比,这是一个相当小的事件数。然而,结果表明,在我们的情况下,获得执行行为就足够了。

衰减ε探索是强化学*的关键。我们使用了一个衰减的ϵ因子。这使得我们的特工可以在第一集探索很多,然后慢慢开始挑选最好的行动。

结果

终于要看到一些成果了!我们的蚂蚁学到什么了吗?我们能解释一下学到的东西吗?我们将从现在开始讨论这类问题。

尽管我们每集训练的步数不超过 1000 步,我们还是制作了一个 20000 步的视频来看看发生了什么。还记得我们如何用 20 只蚂蚁训练我们的模型吗?一旦经过训练,我们实际上可以使用任何数量的蚂蚁!所以,因为更有趣,我们用 50 只蚂蚁做了这个模拟。我们终于可以看到我们的蚂蚁在地图上收集所有的食物,坚持不懈地在整个地图上建立它们的信息素网络,一旦一个用尽就改变目标…我们包括了一些只有信息素的部分,因为我们发现它们很漂亮。

经过 150 个时代的完全训练的蚂蚁

我们观察到它们建立了某种信息素网络,用来在地图上移动。因为他们学会了被某种类型的信息素所吸引,他们更倾向于选择一些路径。这创造了道路的层次,有些是真正的高速公路,有些更像是小乡村小路。

结论、未决问题和进一步发展

我们最初的目标有点雄心勃勃:我们已经在想象蚁群为了食物而相互争斗,蚂蚁将石头推出小路或推入小河以通过障碍并获得更多食物……永远以星星为目标!

即使在 150 个世代之后,结果仍然非常有希望,我们确实在蚂蚁社会中看到了一些新出现的行为,这是我们主要关心的。现在,我们觉得我们不能就此止步,但这已经是我们这个项目的最后时间了。然而,这不会阻止我们更新这个项目和这个职位!

在进一步的发展中,我们将让蚂蚁用它们的下颚来行动,以便像其他蚂蚁一样在拾取食物和对抗威胁之间做出选择。我们还将使地图更加复杂,并为蚂蚁提供一种更容易沟通的方式,通过一种可见的状态,当足够*时,其他蚂蚁可以看到。但是在这之前,我们要用 C++重新实现我们的模拟:我们有一个独家新闻,Python 是

我们只看到了我们所期望的新兴行为的最开始,但是我们相信,如果我们为我们的代理添加更多的工具,并解决更复杂的问题,我们将会看到越来越多的聪明行为出现!

嗯…很多事情可以做,从我们停下来的地方开始!也许新的篇章会随之而来?谁知道呢。

要获得该项目的完整 Python 源代码,请访问我们的 github:【https://github.com/WeazelDev/AntsRL

参考资料:

我们在整个项目中使用的主要模块:

  • Numpy —用于模拟
  • PyTorch —用于代理定义和 DQN 培训
  • PyGame——用于可视化

全文可以在这里看到:

最初发表于https://antoninduval.github.io/

在新冠肺炎时代,我们如何使用机器学*

原文:https://towardsdatascience.com/how-we-used-machine-learning-in-the-era-of-covid-19-c29ba64b07c5?source=collection_archive---------40-----------------------

我们有些人工作的大楼是空的。就每天的工作时间而言,技术招聘并没有放缓,而是增加了。人力资源部没有改变招聘流程。然而,我们改变了候选人的排名方法,并从根本上改变了我们进行面试的方式。

在这个艰难的市场中,哪一个是 ML 的候选人?资料来源:联合国人类住区规划署

我们如何改变技术招聘的背景

我们喜欢认为,作为一个组织,我们的核心专长是预测金融市场未来一个季度(短期赌注)到五年(长期赌注)到二十年(世代赌注)的走向。分裂出来的团体模拟不同大扰动的影响。我们的预测是乐观的,因为公司不采取包括假设扰动的立场。

扰动是混乱的。当不同的研究成员/小组达成共识时,意外的扰动被确定为已经开始。那么(se)扰动变成包括在财务决策制定策略中。

扰动的几个例子,从低到高的概率,是外星技术转让,1 千兆吨流星撞击,10 兆吨流星撞击,实用量子计算,泛流行病,以及全球平均温度上升 3 摄氏度。

还有许多其他的扰动情况。我列举了几个来展示产品系列。新冠肺炎大流行和全球平均气温上升 3 摄氏度是我们金融决策政策的一部分。

我想澄清我的角色:

  • 我是 不是 理财政策的一部分。
  • 我的内部职位是机器学*科学家。
  • 我只是一个有权写下我们技术招聘流程变化的人。

意见如何捕捉、塑造我们在招聘方面的变化

我详述了我们是如何决定我们正在做的事情的。

意见库由我与您分享的意见组成。

这篇文章是基于我的观点,收集了我的组织的意见。我分享与这篇文章相关的观点。 ( 我认为所有收集到的意见目前都是公开的 )

六周前,我们在意见 - 中捕获了可信的意见和假设。(我们几个老前辈偶尔会说漏嘴,把这个叫做知识库。)有一个字段将每个条目标记为意见假设。大约 30%的收集条目有一个任意(随机)的标签意见假设

我们很多人都有朋友、亲戚和熟人,他们是护士、医生、病毒学家、生物物理学家、生物工程师,甚至还有流行病学家。在 6 周的时间里,我们从这些人那里收集了个观点

我们的机器学*( ML-dev )小组,我是其中的一员,被指派分析和报告来自意见库的数据。由于部署时间最短,仪表板报告使用我们专有的时序 ML 框架和 Streamlit 创建。

下面的文章详细介绍了我们最*使用 Streamlit 的一些经验。

[## Streamlit 还不能取代 Flask

Streamlit 2020 路线图

towardsdatascience.com](/streamlit-can-not-yet-replace-flask-the-streamlit-2020-roadmap-64840564acde)

在第一个测试版发布后,我们发现事实假设观点改变或撤回为了降低维护成本,事实被标记为观点,每天开始时有一个基于委员会的筛选。没有给每个条目分配权重,而是留给各种下游应用程序。

从意见库中随机转储的意见

以下参考文献,在我看来,对普通大众来说是更好的来源。这些参考资料为我们的意见库生成了条目。

[## 冠状病毒:为什么你必须现在行动

政治家和商业领袖:你应该做什么,什么时候做?

medium.com](https://medium.com/@tomaspueyo/coronavirus-act-today-or-people-will-die-f4d3d9cd99ca)

真正减少的唯一方法是保持社交距离:让人们尽可能地呆在家里,尽可能长的时间,直到这种情况消退。

我们越是推迟病例,医疗系统就能更好地运转,死亡率就越低,在感染前接种疫苗的人口比例就越高。

[## 冠状病毒:锤子和舞蹈

如果领导人给我们争取时间,未来 18 个月会是什么样子

中等。](https://medium.com/@tomaspueyo/coronavirus-the-hammer-and-the-dance-be9337092b56)

意见库中选择相关条目:

  • 有报告称,年轻人检测出受感染,并在大多数情况下表现出症状。注意:大多数美国人,25 岁以下,表现出症状,因为测试规则选择了症状。
  • 佛罗里达海滩因 2020 年春假而关闭。
  • 新冠肺炎检测必须大于 1000 人中的 5 人。
  • 在美国,医院病床的容量在两到七周内就被超过了(95%的可能性)。随着一些州开放新的医院床位设施,参赛人数变化很大
  • 估计死亡率在 0.5%(有准备的)和 5%(无准备的)之间变化。进入是可变的,因为它取决于不确定和变化的起始条件和费率。
  • 2(最小)米到 4.5(最大)米是社交距离指导。
  • 在美国,权威人士称一个集群中有 2 到 25 个人。
  • 封锁正在拉平中国的感染曲线。
  • 检测和自愿的社会距离拉平了韩国的感染曲线。
  • 欧盟和英国的自愿封锁;
  • 检测是韩国 1000 人中的 4 人;
  • 新冠肺炎是无法治愈的。
  • 一个估计是用于新冠肺炎 T2 T3 的预防性疫苗将在 12 个月后问世。
  • 新冠肺炎正在变异。
  • 新冠肺炎变成了一个类似于流感季节的季节性事件。

[## 流行病计算器

编辑描述

gabgoh.github.io](http://gabgoh.github.io/COVID/index.html)

新冠肺炎时代的工作环境和技术招聘流程是怎样的

企业新冠肺炎政策执行社会距离

我们有一个时间表,将应用开发部门( AppDevD )过渡到一个地理上和时间上分布的工作环境。效仿的榜样是成功的 阿帕奇软件基础

因为新冠肺炎,****时间线已经被废弃。当我们远程工作时,我们正在执行、改进和适应。一个似乎不太需要改变的领域是我们的技术招聘流程。

社交距离所做的更改以斜体突出显示。首先,我详述了 WA-dev (Web-App) groups 流程。

WA-dev 简历的排名得分取决于:

  1. 提到使用两个或更多的 HTML、CSS、Javascript、Flask、和有时Django;****
  2. 使用短语全栈,后端,前端或各种其他关键字。
  3. 一个或多个开源网络应用/项目;
  4. 任何远程开发的经验。

注意:步骤 1、2 是自动解析的。随机抽取 10%进行评分。将人工评分与不同模式的自动评分进行比较。根据不同的群体,如果候选人篡改了他们的简历,这不一定是一件坏事。

这一过程的下一个重要步骤是:

  1. 对代码进行粗略的检查;
  2. WA-dev 运行他们的后期开发工具,并在其中最有趣的工具上运行任何包含的测试;
  3. 后续电话验证候选人编写了代码;
  4. WA-dev 向候选人发送一个过去的(或现在的)编码任务。候选人必须在最多三天内返回代码。候选人被告知 WA-dev 更关心方法而不是完整的代码解决方案。他们应该至少提供一个代码框架和足够的代码解决方案来展示候选人的编码原则。(我们被辅导说纪律不是风格提示提示。)**
  5. 前 3 个月是试用期,小组决定是否继续保留成员资格。

机器学*( ML-dev )组(只是一个组)遵循 WA-dev 招聘步骤。我们确实会根据候选人的资历来改变和增加这些步骤。ML-dev 为出版物、演讲、开源软件包或框架作者放置了不同的排名。我们从未在提交的简历中看到 Streamlit 。如果我们做到了,那当然很好,但现在让它成为行业流行语可能还为时过早。

结论

我们使用新冠肺炎观点库来帮助金融市场预测小组。执行管理层根据金融市场预测小组的意见制定政策。预测和短期和长期政策已经完成。意见库和所有报告已被删除,因为它们现在已经过时。

现在公众可以获得更多的资金和资源。以下是一些我们喜欢的:

** [## 美国各州和国家的冠状病毒死亡人数:每日追踪

随着冠状病毒疫情的出现,世界各地都有人死亡。但是病例和死亡的轨迹不同…

www.nytimes.com](https://www.nytimes.com/interactive/2020/03/21/upshot/coronavirus-deaths-by-country.html?te=1&nl=the-upshot&emc=edit_up_20200323&campaign_id=29&instance_id=16997&segment_id=22618&user_id=48dc240842d821249f8f2b3816220aca&regi_id=7726097920200323)

约翰·霍普斯金冠状病毒新冠肺炎全球病例由系统科学与工程中心仪表板

[## ArcGIS 的操作仪表板

编辑描述

www.arcgis.com](https://www.arcgis.com/apps/opsdashboard/index.html#/bda7594740fd40299423467b48e9ecf6)

新型冠状病毒的基因组流行病学。

[## 吉兆

编辑描述

nextstrain.org](https://nextstrain.org/ncov?c=clade_membership&l=radial)

这篇文章记录了我们在组织中所做的改变,以及这些改变如何改变了我们的组织。我已经详细描述了我们技术招聘过程中的温和变化。 WWW 上有文章会救命。继续读下去,尽你所能保持安全,保护他人的安全。**

网络搜集如何帮助我从学*走向教学

原文:https://towardsdatascience.com/how-web-scraping-helped-me-going-from-learning-to-teaching-20c1bba7a10b?source=collection_archive---------60-----------------------

还有一个快速教程

卡特曼戈斯塔-www.freepik.com 创建的业务向量

我在今年 2020 年初开始学*数据科学的 python。我基本上没有任何编程背景,除了很久以前在大学里用 C++ 类编程。虽然我可以在互联网上找到一些很棒的(有时是免费的)课程,但总有一些情况下,你需要向社区寻求一些帮助,有时是因为你不理解一些概念或技术,有时是因为你正在尝试一些更复杂的东西。我过去经常(现在仍然)这样做。

但是通过第五个月的学*,我开始发现这个问题的另一面:那些回答问题的人。我当时(现在仍然)使用一个名为 Dataquest 的在线平台。他们有一个很棒的社区,人们在那里分享项目,寻求帮助等等。在那里我发现,无论你是一个多么初级的人,总会有人比你更初级。

所以,我现在已经在他们社区活跃了一个月左右。在我被他们的新冠肺炎经济资助奖学金录取后,我开始更频繁地去那里。被接受参加这个项目让我对在每个人都经历的困难时期得到帮助感到非常感激,所以我觉得我应该付出更多的努力来帮助别人。然后,我开始每天访问社区,看看我是否能帮助一些人。

我的想法是,如果我可以帮助其他学生解决他们的问题,我不仅可以帮助我回答问题的学生,还可以帮助最初帮助我的平台。

虽然我已经学*了将*六个月,但我仍然不是 python 专家或有经验的数据科学家或类似的人。我只是一名数据科学学生,所以我不确定我是否有能力回答人们的问题。但事实证明,我是。当我继续回答问题时,我注意到我也在帮助自己,因为我必须重温我已经学过的东西,甚至学*新的东西来回答问题。

过了一段时间,我发现自己每天都要在浏览器中输入几次 community.dataquest.io ,并且乐在其中。所以我想了一个方法来优化我的时间和我提供的帮助:我写了一个 web scraper,每当有新的问题在社区中发布时,它都会通过电子邮件通知我。

这样做的好处是:

我练*刮痧;
·我不再需要一直手动查看网站;学生的问题可以更快得到回答(当然,如果我有能力回答的话)。

我知道,当你是一个初学者,陷入困境时,很容易失去动力,特别是如果你依赖社区来获得一些答案,并且需要等待几个小时甚至几天才能得到一个允许你继续前进的答案。

坏处是…嗯,我没看到。每个人都赢了。

在我让我的 scraper 工作之后,我觉得把这个想法和代码分享给社区中的每个人会很好。我分享的目的只是试图让更多的人帮助别人,展示刮擦(这很有趣)可以很简单,也许会让一些人对它感兴趣,当然,分享我所做的。这个想法很受其他用户和版主的欢迎,我被鼓励去发表这个想法,并接触更多的读者。所以,我现在在这里。

说够了,让我们编码吧!

在我让这个刮刀开始工作后,我每天回答的问题数量激增,现在你已经知道了这个刮刀背后的历史,让我向你展示我是如何让它发生的。

首先,代码是使用谷歌 Chrome 来废弃和 Gmail 来发送电子邮件。当然,你可以使用其他人,但这取决于你。

我们将从导入我们将使用的库开始。你可能已经熟悉了熊猫时间睡眠功能。除此之外,我们将使用 smtplib 发送电子邮件和 selenium 这是一个非常强大的工具来废弃网站。如果你喜欢网络抓取,selenium 是必须的。
此外,你需要下载Chrome web driver(如果你使用 Chrome 的话),并把它放在你的脚本所在的目录下。

现在,我们将编写 send_email 函数来发送电子邮件。这个函数非常简单,即使你从未使用过 smtplib。
我们将使用 tryexcept 子句,这样当脚本无法连接到 Gmail 服务器时就不会出现错误。

现在,我们去刮痧吧。我们将使用一个无限循环来保持代码一直运行,在代码结束时,我们将使用 sleep 来设置我们希望 scraper 在每次检查新帖子之间等待的时间。从现在开始,一切都在里面,而里面。

因此,首先我们设置 selenium 并实例化驱动程序对象。然后我们告诉驱动获取网站。如果你将 option.headless 设置为 False 你就可以实际看到你的浏览器打开并进入网站废弃数据,这真的很有趣。

现在我们在社区中,这是我们感兴趣的网站部分。如果你懂 HTML,你就会知道这是一个表格。如果你没有,你不需要担心:

社区的问答部分

我们将使用 pd.read_htm l 来读取驱动的页面源。这将返回一个列表,以数据帧的形式显示网站上的所有表格。由于我们抓取的页面只有一个表(我们想要的表),我们将把列表的第一个(也是唯一的)元素赋给我们的 table 变量:

这是:

虽然你在这里看不到它,但它有你在之前的图像中可以看到的所有列。另外,请注意,第一个主题似乎是我们不感兴趣的固定主题,因为我们正在寻找新的主题。然后,我们将使用切片来选择前十个主题,不选择固定的主题,只选择主题回复活动列。

我们还需要将 activity 列分成两列,第一列只包含数字,另一列包含表示时间单位(小时或分钟)的字母:

现在我们有了这个:

我将一个新主题定义为 scraper 运行前不到 10 分钟创建的没有回复的主题。因此,我们将创建new _ topics**data frame,只选择满足这些要求的行。然后,我们将使用形状方法将新主题的数量分配给变量 num_new :

然后我们有:

工作基本上完成了。我们将使用一个 if 语句来检查新帖子的数量是否大于零,如果是,我们将设置主题、消息并调用 send_email 函数。如果它不大于零,它将只打印“没有找到新主题。”。

主题包含新帖子的数量,消息正文包含new _ topics*data frame 以便我们可以看到新主题的标题。该消息还包含 url,因此我们只需点击即可直接进入社区。

之后,我们将使用 sleep 让我们的代码在再次检查网站之前等待。我把它设置为十分钟,我认为这是一个公平的时间量。*

最后,要从您的 Gmail 帐户发送电子邮件,您必须允许在您的帐户中使用不太安全的应用程序。我没有为此提供链接,只是谷歌"不太安全的应用程序谷歌",你会看到如何做。

仅此而已。你可以随意使用这段代码,它是完全免费的。完整的代码可以在 GitHub 库中找到。

我希望你喜欢这一点,它可以在某种程度上有用。正如我所说的,我只是想帮助或者激励人们,并且认为我至少完成了其中的一项。

如果你有问题,有建议,或者只是想保持联系,请随时通过 TwitterGitHub ,或者 Linkedin 联系。

人工智能将如何加速药物发现?

原文:https://towardsdatascience.com/how-will-ai-accelerate-drug-discovery-c6386ff0644f?source=collection_archive---------74-----------------------

(并导致新的、更便宜的药物和患者健康的改善)

药物研发的成本

众所周知,药物开发过程非常困难;一种药物从识别出分子到临床应用平均需要 10-15 年的时间,只有大约 3%的初始药物能够顺利通过。一种药物从开发到最后一关失败的成本通常超过 10 亿美元。

对于那些不熟悉药物开发途径的人,这里有一个有用的概述:

如图所示,药物可能在许多阶段失效。早失败比晚失败好得多,所以任何预测哪些药物会失败的能力都是有利的(正如我们将看到的..).不过这样做可能相当困难。

更糟糕的是,开发药物的成本在增加,而开发的成功率在降低(见 Eroom 定律)。制药公司在公众中的名声也不好,各种各样的法规限制不正当的行为(比如人为抬高价格)。总而言之,这为制药公司的发展创造了一个相当棘手的局面…

机器学*:隧道尽头的光?

那么,机器学*(ML)如何提供一条出路呢?在我看来,它从根本上归结于其卓越的模式识别能力,这种能力可以应用于多种方式。让我们按照时间顺序,从这个角度来看它的具体用法。

1.候选人识别和选择

考虑到测试一个分子需要投入大量的时间和成本,花大力气鉴别和选择分子是有意义的。传统上,相当经验性的方法更受青睐,如一系列的溶解度、蛋白结合强度、细胞毒性、分子稳定性等测试。已经尝试采取更“第一原理”的方法,基于我们当前对疾病的理解来识别潜在的分子。虽然很吸引人,但这样做很困难,部分原因是生物系统的复杂性。refoxcib 就是这种的一个例子。

通过模式识别,ML 提供了识别候选人的新方法。逻辑是这样的:候选项越多,其中包含好候选项的概率就越大。一种新颖的方法是使用 GANs ,它训练一个网络来生成与现有分子相似的潜在分子。最*的一个成功案例是去年发表在《自然》杂志上的

另一种方法是使用“知识图”,它将靶标、抑制剂和疾病之间的关系表示为相互连接的节点。基本原理是,通过研究已知的关系,我们可以识别新的关系。例如,如果已知分子 1 抑制信号蛋白 x、y 和 z,并且对疾病 A 有效,并且已知分子 2 也抑制 x、y 和 z(但是到目前为止仅用于治疗疾病 B),那么分子 2 可能也对疾病 A 有效。这是一个过于简单的例子,但是 ML 可以使这种逻辑在规模上得以遵循。Benevolent.ai 已经描述了他们如何使用这种方法来识别目标。

按照咒语 快速失败 的说法,尽早识别将失败的分子是值得的。ML 可以通过与已知的相互作用进行比较来预测不期望的相互作用。

2.优化临床试验

ML 还可以从几个方面提高临床试验的成功率。一种方法是通过识别(通过模式识别)更有可能对药物产生成功反应的亚群。这增加了试验的成功率,从而增加了药物进入市场的可能性。虽然许可证可能更具体,但可以通过后续试验进行扩展。

对于所有这些方法,值得注意的是,机器学*的结合并不能保证新分子的成功开发。药物和生物学是一个非常混乱的行业,我们离完全模拟这些系统还有很长的路要走。然而,这些技术确实提供了增加的可能性和缩短的时间尺度,当在大量试验中扩大规模时,可以产生非常大的影响。

药物发现的新时代?

鉴于采用这种方法的新潜力,现有的制药公司正在将 ML 纳入他们的管道,许多以基于 ML 的发现为中心的新公司已经涌现。这似乎是一个拥挤的空间,正如这些 43 家制药公司和 221 家 T2 初创企业的名单所显示的。然而,我认为这反映了问题的范围,以及从解决方案中获得的经济回报。

那么,到目前为止,我们看到了多少成功呢?我知道有四种新药已经通过了研发+/-临床前阶段,它们明确使用了 ML 技术。这些是;一种来自深度学*药物再利用的抗生素,一种强迫症药物和一种抗纤维化药物,这两种药物都是使用 GANs 鉴定的,还有一种来自多伦多初创企业 Deep Genomics 的威尔逊氏病的靶标

据我所知,还没有一个完全通过管道,这可能反映了技术发展的新*性。

看看事情如何发展会很有趣。我认为将 ML 纳入药物发现标志着一个转折点。大玩家需要适应(我知道他们是这样),与更小、更敏捷的初创企业合作的空间很大。我们将会看到新公司从老巨头那里夺取了多少市场份额。

在过去,药物发现往往是为了找到下一个“重磅炸弹药物”,它提供了指数级的投资回报,从而弥补了所有的失败。我希望 ML 能够改变这种情况,并使药物开发更加平衡。

考虑到健康的根本重要性,以及大量未经治疗的疾病,应该有足够的馅饼可供分配。时间会告诉我们该地区 221 家(还在增加)初创企业的表现。我怀疑其中的失败是不可避免的,最终可能归结于投资者的支持或早期的胜利;后者是由运气和技巧共同决定的。

即使有加速的承诺,药物发现仍然是一个相对长期的游戏,药物有多年的开发和生命周期。所以我们可能要等一段时间,看看到底会发生什么。

无论哪家公司赢了还是输了,我相信患者都可能从更好的药物供应和更低的相关价格中受益。这让我很乐观:)

你怎么看?如果你对这个问题有什么想法,我很想听听。

更新:写完这篇文章后,我和一位在大型人工智能药物研发公司工作的朋友进行了一次讨论,他解释说,许多初创公司的商业模式是向更成熟的制药公司提供候选药物,这些公司将进一步发展。这样,事情就平衡了;较小的初创公司不承担进行昂贵试验的财务责任,较大的公司可以接收更多使用人工智能进行智能筛选的候选药物。

链接

在准备本文时,我遇到的最有用的资源是:

英超将如何收场?

原文:https://towardsdatascience.com/how-will-the-premier-league-end-6f262e76e6c6?source=collection_archive---------62-----------------------

用 XGBoost 预测并完成英超积分榜。

Ajay Meganathan 在 Unsplash 上拍摄的照片

英超联赛,连同几乎足球世界的其他部分,都暂停了。目前还不清楚联赛是否会继续。但如果继续下去,会如何收场?在这篇文章中,我将创建一个模型,预测英超联赛的结果,以完成联赛表。利物浦会赢得联赛冠军吗?曼联会晋级欧冠吗?还有哪些队伍会被拒绝?这些是将在本文结尾回答的一些问题。

资料组

为了创建一个有用的数据集,我们需要大量的匹配统计数据。对我们来说幸运的是,【http://www.football-data.co.uk/】是一个提供从 2005 年到今天每一场英超比赛统计数据的网站。在这里,我下载了每个季节的数据,并将其合并成一个数据集。

import pandas as pd# Dataset df = pd.read_csv('pl_data.csv')df.info()

<class 'pandas.core.frame.DataFrame'>
RangeIndex: **5592** entries, 0 to 5591
Columns: **144** entries, Div to SBA
dtypes: datetime64[ns](1), float64(131), int64(1), object(11)
memory usage: 6.1+ MB

该数据集包含 5592 个观察值和 144 个变量。但是,我们不会在最终模型中使用任何变量。相反,这些变量将用于创建新的变量,如“主队的平均进球”。事实上,该模型将主要依赖于平均变量。由于目标是预测剩下的比赛,变量如‘Form将依赖于早期的预测。为了更清楚地说明这一点,假设我们有变量' Form ' (衡量主队或客场队在最*五场比赛中的得分),我们希望预测本赛季的最后一场比赛。那么变量将只取决于早期预测的结果。这可能会扭曲预测,从而扭曲最终的排名。但是,在创建常规投注模型时,变量如“Form是至关重要的,应该添加。

完整的数据集最终有八个变量,分为主场或客场球队和赛季或总平均水平。这使得变量总数为 822 = 32。这些是变量:

  • 平均进球数。
  • 平均射门次数。
  • 平均出手次数。
  • 平均角数。
  • 平均犯规次数。
  • 平均黄牌数。
  • 红牌的平均数量。
  • 半场平均进球数。

当然,再增加几个变量也无妨。但是现在这样就可以了。下面是为主队和客场队创建总平均变量的代码(在计算“赛季平均”变量时使用类似的方法)。

# Create the columns # 
df['avg_g_hmt'] = df['gameId']
df['avg_g_awt'] = df['gameId']
df['avg_s_hmt'] = df['gameId']
df['avg_s_awt'] = df['gameId']
df['avg_sot_hmt'] = df['gameId']
df['avg_sot_awt'] = df['gameId']
df['avg_c_hmt'] = df['gameId']
df['avg_c_awt'] = df['gameId']
df['avg_f_hmt'] = df['gameId']
df['avg_f_awt'] = df['gameId']
df['avg_yc_hmt'] = df['gameId']
df['avg_yc_awt'] = df['gameId']
df['avg_rc_hmt'] = df['gameId']
df['avg_rc_awt'] = df['gameId']
df['avg_htg_hmt'] = df['gameId']
df['avg_htg_awt'] = df['gameId']gameid_col = df.columns.get_loc('gameId')
HomeTeam_col = df.columns.get_loc('HomeTeam')
FTHG_col = df.columns.get_loc('FTHG')
FTAG_col = df.columns.get_loc('FTAG')
HS_col = df.columns.get_loc('HS')
AS_col = df.columns.get_loc('AS')
HST_col = df.columns.get_loc('HST')
AST_col = df.columns.get_loc('AST')
HF_col = df.columns.get_loc('HF')
AF_col = df.columns.get_loc('AF')
HC_col = df.columns.get_loc('HC')
AC_col = df.columns.get_loc('AC')
HY_col = df.columns.get_loc('HY')
AY_col = df.columns.get_loc('AY')
HR_col = df.columns.get_loc('HR')
AR_col = df.columns.get_loc('AR')
HTHG_col = df.columns.get_loc('HTHG')
HTAG_col = df.columns.get_loc('HTAG')

# Iterate over all teams # 
df = df.sort_values(by = ['Date'])
mylist = list(set(df['HomeTeam']))
count = 0
for i in mylist:
    count = count + 1 
    print(count,": Creating variables for", i)
    homegamesindex = df['HomeTeam'] == i
    awaygamesindex = df['AwayTeam'] == i
    df_1 = df[homegamesindex]
    df_2 = df[awaygamesindex]
    df_3 = pd.concat((df_1,df_2))
    df_3 = df_3.sort_values(by = ['Date'])
    for j in range(len(df_3)):
        gameid = df_3.iloc[j,gameid_col]
        if df_3.iloc[j,HomeTeam_col] == i:
            H_or_A = "H"
        else:
            H_or_A = "A"
        y = j - 1
        # Create the count-variables # 
        avg_g = 0 
        avg_s = 0
        avg_sot = 0
        avg_c = 0
        avg_f = 0
        avg_yc = 0
        avg_rc = 0
        avg_htg = 0
        while y > -1:
        # Home or away in earlier games # 
            if df_3.iloc[y,HomeTeam_col] == i:
                avg_g = avg_g + df_3.iloc[y,FTHG_col]
                avg_s = avg_s + df_3.iloc[y,HS_col]
                avg_sot = avg_sot + df_3.iloc[y,HST_col]
                avg_c = avg_c + df_3.iloc[y,HC_col]
                avg_f = avg_f + df_3.iloc[y,HF_col]
                avg_yc = avg_yc + df_3.iloc[y,HY_col]
                avg_rc = avg_rc + df_3.iloc[y,HR_col]
                avg_htg = avg_htg + df_3.iloc[y,HTHG_col]
            else:
                avg_g = avg_g + df_3.iloc[y,FTAG_col]
                avg_s = avg_s + df_3.iloc[y,AS_col]
                avg_sot = avg_sot + df_3.iloc[y,AST_col]
                avg_c = avg_c + df_3.iloc[y,AC_col]
                avg_f = avg_f + df_3.iloc[y,AF_col]
                avg_yc = avg_yc + df_3.iloc[y,AY_col]
                avg_rc = avg_rc + df_3.iloc[y,AR_col]
                avg_htg = avg_htg + df_3.iloc[y,HTAG_col]

            y = y - 1
       # If the team plays home or away #
       if H_or_A == "H": 
           df['avg_g_hmt'].loc[df['gameId'] == gameid] = avg_g/(j+1)
           df['avg_s_hmt'].loc[df['gameId'] == gameid] = avg_s/(j+1)
           df['avg_sot_hmt'].loc[df['gameId']==gameid]=avg_sot/(j+1)
           df['avg_c_hmt'].loc[df['gameId'] == gameid] = avg_c/(j+1)
           df['avg_f_hmt'].loc[df['gameId'] == gameid] = avg_f/(j+1)
           df['avg_yc_hmt'].loc[df['gameId'] ==gameid]= avg_yc/(j+1)
           df['avg_rc_hmt'].loc[df['gameId'] ==gameid]= avg_rc/(j+1)
           df['avg_htg_hmt'].loc[df['gameId']==gameid]=avg_htg/(j+1)
       else:
           df['avg_g_awt'].loc[df['gameId'] == gameid] =avg_g/(j+1)
           df['avg_s_awt'].loc[df['gameId'] == gameid] =avg_s/(j+1)
           df['avg_sot_awt'].loc[df['gameId']==gameid]=avg_sot/(j+1)
           df['avg_c_awt'].loc[df['gameId'] == gameid] =avg_c/(j+1)
           df['avg_f_awt'].loc[df['gameId'] == gameid] =avg_f/(j+1)
           df['avg_yc_awt'].loc[df['gameId'] ==gameid]=avg_yc/(j+1)
           df['avg_rc_awt'].loc[df['gameId'] ==gameid]=avg_rc/(j+1)
           df['avg_htg_awt'].loc[df['gameId']==gameid]=avg_htg/(j+1)

既然数据集已经完成,让我们来探索它吧!首先,它不应该包含任何 NA:s

all(data.isna() == False)Out[36]: True

完美!现在数据集被分为训练数据集和测试数据集。但是首先,第一轮比赛的所有比赛都被删除了,因为所有的平均变量都为零。此后,为“主场目标”和“客场目标”分别创建一个 XGBoost 模型。这将使我们能够预测即将到来的比赛的结果。在 XGBoost 中,可以绘制变量的重要性,下面是“家庭目标”模型的图。

**from** xgboost **import** plot_importance**plot_importance(**home_mod**)**

正如预期的那样,有几个变量贡献很大,有几个贡献不太大。“客场球队的平均角球数”和“客场球队的平均黄牌数”似乎是最不重要的。而“主队的平均角球”和“主队的赛季平均进球”似乎是最重要的。这完全有意义,因为我们希望预测主队的进球。客队会有多少角球并不会显著改变得分的概率。然而,所有的变量仍将存在于最终的模型中,因为这不会有太大的计算量。

利物浦会赢得联赛冠军吗?

由于利物浦已经领先 25 分,而且只剩下 9 场比赛,他们只需要再赢两场比赛就可以举起奖杯。这是模型如何预测利物浦即将到来的比赛。

预测:利物浦最后一场比赛

轻松点。利物浦在最*的 9 场比赛中以 7 胜 1 平 1 负的成绩轻松夺冠。利物浦不仅是赢家,他们是风格上的赢家。他们以 104 分打破了目前 98 分的积分纪录(曼城,2018/19)。这将是他们 30 年来的第一个 PL 冠军(89/90 赛季)!

那么,其他队表现如何?预测完剩下的比赛,积分榜就这样结束了。

2019/2020 赛季英超联赛预测表

冠军联赛的门票将流向利物浦、曼城(但是他们被禁赛了,所以谁知道呢)、切尔西、曼联,也许还有莱斯特,因为曼城被禁赛了。“前六名”中的另外两支球队,阿森纳和托特纳姆,分别排在第六和第七位。不幸的是,预测下赛季参加锦标赛的球队是布莱顿、阿斯顿维拉和诺维奇。

这种模式似乎有利于大型团队。例如,莱斯特现在在积分榜上排名第三,曼联排名第六,但该模型预测曼联最终会超过莱斯特。类似的事情也发生在布莱顿,它排在第 15 位,但预计会降级。我的假设是,该模型有利于大球队,因为大多数变量取决于球队在许多赛季前的表现。当然,大球队将从中受益。毕竟,他们被认为是大牌,因为他们在过去几个赛季表现出色。如果有人试图自己做这件事,这是一个可以改进的领域。

你有它!利物浦赢了,切尔西下赛季打冠军联赛,诺维奇只拿到 21 分。也就是说,如果我的模型 100%正确。没有模特是这样的。

乔治·特罗瓦托在 Unsplash 上的照片

posted @ 2024-10-15 13:41  绝不原创的飞龙  阅读(311)  评论(0)    收藏  举报