admin管理员组

文章数量:1645532

原文:TowardsDataScience

协议:CC BY-NC-SA 4.0

如何在 2022 年成为一名自由职业数据科学家

原文:https://towardsdatascience/how-to-become-a-freelance-data-scientist-in-2022-e6ce4ea9ce23

关于建立投资组合、获得新客户和创造稳定的额外收入的建议

在 Unsplash 上由Towfiqu barb huya拍摄的照片

由于新冠肺炎疫情,如今的就业形势发生了巨大的变化。除了全职工作,人们现在还可以灵活地从事兼职工作,作为额外的收入来源。

当我进入数据科学领域时,我最初的目标是在这个行业找到一份工作。然而,一旦我找到了一份工作,我意识到我有能力做得更多。在家工作意味着我不必经常参加社交活动。我再也不用来回奔波去工作了。

这不仅节省了时间。它节省了能源。一天工作结束时,我不再疲惫不堪,这意味着我能够承担工作之外的任务。

在本文中,我将向您介绍我作为数据科学自由职业者的经历。我还将为您提供如何开始成为数据科学自由职业者的提示。

首先,让我们看看自由职业对于数据科学的利与弊。

优势

从事自由职业最大的好处是你可以和来自世界各地的人一起工作。机会是无穷无尽的,你学会从许多不同的角度看待一个问题。

你还可以选择要做的项目种类——当你有一份全职工作时,这并不总是可能的。

另外,作为全职员工,你只能在一个行业工作。当自由职业者时,你从事的每个项目都会给你提供一个新领域的领域经验。

当你在许多不同的领域从事各种各样的工作时,你的投资组合就会增长。您不会拘泥于单一的工作方式,可以快速适应新的工作流程。你的学习能力会提高。

不足之处

成为一名数据科学自由职业者没有什么坏处。首先,数据科学领域的自由职业者数量有限。

通常是大中型公司雇佣数据科学家,这些公司倾向于雇佣全职员工,而不是自由职业者。与数据科学家相比,对自由职业网站开发人员/设计师的需求更高。

自由职业也不能保证工作安全,你需要积极寻找新的任务。因此,在从事自由职业的同时保持全职工作是一个好主意,尤其是在刚开始的时候。

可用的演出类型

作为一名自由职业的数据科学家,你可以一次性为组织建立机器学习模型。有时,随着新数据的到来,您甚至可以获得报酬来持续维护和更新这个模型。

然而,您的选择不仅限于模型构建。

由于我的全职工作是在营销领域,我在这方面有一些经验。我利用这一点,以及我的数据技能,帮助客户确定他们的目标受众,并提出营销策略。

另一项非常受欢迎的技能是数据收集。我曾与个人和公司合作,收集外部数据来帮助他们的研究或模型构建任务。

我已经做了一段时间的自由职业技术作家。我为出版物撰写数据科学教程和技巧——无论是一次性的还是基于合同的。我还被要求为该行业的初学者举办数据科学培训研讨会和在线课程。

根据你的技能,你还可以承担许多其他的任务。您可以帮助组织部署和监控他们的机器学习模型。你可以咨询公司,根据你分析的数据给他们提供建议。如果您是数据可视化方面的专家,您可以基于可用数据为客户端创建交互式仪表板。

如何找到一份自由职业

当人们第一次想到成为自由职业者时,他们的思维会跳到 Fiverr 和 Upwork 这样的平台上。

然而,仅仅在这些网站上注册并发送工作建议并不足以让你得到很多工作。这些平台已经高度饱和。为了引起他们的注意,你需要先找几份工作来建立你的投资组合。

我建议先在这些平台之外创建一个投资组合。大多数雇主都在平台之外联系我——通过 LinkedIn 或电子邮件。

我的大部分自由职业都是通过博客找到的。在像 Medium 这样的平台上坚持写作之后,一些出版物曾找过我,让我成为一名技术作家。

我曾经创建了一个集群模型并创建了一个关于 Medium 的教程,之后我被一个想要为他的组织建立一个类似模型的人雇佣。

一个客户看到了我在抓取 Twitter 上的教程,并雇佣我为他建立一个网页抓取器。另一家公司雇用了我,因为我在 Medium 上发表了一篇分析,因为他们想做类似的事情来确定他们的目标受众。

由于我的关系网,我也找到了一些工作。大学的朋友和同事曾经推荐过我。

人们更喜欢在有信任的时候雇佣员工。你更有可能从与你能力相当的人那里得到一份工作,而不是从一个你刚刚向他提出建议的人那里。

如果你成为一名全职自由职业者,一个不利之处是你最终会失去这个网络。你不再有同事或经理推荐你担任职务。因此,我建议参加当地的数据科学活动或在线社区,在那里你可以与同行业的其他专家交流。

其他提示

一旦你完成了一项自由职业任务,一定要向你的客户寻求建议。推荐证明你做了令人满意的工作,并且会让未来的客户对你的产品充满信心。这增加了你再次被雇佣的机会。

像 Upwork 和 Fiverr 这样的平台通常会在每个类别的第一页展示他们评价最高的自由职业者。如果你在这些平台上工作,一封推荐信会增加你被关注的机会。这使得你更有可能再次被类似的职位聘用。

此外,确保始终为你的客户提供高质量的工作。我的许多自由职业安排都是一次性的,因为客户喜欢我的工作质量,他们决定继续和我合作。

如果你始终按时交付成果,并满足客户的期望,他们也会考虑聘用你来完成未来的任务,而不是接触其他候选人。

本文到此为止!我希望它对您有所帮助,并祝您的数据科学之旅好运。

如何成为一名机器学习工程师

原文:https://towardsdatascience/how-to-become-a-machine-learning-engineer-66bd55f17c67

如何在今年成为 ML 工程师的一步一步的指导

作者创造的形象,人就是作者

人工智能工程的世界在召唤你,这正是我们今天要讨论的,如何在 2022 年成为一名机器学习工程师。我是桑德罗,我作为一名 ML 工程师已经工作了大约一年,同时也从事其他数据工作。如果你像我一样曾经计划从你的大学生活过渡到 ML 工程世界,或者从一份不同的工作进入这个令人兴奋的领域并得到你的第一份工作,这篇文章是给你的。

我将向您介绍如果我今天重新开始我会采取的步骤,以及我将关注的具体内容,然后给你一个大概的时间估计,告诉你应该在每个领域关注多长时间,这样你就可以在一年中逐步提高自己的技能。最后,我们会给出很多具体的建议,告诉你如何将这些技能转化为工作机会,以及在哪里可以学到这些技能。

硬技能

我把这篇文章分成 7 部分,第一部分是学习正确的技能。老实说,要成为一名 ML 工程师,你需要知道很多不同的东西,但实际的硬技能,即你将需要转换数据、训练模型以及最重要的将其投入生产的实际技能是必不可少的,其他的大多是很好知道的。这些硬技能定义了你,没有它们你真的找不到一份 ML 工程师的工作。

我认为你的技能集是一个机器学习管道,你必须在日常生活中建立、维护并不断改进。

ML 管道的简化源文章

现在,什么是机器学习管道,它是一个计算机软件,首先从数据源中提取数据,然后将其转换为预测或训练模型,最后部署这个模型,以便其他人可以通过各种数据输入全天候使用它。现在,如果我们后退一步,开始识别所有这些框所共有的最重要的技能,这是第一个技能,即成为一名优秀的软件工程师,这实际上是 ML 工程师的一半。如果你是计算机科学出身,那么恭喜你已经有 50%的成功了。如果不是,我们会马上研究如何建立那套技能。编程、数据结构、算法和计算机体系结构将影响你所做的一切。能够用 80%的 Python 写干净的结构良好的代码,

KDnuggets 软件杆来源

从文件中读取、记录日志、构建 API、编写转换函数,对于您所做的一切都是非常有用的技能。当然,在这个领域中还有很多其他的编程语言,比如 Java 和 C++,但是 Python 显然是大多数 ML 和数据工作的主导语言。因此,软件工程显然是你应该关注的第一技能,因为它影响你将要从事的一切工作。现在从上到下,我认为 R 更多的是数据科学和分析语言,但 SQL 是必须的。如果我们回到我们的管道类比,数据准备的整个左边部分是你需要知道的事情,以使任何项目进行下去。

我想说你至少可以了解 Pandas 和 SQL,SQL 无处不在,大部分企业数据仍然在关系数据库中。此外,SQL 语法在许多较新的数据工具中非常常见,您可以在 pandas 和 spark 中使用它,仅举两个例子。确保至少学习 SQL 的基础知识和如何编写查询,花几周时间专注于它已经足够了。

现在,一旦您从数据源提取了我们的数据,您可能会有一个 CSV 或 Parquet 文件,您将需要一些方法来转换您的数据。行业标准是 Pandas,它将真正帮助你将数据转化为对机器学习有用的东西。这意味着标准化,去除异常值,潜在地验证数据没有问题,以及大量的功能工程。虽然同样的工作有很酷的大数据工具,但我会主要关注 Pandas 和一些 Numpy,直到你有了第一份工作,因为它的语法和功能是黄金标准,我绝对会专注于这一点。从这里开始,类似的技术变得更加新奇,比如说,你可以在工作中学习它们。我认为 Numpy 非常有用,是熊猫的基础,但是纯熊猫 90%的时候会带你去那里。

现在您已经提取、转换和加载了数据,也称为 ETL 管道。让我们来看看你们都已经知道的极其重要的东西,那就是机械学习,ML 工程师中的 ML。也就是说,理解机器学习以及使其工作和推广的基础数学和统计学是非常重要的,也是工作的另一半。在这方面,我至少会关注 Sklearn、XGBoost 以及 Tensorflow 或 Pytorch。

虽然现在每个人都知道深度学习,但不要忘记至少也要学习随机森林、XGBoost 和一些线性回归,你肯定会发现它们在生产中比你现在可能预期的要多得多。有了 ML 知识,也就知道如何选择模型,这意味着能够在测试集上测试您的作品,并使用常见的度量标准(如准确性、召回率、F1 等)对它们进行评估,以确定适合您用例的最佳超参数集和模型类型。

正如许多人所说,机器学习是一种艺术形式,你永远无法充分了解你工作的这一方面,但因为我知道你们中的一些人会过于专注于它,所以我只想说,不要只专注于它,因为这份工作真的不仅仅是擅长 ML。我知道我们都被这些可爱的算法迷住了,但请记住,这只是工作的 50%,甚至更少。到目前为止,我们提到的硬技能组合已经非常强大了,如果你非常了解这些基本技能,你可能只需要知道这些技能就可以申请大多数工作,所以我强烈建议你把最初的大部分时间花在这些方面。

这个过程中的最后一部分,可能也是最容易被忽视的部分,我知道我刚才说了没有它你也能找到工作,但是当你知道这个难题的最后一个关键部分时,你找到工作的机会就会大大增加。这就是如何部署模型以及我们刚刚描述的整个管道。我将其总结为 MLOps,代表机器学习操作,它是一套旨在可靠有效地在生产中部署和维护 ML 模型的实践。

MLOps 的定义来源维基百科

它基本上位于 ML、数据工程(这是我在数据准备中总结的)和 DevOps 的交叉点上。换句话说,你如何在每月的第一天从你的 SQL 数据库中导出数据,用 Pandas 转换它,用 Tensorflow 训练一个模型,最后用 API 在云中部署它。

**免责声明:**我现在会提到很多可能会让你不知所措的流行词汇和复杂技术,但不要害怕,因为每个公司都会使用不同的术语,我会在最后告诉你你真正应该关注哪些术语。就背景而言,大多数公司每年至少一次不断改进和更换部件或扩展他们的技术堆栈,你不可能跟踪所有这些。

说到这里,让我们考虑一下我们的工作流,假设我们编写代码并将其推送到 GitHub,一旦完成,我们就有一个像 Jenkins 或 Airflow 这样的工具,它使用触发器下载代码,然后继续构建所谓的 docker 映像,并使用 Ansible 这样的技术将它们部署到几个集群,Kubernetes 将管理这些 pod 或容器,并向用户公开一些 API。

我们之所以有这样的管道,是因为它们是循环的,所以如果我将新代码推送到我的 GitHub 仓库,整个管道将再次运行,并自动部署新代码,希望不会被黑客攻击,用户可以立即使用,或者等到每月的第一天,Jenkins 再次触发最新的代码进行培训。

迷茫?没关系,这非常复杂,有时在这个过程中会涉及 100 种技术和多种云。对于你的第一份工作,我会说只关注最重要的,并在你工作的时候从那里开始迭代。

如果你有一些空闲时间,一定要关注 Docker,它是大多数这些技术的核心,我认为几乎每个人都在使用它,简而言之,它是一种构建简单的小程序包的技术,该程序包包含在云中或集群上运行应用程序所需的所有代码。另一个非常受欢迎的技术类别是编排工具,如 Airflow 或 Jenkins,简单地说就是确保您的代码运行,例如,每周二早上 5 点或者当您的一个队友将代码推送到特定的 git 存储库时。虽然还有许许多多的事情需要了解,但我确信,如果你知道软件工程、机器学习和 MLOps 这四类技能,你一定会找到一份机器学习工程师的工作。

从哪里学习这些技能

我把它放在自己的部分,这样它就不会让技能部分太混乱。显然,一个很好的起点是大学世界里的任何东西,你在数据和计算机科学中选择的每一门学科都将是你找工作的一个有价值的盟友。如果你还在那里,尝试选择数据科学或计算机科学作为辅修专业,如果你有学士论文或硕士论文等项目,请确保只是运行一个需要你建立一个机器学习算法的问题,你可以将它作为文件夹部分的一个项目。

如果你已经不在大学了,不要担心,外面有那么多好的资源,真的不再需要了。如果我因为某种原因忘记了我已经学过的所有东西,从零开始,我会从学习课程开始,最好最后能拿到证书。首先,从 Coursera 上的一个非正式课程开始,或者只是在 Python 上观看 youtube 视频,直到你能够创建能够正常工作的脚本。现在从这里开始,你可以在数据世界中处理实际的证书,因为我不想为一家公司做太强的广告,让我只说大型科技公司谷歌、IBM 和微软拥有数据世界中几乎所有东西的证书和课程。

他们会很有挑战性,这就是他们真正存在的目的,让你在就业市场上更有价值。所以我给你的建议是,选择一家公司,获得数据科学、数据工程或最好的 ML 工程证书。这也将教会你非常有价值的云技能,这是我没有提到的,因为有些人有谷歌,有些人有 AWS,有些人有 Azure,你需要哪一个取决于你申请的公司。

仅举一个具体的例子,谷歌云机器学习工程师证书是我个人推荐的,它将教会你我刚才提到的一切,但要知道,你应该知道基础知识,并在开始学习之前真正专注于软件工程和机器学习,因为它不是初学者教程。把这些证书想象成你拥有的相关证书越多,公司就会越喜欢你。但是同样要确保不要过度关注一个领域。

获得工作经验

现在,虽然靠自己学习所有这些技能肯定是可能的,但我强烈建议你在工作中学习。如果你还在上大学,许多公司会提供实习的机会,这是你能得到工作的最好方式。如果你正试图进入这一领域,这也适用于你,但我会在实习结束后给你一些可能更好的建议。对于实习来说,进入门槛要低得多,有许多非常有用的途径可以让你获得初级工程职位。我知道,目前作为机器学习工程师的实习机会非常少,这肯定会在未来几年发生变化。然而,如果我们想一想什么是真正的 ML 工程师,我们会发现它是许多其他领域的交汇点,这些领域提供实习或工作机会,如数据科学,数据工程和软件工程。你能在这些领域得到的任何工作或实习都应该是有价值的,也许你不能一直做 ML,但肯定有一些机会在你工作的时候做一点。

ML 工程师从采购的概述

我个人在学习期间开始了软件工程实习,然后在我的学士学位在一家公司进行了数据科学/数据工程/软件工程实习之后,我在攻读硕士学位期间继续在这些领域获得工作经验。

