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

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

从研究到生产:扩展最先进的机器学习系统

原文:https://towardsdatascience.com/from-research-to-production-scaling-a-state-of-the-art-machine-learning-system-6efad0141865?source=collection_archive---------29-----------------------

理解大数据

我们如何实施生产就绪的问答应用程序,并将响应时间减少了两个数量级以上。

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

(图片由作者提供)

想象一下,你已经创建了一个机器学习系统,它在某些任务上超越了最先进的性能。您已经针对一系列目标进行了优化,如分类准确性、F1 分数或 AUC。现在您想从它创建一个 web 服务。其他目标,如向用户交付结果的时间或成本,变得更加重要。

这两组目标通常是冲突的。更精确的模型通常很大,评估起来计算量很大。为了在生产中使用这种模型,通常会引入各种优化,如降低模型的精度和复杂性。虽然有利于降低成本和能耗,但不幸的是,这会损害精度。

显然,如果准确性不重要,推断时间可以大大降低。同样,可以以高成本产生非常准确的响应。最终选择哪种解决方案介于这两个极端之间。选择最佳解决方案的一个有用的技巧是从准确性和成本方面列举它们。不受他人支配的解决方案集被称为帕累托边界,它确定了准确性和成本之间的最佳权衡。

之前的一篇博文中,我们介绍了一个服务系统,它重现了开放领域问答中最先进的准确性。我们基于脸书的密集段落检索(DPR) ,这是一个基于 Python 的研究系统。我们使用 Vespa.ai 构建了服务系统,这是一个开源的大数据服务引擎,由于其对快速相似性搜索和搜索和排名中的机器学习模型的原生支持,它非常适合这样的任务。结果是 web 服务接受一个问题并返回一个精确的答案。

虽然该系统重现了 DPR 的结果,因此具有出色的准确性指标,但从端到端延迟来看,响应时间最初很差。这篇文章将描述我们为使生产系统的性能达到可接受的水平所做的各种优化。

Vespa.ai 是为生产而构建的,因此有相当多的服务时间优化选项。我们将特别使用 Vespa.ai 的能力,通过每个查询使用多个工作线程来检索和排列文档,以达到显著的效果。然而,该应用程序的主要成本是评估两个 BERT 模型。我们想要回答的一个问题是,具有完全精度的较小模型是否优于具有量化参数的较大模型。我们将开发帕累托边界来评估各种优化的优点。

我们将从服务系统的概述开始,并确定系统的哪些部分最初推动了成本。关于实现的更多细节,我们可以参考本系列中之前的博文

问题回答

该系统的任务是对以自然语言给出的问题产生文本回答。主要包括三个阶段:

  • 编码器生成问题的表示向量。
  • 检索器在 2100 万个索引段落中执行最近邻搜索。
  • 读者找到最相关的段落,并摘录最后的答案。

下图说明了这一过程:

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

问答的编码器、检索器和阅读器(图片由作者提供)

编码器首先从问题中创建一个标记化的表示。这个令牌 id 向量作为输入被发送到编码器 BERT 模型。这最初是一个标准的基于 BERT 的模型,有 12 层,隐藏层大小为 768。最终的隐藏层状态被用作问题的表示向量。如上图所示,这主要发生在 Vespa 的无状态容器层。令牌和向量表示被向下传递(“分散”)到所有内容节点以执行查询。

在内容节点上,段落已经用它们自己的表示向量进行了索引。这些向量被构造成使得问题向量和段落向量之间的欧几里德距离指示相似性。这在 HNSW 算法中用于执行近似最近邻搜索。具有最小欧几里德距离的 10 个通道被发送到下一阶段。

同样在每个内容节点上执行的第二阶段排序阶段评估读者 BERT 模型。像编码器模型一样,这最初是具有 12 层和隐藏长度 768 的基于 BERT 的模型。来自查询和每个段落的表征被组合以形成模型输入。读者模型产生三个概率分数:相关性分数和答案在文章标记序列中的开始和结束索引。具有最佳相关性分数的段落被选为获胜者,并且其令牌表示被返回给无状态层。在这里,自定义代码使用起始和结束索引提取最佳跨度,对其进行去标记化,并返回结果文本答案。

现在,那是很多工作。以下是对问题“谁赢得了 2015 年环法自行车赛”的回答示例,其中检索了最相关的段落,并提取了正确答案“克里斯·弗鲁姆”:

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

来自 Vespa.ai 的回应(图片由作者提供)

为了测量性能,我们在一台机器上部署了该系统,该机器配有英特尔至强金色 6240 处理器,200 GB RAM 和固态硬盘。我们评估了超过 3610 个问题的系统,并记录了平均延迟和精确匹配分数。最初,系统获得 40.64 的精确匹配分数。在考虑优化性能之前,上述三个阶段花费的时间为:

  • 编码模式:300 毫秒
  • 近似最近邻搜索:13 毫秒
  • 前 10 名读者排名:9085 毫秒

显然,9.4 秒的总端到端延迟对于服务来说是不可接受的。接下来,我们将把它降低到 100 毫秒以下

多线程检索排序

最初,最昂贵的步骤是阅读器阶段。默认情况下,Vespa 在一个线程上为一个查询进行所有排序。当计算成本较低时,这是最大化吞吐量的合理缺省值。在这种情况下,这意味着读者模型是针对前 10 篇文章中的每一篇依次进行评估的。这导致了很高的查询延迟。

然而,Vespa 可以选择每次搜索使用多线程。设置此值会将平均端到端延迟降低到 2.04 秒,提高了 4 倍以上,而不会影响精确的匹配分数。

值得澄清的是,阅读器模型并不是批量评估的。这是由于 Vespa 的排名框架,其中排名表达式对单个段落和查询对进行评分。然而,对于 BERT 模型,这并不重要,因为评估时间与批量成线性关系。一个原因是具有 3 维或更多维张量的张量乘法,因为这些乘法无论如何都要在几个硬件优化的矩阵-矩阵乘法上迭代。

一般来说,Vespa 有许多选项来调整性能,例如轻松地将工作负载分布在附加的内容节点上。虽然我们不在这里探讨,但请参阅 Vespa 服务扩展指南了解更多信息。

令牌序列长度

BERT 模型的定义和最显著的特征之一是完全注意层。虽然这是语言理解方面的一个重大突破,但它对评估时间有一个不幸的 O(n)影响。

因此,输入到 BERT 模型的标记序列的长度显著影响推理时间。最初,编码器 BERT 模型的输入长度为 128。通过将其减少到 30,我们将推断时间从 300 毫秒减少到 125 毫秒,而不损失准确性。

同样,阅读器模型最初的输入长度为 380。通过将此值减少到 128,我们将平均延迟从 1.9 秒减少到 741 毫秒,这是一个显著的减少。然而,我们的准确率确实下降了,因为一些问题和段落的组合会导致令牌序列超过 128。这将精确的匹配分数降低到 39.61。

编码器和阅读器型号都支持动态长度输入,但 Vespa 目前仅支持固定长度输入。不过,这个问题将在不久的将来得到解决。总之,缩短编码器和阅读器模型的令牌输入长度会导致 3 倍的加速。

模型量化

神经网络模型通常使用单精度浮点数来训练。然而,对于生产中的推理,已经表明这种精度水平并不总是必要的。可以将参数转换成更小的整数表示,而不会显著降低精度。将参数从 32 位浮点转换为 8 位整数会将模型大小减少 75%。更重要的是,整数运算执行起来要快得多。支持 AVX512 矢量神经网络指令(VNNI)的现代 CPU 旨在加速 INT8 推理性能。此外,评估这种量化模型需要更少的功率。

量化阅读器模型使其大小从 435Mb 减少到 109Mb。系统的延迟平均下降到 374 毫秒。这对准确性有一点不幸的影响,精确匹配下降到 37.98。类似地,量化编码器模型导致类似的大小减少,并且系统评估时间下降到 284 毫秒,精确匹配分数下降到 37.87。

总之,阅读器和编码器模型的模型量化导致另一个 3 倍的加速。

微缩模型

到目前为止,编码器和读取器模型都是基于预训练的 BERT-base 模型,包含 12 层,隐藏维度大小为 768,因此大约有 1.1 亿个参数。这些都是相当大的模型,尤其是在时间有限的环境中使用时。然而,在论文“博览群书的学生学得更好:论预训练紧凑模型的重要性”中,作者表明较小的模型确实可以工作得很好。本文引用的“微缩”模型可以在变形金刚模型库中找到。

我们训练了新的读者模型,如 DPR 知识库中所述,基于以下预训练的 BERT 微型模型:

  • 中号(8 层,512 隐藏尺寸)
  • 小(4 层,512 隐藏尺寸)
  • 迷你(4 层,256 隐藏尺寸)
  • 微小(2 层,128 隐藏尺寸)

我们也对每个模型进行量化。下表给出了具有精确匹配分数和平均延迟的所有 20 个模型(5 个阅读器模型,有和没有量化,有和没有量化编码器模型)的完整概述:

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

各种模型类型的精确匹配分数与延迟

绘制这些结果:

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

精确匹配与延迟(图片由作者提供)

在上图中,红线代表帕累托前沿。沿着这条战线的点在上表中也用粗体标出。回想一下,这些点代表了精确匹配和延迟之间的最佳权衡,这意味着对于这条战线上的每个点,没有其他点在精确匹配和延迟方面更胜一筹。

这里可以看到的一个有趣的结果是,一般来说,量化模型以更高的精度支配其他模型。例如,中等量化模型比具有更高精度的小模型具有更好的精确匹配和延迟数。因此,在这种情况下,尽管量化会降低精度,但选择已量化的大模型比选择未量化的小模型更有利。

帕累托前沿将客观上的最佳解决方案可视化,而我们的主观偏好将引导我们找到最佳解决方案。以上测试是在一台英特尔至强金牌 6240 机器上运行的。更强大的处理器会降低整体延迟数字,但不会改变整体形状。选择的确切解决方案基于我们的延迟和硬件预算。例如,拥有大量资源并能够充分扩展的组织可以证明在这方面向右移动是正确的。规模经济可以降低硬件投资和能源消耗的成本,使服务变得可行。这样的解决方案对其他人来说可能遥不可及。

把这些放在一起

请参考配套示例应用程序,了解更多关于如何自己运行该应用程序的详细信息和说明。

结论

总的来说,我们将一个性能不佳的研究应用提升到了适合生产的水平。从完整模型的 9.4 秒到微型模型的 70 毫秒,这代表了 130 倍的加速。不幸的是,为了达到这些水平,我们也注意到精确匹配的显著下降。最佳选择介于这两个极端之间。如果我们要将该应用程序投入生产,我们可以使用更强大的硬件来将延迟降低到 100 毫秒以下,并具有可接受的精确匹配指标。

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

有相当多的优化我们没有尝试,超出了本文的范围。例如, FastFormers:用于自然语言理解的高效转换器模型包括一些额外的优化,用于更高效的推理,如模型修剪。此外,新一代的 BERT 模型试图缓解与完全注意机制相关的性能问题。例如,大鸟架构看起来很有前途。

我们省略了训练微型编码器模型。从延迟的角度来看,在问题编码中使用微型 BERT 模型具有额外的好处,因为问题和段落的向量表示更短。因此,近似最近邻搜索将变得更加有效。然而,这可能会导致准确性的显著下降,并且花费在人工神经网络上的时间无论如何都不是延迟的重要驱动因素。

添加额外的内容节点将允许分配工作负载。这可能不会减少延迟,但会增加我们可以用阅读器模型评估的通道数。我们将在下一篇博客文章中回到这个话题。

利用深度半监督学习从研究到生产

原文:https://towardsdatascience.com/from-research-to-production-with-deep-semi-supervised-learning-7caaedc39093?source=collection_archive---------9-----------------------

理解大数据

分享经验,将研究带入现实世界。

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

我从 2019 年 6 月开始的一叠半监督学习论文,上面是我在该领域阅读的第一篇论文:mix match——我不建议为了很好地回忆你所阅读的内容而在所有东西下面划线。(图片作者)

T 今天大多数深度学习算法的成功很大程度上是几十年研究的结果,GPU 和数据的可用性越来越大。但并不是任何类型的数据——那种丰富、干净、标记为 的**。**

ImageNet、CIFAR10、SVHN 等数据集让研究人员和从业者在计算机视觉任务上取得了显著进展,对我们自己的实验非常有用。然而,对于许多寻求从这一进步中受益的应用程序(如医学)来说,最大的困难恰恰是数据必须是丰富的、干净的和有标签的。

**半监督学习(SSL),**结合了监督和非监督学习的子领域,在过去几年中,在深度学习研究社区中变得越来越受欢迎。很有可能,至少在短期内,SSL 方法可以成为标签繁重的监督学习和数据高效建模的未来之间的桥梁。

在本帖中,我们将讨论何时应该考虑在您的生产环境中使用 SSL 方法,以及我们在 Uizard 使用它们来改进我们的对象检测模型时学到的经验。当然,我们会尽最大努力分享大图,但对我们自己保留一些魔法的细节。

我们希望通过展示 SSL 如何以及何时对我们起作用以及不起作用,并通过分享我们从研究到生产的旅程中所学到的技巧,我们可以激励您在工作中抓住 SSL 的机会,并释放您未标记数据的潜力。

简而言之,这里有一些我们强调的教训:

  • **简单才是王道。**SSL 中从研究转化为生产的最成功的方法是那些最容易复制的方法。具体来说,我们将阐述“与吵闹的学生一起自我训练”(谢等人,2019 )是如何为我们工作的。
  • 使用启发式算法的伪标签精化可能非常有效。伪标签是 SSL 方法的一个受欢迎的组成部分,我们发现使用简单的试探法来改进未标签数据中的伪标签可以提高不同大小的未标签数据集的性能。
  • **半监督图像分类的进展很难转化为目标检测。**我们跟踪的 SSL 的大部分进展是测量图像分类的性能,并承诺在对象检测方面有类似的改进,但我们发现在实践中很难适当地调整它们。因此,在半监督目标检测领域需要更多的工作和研究。

什么是半监督学习(SSL)?

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

半监督学习与监督学习的区别的简单说明。(图片作者)

顾名思义,半监督学习(SSL)是指介于监督和非监督学习之间的一类算法,旨在使用标记和未标记数据来建模分布。

SSL 的目标通常是比单独使用带标签的数据做得更好,能够模拟目标分布,就好像我们也可以访问所有未标记数据的标签一样。

这种算法并不是一个新的想法,尽管在过去的 18 个月中,深度半监督学习已经有了相当多的兴趣、进展和应用,我们将在下面讨论。

我什么时候适合在生产中使用 SSL?

如果您正在考虑使用 SSL 来解决某个问题,那一定是因为您的数据集很大,并且有许多未标记的数据点。你的数据集的一部分可能会被标记,当然标记的数据越多越好——但是希望至少有和标记的数据一样多的未标记的数据,或者更多的数量级。

如果您可用的大部分数据都是带标签的,或者未带标签的数据集来自与带标签的数据集显著不同的分布,那么 SSL 现在可能不太适合您的应用程序。对于后一种情况,请查看域自适应。

考虑到这一点,有两个主要的设置证明了在现实应用程序中研究 SSL 方法的合理性:

  • 您正在处理一个高价值问题,对于该问题,仅标记的数据不足以产生足够的性能,但是**多几倍(10–100 倍以上)**未标记的数据是可用的和/或容易获得的。

在这种情况下,我们强调值得生产的性能的可能性较低——但是在给定一个数量级或更多的未标记数据以及足够的激励、时间和资源的情况下,为几乎没有标记数据的任务尝试 SSL 可能是有意义的。

  • 你正在解决一个问题,对于这个问题,有标记的数据本身就足以产生足够的性能,但是你有一个未标记的样本集合,你想用 T2 进一步提高性能。

在这种情况下,您可能已经有了一个运行良好或几乎达到要求的模型,但是您希望继续提高性能,而不需要花费太多精力来标记新数据。因此,SSL 可以被视为改进建模的许多其他工具之一,如获得更清晰的标记数据集、训练更大的模型等。对于差错率相对降低 5–10%以上的性能关键型应用程序,以及可获得未标记数据的应用程序,SSL 尤其适用。

值得注意的是,特别是因为 Uizard 是一家拥有快速增长的 beta 用户群的初创公司, 在持续/主动学习环境中使用的 SSL 也有可能创造出您在下面看到的循环。 未标记的数据用于在我们的平台中训练和部署改进的模型,这反过来驱动额外的用户,从而产生额外的未标记数据来从头开始该过程。

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

半监督学习(SSL)模型在生产环境中的生命周期,其中不断增长的用户群可以创建一个正反馈循环。(图片由作者提供)

研究的方法

以下是我们在图像分类和对象检测方面尝试的一些方法,但 SSL 同样可以应用于其他领域,如 NLP ( Liang 等人,2005 )和音频/语音处理( Tur 等人,2005 )。

