TowardsDataScience-博客中文翻译-2019-四十一-

news/2024/10/14 11:51:42

TowardsDataScience 博客中文翻译 2019(四十一)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

机器学习中的核心秘密。一

原文:https://towardsdatascience.com/kernel-secrets-in-machine-learning-2aab4c8a295f?source=collection_archive---------5-----------------------

这个帖子不是关于深度学习的。但也可能是无妨的。这就是内核的力量。它们普遍适用于任何机器学习算法。为什么你会问?我将在这篇文章中尝试回答这个问题。

一般在机器学习中,我们要把相似的东西放在相似的地方。这条规则适用于所有的机器学习,无论是监督的、非监督的、分类的还是回归的。问题是,我们如何确切地确定什么是相似的?为了阐明这个问题,我们将从学习内核的基本基础开始,点积。

两个向量之间的点积是一件神奇的事情。我们可以肯定地说,它在某种意义上衡量了相似性。通常,在机器学习文献中,点积表示如下:

表示向量 x 和 x’之间的点积。注意,为了简洁起见,我省略了向量符号的箭头。这个符号是矢量分量乘积之和的简写:

巧合的是,向量的范数是与其自身的点积的*方根,表示为:

这当然不是全部。我们还知道余弦法则,即点积等于向量之间夹角的余弦乘以它们的范数(这很容易通过简单的三角学来证明):

谈论角度和范数的好处是,我们现在可以想象这个点积是什么意思。让我们画出这两个向量,它们之间的夹角为α:

所以如果我们用点积来衡量相似性。什么时候会达到最大值?意味着向量是最相似的。显然,当余弦等于 1 时,会发生这种情况,当角度为 0 度或弧度时会发生这种情况。如果向量各自的范数相同,那么显然我们说的是同一个向量!还不错。让我们把到目前为止学到的东西刻在石头上:

点积是向量之间相似性的度量。

现在你有希望理解为什么讨论点积是有用的了。

当然,点积作为相似性的度量,在问题中可能有用,也可能完全无用,这取决于您要解决的问题。因此,我们需要对输入空间进行某种变换,使点积作为相似性的度量变得实际有用。我们用ϕ.来表示这种转变现在,我们可以定义一个核的含义,映射空间中的点积:

因此,核的定义非常直接,它是映射空间中相似性的一种度量。事实是,数学家喜欢具体化。对于它们所处理的底层函数和空间,不应该有隐含的假设,因此函数分析的内核背后有相当多的理论,这需要另一篇或几篇文章来讨论。简而言之,我们需要明确说明我们希望ϕ:发挥什么样的作用

我们想要一个函数,它从定义域 X 映射到一个点积定义明确的空间,这意味着它是一个很好的相似性度量。

内核可以作为任何可以用点积(或范数)来定义的算法的一般化。使用核作为其主干的算法的最著名的例子是支持向量机和高斯过程,但是也有核用于神经网络的例子。

Photo by Annie Spratt on Unsplash

我们需要内核和映射函数ϕ的另一个原因是输入空间可能没有明确定义的点积。让我们简短地研究一下文档分析的例子,我们只是想根据主题得出两个文档之间的相似性,然后对它们进行聚类。在这种情况下,这两个文档之间的点积到底是多少?一种选择是获取文档字符的 ASCII 码,并将它们连接成一个巨大的向量——当然,这不是你在实践中会做的事情,但这是相当值得思考的。很高兴我们现在把文档定义为向量。但是问题仍然在于长度,即不同的文件有不同的长度。但是没什么大不了的,我们可以通过用 EOS 字符将较短的文档填充到一定的长度来解决这个问题。然后我们可以在这个高维空间里计算一个点积。但是,还有一个问题,这个点积的相关性,或者说,这个点积实际上意味着什么。显然,字符的微小变化都会改变点积。即使我们把一个词和它的同义词交换,它也会改变点积。这是您在按主题比较两个文档时想要避免的事情。

那么内核是如何发挥作用的呢?理想情况下,您会希望找到一个映射函数ϕ,该函数将您的输入空间映射到点积具有您想要的含义的特征空间。在文档比较的情况下,对于语义相似的文档,点积较高。换句话说,这种映射应该使分类器的工作更容易,因为数据变得更容易分离。

我们现在可以看看典型的 XOR 例子来理解这个概念。XOR 函数是一个二元函数,看起来像这样:

蓝色点被分类为 0,红色点被分类为 1。我们可以假设这是一个噪声异或,因为集群有一个大的传播。我们马上注意到一件事,数据不是线性可分的。也就是说,我们不能在红点和蓝点之间划一条线,将它们分开。

在这种情况下我们能做什么?我们可以应用一个特定的映射函数,使我们的工作容易得多。具体来说,让我们构造一个映射函数,该函数将对穿过红点簇的线周围的输入空间进行单侧反射。我们将围绕这条线来反映这条线下面的所有点。我们的映射函数会有以下结果:

映射后,我们的数据变得很好地线性分离,所以如果我们有一个模型试图适应一个分离的超*面(例如感知器),这是一个理想的情况。显然,线性可分性是一件非常好的事情。但是为了建立有效的模型,我们不一定需要线性可分性,这意味着为了建立有效的模型,不是所有的映射函数都需要导致线性可分的数据。

人们经常混淆应用内核和应用映射函数的概念。核函数的输出是一个标量,是两点的相似性或不相似性的度量。映射函数的输出是一个向量,我们基于它来计算相似性。关于内核有趣的事情是,我们有时可以计算原始空间中映射的点积,而不需要显式地映射输入。这允许我们处理无限维映射!这是一件很难理解的事情,所以我将在以后的文章中讨论。

作为结束语,我想推荐 Smola 和 Schoelkopf 的书:用内核学习。这本书对核心机器及其理论背景进行了全面的论述。除此之外,请继续关注内核!

Photo by Eric Nopanen on Unsplash

直接相关的文章/推荐阅读:

  1. 关于维度的诅咒
  2. 机器学习中的内核秘密 Pt。2

机器学习中的核心秘密。2

原文:https://towardsdatascience.com/kernel-secrets-in-machine-learning-pt-2-16266c3ac37c?source=collection_archive---------21-----------------------

想使用内核吗?让我们通过几个众所周知的内核来感受一下吧!

在关于这个主题的第一篇文章机器学习中的内核秘密中,我以最基本的方式解释了内核。在继续阅读之前,我建议你快速浏览一下这篇文章,如果你还不知道内核是什么的话。希望你会得出这个结论:

核是映射空间中两个向量之间的相似性度量。

很好。现在我们可以检查和讨论一些众所周知的内核,以及我们如何组合内核来产生其他内核。请记住,对于我们将要使用的示例,x 是用于绘图目的的一维向量,我们将 x '的值固定为 2。事不宜迟,让我们开始 kerneling。

线性核

这个核的超参数是 sigma 和 offset 参数 c,直观来看,这个核是什么意思?如果我们取一个特定的 x,和其他所有的 x 比较,我们会得到一条直线。这就是为什么它被称为线性核。固定 x 和改变 x '实际上意味着我们沿着这条线移动。

这个内核的另一个特点是它是不稳定的。这意味着它的值相对于 x 的绝对位置而非相对位置变化。这个内核的另一个好处是,由于它是线性的,所以在优化中计算起来非常有效。

多项式核

顾名思义,这个内核是一个偏移量为 c 的多项式函数。我认为值得花一点时间来考虑一下导致这个内核的映射函数ϕ,因为如果你记得内核是映射空间中的一个相似性函数(点积),那么它返回一个标量!二维空间中 2 次多项式核的映射函数如下所示:

当增加输入维数 d 和多项式的次数时,我们映射到的结果特征空间变得相当大。好的一面是,我们可以计算点积,而不需要进行转换,就像上面的公式中指定的那样。这是内核理论中许多美丽的公式之一。

径向基函数核

这是一个非常著名并且经常使用的内核。请注意,由于指数中的负指数,指数值的范围是从 0 到 1,这是一个很好的特性,因为我们可以说 1 表示非常相似,或者相同,接* 0 表示完全不同。指数中的σ参数控制内核的灵敏度。对于低σ值,我们预计只有非常接*的点才会相似。对于更大的σ,我们放宽了相似性标准,因为稍微远一点的点会更相似。

但是当然,内核看起来是这样的,因为我们把 X 固定为 0,改变了 X ',逻辑上足够我们想要计算点之间在整个 X 域中的相似性。这暗示了一个*面,实际上,这个*面就是内核的一个例子:

不够令人印象深刻的是,内核的值在对角线上最高,这里 x 和 x '是相同的。

周期核

当你想到周期性时,你会不由自主地想到正弦和余弦这样的周期函数。逻辑上,周期核有正弦函数在里面。核的超参数再次是σ,其指定相似性的灵敏度,但是另外,我们有参数 p,其指定正弦函数的周期。这应该完全说得通。此外,请注意径向基核和周期核之间的相似性,两者都被限制为输出 0 和 1 之间的值。

什么时候需要使用周期性内核?这是很符合逻辑的,比如说你想建立一个正弦函数的模型。仅仅从这个函数中取两个距离欧几里德距离较远的点,并不意味着函数值有意义的不同。为了解决这类问题,你需要周期内核。为了完整起见,看看当我们调整周期内核的周期性时会发生什么(没有什么意外):

局部周期核

我们基本上只是通过取径向基核,并将其与周期核相乘来得到这个核。我们由此实现的是,所得到的核还随着 x 和 x’之间的距离而改变其值,而不仅仅是随着距离的周期性而改变。这导致了所谓的局部周期性。

只是因为我很好奇,让我们用 3D 绘制这个内核,并得到下面这个漂亮时髦的形状:

看起来相当酷!

构建新内核

现在我们已经看到了一些内核的例子。问题来了,我们需要什么来构造新的内核?内核有两个很好的特性:

  1. 添加带有内核的内核会产生一个新的内核。
  2. 内核相乘产生一个新的内核

这些允许你基本上不需要做太多的数学运算就能构建出非*凡的内核,这真的很直观。乘法也许可以看作是一种 and 运算,特别是当考虑 0 和 1 之间的核时。因此,我们可以通过将周期核与径向基函数核相结合来得到局部周期核。

这些是让您开始您的内核冒险的几个例子。当然,这仅仅触及了所有有趣内核的表面。为某个问题量身定制内核设计是一项重要的任务。精通它需要一定的经验。此外,机器学习中有一整个领域致力于学习内核函数。

由于算法要求,内核设计也可能很棘手。由于许多基于核的算法涉及到所谓的逆矩阵,我们要求我们的核是正定的,但这是我将在未来讨论的内容。

现在我们知道了一些有用的内核,我们可以更深入地研究希尔伯特空间的理论以及它们与内核的关系,但是这要等到下一篇文章。在此之前,如果你在阅读本文时遇到困难,这里有一些推荐读物:

  1. 机器学习中的内核秘密 Pt。1
  2. 关于维度的诅咒
  3. 用内核学习

干得好!

数据科学工厂的关键组成部分:模型开发

原文:https://towardsdatascience.com/key-components-of-a-data-science-factory-model-development-1113b54f6505?source=collection_archive---------26-----------------------

看看模型开发过程,企业可用的新兴替代方案,以及人工智能行业的未来。

Image source

人工智能(AI)领域继续快速扩张。根据 Statista 的数据,到 2025 年,企业人工智能应用的全球收入预计将达到 312 亿美元。从 2018 年开始的预测期内,这一趋势将实现 52.59%的复合年增长率(CAGR)。

对于业内人士来说,这种强劲的扩张将继续推动创新。随着现有工作流的发展,许多企业开始利用人工智能的力量。从图像识别到使用算法和机器学习来防范安全威胁,企业用例正显示出持续的多样化。

企业现在正在建立机器学习模型,这些模型有可能彻底改变他们的业务。然而,在缺乏必要的工具和专业知识的情况下,许多这种模式无法产生真正的回报。因此,许多公司转向简化模型开发、减少摩擦和改善结果的解决方案。

在这篇文章中,我们将探索模型开发过程,企业可用的新兴替代方案,以及人工智能行业的未来。

人工智能模型开发过程

建立一个人工智能模型的过程是复杂而艰巨的。因此,许多企业在开发和实施人工智能解决方案时都在努力保持势头。但是这个过程到底意味着什么呢?让我们仔细看看人工智能模型开发过程的每个组成部分。

问题定义

与任何商业努力一样,从一开始就确定必须解决的问题是至关重要的。业务目标必须足够具体,以指导模型开发过程;像“降低成本”这样的一般目标不会产生最佳结果。对于公司来说,量化他们希望实现的改进量也是至关重要的,这为有意义的 ROI 评估奠定了基础。

数据采集

获取正确数量和质量的数据对任何人工智能模型的成功都至关重要。这里偷工减料会大大降低输出的准确性。该过程的这一步骤产生了训练模型所必需的数据表示。

数据准备

因为算法不够智能,无法从原始数据中提取有意义的见解,所以必须首先使用各种方法进行准备。这些方法从预处理后的原始数据中获得有意义的见解。

特征工程

特征工程是构建任何人工智能系统的重要组成部分。特征是数据中影响模型的参数。识别这些特征的过程被称为特征工程,这非常耗时。据福布斯报道,数据科学家 80%的时间都花在建模前的数据准备阶段。

模型开发

创建模型的第一步包括选择合适的算法。这些算法依赖于准备好的数据来创建和训练模型。数据科学家可以访问数百种机器学习算法,并且每天都有新的算法出现。在生产一个功能性的商业工具时,正确的算法和机器学习问题必须是一致的。

模型验证

模型完成后,公司必须审查结果。这个过程可能涉及评估变更的影响、评估风险和做出部署决策。在模型开发的详尽开发和实验阶段之后,公司必须确保他们保持对原始业务目标的关注。

多模式开发

使用正确的工具来构建人工智能模型取决于正在解决的问题,以及致力于解决该问题的人员的技能。幸运的是,今天的市场为企业提供了几种选择。我们可以将这些选项细分为提供独特功能的精选类别。

基于代码的模型开发

基于代码的模型开发是指在笔记本或 ide 中使用 R、Python、Spark、TensorFlow 等编码语言构建智能模型的那些*台。这些解决方案非常适合拥有丰富开源开发经验的精通技术的团队。

低代码 GUI 模型开发

就目前情况而言,人工智能算法存在于复杂代码层之下。然而,随着用于数据准备、特征工程、模型开发和验证的图形用户界面(GUI)的出现,这种动态正在改变。这些视觉环境使得构建机器学习模型变得更加容易。

因为更广泛的用户可以使用它们,它们促进了人工智能的民主化,也有助于确保该技术得到负责任和合乎道德的使用。

AutoML 解决方案

像谷歌和亚马逊这样的行业巨头可以访问全栈人工智能团队,但大多数公司都没有——这就是 AutoML 的用武之地。AutoML 是指能够实现机器学习过程自动化的技术和工具。例如,AutoML 可以自动化数据收集和清理、模型开发和测试,或者生产部署和扩展。

因为生产成功的企业级人工智能模型仍然具有巨大的抑制性,随着专业技能的短缺持续存在,AutoML 继续获得牵引力。然而,重要的是要注意,虽然 AutoML 可以使模型生产和验证更容易,但它也有局限性。

人工智能建模的演变

虽然开发人工智能模型仍然是一个密集的过程,但像 Quickpath 这样的公司正在努力简化这种体验。通过使用 GUI 和 AutoML *台,企业可以更好地部署资源,以实现可行的项目成果,并在更广泛的混合技能群体中提高生产力。

尽管这一运动还处于早期阶段,但市场混乱已经开始。随着生态系统的不断发展,人工智能的民主化似乎将继续。随着可访问性进一步推动增长,人工智能产业和由此产生的模型显示出巨大的潜力。

人工智能和机器学习的主要区别

原文:https://towardsdatascience.com/key-differences-between-artificial-intelligence-and-machine-learning-fe637cd0deca?source=collection_archive---------5-----------------------

人工智能和机器学习是市场上最流行的两个术语,很多时候可以互换使用。它们已经成为日常生活的一部分,但这并不意味着我们很好地理解它们。在什么是机器学习和什么是人工智能之间存在很多混淆。在大多数公司里;营销忽略了广告和销售的这种区别。

让我们在接下来的几个章节中来看看人工智能和机器学习之间的一些主要区别。

什么是机器学习

在机器学习中,算法通过经验获得知识或技能。机器学习依靠大数据集来提醒数据找到共同的模式。

例如,假设你向机器学习程序提供大量皮肤状况的图像,以及这些状况意味着什么。该算法可以挖掘这些图像数据,并在未来帮助分析皮肤状况。该算法检查图像并识别具有相似条件的这些图像之间存在的模式。

当该算法在未来被给予新的皮肤图像(其状况未知)时,它将当前图像中存在的模式与它通过分析所有过去的图片而学习到的模式进行比较,并且能够预测它是哪种皮肤状况。

如果有新的皮肤状况,或者如果皮肤状况的现有模式发生变化,该算法将不能正确预测这些状况。人们必须将所有新数据输入算法,让它学会根据新的皮肤状况进行预测。

同样,如果您向算法提供客户数据集,该数据集既有流失客户的样本,也有未流失客户的样本,它就可以挖掘这些数据,以了解流失客户和未流失客户的模式。如果给出了新的客户信息,它可以将所提供的客户信息中存在的模式与它之前学习的模式进行比较,并且可以预测该客户是否会流失。

如果客户行为有任何变化,该算法必须输入捕捉新客户行为的新数据,以便能够准确预测未来。

什么是人工智能

另一方面,人工智能通过获取知识和学习如何应用知识来学习。人工智能的目的是增加成功的机会,并找到最优解。人工智能是研究训练计算机去尝试做目前人类能做得更好的事情。人工智能倾向于在适应新场景很重要的情况下使用。

让我们来看一个简单的视频游戏,游戏的目标是使用自动导航汽车穿过雷区,从一边走到另一边。最初,汽车不知道避开地雷的最佳路径是什么。比方说,我们进行模拟运行,以获得关于哪条路径可行、哪条路径不可行的大量数据。这是可以提供给机器学习的数据,因此它可以从过去的驾驶经验中学习,并使用这些数据来安全地驾驶汽车。

让我们把问题复杂化。假设地雷的位置被移动了。机器学习算法将不再有效。机器学习不知道有地雷存在。它所知道的是从最初提供的数据中提取的路径中存在什么模式,并且这是它将继续引导的相同路径,除非提供新的数据供它学习。

另一方面,人工智能将对这些数据做的是分析这些路径为什么会改变,并编纂规则以识别那些(危险)点,以及如何通过留下可见的痕迹来避免它们。它学习知识并应用它们,就像大脑如何工作一样。当地雷被改变时,AI 将开始寻找那些危险点,并通过遵循新的路径慢慢开始避开它们,就像人类大脑如何学习和适应一样。

总结

总之,机器学习使用经验来寻找它所学习的模式。人工智能利用经验来获取知识/技能,以及如何将这些知识应用到新的环境中。

AI 和 ML 都可以有有价值的商业应用。但是在许多公司中,ML 已经被更多的采用来解决关键的商业问题。

数据驱动的关键要素

原文:https://towardsdatascience.com/key-ingredients-to-being-data-driven-f76ab8140bc?source=collection_archive---------17-----------------------

PSA: if you’re still showing data in pie charts, stop.

公司喜欢宣称“我们是数据驱动的”。成为一个数据驱动的组织有明显的好处,现在每个人都有比他们能处理的更多的数据。但是,一个组织究竟需要什么来“数据驱动”呢?

仅仅因为你有大量的数据,并且你已经雇人分析它或建立模型,那使你成为数据驱动的吗?不。这还不够。

虽然我们对数据以及如何使用数据想了很多。数据驱动需要成为管理层的优先事项,并成为组织文化的一部分;不仅仅是拥有一个具备必要能力的团队。

以下是我认为有效实现“数据驱动”所必需的基本素质。现在我在造词。

数据驱动:

  • 测试设计和分析由分析/数据科学团队负责。
  • 仪表板已经到位,使利益相关者能够自助访问关键指标。(否则,您将收到低价值的临时请求来获取这些指标,这将是一个时间浪费。)
  • 分析/数据科学团队与企业合作以了解问题并设计适当的方法。
  • 跨部门/组织的数据治理和数据定义的一致使用。
  • 你有一个数据策略。

你会注意到上面缺少花哨的炒作流行语。你不需要“利用人工智能”或将事实上是假设测试、商业逻辑或简单回归的东西称为人工智能。

我不相信花哨的模型需要考虑你自己的数据驱动。上面列出的许多要点涉及组织的态度,以及他们如何与分析和数据科学团队合作和协作。我和下一个数据科学家一样喜欢建立模型,但你不能在不存在的基础上建立下一级智能。

澄清一下,我并不是说组织中的每个决策都需要由数据来驱动。特别是,如果你要做出一个战略决策,而不考虑测试或分析的结果,那么你应该跳过这个测试。我强烈主张,如果你真的要用结果来做决定,就只把资源分配给一个项目。

让我们从上面的几点来看看。

测试设计和分析由分析/数据科学团队负责:

尽管数据科学和分析团队经常会提出一些奇妙的测试想法。还有许多想法来自一个不属于分析部门的部门。例如,在电子商务中,营销团队会有许多新的提议。网站团队可能想要测试对 UI 的更改。这有时会被传达给数据团队,就像“我们想以这种方式测试这个东西”。虽然这些非分析团队在市场营销和网站设计方面有很强的技巧,并且理解 A/B 测试的力量;他们通常不理解效应大小、样本大小、可靠测试设计等之间的不同权衡。

我在不止一家公司遇到过不止一次这种情况,他们告诉我“我们理解你的担忧,但无论如何我们都会按照自己的方式去做。”这是他们的要求,因为在这些情况下,这些部门在技术上“拥有”测试设计。然而,从这些测试中得到的数据通常不能被分析。所以虽然我们按照他们的方式做了,但是最后的结果并没有回答任何问题。时间被浪费了。

仪表板就位:

这是真正的基础步骤。如果您让分析师每月手动或临时提取相同的数字,会浪费很多时间。这些信息可以实现自动化,利益相关者可以浏览仪表板,这样您就不会收到诸如“按收购渠道统计,每月的流失情况如何?”它在仪表板中,利益相关者可以自己查看。节省下来的时间可以用来深入研究更有趣、更有启发性的问题,而不是提取简单的关键绩效指标。

分析/数据科学团队与企业合作定义问题:

这种关系需要努力,因为它是一种关系。高层领导需要明确表示,数据驱动的方法是实现这一目标的首要条件。此外,分析人员通常需要邀请他们自己参加原本没有被邀请的会议。分析需要提出正确的问题,并引导分析朝着正确的方向发展,才能赢得这个席位。没有关系是一夜之间建立起来的,但这对每个人来说都是双赢的。当您不确定企业试图解决什么问题时,没有什么比提取数据更令人沮丧的了。这是潘多拉魔盒。你拉他们要求的数据,它没有回答问题,所以业务要求你拉他们更多的数据。停下来。坐下来,讨论问题,让企业知道你是来帮忙的。

跨部门/组织的数据治理和数据定义的一致使用:

这一次可能需要对目前的计算方式进行彻底改革。渠道团队、产品团队、站点团队、其他团队,如果企业没有传达一个公认的定义,他们可能会以不同的方式计算事情。这些定义不一定是由分析本身决定的,它们是一致同意的。对于一个已经建立的企业来说,已经做了大量的发展,但是没有足够的治理,可能会感觉到试图说服每个人使用一致的定义的痛苦。但是如果两个人试图做同样的分析,得出不同的数字,你就有问题了。这也是一个基础,你需要这个基础才能前进,才能从事更酷的更高价值的项目,但是如果你把时间花在协调团队之间的数字上就不行了。

您有一个数据策略:

这种数据战略将由业务战略驱动。这个策略将会有目标并且是可衡量的。您计划的分析有很强的用例。人们不会凭空要求与业务的更大优先级不一致的分析。像“我们是优化我们的广告支出还是先解决我们的保留问题?”归结为业务的预期成本。当分析应该致力于解决将为企业节省最多资金的问题时,他们不会偏离正题来回答价值较低的问题。

总而言之:

我希望这篇文章对你有所帮助。数据驱动显然会帮助你更好地利用你的数据。然而,实现数据驱动需要将流程落实到位,并在管理层就谁拥有什么达成一致。这是值得的,但这不是一朝一夕的事。如果你还不是数据驱动型的,我祝你一路走好。你的分析师和数据科学家会感谢你的。

如果您对数据驱动还需要什么有建议,请告诉我您的想法!

原载于 2019 年 3 月 15 日【datamovesme.com】

Kubernetes 键盘命令

原文:https://towardsdatascience.com/key-kubernetes-commands-741fe61fde8?source=collection_archive---------8-----------------------

使用 K8s 启动并运行

Kubernetes 是部署和管理大型应用程序的首要技术。在本文中,我们将在您的本地机器上启动并运行 K8s。然后您将部署您的第一个应用程序。最后,您将看到需要了解的 K8s 命令。

如果你是 Kubernetes 的新手,可以看看我的上一篇文章来学习基本的 K8s 概念。

我们起航吧!⛵️

Lots of containers on a ship.

本地运行 K8s

直到最*, Minikube 还是创建本地单节点 Kubernetes 集群的主要手段。它可以在 Mac、Windows 和 Linux 上运行。Minikube 在一个虚拟环境中运行,带有许多不同虚拟环境的驱动程序。它还有一个扩展的 API。然而,当我将 Minikube 与 VirtualBox 配合使用时,我发现它速度很慢,而且漏洞百出。

如果你是在 Mac 或 Windows 机器上本地玩 K8s,我推荐你使用 Docker 桌面自带的 K8s 版本。它使用 HyperKit 作为它的虚拟环境。我发现这是一股新鲜空气。🌷

如果你在本地使用装有 K8s 的 Linux 机器,请查看一下 MicroK8s 。它是轻量级的,使用一个快照而不是虚拟环境。

本文我运行的是 Docker Desktop CE 的 K8s v1.13.0,2019 年 4 月 Edge 版本。

要在 Mac 上安装并启动 K8s,首先在这里下载带有 K8s 的 Docker Desktop。

安装完成后,进入你的应用程序并启动 Docker。从屏幕顶部的 Docker 图标中选择 Preferences 来安装并启动 K8s。

选择 Kubernetes 选项卡并勾选 Enable Kubernetes 复选框。

同意安装 Kubernetes。可能需要一两分钟才能启动。点击 Docker 下拉菜单,您应该会看到 Kubernetes 正在启动,最后 Kubernetes 正在运行

如果你看到两个绿色的圆圈,那么你就准备好了!如果没有看到两个绿圈,Google 和 Stack Overflow 是一个开发者最好的朋友。😄

你的第一个 K8s 应用

让我们做一个 hello world 部署,它将为 node.js 应用程序拉一个 Docker 映像。我们的应用程序将在浏览器中显示 Hello World 。在生产中,你会以不同的方式做事。这个练习是让你开始练习的第一步。👣

在 K8s 运行的情况下,在终端中输入以下命令:

kubectl create deployment hello-node --image=gcr.io/hello-minikube-zero-install/hello-node

我们使用kubectl API 来创建一个名为 hello-node 的部署,它使用存储在 Google 容器注册表中的 Docker 映像。我们正在使用官方 Kubernetes 的 Docker 容器。

以下是 Dockerfile 文件的内容:

FROM node:6.14.2
EXPOSE 8080
COPY server.js .
CMD node server.js

我们使用的是官方的 node.js 镜像,复制 server.js 的内容,公开端口 8080,用 node 运行 server.js 程序。关于 Docker 文件的更多信息,请点击这里查看我的文章。

下面是 server.js app 代码:

**var http = require('http');var handleRequest = function(request, response) {console.log('Received request for URL: ' + request.url);response.writeHead(200);response.end('Hello World!');
};
var www = http.createServer(handleRequest);
www.listen(8080);**

这段代码将创建一个监听端口 8080 的服务器。当服务器收到请求时,它会向控制台写入一条有用的消息,并返回“Hello World!”。

在运行了 kubectl create 命令之后,您应该会在终端中看到一条消息,说明您的部署已经创建好了。不过,你的应用还不能马上投入使用。K8s 需要提取 Docker 图像并旋转您的容器。

您可以通过kubectl get all查看所有 K8s 资源的状态。提取图像并旋转容器需要几分钟的时间,所以您可能需要输入这个命令几次。你可以到幕后高峰,看看 K8s 在用kubectl get events做什么。

当你看到 1 Pod 显示可用时,你就可以开始了。

为了使 Pod 能够被 K8s 集群之外的世界访问,您需要将 Pod 公开为服务。使用命令kubectl expose deployment hello-node --type=LoadBalancer --port=8080创建服务。

您指定了群集的名称、服务的类型以及它要使用的端口。不是所有的服务类型都创建一个可以从外界访问的 IP,但是负载*衡器可以。

您应该能够通过在 shell 中输入kubectl get services看到服务已经创建。

假设您正在本地运行 K8s,将您的浏览器导航到 http://localhost:8080/ ,您应该会看到消息“Hello World!”。👍

Hello World!

您可以在 YAML 文件中指定它们,而不是通过命令行创建和指定整个部署和服务。使用文件有几个优点,包括可重用性和文档化。我计划在以后的文章中深入讨论 YAML 规范文件,所以请关注 me 以确保您不会错过它们。

现在让我们来看看流行的 K8s 命令。

库贝特尔

Cubes

ku bectl——读作立方体控制、立方体切割——或其他多种方式——是 K8s 的命令行工具。它是这样工作的:

  • 一个 kubectl 命令执行一个动作,如 getcreatedescribe。
  • 该操作在资源上执行,如部署、状态集或服务。
  • kubectl 命令遵循以下格式:

kubectl an_action a_resource a_resource_name --flags

在许多情况下,名称和标志是可选的。

Flags

例如,要获得关于所有现有 pod 的信息,您可以运行这个常见命令:kubectl get pods

提示:如果您想避免键入 kubectl a bajilllion 次,那么创建一个 Bash 别名。有了alias k='kubectl',你可以只输入k而不是kubectl。我在本文中展示了如何在 Mac 上创建 Bash 别名。

事不宜迟,下面是最常见的 K8s 资源及其快捷方式。

11 大 kubectl 资源

你可以写出完整的术语或捷径。

pods, po nodes, no deployments, deploy replicasets, rs daemonsets, ds statefulsets, sts jobs cronjobs, cj services, svc persistentvolumes, pv persistentvolumeclaims, pvc

如果你对这些资源不清楚,可以看看我之前关于 K8s 概念的文章。另外两个需要了解的术语是所有事件

不出所料,all用来指代所有现有的资源。kubectl get all显示了有关运行 pod、服务、部署和复制集的基本信息。这个命令非常方便。😄

同样,kubectl get events显示事件的历史。就像是 K8s 级别的日志而不是容器级别的。

如果你想看更多的 kubectl 资源,请点击这里查看官方文档。现在,让我们看看应用于我们的资源的行动。

7 大 kubectl 行动

help —获取帮助
get —显示关于一个或多个资源的信息
describe —显示关于一个或多个资源的详细信息
logs —显示容器的日志
exec —进入容器中正在运行的进程
apply —创建或更改资源
delete —删除一个或多个资源

让我们简单地看一下每个命令。

求助

在命令后键入--help以获取该命令的帮助。比如kubectl get pods --help

得到

kubectl get all显示了有关运行 pod、服务、部署和副本集的基本信息。这是检查事物状态的常用命令。您可以对单个对象使用get并添加--watch标志来观察实时更新。

形容

kubectl describe all显示了与您的集群相关的几乎所有内容的大量详细信息。您也可以对单个对象使用describe。调试的时候很有帮助。

日志

logs需要一个 Pod 名称。我的“hello world”应用程序使用命令kubectl logs hello-node-7f5b6bd6b8-gr7m7显示了我的 Pod 的日志。当多个容器在一个容器中时,使用标志-c my-container指定一个容器。使用--previous标志获取不再运行的容器的信息。

Wish my logs looked like this.

执行

exec帮助你调试一个容器进程。它允许您通过一个带有-it的伪终端在容器内执行一个流程。例如,要在 my_pod 中输入容器并运行 Bash,输入kubectl exec -it my_pod bash

应用

apply与 YAML 或 JSON 文件一起使用是创建或更改资源的推荐方式。如果一个资源不存在,apply将创建它。如果它确实存在,apply会改变它。apply可以向适用的资源添加服务,或者通过添加 pod 来自动横向扩展部署。

注意,您可以使用create进行部署,使用expose进行服务——这就是我们在上面所做的。然而,使用带有apply的 YAML 文件对于文档和重用来说是一个更好的选择。我们将在以后的文章中介绍这种方法。在这里查看关于创建资源的最佳实践的讨论。

apply是您创建和更新资源的瑞士军刀。

SwissArmy knife

删除

kubectl delete pod my_pod删除名为 my_pod 的 Pod。

要删除相同类型的所有资源,请传递--all标志。例如,您可以用kubectl delete rs --all删除所有的副本集。请注意,如果您尝试这样做,除非您先删除部署,否则副本集将会重新启动。😄

现在您已经看到了关键的 K8s 命令。当你成为一名库伯内特 n̵i̵n̵j̵a̵和*战士,你会获得其他人。可以在这里找到 kubectl 动作的完整列表。

概述

要记住的命令。

带快捷方式的前 11 项资源

pods, po nodes, no deployments, deploy replicasets, rs daemonsets, ds statefulsets, sts jobs cronjobs, cj services, svc persistentvolumes, pv persistentvolumeclaims, pvc

前 7 项行动

--help —获取关于资源的帮助
get —显示关于一个或多个资源的信息。
describe —显示一个或多个资源的详细信息。
logs —显示容器的日志。
exec —进入容器中正在运行的进程。
apply —创建或更改资源。
delete —删除一个或多个资源。

如果你想更深入地了解清单,看看这张更长的备忘单。

当你探索 K8s 的时候,一定要花一些时间和官方的 Kubernetes docs 在一起。它们非常详细,一开始可能会让人不知所措,但它们写得非常好。🎉

包装

That’s a wrap.

我希望这篇文章对你有用。您看到了如何设置 K8s 和运行您的第一个 K8s 应用程序。然后,您了解了如何使用常见命令检查、创建和删除 K8 资源。如果你觉得这篇文章有帮助,请在你最喜欢的社交媒体渠道上分享,这样其他人也可以找到它。👍

我在工作中有未来的 K8s 文章。跟随 me 确保你不会错过它们。😃

我撰写关于数据科学、云计算和 DevOps 的文章。如果你对这些感兴趣,可以在这里查看我的其他文章。

kubectl开!🚀

Kubernetes 的关键概念

原文:https://towardsdatascience.com/key-kubernetes-concepts-62939f4bc08e?source=collection_archive---------3-----------------------

云计算、容器化和容器编排是 DevOps 中最重要的趋势。无论您是数据科学家、软件开发人员还是产品经理,了解 Docker 和 Kubernetes 的基础知识都是有益的。这两种技术都有助于你与其他人合作,部署你的项目,并增加你对雇主的价值。

在本文中,我们将介绍 Kubernetes 的基本概念。有很多 Kubernetes 的术语,这可能会使它变得令人生畏。我会帮你做一个心智模型来加速你对技术的理解。

Orchestrating the movement of shipping containers

如果你首先了解 Docker 概念,Kubernetes 会更有意义。查看我的码头指南,学习基本原理。

[## 学习足够的码头工人是有用的

第 1 部分:概念景观

towardsdatascience.com](/learn-enough-docker-to-be-useful-b7ba70caeb4b)

然后回到这里学习如何编排这些 Docker 容器。

Kuberwhat?

Kubernetes 是一个开源*台,用于管理生产中的容器化应用。Kubernetes 简称 K8s。展望未来,我将主要使用术语 K8s ,因为谁不喜欢效率呢?😃

K8s 火爆。正如你在下面的图表中看到的,谷歌对它的搜索在过去的五年中增长迅速。

Worldwide search interest for kubernetes

K8s 为什么这么抢手?Kubernetes 使您更容易自动扩展应用程序,减少停机时间,并提高安全性。无需再编写脚本来检查、重启和更改 Docker 容器的数量。取而代之的是,你告诉 K8s 你想要的集装箱数量,它会为你完成工作。K8s 甚至可以根据使用的资源自动缩放容器。

Kubernetes 是所有关于抽象的复杂性。它提供了与应用程序开发环境接口的清晰要点。

K8s 对于一个每天只有少量访问者的基本静态网站来说没有太大意义。它的用例是用于可能需要快速伸缩的大型应用程序。

对于大型应用程序,您可以使用 K8s 来充分利用您的计算和存储资源。当与云提供商配对时,K8s 可以为您省钱。💰无论您在哪里运行 K8s,它都应该可以帮助您节省时间并减少 DevOps 的麻烦。

Docker 有一个名为的竞争产品 Docker Swarm ,它编排容器。但是,它没有 K8s 那样的功能和市场份额。虽然你可能认为 Docker 在 K8s 有自己的产品时不会很好地与 K8s 配合,但两者配合得非常好。我强烈建议你使用 K8s 来编排你的容器。

Playing nicely

保持许多 K8s 抽象的直线可能是棘手的。我将解释关键部分是如何组合在一起的,这样您就可以理解这个强大的*台了。让我们来探讨 K8s 的关键概念以及它们之间的关系。

首先,我们将看看六个抽象层和组成它们的部分。然后我们将看看其他七个关键的 K8s API 对象。

K8s 的六层

让我们假设你有一个持续运行的应用,不需要存储状态。

Kubernetes abstractions for a Deployment. © Jeff Hale 2019

以下是 K8s 概念的六层,从最高层的抽象开始。

  1. 部署
  2. 复制集
  3. 豆荚
  4. 节点集群
  5. 节点流程
  6. 码头集装箱

部署创建和管理复制集,复制集创建和管理 pod,pod 运行在节点上,节点上有容器运行时,运行您放在 Docker 映像中的应用程序代码。听起来像爱尔兰民歌“拉特林沼泽”。😄

这是一个分解了工作节点流程的图表。让我们挖一点。

Detailed Kubernetes abstraction Deployment levels. © Jeff Hale 2019

蓝色阴影的层次是更高层次的 K8s 抽象。绿色级别表示您应该知道但不能接触的节点和节点子流程。

请注意,您的 K8s 实例通常会有多个可以在单个节点上运行的 pod。

Docker 容器包含您的应用程序代码。

**语法插曲 * *

根据 K8s 自己的风格指南,API 对象如 Pods 的大写应该遵循“实际对象名中使用的相同的大写和小写字母”然而,在文档中经常没有遵循这一准则——API 对象的大写或小写似乎是随机的。

我将遵循我的 K8s 文章和大写错误中的风格指南声明的政策。

    • 语法插曲结束。😄**

让我们从最高的抽象层次开始,分别看一下这六个层次。

部署

如果你想创建一个持续运行的无状态应用,比如 HTTP 服务器,你需要一个部署。部署允许您在不停机的情况下更新正在运行的应用程序。部署还指定了一个当吊舱死亡时重启的策略。

您可以从命令行或配置文件创建部署。我将在以后的文章中向您展示这两种方法,所以请跟随 me 以确保您不会错过它们。😄

复制集

部署会创建一个副本集,确保您的应用程序具有所需数量的 pod。复制集将根据您在部署中指定的触发器创建和缩放窗格。

复制控制器执行与复制集相同的功能,但是复制控制器是老式的。复制集是 2019 年管理复制 pod 的智能方式。

豆荚

Pod 是 Kubernetes 的基本构建模块。一个 Pod 包含一组一个或多个容器。通常,每个 Pod 有一个容器。

Pod

pod 处理容器的容量、机密和配置。

豆荚是短暂的。它们在死亡时会自动重启。

当应用程序被 ReplicationSet 水*缩放时,窗格被复制。每个 Pod 将运行相同的容器代码。

豆荚生活在工人节点上。

集群级别

一个 K8s 集群由一个 C 集群主节点工作节点组成。

Star Cluster. Credit: NASA, ESA and the Hubble Heritage (STScI/AURA)-ESA/Hubble Collaboration

下面是一个集群的示意图。该图强调了如何在一个 Worker 节点上运行多个 Pods,以及如何由一个 Master 管理多个 Worker 节点。

Kubernetes Nodes, Pods, & Containers © Jeff Hale 2019

工作节点

一个 职工节点 就是也简称节点简称节点是机器的抽象,可以是物理机,也可以是虚拟机。把一个节点想象成一台计算机服务器。

一个或多个 pod 在单个工作节点上运行。

Pod 从不在两个节点之间拆分,它的内容总是位于同一节点上并一起计划。

谁在告诉工人节点做什么?大师。

集群主机

群主 有着多得严重可笑的别名。它也被称为主节点、Kubernetes 主节点、集群控制*面、控制*面、主节点。不管你叫它什么,它都指挥工人节点。主设备做出调度决策、响应事件、实施更改并监控集群。

工作节点和主节点都有子流程组件。

节点流程

主组件

主要组件是 API 服务器(又名 kube-apiserver)etcd 、S 调度器(又名kube-调度器)、kube-控制器-管理器和云控制器管理器。**为了完整起见,我于 2019 年 4 月 10 日添加了控制者-管理者* *

Cluster Master subprocesses

让我们简单看一下每一个。

API 服务器 —公开 K8s API。这是 Kubernetes 控制的前端。(又名。kube-apiserver)认为枢纽
etcd —集群状态数据的分布式键值存储。思考集群信息
调度器 —选择新窗格的节点。好导这里。(又名 kube-scheduler)想想匹配器
kube-controller-manager—运行控制器来处理集群后台任务的进程。想想集群控制器
云控制器管理器 运行与云提供商交互的控制器。想云接口

工作节点组件

Worker 节点的组件是 kubeletkube-proxy容器运行时

Worker Node subprocesses

—负责工人节点上的一切。它与主服务器的 API 服务器通信。想为工节点。
kube-proxy—将连接路由到正确的 pod。还跨服务单元执行负载*衡。想想
交警
容器运行时 —下载图像并运行容器。例如,Docker 是一个容器运行时。想
码头工人

让我们深入到最后一个层次,看看那些容器运行时运行的是什么。😄

码头集装箱水*

如果你想用 K8s 运行你的应用,你的应用需要在某种容器中。Docker 是目前最常见的容器*台。我们假设你正在使用它。

在创建部署时,您将指定 pod 应该使用哪个 Docker 映像。容器运行时将下载映像并创建容器。

K8s 不直接创建容器。它创造了容纳容器的容器。Pod 中的容器共享任何已配置的资源,例如卷存储。

有五个管理和运行 pod 的高级 K8s API 资源:部署、StatefulSets、DaemonSets、Jobs、CronJobs 。这些对象负责管理和运行创建和运行容器的窗格。让我们看看这些创建和管理连续流程的控制器

副本集、状态集和守护集

如你所见,一个复制集创建并管理 pod。如果一个 Pod 由于一个节点故障而关闭,复制集可以自动替换另一个节点上的 Pod。通常应该通过部署创建副本集,而不是直接创建,因为使用部署更新应用程序更容易。

A Volume can be attached to a ReplicaSet or a StatefulSet. © Jeff Hale 2019

有时候你的程序需要保存状态信息。你可以把状态想象成你的用户与你的应用程序交互的当前状态。所以在一个视频游戏中,它是用户角色在某个时间点的所有独特方面。

例如,最初的超级马里奥兄弟游戏中的状态将包括用户游戏的每个相关方面:什么级别,该级别中的什么位置,大还是小,火球还是没有火球,多少硬币,多少点数,以及多少条生命。

当你的应用程序有你需要跟踪的状态时,你会怎么做?使用 StatefulSet。

状态集

像 ReplicaSet 一样,stateful set根据容器规范管理一组 pod 的部署和伸缩。与部署不同,StatefulSet 的 pod 不可互换。每个 Pod 都有一个唯一的、持久的标识符,控制器在任何重新调度中都维护该标识符。StatefulSets 适用于持久的、有状态的后端,如数据库。**

Pod 的状态信息保存在与 StatefulSet 相关联的卷中。我们稍后将讨论体积。

达蒙塞特

DaemonSets 为连续过程。每个节点运行一个 Pod。添加到群集的每个新节点都会自动获得一个由 DaemonSet 启动的 Pod。DaemonSets 对于正在进行的后台任务(如监控和日志收集)非常有用。

StatefulSets 和 DaemonSets 不受部署控制。尽管它们与副本集处于同一抽象级别,但在当前的 API 中,它们并没有更高的抽象级别。

现在我们来看看乔布斯和 CronJobs。

乔布斯和克朗乔布斯

职位

一个 任务 是运行批处理的 pod 的主管。作业创建 Pod,并通过跟踪成功完成 Pod 的数量来确保它们执行任务。与复制集不同,一旦容器内的进程成功完成,容器不会重新启动。当您想要运行一次流程时,请使用作业。

克朗乔布

如果您想要在定期、指定的时间(例如每小时、每天或每月)运行作业,请创建一个 CronJob cron Job 类似于一个作业,但被安排在固定的时间间隔或设定的时间重复。

Time

您通常需要创建一个服务来提供对临时 pod 的一致访问。

服务

K8s 服务 为一组 pod 创建单个接入点。服务提供一致的 IP 地址和端口来访问底层 pod。外部用户和内部 pod 都使用服务与其他 pod 通信。

服务有多种形式。与 K8s 联网是一个值得自己指导的话题。幸运的是,这里有一本由 Sandeep Dinesh 写的好书。

现在,让我们看看用卷和持久卷存储数据。

卷、持久卷和持久卷声明

一个 是一个可以容纳数据的目录。卷是 Pod 的一个组件,并不独立于它。在 Pod 规格中创建一个卷。不能单独删除卷。

一个卷可供 Pod 中的所有容器访问。您想要访问卷的每个容器必须单独装载它。

K8s 卷比任何单个容器都长寿,但是当封装容器死亡时,该卷也会死亡。但是,某些卷类型的文件会继续存在于本地或云存储中,即使在卷消失后也是如此。

Volumes

K8s 卷比 Docker 卷具有更多功能。卷可以提供对本地磁盘存储、内存存储或云存储的访问。一个 Pod 可以同时使用它们的组合。

K8s 卷类型包括空目录、工作节点的文件系统和特定于云提供商的存储。例如,awsElasticBlockStore 和 gcePersistentDisk 是用于长期存储的特定于提供程序的选项。点击查看更多文档。

持久卷和持久卷声明

为了帮助抽象出基础设施细节,K8s 开发了 持久卷持久卷声明。不幸的是,这些名称有点误导,因为普通卷也可以有持久存储。

与单独使用卷相比,PersisententVolumes (PV)和 PersisentVolumeClaims (PVC)增加了复杂性。但是,PV 对于管理大型项目的存储资源非常有用。

使用 PVs,K8s 用户最终仍然会使用一个卷,但是首先需要两步。

  1. 持久卷由群集管理员提供(或动态提供)。
  2. 需要存储 Pod 的单个集群用户创建了一个 PersistentVolumeClaim 清单。它指定了他们需要多少和什么类型的存储。K8s 然后找到并保留所需的存储。

然后,用户创建一个包含使用 PVC 的卷的 Pod。

持久卷具有独立于任何 Pod 的生命周期。事实上,Pod 甚至不知道 PV,只知道 PVC。

PVC 消耗 PV 资源,类似于 pod 消耗节点资源的方式。狂野!

Wild

包装

我希望这篇 K8s 概念的介绍对您有所帮助。如果你有,请在你最喜欢的社交媒体上分享,这样其他人也可以找到它。👍

让我们回顾一下我们见过的 K8s 概念。以下是部署的六个抽象级别:

  • ****部署:管理副本集。用于持久、无状态的应用程序(例如 HTTP 服务器)。
  • 复制集 : 创建并管理 pod。
  • Pod:K8s 的基本单位。**
  • ****节点集群**:工作节点+集群主节点。
    • 工人 节点:用于 pod 的机器。
    • 集群主 : 指挥工作节点。**
  • **节点进程
    Master 子组件:
    • API 服务器 : hub。
    • etcd :集群信息。
    • 调度器:匹配器。
      -kube-controller-manager:集群控制器。
    • 云-控制器-管理器:云接口。
      工作者节点子组件:
    • kubelet :工作者节点大脑。
    • kube-proxy :交警。
    • 容器-运行时 : Docker。**
  • ****Docker 容器:app 代码所在的地方。

下面是需要了解的 7 个额外的高级 K8s API 对象:

  • StatefulSet :类似于有状态进程的复制集。想好状态。**
  • DaemonSet: 每个节点一个自动 Pod。想班长。**
  • 作业**:运行容器直至完成。想
  • CronJob: 重复作业。想时间。**
  • 服务**:吊舱的接入点。想接入点
  • 卷**:保存数据。想想盘。
  • PersistentVolume,PersistentVolumeClaim: 分配存储的系统。认为存储索赔。**

把你的头缠在 K8s 上需要理解很多抽象的概念。不要期望你第一次就能记住它们。查看下面的一些资源来建立你的心智模型。

资源

以下是巩固你所学内容的资源。

  • 这里有一幅来自谷歌的很好的漫画,介绍了一些关键概念。
  • Daniel Sanche对关键 K8s 概念的另一个很好的概述。
  • 看看奈杰尔·波尔顿的《库伯内特的书》——现在在 v3。Kindle Book 最后一次更新是在 2018 年 11 月。

还有,关注我确保你不会错过我以后在 K8s 上的文章。在的下一篇文章中,我将向您介绍如何设置和运行您的第一个 K8s 部署,并介绍关键的 K8s 命令。

我写关于 Python 、 SQL 、 Docker 和数据科学的文章。查看我的文章这里如果你对这些感兴趣,请关注我。😄

开心 K8ing!

使用 Reddit 作为数据源时的关键人口统计点

原文:https://towardsdatascience.com/key-points-when-using-reddit-as-a-source-of-data-4f943918913f?source=collection_archive---------24-----------------------

你应该引用的学术期刊文章和资源列表。

Image: Unsplash/Lukas Blazek

人们一直在使用 Reddit 上的数据。有时他们是学生、学者或数据科学家。

这是三篇来自 Reddit 学术文献的同行评议文章,从方法论的角度来看是最具实质性的。将它们放在研究设计或方法部分绝对是个好主意。

Image: Reddit Inc.

Adams、Artigiani 和 Wish ( 2019 )对比了 Twitter 和 Reddit 进行社交媒体药物研究的情况。他们把重点放在关键词的使用上,以此作为发现人们如何在网上谈论毒品的主要方式。

…子编辑可以被视为自选采样帧。

主要重点和调查结果是:

  • 像许多在线论坛一样,Reddit 很方便地将相关帖子和评论归类到热门子论坛中。被称为“subreddits”。因为主题的范围可以从议题(见/r/政治)、地点(/r/联合王国)或兴趣(/r/电影)等,所以子编辑可以被视为自选的采样框架
  • 因为 Reddit 拥有大量年轻白人男性,它可以成为研究影响这一群体的现象的一个途径。如美国阿片类药物的流行
  • 与 Twitter 相比,讨论毒品时俚语较少,但毒品和毒品相关行为的同义词较多

Image: Unsplash

Shatz ( 2016 )直接将 Reddit 概括为“快速、免费和有针对性”的在线招募参与者*台的来源。

旧的研究指出了很大的性别差异,而新的研究通常指出了一个小的差异,或接**等的用户群

主要的人口统计亮点是:

  • 早期的研究指出了用户群的性别差异,这种差异偏向男性。尽管新的研究似乎不同意这一点,一些研究通常发现两性之间有微小的差异或几乎相等的代表性
  • 一项针对美国成年用户(约占活跃用户的一半)的人口统计数据的研究发现,在控制年龄时,他们相对代表美国成年人口
  • 人口统计数据可能会因子区域而异,而且也没有大的子区域数据库。然而,网站的用户和志愿者有时会进行他们自己的“子编辑调查”,询问各种人口统计信息

Shatz 指出了几个优势:

  • 潜在的大样本,并在短时间内招募
  • 有针对性的基于特定主题的子主题允许从特定人群、特殊利益群体或传统上被边缘化的人群中招募
  • 研究通常可以免费进行。这对学生和早期职业研究者来说很重要

和几个缺点或限制:

  • 低招聘率或保留率的可能性
  • 招聘过程依赖于用户根据帖子标准进行的自我选择,这意味着人们可以撒谎并参与其中。然而,他指出,大多数研究没有提供货币补偿,这可能会减少问题
  • Reddit 不能成为招聘的通用方法。对于某些研究,这可能是一种不合适的招募方法。
  • 与在线招聘相关的一般问题仍然适用。例如伦理考虑、所需的技术专业知识以及采样、测量和无响应方面的各种错误。

Image: Unsplash

Jamik 和 Lane ( 2017 )将 Reddit 的使用与心理学中使用的其他招聘来源进行了比较。

他们将从 Reddit 上抽取的样本与亚马逊的在线众包机械土耳其 (MTurk)和一个典型的本科大学样本进行了比较。由于易于获取且成本低廉,这些类型的样本通常用于心理学(波莱,2019 )。

主要调查结果是:

  • Reddit 样本中男性多于女性,种族多样性低于本科生样本,包含更多非美国人,以及更多受过高等教育的个人,其中一些人已经大学毕业
  • Reddit 的样本比大学生样本更古老,覆盖范围更广。然而,总的*均绩点是相似的
  • 他们得出结论,使用 Reddit 作为招聘来源可能会产生比传统大学生样本更多样化的样本。

主要引文

Adams,Artigiani,E.E .和 Wish,E.D. (2019)“选择你的社交媒体药物研究*台并改进你的关键词过滤器列表”,《药物问题杂志,49(3),第 477-492 页。doi:10.1177/0022042619833911。

Jamnik,M.R .和 Lane,D.J. (2017) “使用 Reddit 作为高质量数据的廉价来源”,实践评估,研究&评估,22(4/5),第 1-10 页。

Shatz,I. (2016)“快速、免费和有针对性:Reddit 作为在线招募参与者的来源”,社会科学计算机评论,35(4),第 537-549 页。doi:10.1177/0894439316650163。

建立有效人工智能组织的关键步骤

原文:https://towardsdatascience.com/key-steps-for-building-an-effective-ai-organization-cad45b1992d7?source=collection_archive---------18-----------------------

Photo by Randy Fath on Unsplash

最*,我迷上了人工智能对任何行业(科技、银行、制造等)的任何业务的影响。)这让我进一步探索这个主题,同时试图理解一家公司应该如何使用人工智能来转变其流程。

在这篇文章中,我很乐意将我的观察总结成一套可行的步骤,可以帮助任何组织启动他们的人工智能转型。我的想法受到了 Landing AI 创始人吴恩达写的令人惊叹的 12 页论文的严重影响,名为“AI 转型剧本”。此外,我还从许多麦肯锡公司的报告中得到了建议,如《麦肯锡关于支付:银行业高级分析特别版》。

#1.组织在部署 AI 时会面临哪些问题?

未能利用人工智能算法和数据实现运营转型的组织通常会面临以下一项或多项挑战:

  • 未能计划和战略性地迈出第一步。
  • 没有专注于交付商业价值。
  • 缺乏高级管理层的承诺。
  • 找不到 AI 人才。

让我们分别检查每个问题。

未能在计划和战略上迈出第一步

如果一个组织决定试点并开始部署人工智能能力,它必须努力准备这个过程。这包括选择正确的试点项目、估计交付时间、与业务部门沟通等。

一个不正确的开始方式是雇佣几个数据工程师/科学家,把他们和公司的其他人隔离开来,希望能施展他们的魔法。不幸的是,没有足够的东西可以交付,这将导致一个错误的结论,即 AI 转型不适合这个组织。

稍后,我会列出一些实用的建议,引导你进行有效的计划。

没有专注于交付商业价值

我将允许自己引用吴恩达的话,他说一个初始的飞行员需要“有一个明确定义的、可衡量的、创造商业价值的目标”

如果人工智能团队未能交付直接影响底线的可测量结果,试点结果可能会被视为太不重要,这可能会导致资金减少,并缺乏进一步试验人工智能的自由。

这个挑战可以通过对人工智能团队最初的努力方向进行战略和仔细的规划来克服。

缺乏高级管理层的承诺

将高级管理层的注意力集中在一个新的实验性过程上是一个具有挑战性但并非不可能的任务,大多数人工智能团队都将面临这一任务。这与前一点关注交付商业价值高度相关。

高层管理人员和人工智能团队应该经常保持透明的沟通,这样项目的焦点仍然是向组织交付有用的结果。

找不到 AI 人才

目前,有能力使用人工智能技术产生有意义的结果的人非常短缺。大多数攻读高级计算机科学学位的博士生都选择了最大的科技巨头。

金融、制造、电信、制药和其他行业的公司没有机会建立强大的内部人工智能团队来解决复杂的问题。

幸运的是,这种挑战可能只是短期的,最终,组织将能够雇用受过教育的人。

但是,在这个非常时刻,公司应该寻找创新的方式来聚集人工智能人才。我将在下面概述一些有用的方法。

#2.实现人工智能转型的可行步骤

您的组织的人工智能转型经历了几个阶段,从精心选择的试点项目开始,慢慢建立一个人工智能单位,为所有其他业务单位提供支持。

从试点项目开始

吴恩达指出“对你的最初几个人工智能项目来说,成功比成为最有价值的人工智能项目更重要”和补充道“重要的是让飞轮旋转起来,这样你的人工智能团队才能获得动力”。

上述陈述将我们引向以下一套策略:

  1. 人工智能试点项目应该由一个独立的人工智能团队来执行(我已经在下一节概述了人工智能团队的细节)。
  2. 第一个人工智能项目应该直接与 组织的商业战略联系起来。
  3. 为了确保交付商业价值,人工智能团队应该与对业务有深入了解的内部团队密切合作。这将确保现有问题的人工智能解决方案正在建立。
  4. 这些首批人工智能项目应该产生可测量的结果,这些结果可以(用数字)向执行委员会解释。
  5. 项目价值应尽快交付(少于 18 个月)。
  6. AI 团队应该对项目的范围形成一个健壮而简洁的计划,这样它在技术上是可行的,并且不会一下子覆盖太多。公司经常无法评估人工智能的力量,认为许多复杂的问题可以用这项技术解决。

一旦你的初始试点获得牵引力并带来商业价值,你公司的其他单位将与人工智能团队展开对话,开始探索转型的可能性。

组建你的人工智能团队

如上所述,建立一个强大的内部人工智能团队是相当具有挑战性的,因为有经验的人供应高,但需求低。

在吴恩达和他的 deeplearning.ai 课程、Siraj Raval 和人工智能学院以及众多书籍和课程(如我最*的书“递归神经网络与 Python 快速入门指南”)的帮助下,这种情况可能会在长期内发生变化。

为了立即采取行动,公司可能需要使用稍微有点不*凡的方法。其中一些包括:

  • 外包 AI 团队

你的组织可以雇佣一个数据工程师/科学家的外部供应商来构建所有的 AI 解决方案。

这种方法被推荐用于较小的和不太关键的项目。理想情况下,你应该拥有你的人工智能团队的“大脑”,并外包需要独特数据源和高级解决方案的项目。

  • 与其他组织合作获取人工智能人才

麦肯锡公司(McKinsey&Company)最*的一份报告解释了一家大型零售组织如何与一家初创企业孵化器建立战略合作伙伴关系,这使他们能够接触到许多已经拥有人才的小公司。将这种合作与核心人工智能内部团队相结合可以促进你的转型。

  • 提供广泛的人工智能培训

从长远来看,培训员工的想法是最有效的,但随之而来的是更多的挑战。

首先,你需要咨询人工智能领域的专家,他曾领导过这次行动,并把方向引导到正确的道路上。

其次,你的首席学习官(CLO)需要仔细策划培训内容。这包括在线视频教程、付费课程、电子书等。

最后,你的组织需要为每一个角色(行政领导、部门/业务单位经理和 AI 工程师/数据科学家)提供培训程序。

为了确保这些步骤得到正确执行,您的组织可能需要像 Landing AI 这样的外部合作伙伴的帮助,目前,该公司旨在用人工智能技术为制造公司提供支持。

选择如何组建你的人工智能团队并不是一个全有或全无的决定,你最有可能混合上述方法来实现所需的结果。

每个公司的内部人工智能团队的结构都会略有不同。在这一部分,我将给出一个分解的例子,包括数据科学家、数据工程师、工作流集成者、数据架构师、交付经理、可视化分析师和翻译。让我们来看看每个角色:

  • 翻译者与业务所有者沟通,以识别业务请求并确定其优先级。
  • 数据科学家与翻译一起开发一个特定的用例。
  • 一名数据工程师与相关业务部门合作,了解数据特征(需求、来源等。)的用例。
  • 数据科学家对算法进行编程,并分析沙盒中的数据以产生见解。
  • 一个可视化分析师为业务用户开发报告和仪表板。
  • 一个工作流集成者与业务所有者一起开发模型和工具的原型。
  • 一个交付经理引导原型和仪表板,并努力获得通过或失败的决定。
  • 交付经理和工作流集成人员与 IT 部门合作,将原型扩展到企业级。
  • 交付经理和翻译人员与业务和 IT 部门合作,以确保采用和持续的模型维护。

正如你所看到的,在人工智能团队(通过翻译、工作流集成和交付经理)和特定的业务单元之间有着持续的沟通。这对于交付成功的试点项目至关重要。

让人工智能部门成为您组织的关键组成部分

在这最后一部分,我想把注意力集中在一个更广阔的画面上,并建议一个人工智能单位如何适应你的组织。

典型地,大公司被分成子单位(营销、IT、法律等)。)向高级管理层报告。为了实现全面的人工智能转型,每个部门都应该采用新技术。

人工智能团队可以作为一个独立的中央单位,它将加强人工智能项目和人才的不同部门。最终,这些项目可以从特定的业务单元进行控制和管理。

使用人工智能的力量,您的公司可以转变成一个更有效的组织,并始终领先于竞争对手。你的重点不应该是成为全球人工智能的领导者,而是用这项技术彻底改变你的特定流程。

谢谢你的阅读。如果你喜欢这篇文章,给它一些掌声👏。希望你有一个伟大的一天!

来自 Strata 2019 @London 的关键要点

原文:https://towardsdatascience.com/key-takeaways-from-strata-2019-london-e623189bea84?source=collection_archive---------28-----------------------

Screenshot from https://learning.oreilly.com/videos/strata-data-conference/9781492050568

这几周我花了一些业余时间观看了 2019 年伦敦地层的主题演讲。有一件特别吸引我的事情,我想和你分享。

我订阅了几个关注技术的播客,毫不奇怪,这些天他们都在谈论数据科学、人工智能。那么这些术语是什么意思呢?这是否意味着我们正在研究的技术将很快消失?这些新技术将如何改变我们的生活?我们将如何更新我们的技能来适应这些新的变化?

来自谷歌的 Cassie Kozyrkov 在会议上指出了一些非常实际的东西,让数据科学变得有用。收集的数据比以往任何时候都多。这是确保我们正确使用数据来分析和构建功能的绝佳机会。

来自金融时报的首席产品和信息官 Cait O'Riordan 讲述了 FT 如何利用北极星指标来提高用户增长并增强工程和产品团队的绩效

稍微介绍一下北极星指标(NSM) 的背景,这是*年来来自硅谷的一个概念,它是一个单一的指标,捕捉产品向客户提供的核心价值。

回到《金融时报》,这家有着 130 年历史的出版商在商业上是一家基于订阅的数字公司。Cait 分享了他们如何通过使用 NSM 获得 100 万付费客户的经验。他们对收入、使用率、取消率、转换率等等做了研究。他们关心的是客户对其内容的参与度。

新盖·曼真瓜,炉边分析公司首席执行官。讨论了如何在组织内培养数据科学能力,尤其是什么类型的个人已准备好成为数据科学家。

那么,什么是数据科学?在她的演讲中,你可以找到的答案是,“数据科学是分析、可视化和货币化数据的过程”,这意味着,数据科学家不是开发人员、统计学家或业务分析师,而是能够处理这些的人,她称之为具有超能力的人。

还有谁有超能力?自学者。这不是第一次看到有人突出这个技能。在这个快节奏的世界里,技术已经发生了很大的变化。以我自己为例,我是微软动态 365 顾问。在我* 3 年的短暂职业生涯中,微软发布了新的功能,废弃了许多客户系统中使用的一些功能。我必须学习一些新的技能来适应这个行业,我相信其他领域的每个人都必须这样做。

来自牛津大学的桑德拉·沃希特戴着律师帽分享了她对【大数据和人工智能时代的隐私、身份和自主性】的见解。当我在伦敦大学学院学习数字人文科学的时候,我参加了一些关于电子出版的法律和社会方面的研讨会。我们讨论了监控和合法获取信息、信息安全和治理。

Sandra 提到脸书、亚马逊、微软等大型科技公司最*被指控在用户不知情的情况下推断用户的非常敏感的信息。他们被指控推断民族、种族、性别、性取向、健康状况,所有这些,即使他们的顾客对此一无所知。更糟糕的是,这些信息通常会与第三方共享,例如信贷机构。

听起来很可怕,是吗?很高兴一些组织已经将道德和合理的数据使用提上日程。她用一句简单的话结束了她的演讲:是时候了,我们不仅要关注什么是可能的,还要关注什么是合理的。

强烈推荐对数据科学感兴趣的人关注 O'Reilly 和 Strata 数据会议。相信我,你会学到很多!

KGCNs:基于 TensorFlow 的知识图机器学习

原文:https://towardsdatascience.com/kgcns-machine-learning-over-knowledge-graphs-with-tensorflow-a1d3328b8f02?source=collection_archive---------9-----------------------

这个项目引入了一个新颖的模型:知识图卷积网络 (KGCN),可以在 Apache 许可下从的 GitHub repo 免费使用。它是用 Python 编写的,可以通过 PyPi 的 pip 安装。

这项工作的主要思想是使用 TypeDB 作为知识图,在知识图、自动逻辑推理和机器学习之间建立一座桥梁。

摘要

通过监督学习,KGCN 可用于创建任何标记的 TypeDB 事物集合的矢量表示嵌入

  1. KGCN 可以被直接训练用于存储在 TypeDB 中的事物的分类或回归。
  2. 未来的工作将包括通过无监督学习构建嵌入。

它是用来做什么的?

通常,数据不太适合表格格式。在知识图中存储复杂和相互关联的数据有很多好处,尤其是每个数据点的上下文可以完整地存储。

然而,许多现有的机器学习技术依赖于每个示例的输入向量的存在。创建这样一个向量来表示知识图中的一个节点是很重要的。

为了利用机器学习中现有的想法、工具和管道的财富,我们需要一种构建这些向量的方法。通过这种方式,我们可以利用知识图中的上下文信息进行机器学习。

这是 KGCN 能做到的。给定知识图中的一个示例节点,它可以检查该示例、其上下文附*的节点。基于这个上下文,它可以确定一个向量表示,例如一个嵌入了的

KGCN 适合完成两种广泛的学习任务

  1. 从知识图进行监督学习以进行预测,例如多类分类(已实施)、回归、链接预测
  2. 知识图嵌入的无监督创建,例如用于聚类和节点比较任务

为了构建一个有用的表示,KGCN 需要进行一些学习。为此,它需要一个函数来优化。回顾我们可以执行的广泛任务,我们有不同的案例来配置学习:

  1. 在受监督的情况下,我们可以针对我们想要执行的确切任务进行优化。在这种情况下,嵌入是学习管道中的过渡张量
  2. 为了构建无监督嵌入作为输出,我们优化以最小化图中的一些相似性度量

方法学

这个项目背后的意识形态在这里描述,还有一个的演示视频。实现的原理基于来自斯坦福 SNAP 小组的 GraphSAGE,经过大量修改后可用于知识图。KGCN 从存储在类型超图类型数据库中的上下文数据中学习,而不是处理典型的属性图。此外,它还从 TypeDB 的自动逻辑推理器推导出的事实中学习。从这一点开始,假设对 TypeDB 的文档有所了解。

现在,我们介绍关键组件及其交互方式。

KGCN

KGCN 负责导出一组事物的嵌入(从而直接学习对它们进行分类)。我们从查询 TypeDB 开始,以找到一组带标签的示例。接下来,我们收集关于每个例子的上下文的数据。我们通过递归地考虑它们的邻居,以及它们邻居的邻居,直到 K 跳远,来做到这一点。

我们从 TypeDB(上图)中检索关于这个邻域的数据。该信息包括所遇到的每个相邻事物的类型层次角色属性值,以及任何推断的邻居(上面用虚线表示)。这些数据被编译成数组,由神经网络接收。

通过操作聚合和组合,为一个事物建立一个单一的矢量表示。这个过程可以递归链接到相邻事物的 K 跳。这为感兴趣的事物构建了一个表示,其中包含从广泛的上下文中提取的信息。

在监督学习中,这些嵌入被直接优化以执行手边的任务。对于多类分类,这是通过将嵌入传递到单个后续密集层并通过 softmax 交叉熵确定损失(针对示例事物的标签)来实现的;然后,优化以尽量减少损失。

一个 KGCN 对象集合了许多子组件,一个上下文构建器、邻居发现器、编码器和嵌入器。

输入管道组件不太有趣,所以我们将跳到有趣的部分。你可以在 KGCN 的自述中读到其余的内容。

嵌入器

为了创建嵌入,我们在 TensorFlow 中构建了一个网络,该网络连续聚合和组合来自 K 跳的特征,直到保留一个“摘要”表示,即嵌入(如下图所示)。

为了创建流水线,嵌入器链聚合并组合所考虑的邻居的 K 跳操作。例如,对于 2 跳的情况,这意味着聚合-组合-聚合-组合。

上图显示了在监督分类的情况下这种链接是如何工作的。

嵌入器负责链接子组件聚合器和组合器,如下所述。

集合商

一个聚合器(如下图)接受一个事物邻居的子样本的向量表示。它产生一个代表所有这些输入的向量。它必须以一种顺序不可知的方式做到这一点,因为邻居是无序的。为了实现这一点,我们使用一个密集连接的层,以及 maxpool 输出(maxpool 是顺序不可知的)。

组合器

一旦我们将一个事物的邻居聚合成一个单一的向量表示,我们需要将它与该事物本身的向量表示结合起来。一个组合器通过连接两个向量来实现这一点,并使用单个密集连接的层来降低维度。

监督 KGCN 分类器

受监督的 KGCN 分类器负责编排实际的学习。它包含一个 KGCN 实例,对于任何使用 KGCN 的学习者,它提供:

  • 训练/评估/预测的方法
  • 从嵌入张量到预测的管道
  • 接受预测和标签的损失函数
  • 乐观主义者
  • 反向传播训练循环

必须是提供这些行为的类,因为 KGCN 不与任何特定的学习任务相关联。因此,这门课提供了监督学习框架所需的所有专业知识。

下面是一个稍微简化的程序流程的 UML 活动图。

使用 KGCNs 构建

要开始使用 KGCNs 进行构建,请查看自述文件的快速入门,确保您具备所有要求,并遵循示例用法说明,重申如下:

这将帮助您为自己的知识图构建一个多类分类器!存储库中还有一个例子,其中有真实的数据,可以填补模板使用中遗漏的任何空白。

如果您喜欢我们正在做的事情,并且您使用 KGCNs 或对其感兴趣,您可以做几件事情:

  • 提交问题以解决您在安装或使用 KGCNs 时遇到的任何问题
  • 如果你愿意帮助我们提升这部作品的知名度,就开始回购吧:)
  • 在 Vaticle Discord channel 上提出问题、提出想法或与我们对话

这篇文章是为第三个 kglib 预发布而写的,使用了 TypeDB commit 20750ca0a46b4bc252ad81edccdfd8d8b7c46caa,随后可能会与回购不一致。查看那里的最新消息!

旧金山社区中的数据聚类

原文:https://towardsdatascience.com/kickstart-your-first-clustering-project-in-san-francisco-neighborhoods-e258e659440c?source=collection_archive---------12-----------------------

在这个项目中,我们将使用 Foursquare API 来探索旧金山的街区,获取每个街区中最常见的场地类别,使用 k -means 聚类算法来查找相似的街区,使用follow库来可视化旧金山的街区及其新兴的集群。

Project Flow

这是我们在这个项目结束时得到的聚类图:

这篇文章的灵感来自 Coursera 上的应用数据科学顶点课程。

先决条件:注册 Foursquare 开发者账户

Foursquare 是一家建立了海量位置数据数据集的科技公司。通过与 Foursquare 数据库通信并调用它的 API,我们可以检索给定位置周围特定类型的场所或商店。

这个项目一个免费账户就够了。创建完帐户后,单击创建新应用程序。标记您的客户端 ID 和客户端密码以备后用。

第一步:从网站上搜集邮编和邻居

导入库:

我们抓取下面的页面,http://www.healthysf.org/bdi/outcomes/zipmap.htm,以便获得邮政编码表中的数据,并将数据转换成熊猫数据帧。

我们删除了不必要的列和行,并将数据分配给新的数据帧sf_data

sf_data.head()

我们的数据帧中有 21 行。

步骤 2:将地址转换成纬度和经度

为了利用 Foursquare 位置数据,我们需要获得每个邻域的纬度和经度坐标。

我们将使用uszipcode,这是一个在 Python 中易于使用的 zipcode 数据库。

第三步:探索旧金山的街区

1.创建一张旧金山地图,在上面叠加街区。

使用geopy库获得三藩市的纬度和经度值。

旧金山的地理坐标是 37.7792808,-122.4192363。

然后我们使用folium库来绘制地图。 叶子 既可以将数据绑定到地图上,也可以将丰富的矢量/光栅/HTML 可视化作为标记在地图上传递。

Map of San Francisco with neighborhoods

你可以在这里找到其他更漂亮的 Matplotlib 颜色调色板。

接下来,我们将开始利用 Foursquare API 来探索社区并对其进行细分。

2.定义 Foursquare 凭证和版本

3。获取 500 米范围内每个社区排名前 100 的场馆。

对每个邻域运行上面的getNearbyVenues函数,并创建一个名为sf_venues的新数据帧。

sf_venues

1084 个场地被 Foursquare 退回。

让我们检查一下每个街区返回了多少个场地:

让我们看看有多少独特的类别可以从所有返回的场馆策划。

共有 214 个独特的类别。

第四步:分析每个邻居

我们首先将Venue Category变量转换成虚拟变量。

sf_onehot

根据邻*区域和每个场地类别出现频率的*均值对行进行分组。

创建一个新的数据框架return_most_common_venues并显示每个街区的前 10 个场馆。

第五步:聚集邻居

如果您需要从未标记的数据中快速发现见解,那么k-means尤其有用。

运行 k-means 将邻域聚类为 5 个聚类。k-means 会把我们的邻居分成 5 组。就数据集中包含的要素而言,每个聚类中的邻域彼此相似。

KMeans 内部参数的简要汇报:

1.random_state : KMeans 是随机的(即使使用相同的输入值运行该函数,结果也可能不同)。为了使结果可重复,可以指定一个 int 来确定随机性。

2.KMeans.fit():用特征矩阵拟合 KMeans 模型。

将原始的sf_data数据帧与聚集的neighborhoods_venues_sorted数据帧合并。

sf_merged

最后,让我们来看一看产生的集群:

步骤 6:检查集群

现在,我们可以检查每个集群,并确定区分每个集群的不同场馆类别。

集群 1

聚类 1 中有 16 个邻域。我们可以很容易地注意到,集群 1 中的大多数社区在他们的前 10 个场馆中都有Coffee Shop

集群 2

簇 2 中只有 1 个邻域。

集群 3

簇 3 中只有 1 个邻域。

集群 4

簇 4 中只有 1 个邻域。

集群 5

聚类 5 中有 1 个邻域。

结论

因为旧金山只有几个街区,我们无法真正获得有见地的集群。然而,你可以尝试使用更大城市的数据集:多伦多,纽约。

参考

  1. 应用数据科学顶点
  2. uszipcode
  3. k-means
  4. 术语“随机状态”在 KMeans 中是什么意思
  5. 叶子

美国军队中的黑仔机器人:事后的伦理

原文:https://towardsdatascience.com/killer-robots-in-the-us-military-ethics-as-an-afterthought-baf07e500d9?source=collection_archive---------24-----------------------

国防部在伟大的人工智能竞赛中争夺第一名的时候,把伦理道德抛在了脑后。

Image by bamenny from Pixabay.

作为美国战争机器中的代理人,美国军方并没有低估杀手机器人或致命自主武器系统(LAWS)的未来发展。人工智能(AI)自最初由艾伦·图灵(Alan Turing)等先驱创立以来,以及他对能够像人类一样学习思考和行为的机器的思考,已经显示出了很大的前景。机器学习及其子集深度学习激发了机器有朝一日能够发展甚至取代人类认知的希望。这是一项潜在的技术,国防部不能也不会忽视。虽然国防部已经制定了第 3000.09 号指令(T0),为开发自主武器系统(AWS)和致命的对应法律制定了一个实用的框架,但他们制定一个全面的伦理框架,充分回应国家和国际关注,目前只是事后的想法。但是,当走向机器人可能夺走人类生命的未来时,伦理难道不应该是这项技术的核心吗?

人工智能军备竞赛

根据美国和国际上的倡导者,AWS 和法律都有可能在战场上拯救生命,。更少的地面部队意味着更少的军事死亡,更精确和高效的任务意味着更少的*民伤亡。虽然接受战争的不可避免性可能是对人类原始本能的压抑提醒,但世界各地的战争机器运转良好,资金充足,并与时俱进。中国、俄罗斯、以色列、澳大利亚、英国和欧盟都在开发 AWS,随着技术的进步,这些 AWS 有可能成为杀手机器人。美国无意落在后面。事实上,在 2020 年的预算中,国防部希望在无人驾驶和人工智能系统上花费46 亿美元。

美国已经有了完善的政府机构,如国防高级研究计划局(DARPA),该机构资助机器人自主和人工智能系统的研究。DARPA 在过去的六十年里一直在运作,现在它正通过它的 AI Next 活动展望未来。DARPA 在考虑国家安全的情况下处理高风险、高回报和长期的项目。DARPA 的 AI Next 项目之一是自主团队的上下文推理( CREATE )。CREATE 的目标是在较小的自主代理团队中建立决策能力,使他们不依赖于集中控制。想想成群的无人机,它们可以在本地协同工作,并立即做出决定,而不是听从命令。

虽然 DARPA 致力于一些长期项目,但联合人工智能中心(JAIC)于 2018 年成立,以跟上和部署技术在私营部门和学术界的开发和使用速度。JAIC 监督国防部各部门对人工智能的采用,并正在发展学术界和私营部门的合作伙伴关系,以获得快速发展和可部署的人工智能技术。但是国防部感受到的不仅仅是国家压力。国际人工智能竞赛的想法已经引起了一些关注,甚至是令人恐惧的法律军备竞赛的想法。这种速度和紧迫性是最令人担忧的。没有哪个州想输掉人工智能竞赛。随着俄罗斯总统弗拉基米尔·普京称“谁成为这个(人工智能)领域的领导者,谁将成为世界的统治者”,忧心忡忡的国家正在加快步伐。美国很有可能赢得研发和部署自主武器的竞赛,但代价是什么?如果没有一个经过深思熟虑的道德框架的约束,美国可能会以一种比 1945 年广岛和长崎原子弹袭击更令人羞愧的方式开发和部署自主武器。

道德问题

像人权观察(HRW)和哈佛法学院国际人权诊所(IHRC)这样的组织正在利用像阻止黑仔机器人的运动这样的目标来减缓人工智能军备竞赛,围绕这项技术的伦理展开讨论。当涉及到发动战争时,人们开始质疑超然的道德标准。由于风险更小,自主系统会让开战的决定更容易吗?给机器杀人的权力和意志意味着什么?出了问题谁来负责?有一种风险是,为了让我们在肮脏的战争事务中保持清白,人类军官监管致命机器的经过消毒的作战室将看不到流血。

Traditional horrors of war. Image by Jonny Lindner from Pixabay.

在国际舞台上,“有意义的人类控制”一词被作为法律伦理发展的一个关键组成部分来讨论。然而,对于“有意义的人类控制”在现实中是什么样子,人们还没有达成共识。在 3000.09 指令中,国防部讨论了人类判断的适当水*,而不是控制。国防部不排除完全自主的武器系统能够在没有人类直接参与的情况下选择目标和部署致命武器的可能性。然而,半自动武器系统将(并且确实)需要人类授权才能使用致命武力。

在联合国内部,《特定常规武器公约》( CCW)主持了关于法律未来的国际讨论,一些国家和组织呼吁全面禁止。但是世界上的大国(和军事支出大国)中国和美国都不希望限制这项技术的潜力。然而,美国公众并没有完全同意。在美国,2019 年 T4 益普索民意调查中,52%的受访者或多或少反对或强烈反对使用法律,而只有 24%的人支持使用法律。如果美国继续发展完全自主的武器,法律伦理将是获得公众支持的关键。民意调查收集了 26 个国家的意见,发现 66%反对使用法律的人认为这种武器越过了道德底线。人们只是对机器决定夺走一个人的生命感到不舒服。

伦理是事后的想法

那么,国防部在法律的道德发展和使用方面的立场是什么?国防部确实承认道德在法律方面的重要性,因为他们最初在宣布需要自己的伦理学家之前从技术行业寻求指导。然而,国防部已经致力于开发人工智能技术一段时间了,像机器人 Shakey 这样的项目可以追溯到 1966 年。最*,2019 年 2 月,国防部公布了其 2018 人工智能战略。然而,直到 2019 年 9 月,国防部才透露了聘请伦理学家的计划,这表明制定一个强大的道德框架并不是一个紧迫的优先事项。随着人工智能竞赛的升温,中国的目标是到 2030 年成为人工智能世界的领导者,谁有时间讨论伦理?

JAIC 主任空军中将杰克·沙纳汉指出,中国与学术界和工业界的紧密联系使他们在人工智能竞赛中占据优势。为了不被超越,国防部计划加强与一系列开发具有双重用途能力的人工智能技术的行为者的联系。根据 2018 年人工智能战略,国防部打算与学术界和工业界合作,为人道主义援助提供人工智能知识和专业知识。这种人道主义的面孔可能使他们成为更有吸引力的合作伙伴,因为一些科技行业的人发现与军队合作在道德上令人反感。谷歌拒绝继续执行五角大楼的项目 Maven 合同,此前其员工抗议以致命意图开发技术。

与担心落后于中国相比,道德根本不是国防部的首要任务。然而,可能并不是麻木不仁让伦理成为一个落后的优先事项。目前,人工智能技术只达到了让机器执行一些基本任务的水*与人类相同,或者略高。图像识别和癌症检测只是两个例子。我们还需要几十年才能开发出一种技术,让机器能够完成人类能够完成的一系列复杂认知任务,更不用说将这种技术与能够像人类一样灵活移动的机器人结合起来了。随着人工智能的大肆宣传,人们很容易认为杀手机器人就在眼前,而事实上,我们可能需要几十年才能开发出这种复杂的技术。国防部可能认为他们有足够的时间来严肃对待法律伦理。与此同时,DARPA 和 JAIC 正在大力推进 AWS 的研发。在幕后的某个地方,国防部正在采取一种悠闲的方式来确保伦理学家和形成透明的道德准则,这将使他们在向人工智能终点线的比赛中承担责任(如果有一个的话)。

正如我们在 bias 中看到的,人工智能系统学到的变成了嵌入和复制。如果法律的发展在每个方面都以伦理为核心,而不仅仅是事后的想法,那么我们创造出比我们更好的机器的机会就会增加。在一台机器内完全复制人类的意识可能是不可能的,在这种情况下,反对杀手机器人的论点可能会变得更强。归根结底(如果技术允许的话),将生死决定权交给一台比我们更有道德的机器可能会带来安慰,而不是引发恐惧。如果国防部想带领美国进入人工智能军备竞赛,它必须从一个强大的道德立场出发,跟上伟大的人工智能竞赛带来的快速技术进步。

KL Divergence Python 示例

原文:https://towardsdatascience.com/kl-divergence-python-example-b87069e4b810?source=collection_archive---------1-----------------------

Photo by Immo Wegmann on Unsplash

随着您作为数据科学家的职业生涯的进展,您将不可避免地遇到 kull back-lei bler(KL)分歧。我们可以把 KL 散度看作距离度量(尽管它是不对称的),它量化了两个概率分布之间的差异。这很有用的一个常见场景是当我们处理一个复杂的发行版时。与直接使用分布相比,我们可以使用另一种具有众所周知特性的分布(即正态分布)来更好地描述数据,从而使我们的生活更加轻松。换句话说,我们可以使用 KL 散度来判断是泊松分布还是正态分布更适合逼*数据。KL 散度也是高斯混合模型和 t-SNE 的关键组成部分。

对于连续随机变量的分布 P 和 Q,Kullback-Leibler 散度被计算为积分。

另一方面,如果 P 和 Q 表示离散随机变量的概率分布,则 Kullback-Leibler 散度被计算为总和。

Python 代码

首先,我们导入以下库。

import numpy as np
from scipy.stats import norm
from matplotlib import pyplot as plt
import tensorflow as tf
import seaborn as sns
sns.set()

接下来,我们定义一个函数来计算两个概率分布的 KL 散度。我们需要确保不包含任何等于 0 的概率,因为 0 的对数是负无穷大。

https://en.wikipedia.org/wiki/Binary_logarithm

def kl_divergence(p, q):return np.sum(np.where(p != 0, p * np.log(p / q), 0))

均值为 0 且标准差为 2 的正态分布与均值为 2 且标准差为 2 的另一分布之间的 KL 散度等于 500。

x = np.arange(-10, 10, 0.001)
p = norm.pdf(x, 0, 2)
q = norm.pdf(x, 2, 2)plt.title('KL(P||Q) = %1.3f' % kl_divergence(p, q))
plt.plot(x, p)
plt.plot(x, q, c='red')

如果我们测量初始概率分布和另一个*均值为 5、标准差为 4 的分布之间的 KL 散度,我们预计 KL 散度将高于上一个示例。

q = norm.pdf(x, 5, 4)plt.title('KL(P||Q) = %1.3f' % kl_divergence(p, q))
plt.plot(x, p)
plt.plot(x, q, c='red')

值得注意的是,KL 散度是不对称的。换句话说,如果我们把 P 换成 Q,反之亦然,我们会得到不同的结果。

q = norm.pdf(x, 5, 4)plt.title('KL(P||Q) = %1.3f' % kl_divergence(q, p))
plt.plot(x, p)
plt.plot(x, q, c='red')

KL 散度越低,两个分布就越接*。因此,在 t-SNE 和高斯混合模型的情况下,我们可以通过最小化一个分布相对于另一个分布的 KL 散度来估计该分布的高斯参数。

最小化 KL 散度

让我们看看如何利用梯度下降来最小化两个概率分布之间的 KL 散度。首先,我们创建一个具有已知均值(0)和方差(2)的概率分布。然后,我们用随机参数创建另一个分布。

x = np.arange(-10, 10, 0.001)
p_pdf = norm.pdf(x, 0, 2).reshape(1, -1)
np.random.seed(0)
random_mean = np.random.randint(10, size=1)
random_sigma = np.random.randint(10, size=1)
random_pdf = norm.pdf(x, random_mean, random_sigma).reshape(1, -1)

假设我们使用梯度下降,我们需要为超参数(即步长、迭代次数)选择值。

learning_rate = 0.001
epochs = 100

就像numpy一样,在tensorflow中我们需要为变量分配内存。对于变量q,我们使用给定 mu 和 sigma 的正态分布方程,只是我们排除了指数之前的部分,因为我们正在归一化结果。

p = tf.placeholder(tf.float64, shape=pdf.shape)
mu = tf.Variable(np.zeros(1))
sigma = tf.Variable(np.eye(1))
normal = tf.exp(-tf.square(x - mu) / (2 * sigma))
q = normal / tf.reduce_sum(normal)

就像之前一样,我们定义一个函数来计算 KL 散度,它排除了概率等于零的情况。

kl_divergence = tf.reduce_sum(tf.where(p == 0, tf.zeros(pdf.shape, tf.float64), p * tf.log(p / q))
)

接下来,我们初始化GradientDescentOptimizer类的一个实例,并使用 KL divergence 函数作为参数调用minimize方法。

optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(kl_divergence)

只有在运行tf.global_variables_initializer()之后,变量才会保持我们声明它们时设置的值(即tf.zeros)。

init = tf.global_variables_initializer()

tensorflow 中的所有操作都必须在一个会话中完成。在前面的代码块中,我们使用梯度下降来最小化 KL 散度。

with tf.Session() as sess:sess.run(init)history = []means = []variances = []for i in range(epochs):sess.run(optimizer, { p: pdf })if i % 10 == 0:history.append(sess.run(kl_divergence, { p: pdf }))means.append(sess.run(mu)[0])variances.append(sess.run(sigma)[0][0])for mean, variance in zip(means, variances):q_pdf = norm.pdf(x, mean, np.sqrt(variance))plt.plot(x, q_pdf.reshape(-1, 1), c='red')plt.title('KL(P||Q) = %1.3f' % history[-1])plt.plot(x, p_pdf.reshape(-1, 1), linewidth=3)plt.show()plt.plot(history)plt.show()sess.close()

然后,我们绘制不同时间点的概率分布和 KL 散度。

KNIME 分析*台是机器学习和统计的“杀手级应用”

原文:https://towardsdatascience.com/knime-desktop-the-killer-app-for-machine-learning-cb07dbef1375?source=collection_archive---------11-----------------------

数据科学|机器学习|数据可视化

一个免费、简单、开源的数据工具?是的,请!

免责声明:

我现在在 KNIME 工作,是一名数据科学家/数据工程师!大约在我申请 KNIME 的一年前,我写了这篇文章。这篇文章的标题和内容是(现在仍然是)我的个人观点。

史蒂文·波特

如果您以任何身份处理数据,请继续并帮自己一个忙:在此下载 KNIME 分析*台。

More data science, less slamming of the mouse and keyboard.

什么是 KNIME 分析*台?

KNIME Analytics Platform 是我迄今为止发现的最强大、最全面的拖放分析、机器学习、统计和 ETL 免费*台。既没有付费墙也没有锁定功能的事实意味着进入的障碍是不存在的。

所有主要提供商都可以使用数据源连接器(内部和云上),从而可以轻松地在不同环境之间移动数据。SQL Server 到 Azure?没问题。谷歌床单到亚马逊红移?当然,为什么不呢?应用机器学习算法并过滤/转换结果如何?你被保护了。

Big data? Small data? Doesn’t matter too much provided that your computer has a solid CPU and 16+ GB RAM.

同样值得一提的是,该社区非常活跃。KNIME 的开发人员和产品负责人是一个很好的合作伙伴,论坛非常活跃。

我可以深入快速入门教程或展示一些更高级的功能,但老实说,它使用起来非常直观。文档直接集成到桌面客户端,用户界面非常简单,UX 很好地融合了复杂性/可定制性(如果需要)和用户友好性。

我可以用 KNIME 分析*台做什么?

KNIME 分析*台非常适合以下情况:

  • ETL 过程(将数据从这里移动到那里并清理)
  • 机器学习
  • 深度学习
  • 自然语言处理
  • API 集成
  • 交互式视觉分析(某种程度上是测试版功能)

有什么条件?

KNIME 分析*台是 100%免费的。在 knime.com 的可以很容易地获得文档,并且有很多对*台的免费扩展。只要你是每次程序运行时点击“Go”的那个人,你就不用付一分钱。永远不会。这就是使用植根于学术界的软件包的好处。

如果您想安排工作流,KNIME Server 是一个高级产品,它允许在其他特性中安排进程。基本层 KNIME Server Small 在 AWS 上的价格大约是每小时 1.67 美元。如果您在 EC2 实例上托管 KNIME 服务器,并安排一个 cron 作业来打开和关闭实例,这是一个 非常 划算的选择。

KNIME 服务器的更高层允许使用 REST API 和 WebPortal 。这些功能允许您自动部署工作流,从另一个服务远程执行工作流,并为用户创建一个交互式中心。自动化工作流的能力使 KNIME Server Medium 成为一个有吸引力的选择。如果您购买了带有 BYOL 选项的最高层(KNIME Server Large ),那么您就可以使用同一个许可证来托管服务器的多个实例。

我如何学习 KNIME 分析*台?

他们的学习页面是这里是,但是如果你精通数据,那么只需下载该*台并尝试一两件事。只要将一些数据加载到应用程序中,剩下的就很直观了,可以从应用程序中访问文档。将节点从“节点资源管理器”拖到视图上。有一个搜索栏…尝试搜索“Excel”并从那里开始。

针织和建议

原文:https://towardsdatascience.com/knitting-and-recommendations-b9d178a86c97?source=collection_archive---------12-----------------------

计算机如何思考:第三部分

事实证明,我对编织所知不多。回过头来看,我想当然地认为我可以在几个小时的网上浏览中获得对如此复杂的领域做出有意义的陈述所需要的所有知识,这看起来太天真了。认为一个好的数据集和一个智能算法可以完全取代专家知识是一种危险的傲慢,但这种想法太普遍了。它源于对数学解决复杂问题的能力的乐观信心,以及对“硬”工程和数学问题相对于“软”社会和人际问题的相对复杂性的一种沙文主义。它导致了许多构想拙劣的初创企业,以及许多用手机应用解决棘手社会问题的善意尝试。幸运的是,我自己对盲目无知的尝试的风险大大降低了。

我这篇文章的计划是演示两种推荐算法。推荐可能是最常见的,也绝对是人工智能在当今互联网上最明显的表现。大型在线零售商试图从浏览器中榨取尽可能多的钱,通过向你展示表面上相关的商品来诱惑你额外购买。在线内容提供商试图让你留在他们的网站上,用另一篇文章或视频提示你,他们猜测是一个类似的主题。音乐网站在提供好的推荐方面做了也许是最深的投资。当使一首歌伟大而另一首歌糟糕的因素如此模糊不清、不可捉摸时,理解音乐品味的复杂性是他们都在竞相解决的问题。

广义来说,推荐算法就是计算相似度。他们从用户喜欢的一个或多个项目中进行推断,以找到用户也会喜欢的一组类似项目。就他们如何计算这种相似性而言,大多数推荐系统分为两大类。第一个可能是最明显的。“基于内容”的推荐假设两个项目相似,如果它们具有相似的质量。要进行基于内容的推荐,你需要对你推荐的东西有很多了解。如果你推荐的东西具有清晰、可比较和可量化的属性,那就很容易了。例如,比较一台冰箱和另一台冰箱是很简单的:大小、瓦数、是否有冷冻室、冰块制造机等等。将冰箱比作搅拌机更困难。基于内容的推荐也经常错过更微妙的环境。如果你最*购买了一台冰箱,该算法可能会假设你一定非常喜欢冰箱,因此你想开始收集它们。

第二种算法叫做“协同过滤”,更加微妙。它假设如果同样的人喜欢两个东西,那么它们是相似的。换句话说,如果你和我都喜欢冰箱,我们都喜欢搅拌机,那么这意味着,在某种程度上,冰箱和搅拌机必须有一些共同点。显然,如果你只看两个人的样本,这种方法会有相当大的误差。你和我碰巧对乡村音乐和自然纪录片都有热情,这并不意味着这两件事之间有很强的联系。但是有了足够多的人,它变得非常可靠。通过汇总大量用户的意见,虚假连接往往会被大量更有意义的连接所淹没——一般来说,购买冰箱的人也更有可能看搅拌机,而不是看弧焊机。在识别难以标记的微妙文化标记方面,这些算法通常比基于内容的方法好得多。由于这个原因,它们经常被用来推荐音乐或电视节目。例如,对于基于内容的算法来说,甲壳虫乐队和门基乐队之间的区别可能很难解析。他们都是 20 世纪 60 年代的四人流行乐队。他们拥有基本相同的乐器,相似的乐观声音,他们都不幸在职业生涯后期涉足迷幻音乐。只考虑这些事实的算法可能会假设这两组非常相似。但是披头士的粉丝不太可能乐意听到 Monkees 出现在他们的播放列表中。一种协同过滤算法能够检测到这些差异——可能会建议一些听起来与披头士很不一样,但有相似粉丝群的歌曲。协同过滤算法有几个弱点。首先,他们依赖用户行为的事实意味着他们容易过度解读异常的离群值。少数有不寻常习惯的用户有时会以不可预知的方式歪曲数据。其次,与第一点相关的是,在他们能够提出合理的建议之前,他们需要与一个新项目进行大量的互动。只有少数用户看到过的项目会有一个基于小数据集的建议,因此可能会反映这一小部分用户的特质。这被称为“冷启动问题”,因为算法需要大量数据来“预热”以提供良好的推荐。

记住这两个算法,让我们回到我尴尬的失败。为了演示这两种推荐方法,我需要一个大型的项目数据集、关于这些项目的一些属性的信息(形成基于内容的算法的基础),以及关于用户及其与这些项目的交互的信息(构建协作过滤算法)。在网上搜索了一段时间,并与一些朋友交谈后,我选择了 Ravelry,一个分享针织图案的网站,作为我的数据来源。Ravelry 可能是互联网上最大的针织和钩针图案在线收藏,其广大用户全年在世界各地上传、评论、分享、下载和保存数十万种图案。他们收集了大量我需要的数据。一封非常大胆的电子邮件之后,Ravelry 非常乐于助人的人给我提供了下载我需要的数据的方法。

Thanks, Ravelry!

现在。这是我应该停下来的地方。盘点一下。思考我正在着手的项目,对我的专业知识进行诚实的评估,并寻求一些专家的帮助。读者,我没有。这件事的后果直到很久以后才变得明显。

为了帮助用户在他们的网站上找到模式,Ravelry 记录了大量的“元数据”。这包括图案的“难度等级”,关于风格的关键词,图案是针织还是钩编,是套头衫还是手套,以及一大堆更模糊的指标。出于我们的目的,这将形成“基于内容”算法的基础。我们要建立一个算法,可以根据一个针织图案的元数据,找到另一个相似的图案。忽略网站上提供的更深奥的信息,我下载了几百个模式的最重要的度量,并开始准备数据。

以下是图案的主要特征——在这种情况下是可爱的针织毛绒玩具——出现在 Ravelry 网站上的方式:

Mr. Dangly, in a contemplative mood

姓名:“丹格里先生”

类别:动物

难度:1.9

工艺:针织

关键词:条纹、接缝、文字图案、加工*面

要将这一团关于针织图案的非结构化信息转化为适合我们算法的数据集,需要一系列数学技巧和转换。首先,除了“困难”之外,所有这些数据都是英语单词的形式,这些单词对计算机的意义就像一串二进制 1 和 0 对你和我的意义一样。我们的首要任务是将这些单词转化为数字。为了做到这一点,我们使用了一种叫做“一键编码”的技巧。

一键编码因电子工程中的一项技术而得名。假设您有一台机器,它可以处于两种状态之一:开或关。你可以很容易地用一盏灯来指示机器的状态。如果灯亮着(或“热”),则机器启动。如果灯关了,机器也关了。但是如果机器有三种状态呢?说,开,关,还有“预热”。现在显示机器的状态就更复杂了。你需要第二盏灯。没有灯意味着机器关闭,第一盏灯意味着机器正在预热,如果第二盏灯亮着,则机器准备就绪。如果两盏灯都亮着,你的机器有问题。对于你的机器可能处于的每一种状态,你都需要增加一个额外的灯。这不是最有效的信息编码方式——如果机器非常复杂,你需要很多灯——但它的优点是可靠性。很难意外地发出错误状态的信号,并且很容易判断是否出了什么问题——一次有多个灯亮着。

我们可以使用相同的技术来编码我们的类别数据。我们有一个单列的数据,每行表示几个类别中的一个,而不是一个可以处于不同状态的机器。我们不使用灯光,而是将单列数据转换成多列,每一列对应一个类别,“围巾”、“套头衫”、“无檐帽”、“羊毛衫”、“围巾”等。对于每一行,所有这些列的值都是零,除了与我们的项目类别相对应的列,它被设置为 1。我们可以通过查看哪一列的值为 1 来确定数据集中每一项的类别。

关键字数据——如“fringe”、“granny-squares”等——基本上得到相同的处理:每个可能的关键字对应一列,如果该项目不包含该关键字,每行包含 0,如果包含该关键字,则包含 1。这创建了一个非常“宽”的表,有许多列。我们的填充朋友,上面的 Dangly 先生,可能(部分)由我们表中的以下行表示:

现在我们已经对这些数据进行了编码,我们可以用它来进行基于内容的推荐。

这类推荐本质上是关于计算相似度的。我们想找到与丹格里先生最相似的模式。为此,我们将使用一种叫做“欧几里德距离”的度量。

欧几里德距离测量距离就像我们在现实生活中测量距离一样——两点间直线的长度。正如我们可以计算地图上两组经纬度坐标之间的距离一样,我们也可以计算表格中两行数值数据之间的距离。如果我们想象我们的数据集只有两列,这很容易想象,“困难”(2 代表丹格里先生),和“动物”(1 代表丹格里先生,他是一只猴子)。我们可以将它绘制在二维图表上,并将其与其他三种假设模式进行比较:“狡猾先生”——一种填充动物,像丹格利先生一样,但制作起来更复杂,难度等级为 3;“易跳投”——像丹格利先生一样容易制作,但不是填充动物玩具;还有“狡猾的手套”——一点也不像丹格利先生,既不容易制作,也不是毛绒动物。

这些假设模式的数据如下:

当我们在二维图表上绘制时,距离计算变得很清楚:

Figure 1: Euclidean distances

丹格利先生和其他三种模式之间的欧几里德距离实际上是它们之间的直线长度,就像你用尺子测量它一样。“狡猾的手套”,由于有一个更长的对角线,丹格里先生,有最大的欧几里德距离,是最不相似的。“轻松跳投”和“狡猾先生”离丹格利先生同样遥远——它们同样相似。

关于欧几里德距离的有趣而又令人困惑的事情是,这个计算适用于任何数量的额外维度。您可以想象在这个图表中添加第三个高度轴,代表其中一个关键字。对于那些不共享关键字的模式,三维空间中的线会更长。(至少对我来说)在三维以上的空间中想象这一点变得越来越困难,但我确信数学是完全正确的,实践证明了这一点。

这张图表也暴露了这种方法的一个问题。你会注意到从丹格里先生到“狡猾先生”和“容易跳楼者”的欧几里得距离是完全相等的。我们的算法假设这两种模式都与丹格利先生相似,都是同样好的推荐。这是一个好的假设吗?一个难度点的区别就相当于一个毛绒动物和一个跳楼者的区别吗?直觉上,感觉是没有。但是我怎么知道呢?如果这两个差别不是一个量级,那么差别有多大?与类别差异相比,我应该给难度差异多少权重?我完全没有资格回答。这是我选择寻求一些外界帮助的时候(太晚了),这样我就能更多地了解编织者是如何选择图案的。结果是…令人羞愧。

事实证明,我之前丢弃的所有晦涩难懂的指标,比如“纱线重量”、“针距”和“码数”,实际上对许多针织者来说至关重要。我是个傻瓜!针织者通常会寻找与现有纱线搭配的图案,而不是为每个图案购买新的纱线。这意味着她们对图案的选择常常受到制作图案所需纱线种类的限制。将它们排除在我的算法之外意味着它生成的建议通常表面上可以接受,但根本不能反映编织者的实际偏好。

为了解决这些问题,首先我不得不回到数据的来源,诅咒自己,重新下载所有数据,包括我现在意识到对分析至关重要的额外指标。然后,在咨询了我匆忙招募的针织专家后,我创建了权重——一个衡量每个指标的值,以反映它对针织者选择图案的重要性。有了这些改进,我可以提出对真正的编织者有意义的建议。

最终的算法主要考虑图案的工艺(无论是针织、钩编还是其他)、类别、纱线重量和难度。但它也考虑了关键词、针规格和许多其他因素。对于其中的每一个,它都会计算出模式之间的“距离”。他们的共同点越多,距离就越小。

The “Spring Collection”

对于上面的毛绒玩具猴子 Dangly 先生,该算法推荐了“春季系列”,一套毛绒玩具图案,包括刺猬、青蛙、兔子和羔羊。它们同样易于编织,采用了相似的技术——有接缝的结构和流苏的使用(丹格里先生用的是一簇整洁的头发,春季系列用的是刺猬的刺)。从很多方面来说,这都是一个非常好的推荐。但是有些事情不太对劲。丹格利先生有一种怪癖,某种程度的奇思妙想或风格使他脱颖而出。相比之下,虽然表面上与丹格利相似,但春季系列缺少他的独特魅力。它们似乎有点乏味,而且有点甜。我觉得丹格利先生的朋友不太可能和春季系列的成员相处融洽。该算法提出了一个理论上正确的建议,但它忽略了模式的一些细微差别。它错过了一些人类看不到的东西。它忽略了他们的个性。

这使得协作算法试图做得更好。协同过滤算法与基于内容的算法非常不同。我们的基于内容的算法使用关于模式本身的元数据,而协作过滤方法关注与这些模式交互的的信息。Ravelry 允许用户“喜爱”图案,并存储他们喜爱的列表。这些列表是公开的,这意味着我可以下载几十万个 Ravelry 用户的“最爱”模式列表。就个人而言,这些列表是独特的,信息不多。喜欢厚针织围巾的人可能也对新奇的茶具感兴趣,这不应该暗示我们关于围巾或廉价家居装饰的任何事情。但总的来说,在我能够从 Ravelry 检索到的各种卷中,这些信息确实变得非常有用。因为协同过滤使用了关于人类行为和偏好的相对更复杂和微妙的信息,我希望我能够更准确地捕捉到难以捉摸的丹格利先生的一些信息。

尽管数据量要大得多,但在许多方面,这种算法构造起来要简单得多。基于内容的算法使用一个数据集,其中每一列代表模式的某个方面,而对于协作算法,我构建了一个数据集,其中每一列代表一个用户,每一行的值反映了该用户是否“偏爱”该模式:

有了这个数据集,我们可以用与基于内容的算法完全相同的方式来计算相似性。在欧几里德距离计算中,每个用户是一个“维度”。相同用户喜欢的模式被认为是相似的。

在我看来,这个算法的第一个结果并不乐观。根据算法,一个小小的针织钱包非常类似于一条花边毛巾。一双编织袜子类似于一条精致的披肩。这毫无意义,直到我与我的编织专家交谈,他们指出了我未经训练的眼睛所忽略的更微妙的相似之处。钱包和毛巾都是小项目,使用各种各样的技术和模式,一个新的编织者可以用来发展他们的技能。袜子和围巾都使用了两种颜色的细纱线,这可能是那些想要用完现有羊毛库存的人的首选。但是其他的建议甚至让我的专业编织者也感到困惑。交互很少的模式——新模式或模糊模式——往往会得到特殊的或明显错误的推荐,算法的产品几乎没有任何信息来作为其相似性计算的基础。这是协作算法的一个弱点,即“冷启动问题”。有一些数学技巧可以用来解决这个问题,我最终使用了很多这些技巧(我不会在这里详细讨论它们),但如果没有良好的用户交互,该算法对任何项目的推荐都很差。

The Socktopus

但是我们的朋友丹格里先生怎么样了?幸运的是,丹格里先生独特的魅力已经为他赢得了足够的关注,并为他提供了一系列的建议。领先推荐是合作推荐优势的理想例证。“Socktopus”顾名思义就是穿袜子的章鱼。他很容易制作,并使用了一些与丹格利先生相似的技术,但也缺少丹格利先生的一些特征——没有接缝,没有边缘。但至关重要的是,Socktopus 与 Dangly 先生有着相同的古怪风格和个性。协作算法发现了一些基于内容的算法没有发现的东西——不仅仅是原始信息,还有人们如何将这些信息联系起来。它能理解它们的的含义

出于这个原因,协作算法非常受任何试图推荐复杂文化产品的人的欢迎,无论是书籍、电影、音乐,甚至是针织图案。但是,当在线*台广泛使用协作推荐来指导他们向用户展示什么内容时,他们有可能成为这种算法的另一个致命弱点的受害者。协作算法非常擅长发现项目之间的微妙联系,擅长定义品味的界限。他们可以区分音乐的子流派,所以死亡金属的粉丝永远不会因为听到毁灭金属(我敢保证,这是完全不同的事情)而被冒犯。他们可以很好地解析新闻文章的主题,这样那些关注他们当地运动队的人就不会被当地的政治所困扰。但是这种边界管理是有代价的。它们可以产生“泡沫”效应。

气泡效应是指用户只看到更大的内容池中的一小部分,而永远不会意识到他们那一小部分之外的任何东西。当一个算法由用户交互的内容驱动,而用户只看到算法展示给他们的内容时,就存在一个反馈回路。用户与展示给他们的东西互动,他们也与展示给他们(或喜欢他们的用户)互动的东西互动。如果不小心,用户会发现自己被包裹在“安全”内容的茧中,只能看到相同种类的内容。从商业上来说,这是在线*台的一个风险。如果用户从来没有发现他们可能喜欢的新东西,如果他们从来没有机会扩展他们的口味,他们会感到厌倦并继续前进。但这也有更微妙的社会风险。在反馈循环中,人们只看到符合他们口味的内容,他们同意的内容,符合他们现有世界观的内容。遇到挑战你对世界的信念的事情是令人不快的;听你不喜欢的音乐,看关于你不了解的事情的电影,或者读关于可怕事件的新闻。但是,遇到并试图理解新的和具有挑战性的事情是我们如何学会适应和与不同于自己的人合作。通过把自己与志同道合的人隔离开来,只看到我们喜欢的东西,我们把自己与更广阔的世界隔离开来。

当你对某件事了解不多的时候,很容易做出假设。我低估了针织及其爱好者的复杂性和细微差别。我以前从未真正遇到过这种情况,这种无知暴露出来让我很不舒服。协作式和基于内容的推荐算法都只能从过去看到的内容中推断出模式。他们和我一样,倾向于根据他们已经知道的东西做出假设。这不是算法本身的问题——数学是无可指责的。问题在于构建算法的人和使用算法的人。我对基于内容的算法的失败在于,我认为大量的数据和一些巧妙的数学运算足以理解一个复杂的领域。协作算法的风险更加微妙,但它们也源于一种傲慢,一种我们可以完全预见用户需求的信念,这种信念就像找到他们已经喜欢的东西一样简单。在这两种情况下,拥抱复杂性,并采用更全面的方法,可以帮助减轻这些风险。

这是我们在之前的算法中看到的主题,我们将在未来的文章中再次看到。这是机器学习算法的一个共同特征。它们只和用来创建它们的数据一样聪明。如果他们要真正学习,真正创造新的东西,而不仅仅是反映我们现有的知识和偏见,那么我们必须教他们。我们必须正视我们的无知。我们必须学习。

本系列上一篇,《线性回归与数列》可用 此处 。本文的代码可以在我的 github 中找到, 这里 。下一篇文章将于 4 月发表。

制作自己的 丹格利 Socktopus,前往www.ravelry.com(账号必填)。

仅用 13 行代码实现 KNN 可视化

原文:https://towardsdatascience.com/knn-visualization-in-just-13-lines-of-code-32820d72c6b6?source=collection_archive---------5-----------------------

是啊!就这么简单。让我们用数据集来想象当“k”变化时,决策边界是如何变化的。

让我们快速回顾一下…

K-NN 是什么?它是如何工作的?

k 最*邻(KNN)算法是一种非常简单、易于理解、通用性强的机器学习算法。在 k-NN 分类中,输出是一个类成员。通过其邻居的多个投票对对象进行分类,将该对象分配到其 k 个最*邻居中最常见的类别(k 是正整数,通常很小)。如果 k = 1,那么该对象被简单地分配到该单个最*邻的类中。

在 KNN,K 是最*邻居的数量。邻居的数量是核心决定因素。如果类的数量是 2,k 通常是奇数。当 K=1 时,该算法称为最*邻算法。这是最简单的情况。假设 P1 是需要预测标签的点。

Basic steps in KNN.

KNN 有三个基本步骤。
1。计算距离。
2。找出 k 个最*的邻居。
3。为班级投票

K 的重要性

你不能为 k 取任何随机值,整个算法都是基于 k 值的。即使对 k 的微小改变也可能导致大的变化。像大多数机器学习算法一样,KNN 的 K 是一个超参数。您可以将 K 视为预测模型的控制变量。

在这篇博客中,我们将看到决策边界如何随 k 变化。为此,我将使用不同类型的玩具数据集。你可以很容易地从下面的链接下载所有这些数据集。

[## 可视化 KNN

下载数千个项目的开放数据集+在一个*台上共享项目。

www.kaggle.com](https://www.kaggle.com/deepthiar/toydatasets)

了解数据集

  1. u 形的

在这个数据集中,我们可以观察到这些类是一个互锁的 u 形。这是一个非线性数据集。
蓝色点属于 0 类,橙色点属于 1 类。

2.两组同心圆

在这个数据集中,我们可以看到这些点形成了两组同心圆。这是一个非线性数据集。
蓝色点属于 0 类,橙色点属于 1 类。

3.异或运算

该数据集类似于 2 变量 XOR k 图。这是一个非线性线性数据集。

蓝色点属于 1 类,橙色点属于 1 类。

4.线性可分的

这是一个线性数据集,其中的点可以线性分离。

蓝色点属于 0 类,橙色点属于 1 类。

5.极端值

在这个数据集中,我们可以观察到两个类中都有异常点。我们将看到异常值的存在如何影响决策边界。这是一个线性数据集。
蓝色点属于 0 类,橙色点属于 1 类。

现在,我们知道了我们的外观,我们现在将继续下去,看看决策边界如何随着 k 值的变化而变化。在这里,我将 1,5,20,30,40 和 60 作为 k 值。您可以尝试任何一组值

首先,让我们导入库。

import matplotlib.pyplot as plt
import pandas as pd
from sklearn import datasets, neighbors
from mlxtend.plotting import plot_decision_regions

需要以下核心功能。

def knn_comparison(data, k):x = data[[‘X’,’Y’]].valuesy = data[‘class’].astype(int).valuesclf = neighbors.KNeighborsClassifier(n_neighbors=k)clf.fit(x, y)# Plotting decision regionplot_decision_regions(x, y, clf=clf, legend=2)# Adding axes annotationsplt.xlabel(‘X’)plt.ylabel(‘Y’)plt.title(‘Knn with K=’+ str(k))plt.show()

你可以观察到它只是一行代码,做了所有的事情—
clf = neighbors。KNeighborsClassifier(n _ neighbors = k)

就是这么简单优雅。现在,我们只需加载我们的 CSV 文件,并将其与 k 一起传递给该函数。我们将对所有数据集逐一执行此操作。

让我们开始吧…

1.u 形

data1 = pd.read_csv(‘ushape.csv’)
for i in [1,5,20,30,40,80]:knn_comparison(data1, i)

KNN visualization for the U-shaped dataset

2.两组同心圆

data2 = pd.read_csv(‘concertriccir2.csv’)
for i in [1,5,20,30,40,60]:knn_comparison(data2, i)

KNN visualization for the two concentric circles dataset

3.异或运算

data3 = pd.read_csv(‘xor.csv’)
for i in [1,5,20,30,40,60]:knn_comparison(data3, i)

KNN visualization for the XOR dataset

4.线性可分的

data4 = pd.read_csv(‘linearsep.csv’)
for i in [1,5,20,30,40,60]:knn_comparison(data4, i)

KNN visualization for the linearly separable dataset

5.极端值

data5 = pd.read_csv(‘outlier.csv’)
for i in [1, 5,20,30,40,60]:knn_comparison(data5, i)

KNN visualization for the outliers dataset

观察结果:

在所有数据集中,我们可以观察到,当 k=1 时,我们过度拟合模型。也就是说,每个点都被正确分类,你可能会认为这是一件好事,正如俗话所说的“太多太坏”,过度拟合本质上意味着我们的模型训练得太好,以至于对模型产生负面影响。

在所有的数据集中,我们可以观察到当 k = 60(一个很大的数字)时,我们对模型拟合不足。欠拟合指的是既不能对训练数据建模也不能推广到新数据的模型。欠拟合的机器学习模型不是合适的模型。在离群数据集的情况下,对于 k=60,我们的模型做得相当好。我们怎么知道这个?因为我们知道那些点是异常值,数据是线性可分的,但并不是每次都是这样,我们无法确定。此外,在 XOR 数据集中,与其他模型不同,k 的值不会在很大程度上影响模型。

研究表明,不存在适合所有类型数据集的超参数(k)的最佳值。每个数据集都有自己的要求。在小 k 的情况下,噪声将对结果具有更高的影响,而大 k 将使其计算代价昂贵。研究还表明,小 k 是最灵活的拟合,它将具有低偏差但高方差,而大 k 将具有更*滑的决策边界,这意味着较低的方差但较高的偏差。

过拟合和欠拟合是机器学习算法性能差的两个最大原因。

结论:

当 K 较小时,我们会限制给定预测的区域,并迫使我们的分类器对整体分布“视而不见”。K 值越小,拟合越灵活,偏差越小,但方差越大。从图形上看,我们的决策边界将会像上面观察到的那样更加参差不齐。另一方面,K 值越高,每次预测的*均点数越多,因此对异常值的适应能力越强。K 值越大,决策边界越*滑,意味着方差越低,但偏差越大。

参考

  1. www . data camp . com/community/tutorials/k-nearest-neighbor-class ification-sci kit-learn
  2. scott.fortmann-roe.com/docs/BiasVariance.html
  3. rasbt . github . io/mlx tend/user _ guide/plotting/plot _ decision _ regions/# references

你还在等什么?继续玩数据集吧!!

了解分类编码,甚至是新的编码!

原文:https://towardsdatascience.com/know-about-categorical-encoding-even-new-ones-c266227b9cbd?source=collection_archive---------7-----------------------

对分类数据进行编码会对 ML 模型的性能产生影响。在本文中,我将向您介绍广泛的编码方法:最常用的和最*使用的。****

Photo by Patrick Fore on Unsplash

介绍

在数据科学问题中,数据集通常会包含分类特征。分类变量通常包含固定数量的可能值。
这些值中的每一个都被称为一个电*。 与分类变量相关的概率分布称为分类分布(伯努利或多项式分布)。

不幸的是,大多数机器学习算法无法处理分类特征。因此,我们必须对这些变量进行编码,以收集尽可能多的信息。

本文旨在介绍其中的一些方法。在处理更复杂的方法之前,我们先介绍一种简单的技术。

方法列表:

  • 一键编码
  • 标签编码
  • 目标编码
  • 特征散列
  • 证据的重要性
  • 轻型 G-Boost 编码

一键编码

独热编码包括为给定定性变量的每个类别生成一个布尔列

一键编码的限制

一键编码是对分类变量的一种非常流行的转换。然而,它增加了数据的维度(维度的诅咒)。
当数据集中的定性变量有多种模态时,通过一键编码进行的转换将导致大小显著增加。这是不可取的,尤其是当原始数据集已经很大的时候。

标签编码

标签编码就是用一个介于 0n_classes -1 之间的值来替换一个类别值的过程(类别数)。然后,机器学习算法可以更好地决定应该如何操纵这些标签。

标签编码的限制

这里的问题是模型可能会误解数据。
事实上,通过应用标签编码,分类特征可以被视为连续特征。

这种方法的另一个限制是,具有高值的标签可能被认为比具有较低值的标签具有更高的优先级。

目标编码

目标编码是指通过用特定目标的后验概率和训练数据上所有目标的先验概率的混合来替换特征,从而将标签转换成数字形式。
好像我们在为每个目标值计算类别的频率。

标签编码的局限性

这种方法的主要缺点是它依赖于目标的分布,并且它的预测能力低于二进制编码方法。

特征散列

特征哈希,被称为哈希技巧,是降维和实用非参数估计的有效策略。

但是,在我们深入这个方法的定义之前,我们将解释一下数组链表的一些基本概念。

  • 数组: 数组是具有固定大小的项目集合。所有元素都有索引,我们使用索引来访问数组中的特定项。****

https://o7planning.org/fr/11567

  • 链表:
    链表是数据元素的线性集合。当您不想担心数组大小时,这是一种非常流行的数据结构。
    链表可以
    动态增长
    。我们简单地将下一个元素的地址存储在前一个元素中。这样,我们就可以把它长到任何大小。但是我们总是需要以一种
    顺序的方式从一个元素到另一个元素。********

https://hackernoon.com/implementing-singly-linked-list-with-ruby-om2df3ya6

这些概念构成了方法散列技巧的基础。

顾名思义,我们将一个散列函数应用于特性,并直接使用它们的散列值作为索引,而不是在关联数组中查找索引。

现在,我们将逐步解释“特征散列”算法😗***

1 — MOD 功能:

我们为什么使用 MOD?我们需要创建一个散列表来存储 MOD 值。提醒指示了索引号,我们可以将分类值(蓝色))存储在散列表中。**

2-哈希表:

我们使用散列位大小来指定创建散列表时使用的位数。例如,在我们的例子中,我们有 MOD 8,那么比特大小是 8。

如果我们对“blue”的哈希值 7 进行 mod 8,它会将值“Blue”存储在哈希表的索引 7 中,如下所示。

有时候,我们会遇到碰撞的问题(比如“蓝色”&“绿色”),所以我们可以通过使用分离链接来解决这个问题,分离链接是链表的组合。

3-单独链接:

在上面的例子中,我们需要在索引 7 中插入单词“Blue”和“Green”。因此,我们简单地在散列表的索引 7 中创建一个链表。

数组链表的组合称为分离链接。****

3-特征散列:

综上所述,我们首先需要找出分类值(颜色)的哈希值。然后,我们对哈希值应用 MOD 函数,得到这些数字的提示。最后,我们创建新特性集,并用相应的值填充表格。

有用的小技巧!

通常,我们在文本挖掘中使用哈希技巧,我们可以将可变长度的文本文档表示为等长的数字特征向量,并实现降维。

下面我们来对比一下单词袋法和哈希法
单词包创建稀疏的特征矩阵。然而,特征散列技术可以用较少数量的特征构建预定义长度的向量。

散列位大小取决于训练集中类别的数量或 n 元语法词汇的大小。如果词汇表很大,可能需要更多的空间来避免冲突。****

证据的重要性

证据权重(WOE)的目标是有效地识别分类预测值列表的证据权重值的最佳记录,并为每个类别分配唯一的证据权重值。

证据权重可用于组合变量组/级别,这个过程称为粗分类。我们组合具有相似 WOE 的类别,然后用连续的 WOE 值替换这些类别。

现在,通过取非事件的百分比与事件的百分比之比的自然对数来计算 WOE。

证据权重(WOE)是为信贷金融部门开发的,主要用于创建预测贷款违约风险的更好模型(信贷风险模型)。

有一个经典的例子来突出 WEO 方法,在这里我们可以通过测量“信用评分来区分好客户坏客户。WOE 公式表示为:

  • 商品的分布——集团内良好顾客的百分比
  • 不良分布——不良客户在一个组中的百分比

分类转换:

对于分类变量,我们计算每组中事件和非事件的数量和百分比。然后,我们通过取非事件百分比和事件百分比的自然对数来计算权重。

我们将举一个的例子来说清楚。

在本例中,我们有一个分类变量(“特征”)和三个组(“A”、“B”和“C”)以及一个二元目标变量(“结果”)和两个类( 1 和 0 )。
我们将目标变量中的 2 个类视为“事件”(类 1)和“非事件”(类 0)。然后我们计算 WOE 值,如下所示。****

转换变量将是一个具有 WOE 值的连续变量。

信息价值:

通常,我们将证据权重与信息值相关联,该信息值表示用于将事件与非事件分开的变量的信息量。这有助于根据变量的重要性对其进行排序。
使用以下公式计算 IV:

我们计算上例中的 IV 值:

信息值相关规则:

在本例中,“特征”变量的 IV 值为 0.221 ,则该预测因子与事件/非事件比值比具有中等强度关系。

https://www.listendata.com/2015/03/weight-of-evidence-woe-and-information.html

有用的小技巧!

WOE 转换的优点是:

  • 处理缺失值
  • 处理分类变量,因此不需要虚拟变量。
  • 该变换基于分布的对数值。这与逻辑回归输出函数一致

对于分类预测器,我们可以组与相似的观察值权重组合,以创建具有连续证据权重值的新编码预测器。

为什么要合并具有相似 WOE 的类别?具有相似权重的类别具有几乎相同的事件和非事件比例。换句话说,两个类别的行为是相同的。

轻型 G-Boost 编码

首先简单介绍一下 Light-GBM (光梯度提升)。

什么是梯度增强?

这是一种升压算法,使用梯度下降法将损耗降至最低。我们所说的增强是指将一组弱学习者结合起来形成一个强规则。这是一个反复的过程。

为什么很轻?

Light GBM 是一个快速、分布式、高性能的梯度推进框架。与其他 boosting 算法不同的是,它按叶方式而不是按层方式分割树。LGBM 跑的非常快,所以才有了“这个词。******

分类特征支持:

LightGBM 可以直接使用分类特征(没有独热或标签编码)。它有一种独特的方式来处理分类变量。

LGBM 应用 Fisher 的 方法来寻找类别上的最优拆分

我们经常用一键编码来表示分类变量,但最佳解决方案是通过将分类划分为 2 个子集来分割分类特征。
如果特征有 k 个类别,则有
个 2^(k-1)-1** 个可能的分区。然后我们需要找到最佳分区。**

LightGBM 实现了独占特性捆绑(EFB)** 技术,该技术基于( D. Fisher,1958 )的研究,以找到类别的最佳分割。**

独家功能捆绑:

给定一组类别,将它们分组以使组内的差异最小化的实用程序是什么?
这里,注意力将被限制在原始类别到组中的各种可能的组合,假设在每个组内按比例分配。

因此,为了找到最佳分组,计算每个可能的2^(k-1-1分区的 D 值就足够了。

N : 一个分区中元素的数量。
w_i :元素 I 的权重
a_i : 元素 I 的数值度量

D 被称为 最小二乘划分 ,其代表与一般*均值的*方偏差之和。为了找到最佳分割,我们选择具有最小 D 值的分区。

有用的小技巧!

轻量级 GBM 支持分类变量,它的方法对于树学习者来说是次优的。

这种方法通常比一键编码执行得更好。
此外,在具有高基数的分类特征的情况下,建立在独热特征上的树往往是不*衡的,并且需要增长得非常深以实现良好的准确性。

leaf-wise 方法(Light GBM 使用)的一个缺点是,当数据很小时,它可能会导致过度拟合。

总结:

在机器学习中,我们通常处理在一列或多列中包含多个标签的数据集。这些标签可以是分类的。因此,我们必须将这些特征转换成机器可读的形式。

在本文中,我们讨论了数据科学问题中一些最常用的编码方法,如上所述。

参考

[1] Deepanshu Bhalla ,证据权重(WOE)和信息价值(IV)解释

[2] LightGBM 的文档

[3]证据权重(WoE)介绍性概述, Statsoft 网站

[4]目标编码器, Scikit-Learn 网站

脚注:

在这项研究中,我们提出了非常著名的技术,这些技术通常用于特征工程,以提高最大似然模型的准确性。

我感谢你们所有人一直和我们在一起。

感谢阅读。😃
尽情享受吧!

认识你自己:利用数据科学探索你自己的基因组

原文:https://towardsdatascience.com/know-thyself-using-data-science-to-explore-your-own-genome-ec726303f16c?source=collection_archive---------18-----------------------

熊猫和硒的 DNA 分析

“Nosce te ipsum”, (“know thyself”), a well-known ancient maxim, frequently associated with anatomical knowledge.

图片来自剑桥大学

23andme 曾经提供给我一套免费的 DNA 和血统测试工具,如果我参加他们的一项临床研究。作为一个脸颊拭子和在大量问卷中展示我的勇气和灵魂的交换,我得到了我的基因组测序,并获得了无数关于我的祖先可能来自哪里,我可能与网站上的其他人有关系,以及我可能遗传了什么健康状况和特征的报告。

Seriously?

23andme 已经提供了大量面向消费者的信息图表和工具,但我知道我可以利用这些数据做更多的事情。勇敢者可以下载他们的原始基因数据,如果他们敢的话,所以我当然把它倒在熊猫身上给看我能做什么。

望着。txt 文件,我可以看到我丢失了一些基因型值,用“—”表示。

大多数染色体是整数,但有三个是 X,Y 和 MT(代表线粒体)。我需要正确地指定数据类型,以便 pandas 在输入中发现混合数据时不会抛出错误。

其他专栏相当简单。我还想让 pandas 忽略文件开头的序言注释,这些注释由以八叉线开头的行组成。

因此,我需要传递的参数是:

  • 分隔符(制表符分隔)
  • 数据类型(作为字典)
  • na_values (' — ') (注意:为了避免和更多的 nan 打交道,我最终决定不这么做)
  • 注释(' # ')

关于列名的快速注释:

  • rsid 代表参考 SNP 簇 id。它识别独特的 SNPs。
  • SNPs 是单核苷酸多态性(“SNPs”),即个体之间不同的基因组位置。它们可以影响疾病风险和药物效果,告诉你你的祖先,并预测你的外表和行为。
  • 所有人类都有几乎相同的 30 亿个 DNA 碱基序列(A、C、G 或 T ),分布在他们的 23 对染色体之间。但是在某些地方,由于医学或其他原因(如系谱学),研究人员宣称存在一些有意义的差异。

我开始用基本的探索性数据分析和数据清理来导航我的新数据框架。

我将字母染色体转换为数字,将它们转换为整数,并创建了一个字典,以便稍后将它们翻译回来,以便我可以更好地处理数据。

一些可视化

RSIDs per chromosome

从 SNPedia 获取 SNPs 数据

为了获得更多关于我的 DNA 的信息,我从 SNPedia 获取了文件,这是一个研究人类遗传学的维基,收集了大量数据并引用了同行评审的科学出版物。SNPedia 对常见的、可重复的 SNP(或在至少 500 名患者的荟萃分析或研究中发现的 SNP)或具有其他历史或医学意义的 SNP 进行分类。

这些列是:

  • 未命名:0(实际上是 SNP 名称)
  • 量级(感兴趣的主观量度)
  • 名声(一种基于研究的基因型是“好”还是“坏”的主观衡量标准,对于血统和眼睛颜色等则为空白)
  • 摘要(叙述性描述)

正则表达式的乐趣

为了与我的原始数据框架一致,我创建了一个基因型列,并使用 regex 分离出基因型,它被缝合到 SNP 名称的末尾。

出于一致性的考虑,我重命名了这些列以匹配我的原始数据帧,并确保 rsids 都是小写的。

我也使用了正则表达式来清理 rsid(因为我会找任何借口使用更多的正则表达式)。

我重写了无效的名声和总结。

将我的数据与 SNPedia 合并

足够恰当的是,我在我的 DNA 上做了 SNPedia 数据框架的内部连接,以查看它在我的特定基因型上有什么数据,如果有的话。

里面藏着什么?

我有很多“好”的基因型,但没有一个是非零的。

我有三个非零的“坏”基因型。

可悲的是,我没有超过 4 的“有趣”基因型,尽管令人振奋的是,我有一些稍微有趣的坏基因型。

用硒刮相关物品

我决定我可能会喜欢阅读我糟糕的遗传学,所以我用 Selenium 从 PubMed 上收集了一些科学论文的摘要。

为了以后疑病症患者的阅读,我使用 pandas DataFrame.to_csv 方法将我的发现连同摘要和超链接导出到一个 CSV 文件中。

研读医学文献

现在我有了一个方便的 CSV 文件,格式很好,引用了科学文章,分析和描述了我的可能没有问题,但具有试验性的基因型。Python 提供了惊人的工具来进行文字自省,这是古代的锯骨人无法想象的。

最初发表于https://www . espritdecorpus . com/posts/using-data-science-to-explore-your-own-genome/

了解您的数据——使用散点图和预测模型为钻石定价

原文:https://towardsdatascience.com/know-your-data-pricing-diamonds-using-scatterplots-and-predictive-models-6cce92d794c1?source=collection_archive---------11-----------------------

我的上一篇文章抨击了人们经常用来分组绘制定量数据的糟糕的可视化,并将饼状图、条形图和点状图放在一起进行两种可视化任务。点状图出现在顶部。我认为这是因为与判断长度、面积、阴影、方向、角度、体积、曲率等相比,人类更擅长在一个共同的尺度上比较位置的认知任务。这一发现归功于克利夫兰和麦吉尔。我喜欢写它,人们似乎也喜欢它,所以我继续我的散点图可视化系列。

散点图

散点图是一个二维*面,我们在其上记录一组案例项目的两个测量值的交集,通常是两个定量变量。正如人类擅长在一个维度上比较普通尺度上的位置一样,我们的视觉能力允许我们在二维空间中看到一系列点时做出快速、准确的判断并识别模式。这使得散点图成为数据分析师在探索数据和向他人传达结果时的宝贵工具。

在这篇文章的第一部分中,我将展示散点图的各种用途,并概述一些策略,以帮助确保关键模式不会被数据中的规模或定性群体差异所掩盖(例如,男女测试分数和收入之间的关系不同)。这篇文章的动机是提出一个钻石价格模型,你可以用它来帮助确保你不会被敲竹杠,这个模型是基于探索性散点图结合(某种程度上)有根据的推测得出的。在第 2 部分中,我将讨论使用面板(也称为小面,也称为小倍数)来揭示数据中的关键模式,以及使用局部回归(黄土)来检查数据中的中心趋势。与我上一篇文章中嘲笑的 3D 柱状图和饼状图相比,这种可视化的糟糕例子要少得多,尽管我仍然能够找到这个可爱的散点图+趋势线。

散点图和笛卡尔坐标系

散点图比我在上一篇文章中提到的可视化有着更丰富的历史。散点图的表面形成了一个二维笛卡尔坐标系,DeCartes 在 1657 年左右发明/发现了这个同名*面,这代表了科学中最基本的发展之一。笛卡尔*面统一了度量、代数和几何,直观地描述了变量(或函数)之间的关系。在笛卡儿*面之前,数学分为代数和几何,两者的统一使许多新的发展成为可能。当然,这包括现代地图制作——制图学,但是笛卡尔*面也是微积分发展的重要一步,没有它,我们的现代几乎不可能。

散点图是帮助理解变量之间关系的强大工具,尤其是在这种关系是非线性的情况下。比方说,你想知道在购买钻石时,你支付的价格是否合适。您可以使用许多钻石的价格和特征数据来帮助确定任何给定钻石的广告价格是否合理,并且可以使用散点图来帮助确定如何以合理的方式对该数据进行建模。考虑一下钻石价格与其克拉重量(与其大小相对应)之间的重要关系:

一些事情马上就浮现出来了。我们可以看到一个非线性关系,我们还可以看到,随着克拉大小的增加,关系的离散度(方差)也增加。通过快速浏览数据散点图,我们了解到价格和克拉大小之间的两个重要函数关系。因此,我们也认识到,对这些数据运行线性模型是一个坏主意。

钻石

如果你曾经使用过 R,你可能会看到 Hadley Wickham 的 ggplot2 附带的 diamonds 数据集的引用。它记录了超过 5 万颗钻石的克拉大小和价格,从 2008 年在收集的http://www.diamondse.info/开始,如果你在市场上寻找一颗钻石,探索这个数据集可以帮助你了解商店里有什么以及价格点。这特别有用,因为每颗钻石都是独一无二的,这与我们习惯购买的大多数制成品不同——你不能只输入型号就在亚马逊上查价格。即使是专家也无法像通过数据获得的整个市场的图片一样包含那么多关于价格的信息(尽管没有什么可以替代定性专业知识来确保你的钻石是零售商声称的那样)。

但是,即使你不打算买钻石,钻石行业的社会经济和政治历史也是迷人的。钻石催生了南非的采矿业,如今南非是非洲最大、最先进的经济体。我在约翰内斯堡工作了一个夏天,我可以向你保证,南非的城市看起来更像洛杉矶和旧金山,而不是拉各斯、开罗、摩加迪沙、内罗毕或拉巴特。钻石首先驱使英国人和荷兰人殖民南部非洲,并引发了从布尔战争到塞拉利昂、利比里亚、科特迪瓦、津巴布韦和刚果民主共和国的现代战争的各种冲突,在 20 世纪 90 年代内战最激烈的时候,200 克拉的千年之星钻石被卖给了德比尔人。在 20 世纪 30 年代的“犹太财产的雅利安化”期间,钻石是犹太人可以向纳粹隐瞒的少数资产之一,国会研究服务中心报告说基地组织利用冲突钻石规避国际制裁,并从 1998 年东非爆炸案到 9 月 11 日袭击为行动融资。

虽然钻石数据集充满了价格和相当深奥的认证评级,但隐藏在数据中的是一场传奇营销活动如何渗透并被我们的文化所包容的反映,关于不同社会阶层如何反应的暗示,以及对钻石市场如何运作的洞察。

据《大西洋月刊》报道,故事开始于 1870 年,当时在南非奥兰治河附*发现了数吨钻石。在那之前,钻石很稀有——每年从印度和巴西开采的钻石只有几磅。在当时,钻石在珠宝之外没有用途,就像今天在许多工业应用中一样,所以价格只取决于稀缺的供应。因此,该项目的投资者在 1888 年成立了德比尔斯卡特尔,以控制全球价格——大多数人认为这是历史上最成功的卡特尔,直到 2000 年左右控制了全球 90%的钻石供应。但是第一次世界大战和大萧条见证了钻石销售的暴跌。

根据《纽约时报》的报道,1938 年,戴比尔斯卡特尔写信给费城广告公司 N. W .艾耶尔父子公司,调查“利用各种形式的宣传”是否会推动美国的钻石销售,当时美国似乎是唯一有潜力的市场。调查显示,钻石在大多数考虑结婚的夫妇的优先考虑清单中排名靠后——这是富人的奢侈品,“钱都打水漂了”被《纽约时报》比作《广告狂人》的佩吉·奥尔森(Peggy Olson)的弗朗西丝·格雷蒂(Frances Gerety)在 N.W .艾耶尔父子公司接管了德比尔夫妇的账户,并朝着公司的目标“创造一种局面,让几乎每个宣誓结婚的人都感到被迫购买一枚订婚钻戒。”几年后,她创造了一个口号,“钻石永恒”

《大西洋月刊》的杰伊·爱泼斯坦认为,这一活动催生了现代需求广告——其目的不是直接销售,也不是强化品牌,而仅仅是为了打动产品本身所包含的魅力、情感和情绪。该公司向电影明星赠送钻石,发出强调名人互赠钻石大小的新闻包,将钻石借给参加奥斯卡颁奖典礼和肯塔基赛马会等重要活动的社交名流,并说服英国王室将钻石佩戴在其他宝石之上。在广告中,钻石还被作为一种地位的象征进行营销,以反映“一个男人…生活中的成功”,并带有“粗花呢、旧皮革和抛光木材的香气,这是一个好俱乐部的特征。”20 世纪 80 年代的一则广告引入了两个月的基准:“两个月的工资难道不是为永恒的东西付出的小小代价吗?"

以任何合理的标准来衡量,弗朗西斯·格雷蒂成功了——订婚意味着在美国得到一枚钻戒。你能想到两个人订婚不戴钻戒的电影吗?当你在脸书宣布订婚时,网站会显示什么图标?仍然认为这场营销活动可能不是历史上最成功的大规模说服努力?我给你看一部詹姆斯·邦德的电影,片名带有钻石卡特尔的商标:

令人肃然起敬,令人恐惧。让我们打开数据集。

您应该考虑做的第一件事是使用 ggpairs()函数绘制关键变量之间的关系。该函数成对地绘制每个变量与其他变量的关系。对于与钻石数据行数一样多的数据集,您可能希望先进行采样,否则会花费很长时间来渲染。另外,如果你的数据集有超过 10 列,将会有太多的绘图窗口,所以首先是列的子集。

不管怎样,情节是这样的:

正在发生的是,ggpairs 以一种非常聪明的方式绘制出每个变量与另一个变量的关系。在图矩阵的下三角中,它对定性-定性对使用分组直方图,对定量-定量对使用散点图。在上面的三角形中,它绘制了定性-定性对的分组直方图(使用 x 变量而不是 y 变量作为分组因子),定性-定量对的箱线图,并提供了定量-定量对的相关性。我们真正关心的是价格,所以让我们把重点放在价格上。我们可以看到价格与净度和颜色之间的关系,这一点我们将在以后开始数据建模时记住,但推动价格的关键因素是钻石的大小/重量。然而,正如我们上面看到的,价格和钻石大小之间的关系是非线性的。如何解释这种模式?在供应方面,没有明显瑕疵的大块钻石可能比小块钻石更难找到。这可能有助于解释指数曲线——我想我是在为我即将成为妻子的妻子选购钻石时注意到这一点的。当然,这与钻石的重量是体积的函数这一事实有关,而体积是 x * y * z 的函数,这表明我们可能对克拉重量的立方根特别感兴趣。

在需求方面,市场上购买较便宜、较小钻石的顾客可能比更富有的买家对价格更敏感。如果不是因为求婚时赠送钻石的社会规范,许多小于 1 克拉的顾客肯定不会购买钻石。而且,能买得起一克拉以上钻石的消费者越来越少。因此,我们不应该期望大钻石的市场像小钻石那样竞争激烈,所以随着克拉数的增加,价格的变化也会增加。

通常情况下,任何货币变量的分布都是高度偏斜的,并且会随着数量级的变化而变化。这可能是由路径依赖(例如,富人越来越富)和/或产生最终价格/美元金额的乘法过程(例如,逐年通货膨胀)造成的。因此,通过把它放在对数标度上来研究压缩任何这样的变量是一个好主意(更多信息请看 Tal Galili 博客上的这篇客座博文)。

事实上,我们可以看到钻石的价格严重倾斜,但当放在 log10 尺度上时,似乎表现得更好(即,更接*正态分布的钟形曲线)。事实上,我们可以看到,数据显示了 log10 规模上的双峰的一些证据,这与我们关于钻石客户性质的两级“富人买家,穷人买家”推测一致。让我们重新绘制我们的数据,但现在让我们把价格放在 log10 标度上:

更好,虽然还是有点古怪——让我们试着使用我们上面推测的克拉的立方根:

很好,在应用了上面的变换以在一个很好的尺度上得到我们的变量之后,看起来像一个几乎线性的关系。

过度绘画

请注意,到目前为止,我还没有做任何关于过度绘制的事情——由于舍入的原因,多个点具有相同的值。事实上,价格四舍五入到美元,克拉四舍五入到两位数。不错,尽管当我们得到这么多数据时,我们会有一些严重的过度渲染。

通常,您可以通过使点变小,使用“抖动”随机移动点以使多个点可见,以及使用透明度来处理这一问题,这可以在 ggplot 中使用“alpha”参数来完成。

这让我们更好地了解关键位置的数据有多密集和稀疏。

利用颜色了解定性因素

当我环顾钻石时,我也注意到净度似乎是价格的一个因素。当然,许多消费者都在寻找一定大小的钻石,所以我们不应该期望净度像克拉重量一样是一个重要因素。我必须承认,即使我的祖父母是珠宝商,我最初也很难区分 VVS1 级和 SI2 级钻石。当然,大多数人需要一个环来区分。此外,根据 BlueNile 的说法,钻石的切割对珠宝商描述为钻石典型特征的“火热”品质有着更重要的影响。关于净度,该网站称,“许多这些瑕疵都是微小的,不会以任何可察觉的方式影响钻石的美丽”然而,当我们将价格可视化为图上的一种颜色时,清晰度似乎可以解释价格中剩余的大量差异:

不管 BlueNile 怎么说,我们在切割上没有看到太多的变化(尽管这个数据集中的大多数钻石都是理想的切割):

颜色似乎也解释了价格的一些差异,尽管 BlueNile 声称 D-J 的所有颜色等级基本上都不明显。

在这一点上,我们已经有了一个很好的想法,我们可能如何建模价格。但是,我们 2008 年的数据存在一些问题——我们不仅需要考虑通货膨胀,而且现在的钻石市场与 2008 年相比也有很大不同。事实上,当我用模型拟合这些数据,然后试图预测我在市场上发现的钻石的价格时,我一直得到的预测都太低了。经过进一步挖掘,我找到了全球钻石报告。事实证明,由于全球金融危机,价格在 2008 年暴跌,自那以后,价格(至少是批发抛光钻石的价格)以大约 6%的复合年增长率增长。中国购买订婚钻戒的夫妇数量迅速增长也可能有助于解释这一增长。在查看了 PriceScope 上的数据后,我意识到不同克拉尺寸的钻石价格增长不均衡,这意味着我最初估计的模型不能简单地通过通货膨胀来调整。虽然我可以用那个模型做得很好,但我真的想根据新的数据来评估一个新的模型。

谢天谢地,我能够没有太多麻烦地拼凑出一个 python 脚本来抓取 diamondse.info 。该数据集的规模约为 2008 年钻石数据集的 10 倍,包含了除美国宝石学院(GIA)之外的一系列权威机构认证的世界各地的钻石。您可以按如下方式读入这些数据(预先警告—超过 50 万行):

我的 github 储存库有复制上面的每一个数字所必需的代码——大多数看起来非常相似,尽管这个数据集包含比原始数据集更昂贵的钻石。无论您使用的是原始的 diamonds 数据集还是当前更大的 diamonds 数据集,您都可以根据我们从散点图中获得的信息来估计模型。我们将回归克拉,克拉的立方根,净度,切割和对数价格的颜色。我在这个模型中只使用 GIA 认证的钻石,并且只看低于$10K 的钻石,因为这些是我见过的大多数零售商出售的钻石类型,因此也是我最关心的类型。通过从数据集中剔除最昂贵的钻石,我们的模型也不太可能被价格和克拉高端的异常值抛弃。新数据集的列与旧数据集的列基本相同,因此我们可以运行下面的代码(如果您想在旧数据集上运行它,只需设置 data=diamonds)。

以下是我搜集的数据集的结果:

这些是非常好的 R *方值,我们几乎解释了 4c 的所有价格差异。如果我们想知道一颗钻石的价格是否合理,我们现在可以使用这个模型并对结果求幂(因为我们取了价格的对数)。我们需要将结果乘以 exp(sigma /2),因为我们的误差在预期中不再为零:

为了更深入地了解最后一步,请看一下关于对数正态分布变量的维基百科页面。感谢米盖尔捕捉到这个。让我们看一个蓝色尼罗河的例子。我就用全型号,m4。

给定我们的钻石的特征和 95%置信区间的上限和下限,结果产生价格的期望值—请注意,因为这是一个线性模型,所以 predict()只是将每个模型系数乘以我们数据中的每个值。结果是这颗钻石比完整模型下的预期值稍微贵了一点,尽管它并没有超出我们 95%的置信区间。大多数人认为 BlueNile 比 diamondse.info 有更好的声誉,然而,在一个依赖于容易伪造的证书并且非专家很容易被愚弄的行业中,声誉是很有价值的。

这说明了将模型从一个数据集推广到另一个数据集的重要一点。首先,数据集之间可能存在重要的差异——正如我在上面所推测的那样——这使得估计值存在系统性偏差。第二,过度拟合——我们的模型可能会拟合数据集中存在的噪声。即使是针对样本外预测进行交叉验证的模型也可能会过度拟合噪声,从而导致数据集之间的差异。当然,虽然这个模型可能会让你感觉到你的钻石是否是对 diamondse.info 钻石的敲竹杠,但并不清楚 diamondse.info 是否应该被视为钻石价格是否合理的普遍真理的来源。尽管如此,在 diamondse.info 上有一个 95%区间的预期价格比我们在开始这个练习之前应该愿意为一颗钻石支付的价格要多得多。

重要的一点是——尽管我们可以根据 4c 的函数几乎完美地预测 diamondse.info 的价格,但你不应该从这个练习中得出一个结论,那就是在哪里购买钻石是不相关的,这显然是过去某些圈子里的传统智慧。如果你在蒂芙尼和好市多购买同样的钻石,你几乎肯定会多付钱。但是好市多也出售一些昂贵的钻石。不管怎样,你可以用这种模型来给你一个指示,看看你是否支付过高。

当然,天然钻石的价值很大程度上是由社会建构的。像金钱一样,钻石只是因为社会认为它们有价值才值钱——投资钻石没有明显的经济效益或回报,除非是在非常主观的意义上,涉及到你和你的另一半的关系。为了了解社会创造了多少价值,你可以比较天然钻石和人造钻石的价格,由于最*的技术发展,人造钻石的质量与“天然”钻石相当。当然,天然钻石的价格要高得多。

最后一件事——生活中很少有保证,我在这里也不能保证。尽管我们在这里所拥有的看起来相当不错,但是数据和模型从来都不是绝对可靠的,显然你仍然可以基于这个模型被采纳(或者被说服传递大量信息)。始终与一个有信誉的经销商购物,并确保她的动机是反对卖给你一个过高的钻石或更糟的是,不符合其证书。没有什么可以替代与一个你可以信任的知名珠宝商建立个人联系和持久的业务关系。

绘制数据有助于您理解数据并获得关键见解。但是如果你不小心的话,即使散点图可视化也可能是欺骗性的。考虑 alr3 软件包附带的另一个数据集——肯尼斯·g·哈伯德(Kenneth G. Hubbard)从 1976 年到 1992 年收集的内布拉斯加州米切尔的土壤温度数据,我在 Weisberg,S. (2005)偶然发现了这些数据。应用线性回归,第三版。纽约:威利(我无耻地窃取了这个例子)。让我们天真地绘制数据:

看起来有点像噪音。这里有什么故事?当其他方法都失败时,想想它。X 轴上是什么?月份。Y 轴上是什么?温度。嗯,内布拉斯加州有四季,所以温度应该每 12 个月波动一次。

但是我们把 200 多个月放在一个非常狭小的空间里。

让我们把它拉长,看看它是什么样子:

不要犯那个错误。

这就结束了散点图系列的第一部分。第二部分将说明使用分面/面板/小倍数的优势,并展示拟合趋势线的工具(包括线性回归和局部回归(黄土))如何有助于获得关于数据的更多见解。

你还可以通过我的同事迪安·埃克莱斯、莫伊拉·伯克和克里斯·萨登教授的 Udacity 课程了解更多关于探索性数据分析的知识,该课程将在未来几周内推出。–>

最初发布于https://solomonmg . github . io/blog/2018/visualization-series-scatter plot-understand-the-diamond-market/

了解你的敌人

原文:https://towardsdatascience.com/know-your-enemy-7f7c5038bdf3?source=collection_archive---------7-----------------------

你如何创造和抵御对抗性攻击

机器学习的当前驱动力是产生越来越精确的模型,而对这些模型的安全性和鲁棒性关注较少。正如我在上一篇文章中提到的,像图像分类器这样的 ML 模型很容易受到输入的微小干扰,从而导致它们做出错误的决定。这篇文章的目的是通过 MNIST 数字分类器的例子告诉你如何创建和防御强大的白盒对抗性攻击。内容:

  1. 计划的梯度下降(PGD)攻击
  2. 对抗性训练产生稳健的模型
  3. 对抗性稳健模型的意想不到的好处(如下)

Class interpolation with high epsilon adversarial examples. This isn’t from a VAE or GAN — it’s from an MNIST classifier trained against the projected gradient descent attack.

查看 这款 Jupyter 笔记本 包含了生成本帖中所有数字并训练你自己的对抗性健壮模型的代码。

投影梯度下降(PGD)

PGD 攻击是一种白盒攻击,这意味着攻击者可以访问模型梯度,即攻击者拥有模型权重的副本。这种威胁模型给予攻击者比黑盒攻击更大的权力,因为他们可以专门设计他们的攻击来愚弄您的模型,而不必依赖于通常导致人类可见的干扰的转移攻击。PGD 可以被认为是最“完整”的白盒对手,因为它解除了攻击者在寻找最佳攻击时可以投入的时间和精力的任何限制。

Left: natural image. Middle: Adversarial perturbation found by PGD attack against ResNet50 model, size of perturbation is magnified x100 to be more visible. Right: adversarial example.

理解 PGD 攻击的关键是将寻找一个对立的例子框定为一个约束优化问题。 PGD 试图找到使特定输入的模型损失最大化的扰动,同时保持扰动的大小小于指定量,称为ε。这种约束通常表示为扰动的 L 或 L∞ 范数,添加这种约束是为了使对立示例的内容与未受扰动的样本相同,或者甚至是为了使对立示例与人类察觉不到的不同。

PGD 在现实世界中可能遭受的攻击有:

  • 修改恶意软件的代码,以绕过基于ML的检测
  • 扰乱图像以绕过 Tumblr 的色情禁令
  • 欺骗 ML 交易策略让他们放弃所有的钱

PGD 算法可以总结为以下 5 个步骤,尽管攻击者可以自由应用任何优化改进,如动量、亚当、多次重启等

  1. 从样品周围 L^p 球的随机扰动开始
  2. 在损失最大的方向采取梯度步骤
  3. 必要时将扰动投射回 L^p 球
  4. 重复 2–3 直到收敛

Projected gradient descent with restart. 2nd run finds a high loss adversarial example within the L² ball. Sample is in a region of low loss.

“投射到 L^P 球”可能是一个陌生的术语,但简单地说就是将某个体积外的点移动到该体积内最*的点。在 2D 的 L 范数的情况下,这是将一个点移动到以原点为中心的特定半径的圆上相应的最*点。

Projecting a point back into the L² ball in 2 dimensions

对于那些有实践思维的人来说,下面的 PyTorch 函数是 PGD 的一个实现,用于为一批图像生成有针对性的或无针对性的对立示例。

对来自 MNIST 的样本运行这段代码会产生以下结果。请记住,由于其较低的维度/分辨率,MNIST 的对立示例比 ImageNet 等数据集更明显——然而,一个不健壮的分类器会被这些图像完全愚弄。

Left column: natural examples. Middle column L² bounded adversarial examples. Right column: L∞ bounded adversarial examples.

然而,我们是数据科学家,可以做得比有趣的图片更好。下面的图表量化了非稳健分类器对不同大小的对抗性扰动ε的准确性。您可以看到性能很差,因为上面显示的 L 和 L∞有界攻击的大小将我们模型的准确性降低到大约随机猜测的水*。让我们看看我们能做些什么!

对抗训练

对抗这种攻击的当前技术状态是对抗训练,这与生成对抗网络(GANs)的训练方案不同,尽管对抗训练的分类器表现出类似 GAN 的特性,我将在后面演示。

对抗性训练只是将 PGD 攻击放入你的训练循环中。这可以被视为“终极数据扩充”,而不是执行随机变换(重新缩放、裁剪、镜像等)。)作为预处理步骤,我们创建特定于扰动,这种扰动最能愚弄我们的模型,事实上,当在小数据集上训练时,对抗性训练的模型确实表现出较少的过度拟合。

这似乎是一个显而易见的方法,但这种训练方法是否会真正收敛还不清楚。原因如下:在常规训练中,我们最小化数据集 {x,y} 、模型参数θ的预期自然损失。

然而,在对抗训练中,我们最小化下面的损失函数,其中δ是一组扰动,我们希望我们的模型对于例如前面讨论的 L 和 L∞扰动是不变的。

因此,我们现在正在解决一个保证是非凸的极大极小问题,也就是鞍点问题。这与下面的 GAN 损失函数有相似之处,GAN 损失函数也是一个两人的 minimax 游戏,其中玩家是鉴别者和生成者,而不是对手和网络。

然而,在实践中,这种训练确实以增加训练时间为代价收敛(并且比 GAN 训练更一致),因为我们为网络的每个训练步骤解决多步优化问题(即 PGD)。以下代码片段训练 MNIST 模型对抗 L∞对手。

下面的图量化了针对 L 和 L∞对手训练的模型的对抗准确性——在鲁棒性方面肯定有所提高。

这里有几个有趣的地方需要注意:

  • L∞训练的模型(紫色)对 L(左)和 L∞(右)有界攻击都更鲁棒
  • 两种稳健模型在自然样本(ε= 0)上的精度都低于非稳健模型:L∞模型约为 0.5%,L 模型约为 3%
  • 左攻击看起来效力饱和(左)。这是一个错觉,因为为了节省计算时间,我固定了 PGD 步骤的数量。允许 PGD 攻击运行直到收敛,仍然可能增加ε的有效性

我解释 L 训练模型的不良稳健和非稳健性能的假设是 L 有界扰动在 MNIST 上是语义相关的。如果你看一下之前定义的对抗性损失,我们正在训练我们的模型,使其对集合δ中的扰动不变,即 L 扰动。如果这些是语义相关的对 MNIST 的干扰,那么 L 对抗性训练正在积极地阻碍我们模型的学习能力!(另一个假设是,我需要为 L 训练搜索更多的超参数……)

健壮模型的意想不到的好处

MNIST 分类器的对抗性训练有一些意想不到的好处,不仅仅是对攻击的鲁棒性。其中最有趣的是使用大ε对立示例在类之间*滑插值的能力。这些是使用前面描述的 PGD 方法产生的,除了我们允许对抗性扰动的大小比训练中使用的大得多。

下面显示的是在 L 训练模型上使用 PGD 攻击创建的有针对性的大ε对抗示例。有一些伪像,但是最终的结果是非常清楚的期望类的图像。这是可能的,因为输入空间中的鲁棒模型的梯度与人类感知很好地对齐,所以用 PGD 跟踪该梯度产生了似是而非的图像。

Leftmost: original sample. Rightmost: targeted (3, 5, 9) adversarial examples with epsilon = 7.5

对非健壮模型做同样的事情会产生垃圾图像,这些图像与所需的类只有一点相似之处。

Gross.

有趣的是,对 L 鲁棒模型的无目标对抗性攻击产生了从最相似到最不相似的类的轨迹。下面显示的是当我们将对立扰动的 L 范数从 0 增加到 10 时的对立例子和预测概率。

Progression of untargeted attack on L2 model

这种现象不仅仅是 MNIST 独有的,因为 Madry 等人能够在 ImageNet 训练的模型上产生相同类型的插值。

Figure 4 from https://arxiv.org/pdf/1805.12152.pdf showing interpolation from turtle -> bird and cat -> dog.

L∞不会产生像 L 模型一样有趣的插值(如果你想产生一些,请查看我的 Juypter 笔记本),但它确实有自己意想不到的好处——即非常稀疏的权重。

稀疏权重本身被认为是有用的,因为它们更易于解释,更易于修剪,因此模型规模更小。对 L∞模型第一层中的 32 个卷积滤波器的人工检查显示了一些有趣的特征。

  • 大多数滤波器是零(即权重是稀疏的)
  • 非零过滤器仅包含 1 个非零权重

由于非零滤波器只有一个权重,因此它们只是原始图像的缩放。将重新缩放与 ReLu 激活相结合意味着这些是阈值滤波器,即 ReLu( ax-b ),对于任何小于 b 的扰动,其激活将保持不变。输入数据的阈值化/二进制化是一种众所周知的对抗性防御,因为它破坏了小扰动——对抗性训练已经使模型独立地学习了这一点!

随着深度学习获得更广泛的采用,我们必须保持谨慎不要将人工智能模型拟人化,因为我们已经看到它们可能会以不同于人类的方式灾难性地失败。然而,一些恒星研究正在进行,以防止这种类型的攻击,并在某些情况下证明 对特定扰动的鲁棒性,所以也许真正鲁棒的深度网络可能就在眼前。

感谢阅读。请随意阅读我的 上一篇文章 其中强调了一些关于对抗性例子的令人惊讶的结果,或者查看一下 这个 Jupyter 笔记本 其中包含了生成这篇文章中所有数字的代码,并训练您自己的对抗性健壮模型。

参考

稳健性可能与准确性不一致—齐普拉斯等人 2018 年

走向抗对抗性攻击的深度学习模型 — Madry 等 2017

了解你的敌人

原文:https://towardsdatascience.com/know-your-enemy-the-fascinating-implications-of-adversarial-examples-5936bccb24af?source=collection_archive---------5-----------------------

为什么对立的例子比你意识到的更重要

Photo by naomi tamar on Unsplash

对抗性的例子是对 ML 模型的输入,这些模型是特制的,以使模型出错——计算机的视错觉。如下所示,典型的对立例子是通过在自然图像中加入少量精心计算的噪声而产生的。事实上,这种攻击可以欺骗最先进的图像识别模型,同时通常人类察觉不到,这表明了人类和深度卷积网络处理视觉信息的方式存在根本差异。这不仅提出了有趣的理论问题,而且也对神经网络在安全关键应用中的就绪性提出了质疑。

Adversarial example from Goodfellow et al. In this an imperceptibly small amount of noise is added to the first image to trick GoogLeNet — the state of the art ImageNet model in 2014.

对立的例子是一种特别有趣的机器学习现象,因为围绕它们有太多开放的问题。为什么他们愚弄深度网络而不是人类?有可能完全保护神经网络免受这些攻击吗?到目前为止,还没有人能够制造出一个对对立例子完全鲁棒的 MNIST 数字分类模型,尽管 MNIST 被大多数机器学习实践者视为一个玩具问题。

本帖将涵盖以下内容:

  1. 如何创造一个对立的例子
  2. 定义和分类敌对的例子和攻击方法
  3. 对立的例子转移到物理世界
  4. 对立范例在模型间的转移
  5. 对立的例子转移到人类身上(kinda)

如何创造一个对抗性的例子

创建对立样本非常简单,并且与神经网络的训练方式(即梯度下降)密切相关。梯度下降的原理很简单。要找到一个未知函数的最小值,首先从一个随机点开始,然后向该函数的梯度方向迈出一小步。对于足够小的步长和非病理函数,这将总是收敛(至少收敛到局部最小值)。

Gradient descent finding the minimum of f(x) = x²

为了将此应用于网络训练,我们首先定义训练数据和网络参数的损失函数(如均方误差,如下所示),该损失函数表示模型输出对于特定样本的错误程度。因此,找到这个损失函数的最小值相当于找到一组好的网络参数。

Mean squared error loss for a single sample, x, and label y. Theta represents the weights of a neural network.

其次,我们将这种损失相对于参数θ进行微分,并更新参数,使得该样本上的损失将减少。在实践中,有更多的细节,如学习率,批量大小,势头等。但原理只是梯度下降。

创造一个对立的例子是通过颠倒这个过程来完成的。如果我们保持模型的参数不变,并对输入数据, x 的损失进行微分,那么我们可以更新 x ,使得模型的预期损失在该样本上增加。

Gradient ascent on the sample, x, to increase the loss L

快速梯度符号法

在这一节中,我将讨论图像像素的扰动,只是为了说明不仅仅是图像分类模型容易受到恶意攻击。

这就把我们带到了快速梯度符号法(FGSM),这是创造一个对立例子的最简单的方法。这与梯度上升的单个步骤完全相同,除了我们将每个像素上的扰动固定为固定大小ε,因此保证在相反的例子中没有像素比原始图像大ε。这个方法产生了这篇文章顶部的例子。

在实践中,这种简单的非常简单的方法导致现有技术的 ImageNet 模型的准确性下降到几乎为零,而图像对于人类来说是察觉不到的。这对神经网络具有超人的图像识别性能(经常在 ImageNet 上声称)的形象来说是一个相当不幸的打击,并暴露了深度神经网络学习的分类函数中的一些根本盲点。你会将自动驾驶汽车中的视觉处理交给一个可能被几个移动像素愚弄的网络吗?

Alternative meme: “One-weird trick to fool any neural network — ML ENGINEERS HATE HIM”

为什么神经网络容易受到这些攻击?

尽管这可能是围绕对立例子的最有趣的问题,但我不能给你一个满意的答案——这是一个完全开放的问题!已经提出了许多建议,包括

  • 神经网络在输入空间的区域过于线性(参考)
  • 预测对弱相关特征的依赖性(参考
  • 内部权重矩阵的大奇异值(参考
  • 对立的例子可能是高维输入空间不可避免的属性

定义对立的例子

在我继续展示一些从对立的例子中得出的有趣结果之前,我将把它们正式化,并对可以执行的攻击类型进行分类。

对抗示例通常被定义为满足以下条件的ε有界示例x’

即,具有参数θ的分类器的决定不是真正的标签 y 。有界对抗性例子也满足

即,在特定的范数(也称为测量距离的方式)下,对立示例和原始示例之间的距离小于某个小ε。

规范 p 的选择决定了对对立例子的限制。所有这些规范都旨在量化一个对抗性的例子对人类来说是多么难以察觉。

  • l⁰·诺姆。ε限定了相对于 x 可以修改的x’中的像素总数(尽管它们可以被修改任意数量)
  • L norm。ε限定了x’中像素值和 x 中相应像素值之间的总*方距离。
  • L∞又名最大范数。ε限定了x’中任何像素与 x 中相应像素之间的最大差值。

然而,最*的一些工作采取了不同的方法,采用了不同的方法,并使用了一个无限的定义。对抗性扰动是对图像的任何修改,它保留了原始图像的语义,但欺骗了机器学习模型,即使攻击可能被人类察觉。这是一类定义不太明确的扰动,但正如下面的例子所证明的那样,这是一类有用的扰动。

Unrestricted adversarial attacks on MNIST. These images are adversarial in the sense that the semantic meaning is preserved for humans but led to incorrect classifications from a machine learning model.

对敌对攻击进行分类

可以在机器学习模型上执行的算法类型(也称为攻击)也可以分类。

  1. 白盒攻击。攻击者可以访问完整的模型架构,包括它的梯度
  2. 黑箱攻击。攻击者不能访问模型梯度,而只能访问概率得分或者更严格地说,只能访问最终模型决策。

你可能会提出一个问题,尽管像上述 FGSM 方法这样的白盒攻击非常有效,但攻击者有多大可能获得为自动驾驶汽车的视觉组件供电的网络的全部权重?事实证明,黑盒攻击和白盒攻击一样有效。这一事实以及我将在接下来的几段中与您分享的一些结果,使得对抗性攻击的安全含义更加真实。

对立例子的迷人特性

对立的例子转移到物理世界

读到这里,你可能会认为对立的例子只是学术上的好奇,或者至少局限于数字环境,比如躲避垃圾邮件过滤器。人们很容易相信,到目前为止你所看到的难以察觉的失真在现实世界中永远不会有效,因为它们会被相机质量、视点、照明等的变化所破坏……嗯 库拉金等人 想和你谈谈。

Figure 1 from https://arxiv.org/pdf/1607.02533.pdf demonstrating that print-out photos of adversarial images can fool classifiers in real life. In this case an Inception network is fooled into classifying a picture of a washing machine is a safe.

在他们出色的论文中,Kurakin 等人演示了对 TensorFlow 相机演示应用的黑盒攻击,该应用使用了强大的 Inception 分类器。他们能够证明,用 FGSM 方法创建的对立范例的打印输出正确分类的比率是常规范例打印输出的一半。这是一个远不如数字领域成功的攻击,但仍然是对神经网络的一个打击。

Athalye 等人更进了一步,通过发明期望超过转换(EOT)攻击来生成真正健壮的真实世界对抗实例。EOT 攻击的前提如下:我们预计一些对抗性的扰动将由于自然发生的图像变换(照明、视点等)而变得无效,因此我们应该优化我们的对抗性示例来说明这一点。他们通过使用交替梯度上升步骤和随机变换的迭代攻击过程来实现这一点。

Adversarial turtle from Athalye et al. Athalye et al were able to use their EOT method generate a 3D printed turtle that was reliably classified as a rifle from most viewpoints.

用类似的方法布朗等人能够使用 EOT 攻击生成一个敌对标签,可以打印出来并应用到任何图像上。这些对立的例子被设计成在大范围的位置、比例、旋转和背景图像上是鲁棒的,因此可以应用于任何东西。这些攻击扩展了对抗性示例的定义,因为它们对人类来说是清晰可见的,但是它们也产生了一些伪装的版本。一个占图像 10%的敌对补丁能够在 90%的时间里欺骗网络。相比之下,一个相同大小的烤面包机的标签在 10%的情况下导致了烤面包机的分类!

Left: adversarial patch successfully fooling a VGG16 network into classifiying a banana as a toaster. Right: a variety of disguised and undisguised adversarial patches, plus a real toaster for reference. See this YouTube video for a demonstration.

也许这只是我的看法,但我发现敌对贴纸在艺术上令人愉悦,事实上它甚至包含了一些类似烤面包机的视觉特征!一般来说,对抗性例子越强,就越符合人类的感知。这一有趣的现象是一个经验主义的暗示,表明人类感知和卷积神经网络之间存在某种联系——这是我将在后面的章节中更多讨论的内容。

对立范例在量词间的转移

当我第一次发现对立的例子时,我认为一个显而易见的防弹攻击是使用一组模型。一个对立的例子显然可以通过利用特定梯度的特性来欺骗一个模型,但它永远不会同时欺骗多个模型,对吗?事实证明我错了。

Table 1 from Liu et al.

刘等全面考察了对立范例在多种分类器上的可迁移性。上表中的每个单元格显示了为攻击行模型而生成的对立示例上的列模型的准确性,例如,第一行中左起第四个单元格表明对 ResNet-152 的攻击导致 VGG016 的准确性下降到 20%(从 70%)。因此,我们可以看到,一群顶级模特仍然有可能被针对单个模特的攻击所愚弄!

作者更进一步,通过对 Clarifai.com和 T3发动黑盒攻击,使用精心制作的对立例子来欺骗分类器群,充分证明了对立例子的可转移性。他们推断,既然我们不知道 Clarifai 模型的数据集、架构或训练程序,那么他们可以通过欺骗合奏来提高他们的机会。令人印象深刻的是,使用这种方法,他们能够让 Clarifai.com 模型在 76%的情况下生成不相关的标签!

Clarifai.com tags before and after adversarial perturbation.

仍然有理由相信只有神经网络容易受到这种攻击,但 Papernot 等人表明,对立的例子在各种模型类型之间转移,包括经典的机器学习算法,如支持向量机和决策树。

我相信本节中讨论的结果提供了证据,证明对立的例子不是任何特定模型的缺陷,而是在高维空间中执行分类时可能固有的问题。一些最*的结果支持这个观点,但是很明显人类能够避免这种情况。

对立的例子愚弄了有时间限制的人类

在前面的章节中,我已经向你展示了强大的对抗性例子更符合人类的感知,并且对抗性例子可以在分类器之间转移。在这篇精彩的论文中,Elsayed 等人展示了对立的例子可以转移到所有分类器中表现最好的——人类视觉系统。

这项精心设计的研究中,人类参与者重复执行以下试验的变体:

  1. 参与者被要求将目光投向屏幕中央的十字
  2. 参与者被短暂地呈现了一个大约 65 毫秒的图像
  3. 参与者都带着高对比度的随机面具(我不确定为什么需要这一步)
  4. 将图像分为两类,例如猫和狗

Visual summary of the experimental setup.

你可能已经注意到,参与者只能在很短的时间间隔内看到图像。事实上,这项研究旨在通过以下选择,最大限度地增加将对立的例子传递给人类的机会

  • 人类是有时间限制的。这限制了大脑可以使用自上而下和循环处理的数量,并且被认为使视觉处理更类似于人工前馈神经网络
  • 对立的例子是从 10 个高性能 ImageNet 模型的集合中创建的,并使用比典型情况大得多的扰动
  • 重要的是,这些扰动对人类来说是可见的,但不会改变一个没有时间限制的人的决定——它们保留了原始图像的类别

尽管如此,对抗性攻击降低了人类在这些试验中的准确性,降低了大约 10%,并且参与者的池足够大,使得这一结果具有统计学意义!

Part of figure 3 from Elsayed et al. This is an example of an adversarial image that was able to fool time-limited humans. Original class: spider, adversarial class: snake. Note that although the adversarial perturbation is visible (and contains some snake-like features, especially around the strand of silk) it is still clearly a picture of a spider.

在我看来,这篇论文展示了深层卷积网络和人类视觉的初始快速视觉反应之间的明确联系。然而,人类的视觉比第一个反应要复杂得多,涉及到不同感兴趣区域之间许多被称为扫视的眼球运动。有可能人类视觉系统的这个或一些其他特征是“秘密调味汁”,使人类视觉不受对立例子的影响,尽管甚至人类视觉也会遭受视错觉的影响(尽管这些与对立例子非常不同)。或者,也许有一天我们会发现一种方法,为无限时间的人类产生对立的例子——一个真正令人不安的想法!

我不能说这篇文章是对对立例子的全面回顾,因为我只触及了这个领域中正在做的杰出工作的一小部分,但是我希望在读完这篇文章后,你会同意我的观点,对立例子是一种迷人的现象。我相信有一天研究界会发现图像识别技术不会受到攻击,并且在这个过程中我们会学到很多关于人类视觉系统的知识。

请继续关注后续文章,在这篇文章中,我将用代码指导您完成一次具体的对抗性攻击。我还将从最*的文献中提供一种对抗性训练方法,并说明它提供了一些意想不到的好处!

更新: 这里是

知识架构——做出更好决策的途径

原文:https://towardsdatascience.com/knowledge-architecture-the-path-to-better-decisions-d376ccd423f2?source=collection_archive---------29-----------------------

Photo by Patrick Tomasso on Unsplash

在许多行业和领域,很少有组织不是数据的消费者和生产者,却能在现代成功运营。这实际上并不是一个新现象——在 20 世纪的大部分时间里,整个工业时代,组织和企业都会采用某种形式的数据,对其进行处理和理解,并使用这些知识来提高他们完成使命的能力。

从根本上改变的是廉价的、可扩展的*台的到来,这些*台可以生成非常大的数据集,以及从这些数据集提取意义的新工具和技术的诞生。这些技术为希望正确管理其数据的组织提供了很多希望,但它们通常以特定的方式部署,用于解决特定部门的特定问题,而不允许更大的群体受益。

知识架构是在上下文感知框架中对数据资源的战略管理,提供了一个组织数据的关联和可解释视图,以支持更好的决策。

不投资知识架构的成本是什么?

1。收集大数据会导致更大的问题

大数据一词流行于 21 世纪初,指的是最*收集和存储数据集的能力激增,这些数据集通常太大,无法通过传统方法进行解释。在这种情况下,“大”一词是相对的——它同样适用于从几十个参与者那里接收数据的小型社区团体,或者试图协调多个国家和时区的运营的国际组织。这是因为虽然收集的规模可能会改变,但如何解释和理解数据的复杂性是不变的。

值得深入思考一下为什么会出现这种情况。一个组织所采用的几乎任何新技术都会立即产生数据——在线财务系统会产生支出和收入记录。库存系统记录资源的数量、位置和状态。工作流管理系统产生关于谁做了什么、工作的性质、克服的问题和实现的结果的历史数据。这些数据流中的每一个都在帮助人们理解组织如何运作方面发挥着重要作用,但它们通常是支离破碎的,并通过不同的存储和解释方法保持不可访问。财务数据可能存在于图表中,库存数据可能存在于电子表格中,工作流数据可能存在于非结构化的人工编写的文本中,这些数据似乎与更结构化的数据类型无关。

如果没有一个有凝聚力的框架来连接这些不同类型的数据,组织就无法做出明智的决策。如果他们幸运的话,他们的员工愿意花时间从一个来源移动到另一个来源,构建一个基于他们的决策的心理图像,但是这本质上是缓慢和困难的。如果不是,他们的人只是根据不完整的信息做出决定。这两种方法都不会有好结果。

2。随着复杂性的增加,很容易忘记你的任务

在大多数组织的早期阶段,使命是明确的,复杂性是最小的。大多数组织的存在都是为了解决现实世界中的问题,并且是由那些相信自己能够解决问题的人发起的。但是,如果它存在的时间足够长,任何团队的工作都会开始变得复杂,要么是因为工作的性质发生了变化,要么是因为他们处理工作的方式发生了变化。

对于在以人为中心的领域中开展的努力来说,尤其如此。人群聚集在一起,相互作用,又以有时违背人道主义和理性的基本逻辑的方式分裂。然而,正是这些群体是许多组织为了完成使命最需要了解的。如果没有一个连贯的框架来理解这些团体产生的数据,简单地管理解释意义的任务很容易使你的任务失去它所需要的重点。

3。跨多个数据集的误解更有可能

它不必像臭名昭著的洛克希德·马丁/美国宇航局,帝国/公制失败摧毁了 1999 年的火星气候轨道器——任何数据集的收集都可能包括如何适当格式化和呈现不同类型数据的假设。即使不是关键任务,这些假设在没有事先了解它们之间的差异的情况下试图将它们连接起来时,也会导致糟糕的结果。

一个设计良好的知识框架将这些约定问题作为一个起点,并抽象出技术差异以创建一个无缝的数据结构作为决策的基础。可能在不同术语下报告相同事物的数据也可以得到适当的处理,使决策过程更加清晰。

投资知识架构有什么好处?

1。它允许一代工人通知下一代,而不需要做额外的工作

大多数组织都经历过失去一个长期服务的员工所带来的负面影响,这个人非常了解如何把事情做好。这些人变得如此有价值和难以替代,因为他们通过经验学习如何驾驭工作环境,并找到成功的方法,尽管存在任何技术限制。他们对一个组织有本能的了解,然后有一天他们离开了,这种了解也就消失了。

好的知识架构能够随着人们的学习而发展,以捕捉他们的经验和见解,而不是传统的方法,希望在时间允许的情况下编写文档。如果有人带来了新的数据流,因为它有助于他们的角色,这些数据应该很容易被吸收到框架中,从而使每个人受益。构建以协作为核心的基础设施是实现这一目标的关键。

2。它打开了数据的更多维度,允许发现意想不到的趋势

了解你的组织的状态和你的数据告诉你什么是一回事。了解上周、上个月和去年的情况,以及未来的走向,完全是另一种体验。也许您的操作正在正常运行,或者也许它们在响应一个不寻常的事件时出现了异常。或者,也许他们正悄悄地、稳步地朝着一个尚未完全意识到的方向前进。无论实际情况如何,如果您只有单一时间点的数据视图,您将无法轻松地将这些趋势纳入您的决策流程,也无法对影响您执行任务能力的变化做出响应。

构建知识架构时考虑了您的组织如何随着时间的推移而运作,可以捕捉数据中与时间相关的适当方面,并以能够为您提供更多见解的方式将它们联系起来。牢记趋势分析来重新评估您的情况永远不会太晚,因为即使是相对较短的数据变化历史也可以帮助开始了解您的组织的发展方向。

3。重要的创新经常发生在部门之间,而不仅仅是部门内部

围绕数据的对话经常使用术语孤岛。这指的是特定类型的数据通常是自己存储的,因为这是相关部门处理数据的方式,也是我们的大脑组织事物的方式。你不会把刀、勺子和叉子都放在厨房抽屉的同一个隔间里。你把它们分开,因为这是你使用它们的方式。对商人和他们的工具箱来说是一样的,对图书管理员和他们的书来说也是一样的。

组织数据的区别在于,它比器皿、工具或书籍承载了更多的细微差别和联系,当整合到一个统一的视图中时,有相当大的潜力释放新的机会和视角。这不仅仅是一个部门更好地了解另一个部门在做什么,而是利用现代技术来揭示以前看不到的关系和原因。'快乐的意外'经常以这种方式发生,知识架构使这成为可能。

我如何开始?

如果你已经决定认真审视你的组织的知识架构,确保你以正确的方式进行以获得最大的投资回报是值得的。取决于你从哪里开始,这个过程可能看起来不同,但以下步骤通常是一个好的起点。

1。与你的人交谈,了解他们的问题和知识差距

规划你的知识架构应该总是从理解它试图解决的问题开始。很多时候,新兴技术被作为一种通用的解决方案提供,但是任何项目,如果不能明显地让组织的员工在履行他们的职责时受益,就不可能持久。

最了解什么问题影响着一个组织的人是在这个组织中工作的人。不应该期望他们定义解决方案,但是在了解当前情况时,应该仔细倾听他们的意见。这些对话并不总是容易进行的——讨论问题有时会被认为与责任和指责的想法交织在一起。一个外部团体帮助你完成这个过程可能是一个好主意。

2。确定并了解您现有的数据来源

选择正确的技术路线需要了解您正在处理的不同类型的数据,因此组织一个完整的清单是一个明智的起点。

这也是开始查看数据集的不同特征的好时机,尤其是当它们相互关联时。每种类型的数据告诉了你什么,或者没有告诉你什么?两者有何相似之处,或有何不同?花些时间思考这些问题有助于确定连接数据的正确方法。

3。为工作选择合适的工具

只有当您清楚地了解了您试图解决的问题,并充分理解了您组织的数据环境后,您才应该选择和实施技术堆栈。这与许多技术过程发生的方式相反,但正如前面提到的,它有助于防止新的、过度宣传的产品被视为解决可能不存在的问题的简单方法。

正确的技术选择将取决于您组织的独特情况,但有一些反复出现的主题,将您的数据视为事件或变化的流,而不是简单的最后已知状态,可以帮助识别趋势。同样,提升数据中实体之间关系价值的技术可以帮助连接看似不相关的来源,提供组织各方面状态的一致画面。

最后的想法

知识架构并不是一个新概念,但在现代数据驱动的环境中实现它的方式已经发生了变化。大多数组织并不缺少数据——事实上,他们现在经常不得不满足于试图管理太多的数据。与此同时,决策需要基于分散的、静态的资源,这些资源不能以应有的有意义的方式相互关联。

着手解决组织的知识管理有时会遇到阻力,因为它经常与机器学习和人工智能一起讨论,这些技术已被用于自动化某些类型的人类工作。真正的知识架构并不是用技术取代人,而是让他们能够做出更好的决策。有无数的领域(特别是那些以人为中心的领域,如前所述),只有有经验、有觉悟和有同情心的人才能决定如何前进,以尊重他人背景和文化并维护其尊严的方式与其他人合作。将这些决策建立在能够充分描述环境的关联、准确数据的基础上,是向更好的结果迈进的一步。

知识架构消耗数据,并着手让数据发挥作用。数据本身很有趣。数据转化为信息是引人注目的。转化为知识的信息是可操作的。

本文首次出现在 insightabletimes.org 的https://insightabletimes . org/why-your-organization-should-invest-in-knowledge-architecture

知识数据科学与语义技术。

原文:https://towardsdatascience.com/knowledge-data-science-with-semantics-technologies-ff54e4fe306c?source=collection_archive---------17-----------------------

数据科学(可能的)未来简介。

Illustration by Héizel Vázquez

欢迎来到关于数据科学的新系列。在这里,我将开始介绍一些指导我们学习的概念和定义。要理解这篇文章,我建议你阅读我过去写的其他文章:

  • 关于数据和科学
  • 构建数据科学的未来
  • 本体与数据科学

我将尝试为我们的领域定义一个新的开始,我称之为:

知识数据科学

我是从知识工程领域取的这个想法,但是仅仅是名字,定义会有点不同。还有另一种类似的方法,你可以在这里阅读。让我首先回顾一下我对数据科学的定义:

数据科学是通过数学编程科学方法来解决业务/组织问题,其中涉及通过分析数据生成预测模型来创建假设实验测试。它负责这些问题转化为也能以创造性方式回应初始假设的适定问题。还必须包括对所获结果的有效沟通,以及解决方案如何为企业/组织增加价值

这里是我们需要谈论的知识数据科学:

知识数据科学是通过数学、编程、科学方法和语义技术解决业务/组织问题的方法,涉及通过分析数据和在知识表示系统内生成预测模型来创建假设、实验和测试。它负责将这些问题转化为适定的问题,这些问题也可以以一种创造性的方式对最初的假设做出回应。它还必须包括对所获结果的有效沟通,以及解决方案如何为企业/组织增加价值。

所以这里的主要区别是增加了语义技术和知识表示系统的概念。在本文中,我将描述这些。

你们中的一些人在读到这里时可能会想:我刚刚开始进入这个新领域,现在又出现了一个?或者:为什么我们需要更多关于数据科学的定义?为什么不专注于解决业务问题,就这样?

我听到了。但是让我告诉你一些事情。数据科学领域的一些人需要谈论我们领域的理论部分;这是我们能够将它的研究系统化并使其他人容易进入它的唯一方法。为什么我要给它添加一个新的部分(语义)?因为是时候了,我们开始理解它能给我们的领域和我们的工作方式带来的奇迹。这在开始时可能看起来不明显,但希望在本系列结束后,您会看到这一点。

语义技术

阅读这篇文章,了解更多背景知识。

Illustration by Héizel Vázquez

语义这个词本身就意味着意义或理解。因此,我们在这里将要讨论的语义技术是关于数据的含义,而不是数据的结构。

当我们理解的时候,我们正在解码组成一个复杂事物的部分,并把我们一开始得到的原始数据转化成有用的和直观的东西。我们通过建模来做到这一点。你可以想象,我们需要这样的模型来理解数据的意义。

我们通常通过创建一个叫做知识图的东西来做到这一点,它依赖于我们链接数据。这里的关键是,在这个新模型下,我们不是在寻找可能的答案,而是在寻找答案。我们想要事实——这些事实从何而来并不重要。

这里的数据可以代表概念、物体、事物、人,实际上是你脑海中的任何东西。图表填充了概念之间的关系和联系。

因此我们可以说,语义技术是那些使用语义、本体、链接数据和知识图的概念来帮助我们理解我们所拥有的数据的含义的技术。这种技术有很多很好的例子,比如:

  • ArangoDB
  • Neo4j
  • Talend
  • 海王星
  • 安佐

还有更多。其中一些是问题的完整解决方案,但其他的则侧重于事务性(OLTP)图数据库。而类似剑桥语义公司的 AnzoGraph 是一个分析(OLAP)图形数据库。不久前,我在一篇文章中谈到了这种差异:

[## 图形数据库。有什么大不了的?

继续分析语义和数据科学,是时候讨论图形数据库以及它们必须…

towardsdatascience.com](/graph-databases-whats-the-big-deal-ec310b1bc0ed)

为什么所有这些对你来说都很重要?因为人们不会在表格中思考(像在传统的 RDBMS 中),但他们会立即理解图形。当你在白板上画出一个知识图表的结构时,它对大多数人的意义是显而易见的。

同样重复我以前写的,我厌倦了编写极长的 SQL 查询,甚至是从数据库中获取简单数据的 NoSQL 查询。这可能是解决这一问题的方法,甚至更多。

知识表示系统

Illustration by Héizel Vázquez

我们在数学世界中表示事物的方式是最基本的。人工智能的大多数理论进步,特别是机器和深度学习,都来自于更好地表示系统和数据,并找到新的有用的技术来分析它。几乎所有我们用来完成这类任务的算法都依赖于代数、微积分和统计。

但是最*几年,以图表的方式表达信息的转变变得越来越重要。你可以在我开头列出的其他文章和文章的其余部分找到原因。但这里重要的部分是,我们需要一种数据表示,不仅包括数据本身,还包括其中的交互是一等公民。

这就是知识表示系统给我们的。一种毫不费力地表示数据及其关系的方法。正如我之前提到的:

关系数据库将高度结构化的数据存储在具有预先确定的列和行的表中,而图形数据库可以映射多种类型的关系数据和复杂数据。因此,图形数据库的组织和结构不像关系数据库那样严格。所有关系都存储在边的顶点中,这意味着顶点和边都可以有与之关联的属性。这种结构允许数据库能够描述不相关的数据集之间的复杂关系。

美国数据科学家可以通过这种方式找到很多帮助来组织我们组织中的数据。我们需要专注于解决问题,而不是处理数据。正如你以前可能听到的,处理和清理数据几乎是我们所做的一切,这种情况必须结束。我们需要开始考虑建立一个数据*台,让我们能够解决问题,并且能够以更好的方式处理数据。

知识表示系统的一个很好的例子是数据结构,我之前定义为:

[…]支持公司所有数据的*台。它是如何被管理、描述、组合和普遍访问的。该*台由企业知识图构成,创建统一的数据环境。

使用像剑桥语义的 Anzo 这样的工具,你可以自动生成查询(是的,这是一个东西),使用它们来处理复杂的图形使提取特征变得容易,并最终完全自动化。以下是 Anzo 的一个示例:

https://www.cambridgesemantics.com/product/

这个新领域的开始要求我们了解更多关于语义学、本体论、语义网、知识图等等。我以前写过这方面的文章,在下一部分,我将深入探讨这些内容以及它们与数据科学的联系。

对这个激动人心的话题,我期待更多。如果您有任何建议,请告诉我:)

如果您有任何问题,请在 Twitter 上关注我:

[## 法维奥·巴斯克斯

Favio Vázquez 的最新推文(@FavioVaz)。数据科学家。物理学家和计算工程师。我有一个…

twitter.com](https://twitter.com/faviovaz)

和 LinkedIn:

[## 法维奥·瓦兹奎——首席执行官——克洛斯特| LinkedIn

‼️‼️重要提示:由于 LinkedIn 的技术限制,我现在只能接受来自我…

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

那里见:)

知识蒸馏——一种为压缩和加速神经网络而开发的技术

原文:https://towardsdatascience.com/knowledge-distillation-a-technique-developed-for-compacting-and-accelerating-neural-nets-732098cde690?source=collection_archive---------25-----------------------

Photo by Kai Dahms on Unsplash

最*的增长见证了深度学习行业的显著增长。随着 AlexNet 在 2012 年 ImageNet 比赛中的突破,更先进的深度神经网络 (ResNet-50,VGGNet,以及许多其他)被开发出来,不断改写记录。然而,这些网络需要大量的计算来产生良好的结果。例如,AlexNet 有 6230 万个参数,使用两个 Nvidia Geforce GTX 580 GPU 训练 90 多个 epochs 需要大约 6 天时间。

因此,这些网络的潜力只能通过繁重的计算来完全利用。相比之下,我们日常生活中使用的大多数移动设备通常对存储和计算资源有严格的限制,这使得它们无法充分利用深度神经网络。因此,为了保持类似的准确性,同时牢记这些限制,开发了一种压缩和加速神经网络的新技术,称为知识提取

在这篇文章中,我们将关注知识的提炼以及如何用它来解决这个问题。

知识蒸馏

直觉

The red plot is of the large model(Teacher), the blue plot is of the student network trained without distillation, and the purple plot is of the student network trained using distillation.

我们的主要目标是训练一个能够在测试数据集上产生良好结果的模型。为了做到这一点,我们训练了一个笨重模型,它可以是许多不同训练过的模型的集合,或者仅仅是一个用正则化子训练的非常大的模型,例如退出。一旦笨重的模型(教师)准备就绪,我们就使用一种称为提炼的技术,将笨重模型学到的复杂知识转移到更适合部署在具有内存和繁重计算约束的设备中的小模型(学生)

通过复杂的知识,我的意思是,繁琐的模型可以区分大量的类。在这样做的时候,它给所有不正确的类分配概率。然而,这些概率是非常小的,它们告诉我们很多关于这个繁琐的模型是如何概括的。一张狗的图片很少会被误认为是猫,但这种错误仍然比误认为是鸽子多很多倍。

繁琐的模型需要很好地概括,所以当我们将知识提取到较小的模型时,它应该能够以与大模型相同的方式概括。例如,如果一个大模型是许多不同模型的集合,那么与在用于训练集合的相同训练集上以正常方式训练的小模型相比,使用提取知识学习的小模型将能够在测试数据集上更好地概括。

将繁琐模型的泛化能力转移到小模型的一种明显的方式是使用由繁琐模型产生的类别概率(通过称为蒸馏的技术产生)作为用于训练小模型的“软目标”。对于转移阶段,我们可以使用相同的训练集或单独的集(完全由未标记的数据组成)

Scatters dots are the data points in the dataset. The blue plot is the cumbersome model(teacher) trained on a complex dataset and the red plot is the small model(student) generalizing on the soft targets generated from the teacher model.

对于软目标,我们可以取所有单个预测分布的几何*均值。当软目标具有高熵时(你可以在这里阅读更多关于熵的信息),它们为每个训练案例提供的信息比硬目标多得多,训练案例之间的梯度差异也小得多,因此小模型通常可以在比原始笨重模型少得多的数据上进行训练,并使用高得多的学习率。

蒸馏

蒸馏是产生软目标概率分布的一般解决方案。在这种情况下,我们使用 softmax 激活函数产生类别概率,该函数将为每个类别计算的 logits z_i 转换成概率 q_i:

Equation-1

这里 T 是温度,通常设置为 1。使用更高的概率分布导致更柔和的概率分布。

z_i 是为数据集中每个数据点的每个类计算的逻辑值。

在蒸馏的最简单变型中,通过在转移集上训练笨重的模型,并对转移集中的每种情况使用软目标分布,将知识转移到小模型,该软目标分布由 softmax 函数中的高温产生。在训练小型或蒸馏模型时使用相同的高温,但是在训练之后,温度被设置为 1。

如果我们有转移集的正确标签,这项技术可以得到显著的改进。一种方法是取两个目标函数的加权*均值。第一个目标函数是软目标的交叉熵,并且使用提取模型的 softmax 中与用于从繁琐模型生成软目标相同的高温来计算该交叉熵。第二个目标函数是正确标签的交叉熵。这是使用提取模型的 softmax 中完全相同的 logits 进行计算的,但温度为 1。保持第二目标函数的权重相当小产生了最好的结果。

因为由软目标产生的梯度的幅度缩放为 1/T,所以当使用硬目标和软目标时,将它们乘以 T 是重要的。这确保了当用元参数进行实验时,如果用于蒸馏的温度改变,则硬目标和软目标的相对贡献大致保持不变。

运行一个示例

Process of deploying deep learning models in embedded devices.

在这个例子中,我们将考虑我们正在处理一个非常复杂的数据集 (X) ,并且使用一个浅层网络(可以部署在移动设备中)在这个数据集上获得良好的准确性,使用传统的模型构建技术几乎是不可能的。因此,为了获得良好的准确性,我们将使用知识提炼技术:

  • 首先,我们将在数据中心使用大型模型(老师)训练数据集 X,该模型能够分解数据集 X 的复杂性,以产生良好的准确性。
  • 现在,我们将使用原始数据集 X 或转移集(数据集 X 的较小版本)从大模型中生成软目标,然后使用它们通过蒸馏技术获得数据集中每种情况的概率分布。
  • 下一步是基于移动设备的内存和计算限制来构建一个浅层网络(学生)
  • 这个浅层网络将根据第二步中产生的概率分布进行训练,并在此基础上进行推广。
  • 一旦该模型被训练,它就准备好被部署在移动设备中。

为了估计提取模型的结果有多好,我们将查看神经网络 中的论文 知识蒸馏的作者使用知识提取在 MNIST 数据集上能够实现的数字。

结果

为了了解蒸馏是如何工作的,MNIST 数据集使用一个非常大的神经网络(教师)进行训练,该网络由两个隐藏层组成,每个隐藏层都有 1200 个经过校正的线性隐藏单元。以下模型已经训练了超过 60,000 个训练案例。该网络实现了 67 个测试错误,而较小的网络(学生)具有两个隐藏单元,每个具有 800 个校正的隐藏单元 146 个测试错误。

但是,如果仅仅通过增加匹配大网在 20℃下产生的软目标的额外任务来调整较小的网,它会产生 74 个测试误差。这表明软目标可以将大量知识转移到提取的模型,包括从翻译的训练数据中学习的关于如何概括的知识,即使转移集不包含任何翻译。

如果你想比较其他数据集的结果,你可以查看原始的论文以获得更多信息。

结论

  • 简单模型的能力没有被硬标签训练充分利用:通过知识提炼来提高。
  • 随着知识的丰富和流畅,软标签更容易匹配。
  • 知识提炼框架主要关注准确性和压缩率,但忽略了对实际应用至关重要的已学习学生网络的健壮性。
  • 学生模型可以用在嵌入式设备中,产生可比较的结果,在某些情况下,它甚至可以复制复杂网络的结果。

为了更深入地了解知识的提炼,我建议你去阅读原文, 在神经网络中提炼知识

如果你喜欢这篇文章并想保持联系,你可以在 LinkedIn 这里找到我。

知识蒸馏:简体

原文:https://towardsdatascience.com/knowledge-distillation-simplified-dd4973dbc764?source=collection_archive---------2-----------------------

窥探师生网络的世界

什么是知识蒸馏?

*年来,神经模型在几乎每个领域都取得了成功,包括极其复杂的问题陈述。然而,这些模型体积庞大,具有数百万(和数十亿)个参数,因此不能部署在边缘设备上。

知识提炼指的是模型压缩的思想,通过一步一步地教会一个较小的网络,使用一个更大的已经训练好的网络来做什么。“软标签”指的是在每个卷积层之后由更大的网络输出的特征图。然后,较小的网络被训练来学习较大网络的确切行为,尝试在每个级别复制其输出(不仅仅是最终损失)。

我们为什么需要这个?

深度学习已经在包括计算机视觉、语音识别、自然语言处理等众多领域取得了令人难以置信的性能。然而,这些模型中的大多数在计算上过于昂贵,以至于不能在诸如移动电话或嵌入式设备上运行。要了解更多关于模型压缩的需求和相关的常用技术,请访问下面的博客。

[## 深度学习—模型优化和压缩:简化

看看最先进的机器学习模型的压缩、修剪和量化领域

towardsdatascience.com](/machine-learning-models-compression-and-quantization-simplified-a302ddf326f2)

这和从零开始训练一个模型有什么不同?

显然,对于更复杂的模型,理论上的搜索空间要比较小的网络大。但是,如果我们假设使用更小的网络可以实现相同(甚至相似)的收敛,那么教师网络的收敛空间应该与学生网络的解空间重叠。

不幸的是,仅凭这一点并不能保证学生网络在同一位置收敛。学生网络可能有一个与教师网络非常不同的汇聚点。但如果引导学生网复制教师网的行为(教师网已经搜索过更大的解空间),则有望使其收敛空间与原教师网收敛空间重叠。

师生网络——它们到底是如何工作的?

  1. 训练教师网络:高度复杂的教师网络首先使用完整数据集单独训练。这一步需要很高的计算性能,因此只能离线完成(在高性能 GPU 上)。

An example of a highly complex and Deep Network which can be used as a teacher network : GoogleNet

2。建立对应关系:在设计学生网络时,需要在学生网络和教师网络的中间输出之间建立对应关系。这种对应可以包括将教师网络中某一层的输出直接传递到学生网络,或者在将其传递到学生网络之前执行一些数据扩充。

An example of establishing correspondence

3。通过教师网络向前传递:通过教师网络传递数据以获得所有中间输出,然后对其应用数据扩充(如果有)。

4。通过学生网络反向传播:现在使用来自教师网络的输出和对应关系在学生网络中反向传播误差,这样学生网络可以学习复制教师网络的行为。

下一步是什么?

对上述传统的学生教师提出了许多新的修改建议,如引入多名教师(即,将一个合奏转变为一个单一的网络),引入一名助教(教师先教助教,助教再教学生)等。然而,这个领域仍然非常年轻,在许多方面还没有被探索。

这个博客是努力创建机器学习领域简化介绍的一部分。点击此处查看完整系列

[## 机器学习:简化

在你一头扎进去之前就知道了

towardsdatascience.com](/machine-learning-simplified-1fe22fec0fac)

或者只是阅读系列的下一篇博客

[## 培养你自己的 RNN 细胞:简化

一窥单个 RNN 细胞的“深层”世界

towardsdatascience.com](/growing-your-own-rnn-cell-simplified-b68ba2c0f082)

参考

[1]王,,等.“DeepVID:基于的图像分类器深度视觉解释与诊断”IEEE 可视化与计算机图形学汇刊 25.6(2019):2168–2180。
[2] Mirzadeh,Seyed-Iman 等,“通过教师助理改进知识升华:弥合学生和教师之间的差距。”arXiv 预印本 arXiv:1902.03393 (2019)。
[3]辛顿、杰弗里、奥里奥尔·维尼亚尔斯、杰夫·迪恩。"从神经网络中提取知识."arXiv 预印本 arXiv:1503.02531 (2015)。
[4]刘,晓东,等.【用改进多任务深度神经网络用于自然语言理解】arXiv 预印本 arXiv:1904.09482 (2019)。

知识图:机器学习的完美补充

原文:https://towardsdatascience.com/knowledge-graph-bb78055a7884?source=collection_archive---------2-----------------------

Photo by Alina Grubnyak on Unsplash

如今,网络上的信息数量惊人,而且还在不断增加。例如,有超过 19.4 亿个网站与万维网和搜索引擎(例如,Google、Bing 等)链接。)可以通过这些链接,以极高的精度和速度提供有用的信息。在大多数成功的搜索引擎中,最重要的特征是使用知识图表。不仅是搜索引擎,社交网站(如脸书等。)、电子商务网站(如亚马逊等。)也在使用知识图来存储和检索有用的信息。

简史

1960 年、、语义网络、被发明出来,以解决对知识表示框架的日益增长的需求,该框架可以捕捉广泛的实体——真实世界的物体、事件、情形或抽象概念和关系,并最终可以应用于扩展的英语对话任务。语义网络背后的主要思想是捕捉广泛的问题,包括计划、行动、时间、个人信念和意图的表示,并且足够通用以适应每个问题。

根据维基百科,在 1980 年末,两所荷兰大学开始了一个名为 知识图 的项目,这是一种语义网络,但增加了一些限制,以方便图上的代数运算。

2001 年,蒂姆·伯纳斯·李创造了术语 语义网 是语义网与 Web 结合的一种应用。

蒂姆·伯纳斯·李说“语义网是当前网络的延伸,在其中信息被赋予明确的含义,更好地使计算机和人合作工作。”

2012 年,谷歌将其知识图谱命名为 知识图谱

未定义的定义

每个公司/团体/个人都创建他们自己版本的知识图,以限制复杂性并将信息组织成数据和知识。比如谷歌的知识图、知识库、微软的 Satori、脸书的实体图等。

因此,知识图没有正式的定义。从更广的角度来看,知识图是语义网络的变体,带有附加的约束,其范围、结构、特征甚至用途都没有完全实现,并且处于发展过程中。

知识图示例

Source: Maximilian Nickel et al. A Review of Relational Machine Learning for Knowledge Graphs: From Multi-Relational Link Prediction to Automated Knowledge Graph Construction

你为什么要兴奋?

随着时间的推移,机器学习和基于知识图的知识表示学习正在迅速发展,无论是在规模上还是在深度上,但方向不同。一方面,机器学习技术在执行各种任务(如分类、生成等)方面越来越好。)在各种数据集上,具有很高的精确度和召回率。另一方面,知识表示带来了以高可靠性、可解释性和可重用性来表示实体和关系的能力。知识表示学习的最新进展包括从图中挖掘逻辑规则。

Source: Bishan Yang et al. Embedding Entities and Relations for Learning and Inference in Knowledge Bases.

然而,将知识图和机器学习结合起来将系统地提高系统的准确性,并扩展机器学习能力的范围。例如,从机器学习模型中推断出的结果将具有更好的可解释性和可信度。

以下是将知识图引入机器学习中可以利用的一些机会:

数据不足

拥有足够数量的数据来训练机器学习模型是非常重要的。在数据稀疏的情况下,知识图可以用来扩充训练数据,例如,用相似类型的实体名称替换原始训练数据中的实体名称。这样,使用知识图可以创建大量的正面和负面例子。

零射学习

如今,机器学习模型面临的主要挑战是,如果没有经过适当训练的数据,就无法区分两个数据点。在机器学习中,这被认为是零射学习问题。这就是知识图表可以发挥很大作用的地方。来自机器学习模型的归纳可以用来自知识图的推断来补充,例如,用训练数据中没有出现情况类型的图片。

可解释性

机器学习行业的主要问题之一是解释机器学习系统所做的预测。一个问题是导致来自机器学习模型的预测的隐式表示。知识图可以通过将解释映射到图中适当的节点并总结决策过程来缓解这个问题。

注意:上述机会在研讨会报告知识图:语义网上知识表示的新方向(Dagstuhl 研讨会 18371) 中有更详细的解释

一些使用案例

  • 问答是知识图最常用的应用之一。知识图包含丰富的信息,问答是帮助终端用户更有效地从知识图中检索信息的好方法。
  • 存储研究信息是另一个有用的应用知识图。最*,许多公司正在使用知识图来存储从研究的各个阶段产生的信息,这些信息可用于建立可访问的模型、风险管理、过程监控等。
  • 网飞使用知识图表为其推荐系统存储大量不同的信息,这有助于发现电影、电视节目、人物等之间的关系。稍后,这些关系可用于预测客户接下来可能喜欢看什么。
  • 供应链管理也受益于知识图的使用。公司可以轻松跟踪不同组件的库存、涉及的人员、时间等,这使他们能够更快速、更经济地移动物品。

还有更多……

公开挑战

  1. 一套连贯的最佳实践,可以在知识图的创建过程中应用,将有助于工程师、开发人员和研究人员理解和重用知识图。
  2. 给定一组非结构化数据和知识图,知识整合的问题是识别数据中提到的实体是否与知识图中呈现的现实世界实体相匹配。虽然这个问题可以使用机器学习算法来解决,但是这些算法的结果直接取决于训练数据的质量。给定各种各样数据集,知识集成变得相当困难。
  3. 知识不是一成不变的,而是不断进化的。例如,如果一个知识图表跟踪病人的健康状况,那么在某个特定时刻存储的数据可能在稍后的某个时刻是错误的。那么,我们如何捕捉这种知识进化的本质呢?
  4. 如何评价一个知识图谱?哪些质量改进(例如,完整性、正确性、链接等。)更重要?

感谢

  • 知识图表:语义网上知识表示的新方向(Dagstuhl 研讨会 18371) Dagstuhl 报道8(2018):29–111。
  • 保罗海姆,黑科。"知识图精化:方法和评估方法综述."语义网8(2016):489–508。
  • 《知识图的关系机器学习回顾》IEEE 会议录104(2015):11–33。
  • 艾伦和弗里希(1982)。“语义网络中有什么”。在:第 20 届会议录。ACL 年度会议,多伦多,第 19-27 页。
  • 奈杰尔等人《语义网再访》 IEEE 智能系统21(2006):96–101。

2019 年知识图谱大会

原文:https://towardsdatascience.com/knowledge-graph-conference-2019-53eadc63a992?source=collection_archive---------30-----------------------

Credit: Columbia University

我对 KGC2019 @哥伦比亚大学的看法

上周,我得以参加哥伦比亚大学的 2019 年知识图谱大会。这是一个为期两天的活动,来自世界各地的优秀演讲者在这一领域的专业知识。这是我对它的简短看法。

如果你是知识图表和“数据结构”的新手,我强烈推荐你阅读法维奥瓦斯奎兹的系列文章。他很好地解释了不太直观的概念,并且很容易理解。

[## 机器学习的数据结构。第 2 部分:构建知识图。

在能够开发数据结构之前,我们需要构建一个知识图。在这篇文章中,我将建立一个基础…

towardsdatascience.com](/the-data-fabric-for-machine-learning-part-2-building-a-knowledge-graph-2fdd1370bb0a)

用例

来自金融行业的代表表现良好,大多数用例涉及法规遵从性、风险和其他后台办公室用例。汤森路透(Thompson Reuters)和其他公司旗下的路孚特公司有一个演示特别引起了我的注意(路孚特向其他金融机构出售市场数据)。一个真正的用例是通过 KG 增强新闻/事件的消费。例如,如果我是一名投资组合经理,并对钢铁价格有所敞口,而一条影响我头寸的突发新闻刚刚发生,知识图将直观地捕捉到这种联系。即使你知道你的头寸和(插入随机全局事件)之间的相关性,使用这样的工具也会加快决策过程(无论你持有还是做空你的头寸)。这只是一个用例,但我很好奇如何利用知识图以其他方式生成 alpha。

科技公司也在使用这项技术。鉴于许多功能/基础设施都是内部构建的,我对工程方面的印象尤为深刻。从零开始!

下面是一篇关于 AirBnb 如何使用他们的知识图表的文章。但简而言之,推荐得到了增强,因为不同实体之间的关系在 KG 中被捕获。

[## 通过构建知识图将 Airbnb 情境化

介绍我们如何在 Airbnb 构建知识图,该知识图帮助我们对库存进行分类并提供上下文…

medium.com](https://medium.com/airbnb-engineering/contextualizing-airbnb-by-building-knowledge-graph-b7077e268d5a)

障碍

大多数机构面临的主要障碍是人为的,而不是技术上的。知识图/语义技术的采用增长迅速,但是仍然很难解释、证明和在全公司范围内采用这种工具。“传播”可能很困难,尤其是当本体学家、IT 和业务之间存在信息鸿沟时。就采用策略而言,与其将组织中的每个数据集都映射或放在“蓝海”中,不如一点一点地慢慢进行被认为是更好的方式。

下一步是什么?

就个人而言,我想学习更多关于图论(遍历、推理、联邦查询、推理等)的知识,并探索在构建 KG/Semantic Web 时使用前沿 NLP 技术增强映射自动化的可能性。

这是一次很棒的教育活动,我要感谢弗朗索瓦·沙夫,组织者,学生志愿者,以及所有使这次活动成功的人。虽然我的博客文章很短,但这些演讲者提供了关于会议的更全面的报告:

来自维基数据/谷歌的 Denny Vrandeč

[## 2019 年知识图谱大会,第一天- Simia

我提出了维基数据和抽象维基百科的概念,认为它超出了知识图表可以轻易表达的范围。我…

simia.net](http://simia.net/wiki/Knowledge_Graph_Conference_2019,_Day_1)

来自 Capsenta 的 Juan Sequeda

[## 2019 知识图谱大会行程报告

刚从哥大专业研究学院组织的 2019 知识图谱大会回来…

www.juansequeda.com](http://www.juansequeda.com/blog/2019/05/11/2019-knowledge-graph-conference-trip-report/)

使用 Stardog 的知识图查询

原文:https://towardsdatascience.com/knowledge-graph-queries-using-stardog-ba882f84ceea?source=collection_archive---------21-----------------------

Stardog:一个允许你探索和查询知识图表的*台。

Image by Stardog. Knowledge graph visualization in Studio

Stardog 不仅仅是一个查询引擎,它是一个前沿*台,允许你探索和查询知识图表。

Stardog 可用于在知识图上运行 SPARQL 查询。如果你不熟悉知识图或者 SPARQL 查询,我建议你看我的博客:使用 Apache Jena (SPARQL 引擎)提取和查询知识图。对于本教程,您可以下载任何知识图表,如 AGROVOC ,或者您可以创建自己的图表,如下所示:

目前,图表如下所示:

明星日志

知识图的功能取决于它所能访问的数据,因此我们构建了数据库连接器来简化数据的统一。Stardog 拥有所有主要 SQL 系统和最流行的 NoSQL 数据库的连接器。此外,我们构建了 BITES 管道来处理您的非结构化数据,如研究论文、简历和监管文档。BITES 使用 NLP 实体识别来识别和提取概念,将这些数据关系添加到知识图中。一旦你的数据在 Stardog 中统一,你就可以在每个数据点上看到 360 度的视图。

Image from Stardog

下载并安装 Stardog

有不同的下载选项,您可以轻松运行下面的curl命令:

curl [https://downloads.stardog.com/stardog/stardog-latest.zip](https://downloads.stardog.com/stardog/stardog-latest.zip) –output stardog-latest.zip

然后使用以下命令将其解压缩:

unzip stardog-latest.zip

现在你应该可以运行命令./stardog-admin.了,我建议你添加路径到你的.bsahrc或者你可以直接使用export PATH=/home/.../stardog:$PATH.之后,你需要使用下面的命令启动 Stardog 引擎:

stardog-admin server start

您应该得到以下内容:

建立一个数据库

然后打开另一个终端,运行下面的命令,从给定的知识图构建一个数据库。

stardog-admin db create -n MoDB data.nt

如果运行成功,您应该会得到类似的输出:

注意:MoDB是数据库名,data.nt是你的知识图名。

运行 SPARQL 查询

最简单的查询之一是返回所有的三元组。这是查询:

stardog query MoDB "select * where { ?s ?p ?o }"

这是输出结果:

或者你可以通过提问来搜索所有感兴趣的东西Mohamed?(该查询将返回所有的三元组,其中interestedIn是关系)

stardog query MoDB "select * where { ?s <[http://example.com#interestedIn](http://example.com#interestedIn)> ?o }"

输出:

到目前为止,我们一直直接从终端运行查询。相反,您可以将查询写到一个文件中,我们称之为que.sparql.要从文件中执行前面的查询,请在que.sparql中粘贴以下内容:

select * where {?s <[http://example.com#interestedIn](http://example.com#interestedIn)> ?o}

要执行查询文件,请运行以下命令:

stardog query MoDB que.sparql

返回最短路径

以下查询将返回两个实体之间的最短路径,在我们的示例中为MohamedJim:

stardog query MoDB "PATHS START ?x = <[http://example.com/Mohamed](http://example.com/Mohamed)> END ?y = <[http://example.com/Jim](http://example.com/Jim)> VIA ?p"

返回所有可能的路径

默认情况下,Stardog 将返回最短路径。要返回所有路径,只需在PATHS后添加关键字ALL:

stardog query MoDB "PATHS ALL START ?x = <[http://example.com/Mohamed](http://example.com/Mohamed)> END ?y = <[http://example.com/Jim](http://example.com/Jim)> VIA ?p"

输出是:

请注意,如果您从Mohamed查询到Mike,您将只获得一条路径,因为从pastaMike没有关系。

这些查询可以应用于任何知识图。

知识图和机器学习

原文:https://towardsdatascience.com/knowledge-graphs-and-machine-learning-3939b504c7bc?source=collection_archive---------8-----------------------

半自动洞察生成的强大组合

知识图是一组由描述一个领域(例如一个企业、一个组织或一个研究领域)的关系所链接的数据点。这是一种强大的数据表示方式,因为知识图可以自动构建,然后可以探索以揭示关于该领域的新见解。

知识图谱是二级衍生数据集:通过对原始数据的分析和过滤获得。更具体地说,数据点之间的关系是预先计算的,并成为数据集的重要部分。这意味着不仅每个数据点都可以快速、大规模地分析,而且每个关系都可以分析。

选择如何描述这种关系以及快速大规模分析的能力是获得新见解的关键。从数据到信息,从信息到知识,从知识到洞察,从洞察到智慧。

例如,地理地图包含城市的名称和坐标,而简单的知识图也包含城市之间的距离。因此,不用在查询时计算所有的距离,我可以直接问:A 点和 R 点之间的最短路径是什么?预先计算距离是一个简单的步骤,但使地理分析更快,也允许轻松测试不同的场景。例如,知道 B 点突然不可到达,A 和 R 之间的最短路线是什么?

图形作为分析工具已经存在了几个世纪,但是直到最*才出现了“知识图”的概念。它的形式定义由 Paulheim ( 2016 )给出,其中一个知识图:

  • 描述现实世界的实体及其相互关系;
  • 定义架构中实体的可能类和关系;
  • 允许任意实体之间潜在的相互关系;
  • 涵盖各种主题。

除了定义之外,知识图还有巨大的市场吸引力:它意味着一个技术人工制品,它封装了一个公司或另一个领域的所有关系,从而导致更好的理解。这正变得越来越真实,这也要归功于机器学习。

使用机器学习描述新关系

机器学习革命的主力是通过深度学习进行数据分类。通过对数据进行分类,我们可以创建属于同一类的相关数据点子集。这种关系在分类之前并不存在,现在可以用来创建知识图。

深度学习的强大之处在于能够对复杂的数据进行分类,而不需要提供明确的描述,只需要简单的例子。图像、语音、文档、电子表格、演示文稿、视频……深度学习可以对许多不同种类的数据进行分类,这为从多个角度描述一个领域提供了前所未有的机会。手动描述数百万个数据点基本上是不可行的。想象一下,必须阅读和分类数百万份精确但枯燥的法律文件。不是对人类时间的最佳利用。

充分利用一个人的时间也是一个公司的 ML 生成的知识图的简单例子:通过分析文档,有可能知道 A-teamteam∈分别在同一主题上工作,这提供了改进协作的机会。

图形和 ML 的强大组合有许多可能的用例。开发需要在两个具有挑战性的方面下功夫:访问数据和找到将导致期望结果的类。第一个问题主要是组织、法律和伦理问题,而第二个问题需要领域知识。在 ML 革命之前,这通常只能由主题专家提供,而现在 ML 系统可以支持这项工作,降低了准入门槛。

ML 也支持关系类的定义

机器学习可以支持使用分类以及类的定义来创建关系。例如,文档的自然语言处理可以对主题建模并识别命名实体。有了它们的统计表示,人们就可以根据数据来决定哪些元素应该构成新的关系类型。这些然后成为分类的标签。

这意味着,为了创建知识图,任何可能包含相关信息的数据库都会被爬行和扫描。文件、目录、活动日志……任何东西都可以进行统计分析,以创建分类和本体,这些术语用于定义数据点之间的类、属性和关系,以及如何创建新的数据点。它们是对所有考虑的数据点进行分类和描述的蓝图和说明。这就是为什么知识图有时也被称为语义网络的核心。语义强调了这样一个事实,即表示的与相应的数据一起编码。这是通过分类法和本体论完成的(它们的通用术语有一些重叠,部分是由于它们的起源。分类学源于生物学,而本体论源于哲学——源于希腊语 Ontologia,“对存在的研究”。存在更正式的定义,如计算机科学中使用的定义,但它们在此上下文中并不完全相关)。

在定义分类法和本体论时,人的判断是很重要的,因为数据可以用无数种方式来描述。机器仍然无法考虑更广泛的背景来做出适当的决定。分类法和本体论就像是提供了一个观察和操作数据的视角。如果没有考虑感兴趣的元素,那么知识图不会提供任何洞察力。选择正确的视角是创造价值的方式。典型地,这个任务是反复执行的,也从失败中学习。

一旦您定义了规则,您就可以将它们应用到新数据,创建元数据,从而创建知识图。在适当的数据库系统中,可以很容易地查询和分析它。例如,一个特定的实体有多少关系?从 A 到 Z 的最短路线是什么?子图有多相似?

知识图的强大之处之一是能够将不同类型的数据和来源联系起来。这对于通过组合来自不同来源的信息来提取价值非常有用,例如跨公司筒仓。

创建知识图是一项重要的工作,因为它需要访问数据、重要的领域和机器学习专业知识,以及适当的技术基础设施。然而,一旦为一个知识图建立了这些需求,就可以为更多的领域和用例建立更多的需求。鉴于可以发现新的见解,知识图是一种从现有非结构化数据中提取价值的变革性方式。明智使用。

[All photos and images by author]

如果你读到这里,你可能会喜欢以光速飞行的——元宇宙的苍蝇如何帮助解决了一个长期存在的工程之谜。

连接点:使用人工智能和知识图表来识别投资机会

原文:https://towardsdatascience.com/knowledge-graphs-in-investing-733ab34abe?source=collection_archive---------7-----------------------

最*,Gartner 的 2018 年人工智能和新兴技术炒作周期宣布知识图表呈上升趋势。它们与 4D 印刷和区块链一样,处于宣传周期的早期,是创新触发阶段的一部分,仅可能在截至 2018 年 8 月的五到十年内达到*台期。

Gartner Hype Cycle for Emerging Technologies, 2018. Source: Gartner (August 2018).

“知识图表是新的黑色!(……)从可用的聊天机器人、引导式流程到自动化顾问,我们将看到在许多行业和领域的使用越来越多,包括医疗保健、金融服务和供应链”

—埃森哲应用智能公司董事总经理兼首席技术官 Jean-Luc chate Lin

知识图谱在金融领域的影响才刚刚开始。然而,随着数据的迅猛增长和市场参与者面临的信息过载,基于知识图的技术将很快从竞争优势转变为必备条件。

知识图谱在投资中的主要用例有哪些?

K 知识图用例包括问答(QA)系统、语义搜索、动态风险分析、基于内容的推荐引擎、知识套利、主题投资和知识管理系统。我们强调四种主要使用情形:

  1. 企业数据治理
  2. 研究和知识发现
  3. 风险暴露
  4. 主题投资

企业数据治理

主要机构通常面临着成千上万个孤立的“数据孤岛”,因此面临着信息过载的挑战。知识图可以通过处理不同的来源和从不同的数据集中提取知识的原子单元,作为集成知识和推理的集中来源。

知识图能够持续“读取”不同的来源,将信息投射到多维概念空间,其中不同维度的相似性度量可用于将相关概念分组在一起。这允许集成的企业解决方案,该解决方案不仅识别实体、人、事件和想法的含义,将它们聚集到整个机构的统一知识层中,而且将概念关联和分组,以允许推理生成和洞察。

研究和知识发现

知识图可以用作语义搜索引擎,在研究和知识发现应用中激发新的想法和发现意想不到的联系。

知识图表利用来自不同领域的数百万篇学术文章、书籍和数据库的数亿个语义连接和概念链接。

知识图表使用户能够直观地浏览概念、关系和领域,从可能被忽略的资源中学习。这不仅增进了理解,创造了更有影响力的作品,而且节省了时间,同时确保了全面和可信的报道。

风险暴露

复杂传染是指一个人需要多种接触来源才能改变行为的现象。投资就是识别关系,揭露风险就是复杂的传染

影响特定公司、行业、市场或经济的潜在联系(包括直接和间接的)呈指数增长。在正确的数学意义上,知识图是实际的图,允许应用基于推理图的技术。从这个意义上说,知识图表的一些最重要的用例与推理和“推断关系”有关——本质上是在有时完全不同的事件或信息之间画出联系,否则这些事件或信息不会被联系起来。这允许在复杂传染框架内量化风险暴露。

Yewno|Edge quantifies portfolio exposure to complex concepts such as Data Privacy, Tariffs, and Brexit. Source: www.yewno.com/edge.

Yewno|Edge 就是一个应用例子,它是 Yewno 的新人工智能金融*台,可以量化投资组合对复杂概念的敞口,无论是苹果公司未能实现的收益,对贸易战的担忧,还是中国经济放缓,你都可以看到几乎任何因素都在影响你的投资组合。使用 Yewno|Edge,您可以通过跟踪公司关系和对想法的接触,而不仅仅是关键字,轻松找到哪些公司、主题和事件正在影响您的投资组合。

主题投资

知识图可以通过从投影的语义空间消除术语的歧义来编码含义。知识图与高级计算语言学相结合,可用于量化公司对人工智能、机器人和 ESG 等目标主题的暴露程度,方法是处理官方文件、政府奖励和专利等文档,这些文档提供了公司业务、产品、服务和知识产权的整体视图。

随着被动投资在过去 10 年的出现,人们对主题 ETF 策略越来越感兴趣,这些策略捕捉未来可能扰乱经济的技术和大趋势。利用知识图表和基于语义的主题投资的金融产品示例包括:

  1. Yewno 旗下 STOXX AI 全球 AI 指数;
  2. 纳斯达克 Yewno 北美大麻经济指数;
  3. 纳斯达克 Yewno 未来流动性指数;
  4. 纳斯达克 Yewno AI &大数据指数;
  5. 纳斯达克 Yewno 颠覆性基准指数;
  6. iSTOXX Yewno 发达市场区块链指数;
  7. 纳斯达克 Yewno 全球创新科技指数;
  8. AMUNDI STOXX 全球人工智能 ETF (GOAI),与 Yewno 合作;
  9. Coincapital STOXX 区块链专利创新指数基金(LDGR),与 Yewno 合作;
  10. DWS 的人工智能和大数据 ETF (XAIX:GR),与 Yewno 合作。

早在 2018 年初,彭博写了一篇关于耶诺斯托克人工智能指数的文章,提出了一个挑衅性的问题“你会让机器人选择你的投资组合吗?”。快进到今天,欧洲最大的资产管理公司(Amundi)用一只 ETF 给出了答案,这只 ETF 在 AUM 复制了 Yewno 的 AI 指数,价值超过 1 . 4 亿美元。

Bloomberg article about Yewno’s AI Index.

每个人都已经可以访问核心财务数据。知识图表如何补充现有的数据集,如基本面,估计,所有权等?

作为替代数据引擎的知识图

企业现在拥有的一个机会是替代数据,即传统金融领域之外的内容,但可以用来提供对金融投资的见解,如航运物流数据、法庭文件、专利、临床试验和社交媒体互动。

根据德勤引用 Opimas 的一份报告,2020 年,这类数据的支出可能超过 70 亿美元,每年增长 21%。来源 : Adena Friedman,纳斯达克总裁兼首席执行官。

虽然替代数据的增加是一个值得关注的重要趋势,但像这样的数据集很难处理、整合并从中产生见解。如今,大多数替代数据来自不同的来源,并且通常是非结构化的格式。简单地吸收更多的数据并不一定会带来更多的洞察力— 信息并不等同于知识

当被问及什么数据集在不久的将来最有价值时,50 家对冲基金和机构资产管理公司表示,不仅包括基本面和定价数据等传统内容,还包括有关人员、企业行动主义和治理以及事件和转录的信息。总的来说,这些数据集遵循不同的频率(每日、每月、每季度)、符号系统标准、数据格式(结构化和非结构化),有时甚至遵循不同的语言。知识图是从这种异构和动态的内容源中生成洞察力的正确解决方案,这些内容源的数量和复杂性只会随着时间的推移而增长。

Core Content Ranked by (Future) Value according to a survey performed by Factset and Coleman Parkes with 50 hedge funds and institutional asset management firms across the U.S., EMEA, and APAC.

Yewno 的知识图能够从不同的数据点进行推断,并提取不同信息领域的见解。通过这种方式,Yewno 的知识图充当了一个替代数据引擎,它从不同种类的替代数据源中提取、处理、链接和表示知识的原子单位——T2 概念。

A Sample of Yewno’s Alternative Data Feeds.

Yewno 目前提供一系列的替代数据源,授权给主要的对冲基金和机构资产管理公司,由包括 Factset 和纳斯达克在内的值得信赖的合作伙伴分发。

如今基于人工智能的投资面临哪些关键挑战,知识图表如何帮助解决这些挑战?

公*、问责和透明(FAT)问题越来越多,但大多仍未被注意到,尤其是在人工智能金融应用中。人们越来越担心,人工智能在投资中应用的复杂性,可能会降低“责怪机器”的相应决策的合理性。在这个领域有一个灰色区域,由于这种方法的复杂性,确定谁应该对基于人工智能的模型所做的决定负责并不总是容易的。

FAT ML is an annual Conference that brings together a growing community of researchers and practitioners concerned with fairness, accountability, and transparency in machine learning. Source: http://www.fatml.org/.

在知识图中,数据的含义可以与图中的数据一起编码,作为知识库本身的一部分。因此,知识图可以是自描述的,即它的知识库可以维护和解释它所包含的知识。这样,知识图表可以作为解决方案的一部分提供透明度和可解释性,从而促进问责制和公*性。

结论

投资就是识别关系,发现隐藏的风险和机会。金融行业对知识图表的采用势不可挡,其使用将很快从竞争优势转变为必备。

Yewno 的知识图可以作为一个可扩展的推理和替代数据引擎,同时通过将透明度作为解决方案的一部分来解决主要的人工智能挑战。

机器学习的知识象限

原文:https://towardsdatascience.com/knowledge-quadrant-for-machine-learning-5f82ff979890?source=collection_archive---------21-----------------------

当今世界上部署的大多数机器学习系统都是从人类反馈中学习的。例如,自动驾驶汽车可以理解停车标志,因为人类已经在从汽车上拍摄的视频中人工标记了 1000 个停车标志的例子。这些标记的例子教授了汽车中部署的自动识别停车标志的算法。

然而,大多数机器学习课程几乎只关注算法,而不是系统的人机交互部分。这可能会给从事现实世界机器学习的数据科学家留下很大的知识缺口,他们将在数据管理上花费更多时间,而不是构建算法。没有人在回路中的机器学习背景,数据科学家经常试图将算法设计和训练数据创建作为完全独立的活动。如果你能结合你的数据和算法策略,算法会更快更准确,所以这是一个错过的机会。

人在回路中的机器学习是解决当今技术中最重要的问题之一的机会:人类和机器应该如何合作解决问题?

这是我为机器学习创建的一个知识象限,用来框定问题和方法:

我们可以将这些象限分为:

  1. 已知的知识:你的机器学习模型今天可以自信而准确地做什么。
  2. 已知的未知:你的机器学习模型今天不能自信地做什么。
  3. 未知的知识:预先训练好的模型中的知识,可以适应你的任务。
  4. 未知的未知:你的机器学习模型中的差距,今天它是盲目的。

我们如何解决每个机器学习知识象限中的问题?

除了单个象限(下面将详细介绍)之外,机器学习知识象限中的行和列对于我们如何解决问题也有重要的共享属性:

最上面一行可以在您当前的模型中解决:模型今天在哪里有信心或没有信心?

最下面的一行意味着在你的模型之外寻找:对于不同的未标记的项目,你应该使用什么样的其他预先训练好的模型和采样方法?

左栏可以通过正确的算法设计来解决:我们如何构建可解释的精确模型并利用预先训练的模型?

右栏可以通过人工交互来解决:我们如何通过主动学习对最优的未标记数据点进行采样,并获得准确的人工标注?

我们如何构建系统来解决每个象限中的问题?

对于迁移学习,机器学习社区仍然处于运动的开始。预训练模型仅在大约 5 年前起飞(甚至更*一些,在机器学习的一些领域,如自然语言处理),因此我们仍在学习利用预训练模型和嵌入的最佳方法,特别是在主动学习和注释的上下文中。

对于我们未知的未知事物,人们今天使用的各种方法甚至没有一个通用的名称,这些方法包括:基于聚类的采样、异常值、异常检测、代表性采样、现实世界多样性采样等。这些方法是从机器学习世界的不同部分被吸收到主动学习中的,因此没有通用的名称,所以我将它们归类到“多样性采样”下:这个象限中的所有方法都试图在更广泛、更多样化的数据点集合上使模型更加准确。

有许多算法可以解决其中一个象限中的问题。例如,不确定性采样有一些常见的算法,如最小置信度、置信界限和基于熵的置信度,其中任何一种算法都可能是对数据中的最佳“已知未知”进行采样的最佳选择。

对于你的机器学习架构,你需要让它能够被主动学习所解释。例如,如果您使用 softmax 方程来生成预测的概率分布,您可能无法相信预测的“置信度”的绝对值。把置信度当作一个排名就足够了,你可以忽略实际值。或者,您可能决定公开您的模型下游处理系统的层,这些层可以更准确地确定置信度。或者作为一种更高级的策略,您甚至可以开发一个并行架构,在您的模型中有两个最终层(或者如果使用基于 transformer 的模型,则有两个注意力头):一个预测标签,第二个确定该预测的置信度。

一个结合了所有四个象限中的解决方案的战略的医疗保健示例

有一些聪明的策略可以将这些象限中的两个或多个问题的解决方案结合起来。

例如,假设您想从医疗保健文档的文本中获取额外的信息。也许你想知道哪些疾病被提到的频率更高,这样你就可以监控潜在的流行病——这是我以前工作过的一个用例。

您可以从使用迁移学习开始,通过调整一个 XLNet 预训练模型来构建一个新模型,以提取您的医疗保健文档中与医疗相关的信息。

然而,XLNet 是在公共网站和其他公开文本上预先训练的,这看起来与你的私人医疗保健文档有很大不同。所以,你需要获取更多的训练实例。

您决定从您的医疗保健文档中抽取未标记的项目,这些项目看起来与 XLNet 接受训练的开放数据不同。为了进一步细化您采样的未标记项目,您今天仅从您的分类器中采样具有< 50%置信度的项目,因为它们最有可能包含错误。

虽然在我们的医疗保健相关示例中,所有工作流都像常识一样,但我们需要正确处理许多实施细节,因为它结合了迁移学习、不确定性采样和多样性采样。您必须决定哪种迁移学习、不确定性采样和多样性采样算法最适合您的数据和用例。

人在回路中的机器学习资源

20 年来,我一直在构建结合人类和算法方法进行机器学习的系统。看到变化如此之大很有趣:

[## 训练数据的简要历史

在过去的 25 年中,培训数据发生了怎样的变化?

towardsdatascience.com](/a-brief-history-of-training-data-9c513fc95b3e)

体验最新进展也很有趣:

[## 使用 StyleGAN 创建新脚本

对前 65,000 个 Unicode 字符应用 StyleGAN 以生成新字符

towardsdatascience.com](/creating-new-scripts-with-stylegan-c16473a50fd0)

为了继续分享我学到的更多东西,我将在未来几个月发表一系列文章和开源代码。本文是第一篇,下一篇将深入探讨不确定性采样。大多数算法是在十多年前发明的,但根据机器学习的新神经方法重新检查是令人兴奋的。

这些例子和开源代码也可以在我最*发布的教科书《人在回路中的机器学习:

[## 人在回路中的机器学习

我学到了很多以前从未想过的关于机器学习的新东西。

www.manning.com](https://www.manning.com/books/human-in-the-loop-machine-learning)

文章和开源代码是独立的,但是如果你想更深入地了解这些主题,请查阅这本书!教科书也将在接下来的几个月里逐章发布。如果你知道一些相关和有趣的研究或我应该强调的人在回路中的机器学习的实际例子,请让我知道!

对于任何象限的解决方案,有一些算法是容易实现的低挂果实,也有一些解决方案将在计算上或实现上非常难以实现。与大多数事情一样,您应该从简单开始,只在需要时才开始构建更复杂的解决方案。关于这一点,下面是第一个开源代码示例:

[## rmunro/pytorch_active_learning

PyTorch 主动学习入门。为 rmunro/pytorch_active_learning 的发展做出贡献,创建一个…

github.com](https://github.com/rmunro/pytorch_active_learning)

它用不到 500 行代码解决了四个象限中的三个象限(除了迁移学习之外的一切),使用了一个类似于上面医疗保健例子的灾难响应场景。

从技术角度来说,我已经用 PyTorch 编写了大部分代码(并将在最终发布之前将整本书转换成 py torch——其中一章目前在 Numpy 中)。因此,对于用 PyTorch 构建人在回路中的机器学习系统的人来说,这些代码会特别有趣。然而,无论您选择何种框架或语言进行编码,这些示例都足够通用,足以让您理解!

罗伯特·芒罗【2019 年 7 月

面部表情识别中的偏见

原文:https://towardsdatascience.com/knowyourai-developing-a-framework-to-address-bias-in-facial-expression-recognition-b3b8040b0a68?source=collection_archive---------22-----------------------

Image: A dancer depicting the navarasa (nine emotions), source: shakti-e.monsite.com.

我如何使用南亚艺术美学来建立一个卷积神经网络。

我从小到大最喜欢的电视节目之一是探索频道的 docu 系列节目“它是如何制作的”这是一场揭示日常用品——从铝箔到实验室玻璃器皿——是如何制作的展览。当你观看自动化机器时,解说员*静的声音解释了这个过程,有时在工厂工人的帮助下,毫不费力地快速建造物体。考虑你周围的物理对象;你可能会有根据地猜测它们是如何制成的或者是由什么制成的。但是,如果我让你告诉我,当你看着手机解锁时,你让 Siri 或 Alexa 为你做一些事情,或者在你打字之前,单词和整个句子是如何自动完成的,会发生什么呢?换句话说,你知道你的人工智能(AI)是怎么做出来的吗?

A machine testing highlighters after they’ve been made. Source: huffpost.com

AI 无缝地融入了我们的生活,并为我们做出了无数甚至我们可能都没有意识到的决定。但是人工智能的存在不仅仅是帮助我们完成日常任务。人工智能为我们做出的决定有可能会有偏差。使用“犯罪风险评估算法的警察部门正瞄准低收入和少数族裔人口,因为他们更有可能犯罪,无人驾驶的汽车无法检测深色皮肤的行人,许多大型科技公司很难识别女性和有色人种的面孔——这样的例子不胜枚举。现在比以往任何时候都更重要的是#了解你的未来。

在我对事物如何运作的好奇心的驱使下,我决定建立自己的人工智能系统,它不会使对代表性不足的社区的偏见永久化。我开发了一个面部识别系统,该系统基于一个解决人工智能偏见的框架,从人们的脸上检测情绪。在这篇文章中,我将向你介绍我开发这个项目的主要步骤,但是如果你想更深入地了解我的代码和分析,请查看我的 GitHub 库。

I developed a facial recognition system that detects emotions from people’s faces.

步骤 1:理解人工智能中的偏见是如何存在的

当 AI 有偏见时,正在收集的数据不是包容性的,或者是有选择地选择来促进某种(有偏见的)叙事。此外, 为人工智能系统做决策的人会影响项目的结果。最后,用来分析数据的框架当它们实际上是基于特定的社会信仰时,就被理解为科学真理。

Addressing bias in AI by understanding the data (how and what data is collected), the people (who are responsible for collecting and/or analyzing that data), and the frameworks (how the data is analyzed). Credit: Jasmine Vasandani.

以下是我如何确保我没有在我的项目中延续偏见:

  1. 数据:我的数据集包括有色人种、性别不合群的人、年轻人和老年人,以及带面部饰品的人的图像。
  2. 人物:我是一个色彩数据科学家的酷儿女,深受 AI 偏见的影响并深感忧虑。
  3. 框架:为了对情绪进行分类,我脱离了“快乐”、“悲伤”、“愤怒”等一般分类,转而引用了 navarasa (或九种情绪)所定义的情绪。

第二步:使用“纳瓦拉沙”对情绪进行分类

The navarasa. Image credit: Leesa Mohanty.

为了从图像中检测面部表情,我建立了一个卷积神经网络(CNN,或 convnet),它由一系列层组成,这些层处理一幅图像,并告诉你它在图像中“看到”了什么情绪。由我来告诉 convnet 检测哪种类型的情绪。对我来说,重要的是不要用一个通用的框架来理解情绪,因为每种文化都有自己对情绪分类的方式。例如,这里的一个眼色(无论“这里”对你来说是什么意思)可能与其他地方的一个眼色不是一回事。相反,我实现了 navarasa 作为一个框架来对情绪进行分类。纳瓦拉萨在梵文文本 Natya Shastra (公元前 200-200 年或公元前 500-500 年)中被定义,由南亚艺术家和哲学家 Bharata Muni 所写。Natya Shastra 被认为是今天南亚古典艺术的基础文本。这段文字创造了梵语术语 rasa ,字面上可以翻译为“汁液”或“果汁”,但也可以表示“精华”、“味道”、“风味”或“情感”。在文本中,巴拉塔陈述道纳瓦拉萨是“所有人类情感的基础” 组成纳瓦拉萨的九种情绪是:

  • adbhuta (惊愕)
  • bibhatsa (厌恶)
  • bhayanaka (恐惧)
  • 哈斯亚(欢乐)
  • 卡鲁纳(悲伤)
  • 鲁德拉(愤怒)
  • 圣诞老人(和*)
  • srngara (爱情)
  • veera (信心)

navarasa 可以有不同的翻译,但我还是坚持上面的翻译。对我来说,使用 navarasa 作为情绪分类的框架只是第一步。在这个项目未来的迭代中,我希望实现其他文化情感框架,以更好地通过人工智能来表现人类表达的复杂性。既然我已经确定了我的框架,是时候构建一个图像数据集了,我将用它来输入到 convnet 中。

Classical South Asian dancers depicting the navarasa.

步骤 3:构建包容性影像数据集

我用来构建面部表情检测器的 convnet 的一切都是可定制的。例如,我可以使用 convnet 构建一个系统来告诉我房间图像中显示的是什么家具,根据面部图像判断一个人的年龄,图像中显示的是什么颜色,等等。对于我的 convnet,我已经定制了输出,即纳瓦拉萨。但是现在我需要告诉模型在什么样的图像中检测导航系统。为了建立我的图像数据集,我手工挑选了 1035 张图像,其中大部分人脸代表了有色人种、性别不合群的人、年轻人和老年人,或者戴着面部饰品的人。

我使用的图片来自以下来源:

  • 副的性别谱收藏
  • Flickr
  • Pexels
  • 去飞溅
  • 科技股照片中的有色人种女性
  • 印度电影人脸数据库
  • 田,杨(2000)
  • 巴西菲人脸数据库

建立一个大型数据集,同时确保图像不仅具有包容性,而且能够代表纳瓦拉萨的九种情绪,这是一项艰巨的任务。我为每种情绪收集了几乎等量的图像,但如果有更少的情绪来组织图像,我可以建立一个更大的数据集。我的数据集的质量可以改进,我希望继续建立一个表达各种情绪的包容性面部图像数据库。下面是根据导航系统分类后的图片预览。

My images dataset categorized into the navarasa. Image source for srngara face.

步骤 4:准备图片来训练我的模型

我现在有了我的 convnet 的输入(图像数据集)和输出( navarasa )。现在,我需要准备构建并激活我的 convnet,以便它可以开始从图像中预测面部表情。该过程的下一步是确保所有的图像都是相同的尺寸和相同的配色方案。所以我检查了我的整个图像数据集,将每张图像设置为相同的矩形尺寸,并将其全部灰度化。使用 python,我从图像中检测人脸,将它们裁剪成特定的大小,并将其转换成灰度。我可以选择一个不同的维度来设置所有图像,并将它们保存为彩色图像,但是这些参数特别适合我的数据集。

Image processing: detect face, crop, and convert to grayscale.

除了上述规范之外,我的所有图像都需要采用数值形式,以便由我的 convnet 处理。所以我把这些图像转换成一个由像素值组成的矩阵。在下图中,最左边的图显示了一个像素化的图像,中间显示了对应于像素颜色的值,左边显示了如果仅用像素值来描绘图像的效果。

Far left: pixelated, middle: pixelated with values, far right: pixel values. Image source: http://ai.stanford.edu/~syyeung/cvweb/tutorial1.html.

将图像转换成像素值的矩阵相对容易,下面是如何用 python 实现的基础知识。

**import** **numpy** **as** **np
from** **PIL** **import** Image#Create a variable to store the path to your image directory
image_dir = #image_directory_path#Open the image
img = Image.open(image_dir)#Convert the image to a numpy array
np.array(img)

步骤 5:实现卷积神经网络(convnet)

简单来说,convnet 通过一系列层来处理图像的像素值,其中每一层都定位图像中的视觉趋势。例如,如果某人微笑的图像通过 convnet 的层,则 convnet 会将上翘的嘴、微笑的眼睛和抬高的脸颊识别为属于笑脸的独特特征。因此,当另一个人微笑的图像通过 convnet 时,它会告诉你图像中的人在微笑。下面是一个 convnet 层的可视化。一幅图像(最左边的输入)通过一个 convnet 的各层,输出是九个纳瓦拉萨之一。如果你想更深入地了解 convnets,请查看这个视频教程。

An example of what the layers of a convnet look like. In this example, if the input image were to be passed through the model, its output would be “santa” (peace).

Convnets 最适合大型数据集,但我的数据集相对较小,只有 1000 多张图片。幸运的是,有一个叫做[ImageDataGenerator](https://keras.io/preprocessing/image/)的工具可以解决我的小数据集问题。通过实现ImageDataGenerator,我的数据集中的每张图片都得到了细微的调整,比如翻转、放大、倾斜等等。这个过程欺骗了 convnet,让它认为我正在处理一个更大的独特图像数据集。如果你想知道我构建的 convnets 的精度和损耗值,请查看我的 GitHub 库。

An example of how an image gets altered to trick the convnet into thinking there are new images being introduced to it. Image source.

第六步:从图像中预测“纳瓦拉沙”

最后,我现在可以根据 convnet 认为图像表达的情绪来生成预测。convnet 只会预测它认为哪个纳瓦拉萨在图像中被表达,它还会告诉你它在图像中检测到了其他纳瓦拉萨中的哪个。

PREDICTION #1.

在“预测 1”可视化中,有一个正在表达 veera (信心)的人的图像。convnet 做出了准确的预测,并有 55%的把握在图像中检测到了 veera 。convnet 还在图像中看到了 roudra(愤怒)、karuna(悲伤)和其他情绪的痕迹。由于 veera 收到的概率最高,因此 convnet 选择这种情绪作为最终预测。

PREDICTION #2. Image Source.

在“预测 2”可视化中,有一个人正在表达 adbhuta(惊讶)的图像,但 convnet 的最强预测只有 15%,而且是针对 bhayanaka(恐惧)的不正确情绪。不准确的预测可能是由许多原因造成的,其中一些原因是该图像可能在其特定的 rasa(情感)上与其他图像不相似,照片的质量差,等等。

PREDICTION #3.

在“预测 3”可视化中,有一个人正在表达 hasya (喜悦)的图像。convnet 几乎 100%确定这是某人表达喜悦的图像。

结论和后续步骤

Artistic depiction of the navarasa. Source.

完全使用开源资源并在有限的时间框架内工作,我能够建立一个人工智能系统,它不会使对服务不足的社区的偏见永久化。首先,我确定了人工智能中的偏见是如何延续的:通过收集什么数据,谁解释数据,以及如何分析数据。在我的项目中,我使用这个框架来直接解决和减轻偏见。对我来说,确定我的下一步很容易,那就是建立一个包容性的图像数据集,并开发一个基于文化特定情感的预测人工智能。如果有更多的时间和资源,我会扩大我的数据集,以包括更多关于纳瓦拉沙的图像和艺术描述,与合作者一起工作,并测试更多的人工智能方法。总的来说,我对这个项目的结果很满意,因为它帮助我开发了一个基于项目的框架来解决人工智能中的偏见。

作为这篇文章的读者,无论你是否是人工智能专家,我希望我已经激发了你对#KnowYourAI 的好奇心。

要查看这个项目中使用的代码,请查看我的 GitHub 资源库

A classical dancer depicting the navarasa.

感谢在我完成这个项目时支持和指导我的以下人员:Anuva Kalawar、ADI wid(Boom)Devahastin Na Ayudhya、Matthew Brems、Riley Dallas、Tim Book。再次特别感谢 Anuva Kalawar,没有他,这个项目就不会存在。

Jasmine Vasandani 是一名数据科学家。你可以在这里了解她的更多:www.jasminev.co/

Kohonen 自组织地图

原文:https://towardsdatascience.com/kohonen-self-organizing-maps-a29040d688da?source=collection_archive---------2-----------------------

一种特殊类型的人工神经网络

EMNIST Dataset clustered by class and arranged by topology

背景

自组织地图是由芬兰教授和研究员 Teuvo Kohonen 博士于 1982 年提出的,它是一种无监督的学习模型,旨在应用于维护输入和输出空间之间的拓扑很重要的情况。该算法的显著特点是高维空间中相*的输入向量也被映射到 2D 空间中的邻*节点。它本质上是一种降维方法,因为它将高维输入映射到低维(通常是二维)离散表示,并保留其输入空间的底层结构。

一个有价值的细节是,整个学习是在没有监督的情况下进行的,即节点是自组织的。它们也被称为特征图,因为它们本质上是重新训练输入数据的特征,并且简单地根据彼此之间的相似性将它们自己分组。这对于将复杂或大量的高维数据可视化,并将它们之间的关系表示到低维(通常是二维)域中,以查看给定的未标记数据是否具有任何结构,具有实用价值。

结构

Kohonen Architecture

自组织映射(SOM)在结构和算法特性上都不同于典型的人工神经网络。首先,它的结构由单层线性 2D 神经元网格组成,而不是一系列层。该网格上的所有节点都直接连接到输入向量,但彼此不连接,这意味着节点不知道其邻居的值,并且仅更新其连接的权重作为给定输入的函数。网格本身就是地图,它在每次迭代中根据输入数据的输入来组织自己。这样,在聚类之后,每个节点具有其自己的 (i,j) 坐标,这允许人们通过勾股定理来计算 2 个节点之间的欧几里德距离。

Kohonen network’s nodes can be in a rectangular (left) or hexagonal (right) topology.

属性

此外,自组织映射使用与纠错学习相反的竞争学习来调整其权重。这意味着在每次迭代中只有一个节点被激活,其中输入向量的实例的特征被呈现给神经网络,因为所有节点竞争对输入做出响应的权利。

所选结点(最佳匹配单元(BMU))是根据当前输入值和格网中所有结点之间的相似性选择的。

选择在输入向量和所有节点之间具有最小欧几里德差的节点以及其在某个半径内的相邻节点,以稍微调整它们的位置来匹配输入向量。

通过遍历格网上的所有结点,整个格网最终会与完整的输入数据集相匹配,相似的结点会被组合到一个区域,而不相似的结点会被分开。

A Kohonen model with the BMU in yellow, the layers inside the neighbourhood radius in pink and purple, and the nodes outside in blue.

变量

  • t 是当前迭代
  • n 是迭代极限,即网络可以经历的总迭代次数
  • λ是时间常数,用于衰减半径和学习速率
  • i 是节点网格的行坐标
  • j 是节点网格的列坐标
  • d 是节点和 BMU 之间的距离
  • w 是权重向量
  • w_ij(t) 是网格中节点 i,j 与输入向量在迭代 t 处的实例之间连接的权重
  • x 是输入向量
  • x(t) 是输入向量在迭代 t 时的实例
  • α(t) 为学习率,在区间[0,1]内随时间递减,保证网络收敛。
  • β_ij(t) 是邻域函数,单调递减,表示节点 i,j 到 BMU 的距离,以及它对步骤 t 的学习的影响。
  • ∑(t)是邻域函数的半径,其确定在更新向量时在 2D 网格中检查多远的邻居节点。随着时间的推移逐渐减少。

算法

  1. 将每个节点的权重 w_ij 初始化为随机值
  2. 选择一个随机输入向量 x_k
  3. 重复第 4 点。和 5。对于图中的所有节点:
  4. 计算输入向量 x(t) 和与第一节点相关联的权重向量 w_ij 之间的欧几里德距离,其中 t,I,j = 0。
  5. 追踪产生最小距离 t 的节点。
  6. 找到整体最佳匹配单元(BMU),即与所有计算出的单元距离最小的节点。
  7. 确定 Kohonen 图中 BMU 的拓扑邻域 βij(t) 其半径 σ(t)
  8. 对 BMU 邻域中的所有节点重复:通过添加输入向量 x(t) 和神经元的权重 w(t) 之间的差的一部分来更新 BMU 邻域中的第一个节点的权重向量 w_ij
  9. 重复整个迭代过程,直到达到选定的迭代极限 t=n

步骤 1 是初始化阶段,而步骤 2–9 代表训练阶段。

公式

根据以下公式对变量进行更新和更改:

邻域内的权重被更新为:

第一个等式告诉我们,节点 i,j 的新的更新权重 w_ij (t + 1) 等于旧的权重 w_ij(t) 和旧的权重与输入向量 x(t) 之差的一部分的总和。换句话说,权重向量向输入向量“移动”得更*。要注意的另一个重要因素是,更新的权重将与邻域半径中的节点和 BMU 之间的 2D 距离成比例。

此外,相同的等式 3.1 没有考虑到学习与节点距 BMU 的距离成比例的影响。更新的权重应该考虑这样的因素,即学习的效果在邻域的末端接*于零,因为学习的量应该随着距离而减少。因此,第二个方程增加了额外的邻域函数因子 βij(t) ,是更精确的深度方程。

半径和学习率都类似地随时间呈指数衰减。

邻域函数的影响 β_i(t) 计算如下:

每个节点的权重向量和当前输入实例之间的欧几里德距离是通过勾股公式计算的。

从所有节点的计算距离中选择 BMU 作为最小距离。

进一步阅读

  • 更深入地阅读算法的各个方面:https://eklavyafcb.github.io/som.html
  • 在https://github.com/EklavyaFCB/EMNIST-Kohonen-SOM可以找到该算法的一个很好的实现

kt rain:Keras 的一个轻量级包装器,用于帮助训练神经网络

原文:https://towardsdatascience.com/ktrain-a-lightweight-wrapper-for-keras-to-help-train-neural-networks-82851ba889c?source=collection_archive---------9-----------------------

ktrain 是一个在深度学习软件框架 Keras 中帮助构建、训练、调试和部署神经网络的库。(从v0.7开始,ktrain 在 TensorFlow 中使用tf.keras而不是独立的 Keras。)受 fastai 库的启发, ktrain 只需几行代码,就能让您轻松:

  • 在给定数据的情况下,使用学习率查找器估计模型的最佳学习率
  • 采用学习率计划,如三角学习率政策、1 周期政策和 SGDR 来更有效地训练您的模型
  • 为文本分类(例如,NBSVM、fastText、带有预训练单词嵌入的 GRU)和图像分类(例如,ResNet、Wide Residual Networks、Inception)采用快速且易于使用的预设模型
  • 加载和预处理各种格式的文本和图像数据
  • 检查错误分类的数据点,以帮助改进模型
  • 利用简单的预测 API 保存和部署模型和数据预处理步骤,对新的原始数据进行预测

ktrain 是开源的,可以在 GitHub 这里获得。它需要 Python 3,可以用 pip 安装如下:pip3 install ktrain

我们将通过例子展示几个关于 ktrain 的用例。

将模型和数据包装在学习者对象中

ktrain 设计用于与 Keras 无缝协作。在这里,我们加载数据并定义模型,就像您在 Keras 中通常所做的那样。以下代码直接复制自 Keras fastText 文本分类示例。它加载 IMDb 电影评论数据集,并定义一个简单的文本分类模型来推断电影评论的情感。

*# load  and prepare data as you normally would in Keras*
**from** **tensorflow**.**keras.preprocessing** **import** sequence
**from** **tensorflow.keras.datasets** **import** imdb
NUM_WORDS = 20000
MAXLEN = 400
**def** load_data():(x_train, y_train), (x_test, y_test) = imdb.load_data(num_words=NUM_WORDS)x_train = sequence.pad_sequences(x_train, maxlen=MAXLEN)x_test = sequence.pad_sequences(x_test, maxlen=MAXLEN)**return** (x_train, y_train), (x_test, y_test)
(x_train, y_train), (x_test, y_test) = load_data()*# build a fastText-like model as you normally would in Keras*
**from** **tensorflow.keras.models** **import** Sequential
**from** **tensorflow.keras.layers** **import** Dense, Embedding, GlobalAveragePooling1D
**def** get_model():model = Sequential()model.add(Embedding(NUM_WORDS, 50, input_length=MAXLEN))model.add(GlobalAveragePooling1D())model.add(Dense(1, activation='sigmoid'))model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])**return** model
model = get_model()

要使用 ktrain ,我们只需使用get_learner函数将模型和数据包装在一个ktrain.Learner对象中:

import **ktrain**
learner = **ktrain.get_learner**(model, train_data=(x_train, y_train),val_data = (x_test, y_test))

默认的批处理大小是 32,但是可以通过向get_learner提供一个batch_size参数来改变。学习者对象有助于以各种方式训练您的神经网络。例如,调用学习者对象的fit方法允许你以不同的学习速度进行交互式训练:

# train for three epochs at 0.005
**learner.fit**(5e-3, 3)# train for additional three epochs at 0.0005
**learner.fit**(5e-4, 3)

由学习者对象包装的底层 Keras 模型总是可直接访问的,如下:learner.model

接下来,我们展示了学习者对象也可以用于找到一个好的初始学习率,并且容易地使用各种不同的学习率计划,这些计划在训练期间自动改变学习率。

调整学习率

学习率是在神经网络中设置的最重要的超参数之一。各种优化器(如 Adam 和 SGD)的默认学习速率可能并不总是适合给定的问题。神经网络中的训练包括最小化损失函数。如果学习率太低,训练将会很慢或者停滞不前。如果学习率太高,损失将无法最小化。这两种情况都会对模型的性能产生负面影响。要为您的模型找到一个最佳的学习率,可以通过以低学习率开始并逐渐增加学习率来模拟训练。 Leslie Smith 展示了当绘制学习率与损失的关系图时,与持续下降的损失相关的最大学习率是一个很好的培训选择。他将此称为 LR 范围测试(也称为 LR Finder)。遵循与 fastai 库类似的语法,这可以在 ktrain 中完成,如下所示:

**learner.lr_find()
learner.lr_plot()**

上面的代码将为上面加载的模型和数据显示以下图形:

We must select the maximal learning rate where the loss is still falling prior to divergence.

根据该图,0.005 的学习率似乎是一个合理的选择,因为损失在更高的学习率下开始发散。

学习费率表

许多研究表明,在训练过程中以各种方式改变学习率可以提高神经模型的性能,使损失最小化,并提高验证的准确性。例如,除了最初的1 周期论文之外,Sylvain Gugger 的本实验中还演示了具有循环动量的1 周期学习率计划的好处。 ktrain 允许您轻松采用几种不同的学习率策略。这里,我们展示一些例子:

ktrain 中训练模特的不同方法:

# employs a static learning rate of 0.005 for 3 epochs
**learner.fit**(0.005, 3)# employs an SGDR schedule with a cycle length of one epoch.
# learning rate is varied between 0.005 and near-zero value.
**learner.fit**(0.005, 3, cycle_len=1)# employs an SGDR schedule with a cycle length
# that increases by a factor of 2 each cycle
**learner.fit**(0.005, 3, cycle_len=1, cycle_mult=2)# employs the 1cycle learning rate policy
**learner.fit_onecycle**(0.005, 3)# employs a triangular learning rate policy with automatic stopping
**learner.autofit**(0.005)# employs a triangular learning rate policy with both maximum
# and base learning rates reduced when validation loss stalls
**learner.autofit**(0.005, 20, reduce_on_plateau=3)

我们将在下面详细介绍每一种方法,并从 SGDR 学习率政策开始。

SGDR 学习率政策

带重启的随机梯度下降(或 SGDR) 在用前述学习率探测器识别的初始学习率和接*零的学习率之间循环学习率。使用余弦退火来衰减学习速率。fit方法允许你以类似于 fastai 库的语法轻松使用 SGDR 学习率策略。当提供 cycle_len 参数时,余弦退火用于衰减周期持续时间内的学习速率。这里,我们显示了两个周期,每个周期具有一个时期的长度:

SGDR: learner.fit(0.005, 2, cycle_len=1)

cycle_mult 参数以指定的因子增加循环的长度。这里,周期长度随着每个周期而加倍( cycle_mult=2 ):

SGDR: learner.fit(0.005, 3, cycle_len=1, cycle_mult=2)

1 周期和三角学习率政策

除了fit,还有autofit方法(采用三角学习率策略)和fit_onecycle方法(采用1 周期策略)。两者都是由 NRL 海军研究实验室的 Leslie Smith 提出的。fit_onecycle方法在前半段训练中将学习速率从基本速率提高到最大速率,在后半段训练中将学习速率衰减到接*零值。最大学习率是使用上述学习率查找器设置的。

1cycle policy: learner.fit_onecycle(0.005, 3)

此外,如果将 Adam、Nadam 或 Adamax 优化器与fit_onecycle一起使用,动量在 0.95 和 0.85 之间循环,使得动量在低学习率时高,动量在高学习率时低。以这种方式改变动量在本文中被提出,并被证明可以加速收敛。

cyclical momentum in the 1cycle policy

autofit方法简单地在每个时期执行一个周期策略(可以认为是三角策略的变体):

Triangular Policy: learner.autofit(0.005, 2)

像这样每个时期执行一个周期,更适合与明显有效的内置 Keras 训练回调一起使用。这样的 Keras 回调可以很容易地通过autofit的方法参数来启用,例如early _ stopping(early stopping 回调)、reduce _ on _ plateau(ReduceLROnPlataeu)和check point _ folder(model check point)。例如,当 reduce_on_plateau 启用时,如果验证损失没有改善,峰值和基本学习率都会定期降低(或退火),这有助于提高性能:

Triangular Policy with ReduceLROnPlateau: learner.autofit(0.005, 8, reduce_on_plateau=2)

如果未向autofit提供时期数,则自动启用提前停止回调,训练将继续,直到验证损失不再增加。也有更多的理由让autofit进一步微调训练过程。在 Jupyter 笔记本中键入help(learner.autofit)了解更多详情。最后,虽然这里没有显示,但是autofit方法(像 1 周期策略)在 0.95 和 0.85 之间循环动量。

在前面的章节中,我们手动定义了一个模型,并在 ktrain 之外加载了数据。 ktrain 公开了许多方便的函数,可以轻松地从各种来源加载数据,并毫不费力地使用一些非常强大的基线模型。我们将展示一个图像分类和文本分类的例子——每一个都只需要几行代码。

图像分类:给狗和猫分类

图像分类和深度学习介绍中使用的一个标准数据集是狗对猫数据集。我们将在 ktrain 中使用该数据集作为图像分类的示例。在下面的代码块中,images_from_folder函数用于加载训练和验证图像作为 Keras 目录迭代器对象,并为训练图像增加数据。然后使用image_classifier函数在 ImageNet 上建立一个 ResNet50 模型。我们在目测了lr_plot生成的剧情后,选择 7e-5 作为学习率。由于我们在本例中调用autofit时没有指定历元数,当验证损失没有改善时,训练将自动停止。默认情况下,提前停止耐心值为 5,而减少延迟耐心值仅为 2。这些可以使用autofit的 early_stopping 和 reduce_on_plateau 参数来更改。该代码块的精度通常在 99.35%99.55% 之间,如本笔记本所示。

# import ktrain modules
import **ktrain**
from **ktrain import vision as vis**# get default data augmentation with 
# horizontal_flipping as only modification
data_aug = **vis.get_data_aug**(horizontal_flip=True)# load the data as Keras DirectoryIterator generators
(trn, val, preproc) = **vis.images_from_folder**(datadir='data/dogscats',data_aug=data_aug,train_test_names=['train', 'valid'], target_size=(224,224), color_mode='rgb')# build a pre-trained ResNet50 model and freeze first 15 layers
model = **vis.image_classifier**('pretrained_resnet50', trn, val, freeze_layers=15)# wrap model and data in a Learner object
learner = **ktrain.get_learner**(model=model, train_data=trn, val_data=val, workers=8, use_multiprocessing=False,batch_size=64)
**learner.lr_find()** # simulate training to find good learning rate
**learner.lr_plot()** # visually identify best learning rate# train with triangular learning rate policy
# ReduceLROnPlateau and EarlyStopping automatically enabled.
# ModelCheckpoint callback explicitly enabled.
**learner.autofit**(7e-5, checkpoint_folder='/tmp')

通过在训练后调用learner.view_top_losses(preproc, n=3),我们可以查看验证集中分类错误最严重的前 n 个例子。这可以揭示如何改进您的模型或数据处理管道,以及是否要删除“垃圾”数据的数据集。例如,在狗和猫的数据集中,下图是验证集中分类错误最多的示例之一:

A misclassified example in the validation set

正如你所看到的,这张图片被贴上了“猫”的标签,尽管图片上同时出现了一只狗和一只猫,但狗的特征更加突出。这可能会有问题,因为该数据集将类视为互斥的。类别不互斥的数据集称为多标签分类问题,将在本文稍后讨论。

对新数据的预测

有了训练好的模型,我们可以将我们的模型和由images_from_folder返回的预预测对象包装在一个预测器对象中,从而轻松地对新的原始图像进行分类:

The Predictor object automatically preprocesses raw data before making predictions.

preproc 对象自动预处理并适当转换原始数据,以便准确地做出预测。预测器对象可以保存到磁盘,并在以后作为已部署应用程序的一部分重新加载:

有关详细的解释和结果,请参见我们的图像分类教程笔记本。

文本分类:识别有毒在线评论

Kaggle 上的有毒评论分类挑战涉及将维基百科评论分类为一个或多个所谓的有毒评论的类别。有毒在线行为的类别包括有毒重度 _ 有毒淫秽威胁侮辱身份 _ 仇恨。与前面的例子不同,这是一个多标签分类问题,因为类别不是互斥的。例如,一条评论可能属于多个类别的有害在线行为。 ktrain 从数据中自动检测多标签分类问题,并适当配置内置模型。

数据集可以从比赛现场以 CSV 文件的形式下载(即下载文件 train.csv )。我们将使用texts_from_csv方法加载数据,该方法假设 label_columns 字段已经在电子表格中进行了一次热编码(Kaggle 的 train.csv 文件就是这种情况)。然后,我们将使用text_classifier方法加载一个类似 fastText 的模型。最后,我们使用autofit方法来训练我们的模型。在第二个示例中,我们明确地将历元数指定为 8。使用三角形学习率策略,因此执行 8 个三角形循环。

import **ktrain
from ktrain import text as txt**DATA_PATH = 'data/toxic-comments/train.csv'
NUM_WORDS = 50000
MAXLEN = 150
label_columns = ["toxic", "severe_toxic", "obscene", "threat", "insult", "identity_hate"](x_train, y_train), (x_test, y_test), preproc =    **txt.texts_from_csv**(DATA_PATH,'comment_text',label_columns=label_columns,val_filepath=None, max_features=NUM_WORDS, maxlen=MAXLEN,ngram_range=1)# define model a fastText-like architecture using ktrain
model = **txt.text_classifier**('fasttext', (x_train, y_train), preproc=preproc)# wrap model and data in Learner object
learner = **ktrain.get_learner**(model, train_data=(x_train, y_train),val_data=(x_test, y_test))# find a good learning rate
**learner.lr_find()**
**learner.lr_plot()**# train using triangular learning rate policy
**learner.autofit**(0.0007, 8)

上面的代码块在 Titan V GPU 上仅用 6 分钟的训练就实现了大约为 0.98 的 ROC-AUC。如我们 GitHub 项目中的示例笔记本所示,使用带有预训练单词向量的双向 GRU(在 ktrain 中称为“bigru ”)可以获得更好的结果。

和前面的例子一样,我们可以实例化一个预测器对象来轻松地对新的原始数据进行预测:

更多信息

有关 ktrain 的更多信息和细节,请参见 GitHub 上的教程笔记本:

  • 教程笔记本 1: 简介k train
  • 教程笔记本 2: 调整学习率
  • 教程笔记本 3: 图像分类
  • 教程笔记本 4: 文字分类
  • 教程笔记本 5: 从无标签文本数据中学习
  • 教程笔记本 6: 文本序列标注
  • 教程笔记本 7: 图形神经网络
  • 教程笔记本 A1: 关于其他主题的附加技巧,例如为模型设置全局权重衰减、调试 Keras 模型、预览数据扩充方案,以及在 ktrain 中使用内置回调
  • 教程笔记本 A2: 讲解文字和图像分类
  • 教程笔记本 A3: 文字分类与抱脸变形金刚
  • 附加示例

2019–08–16:Google Colab 上使用 ktrain ?请参见 BERT 的演示。

Kubeflow 组件和管道

原文:https://towardsdatascience.com/kubeflow-components-and-pipelines-33a1aa3cc338?source=collection_archive---------14-----------------------

Kubeflow 是一个大的生态系统,一堆不同的开源工具 ML tools。

我想让事情变得简单,因此我们涵盖了组件、管道和实验。通过管道和组件,您可以获得构建 ML 工作流所需的基础知识。Kubeflow 中集成了更多的工具,我将在接下来的文章中介绍它们。

Kubeflow 起源于谷歌。

使在 Kubernetes 上部署机器学习(ML)工作流变得简单、可移植和可扩展。
来源:Kubeflow 网站

Photo by Ryan Quintal on Unsplash

目标

  • 演示如何建造管道。
  • 演示如何创建组件。
  • 演示如何使用组件。
  • 演示如何在笔记本电脑中运行管道和实验。
  • 易于理解和使用的示例

管道

成分

在管道中执行一步的代码。换句话说,一个 ML 任务的容器化实现。
组件类似于函数,它有名称、参数、返回值和主体。流水线中的每个组件独立执行和必须打包成 docker 映像。

The components.

图表

组件之间的表示。它显示了管道正在执行的步骤。

The graph.

管道

流水线描述了机器学习的工作流程,它包括组件和图。

The pipeline.

奔跑

一次运行是一条流水线的单次执行为了比较,所有运行都被保留。

A run is a single execution of a Pipeline.

重复运行

循环运行可用于重复管道运行,如果我们想要以预定的方式在新数据上训练更新的模型版本,这很有用。

实验

类似于工作空间,它包含不同的运行。跑分可以比较。

An overview of all runs in this specific experiment.

组件类型

Kubeflow 包含两种类型的组件,一种用于快速开发,另一种用于重用。

轻量级组件

用于笔记本环境中的快速开发。快速简单,因为不需要构建容器映像。

可重复使用的集装箱组件

可以通过装载到 Kubeflow 管道中来重复使用。这是一个内含 T42 的组件。

要求实施时间

可重用成分

在本节中,您将获得可重用组件的基础知识。

组件结构

组件本身很简单,只由几个部分组成:

  • 组件逻辑
  • 一个组件规格为 yaml。
  • 构建容器需要一个 Dockerfile
  • 一个自述文件解释组件及其输入和输出。
  • 助手脚本构建组件,然后组件推送到 Docker 仓库。

Parts of a reusable Kubeflow component.

部件规格

规范描述了用于 Kubeflow 管道的容器组件数据模型。

以 YAML 格式编写(component.yaml)。

  • 元数据描述组件本身,如名称和描述
  • 接口定义组件的输入和输出。
  • 实现指定组件应该如何执行。

处理输入

一个组件通常需要某种输入,比如训练数据的路径或者模型的名称。它可以消耗多个输入。

  • 在 component.yaml 中定义输入
  • 输入定义为容器的参数
  • 解析组件逻辑中的 参数

The training component might require training data as input and produces a model as output.

处理输出

需要输出来在组件之间传递数据。重要的是要知道流水线中的每个组件都独立执行

  • 组件在不同的进程中运行,不能共享数据。
  • 传递小数据的过程不同于传递大数据的过程。

对于小数据

  • 值可以作为输出直接传递。

对于大数据

  • 大型数据必须序列化为文件,以便在组件之间传递。
  • 上传数据到我们的存储系统。
  • 并且将此文件的一个引用传递给下一个组件。
  • 管道中的下一个组件将获取该引用,并且下载序列化数据。

Dockerize 组件

每个组件都是一个容器映像,需要一个 order 文件来构建映像。

映像构建完成后,我们将组件容器映像推送到 Google 容器注册表

构建组件容器映像并将其上传到 Google 容器注册表只是几行代码:

# build_image.sh
image_name=gcr.io/ml-training/kubeflow/training/train
image_tag=latestfull_image_name=${image_name}:${image_tag}docker build --build-arg -t "${full_image_name}" 
docker push "$full_image_name"

在第一次 docker 推送时,您可能会得到以下错误消息:

您没有执行此操作所需的权限,并且您可能有无效的凭据。要验证您的请求,请遵循以下步骤:https://cloud . Google . com/container-registry/docs/advanced-authentic ation

在这种情况下,只需运行以下 gcloud 命令并再次推送:

$ gcloud auth configure-docker

使用管道

加载组件

有权访问 Docker 存储库和 component.yaml 的每个人都可以在管道中使用组件

Load a component from a component.yaml URL.

然后可以基于 component.yaml 将组件加载到

operation = kfp.components.load_component_from_url(
'[https://location-to-your-yaml/component.yaml'](https://storage.googleapis.com/spielwiese-sascha-heyer/test9/component.yaml'))help(operation)

创建管道

dsl 装饰器通过管道 SDK 提供,用于定义管道并与之交互。dsl.pipeline为返回管道的 Python 函数定义一个装饰器。

[@dsl](http://twitter.com/dsl).pipeline(name='The name of the pipeline',description='The description of the pipeline'
)
def sample_pipeline(parameter):concat = operation(parameter=first)

编译管道

为了编译管道,我们使用了compiler.Compile()函数,它也是管道 SDK 的一部分。编译器生成一个 yaml 定义,Kubernetes 使用它来创建执行资源。

pipeline_func = sample_pipeline
pipeline_filename = pipeline_func.__name__ + '.pipeline.zip'compiler.Compiler().compile(sample_pipeline, pipeline_filename)

创造一个实验

管道总是实验的一部分,可以用 Kubeflow 管道客户端kfp.client()创建。目前无法删除实验。

client = kfp.Client()try:experiment = client.get_experiment(experiment_name=EXPERIMENT_NAME)
except:experiment = client.create_experiment(EXPERIMENT_NAME)print(experiment)

运行管道

为了运行管道,我们使用实验 id 和在前面步骤中创建的编译管道。client.run_pipeline运行管道,并提供与库巴流实验的直接链接。

run_name = pipeline_func.__name__ + ' run'
run_result = client.run_pipeline(experiment.id, run_name, pipeline_filename)

GitHub 上的例子

我创建了一个基本的管道来演示本文中的所有内容。为了简单起见,管道不包含任何特定于 ML 的实现。

https://github . com/SaschaHeyer/Machine-Learning-Training/tree/master/kube flow/lightweight-component-Training

Usage

感谢阅读。
更多如 Kubeflow 整流罩、Katib 等话题敬请关注。

这篇文章的代码可以在GitHub上找到。

您的反馈和问题非常感谢,您可以在 Twitter 上找到我@ HeyerSascha

关于作者

Sascha HeyerIo Annotator 的创始人一个用于文本和图像的 AI 注释*台
,它提供了几种图像和文本注释工具。

诗人的库伯流

原文:https://towardsdatascience.com/kubeflow-for-poets-a05a5d4158ce?source=collection_archive---------5-----------------------

机器学习生产流水线的容器化指南

本系列文章提供了一种在 Kubernetes 上使用 Kubeflow 生产机器学习管道的系统方法。构建机器学习模型只是一个更广泛的任务和过程系统的一部分,这些任务和过程共同交付一个机器学习产品。Kubeflow 使得利用容器化的微服务范例来分离在 Kubernetes 上编排的应用程序的模块化组件成为可能。虽然 Kubernetes 是*台不可知的,但本系列将重点关注在 Google 云*台上部署一个机器学习产品,利用 Google Cloud BigQuery、Google Cloud Dataflow 和在 Google Kubernetes 引擎上编排的 Google Cloud 机器学习引擎。

内容

内容安排如下:

  • 简介
  • 微服务架构
  • 码头工人
  • Kubernetes
  • Kubeflow
  • Kubeflow 管道
  • 在 Kubeflow 管道上部署端到端机器学习解决方案

源代码和贡献:

完整的源代码可以在 Github 上获得。贡献和更正是受欢迎的拉请求。

介绍

机器学习通常被正确地视为使用数学算法来教会计算机学习任务,这些任务在计算上不可编程为一组指定的指令。然而,从工程的角度来看,这些算法的使用只占整个学习过程的一小部分。构建高性能和动态的学习模型包括许多其他重要的组成部分。这些组件实际上主导了交付端到端机器学习产品的关注空间。

典型的机器学习生产管道如下图所示。

从上图中,可以观察到管道中的流程流是迭代的。这种重复模式是机器学习实验、设计和部署的核心。

效率挑战

很容易认识到,在构建学习模型时,流水线需要大量的开发操作来实现从一个组件到另一个组件的无缝转换。这种零件的互操作性产生了机器学习操作,也称为 MLOps。这个术语是机器学习和 DevOps 的混合体。

进行机器学习的传统方式是在 Jupyter 笔记本电脑上执行所有的实验和开发工作,模型被导出并发送给软件开发团队进行部署和端点生成,以集成到下游软件产品中,而 DevOps 团队处理机器的基础设施和配置以进行模型开发。这种单一的工作方式导致机器学习过程不可重用,难以扩展和维护,更难以审计和执行模型改进,并且容易充满错误和不必要的复杂性。

然而,通过将微服务设计模式整合到机器学习开发中,我们可以解决这些问题,并真正简化生产过程。

谷歌云*台上的一句话(GCP)

该教程将重点关注在谷歌云*台的基础设施上开发和部署生产模型。云的优势是易于根据资源需求分发和扩展单个工作流组件。然而,当使用微服务时,容器化管道是机器无关的,可以快速部署在任何其他本地基础设施或公共云服务提供商,如 AWS 或 Azure 上。

谷歌云*台拥有一系列强大的人工智能无服务器服务,我们将整合这些服务来处理生产管道的一些组件。这些服务包括 Google BigQuery,用于暂存我们的转换数据集以进行轻松分析,Google Dataflow 用于大规模数据转换,Google Cloud Machine Learning Engine 用于大规模模型训练和模型部署。

微服务架构

微服务架构是一种开发和部署企业云原生软件应用的方法,它涉及将应用的核心业务功能分离成分离的组件。每个业务功能都代表应用程序作为服务提供给最终用户的一些功能。微服务的概念与整体架构形成对比,后者将应用程序构建为其“单独”功能的组合。

微服务使用表述性状态转移(REST)通信进行交互,以实现无状态互操作性。所谓无状态,我们指的是“服务器不存储关于客户端会话的状态”。这些协议可以是 HTTP 请求/响应 API 或异步消息队列。这种灵活性允许微服务轻松扩展并响应请求,即使另一个微服务出现故障。

微服务的优势

  • 松散耦合的组件使应用程序具有容错能力。
  • 能够横向扩展,使每个组件高度可用。
  • 组件的模块化使得扩展现有功能变得更加容易。

微服务的挑战

  • 软件架构的复杂性增加了。
  • 微服务管理和编排的开销。然而,我们将在接下来的会议中看到 Docker 和 Kubernetes 如何努力缓解这一挑战。

码头工人

Docker 是一个虚拟化应用程序,它将应用程序抽象到被称为容器的隔离环境中。容器背后的想法是提供一个统一的*台,其中包括用于开发和部署应用程序的软件工具和依赖项。

开发应用程序的传统方式是在单个服务器上设计和托管应用程序。这种设置导致了许多问题,包括著名的“它在我的机器上工作,但在你的机器上不工作”。此外,在这种体系结构中,应用程序难以扩展和迁移,从而导致巨大的成本和缓慢的部署。

虚拟机与容器

Left: Virtual machines. Right: Containers

虚拟机(VMs)模拟物理机的功能,使得通过使用虚拟机管理程序来安装和运行操作系统成为可能。虚拟机管理程序是物理机(主机)上的一个软件,它使虚拟化成为可能,在虚拟化中,多个客户机由主机管理。

另一方面,容器通过自己的库和软件依赖关系隔离了应用程序的宿主环境,然而,与 VM 相反,机器上的容器都共享相同的操作系统内核。Docker 是容器的一个例子。

使用 Docker

首先在本地机器上安装 Docker 软件,使其能够运行 Docker 容器。参观 https://www.docker.com/get-started开始吧。

需要注意的关键概念是:

  • docker file:docker file 是一个指定如何创建图像的文本文件。
  • Docker 图像:通过构建 Docker 文件来创建图像。
  • Docker 容器: Docker 容器是图像的运行实例。

下图突出显示了构建映像和运行 Docker 容器的过程。

介绍 DockerHub

DockerHub 是一个托管 Docker 图像的库。

编写 docker 文件时的关键例程

以下是创建 docker 文件时的关键例程。

+------------+-----------------------------------------------------+
| **Command**    | **Description** |
+------------+-----------------------------------------------------+
| **FROM**       | The base Docker image for the Dockerfile.           |
| **LABEL** | Key-value pair for specifying image metadata.       |
| **RUN**        | It execute commands on top of the current image as  |                              |              new layers.                                         |
| **COPY**       | Copies files from the local machine to the          |
|              container filesystem.                               |
| **EXPOSE**     | Exposes runtime ports for the Docker container.     |
| **CMD**        | Specifies the command to execute when running the   |   |              container. This command is overridden if another    |   |              command is specified at runtime.                    |
| **ENTRYPOINT** | Specifies the command to execute when running the   |      |              container. Entrypoint commands are not overridden   |
|              by a command specified at runtime.                  |
| **WORKDIR**    | Set working directory of the container.             |
| **VOLUME**     | Mount a volume from the local machine filesystem to | |              the Docker container.                               |
| **ARG**        | Set Environment variable as a key-value pair when   |              |              building the image.                                 |
| **ENV**        | Set Environment variable as a key-value pair that   | |              will be available in the container after building.  |
+------------+-----------------------------------------------------+

构建并运行一个简单的 Docker 容器

在这个简单的例子中,我们有一个名为date-script.sh的 bash 脚本。该脚本将当前日期赋给一个变量,然后将日期打印到控制台。Dockerfile 会将脚本从本地机器复制到 docker 容器文件系统,并在运行容器时执行 shell 脚本。构建容器的 Dockerfile 文件存储在docker-intro/hello-world中。

***# navigate to folder with images***
cd docker-intro/hello-world

让我们来看看 bash 脚本。

cat date-script.sh*#! /bin/sh*
DATE**=**"**$(**date**)**"
echo "Todays date is $DATE"

让我们来看看文档。

***# view the Dockerfile***
cat Dockerfile*# base image for building container*
FROM docker.io/alpine
*# add maintainer label*
LABEL maintainer**=**"dvdbisong@gmail.com"
*# copy script from local machine to container filesystem*
COPY date-script.sh /date-script.sh
*# execute script*
CMD sh date-script.sh
  • Docker 映像将基于 Alpine Linux 包构建。参见https://hub.docker.com/_/alpine
  • 当容器运行时,CMD例程执行脚本。

建立形象

***# build the image***
docker build -t ekababisong.org/first_image .

生成输出:

Sending build context to Docker daemon  2.048kB
Step 1/4 : FROM docker.io/alpine
latest: Pulling from library/alpine
6c40cc604d8e: Pull complete 
Digest: sha256:b3dbf31b77fd99d9c08f780ce6f5282aba076d70a513a8be859d8d3a4d0c92b8
Status: Downloaded newer image for alpine:latest---> caf27325b298
Step 2/4 : LABEL maintainer="dvdbisong@gmail.com"---> Running in 306600656ab4
Removing intermediate container 306600656ab4---> 33beb1ebcb3c
Step 3/4 : COPY date-script.sh /date-script.sh---> Running in 688dc55c502a
Removing intermediate container 688dc55c502a---> dfd6517a0635
Step 4/4 : CMD sh date-script.sh---> Running in eb80136161fe
Removing intermediate container eb80136161fe---> e97c75dcc5ba
Successfully built e97c75dcc5ba
Successfully tagged ekababisong.org/first_image:latest

运行容器

***# show the images on the image***
docker imagesREPOSITORY                    TAG                 IMAGE ID            CREATED             SIZE
ekababisong.org/first_image   latest              e97c75dcc5ba        32 minutes ago      5.52MB
alpine                        latest              caf27325b298        3 weeks ago         5.52MB***# run the docker container from the image***
docker run ekababisong.org/first_imageTodays date is Sun Feb 24 04:45:08 UTC 2019

用于管理图像的命令

+---------------------------------+--------------------------------+
| **Command**                         | **Description** |
+---------------------------------+--------------------------------+
| **docker images**                   | List all images on the         |   |                                   machine.                       |
| **docker rmi [IMAGE_NAME]** | Remove the image with name     | |                                   IMAGE_NAME on the machine.     |
| **docker rmi $(docker images -q)**  | Remove all images from the     | |                                   machine.                       |
+------------+-----------------------------------------------------+

用于管理容器的命令

+-------------------------------+----------------------------------+
| **Command**                       | **Description** |
+-------------------------------+----------------------------------+
| **docker ps**                     | List all containers. Append -a   |
|                                 to also list containers not      | |                                 running.                         |
| **docker stop [CONTAINER_ID]** | Gracefully stop the container    |                                 |                                 with [CONTAINER_ID] on the       |   |                                 machine.                         |
| **docker kill CONTAINER_ID]**     | Forcefully stop the container    |
|                                 with [CONTAINER_ID] on the       |                              |                                 machine.                         |
| **docker rm [CONTAINER_ID]**      | Remove the container with        |   |                                 [CONTAINER_ID] from the machine. |
| **docker rm $(docker ps -a -q)**  | Remove all containers from the   | |                                 machine.                         |
+------------+-----------------------------------------------------+

运行 Docker 容器

让我们分解下面运行 Docker 容器的命令。

docker run -d -it --rm --name [CONTAINER_NAME] -p 8081:80 [IMAGE_NAME]

在哪里,

  • -d:以分离模式运行容器。该模式在后台运行容器。
  • -it:以交互模式运行,附带终端会话。
  • --rm:退出时取出容器。
  • --name:指定容器的名称。
  • -p:从主机到容器的端口转发(即主机:容器)。

使用 Docker 在nginx网络服务器上提供网页

文档文件

# base image for building container
FROM docker.io/nginx
# add maintainer label
LABEL maintainer="dvdbisong@gmail.com"
# copy html file from local machine to container filesystem
COPY html/index.html /usr/share/nginx/html
# port to expose to the container
EXPOSE 80

建立形象

**# navigate to directory**
cd docker-intro/nginx-server/**# build the image**
docker build -t ekababisong.org/nginx_server .Sending build context to Docker daemon  2.048kB
Step 1/4 : FROM docker.io/nginx
latest: Pulling from library/nginx
6ae821421a7d: Pull complete
da4474e5966c: Pull complete
eb2aec2b9c9f: Pull complete
Digest: sha256:dd2d0ac3fff2f007d99e033b64854be0941e19a2ad51f174d9240dda20d9f534
Status: Downloaded newer image for nginx:latest---> f09fe80eb0e7
Step 2/4 : LABEL maintainer="dvdbisong@gmail.com"---> Running in 084c2484893a
Removing intermediate container 084c2484893a---> 2ced9e52fb67
Step 3/4 : COPY html/index.html /usr/share/nginx/html---> 1d9684901bd3
Step 4/4 : EXPOSE 80---> Running in 3f5738a94220
Removing intermediate container 3f5738a94220---> 7f8e2fe2db73
Successfully built 7f8e2fe2db73
Successfully tagged ekababisong.org/nginx_server:latest**# list images on machine**
docker imagesREPOSITORY                       TAG                 IMAGE ID            CREATED             SIZE
ekababisong.org/nginx_server     latest              0928acf9fcbf        18 hours ago        109MB
ekababisong.org/first_image      latest              773973d28958        20 hours ago        5.53MB

运行容器

**# run the container**
docker run -d -it --name ebisong-nginx -p 8081:80 ekababisong.org/nginx_server**# list containers**
docker psCONTAINER ID        IMAGE                          COMMAND                  CREATED             STATUS              PORTS                  NAMES
b3380cc02551        ekababisong.org/nginx_server   "nginx -g 'daemon of…"   7 seconds ago       Up 4 seconds        0.0.0.0:8081->80/tcp   ebisong-nginx

在运行的服务器上查看网页

打开 web 浏览器并转到:0.0.0.0:8081

清除

**# shutdown the container**
docker stop b3380cc02551**# remove the container**
docker rm ebisong-nginx

将图像推送到 Dockerhub

登录 Docker 并提供您的useridpassword

**# login to docker**
docker login**# tag the image**
docker tag 096e538abc1e ekababisong/ebisong-nginx-server:latest**# push to Dockerhub**
docker push ekababisong/ebisong-nginx-serverThe push refers to repository [docker.io/ekababisong/ebisong-nginx-server]
db4c3e547e3f: Pushed
6b5e2ed60418: Mounted from library/nginx
92c15149e23b: Mounted from library/nginx
0a07e81f5da3: Mounted from library/nginx
latest: digest: sha256:733009c33c6cf2775fedea36a3e1032006f1fe3d5155f49d4ddc742ea1dce1f1 size: 1155

本地目录可以作为卷安装到正在运行的容器中,而不是容器文件系统本身。对于卷,数据可以与容器共享,同时保存在本地机器上。卷在docker run命令中贴有-v标签。

将卷挂载到容器化的nginx Web 服务器

docker run -d -it --name ebisong-nginx -p 8081:80 -v /Users/ekababisong/Documents/Talks/kubeflow-for-poets/docker-intro/nginx-server/html:/usr/share/nginx/html  ekababisong.org/nginx_server

现在,无论对文件index.html做了什么更改,都可以从 Docker 容器中的nginx服务器的 web 浏览器上立即看到。

从 Dockerhub 运行 Tensorflow Jupyter 图像

注意:这张图片很大,从 Dockerhub 中提取需要一段时间。

**# pull the image from dockerhub**
docker pull jupyter/tensorflow-notebookUsing default tag: latest
latest: Pulling from jupyter/tensorflow-notebook
a48c500ed24e: Pull complete
...
edbe68d32a46: Pull complete
Digest: sha256:75f1ffa1582a67eace0f96aec95ded82ce6bf491e915af80ddc039befea926aa
Status: Downloaded newer image for jupyter/tensorflow-notebook:latest

运行 Tensorflow Jupyter 容器

这个命令启动一个运行 Jupyter 笔记本服务器的短暂容器,并在主机端口 8888 上公开服务器。服务器日志出现在终端中。访问 http:// <主机名> :8888/?浏览器中的 token= < token >加载 Jupyter 笔记本仪表板页面。它是短暂的,因为 Docker 在笔记本服务器退出后销毁了容器。这是因为docker run命令中的--rm标签。

**# run the image**
docker run --rm -p 8888:8888 jupyter/tensorflow-notebook

下图显示了一个从 Docker 容器运行的笔记本。

按下control + c收回本地终端。

库伯内特斯

当微服务应用程序被部署到生产环境中时,它通常会有许多正在运行的容器,需要为这些容器分配适量的资源来响应用户的需求。此外,还需要确保容器在线、正在运行并相互通信。高效管理和协调集装箱化应用集群的需求催生了 Kubernetes。

Kubernetes 是一个软件系统,它解决了部署、扩展和监控容器的问题。因此,它被称为容器编排器。其他类似的例子有 Docker Swarm、Mesos Marathon 和 Hashicorp Nomad。

Kubernetes 是由谷歌作为开源软件构建和发布的,现在由云本地计算基金会(CNCF) 管理。谷歌云*台提供了一个名为 的托管 Kubernetes 服务,谷歌 Kubernetes 引擎(GKE) 。针对 Kubernetes (EKS)的亚马逊弹性容器服务也提供托管的 Kubernetes 服务。

库伯内特的特点

  • 水*自动缩放:根据资源需求动态缩放容器。
  • 自我修复:重新配置失败的节点以响应健康检查。
  • 负载*衡:有效地在 pod 中的容器之间分配请求。
  • 回滚和更新:轻松更新或恢复到以前的容器部署,而不会导致应用程序停机。
  • DNS 服务发现:使用域名系统(DNS)作为 Kubernetes 服务来管理容器组。

库伯内特斯的成分

Kubernetes 发动机的主要部件有:

  • 主节点:管理 Kubernetes 集群。出于容错目的,它们可以是处于高可用性模式的多个主节点。在这种情况下,只有一个是主,其他的都是从。
  • 工作节点:运行被调度为 pod 的容器化应用程序的机器。

下图提供了 Kubernetes 架构的概述。稍后,我们将简要介绍各个子组件。

主节点

  • etcd(分布式密钥存储):管理 Kubernetes 集群状态。这个分布式密钥库可以是主节点的一部分,也可以在主节点之外。然而,所有主节点都连接到它。
  • api 服务器:管理所有管理任务。api server接收来自用户的命令(kubectl cli、REST 或 GUI),执行这些命令,并将新的集群状态存储在分布式密钥库中。
  • 调度器:通过分配 pod 将工作调度到工作节点。它负责资源分配。
  • 控制器:确保 Kubernetes 集群保持所需的状态。理想状态是 JSON 或 YAML 部署文件中包含的状态。

工作节点

  • kube let:kubelet代理运行在每个工人节点上。它将工作节点连接到主节点上的api server,并从它那里接收指令。确保节点上的单元运行正常。
  • kube-proxy: 它是运行在每个工作节点上的 Kubernetes 网络代理。它会监听api server,并将请求转发给适当的 pod。这对负载*衡很重要。
  • pod:由一个或多个共享网络和存储资源以及容器运行时指令的容器组成。豆荚是库伯内特最小的可部署单位。

编写 Kubernetes 部署文件

Kubernetes 部署文件定义了各种 Kubernetes 对象所需的状态。Kubernetes 对象的示例有:

  • 一个或多个容器的集合。
  • 副本集:主节点中controller的一部分。指定在任何给定时间应该运行的 pod 的副本数量。它确保在集群中维护指定数量的 pod。
  • 部署:自动创建ReplicaSets。它也是主节点中controller的一部分。确保集群的当前状态与所需状态相匹配。
  • 名称空间:将集群划分成子集群,以便将用户组织成组。
  • 服务:一组逻辑单元,具有访问它们的策略。
  • 服务类型:指定服务的类型,如ClusterIPNodePortLoadBalancerExternalName。例如,LoadBalancer使用云提供商的负载均衡器对外公开服务。

编写 Kubernetes 部署文件的其他重要标记。

  • 规格:描述集群的期望状态。
  • 元数据:包含对象的信息。
  • 标签:用于将对象的属性指定为键值对。
  • 选择器:用于根据标签值选择对象的子集。

部署文件被指定为一个yaml文件。

下一节中的示例将在前面的章节中推送到 Dockerhub 的 nginx 服务器映像部署到 Kubernetes 集群。该图像可在https://hub.docker.com/r/ekababisong/ebisong-nginx-server获得。

服务对象的示例

这个Service对象的代码片段保存在kubernetes-intro/deployment.yaml中。

kind: Service
apiVersion: v1
metadata:name: nginx-server-service
spec:*# service applies to the application with name `nginx-server`*selector:app: nginx-serverports:- protocol: "TCP"*# port inside cluster*port: 8080*# forward to port inside the pod*targetPort: 80*# accessible outside cluster*nodePort: 30001*# load balance between 5 instances of the container application*type: LoadBalancer

部署对象的示例

这个Deployment对象的代码片段保存在kubernetes-intro/deployment.yaml中。

apiVersion: extensions/v1beta1
kind: Deployment
metadata:name: nginx-server-deployment
spec:replicas: 5template:metadata:labels:app: nginx-serverspec:containers:- name: nginx-serverimage: ekababisong/ebisong-nginx-serverports:- containerPort: 80

使用 Minikube 在本地机器上运行 Kubernetes

Minikube 使得在本地机器上安装和运行单节点 Kubernetes 集群变得很容易。前往https://kubernetes.io/docs/tasks/tools/install-minikube/获取安装 Minikube 的说明。

  1. 安装一个管理程序,例如 VirtualBox 。
  2. 安装 Kubernetes 命令行界面kubectl。对于 mac:
brew install kubernetes-cli

检查安装的版本:

kubectl version

3.安装 Minikube。对于 mac:

brew cask install minikube

Minikube 命令概述

+---------------------+--------------------------------------------+
| **Command**             | **Description** |
+---------------------+--------------------------------------------+
| **minikube status**     | Check if Minikube is running.              |
| **minikube start** | Create local kubernetes cluster.           |                                 
| **minikube stop**       | Stop a running local kubernetes cluster.   |
| **minikube dashboard**  | Open Minikube GUI for interacting with the | |                       Kubernetes cluster. Append & to open in    | |                       background mode minikube dashboard &.      |
| **minikube ip**         | get ip address of Kubernetes cluster.      |
+------------+-----------------------------------------------------+

kubectl命令概述

+-------------------------------------------+----------------------+
| **Command**                                   | **Description** |
+-------------------------------------------+----------------------+
| **kubectl get all**                           | list all resources.  |
| **kubectl get pods** | list pods.           |                                 
| **kubectl get service** | list services.       | 
| **kubectl get deployments --all-namespaces**  | list deployments for | |                                             all namespaces.      | | **kubectl create -f [DEPLOYMENT_FILE.yaml]**  | create a new resource|  |                                             based on the desired | |                                             state in the yaml    |  |                                             file.                | | **kubectl apply -f [DEPLOYMENT_FILE.yaml]**   | if the resource      |  |                                             already exists,      | |                                             refresh the resource |  |                                             based on the yaml.   |             |                                             file.                |
| **kubectl delete -f [DEPLOYMENT_FILE.yaml]**  | remove all resources |  |                                             from the yaml file.  |
| **kubectl get nodes**                         | get the nodes of the | |                                             Kubernetes cluster.  | | **kubectl delete deployment [DEPLOYMENT_NAME]** | delete the         | |                                               deployment with    | |                                               [DEPLOYMENT_NAME]. |
| **kubectl delete svc [SERVICE_NAME]** | delete the service   | |                                             with [SERVICE_NAME]. |
| **kubectl delete pod [POD_NAME]**             | delete the pod with  | |                                             [POD_NAME].          |
+------------+-----------------------------------------------------+

使用kubectl在带有 Minikube 的本地机器上部署 Kubernetes

***# create local kubernetes cluster***
minikube startStarting local Kubernetes v1.13.2 cluster...
Starting VM...Getting VM IP address...
Moving files into cluster...
Setting up certs...
Connecting to cluster...
Setting up kubeconfig...
Stopping extra container runtimes...
Machine exists, restarting cluster components...
Verifying kubelet health ...
Verifying apiserver health ....
Kubectl is now configured to use the cluster.
Loading cached images from config file.Everything looks great. Please enjoy minikube!***# navigate to the directory with deployment file***
cd kubernetes-intro/***# create a new resource from yaml file***
kubectl create -f deployment.yamlservice "nginx-server-service" created
deployment.extensions "nginx-server-deployment" created***# launch minikube dashboard***
minikube dashboardVerifying dashboard health ...
Launching proxy ...
Verifying proxy health ...
Opening http://127.0.0.1:54356/api/v1/namespaces/kube-system/services/http:kubernetes-dashboard:/proxy/ in your default browser...

***# list pods***
kubectl get podsNAME                                      READY     STATUS    RESTARTS   AGE
nginx-server-deployment-f878d8679-5ptlc   1/1       Running   0          10m
nginx-server-deployment-f878d8679-6gk26   1/1       Running   0          10m
nginx-server-deployment-f878d8679-9hdhh   1/1       Running   0          10m
nginx-server-deployment-f878d8679-pfm27   1/1       Running   0          10m
nginx-server-deployment-f878d8679-rnmhw   1/1       Running   0          10m***# get ip address of kubernetes cluster***
$ minikube ip192.168.99.102

在由 Kubernetes 编排的 pod 上运行网页

让我们通过运行 192.168.99.102:30001 来访问 Kubernetes 集群中的应用程序。我们使用端口30001,因为我们从集群外部访问应用程序。

删除部署并停止 Minikube

***# delete the deployment***
kubectl delete -f deployment.yamlservice "nginx-server-service" deleted
deployment.extensions "nginx-server-deployment" deleted***# stop minikube***
minikube stopStopping local Kubernetes cluster...
Machine stopped.

在 Google Kubernetes 引擎上部署 Kubernetes

为了从本地 shell 在 GCP 上创建和部署资源,必须安装和配置 Google 命令行 SDK gcloud。如果您的机器不是这种情况,请遵循https://cloud.google.com/sdk/gcloud/中的说明。否则,更简单的选择是使用已经安装了gcloudkubectl(Kubernetes 命令行界面)的 Google Cloud Shell。

创建 GKE 集群

*# create a GKE cluster*
gcloud container clusters create ekaba-gke-cluster

Kubernetes 集群在 GCP 上创建,有 3 个节点(默认)。

Creating cluster ekaba-gke-cluster in us-central1-a... Cluster is being deployed...done.
Created [https://container.googleapis.com/v1/projects/oceanic-sky-230504/zones/us-central1-a/clusters/ekaba-gke-cluster].
To inspect the contents of your cluster, go to: https://console.cloud.google.com/kubernetes/workload_/gcloud/us-central1-a/ekaba-gke-cluster?project=oceanic-sky-230504
kubeconfig entry generated for ekaba-gke-cluster.
NAME               LOCATION       MASTER_VERSION  MASTER_IP     MACHINE_TYPE   NODE_VERSION  NUM_NODES  STATUS
ekaba-gke-cluster  us-central1-a  1.11.7-gke.4    35.226.72.40  n1-standard-1  1.11.7-gke.4  3          RUNNING

要了解有关使用 Google Kubernetes 引擎创建集群的更多信息,请访问https://cloud . Google . com/Kubernetes-Engine/docs/how-to/creating-a-cluster。

***# get the nodes of the kubernetes cluster on GKE***
kubectl get nodesNAME                                               STATUS    ROLES     AGE       VERSION
gke-ekaba-gke-cluster-default-pool-e28c64e0-8fk1   Ready     <none>    45m       v1.11.7-gke.4
gke-ekaba-gke-cluster-default-pool-e28c64e0-fmck   Ready     <none>    45m       v1.11.7-gke.4
gke-ekaba-gke-cluster-default-pool-e28c64e0-zzz1   Ready     <none>    45m       v1.11.7-gke.4

在 GKE 上部署 Nginx Web 服务器

***# navigate to directory with deployment file***
cd kubernetes-intro/***# create new resource from yaml file***
kubectl create -f deployment.yamlservice "nginx-server-service" created
deployment.extensions "nginx-server-deployment" created

部署详情可在 GCP Kubernetes 发动机控制台上查看:

Kubernetes 引擎控制台上的工作负载

GKE 控制台上的部署详情

列表框

***# list pods***
kubectl get podsNAME                                       READY     STATUS    RESTARTS   AGE
nginx-server-deployment-6d4cf7bb78-4swcb   1/1       Running   0          41m
nginx-server-deployment-6d4cf7bb78-5cdqc   1/1       Running   0          41m
nginx-server-deployment-6d4cf7bb78-bkjrp   1/1       Running   0          41m
nginx-server-deployment-6d4cf7bb78-d8b2l   1/1       Running   0          41m
nginx-server-deployment-6d4cf7bb78-mhpss   1/1       Running   0          41m

获取 GKE 上吊舱部署的外部 IP

***# get kubernetes service***
kubectl get serviceNAME                   TYPE           CLUSTER-IP      EXTERNAL-IP      PORT(S)          AGE
kubernetes             ClusterIP      10.23.240.1     <none>           443/TCP          1h
nginx-server-service   LoadBalancer   10.23.248.194   35.188.151.138   8080:30001/TCP   57m

在 GKE 上运行的应用程序

通过运行35.188.151.138:8080来访问部署在 GKE 上的应用程序。

删除在 GKE 的部署

***# delete the deployment***
kubectl delete -f deployment.yamlservice "nginx-server-service" deleted
deployment.extensions "nginx-server-deployment" deleted

删除 GKE 上的 Kubernetes 集群

***# delete the kubernetes cluster***
gcloud container clusters delete ekaba-gke-clusterThe following clusters will be deleted.- [ekaba-gke-cluster] in [us-central1-a]Do you want to continue (Y/n)?  YDeleting cluster ekaba-gke-cluster...done.
Deleted [https://container.googleapis.com/v1/projects/oceanic-sky-230504/zones/us-central1-a/clusters/ekaba-gke-cluster].

库贝弗洛

Kubeflow 是一个*台,旨在增强和简化在 Kubernetes 上部署机器学习工作流的过程。使用 Kubeflow,通过将组件(如培训、服务、监控和记录组件)放入 Kubernetes 集群上的容器中,管理分布式机器学习部署变得更加容易。

Kubeflow 的目标是抽象出管理 Kubernetes 集群的技术细节,以便机器学习从业者可以快速利用 Kubernetes 的能力和在微服务框架内部署产品的好处。在 2017 年底开源之前,Kubeflow 一直是谷歌在 Kubernetes 上实现机器学习管道的内部框架。

使用 Kubeflow

以下是 Kubeflow 上运行的一些组件:

在 GKE 建立一个 Kubernetes 集群

***# create a GKE cluster***
gcloud container clusters create ekaba-gke-clusterCreating cluster ekaba-gke-cluster in us-central1-a... Cluster is being health-checked (master is healthy)...done.
Created [https://container.googleapis.com/v1/projects/oceanic-sky-230504/zones/us-central1-a/clusters/ekaba-gke-cluster].
To inspect the contents of your cluster, go to: https://console.cloud.google.com/kubernetes/workload_/gcloud/us-central1-a/ekaba-gke-cluster?project=oceanic-sky-230504
kubeconfig entry generated for ekaba-gke-cluster.
NAME               LOCATION       MASTER_VERSION  MASTER_IP      MACHINE_TYPE   NODE_VERSION  NUM_NODES  STATUS
ekaba-gke-cluster  us-central1-a  1.11.7-gke.4    35.193.101.24  n1-standard-1  1.11.7-gke.4  3          RUNNING***# view the nodes of the kubernetes cluster on GKE***
kubectl get nodesNAME                                               STATUS    ROLES     AGE       VERSION
gke-ekaba-gke-cluster-default-pool-0f55a72b-0707   Ready     <none>    4m        v1.11.7-gke.4
gke-ekaba-gke-cluster-default-pool-0f55a72b-b0xv   Ready     <none>    4m        v1.11.7-gke.4
gke-ekaba-gke-cluster-default-pool-0f55a72b-g4w8   Ready     <none>    4m        v1.11.7-gke.4

创建 OAuth 客户端 ID 来标识云 IAP

Kubeflow 使用云身份感知代理(Cloud IAP)安全地连接到 Jupyter 和其他正在运行的 web 应用。Kubeflow 使用电子邮件地址进行身份验证。在本节中,我们将创建一个 OAuth 客户端 ID,用于在请求访问用户的电子邮件帐户时识别 Cloud IAP。

  • 转到 GCP 控制台中的API&服务- >凭证页面。
  • 转到 OAuth 同意屏幕:
  • 分配一个应用程序名称,例如 My-Kubeflow-App
  • 对于授权域,请使用[您的产品 ID].cloud.goog

  • 转到凭据选项卡:
  • 单击创建凭据,然后单击 OAuth 客户端 ID。
  • 在应用程序类型下,选择 Web 应用程序。

  • 选择一个名称来标识 OAuth 客户端 ID。
  • 在“授权重定向 URIs”框中,输入以下内容:
https://<deployment_name>.endpoints.<project>.cloud.goog/_gcp_gatekeeper/authenticate
  • <deployment_name>必须是库巴流部署的名称。</deployment_name>
  • 是 GCP 项目 ID。
  • 在这种情况下,它将是:
[https://ekaba-kubeflow-app.endpoints.oceanic-sky-230504.cloud.goog/_gcp_gatekeeper/authenticate](https://ekaba-kubeflow-app.endpoints.oceanic-sky-230504.cloud.goog/_gcp_gatekeeper/authenticate)

  • 记下 OAuth 客户端窗口中出现的客户端 ID 和客户端密码。这是启用云 IAP 所必需的。
***# Create environment variables from the OAuth client ID and secret earlier obtained.*** export CLIENT_ID**=**506126439013-drbrj036hihvdolgki6lflovm4bjb6c1.apps.googleusercontent.com
export CLIENT_SECRET**=**bACWJuojIVm7PIMphzTOYz9D
export PROJECT**=**oceanic-sky-230504

下载 kfctl.sh

***# create a folder on the local machine***
mkdir kubeflow***# move to created folder***
cd kubeflow***# save folder path as a variable***
export KUBEFLOW_SRC**=$(**pwd**)*****# download kubeflow `kfctl.sh`***
export KUBEFLOW_TAG**=**v0.4.1curl https://raw.githubusercontent.com/kubeflow/kubeflow/**${**KUBEFLOW_TAG**}**/scripts/download.sh | bash% Total    % Received % Xferd  Average Speed   Time    Time     Time  CurrentDload  Upload   Total   Spent    Left  Speed
100   800  100   800    0     0   1716      0 --:--:-- --:--:-- --:--:--  1716
+ '[' '!' -z 0.4.1 ']'
+ KUBEFLOW_TAG=v0.4.1
+ KUBEFLOW_TAG=v0.4.1
++ mktemp -d /tmp/tmp.kubeflow-repo-XXXX
+ TMPDIR=/tmp/tmp.kubeflow-repo-MJcy
+ curl -L -o /tmp/tmp.kubeflow-repo-MJcy/kubeflow.tar.gz https://github.com/kubeflow/kubeflow/archive/v0.4.1.tar.gz% Total    % Received % Xferd  Average Speed   Time    Time     Time  CurrentDload  Upload   Total   Spent    Left  Speed
100   125    0   125    0     0     64      0 --:--:--  0:00:01 --:--:--    64
100 8099k    0 8099k    0     0  1309k      0 --:--:--  0:00:06 --:--:-- 2277k
+ tar -xzvf /tmp/tmp.kubeflow-repo-MJcy/kubeflow.tar.gz -C /tmp/tmp.kubeflow-repo-MJcy
...
x kubeflow-0.4.1/tf-controller-examples/tf-cnn/README.md
x kubeflow-0.4.1/tf-controller-examples/tf-cnn/create_job_specs.py
x kubeflow-0.4.1/tf-controller-examples/tf-cnn/launcher.py
++ find /tmp/tmp.kubeflow-repo-MJcy -maxdepth 1 -type d -name 'kubeflow*'
+ KUBEFLOW_SOURCE=/tmp/tmp.kubeflow-repo-MJcy/kubeflow-0.4.1
+ cp -r /tmp/tmp.kubeflow-repo-MJcy/kubeflow-0.4.1/kubeflow ./
+ cp -r /tmp/tmp.kubeflow-repo-MJcy/kubeflow-0.4.1/scripts ./
+ cp -r /tmp/tmp.kubeflow-repo-MJcy/kubeflow-0.4.1/deployment ./***# list directory elements***
ls -ladrwxr-xr-x   6 ekababisong  staff   204 17 Mar 04:15 .
drwxr-xr-x  25 ekababisong  staff   850 17 Mar 04:09 ..
drwxr-xr-x   4 ekababisong  staff   136 17 Mar 04:18 deployment
drwxr-xr-x  36 ekababisong  staff  1224 17 Mar 04:14 kubeflow
drwxr-xr-x  16 ekababisong  staff   544 17 Mar 04:14 scripts

部署 Kubeflow

***# assign the name for the Kubeflow deployment*
*# The ksonnet app is created in the directory ${KFAPP}/ks_app***
export KFAPP**=**ekaba-kubeflow-app***# run setup script***
**${**KUBEFLOW_SRC**}**/scripts/kfctl.sh init **${**KFAPP**}** --platform gcp --project **${**PROJECT**}*****# navigate to the deployment directory***
cd **${**KFAPP**}***# creates config files defining the various resources for gcp*
**${**KUBEFLOW_SRC**}**/scripts/kfctl.sh generate platform
*# creates or updates gcp resources*
**${**KUBEFLOW_SRC**}**/scripts/kfctl.sh apply platform
*# creates config files defining the various resources for gke*
**${**KUBEFLOW_SRC**}**/scripts/kfctl.sh generate k8s
*# creates or updates gke resources*
**${**KUBEFLOW_SRC**}**/scripts/kfctl.sh apply k8s***# view resources deployed in namespace kubeflow***
kubectl -n kubeflow get  all

Kubeflow 可从以下网址获得:https://e kaba-kube flow-app . endpoints . oceanic-sky-230504 . cloud . goog/

注意:URI 可能需要 10-15 分钟才能可用。Kubeflow 需要提供一个签名的 SSL 证书并注册一个 DNS 名称。

kube flow 主屏幕

库伯弗洛管道公司

Kubeflow Pipelines 是一个简单的*台,用于在 Kubernetes 上构建和部署容器化的机器学习工作流。Kubeflow 管道使得实现生产级机器学习管道变得容易,而不需要考虑管理 Kubernetes 集群的底层细节。

Kubeflow 管道是 Kubeflow 的核心组件,也是在部署 Kubeflow 时部署的。

Kubeflow 管道的组件

管道描述了机器学习工作流,其中管道的每个组件都是一组自包含的代码,这些代码被打包为 Docker 图像。每个管道都可以单独上传,并在 Kubeflow 管道用户界面(UI)上共享。管道接收运行管道所需的输入(参数)以及每个组件的输入和输出。

Kubeflow 管道*台包括:

  • 用于管理和跟踪实验、作业和运行的用户界面(UI)。
  • 用于安排多步骤 ML 工作流的引擎。
  • 用于定义和操作管道和组件的 SDK。
  • 使用 SDK 与系统交互的笔记本电脑。(摘自:库贝弗管道概述)

执行示例管道

  1. 点击名称【样本】基本—条件

2.点击开始实验

3.给实验起个名字。

4.给出运行名称。

5.点击运行名称开始运行。

在 Kubeflow 管道上部署端到端机器学习解决方案

Kubeflow 管道组件是管道任务的实现。组件是工作流中的一个步骤。每个任务将一个或多个工件作为输入,并可能产生一个或多个工件作为输出。

每个组件通常包括两个部分:

  • 客户端代码:与端点对话以提交作业的代码。比如连接谷歌云机器学习引擎的代码。
  • 运行时代码:执行实际工作的代码,通常在集群中运行。例如,为云 MLE 上的训练准备模型的代码。

组件由接口(输入/输出)、实现(Docker 容器映像和命令行参数)和元数据(名称、描述)组成。

简单的端到端解决方案管道概述

在这个简单的例子中,我们将实现一个深度神经回归器网络来预测比特币加密货币的收盘价。机器学习代码本身非常基础,因为它不是本文的重点。这里的目标是在具有 Kubeflow 管道的 Kubernetes 上使用微服务架构来编排机器学习工程解决方案。

管道由以下组件组成:

  1. 将 Github 上托管的原始数据移动到存储桶中。
  2. 使用谷歌数据流转换数据集。
  3. 在云机器学习引擎上进行超参数训练。
  4. 用优化的超参数训练模型。
  5. 部署在云 MLE 上服务的模型。

为每个组件创建一个容器图像

首先,我们将把客户机和运行时代码打包成一个 Docker 映像。该映像还包含安全服务帐户密钥,用于针对 GCP 进行身份验证。例如,使用数据流转换数据集的组件在其映像中内置了以下文件:

| _ _ data flow transform
| _ _ _ _ _ _ _ _ Docker file:Docker file 来构建 Docker 映像。
|_____ build.sh:启动容器构建并上传到 Google 容器注册表的脚本。
|_____ dataflow_transform.py:在云数据流上运行 beam 管道的代码。
|_____ service_account.json:在 GCP 上验证容器的安全密钥。
|_____ local_test.sh:本地运行图像管道组件的脚本。

在上传到 Kubeflow 管道之前构建容器

在将管道上传到 Kubeflow 管道之前,请确保构建组件容器,以便将最新版本的代码打包并作为映像上传到容器注册中心。代码提供了一个方便的bash脚本来构建所有容器。

使用 Kubeflow 管道 DSL 语言编译管道

管道代码包含组件如何相互作用的规范。每个组件都有一个输出,作为管道中下一个组件的输入。Kubeflow Pipelines SDK 中的 Kubeflow 管道 DSL 语言dsl-compile用于编译 Python 中的管道代码,以便上传到 Kubeflow 管道。

通过运行以下命令,确保 Kubeflow Pipelines SDK 安装在本地计算机上:

***# install kubeflow pipeline sdk***
pip install https://storage.googleapis.com/ml-pipeline/release/0.1.12/kfp.tar.gz --upgrade*# verify the install*
which dsl-compile

通过运行以下命令编译管道:

***# compile the pipeline***
python3 **[**path/to/python/file.py] **[**path/to/output/tar.gz]

对于示例代码,我们使用了:

python3 crypto_pipeline.py crypto_pipeline.tar.gz

将管道上传并执行到 Kubeflow 管道

  1. 将管道上传到 Kubeflow 管道。

2.单击管道以查看流量的静态图。

3.创建一个ExperimentRun来执行流水线。

4.完成管道运行。

完整的数据流管道

云 MLE 上部署的模型

删除 Kubeflow

***# navigate to kubeflow app***
cd **${**KFAPP**}*****# run script to delete the deployment***
**${**KUBEFLOW_SRC**}**/scripts/kfctl.sh delete all

删除 Kubernetes 集群

***# delete the kubernetes cluster***
gcloud container clusters delete ekaba-gke-cluster

参考

以下资源有助于创建和部署 Kubeflow 管道。

  • 如何创建和部署 Kubeflow 机器学习管道(第一部分)
  • 如何将 Jupyter 笔记本电脑部署为 Kubeflow ML 管道的组件(第 2 部分)

Kubernetes,ML 管道的开放和可扩展方法

原文:https://towardsdatascience.com/kubernetes-the-open-and-scalable-approach-to-ml-pipelines-1e972a965f0d?source=collection_archive---------12-----------------------

还在等 ML 训练结束?厌倦了手动运行实验?不确定如何重现结果?在开发运维及数据争论上浪费太多时间?

如果你是一个业余爱好者,这没关系,但是数据科学模型应该被整合到真正的商业应用中。如果看不到积极的投资回报,企业就不会投资数据科学。这就要求采用“工程化”的方法——否则它只不过是一个美化了的有数据的科学项目。

工程师在现代敏捷开发中使用微服务和自动化 CI/CD ( 持续集成和部署)。你写代码,推送,它会在大规模的集群上自动测试。如果通过测试,它将进入某种形式的 beta/ 金丝雀测试阶段,并从那里投入生产。 Kubernetes ,一个云原生集群编制器,是现在被开发人员和开发者广泛使用的工具,用来构建一个敏捷的应用交付环境。

领先的 ML 工程师和 AI/ML 驱动的公司已经在使用 Kubernetes,它带有预集成的工具和可扩展的框架,用于数据处理、机器学习和模型部署。一些 Kubernetes 框架还支持水*扩展和高效使用 GPU,这进一步减少了总体等待时间和成本。

不要满足于专有的 SaaS/云解决方案或传统架构,如 Hadoop 。获得基于 Kubernetes 的解决方案,打造可扩展的前瞻性数据科学*台。以下帖子回顾了用于扩展和操作数据科学工作的流程和 Kubernetes 框架的最佳实践,并提供了有关 Kubernetes (K8s)的 KubeFlow ML 工具包的详细信息。

数据科学管道

数据科学家在开发阶段通常会经历以下步骤:

  1. 从 CSV 或密集格式(如拼花地板)收集数据,需要从外部来源手动提取。
  2. 手动标记、探索和丰富数据,以识别潜在的模式和特征。
  3. 模型训练和验证。
  4. 使用真实/新鲜数据进行模型测试,或者作为更大应用程序的一部分。
  5. 如果对结果不满意,冲洗并重复。

Data Science Pipeline and Output Artifacts

一旦完成了开发,尽管困难重重,模型还是被部署到生产环境中,在那里展示了花哨的仪表板来识别异常或预测行为。我们中那些在人工智能旅程中更先进的人也创建人工智能驱动的用户交互/应用程序或触发警报和行动。

但随后数据发生了变化…模型精度漂移…用户要求更新应用程序和仪表板等…现在我们发现自己再次运行大部分管道来生产新模型。这是我们开始谷歌持续开发和集成方法的地方,但是稍后会有更多的内容。

构建管道所需的工具可分为以下六类:

A.来自离线或在线来源的自动数据收集器。

B.用于数据标注、探索和模型开发的交互式工具。

C.用于大规模聚合、连接和透视数据的分析工具/数据库。

D.并行模型培训框架。

E.模型和 API 服务框架。

F.管理、监控和仪表板。

将所有这些工具集成到一个*台下的唯一明智的方法就是使用 Kubernetes!

Kubernetes,ML *台的选择

Kubernetes 在同一个集群上托管多个打包的和预集成的数据和数据科学框架。它们通常是可伸缩的或者是自动伸缩的,并且它们是通过声明性的方法来定义/管理的:指定您的需求是什么,服务将不断地寻求满足它们,这提供了弹性并最大限度地减少了手动干预。

KubeFlow 是一个开源项目,集合了领先的相关 K8 框架。KubeFlow 组件包括 Jupyter 笔记本、KubeFlow Pipeline (工作流和实验管理)、可扩展培训服务(针对 TensorFlow 、 PyTourch 、 Horovod 、 MXNet 、 Chainer )、模型服务解决方案以及 Iguazio 的无服务器框架 (Nuclio 。KubeFlow 还提供了示例和预集成/测试组件。

除了典型的数据科学工具,Kubernetes 还可以托管数据分析工具,如 Spark 或 Presto ,各种数据库和监控/日志解决方案,如 Prometheus 、 Grafana 、 Elastic Search 等。它还支持使用无服务器功能(即自动构建/部署/扩展代码,如 AWS Lambda )执行各种数据相关任务或 APIs 模型服务,请在我的帖子(无服务器:它能简化数据科学项目吗?)。

Using Kubernetes for Data-Science and Analytics

与专有云或 SaaS 解决方案相比,Kubernetes 的主要优势在于其工具会定期添加和升级,谷歌的搜索和堆栈溢出通常是最快的帮助途径,并且该解决方案可以部署在任何地方(任何云,甚至是本地或笔记本电脑)。社区项目还迫使相关的组件/服务符合一组简化互操作性、安全性、监控等的标准/抽象。

您可以自己构建和管理 Kubernetes 数据科学*台(遵循文档),或者使用云提供商或 Iguazio 等公司的托管和预集成解决方案。

构建高效的数据科学管道

不幸的是,仅仅押注于一个可信的*台是不够的。相信我,这是我的经验之谈:一旦你采纳了三条指导原则,生活会变得更容易:

  1. 使其功能化 —创建可重用的抽象函数/步骤,可以接受参数。
  2. 使其可扩展 —将并行性应用于每一步(或者尽可能经常地,在合理的范围内)。
  3. 自动化 —通过使用声明性语义和工作流来避免手动和重复的任务。

数据科学的当前趋势是建立“ML 工厂”,即非常类似于敏捷软件开发,建立自动管道来获取数据、预处理数据、运行培训、生成、部署和监控模型。Kubernetes 提供的声明式自动化部署和扩展方法是一个很好的基线,但它缺少一种在此基础上管理此类管道的方法。

KubeFlow 项目中一个相对较新的工具是 Pipelines ,这是一组旨在创建和管理 ML 管道的服务和 UI。我们可以编写自己的代码,或者从谷歌、亚马逊、微软、IBM、英伟达、 Iguazio 等公司提供的大量预定义组件和算法中构建。

Kubeflow Piplines UI

一旦我们有了一个工作流,我们就可以按预定的时间间隔运行它一次,或者自动触发它。管道、实验和运行被管理,并且它们的结果被存储和版本化。管道解决了复制和解释我们的 ML 模型的主要问题。这也意味着我们可以直观地比较运行,并在各种对象/文件存储库中存储版本化的输入和输出工件。

一个主要的挑战是如何大规模地进行实验和数据处理。管道协调各种水*扩展和 GPU 加速的数据和 ML 框架。单个逻辑流水线步骤可以在 TensorFlow、Spark 或 Nuclio 函数的十几个并行实例上运行。管道也有映射到现有云服务的组件,因此我们可以提交一个逻辑任务,该任务可能在托管的谷歌人工智能和数据服务上运行,或者在亚马逊的 SageMaker 或 EMR 上运行。

KubeFlow 和它的管道,就像这个类别中的大多数工具一样,仍然在发展,但是它背后有一个庞大而活跃的多厂商社区。这保证了一个可行和开放的框架。很像 Kubernetes 的第一天,云提供商和软件供应商有他们自己的管理容器的专有解决方案,随着时间的推移,他们都让位于社区要求的开源标准。

如果你下周碰巧在巴塞罗那的 KubeCon,请参观 KubeFlow 会议和各种成员展示的演示,包括我自己。我将于 5 月 20 日出席无服务器从业者峰会(Fira Gran Via Hall 8.0 Room D4+cc 8.17–20),并于 5 月 23 日下午与谷歌的 Maulin Patel 会面https://KC cnce u19 . sched . com/event/MPaf/economics-and-best-practices-of-running-aiml-workloads-on-kubernetes-maul in-Patel-Google-yaron-haviv-iguazio。

气流 KubernetesExecutor

原文:https://towardsdatascience.com/kubernetesexecutor-for-airflow-e2155e0f909c?source=collection_archive---------2-----------------------

在 Kubernetes 上自然缩放气流

在 1.10 版本中,Airflow 引入了一个新的执行器来大规模运行 workers:Kubernetes 执行器。在本文中,我们将探讨:

  • 什么是气流,它解决什么问题
  • 库伯内特遗嘱执行人及其与芹菜遗嘱执行人的比较
  • minikube 上的示例部署

TL;速度三角形定位法(dead reckoning)

气流有了一个新的执行者,可以在 Kubernetes 上自然产生工蜂。在这个 git 库中有一个导航图,以及一些帮助你开始使用 KubernetesExecutor 的例子。

气流作为工作流调度程序

Background image

数据工程领域迅速发展,以处理和存储不断增长的数据量。现在有很多技术可以在所谓的数据湖或数据仓库中存储和查询数 Pb 的原始数据。想想开源*台——Hadoop、Kafka、Druid、Ceph——或者云原生解决方案——亚马逊红移和 S3、谷歌 BigQuery 和 GCS、Azure 数据仓库和数据湖。你可以使用 Spark、Flink、Storm 或 Beam 等工具来处理这些海量数据。或者在数据仓库上运行查询,并将结果存储在新表中。数据管道通常由许多步骤和工具组成,用于移动数据。那么,我们如何将这些组件缝合到一个可靠的工作流中呢?

工作流调度程序管理任务之间的依赖关系,并协调它们的执行。知名的调度有气流、路易吉、 Oozie 和阿兹卡班。Airflow 因其丰富的 UI、灵活的配置和编写定制扩展的能力而获得了社区的大力支持。Airbnb 启动了这个项目,并将其开源为 Apache 孵化器。

想象一下,我们有一堆数据放在谷歌云存储(GCS)的某个地方,等待处理。我们希望使用 Spark 清理数据,并将其移动到 BigQuery 进行分析。预算紧张,所以我们没有全天候运行的 Hadoop 集群。我们首先要创建一个新的 Dataproc 集群(Dataproc 是 Google Cloud 上的 Hadoop)。然后,Spark 作业从 GCS 获取数据,对其进行处理并将其转储回 GCS。最后,BigQuery 作业将数据从 GCS 加载到一个表中。同时,我们可以关闭 Dataproc 集群来清理我们的资源。这是这样一个气流工作流程的样子。

气流本身支持上述所有步骤以及更多。Airflow 还负责对 GCS、Dataproc 和 BigQuery 的认证。这是一个简单的示例,说明了气流如何在任务之间创建工作流。如果你是气流的新手,我强烈推荐你在 Github 上查看这个资源管理。这篇文章假设你已经理解了气流的本质。

规模化气流

Background image

气流不仅仅可以运行数据管道。它可以触发任何带有 API 的作业。这开启了一个充满机遇的世界!不知不觉中,你的气流装置变得挤满了管道。是时候扩大规模了。Kubernetes 是扩展应用的领先技术之一。应用程序的各个部分在所谓的 pod 中作为独立的容器运行。当应用程序需要更多功率时,Kubernetes 会复制这些 pod。

Airflow 的架构非常适合这种模式。在其核心,调度程序决定哪些任务需要运行下一步。web 服务器使用户能够与 Dag 和任务进行交互。数据库跟踪当前和过去作业的状态。最后,气流有运行任务的工人。调度程序、web 服务器和数据库通常不需要扩展。完成繁重任务的是工人节点。Airflow 有两个流行的执行器可以大规模部署工作人员 CeleryExecutor 和 KubernetesExecutor。

Celery 是一个分布式任务队列,在多个节点之间*衡工作负载。使用芹菜在工人节点上调度作业是一种流行的扩展气流的方法。在这里您可以找到一张导航图,使用 CeleryExecutor 自动完成部署。但是,如果使用芹菜效果如此之好,那么我们为什么还需要另一个 Kubernetes 的执行者呢?因为芹菜挺复杂的。您需要在系统中部署芹菜作为额外的组件。而芹菜需要 RabbitMQ 或 Redis 这样的经纪人作为后端。此外,您可能希望用 web 界面 Flower 来监控芹菜。也许这些组件对于手头的任务来说增加了太多的开销?我们不能来点更简单的吗?是啊!Airflow 1.10 引入了一个新的执行器来扩展工作人员:Kubernetes 执行器。

对于芹菜,你在前面部署几个工人。然后,队列将在它们之间调度任务。相比之下,KubernetesExecutor 不会持续运行任何工人。相反,它为每项工作产生了一个新的工人群体。工作完成后,气流会立即清理资源。现在我们充分利用 Kubernetes 的潜力。不再需要额外的组件。扩展仅受限于集群的大小。只要你有足够的 CPU 和内存可用,气流可以不断调度更多的任务。当 Airflow 不再有作业运行时,只有调度程序、web 服务器和数据库保持活动状态。您的群集可以将其资源用于其他应用程序。

实践中的 Kubernetes 执行者

让我们深入实际细节。这篇文章的剩余部分将通过一个简单的例子来说明。我们将使用掌舵图在 minikube 上设置气流,但是如果你愿意,你可以在任何云提供商上部署它。我们的部署将定期从 Airflow 的 git 存储库中同步 Dag。让我们从克隆 git 存储库开始。

git clone [https://github.com/BrechtDeVlieger/airflow-kube-helm](https://github.com/BrechtDeVlieger/airflow-kube-helm)
cd airflow-kube-helm

在继续之前,请确保 minikube 已启动并正在运行。在 minikube 开始旋转仪表板后,您可能需要等待一分钟。

minikube start
minikube dashboard

首先,我们需要一个包含 Airflow 版本 1.10.2 或更高版本的 docker 映像。确保您已经安装了 Docker,并且 minikube 已经启动并正在运行。按照这些指南来安装和设置 docker 和 minikube。该存储库包含一个构建 docker 映像的脚本。

./examples/minikube/docker/build-docker.sh

该脚本使用 Kubernetes 依赖关系从 docker-airflow 构建了一个新的图像。当脚本完成时,图像将在 minikube 的注册表中作为airflow:latest出现。

Helm charts 允许开发人员创建可重用的 Kubernetes 部署。Helm 读取 values.yaml 文件并生成一组 yaml 文件。这些文件描述了一个 Kubernetes 部署。我们只需创建一个新的 yaml 文件来覆盖默认设置,从而创建一个定制部署。你可以在这里找到所有的默认值及其解释。我们将逐一介绍必要的更改。首先创建一个新的 values.yaml 文件。

Airflow 使用 fernet 密钥对数据库中的密码进行加密。当然,我们不想以纯文本的形式存储它们。下面是生成这样一个密钥的方法。

python -c "from cryptography.fernet import Fernet; FERNET_KEY = Fernet.generate_key().decode(); print(FERNET_KEY)"

将生成的密钥粘贴到 values.yaml 文件中。

airflow:fernet_key: "j0PNE8131Vx-ix7BsNDwskFUlnLa00mWU17BRujVcdY="

接下来,我们必须告诉使用哪个图像。如果您在 minikube 上构建映像,那么配置如下所示:

airflow:...image:repository: airflowtag: latestpull_policy: IfNotPresent

pull_policy在 minikube 上无关紧要,因为它使用其本地注册表来获取气流图像。

我们必须告诉气流从哪里得到这些数据,以及如何存储它们。我们的示例定期从气流存储库获取示例 Dag,并将它们复制到 Dag 文件夹中。以下代码片段向您展示了如何做到这一点:

airflow:...dags:persistence:enabled: falsegit:url: [https://github.com/apache/airflow](https://github.com/apache/airflow)branch: mastersubpath: airflow/example_dagswait: 60

要从 git 中提取 Dag,必须禁用持久性。在大多数情况下,dag 不存在于根 git 文件夹中。在我们的例子中,我们必须在子目录./airflow/example_dags中寻找它们。我们将把这个目录传递给subpath参数。其默认值为dags。您可以使用wait字段配置从 git 获取 Dag 的频率。

在继续部署之前,确保您的 values.yaml 文件看起来像下面的代码片段。

airflow:fernet_key: "j0PNE8131Vx-ix7BsNDwskFUlnLa00mWU17BRujVcdY="image:repository: airflowtag: latestpull_policy: IfNotPresentdags:persistence:enabled: falsegit:url: [https://github.com/apache/airflow](https://github.com/apache/airflow)branch: mastersubpath: airflow/example_dagswait: 60

教程的其余部分是小孩子的游戏。只需几个命令,我们就能让气流流动起来。但首先,我们需要在 minikube 上安装 Helm。顺便说一下,我们把运行在 Kubernetes Tiller 上的 Helm 部分称为。我们还将安装所需的舵依赖。

kubectl apply -f airflow/tiller.yaml
helm init --service-account tiller
helm dependency update

使用 Helm 生成 yaml 文件并部署 Airflow。

helm upgrade --install airflow airflow/ \--namespace airflow \--values values.yaml

几分钟之内,气流就会开始流动。如果需要一点时间,请不要担心。通常,web 服务器和调度程序会在 Postgres 数据库准备好之前尝试连接到它。在 pod 失败并重新启动之前,连接需要超时。为了加速这个过程,只要数据库准备好,就手动重新启动 web 服务器和调度程序窗格。

当所有的 pods 都准备好时,您可以使用这个命令将 web UI 转发到 http://localhost:8080 。

kubectl port-forward --namespace airflow $(kubectl get pod --namespace airflow --selector="app=airflow-web,release=airflow" --output jsonpath='{.items[0].metadata.name}') 8080:8080

现在尝试通过取消暂停来运行example_bash_operator。DAG 现在应该运行两次。在 minikube 仪表板上观察气流如何启动新的 pod 并清理已完成的 pod。您可以在图形和树视图中查看日志。遗憾的是,您无法从任务实例面板查看日志。这仍然是 KubernetesExecutor 中的一个 bug。

结论

气流 1.10 引入了一个新的执行器来大规模运行气流:KubernetesExecutor。调度器直接与 Kubernetes 交互,在任务开始和结束时创建和删除 pods。因此,当 Airflow 空闲时,只有调度程序和 web 服务器在运行。这为集群中的其他应用程序释放了资源。气流现在能够在 Kubernetes 上自然扩展,而不需要芹菜等附加组件。部署更加简单明了。

然而,新的执行程序仍然很新,有时表现有点出乎意料。1.10.2 版本解决了大部分问题,所以我建议只使用这个版本或更高版本。不过还有一个棘手的问题。日志卷需要允许从所有 Airflow pods 进行读写访问。云提供商本身不支持读写多个卷,因此您必须自己提供解决方案。该存储库包含一个 NFS 服务器的示例。

尽管如此,executor 按照预期工作,并且足够稳定,可以投入生产。气流的开发团队做得很棒。太棒了。谢谢你坚持到最后,希望这篇帖子能对你接下来的部署有用。

释放数据的价值

原文:https://towardsdatascience.com/label-encoding-tricks-c91a0966e8c6?source=collection_archive---------23-----------------------

Photo by Sereja Ris on Unsplash

标签编码—通过编码释放您的数据

在这篇文章中,我分享了一些处理标签的技巧。我提出方法来揭示你的字符串数据的内部值。第一部分回顾了经典的方法,下面几节讨论更具体的方法。

如何处理:
1。标签
2。颜色
3。位置
4。周期性特征

1.如何转换标签

Photo by Max Baskakov on Unsplash

大多数机器学习算法无法处理带标签的特征。字符串列很难转换成数值。

让我们考虑以下卡特彼勒特性数据集:

id    hair     breed
1     naked    sphynx
2     short    siamois
3     naked    sphynx
4     angora   ankara
..    ...      ...

hairbreed包含字符串格式的数据

要将hair特征转换成数值,可以给每个头发标签设置一个数字。例如naked变成 0,short变成 1 等等;

id    hair   breed
1      0     sphynx
2      1     siamois
3      0     sphynx
4      2     ankara
..    ...    ...

这种标签编码方法在头发值之间创建了一个层次。/naked小于1 / short2 / angora。这个等级在这里不是问题,因为它反映了猫毛的长度。

由于猫品种之间没有****的特定顺序,应用以前的标签编码方法会误导算法。在这种情况下, One Hot Encoding 方法最合适。它用布尔值(0-假/1-真)按品种创建一个列。结果是:

id  hair  sphynx  siamois  ankara
1    0      1        0        0
2    1      0        1        0
3    0      1        0        0
4    2      0        0        1
.   ...    ...      ...      ...

通过使用虚拟矩阵,每个品种都被认为是独立的。这种标签编码变体不涉及层次结构。****

Photo by Linnea Sandbakk on Unsplash

小心,一个热点编码一个栏目会产生更多可供学习的功能。如果品种的数量与数据集中猫的数量相比较小,则应使用此方法。

注意:创建虚拟对象会给你的数据集带来冗余。事实上,如果一只猫既不是斯芬克斯猫也不是暹罗猫,那么它必然是安卡拉猫。因此,可以安全地删除一个虚拟列,而不会丢失任何信息:

id   hair   sphynx   siamois
1     0      1        0         
2     1      0        1         
3     0      1        0         
4     2      0        0         
..   ...    ...      ...

****奖金。认为不同品种的猫相互独立简化了现实。例如,一只猫可能一半是暹罗猫,一半是安卡拉猫。在我们的编码数据集中,我们可以通过在 siamois 和 ankara 列中写入 0.5 来轻松表示这种混合。

id   hair   sphynx   siamois
1     0      1        0         
2     1      0        0.5        
3     0      1        0         
4     2      0        0         
..   ...    ...      ...

第一部分介绍了编码标签的经典方法。但是更具体的技术可能更适合。这取决于标签信息以及您需要如何处理数据。F** 跟随技术**可能会有更好的效果。****

2.如何转换颜色

假设我们现在有了每只猫的眼睛颜色:

Photo by Antonio Lapa on Unsplash

id   eyecolor
1    light_green    
2    dark_cyan
3    medium_sea_green 
4    yellow_green
..   ...

这一次,以前的方法不太适合表达颜色标签中的价值。相反,我们可以将颜色列分为红绿蓝三种色调:

id  eye_red  eye_green  eye_blue
1    173       237         150    
2    70        138         139
3    105       178         117 
4    168       205         67
..   ...       ...         ...

一般来说,颜色有几种编码方式。人们可能需要添加透明度信息。根据数据的使用方式,可以用 HSB(色调饱和亮度)而不是 RGB 进行编码。

3.如何转换位置

现在我们考虑猫的位置。我们有他们居住地的城市名。

Photo by Anthony DELANOIX on Unsplash

id   city
1    Paris
2    New-York
3    Cairo
4    New-York
..   ...

这里,我们可以用城市的 GPS(纬度/经度)十进制度坐标来代替城市名称,而不是使用常规的标签编码方法:

id  latitude   longitude
1   48.85341   2.3488
2   37.6       -95.665
3   30.06263   31.24967
4   37.6       -95.665
..  ...        ...

如您所见,我们根据地理属性对位置进行了编码。

根据我们的需要,城市可以用其他指标来表征。例如,如果我们需要预测猫的预期寿命,那么 城市发展指数 ,或者 *均家庭收入 可能更适合。

这些翻译带来了其他类型的信息。人们可以结合指标来丰富数据集。****

4.如何转换周期性特征

最后但同样重要的是,让我们关注循环特性。我们现在有了猫外出夜游的*均时间:

Photo by Agê Barros on Unsplash

id   avg_night_walk_time
1     11:30 PM
2     00:12 AM
3     10:45 PM
4     01:07 AM
..    ...

首先让我们把它转换成十进制小时:

id   avg_night_walk_time
1     23.5
2     0.2
3     22.75
4     1.12
..    ...

所以现在我们有了023.99之间的时间。作为人类,我们知道 23:59 和 00:00 很接*,但它没有出现在数据中。要改变它,我们可以用余弦和正弦来转换时间。它将数据投影到一个圆形空间中,在该空间中 00:00 AM11:59 PM 靠得很*。

id   avg_nwt_cos   avg_nwt_sin
1    0.99          -0.13
2    0.99          0.05
3    0.94          -0.32
4    0.95          0.28
..   ...           ...

通过转换时间,我们失去了一些人类的理解,但我们可以在任何时候将余弦和正弦数据转换回小时。这种转换并不意味着信息的丢失。

这种循环转换也应该应用于角度和周期过程。

正确处理周期性特征会大大增加数据集的价值。当你用小时、工作日、月、角度工作时,不要忘记它...

PS:在本文中,我没有谈论特性缩放,因为我关注的是数据转换。如有必要,考虑在转换后缩放/居中数据。

标签*滑:更高模型精度的一个要素

原文:https://towardsdatascience.com/label-smoothing-making-model-robust-to-incorrect-labels-2fae037ffbd0?source=collection_archive---------6-----------------------

1.介绍

图像分类是从一组固定的类别中给输入图像分配一个标签的任务。这是计算机视觉中的核心问题之一,尽管它很简单,却有大量的实际应用。

示例:例如,在下图中,一个图像分类模型获取一张图像,并将概率分配给两个标签:{猫,狗} 。如图所示,请记住,对于计算机来说,图像是一个大型的三维数字数组。在这个例子中,猫图像是 248 像素宽,400 像素高,并且具有三个颜色通道红色、绿色、蓝色(或简称为 RGB)。因此,图像由 248 x 400 x 3 个数字组成,即总共 297,600 个数字。每个数字都是从 0(黑色)到 255(白色)的整数。我们的任务是将这 25 万个数字转换成一个标签,比如“cat”

同样地,你可以训练一个模型,让它通过看卡戴珊的照片告诉你你在看哪个——金,凯莉,还是其他

2.训练分类模型

训练将图像分类为猫图像或狗图像的模型是二元分类的一个例子。

图像分类流水线。我们已经看到,图像分类的任务是获取代表单个图像的像素阵列,并为其分配标签。我们的完整渠道可以概括如下:

  • 输入:我们的输入由一组 N 图像组成,每个图像都标有一个 K 不同的类。我们将该数据称为训练集

training dataset

学习:我们的任务是使用训练集来学习每个类的样子。我们称这个步骤为训练分类器学习模型

3。数据标注错误问题

但是如果你的训练数据包含不正确的标注呢?如果一只狗被贴上猫的标签会怎样?如果凯莉被贴上肯德尔的标签,或者金被贴上坎耶的标签怎么办?如果你从互联网上获取数据,这种错误的数据标注可能会发生。

这最终会导致您的问题要么学习数据集中的噪声,要么学习不正确的要素。但是,这在一定程度上是可以避免的。如果你在一个小数据集上训练,你可以检查所有的标签并手动检查,或者使用你的爪牙来做脏活。下一节将分享另一种数学方法。

所以,问题是你的模型将会学习不正确的特征(从一只狗身上),并将这些特征与标签“猫”联系起来。我们如何解决这个问题?为了深入了解这一点,让我们看看在图像分类问题中使用的损失函数。

在我们得到损失函数之前,我们应该确定分段模型给出了每类的概率:

…maybe this is not how you see her…

在图像分类问题中,我们使用 softmax loss ,其定义如下两类:

l =(ylog(p)+(1y)log(1p))

这里, L 为损失, y 为真实标签(0 —猫,1 —狗), p 为图像属于 1 类即狗的概率。模型的目标是减少损失。

损失本质上驱动了你的“梯度”,简单来说就是决定了模型的“学习”。因此,我们需要密切关注损失。

比方说,你得到一张狗的图片,概率为 0.99。你的损失将是:

l =-(1 (log(0.99)+(1–0.99) log(0.01))≈0

哪个好!预测准确的情况下损失应该不大!

如果你的数据有不正确的标签,这种损失会特别大,从而导致 在学习 时出现问题。

那么我们该如何处理呢?在下一节中,我们将看到一种在标签不正确的情况下将损失最小化的方法。

3。标签*滑 —一种可能的解决方案

向标签*滑问好!

当我们将交叉熵损失应用于分类任务时,我们期望真正的标签为 1,而其他标签为 0。换句话说,我们毫不怀疑真正的标签是真的,其他的不是。总是这样吗?也许不是。许多手动注释是多个参与者的结果。他们可能有不同的标准。他们可能会犯一些错误。他们毕竟是人。因此,我们一直坚信的地面真相标签可能是错误的。

一个可能的解决办法是放松我们对标签的信心。例如,我们可以将损失目标值从 1 稍微降低到 0.9。自然地,我们稍微增加了其他人的目标值 0。这种想法被称为标签*滑。

下面是张量流中定义的交叉熵损失的论点:

arguments in softmax cross entropy loss

这是 Tensorflow 文档对label_smoothing参数的描述:

如果label_smoothing不为零,则将标签向 1/num_classes 方向*滑:new _ onehot _ labels = onehot _ labels *(1-label _ smoothing)+label _ smoothing/num _ classes

这是什么意思?

假设你正在训练一个二元分类模型。你的标签应该是 0-猫,1-不是猫。

现在,假设你label_smoothing = 0.2

使用上面的等式,我们得到:

new _ onehot _ labels =[0 1](1—0.2)+0.2/2 =[0 1](0.8)+0.1

new_onehot_labels =[0.9 0.1]

这些是软标签,而不是硬标签,即 0 和 1。当有一个不正确的预测时,这将最终给你较低的损失,随后,你的模型将惩罚和学习不正确的程度稍低。

本质上,标签*滑将帮助您的模型围绕错误标签的数据训练,从而提高其健壮性和性能。

4.进一步阅读

标签*滑什么时候有帮助?

使用机器学习标记法律文档

原文:https://towardsdatascience.com/labeling-legal-documents-using-machine-learning-49e3a34f2619?source=collection_archive---------30-----------------------

简介

标记数据的问题通常被认为是机器学习项目的第一步,其中开发了一个训练数据集,该数据集精确地表示看不见的、预期的“测试”数据。然而,对于大型数据集,包括自然语言语料库,标注工作本身就可以给组织带来巨大的价值。

图书馆,尤其是那些旨在教育学生和未来研究人员的学术机构,承担着这样的负担。虽然在使用光学字符识别(OCR)对无数数量的信息进行数字化方面已经取得了长足的进步,但是如果文本没有与基础附录或其他参考材料的链接,研究仍然会被证明是乏味和耗时的。

数据

在最*与一家受人尊敬的图书馆的项目中,我的任务是通过识别和标记所提交的证据文件的来源,促进历史法庭的抄本的易用性。这些文件要么是审判文件,要么是证据文件,要么是检方或辩方用来为自己的案件辩护的文件,证据文件是更广泛的文件领域的一部分,包含它们自己的命名方案。

每个人都有自己特定的识别方式。对于证据文件文档,正则表达式(regex)用于查找一组预定义的编码文档组中的任何一个。另一方面,区分控方和辩方的审判文件依赖于更微妙的上下文线索,并且经常需要仔细阅读记录以便正确地跟踪谈话。

该方法

在第一遍中,所有可能的引用都用 regex 标记,并且证据文件文档被分区。在剩余的参考文献中,那些明显是起诉或明显是辩护的参考文献被立即分类并搁置,以用作随机森林算法的训练集,以便对更模糊的情况做出决定。

这是模型最容易出错的地方。标签的准确性是最重要的,但紧接着是回忆(找到尽可能多的参考文献)。因此,我们与客户进行了定期的交流,客户对结果进行了人工检查,并向我们汇报。通过这种方式,我们可以对算法进行微调,例如,提供额外的功能、超参数调整或增加较少表示的类。

使用的主要特征是参考上下文。在所讨论的引用的任意一侧收集给定数量的单词或标记后,对实体进行词干分析和词汇化,并最终转换为词频逆文档频率(tf-idf)嵌入。这种方法根据最常见单词在每个“文档”中出现的频率(在这种情况下是围绕单个引用的上下文)对最常见单词的计数进行加权。因此,所有单词都将具有整数表示,能够作为输入提供给机器学习算法。

同样的方案也适用于现任议长。其他特征是基于关键触发词的存在或不存在而构建的,例如“起诉”,或者律师或被告之一的名字。随机森林实现为:

forest = RandomForestClassifier(criterion='entropy', n_estimators=500, random_state=0, n_jobs=-1)

其中使用了“熵”分离选择标准。尽管计算量更大,但它通常更适合分类数据。确定在一系列概率阈值的每一个处的算法性能,以便最大化准确性和召回率。此后,任何大于这个界限的都被标为“起诉”,小于这个界限的都被标为“辩护”。

问题

从一开始,该模型的准确性就很高,几乎不需要进一步增强。更大的挑战是确保我们获得大部分的引用。引用参考文献的方式有很大的不同,包括从缩写到零散的标点符号。必须构建正则表达式来接受跨多行出现的引用。此外,许多引用包含不同可能类型的组合,对于正则表达式定义来说,这看起来像多个唯一的标记机会。当在末尾用标签重新构造文本时,后者会变得特别麻烦,因为引用的尾部很容易被切断,并过早地被标签替换。

这些边缘情况的唯一共同点是存在一个长度不超过五位数的数字。在第二次浏览抄本时,我们识别了所有剩余的数字,过滤掉任何可能发现的假阳性(日期、页码、基本形容词)。在剩下的那些中,规则被开发以确保参考(某些介绍性短语的存在)和分配的标签。

经验教训

虽然是功能性的,但是第二遍中所做的工作是非常特殊的,并且不容易在其他数据集上使用。然而,大部分工作,以及整个项目中的工作,非常类似于作为斯坦福大学潜泳项目一部分的标记函数(LFs)的应用。意识到标记数据是机器学习中最耗时和不一致的部分,他们使用基于规则的 LFs 来编码标记数据的方法。在这种情况下,覆盖率通常比精确度更难控制,因此,考虑到我们对回忆的限制,这个公式能有多好的帮助还有待观察。

我们使用的数据集不应被视为异常独特或不规则。法律文本是所有职业中最密集的,对于自然语言处理(NLP)提供的许多节省成本和时间的措施来说,似乎已经成熟。搜索速度至关重要,无论是像这里描述的那样,还是将文本实体与更广泛的关键词联系起来的一种手段。尽管我们的工作因文本不一致而变得复杂,这可能是 OCR 的产物,但我们不能指望更现代的文档会好得多。

滞后变量回归和真理

原文:https://towardsdatascience.com/lagged-variable-regressions-and-truth-4edb7b9e8f47?source=collection_archive---------7-----------------------

动态回归模型提供了巨大的代表性,但也有偏见风险

Variables related to each other over adjacent time steps, originally in the context of dynamic Bayesian networks (Wikimedia user Guillaume.lozenguez, CC BY-SA 4.0)

  • 使用有理传递函数公共滤波器,将非线性结构时间序列模型转化为滞后变量的回归
  • 见普通最小二乘滞后变量回归中的偏差由于误差中剩余的序列相关性,
  • 使用广义最小二乘法消除偏差,恢复过程参数,即“真相”

托布勒(Tobler)的(非常可信的)地理第一定律指出:“耳边的事物比远处的事物更加相关。无论我们对底层的数据生成机制知之甚少,我们经常可以利用纯粹的邻*性——在时间或空间上——来获得优势。但我们也知道,回归因变量的时移副本,即受所有相同因素影响的副本,会带来一些警告。

最大的警告是普通最小二乘(OLS)回归中潜在的渐*偏差,这是任何额外数据都无法缓解的。当回归变量与误差项同时相关时,就会发生这种情况。正如 Peter Kennedy 在计量经济学指南中所解释的,“这是因为 OLS 程序在为解释因变量的变化而将‘信用’分配给回归变量时,错误地将因变量的一些扰动产生的变化分配给了与扰动同时相关的回归变量”简而言之,当回归变量和误差相关时,OLS 无法将两者的影响分开。

从被动预测的角度来看,偏差可能无关紧要,本文标题中的“t ruth ”指的是时间序列背后的真实数据生成过程。此后,我们的目标是过程参数的质量评估。对于客观事实和参数具有科学意义的情况,我将转向非线性、非*稳、结构化的时间序列模型,即运动表现的“体能-疲劳”模型。该模型通过潜在的健康疲劳结构将训练历史与运动表现联系起来,并通过有科学意义的参数进行调整。

通过使用输入到输出的合理传递函数重写这个模型,一组“公共过滤”操作将变得显而易见。应用这些过滤器会将模型转换为动态线性回归,但是过滤操作也会有副作用:MA(2)相关结构的错误。我们将在 OLS 回归中看到回归变量和误差之间同期相关性的破坏力,但最终,我们将通过适应这种结构的 GLS 回归得到真相。

非线性结构时间序列模型

运动表现的“体能-疲劳”模型具有以下形式:

其中 p_t 是(运动)表现的数字测量值, w_t 是训练“剂量”,而 ϵ_t 是同分布高斯误差。该模型可以被视为具有两个非线性特征的线性回归,

运动员“健康”和“疲劳”的潜在表征。这些特征是具有指数衰减的运动训练历史的卷积,不同之处仅在于衰减速率。通常,疲劳 ( g_t )相对短暂,并与更快的指数衰减相关联,但与适应度相比,也具有相对较大的回归权重。

借助一点代数知识,体能疲劳可以转化为动态形式:

其中θ_1 = exp(-1/τ_1)θ_2 = exp(-1/τ_2)。

如果我们将健康和疲劳的动态表示插入到原始模型中,我们会得到

这看起来更好,但不是立即有用的,因为 h _t 和 g _t 取决于未知参数。

理性传递函数到救援

再努力一点,我们可以对任何时间索引变量 y 使用由By _ t=y_ {t-1 }定义的“后移运算符” B ,得到

求解 h _ tg _ t 并将它们插回到原始模型中,我们得到:

因此,我们有两个对外生输入序列 w_t 进行操作的有理传递函数。对于有理传递函数,形式为(1- θ B)的分母项对应于一个自回归脉冲响应,即一个具有长记忆的过程,这对我们来说是一个麻烦。我们可以选择去掉分母成分,但这不是没有代价的。

在多输入传递函数模型的识别(刘& Hanssens,1982)中讨论的“公共滤波器”通过(1- θ B 来预乘时间序列方程的右侧和左侧。它不会改变传递函数权重,因此您可以连续应用多个公共滤波器,除了会导致复杂性和由于滞后而丢失一些行之外,您还没有破坏输入和输出序列之间的关系。

关键是,如果我们要使用公共滤波器(1-θ_ 1b)(1-θ_ 2b),我们就可以去除自回归成分:

上面的内容看起来仍然很难看,但是在展开应用后移运算的多项式之后,我们得到:

这是对两个自身滞后版本和外部培训输入的性能回归,但有一个转折。存在由公共滤波器引起的 MA(2)误差结构的问题,并且它具有真实的后果。

R 中的一个模拟例子

本节将使用可从 R 要点复制或直接下载为 csv 文件的模拟数据。要运行下面的 R 代码,请在下面的 R 代码块中更改文件路径:

train_df <- read.csv("c:/devl/data/train_df.csv")
head(train_df)

以下计算显示了模拟的滞后变量模型中所有系数的理论值:

# True parameter values:
mu <- 496
theta1 <- exp(-1 / 60)
theta2 <- exp(-1 / 13)
k1 <- .07
k2 <- .27#Theoretical coefficient for intercept is
(1 - theta1) * (1 - theta2) * mu#Theoretical coefficient for performance lagged once is
theta1 + theta2#Theoretical coefficient for performance lagged twice is
-theta1 * theta2#Theoretical coefficient for training lagged once is
k1 * theta1 - k2 * theta2#Theoretical coefficient for training lagged twice is
-theta1 * theta2 * (k1 - k2)

因此,目标是恢复以下等式:

侧注: 反其道而行之,通过代入求解θ_1 和θ_2,得出两个参数之一的二次方程。它们导致相同的两个根,所以选择θ_1 为两者中较大的一个。有了θ_1 和θ_2,求解μ就变得简单了,k1 和 k2 构成了一个含有两个方程和两个未知数的线性系统。

拟合滞后回归模型

为了准备回归,下面的代码将性能和训练变量分别延迟一次和两次。dplyr套装让一切变得简单:

library(dplyr)train_aug <- train_df %>%mutate(perf_lag1 = lag(perf, n = 1, order_by = day),perf_lag2 = lag(perf, n = 2, order_by = day),train_lag1 = lag(w, n = 1, order_by = day),train_lag2 = lag(w, n = 2, order_by = day))

让我们看看当我们使用 OLS 回归这些滞后变量的表现时会发生什么:

my_lm <- lm(perf ~ perf_lag1 + perf_lag2 + train_lag1 + train_lag2,data = train_aug[3:nrow(train_aug), ])
summary(my_lm)

上面的代码产生了部分输出:

Coefficients:Estimate Std. Error t value Pr(>|t|)    
(Intercept) 33.99821   12.09470   2.811 0.005327 ** 
perf_lag1    0.48066    0.05619   8.553 1.18e-15 ***
perf_lag2    0.46189    0.05504   8.393 3.45e-15 ***
train_lag1  -0.15602    0.04406  -3.541 0.000475 ***
train_lag2  -0.02346    0.04516  -0.520 0.603807    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1Residual standard error: 8.518 on 252 degrees of freedom
Multiple R-squared:  0.9117,	Adjusted R-squared:  0.9103 
F-statistic: 650.4 on 4 and 252 DF,  p-value: < 2.2e-16

由于残差中仍然存在序列相关,OLS 系数估计中明显存在偏差。

幸运的是,R 的nlme包通过gls函数提供了广义最小二乘(GLS)模型拟合,它处理 MA(2)误差结构:

library(nlme)
my_gls <- gls(perf ~ perf_lag1 + perf_lag2 + train_lag1 +train_lag2,data = train_aug[3:nrow(train_aug), ],corARMA(form = ~day, p = 0, q = 2))
summary(my_gls)

下面的部分输出来自上面的代码:

Correlation Structure: ARMA(0,2)Formula: ~day Parameter estimate(s):Theta1     Theta2 
-1.9059497  0.9117409 Coefficients:Value  Std.Error    t-value p-value
(Intercept)  0.6571088 0.11700730    5.61596       0
perf_lag1    1.9187158 0.00815689  235.22646       0
perf_lag2   -0.9200058 0.00815495 -112.81568       0
train_lag1  -0.1662026 0.02238219   -7.42566       0
train_lag2   0.1664704 0.02241510    7.42671       0

通过 GLS 回归,我们已经将真实的参数值恢复到合理的估计误差范围内。

讨论

之前关于体能-疲劳模型的文章已经使用重型机械来估计参数:非线性最小二乘法、l 具有复杂样条卷积特征的线性回归和卡尔曼滤波器,仅举三个例子。对几个滞后变量的线性回归(通过 GLS 拟合)能够恢复理论上的基本过程说明了动态回归模型的表达能力

在投入和产出各滞后几次的情况下盲目回归的代价是什么?只关注提前一步的预测精度,大概不会很多。带有滞后变量的 OLS 回归“解释”了 next 性能值的大部分变化,但它也表明了一个与用于模拟数据的过程完全不同的过程。这个过程的内部被 GLS 回归恢复了,这就谈到了标题中提到的“真相”。

进一步研究和讨论的主题是,对所有动态回归使用具有 MA( q )误差结构的 GLS 回归是否明智。通过nlme在 R 中实现非常容易。另一方面,它的预报功能没有使用误差结构,因此需要用户作出额外的努力,使 GLS 的预报能与 OLS 的预报竞争。对于开箱即用的一步预测,可能很难证明 GLS 过程的额外复杂性。为了获得真正的底层系统参数,通过 GLS 合并 MA( q )误差结构很可能使我们更接*真相

拉格朗日乘数与可视化和代码

原文:https://towardsdatascience.com/lagrange-multipliers-with-pictures-and-code-ace8018dac5e?source=collection_archive---------1-----------------------

终极优化武器,端到端解释。

在这个故事中,我们将通过拉格朗日乘数进行一次空中优化之旅。我们什么时候需要它们?每当我们遇到有约束的优化问题时。以下是一些例子:

  1. 对冲基金希望决定其投资组合中包含的股票比例,以使他们获得最大可能的预期回报,并保持在一定的风险偏好范围内(例如,风险可以根据回报的方差来衡量)。
  2. 一个学区想要为他们的学生确定午餐菜单上各种项目的分配。他们希望将每顿午餐的成本降至最低,同时确保孩子们获得一定量的所有必需营养。
  3. 一家卡车运输公司想要将货物从源仓库运输到目的地城市。给定每个仓库-城市对的运输成本、每个仓库的总供应量和每个城市的总需求,决定从每个仓库向每个城市运送多少,以使总成本最小化并满足需求(约束)。

我们可以看到,约束优化可以解决从物流到金融领域中出现的许多实际的、真实的问题。在博客的其余部分,我们将从没有约束的普通优化开始。然后,我们将添加等式约束。然后,我们将描述具有等式和不等式约束的完全一般约束优化问题的解(这些条件被称为 KKT —卡鲁什、库恩、塔克条件)。最后,我们在一些玩具问题上展示了这些条件的力量。许多人认为 Nocedal 和 Wright 的书是数值优化的圣经,我们将大致遵循第 13 章,避开严格的证明(总是可以从文本中读到)并更多地关注视觉直觉。

无约束优化

在这个场景中,我们的控制中有一些变量和一个依赖于它们的目标函数。对变量没有约束,目标函数将被最小化(如果这是一个最大化问题,我们可以简单地否定目标函数,然后它将变成一个最小化问题)。

在任何一点,对于一个一维函数,函数的导数指向一个增加它的方向(至少对于小的步长)。这意味着,如果我们有一个函数 f(x)并且导数f’(x)为正,那么增加 x 将增加 f(x),减少 x 将减少 f(x)。如果我们要最小化 f(x),我们只需向与 f'(x) 符号相反的方向迈出一小步,就可以减小 f(x)。如果我们在一个点上f’(x)= 0 呢?然后,我们可能已经到达 f(x)的一个最优值,因为没有别的地方可去。

如果有多个变量(比如 x 和 y),我们可以对每个变量求导。如果我们用这两个数字构造一个二维向量,我们就得到了函数的梯度。现在,沿梯度方向移动将增加函数,而向相反方向移动将减少函数(对于小步长)。

这意味着只要梯度不为零,我们就不可能处于最小值,因为我们可以简单地沿着与梯度相反的方向迈出一小步,并进一步减小函数。这意味着最小化函数的点的必要(但非充分)条件是梯度在该点必须为零。

让我们举一个具体的例子,这样我们就可以想象这是什么样子。考虑函数 f(x,y) = x +y,这是一个抛物面,当 x=0,y=0 时最小化。关于 x 和 y 的导数分别变成 2x 和 2y。所以,梯度变成了矢量∇f = [2x,2y]。我们可以看到,只有当 x=0,y=0 时,这才是零。否则,梯度指向 f(x,y)将增加的方向。所以,与梯度相反的方向会减少 f(x,y)。如下图所示。粉色曲线是在绿点(0,0)处最小化的目标函数 f(x,y)。紫色箭头是梯度,它指向 f(x,y)增加的方向。为了减少它,我们向相反的方向移动,直到到达绿点。

Fig 1: Paraboloid with gradients. Made using https://github.com/ryu577/pyray

总而言之,当优化函数 f 时,在无约束优化问题中,处于局部最优的必要(但非充分)条件是:

∇f = 0

这就像当你站在山顶时(那将是一匹千里马)。你怎么知道你在顶端?无论你朝哪个方向走,你最终都会降低你的高度。所以你肯定是在当地的一个最佳状态。现在,你旁边可能还有一座更高的山。所以,你可能不在环球 optima。事实上,如果我们将地球表面视为我们的领域(将海拔高度视为我们的目标函数),如果你在任何一座古老的山峰(或建筑)的顶部,那么你就处于局部最优,但只有当那座山是珠穆朗玛峰时,你才处于全局最优。在本文中,我们将满足于寻找局部最优解。

如果我们想待在一个国家的范围内呢?这将意味着限制我们可以搜索最优解的空间,使这成为约束优化的一个例子。在某种程度上,无约束优化只是约束优化的一个特例。

*等约束

对于无约束最小化/最大化问题,我们简单地寻找梯度为零向量的点。如果梯度不为零,我们就向它指向的相反方向迈一小步(如果我们最小化;沿着它,如果我们最大化)并继续这样做,直到我们确实到达一个点,在那里它零,因此,没有其他地方可去(这种优化方法被称为梯度下降)。请注意,我们不必完全沿着梯度移动。只要我们沿着梯度有正投影(阴影)的方向移动,我们最终会增加目标函数(如果我们沿着负梯度有正投影,则目标函数会减少)。下图说明了这一点。绿色箭头是蓝色*面的梯度(因此与其垂直),红色箭头是负梯度。因为浅蓝色的箭头位于*面上,如果我们沿着它们走一步,*面的方程将产生 0。黄色箭头沿着绿色箭头有一个正阴影(投影)。因此,沿着它们移动将导致当插入*面的方程时产生正数的点(“增加”它)。类似地,粉色箭头沿着红色箭头有一个正阴影(反向渐变)。因此,沿着它们移动将导致在插入*面方程时产生负数的点(“减少”它)。

Fig 2: Vectors on opposite sides of a plane. See text for explanation. Made using https://github.com/ryu577/pyray

对于无约束最小化,我们寻找梯度为零的点。这是因为如果不是这样,我们可以通过与梯度相反的方向来降低目标函数。

同样的想法可以扩展到我们有等式约束的情况。像以前一样,我们需要找到一个点,在这个点上我们找不到任何可能的方向来移动目标函数减小的地方。对于无约束优化,这仅仅意味着不存在这样的方向。当我们有一个约束时,还有另一种可能性。如果减少目标函数的方向存在,但是约束禁止我们沿着它前进。

假设你想最大化你银行账户里的钱。一个立即增加收入的方法是卖掉一个肾。但是你可能有一个约束,说你不会失去一个重要的器官。所以,即使有一条简单的途径可以增加你的收入,你的约束也会阻止你去实现它。

这意味着等式约束的存在实际上降低了梯度条件的严格性。虽然对于没有等式约束的局部最优,它需要为零,但现在只要沿着任何有正阴影的方向移动会导致我们违反约束,它就可以非零。这只有在约束*面垂直于渐变时才会发生(如图 2 中的*面和绿色箭头)。

让我们回到我们的目标函数 f(x,y)=x +y。让我们添加一个等式约束,y=1。这是架飞机。在下面的图 3 中,目标函数是粉红色的,*面是蓝色的。由于我们被约束在*面上,我们不能沿着*面的梯度(下图中的蓝色箭头)在任何有正或负阴影的方向上移动,因为这将增加或减少约束的等式,而我们希望保持它不变。该*面与我们的目标函数(粉红色抛物面)的方程相交于一条抛物线上。下图中的粉色箭头是目标函数在这条抛物线上各点的梯度。如果粉红色的箭头有一个沿着蓝色*面的投影,我们可以沿着与该投影对应的向量相反的方向移动。这将使我们保持在*面上,确保我们不违反约束,同时仍然减少目标函数。然而,在下面图 3 中的绿点处,粉色箭头(目标函数的梯度)在蓝色*面上没有任何投影。换句话说,粉色箭头*行于蓝色箭头(这是约束*面的渐变)。

Fig 3: Constraint gradient aligns with objective function gradient at optima. Made using https://github.com/ryu577/pyray

为了降低目标函数,我们需要沿着负梯度的方向移动。但是一旦我们这么做了,我们就会离开约束*面。因此,该约束使得不可能在绿点处进一步降低目标函数。这意味着它一定是局部最小值。检查该条件的一个简单方法是要求目标函数的粉色渐变*行于约束*面的蓝色渐变。如果两个向量*行,我们可以把其中一个写成另一个的倍数。我们称这个倍数为λ。如果目标函数的梯度是∇f,约束的梯度是∇c,则上述条件是:

∇f = λ ∇c

上面的λ叫做拉格朗日乘数。因此,我们现在有一个具体的条件来检查时,寻找局部最优的约束优化问题。

不等式约束

不等式约束意味着你必须呆在定义约束函数的边界的一边,而不是在边界上(等式约束就是这种情况)。例如,呆在栅栏的边界内。如果我们知道如何处理不等式约束,我们就可以解决任何约束优化问题。这是因为等式约束可以转换为不等式约束。假设我们要求:c(x) = 0。另一种表达方式是:c(x)≥0,c(x)≤ 0。因此,每个等式约束总是可以用两个不等式约束来代替。

正如带有等式约束的约束优化可以用前面部分描述的拉格朗日乘子来处理一样,带有不等式约束的约束优化也可以。将不等式约束条件与等式约束区分开来的是不等式约束的拉格朗日乘数必须为正。要知道为什么,再次考虑沿着梯度有一个正分量的方向迈出一小步。如果我们能沿着这个方向迈出一步(如果我们是最大化;相反,如果我们是最小化);我们不可能处于最大值/最小值。对于不等式约束,这意味着拉格朗日乘数为正。要了解原因,让我们回到我们之前考虑的约束优化问题(图 3)。

最小化:f(x,y) = x +y

服从:c(x,y)=y-1=0

现在,让我们将等式约束改为不等式约束。这可以通过两种方式实现,结果完全不同。我们可以要求:

c(x,y) = y-1 ≥0。在这种情况下,约束允许图 3 中蓝色*面前面的任何东西。很容易看出,图 3 中的绿点仍然是局部最优。此外,由于表示约束梯度的蓝色箭头和表示目标函数梯度的粉色箭头指向相同的方向,因此我们有:

∇f = λ ∇c

λ>0。

另一种可能是,c(x,y) = y-1≤0。现在,可行区域变成了蓝色飞机后面的一切。约束梯度将翻转。因此,图 3 最终将看起来像这样:

Fig 4: Flipping the sign of inequality constraint from figure 3.

请注意,现在,

  1. 绿点不再是局部最优,因为我们可以自由移动到(0,0);也就是上面图 4 中的黄点。
  2. 在绿点,我们仍然有∇f=λ ∇c.,因为蓝色向量指向粉红色向量的相反方向,我们有λ <0.

So, it is clear that for an inequality constraint, the condition ∇f=λ ∇c indicates we’re at a local optima only when λ> 0。

将所有这些放在一起,对于一般的优化问题:

最小化 f( x )

服从于:

对于 i ∈等式,c_i( x ) =0

对于 i ∈不等式,c_i( x )≥0

我们得到了达到局部最优所需的全套条件:

拉格朗日乘数条件;

∇f =∑_ Iλ_ I ∇c_i(x)+∑_ jλ_ j ∇c_j(x);等式(1)

其中 i ∈等式和 j ∈不等式约束。

对于所有 I,c _ I(x)= 0;等式(2)

对于所有 j,c _ j(x)≥0;等式(3)

λ_ j≥0;等式(4)

还要注意,对于我们考虑的两个不等式约束问题,当我们有 y-1≥0 时,图 3 中的绿点就是解。此时,我们在约束*面上(y-1=0)。所以,我们实际上有 c( x )=0 和λ > 0。

另一方面,当我们考虑 y-1≤0 时,图 4 中的黄点(x=0,y=0)成为局部最小值。这一点也是无约束问题的解决方案。所以,我们这里只有∇f=0。由于拉格朗日条件要求∇f = λ ∇c,我们得到λ ∇c = 0。现在,∇c 在这一点上≠0,这意味着我们必须有:λ=0。

这意味着如果约束是活动的(c( x )=0),我们应该得到λ≥0,而如果不是(c( x )≠ 0),我们应该得到λ=0。所以,在所有情况下,其中一个应该是零。这导致了最后一个条件(互补条件):

λ_j c_j( x ) = 0 对于所有 j ∈不等式;等式(5)

等式(1)到(5)被称为 KKT 条件。请注意,我们并没有真正为它们提供严格的证明,只是基于简单的例子来构造它们。为了证明这一点,读者应该参考诺塞达尔和赖特的书的第 13 章。

很多人看到这五个方程时,觉得问题变得更加复杂了。这些方程实际上如何帮助我们解决约束优化问题。感受这一点的最好方法是通过一些具体的例子。在下一节中,我们拿一个我们事先知道答案的样本问题,看看 KKT 条件如何帮助我们正确地识别所有局部最优解。

代码示例

广义优化问题的特殊情况涉及线性目标函数和线性约束。这被称为线性约束线性规划(LCLP)。目标函数和约束也可以是二次的,这样的优化问题称为二次约束二次规划(QCQP)。有一些软件包能够解决这类针对大量约束条件(数百万)的优化问题。然而,对于具有更多可管理的约束的简单问题,我们可以利用能够解决大多数(更一般的)多项式约束多项式程序的算法。这意味着目标函数和约束可以是任意多项式函数。这是因为有一个用于求解多项式方程组的通用框架,称为“Buchberger 算法”,并且上述 KKT 条件可以简化为多项式方程组。我在这里写了一篇关于 Buchberger 求解多项式方程组的算法的详细博客。有一个名为“sympy”的 python 库,它在幕后使用类似这样的算法,并求解一般的多项式方程组。所以,事不宜迟,让我们框架我们的第一个约束优化问题。

*等约束

Minimize: x³+y³
Subject to: x²+y²=1

注意,约束(x +y =1)意味着我们在半径为单位的圆的边界上。所以,我们可以说:x=cos(t),y=sin(t)。目标函数于是变成:sin (t)+cos (t)。如果我们用 t 来绘制,我们会得到下图:

Fig 5: Objective function sin³(t)+cos³(t) plotted with t at the boundary of the constraint.

我们可以看到 t=0,π/2 和 5π/4 对应于局部极大值,而 t=π/4,π和 3π/2 对应于局部极大值。既然我们预先知道了答案,让我们看看上面描述的 KKT 条件是否也能找到这些。

等式(1)给出(取目标函数和约束的导数):

[3x,3y ] = λ[2x,2y]

使两侧向量的两个分量相等会得到两个等式:

3x -2λx=0

3y -2λy=0

等式(2)简单地要求等式约束得到满足:

x +y =1

并且由于没有不等式约束,我们不需要方程(3)到(6)。现在,我们可以将上面的三个方程输入到 python 库 sympy 提供的符号方程求解器中。

这导致以下结果(上述系统的所有可能解,其中 x、y 和λ的值按此顺序排列):

[(-1, 0, -3/2),(0, -1, -3/2),(0, 1, 3/2),(1, 0, 3/2),(-sqrt(2)/2, -sqrt(2)/2, -3*sqrt(2)/4),(sqrt(2)/2, sqrt(2)/2, 3*sqrt(2)/4)]

(-1,0)对应 t =π;(0,-1)对应 t = 3π/2;(-sqrt(2)/2,-sqrt(2)/2)对应于 t=5π/4,(sqrt(2)/2,sqrt(2)/2)对应于 t=π/4。因此,我们可以看到,我们上面确定的所有局部最大值和局部最小值都是由 KKT 条件确定的。现在,我们可以简单地在这些候选点找到目标函数的最大值和最小值。

不等式约束

现在,让我们把上面问题中的等式约束改为不等式约束,看看它如何改变我们的解。

Minimize: x³+y³
Subject to: x²+y²≤1

在前面的例子中,约束意味着我们只能在单位圆的边界上,现在我们可以在单位圆内的任何地方。

约束盘内目标函数的完整热图绘制如下(看起来像一个右上角有一颗星的行星)。红色箭头是约束边界的梯度,而黑色箭头是目标函数的梯度。

Fig 6: x³+y³ plotted within the disk x²+y²≤1

等式约束问题是一维问题,而不等式约束优化问题是二维的。而在一维中只有两种方法接*一个点(从左或右);在二维空间中有无数种方法可以接*它。这意味着我们需要小心鞍点。这些点有资格成为最优点,但不是真正的最优点,因为当你从一个方向接*它们时,它们是最大值,而当你从另一个方向接*它们时,它们是最小值。下图显示了鞍点的样子。

Fig 7: A saddle point. Maxima when you approach it from one direction, but minima when you approach it from another.

因此,我们需要重新评估在等式约束的情况下是局部最小值或最大值的所有点,并确保它们都不会成为鞍点。

图 5 告诉我们,当沿着边界接*时,t=0 (x=1,y=0)是局部最大值。当我们也从圆盘内部接*该点时(比如沿着连接 x=0,y=0 到该点的线),目标函数值随着我们接*它而增加。所以,t=0 是一个局部最大值,不管我们从哪里接*它。使用类似的论点(或者注意 x 和 y 的对称性),t=π/2 也是如此。

类似地,我们可以证明 t=π和 t=3π/2 是局部极小值,不管我们从可行域内的什么地方去接*它们。

然而,看看 t=π/4,我们从图 5 中注意到,沿着边界接*它使它成为局部最小值。然而,从圆盘内部接*它(例如,沿着原点到该点的连线)会使它成为局部最大值。所以,它总体上既不是局部极大值也不是局部极小值。这样的点称为鞍点。用类似的论证,t=5π/4 也是鞍点。

现在,让我们看看 KKT 条件对我们的问题是怎么说的。将目标函数和约束代入 KKT 方程(1)至(5),我们得到:

Equations 6 (a) through (e).

为了利用多项式方程解算器,我们需要将它们转换成一个多项式方程组。前两个条件(6-(a)和(b))已经是方程了。第三个,x +y ≤1 (6-(c))是一个不等式。但我们可以通过引入松弛变量 k,将其转化为等式;x +y +k =1。最后一个等式,λ≥0 同样是一个不等式,但是如果我们简单地用λ代替λ,就可以把它去掉。现在,我们演示如何将这些输入 python 提供的符号方程求解库。

Code solving the KKT conditions for optimization problem mentioned earlier.

这产生了以下结果(上述系统的各种解,变量 x,y,λ,k 按顺序排列):

[(-1, 0, -sqrt(6)/2, 0),(-1, 0, sqrt(6)/2, 0),(0, -1, -sqrt(6)/2, 0),(0, -1, sqrt(6)/2, 0),(0, 0, 0, -1),(0, 0, 0, 1),(0, 1, -sqrt(6)*I/2, 0),(0, 1, sqrt(6)*I/2, 0),(1, 0, -sqrt(6)*I/2, 0),(1, 0, sqrt(6)*I/2, 0),(-sqrt(2)/2, -sqrt(2)/2, -2**(1/4)*sqrt(3)/2, 0),(-sqrt(2)/2, -sqrt(2)/2, 2**(1/4)*sqrt(3)/2, 0),(sqrt(2)/2, sqrt(2)/2, -2**(1/4)*sqrt(3)*I/2, 0),(sqrt(2)/2, sqrt(2)/2, 2**(1/4)*sqrt(3)*I/2, 0)]

以上解决方案中的大写“I”指的是单位的*方根。我们想要拒绝这些解,因为我们要求λ ≥0。这意味着满足 KKT 条件的点是:(-1,0);(0,-1);(0,0)😭-1/sqrt(2),-1/sqrt(2))。如前所述,点(-1,0)(对应 t=π)和(0,-1)(对应 t=3π/2)为极小值。(0,0)和(-1/sqrt(2),-1/sqrt(2))是也陷入网中的鞍点。但是请注意,没有一个局部最大值被捕获。我留给你们一个小小的挑战。修改上面的代码,让它捕捉最大值而不是最小值。


如果你喜欢这个故事,成为推荐会员:)

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

巴西亚马逊地区的土地利用和森林砍伐

原文:https://towardsdatascience.com/land-use-and-deforestation-in-the-brazilian-amazon-5467e88933b?source=collection_archive---------8-----------------------

使用卫星图像和深度学习进行环境保护

简介和问题陈述

为什么是卫星图像?

去年 11 月,在大会上参加数据科学沉浸式课程时,我很兴奋,并确信我将要学习的工具将有许多应用。我几乎不了解 Python,没有接触过数据帧,也不能告诉你太多关于神经网络的知识。但我确信会有令人兴奋的事情发生。

从那以后,我完成了这个项目,最值得骄傲的是,我的顶点项目使用来自星球的卫星图像,根据天气、土地利用和土地覆盖对巴西亚马逊地区的场景进行分类。

这个项目令人兴奋的原因有很多:

  • 它给了我直接应用新技术解决生态保护问题的经验。
  • 这项工作提供了一个机会,让我足不出户就可以研究地球上任何地方的任何生态系统。(这并不是因为我懒。这并不是因为我不喜欢旅行。我在生态学领域的一个关注点是找到我们可以研究这个星球的方法,而不用年复一年地乘飞机去实地考察和参加会议。这种目前的做法令人感到讽刺和质疑——随着我职业生涯的进一步发展,我仍在试图解开这一点。也许这是我们无法避免的。或者我们可以用新技术来推进这个领域,以更可持续的方式发展。)
  • 它为未来的科学探索打开了新问题、新方法和新项目的潘多拉魔盒!

为什么是亚马逊?

许多生态学研究人员将注意力集中在热带和亚热带森林,因为地球上大部分的生物多样性和生物量都集中在这些地区。这些生态系统处于地球生态气候系统的中心,通过水、二氧化碳和氧气的循环影响区域和全球气候动态。

当然,这些森林是大量资源的家园,反过来又面临着来自森林砍伐和土地使用变化的巨大压力——以及全球气候变化。借助 Planet 等公司改进的卫星技术,我们可以找到远程监控这些珍贵生态系统的方法。通过机器学习模型,我们可以实时跟踪这些生态系统的变化,向当地政府和保护组织发出非法林业活动的警报,这些活动威胁着我们森林的生物多样性和生态气候功能。

收集数据

这个项目的数据来自这个 2017 Kaggle 比赛,由 Planet 收集和清理。

然而,为了演示用 Planet 的 API 生成我自己的图像,我构建了脚本来过滤和下载给定感兴趣区域(AOI)的图像。这是该项目的一个令人兴奋的方面,因为我非常喜欢数据管道工程任务,并探索新 API 的功能。

为监督学习分类问题生成我自己的图像的一些挑战是标记和格式化。图像没有固有的标签,因此如果我要收集足够多的图像(可能有数千个)来训练一个健壮的模型,标记可能是一个机械而费力的过程。此外,图像必须是标准大小才能用作神经网络的输入——编写一个程序将图像裁剪和剪切成标准格式本身就是一个项目!

考虑到时间限制,我决定继续研究 Kaggle 数据集。然而,随着时间和权限的增加(即访问 Planet 免费开放的加州图像之外的数据),Planet 的 API 对于未来的项目和应用来说是一个不可思议的资源。

Kaggle 数据集

这是我第一次涉足更严肃的大数据项目。该数据集包括一个训练数据集(40,000 张带标签的图像)和一个测试数据集——在竞赛网站上提交和评分的无标签图像。总的来说,这代表了超过 50 GB 的数据—远远超过了我的计算机上的 RAM(稍后会详细介绍)。

这些图像来自 PlanetScope 卫星,分辨率为 3m。包括分析 Geotiff 和可视 JPEG 格式,裁剪为 256 x 256 像素。图像包含四个颜色波段(红、绿、蓝、*红外),而 JPEGs 被校正为 EDA 的 3 波段视觉产品。

探索性数据分析

我的 EDA 的很大一部分包括更广泛地研究卫星图像数据。这是我第一次深入研究计算机视觉项目,所以这对我来说是一项相当大的任务。要了解更多这方面的内容,请查看我的另一篇媒体文章,主题是理解卫星图像中的图像数据和颜色通道。

在建模之前,了解数据集中不同标注分类的分布也至关重要。标签分为两类——天气和土地覆盖。图像只包含一个天气标签,但可以包含多个土地覆盖标签(这是多标签分类)。标签按类别组织如下:

  • 天气标签:晴,霾,多云,局部多云
  • 土地使用和土地覆盖标签:原始森林、道路、水、农业、住宅、裸地、耕作、开花、手工采矿、选择性伐木、刀耕火种、常规采矿、排放

下面,我绘制了图像标签在数据集中的出现频率。

Frequency of labels in the train dataset. Images can contain multiple labels

重要的是要注意到我们标签的严重不*衡。这在模型训练中是很重要的——模型将很难识别预测它没有频繁看到的标签所需的模式。

图像预处理

由于数据集庞大,需要克服各种障碍。为了准备用于建模的图像,必须从目录中读入图像以供神经网络处理。一种方法是通过名为 rasterio 的库。Rasterio 是一个很棒的库,因为它将地理位置数据保存在 tiffs 中,以防您在项目中使用这些信息。

我编写了一个自定义函数来实现这一点,但是,我缺少在单台机器上实现这一点所需的 RAM,我不得不尝试其他工具。

使用 AWS 迁移到云

一旦我掌握了在笔记本电脑上工作的挑战,我就改变了方式,使用亚马逊网络服务的深度学习 GPU 将项目转移到了云上。这让我在使用云中提供的大数据工具方面有了新的体验,并且需要调整弹性块存储卷来适应我的大型数据集。

然而,在使用 AWS 服务器时,我仍然面临内存限制,所以我必须使用 KERAS 自带的图像预处理工具来准备我的数据集进行建模。

测试时间增加

神经网络通过识别图像特征中的模式来“学习”。对于每个图像,特征是一个像素。然而,如果某种天气或土地类型只出现在图像的某个区域,神经网络将不会识别出图像中不同位置的完全相同的特征。

在 Keras 图像预处理中,我接触到了 ImageDataGenerator 类。这允许我应用测试时增强(随机翻转、旋转、缩放训练图像)来获得更好的建模方法。

Example TTA technique

图像数据生成器成批地从它们的目录中提取图像,读入图像,应用 TTA,并通过网络运行它们。这极大地减少了内存负载,并允许我训练神经网络,并在我的远程服务器上仅使用 7.5 GB RAM 的情况下对超过 50 GB 的图像进行预测。GPU 是令人难以置信的深度学习工具——如此不可思议,以至于我为它们创造了一个迷因!

建模

我构建了一个建模管道,可以适应多种模型和交叉验证。我计划训练一个更深层次的神经网络,并设置了一些功能来简化这个过程。不幸的是,在我不得不结束我的项目时,代码中的错误阻止了我在多个交叉验证折叠上训练神经网络(参见下面的限制和未来步骤部分)。

我使用了一个中等大小的卷积神经网络,带有调整大小的训练图像——由于内存和时间限制,缩小到 3 波段,128 x 128 像素。网络架构如下:

  • 输入的批量规范化
  • 32 过滤卷积层+最大池层+漏失(0.5)
  • 64 过滤卷积层+最大池层+下降(0.5)
  • 展*输出-128 节点密集连接图层+下降(0.5)
  • 17 节点输出层(代表 17 个目标标签类)。

我在 25 个时期内训练了我的模型(首先,20 个时期→权重重新初始化→ 5 个时期)。

结果

我跟踪了准确性和 F-Beta 分数(它们遵循相似的趋势),但主要关注 F-Beta 分数。F-beta 是精确度和召回率(灵敏度)的*均值,包括对假阳性和假阴性的加权惩罚,因此与精确度相比分数较低。与准确度相比,它可以是更严格的分类度量,尤其是对于多标签分类。

验证数据的最终 F-Beta 分数为 0.843 。测试数据集上的预测被提交给 Kaggle,并具有相似的 F-Beta (0.834),表明我的模型在大范围的未知数据上概括得很好。该模型稍有欠拟合,这可能是由于网络中过度激进的 TTA 或过度正则化(在多个层中的 0.5 的下降),或者是由于对看不见的数据的标注的过度预测。

过度预测导致验证集上 F-beta 分数的相对不稳定性。对于验证数据(其中我们可以跟踪预测与真实标签),该模型预测了 10,000 张图像的 43,000 多个标签,其中只有 28,000 个真实标签。这可能导致 F-Beta 分数的不稳定性和更高的准确度分数。例如,如果预测每个图像的所有 17 个标签,则预测的准确度为 1(因为每个正确的标签都被考虑在内)。但是,F-Beta 分数会低得多,因为对于实际上不在图像中的所有标签,会有许多假阳性。

Comparison of True and Predicted Label frequencies after model validation.

不*衡的类别也极大地影响了模型预测。模型预测很少包括训练数据中初始观察值少于 1,000 的标签(见上文)。虽然这些图像可能在测试数据集中的代表性较低,但我们的模型能够区分和预测这些特征对于模型的实时应用仍然很重要。

未来的步骤和限制

  • 限制每个图像或每个数据集的标签预测数量:为了纠正过度预测的问题,我可以在转换模型输出(概率)时限制可能的标签总数,以更好地反映标签的可能数量。这会是什么样子?第一,只考虑排名前T5【n的概率。在那些最高概率中,只接受那些高于阈值的概率。
  • 使用多个阈值测试预测的 F-beta 分数:模型输出 17 个概率,表示某个标签出现在每个图像中的可能性。然后,我们设置一个阈值,只接受高于阈值的概率。这些被转换为 1,意味着该特征在图像中。我对所有标签使用一个阈值。然而,改善模型结果的一种方法是更积极地为各个类别寻找最佳阈值。成功实现 k 重交叉验证和训练 k 个模型将允许 k 搜索最佳阈值。然后,我们可以选择每个折叠的*均阈值。
  • 引导以*衡标签类别:我还将通过具有低采样标签的目标图像来引导(创建“复制”不频繁标签的样本),增强那些图像并将增强的副本添加回数据集中。这可能会改进训练,而不管数据集中标签的初始频率(更多数据,由于扩充而不同的图像)。
  • 投资强大的计算资源:我的项目中的主要限制是 RAM。虽然访问远程 GPU 对于减少训练时间至关重要,但在整个项目中,我遇到了 RAM 过载的相当大的障碍(尽管我采取了措施来减少批量)。这些内存挑战,以及使用基于云的服务器的自付费用,也使得实验更深层次的神经网络变得困难(我对使用具有“ImageNet”权重的 ResNet 50 的潜力特别兴奋)。
  • 用模型集成进行实验:我通过在 Kaggle 讨论中的研究了解到集成对于神经网络的价值。在基本水*上,可以训练多个 CNN,并且可能对数据集中的某些标签做出更好的预测。然后可以组合来自每个神经网络的预测,并且对于每个输出(可能的标签),可以使用线性回归模型来预测每个图像的标签的“真实值”。不同的 CNN 预测将是预测目标值(1 或 0,存在或不存在)的特征。这些新值将仍然受制于用于在每个图像中存在或不存在标签时最终着陆的相同阈值。
  • 考虑模型的有效性和资源的使用:最有效的建模技术本质上需要无限的资源。虽然复杂的多模型集成方法可能会产生最佳的预测能力,但利益相关者必须考虑构建这样一个庞大的建模系统所需的成本(金钱和时间),以及如果模型要实时使用,分类速度会降低。这是一个正在进行的,逐例权衡的过程,但必须在深度学习的背景下考虑。

感谢阅读!请随意查看我在 GitHub 上的完整项目库。请分享你对我如何改进这个项目的方法的想法——我很想听听你的想法!

卡梅隆

使用生产数据的语言检测基准

原文:https://towardsdatascience.com/language-detection-benchmark-using-production-data-8fe6c1f9f46c?source=collection_archive---------35-----------------------

这是多语言语言检测算法的真实社交媒体数据基准。

The Tower of Babel by Pieter Bruegel the Elder (1563)

作为数据科学家,我们习惯于处理许多不同类型的数据。但是对于基于文本的数据,了解数据的语言是重中之重。在为英语、西班牙语、法语和塞尔维亚语开发四种基于语言的算法时,我亲身经历了这一挑战。

一般来说,处理多语言 NLP 算法的第一步是:检测文本的语言。然而,在生产过程中,数据在需要处理的不同语言之间通常是不*衡的,这意味着在将数据发送给算法之前,必须定义每个数据点的语言。对于任何处理数据中语言不*衡的产品来说,显然不“丢失”数据是产品成功的关键。因此,为了确保产品不会丢失数据,我们必须确保数据不会因为 LD 故障而被发送到错误的算法。了解数据分布对于为任何研究项目找到一个好的关键绩效指标(KPI) 至关重要,尤其是对于这个基准测试项目。

测试集的采样数据:

对于这个基准测试,我希望测试集尽可能地代表我在生产中通常拥有的东西。因此,我从 Twitter 上选择了有语言参数的 10 万条帖子,包括 95780 条英语推文、1093 条西班牙语推文、2500 条法语推文和 627 条塞尔维亚语推文。这个分布代表了生产中大约两周的数据。

此外,为了获得最好的测试集,一些注释者手工检查并纠正了 Twitter 语言参数中的潜在错误。这意味着我将测试过的模型与这个事实进行了比较。我还可以通过正确标记数据来消除 Twitter LD 偏见。(这里有个好办法)。

测试算法:

对于这个语言检测(LD)基准,我对比了 多语种 LD Azure Text Analytics LDGoogle Cloud LDfast Text LD

为了重现下面的代码,您需要 pip 安装所有导入的包。此外,您需要下载 FastText 算法,以创建 Azure API 信用和 Google Cloud API JSON 信用。

结果分析:

我的基准测试项目的结果表明,不同的模型服务于不同的度量。

准确性:如果准确性是最重要的指标,那么所有模型的表现几乎都是一样的(图 1)。

Figure 1: Global accuracy per model

然而,在我的项目中,准确的语言检测并不是唯一重要的 KPI。此外,防止数据丢失也很重要,因为如果数据丢失,产品将会失败。

召回:召回图(图 2)显示,尽管每个模型都非常精确,但总体而言,谷歌的模型在召回方面优于其他模型。

Figure 2: Recall by model for all languages

结论:

虽然第一直觉是只看准确性指标,这将导致有人假设 Azure 是语言检测的最佳表现者,但当其他指标发挥作用时,其他模型可能更好。在这种情况下,Google Cloud LD 在召回率方面优于 Azure(和所有其他测试的模型),特别是当正在处理的语言之间的数据不*衡时,其中有一个较大的数据集(英语),然后是其他语言(西班牙语、法语和塞尔维亚语)的明显较小的数据集。在我的特定项目中,回忆是主要的衡量标准,Google Cloud LD 最终是我的 LD 模型选择。

我要感谢来自 Zencity 的同事,他们在这个项目中发挥了重要作用:Inbal Naveh Safir、Ori Cohen 和 Yoav Talmi。

Samuel Jefroykin 是 Zencity.io 的一名数据科学家,他试图积极影响城市的生活质量。他还共同创立了 Data For Good Israel,这是一个致力于利用数据的力量解决社会问题的社区。

使用 RNNs 进行语言翻译

原文:https://towardsdatascience.com/language-translation-with-rnns-d84d43b40571?source=collection_archive---------1-----------------------

建立一个将英语翻译成法语的递归神经网络

2018 年 8 月 29 日由 托马斯·特雷西 ,原载 发布于 Github

西班牙语版本——此贴的西班牙语译文在此处,由Ibidem Group提供。非常感谢*!***

Image Credit: Peter Booth and Alexandra Booth / iStock

这篇文章探索了我在 Udacity 人工智能纳米学位项目的最终项目中的工作。我的目标是帮助其他学生和专业人士在机器学习(ML)和人工智能(AI)方面建立直觉的早期阶段。

尽管如此,请记住,我的职业是产品经理(不是工程师或数据科学家)。因此,接下来的内容是对这个项目中的 ML 概念和算法的半技术性但可接*的解释。如果下面提到的任何事情不准确,或者如果你有建设性的反馈,我很乐意听到你的意见。

我对这个项目的 Github 回购可以在这里找到。本项目的原始 Udacity 源回购位于此处。

项目目标

在这个项目中,我建立了一个深度神经网络,作为机器翻译管道的一部分。管道接受英语文本作为输入,并返回法语翻译。目标是尽可能实现最高的翻译准确性。

为什么机器翻译很重要

相互交流的能力是人类的一个基本组成部分。全世界有将* 7000 种不同的语言。随着我们的世界变得越来越紧密,语言翻译为来自不同国家和种族的人们提供了重要的文化和经济桥梁。一些比较明显的用例包括:

  • ****商业:国际贸易、投资、合同、金融
  • ****商业:旅游、购买外国商品和服务、客户支持
  • ****媒体:通过搜索获取信息,通过社交网络分享信息,内容本地化和广告
  • 教育:分享想法,合作,翻译研究论文
  • 政府:外交关系,谈判

为了满足这些需求,技术公司正在大力投资机器翻译。这项投资和深度学习的最新进展极大地提高了翻译质量。根据谷歌的说法,与之前在谷歌翻译中使用的基于短语的方法相比,切换到深度学习使翻译准确度提高了 60%。今天,谷歌和微软可以翻译 100 多种不同的语言,其中许多语言的准确度已经接*人类水*。

然而,尽管机器翻译已经取得了很大的进步,但它仍然不完美。😬

Bad translation or extreme carnivorism?

本项目的方法

为了将英语文本的语料库翻译成法语,我们需要建立递归神经网络(RNN)。在深入实现之前,让我们先对 rnn 建立一些直觉,以及为什么它们对 NLP 任务有用。

RNN 概述

rnn 被设计成接受文本序列作为输入,或者返回文本序列作为输出,或者两者都接受。之所以称之为递归,是因为网络的隐藏层有一个循环,其中每个时间步的输出和单元状态成为下一个时间步的输入。这种重现是一种记忆形式。它允许上下文信息在网络中流动,以便先前时间步的相关输出可以应用于当前时间步的网络操作。

这类似于我们阅读的方式。当你读这篇文章的时候,你正在储存以前的单词和句子中的重要信息,并用它作为理解每个新单词和句子的上下文。

其他类型的神经网络(还)做不到这一点。想象一下,您正在使用卷积神经网络(CNN)来执行电影中的对象检测。目前,没有办法从先前场景中检测到的对象信息通知模型在当前场景中检测到的对象。例如,如果在前一个场景中检测到法庭和法官,该信息可以帮助正确分类当前场景中法官的木槌,而不是将其错误分类为锤子或木槌。但是 CNN 不允许这种类型的时间序列上下文像 RNNs 一样在网络中流动。

RNN 设置

根据不同的用例,您可能希望设置您的 RNN 来以不同的方式处理输入和输出。对于这个项目,我们将使用多对多流程,其中输入是一系列英语单词,输出是一系列法语单词(下图中左起第四个)。

Diagram of different RNN sequence types. Credit: Andrej Karpathy

每个矩形是一个向量,箭头代表函数(如矩阵乘法)。输入向量是红色的,输出向量是蓝色的,绿色向量代表 RNN 状态(稍后会有更多介绍)。

从左到右:(1)没有 RNN 的普通处理模式,从固定大小的输入到固定大小的输出(例如图像分类)。(2)序列输出(例如图像字幕拍摄图像并输出一句话)。(3)序列输入(例如,情感分析,其中给定句子被分类为表达积极或消极情感)。(4)顺序输入和顺序输出(例如机器翻译:一个 RNN 读一句英语,然后输出一句法语)。(5)同步序列输入和输出(例如,视频分类,其中我们希望标记视频的每一帧)。请注意,在每种情况下,长度序列都没有预先指定的约束,因为递归转换(绿色)是固定的,可以应用任意多次。

— Andrej Karpathy,递归神经网络的不合理有效性

建设管道

下面是各种预处理和建模步骤的总结。高级步骤包括:

  1. ****预处理:加载和检查数据、清洗、分词、填充
  2. ****建模:构建、训练、测试模型
  3. ****预测:生成英语到法语的特定翻译,并将输出翻译与实际翻译进行比较
  4. ****迭代:迭代模型,试验不同的架构

要获得包括源代码在内的更详细的演练,请查看项目报告中的 Jupyter 笔记本。

结构

在这个项目中,我们使用 Keras 作为前端,TensorFlow 作为后端。我更喜欢在 TensorFlow 上使用 Keras,因为语法更简单,这使得构建模型层更直观。但是,Keras 有一个代价,因为您失去了进行细粒度定制的能力。但这不会影响我们在这个项目中构建的模型。

预处理

加载&检查数据

这是一个数据样本。输入是英语句子;输出是法语的相应翻译。

当我们进行字数统计时,我们可以看到数据集的词汇非常少。这是这个项目的设计。这允许我们在合理的时间内训练模型。

清洁

此时不需要进行额外的清洁。数据已经被转换为小写并被拆分,因此所有单词和标点符号之间都有空格。

****注意:对于其他 NLP 项目,您可能需要执行额外的步骤,例如:移除 HTML 标签、移除停用字词、移除标点符号或转换为标签表示、标注词性或执行实体提取。

标记化

接下来,我们需要对数据进行标记化——即,将文本转换成数值。这允许神经网络对输入数据执行操作。对于这个项目,每个单词和标点符号将被赋予一个唯一的 ID。(对于其他 NLP 项目,给每个字符分配一个唯一的 ID 可能是有意义的。)

当我们运行 tokenizer 时,它会创建一个单词索引,然后用来将每个句子转换成一个向量。

填料

当我们将单词 id 序列输入到模型中时,每个序列都需要有相同的长度。为了实现这一点,填充被添加到任何比最大长度短的序列(即比最长的句子短)。

一键编码(未使用)

在这个项目中,我们的输入序列将是一个包含一系列整数的向量。每个整数代表一个英文单词(如上图)。然而,在其他项目中,有时需要执行一个额外的步骤来将每个整数转换成一个独热编码向量。我们在这个项目中没有使用一键编码(OHE),但是你会在某些图中看到它的引用(如下图所示)。我只是不想让你困惑。

OHE 的优势之一是效率,因为它可以以比其他编码更快的时钟速率运行。另一个优点是,OHE 可以更好地表示不同值之间没有顺序关系的分类数据。例如,假设我们将动物分为哺乳动物、爬行动物、鱼类或鸟类。如果我们将它们分别编码为 1,2,3,4,我们的模型可能会假设它们之间有一个自然的排序,但实际上并没有。把我们的数据组织成哺乳动物在爬行动物之前是没有用的。这可能会误导我们的模型,导致糟糕的结果。然而,如果我们随后对这些整数应用一键编码,将它们更改为二进制表示形式(分别为 1000、0100、0010、0001 ),那么模型就无法推断出序数关系。

但是,OHE 的一个缺点是向量会变得很长很稀疏。向量的长度由词汇表决定,即文本语料库中唯一单词的数量。正如我们在上面的数据检查步骤中看到的,我们这个项目的词汇量非常小——只有 227 个英语单词和 355 个法语单词。相比之下,牛津英语词典有 172000 个单词。但是,如果我们包括各种专有名词、单词时态和俚语,每种语言可能有数百万个单词。例如,谷歌的 word2vec 是在 300 万个独特词汇的基础上训练出来的。如果我们在这个词汇表中使用 OHE,每个单词的向量将包括一个被 2,999,999 个零包围的正值(1 )!

而且,由于我们正在使用嵌入(在下一步中)来进一步编码单词表示,我们不需要为 OHE 费心。对于这么小的数据集,任何效率提升都是不值得的。

建模

首先,让我们从高层次上分析一下 RNN 的架构。参考上图,我们需要了解模型的几个部分:

  1. ****输入。输入序列被输入到模型中,每个时间步长一个单词。每个单词都被编码为一个唯一的整数或独一无二的编码向量,映射到英语数据集词汇。
  2. ****嵌入层。嵌入用于将每个单词转换成一个向量。向量的大小取决于词汇的复杂程度。
  3. ****递归层(编码器)。这是将先前时间步骤中的单词向量的上下文应用于当前单词向量的地方。
  4. ****密集层(解码器)。这些是典型的全连接层,用于将编码输入解码成正确的翻译序列。
  5. ****输出。输出以整数序列或独热编码向量的形式返回,然后可以映射到法语数据集词汇表。

嵌入

嵌入允许我们捕捉更精确的句法和语义单词关系。这是通过将每个单词投影到 n 维空间中来实现的。意义相似的词占据这个空间的相似区域;两个词越接*,就越相似。单词之间的向量通常代表有用的关系,如性别、动词时态,甚至地缘政治关系。

Photo credit: Chris Bail

从头开始在大型数据集上训练嵌入需要大量的数据和计算。因此,我们通常使用预先训练好的嵌入包,如手套或 word2vec ,而不是自己动手。以这种方式使用时,嵌入是一种迁移学习的形式。然而,由于我们这个项目的数据集只有很少的词汇和很低的语法变化,我们将使用 Keras 来训练我们自己的嵌入。

编码器和解码器

我们的序列到序列模型链接了两个递归网络:编码器和解码器。编码器将输入汇总到一个上下文变量中,也称为状态。然后解码该上下文,并生成输出序列。

Image credit: Udacity

由于编码器和解码器都是递归的,它们有循环,在不同的时间步处理序列的每个部分。为了描述这一点,最好展开网络,这样我们就可以看到每个时间点发生了什么。

在下面的例子中,编码整个输入序列需要四个时间步长。在每个时间步,编码器“读取”输入单词,并对其隐藏状态进行转换。然后将隐藏状态传递给下一个时间步。请记住,隐藏状态表示流经网络的相关上下文。隐藏状态越大,模型的学习能力越大,但计算需求也越大。当我们讨论门控循环单元(GRU)时,我们将更多地讨论隐藏状态中的转换。

Image credit: modified version from Udacity

现在,请注意,对于序列中第一个单词之后的每个时间步长,有两个输入:隐藏状态和序列中的一个单词。对于编码器,它是输入序列中的下一个字。对于解码器,它是输出序列中的前一个字。

此外,请记住,当我们提到“单词”时,我们实际上是指来自嵌入层的单词的矢量表示

这是另一种可视化编码器和解码器的方法,除了普通话输入序列。

Image credit: xiandong79.github.io

双向层

现在我们已经了解了上下文是如何通过隐藏状态在网络中流动的,让我们更进一步,允许上下文双向流动。这就是双向层的作用。

在上面的例子中,编码器只有历史上下文。但是,提供未来的上下文可以获得更好的模型性能。这似乎与人类处理语言的方式相违背,因为我们只能单向阅读。然而,人类经常需要未来的上下文来解释正在说的话。换句话说,有时直到最后提供了一个重要的单词或短语,我们才理解一个句子。尤达一说话就会这样。😑 🙏

为了实现这个,我们同时训练两个 RNN 层。第一层按原样输入输入序列,第二层输入反向拷贝。

Image credit: Udacity

具有门控递归单元的隐藏层(GRU)

现在让我们让我们的 RNN 更聪明一点。与其让隐藏状态的所有信息在网络中流动,不如我们更有选择性?也许一些信息更相关,而其他信息应该被丢弃。这基本上就是门控循环单元(GRU)所做的。

GRU 中有两个门:更新门和复位门。西蒙·科斯塔迪诺夫的这篇文章详细解释了这些。总之,更新门 (z)有助于模型确定有多少来自先前时间步骤的信息需要传递到未来。同时,复位门 (r)决定要忘记多少过去的信息。

Image Credit: analyticsvidhya.com

最终模型

既然我们已经讨论了模型的各个部分,让我们来看看代码。同样,所有的源代码都可以在笔记本 ( )的中找到。html 版本)。

结果

最终模型的结果可以在笔记本的单元格 20 中找到。

验证准确率:97.5%

训练时间:23 个时代

未来的改进

  1. 进行适当的数据分割(培训、验证、测试)。目前,没有测试集,只有训练和验证。显然,这不符合最佳实践。
  2. LSTM +关注。这是过去几年中 rnn 的事实架构,尽管有一些限制。我没有使用 LSTM,因为我已经在另一个项目中用 TensorFlow 实现了它,我想在这个项目中用 GRU + Keras 做实验。
  3. 在更大更多样化的文本语料库上训练。这个项目的文本语料库和词汇非常小,语法变化很小。因此,模型非常脆弱。为了创建一个更好的概括模型,你需要在语法和句子结构上有更多可变性的更大的数据集上进行训练。
  4. 残留层。你可以添加残余层到一个深 LSTM RNN,如本文所述。或者,使用剩余层作为 LSTM 和 GRU 的替代,如这里所述。
  5. 嵌入。如果你在一个更大的数据集上训练,你肯定应该使用一组预训练的嵌入,比如 word2vec 或者 GloVe 。更好的是,使用 ELMo 或 BERT。
  • 嵌入语言模型(ELMo) 。2018 年通用嵌入最大的进步之一是 ELMo ,由艾伦人工智能研究所开发。ELMo 的主要优势之一是它解决了一词多义的问题,即一个单词有多个意思。ELMo 是基于上下文的(不是基于单词的),因此一个单词的不同含义在嵌入空间中占据不同的向量。使用 GloVe 和 word2vec,每个单词在嵌入空间中只有一个表示。例如,“queen”这个词可以指皇室的女族长、蜜蜂、棋子或 20 世纪 70 年代的摇滚乐队。对于传统的嵌入,所有这些含义都与单词 queen 的一个向量联系在一起。对于 ELMO,这是四个不同的向量,每个向量都有一组独特的上下文单词,占据嵌入空间的相同区域。例如,我们期望在与国际象棋游戏相关的类似向量空间中看到像皇后这样的词。我们期待看到蜂后蜂房蜂蜜出现在与蜜蜂相关的不同向量空间中。这极大地促进了语义编码。
  • 双向编码器表示来自 变压器 (BERT) 。2019 年到目前为止,双向嵌入最大的进步是 BERT ,由谷歌开源。伯特有什么不同?

诸如 word2vec 或 GloVe 之类的上下文无关模型为词汇表中的每个单词生成单个单词嵌入表示。例如,单词“bank”在“bank account”和“bank of the river”中具有相同的上下文无关的表示相反,上下文模型根据句子中的其他单词生成每个单词的表示。例如,在句子“我访问了银行帐户”中,单向上下文模型将基于“我访问了”而不是“帐户”来表示“银行”然而,BERT 使用它的上一个和下一个上下文来表示“银行”——“我访问了……账户”——从深度神经网络的最底层开始,使其具有深度双向。
—雅各布·德夫林和张明蔚,谷歌人工智能博客

接触

我希望你觉得这很有用。同样,如果你有任何反馈,我很想听听。欢迎在评论中发表。

如果你想讨论其他合作或职业机会,你可以在 LinkedIn 这里找到我,或者在这里查看我的作品集。

Laravel 和 Vue.js:这对情侣为什么会红?

原文:https://towardsdatascience.com/laravel-and-vue-c30770f1e88?source=collection_archive---------3-----------------------

source

你可能想知道 VueJS 和 Laravel 怎么会有关系。VueJS 是一个 Javascript 框架,Laravel 是一个 PHP 框架,它们不可能互相服务于任何目的,不是吗?记住,如果在任何时候你觉得事情超出了你的能力范围,你可以随时雇佣一个开发人员。

然而,要理解这一点,您首先需要用这么多的事实来启发自己,这是一个详尽的停止,在这里您将找到您需要了解的关于这两个框架的一切,更不用说它们如何对彼此有用了。再来说说 Vue。JS 第一。

简单介绍一下 Vue。射流研究…

如果你还不知道的话,Vue。JS 是一个非常高级的 Javascript 框架,是为设计用户界面和单页应用程序而构建的。VueJS 由尤雨溪开发,是一个开源的 javascript 框架,具有自适应的架构。它侧重于声明性呈现和组件组合。

目前 Vue.js 在 GitHub 上有超过 148k 颗星,这说明了它在开发者中的受欢迎程度。如果你是一个前端框架爱好者,那么你会惊讶于它是如何无缝地集成到大型项目中并简化 web 开发过程的。

好书 : 将统治 2020 年的顶级软件趋势

VueJS 的 5 大特点

到目前为止,我上面所说的一切都是空谈,但让我们深入了解它的具体特性,并向您展示为什么 Vue 应该是您的下一个框架

虚拟 Dom

您在 Vue 中引入的任何修改都不会直接反映在 DOM 中。相反,DOM 的副本是作为 Javascript 数据结构创建的。如果需要进行更改,那么它们会被引入到数据结构的 Javascript 中。然后将它与初始数据结构进行比较,这样可以节省大量时间。

数据绑定

数据绑定是一个过程,通过该过程,用户可以使用 web 浏览器操纵网页的元素。它利用动态 HTML,不需要任何复杂的脚本或编程。在这个函数的帮助下,您可以轻松地管理值或将它们分配给 HTML 属性。

成分

VueJS 的一个特征是它能够重用组件。这些组件帮助您扩展基本的 HTML 元素来封装可重用的代码。

动画/过渡

在 VueJS 中,当 HTML 元素被添加到 DOM 或从 DOM 中删除时,您会发现几种在 HTML 元素中应用转换的方法。它有一个内置的过渡组件,必须环绕元素才能获得过渡效果。我们也可以添加第三方动画库。

模板

Vue。JS 附带了基于 HTML 的模板,这些模板将 DOM 与 Vue 实例数据绑定在一起。Vuejs 将这些模板编译成虚拟 DOM 渲染函数。为了使用渲染函数模板,我们必须用渲染函数替换模板。

关于拉勒维尔的一点简介

Laravel 是一个基于 PHP 的免费开源 web 框架。Laravel 由 Taylor Otwell 创建,旨在提高生产率。他们每 6 个月推出一个新版本,最*他们在两周前的 9 月 3 日推出了最新版本,这个版本有长期支持(LTS)。Laravel 具有过多的功能。让我们来看看其中的一些。

也读: 如何在预算内 雇佣 React 开发者

Laravel 的五大特点

雄辩的 ORM

ORM 或对象关系映射是活动记录模式的 PHP 实现。它允许我们做的是将数据库表表示为类。如果您感到困惑,这意味着您可以定义一个类,比如说“User”,它将绑定到数据库中的“users”表。现在“users”表中的每一行都将被表示为 Laravel 中 User 类的一个实例。

模板引擎

Laravel 因其轻量级模板而得到高度认可,该模板可以帮助您使用动态内容播种来创建令人惊叹的布局。最重要的是,它有多个包含 CSS 和 JS 代码的小部件,结构坚固。laravel 框架的模板是专门设计来创建具有独特部分的简单布局的。

技工

Laravel 提供了一个名为 Artisan 的内置命令行工具。它们用于创建数据库结构、框架代码,并构建它们的迁移,这使得管理数据库系统变得非常容易。不仅如此,它还可以通过命令行瞬间交错生成基本的 MVC 文件,并管理那些资产及其各自的配置。

自动包裹递送

过去,安装数据包并不容易,直到 Laravel 5.5 推出了一个方便的解决方案。顾名思义,Automatic Package Delivery 自动检测用户想要安装的软件包,而不需要设置任何别名或提供者来安装新的软件包。

数据库迁移

Laravel 的命令行界面(CLI)Artisan 使数据库迁移和播种变得极其容易。如果您将所有数据库工作都放在迁移和种子中,那么您可以轻松地将更改迁移到您拥有的任何其他开发机器上。

好读: 现在你可以 以 60%的成本雇佣 laravel 开发者

VueJS 是如何工作的?

如果您在事件驱动的前端 JavaScript 框架出现之前曾经为 web 编程,那么您可能会理解尝试更新文档对象模型(DOM)会带来相当大的困难和低效。

更新 DOM 仅仅意味着您必须获取页面,对其中的一小部分进行必要的更改,然后重新加载整个 DOM,这样更改才能生效。例如,如果你正在观看一个 YouTube 视频,并且添加了新的评论,那么整个页面都必须重新加载,这也意味着你的视频将从头开始。

Vue 通过整合虚拟 DOM 来管理用户将看到的内容,努力应对这些挑战。就像我上面说的,Vue 本质上做的是创建 DOM 的副本并存储它。如果对 DOM 的一部分做了任何更改,它只更新 DOM 的那个部分,而不重新加载整个 DOM。这意味着评论会在你没有注意到的情况下更新。

Vue 提供了可反应的和可组合的视图组件。它响应任何更新,并立即触发 DOM 中所需的更改。它的可组合组件可以选择和组装成各种组合,以满足任何需要。你可以为所有的事情准备组件,并根据你的需要重用它们。如果这很难理解,你可以雇佣一个 VueJS 开发者。

好读: 如何能在印度 雇佣安卓开发者 以更少的成本

为什么我们应该将 Vue 与 Laravel 一起使用?

尽管 Laravel 和 VueJS 来自不同的编程语言,而且 VueJS 如何支持 Laravel 似乎无关紧要,但令我惊讶的是,它支持的方式不止一种。以下是您应该将 VueJS 与 Laravel 一起使用的原因:-

1.一切都发生在前端

当今的 Web 应用程序是事件驱动的。它们的构建是为了确保用户拥有无缝的体验,就像他们使用安装在他们计算机上的应用程序一样。所有的改变都发生在前端,用户再也不用重新加载页面了(感谢 JavaScript)。

2.反应式组件构成了一个优秀的事件驱动应用程序

Vue 可以帮助您构建一个全面的事件驱动的 web 应用程序,处理前端的所有活动。它还提供了可以任意使用的可组合组件。鉴于它与 Laravel 配合得很好,您只需往返几次就可以从 Laravel 应用程序请求数据,并通过切换组件来更改 UI,而无需重新加载页面。

您可以简单地在您的 Vue(前端)中提示 UI 更改,这反过来为您的用户提供了一个惊人的体验。它可以简单到使页面上的文本可编辑,或者换出整个组件来加载用户请求的视频,而无需重新加载页面。

鉴于 Vue 的速度和性能,这发生得非常快和顺利,而不占用你的电脑资源这么多。

3.构建最佳复杂前端页面

如果您考虑构建一个部分需要频繁更新的应用程序,除了让前端完全运行在 JavaScript 上,您没有其他选择。

没有虚拟 DOM 的普通 JavaScript 或 jQuery 或其他 JavaScript 库面临的挑战是,随着更新频率的增加或跟踪变化的数据量的显著增加,您很快就会遇到性能问题。对 DOM 的更改将逐渐不再是即时的,您将开始体验到明显的性能滞后。

当您使用 Vue 组件编写应用程序时,每个组件的依赖关系都会在呈现过程中被自动跟踪,因此当数据发生变化时,系统可以准确地知道哪个组件实际上需要更新。这使得对 DOM 的所有更新使用最少的资源,从而提高了整个应用程序的效率。

Vue 还与 Flux、Redux 和 Vuex 等状态管理器兼容,这些管理器在管理复杂应用程序中的数据流方面表现出色。Vue 对单向数据绑定模型的利用也使得复杂应用程序中的状态管理更加容易。

4.单页应用程序

我想分享一个个人观点——单页应用程序是过去十年中互联网上发生的最伟大的事情。它向比以前更广泛的用户开放了应用程序。

当你考虑到美国和欧洲某些地区之外的许多互联网用户在上网方面有困难时,你开始意识到单页应用程序在向他们提供丰富的网络体验方面所起的作用。

您的整个应用程序资产被加载一次(其中大部分被缓存),当用户使用它时,您的应用程序所做的只是请求数据,这通常需要很低的带宽来完成。

5.易于学习和使用

Vue 很容易进入。作为开发人员,它为您提供的选项很少,而且抽象了很多。当你使用 Vue 时,你会觉得你在编写普通的 JavaScript,你可以用普通的 JavaScript 编写一个简单的应用程序,它在 Vue 中仍然有效。

Vue 的另一个优点是你的有效 HTML 也是一个有效的 Vue 模板。您可以将 CSS 保留在外部,也可以根据您的应用程序需求用 JavaScript 来处理它。您还可以利用作用域样式,在不影响其他组件的情况下,动态地将样式更改应用于单个组件。

如果您熟悉 JavaScript,只需花一天时间阅读文档,就可以用 Vue 构建一个不*凡的应用程序。

结论

现在,您已经非常详细地了解了 Vue 和 Laravel,并且了解了如何将 Laravel 和 VueJS 集成在一起,将有助于您获得两者的最佳效果。这些框架分别为世界上一些主要的 web 应用程序做出了贡献,想象一下你可以用它们一起做什么。如果你想雇佣一个 PHP 开发人员或者甚至雇佣一个 VueJS 开发人员,你可以很容易地找到他们,因为他们是市场上最受欢迎的一些框架。

大型图形可视化工具和方法

原文:https://towardsdatascience.com/large-graph-visualization-tools-and-approaches-2b8758a1cd59?source=collection_archive---------2-----------------------

怎么办,如果你需要可视化一个大型网络图但是你尝试的所有工具都只能画一个毛球或者吃掉你所有的 RAM 挂你的机?两年多来,我一直从事大型图形(上亿个节点和顶点)的工作,并且尝试了很多工具和方法。但是我仍然没有找到任何好的调查,所以现在我自己写这样一份调查。

(这是我在 habr 上的文章的翻译,原文是俄语)

为什么要可视化一个图表呢?

  1. 找什么找什么
    通常,我们只是简单地有一组顶点和边作为输入。我们可以根据这样的数据计算一些统计数据或图形度量,但这还不足以了解结构。一个好的可视化可以清楚地显示图形中是否有一些集群或桥,或者可能是均匀的云,或者其他什么。
  2. 为了给公众留下深刻印象,数据可视化显然是用来展示的。这是展示已完成工作的结论的好方法。例如,如果您解决了一个聚类问题,您可以通过标签为您的图着色,并显示它们是如何连接的。
  3. 获取特征
    尽管大多数图形可视化工具只是为了制作一些图片而创建的,但它们也是很好的降维工具。表示为邻接矩阵的图是高维空间中的数据。当我们画它的时候,每个顶点有两个(通常)坐标。这些坐标也可以用作特征。这个空间中顶点之间的接*意味着相似。

大图表有什么问题?

我的意思是“大图”的大小大约从 10K 顶点和/或边。尺寸小一点的通常没有问题。通过几分钟的搜索,你能找到的所有工具很可能至少可以接受。大型网络有什么问题?主要有两个问题:可读性和速度。通常,大型图形的可视化看起来很混乱,因为在一个图中有太多的对象。此外,图形可视化算法大多有可怕的算法复杂性:边或顶点的数量的二次或三次依赖。就算等一次结果,找到更好的参数也太久了。

关于这个问题已经写了什么?

[1] Helen Gibson,Joe Faith 和 Paul Vickers:“信息可视化二维图形布局技术综述”

本文的作者讲述了现有的图形可视化方法以及它们是如何工作的。还有一个很好的表格,里面有关于算法、它们的特性和复杂性的信息。我在这篇文章中使用了那篇论文中的一些图片。

[2]Oh-Hyun Kwon、Tarik Crnovrsanin 和 Kwan-刘妈“在这种布局下,图表看起来会是什么样?大型图形可视化的机器学习方法"

作者做了大量的工作。他们尝试了所有可能的算法。然后他们画出来,人工评估相似度。之后,他们拟合模型来预测图表在这种布局下会是什么样子。我也使用了这幅作品中的一些图片。

理论部分

布局是一种将坐标映射到每个顶点的方法。通常,这是 2D *面上的坐标。

什么是好的布局?

很容易判断某物看起来是好是坏。命名标准并不容易,机器怎么能评估它。为了做出所谓的“好”布局,可以使用美学度量。以下是其中的一些:

  1. 最小边缘交点
    显而易见:过多的交点会使情节看起来混乱。
  2. 相邻的顶点比不相邻的顶点彼此更靠*
    这是连接的节点应该彼此靠*的逻辑。根据定义,它代表了图表中的主要信息。
  3. 社区被分组为簇
    如果有一组顶点相互之间的连接比图中的其他部分更频繁,它们应该看起来像一朵密集的云。
  4. 最小重叠边和节点。
    同样显而易见的是:如果我们不能确定顶点是少还是多,那么绘图的可读性就很差。

存在哪种布局?

我认为提及这三种类型的布局很重要。然而,可以用许多其他方式对它们进行分类。但是这种分类足以浏览所有可能的类型。

  • 力导向和基于能量
  • 降维
  • 基于节点特征

力导向和基于能量

Force-directed layouts examples. Source of the picture is [1]

这类方法基于物理系统模拟。顶点被表示为相互排斥的带电粒子,边被视为弹性弦。这些方法试图模拟这个系统的动态或找到最小能量。

这种方法通常给出非常好的结果。结果图很好地反映了图形的拓扑结构。但是它们也很难计算,并且有许多参数需要调整。

这个家族的重要成员有原力·阿特拉斯、弗吕赫特曼-莱因戈尔德、卡马达·卡哇伊和奥彭德。最后一个使用巧妙的优化来加快计算速度,例如,它切割长边。因为一个有用的副作用图表变得更加聚集。

降维

Dimension reduction layouts examples. Source of the picture is [1]

一个图可以定义为邻接矩阵 NxN,其中 N 是节点数。这个矩阵也可以被视为 N 维空间中的 N 个对象的表格。这种表示允许我们使用通用的降维方法,如 PCA、UMAP、tSNE 等。另一种方法是计算节点之间的理论距离,然后在移动到低维空间时尝试节省比例。

基于特征的布局

Hive Plot example. Source of the picture is [1]

通常,图形数据与现实世界中的一些对象相关。因此顶点和边可以有自己的特征。因此我们可以用这些特征在*面上表示它们。我们可以使用上述降维方法或通过直接绘制成对特征的散点图,像处理通常的表格数据一样处理节点特征。值得一提的是蜂巢图,因为它与所有其他方法都很不同。在蜂巢图中,节点与几个径向轴对齐,边是它们之间的曲线。

大型图形可视化工具

The joy of graph visualization.

尽管图形可视化问题相对古老和流行,但对于可以处理大型图形的工具来说,情况非常糟糕。大部分都被开发商抛弃了。几乎每一种都有它们的大缺点。我将只讲述那些值得一提并能处理大图的人。关于小图,没有问题。你可以很容易地找到一个工具来实现你的目的,而且很有可能它会工作得很好。

GraphViz

Bitcoin transaction graph before 2011

Sometimes it’s hard to tune the parameters

这是一个老派的 CLI 工具,有自己的图形定义语言“dot”。这是一个有几种布局的包。对于大型图形,它有sfdp布局,来自 force-directed 系列。这个工具的优点和缺点是一样的:它从命令行运行。这对自动化很有用,但是没有交互性就很难调整参数。你甚至不知道你需要等待结果多久,也不知道你是否需要停止它,用其他参数重新运行。

格菲

Image from gephi.org

137K movies recommendation graph from iMDB

A few million is already too much for Gephi

我所知道的最强大的图形可视化工具。它有图形用户界面,它包含几个布局和大量的图形分析工具。还有很多社区写的插件。例如,我最喜欢的布局“Multigravity Force-Atlas 2”或 sigma.js 导出工具,它可以根据您的项目创建交互式网页模板。在 Gephi 中,用户可以根据它的特性给节点和边着色。

但是 Gephi 被开发者抛弃了。它也有一个有点过时的图形用户界面,缺乏一些简单的功能。

igraph

Last.fm music recommendation graph. Source, description and interactive version are here

我需要向这个通用图形分析包致敬。最令人印象深刻的图形可视化之一是由 igraph 的作者之一制作的。

igraph 的缺点是 python API 的文档很糟糕,但是源代码是可读的,并且有很好的注释。

LargeViz

Several tens of million vertices (transactions and addresses) in one of the largest bitcoin clusters

当你需要画一张真正巨大的图表时,它是一个大救星。LargeViz 是一个降维工具,不仅可以用于图形,还可以用于任意表格数据。它从命令行运行,工作速度快,消耗一点内存。

制图

Addresses that could be hacked in one week and their transactions

Intuitive and pretty looking GUI, but very limited

它是本次调查中唯一的付费工具。Graphistry 是一项服务,它获取你的数据,并在其端进行所有的计算。客户只看他浏览器中的漂亮图片。其他特性并不比 Gephi 好多少,除了 Graphistry 有合理的默认参数,良好的配色方案和略好的交互性。它只提供一种强制布局。它也有 80 万个节点或边的限制。

图形嵌入

对于疯狂的尺寸也有一种方法。从大约一百万个顶点开始,只看顶点密度是合理的,根本不画边和特定的顶点。仅仅是因为没有人能够在这样的地块上辨认出单个的物体。此外,大多数为图形可视化设计的算法在这样的规模下需要工作很多小时,甚至几天。如果我们稍微改变一下方法,这个问题就可以解决。有许多方法可以获得反映图顶点特征的固定大小的表示。在得到这样的表示之后,你唯一需要做的就是把维数减少到两个,以便得到一幅图像。

Node2Vec

Node2Vec + UMAP

这是 word2vec 对图形的改编。它使用图中的随机游走而不是单词序列。因此,该方法仅使用关于节点邻域的信息。在大多数情况下,这就足够了。

VERSE + UMAP

通用图形表示的高级算法。我经历中最好的之一。

图形卷积

Graph Convolutions + Autoencoder. Bipartite graph.

有很多方法可以定义图上的卷积。但实际上,这是顶点的邻居对特征的简单“传播”。我们也可以把局部拓扑信息放在顶点特征中。

小奖励

我做了一个没有神经网络的简化图卷积的小教程。它位于[这里](https://github.com/iggisv9t/graph-stuff/blob/master/Universal Convolver Example.ipynb)。我还制作了一个[图形嵌入教程](https://github.com/iggisv9t/graph-stuff/blob/master/Graph Embeddings Tutorial.ipynb),在那里我展示了如何使用上面提到的一些工具。

链接

【arxiv.org/pdf/1902.07153.pdf】简化图卷积网络
T4

GraphVizgraphviz.org

Gephigephi.org

igraph.org

arxiv.org/abs/1602.00370
github.com/lferry007/LargeVis

www.graphistry.com
制图

node 2 vecsnap.stanford.edu/node2vec
github.com/xgfs/node2vec-c


tsitsul.in/publications/verse
github.com/xgfs/verse

带简化图形卷积的笔记本示例
github . com/iggisv 9t/graph-stuff/blob/master/Universal % 20 convolver % 20 example . ipynb

图卷积关于图卷积网络的论文列表:github.com/thunlp/GNNPapers

TL;博士:

graphia[2020 年 6 月 5 日更新]

This is the neuron connections of the part of the fly brain from https://neuprint.janelia.org/

这篇文章发表于大约一年前。现在有了一个新的非常有前途的图形可视化工具,特别是大型图形: Graphia 。它正在积极开发中,而不是早已废弃的 Gephi,而且运行速度也快得多。因为 Gephi 集成了很多工具,你可以在这里阅读:https://graphia.app/userguide.html

缺点是可以原谅的:

  • 目前,它只有一个力导向的布局和非常有限的方法来调整它。
  • 渲染选项不适用于大型图形。至少选择关闭边缘显示或增加不透明度将是非常有用的。
  • 目前 Graphia 相对来说还不成熟。例如,我必须用 Gephi 转换图形格式,以便放入 Grapia,它在表示为 CSV 的相同图形上崩溃。但是我相信这些小事情很快都会得到改善的。

优点不胜枚举。想象一下,Gephi 拥有所有这些分析工具,但在 C++上从头开始重写,速度更快,并且正在积极开发中。做个对比:Gephi 布局 173K 节点图需要几个小时,Graphia 只需要几分钟。

我相信这个评论很快就会过时,所以最好自己检查一下这个 app 的当前状态。

【2022 年 7 月更新】

不得不说这篇文章有些观点有点过时了:

  • 格菲不再被遗弃了
  • Graphia 看起来还很原始。它很快,但是可视化太混乱,而且不可能调整视图使其可用。
  • 现在有几个很棒的在线工具

新工具

宇宙摄影仪

[## Cosmograph:大图的可视化分析

在您的笔记本电脑上处理由成千上万个节点和边组成的网络图。

cosmograph.app](https://cosmograph.app/)

在 webgl、开源核心和 sane 默认设置上使用强制布局的超快速工具。简单,漂亮,简约,但有许多有用的功能。可以处理成千上万的顶点和边。甚至比桌面工具还快。

Image from cosmograph’s site

视网膜

[## 视网膜

共享网络可视化的 web 应用程序

ouestware.gitlab.io](https://ouestware.gitlab.io/retina/beta/)

我能够使用视网膜约 10K 顶点,但这个工具的主要功能是出版。在网上的某个地方托管 gexf 或 graphml 文件(他们甚至提供指令)并获得可以共享的图形分析工具。许多最常见的场景不需要使用桌面工具,如节点搜索、节点邻居探索、按属性过滤等。

Graph hosted online loaded in Retina

例如,我在 Github 上找到了哈利·波特人物互动图,现在我可以分享可视化效果

应该只有一个!

原文:https://towardsdatascience.com/large-objects-in-python-classes-165a6f98d840?source=collection_archive---------18-----------------------

Photo by George Hiles on Unsplash

如何在 Python 类中最有效地加载大型模型(和其他对象)

由于开源的机器学习框架,每个人都可以将强大(和大型)的模型集成到数据管道中。这样做的机会带来了大多数数据科学家没有能力应对的挑战。这篇博客文章解决了其中的一个问题:如何在不使计算系统过载的情况下,以集成最先进模型的方式构建代码?

这里有一个具体的例子。想象一下,你的工作是构建一个处理产品评论的 Python 管道。目标是检测那些试图降低你产品分数的虚假评论。您决定采用多步骤方法来实现这一点:

  • 首先,你检查是否有条新评论可用。
  • 第二,你检查他们的评级是否低到足以证明进一步调查的正当性。
  • 第三,机器学习流水线通过计算嵌入并应用分类模型来检查通过两次检查的文本。

所有产品每天都运行这一流程。这是我们最初版本的ReviewClassifier类:

从输出中可以看到,分类器的每个实例都重新加载了复杂的模型。我们假设每次加载一个模型大约需要一分钟。如果每天有 100 个产品有可疑评论,那就已经是 100 分钟的加载时间了!这是你的管道需要做的最重要的事情。

为了改进这一点——并节省 99%的加载时间——我们需要将加载从实例转移到级别。这是我们的下一个版本:

这好得多,但我们可以进一步改进。目前,当您导入类时,分类器会立即加载模型:

from review_pipeline import ReviewClassifier
# Loaded: A Complicated Model

我们不想过早装货。也许我们根本不需要模型。它还会很快搞乱单元测试。

为了改变这一点,当我们计算嵌入时,我们检查模型是否在类级别上加载,如果没有,就这样做。这是我们的最终版本:

现在我们已经实现了我们的目标。模型在第一次需要时被加载,因此可供以后使用。

一旦你意识到这个模式,你会发现许多有用的应用。例如,有些情况下,带有后续本地过滤的单个数据库导出比重复的小查询更适合您的基础设施。对于大型预计算来说也是如此。

尽管这是一种巧妙的模式,但有些替代方案更适合某些用例。如果您应用上面的设计,类对象将保留在内存中,这会导致难以检测的问题。在这些情况下,最好创建一个本地副本(一次),并为每个新的类实例从文件系统重新加载对象。

如果这篇文章对你有所帮助,或者你想补充什么,请在评论或 Twitter 上告诉我。我也很乐意在 LinkedIn 上联系。感谢阅读!

pySpark 中使用隐式数据的大规模工作推荐引擎

原文:https://towardsdatascience.com/large-scale-jobs-recommendation-engine-using-implicit-data-in-pyspark-ccf8df5d910e?source=collection_archive---------9-----------------------

为什么是隐式数据?因为我们作为懒惰的用户,几乎不会为我们在任何*台上做的任何事情提交评分(显性数据),无论是网飞、亚马逊、LinkedIn 等等。
我们所做的,只是看电影(隐含数据),查看产品或点击 LinkedIn 上的工作项目,然后继续前进。

在几乎每一个面向消费者的企业中提供相关的推荐,对于将潜在客户转化为客户是非常重要的。个性化是建立推荐引擎(RE)的关键,我们在网飞、亚马逊、LinkedIn 上看到它,它甚至存在于在线黑市。
这个项目的完整代码在我的 GitHub 档案。

Because you have not built a Recommendation Engine Bruh! 😄 [1]

激发我在 RE 上写这篇博客的是隐式数据的使用。我们已经看到了很多使用显式数据的 RE 案例研究,但是很少有使用隐式特征的例子。让我们先了解一下这两种数据的根本区别:

显式数据:用户明确给出的偏好,它可以是评级、喜欢或不喜欢方面的任何分数。
隐式数据:用户隐式给出的偏好,这些偏好不太明显,如查看、点击、在购物车中添加商品等。

所以,使用隐式数据,你实际上不知道,如果客户点击了一个项目,他们是否真的喜欢它?

让我们解决构建 RE 时处理隐式数据的问题。
我们将本博客主要分为三个部分:

  1. 构建 Rec 引擎的协同过滤算法
  2. 了解协同过滤如何处理隐式数据
  3. 让我们编码:使用 pySpark (MLlib)练习上面两个

1。协同过滤(CF)

如果你已经理解了协同过滤的概念,你可以跳过这一节。

CF 背后的基本思想非常简单。假设你有一个用户“X ”,你想推荐工作给“X ”, CF 将帮助你找到一组用户“N ”,他们的喜好和厌恶与用户“X”相似。一旦计算出这组 N 个用户,我们就可以向用户 x 推荐这组 N 喜欢的作业。

Source: [2]

现在,问题是 CF 如何帮助你找到一组与 X 相似的用户。主要有两种方法来找到“N”个相似用户的组:

  1. 基于记忆的方法:使用余弦相似性的概念并找到 k 个最*的邻居来计算未被用户评级的项目的评级(假设用户‘X’)
  2. 基于模型的方法:使用矩阵分解(SVD)、聚类或深度学习模型(受限波尔兹曼机器)的概念来预测用户评级。

在本帖中,我们将更多地讨论 CF 最常用的方法:

假设你有这种由不同用户给出的电影评级矩阵。在现实世界的例子中,这个矩阵非常稀疏。

Original user-movies(items) ratings matrix [4]

矩阵分解(MF):

Source: [3]

上图中解释的 MF 背后的直觉是使用用户-电影(项目)矩阵的降维,该矩阵由具有 k 个潜在因子(嵌入)的两个小矩阵*似,这两个小矩阵是用户嵌入矩阵和电影嵌入矩阵。

奇异值分解(SVD)就是这样一种降维技术,它在内部执行矩阵分解。

Factorized matrix [4]

现在,一旦生成了用户和电影嵌入矩阵,任何用户(假设为“X”)的用户嵌入向量(任何单行)就与电影嵌入向量相乘,以获得预测的评级值。

评级模型预测(黄色单元格中的 3.25)= 2 个绿色向量(嵌入向量)的点积+ 0.14(电影偏差)+ 0.87(用户偏差)[4]

我们可以对所有用户-电影组合执行此操作,以获得评级的预测值。我们将使用实际评级和相应的预测评级来计算 RMSE 损失。

:在计算 RMSE 时,我们不会考虑实际收视率缺失的预测收视率。

最后,我们稍后将在 pySpark 中实现的最后一件事是交替最小二乘法,它使用梯度下降优化来计算用户和项目嵌入矩阵。

可选:为了了解更多关于 CF 算法的内容,你可以在 Coursera 上观看吴恩达的这个视频:链接(基于模型的方法),另一个视频解释了斯坦福大学数据挖掘课上的基于记忆的方法:链接。对于 excel 中的动手练习:链接和不同类型的 CF: 链接

2.隐式数据协同过滤

以上是一些大剂量的算法,但当数据是等级形式(显式)时,理解 CF 是非常必要的。一旦您理解了 CF 的基本原理,就很容易用隐式数据功能来调整 CF。我们开始吧:

本节中使用的大部分方法都来自本研究论文: 链接

隐式反馈的数值描述了行动的频率,例如,你点击数据科学职位的次数,你看网飞电视连续剧的时间,你听一首歌的次数等。我们利用用户给出的这些隐含数字来获取用户偏好或不偏好的置信度。用户‘u’对项目‘I’的偏好( pui )由以下等式捕获:

其中'瑞'是该项目的记录值(例如,你听一首歌的次数)。因此,如果记录的值大于 0,则首选项为 1,如果它等于 0,则首选项为 0。

现在,假设你只听了一首歌一次,这并不意味着你喜欢它,它可能在你的 YouTube 上处于自动播放模式。同样,如果记录值为零,并不意味着你不喜欢这首歌,这可能意味着你从来不知道这首歌的存在,或者你还没有发现它。因此,为了捕捉这种偏好关系,我们需要明确信心的概念:

总的来说,随着“ rui ”的增长,我们有更强的迹象表明用户确实喜欢这个项目。【Cui】,衡量我们对观察g【pui】的信心。我们可以注意到,即使对于“rui”为 0 的用户项目对(表示对该项目没有偏好),我们也有相关的最小置信度 1。并且“pui”等于 1 的置信度随着积极偏好证据的增加而增加。

增加速率由常量调谐参数α控制。

偏好被假设为内积:pui =(转置)U. X

现在,我们将计算两个矩阵:用户嵌入矩阵(U’)和项目嵌入矩阵(X’),就像我们在如上所述的协同过滤技术中所做的那样,与我们在显式数据的情况下所做的相比,只有两个区别:

  1. 我们需要考虑不同的置信水*
  2. 优化应考虑所有可能的用户-项目对,而不仅仅是那些与观察数据相对应的用户-项目对

嵌入/因子通过最小化以下成本函数来计算:

[5]

这可以通过使用 ALS 优化过程来*似我们的偏好矩阵并基于偏好向用户提供推荐来解决。

3。PySpark 代码构建大规模作业 Rec 引擎

最后,是时候把我们到目前为止学到的关于协同过滤或推荐引擎的知识进行编码了。

让我们编造一些数据。

job posts clicks by different users (job_clicks.csv)

jobs category like IT, Finance, HR etc (jobs.csv)

因此,第一步是将上面显示的数据加载到 rdd 中并处理它。接下来,为了建模的目的,我们需要将它分成训练、验证和测试集。

Data load and splitting

将数据分成三组后,使用训练和验证组来训练模型并调整超参数(或使用交叉值)。

[7]

观察上面代码中用于交替最小二乘法(ALS.trainImplicit function)调整的 4 个超参数:

  1. 秩:表示嵌入矩阵的宽度/列
  2. iters(迭代):表示我们在 ALS 过程中振荡多少次来生成嵌入矩阵
  3. alpha:与置信度等式中的记录规模(用户执行任何动作:观看电影的次数)相关
  4. reguls (lambda):是防止过度拟合的正则化参数

最后,您可以使用最佳超参数集来训练模型,并使用它来预测用户偏好的推荐或置信度,以显示前 N 个推荐。

下面是加载和处理数据、建立模型以及为所有用户预测推荐的代码。

要获得本文中使用的数据集的完整项目演示,请查看 GitHub 链接。

下一步可能是将该模型放入云中,并根据您的需求实时显示建议。此外,还有其他一些很酷的库,如用于构建 Rec 引擎的“implicit ”,但其基本概念与我们在前两节中讨论的相同。

此外,请分享您的宝贵意见或反馈,让它变得更好,更具可扩展性。我有另一个关于使用 Docker 容器构建和部署模型的博客,所以如果你喜欢缩放你的模型,请查看一下。

参考文献

[1] RE Image: link

【2】https://www.youtube.com/watch?v=h9gpufJFF-0&t = 23s

[3]https://www . EDX . org/course/big-data-analysis-Apache-spark-UC-berkeleyx-cs110 x

【4】https://towards data science . com/collaborative-filtering-and-embedding-part-1-63 b 00 b 9739 ce

http://yifanhu.net/PUB/cf.pdf

[6]https://databricks . com/session/building-a-implicit-recommendation-engine-with-spark

【7】https://github . com/Google cloud platform/spark-re commendation-engine/blob/master/py spark/find _ model _ collaborative . py

基于线性回归和深度学习的 Lasso 正则化

原文:https://towardsdatascience.com/lasso-regularization-on-linear-regression-and-other-models-70f65efda40c?source=collection_archive---------28-----------------------

对套索惩罚的影响及其对线性回归的影响的数学分析,包括对深度学习的可能扩展

介绍

曲线拟合-欠拟合和过拟合

正如我在上一篇文章中所讨论的,当问题不适当时,就会出现“曲线拟合”的问题。不足通常不是一个大问题,因为我们可以通过获取/设计新特性来扩展特性集。然而,过度拟合并不容易处理。

回归中的最佳子集选择

考虑一个有 p 个预测变量的线性回归。假设整个数据集用于训练。众所周知,训练集 R 不会随着特征的增加而减少。因此,R 不是一个很好的拟合优度的度量。调整后的-R,马洛的 Cₚ,AIC,BIC 等。是用来衡量拟合优度的。然而,在添加/移除预测变量时,不存在关于这些测量值的变化的先验知识。因此,可能需要所有 2ᵖ-1 独特模型来判断为结果变量建模所需的特征的“最佳子集”。然而,这在计算上非常昂贵。这就需要一种适当的方法来减少变量,而不需要建立指数级的大量模型。套索惩罚有助于部分实现这一目标。

制定

线性回归和正规方程

Regression equation

Linear regression estimated on sample

OLS solution — same as MLE under certain conditions

Normal equation

我们观察到,如果协方差矩阵是不可逆的,则 OLS 解不存在(可能不是唯一的)。

套索公式

Regression equation

Lasso solution estimated on sample

Lasso solution

对于这种最小化,不存在解析解。梯度下降也不能保证收敛于这个损失函数,即使它是凸的。需要另一个公式来计算解决这个问题。

解决办法

正交协方差的软阈值处理

Equations copied from my personal notes

Assumption to simplify the analysis

Separating out the dimensions

Soft thresholding

可以在每个维度上单独执行软阈值处理。这种更新将收敛到最佳β,因为它们是独立的。这种想法类似于轮廓似然 —关键参数的估计是通过描绘出(固定)噪声参数并最大化似然(假设为凸的)来完成的,然后通过将关键参数固定在其计算出的最佳值来估计噪声参数:这在参数独立时有效。

这种一次更新一个参数的方法称为坐标下降法。

坐标下降:一般情况

对于没有正交设计的一般情况,坐标下降可总结如下:

  • 从猜测套索解开始,设置收敛参数ϵ
  • 迭代 I,从 1 到 max_iter:
  • —从 1 到 p 迭代 j:
  • — —通过设置βⱼ = 0 来计算残差
  • — —回归第 j 个预测因子上的残差,得到第 j 个β的 OLS 解
  • — —对 OLS 解应用软阈值,获得第 j 个β的套索解
  • — —检查收敛:β < ϵ?
  • Return final β. Did β converge in max_iter iterations?

Coordinate descent is guaranteed to converge in one iteration for orthogonal design. It is not guaranteed to converge in 1 iteration if the design matrix is not orthogonal, but it will converge in finite number of iterations.

Geometric interpretation

Dual form of optimization

Lasso loss

Dual form of optimization

Contour plot for lasso. Image credits: https://stats.stackexchange.com/questions/30456/geometric-interpretation-of-penalized-linear-regression

The blue squares correspond to |β|₁ ≤ s for different s, where |β|₁ = constant along a square. Increasing λ decreases the size of the square. The red ellipses correspond to different distinct values of (y-xβ)₂² where (y-xβ)₂² = constant along an ellipse. For a fixed λ the value of s is fixed: this corresponds to one of the blue squares.

The minimum value of (y-xβ)₂² in unconstrained case occurs at the center of the ellipse. However, under the constrained case of |β|₁ ≤ s the solution will be displaced towards the origin.

The unique lasso solution is located at the point where these two ‘curves’ touch. Since the curve |β|₁ ≤ s is non-differentiable at few points the lasso solution for few βᵢs can be zero. On increasing λ (decreasing s) these βᵢs remain 0; other βᵢs tend to 0. This causes sparsity in the coefficients of lasso.

Extension to deep learning

Deep learning networks inevitably have fully-connected layers. These layers perform linear transformation on the input and apply an activation on the transformed variables. When the transformed outputs are small in magnitude (typically less than 1) the non-linearity can be ignored. With lasso penalty on the weights the estimation can be viewed in the same way as a linear regression with lasso penalty. The geometric interpretation suggests that for λ > λ₁中更新的 L1 范数(最小λ,其中只有一个β估计为 0)我们将至少有一个权重= 0。这造成了权重的稀疏性。这一论点也适用于具有较大转换输入值的非线性情况。

结论

套索惩罚通过将一些系数驱动到 0 来创建系数的稀疏性。这适用于线性回归和深度神经网络中的全连接层。因此,对于合适的λ值,lasso 惩罚可以降低深度学习模型的复杂性。然而,它不是所有问题的解决方案。

如果基础模型是线性的(Y = Xβ + ϵ),非零λ会导致套索解(E(βˡᵃˢˢᵒ)中的偏差≠ β,但估计量的方差低于最大似然法),因此,即使对于简单的情况,它也不能同时实现估计和选择的一致性。尽管有这个缺点,但它是对有限样本过度拟合的一个好的解决方案,特别是在具有大量参数的深度神经网络中,这些参数往往会过度拟合。

潜在狄利克雷分配

原文:https://towardsdatascience.com/latent-dirichlet-allocation-15800c852699?source=collection_archive---------14-----------------------

潜在狄利克雷分配 (LDA)是由零件组成的复合物集合的“生成概率模型”。就主题建模而言,组合是文档,部分是单词和/或短语(n 元语法)。但是你可以将 LDA 应用于 DNA 和核苷酸,比萨饼和配料,分子和原子,雇员和技能,或者键盘和面包屑。

Source

潜在狄利克雷分配(LDA)是一种自动发现这些文档包含的主题的技术。

假设你有下面这组句子:

根据上面的句子,LDA 可能会将红色单词归类到主题 F 下,我们可以将其标记为“食物”。类似地,蓝色单词可能被归类到一个单独的主题 P 下,我们可以将其标记为“宠物”。LDA 将每个主题定义为一个单词包,你必须按照你认为合适的方式给主题贴上标签。

LDA 在单词级别定义主题有两个好处:

1)我们可以通过字数来推断每个句子的内容传播:

第一句 : 100%话题 F
第二句 : 100%话题 P
第三句 : 33%话题 P 和 67%话题 F

2)我们可以推导出每个单词在给定主题中所占的比例。例如,主题 F 可能包含以下比例的单词:40%吃,40%鱼,20%蔬菜,…

LDA 分三步实现上述结果。

为了说明这些步骤,假设您现在正在文档中发现主题,而不是句子。假设您有两个包含以下单词的文档:

第一步
你告诉算法你认为有多少个题目。您可以使用可靠的估计(例如之前分析的结果),也可以简单地试错。在尝试不同的估计时,你可以选择一个产生你想要的可解释性水*的话题,或者一个产生最高统计确定性(即对数可能性)的话题。在上面的例子中,主题的数量可以通过目测文档来推断。

步骤 2
算法会将每个单词分配给一个临时主题。主题分配是临时的,因为它们将在步骤 3 中更新。临时主题以半随机的方式(确切地说,根据狄利克雷分布)被分配给每个单词。这也意味着,如果一个词出现两次,每个词可能被分配到不同的主题。注意,在分析实际文档时,功能词(例如“the”、“and”、“my”)被移除,并且不被分配给任何主题。

步骤 3(迭代)
该算法将检查并更新主题分配,遍历每个文档中的每个单词。对于每个单词,其主题分配基于两个标准进行更新:

  • 这个词在各种话题中有多普遍?
  • 文档中的主题有多普遍?

为了理解这两个标准是如何工作的,假设我们现在正在检查文档 Y 中单词“fish”的主题分配:

  • 这个词在各种话题中有多普遍?由于两个文档中的“鱼”字包括几乎一半的剩余主题 F 字,但是 0%的剩余主题 P 字,所以随机挑选的“鱼”字更可能是关于主题 F 的

  • 文档中的主题有多普遍?因为文档 Y 中的单词以 50:50 的比例分配给主题 F 和主题 P,所以剩余的“鱼”单词似乎同样可能与任一主题有关。

权衡两个标准得出的结论,我们将把 Doc Y 的“鱼”字分配给 Topic f。Doc Y 可能是一个关于喂小猫什么的文档。

对每个文档中的每个单词重复检查主题分配的过程,在整个文档集合中循环多次。这种迭代更新是 LDA 的关键特征,它生成具有连贯主题的最终解决方案。

潜在狄利克雷分配(LDA)初学者指南

原文:https://towardsdatascience.com/latent-dirichlet-allocation-lda-9d1cd064ffa2?source=collection_archive---------0-----------------------

发现抽象话题又名 话题建模 的统计模型。

Photo by Giulia Bertelli on Unsplash

什么是主题建模?

主题建模是一种对文档进行无监督 分类的方法,类似于对数字数据进行聚类,即使我们不确定我们在寻找什么,它也会找到一些自然的项目(主题)组。

一个文档可以是多个主题的一部分,有点像模糊聚类(软聚类)中每个数据点属于多个聚类。

为什么要主题建模?

主题建模提供了自动组织、理解、搜索和总结大型电子档案的方法。
它可以在以下方面提供帮助:

  • 发现收藏中隐藏的主题。
  • 将文档分类到发现的主题中。
  • 使用分类来组织/总结/搜索文档。

例如,假设一个文档属于主题食品、狗健康。因此,如果用户查询“狗粮”,他们可能会发现上述文档相关,因为它涵盖了这些主题(以及其他主题)。我们能够计算出它与查询的相关性,甚至不需要浏览整个文档。

因此,通过注释文档,基于建模方法预测的主题,我们能够优化我们的搜索过程。

皱胃向左移

它是最流行的主题建模方法之一。每个文档由各种单词组成,每个主题也有属于它的各种单词。LDA 的目的是根据文档中的单词找到文档所属的主题。很困惑吗?这里有一个例子来引导你。

模型定义

Each document is a collection of words.

我们有 5 个文档,每个文档都包含前面列出的单词(按出现频率排序)。

我们要搞清楚的是不同题目中的单词,如下表所示。表格中的每一行代表一个不同的主题,每一列代表语料库中的一个不同的单词。每个单元格包含单词(列)属于主题(行)的概率。

Each topic contains a score for all the words in the corpus.

寻找主题的代表词

  • 我们可以根据单词的概率得分对单词进行排序。
    从每一个题目中选出最上面的 x 个单词来代表题目。如果 x = 10,我们将根据得分对 topic1 中的所有单词进行排序,并取前 10 个单词来代表该主题。这一步可能并不总是必要的,因为如果语料库很小,我们可以按照分数来存储所有的单词。
  • 或者,我们可以在分数上设置一个阈值。主题中分数高于阈值的所有单词可以按照它们的分数顺序存储为其代表。

Photo by Anusha Barwa on Unsplash

假设我们有两个主题,可以分类为与猫相关的与狗相关的。一个话题对每个单词都有概率,所以像牛奶小猫这样的单词,在猫 _ 相关话题中的概率会比在狗 _ 相关话题中的概率高。同样地,与狗相关的话题中出现小狗吠叫骨头等词语的概率也很高。

如果我们有一个包含以下句子的文档:

喜欢骨头上的并捡棍子。
小狗
“都喜欢对吠叫。”

我们可以很容易地说它属于话题狗 _ 相关,因为它包含了诸如狗、骨头、小狗吠叫等词语。尽管它包含属于主题 CAT_related 的单词 milk ,但该文档属于 DOG_related ,因为更多的单词与之匹配。

假设:

  • 每个文档只是一个单词的集合或一个“单词包”。因此,单词的顺序和单词(主语、宾语、动词……)的语法角色在模型中不被视为
  • 像 am/is/are/of/a/the/but/…这样的词不携带任何关于“主题”的信息,因此可以作为预处理步骤从文档中删除。事实上,我们可以 消除至少在文档的%80 ~ %90 中出现的单词,而不会丢失任何信息。例如,如果我们的语料库只包含医学文档,则像人类、身体、健康等词可能出现在大多数文档中,因此可以被移除,因为它们没有添加任何使文档突出的特定信息。
  • 我们预先知道我们想要多少主题。k‘是预先决定的。
  • 除了正在讨论的当前单词之外的所有主题分配都是正确的,然后使用我们的文档生成模型更新当前单词的分配

LDA 是如何工作的?

LDA 有两个部分:

  • 这个字,属于一个文档 ,这个我们已经知道了。
  • 属于主题 的 个单词或者单词属于一个主题的概率,我们需要计算。

找到后者的算法

  • 浏览每个文档,并随机将文档中的每个单词分配到 k 主题中的一个(事先选择了 k )。
  • 对于每个文档 d ,遍历每个单词 w 并计算:
  1. p(主题 t |文档 d ) :文档 d 中分配给主题 t 的文字比例试图捕捉给定文档 d 中有多少单词属于主题 t 。排除当前单词。
    如果来自 d 的很多字属于 t 的话,字 w 属于 t 的可能性更大。
    (中的#字数 dt+alpha/中的#字数 d 带任意话题+ k * alpha )
  2. p(wordw| topict):分配给 topic t 的任务占所有来自 word w 的文档的比例。试图捕获多少文档在主题 t 中,因为单词 w 。LDA 将文档表示为主题的混合物。同样,一个题目也是单词的混合体。如果一个单词出现在主题中的概率很高,那么所有带有 w 的文档也将与 t 有更强的关联。类似地,如果 w 不太可能出现在 t 中,则包含 w 的文档出现在 t、中的概率很低,因为 d 中的其余单词将属于其他主题,因此 d 出现在这些主题中的概率更高。所以即使 w 被添加到 t 中,也不会给 t 带来很多这样的文档。
  • 更新单词 w 属于主题 t 的概率,如下所示
p(word w with topic t) = p(topic t | document d) * p(word w | topic t)

外行的例子

假设你有各种各样的照片(文档)和标题(文字)。您希望在画廊中展示这些照片,因此您决定根据不同的主题(主题)对照片进行分类,并根据这些主题在画廊中创建不同的部分。

Photo by Soragrit Wongsa on Unsplash

你决定在你的相册中创建 k=2 个部分——自然与城市。自然,分类不是很清楚,因为一些城市的照片有树和花,而自然的照片可能有一些建筑。首先,你决定将只有自然或城市元素的照片归入各自的类别,而你随机分配其余的。

你会注意到《自然》杂志上的许多照片标题中都有“T2 树”这个词。所以你断定这个词和 topi c 自然一定是密切相关的。

接下来,你选择单词 building 并检查有多少张照片出现在 nature 中,因为它们的标题中有单词 building 。你不会发现很多人现在不太确定建筑属于主题自然并更强烈地将其与主题城市联系起来。

然后你选择一张标题为“树在建筑物前,车后”的照片,你会发现它现在属于自然类别。
然后你选择文字 ,并计算第一概率 p(题目 t |文件 d ): 标题中的其他文字是,大多数带有标题的照片都是在
现在第二个概率 p(单词 w |题目 t ) :我们知道自然界很多照片里面都有树木这个单词。所以你在这里得到高分。
你通过将两者相乘来更新属于自然的概率。你在主题自然中得到的的值比之前低,因为现在你已经看到在同一个标题中建筑 / 汽车等词,暗示着城市中也可以找到树。
出于同样的原因,当你更新主题城市归属的概率时,你会注意到它会比以前大。

在对所有照片和每个主题进行多次迭代后,你将获得每个主题的每个单词的准确分数。你的猜测会越来越好,因为你会从上下文中得出结论,建筑物、人行道、地铁等词一起出现,因此肯定属于同一个主题,我们可以很容易地猜到是城市
像山、田野、海滩这样的词可能不会在很多标题中同时出现,但它们确实经常在没有城市词的情况下出现,因此自然的得分较高。
而像树、花、狗、天空这样的词在两个主题中出现的概率几乎相同。

至于照片,你看到它有 1 个词(*均概率)来自自然类别,2 个词(高概率)来自城市,你得出结论,它属于城市比属于自然更强烈,因此你决定将它添加到城市。

边注

LDA 的应用不需要局限于自然语言处理。我最*完成了一篇论文,其中我们使用 LDA(以及神经网络)来提取图像的特定场景上下文。如果你有兴趣了解更多,请留下评论或留言。

参考

  • 如果你正在寻找 LDA 的实现,这里有一篇关于数据科学的惊人的文章,它做得很好!
  • 参见 Edwin Chen 博客中的“一个外行的例子”以获得更多关于 LDA 的直觉。

我认为你会喜欢的其他文章😄

  • NLP 模型评估—最新基准
  • 理解深度学习中的注意力
  • 变形金刚——谷歌的 BERT 和 OpenAI 的 GPT 等模型的基本模块。

我很高兴你坚持到了这篇文章的结尾。🎉我希望你的阅读体验和我写这篇文章时一样丰富。💖**

请点击这里查看我的其他文章。

如果你想联系我,我的选择是推特。

2019 年 CVPR 最新计算机视觉趋势

原文:https://towardsdatascience.com/latest-computer-vision-trends-from-cvpr-2019-c07806dd570b?source=collection_archive---------3-----------------------

用数据做酷事!

2019 年 IEEE 计算机视觉和模式识别大会(CVPR)于今年 6 月 16 日至 6 月 20 日举行。 CVPR 是计算机视觉领域全球三大学术会议之一(与 ICCV 和 ECCV 并列)。今年共有 1300 篇论文从创纪录的 5165 篇提交中被接受(25.2%的接受率)。

CVPR 带来了计算机视觉领域的顶尖人才,每年都有许多令人印象深刻的论文。

我从 CVPR 拿了被接受的论文,并对它们做了分析,以了解论文标题中的主要研究领域和常见关键词。这可以显示出研究的进展方向。

底层数据和代码可以在我的 Github 上找到。随意拉这个,加入你自己的旋转。

CVPR 给每篇论文指定一个主要的主题领域。被接受的论文按学科领域分列如下:

不奇怪,大部分研究都集中在深度学习上(现在不都是深度学习吗!),检测和分类以及人脸/手势/姿势。这种分类非常笼统,并没有给出很好的见解。所以接下来我从接受的论文中提取了所有的单词,并用一个计数器来计算它们的频率。最常见的 25 个关键词如下:

现在这个更有趣了。最受欢迎的研究领域是检测、分割、3D 和对抗训练。它也显示了无监督学习方法的研究日益增长。

最后我还画了云这个词。

你可以使用我的 Github 按主题提取热门论文,如下所示

Papers with research on “face”

我经营一家机器学习咨询公司。点击查看我们的网站。我喜欢从事计算机视觉项目。如果你有我们可以合作的想法,请随时通过网站或电子邮件联系 info@deeplearninganalytics.org。

接下来,我在博客中选择了 5 篇来自关键研究领域的有趣论文。请注意,我挑选了最吸引我的论文。

  1. 通过看冻人了解感动人的深度

人类视觉系统有一种非凡的能力,可以从 2D 投影中理解我们的 3D 世界。即使在具有多个移动对象的复杂环境中,人们也能够保持对对象的几何形状和深度排序的可行解释。在过去的几年中,已经使用相机图像在深度估计方面做了大量的工作,但是在许多情况下,鲁棒的重建仍然是困难的。当相机和场景中的对象都自由移动时,会出现一个特别具有挑战性的情况。这混淆了基于三角测量的传统 3D 重建算法。

要了解更多关于深度图像和估计场景深度的信息,请查看这个博客。

本文通过在相机和主体都自由移动的场景上建立深度学习模型来解决这一问题。见下图 gif:

Depth estimation on moving people

为了创建这样一个模型,我们需要移动摄像机捕捉的自然场景的视频序列,以及每幅图像的精确深度图。创建这样一个数据集将是一个挑战。为了克服这一点,该论文非常创新地使用了现有的数据集——YouTube 视频,其中人们模仿人体模特摆出各种各样的自然姿势,同时手持摄像机巡视现场。因为场景是静止的,只有相机在移动,所以可以使用三角测量技术来构建精确的深度图。这篇论文非常有趣。它解决了一个复杂的问题,并在为其创建数据集方面极具创造性。

经过训练的模型在移动摄像机和人的互联网视频剪辑上的性能比以前的任何研究都好得多。见下文:

Model comparison through the paper

你可以在这里阅读全文。

2。BubbleNets:通过深度排序帧学习选择视频对象分割中的引导帧

我看过几篇关于视频对象分割的论文(VOS)。这是在第一帧提供单个注释的情况下分割视频中的对象的任务。这在视频理解中有应用,并且在过去的一年中有很多研究。

视频中对象的位置和外观可能会逐帧发生显著变化,并且该论文发现,使用不同的帧进行注释会显著改变性能,如下所示。

Bubblenets video demo

BubbleNets 迭代地比较和交换相邻的视频帧,直到具有最大预测性能的帧排名最高,此时,选择该帧供用户注释和用于视频对象分割。

BubbleNet first frame selection

该模型的视频描述在 youtube 上分享,源代码在 Github 上开源。

BubbleNets 模型用于预测两个帧之间的相对性能差异。相对性能通过区域相似性和轮廓准确度的组合来测量。

它将 2 个要比较的帧和 3 个参考帧作为输入。然后,它通过 ResNet50 和完全连接的层来输出表示 2 帧比较的单个数字 f。为了执行冒泡排序,我们从前 2 帧开始,并对它们进行比较。如果 BubbleNet 预测帧 1 比帧 2 具有更好的性能,则交换帧的顺序,并将下一帧与迄今为止最好的帧进行比较。在整个视频序列的处理结束时,最好的帧保留下来。下图显示了 BubbleNets 架构和冒泡排序过程。

总体而言,作者表明,在不改变底层分割算法的情况下,改变标注帧的选择方式,可以使 DAVIS 基准数据集的性能提高 11%。

Bubblenets architecture

3.单幅 RGB 图像的三维手形和姿态估计

三维手形和姿态估计是最*非常活跃的研究领域。这在虚拟现实和机器人技术中有应用。本文使用单目 RGB 图像来创建一个 3D 手姿态和手周围的 3D 网格,如下所示。

3D hand mesh from single image

本文使用图形细胞神经网络重建手的全三维网格。这里很好的介绍了图形 CNN 这个话题。为了训练网络,作者创建了一个包含地面真实 3D 网格和 3D 姿态的大规模合成数据集。在真实世界的 RGB 图像上手动注释地面真实 3D 手网格是极其费力和耗时的。然而,在合成数据集上训练的模型通常在真实数据集上产生不令人满意的估计结果,因为它们之间存在领域差距。为了解决这个问题,作者提出了一种新的弱监督方法,通过利用深度图作为 3D 网格生成的弱监督,因为在收集真实世界训练数据时,深度图可以很容易地被 RGB-D 相机捕获。本文在数据集、训练过程等方面有丰富的细节。如果这是你感兴趣的领域,请通读。

对我来说,一个有趣的学习是 CNN 用于网格生成的图形架构。这个网络的输入是来自 RGB 图像的潜在向量。它经过 2 个完全连接的图层,在粗略的图形中输出 80x64 的要素。然后,它通过层层上采样和图形 CNN 来输出更丰富的细节,最终输出 1280 个顶点。

3D hand mesh model architecture

4。推理-RCNN:将自适应全局推理统一到大规模目标检测中

Reasoning RCNN output

随着许多常见的计算机视觉应用,对象检测已经获得了很大的普及。快速 RCNN 是一种常用的目标检测模型。要了解更多关于物体检测和更快的 RCNN 检查这个博客。然而,当检测类别的数量很少时(少于 100),对象检测是最成功的。本文研究了具有数千个类别的大规模目标检测问题,该问题由于长尾数据分布、严重遮挡和类别歧义性而面临严峻挑战。

推理-RCNN 通过构建一个知识图来编码人类常识知识来实现这一点。什么是知识图?知识图对对象之间的信息进行编码,如空间关系(上,*),主语-动词-宾语(例如。驾驶、跑步)关系以及属性相似性,如颜色、尺寸、材料。如下所示,彼此具有视觉关系的类别彼此更接*。

Knowledge Graph

就架构而言,它在标准对象检测器(如更快的 RCNN)之上堆叠了一个推理框架。收集先前分类器的权重以生成所有类别的全局语义池,该语义池被馈送到自适应全局推理模块。增强的类别上下文(即推理模块的输出)通过软映射机制被映射回区域提议。最后,每个区域的增强特征用于以端到端的方式提高分类和定位的性能。下图显示了模型架构。请参考论文更详细的了解他们的架构。

该模型在 3 个主要数据集上进行训练和评估——Visual Gnome(3000 个类别)、ADE (445 个类别)和 COCO (80 个类别)。该模型能够在地图得分上在视觉侏儒上获得 16%的提升,在阿德上获得 37%的提升,在可可上获得 15%的提升。

培训代码将在此链接处开源。尚不可用。

5.深度学习零拍人脸反欺骗

在过去的几年中,面部检测已经取得了很大的进步,现在面部检测和识别系统在许多应用中普遍使用。事实上,用 8 行代码就能建立一个检测人脸、识别人脸并理解其情绪的系统是可能的。见博客这里。

然而,也存在人脸检测被欺骗以获得非法访问的持续风险。人脸反欺骗旨在防止人脸识别系统将伪造的人脸识别为真正的用户。虽然开发了先进的人脸反欺骗方法,但是新类型的欺骗攻击也正在被创建,并成为对所有现有系统的威胁。介绍了检测未知欺骗攻击的概念,即零枪击人脸反欺骗(ZSFA)。之前的 ZSFA 著作只研究了 1- 2 种类型的欺骗攻击,比如 print/replay,限制了对这个问题的洞察。这项工作调查了 ZSFA 问题的范围广泛的 13 种类型的欺骗攻击,包括打印,重放,三维面具,等等。下图显示了不同类型的欺骗攻击。

面部欺骗可以包括各种形式,如打印(打印面部照片)、重放视频、3D 面具、带有眼睛剪切的面部照片、化妆、透明面具等。该论文提出使用深度树网络以无监督的方式从欺骗图片中学习语义嵌入。这里的嵌入可以模拟像人类凝视这样的事情。它创建了一个欺骗图像的数据集来学习这些嵌入。在测试过程中,未知攻击被投射到嵌入中,以找到最接*欺骗检测的属性。

阅读论文以获得关于深度树网络的模型架构和训练它的过程的更多细节。该论文能够创建嵌入,将具有各种类型的欺骗的真实面部(真实面部)分离出来。见下面的 t-SNE 图

这篇论文太棒了。解决实际问题的有希望的研究。

结论

看到计算机视觉的所有最新研究令人着迷。这里分享的 5 篇论文只是冰山一角。我希望你会用我的 Github 来整理文件,选出你感兴趣的。

我对计算机视觉和深度学习充满热情。我有自己的深度学习咨询公司,喜欢研究有趣的问题。我已经帮助许多初创公司部署了基于人工智能的创新解决方案。请到 http://deeplearninganalytics.org/.来看看我们吧

你也可以在https://medium.com/@priya.dwivedi看到我的其他作品

如果你有一个我们可以合作的项目,请通过我的网站或 info@deeplearninganalytics.org 联系我

参考文献:

  • CVPR
  • 博客中使用的图片是从报纸上借来的

利用有限数据进行 Kaggle 图像分类的最新成功技术

原文:https://towardsdatascience.com/latest-winning-techniques-for-kaggle-image-classification-with-limited-data-5259e7736327?source=collection_archive---------5-----------------------

关于如何防止模型在小数据集上过度拟合但仍能进行准确分类的教程

http://www.dakanarts.com/13-black-white/

在本文中,我将介绍我在课堂卡格尔挑战中使用的方法。我花了大约两周的时间进行挑战,最终提交分数为 0.97115 ,在最终排行榜上名列第二。我从借用的这篇文章开始,我也推荐这篇文章。

挑战攻略

提出的挑战是一个自然图像分类任务,有 13。这项挑战的第一个困难是可用数据的稀缺:只有 3 859 张图像用于训练。挑战的规则是在训练中不使用外部数据。在数据很少的情况下,模型将更容易过度拟合,而不学习概括。

此外,由于这些图像处于灰度,它们包含的信息比 ImageNet 数据集等彩色图像少,因此彩色图像上的预训练模型不能直接应用于此任务。在进一步检查数据集时,许多类包含视觉上非常相似或包含相同元素的图像。混淆此类类别时,模型将失去准确性。

Some examples of images to classify

数据处理

首先,我们数据集中的图像并不都具有相同的尺寸,所以我们在将图像输入到模型之前,调整了所有图像的尺寸。一半以上的训练图像的尺寸为 256 x 256,因此我们将其他图像的尺寸调整或裁剪到这个尺寸。

我们还将应用规范化。最初,图像被表示为像素值范围从 0 到 255 的张量。我们简单地将每个值除以 255,以重新调整并获得神经网络首选的 0 到 1 之间的值。此外,我们将对比度拉伸应用于所有图像以增强图像。这将有助于模型更清楚地“看到”图像中的细节。

这些类也是不*衡的,这意味着每个类之间的数据量不相等。这将使模型或多或少地偏向某些类。为了解决这个问题,我们人为地添加更多的图像,使得每个类都有与最大类一样多的图像。为了对小班进行重采样,我们在图像中随机裁剪一个区域来创建一个新样本。这是基于这样的假设,即裁剪后的图像将包含作为该类特征的相同元素。

最后,随着深度网络在大量训练数据的情况下表现和概括得更好,我们执行了数据增强。我们的目标是人为地创造出包含同类特征的新图像。为此,我使用的技术可以总结如下:

在开始训练之前,我们将数据集分成训练集(80%)和验证集(20%)。除了仅在训练集上使用的图像增强之外,我们在两个集上都应用了上面讨论的所有处理技术。

迁移学习

因为我们的数据集包含的图像与 ImageNet 中的图像相似,所以我们将从一个已经在 ImageNet 上经过预训练的 CNN 模型开始。我们的想法是冻结预训练模型的较低层,这些模型可以捕捉通用特征,同时针对我们的特定领域对较高层进行微调。我们还重新定义了最后一层来输出 13 个值,每个类一个。

ImageNet dataset samples

PyTorch 提供了几种不同架构的预训练模型。其中, ResNet18 是我采用的架构,因为在运行了 5 个时期的各种架构后,它在对我们的数据进行训练时给出了最佳的验证准确性。在对不同数量的冷冻层进行实验后,发现 7 是最好的。我还使用了 SGD 优化器权重衰减来阻止过度拟合。

学习率调度

为了进一步改善结果并使模型收敛到全局最小值,我们希望调整学习率。我选择使用循环学习率调度,而不是通过实验来确定最佳学习率。这种方法使得学习速率循环变化,从而使模型能够收敛和逃离几个局部极小值。它还消除了“手动”寻找最佳学习率的需要。

快照集成

集成方法在提高模型整体性能方面非常强大。然而,为集成学习分别训练几个不同的模型在计算上也是昂贵的。这就是我选择使用快照集合和循环 LR 调度的原因。

快照集合在训练期间定期保存模型的参数。想法是在循环 LR 调度期间,模型收敛到不同的局部最小值。因此,通过在不同的局部最小值保存模型参数,我们获得了一组模型,这些模型可以为我们的预测提供不同的见解。这使得我们可以在一个单一训练周期中集合一群模型。

https://arxiv.org/abs/1704.00109

对于每个图像,我们连接每个“快照”模型的分类概率预测以形成新的数据点。这个新数据然后被输入到一个 XGBoost 模型中,根据快照模型给出一个预测。

子类决策

在检查单个模型的验证集上的混淆矩阵时,我们发现它经常将一个类与相同的另一个类混淆。事实上,我们发现的三个子类经常被混淆在一起:

  • 【房间】:卧室、厨房、客厅、办公室
  • “自然”:海岸、森林、山脉、野外、公路
  • “城市”:城市、街道、高楼

此外,该模型已经非常善于区分这些子类(并找到郊区)。要获得良好的性能,剩下的就是让模型准确地识别子类中的分类。

为此,我们使用与之前相同的方法,在每个子类上训练三个新的独立模型。有些类的训练数据很少,所以我们增加数据扩充量。我们还发现了针对每个子类调整的新参数。

在预测过程中,我们首先使用在整个数据集上训练的模型。然后,对于得到的每个预测,如果类概率低于某个阈值,我们取相关子类模型预测的类来代替。

抗锯齿

大多数现代卷积网络,如 ResNet18,都不是移位不变的。网络输出可能会随着输入的微小偏移或转换而发生剧烈变化。这是因为卷积网络中的跨步操作忽略了奈奎斯特采样定理和混叠,从而破坏了移位等方差。****

我决定应用最*于 2019 年 4 月发表的论文中提出的反走样方法。这是通过在网络的卷积层之后简单地添加“模糊池”层来实现的,即模糊滤波器和子采样层。这种方法已被证明改善了图像的不同偏移之间的分类一致性,并且由于更好的概括而具有更高的分类准确度。

https://arxiv.org/abs/1904.11486

我使用预训练的抗锯齿 ResNet18 模型来微调挑战的数据集。通过反走样,我希望通过将模型推广到图像*移和移动来克服由于数据匮乏而导致的过度拟合。

如果你想更多地了解这种反走样方法,我在这里更详细地解释了“让卷积网络再次保持*移不变”这篇文章:

** [## 使卷积网络再次保持*移不变

现代卷积网络有什么问题,如何修复?如果你使用 CNN,你可能想读这个。

towardsdatascience.com](/https-towardsdatascience-com-making-convolutional-networks-shift-invariant-again-f16acca06df2)

结果摘要

所用的方法可总结如下:

对 ResNet18 模型进行 5 个时期的数据微调,除了调整大小之外不进行任何处理,已经给出了 0.91442 的测试精度。这揭示了迁移学习的显著效率——用很少的数据和计算,该模型已经可以在相关任务上表现出良好的性能。

加上数据扩充和 10 个历元的较长训练,我们得到的测试精度为 0.93076 。这证实了拥有大型训练数据集和增强技术可扩展性的重要性。

增加类*衡学习率调度,测试精度上升到 0.94230 。此外,混淆矩阵表明,*衡后,该模型以更高的精度预测代表性不足的类别。这也说明了学习率是模型收敛的一个重要参数。

然后,通过在所有数据上训练的模型上的快照集合,测试精度提高到 0.95000 。这说明了循环 LR 调度如何允许我们通过单个训练循环获得具有不同行为的模型,并且 XGBoost 元学习器可以从它们的预测中提取有用的信息。

通过对比拉伸所有图像以及特定子类上的训练模型并结合它们的预测,测试精度上升到 0.95865 。混淆矩阵显示了子类内精确分类的改进,特别是对于“城市”子类。开发在某些类上是“专家”的模型,并将它们与善于区分子类的模型一起使用,被证明是非常有效的。

最后,在反走样resnet 18 网络并结合训练集和验证集使用所有可用于训练的标注数据后,测试精度上升到 0.97115 。反走样是提高泛化能力的有力手段,在图像数据有限的情况下尤为重要。

Yay!

其他想法

以下是我为应对这一挑战而想出的一些其他主意,它们要么效果不好,要么我没有办法去尝试。

单通道图像

这些图像是灰度的,所以尽管它们在加载时被编码成三个通道,但它们可以被表示为单通道矩阵。我的想法是,这种降维可以加速训练,同时保留所有必要的信息,但通过实验,这种方法显示出在没有显著加速训练的情况下损失了准确性。

其他集成方法

我还尝试对通过其他方式检索的模型进行集成,例如在不同处理方法(有/没有类别*衡、不同图像增强技术、不同数据增强方法)之后对图像进行训练的模型,但是这些方法计算量更大,并且不能提供明显更好的准确性。

生成对抗网络

如前所述,数据扩充和类*衡在模型性能中起着关键作用。除了经典的图像处理,生成模型可以单独用于合成带注释的数据。例如,DAGAN 模型可用于数据扩充,而 BAGAN 可用于*衡。

灰度图像网络预训练

所提供的数据集中的图像具有与组成 ImageNet 数据集的自然图像相似的内容,不同之处在于我们的图像是黑白的。因此,在灰度图像上预先训练的模型将更适合于这个任务。

人工图像彩色化

如果我不能获得灰度图像的预训练模型,我的下一个想法是人工给图像着色,希望增加额外的信息。人工图像着色的预训练模型确实存在,并且是公开可用的,如果你尝试这种方法,请告诉我!**

感谢阅读,我希望你喜欢这篇文章!你可以在 GitHub 上找到我的方法的完整代码。

通过基础设施代码(Boto3、CloudFormation、Python)发布 AWS EMR 支持的 SageMaker 笔记本电脑

原文:https://towardsdatascience.com/launching-emr-backed-sagemaker-notebook-via-infrastructure-as-code-boto3-cloudformation-4d2ced33c417?source=collection_archive---------21-----------------------

如今,云中的可扩展分析是游戏的名称。所有领先的云提供商都非常关注简化机器学习的端到端生命周期的供应服务。如今的趋势是在 data-lake 上获取数据(这需要自己的一套考虑因素),并通过 Spark 这样的大数据处理框架对其进行处理。一旦数据在 Data Lake 中以相当标准的格式可用(这样做是为了减轻 it 成为数据沼泽的风险),这些数据就被认为可供从数据分析师、数据科学家等多个类别的最终用户使用。由于数据湖中的数据量通常很大,如果想要将其用于分析目的,一个自然的选择是使用大数据原生工具集来执行探索性分析和随后的功能工程。此外,数据科学社区最喜欢的工具之一是 Jupyter notebook,它有助于提高工作效率和协作。因此,对于数据科学家来说,乌托邦或涅槃状态是能够使用 Jupyter(如云中的笔记本电脑)来消费数据湖中的数据,并且还能够无缝地使用 Spark 等大数据工具来进行功能工程。

如果您使用 AWS 堆栈来实现升级的结果,您可能最终会使用以下一组 AWS 本机服务:

  1. EMR(Elastic MapReduce)—AWS 中的托管 Hadoop 框架(特别是在 EMR(领先的内存和分布式计算引擎)中使用 Spark)
  2. SageMaker——AWS 中主要的机器学习服务之一
  3. 简单存储服务(S3)—AWS 提供的大规模可扩展对象存储服务,是构建数据湖的基础

因此,如果你在 S3 有数据,通过电子病历处理,如果你想执行机器学习任务,如探索性分析,特征工程;您很可能会使用 SageMaker 的托管笔记本(Jupyter)实例。通常这些笔记本用于特别分析,一旦你对你的分析和特征工程方法感到满意,你通常会通过其他工具集(如 Glue 或 EMR,尽管有些人仍然可以出于上述目的使用笔记本)来操作它的执行。

这一切看起来都很好,但当您打算将 SageMaker 笔记本与 EMR 结合使用时,就会遇到挑战。默认情况下,这两个组件不是开箱即用的,例如,您不能在启动时使用 SageMaker notebook 实例来运行 pyspark 查询。如前所述,如果您想要使用 sweet 托管笔记本电脑来执行大规模分析,而处理是由 EMR (Spark)在后端执行的,您必须在 SageMaker 笔记本电脑中为此进行一些配置。AWS 的 blogpost 强调了这样做的步骤,包括访问笔记本的外壳,从互联网下载“config.json ”,然后修改它以实现 EMR 集成。如果您为自己(不同尺寸)或不同用户反复启动笔记本电脑,这些手动配置任务会增加操作开销,并且容易出错。这就是如今你可以利用这个游戏的另一个名字的地方:“作为代码的基础设施”。

作为代码的基础设施(或简称为 IaC)是指以编程方式在您的*台(无论是本地还是云)中提供资源的方法。有各种特定于云的方法来实现这一点,例如 Azure 使用 ARM 模板,AWS 支持云形成。类似地,还有配置管理工具,比如 Ansible/Chef/Puppet/Terraform。进一步说,所有领先的云提供商都提供 SDK,您可以使用它们来实现类似的 IaC 功能。无论您使用哪种方法,它都能让您运行代码/脚本,并为您提供资源。它增强了部署的可重复性和一致性,还节省了大量时间。这正是本文的价值主张:

为您提供 IaC 功能,在 AWS 中配置集成 EMR 的 SageMaker 笔记本电脑。

如上所述,IaC 可以通过多种方式实现,在本文中,我将重点介绍几种方法的组合:

  1. AWS Boto3 SDK
  2. 云的形成

使用 Python。因此,没有进一步的到期,让我们开始编码,因为谈话是廉价的。

先决条件:

这篇文章假设:

  1. 您有 AWS 帐户
  2. 您已经在您的帐户中完成了基本的网络设置(VPC、子网等)
  3. 您知道如何配置 EMR 集群,并且已经有一个 EMR 集群在运行(至少有 Spark 和 Livy 服务)
  4. 您已经为 EMR 集群和 SageMaker 笔记本配置了安全组,并在 EMR 主节点的安全组中添加了 SageMaker 的安全组。参考 AWS 博客了解更多内容。
  5. 您已经在您的环境中为 SageMaker 和 EMR 配置了 IAM 角色
  6. 您已经在您的环境中为一个具有帐户管理员访问权限的用户配置了 IAM 配置文件(或者您可以让一个用户具有仅限于 SageMaker、EMR 和 CloudFormation 的权限)
  7. 你对 Python 有基本的了解

(我很想深入了解上面的细节,但是上面的每一个话题都需要深刻的理解,我已经把它排除在这篇文章的范围之外了。)

设置:

要跟进,您必须具备:

  1. Python 安装在您的系统中。理想情况下还带有一个 IDE。我更喜欢皮查姆。
  2. 您已经安装了 boto3(如果没有,在您的环境中运行:pip install boto3)

代码:

让我们从导入所需的库开始:

import boto3
import json
import sys
import base64

我更喜欢创建我将在程序中使用的参数的映射/字典。您可以选择不同的方法:

parameters = 
{"SecurityGroupIds":["sg-<>"],
"SubnetId":"subnet-<>","VolumeSizeInGB":5,
"RoleArn":"arn:aws:iam::<>:role/service-role/<>",
"nb_instance_type":"<>",
"nb_instance_name":"<>"
"lifecycle_config_name":"<>"}

在上面的字典中,指定了以下参数:

  1. security group pids—您为 SageMaker 笔记本创建的安全组的 ID
  2. SubnetId —您将在其中置备笔记本的 subner 的 Id
  3. VolumeSizeInGB —您可以将 EBS 卷附加到笔记本上。您可以在这里指定以 GB 为单位的大小。我指定了 5GB。
  4. role arn—在 SageMaker 服务与您帐户中的其他 AWS 服务进行交互之前,您应该已经创建的 IAM 角色。在这篇文章中,这也被强调为一个先决条件。
  5. nb _ instance _ type—sage maker 笔记本的实例类型
  6. nb 实例名称 SageMaker 笔记本实例的名称
  7. 生命周期配置名称—将作为此代码的一部分创建的 SageMaker 生命周期配置的名称

现在让我们定义几个助手函数,我们很快就会用到:

正在获取 EMR 主节点的私有 IP:

def get_emr_master_pvt_ip(boto_client_emr, cluster_id):emr_list_instance_rep = boto_client_emr.list_instances(ClusterId=cluster_id,InstanceGroupTypes=[**'MASTER'**,],InstanceStates=[**'RUNNING'**,])return emr_list_instance_rep[**"Instances"**][0][**"PrivateIpAddress"**]

这个函数的目的是获取 EMR 主节点的私有 IP,我们稍后将在 SageMaker 生命周期配置中使用它。更多细节:

  1. 这个函数需要一个 EMR boto 客户端(我们稍后将初始化)和一个 EMR 集群 ID(您可以从 AWS 控制台获得)
  2. 然后,它使用 EMR boto 客户端,通过 list_instances 函数列出 EMR 集群实例,并传递参数(指定您想要检索其详细信息的集群 ID,指定您想要主节点的详细信息,还指定您只想查询正在运行的实例。它返回一个字典,您可以从中检索所需的值(EMR _ list _ instance _ rep[" Instances "][0][" private IP address "])并将其返回。它返回一个字符串,表示指定的运行 EMR 实例的私有 IP。

呈现 SageMaker 生命周期配置脚本:

def render_emr_script(emr_master_ip):emr_script = **'''** #!/bin/bashset -e# OVERVIEW# This script connects an EMR cluster to the Notebook Instance using SparkMagic.# # Note that this script will fail if the EMR cluster's master node IP address not reachable#   1\. Ensure that the EMR master node IP is resolvable from the Notebook Instance.#       - One way to accomplish this is having the Notebook Instance and the EMR cluster in the same subnet#   2\. Ensure the EMR master node Security Groups provides inbound access from the Notebook Instance Security Group#       Type        - Protocol - Port - Source#       Custom TCP  - TCP      - 8998 - $NOTEBOOK_SECURITY_GROUP#   3\. Ensure the Notebook Instance has internet connectivity to fetch the SparkMagic example config  ## https://aws.amazon.com/blogs/machine-learning/build-amazon-sagemaker-notebooks-backed-by-spark-in-amazon-emr/# PARAMETERSEMR_MASTER_IP={0}cd /home/ec2-user/.sparkmagicecho "Fetching SparkMagic example config from GitHub.."wget https://raw.githubusercontent.com/jupyter-incubator/sparkmagic/master/sparkmagic/example_config.jsonecho "Replacing EMR master node IP in SparkMagic config.."sed -i -- "s/localhost/$EMR_MASTER_IP/g" example_config.jsonmv example_config.json config.jsonecho "Sending a sample request to Livy.."curl "$EMR_MASTER_IP:8998/sessions" **'''**.format(emr_master_ip)b64_encoded = base64.b64encode(emr_script.encode())return b64_encoded.decode(**'**ascii**'**)

上述功能的主要目的是修改 SageMaker 生命周期配置脚本,以便在启动时,它指向正确的 EMR 主节点。这个 shell 脚本将在创建 SageMaker notebook 时执行,它执行以下步骤:

  1. 它导航到/home/ec2-user/。sparkmagic 目录
  2. 然后从一个 URL(https://raw . githubusercontent . com/jupyter-incubator/spark magic/master/spark magic/example _ config . json)下载一个示例 JSON
  3. 然后,Linux 的 sed 将“localhost”替换为 EMR 主节点的私有 IP,然后将 example_config.json 重命名为 config.json
  4. 作为最后一步,它卷曲 EMR 主节点,一旦成功互连,就应该成功。

基本前提是您配置 SageMaker 与 EMR 中的 Livy 服务对话,该服务可以配置为在 EMR 集群中运行,并支持 REST 上的交互。该机制用于实现 SageMaker 笔记本和 EMR 之间的集成。

5.在这个函数中,shell 脚本(以多行字符串的形式)被修改为替换值 EMR private IP。稍后将使用该脚本来创建 SageMaker 生命周期配置,该调用要求该脚本是 base64 编码的。这就是为什么您可能已经注意到在函数体中使用 base64.b64encode 等函数,这样做是为了确保它符合要求。

SageMaker 笔记本渲染云模板:

def render_cf_template():cf_template_dct = {"AWSTemplateFormatVersion": "2010-09-09","Description": "CloudFormation template to create simple sagemaker notebook in a subnet","Resources": {"sagemakernotebook": {"Type": "AWS::SageMaker::NotebookInstance","Properties": {"DirectInternetAccess": "Enabled","InstanceType": "ml.t2.medium","LifecycleConfigName": "configName","NotebookInstanceName": "nbname","RoleArn": "<>","RootAccess": "Enabled","SecurityGroupIds": ["sg-<>"],"SubnetId": "subnet-<>","Tags": core_tags.resource_group_tags,"VolumeSizeInGB": 5}}}}#user defined parameters:cf_template_dct["Resources"]["sagemakernotebook"]["Properties"]["InstanceType"] = parameters["nb_instance_type"]
cf_template_dct["Resources"]["sagemakernotebook"]["Properties"]["NotebookInstanceName"] = parameters["nb_instance_name"]
cf_template_dct["Resources"]["sagemakernotebook"]["Properties"]["LifecycleConfigName"] = parameters["lifecycle_config_name"]cf_template_dct["Resources"]["sagemakernotebook"]["Properties"]["RoleArn"] = parameters["RoleArn"]cf_template_dct["Resources"]["sagemakernotebook"]["Properties"]["SecurityGroupIds"] = parameters["SecurityGroupIds"]cf_template_dct["Resources"]["sagemakernotebook"]["Properties"]["SubnetId"] = parameters["SubnetId"]cf_template_dct["Resources"]["sagemakernotebook"]["Properties"]["VolumeSizeInGB"] = parameters["VolumeSizeInGB"]return json.dumps(cf_template_dct)

在上面的函数中:

  1. 我们首先以字典的形式指定 SageMaker 笔记本的云信息模板。
  2. 然后,我们根据参数字典中的值更新这个字典。具体来说,我们更新:

a.实例类型
b .实例名
c .生命周期配置名
d .角色 ARN
e .安全组
f .子网 Id
g .卷大小调整 b

SageMaker 笔记本的一部分,该部分将作为此代码的结果进行配置。

所有助手功能就绪后:

session = boto3.Session(profile_name="<>")
client_cf = session.client("cloudformation")
client_sm = session.client("sagemaker")
client_emr = session.client("emr")

我们使用您已经在系统中配置的 IAM 配置文件初始化 boto3 会话。确保与 IAM 配置文件对应的用户通过 IAM 策略(直接附加或附加到用户所属的组)拥有足够的权限来执行手头的任务。

然后,我们使用会话对象创建三个 boto3 客户端:

  1. 云的形成
  2. SageMaker
  3. (同 electromagneticriveting)电磁铆

因为它们很快就会被使用。

emr_master_pvt_ip = get_emr_master_pvt_ip(client_emr,parameters[**"emr_cluster_id"**])

然后我们调用 get_emr_master_pvt_ip 函数来获取 emr 主节点的私有 ip。这将以字符串的形式返回其 IP。

有了 EMR master 的私有知识产权,我们就有能力制定 SageMaker 的生命周期政策:

print(**"creating SM lifecycle config"**)
lc_config_rep = client_sm.create_notebook_instance_lifecycle_config(NotebookInstanceLifecycleConfigName=parameters[**"lifecycle_config_name"**],OnCreate=[{**'Content'**: render_emr_script(emr_master_pvt_ip)},]
)

我们使用 SageMaker boto 客户端(client_sm)及其函数(notebook _ instance _ life cycle _ config)来创建生命周期配置并传递所需的参数。特别是,对于 OnCreate 参数,我们调用 render_emr_script 函数,该函数将使用 base64 编码的 emr 主私有 IP 返回呈现的生命周期配置脚本。

运行该程序后,您应该能够验证已经在 SageMaker 中创建了一个生命周期:

您可以通过单击配置名称并单击“查看脚本”来进一步验证您的脚本是否已使用 EMR 主专用 IP 地址正确呈现(查找 EMR_MASTER_IP 变量的值):

现在创建了生命周期配置,让我们启动 SageMaker 笔记本。

rendered_cf_template = render_cf_template(parameters)

我们调用 render_cf_template 函数来根据需求渲染 CloudFormation 模板。这将给出一个字符串形式的 CloudFormation 模板,我们将在下一步中使用它:

create_stack_response = client_cf.create_stack(StackName=parameters[**"stack_name"**],TemplateBody=rendered_cf_template,ResourceTypes=[**'AWS::SageMaker::NotebookInstance'**,],OnFailure=**'ROLLBACK'**,EnableTerminationProtection=False
)

因此,我们利用 CloudFormation boto3 客户端来创建一个堆栈(当您想要通过 CloudFormation 部署资源时,您可以创建一个堆栈)。在参数中,您可以注意到我们正在传递渲染的 CloudFormation 模板和一些其他方便的设置(例如,在失败时,我们希望回滚发生,并且终止保护设置为 false,以便可以通过编程直接终止)

执行后,需要一段时间才能完成,因为这将启动 SageMaker notebook 的启动过程。完成后,您会注意到 AWS 控制台中的 CloudFormation 部分将显示成功,如下所示:

关键时刻:您可以在 SageMaker 笔记本中验证它也成功地与 EMR 集成:

正如您所看到的,如果您推出一款采用 SparkMagic (PySpark)内核的笔记本电脑,您将能够成功使用 Spark API,并可以将这款笔记本电脑用于探索性分析和大规模特性工程,而 EMR (Spark)则在后端执行繁重的工作!

希望这篇文章有深刻的见解。如果你有兴趣了解更多关于 Spark 的知识,可以看看我在 Udemy 上最畅销的课程和最*推出的书籍。

在您的工作场所启动生产级人工智能

原文:https://towardsdatascience.com/launching-production-grade-ai-at-your-workplace-73ccf6ae02dd?source=collection_archive---------30-----------------------

人工智能风靡一时,许多技术人员已经扩大了人工智能和人工智能知识的规模。然而,想出一个好的生产级工业人工智能完全是另一回事。我想我会分享一些我自己在这个主题上的学习,并给你一个框架,列出你需要解决问题的领域,然后让人工智能在你的工作场所发生

步骤 0

评估数据的质量。你的人工智能将基于你捕获的关于你的用户的独特数据集。你的数据是你的秘方,而不是你的人工智能算法。您需要提出自己独特的数据验证框架,从完整性(您的数据中是否有太多漏洞)、可信度(您存储在后端云中的位和字节是否与现实世界的证据相匹配)等方面评估您的数据集。提示:不要被数据集的大小所迷惑。如果你的数据集已经捕获了许多关于你正在解决的人工智能问题陈述的变化,千兆字节的数据集也是好的。

基于你对数据质量的评估,决定你是想要组织一个团队来破解人工智能还是继续以一种特别的方式做人工智能

第一步

扁*化您的事务/运营数据库,构建您的数据工程。让你的人工智能工程师从一个杠杆的位置工作。事务性数据库设计旨在实现高读/写吞吐量。并不意味着运行调查性查询来理解/探索数据洞察力。根据你计划解决的人工智能问题的类型,为你的人工智能数据模型建模,以简化和方便调查。这一步的一部分还包括弄清楚你的数据工程管道(Kafka/Airflow/ECS 等)和架构。

第二步

使用标准词汇注释数据。这有两个好处。首先,不同的源系统可以使用不同的语义标签来说同样的事情,但标准化可以确保你有一个统一的词汇来运行人工智能。其次,标准词汇表也可以与您所在行业的标准层次结构结合使用。基本上这个世界上没有什么是孤立存在的,你会想要在你的数据集中注入本体或领域知识,以推动更好的人工智能推理。

第三步

确定您的最终目标,以推动产品的关键业务指标。这是人工智能的标准产品路线图练习。

第四步

基于上述内容,确定抽象数据科学*台的目标。不要每次都从头分析。最好确定更广泛类别的人工智能问题陈述,并装备您的数据*台来处理此类情况。

第五步

基于以上选择人工智能问题的类别并构建->测试->部署->学习和重复。这一步的问题陈述的一部分也是弄清楚你的整个 ML DevOps 策略。

希望这有用。

机器学习领域的劳雷尔和哈迪

原文:https://towardsdatascience.com/laurel-hardy-in-machine-learning-a0e739b51225?source=collection_archive---------42-----------------------

Source: Flickr

"好吧,你又给我惹了一个大麻烦!"

本周,我引用了更早的资料,一直追溯到 20 世纪 30 年代。万一一些千禧一代的读者只是想“OK Boomer”,我想澄清一下,我自己也是千禧一代。只是有时候旧时代的参考比现代的更有意义。

所以,对于那些不知道劳雷尔&哈代的人,我建议你们在继续阅读之前,先去 Youtube 上看几个视频。对于那些有幸经历过这一对搭档的人来说,我希望你能看到我接下来要说的相似之处。

机器学习的 Laurel & Hardy 被称为偏差和方差。就像劳雷尔和哈代一样,偏见和差异交织在一起。虽然两者都可能导致你的模型出现重大错误,但与 Laurel 和 Hardy 不同,他们理解错误在让人发笑方面的力量,在机器学习中,错误可不是闹着玩的。如果你不注意偏见和差异,它们会让你丢掉工作。

为了帮助你避免陷入困境,让我们看看为什么机器学习的 Laurel & Hardy 值得你关注。

差异

Stan Laurel, Source:Flickr

"你可以把马牵到水边,但必须牵着一支铅笔."—劳雷尔

这部剧的粉丝会记得劳雷尔有真正好的想法。他会想出一个有趣的做事方法,并与哈代分享,然后哈代会去“再告诉我一遍”。这些话一出口,劳雷尔就会犯错误,第二次给出他的想法的一个完全荒谬的版本。

劳雷尔举例说明了机器学习中的差异。方差是你的模型的错误,当它不能推广到它以前没有见过的数据。如果你稍微改变一下数据,模型的预测就会完全偏离。就像劳雷尔的“再告诉我一遍”的每次迭代都会导致不同的答案一样,如果你的机器学习模型具有非常高的方差,也会发生同样的情况。

换句话说,你的模型将随着信号学习噪音,所以如果有一个从铅丢失,它将不能简单地分离东西!

偏向

Oliver Hardy, Source:Flickr

“你实际上在用你的大脑。这就是与我交往的结果。”—哈代

另一方面,当劳雷尔第一次分享他的想法时,他从来没有理解过劳雷尔,至少对观众来说,他的想法是清楚的。然而,哈代有一种不可思议的能力,能够理解劳雷尔第二次脱口而出的非荒谬的版本。

显然,哈迪很难将信号从噪音中分离出来,这就是偏见。简单来说,偏差可以定义为由于模型无法从训练数据中学习到任何东西而导致的错误。

换句话说,如果你只是简单地使用你的大脑,而不是使用一个有高度偏见的模型,你会看起来更聪明。

那又怎样?

老样子来了那又怎样?你为什么要关心这些可怕的强制类比呢?你必须关心它们,因为每个机器学习问题都是关于*衡两者之间的权衡。

Source: elitedatascience.com

如果你的模型有很高的偏差,那它就是学习得不够(或者根本没有学习),所以这就打败了机器学习的意义。例如,这可能会发生,因为您正在对非线性问题使用线性回归。所以,一个从耐寒到耐寒的方法是使用更复杂的模型。

如果你让你的模型变得太复杂,比如用一个复杂的反推 SVM,Laurel 开始产生铅笔和马的幻觉,就像我刚刚产生了模型名字的幻觉一样,所以你也要避免这种情况。

基本上,你需要做的是在两者之间找到一个*衡点,一个劳雷尔&哈代和你和谐相处的快乐之地。

直到你让自己陷入另一个烂摊子!但这就是数据科学家的生活,不是吗?

现在,如果你们中的任何人已经遭受了这种痛苦,下面我提供了一个链接,可以更好地解释偏差和方差的权衡,这可能会帮助你的大脑从刚刚阅读的内容中恢复过来:

https://elitedatascience.com/bias-variance-tradeoff

人工智能和法律技术的采用

原文:https://towardsdatascience.com/lawtech-and-artificial-intelligence-fc5d7899c37b?source=collection_archive---------17-----------------------

Photo by @chrisyangchrisfilm

责任、不断增加的压力和量化律师

我们可以随心所欲地谈论道德,但在某一点上,政治中争论已久的对与错将会变成法律。微软等大型科技公司及其总裁辩称:“科技公司必须停止‘如果合法,那就是可以接受’的做法。”据《卫报》(Hern,2019)报道。微软现在是一家价值一万亿美元的公司。然而,不仅仅是科技公司必须三思而后行,在新法规出台前做到合法。适应得越快越好还是越差,法律职业在技术中会是什么样子?

法律技术 又称法律技术,是指利用技术和软件提供法律服务。

法律技术采用

英国法律协会于 2019 年 2 月发布了一份名为 LawTech 收养研究的报告。这份报告是由科技分析师 TechMarketView (TMV)撰写的。法律协会代表英格兰和威尔士 190,000 多名律师。

根据该报告:“*年来,法律科技公司的数量有所增加,但法律从业者采用法律科技的比率并没有加快。” (TechMarketView,2019)因此,技术创新似乎不会立即成为问题,但是,公司选择适应这种变化的方式可能是,而且确实是相关的。现在下结论可能太快了。

TechMarketView 发现并调查了 100 多家在英国运营的法律技术公司。许多是由律师或前律师提出的“单点解决方案”。其他法律技术供应商是技术提供商,最初服务于金融服务等其他行业,现在正转向法律市场。

“我发现初创企业很难打交道。我接触过的一些公司似乎是由一个心怀不满的律师建立的,他碰巧和一个 IT 人员一起去了大学。我只是觉得,他们中很少有人真正在做什么新的事情,他们往往分为三种主要类型:生成文档、审阅和分析文档或分析管理信息,如法律支出或工作流程。他们不一定是在重新发明轮子,而是希望提供一个更闪亮的新轮子”。

然而,尽管传统律师可能不同意或涉及现有的解决方案,但不同的行为者都有采用新技术的压力,这在同一份报告中有所概述。

Image by techMarketView in the report LawTech Adoption Research retrieved the 21st of September 2019.

我将列举这些不同报告中提出的几个要点:

  • 客户 :应对客户收费压力的效率和生产力,以及律师展示他们如何为客户利益创新的需要。
  • 一般委员会 期望在相同的预算内看到更多的尽职调查或电子发现。
  • 对透明度的需求 。客户压力直接转化为法律技术采用的一个领域是法律成本透明度。计费有时很抽象和困难,这可能会改变。
  • 对新工作方式的需求 。客户对律师事务所施加越来越大的压力,要求他们以更低的成本办事,在某些情况下,客户甚至要求律师事务所在其服务中加入特定的技术解决方案。
  • 来自适应更快的会计服务提供商的竞争 。“英国所有的‘四大’会计服务提供商现在都有一个法律部门。2014 年初,普华永道的法律业务获得 ABS 资格,同年晚些时候,毕马威和 EY 获得 SRA 批准。2018 年 6 月,德勤英国被授予 ABS 资格。
  • 炒作。与 lawtech(特别是人工智能和机器学习技术)相关的炒作和宣传对提高整个法律部门的认识产生了积极影响。
  • 调控驱动 。已经为金融服务和银行业提供解决方案的所谓“regtech”公司已经开始转向法律领域
  • 遗留 IT 系统 s .通过用机器人维护现有流程自动化,在某些情况下需要最终迁移到新系统上。
  • 【律师事务所开业】 对技术和 IT 提出了更高的要求,以提供移动工作环境。
  • 改变人口统计 。你可能会发现更多的人从大学选修了计算机科学模块和法律。越来越多的模块侧重于法律技术或法律技术。
  • 缺少律师 。在某些情况下,缺乏律师,或者有些人无法接触律师。这在家庭法等领域可以有所改变(这些领域一直缺乏律师)。
  • 云应用 。云计算降低了进入各种应用程序的成本和商业壁垒,随着传统案例管理系统或实践管理系统的生命周期结束,这些应用程序可以进入企业。

机器人流程自动化 (RPA)是用于部分或全部自动化人工、基于规则和重复的人类活动的软件工具的术语。

总法律顾问 ,首席法律顾问,或首席法务官(CLO)是法律部门的首席律师,通常在公司或政府部门。

定量律师

不久前,金融服务行业在其领域中创建了一个新的方向。他们被称为‘quants’或数量统计学家 ,专门研究应用数学和统计方法解决金融和风险管理问题

Khandani 在一篇论文中指出,通过间接手段,2007 年 8 月 6 日至 10 日的事件可能是一个或多个大型多空股票投资组合快速*仓的结果,最有可能的是最初的量化股票市场中性投资组合。因此,这可能是 2007-2008 年大规模金融危机的部分原因(Khandani,2007)。

如果定量统计、情感分析等正在进入法律领域,这是一个警告。如果律师或法律行业的其他人认为自己比金融行业更擅长管理风险,这可能是一个滑坡——相对较小的第一步会导致一系列相关事件,最终导致一些重大(通常是负面)影响。或许我们可以希望,正是考虑到这一点,法律行业在适应技术方面经历了如此艰难的时期,但我怀疑事实是否如此。

无论如何,这是很重要的,因为法律职业可能会变得与技术更加融合,法律从业者习惯于超越眼前的利益,看到潜在的风险。让我举几个假设。

  • 想象一下,一份符合当地法规的合同为 100,000 人提供简单的保险索赔,您可以自己拍摄并发送。
  • 维护社交媒体*台上数十亿用户的条款和条件。通过从政府法律公告中“抓取”在线文本,并根据当地参与者的分析进行预测,不断监控改革,以适应世界上大多数国家的当地法规。
  • 在一家大型国际公司中整理 40,000 份文档,以找到支持诉讼的历史数据,同时在线运行情绪分析,以找到受影响的受害者。

在所有这些情况下:什么会变得糟糕透顶?在法律失控的最坏情况下,我们能期待看到什么?

在最好的情况下,利用技术的伟大法律实践会是什么样的呢?

法律中的人工智能

有人说,法律的核心是语言,所以长期以来,基于自然语言运行的软件在法律职业的一些领域发挥了作用,这并不奇怪。

自然语言处理: 通常简称为 NLP,是人工智能的一个分支,利用自然语言处理计算机与人类之间的交互。

关于法律技术的许多争论和宣传焦点都集中在人工智能上。这可能是由于客户在展示创新方面的压力(通常通过新闻稿分享)。许多人可能高估了人工智能增强运营的潜力。这些技术似乎首先被英国的大公司采用,后来被小公司采用。因此,你最终只能在价格上竞争。

技术并不能解决一切。吸收一份文件并提取出标准的东西是很容易的,但理解合同语言却不容易。因此,在法律背景下,要确信已经提取了所有关键数据点并不那么容易。几乎没有标准的合同语言或带有标签的信息保密示例,因此这带来了一些困难。

人工智能可以帮助降低风险,通常是通过在诉讼过程中协助律师。这也是非常重要的,因为只审查十分之一的文件会有什么样的风险?该报告问道:“十分之一由人类审阅的文档比婴儿人工智能系统查看每一份文档的风险低吗?”我非常确定这个问题的答案并不简单。

法律技术的三个领域

《法律技术应用研究报告》将法律服务细分为三个具有不同需求的领域。

  • 企业对企业(B2B)律师事务所
  • 企业对消费者(B2C)律师事务所
  • 内部法律部门(主要在大型商业或公共部门组织中)。

法律技术领域

在英国的法律技术领域,有更多的参与者,他们在上述报告中得到了相对简洁的总结。

Image by techMarketView in the report LawTech Adoption Research retrieved the 21st of September 2019.

在过去的四年里,一小群公司已经在法律市场上站稳了脚跟。像 Kira、Luminance 和 RAVN(现在的 iManage )这样的供应商已经在 B2B 领域获得了牵引力。

Apperio正在帮助公司分析他们的法律支出,并在 2018 年年中在 A 轮融资中筹集了 1000 万美元(750 万英镑)。今年,Clarilis、Lexoo 和 Juro 等公司在 2000 万至 1000 万英镑之间进行了融资,这种情况在几年前还是闻所未闻的。

除此之外,还列出了具体的应用程序,以便更好地理解技术和应用程序可以集成或包含在哪里。这些也构成了研究的重点。

结论

在处理新问题时,我们必须确保不要制造太多的新问题。从某种程度上来说,法律行业在改变其做法上如此缓慢是不可避免的,也许这是更好的。这仍有待观察,因为法律公司可能会尝试在更大程度上用数学和统计学以及计算机科学来量化信息。英国市场上有大量的解决方案,在这个重要的领域可能会有一大批新的竞争者。

如果你有兴趣阅读更多关于 LawTech 的内容,我以前写过另一篇关于这个主题的文章:

[## 人工智能和法律技术

人工智能领域的不同法律应用

medium.com](https://medium.com/dataseries/artificial-intelligence-and-lawtech-4d7181a03202)

一个响亮的旁注——存在气候危机

除了我们能与法律行业合作的令人兴奋的新技术方法之外,一个更相关的问题是这些创新者应该关注什么。一个可能的地点当然是当前的气候危机和这一领域的法律应用。超过 30 万人走上悉尼街头,但 9 月 20 日,数百万人走上街头抗议,要求我们更加严肃地对待气候危机,减少排放。哪个创新的律师会使用这些新技术来解决气候变化的问题?这是今天的一个深刻的旁注。

Sydney as shared by Greta Thunberg

参考

戴尔河(2019)。法律与词序:法律技术中的自然语言处理。自然语言工程25 (1),211–217。

鲍勃·古德曼(2014 年 12 月 16 日)。《聪明的创业公司颠覆法律的四个成熟领域》。今日法律技术。检索时间 2019 年 9 月 20 日。

Hern,A. (2019 年 9 月 20 日)。微软老板:科技公司必须停止“如果合法,就可以接受”的做法。检索自https://www . the guardian . com/technology/2019/sep/20/Microsoft-boss-tech-firms-must-stop-if-its-legal-its-acceptable-approach

汉达尼和罗(2007 年)。2007 年 8 月,宽客发生了什么?。可在 SSRN 1015987 处获得。

TechMarketView。(2019 年 2 月)。法律技术采用研究报告。检索自https://www . law society . org . uk/support-services/research-trends/law tech-adoption-report/

这是第 500 天的第 109 天。我目前第 101-200 天的重点主要是 Python 编程,但是今天我决定进入 lawtech,因为明天我将在一个黑客马拉松中与一个团队就这个具体问题进行合作。如果你喜欢这篇文章,请给我一个答复,因为我确实想提高我的写作或发现新的研究,公司和项目。

反向传播入门

原文:https://towardsdatascience.com/laymans-introduction-to-backpropagation-efa2c64437db?source=collection_archive---------5-----------------------

训练一个神经网络不是一件容易的事,但理解它可能很简单

反向传播是调整神经网络的权重以提高预测精度的过程。神经网络中的信息流动有两个方向。

  1. 前向传播——也称为推理——是指数据进入神经网络并弹出预测。
  2. 反向传播 —通过查看预测和实际结果之间的差异来调整权重的过程。

Photo by Pankaj Patel on Unsplash

反向传播是在神经网络准备部署到现场之前完成的。人们使用已知结果的训练数据来执行反向传播。一旦我们确信网络得到了充分的训练,我们就开始推理过程。

如今,反向传播就是使用无数工具中的一个命令。因为这些工具很容易训练神经网络,大多数人倾向于跳过理解反向传播背后的直觉。可以理解,当数学看起来像这样。

Andrew Ng’s Coursera course: https://www.coursera.org/learn/machine-learning

但是,在如此多的机器智能的核心过程背后获得一种直觉是非常有意义的。

权重在神经网络中的作用

在试图理解反向传播之前,让我们看看权重实际上如何影响输出,即预测。第一层的信号输入通过控制相邻层神经元之间连接强度的权重向前传播到网络中。

Source: http://tuxar.uk/brief-introduction-artificial-neural-networks/

训练网络意味着微调其权重以提高预测精度

调整权重

一开始,神经网络的权重是随机的,因此预测都是错误的。那么,我们如何改变权重,以便当给一只猫看时,神经网络以很高的可信度预测它是一只猫呢?

  • 一次一个权重:训练网络的一个非常基本的方法是改变一个权重,同时保持其他权重不变。
  • 权重组合:另一种方法是在一个范围内(比如从 1 到 1000)随机设置所有权重。可以从全 1 开始,然后全 1 和一个 2 等等。组合看起来像这样— (1,1,1),(1,1,2),(1,2,1),(1,2,2),(2,2,2),(2,2,3)

为什么这两种方法都不好?

这是因为如果我们尝试 N 个权重的所有可能组合,每个组合的权重范围从 1 到 1000,这将花费大量的时间来筛选解空间。对于运行在 1GHz 的处理器,2 个神经元的网络需要 1⁰⁶/1⁰⁹ = 1 毫秒。对于 4 个神经元的网络,相应的处理时间将是 16 分钟,并且对于更大的网络,处理时间将保持指数增长。

The Curse of Dimensionality

对于 5 个神经元网络来说,这将是 11.5 天。这就是维度的诅咒。一个真正的神经网络将有 1000 个权重,需要几个世纪才能完成。

这就是反向传播的用处

一旦你对反向传播有了直观的认识,数学就很容易理解了。假设一家公司有 2 名销售人员、3 名经理和 1 名首席执行官。反向传播是首席执行官向中层管理人员提供反馈,他们反过来又向销售人员提供反馈。

每一层的员工都向所有后续层的经理汇报,用箭头的宽度表示不同的“强度”。因此,一些员工比其他人更经常向一位经理汇报工作。此外,CEO 认为设计经理(第二层的底层神经元)的意见比销售经理(自行车骑手)的意见更重要。

每次销售完成后,首席执行官都会计算预测结果和预期结果之间的差异。这位首席执行官稍微调整了一下,他希望对哪位经理的话给予多大的“权重”。经理汇报结构也根据首席执行官的指导方针而改变。每位经理都试图以一种让他/她更了解情况的方式重新调整权重。

Top Down: Backpropagation happening after CEO receives wrong inputs from Middle Management

首席执行官重新调整对中层管理人员的信任。

这种将反馈传播回前几层的过程就是它被称为反向传播的原因。

首席执行官不断改变他的信任级别,直到客户的反馈开始符合预期的结果。

一点点数学知识

Source: https://www.xkcd.com/435/

一撮数学 一个神经网络的成功是用代价函数来衡量的。花费越少,训练越好。目标是以最小化成本函数的方式修改权重。

所以两个重要的术语—

  • 误差 =预期与现实之间的差异
  • 成本函数的梯度 =改变权重时成本的变化。

反向传播包含单词“back”。这意味着我们从输出回到输入。我们看看错误是如何反向传播的。

看看δˡ是如何依赖δˡ⁺的

http://neuralnetworksanddeeplearning.com/chap2.html

如果你仔细观察,方程的第二项有一个 z。我们在那里测量 z 变化的速度。这告诉我们误差会变化多快,因为δˡ也依赖于 z =神经元的输出。

http://neuralnetworksanddeeplearning.com/chap2.html

右边的第一项只是衡量成本作为第 j 个输出激活的函数变化有多快。右边的第二项测量第 j 个神经元输出端的激活函数σ变化有多快。

结果向前流,错误向后流。由于我们反向传播误差,我们需要误差如何在两个相邻层之间流动的数值表示。成本相对于重量的变化率由下式给出

http://neuralnetworksanddeeplearning.com/chap2.html

有了这些基础,反向传播算法可以总结如下

http://neuralnetworksanddeeplearning.com/chap2.html

从机器学习的角度考虑实际问题

  • 即使反向传播也需要时间。最好把输入的数据分批次。(随机梯度下降)。
  • 训练数据越多,权重调整越好。通常,神经网络需要数千个预先标记的训练样本。

反向传播虽然现在很流行,但在引入时也遭到了反对。许多著名的科学家和认知心理学家(包括著名的英国认知心理学家 Geoff Hinton)都不相信反向传播。反向传播由于很多原因而面临反对,包括它不能代表大脑如何学习。

Quora answer

尽管如此,它仍然是一个非常广泛使用的和非常有效的训练神经网络的方法。目前,专门的硬件正在开发,以更有效地执行反向传播。

** [## 自我学习人工智能:这种新的受神经启发的计算机自我训练

来自比利时的一组研究人员认为他们已经接*扩展摩尔定律的预期终点,他们…

futurism.com](https://futurism.com/self-learning-ai-this-new-neuro-inspired-computer-trains-itself)**

外行人对 KNN 的介绍

原文:https://towardsdatascience.com/laymans-introduction-to-knn-c793ed392bc2?source=collection_archive---------9-----------------------

k-最*邻算法是大多数人在开始机器学习时的起点。

Photo by timJ on Unsplash

kNN 代表 k-最*邻。它是一个监督学习算法。这意味着我们在监督下训练它。我们使用已有的标签数据来训练它。给定一个由观察值 (x,y)组成的带标签的数据集,我们希望捕获 x —数据y —标签之间的关系。更正式地说,我们想要学习一个函数 g : X→Y 以便给定一个看不见的观察值 Xg(x) 可以自信地预测相应的输出 Y

监督学习算法的其他例子包括随机森林、线性回归和逻辑回归。

Source: Edureka

kNN 实现起来非常简单,在任何机器学习设置中被广泛用作第一步。它通常被用作更复杂分类器的基准,如人工神经网络(ANN)和支持向量机(SVM)。尽管简单,k-NN 可以胜过更强大的分类器,并用于各种应用,如经济预测,数据压缩和遗传学。

  • 遗传学

[## 一个基于回归的 K 最*邻算法用于基因功能预测。

随着各种功能基因组学和蛋白质组学技术的出现,越来越需要…

bmcbioinformatics.biomedcentral.com](https://bmcbioinformatics.biomedcentral.com/articles/10.1186/1471-2105-7-S1-S11)

  • 农业

[## 用现场数据、航空数据估算火炬松人工林的林分高度和树木密度

准确的森林库存对于优化纸浆和造纸行业的整个供应链管理具有重要的经济意义

www.scielo.br](http://www.scielo.br/scielo.php?pid=S0001-37652018000100295&script=sci_arttext)

  • 航空— 空中交通流量预测

[## 基于 k *邻回归的空中交通流量预测

为了提高空中交通流量的预测精度,提出了将 k *邻回归应用于空中交通流量预测的方法

ieeexplore.ieee.org](https://ieeexplore.ieee.org/abstract/document/8630470)

正如 20 世纪初的大多数技术进步一样,KNN 算法也诞生于为军队所做的研究。美国空军航空医学院的两个办公室——Fix 和 Hodges (1951) 写了一份技术报告,介绍了一种用于模式分类的非参数方法,这种方法后来成为流行的 k-最*邻(kNN)算法。

Source: DTIC — The Declassified Paper in full.

它是如何工作的?

假设我们有一个包含两种点的数据集,即标签 1 和标签 2。现在给定这个数据集中的一个新点,我们想找出它的标签。kNN 的做法是通过其最*的 k 个邻居的多数投票。k 可以取 1 到无穷大之间的任何值,但在大多数实际情况下,k 小于 30。

蓝色圆圈 v/s 橙色三角形

假设我们有两组点——蓝色圆圈橙色三角形。我们要将测试点= 带问号的黑色圆圈,归类为蓝色圆圈或橙色三角形。

目标:给黑圈贴标签。

对于 K = 1,我们将着眼于第一个最*的邻居。因为我们采取多数投票,并且只有一个投票人,所以我们将其标签分配给我们的黑色测试点。我们可以看到,对于 k=1,测试点将被归类为蓝色圆圈。

将我们的搜索半径扩大到 K=3 也保持了相同的结果,只是这次不是绝对多数,是 3 中的 2。仍然在 k=3 的情况下,测试点被预测为具有蓝圈类别→因为大多数点是蓝色的。

我们来看看 k=5 和 K =9 是怎么做的。为了查看最*的邻居,我们以测试点为中心画圆,当 5 个点落在圆内时停止。

当我们观察 5 以及随后的 K = 9 时,我们测试点的大多数最*邻都是橙色三角形。这表明测试点必须是一个橙色的三角形。

Left→K=5, Majority = Orange | Right→K =9, Majority = Orange

既然我们已经标记了这一个测试点,我们对所有未知点重复相同的过程(即测试集)。一旦使用 k-NN 标记了所有的测试点,我们尝试使用判定边界来分离它们。决策边界显示了训练集的分离程度。

k-NN Live!

这就是 k-NN 如何发生的要点。让我们从一个机器学习工程师大脑的角度来看。

首先他们会选择k。我们在上面已经看到,k 越大 k 的票数就越多。这意味着正确的几率更高。但是你说,代价是什么?

获得 k 个最*邻意味着对距离进行排序。那是一个昂贵的手术。需要非常高的处理能力,这意味着更长的处理时间或更昂贵的处理器。K 值越高,整个过程的成本越高。但是过低的 k 会导致过度拟合。

非常低的 k 将不能概括。非常高的 k 值是昂贵的。

K = 1, 5, 15. Source code below.

当我们达到更高的 K 值时,边界变得*滑。蓝色和红色区域大致分开。一些蓝红战士被留在了敌后。它们是附带损害。它们说明了训练准确性的损失,但是导致了更好的概括和高测试准确性,即新点的正确标记的高准确性。

相对于 K 绘制的验证误差图通常如下所示。我们可以看到,在 K = 8 左右,误差最小。它在任何一边上升。

Left : Training error increases with K | Right : Validation error is best for K = 8 | Source: AnalyticsVidhya

然后他们会尝试找出点与点之间的距离。我们如何决定哪些邻居是附*的,哪些不是?

  • 欧几里德距离—最常见的距离度量
  • 切比雪夫距离— L∞ 距离
  • 曼哈顿距离-L1 距离:它们的坐标的(绝对)差之和。

在国际象棋中,棋盘上的方格之间的距离用曼哈顿距离来度量;国王和王后使用切比雪夫距离——维基百科

All 3 distance metrics with their mathematical formulae. Source: Lyfat

一旦我们知道如何根据距离来比较点,我们就会训练我们的模型。k-NN 最好的一点是没有明确的训练步骤。我们已经知道了关于数据集的所有信息——它的标签。本质上,算法的训练阶段仅包括存储训练样本的 特征向量 和类别标签。

The Tinkersons, December 2, 2017

K-NN 是一个懒惰的学习器,因为它不从训练数据中学习判别函数,而是记忆训练数据集。

一个渴望学习的人有一个模型拟合或训练步骤。懒惰的学习者没有训练阶段。

最后,为什么是 k-NN?

xkcd

  • 快速实现:这也是它作为基准算法受欢迎的原因。
  • 较少的培训时间:更快的周转时间
  • 可比较的准确性:正如许多研究论文中指出的,它的预测准确性对于许多应用来说是相当高的。

当一个人必须快速交付一个具有相当准确结果的解决方案时,k-NN 是一个救命稻草。在大多数工具中,如 MATLAB、python、R,它是作为一个单行命令给出的。尽管如此,这是非常容易实现和有趣的尝试。

R 图的源代码

library(ElemStatLearn)
require(class)**#Data Extraction**
KVAL <- 15
x <- mixture.example$x
g <- mixture.example$y
xnew <- mixture.example$xnew**#KNN and boundary extraction**
mod15 <- knn(x, xnew, g, k=KVAL, prob=TRUE)
prob <- attr(mod15, "prob")
prob <- ifelse(mod15=="1", prob, 1-prob)
px1 <- mixture.example$px1
px2 <- mixture.example$px2
prob15 <- matrix(mod15, length(px1), length(px2))**#Plotting Boundary**
par(mar=rep(2,4))
contour(px1, px2, prob15, levels=0.5, labels="", xlab="x", ylab="y", main="", axes=TRUE)**#Plotting red and blue points**
points(x, pch = 20, col=ifelse(g==1, "coral", "cornflowerblue"))gd <- expand.grid(x=px1, y=px2)
points(gd, pch=".", cex=0.001, col=ifelse(prob15>0.5, "coral", "cornflowerblue"))
legend("topright", pch = c(19, 19), col = c( "red","blue"), legend = c( "Class 1", "Class 2"))
title(main="Boundary for K=15", sub="ii", xlab="Feature 1", ylab="Feature 2")
box()

线性回归入门

原文:https://towardsdatascience.com/laymans-introduction-to-linear-regression-8b334a3dab09?source=collection_archive---------8-----------------------

当你的数据遵循直线趋势时,线性回归是你的朋友

线性回归试图通过将线性方程(=直线)拟合到观察到的数据来模拟两个变量之间的关系。一个变量被认为是解释变量(如你的收入),另一个被认为是因变量(如你的支出)。

Photo by M. B. M. on Unsplash

线性回归所做的就是简单地告诉我们一个任意的独立/解释变量的因变量的值。例如,基于 Twitter 用户数量的 Twitter 收入。

从机器学习的角度来看,这是可以在你的数据上尝试的最简单的模型。如果您预感到数据遵循直线趋势,线性回归可以给你快速且相当准确的结果。

Jorge Cham

简单的预测都是线性回归的情况。我们首先观察趋势,然后根据趋势预测,例如,你必须刹车的力度取决于你前面汽车的距离。然而,并非所有情况都遵循线性趋势。例如,从 2015 年到 2016 年,比特币的上涨是线性的,但在 2017 年,它突然变成了指数级的。因此,线性回归无法很好地预测 2017 年后的比特币

因此,重要的是要理解,即使线性回归可以是理解数据的第一次尝试,它也不总是理想的。

这是我们做线性回归的方法

  1. 我们将因变量(y 轴)与自变量(x 轴)相对照
  2. 我们试图绘制一条直线,并测量相关性
  3. 我们不断改变直线的方向,直到得到最佳相关性
  4. 我们从这条线推断出 y 轴上的新值

外推是基于“一些信息”来“做出预测”

这对于区分作为统计技术的线性回归和作为机器学习算法的线性回归是至关重要的。ML 更关心预测,统计更关心参数推断

术语方面

预测' =因变量
'一些信息' = 自变量。

Extrapolating

线性回归为您提供了一条直线,让您推断因变量

示例—啤酒控制

线性回归的核心是一种寻找代表一条线的参数值的方法。

方程 Y=mX+C

根据坐标几何,如果因变量称为 Y ,自变量称为 X ,那么一条直线可以表示为 Y = m*X+c 。其中 m 和 c 是两个数字,线性回归试图计算出这两个数字来估计白线。

看下图。假设你决定意识到自己喝了多少酒。

你看到了什么?你每月大约喝多少啤酒?一个简单的观察显示你每个月大概喝 9-10 品脱(不错!).

你认为趋势线会是什么样子?年底有多少啤酒?

120 Beers in a year. Imagine that!

一个简单的线性回归显示了我们可以清楚地看到什么。Y = 10.027X + 0.0455 = > m=10.027,c = 0.0455

c 是一个很小的数,所以现在我们忽略它。看看这个直线方程告诉我们,每个月我们要喝 10.027 瓶啤酒。这就是趋势。我在 MS PowerPoint 中推导出了这个等式,但是我们如何用数学方法来推导呢?

机器学习工程师是如何做到这一点的?

线性回归的一般方程

https://xkcd.com/1725/

请原谅我。这一部分有一点数学,但我们将轻松地通过它。

线性回归是监督学习的一种形式。监督学习涉及那些我们使用现有数据来训练机器的问题集。在啤酒的例子中,我们已经知道了前 10 个月的数据。我们只需要预测第 11 个月和第 12 个月的数据。

线性回归可能涉及多个独立变量。例如,房价(依赖)取决于位置(独立)和土地面积(独立),但其最简单的形式涉及一个独立变量。

在其通用形式中,它被写为

其中所有的阿尔法都是我们的机器学习算法需要计算的系数。x 是已知的,因为它们是独立的。我们可以给他们设定任何东西。我们需要找到的是 Y

对于单个独立变量,方程简化为

Simple Linear Regression

为简单起见,x0 设为等于 1,alpha0 命名为 c。x1 称为 x,alpha1 = m。它简化为:

Simple Linear Regression written slightly differently

行话

为了算出 mm和 c我们画了一条线,使用 m 和 c初始猜测通过我们已经有的一组点。我们计算这条线到这些点的距离。我们取这些距离 ( 成本函数)*方和的*方根。我们不断地改变 m 和 c,看看这个成本函数是否减少。当成本停止下降时,我们确定 m 和 c 为最终结果。得到的线是我们对数据的最佳线性拟合。现在对于任何新的 x,我们可以用这条线算出 y。**

这个行话的意思是,我们不断地重画这条线,直到它看起来最符合数据。这就是所有需要的行话。

机器学习

下面我们有一个人口与利润的数据集。我们画一个散点图,并试图拟合一条穿过它的直线。仔细观察最初的猜测(蓝线)如何向数据所遵循的趋势转变。还要看看需要多少次迭代才能达到 5.87 的稳定成本

它以 32 英镑的价格开始,最初的猜测差得很远!

从那时起,情况稳步改善。经过 200 次迭代后,成本已经减半。

400 次迭代后,成本是 1/3

在 600 次迭代时,猜测进一步提高

在 1000 次迭代之后,成本的降低已经减缓,并且拟合或多或少是稳定的

经过 3000 次迭代后,我们确信我们有一个很好的拟合

c = 0.02, m = 0.8

就这么简单!显而易见的是,线性回归是一种基于遵循线性趋势的数据进行预测的简单方法。因此,如果我们要拟合正弦曲线或圆形数据集,我们将会彻底失败。

最后,对于初学者来说,线性回归总是很好的第一步(如果数据在视觉上是线性的)。这绝对是一个很好的第一个学习目标!

来自我们数据科学团队初级成员的领导力课程

原文:https://towardsdatascience.com/leadership-lessons-from-my-administrative-assistant-a62e5422e103?source=collection_archive---------23-----------------------

如果你知道如何去寻找,智慧无处不在

Photo by Annie Spratt on Unsplash

我们都从老板那里学到了领导力的课程。优秀的老板通过他们正面的榜样力量教会我们应该做什么。让我们对自己和自己在组织中的位置感觉良好的事情。我们满怀希望地认识到这些时刻是什么,并在心里记下“更像那样”或“在这种情况下为某人做那件事”。

我们也从坏老板的有力例子中学习。有时,这些问题更加突出,因为我们花了大量时间关注那些让我们不舒服或让我们感觉比互动前更糟糕的人和情况。

我们对这些时刻有着强烈的记忆,通常会详细了解那些老板应该采取不同的做法,或者没有做的事情,以及这些事情如何直接影响我们和公司(特别是当我们花时间与同事一起同情那个老板时)。)

但是有一天,我意识到我从观察我们数据科学团队初级成员的互动和行动中学到了多少。这是一个混合角色,充当入门级数据分析师和支持角色,帮助完成许多管理任务。

有时很容易忘记我们刚开始职业生涯时是什么样子。我们是多么兴奋,但也是如此天真。回想起来,我有时会想,我到底有多少次说错话了,或者因为兴奋多于经历而出丑了。但我也发现,我还是更希望我的团队里有具备这种组合的人,而不是那些把自己的入门级工作视为阻碍他们获得“实际上应得的”职位的人。

这里的教训是做好你的工作。花时间把它学好,而不是不停地去找你想要的工作。在你掌握了你面前的东西之后,你会有时间去做的。

几周前,我参加了一个由中层员工组成的领导小组。当我战胜自己的冒名顶替综合症,试图传达一些可能对他们的职业生涯有所帮助的有用建议时,我选定了一个我经常提到的主题:每个人都是自己故事中的英雄

我不记得我是在哪里第一次遇到这个想法的,但它一直是我生活中一个有用的工具。本质是每个人都在做自己认为好的事情。每个人都在接*这个世界和他们的工作,好像他们是这个世界的中心。

此外,他们告诉自己关于他们周围世界的故事是一个他们是英雄的故事。在故事的特定情节中,他们的英雄可能是受害者、被误解的天才或白衣骑士……但他们不认为自己是小人物或坏人。

我坚信每个人都想把工作做好并产生积极的影响。我还不至于无知到相信他们总是这样做,或者相信他们的“正确”观念是每个人都认同的。但这个想法的简单本质是,很少有人带着做“坏事”的意图来到这个世界,考虑这种情况几乎是浪费时间。

相反,我认为一个人的每一个行动和努力都是因为他们认为那是“应该做的事情”。有时这是因为对世界的自私或受伤的理解,但关键是他们觉得在他们的思想中是合理的。

作为一名领导者,这意味着虽然我并不总是同意他们的行为和观点,但我至少应该试着理解他们的观点,这样我才有希望理解他们的动机。

我经常发现,对组织有害的行为和感觉源于缺乏共同的理解或目标。这些情况是最容易补救的,也是对所有领导人的一个很好的提醒,除了“是什么”之外,还要花更多的时间谈论政策或过程的“为什么”。

在某些情况下,个人和组织之间存在更基本的价值冲突,但这种情况非常罕见。在某些情况下,理解这一点可以导致更和谐的局面,经理和员工可以达成更好的共识。在其他情况下,最好是让员工跳槽到一个更符合他们价值观和动机的组织。快速发现这一点可以为团队节省很多困难和干扰。

本质上,这种方法让我不再认为我的团队成员和我有相同的热情和动机,而是更加流畅地尝试识别他们独特的动机。

这让我能够对我认为需要做的事情达成共识,并与他们产生共鸣。这也有助于我更好地识别机会和挑战,根据他们所处的位置、他们重视和喜欢的东西以及他们希望获得的经验来分配给不同的人。

前几天,当我看到我们的初级数据科学成员与同事互动时,我注意到了几件重要的事情,这就是为什么她是团队中一个优秀的人,并且提醒我们应该如何对待自己的工作和领导。

看到更大的目标:她很忙,但是当人们把他们的问题和工作带给她时,她总是礼貌地向他们表示感谢。她意识到他们并没有让她分心,而是为了实现组织的目标而必须做的事情。她当时的具体任务可能不同,但更大团队的需求是重要的工作。

投入超越你的具体职位:除此之外,她清楚地知道自己的职责是什么,但她会毫不犹豫地承担她认为需要完成的额外工作。

培养你周围的人:然而,她也认识到,当有人给她带东西时,她不一定要自己做。在这种情况下,她会花时间训练把它带给她的人,而不仅仅是做这件事。她知道这通常会在最初花费更多的时间,但从长远来看,这对她和公司都有好处。

没有自我:她很谦逊。非常强烈。对于她的职位来说,她受了过多的教育,资历过高,但是没有什么任务是她力所不及的。她知道有时即使是最高级的管理人员也需要复印或运行幻灯片。因此,如果被要求为演示整理图表,而不是研究新的机器学习模型,她连眼睛都不会眨一下。

不断学习:然而,她也意识到她需要学习的东西太多了。她总是渴望帮助完成一个项目,或者志愿做一些其他的事情,因为她知道这些都是学习一些关于组织和她的工作的新东西的机会。也许帮助构建一个非常大的 SQL 查询将允许她更好地学习数据库,并在组织中获得更多的领域知识。

她意识到,作为一个配角,你的时间就是别人的时间。事情不可能总是被安排得井井有条,并按照她能做到的方式处理。有时候,她需要在运行中重新确定优先级。根据我的经验,太多的领导者忘记了这也适用于他们。也许这意味着她每天花更多的时间来帮助获得供应品、软件或书籍旅行,而不是从事高调的数据分析。

如果我们花时间真正尝试通过别人的眼睛来看待这个世界,我们可以了解他们、这个世界和我们自己。作为一名领导者,在工作场所应用这一点将提高你的情商,并本能地将你拉出自己的观点和视角,以更好地了解你的团队。

除了学习如何支持他们并让他们为组织提供最好的帮助,你还将学习如何最好地领导团队,并更好地了解自己的行为如何影响他们的日常生活。

如果你还不是一个领导者,也许处于初级职位,你的观点是什么?你是否珍惜你现在的位置,并利用每一个机会去学习和获得更好的经验?或者你希望自己处于另一个位置,从事更高层次的项目?

态度很重要,我们对待工作的方式会引起经理和同事的共鸣。即使任务可以完成,也很少有组织目标可以通过个人努力来完成。因此,我们对团队的贡献至关重要。

当你不是数据科学家时,领导一个数据科学团队

原文:https://towardsdatascience.com/leading-a-data-science-team-when-you-are-not-a-data-scientist-540db8fa9acf?source=collection_archive---------18-----------------------

这不仅仅是克服冒名顶替综合症,还有真正的价值。

Photo by Mubariz Mehdizadeh on Unsplash

我们很多人都很了解这种感觉。或者有一天你会的。你已经进入了一个全新的职位。你被雇用或提升是因为你在公司的不同部门工作。在许多情况下,你的第一个领导角色是领导一个由个人贡献者组成的团队,而你也曾经是其中的一员。很可能你在那里得到了晋升,学习了工作、文化和组织中的成员。

但是现在你被提升到一个不同的角色。您对这一部分有些熟悉,但并不真正了解。你不了解这个团队,你也不确切知道他们都做什么以及他们是如何做的。

你习惯于在任务上培训你的团队,因为你过去常常自己做任务…现在你不能这样做了。你甚至不能总是理解他们是如何做他们所做的事情的。

这是我在管理一个数据科学团队时的样子。我的背景是社会科学和政策。我以前从未在我的硕士学位的一些 Stata 之外编写过代码(在 Stata 中使用“编码”是有争议的),我的大多数数学和统计都是基于社会科学研究的。老实说,我通常在研究和工作中更倾向于定性方法。

现在,我正和一个团队坐在一起,试图了解他们是如何收集数据并将其编译到仪表板中的。我不仅需要尽快理解这一点,还需要帮助他们更好地完成工作,为组织增加价值。我真的不确定从哪里开始。

幸运的是,我最*开始了一个博士项目,对绩效评估、基于证据的政策和数据分析领域越来越感兴趣。这至少让我熟悉了“数据科学”这个术语。

此外,我对自己进入这个职位有一个很好的计划。我根据迈克尔·沃特金斯的《前 90 天》制定了这个计划。关键的一点是为自己制定一个学习计划。

这做了三件重要的事情。首先,它确保你有意识地了解你在新工作中需要学习的人、事和关系。第二个,它让你的新团队看到你是带着虚心向他们学习的态度来的,而不是认为你已经什么都知道了。最后一点,它给你一天中的时间和空间去真正了解你的团队在做什么以及他们是如何做的。

好好利用这段时间,它会在以后极大地帮助你。你还会惊讶地发现,通过这种方式,你会对团队和组织有更多的了解,而不仅仅是安排一对一的会议。真正利用优势,投入到工作中,努力做出实际贡献,而不是走过场。

在我自己的例子中,这就是我如何更熟悉团队使用的工具。SQL、R、Python 和 Tableau 以前对我来说都是陌生的。这也让我明白了我如何能够为团队增加价值。稍后会详细介绍。

在办公室之外,也为自己制定一个学习计划。有你应该读的书吗?你应该参加的会议或大会?你应该学的课程?

记住,你不需要成为技术专家…那不是你被提升的原因。但是你需要有足够的熟悉度来理解团队在做什么以及他们是如何做的。

当我完成新职位的学习计划时,我对团队的能力和未来工作的可能性有了更多的了解。

在我的博士项目研究中,我还专注于将数据分析、决策科学技术和机器学习过程应用于政府政策和项目。

不管是不是有意的,我在外面的研究和工作学习之间有了一个美丽的重叠。与基于大量优秀资源的一些数据科学优化建议相比,我还受益于对我团队组织结构的了解。

我们的团队有几个成员已经在这个组织工作了一段时间,他们主要致力于提供描述性的统计数据。我们也有几个新成员,他们是因为在一些涉及机器学习和预测分析的特殊项目中的技术技能而加入进来的。缺少的是团队的明确战略和我们可以为整个组织改进的关键领域。

这是我的“电灯泡”时刻。这发生在我开始工作的几个月后。这是我的主要观点:在开始一个新的职位时,如果不努力寻找早期和明确的成功,以向你的老板、你的团队和你自己展示你确实配得上你的角色,这真的很难!

然而,根据我的经验,作为一名领导者,你所做的有价值的工作需要的时间比你想象的要长。你需要时间来建立必要的理解和知识,以提供实际的战略愿景或洞察力。耐心做好工作,它会来的。

接下来的步骤也需要时间。仅仅因为你有一些战略洞察力或远见,并不意味着你会迅速重组团队,将他们转向所需的任务,并开始向这个新的方向推进。

作为一名高级领导,我学到的一件令人惊讶的事情是,我必须投入多少工作来“推销”我的愿景,并向团队中的其他人解释它。这不仅仅是买入,你头脑中如此坚定的愿景对其他人来说要难得多。我曾天真地认为,仅凭我的头衔就能为我完成这项工作。我错了。

在此阶段,有两个主要策略要遵循:

指令。你可以非常直接,简单地将组织或团队指向你的目标,并密切监控所有工作,以确保它符合设计。

许多人会将这种策略视为微观管理或独裁,但重要的是要注意,在某些情况下这是可行的和首选的。

例如,在一个组织的危机情况下,或者当有不灵活的需求和时间表时,这可能是一个非常有用的策略。史蒂夫·乔布斯因运用这一策略而闻名(或声名狼藉)。有时它会带来成功,但也会让他陷入低谷。小心这个策略!

支持的。另一种策略通常包括帮助团队作为一个小组来讨论和决定策略。这可以通过多种不同的方式来实现,但通常涉及促进小组工作,旨在确定成员对所需输出和内部约束的看法,以确定他们认为组织可以实现和合理的目标。

这将花费比指导更长的时间,但有利于在团队中建立基于他们所有观点的共同愿景。这也有助于领导者避免因忽视细微差别和团队掌握的信息而犯错误。

根据我的经验,在大多数情况下,支持策略是应该遵循的途径。请记住,虽然可能有一些关键的团队成员需要一些额外的指导推动,让他们中断他们的日常工作或承认盲点。这种情况通常发生在长期团队成员身上,但也常见于拥有深厚技术知识但缺乏领域知识或对组织缺乏了解的新成员。

当我们的团队一起工作来确定当前的工作需求和痛点时,他们达成了共识,即我们可以利用团队中的新工具和技能来改进和自动化数据报告需求。这将释放我们的资源,然后处理许多以前不可能的新项目。

我对团队的愿景和价值来自这里。我确保团队明白他们的努力是多么有价值,但也解释了他们如何能更好地生产工具,以他们不知道的方式帮助组织。

我已经对他们的知识和技能有了足够的了解,可以向他们解释机器学习项目的不同用例,这些用例与组织的首要任务直接相关。

此外,我还帮助他们了解我们需要如何向领导层展示数据分析的结果和信息,以便他们可以在决策中使用。

最后,我确保在我们着手这些新项目时,我用我的观点和理解来确保所有相关的利益相关者都参与进来,而不仅仅是那些与我们有良好工作关系的人。

在这长达数周的过程中,我还不断与我的老板沟通,以确保他们理解、同意并支持我们的战略。这确保了我们甚至在提交最终战略计划供他们批准之前就获得了他们的认可。

这次经历给了我一些宝贵的教训。

当你加入一个数据科学团队时,不要被自己知识的匮乏所淹没。即使你有数据科学背景,也有你不擅长而别人擅长的领域。有不同的技能组合和需要的角色。找到你的,并专注于在此基础上增加价值。作为一名领导者,你还需要专注于团队的目标,并确保你在团队中拥有不同的技能来实现这些目标。

对自己要有耐心。很多时候,当我们加入一个新团队时,我们会强烈地感到需要有所作为。作为领导者和个人,要认识到在投入生产之前花时间彻底学习的价值。你可能会觉得自己是团队的负担,但从长远来看,你会更有用。

充当桥梁。作为一名领导者,尤其是数据科学团队的领导者,确保将组织的观点和需求带到团队中。帮助他们看到优先事项和目标,然后挑战他们找到让他们的技能帮助实现这些目标的方法。在这里,我并不总是成功,但即使是那个错误也让我明白了这有多重要。

预测心脏病死亡率

原文:https://towardsdatascience.com/leading-causes-of-death-in-the-united-states-39fb0e6bd755?source=collection_archive---------29-----------------------

深入分析

作为美国死亡的主要原因,我们使用机器学习来识别高危状态。

疾病控制中心(CDC)的国家健康统计中心(NCHS)维护着一个按年龄调整的死亡率数据库,并统计了全美十大死亡原因。按照原因、州和年份分组,数据可用于 1999 年至 2016 年,前 10 位死亡原因如下:

  • 阿尔茨海默病
  • 巨蟹星座
  • 慢性下呼吸道疾病(CLRD)
  • 糖尿病
  • 心脏病
  • 流感和肺炎
  • 肾脏疾病
  • 中风
  • 自杀
  • 意外伤害

通过 CDC 网站的 HTTP GET 请求访问完整的数据集。

Sample of 2016 data for New York.

因此,人口统计和人口数据可以得到适当的解释,死亡人数将被用来代替年龄调整率。为了计算人均死亡人数,纳入了来自 CDC 跨种族人口报告工具(WONDER) 的数据,该工具按年份、州、年龄组和性别对人口计数进行分组。将这个数据与死亡统计数据结合起来,人均死亡人数可以按州,按年计算,我们可以开始问一些问题。

目标

最终,目标是确定自 1999 年以来美国的主要死亡原因,然后确定 2019 年应被视为高风险的州。为了指导分析,需要回答四个具体问题:

  1. 在美国,导致死亡的主要原因是什么?
  2. 主要死亡原因的当前趋势是什么?
  3. 哪些因素对这些比率影响最大?
  4. 今天哪些州应该被视为高风险?

我们开始吧!

在美国,导致死亡的主要原因是什么?

如下图所示,根据 1999-2016 年的数据,美国的主要死亡原因是心脏病,占主要死亡原因的 34%。紧随其后的是癌症,占另外 30%。

然而,确实想到的一个问题是心脏病和癌症之间的差异是否有统计学意义。换句话说:年率的正态方差解释这种差异的可能性有多大?对这个问题进行了双尾学生 t 检验,得到的 p 值为 0.00008 表示 A 偶然遇到这样结果的概率小于万分之一。考虑到这一点,继续分析心脏病是安全的。

主要死亡原因的当前趋势是什么?

在州和国家两级审查了这方面的趋势。所有州和年份的最小和最大记录比率被用来限制结果,并获得一段时间内的相对变化。在下面的时间间隔中,绿色代表人均死亡人数最低,而红色代表最高。地图下方的图表显示了同一时期全国的死亡率变化。

由此可以很容易地观察到,总体比率一直在提高,大部分红色和橙色变成了绿色和黄色。国家一级的明显下降趋势进一步证实了这一点。这是个好消息,但是这种趋势是否会持续到未来还需要确定。

为了实现这一目标,研究对心脏病影响最大的因素是很重要的。

哪些因素对这些比率影响最大?

在对该主题进行了一些一般性研究后,决定将重点放在三个方面:

  1. 人口统计学(特别是年龄和性别)
  2. 饮酒
  3. 吸烟

明确地说,这些领域仅仅代表了可能性的一个子集,它们可能被合并到模型的未来版本中。

这里最大的挑战在于收集数据。虽然年龄和性别信息包含在疾病控制中心的人口数据中,但酒精和吸烟的数据还需要进一步挖掘。幸运的是,没有什么是一点研究和网络搜集不能处理的。

吸烟数据可从联合健康基金会获得,年度数据保存在单独的 CSV 文件中。吸烟率本身定义如下:

吸烟的成年人百分比(据报告一生中至少吸烟 100 支,目前每隔一天或几天吸烟一次)

通过网站 API 快速浏览相关年份,可以轻松访问这些数据。剩下的工作就是在本地保存每个文件,将数据连接到一个数据框架中,并执行一些基本的清理工作(删除全国汇总的行,检查数据类型,并选择相关的列)。

Sample of smoking rate data in New York.

很快就会出现问题的一件事是,人们意识到数据源在 2014 年发生了变化。进一步调查显示,收集数据的方法实际上在 2012 年发生了变化,新方法更加准确。然而,这也造成了一种错觉,即在此期间,美国的吸烟率突然飙升。出于本分析的目的,吸烟率的逐年变化比实际吸烟率本身更重要,因此决定解决差异的最佳方法是调整 2012 年及以后的数据,使其与前一年的趋势更加一致。全国范围内的结果如下。

关于酒精消费,可从国家酒精滥用和酒精中毒研究所获取数据。这里的酒精消耗量报告如下:

各州的人均乙醇消费量。[加仑乙醇,基于 14 岁及以上人口。]

此外,酒精消费按饮料类型(啤酒、葡萄酒和烈酒)进行细分。该组织网站上的数据分布在一个 16 页的表格中,因此需要一些漂亮的网页抓取。上面的链接指向数据的第一页,以给出结构的感觉,但 html 的截图和样本也应该有所帮助。

最上面一行使用 strong 标签来标识州名,后面是年份行,相关数据由 datagraydata 类标识。这个特定的行将每年重复 40 次,然后显示下一个州。然而,整个表也被包装起来,并用强标签标记,这意味着对于每个新页面,也将有一个表名而不是州名。下面的代码块用于解析所有的 html 并将结果保存到 dataframe 中。

既然困难的部分已经过去,数据可以与现有的吸烟、人口统计和疾病预防控制中心的数据结合起来开始分析。在这一点上有 20 个预测变量:每个年龄组、性别、吸烟率和饮酒率各有一个。另外两个更令人好奇的预测指标也包括在内:人均糖尿病死亡人数和人口密度。这些变量的重要性被证明是最小的,尽管后者至少提供了一个相关的见解,这将在后面触及。

所有数据都经过了缩放和对数转换,结果可以用*衡的百分比表示。结果分布如下所示:

虽然某些参数确实表现出一些偏斜,但总体上相当*衡,在稍后将数据输入预测模型时,没有表现出明显的问题。所以,现在终于有可能将数据输入回归模型,找出对死亡率影响最大的因素。在多重线性回归中使用了 4 个预测因子的所有可能组合,以寻找最高的调整 r *方值。最终,四个变量被发现可以解释 83.4%的心脏病死亡率差异:吸烟率、75-79 岁年龄组、葡萄酒消费量和性别。这里至少有一个结果会让你大吃一惊。

最不令人惊讶的项目在底部:随着越来越多的人口达到 75-79 岁年龄段,越来越多的人口可能死于心脏病。从行为的角度来看,吸烟表现出同样类型的关系。

然而,更出乎意料的是,男性似乎比女性更不容易死于心脏病。这并不一定意味着男性较少患心脏病,只是意味着他们死于心脏病的可能性较小。根据疾病控制中心的说法,

尽管在过去几十年中人们的意识有所提高,但只有大约一半(56%)的女性认识到心脏病是她们的头号杀手。

所以,对于那些不知道的人来说,这是一个公共服务公告。

另一件令人惊讶的事情是,饮酒似乎对心脏病死亡率没有太大影响。事实上,数据表明,增加葡萄酒消费实际上可以降低这些比率。现在,在你跑出去买你最喜欢的一瓶红酒之前,提醒你一句:葡萄酒消费量的增加也被观察到与吸烟率的降低相关。因此,很可能不一定是葡萄酒消费,而是饮酒者吸烟率的降低导致了心脏病死亡率的降低。

这一点在下面的关联热图中得到了证实,其中深蓝色方块表示强烈的负关联,亮红色表示强烈的正关联。最左栏中的方块重申了回归模型中已知的内容。

今天哪些州应该被视为高风险?

我们几乎准备好建立一些模型并进行预测,但有两个问题需要解决。一、高危是怎么定义的?出于本分析的目的,高风险州将被定义为在所有数据范围内人均死亡人数处于所有比率前 33%的州。相反,低风险州是那些利率在底部 33%的州。将需要额外的领域专业知识来调整目标变量以反映行业标准,尽管这不应该降低模型本身的有效性,如果它们产生有希望的结果的话。

然而,第二个问题更具挑战性:我们的目标是对 2019 年进行预测,但只有 2016 年的数据。试图根据同一年获得的信息做出预测是不太现实的。虽然回顾过去有助于获得理解感,但展望未来却毫无用处。那么,解决办法是什么呢?时间滞后!

实际上,假设 2016 年的数据大约在 2017 年年中可用,但可以很容易地进行调整,以考虑这方面的差异。如果一个模型能够根据这些信息做出可靠的预测,那么组织将有一年半的时间来计划预期的变化。此外,该模型在进行预测时也不应该简单地忽略 2015 年和 2014 年的数据。所以,需要做的是使用 3 到 5 年的数据时滞,并将其作为当年死亡率的预测指标。结果将是预测变量的 3 倍,从 22 到 66。为了获得规模感,下面的关联热图突出了每个变量之间关系的性质。在这一点上,围绕多重共线性的问题将被搁置,这是因为预计会有相当数量的自相关。但是,也应该捕获 3 年窗口内的一致变化,这些变化是模型预测的主要关注点。

现在,试图用这么多预测变量建立一个模型将是非常低效的,尤其是在 13 英寸的笔记本电脑上。因此,进行了主成分分析(PCA ),以确定解释数据中 99%方差的最小特征组。因此,66 维的数据可以减少到 19 维。剩下的唯一事情就是建立模型,用最好的模型进行预测。

构建、训练和测试了六种不同的模型类型,出于测试目的保留了 20%的数据:

  • 决策树分类
  • 逻辑回归
  • 支持向量机
  • 随机森林分类
  • adaboost 算法
  • XGBoost

剩下的 80%使用 5 重交叉验证进行训练。此外,我们还对每个型号进行了网格搜索,以找出表现最佳的型号,结果产生了 1,413 种不同的型号变体。

除非在课堂回忆或精确度分数上有任何明显的不*衡,F1 分数被选为精确度/性能的主要衡量标准。最终,有一个模型在所有方面都明显优于其他模型:支持向量机。如下所示,它对所有截面的测试数据都达到了 90%的准确率。然而,当根据以前从未见过的测试数据进行预测时,该模型被证明更加有效,达到了几乎 92%的准确率。

另一项值得注意的是,该模型在精确度方面的表现确实优于召回率,这种差异在高风险状态的预测中最为突出。为什么这很重要?在进行这些类型的预测时,高估风险水*比低估风险水*要好。精确度和回忆分数表明这正是模型容易出错的地方。

完成所有这些后,现在可以使用 2014-2016 年的数据对 2019 年进行预测,并对预测的可靠性有所了解。在下图中,红色、黄色和绿色代表基于实际死亡率的 2016 年实际风险水*。红色代表高风险,绿色代表低风险。时间推移侧重于预计将改变风险水*的状态,并显示 2019 年的预期结果。

这里的结果有点复杂:四个状态从极端移动到中心,而两个状态从中心移动到极端。马萨诸塞州和马里兰州从低风险到中等风险,而密歇根州和宾夕法尼亚州从高风险到中等风险。伊利诺伊州和田纳西州走向相反的极端,分别从中等风险水*到低风险和高风险水*。但是有一个州特别突出:俄克拉荷马州。

俄克拉荷马州在 2016 年是一个高风险州,所以看到它这么快就被预测为低风险是一个很大的惊喜。经过更仔细的检查,很明显,这一变化的原因是吸烟率从 2010 年的 25.5%下降到 2015 年的约 19%,创历史新低。

目前尚不完全清楚这些结果是如何实现的,尽管该州卫生与公众服务部部长特里·克莱恩(Terry Cline)表示,这至少可以部分归因于该州的禁烟令,以及那些选择加入认证健康俄克拉荷马州计划的组织的商业地产。这绝对值得仔细看看他们在做什么,看看这些结果是否可以在其他地方复制。

再缩小,可以看到整个国家的 2019 年预测图。

最引人注目的是预测风险水*的地区差异。在这 9 个州中,有 8 个在 2016 年已经属于高风险类别,田纳西州今年被添加到列表中。那么,这些州能做些什么来降低各自社区的风险水*呢?

推荐

正如俄克拉荷马州所展示的,这些州所能做的最好的事情就是集中精力降低吸烟率。区域的接*性表明,如果俄克拉荷马州的项目在任何地方都有效,那将是在这些可能有相当多文化重叠的州。

此外,针对退休人员和女性的心脏病宣传活动也大有可为。数据中的另一项观察表明,在人口密集地区,妇女占人口的比例更大。因此,在城市中更加重视这些运动可能会产生更好的效果。

当然,看看这些结果是否可以进一步改善也是件好事,特别是在纳入种族数据和人群饮食习惯的情况下。可能性几乎是无穷无尽的,但潜力是显而易见的。

最后的想法

心脏病是一种在生活中的某个时刻影响到大多数人的疾病。也许你已经被折磨了。也许某个朋友或家人是幸存者,还在挣扎,或者已经去世。对我来说,那是一个两个月前因心脏病发作去世的叔叔,他还不到 60 岁。根据疾控中心:

  • 在 2005 年的一项调查中,大多数受访者(92%)认为胸痛是心脏病发作的一种症状。只有 27% 的人知道所有的主要症状,并知道在有人心脏病发作时拨打 9-1-1。
  • 大约 47% 的心源性猝死发生在医院外。这表明许多心脏病患者不会对早期预警信号采取行动。

如果只有一件事是你从这件事中学到的,我希望它是让你自己检查一下,让你自己意识到可能使你处于高风险水*的因素。

参考

Jupyter 笔记本和这个项目使用的所有资源都可以在 Github 上找到。

精益+数据科学

原文:https://towardsdatascience.com/lean-data-science-8dda17663ca7?source=collection_archive---------24-----------------------

TL;dr
1。数据科学实践充满了浪费
2。明确的假设检验有助于微调想法
3。沟通是将数据科学家融入软件开发生命周期的关键

我加入这个领域是因为我们在发现新的数据模式时感到兴奋。然而,随着时间的推移,很明显,识别模式只是这个旅程的前半部分。还有一部分,是关于分享这个发现的。“分享”可以是展示的形式,可以是现有产品的改变,甚至是全新的产品。因此,这两个部分——从创意到产品的培育——是数据科学的完整堆栈。

在这篇文章中,我分享了我关于如何以有效的方式将机器学习模型构建到软件中的经验。在进入细节之前,让我们提出一些基本的假设:

  • 产品开发需要钱。一些公司有更多,一些有更少,但是,他们都希望看到他们的投资回报。
  • 产品开发需要时间。时间是普遍短缺的;因此,我们应该确保在我们突然用完的时候有一些投资回报。
  • 产品开发天生具有不确定性。我不知道我们刚刚开始开发的产品的最终功能集会是什么,可能连客户都不知道。在这种情况下,我们可以做两件事:1)诚实,一起发现 2)假装我们知道市场想要什么(而且往往失败得很惨)。

数据科学中的精益产品开发

精益制造在多个行业都有良好的记录。尽管它最初是作为汽车工业的方法论而形成的,但是由于 Mary 和 Tom Poppendieck 的杰出工作,它已经扩展到软件开发中。精益的核心原则是减少过程中的浪费,以最大限度地提高生产率。Poppendiecks 指出了软件的七种浪费。他们在这里,锚定数据科学实践。

  1. 部分完成的工作。我认为大多数 Jupyter 笔记本是最好的例子。它们是部分完成的工作,因为您通常既不添加文档也不添加测试。重要的是,这不是过去的浪费:而是未来的浪费。每次有人想知道那本笔记本的用途时都浪费时间?浪费每次有人想建立它,结果是你离开了一个非线性运行的细胞。
  2. 额外功能。不久前,我们真的在推动一项功能的推出,因为我们想证明它是可行的。成功了。不幸的是,我们没有看到问题不是怀疑该功能从机器学习的角度来看是否可行,而是怀疑它在市场上是否可行。因为这个误会,我们浪费了两个星期的努力和时不时几个小时的维护。
  3. 重新学习。一个简单的例子是,每个人每次都从头开始编写代码,但是这些代码非常复杂,需要花两个小时来重新实现。想想读取数据,建立交叉验证等。
  4. 交接。这和重新学习有点不同,因为这是你无法避免的。不过,代码切换可以作为一个过程进行优化。我经常看到的一个重要的交接地点是在原型和产品数据团队之间。
  5. 任务切换。您很匆忙,这是通常的情况,所以您决定同时处理两个功能。也许你这样做是因为,否则,你会觉得你会花太多时间在一件事上,而没有时间做第二件事。
  6. 延期。预算、分配、等待 QA、等待模型训练、等待测试通过等等的批准时间。虽然在这种时候,如果人们能放松 10 分钟是最理想的,但通常这是不会发生的。相反,由于沮丧,他们开始解决它(例如,开始实现下一个特性)。
  7. 缺陷。损失去南;概率是 1.2;模型在不同版本中序列化,生产中缺少数据…等等。编写覆盖良好的代码并不意味着你不会面临缺陷,但是修复这些缺陷会容易得多。

我们很容易同意,减少这些浪费肯定有助于提供更可靠的输出。通常的问题是,是否有一种既省时又经济的方法来克服这些浪费。我认为关键是从第一天起就接受不确定性并为此进行设计。

拥抱不确定性

拥抱不确定性意味着接受我们不知道一切的事实。我们不知道 GAN 是否会比一些简单的仿射变换更好地用于数据生成,我们不知道我们现在的产品想法是否会引起真实客户的兴趣,我们不知道许多事情。然而,我们可以有好的实践来帮助我们在正确的时间以正确的方式回答这些问题。

Harry called everyone for a brainstorming meeting to do some market research. The aim of the meeting is to finetune the scope of the company’s next breakthrough product. Image from The Data Department

这些良好实践的基础是沟通和假设。在本系列的前一篇文章中,我已经谈到了假设的重要性。那一次是单位和系统层面的假设,在这里,我要谈谈业务单位层面假设的重要性。产品失败的最重要原因是不符合市场需求。数据科学产品经常发生的情况是,团队延迟发布,例如,模型在所有情况下都表现不佳。然后,当发布最终突然发生时,似乎没有人在乎。

这些故事背后的原因是一个错误的产品开发理念。在实现一个特性一年之前,我们首先要确定这个特性是需要的。让我们以 x.ai 是人工智能驱动的会议安排者为例。他们有关于如何用机器学习解决问题的想法,但他们没有首先从头开始实施,而是开始在人类会议安排者的帮助下测试这个概念。他们对市场需求了如指掌,正因为如此,现在他们的业务在不断增长。只有做出正确的选择,接受不确定性并减少浪费,在明确功能是否能为客户带来价值之前,不实施这些功能,这才是可能的。

数据科学的全部内容

我的一位资深同事在阅读了 TDD 帖子后问我,数据科学家的工资是多少,与他们互动的软件工程师的工资是多少,数据工程师的工资是多少。这个问题让我想到我是如何看待数据科学实践的。我认为数据科学团队是软件开发过程中的一个特殊部分。由于机器学习需要深入的数学知识(尤其是统计学),人们经常从各种非软件开发领域加入到团队中。这很好,因为这些技能传统上是软件工程研究中所缺少的。

Sometimes waste is hard to distinguish from the expertise. Image from The Data Department

然而,机器学习模型是软件的一部分,因此,它必须无缝集成。假设您已经构建了一个优秀的图像分类器,但是它不适合目标设备内存;流中的数据点没有按时间顺序到达;为了提供实时反馈,我们必须快速读取数据;模型的输出应该以一种有效且易于理解的方式显示。这意味着一名优秀的数据科学家还应该了解端到端流程。

如今,市场称这样的专业人士为全栈数据科学家(我们通常称之为独角兽)。我还可以在这里补充一点,一个人成为全栈数据科学家的最快方式是通过交流。你去软件开发人员的办公桌前问一问(同一件事连问两遍都没问题)。当 DevOps 同事解释他如何有效地解决模型部署时,您可以从他那里学到东西。你告诉数据工程师你对模型访问的新想法,也许她已经实现了那个特性或者知道它。幸运的是,我有几个同事通过这个简单的方法成为数据科学独角兽的例子。

最后,我相信在就业市场寻找独角兽之前,所有的公司都应该审视一下自己,看看是否能够培育它。答案可能是“是的,但我们没有时间做这些”,然而只有培养这种人才的文化才能发挥他们的全部潜力。

20 分钟熊猫高级功能综合指南

原文:https://towardsdatascience.com/learn-advanced-features-for-pythons-main-data-analysis-library-in-20-minutes-d0eedd90d086?source=collection_archive---------2-----------------------

熊猫终极指南——第二部分

熊猫高级功能代码指南。

Red Panda — Photo by Linnea Herner on Unsplash

我大胆假设小熊猫比它们的黑白同胞更聪明,也更高级。因此,封面图片。

在这个熊猫系列的第一部中,我们探索了熊猫的基础,包括 :

  • 如何加载数据;
  • 如何检查、分类和过滤数据;
  • 如何使用 and groupby/transform 分析数据

如果这些概念对你来说是新的,回到第一部分,快速复习一下。

[## 如何在 20 分钟内掌握 Python 的主要数据分析库

熊猫基本功能的代码指南。

towardsdatascience.com](/how-to-master-pandas-8514f33f00f6)

在今天的文章中,我们将讨论以下主题:

  1. 数据类型和转换
  2. 对某些数据类型有用的访问器方法
  3. 组合数据帧
  4. 重塑数据帧

先决条件

一个 Python 环境(建议 Jupyter 笔记本)。如果你还没有设置这个,不要担心。这是毫不费力的,不到 10 分钟。

[## 所以你想成为一名数据科学家?

到底是什么阻止了你?下面是如何开始!

towardsdatascience.com](/get-started-with-python-e50dc8c96589)

设置

Photo by dylan nolte on Unsplash

T21:在进行任何数据操作之前,让我们先获取一些数据。我们将使用一些虚构的销售数据。这个 GitHub Repo 保存了本文的数据和代码。

新建一个笔记本,导入熊猫(import pandas as pd)。我倾向于这样调整我的笔记本设置:

from IPython.core.display import display, HTML
display(HTML("<style>.container {width:90% !important;}</style>"))

这些命令使笔记本变得更宽,从而利用更多的屏幕空间(通常笔记本的宽度是固定的,这与宽屏很不一样)。

加载数据

invoices = pd.read_csv('[https://raw.githubusercontent.com/FBosler/you-datascientist/master/invoices.csv'](https://raw.githubusercontent.com/FBosler/you-datascientist/master/invoices.csv'))

①数据类型和转换

Photo by Guillaume Bolduc on Unsplash

可用的数据类型

在开始研究数据之前,让我们快速总结一下所有可用的 Pandas 数据类型。总共有七种:

  • **object**:该数据类型用于字符串(即字符序列)
  • **int64**:用于整数(整数,无小数)
  • **float64**:用于浮点数(即带小数/分数的数字)
  • **bool**:用于只能为真/假的值
  • **datetime64**:用于日期和时间值
  • **timedelta**:用来表示日期时间的差异
  • **category**:用于从有限数量的可用选项中选择一个选项的值(类别不是必须的,但可以有明确的排序)

显示数据类型

答在读取数据并运行快速invoices.sample(5)后,我们观察到数据集似乎相当大,但结构良好。

为了对数据有所了解,我通常会先从sample开始,然后是infodescribe,但是我们在这里是为了学习数据类型,现在将跳过典型的探索步骤。毫不奇怪,有一个命令可以打印出数据帧的数据类型。

**IN:** invoices.dtypes**OUT:** Order Id               object
Date                   object
Meal Id                object
Company Id             object
Date of Meal           object
Participants           object
Meal Price            float64
Type of Meal           object
Super Hero Present       bool
dtype: object

我们在没有任何类型转换的情况下加载数据,所以 Pandas 在分配类型时做出了最好的猜测。我们可以看到,除了Meal PriceSuper Hero Present之外,所有的列都是类型object(即字符串)。根据我们之前的快速检查,似乎有些列可以被分配一个更明确的数据类型。所以让我们改变这一点。

转换数据类型

有两种转换 pandas 数据类型的标准方法:

  • <column>.astype(<desired type>)
  • 转换辅助函数,如pd.to_numericpd.to_datetime

ⓐ原型

astype 速度很快,适用于干净的数据和直接转换,例如从 int64 转换到 float64(反之亦然)。
必须在要转换的列上直接调用 astype。像这样:

invoices['Type of Meal'] = invoices['Type of Meal'].astype('category')invoices['Date'] = invoices['Date'].astype('datetime64')invoices['Meal Price'] = invoices['Meal Price'].astype('int')

为了验证我们的类型转换的效果,我们再次运行invoices.dtypes:

**OUT:** Order Id                      object
Date                  datetime64[ns]
Meal Id                       object
Company Id                    object
Date of Meal                  object
Participants                  object
Meal Price                     int64
Type of Meal                category
Super Hero Present              bool
dtype: object

注:熊猫版本有点差别。对于 Pandas 版本0.23.x,可以使用.astype('datetime64')转换Date of Meal列,Pandas 将自动转换为 UTC 。UTC 格式很有用,因为它是一种标准化的时间格式,允许我们从其他日期中减去或加上日期。

然而,这对于 Pandas 版本0.25.x不再有效,我们将得到一个 ValueError,让我们知道 Tz-aware(time zone-aware)datetime 在没有进一步调整的情况下不能被转换。

ⓑ转换辅助函数

有三个pd.to_<some_type>函数,但对我来说,其中只有两个经常出现:

  • pd.to_numeric()
  • pd.to_datetime()
  • pd.to_timedelta()(老实说,我不记得我是否用过这个)

**astype** 相比,它们的主要优势在于,可以指定遇到无法转换的值时的行为。
两个函数都接受一个额外的参数errors,该参数定义了应该如何处理错误。我们可以选择通过传递errors='ignore'来忽略错误,或者通过传递errors='coerce'将有问题的值转化为np.nan值。默认行为是引发错误。

我发现没有 cutty cutter 解决方案,我通常会在做出决定之前进行调查。与你观察到的数量相比,不合适的值越少,我就越有可能强迫它们。

**pd.to_numeric()** 为了便于讨论,让我们把数据稍微弄乱一点:

invoices.loc[45612,'Meal Price'] = 'I am causing trouble'
invoices.loc[35612,'Meal Price'] = 'Me too'

invoices['Meal Price'].astype(int)现在将失败,并返回一个值错误:以 10 为基数的 int()的文本无效:“我也是。”因为没有明显的方法把字符串转换成整数。每当我遇到意外的转换错误时,我通常会显式地检查列的值,以便更好地理解奇怪值的大小。

**IN:**
invoices['Meal Price'].apply(lambda x: type(x)).value_counts()**OUT:** <class 'int'>    49972
<class 'str'>        2
Name: Meal Price

然后,您可以通过执行以下操作来识别违规的行:

**IN:** invoices['Meal Price'][invoices['Meal Price'].apply(lambda x: isinstance(x,str)
)]**OUT:** 35612                  Me too
45612    I am causing trouble
Name: Meal Price, dtype: object

从这里开始,可以快速修复这些值,或者做出明智的决定,决定如何处理失败的转换。

上面的例子是一个很好的例子,通过像这样将errors='coerce'传递给pd.to_numeric()来将值转换成np.nan是非常合理的:

pd.to_numeric(invoices['Meal Price'], errors='coerce')

现在应该注意的是,您的数据中构造有两个np.nan值,所以就地处理它们可能是个好主意。np.nans`的问题是整数列不知道如何处理它们。因此,该列将是一个浮动列。

**# convert the offending values into np.nan**
invoices['Meal Price'] = pd.to_numeric(invoices['Meal Price'],errors='coerce')**# fill np.nan with the median of the data**
invoices['Meal Price'] = invoices['Meal Price'].fillna(invoices['Meal Price'].median())**# convert the column into integer**
invoices['Meal Price'].astype(int)

**pd.to_datetime()**顾名思义,该方法将字符串转换为日期时间格式。要在一个列上调用to_datetime,你可以做:pd.to_datetime(invoices['Date of Meal'])。Pandas 将猜测格式,并尝试从输入中解析日期。它做得非常好:

**IN:**
print(pd.to_datetime('2019-8-1'))
print(pd.to_datetime('2019/8/1'))
print(pd.to_datetime('8/1/2019'))
print(pd.to_datetime('Aug, 1 2019'))
print(pd.to_datetime('Aug - 1 2019'))
print(pd.to_datetime('August - 1 2019'))
print(pd.to_datetime('2019, August - 1'))
print(pd.to_datetime('20190108'))**OUT:**
2019-08-01 00:00:00
2019-08-01 00:00:00
2019-08-01 00:00:00
2019-08-01 00:00:00
2019-08-01 00:00:00
2019-08-01 00:00:00
2019-08-01 00:00:00
2019-01-08 00:00:00

然而,有时您可能会遇到一些非典型的格式,就像上面列表中的最后一个例子。在这种情况下,您可能希望提供一个自定义格式,您可以这样做:pd.to_datetime('20190108',format='%Y%d%m')。可以把格式字符串看作一个掩码,用来检查日期字符串,如果这个掩码合适,转换就会发生。查看链接获取所有可能的日期格式组件列表。使用定制格式时,另一个值得注意的参数是exact=Falseprint(pd.to_datetime('yolo 20190108', format='%Y%d%m', exact=False))将会工作,但是如果没有确切的参数,它将会失败。Pandas 试图匹配日期字符串中任何位置的模式。

在继续之前,让我们转换我们的Date of Meal列,像这样invoices['Date of Meal'] = pd.to_datetime(invoices['Date of Meal'], utc=True)

②对某些数据类型有用的访问器方法

Photo by Todd Quackenbush on Unsplash

如果你唯一的工具是锤子,那么每个问题看起来都像钉子。

把 Pandas 访问器看作是一个属性,它充当特定于你试图访问的类型的方法的接口。那些方法是高度专业化的。他们只为一项工作服务。然而,对于特定的工作来说,它们非常优秀而且非常简洁。

有三种不同的访问器:

  • dt
  • str
  • cat

通过在选择的列上调用.<accessor>.method可以访问所有的方法,就像这样:invoices['Date of Meal'].dt.date

存取器— dt

我认为他的方法是最有用和最直接的访问器方法:

  • **date** (返回日期时间的日期值),或者
**IN:** invoices['Date of Meal'].dt.date**OUT:** 0        2015-01-29
1        2017-10-30...    
49972    2017-09-06
49973    2015-08-20
Name: Date of Meal, Length: 49974, dtype: object
  • **weekday_name** (返回当天的名称)、**month_name()** (这种实现方式有些不一致,因为 weekday_name 是一个属性,而 month_name 是一个方法,需要用括号调用)
**IN:** invoices['Date of Meal'].dt.weekday_name**OUT:** 0         Thursday
1           Monday...    
49972    Wednesday
49973     Thursday
Name: Date of Meal, Length: 49974, dtype: object**IN:** invoices['Date of Meal'].dt.month_name()**OUT:** 0          January
1          October...    
49972    September
49973       August
Name: Date of Meal, Length: 49974, dtype: object
  • **days_in_month**
**IN:** invoices['Date of Meal'].dt.days_in_month**OUT:** 0        31
1        31..
49972    30
49973    31
Name: Date of Meal, Length: 49974, dtype: int64
  • **nanosecond****microsecond****second****minute****hour****day****week****month****quarter****year**得到对应频率的整数。
**EXAMPLES: (same logic applies for** **nanosecond**, **microsecond**, **second**, **minute**, **hour)****IN:** invoices['Date of Meal'].dt.day**OUT:** 0        29
1        30..
49972     6
49973    20
Name: Date of Meal, Length: 49974, dtype: int64**IN:** invoices['Date of Meal'].dt.week**OUT:** 0         5
1        44..
49972    36
49973    34
Name: Date of Meal, Length: 49974, dtype: int64**IN:** invoices['Date of Meal'].dt.month**OUT:** 0         1
1        10..
49972     9
49973     8
Name: Date of Meal, Length: 49974, dtype: int64**IN:** invoices['Date of Meal'].dt.quarter**OUT:** 0        1
1        4..
49972    3
49973    3
Name: Date of Meal, Length: 49974, dtype: int64**IN:** invoices['Date of Meal'].dt.year**OUT:** 0        2015
1        2017... 
49972    2017
49973    2015
Name: Date of Meal, Length: 49974, dtype: int64
  • **is_leap_year****is_month_start****is_month_end****is_quarter_start****is_quarter_end****is_year_start****is_year_end**分别为每个值返回 True 或 False。is_month_end见下例
**IN:** invoices['Date of Meal'].dt.is_month_end**OUT:** 0        False
1        False...  
49972    False
49973    False
Name: Date of Meal, Length: 49974, dtype: bool

我们可以使用结果过滤我们的数据,只保留行,其中Date of Meal在月末。

Invoices filtered for Date of Meal is_month_end

  • **to_pydatetime()**,它将 Pandas datetime 转换成常规的 Python datetime 格式(有时您可能会用到),以及**to_period(<PERIOD>)** 【可用的周期有 W、M、Q 和 Y】,它将日期转换成周期。
**IN:** invoices['Date of Meal'].dt.to_pydatetime()**OUT:** array([datetime.datetime(2015, 1, 29, 8, 0),datetime.datetime(2017, 10, 30, 20, 0),datetime.datetime(2015, 2, 10, 11, 0), ...,datetime.datetime(2017, 3, 7, 19, 0),datetime.datetime(2017, 9, 6, 6, 0),datetime.datetime(2015, 8, 20, 18, 0)], dtype=object)**IN:** invoices['Date of Meal'].dt.to_period('W')**OUT:** 0       2015-01-26/2015-02-01
1       2017-10-30/2017-11-05...         
49972   2017-09-04/2017-09-10
49973   2015-08-17/2015-08-23
Name: Date of Meal, Length: 49974, dtype: object

存取器—字符串

str 访问器也非常有用,不是因为它支持额外功能,而是因为它使代码更加可读。

  • **lower()** / **upper()** 管理字符串的大小写
**IN:** invoices['Type of Meal'].str.lower()**OUT:** 0        breakfast
1           dinner...    
49972    breakfast
49973       dinner
Name: Type of Meal, Length: 49974, dtype: object**IN:** invoices['Type of Meal'].str.upper()**OUT:** 0        BREAKFAST
1           DINNER...    
49972    BREAKFAST
49973       DINNER
Name: Type of Meal, Length: 49974, dtype: object
  • **ljust(width)****rjust(width)****center(width)****zfill(width)**来控制琴弦的定位。它们都将所需结果字符串的总宽度作为输入。ljustrjustcenter用空格将差值填充至所需长度。添加许多前导零。ljust是向左的,rjust是向右的。********
******IN:** invoices['Type of Meal'].str.ljust(width=15)**OUT:** 0        Breakfast      
1        Dinner         ...       
49972    Breakfast      
49973    Dinner         
Name: Type of Meal, Length: 49974, dtype: object**IN:** invoices['Type of Meal'].str.rjust(width=15)**OUT:** 0              Breakfast
1                 Dinner...       
49972          Breakfast
49973             Dinner
Name: Type of Meal, Length: 49974, dtype: object**IN:** invoices['Type of Meal'].str.center(width=15)**OUT:** 0           Breakfast   
1             Dinner    ...       
49972       Breakfast   
49973         Dinner    
Name: Type of Meal, Length: 49974, dtype: object**IN:** invoices['Type of Meal'].str.zfill(width=15)**OUT:** 0        000000Breakfast
1        000000000Dinner...       
49972    000000Breakfast
49973    000000000Dinner
Name: Type of Meal, Length: 49974, dtype: object****
  • **startswith(<substring>)** **endswith(<substring>)**、、**contains(<substring>)**检查子串的存在****
****IN:** invoices['Type of Meal'].str.endswith('ast')**OUT:** 0         True
1        False...  
49972     True
49973    False
Name: Type of Meal, Length: 49974, dtype: bool**

using str.contains to filter for rows that include ‘Bruce.’

  • **swapcase()** 的拳打脚踢
****IN:** invoices['Type of Meal'].str.swapcase()**OUT:** 0        bREAKFAST
1           dINNER...    
49972    bREAKFAST
49973       dINNER
Name: Type of Meal, Length: 49974, dtype: object**IN:** invoices['Type of Meal'].str.repeat(2)**OUT:** 0        BreakfastBreakfast
1              DinnerDinner...        
49972    BreakfastBreakfast
49973          DinnerDinner
Name: Type of Meal, Length: 49974, dtype: object**

访问者— cat

在我看来是三个中最不强大的,或者至少是我最不常用的。cat提供对几个类别操作的访问,如:

  • **ordered** 让您知道列是否有序
****IN:** invoices['Type of Meal'].cat.ordered**OUT:**
False**
  • **categories** 返回类别
****IN:** invoices['Type of Meal'].cat.categories**OUT:** Index(['Breakfast', 'Dinner', 'Lunch'], dtype='object')**
  • **codes** 用于将类别快速转换成其数值表示
****IN:**
invoices['Type of Meal'].cat.codes**OUT:** 0        0
1        1
2        2
3        2
4        2..
49969    1
49970    2
49971    1
49972    0
49973    1
Length: 49974, dtype: int8**
  • **reorder_categories** 改变现有类别的顺序
****IN:**
invoices['Type of Meal'].cat.reorder_categories(['Lunch','Breakfast','Dinner']
)**OUT:** 0        Breakfast
1           Dinner
2            Lunch
3            Lunch
4            Lunch...    
49969       Dinner
49970        Lunch
49971       Dinner
49972    Breakfast
49973       Dinner
Name: Type of Meal, Length: 49974, dtype: category
Categories (3, object): [Lunch, Breakfast, Dinner]**

③组合数据帧

Image by Pexels from Pixabay

连结

当你有相似的数据(结构上和内容上)分布在多个文件中时,oncatenating 就很方便了。您可以垂直连接数据(即,将数据堆叠在一起)或水*连接数据(即,将数据堆叠在一起)。

ⓐ串联—垂直堆叠

作为一个例子,假设一个客户每月或每年向你提供一个文件的数据(例如,因为他们的报告在月末运行)。这些文件在概念上是相同的,因此是垂直堆叠的主要例子。

A simplified example of vertical stacking

让我们看看如何用 Python 的熊猫来做这件事。让我们人为地把发票文件按年份分开。

****# Use dt accessor to count all the years
IN:** invoices['Date of Meal'].dt.year.value_counts().sort_index()**OUT:** 2013       38
2014     9988
2015    10060
2016     9961
2017     9964
2018     9931
2019       32
Name: Date of Meal, dtype: int64**# Split the data** y_2013 = invoices[invoices['Date of Meal'].dt.year == 2013].copy()
y_2014 = invoices[invoices['Date of Meal'].dt.year == 2014].copy()
y_2015 = invoices[invoices['Date of Meal'].dt.year == 2015].copy()
y_2016 = invoices[invoices['Date of Meal'].dt.year == 2016].copy()
y_2017 = invoices[invoices['Date of Meal'].dt.year == 2017].copy()
y_2018 = invoices[invoices['Date of Meal'].dt.year == 2018].copy()
y_2019 = invoices[invoices['Date of Meal'].dt.year == 2019].copy()**

我们使用.copy()来确保生成的数据帧是数据的副本,而不仅仅是对原始数据帧的引用。

让我们验证一下拆分是否有效。

All Invoices where the date of the meal was in 2017

现在,为了将数据连接成一个统一的数据帧,我们将像这样调用pd.concat(<LIST OF DATAFRAMES>):

Stacking multiple DataFrames on top of each other

pd.concat在您调用concat的数据帧列表旁边,接受几个可选参数:

  • **axis** : 0为垂直,1为水*。**axis** 默认为**0**
  • **join** : 'inner'为交集,'outer'为非连接轴索引的并集。当我们使用axis=0join='inner'时,我们将只考虑重叠的列。当使用axis=1join='inner'时,我们只考虑重叠指数。在outer的情况下,非重叠列/索引将用nan值填充。**join** 默认为**outer**
  • **ignore_index** : True忽略预先存在的索引,而使用从 0 到 n-1 的标签作为结果数据帧。**ignore_index** 默认为**False**
  • **keys** : 如果我们提供一个列表(必须与数据帧的数量相同的长度),一个层次索引将被构建。keys默认为None keys为例,添加数据的来源。最好与名字连用。
  • **names** : 假设您提供了键,那么这些名称将用于标记生成的层次索引。**names** 默认为**None**

Stacking multiple DataFrames on top of each other with keys

ⓑ串联—水*堆叠

水*堆叠的一个用例是指多个时间序列具有重叠但不相同的索引。在这种情况下,您不会希望最终得到一个可能有数千列的数据帧,而是一个有数千行的数据帧。

A simplified example of horizontal stacking

在 Python 中运行下面的代码片段将得到下面的屏幕截图:

**range_a = pd.date_range(datetime.datetime(2019,1,2),datetime.datetime(2019,1,8)
)
df_a = pd.DataFrame(index=range_a, data=np.random.randint(2,10,size=len(range_a)),columns=['observations_A']
)range_b = pd.date_range(datetime.datetime(2019,1,5),datetime.datetime(2019,1,12)
)df_b = pd.DataFrame(index=range_b, data=np.random.randint(2,10,size=len(range_b)),columns=['observations_B']
)pd.concat([df_a,df_b],axis=1)**

Horizontally stacked DataFrames

关于**Append** : 你可能已经看到append的用法和concat一样的结尾。我建议不要使用 **append**,因为它只是concat的一个特例,并没有提供比串联更好的优势。

合并

与将数据帧连接在一起相反,合并允许我们以一种更传统的 SQL 查询方式将两个数据帧组合在一起。当合并数据帧时,大多数情况下,您希望一些信息来自一个源,另一些信息来自另一个源。而当连接数据帧时,它们在结构上和内容上非常相似,您希望将它们组合成一个统一的数据帧。

我喜欢在面试中使用的一个简单例子是这样的:

假设你有两张桌子。一个表包含员工姓名和位置 id,另一个表包含位置 id 和城市名称。你怎么能得到每个雇员的名单和他们工作的城市?

在 Pandas 中合并两个数据帧是用pd.merge完成的。让我们来看看函数的签名(签名是指函数所有可能参数的列表,通常还包括输出)。我加粗了最相关的参数。

**pd.merge(**left, right,** **how='inner', on=None,** **left_on=None,** **right_on=None,** **left_index=False,****right_index=False,** sort=True,**suffixes=('_x', '_y'),** copy=True, indicator=False,validate=None
) -> pd.DataFrame**

让我们一个一个地检查参数:

  • **left/right**:要合并的左、右数据帧
  • **how** : 'left''right''outer''inner'**how** 默认为**'inner'** 。下面是它们各自功能的示意图。稍后我们将讨论具体的例子。

Image from DataScienceMadeSimple

  • **left_index/right_index** : 如果True,使用左/右数据帧的索引合并。**left_index/right_index** 默认为False
  • **on** : 要合并的列名。列名必须同时存在于左侧和右侧数据框架中。如果未通过且left_indexright_indexFalse两个数据帧中的列的交集将被推断为连接。
  • **left_on/right_on** : 左/右数据框中要连接的列名。典型用例:您正在连接的键在您的数据帧中有不同的标签。例如,您左侧数据帧中的location_id可能是您右侧数据帧中的_id。在这种情况下,你会做**left_on='**location_id', **right_on**='_id'
  • **suffixes**:应用于重叠列的字符串后缀元组。**suffixes**默认为('_x', '_y')。我喜欢用('_base', '_joined')

合并—加载和检查新数据

理论够了,我们来看一些例子。为此,我们需要一些额外的数据来合并。

加载数据:

****# Load some additional Data**
order_data = pd.read_csv('[https://raw.githubusercontent.com/FBosler/you-datascientist/master/order_leads.csv', parse_dates=[3](https://raw.githubusercontent.com/FBosler/you-datascientist/master/order_leads.csv',parse_dates=[3)])**# Note the parse_dates? We need this to have consistent types with invoices, otherwise the subsequent merges would throw errors**sales_team = pd.read_csv('[https://raw.githubusercontent.com/FBosler/you-datascientist/master/sales_team.csv'](https://raw.githubusercontent.com/FBosler/you-datascientist/master/sales_team.csv'))**

检查数据:

Some overlapping (keys), some unique columns (features) spread out across three DataFrames

我们马上就能看到,**Order ID****Company ID****Date** 出现在多个数据帧中,因此是很好的合并对象。

合并—如何进行

让我们将**invoices****order_data** 合并,并对参数进行一点试验。

  • 未提供参数:所有参数将使用其默认值。
    合并将是一个内部合并(相当于**how='inner'**)。
    将对所有公共列进行合并,即**Date****Order Id****Company Id**(相当于**on=['Date','Order Id','Company Id]**)。
    后缀是不相关的,因为所有公共列都将用于合并,所以不会剩下重复的列。
    运行**pd.merge(order_data,invoices)** :

Merge with no parameters. Defaults to inner, i.e., only rows where there is data in both tables. Note how this results in ~50k rows.

  • **how='left'**:同样,合并基于所有公共列。后缀是不相关的,因为所有公共列都将用于合并,所以不会留下重复的列。
    然而,这一次,我们与**how='left'**合并,这意味着我们将从左侧帧中取出所有行,并且只添加右侧帧中我们找到的一些数据。运行**pd.merge(order_data,invoices,how='left')** :

“left-sided” merge, i.e., we take all rows from the left DataFrame and combine data from the right DataFrame, where we find some. Note how this results in 100k rows.

  • **how='right'**:同样,合并基于所有公共列。后缀是不相关的,因为所有公共列都将用于合并,所以不会留下重复的列。
    然而,这一次,我们与**how='right'**合并,这意味着我们将从右帧中取出所有行,并且只添加我们在左帧中找到的一些数据。这种情况相当于我们示例中的**'inner'**,因为左侧数据帧中的每一行在右侧数据帧中都有相应的行。
    运行**pd.merge(order_data,invoices,how='right')** :

“right-sided” merge, i.e., we take all rows from the right DataFrame and add data from the left DataFrame, where we find some. Note how this results in ~50k rows

  • **how='outer'**:同样,合并是基于所有公共列的。后缀是不相关的,因为所有公共列都将用于合并,所以不会留下重复的列。
    然而,这一次,我们与**how='outer'.**合并,我们从左侧或右侧数据帧中取出所有行,并在其他数据帧中找到的位置添加相应的数据。这种情况相当于我们示例中的**'left'**,因为左侧数据帧中的每一行在右侧数据帧中都有相应的行。运行**pd.merge(order_data,invoices,how='outer')** :

“outer” merge, i.e., we take all rows from both DataFrames and add data from the corresponding other DataFrame, where we find some. Note how this results in 100k rows.

合并—开/后缀

如果我们确实显式提供了一个**on**参数,这将覆盖默认行为,并尝试在两个数据帧中找到所提供的列。未用于合并的剩余重复列将被加上后缀。

在下面的例子中,我们只在**Order Id**进行合并。然而,由于**Date****Company Id** 列同时出现在两个数据帧中。这些列足以表明它们来自哪个源数据帧,如下例所示。

运行:**pd.merge(order_data,invoices,on='Order Id')**

Merge on one common column, default suffixes

我们也可以像这样指定自定义后缀:
**pd.merge(order_data,invoices,on='Order Id',suffixes=('_base','_join'))**

Merge on one common column, custom suffixes (_base and _join)

合并—左开/右开

当两个数据帧中的列名称不同时,通常会使用**left_on****right_on** 参数。

Contrived example, where we first rename “Order Id” to “New Id” to then use it as our right_on target column

**Join** 注: 你可能见过join的用法跟merge一个下场。join默认情况下,合并两个数据帧的索引。我建议不要使用 **join**,因为它只是merge的一个特例,并不能提供比合并更好的好处。

地图

到结束关于组合数据帧的章节,我们应该快速讨论一下mapmap可以在 DataFrame 列或其索引上调用,如下所示:

We create a new column based on the Sales Rep for the associated company by mapping the company column against a previously created lookup

map的参数(在我们的例子中是lookup)必须是一个序列或一个字典。虽然不完全相同,但熊猫系列和普通字典有很多共同的功能,并且经常可以互换使用。就像通过字典一样,你可以通过调用for k,v in series.items():来循环遍历一个系列。

组合数据帧的摘要:

  • 使用 **pd.concat**将多个数据帧“堆叠”在一起。默认情况下,堆叠是垂直的。要覆盖默认设置,使用axis=1。默认情况下,堆栈将覆盖所有列/索引。使用join='inner'限制公共列/索引。
  • 不要使用 **pd.DataFrame.append**,因为它只是pd.concat的一种特殊的、有限的情况,只会让你的代码不那么标准化,不那么连贯。而是使用pd.concat
  • 使用 **pd.merge**合并两个数据帧的信息。Merge 默认为内部连接,并将从数据帧中最大的公共列子集推断要合并的列。
  • 不要使用 **pd.DataFrame.join**,因为它只是pd.merge的一种特殊的、有限的情况,只会让你的代码不那么标准化,不那么连贯。相反,使用pd.merge
  • 使用 **pd.Series.map** 作为类似查找的功能,从序列/字典中获取特定索引/键的值。

④重塑数据帧(融合、旋转、转置、堆叠、拆分)

Photo by Chris Lawton on Unsplash

移项

T 转换数据帧意味着交换索引和列。换句话说,你是在围绕原点旋转数据帧。转置不会改变数据帧的内容。数据帧仅改变方向。让我们用一个例子来形象地说明这一点:

The first seven rows of invoices DataFrame and first seven rows of invoices DataFrame transposed

通过简单地调用数据帧上的.T来转置数据帧,例如invoices.T

熔化

M elt 将数据帧从宽格式转换成长格式。Melt 为如何进行转换提供了灵活性。换句话说,melt 允许抓取列并将其转换为行,同时保持其他列不变。融化最好用一个例子来解释。让我们创建一些样本数据:

**melt_experiment = pd.merge(invoices,pd.get_dummies(invoices['Type of Meal']).mul(invoices['Meal Price'].values,axis=0),left_index=True,right_index=True
)
del melt_experiment['Type of Meal']
del melt_experiment['Meal Price']
melt_experiment**

melt_experiment (unpacked Type of Meal into columns)

诚然,这个例子有点做作,但说明了这一点。我们将Type of Meal转换成列,并将价格分配到相应的行中。现在把它转换回一个版本,其中食物类型是一个列,值是价格,我们可以像这样使用pd.melt:

**pd.melt(frame=melt_experiment,id_vars=['Order Id', 'Date', 'Meal Id', 'Company Id', 'Date of Meal','Participants', 'Heroes Adjustment'],value_vars=['Breakfast', 'Dinner', 'Lunch'],var_name='Type of Meal',value_name='Expenses'
)**

导致:

“melted” DataFrame

Melt 有助于将数据帧转换成一种格式,其中一列或多列是标识符变量(id_vars),而所有其他列,即测量变量(value_vars),被移动到行轴,只留下两个非标识符列。对于我们融合的每一列(value_vars),对应的现有行被复制,以适应将数据融合到一列中,并且我们的数据框架扩展。熔化后,我们的行数是之前的三倍(因为我们使用了三个value_vars,因此每行三倍)。

分组依据

我们在上一篇文章中讨论过,但是在这里快速回顾一下是有意义的,特别是在堆叠和拆堆方面,我们将在后面讨论。其中转置和熔化保持数据帧的内容不变,并且“仅”重新排列外观分组,并且以下方法以一种或另一种形式聚集数据。Groupby 将产生一个具有新索引(分组所依据的列的值)的聚合数据帧。如果按多个值进行分组,得到的数据帧将具有多重索引。

**invoices.groupby(['Company Id','Type of Meal']).agg({'Meal Price':np.mean}
)**

groupby result with multi-index

从 pandas 版本 0.25.1 开始,也有了命名聚合,这使得 groupby 可读性更好一些。

**invoices.groupby(['Company Id','Type of Meal']).agg(Avg_Price = pd.NamedAgg(column='Meal Price', aggfunc=np.mean)
)**

结果实际上与前面的计算相同。但是,该列在此过程中会被重命名。

groupby result with multi-index and renamed output column

在枢轴上转动

和 Excel 的数据透视表一样,andas 也包含了一个pivot_table功能。但是我必须承认,我从来没有使用过pivot,因为我看不出它比 groupby 操作有什么优势。总的来说,我认为使用你感到舒适的东西并坚持这样做是有意义的。我建议不要在没有必要的时候混合使用不同的方法。不过,pivot_table有一个优势就是margin=True

**pd.pivot_table(invoices,index=['Company Id','Type of Meal'],values='Meal Price',aggfunc=np.mean,margins=True
)**

result of pivot_table operation with margins=True

结果应该看起来有些熟悉,因为我们基本上重新创建了 groupby 功能。然而,除了单个组的结果之外,我们还获得了跨所有组的计算值的额外好处(如最后一行所示)。

我们还可以为数据透视表指定列:

**pd.pivot_table(invoices,index=['Company Id'],columns=['Type of Meal'],values='Meal Price',aggfunc=np.mean,margins=True
)**

Pivot table with index and columns specified

堆叠/拆分

重新排列列和索引时,Sstack 和 unstack 非常方便。默认情况下,将在索引的最外层调用 Unstack,正如在下面的示例中可以很好地看到的那样,调用unstack()会将Heroes Adjustment索引变成两列。

calling unstack() on three-level index DataFrame rotates the outmost index into columns

我们还可以拆分特定级别的索引,如下例所示,其中我们拆分了Type of Meal

另一方面,堆叠的作用正好相反。堆叠将列转化为行,但是也在这个过程中扩展了索引(与melt相反)。让我们看一个例子。

我们必须首先构建一些数据,在这些数据中,堆叠会派上用场。执行下面的代码片段会产生一个多索引、多级别列的数据框架。

**stack_test = invoices.groupby(['Company Id','Type of Meal']).agg({'Meal Price':[max,min,np.mean],'Date of Meal':[max,min],
})
stack_test**

如果我们想要堆叠这个数据帧,我们将调用stack_test.stack()并得到:

stacked groupby result

在这里,stack 使用了我们的多级列的最外层,并将其转换为一个索引。我们现在只有单层列。或者,我们也可以用level=0调用 stack,得到如下结果:

stacked (on level=0) groupby result

摘要

在这篇文章中,你学会了如何成为一个真正的熊猫忍者。您了解了如何将数据转换成所需的类型以及在类型之间进行转换。您了解了如何为这些类型使用独特的方法来访问功能,否则需要一行又一行的代码。您学习了如何组合不同的数据帧,方法是将它们堆叠在一起,或者从数据帧中逻辑地提取信息,并将它们组合成更有意义的内容。你学会了如何翻转你的数据框,就像翻转煎饼一样。您学习了在其原点旋转、将列移入行、通过 pivot 或 groupby 聚合数据,然后堆叠和拆分结果。

干得好,感谢您的阅读!

通过拯救地球来合作学习人工智能

原文:https://towardsdatascience.com/learn-ai-collaboratively-by-saving-the-planet-9590efd4370e?source=collection_archive---------14-----------------------

Omdena 和 Ciencia y Datos 合作举办了一场新的人工智能挑战赛,如果你想成为 50 名人工智能爱好者之一,通过解决一个有意义的全球性问题来获得实践技能,你需要阅读这篇文章。

Learn more here: https://www.cienciaydatos.org/educacion

和所有人争着解决一个问题不累吗?不要误解我的意思,竞争是重要的,并且推动创新,但是如果你想学习,也许这不是最好的方法。

这就是为什么当 omdena.com 大学的人联系我们 T2 科学与技术大学的人,与他们一起合作挑战人工智能学习时,我们说是的!!

在详细讨论挑战和如何应用之前,让我简单地谈谈协作学习。

协作学习

http://blog.fusemachines.com/ai-human-collaboration/

学习一个新的话题总是具有挑战性,但是有一些方法可以让它变得简单。不久前,在我关于人们在学习数据科学时犯的最大错误的文章中,我提到如果你想真正学到一些你需要实践的东西,要认真学习,而且最好与对同一领域感兴趣的其他人一起学习。

我不是说你需要和你的闺蜜们一起开始一门课程,但是你应该利用今天在线*台给我们的东西。

一个社区的形成是因为它的成员有共同的价值观、兴趣和目标。现在有很多人在学习人工智能。很多!有一个很好的理由:

AI 就是新电!

这是伟大的吴恩达 2 年前说的,现在比以往任何时候都更正确。

许多人以这样或那样的方式使用人工智能,称自己为数据科学家、机器学习工程师、人工智能工程师或类似的人。正如我在之前提出的:

数据科学家不是单独存在的,他们需要一个团队,这个团队将使开发智能解决方案成为可能。协作是科学的一大部分,数据科学也不应该例外。

协作学习是一个已被证实的事实,积极的、社交的、有背景的、吸引人的、学生拥有的教育体验会带来更深层次的学习。

学习是一个积极的、建设性的过程。为了学习新的信息、想法或技能,协作学习方法规定学生必须有目的地与他人积极合作。他们需要把这些新材料与他们已经知道的东西结合起来——或者用它来重新组织他们认为他们知道的东西。

此外,因为现实生活项目中的人有不同的背景、学习风格、经验和抱负,所以当我们一起工作时,我们可以直接了解我们和其他人是如何学习的,以及他们给工作带来了什么经验和想法。我们需要在学习时利用多样性。

人工智能可能非常复杂,但汇集更多的智慧,利用我们的差异和相似之处,将有助于以更有效的方式解决困难的问题。但是我们需要结构和指导。让我解释一下这个挑战是关于什么的。

人工智能挑战:在卫星图像上识别树木

https://jesserosenstein.com/

如果你想阅读 Omdena 的完整故事以及他们在做什么,请看这篇文章:

[## 为什么社区和协作是构建道德人工智能的关键

一种新的建立人工智能解决方案的方式,通过形成组织、专家和学生的社区来合作…

medium.com](https://medium.com/omdena/why-community-and-collaboration-is-the-key-for-building-ethical-ai-e3389157b691)

你会怎么做?

你将参与一个全球范围的社会影响项目。最少的产出是有一个概念证明。根据你的技能,你将参与不同的角色,如定义项目范围,准备数据,建立人工智能模型。

该项目的目标是建立一个在卫星图像上识别树木的模型。该解决方案将防止因倒下的树木和风暴引发的停电和火灾。这将拯救生命,减少二氧化碳排放,并改善基础设施检查。

申请的要求是什么?

欢迎所有人申请挑战,但我们在这里寻找的是至少完成了一门机器学习或数据科学在线课程的人工智能爱好者。

以下是实际需求:

  • 英语良好,能使用电脑上网
  • 对计算机科学和/或数学有很好/非常好的理解
  • 学生、初级开发人员或正在改变工作领域的开发人员
  • 具有 C/C++、C#、Java、Python、R、Javascript 或类似语言的编程经验
  • (基础)了解 ML 和深度学习算法。
  • 通过或开始了机器学习/深度学习的在线课程。
  • 每周约 7-15 小时的工作时间。

对我有什么好处?

您将与真实图像一起工作,应用深度学习算法,同时与领先的导师合作,获得项目认证,并与世界各地志同道合的人一起提升您的技能。

但如果这还不够,我们还有一件事…

WAAAIIITTT FOR IIITTTTTT!!!!!

除了独特的学习经历,成功完成挑战后,项目社区将获得 3000 美元的集体奖金。这笔钱将由所有参与的社区成员*分,通过协作、社区和共享学习来解决问题。

如何申请?

超级简单,在这里申请就行:

【http://omdena.com/trees/

之后,我们将选择一组人工智能爱好者进行挑战。在项目结束时,成果将会呈现在世人面前。

重要提示:

挑战的空间有限,所以最多只能接受 50 人。不要犹豫,现在就申请吧!挑战下周开始!

项目伙伴关系

我们在sciencia y Datos很高兴能在这个项目中与 Omdena 合作,同时我们帮助建立世界上最大的*台,用于在人工智能、数据科学等领域学习和获得经验。

希望我们将在这个伟大的项目中一起工作,在那里你将学习,享受乐趣并帮助拯救地球,你还能要求什么呢?

如果您有任何问题,请在 Twitter 上添加我,我很乐意帮助您:

[## 法维奥·巴斯克斯(@法维奥·巴斯克斯)|推特

Favio Vázquez 的最新推文(@FavioVaz)。数据科学家。物理学家和计算工程师。我有一个…

twitter.com](https://twitter.com/faviovaz)

学习足够的码头工人是有用的

原文:https://towardsdatascience.com/learn-enough-docker-to-be-useful-1c40ea269fa8?source=collection_archive---------0-----------------------

第 2 部分:你需要知道的十几个码头术语

在本系列的第 1 部分中,我们探索了 Docker 容器的概念景观。我们讨论了 Docker 容器重要的原因以及思考它们的几种方式。我们把其中一个做成披萨🍕。在本文中,我将分享你需要知道的来自 Docker 生态系统的十几个附加术语。

Keeping with the food theme from the first article in the series. Here’s a dozen delicious Docker donuts. Think of each donut as a Docker container. 😄

Docker 生态系统术语

为了更容易地创建心智模型,我将 Docker 术语分为两类:要点缩放。先打八个要领。

码头工人必备

Docker *台 是Docker 的软件,提供在任何 Linux 服务器上的容器中打包和运行应用程序的能力。Docker *台捆绑了代码文件和依赖项。它通过实现便携性和再现性来促进容易的缩放。

Docker 引擎 是客户端-服务器应用程序。Docker 公司将 Docker 引擎分为两个产品。 Docker 社区版(CE) 是免费的,很大程度上基于开源工具。可能就是你要用的。Docker Enterprise附带了额外的支持、管理和安全功能。企业是码头公司保持运转的方式。

Engine makes things run

Docker 客户端 是你与 Docker 互动的主要方式。当您使用 Docker 命令行界面(CLI) 时,您可以在终端中键入以docker开头的命令。Docker 客户机然后使用 Docker API 将命令发送到 Docker 守护进程。

Diagram from the Docker docs

Docker 守护进程 是监听 Docker API 请求的 Docker 服务器。Docker 守护进程管理映像、容器、网络和卷。

Docker Volumes 是存储应用消耗和创建的持久数据的最佳方式。在本系列的第 5 部分中,我们将对 Docker 卷有更多的了解。跟着我,确保你不会错过。

Volumes

A Docker 注册表 是储存 Docker 图像的远程位置。你把图像推送到一个注册表,又从一个注册表中拉出图像。您可以托管自己的注册表或使用提供商的注册表。比如 AWS 和 Google Cloud 都有注册表。

Docker Hub 是 Docker 图片最大的注册表。这也是默认的注册表。你可以在 Docker Hub 上免费查找图片并存储自己的图片。

Hubs and spokes

一个Docker 储存库 是一个名称相同,标签不同的 Docker 图片的集合。标签是图像的标识符。

通常,一个存储库有相同图像的不同版本。比如Python就是 Docker Hub 上最流行的官方 Docker 图片库的名字。 Python:3.7-slim 是指 Python 库中带有 3.7-slim 标签的镜像版本。您可以将存储库或单个映像推送到注册表。

现在让我们看看与扩展多个 Docker 容器相关的 Docker 术语。

缩放 Docker

以下四个概念与一次使用多个容器有关。

Docker 联网 让你把 Docker 的容器连接在一起。连接的 Docker 容器可以在同一台主机上,也可以在多台主机上。关于 Docker 网络的更多信息,请看这篇文章。

Docker Bridge Network

Docker Compose是一款工具,可以让运行需要多个 Docker 容器的应用变得更加容易。Docker Compose 允许您将命令移动到一个docker-compose.yml文件中以便重用。Docker Compose 命令行界面(cli)使得与多容器应用程序的交互更加容易。Docker Compose 随 Docker 的安装免费提供。

Docker Swarm 是一款编排容器部署的产品。官方 Docker 教程的第四部分让你使用 Docker Swarm。我建议你不要花时间在 Docker Swarm 上,除非你有令人信服的理由。

Bee swarm

Docker 服务 是分布式 app 的不同部分。来自文档:

服务实际上只是“生产中的容器”一个服务只运行一个映像,但是它规定了该映像运行的方式——它应该使用什么端口,应该运行多少个容器副本,以便服务具有它需要的容量,等等。扩展服务会改变运行该软件的容器实例的数量,在这个过程中为服务分配更多的计算资源。

Docker 服务允许您跨多个 Docker 守护进程扩展容器,并使 Docker 集群成为可能。

这就是你应该知道的十几个美味的码头术语。

概述

这里有一行解释可以帮助你把这十几个术语搞清楚。

基础

*台 —使 Docker 容器成为可能的软件
引擎 —客户端-服务器应用程序(CE 或企业)
客户端 —处理 Docker CLI 以便您可以与守护程序
守护程序 —管理关键事物的 Docker 服务器
—持久数据存储
注册表 —远程映像存储
Docker Hub —默认且最大

缩放比例

联网 —将容器连接在一起
组合 —为多容器应用节省时间
群集 —协调容器部署
服务 —生产中的容器

因为我们一直在用食物做比喻,而且每个人都喜欢一打面包,所以我们为你多了一个相关的术语: Kubernetes

One more donut with extra icing and sprinkles

Kubernetes自动化容器化应用的部署、扩展和管理。它显然是容器编排市场的赢家。不要使用 Docker Swarm,而是使用 Kubernetes 来扩展具有多个 Docker 容器的项目。Kubernetes 不是 Docker 的官方部分;更像是 Docker 的 BFF。****

我有一系列关于 Kubernetes 的作品。Kubernetes 很棒。

既然你已经知道了概念和常用术语,我建议你试试 Docker。

用 Docker 烘烤

如果你以前没有和 Docker 合作过,现在是时候进入厨房做点东西了!

Docker 在 Linux、Mac 和 Windows 上本地运行。如果你在 Mac 或 Windows 机器上,安装最新稳定版本的 Docker 桌面这里。作为奖励,它带有 Kubernetes。如果你在其他地方安装 Docker,到这里找到你需要的版本。

安装 Docker 后,做 Docker 教程的前两部分。然后在这里见面,享受更多码头的乐趣。在本系列接下来的四个部分中,我们将深入探讨 Docker 文件、Docker 映像、Docker CLI 和数据处理。跟着我,确保你不会错过这次冒险。

关于 Dockerfiles 的第 3 部分现可在此处获得:

***** [## 学习足够的码头工人是有用的

第 3 部分:一打漂亮的 Dozen 文件指令

towardsdatascience.com](/learn-enough-docker-to-be-useful-b0b44222eef5)

如果你觉得这篇文章有帮助,请在 Twitter、脸书、LinkedIn 和你喜欢的论坛上分享。感谢阅读!*****

学习足够的码头工人是有用的

原文:https://towardsdatascience.com/learn-enough-docker-to-be-useful-b0b44222eef5?source=collection_archive---------1-----------------------

第 3 部分:一打漂亮的 Dozen 文件指令

Keeping with our carb-rich food metaphors, we’ll explore a dozen tasty Dockerfile instructions.

这篇文章是关于 Dockerfiles 的。这是 Docker 六集系列的第三部分。如果你还没有阅读过第 1 部分,请先阅读一下,以全新的视角来看待 Docker 容器概念。💡第 2 部分是 Docker 生态系统的快速演练。在未来的文章中,我将着眼于精简 Docker 映像、Docker CLI 命令以及使用 Docker 数据。

让我们跳进十几个 Dockerfile 指令就知道了!

Jump in. True picture 😉

Docker 图像

回想一下,Docker 容器是一个栩栩如生的 Docker 图像。这是一个包含应用程序代码的独立的最小操作系统。

Docker 映像是在构建时创建的,Docker 容器是在运行时创建的。

Docker 文件是 Docker 的核心。Docker 文件告诉 Docker 如何构建将用于制作容器的图像。

每个 Docker 图像包含一个名为 Dockerfile 的文件,没有扩展名。当调用docker build创建图像时,Dockerfile 被假定在当前工作目录中。可以用文件标志(-f)指定不同的位置。

回想一下,容器是由一系列层构成的。每个层都是只读的,除了位于其他层之上的最后一个容器层。Docker 文件告诉 Docker 要添加哪些层以及添加的顺序。

每一层实际上只是一个文件,其中包含了自上一层以来的更改。在 Unix 中,几乎所有东西都是一个文件。

基础图像提供初始层。基础映像也称为父映像。

将图像从远程存储库提取到本地计算机时,只会下载本地计算机上没有的图层。Docker 通过重用现有层来节省空间和时间。

A base (jumping) image

Dockerfile 指令是行首的一个大写单词,后跟它的参数。Dockerfile 文件中的每一行都可以包含一条指令。构建映像时,指令是从上到下处理的。说明是这样的:

FROM ubuntu:18.04
COPY . /app

只有来自、运行、复制和添加的指令才能在最终图像中创建层。其他指令配置东西,添加元数据,或者告诉 Docker 在运行时做一些事情,比如公开端口或者运行命令。

在本文中,我假设您使用的是基于 Unix 的 Docker 映像。您也可以使用基于 Windows 的图像,但这是一个较慢、不太愉快、不太常见的过程。所以可以的话就用 Unix 吧。

让我们快速浏览一下将要研究的十几条 Dockerfile 指令。

一打 Dozen 文件说明

FROM —指定基础(父)图像。
LABEL—提供元数据。包含维护者信息的好地方。
ENV —设置持久的环境变量。
RUN—运行命令并创建一个图像层。用于将包安装到容器中。
COPY —将文件和目录复制到容器中。
ADD —将文件和目录复制到容器。可以备份本地。焦油文件。
CMD —为正在执行的容器提供命令和参数。参数可以被覆盖。只能有一个 CMD。
WORKDIR —设置后续指令的工作目录。
ARG —定义在构建时传递给 Docker 的变量。
ENTRYPOINT —为正在执行的容器提供命令和参数。争论一直存在。
EXPOSE —暴露一个端口。
VOLUME —创建目录挂载点以访问和存储持久数据。

我们开始吧!

说明和示例

Dockerfile 文件可以简单到只有这一行:

FROM ubuntu:18.04

从到

Dockerfile 必须以 FROM 指令或 ARG 指令开头,后跟 FROM 指令。

FROM 关键字告诉 Docker 使用与提供的存储库和标签相匹配的基本图像。基础图像也被称为父图像。

在本例中, ubuntu 是图像库。Ubuntu 是一个官方 Docker 库的名字,它提供了流行的 Linux 操作系统 Ubuntu 版本的基础版本。

Linux mascot Tux

注意,这个 docker 文件包含了一个基本图像的标签: 18.04 。这个标签告诉 Docker 要从 ubuntu 库中提取哪个版本的图像。如果没有包含标签,那么 Docker 默认采用最新的标签。为了使您的意图清晰,指定一个基本图像标签是一个好的做法。

当上面的 Docker 文件首次用于在本地构建映像时,Docker 会下载在 ubuntu 映像中指定的层。这些层可以被认为是相互堆叠的。每一层都是一个文件,其中包含了与前一层的一系列差异。

创建容器时,在只读层之上添加一个可写层。

From the Docker Docs

Docker 使用写入时复制策略来提高效率。如果一个层存在于映像中的前一层,而另一个层需要对它进行读取访问,Docker 将使用现有的文件。什么都不需要下载。

当映像运行时,如果某个层需要被容器修改,则该文件会被复制到顶部的可写层中。查看 Docker 文档这里了解更多关于写时复制的信息。

更实质性的文档

虽然我们的单行图像很简洁,但它也很慢,提供的信息很少,并且在容器运行时什么也不做。让我们看一个更长的 Dockerfile,它构建一个更小的映像,并在容器运行时执行一个脚本。

FROM python:3.7.2-alpine3.8
LABEL maintainer="[jeffmshale@gmail.com](mailto:jeffmshale@gmail.com)"
ENV ADMIN="jeff"RUN apk update && apk upgrade && apk add bashCOPY . ./appADD [https://raw.githubusercontent.com/discdiver/pachy-vid/master/sample_vids/vid1.mp4](https://raw.githubusercontent.com/discdiver/pachy-vid/master/sample_vids/vid1.mp4) \
/my_app_directoryRUN ["mkdir", "/a_directory"]CMD ["python", "./my_script.py"]

哇,这是怎么回事?让我们一步一步来揭开它的神秘面纱。

基础图片是官方的 Python 图片,标签为 3.7.2-alpine3.8 。正如你可以从它的源代码中看到的,图像包括 Linux、Python,没有太多其他的。阿尔卑斯山的图像很受欢迎,因为它们小,快,安全。然而,Alpine 图像并不具备操作系统的许多优点。如果需要,您必须自己安装这些软件包。

标签

下一条指令被标记。标签向图像添加元数据。在这种情况下,它提供了映像维护者的联系信息。标签不会降低构建速度或占用空间,它们确实提供了关于 Docker 图像的有用信息,所以一定要使用它们。关于标签元数据的更多信息可以在这里找到。

环境

ENV 设置一个在容器运行时可用的持久环境变量。在上面的例子中,您可以在创建 Docker 容器时使用 ADMIN 变量。

ENV 很适合设置常量。如果您在 docker 文件中的几个位置使用了一个常量,并希望在以后更改它的值,那么您可以在一个位置这样做。

ENVironment

使用 Dockerfiles,通常有多种方法来完成同一件事情。对你的情况来说,最好的方法是*衡 Docker 惯例、透明度和速度。例如,RUN、CMD 和 ENTRYPOINT 有不同的用途,都可以用来执行命令。

运行

运行在构建时创建一个层。Docker 在每次运行后提交映像的状态。

RUN 通常用于将软件包安装到镜像中在上面的例子中,RUN apk update && apk upgrade告诉 Docker 从基础映像更新包。 && apk add bash告诉 Docker 将 bash 安装到镜像中。

apk 代表 Alpine Linux 包管理器。如果您使用的是除 Alpine 之外的 Linux 基础映像,那么您应该安装带有 RUN apt-get 而不是 apk 的包。 apt 代表高级包装工具。我将在后面的例子中讨论安装包的其他方法。

RUN

RUN——以及它的表亲 CMD 和 entry point——可以在 exec 形式或 shell 形式中使用。Exec 格式使用 JSON 数组语法如下:RUN ["my_executable", "my_first_param1", "my_second_param2"]

在上面的例子中,我们使用了格式为RUN apk update && apk upgrade && apk add bash的 shell 表单。

稍后在 docker 文件中,我们使用首选的 exec 格式和RUN ["mkdir", "/a_directory"]来创建一个目录。不要忘记在 exec 表单的 JSON 语法中对字符串使用双引号!

复制

COPY . ./app 指令告诉 Docker 获取本地构建上下文中的文件和文件夹,并将它们添加到 Docker 映像的当前工作目录中。如果目标目录不存在,复制将创建它。

COPY

添加

ADD 做的事情和 COPY 一样,但是多了两个用例。ADD 可用于将文件从远程 URL 移动到容器,ADD 可提取本地 TAR 文件。

在上面的例子中,我使用 ADD 将一个文件从远程 url 复制到容器的 my_app_directory 中。Docker 文档不推荐以这种方式使用远程 URL,因为你不能删除文件。额外的文件会增加最终图像的大小。

Docker 文档还建议尽可能使用 COPY 而不是 ADD 来提高清晰度。Docker 没有将 ADD 和 COPY 合并成一个命令来减少 Dockerfile 指令的数量以保持直线,这太糟糕了😃。

注意,ADD 指令包含了\行继续符。通过将一个长指令分成几行来提高可读性。

CMD

CMD 为 Docker 提供了一个在容器启动时运行的命令。它不会在构建时将命令的结果提交给映像。在上面的例子中,CMD 将让 Docker 容器在运行时运行 my_ script.py 文件。

That’s a CMD!

关于 CMD 需要知道的其他一些事情:

  • 每个 docker 文件只有一条 CMD 指令。否则,除了最后一个,其他的都将被忽略。
  • CMD 可以包含一个可执行文件。如果 CMD 没有可执行文件,那么入口点指令必须存在。在这种情况下,CMD 和 ENTRYPOINT 指令都应该是 JSON 格式。
  • docker run的命令行参数覆盖 Dockerfile 文件中提供给 CMD 的参数。

准备好了吗?

让我们在另一个示例 Dockerfile 中再介绍一些指令。

FROM python:3.7.2-alpine3.8
LABEL maintainer="[jeffmshale@gmail.com](mailto:jeffmshale@gmail.com)"# Install dependencies
RUN apk add --update git# Set current working directory
WORKDIR /usr/src/my_app_directory# Copy code from your local context to the image working directory
COPY . .# Set default value for a variable
ARG my_var=my_default_value# Set code to run at container run time
ENTRYPOINT ["python", "./app/my_script.py", "my_var"]# Expose our port to the world
EXPOSE 8000# Create a volume for data storage
VOLUME /my_volume

请注意,您可以在 docker 文件中使用注释。评论从#开始。

软件包安装是 Dockerfiles 的主要工作。如前所述,用 RUN 安装软件包有几种方法。

您可以使用 apk 在 Alpine Docker 映像中安装一个包。apk 就像普通 Linux 版本中的 apt-get 。例如,Dockerfile 中带有基本 Ubuntu 映像的包可以像这样更新和安装:RUN apt-get update && apt-get install my_package

除了 apkapt-get 之外,Python 包还可以通过 pipwheelconda 进行安装。其他语言可以使用各种安装程序。

底层需要为安装层提供相关的包管理器。如果您在安装软件包时遇到问题,请确保在尝试使用软件包管理器之前安装了它们。😃

您可以使用 RUN with pip 并在 docker 文件中直接列出您想要安装的软件包。如果这样做,将软件包安装连接成一条指令,并用行继续符()将其分隔开。这种方法比多重运行指令更清晰,层次更少。

或者,您可以在一个文件中列出您的包需求,并在该文件上运行包管理器。民间通常将文件命名为 requirements.txt 。在下一篇文章中,我将分享一个推荐的模式来利用构建时缓存和 requirements.txt

工作方向

WORKDIR 为其后的 COPY、ADD、RUN、CMD 和 ENTRYPOINT 指令更改容器中的工作目录。一些注意事项:

  • 最好用 WORKDIR 设置一个绝对路径,而不是用 Dockerfile 中的cd命令在文件系统中导航。
  • 如果该目录不存在,WORKDIR 会自动创建它。
  • 您可以使用多个 WORKDIR 指令。如果提供了相对路径,那么每个 WORKDIR 指令都会改变当前的工作目录。

WORKDIRs of some sort

ARG

ARG 定义了一个在构建时从命令行传递到映像的变量。可以为 docker 文件中的 ARG 提供一个默认值,如示例中所示:ARG my_var=my_default_value

与 ENV 变量不同,ARG 变量不可用于正在运行的容器。但是,您可以在构建映像时使用 ARG 值从命令行为 ENV 变量设置默认值。然后,ENV 变量在容器运行时保持不变。点击了解更多关于这项技术的信息。

入口点

ENTRYPOINT 指令还允许您在容器启动时提供默认命令和参数。它看起来类似于 CMD,但是如果使用命令行参数运行容器,入口点参数不会被覆盖。

相反,传递给docker run my_image_name的命令行参数被附加到 ENTRYPOINT 指令的参数中。例如,docker run my_image bash将参数 bash 添加到 ENTRYPOINT 指令现有参数的末尾。

ENTRYPOINT to somewhere

Dockerfile 应该至少有一个 CMD 或 ENTRYPOINT 指令。

Docker 文档有一些关于在 CMD 和 ENTRYPOINT 之间选择初始容器命令的建议:

  • 当您需要每次都运行相同的命令时,请选择 ENTRYPOINT。
  • 当一个容器将被用作一个可执行程序时,选择 ENTRYPOINT。
  • 当您需要提供可以从命令行覆盖的额外默认参数时,请选择 CMD。

在上面的例子中,当容器开始运行时,ENTRYPOINT ["python", "my_script.py", "my_var"]让容器运行带有参数 my_var 的 python 脚本 my_script.py 。my_var 然后可以通过 argparse 被 my_script 使用。请注意, my_var 有一个默认值,由前面 docker 文件中的 ARG 提供。因此,如果没有从命令行传递参数,那么将使用默认参数。

Docker 建议你一般使用 exec 形式的 ENTRYPOINT: ENTRYPOINT ["executable", "param1", "param2"]。这种形式是带有 JSON 数组语法的形式。

曝光

EXPOSE 指令显示了打算发布哪个端口来提供对正在运行的容器的访问。EXPOSE 实际上并不发布端口。相反,它充当构建映像的人和运行容器的人之间的文档。

EXPOSEd

在运行时使用带有-p标志的docker run来发布和映射一个或多个端口。大写的-P标志将公布所有暴露的端口。

VOLUME 指定容器存储和/或访问持久数据的位置。卷是本系列即将发表的一篇文章的主题,因此我们将在那时研究它们。

VOLUME

让我们回顾一下我们研究过的十几个 Dockerfile 指令。

重要的文档说明

FROM —指定基础(父)图像。
LABEL—提供元数据。包含维护者信息的好地方。
ENV —设置持久的环境变量。
RUN—运行命令并创建一个图像层。用于将包安装到容器中。
COPY —将文件和目录复制到容器中。
ADD —将文件和目录复制到容器。可以备份本地。焦油文件。
CMD —为正在执行的容器提供命令和参数。参数可以被覆盖。只能有一个 CMD。
WORKDIR —设置后续指令的工作目录。
ARG —定义在构建时传递给 Docker 的变量。
ENTRYPOINT —为正在执行的容器提供命令和参数。争论一直存在。
EXPOSE —暴露一个端口。
VOLUME —创建目录挂载点以访问和存储持久数据。

现在你知道一打 Dockerfile 指令让自己有用!这里有一个额外的百吉饼:一个有所有文档说明的小抄。我们没有涉及的五个命令是 USER、ONBUILD、STOPSIGNAL、SHELL 和 HEALTHCHECK。如果你遇到他们,你会看到他们的名字。😃

Bonus bagel

包装

Docker 文件可能是 Docker to master 的关键组成部分。我希望这篇文章能帮助你获得对他们的信心。我们将在本系列关于减肥图片的下一篇文章中再次讨论它们。跟着 me 确保不要错过!

如果你觉得这篇文章有帮助,请分享到你最喜欢的社交媒体上,帮助其他人找到它。👍

我写关于数据科学、云计算和其他技术的东西。关注我,在这里阅读更多。

码头快乐!

学习足够的码头工人是有用的

原文:https://towardsdatascience.com/learn-enough-docker-to-be-useful-b7ba70caeb4b?source=collection_archive---------1-----------------------

第 1 部分:概念景观

容器对于提高软件开发和数据科学中的安全性、可再现性和可伸缩性非常有帮助。它们的崛起是当今科技领域最重要的趋势之一。

Docker 是一个在容器内部开发、部署和运行应用程序的*台。码头工人本质上是集装箱化的同义词。如果你是一个当前的或有抱负的软件开发人员或数据科学家,Docker 是你的未来。

如果你还没有跟上速度,不要担心——这篇文章将帮助你理解概念上的前景——并且你将在途中做一些比萨饼。

在本系列接下来的五篇文章中,我们将讨论 Docker 术语、Docker 文件、Docker 图像、Docker 命令和数据存储。第 2 部分现已上线:

[## 学习足够的码头工人是有用的

第 2 部分:你需要知道的十几个码头术语

towardsdatascience.com](/learn-enough-docker-to-be-useful-1c40ea269fa8)

到本系列结束时(经过一点实践),你应该知道足够有用的 Docker😃!

码头隐喻

首先,我要解释一下 Docker 隐喻。

They’re everywhere! Just check out this book.

谷歌对隐喻的第二个定义是我们想要的:

被认为是其他事物的代表或象征的事物,尤指抽象的事物。

隐喻帮助我们理解新事物。比如实体容器的比喻,帮助我们快速抓住虚拟容器的本质。

A physical container

容器

像物理塑料容器一样,码头集装箱:

  1. 拿东西 —东西要么在容器里面,要么在容器外面。
  2. 是可移植的——它可以在你的本地机器、你同事的机器或者云提供商的服务器(例如 AWS)上使用。有点像你从一个家搬到另一个家随身携带的那盒童年小摆设。
  3. 有清晰的访问接口 —我们的物理容器有一个盖子,用于打开、放入和取出东西。类似地,Docker 容器有几种与外界接口的机制。它有可以通过浏览器打开进行交互的端口。您可以将其配置为通过命令行与数据交互。
  4. 可以从遥远的地方获得 —当你需要的时候,你可以从 Amazon.com 得到另一个空的塑料容器。亚马逊从制造商那里获得塑料容器,这些制造商从一个模具中冲压出数千个塑料容器。在 Docker 容器的情况下,一个异地注册中心为您的容器保存一个映像,就像一个模子。然后,当你需要一个容器时,你可以根据图片制作一个。

与虚拟 Docker 容器不同,亚马逊的新塑料容器会让你花钱,而且里面不会有你商品的副本。遗憾的💸。

活生生的例子

你可以认为 Docker 容器的第二种方式是作为一个有生命的东西的实例。实例是以某种形式存在的东西。不仅仅是代码。是代码给生活带来了一些东西。像其他生物一样,实例最终会死亡——这意味着容器会关闭。

An instance of a monster

Docker 容器是一个栩栩如生的 Docker 图像。

软件

除了容器隐喻和活生生的实例隐喻之外,您可以将 Docker 容器想象成一个软件程序。毕竟是软件。在最基本的层面上,容器是一组操作其他位的指令。

Containers are code

当 Docker 容器运行时,它通常有程序在里面运行。容器中的程序执行动作,所以你的应用程序会做一些事情。

例如,Docker 容器中的代码可能已经向您发送了您正在该网页上阅读的内容。或者,它可能会将您的语音命令发送到 Amazon Alexa,并将其解码为不同容器中的另一个程序将使用的指令。

使用 Docker,您可以在一台主机上同时运行多个容器。和其他软件程序一样,Docker 容器可以运行、检查、停止和删除。

概念

虚拟机

虚拟机是 Docker 容器的前身。虚拟机还隔离应用程序及其依赖关系。然而,Docker 容器优于虚拟机,因为它们占用更少的资源,非常便携,并且启动更快。查看这篇文章中关于相似性和差异性的精彩讨论。

Docker 图像

我在上面提到了图像。什么是图像?很高兴你问了!Docker 上下文中的术语 image 的含义并不能很好地映射到物理图像。

Images

Docker 图像更像是蓝图、饼干切割器或模具。图像是不可变的主模板,用于抽取完全相同的容器。

Cookie cutters

映像包含应用程序运行所需的 docker 文件、库和代码,所有这些都捆绑在一起。

Dockerfile 文件

Dockerfile 是一个说明 Docker 应该如何构建您的图像的文件。

Dockerfile 指的是用于构建初始图像层的基础图像。热门官方基图有 python 、 ubuntu 、 alpine 。

然后,根据 docker 文件中的说明,可以在基本图像层的顶部堆叠附加层。例如,机器学习应用程序的 Docker 文件可以告诉 Docker 在中间层添加 NumPy、Pandas 和 Scikit-learn。

最后,根据 Dockerfile 代码,将一个薄的可写层堆叠在其他层的顶部。(你理解薄层体积小是因为你直观地理解了的比喻,对吗😃?)

我将在本系列的后续文章中更深入地探讨 Dockerfiles。

码头集装箱

Docker 图像加上命令docker run image_name从图像创建并启动一个容器。

集装箱登记处

如果您希望其他人能够根据您的图像制作容器,您可以将图像发送到容器注册表。 Docker Hub 是最大的注册表和默认注册表。

唷!那是很多块。让我们把这一切放在一起,做一个比萨饼。

用 Docker 做饭

Landscape Metaphor

  • 菜谱就像 Dockerfile 。它告诉你该怎么做才能达到你的最终目标。
  • 配料是。你有比萨饼的外壳、调味汁和奶酪。

把食谱和配料组合在一起,就像一个完整的比萨饼制作工具包。是 Docker 形象

菜谱(Dockerfile)告诉我们要做什么。计划是这样的:

  • 外壳是预先形成的,不可改变的,它就像一个基本的 ubuntu 父图像。这是最底层和最先建造的
  • 然后你会加一些奶酪。将第二层添加到比萨饼中就像安装一个外部库——例如 NumPy。
  • 然后你会撒上一些罗勒。罗勒就像是你为运行你的应用程序而编写的文件中的代码。

好吧,我们开始做饭吧。

Oven

  • 烤披萨的烤箱就像 Docker *台。你搬进来的时候把烤箱装在了家里,这样你就可以用它做东西了。类似地,你在你的电脑上安装了 Docker,这样你就可以制作容器了。
  • 你转动旋钮来启动烤箱。docker run image_name命令就像您的旋钮——它创建并启动您的容器。
  • 煮熟的比萨饼就像一个码头集装箱。
  • 吃披萨就像使用你的应用程序。

就像做比萨饼一样,在 Docker 容器中制作一个应用程序需要一些工作,但最终你会得到一些很棒的东西。享受🍕!

包装

这就是概念框架。在本系列的第 2 部分中,我澄清了你将在 Docker 生态系统中看到的一些术语。跟着我,保证你不会错过!

希望这个概述能帮助你更好地理解 Docker 的前景。我也希望它能让你看到隐喻在理解新技术中的价值。

如果你觉得这很有帮助,请在你最喜欢的社交媒体上分享,这样其他人也可以找到它。👏

我写关于 Python、Docker、数据科学等等的文章。如果你对此感兴趣,请阅读更多此处并关注我的 Medium。😄

感谢阅读!

学会足够有用的东西

原文:https://towardsdatascience.com/learn-enough-git-to-be-useful-281561eef959?source=collection_archive---------2-----------------------

GitHub 项目的 4 个基本工作流程

在这篇文章中,我们将在四种常见的场景中探讨如何使用 Git 和 GitHub。

  1. 独自带着自己的原创项目推送到分支。
  2. 独自处理自己的原始项目和拉取请求。
  3. 独自进行一个克隆项目。
  4. 共同参与一个项目。

Git 对于开发人员、数据科学家和产品经理来说是必不可少的版本控制技术。

GitHub 是最流行的远程 Git 存储库注册中心。它托管了超过 1 亿个存储库,并且是许多开源软件构建的地方。

如果你是一名开发人员,你应该有一个 GitHub 帐户,显示你可以用代码做事情。虽然 GitLab 和 BitBucket 是流行的注册表选项,但最*被微软收购的 GitHub 显然是市场领导者。

先决条件

如果您有一个 GitHub 帐户,并且已经在您的计算机上安装并配置了 Git,请直接跳到前面。

如果你没有 GitHub 账户,请点击这里注册一个免费账户。点击查看如何安装和配置 Git 。你需要命令行工具。按照链接下载、安装它,设置您的用户名,并设置您的提交电子邮件地址。

一旦解决了这个问题,您就可以从我们的基本示例开始了。如此微不足道!😆

场景 1:单飞推主工作流

  1. 在 GitHub 上创建一个回购。

输入存储库名称。然后输入描述——如果您切换用自述文件初始化此存储库,此描述将成为初始化时的自述文件。您可以稍后更改自述文件的内容。

在这里,我正在为我的关于 Python OS 命令的文章制作一个 repo。

如果你想让其他人能够找到你的作品,保持 Public 单选按钮高亮显示。私人回购过去是要花钱的,但用户现在有无限量的免费回购。

从下拉列表中添加一个. gitignore 。我选择了 Python 作为我的 os-examples 项目,因为我正在做一个 Python 项目。的。gitignore file 将匹配您不想在 Git repo 中使用的常见文件夹和文件类型。你可以改变你的。gitignore 稍后排除其他不必要的或敏感的文件。

我建议您从添加许可证下拉列表中选择一个许可证。许可证定义了存储库内容的用户可以做什么。有些许可证比其他的更宽松。如果没有选择许可证,则默认版权法适用。点击了解更多关于执照的信息。

现在你在 GitHub 上有回购了,亲爱的!是时候把它复制到你的本地机器上了。

2.从 GitHub 抓取网址进行克隆。

3.启动一个终端会话,并导航到您希望存储 repo 的本地目录。考虑一下这个位置——您可能想要创建一个新目录来保持整洁。

然后运行:

git clone [https://github.com/your_repo_name/your_repo](https://github.com/your_repo_name/your_repo)

ls查看您的新目录

cd进入你的目录

ls查看您的新目录和文件

现在是时候投入到您的推动工作流程中了。

推送至主工作流

1.当您克隆一个回购时,默认情况下,您从本地回购的主分支开始。创建一个临时分支并在其中工作是很好的实践。

创建一个新的分支并用git checkout -b my_feature_branch切换到它。

你可以给你的分公司起任何你喜欢的名字。然而,与编程中的大多数名称一样,简明扼要是个好主意。😄

2.在代码编辑器中编写一些代码并保存。我是 Atom 的粉丝。它是免费的、开源的、受欢迎的,并且运行良好。

3.使用git status检查本地文件更改的状态。您应该会看到一个红色的新文件列表。这些是未被追踪的文件。Git 知道这些文件,所以 Git 对它们进行了索引。这些文件与中的文件不匹配。gitignore,所以它们不会被 Git 忽略。

例如,这是我的未跟踪文件。

4.要暂存所有更改,请输入git add -A

您可能会看到一个您不想添加到 GitHub repo 的文件被列出。在这种情况下,您可以使用git add my_filename单独添加想要暂存的文件。

此外,你应该改变你的。gitignore file 排除不想添加到 repo 中的文件类型和文件夹。保存您的。gitignore file,它应该以红色显示为一个包含未分级更改的文件。

再次确保您要提交的文件是暂存的。文件更改必须暂存才能提交。

打个棒球或垒球的比方,我认为阶段性变化就像甲板上的击球手。他们正在为接下来的事情做准备:真正的事情。

Batter in on deck circle.Credit: Tdorante10 [CC BY-SA 4.0 (https://creativecommons.org/licenses/by-sa/4.0)]

要提交的文件将以绿色显示。

5.用git commit -m "my commit message"提交更改。使用现在时态,例如“更新参考文献的链接”。

6.用git checkout master切换到当地总支。

你可以用git branch -v看到你所有的分支。

7.用git merge my_feature_branch将你当地的特色分支合并到你当地的主分支。

8.用git push origin master将更新的 master 分支推送到 GitHub。

9.用git branch -d my_feature_branch删除你的旧的,本地的,非主分支。

重复🔁

如果你是单干的话就这样。现在您的工作已经备份,更改可以回滚,其他人可以使用和查看您的代码。😄

接下来,我们将看一个稍微复杂一点的带有拉请求的工作流。

场景 2:单独拉式请求工作流

我将通过对我的 GitHub repo 进行修改来演示这个工作流,我的 GitHub repo 曾经为一篇关于如何使用 argparse 的文章做了一个例子。

在到达步骤 6 之前,一切都与场景 1 的设置和工作流程相同。不要转到你当地的主分支,而是留在你当地的特色分支。这是新的第六步:

6.用git push origin my_feature_branch将您的特性分支推送到您的远程存储库。

7.在浏览器中导航到您的 GitHub repo,您应该会看到一个警告,提示您可以比较&拉取请求

单击绿色按钮,您将能够创建拉取请求。

8.点击创建拉动请求。我在这里没有设置持续集成,但是我将在以后关于创建开源项目的文章中深入探讨这个主题。跟着我,确保你不会错过它。😄

9.确认您要合并提取请求。

10.您可以选择删除远程分支。删除它。

11.回到你的终端,用git checkout master切换回你当地的主分支。

12.用git pull origin master从您的远程存储库中下载主分支。或者,您可以从要素分支中合并本地更改。然而,最好养成从您的远程存储库中下载变更的习惯,以防您的合作者的变更被合并到 master 中。此外,您可能已经通过浏览器快速修复了一个降价文档,但却忘记了。所以安全总比后悔好。😄

13.用git branch -d my_feature_branch删除不再需要的局部特征分支。

通过选择下一个要处理的 bug 或特性,并创建和检查一个新的分支,重新开始这个循环。🔁

注意,您可以从命令行创建和管理拉请求流程,但是我发现从浏览器管理流程更容易。

场景 3:单独克隆的项目

场景是这样的:你想玩别人写的放在 GitHub 上的代码。您可能会发现自己在教程中这样做。让我们假设你没有把你的作品发送到 GitHub。

例如,您可以从穆勒和圭多的Python 机器学习入门(我强烈推荐给数据科学家的一本书)下载带有示例代码的存储库。

git clone [https://github.com/amueller/introduction_to_ml_with_python.git](https://github.com/amueller/introduction_to_ml_with_python.git)从 GitHub 抓取网址进行复制。

在你的克隆回购中启动 Jupyter Lab 并开始玩例子。如果你只是在本地玩,那就这样吧。又短又甜!

场景 4:合作参与项目

你想为一个现有的开源项目做贡献。欺负你!👏

Now we’re flying together

让我们使用首次投稿/首次投稿。这个 GitHub repo 旨在帮助你为一个开源项目做出第一份贡献。这非常简单:你发出一个 pull 请求,将你的名字添加到一个列表中。

在这种情况下,您从派生回购开始。

  1. 点击 GitHub repo 右上角的

GitHub 会为你分叉回购,带你分叉。

2.现在像以前一样在本地克隆您的 repo,替换您的 GithHub 用户名。

git clone [https://github.com/your_username/first-contributions.git](https://github.com/discdiver/first-contributions.git)

cd放入你的项目文件夹。

3.设置您的本地存储库来跟踪原始存储库中的更改。

git remote -v在 GitHub 上展示你的远程仓库。您应该会看到类似这样的内容:

origin https://github.com/discdiver/first-contributions.git (fetch)
origin https://github.com/discdiver/first-contributions.git (push)

为了跟踪原始的 firstcontributions 存储库,我们需要将其添加为远程上游存储库。要使用的命令是git remote add upstream [https://github.com/firstcontributions/first-contributions.git](https://github.com/firstcontributions/first-contributions.git)

git remote -v 现在应该给你看这样的东西:

origin https://github.com/discdiver/first-contributions.git (fetch)
origin https://github.com/discdiver/first-contributions.git (push)
upstream https://github.com/firstcontributions/first-contributions.git (fetch)
upstream https://github.com/firstcontributions/first-contributions.git (push)

你准备好了!

4.现在用git checkout -b “add_my_name”做一个新的本地分支。

只要你需要,git branch就会显示你当地的分支机构,以及你在哪个分支机构。😄

5.在代码编辑器中打开 Contributors.md 文件。将您的名字添加到第一行或最后一行以外的行中。保存文件。

6.使用git status检查一切是否正常。

7.用git add -A改变阶段。

8.用git commit -m “my commit message”提交您的更改。

9.用git checkout master切换到主分支。

10.用git merge add_my_name将您的更改从本地特征分支合并到本地主分支。

11.从远程first contributionsrepo 获取最新的更改,以确保您的更改不会干扰自您克隆 repo 以来所做的其他更改。使用git fetch upstream将更改放入您的本地 Git 存储库。

12.如果原回购发生变更,您可以通过git merge upstream/master将变更合并到您当地的主分行。

除了合并变更之外,您还可以集成变更并使用git rebase创建一个线性提交历史。重置基础会带来问题,所以除非你确定你在做什么,否则不建议这么做。这里是一个关于这个话题的讨论和一个强有力的反 rebase 论点是这里是。

13.当集成您的提交时,您的更改有时会与已经合并到远程存储库中的其他人的更改相冲突。例如,您可能已经更改了另一个人也更改了的一行代码。

Atom 通过向您显示您或他们更改了文件的哪些部分,使解决这些合并冲突变得很容易。

Wilma wants to add her name

选择每个冲突要使用谁的更改。解决所有更改后,您可以提交您的更改。

在更高级的项目中,您可能需要运行测试和/或构建文档,以确保您的更改不会破坏东西。对于这个基本示例,这两个步骤都不是必需的。

14.用git push origin master将您的本地更改推送到原始存储库的分支中。

15.在浏览器中转至您的回购,并创建一个拉取请求。

在更复杂的项目中,可能会自动运行持续集成(CI)测试。如果是这样,您将能够看到您的更改是否使回购通过或未通过 CI 测试。如果失败了,你可能不得不做出改变。😦

您可以将额外的提交推送到同一个分支,CI 测试将自动重新运行。

对于这个小例子,您不必担心 CI 测试。只是坐以待毙,让项目维护人员审核你的 PR,合并到主分支。恭喜你为一个开源项目做公关!👍

重复🔁

概述

让我们回顾一下我们的工作流程。

场景 1:单飞推主工作流

首先创建一个 repo 并在本地克隆它。然后:

  1. git checkout -b my_feature_branch
  2. 编写并保存代码。
  3. git status
  4. git add -A
  5. git commit -m "my commit message"
  6. git checkout master
  7. git merge my_feature_branch
  8. git push origin master
  9. git branch -d my_feature_branch

场景 2:单独拉式请求工作流

  1. git checkout -b my_feature_branch
  2. 写代码。
  3. git status
  4. git add -A
  5. git commit -m "my commit message"
  6. git push origin my_feature_branch
  7. 在浏览器中打开 PR。
  8. 确认公关。
  9. 合并公关。
  10. 删除远程要素分支。
  11. git checkout master
  12. git pull origin master
  13. git branch -d my_feature_branch

场景 3:单独克隆的项目

  1. git clone repo_to_be_cloned

场景 4:合作参与项目

  1. 在浏览器中派生原始回购。
  2. git clone repo_to_be_cloned
  3. git remote add upstream original_repo
  4. git checkout -b my_feature_branch
  5. 写代码。
  6. git status
  7. git add -A
  8. git commit -m "my commit message"
  9. git checkout master
  10. git merge my_feature_branch
  11. git fetch upstream
  12. git merge upstream/master
  13. 解决任何合并冲突。如果有冲突,提交您的更改。
  14. git push origin master
  15. 在浏览器中,发出一个“拉”请求,将您的分支合并到远程上游主分支中。

包装

知道如何使用 Git 和 GitHub 是强大的、必不可少的,有时也会令人困惑。希望本指南为您提供了一些可行的工作流程,您可以在需要时参考。如果有,请在你最喜欢的社交媒体渠道上分享,这样其他人也能找到它!👏

在以后的文章中,我们将了解其他重要的 Git 命令。跟着 me 确保不要错过。😄

我撰写关于数据科学、Python、Docker 和其他技术主题的文章。如果你对这些感兴趣,请点击这里查看。

祝你快乐!😀

学习足够有用的 Python:arg parse

原文:https://towardsdatascience.com/learn-enough-python-to-be-useful-argparse-e482e1764e05?source=collection_archive---------2-----------------------

如何在脚本中加入命令行参数

如果你计划成为一名 Python 软件开发人员,你会希望能够使用argparse来满足你的脚本需求。如果您是一名数据科学家,您可能会发现自己需要将 Jupyter 笔记本中的代码移植到可复制的脚本中。对于许多新的数据科学家来说,这可能是从一个舒适、快乐的地方向可怕的土地迈出的一步。本指南旨在让跳跃不那么可怕。

Like a mountain through the clouds, argparse brings arguments from the command line. 😏

[argparse](https://docs.python.org/3/howto/argparse.html#id1)是“Python 标准库中推荐的命令行解析模块”它是你用来把命令行参数放进你的程序的。

当我需要的时候,我找不到一个好的argparse介绍指南,所以我写了这篇文章。尽情享受吧!

Jupyter is great

超越朱庇特笔记本

我第一次在一个业余项目的 Python 脚本中看到argparse时,我想,“这是什么巫术?”并迅速将代码转移到 Jupyter 笔记本上。这一举措被证明是次优的。😦

我希望能够运行脚本,而不是一步一步地翻阅笔记本。带有argparse的脚本使用起来会简单得多,工作量也会少得多。不幸的是,我赶时间,没有找到容易掌握的文件。

从那以后,我开始理解并享受argparse。不可或缺。

以下是你需要知道的。

为什么要使用 argparse?

*argparse* 解析参数。

使用argparse可以让程序的用户在运行时为变量提供值。它是程序作者和用户之间的一种交流方式。那个用户可能就是你未来的自己。😃

使用argparse意味着不需要进入代码并修改脚本。让用户能够输入命令行参数提供了灵活性。

Python is great, too!

例子

假设您有一个包含视频的目录,并希望使用 OpenCV 库将这些视频转换成图像。您可以使用argparse让用户输入输入和输出目录。下面是你的 videos.py 文件的argparse部分的样子:

# videos.py
import argparseparser = argparse.ArgumentParser(description='Videos to images')
parser.add_argument('indir', type=str, help='Input dir for videos')
parser.add_argument('outdir', type=str, help='Output dir for image')args = parser.parse_args()print(args.indir)

这个文件导入了argparse库。然后,它创建一个带有描述的解析器对象。然后使用parser.add_argument()创建变量间接。变量的类型设置为 string,并提供一条帮助消息。然后对输出进行同样的操作。接下来 args 变量被设置为解析后的参数值。

现在,可以从命令行运行以下命令:

python videos.py /videos /images

注意,当您传递值/videos/images时,不需要用引号将它们括起来。

"/videos"成为args.indir的值,"/images"成为args.outdir的值。

打印到终端的输出是/videos

我们刚刚展示了您可以在程序中的任何地方使用args.indir变量。多酷啊。

您现在已经看到了 argparse 的魔力!

How do they do that?

关于 argparse 还应该知道什么?

位置参数

parser.add_argument('indir', type=str, help='Input dir for videos')创建了一个位置自变量。对于 Python 函数的位置参数,顺序很重要。从命令行传递的第一个值成为第一个位置参数。传递的第二个值成为第二个位置参数。

如果您排除这些位置参数并尝试运行python videos.py会发生什么?

您将得到一个错误:videos.py: error: the following arguments are required: indir, outdir。运行脚本的命令中总是需要传递位置参数。

可选参数

如果运行python videos.py --help会怎么样?

我们把有用的信息放进我们的脚本,告诉你需要做什么。

Output of python videos.py --help

太棒了。help是一个可选参数的例子。注意--help是你唯一免费得到的可选参数,但是你可以做更多。

可选参数的创建类似于位置参数,只是它们的名称开头有一个'--'双破折号(或者一个'-'单破折号和一个额外的字符用于短版本)。例如,您可以使用parser.add_argument('-m', '--my_optional')创建一个可选参数。

以下较大的示例显示了如何创建和引用可选参数。注意,在这个例子中,我们为整数指定了类型int。您还可以指定其他有效的 Python 变量类型。

# my_example.py
import argparseparser = argparse.ArgumentParser(description='My example explanation')parser.add_argument('--my_optional',default=2,help='provide an integer (default: 2)'
)my_namespace = parser.parse_args()print(my_namespace.my_optional)

注意,用'--my_optional'指定的参数变成了这个不带破折号的命名空间变量:'my_namespace.my_optional'

另请注意,可选参数可以有默认值。这里我们指定默认值为 2。运行python my_example.py输出 2

可选参数值可以在运行时从命令行设置,如下所示:python my_example.py--my_optional=3。然后程序输出 3

Integers

使用argparse,您可以做更多事情。例如,您可以使用nargs='*’将参数收集到列表中。您也可以使用choices检查数值范围。请参见[argparse](https://docs.python.org/3/library/argparse.html) 文档了解您能做的一切。

我还可以在什么时候使用 argparse?

您也可以将argparse用于 Docker 容器中运行的程序。如果您想在构建映像时向脚本传递命令行参数,可以使用 RUN。如果想在运行时向脚本传递参数,可以使用 CMD 或 ENTRYPOINT。在我的 Docker 系列中了解更多关于 Dockerfiles 的信息:

[## 学习足够的码头工人是有用的

第 3 部分:一打漂亮的 Dozen 文件指令

towardsdatascience.com](/learn-enough-docker-to-be-useful-b0b44222eef5)

包装

现在你已经看到了argparse的基础。您已经看到了如何从命令行将位置参数和可选参数输入到程序中。您还看到了如何设置默认的可选参数。如果你想深入了解,请查阅官方文件。

更新 2019 年 3 月 6 日我应该提一下,有很多包可以用来给你的程序添加命令行参数。读者在评论中提出了几个建议,其中最受欢迎的我在这里做了链接:

  • 点击
  • docopt

More mountains through the mist

这里还有一些建议可以帮助你走出 Jupyter 笔记本。

环境变量是在程序外部设置的有用变量。这里有一个很好的,清晰的介绍。这篇来自 DataCamp 博客的文章关注的是路径变量。

您可以使用 Jupyter 笔记本将 repos 转换为 Docker 图像,使用 Repo2Docker 。 Will Koehrsen 在这里写了一篇关于工具的很好的指南。

我计划写更多关于与文件系统和脚本交互的文章。跟着我,确保你不会错过他们!😃

我希望这篇介绍对你有用。如果你有,分享到你最喜欢的论坛和社交媒体上。不知道argparse的数据科学家和程序员会感谢你的!

我写关于数据科学、云计算和其他技术的东西。关注我,在这里阅读更多。

感谢阅读!👏

学习足够有用的 Python 第 2 部分

原文:https://towardsdatascience.com/learn-enough-python-to-be-useful-part-2-34f0e9e3fc9d?source=collection_archive---------17-----------------------

如何使用 if name == "main

本文是帮助您熟悉 Python 脚本的系列文章之一。它面向数据科学家和任何 Python 编程新手。

cat_breed = maine_coon

if __name__ == "__main__":是你在 Python 脚本中看到的那些经常不被解释的东西之一。你可能已经看过上百个关于 Python 列表理解的教程,但是 Python 脚本约定却没有得到足够的重视。在这篇文章中,我将帮助你把这些点联系起来。

state = maine

if __name__ == "__main__":确保 if 块中的代码只有在找到它的文件被直接运行时才运行。让我们来分析一下这是如何工作的。

这是什么?

每个 Python 文件都有一个名为__name__的特殊属性。

测试一下。创建一个以print(__name__)为唯一内容的 Python 文件 my_script.py 。然后在您的终端中运行python my_script.py__main__你将会看到。

注意,名字两边都是双下划线。那些被称为 dunders 的是双下划线。他们也被称为魔法方法特殊方法

您可能熟悉来自 init 方法的 dunders,该方法用于初始化您创建的类的对象。

为什么要用 main

如果您将文件作为模块导入,则代码不会运行。只有当该文件作为自身运行时,代码才会运行。

看看这个例子。代码可从 GitHub 获得。

# my_script
print(f"My __name__ is: {__name__}")def i_am_main():print("I'm main!")def i_am_imported():print("I'm imported!")if __name__ == "__main__":i_am_main()
else:i_am_imported()

使用python my_script.py在终端中运行程序会导致

My __name__ is: __main__
I'm main!

好的。这正是我们所期待的。😀__name__被设置为__main__,因为文件本身被执行。

让我们看看如果导入文件会发生什么。用python在终端中启动一个 IPython 会话,然后用import my_script导入文件(用 no。py 扩展名)。这会产生以下输出:

My __name__ is: my_script
I'm imported!

狂野!文件导入后,__name__成为文件名my_script!又不是*__*main*__*

所执行的功能是 else bloc: i_am_imported中的功能。

当您创建一个真正的模块导入到您的程序中时,这个功能是很有用的。测试时也很方便。在这里阅读更多。

another_cat = maine_coon

包装

希望这个解释能让你在使用 Python 脚本时更加得心应手。去和if __name__ == "__main__":玩玩,找个人解释一下,巩固你的知识。

如果您对 Python 脚本的更多技巧感兴趣,请查看我写的这篇关于argparse的文章。

[## 学习足够有用的 Python:arg parse

如何在脚本中加入命令行参数

towardsdatascience.com](/learn-enough-python-to-be-useful-argparse-e482e1764e05)

我正在撰写更多关于跳出 Jupyter 笔记本的文章,所以请关注我并加入我的数据惊人邮件列表,确保你不会错过它们!🎉

我希望这个指南对你有所帮助。如果你有,请在你最喜欢的社交媒体渠道上分享,这样其他人也可以找到它。😃

感谢阅读!👏

通过更智能的数据标签更快地学习

原文:https://towardsdatascience.com/learn-faster-with-smarter-data-labeling-15d0272614c4?source=collection_archive---------8-----------------------

用不同的主动学习技术优化标记过程的发现

简介

大量的深度学习工具使我们能够以令人难以置信的性能快速构建新的应用程序,从计算机视觉对照片上的复杂对象进行分类,到通过从文本中提取语义来理解自然语言。然而,所有这些方法的主要瓶颈是训练所有这些模型所需的大量数据,通常有数十万个训练示例。

如果您从零开始构建图像分类器,比方说,为了检测车道上的陈旧产品,您将需要几周或几个月的时间来收集和手动注释所有这些照片。幸运的是,有许多深度神经网络,已经在具有许多类的大型图像数据集上进行了预训练,并准备好用于缓解冷启动问题。迁移学习的核心思想是利用这些模型的输出,捕捉高级图像语义,作为解决目标任务的新分类器的输入。它大大减少了需要人工标注的数据量,从几十万到几千张图像。

然而,即使注释成千上万的例子也可能是昂贵的,尤其是如果每个注释任务都依赖于主题专家的知识。理想情况下,它将非常适合只标记几百个任务,并让深度学习机器在没有任何监督的情况下进行自我学习。这个问题也被称为预算学习:我们节约了花费在获取训练数据集上的钱,以建立所需性能的模型。另一个问题与概念漂移有关——当目标任务随时间变化(新产品进入检测机生产线)并且预测性能在没有人为干预的情况下下降。

更聪明地学习

那么,除了迁移学习所提供的,我们能进一步减少标记工作量吗?事实上,答案是肯定的,有一些技术是存在的。其中研究得最好的就是 主动学习 。原则很简单:只标注对你当前模型有用的东西。形式上,主动学习算法可以概括为以下步骤:

  1. 训练初始模型
  2. 选择一个最有用的样本(一个模型不确定的样本,基于它的预测分类概率)
  3. 标记此样本并将其添加到训练集中
  4. 基于新训练集的再训练模型
  5. 从步骤 2 开始重复

这种启发式方法对老派的机器学习模型(例如线性分类器,如逻辑回归、SVM 等)非常有效。),但实证研究表明,它在深度学习环境中变得无效。另一个很少提到的缺点是,经典的主动学习需要在每个新的标记样本后重新训练模型,这是一个耗时的过程。

因此,总的来说,为了能够在没有任何标记数据的情况下,以最少的人力快速训练新的分类器,我们必须处理以下问题:

  1. 利用由一些高质量的预训练模型产生的特征空间
  2. 仅选择信息最丰富的样本,由人工注释者进行标记
  3. 快速更新我们当前的机器学习状态

第一步在许多研究论文和评论中得到了很好的研究,甚至大型企业公司现在也分享他们预先训练的神经网络,可以非常容易地以 的方式插入到特征提取管道中。理想的起点是看tensorflohub

下一步是机器学习的微妙艺术。尽管样本的信息量背后的直觉是清楚的,但不清楚如何准确地计算它。因此,存在许多基于类别概率的不同度量【p₁(x】【p₂(x】,…【pᵢ(x】, …,按降序排序:

Uncertainty

Margin

Entropy

一旦我们发现了这种不明确的例子 x ,我们就有希望看到模型在经过重新训练后,在 x 的邻域内变得更加自信。但是如果 x 的邻域内没有项目呢?实际上,尽管这个例子具有模型不确定性,但它没有为我们提供足够的信息来加快模型收敛,所以我们必须从我们的搜索空间中排除这样的异常值。这可以通过最大化:

Informational Density

也叫一个例子的信息密度。通过最大化【x】,我们只挑选那些在我们的特征空间中被其他点密集包围的点。

不确定性测量与信息密度相结合,使我们能够挑选出优秀的代表点,并为模型提供新的知识。但是如果有两个模型不自信的代表点,你怎么选择一个呢?一种方法是选择与已经选择的例子最不相似的例子。最后一个成分信息指标是多样性:

这促进了尽可能多的选择不同的点。

要在一个评分函数中结合这三个指标,可以使用它们相应的累积分布函数(CDF)的乘积(否则,您应该处理不同标度的数字,甚至负数):

Scoring Function

其中每个大写字母函数表示 CDF,例如U(x)= P(U<U(x))

更快获得结果

最后,我们选择了示例,并可以对其进行标记(有许多数据标记工具可用。最后一步是训练模型。可能要等几个小时,直到模型完成重新训练过程,我们才能继续下一个样本。

那么如果我们根本不训练呢?听起来很疯狂,但是,如果您的特征空间存在,没有任何额外的参数需要学习,那么您可以依赖它产生的嵌入,并使用简单的度量标准,如欧几里德距离和余弦距离。这种技术被称为 k-最*邻分类器:对于任何样本,从最*邻的类(或从 k 个最*邻)中指定未知类。

尽管它很简单,但它是一种非常强大的方法,因为:

  • 它支持立即“学习”新模型——实际上不执行任何学习,标记的示例只是存储在一些有效的数据结构中(除非您使用强力搜索)
  • 它产生一个非线性模型
  • 它可以很容易地扩展和部署,无需模型再培训——只需在运行模型中添加新的向量
  • 如果像欧几里德这样简单的距离还不够,新的度量空间可以离线学习(参见一些度量学习方法的概述以及少量学习
  • 它还提供了一些可解释性:当对一些未知的例子进行分类时,总是有可能调查是什么影响了这种预测(因为我们可以访问所有的训练集,这在只有学习参数的情况下是不可行的)

下面是它在实践中的样子:

有两类,紫色( p )和橙色( o )。在每一步,我们的选择方法试图尽最大努力获得最丰富的例子,并将其标记出来。正如你所看到的,模型总是试图在第一和第二类点之间挑选下一个样本,主要是因为最大化不确定性度量【x】导致最小化

T 什么导致边界探索(大约 X=0 )在~30 的前几步。然后我们的主动选择方法试图潜入密集的点群,感谢信息密度。此外,由于多样性度量,它总是旨在探索不同的点,这是更好的方式:传统的主动学习只停留在一个边界上,可能会忽略不同的点群。

验证和结果

为了验证这种主动采样方法,让我们在新鲜/腐烂水果图像的真实数据集上运行一个实验。

水果有 3 类(苹果、香蕉、橘子),每类都有新鲜和腐烂的图片曝光,所以一共 6 类。数据集的 90%被保留用于训练目的,其余的用于测试。为了减少统计误差,使用 K=16 的 K 倍交叉验证,然后对测试误差进行*均。

我们将MobileNet-v2神经网络的 1280 维输出作为特征空间的嵌入,度量空间采用余弦距离。以下是关于嵌入式数据集外观的一些见解

您可以看到有一些云团,因此除了不确定性之外,我们还可以通过使用额外的信息含量指标来获益。

此处描述了*均模型性能与标记示例数量的关系。正如我们所看到的,与随机选择点进行标记的策略相比,主动采样策略达到 90%的准确率所需的标记任务几乎减少了两倍。

另一个实验是在文本数据上进行的,这些数据取自 sensition 140数据集。这项任务包括将推文分为积极/消极情绪。出于实验目的,我们随机采样 20k 个点,并对上面的新鲜/腐烂水果图像进行相同的实验。作为特征提取器,通用语句编码器为每条推文生成 512 维嵌入。

类似地,这里是模型如何执行标记步骤,比较主动和随机选择策略。同样,主动选择应该收敛得更快,尽管绝对性能较低(只有 62%的精度,当使用完整数据集时,70%是最佳精度)。

总结

  • 当标记过程是构建下一个机器学习项目的瓶颈时,使用主动学习来最小化标记任务的数量
  • 使用预先训练的深度神经网络的输出,将您的任务从原始数据(图像、文本)转换为矢量(嵌入)
  • 应用信息性度量的组合来挑选下一个训练样本,以减少模型的不确定性,促进代表性和多样性
  • 当您想要进行即时训练和快速透明的预测时,请选择 k-NN 作为您的分类器
  • 将您在每个步骤中的主动学习结果与维持数据集上的统一采样策略进行比较,以了解性能如何随挑选步骤而变化,以及如何节省您的标注预算

学会如何倾听

原文:https://towardsdatascience.com/learn-how-to-listen-edaea38fb276?source=collection_archive---------15-----------------------

作为一名数据科学家最难的部分之一。

当你开始学习数据科学(DS)课程和 MOOCs 时,他们没有告诉你的一件事是,你的大量时间(一千多)将花在会议上。

这些会议很重要。非常重要。在那里你可以了解业务,该领域的目标,他们的 KPI,以及他们希望你做的工作的要求。

倾听。最难的部分。

有时候倾听很难。你可能会听到一些你不想听到的事情,或者你所有的信念都动摇了。

因此,学会倾听是一项需要日积月累的技能。通常在工作会议中,会有许多不同的观点,与其总是试图将你的观点强加于人,不如努力达成一致,并找到解决问题的更通用的解决方案。

这里要小心,这并不意味着如果你是对的,并且你有办法证明它,你就应该呆在那里,同意任何事情。思想精英的概念在这里很重要。每个人都有自己的观点,一个比另一个更好,能够辨别并找到问题的最佳解决方案是可能的。在这里,您可以看到一个很棒的视频,它以一种更加图形化的方式解释了这一点:

如果你想在 DS 中增加价值和改进流程,倾听和理解是至关重要的。因此,我在这里提到了我在这些会议中如何倾听和表现的一些经验教训:

谦虚一点

Observe and understand

是的,你可能认为你知道很多,或者人们以前创建的一些模型,因为没有使用“深度学习”,是不够的。但那不是办法。

倾听他们所说的,理解他们创造模型和解决方案的心理过程。不要低估,或者说“是的,你们做的事情又老又奇怪,等我的吧”。

https://twitter.com/faviovaz

认真听,像真的一样。

Stone cold listening

不要只是盯着演示文稿,或人们的脸,你的手机或其他任何东西。利用这 30-45 分钟来开一个富有成效的会议,集中注意力。需要就做笔记,但是要注意,这是他们应得的。

到场

Be active.

这意味着,问问题,对他们说的和做的事情感兴趣。建设,不要破坏。

将想法转化为恰当的问题

一名优秀的数据科学家需要将问题和想法转化为适定的问题,我指的是在数据科学过程中有解决方案的问题。

[## 创建 ROI 驱动的数据科学实践的敏捷框架

数据科学是一个令人惊叹的研究领域,学术界和工业界都在积极发展…

www .商业科学. io](https://www.business-science.io/business/2018/08/21/agile-business-science-problem-framework.html)

如果找不到一个可行的路径来解决这个问题,最终将解决这个问题,那么有两个选择,回去继续问问题,或者这个问题不能用数据科学来解决。

你可以问一些有助于澄清某些会议气氛的问题:

  1. 这个模型是什么时候创建的,你用什么数据建立的?
  2. 模型的限制是什么,你创建模型的假设是什么?
  3. 您使用了哪些语言或框架来构建模型?
  4. 您是否有创建模型的完整过程文档?
  5. 模特表现如何?你对数据科学团队有什么需求?
  6. 有多少人参与了这个项目?
  7. 你为什么走这条路?你考虑的还多吗?
  8. 这个变量从何而来?
  9. 你能和我们分享一下这个项目的技术细节吗?
  10. 项目的范围是什么?
  11. 你提议的项目时间表是什么?
  12. 你对项目的目标有多灵活?
  13. 你为什么认为这是一个数据科学项目?
  14. 项目的优先级是什么?

玩得开心!

这是你闪光和帮助的时候了!

感谢阅读。如果您有任何建议或其他推荐,请分享:)

了解如何用 Python 快速创建 ui

原文:https://towardsdatascience.com/learn-how-to-quickly-create-uis-in-python-a97ae1394d5?source=collection_archive---------2-----------------------

最后,你可以在 5 分钟内找到一个图书馆

Photo by Eftakher Alam on Unsplash

python 的最大优势是易用性和丰富的库。通过几行代码,没有什么是你做不到的。只要您的 python 脚本是供个人使用的,或者您的目标受众具有足够的技术水*,您就永远不必考虑用户界面(UI)。

然而,有时候你的目标受众不够专业。他们很乐意使用你的 python 脚本,但前提是他们不用看任何一行代码。在这种情况下,提供命令行脚本是不够的。理想情况下,你需要为他们提供一个用户界面。虽然如果你有典型的桌面客户端基于网络的 UI 的争论,我不会感到惊讶,但是在这篇博文中,我们的目标是专门使用 Python。

可供用户界面使用的 Python 库

本质上有 3 个大的 Python UI 库;Tkinter,wxPython 和 PyQT。在回顾这三个库的时候,我意识到我喜欢的 Python 的所有东西在使用这些库的时候都找不到。总的来说,Python 库在抽象掉超级技术方面做得非常好。如果我需要使用面向对象编程,我还不如加载 Java 或. Net。

然而,令我非常高兴的是,我遇到了第四个选项,似乎迎合了我的喜好。我开始审查并最终选择从中创建 Python UIs 的库叫做 PySimpleGUI。有趣的是,这个库使用了所有 3 个流行的库,但是抽象掉了超级技术。

事不宜迟,让我们通过同时解决一个实际问题来深入研究这个库。

检查两个文件是否相同

使用我以前的文章 3 种在 Python 中比较数据的快速方法, 我们可以使用第一部分,检查数据的完整性来尝试构建一个 UI。

[## 在 Python 中比较数据的 3 种快速方法

对于任何从事分析工作的人来说,收到比较数据的请求都太熟悉了。不管那是…

medium.com](https://medium.com/financeexplained/3-quick-ways-to-compare-data-in-python-65201be10b6)

我们本质上需要一种方法来加载两个文件,然后选择我们想要使用的加密来进行文件比较。

编写用户界面代码

要构建该 UI,我们可以使用以下代码:

import PySimpleGUI as sg
layout = [[sg.Text('File 1'), sg.InputText(), sg.FileBrowse(),sg.Checkbox('MD5'), sg.Checkbox('SHA1')],[sg.Text('File 2'), sg.InputText(), sg.FileBrowse(),sg.Checkbox('SHA256')],[sg.Output(size=(88, 20))],[sg.Submit(), sg.Cancel()]
]
window = sg.Window('File Compare', layout)
while True:                             # The Event Loopevent, values = window.read()# print(event, values) #debugif event in (None, 'Exit', 'Cancel'):break

这导致:

Simply Python UI, generated by the above code

插入逻辑

有了 UI,就很容易看到如何插入其余的代码。我们只需要监视用户输入的内容,然后采取相应的行动。我们可以很容易地做到这一点,用下面的代码。

import PySimpleGUI as sg
import re
import hashlibdef hash(fname, algo):if algo == 'MD5':hash = hashlib.md5()elif algo == 'SHA1':hash = hashlib.sha1()elif algo == 'SHA256':hash = hashlib.sha256()with open(fname) as handle: #opening the file one line at a time for memory considerationsfor line in handle:hash.update(line.encode(encoding = 'utf-8'))return(hash.hexdigest())layout = [[sg.Text('File 1'), sg.InputText(), sg.FileBrowse(),sg.Checkbox('MD5'), sg.Checkbox('SHA1')],[sg.Text('File 2'), sg.InputText(), sg.FileBrowse(),sg.Checkbox('SHA256')],[sg.Output(size=(88, 20))],[sg.Submit(), sg.Cancel()]
]window = sg.Window('File Compare', layout)while True:                             # The Event Loopevent, values = window.read()# print(event, values) #debugif event in (None, 'Exit', 'Cancel'):breakif event == 'Submit':file1 = file2 = isitago = None# print(values[0],values[3])if values[0] and values[3]:file1 = re.findall('.+:\/.+\.+.', values[0])file2 = re.findall('.+:\/.+\.+.', values[3])isitago = 1if not file1 and file1 is not None:print('Error: File 1 path not valid.')isitago = 0elif not file2 and file2 is not None:print('Error: File 2 path not valid.')isitago = 0elif values[1] is not True and values[2] is not True and values[4] is not True:print('Error: Choose at least one type of Encryption Algorithm')elif isitago == 1:print('Info: Filepaths correctly defined.')algos = [] #algos to compareif values[1] == True: algos.append('MD5')if values[2] == True: algos.append('SHA1')if values[4] == True: algos.append('SHA256')filepaths = [] #filesfilepaths.append(values[0])filepaths.append(values[3])print('Info: File Comparison using:', algos)for algo in algos:print(algo, ':')print(filepaths[0], ':', hash(filepaths[0], algo))print(filepaths[1], ':', hash(filepaths[1], algo))if hash(filepaths[0],algo) == hash(filepaths[1],algo):print('Files match for ', algo)else:print('Files do NOT match for ', algo)else:print('Please choose 2 files.')window.close()

运行上述代码将会产生以下结果:

结束语

虽然这个库不是最好看的 ui,但是它允许你快速地创建简单的 python UIs,并与你需要的任何人分享。更重要的是,这样做所需的代码非常简单,可读性很强。您仍然会有必须运行代码来获得 UI 的问题,这可能会使共享有点困难,但是您可以考虑使用 PyInstaller 之类的东西,它会将您的 python 脚本转换为人们只需双击即可的. exe。

在你离开之前,如果你喜欢这篇博客,并且想看看如何构建更复杂的用户界面,请查看:

[## 构建 Python UI 以保持库的最新状态

就在几天前,我试图通过使用最*引入的功能来解决我的一个问题

link.medium.com](https://link.medium.com/qEZnbhQQc6) [## 构建用于比较数据的 Python UI

如何快速让您的非技术团队能够比较数据

towardsdatascience.com](/building-a-python-ui-for-comparing-data-13c10693d9e4)

用鸡饭学习机器学习和计算机视觉

原文:https://towardsdatascience.com/learn-machine-learning-and-computer-vision-using-chicken-rice-9416bf61efad?source=collection_archive---------17-----------------------

我在最*的 PechaKucha 上就“如何在人工智能取代你之前取代它”发表了演讲。为了展示我们今天拥有的机器学习算法有多智能,我举了一个例子,我们可以很容易地训练一个机器学习模型来区分不同类型的鸡饭(一种典型的马来西亚/新加坡人最喜欢的美食)。

许多参与者在活动结束后立即联系我,并问了类似这样的问题:

  • 那是真的吗?真的可以训练机器模型识别鸡饭吗?
  • 除了鸡饭,我还能把它用于其他用例吗?
  • 图像的机器学习是如何工作的?

这就是本教程的背景。我将一步一步地向你展示如何训练一个机器学习模型,使用计算机视觉来识别鸡饭。在此之前,我们需要以下物品:

  • 一组鸡饭图像
  • 地面实况(标注类)
  • 一个谷歌云*台,GCP 帐户(为我们使用谷歌汽车视觉云服务。)

最初的想法来自这篇博文。

我将尽可能地遵循他的方法,并添加额外的提示,让你更容易理解。我包括了一些细节,比如 scrapper 和带标签的训练数据,以使工作具有可重复性,这样你就可以自己尝试了。

我相信由于 Instagram 的限制,我不能将标记的训练数据与图片分享。但是您可以从这里的文件中获得文件名及其相应的类。

观看上面的整个教程。更喜欢看书?下面继续就好。

O.S.E.M.N 框架

让我们遵循 5 步 OSEMN 框架来指导我们完成这个过程。

OSEMN 框架旨在帮助我们在不同阶段关注并优先考虑正确的数据科学任务。

步骤 1:获取数据

我们将需要找到鸡饭图像作为我们的训练数据集。

对我们来说幸运的是,有一个新加坡人每天都吃鸡饭(在写作时连续 454 天),并把它的照片发布到他的 Instagram 账户 @kuey.png 。

Kuey Png 在闽南语中的字面意思是鸡饭。

然后你可以使用刮刀将所有图像下载到你的本地电脑。我用的是 https://github.com/rarcega/instagram-scraper 的 Python 版本。不要忘记在最后加上-u <username> and -p <password>(我已经镶嵌的部分)。

步骤 2:擦除数据

数据永远不会变得清晰,即使是在这样一个有这么多精心拍摄的照片的集中数据集中。虽然大多数照片都不错,但你会遇到像下面这样的照片——事实上,不难看出这是一包蒸鸡饭。

He was probably too hungry to take a good picture

真正的挑战来自特殊情况,我们不得不从训练集中排除以下图像,因为我们的专家无法得出结论。

steamed chicken rice mixed with char siew (bbq pork)

我们也排除 7 张扒鸡(另一种烧鸡方式)的照片。因为它们既不是蒸鸡也不是烤鸡。此外,我们没有足够的训练图像来将其分类为单独的类别。

步骤 3:浏览数据

在我们探索我们的数据之前,我们将需要标记图像并创建地面真相。在数据科学项目中,术语“基础事实”指的是收集适当的客观数据的过程。

在图像分类任务中,地面真实指的是我们手动标记的训练分类,用于监督学习。

根据基准,我们从我们的团队中聘请了 3 个人作为专家,他们对鸡饭类型有足够的了解来标记这些图像。只有当三位专家一致同意标签时,我们才会使用图片。

He obviously preferred roasted chicken (but I don’t judge).

在标记过程之后,我们的训练数据包含 447 个训练图像。我们将 285 张图片标注为烤鸡 (63%),162 张图片标注为蒸鸡 (37%)。

贴标签的人无法达成共识的图片被丢弃,同时被丢弃的还有焖鸡的图片。以后训练图像多了,我们可能会把【扒鸡】作为另一类加入。

步骤 4:模型数据

如果你读到这里,这是你一直在等待的部分。建模阶段。

我将向你展示我是如何使用谷歌自动视觉的具体步骤。首先,你需要建立一个谷歌云账户。

Google Cloud Dashboard

创建一个新项目,从左侧菜单栏中选择 Vision at,点击getting started with AutoML创建一个自定义模型。相应地设置计费信息

不要担心被收取你的信用卡资料,谷歌承诺,他们会在收取你的信用卡费用前征求你的许可。然后,点击“立即设置,等待该过程完成。

然后,单击“创建数据集创建一个新的数据集来存储我们的鸡饭图像。选择“稍后导入图片,因为我们会自己上传两批鸡饭图片,选择“启用多标签分类”。

在上传图片之前,我们先创建两个标签,分别是: 点击添加图像,将我们的训练图像上传至 AutoML Vision。

之后上传烤鸡的图片。确保为图像标记“烘焙”,如下图所示。对蒸鸡图像也重复同样的过程。

一旦我们上传并标记了训练数据,我们就可以开始训练模型了。AutoML vision 要求每个标签至少有 100 张图像。

因此,当我们有更多的训练数据时,我们只能包括扒鸡图像(保持良好的工作,先生)。点击“开始训练,等待大约 15-20 分钟来建立我们的模型。培训过程完成后,您将收到一封电子邮件通知。

步骤 5:解释模型

Precision recall evaluation for “steamed” class

AutoML 简化了许多建模任务,甚至简化了数据科学家需要几个小时才能完成的评估。点击“查看完整评测”来看看我们这款车型的性能吧。(请注意,在构建模型时,您的结果可能会有所不同)。

我们通常在分类任务中使用的指标是精度召回

例如,如果我们查看蒸鸡类,Precision 测量预测能力,即我们的模型检测到多少蒸鸡图像是正确的。回忆然后测量检索所有蒸鸡图像的能力。

有一个滑块,我们可以调整分数阈值。换句话说,如果我们将阈值设置为 0.00,我们的召回率将是 100%(因为我们可以说每个图像都是“蒸过的”,我们不会错过任何图像),但精度将非常差。

一旦你完成了性能评估,我们就可以进入有趣的部分,使用我们的模型来预测未知的鸡饭图像。

你可以自己拍一张鸡饭的照片或者只去 Google images 找一些图片。这些是我在预测测试中使用的图片。

结果是相当惊人的和准确的,对吗?

结论——接下来是什么?

虽然这是一个简单的例子,但它是一个每个人都能很容易联系起来的例子。我已经向你展示了我们建立一个基于计算机视觉的机器学习模型是多么简单。

实际上,我们需要更好地了解特征本身,以及如何根据纹理、颜色分布、线条和边缘特征选择好的图像用作训练集。对于没有技术背景并且希望通过构建机器学习模型来学习的人来说,AutoML vision 绝对是一个很好的起点。

自己尝试一下,如果你能做到,请在下面的评论区告诉我!此外,如果你觉得这个教程有用,一定要和一个正在学习机器学习和计算机视觉的朋友分享。

最初发表于www . the lead . io

10 分钟学会元流——网飞的数据科学 Python/R 框架

原文:https://towardsdatascience.com/learn-metaflow-in-10-mins-netflixs-python-r-framework-for-data-scientists-2ef124c716e4?source=collection_archive---------2-----------------------

花更多时间建模,花更少时间管理基础架构。实践教程。

上周在 AWS re:Invent 上,网飞开源了一个用于构建和管理数据科学项目的本土框架——Metaflow。在过去的两年中,它在内部数据科学团队中得到了快速采用,使许多项目加快了生产时间。

Metaflow adoption at Netflix

什么是元流?

Metaflow 是一个用于创建和执行数据科学工作流的框架,配备了内置功能来:

  • 管理计算资源,
  • 执行集装箱化运行,
  • 管理外部依赖关系,
  • 版本、重放和恢复工作流运行,
  • 用于检查过去运行情况的客户端 API 适用于笔记本电脑,
  • 在本地(例如在笔记本电脑上)和远程(在云上)执行模式之间来回切换

元流在内容寻址的数据存储中自动对代码、数据和依赖项进行快照,虽然本地文件系统也受支持,但通常由 S3 提供支持。这使您可以恢复工作流程,重现过去的结果,并检查有关工作流程的任何内容,例如在笔记本中。

— 在 Ycombinator 上的虚拟世界

基本上,它旨在通过让数据科学家专注于实际的数据科学工作,并通过促进他们的可交付成果的更快生产,来提高他们的生产力。

Actual Data Science vs Infrastructure Concerns

元流使日常场景成为可能

  • 协作:你想帮助另一位数据科学家调试一个错误。你希望你能在你的笔记本电脑上调出他的失败运行状态。
  • 恢复运行:运行失败(或被故意停止)。您修复了代码中的错误。您希望可以从失败/停止的地方重新启动工作流。
  • 混合运行:您想要在本地运行工作流的一个步骤(可能是数据加载步骤,因为数据集在您的下载文件夹中)但是想要在云上运行另一个计算密集型步骤(模型训练)。
  • 检查运行元数据:三位数据科学家一直在调整超参数,以便在同一模型上获得更好的准确性。现在,您希望分析他们的所有训练运行,并选择性能最佳的超参数集。
  • 同一个包的多个版本:您希望在您的项目中使用多个版本的sklearn库——0.20 用于预处理步骤,0.22 用于建模。

那么,一个典型的元(工作)流是什么样子的呢?

概念地

元流工作流在本质上是Dag(有向无环图)—简单来说就是下面的图片。图中的每个节点代表工作流中的一个处理步骤。

A linear acyclic graph

A branched acyclic graph

Metaflow 在工作流的每个步骤中执行惯用的 python 代码,这些代码在单独的容器中与相应的依赖项打包在一起。****

Metaflow 架构中的这个关键方面使您能够在 Metaflow 中注入几乎任何来自 conda 生态系统的外部库,而不需要插件。这也是 Metaflow 与其他通用解决方案(如气流)的不同之处。

程序化

每个流都可以写成一个标准的 python 类,只要它满足以下最低条件:

  • 从 Metaflow 的FlowSpec类继承。
  • 代表一个步骤的每个函数都用一个@step装饰器标记。
  • 每个步骤函数都应该以指向它的后继步骤函数结束。你可以用self.next(self.function_name_here)做到这一点
  • 实现了startend功能。

以下是一个最小三节点流的示例:

start → process_message → end

A minimal three-node flow: start → a → end

安装说明

安装和基本运行

  • 安装元流(Python3 推荐):pip3 install metaflow
  • 将上面Snippet 1中的示例代码放在linear_flow.py文件中。
  • 要看这个流程的设计:python3 linear_flow.py show
  • 运行流程:python3 linear_flow.py run

A sample flow run

这里需要注意一些事情。 Metaflow 创建一个本地数据存储 ***.metaflow*** ,在此存储所有运行元数据和与运行相关的数据快照。如果您配置了云设置,数据快照将存在于 AWS S3 存储桶中,运行元数据将加载到由 RDS(关系数据存储)支持的元数据服务中**。我们将在后面看到如何使用客户端 API 轻松检查这个运行元数据。另一个值得注意的微妙但重要的事情是,每个步骤附带的*pid (process ID*是不同的。这让我想起了以前的一点,即 Metaflow 将流的每一步分别封装起来,并在它们自己的环境中运行(只来回传输数据)**

Conda 设置(如果您计划注入依赖项)

  • 下载并安装 Miniconda (如果您还没有安装的话)
  • 加一个康达频道 : conda config --add channels conda-forge
  • 现在,您可以在工作流程中注入 conda 依赖项了。我将在下面展示具体细节。

实施更现实的工作流程

随着您逐步完成这项任务,元流的新概念将在适当的地方介绍和解释。

任务

在这个流程中,我们将实现一个工作流,它

  1. 将 CSV 接收到熊猫数据帧中
  2. 并行计算各种流派的四分位数统计数据
  3. 保存特定类型的统计数据字典。

流动

下面是一个框架类,它可以帮助你看到事情的一般流程。

上面的框架类中介绍的一些概念

  • start步骤的第 24 行,注意到foreach参数了吗?**foreach** **genres** 列表中的每一个条目的每一个循环内的 **compute_statistics** 步骤执行并行复制。
  • 在第 26 行,**@catch(var='compute_failed')**装饰器将捕捉在 **compute_statistics** 步骤中发生的任何异常,并将其赋给一个compute_failed变量(它的后继者可以读取该变量)****
  • 在第 27 行,**@retry(times=1)**装饰器做它所暗示的事情——在出现任何错误时重试该步骤。
  • compute_statistics的第 31 行,self.input神奇地出现在哪里?**input** 是 Metaflow 提供的一个类变量,包含了适用于 **compute_statistics** 这个实例的数据(当这个函数有多个副本并行运行时?)只有当一个节点分支到多个并行进程时,或者当多个节点合并为一个时,才由元流添加。
  • 这个示例任务只显示了同一个compute_statistics函数的多次并行运行。但是对于那些好奇的人来说,完全不同和不相关的功能并行启动是可能的。为此,你可以将第 24 行改为第 9 行。当然,您必须相应地更新join步骤来处理这种情况。

这是骨架类的可视化表示。

Visual Flow

读入数据文件和自定义参数

  • 下载此 csv 文件,其中包含由 Metaflow 准备的电影数据。
  • 现在我们希望支持动态地将文件路径movie_data和一个max_genres值作为外部参数传递给我们的工作流。元流允许您通过在运行命令中附加附加标志来传递参数。例如python3 tutorial_flow.py run --movie_data=path/to/movies.csv --max_genres=5****
  • 为了在工作流中读入这样的定制输入,Metaflow 提供了IncludeFileParameter对象。我们通过将一个 **IncludeFile** **Parameter** 对象赋给一个类变量来访问传入的参数,这取决于我们是在读取文件还是常规值。****

Reading in custom parameters passed through CLI

向流体中注入康达

  • 完成上面 Conda 设置部分概述的步骤。
  • 将 Metaflow 提供的 **@conda_base** 装饰器添加到你的 flow 的类。它期望传入一个python版本,这个版本可以是硬编码的,也可以通过下面这样的函数提供。

Injecting Conda to the Flow

  • 现在,您可以将 **@conda** 装饰器添加到流程中的任何步骤。它期望通过 **libraries** 参数传递一个具有依赖关系的对象。在执行该步骤之前,元流将负责准备具有这些依赖关系的容器。可以在不同的步骤中使用不同版本的包,因为元流在不同的容器中运行每个步骤。****

  • 新运行命令 : python3 tutorial_flow.py --environment=conda run

执行'start’步骤

Implementation of start step

这里需要注意一些事情:

  • 注意 **pandas** 导入语句是如何存在于 step 函数中的?那是因为康达只在这一步的范围内注射。
  • 然而,这里定义的变量(**dataframe**&**genres**)甚至可以通过在此之后运行的步骤来访问。这是因为元流的工作原理是隔离运行环境,但允许数据自然流动。****

实施'compute_statistics’步骤

Implementation of compute_statistics step

注意,这一步是访问和修改在前面的start步骤中定义的dataframe变量。前进到下一个步骤,这个新改装的dataframe将会生效。

实施“加入”步骤

Implementation of join step

这里要注意两件事:

  • 在这一步,我们使用了一个完全不同版本的pandas库。
  • **inputs**数组中的每个索引代表在此之前运行的 **compute_statistics** 的一个副本。它包含该运行的状态,即各种变量的值。因此,input[0].quartiles可以包含喜剧类型的四分位数,而input[1].quartiles可以包含科幻类型的四分位数。****

最终代码工件

本演示中开发的流程可在我的教程报告中找到。

为了看到它的流程设计:

python3 tutorial_flow.py --environment=conda show

要运行它:

python3 tutorial_flow.py --environment=conda run --movie_data=path/to/movies.csv --max_genres=7

通过客户端 API 检查运行

您可以利用 Metaflow 提供的 客户端 API 来检查您过去运行的数据和状态快照。它非常适合在笔记本上探索您的历史跑步记录。

下面是一个简单的代码片段,我打印了上次成功运行GenreStatsFlow时的genre_stats变量。

Metaflow Client API Demo

在云上运行

在本地系统上做了一些原型之后,您可能希望利用云资源来加快速度。

目前 Metaflow 只支持与 AWS 的集成,下面是 AWS 服务 Metaflow 使用的并排比较。

Integration between Metaflow and AWS

  • 首先,您需要在 AWS 上进行一次性设置,为 Metaflow 的运行创建资源。如果你想分享和访问彼此的跑步记录,你的团队可以利用相同的资源。请按照本页的说明进行操作。由于 Metaflow 为设置提供了一个 Cloudformation 模板,所以应该很快。
  • 然后,在本地系统上运行 **metaflow configure aws** ,并提供提示的详细信息。这是必要的,以便 Metaflow 可以使用您刚刚在 AWS 上设置的数据存储和 metastore。****
  • 现在要在云上运行您本地系统上的任何工作流,您所要做的就是将 **--with batch** 添加到您的运行命令中。举个例子python3 sample_flow.py run --with batch。轻松微风!****
  • 对于混合运行,即在本地运行几个步骤,在云上运行几个步骤 —将@batch装饰器添加到您想要在云上运行的工作流中的步骤。例如@batch(cpu=1, memory=500)

元流目前的局限性(或优势)

  • 与 AWS 紧密集成,尽管路线图中有支持更多云提供商的计划。
  • Metaflow 完全基于 CLI,不附带 GUI。(不同于其他通用工作流框架,如 Airflow)

问题和反馈?

如果你在评论区有任何进一步的问题/反馈,或者有任何你想让我介绍的新技术,请告诉我。

感谢你的阅读!

是时尚科技创业公司 的联合创始人之一,也是开源电子商务的创造者他还为多家美国财富 500 强公司担任顾问,这些公司都是技术负责人、高级全栈工程师和数据科学家,负责从应用程序开发到大数据分析和机器学习的项目。****

加入 EJ 的邮件列表,这样就能收到新故事的通知!❤

你可能会喜欢 EJ 的其他文章

******* [## 6 分钟学会 hip lot——脸书用于机器学习可视化的 Python 库

高维互动情节变得简单。实践教程。

medium.com](https://medium.com/@viveckh/learn-hiplot-in-6-mins-facebooks-python-library-for-machine-learning-visualizations-330129d558ac) [## 在 10 分钟内建立一个量子电路。Qiskit,IBM 用于量子编程的 Python SDK

学习量子力学的基本概念,在真实的量子上使用 Python 构建和执行量子电路…

medium.com](https://medium.com/@viveckh/build-a-quantum-circuit-in-10-mins-ft-qiskit-ibms-sdk-for-quantum-programming-75435b99ee9e) [## 适用于您的机器学习解决方案的 AWS 架构

利用 AWS 支持的销售智能 ML 渠道推动数百万收入的真实使用案例

towardsdatascience.com](/aws-architecture-for-your-machine-learning-solutions-a208ece806de) [## 为什么我的创业公司从未上线,尽管它已经有了可以投入生产的技术

技术型联合创始人的 6 个关键咒语。

medium.com](https://medium.com/swlh/why-my-startup-never-went-live-despite-a-production-ready-tech-55d344c0c057)*******

学习自然语言处理的实用方法

原文:https://towardsdatascience.com/learn-nlp-the-practical-way-b854ce1035c4?source=collection_archive---------18-----------------------

从无到有。

与十五年前相比,今天的写作有了很大的不同。

出版曾经意味着印刷,这限制了空间,但不那么仓促。守门人越来越多,争夺读者注意力的内容越来越少。虽然只花了几年时间,但科技已经彻底改变了书面文字的经济状况。

我还以为过程没有结束。

我喜欢写作,至少到目前为止,这是我职业生涯的核心。但是,在未来几十年的工作中,我觉得忽视自然语言处理(NLP)的进展是危险的。2017 年末,我决定是时候提升技能了。

在这样做的过程中,我遇到了许多“学习指南”,它们本质上是免费课程和书籍的汇编。问题是,仅仅一门课就要占用你数周的时间。同样,消化一本技术书籍也是极其困难的——更不用说一大堆了。

作为一个想学习如何应用 NLP 工具和技术的人,这似乎不太实际。这篇文章追溯了我最终铺设的实际学习路径。

我是为那些想从文本中提取价值的人写的。如果你只带走一样东西,那就让它成为你能得到的东西。不是立刻,也许不是很快,但这是可行的。

我这样说是因为冒险进入一个新的领域总是会挫伤自我:首先,从基本原则建立一个知识库比扩展一个现有的要难得多。第二,在寻求向那些知道得更多的人学习的过程中,你闷闷不乐地接受了这意味着几乎任何人

我常常想,哇,我这么努力真是个失败者。我不得不主动提醒自己,学习既是一种选择,也是一种巨大的特权。

所以重要的是不要失去那种冒险的感觉。回顾过去,我突然意识到这就像是一个游客,欣赏被你所拥有的东西过滤的风景和经历。那我们就当游客吧。

欢迎来到伦敦。

1。绝对必须有

大多数游客首先去哪里?

当人们开始使用 NLP 时,许多人会直接使用现成的数据:电影评论、新闻组、Twitter 情绪。

主流观点认为,最好从常见的例子和技巧开始,最终将这些知识应用到“真实”的文本中。这意味着你正在引导你的学习走上一条把问题硬塞进你已经学会做的事情的道路。

不要。

相反,我建议你先搜集一些文本。这将使您能够处理与您的特定需求相关的文本内容,并让您亲身体验将这些类型的文本分开会产生什么效果。

同样重要的是,它会让你思考哪些标签可以很容易地从数据中提取出来,哪些是你可能想要计算的。

首先学习如何使用 请求urllib库,以及一个解析器(比如 美汤 )。抓取文本通常只是短短的三行代码。努力的方向是查看解析后的 HTML 并提取出您需要的部分。任何搜索都会发现大量的分步指南。

*现在,您可能希望将数据转换成某种可行的格式:一种易于加载和处理的格式,而且您可以打开 Excel 轻松查看数据。为此,您应该熟悉数据帧。除了如何初始化、添加内容和访问数据,一开始不要浪费任何时间。(这里,试试 这个 指南。)其他的,你走着走着就学会了。

另一个绝对必备的就是正则表达式。语言感觉几乎有章可循。只有通过实际写下一些规则,你才能体验到异常的膨胀负担。也就是说,有时轻松提取 70%的相关信息就足够了。*

这里有一个 教程 让你入门,一个 在线测试器 测试思路,还有一个 regex 小抄

2。玩弄文本

这很奇怪,但在完全忽略语言的同时处理语言已经成为惯例。许多 NLP 都是从将单词和单词组合转换成数字对象开始的,然后对这些对象进行数学处理。人们很容易忘记,你所操作的是语言的一种表示,而不是事物本身。

这种情况正在发生,因为操纵事情本身是 NLP 从业者多年来一直在做的事情——但成功有限。你被告知使用的工具是 NLTK,一个庞大的教育 NLP 图书馆。

嗯,我试过用 NLTK,不喜欢。我试着阅读附带的手册,这只会让事情变得更糟。然后,我转向 spaCy,再也没有回头。

空间干净高效。其清晰、视觉愉悦的 文档 使其具有高度的可访问性,因此完成工作非常简单。它甚至还有一门 在线课程

入口点是它的管道:默认情况下,当你处理一个段落时,你得到的是一个已经被分割成句子和单词对象的对象(称为令牌);对句子进行解析,并根据它们的词性对标记进行标记;有些标记甚至被识别为命名实体(例如,“德国”是一个国家)。以后,如果需要,您可以删除其中的一些步骤,或者在上面添加其他步骤。但是这个默认设置很好地衬托了你。

学习语言学句子解析就像获得牡蛎卡一样:开始有点不方便,但很容易使用。当我试图抓住它时,我需要帮助。为了更进一步,我写了这篇 简短的讲解文章

开始和课文玩小游戏:你会数动词吗?你能把文字分开吗?你能把一些文字放在一起吗?

随着你越来越熟悉 spaCy,这些游戏可以变得更加丰富。在你意识到之前,你已经在那里了,不是用键盘或笔来操作文本,而是好像它是乐高积木的一部分。

3。大量浅阅读

浅阅读是一种被大大低估的学习工具。

我们通过将新思想与熟悉的概念联系起来学习得最好。当一切都是新的——没有任何诱惑。通过略读大量关于某个主题的文章,即使你积极地理解得很少,你的寻找模式的大脑也会注意到某些术语是如何经常一起出现的。你会在完全理解概念和想法之前很久就开始认识它们。

很快,你就有了自己的衣架。

我建议避开关于他们的学术论文或博客文章。作者写作是为了在他们的专家群体中获得影响力;他们的目标受众不是好奇的 noob。

相反,我的 NLP 文章的来源是 Medium,尤其是面向数据科学的出版物。其他伟大的来源是 fast.ai 博客 、分析 Vidhya 博客 和 Sebastian Ruder 的时事通讯 。当然可以选择别人;重要的是坚持阅读各种各样的文章。

还有 杰·阿拉玛的博客 。帖子不多,但每一篇都是对机器学习概念的高度可视化解释——强烈倾向于深度学习 NLP 的最新进展。

4.书

书籍就像购物:有无限的供应,争夺你有限的资源。此外,无论你选择什么,一半的东西最终将被证明是无用的。不过,这种经历会让你一下子接触到一堆新的东西。

就像我说的,目前人们似乎更关注“处理”部分,有点忘记了“自然语言”部分。我觉得这可能是个错误。

对我来说,这意味着读一本关于语言学的书,以及尽可能多的关于人们把什么当作语言的书。举几个例子:我花了一段时间阅读了所有关于科科的资料,这只大猩猩学会了手语,还学会了一些 T21 语,很多人认为是英语。我对科科是否讲过(手语)英语不感兴趣;我想知道是什么让人们相信她有。

我花了同样多的时间阅读 IBM 的沃森是如何赢得 Jeopardy 的,以及该团队的领导者大卫·法鲁奇(David Farucci)写的关于他努力开发故事写作软件的书。

不过,如果你真的想思考语言以及如何使用语言,我最推荐的一本是维特根斯坦的 哲学研究 。我知道这听起来像是大材小用,这与 Python 或花哨的神经网络毫无关系。但我认为,你对自然语言部分理解得越好,你就能通过更简单的算法变得越聪明。

回到加工部门,我对书籍非常失望。

奥莱利动物系列,我拿到了用 Python应用文本分析(还算新),和 编程集体智能 (还不是)。我发现这两本书都没什么用。具有讽刺意味的是——因为它们本应是编码书籍——在这两种情况下,问题都出在代码上:

旧版本充斥着过时的代码,包括现在已经失效的 API 和库。新的可能是最新的,但是代码用一个主项目说明了思想,这个主项目是逐步构建的。这意味着几乎每一章都需要熟悉前面的代码库。在这两本书里,解释这些原则的文字都严重缺乏。不管他们的目标读者是谁,都不是我。

这是一个主要的低谷。我想学习 NLP 技术,然而我却在这里:寻找世界上所有关于理论、实践的内容却毫无进展。****

5.任务和库

相反,我回到了文章。如果说最初浅阅读有助于获取概念,那么随着时间的推移,人们探索的任务(情感、总结、主题建模、文本生成、数据可视化)和他们创造解决方案的技术(算法、库)中已经开始出现模式。

就像尽管每个人都有自己独特的伦敦,但我们很多人碰巧喜欢相同的东西。

我开始绘制问题空间,以及常用的技巧。

当人们分享他们的学习时,大多数文章都以他们最容易理解的水*为特色,使用玩具数据集或玩具问题。通过阅读几篇关于任何给定主题的文章并遵循代码,我最终会明白。

本质上,任何我可以通过搜索解决的问题,我都认为是已经解决的问题。这最后一句话不同于你将得到的大多数建议,但它绝对是应用自然语言处理的关键。**

以文本摘要为例,无论用什么标准衡量,这都是一项艰巨的任务。你可以花时间阅读大量的 学术研究 ,它们竞相提高单个数据集的性能。或者,您可以 找到如何实现文本等级 ,这是最常见的提取方法。

或者,您可以理解 Text Rank 是做什么的,并使用 PyTextRank (刚刚发布;由知名专家编码;并对原算法进行了改进。而且,你发现这一点只是因为你一直在努力进行浅阅读。

这并不是说一种方法优于其他方法——每种方法都有不同的收益。你的工作是确定目标,评估哪里最适合你。

同样的原则也适用于代码。有那么多优质的开源库。现在让我告诉你——大部分我还没用过。相反,我一直在维护一个列出有用库的文档,并在需要时使用它们。这里有一个资源让你开始列出自己的清单。****

简单回到文章,还有激动人心的小众。有时,你会看到有人试图将想法应用到一个非常具体的任务中,他们专注于制造一些实际可行的东西。通常情况下,他们会使用熟悉的工具,但使用方式不同。

确保您保存了任何此类文章;很可能,你以后会想要它。

6.小型项目

假设你读了 25 篇关于某个旅游景点的评论,所有的评论都很糟糕。这个景点也不便宜,而且会耗掉一整天。

你会去吗?

你读的文章会给你指出你能做的事情,但不一定是你应该做的事情。我拒绝花时间实现我从未见过任何有意义的结果的算法。

为什么?因为,从广义上讲,开箱即用的算法在有用的任务上表现很差。你可以花上几个月甚至几年的时间来学习书中的每一个技巧——但仍然无法增加价值。

对于任何想增加编码时间或刚刚开始职业生涯的人来说,这是一个糟糕的建议。但是如果你想在你的领域内使用自然语言处理,最重要的技能是提出商业问题,并考虑如何解决这些问题。

哪个更好——一个大项目,还是几个小项目?一开始我会说,越小越好。把它想象成一次小小的冒险。

最初,我实现了我看到其他人做的有趣的东西。然后我开始应用我自己的想法,只是想看看会发生什么。

例如,已经发生的一件事是,我对 财经新闻 进行情感标签的技术目前在任何相关的谷歌搜索中排名靠前或接*靠前。

我提到这一点是为了强调我之前的观点:是的,通过从新的角度看待已知的问题,你可以交付新的价值。

至于你应该实现什么——这是你自己的观点。我推荐阅读以下两位作者以前的帖子,因为他们一贯的冒险精神和敢做的态度: Susan Li ,他们的博客主要是关于 NLP 的东西,以及 Will Koehrsen ,他们的博客涉及各种机器学习主题。

而作为一个游客,大概也该回家了。

Phew!

接下来呢?

因此,现在学习路径出现了分叉:一种方式是朝着更持续的语言观点发展,这种观点转向“处理”:这都是关于通过迁移学习来利用大型语言模型。

另一个是对语言的更离散的观点,我认为这更接*于“自然”的部分:这是包含知识图表和组合表示的东西。

就像“自然语言处理”是一个单一的想法,这些路径最终会重新连接起来。但最初它们是不同的。因为我是理论不可知论者——这是一种说我会愉快地挑选适合问题的东西的花哨说法——我想探索两者。

出于现实原因,我决定从迁移学习入手,上了 fast.ai NLP 课程 。我想在某个时候写下它。

****更新,2020 年 8 月:虽然我极力推荐这门课程,但我从未抽出时间来写它。然而,我最终还是为伯特和 GPT-2 写了ABBA 终极解说,你可能会觉得有帮助。

同时,让我们总结一下:为了充分熟悉工具和实践,以便我可以试验它们,我遵循了上面追踪的学习路径。我希望它的一部分也能帮助你。

继续学习数据科学

原文:https://towardsdatascience.com/learn-on-towards-data-science-52245bc91451?source=collection_archive---------15-----------------------

最后更新于 2021 年 3 月

发现、学习和分享您自己的项目

Photo by Bonnie Kittle on Unsplash

欢迎👋去我们的学习区!

无论您是想学习一项新技能、改善您的职业选择、发展一项爱好,还是想更好地参与围绕数据科学、机器学习、人工智能、编程等不断变化的对话,我们都将为您的成功提供支持。

为了帮助您以适合您的速度学习这些引人注目的概念,我们按主题整理了最有帮助的内容。我们希望一次完成一个主题能给你一种类似于一些最好的在线课程的学习体验,但采用我们熟悉的数据科学风格。

您可以在下面找到我们不断更新的当前主题列表。快乐学习!

数据科学

  • 入门
  • 概率与统计
  • 信息论
  • 清洗数据
  • 数据可视化
  • 案例分析
  • A/B 测试
  • 职业

机器学习

  • 无监督学习
  • 监督学习
  • 车型评价
  • 强化学习
  • 时间序列
  • 机器学习的贝叶斯方法
  • 深度学习
  • 遗传算法
  • 图论和网络分析
  • 自然语言处理
  • 偏见、公*和可解释性

编程;编排

  • R
  • Python
  • 其他编程语言

其他人

  • 艺术、创意和数据科学
  • 如何在《走向数据科学》发表?

从假专辑封面游戏中学习 Python

原文:https://towardsdatascience.com/learn-python-from-the-fake-album-covers-game-b8459e83c268?source=collection_archive---------19-----------------------

网页抓取、字符串处理、图像处理

Web Scraping with Python (Source)

在这篇文章中,我们将学习如何使用 python 进行基本的网页抓取、图像处理和字符串处理,同时玩一个名为“假专辑封面”的游戏。这个游戏的想法是按照下面的步骤为你自己乐队的 CD 制作一个假封面

  1. 从 Lorem Picsum 中获得任意一张图片,作为封面专辑。
  2. 封面上的乐队名称将使用任何随机维基页面标题中的标题生成。
  3. 专辑名将是语录页中任意一页中最后一句语录的最后四个单词。随机链接不再起作用了,我查看了 reddit,发现设计师们现在使用 wikiquote 页面。所以在这篇文章中,我使用了随机生成的维基百科页面的标题。

为了开始游戏,我们需要从上面提到的网站获取图像,这里我们需要非常简单的 python 网页抓取技术。简而言之,网页抓取的思想是,代替人类浏览和复制粘贴文档中的相关信息,计算机程序做同样的事情,更快更正确,以节省时间和精力。尽管我们在这里没有使用 web 抓取来进行数据分析,但是记住这些网站大部分是使用 HTML 编写的,并且这些是结构化文档,不像我们熟悉的 CSV 或 JSON 格式,可以直接使用数据框库来处理,就像使用pandas一样。

首先,第一个问题是什么库可以帮助我们使用 Python 进行 web 抓取?最常用的三个库是 BeautifulSoup、Requests、和 Scrapy 。在这里,我们将学习使用请求和请求,这将允许我们发送 HTTP 请求来获取 HTML 文件。

首先,我们可以从 Lorem Picsum 网站获取一张随机图片开始

*import requests response_obj = requests.get('[https://picsum.photos/g/500/?random'](https://picsum.photos/g/500/?random'))* 

这里我们通过使用requests.get创建了一个响应对象‘raw _ pic’。现在要从这个对象中获取信息,我们需要访问响应体,为此我们将使用content。下面是一个将响应对象保存为. png 图像的示例—

*name = 'first_pic.png'with open(name1,'wb') as raw_file: 
*# 'wb': write binary, binary is necessary because it is a png file*raw_file.write(response_obj.content)*

我得到了一个随机图像如下

Scraping images with Python from Lorem Picsum.

现在作为游戏规则,我们需要把专辑名和乐队名放在这张图片上,为此我们将使用 python 图像库 (PIL)。

*from PIL import Image*

首先使用Image.open打开并识别图像文件

*img = Image.open("first_pic.png")*

由于我们想在这张图片上绘制(书写)文字来完成封面,我们将使用 PIL 图书馆的ImageDraw模块。

*from PIL import ImageDraw
draw = ImageDraw.Draw(img)*

这个对象'draw’以后可以用来插入文本。

下一个目标是指定我们将用来写乐队名称和专辑的字体的字体目录路径,我要求你发挥字体风格和创造性。为了加载一个字体文件并创建一个字体对象,我们将再次使用 PIL 库的ImageFont模块。

*from PIL import ImageFontband_name_font = ImageFont.truetype("path_to_font/font1.ttf", 25)album_name_font = ImageFont.truetype("path_to_font/font2.ttf", 20)*

在我们放置文本并使用这些字体书写之前,我们需要再次使用 web 抓取来从网站中提取文本,这些文本是使用 HTML 编写的。

像之前的图片一样,我们为随机维基页面创建了一个响应对象

*wikipedia_link='[https://en.wikipedia.org/wiki/Special:Random'](https://en.wikipedia.org/wiki/Special:Random')r_wiki = requests.get(wikipedia_link)*

要阅读响应的内容,可以使用下面的text

*wiki_page  = r_wiki.text*

**请求库将自动解码来自服务器的内容。当我们发出请求时, Requests 库将根据 HTTP 头对响应的编码进行有根据的猜测,我们可以在这里使用r_wiki.headers看到这一点。当我们运行r_wiki.text时,使用由请求猜测的测试编码。让我们检查编码类型

*print "encoding type", r_wiki.encoding>>> encoding type UTF-8print type(wiki_page)>>> <type 'unicode'>*

让我们看看解码后的内容是什么样的

*print (wiki_page)*

我得到如下所示的输出

我们的想法是用维基页面的标题作为乐队的标题。在上面的输出中可以看到,文章的标题被 XML 节点包围,如下所示Menyamya District—Wikipedia。这是任何维基页面 <标题>标题——维基百科</标题>,的通常格式,如果我们考虑文章的标题。我们提取标题的第一项工作,是找到 XML 节点 < title >< /title >。我们将使用 string.find() 函数来查找这些节点,但在此之前,由于我使用了 python 2.7,我需要将 unicode 转换为字符串,如下所示**

*wiki_page = wiki_page.encode("ascii", errors='ignore')print type(wiki_page)>>> <type 'str'>*

在这之后,我们准备好使用 string.find() ,并最终选择 XML 的特定部分,如下所示

*xml_e = wiki_page.find('</title>')
xml_b = wiki_page.find('<title>')
title_b_len = len('</title>')
total_len = xml_e + title_b_lentitle_wiki = wiki_page[xml_b:total_len]
print "title including wiki: ", title_wiki>>> title including wiki:  <title>Menyamya District - Wikipedia</title>*

剩下的任务是去掉不必要的部分,我们将只剩下标题。你可以把这当成用 python 进行字符串操作的一个小任务,因为有很多方法可以做到这一点,稍后查看 github 页面比较解决方案。对于 wikiquote 页面,我们遵循相同的过程,提取标题,这将是我们的相册名称。

最后,一旦我们从网络搜集中获得了乐队名和专辑名,我们将把它们作为文本写入(绘制)到图像文件中。为此,我们将在之前定义的 draw 对象上使用text。因为我只处理灰度图像,所以我可以用文字颜色来玩,但是如果你想用彩色图像作为假封面,那么最好的选择是用某种方式来写文字,这样它在任何颜色的背景下都是可见的。这样的格式是由亚历克·班尼特提供的,你可以遵循它并随机应变。一旦完成,我们准备检查我们的假 CD 封面,并记住图像,乐队名称和专辑名称都可能在每次运行时发生变化。所以玩得开心点!下面是我在一次这样的跑步中得到的

Fake CD Cover !

在玩这个有趣的游戏时,我们学到了什么

  1. 网页抓取使用请求模块。
  2. 字符串处理;基本操作,如替换,剥离等(为您分配)。
  3. 使用 PIL 图书馆的图像处理。

相当多,不是吗?完整的笔记本可以在我的 github 页面上找到。这整个游戏是 Coursera 应用数据科学课程 Python 期末作业的一部分,和往常一样,这些课程包含一些精彩的实验环节,可以用 Python 进行游戏和学习。然而,为了生成专辑和乐队名,我们两次使用了维基百科页面,而不是维基百科页面。

敬请关注更多内容!

关于我:我参与了CALET电子光谱的科学分析,寻找暗物质签名。在Linkedin找我。

以 Excel 为桥梁学习 SQL

原文:https://towardsdatascience.com/learn-sql-by-using-excel-as-a-bridge-30cea4d314e0?source=collection_archive---------14-----------------------

比你想象的要容易得多的转变

Photo by Mika Baumeister on Unsplash

作为一名前会计师转行的分析师,微软 Excel 一直是,并且直到今天仍然是我最喜欢的工具之一。我曾经傻到以为在未来的某一天,Excel 会被认为是无关紧要的。事实是,相反的事情正在发生。总的来说,Excel 和电子表格比以往任何时候都更加重要。

我经常遇到需要一些基本分析和/或报告的人。他们完全在 Excel 中处理这个问题。

问题是,当数据存在于数据库中时,大多数情况下,必须使用数据进行分析或报告的人与知道如何提取数据的人是不同的。这给每个公司都带来了一个问题,因为公司的分析师数量有限,必须不断地切换环境。

这就产生了对非数据分析师职位的员工的需求,他们需要了解基本的查询和数据库的基础知识。

主要的问题是很多人不知道从哪里以及如何开始。

幸运的是,作为一个经历了从电子表格到数据库的旅程的人,我可以并且想要成为你的向导。现实地说,电子表格和数据库是一样的东西,但是我们只需要学习一种新的简单的语言来浏览它们。

Excel 和数据库基础

擅长

我有一个 Excel 工作簿,我将用它作为我解释的基础。在本工作簿中,我有多个工作表,其外观和功能就像您的 web 浏览器中的选项卡。这些表中的每一个都存储不同的数据。

我将使用的工作簿包含我的水果店的运营数据。如您所见,有客户、项目和 purchase_log 的表。

A preview of my fruit store’s data tables

这些选项卡都包含尚未格式化的原始数据。数据被组织成每个字段的列和每个记录的行。

customers table

fruits available for sale

a list of transactions that happened in my store

如您所见,该表由 id 组成,后面是其他详细信息。传统上,在 Excel 中,如果我想将更多的商品和客户信息附加到购买日志中,我会使用索引匹配或 vlookup 来实现,如下所示。

using index match to combine data from different tables

combining first and last name fields into a full name in the purchase log table

这就是我们要做的——在我们的电子表格数据库中组合来自不同表格的信息非常简单。我们现在的分析可能非常危险。

让我们在 SQL 中做同样的事情

在 Excel 中,我们有工作簿,其中有工作表。在数据库中,我们可以称工作簿为模式,称工作表为表格。他们以同样的方式工作。这些表还包含格式完全相同的信息——表格形式,字段作为列,行作为记录。

现在的区别是,我们只需编写快速查询,而不是点击一下按钮就能获得数据。

我们现在有一个包含 3 个表的模式:

using sqlfiddle.com

如果我们想查看每个表中的所有数据,我们只需编写以下代码:

select * from customers

或者,如果我们想从项目表中选择:

select * from items

或购买日志:

select * from purchase_log

如果我们想创建购买日志,记录客户的全名以及他们购买的水果的名称,比如

select purchase_log.id, time, concat(firstname,' ' ,lastname) as 'customer full name', item as fruit
from purchase_log
inner join customers on purchase_log.customer_id = customers.id
inner join items on purchase_log.item_id = items.id
order by id asc

SQL 语法的简单分解

SQL 非常深入,我们有很多方法可以调整查询,但是我上面给你展示的已经排除了大部分。

阅读我之前写的查询非常容易。 Select 表示选择, ***** 表示所有字段,【T4 from】表示我要选择所有的表。

例如,我想从 customers 表中选择所有字段/列,所以我要写:

**select** * **from** **customers**

在上面的最后一个表中,我将其他表中的数据拖到购买日志中,并重命名了这些字段。该查询比使用“全选”来查看表稍微复杂一些。不用担心,我会用一种容易理解的方式来分解它。

我们的疑问:

**select** purchase_log.id, time, **concat**(firstname,' ' ,lastname) **as** 'customer full name', item **as** fruit
**from** purchase_log
**inner join** customers **on** purchase_log.customer_id = customers.id
**inner join** items **on** purchase_log.item_id = items.id
**order by** id **asc**
  • 我们有一个 select 子句,和以前一样,但是这次增加了一些晦涩难懂的内容。
  • 有一个 from 子句,保持不变。
  • 两个内连接子句和一个 order by。嗯?

[表格]。[字段]

在我们之前的查询中,因为我们使用了*,所以我们只是选择了所有的字段。如果我们的查询被隔离到一个表中,我们可以通过写出并使用逗号分隔来选择我们想要的字段。

select item, price from items

这将只给我们一个包含商品及其价格的表,没有它们的 id。

但是,该查询从不同的表中提取数据,有时该表中的字段被命名为相同的名称,例如“id”。因此我们必须指定哪个 id 是我们想要的。

purchase_log.id, customer.id, purchase_log.customer_id

以上内容如下—

id 字段来自 purchase_log 表,

id 字段来自客户表,

客户 id 字段来自购买日志

内部连接是索引匹配中的匹配

这允许我们使用具有匹配值的列将两个不同的表粘合在一起。

**inner join** customers **on** purchase_log.customer_id = customers.id

用简单的英语解释:我想在我的当前表( purchase_log )中使用来自 customers 表的数据,我可以这样做,因为这个表中的 customer_id 存在于 customers 表中的 id 中。

您希望从连接表中使用的实际数据将被添加到 select 语句中。

有了它,您就可以从数据库中取出任何想要的东西,并保存到一个表中。

在表格内进行调整

我的查询中包含的常用语句和函数,用于修改标记数据的方式:

  • order by 是它自己的语句,相当于 excel 中的排序。
    order by 【字段】=排序 Z 到 A
    order by 【字段】 asc =排序 A 到 Z
  • as 是一种将列命名为其他名称的简单方法。
    选择【字段】作为【您想要给出的名称】
  • concat 与 excel 中的 concat()功能相同。如果想在 select 语句中组合多个列,只需编写:
    select concat([字段],[i],[want],[组合]) 作为[名称]

我们找到了。现在,您可以从数据库中随意提取数据,并对其标注方式进行修改!

虽然我是 Excel 的忠实粉丝,因为它帮助我度过了早期的职业生涯,但从那以后,我的工具库中增加了很多东西。SQL 的“兔子洞”要深入得多,我希望这篇介绍能激发您去探索它。

学习数据科学的艺术;十年编程语言。

原文:https://towardsdatascience.com/learn-the-art-of-data-science-programming-languages-of-the-decade-a2850830ab76?source=collection_archive---------23-----------------------

从童年开始,我们的大脑就被周围的环境所束缚。我们的社会、环境、文化、信仰和背景对我们的成长起着重要作用。但是,这并没有什么坏处,因为至少它有助于我们区分善与恶、对与错、正义与非正义、邪恶与美德。我同意不同意,但这可能是我爱机器胜过爱人类的原因。此外,人类不可能像机器学习一样具有人工智能和不朽。

谈到机器学习,这让我想到了数据科学,因为机器学习是数据科学的一部分,而数据科学是一切的主宰。

简而言之,数据科学是一门存储、清理和组织数据的艺术,将数据转化为有价值的资源,帮助制定业务战略。与其说它是一门科学,不如说它是一门艺术,因为它是关于从原始数据中发现模式和洞察力的。

它需要拥有所需技能的人来精通这一领域。除了数学技能,还需要编程技能。但是在获得专业知识之前,一个有抱负的数据科学家必须能够对工作所需的编程语言类型做出正确的决定。在本文中,我们将介绍数据科学编程语言,这是当前的需要,以及如何让 成为一名精通数据的科学家

那么,让我们来学习这十年的语言吧!

1.计算机编程语言

它易于使用,是一种基于解释器的高级编程语言。 Python 是一种多功能的语言它拥有大量的用于多种角色的库。更容易的学习曲线和有用的库使它成为数据科学最受欢迎的选择。另外,代码可读性的特性使得 Python 成为数据科学最受欢迎的选择。这是一个很大的好处,因为数据科学家处理复杂的问题,因此,拥有一种更容易理解的语言是理想的。

它还使用户在遵循所需算法标准的同时更容易实现解决方案。

支持各种各样的库。此外,数据科学中解决问题的各个阶段都使用自定义库。解决数据科学问题涉及数据预处理、分析、可视化、预测和数据保存。为了执行这些步骤,Python 有专门的库,如 Pandas、Numpy、Matplotlib、SciPy、scikit-learn 等。此外,Tensorflow、Keras 和 Pytorch 等高级 Python 库为数据科学家提供了深度学习工具。

2.稀有

R 是一种实质性的语言 因为它有助于让工作面向统计的任务。与 Python 相比,有抱负的数据科学家可能不得不面对陡峭的学习曲线。 R 专门用于统计分析。因此,它在统计学家中很受欢迎。深入研究数据分析和统计很有帮助。R 的唯一缺点是它不是一种通用编程语言,这意味着它不能用于统计编程以外的任务..

CRAN 的开源存储库中有超过 10,000 个软件包,R 可以满足所有统计应用的需求。还具有处理复杂线性代数的能力。R 的另一个重要特性是它的可视化库‘gg plot 2’。还有其他工作室包,如 tidyverse 和 Sparklyr,它们为 R. R 提供了 Apache Spark 接口,r studio 等基于 R 的环境使连接数据库变得更加容易。它有一个名为“RMySQL”的内置包,并提供 R 与 MySQL 的本地连接。所有这些特性使 R 成为核心数据科学家的理想选择。

3.结构化查询语言

SQL 被称为“数据科学的基础”,是数据科学家必须掌握的最重要的技能 SQL 或‘结构化查询语言’是用于从称为关系数据库的有组织的数据源中检索数据的数据库语言。SQL 在数据科学中起着至关重要的作用,因为它有助于更新、查询和操作数据库。除此之外,知道如何检索数据是数据科学家工作中最重要的部分。它是数据科学家的“随身武器”,这意味着它提供有限的功能,但对特定的角色至关重要。它有多种实现,如 MySQL、SQLite、PostgreSQL 等。

SQL 知识是必须的,因为从数据库中提取和处理数据是通过 SQL 完成的。由于它的声明性语法,它也是一种可读性很高的语言。例如,从薪金> 20000 的用户中选择姓名非常直观。

4.斯卡拉

Scala 是运行在 JVM 上的 Java 编程语言的扩展。它是一种通用编程语言。它既有面向对象技术的特点,也有函数式编程语言的特点。可以配合大数据*台 Spark 使用。

Scala 提供了与 Java 的完全互操作性,同时保持了与数据的紧密联系。它也有助于将数据塑造成任何需要的形式,因此它是一种专门为这个角色设计的高效语言。Scala 最重要的一个特性是它能够促进大规模的并行处理。然而,它的学习曲线很陡,我们不推荐初学者使用。最后,如果你作为数据科学家的偏好是处理大量数据,那么 Scala + Spark 是你的最佳选择。

因此,这使得它成为处理大量数据时的理想编程语言。

5.朱莉娅

Julia 是科学计算的最佳编程语言。这是一种最*发展起来的语言。它因像 Python 一样简单而广受欢迎,并拥有 C 语言闪电般的性能。这些特性使它成为需要复杂数学运算的领域的理想语言。数据科学家,研究需要复杂数学的问题。朱莉娅能够以很高的速度解决如此复杂的问题。

由于最*的发展,这种语言在其稳定版本中面临一些问题。但终成眷属的是,这种语言现在被公认为是一种语言 Flux,是机器学习架构,是 Julia 用于高级 AI 进程的一部分。许多银行和咨询服务机构都在使用 Julia 进行风险分析。**

6.斯堪的纳维亚航空公司

和 R 一样,可以使用 SAS 进行统计分析。唯一的区别是,SAS 不像 r 一样是开源的。然而,它是为统计设计的最古老的语言之一。SAS 语言的开发者开发了他们自己的软件套件,用于高级分析、预测建模和商业智能。 SAS 可靠性高,得到了专业人士和分析师的高度认可。寻求稳定安全*台的公司使用 SAS 来满足其分析需求。虽然 SAS 可能是一个闭源软件,但它提供了大量用于统计分析和 机器学习 的库和包。

SAS 有一个优秀的支持系统,这意味着您的组织可以毫无疑问地依赖这个工具。然而,随着先进的开源软件的出现,它落后了。其原因是,这是一个有点困难,非常昂贵的语言纳入。现代编程语言提供的更高级的工具和特性。

结论:

对于数据科学家来说,这些是一些重要的编程语言。虽然每种语言都有其重要性,但这 6 种语言应该保持优先地位,因为掌握好这 6 种语言会让你在各自的领域更上一层楼。

最后,你将不得不最终确定你的语言并开始学习。你需要在这方面培养自己的直觉,并获得超越他人的实践经验。那么,你还在等什么?人工智能!

学会关注!细胞神经网络中可训练的视觉注意

原文:https://towardsdatascience.com/learn-to-pay-attention-trainable-visual-attention-in-cnns-87e2869f89f1?source=collection_archive---------5-----------------------

在训练图像模型时,我们希望模型能够关注图像的重要部分。实现这一点的方法之一是通过可训练的注意力机制。在这篇文章中,我们将首先讨论事后注意力和可训练注意力以及软注意力和硬注意力之间的区别。然后,我们将深入研究 2018 年 ICLR 的一篇论文“学会关注”的细节,该论文描述了一种用于图像分类的可训练软注意力的方法。

关键论文参考

这里是我们在这篇文章中要研究的关键论文:杰特莱 S,洛德纳,李 N,托尔 PH. 学会注意。2018 年 ICLR 奥运会。

这里还有一个很好的 Pytorch 实现:SaoYan/LearnToPayAttention

注意:注意力也广泛用于自然语言处理。这篇文章的重点是计算机视觉任务中的注意力。

什么是注意力?

可训练与事后注意机制

让我们先从这个词的英文定义:

注意:对某人或某事的注意;认为某人或某事有趣或重要

同样,在机器学习中,“注意力”指的是:

定义(1): 可训练的注意力:帮助“训练中的模型”更有效地注意重要事物的一组技术

定义(2): 事后注意力:一组帮助人类可视化已经训练好的模型认为重要的东西的技术

当人们想到注意力时,他们通常会想到定义(1),即可训练的注意力。一种可训练的注意力机制在网络被训练的同时被训练,并且应该帮助网络聚焦于图像的关键元素。

令人困惑的是,事后热图可视化技术有时也被称为“注意力”,这就是我包含定义(2)的原因。这些事后注意机制根据已经训练好的网络创建热图,包括:

  • 通过遮挡的热图(泽勒,2013 年)
  • 显著图(西蒙扬 2013)
  • 【凸轮】(周 2016)
  • Grad-CAM (塞尔瓦拉茹 2017)
  • 修复了 Grad-CAM 的一个问题

我强调,这些事后技术不是为了改变模型学习的方式,或者改变模型学习的内容。它们被应用于已经训练好的具有固定权重的模型,并且仅用于提供对模型决策的洞察。

最后,让我们看看 Jetley 等人对“注意力地图”的定义:

注意图:标量矩阵,表示在不同 2D 空间位置的层激活相对于目标任务的相对重要性

即,注意力地图是指示什么 2D 位置对于任务是重要的数字网格。重要位置对应更大的数字,通常在热图中用红色表示。在以下示例中,显示了“边境牧羊犬”的注意力地图,强调了边境牧羊犬在原始蒙太奇中的位置:

Image Source: ramprs/grad-cam

软关注与硬关注

你可能听说过“软注意”和“硬注意”这两个术语。它们之间的区别如下:

Modified from Image Source

  • 柔和关注使用“柔和阴影”来关注区域。可以使用传统的反向传播/梯度下降来学习软注意力(用于学习神经网络模型的权重的相同方法)。)软注意力地图通常包含 0 到 1 之间的小数。
  • 硬关注使用图像裁剪来关注区域。它不能使用梯度下降来训练,因为没有“在这里裁剪图像”过程的导数像强化这样的技术可以用来训练严格的注意力机制。完全符合 0 或 1 的硬注意图,没有介于两者之间的东西;1 对应于保留的像素,0 对应于裁剪掉的像素。

关于软注意力和硬注意力的更深入的讨论,请看这篇文章(小节“什么是注意力?”、“硬注意”和“软注意”)以及这篇文章(子部分“软与硬注意”)。

学会集中注意力

论文“学会集中注意力”在 CNN 模型中展示了一种软可训练视觉注意力的方法。他们考虑的主要任务是多类分类,其中的目标是将输入图像分配给单个输出类,例如将一张熊的照片分配给“bear”类作者证明了软可训练注意力在 CIFAR-100 上提高了 7%的多类分类性能,他们展示了示例热图,强调了注意力如何帮助模型专注于与正确的类标签最相关的图像部分。

型号概述

这是他们的模型图,根据论文中的图 2 修改而来:

该模型基于 VGG 卷积神经网络。VGG 网络有不同的配置,如图 2 所示。(如果你好奇的话,“学会集中注意力”这篇论文似乎使用了介于配置 D 和 d E 之间的 VGG 配置;具体来说,有三个类似配置 D 的 256 通道层,但有八个类似配置 e 的 512 通道层。)

该图的要点是作者对基本的 VGG 设置做了两个关键的改变:

  1. 他们在第 7 层、第 10 层和第 13 层(我用黄色突出显示的层数)后插入了注意力评估器。)第 7 层之后的注意力估计器获取第 7 层的输出,并计算 0 和 1 之间的数字的“注意力屏蔽”,然后将其与第 7 层的原始输出相乘,以产生“g_a”(如上图所示。)对于层 10 和 13 之后的注意力估计器发生相同的过程,以分别产生 g_a 和 g_a。
  2. 下一个大的变化是,作者去掉了通常位于 VGG 末尾的全连接层来产生预测(通常在编号为“16”的 FC 层之后还有另一个 FC 层,但他们已经去掉了它。)相反,分类现在通过一个新的全连接层进行,该层从三个注意力估计器接收输入。

符号

在我们深入研究他们的注意力机制是如何工作的之前,这里有一个在这篇文章中使用的符号的总结,我们将在这篇文章的剩余部分使用它:

注意力是如何工作的

第一步:计算兼容性得分。

使用局部特征 l 和全局特征向量g来计算“兼容性得分”

作者解释说,当由局部特征描述的图像块“包含主导图像类别的部分”时,兼容性得分旨在具有高值

例如,如果图像中有一只猫,我们假设整只猫是由全局特征向量 g 描述的,此外,我们期望一个特别“像猫”的补丁(例如,猫脸上的一个补丁)将产生局部特征 l ,当与g组合时,这些局部特征产生高的兼容性分数

作者提出了从局部特征 l 和全局特征向量 g 计算兼容性得分 c 的两种不同方法:

方法 1 :“参数化兼容性”或“pc”:

方法 2 :“点积”或“dp”:

(剧透警告:“参数化兼容性”在他们的结果中表现更好。)

在“参数化兼容性”中,我们首先将局部特征添加到全局特征中, l+g ,然后我们用学习向量 u 进行点积。直觉上, lg 的连接可能比加法更有意义,但作者指出,“给定局部和全局图像描述符之间现有的自由参数[……]我们可以将连接[……]简化为加法运算”,以便“限制关注单元的参数。”(其中一位审稿人还问为什么做加法而不做串联;参见打开查看。)

在“点积”方法中,我们简单地取局部特征 l 和全局特征向量g的点积。注意,对于我们应用关注的每个 conv 层(层 7、10 和 13),局部特征 l 对于该层将是唯一的,但是全局特征向量 g 是相同的。

如果 lg 大小不一样怎么办?

事实证明,conv 第 7 层的 l 有 256 个通道,但是 g 有 512 个通道。为了将两个向量相加(pc 方法)或进行点积(dp 方法),向量必须大小相同。

作者说如果 lg 大小不一样,那么他们先把 g 投影到 l 的低维空间。他们不将 l 投影到 g 的高维空间的原因是为了限制参数的数量。(他们所说的“项目”是指应用神经网络层,使 lg 大小相同。)

请注意,将 l 投影到 g 仍然是一个可接受的解决方案;你只是让 l 变大,而不是让 g 变小。“学会集中注意力”的 Pytorch 实现使用“c1,G1 = self . Attn 1(self.projector(L1),g)”行投射 lg ,其中 self . projector 是一个单卷积层,它采用 l 作为 256 个通道的输入,并创建 512 个通道的输出,以匹配 g 的 512 个通道。

步骤 2:根据相容性分数 c 计算注意力权重 a

我们在这里所做的就是使用一个 softmax 将兼容性得分 c 压缩到范围(0,1)内,我们将输出称为。有关 softmax 操作的回顾,请参见这篇文章。

第三步:计算每层 s 的注意机制的最终输出。

这里,我们通过对该层的 l 进行加权组合来计算特定层 s 的注意机制 g_a 的最终输出(回想一下,l 只是该层的输出)。)我们使用的权重是我们刚刚计算的注意力权重 a

步骤 4:基于关注度最终输出进行分类预测

现在我们想要使用我们刚刚为第 7、10 和 13 层计算的注意力输出 g_a 来做出分类决定。作者研究了两种选择:

方法 1: “串联”:首先串联注意力输出,然后将它们一起馈入单个全连接层,以获得最终的预测。

方法二:“indep”:将每个注意力输出馈入一个独立的全连接层,得到中间预测,然后将那些中间预测*均,得到最终预测。

(剧透警告:“concat”在他们的结果中表现更好。)

结果

可训练的注意力提高表现

作者评估了他们在各种任务中的注意机制,包括用 CIFAR-10、CIFAR-100 和 SVHN 进行多类分类。他们发现,使用他们的可训练注意力机制提高了“无注意力”基线的性能,相比之下,事后注意力机制( CAM )会导致性能下降(由于 CAM 方法施加的架构限制)。)

他们的方法的以下变体执行得最好:“参数化兼容性”(通过将 lg 相加,然后与学习向量 u 和“concat”(在将注意力输出 g_a 送入 fc 层进行预测之前,将它们连接起来)来计算兼容性得分。)

这是他们论文中图 3 的一部分,展示了一些关注相关物体的注意力地图示例:

全局特征向量 g 有多大用处?

他们论文的附录包含了一个有趣的讨论,关于全局特征向量 g 在注意力计算中的效用。回想一下,获得兼容性得分的“pc”和“dp”方法都利用了全局特征向量 g 。作者进行了实验,他们交换了使用的 g,发现:

  • 对于基于点积的注意机制[dp,表现较差]:“全局向量在引导注意方面起着突出的作用”
  • 对于参数化的兼容性函数[pc,性能更好]:“全局特征向量似乎是多余的。全局特征向量的任何变化都不会转移到结果注意力图。事实上,数值观察表明,全局特征的数量级通常比相应的局部特征的数量级小几个数量级。因此,全局特征向量的变化对预测的注意力得分几乎没有影响。然而,注意力地图本身能够始终如一地突出物体相关的图像区域。因此,似乎在基于参数化兼容性的注意力的情况下,以对象为中心的高阶特征被学习为权重向量 u 的一部分。

换句话说,我们也许可以像这样计算兼容性得分:

根本不用 g

不管 g 扮演的确切角色是什么,这种“学会集中注意力”的方法确实改善了结果,也确实产生了不错的注意力地图——因此,可训练的注意力显然在做一些有用的事情,即使它没有按照作者最初打算的方式使用 g

摘要

  • 可训练的注意力机制具有在训练期间学习的注意力权重,这有助于模型聚焦于对任务重要的图像的关键部分;
  • 事后注意机制是在模型完成训练后应用的技术,旨在提供模型在进行预测时观察哪里的洞察力;
  • 注意力集中是图像裁剪,可以通过强化来训练。软注意产生“模糊”的焦点区域,可以使用常规的反向传播来训练。
  • “学会关注”是一篇有趣的论文,展示了软可训练的注意力如何提高图像分类性能并突出图像的关键部分。

额外资源

  • 神经网络中的注意力以及如何使用它亚当·科西奥雷克著。这是一篇关于计算机视觉中注意力的伟大文章。它讨论了为什么注意是有用的,软与硬注意,高斯注意(代码),空间转换器(代码)。
  • 注意?立正!作者莉莲·翁。这是另一篇很棒的文章,关注自然语言处理中的注意力。它讨论了 seq2seq,自我注意,软与硬注意,全局与局部注意,神经图灵机,指针网络,变形金刚,蜗牛和自我注意甘。
  • 变形金刚:注意力是你所需要的全部:解释变形金刚,包括它的多头可训练自我注意力机制。
  • CNN 热图:显著性/反向传播:解释事后注意力技术显著性映射。
  • CNN 热图:梯度 vs .去卷积 vs .引导反向传播:解释这三种事后注意力方法实际上是相同的,除了对非线性的处理。
  • CNN 热点图:类激活映射(CAM) :解释了类激活映射架构和注意机制,和 HiResCAM 一起被证明可以保证显示模型在看哪里。
  • 制导摄像机坏了!显著图的健全性检查:解释 NeurIPS 的一篇论文,该论文揭示了几种流行的注意力机制的问题。
  • Grad-CAM:来自深度网络的视觉解释:解释事后注意机制 Grad-CAM。注意:尽管 Grad-CAM 的论文被引用了几千次,最*的工作证明了 Grad-CAM 的一个严重问题,即它有时会突出显示模型实际上没有使用的无关区域。

关于特色图片

图片来源:表演者带火 poi 。 Poi 是一种专注于摆动系留重物的表演艺术。它起源于新西兰。

原载于 2019 年 8 月 10 日http://glassboxmedicine.com

学习型企业家

原文:https://towardsdatascience.com/learned-entrepreneurship-5f4d47561ead?source=collection_archive---------27-----------------------

获得资金最多的创业公司有什么共同点?

(Source: Salesforce)

||简介||

创业公司的世界是一个动态的地方——对于创业者来说,一旦他们开始运作,很少会有既得利益或回报的承诺。私募股权和风险投资公司享受着丰厚的利润,因为他们理应擅长于识别哪些初创公司炙手可热,哪些失败了,但有没有一种方法可以自动化这一过程?我的目标是建立一个模型来回答这个问题:

计算机能模拟一家初创公司应该得到多少资金吗?

注意:本文中的表格是用来在计算机上查看的!

||数据||

本文使用的数据是通过 PitchBook 获得的,pitch book 是关于创业公司和私人投资领域的研究和财务信息的最佳来源之一。PitchBook 向我提供了以下信息:

  1. 最*估值(百万)
  2. 上次融资规模(百万)
  3. 上一轮融资(A 轮、B 轮等。)
  4. 最后融资阶段(种子轮、早期 VC 等。)
  5. 总部位置
  6. 雇员人数
  7. 行业领域(医疗保健、消费品等。)
  8. 行业集团(医疗保健服务、制药、软件等。)
  9. 筹集总额
  10. 活跃投资者数量

该实验中使用的总样本量由过去两年中获得资金的 973 家初创公司组成。

||探索性数据分析||

AngelList 对与创业文化相关的几个变量进行了统计演示,但更让我感兴趣的是实际的创业过程。下图(摘自 CBInsights)详细描述了“风险资本漏斗”,即大多数初创公司如何遵循特定的可预测生命周期。

The Venture Capital Funnel (Source: CBInsights)

下图展示了一家初创公司位于西北部(华盛顿州、加利福尼亚州、俄勒冈州)或东北部(纽约州、马萨诸塞州、宾夕法尼亚州)的可能性——我很想知道地理位置是否真的在预测支票金额方面发挥了作用!

Distribution of startups by region

||方法||

根据下面定义的规则,给定的初创公司被组织成不同的类别(其中 x 是资助金额):

 x ≤ $5M   -->  Class 1(SMALL) $5M < x ≤ $25M  -->  Class 2(MEDIUM) $25M < x ≤ $45M -->  Class 3(LARGE) x > $45  -->  Class 4(GIANT)

我这样做是为了改变我试图从一个回归问题中解决的问题(创业公司将获得的资金的确切价值是多少?)变成一个分类问题(资助会落在哪个区间?).这里精度的损失并不是一个大问题,因为没有必要去尝试和预测精确值!

使用 R 包“mice”,数据集中的缺失值通过一个神经网络进行*似,该网络使用“总募集额”和“活跃投资者数量”等变量(仅举几例)。这些变量被删除是因为,例如,模型可能在一轮融资结束之前无法访问活跃投资者的数量。

以下模型针对一组有限的功能进行了训练,并在测试期间根据它们在训练期间的表现进行了适当的加权:

  • 随机森林
  • 线性 XGBoost
  • 树 XGBoost
  • 极限学习机
  • 条件推理树
  • 袋装分类和回归树(CART)
  • 神经网络
  • k-最*邻

||结果||

我对从我相当复杂的模型中得到的结果印象深刻!在我执行动态加权后,我得到了以下结果。第一个表是我计算的分类分数汇总,第二个表是混淆矩阵。

 ╔════════════**═**╦══════════════╗║   accuracy  ║    kappa     ║╠═════════════╬══════════════╣║   0.70696   ║   0.51984    ║╚═════════════╩══════════════╝ **Predicted****Observed**     **1**   **2**   **3**   **4****1** | 71  13   0   2**2** | 27 110   6   4**3** |  1  12  11  15**4** |  0   0   0   1

这些结果表明,我的模型能够以 70.6%的准确率进行预测,并且具有中等程度的一致性。这些模型在估算“大”类资金规模时确实有些困难,但总体表现相当不错。

现在,更有趣的部分。模型最关心的变量是什么?R 中的‘caret’库提供了一种测量变量相关性的简单方法。

 **Class 1  Class 2  Class 3**  **Class 4  Average  Rank**
**Funding Round**   | 100.00   73.286   58.538   100.00   82.956    2
**Employees** |  83.11   98.774   53.270    98.77   83.481    1
**Funding Stage** |  73.62   72.776   60.768    73.62   70.196    3
**HQ Location** |  17.79   21.155   17.786    21.15   19.470    4
**Industry Group** |  12.54    0.000   13.984    12.54    9.766    5
**Industry Sector** |  10.48    5.845    5.972    10.48    8.194    6

从这张表来看,它看起来像是“融资轮”(A 轮、B 轮等。)和雇员人数是最重要的变量。这是有意义的,因为随着初创企业进入更多的融资轮或变得更大(即拥有更多员工),支票金额也会增加。然而,更有趣的是,“行业组”和“行业部门”变量对模型的贡献很小——这意味着初创企业的行业(软件、制药等)。)没什么区别!有趣的是,我们看到投资领域并不仅仅偏向于软件初创公司。最后,看起来公司总部的位置确实给出了某种迹象,表明这家初创公司是否会获得更高的支票金额!

然而,从本质上来说,理想的“启动条件”被掩盖了,因为有大量的其他变量在决定支票金额时起着更大的作用。

这种现象的一些现实例子包括 Dwolla 和 AgCode ,这两个非常成功的初创公司分别在伊利诺伊州的得梅因和明尼苏达州的格伦伍德开始了他们的旅程。他们成功的真正预测因素不是他们的行业(金融服务和农业技术),一个只在当地受过训练的天真模型会使他们失去信誉(看看他们是如何立足于美国中西部地区的)。我的模型强调初创企业能够成长和扩张的方式是一个更好的预测因素,引用员工总数和相应的融资轮数作为更强的输入。换句话说,能以更少的融资轮数更快成长(更多员工)的创业公司是健康的。

创业和私人投资市场是极其复杂的领域。我邀请你进行你自己的与这个主题相关的实验,并希望听到任何发现或进展!如果你喜欢这篇文章,请给它一些掌声关注 TDS 团队和我( Abhinav Raghunathan ),继续关注更多数据驱动的想法探索!你可以在这里找到这个项目的代码!感谢阅读!

||引文||

数据提供者:手册

图片: CBInsights 和 Salesforce

请参见文章的代码资源库获取完整的引用。

学习聚合函数

原文:https://towardsdatascience.com/learning-aggregate-functions-5b4102383433?source=collection_archive---------14-----------------------

利用关系数据的机器学习

https://pixabay.com

本文灵感来源于 Kaggle 大赛https://www . ka ggle . com/c/elo-merchant-category-recommendation。虽然我没有参加比赛,但我用这些数据探索了另一个在使用真实数据时经常出现的问题。所有的机器学习算法都可以很好地处理表格数据,但实际上很多数据都是关系型的。在这个数据集中,我们试图根据交易历史得出关于用户(由卡 id 标识)的结论。

The first two rows of the historical transactions

事务表列出了事务,因此包含每个用户的多行。让我们看看对数标度的直方图。

Histogram in the logarithmic scale

正如我们从这个图中看到的,大多数用户有不止一个交易。如果我们想对用户进行分类,我们会遇到每个用户有多条记录的问题,而机器学习算法需要表格数据。

Illustration of the problem we have with machine learning with relational data

这类似于 SQL GROUP BY语句,它帮助我们根据键(在我们的例子中是卡 id)对数据进行分组。SQL 还定义了许多聚合函数,这些函数的完整列表由定义并可以找到,例如,此处为。在 Pandas 中,聚合函数由 agg 函数支持。

许多机器学习实践者为所有可能的聚合函数定义了额外的特征,如countsummean等。问题是我们通常不知道哪些聚合函数是重要的。例如,我们可以添加总量作为一个特性,但是如果标签受到特定类别的总量的影响呢?我们最终会添加许多额外的特性,其中大部分是无用的,并且很可能会错过真正重要的东西。

如果我们可以用算法来学习它们,而不是手工制作集合特征,会怎么样?虽然过去研究过这种方法(例如,参见级联相关方法),但是当事务之间没有相关性时,我们可以使用一个简单的神经网络,该网络将使用一些标准张量流函数来学习聚合函数。

在我们的例子中,神经网络的结构非常简单。我们有一个完全连接的层,后面是segment_sum函数,它实际上执行分组操作,并对第一层的输出求和。第二个完全连接的层连接到输出,在我们的例子中,这是一个聚合函数,我们正在尝试学习。为简单起见,在这个概念验证中,我们使用线性单位,但对于更复杂的情况,我们必须引入非线性。

Sample neural network architecture

第一层中单元的数量给了我们它可以同时学习的集合函数的数量。

让我们考虑两个例子:学习计数和求和。

如果我们将第一层中的所有权重设置为零,并将所有偏差设置为 1,那么(假设线性单位),输出的总和将为我们提供每个用户的事务计数。

然而,如果我们将偏差和所有权重设置为零,但是将purchase_amount的权重设置为 1,我们将获得每个用户的总购买量。让我们在 TensorFlow 中演示我们的想法。

函数 segment_sum 的工作方式如下:

The image taken from TensorFlow documentation

它接受具有段 id 的单独张量,并且数据必须用相同的段 id 标记。它按段 id 对数据进行分组,并在零的维度上进行求和缩减。

Cost after epoch 0: 187.700562
Cost after epoch 100: 0.741461
Cost after epoch 200: 0.234625
Cost after epoch 300: 0.346947
Cost after epoch 400: 0.082935
Cost after epoch 500: 0.197804
Cost after epoch 600: 0.059093
Cost after epoch 700: 0.057192
Cost after epoch 800: 0.036180
Cost after epoch 900: 0.037890
Cost after epoch 1000: 0.048509
Cost after epoch 1100: 0.034636
Cost after epoch 1200: 0.023873
Cost after epoch 1300: 0.052844
Cost after epoch 1400: 0.024490
Cost after epoch 1500: 0.021363
Cost after epoch 1600: 0.018440
Cost after epoch 1700: 0.016469
Cost after epoch 1800: 0.018164
Cost after epoch 1900: 0.016391
Cost after epoch 2000: 0.011880

MSE loss vs. iterations

在这里,我们绘制了每次迭代后的成本函数。我们看到算法学习计数功能相当快。通过调整 Adam 优化器的超参数,我们可以获得更高的精度。

Cost after epoch 0: 8.718903
Cost after epoch 100: 0.052751
Cost after epoch 200: 0.097307
Cost after epoch 300: 0.206612
Cost after epoch 400: 0.060864
Cost after epoch 500: 0.209325
Cost after epoch 600: 0.458591
Cost after epoch 700: 0.807105
Cost after epoch 800: 0.133156
Cost after epoch 900: 0.026491
Cost after epoch 1000: 3.841630
Cost after epoch 1100: 0.423557
Cost after epoch 1200: 0.209481
Cost after epoch 1300: 0.054792
Cost after epoch 1400: 0.031808
Cost after epoch 1500: 0.053614
Cost after epoch 1600: 0.024091
Cost after epoch 1700: 0.111102
Cost after epoch 1800: 0.026337
Cost after epoch 1900: 0.024871
Cost after epoch 2000: 0.155583

MSE vs. iterations

我们看到成本也下降了,但随着我们向算法提供新数据,成本会出现峰值,这可以用高梯度来解释。也许我们可以调整超参数来改善学习过程的收敛性。

结论和下一步措施

我们演示了一个简单的神经网络,它可以学习基本的聚合函数。虽然我们的演示使用了线性单位,但实际上我们必须对第 1 层使用非线性单位,以便能够学习更复杂的聚合函数。例如,如果我们想知道category2 = 5的总量,那么线性单位就不起作用。但是如果我们使用例如 sigmoid 函数,那么我们可以将偏差设置为-100,然后将category2 = 5的权重设置为+100,并将purchase_amount的权重设置为小的正值 ω ω。在第二层中,我们可以将偏差设置为零,权重设置为 1 ω 1ω。

这种架构不学习功能mean。但是它学习它两个组件:sumcount。如果我们的决策边界取决于*均销售额,这与它取决于交易数量和总金额是一样的。

这种架构也不会学习更复杂的函数,如方差和标准差。这在金融领域可能很重要,因为你可能想根据市场波动来做决定。可能需要聚合前附加层来实现这一点。

最后,在这个例子中,学习速度很慢,因为我们必须以汇总的形式显示数据。可以通过预聚合数据,然后重新采样来提高速度。

本文中使用的所有代码都可以在我的 github repo 中找到。

学习分析

原文:https://towardsdatascience.com/learning-analytics-13a409156d7c?source=collection_archive---------10-----------------------

哇哦。这是一个值得深入研究的有趣话题。

使用 Nigel Geuenole、Jonathan Ferrar 和 Sheri Feinzig 在他们的书《人的力量》中提出的劳动力分析八步方法,我将在本文中探讨两个案例研究。

第一步:框定业务问题

ColesX 是一家虚构的澳大利亚超市、零售和消费服务连锁店,总部设在墨尔本。

新员工需要参加为期三天的研讨会,了解公司及其在工作场所健康和安全、工作场所欺凌和骚扰、伙伴计划、IT 政策、数据隐私法规等方面的政策。在研讨会结束时,他们将接受测试,以衡量他们对公司及其政策的了解程度。新员工培训的传统方法是现场讲座和问答。管理层决定为新员工试验一种新的基于电子学习的培训,可能需要 1 天时间才能完成。如果这个实验成功,它可以在几年内为公司节省数千美元。然而,在全球实施之前,高级管理层渴望确定新的电子学习培训计划是否比 2 天面对面的方法更有效。

ColesX 有很多在收银台工作的员工。该公司定期将其员工的扫描速度与目标扫描速度目标进行对比。扫描率基本上是一名员工一周内每分钟扫描的*均项目数。管理层最*决定引入一项特殊的培训计划,以分享提高扫描率的最佳实践。在第一阶段,员工可以选择参加这项培训。ColesX 非常清楚,稍微提高员工的*均扫描率将会显著提高月销售额。该组织热衷于研究新培训对扫描速度性能的影响。

基于这些事件,我们将 ColesX 的业务问题框定为:

  1. 与传统的 2 天面对面计划相比,1 天新入门计划的效果如何
  2. 新的特殊扫描速率改进培训计划的效果如何?哪些因素影响着扫描速率的性能

第二步:建立假设

为了测试这两种培训方法的差异,经理们选择了一组 15 名新员工参加为期 2 天的研讨会(方法 A),另一组 12 名新员工参加为期 1 天的电子学习(方法 B)。从所有新员工那里收集了每种培训方法的测试分数,这些分数将构成进一步分析的一部分

为了测试新的特殊扫描率培训计划的有效性,在提供培训之前和之后测量了所有员工的扫描率。

假设是有根据的、可测试的解释或预测,用于解决业务问题并支持数据收集和分析。在我们的案例研究中,确定了以下假设:

  1. 新开始训练方法 A 和 B 的*均测试分数没有区别。
  2. 特殊培训计划前后员工的扫描率没有差异。

下面进行的分析工作将试图反驳上述假设。如果我们成功地做到了这一点,我们将证明变革正在起作用。

在此阶段,业务负责人应审核并签署业务问题和假设,以便数据科学团队开始分析工作。

步骤 3:收集数据

对于我们新的初学者培训案例研究,从培训方法 A (2 天的研讨会)和 B(1 天的电子学习)中收集的测试分数如下所示:

对于我们的扫描速率训练计划案例研究,已经捕获了几个数据点。数据项包括工人 ID、edu(接受教育的年数)、残疾(0 表示无残疾,1 表示某种形式的相关残疾)、性别、扫描分钟数(本周每分钟扫描的*均项目数)、培训(0 =员工未接受培训)。1 =员工接受了培训)、ScanPminuteTime2(培训后一周内每分钟的*均项目数)。年龄字段与员工的特定年龄类别相关(如年龄 1 = 16–19 岁,年龄 2(20–24 岁)等)。

步骤 4:进行分析

  1. 新启动计划有效性分析

该分析包括测试数据集中的*均分数,以比较分数是否因训练方法而不同。这就是统计学的应用在引入独立样本 T 检验时发挥作用的地方。

独立性:因为每种训练方法的两组测试成绩没有依赖性。新员工被分成不同的小组

t 检验:用于检验不同组之间的*均值,并确定这些*均值在统计上是否不同。然而,T 检验假设每组的方差相等,这意味着训练方法 A 和训练方法 B 的两个样本组的测试分数的变化内大致相同。

让我们通过使用 Levene 的测试来测试数据集中方差的相等性。基于显著性结果(P 值大于 0.5),我们可以假设这两个样本组的测试分数没有差异。

现在让我们运行所有重要的 T 检验来检验我们的第一个假设:两种训练方法之间的测试分数没有显著变化。

哇:A 组和 B 组的*均测试分数相差至少 8 分。培训方法 B (1 天 E 学习)的*均得分明显更高,为 56.5。T 检验结果也具有小于 0.05 的显著 P 值结果,这意味着可以拒绝两个培训计划的*均测试分数相同的假设。

换句话说,这种 1 天 E 学的训练方法被证明是非常有效的。

2。新扫描率培训效果分析

这里的分析处理的是确定什么因素在驱动训练后进行的新的扫描速率测量。在这里,我们试图确定可变培训(员工参加过培训课程)是否对新的扫描率有任何影响。

我们可以通过开发多元线性回归模型来开发这样一个变化模型。使用 NewScanrate 分数作为响应变量,使用数据集中的所有其他变量作为独立预测变量,开发回归模型。让我们看看分析显示了什么。

多元线性回归结果产生了一些有趣的结果(参见每个变量最右侧的*标记,以确定驱动扫描速率的重要因素)

  • 随着时间的推移,女性的扫描速度越来越快。
  • 年龄在 1 岁(16-19 岁)和 6 岁(40-44 岁)的员工的扫描速度表现随着时间的推移逐渐提高
  • 正如所料,现有扫描率较高的员工在培训活动后会产生较高的扫描率分数
  • 最重要的是:培训领域非常重要,证明参加新的扫描率培训计划有可能提高扫描率

第五步:展现洞察力

酷毙了。所以我们的分析成功地消除了这两种假设。根据分析,可以得出以下结论

  1. 为期 1 天的电子学习新手培训比为期 2 天的面对面培训更有效
  2. 新的扫描速度培训在提高员工培训后的扫描速度表现方面是有效的

但是,等等,关于第二个观点,我们的研究表明,随着时间的推移,女性群体已经表现出更高的扫描速度。为了确定新培训对扫描率的有效性,让我们控制性别和培训的交互变量,以评估扫描率的表现如何在培训后得到改善。

我们这样做是通过开发一个交互作用图的扫描率测量后,培训与交互变量的培训(采取:是或否)和性别。

我们发现,参加培训的男性群体的扫描速度从 18 提高到了 22。无论有没有训练,女性的扫描率几乎保持不变。

因此,这里发现了第三个洞见。

3.新扫描率培训的引入使男性雇员比女性雇员受益更多(女性雇员已经表现得更好)

步骤 6:确定建议

根据我们的发现,可以提出一些非常有针对性的建议,例如:

  1. 将为期 2 天的面对面新入门培训替换为为期 1 天的在线学习。这一举措将为公司节省数千美元,同时提高流程的效率。此处可以开发一个成本模型来评估 2 天培训与 1 天培训的成本,以便将来进行跟踪和评估
  2. 为所有员工推出新的扫描速率性能培训。跟踪课程的出席情况,尤其是男性,鼓励他们在商场参加培训。引入采用计划,如奖金计划,以推动更多人参与培训,并提高目标扫描率,以推动整体绩效的提高

第七步:表达你的观点

本节讨论如何将建议转化为公司的行动。这就需要一个强有力的项目发起人来支持分析事业,并确保建议得到适当的实施和沟通。

变革管理、培训、沟通都是推动公司采纳建议的一部分。

步骤 8:实施和评估

比方说,在每 6 个月的实施期内,会定期根据开始时设定的 KPI 对为期 1 天的新入门培训计划的测试分数、成本节约、绩效扫描率和销售绩效进行审查,以衡量计划的持续有效性。财务效益衡量是此类项目评估的关键部分。

报告分析项目的节约是为组织内更多基于分析的项目开发业务案例的关键。

参考

预测人力资源分析:马丁爱德华兹和柯尔斯顿爱德华兹。

《人民的力量》:奈杰尔·古诺尔、乔纳森·费拉和谢里·费恩齐格

第二个案例研究的数据集来自 Martin R Edwards 和 Kirsten Edwards 所著的《人力资源预测分析》一书

我开发的 r 代码和数据集都在我的 github 帐户中:

https://github . com/sambit 78/People-Analytics-Project/tree/master/06% 20-% 20 training % 20 Analytics

通过预测游客购买意向学习人工神经网络

原文:https://towardsdatascience.com/learning-artificial-neural-networks-by-predicting-visitor-purchase-intention-724ba2be7c29?source=collection_archive---------21-----------------------

使用 Keras 和 Tensorflow 构建人工神经网络

当我在 Udemy 上学习关于深度学习的课程时,我决定利用我的知识,尝试预测一个访问者是否会购买(产生收入)。数据集取自 UCI 机器学习库。您可以在下面的回购协议中找到完整的代码:

[## kb22/购买意向预测

该项目包括预测游客是否会购物。-kb22/购买意向预测

github.com](https://github.com/kb22/Purchasing-Intention-Prediction)

导入库

第一步是导入必要的库。除了常规的数据科学库包括numpypandasmatplotlib之外,我导入了机器学习库sklearn和深度学习库keras。我会用keras开发我的以tensorflow为后端的人工神经网络。

导入数据集

我将导入数据集并获得数据的基本概述。有 1,908 名访客带来了收入,而 10,422 名访客没有。

有 18 列、17 个特性和 1 个目标变量(收入)。没有丢失的值。我也跑了dataset.describe()。每一列的mean各不相同,因此,缩放应该有所帮助。

考虑到Revenue是目标列,我将把数据集分成测试集和训练集。我将数据集分成 80%的训练数据和 20%的测试数据。

数据分析和可视化

目标列

我首先在产生收入的访问者和没有产生收入的访问者之间创建了一个条形图。

Target column bar chart

从上面的柱状图中可以清楚地看出,数据集包含了大多数没有产生收入的要素值。数据集是高度不*衡的,这是我们必须创建一个有效的模型,仍然可以准确地在两个类之间进行分类。

相关矩阵

我创建了相关矩阵,然后根据相关程度给它着色。

Correlation Matrix (Part 1)

Correlation Matrix (Part 2)

看来PageValues与我们的目标值线性相关最大。另外,像OperatingSystemsRegionTrafficType这样的特性的相关性小于0.02或大于-0.02,所以我将删除这些列。

从相关矩阵中可以看出,AdministrativeAdministrative_DurationInformationalInformational_Duration以及ProductRelatedProductRelated_Duration之间的关系似乎具有非常高的相关性。这是意料之中的,因为在一种类型的页面上花费的时间肯定会受到该类型页面的访问量的影响。因此,我们可以删除每种类型访问的页面数量。

数据工程

移除列

我现在将删除所有不需要的列,包括AdministrativeInformationalProductRelatedOperatingSystemsRegionTrafficType

编码分类列

我将使用LabelEncoder对分类列进行编码。我将使用OneHotEncoder对列类进行编码,然后将它们追加到数据集中。

缩放数据

接下来,我将重新调整数据,使每一列的*均值都在 0 左右。

模型生成

我将使用 Keras 和 Tensorflow 作为后端来生成一个人工神经网络。有 32 个输入节点,接着是 4 个隐藏层和 1 个输出层。该模型体系结构被设计为增加验证集的准确性以及防止在训练集上过度拟合。

Artificial Neural Network

我为人工神经网络开发了一个序列模型。这些层或者是致密层或者是脱落层。每个密集层表示中子数为units,激活函数为relu,第一层还包括输入的input_dim。输出层的激活是sigmoid。退出确保训练数据不会过度拟合。

训练和评估模型

我训练了总共 50 个时期的模型,其中 90%是训练,10%是验证分割。我达到了 90.44%的训练准确率和 89.06%的验证准确率。

最后,对试验数据进行了预测。然后,我使用预测值和实际值创建混淆矩阵,计算出 88.77%的测试准确率。

结果分析

混淆矩阵显示,我们能够识别两种类型的访问者,将产生收入的访问者和不会产生收入的访问者。我们可以如下使用这些信息:

  1. 一旦我们能够确定某人将产生收入,我们不需要提供任何优惠券,而是我们可以给访问者特殊的奖励积分,他们可以在下次访问时使用。
  2. 不太可能进行购买的访问者可以被提供折扣券,使得他们更有可能进行购买。

感谢阅读。请分享你的想法、观点和建议。你也可以通过 LinkedIn 联系我。您可能还会喜欢以下内容:

[## 在 Kaggle 上使用 CNN 进行深度学习以识别疟疾细胞

医学领域的深度学习

towardsdatascience.com](/deep-learning-to-identify-malaria-cells-using-cnn-on-kaggle-b9a987f55ea5) [## 利用 OpenCV 人脸检测神经网络提取人脸

使用预先训练的人脸检测系统

towardsdatascience.com](/extracting-faces-using-opencv-face-detection-neural-network-475c5cd0c260) [## 使用机器学习预测心脏病的存在

机器学习在医疗保健中的应用

towardsdatascience.com](/predicting-presence-of-heart-diseases-using-machine-learning-36f00f3edb2c) [## 使用 React 和 Flask 创建一个完整的机器学习 web 应用程序

用 UI 和后端构建完整的 ML 应用程序

towardsdatascience.com](/create-a-complete-machine-learning-web-application-using-react-and-flask-859340bddb33)

使用 Keras 和 Tensorflow 从图形数据中学习

原文:https://towardsdatascience.com/learning-from-graph-data-using-keras-and-tensorflow-5b54e3ddffbf?source=collection_archive---------12-----------------------

Cora Data set Citation Graph

动机:

在引用网络、社交网络(关注者图、朋友网络……)、生物网络或电信等现实应用中,有许多数据可以用图表的形式表示。
使用图提取的特征可以通过依赖相邻节点之间的信息流来提高预测模型的性能。然而,表示图形数据并不简单,尤其是如果我们不打算实现手工制作的特性,因为大多数 ML 模型期望固定大小或线性的输入,而图形数据并非如此。
在本帖中,我们将探索一些处理一般图形的方法,以便根据直接从数据中学习到的图形表示进行节点分类。

数据集:

Cora 引文网络数据集将作为贯穿本文的实现和实验的基础。每个节点代表一篇科学论文,节点之间的边代表两篇论文之间的引用关系。
每个节点由一组二元特征(单词袋)以及一组将它与其他节点链接起来的边来表示。
数据集具有被分类为七个类之一的 2708 节点。网络有 5429 个链接。每个节点也由指示相应单词存在的二进制单词特征来表示。总的来说,每个节点有 1433 个二元(稀疏)特征。下面我们使用 140 样本进行训练,其余用于验证/测试。

问题设置:

问题:在训练样本很少的情况下,给图中的节点分配类别标签。
直觉 / 假设:图中距离较*的节点更有可能有相似的标签。
解决方案:想办法从图中提取特征,帮助分类新节点。

提议的方法:

基线模型:

Simple Baseline Model

我们首先用最简单的模型进行实验,该模型学习仅使用二元特征并丢弃所有图信息来预测节点类。
该模型是一个全连接的神经网络,将二元特征作为输入,输出每个节点的分类概率。

基线模型准确率: 53.28%

这是初始精度,我们将通过添加基于图形的功能来提高它。

添加图形特征:

一种自动学习图形特征的方法是将每个节点嵌入到向量中,方法是在预测两个输入节点之间最短路径长度倒数的辅助任务上训练网络,如下图和代码片段所示:

Learning an embedding vector for each node

下一步是使用预训练的节点嵌入作为分类模型的输入。我们还添加了一个额外的输入,它是使用学习嵌入向量的距离的相邻节点的*均二进制特征。

下图描述了生成的分类网络:

Using pretrained embeddings to do node classification

图嵌入分类模型准确率:73.06%

我们可以看到,与基线模型相比,将学习到的图特征作为输入添加到分类模型有助于显著提高分类精度,从 53.28% 73.06% 😄。

改进图形特征学习:

我们可以通过进一步推动预训练并在节点嵌入网络中使用二进制特征,然后除了节点嵌入向量之外,再使用来自二进制特征的预训练权重,来进一步改进先前的模型。这导致模型依赖于从图结构中学习的二进制特征的更有用的表示。

改进的图嵌入分类模型准确率: 76.35 %

与以前的方法相比,这种额外的改进增加了几个百分点的准确性。

结论:

在这篇文章中,我们看到,我们可以从图结构数据中学习有用的表示,然后使用这些表示来提高节点分类模型的泛化性能,从**的 53.28%提高到* 的 76.35% 😎。*

复制结果的代码可从这里获得:https://github.com/CVxTz/graph_classification

如果您有任何建议或者您需要一些在您的机器上运行代码的指示,请随意评论😉

向机器学习:数据供应链

原文:https://towardsdatascience.com/learning-from-machines-the-data-supply-chain-4380f420bb2c?source=collection_archive---------15-----------------------

从航空工程师转型为数据科学家的见解

这是由两部分组成的系列探索机器学习(ML)产品中的 第二部分 。在 第一部分 : 传统制造业能教给我们的关于数据产品的东西 中,我把实物产品和 ML 产品进行了类比。在第二部分中,我将讨论这些相似性如何帮助数据科学家和数据组织进行产品开发,并通过利用精益制造和供应链概念降低与数据依赖相关的风险。

Photo by Ivan Bandura on Unsplash

总结上一篇文章:机器学习模型的性能和持续可靠性高度依赖于数据的质量。从这个意义上说,数据产品在特定方面类似于物理产品。两者:

  • 要求持续供应高质量的投入(数据集与物理部件)以持续生产/交付;
  • 处于供应链的支配之下,尤其是当产品依赖于非内部生成的数据时(例如,开源数据与购买的制造部件);
  • 根据需要,要求随着时间的推移进行重新设计,以满足可持续性和/或性能需求。这通常严重依赖于供应链(例如,如果不再维护某些数据集,需要替换/删除数据,而零件变得过时且不再上市,则产品需要替代解决方案)。

像原材料或零件一样,数据集是有形的关键组件,需要妥善管理,以确保 ML 产品的持续质量、可靠性和可用性。这是一项最终由数据组织中不同角色共同承担的责任,对于每个数据集需要做出不同的决策和考虑。

数据供应链

定义:数据的生命周期过程;选择、采购、传输、质量保证、仓储/存储、数据管理、转换、监控和分发——为数据产品中使用的数据管道提供信息。

我从精益制造中学到的最有用和最直观的概念之一是重新考虑你的千篇一律的流程。在更精细的层面(即原材料或零件层面)制定战略有助于组织更好地管理产品库存,同时降低间接成本。当您的产品基于数据构建时,中心思想是为每个数据集制定不同的计划。

为每个数据集制定计划

精益制造原则: 对每一个零件进行计划 【准备】

这是关于了解数据集需要管理的全面程度、它需要什么资源、与之相关的成本和风险,并考虑这些因素,为每个数据集创建一个计划,在确保质量的同时减少维护和管理负担(更快乐的数据工程师)。

正如所有数据科学家、数据分析师和数据工程师所经历的那样,并非所有数据集都是*等的。有些具有设计良好的模式,而有些则是过程的副产品,有些更值得信赖,有些覆盖率低,有些杂乱无章,需要大量清理,而有些则不定期更新。有些甚至可能在未来变得不可用。除了这种多样性,事实是某些数据集比其他数据集对 ML 模型的成功更重要。应该对最关键和最难处理的问题进行更多的规划。这里的想法是确定构建高性能 ML 模型所需的数据集,并确保这些数据集经过评估,并被认为适合在模型原型阶段的生产中使用。这将省去以后的一些麻烦。一旦他们通过了审查,确保最重要的计划和解决第一。每种方法都可能需要不同的方法来保证供应、质量监控、数据管理和管道维护。

因此,您已经与业务需求保持一致,并且已经构建了一个原型模型。现在您想将其部署到生产环境中。您需要考虑许多事情才能有效地做到这一点,但根据以下问题的答案,您可能会从将供应链管理概念纳入每个数据集的计划中受益:

您的 ML 模型或数据产品是否完全依赖于组织内部生成的数据集?

如果答案是肯定的,你可能不会从以下供应链概念中受益,因为(希望)你可以与各部门协调设计符合你的 ML 产品需求的数据管道。然而,如果您需要获得开源/第三方数据,或者难以在内部可靠地保护数据,以下概念可以帮助最小化 ML 产品性能风险。

数据集采购策略

采购行话 :单一来源对多个供应商,单一来源和购买对制造。

这一概念主要适用于保护基于开源、公开来源、第三方供应商或业务合作伙伴的原始或衍生数据集。该计划不需要在原型阶段完全具体化,但在过程的早期开始是很重要的。然而,一旦你仔细检查了不同数据集的质量、可信度、完整性等。并且你有一个最小可行产品(MVP),创建一个数据源计划将帮助你更*稳地过渡到生产

最保守的策略是从多个来源获取数据。拥有一个替代源是保护您的产品免受外部问题影响的一个好方法,但是要求所有外部数据集立即拥有一个备份源有时是不现实的、昂贵的并且通常是不必要的。类似地,即使数据集是关键的,但可以广泛获得,您可能会决定依赖一个来源,并意识到如果您失去了第一个提供者,您将需要切换到另一个提供者(当然,重新训练您的模型),只要您的用户可以接受这段停机时间。在制造业中,这种策略被称为“单一来源”,即与单一供应商合作的好处——减少开销/维护、节约成本等。—超过与多家供应商合作的成本。

但是,如果一个可比较的替代数据集 不存在 ,您可能需要与您的来源建立合作关系,并创建一个供应商合作关系。虽然通常应避免依赖唯一的数据集,但该数据集可能会给你带来超过风险的竞争优势。在这些情况下,您可以通过与源组织建立牢固的合作关系来防止这些数据集的意外丢失。

如果发现数据很重要,但是没有生产就绪的数据集,您可能别无选择,只能自己生成数据(或者将工作分包出去)。这通常不太理想,但可能存在这样的情况,即在内部创建数据集解决了关键的数据需求,值得投入资源。这是我在一个个人分类项目中做的。我意识到我不能依靠众包的努力,因为标记标签需要特定的领域知识。

Inspection — Photo by Shane Aldendorff on Unsplash

数据质量检查

质量工程师发言: 来料检验&组件测试

一旦您接受了一个数据源,并且可能接受了一个替代数据源,您将希望随着新数据的到来以及数据在整个过程中的聚合和转换,继续评估数据的质量。就像物理产品一样,只需一个有缺陷的数据点或一次错误的批量刷新就能导致您的产品失败。为了避免这种情况,请确定可接受的质量水*,并通过构建数据管道测试来监控每个数据集。这些将识别数据何时不符合预期的模式、数据类型或值范围。可以用各种创造性的方法检查值,例如通过应用简单的范围内检查、统计分布测试和趋势检查或其他更高级的业务规则。这种逻辑应该由数据科学家和分析师来设计和审查——他们很好地理解数据集和 ML 模型依赖关系。检查和存储数据质量结果的日志将有助于查明虚假数据的存在。这在调查 ML 模型为何表现不佳时特别有用

重要的是要明白,自动化质量检查不能捕捉一切,你可能不知道要立即实现什么。这是一个反复试验的过程——检查哪些相关,哪些不相关?如果数据集被标记,该怎么办?随着时间的推移,随着数据的变化和产品的成熟,需要重新审视这一逻辑。

持续源评估

供应链管理参考: 年度供应商评审

一旦构建了生产数据管道,您可能希望定期检查每个数据集的性能(查看那些数据质量日志)。数据提供程序是否不断更改格式/模式?是否存在任何价值一致性问题,这些问题是否持续存在?您还应该定期查看使用情况并进行评估,以确定它们的数据集对您的产品或组织是否仍然有价值。供应是否仍然可靠和可持续?价格是否有变化,或者争论、加工和储存的间接成本是否有变化?是否出现了更适合您的需求或支持增强功能的替代数据源?如果是这样,你需要确定这些数据是否仍然值得。

实际上,根据来源及其数据集对您的 ML 产品的重要性,持续的来源评估在深度和频率上会有所不同。如果您的业务密切合作,您经常会遇到数据源的数据质量问题,或者如果您想要进一步扩展数据集的功能,使其超出当前支持的范围,您可能需要更频繁地查看这些数据源。

Photo by Joshua Coleman on Unsplash

为了充分利用这些概念,作为一名数据科学家,您需要在整个组织中持续协作,从产品的原型开发阶段到产品开发、发布和维护阶段,并积极为产品数据战略做出贡献。不能为一个产品建立一个数据供应链,然后任其运行。它将随着数据和产品不断发展——工作永远不会完全完成。随着时间的推移,总会有紧急情况需要解决和调整。如果你的 ML 产品依赖于你控制之外的任何东西,有远见的管理和计划是至关重要的。

总之,生产 ML 模型中使用的每个数据集都是产品的核心组件。每个数据集的价值、用途、可用性和可靠性应该反映出您的组织如何管理它。要主动管理数据供应风险,您需要评估您的来源,评估您如何保护您的供应,监控数据质量,并定期重新检查每个数据集的计划。最终,整个组织的责任是建立和支持一个强大、可靠、高质量的数据供应链,以确保 ML 产品的持续成功。

嗨,我是 凯蒂·拉泽尔-费尔曼 。我是一名数据科学家,是纽约市 artluxe.co*的创始人。对这个帖子有疑问或者对这个话题很好奇?下面评论或者随时* 联系我

从模拟数据中学习

原文:https://towardsdatascience.com/learning-from-simulated-data-ff4be63ac89c?source=collection_archive---------19-----------------------

困扰深度神经网络的最大问题之一是,训练它们需要大量的标记数据集。一些研究人员试图通过对元学习和少量学习等领域的研究来克服这一限制。然而,就目前而言,在诸如对象检测的任务中,需要大量的数据集才能成功。

This article discusses combining Graphics Engines such as Unity with GANs to build big datasets

用于驱动视频游戏(如 Unity)的图形引擎能够产生大量带标签的数据集。深度学习智能体可以在视频游戏环境中接受训练,以执行自主导航等任务。然而,它们仍然是模拟和真实数据集之间的鸿沟,这是深度卷积神经网络自身无法克服的。

解决这个问题的方法是生成性对抗网络。GANs 可以使用“真实”对“虚假”的损失函数来推动模拟数据更接*真实图像。这使得深度学习模型能够利用图形引擎,这些引擎可以产生巨大的标记数据集。本文将解释苹果公司研究人员提出的 SimGAN 模型的细节。本文着重于将来自 Unity 引擎的模拟眼睛图像移动到来自 MPIIGaze 数据集的真实图像,用于眼睛注视估计的任务。

High Level Overview of the SimGAN model

以下是这篇论文的链接:

[## 通过对抗训练从模拟和无监督图像中学习

随着图形学的最新进展,在合成图像上训练模型已经变得更加容易处理,有可能…

arxiv.org](https://arxiv.org/abs/1612.07828)

导言和结果

在深入研究这个模型是如何实现的细节之前,这里有一些实验结果来激发你的兴趣。一项结果评估是用视觉图灵测试进行的。这需要使用人工标记来确定哪些图像是“真实的”或“虚假的”。原始模拟数据由人类标记器正确标记,正确率为 162 / 200 (81%)。在应用 SimGAN 后,人类标记器的表现与随机猜测一样好(最大熵),比率为 517 / 1000 (51.7%)。

此外,仅在合成数据上训练的模型对真实数据集上的眼睛凝视的分类率为 64.9%。一旦使用 SimGAN 进行了细化,根据细化数据训练的模型对真实数据集的分类率为 87.2%。使用 GAN 改进数据导致了 22.3%的分类性能!

下面介绍了使 SimGAN 工作得如此出色的主要技术:

自我调整的对抗性损失

在这个 GAN 公式中,发生器将改进模拟眼睛图像,使得鉴别器不能分辨改进的和真实的图像之间的差异。然而,GAN 训练可能是不稳定的,并且在没有额外的正则化的情况下,不能保证生成器将以保留原始图像的标签的方式来细化图像。注意,这样做的全部目的是模拟图像都被标记。因此,图像的增强必须保留这个标签。直接引用论文,

"习得的转换不应该改变凝视的方向."

在 SimGAN 中使用的自正则化损失对于产生与原始图像大相径庭的图像的生成器是不利的。这是在以下损失的情况下完成的:

Regularization Loss Term

上述损失增加了一个额外的损失项,即细化图像和原始图像之间的 L1 距离。请注意,这是每个像素的损失,这意味着细化图像中的每个像素都要与原始图像进行比较。将这种损失与对抗性损失相加,生成者的目标如下:

Generator Loss for the SimGAN model, top component: adversarial loss with respect to the discriminator, bottom component: self-regularization term which ensures the generator does not dramatically alter the original image.

phi(x)(抱歉,不知道如何将希腊符号添加到中等文章中),术语指的是修改细化图像和原始图像的函数。这可以是标识符映射,使得 phi(x) = x 或者图像导数、颜色通道*均值或者学习的变换。本文简单地使用了恒等式映射 phi(x) = x。

局部对抗性损失

一般来说,GANs 的一个最大问题是,生成器往往会产生诸如三条腿的狗或两个头的青蛙之类的人工产物。对此的一个解决方案是让鉴别器批评局部图像碎片,而不是整个图像。SimGAN 模型中的实现类似于另一种称为 PatchGAN 的鉴频器,但在鉴频器的输出维度上有很大不同。

这种损失的目的是让鉴别器将每个局部小块分类为真的或假的。SimGAN 通过让鉴别器输出大小为(w x h)的概率图来实现这一点,其中(w x h)是要分类的局部小块的数量。通过在每个局部小块概率输出上取交叉熵损失,该信号被传播回生成器。

使用细化图像的历史更新鉴别器

GANs 的另一个大问题是深度神经网络难以在线/持续学习。这指的是从不断变化的分布中学习的任务。在这种情况下,由发生器产生的图像的分布是不断变化的,因此鉴别器受到诸如“灾难性遗忘”的持续学习问题的影响。

SimGAN 模型通过保留前一次迭代生成的图像的缓冲区来应对从非*稳分布中学习的挑战。该缓冲区包含先前生成的图像。如果 b 是由生成器创建的图像的批量大小,则鉴别器显示 b/2 个当前生成的图像以及 b/2 个从缓冲区采样的图像。

讨论

SimGAN 的一个有趣的组成部分是,生成器从模拟图像开始,而不是从随机向量开始。我无法从论文中找出鉴别器是否额外以先前的图像为条件,尽管考虑到局部对抗损失的细节,我认为情况并非如此。看看这种额外的调节是否能改善这个模型将会很有趣。

局部对抗性损失是 SimGAN 模型中另一个非常有趣的概念。我想知道作者会如何看待使用自我关注模块。自关注模块似乎非常适合于对抗由发生器引入的伪像,并且它具有模拟局部损失不会捕捉到的长程相关性的额外好处。然而,在这种情况下,以及在超分辨率等应用中,长程相关性并不是 GAN 模型的主要挑战。在这种情况下,真正区分模拟图像和真实图像的是局部统计。

这是一篇非常有趣的论文,我对使用 GANs 建立深度学习模型的潜力感到非常兴奋,这些模型是在来自 Unity 等图形引擎的模拟数据上训练的!感谢您的阅读!

从对称性中学习

原文:https://towardsdatascience.com/learning-from-symmetry-81b2edc3d8b5?source=collection_archive---------49-----------------------

Photo by Justin Main on Unsplash

对称的物体在视觉上和智力上都很吸引人。我们日常生活中的许多物品都是对称的——桌子、我们的交通工具、鲜花、时间。

甚至我们自己的身体也有很多对称性。

这是我们研究实验室喜欢的地方。

在我们的实验室中,我们正在探索如何利用大脑中对称性的本质来训练一个从这些复杂细节中学习的机器学习模型。

例如,我们小组提出了一种算法,可以利用大脑左右半球的差异来检测中风。前提是:

  • 病人的大脑在两个半球之间大致对称
  • 当一个人中风时,他的大脑半球会有明显的变化,因为他大脑两侧中风的可能性极小

巴曼博士测试了医院环境中使用的不同类型的成像,并能够利用两个大脑半球之间的差异有效地训练一个模型。

这项工作强调了一个简单的从对称性中学习的想法如何能够在中风检测等时间敏感的诊断中产生强大的影响。

我们甚至可以通过时间来延伸这个想法。

举一个更复杂的例子,使用病人的大脑连接体。简而言之,连接体是一种特殊类型的大脑成像的产物,当与复杂的图像预处理相结合时,能够模拟大脑内神经纤维的表示。

该小组开发的一个应用程序使用了健康人和帕金森病患者两个不同时间点的大脑图像,帕金森病是一种常见的神经退行性疾病。

前提是:

  • 帕金森病是一种连接主义疾病——我们知道大脑的某些部分会随着时间的推移而退化
  • 也许我们可以使用一个病人在时间内的数据,找到他们自己大脑之间的差异,从而找到代表一个帕金森氏症患者的任何有意义的模式
  • 这是可能的,因为我们将比较病人的大脑和他们自己,这免除了我们大多数研究的混乱的横截面性质

结果发现,我们可以发现帕金森氏症的有趣模式,研究人员通过将其应用于一组外部患者来测试这一点。

未来,我们将研究其他大脑疾病——最主要的是阿尔茨海默病。这是一种很多人都想知道答案的疾病,因为它影响着全世界数百万人,并且随着老年人口的开始增长,这种疾病还将继续增长。

人类大脑是我们这个时代最大的谜团之一,并将继续如此。人们一直在争论,是否需要 20 年、500 年或者无限年才能真正掌握我们大脑中发生的事情。

正是通过推动这些抽象的想法,试图让我们形成这些复杂现象的模型,在那里我们将能够更深入地了解大脑运转的本质。

我们认为对称性在这里发挥了作用。

感谢阅读。

通过各种自然语言处理任务学习一般句子表征

原文:https://towardsdatascience.com/learning-generic-sentence-representation-by-various-nlp-tasks-df39ce4e81d7?source=collection_archive---------13-----------------------

通用句导论

Photo by Edward Ma on Unsplash

有很多论文介绍了计算更好的文本表示的不同方法。从字嵌入、词嵌入到句嵌入,我介绍了不同的处理方法。但是大部分都是单个数据集或者问题域的训练。Subramania 等人探索了一种简单、有效的句子嵌入多任务学习方法。假设是好的句子表征可以从大量弱相关的任务中学到。

看完这篇文章,你会明白:

  • 通用语句表示设计
  • 体系结构
  • 履行
  • 拿走

通用语句表示设计

GensSen 由 Subramania 等人于 2018 年推出..他们探索了多任务方法,即在训练期间切换 5 个 NLP 任务来学习下游任务的通用句子表示。选定的任务包括:

  • 神经机器翻译(NMT):将英语翻译成法语和德语
  • 跳过思维向量:预测上一句和下一句
  • 内容分析:识别句子结构
  • 自然语言推理 (NLI):分类蕴涵

An approximate number of sentence pairs for each task. (Subramania et al., 2018)

在下表中,我们注意到“我们的模型”(Subramania 等人提出的方法)在添加更多任务时传输性能得到了提高。

Evaluation of sentences representation on 10 tasks. (Subramania et al., 2018)

除了句子表征,我们还注意到单词嵌入的结果比下表中的其他结果要好

Evaluation of word embeddings. (Subramania et al., 2018)

体系结构

所有 5 个任务都是序列到序列的问题,但是解决不同的 NLP 问题。序列到序列架构是编码器-解码器模型之一,而输入和输出都是顺序的。编码器将句子转换成固定长度的向量,而解码器试图通过链式规则产生条件概率。

编码器采用双向选通递归单元(GRU ),解码器采用单向递归单元。GRU 有助于消除消失梯度的影响,具有更快的计算速度。

由于我们需要学习一个通用的句子表示,我们必须在任务之间共享编码器,这样它就可以从不同的任务中学习一些东西。编码的句子表示将被发送到不同的解码器(每个任务的委托解码器)以解码向量并分类/预测结果。在训练模型之后,那些解码器将被扔掉,我们只需要在你的特定 NLP 问题中共享编码器。

由于作者建议使用不同的方法来训练编码器,我们必须解决什么时候应该切换任务?作者采用了一种简单的方法,即在每次参数更新后,选取一个任务进行训练。

拿走

  • 多任务学习有助于概括词向量,从而可以很容易地转移到其他问题领域并获得更好的结果。

关于我

我是湾区的数据科学家。专注于数据科学、人工智能,尤其是 NLP 和*台相关领域的最新发展。你可以通过媒体博客、 LinkedIn 或 Github 联系我。

参考

Sandeep S .、Adam T .、Yoshua B .、Christopher J . p .,通过大规模多任务学习学习通用分布式句子表示。2018

https://github.com/Maluuba/gensen

用 Python 学习图形(第 3 部分)

原文:https://towardsdatascience.com/learning-in-graphs-with-python-part-3-8d5513eef62d?source=collection_archive---------6-----------------------

内线艾

Python 的概念、应用和示例

A wonderful evening in Greenland, back in 2016

G 如今,raphs 正成为机器学习的核心,例如,无论你是想通过预测潜在的联系来了解社交网络的结构,检测欺诈,了解汽车租赁服务的客户行为,还是提出实时建议。

在本文中,我们将讨论:

  • 主要的图学习算法
  • Python 中的用例及实现

我在这个资源库上发布我所有的文章和相应的代码:

[## mael fabien/机器学习教程

本报告包含练习、代码、教程和我的个人博客文章

github.com](https://github.com/maelfabien/Machine_Learning_Tutorials)

这是我的图形系列的最后一篇文章。如果您还没有,请务必阅读本系列的第一篇文章:

[## 图表介绍(第一部分)

Python 中的主要概念、属性和应用

towardsdatascience.com](/introduction-to-graphs-part-1-2de6cda8c5a5) [## 图形算法(第二部分)

Python 中的主要概念、属性和应用

towardsdatascience.com](/graph-algorithms-part-2-dce0b2734a1d)

接下来,打开 Jupyter 笔记本,导入以下包:

import numpy as np
import random
import networkx as nx
from IPython.display import Image
import matplotlib.pyplot as plt

以下文章将使用最新版本的networkx``2.x。NetworkX 是一个 Python 包,用于创建、操作和研究复杂网络的结构、动态和功能。

我将尽量保持一种实用的方法,并举例说明大多数概念。

在本文中,我们将讨论图形学习中的三个主要任务:

  • 链接预测
  • 节点标签预测
  • 图形嵌入

先说链接预测!

I .链接预测

链接预测 中,给定一个图 G,我们旨在预测新的边。预测对于 预测未来的关系或者缺失的边 很有用,例如当图表没有被完全观察到时,或者当新的客户加入一个*台时(例如一个新的 LinkedIn 用户)。

LinkedIn 新用户的链接预测只是对他可能认识的人的建议。

在链接预测中,我们简单地尝试在成对的节点和节点之间建立一个相似性度量,链接最相似的 节点。现在的问题是识别和计算正确的相似性分数!

为了说明不同的相似性得分,让我们考虑下图:

Initial graph

设 N(i)是节点 I 的一组邻居。在上图中,节点 I 和 j 的邻居可以表示为:

Neighbors of j

和我的邻居:

Neighbors of i

1.相似性得分

我们可以基于它们的邻域为这两个节点建立几个相似性分数。

  • 共同邻居: S(i,j)=∣N(i)∩N(j)∣,即共同邻居的数量。在本例中,分数仅为 12,因为它们只有两个共同的邻居。

Common Neighbors

  • Jaccard 系数:一个归一化的共同邻居版本。

交集是共同的邻居,并集是:

Union

因此,Jaccard 系数由粉红色与黄色之比给出:

Jaccard Coefficient

值是 2/7。

  • Adamic-Adar 索引:对于节点 I 和 j 的每个共同邻居,我们加 1 除以该节点的邻居总数。其概念是,当预测两个节点之间的连接时,与少量节点之间共享的元素相比,具有非常大的邻域的公共元素不太重要。

  • 优先附件 : S(i,j)=∣N(i,j)∣∗∣N(j)∣
  • 我们也可以使用可用的社区信息。

2.性能指标

我们如何执行链接预测的评估?我们必须隐藏节点对的子集,并根据上面定义的规则预测它们的链接。这相当于监督学习中的训练-测试-分割。

然后,我们评估密集图形的正确预测比例,或者使用稀疏图形的曲线标准下的面积。

3.履行

让我们用 Python 来实现我们在前两篇文章中使用的空手道图!首先,打印关于图形的信息:

n = G_karate.number_of_nodes()
m = G_karate.number_of_edges()
print("Number of nodes :", str(n))
print("Number of edges :", str(m))
print("Number of connected components :" str(nx.number_connected_components(G_karate)))

然后,绘制图表本身:

plt.figure(figsize=(12,8))
nx.draw(G_karate)

现在,让我们删除一些连接,例如 25%的节点:

# Take a random sample of edges
edge_subset = random.sample(G_karate.edges(), int(0.25 * G_karate.number_of_edges()))# Remove some edges
G_karate_train = G_karate.copy()
G_karate_train.remove_edges_from(edge_subset)

并绘制部分观察到的图形:

plt.figure(figsize=(12,8))
nx.draw(G_karate_train)

Partially observed graph

您可以打印我们删除的边数和剩余的边数:

edge_subset_size = len(list(edge_subset))
print("Deleted : ", str(edge_subset_size))
print("Remaining : ", str((m - edge_subset_size)))

这个标题是:

Deleted : 15
Remaining : 63

雅克卡系数

我们可以首先使用 Jaccard 系数进行预测:

prediction_jaccard = list(nx.jaccard_coefficient(G_karate_train))
score, label = zip(*[(s, (u,v) in edge_subset) for (u,v,s) in prediction_jaccard])

预测看起来像这样,第一个节点,第二个节点,和一个 Jaccard 分数(或者直接是一个标签):

[(0, 32, 0.15),
(0, 33, 0.125),
(0, 3, 0.21428571428571427),
(0, 9, 0.0),
(0, 14, 0.0),
(0, 15, 0.0),
...

我们可以使用 ROC-AUC 标准来比较不同模型的性能,因为我们既有标签又有概率。

Adamic-Adar

我们现在可以对 Adamic-Adar 指数重复这一过程:

prediction_adamic = list(nx.adamic_adar_index(G_karate_train))
score, label = zip(*[(s, (u,v) in edge_subset) for (u,v,s) in prediction_adamic])

优先附件

对于优先附件分数:

prediction_pref = list(nx.preferential_attachment(G_karate_train))
score, label = zip(*[(s, (u,v) in edge_subset) for (u,v,s) in prediction_pref])

然后,我们选择最大化曲线下面积的模型,例如,或您选择的任何其他标准。到目前为止,我们讨论了链接预测最常见的相似性得分。

我们现在将更详细地介绍节点标记算法。

二。节点标记

给定一个图,其中一些节点没有被标记,我们想要预测它们的标记。这在某种意义上是一个半监督学习问题。

处理这类问题的一个常见方法是假设图上有某个*滑度*滑假设指出,通过数据上高密度区域的路径连接的点可能具有相似的标签。这是标签传播算法背后的主要假设。

标签传播算法(LPA)是一种快速算法,用于仅使用网络结构作为其向导来在图中发现社区,而不需要任何预定义的目标函数或关于社区的先验信息。

Neo4J Illustration of LPA

单个标签可以在连接密集的节点群中迅速占据主导地位,但在穿越连接稀疏的区域时会遇到困难。

半监督标签传播是如何工作的?

首先我们有一些数据:x1,…,xl,xl+1,…,xn ∈ Rp,前 l 个点的标签:y1,…,yl ∈ 1…C。

我们定义初始标签矩阵 Y ∈ R(n×C ),使得如果 xi 具有标签 yi=j,则 Yij=1,否则为 0。

该算法将生成一个预测矩阵 F∈R(n×C ),我们将在下面详述。然后,我们通过找到最可能的标签来预测节点的标签:

什么是预测矩阵 F?

预测矩阵是最小化*滑度和准确度标准的矩阵 F*。因此,在我们的结果的*滑度和准确性之间有一个折衷。

问题表达比较复杂,就不赘述了。然而,解决方案由下式给出:

如果你想在这个主题上更进一步,检查图函数的光滑性和流形正则化的概念。这部分的实现我就不赘述了,不过如果你感兴趣的话,斯坦福有一组很棒的带标签的图可以下载:https://snap.stanford.edu/data/,Networkx 有一个标签传播的直接实现:https://Networkx . github . io/documentation/latest/reference/algorithms/generated/Networkx . algorithms . community . label _ propagation . label _ propagation _ communities . html

三。图形嵌入

当处理 NLP 或计算机视觉问题时,我们习惯于在深度神经网络中嵌入图像或文本。到目前为止,我们所看到的图形的局限性之一是缺少矢量特征。但是,我们可以学习图的一个嵌入!图中有几个嵌入级别:

  • 嵌入图形组件(节点、边、特征…) ( Node2Vec )
  • 嵌入图的子部分或整个图( Graph2Vec )

1.节点嵌入

我们将首先关注图组件的嵌入。有几种方法可以嵌入节点或边。例如, DeepWalk 使用短时间的随机行走来学习图中边的表示。我们会谈到 Node2Vec ,一篇由来自斯坦福大学的 Aditya Grover 和 Jure Leskovec 于 2016 年发表的论文。

根据作者的说法:“ node2vec 是一个在图上进行表征学习的算法框架。给定任何图形,它都可以学习节点的连续特征表示,然后可以用于各种下游机器学习任务。”

该模型通过使用随机行走优化邻域保持目标来学习节点的低维表示。

Node2Vec 的代码在 GitHub 上有:https://github.com/eliorc/node2vec

要安装该软件包,只需运行:

pip install node2vec

然后,在你的笔记本上,我们会嵌入空手道图:

from node2vec import Node2Vec

然后,预先计算概率并生成行走:

node2vec = Node2Vec(G_karate, dimensions=64, walk_length=30, num_walks=200, workers=4)

然后我们可以嵌入节点:

model = node2vec.fit(window=10, min_count=1, batch_words=4)

要获得一个节点的向量,比如说节点“2”,使用 get_vector:

model.wv.get_vector(‘2’)

结果具有以下形式:

array([-0.03066591,  0.52942747, -0.14170371,  0.5471569 ,  0.07588464, -0.5693364 , -0.3017375 ,  0.21902356,  0.05244258 ...

因为我们在上面将维度定义为 64,所以它的长度为 64。我们能用这种嵌入做什么?例如,第一选项之一是识别最相似的节点!

model.wv.most_similar(‘2’)

它返回最相似节点和相应概率的列表:

[('3', 0.6494477391242981),('13', 0.6262941360473633),('7', 0.6137452721595764),
...

如果节点有标签,我们可以训练一个基于嵌入的算法并附加一个标签(节点标签,最相似节点…)

2.边缘嵌入

边缘也可以被嵌入,并且嵌入可以进一步用于分类。

from node2vec.edges import HadamardEmbedder
edges_embs = HadamardEmbedder(keyed_vectors=model.wv)

然后,通过指定两个链接节点的名称来检索向量:

edges_embs[(‘1’, ‘2’)]

哪些标题:

array([-8.1781112e-03, -1.8037426e-01,  4.9451444e-02,  2.8731486e-01...

同样,我们可以检索最相似的边,这可用于缺失边预测,例如:

edges_kv = edges_embs.as_keyed_vectors()
edges_kv.most_similar(str((‘1’, ‘2’)))

这个标题是:

[("('2', '21')", 0.8726599216461182),("('2', '7')", 0.856759786605835),("('2', '3')", 0.8566413521766663),
...

3.图形嵌入

也有直接嵌入图或子图的方法。这种方法是在 Graph2Vec 论文中开发的,可用于将图形或子图形表示为向量,从而允许图形分类或图形相似性度量。我不会深入研究这种技术,但是可以随意查看这个项目的 Github:

[## benedekrozemberczki/graph2vec

《graph2vec:学习图的分布式表示》(MLGWorkshop 2017)的并行实现。…

github.com](https://github.com/benedekrozemberczki/graph2vec)

要运行嵌入,非常简单:

python src/graph2vec.py --input-path data_folder/ --output-path output.csv

四。更进一步

我们现在已经介绍了图的介绍、图的主要类型、不同的图算法、它们在 Python 和 Networkx 中的实现,以及用于节点标记、链接预测和图嵌入的图学习技术。

不用说,这只是冰山一角。图论正在不断扩展,我认为列出一些资源会有所帮助:

  • 图卷积网络:https://towards data science . com/how-to-do-deep-learning-on-graphs-with-graph-convolutionary-Networks-7d 2250723780
  • 图形和流形上的几何深度学习:【http://www.geometricdeeplearning.com/ T3
  • 一个可能有所帮助的 MOOC:https://www . EDX . org/course/advanced-algorithmics-and-graph-theory-with-python

如果你有任何你认为有用的资源,不要犹豫留下评论,我会把它添加到列表中!

我希望这一系列的文章是有趣的后续!如果您有任何问题或意见,请随时评论。

注:本文最初发表在我的个人博客:https://maelfabien.github.io/

来源:

  • Neo4j 中的图形算法综合指南
  • 网络 x 文档,https://networkx.github.io/documentation/stable/
  • 巴黎电信的图论课程

学习语言从基础知识到 SQL

原文:https://towardsdatascience.com/learning-languages-from-abcs-to-sql-c1843d6853a3?source=collection_archive---------29-----------------------

除了基本的 SELECT 和 FROM 命令之外的 SQL 查询。

Photo via Pexels

如果你能理解我的头衔,我想教你一些基本的SELECTFROM命令之外的 SQL 查询命令,你可能会在工作描述中看到这些命令。我将编写代码,您可以使用这些代码通过 Google BigQuery 公共数据集 查询 StackOverflow 数据集 。每月最多可以免费查询 1TB 的这些数据。

对于下面的示例查询,我们将使用usersbadges表。下面的所有查询都将包含SELECTFROM命令,因此当我们向查询中添加新命令时,部分标题将会显示出来。

选择,从,限制

SELECT *
FROM `bigquery-public-data.stackoverflow.users`
LIMIT 5;

结果:从users表中返回所有列*,并将其限制为五行。

SELECT id, display_name
FROM `bigquery-public-data.stackoverflow.users`
LIMIT 5;

结果:从users表中返回iddisplay_name列,将其限制为五行。

SELECT u.id, u.display_name
FROM `bigquery-public-data.stackoverflow.users` AS u
LIMIT 5;

结果:这是与前一个查询相同的查询。

我们现在看到u.被添加到我们的列中,而AS u被添加到我们的第二行代码中。这叫做命名空间;这样我们可以给我们的表一个临时的别名。当从多个表中查询时,用表的别名作为列的前缀非常有用,我们将在后面看到。同样值得注意的是,第二行代码没有AS也会工作,像这样:FROM bigquery-public-data.stackoverflow.users u

不同,排序依据

SELECT DISTINCT u.id, u.display_name as name
FROM `bigquery-public-data.stackoverflow.users` u
ORDER BY u.display_name ASC
LIMIT 5;

结果:从users表中返回iddisplay_name列的五个唯一行(DISTINCT)。它按照display_name列的升序(或字母顺序)对它们进行排序。我们还可以看到display_name列已经被临时别名为“name”。

哪里,和,或者

SELECT *
FROM `bigquery-public-data.stackoverflow.users` u
WHERE u.up_votes >= 500 AND u.reputation >= 100
LIMIT 10;

第三行的AND可以用OR代替,下面我用其中一个解释结果。

带有AND的结果:返回users表中的所有列(*),限制为十个结果,其中的投票数等于或大于 500的信誉分数等于或大于 100。

使用OR的结果:返回users表中的所有列(*),限制为十个结果,其中支持票数等于或大于 500信誉分数等于或大于 100。

喜欢,我喜欢

SELECT u.display_name, u.location 
FROM `bigquery-public-data.stackoverflow.users` u
WHERE u.location LIKE 'United%'
LIMIT 10;

结果:从users表中返回 display_name 和 location 列,将其限制为十行,其中位置名称“United”开头。所以我们会看到居住在美国、英国等地的用户。在我们的结果中。或者,WHERE u.location LIKE ‘%United’将返回位置名称结尾的用户。因此,我们可能会看到用户在位置字段中输入错误,如“美国”。

需要注意四点:

  • 百分号(%)是通配符
  • 你可以用NOT LIKE否定一个LIKE
  • LIKE区分大小写,因此大写很重要
  • ILIKE不区分大小写LIKE,因此大小写无关紧要

内部连接

通常需要在一个查询中组合多个表中的数据。我们可以通过连接表来实现这一点。有几种类型的联接,但最常见的是内部联接,如下所示。

SELECT b.name, b.class, u.display_name
FROM `bigquery-public-data.stackoverflow.badges` b
INNER JOIN `bigquery-public-data.stackoverflow.users` u
ON b.user_id = u.id
WHERE b.class = 1 
LIMIT 5;

结果:返回徽章的名称和类别以及用户的关联显示名称,其中类别等于 1,结果限制为 5 个。

分组依据,AVG

有时我们需要将数据分组,然后运行聚合函数。一些常用的聚合函数有COUNTMINMAX —我们在下面的例子中重点关注AVG

SELECT b.name, AVG(u.reputation)
FROM `bigquery-public-data.stackoverflow.badges` b
INNER JOIN `bigquery-public-data.stackoverflow.users` u
ON b.user_id = u.id 
GROUP BY b.name
LIMIT 5;

结果:回答此问题—每个徽章的*均用户声誉得分是多少?

我希望这个指南能成为一个有用的资源,让你轻松地进行 SQL 查询。要了解更多关于这种语言的知识,我推荐查看 Connor Leech 的这个伟大的 资源 。如果你有任何问题,你喜欢/不喜欢什么,或者想在下面的评论中看到更多,请告诉我!

像婴儿一样学习

原文:https://towardsdatascience.com/learning-like-babies-image-classification-using-semi-supervised-learning-ccfb5b391d1f?source=collection_archive---------18-----------------------

内部 AI

基于半监督学习的图像分类

Features of visual hierarchy

Simple CNN architecture for image classification

卷积神经网络(CNN),一个为图像分类取得最大性能的概念,其灵感来自于哺乳动物的视觉皮层系统。尽管自动化计算机视觉系统取得了非凡的进步,但图像分类架构的大部分成功都来自标记数据。问题是现实世界的大部分数据都没有标注。

根据 CNN 之父、NYU 大学教授 Yann LeCun 的说法,人工智能的下一个“大事”是半监督学习——一种利用未标记数据进行训练的机器学习任务——通常是少量已标记数据和大量未标记数据。这就是为什么最*大量的研究工作集中在无监督学习上,而没有利用大量昂贵的监督。

“革命不会被监督”——阿廖沙·埃夫罗斯

受这个概念的启发,我们在 NYU 大学的班级举办了一场比赛,从 ImageNet 的 512k 未标记图像和 64k 标记图像中设计半监督算法。

半监督学习实际上是婴儿最常用的学习方法。当我们出生时,我们不知道世界是如何运作的:我们不区分重力,我们不理解深度,更不认识人类的表情。人脑大多以无监督或半监督的方式吸收数据。

Babies learn orientation unconsciously from a very early age. This can be considered ‘semi-supervised learning’.

方法:通过预测图像旋转的半监督表示学习

为了竞争,我们的算法采用的方法识别应用于输入图像【2】的 2d 旋转。在某种程度上,这类似于婴儿如何通过经验学习看世界。例如,随着时间的推移,婴儿会习惯于物体如何站立,山脉如何位于天空之下。事实证明,即使是这种简单的图像旋转任务也能让网络学习与监督任务相关的特征。

我们使用 ResNet 架构(更具体地说是 ResNet-50)进行最终提交。ResNet 模型在许多分类数据集上实现了一流的性能。此外,ResNet 剩余单元在某些条件下是可逆的,这可能有助于保存作为预训练的结果而获得的来自网络早期层的信息。我们利用一大组未标记的图像来预训练关于旋转预任务的 ResNet-50 模型。该模型的目标是预测每个输入图像的四个旋转角度(0、90、180、270)之一。作为在这个辅助任务上训练模型的结果,我们期望它学习在主要分类任务中有帮助的特征。

Semi-supervised learning using image rotation (left) and data augmentation (right)

经过预训练后,我们在这个特征提取器的顶部为主要任务训练了一个线性分类器,并通过从顶部开始逐步解冻各层来微调整个网络。我们还使用了数据扩充。与以前的模型相比,这种策略大大提高了准确性。

结果

下图显示了训练和验证损失曲线,以及训练过程中最终模型的准确性。红线表示从仅训练线性分类器切换到微调整个网络的时刻。

Train loss, validation loss and accuracy for the final submission

下图显示了验证数据集中 4 个随机图像的最*邻(第一列)。可以看出,半监督旋转模型清楚地设法学习图像的有意义的表示。

Nearest neighbors in the validation dataset: Semi-supervised model (left) and Supervised model (right). As it can be seen, semi-supervised rotation model (with rotation labels) shown on the left managed to learn meaningful representations of the images.

最终的前 1 名验证准确率为 32.4%。总之,我们可以得出结论,对未标记数据的半监督预训练有助于提高主要分类任务的准确性。然而,与在现有的大型标记数据集(如 ImageNet)上进行预训练相比,半监督训练的益处有多大尚不清楚。

更多信息,你可以参考我们的论文。

本项目由叶夫根尼·尼基丁、@sunor.yavuz、 曼里克 开发

参考文献

[1] Carl Doersch、Abhinav Gupta 和 Alexei A. Efros。基于上下文预测的无监督视觉表征学习。参加 2015 年计算机视觉国际会议(ICCV)。[2]斯皮罗斯·吉达里、普拉维尔·辛格和尼科斯·科莫达基斯。通过预测图像旋转的无监督表示学习。CoRR,abs/1803.07728,2018。
[3]艾丹·戈麦斯、叶萌·任、拉克尔·乌尔塔松和罗杰·b·格罗斯。可逆残差网络:不存储激活的反向传播。更正,abs/1707.04585,2017。【四】何、、、任、。用于图像识别的深度残差学习。更正,abs/1512.03385,2015 年。
[5]何、、任、。深剩余网络中的身份映射。更正,abs/1603.05027,2016。
[6]亚历山大·科列斯尼科夫,翟晓华,和卢卡斯·拜尔。重新审视自我监督的视觉表征学习。澳大利亚统计局/1901.09005,2019。
【7】塞巴斯蒂安·鲁德。梯度下降优化算法综述。更正,abs/1609.04747,2016。
【8】谢尔盖·扎戈鲁伊科和尼科斯·科莫达基斯。广泛的剩余网络。更正,abs/1605.07146,2016。

用真实数据学习 NLP 语言模型

原文:https://towardsdatascience.com/learning-nlp-language-models-with-real-data-cdff04c51c25?source=collection_archive---------5-----------------------

语言模型(LMs)估计不同短语的相对可能性,并且在许多不同的自然语言处理应用(NLP)中是有用的。例如,它们已经被用于 Twitter 机器人的“机器人”帐户,以形成自己的句子。

在本帖中,我们将首先正式定义 LMs,然后演示如何用真实数据计算它们。下面的 Kaggle 笔记本中用代码完整演示了所有显示的方法。

https://www . ka ggle . com/osbornep/education-learning-language-models-with-real-data

Source: https://www.pexels.com/photo/man-standing-infront-of-white-board-1181345/

第 1 部分:定义语言模型

概率语言建模的目标是计算单词序列的句子的概率:

并且可以用于找到序列中下一个单词的概率:

计算其中任何一个的模型被称为语言模型

计算概率的初始方法

定义:条件概率

设 A 和 B 是 P(B) =/= 0 的两个事件,给定 B 的条件概率为:

定义:链式法则

一般情况下,公式如下:

因此,应用于计算序列中单词的结合概率的链规则是:

例如:

这需要大量的计算,难道我们不能简单地通过计算和划分结果来估算吗,如下式所示:

总的来说,没有!在这种方法中有许多可能的句子需要计算,我们希望有非常稀疏的数据使结果不可靠。

方法采用马尔可夫假设

定义:马尔可夫性质

如果随机过程的未来状态的条件概率分布(取决于过去和当前状态)仅取决于当前状态,而不取决于之前的事件序列,则该随机过程具有马尔可夫性质。具有这种性质的过程称为马尔可夫过程。(维基百科)

换句话说,仅给定前 k 个单词,就可以估计出下一个单词的概率。

例如,如果 k=1 :

或者如果 k=2 :

马尔可夫假设的一般方程, k=i :

n 元模型

根据马尔可夫假设,我们可以正式定义 N 元模型,其中 k = n-1 如下:

其最简单的版本被定义为一元模型(k = 1)和二元模型(k=2)。

单字模型(k=1):

二元模型(k=2):

这些等式可以扩展到计算三元模型、4 元模型、5 元模型等。总的来说,这是一个不充分的语言模型,因为句子通常有长距离依存。例如,一个句子的主题可能在开头,而我们要预测的下一个单词出现在 10 个单词之后。

使用最大似然估计来估计二元模型概率;

小例子

给定一个包含以下三个句子的语料库,我们希望找到“I”开始该句子的概率。


~~~~~~因此,我们有:~~~~~~~~~~~~![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/7bbed2b06d0801aeff902374d15d0e24.png)~~~~~~~~~~~~换句话说,这个句子在我们的语料库中出现了三次,“I”作为第一个词出现。~~~~~~# ~~~~~~第 2 部分:将语言模型应用于真实数据~~~~~~# ~~~~~~数据源和预处理~~~~~~~~~~~~在这次演示中,我们将使用由斯坦福大学[提供的 IMDB 大型电影评论数据集。该数据包含评审者给出的评级、极性和完整注释。](http://ai.stanford.edu/~amaas/data/sentiment/)~~~~~~~~~~~~![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/a81914dcb4bcbc58507cf8397410ecc9.png)~~~~~~~~~~~~例如,第一条负面评论全文如下:~~~~~~~~~~~~![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/0ffb9d52e955fb17c227a2d640be5eb3.png)~~~~~~~~~~~~首先,我们将完整的注释转换成单独的句子,为句子的开头和结尾引入符号,并通过删除任何标点符号和小写所有单词来清理文本。~~~~~~~~~~~~![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/54c78179f7a7f07538c5fa4475ee1925.png)~~~~~~## ~~~~~~单字模型~~~~~~~~~~~~因为这是最容易计算的,我们可以找到每个单词出现的概率,用它来估计整个句子出现的概率,如下所示:~~~~~~~~~~~~![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/fa64c35e72fd5829c6f331f6bb5657c0.png)~~~~~~~~~~~~或者,我们可以通过对数规则使用对数来计算,以下情况成立:~~~~~~~~~~~~![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/b1e98a7f821b5ea08eb95602a30eef57.png)~~~~~~~~~~~~我们这样做是因为加法的计算速度通常比乘法快。~~~~~~~~~~~~例如,使用 unigram 模型,我们可以计算以下单词的概率。~~~~~~~~~~~~![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/323d6bf4717e591477a536a7a1ca4a9a.png)~~~~~~## ~~~~~~二元模型~~~~~~~~~~~~一元模型可能不准确,因此我们引入二元模型估计。应用这个有点复杂,首先我们在单词-单词矩阵中找到每个单词的共现。然后,计数通过前一个字的计数进行归一化,如下式所示:~~~~~~~~~~~~![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/64a7b389811e5b47ce59bc38356b746e.png)~~~~~~~~~~~~因此,举例来说,如果我们想改进前面显示的 P(a|to)的计算,我们首先计算(to,a)的出现次数,然后除以(t0)的出现次数。~~~~~~~~~~~~![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/70e85b3ec277093d4a517ff8e8dea012.png)~~~~~~~~~~~~同样地,如果我们把第一个单词改成“has”:~~~~~~~~~~~~![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/971b28c6a6edd91df953773542092476.png)~~~~~~~~~~~~如前所述,为了正确利用二元模型,我们需要计算所有单词对出现的单词-单词矩阵。有了这个,我们可以找到最有可能跟随当前单词的单词。然而,如果语料库很大,这也需要额外的时间量,因此最好根据需要为单词计算这一点,而不是穷尽地这样做。~~~~~~~~~~~~![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/4daf94315eea4bbba268ec2411478487.png)~~~~~~~~~~~~有了这个,我们就可以找到一些跟在给定单词后面的最有可能的单词的例子:~~~~~~~~~~~~![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/ba2ca2c122f57f0d6bdfaedcb560d72d.png)~~~~~~~~~~~~![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/0f2cf7d9f21d69d46a5d2195a51ad1b9.png)~~~~~~~~~~~~![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/db6fa2cf41d808ac954fee3790185007.png)~~~~~~~~~~~~一些单词后面有许多可能的单词,但是其他的,例如“非自然的”只有一个。这可能是因为这个词很少出现在第一个地方。~~~~~~## ~~~~~~用概率造句~~~~~~~~~~~~这些计算可以用来构成基本句子。我们将把句子的开头和结尾固定在各自的符号“~~”上,并将改变从单词-单词矩阵中选择的列,从而使句子变得不同。~~~~~~~~~~~~~~即使是‘在运行中’计算下一个单词,这样做所需的时间也特别多。例如,即使是我机器上的一个句子也要花将*两个小时来计算:~~~~~~~~~~~~![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/61b7e762bc929f702ee9a9145ea5e8fd.png)~~~~~~~~~~~~手动检查这些概率,我们发现这些词非常有可能,例如:~~~~~~~~~~~~![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/af2fd3637750265c37b1057256b564fa.png)~~~~~~## ~~~~~~三克及以上!~~~~~~~~~~~~如果我们继续估计方程,我们可以形成一个三元模型:~~~~~~~~~~~~![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/fd83de332786cb299696ebac29d2c5b8.png)~~~~~~~~~~~~例如:~~~~~~~~~~~~![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/6d29445de9fe1fcd7b0aa437a7248aad.png)~~~~~~~~~~~~**因此,三字短语“to a movie”比“to a movie”更常用,是我们的算法在造句时会选择的短语。**~~~~~~# ~~~~~~第 3 部分:训练和测试语言模型~~~~~~~~~~~~用于训练我们的 LMs 的语料库将影响输出预测。因此,我们需要引入一种方法来评估我们训练有素的 LMs 表现如何。训练最好的 LM 是能够在未知的测试集中正确预测句子的下一个单词的 LM。~~~~~~~~~~~~这可能非常耗时,构建多个 LMs 进行比较可能需要几个小时的计算时间。因此,我们介绍一下**困惑**的内在评价方法。简而言之,困惑是对概率分布或概率模型预测样本的程度的一种度量。~~~~~~## ~~~~~~定义:困惑~~~~~~~~~~~~困惑度是由单词数归一化的测试集的逆概率,更具体地,可以由以下等式定义:~~~~~~~~~~~~![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/92cafdb3b35556830a53d8384bf6b5a6.png)~~~~~~~~~~~~例如,假设一个句子由随机数字[0–9]组成,通过为每个数字分配相等概率(即 P=1/10)的模型,这个句子的困惑是什么?~~~~~~~~~~~~![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/0d1f92b321be1be3af5c7ff139231493.png)~~~~~~## ~~~~~~力学和信息论中的熵~~~~~~~~~~~~在力学中,玻尔兹曼定义了一个系统的熵与微观状态数量的自然对数有关:~~~~~~~~~~~~![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/0708f599098780924887844b8ad922c3.png)~~~~~~~~~~~~w 是微状态的数量,计算公式如下:~~~~~~~~~~~~![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/c6fcf375d484b6feedff3eb50a81a875.png)~~~~~~~~~~~~其中 n 是位置的数量,x 是分子的数量。~~~~~~~~~~~~在信息论中,随机变量 X 的熵(表示为 H(X))是由下式定义的预期对数概率:~~~~~~~~~~~~![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/540330a87b3b2f09c65ae4cd3f1c4b84.png)~~~~~~~~~~~~并且是不确定性的量度。~~~~~~~~~~~~**换句话说,熵就是一个系统可能存在的状态的数量。**~~~~~~## ~~~~~~例子:有偏向的掷硬币的熵~~~~~~~~~~~~假设掷硬币时正面和反面的概率定义为:~~~~~~*   ~~~~~~头=头=头~~~~~~
*   ~~~~~~P(尾部)= 1 P(尾部)= 1 P~~~~~~~~~~~~那么它的熵就是:~~~~~~~~~~~~![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/b8ee4d60983a5b7636e602ee057925a6.png)~~~~~~~~~~~~如果硬币是公*的,即 p = 0.5,那么我们有:~~~~~~~~~~~~![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/485a9556788f1d45225d71185079ee9b.png)~~~~~~~~~~~~不同偏倚概率下的全熵分布如下所示。~~~~~~~~~~~~![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/5444c5f212948a3adc0fefbe4687b690.png)~~~~~~# ~~~~~~语言的熵~~~~~~~~~~~~![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/cd98f9a09ef011a0312abf88aea41497.png)~~~~~~## ~~~~~~困惑与熵~~~~~~~~~~~~![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/a4522011196895ab998e6c49d9a55ec7.png)~~~~~~~~~~~~例如:~~~~~~~~~~~~![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/b8988d66683a60c6bbee3a84d11669c6.png)~~~~~~# ~~~~~~第 4 部分:拟合语言模型的挑战~~~~~~~~~~~~由于 LMs 的输出依赖于训练语料库,只有当训练语料库类似于测试数据集并且我们在训练中有过度拟合的风险时,N-grams 才工作良好。~~~~~~~~~~~~与任何机器学习方法一样,我们希望结果能够概括新信息。~~~~~~~~~~~~更难的是我们如何处理那些甚至没有出现在训练中但出现在测试数据中的单词。~~~~~~# ~~~~~~训练中零计数的处理:拉普拉斯+1 *滑~~~~~~~~~~~~为了处理在训练中看不到的单词,我们可以引入加法*滑。为此,我们只需在每个单词的计数上加 1。~~~~~~~~~~~~这稍微改变了分布,通常用于文本分类和零的数量不多的领域。然而,这并不经常用于 n-gram,相反,我们使用更复杂的方法。~~~~~~~~~~~~首先,让我们从原始数据中创建一个虚拟的训练语料库和测试集。在我们的例子中,我们发现小测试集中包含的 25%的单词没有出现在我们有限的语料库中。~~~~~~~~~~~~因此,我们通过将这些看不见的单词添加到训练集中并对所有计数加 1 来应用拉普拉斯+1 *滑:~~~~~~~~~~~~![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/ea3cd6892a7082ab4adc4b86f70c1970.png)~~~~~~## ~~~~~~进一步的*滑方法~~~~~~~~~~~~拉普拉斯+1 *滑用于文本分类和零点数量不多的领域。然而,它并不经常用于 n-gramss,一些更好的 n-gram *滑方法有:~~~~~~*   ~~~~~~加法-k 拉普拉斯*滑~~~~~~
*   ~~~~~~好图灵~~~~~~
*   ~~~~~~肯泽内伊~~~~~~
*   ~~~~~~威滕-贝尔公司~~~~~~# ~~~~~~第 5 部分:选择要使用的语言模型~~~~~~~~~~~~我们已经介绍了前三种最小均方模型(一元模型、二元模型和三元模型),但是哪一种最好用呢?~~~~~~~~~~~~三元模型通常提供比二元模型更好的输出,二元模型提供比一元模型更好的输出,但是随着我们增加复杂性,计算时间变得越来越长。此外,当我们增加 n 时,可用的数据量减少(即,在 10-gram 中可用的下一个单词将比二元模型少得多)。~~~~~~# ~~~~~~后退方法~~~~~~~~~~~~如果有充分的证据,使用三元模型(或更高的 n 元模型),否则使用二元模型(或其他更简单的 n 元模型)。~~~~~~# ~~~~~~插入文字~~~~~~~~~~~~在插值中,我们使用 n 元模型的混合。~~~~~~## ~~~~~~简单插值:~~~~~~~~~~~~![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/f6428d02cfccebd90a154dce2f01706c.png)~~~~~~~~~~~~在哪里~~~~~~~~~~~~![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/e08e7325e090f1164d70242d71431ff3.png)~~~~~~~~~~~~为了计算 lambdas,使用语料库的保留子集并尝试参数,直到找到最大化保留数据概率的组合。~~~~~~## ~~~~~~小例子~~~~~~~~~~~~假设我们得到以下语料库:~~~~~~~~~~~~~~~~![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/353a5c5b3aee203b8755c70148de6db3.png)~~~~~~~~~~~~~~~~~~~~![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/1354258d8add08c764cc859b11e1cb64.png)~~~~~~~~~~## ~~~~~~~~~~IMDB 数据示例~~~~~~~~~~~~~~~~~~~~我们再次应用公式:~~~~~~~~~~~~~~~~~~~~![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/5c681f0d8e2596f6eb28c7090d6f2b3d.png)~~~~~~~~~~~~~~~~~~~~使用先前从 IMDB 源定义的语料库,我们将其中的一个小子集(10%)作为“保留”集。~~~~~~~~~~~~~~~~~~~~测试一系列可能的λ值(注意λ1 + λ2 = 1),我们发现如下:~~~~~~~~~~~~~~~~~~~~![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/df112906fe04e7166dafa18a97d4b90e.png)~~~~~~~~~~~~~~~~~~~~因此,本例的最佳λ值为:~~~~~~~~~~~~~~~~~~~~λ1 = 0~~~~~~~~~~~~~~~~~~~~λ2 = 1~~~~~~~~~~~~~~~~~~~~我希望这为您提供了一个不错的语言模型介绍,并且代码有助于您的学习。~~~~~~~~~~~~~~~~~~~~谢谢~~~~~~~~~~~~~~~~~~~~哲学(philosophy 的缩写)~~~~~~~~~~# 学习参数,第 0 部分:基本知识> 原文:<https://towardsdatascience.com/learning-parameters-part-0-5cfffd647bdc?source=collection_archive---------23----------------------->## 快速浏览一些对理解参数如何学习至关重要的基本内容。这是我写的关于学习参数的 5 部分系列的可选读物。在这篇文章中,你会发现一些基本的东西,你需要了解我的其他博客文章,关于深度神经网络如何更好地学习它们的参数。你可以点击这个帖子顶部的踢球者标签查看 ***学习参数*** 系列的所有帖子。我们将简要了解以下主题:1.  多元函数
2.  局部最小值与全局最小值
3.  理解梯度
4.  成本或损失函数
5.  等高线地图# 1.多元函数多变量函数就是其输入和/或输出由多个数字/变量组成的函数。例如 *f(x,y) = z= x + y .*![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/4ba6dd4e5733ff8b36b6e72e07fa8cb8.png)Fig1\. z = x² + y² graph by Google. **Image Source:** Google the equation.具有多个输出的函数也称为多变量函数,但它们在这里无关紧要。# 3.理解梯度术语“梯度”只是指多变量函数的导数的一种奇特方式。虽然可以为单变量函数定义导数,但对于多变量函数,梯度取而代之。梯度是向量值函数,而导数是标量值函数。单变量函数的导数,用***【f’【x】****或****df*/*dx****,*表示,告诉我们一个输入单位变化,函数值变化多少。但是如果一个函数有多个输入 ***x*** 和 ***y*** ,我们需要知道这个函数的值分别相对于 ***x*** 和 ***y*** 变化了多少,即, 当*x***y***保持不变时 ***f(x,y)*** 变化多少,以及当*y*保持不变时 ***x*** 变化多少。 这些被称为函数的*偏导数*通常分别用**∂*f*/*∂x****和****∂f*/∂y**表示当你把这两个无辜的标量放入一个向量中时,用∇ ***f*** 表示!********![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/081a5a27161a34bedc63609aa65d033c.png)*## *渐变的属性**还有很多属性,但让我们只关注两个必要的属性:**   *梯度指向函数增长最大的方向。*
*   *在局部最大值或局部最小值处为零(因为没有单一的增加方向)**第一个性质说,如果你想象站在 *f* 的输入空间中的一个点 *(x,y)* ,向量∇ *f* ( *x* , *y)* 告诉你应该向哪个方向行进才能最快速地增加 *f* 的值。这显然适用于 N 次方。当我第一次在学校了解到这一点时,并不清楚为什么会这样,但请查看 Khan Academy 上的这些[视频](https://www.khanacademy.org/math/multivariable-calculus/multivariable-derivatives#partial-derivative-and-gradient-articles)以了解更多信息。**为了理解第二个性质,我们需要直观地知道什么是导数。直线的导数是直线的斜率,曲线在任一点的导数是曲线在该点的切线的斜率。**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/8506eed70d6ccb2ea334fe51cf8e9b0f.png)****y(x)=x²-3x+3** with the tangent line through the point **(3,3)**. **Image Source:** [5]**对于两个变量的函数(一个曲面),在一个给定点有多条线与曲面相切。如果我们有一个足够好的函数,所有这些线形成一个*面,称为曲面在该点的切*面。**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/35bed436586b96d7008a6eed419cab86.png)**The tangent plane to the surface ***z=-x²-y²*** at the point **(0,2)**. **Image Source:** [5]**我相信你可以说服自己,这个*面在表面的最大值,即在表面的尖端,将*行于***XY***-*面,这表明切线的斜率最大为 0。如果不能,看下面。**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/57fdc8a8a928dafe5f82b5242500b0cf.png)**The tangent planes to the surfaces **z=-x²-y²** and **z=x²+y²** at their maximum and minimum respectively.*# *3.成本/损失函数**可以说,在训练神经网络时,你最想关心的价值是损失/成本。它衡量模型与数据拟合的“好”或“坏”程度。任何 GD like 算法的主要目标是找到产生最小成本的参数集。围绕参考文献的所有戏剧性事件,如“寻找最小值”、“在误差面上行走”,都只是在谈论以一种我们最终获得最小可能成本函数值的方式来调整参数。您可以将成本函数视为以模型权重为参数的多变量函数。试着不要想超过 2 个参数——你知道为什么!**有很多方法可以构建你的损失函数。不同类型的问题(分类和回归)可以有不同类型的损失函数,这些函数最好地代表了模型的性能,这是另一天,另一篇文章。目前,这种直觉足以理解故事的其余部分。你可以看 Siraj Raval 的这个视频[6]来了解更多关于损失函数的知识。*# *4.局部最小值与全局最小值**在图 1 中,你看到了多少个“最小值”?我只看到一个。多好啊!如果你的损失函数看起来像这样,你可以从图上的任何地方开始下降(我的意思是,不断改变你的参数),旁边有一个可靠的向导(咳咳梯度下降咳咳),很有可能你会在表面上那个甜美的深绿色点结束。太糟糕了,当优化最小的网络时,你最终会遇到的错误可能会更糟糕,从某种意义上来说,更可怕。**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/993e61a8fae43b86e5b182d3f7b2090a.png)**Fig2\. Not so friendly cost function eh? **Image Source:** [1]**在许多实际情况下,你要达到的最小值很大程度上取决于你开始下降的点。如果你在一个山谷附*开始下降,GD 算法肯定会强迫你进入那个山谷(局部最小值),但真正的最小值(全局最小值)可能在地表的其他地方。**看看两个最流行的神经网络的成本函数,VGG-56 和 VGG-110。**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/7ff42b2d74b22c6beb1aa00bc67145ed.png)**Fig3\. “Bumpier” and “scarier” cost functions of VGG-56 and VGG-110 networks. **Image Source:** [3]*> *停下来深思!!
> 你怎么可能用 3D 的方式来可视化一个“大”网络的成本函数?大型网络通常有数百万个参数,这怎么可能呢?阅读参考文献中链接的论文来找出答案。*# *5.轮廓**在三维空间中可视化有时会有点麻烦,等值线图是一种方便的替代方法,可以用二维输入和一维输出来表示函数。用图表解释比用文字解释更容易。**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/0439e778f9139c9a3f84bd3c6edb5233.png)**Fig4\. Step Wise Illustration Of Contour Mapping Process. **Images Taken From** [7]*## *等高线绘制过程****第一步:**从函数的图形开始。
**第二步:**用*行于输入*面的不同高度的*面,按规则的间隔将其切片。
**第三步:**在图上标出*面所经过的所有地方。
**第四步:**将标记投影到二维*面上,标注相应的*面高度,并相应地映射。*## *关键要点**   *等高线之间的小距离表示沿该方向的陡坡*
*   *等高线之间的大距离表示沿该方向的缓坡**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/b145b5efc017e4ea713e28de282c5267.png)**Fig5. **Image Source:** Wikipedia*## *测试你的理解能力**如果你仍然不能完全理解等高线地图的概念,那也没关系。您可以通过猜测以下等高线图的三维图(不看图 6 右栏中的解决方案)来测试您的理解。**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/1928bad9d2b018f4a2705ecbc1656b5f.png)**Fig6\. Test Your Understanding! **Image Source:** [8]**请阅读汗学院的这篇精彩文章[7]以了解更多关于等值线图的信息。**查看本系列的下一篇文章:**   *[学习参数,第一部分:梯度下降。](/learning-parameters-part-1-eb3e8bb9ffbb)*# *参考*1.  *[深度学习的难点](https://math.oregonstate.edu/home/programs/undergrad/CalculusQuestStudyGuides/vcalc/tangent/tangent.html),[雷扎·扎德](https://www.oreilly.com/people/4a99a-reza-zadeh)。*
2.  *[深度学习中的优化介绍:梯度下降](https://blog.paperspace.com/intro-to-optimization-in-deep-learning-gradient-descent/), [Ayoosh Kathuria](https://blog.paperspace.com/author/ayoosh/) 。*
3.  *[可视化神经网络的损失景观](https://www.cs.umd.edu/~tomg/projects/landscapes/),CS-UMD。*
4.  *[梯度下降优化算法概述](http://ruder.io/optimizing-gradient-descent/index.html),[塞巴斯蒂安·鲁德](http://ruder.io/)。*
5.  *[切面和全微分](https://math.oregonstate.edu/home/programs/undergrad/CalculusQuestStudyGuides/vcalc/tangent/tangent.html),俄勒冈州立大学。*
6.  *[损失函数解释](https://www.youtube.com/watch?v=IVVVjBSk9N0),Siraj Raval。*
7.  *[等高线图(篇)](https://www.khanacademy.org/math/multivariable-calculus/thinking-about-multivariable-function/ways-to-represent-multivariable-functions/a/contour-maps),可汗书院。*
8.  *[CS7015:深度学习,印度理工学院](https://www.cse.iitm.ac.in/~miteshk/CS7015.html),马德拉斯。*# 学习参数,第 1 部分:梯度下降> 原文:<https://towardsdatascience.com/learning-parameters-part-1-eb3e8bb9ffbb?source=collection_archive---------14----------------------->## [学习参数](https://towardsdatascience.com/tagged/learning-parameters)## 梯度下降是一种迭代优化算法,用于寻找函数的(局部)最小值。梯度下降是最优化中最流行的技术之一,非常常用于训练神经网络。给定基本微积分的正确背景,它是直观的和可解释的。看一看我的这篇博客文章— [第 0 部分](/learning-parameters-part-0-5cfffd647bdc),它涵盖了更好地理解这个系列所需的一些先决条件。你可以点击这个帖子顶部的标签查看 ***学习参数*** 系列的所有帖子。在这篇博文中,我们用一个玩具神经网络来建立梯度下降的动机。我们还从零开始推导梯度下降更新规则,并使用相同的玩具神经网络解释几何发生的事情。> 引用说明:本博客中的大部分内容和图表直接取自 IIT 马德拉斯大学教授 Mitesh Khapra 提供的深度学习课程第 5 讲。# 陈腐的比喻想象你站在一座山上,有很多可能的路径可供你下山。梯度下降(GD)简单来说就是给你一个下山的原则性方法。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/7db44f12dec87f6948353e9f08b85c29.png)全球动力局鼓励你首先找到一个方向,在这个方向上,山有最陡的上升,并要求你去完全相反的方向。你可能会说这个看似简单的想法并不总是有效。你是对的,GD 可以让你走得慢,即使是在*坦的地面上(当你可以跑的时候),但是我们会在文章的最后解决这个限制。# 动机以一个玩具为例,假设我们想要训练一个只有一个神经元的玩具神经网络。前提是:![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/2d522840b2c561f81d47082d045ed509.png)训练目标是找到使函数***L(w,b)*** 输出其最小值*的**和* ***b*** 的最佳组合。***![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/6346b24ac043c9dda78ac8b7293922a2.png)**现在,训练一个网络意味着什么?假设我们用( *x,y* ) *=* (0.5,0.2) 和(2.5,0.9)训练玩具网络,在训练结束时,我们期望找到*******和 ***b**** 使得 *f* (0.5)输出 0.2 和 *f* (2.5)我们希望看到一个 sigmoid 函数,使得(0.5,0.2)和(2.5,0.9)位于 sigmoid 上。*## *你永远不会做的暴力行为**我们能不能试着手动找到这样一个***w *******b ****?让我们试着随机猜测一下..(假设 w = 0.5,b = 0)**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/65a98fbd2cb5af3aee9007084e0fa8e0.png)**我们继续猜。我们走吧。**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/26d443237e7417a37a65084281681a28.png)*## *你永远不会做的事情的几何解释**我们能把猜测形象化吗?我们可以!由于我们只有 2 个点和 2 个参数 ***(w,b)*** ,我们可以很容易地为 ***(w,b)*** 的不同值绘制***【L(w,b)】***,并选择其中***【L(w,b)*** 最小的一个。**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/eeac649b1b5ebf715319b05b561ee3ec.png)**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/dbb4ebcbe8c400fe2c4fcad867ef6cea.png)**但是当然,一旦有了更多的数据点和更多的参数,这就变得棘手了!此外,这里我们只绘制了来自(6,6)的 ***(w,b)***的小范围误差表面,而不是来自(inf,inf)的误差表面。梯度下降救援!*# *梯度下降**如果还不清楚,手头的任务就是找到使损失函数最小的最佳参数组合。梯度下降为我们提供了一种遍历误差面的原则性方法,这样我们就可以快速达到最小值,而无需诉诸蛮力搜索。*## *推导梯度下降规则**合理的做法是随机初始化 ***w*** 和 ***b*** ,然后以**最佳方式**迭代更新它们,以达到我们最小化损失函数的目标。让我们用数学来定义它。**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/634fadea048f91012bade93a0ed6ab9f.png)**但是我们如何找到 *θ* 中最‘想要’的变化呢?什么是正确的**δ***θ*使用?答案来自于 [**泰勒级数**](http://fourier.eng.hmc.edu/e176/lectures/NM/node45.html) 。**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/fcc11e5bc64302558f3604d495b8acb5.png)**这意味着我们要移动的方向 *u* 或***δ***θ*应该与坡度成 180 度角。在损失面上的给定点,我们的移动方向与该点损失函数的梯度方向相反。这就是黄金梯度下降法则!!**## **权重/参数更新规则****![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/b1553cbf9f09d3f634f8465240c5ec6f.png)**## **算法****既然我们在 ***w-b*** *面上有了比我们的蛮力算法更有原则的移动方式。让我们根据这个规则创建一个算法…****![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/9e8207957ad3281c450bd230801b3301.png)**# **梯度下降在行动****为了在实践中看到 GD,我们首先必须为我们的玩具神经网络导出∇ ***w*** 和∇ ***b*** 。如果你算出来,你会看到它们如下:****![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/41171c6d6cff1532c4f98f7d8bcec5bc.png)**## **Python 代码**## **几何解释****让我们从误差面上的一个随机点开始,看看更新情况。****![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/ff599214be7e1dc6ff521d15b80cfe34.png)**# **限制****原始形式的梯度下降有一个明显的缺点。让我们看一个示例曲线 *f(x) = x + 1,*如下所示:****![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/115db4ff25e16f27260b0c1c6ef050af.png)***   **当曲线很陡时,梯度(∇y1/∇x1)很大。**
*   **当曲线*缓时(∇y2/∇x2)很小。****回想一下,我们的权重更新与梯度 ***w = w — η∇w*** *成正比。*因此,在曲线*缓的区域,更新较小,而在曲线陡峭的区域,更新较大。让我们看看当我们从曲面上的不同点开始时会发生什么。****![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/5f662f4c47fbfb4b66ac7ee00d08df35.png)****不管我们从哪里开始,一旦我们碰到一个缓坡的表面,前进的速度就会减慢。由于这个原因,训练方法可能永远无法收敛。**# **结论****在这篇博文中,我们用一个玩具神经网络来强调梯度下降的必要性。我们还从零开始推导梯度下降更新规则,并使用相同的玩具神经网络以几何方式解释每次更新发生的情况。我们还解决了 GD 的一个重要限制,在*缓区域减速的问题,以曲线图示的原始形式。*基于动量的梯度下降*通过让最*梯度更新的“动量”控制当前步骤中的更新幅度,在一定程度上克服了这个缺点。****请阅读本系列的下一篇文章,网址是:***   **[学习参数,第 2 部分:基于动量和内斯特罗夫加速梯度下降](/learning-parameters-part-2-a190bef2d12)**# **承认****非常感谢 IIT·马德拉斯教授的 [**和**](https://www.cse.iitm.ac.in/~miteshk/) **[**CS7015:深度学习**](https://www.cse.iitm.ac.in/~miteshk/CS7015.html) 课程的丰富内容和创造性的可视化。我只是简单地整理了提供的课堂讲稿和视频。******![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/31223c7659a9f173beddaf102e33c1b8.png)****Source: CS229 — Machine Learning Lecture Notes, Stanford University**# 学习参数,第 2 部分:基于动量和内斯特罗夫加速梯度下降> 原文:<https://towardsdatascience.com/learning-parameters-part-2-a190bef2d12?source=collection_archive---------9----------------------->## [学习参数](https://medium.com/tag/learning-parameters/latest)## 让我们看看梯度下降的两个简单但非常有用的变体。在这篇文章中,我们看看如何在一定程度上利用动量的概念来克服梯度下降的*缓表面的限制。如果你不清楚这是关于什么的,一定要看看我的博客文章——[学习参数,第一部分:梯度下降](/learning-parameters-part-1-eb3e8bb9ffbb)。在整篇博文中,我们都在解决第 1 部分中介绍的玩具问题。你可以点击这个帖子顶部的踢球者标签查看 ***学习参数*** 系列的所有帖子。在第 1 部分中,我们清楚地看到了一条曲线,在误差曲面的*缓区域,梯度可能很小,这可能会减慢速度。让我们看看什么样的动力可以克服这个缺点。> 引用说明:本博客中的大部分内容和图表直接取自 IIT 马德拉斯大学教授 Mitesh Khapra 提供的深度学习课程第 5 讲。# 基于动量的梯度下降从登山运动员的角度来看,MBGD 背后的直觉(是的,这是我们在第 1 部分中使用的老掉牙的比喻)是> 如果我被反复要求朝同一个方向前进,那么我可能应该获得一些信心,开始朝那个方向迈出更大的步伐。就像一个球滚下斜坡时获得动量一样。## 动量更新规则我们在梯度更新规则中容纳动量概念如下:![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/b8d8a0691b901f2927b1e614c0de36ae.png)除了当前的更新,我们还会查看更新的历史。我鼓励你花点时间来处理新的更新规则,并尝试将*更新*期限在每个步骤中的变化写在纸上。还是继续看。分解它,我们得到![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/c4e8fce34552a060f4b4ecbed8643aef.png)您可以看到,当前更新不仅与当前梯度成比例,还与先前步骤的梯度成比例,尽管它们的贡献在每个时间步骤减少***γ***(γ)*倍。这就是我们如何在*缓区域提高更新的幅度。*# *行动中的动力**我们将普通梯度下降代码(如第 1 部分所示&也可从[这里](https://gist.github.com/akshaychandra21/703ecc8949a01f472d17db3359d56985)获得)稍微修改如下:**从现在开始,我们将只使用等高线地图。将事物可视化为三维可能会很麻烦,因此等值线图可以作为一种便捷的替代方法来表示具有二维输入和一维输出的函数。如果你没有意识到它们/对它们感到不舒服,请阅读我的基本材料博客文章-[*学习参数,第 0 部分:基本材料*](http://asasasasas) 的**第 5 节**(甚至有一个自我测试,你可以更好地理解它们)。让我们看看 MBGD 使用我们在第 1 部分中介绍的相同的玩具神经网络有多有效。**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/d9633294da9e99ce48952b18b741d6e9.png)**Momentum-Based Gradient Descent. 100 iterations of vanilla gradient descent make the black patch.**它工作了。普通梯度下降的 100 次迭代形成黑色斑块,很明显,即使在缓坡区域,基于动量的梯度下降也可以迈出实质性的步伐,因为动量带着它前进。**重要的是,快速行动总是好的吗?会不会有这样一种情况,动量会导致我们超越目标?让我们通过改变我们的输入数据来测试 MBGD,这样我们最终得到一个不同的误差表面。**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/585334d8cf620fab32ab3638a5127199.png)**比如上面显示的这个,误差在最小值谷的两边都很高。在这种情况下,冲力还能发挥作用吗?或者相反,冲力可能是有害的?让我们找出答案。**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/1370c8eafa2a4219a24049b04e581a75.png)**100 iterations of vanilla gradient descent make the black patch.**我们可以观察到,以动量为基础的梯度下降,随着动量带着它离开极小值谷,在极小值谷内外振荡。这使得我们在最终收敛之前做了很多 U 形转弯。尽管有这些 U 形转弯,它仍然比普通梯度下降收敛得更快。在 100 次迭代之后,基于动量的方法已经达到 0.00001 的误差,而普通梯度下降仍然停留在 0.36 的误差。**我们能做些什么来减少振荡/U 形转弯吗?是的,内斯特罗夫加速梯度下降帮助我们做到了这一点。*# *内斯特罗夫加速梯度下降**NAG 背后的直觉可以用一句话来概括:*> *三思而后行!**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/aea1ecd389f763f9f8c568c30d299fdc.png)*## *NAG 更新规则**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/844f07cceb4da4737563bbe594f0546c.png)**但是为什么向前看能帮助我们避免过度呢?我敦促你们停下来思考一下。如果还不清楚,我相信几分钟后就会清楚了。看一下这个图。**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/659fec5826238d4f608639e85358d08a.png)**A toy illustration.**在图(a)中,更新 1 为正,即梯度为负,因为随着 ***w_0*** 增加 ***L*** 减少。甚至更新 2 也是积极的,你可以看到更新比更新 1 稍大,这要归功于动量。到目前为止,你应该确信更新 3 将比更新 1 和更新 2 更大,仅仅是因为动力和积极的更新历史。更新 4 是事情变得有趣的地方。在普通动量情况下,由于正历史,更新过冲,下降通过进行负更新来恢复。**但是在 NAG 的情况下,每次更新分两步进行——首先,部分更新,我们到达 *look_ahead* 点,然后是最终更新(参见 NAG 更新规则),参见图(b)。NAG 的前 3 次更新非常类似于基于动量的方法,因为在那些情况下两次更新(部分和最终)都是正的。但是真正的区别在 update 4 中变得很明显。通常,每次更新分两个阶段进行,部分更新(4a)为正,但最终更新(4b)将为负,因为在 ***w_lookahead*** 计算的梯度将为负(通过观察图表说服自己)。这个负的最终更新稍微降低了更新的总幅度,仍然导致过冲,但是与普通的基于动量的梯度下降相比,过冲较小。我的朋友,这就是 NAG 如何帮助我们减少超调,即让我们采取更短的 U 形转弯。*# *唠叨在行动**通过稍微更新 momentum 代码来进行部分更新和完全更新,我们得到了 NAG 的代码。**让我们用同样的玩具例子和同样的误差表面来比较基于动量的方法和 NAG 的收敛性。**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/23e835f9a3c90cd86ce0d87a31b565c0.png)**You can see that (I hope you can) NAG (blue) is taking smaller U-turns compared to vanilla momentum (red).**即使接*误差面上的极小值谷,NAG 肯定也在进行较小的振荡/较短的 U 形转弯。与基于动量的梯度下降相比,向前看有助于 NAG 更快地修正其路线。因此,振荡更小,逃离极小值谷的机会也更小。之前,我们证明了回顾过去有助于**咳咳动力咳咳** ,现在我们证明了展望未来也有帮助。*# *结论**在这篇博客文章中,我们看了两个简单的混合版本的梯度下降,帮助我们更快地收敛——*基于动量的梯度下降*和*内斯特罗夫加速梯度下降(NAG)* ,还讨论了 NAG 击败普通动量法的原因和位置。我们研究了它们的更新规则、方法的 python 代码实现中的细微差别,并在一个玩具示例中用图形展示了它们的收敛性。在下一篇文章中,我们将稍微偏离主题,谈谈这些算法的随机版本。**请阅读本系列的下一篇文章,网址是:**   *[学习参数,第 3 部分:随机&小批量梯度下降](/ee8558f65dd7)*# *承认**IIT·马德拉斯教授的[](https://www.cse.iitm.ac.in/~miteshk/)**和 [**CS7015:深度学习**](https://www.cse.iitm.ac.in/~miteshk/CS7015.html) 课程如此丰富的内容和创造性的可视化,这要归功于很多。我只是简单地整理了提供的课堂讲稿和视频。***# 学习参数,第 3 部分:随机和小批量梯度下降> 原文:<https://towardsdatascience.com/learning-parameters-part-3-ee8558f65dd7?source=collection_archive---------22----------------------->## [学习参数](https://medium.com/tag/learning-parameters/latest)## 让我们暂时离开优化器,谈谈这些算法的随机
版本。在第 2 部分中,我们看了梯度下降的两个有用的变体——基于动量的[和内斯特罗夫加速梯度下降](/learning-parameters-part-2-a190bef2d12)。在这篇文章中,我们将看看梯度下降的随机版本。你可以点击这个帖子顶部的踢球者标签查看 ***学习参数*** 系列的所有帖子。> 引用说明:本博客中的大部分内容和图表直接摘自 [CS7015:深度学习](https://www.cse.iitm.ac.in/~miteshk/CS7015.html)课程的第 5 讲,该课程由[IIT 马德拉斯大学的 Mitesh Khapra](https://www.cse.iitm.ac.in/~miteshk/) 教授讲授。# 动机让我们看看我们在本系列的第 1 部分中谈到的香草梯度下降。如果您观察两个奇怪注释行之间的代码块,您会注意到梯度是在整个数据集上计算的。也就是说,该算法在更新参数之前会对整个数据进行一次检查。为什么?因为这是前面第 1 部分中推导出的损失的真实梯度(对应于每个数据点的损失梯度的总和)。这是一件好事,因为我们没有逼*任何东西。因此,所有的理论假设和保证都成立(换句话说,每一步都保证损失会减少)。这是可取的吗?当然是,但是另一方面是什么?假设我们有一百万个训练数据点。对 ***w*** , ***b*** 进行 1 次更新,算法进行百万次计算。显然,这可能会非常慢!!我们能做得更好吗?是的,我们来看看随机梯度下降。# 随机梯度下降随机梯度下降(常简称为 SGD)是一种优化可微目标函数的迭代方法,是梯度下降优化的随机*似。基本上,你是在用某种*似,而不是高贵的“真实梯度”。随机梯度下降是用于训练深度学习模型的主要方法。让我们直接看看 SGD 的代码。事情是这样的——我们不是通过计算所有数据点的梯度来进行更新,而是一次只更新一个数据点的梯度。因此,名称随机,因为我们是估计总梯度的基础上,一个单一的数据点。几乎就像只扔一次硬币,然后估算 P(正面)。现在,如果我们有一百万个数据点,我们将在每个时期进行一百万次更新(1 个时期= 1 遍数据;1 步= 1 次更新)。另一面是什么?这是一个*似的(相当随机的)梯度,所以不能保证每一步都会减少损失。## SGD 在行动当我们有一些数据点时,让我们从几何角度来看这个算法。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/f441608773d7ffdf39fff55ca136ca9f.png)如果你仔细观察,你会发现我们的下降产生了许多微小的振荡。为什么?因为我们正在做出贪婪的决定。每个点都试图将参数推向对其最有利的方向(没有意识到这会如何影响其他点)。局部有利于一个点的参数更新可能会损害其他点(就好像数据点在相互竞争)。我们能否通过改进梯度的随机估计(目前一次仅从一个数据点进行估计)来减少振荡?是的,让我们看看小批量梯度下降。# 小批量梯度下降在小批量的情况下,我们不是一次更新一个数据点的梯度,而是计算一批大小为 k 的数据点的梯度。注意,该算法在看到*个 mini_batch_size* 个数据点后更新参数。随机估计现在应该稍微好一点了。## 小批量生产当*k*/*mini _ batch _ size*= 2 时,让我们看看这个算法是如何运行的。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/926b65421bacec7e078f1c31e1ed5818.png)即使批量大小为 *k=2,*振荡也略有减少。为什么?因为我们现在对梯度有了更好的估计(类比:我们现在投掷硬币 *k=2* 次来估计 P(正面))。k 值越高,估计就越精确。实际上,k 的典型值是 16、32、64。当然,仍然存在振荡,只要我们使用的是与“真实梯度”相对的*似梯度,振荡就会一直存在插图不清楚,而且最重要的是, *k* 仅仅是 2,所以很难看出有什么不同。但是相信数学,mini-batch 帮助我们得到稍微好一点的梯度估计。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/82296133bee5f9e2db5679217264c7b4.png)# 新币与动力和老马我们可以有基于动量的梯度下降和内斯特罗夫加速梯度下降的随机版本。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/ac12032ff6ddb45ef82cdc030087ed0c.png)虽然动量(红色)和 NAG(蓝色)的随机版本都表现出振荡,但 NAG 相对动量的优势仍然存在(即 NAG 的 u 形转弯相对较短)。此外,它们都比随机梯度下降更快(在 60 步之后,随机梯度下降[黑色左图]仍然表现出非常高的误差,而 NAG 和动量接*收敛)。当然,我们也可以有 Momentum 和 NAG 的小批量版本,但不在本文中。# 结论在学习参数系列的这一部分中,我们看了*似梯度更新的梯度下降算法的变体——随机梯度下降和小批量梯度下降。我们研究了它们之间的主要区别,这两种方法的 python 代码实现,并在一个玩具问题上用图形展示了它们的收敛性。我们还设想了动量和 NAG 的随机版本。在下一篇文章中,我们将讨论一些调整学习率和动量相关参数的有用技巧,并简要介绍什么是线搜索。请阅读本系列的下一篇文章,网址是:*   [学习参数,第 4 部分:调整学习率的技巧&动量,线搜索](/learning-parameters-part-4-6a18d1d3000b)# 承认IIT·马德拉斯教授的[](https://www.cse.iitm.ac.in/~miteshk/)**和 [**CS7015:深度学习**](https://www.cse.iitm.ac.in/~miteshk/CS7015.html) 课程如此丰富的内容和创造性的可视化,这要归功于很多。我只是简单地整理了提供的课堂讲稿和视频。****![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/03ac32e1d32aca2be7d0cd9f2a48ade0.png)**# 学习参数,第 4 部分:调整学习速度的技巧,线搜索> 原文:<https://towardsdatascience.com/learning-parameters-part-4-6a18d1d3000b?source=collection_archive---------20----------------------->## [学习参数](https://medium.com/tag/learning-parameters/latest)## 在进入高级优化算法之前,让我们回顾一下梯度下降中的学习率问题。在[第 3 部分](/learning-parameters-part-3-ee8558f65dd7)中,我们看到了优化器的随机性和小批量版本。在这篇文章中,我们将会看到一些关于如何调整学习率等的普遍遵循的启发法。如果你对这些试探法不感兴趣,可以直接跳到[学习参数](https://medium.com/tag/learning-parameters/latest)系列的[第 5 部分](/learning-parameters-part-5-65a2f3583f7d)。> 引用说明:本博客中的大部分内容和图表直接取自 IIT 马德拉斯大学教授 Mitesh Khapra 提供的深度学习课程第 5 讲。有人可能会说,我们可以通过设置较高的学习率来解决在缓坡上导航的问题(即,通过将较小的坡度乘以较大的学习率 ***η*** )来放大较小的坡度)。这个看似微不足道的想法有时在误差函数*缓的情况下确实有效,但当误差面*坦时就不起作用了。这里有一个例子:![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/d55609642b49918959624769367809ea.png)显然,在斜率较大的区域,已经很大的梯度会进一步扩大,较大的学习率在某种程度上有助于这一原因,但一旦误差表面变*,就没有太大帮助了。假设有一个可以适应梯度的学习率总是好的,这是安全的,我们将在学习参数系列的下一篇文章(第 5 部分)中看到一些这样的算法。# 一些有用的提示## 初学率小贴士*   调整学习率。在对数标度上尝试不同的值:0.0001、0.001、0.01、0.1、1.0。
*   每一个都运行几个时期,找出一个最有效的学习速率。
*   现在围绕这个值进行更精细的搜索。例如,如果最佳学习率是 0.1,那么现在尝试一些值:0.05,0.2,0.3。
*   声明:这些只是启发,没有明确的赢家策略。## 退火学习率提示**阶跃衰减***   每 5 个周期后将学习率减半
*   如果验证误差大于前一个时期结束时的误差,则在一个时期后将学习率减半**指数衰减***   *η = η₀⁻ᵏᵗ* ,其中 *η₀* 和 *k* 为超参数,t 为步数**1/t 衰变***   *η = (η₀)/(1+kt),*其中 *η₀* 和 *k* 为超参数,t 为步数。## 动量秘诀以下时间表由 Sutskever *等人*于 2013 年提出![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/7c78f923943ac86f2aee6f3c87e064f4.png)其中, *γ_max* 选自{0.999,0.995,0.99,0.9,0}。# 线搜索在实践中,通常进行线搜索以找到相对更好的 *η* 值。在线搜索中,我们使用不同的学习率( *η* )更新 *w* ,并在每次迭代中检查更新后的模型的误差。最终,我们保留给出最低损失的 *w* 的更新值。看一下代码:本质上,在每一步,我们都试图从可用的选项中使用最佳的 *η* 值。这显然不是最好的主意。我们在每一步都做了更多的计算,但这是寻找最佳学习速率的一种折衷。今天,有更酷的方法可以做到这一点。## 在线搜索正在进行![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/5a1cf474579bfe100a291988aee84ce5.png)显然,收敛比普通梯度下降更快(见[第 1 部分](/learning-parameters-part-1-eb3e8bb9ffbb?source=your_stories_page---------------------------))。我们看到一些振荡,但注意到这些振荡与我们在动量和 NAG 中看到的非常不同(见[第 2 部分](/learning-parameters-part-2-a190bef2d12))。**注:** Leslie N. Smith 在他 2015 年的论文中, [*循环学习率用于训练神经网络*](https://arxiv.org/pdf/1506.01186.pdf) 提出了一种比线搜索更聪明的方式。我建议读者参考[这篇由](/estimating-optimal-learning-rate-for-a-deep-neural-network-ce32f2556ce0) [Pavel Surmenok](https://towardsdatascience.com/@surmenok) 撰写的文章来了解更多信息。# 结论在学习参数系列的这一部分中,我们看到了一些启发,可以帮助我们调整学习速度和动力,以便更好地进行培训。我们还研究了线搜索,这是一种曾经流行的方法,用于在梯度更新的每一步找到最佳学习速率。在学习参数系列的下一(最后)部分,我们将仔细研究具有自适应学习速率的梯度下降,特别是以下优化器——AdaGrad、RMSProp 和 Adam。你可以在这里找到下一部分:*   [学习参数,第 5 部分:AdaGrad、RMSProp 和 Adam](/learning-parameters-part-5-65a2f3583f7d)# 承认IIT·马德拉斯教授的[](https://www.cse.iitm.ac.in/~miteshk/)**和 [**CS7015:深度学习**](https://www.cse.iitm.ac.in/~miteshk/CS7015.html) 课程如此丰富的内容和创造性的可视化,这要归功于很多。我只是简单地整理了提供的课堂讲稿和视频。****![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/76bca3209966c0bfa781d09c81a5c8a7.png)**# 学习参数,第 5 部分:AdaGrad、RMSProp 和 Adam> 原文:<https://towardsdatascience.com/learning-parameters-part-5-65a2f3583f7d?source=collection_archive---------4----------------------->## [学习参数](https://medium.com/tag/learning-parameters/latest)## 让我们看看具有自适应学习率的梯度下降。在[第四部分](/learning-parameters-part-4-6a18d1d3000b)中,我们看了一些启发法,可以帮助我们更好地调整学习速度和动力。在[系列](https://medium.com/tag/learning-parameters/latest)的最后一篇文章中,让我们来看看一种更有原则的调整学习速度的方法,并给学习速度一个适应的机会。> 引用说明:本博客中的大部分内容和图表直接取自 IIT 马德拉斯大学教授 Mitesh Khapra 提供的深度学习课程第 5 讲。## 适应性学习率的动机考虑以下具有 sigmoid 激活的简单感知器网络。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/b3e77107b518fc5facb8aa8df6dc2320.png)很容易看出,给定一个点( **x** , *y* ),梯度 **w** 如下:![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/dc736a735335ae2f4c68d83ec5078b06.png)See [Part-1](/learning-parameters-part-1-eb3e8bb9ffbb) if this is unclear.***【f(x)****w . r . t 的梯度到一个特定的权重显然依赖于其相应的输入。如果有 *n* 个点,我们可以将所有 *n* 个点的梯度相加得到总梯度。这条新闻既不新鲜也不特别。但是,如果特征 ***x2*** 非常稀疏(即,如果它的值对于大多数输入都是 0),会发生什么呢?假设∇ ***w2*** 对于大多数输入(见公式)将为 0 是合理的,因此 ***w2*** 将不会获得足够的更新。**不过,这有什么好困扰我们的呢?需要注意的是,如果***【x2】***既稀疏又重要,我们会认真对待 ***w2*** 的更新。为了确保即使在特定输入稀疏的情况下也能进行更新,我们是否可以为每个参数设定不同的学习速率,以考虑特征的频率?我们当然可以。我的意思是,这是这篇文章的全部要点。*# ***AdaGrad —自适应梯度算法***## *直觉**衰减参数的学习率与其更新历史成比例(更新越多,衰减越多)。*## *AdaGrad 的更新规则**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/2e32acecc9dfef78d72dcb5fc9046289.png)**从更新规则可以清楚地看出,梯度的历史累积在 ***v*** 中。累积的梯度越小,**T5【v值就会越小,导致学习率越大(因为**v除以 *η* )。*****## *阿达格拉德的 Python 代码*## *阿达格拉德在行动**要查看 AdaGrad 的运行情况,我们需要首先创建一些其中一个要素稀疏的数据。对于我们在学习参数系列的所有部分中使用的玩具网络,我们将如何做呢?嗯,我们的网络正好有两个参数( ***w*** 和 ***b*** ,参见 [part-1](/learning-parameters-part-1-eb3e8bb9ffbb) 中的*动机*)。这其中,b 对应的输入/特征是一直开着的,所以我们不能真的让它稀疏。所以唯一的选择就是让 x 稀疏。这就是为什么我们创建了 100 个随机的 *(x,y)* 对,然后大约 80%的这些对我们将 *x* 设置为 0,使得 ***w*** 的特征稀疏。**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/2b7a8c1f36a550b0ecfc54f9c5b3de26.png)**Vanilla GD(black), momentum (red), NAG (blue)**在我们实际查看运行中的 AdaGrad 之前,请查看上面的其他 3 个优化器——香草 GD(黑色)、momentum(红色)、NAG(蓝色)。这 3 个优化器为这个数据集做了一些有趣的事情。你能发现它吗?请随意停下来思考。**答:**最初,三种算法都是主要沿垂直( ***b*** )轴运动,沿水*( ***w*** )轴运动很少。为什么?因为在我们的数据中,对应于 ***w*** 的特征是稀疏的,因此 ***w*** 经历很少的更新。另一方面, ***b*** 非常密集,经历很多更新。这种稀疏性在包含 1000 个输入特征的大型神经网络中非常普遍,因此我们需要解决它。现在让我们来看看阿达格拉德的行动。**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/6552cdcbacfd5810986a889c01cb51bb.png)**瞧啊。通过使用参数特定的学习率,AdaGrad 确保尽管稀疏度*w 获得更高的学习率,并因此获得更大的更新。而且,这也保证了如果**b经历大量更新,其有效学习率会因为分母的增长而下降。实际上,如果我们从分母中去掉*方根,效果就不那么好了(这是值得思考的)。另一面是什么?随着时间的推移, ***b*** 的有效学习率将衰减到不再对 ***b*** 进行更新的程度。我们能避免这种情况吗?RMSProp 可以!****# **RMSProp — **均方根传播****## **直觉****AdaGrad 非常积极地降低学习率(随着分母的增长)。结果,一段时间后,由于学习率的衰减,频繁参数将开始接收非常小的更新。为了避免这种情况,为什么不衰减分母,防止其快速增长。**## **RMSProp 的更新规则****![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/c683c13895af3e2d1b7b03b16b4a1316.png)****一切都非常类似于阿达格拉德,除了现在我们也衰减分母。**## **RMSProp 的 Python 代码**## **RMSProp 正在运行****![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/a425e7f0f2f79723423c80d9e9e3388a.png)****Vanilla GD(black), momentum (red), NAG (blue), AdaGrad (magenta)****你看到了什么?RMSProp 和 AdaGrad 有什么不同?请随意停下来思考。**回答:**阿达格拉德在接*收敛的时候卡住了,因为学习率的衰减,已经无法在垂直( ***b*** )方向
移动。RMSProp 通过减少衰减来克服这个问题。**# **Adam — **自适应矩估计****## ****直觉******尽 RMSProp 所能解决 AdaGrad 的分母衰减问题。除此之外,使用梯度的累积历史。**## **更新 Adam 的规则****![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/b53268d38e4a10c45ee0a48b5ed300ae.png)****以及类似于***b****_ t*的一组方程组。注意,Adam 的更新规则与 RMSProp 非常相似,除了我们也查看梯度的累积历史(***m****_ t*)。注意,上面更新规则的第三步是偏差修正。Mitesh M Khapra 教授解释了为什么偏差校正是必要的,可在[这里](https://www.youtube.com/watch?v=-0ZMU-gnm2g)找到。**## **亚当的 Python 代码**## **亚当在行动****![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/53fa589dcd24ec832460fb9fe30d5b6a.png)****很明显,获取梯度的累积历史可以加快速度。对于这个玩具数据集,它似乎是超调(有点),但即使这样,它收敛的方式比其他优化。**# **百万美元问题:使用哪种算法?***   **亚当现在似乎或多或少是默认的选择( *β1* = 0.9, *β2* = 0.999,*ϵ*= 1e 8)。**
*   **虽然它被认为对初始学习速率是鲁棒的,但是我们已经观察到对于序列生成问题 *η* = 0.001,0.0001 工作得最好。**
*   **话虽如此,但许多论文报道,具有简单退火学习速率调度的动量(内斯特罗夫或经典)SGD 在实践中也运行良好(通常,序列生成问题从 *η* = 0.001 开始,0.0001)。**
*   **亚当可能是最好的选择。**
*   **最*的一些工作表明 Adam 存在问题,在某些情况下它不会收敛。**# **结论****在本系列的最后一篇文章中,我们研究了具有自适应学习速率的梯度下降如何帮助加快神经网络的收敛。本文涵盖了直觉、python 代码和三个广泛使用的优化器的可视化说明——AdaGrad、RMSProp 和 Adam。Adam 结合了 RMSProp 和 AdaGrad 的最佳特性,即使在有噪声或稀疏的数据集上也能很好地工作。**# **承认****IIT·马德拉斯教授的 [**和**](https://www.cse.iitm.ac.in/~miteshk/) **[**CS7015:深度学习**](https://www.cse.iitm.ac.in/~miteshk/CS7015.html) 课程如此丰富的内容和创造性的可视化,这要归功于 Mitesh M Khapra** 教授和助教。我只是简单地整理了提供的课堂讲稿和视频。****![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/000199b8e4919d7f7011bd2f6a551f3e.png)******Source:** Paperspace article on RMSProp by [Ayoosh Kathuria](https://blog.paperspace.com/intro-to-optimization-momentum-rmsprop-adam/).**# 学习强化学习:用 PyTorch 强化!> 原文:<https://towardsdatascience.com/learning-reinforcement-learning-reinforce-with-pytorch-5e8ad7fc7da0?source=collection_archive---------5----------------------->## 策略梯度入门![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/8d44a9531a33686b35abcb9b595dfb9e.png)Photo by [Nikita Vantorin](https://unsplash.com/@vantorin?utm_source=medium&utm_medium=referral) on [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral)强化算法是强化学习中最早的*策略梯度*算法之一,也是进入更高级方法的一个很好的起点。策略梯度不同于 Q 值算法,因为 PG 试图学习参数化的策略,而不是估计状态-动作对的 Q 值。因此,策略输出被表示为动作的概率分布,而不是一组 Q 值估计。如果有任何困惑或不清楚的地方,不要担心,我们会一步一步地分解它!# TL;速度三角形定位法(dead reckoning)在这篇文章中,我们将看看加强算法,并使用 OpenAI 的 CartPole 环境和 PyTorch 对其进行测试。我们假设对强化学习有一个基本的理解,所以如果你不知道状态、动作、环境等是什么意思,在这里查看一些[到其他文章的链接](https://www.datahubbs.com/reinforcement-learning/)或者在这里查看关于这个主题的[简单入门](https://www.datahubbs.com/intro-to-q-learning/)。# 政策与行动价值观我们可以将策略梯度算法与 Q 值方法(例如,深度 Q 网络)区分开来,因为策略梯度在不参考动作值的情况下进行动作选择。一些策略梯度学习值的估计以帮助找到更好的策略,但是这个值估计不是选择动作所必需的。DQN 的输出将是价值估计的向量,而政策梯度的输出将是行动的概率分布。例如,假设我们有两个网络,一个政策网络和一个 DQN 网络,它们已经学会了用两个动作(左和右)做横翻筋斗的任务。如果我们将状态 *s* 传递给每一个,我们可能会从 DQN 得到以下内容:![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/607675979a39547a9589b0729aa223e0.png)这来自政策梯度:![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/2fc3e86cee1b77ca4e8850c94e8b06e6.png)DQN 为我们提供了该州未来奖励折扣的估计值,我们基于这些值进行选择(通常根据一些ϵ-greedy 规则取最大值)。另一方面,政策梯度给了我们行动的概率。在这种情况下,我们做出选择的方式是在 28%的情况下选择行动 0,在 72%的情况下选择行动 1。随着网络获得更多的经验,这些概率将会改变。# 概率值为了得到这些概率,我们在输出层使用了一个简单的函数叫做 *softmax* 。该函数如下所示:![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/a138047fd1b7912ec809aa85cdbd468d.png)这将所有值压缩到 0 和 1 之间,并确保所有输出总和为 1(σσ(x)= 1)。因为我们使用 exp(x)函数来缩放我们的值,所以最大的值往往占主导地位,并获得更多分配给它们的概率。# 强化算法现在谈谈算法本身。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/f4e5757f3d9606598de45dc2dc9661aa.png)如果你已经关注了[之前的一些帖子,](https://www.datahubbs.com/reinforce-with-pytorch/)这看起来应该不会太令人生畏。然而,为了清楚起见,我们还是要走一遍。要求相当简单,我们需要一个可区分的策略,为此我们可以使用一个神经网络,以及一些超参数,如我们的步长(α)、折扣率(γ)、批量(K)和最大集数(N)。从那里,我们初始化我们的网络,并运行我们的剧集。每集之后,我们会对我们的奖励进行折扣,这是从该奖励开始的所有折扣奖励的总和。我们将在每一批(例如 K 集)完成后更新我们的政策。这有助于为训练提供稳定性。保单损失(L(θ))起初看起来有点复杂,但如果仔细观察,不难理解。回想一下,策略网络的输出是一个概率分布。我们对π(a | s,θ)所做的,只是得到我们网络在每个状态下的概率估计。然后,我们将其乘以折扣奖励的总和(G ),得到网络的期望值。例如,假设我们处于状态 *s* 网络分为两个行动,那么选择 a=0 的概率是 50%,选择 a=1 的概率也是 50%。网络随机选择 a=0,我们得到 1 的奖励,剧集结束(假设贴现因子为 1)。当我们回过头来更新我们的网络时,这个状态-动作对给我们(1)(0.5)=0.5,这转化为在该状态下采取的动作的网络期望值。从这里,我们取概率的[对数,并对我们这一批剧集中的所有步骤求和。最后,我们将其*均,并采用该值的梯度进行更新。](https://stats.stackexchange.com/questions/174481/why-to-optimize-max-log-probability-instead-of-probability)快速复习一下,[推车杆](https://gym.openai.com/envs/CartPole-v0/)的目标是尽可能长时间地保持杆在空中。您的代理需要决定是向左还是向右推购物车,以保持*衡,同时不要越过左右两边的边缘。如果你还没有安装 OpenAI 的库,只要运行`pip install gym`就应该设置好了。此外,如果你还没有的话,请抓住 pytorch.org 的最新消息。继续并导入一些包:```
import numpy as np
import matplotlib.pyplot as plt
import gym
import sysimport torch
from torch import nn
from torch import optimprint("PyTorch:\t{}".format(torch.__version__))PyTorch:	1.1.0
```# PyTorch 中的实现导入我们的包后,我们将建立一个名为`policy_estimator`的简单类,它将包含我们的神经网络。它将有两个隐藏层,具有 ReLU 激活功能和 softmax 输出。我们还将为它提供一个名为 predict 的方法,使我们能够在网络中向前传递。```
class policy_estimator():def __init__(self, env):self.n_inputs = env.observation_space.shape[0]self.n_outputs = env.action_space.n# Define networkself.network = nn.Sequential(nn.Linear(self.n_inputs, 16), nn.ReLU(), nn.Linear(16, self.n_outputs),nn.Softmax(dim=-1))def predict(self, state):action_probs = self.network(torch.FloatTensor(state))return action_probs
```请注意,调用`predict`方法需要我们将状态转换成一个`FloatTensor`,供 PyTorch 使用。实际上,`predict`方法本身在 PyTorch 中有些多余,因为张量可以直接传递给我们的`network`来得到结果,但是为了清楚起见,我把它包含在这里。我们需要的另一件事是我们的贴现函数,根据我们使用的贴现因子γ来贴现未来的奖励。```
def discount_rewards(rewards, gamma=0.99):r = np.array([gamma**i * rewards[i] for i in range(len(rewards))])# Reverse the array direction for cumsum and then# revert back to the original orderr = r[::-1].cumsum()[::-1]return r — r.mean()
```我在这里做了一件有点不标准的事情,就是减去最后奖励的*均值。这有助于稳定学习,特别是在这种情况下,所有奖励都是正的,因为与奖励没有像这样标准化相比,负奖励或低于*均水*的奖励的梯度变化更大。现在谈谈增强算法本身。```
def reinforce(env, policy_estimator, num_episodes=2000,batch_size=10, gamma=0.99): # Set up lists to hold resultstotal_rewards = []batch_rewards = []batch_actions = []batch_states = []batch_counter = 1# Define optimizeroptimizer = optim.Adam(policy_estimator.network.parameters(), lr=0.01)action_space = np.arange(env.action_space.n)ep = 0while ep < num_episodes:s_0 = env.reset()states = []rewards = []actions = []done = Falsewhile done == False:# Get actions and convert to numpy arrayaction_probs = policy_estimator.predict(s_0).detach().numpy()action = np.random.choice(action_space, p=action_probs)s_1, r, done, _ = env.step(action)states.append(s_0)rewards.append(r)actions.append(action)s_0 = s_1# If done, batch dataif done:batch_rewards.extend(discount_rewards(rewards, gamma))batch_states.extend(states)batch_actions.extend(actions)batch_counter += 1total_rewards.append(sum(rewards))# If batch is complete, update networkif batch_counter == batch_size:optimizer.zero_grad()state_tensor = torch.FloatTensor(batch_states)reward_tensor = torch.FloatTensor(batch_rewards)# Actions are used as indices, must be # LongTensoraction_tensor = torch.LongTensor(batch_actions)# Calculate losslogprob = torch.log(policy_estimator.predict(state_tensor))selected_logprobs = reward_tensor * \  torch.gather(logprob, 1, action_tensor).squeeze()loss = -selected_logprobs.mean()# Calculate gradientsloss.backward()# Apply gradientsoptimizer.step()batch_rewards = []batch_actions = []batch_states = []batch_counter = 1avg_rewards = np.mean(total_rewards[-100:])# Print running averageprint("\rEp: {} Average of last 100:" +   "{:.2f}".format(ep + 1, avg_rewards), end="")ep += 1return total_rewards
```对于算法,我们传递我们的`policy_estimator`和`env`对象,设置一些超参数,然后我们就可以开始了。关于实现的几点,在将值传递给`env.step()`或像`np.random.choice()`这样的函数之前,一定要确保将 PyTorch 的输出转换回 NumPy 数组,以避免错误。此外,我们使用`torch.gather()`将实际采取的行动与行动概率分开,以确保我们如上所述正确计算损失函数。最后,你可以改变结局,让算法在环境一旦“解出”就停止运行,而不是运行预设的步数(连续 100 集*均得分 195 分以上就解出 CartPole)。要运行这个程序,我们只需要几行代码就可以完成。```
env = gym.make('CartPole-v0')
policy_est = policy_estimator(env)
rewards = reinforce(env, policy_est)
```绘制结果,我们可以看到它工作得相当好!![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/f9c82d1b8379cba84eeee96f69234403.png)即使是简单的策略梯度算法也可以很好地工作,并且它们比 DQN 算法的负担更少,后者通常采用像记忆回放这样的附加功能来有效地学习。看看您可以在更具挑战性的环境中使用该算法做些什么!# 学习 SQL 201:优化查询,不考虑*台> 原文:<https://towardsdatascience.com/learning-sql-201-optimizing-queries-regardless-of-platform-918a3af9c8b1?source=collection_archive---------1----------------------->## TL;博士:磁盘太慢了。网络更差。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/7c91bb8fa44fc7cae57e5e55622045b3.png)It’s hard to find a photo that says “optimization” okay? (Photo credit: Randy Au)*警告:在撰写本文时,我已经在生产环境中使用了以下类似数据库的系统:MySQL、PostgreSQL、Hive、Hadoop 上的 MapReduce、AWS Redshift、GCP BigQuery,以及各种本地/混合/云设置。我的优化知识很大程度上来源于这些。在这里,我将坚持策略/思维过程,但是在其他流行的数据库中肯定有我不熟悉的特性和怪癖,尤其是 SQL Server 和 Oracle。*这篇文章是关于速度,让事情进行得更快的通用策略,同时避免具体的实现细节。我是想表达优化的思维过程,而不是具体的机制。在我知道它之前,它已经变成了一篇文章的怪物。有很多要讲的!# 简介和背景优化查询是一个很难写的主题,因为它涉及到细节。关于数据库引擎、软件,有时甚至是硬件和网络架构的细节。我多次被要求写关于这个主题的文章,我总是拒绝,因为我找不到一种方法来写一篇普遍有用的文章,来讨论一些很快就会被遗忘的东西。有[整本](https://www.amazon.com/dp/0071782796) [的书](https://www.amazon.com/dp/0596101716) [写的](https://www.amazon.com/dp/1785284339)关于如何优化不同的数据库系统,其中包括查询,但也包括系统本身调优的细节。他们总是写一个特定的[*台,而不是一般的*台。这是有充分理由的——每个*台都是不同的,您需要的调优参数取决于您的工作负载和设置(写密集型与读密集型、固态硬盘与旋转磁盘等)。](https://hortonworks.com/blog/5-ways-make-hive-queries-run-faster/)但是在一次令人讨厌的热浪中,在回家的路上,我突然有了一个关于线程将优化联系在一起的想法。所以我试着写这篇疯狂的文章。我将避免过多的细节,而将重点放在核心的思考过程上,这一过程将使您的查询进行得更快。出于说明的目的,将会涉及一些细节,没有真正的代码示例。同样为了简洁起见,我不能说得太详细,但是我会边走边链接例子和进一步的阅读。*注意:在整篇文章中,我将使用“数据库/DB”这一术语来表示各种各样的数据存储,这些数据存储具有完全不同的后端架构,但呈现类似 SQL 的接口。它们可能是传统的 SQL 数据库,如 MySQL/PostgreSQL,或者基于 Hadoop 的 NoSQL 商店,或者是 NewSQL 数据库,如 CockaroachDB。*# 查询优化是指计算机在查询时做更少的工作让您的查询更快归结为让您的查询做更少的工作来获得相同的结果。有许多不同的策略来实现这个目标,并且需要技术知识来知道采用哪种策略。做更少的工作意味着理解两件事:*   知道你的数据库在做什么
*   知道如何调整你命令数据库做的事情,减少工作量实现这一目标的途径在很大程度上取决于您工作的具体技术环境。优化 Hive 查询在某些方面与优化 PostgreSQL 查询截然相反。事实上,一些加快一个查询策略实际上会减慢另一个查询策略。当“优化查询”时,您实际上正在做的是找到使您的查询工作负载与您的系统的硬件和算法限制很好地配合的方法。这意味着你对硬件、软件和系统特性越熟悉,你就会做得越好。这也是为什么这个话题如此难教,你不能把它当作一种 SQL 风格的问题。“规则”只是指导方针,经常有反例。你也不能忽视系统的基本实现——尽管供应商会告诉你不必担心实现,但它很重要。这是我们今天要讲的要点列表,从数据库开始,向外扩展。为了您的方便,它有链接跳转。*   [查询计划](#0b55)
*   [索引和提示](#7f1b)
*   [磁盘写入](#6a30)
*   [子查询](http://86c2)
*   [临时表](#03e5)
*   [网络](#b554)
*   [CPU 使用率和算法](#8d49)
*   [【架空】](#015b)
*   [争用](#3d2b)
*   [$$$](#7533)我可能漏掉了一些案例(你可以随时评论并告诉我我错过的事情),但这些都是我能想到的大案例。让我们开始吧。# 查看查询计划当谈到互联网上关于优化 SQL 查询的博客帖子时,使用 EXPLAIN 通常是你听到的第一件事(有时是唯一的事……)。EXPLAIN 是从数据库中调用查询执行计划的 SQL 方式。它是数据库给你一个关于它如何计划执行你的查询的报告——它将描述它正在使用的任何索引、表连接的顺序、它是否将扫描整个表,有时甚至它在执行操作时期望查看多少行(基数)。这个想法是,如果您可以访问这个计划,您应该能够找出(以某种方式)如何使您的查询更快。令人沮丧的是,人们通常不会告诉你该怎么做。## 你在寻找工作的迹象学习如何阅读乍一看像是胡言乱语的查询执行计划需要练习和耐心。更糟糕的是,执行计划看起来没有标准。每个数据库都有很大的不同。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/535d5160c1a516dd8e30e9d973f5e950.png)An example MySQL EXPLAIN (src: [https://www.eversql.com/mysql-explain-example-explaining-mysql-explain-using-stackoverflow-data/](https://www.eversql.com/mysql-explain-example-explaining-mysql-explain-using-stackoverflow-data/))![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/079725ac78da445205a4e58fe3f7f4e2.png)An example PostgreSQL EXPLAIN (src: [https://thoughtbot.com/blog/reading-an-explain-analyze-query-plan](https://thoughtbot.com/blog/reading-an-explain-analyze-query-plan))对于您使用的每个数据库,您都必须重新学习这项技能。您还必须了解怪癖在哪里(就像有时 MySQL 解释说基数错误,它被误导了,因为它对索引做了奇怪的假设)。不管您使用的是什么数据库,您都在寻找数据库做大量工作和花费大量时间的地方。然后你看看能不能想办法减少。请查阅特定数据库的文档,以了解每个语句的确切含义。## 工作的迹象*   表扫描—数据库读取表中的每一个条目,产生大量磁盘使用(这很慢)
*   高基数操作——无论是否使用了索引,当数据库必须处理大量的行时,这又意味着使用更多的磁盘和内存,并且需要花费时间来完成所有这些操作
*   对大量记录执行类似循环的操作——比如相关子查询,其中数据库必须为一组行执行单独的子查询,这很像一般编程中的 for 循环。
*   由于内存限制而写入磁盘——在 [RDBMS](https://dev.mysql.com/doc/refman/5.7/en/internal-temporary-tables.html) [和](https://www.citusdata.com/blog/2018/06/12/configuring-work-mem-on-postgres/) [Hadoop](https://stackoverflow.com/questions/8504611/should-spilled-records-always-be-equal-to-mapinput-records-or-mapoutput-records) 系统中都会发现这种情况,当某个东西变得太大而无法在内存中处理时,它必须将其工作写入磁盘才能继续运行而不会崩溃
*   使用网络——尤其是对于几乎需要网络流量的分布式系统,相比之下,它使磁盘看起来更快。## “磁盘”确实经常出现希望你注意到“磁盘”这个词的出现。因为一般来说,磁盘访问是非常慢的,并且是你想要最小化的。即使固态硬盘比旋转硬盘快,它们仍然比 RAM 慢几个数量级。这就是为什么优化的第一部分通常包括寻找尽可能避免使用磁盘的方法,以及在别无选择的情况下有效使用磁盘的方法。## 侧栏:各种组件的速度![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/d0484d4bbc5868f23c0967468cbfd592.png)Comparison of access latency, data and scaling from [https://www.prowesscorp.com/computer-latency-at-a-human-scale/](https://www.prowesscorp.com/computer-latency-at-a-human-scale/)如果你看一下 CPU 和 RAM 速度与 SSD/HDD/网络操作的比较,你就会明白为什么。RAM 访问比 CPU/L1/L2 慢 3 个数量级。永久内存模块,本质上是位于 DRAM 总线而不是 SATA 或 SAS 总线上的固态硬盘,仍然比标准 RAM 慢大约 3 倍。一个更典型的 SSD,我们会认为是一个比 RAM 慢 2-3 个数量级的磁盘,旋转磁盘以毫秒为单位:比 RAM 慢 4 个数量级。根据条件和光速的不同,网络在 5-6 个数量级时甚至更差。[【返回主题列表】](#635a)# 减少工作量:索引在“减少工作”的背景下,希望你能明白为什么索引出现得如此频繁。索引本质上是一个预先计算的数据映射,更重要的是,它告诉数据库在磁盘上的什么位置可以找到某些条目。这意味着您不必扫描整个表来搜索所有内容。全表扫描会变得非常昂贵,因为:1.  你正在阅读大量可能与你无关的数据(白费力气)
2.  您可能正在使用旋转磁盘,这种磁盘具有非常慢的随机存取特性(固态硬盘可以大大改善这一点),并且
3.  数据库文件可能会在整个驱动器上被分割,这使得寻道惩罚更加严重(固态硬盘肯定有助于这一点)。但是,深入研究索引,您仍然需要知道您的特定数据库如何使用索引。例如,从版本 8 开始,PostgreSQL 已经能够通过[位图扫描](https://www.postgresql.org/docs/8.3/indexes-bitmap-scans.html)同时使用多个索引。与此同时,MySQL,即使在他们的版本 8 中,[在默认的 InnoDB 存储引擎中只有 HASH 和 B-tree 索引](https://dev.mysql.com/doc/refman/8.0/en/index-btree-hash.html),不能将索引组合在一起。了解这些繁琐的细节对于优化来说是非常重要的。在 MySQL 中,如果您想在一个索引查询中使用两列或更多列,您必须使用这些列构建一个特定的多列索引,并且顺序很重要。*索引(A,B)!= index(B,A)* 。如果您有 *index(A,B)* ,但是需要快速访问 B,您至少需要一个单独的 *index(B)* 。与此同时,在 PostgreSQL 中,更常见和更受欢迎的做法是只使用单独的索引:index(A)和 index(B ),因为它可以通过位图扫描自动使用 AND/OR 逻辑动态地组合 A 和 B。您可以构建一个多列的索引(A,B) ,这样会更有效,但是您已经通过两个单独的索引获得了很多好处。此外,如果您稍后需要您想要编写的*索引(C)* 和*索引(D)* ,它的伸缩性会更好。## 针对您的用例使用正确的索引类型大多数数据库引擎在定义索引时会提供多种索引算法供您使用。缺省值通常是 B 树的某种变体,它适用于大量典型的数据库用例。但是您经常会发现像用于空间数据库的 R/radix 树,或者散列和全文索引这样的东西。有时,对于更具体的用例,甚至有更深奥的东西可用。不管它是什么,使用最适合您的特定用例的,使用错误的会适得其反。## 索引提示有时您有一个索引,但是由于某种原因查询计划没有使用它。MySQL 经常因其相当愚蠢的查询优化器而被取笑,因此许多高级用户使用了大量的[索引提示](https://dev.mysql.com/doc/refman/8.0/en/index-hints.html),特别是**force index(*idx*)**和 **straight_join,**来强制优化器做正确的事情。经常发生的情况是,优化器认为忽略并索引和扫描一个表会更有效,因为它对正在操作的一个表的基数估计不正确。同时,在 PostgreSQL 中,[索引提示实际上并不是一件事](https://stackoverflow.com/questions/309786/how-do-i-force-postgres-to-use-a-particular-index)。由于索引提示本质上是对某些表的基数的攻击,随着数据库的不断变化,它们很容易过时。相反,开发人员强迫您依赖他们的查询优化器。谢天谢地,优化器犯的错误比 MySQL 少,所以它不像听起来那么疯狂,尽管您偶尔会遇到难以克服的边缘情况。不是每个数据库都有索引,许多运行 Hadoop 的东西,比如 Hive 和 Spark,没有这个概念,因为底层的 HDFS 系统只是一个大型文件的分布式存储系统,工具只是数据处理器。您可以使用文件结构(最常见的是使用年/月/日)人工创建类似于索引的东西,但是您必须自己维护它。希望上面的例子也能向你说明,你擅长优化意味着非常熟悉你正在使用的特定工具。[【返回主题列表】](#635a)# 减少工作量:磁盘写入索引在很大程度上是从磁盘上读取内容。当数据进入时,您需要支付预先计算的成本来维护索引,但是读取索引变得更快。那么,如何管理磁盘写入呢?—等一下。你会问,当我们在做选择操作时,为什么还要讨论写入磁盘呢?选择不主要是一个阅读操作吗?遗憾的是,选择不仅仅是读取数据,因为有时需要写入磁盘来完成操作。最简单的例子是 Hadoop,MapReduce 过程中的每一步都涉及到将数据写到磁盘,以便它可以传输到下一步(参见[这里的执行概述](/a-mapreduce-overview-6f2d64d8d0e6))。另一个相当常见的场景是当您处理大型数据集时,结果集不适合进程的主内存。然后,数据库必须将内容转储到磁盘(无论是通过操作系统交换还是显式转储到文件)才能继续工作。当一个在小数据集上运行耗时 5 秒的查询在稍大的数据集上却要花 5000 秒时,您会经常注意到这一点。您需要参考特定的数据库文档,以确定如何判断您的数据库是否正在写入磁盘,但是当您发现它正在发生时,它通常是优化的候选对象。## 一次使用较少的数据在任何系统中,最小化磁盘写入的唯一通用方法是减少您在任何给定时间处理的数据量。这将减少你被迫离开高速内存并掉进磁盘的机会。即使在必须放到磁盘上的情况下,您至少可以写得更少。您还应该警惕增加行数的操作,也就是将一行数据连接到多行数据的连接。如果您给数据库一些条件,您的数据库可能会进行优化以过滤掉一个巨大的交叉连接,但是如果您一开始就不给它一些条件,您可能会创建一些巨大的数据集。这在分布式数据系统(如 Hadoop)上变得更加重要,集群中的单个工作节点在某些时候需要将状态和中间结果传输到其他工作节点以继续工作,并且**网络流量甚至比旋转磁盘还要慢。**您希望尽可能地减少这种情况,同样是通过限制您在任一时间点处理的数据量。[【返回话题列表】](#635a)# 兼职工作:子查询子查询可以有效地在数据库中创建一个临时结果表,该表只在查询期间有效。我在这里汇总的一个相关特性是通用表表达式(CTE ),它本质上是一个具有更好语法的命名子查询,可以在一个查询中多次使用,而无需重复执行。子查询是有趣的生物。它们可能会使事情变得更快或更慢,你必须努力思考和实验,看看它们是否适合用作优化。关于子查询要知道的是,它们通常是驻留在内存中的**未索引的**临时表状结构。 [PostgreSQL](https://medium.com/@hakibenita/be-careful-with-cte-in-postgresql-fca5e24d2119) 不会,但是 MySQL“可能”[尝试用散列索引](https://dev.mysql.com/doc/refman/5.6/en/subquery-materialization.html)具体化子查询。从技术上来说,Hive 和 Spark 中的子查询也是无索引的,但是索引在这些系统中并不是一件真正的事情,所以这一点有点争议。它只是内存中的一堆行或一个慢慢溢出到磁盘的表。(又是那个词,明白我的意思了吗?)[CTE/](https://paquier.xyz/postgresql-2/postgres-12-with-materialize/) 物化视图还可以阻止优化器利用子查询和主查询之间的索引关系,就像数据库无法跨越的优化栅栏。这可能是你想要的,也可能不是。使子查询成为潜在优化的部分是当使用它们过滤数据源的成本低于使用原始数据源的成本时。1K 行的表扫描可能比扫描 1M 行索引更便宜。您在 Hadoop 生态系统中尤其会看到这一点,因为没有索引,而且 MapReduce 总是会溢出到磁盘。一个写得好的子查询可以过滤掉一个数据集,并减少整个查询过程中的后续操作。这也是为什么您更喜欢在 MapReduce 作业的早期使用这些操作,因为您需要为每一步付出磁盘和网络成本。同时,在关系数据库中,使用现有索引通常比使用无索引的临时结构更有效。如果子查询太大以至于必须转到磁盘,情况就更糟了。所以你会更小心地使用它们,并且在使用时尽量保持它们的尺寸较小。[【返回主题列表】](#635a)# 减少低效/重复性工作:临时表格继续关于子查询的讨论,如果子查询是不可避免的,但是非常慢,该怎么办?您还可以尝试进一步优化—使用带索引的临时表。请记住,子查询的主要缺陷是它们(大部分)没有被索引。如果我们能给它们加上一个指数,我们就成了黄金。解决这个问题的方法是制作一个临时表,把你需要的索引放在上面。然后我们将有一个合适的索引(通常是 B 树或类似的),它支持我们想要的许多比较操作符。构建临时表的另一个潜在优势是,它离成为永久表只差一个关键字。创建表与创建临时表。如果您打算跨事务多次重用该结构,那么这是值得的。但是有什么问题呢?使用临时表的成本是多少?一个是简单的权限,您需要能够运行创建命令,但可能没有该级别的访问权限。这可能是一个服务器安全性/可靠性问题,尤其是在生产环境中。第二个缺点是,一旦系统中有了这个中间表,就必须维护它,使它不会过时。随着人们开始依赖该表,您可能需要维护它,或者更频繁地更新它。这都是开销和开发时间。最后,因为您正在创建一个表,所以您是*显式地*写入磁盘。我已经反复强调这是一个缓慢的操作,你不想重复做。您的 DB 可以选择在内存中而不是磁盘中创建临时表,但是如果它变得太大,您就要返回到磁盘。因此,您只希望在已经准备写入磁盘的情况下使用这个选项,这样写入磁盘和创建索引的成本基本上可以忽略不计。如果您打算多次重复使用该表,也可以这样做,这样做一次比重复使用花费更少。[【返回话题列表】](#635a)# 减少在网络上的工作如果有什么东西比旋转硬盘还慢,那就是网络连接。如果您有一个分布式系统,需要与位于大陆或地球另一端的服务器进行协调,那么您确实会受到光速和网络拥塞的限制。最重要的是,网络链接的带宽通常小于硬盘驱动器到 CPU 的带宽,这使得运行速度更慢。此外,网络 TCP 开销是一个非常重要的事情。您可能会认为这是复杂分布式系统人员的问题。的确,对于大型 Hadoop 集群来说,它们比单个托管服务器更重要,但即使是单个服务器安装也会偶尔出现这种情况。当您向外扩展时,您的数据库将独立于您的应用程序或您的分析服务器。我曾经有一个简单的即席查询变成了常规仪表板,从一个大表中选择一些字段,简单的从表中选择 foo。将数据拉到另一台服务器上运行摄取到 pandas,并在那里进行分组/透视以进行演示,这非常容易。有索引和一切,但它的反应仍然相对较慢。当我更深入地研究时,我发现很多延迟是在数据库准备和通过网络发送许多兆字节的输出到进行分析的地方。加快速度的最简单方法是将一些分析逻辑转移到 SQL 查询本身,这样就可以减少通过网络发送的原始数据。[【返回主题列表】](#635a)# 最小化算法工作:使用更少的 CPU对于本文的大部分内容,我一直在谈论 I/O,因为 I/O 通常是最大的缓慢来源,也是您可以找到最容易摘到的果实的地方。但我们还没完!计算机还有其他可能很慢的东西,比如实际的计算部分本身!数据库不是神奇的计算系统,它们和你自己编写的任何程序一样,受到相同的算法约束。它们的排序速度不会比最著名的排序算法更快(因为它们是通用的,所以它们可能也不会使用最适合你的特定情况的算法)。这意味着您调用的特定操作和函数会对性能产生重大影响。请记住,就像所有复杂的现实世界一样,**没有灵丹妙药。我不能给你一个做什么/不做什么的硬性规定。您必须努力思考并实际测试性能,以找出适合您的特定设置的方法。**## 文本匹配功能处理大量文本总是计算密集型工作。无论你做什么,如果你必须一个字符一个字符地扫描整个字符串,这是对字符串长度的 O(n)运算。所以像这样带有%通配符和不区分大小写的操作符**是相当密集的操作。他们还可以与索引进行[有趣的互动](https://use-the-index-luke.com/sql/where-clause/searching-for-ranges/like-performance-tuning)。其他字符串函数,split、substr、concat 等。所有这些都使用相似的算法,因此在许多情况下并没有好到哪里去。[正则表达式使用起来更加昂贵](https://stackoverflow.com/questions/5892115/whats-the-time-complexity-of-average-regex-algorithms?lq=1),因为它们更加复杂。所以你越是使用这些功能,一切都变得越慢。**除了纯粹的计算复杂性,字符串可能是数据库中实际存储的最大的东西。这是假设您使用最佳实践,并且不在数据库中存储大型 BLOBs。如果使用 unicode 编码,每个字符可能是 1、2、3 甚至 4 个字节的数据,这取决于具体情况。文本字段可能包含数兆字节的文本。所有这些意味着我们将很快耗尽内存。## **分析和**窗口功能窗口函数非常棒,从过去遗留的 MySQL 5.4 代码库(没有窗口函数)移植到 Postgres 9.4 令人大开眼界。窗口函数可以做像计算百分位数或滞后这样的事情,这在过去是非常困难的和/或非常繁重的连接/子查询。在这方面,窗口函数往往比没有它们的性能有很大的提升。也就是说,它们不是魔法。所有数组值的额外存储和排序都是计算工作。除非你注意排序、索引和窗口大小等细节,否则它们可能会造成浪费。优化它们往往需要实验和深入阅读查询计划。但这是可行的,用[举例](https://www.cybertec-postgresql.com/en/postgresql-speeding-up-analytics-and-windowing-functions/) [像](https://www.red-gate.com/simple-talk/sql/t-sql-programming/t-sql-window-functions-and-performance/) [这些](https://stackoverflow.com/questions/16343484/sql-window-functions-performance-impact-of-returning-the-same-avg-many-times)。[【返回主题列表】](#635a)# 降低交易成本:避免开销开销很少对新手,甚至是系统的中级用户讲。不管出于什么原因,它被认为是一种深度的书呆子式的巫术,因为它被束缚在“系统的内脏”,在系统如何工作的元层中。但是当你开始寻找它时,你开始意识到开销无处不在。实际上,我们用计算机做的每件事都涉及一定数量的开销,基本上是准备和维护我们“真正在做”的事情。我们已经讨论了很多可以被认为是开销的东西,这取决于你的观点。正如我之前提到的,[网络开销可能很大](https://stackoverflow.com/questions/3613989/what-of-traffic-is-network-overhead-on-top-of-http-s-requests),我们希望通过减少网络传输来避免这种情况。它会消耗您的最大传输带宽,并且不是特定的数据库问题。谷歌提出并发布了一种网络协议 [QUIC](https://ma.ttias.be/googles-quic-protocol-moving-web-tcp-udp/) ,这种协议通过使用 UDP 避免了一些与 TCP(以及网络堆栈的邻*部分)相关的开销,从而提高了网络性能,这一点非常重要。还有旋转磁盘并寻找正确的扇区来读取数据的“开销”,我们认为这是硬盘寻道时间慢的原因,也是大多数系统转向固态硬盘的原因。这也是我们在整篇文章中竭力避免磁盘操作的部分原因。类似地,数据库本身也有大量的开销要处理。当它接受一个连接、打开一个事务、提交一个事务时,所有这些都需要时间。你会问,这种开销可能是多少?一个非常常见的优化是将大量数据上传到数据库。几乎总是这样,您希望避免进行多次小的插入,因为数据库在负载下会陷入困境。即使您在一个包含许多插入的事务中处理所有的事情,它仍然需要不断旋转查询解释器来处理每个查询调用。相反,最佳实践是创建一个巨大的文件(CSV 或其他文件)并一次性批量加载数据,即使您通过查询在网络上发送文件。这是**快了多个数量级的**。当你第一次遇到它的时候,它是完全疯狂和令人兴奋的。但是这完全有意义,因为对于一个小的单行插入,连接/事务处理时间比处理该插入所花费的时间要多。同样的开销问题也适用于运行一组 SELECT 语句。这里仍然涉及到开销。如果你一直用大量的小请求敲打数据库,最终会使整个服务器陷入瘫痪。您可能希望获取更多数据并在本地处理,或者考虑使用某种缓存。## 到处都有缓存应用程序实际使用的一种提高应用程序响应性和减少数据库负载的技术是简单地缓存一段时间的查询结果,以便重复的调用完全跳过数据库,只给出缓存的结果。这是应用程序级别的东西,并不是专门针对您的 SQL 查询的优化,但这是一种足够常见的响应模式,您可能会在您使用的一些分析工具上看到它。然而,在 SQL 查询级别,缓存仍然是一件需要注意的事情。快速连续多次运行完全相同的查询实际上会产生不同的运行时间,即使数据库没有缓存结果。这是因为第一个查询用数据填充了磁盘缓存和操作系统缓存。这不太可能是你的全部数据集,但在少数情况下,这是一个显著的(暂时的)速度提升。如果你是标杆管理的新手,这会影响你做的任何标杆管理。事实上,虽然您通常没有意识到这一点,但数据库和它们运行的操作系统会使用缓存技术来挤出额外的性能。这里有一个关于 [Postgresql 的缓存](https://madusudanan.com/blog/understanding-postgres-caching-in-depth/)行为的帖子,广义来说其他数据库也会在不同程度上做类似的事情。[【返回话题列表】](#635a)# 与他人相处融洽:竞争作为一个刚刚开始查询的最终用户,很容易**忘记数据库是多用户系统。他们通常处理事情非常迅速和透明,你永远不会真正知道通常有其他人在同一时间攻击服务器。但是,当您将服务器推向其操作极限时,您可能会遇到这样的情况:来自其他用户的查询,或者来自您自己的并行作业的查询,将开始对您产生影响。**## 一般负荷计划机器的使用遵循人类的活动模式,因此一天中的某些时段会比其他时段更忙。随着报告和数据库查询开始自动化,大批量请求的时间安排变得越来越重要。夜间作业通常被设置为在晚上非常相似的时间运行(通常在午夜左右),因为每个人都认为那时服务器将是“空的”。只不过它们不是,现在系统必须在同时运行的 10 个批处理查询之间进行任务切换。这仅仅是一个资源调度问题,但是我见过在空载服务器上运行只需 5-10 分钟的批处理作业延长到 30 分钟以上,因为它们与一堆其他作业争夺资源。## 锁一般负载有点烦人,因为它使事情变得不必要的慢,但是通过锁定会出现更严重的争用问题。数据库希望保持一致,这有时意味着当某些操作运行时,例如大的更新/写操作,整个表可能会被锁定。无论是行级锁还是表级锁,都取决于具体的细节,但无论是哪种情况,如果您有另一个查询需要访问那些被锁定的行,那么在解除锁之前,它们都不允许运行。锁有时会变成被称为死锁的病态情况,但这种情况很少见。更常见的情况是,它会造成查询堵塞,因为等待而似乎要花很长时间。另一个不太常见的影响是,锁会影响服务器复制,有时甚至会停止数据复制,这意味着没有新的数据更新进出服务器,并导致各种意想不到的副作用。(我向 devops 的人们深表歉意,这些年来我用超长的分析查询破坏了复制)。[【返回主题列表】](#635a)# 最后,答案是否定的:向问题扔钱整篇文章都致力于让查询变得更快。因此,忽视速度的最终答案是错误的——更多的硬件和/或更好的软件,也就是投入资金解决问题。这是我们的最后一招,不是第一招,但也不能忽视。有时,尽管您尽了最大努力来优化您的查询以使事情进行得更快,您还是会遇到 I/O 的限制,有时还会遇到 CPU 的限制,这些限制是您所拥有的系统无法克服的。在这种情况下,只有一件事可以让事情进展得更快:砸钱。重新设计您的系统,获得更多内存、更大的 RAID 阵列、更快的磁盘、更快的 CPU、更快的网卡和互连,当所有这些还不够时,可以通过集群进行扩展。我不是在开玩笑,脸书一度将他们的 [MySQL 设置扩展到了完全疯狂的](http://highscalability.com/blog/2015/5/18/how-mysql-is-able-to-scale-to-200-million-qps-mysql-cluster.html)水*。如果集群还不够,请根据您需要的速度重新设计您的整个应用系统架构,而不仅仅是 DB 架构。我们优化查询和数据库的目标是尽可能提高设备的性能,让花在系统上的每一分钱都获得最佳性能。非常容易顾全大局,嘲笑“如果不能做得更快,就多买些设备”的想法。但我们需要承认,优化不可避免地会有一个硬限制,即使这是一个非常高的限制,但确实存在一个收益递减点。经过完美调校和改装的 Miata 永远无法达到 F1 赛车的速度。查询优化的最后一个技巧是了解何时已经完成了所有可行的优化,何时速度的代价比升级的成本更高。这很难,因为这是一个排除的过程,一个否定的“我们在这里做不了更多”的证明。但是如果你真的发现自己处于这种情况,那就出去升级系统,这样你就可以重新优化了。# 在写这篇文章的时候,我发现了一些有趣的链接排名不分先后:*   [使用索引,Luke](https://use-the-index-luke.com/sql/preface)—DB performance for developers,许多关于数据库不同部分的性能和行为的小细节
*   [关于硬件和服务器性能的神话](https://logicalread.com/mythbusting-hardware-sql-server-perf-dc01/)——有很多关于用硬件解决问题并不是解决方案的故事
*   [PostgreSQL 中的缓存](https://madusudanan.com/blog/understanding-postgres-caching-in-depth/) —详细介绍了 PostgreSQL 用来更快交付结果的缓存策略,以及缓存如何与其他函数交互
*   [查询优化的故事](https://parallelthoughts.xyz/2019/05/a-tale-of-query-optimization/) —有人记录了他们优化查询的旅程,经历了许多曲折,最终追溯到数组比较& &操作符# 艰难地学习 SQL> 原文:<https://towardsdatascience.com/learning-sql-the-hard-way-4173f11b26f1?source=collection_archive---------5----------------------->![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/f6ebe40c912fa796493749a26704d61d.png)[Pixabay](https://pixabay.com/?utm_source=link-attribution&utm_medium=referral&utm_campaign=image&utm_content=1246836)## 通过写它***一个不懂 SQL 的数据科学家不值他的盐*** *。*在我看来,这在任何意义上都是正确的。虽然我们觉得创建模型和提出不同的假设更有成就,但数据管理的作用不能低估。当谈到 ETL 和数据准备任务时,SQL 无处不在,每个人都应该知道一点,至少是有用的。我仍然记得我第一次接触 SQL 的时候。这是我学会的第一种语言(如果你可以这么说的话)。这对我产生了影响。我能够将事情自动化,这是我以前从未想过的。在使用 SQL 之前,我曾经使用 Excel——VLOOKUPs 和 pivots。我在创建报告系统,一次又一次地做着同样的工作。SQL 让这一切烟消云散。现在我可以写一个大的脚本,一切都将自动化——所有的交叉表和分析都是动态生成的。这就是 SQL 的强大之处。尽管你可以使用 [Pandas](/minimal-pandas-subset-for-data-scientists-6355059629ae) 做任何你用 SQL 做的事情,你仍然需要学习 SQL 来处理像 HIVE,Teradata,有时还有 [Spark](/the-hitchhikers-guide-to-handle-big-data-using-spark-90b9be0fe89a) 这样的系统。***这个帖子是关于安装 SQL,讲解 SQL,运行 SQL 的。***# 设置 SQL 环境现在,学习 SQL 的最好方法是用它来弄脏你的手(对于你想学的任何其他东西,我也可以这么说)我建议不要使用像 w3schools/tutorialspoint for SQL 这样的基于网络的菜谱,因为你不能用这些菜谱来使用你的数据。此外,我会建议您学习 MySQL 风格的 SQL,因为它是开源的,易于在您的笔记本电脑上安装,并且有一个名为 MySQL Workbench 的优秀客户端,可以让您的生活更加轻松。我们已经解决了这些问题,下面是一步一步地设置 MySQL:*   您可以从[下载 MySQL 社区服务器](http://dev.mysql.com/downloads/mysql/)为您的特定系统(MACOSX、Linux、Windows)下载 MySQL。就我而言,我下载了 DMG 档案。之后,双击并安装文件。你可能需要设置一个密码。记住这个密码,因为以后连接到 MySQL 实例时会用到它。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/e005db125eb7287cb9876f06ed3e323f.png)*   创建一个名为`my.cnf`的文件,并将以下内容放入其中。这是向 SQL 数据库授予本地文件读取权限所必需的。```
[client]
port= 3306
[mysqld]
port= 3306
secure_file_priv=''
local-infile=1
```*   打开`System Preferences>MySQL`。转到`Configuration`并使用选择按钮浏览到`my.cnf`文件。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/e4142255f7ae70063142822c6f3290b4.png)*   通过点击停止和启动,从`Instances`选项卡重启服务器。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/d8546511d804bed0ca9e9920ee00d3e9.png)*   一旦服务器开始运行,下载并安装 MySQL 工作台:[下载 MySQL 工作台](https://dev.mysql.com/downloads/workbench/)。工作台为您提供了一个编辑器来编写 SQL 查询并以结构化的方式获得结果。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/6c85dfc7a0dd28dd1a07bbc0951cd438.png)*   现在打开 MySQL 工作台,通过它连接到 SQL。您将看到如下所示的内容。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/f152a90a6fac6c4bb3a5788458f8c07e.png)*   您可以看到本地实例连接已经预先为您设置好了。现在,您只需点击该连接,并开始使用我们之前为 MySQL 服务器设置的密码(如果您有地址、端口号、用户名和密码,您还可以创建一个到现有 SQL 服务器的连接,该服务器可能不在您的计算机上)。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/ea2872a799f929ab4a8d01ae5a587666.png)*   你会得到一个编辑器来编写你对特定数据库的查询。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/f841569e5a66a2db4a54bac0c5e22832.png)*   检查左上方的`Schemas`选项卡,查看显示的表格。表`sys_config`中只有一个`sys`模式。不是学习 SQL 的有趣数据源。所以还是装一些数据来练习吧。
*   如果你有自己的数据要处理。那就很好。您可以使用以下命令创建一个新的模式(数据库)并将其上传到表中。(您可以使用`Cmd+Enter`或点击⚡️lightning 按钮来运行命令)![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/8639241d8a0ee1ca4d0e497cfd1ee8c1.png)然而,在本教程中,我将使用 Sakila 电影数据库,您可以通过以下步骤安装该数据库:*   转到 [MySQL 文档](https://dev.mysql.com/doc/index-other.html)并下载 Sakila ZIP 文件。
*   解压文件。
*   现在转到 MySQL 工作台,选择文件>运行 SQL 脚本>选择位置`sakila-db/sakila-schema.sql`
*   转到 MySQL 工作台,选择文件>运行 SQL 脚本>选择位置`sakila-db/sakila-data.sql`完成后,您将看到模式列表中添加了一个新的数据库。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/c9f436d76729eb756cf20afbb3479f22.png)# 玩弄数据现在我们有了一些数据。最后。让我们从编写一些查询开始。您可以尝试使用 [Sakila Sample Database](https://dev.mysql.com/doc/sakila/en/sakila-structure.html) 文档详细了解 Sakila 数据库的模式。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/44988c70c407c185a6eaf4d2730fc1d4.png)Schema Diagram任何 SQL 查询的基本语法都是:```
SELECT col1, SUM(col2) as col2sum, AVG(col3) as col3avg 
FROM table_name 
WHERE col4 = 'some_value' 
GROUP BY col1 
ORDER BY col2sum DESC;
```该查询中有四个元素:1.  **选择**:选择哪些列?在这里,我们选择`col1`,在`col2`上进行总和聚合,在`col3`上进行 AVG 聚合。我们还通过使用`as`关键字给`SUM(col2)`起了一个新名字。这就是所谓的混叠。
2.  **FROM** :我们应该从哪个表中选择?
3.  **WHERE** :我们可以使用 WHERE 语句过滤数据。
4.  **分组依据**:不在聚合中的所有选定列都应该在分组依据中。
5.  **排序依据**:排序依据`col2sum`上面的查询将帮助您在数据库中找到大多数简单的东西。例如,我们可以使用以下方法找出不同审查级别的电影在不同时间播放的差异:```
SELECT rating, avg(length) as length_avg 
FROM sakila.film 
GROUP BY rating 
ORDER BY length_avg desc;
```![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/a427dc43ae531e31ddd7a1803c480080.png)## 练习:提出一个问题你现在应该提出一些你自己的问题。例如,你可以试着找出 2006 年发行的所有电影。或者试图找到分级为 PG 且长度大于 50 分钟的所有电影。您可以通过在 MySQL Workbench 上运行以下命令来实现这一点:```
SELECT * FROM sakila.film WHERE release_year = 2006; 
SELECT * FROM sakila.film WHERE length>50 and rating="PG";
```# SQL 中的联接到目前为止,我们已经学习了如何使用单个表。但实际上,我们需要处理多个表。接下来我们要学习的是如何连接。现在连接是 MySQL 数据库不可或缺的一部分,理解它们是必要的。下图讲述了 SQL 中存在的大多数连接。我通常最后只使用左连接和内连接,所以我将从左连接开始。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/2453386f12eef4274be193fad388fdd0.png)当您希望保留左表(A)中的所有记录并在匹配记录上合并 B 时,可以使用左连接。在 B 没有被合并的地方,A 的记录在结果表中保持为 NULL。MySQL 的语法是:```
SELECT A.col1, A.col2, B.col3, B.col4 
FROM A 
LEFT JOIN B 
ON A.col2=B.col3
```这里,我们从表 A 中选择 col1 和 col2,从表 b 中选择 col3 和 col4。当您想要合并 A 和 B,并且只保留 A 和 B 中的公共记录时,可以使用内部联接。## 示例:为了给你一个用例,让我们回到我们的 Sakila 数据库。假设我们想知道我们的库存中每部电影有多少拷贝。您可以通过使用以下命令来获得:```
SELECT film_id,count(film_id) as num_copies 
FROM sakila.inventory 
GROUP BY film_id 
ORDER BY num_copies DESC;
```![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/7d08080ef7e9bb58151a7dd69824f202.png)这个结果看起来有趣吗?不完全是。id 对我们人类来说没有意义,如果我们能得到电影的名字,我们就能更好地处理信息。所以我们四处窥探,发现表`film`和电影`title`都有`film_id`。所以我们有所有的数据,但是我们如何在一个视图中得到它呢?来加入救援。我们需要将`title`添加到我们的库存表信息中。我们可以用——```
SELECT A.*, B.title 
FROM sakila.inventory A 
LEFT JOIN sakila.film B 
ON A.film_id = B.film_id
```![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/a0743c960ef71f75b47bb39b7b0e18a5.png)这将向您的库存表信息中添加另一列。正如你可能注意到的,有些电影在`film`表中,而我们在`inventory`表中没有。我们使用了一个左连接,因为我们希望保留库存表中的所有内容,并将其与`film`表中对应的内容连接,而不是与`film`表中的所有内容连接。因此,现在我们将标题作为数据中的另一个字段。这正是我们想要的,但我们还没有解决整个难题。我们想要库存中标题的`title`和`num_copies`。但是在我们继续深入之前,我们应该首先理解内部查询的概念。# 内部查询:现在您有了一个可以给出上述结果的查询。您可以做的一件事是使用```
CREATE TABLE sakila.temp_table as 
SELECT A.*, B.title FROM sakila.inventory A 
LEFT JOIN sakila.film B 
ON A.film_id = B.film_id;
```然后使用简单的 group by 操作:```
SELECT title, count(title) as num_copies 
FROM sakila.temp_table 
GROUP BY title 
ORDER BY num_copies desc;
```![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/69c8ac4f7bbdf14941ebc4350fcf87dd.png)但这是多走了一步。我们必须创建一个临时表,它最终会占用系统空间。SQL 为我们提供了针对这类问题的内部查询的概念。相反,您可以在一个查询中编写所有这些内容,使用:```
SELECT temp.title, count(temp.title) as num_copies 
FROM (
SELECT A.*, B.title 
FROM sakila.inventory A 
LEFT JOIN sakila.film B 
ON A.film_id = B.film_id) temp 
GROUP BY title 
ORDER BY num_copies DESC;
```![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/073edbdf4bac180c0cb2d15b558e6a81.png)我们在这里做的是将我们的第一个查询放在括号中,并给这个表一个别名`temp`。然后我们按照操作进行分组,考虑`temp`,就像我们考虑任何表一样。正是因为有了内部查询的概念,我们才能编写有时跨越多个页面的 SQL 查询。# 从句HAVING 是另一个有助于理解的 SQL 结构。所以我们已经得到了结果,现在我们想得到拷贝数小于或等于 2 的影片。我们可以通过使用内部查询概念和 WHERE 子句来做到这一点。这里我们将一个内部查询嵌套在另一个内部查询中。相当整洁。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/c44cd5e9adf7f23041b168c68b1531f5.png)或者,我们可以使用 HAVING 子句。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/88f50581f677de96b8d61a4fdbd26114.png)HAVING 子句用于过滤最终的聚合结果。它不同于 where,因为 WHERE 用于筛选 from 语句中使用的表。在分组发生后,对最终结果进行过滤。正如您在上面的例子中已经看到的,有很多方法可以用 SQL 做同样的事情。我们需要尽量想出最不冗长的,因此在许多情况下有意义的。如果你能做到这一步,你已经比大多数人知道更多的 SQL。接下来要做的事情: ***练习*** 。尝试在数据集上提出您的问题,并尝试使用 SQL 找到答案。首先,我可以提供一些问题:1.  ***在我们的盘点中,哪位演员的电影最鲜明?***
2.  ***在我们的盘点中,哪些类型片的租借率最高?***# 继续学习这只是一个关于如何使用 SQL 的简单教程。如果你想了解更多关于 SQL 的知识,我想向你推荐一门来自加州大学的关于数据科学的优秀课程。请务必阅读它,因为它讨论了其他 SQL 概念,如联合、字符串操作、函数、日期处理等。将来我也会写更多初学者友好的帖子。在 [**中**](https://medium.com/@rahul_agarwal) 关注我,或者订阅我的 [**博客**](http://eepurl.com/dbQnuX) 了解他们。一如既往,我欢迎反馈和建设性的批评,可以通过 Twitter [@mlwhiz](https://twitter.com/MLWhiz) 联系到我。此外,一个小小的免责声明——这篇文章中可能会有一些相关资源的附属链接,因为分享知识从来都不是一个坏主意。# 学习理论:(不可知论者)大概*似正确的学习> 原文:<https://towardsdatascience.com/learning-theory-agnostic-probably-approximately-correct-learning-dfd0d7c76467?source=collection_archive---------3----------------------->![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/1c3b46fd5733045073611bd81e7fbaa9.png)在我以前的文章中,我讨论了什么是经验风险最小化,以及它在某些假设下产生令人满意的假设的证明。现在我想讨论一下大概正确的学习(这有点拗口,但是有点酷),这是 ERM 的一个概括。对于那些不熟悉 ERM 的人来说,我建议阅读我在该主题上的[前一篇文章](/learning-theory-empirical-risk-minimization-d3573f90ff77),因为这是理解 PAC learning 的先决条件。请记住,在分析 ERM 时,我们得出的结论是,对于有限的假设空间 **H** 我们可以得出一个假设,当假设假设空间中存在这样一个假设时,它的误差以一定的概率低于**ε**。基于这些参数,我们可以计算出需要多少样本才能达到这样的精度,我们得出了样本的下限值:![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/cebc85b885e0285a4e24413ad9ddbcb6.png)这可以放入通用的 PAC 学习框架,下面的正式定义来自《理解机器学习》一书:![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/3a3afb6789cd903e2b6aa6d7579ab454.png)至少对我来说,这个定义一开始有点混乱。这是什么意思?该定义规定,如果存在函数 **m_H** 和算法,则**假设类**是 PAC 可学习的,该算法对于输入域 **X、δ**和**ε**上的任何标记函数 **f、**分布 **D** ,其中 **m ≥ m_H** 产生假设 **h** ,使得概率为 1-**δ**一个标注函数无非就是说我们有一个确定的函数 **f** 标注域内的数据。这里,假设类可以是任何类型的二元分类器,因为将标签分配给来自域的例子的标签函数分配标签 **0** 或 **1。****m _ H**函数为我们提供了一个最小样本数的界限,我们需要该界限来实现低于**ε**的误差,并具有置信度**δ。**精确度**ε**逻辑上控制必要的样本大小,因为我们的精确度越高,逻辑上我们需要我们的训练集是来自领域的更忠实的样本,因此,增加实现这种精确度所需的样本数量。## 使模型不可知![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/73c0b7c5720526f9be3d379c4a485c1b.png)Photo by [Evan Dennis](https://unsplash.com/@evan__bray?utm_source=medium&utm_medium=referral) on [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral)上述模型有一定的缺点,由于可实现性假设(在[经验风险最小化](/learning-theory-empirical-risk-minimization-d3573f90ff77)中解释),它不够通用——没有人保证存在一个假设,由于模型的失败,该假设将导致我们当前假设空间中的真实误差为 0。另一种看待它的方式是,也许标签没有被数据很好地定义,因为缺少特征。我们绕过可实现性假设的方法是用数据标签分布代替标签函数。您可以将此视为在标注函数中引入了不确定性,因为一个数据点可以共享不同的标注。那么为什么叫**不可知 PAC 学习**?不可知论一词来源于这样一个事实,即学习对于数据标签分布是不可知论的——这意味着它将通过不对数据标签分布做任何假设来学习最佳标签函数 **f** 。这种情况下有什么变化?嗯,**真误差**定义改变了,因为一个标签到一个数据点是在多个标签上的分布。我们不能保证学习者将达到最小可能的真实错误,因为我们没有数据标签分布来说明标签的不确定性。经过这些考虑,我们从一书中得出了以下正式定义:![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/00f30bf6079fd089669f40ff119597d7.png)注意定义中关于 **PAC** 可学习性的变化。通过引入数据标签分布 **D** ,我们考虑到学习假设的**真实误差**将小于或等于**最优假设的误差**加上因子**ε**的事实。这也包含了 **PAC** 在假设空间中存在最优假设的情况下的自我学习,该假设产生的**真误差**为 0,但我们也考虑到可能不存在这样的假设。这些定义将在稍后解释 **VC 维度**和证明**没有免费的午餐定理时有用。**如果术语对你来说有点陌生,我建议你看一下[学习理论:经验风险最小化](/learning-theory-empirical-risk-minimization-d3573f90ff77)或者更详细地看一下文章中提到的 Ben-David 的精彩著作。除此之外,继续机器学习!# 学习理论:经验风险最小化> 原文:<https://towardsdatascience.com/learning-theory-empirical-risk-minimization-d3573f90ff77?source=collection_archive---------2----------------------->![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/06d6562d4f49a3dde58b3d144103a0dd.png)经验风险最小化是机器学习中的一个基本概念,然而令人惊讶的是许多从业者并不熟悉它。理解 ERM 对于理解机器学习算法的限制以及形成实用的问题解决技能的良好基础是至关重要的。企业风险管理背后的理论是解释风险资本维度、大概正确(PAC)学习和其他基本概念的理论。在我看来,任何认真对待机器学习的人都应该乐于谈论 ERM。我将尽可能简单、简短和有理论依据地解释基本概念。这篇文章在很大程度上基于 Schwartz 和 Ben-David 的书[理解机器学习](http://www.cs.huji.ac.il/~shais/UnderstandingMachineLearning),我强烈推荐给任何对学习理论基础感兴趣的人。先说一个简单的监督学习分类问题。假设我们要对垃圾邮件进行分类,这可能是机器学习中最常用的例子(注意,这不是关于朴素贝叶斯的帖子)。每封邮件都有一个标签 0 或 1,要么是垃圾邮件,要么不是垃圾邮件。我们用 ***X*** 表示领域空间,用 ***Y*** 表示标签空间,我们还需要一个将领域集合空间映射到标签集合空间的函数,****f:X->Y***,这只是一个学习任务的形式化定义。**现在我们有了正式的问题定义,我们需要一个模型来做出我们的预测:垃圾邮件或不是垃圾邮件。巧合的是,**模型**的同义词是假设 ***h*** ,可能有点混乱。在这种情况下,假设只不过是一个从我们的域 ***X*** 获取输入并产生标签 0 或 1 的函数,即函数***h:X->Y****。***最后,我们实际上想找到最小化我们误差的假设,对吗?由此,我们得出了经验风险最小化这一术语。术语“经验的”意味着我们基于来自领域集合 **X** 的样本集合 ***S*** 来最小化我们的误差。从概率的角度来看,我们说我们从域集合 **X** 中采样 ***S*** ,其中 ***D*** 是在 **X** 上的分布。因此,当我们从域中采样时,我们表示从域 **X** 中通过***D***(**S**)采样的域子集的可能性有多大。**在下面的等式中,我们可以定义**真误差**,它基于整个域 **X** :**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/6be695c5ca70021052c9bfcca352d8be.png)**The error for hypothesis h. Starting from left to right, we calculate the error L based on a domain distribution D and a label mapping f. The error is equal to the probability of sampling x from d such that the label produced by the hypothesis is different from the actual label mapping.**由于我们只能访问输入域的子集 ***S*** ,因此我们是基于训练示例的样本进行学习的。我们无法访问**真实误差**,但可以访问**经验误差**:**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/88a338344194a3d6f53a876c496c3095.png)**m denotes the number of training examples. You can see from the equation that we effectively define the empirical error as the fraction of misclassified examples in the set S.**经验误差有时也被称为概括误差。原因是,实际上,在大多数问题中,我们无法访问输入的整个域*,而只能访问我们的训练子集**。W* e 想在 ***S*** 的基础上进行归纳学习,也叫归纳学习。这个误差也被称为**风险,**因此在经验风险最小化中称为风险。如果这让你想起了小批量梯度下降,那你就对了。这个概念在现代机器学习中基本是无处不在的。*****现在可以谈谈**过拟合**的问题了。也就是说,由于我们只有数据的子样本,可能会发生这样的情况:我们最小化了**经验误差**,但实际上增加了**真实误差。**这个结果可以在简单的曲线拟合问题中观察到。让我们想象一下,我们有一些想要控制的机器人,我们想要将一些传感器数据 **X** 映射到扭矩。传感器数据有某种噪声,因为传感器从来都不是完美的,在这种情况下,我们将对传感器数据使用简单的高斯噪声。我们拟合了一个神经网络来做这件事,并且我们获得了以下结果:****![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/427d4ac6028c38aa20cb95feb30225d9.png)****The green points are the points that were used in fitting the model, our sample S. The model is actually quite good considering the small number of training points, but deviations from the optimal curve can be seen.****我们可以从另一个图中看到这种泛化误差,请注意,在某个点上,真实误差开始增加,而经验误差进一步减少。这是模型过度拟合训练数据的结果。****![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/64a6383aa9f48867a8ef04b0391f28fc.png)****既然我们已经定义了我们的**经验风险**和**实际风险**,那么问题就来了,我们是否真的能用这些做些有用的事情?事实证明,我们可以有把握地保证 ERM 将会发挥作用。换句话说,我们希望以一定的信心得出模型误差的上界。上界的意思很简单,我们可以保证误差不会超过这个界限,因此有了界这个词。****![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/e03d52aa958b1af24b34427392f45ba3.png)****This gives us the probability that a sampled set S (or training data in other words) is going to overfit the data, i.e. that the true error(L) is going to be larger than a certain number epsilon.****在当前情况下,我们将在**可实现性假设**下操作。我不打算写正式的定义,但简而言之,假设表明在所有可能的假设*的空间中存在一个假设 ***h*** ,该假设在真实风险为 0 的意义上是最优的,这也意味着在子集 ***S*** 上找到的假设实现了 0 经验误差。当然,这在现实世界的用例中大多是不正确的,有一些学习范例放松了这种假设,但这一点我可能会在另一篇文章中讨论。*****让我们定义真实误差高于ε的一组假设:****![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/d69289813af92f0597d9fc4d0ccd7342.png)****对于这组假设,很明显,要么他们接受了一组非代表性的学习,这导致了低的经验误差(风险)和高的真实误差(风险),要么他们没有好到足以学到任何东西。****我们想要分离导致假设的误导性训练集,这些假设导致低经验误差和高真实误差(过拟合的情况),这将在稍后推导上限时有用:****![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/e87d9deb067bd446d754872a02b2b954.png)****抽样一个非代表性样本的特定子集 ***S*** 的概率在逻辑上等于或低于抽样 ***M*** 的概率,因为 ***S*** 是*M 的子集,因此我们可以写成:******![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/76235bcc0faae966de1a540a6bd41ef3.png)******我们将并集界引理应用于等式的右侧,该引理表示对两个集合的并集进行采样的概率低于对它们分别进行采样的概率。这就是为什么我们可以把总数写在右边:******![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/bff57c1c25c8ed9a369c1ac99f8107d1.png)******此外,我们假设这些例子是独立同分布的(iid ),因此我们可以将经验误差为零的概率写成各个预测正确的概率的乘积:******![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/414eff38d00c06223b6b1860a46e4275.png)******The constant m denotes the number of training examples in the set S.******假设在某一数据点正确的概率可以写成 1 减去**真实风险**。这是因为我们将风险定义为错误分类样本的分数。这个不等式来自于我们假设误差低于或等于上界的事实。******![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/fb1d9d86e8f65a93ea99e52d84e75961.png)******如果我们把前面的两个等式结合起来,我们会得到下面的结果:******![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/6ca6d8a5649d32a6f0c80e0945bb0e57.png)******The exponential on the right comes from a simply provable inequality.******如果我们将上面的等式与应用联合边界的前一个等式结合起来,我们会得到以下有见地的结果:******![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/001960c161ab5957c16b50f3721ee1d0.png)******Here |H| is the cardinality of the hypothesis space, obviously, this formulation doesn’t make sense in the case when we have an infinite number of hypotheses.******我们可以用某个常数 1δ来代替左侧,其中δ是我们希望误差不高于ε的置信度。我们可以简单地重新排列等式,以便表述如下:******![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/cebc85b885e0285a4e24413ad9ddbcb6.png)******最终结果告诉我们,我们需要多少个示例(m ),以便 ERM 不会导致高于ε且具有某个置信度δ的误差,即,当我们为 ERM 选择足够多的示例时,它可能不会具有高于ε的误差。我在这里使用可能这个词,因为它取决于我们的置信常数δ,它在 0 和 1 之间。这是一件很直观的事情,但我认为有时候看看方程,发现它在数学上是有意义的,这很好。******在企业风险管理中,做出了许多假设。我提到了可实现性假设,即在我们的假设池中有一个最优假设。此外,假设空间可能不是有限的,因为它是在这里。在未来,我计划通过范例来放松这些假设。然而,ERM 是学习理论中的一个基本概念,对于任何认真的机器学习实践者都是必不可少的。***# 为数据科学家和学者学习编码> 原文:<https://towardsdatascience.com/learning-to-code-for-data-scientists-and-academics-8019b4677537?source=collection_archive---------29----------------------->![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/df05fc2f9d75f3fa9feb723a888d1866.png)作为一名高年级研究生,我经常指导低年级实验室成员(例如,本科生、学士后研究助理、低年级研究生)。我强烈鼓励我的同事学习如何编码。即使你不打算成为一名“数据科学家”,知道如何编码也是非常有用和有市场的(至少现在是这样!)技能要有。如果你是一名“学者”,我几乎可以向你保证,编码至少会节省你处理/分析数据的时间,甚至可能提高你的研究质量。你甚至会发现你喜欢编码——我知道我喜欢!我认为最适合数据科学家和学者学习的两种语言是 Python 和 r。虽然我认为这两种语言都很好学,但我个人鼓励我的同事使用 Python。Python 是一种相对容易学习的语言,而且非常灵活。此外,我是一名深度学习实践者,深度学习库主要基于 Python。下面我有一些关于如何开始学习编码的建议。# 1.学习基础知识在深入所有的机器学习和统计软件包之前,我认为学习 Python 的基础知识是很重要的。一个非常好的免费在线资源是为每个人准备的 T2 Python。该资源包括讲座和附带练习的教科书。当我刚开始学习 Python 时,我浏览了这些讲座/章节。学完这门课后,你将会有一个相当扎实的 Python 基础。# 2.Jupyter 笔记本中的代码我强烈建议您在 Jupyter 笔记本中编写代码。Jupyter Notebook 是一个基于 web 应用程序的编码环境,允许您交互式编码。这些笔记本允许您轻松地记录代码和创建可视化效果。对于学者,我通常会有一个 Jupyter 笔记本,里面包含我在出版物中使用的代码。这让我可以轻松地查阅我的代码,并与想要复制我的分析的其他人分享。我甚至在非正式的演讲中使用过 Jupyter 笔记本。最*有一篇关于 Jupyter 笔记本不同特性的非常好的博文([点击此处](/bringing-the-best-out-of-jupyter-notebooks-for-data-science-f0871519ca29)查看博文),我推荐你去看看。你可以在 [Anaconda 发行版](https://www.anaconda.com/distribution/)中随 Python 一起安装 Jupyter Notebook。**我推荐用这种方式安装 Python**因为它也会安装很多有用的包。# 3.用于数据辩论、统计、机器学习和数据可视化的学习包学习对数据争论、统计、机器学习和数据可视化有用的 Python 包。大的有 NumPy,Pandas,SciPy,scikit-learn,Matplotlib 和 seaborn。我通过 *Python 数据科学手册*学习了这些包,在[作者的网站](https://jakevdp.github.io/PythonDataScienceHandbook/)上可以免费获得。这本书的一个缺点是它没有任何练习*。*我也听说过关于[用于数据分析的 Python](http://shop.oreilly.com/product/0636920050896.do)的很棒的东西,最*更新了。这本书是熊猫的创造者写的。我想在某个时候抽出时间来浏览这本书。对于不一定使用机器学习的学者,你可能也想看看 [StatsModels](https://www.statsmodels.org/stable/index.html) 。当处理较小的数据集并且不使用机器学习时,我经常使用这个包。对于那些没有使用机器学习方法的人,我最*看到了这个关于 Python 中统计的[教程,它快速介绍了这些包的一些有用特性。](http://scipy-lectures.org/packages/statistics/index.html)# 结论在经历了这些步骤之后,你将在数据科学家和学者经常使用的编码技巧方面有一个相当坚实的基础(并不是说不可能有学术数据科学家!).当你开始学习编码时要记住的一点是,任何人刚开始时都不容易,需要耐心。坚持下去,尽可能多地编码,最终你会达到像专业人士一样编码的地步!祝你的编码之旅好运,并请在评论中发布你认为对初学编码者有益的其他资源!# 几分钟内学会*稳驾驶> 原文:<https://towardsdatascience.com/learning-to-drive-smoothly-in-minutes-450a7cdb35f4?source=collection_archive---------4----------------------->## 小型赛车上的强化学习![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/e3713abe60565ffef777d3f5c38333fb.png)Donkey Car in action with teleoperation control panel in the unity simulator在这篇文章中,我们将看到如何在几分钟内训练一辆自动驾驶赛车,以及如何*稳地控制它。这种基于强化学习(RL)的方法,在这里的模拟(驴车模拟器)中提出,被设计成适用于现实世界。它建立在一家名为 [Wayve.ai](https://wayve.ai/) 的专注于自动驾驶的初创公司的工作基础上。本文中使用的代码和模拟器是开放源代码和公共的。更多信息请查看[关联的 GitHub 库](https://github.com/araffin/learning-to-drive-in-5-minutes);)(预先训练的控制器也可以下载)**重要提示:如需最新版本(使用**[**Stable-baselines 3**](https://github.com/DLR-RM/stable-baselines3)**和 PyTorch),请查看**[https://github . com/araffin/aae-train-donkey car/releases/tag/live-twitch-2](https://github.com/araffin/aae-train-donkeycar/releases/tag/live-twitch-2)**2022 年 4 月更新**:我用强化学习做了一系列学习赛车的视频:[https://www.youtube.com/watch?v=ngK33h00iBE&list = pl 42 JK f1 t1 f 7 dfxe 7 f 0 vteflhw 0 ze Q4 XV](https://www.youtube.com/watch?v=ngK33h00iBE&list=PL42jkf1t1F7dFXE7f0VTeFLhW0ZEQ4XJV)## 录像## GitHub 库:重现结果[](https://github.com/araffin/learning-to-drive-in-5-minutes) [## araffin/5 分钟学会驾驶### 实施强化学习方法,使汽车在几分钟内学会*稳驾驶——5 分钟内学会驾驶github.com](https://github.com/araffin/learning-to-drive-in-5-minutes) ## 赛车比赛自从几年前 DIY Robocars 诞生以来,现在已经有了无数的自主赛车比赛(例如[图卢兹机器人大赛](http://toulouse-robot-race.org/)、[铁车、](http://www.ironcar.org/)……)。在这些项目中,目标很简单:你有一辆赛车,它必须在赛道上尽可能快地行驶,只给它车载摄像头的图像作为输入。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/4de4ee9de4ed151a7f05d6d133853174.png)The Warehouse level, inspired by DIY Robocars自驾挑战是进入机器人领域的好方法。为了方便学习,开发了开源的自动驾驶*台[驴车](http://www.donkeycar.com/)。在其生态系统中,现在有一个以那个小机器人为特色的 [unity 模拟器](https://github.com/tawnkramer/sdsandbox/tree/donkey)。我们将在这辆驴车上测试提议的方法。## 概述在简要回顾了小型自动驾驶汽车比赛中使用的不同方法后,我们将介绍什么是强化学习,然后详细介绍我们的方法。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/04c3dfea2991b2067b33f1e76a1308b9.png)[Autonomous Racing Robot With an Arduino, a Raspberry Pi and a Pi Camera](https://becominghuman.ai/autonomous-racing-robot-with-an-arduino-a-raspberry-pi-and-a-pi-camera-3e72819e1e63)## 自驾车比赛中使用的方法:路线跟踪和行为克隆在介绍 RL 之前,我们将首先快速回顾一下目前在 RC 赛车比赛中使用的不同解决方案。在[之前的博客文章](https://becominghuman.ai/autonomous-racing-robot-with-an-arduino-a-raspberry-pi-and-a-pi-camera-3e72819e1e63)中,我描述了第一种自动驾驶的方法,它结合了*计算机视觉和 PID 控制器*。虽然这个想法很简单,适用于许多设置,但它需要手动标记数据(以告诉汽车赛道的中心在哪里),这既费钱又费力(相信我,手动标记并不好玩!).![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/27e0864a254117f2f7b40f9280600152.png)[Predicting where is the center of the track](https://www.youtube.com/watch?v=xhI71ZdSh6k)作为另一种方法,许多竞争对手使用监督学习来*再现人类驾驶员行为*。为此,人类需要在几圈期间手动驾驶汽车,记录相机图像和来自操纵杆的相关控制输入。然后,训练一个模型来再现人类驾驶。然而,这种技术并不是真正健壮的,需要每条赛道的同质驾驶和再训练,因为它的泛化能力相当差。## 什么是强化学习(RL),我们为什么要使用它?鉴于上述问题,强化学习(RL)似乎是一个有趣的选择。在强化学习环境中,一个代理(或机器人)作用于它的环境,并接收一个奖励作为反馈。它可以是积极的奖励(机器人做了好事)或消极的奖励(机器人应该受到惩罚)。*机器人的目标是累积奖励最大化。*为了做到这一点,它通过与世界的交互来学习所谓的策略(或行为/控制器),将它的感官输入映射到行动。在我们的例子中,*输入是摄像机图像,动作是油门和转向角度*。因此,如果我们以这样一种方式模拟奖励,即赛车保持在赛道上并使其速度最大化,我们就完成了!![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/c73c9281f30e2aeefc8da04bb6e29fcb.png)[Stable-Baselines: an easy to use reinforcement learning library](https://github.com/hill-a/stable-baselines)这就是[强化学习](https://spinningup.openai.com/en/latest/)的美妙之处,你只需要很少的假设(这里只设计一个奖励函数),它会直接优化你想要的(在赛道上快速前进,赢得比赛!).注意:这不是第一篇关于小型无人驾驶汽车强化学习的博客文章,但与[以前的方法](https://flyyufelix.github.io/2018/09/11/donkey-rl-simulation.html)、*相比,本文介绍的技术只需要几分钟*、**、**(而不是几个小时)就可以学会一个良好而*滑的控制策略(对于一个*滑的控制器来说大约需要 5 到 10 分钟,对于一个非常*滑的控制器来说大约需要 20 分钟)。现在我们已经简要介绍了什么是 RL,我们将进入细节,从剖析 Wayve.ai 方法开始,这是我们方法的基础。## 一天学会驾驶——way ve . ai 方法的关键要素[Wayve.ai](https://wayve.ai/blog/learning-to-drive-in-a-day-with-reinforcement-learning) 描述了一种在简单道路上训练现实世界中自动驾驶汽车的方法。这种方法由几个关键要素组成。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/a580601d609ab575dd2e2d76ce413ee8.png)[Wayve.ai approach](https://www.youtube.com/watch?v=eRwTbRtnT1I): learning to drive in a day首先,他们*训练一个特征提取器*(这里是一个可变自动编码器或 *VAE* )将图像压缩到一个更低维度的空间。该模型被训练来重建输入图像,但是包含迫使其压缩信息的瓶颈。**这个从原始数据中提取相关信息的步骤叫做** [**状态表征学习(SRL)**](https://github.com/araffin/robotics-rl-srl) ,是我主要的[研究课题](https://openreview.net/forum?id=Hkl-di09FQ)。这显著地允许减少搜索空间,并因此加速训练。下图显示了 SRL 和端到端强化学习之间的联系,也就是说,直接从像素学习控制策略。注意:训练自动编码器[并不是提取有用特征的唯一解决方案](https://arxiv.org/pdf/1802.04181.pdf),你也可以训练例如[逆动力学模型](https://github.com/araffin/srl-zoo)。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/f507dcffa84821df6392e6b5f9569280.png)[Decoupling Feature Extraction from Policy Learning](https://openreview.net/forum?id=Hkl-di09FQ)第二个关键要素是使用名为[深度确定性策略梯度(DDPG)](https://stable-baselines.readthedocs.io/en/master/modules/ddpg.html) 的 RL 算法,该算法使用 VAE 特性作为输入来学习控制策略。这个政策每集之后都会更新。该算法的一个重要方面是*它有一个内存,称为重放缓冲区***,在这里它与环境的交互被记录下来,并可以在以后“重放”。因此,即使汽车不与世界互动,它也可以从这个缓冲区中采样经验来更新它的策略。****在人类干预之前,汽车被训练成最大化行驶的米数。这是最后一个关键因素:一旦汽车开始偏离道路,人类操作员就结束这一集。这个*提前终止*真的很重要(如[深度模仿](https://xbpeng.github.io/projects/DeepMimic/index.html)所示),防止汽车探索不感兴趣的区域来解决任务。****到目前为止,没有什么新的东西被提出来,我们只是总结了 Wayve.ai 的方法。以下是我对基本技术的所有修改。**## **几分钟内学会驾驶——最新方法****虽然 Wayve.ai 技术在原理上可能行得通,但要将其应用于自动驾驶的遥控汽车,还需要解决一些问题。****首先,因为特征提取器(VAE)在每集之后被训练,所以特征的分布不是固定的。也就是说,*特征随着时间的推移而变化*,并可能导致策略训练的不稳定性。此外,在笔记本电脑上训练 VAE(没有 GPU)相当慢,所以我们希望避免在每一集后重新训练 VAE。****为了解决这两个问题,我决定*事先训练一只 VAE*并使用谷歌 [Colab 笔记本](https://colab.research.google.com/drive/1mF2abRb_yi4UNqYXVBF-t4FuCy6fl1c1#scrollTo=9bIR_N7R11XI)来保存我的电脑。通过这种方式,使用固定的特征提取器来训练策略。****在下面的图片中,我们[探索 VAE 学到了什么](https://github.com/araffin/srl-zoo)。我们在它的潜在空间中导航(使用滑块)并观察重建的图像。****![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/dd08a7178f11ba8a76ea406fd3f4c2eb.png)****[Exploring the latent space](https://github.com/araffin/srl-zoo) learned by the VAE****然后,众所周知,DDPG 是不稳定的(在某种意义上,它的表现会在训练中灾难性地下降),并且很难调整。幸运的是,最*一个名为 [**的软演员评论家**](https://stable-baselines.readthedocs.io/en/master/modules/sac.html) **(SAC)的算法具有相当的性能,并且更容易调整** *。*****在我的实验中,我尝试了 PPO、SAC 和 DDPG。DDPG 和 SAC 在几集内给出了最好的结果,但 SAC 更容易调整。****对于这个项目,我使用了我为[stable-baselines](https://github.com/hill-a/stable-baselines)**编写的软 Actor-Critic (SAC)实现(如果你正在使用 RL,我肯定推荐你看一看;) ),里面有算法的[最新改进](https://bair.berkeley.edu/blog/2018/12/14/sac/)。********[](https://github.com/hill-a/stable-baselines) [## 丘陵/稳定基线### OpenAI 基线的一个分支,强化学习算法的实现- hill-a/stable-baselinesgithub.com](https://github.com/hill-a/stable-baselines) 最后,我更新了奖励函数和动作空间,以*滑控制和最大化速度。## 奖励功能:走得快但留在赛道上!机器人汽车没有任何里程计(也没有速度传感器),因此行驶的米数(也没有速度)不能作为奖励。因此,我决定在每个时间步给予“生命奖励”(即停留在赛道上的+1 奖励),并对机器人进行惩罚,对离开赛道的使用**碰撞惩罚**(-10 奖励)。此外,我发现惩罚开得太快的车也是有益的:与油门成比例的额外负奖励被加到撞车惩罚上。********最后,因为我们想跑得快,因为它是一辆赛车,我添加了一个与当前油门成比例的“油门加成”。这样,**机器人会尽量待在轨道上,同时最大化速度**。********总结一下:********![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/3b4cd4be26f3f19a2c13e9c93ddf4289.png)********其中 w1 和 w2 是常数,允许*衡目标(w1 << 10,w2 << 1,因为它们是次要目标)****## ****避免摇晃控制:学习*稳驾驶****> ****世界并不是随机的。如果你注意到了——机器人不会自发地开始颤抖。除非你给它接上一个 RL 算法。—埃莫·托多洛夫********![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/a322fb12a155612a7649ac6753fae454.png)********Left: Shaky Control — Right: Smooth Control using the proposed technique********如果到目前为止你应用了所介绍的方法,它将会起作用:赛车将会停留在赛道上,并且会试着跑得更快。然而,**你很可能会以一个不稳定的控制结束:**汽车会如上图所示振荡,因为它没有动力不这样做,它只是试图最大化它的回报。***********滑控制的解决方案是约束转向角的变化,同时用先前命令的历史增加输入**(转向和油门)。这样,*你就能在转向中保持连贯性。*********举例来说,如果当前汽车转向角度为 0,并且它突然尝试以 90°转向,则连续性约束将仅允许它以 40°转向。因此,两个连续转向命令之间的差异保持在给定的范围内。这种额外的约束是以多一点培训为代价的。********在找到令人满意的解决方案之前,我花了几天时间试图解决这个问题**,以下是我尝试过但没有成功的方法**:*****   ****输出相对转向而不是绝对转向:产生较低频率的振荡****
*   ****添加一个连续性惩罚(惩罚机器人转向的高变化):机器人没有优化正确的事情,它有时会工作,但后来不会留在轨道上。如果惩罚的成本太低,它就忽略它。****
*   ****限制最大转向:在急转弯时,汽车不能再停留在赛道上****
*   ****[堆叠几帧](https://danieltakeshi.github.io/2016/11/25/frame-skipping-and-preprocessing-for-deep-q-networks-on-atari-2600-games/)以给出一些速度信息:产生较低频率的振荡********注:最*,[苏黎世联邦理工学院的研究人员](http://robotics.sciencemag.org/content/4/26/eaau5872)建议利用课程学习进行持续的节能控制。这可能是第二个解决方案(尽管有点难以调整)。****## ****概述该方法********在我们的方法中,我们将策略学习从特征提取中分离出来,并添加一个额外的约束来*滑控制。********首先,人类通过手动驾驶汽车来收集数据(手动驾驶约 5 分钟可获得 10k 张图像)。这些图像被用来训练 VAE。********然后,我们在探索阶段(使用随机策略)和策略培训(当人类将汽车放回赛道以优化花费的时间时完成)之间交替。********为了训练该策略,首先使用 VAE(这里具有 64 维的潜在空间)对图像进行编码,并将其与最*十次采取的动作(油门和转向)的历史连接,从而创建 84D 特征向量。********控制策略由神经网络(32 和 16 个单元的两个全连接层,具有 ReLU 或 eLU 激活功能)表示。********该控制器输出转向角和油门。我们将油门限制在给定的范围内,并且还限制了当前转向角和先前转向角之间的差异。****## ****结论********在这篇文章中,我们提出了一种方法,只使用一个摄像头,在几分钟内学习驴车的*稳控制策略。********由于该方法旨在应用于现实世界,这肯定是我在这个项目中的下一步:在一辆真实的 RC 汽车上测试该方法*(见下文)。这将需要缩小 VAE 模型(政策网络已经很小了),以便让它在树莓派上运行。********今天到此为止,不要犹豫测试代码,评论或提问,记住,分享是关怀;)!********* Roma Sokolkov 在一辆真实的遥控汽车上复制了 wayve.ai 方法[,但是这不包括*滑控制的最新改进](https://www.youtube.com/watch?v=6JUjDw9tfD4)****## ****感谢********如果没有 [Roma Sokolkov](https://github.com/r7vme/learning-to-drive-in-a-day) 对 Wayve.ai 方法的重新实现、 [Tawn Kramer](https://github.com/tawnkramer) 的驴车模拟器、 [Felix Yu](https://flyyufelix.github.io/2018/09/11/donkey-rl-simulation.html) 的博客文章获得灵感、 [David Ha](https://github.com/hardmaru/WorldModelsExperiments) 在 VAE 的实现、 [Stable-Baselines](https://github.com/hill-a/stable-baselines) 及其 [model zoo](https://github.com/araffin/rl-baselines-zoo) 用于 SAC 实现和训练脚本、用于遥控操作的[赛车机器人项目](https://github.com/sergionr2/RacingRobot)和[就不可能完成这项工作](https://github.com/araffin/robotics-rl-srl)********我也想感谢罗马,塞巴斯蒂安,塔恩,佛罗伦萨,约翰内斯,乔纳斯,加布里埃尔,阿尔瓦罗,阿瑟和塞尔吉奥的反馈。****## ****附录:学习状态表示*********潜在空间维度和样本数的影响*********VAE 的潜在空间维度只需要足够大,以便 VAE 能够重建输入图像的重要部分。例如,64D 和 512D VAE 之间的最终控制策略没有巨大差异。********重要的不是样本的数量,而是样本的多样性和代表性。如果你的训练图像没有覆盖所有的环境多样性,那么你需要更多的样本。********我们能从随机特征中学习控制策略吗?********我试图在初始化后立即修正 VAE 的权重,然后学习关于那些随机特征的策略。然而,这并没有奏效。*********与像素学习的比较*********我没有时间(因为我的笔记本电脑没有 GPU)来比较直接从像素学习策略的方法。然而,如果有人能使用我的代码库做到这一点,我会对结果感兴趣。*********有效的最低限度政策是什么?*********单层 mlp 有效。我也尝试了线性策略,但是,我没有成功地获得一个好的控制器。********# 学习用价值迭代网络进行计划> 原文:<https://towardsdatascience.com/learning-to-plan-with-value-iteration-networks-5768e80df2c3?source=collection_archive---------15----------------------->## 可以学习模仿规划算法的神经网络**被动策略**深度强化学习的第一个主要成就是著名的 DQN 算法在各种雅达利视频游戏中的人类水*表现,其中一个神经网络使用原始屏幕像素作为输入来学习玩游戏。在强化学习中,我们希望学习一种将状态映射到行动的**策略**,这样可以最大化累积的回报。例如,在 DQN 的论文中,神经网络是一种卷积神经网络,它将屏幕图像作为输入,并输出可能行为的得分。虽然强化学习算法被设计成使得该策略应该学习挑选具有长期益处的动作,但是我们从我们的策略获得的信息仅适用于当前状态。这被称为**反应策略**,这是一种将当前状态映射到应该立即采取的行动的策略,或者映射到行动的概率分布**。**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/1e2f9f50c0659f7cb0cf18bffbb67f43.png)[source](http://: http://karpathy.github.io/assets/rl/policy.png)虽然反应性政策主导了大多数强化学习文献,并导致了一些惊人的和广为人知的成就,但有时我们需要从我们的政策中获得更丰富的答案,而当前推荐的行动是不够的。有时,我们的应用程序要求我们能够比单一步骤看得更远,并验证我们的策略将带我们走上一条“安全”的轨道,这要受到我们系统的其他组件的审查。在这种情况下,与其采取当前最好的行动,我们更想要的是一个完整的计划,或者至少是一个特定的未来计划。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/5268986e831b31ac38da235145736780.png)[source](https://cdn-images-1.medium.com/max/1000/1*umJ5XJ3PS828PE0cr8nCmg.png)但是,如果我们伟大的 RL 算法可以学习非常好的反应策略,我们为什么要为一个完整的计划费心呢?一个可能的原因是,RL 策略在成功学习任务之前通常需要大量的尝试,因此通常在模拟环境中训练,在模拟环境中,策略可以尽可能多地撞车,或者射击友军,如果失败就再试一次。模拟并不是真实世界的完美呈现,尽管存在这些差异,我们还是希望我们的系统能够正常工作,这是 RL 代理人[所知的与](https://arxiv.org/pdf/1812.02341.pdf)斗争的事情。拥有一个完整的计划可以让我们使用外部知识来评估它,并防止采取危险的行动。例如,如果一辆自动驾驶汽车希望改变车道,但突然有一辆汽车非常快地接*,比训练期间模拟汽车的速度还快,则外部程序可以预测当前计划的轨迹将会发生碰撞,并中止操纵。对于被动的政策来说,这要困难得多,因为在这种情况下,可能很难预测该情景在结束之前会如何结束。渴望一个完整计划的另一个原因是,它可能使我们的政策执行得更好。也许通过迫使它提前计划,我们可以约束我们的政策更加一致,并能够更好地适应看不见的情况,这就是我们想要的。**马尔可夫决策过程**规划问题的一个非常常见的模型是马尔可夫决策过程,或 MDP。在 MDPs 中,我们将世界定义为一组**状态** S,一组可能的**动作**采取 A,一个**奖励函数** R 和一个**转换模型** P。它们一起构成元组:![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/d46a751284cc737fa978a2c84a98ceaf.png)它定义了 MDP。让我们看一个具体的例子:![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/cc380a77d606809e8a5150e832851def.png)[source](https://i.stack.imgur.com/jkJ5b.png)在这个例子中,一个代理人必须在 2D 地图上导航并到达绿色方块,因为绿色方块它会得到+1 奖励,并且避免红色方块,如果踩到红色方块它会受到-1 奖励的惩罚。其余状态不返回奖励(或等价地返回 0)。按照我们对 MDP 的定义,州是地图上除了黑色瓦片以外的瓦片集合,黑色瓦片是一个障碍。这组动作是四个方向,转移概率由右图给出。假设采取了特定的动作,转换模型指定了从当前状态转换到另一个状态的概率。在我们的例子中,如果我们的代理选择向上的动作,它将有 80%的机会向上移动,10%的机会向左或向右移动。如果代理选择正确的动作,它有 80%的机会向右移动,10%的机会向上或向下移动。假设我们的代理位于地图的左下角,并且必须安全地导航到绿色方块。必须区分规划**轨迹**还是寻找**政策**。如果我们计划一个轨迹,我们会得到一个序列,指定应该采取行动的顺序,例如:(**上,上,右,右,右**)。如果我们的问题是确定性的,并且选择一个方向将有 100%的机会将我们的代理移动到那个方向,那么这将对应于轨迹:![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/405c410d84b3bc51158ff2e3164535b8.png)edited from: [source](https://mpatacchiola.github.io/blog/images/reinforcement_learning_example_r004.png)然而,由于我们的问题是不确定的,我们可能会偏离我们想要走的道路,这一系列的行动对我们来说是不够的。我们真正想要的是一个完整的计划,将每个状态映射到期望的动作,就像这样:![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/42a76ef321c05e402d4e114551c340cb.png)[source](https://mpatacchiola.github.io/blog/images/reinforcement_learning_example_r004.png)这实际上正是我们的 RL 策略所代表的,从状态到行动的映射。不同的是,在这个简单的问题中,我们可以把整个状态空间展开,然后观察这个策略。在复杂的现实世界问题中,我们可能知道我们当前的状态,但是计算出未来行动和状态的可能结果可能是不现实的。,尤其是当我们的输入是图像或视频等高维传感器观测数据时。但是回到我们的例子,我们怎样才能找到如上图所示的最优策略呢?这类问题有一个经典的算法叫做**值迭代**。这个算法所做的是计算当前处于某种状态所能获得的长期收益,通过问这个问题“如果我从这种状态开始,我能获得的最佳利润是多少?”。在 MDP 行话中,这个量被称为状态**值**,直观地看,如果我们知道每个状态的**值**,我们可以尝试总是移动到具有更高**值**的状态,并获得它们承诺的好处。假设我们知道问题中所有状态的最优值;V*(s),我们现在可以定义从我们的状态采取一个具体行动的价值,并从此采取最优行动;Q*(s,a)。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/0cea3a623a28bfa4521f35d064ec65a2.png)状态-行动值是除了下一个状态的最优值之外,我们在这个状态采取行动得到的回报。但是,由于我们的问题是随机的,我们必须对它有一个预期,以便考虑到达未来状态的不同概率。但是由于 V*(s)是我们可以从当前状态获得的最佳值,这意味着这个等式必须成立:![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/12c082416a7f1854faec4b6ad90a33ea.png)这给出了最优值函数的递归定义:![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/ac11e40a9d385de05439c80ac98cb160.png)如果我们为每个状态猜测一个值,并且证明这个递归方程对所有状态都是满足的,我们**知道**我们有一个最优值函数。但除此之外,我们可以猜测我们状态的任何初始值函数,并使用我们的方程来更新它,如下所示:![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/c3b7e9ddee62984ed48d1f1537d04614.png)通过使用一些数学方法,我们甚至可以证明,如果在每次迭代中,我们对问题中的所有状态都这样做,最终我们的价值函数将收敛到最优价值函数。一旦我们有了最优价值函数,我们就可以很容易地提取最优策略:![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/5bb44ba093bc868c560879e93999b648.png)这整个过程被称为**值迭代**。但是这显然不能用于复杂的问题,在这些问题中,我们甚至无法获得转换模型的描述,甚至可能无法获得回报函数,那么我们如何将它用于更有趣的问题呢?**价值迭代网络**伯克利的研究人员在 NIPS 2016 上发表了一篇非常有趣的论文(他们因此获得了最佳论文奖),试图以一种非常优雅的方式解决这个问题,即赋予神经网络在其内部执行类似过程的能力。想法是这样的:因为我们并不真正知道我们真正问题的潜在 MDP,我们可以让我们的神经网络学习一些其他的 MDP,这与真正的不同,但为真正的问题提供了有用的计划。他们在一个 2D 导航问题上演示了他们的方法,其中输入是包含目标位置和障碍的地图图像。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/32783012470b47ac7945906e880be9db.png)[source](https://arxiv.org/pdf/1602.02867.pdf)输入图像被馈送到卷积神经网络,该网络输出相同大小的图像,该图像表示地图中不同位置的“回报”,并被馈送到另一个 CNN,该 CNN 将其映射到初始值地图。然后,对于 M 次迭代,卷积层被应用于连接的值和回报图像,以产生 Q 值图像,其具有 K 个通道,每个通道表示学习的 MDP 中的“动作”。最大池是沿着通道的维度执行的,本质上执行的操作与我们在上一节中看到的值迭代算法非常相似。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/ec3e021faf83b078061e171fcac472ec.png)[source](https://arxiv.org/pdf/1602.02867.pdf)最终的价值图(或者它的特定部分)被提供给一个反应策略,该策略选择在我们的实际问题中执行的动作。值得注意的是,在任何阶段,模型都不会被赋予真实回报图或价值图的基础事实标签,我们只是希望通过学习使用这个价值迭代网络(VIN)来行动,我们的神经网络将**学习** **成为有用的 MDP** 。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/aa2a2c2e28891ce6e25ed70d7f4f6b99.png)[source](https://arxiv.org/pdf/1602.02867.pdf)这整个模型要么通过使用给定轨迹的模仿学习来训练,要么通过从头开始的强化学习来训练,结果证明,结果确实非常棒:![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/8f99eed04bc6dd68ee933d6fe5970a16.png)[source](https://arxiv.org/pdf/1602.02867.pdf)在没有给它们的情况下,神经网络学习了奖励和价值图,它们看起来正是我们认为它们应该是的。奖励地图在目标位置及其附*具有高值,在障碍物处具有负值。值图似乎有一个梯度,将点引向目标位置并远离障碍物,这非常有意义。虽然这个 2D 导航任务看似简单,但实际上看似困难。在一组训练地图上训练一个标准的 CNN 策略是可行的,但是对于看不见的地图的泛化能力相对较差。使用 VIN,作者显示了对不可见地图的更好的概括能力。除了简单的网格世界导航任务,他们还展示了使用月球表面高程图像的导航问题的算法,其中月球车必须在不可穿越的特征中安全导航,以及使用自然语言输入的网络导航问题。我发现非常令人惊讶的是,模型可以完全从图像输入中学习这些,我们可以将这一成功归因于架构产生的固有归纳偏差,这迫使模型以类似于规划算法的方式执行计算。从那时起,这项工作已经得到了改进,并扩展到了更一般的领域,如图形,但仍然是一个令人印象深刻的成就。# 学习以每秒 100 万帧的速度玩蛇> 原文:<https://towardsdatascience.com/learning-to-play-snake-at-1-million-fps-4aae8d36d2f1?source=collection_archive---------15----------------------->## 用优势耍蛇演员兼评论家![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/31abdbde45caba0a5e61fb5f3d22c968.png)在这篇博文中,我将向你介绍我最*的项目,它结合了我觉得很有趣的两件事——电脑游戏和机器学习。很长一段时间以来,我一直想掌握深度强化学习,我认为没有比做自己的项目更好的方法了。为此,我用 PyTorch 实现了经典的手机游戏“Snake ”,并训练了一个强化学习算法来玩这个游戏。这篇文章分为三个部分。1.  贪吃蛇游戏的大规模并行矢量化实现
2.  《优势演员——批评家》解读(A2C)
3.  结果:分析不同药剂的行为![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/9702679370f94aaa34dffc0b777360ce.png)本项目的代码可在 https://github.com/oscarknagg/wurm/tree/medium-article-1获得# Snake —矢量化尽管取得了令人印象深刻的成就,深度强化学习仍然非常缓慢。像 DotA 2 和星际争霸这样的复杂游戏已经取得了令人难以置信的成绩,但这些都需要数千年的游戏时间。事实上,即使是引发当前对深度强化学习(即学习玩 Atari 游戏)兴趣的工作,也需要数周的游戏时间和每场游戏数亿帧的画面。从那以后,在通过并行化和改进的实现来加速深度强化学习方面,以及在样本效率方面,已经进行了大量的研究。许多先进的强化学习算法同时在一个环境的多个副本中被训练,通常每个 CPU 核心一个。这产生了一个大致线性的速度,你可以用更多的 CPU 内核产生游戏体验的速度。因此,为了试验深度强化学习,你最好有大量的计算资源。一个非常快速/并行的环境或愿意等待很长时间。由于我没有访问大型集群的权限,并且希望快速看到结果,所以我决定创建一个矢量化的 Snake 实现,它可以实现比 CPU 内核数量更高级别的并行化。## 什么是矢量化?矢量化是单指令多数据(SIMD)并行的一种形式。对于那些 Python 程序员来说,这就是 numpy 运算通常比执行相同计算的显式 For 循环快几个数量级的原因。基本上,矢量化是可能的,因为如果处理器可以在一个时钟周期内对 256 位数据执行操作,而您的程序的实数是 32 位单精度数,那么您可以将这些数中的 8 个打包到 256 位中,并在每个时钟周期内执行 8 次操作。因此,如果一个程序足够聪明,能够在正确的时间调度指令,使得总是有 8 个操作数在适当的位置,那么理论上,它应该能够比一次对一条数据执行指令实现 8 倍的加速。## 实现:表示环境![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/ada214c3d1cc83c361ff3119fba537f7.png)关键思想是将环境的完整状态表示为单个张量。事实上,多个环境被表示为单个 4d 张量,其方式与表示一批图像的方式相同。在蛇的情况下,每个图像/环境有三个通道:一个用于食物颗粒,一个用于蛇头,一个用于蛇身,如上所示。这样做可以让我们利用 PyTorch 已经拥有的许多特性和优化来处理这类数据。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/9a7bba8ebe6eb1a9598257ddba056b73.png)The example above rendered with a black border. This is a smaller version of the input given to the agent.## 实现:移动蛇所以现在我们有了一种表示游戏环境的方法,我们需要只使用矢量化张量运算来实现游戏。第一个技巧是,我们可以在每个环境中移动所有蛇头的位置,方法是用手工制作的过滤器对环境张量的头部通道应用 2D 卷积。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/56ab2e331e15f23a6871eeb1ee3823be.png)然而 PyTorch 只允许我们对整批应用相同的卷积滤波器,但我们需要能够在每个环境中采取不同的行动。因此,我应用了第二个技巧来解决这个限制。首先将 4 个输出通道(每个运动方向一个)的卷积应用到每个环境,然后使用非常有用的 [torch.einsum](https://pytorch.org/docs/stable/torch.html?highlight=einsum#torch.einsum) 使用一个动作的热键向量来“选择”正确的动作。我强烈推荐阅读[这篇](https://rockt.github.io/2018/04/30/einsum)文章,它很好地介绍了爱因斯坦求和及其在 NumPy/PyTorch/Tensorflow 中的应用。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/f25410e1996636d7f62ad53767f47a62.png)The full head movement procedure. See [this gist](https://gist.github.com/oscarknagg/863602483afc83d698ce399a67eb21d4) for a minimal implementation.现在我们移动了头部,我们需要移动身体。首先,我们通过从所有身体位置减去 1 来向前移动尾部(即身体上的 1 位置),然后应用 ReLu 函数来保持其他元素大于 0。其次,我们复制头部通道,乘以最大身体值加 1。然后,我们将这个副本添加到头部通道,为身体创建一个新的前位置(图中的位置 8)。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/9dc0f50965a0f491491e729d0f522e6a.png)Body movement procedure. The input action is left. See [this gist](https://gist.github.com/oscarknagg/627dbcfe020cc63dd47d57e1cf6b076c) for a minimal implementation.需要更多的逻辑,例如检查碰撞和食物收集,在死后重置环境,以及检查蛇是否试图向后移动——以跨多个环境矢量化的方式实现这一切的方法非常有趣。所有这些优化的最终结果如下图所示。使用单个 1080Ti 和大小为 9 的环境,我可以使用随机代理每秒运行超过一百万步的最大值,而使用 A2C 训练卷积代理每秒运行超过 70,000 步(使用与后面结果相同的超参数)。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/76bb8388dc93c1064bdd06e1eaa3a1f3.png)Clickbait title — justified [✓] not justified [ ]# 最佳演员兼评论家(A2C)*在本节中,我假设您熟悉强化学习的基本术语,例如价值函数、政策、奖励、回报等……*演员-评论家算法背后的想法很简单。你训练一个行动者网络,将观察到的状态映射到行动(即策略)的概率分布。这个网络的目的是学习在特定的状态下应该采取的最佳行动。同时,你也训练了一个从状态映射到期望值的批判网络,即处于这种状态后预期的未来回报的总和。这个网络的目的是学习处于某一特定状态是多么令人向往。这个网络还通过为状态提供基线值来稳定策略网络的学习,我们将在后面看到。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/29d7254ac3bc93d76689f79342b46ae2.png)Table of symbols to make reading the following part easier.## 价值函数学习价值函数的损失是特定状态的预测值和从该状态产生的实际回报之间的*方差。因此,价值函数学习是一个回归问题。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/b76cb99ff606690bed1ec90b2c4e9971.png)在实践中,计算特定状态的真实回报需要从该状态开始直到时间结束的轨迹,或者至少直到代理人死亡。由于有限的计算资源,我们计算来自固定有限长度 T 的轨迹的回报,并使用自举来估计最终轨迹状态之后的遥远回报。Bootstrapping 是指我们用轨迹中最终状态的预测值替换总和的最后一部分——模型的预测被用作其目标。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/f8125aed7b5c08440b6f86fa53476fc5.png)## 政策学习在强化学习领域有一个重要的结果被称为策略梯度定理。这表明,对于参数化策略(例如,从状态到动作的神经网络映射),其参数存在梯度,*均而言,这导致策略性能的提高。策略的性能被定义为该策略所访问的状态分布的期望值,如下所示。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/42e0a7a25354b55fae2192d782bd069d.png)The loss function maximised by the policy gradient.这实际上是一个比乍看起来更令人惊讶结果。给定一个特定的状态,计算改变策略参数对行为的影响以及相应的回报是相对简单的。然而,我们感兴趣的是策略所访问的州的分布中的期望回报,这也将随着策略参数而改变。改变策略对状态分布的影响通常是未知的。因此,当性能取决于政策变化对状态分布的未知影响时,我们可以计算性能相对于政策参数的梯度,这是非常值得注意的。下面显示的是策略梯度算法的一般形式。这个定理的证明和完整的讨论超出了范围,但是如果你有兴趣深入研究,我推荐萨顿和巴尔托的《强化学习:导论》的第 13 章。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/81f6e53972d5104626dd75fe3712a5db.png)利用一点数学知识,我们可以把它写成对我们的策略所访问的状态和动作的期望。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/e999126a5be3070b424f6c0a480bced9.png)这个表达式更容易得到一个直觉。期望中的第一部分是政策所看到的状态-动作对的 Q 值,即性能测量。第二部分是增加特定动作的对数概率的梯度。直觉上,总体政策梯度是增加高回报行为概率的个体梯度的期望。相反,如果 Q(s,a)为负(即不良行为),那么各个梯度必须降低这些行为的概率。如前所述,对政策梯度定理的一个重要认识是,如果将任意的独立于动作的基线 *b(s)* 添加到 Q 函数中,它不会改变。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/cec6491d2321bb87266b0e7372463102.png)添加这个基线函数给策略梯度引入了一个新的项,假设它是独立于动作的,则总是等于 0。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/8bc5ba3406a20c68361523b64614620e.png)尽管添加基线不会影响政策梯度的*预期*,但它会影响其*方差*,因此一个精心选择的基线可以加快学习一个好政策的速度。A2C 选择的基线是*优势函数*(因此是优势行动者-批评家)。这量化了特定状态-动作对与该状态的*均动作相比有多好。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/654f108ca2f0ed2de1d8a856eab70cc0.png)The advantage function.基于这个表达式,看起来我们需要学习另一个网络来逼* Q(s,a)。然而,我们可以用更简单的方式重写。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/38247f3a7d44c492cbf338cf3e09ee7b.png)我们可以这样做,因为一个特定政策的 Q 函数的定义是在状态 *s* 中行动 *a* 的回报加上在这一集的剩余时间里遵循该政策的预期回报。因此,最终的优势演员-评论家梯度如下。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/d134dfa30573208ccc84a526b66ec468.png)## 整体算法既然我已经勾勒出了 A2C 的理论基础,是时候看看完整的算法了。我们需要获得我们的策略的增量改进的全部是获得样本的方法,使得那些样本的梯度的期望与上面的表达式成比例。这可以非常简单地通过记录我们的政策所产生的经验轨迹来实现。为了加速这一过程,我们可以在同一环境中并行运行我们策略的多个副本,以更快地获得经验。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/05cf62ac29618e698bba1f0711806c7e.png)这是著名的异步优势行动者-批评家算法(A3C)的同步版本。不同之处在于,在 A3C 中,参数更新是在许多工作线程中分别计算的,并用于更新其他线程定期与之同步的主网络。在分批 A2C 中,来自所有工人的经验被周期性地组合以更新主网络。A3C 异步的原因是不同线程中环境速度的差异不会降低彼此的速度。然而,在我的 snake 环境中,环境速度总是完全相等的,因此同步版本的算法更有意义。# 结果现在我已经描述了实现和理论,是时候学习玩蛇了!在我的实验中,我比较了三种不同架构的性能,如下图所示。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/d181a402869186d5d2f57ae3d6d83930.png)第一个代理(左)是 Deepmind 的“[具有关系归纳偏差的深度强化学习](https://openreview.net/pdf?id=HkxaFoC9KQ)”论文中的代理的较小版本。这个代理包含一个“关系模块”,它本质上是来自应用于 2D 图像的[转换器](https://arxiv.org/abs/1706.03762)模型的自我关注机制。此后,我们在值和策略输出之前应用通道式最大池和单个全连接层。为了比较,我还实现了一个卷积代理(中间层),除了关系模块被更多的卷积层取代之外,其他方面都是一样的。作为一个黑马竞争者,我介绍了一个更简单的纯前馈代理(右),它只接受蛇头周围的局部区域作为输入,使环境部分可观察。输入观测值被展*并通过两个前馈层。与其他两个代理一样,值和策略输出是最终激活的线性投影。所有 3 个代理都在 9 号环境中接受了 5 次 5000 万步的训练。具有 1 个标准偏差的训练曲线如下所示。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/35b6523665a99e583ee0b95f9b8e9f60.png)有趣的是,仅具有部分环境可观测性的前馈代理表现非常好,实现了所有代理中最高的*均规模。它也学得最快,可能是因为拥有最小的观察空间。正如你从下面的 GIF 中看到的,它已经学会了通过环绕环境来避免能见度有限的缺点,这样所有的东西最终都会进入视野。这使它能够找到分散在环境中的回报,但不如卷积和关系代理有效。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/5c9d3737c44b251e1afa684236ae0a64.png)The feedforward agent in action其他代理或多或少地直接走向奖励,但也有犯一些愚蠢错误的倾向,这反映在与前馈代理相比相当高的边缘冲突率上。有趣的是,在这个任务中,关系代理的表现并不比卷积代理好。我假设 snake 环境太简单了,关系模块中的归纳偏差没有用。Deepmind 对关系代理进行基准测试的任务涉及收集多个盒子的多个密钥,以便收集最终的大笔奖励——比 snake 复杂得多!![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/94e12832f7f589276bf6c2f9556d138e.png)The convolutional agent in action.## 好处:转移到更大的环境中作为一个额外的实验,我决定看看如果我将代理从较小的 9 号环境转移到较大的 15 号环境会发生什么。我评估了每种类型的代理的 5 个实例在更大的环境中一百万步的性能,没有进一步的培训。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/663baabc8c18e58ad3f0b1e3e8c9c16f.png)Agent performance transferring from size 9 to size 15 environment.此表显示了不同类型的座席代表之间,甚至在特定的训练运行中,转移性能的巨大差异。卷积代理泛化得很好,实现了大的*均规模和高报酬率。事实上,卷积代理比在更大的环境中从头开始训练的相同代理表现得更好。我相信这是因为在更大的环境中奖励更少,所以在更大的环境中学习会明显变慢。可以观察到一些相当聪明的行为。在大型蛇形飞机上,卷积智能体有时会执行一个“盘旋”动作,同时等待它的尾巴移开。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/743e6ff8519d315302e8bbe1e4418822.png)Convolutional agent waiting for its tail to move out of the way.有限可见性代理继续围绕环境边缘的相同策略。这可以很好地执行,直到一个食物团在代理人无法观察到的环境中心产生,从这一点上代理人不再收集奖励。这与上表中的大尺寸小奖励率是一致的。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/1f70c4abc1e2853c7ea53c582cefefd8.png)The limited visibility agent fails to transfer.关系代理的性能至少可以说是不稳定的。在某些运行中,它会执行得相当好,而在其他运行中,它几乎会立即死亡或陷入循环。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/eab812c47c00d877df81382a38202bab.png)Transfer behaviour of the relational agent.在这个项目中,我亲眼目睹了深度强化学习的缓慢,并想出了一个简洁的、尽管是蛮力的方法来绕过它。我还通过观察非常相似的环境之间失败的转移,体验了 deep RL 的脆弱本质。在未来的工作中,我想实现更多的 gridworld 游戏,以研究游戏之间的迁移学习。或者,我可能会实现一个多代理 snake 环境,以便回答 OpenAI 的“slither in”[研究请求](https://openai.com/blog/requests-for-research-2/)。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/9a1db6dbb536a4319adbe3b282afa386.png)Multi-agent slither.io style environment.本项目的*代码位于:*# 学习模拟> 原文:<https://towardsdatascience.com/learning-to-simulate-c53d8b393a56?source=collection_archive---------9----------------------->## 学习如何模拟更好的合成数据可以改善深度学习*在* ***ICLR 2019*** *发表的论文可以在* [*这里*](https://arxiv.org/abs/1810.02513) *。我还有一张* [*幻灯片*](https://docs.google.com/presentation/d/1AEqPi-bJ1q-o1bxosBjcqEgCb2Vs2TcJF6cI4nHZKTg/edit?usp=sharing) *以及一张* [*海报*](https://natanielruiz.github.io/docs/lts_poster.pdf) *详细解释了这项工作。*![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/8392cc2a8b133deba76f2f354ae009a1.png)Photo by [David Clode](https://unsplash.com/@davidclode?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) on [Unsplash](https://unsplash.com/s/photos/brain?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)深度神经网络是一项令人惊叹的技术。有了足够多的标记数据,他们可以学习为图像和声音等高维输入产生非常准确的分类器。*年来,机器学习社区已经能够成功解决诸如分类对象、检测图像中的对象和分割图像等问题。上述声明中的警告是**带有足够的标记数据。对真实现象和真实世界的模拟有时会有所帮助。在[计算机视觉](https://www.di.ens.fr/willow/research/surreal/data/)或[机器人控制应用](https://openai.com/blog/generalizing-from-simulation/)中,有合成数据提高深度学习系统性能的案例。**模拟可以给我们免费标签的精准场景。但是我们就拿侠盗猎车手 V (GTA)来说吧。[研究人员利用了通过自由漫游 GTA V 世界收集的数据集](https://arxiv.org/abs/1608.02192),并一直使用该数据集来引导深度学习系统等。许多游戏设计师和地图创作者都致力于创造 GTA V 的错综复杂的世界。他们煞费苦心地设计它,一条街一条街,然后精细地梳理街道,添加行人,汽车,物体等。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/b718c71238e12dc7d24fcd6332e199fe.png)An example image from GTA V (Grand Theft Auto V)这个很贵。无论是时间还是金钱。使用**随机模拟场景**我们可能不会做得更好。这意味着重要的边缘情况可能严重欠采样,我们的分类器可能不知道如何正确地检测它们。让我们想象我们正试图训练一个检测**危险场景**的分类器。在现实世界中,我们会很少遇到像下面这样的危险场景,但它们非常重要。如果我们生成大量的随机场景,我们将很少有像下面这样的危险场景。对这些重要案例进行欠采样的数据集可能会产生一个对这些案例失败的分类器。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/4ba7664a2a774b51e33686f9c86d38b4.png)Example of a dangerous traffic scene. These important cases can be undersampled when randomly sampling synthetic data. Can we do better?**学习模拟**的想法是,我们可以潜在地学习如何最佳地生成场景,以便深度网络可以学习非常好的表示,或者可以在下游任务中表现良好。为了测试我们的工作,我们使用虚幻引擎 4 和 Carla 插件[创建了一个*参数化程序交通场景模拟器*。我们的模拟器创建了一条具有不同类型十字路口(X、T 或 L)的可变长度的道路。我们可以在道路上放置建筑物,并在道路上放置 5 种不同类型的汽车。建筑物和汽车的数量由可调参数以及汽车的类型控制。我们还可以在 4 种不同的天气类型之间改变天气,这 4 种天气类型控制照明和雨的效果。主要思想是学习控制不同任务(例如语义分割或对象检测)的这些场景特征的最佳参数。](http://carla.org)A demo of our procedural scene simulator. We vary the length of the road, the intersections, the amount of cars, the type of cars and the amount of houses. All of these are controlled by a set of parameters.为了获得传感器数据,我们在我们生成的场景的道路上放置一辆汽车,它可以从生成的场景中捕获 RGB 图像,这些图像自动具有语义分割标签和深度注释(免费!).An inside view of the generated scenes from our simulator with a fixed set of parameters但是,模拟算法的学习比这更一般。我们不必将它专门用于交通场景,它可以应用于*任何类型的参数化模拟器*。我们的意思是,对于任何将参数作为输入的模拟器,我们提供了一种搜索最佳参数的方法,使得生成的数据对于深度网络学习下游任务是最佳的。据我们所知,我们的工作是首先进行**模拟优化,以最大限度地提高主要任务**的性能,以及**将其应用于交通场景**。**继续我们算法的关键点**。传统的机器学习设置如下,其中数据从分布 P(x,y)中采样(x 是数据,y 是标签)。这通常是通过在现实世界中收集数据并手动标记样本来实现的。这个数据集是固定的,我们用它来训练我们的模型。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/421bde21aca34ecffb0886fba4f5f276.png)Traditional machine learning setup通过使用模拟器来训练主任务网络,我们可以从模拟器定义的新分布 Q 中生成数据。这个数据集不是固定的,只要计算和时间允许,我们可以生成尽可能多的数据。尽管如此,在该域随机化设置中生成的数据是从 Q 中随机采样的**。获得一个好的模型所需的数据可能很大,并且性能可能不是最佳的。**我们能做得更好吗?****![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/83c2da1269e333f7e39250820121bd64.png)我们引入了学习模拟,它优化了我们在主要任务上选择的度量——通过定义与该度量直接相关的奖励函数 R(通常与度量本身相同)来训练流水线。我们从参数化模拟器 Q(x,y |θ)中采样数据,用它在算法的每次迭代中训练主任务模型。然后,我们定义的奖励 R 用于通知控制参数θ的策略的更新。通过在验证集上测试训练好的网络来获得奖励 R。在我们的例子中,我们使用普通的策略梯度来优化我们的策略。非正式地说,我们试图找到最佳参数θ,它给出了分布 Q(x,y |θ),使主要任务的精度(或任何度量)最大化。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/23a6a406cbaf4e38e015d644146bd82a.png)Learning to simulate setup学习模拟问题的数学公式是一个双层优化问题。试图用基于梯度的方法来解决它对较低层次的问题提出了光滑性和可微性约束。在这种情况下,模拟器也应该是可微的,这通常是不正确的!这就是为什么像香草政策梯度这样的无导数优化方法是有意义的。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/155a1598d304358532770b7fb854bcd0.png)Mathematical formulation of the bi-level learning to simulate optimization problem我们在**实例计数**和**语义分割**上演示我们的方法。我们研究的汽车计数任务很简单。我们要求网络计算场景中每种特定类型的汽车数量。下面是一个右侧带有正确标签的示例场景。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/56ec8c35ec271b00d880db9c06be4cdb.png)Car counting task example我们使用**学习来模拟**来解决这个问题,并与仅使用**随机模拟**的情况进行比较。在下图中,关注**红色和灰色**曲线,它们显示了学习模拟(LTS)如何在 250 个时期后获得更高的回报(计数车辆的*均绝对误差更低)。随机抽样的情况会有短暂的改善,但是一旦抽样的随机批次不足以完成任务,性能就会下降。灰色曲线在几次迭代中缓慢上升,但是学习模拟**收敛于蓝色曲线**所示的最佳可能精度(这里我们使用地面真实模拟参数)。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/d25de497cdec111878d0cf893ba289fa.png)Reward for the car counting task. Note how learning to simulate converges to the best possible reward (on a simulated dataset) shown by the blue curve.发生了什么事?一个很好的方法是通过可视化我们场景中不同场景和物体的概率。我们绘制了一段时间内的天气概率。我们生成的地面实况验证数据集对某些天气(晴朗的正午和晴朗的日落)进行了过采样,而对其余天气进行了欠采样。这意味着与其他类型的天气相比,有更多清晰的中午和清晰的日落天气的图像。我们可以看到,我们的算法恢复了粗略的比例!![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/207d80023c99c10c1783ebe133c94c7f.png)Weather probabilities (logits) over time让我们对汽车产卵概率做同样的事情。我们的地面实况数据集对某些类型的汽车(银色日产和绿色甲壳虫)进行了过度采样。学习模拟也反映了训练后的这些比例。本质上,该算法推动模拟器参数生成类似于地面真实数据集的数据集。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/6fb606d809a2aa1634a06d06822807e6.png)Car probabilities (logits) over time现在,我们展示一个示例,说明学习模拟如何提高在 [KITTI 交通分割数据集](http://www.cvlibs.net/publications/Geiger2013IJRR.pdf)上进行随机模拟的准确性,该数据集是在现实世界中捕获的数据集**。**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/3d2724a0badb4f684a8a3b5078484416.png)An example image from the KITTI dataset.![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/c91e74330190f4b0d3126ea79a09982f.png)An example of ground-truth semantic segmentation labels on our simulator. In a simulator, you can get object labels for free — no need for a human annotator作为我们的基线,我们分别训练主任务模型 600 次,模拟器使用不同的随机参数集为每个模型生成数据。我们监控每个网络的验证 Car IoU 指标,并选择验证奖励最高的网络。然后我们在*看不见的 KITTI 测试设备*上测试它。我们训练学习以模拟 600 次迭代,并获得汽车 IoU(广泛分割度量)的 **0.579,**远高于使用随机参数基线(random params)获得的 **0.480** 。我们还使用另一种无导数优化技术(随机搜索)展示了我们的结果,这种技术在本实验中没有获得好的结果(尽管它在汽车计数中工作得相当好)。最后,我们还通过在 982 个带注释的真实 KITTI 训练图像(KITTI 训练集)上进行训练来展示我们用于分割的 ResNet-50 网络的实际性能,以展示上限。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/b41a2a764b6ac0c4f76c6a0e60798e70.png)Results for semantic segmenation on the unseen KITTI test set for car semantic segmentation学习模拟可以被视为元学习算法,其调整模拟器的参数以生成合成数据,使得基于该数据训练的机器学习模型分别在验证和测试集上实现高精度。我们证明它在实际问题中胜过领域随机化,并且相信它是一个非常有前途的研究领域。在不久的将来,看到这方面的扩展和应用会发生什么将是令人兴奋的,我鼓励每个人都来看看模拟和学习模拟如何帮助你的应用或研究。欢迎所有问题!我的网站在下面。[](https://natanielruiz.github.io) [## 纳塔尼尔·鲁伊斯### 研究我探索了计算机视觉的几个课题,包括面部和手势分析,模拟和…natanielruiz.github.io](https://natanielruiz.github.io)# 使用强化学习从头开始学习解魔方> 原文:<https://towardsdatascience.com/learning-to-solve-a-rubiks-cube-from-scratch-using-reinforcement-learning-381c3bac5476?source=collection_archive---------11----------------------->![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/da038eab6d9d9c57070a58261cb483bb.png)Photo by [Olav Ahrens Røtne](https://unsplash.com/@olav_ahrens?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) on [Unsplash](https://unsplash.com/s/photos/rubik?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)# 动机:![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/5d143d14fa49e262853dca0957d82b6c.png)魔方是一种有 6 个面的 3D 拼图,每个面通常有 9 个 3×3 布局的贴纸,拼图的目标是达到每个面只有一种独特颜色的已解状态。一个 3x3x3 魔方的可能状态有[万亿次](https://en.wikipedia.org/wiki/Quintillion)的数量级,其中只有一个被认为是“已解”状态。这意味着任何试图解立方体的强化学习代理的输入空间都是 huuuuuge。# 数据集:我们使用 python 库 [pycuber](https://github.com/adrianliaw/pycuber) 来表示一个立方体,并且只考虑四分之一旋转(90°)移动。这里没有使用注释数据,所有样本都是作为一个状态序列生成的,该序列从已解状态开始,然后被反转(以便它进入已解状态),然后这些序列就是用于训练的序列。# 问题设置:![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/64d0ca44bc817568cdd736905911468b.png)Flattened Cube从一个像上面例子一样的随机洗牌的立方体中,我们想要学习一个模型,它能够从集合{**‘F’**:0,**‘B’**:1,**‘U’**:2,**‘D’**:3,**‘L’**:4,**‘R’**:5,**【F’**:6, **"L'"** : 10, **"R'"** : 11} *(定义见*[*【https://ruwix.com/the-rubiks-cube/notation/】*](https://ruwix.com/the-rubiks-cube/notation/)*)*进入如下所示的求解状态:![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/6fdf450faa472e45e9ff59e8176fe8c1.png)Flattened solved Cube# 型号:这里实现的想法大多来自论文[在没有人类知识的情况下解魔方](https://arxiv.org/abs/1805.07470)![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/2c4c6df1317b71ecb7c058e18337f700.png)Figure from “Solving the Rubik’s Cube Without Human Knowledge” by McAleer et al.所实施的 RL 方法被称为自动教学迭代或 ADI。如上图所示(来自论文)。我们通过从已解决状态往回走来构建到已解决状态的路径,然后我们使用完全连接的网络来学习路径中每个中间状态的“策略”和“值”。学习目标被定义为:![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/7197b6f5f42d62e44741bb58dd268af9.png)其中“A”是引言中定义的所有 12 个可能动作的变量,R(A(x_i,A))是通过从状态 x_i 采取动作 A 获得的回报。如果我们到达已解决状态,我们定义 R = 0.4,否则为-0.4。奖励是网络在训练期间得到的唯一监督信号,该信号可能被多个“动作”决策延迟,因为具有正奖励的唯一状态是最终解决的状态。在推理时,我们使用价值策略网络来指导我们对已解决状态的搜索,以便我们可以通过减少“值得”采取的行动的数量来在尽可能短的时间内解决难题。# 结果:我用这个实现得到的结果并不像论文中呈现的那样壮观。据我所知,这个实现可以很容易地解决离已解决状态 6、7 或 8 步的立方体,但在此之后就困难多了。
网络运行示例:![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/47b10b18eecde6b20e1ca109e5d173b2.png)# 结论:这是强化学习的一个非常酷的应用,用来解决一个组合问题,其中有大量的状态,但没有使用任何先验知识或特征工程。重现结果的代码可在:[https://github.com/CVxTz/rubiks_cube](https://github.com/CVxTz/rubiks_cube)获得# 如何在 Python 中使用进度条> 原文:<https://towardsdatascience.com/learning-to-use-progress-bars-in-python-2dc436de81e5?source=collection_archive---------3----------------------->## 4 个不同库的介绍(命令行和用户界面)![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/f86b50a37d1eebba351acc736b298337.png)Photo by [Arget](https://unsplash.com/@arget?utm_source=medium&utm_medium=referral) on [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral)![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/532fbd0fc6fc44400c146f06317f40c3.png)Types of bars from ProgressBar (gif from the library’s page)# 进度条太棒了进度条是一个可视化的表示,表示一个过程还剩下多长时间才能完成。它们让您不必担心进程是否已经挂起,或者试图预测您的代码进展如何。您可以实时直观地看到脚本的进展情况!如果你以前从未想过或使用过进度条,很容易认为它们会给你的代码增加不必要的复杂性,并且很难维护。这与事实相去甚远。在短短几行代码中,我们将看到如何在命令行脚本和 PySimpleGUI UIs 中添加进度条。# 使用进度第一个要回顾的 python 库是 *Progress。*你需要做的就是定义你期望做的迭代次数,bar 的类型,并在每次迭代时让 bar 知道。```
import time
from progress.bar import IncrementalBarmylist = [1,2,3,4,5,6,7,8]bar = IncrementalBar('Countdown', max = len(mylist))for item in mylist:bar.next()time.sleep(1)bar.finish()
```返回:![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/9e1ce59b2d2d1656672450b46d408be6.png)Incremental Bar of Progressbar如果你不喜欢进度条的格式,有很多供你选择:![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/532fbd0fc6fc44400c146f06317f40c3.png)Types of bars from ProgressBar (gif from the library’s page)别忘了查看他们的[文档](https://pypi.org/project/progress/1.5/)。# 使用 tqdm在我们的评论中,下一个是 *tqdm* 库。> Python 和 CLI 的快速、可扩展进度条就像前面的库一样,我们已经看到,通过几行代码我们可以引入一个进度条。在设置方面只有一点不同:```
import time
from tqdm import tqdmmylist = [1,2,3,4,5,6,7,8]for i in tqdm(mylist):time.sleep(1)
```给了我们:![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/06236d24bd7eafe2b095aa2ca5fbecdc.png)和以前一样,酒吧也有一些选择。务必检查[文档](https://github.com/tqdm/tqdm)。# 使用实时进度顾名思义,这个库试图让进度条活起来。它比我们之前看到的进度条多了一些动画。然而,就代码而言,它们非常相似:```
from alive_progress import alive_bar
import timemylist = [1,2,3,4,5,6,7,8]with alive_bar(len(mylist)) as bar:for i in mylist:bar()time.sleep(1)
```酒吧看起来像预期的那样:![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/b73d67a6c1e787438de2d21a18837fa2.png)再一次,不要忘记探索图书馆的[不同特性](https://github.com/rsalmei/alive-progress)。# 使用 PySimpleGUI 的图形进度条本着我们到目前为止所看到的同样的精神,我们可以添加一行代码来获得命令行脚本的图形化进度条。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/b88824829d058428be6b177f33871839.png)为了实现上述目标,我们需要的是:```
import PySimpleGUI as sg
import timemylist = [1,2,3,4,5,6,7,8]for i, item in enumerate(mylist):sg.one_line_progress_meter('This is my progress meter!', i+1, len(mylist), '-key-')time.sleep(1)
```*感谢* [*麦克*](https://medium.com/u/bc85c7e63ea3?source=post_page-----2dc436de81e5--------------------------------) *指出这一点!*# PySimpleGUI 应用程序中的进度条如果你一直关注我最*的博客,我们探索了如何[快速启动 Python UI](/learn-how-to-quickly-create-uis-in-python-a97ae1394d5),然后我们构建了一个带有 UI 的[比较工具。为了继续我们的学习之旅,今天我们将探讨如何集成一个进度条。](/building-a-python-ui-for-comparing-data-13c10693d9e4)用户界面:![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/496fed05d6826193da1b5d3d902b52e7.png)代码:```
import PySimpleGUI as sg
import timemylist = [1,2,3,4,5,6,7,8]progressbar = [[sg.ProgressBar(len(mylist), orientation='h', size=(51, 10), key='progressbar')]
]
outputwin = [[sg.Output(size=(78,20))]
]layout = [[sg.Frame('Progress',layout= progressbar)],[sg.Frame('Output', layout = outputwin)],[sg.Submit('Start'),sg.Cancel()]
]window = sg.Window('Custom Progress Meter', layout)
progress_bar = window['progressbar']while True:event, values = window.read(timeout=10)if event == 'Cancel'  or event is None:breakelif event == 'Start':for i,item in enumerate(mylist):print(item)time.sleep(1)progress_bar.UpdateBar(i + 1)window.close()
```# 结论伙计们,这就是了!只需几行代码,您就可以在 python 脚本中实现进度条!这没什么太复杂的,你不必再猜测你的剧本进展如何了!希望你觉得这有用!# 学习矢量量化> 原文:<https://towardsdatascience.com/learning-vector-quantization-ed825f8c807d?source=collection_archive---------10----------------------->## 基于原型的学习导论![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/80fdf5b93500efa069bf25bb63f56414.png)Image from Pixabay from Pexels如今,机器学习和人工神经网络这两个术语似乎可以互换使用。然而,当谈到最大似然算法时,世界上不仅仅只有神经网络。事实上,在大学期间,我所做的大多数 ML 项目根本没有使用神经网络。但是除了神经网络,为什么还要使用其他东西呢?的确,神经网络可以对非常复杂的问题取得惊人的结果。不过,还有一些关键问题。它们需要大数据集和大量的计算能力,尤其是后者并不总是在一个人的能力范围内。通常,对于相当小而简单的问题,使用像神经网络这样复杂的东西是没有意义的,因为其他算法更快,可能更好!学习矢量量化(LVQ)就是我经常使用的一种算法。虽然与其他一些算法相比,该算法本身并不是特别强大,但它非常简单和直观。此外,它有一些扩展,可以使算法在各种 ML 相关任务中成为一个强大的工具。LVQ 是一种所谓的原型学习方法。一个或多个原型用于表示数据集中的每个类,每个原型被描述为特征空间中的一个点。然后,新的(未知的)数据点被分配最接*它们的原型的类别。为了使“最*”有意义,必须定义距离度量。您可以自由选择任何距离度量,通常,欧几里得距离是距离度量的选择。每个类可以使用多少原型没有限制,唯一的要求是每个类至少有一个。下图显示了一个简单的 LVQ 系统,其中每个类(红色和蓝色)由一个原型(较大的点)表示。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/4b0a38d72d8117a895760ece05b9cb8a.png)2D LVQ system with corresponding prototypes representing each class那么我们如何让原型适合每一个类,使它们能够很好地代表那个类呢?我们从选择距离度量开始,在本例中,我们将应用欧几里德距离度量。回想一下,N 维中 2 个向量之间的欧几里德距离由下式给出:![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/5e40457fdb011709b01528da4d18b88f.png)请注意,我们可以使用*方欧几里得距离,这不需要我们计算*方根。# 那么我们该怎么做呢?第一步是初始化每个原型,通常原型是通过使用类方法初始化的。下一步是遍历数据集,一次一个特征向量。对于每个这样的特征向量,我们需要使用选择的距离度量来计算到每个原型的距离。然后我们只对最接*的原型进行更新。如果原型具有与特征向量相同的标签,则原型被推向特征向量,否则原型被从相反方向推离特征向量。推动的幅度由学习速率决定,学习速率是算法的参数之一。一旦我们对数据集中的每一个样本都这样做了,我们就可以多次重复这个过程,直到算法收敛。对数据集的一次扫描也称为训练时期。该算法通常需要几个历元来达到收敛,这取决于问题的复杂程度。下面的代码是 LVQ 算法在 Python 中的实现。# 给我看看代码请随意试验您选择的数据集。你也可以改进算法,例如允许每个类使用多个原型。现在我们已经有了算法,让我们在一些样本数据上测试它。在这种情况下,我使用了来自 UCI 机器学习库的[钞票认证数据集](https://archive.ics.uci.edu/ml/datasets/banknote+authentication)。在对样本数据集运行算法之前,我对特征向量进行了洗牌,并留出 10 %的集合作为验证集。现在你应该如何处理学习率参数呢?理想情况下,您应该使用交叉验证来找出最佳值。在这种情况下,我简单地选择 0.01 作为学习率,因为它给出了不错的结果。在 25 个时期之后,该算法在验证集上收敛到 0.28 的误差。对于一个如此直观和简单的算法来说,这并不是一件坏事。为了对新的未知特征向量进行分类,只需将最接*的原型的类别分配给它。# 谢谢,还有别的吗?LVQ 有一些明显的优势:它简单、直观、易于实现,同时还能产生不错的性能。然而,在更复杂的问题中,如果数据有很多维度或有噪声,欧几里德距离会引起问题。特征空间的适当归一化和预处理是必要的。但是,即使这样,如果你的数据有很多维度,你可能会遭受[维度](/the-curse-of-dimensionality-50dc6e49aa1e)的诅咒,你可能会考虑某种形式的降维。伙计们,现在就到这里吧!下一次,我们将研究处理 LVQ 问题的算法的更复杂的变体。# Python 中的最小二乘线性回归> 原文:<https://towardsdatascience.com/least-squares-linear-regression-in-python-54b87fc49e77?source=collection_archive---------1----------------------->![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/9b188b3e7c329d99414f1078a2b821c4.png)Photo by [Jeswin Thomas](https://unsplash.com/@jeswinthomas?utm_source=medium&utm_medium=referral) on [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral)顾名思义,****最小二乘法**的方法是将数据集中观察到的目标与线性*似预测的目标之间的残差的***方**之和最小化。在这篇后续文章中,我们将看到如何使用线性代数找到最佳拟合线,而不是像梯度下降这样的东西。**# **算法****与我最初的想法相反,线性回归的`scikit-learn`实现最小化了以下形式的成本函数:****![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/46652b1509d31762a70fa24991666836.png)****利用 x 的奇异值分解。****如果您已经熟悉线性回归,您可能会发现它与前面的方程和均方差(MSE)有一些相似之处。****![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/a3d818a01473389d27aed816b7711654.png)****作为快速复习,假设我们有下面的散点图和回归线。****![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/73451d0dc12dce50d7d0e8a2dbae5d79.png)****我们通过从一个数据点减去另一个数据点来计算从直线到给定数据点的距离。我们取差值的*方,因为我们不希望低于实际值的预测值被高于实际值的预测值抵消。用数学术语来说,后者可以表示如下:****![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/67f42bfce3ca3e6bffc0a3ceac7b4c61.png)****![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/1ba9f9a5216aade557d982972fc12fc8.png)****`scikit-learn`库中使用的成本函数是相似的,只是我们同时使用矩阵运算来计算它。****对于那些上过微积分课程的人来说,你们可能以前遇到过这种符号。****![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/242443207a2b4a9a457c6570271fcc7c.png)****在这种情况下, **x** 是一个矢量,我们正在计算它的大小。****在同样的意义上,当我们用竖线包围矩阵的变量(即 A)时,我们是说我们想从一个由行和列组成的矩阵变成一个标量。从矩阵中导出标量有多种方法。取决于使用哪一个,你会在变量的右边看到一个不同的符号(等式中多出来的 2 不是偶然放在那里的)。****![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/501a4a44160be670079c518953f2ad92.png)****额外的 2 意味着我们取矩阵的[欧几里德范数](https://en.wikipedia.org/wiki/Euclidean_norm)。****![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/72ac6b343be52367c912e80fcb59dc40.png)****假设我们有一个矩阵 A,A 的欧氏范数等于 A 点转置的最大[特征值](https://en.wikipedia.org/wiki/Eigenvalue)的*方根,为了清楚起见,我们来走一个例子。****![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/545be9cb9457b795f7bbe73f6d72114a.png)****![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/a78c4a31dc95bb006ea6b1cde6d49b1d.png)****这就是我们量化误差的方法。然而,这引起了一个新的问题。具体来说,我们实际上如何着手最小化它呢?事实证明,最小范数最小二乘解(系数)可以通过计算输入矩阵 X 的伪逆并乘以输出向量 y 来找到。****![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/106c56acd3e91b287ad26bfb37d488a2.png)****其中 X 的伪逆定义为:****![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/22eb2458bfb59c064bf3d1d05bf032a8.png)****上述矩阵均可从 X 的奇异值分解(SVD)中获得。回想一下,X 的 SVD 可描述如下:****![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/3d99d9ff42273354d7df21f78710ac1f.png)****如果你对如何确定 U,sigma 和 V 的转置很好奇,看看我不久前写的这篇文章[](/singular-value-decomposition-example-in-python-dab2507d85a0)**,这篇文章讲述了如何使用 SVD 进行降维。********我们通过对`sigma`矩阵中的值求逆来构造对角矩阵 D^+。`+`指的是所有元素必须大于 0,因为我们不能被 0 整除。********![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/611d3a4d4f29829aa4d8acdc4012eeb2.png)********![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/3960ada37a35cd625afc85c226728d1b.png)****# ****Python 代码********让我们看看如何使用基本的`numpy`函数从头开始实现线性回归。首先,我们导入以下库。****```
**from sklearn.datasets import make_regression
from matplotlib import pyplot as plt
import numpy as np
from sklearn.linear_model import LinearRegression**
```****接下来,我们使用`scikit-learn`库生成数据。****```
**X, y, coefficients = make_regression(n_samples=50,n_features=1,n_informative=1,n_targets=1,noise=5,coef=True,random_state=1
)**
```****![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/9855673fd03a2531f95e8bca600e21f8.png)********我们将矩阵的秩和列数存储为变量。****```
**n = X.shape[1]
r = np.linalg.matrix_rank(X)**
```****我们使用奇异值分解找到我们的特征矩阵的等价物。****```
**U, sigma, VT = np.linalg.svd(X, full_matrices=False)**
```****然后,D^+可以从西格玛得到。****```
**D_plus = np.diag(np.hstack([1/sigma[:r], np.zeros(n-r)]))**
```*****V* 当然等于其转置的转置,如以下恒等式所述。********![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/04f896e493d0308fa9385f98b4f4b380.png)****```
**V = VT.T**
```****最后,我们确定 x 的 **Moore-Penrose 伪逆**。****```
**X_plus = V.dot(D_plus).dot(U.T)**
```****正如我们在上一节中看到的,系数向量可以通过矩阵 X 的伪逆乘以 y 来计算。****```
**w = X_plus.dot(y)**
```****![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/3bc4357eafe94a25803a8e25445d46f8.png)********为了获得实际误差,我们使用我们看到的第一个等式来计算残差*方和。****```
**error = np.linalg.norm(X.dot(w) - y, ord=2) ** 2**
```****![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/e1e73f4181779f43e8162a1cf5781053.png)********为了验证我们得到了正确的答案,我们可以使用一个`numpy`函数来计算并返回线性矩阵方程的最小二乘解。具体来说,该函数返回 4 个值。****1.  ****最小二乘解****
2.  ****残差和(误差)****
3.  ****矩阵的秩(X)****
4.  ****矩阵的奇异值(X)****```
**np.linalg.lstsq(X, y)**
```****![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/2fef82d4c8a313303c16c5bed237b493.png)********通过绘制回归线,我们可以直观地确定系数实际上是否导致最佳拟合。****```
**plt.scatter(X, y)
plt.plot(X, w*X, c='red')**
```****![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/1f0143941edf2225a6b437df36d81222.png)********让我们使用线性回归的`scikit-learn`实现做同样的事情。****```
**lr = LinearRegression()lr.fit(X, y)w = lr.coef_[0]**
```****![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/2132da538a69c5bb0182765fce4053dd.png)********最后,我们使用新发现的系数绘制回归线。****```
**plt.scatter(X, y)
plt.plot(X, w*X, c='red')**
```****![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/1f0143941edf2225a6b437df36d81222.png)****# Python 中熊猫数据框的左连接> 原文:<https://towardsdatascience.com/left-join-with-pandas-data-frames-in-python-c29c85089ba4?source=collection_archive---------0----------------------->关于如何在左连接的结果中正确标记空值来源的教程。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/9cca7e3fa1107f721cbc2f88d9e2c61c.png)StackOverflow 文章 [Pandas Merging 101](https://stackoverflow.com/questions/53645882/pandas-merging-101) 详细介绍了合并 Pandas 数据帧。然而,我给数据科学课后测试评分的经验让我相信左连接对许多人来说仍然是一个挑战。在本文中,我将展示如何正确处理 Pandas 左连接中的右表(数据框)包含空值的情况。让我们考虑一个场景,其中我们有一个表`transactions`包含一些用户执行的事务,还有一个表`users`包含一些用户属性,例如他们喜欢的颜色。我们希望用用户的属性来注释事务。以下是数据框:```
import numpy as np
import pandas as pdnp.random.seed(0)
# transactions
left_df = pd.DataFrame({'transaction_id': ['A', 'B', 'C', 'D'], 'user_id': ['Peter', 'John', 'John', 'Anna'],'value': np.random.randn(4),})# users
right_df = pd.DataFrame({'user_id': ['Paul', 'Mary', 'John','Anna'],'favorite_color': ['blue', 'blue', 'red', np.NaN],})
```请注意,彼得不在`users`表中,安娜也没有最喜欢的颜色。```
>>> left_dftransaction_id user_id     value
0              A   Peter  1.867558
1              B    John -0.977278
2              C    John  0.950088
3              D    Anna -0.151357>>> right_dfuser_id favorite_color
0    Paul           blue
1    Mary           blue
2    John            red
3    Anna            NaN
```使用用户 id 上的左连接将用户喜欢的颜色添加到事务表中似乎很简单:```
>>> left_df.merge(right_df, on='user_id', how='left')transaction_id user_id     value favorite_color
0              A   Peter  1.867558            NaN
1              B    John -0.977278            red
2              C    John  0.950088            red
3              D    Anna -0.151357            NaN
```我们看到彼得和安娜在`favorite_color`列中有`NaN`。然而,丢失的值有两个不同的原因:Peter 的记录在`users`表中没有匹配,而 Anna 没有最喜欢的颜色的值。在某些情况下,这种细微的差别很重要。例如,它对于在初始勘探期间理解数据和提高数据质量至关重要。这里有两个简单的方法来跟踪左连接结果中缺少值的原因。第一个由`merge`函数通过`indicator`参数直接提供。当设置为`True`时,结果数据帧有一个附加列`_merge`:```
>>> left_df.merge(right_df, on='user_id', how='left', indicator=True)transaction_id user_id     value favorite_color     _merge
0              A   Peter  1.867558            NaN  left_only
1              B    John -0.977278            red       both
2              C    John  0.950088            red       both
3              D    Anna -0.151357            NaN       both
```第二种方法与它在 SQL 世界中的实现方式有关,它在右边的表中显式地添加了一个表示`user_id`的列。我们注意到,如果两个表中的连接列具有不同的名称,那么这两个列都会出现在结果数据框中,因此我们在合并之前重命名了`users`表中的`user_id`列。```
>>> left_df.merge(right_df.rename({'user_id': 'user_id_r'}, axis=1),left_on='user_id', right_on='user_id_r', how='left')transaction_id user_id     value user_id_r favorite_color
0              A   Peter  1.867558       NaN            NaN
1              B    John -0.977278      John            red
2              C    John  0.950088      John            red
3              D    Anna -0.151357      Anna            NaN
```一个等效的 SQL 查询是```
**select**t.transaction_id, t.user_id, t.value, u.user_id as user_id_r, u.favorite_color
**from**transactions t**left join**users u**on** t.user_id = u.user_id
;
```总之,添加一个额外的列来指示 Pandas left join 中是否有匹配,这允许我们随后根据用户是否已知但没有最喜欢的颜色或者用户是否从`users`表中缺失来不同地处理最喜欢的颜色的缺失值。这篇文章最初出现在 [Life Around Data](http://www.lifearounddata.com/left-join-with-pandas-data-frames-in-python/) 博客上。*照片由 Unsplash 上的* [*伊洛娜·弗罗利希*](https://unsplash.com/@julilona) *拍摄。*# 法律确定性和法庭上计算机决策的可能性> 原文:<https://towardsdatascience.com/legal-certainty-and-the-possibility-of-computer-decision-making-in-the-courtroom-ac4b1a6c42d1?source=collection_archive---------28----------------------->## 薇薇安·林登伯格(2018)撰写,作为阿姆斯特丹自由大学的法学学士论文。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/00b10b43f83dfb0b2b68c422eb90c36f.png)电脑会接管我们的工作吗?在工业革命期间,许多人担心自动化会导致依赖体力劳动的行业出现大规模失业。更复杂的机器人和人工智能的发展带来了类似的讨论,只是现在智力工作也处于危险之中。这包括法律行业的许多职业,如律师和法官(维穆伦&芬威克,2017)。然而,荷兰司法系统似乎很有信心,他们不会很快被计算机取代。2017 年,司法委员会与 LexIQ 一起做了一项实验。两起案件由一名法官和一个计算机程序进行了评估。在这两种情况下,计算机得出的结论都不如法官满意(De Rechtspraak,2017b)。尽管如此,人工智能在未来变得越来越重要似乎是不可避免的。荷兰公诉机关使用软件 *BOS-Schade* 来帮助评估不太严重的刑事案件中的损失金额。这是一种已经在使用的计算机辅助的基本形式(Openbaar Ministerie,2018 年 6 月 11 日访问)。另一方面,人们仍然担心自动化系统的使用会侵犯人们的权利。例如,见最*生效的《一般数据保护条例》第 22 条:个人有权"*不受制于仅基于自动处理的决定*(《一般数据保护条例》,第 22 条)。荷兰法律体系中一个重要的基本价值观是法律确定性。它认为政府的行为应该是可预测的。然而,这并不意味着法官总是必须严格遵守法律条文。有时,立法者故意留下解释的空间,甚至允许法官无视法律条文,以确保合理和公*的结果。计算机的一个重要优势是它们似乎能够做出中立的决定。这意味着,从法律确定性的角度来看,计算机的裁决将优于人类法官的裁决。本论文的主要问题是:**“从法律确定性的角度来看,在荷兰法律体系中,计算机应该在多大程度上做出法律决定?”**。要回答这个问题,一些关键问题将是:计算机真的使司法判决对公民来说更确定吗?法律的确定性总是可取的吗?这篇论文的结构如下。我将首先介绍计算机已经在司法系统中使用的一些方式。接下来,我将探讨法律确定性的一个重要特征:一致的决策。然后,我将着眼于一个更实际的方面:偏见会破坏法律的确定性,即使这些偏见是一贯适用的。之后,我将着眼于法律确定性的一个更为主观的方面:公民眼中的决策透明度。对于每个主题,我将试图确定计算机对法律确定性的影响。最后,我会给出一个结论,并参考未来可能的研究。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/2bfcf13c3e0c4c58afc5fcf226538535.png)# 1.当前状态## 1.1 决策和计算机系统法官的目标取决于他们处理的案件类型。在刑法中,目标是发现真相,然后找到适当的应对措施。另一方面,在民法中,目标是解决争端。这通常涉及查明事实真相,但当事方也有可能构建自己的法律现实。法官的任务是根据双方提出的事实来解决冲突,而不是查明无争议的主张是否属实。“真相”不是可以确定的东西。一般来说,法官会假定某些事实是真实的,并根据这些事实做出判决。计算机可以以许多不同的方式帮助做出法律决定。最重要的区别在于计算机在多大程度上接管了决策过程。Noortwijk & De Mulder 描述了法律系统中计算机系统的三个等级。法律技术 1.0 是旨在仅仅帮助人类做决定的系统。这方面的一个例子是用于法律研究的链接数据系统。法律技术 2.0 接管了很大一部分决策过程,而人类仍然拥有最终发言权。自动起草合同就是一个例子。最后,法律技术 3.0 完全接管了这一过程,因为系统可以在没有人类帮助的情况下自主做出决定(Noortwijk & De Mulder,2018,第 10 段)。5).这种区别并不表明具体使用什么方法来实现目标。一个显而易见的方法是大数据分析,比如数据挖掘。通过使用数据挖掘算法,可以在大量数据中寻找模式(Calders & Custers,2013 年,第 28、32 页)。## 1.2 示例荷兰司法系统已经在尝试各种数字技术。数字诉讼正逐渐成为强制性的,最*甚至有一项实验将计算机的司法判决与人类法官的判决进行了比较(Heemskerk & Teuben,2017 年,第 10 章;2017 年 b)。在一份报告中,司法委员会陈述了试验“智能技术”的重要性,尽管是小心翼翼的小规模试验(De Rechtspraak,2017a,第 44-45 页)。在荷兰之外,也使用法律技术。例如,在美国,风险评估工具 COMPAS 除了其他用途之外,还被用作刑事案件判决的辅助工具。诸如药物滥用、犯罪态度和先前的犯罪参与等变量被用来确定一个人是高风险还是低风险。然后法官可以在量刑时使用这个分数(Equivant,2017 年,第 4 章)。在量刑中使用这一工具并非完全没有争议,因为它可能对黑人被告有偏见(Angwin,Larson,Mattu & Kirchner,2016)。在荷兰,法官目前尚未将大数据用于决策,但越来越多的数据正在数字系统中收集,这为未来使用大数据分析奠定了基础(De Rechtspraak,2017a,第 44–45 页)。除了数字系统的实际应用,预测法律判决的研究也在进行中。来自英国的研究人员试图通过使用自然语言处理和机器学习来预测欧洲人权法院的决定。在预测是否会出现侵犯人权的情况时,这些预测达到了 79%的准确率。分析文本以做出预测的方法似乎是有效的,尽管研究人员并不打算设计一个可以完全接管法官工作的系统(阿勒特拉斯,Tsarapatsanis,Preoţiuc-Pietro 和兰波斯,2016 年)。除了司法系统中的技术,许多律师事务所也在探索计算机可以提供的可能性。律师事务所正在开发软件,以便与客户进行更多的互动,并使律师的日常工作变得更容易。使用计算机系统可以提高效率,通常受到客户的重视(Rietbroek,2017)。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/7b09ae0011dadd529aaa964c96ac1bc7.png)# 2.一致的决策## 2.1 界定法律确定性法律确定性的早期描述可以追溯到公元前 350 年左右,在亚里士多德的著作中。他描述说,由法律裁决比根据个案做出决定更好,因为“*法律是经过长时间考虑后做出的,而法院的决定是在短时间内做出的,这使得那些审理案件的人很难满足正义的要求*”(斯坦福哲学百科全书,2016 年,第 101 段)。3.1).洛克在他的社会契约理论的背景下描述说,无论是谁掌权“*都必然要按照既定的、颁布的、为人民所知的法律来治理,而不是通过临时的法令*”(洛克,1689 年,第 111 段)。131).拉德布鲁赫描述了法律的三个核心价值:正义、权宜和法律确定性。法官适用法律最重要的价值是法律确定性,因为法律秩序的存在比法律秩序中的正义和权宜更重要。然而,这三个值都很重要,它们之间应该有一个*衡(Radbruch,(1932) 1950,第 108-111 页,第 118-119 页)。法律确定性原则包含许多不同的要求,如:政府只应在法律范围内行事,法官应独立,法律应公开。此外,法官应当适用法律,而不应当根据个人意见作出判断(斯坦福哲学百科全书,2016 年,第 10 段)。5.1–5.2;Van Ommeren,2003 年,第 7-22 页;Scheltema,1989 年,第 10 段。2.1).然而,不遵守法律可能有重要的原因。保护基本权利有时意味着绕过国家法律。这可以被视为对法律确定性原则的明显侵犯,因为法律没有得到遵守。另一方面,公民最有可能期望法律的解释能够保证他们的基本权利。无论法律如何适用,始终以某种程度上一致的方式来实现这一点是很重要的(Soeteman,2010 年,第 10 段)。7.6).德沃金将法律中的这种稳定性称为“完整性”。以一致的方式应用法律使社区具有凝聚力,因为它在整个社区中创造了连续性,并且随着时间的推移也是如此(德沃金,1986 年,第 225-275 页;马莫,2012 年,第 9 章)。总而言之,法律确定性是一种针对国家公民的价值观:它提供了针对政府权力的保护,并诱导对政府的信任,从而使制度更加稳定。这种价值的客观方面是,法律制度应该永远得到遵守;决定不应该随意做出。还有一个主观成分:公民应该有一种感觉,他们的政府是值得信任的(斯坦福哲学百科全书,2016 年,第 10 段)。5.1).## 2.2 实现法律确定性尽管荷兰没有具有法律约束力的先例制度,但由于上诉和翻案制度,法律通常会得到统一解释。当最高法院以某种方式解释规则时,下级法院通常会遵循这种方式(Soeteman,2010,第 46–47 页)。这意味着,一般来说,每个法官在每个案件中都会以同样的方式适用法律。然而,并非在法律的每一个领域都有对案件进行上诉的惯例,即使在司法系统的较高层次,法官在类似案件中适用法律的方式也可能略有不同。在某些情况下,法律是非常明确的,法官将很可能在每个案件中得出相同的结论。在这些案件中有很高的确定性:如果你只是严格遵守法律,结果是显而易见的。对于这些类型的情况,决定是由人还是由计算机做出并不重要,尽管后者会更有效(如果广泛使用的话)。同样,在有些情况下,法律模糊不清,但结果却非常清楚。以刑事案件中的证据标准为例。根据《荷兰刑事诉讼法》第 338 条,只有在法官根据现有证据确信嫌疑人有罪的情况下,才能认定嫌疑人有罪。除此之外,认定嫌疑人有罪的门槛相当低:一般来说,两件证据就足够了。尽管第 338 条的标准是模糊的,但在个别情况下,结果可能非常清楚。例如:当有许多证人时,嫌疑人被当场抓住,手里拿着一把带血的刀,并且承认了罪行,每个人都可能得出相同的结论,即嫌疑人就是犯下谋杀罪的人。当证据不明确时,事情就变得更复杂了。那么,类似的案件完全可以区别对待,因为两种选择(有罪或无罪)都同样有利。当在一个问题上意见分歧时,一个可能的妥协是随机决定某人是否有罪。实际上,这种情况下的结果或多或少确实是随机的。德沃金谈到了“棋盘式”解决方案:由于意见分歧,法律对类似的案件采取不同的处理方式。在大多数情况下,人们会本能地认为这些类型的解决方案是不公*的(德沃金,1986 年,第 179-183 页)。判决也是如此。从法律确定性的角度来看,最好是每一项决定都是一样的,不管这项决定是比另一项选择稍微好一点还是差一点。当法官在相同的案件中可以得出两种不同的结论时,当输入相同时,计算机总是给出相同的结论。每个人类法官都以独特的方式做出决定,计算机系统可以很容易地被复制。这意味着通过使用后者,可以在全国范围内采用相同类型的决策,并且可以在整个时间内保持稳定。## 2.3 法律确定性的限制然而,法律的确定性总是可取的吗?一些哲学家公开反对严格遵守规则。例如,柏拉图曾说,这种做法“就像一个顽固、愚蠢的人,他拒绝允许对自己的规则有丝毫的偏离或质疑,即使事实上情况已经改变,事实证明违反这些规则对某人来说更好”(斯坦福哲学百科全书,2016 年,第 10 段)。7).甚至拉德布鲁赫也认为,虽然原则上必须遵循实在法,但当法律极不公正时,它就不能被视为有效(Bix,2013 年,第 10 段)。5.2).在个别案件中,严格执行法律可能会导致不公正的结果。尽管法律确定性是荷兰法律体系最重要的价值观之一,但灵活性也很重要。正如导言中已经提到的,立法者有时故意在法律中留有解释的余地,基本权利保护可以影响法律在个案中的适用,即使法律非常具体。后者可被视为法律确定性的一种形式,即无论如何,特定的一般原则总是受到保护。另一方面,它可以被视为是不确定的,因为针对这种情况的具体法律并不适用。基本权利原则上在某种程度上是不变的,因此从一致性的角度来看,遵循前一种解释是有意义的。然而,在现实中,即使是基本权利也会随着社会的变化而变化,其适用也并非总是没有争议。此外,在这些权利通常表述模糊的情况下,下级立法往往更加具体,从而使公民更加确定如何在他们的具体情况下适用法律。尽管偏离特定法律对法律确定性没有好处,但它可能会导致更公正的结果。刑法中的一个例子说明了在个别案件中背离法律的重要性,这就是" Huizense Veearts "案的判决。在这种情况下,一名兽医将健康的奶牛与感染口蹄疫的奶牛接触,根据当时适用的法律,这是刑事犯罪。然而,兽医故意应用这种(科学上可接受的)方法,以保护动物在未来不会得重病。这项法律制定时显然没有预料到这种可能性。最高法院最终判决惩罚兽医是不公正的,因为他的行为符合法律的根本目标,尽管法律明确禁止这些行为(最高法院,1933 年 2 月 20 日)。计算机很可能会“盲目”应用法律,而不考虑法律所基于的原则。通常,这将导致正确的结果。然而,在这样的例子中,它会导致不可接受的结果。这是因为立法者很难预测未来会发生什么情况。此外,基于统计分析得出结果的计算机系统可能无法处理异常值:非典型的情况(Custers,2016 年,第 15-16 页)。法官的一个重要职能是在不同的个案中适用法律,甚至在一定程度上创造新的法律(Bovend'Eert,2011 年,第 32-40 页)。对计算机的严重依赖可能意味着离群值将被不公正地视为*均案件,法律发展将会停止。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/a3aed10d3a022b7a1496bd831ccaa2f1.png)# 3.不必要的偏见## 3.1 消除不必要的偏见仅仅一贯地适用法律并不意味着歧视是不可能的。一个法律中嵌入了某种形式歧视的系统仍然是确定的,只要它不是随机适用的(斯坦福哲学百科全书,2016 年,第 102 段)。5.3).在荷兰,根据《宪法》第 1 条,法律禁止歧视,尤其是当歧视涉及性别、种族和宗教等因素时。因此,这些因素不应在法律决策中发挥作用,除非有具体的法律允许这样做。计算机自动化肯定会导致更一致的判断,即使它们包含不必要的偏见。然而,从法律确定性的角度来看,判决中的差异应基于案件之间司法相关的差异。没有一个好的理由来区分群体是武断的,因此是不确定的(斯坦福哲学百科全书,2015 年,第 10 段)。4.1).使用计算机代替人类法官的一个重要原因是为了消除不必要的偏见。例如,根据美国的多项研究,某些种族的人在刑事案件中被判的刑罚更高,更有可能被判死刑(C. O'Neil,2016,第 29 页)。在荷兰,关于种族偏见的存在一直存在争议。研究表明,不同种族群体之间的量刑差异在很大程度上可归因于司法相关情况(De Rechtspraak,2016 年)。尽管如此,任何司法系统中一个迫在眉睫的危险是,法官让本应无关紧要的因素在他们的决策过程中发挥作用(尽管是无意识的)。人类容易受到各种偏见的影响,而计算机原则上是中立的。他们根据预先编程的算法做出可预测的决策。因此,如果一个变量,如种族,不应该在决策过程中发挥作用,它可以简单地不输入系统。然后,该系统将对这一因素视而不见(这假设也没有以间接方式指示人的种族的变量,例如区分某些街区或家庭背景)。然而,Harcourt 提到,在美国,大约从 20 世纪 70 年代开始,将种族作为风险分析的一个因素在政治上不再正确,然而该系统仍然具有歧视性(Harcourt,2010 年,第 4 页)。在使用大数据时,会有系统用来进行计算的预定因素。只要清楚系统使用的是什么因素,这将是保护司法系统免受不必要的偏见的有效方式。## 3.2 隐藏的偏见尽管计算机可能是对抗不必要的偏见的解决方案,但它在很大程度上取决于系统是如何设计的。计算机系统将由人类设计,并使用现有数据,这可能意味着它只是复制现有的偏见,而系统似乎是中立的。即使算法本身没有偏差,插入的数据也可能导致不想要的结果。如果现状中的法官有歧视,系统使用的数据就会有偏差。奥尼尔描述说,在美国,风险模型在全国范围内被用来(除其他外)提高一致性和打击个别法官的偏见。这些模型用于确定罪犯的预期再犯率。这些特定模型使用与所犯罪行相关的信息,以及与犯罪者相关的因素。利用一个人的特征可能是一种歧视性的做法。即使该系统看起来没有偏见,因为它根据早期的信息做出一致的决定,但它实际上是歧视性的(O'Neil,2016,第 29-30 页)。calders & lio bait 指出,仅仅消除一个特定的歧视性变量并不一定能解决问题,因为可能还有其他变量与之相关,因此结果是一样的。然而,有办法通过纠正数据来消除歧视。另一种可能出现问题的方式是使用不正确或不完整的数据。如果数据的选择性部分缺失,将会导致不良后果(Calders & lio bait,2013 年,第 10 段)。3.4.1–3.4.2).## 3.3 检测偏差尽管计算机化的决策不会自动减少偏差,但大数据可以用来使原本隐藏的偏差变得可见(Pedreschi,Ruggieri & Turini,2013 年,第 100-101 页)。然而,通过研究现有的判例法来发现偏见是极其困难的。因为没有一个案例是完全相同的,很多事情总是可以归因于案例中的具体事实。即使计算机程序和普通法官一样有偏见,计算机似乎也比人更容易测试。一个可能的选择是让系统判断一个假案件,特别是设计来检查它是否对某一群人有不合理的偏见。例如,可以进行一项测试,对两个相同的刑事案件进行判决,只是一个案件中的嫌疑人是女性,另一个是男性。如果系统偏向于某一性别,其中一名嫌疑人更有可能被判有罪,或者比另一名嫌疑人获得更高的刑期。要发现人类法官的这一点要困难得多。首先,人类将很可能知道自己正在接受测试,并将(有意识或无意识地)相应调整自己的行为。第二,如前一段所述,每个法官都可能做出略微不同的决定,因此需要大量的参与者来对总体做出一些结论。与法官不同,如果结果不理想,计算机系统可以直接调整。所使用的模型可以简单地改变。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/d285c23bb073a4da522f5ff770f02a93.png)# 4.透明性## 4.1 预编程透明度法律确定性的一个重要因素是公民对法律的了解(因此也是法庭案件最有可能的结果)。尽管司法判决确实包含了对为什么选择某一结果的解释,但这些解释可能有些模糊。当不同的利益被权衡时,这是显而易见的。虽然会有不同利益的概述,但在大多数情况下,不清楚他们在最终决策中究竟扮演什么角色。法律现实主义理论认为,在困难的案件中,法官将首先决定结果,随后将构建一个合适的推理。现实主义者杰罗姆·弗兰克等人认为,案件的结果在很大程度上取决于法官的个性及其与诉讼当事人的特征和案件事实的相互作用(Marmor,2012 年,第 9 章)。如果事实确实如此,法官的推理在某种程度上是无关紧要的。如果用计算机来做决策,很明显,在做最后决定之前会进行“推理”。结果总是基于案件的某些客观情况。根据所使用的计算机程序的类型,这可能是一种非常透明的决策方式。理论上,所有的输入和系统如何处理都可以公开。因此,决策过程将比现状更加透明。## 4.2 算法的保密性尽管理论上使用计算机系统是一种透明的决策方式,但实际上它可能一点也不透明。使用计算机系统可能就像人类法官一样不透明。不同之处在于,目前是由一名法官负责裁决。当使用先进的计算机(支持)系统时,可能不清楚出错时谁负责。此外,如果人们不知道系统是如何做出决定的,他们可能不会信任系统。一个解决办法是告诉人们算法是如何工作的。国务委员会在 2017 年的一项判决中表示,(在行政法中)政府有义务公布决策方法以及决策所依据的数据和假设,以保护公民的法律地位(国务委员会,2017 年 5 月 17 日,第 10 段)。14.4).所使用的算法通常由第三方创建。算法的确切工作方式通常是公司的秘密,被它评判的人是不知道的。保守秘密的好处是,人们将无法“玩弄系统”(奥尼尔,2016 年,第 17、29、32 页)。这将是一个危险,因为系统有时依赖于受试者直接生成的数据,如问卷(例如:[ [link](https://www.documentcloud.org/documents/2702103-Sample-Risk-Assessment-COMPAS-CORE.html) )。围绕透明度的另一个问题是,计算机系统可能非常复杂,可能只有直接参与创建它们的人才能理解(O'Neil,2016,第 14 页)。一个表明缺乏透明度会造成问题的例子是电子法院。E-Court 是一家为解决消费者和某些大公司之间的纠纷提供司法程序私人替代方案的公司。原则上,所有程序都是在线的,似乎该服务使用算法来做出决定(Aanhangsel handelingen II 2017/18,1803,答案 9,on:[https://zoek . officielebekendmaking en . nl/ah-tk-2017 2018-1803 . html](https://zoek.officielebekendmakingen.nl/ah-tk-20172018-1803.html))。这项服务因缺乏透明度而受到抨击。不清楚“法官”是谁,以前做出了什么决定,以及这些决定是如何做出的(由于受到批评,电子法院最*开始公布决定和他们的“法官”的姓名)。此外,缺乏向消费者提供的关于其权利和程序的信息。正因为如此,有人担心消费者在这类争端解决中的法律地位(Kuijpers,2018)。## 4.3 激励的重要性判断的一个重要部分,如果不是最重要的部分,是最终决定的动机。《宪法》第 121 条要求做出决定。这可以是仅仅引用裁决所依据的适用法律,也可以是进一步解释如何适用规则的广泛推理。这要看具体情况。如果一个规则是明确的,并且应该毫无例外地被执行,这就不需要太多的动机。计算机可以在没有任何人工干预的情况下做出决定,因为它只需参考适用的法律。如果一个定律更模糊,它很可能需要一个更广泛的动机,这对计算机程序来说是困难的。即使人类法官仍有最终决定权,动机也可能是一个问题。计算机可能会对案件的某一特定方面做出判断,然后法官会对所有其他因素进行权衡。如果法官(部分)遵循计算机的决定,那么就很难解释确切的原因,除非计算机说这是基于所用算法的正确反应。尽管决策可能非常确定,但如果人们不知道在他们的个人情况下是如何做出决策的,那么这些决策就会显得很随意。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/a04c4009dcdab293d989aec11f991b2c.png)# 5.结论本论文的主要问题是:“从法律确定性的角度来看,在荷兰法律体系中,计算机应该在多大程度上做出法律决定?”。法律确定性是荷兰法律制度的重要价值。总有一定程度的不确定性,这在个别情况下可能是件好事。然而,一般来说,法官在作出裁决时最好不要偏离法律。法律确定性的第一个方面是一致性。尽管上诉和翻案制度确实有助于法律的适用更加统一,但下级法院仍然可能存在差异,因为并非所有案件都进入上诉程序,最高法院可能以不同方式判决两起类似案件。使用计算机辅助决策肯定会使法律的应用更加一致。另一方面,它也可能减缓法律发展,并可能在具体案件中导致不公正的结果。偏见的存在是一个更实际的问题,会损害法律的确定性。根据所使用的计算机系统的类型,它可以对抗歧视,因为单个法官的偏见将不再是一个问题。尽管在设计系统时必须小心谨慎:如果数据有偏差,可能会导致不希望的结果。分析现有数据可能有助于发现偏见,从而消除偏见。法律确定性的另一个重要方面是透明度。公民必须了解法律以及如何适用法律。当人类法官作出决定时,有不止一种方法来得出这个决定。尽管判断包含动机,但动机之外的其他因素也很可能发挥了作用。在这方面,人类的决策过程是非常不透明的。一个设计良好的计算机系统可以提供高度的透明度,因为决策过程是由算法规定的,理论上可以向公众公开。计算机的一个困难是激发判断。即使人类法官继续参与,他们也很难解释(甚至理解)算法是如何做出决定的,因为这些算法可能非常复杂。从法律确定性的角度来看,使用计算机做出法律决定肯定有一些有前途的可能性。然而,需要注意的是,数据可能会有偏差,判断动机的重要性不应被低估。此外,法律的某些领域对计算机来说比其他领域更难掌握。对于不需要太多解释的基本定律,使用计算机可能是一个结果。有待解释的开放规范和需要快速适应时间的法律将需要更先进的计算机程序来应用它们。目前,在这些复杂的法律领域中,人的参与是必不可少的,尽管计算机在任何类型的案件中都是有用的助手,即使它们只是用来寻找适用的判例法。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/0cd450951dc9052f2bff8acd838b151a.png)# 6.讨论值得注意的是,尽管从法律确定性的角度来看,计算机的参与肯定是有益的,但这个问题还有许多其他方面。例如,在决策过程中使用计算机可能有经济上的原因。然而,至关重要的是,不能仅仅为了效率而损害法律制度最重要的价值观。为了在司法系统中实施技术,法律专业和算法开发人员之间需要进行强有力的合作。当司法系统开始使用计算机程序作为量刑的辅助手段时,法官必须知道结果意味着什么,从而知道如何在他们的判决中使用它。此外,系统的设计必须符合法律制度的要求,例如,不应有不合理的歧视(即使这可能是有效的)。此外,研究立法过程能在多大程度上适应技术进步也是很有意思的。如果法律能够以一种更容易在计算机系统中实施的方式来制定,那么在计算机的帮助下根据这些法律做出决定也就不会那么复杂了。尽管计算机在短期内完全接管司法系统的可能性极小,但看看先进技术在法律方面的机遇还是很有趣的,即使它们只是用作辅助手段。为了有效地实施这种类型的决策支持,不仅有必要探索法官在其案件中使用该技术的最佳方式,而且有必要为这些技术进步培养未来的法律专业人员。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/c1f03d90717f41f5806a0e6a76e6e302.png)# 来源**Aletras,Tsarapatsanis,preoţiuc-pietro&Lampos 2016—**n . aletras,D. Tsarapatsanis,D. Preoţiuc-Pietro &诉 lampos,“预测欧洲人权法院的司法判决:自然语言处理视角”,PeerJ Comput。Sci。2:e93 2016。**安格温,拉森,马特图&基什内尔 2016 —** J .安格温,j .拉森,s .马特图& L .基什内尔,《机器偏见:全国各地都有用来预测未来罪犯的软件。而且对黑人有偏见。,ProPublica 2016 年 5 月,[https://www . ProPublica . org/article/machine-bias-risk-assessments-in-criminal-pending](https://www.propublica.org/article/machine-bias-risk-assessments-in-criminal-sentencing)**Bix 2013 —** B.H. Bix,“拉德布鲁赫公式、概念分析和法治”,载于:Flores I .、Himma K. (eds) *法律、自由和法治*,Ius Gentium:法律和司法的比较观点,第 18 卷,多德雷赫特:Springer,2013 年。**bo vend ' eert 2011—**p . bo vend ' eert,Dient de rechtsvormende taak van de Hoge Raad versterkt te worden bij de herziening van het cassatiestelsel?,in: A. Nieuwenhuis e.a .(红色。), *Rechterlijk activisme。J.A. Peters 先生教授的意见*,奈梅亨:Ars Aequi Libri 2011,第 31–41 页。**Calders&Custers 2013—**t . Calders&b . Custers,“什么是数据挖掘,它是如何工作的?”B. Custers,T. Calders,B. Schermer,T. Zarsky(编辑),*信息社会中的歧视和隐私:大型数据库中的数据挖掘和分析*,第 2 章,柏林:Springer,2013 年。**Calders&lio bait 2013—**T. Calders&I . lio bait,“为什么不带偏见的计算过程会导致歧视性决策程序”,载于:B. Custers,t . Calders,B. Schermer,T. Zarsky(编辑),《信息社会中的歧视和隐私:大型数据库中的数据挖掘和分析》,第 2 章,柏林:Springer,2013 年。**Custers 2016—**b . h . m . Custers,“wetenschappelijk onderzoek 中的大数据”, *JV* 2016/01,第 8–21 页。**德沃金 1986 —** R .德沃金,*劳氏帝国*,麻省剑桥。:哈佛大学出版社 1986 年。**Equivant 2017 —** Equivant,“COMPAS Core 从业者指南”,2017 年 12 月。**哈科特 2010 —** B. E .哈科特,“风险作为种族的代理”,*法律&经济学工作论文*第 535 号,2010。**希姆斯克尔克&条顿 2017 —** W .希姆斯克尔克& K .条顿,*科特·贝格里普·范·KEI*,多德雷赫特:2017 年护航队。**Kuijpers 2018—**k . Kuijpers,“电子法院 zwicht voor kritiek”,Investico 2018,[https://www . platform-Investico . nl/artikel/E-Court-zwicht-voor-krit iek/](https://www.platform-investico.nl/artikel/e-court-zwicht-voor-kritiek/)**洛克 1689 —** J .洛克,1689,*两部政府论*,p .拉斯莱特(编。),剑桥:剑桥大学出版社,1988 年。**Marmor,2012 —** A. Marmor,*The Routledge companies to The Law Philosophy*,第 9 章,阿宾登:Routledge 在线手册,2012 年。**Noortwijk&De Mulder 2018—**k . Noortwijk&r . De Mulder,' Computerrecht,Het rijpingsprocess van juridische technologie ', *Computerrecht* 2018/50。**范·奥米伦 2003 —** 范·奥米伦,《法律与实践》,载于:范·奥米伦& S.E. Zijlstra(红色。),*De rechtstat als toetsingskader*,海牙:Boom Juridische uitgevers 2003,第 7-22 页。**Openbaar Ministerie,2018 年 6 月 11 日访问—** Openbaar Ministerie,' BOS-Schade ',[https://www . om . nl/onderwerpen/slacht offers/BOS-Schade/BOS-Schade-0/](https://www.om.nl/onderwerpen/slachtoffers/bos-schade/bos-schade-0/)**奥尼尔 2016 —** C .奥尼尔,*数学毁灭的武器:大数据如何增加不*等并威胁民主*,纽约:皇冠出版集团 2016。**Pedreschi,Ruggieri&Turini 2013—**d . Pedreschi,S. Ruggieri & F. Turini,《歧视的发现》,载于:B. Custers,T. Calders,B. Schermer,T. Zarsky (eds),《信息社会中的歧视和隐私:大型数据库中的数据挖掘和分析》,第 2 章,柏林:Springer,2013 年。拉德布鲁赫(1932 年)1950 年法律哲学,收录于:*《拉斯克、拉德布鲁赫和达宾的法律哲学》*,第 43–224 页。剑桥:哈佛大学出版社 1950。〔t0〕〔2016 年第一次审判〕〔不同但同样受到惩罚〕〔2016 年第二次〕〔https://www . justice . com/组织/联系/组织/法律顾问/新闻/网页/其他**2017 a—**法庭,“在法治之家建设:2030 年情景规划法庭”,2017 年法庭建议。**法庭 2017 b)**法庭,“审判日:计算机与法官”,2017,[https://www . court . com/组织/联系/组织/咨询/诉讼前/新闻/页面/日](https://www.rechtspraak.nl/Organisatie-en-contact/Organisatie/Raad-voor-de-rechtspraak/Nieuws/Paginas/Dag-van-de-Rechtspraak-computer-vs-rechter.aspx)**2017 年直条裤子—** 。"大律师与新技术创新",2017 年律师杂志,T12 版" http://advocationmagazine . sdu . nl/2017 年 9 月-2011 年版"!《律师与法律技术》T13**原理图 1989 —** 。"法治"的模式,在英语 e.a. (red)中。*法治回顾*,肿胀:w . j .检查威尔林克 1989。**第一季第 10 集。苏特曼、*关于权利的介绍,*,第 4 和第 10 章,奈梅亨:*埃奎利* 2010 年。****2015 年《斯坦福哲学百科全书》**【2015 年 8 月《斯坦福哲学百科全书》、《歧视》】【t26 https://Plato .斯坦福. edu/entries/歧视】**2016 年《斯坦福哲学百科全书》**2016 年《斯坦福哲学百科全书》、《法律规则》,t30《https://Plato .斯坦福. edu/entry/法律规则》**&芬威克 2017】**p . m . vermeel&的缩写。芬威克,《技术革命与法律的未来》,T34 年第 35 期《最高法院》2017 年(5 期)378 期。## **案例法:**[**国务委员会 2017 年 5 月 17 日**](https://uitspraken.rechtspraak.nl/inziendocument?id=ECLI:NL:RVS:2017:1259&showbutton=true&keyword=ECLI%3ANL%3ARVS%3A2017%3A1259)**——**国务委员会,2017,ECLI:NL:RVS:2017:1259。**最高法院,1933 年 2 月 20 日—** 最高法院,1933 年 2 月 20 日, *NJ* 1933/918 (Veearts)。2018 年 6 月 11 日访问了所有在线来源。顶部的横幅图片是由 FlitsArt。所有其他图片来自 pixabay.com。# 列奥纳多与甘之梦> 原文:<https://towardsdatascience.com/leonardo-and-the-gan-dream-f69e8553e0af?source=collection_archive---------25----------------------->## 通过回到文艺复兴时代来探索 GAN 网络的概念,因为莱昂纳多面临着他最令人惊讶的挑战之一![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/e12c2eddd80111771bdfe4fcc32c7642.png)莱昂纳多用拳头猛敲桌子。
—令人发指!悲惨之猪。国王的朝臣和其他皇室成员从大房间的侧面凝视着这一场景。克拉拉,他的表妹和知己,试图安慰他。大师,发生了什么事?发生了什么事?莱昂纳多犹豫了一会儿。然后叹了口气,抬起眼睛看着克拉拉。突然,他的食指做了一个巨大的跳跃,把克拉拉的目光一直带到了豪华房间的另一端。—安东尼奥?你徒弟怎么了?我以为你很高兴,而且..大家赶紧小声说。莱昂纳多举起了手,整个房间陷入了沉默。他站起来,一边踱步一边急促地说话。—我为什么要雇佣安东尼奥?特尔喃喃自语道。—安东尼奥将负责挑选吉诺维斯画室首席画家的最佳作品,带给我。与此同时,安东尼奥应该利用自己的时间,靠自己慢慢地、仔细地、有条不紊地学习和提高自己的技术..克拉拉假装不明白,尽管事实上,她理解得很好,一如既往。列奥纳多继续说道。—我很快警觉到吉诺维斯工作室的作品与我想象的完全不同..主题,技巧,都是错的!他停顿了一下,抬头向上看..仿佛他能再次见到他们。—它们会包含一些令人震惊的错误..太可怕了。完全没有手艺。但是安东尼奥..他..对我说甜言蜜语,他说..首席艺术家生病了,产生了幻觉,正在经历一些个人的混乱..你会相信吗与此同时,克拉拉试图给莱昂纳多提供一些水。但是列奥纳多越来越激动。—你们所有人!你想知道真相吗?达夫韦罗?真理报。
他用手指着安东尼奥,他在房间的另一端,不安地看着地板。—他在撒谎!那些可怕的画,是他自己的!安东尼奥是..制造它们!他们是..糟透了。莱昂纳多再次用手指指着安东尼奥。—当然,开头很糟糕。我会告诉他哪里出了问题,然后…嗯..随着时间的推移,他们变得更好..和..较好的..直到有一天..克拉拉几乎要跌倒了,她不停地试图把一杯水放在莱昂纳多的手上,但是莱昂纳多没有注意到。——那天,我告诉安东尼奥,这位吉诺维斯画家已经恢复了他的触觉。我很高兴..一切都恢复正常了!克拉拉终于设法把杯子放在了他的手上。
—莱昂纳多,喝一杯,坐下,冷静下来。莱昂纳多坐下来,匆匆喝了些酒,然后急切地看着克拉拉。——但是那天晚上克拉拉,那天晚上..我抓住他了!!秘密绘画,画一个..就像被隐藏的开关激活一样,安东尼奥向莱昂纳多冲去,莱昂纳多惊讶地看着他。房间变成了窃窃私语的海洋。—列奥纳多大师,我需要你明白,让我解释一下。—解释?,雷奥纳多恼怒的回答道。几周前,我做了一个梦,主人。低语的海洋来来回回,左右,然后转了三圈,停在了莱昂纳多的鼻子上,他用力地把它推到了一边。—我知道,令人困惑,我也不明白它主人,但是..我现在相信我们是一个..甘。房间里的每个人都陷入了沉默,除了萨宾娜女士,她声嘶力竭地喊道——亵渎!克拉拉要求每个人都冷静下来。莱昂纳多好奇地看着安东尼奥。—马彻 cosa?,告诉我..你喝酒了吗?—师傅,我来解释一下。莱昂纳多脸色阴沉。如果你没有喝酒,你最好现在就解释..,否则..安东尼奥的脸变得容光焕发。—是的,我解释。师父,几周前的那个下午,当你休息的时候,我收到了一封信。Genovese 工作室的业主决定翻新他们的整个建筑,并将所有工作推迟到明年。一名朝臣拿来一把椅子,安东尼奥坐了下来。——我慌了,我知道你会失望的。国王相信你和你的名声会把吉诺维斯工作室的作品带到他的宫廷,作为交换,他会资助你下一阶段的研究。我沮丧地睡着了。一切都不顺利。我非常想学习成为一名伟大的画家。但由于我被雇来监督与热那亚的沟通,我担心一旦你知道他们的工作室将所有工作推迟到明年,你会把我送回家。莱昂纳多目不转睛地看着安东尼奥,试图破译他接下来要说什么。—我发烧了。然后就发生了..我做了一个奇怪的梦。我在寻找一种快速的方法来解开这个谜。我怎么能在为你工作的同时,像热那亚的大师们一样学习绘画,却不给你带来坏消息,他们的画室要关闭几个月的消息…当他们听着的时候,每个人都慢慢走向房间的中央,安东尼奥正在那里讲话。—我开始想象..如果我把自己画成吉诺维斯的作品呢?。但是,当然,我不知道如何像他们一样画画,甚至不知道他们的画是什么样子。然而,我决定尝试一下。安东尼奥戏剧性地停顿了一下,看了看每个人,然后转向莱昂纳多。—我的第一次尝试看起来..命运..几乎是随机的。莱昂纳多翻了翻白眼。房间里到处都能听到窃窃私语。—我送给你的。你被激怒了。你说过这不可能是真的。所以我问你:为什么不呢?。莱昂纳多不安地在椅子上动了动。你向我解释了,你解释了我的创作与真实事物的不同之处。对你的解释很满意,我向你保证我会向吉诺维斯工作室投诉,你对此很满意。列奥纳多看起来仍然有些恼火,但同时也真正地着迷了。—然后我创作了另一幅不同主题的画。但是这一次,我采纳了你给我的反馈。第二天,我回来了,在展示任何东西之前,我解释说吉诺维斯的首席艺术家已经回复说他有一些健康和个人问题,将持续一段时间。安东尼奥继续说着,太阳开始把房间染成金色。—然而,我告诉你,首席画家向我保证,他会尽最大努力向你和国王交付伟大的作品。他请求耐心和理解。然后,我给你看了我的作品。你诅咒了又诅咒。你给了我一个很长的演讲,关于一个叫做“即兴表演”的神秘状况,然后继续启发我更多关于我的画和你所期待的之间的差异。列奥纳多脸上的表情是痛苦和喜悦的混合体。—日复一日,这个过程继续着。对我来说很明显,你真的相信了吉诺维斯画家的故事,并且随着我的画变得更好,你逐渐变得不那么沮丧了,这要感谢你的反馈。几周后,关键的一天终于到来了。莱昂纳多皱起了眉头。克拉拉冲到他身边。低语的海洋冲了回来。——我给你看了《五月多恩》的画。你很高兴。你笑了。你拥抱了我,并宣布吉诺维斯的首席艺术家恢复了健康。—妈妈咪呀!,莱昂纳多朝着高高的天花板叹了口气。—我感到非常自豪。在梦里,我和我的妻子玛加以及两个孩子安娜和皮埃特罗一起庆祝。我女儿带来了一个很棒的草莓蛋糕。在蛋糕上,草莓之间,有三个大大的粗体字:甘。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/20648bc2fa32d56c623dfd0760fa8aaf.png)那是什么,安娜?,我问她。她很快开始就事论事地说话。—太清楚了,爸爸。你和莱昂纳多成了一个网络。你创作了越来越多的吉诺维斯风格的作品。你这样做是试图欺骗达芬奇,让他相信你的画实际上来自吉诺维斯工作室。然而,列奥纳多是这样一个天才,一个伟大的鉴别者和批评家。他会非常准确地指出并解释你的作品与 Genovese 工作室的真品之间的差异。有了这些反馈,你就能不断进步。直到有一天,列奥纳多真的相信你的创作是一幅价值相当于吉诺维斯工作室首席艺术家的画。安娜做了一个快速暂停呼吸,并继续进行。—你的网络达到了稳定,你成为了一个伟大的吉诺维斯风格的画家。爸爸,你所做的一切都是通过在你们两个之间创造一个敌对的动态过程。这就是为什么你的网络是一个 GAN,一个生成性的对抗性网络。安东尼奥和玛加面面相觑,说不出话来。如果你不相信我,去问伊恩·古德菲勒好吗?他想出了所有这些东西,这是我自己的梦在你的梦里告诉我的!—这些天她是不是功课太多了?,玛加小声对安东尼奥说。你还好吗,亲爱的?,安东尼奥给了安娜一个厚脸皮的微笑。但是安娜并没有结束,继续往前走。——好吧,好吧,但是你难道不打算在你自己的梦里好好听听你女儿的话吗?还有很多,爸爸。莱昂纳多逐渐变得越来越善于辨别你的创作和真实的东西,你一直在进步,直到你达到模式崩溃!—模式什么?安东尼奥正尽最大努力跟上安娜热情而自信的讲话。—当你一遍又一遍地画着同样的东西,对它如此着迷。莱昂纳多要疯了!玛加和安东尼奥交换了一下眼神。安东尼奥满意地说:“那些蔬菜汤很有效。”。佩德罗直接跳了进去。
—我们可以玩 GANs 吗?求你了,求你了爸爸,安娜和我能去玩甘斯吗?
——我想成为评论家!,安娜自告奋勇。我会成为艺术家,我会愚弄你!,佩德罗提前庆祝。
——好了,孩子们,去玩吧,去玩甘斯吧。对我来说..,我必须走出梦的这一部分,我听到一些东西…列奥纳多笑了,像打雷一样,他的笑声从装饰华丽的墙壁上反弹回来。
—非凡!贝利西莫。你聪明的孩子,好吧,你让我安东尼奥,一个甘,我们是一个甘!安东尼奥被莱昂纳多的反应吓了一跳。莱昂纳多示意安东尼奥坐在他旁边。—安东尼奥,这个甘的东西很棒。你知道我没有时间教你像吉诺维斯大师那样画画。然而,你需要我的直接反馈来改进。所以你试图愚弄我,一次又一次。随着你越来越好,我渐渐发现不了你作品中的问题。但是安东尼奥,这个网络可能有问题。那会是什么呢,莱昂纳多大师?— Lenta,molto lenta,非常慢。你将需要大量的图形处理器。安东尼奥看了看克拉拉,然后回到莱昂纳多身边。—很多什么?莱昂纳多笑了。—哦,聪明的安东尼奥,你以为你是唯一一个想出令人讨厌的术语的人吗?我也能发明随机的时髦玩意儿,我的孩子!GPU!TPU!还有 CycleGAN 呢!呃!斯塔根。阿坦甘!比根。安东尼奥对这些新单词的发音感到惊讶。主人,我明白了。我花了很长时间才走到这一步,付出了很多努力。你真的认为这个过程可以更快吗?—也许吧—怎么做,主人?—还是等到第二部吧,哈?—什么部分?——我也做了一个梦安东尼奥。我梦见我们生活在——灵媒——这是第一部分。此外,我觉得让每一部分都超过几分钟并不是一个好主意。这种东西是有统计数据的,你明白我的意思吗,安东尼奥?克拉拉冲出房间,急切地请求帮助。
—药,把......的药·雷奥纳多带来!!——Va bene 大师,我们等到第 2 部分,但请告诉我,如果我的女儿一直问我,我们是否生活在模拟中,我应该担心吗?# 从第一线分析中获得的经验教训> 原文:<https://towardsdatascience.com/lesson-analytics-front-line-af0e5fb676ea?source=collection_archive---------26----------------------->![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/9ad8177e92bf85fab6f11e17290d9e56.png)Photo by [Stefan Spassov](https://unsplash.com/@stefanspassov?utm_source=medium&utm_medium=referral) on [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral)## *利用数据解决现实世界问题的实用课程*It 两年前,我开始了数据分析师的职业生涯,与各种业务利益相关者密切合作,专注于建立一个旨在成为行业类别领导者的产品线,从那以后一直在经历(超)增长。在经历了这个职业在高风险情况下的起起落落后,我对这个职业的认识变得更加成熟,并且在这个过程中我学到了一些重要的经验。本文将重点介绍这些经验:1.  **瞄准冲击**
2.  **找出利益相关者真正需要的东西**
3.  **不同的利益相关者需要了解不同深度的信息**我写这篇文章的主要目的是给自己一个机会退后一步思考这些教训,并分享我迄今为止在整个旅程中学到的教训。分享这些经验教训并不意味着我已经完全掌握了它们。老实说,在这方面我还有很长的路要走。我希望这些教训对其他人有价值,就像它们对我有价值一样。# **瞄准冲击**随着人工智能、机器学习和“大数据”方法的激增,世界目前正在收集大量数据,特别是在过去几年里,已经发明了许多数据角色,以使用这些数据和方法来带来现实世界的价值。数据科学家/分析师需要具备许多技能,包括能够使用各种编程语言、数据技术堆栈、库和各种复杂的不同建模技术。随着行业的不断发展,提高我们与这些事情相关的知识和能力将非常重要,并使我们能够不断适应。然而,在我们不断提高知识和能力的同时,我们应该时刻提醒自己,我们职业的主要目标是:> 归根结底,伟大的数据科学家/分析师关注的是利用数据产生最大的影响,而不是他们所拥有的工具/方法。当我谈到影响时,我指的是我们可以用我们所掌握的数据做的改变。从推动一个指标,创造新的产业(或颠覆旧的产业),到解决当今世界存在的问题。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/19b913627933df06dbf3d83383e8c077.png)Photo by [Green Chameleon](https://unsplash.com/@craftedbygc?utm_source=medium&utm_medium=referral) on [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral)与其没完没了地思考不同的工具和模型,不如专注于你能创造最大影响的地方,这可能是更好地利用你的时间的一种方式。通过瞄准影响,你将专注于将你的努力引向某个目标,并将实现它置于实现目标的技术细节之上。现在,这并不意味着我们应该只优化影响。我们应该努力优化的是试图*创造我们能创造的最大影响,同时融入我们更喜欢使用的技能,或者更喜欢在我们的职业生涯中发展的技能。这样做你会更有成效(职业和个人方面),随着时间的推移,你会开始看到你行动的成果在你面前实现。*# 找出你的利益相关者真正需要什么当我与不同的利益相关者一起工作时,我意识到的一件事是,他们有不同的背景(因此有不同的数据素养水*),这可能会在他们需要什么和他们说/认为他们需要什么之间产生*误解。*这一课强调了对你的利益相关者*实际上*需要什么有一个深刻(足够)理解的重要性,而且有时候你将不得不引导他们达到那个点。通常,您会引导利益相关者以数据驱动的方式解决他们的问题,我认为这是一个伟大的数据科学家/分析师的基本能力之一。这就引出了本节的标题,也是我在工作期间学到的重要一课,那就是:> 找出你的利益相关者真正需要什么当你和你的利益相关者就你将要承担的项目或问题进行最初的会议/讨论时,这一课是最有效的。这些会议/讨论是你必须真正尝试了解他们真正需要什么的最佳时机,因为你还没有投入任何资源。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/80df9323a7a666f5636298477859b8ad.png)Photo by [Charles 🇵🇭](https://unsplash.com/@charlesdeluvio?utm_source=medium&utm_medium=referral) on [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral)通过在过程的早期这样做,你不仅会在你花费的时间方面更有效(通过确保你产生了影响),还会向你的利益相关者表明你确实*想要*帮助他们(我希望你大体上是这样做的)。当你设法正确地引导你的利益相关者时,你给予他们的那种关注感是一种授权感,是你的利益相关者会注意到并欣赏的,特别是如果你随着时间的推移持续表现出这种关注。它在你和他们之间建立了一种信任感,这将对你的职业生涯产生深远的影响。以下是每当我要开始一个项目或开始与利益相关者一起解决一个问题时,我总是会讨论的话题:1.  项目/问题的一般描述(问题陈述、当前情况、时间表)
2.  他们心目中的*预期结果*第一个主题是每个人在开始一个新项目时都应该做的事情,它会让你对你的利益相关者希望承担的项目有一些基本的了解。第二点是,作为数据从业者,我们实际上可以理解我们的利益相关者的预期结果是什么,以及您可能会看到哪里发生了脱节。通常情况下,提交给你的项目/问题可能没有根据其目标进行适当的详细说明,或者甚至可能与涉众实际想要实现的结果脱节。通过看到项目和预期结果之间的联系,我们可以向我们的利益相关者提出我们的建议或意见,告诉他们如何更有效地处理手头的项目或问题,或者能够实际获得他们首先想到的结果。# 不同的利益相关者需要了解不同深度的信息**随着你开始在你工作的组织内工作并认识越来越多的利益相关者,你也很有可能遇到组织内不同角色和级别的利益相关者并与之共事。由于这一事实,我们必须记住,**> **我们讨论或展示的信息/细节的深度可能会因谈话对象的不同而有很大差异。****现在,如果你是一个与几个利益相关者一起工作的人,没有不同的背景和角色级别,这将是你不太关心的事情。*当你的利益相关者在你工作的组织中担任不同的职位,并且可能有不同的背景时,这个建议就更重要了*。****例如,我目前的涉众在角色级别和经验方面有很大的不同。从从事日常工作的业务运营人员、拥有大量数据和技术经验的经理,到我所从事的产品垂直行业的业务主管。鉴于这种情况,我需要适当地实践这条建议,以便有效地履行我的职责。****![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/2d056afa051337eccd6109279aa227a2.png)****Photo by [Austin Distel](https://unsplash.com/@austindistel?utm_source=medium&utm_medium=referral) on [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral)****这个建议集中在这样一个事实上,当你谈论你正在做的项目或介绍你已经完成的工作时,你必须考虑你正在交谈/介绍的另一方,以便恰当地交流结果。在你的公司中担任管理职位的人不一定需要知道你用来解决他们问题的算法和模型的细节,但是如果你的同事想要将你的解决方案应用到他们正在处理的其他问题中,他们可能会对这些细节感兴趣。反之亦然。谈论你用来分析/解决问题的总体策略和逻辑可能是你的管理层利益相关者想要完全理解的事情,但是你的同事可能想要知道更多细节,而不仅仅是你用来解决你正在处理的问题的总体策略和逻辑。****当你与不同角色的利益相关者讨论你的工作时,这同样适用。当您与工作场所运营团队中的利益相关者交谈时,他们可能更感兴趣的是您的工作如何改善他们的日常工作,而不是信息技术的长期影响。然而,在战略团队工作的人更有可能对你的工作的中长期影响感兴趣,这意味着当你与他们讨论时,你可能应该更多地关注你工作的这一方面。****当你准备讨论你正在做的项目或展示你的工作成果时,考虑这一课总是一个好主意。这样做会让你成为一个更有效的沟通者(这在数据专业中总是一个很大的优势),同时让你的利益相关者更好地理解你所做工作的价值。**# **包装东西****当我写完这篇文章时,我能记起我犯过的错误,这些错误让我得到了这些教训。似乎那些错误就是我吸取这些教训的原因,我很高兴意识到那些错误其实是有用的。随着我们在数据职业生涯中的进步,我们会遇到许多错误,也许我们首先是这些错误的原因。尽管它们很糟糕(或者无论你如何描述它们),但从长远来看,重要的是我们要留意它们,从中吸取教训,然后继续前进。这样做可能是我们职业生涯中的区别点,让我们变得不同,或许更聪明。*****本文发表于 2019 年 9 月 29 日。对于那些希望接触的人,请通过我的* [*Linkedin*](https://www.linkedin.com/in/anthonyivansunardi/) *随时联系。***# 真实机器学习项目的经验,第 1 部分:从 Jupyter 到 Luigi> 原文:<https://towardsdatascience.com/lessons-from-a-real-machine-learning-project-part-1-from-jupyter-to-luigi-bdfd0b050ca5?source=collection_archive---------12----------------------->## 如何组织机器学习代码![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/45c45564f10675682c825ac2adb18123.png)在过去的 6 个月里,我和我的 awesome 团队一直在从事一个具有挑战性的企业级机器学习项目:从零开始重建一家主要能源提供商的短期电力负荷预测模型。这是一个艰难但令人满意的旅程:我们学到了很多,主要是通过试图从幼稚的错误中恢复过来。是时候尝试分享学到的主要教训了,希望能有所帮助——为什么不呢?—得到帮助,进一步提高。一篇文章太长了,而且很无聊:我会试着贴一堆,每一篇都关注一个主题。这一条涵盖了一个非常棘手的问题:如何组织、构建和管理机器学习项目的代码。# 开始:一个基于 Jupyter 的项目我在最*的学术项目中使用过 Jupyter 我喜欢它的强大和灵活性。一个快速原型工具也是最终的成果共享*台是无价的,不是吗?因此,Jupyter 是我们第一次分析的选择。它只进行了数据探索。那时,我们的项目库看起来像这样。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/a84e589cbbb742ac604681a022009356.png)你发现问题了,对吗?它不可扩展。一点也不。我们过去常常将部分代码从一个笔记本复制粘贴到另一个笔记本上——这是任何软件工程师都无法忍受的。此外,我们实际上被阻止在相同的代码基础上合作,因为基于 json 的笔记本结构使得用 git 进行版本控制非常痛苦。# 突破:ML 中的软件工程在越过不归路之前,我们寻找一个更具可伸缩性的结构。我们发现以下资源非常有用:*   [Mateusz Bednarski,机器学习项目的结构和自动化工作流,2017 年](/structure-and-automated-workflow-for-a-machine-learning-project-2fa30d661c1e)
*   [Kaggle 社区,如何管理一个机器学习项目,2013](https://www.kaggle.com/general/4815)
*   [丹·弗兰克,可重复研究:Stripe 的机器学习方法,2016 年](https://stripe.com/blog/reproducible-research)
*   [DrivenData,数据科学 cookiecutter,2019](https://github.com/drivendata/cookiecutter-data-science) (最后更新)他们都在重复同样的信息。*机器学习项目的代码与任何其他项目没有不同,应遵循软件工程的最佳实践。*因此,我们重构了整个代码库:1.  我们将笔记本中所有可重用的代码提取到几个实用模块中,从而消除了笔记本中的所有重复
2.  我们将模块分成 4 个包,对应于我们工作流程的 4 个主要步骤:数据准备、特征提取、建模和可视化
3.  我们将最关键的功能置于单元测试之下,从而防止危险的回归操作一完成,Python,非笔记本代码就成了事实的唯一来源:按照团队惯例,它是我们最先进的数据准备、特征提取、建模和评分版本。每个人都可以进行试验,但是只有当一个经过验证的改进模型可用时,Python 代码才会被修改。实验呢?而笔记本呢?两个问题,同一个答案。当然,笔记本电脑并没有从我们的开发流程中消失。它们仍然是一个令人敬畏的原型开发*台和一个无价的结果共享工具,不是吗?我们只是开始将它们用于它们最初被创造的目的。笔记本变得个性化,从而避免了任何 git 的痛苦,并遵循严格的命名规则:*author _ incremental number _ title . ipynb*,以便于搜索。它们仍然是所有分析的起点:模型是用笔记本做原型的。如果有一个碰巧超过了我们最先进的,它被集成到了*生产* Python 代码中。超越的概念在这里被很好地定义了,因为评分程序是在实用模块中实现的,并由团队的所有成员共享。笔记本也构成了大部分文档。我们作为一个团队只花了几天时间就完成了转型。差异令人难以置信。几乎在一夜之间,我们释放了集体代码所有权、单元测试、代码可重用性以及过去 20 年软件工程的所有遗产的力量。显而易见的结果是,生产率和对新请求的响应能力大大提高。最明显的证据是当我们意识到我们在所有的拟合优度图表中缺少测量单位和标签时。因为它们都是由一个函数实现的,所以修复它们既快又容易。如果同样的图表仍然被复制并粘贴在许多笔记本上,会发生什么?在转换的最后,我们的存储库看起来像这样。```
├── LICENSE
├── README.md          <- The top-level README for developers
│
├── data
│   ├── interim        <- Intermediate data
│   ├── output         <- Model results and scoring
│   ├── processed      <- The final data sets for modeling
│   └── raw            <- The original, immutable data dump
│
├── models             <- Trained and serialized models
│
├── notebooks          <- Jupyter notebooks
│
├── references         <- Data explanatory materials
│
├── reports            <- Generated analysis as HTML, PDF etc.
│   └── figures        <- Generated charts and figures for reporting
│
├── requirements.yml   <- Requirements file for conda environment
│
├── src                <- Source code for use in this project.│├── tests          <- Automated tests to check source code│    ├── data           <- Source code to generate data│├── features       <- Source code to extract and create features│├── models         <- Source code to train and score models│└── visualization  <- Source code to create visualizations
```双赢的局面。# 结束:框架的价值我们对 Jupyter 原型和 Python 产品代码的分离感到满意,但是我们知道我们仍然缺少一些东西。尽管尝试应用干净编码的所有原则,但是随着越来越多的步骤加入,我们用于训练和评分的端到端脚本变得有点混乱。再一次,我们发现我们处理问题的方式有缺陷,于是我们寻找更好的解决方案。宝贵的资源再次出手相救:*   [Norm Niemer,你的机器学习代码可能不好的 4 个原因,2019](/4-reasons-why-your-machine-learning-code-is-probably-bad-c291752e4953)
*   [Lorenzo Peppoloni,数据管道,Luigi,气流:你需要知道的一切,2018](/data-pipelines-luigi-airflow-everything-you-need-to-know-18dc741449b7)我们研究了气流、Luigi 和 d6tflow,最终选择了 Luigi/d6tflow 管道,后者用于更简单的任务,而前者用于更高级的用例。这一次只花了一天时间来实现整个管道:我们保存了所有的函数和类,封装了预处理、特性工程、训练和评分的逻辑,并且用管道替换了脚本。易读性和灵活性方面的改进是显著的:当我们必须改变训练集和测试集的划分方式时,我们可以只修改两个任务,保留输入和输出签名,而不用担心其他任何事情。# 包扎总结一下,我们得到了关于机器学习项目中代码的三个重要教训:1.  一个机器学习项目*是*一个软件项目:我们应该关心我们代码的质量。不得不处理统计和数学不是编写糟糕代码的借口
2.  Jupyter 笔记本是很好的原型制作和共享工具,但不能取代由模块、包和脚本组成的传统的 T4 代码库
3.  有向无环图(DAG)结构非常适合数据科学和机器学习管道。当有非常好的框架可以帮助时,尝试从头创建这样的结构是没有意义的我的读者,感谢你来到这里!这是我第一篇关于媒介的文章,但我绝不是一个好作家。如果你有任何意见、建议或批评,我恳求你与我分享。*还有,如果你对本帖的话题有任何疑问或疑问,欢迎随时联系!*# 真实机器学习项目的经验,第 2 部分:数据探索的陷阱> 原文:<https://towardsdatascience.com/lessons-from-a-real-machine-learning-project-part-2-the-traps-of-data-exploration-e0061ace84aa?source=collection_archive---------17----------------------->## 如何落入数据探索的陷阱并逃脱![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/d2b12eaa3e4be8ec50de06ece531c4d8.png)这是该系列的第二个故事,所以我将残酷地缩短介绍。我写信来分享一个真实的企业级机器学习项目教会了我和我的团队什么。如果你好奇想了解更多,可以随意查阅第一章: [*从朱庇特到路易吉*](/lessons-from-a-real-machine-learning-project-part-1-from-jupyter-to-luigi-bdfd0b050ca5) *。*# 开头:冗长乏味的总结在大学,我听说过数据探索。在真正的乐趣开始之前,这是一个乏味的初步步骤。您汇总数据集,绘制一些图表,并检查模型的假设。很简单,但不是很有用,对吧?# 教训:数据探索的陷阱这种不好的观点相当普遍,但本质上是有缺陷的。为了说明原因,让我们将数据探索的正式定义与我们的经验进行比较。据[维基百科](https://en.wikipedia.org/wiki/Data_exploration):> 数据探索是一种类似于初始数据分析的方法,通过这种方法,数据分析师使用可视化探索来了解数据集中的内容以及数据的特征。第一部分。*数据探索是一种类似于初始数据分析的方法。*其实它*就是*的初始数据分析。探索应该先于任何统计分析和机器学习模型。这对于避免**第一陷阱**至关重要:汇总指标,如*均值和标准偏差。辛普森悖论是一个众所周知的例子,它表明全球指标可能是肤浅和误导的。这是一个玩具,学术案例研究,但类似的事情也可能发生在现实世界中,你马上就会看到。第二部分。*当数据分析师使用可视化探索来了解数据集中的内容时,就会发生数据探索。*当然,它比这更复杂。想象阅读一个巨大的表格,有几千行几十列,全是数字。你在视觉上探索数据,但是你不可能获得一些洞察力。这是因为我们不是为处理庞大的数字表格而设计的。我们擅长从形状、尺寸和颜色方面解读世界。一旦转化成线、点和角度,数字就更容易理解了。不幸的是,第二个陷阱来了:设计糟糕或吹毛求疵的图表。有时,错误的可视化会阻止数据科学家捕捉正确的洞察力或共享正确的信息。这不是缺乏经验或天赋的问题。世界上最优秀的故事讲述者也会犯错。几周前,《经济学人》的莎拉·利奥发表了一组[的优秀范例。](https://medium.economist.com/mistakes-weve-drawn-a-few-8cdd8a42d368)# 案例研究:电力负荷和温度为了展示我们如何掉进陷阱以及如何毫发无损地逃脱,我将使用一个公共数据集,其中包含希腊每小时的电力负荷和温度。为了简单起见,让我们只考虑 2007 年。我们想预测电力负荷,我们有兴趣了解温度如何有所帮助。起初,数据看起来像这样:![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/79e5683a3b665a2decb4eb7097152028.png)第一步可能是计算线性相关性:![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/18a095fa88b9940ad723677a1bcf1aa0.png)接* 0.42 的值没什么好激动的。这样说,我们就陷入了第一个陷阱:根据汇总指标得出结论。幸运的是,逃避相当容易:我们可以召唤一个简单的图表来拯救我们。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/df029207ee2411f6a9c7bacbde6ea619.png)电力负荷和温度之间的关系远不是线性的。因此,皮尔逊相关性是没有意义的。这对建模来说是一个很强的暗示:我们要么应用适当的特征工程,要么使用非线性模型。线性回归本身无法捕捉到这种模式。我们做到了!我们摆脱了第一个陷阱,并获得了建模的重要线索。不幸的是,我们不知不觉地陷入了第二个更微妙的陷阱。如果你仔细观察图表,你会注意到数据中有两种不同的模式。在图的左边:在一条几乎是直线的上面有一条更弯曲的条纹。起初,我们错过了这一点,因为一条重要的信息丢失了。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/b2cf89b4038bd276c7df321691251642.png)The color maps the hour of the day温度对电力负荷的影响随时间而变化。在图表中引入这个额外的维度揭示了另一个重要的证据:我们需要让模型知道一天中的某个时刻。例如,我们可以包括小时和温度之间的交互,或者拟合 24 个不同的模型。为了更清楚起见,我们可以只显示白天或晚上的时间:![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/2a9e4b5c7e977c3808dbe3eb124e2b51.png)![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/f6353fa3853ea864b108723125c3147a.png)最后,我们也克服了第二个陷阱,剩下两个正确设计模型的重要提示:*   温度对电力负荷有非线性影响
*   温度和负荷之间的关系随着一天中的每个小时而变化# 包扎最后,我们知道了数据探索的重要性和难度。我们检测到两个主要陷阱:*   **汇总指标**,可能隐藏数据中的复杂模式
*   **设计不良的图表**,这可能会导致错误的结论或妨碍更深入的分析我们没有找到一个单一的解决方案,但一些提示可能会有所帮助:*   尽可能喜欢直观探索,而不是汇总指标
*   尝试调查图表显示的所有不寻常的事情
*   确保你得出的每个结论在现实世界中都有意义我的读者,谢谢你来到这里!*如果您有任何意见、建议或批评,我恳请您通过我的* [*LinkedIn 个人资料*](https://www.linkedin.com/in/emanuelefabbiani/) *与我分享。**还有,如果你对本帖的话题有任何疑问或疑问,欢迎随时联系!*# 数据科学领域一年的经验教训> 原文:<https://towardsdatascience.com/lessons-from-a-year-in-the-data-science-trenches-f06efa6355fd?source=collection_archive---------13----------------------->![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/d9e8ebc5711832852f8030e3d29a956f.png)[(Source)](https://www.pexels.com/photo/photography-of-lake-beside-mountain-and-pine-trees-3351654/)## 在[学习将机器学习投入生产的五点收获皮层构建智能](https://get.cortexintel.com/)在过去的一年里,我已经从编写 Jupyter 笔记本的简单世界转向开发机器学习管道,以便全天候向建筑工程师提供实时建议。虽然我还有改进的空间(我仍然会犯很多编码和数据科学方面的错误),但我已经设法了解了一些关于数据科学的事情,我们将在本文中讨论。希望通过下面的课程,您可以避免我在日常数据科学前沿学习操作时犯的许多错误。1.  **生产数据科学主要是计算机科学**
2.  **数据科学仍然高度主观**
3.  **人际交往和沟通技巧至关重要**
4.  **使用标准工具,缓慢采用新技术**
5.  **用外在的简单隐藏数据科学的内在复杂性**作者注:这是从单一角度写的,不代表数据科学的整个领域。请记住,这是一位端到端(从概念到部署的机器学习系统)数据科学家在建筑能源领域的工作,为更有效地运营建筑提供实时建议。如果你有过不同的经历或者想反驳我,评论区等着你的回复。# 生产数据科学主要是计算机科学当被问及这项工作最难的部分时,我坚定地回答说这不是机器学习,考虑到我们所有的 ML 看起来都像:```
from sklearn import ModelModel.fit(features, target)
predictions = model.predict(testing_features)
```相反,数据科学最难的部分是开发建模前后发生的一切。在我们之前有:从数据库加载数据、特征工程、数据验证和数据处理管道(假设我们的工作在数据被摄取之后开始)。在我们需要验证结果之后,将任务设置为按计划自动运行,将结果写回我们的数据库,并发送 webhooks 来触发其他服务。这些外围动作,包括机器学习中的大部分工作,都需要扎实的计算机科学实践。A [与开发代码相关的一些](https://en.wikipedia.org/wiki/Best_coding_practices#Coding_standards) e 实践是编写许多短函数,每个函数做好一件事,开发实现相关函数的类,适当的[命名约定](/data-scientists-your-variable-names-are-awful-heres-how-to-fix-them-89053d2855be),对代码和数据编写单元测试,编写易于阅读的代码,以及不重复代码。此外,围绕代码本身还有其他计算机科学实践可以应用,如版本控制、代码审查、持续集成、代码覆盖和部署,这现在已经催生了一个完全独立的领域[机器学习操作](https://en.wikipedia.org/wiki/MLOps) (MLOps)。虽然我成功地完成了机械工程->数据科学家的转型,但现在回想起来,做工程->计算机科学->数据科学会更有成效。第二种方法意味着我不必忘记我在数据科学课上学到的糟糕的编码实践。换句话说,我认为在扎实的计算机科学背景之上加上数据科学比先学数据科学再从事计算机科学更容易(但两条路线都有可能)。计算机科学涉及一种完全不同的系统思维方式,在编码前有条不紊地计划,慢慢地写代码,一旦写好就测试代码。干净的代码与数据科学的自由天性形成鲜明对比,数据科学有几十个写了一半的笔记本(我们都有叫做`Untitled12.ipynb`的笔记本),强调立即获得结果,而不是编写可以重用的无错误代码。See also [https://www.youtube.com/watch?v=7jiPeIFXb6U](https://www.youtube.com/watch?v=7jiPeIFXb6U) for why notebooks aren’t always great所有数据科学家都可以从关于计算机科学最佳编码实践的[课程](https://software-carpentry.org/)中受益。结构化脚本和包、编写干净的代码、测试和记录代码的能力使得从探索性数据科学到生产机器学习的过渡更加易于管理。此外,他们灌输了一种思维模式,这种思维模式可以让其他人更容易理解可重用的代码。即使是通常编写数据科学脚本来为论文分析数据的学术数据科学家,也会受益于更好的实践。如果科学家编写更干净的代码,并包含单元测试来验证输入、输出和功能行为,那么科学中的[再现性问题](https://fivethirtyeight.com/features/science-isnt-broken/#part1)可能会得到改善。数据科学中有许多要学习的主题,有时会感到不知所措。然而,计算机科学不应该被看作是一种附加物;相反,它应该被视为希望看到他们的代码可操作化的数据科学家的基础。幸运的是,有大量的资源,例如[软件木工](https://software-carpentry.org/lessons/),任何人都可以用来学习和应用这些实践。# 数据科学仍然是高度主观的数据科学承诺使用数据而不是人类判断来做出最佳决策。这是一项崇高的事业,但它与当前的现实相去甚远,因为我们用来分析它的数据和方法在很大程度上受到了人类的影响。即使是数据科学的客观领域也依赖于人类行为。正如 Vicki Boykis 在她出色的 [Normcore Tech](https://vicki.substack.com/) 时事通讯中所说的那样,[神经网络完全就是人。](https://vicki.substack.com/p/neural-nets-are-just-people-all-the)典型的机器学习系统的每一步都受到个人选择的影响。以下是其中的一些决定:*   **收集数据**:我们收集什么数据?我们用什么传感器?我们调查谁?我们如何表达我们的问题?
*   **特征工程**:我们做什么特征?我们使用领域知识还是[自动化特征工程](/automated-feature-engineering-in-python-99baf11cc219)?我们如何填充缺失值?应该删除哪些观察值?
*   **建模**:我们应该用什么超参数?我们应该制作多复杂的模型?
*   **验证**:评估的指标是什么?验证程序是什么?我们需要什么水*的性能?
*   **部署:**我们是否足够信任这些数字并向客户展示?我们是否需要一个人来评估这些预测以进行理智检查?不可避免地,通过这个过程,不同的人会得出不同的结论。这方面的一个例子记录在论文[许多分析师,一个数据集](http://Many Analysts, One Data Set)中,该论文描述了数据科学家如何通过相同的数据集得出相互矛盾的决策,因为他们采用了不同的方法。毫不夸张地说,通过改变分析,你可以用一个数据集来证明一个论点及其对立面。这表明你不应该过于相信从一项研究中得出的任何结论,而是应该(带着怀疑的态度)看看[荟萃分析](https://www.sciencedirect.com/topics/neuroscience/meta-analysis)(并阅读 [*如何用统计数据*](/lessons-from-how-to-lie-with-statistics-57060c0d2f19) )。此外,人类的偏见,无论是有意还是无意,都会进入数据,从而影响机器学习模型。像 [*数学毁灭的武器*](https://blogs.scientificamerican.com/roots-of-unity/review-weapons-of-math-destruction/) 这样的书里说的那样,把决定权让给机器并不能消除歧视,而是把现实世界数据中出现的现有偏见编成法典。用数据科学结束偏见决策的目标是崇高的,但只要人类参与其中,我们就不能盲目依赖机器学习预测。数据科学中的主观性是否意味着我们应该放弃所有的真理观?我认为我们应该重新定义这个问题:我们不是寻找一个正确的答案,而是使用数据科学,不管它有多么有缺陷,朝着更好的解决方案的方向前进。毕竟,数据科学是科学的一个子领域,目标是[随着时间的推移](https://www.npr.org/sections/13.7/2018/02/12/585057058/a-new-goal-aim-to-be-less-wrong)减少错误。此外,越多的人致力于一个问题,并比较他们的工作,我们就越接*更好的结果。这 20 位科学家可能已经进行了 20 种不同的分析,但是如果他们比较他们的方法并一起工作,最终的结果将会比任何一个单独的项目都要好。在实践数据科学时,我们必须记住,数据科学像任何领域一样,不是没有缺陷的,不应该毫无疑问地被信任。实践负责任的数据科学意味着以[不确定性区间](/how-to-generate-prediction-intervals-with-scikit-learn-and-python-ab3899f992ed)呈现结果,寻找反驳你的结论的理由,将你的结果与其他类似工作进行比较,并在呈现发现时保持现实。由于数据科学依赖于人的判断,我们需要认识到…# 人际交往和沟通技巧至关重要虽然看似显而易见(有没有哪个领域的沟通技巧是不利的?),我每天都被提醒需要与技术领域的人有效地交流机器学习。[懂你的 ML 行话](https://developers.google.com/machine-learning/glossary)还不够;你需要能够在人们理解的范围内与他们见面,并且只告诉他们需要知道的细节。(举个有点幽默的例子,我的工作对一些人来说是“计算机的东西”,对另一些人来说是关于机器学习细节的半小时讨论。)至少在我们的情况下,机器学习决策不会取代人类的选择(即使它们[更准确](https://www.sciencedaily.com/releases/2018/05/180528190839.htm)),因为使用我们的建议取决于建筑工程师。(自动建筑运营可能比自动驾驶汽车更遥远)。仅仅建立模型、展示模型的准确性、将结果交给客户并期望他们立即实现预测是不够的。数据科学家仍然需要掌握混乱的社交艺术。你可以产生尽可能最好的机器学习模型,但如果你不能说服人们使用它,那么它就没有任何影响。我的工作中最常见的人员方面是通过写作和向内部和外部团队演示来解释方法,了解我们的客户当前如何做出决策,并与领域专家交谈以将其知识转化为数据科学系统。在大学里,我被告知数据科学家可以隐藏在完美客观的数字背后,但这些都没有被提及。即使你解释了计算机是如何做出决定的,这个建议也可能被忽略,因为人[并不完全理性](https://en.wikipedia.org/wiki/Predictably_Irrational)。当面对客观上更好的选择时,人们可能会出于各种原因选择另一个选项:习惯、缺乏信任、熟悉、错误信息。考虑风景路线的选择:有时,人们,出于似乎没有逻辑的原因,会在两个地方之间选择一条明显更长的路线。为什么?因为一路上还有更美的风景。一个天真的数据科学家可能只显示模型推荐的最短路线,但是,一个了解她的客户的数据科学家会知道,他们希望在他们的旅程中看到的不仅仅是无尽的州际公路。同样,最佳机器学习预测可能不会被使用,因为准确性不是唯一的考虑因素。例如,我们预测建筑工程师开始为他们的建筑供暖的理想时间,但许多工程师仍然会更早打开设备,因为他们不想让租户感到不适。这是不合理的(我们对我们的建议进行计时,以确保租户到达时大楼将处于正确的温度),但是,在我们将人类从决策过程中移除之前,我们将不得不使我们的计算机系统适应人类,而不是相反。或许除了你的计算机科学课程,还可以上几门社会学课程来了解你的人类同胞(或者读一些行为经济学书籍,比如理查德·塞勒的《T2》、《T3》、《行为不端》、《T4》、《T5》、《T6》、《T7》或者丹尼尔·卡内曼的《思考》、《快与慢》、《T10》、《T11》,两位诺贝尔经济学奖得主)。# 使用标准工具,缓慢采用新技术确保您的算法不包含任何错误的最佳方法是什么?从`sklearn`导入一个模型,而不是自己写。除非你在做前沿研究,否则几乎没有理由编写自己版本的机器学习模型。相反,使用广泛使用且经过良好测试的库(标准工具)中的函数来完成任务。在最*的一条推文中,我说最差的数据科学家编写自己的算法,最好的从标准库中导入。我是在开玩笑,但我支持这样的原则,即使用开源库中经过良好测试的代码几乎总是比开发自己的代码更有效。使用标准工具的逻辑不仅适用于机器学习模型。你想对数据集做的一切都已经在`pandas`中实现了(假设你使用 Python ),所以先在那里寻找一个解决方案。同样,有用于统计、绘图、测试、调度、部署任务和机器学习管道的大多数部分的标准库。我从两位博士数据科学家那里接管了我的职位,他们迫切希望(可能是为了证明他们的学位)发明自己的数据结构、度量、算法、文件加载等。,这导致了一大堆没人理解的乱码。我工作的前六个月主要是用三个 import 语句替换数百行脚本,直到今天,我还很自豪地成为我们机器学习库的净负贡献者。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/e758daed05a5fc084ca31b83d9f854e6.png)Via Negativa: [addition by subtraction](http://www.rationalwalk.com/?p=16047)而且,[不要因为新](https://vicki.substack.com/p/you-dont-need-kafka)就切换到新的库/技术/框架/数据库。像 SQL 数据库,机器学习的 sklearn 和数据操作的 pandas 这样的标准工具工作得很好。他们可能*淡无奇,因为他们(相对)老了,但他们也是经过考验和可靠的。作为早期采用者,一开始可能看起来很有趣,但是当你在错误和有限的文档中挣扎时,很快就会变得筋疲力尽。虽然新技术推动了媒体周期,但它们通常对实际工作的人和公司几乎没有直接影响([当心工程媒体](https://www.nemil.com/on-software-engineering/beware-engineering-media.html))。年轻时的我不相信我会这么说,但我现在更喜欢乏味的、经过验证的技术,而不是令人兴奋的、新奇的、尚未产生结果的技术。在内部,我们的工程团队对升级库版本进行了长时间的辩论,如果没有明显的好处或需要,那么我们不会升级,因为有新的版本。向我们的机器学习代码库添加一个库需要证明需求,因为另一个库意味着要管理另一个依赖。最长寿的公司是那些做*凡的事情并且行动缓慢的公司([像卡特彼勒](https://en.wikipedia.org/wiki/Caterpillar_Inc.)),而行动迅速并且做“酷”事情的初创公司往往会在几年后消失。最强大的机器学习系统不会是那些使用尖端技术的系统,而是那些坚持使用久经考验的数据科学标准工具的系统。# 用外在的简单隐藏数据科学的内在复杂性计算机非常擅长处理大量的数字。人类几乎无法比较几个数字。为了最有效地结合计算机和人类的能力,我们应该使用计算机来分析大型数据集,并只向人类提供最关键的数字来做出决策。数百万个数字输入,尽可能少的数字输出。内部是复杂的模型,外部是可行的建议。在过去的一年里,我发展了一个理论,一个图表的数据点越多,就不仅仅是一个小数字([也许是数字 7?](https://en.wikipedia.org/wiki/The_Magical_Number_Seven,_Plus_or_Minus_Two)),越没用。人类没有能力精确地分析复杂的定量图表。热图很酷,但是有没有人从一个有 1000 个数据点的热图和一个有五个数字的条形图中做出一个重要的决定?![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/a00b4050d84383ba00e0fd0f14c58456.png)Cool, but what am I supposed to do with this information? ([Source](https://jokergoo.github.io/ComplexHeatmap-reference/book/more-examples.html))作为一个通常喜欢细读数字和倾听机器学习模型细节的人,我很难习惯大多数人不想要更多信息的想法。顾客和做决定的人渴望外卖,就是这样。更少的墨水意味着更好的图表。(如果需要制作图表的帮助,请咨询[定量信息可视化展示](https://www.edwardtufte.com/tufte/books_vdqi)或[数据可视化基础】](https://serialmentor.com/dataviz/)。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/47f1f538e513b70839184e557941172f.png)Dull? Probably. Informative? Absolutely.外部简单性的论点并不意味着[只使用线性模型](/thoughts-on-the-two-cultures-of-statistical-modeling-72d75a9e06c2)。数据科学可能涉及复杂的算法和高度技术性的操作。只有数据科学面向外部的部分必须足够简单,非技术人员才能理解。尽管如此,小心不要把你的模型做得太复杂,以至于连你自己都不理解。以不能解释你的模型为代价,为了一个小的精度增益,值得一个混合模型吗?为了用外部的简单性掩盖内部的复杂性,使用可以帮助描述模型决策的工具。 [SHAP 值](https://github.com/slundberg/shap)是一种有用的技术,你可以在其他方法上再加一层。为了解释建筑物的最佳开始时间建议,我们采用包括工程特征在内的所有特征的 SHAP 值,并将它们组合成人类可以理解的特征组,如天气和内部建筑条件。我们采用复杂的机器学习算法,用我们能理解的 SHAP 值简化它,然后在向客户展示之前,用我们的知识进一步简化它。简化定量信息的一种方法是准备一份报告,从一个数字开始,然后根据需要添加其他数字(这也适用于图表)。这种相加的方法不是从几十个数字开始并删除它们,而是确保没有无关的统计数据进入演示和报告。记住,人不是计算机,你不应该像计算机一样呈现结果。# +1 每个人都有冒名顶替综合症的感觉,都会犯错;不要让任何一个阻碍你最后,因为这是数据科学(和其他职业)中的一个重要问题,这里有一个额外的教训作为鼓励:不要让冒名顶替综合症或错误让你沮丧。每个人都有某种感觉,他们没有归属感,或者他们最终会被发现无法胜任这份工作,所以如果你有这种感觉,不要担心。你不是唯一一个有这些想法的人,学习新东西和产生结果一样重要,而且,如果你相对较新,作为新手也有好处(比如找到解决问题的新方法)。此外,环顾四周,很容易看到人们取得巨大的成功,但你没有看到他们一路上遇到的所有失败(一种形式的[生存偏见](https://en.wikipedia.org/wiki/Survivorship_bias))。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/80449fd8d01ed5abb9ed7bd7b6365355.png)People have different areas of knowledge ([Source](https://psychologycompass.com/blog/overcoming-imposter-syndrome/))即使是最好的表演者也是从初学者开始的,她会犯(并且继续犯)一些错误。错误并不意味着你不应该成为数据科学家或计算机程序员;它们意味着你有机会学习如何把事情做得更好。我们需要更多的人和更多样化的数据科学人才,我担心我们将数据科学家描绘成精英,并且数据科学职位需要多年的经验,从而将有技能的候选人排除在外。你只能通过在一个领域工作来获得专业知识,这不是你在开始职业生涯之前就有的东西。事实是,没有进入数据科学领域的“典型”途径。如果你因为背景或缺乏经验而认为自己不属于这里,好消息是那是一种[认知扭曲](https://en.wikipedia.org/wiki/Cognitive_distortion);数据科学不是只为少数精英保留的职业。# 结论在这个领域工作了一年后,我最初对数据科学的无限乐观已经转变为谨慎的热情。机器学习可以很好地解决小范围的问题(比人类更好),但不是解决人类错误的万灵药。认识到该领域的局限性以避免过度推销数据科学至关重要。尽管如此,以现实的态度对待机器学习,并牢记这些教训,机器学习可以带来令人印象深刻的结果。最好的机器学习系统将[通过让我们更有效地工作来帮助人类](https://www.designkit.org/human-centered-design),而不是取代他们。我感谢反馈和建设性的批评。联系我的最佳方式是在下面的回复中,或者在 twitter 上 [@koehrsen_will](http://twitter.com/@koehrsen_will) 。# 波音公司关于生活在计算机化世界的教训> 原文:<https://towardsdatascience.com/lessons-from-boeing-about-living-in-a-computerized-world-74d89f40874f?source=collection_archive---------12----------------------->![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/5aaa45b80922f43eb436bf4d475cea61.png)波音公司在最*两起事故中遇到的麻烦引起了媒体的广泛关注。除了对波音公司、认证的政治和商业以及飞行时的安全感的影响,还有一些关于计算机和软件在我们生活中日益增长的存在的更重要的教训。作为背景,我受过软件开发和软件架构方面的培训,也读过无数的航空调查报告。为什么?因为它们是在重大不利条件下找到根本原因,然后改进系统以防止其再次发生的黄金标准。在学习和将学习付诸行动方面,没有哪个行业比美国航空业做得更好。这就是为什么波音公司的这一失误更加重要。生活中很多事情都是循环往复的。吸取教训,有时是艰难的。行为改变,安全措施到位。事情进展顺利很长一段时间。动机甚至对为什么会减弱的理解。直到重新吸取教训。这是人的本性。但是,除了波音和航空业,还有其他值得学习的地方。虽然调查仍在进行中,但很明显,这两起事件都是人类与一台顽固的计算机作战并失败的案例。随着计算机控制着我们生活的越来越大的份额,甚至在这场技术革命的几十年里,我们将越来越多地面对计算机在我们生活中的角色,它们不仅仅承担卑微和麻木的任务,而且还控制着影响我们生活的决策。有时候重大决策。有时甚至是生死抉择。他们不会总是做出正确的决定。那现在怎么办?当你确信计算机是错误的时候,你如何与计算机争论?打电话给主管?有人能控制电脑吗?在这种环境下,常识怎么可能占上风?随着计算机从低级工作人员手中接管任务,无论是收银台还是各种行政办公室,对这些工作人员的期望和培训都下降了。我们把过程、数据解释和工作流程外包给计算机,把最后一英里留给剩下的人。如果一切都符合软件设计师使用的工作流程图,那就太棒了。但是如果没有呢?职员有权做决定吗?职员受过做决定的训练吗?那个职员能控制电脑吗?在许多情况下,答案是否定的。计算机不懂常识,也不会听可能懂常识的人的话。回到波音第二:在航空业的顶端有两个对手——波音和空客。几十年来,他们遵循不同的飞机设计理念。波音来自一个时代,当时飞机仍然有所有的机械电缆和滑轮控制,而空中客车是一个相对较新的实体。在波音飞机上,计算机辅助飞行员,但直到现在,飞行员才是最终的控制者。空客飞机从一开始就被设计成由计算机监督飞行员的决策,并可能拥有最终决定权。波音公司事故中涉及的 MCAS 系统是计算机在后台工作并在波音飞机上顽固不化的第一个案例。飞行员没有被告知或训练过。所有的软件都需要测试。而且所有的软件都有 bug,否则我们永远也不会去安装安全更新和紧急补丁。如果计算机真的做出生死决定,而且它也有最后决定权,那么测试的门槛就会大大提高。这在预算、时间表和谁有权说“还没准备好”方面有文化含义。在多年设计受计算机影响程度更高的飞机后,空客公司应该已经做好了准备。波音公司可能在这方面措手不及,没有为这种类型的软件测试做好文化准备。他们显然被传感器的故障率弄得措手不及,而这些传感器本应驱动更高的安全措施,他们错误判断的不是系统的单个功能,而是多次重置后的累积影响。正是这种难以测试的东西,因为它超越了整洁的流程图,而是涵盖了复杂的系统交互。[根据《纽约时报》报道]事实是,在传统的编程中,人类将问题分解成许多小步骤和 if-then-else 决策。然后编写程序以极快的速度运行这些步骤。一旦程序写好了,就必须用尽可能多的场景进行测试,并验证预期的结果是否出现。问题 A 是这非常复杂和耗时。所以通常只有一小部分可以完成,作为测试覆盖率来衡量。剩下的就留给希望、信心和机会了。在大多数情况下,如果遗漏了什么,几周后总会有软件更新。问题 B 是在设计和测试过程中很难预见所有的排列。我们怎么知道我们真的想到了所有可能发生的事情?事实是我们不知道。我们可以建立统计模型,并获得更高程度的信心。但是我们必须承认会有不可预见的情况。那怎么办呢?嗯,计算机本身只服从命令(首先是程序员,其次是用户),它不会思考。因此,我们必须让人类来评估情况,并在这种情况下做出最佳决策。这当然要求人能够控制局面。任何飞行员都应该能够手动驾驶飞机,这意味着没有自动驾驶仪或计算机的指导。他们受过这方面的训练。在这两起事故中,他们显然都试图这样做。根据目前掌握的信息,计算机不会让他们这么做。这也应该是我们对人工智能的关注,下一波计算机将在我们的日常生活中占据一席之地。普通大众对 AI 了解不多,这个词本身就有相当的误导性。人工智能给人的感觉是,计算机可能在某些时候与人类不相上下。它可能拥有传统程序所缺乏的常识。也许在遥远的未来某一天他们会。传统程序和人工智能程序之间的关键区别在于,在传统软件中,开发者必须预见软件正在解决的整个复杂问题的每一个细节。在我们赋予计算机的越来越大的任务中,这面临着越来越大的挑战。人工智能可以解决一些更大的问题,因为不是所有事情都必须预先考虑和编码。程序可以学习输入和输出的模式,然后找到方法将相同的逻辑应用到开发过程中没有单独考虑的情况。不久前优步在亚利桑那州的致命事故可能会对此有所启发。为了训练自动驾驶汽车,这些算法需要输入数百万张标准交通场景和路况的图像。这有助于他们分析摄像头反馈,解码汽车面临的情况以及他们应该如何处理。问题是,训练中灌输的许多意象不够多样化,不足以应对偶尔出现的奇怪事情。就像一个女人推着自行车在黑夜中穿过街道。你能在谷歌上找到多少这样的照片?人类司机也可能第一次看到这一点。但是,人类驾驶员在做出最佳决策方面仍然更胜一筹。人类大脑比今天的人工智能系统有更多的生活经验。人工智能程序最终能与人类的判断并行吗?是的,一旦我们可以用 70 亿人一生的经历、一个世纪的历史中可能的和期望的结果来训练它。但这是一个完全不同的层面。这就是为什么我们应该对生活中的计算机持非常怀疑的态度。毫无疑问,它们以各种想象的方式让我们的生活变得更加美好。但是我们确实需要让常识占上风的方法。如果计算机是错误和顽固的,我们确实需要一个可以与之争论的人。如果必要的话,我们需要一种方法在适当的监督下控制电脑。最简单的例子就是 IVR 系统(用于客户支持的自动电话菜单)。你多久在自动菜单中找到一次答案?我想很少。我们都学会了在遇到非标准问题时,按“0”或说“代表”来点击退出按钮,并与人交流。顺便说一句,这通常是我们拨打支持电话的情况。我发现 IVR 系统是一个非常误导和令人沮丧的成本节约策略。但最糟糕的是,如果系统不让你按零或与人交谈。有一次,我试了三次听不懂我的外国口音后,T-Mobile 就直接挂了我的电话,说“对不起,我们听不懂你的话,再见!”。计算机赢得战斗但输掉战争的定义。幸运的是,这是一个简单的服务问题,而不是生死攸关的情况。这些天我用 AT&T。电脑是你的朋友。但它也可能是你的敌人。我们不要找麻烦了。## 其他想法以上为飞行员、办公室工作人员、收银员以及几乎所有与计算机工作流程交互的人提供了推翻计算机决定的机会。但是如何有序地做到这一点呢?作为系统设计师,我们不希望他们拔掉电脑上的插头。在飞机上,断路器面板长期以来一直是禁用故障系统的最后手段。因此,系统实际上必须设计覆盖用例。被授权的人必须表明他想推翻计算机的决定。通过这种方式,覆盖可以被本地化,它可以在数据模型中被标记,并且它可以在以后被跟踪以供审查和审计。一个明显的挑战是如何防止覆盖破坏数据模型完整性规则或软件中的其他假设。系统设计中的连锁反应是巨大的。当然,为覆盖设计的用例可能仍然不工作。这就变成了一个递归问题。在某些时候,只需要拔掉插头。在昨天的最新报道中,似乎在波音公司的第二起相关事故中,飞行员遵循了系统设计师的程序来超越系统,但仍然失败了。众所周知的断路器时间到了。人类是最后一道防线,没有例外。根据模拟器测试,飞行员有 40 分钟。)来诊断、隔离、超越、从情况中恢复并有机会成功。没时间和电脑辩论了。接*地面的故障具有更小的裕度。所有的智能设备不仅需要一个唤醒词‘Alexa,…’,还需要一个转义词‘Alexa,停止’。毫不含糊。否则,我们将在未来几年迎来#metoo 版本的人工智能。# 为洛杉矶市长埃里克·加希提做数据科学的经验> 原文:<https://towardsdatascience.com/lessons-from-doing-data-science-for-eric-garcetti-mayor-of-los-angeles-1abfc835eab0?source=collection_archive---------23----------------------->![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/f3adcbfcca41335216663e2118542a27.png)我一直梦想成为政府的数据科学家。我想通过数据解决与不*等和社会流动性相关的问题,因为这些是一些与我家非常接*的最有趣的问题。事实上,数据科学的这种特殊应用是吸引我进入这一领域的首要原因。过去一年,我一直在跟踪市长预算和创新办公室(MOBI)的数据团队(T1)的工作,所以当我获得在该办公室实习的机会时,我欣喜若狂。[洛杉矶市拥有美国第一数字城市的称号](https://www.lacity.org/blog/los-angeles-named-america-s-1-digital-city-for-third-year-row):数据团队的工作是美国端到端数据工作的黄金标准,从数据收集到分析和建模。我很高兴能沉浸在一个公共政策、信息技术和数据专家每天都在努力工作的空间里,不辜负这样的荣誉。我了解到,作为市长办公室的一名数据科学家,需要的不仅仅是数据科学本身,我在那里的时间让我能够探索这些数据的细微差别。当我探索为公共部门做数据科学意味着什么时,以下是我牢记在心的一些自我提醒。# 1.关注数据我的实习要求我在工作中扮演不同的角色。当我专注于构建一个可行的解决方案时,我倾向于戴上工程师的帽子去编码、插入数据并开始工作。有时手头的任务很简单,例如,生成一些数据集的可视化和汇总统计数据。但我经常不得不戴上决策者的帽子,问一些内省的问题,以超越表面层面对产出进行分析:*这些数字与社会和人口观察和/或过去的研究一致吗?进行分析的基础数据集有哪些漏洞和偏差?*此外,我不得不停下来思考这个过程本身:*我如何展示我的结果,使它们对决策者有意义?他们应该从这个项目中学到什么,他们还不知道的?有哪些数据没有讲述的故事应该得到解决?*科林·马洛在 1997 年的费希尔纪念演讲中把我的困境称为第零个问题。他认为,在我们能够分析数据之前,当然也是在我们有了模型之前,需要对现实世界的问题、与研究问题相关的人群、生成数据的研究以及数据集中的变量有重要的了解。在课堂上,我将干净的数据输入到模型或分析中,我的大部分努力都集中在优化过程和解释输出上。处理现实生活中的数据是一个更加复杂、多方面的过程,其中输入的细微变化并不总是会导致输出的预测性变化。在我所有的任务和项目中,我必须将数据及其叙述放在与所涉及的技术相关的前端和中心。尽管我的实习是编码密集型的,但我每天都会花时间阅读市长的新闻剪报,通过我们的 Slack 频道了解最新的推荐读物,并对办公室出现的每个话题进行自己的研究。一开始,我对在政府部门工作的经验知之甚少,甚至毫无经验。我必须熟悉办公室的愿景和使命,同时为之做出贡献。我不完全确定该问什么问题,我写剧本的意图是什么。因此,我不确定我对这个更大的问题有多大影响。我必须训练自己将数据视为组织内所有其他操作和结构的相关组件。确保我能接受各种任务和情况下特定问题的利益相关者之间的关系成为我的首要任务。# 2.设定意图![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/fa79ec3f26e7d786c3f09abe82715d21.png)my daily reminder on my way to work关于团队会议,我最喜欢的一件事是和我的队友一起为剩下的两周设定个人目标。不仅如此,我喜欢了解并成为我的队友的个人和工作相关的目标的一部分,而且我喜欢作为一个团队有一个共同的焦点和方向。我在整个实习期间一直强调的一个意图是上面的第一条。回顾过去,我意识到关注数据是发展**数据成熟度**的关键一步。我没有意识到持续挑战你的模型和分析是多么重要,不仅是在提高效率和考虑各种方法方面,而且是在涉及其他观点的方式上——技术的和非技术的——并对他们开放。我还了解到,作为一名数据科学家,需要一点创造力和随机应变的勇气。有人可能带着一个问题来到团队,但是他们需要回答的问题可能实际上不是他们正在问的问题。作为数据科学家,解开引导问题的意图至关重要。对于市长*台和数据所代表的人口/组织而言,一个项目或一项任务还有更多的内容。# 3.奥卡姆剃刀(有点)在数学或统计学中,[奥卡姆剃刀](https://simple.wikipedia.org/wiki/Occam%27s_razor)是一种解决问题的原则,在建立模型时拥抱简单(更少的假设)。我参与的项目教会了我如何构建简单、有针对性的解决方案来产生影响。例如,我的第二个项目是编写一个脚本,生成 GeoHub(城市的空间制图门户)内部使用的汇总统计和可视化。我们专注于涉及文件大小的汇总统计数据,以告知团队空间数据的使用情况,目标是改进存储。在决定了感兴趣的度量标准后,我可以专注于研究结果中的细微之处,产生与团队目标相关的叙述。我了解到,创建具有增量结果的快速修复是探索这些微妙之处及其不可预测的变化的好结果。通过利用简单的过程和分析,我们减少了可能进一步模糊复杂数据的不确定性的假设。# 4.讲个故事!我也是通过收入和租金人口统计研究首次接触到 ArcGIS 的。我如此习惯于在表格中表示数字供自己使用,以至于将这些数字嵌入地理信息的概念看起来很陌生。乍一看,我并没有真正认识到通过在地图中编织信息层来讲故事的力量。对我来说,数字更直观。但是我考虑到了我的队友在城市地理方面的知识(我对此并不了解!哈哈)我意识到我可以利用他们独特的视角来更有效地交流信息。现在,观众不用在汇总表中报告社区的中值收入,而是可以在彩色编码的交互式洛杉矶地图上看到中值收入的趋势。观众可以很容易地在同一张地图上切换查看租金中位数。比盯着一张枯燥的桌子看要有趣得多的锻炼。尽管我是城市地理学的新手,但像 ArcGIS 这样的*台给了数据科学家将数据无缝转换成不同形状的能力。意识到这些不同的转换可能会以不同的方式传达相同的故事,这是吸引不同观众的关键。我的项目的结果或输出不一定是最终结果,但它传达的故事产生了预期的影响。# 5.解决一个超出你想象的问题很多时候,我没有意识到向不同背景的人寻求帮助和意见的动机。例如,当我在一个项目中陷入困境时,我的主管建议我向该市另一个部门的成员寻求建议,他们已经解决了类似的数据合并问题,尽管她在人口普查部门工作,并且她的职位没有与“数据”相关的词。类似的去另一个方向。对我来说是第二天性的任务,如编写循环,被证明有助于帮助我的 GIS 专家队友在自动化脚本中编写快捷方式。因此,他减少了提取数据的体力劳动时间,现在可以专注于自己的专业领域。当我每天处理非常困难的问题时,我最终会找到解决问题的方法,这些方法超出了我的技能,也就是说,超出了我的头脑。认识到自己的弱点需要一些创造力和谦逊,在意想不到的地方寻求帮助需要一些勇气。在加州大学洛杉矶分校的最后一个季度,我每周两次通勤到市政厅,同时还要应付一门要求很高的课程。我非常感谢团队为一名初露头角的数据科学家营造的支持和关爱的环境——我希望我能在办公室花更多的时间和我的团队在一起。我意识到,实习期间的“面对面时间”对于让自己沉浸在数据背后的文化中,并最终理解数据科学中的数据是有价值的。我学到的技术技能至关重要,但数据科学不仅是技术,也是数据收集和构建背后的故事、文化和人员。## 参考资料:*   软糖科林。“第零个问题。”*《美国统计学家》*,1998 年第 52 卷第 1 期,第 1 页。,doi:10.2307/2685557。# 关于如何与统计数据撒谎的课程> 原文:<https://towardsdatascience.com/lessons-from-how-to-lie-with-statistics-57060c0d2f19?source=collection_archive---------0----------------------->![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/0d0e1dce44ad670ac2f92f9f208efd6a.png)[(Source)](https://www.pexels.com/photo/silhouette-of-trees-2058946/)## 永恒的数据素养建议*如何用统计数据撒谎*是一本 65 岁的书,可以在一个小时内读完,比任何关于“大数据”或“深度学习”的书都更能教会你每天可以使用的实用信息。尽管机器学习和 Pb 级数据承诺了一切,但数据科学中最有效的技术仍然是小表格、图表,甚至是总结情况的单个数字,并帮助我们或我们的老板根据数据做出决策。一次又一次,我看到数千个复杂算法的工作时间被总结成一个数字。最终,这就是最大的决定是如何做出的:用一些人类可以处理的数据。这就是为什么《如何用统计数据撒谎》(达雷尔·赫夫著)中的教训是相关的,即使我们每个人可能[在一天内产生的数据](https://www.weforum.org/agenda/2019/04/how-much-data-is-generated-each-day-cf4bddf29f/)比在写这本书时全世界产生的数据还要多。作为表格和图表的制作者,我们需要有效地呈现有效的摘要。作为信息的消费者,我们需要发现误导/夸大的统计数据,这些数据操纵我们采取有利于他人而损害我们利益的行动。这些技能属于一个被称为[“数据素养](https://en.wikipedia.org/wiki/Data_literacy)”的类别:阅读、理解、争论和从信息中做出决策的能力。与算法或大数据处理相比,数据素养似乎并不令人兴奋,但它应该成为任何数据科学教育的基础。幸运的是,这些核心思想不会随着时间的推移而改变太多,而且通常关于这个主题的最好的书(比如量化信息的可视化展示)已经有几十年的历史了。本文中讨论的经典书籍以简洁、有效和令人愉快的格式阐述了负责任的数据消费。以下是我从“如何用统计数据撒谎”中学到的经验,并附有我个人经历的评论。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/8f0d86d80dff0dbce6a33d5b9a4a88e1.png)The Classis Book on Data Literacy: “How to Lie with Statistics” [(Source)](https://www.google.com/url?sa=i&source=images&cd=&cad=rja&uact=8&ved=2ahUKEwijgYTJgNXjAhVQVd8KHctoCW0Qjhx6BAgBEAM&url=https%3A%2F%2Fwww.target.com%2Fp%2Fhow-to-lie-with-statistics-reissue-paperback-darrell-huff%2F-%2FA-11395199&psig=AOvVaw0U0FRS-6ApdqUQuZBgro7K&ust=1564313614376777)## 1.以怀疑的态度看待相关性当两个变量 X 和 Y 相关时——意味着它们一起增加,一起减少,或者一个上升另一个下降——有四种可能的解释:**A. X 导致 Y****B. Y 原因 X****C .第三个变量 Z 同时影响 X 和 Y****D. X 和 Y 完全不相关**当 C 或 D 同样可能的时候,我们经常立刻跳到——或者被引导去相信——A 或 B。例如,当我们听说更多年的大学教育与更高的收入正相关时,我们得出结论,更多年的大学教育会带来更多的财富。然而,这也可能是第三个因素,如努力工作的意愿或父母的收入,是更多年的高等教育和更高收入的背后原因。第三个隐藏变量会导致我们得出关于因果关系的错误结论。其他时候,两个变量可能看起来相关,但实际上彼此无关。如果你在数据集之间进行足够多的比较,你一定会发现一些有趣的关系,它们看起来是同步的。泰勒·维根在[记录了这些虚假的相关性。](http://www.tylervigen.com/spurious-correlations)![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/c90ac4d2558a116e0075f890ff7e9366.png)A Questionable Correlation [(Source)](https://www.google.com/url?sa=i&source=images&cd=&cad=rja&uact=8&ved=2ahUKEwjm16yEgtXjAhXtc98KHfMLB5sQjhx6BAgBEAM&url=https%3A%2F%2Fwww.tylervigen.com%2Fspurious-correlations&psig=AOvVaw05f4jHFaINXtZjcJ2N6YjL&ust=1564313998141351)我们都听说过这样的建议,相关性并不意味着因果关系,但即使有因果关系,也往往不确定它会如何发展。老师对学生的表扬越多,成绩越好吗?分数越高引起的好评越多吗?还是有第三个因素,更小的班级规模或更多的自然采光,导致这两个变量都增加了?原因问题由随机对照试验来回答,而不是由观察性研究来回答,在观察性研究中,我们不能排除我们没有测量的其他因素。为了避免被误导,通过寻找**混淆因素**来怀疑变量之间的相关性。人类喜欢简洁的因果叙述,但这通常不是数据告诉我们的。## 2.关系不会永远持续下去如果你已经成功地确定了一个相关性,不要假设它会永远存在,无论是正向还是负向。线性关系几乎总是仅在两个变量的有限区域内是线性的*。*超过一个点,关系可能变成对数,完全消失,甚至反转。这可以在随时间外推的生长曲线中观察到。有一些线性时期,经济以恒定的速度增长,但最终增长会趋于*稳,因为几乎没有什么东西会无限期地增长下去。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/63327ad2ce7d0364357125791f4f440c.png)Male Height vs Age Showing Leveling Off of Growth Curve [(Source)](https://en.wikipedia.org/wiki/Growth_curve_(biology)).在一个关系的适用范围之外进行外推被称为泛化误差。你是在利用一种本地现象,并试图将其应用到全球。随着人们摆脱贫困,他们往往会对生活更加满意。然而,一旦他们达到某个点(也许是 75,000 美元/年),幸福感不会随着财富而增加,甚至可能会减少。这表明财富的增加存在收益递减,就像人类活动的许多方面一样,比如为考试而学习。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/3c31b33f009c4d7d1a0428d41690a9a2.png)Happiness Increases with Wealth Up to a Certain Income Level [(Source)](https://www.richardcarrier.info/archives/13954)我们总是看到推断:公司增长率、人口统计、股票价格、国家支出等等。通常,人们会在一个地区使用有效的关系来表明一个地区的观点(例如声称 100 万美元/年将带来纯粹的幸福)。请记住,局部地区的关系并不总是适用于全球。即使你已经证实了因果关系——或者在图表中看到了——也要确保你不理解有限有效区域之外的内容。## 3.总是看图表上的坐标轴调整图表的轴来表示一个点是操纵图表的经典[技术。](https://venngage.com/blog/misleading-graphs/)作为首要原则,条形图上的 y 轴应该*始终*从 0 开始。如果不是,通过操纵范围来证明一个论点是很容易的,例如,把微小的增加变成巨大的变化:![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/2cb3dfe742d2038213fffb64507833b1.png)Misleading Graph That Does not start at 0 on the Y-Axes (Left) [(Source)](https://www.datasciencejunction.com/2019/01/how-to-be-cautious-about-misleading.html)另一个误导性图表的例子是不同比例的 y 轴。通过仔细调整价值,你会在不存在的地方创造出令人惊讶的趋势。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/880b4b359ee9f84ddfcc3e5655428135.png)A Misleading Graph Creating An Extreme Trend Where There is Only a Small Increase [(Source)](https://www.statisticshowto.datasciencecentral.com/misleading-graphs/)虽然这看起来像是一个明显的操纵,但广告商和报纸逃脱了惩罚,因为人们不阅读信息。大多数人看到一个图表,会立即从线条或条形的形状中得出结论,这正是制作图表的人想要的。要解决这个问题,请尝试读取轴值。一个简单的检查可能会告诉你变化并不像看起来那么大,趋势是从无到有的!一旦你做了一些制作图表的练习,你就会意识到操纵它们对你有利是多么容易。防止不准确数据的最好方法可能是亲自动手制作。(如果你想要一本关于制作合理的数据可视化的好书,可以看看爱德华·塔夫特的[定量信息的可视化显示](https://www.edwardtufte.com/tufte/books_vdqi)或者克劳斯·威尔基的数据可视化基础。)## 4.小样本产生令人震惊的统计数据如果我告诉你最高的癌症发病率往往发生在人口最少的县,你会惊讶吗?没那么震惊。如果我补充说,最低的癌症发病率也往往发生在人口最少的县,那会怎么样?[这是一个小样本情况下发生的经过验证的例子](https://en.wikipedia.org/wiki/Insensitivity_to_sample_size#cite_ref-4):极值。任何时候研究人员进行研究,他们使用所谓的样本:代表整个人口的人口子集。当样本足够大并且具有更大人群的相同分布时,这可能会很好,但通常,由于资金或响应率有限,心理、行为和医学研究是用小样本进行的,导致结果有问题并且无法重现。科学家通常被合法的问题限制在小样本范围内,但广告商通过进行许多微小的研究来利用少量参与者,其中一项将产生积极的结果。在评估一项研究时,人类并不擅长调整样本量,这实际上意味着我们将 1000 人试验的结果视为 10 人试验的结果。这被称为“对样本大小不敏感”或“样本大小忽略”。这是另一个例子。如果你认为自己懂数据,那么这个问题对你来说没有问题:> 某镇有两家医院。在大医院,每天大约有 45 个婴儿出生,在小医院,每天大约有 15 个婴儿出生。如你所知,大约 50%的婴儿是男孩。然而,确切的百分比每天都在变化。有时可能高于 50%,有时更低。
> 
> 在一年的时间里,每家医院都记录了超过 60%的新生儿是男孩的日子。你认为哪家医院记录了更多这样的日子?
> 
> 1.较大的医院
> 
> 2.较小的医院
> 
> 3.差不多(也就是彼此相差 5%以内)如果你猜是 2。,那么恭喜你,你懂数据!原因是样本量越小,数值越极端。(这是来自 Tversky 和 Kahnemann 的[不确定性下的判断:启发和偏见](https://www.its.caltech.edu/~camerer/Ec101/JudgementUncertainty.pdf)。我强烈推荐阅读这篇论文,并思考,无论快慢,来了解影响我们决策的认知偏差。)你可以通过掷硬币来检验小样本产生极端结果的原理。对于一个小样本,比如说 5 次投掷,你很有可能得到 4 条尾巴。这是不是意味着硬币总是 80%是反面?不,这意味着你的样本太小,不能得出任何有意义的结论。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/8e92cc9c7837fc8146fbaf98d250ad09.png)With smaller sample sizes, we get more extreme results [(Source)](https://breakingdownfinance.com/finance-topics/behavioral-finance/sample-size-neglect/)这种技巧通常在通过向少数人询问特定品牌来营销产品时使用。如果你反复调查小群体,只报告有利的结果,你可以得到令人印象深刻的数字(90%的医生喜欢这种牙膏)。问一个小组,看看结果,扔掉不好的,重复直到你得到你需要的统计数据!避免被小样本愚弄的解决方案是在数据中寻找观察值的数量。如果没有给出,那么假设无论是谁进行了这项研究,都有所隐瞒,这些数据是没有价值的。行为科学家已经表明,我们大多数人容易忽视样本量;不要犯同样的错误——相信大量的观察结果,而不是来自小样本的令人震惊的统计数据。## 5.看看所有描述数据集的数字检查样本大小可能是避免被数据愚弄的一种方法,但前提是样本大小已经提供。误导数据消费者的另一个技巧是避免列出描述数据集的相关数字,如观测值的计数、数据的分布(范围)、数据的不确定性(标准误差)、数据的分位数等等。其中的每一个都可以用来更深入地研究数据,这往往违背了提供数据集的人的利益。例如,如果你听说一个城市一年的*均温度是华氏 62 度,但不知道最高和最低温度,这是没有帮助的。这个城市可能会冷到零下 20 华氏度,热到 120 华氏度,但*均起来还是一个舒适的值。在这种情况下,正如在许多其他情况下一样,*单个数字不足以描述数据集*。作为书中的另一个例子,如果你有两个孩子,其中一个智商测试 99,另一个 102,你真的不应该告诉他们,以避免比较。为什么?因为[智商测试可以有大约 3 分的标准误差](https://psycnet.apa.org/record/1990-03261-001),这意味着一个曾经得过 99 分的孩子有大约 68%的几率会得到 96 到 102 分。总体差异可能并不显著,并可能在重复测试中逆转。换句话说,通过在结果中忽略预期的标准误差,你可以得出一个比数据更激烈的结论。不报告一个以上数字的研究通常有所隐瞒。同样地,如果一个图表看起来切断了一些数据,它是不可信的。通过子集化数据来改变叙述太容易了。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/31d21cc3ff14eb6dbc4f04b1a1887aba.png)Graphs can change based on data shown [(Source)](https://venngage.com/blog/misleading-graphs/)你可以这样想:如果有一种药能让寿命*均延长两年,你会服用吗?如果最坏的影响是损失 12 年寿命,最多增加 14 年寿命,你会改变主意吗?重要的通常是细节,一个汇总统计数据不能说明全部情况。## 6.检查使用哪个*均值另一个有用的方法是改变“*均值”的定义。你有 3 个选择(如果你聪明的话,可能更多):1.  *均值:将这些值相加,然后除以观察次数
2.  中位数:从最小到最大对数值进行排序,并找出中间值
3.  模式:找到最常出现的值我以前写过这个问题([详见这里](/how-90-of-drivers-can-be-above-average-or-why-you-need-to-be-careful-when-talking-statistics-3df7be5cb116)),基本思想是:一个分布的均值和中值只有在它是正态的情况下才是相同的,我们生活在一个主要有[非正态数据的世界](https://sciencestruck.com/types-of-skewed-distribution-with-real-life-examples?source=post_page---------------------------)。这意味着数据集的*均值和中值不是同一个值,通常相差很大。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/ca07a21f2064f4a1a2ed9e3c6e32fdce.png)Mean vs Median vs Mode in Normal and Skewed Data [(Source)](https://www.quora.com/Is-median-always-greater-than-mean)例如,美国[的*均收入和中值收入相差大约 16000 美元](https://dqydj.com/united-states-income-brackets-percentiles/?source=post_page---------------------------)。通过选择报告的*均值,政治家、营销人员和首席执行官可以从相同的数据中得出相反的结论。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/ae09d934900985e2a79479c77a707950.png)A skewed distribution with different mean and median [(from my story on types of averages.)](/how-90-of-drivers-can-be-above-average-or-why-you-need-to-be-careful-when-talking-statistics-3df7be5cb116)避免这种情况的方法是查看数据集的*均值、中间值和众数(同样,您需要所有这些数字!).找出哪一个是最合适的(通常是收入、城市规模、寿命、房价等高度倾斜数据集的中间值),如果你需要一个数字的摘要,就用它。如果可以的话,将整组数值绘制成直方图,并观察分布情况。试着用一个以上的数字来描述一个数据集,如果你报告一个*均值,请说明你使用的是哪一个!## 7.使用与公共基线的比较查看统计数据时,重要的问题通常不是值是什么,而是当前值与以前的值相比如何?换句话说,与绝对量级相比,相对变化是多少。如果我告诉你,2017 年美国国内生产总值为 19.39 万亿美元,这听起来令人难以置信,因为你的日常经历。然而,如果你与美国前一年的 GDP 18.62 万亿美元相比,它看起来并不那么令人印象深刻。数据通常在我们不熟悉的尺度上,我们需要与其他数字进行比较,以了解统计数据是否代表了真正的变化。火星*均半径 3389 公里大吗?我不知道这意味着什么,直到它与其他星球相比!![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/b8f89469abe74d98b020561887bde8b5.png)Compare stats to other similar numbers [(Source)](https://www.google.com/url?sa=i&source=images&cd=&cad=rja&uact=8&ved=2ahUKEwjk1MnshtjjAhWLVN8KHUiQAdYQjhx6BAgBEAM&url=https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FSolar_System&psig=AOvVaw3yOgcjG7f24zAzlDAvIRQA&ust=1564418379443499)我们不仅希望将统计数据与过去的值以及同一类别中的数字进行比较,还希望确保统计数据的定义不会改变。根据《如何撒谎》一书,美国农场的数量从 1930 年到 1935 年增加了 50 万,因为人口普查局对农场的定义改变了!降低失业率最简单的方法就是改变定义,将停止找工作的人排除在外。数据收集方式或数值定义的变化往往会产生被误认为实际趋势的极端结果。为了解决这个问题,首先,从整体上看整个系列的值。其次,确保定义在时间范围内没有改变。只有这样,你才能开始从数据系列中得出结论。你可以说[纽约在 2018 年发生了](https://en.wikipedia.org/wiki/Crime_in_New_York_City) 289 起谋杀案来吓唬人们,但当你将这一数字与 1990 年的 2245 起相比较时,你会意识到纽约市从未如此安全过!重要的通常是比较;不要让一个孤立的数字左右了你的理性思考。## 8.寻找样本选择中的偏差还记得我们谈到的从样本中收集的所有数据吗?我们希望这些样本能够代表总体?除了关注样本大小,我们还需要寻找样本中的任何偏差。这可能来自所使用的测量方法:固定电话屏幕可能有利于更富有、更年长的参与者。它也可能来自物理位置:只调查住在城市的人,因为它更便宜,可能会使结果偏向更进步的观点。样本偏差在政治民意调查中尤其普遍,2016 年的调查显示,有时样本并不能代表整个人口。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/2ed15bd7c9ec63f39aeea3418bd339f0.png)Sampling Bias in Action [(Source)](https://www.geckoboard.com/learn/data-literacy/statistical-fallacies/sampling-bias/)在检查一项研究时,我们需要问谁被纳入样本,谁被排除在外。几十年来,心理学和社会学研究一直受到这种怪异偏见的伤害。样本只包括来自西方、教育、工业化、富裕、民主国家的人(通常是大学生)。当参与者如此有限时,很难合理地说一项调查代表了全人类!我们还应该在我们的信息来源中寻找抽样偏差。现在,我们大多数人通过选择我们倾向于认同的信息来源,将信息选择偏见强加给自己。这导致了危险的情况,在这种情况下,我们不会遇到有不同意见的人,因此我们会变得更加固执己见。解决这个问题的方法很简单,但是很难:阅读不同来源的新闻,尤其是那些与你不一致的新闻。如果你是《纽约时报》的读者,可以试试《华尔街日报》。对于那些喜欢冒险的人,你甚至可以试着和与你意见不同的人交谈。虽然这看起来有点吓人,但我发现表面上不同意的人往往有更多的共同点——相同的核心驱动欲望——促使他们选择各自的立场。面对面地达成共识要容易得多,但即使是在网上进行文明对话也是可能的、有成效的,可以帮助你摆脱自我强加的信息选择偏见。总之,我们需要警惕外部取样偏差和我们选择媒体来源时自己造成的取样偏差。你不会喜欢有人告诉你只看一份报纸,所以不要对自己做同样的事情。不同的观点会带来更好的结果,整合不同观点的不同信息来源会让你对事件有更全面的了解。我们不能总是得到一件事情的完全真相,但我们至少可以从多个侧面看到它。同样,当阅读一项研究时,确保你认识到样本可能不能代表整个人群,并试图找出偏向的方向。## 9.警惕研究中的“大人物”,审查权威Huff 描述了一个“好名字”的想法,作为一个添加到一项研究中,赋予它一种权威的空气。医学专业人士(医生)、大学、科学机构和大公司的名字让我们自动信任他们产生的结果。然而,很多时候这些“专家”实际上并没有创作出作品,而只是间接参与其中,这个名字是为了迷惑我们而加进去的。其他时候,比如当卷烟制造商利用医生来销售他们的致命产品时,当局直接被收买去撒谎。避免被令人印象深刻的名字说服的一个方法是“确保病历报告上的名字位于病历报告的后面,而不是旁边。”不要看到一个机构的名字就马上假设这项研究是可靠的。我认为我们不应该看作者或大学,直到我们分析了统计数据,以避免我们强加给自己的任何无意识的偏见。即使结果来自一位公认的“专家”,也不意味着你应该毫无疑问地接受它们。权威人士的[观点是一种谬误,当我们假设拥有更大权力的人更有可能是正确的时候就会出现这种谬误。这是错误的,因为过去的成功与当前的结果是否正确没有关系。正如卡尔·萨根所说:“当局必须像其他人一样证明自己的论点。”(](https://en.wikipedia.org/wiki/Argument_from_authority)[出自*闹鬼世界:*](https://books.google.com/books?id=Yz8Y6KfXf9UC&q=Arguments+from+authority#v=snippet&q=Arguments%20from%20authority&f=false) *黑暗中的科学蜡烛*)。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/27506cc9a01099d586712f065a3a981c.png)The Appeal to Authority logical fallacy [(Source)](https://www.google.com/url?sa=i&source=images&cd=&cad=rja&uact=8&ved=2ahUKEwjOs9PIjNjjAhWIT98KHdFNC_kQjhx6BAgBEAM&url=https%3A%2F%2Ftheupturnedmicroscope.com%2Fcomic%2Flogical-fallacies-appeal-to-authority%2F&psig=AOvVaw3vwrBcjXOLbnJ7Co3UDiOV&ust=1564419925139695)正如我们在整个科学史中所看到的,没有人是不怀疑的(记得亚里士多德说过有五种元素吗?或者当 IBM 的总裁说“我认为大约有五台电脑的世界市场”。)许多最伟大的发现都来自于挑战权威和公认的智慧。一个有着响亮名字的统计数据应该和其他任何统计数据一样受到同样多的审查。统计和数据并不效忠于更高的权力。## 10.不要过于相信任何一个统计数字“如何对统计数据撒谎”的总主题是:用怀疑的眼光看待任何一个统计数据。任何数字都代表一组数据的精华,这些数据是由容易出错的人使用不完善的工具,在不断变化的条件下,在某个时间点对人口样本进行提取的。数据由另一个人分析,他为一个机构工作,这个机构可能有不同动机的外部资助者。最后,统计数据或图表是由出版商提供给你的,出版商有自己的利益让你相信一个想法。所有这些导致了两个结论:1.  如果你把所有的信念都放在一个数字上,那么你将会过度适应产生这个数字的特定环境。
2.  统计和数据从来都不是纯粹客观的。统计是对不确定数据的一种解释,旨在说服。我们不应该完全放弃统计和数据收集。有了正确的设计,研究可以发现关键的趋势——吸烟对你有害,[氯氟烃在臭氧层上制造了一个洞](https://news.nationalgeographic.com/news/2010/05/100505-science-environment-ozone-hole-25-years/),[更多的财富带来更多的幸福](https://www.visualcapitalist.com/relationship-money-happiness/),以及[氟化水极大地改善了牙齿健康](/a-great-public-health-conspiracy-73f7ac6fb4e0)——然后带来更好的总体结果。相反,我们需要承认数据收集和处理是一个不确定的过程,有许多因素影响我们看到的最终数字。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/eb33d60bfe5548ece509d0cbe0d21366.png)The identification and work to close the ozone layer hole is a data and environmental success story [(Source)](https://www.google.com/url?sa=i&source=images&cd=&cad=rja&uact=8&ved=2ahUKEwjl7OqRk9jjAhUFT98KHUX1CJkQjhx6BAgBEAM&url=https%3A%2F%2Fsvs.gsfc.nasa.gov%2F11781&psig=AOvVaw0gYXd4Z_LQcVK8vltOUw9R&ust=1564421545359104)人类是可变的,世界也是可变的——这是生活在其中如此美好的部分原因——所以我们应该警惕声称用一个图表或表格来概括它的统计数据。我们应该寻找值的范围,用置信区间报告数字,在下结论之前收集更多的数据,比较多项研究,并询问数据收集过程的设计。当证据的负担无可辩驳时,我们需要承认我们错了,改变我们的想法。也许没有适用于整个宇宙的客观真理,但随着时间的推移,我们会变得不那么错误。这基本上是科学的目标:每一项新的研究都让黑暗多一点光明。这也应该是数据科学的目标:通过每一个新的数据集揭示我们世界的更多结构。同时,我们需要认识到数据的局限性,不要过度概括。更多的数据不是万灵药,但是更多的数据加上辩论、多重分析和审查可以带来更好的现实世界决策,这就是我们作为[数据素养公民所希望的。](https://en.wikipedia.org/wiki/Data_literacy)# 结论如果我在数据科学领域学到了什么,那就是最有效的消磨时间的方式是用 4 个数字做一个条形图。机器学习建模是前沿的,但最终,CEO 想要看到的只是一个简单的图表,她可以从中得出结论。这本身没有错:作为数据科学家,我们的工作是从大量数据中提取意义。意义并不意味着显示几百个数字,它意味着显示有限的几个具有高价值的数字。我们呈现这些数字的方式会对它们的使用方式(或是否使用)产生很大影响。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/084dbe5790405d542568af331bae56b4.png)Simple charts are usually the most effective [(Source)](http://www.storytellingwithdata.com/blog/2018/3/9/bring-on-the-bar-charts)数据素养意味着拥有解释图形、图表和统计数据并得出可行结论的技能。这些结论不一定与制作图表的人一致,当他们一致时,你应该持怀疑态度。作为数据产品的消费者,我们需要了解操纵数据来证明一个观点或将消极因素转化为积极因素是多么容易。练习阅读统计数据和可视化数据——实际上是阅读一个数字——会有所帮助。另一个有用的策略是自己制作大量图表。练习使用最好的技术,并确保不故意误导他人。这个世界不是一个糟糕的地方,但有人不把你的美好愿望放在心上。通常,他们会利用数据作为工具,说服你按照他们的利益行事,而不是按照你自己的利益行事。对抗这些策略的最佳屏障是基本的数据素养:理解数据是如何被操纵的,以及你可以突破错误观念的方法。适度的怀疑对你个人和整个数据科学领域都有好处。记住这些教训,走出去,做一个负责任的数据生产者和消费者。一如既往,我欢迎反馈和建设性的批评。你可以在推特上找到我。# “无限记忆”的教训> 原文:<https://towardsdatascience.com/lessons-from-unlimited-memory-f0791e7df56?source=collection_archive---------22----------------------->## 我如何学得更好。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/28019dda529c5f0df9bf980098d4cdf7.png)Photo by [Kimberly Farmer](https://unsplash.com/@kimberlyfarmer?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) on [Unsplash](https://unsplash.com/search/photos/learning?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)有无数关于数据科学的资源(以及你可能感兴趣的任何东西),但是你如何真正地学习它呢?比我愿意承认的更多的时候,我发现自己在课程和辅导之间跳来跳去(也许什么也没完成🤦‍♀).我知道这不是学习新概念的有效方法。所以我决定从技术上退一步,学习如何更有效地学习。我找到了凯文·霍斯利写的《无限记忆》这本书。这是一本很棒的读物——短小精悍,额外的好处是可以用亚马逊的 Kindle Unlimited 免费阅读!我从他的书中获得了很多可行的建议,但我的三大收获是:*   别找借口了。
*   你相信什么,你就会成为什么。
*   用心学习。## **别找借口了。**霍斯利首先问你会找什么借口不读完这本书,或者用你学到的东西,或者做出改变。这让我想到了为什么我还没有发表下一篇文章的借口…我最喜欢的包括我太累了,或者太忙了,还有我不够聪明。我喜欢 Horsely 称借口为“思想病毒”。他解释说,借口会让你变得更弱,阻碍你的注意力和精力。你不能既有成功又有借口。所以别找借口了。## **你相信什么,你就会成为什么。**可能有点嬉皮,但是太真实了。我是嬉皮士的忠实信徒。所有的自助和呜呜呜的建议绝对在我心中占有一席之地。你吃什么就是什么。你成为你所相信的人。> 如果你相信自己的极限,你的人生将会非常有限。霍斯利写道“你的信念是关于你自己的故事,你已经接受它是真实的”。所以你必须学会控制内心的声音,并训练它去创造有益的故事。一个很好的方法是可视化冥想:我找一个安静的地方,在我的手机上设置定时器(只要 5 分钟就够了!),并想象我的梦幻世界。## **用心学习。**Horsely 教导我们坐下来学习时要有强烈的好奇心。如果你没有一个强烈的目标,你就不能有效地学习。这个对我来说也很重要。我无法告诉你有多少次我开始学习 x 话题,然后几个小时后我就像掉进兔子洞一样,甚至不在同一个字母表里——我仍然对 x 一无所知。> 你的思想从不徘徊;它走向更有趣的东西。尤其是在数据科学领域,有无数的教程和书籍、博客帖子和视频——你不可能消费所有的内容。选择一件事来学习,并真正地学习它。完成那门课程。完成教程。完成项目…或文章。😳你不能把半成品放在你的文件夹里。我是这里最糟糕的罪犯之一。但是,我承诺带着目的、兴趣和好奇心去学习。## 结论《无限记忆》是一本很棒的速读读物,里面塞满了令人振奋的可操作的花絮。这给了我一个小小的激励,让我可以回去工作,提高自己的技能,每天学习新的东西。因为,正如霍斯利所言“学习不是目的地;这是一个持续的过程。”# 我作为数据科学家第一年的经验教训> 原文:<https://towardsdatascience.com/lessons-in-my-first-year-as-a-data-scientist-1a03f34a88ea?source=collection_archive---------35----------------------->![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/46a88b29586e77cb4f82da54be3b9c6f.png)Photo by [Briana Tozour](https://unsplash.com/@britozour?utm_source=medium&utm_medium=referral) on [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral)当了一年数据科学家后,我写下了这些想法。现在,几年后,它们仍然是真实的。举例来说,我在一家医疗保健公司工作的第一年,数据科学小组的行为有点像一家咨询公司——我们会接手一些项目,以创建预测模型并提供其他分析支持。出于这个原因,我学到的许多经验教训更多地与在业务中运营数据科学项目的问题有关。在接下来的几年里,这些教训让我受益匪浅。# 特征工程很重要这一年的一大教训是,特征工程是建立预测模型的最重要部分。对于任何有很多机器学习经验的人来说,这可能并不奇怪,我在开始时肯定听说过这一点。但老实说,在我开始之前,我很难想出什么时候或为什么它很重要的例子。在实践中反复看到这样的例子,真的让我有了更深层次的理解。如果你的特性很糟糕,你使用什么样的模型并不重要,能够理解什么样的特性会有用是一项需要抽象思维和直觉数学的技能。这就是机器学习难的地方。# 获得最佳性能并不重要当我最初学习数据科学和机器学习时,有很多对性能指标的强调。事实是,对于几乎每个项目,你可以很快获得项目实际价值的 90%,而最后的 10%将花费你十倍的时间。对于大多数项目来说,这是不值得的。虽然使用 Kaggle 时,您希望尽可能完善模型,因为您选择的性能指标 0.01 的增长可以成就您,也可以毁灭您,但在现实世界中,微小的增长很少会有影响(尽管显然这取决于行业和项目)。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/a466f5f0c32a5efb1be52a58aaae8555.png)Photo by [Campaign Creators](https://unsplash.com/@campaign_creators?utm_source=medium&utm_medium=referral) on [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral)# 项目最难的部分不是机器学习,而是其他一切比知道如何构建最佳预测模型更重要的是,知道如何将业务问题转化为预测模型可以帮助解决的问题,并将预测模型转化为可操作的东西。当其他部门的人听说我们可以建立预测模型时,他们通常会想到一些他们认为预测起来会很有趣的想法。通常,他们的想法没有意义,但解释为什么会这样,涉及的技术问题,并提出可行的替代方案——这很重要。同样重要的是,一旦建立了模型,输出实际上是可用的——预测事情很容易,但通常只有当它带有一些额外的洞察力时,预测才有用。使用像 [lime](https://github.com/marcotcr/lime) 这样的工具是有用的,也是解决方案的一部分,但有时你的功能对于最终用户来说是不可操作的或不容易理解的,所以 lime 是有用的,但不是灵丹妙药——需要投入更多的思考,而不仅仅是把 lime 粘在最后。# 在你开始一个项目之前,问正确的问题最后,这可能是我今年艰难学到的最重要的一课:在投入太多精力或承诺任何期限之前,确保你事先知道数据将来自哪里,项目将如何使用。有人向我描述了一个项目,我很兴奋地着手处理,并承诺很快就能完成,结果却发现编写算法是容易的部分。我得到了一份数据样本,并认为这意味着我有一个获取数据的流程。实际上,并没有这样的过程,而且要花几个月的时间才能弄清楚如何访问必要的数据。尽管大部分时间都花在了等待人们回复电子邮件上,这样我就可以追踪并获得必要的数据,但我最终还是因为超出了我最初的时间估计而看起来很糟糕。在大公司里搞清楚数据管道真的很难!当另一位数据科学家离开时,我还必须接手一些在我之前开始的项目。一个是放在一起帮助导航和可视化一些文本数据的仪表板。当我与最终用户交谈,询问他们还想对项目做些什么时,我惊讶地发现,他们想要的所有更改都包括删除功能。仪表板被大规模过度设计,它的一些主要功能要么被移除,要么被保留,但从未被使用过。更糟糕的是,仪表板从来就没有打算长期使用,一年后就会退役,所以这些功能没有机会找到最终用途。这意味着时间被浪费了两次——一次是创建这些功能,另一次是返回并删除它们以简化控制面板。这一经历和其他经历真正教会了我,无论我在做什么项目,都要和最终用户建立紧密的反馈回路。两周一次的半小时会议可以节省很多时间。# 我在开发人工智能策略中学到的经验> 原文:<https://towardsdatascience.com/lessons-ive-learned-developing-an-ai-strategy-45e3f7c18426?source=collection_archive---------19----------------------->## 大公司如何建立人工智能战略?他们如何在 AI 时代建立竞争优势?他们如何构建 AIoT 生态系统?![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/5407ad8227408a05658ae63af9f13781.png)作为一家全球科技公司的顾问,我在过去的两年里一直在研究这些问题。在这篇文章中,我想展示一家大公司是如何思考和构建其人工智能战略的。许多公司正在试图从低成熟度的状态过渡到人工智能优先的模式。然而,成为一个人工智能优先的组织被证明是极其困难的,但也是非常有益的...# 数据和竞争优势我相信大公司已经到了**运营人工智能**的时代。他们有几个人工智能项目已经投入生产,并在其流程或产品中带来了真正的附加值。此外,他们已经将人工智能结果确立为整个公司的新标准,并正在进行持续的改进。在考虑人工智能之前,我们花了很多时间通过几个计划(策划数据管道、数据湖等)来改善我们的数据文化。).它是人工智能生态系统首先工作的基础。显然,拥有高质量数据的数据湖的公司可以训练出最好的 AI 系统;最好的系统有最广泛的用途;这些系统的广泛使用为拥有最佳人工智能系统的最大公司的数据湖贡献了更多数据。然后,这些数据可以用来改进现有的模型,并创建全新的模型,从而形成一个强化/虚拟循环。那些拥有最多数据的人往往能够训练出最好的人工智能系统,而那些拥有最好人工智能系统的人往往能够收集到最多的数据。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/019d2ed4a53fa78568f4cad331451318.png)这场数据竞赛具有重要的战略意义。事实上,一旦收集到足够的数据**(实时数据收集的过程是高效的)**试图进入该行业的新公司几乎没有选择,只能依赖先行者控制的数据。**我相信,当涉及到数据& AI 时,先发优势的想法更加强烈。**事实上,访问大量相关的数据集意味着收集数据的新努力注定非常耗时,因此在商业上也很困难。> 我们的目标是达到数据统治的水*。我认为,许多公司花费大量时间和金钱积累的数据资产并不真正值得这么多**,因为从数据的角度来看,它们并没有提供一种主导市场的方式。**最好的情况是,你的专有数据非常有价值(复制起来很难,成本也很高),这就是为什么免费的数据如此之少。我相信,随着时间的推移,开发您的专有数据存储库将会产生价值和防御能力。我们制定战略时谨记,我们的数据是捍卫我们市场地位的一种方式。数据统治也使你能够测试各种基于人工智能的想法。由于预算原因,小公司承担不起这么大的风险。您的数据优势越小,您的数据战略与业务战略分离的可能性就越小。**受益于人工智能的公司比竞争对手更早投资,这绝非偶然。**很明显,还需要准备好关闭早期阶段没有明显收益的人工智能概念验证。越早开始,竞争对手就越难赶上。更好的预测将吸引更多的消费者,更多的消费者将产生更多的数据来训练人工智能,更多的数据将导致更好的预测,以此类推,形成良性循环。**过早采用可能代价高昂,但过晚采用可能是一个战略错误。**另一个经常被低估的重要因素是发展伙伴关系的必要性。我们花了很多时间思考如何通过与其他组织、大学、数据提供商或政府部门合作来积累更多战略数据。建立互惠互利的关系可以为您的公司提供独家数据和相关利益。*   大型公司和创业公司我注意到,尽管拥有大量数据,但大公司仍在努力构建有效的人工智能系统。另一方面,人工智能创业公司缺乏相关的高质量数据集来训练他们的模型。这种情况创造了一种环境,在这种环境中,两个实体需要并经常相互合作。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/89f968cc09c212eab208e3e9e8db97f8.png)大公司坐拥大量数据,他们甚至不知道如何处理这些数据,所以通常情况下,需要帮助的是那些人,但另一方面,初创公司,如果他们只使用开放数据,他们可能不具备训练算法所需的相关性和质量。*   开放数据我也意识到只有少数大公司倾向于使用公开数据。事实上,许多公司认为,公共部门组织公开发布的数据往往质量很差,需要进行广泛清理,并与其他专有数据集结合起来,以证明其有用。然而,许多人工智能系统实际上主要或专门针对开放或可公开访问的数据进行训练。例如,可以对来自维基百科或 Twitter 等社交媒体的文本训练自然语言处理系统。*   用更少的数据做更多的事我们也非常重视一切可以帮助我们用更少的数据开发项目的东西。事实上,我们已经依赖数据增强技术或转移学习来提供帮助,但在未来,由于利用数据的新方法,我们可能会看到另一种转变。# 商业模式和数据决策者现在意识到,传统的商业模式在持续混乱的商业环境中根本行不通。建立人工智能战略的一个关键挑战是找到收集有用数据的方法,并用它们来加强你的地位。收集数据的最有趣的方式之一是,即使没有机器学习,也要构建一些有价值的东西,然后以一定的成本出售,以收集数据,甚至免费提供数据。通常,这种策略经常被创业公司用作商业模式。> 当您希望通过从一开始就向用户提供大量价值来收集大量数据时,这种构建“数据陷阱”的想法非常有用。数据枯竭只是产品效用的副产品。我们还试图将讨论从数据转移到智能产品和流程上。的确,数据可能是基础,但基础需要被设计成支持位于其上的东西:更智能的产品和业务流程。我们的目标是通过人工智能增强我们所有的产品或后端操作,并为最终消费者创造真正的附加值。我经常听到人们说“我们必须进入 AI”,但这是一个错误。**问题的一部分在于,没有人工智能商业案例这种东西。**相反,商业案例将针对特定的商业场景、问题或用例,将人工智能方法和技术作为整体解决方案的一部分。在我们的大多数人工智能项目中,我们非常注意在维护我们的品牌形象(精度、效率等)之间找到正确的*衡。)以及我们的模型提供的整体准确性。**没有一个模型是 100%没有错误的。**模型总会犯一些错误,但你要知道错误的后果是什么。它将如何影响您的品牌形象?你的客户会有什么反应?…*   创造新的收入来源由于人工智能的出现,我们还寻求通过利用我们所掌握的新信息来创造新的收入来源。我们使用这种方法来推动整体增长,通过这种方法,公司可以使用人工智能来不断识别结合自身和外部数据的领域,从而为他们提供进入新市场的途径。**商业模式的转变在建立长期竞争优势方面具有战略意义,因为当公司使用人工智能做新的事情而不是做同样的事情时,人工智能在推动增长方面最有价值,只是稍微好一点**。例如,通过聊天机器人应用人工智能来改善你的网站体验听起来很棒。但是,越来越多的公司做同样的事情,这不再是差异化。我们总是试图改变客户体验,提供全新的东西。*   销售知识我们也想了很多关于如何销售由于我们的人工智能计划而产生的见解。AI 的知识捕捉能力为企业创造了一个从销售实体产品转向销售知识的机会。例如,一个最先进的制造工厂可以使用人工智能系统向同行业的竞争对手展示其知识或流程。# 建设文化人工智能不仅仅是一种技术解决方案。我们花了很多时间围绕它建立一种文化。事实上,现在不同的部门不再互相争斗,而是分享他们的创新知识,以提供定制的、有凝聚力的客户体验。为了改进我们的流程,我们决定用机器学习来改革公司。我们意识到推广我们的数据集和挑战成为潜在雇员的强大诱惑。从人工智能采用的早期阶段及以后,许多公司要么止步不前,要么由于从数据、人才到技术本身的几个障碍而放缓。虽然人工智能提供了打开新市场和创造新收入流的独特能力,但当在整个企业范围内大规模实施时,它的好处会最大化。我坚信一个人工智能的策略是不够的。在探索和利用战略机会方面,用人工智能制定战略同样重要,甚至更重要。优化精心选择的 KPI 成为 AI 的战略目标。# 新手数据科学家在真实数据团队中工作的经验教训。> 原文:<https://towardsdatascience.com/lessons-learned-by-a-rookie-data-scientist-from-working-in-a-real-data-team-4091f33055fe?source=collection_archive---------32----------------------->![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/b222013f8dbba951b26e41fb27c41e25.png)在写这篇文章的大约两个月前,我是一名本科生,对机器学习和数据科学有浓厚的兴趣,并有一些有趣的个人项目。但在此期间,我在一家名为 SocialCops 的数据智能公司实习,担任数据科学职位。这是我人生中最陡峭的学习曲线之一,帮助我了解了成熟的数据驱动项目的复杂性以及数据团队的功能和本质。以下是我的一些关键收获,这些是我从其他在线课程或个人宠物项目中永远得不到的。我希望当他们从事第一份数据科学工作时,他们能帮助像我一样的其他人—1.  规模是克星如果这是一场 kaggle 竞赛,一个 7Gb 的模型以 x%的准确率给出你的最终预测,就像一个 2Mb 的模型以 x-1 %的准确率给出你的最终预测一样好。在现实生活中,没有那么多。不仅要考虑模型的当前性能,还要考虑它将如何随着时间的推移而发展,这是至关重要的。更快的迭代需要敏捷模型。可以通过添加新数据来改进的模型,并且不需要大量资源来部署和获取反馈。认识到准确性不是唯一的衡量标准,可伸缩性也是同样重要的因素,这一点至关重要。2.团队交付,不仅仅是数据科学家在我通常的宠物项目中,我是清理数据的人,是尝试模型的人,是忽视其可重复性和可持续性的人。增加价值的项目是由数据团队共同努力完成的。这可能是一个大约 7-8 人的团队,有时也取决于团队和组织的成熟度。数据科学家是团队的一员。其主要角色是从数据中推动分析,收集和报告见解,并在需要时使用统计和深度学习模型来协助分析过程。另一个是数据工程师。他处于后端软件开发和大数据分析师之间的中间位置,通常负责管理数据工作流、管道和 ETL 流程。然后是业务团队的成员,他们与客户沟通,了解他们的问题,并将其传达给团队。他们还从团队中获得见解,并根据最终用户的需求进行分解,然后传达给他们。除了这些人之外,通常在工作良好的数据团队中,还有来自组织高层的人参与团队的日常运作。他们有助于团队在组织中的存在,并向其他人传达团队成员的工作。3.安全和信任数据是新的石油。数据也是新的电力。如果不小心的话,两者都可能被偷或误用。在本地机器上处理敏感数据是一大禁忌。数据不能根据个人的奇思妙想自由进出。与您的组织共享数据的个人和组织的信任至关重要。信任通过安全来保证。每个数据源以及为处理该数据源而编写的每段代码的安全性。负责这件事的人肩负着巨大的责任。作为一名实习生,记住我工作的安全方面并明智地使用和存储我的数据对我来说非常重要。如果是你的个人项目,这种情况几乎不会发生。因此,在处理数据及其流程时保持警惕,是需要采取的必要步骤之一。4.交流。问吧。不要卡住。当你在一个组织中工作时,与你在一个个人项目中工作时相比,有一件事是非常不同的,那就是你周围有许多聪明的头脑。肯定有人研究过你将要使用的这个新框架,或者你将要尝试的那个新的预处理技术。最好是礼貌地请求这些人给你一些宝贵的时间,一旦你对你将要尝试的事情有了一个很好的背景,就和这些人进行一次一对一的头脑风暴。这将给你一个明确的项目路线图,并消除你可能有的任何错误观念。如果你已经被一个小错误困扰了一段时间,这同样适用。问!除了知识/代码/实现部分之外,这个领域还有很多东西需要学习。我认为这让它变得更加有趣和吸引人。我很感激能在 SocialCops 这样的地方和环境中迈出我职业生涯中重要的第一步。我希望这篇文章能对那些即将踏上类似旅程的人有所帮助。干杯!# 构建人工智能写作应用的经验教训[指南,开源]> 原文:<https://towardsdatascience.com/lessons-learned-from-building-an-ai-writing-app-guide-open-sourced-6f661f9caec6?source=collection_archive---------41----------------------->![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/daf90f290ee1ee1f7b9f9998ebbb9a1f.png)[**writeup.ai**](https://writeup.ai) **是一个开源的文本机器人,与你一起写作。**它(大部分)由 OpenAI 的 [GPT-2](https://openai.com/blog/better-language-models/) 驱动,并有额外的微调型号:*   合法的
*   文案和使命陈述
*   抒情诗
*   [文学作品]哈利波特
*   《权力的游戏》
*   学术研究文摘主要的技术挑战是创建一个能够快速******支持 10-20 个重度用户的应用程序,该应用程序可以交付 OpenAI 的 GPT-2 媒体(一个生成文本的 ml 模型)。******# ****初始状态:*****   ****开始是作为学习在 NLP(自然语言处理)中训练 ML 模型的借口。我最终主要学习了部署模型。****
*   ****估计要一个月才能建成。不对。花了我三个月的时间。****
*   ****工程师很难估计。过分自信的傻逼估计就更难了(咳)。****
*   ****遗憾的是,我对训练模型了解不多(lol)。还是什么都不知道。****
*   ****许多开源的训练脚本( [nsheppard](https://github.com/nshepperd/gpt-2/tree/finetuning) )做了繁重的工作。发现 gwern 的 [GPT2 指南](https://www.gwern.net/GPT-2)对于培训教程来说非常有价值。另一个很棒的快速入门工具是 Max 的 [gpt-2-simple](https://github.com/minimaxir/gpt-2-simple) repo。****
*   ****writeup.ai 大部分都是开源的。我添加了相应的链接,从我的错误/失败中吸取教训。我还在 GitHub 中添加了代码的直接链接。****# ****链接。它是开源的!********app—[https://write up . ai](https://writeup.ai)
[前端回购](https://github.com/jeffshek/writeup-frontend)
[后端回购](https://github.com/jeffshek/open)****# ****背景:*****   ****在 [React](https://reactjs.org/) 、 [Django](https://www.djangoproject.com) 、 [Flask](https://palletsprojects.com/p/flask/) 做了太多年的网络应用。****
*   ****对机器学习(ML)和 MLOps(机器学习 devops)不熟悉,所以请以健康的怀疑态度阅读任何建议。****# ****读者:*****   ****一些网络开发的背景是必要的,但是我积极地用行话来帮助链接。****
*   ****机器学习的基础知识是有帮助的。****# ****警告:*****   ****简明扼要的要点。****
*   ****完整的短语和缩写。即。机器学习>机器学习****
*   ****在大多数情况下,模型意味着机器学习模型。编写“ML 模型”是多余的。****
*   ****供应商锁定是真实的。享受了[谷歌云*台](https://cloud.google.com) (GCP)这么多,从来没有打算离开。一些建议以 GCP 为中心。****
*   ****GCP 部署和扩展 ML 资源比以前的 AWS 体验更好。****
*   ****电子邮件,[推特](https://twitter.com/shekkery),评论任何你想澄清的事情。****# ****技术架构:********![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/6d39fd53c9c1cc9b87daff04453a43fe.png)*****   ****前端(ReactJS)加入后端(Django)上的 WebSocket。通过 WebSockets 与后端通信。[前端代码](https://github.com/jeffshek/writeup-frontend/blob/8e2699cd7fffbe301673c32db272ff4510482b82/src/components/MainComponent/Main.js#L187) | [后端代码](https://github.com/jeffshek/open/blob/158e7095400e61688e62cde46e5565083d30b66a/open/core/writeup/consumers.py#L90)****
*   ****后端解析和序列化前端请求。将消息(文本、算法、设置)和 WebSocket 通道打包到 Google 负载*衡器。[后端代码](https://github.com/jeffshek/open/blob/158e7095400e61688e62cde46e5565083d30b66a/open/core/writeup/consumers.py#L131)****
*   ****负载*衡器中继到适当的微服务(小型、中型、大型、哈利波特、法律等)。****
*   ****微服务定期用建议词实时更新 websocket。这就产生了“流”的效果。****
*   ****前端从微服务接收更新的 WebSocket 消息。****
*   ****每个 ML 模型(小、中、大、哈利波特、法律、研究)都是一个微服务。利用率自动扩展。****
*   ****尝试了无数次迭代才做出 fast(er)。****
*   ****我通常不喜欢微服务架构(增加了额外的复杂性)。尽管尽了最大努力,微服务架构对于性能还是必要的。****
*   ****微服务的请求和计算成本与后端服务器有着本质的不同。传统的 web 服务器每秒可以轻松处理 500–5000 多个请求(参见 [C10K](https://en.wikipedia.org/wiki/C10k_problem) )。然而,对于一个运行 1gb 模型的实例来说,每秒 50 个请求生成 50-100 个单词就可以压垮一台机器。(*)****
*   ****后端和微服务都是用 Python 3.6 写的。姜戈(DRF)负责后台。Django 的一个单独实例被用于微服务。****
*   ****所有微服务实例都有一个附加的 GPU 或一个 Cascade Lake CPU 来运行 ML 模型。详情如下。****
*   ****后端和微服务托管在谷歌云*台上。****
*   ****谷歌负载*衡器将所有流量路由到微服务。它基于 URL 后缀"/gpt2-medium,/gtp2-medium-hp 等进行路由..负载*衡器还运行健康检查来检查 CUDA 崩溃。********(*) —每当您必须证明您的微服务用例时,这可能意味着它不值得如此复杂。****# ****秘鲁利马三周:*****   ****在秘鲁利马为期三周的旅行开始时开始认真编码。Trip 起到了催化剂的作用。****
*   ****一些朋友在接*尾声时开始了 beta 测试。缓慢且经常失败。****
*   ****我旅行的 80%时间都在一个[共同工作空间](https://worx.pe)中编码。****
*   ****后端和开发运维两周,前端上周。****
*   ****随着复杂性的增加,重写了 DevOps。****
*   ****在行程结束时,前端通过 POST 请求与后端通信,后端再转发给微服务。****
*   ****不算好看也不算快,但是看到第一条消息从前端→后端→微服务端到端,让我傻乎乎地兴奋起来。**********MVP 版本**********![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/4ae7673d31e3552a38bbc99372de2e7f.png)****# ****在利马取得的成就:*****   ****前端的合理数量。它有一个简单的文本编辑器和由微服务填充的决策选项。****
*   ****后端可以创建 WebSockets 来与前端通信。在第一次迭代中,后端通过 POST 请求与微服务通信,然后将消息转发到 WebSocket。我非常想让微服务保持沉默,不处理 WebSockets。****
*   ****通过 Ansible 实现自动化部署(后来被重构/移除到 Google 启动脚本中)****
*   ******错误:提前发射!**事后看来,我本应该在构建 4-5 周后就发布。到那时,它已经是一个很好的 MVP 了,但是我害怕,如果没有那些花里胡哨的东西,它就是一个笑话。********![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/d626631d3db33dba867e2bb5d6e7723f.png)**********Random**: There’s something magical about flow, 2:00 AM and an empty coworking space. Anything feels possible.****# ****90/90 法则:****> *****第***百分之九十的代码占了第* ***第*** *百分之九十的开发时间。剩下的* ***10*** *百分之十的代码占了其他* ***90*** *百分之十的开发时间。——****汤姆·卡吉尔,贝尔实验室*********   *****工程师不擅长估算。*****
*   *****严重低估了机器学习 DevOps(孩子们称之为“MLOps”)的难度。*****
*   *****第二个主要的低估是管理我自己的特性蠕变。*****
*   *****让微服务在 Docker 容器上工作、扩展以及用合适的模型安装 CUDA 驱动程序出乎意料地困难。************为了让 ml-微服务在 Docker 容器中工作,我必须:********   *****使用安装了 CUDA 的定制 TensorFlow 引导映像*****
*   *****向 Google 传递一个特殊的标志来安装 nvidia 驱动程序(对于某些图像并不总是必需的)*****
*   *****在 GCP 实例上安装 Docker*****
*   *****将 docker 的默认运行时覆盖到 nvidia(使得使用 docker 和 docker-compose 更容易)。*****
*   *****确保 docker 没有删除我的配置更改或恢复配置。*****
*   *****将 GitHub 与 GCP 同步;推送时建立 Docker 图像。*****
*   *****将 ml 模型与谷歌云存储同步。GCP 存储和实例的读取速度快得惊人。比 AWS 快。*****
*   *****从 Google Cloud Build 中提取预构建的 Docker 映像。*****
*   *****从云桶中提取 ml 模型,并使用单独的适当文件夹安装在 Docker 中。*****
*   *****祈祷所有的需求(TensorFlow / PyTorch)都被正确安装。*****
*   *****保存高清图像/快照,以便实例可以从图像快速冷启动。*****
*   *****其余的传统 DevOps (git、monitoring、start docker 容器等)。*****
*   *****在反思的时候,解决这些问题要容易得多,但是在那时,我不知道我让自己陷入了什么。**********上述步骤必须完全自动化,否则缩放会失败。将 bash 脚本作为自动化部署的一部分来编写(在 2019 年)感觉很脏,但在 Google [startup-scripts](https://cloud.google.com/compute/docs/startupscript) 上使用自动缩放时,这是必要的。Kubernetes 是另一个选择,但我没有聪明到用 K8。Google startup-scripts 在机器启动时运行一个 shell 脚本。自动缩放实例时很难使用 Ansible。************提示:**使用[启动-脚本-网址](https://cloud.google.com/compute/docs/startupscript?hl=en_US&_ga=2.127770893.-1480088751.1570398368#cloud-storage)!这告诉实例从定制的 bucket URL 运行脚本。这比将你的脚本复制/粘贴到 GCP 的 CLI/UI 中要好得多。您将会遇到许多对启动脚本的小改动。******   *****设置后端很简单。这是我第一次使用 Django 通道,它配置 WebSockets。姜戈频道的道具。*****
*   *****由于功能蔓延,前端花费了额外的时间。我一直在增加一个新功能,因为我担心它不够好。*****
*   *****微服务最初是用 Flask 编写的(因为每个人都这么建议)。然后我查看了基准测试,意识到如果我剥离它,我可以在 django-rest-framework 中获得相同的性能。在 django-rest-framework 中拥有一切对我来说要容易得多(我的背景是 django)。*****
*   *****优化微服务需要一些时间。我试验了不同的显卡、CPU、内存配置和图像。稍后会详细介绍。*****## *****令人震惊的事情:******   *****直到两个月前,TensorFlow 图片上的默认 python 是 2.7*****
*   *****PyTorch 的 docker images 使用了 conda。*****
*   *****使 nvidia 运行时在 Docker 上工作所需的覆盖。*****
*   *****ML 开源代码的例子比比皆是。很多意大利面和胶带。*****
*   *****Google 的 TensorFlow Docker 图片都是这么优化的(!)他们跑 PyTorch 的速度比 PyTorch 官方图片上的 PyTorch 跑的还快。这可能是上游 PyTorch 图像中的一个错误,没有进行调查。*****
*   *****从 Docker 容器(TensorFlow / PyTorch)中提取时,构建可能会在上游中断。一切都变化得太快了,你会习惯的。************提示**:尽量避免手动安装 CUDA。使用谷歌预装的引导镜像。
**提示**:记下什么 CUDA 版本/其他配置。有助于谷歌没有 CUDA 版本+一些其他要求的问题。很多 CUDA 版本 Bug +框架版本的墓地。************总的来说**:一旦你知道什么配置(引导映像、Docker 映像、Docker 配置、CUDA)起作用,事情就简单了。难的是提前知道…************提示** : ML 有很多新术语/行话要掌握。保存并写一份术语备忘单是有帮助的。我推荐[间隔重复和 Anki](https://senrigan.io/blog/chasing-10x-leveraging-a-poor-memory-in-software-engineering/) 。*****# *****推理剖析:GPU 的名字听起来吓人!******   *****当在网络上运行机器学习模型时,你有两种硬件选择:GPU(显卡)或 CPU。*****
*   *******优点**:GPU 更快,性能通常是 CPU 的 5-15 倍。 **CONS** :成本更高,增加部署复杂性。*****
*   *****许多机器学习任务只需要几分之一秒(又名图像分类)。完全可以使用中央处理器。*****
*   *****大多数用户不会注意到异步任务中 0.05 秒和 0.5 秒的区别。你的网页应该加载很快,但是加载任务结果很慢。*****
*   *****在 CPU 上运行 gpt-2 中等型号(1.2-1.5 GB)并不快。*均 CPU 每秒产生大约 3-7 个单词,不是理想的 UX。*****
*   *****在谷歌云上的 Cascade Lake(最新一代至强 CPU,针对 ML 优化)、K80s、V100s 或 P100s 之间做出决策。*****
*   *******这些基准并不是科学基线。这更像是写在餐巾纸上的快速排序启发法。*******
*   *****表格在 Medium 上显示不好(抱歉!).喀斯喀特湖:8-10 字每秒,K80:12-24 字每秒,P100:32-64 字每秒,V100:32-64 字每秒。*****
*   *******注意**:这是在运行多个 PyTorch 实例时。我这样做是为了消除 CPU / GPU 阻塞操作的利用率。例如,在具有 GPU 的同一台机器上,由于消除了 CPU/GPU 瓶颈,两个 PyTorch 实例产生的结果可能是单个 PyTorch 实例的 1.5 倍。运行单个 PyTorch 应用程序的实例可能每秒生成 15 个单词,但是运行两个 Python 应用程序可能每秒生成 10 个单词。*****
*   *****注意:我犯了一个巨大的错误,但是我没有尝试安装最新的 [MKL-DNN](https://github.com/intel/mkl-dnn) 驱动程序。你可能会看到一个很好的性能跳跃。或者你可能不会。*****
*   *****随着文本输入的增加,更高的记忆力是有帮助的。*****
*   *****从每周期成本来看,相比 GPU,Cascade Lakes 性价比更高。感觉喀斯喀特湖刚好低于 UX 的流速下限。Cascade Lakes 没有像我希望的那样快速生成提示。*****
*   *****我发现,在生成<50 words at once.*****
*   *****Ended up using mostly Cascade Lakes and K80s except for GPT-2 Large. Cost.************提示**时,K80s 与 P100 的权衡对 UX 的影响是可以接受的:你可以让其中的大多数运行为可抢占的,其成本是前者的 1/2。除了产品发布期间,我大部分时间都在使用 preemptible。
**提示**:如果使用 preemptible,Google 会每 24 小时强制重启一次。在凌晨 2 点这样的奇怪时间创建它们,这样对访问者的影响最小。提示:瀑布湖是一个完美的合理权衡。
**注意事项**:这些“基准”仅用于推断(实时运行模型)。大多数训练应该在 GPU 上完成。*****# *****汤姆森给第一次做望远镜的人的规则是:*****> ********“做四寸镜比做六寸镜快。”*** *—编程珍珠,美国计算机学会通讯,1985 年 9 月*******   *****从简单开始:API 端点从 gpt2-medium 生成单词。慢点。同步任务。用过的烧瓶。单端点。*****
*   *****添加了前端。会查询 API 端点。慢点。重复的请求可能会破坏 API。*****
*   *****添加后端作为 API 端点的看门人。*****
*   *****将烧瓶终点改写为姜戈-DRF。*****
*   *****集成 django-后端处理 Websockets 的通道。添加了 redis-cache,在转发到微服务之前检查重复请求。*****
*   *****更改了前端以通过 WebSockets 进行通信。*****
*   *****重写了 Ansible 的部署脚本,以处理 Google Cloud 的启动脚本范例。*****
*   *****集成的微服务通过 WebSockets 进行通信,也就是允许“流式传输”。*****
*   *****培训并添加了额外的微服务(小型、中型、大型、法律、写作、哈利波特、歌词、公司、xlnet)*****
*   *****复杂性是从简单端点的最初概念逐渐发展而来的。**********经过这些恶作剧之后,我在部署 ML 方面有了很大的提高。
**弊**:与 GCP 的核心产品(特别是存储、云构建、自动扩展、映像)紧密结合。单一服务供应商上的紧密耦合并不总是理想的(技术上或战略上)。
**提示**:如果你能接受与 GCP 产品的紧密耦合,你可以构建得更快。一旦我接受使用启动脚本,一切都变得容易了。
**总体而言**:如果我知道最终架构的复杂性(以及我自己对 DevOps 的无知),我可能会感到气馁/害怕。归因于缺乏规划和不知道自己不知道什么风险。在我的许多错误中,从简单的架构构建一个应用程序,然后逐渐用更复杂的方式重构它,是我做对的事情。*****# *****码头工人!我的显卡呢?!和其他部署困难。**********注:GCP 和多克都有图像的概念。为了避免混淆,我将声明 GCP 的总是作为引导映像。**********一般来说,使用 Docker 容器有助于简化部署、服务配置和代码可复制性(“iuno,worked on my machine problems”)。**********在 ML 中使用 Docker 更难。问题:******   *****图像会变得非常大。官方 TensorFlow Docker 图片大小轻松 500mb-1.5gb。*****
*   *****大多数 GCP 机器学习引导映像都没有 Docker/Compose。*****
*   *****计数器:许多包含 Docker 的引导映像没有 CUDA。*****
*   *****如果你有勇气从零开始安装 TensorFlow 和 CUDA,我为你鼓掌。*****
*   *****诀窍是找到一个足够好的启动映像,并安装两者中难度较低的(CUDA,Docker)。大多数时候,Docker + Docker Tools 比 CUDA 更容易安装。*****
*   *****许多模型经常是 1gb 以上,对于源代码控制来说太大了。需要在启动/部署时同步大型模型的脚本。*****
*   *****很容易忘记将 nvidia 运行时传递给 Docker 命令。*****
*   *****DevOps 中的反馈循环比编程慢得多。你可以做出改变,意识到你有一个打字错误,然后再花 10 分钟来部署。如果使用谷歌滚动部署,可能需要更长时间。************PRO** :一旦容器安装好,惊人的坚固。
**弊** : Docker 增加了部署的复杂性。合理反驳:如果做了这么多,为什么不加 Kubernetes?回答:我对 Kubernetes 不够聪明。
**提示**:小心谨慎,把你运行的每一个 shell 命令都放在一个颤动日志中(或者某种类型的记录保存)。您可能会多次复制和粘贴您的命令。稍后您将自动完成其中的大部分工作。如果你“有点”记得命令顺序,自动化就更难了。
**提示**:以绝对路径运行/保存命令,以避免覆盖错误的目录。即。“rsync /path1 /path2”而不是“rsync path1 path2”,哦 f f.
**提示**:如果你知道 Ansible,使用 Ansible 重新运行 google 的启动脚本。比 GCP 的滚动部署要快得多。*****```
***- name: Deploy to Open# startup scripts does most of the hard work, but make sure # you're only deploying to things that finished from startup scriptshosts: open_django:&finished_startupgather_facts: truebecome: truepost_tasks:- name: Run Startup Scriptshell: |google_metadata_script_runner --script-type startup --debugargs:chdir: /become: yes***
```*******提示:花额外的时间写提纲*******1.  *****模型应该存放在哪个桶上。建议将培训和生产的云桶分开。*****
2.  *****实例上应该同步桶/目录的位置。*****
3.  *****如果可能的话,让实例共享与 docker 容器的挂载目录完全相同的位置。即。实例的/models 挂载到 docker 容器的/models 路径*****
4.  *****将正确的 rsync 命令写入桶中。使用 rsync!(不是 cp)。重启时比通过 cp 拉同样的文件更有效。************提示**:对 py torch(torch . cuda . is _ available)或 tensor flow(TF . test . is _ GPU _ available)进行快速自动检查,可以省去确保 Docker 使用 nvidia 的麻烦。
**总的来说**:这个领域可能是许多 web 工程师在部署预先训练好的 ML 应用程序时努力的地方。*****# *****寻找瓶颈。你说我内存不足是什么意思?******   *****监控传统的 web 服务器负载通常是简单明了的。所有 GCP 页面上列出的 CPU 使用率百分比。对于内存,top 命令可以快速告诉程序使用了多少内存。谷歌的 StackDriver 会自动将内存使用情况转发到谷歌云。*****
*   *****几十年来,DevOps 一直关注对 cpu、内存、磁盘使用、网络的监控。*****
*   *****然而,唯一关心 GPU 使用的人是超频游戏玩家(又名 crysis-99-fps-water cooled-noobmaster)。自从 AlexNet(社区学会了使用 GPU 进行 ML)以来,生产 GPU 监控工具还没有完全达到标准。*****
*   *****为了正确地监控 GPU 的使用,你必须使用 nvidia-smi,按设定的时间间隔输出结果,编写一个供 Prometheus 读取的脚本,然后将其传递给 StackDriver。总之你要写一个微服务来监控一个微服务。*****
*   *****在使用过程中,CPU 和 GPU 的使用量都呈线性增长。作为一个黑客,我发现 vcpu 的最低数量可以达到 80–100 %,并根据 CPU 的使用情况自动扩展。太多的 vcpu 和 CPU 使用率%不会让步,而 GPU 受到打击。*****
*   *****当 GPU 耗尽内存时,可能会出现问题。当用户传递较长的提示(> 200 字)时,就会发生这种情况。PyTorch 引发了一个异常,但不幸的是包含了大量的内存泄漏。为了处理这个问题,我捕获了 PyTorch 异常并强制释放未使用的内存。nvidia-smi 没有用,因为内存使用统计数据不是实时精确的(IIRC,它只显示一个进程的内存使用峰值)。*****# *****培训模型******   *****微调了 gp T2-中型 P100 的附加型号。训练迭代(周期)从《权力的游戏》(GoT)和《哈利波特》(HP)上的 60k 到 600k(学术研究,在 200k 论文摘要上训练)。*****
*   *****用了 TensorFlow 1.13 来训练。*****
*   *****训练时间从几个小时(60k)到几天(600k)不等。*****
*   *****交叉熵损失在 2-3 之间。过度训练时,公制没有用。*****
*   *****分叉 nsheppard 的 gpt2 repo,做了一些小的修改来加速更大数据集的启动。*****
*   *****一旦你理解了 ML 的行话(尽管这可能是最难的部分),遵循 gwern 的教程是非常简单的。*****
*   *****使用梯度检查点来处理内存问题。在没有内存问题的情况下,不可能在单个 GPU 上微调 gpt2-large (774M 参数,1.5gb)。*****
*   *****寻找和清理数据集从轻微的麻木痛苦到乏味的挫折。*****
*   *****同样,数据清理是 80%的工作。*****
*   *****从 Kaggle,Google 和 misc. free 数据集抓取数据集进行填充。在清理过程中,数据集异常、新行(\r,\n\,回车符)、unicode 检测和语言检测等问题是最耗时的。*****
*   *****Gwern 使用了大量 bash /命令行来清理他的莎士比亚文集。我推荐用 Python。更容易在不同的数据集上重用代码。*****
*   *****无法使 16 位训练(apex)在 Docker 中正常工作。Nvidia 性能指标评测(尽管是营销..)显示 16 位可以将训练周期缩短 2 倍(甚至更多)。没有太努力(累)去做 16 位的作品。*****
*   *****训练后,使用 huggingface 脚本将模型转换为 PyTorch。在 pytorch-transformers 上部署非常简单。*****
*   *****想避免在哈利波特语料库上过度训练,但事后看来,感觉过度训练比训练不足更好。在*衡小数据集的过度/不足训练风险时,您的结果可能会有所不同。************提示**:当你有了原始的训练数据集后,做一个拷贝。不要修改原始数据集。将修改后的输出复制到单独的文件夹中。将修改过的数据集和原始数据集保存在不同的文件夹中,以避免错误/混淆。
**提示**:如果你发现自己曾经清理过一个特定的数据集,后退一步,寻找一个没有问题的类似数据集。这发生在哈利波特数据集上。
**提示**:学习 tmux!使用 tmux 可以更容易地在远程机器上开始训练,并且您可以放心地退出。
**提示**:用箭袋来装你所有的命令。非常容易出现错别字。*****# *****运行模型******   *****二手 PyTorch。pytorch-transformers 为模型创建了方便的 API 调用点。模仿 huggingface 中 run_gpt2.py 的例子。然后应用大规模重构。*****
*   *****在 PyTorch 中加载 GPT-2 模型很慢(1-2 分钟)。*****
*   *****为了缩短加载时间,当微服务启动时,WSGI 加载适当的模型(gp T2——小型、中型、大型等),并将 PyTorch 实例存储为单例。*****
*   *****所有后续请求都使用 singleton PyTorch 实例。*****
*   *****基于模型大小,对运行的 WSGI 进程数量的配置限制。WSGI 进程太多,CUDA 内存不足。太少,GPU 利用不足。*****
*   *****当 PyTorch 耗尽内存时捕获异常;释放内存泄漏。*****```
***def get_process_prompt_response(request, validated_data):try:output = generate_sequences_from_prompt(**validated_data)except RuntimeError as exc:if "out of memory" in str(exc):logger.exception(f"Ran Out of Memory When Running {validated_data}. Clearing Cache.")torch.cuda.empty_cache()oom_response = get_oom_response(validated_data)return oom_responseresponse = serialize_sequences_to_response(output,validated_data["prompt"],validated_data["cache_key"],WebsocketMessageTypes.COMPLETED_RESPONSE,completed=validated_data["length"],length=validated_data["length"],)# clear cache on all responses (maybe this is overkill)torch.cuda.empty_cache()return response***
```*   *****95%的请求时间用于预测逻辑。另一个是来自前端->后端->负载*衡器的路由和反序列化。*****
*   *****每隔五个单词,微服务就用更新的文本更新 WebSocket。*****
*   *****向后端添加缓存以防止重复请求很有帮助。*****
*   *******为了简化来自不同实例的相同响应,我对所有请求使用 42 的种子。*******# *****其他部署改进、提炼和想法******   *****TensorFlow 有 [TensorFlow Serve](https://www.tensorflow.org/tfx/guide/serving) 和 PyTorch 有 [TorchScript](https://pytorch.org/docs/stable/jit.html) 将模型转化为生产级。好处包括合理的速度提升(redditor 引用了 30%的提升)和在没有 Python 的设备上更容易部署。我在一些模型上追踪了(PyTorch 的转换过程),但是我发现速度上的好处并不明显,但是增加了更多的复杂性。*****
*   *****在过去的几个月中,模型的提取(在<50% of the size and runtime) has picked up traction. Huggingface’s distillation of gpt2-small is 33% smaller and 2x faster.*****
*   *****There’s a recently published paper about [Extreme Language Model Compression 中提取 90–95%以上的模型,将 BERT 压缩了 60 倍](https://arxiv.org/abs/1909.11687))。如果能在 GPT2 上应用,将会有很多影响!*****
*   *****有点反模式,但是 PyTorch 和 TensorFlow 在同一个 Docker 图像上非常有用。我能够更快地诊断和尝试潜在的解决方案。*****
*   *****我本来集成了 [XLNet](https://arxiv.org/abs/1906.08237) ,但是没有 GPT2 那么强的发现生成输出。我还试图让它建议单个单词(类似于它的屏蔽语言模型),但我找不到一个好的写作用例/ UI。*****# *****其他宝贵的工具******   *****上面的一些重复。*****
*   *****哨兵对于错误报告来说是无价的。与 ASGI (Django-Channels)一起使用比正常情况下稍微困难一些。*****
*   *****[tmux](https://www.hamvocke.com/blog/a-quick-and-easy-guide-to-tmux/) —使用它来保持远程会话打开。另一种选择是屏蔽。*****
*   *****使用 django-rest-framework 是一种乐趣。感觉像是作弊代码。*****
*   *****Netlify 非常适合部署。*****# *****应对倦怠**********![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/26833ad3277c908e708b56cf59c9da73.png)**********How I Treat My Mental State Until It’s Too Late …******   *****在接*终点线时撞上了一堵墙。*****
*   *****在大约 2-2.5 个月内开始燃烧。*****
*   *****精神上的痛苦,因为我觉得我应该发射,但还不够好。痴迷于缺失的功能。*****
*   *****打电话给一个亲密的朋友倾诉真的很有帮助(谢谢詹姆斯 C)。*****
*   *****自我施加的压力“发射!”让我避免给家人打电话。那是个错误。**我发现给妈妈打电话只是想问问她的生活让我又松了一口气。*******
*   *****很自豪我完成了这个。了解了许多关于 ML 部署的意想不到的事情。对我的下一个项目有用。*****# *****非常感谢******   *****GPT2 的 OpenAIpytorch 变形金刚的拥抱脸。*****
*   *****GCP 要求学分,否则负担不起。有偏见,但我发现 GCP 指标比 AWS 全面(桶、网络、易用性)更好。*****
*   *****我的朋友们帮助我进行了测试,并给了我宝贵的反馈。感谢(随机排序):克里斯汀李,,凯特阿克塞,Zoltan 萨拉斯,斯蒂芬林森和哈里尼巴布,他们都给了宝贵的反馈。*****
*   *****许多 Redditors / ProductHunt 真的在推动和玩产品,还有很好的反馈和令人捧腹的写作提示。*****# *****下一步是什么?******   *****致力于蒸馏 GPT 二号。能搞清楚的我就开源。*****
*   *****使用 GANs 制作营销图像。敬请期待!*****
*   *****还不至于愚蠢到再次做出不准确的时间表估计。***********最初发布于*[*https://senri gan . io*](https://senrigan.io/blog/how-writeupai-runs-behind-the-scenes/)*。******# 从卡格尔的空中客车挑战中吸取的教训。> 原文:<https://towardsdatascience.com/lessons-learned-from-kaggles-airbus-challenge-252e25c5efac?source=collection_archive---------9----------------------->![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/5bce72fbed57d70239cae1d95068752c.png)The challenge banner在过去的三个月里,我参加了[空客船只探测卡格尔](https://www.kaggle.com/c/airbus-ship-detection)挑战赛。顾名思义,这是一项由[空中客车](http://www.intelligence-airbusds.com/satellite-data/)(其卫星数据部门)提出的检测计算机视觉([分割](https://en.wikipedia.org/wiki/Image_segmentation)更准确地说)竞赛,包括**在卫星图像**中检测船只。在我开始这个挑战之前,我是(在某种程度上仍然是)细分领域的初学者。我很好地掌握了“经典”机器学习([梯度提升树](https://en.wikipedia.org/wiki/Gradient_boosting),线性模型等等),并将其用于生产,但深度学习对我来说仍然是一个新事物。之前我写过一系列的博文解释和实现了使用 Keras 的 CNN(此处查看[此处](https://dsotb.quora.com) [)](https://dsotb.quora.com/) 并上过大 Coursera [深度学习赛道](https://www.coursera.org/specializations/deep-learning)系列。然而,我觉得我所学的缺乏实际应用。事实上,尽管有一些指导性的项目,但仅仅是课程并不能帮助你发展“现实世界”的技能。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/1a4fe252d59c10145802626dda6a5c1c.png)The competition’s timeline那么,该怎么办呢?我开始寻找“真实世界”的应用,因此,大约在 2018 年 3 月,我遇到了[数据科学碗 2018 Kaggle](https://www.kaggle.com/c/data-science-bowl-2018) 挑战。竞争在于检测细胞核。与空客挑战类似,这是一项实例细分任务。当我发现这项挑战时,它已接*尾声(比赛于 2018 年 4 月 16 日结束)。因此,我关注了一些讨论,阅读并探索了一些模型,使用 [U-Net](https://arxiv.org/abs/1505.04597) 模型(及其变体)了解了许多关于细分的知识,但没有时间参与。因此,当空中客车公司的挑战到来时,我更加兴奋,并为自己设定了以下目标:**训练一个细分模型,并根据该模型至少提交一份材料**。我达到目标了吗?是的,我做了,而且可能更多(你可以在读完这篇文章后自己决定)。总的来说,这个过程是愉快的(至少大部分时间是这样),我获得了很多实用的知识。接下来,我会和你分享我学到的一些经验(排名不分先后)。让我们开始吧。## 理解手头的任务这当然是显而易见的,但并不是很多人关注的焦点(至少在他们开始的时候)。尽管这听起来很明显,但每项任务都是不同的。许多比赛从远处看都很相似(例如卫星图像分割),但细微的差异使得每项任务都很独特和困难(按照特定流程收集的数据、不*衡的数据集、不同的评估指标……)。所以一定要理解任务,不要犹豫依靠社区来帮助你。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/94f2ffac265ef1e90695dedf79254910.png)Various computer vision tasks (source: [http://cs231n.stanford.edu/slides/2018/cs231n_2018_lecture11.pdf](http://cs231n.stanford.edu/slides/2018/cs231n_2018_lecture11.pdf))顺便说一句,如果你对计算机视觉世界和更精确的图像分割不熟悉,可以看看这些来自斯坦福大学 [CS231](http://cs231n.stanford.edu/) 课程的[幻灯片](http://cs231n.stanford.edu/slides/2018/cs231n_2018_lecture11.pdf)。## 尽可能使用预先训练的模型不要重新发明轮子或者在深度学习的情况下,不要从头重新学习所有的权重。事实上,很多分段架构包含两部分:**一个编码器**和**一个解码器**。编码器通常使用在另一个数据集(例如 [ImageNet](http://image-net.org/) )上学习的预训练权重进行初始化。使用这些权重来初始化您的模型也非常容易。查看以下示例:在我忘记之前,非常感谢 [Pavel Yakubovskiy](https://github.com/qubvel) (和其他贡献者)的[分段模型](https://github.com/qubvel/segmentation_models)回购(注意它包含了比 U-net 更多的架构)。;)## 投入一些时间构建一个可靠的架构,即不要只依赖笔记本电脑![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/4149b40c471a5fde66d5c1a7f5baff2d.png)A partial view of my solution (source: [https://github.com/yassineAlouini/airbus_ship_detection](https://github.com/yassineAlouini/airbus_ship_detection))许多 Kaggle 用户经常使用(或分叉)一个内核(Kaggle 的定制 [Jupyter](https://jupyter.org/) 笔记本实现)来发起一场竞赛。这对于做 EDA(探索性数据分析)和感受竞争以及探索新想法是很好的。然而,这并不能很好地扩展。假设你想和一个同事合作(顶级竞争对手的常见做法),整个代码库都在笔记本里。众所周知,笔记本很难协作,也很难进行版本控制(尽管有一些解决方案,如 [nbdime](https://github.com/jupyter/nbdime) )。相反,我推荐以下更好的工作流程:*   只保留用于 EDA 和可视化的笔记本
*   使用 git 进行版本控制
*   让你的代码模块化:一个文件用于数据预处理,一个用于建模,一个用于评估,一个用于运行管道,等等。当你开始的时候,这些步骤会让你觉得有些多余,但是相信我,从长远来看是值得的。这种方法的另一个好处是,你将发展更好的软件工程技能。这些都是就业市场上非常有价值的技能。事实上,你不仅想设计好的模型,还想学习如何有效地与其他同事合作,将模型投入生产,并确保它们的规模。## 良好的数据扩充很重要![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/294d255644c26bff09f320add920902c.png)Example of image data augmentaion (source: [https://github.com/albu/albumentations](https://github.com/albu/albumentations))在处理深度学习模型时,数据越多越好。事实上,在大多数的 ML 任务中,**获取更多的数据通常是昂贵的。**可以使用亚马逊的[机械土耳其](https://www.mturk.com/)(或类似的替代品)或使用专家标记(例如医学图像的医生)来手动完成。幸运的是,由于数据增强,生成新图像更具可扩展性。这是避免[过度拟合](https://en.wikipedia.org/wiki/Overfitting)的一个很有价值的技巧。![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/721bb4a21e108b72815ead99e0e41e6e.png)A sample of data augmentation using Keras (source: [https://github.com/yassineAlouini/airbus_ship_detection/blob/master/asd/preprocessing.py](https://github.com/yassineAlouini/airbus_ship_detection/blob/master/asd/preprocessing.py))在这次挑战中,我使用了 Keras 的 [ImageDataGenerator](https://keras.io/preprocessing/image/) ,这是一种生成批量增强图像的非常简单的方法。在挑战结束时,我发现了一个新的增强库:albumentations。我当时无法使用它,因为它更容易与 pytorch 集成,但计划在以后的挑战中尝试一下。检查[回购](https://github.com/albu/albumentations)和[纸张](https://arxiv.org/pdf/1809.06839.pdf)。它值得阅读和努力。## 仪器和监控您的实验![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/d4e5cbf6dcafaef72f79449b99745719.png)An example of a monitoring dashboard (using comet.ml)你无法改善你无法衡量的东西(至少会更难)。因此,花一些时间设置 ML 监控并组织好你将要进行的各种实验是一个好的实践。幸运的是,有很多工具可以让你的生活更轻松。comet.ml 是一个很好的工具,如果你的代码是开源的,它有一个免费的计划。你可以在这里找到我的空客挑战赛仪表板。## 探索预测![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/f79e8bf675d3e36999dd9bb1d9985365.png)Predicted ships masks (source: [https://www.kaggle.com/iafoss/unet34-dice-0-87](https://www.kaggle.com/iafoss/unet34-dice-0-87))好吧,让我们假设你已经编码了一个模型,训练了它,它在交叉验证数据集上给出了一个很好的分数。你该怎么办?由于这是一场计算机视觉比赛,一件显而易见的事情是检查一些预测的分割。这将给你一种直觉,知道哪些可以改进(也许你的模型很难找到较小的船只或正确分割附*的船只),以及你可以尝试哪些后处理技术。## **投资好的硬件**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/7c445496cc1a82ec3a52e58be978d8ee.png)Build your own desktop if you can.许多供应商使参加 ML 比赛比以前更容易。例如,谷歌和 Kaggle 提供免费的 GPU 笔记本电脑。因此,理论上,你只需要一个互联网连接和一台笔记本电脑。也就是说,如果你对 Kaggle 竞赛(以及更广泛的 ML 实验)很认真,那么最好的投资就是构建你自己的桌面。如果你不擅长硬件,不要担心,我会帮你解决的。检查我的[建立](https://medium.com/@YassineAlouini/how-i-built-a-deep-learning-box-9dcbf284eab0)职位,我解释了整个过程。我还包括了一个部分,在那里我谈到了其他的选择。## **选择一个合适的损耗**您在模型中优化的内容有时与模型结构本身一样重要。例如,对于分段任务,有几个变量:*   骰子损失(是一减去[骰子系数](https://en.wikipedia.org/wiki/S%C3%B8rensen%E2%80%93Dice_coefficient)
*   Lovasz-softmax 损失
*   [焦](https://arxiv.org/abs/1708.02002)损
*   [交叉熵](https://en.wikipedia.org/wiki/Cross_entropy)损失(也称为对数损失)
*   [铰链](https://en.wikipedia.org/wiki/Hinge_loss)丢失
*   例如骰子和交叉熵的加权和(或其他组合)![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/36c488b293c644f75c237e1cb3df704b.png)One of the losses I have tried (source: [https://github.com/yassineAlouini/airbus_ship_detection/blob/master/asd/losses_metrics.py](https://github.com/yassineAlouini/airbus_ship_detection/blob/master/asd/losses_metrics.py))我最后尝试了骰子和交叉熵的加权和,以及焦点损失和骰子。那么,选择哪一个呢?如果你熟悉计算机视觉任务和竞赛,你会有一种直觉,知道什么可能做得最好。现在,如果您是新手(像我一样),尝试各种方法,并选择一种在执行时间和交叉验证性能方面最有希望的方法。最后,如果你不熟悉分类的损失函数,维基百科[页面](https://en.wikipedia.org/wiki/Loss_functions_for_classification)是一个很好的起点。请注意,我正计划写一篇关于各种机器学习设置中的损失函数的更长的博文。所以请继续关注这方面的更多信息。;)## 相信交叉验证![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/1815a1999897e61dcc3b9ea2511040a7.png)Trust the cross-validation (source: [https://sebastianraschka.com/blog/2016/model-evaluation-selection-part3.html](https://sebastianraschka.com/blog/2016/model-evaluation-selection-part3.html))我怎么强调都不为过。这在 Kaggle 竞赛(否则你会[过度适应公共领导委员会](https://www.kaggle.com/caseyftw/overfitting-the-leaderboard))和“现实生活”机器学习模型中当然很重要。所以,抵制诱惑,提交在公共领导板上表现最好的模型,并选择交叉验证集中最好的一个。## 理解数据很重要![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/eadbdcbbdfef2ea3ece70ba916326e2f.png)Is there a ship here or only waves?数据不*衡吗?是不是很乱,需要很重的预处理?这些问题对于决定你应该在哪些方面投入时间以及如何解决这个问题非常重要。事实上,由于这场比赛中的数据非常不*衡(空海图像比有船的图像多得多),一个聪明的解决方案是首先训练一个分类模型(无论是否有船),然后在预测的有船图像上训练一个分割模型。查看这个[讨论](https://www.kaggle.com/c/airbus-ship-detection/discussion/71659)线程,寻找这样的解决方案。## 向社区学习,尽你所能提供帮助![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/444d1a628b6f55c10d166229f5a00647.png)One day you could be here ;) (source: [https://www.kaggle.com/c/airbus-ship-detection/discussion/71591#422787](https://www.kaggle.com/c/airbus-ship-detection/discussion/71591#422787))有一个巨大而有用的 Kaggle 社区,所以你可以利用它:如果你觉得有困难,就问问题,分享你所学到的,投票支持好的内核和帖子,并与竞争对手保持同步。这在这场比赛中尤为重要。事实上,一个数据泄露被[发现](https://www.kaggle.com/c/airbus-ship-detection/discussion/64355),并与整个社区共享。最终[做出了](https://www.kaggle.com/c/airbus-ship-detection/discussion/64388)的修正,事情顺利地从那里恢复了。## 堆叠和后处理,如果你是认真的 LB 分数![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2019/-/raw/master/docs/img/192f35ba3403b0195addfb7f8c74c5f4.png)Stacking classifiers (source: [http://rasbt.github.io/mlxtend/user_guide/classifier/StackingClassifier/](http://rasbt.github.io/mlxtend/user_guide/classifier/StackingClassifier/))许多最*获胜的解决方案(例如,查看此[讨论](https://www.kaggle.com/c/tgs-salt-identification-challenge/discussion/69291))是[堆叠](http://blog.kaggle.com/2016/12/27/a-kagglers-guide-to-model-stacking-in-practice/)模型(具有一层,有时两层或多层堆叠)。通常,它还与后处理技术相结合,因为这些在图像分割中非常重要。你可以在这个代码 [repo](https://github.com/ybabakhin/kaggle_salt_bes_phalanx) 中找到这些技术的一个很好的例子。## 花费的时间很重要每个竞争都伴随着新的变化和特定的问题:不同的评估指标、棘手的处理步骤、不*衡的数据、低质量的数据等等。因此,不要期望很快得到“好”的结果(否则每个人都会这样做,竞争是不值得的)。相反,尽可能长时间地坚持比赛。不要很快灰心丧气(说起来容易做起来难),要相信,经过足够的时间和努力,你最终会得到更好的结果(并且在某个时候,会取得胜利)。## 尽情享受[心流](https://en.wikipedia.org/wiki/Flow_(psychology))这应该是当然的一个重要方面。试着*衡学习经历的乐趣和你的心流状态:逐步挑战自己,不要一开始就被所有事情压垮。慢慢开始,随着你的进步逐渐增加。试着一次专注于一个方面,并有意识地努力改进你不擅长的领域。对我来说,这是图像预处理,增强,和后处理。给自己一点时间。我希望你喜欢这篇文章,并获得新的见解。敬请期待下一期!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/71394.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

TowardsDataScience-博客中文翻译-2019-四十二-

TowardsDataScience 博客中文翻译 2019(四十二)原文:TowardsDataScience Blog 协议:CC BY-NC-SA 4.0井字游戏的经验教训:实用强化学习技巧原文:https://towardsdatascience.com/lessons-learned-from-tic-tac-toe-practical-reinforcement-learning-tips-5cac654a45a8?so…

.Net PdfiumViewer 打印时无法渲染电子签名问题的解决方法

需要修改源代码或直接反编译动态库修改 PdfPrintDocument.RenderPage 方法,本文仅介绍修改动态库。转载请标明原出处:https://www.cnblogs.com/crpfs/p/18463735 1. 先决条件 本文修改的动态库是从如下的 NuGet 包中获取的:如果使用的是 Visual Studio 中的 NuGet 包管理器获…

现代化 React UI 库:Material-UI 详解!

随着 React 在前端开发中的流行,越来越多的 UI 框架和库开始涌现,以帮助开发者更高效地构建现代化、响应式的用户界面。其中,Material-UI 是基于 Google Material Design 规范设计的一款开源 React UI 库,Github Star高达 94K,凭借其丰富的组件库、灵活的定制化选项以及无…

将html元素保存为图片

初始需求是echarts绘制的图表保存为图片, 后来发现,echarts图标之外,还有一个参数input/button也要放到图片中 于是,技术实现从简单的《echarts导出为图片》 变成了较为复杂的《html元素导出为图片》先放出已经实现的《echarts导出为图片》的代码,// 导出 图片generatePic…

第十期机器学习基础 02注意力机制和Transformer/Bert

一:注意力机制 (一)前提背景 1.人类的选择性视觉注意力 视觉注意力机制是人类视觉所特有的大脑信号处理机制。人类视觉通过快速扫描全局图像,获得需要重点关注的目标区域,也就是一般所说的注意力焦点,而后对这一区域投入更多注意力资源,以获取更多所需要关注目标的细节信…

查找大量时序遥感文件缺失、不连贯的成像日期:Python代码

本文介绍批量下载大量多时相的遥感影像文件后,基于Python语言与每一景遥感影像文件的文件名,对这些已下载的影像文件加以缺失情况的核对,并自动统计、列出未下载影像所对应的时相的方法~本文介绍批量下载大量多时相的遥感影像文件后,基于Python语言与每一景遥感影像文件的文…

AI智能照片放大软件--Topaz Gigapixel AI macOS苹果电脑安装包(含激活秘钥)

Topaz Gigapixel AI是一款功能强大的图像无损放大工具,具有以下功能特色:首先,它利用人工智能技术,能自动识别并增强图像中的细节,包括纹理、边缘等,同时减少噪声,使图像更加清晰细腻。其次,软件支持超高放大倍率,最高可达600%,且放大后的图像质量依然保持优秀。此外…