如果你已经工作了,并且不打算再学习,我会试着说服我的雇主再找一些在这些领域的副业。只要记住,你对数据或软件所做的一切都会让你离成为机器学习工程师更近一步。我知道向你的老板推销包括机器学习在内的内部项目可能令人害怕,但如果你向他展示你的解决方案可以节省时间,而且你真的有动力,他们肯定会喜欢。一个非常常见的例子是,对收到的电子邮件进行分类,并需要路由到正确的人,通常公司有太多的方法,一些简单的机器学习真的可以节省你的公司很多时间,所以真的坐下来想想 easy ML 可以帮助你当前的公司,也许你最终会为你的投资组合提供一个很好的项目,并且你可以获得报酬。

创建一个 ML 组合或应用程序

学了这么多之后,你需要能够向招聘经理或招聘人员展示你确实知道这些技能,你将如何做到这一点?无论是如上所述的工作经验,还是你需要创建一个文件夹,或者如果你在大学里,写论文并进行项目,向他们展示你可以做到这一点。

你现在可以创建一个网站、Linkedin 个人资料或博客,人们可以去那里看看你的资历和你做过的项目,然后说哇,这家伙真的知道如何建立机器学习模型并将其投入生产。我个人经历了获得计算机科学硕士学位的经典之路,并与人合著了一些小论文,但如果你能够构建一个功能正常的机器学习应用程序,并将其部署给其他人使用,这真的是你能做的最大的事情之一,可以帮助你获得注意,获得工作,并向雇主展示你知道这些技能。

创建机器学习工程师简历

合乎逻辑的下一步是为机器学习工程师创建一份简历,正如你已经知道的那样,你将需要一份简历或简历来申请你潜在想要申请的任何工作。所以,把你所有的技能、证书和项目都写在一张纸上。所有这些技能和项目实际上会为你创造这份简历,我不打算撒谎,但拥有一些 STEM 领域的学位也是许多工作的一个要求,但正如计算机科学中的一切表明你可以交付质量一样,项目也将发挥作用。如果你正在寻找更多的指导,我确实有一个完整的视频,带你完成为机器学习工程师创建简历的过程,真的可以通过这个视频从头开始创建你的个人简历。

Linkedin 是你的朋友

自从我制作了这个简历视频后,Linkedin 在招聘过程中的重要性急剧增加,我每周都会收到招聘人员和其他求职者的信息。因此,如果你想在这个领域找份工作,我真的会把我们到目前为止讨论过的所有信息放在你的个人资料上,这些证书和项目会确保人们注意到你,让你出现在他们的搜索中。很多时候,招聘人员会注意到你,并希望能够帮助把你“推销”给潜在的雇主。

此外,如果你正在申请,许多人会查看你的 LinkedIn 个人资料,查看你迄今为止做了什么,你在哪里工作,你在数据社区从事什么工作。这确实是人们倾向于跟踪你的第一个地方,让它成为一次对他们来说很好的经历真的可以走很长的路。

如何分配你的时间?

正如我在开始时承诺的,我将把我们在这个视频中讨论的所有内容放到一个更大的画面中,这样你就可以找出你的弱点,并利用所有这些技能打下良好的基础。我之前已经提到过,但是在我们处理其他方面之前,你应该至少有 1 年编程、数据科学家、数据工程师的经验,或者 STEM 领域的学士学位。

我知道很多人会在网上告诉你,你可以在几个月内做到,但即使是最积极的个人,我也要说这是不现实的。也就是说,我强烈建议你至少花一年时间在编程上,当然,这可以是在你攻读学位、数据科学或机器学习项目的时候。

现在,在你了解编程的基本方法之后,我会把我的时间分成 30%编程,20%机器学习,20%数据科学,15%数据工程和 15% MLOps。这些数字都是我编的吗?是的,我做了,但我绝对可以支持他们,而且也很难拿出更明智的东西,因为最终所有这些方面都包括编程和版本管理 pip 包或任何东西。我想说,只要你牢记自己的目标,从头到尾把所有的时间都花在建设项目上,你就会得到正确的时间分配,而不用想太多。

那我为什么要提呢?嗯,我觉得很多人最终只做了机器学习和调整花哨的深度学习模型,而忘记了其他的,只是要确保也将它们投入生产,这是数据科学家或人工智能研究员与机器学习工程师之间的主要区别。

结论

这是一个很大的挑战,不要害怕,我的朋友们,每天迈出一步,你很快就会到达你想去的地方。

如果你想知道他们在工作面试中可能会问你什么具体的问题,我制作了一个关于机器学习工程师面试问题的完整视频,它会给你一些提示,告诉你可能需要在哪些方面投入更多时间。

通常机器学习会在最意想不到的领域发展。虽然大趋势仍然是越大越好,越来越多的倡导者告诉我们,我们也可以用更少的钱做到这一点。我坚信这种发展不仅会让机器学习变得更容易,还会教会我们更有效地使用更大的模型

如果你喜欢这篇文章,我会很高兴在 Twitter 或 LinkedIn 上联系你。

一定要看看我的 YouTube 频道,我每周都会在那里发布新视频。

如何成为更高效的数据科学家

原文:https://towardsdatascience/how-to-become-a-more-efficient-data-scientist-357df86cda4d

网上有数百万篇关于如何提高效率的文章。我们不会在这里分享任何一个,因为生产力的概念是…一个棘手的问题。很多时候,我们很难区分提高生产力的要求和过度劳累的压力。

另一方面,效率是一个具有内在灵活性的概念。它鼓励我们充分利用给定的情况,但随着环境的变化,混乱有时是不可避免的,人们是复杂的存在。当我们有效率的时候,我们让事情变得简单(或者至少不会比他们需要的更复杂),保存能量而不是烧掉它。

成为一名高效的数据科学家意味着什么?本周,我们选择了几篇优秀的文章,试图从多个角度解决这个问题。无论您是大型团队的一员,还是单独的顾问、其他数据专业人员的经理或贵公司的最新分析师,我们认为您都可以在这里找到一些可靠、可行的见解。

  • 结果比你花在一个项目上的时间更重要 Samuel Flender 解开了杠杆的概念,并提出了三个策略,可以帮助数据从业者重新专注于产生最大影响,而不是最努力或最长时间的工作。
  • 面向未来的生产数据管道艺术 。Marian Nodine 说随着时间的推移,数据产品的质量以及对使用和解释数据的支持都会下降。为了让您(和您的同事)的生活更轻松,Marian 强调了建造具有长保质期的坚固管道的四个基本标准。
  • 学习如何有效地对数据请求进行优先级排序 。来自业务利益相关者的持续不断的时间敏感查询已经打乱了无数数据团队的计划。正如玛丽·勒费夫尔解释的那样,问五个具体的问题并获得适当的语境可以帮助你在不失去焦点(或朋友)的情况下筛选请求。

鲍里斯·邓南德在 Unsplash 上的照片

  • 做好记录至关重要 。Robert Yi在谈到围绕即席分析请求的一系列类似挑战时,强调了记录您在为组织内其他团队服务时所做工作的重要性。它不仅使你的努力可见,还可以简化未来的项目,并允许你随着时间的推移发现模式。
  • 确定数据项目价值的框架 。如果你喜欢用结构化的方法来解决复杂的问题,看看乔丹·g .的方法,来决定哪个项目应该放在你清单的首位。它将促使你量化预期的时间承诺、成功概率和潜在影响,并导致更明智的决策。
  • 定义指标的重要性 。如果你的数据不可靠,你就不太可能成为一名高效的数据科学家。这就是为什么高建议将你的承诺——作为个人贡献者或团队的一部分——整理成文,以提供高质量的数据和见解,并就衡量成功的明确标准达成一致。

如果你还有时间多读几本一流的书,以下任何一点都不会错:

  • 我们将我们最新的月刊致力于最近几个月最令人兴奋和发人深省的技术进步之一:文本到图像人工智能工具的出现和日益广泛的采用。
  • 在她的第一篇 TDS 文章中,露西·迪金森在逻辑回归的背景下揭开了分类变量的神秘面纱。
  • 人工智能如何改变现代教育系统?高中毕业班 Sanjay Adhikesaven 、 Abyan Das 和 Monish Muralicharan 在探索最新创新的收益和风险方面处于独特的地位。
  • 我们很高兴分享由 TDS 新作者卡洛斯·科斯塔撰写的关于 CUDA——一种通用 GPU 接口——的四部分系列文章。如果你不熟悉这个话题,第一部分是最好的开始。
  • 驾驭办公室政治(尤其是在大型企业环境中)是任何数据训练营都无法教授的技能。凯西·科兹尔科夫通过鼓励数据科学家提出正确的问题填补了这些空白。

谢谢你一如既往的支持。如果你想产生最大的影响,考虑成为中层成员。

直到下一个变量,

TDS 编辑

如何更好地部署您的机器学习模型

原文:https://towardsdatascience/how-to-better-deploy-your-machine-learning-model-6f179483a289

我反对自制解决方案和替代方案的理由

安德烈·德·森蒂斯峰在 Unsplash 上拍摄的照片

每周,我都要花相当多的时间从研究和工程两方面学习机器学习(ML ),因为我是一名博士生,因为我已经做了相当长一段时间的软件开发人员。在浏览时,我不断看到这些教程,介绍如何使用一些声称“最快”或最简单的 python 库来部署 ML 模型。然而,我认为使用 python web 框架来部署您的 ML 模型并不是最好的选择。

这篇文章将解释为什么我认为你不应该依赖 python web 框架来部署你的 ML 模型,并提出一个替代方案。然而,这不是一个使用建议选项的教程。尽管如此,这是我正在努力发布的东西,所以请继续关注。

为什么 Python 框架不是正确的选择

使用 python 框架部署模型的第一个缺点是您必须构建它。是的,你可以找到一些带有不错的模板的存储库,甚至是一个基于 web 框架的框架,但是你仍然需要做一些修改。问问任何一个经验丰富的软件开发人员,他们都会告诉你,任何一段新代码都有可能出现错误。所以对于每一个新的软件,你都需要处理测试和维护。知道维护占软件总成本的 70%左右,你应该在添加新东西之前三思。

我围绕这一点进行了多次讨论,我一直听说构建这些应用程序是机器学习工程师的工作,这是真的。尽管如此,您并没有让开发人员使现有的应用程序更加健壮,而是添加了一个新的应用程序。

其次,我遇到的所有实现都模糊了 ML 框架和应用程序代码之间的界限,违反了关注点分离原则。因此,您需要进行的任何更新都会更加复杂,因为应用程序代码是与 ML 框架耦合在一起的。随着复杂性的增加,引入新 bug 的可能性也会增加。在某些情况下,当从一个 ML 框架跳到另一个框架时,由于 CUDA 驱动程序不匹配,您甚至可能需要更新您的基础设施。所以想象一下,你有多个研究团队,每个团队都想出于合理的原因使用不同的框架。想想所有的“同步”会议和“设计”讨论,以及需要发生的“重构”工作。

最后,python web 框架不是为机器学习而设计的,因为有一个硬件组件不容易抽象。此外,您将需要处理只在 CPU 或 GPU 上运行的情况,我甚至没有谈论多 GPU 或多节点推理。

这是可以理解的,看到自制的框架建立了一段时间,因为这些推理框架大多是非常新的。然而,如果你正在开始新的东西,我不明白你为什么要走那条路。如果您仍然选择使用自制的实现,您必须明白,在修复错误或重构样板代码时,您并没有为您的工作增加价值。所以确保你有一个合理的理由。

此外,一个人应该明白简单和容易之间的区别。使用现有的遗留自制实现很容易,因为它已经存在,但是当进行更新非常复杂时,使用起来就不简单了。

一种可能的选择

我将这一部分命名为“可能的替代”,因为这不是部署您的 ML 模型的最终方法。然而,这是一个我知道并使用的方法,我认为这是一个比我所知道的任何自制实现更好的解决方案。

我建议的替代方案是 NVIDIA Triton 推理服务器。但是,我想澄清一下,我和英伟达没有任何隶属关系。此外,它是开源的,所以我不建议你买什么。

为什么选择 NVIDIA Triton 推理服务器?

首先,英伟达是创作者。我知道你不应该通过封面来判断一本书,但众所周知,他们为任何与 GPU 和 ML 相关的东西都提供了坚实的产品。最重要的是,你可以确定它将支持未来任何新的 GPU 架构或 ML 框架,并且你不必处理任何驱动程序问题。如果你以前和 CUDA 或者 NCCL 车手打过交道,你就会明白我在说什么。此外,它经过高度优化,可以在 NVIDIA GPUs 上运行,这是行业标准,并有 CPU 支持。

第二,好用。从高层次来说,要部署一个新的模型,首先要将模型二进制文件保存在模型库中,它可以是您的本地硬盘驱动器、网络卷或任何 blob 存储,如 S3。然后创建一个描述输入、输出、调度和硬件要求的文本配置文件。之后,使用管理 API 加载模型。最后,应用程序或用户可以通过推理 API 使用模型。

作者图片

因此,部署一个新模型减少到几个 API 调用,这有多种优势:

  • 您的团队没有在样板代码上花费时间,而是通过将大部分时间花在模型上来更加关注增加价值。
  • 您缩短了上市时间。一旦运行了推理服务器,就不需要为新模型做额外的工作了。
  • 它赋予研究人员权力。由于部署模型很简单,研究人员或者没有软件工程背景的人可以将新模型部署到开发环境中进行测试,这减少了您的支持团队的负担。
  • 删除瀑布任务。如果另一个应用程序使用推理结果,任何其他团队都可以部署模型来测试集成,而不是等到您构建自制的推理服务器。我知道你可以在团队之间签订合同,但是问问任何一个经验丰富的开发人员最近的集成进展如何。
  • 帮助在开发过程的早期发现问题。由于部署模型很容易,研究团队可以使用与生产环境中相同的堆栈,这有助于在过程的早期发现问题,比如超过 SLA 的响应时间。相比之下,研究团队正在选择模型,而工程团队正在构建推理服务器。一旦完成,他们意识到模型响应时间超过了 SLA,需要从头开始。

最后,它功能丰富。Triton 附带了许多特性,从简单用例到更复杂的用例,我知道其中一些特性很难实现,比如调度器或用 C API 访问共享内存。此外,它几乎支持我们今天拥有的所有 ML 框架,因此 Triton 的单个实例可以部署任何格式的模型,并且所有这些都有多个优点:

  • 维护成本降低,尤其是对于复杂的功能。你与 NVIDIA 和社区分摊维护成本(因为它是开源的)。此外,如果你也想减少社区中的浪费,你可以公开 bug 请求,甚至可以投稿。
  • 给研究人员更多的灵活性和自主权。研究团队可以为每个模型选择合适的框架。当一个 ML 框架没有特定的模型架构可用,并且研究人员想要避免从头构建它时,就会发生这种情况。
  • 您可以访问您的团队没有能力或知识来构建的功能。如果您查看文档,您会发现一些功能需要具有特殊和罕见才能的员工,通过使用 Triton 这样的工具,您可以免费获得它(嗯,有些免费,因为成本包含在 GPU 价格中)。

结论

我在 ML 模型部署方面没有几十年的经验,我在本文中提出的论点可能有漏洞。然而,根据我有限的经验,我发现使用这样的工具会使生活变得更容易,并且可以将注意力集中在最终产品上。

此外,除了检查 Triton 推理服务器之外,另一个信息是在编写自制实现之前,总是先寻找现有的东西,尤其是在当前的创新速度下。

在你走之前

在 Twitter 上关注我,在那里我会定期发关于软件开发和机器学习的微博,或者在 Youtube 上关注我,在那里我会分享实践视频教程。

如何将数字数据与熊猫绑定

原文:https://towardsdatascience/how-to-bin-numerical-data-with-pandas-fe5146c9dc55

用熊猫离散化数值变量,介于,cut,qcut 和值计数之间

介绍

宁滨也称为分桶或离散化,是一种常见的数据预处理技术,用于将连续数据的间隔分组到“箱”或“桶”中。在本文中,我们将讨论使用 python 熊猫库计算宁滨数值的 4 种方法。

Pawel Czerwinski 在 Unsplash 上拍摄的照片

方法

为了便于说明,我们创建了以下合成数据。

import pandas as pd # version 1.3.5
import numpy as npdef create_df(): df = pd.DataFrame({'score': np.random.randint(0,101,1000)}) return dfdf = create_df()df.head()