图像分类

  • MixMatch(贝特洛等人,2019)[ pdf ][ 代码
  • 无监督数据增强(UDA)(谢等,2019)[pdf][code]
  • FixMatch (Sohn 等人,2020-A)[ pdf ][ 代码 ]

物体检测

任务无关

  • 吵闹的学生(谢等,2019)[pdf][code]

虽然我们不会详细讨论上面的每一种方法,但是下面关于半监督学习的博客非常棒,涵盖了上面列出的许多技术。

第一课:简单是王道。

在 2019 年 6 月我们对半监督学习方法的最初文献综述中,读到 MixMatch 和 UDA 在 SSL 方面取得了显著进展,特别是在标签数据极其有限的情况下,这令人着迷。我们能够相对轻松地在 CIFAR10 和 SVHN 上重现他们的结果,这让我们对他们将这些性能提升转化到我们的数据集的能力充满信心。

然而,我们这样做的体验并不理想,主要是因为——惊喜!—超参数调谐。论文中使用的数据集的许多开箱即用的超参数对我们数据集的性能变化更敏感。我们还注意到,我们的标记数据集在分布上与未标记数据集略有不同,这个问题通常会降低 SSL 技术的性能,并在 Oliver et al .,2018 中提出,作为 SSL 需要克服的挑战,以用于“现实”设置(请参见本博客末尾的附录 A,了解我们对此的研究工作)。截至 2019 年 9 月,现有的最先进的 SSL 技术似乎不够简单或灵活,不足以让我们继续前进。

快进到 2020 年 6 月,已经发布了两个关于 SSL 的新作品,主要关注简单的实现——fix match 和嘈杂学生的自我训练。

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

FixMatch 中如何使用未标记图像的示意图。(图片来自 Sohn 等人,2020 )

FixMatch 是其前身 MixMatch 的一个更简单但更有效的版本,我们成功地在论文中提出的数据集上复制了他们的结果。这一次,我们能够在我们自己的图像分类数据集上看到良好的结果,性能对超参数的选择不太敏感,并且可调整的超参数更少。

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

有吵闹学生的自我训练图。(图片来自谢等人 2019 )

嘈杂的学生训练由一个迭代过程组成,在这个过程中,我们训练一个教师模型(可以访问标记数据的模型),使用这个模型来推断未标记数据的输出,然后根据标记数据和伪标记数据重新训练一个新模型,称为学生。然后,我们可以重复这个循环,称为自训练,通过使用这个学生模型在未标记集合上推断新的伪标签。在 Xie et al .,2019 中,他们展示了上述框架如何在使用 300M 未标记图像时提高 ImageNet 分类精度,并强调了各种类型噪声的添加(增强、丢失等。)作为几项消融研究成功的关键。

值得注意的是,嘈杂的学生方法是一个任务无关的框架,可以广泛应用于:图像分类,对象检测,情感分析等。 对我们来说,在我们尝试的所有技术中,嘈杂的学生方法是最成功的对象检测方法。 我们在第 3 课中讨论了为什么 FixMatch 的对象检测对应物(STAC)和其他方法可能对我们不起作用,但是我们坚信吵闹学生的简单性和灵活性与其他方法相比是我们看到生产模型改进的原因。

为什么很简单?*现有训练超参数和设置几乎没有变化。*以下是完整管道所需的内容:

  1. 把我们现有的生产模式当成教师模式。
  2. 与老师一起编写几个脚本来推断和提炼无标签数据上的伪标签(有关伪标签提炼的更多信息,请参见第 2 课)。
  3. 用添加的噪声(增强等)训练“学生”模型。).
  4. 按照嘈杂的学生图中所示的框架重复该过程。

其他注意事项和想法:

  • 当**可用的未标记数据少于标记数据时,我们惊讶地看到用嘈杂学生方法实现的一些模型有所改进。**第二课将详细介绍这一点。不过一般来说,如谢等,2019 所述,未标记的数据越多越好。
  • 我们看到,使用普通的自我训练,我们的学生模型的性能有所改善,而没有实现谢等人,2019 的一些部分,如辍学、随机深度或软伪标签。这些部分一旦被添加,可能会像在 ImageNet 上那样进一步提升我们的性能。
  • 使用更大的学生模型的结果是混合的——对我们来说,这意味着在我们的检测模型中从 ResNet-50 到 ResNet-101 主干。

总的来说,当涉及到图像分类或物体检测时,简单是王道。与 MixMatch 相比,FixMatch 明显更容易适应我们的自定义图像分类数据集,而 Noisy Student 只需要对我们现有的对象检测管道进行很小的更改,就可以看到性能的提高。

第二课:启发式伪标签提炼非常有效。

伪标记,也称为自我训练,是 SSL 中的一种范式,早在 20 世纪 60 年代和 70 年代就出现了,并且由于其简单性而一直存在( Scudder,1965麦克拉克伦,1975 。深度 SSL 伪标记的引入( Lee,2013 )展示了用标记数据训练模型,使用该模型推断未标记数据上的标签(现在称为伪标签),然后用标记和伪标记数据进行重新训练的想法是多么简单而强大。今天,许多 SSL 技术使用某种形式的伪标记,包括 FixMatch 和嘈杂学生的自我训练。

然而,这些伪标签经常会有噪声,并且需要某种形式的改进才能被使用。在 FixMatch 和 Noisy Student 中,这意味着将阈值(比如 0.7 或 0.9)应用于推断的伪标签,并且仅采用 softmax 置信度得分高于该阈值的那些预测。我们发现这是获得高质量伪标签的一种有用的启发式方法,但是还发现对伪标签应用其他领域特定的启发式方法在嘈杂的学生设置中有很大帮助。

我们在谈论什么样的启发法?例如,假设您正在为一家房地产公司构建一个对象检测分类器,该公司需要为家中的不同对象添加边框注释。您注意到(教师)模型的预测通常是好的,但是,分类器倾向于在未标记的集合上产生几个不正确的、高置信度的预测,即一些梳妆台实际上是厨房岛。

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

我们可以在嘈杂的学生训练中使用特定领域的启发式算法来改进伪标签,以提高半监督性能。(图片由作者提供)

这里有一些启发性的例子,我们可以从中选择来完善这个标签:

  • 如果在同一个图像中预测了岛和床,请将岛标签转换为梳妆台。
  • 如果梳妆台和岛预测在同一图像中,请将岛标签转换为梳妆台。
  • 如果在同一个图像中预测了岛、床和梳妆台,请将岛标签转换为梳妆台。

以上哪种启发最有意义?这将取决于您的数据集和最常见的错误类型。如果模型在检测床方面做得很好,也许像第一个或第三个例子这样的启发式方法可能会有用,因为我们不希望床和厨房岛出现在同一张图像中。

特别是在对象检测中,当对象的位置和大小遵循您的应用领域中的特定规则时,您可以定义类似这样的试探法来优化嘈杂的伪标签,并帮助您的学生模型学习教师模型无法学习的更好的表示。

我们能够在我们自己的有噪声的学生模型中实现更好的性能,使用启发式伪标签细化,在某些情况下,使用**,无标签数据比有标签数据少一个数量级。**我们还发现有趣的是,这一课听起来与罗森伯格等人 2005 年发表的题为对象检测模型的半监督自我训练的论文中的观察结果惊人地相似:

…独立于检测器定义的训练数据选择度量大大优于基于检测器生成的检测置信度的选择度量。

这是您所有数据和建模问题的解决方案吗?当然不是——但它说明了启发式仍然是深度(半监督)学习管道中有用的一部分。同样,这里应用的试探法是特定领域的,只有仔细研究您的数据和模型的偏差,才能揭示有用的伪标签细化。

第三课:半监督图像分类的进展很难转化为目标检测。

我们跟踪的 SSL 研究的大部分进展都是测量图像分类的性能,希望能够轻松地将技术应用于其他任务的类似改进,如对象检测。然而,在我们自己尝试将图像分类方法用于对象检测时,我们遇到了几个挑战,这导致我们坚持使用第 1 课中提到的最简单的半监督对象检测方法。以下是其中的一些挑战:

  • 在线与离线伪标签生成

在许多用于图像分类的 SSL 技术(FixMatch、UDA 等)中。),未标记数据的伪标记目标在训练期间在线被更新/计算。在离线中,学习培训分为多个阶段。首先用标记样本训练模型,然后用标记样本生成伪标签。然后可以用标记的和伪标记的样本训练新的模型。

FixMatch 和 UDA 是 SSL 技术的示例,它们使用在线学习来通过阈值取得良好效果,仅允许预测高于某个阈值的未标记样本对训练信号有所贡献——在嘈杂的学生和 STAC(fix match 的对象检测变体)中,然而,伪标签是离线生成的。

虽然在线学习似乎是有利的——允许在稍后的训练步骤中纠正早期训练中的不良伪标签— **,但它使得训练在计算上更加昂贵,对于训练对象检测模型来说更是如此。**为什么?两件事:数据扩充和批量大小。关于数据扩充,让我们重温一下在第 1 课 FixMatch 中首次出现的图表。

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

FixMatch 中如何使用未标记图像的示意图。(图片来自 Sohn 等人,2020 )

我们看到,每个未标记的示例在训练期间都是“弱增强”和“强增强”的,并且需要将两个增强图像通过网络向前传递以计算损失。这种数据扩充是许多 SSL 方法的基础,并且尽管对于图像分类是可行的,但是对于大图像(512x512+)上的对象检测任务的处理训练时间扩充会显著减慢训练。

在批量大小方面,许多作品(MixMatch、UDA、FixMatch、Noisy Student)和我们自己的实验也强调,未标记的批量大小是标记的批量大小的几倍对于 SSL 方法的成功至关重要。对对象检测任务的这种要求与存储器中的大图像以及对无标签批次中的所有样本的必要扩充相结合,产生了极大的计算负担。数据扩充和无标签批量大小这两个挑战是我们无法将像 FixMatch 这样的工作一对一转换为对象检测的最终原因。

在与 STAC 的作者的讨论中,他们也注意到了半监督对象检测空间中在线学习带来的沉重资源开销。我们希望未来的工作将更深入地研究这个问题,并且在未来几年中取得的计算成果将使研究人员更容易进行这样的工作。

  • 用阶级平衡管理长尾

SSL 研究中的许多基准数据集,如 CIFAR10、CIFAR100 和 STL-10,都使用类平衡标记的训练集。我们的数据集,像许多真实世界的数据集一样,是极其长尾的。类别平衡被认为是许多 SSL 方法的关键组成部分(谢等人,2019宋等人,2020 ),在图像分类中,上采样和下采样技术是常见的做法。然而,在对象检测设置中,有效的类平衡技术并不简单。

如果类平衡对于 SSL 在实践中的成功至关重要,那么我们如何在半监督对象检测中实现类平衡呢?解决这个问题的未来研究肯定会受到欢迎。

其他提示

迁移学习和自我培训是相加的

正如在 Zoph 等人关于 COCO 训练的 2020 中所发现的,执行从 COCO 到我们数据集的迁移学习,然后在嘈杂的学生环境中执行自我训练,所产生的结果比单独执行这两个步骤中的任何一个都要好。很可能任何应用于生产模型的迁移学习也可以应用于 SSL 模型,并带来同等或更多的好处。

适当的数据扩充很重要

由于数据扩充是现代 SSL 方法的主要组成部分,所以要确保这些扩充对您的领域有意义。例如,如果可用的增强集包括水平翻转,那么应该被训练来区分左箭头和右箭头的边界框的分类器显然会受到影响。

此外,在( Sohn 等人,2020-B )和吵闹的学生(谢等人,2019 )中,他们观察到,在自我训练中,对教师模型使用数据增强会导致下游学生模型较差。

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

(表 6 来自谢等,2019 )。在这项消融研究中,他们说明了具有增强功能的教师模型比没有增强功能的教师模型表现稍差(在 130 万张未标记图像上,84.4%对 85.1%)。

然而,我们发现嘈杂的学生和 STAC 在我们的数据集上的表现与增强的教师模型相等或略好于非增强的教师模型。虽然我们的结果对于我们自己的数据集来说可能是一个特例,但我们相信这表明了广泛实验的 重要性,以及对你在论文中读到的观点的所谓成功和失败感到好奇。 论文中显示的经验结果是一个很好的开端,但成功肯定是无法保证的,而且从理论角度来看,SSL 中仍有许多东西没有得到很好的理解。

离别赠言

半监督学习(SSL)在过去的一年中一直是我们工作的一个令人兴奋的领域,它在我们的生产模型中的最终结果向我们(希望你们所有人)表明,在某些情况下可以并且应该考虑 SSL。

特别是,对吵闹的学生进行自我训练对改进我们的目标检测模型是有效的。以下是我们在研究和生产深层 SSL 技术时学到的 3 个主要经验:

  • 简约为王。
  • 启发式伪标签精化非常有效。
  • 半监督图像分类的进展很难转化为目标检测。

今天,许多深度学习工程仍然在为潜在的应用进行反复试验,我们希望你带着更多的先验知识离开,以推进半监督学习的工作。

作者 Varun Nair,杜克大学四年级本科生,前深度学习研究实习生。

致谢:

非常感谢 Javier Fuentes AlonsoTony Beltramelli 阅读了这篇文章的几份初稿,并在我在 Uizard 工作期间成为了令人惊叹的同事和导师。我还要感谢 Uizard 的整个团队,感谢他们支持我,为我创造了一个绝佳的工作环境,无论是面对面的还是远程的。如果你有兴趣了解更多关于 Uizard 的工作和职位空缺,请查看我们的网站。

也感谢北卡罗来纳大学/谷歌的Colin raff El博士对这篇文章的早期草稿提供了很好的见解和反馈,感谢谷歌的Kihyuk Sohn博士对我关于他的作品的问题的积极和开放的回答。

附录

A —对非分布样本的稳健性

在我们过去的工作 RealMix ( Nair et al .,2019 )中,我们通过模仿 Oliver et al .,2018 中首次建立的一个实验,研究了 SSL 网络中对分布外未标记样本的鲁棒性。

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

(图片由作者提供)原载于奈尔等人,2019

我们最近在 75%的标签错配设置下对 FixMatch 进行了相同的鲁棒性实验,并在下面展示了这些结果。FixMatch 是一个更好的 SSL 应用程序,在标记和未标记的分布之间的不匹配率为 0%和 75%,但是,在这种情况下,它的性能与 MixMatch 一样差。有可能通过将 RealMix 中的元素与 FixMatch 结合起来,这种结合的技术可以克服这个问题。

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

在六类 CIFAR10 上进行 0%和 75%分布不匹配实验的错误率。(图片由作者提供)

从资源管理到数据科学:构建实时爬虫

原文:https://towardsdatascience.com/from-resource-management-to-data-science-building-real-time-crawler-dcbb4d413d7f?source=collection_archive---------54-----------------------

对构建和实现大规模网络爬虫感兴趣?从我们的错误、经验和建议中学习,这将有助于您创建一个强大的 web 数据采集工具。

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

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

Oxylabs 我们几乎是偶然地创建了一个大规模的网络爬虫。正如人们偶然发现的任何开发项目一样,我们在这个过程中犯了很多错误,也吸取了很多教训。我们希望我们的故事能对任何对创建数据采集工具感兴趣的人有用。

我们一开始是代理提供商,为所有想要执行大规模数据收集项目的人提供服务。正如那些深入研究这个行业的人所熟知的那样,当代理被用来抓取搜索引擎结果和复杂的电子商务网站时,它们很容易被禁止。

我们注意到,一些用户比其他人有更好的成功率和代理寿命,即使是在抓取相同的目标时。随着时间的推移,获得了很多关于网络抓取的知识。反过来,我们试图通过分享任何相关信息来提供价值。就像我们现在希望的那样。

卑微的出身

不幸的是,即使是最好的指导方针也无法抵御防刮擦措施不断变化的性质以及对持续数据流的需求。代理最终还是被封锁了。更换它们会推高交易双方的成本。

代理受阻对双方来说都是痛苦的经历。由于被封锁的 IP 地址,公司需要减慢他们的数据采集操作,而我们需要不断地采购更多的代理。幸运的是,一个解决我们困境的方法以最意想不到的方式出现了:我们的一位数据分析师学习了 Python 的基础知识。

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

照片由 Unsplash 上的除以零

不是这种类型的 Python。

构建原型

一位用户与电子商务网站进行了长期的斗争。不管他们是运气不好还是在爬虫的开发过程中出了什么差错,我们提供的代理似乎总是被屏蔽。在内部,开发我们自己的铲运机的想法已经流传了很长时间,但没有人坐下来真正开发它。直到我们的一位数据分析师决定亲自动手。

与任何对工具包有非常基本的理解但又充满热情的项目一样,它是一个烂摊子,由 Flask API、请求库和对古代蛇神的祈祷组成。当然,这是一个烂摊子,但它的工作。事实上,我们的原型做得相当好,尽管它确实有一些小问题,只是后来才变得明显。因此,在 2017 年的一个深夜,我们最新的解决方案诞生了,我们继续称之为实时爬虫。

规划和开发实践中的经验教训

不幸的是,虽然我们的解决方案有效,但最初为其开发实时爬虫的客户并没有接受我们的提议。但是我们确实有一个工作原型,它展示了很多希望。我们的想法是,我们可以进一步优化这个工具,以比以前更有效地从大型电子商务网站和搜索引擎获取数据。通过坚持我们随时间发展的最佳实践,我们可以充分利用每个 IP 地址并避免潜在的阻塞。如果我们不提供资源来购买产品,而是提供产品本身,会怎么样?希望没有人会再为棘手而复杂的数据采集过程而挣扎。

虽然我们的原型运行良好,但它仍然不适合广泛使用:一个单独的服务器托管整个过程,一次只能处理几个请求,最糟糕的是,获取的数据以 html 文件的形式存储在服务器文件系统上。当我们的工具最初被开发出来时,我们并不关注长期的大规模实施,因为它是出于我们能够解决一个特定挑战的希望。

我们意识到,如果我们承受任何压力,它都会在几秒钟内折断。但是希望就在那里,这就足够了。我们的高管和高级开发团队与我们的数据分析师坐下来,开始为未来制定计划。我们会用一个更好的计划重新开始。

亲爱的朋友们,再一次冲向缺口,再一次

于是,我们的实时爬虫开始了认真的开发。需要实现几个特性:

  • 更好的请求和交付处理
  • 排队系统
  • 更好的服务器基础设施

幸运的是,最后两点并没有带来什么挑战。我们开发了队列系统,并通过使用 API 和 MySQL 将实时爬虫部署到许多不同的服务器上。当然,这些变化不是一夜之间发生的。虽然最初的实现相当快,但近 3 年的大部分时间都致力于消除细节和添加附加功能。

一个更好的请求和数据传递系统并不容易实现。然而,我们必须快速开发一个,因为用户在实现我们最初的构建时遇到了问题。

查询和交付:一场我们自己打的硬仗

我们开始时只有一种查询和检索数据的方法——回调。用户将发送一个有效载荷,详细说明他们对我们的服务器的请求,并能够在作业完成后检索所请求的数据。出于检索目的,将为每个有效负载分配一个唯一的作业 ID。此外,我们实现了回调 URL,我们将 ping(如果提供的话)它,以便平滑这个过程。

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

来源:Oxylabs 的设计团队

然而,回调有一个我们无法预测的问题:它很难实现用于测试目的。不足为奇的是,如果你的目标受众无法轻易测试你的工具,那么让别人相信你的工具对双方都有利是很难的。但我们希望以最高效的方式交付所需的数据。更重要的是,这个行业的大多数企业已经有了内部的网络爬行解决方案。为这些公司提供价值比我们预期的要困难得多。

我们的销售和营销团队不得不加倍努力工作。如果我们稍微多关注一下我们周围的开发文化****——哪些语言、API、框架等被广泛使用,就可以节省很多精力和时间。

可靠性与电子商务

我们知道我们将面临一个无止境的挑战——布局和反瓶颈变化。搜索最具挑战性和最受欢迎的搜索引擎和电子商务网站并不容易。这两家公司都不会永远使用相同的布局,也不愿意轻易放弃他们的数据。所有这一切意味着我们的大部分资源过去和现在都致力于了解反刮擦措施是如何实施的,以及我们可以为此做些什么。