这些数据包括 1000 名学生从 0 到 100 的学习成绩。任务是将数值分数分为“A”、“B”和“C”三个等级,其中“A”是最好的等级,“C”是最差的等级。

作者图片

1.& loc 之间

Pandas *.between* 方法返回一个包含 True 的布尔向量,无论相应的 Series 元素在边界值 left 和 right[1]之间。

参数

  • left:左边界
  • right:右边界
  • inclusive:包含哪个边界。可接受的值是 {“两者”、“两者都不是”、“左”、“右”}。

让我们根据以下间隔将学生的分数分成几个等级:

  • 答:(80,100)
  • 乙:(50,80)
  • 丙:[0,50]

其中方括号[和圆括号)分别表示边界值包含和不包含。

我们识别哪些score位于感兴趣的区间之间,并为其分配相应的grade值。对于等级“A”和“B ”,只有右边界包含在内,因此我们将right传递给inclusive参数。对于等级“C ”,两个边界都包含在内,因此我们将both传递给inclusive参数。

df.loc[df['score'].between(0, 50, 'both'), 'grade'] = 'C'
df.loc[df['score'].between(50, 80, 'right'), 'grade'] = 'B'
df.loc[df['score'].between(80, 100, 'right'), 'grade'] = 'A'

作者图片

这是每个箱子里的学生人数

df.grade.value_counts()

作者图片

这种方法需要为每一个 bin 添加一行新的代码,因此它只适用于 bin 很少的情况。

2.切口

将值装入离散区间。当您需要将数据值分段和排序到箱中时,请使用 cut。这个函数对于从连续变量到分类变量也很有用[2]。

基于与上述示例相同的间隔对学生进行分组。这些是所使用的参数:

  • x:要入库的输入数组。必须是一维的。
  • bins:标量序列:定义允许非均匀宽度的 bin 边缘。
  • labels:指定退回箱子的标签。必须与生成的条柱长度相同。
  • include_lowest : (bool)第一个区间是否应该左包含。
bins = [0, 50, 80, 100]
labels = ['C', 'B', 'A']
df['grade'] = pd.cut(x = df['score'], bins = bins, labels = labels, include_lowest = True)

我们创建一个包含面元边界值的bins列表和一个包含相应面元标签的labels列表。

作者图片

这是每个箱子里的学生人数

df.grade.value_counts()

作者图片

结果与第一个示例相同。

3.qcut

基于分位数的离散化函数。根据等级或样本分位数将变量离散化为大小相等的桶[3]。

在前面的例子中,我们已经为每个年级定义了分数区间,这导致每个年级箱中的学生数量不均匀。在下面的例子中,我们尝试将学生分成 3 个年级组,每个组有相同(大约)数量的学生。我们有 1000 名学生,因此每个库应该有大约 333 名学生。首先根据分数对学生进行排名,前三分之一、中三分之一和后三分之一的学生分别被分配到“A”、“B”和“C”等级。

以下是以下示例中使用的参数:

  • x:要入库的输入数组。必须是一维的。
  • q:分位数的个数。十分位数为 10,四分位数为 4,等等。分位数的交替排列,例如[0,. 25,. 5,. 75,1。]对于四分位数。
  • labels:指定退回箱子的标签。必须与生成的条柱长度相同。
  • retbins : (bool)是否退回(箱子,标签)。如果条块以标量形式给出,则非常有用。
df['grade'], cut_bin = pd.qcut(df['score'], q = 3, labels = ['C', 'B', 'A'], retbins = True)
df.head()

作者图片

retbins作为True传递会返回容器边界。

print (cut_bin)
>> [  0\.  36\.  68\. 100.]

箱子的间隔如下:

  • 丙:[0,36]
  • 乙:(36,68)
  • 答:(68,100)

我们可以使用.value_counts()检查每个年级组中有多少学生。理想情况下,每个箱子应该有大约 333 名学生。

df.grade.value_counts()

作者图片

4.值计数

虽然 pandas .value_counts通常用于计算一个系列中唯一值的数量,但它也可用于使用bins参数[4]将值分组到半开的箱中。

df['score'].value_counts(bins = 3, sort = False)

默认情况下,.value_counts按值的降序对返回的序列进行排序。将sort设置为False,按照索引的升序对系列进行排序。

作者图片

序列索引是指每个 bin 的区间范围,其中方括号[和圆括号)分别表示边界值包含和不包含。返回系列的值指示每个箱中有多少条记录。

.qcut示例不同,每个箱中的记录数量不一定相同(大约)。.value_counts不会将相同数量的记录分配到每个等级箱中,而是根据最高和最低分数将分数范围分成三个相等的部分。分数的最小值为 0,最大值为 100,因此 3 个部分的范围约为 33.33。这也解释了为什么除了最低的左边界之外,仓的边界是 33.33 的倍数。

我们还可以通过传入一个边界列表来定义 bin 的边界。

df['score'].value_counts(bins = [0,50,80,100], sort = False)

作者图片

这给出了与实施例 1 和 2 相同的结果。

摘要

在本文中,我们研究了如何使用.between.cut.qcut.value_counts对连续值进行装箱。上面例子的 Colab 笔记本可以在这里找到。

参考

[1] 熊猫之间

【2】熊猫切

熊猫 qcut

[4] 熊猫价值统计

如何提高熊猫的速度,在几毫秒内处理 1000 万行数据集

原文:https://towardsdatascience/how-to-boost-pandas-speed-and-process-10m-row-datasets-in-milliseconds-48d5468e269

按照预期的方式使用熊猫

照片由supreme拍摄

介绍

“太好了…另一篇关于如何让熊猫速度提高 n 倍的文章.”

我想我已经说过无数次了,在过去的两年里我一直在用熊猫。最近看到的一条说“让熊猫快 71803 倍”。

但我不会给你这种承诺。我将向你展示如何以最快的方式使用熊猫。因为你不能加快已经很快的东西。没道理?

让我问你这个问题。当我说“摸摸你的右耳”时,你用哪只手当然,右手。把你的左手放在头上,你不会碰到你的右耳。那会很奇怪。

嗯,使用这些函数,熊猫文档清楚地说明了慢而不是最快的方法,也会很奇怪。

这就是为什么本文将向您展示 Pandas 中一些最常见的数据操作的最佳实践。你甚至可以将这些最佳实践视为“常识”,因为这就是熊猫的创造者打算如何使用他的图书馆。

获得由强大的 AI-Alpha 信号选择和总结的最佳和最新的 ML 和 AI 论文:

https://alphasignal.ai/?referrer=Bex

高效索引

先说最基础的操作。具体来说,我们将看到选择行和列的最快方法。如你所知,熊猫有两个索引操作符——lociloc。尽管它们的差异对于小数据集来说关系不大,但随着数据量的增加,它们会变得非常明显。

首先,对于选择一行或多行,iloc更快。

相比之下,loc最适合选择带有标签的列:

>>> tps.loc[:, ["f1", "f2", "f3"]]

对于采样列或行,内置的sample函数是最快的。您可能认为通过 NumPy 使用随机索引进行采样会更快,但事实并非如此:

# Sampling rows
>>> tps.sample(7, axis=0)

# Sampling 5 columns and 7 rows
>>> tps.sample(5, axis=1).sample(7, axis=0)

有效替换值

大多数时候,我看到人们使用lociloc来替换数据帧中的特定值:

的确,这种方法似乎是最快的,因为我们指定了要替换的值的确切位置,而不是让 Pandas 来搜索它。但是,这种方法很笨拙,而且没有replace快:

速度是replace的第一个好处,其次是它的灵活性。上面,我们用NaN替换了所有的问号——这是一个基于索引替换的多次调用操作。

另外,replace允许使用列表或字典同时改变多个值:

当用一个值列表替换另一个值列表时,它们将具有一对一的索引到索引的映射。你可以更具体地使用字典,比如:

使用嵌套字典可以更细化:

当您只想影响特定列的值时,嵌套替换会有所帮助。这里,我们只替换educationincome列中的值。

replace还有其他好处,包括基于正则表达式的替换,这可以在文档中读到。

https://ibexorigin.medium/membership

高效迭代

对整列或数据帧应用操作的黄金法则是永远不要使用循环。这是行之有效的陈词滥调。但是,我明白了——如何在不循环的情况下操作整个数组?

诀窍是开始将数组视为向量,将整个数据帧视为矩阵。毕竟 ML 模型就是这么接受数据的——说白了都是多变量向量值函数。

从线性代数中,我们知道对向量的运算是对整个向量进行的,不管是乘法、加法等等。幸运的是,这种对数学向量进行操作的思想在 Pandas 和 NumPy 中实现为矢量化。

因此,如果您想在一个或多个列上执行任何数学运算,很有可能该运算在 Pandas 中是矢量化的。例如,像+、-、*、/、**这样的内置 Python 操作符就像对向量一样工作。

为了体验一下矢量化,让我们对大规模数据集执行一些操作。我们将选择 Kaggle TPS 九月竞赛的约 1M 行数据集:

让我们用熊猫apply函数对几列进行一些数学运算。那是熊猫最快的内置迭代器。

我们将用apply在三列上运行这个函数,并检查运行时间:

1M 行数据集为 19.3 秒。还不错。现在,看看当我们将列作为向量而不是标量传递时会发生什么。无需修改功能:

37 毫秒!这比最快的迭代器快了大约 600 倍。但是我们可以做得更好—在 NumPy 阵列上使用时,矢量化甚至更快:

只需添加.values即可获得熊猫系列的底层 NumPy ndarray。NumPy 数组速度更快,因为它们不像 Pandas 系列那样执行额外的索引调用和数据类型检查。

让我们快速疯狂吧

我们应该到此为止吗?熊猫还有一些锦囊妙计。不过,公平的警告是,除非你有超过 100 万行,否则这些不会给你带来太多好处。

好了,我们开始吧。首先,我们将把数据集的大小增加十倍,给自己一个挑战:

大约 9gb,这应该足够了。哦,顺便说一下,如果这种规模的数据集对你来说是一个问题,请查看我关于驯服这些野兽的文章:

现在,我们将继续使用我们的crazy_function,从 NumPy 矢量化作为基线开始:

对于 10M 行的数据集,大约 0.3 秒。当我用apply试着这样做的时候,它甚至在一个小时内都没有完成。

现在,让我们进一步改进运行时。第一个候选人是农巴。我们通过 pip ( pip install numba)安装并导入它。然后,我们将用jit功能来装饰我们的crazy_function。JIT 代表 *just in time,*它将纯 Python 和 NumPy 代码翻译成本机指令,从而大大提高了速度。

现在,我们像运行任何其他函数一样运行它:

我们实现了大约 1.5 倍的速度提升。请注意,Numba 最适用于包含许多原生 Python 循环、大量数学运算的函数,甚至更好的是 NumPy 函数和数组。

Numba 可以做得更多,包括并行计算和基于 GPU 的编译。查看文档。

如果你不在乎额外的依赖,我给你介绍一下熊猫的eval功能。有两个版本- pd.eval(更高级)和df.eval(在数据帧的上下文中)。像 Numba 一样,您应该在数据帧中至少有+10,000 个样本才能看到改进。但是一旦你这样做了,你将会看到速度上的巨大好处。

让我们在df.eval的上下文中运行我们的crazy_function:

没有矢量化或 Numba 快,但它有几个好处。首先,通过避免引用 DataFrame 名称,您编写的代码要少得多。接下来,它显著加快了对数据帧的非数学运算,如布尔索引、比较等等。

当你不做数学运算时,评估你在pd.eval中的陈述。我建议从文档中查看使用eval的注意事项。

注意,即使对于 10M 行的数据集,我们也是在毫秒的范围内讨论。

包装

我们讨论的大部分内容摘自 Pandas 文档中信息丰富的 提高速度 部分。我们已经涵盖了最重要和最有效的方法,忽略了小细节。我强烈建议你通过它来获得更多的速度提示。

https://ibexorigin.medium/membership https://ibexorigin.medium/subscribe 💔-step-feature-selection-guide-in-sklearn-to-superchage-your-models-e994aa50c6d2>

如何使用内存映射文件提升 PyTorch 数据集

原文:https://towardsdatascience/how-to-boost-pytorch-dataset-using-memory-mapped-files-6893bff27b99

本文将讨论实现使用内存映射文件的 PyTorch 数据集的原因和步骤

埃尔奥诺雷·凯梅尔在 Unsplash 上的照片

介绍

W 在训练神经网络时,最常见的速度瓶颈之一就是数据加载模块。如果我们通过网络传输数据,除了预取和缓存之外,没有其他简单的优化方法可以应用。

但是,如果数据在本地存储中,我们可以通过将整个数据集合并到一个文件中来优化文件读取操作,然后我们可以将该文件映射到主内存中,这样我们就不需要为每个文件读取进行昂贵的系统调用,而是让虚拟内存管理器来处理内存访问。

这段短暂旅程中的几站:

  • 什么是内存映射文件
  • 什么是 PyTorch 数据集
  • 实现我们的定制数据集
  • 基准
  • 结论

什么是内存映射文件?

我们称一个内存映射文件,这个文件的内容直接分配给 虚拟内存 的一个段,这样我们可以在那个段上执行任何操作,就像在当前进程中我们可以访问的主存的任何其他部分一样。

由于虚拟内存所代表的额外抽象层,我们可以映射到比我们机器的物理容量大得多的内存文件中。运行进程所需的内存段(称为 )由虚拟内存管理器从外部存储器中取出并自动复制到主内存中。

使用内存映射文件的好处:

  • 提高 I/O 性能,通过系统调用的正常读/写操作比本地内存中的更改要慢得多
  • 该文件以一种“懒惰”的方式加载,通常一次只加载一页,因此即使对于较大的文件,实际的 RAM 利用率也是最小的。

什么是 PyTorch 数据集

Pytorch 提供了两个主要模块,用于在训练模型时处理数据管道:数据集数据加载器。

DataLoader 主要用作数据集的包装器,它提供了许多可配置的选项,如批处理、采样、预取、混排等。,并抽象出大量的复杂性。

数据集是我们拥有大部分控制权的实际部分,我们实际上必须编写为训练过程提供数据的方式,这包括将样本加载到内存中并应用任何必要的转换。

从高层来看,我们要实现树函数:【_ _ init _ _】、len,以及 _ _ getitem _ _;我们将在下一节看到一个具体的例子。

实施我们的定制数据集

接下来,我们将看到上述三个函数的实现。

最重要的部分在 init中,我们将使用 numpy 库中的NP . memmap*()***函数来创建一个 ndarray ,它由映射到文件的内存缓冲区支持。

ndarray 将从一个 iterable(最好是一个生成器来填充,以将内存利用率保持在最低水平),这样我们就可以保持对数据集支持的数据的形式和类型的高度适应性。我们还可以提供一个转换函数,当从数据集中检索时,该函数将应用于输入数据。

关于更全面的视图和其他示例,实际项目也在 Github 上这里。

还有两个实用程序类型的函数,我们在上面给出的代码中使用过。

基准

为了展示一个性能提升的真实例子,我将内存映射数据集实现与以经典惰性方式读取文件的普通数据集实现进行了比较。这里使用的数据集由 350 个 jpg 图像组成。基准测试的代码可以在这里看到。

从下面的结果中,我们可以看到我们的数据集比普通的数据集快 30 倍以上:

数据集比较

结论

本文中给出的实现决不是产品级的,但是其背后的思想是非常有效的,在使用中型到大型文件时,内存映射文件方法还有更多的用途。

感谢你的阅读,我希望你会发现这篇文章很有帮助,如果你想了解最新的编程和机器学习新闻以及一些优质的模因:),你可以在 Twitter 上关注我这里或者在 LinkedIn 上联系这里。

参考

  • 【https://en.wikipedia/wiki/Memory-mapped_file
  • https://man7/linux/man-pages/man2/mmap.2.html

如何提升你的 GNN

原文:https://towardsdatascience/how-to-boost-your-gnn-356f70086991

改善图形神经网络的技巧和诀窍

由彼得罗·郑在 Unsplash 上拍摄的照片

图形神经网络(GNN)是新的酷小子。它的名字听起来很花哨,数学很先进,GNNs 在各种任务上表现出最先进的性能。

GNNs 提供了一种在图结构数据上使用深度学习技术的方法。图结构数据无处不在:从化学(如分子图),到社交媒体(如社交网络),还有金融投资(如风险投资网络)。

在我的硕士论文期间,我在一个由投资者、创业公司和个人组成的投资网络上,使用 GNNs 预测了创业公司的未来融资轮次。当我实现 GNN 模型(R-GCN 和 HGT)时,基线随机森林模型已经相当强大(AUC = 0.69)。

我很高兴看到先进的 GNN 将如何提高我的成绩。令我惊讶的是,GNN 模型总是落后于基线模型的表现。增加层数和隐藏尺寸没有帮助。所以我开始研究,发现我并不是唯一一个有 GNN 关系问题的人。

如果这听起来对你来说很熟悉(很可能是这样,否则你为什么要费心阅读这篇枯燥的博客文章),我可能有一些提高你的 GNN 模型性能的技巧。

什么是 GNNs 来着?

在我们讨论如何改进 gnn 之前,让我们快速回顾一下它们是如何工作的。关于图形神经网络的伟大而深入的介绍,请查看来自 DeepFindr (或一些 literature⁴)的 Youtube 频道

假设我们有一个简单的图表,如下所示:

包含节点特征的图(图片由作者提供,改编自 DeepFindr)


图包含节点(I,j,k)和连接这些节点的边(e)。此外,该图还包括每个节点(X1,…)的节点特征,可能还包括每条边(黑色)。目标节点用黄色表示,它的 1 跳邻居用蓝色表示,2 跳邻居用绿色表示。包括不同类型节点的图被称为“异构”图,就像我们的例子一样。

消息传递
节点在步骤 0 的嵌入只是它的特征向量(由特征 X1,X2……组成)。为了获得我们的目标节点 I(黄色)的新的(l + 1)节点嵌入 h,我们从它的相邻节点 j(蓝色)、它自己的表示以及潜在的边特征 e(黑色)中提取所有嵌入,并且聚集这些信息。这显示在下面的公式中。但是,请记住,目前大多数著名的 GNN 架构都没有利用边缘 features⁵.之后,我们可以将这些新的节点嵌入用于各种任务,例如节点分类、链路预测或图形分类。

通用 GNN 层公式

GNNs 的问题

在实践中 最近在各个领域的许多研究发现,GNN 模型并没有提供预期的 performance⁵ ⁶ ⁷.当研究人员将它们与更简单的基于树的基线模型进行比较时,GNNs 无法超越甚至匹配基线。

其他研究人员对 GNNs⁸.有时表现不佳提供了理论上的解释根据他们的实验,GNNs 仅执行特征去噪,而不能学习非线性流形。因此,他们主张将 GNNs 视为图学习模型的一种机制(例如,用于特征去噪),而不是一个完整的端到端模型。

修理

为了弥补这些缺点,提高你的 GNN,我找到了 3 个主要的技巧/想法:

  1. 利用 GNN 中的边缘特征
  2. GNNs 自我监督预培训
  3. 单独托辞&下游任务

让我们来详细了解一下。

利用边缘特征

利用边要素的想法在很大程度上取决于您正在处理的数据类型。如果您的数据包含(多维)边要素,利用边要素可以提高模型的性能。

然而,很少建立的 GNN 模型架构支持多维边缘 features⁵.我使用的一个简单的工作方法是创建人工节点:

人工节点 通过使用人工节点,你可以继续使用你之前使用的相同模型。我们唯一要改变的是图表本身,它会变得更复杂一点。不是边保存边特征,而是每条边将成为自身的一个节点(浅蓝色)连接到原始的深蓝色节点。

添加人工节点前后的投资网络元图(图片由作者提供)

这样,您可以通过将边要素作为人造节点的节点要素传递给模型来间接利用边要素。如果边要素与任务相关,这可以提高模型的性能,但也会增加复杂性。您可能需要考虑向模型中添加更多的 GNN 图层(以允许更多的邻居跃点)。人工结节导致 AUC 增加约 2%。

你自己的 Edge 特性架构 你也可以创建自己的 GNN 层实现。这听起来很难;但是,如果你使用一个图形学习库,比如 DGL ,这肯定是可行的。我建议您使用现有的 GNN 实现(见这里)并根据您的需要进行调整。

作为一个例子,我基于 GAT ⁰和 R-GCN 的现有思想制定了自己的实现,我称之为 Edge-GCN:

我自己的边缘-GCN 公式(v 代表节点,e 代表边缘,sigma 是非线性激活函数[在这种情况下是 RELU],alpha 是每个关系类型的学习注意力分数,c 是归一化常数)

边 GCN 使用注意机制来学习所有不同关系类型的边相对于节点特征的重要性。如果您对 DGL 的实施感兴趣,请联系我。E-GCN 架构将 GNN 模型的 AUC 结果提高了约 2%(人造节点也是如此)。

自我监督的预培训

这可能是提高你的 GNN 性能的最重要的技巧。尽管预训练 GNNs 已经在理论上进行了探索,但在实践中的应用仍然是 rare⁶ ⁷ ⁸.

这个想法与计算机视觉和自然语言处理领域的概念非常相似。以语言模型 BERT 为例,它被训练来预测句子中的屏蔽词(这是自我监督的,因为它不依赖于标记的数据)。我们通常不太关心预测屏蔽词的具体任务。然而,由于模型了解特定单词如何相互关联,因此得到的单词嵌入对于许多不同的任务非常有用。

自我监督
我们想要使用自我监督任务来预训练 GNN 模型节点嵌入。在有噪声的标签的情况下,这可能是特别有益的,因为自我监督过程提供了更多的“有标签的”例子(因为我们不需要为预训练提供标签),并且可能也不容易有噪声。

如果我们的最终目标是对节点进行分类,我们可以在整个图上使用链接预测作为自我监督的预训练任务。在链接预测中,我们试图预测两个节点之间是否存在边(=链接)。因此,我们训练 GNN 来区分图中的真实边和人工引入的假边(“用于链接预测的负采样”)。由于我们只是简单地添加伪边并移除图中现有节点之间的真实边,因此我们不依赖任何标记的数据。接下来,我们可以使用从链路预测 GNN 模型得到的节点嵌入作为另一个节点分类模型的输入。

将自我监督的预训练管道添加到模型中,其 AUC 分数惊人地增加了 14%,使这成为最有影响力的技巧。

单独的借口和下游任务

到目前为止,我们只讨论了在自我监督的任务(“借口”)上对 GNN 进行预训练,以及在最终(“下游”)任务上使用相同的 GNN 架构。然而,我们不必为这两个任务使用相同的模型架构。您还可以组合不同的 GNN 架构。或者更有希望的是:

两全其美 如前所述,GNN 层可能无法在各种情况下高效学习。因此,我们可以使用 GNN 模型,通过自我监督的预训练来创建节点嵌入,并将这些嵌入传递给经典的机器学习算法或完全连接的神经网络层,以用于最终的下游任务。这种架构可以用于许多不同的下游任务,从图形分类到节点分类和回归。

该模型将受益于将访问图中包含的所有信息的能力与非线性流形学习属性相结合。此外,该模型继承了更简单的机器学习算法的一些好处,如减少训练时间和更好的可解释性。在我们的实验中,基于树的模型(例如随机森林)对于节点分类的下游任务显示出特别强的性能,因此可以从那里开始。

接下来,您可以看到包含所有三个提出的想法的最终管道的图形概述:

最终管道使用边缘特征、自我监督预训练和下游随机森林模型对图中的节点进行分类(X 表示特征,E 表示学习嵌入,h 表示隐藏节点表示)(图片由作者提供)

这种架构代表了我们的最终模型,AUC 得分为 78.1(另一个+ 1.5%),或以 AUC 衡量的总性能增加 17%(基础 R-GCN 模型:AUC = 66.6)。

结论

在这篇博文中,我们讨论了图形神经网络模型的缺点以及提高模型性能的三个主要技巧。结合这些技巧,我能够将我的最终 GNN 模型的 AUC 提高 17%(其他指标甚至更高)。

首先,如果您的数据包含边特征,并且您认为它们对最终的预测任务很有帮助,那么您可以尝试利用边特征。第二,使用自我监督的目标预先训练 GNN 模型通常有益于最终模型的性能。它可以增加训练样本的数量,有时还可以减少固有噪声。第三,测试前文本和最终预测任务的不同架构可以提高模型的预测能力。

这些技巧对你有用吗?如果你有任何补充或反馈,请在评论区告诉我!GNN 调音快乐!

参考

[1] Michael Schlichtkrull、Thomas N. Kipf、Peter Bloem、Rianne van den Berg、Ivan Titov 和 Max Welling。用图卷积网络对关系数据建模,2017。

[2]胡,董,王宽三,。异构图形转换器,2020。

[3]https://deepfindr,2020 年。

[4]达维德·巴丘、费德里科·埃里卡、阿莱西奥·米凯利亚、马尔科·波德达。图形深度学习的温和介绍,2020

[5]杨。NENN:在图形神经网络中结合节点和边特征,2020

[6]费德里科·埃里卡、马尔科·波德达、达维德·巴丘和阿莱西奥·米凯利。用于图形分类的图形神经网络的公平比较,2020。

[7]克莱门特·加斯托、西奥菲勒·卡尼尔和让-米歇尔·达勒。创业融资成功的外部因素的不同重要性:早期阶段的竞争和成长期的网络,2019。

[8]蒋德军,吴振兴,谢长玉,,陈,廖奔,王哲,,曹东升,,侯廷军.图形神经网络可以为药物发现学习更好的分子表示吗?2021.

[9]黄 NT 和前原诚司。重温图形神经网络:我们所拥有的只是低通滤波器,2019。

[10]Petar veli kovi、Guillem Cucurull、Arantxa Casanova、Adriana Romero、Pietro Liò和 Yoshua Bengio。图注意力网络,2018。

11 卡罗·哈普雷希特。使用图形神经网络预测未来融资轮次,2021

[12]华伟·胡、、约瑟夫·戈麦斯、马林卡·兹特尼克、珀西·梁、维贾伊·潘德和朱尔·莱斯科维奇。预训练图神经网络的策略,2019。

[13] Jacob Devlin,Chang Ming-Wei,Kenton Lee 和 Kristina Toutanova。BERT:面向语言理解的深度双向转换器预训练,2018。

如何建立全超参数整合的贝叶斯岭回归模型

原文:https://towardsdatascience/how-to-build-a-bayesian-ridge-regression-model-with-full-hyperparameter-integration-f4ac2bdaf329

我们如何处理控制正则化强度的超参数?

在这篇博文中,我们将描述一种贝叶斯岭回归算法,其中代表正则化强度的超参数被完全积分。在【github/rnburn/bbai】有一个实现。

θ = (σ, w )表示具有权重 w 和方差σ的正态分布误差的线性回归模型的参数。

如果 X 表示具有 p 个回归量
和 n 行的满秩 n×p 矩阵,则 θ 指定可能的
目标值 y 的概率分布

假设我们观察到 y 并假设 y 是由未知参数的线性模型产生的。贝叶斯推理方法寻求量化我们对给定观测值的未知参数 θ 的信念。

应用贝叶斯定理,我们可以将概率改写为

我们指的是

  • P( θ | y )作为后验分布
  • P( y | θ )作为似然函数
  • P( θ )先验分布

先验分布描述了我们在观察到 y 之前对 θ 的信念,后验分布描述了我们在观察到 y 之后更新的信念。

假设先验分布可以表示为

其中 h(⋅,η) 表示由我们称之为超参数η参数化的概率分布族

传统的贝叶斯线性回归方法使用了所谓的共轭先验。一族先验 h(⋅,η)是共轭的,如果后验也属于该族