仅仅通过提供我们通常的商业服务,我们就在数据采集行业获得了大量的经验和专业知识。强大的技术基础使我们能够预见某些挑战,并在它们出现之前实施解决方案。然而,有两个问题我们的经验无法解决:数据存储和易于实施。

处理数据存储问题

数据存储成为一个比预期更大的问题。我们犯的一个错误是只从一个方法开始——回调。回调似乎是一开始处理数据的好方法,因为理论上非常简单。不幸的是,被查询的数据必须放到某个地方,直到有人检索它。通常情况下,检索会被延迟。因此,这些数据必须存储,直到有人来取走。

我们实施了一个 24 小时(通常,用户有更多的时间)的政策,因为它似乎是合理的。不可避免的是,24 小时以上存储大量数据会给任何存储基础架构带来很大压力。为此,我们决定通过创建缓存、优化数据库和简单地装备更好的硬件来消除冗余的数据查询。但这些解决方案只能到此为止。此外,电子商务数据具有时效性,24 小时前的数据可能已经过期。我们需要找到更好的方式让用户发送查询和接收数据。

将我们的重点转向提供更好的交付方法和更简单的方法来实现我们的工具给我们带来了巨大的成功。我们确信实时爬虫对双方都有利,但是我们需要一种方法来减少进入的障碍。

试用、易于实施和新的交付方法

试验问题从相同的初始开发过程中分支出来。如前所述,实现实时爬虫相当困难,这使得试验和测试非常痛苦。我们的解决方案之一是为我们的工具开发额外的方法。正如我们工具的包装上所说,实时是第二个被创造出来的方法。它的实现稍微容易一些,但是它依赖于一个开放的连接来不断地传递查询的数据。

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

来源:Oxylabs 的设计团队

实时给我们带来了两个好处——测试稍微容易一些,减少了对数据存储设备的压力。实时带来了一场革命,因为其他人无需重建整个基础设施就可以看到它的运行。但它仍然不够好,因为长期的实现仍然需要用户修改他们当前的爬行解决方案。需要另一种解决方案。

SuperAPI 是实时爬虫的最终形式。它允许用户实现我们的网络抓取解决方案,而不需要修改任何东西。他们会将我们的工具设置为他们自己的网络爬行工具中的代理服务器。其他一切都将正常工作,就好像它是通过其他方法实现的一样。最后,用户可以实现我们的解决方案,而不需要通过复杂的过程来改变已经为他们工作的东西。

现在有三种交付方式:

  • 回收
  • 实时
  • SuperAPI

他们每个人都有自己的优点和缺点。大多数用户仍然使用老式的回拨,因为它可靠且使用简单,尽管入门有点困难。我们后来开发了更多的交付方法,因为我们更加关注提供更好的测试机会。现在,提高稳定性将是我们的最新目标。

维持稳定

我们最后的挑战是保持稳定。每一种工具都会偶尔发生故障,而大多数其他流程都准备好处理它。在数据采集中,尤其是与电子商务相关的数据采集,过程中的故障可能是灾难性的。

数据获取的稳定性是网站和开发者之间不断的拉锯战。出于用户体验的原因,网站可能会更新其布局,这也是一种反对数据抓取的做法。每次布局变化都会中断数据采集过程,并且需要一些时间进行重新开发。

防刮算法改进更差。就像布局变化一样,它们会破坏任何工具,但是重新开发过程会困难得多。逆向工程将是必需的,这意味着没有一个令人敬畏的开发团队和一点点运气,回到正常工作秩序可能需要大量的时间和资源。不幸的是,没有允许任何人无限期保持稳定的长期解决方案,只有最佳实践。

随着时间的推移,我们已经学会了关于保持稳定的两件事。首先,必须有一个专门的危机应对团队,每个人都准备好昼夜不停地工作,直到问题得到解决。每一个小时都很宝贵。第二,危机解决后,寻找数据采集过程中断的模式。根据你的预测打补丁也许你会避免以后出现类似的问题。

最终确定概念

虽然我们一直在构建和改进我们的网络爬行解决方案,但随着时间的推移,主要概念保持不变。以下是我们的实时爬虫如何工作的基本概要:

  1. 有效负载已发送到 API。
  2. 记录作业并设置 ID。
  3. 设置成队列系统。
  4. 每个队列可以被许多不同的 RTC 实例/服务器使用。
  5. 该作业由特定实例获取。
  6. 设置并检查指纹(根据最初要求)。
  7. 在作业启动之前,我们的[主]代理轮转程序会处理和分配合适的 IP。
  8. 作业已启动,HTML 已下载。
  9. 用过的 IP 会被送去冷却。
  10. 如果作业失败,实时爬网程序将使用不同的设置重试,直到成功。
  11. 数据被解析并为检索做好准备。

成功的步骤:数据收集的教训

我们的工具已经运行了一段时间了。从最初的粗陋到现在的天网般的机器霸主——实时爬虫,我们学到了很多东西:

  • 创造工具,一只眼睛盯着未来,另一只眼睛看着市场。分析哪些语言、API、框架最受欢迎。它将为您节省大量的时间和成本。
  • 构建行业领先的软件需要时间。这些年来,我们面临(现在依然如此)数百个挑战,有时我们认为实时爬虫可能没有我们最初想象的那么好。
  • 想办法提供一个简单的测试环境。通常你必须说服商人,而不是开发商。
  • 编写简单易懂的教程,并提供大量成功的例子。
  • 确保您的工具是可扩展的,并且其功能不会在其他领域(如数据存储)引起问题。
  • 数据存储将不可避免地成为一个问题。创建节省空间的流程—构建缓存、收购更多存储中心。
  • 有一个专门的危机应对团队,因为故障是不可避免的。
  • 分析每个分解。每一次危机至少都会为未来可能的崩溃提供线索。根据线索打补丁。

结局?

随着互联网格局的不断变化,大规模数据收集是一个永无止境的过程。我们仍在通过添加更多的目标,增加稳定性和适用性来改进我们的实时爬虫。我们最新的 fork,通用实时爬虫,仍然是一个萌芽项目,我们希望扩展到和它的前辈一样的高度。

我们花了很多年的时间和无数的错误来建立一个成功的大规模爬行工具。我们邀请所有人向我们学习。通过遵循我们在这一过程中学到的经验,您将使任何数据采集项目成本更低,耗时更少。

从零开始到搜索:处理数据(Elasticsearch 摄取管道)

原文:https://towardsdatascience.com/from-scratch-to-search-playing-with-your-data-elasticsearch-ingest-pipelines-6d054bf5d866?source=collection_archive---------5-----------------------

一条管道来统治他们,一条管道来吸收他们,一条管道来转变他们,并在弹性搜索中绑定他们。

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

朱利安·维勒拉在 Unsplash 上拍摄的照片

介绍

在这篇文章中,我想快速浏览一下 Elasticsearch 提供的一个有趣的特性,我也倾向于在作为摄取管道的生产设置中使用它。此功能允许 在实际文档索引发生之前预处理文档 。听起来很有趣,为什么…

***Note: for an introductory hands-on overview of the Elasticsearch technology check out*** [***my previous article***](/from-scratch-to-search-setup-elasticsearch-under-4-minutes-load-a-csv-with-python-and-read-e31405d244f1)***.***

这在很多方面都很有用,但我认为有两个主要原因。首先,当你更多地处于(大)数据分析/处理方面时,你的优先事项(和任务)可能不会涉及源系统的主动变更。因此,您必须在原始数据到来时对其进行处理,并对其进行预处理以满足您的数据需求。第二,即使你打算改变生产者,你 A)可能不能直接控制所有的生产者(例如,由于一些组织方面的原因,例如,他们的遗留性质)和/或 B)仍然需要做好准备,改变可能需要相当长的时间(例如,想想你想要在你的共享日志库的新版本上升级数十/数百个微服务,等等)。).

对于这些情况,您可以调用来维护接收管道。

它是如何工作的

摄取管道是数据解析和转换领域的新玩家,长期以来一直被 Logstash 所占据。摄取管道实际上不是 Logstash 的完全替代。但是使用 Logstash 的考虑是,它不可避免地给你的架构带来了另一个 sw 组件,从而使它的操作更加复杂。摄取管道则不是这样,因为它们是由集群中的任何(或所有)常规 Elasticsearch 节点直接执行的。该节点只需要是摄取节点的类型(这是默认的),这样当您想要开始使用它们时,甚至不需要修改配置。

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

在索引操作期间,在协调器节点接收到请求之后,在摄取节点上执行流水线。图片来源:elastic.co

管道定义

一般来说,管道是通过一个简单的 JSON 文档定义的,该文档包含一个处理器阵列,它代表一组有序的步骤,这些步骤应用于所有传入的文档并在其上执行。实际的处理器有各种各样的风格,所以我强烈推荐您浏览一下文档中的列表来熟悉一下。

处理器有一些共同之处。这些是:

稍后将详细介绍这些内容。

测试环境加速旋转

理论已经讲得够多了,让我们在本地机器上的 Docker 中构建一个简单的(单节点)集群,并尝试第一个管道定义。注意:如果你需要更多关于 docker 部分的信息,可以在 我之前的文章 中找到。让我们也做一个 Kibana 的实例,以便有一个简单的 GUI 来查看。

#!/bin/bashdocker network create elastic-networkdocker run --rm --detach --name elastic4pipelines -p 9200:9200 -v esdata01:/usr/share/elasticsearch/data --network elastic-network -e "node.name=elastic4pipelines" -e "discovery.type=single-node" -e "bootstrap.memory_lock=true" --ulimit memlock=-1:-1 -e ES_JAVA_OPTS="-Xms2g -Xmx2g" docker.elastic.co/elasticsearch/elasticsearch:7.5.1docker run --rm --detach --link elastic4pipelines:elasticsearch --name kibana4pipelines --network elastic-network -p 5601:5601 docker.elastic.co/kibana/kibana:7.5.1

当您运行上面的脚本并等待几分钟时,您的临时弹性堆栈应该开始运行并为我们的管道测试做好准备(Kibana 在 http://localhost:5601/ 上运行)。

用管道处理文档

为了进行测试,我们将从小处着手,创建一个管道,它将:

curl -XPUT localhost:9200/_ingest/pipeline/my_simple_pipeline \
-H "Content-Type: application/json" \
-d '{
    "processors": [
        {
            "split": {
                "field": "meta.tags",
                "separator": " ",
                "target_field": "meta.tags_parsed",
                "ignore_missing": true
            }
        },
        {
            "foreach": {
                "field": "meta.tags_parsed",
                "processor": {
                    "uppercase": {
                        "field": "_ingest._value"
                    }
                }
            }
        }
    ]
}'

现在,让我们创建一个索引,将该管道用作默认的接收管道。

curl -XPUT localhost:9200/my_index \
-H "Content-Type: application/json" \
-d '{
    "settings": {
        "index.default_pipeline": "my_simple_pipeline"
    }
}'

最后,让我们索引一个将由这个管道处理的虚拟文档。

curl -XPOST localhost:9200/my_index/_doc \
-H "Content-Type: application/json" \
-d '{
    "comment": "I liked this article on pipelines!",
    "meta": {
        "tags": "good enjoyed recommended"
    }
}'

现在我们可以看看基巴纳的文件。注意:不要忘记创建一个索引模式。我们可以看到适当的转换。

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

基于值的脚本和条件执行

不,让我们尝试两件事,为了更有效,让我们在一个处理器中同时使用这两件事:)

  • 使用if子句的条件执行(对所有处理器都是可能的)
  • 使用脚本处理器进行更复杂的处理(当预制处理器不够用时)

这两者都使用了一种简单的脚本语言(基于 Groovy)。阅读无痛指南了解更多信息。然而重要的是:

  • 可以通过ctx变量(所谓的摄取处理器上下文)在脚本中访问您处理过的文档
  • ctx 包含提取的 JSON 的映射结构(用方括号ctx['my_field']引用各个字段)
  • 您可以修改 ctx 变量的值来添加、修改或删除文档的字段

简单的例子:如果 rest 对我们的目的没有用,我们可以用它只索引原始文本的一部分(子串)。所以只要更换管道…

curl -XPUT localhost:9200/_ingest/pipeline/my_simple_pipeline \
-H "Content-Type: application/json" \
-d '{
    "processors": [
        {
            "script": {
                "source": "ctx.comment = ctx.comment.substring(0,20) + '\'' (…)'\''",
                "if": "ctx.containsKey('\''comment'\'') && ctx['\''comment'\''].length() > 20"
            }
        }
    ]
}'

…并为新文档编制索引。

curl -XPOST localhost:9200/my_index/_doc \
-H "Content-Type: application/json" \
-d '{
    "comment": "Hello, this is a message which deserves a hair cut."
}'

提取结构化字段(解析默认 NGINX 日志行格式)

如果您正在处理以某种定义明确的格式构建的数据(但不是在单个字段中提取的),您可以尝试使用剖析处理器。只需用带百分号%{my_field}的花括号描述提取的单个字段的模式。

我们可以使用这个处理器解析默认 NGINX 日志行格式(combined/main)之外的结构化字段,该格式具有以下结构。

log_format main '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';

有关 NGINX 日志的更多信息,请参见日志模块 ngx_http_log_module 的文档。我们还可以使用日期处理器提取@timestamp,因为原始值默认为非标准格式。

让我们把它放在新管道里。

curl -X PUT [localhost:9200/_ingest/pipeline/nginx_pipeline](http://localhost:9200/_ingest/pipeline/my_simple_pipeline) \
  -H 'Content-Type: application/json' \
  -d '{
    "processors": [
        {
            "dissect": {
                "field": "message",
                "pattern" : "%{remote_addr} - %{remote_user} [%{time_local}] \"%{request}\" %{status} %{body_bytes_sent} \"%{http_referer}\" \"%{http_user_agent}\" \"%{http_x_forwarded_for}\""
            }
        },
        {
            "date": {
                "field": "time_local",
                "formats": [
                    "dd/MMM/yyyy:HH:mm:ss Z"
                ],
                "timezone": "Europe/Prague"
            }
        }
    ]
}'

现在,您可以在消息字段中发布一个日志行并提取它。注意,您可以用查询字符串中的新管道覆盖索引中的默认管道。

curl -X POST localhost:9200/my_index/_doc?pipeline=nginx_pipeline \
  -H 'Content-Type: application/json' \
  -d '{
    "message": "172.17.0.1 - - [24/Dec/2019:10:09:42 +0000] \"GET / HTTP/1.1\" 200 95 \"-\" \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36\" \"-\""
}'

刷新您的索引模式,并在 Kibana 中查看一下。

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

如果你想尝试一下,只需启动 nginx docker 容器并在/var/log/nginx 中找到你的日志。

您可以对不同格式的内容使用类似的处理器,例如 CSV 处理器(从 CSV 中提取字段)、 KV 处理器(解析 key=value 对)或基于 regex 的 Grok 处理器

用另一个索引的值充实

我们要使用的最后一个东西是 Enrich 处理器,它可以用来自另一个索引的数据来丰富您的文档。酷吧!

在管道中使用它之前,有三个先决条件:

  • 您需要有我们将从中获取浓缩数据的源索引
  • 您需要定义一个丰富策略来定义源索引、匹配字段和附加字段
  • 您需要_executeenrich 策略来为该策略创建一个 enrich 索引

让我们扩展前面的例子,使用已知 IP 地址的源索引(让我们忘记我们现在运行在 localhost 上的事实:),我们将检查添加一些数据,看看 IP 是否不在潜在的黑名单上。

首先创建源索引和一个文档(注意:使用refresh查询参数来确保索引可以立即用于搜索):

curl -X POST localhost:9200/ip_source_index/_doc?refresh=wait_for \
  -H 'Content-Type: application/json' \
  -d '{
    "ip": "172.17.0.1",
    "black_listed": false,
    "user_category": "test"
}'

下一步将创建充实政策。很简单——只需链接我们的源索引(我们在上面创建的),匹配 ip 字段并列出相关字段。

curl -X PUT localhost:9200/_enrich/policy/ip-policy \
  -H 'Content-Type: application/json' \
  -d '{
    "match": {
        "indices": "ip_source_index",
        "match_field": "ip",
        "enrich_fields": ["black_listed", "user_category"]
    }
}'

我们需要执行它来创建 enrich 索引。

curl -X POST [localhost:9200/_enrich/policy/ip-policy/_execute](http://localhost:9200/_enrich/policy/ip-policy/_execute)

现在我们终于可以将 Enrich 处理器添加到我们之前的 nginx 管道中了。我们需要引用 enrich 策略、我们将匹配的字段(我们在上一步中提取的 remote_addr)、enrich 数据的目标字段和 max_matches(要包含的最大匹配文档数)。将以下内容添加到处理器中…

{
    "enrich" : {
        "policy_name": "ip-policy",
        "field" : "remote_addr",
        "target_field": "meta.ip",
        "max_matches": "1"
    }
}

现在只需(重新)发布之前的文档(使用相同的 nginx 日志行)并提取日志内容,然后从我们的“ip info”索引中丰富日志内容。

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

不错!

“生产”建议

最后,我想向您介绍摄取管道的其他概念和功能,当您想在实际场景中开始使用管道时,这些概念和功能与它们结合使用是非常有用的。

与索引模板一起使用

如果您旋转索引(在处理时间序列数据时,您可能应该这样做,大小在几十 GB 以上,等等。)如果您通过索引生命周期管理(我倾向于这样做)实现了这些自动化,那么更值得推荐的是利用索引模板。这些有助于将从索引模板创建的所有索引的配置(设置和映射)形式化。

从管道角度来看,您可以在设置中指定:

  • index.default_pipeline 如果请求中没有直接指定其他管道,则默认应用该管道(如果有,则默认被覆盖)。
  • index.final_pipeline 默认管道或请求管道之后每次运行的管道。

在包含它们之前,请确保您的管道存在,否则您的请求将会失败。

管道模拟

通过 _simulate API 来测试这些无疑是有用的(当你已经准备好管道并且需要执行一些改变的时候)。您可以在请求体中指定新的管道定义以及几个测试文档,并像处理这些文档一样获得结果。

POST /_ingest/pipeline/_simulate
{
    "pipeline": {
        "processors": [
            ...
        ]
    },
    "docs": [
        {
            "_index": "index",
            "_id": "id",
            "_source": {
                // your doc here
            }
        }
    ]
}

故障处理

确保您处理流水线执行过程中发生的最终故障。通过在特定处理器级别或作为一个整体的流水线级别定义on_failure块(由一些其他处理器组成)来实现。

将有问题的文档传递到不同的索引。

{
    "processors": [ … ],
    "on_failure": [
        {
            "set": {
                "field": "_index",
                "value": "failed-{{ _index }}"
            }
        }
    ]
}

空值的处理

对于需要条件执行的情况(即只有在字段存在的情况下),确保在引用的字段丢失或具有无效值时处理这些情况。你可以通过一些处理器提供的ignore_missing属性(转换、重命名、删除……)或者在if块中实现。

"if": "ctx.containsKey('foo') && ctx['foo'].containsKey('bar')"

重新索引

通常,当您发现接收管道时,您的现有索引中已经有大量数据。要让新的 shiny 管道处理这些数据,只需创建一个新的索引,并使用 reindex API 来复制数据。若要处理数据,请在索引设置或 reindex 请求正文中指定管道。

POST /_reindex
{
    "source": {
        "index": "source-index-*"
    },
    "dest": {
        "index": "destination-index",
        "pipeline": "my_pipeline"
    }
}

注意:用 ILM 重新索引时要更加小心。

好了

我们研究了接收管道的各种特性,并进行了测试。希望你喜欢这个介绍,你可以在你的场景中看到一些潜力。

从脚本到预测 API

原文:https://towardsdatascience.com/from-scripts-to-prediction-api-2372c95fb7c7?source=collection_archive---------32-----------------------

submission.csv?不用了,谢谢!

这是我上一篇文章的延续:

从 Jupyter 笔记本到脚本

上次我们讨论了如何将 Jupyter Notebook 转换成脚本,以及各种基本的工程实践,如 CI、单元测试、包环境、配置、日志记录等

即使是脚本形式,它仍然需要我们更改配置并运行脚本,这对于 Kaggle 比赛来说是可以的,因为你所需要的只是 submission.csv ,但是你可能不想全天候坐在计算机后面,每当用户向你发送预测请求时就点击运行🙁

在本文中,我们将讨论如何利用我们上次构建的模型,并使用 FastAPI 创建预测 API 来提供模型服务!

对于 ML/DL 的乡亲们,我们说的是 FastAPI ,不是 fast.ai !!!

背景:FastAPI

Python 生态系统中有很多针对 API 的框架,我最初的想法是用 Flask。但是我对 FastAPI 的简单和直观印象深刻,并且喜欢在这个迷你项目中尝试它!

“冰冻三尺,非一日之寒”,FastAPI 从 Django、Flask、APIStar 等之前的框架中学到了很多,我无法比创作者本人更好的解释这篇文章太棒了!

无聊但必要的设置

东西都在 one repo 这大概不是一个好的做法,应该是真实用例中不同的 GitHub repo,可能我以后会重构【专业的说法“清理我以前的 sxxt”】!

CS 的人总是说单一责任原则*,而不是说“不要把不同功能的代码放在一起”,下次也许你可以说“我们应该遵循单一责任原则!”

首先,让我们用新的包更新 requirements.txt,正如我们上次提到的,我们应该指定确切的版本,这样其他人就可以复制这个作品了!

# for last article
pytest==6.0.1
pandas==1.0.1
Click==7.0
scikit-learn==0.22.1
black==19.10b0
isort==4.3.21
PyYAML==5.2# for FastAPI
fastapi==0.61.0
uvicorn==0.11.8
chardet==3.0.4

在这之后,我们需要在 conda env 中再次安装 requirements.txt 因为我们有了新的包]

*# You can skip the line below if you have created conda env*
conda create - name YOU_CHANGE_THIS python=3.7 -yconda activate YOU_CHANGE_THISpip install –r requirements.txt

游戏计划

让我们想想发生了什么,我们希望有 API 端点来做预测,具体来说,如果用户给 us 输入,我们需要使用模型来预测并返回预测。

我们没有让us【human】处理传入的请求,而是创建一个 API 服务器来等待请求、解析输入、进行预测并返回结果。API 只是与我们的计算机对话并请求服务的结构化方式[在这种情况下是预测]

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

高层正在发生什么

下面是伪代码:

*# Load trained model*
trained_model = load_model(model_path)*# Let's create a API that can receive user request*
api = CreateAPI()*# If user send us the request to `predict` endpoint*
when user sends request to `api`.`predict`:
    input = api[`predict`].get(input) # get input
    prediction = trained_model(input) # apply model
    return prediction                 # return prediction

这对快乐流有好处!但是我们应该永远不要相信用户,问问你自己,你会在日常生活中阅读用户手册吗?

例如,我们期望从用户那里得到{‘a’: 1,’ b’: 2,’ c’: 3},但是我们可能得到:

  • 顺序错误{‘b’: 2,’ a’: 1,’ c’: 3},或
  • 错误的键{‘a’: 1,’ b’: 2,’ d’: 3},或者
  • 缺少密钥{‘a’: 1,’ b’: 2},或者
  • 负值{‘a’: -1,’ b’: 2,’ c’: 3},或
  • 错误的类型{ ’ a ‘:’ HELLO WORLD ‘,’ b’: 2,’ c’: 3},或者
  • 等等等等

这对我们的 API 是致命的,因为我们的模型不知道如何对此做出响应。我们需要引入一些输入结构来保护我们!因此,我们应该更新我们的伪代码!

**# Define input schema
input_schema = {......}***# Load trained model*
trained_model = load_model(model_path)*# Let's create a API that can receive user request*
api = CreateAPI()*# If user send us the request to `predict` endpoint*
when user sends request to `api`.`predict`:
    input = api[`predict`].get(input) # get input **transformed_input = apply(input_schema, input)
    if not transformed_input.valid(): return Error**    prediction = trained_model(**transformed_input**) # apply model
    return prediction                 # return prediction

代码

我现在觉得不错!让我们用 FastAPI 一部分一部分地翻译它们吧!

输入模式

看起来有很多行,但事情是一样的,正如你所猜测的,我们定义了一个名为“Sample”的类,它将每个预测器定义为 float大于[gt] zero!

负载模型

然后我们加载训练好的模型,嗯嗯什么是‘预测器’?它只是一个用不同方法包装模型的定制类,因此我们可以调用一个方法,而不是在 API 服务器中实现逻辑

创建一个 API 服务器

然后我们使用 FastAPI 创建 API 伪代码几乎已经是代码了

预测终点

这看起来很复杂,但是非常简单

不是说*“当用户向‘API’发送请求时。‘predict’”*

我们说:“嘿,app,如果有人发送"GET请求"为了预测',请运行函数 predict_item,我们期望输入遵循我们在示例`中定义的模式”

predict_item 所做的只是转换输入形状,馈送给训练好的模型并返回预测,简单的 Python 函数

如果你想了解更多关于 HTTP 请求方法

但是你可能会问:哎!少了一行!!!输入验证在哪里?如果用户提供了错误的数据类型/键或者遗漏了一个字段,该怎么办?

嗯……还记得我们已经为输入模式定义了“Sample”类吗?快速 API 自动根据模式为我们验证它,我们不需要关心这个!!!这为构建一个健壮的、经过良好测试的 API 节省了大量的脑力和代码!

尝试使用

# At project root, we can run this
# --reload is for development, API server autorefresh
# when you change the codeuvicorn prediction_api.main:app --reload

你应该能看到这些,API 服务器现在运行在“http://127.0.0.1:8000”上!

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

根据您的环境,有不同的方法来试验 API,您可以在 Python 中使用请求,在命令行中使用cURL。 BTW 有一个好用的工具叫做邮差,试试吧,这是一个非常直观和人性化的 API 工具!

我们将在下面的例子中使用 Python 请求,你可以在这本笔记本中看到它们【有时 Jupyter 是有帮助的😎]

下面的例子使用了一个有效的输入:耶!😍我们成功了!端点返回预测!!!

payload = {
    "fixed_acidity": 10.5,
    "volatile_acidity": 0.51,
    "citric_acid": 0.64,
    "residual_sugar": 2.4,
    "chlorides": 0.107,
    "free_sulfur_dioxide": 6.0,
    "total_sulfur_dioxide": 15.0,
    "density": 0.9973,
    "pH": 3.09,
    "sulphates": 0.66,
    "alcohol": 11.8,
}result = requests.get("[http://127.0.0.1:8000/predict](http://127.0.0.1:8000/predict)", data = json.dumps(payload))print(result.json())**Output**
{'prediction': 1, 'utc_ts': 1597537570, 'model': 'RandomForestClassifier'}

下面的例子遗漏了一个字段,FastAPI 帮助我们根据我们定义的模式来处理它,除了模式类,我什么也没写

payload = {
    "volatile_acidity": 0.51,
    "citric_acid": 0.64,
    "residual_sugar": 2.4,
    "chlorides": 0.107,
    "free_sulfur_dioxide": 6.0,
    "total_sulfur_dioxide": 15.0,
    "density": 0.9973,
    "pH": 3.09,
    "sulphates": 0.66,
    "alcohol": 11.8,
}result = requests.get("[http://127.0.0.1:8000/predict](http://127.0.0.1:8000/predict)", data = json.dumps(payload))print(result.json())**Output**
{'detail': [{'loc': ['body', 'fixed_acidity'], 'msg': 'field required', 'type': 'value_error.missing'}]}

只是为了好玩,我还实现了一个 update_model PUT API 来交换模型,例如,最初我们使用随机森林,我将其更新为渐变 Boosting☺️

result = requests.put("[http://127.0.0.1:8000/update_model](http://127.0.0.1:8000/update_model)")print(result.json())**Output**
{'old_model': 'RandomForestClassifier', 'new_model': 'GradientBoostingClassifier', 'utc_ts': 1597537156}

自动生成的文档

其中一个很酷的 FastAPI 特性是 auto-document,只需进入http://127 . 0 . 0 . 1:8000/docs #/即可获得开箱即用的交互式强大 API 文档!如此直观,我不需要细说

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

重访 pytest

我再怎么强调单元测试的重要性也不为过,它验证了函数正在做我们期望它们做的事情,这样你就不会不小心弄坏东西了!

但是,如果我试图涵盖每一个测试,这将是太无聊和冗长。我打算在这里分享一些我会无脑测试的领域&一些[可能有用的]文章。然后我会讲一个叫参数化单元测试的 pytest 特性,以及 pytest 中的一些测试选项。激励自己学习单元测试最简单的方法就是尝试重构你之前的代码,越大越好!

单元测试

每当你发现编写/理解单元测试有困难时,你可能需要首先回顾你的代码结构。以下是我会不假思索考虑的 4 个方面:

  1. 输入数据:dimension [eg: df.shape],type [eg: str],值域[eg: -/0/+]
  2. 输出数据:dimension [eg: df.shape],type [eg: str],取值范围[eg: -/0/+]
  3. 比较:输出和预期结果
  4. 我调试后,防止它再次发生

例如,我非常关注下面的输出维度、类型和值范围。这似乎很简单,但如果你修改任何输出格式,它会提醒你什么是预期的格式!

FYR 的一些文章:

数据科学家的单元测试

如何单元测试机器学习代码【深度学习】

参数化单元测试

假设您有 100 个模拟数据[用 D_i,i: 1 标注…100]并且你想为它们中的每一个运行相同的单元测试,你会怎么做呢?

蛮力大法

def test_d1():
    assert some_operation(D_1)def test_d2():
    assert some_operation(D_2)def test_d3():
    assert some_operation(D_3)......def test_d100():
    assert some_operation(D_100)

但是如果你需要修改“some_operation ”,你需要修改 100 次 LOL……虽然你可以把它作为一个实用函数,但这使得测试很难阅读,而且非常冗长

更好的方法也许是 for-loop?

def test_d():
    for D in [D_1, D_2, D_3, ..., D_100]:
        assert some_operation(D)

但是你不能确切地知道哪些测试失败了,因为这 100 个测试都在一个测试中

pytest 为我们提供了一个名为 参数化 的特性

[@pytest](http://twitter.com/pytest).mark.parametrize("test_object", [D_1, D_2, ..., D_100])
def test_d(test_object):
    assert some_operation(test_object)

常见 pytest 选项

pytest 文件夹

上次我们提到我们可以在命令行中运行`pytest’, pytest 会在文件夹下找到所有的测试。但是有时我们可能不想在开发过程中运行所有的单元测试[也许一些测试花费了很长时间,但是与您当前的任务无关]

在这种情况下,你可以简单地运行 pytest 文件夹,例如:` pytest。/scripts ‘或’ pytest。演示中的/prediction_api ’

并行 pytest

有时你的测试用例太重,并行运行可能是个好主意!您可以安装 pytest-xdist 并在您的命令中用 py.test 替换 pytest,例如:py.test -n 4

pytest -v

这是个人喜好,我更喜欢冗长的输出,看到绿色通过✅开始我的一天

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

pytest

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

pytest -v

您可以从以下材料中了解更多信息:

https://docs.pytest.org/en/stable/

https://www.guru99.com/pytest-tutorial.html#5

最后,我希望你能和我一样喜欢这个 1 分钟的 Youtube 视频😆

结论

Yooo✋:我们已经创建了一个使用我们模型的预测 API,用户现在可以发送请求并获得预测,而无需人工参与,这过度简化了现实[吞吐量、延迟、模型管理、身份验证、AB 测试等],但这就是我们的想法!

至少如果你的原型达到了这个水平,工程师们会更乐意接手,从而加快整个过程,你可以向他们展示你知道一些东西😈

最后,我们:

a. Update conda env [requirements.txt]
b. Brainstorm pseudocode and convert to code [FastAPI, uvicorn]
c. Utilize API [cURL, requests, Postman]
d. Talk about Auto-generated documents by FastAPI
e. Some pytest techniques [parallel, parameterized, -v]

下面的文件树显示了开发步骤

.
├── notebook
│   ├── prediction-of-quality-of-wine.ipynb
│   └── prediction_API_test.ipynb           [c] <-consume API
├── prediction_api
│   ├── __init__.py
│   ├── api_utility.py                      [b] <-wrap up methods
│   ├── main.py                             [b] <-modify demo
│   ├── mock_data.py                        [e] <-Unit test
│   ├── test_api_utility.py                 [e] <-Unit test
│   └── test_main.py                        [e] <-Unit test
├── requirements.txt                        [a] <-FastAPI doc
.
.
.

但是(还是那句话,坏消息通常以 BUT 开头)它们还在我的本地电脑上。

尽管我们不需要坐在后面点击 Run,但是用户请求不能到达 API 端点。即使他们这样做了,这也意味着我不能关闭我的 Macbook,这意味着如果有许多传入的预测请求,我就不能扩展😱!!!

正如我们在上一篇文章中提到的,逃离这个地狱的方法是,要么购买另一台计算机,要么从 AWS 等云提供商那里租用服务器

但是首先,我们还需要确保代码在那里工作正常!怎么会?

简答:Docker

旁白:

虽然我没有尝试过,但有一家名为 Cortex 的初创公司专注于开源机器学习 API 框架,他们也在幕后使用 FastAPI

到现在,你应该能理解他们的教程了,简而言之,他们在幕后解决了滚动更新、DL 模型推理、与 AWS 集成、自动缩放等许多生产层面的问题……这些都是 DevOps 关心的问题?或者用一个更好的术语: MLOps

但是从用户的角度来看,他们使用声明性的 yml 部署 APIs 类似于我们在上一篇文章中配置模型的方式],有一个预测器类[类似于我们的预测器类],trainer . py[类似于上一篇文章中的 train.py

编写代码相对容易,但是为代码写一篇文章却很难,如果你觉得这篇文章有用,你可以留下一些评论

或者你可以开始我的回购

或者我的 LinkedIn 【欢迎但请留话表示你不是僵尸】!

从 sklearn 导入*

原文:https://towardsdatascience.com/from-sklearn-import-478c711dafa1?source=collection_archive---------1-----------------------

以及其他暴露你是假数据科学家的证据

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

像大多数报道“黑客”的新闻媒体一样,虚假数据科学家乐于使用他们在网上找到的任何随机代码(图片来源: Picography

最近,似乎每个人和他们的狗都在推销自己是数据科学家——你很难责怪他们,因为“数据科学家”被评为本世纪最性感的工作,并且拿着高薪。尽管如此,我们还是会责怪他们,因为许多装腔作势的人在公司间招摇撞骗,尽管他们几乎没有实践经验,甚至更没有理论基础。在我采访和与当前和未来的数据科学家合作的经历中,我发现了一些区分装腔作势的文章和真实文章的线索。我无意贬低自学成才和有抱负的数据科学家——事实上,我认为这个领域特别适合热情的自学者——但我肯定想贬低那种参加一门在线课程,然后自称专家的人,尽管对该领域的基本理论一无所知(或不感兴趣)。我整理了这份清单,这样,如果你是一名招聘经理,不知道你在数据科学家身上寻找什么,你可以过滤掉渣渣,如果你是一名有抱负的数据科学家,并且其中任何一条引起了你的共鸣,你可以在自己变成装腔作势者之前解决它们。以下是数据科学的三大领域失言和具体的例子,它们会让你的简历被扔进垃圾箱。

1.你不用费心去探索数据

数据探索是任何机器学习项目的第一步。如果你不花时间去熟悉你的数据,并充分了解它的特性和怪癖,你将会浪费大量的时间,在得到一个可用的产品之前,错误地选择决策树——如果你真的成功了的话。

a)您没有可视化您的数据

探索性数据可视化是启动任何数据相关项目的最佳方式。如果你正在应用机器学习,很可能你正在处理大量的高维数据;仔细阅读 Excel 中的. csv 文件或运行df.describe()并不是适当的数据可视化的合适替代方法。Francis Anscombe 在他著名的四重奏中阐述了数据可视化的重要性:

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

安斯科姆的四重奏(来源:维基共享资源)

每个面板中的数据集都具有基本相同的汇总统计数据:xy 均值、 xy 样本方差、相关系数、R 平方值和最佳拟合线都(几乎)相同。如果您不可视化您的数据并依赖汇总统计数据,您可能会认为这四个数据集具有相同的分布,但粗略一看就会发现显然不是这样。

数据可视化允许您识别数据中的趋势、工件、异常值和分布;如果你跳过这一步,你也可以蒙着眼睛完成项目的其余部分。

b)您没有清理您的数据

数据是杂乱的:数值输入错误;转换出错;传感器瘫痪了。在你浪费时间在一个没有前途的项目上之前解决这些问题是很重要的,在将你的模型推向生产之前解决这些问题是非常关键的。记住:垃圾入垃圾出

有很多好的方法来识别数据中的问题,但没有好的方法来识别所有问题。数据可视化是很好的第一步(我提到过这个吗?),虽然这可能是一个繁琐的手动过程,但它的回报是很多倍的。其他方法包括自动异常检测和条件汇总统计。