共轭先验在数学上是方便的,因为连续观测可以被视为对分布族的参数进行连续更新,但是要求 h(⋅η是共轭的是一个强假设。

注意:关于与其他贝叶斯算法的更详细的比较,请参见附录 A。

我们将描述一种算法,其中

  1. 先验被选择为收缩 w ,反映了先前的假设,即 w 不是
    预测性的,并且对于其他参数近似为非信息性的
  2. 我们在超参数上完全积分,因此不需要任意选择η。

让我们首先考虑一下,先验无信息意味着什么。

如何挑选无信息的前科?

注意:这里对非信息先验的介绍紧跟 Box & Tiao 的书统计分析中的贝叶斯推断的第 2 章。

假设 y 是均值为 0 但方差未知的正态分布产生的数据。设σ表示标准差,ℓ表示似然函数

假设我们在σ上施加统一的先验,使得后验概率为

累积分布函数是

其中 N 是某个归一化常数。

但是现在让我们假设我们用方差来代替标准差。将 u=σ代入累积分布函数,我们得到

因此,我们看到选择σ上的一致先验等价于选择不适当的先验

超方差。一般来说,如果 u=φ(θ ) 是参数化似然函数的另一种方式,其中φ是某种单调的一对一函数。那么 u 上的一致先验等价于选择一个先验

超过θ。

那么,如果选择对参数化敏感,什么时候使用统一的先验有意义呢?

让我们考虑观察值 y ^⊤ y 的变化是如何影响可能性的。

具有零均值、
n=10 和不同的 y ^⊤ y 值的正态分布数据的标准差的似然函数。

正如我们从图中看到的,随着 y ^⊤ y 的增加,似然函数的形状发生了变化:它变得不那么尖锐并且更加分散。

注意,我们可以将似然函数改写为

在哪里

因此,在参数 log σ中,可能性具有以下形式

在哪里

我们说似然函数是对数σ中的数据转换,因为除了位置和观察值仅用于移动曲线之外,关于似然曲线的一切都是已知的。

均值为零、
n=10、 y ^⊤ y 不同值的正态分布数据的对数标准差的似然函数。

当似然函数是参数中的转换数据时,对非信息先验使用统一函数是有意义的。在观察数据之前,我们没有理由选择一个参数范围[a,b]而不是另一个相同宽度的范围[t + a,t + b],因为如果观察到的数据平移 t,它们相对于似然曲线的位置是相等的。

现在,让我们回到挑选我们的前科。

挑选正则化贝叶斯线性回归先验

对于参数σ,我们使用无信息先验

这相当于在参数 log σ上使用统一的先验。对于 w ,我们想要一个收缩权重的信息先验,反映权重不可预测的先验信念。让η表示控制
收缩程度的超参数。然后我们使用协方差矩阵为(σ/λ_η) I 的球形正态分布

请注意,我们还没有描述η如何参数化λ,我们还将对η进行积分,因此我们另外有一个η的先验(称为超先验),因此

我们的目标是先验 P(η)是无信息的。所以我们想知道:在什么参数化中,P( y |η)会被数据翻译吗?

收缩先验如何参数化?

在考虑如何参数化λ之前,我们先来刻画一下λ的似然函数。

展开被积函数,我们有

在哪里

注意#1 与 w 无关,因此关于 w 的积分等同于在非标准化高斯上的积分。

注意:回想一下归一化高斯积分的公式

因此,

接下来让我们考虑σ上的积分。

然后我们可以重写

在改变变量之后,我们可以把关于σ的积分表示为伽马函数的一种形式。

考虑一个积分

然后

其中γ表示伽马函数

因此,我们可以写

UσV 表示 X
的奇异值分解,从而

让ξ₁,ξ₂,…表示σ的非零对角线元素。放λ=σ^⊤σ。那么λ是一个对角矩阵,有ξ₁,ξ₂,…和

注意:为了实现我们的算法,我们将只需要矩阵 Vσ的非零对角元素,这可以通过部分奇异值分解来有效地计算。参见 LAPACK 函数 gesdd 。

那么我们可以把 h 和 g 改写成

这里我们采用术语

那么 r 是范围从 0 到 1 的单调递增函数,
我们可以认为 r 是特征向量的平均收缩因子。

现在,让我们通过用平均值替换单个特征向量收缩来进行近似:

将近似值代入似然性,我们就得到

我们看到近似的可能性可以表示为

因此,这种可能性大约是对数 r(λ)中的数据转换。

因此,如果我们
让η代表平均收缩率,我们可以获得近似无信息先验

并使用超级优先级

注意:为了求 r 的倒数,我们可以使用一个标准的求根算法。

对 r(λ)求导得到

利用导数和牛顿算法的变体,我们可以快速迭代得到 r⁻ (η)的解。

做预测

拟合贝叶斯模型的结果就是后验分布 P( θ | y )。让我们考虑在给定一个新的数据点 x 的情况下,如何使用该分布进行预测。

我们将从计算预期目标值开始

注意:为了计算包含η的表达式的期望值,我们需要对后验分布 P(η| y )进行积分。我们没有积分的解析形式,但是我们可以用一个自适应积分来高效精确地积分。

为了计算方差,我们有

从 E[σ | y ]开始,回想一下

因此,

注意:伽玛函数具有属性

所以,

因此

对于 e[ww**^t|**y],我们有

算法概述

我们已经看到,计算关于预测的统计数据涉及对后验分布 P(η| y )的积分。我们将简要地勾画出计算这种积分的算法。我们描述它只是为了计算 w 的期望值。其他期望值可以通过简单的修改来计算。

过程 SHRINK-INVERSE 应用牛顿算法用 r 和 r '求根来计算 r⁻。

为了计算超参数后验积分,我们利用自适应求积算法。在不同的求值点上,用加权和来近似积分。

一般来说,使用的评估点数越多,近似值就越精确。自适应求积算法比较不同细化级别的积分近似值,以逼近误差,并增加评估点数,直到达到所需的容差。

注意:我们省略了所使用的求积算法的细节,仅在较高层次上进行描述。有关具体求积算法的更多信息,请参考高斯-埃尔米特求积法和双曲正切法。

实验结果

为了更好地理解算法在实践中是如何工作的,我们将设置一个小的
实验数据集,并将贝叶斯算法的模型拟合与普通最小二乘法(OLS)和岭回归模型拟合进行比较,以便最小化数据集的留一交叉验证(LOOCV)的误差。

实验的全部源代码可以在 github/rnburn/bbai/example/03-bayesian.py 的 T2 获得。

生成数据集

我们将从设置数据集开始。对于设计矩阵,我们将使用均值为零的高斯和协方差矩阵 K 随机生成一个 20 乘 10 的矩阵 X ,其中

我们将从具有单位方差的球形高斯中生成具有 10 个元素的权重向量,并且我们将重新调整权重,使得信号方差等于 1。

那我们就开始吧

其中 ε 是从具有单位方差的高斯分布中提取的 20 个元素的向量。

下面是设置数据集的 Python 代码。

拟合模型

现在,我们将拟合贝叶斯岭回归模型、OLS 模型和具有正则化强度设置的岭回归模型,以便最小化 LOOCV 的均方误差。

我们可以使用以下等式来测量每个模型的样本外误差方差

这样做给了我们

模型的样本外性能

我们看到贝叶斯和岭回归模型都能够防止过度拟合,并获得更好的样本外结果。

最后,我们将比较贝叶斯模型和 OLS 模型的估计噪声方差。

这给了我们

σ的模型估计

结论

当将贝叶斯方法应用于岭回归时,我们需要解决:我们如何处理控制正则化强度的超参数?

一种选择是使用点估计,其中超参数的值被选择来优化一些度量(例如,可能性或交叉验证)。但是这种方法违背了使用概率分布表示参数可信度的贝叶斯方法,特别是如果可能性在超参数的特定值附近不是很强的峰值。

通常使用的另一种选择是应用超参数先验的已知分布(例如半柯西分布)。这种方法给出了超参数的后验分布,并且在实践中可以很好地工作,但是先验分布的选择有些武断。

在这篇博客文章中,我们展示了一种不同的方法,我们选择了一个超参数先验分布,以便近似无信息。我们开发了在给定非信息先验的情况下计算标准预测统计的算法,并且我们通过一个小例子证明了它比使用选择的超参数的点估计来优化留一交叉验证更有利。

附录 A:与其他贝叶斯算法的比较

这里,我们将对 scikit-learn 的贝叶斯岭回归算法做一个简单的比较。

Scikit-learn 的算法利用共轭先验,因此仅限于使用伽马先验,这需要四个任意选择的小值超参数。此外,它需要参数α和λ的初始值,然后根据数据进行更新。

算法的性能可能对这些参数值的选择很敏感,scikit-learn 的文档提供了一个曲线拟合示例,其中默认值表现不佳。

相比之下,我们提出的算法不需要初始参数;并且因为超参数被积分,表现差的值对后验概率质量贡献很小。

我们可以看到,我们的方法处理曲线拟合的例子,不需要任何调整。

完整的曲线拟合对比示例可在 github/rnburn/bbai/blob/master/example/04-curve-fitting 的获得。

本帖最初发表于buildingblock.ai/bayesian-ridge-regression

如何建立一个代码搜索工具使用 PyTorch 变压器和骚扰

原文:https://towardsdatascience/how-to-build-a-code-search-tool-using-pytorch-transformers-and-annoy-29bc3920e6c7

利用联合文本和代码嵌入进行搜索。

根据 Unsplash 上马库斯·温克勒的照片修改

你有没有因为懒得自己写而在 google 上找一段代码片段?我们大多数人都是!那么从头开始构建自己的代码搜索工具怎么样?这就是我们将在这个项目中努力做的事情。我们将使用 StackOverflow 问题和相应代码样本的并行数据集来构建一个系统,该系统能够根据现有代码片段与自然语言表达的搜索查询的“匹配”程度来对它们进行排序。

如果你想尝试这种方法,在博客的末尾有一个 Colab 笔记本链接。

系统描述:

系统图:作者照片

我们试图建立一个系统,它能够接受用自然语言表达的问题,然后从成千上万的 Python 代码片段中返回与这个问题最匹配的代码片段。

它是如何工作的?

该系统将基于代码片段的学习嵌入和“如何做”问题的嵌入。搜索部分将使用 Annoy,这是 Python/C++中的近似最近邻实现。

数据:

我们将使用stat QC数据集,其中有从堆栈溢出中自动挖掘的(问题,代码片段)对。

数据集的样本如下所示:

问题:如何使用 python 从 MongoDB 中的 10 亿个文档中获取随机的单个文档?

代码:

import randomcollection = mongodb[""collection_name""]rand = random.random()  # rand will be a floating point between 0 to 1.
random_record = collection.find_one({ 'random' => { '$gte' => rand } })

数据集有 85,294 个单代码片段答案和 60,083 个多代码片段答案。

预处理:

代码和问题都是字符串,所以我们需要在将它们输入模型之前对它们进行标记化。因为我们是在处理代码,所以我们不能使用常规的预先训练好的记号赋予器,因此必须自己构建。

首先,我们需要我们的标记器来拆分特殊字符,如“_”或“=”,并正确地拆分 camelCase 变量名。

我们分两步走:

  • 在 camelCase 中,在特殊字符周围添加空格,在单词周围添加空格。
  • 用空格预标记训练一个拥抱脸标记器。

这将产生以下结果:

问题- >

如何使用 python 从 MongoDB 中的 10 亿个文档中获取一个随机的单个文档?

标记化问题- >

[‘[CLS]’,‘如何’,‘到’,‘得到’,’ a ‘,‘随机’,‘单个’,‘文档’,‘从’,’ 1 ‘,‘比尔’,’ # #离子’,‘文档’,‘在’,‘蒙戈’,’ db ‘,‘使用’,’ python ‘,’?‘,’[SEP]']

代码片段- >

class MyLabel(Label): pass    
class AwesomeApp(App):
    def build(self):
        return MyLabel()

令牌化代码->

[‘[CLS]’,’ class ‘,’ my ‘,’ label ‘,’(‘,’ label ‘,’)‘,’:‘,’ pass ‘,’ class ‘,’ awesome ‘,’ app ‘,’(‘,’ app ‘,’)‘,’:‘,’ def ‘,’ build ‘,’(‘,’ self ‘,’)‘,’:‘,’ return ‘,’ my ‘,’ label ‘,’(‘,’)‘,’,‘,’[SEP]']

ML 部分:

系统的 ML 部分。作者图解。

在这一部分中,我们将训练一个模型,它能够将一个字符串(代码片段或问题)映射到一个大小为 256 的固定维度向量。我们将应用于该输出向量的约束是,我们希望问题的向量与其对应的代码片段的向量之间的相似性高,而在所有其他情况下具有低的相似性。

我们使用双线性相似性度量:

其中 W 是可学习的参数。详见“通用音频表征对比学习”。

为了学习有用的嵌入,我们需要正面的例子,它们是成对的“如何做”问题和它们相应的代码片段。我们还需要一个反例,它将是该批中的所有其他向量。这意味着正对的表示将被推到更高的相似性得分,而我们将样本向量和批中所有不相关向量之间的相似性引导到更低的值。

x_i 和 y_j 是该批的嵌入向量。

我们希望批次矩阵尽可能接近恒等式。

这种进行对比学习的方法摘自上面提到的论文。它允许在某种程度上获得“自由”的反例,因为它们已经被计算为批处理的一部分。与其他方法(如三元组丢失)相比,它还有一个很大的优势,因为我们可以获得 batch_size -1 个负样本,而不是每个正样本只有一个负样本,这迫使编码器学习更多有区别的嵌入。

将文本输入映射到固定的 dim 向量的全部意义在于,它通过使用近似最近邻算法使搜索部分更加有效。

搜索部分:

一旦我们将所有的代码片段编码成向量,并建立一个模型以同样的方式编码一个新问题,我们就可以开始系统的搜索部分了。我们将使用一个名为的库来骚扰。

使用 Annoy 将允许我们在 O(log(n))时间内查询 n 个代码片段的数据集。

# We define the Annoy Indext = AnnoyIndex(len(samples[0]["vector"]), "angular")# We add all the vectors to the indexfor i, sample in enumerate(samples):
    t.add_item(i, sample["vector"])# We then build the trees for the approximate searcht.build(100)# We can use it to query the NN of a question vectorindexes = t.get_nns_by_vector(search_vector, n=3, search_k=-1)

搜索查询的示例结果:

如何转义 HTML 特殊字符?

# Search Result 1 -->
raw_html2 = raw_html.replace('\\n', '')

# Search Result 2 -->
def escape(htmlstring):
    escapes = {'\"': '"',
               '\'': ''',
               '<': '&lt;',
               '>': '&gt;'}
    # This is done first to prevent escaping other escapes.
    htmlstring = htmlstring.replace('&', '&amp;')
    for seq, esc in escapes.iteritems():
        htmlstring = htmlstring.replace(seq, esc)
    return htmlstring

# Search Result 3 -->
mytext.replace(r"\r\n", r"\n")

# Query encoded in 0.010133743286132812 seconds
# Search results found in in 0.00034046173095703125 seconds

如何唯一化列表?

# Search Result 1 -->
seen = set()
L = []
if 'some_item' not in seen:
                L.append('some_item')
                seen.add('some_item')

# Search Result 2 -->
def is_duplicate(a,b):
        if a['name'] == b['name'] and a['cost'] == b['cost'] and abs(int(a['cost']-b['cost'])) < 2:
                return True
        return False

newlist = []
for a in oldlist:
        isdupe = False
        for b in newlist:
                if is_duplicate(a,b):
                        isdupe = True
                        break
        if not isdupe:
                newlist.append(a)

# Search Result 3 -->
>>> L = [2, 1, 4, 3, 5, 1, 2, 1, 1, 6, 5]
>>> S = set()
>>> M = []
>>> for e in L:
...     if e in S:
...         continue
...     S.add(e)
...     M.append(e)
... 
>>> M
[2, 1, 4, 3, 5, 6]

M = list(set(L))

# Query encoded in 0.006329536437988281 seconds
# Search results found in in 0.0003654956817626953 seconds 

我们可以看到,这个系统可以在几毫秒内,从 145,000 个可能的答案中找到相关的代码片段。

结论

在这个小项目中,我们训练了一个 transformer 模型来预测文本和代码的嵌入。这些嵌入然后被用来建立一个 KNN 搜索索引使用近似最近邻在苦恼。通过使用更大的问题/代码数据集或通过对不同的对比学习策略进行基准测试,这种方法还可以进一步改进。

您可以通过克隆存储库来运行自己的查询:

  • https://github/CVxTz/code_search

或者通过运行这个 colab 笔记本:

  • https://colab . research . Google . com/drive/1 gagzoxivutyagxqol-7ny v2-AV _ ol VFD?usp =分享

参考资料:

  • 通用音频表征的对比学习
  • https://github/spotify/annoy

如何在 R 和 caret 中建立完整的分类模型

原文:https://towardsdatascience/how-to-build-a-complete-classification-model-in-r-and-caret-73c68c3392e1

机器学习

一个完整的例子,展示了如何使用 R 和脱字符包来运行分类任务

由托马斯·帕克在 Unsplash 拍摄的照片

r 是一种主要用于统计的编程语言,但它也为机器学习提供了有效的库。在本教程中,我描述了如何使用 r。

该任务包括以下步骤:

  • 问题定义
  • 数据集预处理
  • 模特培训
  • 模型评估

1 问题定义

这个例子的目的是通过 K-Neighbors 分类器来预测心脏病发作。这个例子使用了 hearts 数据集,该数据集在 CC0 公共领域许可下可在 Kaggle 上获得。

在我之前的文章中,我已经使用 scikit-learn 和 pycaret 用 Python 分析了这个数据集。在这篇文章中,我试图解决 r。

下图显示了数据集的摘录:

作者图片

作为输入特性,我考虑了所有的列,但是最后一列被命名为 output,我将其视为目标类。

为了解决这个问题,我使用了 caret 库,它可以按如下方式安装:

install.packages('caret')

caret 包(Cclass ificationAndREgressionTraining)对于分类和回归任务来说是一个非常有用的 R 包。它提供了预处理、模型训练、模型预测和模型评估的功能。

安装完成后,我如下导入插入符号包:

library(caret)

然后,我将 hearts 数据集作为数据帧加载:

df <- read.csv('heart.csv')

我还将种子设置为一个随机数,以使实验具有可重复性:

set.seed(12)

2 数据集预处理

现在,我转换数据集进行训练。我对数据集执行以下操作:

  • 编码输出列
  • 缩放和居中输入列
  • 将数据集分成训练集和测试集
  • 设置交叉验证方法

如前所述,我将输出列视为一个目标类,因此我将它编码如下:

df$output <- as.factor(df$output)

factor()函数将向量编码为类别或因子。

然后,我通过缩放和居中来规范化输入列,如下所示:

preProcess <- c("center","scale")

简单地说,我定义了一个预处理变量,它包括两个操作:居中和缩放。然后,我将把这个变量作为输入传递给训练函数。

现在,我准备通过使用 caret 库提供的createDataPartition()函数将数据集分成训练集和测试集:

i <- createDataPartition(y = df$output, times = 1, p = 0.8, list = FALSE)

该函数返回指定如何拆分数据的索引。我不得不 0.8 的百分比分裂。现在我分割数据集:

training_set <- df[i,]
test_set <- df[-i,]

最后,我通过定义以下变量来设置交叉验证,我将把这些变量作为训练函数的输入:

trControl <- trainControl(method = "repeatedcv",number = 10,repeats = 10)

我已经将方法设置为重复交叉验证,折叠次数设置为 10,重复次数设置为 10。

3 模型训练

我准备好训练模型了。我使用 caret 提供的train()函数如下:

model <- **train**(output ~ ., method='knn', data = training_set, metric='Accuracy',preProcess = preProcess, trControl=trControl)

我已经将模型设置为 knn (K-Nearest Neighbors),将数据设置为training_set,将优化度量设置为Accuracy,将预处理技术设置为之前定义的preProcess,将训练控制设置为之前定义的trControl变量。

训练过程真的很简单😃

4 模型评估

一旦模型被训练,我就可以评估它的性能。我使用 predict()函数来预测测试集的输出:

test_set$pred <- predict(model, test_set)

为了计算指标,我必须将输出转换成一个因子,如下所示:

test_set$factor_pred <- as.factor(test_set$pred)
test_set$factor_truth <- as.factor(test_set$output)

现在,我计算精度:

precision <- **posPredValue**(test_set$factor_truth, test_set$factor_pred)

召回:

recall <- **sensitivity**(test_set$factor_truth, test_set$factor_pred)

混乱矩阵:

cm <- **confusionMatrix**(test_set$pred, test_set$output)

精确度可以从混淆矩阵中提取:

accuracy <- cm$overall[1]

我还计算了对应于混淆矩阵的表:

confusion_matrix <- cm$table

作者图片

为了绘制 ROC 曲线,我使用 pROC 库:

library(pROC)
test_set$pred <- predict(model, test_set,probability=TRUE)
roc_curve = **roc**(test_set$output, predictor=factor(test_set$pred,ordered = TRUE))
plot(roc_curve, col="red", lwd=3)

roc()函数接收概率形式的预测,所以我通过 predict()函数设置probability=TRUE再次计算预测。

作者图片

roc()函数并不绘制实际的 ROC 曲线,而是绘制灵敏度对特异性曲线。实际的 ROC 曲线绘制的是灵敏度对特异性。

摘要

恭喜你!您刚刚学习了如何在 R 中运行一个完整的分类任务!该示例使用了 caret 包,其中包括用于模型定型和评估的函数。

您可以在我的 Github 资源库中找到本文中描述的完整示例。

请继续关注,了解一些关于 R 的新知识!

如果你读到这里,对我来说,今天已经很多了。谢谢!你可以在这篇文章中读到更多关于我的信息。

相关文章

https://medium/geekculture/moving-from-python-to-r-how-to-build-a-simple-regression-model-7d0f8ff79625

来自社区

安吉莉卡·洛·杜卡

机器学习

View list6 stories

当归罗杜卡

评估指标

View list2 stories

当归罗杜卡

数据预处理

View list12 stories

参考

ROC 曲线的一些 R 包

如何不用代码轻松构建一个计算机视觉项目

原文:https://towardsdatascience/how-to-build-a-computer-vision-project-easy-and-without-code-d6fb0462f41

一个初学者友好的,无代码的水果探测器解决方案。还有,把模型上传到网上给大家看看!

凯文·克罗斯比在 Unsplash 上拍摄的照片

⚠️读了我在⚠️博客中的原帖

要不要建个 app 检测什么东西?猫对狗,检测一个水果有多熟,在图像中寻找品牌?

你想仅仅标记一些图像,制作一个模型并测试它而不需要做很多工作吗?

如果你的答案是肯定的,那么这篇文章是给你的!

我将向您展示如何为您的探测器构建一个应用程序,并将其放入互联网供所有人查看。

最后,你会有这样的东西给你的同事和朋友看:🤗https://huggingface.co/spaces/Kili/plastic_in_river

您将能够上传一个测试图像,模型将返回盒子和标签。太神奇了!⚡️

免责声明:你需要在你的电脑上安装 git 来上传文件到 HuggingFace Spaces。如果没有,也不用担心!它非常容易安装。跟着这个:https://git-scm/downloads

这将是该项目的工作流程:

项目的工作流程

  1. 首先,你必须为你的项目收集图像。要不要从长颈鹿身上检测出斑马?获取两只动物的图像。无论你想探测什么,你都需要图像。这个点在工作流程中是白色的,意味着你必须在你的电脑上完成工作。
  2. 标签图像在工作流程中显示为蓝色,这是因为您将使用 Datature 的标签工具。 Datature 是一家专门为数据标注和模型训练构建用户友好工具的公司。
  3. 您还将使用 Datature 的工具来训练一个模型,以一种无代码且非常简单的方式。
  4. 一旦模型被训练,你将把它下载到你的电脑,把所有的文件放在一起(这些文件我会提供给你)
  5. 当所有文件放在一起时,您将把它们上传到🤗HuggingFace Spaces 和您的模型就可以使用了!🚀

1.查找图像

在计算机视觉项目中,我们需要做的第一件事是收集图像。如果我们想训练一个深度神经网络,我们需要成千上万的图像。

幸运的是, Datature 使用非常先进的模型,并且可能经过预先训练,这意味着我们只需要从头开始训练模型时所需图像的一小部分。

每个类大约有 100 张图片就足够了。例如,如果你想检测 t 恤和裤子,你需要 100 张 t 恤和 100 张裤子的图像。这个例子当然也适用于其他情况。例如,你可以有 100 张有猫和狗的图片,所以你得到 100 个猫的例子和 100 个狗的例子。

如果存在类别不平衡也没关系,例如,如果您的项目是检测晴天和多云,您可以有 120 张晴天图像和 100 张多云图像。但重要的是,模型有最少数量的图像,100 左右应该足够了。

收集所有图像,并将它们存储在电脑的一个文件夹中。

2.标签图像

在数据中创建一个账户,并为您的用例创建一个项目。来自 Datature 团队的这个教程解释了如何创建一个项目和标记图像。

https://data ture . io/blog/train-and-visualize-face-mask-detection-model

这篇博文详细介绍了如何:

  • 创建 Datature Nexus 帐户(免费试用)
  • 创建项目
  • 上传图像
  • 创建类
  • 注释图像
  • 在图像中创建矩形框
  • 给每个盒子分配一个类别

对于每个图像,您将注释一个框(对象在哪里?)和一个类(这个对象是什么?).

只读标签部分,之后,在项目概述中,你应该看到你的图像统计,标签分布等。例如,项目概述应该是这样的:

标注后的项目概述示例

在这个例子中,我有一个名为香蕉的项目,我标记了 16 个图像,我有 3 个类别:成熟、可食用和无效。这只是一个例子,所以要确保每门课至少有 100 个例子!

3.火车模型

一旦我们有了图像,我们就可以训练我们的模型了!我们必须在 Nexus 中创建一个“工作流”。尝试使用上一节的文档和博客文章:https://data ture . io/blog/train-and-visualize-face-mask-detection-model来执行以下步骤:

  • 建立训练工作流程:选择训练-测试分流比,选择增强,选择模型设置
  • 火车模型
  • 监控模型:丢失、精度和召回
  • 导出模型

该模型将需要大约 1 小时的训练,之后你应该会看到这一点

完成培训示例

转到工件并下载张量流模型

工件下载示例

当在计算机中导出一个. zip 文件并带有训练好的模型参数时,本节就完成了。

4.创建一个🤗HuggingFace 帐户

模型已经训练好了,我们已经把它作为. zip 文件下载到我们的计算机上。但是我们如何与之互动呢?

我们可以通过上传到 Huggingface Spaces 与它互动。我们还需要一些网站前端的代码,这些代码你可以在本教程中找到。

Huggingface Spaces 是 Huggingface 的一个网站,人们可以在这里展示自己的模特并与她们互动。按“最喜欢”对空间进行排序,并浏览一些空间:)

这些是步骤

  1. 创建 Huggingface 帐户
  2. 创建一个空间
  3. 为空间写一个名称。请记住,该网站将是公开的,因此请选择一个与该应用程序的功能相匹配的名称!例如:香蕉分析或类似的东西
  4. 选择 Streamlit 作为 Space SDK
  5. 选择公共
  6. 完成空间分配后,将存储库克隆到本地计算机上的一个文件夹中
  7. 或者,使用文本编辑器打开 README.md 并更改项目的表情符号

5.收集所有文件并上传到🤗拥抱面部空间

现在我们有了属于🤗我们电脑里的空间。我们必须将所有文件复制到那里,并将所有内容上传到🤗使用 git 的空间。

首先,将模型文件(saved_model/ folder,label_map.pbtxt 文件)复制到该文件夹中

然后,在文件夹中创建这个 Gist 中的 3 个文件:https://Gist . github . com/anebz/2 f 62 caea B1 f 24 AABB 9 F5 D1 a 60 a4 C2 d 25

app.py

该文件包含上传图像、加载模型、进行预处理以及从模型中获取预测的代码。

请注意带有#TODO 的行,您必须更改这些行!

尤其是第 112–115 行中的 color_map,这些是每个类的方框的颜色。打开 label_map.pbtxt 文件,查看为每个类分配了什么 label_id,并使用此 label_id 为颜色分配 RGB 值。在这个例子中,我只有两个类,因此只有两种颜色。如果有更多的类,请按照示例的格式添加更多的行:

1: [255, 0, 0],

记住,除了最后一行,每一行的末尾都要有一个逗号!

packages.txtrequirements.txt 是将要安装在🤗空间。这些文件非常重要,没有它们代码将无法运行。

最终,文件夹应该是这样的

文件夹概述

  • saved_model/ 是位于。你之前从 Datature 下载的 zip 文件
  • label_map.pbtxt 在。你之前从 Datature 下载的 zip 文件
  • 。gitattributes 已经在文件夹中了🤗空间
  • README.md 在您从🤗空间
  • app.py 是你用我在文章前面写的代码创建的文件
  • requirements.txt 是您用我在本文前面写的代码行创建的文件
  • packages.txt 是您用我在本文前面写的代码行创建的文件

一旦我们需要的所有文件都在文件夹中,我们就可以把它推到🤗空间。打开 Git Bash 并逐个粘贴这些命令:

  • git 添加。
  • git commit -m“添加的文件”
  • git 推送

该应用程序将需要一些时间来上传文件,尤其是模型文件。git 推送完成后🤗Space 需要几分钟来构建应用程序,并在中显示我们的应用程序🤗空间。

如果 git 显示关于模型文件太大的错误,请查看这些帖子:https://discuse . hugging face . co/t/uploading-large-files-5gb-to-HF-spaces/12001/4和https://discuse . hugging face . co/t/uploading-files-big-than-5gb-to-model-hub/4081/6

最后你的 app 会出现类似这样的:https://huggingface.co/spaces/anebz/test

你可以上传一张图片,模型需要几秒钟加载,然后你会看到预测。项目完成!🏋️

结论

你的项目完成了,恭喜你!!你能够从零开始快速创建一个应用程序,只使用几百张图片。你只需要在你的电脑上安装 Git,不需要 Python 或者不需要编写任何代码。

⚠️‼️如果你试图做这个项目,遇到错误或困难,不要犹豫,与我联系!我将非常乐意帮助你。

  • https://twitter/anebzt
  • github:https://github/anebz/

感谢您的阅读!

如何从零开始构建数据湖—第 2 部分:连接组件

原文:https://towardsdatascience/how-to-build-a-data-lake-from-scratch-part-2-connecting-the-components-1bc659cb3f4f

如何利用流行技术构建数据工程沙盒的完整教程

在这一系列文章中,我将指导您建立自己的数据湖基础设施作为数据工程沙箱。在这一部分中,我将展示如何连接我们的数据湖基础设施的各种服务。在第一部分中,我已经展示了如何用 docker 托管必要的服务,并解释了各个配置选项。

一旦组件“相互对话”,您将能够实施自己的数据工作流,并将技术和大数据方法用于自我测试!您将能够利用该平台来了解设置、实施附带项目、概念验证、使用案例或使用这些技术来学习其他教程。大多数数据任务可以通过这种基础设施实现自动化。在“生产”环境中,服务也可以作为 docker 化的服务托管在 AWS EC2 实例上,但是对于我们的沙箱,使用 docker 在本地托管它们就足够了。

图片由 Unsplash 的加勒特·西尔斯拍摄

我们使用以下技术组合:

  • Apache NiFi 来处理和分发数据。
  • Apache NiFi Registry 用于存储、管理和版本控制 NiFi 资源。
  • Apache Airflow 以编程方式创作、安排和监控工作流。
  • Postgres 作为一个对象关系数据库。
  • pgAdmin 作为 postgres 数据库的管理和开发平台。
  • MinIO 作为本地托管的、S3 兼容的对象存储。
  • 码头工人来主持我们的服务。

著名的Hello world!最早是在 Brian Kernigsham 的《语言 B 入门教程》一书中提到的,后来因《C 编程语言》一书而出名(来源)。如今,许多教程仍然使用将Hello world!写入终端的任务来检查用户是否已经完成了设置阶段,并准备好投入编码挑战。

在本文中,我们将实现服务间通信的Hello world!:通过设置服务交互的超级简单的例子。我将指导您为每一对需要相互通信的服务建立连接。之后,您将能够继续自己的工作,充分利用数据湖基础设施的全部功能。

如果您还没有设置 docker 容器,也还没有运行您的组件,那么请继续阅读本系列的第 1 部分。我们将从停止的地方继续:我们将 docker-compose.yml 文件从这里复制到我们的本地计算机,并使用docker-compose up启动服务。

到目前为止,我们的服务仍未连接,但是我们的目标基础设施将如下所示:

数据湖组件—由作者创建的图像。维基百科的图标。

在以下章节中,我们将连接:

  1. postgres 数据库的 pgAdmin
  2. Apache NiFi 到 NiFi 注册表(反之亦然)
  3. Apache NiFi 到 postgres 数据库
  4. 阿帕奇 NiFi 到 MinIO
  5. 到 postgres 数据库的 Apache 气流
  6. 阿帕奇气流到阿帕奇尼菲
  7. 阿帕奇气流到 MinIO

让我们直接进入 pgAdmin 的设置吧!

pgAdmin

服务运行后,您可以在浏览器中访问 pg admin:http://localhost:5050/

如果您在启动 docker 容器后第一次访问该服务,它会要求您设置一个主密码。选择一个你能记住的密码。

我们想通过连接到 postgres 数据库并对该数据库运行一个简单的查询来从 pgAdmin 对其说Hello world!

pgAdmin:你好,postgres 数据库

单击页面中间“快速链接”下的“添加新服务器”,或者右键单击左上角的“服务器”,然后选择“创建”->“服务器…”。

我们需要配置连接细节以添加新的数据库服务器:

  1. 常规选项卡中:为您的数据库服务器选择一个名称,例如postgres_db
  2. 连接选项卡中:“主机名/地址”是而不是“本地主机”,而是postgres 容器的 IP 地址——因为容器需要通过 docker 网络相互通信。因为我们在一个用户定义的网络(dataworld)上,我们可以只使用主机名mypostgres而不是固定的 IP 地址,让 docker 在后台处理 DNS 解析。
  3. 连接页签中:端口是 postgres 数据库的标准应用端口— 5432
  4. 连接选项卡中:用户名和密码在docker-compose.yml中被指定为 postgres 服务的环境变量(如果还没有更改的话,则为postgrespostgres)。

连接设置—由作者创建的图像。

除了使用主机名,我们还可以通过获取 postgres 容器的 ID 并检查它以检索其 IP 地址来标识我们的数据库:

获取容器 ID:

检查容器,将返回的行过滤为 IP 地址为:

这是相当麻烦的,特别是因为每当我们重启我们的容器时,我们将不得不重新开始,因为 docker 网络中容器的 IP 地址可能会改变。使用主机名并让 Docker 在我们在 docker-compose.yml 中定义的用户定义的网络中解析它要容易得多。

连接到数据库后,我们现在可以运行查询了。右击数据库,选择查询工具

pgAdmin 中的查询工具—由作者创建的图像。

为了测试一切是否正常,让我们运行下面的查询来检查连接——我们自己的小版本**“hello world!”。sql** :

恭喜你!PgAdmin 现在连接到 postgres 数据库了!

阿帕奇尼菲

如果您的 docker 服务正在运行,您将能够通过http://localhost:8091/NiFi/联系到 NiFi。注意:您可能会看到消息The Flow Controller is initializing the Data Flow。NiFi 将需要一分钟(在您启动服务之后)才能到达应用程序,因为领导者选举周期需要首先完成。

我们希望连接到:

  • NiFi 注册表
  • postgres 数据库
  • 米尼奥

你好,NiFi 注册中心

为了将 NiFi 连接到 registry,我们首先需要在 registry 中创建一个“bucket”来存储和组织我们的数据流。继续操作并打开位于http://localhost:18080/nifi-registry/的注册表。

  1. 单击窗口右上角的扳手符号。
  2. 点击右侧的“新桶”。
  3. 为您的存储桶输入一个名称,例如myfirstbucket

NiFi 注册表—创建新的存储桶—图片由作者创建。

我们现在可以将 NiFi 的流程组和流程存储在新创建的 bucket 中。

请注意,默认情况下没有配置任何权限。在这个实例中,有权访问注册表的每个人都可以查看、创建和修改存储桶。有关保护系统的信息,请参见系统管理员指南。

前往http://localhost:8091/nifi/,点击右上角的three bars进入controller setting。然后点击选项卡registry client和右侧的plus-symbol

选择任何你喜欢的名字,并添加以下网址:http://myregistry:18080。Docker 将再次在 docker 网络上将主机名解析为容器的 IP 地址。

Nifi —添加注册中心客户端—由作者创建的图像。

既然我们已经向 NiFi 添加了注册客户机,那么让我们测试它的功能:创建一个新的进程组,其中包含一个或两个虚拟处理器。

右键点击流程组,选择Version->-Start version control:

Nifi —启动过程组的版本控制—由作者创建的图像。

现在我们能够选择我们想要使用哪个注册中心和存储桶来进行版本控制(如果我们已经配置/创建了多个的话),以及在注册中心中应该以哪个名称对流程组进行版本控制。输入名称,还可以选择输入描述和版本注释。

NiFi —将流文件版本保存到由作者创建的注册表图像中。

单击“保存”后,您会注意到流程组的左上角有一个绿色复选标记。这意味着组的当前状态被保存到桶中!如果我们更改了内部的某些内容,例如将处理器移动到另一个位置、更改某些配置或添加/删除处理器,复选标记将会被一个灰色的星号取代。这个星号象征着对底层流程的一些未提交的更改。

NiFi —过程组版本控制状态的变化—由作者创建的图像。

要在注册表的桶中存储最新的更改,右键单击处理器组,然后单击Version - > Commit local changes。绿色复选标记将再次出现。如果我们想要放弃更改,我们可以选择Revert local changes,过程组将被重置为保存到注册表的最新版本。Local(在注册表的上下文中)是指 Nifi 实例,而不是您的本地计算机。

NiFi —提交本地更改—图片由作者创建。

我们现在已经有了 Apache NiFi 数据流和 ETL 管道的完整版本控制系统!我们可以检查本地更改,将它们提交到注册表中,或者从注册表中取出最新版本的进程组。对我们的工作进行版本控制,并且能够跟踪变更,这极大地改善了我们的开发工作!

当我们创建一个新的进程组时,我们甚至可以从注册表中导入一个存储的进程组的特定版本(作为一个模板):

NiFi —从注册表导入模板—由作者创建的图像。

在接下来的几章中,当我们连接到其他服务时,请随意使用这个特性!

Apache NiFi:你好 postgres 数据库

为了能够查询 postgres 数据库,我们需要配置:

  • 一个DBCPConnectionPool,它包含数据库的连接细节
  • 微型工作流程:
  1. 第一个处理器创建一个空的流文件来触发后续的处理器
  2. 第二处理器执行对数据库的查询
  3. 第三个处理器用于在查询执行后查看队列中的数据。

JDBC 控制器 postgres

当创建控制器服务时,总是在需要它们的最顶层进程组中创建它们——甚至可能是根进程组。控制器服务只能在创建它们的组以及所有后续子组中访问。

为了能够设置连接到 postgres 数据库的控制器服务,我们需要下载 postgres 的当前 JDBC 驱动程序,例如从这里。下载完成后,将postgresql-42.3.1.jar文件(或您使用的任何版本)复制到 docker 挂载的目录/nifi/jdbc/。这个过程对于任何其他数据库都是一样的,我们总是需要将 NiFi 指向 jdbc-driver jar-file。

通过左侧当前过程组的gear-symbol按钮进入 NiFi 中的控制器配置。在Controller services选项卡中,点击右侧的plus-symbol添加一个新控制器。从可用控制器的长列表中选择DBCPConnectionPool并点击Add

编辑新创建的控制器的属性,如下所示:

  • 数据库连接 URL: jdbc:postgresql://mypostgres:5432/postgres
  • 数据库驱动类名:org.postgresql.Driver
  • 数据库驱动位置:/opt/nifi/nifi-current/jdbc/postgresql-42.3.1.jar(注意,我们配置的是 docker 容器内部的路径,而不是本地机器上的路径!)
  • 数据库用户:postgres(或您在设置过程中更改的任何名称)
  • 密码:postgres(或您在设置过程中更改的任何密码)

NiFi—JDBC 控制器的属性—微型工作流程:

点击Apply并通过选择描述新创建的控制器的线的lightning-symbol并在打开的窗口中选择Enable来启用服务。

处理器

为此版本的Hello world!创建三个处理器:

  1. 处理器:GenerateFlowFile——作为我们数据流的起点。
  2. 处理器:ExecuteSQL —在 postgres 数据库上执行查询。
  3. Processor: RouteOnAttribute —作为一个虚拟处理器,这样我们可以查看队列中的流文件。

success流程按顺序连接处理器。

生成流文件

GenerateFlowFile处理器中,将调度选项Run Schedule更改为60 sec,并将调度选项Execution更改为Primary node。这样,我们可以确保无论何时启动处理器时,主节点都会创建一个流文件,从而触发我们的 ETL 管道。每隔 60 秒就会创建另一个流文件——除非我们事先停止了处理器。这是一个简单的技巧,可以精确地触发我们的流水线一次:在调度时间再次完成之前启动然后停止GenerateFlowFile处理器。

NiFi —调度处理器—图片由作者创建。

执行 SQL

ExecuteSQL处理器中,选中主配置中failure旁边的复选框,以便在查询失败时自动终止进程。在properties选项卡中,将Database Connection Pooling Service属性更改为新创建的postgresql_connectionpool,并将字段SQL select query编辑为数据库连接的测试查询。一个例子可能是:

如果您的 DBCPConnectionPool 没有出现在可用的控制器服务列表中,请确保您已经在同一个处理器组或其上的任何处理器组中创建了 DBCPConnectionPool。不能选择当前组之外或之下的流程组的控制器服务!

NiFi —配置 executeSQL 处理器—图片由作者创建。

我们不需要配置最后一个处理器,因为我们只是将它作为一个替身来使用,以便能够检查通向它的队列中创建的流文件。您的处理器流程应该如下所示:

NiFi —处理器流程—图片由作者创建。

一旦启动了前两个处理器,就会创建一个流文件,并触发 ExecuteSQL 处理器。ExecuteSQL 处理器之后的流文件现在将包含我们从数据库中查询的数据。您可以通过右击队列并选择List queue来检查数据。您可以下载队列中的每个项目,或者通过单击右侧的符号在浏览器中查看其内容。

NiFi —检查队列的流文件—作者创建的图像。

浏览器检查(格式化视图)中的流文件内容如下所示:

NiFi —队列中的文件内容—作者创建的图像。

这意味着我们已经成功地从 NiFi 查询了数据库!我们离全功能数据湖架构又近了一步!

阿帕奇·尼菲:你好,米尼奥

在我们连接 NiFi 之前,我们必须配置 MinIO。您可以在浏览器中的http://localhost:9001/dashboard下访问该服务。用户名和密码通过环境参数MINIO_ACCESS_KEYMINIO_SECRET_KEY在 docker-compose.yml 文件中配置。除非您在创建容器之前更改了它们,否则它们是minio_adminminio_password

配置 MinIO

点击左侧导航栏中的Buckets,点击右上角的Create Bucket。为您的存储桶选择一个名称,例如miniobucket,保留默认配置并点击Save。请注意如何命名您的存储桶,名称必须在 3 到 63 个字符之间,并且只能由小写字母、数字、点和连字符组成!

MinIO bucket —作者创建的图像。

创建 bucket 后,在本地创建一个名为minio_testfile.txt的新文件,内容为This is the content of a testfile from MinIO.

选择您的桶并点击Browse。创建一个名为test的新目录,并在其中点击Upload file符号上传minio_testfile.txt。在下一步中,我们将配置 NiFi 从 MinIO 中检索这个文件!

MinIO 桶内容—由作者创建的图像。

配置 NiFi

为了能够在 NiFi 中创建从 MinIO 检索文件的管道,我们还需要配置 NiFi。在本地绑定挂载的目录/nifi/credentials/中创建一个名为credentials.properties的文件。

该文件的内容是 MinIO 的环境变量的值——如果您没有在您的 docker-compose.yml 文件中更改它们,credentials.properties文件的内容将是:

如有必要,更改键值。

转到http://localhost:8091/nifi/并创建一个新的进程组。在组内,为GenerateFlowFileFetchS3ObjectRouteOnAttribute类型各创建一个处理器。用success关系连接处理器。由于 MinIO 与 S3 兼容,我们可以将 NiFi 的所有 S3 处理器与 MinIO 端点一起使用!

NiFi —处理器流程—图片由作者创建。

再次更改GenerateFlowFile处理器的调度选项Run Schedule60 sec以及调度选项ExecutionPrimary node。这样,我们可以确保无论何时启动处理器,都会创建一个流文件,触发我们的 ETL 管道。

FetchS3Object处理器中,勾选复选框以自动终止failure上的关系,并配置以下属性:

  • 桶:miniobucket
  • 对象键:test/testfile.txt(我们需要配置桶内的完整路径,包括目录)
  • 端点覆盖 URL: http://myminio:9000(用我们的私有 MinIO 实例之一覆盖 AWS S3 的端点)
  • 凭证文件:/opt/nifi/nifi-current/credentials/credentials.properties(容器内指定的路径)

NiFi—fetchs 3 对象处理器配置—图片由作者创建。

如果您想为 NiFi 创建一个单独的技术 MinIO 用户,您只需更新本地目录中的credentials.properties文件。

运行您的管道——您可以通过启动和停止GenerateFlowFile处理器或右键单击它并选择“恰好运行一次”选项来完成此操作。通过右键单击通向RouteOnAttribute处理器的队列,我们可以检查流文件。

NiFi —检查队列的流文件—作者创建的图像。

我们现在可以验证我们的文件确实被 NiFi 检索和加载了:

NiFi —流文件内容—由作者创建的图像。

恭喜,我们又连接了两个服务!我们现在可以从 MinIO 和 postgres 数据库中检索和写入数据。如果我们以后从 MinIO 切换到实际的 S3 存储,我们只需删除被覆盖的端点 URL 并更新我们的凭证文件。

气流

为了让 Airflow 能够连接到 MinIO(以及 S3 或其他 S3 兼容的存储设备),我们需要在 Airflow 服务上安装一个 python 包。我们可以通过挂载一个requirements.txt文件来做到这一点。在本地挂载的目录(./airflow/requirements/requirements.txt)中创建以下文件,内容如下:

创建文件后,我们需要重启 docker 服务。启动时,Airflow 会自动安装文件中提到的所有软件包。当 docker 检查必要的包时,这可能会使启动延迟几秒钟,但不会太长。

一旦你完成了这个准备步骤,让我们到达气流中的Hello world!

阿帕奇气流:你好 postgres 数据库

在我们创建任何代码之前,我们需要在 Airflow 中配置连接细节。在http://localhost:8085/admin/的浏览器中打开服务,点击顶栏中的Admin - > Connections。默认情况下,Airflow 附带了许多连接,但是让我们为我们的目的创建一个新的连接。

点击Create,填写必要的详细信息:

  • Conn Id : mypostgres_connection -稍后我们可以用它来检索连接细节的 ID。
  • Conn Type : Postgres -从下拉菜单中选择。
  • Host : mypostgres - Docker 将解析主机名。
  • Schema : postgres -数据库名称(该标签具有误导性)
  • Login : postgres -或者您在 docker-compose.yml 文件中设置的用户名。
  • Password : postgres -或者您在 docker-compose.yml 文件中设置的任何密码。
  • Port:5432-docker 网络中数据库的标准端口。

点击保存:

气流连接-由 autor 创建的图像。

现在我们可以开始写 DAG 了。DAG(有向无环图)是气流的核心概念,它定义了任务、它们的依赖关系和时间表(在这里阅读更多内容)。

DAG 指定任务,更重要的是,指定任务应该执行的顺序。我们甚至可以将任务配置为仅在一个(或多个)先前任务失败时执行。Airflow 附带了许多所谓的任务“操作符”——这意味着我们可以用 Python、Bash、Druid、Hive、MSSQL 甚至 PostgreSQL 等等编写任务!所有 Dag 都是 Python 文件,但是操作符中的代码取决于操作符的类型。

例如,我们可以使用 postgres 操作符来执行 postgres 数据库中的 SQL 代码。或者,我们可以使用 python 操作符编写一个小的 python 程序,该程序反过来在数据库上执行查询。我们选择哪种方案取决于我们的用例。为了这个Hello postgres database!,让我们创建一个简单的 postgres 操作符,它将在我们的数据库中创建一个空表。

注意:根据您的 Airflow 版本,您需要不同的导入路径。本文的 docker-compose.yml 文件中使用的 docker 映像使用了旧版本1.10.9。我在代码摘录中包含了新的 Airflow 版本的导入路径。

在本地挂载的目录下创建一个文件:airflow/dags/hello_postgres.py,内容如下:

为了能够多次执行 DAG,我们在 DAG 中有两个任务:第一个任务删除已经存在的表,第二个任务创建表。如果我们不包括第一个任务,DAG 将在第二次和任何后续执行中失败,因为它无法成功执行创建查询。通过参数postgres_conn_id传递连接细节,我们不必担心代码中的主机名、用户名或密码。

保存文件,等待它出现在你的网页浏览器的DAGS视图中。根据您的 DAG,这可能需要一些时间。一旦它被列出,在左边激活它,并点击“触发 DAG”在右手边。

我们现在可以在 pgadmin 的界面中验证创建的表:

pgAdmin —表格的验证—由作者创建的图像。

恭喜你!我们现在能够从 Airflow 调度任务来执行数据库上的代码!

阿帕奇气流:你好阿帕奇尼菲

从 Airflow DAG 连接到 NiFi 使我们能够更新处理器属性、更改处理器的内容(如 sql 语句)、启动或停止处理器、列出/更改/启动控制器等等。Apache NiFi 为多种配置目的提供了一个深入的 REST-API。我们可以检索和配置对象,如控制器、流、处理器、处理器组、端口、标签、漏斗、策略,甚至将事务提交到特定的输入端口。对于我们的Hello world!目的,我们将创建一个简单的 GET 请求。您是使用 API 的包装库,如 nipyapi 还是使用官方 REST-API 编写自己的逻辑和请求,取决于您的用例。我个人喜欢直接使用 REST API,因为它的文档非常详细。

首先,让我们为 NiFi 服务创建一个气流连接,如下所示:

  • Conn ID : mynifi_connection
  • Conn Type : Postgres由于没有NiFi连接类型,因此我们使用 postgres 作为替身。
  • Host : http://mynifi
  • Port : 8080这是网络内部的端口,不是我们对外映射的那个!

气流连接-由 autor 创建的图像。

接下来,我们需要创建一个 DAG。我利用请求库来创建对GET /nifi-api/processors/{id} REST-API 端点的请求。在文档中我们可以看到必要的 URI 和预期的回报——一个 ProcessorEntity JSON 对象:

NiFi REST API 文档—由 autor 创建的图像。

为了检索连接细节并在脚本中构建我们的 URI,我们使用了 Airflow 的 BaseHook 模块,并将我们的连接 ID ( mynifi_connection)传递给它。如果您使用下面的脚本,不要忘记将 processor_id 字符串改为您自己的!

根据您在生产中的设置,您将首先需要通过端点POST /nifi-api/access/token检索带有用户名/密码组合的访问令牌。之后,您必须在下面的代码中添加不记名令牌。幸运的是,在我们简化的设置中,这是不必要的。我们可以对 REST API 进行未经验证的调用,如下所示:

如果您按照说明操作,您将能够在 DAG 的日志中看到以下信息行:

如果是,那么恭喜您,我们连接了服务!您现在可以基于这个Hello world!构建工具和 API 调用来配置处理器或启动/停止处理器。如果您有进一步的兴趣,查看我的文章,了解如何通过执行以下模式将气流与成熟的 ETL 管道连接起来:

  1. 预定气流 DAG 执行准备任务,
  2. 气流触发了 Apache NiFi 中的处理器,
  3. NiFi 执行一个 ETL 过程,
  4. 气流等待 NiFi 完成,
  5. 气流继续执行其他任务。

但是够了,下一章在等着你!我们就要完成了,所以如果你已经走了这么远,感谢你的关注!我不会耽搁你太久——让我们一起完成这个项目和我们的下一(也是最后一)章吧!

阿帕奇气流:你好米尼奥/S3

Airflow 提供了一个 S3Hook,我们可以使用它无缝连接到 S3 或 S3 兼容的存储设备,如 MinIO!如前所述,为了使用钩子,我们需要在我们的 Airflow 服务上安装包boto3,方法是在我们的本地airflow/requirements/requirements.txt文件中添加一行boto3,并重启 Airflow docker 服务。虽然我们不会直接导入boto3,但如果没有它,我们将无法使用 Airflow 的airflow.hooks.S3_hook模块。

重启气流后,在Admin->-ConnectionsGUI 下建立新的连接:

  • Conn ID : myminio_connection
  • Conn Type : S3由于没有NiFi连接类型,因此我们使用 postgres 作为替身。
  • Extra:由以下 JSON 组成:

不要忘记用您自己的密钥替换访问密钥,您可能已经在您的 docker-compose.yml 文件中覆盖了这些密钥。

气流连接——图片由作者创作。

为了最初在 MinIO 中与文件交互,我们将实现两个简单的操作:将文件写入 MinIO 和从 MinIO 中的文件读取。为此,S3Hook 提供了两个简单易用的函数:load_fileread_key

在您的本地airflow/dags存储库中创建一个新的 DAG(例如,名为hello_minio.py)并复制粘贴下面的代码。第一个任务将把一个名为my-test-upload-file.txt的文件上传到我们的 MinIO bucket 中的test目录。

执行 DAG,完成后,检查操作是否成功:

  1. 在 MinIO 中,您应该在test目录的miniobucket桶中找到一个新文件。
  2. 在任务的气流日志中,您应该能够看到下面的行File contents: 'This is the content of a testfile from MinIO.'.,描述了之前测试文件的文件内容。请注意,我们在这里使用的文件与我们在前面的 Hello-MinIO-from-NiFi 示例中为 NiFi 使用的文件相同。

连接设置完成后,我们现在可以开始使用连接的组件了!

回顾和总结想法

在这篇文章中,我们了解到

  • 如何配置我们的服务,
  • 如何把我们的服务互相连接起来,
  • 如何利用整体基础设施和
  • 服务之间如何交互和通信。

我邀请您在这个超级简单但广泛的基础设施上进行测试、试验和实现概念验证。大多数数据工程任务都可以使用现有的工具来实现!

作为一个快速提醒,我们可以使用

  • Apache NiFi 处理和分发数据。
  • Apache NiFi Registry 用于存储、管理和版本控制 NiFi 资源。
  • Apache Airflow 以编程方式创作、安排和监控工作流。
  • PostgreSQL 作为对象关系数据库。
  • 作为 PostgreSQL 的管理和开发平台。
  • MinIO 作为对象存储——向来自 minIO 的人们大声疾呼,因为他们的社区版拥有标准版和企业版的所有功能!
  • 主持我们的服务。

一如既往,我们永远不会停止学习,所以如果您想了解更多,请随时查看以下链接

  • 这个系列的第一部分
  • Docker 的自定义桥
  • 码头工人的集装箱及其命名的重要性
  • Docker 的重启策略
  • Docker 的环境变量在 compose
  • 资源、客户端和会话之间的 boto3 差异。
  • 如何将气流与 NiFi ETL 管道连接
  • 阿帕奇气流
  • 阿帕奇尼菲
  • Apache NiFi 注册表
  • Nifi 注册管理机构的系统管理员指南
  • PostgreSQL
  • pgAdmin
  • MinIO

如何构建一个不会回来困扰你的数据产品

原文:https://towardsdatascience/how-to-build-a-data-product-that-wont-come-back-to-haunt-you-1a220f4c75fb

作者图片

当数据科学遇到生产工程

回想一下,您曾被要求将数据科学分析转变为可重复、受支持的报告或仪表板,以适应贵公司的生产数据管道和数据架构。也许你之前进行了原型分析,该解决方案信息丰富且运行良好,因此你的老板要求你将其投入生产。也许你发现自己不断地为相同类型的分析、培训和测试新模型重新提取数据,你想自动化整个过程以节省宝贵的时间

或者,您的生产数据产品可能会遇到问题。也许你有数据科学支持的仪表板,你已经开发并投入生产,但用户对它们越来越失望,并失去信任。也许你会发现自己在浪费时间来支持现有的生产仪表盘和报告,这阻碍了你从事更新、更有趣的项目的能力。

将数据产品投入生产本身就是一门艺术。如果做得好,自动化可以提高数据科学团队工作的准确性、可信度和速度。如果做得不好,自动化会导致错误的增加,从而传播挫折感和不信任感。

许多最初的数据科学分析从零开始,并通过手工制作的管道处理所有数据。因为他们从定制的数据流程开始,数据科学家后来可能会陷入个人管理管道的责任中。他们花额外的时间检查他们的管道,以检测新出现的问题,及时修复它们,并在产品的消费者失去信任时,采取必要的措施来恢复失去的信任。

当将仪表板投入生产时,您不仅要考虑数据、报告和用户的情况,还要考虑数据和用户群在未来将如何变化。现在,一份报告对当前用户来说可能是清晰而准确的,尤其是因为你可以回答他们可能有的任何问题。但是,数据漂移可能会导致将来的报告不准确。一个你平时不怎么接触的经理可能会看到你的报告,但不能清楚地理解它,也不知道去哪里寻求帮助来理解它。因此,数据产品的质量以及对使用和解释数据产品的支持都会随着时间的推移而降低。

这些年来,我既是首席数据架构师,负责设计数据流程的管道,也是首席数据科学家,利用工程数据开发生产流程和可视化中使用的模型。

这篇文章整理了我一路走来学到的一些经验。我描述了生产数据管道的四个理想属性——不言自明、值得信赖、适应性强和有弹性。为了使数据管道正常运行,您需要在三个不同的数据处理阶段提供脚手架,包括您用作输入的数据(第一英里)、您向用户呈现结果的方式(最后一英里)以及数据处理和模型开发的运行和执行(中间的一切)。综合考虑,这两个轴提供了 12 个不同的接触点,每个接触点都有一个或多个重要的考虑事项需要解决。在我发布我的生产报告、仪表板和/或模型之前,这里是我在这些接触点上解决的一些考虑和重要问题。

三个管道阶段

我们说链条的强度取决于它最薄弱的一环。在数据管道中也是如此。数据产品的强度取决于构成产品的数据、管道和流程中最薄弱的部分。然而,在数据产品的情况下,许多这些“链接”不在你的控制之下。

你如何打造最强大的产品?你关注的是在你的特定管道部分的三个阶段——输入、输出和执行——中的每一个阶段需要加强的最重要的东西。

你的第一英里:你是从正确的东西开始的吗?此阶段的关注点集中在您放入管道或模型的输入数据上。您支持用户的能力取决于您开始时输入数据的质量。输入数据中的故障和降级通常不受您的控制,但会严重影响您的数据产品被接收和接受的程度。

**你的最后一英里:你的数据产品带来了理解、信任和信心吗?**您可能有一个很棒的数据产品,可能真的能满足需求,但所有这些都没有实际意义,除非用户理解报告,并对其底层数据的新鲜度和准确性有信心。“最后一英里”中的关注点集中在建立和维护这种信任上,这种信任不仅来自于您当前的报表查看者,也来自于将来可能查看该报表的任何人。

**在你、未来的你和你未来的替代者之间的旅程:你让事情变得简单了吗?**好的数据产品会存在很长一段时间。寿命和可维护性的考虑集中在您自己的特定提取、转换和加载过程上。数据管道出现故障,可能由于调度效率低下而降级,并可能产生规模问题。数据输入改变或消失。随着时间的推移,在使用您的数据生成的模型中,您可能会看到数据漂移或模型漂移。

支持一个生产过程可能很耗时,您希望为您自己、与您一起工作的其他人(他们可能会分担您的工作量)以及任何可能取代您的人简化维护过程。

四个重要标准

第二个轴包括不同的质量标准——让你的产品更强大的标准。我用四个标准来评估我的数据产品对未来数据问题和用户挑战的弹性。产品是否自明?T2 能激发信任和信心吗?随着数据输入的变化,是否容易适应?是否可靠、准确、维护?在开发生产管道时,仔细注意这些有助于减少未来维护任务所需的时间。

不言而喻:一旦你把你的数据产品投入生产,那些你不直接与之互动的人可能正在看着它。数据产品越简单明了,就越容易支持未来的用户。您希望尽可能地置身事外,同时仍能提供良好的支持。

随着时间的推移,您或其他人将需要进行一定量的监控和维护,以确保数据产品保持更新和准确。保持一个较低的心理负荷,以便拿起报告并学习,或者提醒自己报告是如何工作的,有助于这种维护。

值得信任:信任很难得到,也很容易失去。通常,当您第一次交付一个数据产品时,会有很多希望和一些信任。对于报表或仪表板,当用户获得报表或仪表板的长期感觉时,信任才会真正发展:

  • 回答他们的问题
  • 使用准确的数据
  • 保持最新
  • 提供一种可靠的方法来解决他们所看到的问题或潜在问题

如果用户开始怀疑这些事情中的任何一件,信任开始被侵蚀,报告不再像开始时那样有用。重复或重叠的关注点意味着产品最终会从他们的雷达上消失,用户会尝试用不同的方法来回答他们的问题。

适应性:数据输入和形状随时间变化。模式会改变。键值的分布发生变化。地方停止报告数据。数据集可以增长和扩展到超出您的数据处理和查询所能有效处理的范围。所有这些都会影响自动化流程交付准确及时的产品的能力。

作为一名数据科学家,您不希望花费时间频繁而详细地查看您的每一个产品,以确保您注意到数据中的所有小故障以及所有可能看起来不正确的地方。相反,最好是将监控任务委托给自动化系统,并以较慢的节奏对每个报告进行详细的深入研究。您可以自动监控的内容包括:

  • 对一个或多个输入数据流的架构的相关更改
  • 您正在使用的关键字段中数据形状的相关更改
  • 数据量的显著增加或减少
  • 最近使用的记录和当前时间之间有明显的滞后
  • 关于数据量或滞后的趋势

除了监控相关问题之外,当有人注意到问题时,您需要做好准备,做出反应并制定解决方案,避免过度复杂化。确切地知道在哪里寻找是第一步,但是以一种易于适应和维护的方式设置您的数据过程也是成功的关键。

当你在设计和建立你的管道时,要考虑到你未来的自己(或者可能是你的替代者)。将定期重新训练模型的过程自动化,以考虑数据的变化。有一个检查您的数据和模型的节奏,以确保它们仍然符合您在设置初始流程时所做的假设。

可靠:可靠性是关于你的管道和模型的执行效果。在这种情况下,管道可靠性与管道中的流程执行和计时相关。这与适应性(如上)形成对比,适应性与正在处理的实际数据有关。

为了确保可靠性,您需要确保组成管道的不同部分是可靠的,并且编排这些部分的流程是健壮的。

当数据和模型构建管道自动化时,您没有关于正在执行什么、是否遇到任何问题或者甚至结果数据产品看起来像什么的即时和集中的反馈。为此,为了了解不同部分或阶段的可靠性,有一个监控系统会有所帮助,该系统会集中这些信息并提醒您需要注意的事情。

要监控整个流程的每个处理阶段,就要监控每个阶段的可靠性。监控阶段包括检查以下内容:

  • 其输入数据得到了及时更新
  • 该阶段在预期的时间开始执行
  • 该阶段已成功完成
  • 在任何下游阶段需要读取其结果之前完成的阶段

把东西放在一起

当形成我的初始生产质量系统时,我在流水线的每个阶段都提出具体的问题,集中在前面提到的问题上。通过系统地研究这些问题,我能够解决所有 12 个接触点的质量问题。

不言自明/第一英里:

  1. 我使用的数据是否有据可查?
  2. 我使用的数据是否符合其预期用途?
  3. 我是否尽可能多地重用现有的工程管道,以降低整体维护工作量,并确保我的使用与相同数据项的其他使用一致?

不言自明/最后一英里:

  1. 报告或仪表板的呈现方式是否易于访问和理解,甚至对于将要查看它的人也是如此,并且不需要我的解释?
  2. 我是否使用了最终用户理解的词汇和可视化,并且他们理解的方式和我完全一样?
  3. 我是否以一种直观且易于从数据产品本身获取的方式提供了良好的支持文档和信息?

自明/介于:

  1. 数据流程的要求、约束和实现是否记录得足够好,以便可能接替我进行维护的其他人能够理解?

值得信赖/第一英里:

  1. 我连接到输入数据的方式在生产管道中得到很好的支持吗?
  2. 维护我正在使用的数据集的人是否明确支持我?
  3. 这些输入数据在未来很长一段时间内可能会被保留吗?
  4. 什么时候我可能需要检查以确保数据仍然被维护?
  5. 我如何报告我在输入数据中看到的任何问题?
  6. 谁负责通知我数据有问题?
  7. 谁负责解决这些问题?

值得信赖/最后一英里:

  1. 用户如何知道他们何时可以相信报告是准确的和最新的?
  2. 是否有一种有效的和/或自动化的方式将可能的问题传达给最终用户?
  3. 是否有一个清晰且可访问的流程,供用户报告与数据或报告有关的问题,以及通知用户是否有任何补救流程?

值得信赖/介于两者之间:

  1. 我是否制定了定期的计划来审查数据和报告,以确保数据管道仍然运行良好,并且报告符合要求?
  2. 在什么情况下应将此报告标记为已弃用?
  3. 如果报告被否决,我如何确保用户得到通知?

适应性强/第一英里:

  1. 我的分析依赖于输入数据中的哪些要素?
  2. 我如何知道这些特性是否不再受支持,是否受到模式更改的影响,或者是否以可能影响我的分析的方式改变了形状?
  3. 我如何知道数据的规模是否增长到了需要重构过程的程度,以便跟上产品对新鲜度的要求?

适应性强/最后一英里:

  1. 产品或报告的设置方式是否便于申请变更和/或新功能?

适应性强/介于两者之间:

  1. 我是否为重新检查需求建立了一个定期的时间表,以确保我仍然在生产用户需要和期望的东西?
  2. 用户指出需求变化的过程是什么,这些变化是如何解决的?
  3. 当输入以某种相关方式改变时,重构和重新测试数据管道的过程是什么?

可靠/第一英里:

  1. 我的流程是否很好地融入了组织中的数据实践和工程生产系统?
  2. 我是否有自动通知系统来监控输入数据的可用性、新鲜度和可靠性?

可靠/最后一英里:

  1. 谁负责仪表板本身的持续监控、审查、故障排除和维护?
  2. 内部报告和解决问题的职责和程序是否明确到位?

可靠/介于:

  1. 我的管道中的每个阶段都及时执行和完成了吗?
  2. 在任何阶段,处理时间和/或正在处理的数据量是否存在漂移,这可能表明管道功能下降?

结论

将一个数据产品投入生产所面临的挑战,不仅仅是一次性地或作为一个原型让某样东西表现良好。从一开始就适当关注与生产相关的问题,可以最大限度地减少您在生产中产品的日常维护任务上花费的时间,从而提高您的整体生产效率。

当您第一次构建一个数据产品时,您会考虑可以使用哪些数据,以及如何在您的产品中最好地使用这些数据来满足目标用户的需求。对于分析师或数据科学家来说,这通常有点像是单独的工作。

将产品投入生产更多的是团队的努力。通常还有其他人——可能是数据工程团队——负责确保您所依赖的数据源保持准确和最新。您希望以最适合他们的方式连接他们的数据。你也有你的用户——现在是一群更加开放的人——他们会使用你的产品。你希望他们信任你的产品。你希望尽可能简单地使用和理解你的产品。最后,你有自己的数据管道。当发生影响其功能的事情时,您希望尽快知道。

本文中的 12 个接触点以及与每个接触点相关的问题为您的产品化过程提供了一个结构。关注这些问题将有助于防止你陷入支持困境,并给你更多的时间来发挥创造力和创造新事物。

玛丽安·诺丁是 Mighty Canary 的首席数据科学家。

Mighty Canary 是一家专注于构建工具的公司,旨在帮助数据和分析专业人员增加对其报告的信任,并减少他们支持旧报告所花费的时间。

本文标签: 中文翻译博客TowardsDataScience一百九十七