例如,考虑人类身高的直方图:

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

成人身高直方图

用这些数据训练一个模型无疑会导致糟糕的结果。但是,通过检查数据,我们发现这 100 个“异常值”实际上是以米而不是厘米为单位输入身高的。这可以通过将这些值乘以 100 来校正。适当地清理数据不仅可以防止模型被错误的数据训练,而且,在这种情况下,让我们挽救 100 个数据点,否则它们可能会被丢弃。如果您没有适当地清理您的数据,最好的情况是将钱留在桌子上,最坏的情况是构建一个有缺陷的模型。

c)您不必为功能选择和工程设计费心

神经网络的一个很酷的事情是,你可以经常把你所有的原始数据扔给它,它会学习你的目标函数的一些近似值。不好意思,错别字,我指的是其中的 最坏的 事情。当然,这很方便,但是效率低而且脆弱。最糟糕的是,这使得初学数据的科学家依赖深度学习,而通常情况下,更传统的机器学习方法可能更合适,这让他们慢慢陷入困境。进行功能选择和工程设计没有“正确”的方法,但有几个关键的结果值得努力:

  • 降维:数据越多并不总是越好。通常,您希望在拟合模型之前减少特征的数量。这通常涉及删除不相关和冗余的数据,或将多个相关字段合并成一个字段。
  • 数据格式化:电脑是哑巴。你需要把你的数据转换成你的模型容易理解的格式:神经网络喜欢-1 到 1 之间的数字;分类数据应该是一次性编码的;有序数据(可能)不应该表示为单个浮点字段;对指数分布数据进行对数变换可能是有益的。简单地说,在数据格式化中有许多依赖于模型的细微差别。
  • **创建特定领域的特性:**从数据中创建自己的特性通常很有成效。如果您有计数数据,您可能希望将其转换为相关的二进制阈值字段,如"≥100" vs " < 100 “,或” is 0" vs "is not 0 "。如果您有连续的数据 xz ,您可能希望在您的特征集中包含字段 xxzz 以及 xz 。这是一个高度依赖于问题的实践,但是如果做得好,可以极大地提高某些类型模型的性能。

大多数外行人认为机器学习就是从原始数据中神奇地产生结果的黑盒;请不要助长这种误解。

2:您没有选择合适的型号

机器学习是一个有着丰富历史的广阔领域,在那段历史的大部分时间里,它被称为“统计学习”。随着 Scikit-Learn 和 TensorFlow 等易于使用的开源机器学习工具的出现,结合我们现在收集的海量数据和无处不在的快速计算机,使用不同的 ML 模型类型进行实验从未如此简单。然而,这并不是一个巧合,取消 ML 从业者实际上理解不同模型类型如何工作的要求导致许多 ML 从业者不理解不同模型类型如何工作。

a)你什么都试了

有抱负的数据科学家的 github repos 上散落着 Kaggle 项目和在线课程作业,看起来像这样:

from sklearn import *
for m in [SGDClassifier, LogisticRegression, KNeighborsClassifier,  
             KMeans, KNeighborsClassifier, RandomForestClassifier]:
    m.overfit(X_train, y_train)

这是一个明显的信号,表明你不明白自己在做什么,而且这么多在线课程推荐这种做法,这是一个该死的耻辱。这是浪费时间,并且容易导致选择不合适的模型类型,因为它们碰巧在验证数据上工作良好(您记得持有验证集,对吗?对吗?)。应该根据底层数据和应用程序的需求来选择所使用的模型类型,并且应该对数据进行设计以匹配所选择的模型。选择模型类型是数据科学过程中的一个重要部分,在几个合适的模型之间进行直接比较可能是有保证的,但盲目地应用每一种工具来寻找“最佳数字”是一个主要的危险信号。特别是,这掩盖了一个潜在的问题,即…

b)你实际上并不了解不同的模型类型是如何工作的

如果您的输入是“车龄”和“行驶公里数”,为什么 KNN 分类器可能不太好用?应用线性回归预测全球人口增长有什么问题?为什么我的随机森林分类器不能在我的数据集上使用 1000 类一热编码变量?如果你回答不了那些问题,没关系!有很多很好的资源可以学习这些技术是如何工作的;在你申请这个领域的工作之前,一定要阅读并理解它们*。*

这里更大的问题不是人们不知道不同的 ML 模型是如何工作的,而是他们不关心并且对底层的数学不感兴趣。如果你喜欢机器学习但不喜欢数学,那你不是真的喜欢机器学习;你看上什么你就看上什么 觉得 那就是。如果你不关心学习模型是如何工作的,或者是否适合数据,那么当它们不可避免地出错时,你就没有希望解决它们。当…时,问题只会加剧

c)你不知道你想要的是准确性还是可解释性,也不知道为什么你必须做出选择

所有模型类型都有其优点和缺点。机器学习中的一个重要权衡是准确性和可解释性之间的权衡。你可以有一个预测能力很差但很容易理解并能有效解释过程的模型,你可以有一个非常准确但其内部运作是个谜的黑匣子,或者你可以在中间的某个地方着陆。

您选择哪种类型的模型应该根据这两个特征中哪一个对您的应用更重要来决定。如果目的是对数据建模并获得可操作的见解,那么一个可解释的模型,如决策树或线性回归,是显而易见的选择。如果应用程序是生产级别的预测,如图像注释,那么可解释性就不如准确性,随机森林或神经网络可能更合适。

以我的经验来看,不理解这种权衡的数据科学家,以及不考虑为什么可解释性很重要而一味追求准确性的人,都不是你想要的那种训练模型。

3:你没有使用有效的度量和控制

尽管构成了 50%的单词和 64%的字母,但数据科学的“科学”部分经常被忽略。对于 poser 数据科学家来说,盲目地在真空中应用单一指标作为他们的模型评估并不罕见。不知情的利益相关者很容易被像“90%的准确率”这样的大胆断言所震惊,这些断言在技术上是正确的,但是对于手头的任务来说却是非常不合适的。

a)您没有建立基线模型

我有一个胰腺癌测试,准确率超过 99%。不可思议吧。嗯,这是真的,你可以点击这个链接自己试试。

如果你看到一个红色圆圈,中间有一条线穿过,你的测试结果是阴性。如果你看到一个绿色的对勾,你在撒谎。关键是,99%的人没有胰腺癌(实际上,更多,但为了这个例子,让我们假设是 99%),所以我的愚蠢的小“测试”在 99%的时候是准确的。因此,如果准确性是我们所关心的,任何用于诊断胰腺癌的机器学习模型都应该至少像这个无信息的基线模型一样执行**。如果你刚从大学聘用的能人声称他开发了一个准确率高达 95%的工具,将这些结果与基线模型进行比较,确保他的模型比随机模型表现得更好。**

b)您使用了错误的度量标准

继续上面的诊断示例,确保使用正确的度量标准很重要。对于癌症诊断,准确性实际上是一个糟糕的指标;如果降低准确度意味着灵敏度的提高,那么降低准确度通常是更好的选择。假阳性的代价是什么?病人的压力,以及浪费的时间和资源。假阴性的代价是什么?死亡。理解你的模型在现实世界中的含义,并理解这些含义如何支配指标选择,可以清楚地将真正的数据科学家与他们的脚本小子相似者区分开来。

你搞砸了训练/测试

这是一个大问题,而且太普遍了。正确测试模型对于数据科学过程来说是绝对必要的。这可能会在很多方面出错:不理解验证和测试数据之间的差异,在拆分之前执行数据扩充,不堵塞数据泄漏,完全忽略数据拆分……除了如果您不知道或不关心如何创建一个合适的维持集,您的所有工作都是浪费时间。

…将张量流作为 tf 导入

这些只是少数放弃游戏的告诉。有了足够的经验,他们很容易被发现,但如果你刚刚开始在这个领域工作,你可能很难区分世界上的 Siraj Ravals 和 Andrew Ngs。现在,我并不是说要把这个领域留给有抱负的数据科学家;如果你觉得被以上任何一个例子攻击,我很高兴听到它,因为这意味着你关心把事情做好。继续学习,继续攀登,这样你也可以被人山人海的装腔作势者无休止地折磨。

从懒鬼到数据科学家

原文:https://towardsdatascience.com/from-slacker-to-data-scientist-b4f34aa10ea1?source=collection_archive---------24-----------------------

数据科学/职业

我的无学位数据科学之旅。

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

Clem Onojeghuo 在 Unsplash 拍摄的照片

我肚子里的蝴蝶;我的胃打结了。我知道分享我的故事是在冒险,但我想接触到其他渴望成为数据科学家的人。我写这些是希望我的故事能鼓励和激励你。至少,希望你的旅程不会像我一样漫长。

所以,全速前进。

我没有博士学位。见鬼,我连什么学位都没有可言。尽管如此,我还是非常幸运地在一家好得离谱的公司担任数据科学家。

我是怎么做到的?提示:我得到了很多帮助。

永远不要让学校教育干扰你的教育——格兰特·艾伦

形成性格时期

那是 1995 年,我刚刚拥有了我的第一台电脑。这是 1982 年的苹果谎言。它没有附带任何软件,但有一本手册。我就是这样学会了我的第一门计算机语言:Apple BASIC。

我对编程的热爱由此而生。

在代数课上,我记得学过二次方程。那时我有一个便宜的图形计算器,卡西欧,价格大约是 TI-82 的一半。它还附带了一个手册,所以我决定写一个程序,可以毫不费力地为我解二次方程。

我对解决问题的热爱由此而生。

在我高三的时候,我的父母对经济资助一无所知,但我决心要上大学,所以我决定加入海军,这样我就可以用 MGIB 支付我的大学费用。毕竟,四年的服务似乎没那么长。

我对冒险的热爱由此而生。

后来在我的海军生涯中,我被提升为船上的财务经理。我负责管理多项预算。这段经历教会了我记账。

我对数字的热爱由此而生。

从海军退役后,我结束了在一家非营利机构的志愿服务。他们最终招募了我,让我从零开始启动一个家庭暴力危机项目。我没有社会工作经验,但我还是同意了。

我喜欢说“为什么不呢?”诞生了。

谷底

在成功的几年后,我的老板退休了,新老板解雇了我。我崩溃了。我陷入了临床抑郁症的深度状态,觉得自己一文不值。

我记得在厨房的桌子上哭得很大声。离开非营利工作已经一年多了,我还没有找到下一份工作的前景。我在一个非常黑暗的空间里。

谢天谢地,哭泣是一次宣泄的经历。它给了我一个震动,让我做一些反省,停止抱怨,并提出一个计划。

“选择一份你热爱的工作,你这辈子就一天都不用工作了。”—匿名

坠入爱河,从头再来

为了支付账单,我一直在做自由网页设计师/开发者,但我并不快乐。坦白地说,做网页设计的工作让我很无聊。与那些思维和行为都像设计专家的客户一起工作令人沮丧。

所以我开始想,“下一步是什么?”。

在网上搜索时,我偶然发现了人工智能的最新消息。它引导我走向机器学习,这反过来又引导我走向数据科学的主题。

我被迷住了。

我在 Coursera 上注册了吴恩达的机器学习课程。我听了 TwitML,线性题外话,还有其他几个播客。我重温了 Python,在 Github 上重新认识了 git。

我恋爱了。

就在这个时候,我有意识地决定成为一名数据科学家。

信念的飞跃

学习新事物对我来说很有趣。但是,我脑海中仍然有一个声音告诉我,无论我学习多少,我永远也找不到工作,因为我没有学位。

所以,我认真地看了看镜子,承认我需要帮助。现在的问题是从哪里开始寻找。

然后突然有一天,女朋友问我什么是数据科学。我跳了起来,马上开始解释。一旦我停止解释喘口气,我设法问她为什么问。就在那时,她告诉我她在广告牌上看到了一个标志。我们开车出去兜风,亲眼看到了那个标志。这是一个奇怪的广告牌,上面有两个大字“数据科学”,还有一个较小的写着“Codeup”。我上了他们的网站,研究了他们的就业结果

我被卖了。

准备

上课前,我们拿到了一份要复习的材料清单。

鉴于我只有大约两个月的准备时间,我并不指望能完成这些课程。我基本上被告知只是浏览一下内容。不管怎样,我还是做了。我日以继夜地复习课程和材料。做了测试,拿到了证书!

训练营

新兵训练营一片模糊。我们在海军有一句关于新兵训练营经历的谚语:“日子过得很慢,但几周过得很快。”对于 Codeup 新兵训练营来说也是如此。

Codeup 被描述为“完全沉浸式的、基于项目的 18 周数据科学职业加速器,为学生提供 600 多个小时的应用数据科学专家指导。学生在整个数据科学管道(规划、获取、准备、探索、建模、交付)中发展专业知识,并适应处理真实、杂乱的数据,以便向不同的利益相关方提供可操作的见解。”

我们用 Python 编码,查询 SQL 数据库,用 Tableau 制作仪表盘。我们做了一个又一个项目。我们学习了不同的方法,如回归、分类、聚类、时间序列、异常检测、自然语言处理和分布式机器学习。

更重要的是,这次经历教会了我们以下几点:

  1. 真实数据杂乱无章;处理好它。
  2. 如果你不能和你的利益相关者沟通,你就没用。
  3. 记录您的代码。
  4. 阅读文档。
  5. 永远学习。

求职

我们的求职过程从新兵训练营的第一天就开始了。我们更新了我们的 LinkedIn 个人资料,并确保我们几乎每天都在推送 Github。我甚至美化了我的个人网站,把我们在课堂上做过的项目包括进来。当然,我们确保了简历的良好状态。

Codeup 帮助我解决了所有这些问题。

此外,Codeup 还帮助我们为技术和行为面试做准备。我们按照 S.T.A.R .格式(情境、任务、行动、结果)练习答题。我们优化了我们的答案,以突出我们作为高潜力候选人的优势。

毕业后

我的教育甚至在毕业后还在继续。在填写应用程序的间隙,我会每天编写代码,尝试不同的 Python 库。我定期阅读新闻,了解机器学习的最新进展。做家务的时候,我会听播客、ted 演讲或 LinkedIn 学习视频。无聊的时候,我就听书或者看书。

有很多好的技术书籍可供阅读。但是对于非技术性的,我推荐如下:

  • 用数据思考
  • 数学毁灭的武器:大数据如何增加不平等并威胁民主
  • 《看不见的女人:为男人设计的世界中的数据偏差》
  • 菜鸟智慧:为什么在工作的新游戏中学习胜过了解
  • 《勇气:激情和毅力的力量》,安吉拉·杜克沃斯著
  • 第一个 90 天:迈克尔·沃特金斯证明的更快更聪明地达到目标的策略

处理拒绝

我被拒绝了很多次。第一个是最难的,但之后,它变得越来越容易。我脸皮厚了,继续生活。

被拒绝了。尽量不要往心里去。没有人喜欢失败,但它会发生。当它出现时,失败。

结论

我从新兵训练营毕业后花了 3 个月才找到工作。付出了很多牺牲。当我最终得到这份工作时,我感到非常感激、宽慰和兴奋。

没有 Codeup 和家人的支持,我不可能做到这一点。

感谢阅读!我希望你从这篇文章中有所收获。

所有有抱负的数据科学家,不要放弃。尽量不要听信外面所有的仇恨者。如果必须的话,听听他们要说什么,评估一下你的弱点,并渴望比昨天学得更好。但是永远不要让他们打击你。请记住,数据科学技能取决于光谱。如果你有热情和毅力,我很确定有一家公司或组织非常适合你。

如果你正在考虑开始数据科学家的职业生涯,请查看下面的文章:

[## 懒鬼将自己重塑为数据科学家指南

给我们其他人的固执己见的建议。热爱数学,选修。

towardsdatascience.com](/the-slackers-guide-to-rebranding-yourself-as-a-data-scientist-b34424d45540)

敬请期待!

你可以通过推特LinkedIn 联系我。

[1] Codeup 校友门户。(2020 年 5 月 31 日)。简历——埃德纳林·c·德迪奥斯https://alumni.codeup.com/uploads/699-1562875657.pdf

从流数据到新冠肺炎 Twitter 分析:使用 AWS Lambda、Kinesis Firehose 和 Elasticsearch

原文:https://towardsdatascience.com/from-streaming-data-to-covid-19-twitter-analysis-using-aws-lambda-kinesis-firehose-and-b71b71279335?source=collection_archive---------14-----------------------

释放 AWS 和 Elasticsearch 的力量

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

分析实时推文的仪表板。

介绍

在我之前的博文 从流数据到新冠肺炎 Twitter 分析:使用 Spark 和 AWS Kinesis 中,我涵盖了用 Spark 和 AWS Kinesis 构建的数据管道。在这篇文章中,我将采用另一种方式来达到同样的目的。

在之前的工作经历中接触过 AWS Lambda 和 Elasticsearch。Lambda 的无服务器、事件触发特性以及与其他 AWS 工具的丰富连接给我留下了深刻的印象。Elasticsearch 向我展示了系统生成的杂乱日志是如何被整齐地处理的,并且在 Kibana 上是可见的。受到这篇文章的启发: 用 AWS 构建一个接近实时的发现平台,我复制了数据管道并将其应用于 Twitter 上的新冠肺炎分析。为了尊重原创作品的版权,我不会将这个帖子货币化。

参考文章 相比,我新增内容如下:

  • 进行代码更改以与依赖项的最新版本保持一致。
  • 提供更多关于人们容易遇到的问题的细节,而这些问题在参考文章中没有涉及。
  • 遇到 Lambda 和 Elasticsearch 相关错误时如何调试?

数据管道遵循接近实时流的时尚,从消化实时 Twitter 数据到可视化。组装拼图的大部分碎片来自 AWS 家族: AWS Kinesis FirehoseAWS S3 水桶AWS Lambda亚马逊弹性搜索服务。架构是这样的:

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

数据管道的体系结构。

本文作为参考文章的补充指南,将讨论分为以下步骤:

  • IAM 设置
  • 创建亚马逊弹性搜索服务集群
  • 配置 AWS Kinesis 消防软管和 S3
  • 创建 AWS Lambda 函数
  • 代码打包和更改
  • Kibana 可视化和 Twitter 分析

Lambda 函数和 Twitter 捕获程序的代码已经上传到我的公共回购中。

IAM 设置

在构建数据管道之前,您需要有一个 AWS 帐户和 Twitter API 密钥以及访问令牌,这在参考文章的的先决条件中也有提及。除此之外,IAM 角色非常重要,必须正确设置。需要两个角色:

  • Kinesis Firehose 需要一个 IAM 角色,并被授予传送流数据的权限,这将在 Kinesis 和 S3 桶一节中讨论。
  • AWS Lambda 需要权限来访问 S3 事件触发器、添加 CloudWatch 日志以及与 Amazon Elasticserch 服务进行交互。

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

lambda 函数的 IAM 角色 lambda-s3-es-role。

如上图所示,我给 Lambda 执行角色 lambda-s3-es-role 附加了三个策略。如果您不确定如何配置策略,我将这些策略附在 repo 中以供参考。

创建亚马逊弹性搜索服务集群

我假设读者已经按照参考文章中的步骤在 Amazon ES 主页创建了一个 Amazon ES 域。对于自由层用户,他们可以选择 t2.micro 或 t2.small 等实例类型,并免费获得 750 小时的 Amazon ES 使用时间。创建 ES 域时需要注意几点:

  • 无需设置“专用主节点”。
  • 作为演示项目,我在“网络配置”中选择公共接入。

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

事情是这样的。在配置"访问策略"时,选择"客户访问策略",需要添加以下策略:

  1. 选择“ARN”,允许 lambda 执行角色 lambda-s3-es-role 访问 es 服务。

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

我在这里留下一个疑问:设置是否正确?我们稍后会测试它。

配置 AWS Kinesis 消防软管和 S3

参考文章不同,我选择在 Kinesis 消防水龙带流控制台创建一个 Kinesis 消防水龙带。步骤很简单:

  • 填写消防水带流的名称
  • 来源:直接投资或其他来源
  • 目的地:一个 S3 桶,用于存储数据文件(实际上是推文)。在这里,您可以选择一个您已经创建的 S3 桶或创建一个新的飞行。
  • 权限。

正如在 IAM 部分中提到的,一个 Firehose 流需要 IAM 角色来包含所有必要的权限。单击“新建或选择”,并选择“创建新的 IAM 角色”,或使用现有的角色。默认策略将被附加,并应满足需要。

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

Kinesis Data Firehose Stream (KDF)和 Kinesis Data Stream (KDS)有时可能会让人混淆。KDF 在传输流数据时有额外的功能。在传递到目的地的过程中,源数据可以通过 Lambda 函数进行转换。我的另一个帖子涵盖了 KDF 的用法。

创建 AWS Lambda 函数

AWS Lambda 在这个管道中起着核心作用。我们将创建一个 Lambda 函数来完成以下工作:

  • 一旦在目标 S3 桶中创建了新的数据文件,Lambda 函数就会被触发。
  • 数据将使用指定的结构进行解析,这与文档的映射一致。
  • 数据将被加载到 ES 集群中。

一下子实现这样一个 Lambda 函数很难。将繁琐的过程分成更小的步骤,我首先需要正确设置 Lambda 环境。

AWS Lambda 主页创建功能:

  • 选择 Python 3.7 运行时。
  • 选择 lambda-s3-es-role 作为执行角色*。*
  • 将内存保持在 128 MB,并将超时设置为 2 分钟。
  • 为 S3 添加一个触发器。如果任何新文件进入 S3 桶,Lambda 函数将接收事件并被调用。

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

为 Lambda 函数创建一个 S3 触发器,注意前缀“debug”用于调试,可以根据需要替换。

现在,我们可以测试 Lambda 函数是否能对 S3 事件做出反应。使用示例代码和配置好的处理程序,我们将一个文件放入 S3 桶 twitter-stream-sink。

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

创建一个 Lambda 函数,并将一个测试文件放入 S3 桶中。请注意,处理程序名称应该与函数代码中的入口函数相匹配。

在 Lambda function 面板的“Monitoring”选项卡上,有一个点出现在指标图上。单击“查看 CloudWatch 中的日志”,我们得到了这次调用的 CloudWatch 日志,该日志打印了我们刚刚放入的源 S3 桶和文件名。

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

左侧窗口显示了度量图中的一个点,表示对 Lambda 函数的调用。右侧窗口显示了 CloudWatch 日志的详细信息。

代码打包和更改

参考文章是几年前发表的,所以项目代码需要更新。

项目代码可以从 repo 下载。代码目录包含 4 个 python 文件: config.pymyhandle.pytweet_utils.pytwitter_to_es.py 。要将必要的库添加到项目文件夹中,只需键入命令:

pip install library_name -t .

导入到项目目录所需的库如下:

requests
requests_aws4auth
elasticsearch
textblob=0.15

Lambda 函数接受 zip 格式的代码包。将代码目录与库打包需要以下命令:

zip -r ../your_package_name.zip * -x "*.git*"

关于 Lambda 部署包的教程可以在 AWS Lambda 文档中找到。

现在让我们看一下每个 python 文件:

myhandle.py

  • 充当 Lambda 函数的入口点。
  • 解析事件信息,获取 JSON 格式的 S3 文件内容。

twitter_to_es.py

  • 向 es 集群添加索引和映射。
  • 采用 bulk 方式将解析后的数据加载到 ES 集群中。
  • 授权发送到 ES 集群的请求。

tweet_utils.py

  • 充当助手模块。
  • 将推文解析到结构化字典中。
  • 使用 TextBlob 分析推特上的情绪。

配置. py

  • 充当共享配置。

参考文章中的原代码相比,我做了一些代码改动:

  1. 将额外的库添加到包 requests_aws4auth,requests 中。

2.将源代码从 Python 2 移植到 Python 3。

3.修复错误,因为 Elasticsearch 及其 Python 客户端库与以前的版本不兼容。

为了将源代码从 Python 2 移植到 3,我们可以使用库2to3

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

使用 2to3 命令将 Python 2 代码移植到 Python 3 的例子。

不兼容问题已修复:

为了熟悉 Elasticsearch 的 Python 客户端,你可以打开一个 Jupiter 笔记本来测试与 ES 集群的连接。

研究完代码后,我们需要打包代码。为了测试 Lambda 函数,我们将一个捕获的 twitter 文件放入 S3 桶,并查看 tweets 是否被正确解析并加载到 e S 集群中。

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

左边的窗口显示了 Lambda 函数的面板,右边的窗口显示了将带有 tweets 的样本数据文件放入 S3。

如果数据成功加载到 ES 集群中,我们可以使用 Kibana 的“Discover”功能来检查它。

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

左侧窗口显示调用 Lambda 函数期间的跟踪日志,右侧窗口显示加载到 es 中的 tweets。

除了 Lambda 函数上的代码变化,我使用一个运行在 AWS EC2 实例上的 Python 程序来捕获 tweets,可以在这里找到。参考文章包含一个 node.js 程序来捕捉推文,它们都做同样的工作。

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

运行 Python tweet 捕获程序

这里要注意一点。当我实现管道并尝试将数据加载到 ES 集群时,我在 Lambda 调用和 Kibana 上遇到了身份验证错误:

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

当我将一个数据文件放入 S3 桶时,Lambda 函数报告了这样一个错误。

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

当我在设置了 ES 集群后试图访问 Kibana 时。

为了找出原因,我们需要去指定 Amazon ES 的身份和访问管理的页面。

基于 IP 的策略的主要吸引力在于,它们允许对 Amazon ES 域的未签名请求,这允许您使用像 curlKibana 这样的客户端,或者通过代理服务器访问域。

所有对 Amazon ES 配置 API 的请求都必须签名。在上面的错误中,即使添加了 Lambda 执行角色,请求还是未签名并被拒绝,尤其是 HTTP 请求。为了解决这个问题,我们可以添加基于 IP 的策略,或者使用 AWS SDK 或请求添加标志。因此,我们需要将基于 IP 的策略添加到 ES 访问策略中:

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

Kibana 可视化和 Twitter 分析

一旦我们开始运行 twitter 捕获程序,大量的推文将被传入 S3,Lambda 函数将处理数据文件。反映数据的最佳方式是通过 Elasticsearch 中提供的可视化工具 Kibana

加载到 Elasticsearch 中的所有数据都需要分配索引,因此 Kibana 可以使用索引模式来检索数据。在 twitter_to_es.py 中,推文用“twitter”做索引。现在我们可以创建一个索引模式“twitter*”,并开始在 Kibana 中发现数据。

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

创建索引模式“twitter*”,以匹配所有以“twitter”开头的索引。

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

当我们在 tweet_utils.py 中添加映射时,会指定“timestamp_ms”字段。

创建索引模式后,我们可以通过选择左侧栏上的“Discover”按钮来浏览数据,数据可以按时间序列显示。

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

在这篇文章中,我选择了标签“ #StayHome ”和“# social distance”来挖掘 Twitter。像参考文章一样,我创建了一个仪表板来可视化推文。仪表板中有三种可视化效果:

  • 一张坐标地图,展示推文的地理分布,仅当推文包含位置信息时有效。
  • 一个饼图,展示用户发送推文时的情绪受欢迎程度,包括积极、中性和消极三种情绪。
  • 一个数据表,统计每个情绪中包含的表情符号,只列出前 5 个表情符号。

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

在基巴纳创建的仪表板。

结论

AWS Lambda 和 Elasticsearch 是非常强大的技术,这篇文章可能只是展示了应用场景中的一个案例。除了实时数据处理,Lambda 还可以与 ETL(提取、转换、加载)和应用后端集成。Elasticsearch 在日志记录/日志分析和全文搜索方面已经建立了声誉。

我希望你在阅读和摆弄大数据技术时能够找到乐趣。这就是大数据让我着迷的地方。

编者注: 走向数据科学 是一份以数据科学和机器学习研究为主的中型刊物。我们不是健康专家或流行病学家,本文的观点不应被解释为专业建议。想了解更多关于疫情冠状病毒的信息,可以点击 这里

从细流到赫罗库

原文:https://towardsdatascience.com/from-streamlit-to-heroku-62a655b7319?source=collection_archive---------16-----------------------

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

马特·霍华德Unsplash 上拍照

如何主持你的项目的简单指南?

注意这个指南是针对 Heroku 上的主机的,如果你想在 AWS 实例上主机,请查看我的朋友 Marco 的 Streamlit to AWS 指南这里!

大家好,本周我将一步一步地介绍如何将您的 streamlit 项目从笔记本电脑转移到在线服务器上。对于这个例子,我将使用我的 Yelp 评论应用程序来指导您。

我们开始吧,好吗?假设我们已经在本地安装并运行了我们的 streamlit 应用程序,但是我们希望在我们的家庭环境之外安装它。在你的 Jupyter 笔记本上应该是这样的:

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

现在,如你所知,为了让你的 Streamlit 应用程序启动并运行,你必须把它放到一个. py 文件中,以便 Streamlit 在本地运行它,Heroku 也是如此。因此,我们将点击“文件”和“下载为…”一个 python 文件。

为 Heroku 做准备

Heroku 为开发者提供了一个在云上运行和操作平台的平台。它不仅提供托管服务,还为你的应用程序提供了一个易于构建的虚拟环境。因此,我们需要给 Heroku 准备一堆指令来启动和运行它。

对我来说,开始时最好的事情是把我的前端和项目的其他部分分开,因为我们要做一些翻找和创建文件的工作,我不想让这些文件混淆。首先,Heroku 需要一些文件来给它必要的指令,以使虚拟环境运行起来。下面是我的文件树的样子,列出了必要的文件:

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

Procfile

现在,app.py 就是您在。py 格式。下一个文件, Procfile 是一个声明启动时要运行什么命令的文件。它没有特殊的扩展名,只是简单地命名为 Procfile。要创建它,只需打开 Jupyter 笔记本上的应用程序,点击右上角的“新建”按钮,然后选择“文本文件”

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

这将创建一个没有特殊附件的空白文档。打开它,输入以下代码:

web: sh setup.sh && streamlit run app.py

您会注意到代码的后半部分包含运行我们的应用程序的 streamlit 命令。

requirements.txt

现在,我们将对 requirements.txt 做同样的事情。Requirements.txt 向 Heroku 提供了关于库的说明,这是我们运行应用程序所需要的。这实质上是定义您在设置虚拟环境时需要的东西。在我的 *requirements.txt,*我正在输入以下内容:

streamlit==0.49.0
numpy==1.17.3

通过这种方式,我让 Heroku 知道这个应用程序需要这个版本的 Streamlit 和那个版本的 Numpy。这并不是说 Heroku 手头没有它,但这允许我修正我想要的版本,而不必担心一些新的更新会破坏我的代码。

setup.sh

编辑:来自 的反馈 Samudrala Sai kiran mayee表示 setup.sh 全部小写以避免问题很重要。

转到 setup.sh ,我们将按照创建上两个文件的相同方式创建文件,在 Jupyter Notebook 中创建一个新的 txt 文件。顺便说一下,不要忘记用适当的扩展名来重命名您的文件。与 requirements.txt 一样,s etup.sh 有助于为我们的 streamlit 应用程序的运行创建必要的环境。我们将在 s etup.sh 中输入以下命令:

mkdir -p ~/.streamlit/echo “\
[general]\n\
email = \”[your-email@domain.com](mailto:your-email@domain.com)\”\n\
“ > ~/.streamlit/credentials.tomlecho “\
[server]\n\
headless = true\n\
enableCORS=false\n\
port = $PORT\n\
“ > ~/.streamlit/config.toml

如果你愿意,可以把电子邮件改成你自己的。如果没有,不要担心,它仍然会运行良好。

与 Heroku 互动

现在我们已经安排好了所有的事情,是时候准备和 Heroku 接触了。有一个 git 方法,但是我更喜欢使用 Heroku 的 CLI(命令行界面),因为它可以减少混乱。你可以在这里安装 Heroku 的 CLI 。注意,你还需要在你的电脑上安装某种形式的 Github。Heroku 与 Github 携手合作,我还没有看到一个部署选项在某种程度上不需要 Git。我个人用 Github 桌面。

登录 Heroku

Heroku 的 CLI 允许您从家庭终端直接与 Heroku 交互。打开终端,用 CD 找到你的应用程序的根目录。在那里,输入以下命令:

$ heroku login

这将触发一个新的网络浏览器,您可以在其中输入 Heroku 的登录信息。输入您的登录信息并点击登录,当网站通知您已登录时,您就可以关闭浏览器了。

创建一个 Heroku 实例

接下来,我们通过键入以下命令指示 Heroku 创建一个 Heroku 实例:

$ heroku create

Heroku 会自动运行并给你的应用分配一个随机的名字,我们稍后会更改它的名字。

将你的文件载入 Heroku

接下来,我们将把所有文件传送到 heroku 实例中。因为 heroku 使用 Git,所以这个过程应该很熟悉:

$ git push heroku master

现在请记住,我们仍然应该在你的应用程序的前端根目录,所以它会把所有的东西都转移到 Heroku。记住这一点很重要,因为稍后我们将讨论在您做出更改时更新 Heroku 上的应用程序。

运行您的应用

最后,我们将启动并运行我们的应用程序。输入以下内容:

$ heroku ps:scale web=1
$ heroku open

第一个命令告诉 Heroku 启动一个 dyno (Heroku 对虚拟机实例的术语)。PS 是 Heroku 影响 dynos 的许多命令的前缀。 Scale web=1 告诉 Heroku 加速 1 dyno,根据你的服务器流量,你可以告诉它加速更多。这整个命令基本上启动了你的应用程序。

最后一个命令将弹出你选择的浏览器,并把你带到应用程序。您会注意到网址是自动生成的实例名加上 heroku。

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

更改应用程序的名称

要改变这一点,我们必须去我们的 heroku 仪表板。在你的浏览器中,进入 Heroku.com。前往您的仪表盘,点击您的应用程序。

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

你现在应该在你的应用程序的“概述”页面。点击设置。

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

“设置”是一个非常明显的工作页面,您应该可以在这里看到更改应用程序名称的选项:

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

更新您的 Git 远程路径

请记住,更改名称将要求您在进行任何更新之前更新 git remotes。这里的给出了这样做的指示

最后,在我们结束之前,如果您已经在本地更新了您的应用程序,并且想要更新您的应用程序,您需要做的就是单击“部署”

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

向下滚动 deploy 页面,您会看到一些有用的 git 命令,帮助您根据需要克隆或更新 heroku 实例。

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

这就对了。您的应用程序应该已经启动并运行,希望用户已经准备好了!我希望这个指南对你有所帮助。还有许多其他有用的 streamlit 到 Heroku 指南,但更多的例子总是更好。祝你好运,并享受构建应用的乐趣!

从桥梁到任务规划:用 Python、R 和 Tableau 构建 Gannt 图表

原文:https://towardsdatascience.com/from-the-bridge-to-tasks-planning-build-gannt-chart-in-python-r-and-tableau-7256fb7615f8?source=collection_archive---------18-----------------------

史诗图表

使用基本的 DataViz 工具创建项目进度可视化

前一段时间我有一个想法,有很多关于条形图,直方图,散点图,折线图和其他有效但非常简单和普通的数据可视化工具的信息。我甚至可以假设,对于每个数据科学家或 DataViz 专家来说,如何构建这些通用图表的知识必须被视为基本和必须的。但是有各种各样的情节和想象。它们不太常见,更具体,但肯定应该在你的清单中。更重要的是,你还必须熟悉一些现代工具来制作这样的图表。这就是我如何想出“史诗图表”系列的想法,你现在看到的是它的第一期。

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

桥梁施工(1912)甘特图示例,Schürch,1916。参考自《亨利·甘特工作回顾》(2012)

我的“史诗图表”系列的第一期是献给甘特图。这是进度可视化的一个例子。它的经典实现显示了项目中任务的周期:水平线包含任务(或阶段),垂直线包含日期或时间范围,甚至简单的周期计数。因此,每个任务都显示为一个固定长度的条形图,占据了一些时间线(或几个时间线)。现代版本还可以包括关于紧急程度、阶段之间的关系以及阶段之间的转换的附加数据。

1.很少的历史评论

这张图表最早由凯罗尔·阿达米耶茨基于 1896 年创建,亨利·甘特在他的作品《工作工资和利润》中对其进行了详细描述,其中也包含了他早期的出版物。甘特图及其可视化的首次应用出现在 1912 年 Hermann Schürch 的出版物中。实际上,这是封面上的一张图表。Gannt 开发了几种进度图的变体(例如,见下面的一个),但是 Schürch 给出了我们一直使用到今天的形式。

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

“奖金图表”信息来自甘特的“工作工资和利润”(1916)。参考自《亨利·甘特工作回顾》(2012)

你可以在当时的资料中找到更多信息——“甘特图,一种管理的工作工具” (1922),以及在现代研究中——“亨利·l·甘特,1861–1919。回顾他的作品《T8》(2012)。史实到此为止,我们去实施吧。

2.Python 中的甘特图

我们将使用我创建的测试示例。它是简单的项目模拟,包括几个阶段、一些同时进行的任务和一些可重复的任务。

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

我们将从众所周知的matplotlib库开始。因为这是每个数据科学家都知道的基本知识,所以不需要介绍。所以,一点日期操作和情节是准备好的:

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

在另一个例子中,我们将使用Plotly库——另一个著名的包。它有一个强大的交互式可视化引擎和许多内置的图表类型。包括甘特一号!

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

3.R 中的甘特图

R community 开发了许多绘图库,包括一些交互式图表。当然,它们在可视化风格、交互性和绘图参数的语法方面有所不同,但是图表原理是相同的。因为没有选择哪个库的问题,我将创建两个例子。

首先,我将用最著名的图书馆纯ggplot2制作一个甘特图。我们将使用相同的数据,做一些准备,这就是:

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

第二个例子使用[plotrix](https://cran.r-project.org/web/packages/plotrix/plotrix.pdf) ——独立绘图库之一。因为它集合了很多功能,所以代码更短,结果“更漂亮”。

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

当然,你可以自由选择其他的图书馆。

4.表格中的甘特图

我已经用 Python 比较了 Tableau 和自定义绘图。我发现 Tableau 是一个非常好的工具,可以让你看到美丽的画面。它的库存很大,可以生成几乎任何类型的图表。包括甘特图!

算法非常简单:

  • 加载数据;
  • 使用图表的默认线条类型;
  • 使用公式创建计算字段持续时间:
    DATEDIFF(‘day’,[Start.Date],[End.Date])
  • 拖放开始。日字段添加到列中;
  • 将名称字段拖放到行中;
  • 更改任务名称的排序选项:按“字段”排序,升序,使用[Start.Date]变量,按最小值聚合;
  • 将以前创建的持续时间字段拖到“大小”选项中;
  • 拖放是。颜色选项的关键字段;
  • 做一些美化。

瞧,图表准备好了:

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

今天到此为止。敬请关注下一期的“史诗排行榜”。而且,和我的文章一样,您可能会在我的 GitHub 上找到工作示例:

[## 中级/中等 _jupyter_notes

此时您不能执行该操作。您已使用另一个标签页或窗口登录。您已在另一个选项卡中注销,或者…

github.com](https://github.com/Midvel/medium_jupyter_notes/tree/master/epic_gantt_chart)

另外,请不要错过我的关于用 Python 再现 Tableau 可视化的文章:

[## Python dataviz 库可以重复 Tableau 工作表吗?

我对 Tableau 用法及其与 Python 代码的比较的第一印象

towardsdatascience.com](/can-python-dataviz-libraries-repeat-the-tableau-worksheet-e38ef2876f04)

从生物学家的角度来看

原文:https://towardsdatascience.com/from-the-perspective-of-a-biologist-85e68cac84a0?source=collection_archive---------55-----------------------

生物学家如何在数据革命中导航

这是我的第一篇媒体文章。首先,我想简单介绍一下我自己。我目前在加拿大阿尔伯塔大学学习分子、细胞和发育生物学,重点是生物信息学。我以前对计算机科学毫无背景。事实上,我现在正在大学二年级上我的第一堂计算机科学课。

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

国家癌症研究所Unsplash 上拍摄的照片

像大多数生物学家一样,我也缺乏计算机科学技能,也不擅长数学。我第一年上过微积分课,绩点 1.3。是的……但是这并不能准确的描述我的数学能力。那是大学第一年。我讨厌教授把大部分话题搞得过于复杂(我在高中接触微积分的前一年就自学了这些概念,并被它的优雅所折服),嗯,我只是太鲁莽了。退一步说,这只是你大学第一学期的常规课程,你要尝试很多新的经验,微积分真的不是你的首要任务。我想这是合理的,因为你大学的第一学期是为有点鲁莽而准备的,因为你以后不能再这样了,或者至少我是这么认为的。

无论如何,我第一次探索编程是在疫情飓风来袭,我无处可去的时候。近一年来,我一直在窥视编程和生物信息学的整个领域,但从未真正有足够的动力去认真对待它。每次我尝试的时候,即使是设置 Python 和 IDE 的过程对我来说也是极其可怕的,不可避免地,我会立刻放弃。现在疫情将我关在里面,周围没有朋友或家人(那是大学的第一个暑假,我是一名国际学生,因为 Covid,我所有的朋友都回了家),没有其他事情可做,我有足够的时间来玩这个我想了很久的新东西。所以我就一头扎进去了。

我打开 YouTube,搜索“python 教程”。Python 只是我想到的第一种语言。我很幸运找到了完美的教程。这个教程真正让我印象深刻的是,老师是如何让概念变得真正相关和简化,而不是过于简单。

并不是我只跟着这个教程就精通 Python 了。事实上,直到今天,我只看了视频的前 60%左右。但这足以让我在 Python 的上下文中了解编程语言的基本思想。过了一段时间,我还看了一些基本的 Java 教程,其中一个特别适合我,这进一步使我理解了计算机语言,尤其是面向对象编程语言是如何根据它们的语法和结构创建的。

除了阅读本教程,我还寻找了有效学习编程语言的方法。作为一名程序员和一名独立学习者,其中一些技巧对我的发展非常重要。为了熟悉一个概念,我会看无数的其他视频。

每次我遇到一个新的概念,我都会在 YouTube 上看一些关于它的视频,这在开始时很有效。我会从各种不同的 YouTubers 上观看相同概念的视频,只是为了从不同的角度理解它们。这给了我很大的帮助,因为如果一个老师不能足够清楚地解释这个主题,或者以一种适合我的方式解释,我会准备另一个。这都是关于尝试和错误,看看谁最适合我的学习风格。

后来,当我学到更复杂的概念时,我不得不用笔记本记下我理解的内容。并不是说我以后会看这些笔记。在学习新东西后,从我的脑海中提取概念,用我自己的话写下来的行为足以将它们嵌入我的记忆中,至少在几周内。当然,随着时间的推移,这变得越来越容易。

我进行的另一个重要实践是在整个学习过程中混合使用自上而下和自下而上的方法。事实上,直到今天我还在学习。自下而上的方法是首先学习基础知识,然后学习稍微复杂一点的概念,最后应用这些概念。自顶向下是当你选择一个特定的应用或用例,然后尝试学习理解这个特定的概念或用例所需要的一切。我决定长期采用自下而上的方法,短期采用自上而下的方法。我来详细说明一下。我从相对简单的概念开始,如循环、数据类型、变量等。,然后慢慢上升到更复杂的概念。这个挺标准的。但是我所做的与众不同的是,我使用了特定的用例来试图理解它所需要的一切。

随着时间的推移,我对用例的选择变得越来越复杂,因为我遵循了长期的自底向上的策略。例如,我最初在生物学的背景下测试并应用了我从第一个教程中学到的东西,这个教程是在罗莎琳德网站上找到的。这是我最初感兴趣的地方;使用现代计算工具回答生物学问题。由于这些问题对我有限的知识来说太复杂了,我继续前进,决定创建一个以新冠肺炎为主题的太空入侵者游戏。我使用 Pygame 遵循了一个普通的太空入侵者教程,但是加入了我自己的修改,把它变成了一个新冠肺炎主题游戏。这很有趣,有共鸣,最重要的是,鉴于我当时的技能水平,我对这一点相当满意,可以应用我最初学到的基础知识,但当我完成它时,也有足够的机会教我新概念。在选择用例或项目时,取得这种平衡可能是独立学习最重要的部分。

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

作者创建的图像。目的是在病毒到达底部的关键工人之前,使用注射液滴(挤压空间)杀死病毒。 GitHub

快进到今天,我现在精通许多 Python 数据科学库,自学机器学习,使用来自 Kaggle 的数据集,如新冠肺炎研究数据集或 FIFA 19 数据集,类似地结合了自下而上和自上而下的方法。我绝不是数据科学甚至编程方面的专家。我和你一样,是一名数据科学爱好者,试图利用互联网上的大量开源信息自学这个迷人的领域,坦率地说,这些信息有时会让人不知所措。但是到目前为止,我觉得我做得挺好的,如果我能做到,你也能。把我当成你的学习伙伴,而不是专家。我喜欢写和谈论我感兴趣的事情,这次媒介之旅对我来说只是一个创造性的出口,在那里我结合了我对生物学、数据科学和编程的热情。请关注我的更多文章,学习如何自学这些知识。

数据革命将在不久的将来改变许多基本的生活方式,我对它了解得越多,就越喜欢它。如果你想让我谈论它的任何特定方面,请在评论中告诉我。我喜欢开门见山,这可能是我所有文章的一贯特点。快乐学习!

附言:要获得更多关于数据科学、编程以及生物学家如何在数据革命中导航的简明扼要的文章,可以考虑关注我的博客

由于每分钟都有成千上万的视频被上传,所以过滤掉它们是很重要的,这样你就可以只使用高质量的数据。我亲自挑选的,我会把你感兴趣的主题的教育视频发邮件给你。报名这里

感谢您的阅读!

从理论物理学家到数据科学家

原文:https://towardsdatascience.com/from-theoretical-physicist-to-data-scientist-d8b781462c9?source=collection_archive---------14-----------------------

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

我如何成为一名拥有理论物理博士学位的数据科学家

有很多人解释他们如何成为数据科学家的故事,但我发现当我进行转换时,很难找到一个符合我个人资料的故事。这就是为什么我想分享我的旅程,以防它可以激励其他人经历同样的事情。一年多前(2018 年秋季),我决定从事数据科学职业,现在我是加拿大 Décathlon 的一名数据科学家,所以我实现了我的目标。我将描述我的旅程作为一个例子,但这并不意味着作为建议。我不是找工作的专家。

我的背景

我没有从事数据科学的人的典型背景,我指的是计算机科学或某种工程学位。我在蒙特利尔大学完成了数学和物理的本科学习,然后去了麦吉尔大学完成了理论物理的硕士和博士学位。在这些学位期间,我主要学习了高等数学以及如何利用它们解决问题。我主要做理论工作,但也做一点科学编程。我还积极参与组织每周的讲座和阅读课程,去小学和孩子们一起做科学活动,并志愿参加会议和活动。

在我博士学位快结束的时候,我开始考虑用我的学位能找到什么样的工作。我得告诉你,直接涉及理论物理的工作非常难找。他们中的大多数都在大学,他们需要至少一名博士后,所以我把他们排除了。我想过找一份教书的工作(在塞 GEP,给知道那是什么的人),但我想找一份更有挑战性的工作。引起我注意的一个话题是人工智能。

学习人工智能

当然,人工智能现在是一个大趋势,作为一个住在蒙特利尔的学生,我听到了更多关于它的事情。我花了很多时间在网上试图了解在数据科学领域找到工作的要求,发现每个人都建议在 Coursera 上学习吴恩达的机器学习课程。我听从了这个建议,发现这个课程非常棒,我从中学到了很多东西。然而,在完成它之后,我觉得我对人工智能的理论方面有了很好的理解,特别是从我的角度来看,它是基于简单的数学,但我不知道如何实现它。这就是为什么我在 Udemy 上参加了数据科学和机器学习训练营的 Python。我学习了 python、numpy、pandas 和 scikit-learn,以便实际进行机器学习。

我经常在网上读到的下一个建议是,专注于通过个人项目学习,并在 Github 和你的简历中展示它们。这是我在参加网络课程后的几个月里所做的事情。你可以在这里看到我的第一个项目。在做这些事情的时候,我总是在网上看招聘信息,看看有什么工作机会,他们需要什么技能,我认为最重要的是深度学习。这让我参加了 Coursera 上的深度学习专业,我发现这非常有趣,并给了我新的个人项目的多个想法。

第一轮求职申请

当然,我要说明的是,这些都是我还在读博的时候兼职做的。上面提到的步骤花了我大约 6 个月的时间来完成我作为博士生的常规任务。我实际上有一点点额外的空闲时间,因为研究人员的任务之一是保持最新的新研究成果,为未来的项目做准备,但我快要毕业了,所以我不必这样做。我还有额外一年的奖学金,所以我不用急着找工作,所以我慢慢来。

大约在我完成深度学习专业化的时候,我开始申请提到我所拥有的技能的工作和实习。没有多少,但我仍然设法得到了实习和几份工作的面试机会。这些职位是为像我这样有良好科学背景和一些人工智能经验的人准备的。即使我很兴奋,我认为这有点为时过早,我是对的,因为我没有得到位置。

打磨我的技能

然后,我决定在开始认真申请工作之前,把重点放在增加技能和经验上。2019 年夏天,我的情况很好,我仍然有资金,但我的论文几乎完成了。然后我就可以集中精力找工作,并在工作完成后提交论文。我也考虑过在获得博士学位后留在麦吉尔大学进行 Mitacs 实习的选择,这是一个由一位教授和一家公司共同完成的研究项目。

我没有提到的一个细节是,我和人们交谈。我发现我周围和 linkedIn 上的人已经做了我想做的事情,我向他们征求建议。我通过电子邮件与他们中的一些人交谈,并与一些人一起喝咖啡,我收到了非常好的建议。

因为我有更多的时间学习新的东西,所以我看书(尤其是这本)和看很多 Youtube 视频(sentdex 的频道非常鼓舞人心)。我开发了像这个语言标识符这样更复杂的项目,并写了关于我的项目的博文(见我的简介)。我终于花了一些时间学习数据科学工作所需的更实际的技能,如 SQL、git、linux 和 flask。

毕竟,我对只申请我感兴趣的工作很有信心。我仍然对研究和商业工作感兴趣,所以我两个都找了。我每天都在寻找新的职位,并附上个性化的求职信。一些人回来找我,我设法得到了加拿大 Décathlon 的面试机会,我现在在那里从事计算机视觉和数据驱动项目的混合工作。我在开始工作前完成了论文,在开始论文答辩几个月后,我请了一周的假。

对感兴趣的人来说,这是我用来获得目前工作的简历:

从变形金刚到表演者:近似注意力

原文:https://towardsdatascience.com/from-transformers-to-performers-approximating-attention-69c88af0b11f?source=collection_archive---------9-----------------------

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

作者图片

加速变压器的数学技巧

几周前,来自谷歌、剑桥大学、DeepMind 和艾伦图灵研究所的研究人员发布了论文反思表演者的注意力,该论文旨在寻找解决变形金刚中 softmax 瓶颈问题的解决方案[1]。他们的方法利用了一个聪明的数学技巧,我将在本文中解释。

先决条件:

  • 变压器的一些知识
  • 核函数

涵盖话题:

  • 为什么是变形金刚?
  • 变压器的问题是
  • 绕过 softmax 瓶颈

为什么是变形金刚?

从本质上讲,Transformer 是一个设计用来高效处理顺序数据的模型,实际上它在自然语言处理(NLP)任务中被大量使用,这些任务需要处理单词/字母序列。与其他顺序模型不同,transformer 利用注意力机制来并行处理顺序数据(即:不需要一次处理一个单词/输入)[2]。

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

作者图片

如果你不熟悉变形金刚,我推荐你阅读注意力是你所需要的全部——2017 年介绍它们的论文,非常容易理解——或者图解变形金刚以获得对初学者更友好的介绍。[3][4]

变压器的问题是

变形金刚基于注意力,计算如下:

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

其中 Q,K,V (维度 L x d )是查询、键和值矩阵, L 是序列的长度, d 是查询、键和值向量的(任意)维度。

注意:如果你不知道这是从哪里来的,我强烈推荐阅读前面提到的文章(注意力是你所需要的全部),尽管对于本文的目的来说,并不严格需要知道什么是查询、键和值,以及为什么注意力是这样计算的(或者它是什么)。

transformer 的问题来自 softmax 函数,让我们看看为什么。

注意的时间复杂性

提醒一下,两个维数为 n x mm x p 的矩阵相乘的时间复杂度为 O( nmp )。

如果我们看一下注意力的等式,我们会看到我们在乘以三个矩阵: Q (维度为 L x d )、k^t(dxl,以及v(lxd)。我们会得到不同的复杂度,取决于我们相乘的顺序。
暂且忽略 softmax 和分母 sqrt(d)(它只是一个标量),我们可以看到,通过乘以 Q K ^T 我们首先获得复杂度 O( L d ),而如果我们乘以 K ^T V 我们首先获得复杂度
O( d L )。

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

作者图片

我们更喜欢 O( d L ),因为 d 是我们可以选择的参数,通常我们可以有 d < L 。然而,我们实际上不能按照这个顺序执行乘法,因为 Q K ^T 被“卡”在了 softmax 里面,没有简单的方法把它取出来。这意味着我们不得不处理 O( L d )的时间复杂度,这是序列长度的二次方(因此处理更长的序列在计算上变得越来越昂贵)。
所以,softmax 是变形金刚的瓶颈,我们想找到一种方法来解决这个问题。

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

作者图片

绕过 softmax 瓶颈

从高层次来看,本文提出的方法非常简单。我们能否找到一种方法来近似 softmax,以允许我们选择矩阵的计算顺序?

本质上,我们能找到一些矩阵**Q’K’**使得

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

目标很容易理解,但是如何实现的细节有点复杂。

首先,让我们回忆一下,softmax 是一个函数,它给定一个长度为 n 的向量 z ,将所有元素归一化为:

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

鉴于此,请注意,我们可以将注意力等式中的 softmax 改写为:

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

其中 A 中的指数是按元素应用的, 1 _L 是长度为 L 的全 1 向量, D 是具有元素 A1 _L 的对角矩阵。 D 给出了 softmax 的分母(实际上, A1 _L 只是通过对的列求和而获得的长度为 L 的向量)

A ,它的元素指数,是这里真正的问题,所以我们的目标是以某种方式分解它。我们可以忽略标量分母 sqrt(d ),因为这只是用于规范化,但我们可以等效地规范化查询和键。这意味着我们的目标是找到一些**Q’K’**使得:

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

通过高斯核寻找 Softmax 核

这就是内核发挥作用的地方。我们知道核是等价于某个特征映射φ的点积的函数:

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

通常,给定某个高维特征图φ,我们感兴趣的是找到一个等价函数 K,它将允许我们避免在φ的高维空间中进行计算。然而,在我们的例子中,我们实际上要走相反的路:如果我们假设 A 是一个包含元素 A ( i,j)=k(q_ I,k_ j)= exp(q _ I k_j^t)(其中 q_ik

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

现在,大多数核可以用以下形式的特征图来近似

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

其中 hf₁,…,f_l 是一些确定性函数, w₁,…,w_m 是从分布 D 中抽取的随机值(所以φ( x 是一个具有 l x m 元素的向量)。【5】

一篇以前的论文已经证明我们可以通过使用配置获得高斯核:

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

也就是说,如果我们从均值为 0 且单位方差的正态分布中画出 w ,我们可以通过使用特征图获得高斯核:

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

注意,具有单位方差的高斯核由下式给出:

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

现在请记住,我们希望找到一个 softmax 内核:

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

我们可以看到 Softmax 核的结构与高斯核相差不远。事实证明,我们可以利用这种相似性找到 softmax 内核。事实上,请注意

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

这意味着我们实际上可以将 softmax 内核重写为

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

并且我们可以通过将 h 函数从 h ( x ) = 1 改为:

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

这是一个不错的近似值,但它有一些问题。softmax 函数总是输出正值,所以 A 的所有元素都应该是正的。然而,使用这个内核来近似 softmax 可能会给出一些负值。事实上,由于我们是从均值为 0 的正态分布中抽取 w ,这些值中的一些将是负的,这反过来意味着 A 的一些值将是负的。这会导致问题和异常行为。

寻找更稳定的 Softmax 内核

研究人员发现,softmax 内核也可以重写为:

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

(这实际上是 softmax 内核的证明可以在论文的附录中找到。)

因此,我们可以简单地从前面的功能图形式,并设置

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

通过这样做,我们可以看到所有的值都是正的,因为我们使用了 exp,因此解决了我们之前的问题。

作者还建议了另一个导致相同内核的特性图,如果你感兴趣,我推荐你阅读这篇论文。

使用 softmax 内核查找 Q '和 V ’

让我们回顾一下。我们从注意力等式开始

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

发现我们可以把它改写成

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

然后我们找到了 softmax 内核的特性图,我们可以用它来近似矩阵 A :

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

所以我们现在可以使用特征映射替换 A 中的元素:

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

注意,我们是从长度为 L 的向量 q_k 移动到长度为 m 的向量φ( q _i)和φ( k _j)。

我们现在可以分解 Q’K’ 中的 A ,其中 Q’K’ 的元素为φ( q _i)和φ( k _j)。最后,我们可以自由地改变矩阵乘法的顺序,并将时间复杂度从 O( L d )降低到 O( Lmd ),从而获得序列长度的线性复杂度,而不是二次复杂度。

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

作者图片

我们完了。

结论和一些结束语

本质上,在本文中,作者设法找到了一种使用特征图的点积来近似 softmax 函数的方法。由于这一点,在变压器中计算注意力的时间复杂度可以从序列长度的平方减少到线性。在处理长序列时,这将显著提高转换器的速度。

需要注意一些有趣的事情:

  • 虽然这种方法是在考虑变形器的情况下开发的,但它实际上可以应用于任何需要 softmax 的模型。看看这在哪里会变得有用将会很有趣。
  • 作者指出,这种方法不仅速度更快,而且内存效率更高。这可以通过查看需要存储的矩阵的维数来看出。

参考

[1] Choromanski 等人《与表演者重新思考注意力》,2020 年 9 月 30 日
【2】Jay alam mar。《可视化一个神经机器翻译模型(带注意力的 Seq2seq 模型的力学)》,2018 年 5 月 9 日
【3】瓦斯瓦尼等人《注意力就是你所需要的一切》,2017 年 12 月 6 日
【4】杰伊·阿拉姆马。《图解变压器》,2018 年 6 月 27 日
【5】刘等,“核逼近的随机特征:算法、理论及超越的综述”,2020 年 7 月 4 日

觉得这个故事有帮助?考虑 订阅 到媒体扶持写手!

从。txt 文件到 d3.js 可视化

原文:https://towardsdatascience.com/from-txt-file-to-d3-js-visualization-7070ef7af837?source=collection_archive---------21-----------------------

使用数据科学技术读取、清理非结构化数据,并将其转换为引人入胜的 web 可视化

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

照片由兰迪·法特Unsplash 上拍摄

几年前,IBM 指出,作为一名数据科学家,你可能必须经常遵守“80/20 法则”——你 80%的时间将用于简单地查找、清理和组织数据,只留下 20%的时间用于实际执行分析。

作为一名数据科学研究生,我的第一门课程只关注最初的 80%。有一项任务特别需要清理下面的文本文件,其中包含虚构国际象棋选手的“elo 评级”以及虚构国际象棋锦标赛的分数和点数:

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

模拟国际象棋“elo”评分和点数

太残忍了!我把这个文件的底部剪了下来,因为它很长,但是总共有 64 个玩家。

现在,你可能在想,我们能用这个做什么?这里有什么有趣的信息吗?我们将使用以下工作流程进行调查:

工作流程

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

从文本文件到 d3.js 可视化

将文本文件读入 R

我们要做的第一件事是。txt 文件并将其拉入 R。为此,我们可以使用基本的 R 函数paste()readLines():

library(stringr)
library(knitr)chess_data <- paste(readLines("https://raw.githubusercontent.com/zachalexander/data607_cunysps/master/Project1/chess_ratings.txt"), collapse = '\n')

正如您将从链接中看到的,我将文本文件保存在一个新的 GitHub 存储库中,并访问“Raw”选项,以便提取正确的文件。此外,我已经加载了用于处理文本的stringr()knitr()包。

使用正则表达式处理文本文件

尽管我已经将文本文件放入 R 中,但是如果我检查我的变量“chess_data”并将其打印到控制台,您将会看到数据根本没有格式化:

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

将原始文本文件放入 R 中之后——处理之前。

幸运的是,如果您仔细观察,在这个文件中有一些微妙的模式,我们可以用它们通过正则表达式解析出关键信息。如果你需要温习正则表达式,我推荐这个资源。

首先,如果能得到玩家的名字就太好了。为此,我们可以结合使用str_extract_all()函数和定制的正则表达式来隔离这些数据。我们可以看到球员的名字全部用大写字母列出,因此,我们可以通过运行以下语法提取他们:

player_names <- unlist(str_extract_all(chess_data, '([:upper:]+\\s[:upper:]+(\\s[:upper:]+)?(\\s[:upper:]+)?)'))# change to 'proper' case
player_names <- str_to_title(player_names)
head(player_names)

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

在上面语法的第二部分,我简单地将所有大写字母的名字转换成“正确的”形式。你可以看到印在上面控制台上的最终产品。我们现在有 64 个玩家名字的向量!就这么简单!

查看原始文本文件,我认为将玩家的原籍州、每个玩家的赛前 elo 评级以及每个玩家的赛后 elo 评级分离出来会很有趣。下面的正则表达式解决了这个问题:

# found that each player's state could be extracted through this regular expression combination
location <- unlist(str_extract_all(chess_data, '(\n)\\s\\s\\s[:upper:]+'))
location <- unlist(str_replace_all(location, '^\\s+|\\s+$', ""))# found that each player's pre-rating could be extracted through this regular expression combination
pre_rating <- unlist(str_extract_all(chess_data, '(R:)\\s{1,}\\d+'))
pre_rating <- unlist(str_replace_all(pre_rating, '(R:)\\s', ""))# found that each player's post-rating could be extracted through this regular expression combination (used later in data visualization)
post_rating <- unlist(str_extract_all(chess_data, '(->)(\\s{1,})?\\d+'))
post_rating <- unlist(str_replace_all(post_rating, '(->)(\\s)?', ""))

类似于隔离玩家名字,由于原始文本文件中的某些模式,上面的每一项都可以被隔离。

玩家结果-其他 R 函数

这些信息安全地存储在有组织的向量中。让我们评估一下我们现在所处的位置,以及我们希望收集哪些额外的信息来进行分析。下面用黄色突出显示的所有数据都已提取,用绿色突出显示的所有数据都是从该文本文件中获取的有用值——我们将在下一步中关注这些值。

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

我们目前在工作流程中的位置。

最初,我们可以看到每个玩家在锦标赛中的总点数包含带小数位的数字。为了分离这些值,我们可以根据这个字符序列提取所有值(见下文)。

然后,由于用绿色突出显示的其余数据在每一轮之间用“|”字符格式化,我们可以做一些操作来获取这些分数,继续利用我们的正则表达式。

# found that each player's total points could be extracted through this regular expression combination
total_points <- unlist(str_extract_all(chess_data, '(\\d\\.\\d)'))results <- unlist(str_extract_all(chess_data, '(\\d\\.\\d\\s{2}(\\|[:upper:]\\s{2}(\\s)?(\\s)?(\\d+)?){1,})'))
results <- unlist(str_replace(results, '\\d\\.\\d\\s{2}\\|', ''))

最后,我能够将每个玩家的这些值转换成一个临时数据帧,方法是使用 for 循环去掉多余的符号,并确保它们与我的初始向量中的玩家匹配。您可以看到下面的 for 循环过程:

*# used a for loop here to iterate over V1, using strsplit and the comma to separate out the opponent numbers into the appropriate columns. This also stored N/As in columns where a player didn't play an opponent.*
**for**(i **in** 1:7){
  tempdf[, paste0('game', i)] <- sapply(strsplit(as.character(tempdf$V1),','), "[", i)
}

将这些数据与我的球员数据结合后,我们得到以下数据帧:

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

现在我们有所进展了!

如您所见,在 game1、game2…gameN 列中找到的数据对应于索引行号。既然我们已经有了这些信息,我想用与每个球员指数相对应的赛前评分来替换这些列中的指数会很有趣。如果我这样做是正确的,我就可以确定每个玩家的“时间表强度”!为此,我再次使用了 for 循环:

*# while iterating over the game columns, iterate over the player opponent number and match it with the opponent's pre-tournament elo rating. Then replace the opponent number with their elo rating.*
**for**(i **in** 6:12) {
  **for**(j **in** 1:64) {
    value <- chess_ratings_df[,i][j]
    chess_ratings_df[,i][j] <- chess_ratings_df$player_pre_rating[value]
  }
}

我们走吧!这是我们最后的数据帧,已经清理干净,可以进行分析了:

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

包含棋手信息的最终数据帧,从锦标赛中获得的总点数,以及他们面对的每个对手的预 elo 评级。

初步分析

给定这个数据框架,我感兴趣的是仅基于对手的赛前评级来确定哪个(哪些)玩家的锦标赛赛程最艰难。此外,从赛前到赛后,谁的 elo 评分上升幅度最大?

为了弄清楚这一点,我首先使用了rowMeans()函数来计算七场锦标赛的对手赛前 elo 评分的平均值。然后我创建了一个名为average_opp_rating的新列来存储每个玩家的计算结果。

chess_ratings_df$average_opp_rating <- round(rowMeans(chess_ratings_df[,6:12], na.rm = TRUE), digits = 0)

我还决定再创建几个专栏,以确定玩家赛前评级和赛后评级的差异(最终看谁的 elo 评级收益/损失最高)。此外,我还创建了一个专栏,讨论前后的评分差异是正还是负。

最后,我开发了一个相当全面的数据框架,可以回答我的许多问题。许多人会觉得这是令人满意的,大多数情况下确实如此。然而,如果我们把它可视化不是更有吸引力吗?

将数据导出到. csv 文件

准备好数据帧后,我可以用 R 中的以下语法将其导出为. csv 文件:

filename <- './../.../filepath'
write.csv(final_df, file = filename)

对于那些熟悉 d3.js 的人来说,有一个内置函数能够读取. csv 文件并遍历其中的行。然而,我更喜欢直接与。json 文件(只是我个人的喜好)。你可以快速使用免费的在线服务,如 csvjson.com 的来转换格式。

一旦准备好了,我就有一个可行的。json 文件:

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

我的 R 数据帧先转换成. csv 文件,然后转换成. json 文件的例子

使 d3.js 可视化

由于时间的原因,我将简单介绍一下制作 d3.js 可视化的大部分内容。然而,如果你对学习感兴趣,我会推荐这本书——交互式数据可视化——这真的是开始接触 d3 和 Javascript 的好指南!

用我的。json 文件准备好了,我可以接着做下面的事情:

  1. 使用 angular-cli 创建一个角度 2+项目。
  2. 创建一个 firebase 项目,并使用 firebase 部署我的 Angular 2+项目。这是一个很好的指南。
  3. 我创建一个组件,安装必要的模块,并开始构建我的可视化!

最后,我生成了一个条形图,显示每个玩家的赛前 elo 评级,然后您可以单击一个按钮来查看他们的 elo 评级根据赛后评级的变化。您也可以将鼠标指针置于初始栏上,查看赛前评级:

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

最终 d3.js 可视化——要查看最终产品,请前往https://zach-alexander.com/chess-elo

要看到完整的、互动的可视化,你可以去 https://www.zach-alexander.com/chess-elo 的。希望你会发现它很吸引人。您还会注意到,我创建了一个与该数据相关的模拟报纸故事——只是为了好玩!

说到底,尽管大多数人抱怨“80/20 法则”,但我们可以看到它对这样的任务是多么重要。到处都有有用的数据,但前提是你愿意花时间去处理它们!

从用户到价值创造

原文:https://towardsdatascience.com/from-users-to-value-creation-bb9b14c882f8?source=collection_archive---------55-----------------------

上的数据值

数据的使用及其如何创造价值

T 何第一个“首席数据官”是在近二十年前的 2002 年被任命的(当时她还是一名女性)。从那时起,大数据革命开始了,今天首席数据官的头衔在某种程度上是公司内数据专业人员的最高荣誉。

这个新职位在公司最高管理层的出现至少意味着对数据创造价值潜力的某种认可。这种价值创造是围绕数据生产和使用的若干战略和政策以及为数据管理和治理实施的手段的结果。

在这一系列文章中,我将尝试解释这几个策略和政策的原因,以及如何将它们结合起来,以便从数据中创造商业价值。

第一部分是关于数据的价值是什么,谁使用它,用于什么目的。第二部分将关注方法,以及如何通过数据管理和分析最大限度地创造价值第三部分也是最后一部分将讨论谁做什么,以及 IT 业务团队在数据时代的角色变化&。

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

照片由 Riccardo AnnandaleUnsplash 上拍摄

从数据中创造商业价值

当你让一个人描述数据的价值是什么时,对他们来说,你会自然而然地得到的第一个答案是数据有内在的市场价值,这意味着你实际上可以以给定的价格出售它。当数据是一家公司卖给其客户的产品时,情况确实如此。

但对于我们绝大多数人来说,对于核心业务不是卖数据的公司来说,数据的这种内在市场价值,只占从中要创造的潜在商业价值的一小部分。

对于这些公司来说,数据以某种方式“间接”创造了超出其市场价值的价值,这种价值创造可以以不同的方式转化,可以分为三类:

  1. 提高客户忠诚度,通过使用数据来提高服务质量,以更好地了解客户,识别模式,预测客户流失,从而避免失去客户,实施新的高附加值数据或报告服务(此处数据或多或少会直接货币化)
  2. 增加市场份额,通过增加与现有客户和新客户的活动,利用数据更好地了解市场及其演变,预测、预测甚至影响市场,从而改变市场
  3. 降低成本,通过使用数据来优化运营、提高生产率、更好地理解和构建产品、提高效率、自动化某些活动

如果您想从业务的角度定义公司数据计划的目标,处理业务案例,评估项目投资回报,设置优先级并指导路线图,那么充分理解这一点是至关重要的。

在本文中,我将只讨论公司、产品和服务以及市场价值(直接或间接)。数据也代表了科学的巨大价值,让我们更好地了解我们生活的世界,让医学更好地了解我们自己以及如何治愈我们。但是,即使目的不同(赚钱与理解宇宙和帮助人类),与数据的生产、使用和管理相关的实践和过程是相同的。

应用程序和用户是从数据中创造价值的基础

显然,我们没有等到计算机被发明出来才开始生产数据,并利用数据创造价值。然而今天,绝大多数数据都是通过计算机应用程序生成的。

事实上,计算机应用程序本质上是生成和处理数据的系统,其中数据被输入或摄取、存储、处理、可视化、分析等。

和/或分析,从而直接或间接参与从数据中创造价值。

从应用用户到价值创造

应用程序用户除了使用软件的功能外,还对其数据进行特定的使用。这种用法要么是操作性的(do),要么是分析性的(decide),有时两者都有(实际上越来越多)。

数据的运营使用与制造产品或提供服务有关,因此会对服务质量和卓越运营、效率和生产力产生影响。让我们看一个电子商务应用程序的例子:

  • “客户-用户”的数据操作用途是访问公司提供的不同产品或服务的数据、它们的特征、它们的价格等。
  • “操作员-用户”的数据操作用途是访问客户数据以处理订单。

数据的分析用途的主要目的是报告和/或分析以理解和预测,在从业务战略到员工日常决策的决策过程中起着至关重要的作用。可以是简单的报告或商业智能,以分析销售、客户(著名的 V360),了解导致特定情况的模式,如客户流失等。

在两者之间的边界,分析也可以直接集成到运营中,在现场和实时进行。警报功能就是一个很好的例子,它监控过程并在出现问题时警告操作人员,以便他能够做出决定并采取行动。

服务质量、卓越运营和决策:价值创造的三个关键驱动因素

正确理解用户对数据的操作和/或分析使用对于正确理解相关的价值创造至关重要,因为数据的使用方式将影响这种价值创造的三个关键驱动因素:

  1. 服务质量,满足客户并满足其需求的能力 : 在这里,数据及其使用方式会对客户满意度产生积极或消极的影响。例如,如果电子商务应用程序中的库存没有正确更新,客户下了订单,认为产品有库存,但他/她的订单因为实际上缺货而无法处理,他/她将不会满意。相反,对于电子商务网站来说,提供实时的库存可见性是客户满意度的一个重要标准。
  2. 卓越运营,做好工作的能力:在这里,数据的使用方式可以通过效率和生产率来衡量。比如,当某些发货信息缺失或错误时,产品无法发货,不得不重新安排发货时间(从公司的角度来看这是效率的缺失)。
  3. 决策,在正确的时间做出正确决定的能力:这里我们主要谈论的是对数据的“分析性”使用,即利用数据中的信息,做出符合事实的东西,通过分析相关性和因果关系来更好地了解情况,预测将会发生什么,从而决定要采取的行动。

卓越运营问题不一定会影响服务质量(效率损失会增加成本,但如果满足了要求,客户会很高兴),反之亦然。然而,糟糕的服务质量将意味着某个地方更经常地存在潜在的运营卓越问题。

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

总之,如上图所示,运营商、分析师、客户等使用数据的方式。影响服务质量、卓越运营和决策,这是从数据中创造商业价值的三个关键驱动因素。因此,充分理解数据的用途为什么至关重要,这样才能最大化从中创造的相关商业价值。

感谢您的阅读,请让我知道您的想法,并毫不犹豫地分享。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值