Domino-博客中文翻译-二-
Domino 博客中文翻译(二)
原文:Domino Blog
建立人工智能卓越中心的五个步骤
原文:https://www.dominodatalab.com/blog/five-steps-to-building-the-ai-center-of-excellence
由战略&创新副总裁林振和 Mark III 系统首席技术官大卫舒尔曼合著,后者是多米诺数据实验室的合作伙伴营销主管。
通过数据科学获得竞争优势的最具创新性的组织正在创建数据科学的卓越中心(CoE)模型。 麦肯锡指出,在高级分析领域,60% 的顶级公司都遵循 CoE 方法。 例如,Bayer Crop Science 将许多优势归功于 CoE 方法,例如跨团队更好地共享知识、提高数据科学计划的效率、更好地协调数据科学和业务战略,以及改善人才获取。
建设欣欣向荣的人工智能卓越中心(CoE)的路径是什么?
在 Mark III,我们在过去几年里有幸与 NVIDIA 和几十个组织一起在工作,以支持他们的 AI CoE 之旅。在 9 月 19 日至 22 日的 NVIDIA GTC 大会上,我们宣布了新的 AI CoE 解决方案,采用了 NVIDIA 和 Domino 数据实验室的最新技术。
尽管每个故事和道路都略有不同,但我们注意到,它们在成熟时大多遵循相同的五个一般步骤或阶段。多米诺数据实验室的企业 MLOps 平台 集成了英伟达的产品线 的基础设施,如英伟达 DGX 系统,来自领先原始设备制造商的英伟达认证系统,以及英伟达 AI 企业软件套件。我们还帮助像【Allstate】【SCOR】Topdanmark这样的组织扩展他们的 Coe。尽管每个故事和道路都略有不同,但我们注意到,它们在成熟时大多遵循相同的五个一般步骤或阶段。
但在我们描述我们观察到的这些步骤是什么之前,我们可能应该定义什么是人工智能卓越中心(至少是我们对人工智能卓越中心的看法)。
什么是人工智能卓越中心?
很简单,人工智能卓越中心是一个集中的数据科学和人工智能/人工智能计算资源,在某一点上由一个团队管理,但可以服务于一个、五个、十个、一百个甚至数千个数据科学家,每个人都有自己独特的关于 ide、框架、工具集、库、模型、应用程序的需求,他们在其中工作的团队,都可以“用脚投票”在哪里构建和运行他们的模型。
简而言之,即使你成功地构建了技术栈来服务于你的数据科学社区,如果你不同时保持对团队、文化、人员、用户体验和教育方面的高度关注,他们也不会喜欢它,他们会转向其他东西(甚至拒绝使用它),你的 AI CoE 也不会成功。
因此,通往人工智能卓越中心的旅程确实一半是技术,一半是非技术(教育/文化/团队)。你会发现这个想法在下面有显著的特征。
构建人工智能 CoE 的五个步骤是什么(根据与几十个机构和组织的合作观察),我们如何合作以确保它的成功?
教育
甚至在关于技术的任何讨论以及关于集中式平台或 MLOps 的任何想法之前,我们已经发现,最成功的组织已经在教育他们的数据科学社区,为将来某一天的集中式 AI CoE 技术堆栈做准备。在任何给定的时间点,我们已经注意到至少 70%的与会者要么开始,要么试图加强基本的 AI/ML 基础,所以持续的实践教育在开始和持续的基础上都是重要的。
Mark III 帮助填补了这一空白,它在早期阶段对组织内的社区进行教育,并通过其 人工智能教育系列 提供所有阶段的继续教育,这是一套为不同地理位置的受众设计的实时虚拟教程/实验室,专为实用的人工智能教育理念而设计。焦点完全集中在术语、实用概念和实验室 — 上,可以被与会者立即“带回家”,让他们插入自己的数字、数据和用例,并立即开始迭代。
Domino 已经在组织中看到了类似的例子,不仅是数据科学家,还有商业领袖。好事达采用教育计划,专注于向业务领导者传授数据科学知识,通过为业务领导者和数据科学家提供“共同语言”来促进跨职能部门的沟通,以解决棘手的业务问题(在 43:00 的 了解更多信息,这是一个点播小组 )。
我们看到的培养这种文化并为 AI CoE“摆好桌子”的其他教育示例包括交互式用户驱动的研讨会、跨职能团队建设以及围绕共同挑战的“快速构建”。
实验
我们通常看到的下一个阶段,通常与“教育”阶段(一旦开始,实际上总是在进行中)重叠,是“实验”阶段,数据科学家和“构建者”从阴影中出现,告诉你他们正在做什么,以及他们如何使用或考虑使用数据科学和人工智能模型在整个组织中做改变游戏规则的事情。
Domino 已经看到组织为数据科学家实验和创新留出有意的时间——,这可能超出了“自上而下”的业务目标。好事达分配了一部分数据科学家的时间来从事任何感兴趣的项目,促进跨团队实验和协作来推动创新。更多详情,请查看 本点播面板 )。
在过去的 5-10 年里,人工智能的开源本质和历史令人难以置信的是,几乎任何人都可以从他们的笔记本电脑或工作站开始,无论是在办公室内还是办公室外。围绕数据科学对社区进行正式教育的官方努力几乎就像是为这些构建者走出来展示他们一直在做的工作开了绿灯。在这一点上,组织有机会鼓励社区在他们各自的组中继续并加速他们的工作,方法是让他们在他们习惯的工作流中访问更好的平台和工具。
评价
有了足够的教育和鼓励,组织将很难跟踪所有正在构建的模型以及所有孤岛和小组中发生的所有数据科学活动。相反,数据科学家开始遇到真正的挑战,例如模型漂移、无法跟踪数据集版本、无法获得模型所需的最佳数据集、模型从训练到生产推理的速度缓慢等等。好的一面是,整个组织有很多活动和讨论,但这些是真正的问题,如果不解决,可能会破坏所有的势头。
这个转折点是“评估”和审视 MLOps 平台的最佳时机,如果操作得当,该平台可以作为人工智能卓越中心向前发展的技术核心,并允许组织在某一点管理 CoE,而不会在组织扩展时侵犯每个数据科学家的独特需求和偏好。
开放性和灵活性是数据科学创新的关键,这就是为什么它是 Domino 平台的核心支柱。数据科学工具和技术的前景是异构的,并且不断发展,处于 CoE 核心的平台必须提供灵活性、敏捷性和可伸缩性。 拜耳 将此视为评估 Domino 的关键因素,数据科学家使用了许多工具,如 RStudio、Jupyter、Flask 等。拜耳数据科学卓越中心负责人 Naveen Signla 指出,“Domino 使全球企业中使用不同工具、具有不同背景和技能的用户更容易相互合作,利用过去的工作,并快速协作。"
我们在这一阶段使用的词是“评估”,因为它不仅需要试验和“推广”由 Domino 的企业 MLOps 平台和 Kubernetes 基金会支持的 MLOps 技术堆栈的能力,还需要确保任何试验中的数据科学家都有培训、部署和运行他们的模型的出色体验。总之是真实的评价。如果你的早期数据科学用户没有很好的体验,你的 AI CoE 可能无法进入下一阶段。
使能够
如果组织取得成功,通往人工智能卓越中心之旅的第四步是“启用”阶段,该阶段的中心是将人工智能卓越中心的成功试点推广到早期生产中,确保数据科学用户的数量增加,并与 IT 运营团队合作,以确保环境保持正常运行。
Mark III 发现,将 AI CoE 几乎像软件即服务产品 — 一样对待和支持,并将管理它的团队视为产品管理团队 — 是构建团队和战略的有效视角。Domino 已经看到了类似的侧重于支持数据科学家和业务的方法,其中 S & P Global 使用 Domino 作为“粘合剂”,支持一项对全球 17,000 名员工进行数据科学教育的计划。SCOR 将数据科学家嵌入业务中,以更好地培养理念、实践、技术和文档,从而推动数据科学的采用。此外,他们的数据科学专家使用 Domino 作为工具来 分享最佳实践和模板 。
Mark III 帮助组织完成了从建立知识库和入门教程到与 IT 运营团队“合作指导”的各种工作,以保持整体 AI CoE 环境的运行和优化。
从事
通往人工智能卓越中心的旅程的第五步也是最后一步是“参与”阶段,这是关于激活数据科学社区的剩余部分来加入人工智能卓越中心的。如果你从技术采用曲线的角度考虑,这将包括早期多数用户和后期多数用户。
到这个时候,组织的 AI CoE 和 MLOps 平台正在运行,大多数组都充分意识到了,并且入职和用户体验应该运行顺利,即使对于非专家用户也是如此。
此时,AI CoE 应该像一台运转良好的机器一样运行。重点是提高大众的参与度,鼓励他们更多地参与 AI CoE。在 Mark III,我们经常在“参与”阶段联合举办黑客马拉松,不仅提高整个组织的意识,还帮助建立与外部组织的合作伙伴关系,包括行业和公共部门。
类似地,Domino 通常是黑客马拉松中使用的 MLOps 平台,提供参与者所需的基础设施、数据和工具。强生公司 举行了一次内部黑客马拉松 来提高视力保健业务的预测能力,利用达美乐的平台让几十个团队提出最佳模式。 BNP Paribas Cardif 举办了一次虚拟数据科学黑客马拉松 ,来自大学和合作公司的 100 多名数据科学家参加,使用 Domino Data Lab 使每个团队能够访问他们需要的基础设施资源。
如何构建人工智能 CoE:英伟达 GTC 发布新解决方案
通往人工智能卓越中心的旅程对每个组织来说都是不同的,但我们认为,如果规划并遵循这五个步骤,它将有可能导致成功,无论确切的路径如何。如上所述,这一旅程基于一半技术、一半文化/团队/教育,并且我们的集体团队可以通过我们的共同学习来提供帮助。
企业 MLOps 在通往人工智能卓越中心的道路上至关重要,因为它构成了卓越中心的技术核心,但请不要忽视这条道路上的其他关键步骤和环节。
毕竟,人工智能卓越中心的成功在于过程,而不是目的地。了解更多关于我们 AI CoE 解决方案的信息,NVIDIA 于 9 月 19 日至 22 日在 GTC 宣布。
将您的数据科学职能引向 MLOps 卓越的五个技巧
编者按:这是分享开发企业数据科学战略的公司最佳实践的系列文章的一部分。一些文章将包含关于他们使用 Domino 的信息。
在我毕业后的 15 年职业生涯中,我有幸为金融和保险行业的公司开发数据科学团队。我最近被要求思考哪些行动有助于使数据科学团队成功融入组织。以下是我提供给任何踏上构建企业数据科学功能之旅的人的五个技巧。
雇佣多样化的技能组合
当我五年前加入纽约人寿时,我的任务是将一个由七名成员组成的数据科学团队发展成为一个企业范围的集中式数据科学中心,并在全公司范围内提供具有新水平的服务、专业知识和效率的人工智能解决方案。
如今,数据科学和人工智能中心(CDSAi)是一个 50 人的团队,拥有在我们的财富 100 强人寿保险公司中成功提供数据科学和人工智能专业知识、解决方案和教育所需的各种技能。CDSAi 不仅包括数据科学家,还包括机器学习工程师、数据工程师、项目和产品经理、运营和变革管理负责人、建立外部合作伙伴关系的开发经理以及数据科学社区负责人。
我们的数据科学家参与模型开发生命周期的每个方面。他们由负责模型部署和我们各种技术平台的项目经理和 ML/Ops 工程师提供支持。我们的变革经理、产品经理和开发经理携手合作,构思和整合新业务合作伙伴的数据科学。
促进透明度和数据科学教育
关于揭开数据科学神秘面纱的重要性已经说了很多,我参与的每个组织都是如此。我们的业务合作伙伴越是见多识广,他们就越会兴奋地将数据科学纳入他们的决策流程。为此,我们为公司创造了多种学习和参与数据科学的方式。
感谢纽约人寿的大力支持,我们已经成功建立了一个包容性的数据科学社区,通过各种计划覆盖所有领域、职业、级别和数据科学经验水平。其中包括:
- 关于项目、方法和数据的每月“午餐和学习”
- 年度数据科学博览会
- 数据科学论坛
- 外部嘉宾扬声器
通过这些活动,我们的内部数据科学家可以继续相互学习,公司内感兴趣的员工可以接触到数据科学在不同业务领域的应用。
此外,通过我们的数据科学学院,我们为纽约人寿的所有员工创造了机会,让他们以最舒适的方式学习数据科学。这包括技术和非技术认证途径以及文章和视频系列。我们举办了一系列研讨会,涵盖的主题从如何开始使用 Python 到我们的高级管理人员如何充分利用我们的数据科学能力。
通过这些活动、学习机会和纽约人寿的内部网,我们提高了对数据科学的理解水平,并强调了它可以提供的巨大价值。这有助于我们与现有业务伙伴、潜在的新业务伙伴以及其他利益相关方的关系。
经常有意义地联系
继续这个主题,您的业务合作伙伴知识越丰富,他们就越愿意将数据科学纳入他们的决策过程,我们非常鼓励 CDSAi 团队经常与我们的业务合作伙伴联系。
对于我们的数据科学家来说,这意味着每周或每两周与利益相关者会面。可能并不总是有重大的更新,但是在这些会议中,我们继续了解业务的细微差别以及棘手问题,他们也了解我们的流程。这对双方都有利,而且从个人层面来说,令人愉快和有益。其他团队成员也参与这些定期安排的会议。项目里程碑一起庆祝。虚拟工作当然也没有阻止我们承认项目中的所有重要时刻。
除了这些会议,我们的团队成员还会定期与公司的其他人进行互动。这有助于了解更多的业务以及我们如何提供帮助,同时,在有意义的层面上了解他人也是工作中令人满意的一部分。找到我们与同事的联系点对于个人参与和确保项目顺利进行都很重要。
与所有利益相关方保持一致
我们认为,确保我们与所有利益相关方有效协调我们的工作至关重要,包括:
- 业务领导 -我们经常与销售、营销、财务、产品、服务和其他业务团队的业务领导交谈,讨论机会并确保我们保持一致。CDSAi 经理与我们所服务的业务部门中的同行非常一致。
- 技术-我们需要在技术方面保持敏捷,特别是当我们迅速将新平台、库和工具引入我们的数据科学生态系统,以帮助我们的团队推动创新时。为此,与我们的技术合作伙伴进行良好的沟通至关重要。对于每一个请求,我们都分享为什么我们需要一种特定的技术,以及它如何从技术和业务的角度推动我们前进。此外,我们的数据工程师积极与技术合作,以确定数据优先级以及数据将如何流入分析开发。然后,CDSAi 团队处理“最后一英里”的数据处理,将数据输入到我们的模型中。
** 【治理团队】- 作为一家公司,我们有广泛的治理流程。对于更大的项目,我们有各种各样的治理团队。因此,在我们所有的项目计划中,我们有流程来确保我们的团队在我们需要决策之前几个月就开始这些对话,这样我们就可以确保我们在开发的早期解决任何需求。*
*### 投资技术基础设施
我们投资于有助于加速模型开发和部署的基础设施。例如,我们已经使用 Python 和 R 栈以及模型开发创建了一个计算环境。最近,我们在 Domino 平台的帮助下创建了模型部署的基础设施。我们使用 Domino 来消除将模型转移到生产环境中的手工工作,这需要大量的质量保证(QA)工作来保证它的正确性。现在,有了 Domino 平台和底层的 Kubernetes 集群,我们消除了数月的重新编码工作,可以直接将 Python 和 R 代码投入生产。我们的模型现在可以通过 API 从公司的任何生产平台访问。实现、运行和管理 Domino 平台以及部署模型在很大程度上是 CDSAi 和我们的技术团队之间的协作。
最终反射
我对 CDSAi 在帮助纽约人寿多元化团队做出模型驱动的决策方面所发挥的影响感到无比自豪。仅举几个例子,销售、营销、核保和代理等职能部门都在利用数据科学来自动化关键流程和改进决策,以便更好地为我们的客户服务。该团队已经建立了一个强大的基础—跨越人员、流程和技术—并在帮助高效和协作地实现这一影响方面发挥了关键作用。
随着我们进一步扩展纽约人寿的数据科学能力,我们将在许多方面继续努力。例如,最近的一项工作是增强我们的数据流,并创建一个特征库,该库记录并制度化了用于特定模型的最佳特征的知识。功能工程是一个耗时的过程,这项工作将使我们的团队能够不断地建立在彼此的知识之上,并更快地解决复杂的业务问题。
以上五个建议来自我的经验,这个旅程当然还会继续。
祝贺我们佛罗伦萨数据科学家抽奖活动的获胜者
原文:https://www.dominodatalab.com/blog/florence-book-sweepstakes-winner
By Domino Data Lab on June 01, 2021 in Company Updates
为了庆祝全国数学意识月,我们在 Domino 数据实验室的团队最近出版了世界上第一本关于数据科学的儿童书籍数据科学家 Florence 和她的神奇移动图书。我们还为这本书的读者提供了赢得一台笔记本电脑和 5000 美元大学学费的机会。我们很兴奋地宣布,威廉·布拉顿,阿肯色州波茨维尔中学的五年级学生,赢得了我们的抽奖!
威廉有幸阅读了这本书,并从他学校的图书管理员梅丽莎·穆迪那里了解了抽奖活动。
威廉的母亲克里斯蒂娜·津内尔说:“这不仅让我的儿子开心,也让他对自己和自己的梦想更有信心。”“他学校的每个人都以他为荣!”
津内尔补充说,虽然威廉喜欢这本书,但他尤其喜欢书中的主角如何利用科学来获得她想要的东西。
数据科学家弗洛伦斯和她的神奇的流动图书车围绕着一个名叫比阿特丽斯的好奇的孩子展开。当一辆神秘的流动图书车在她住的街道上行驶时,比阿特丽斯被这辆车后面的人所吸引。司机叫弗洛伦斯,算是一名图书管理员,他确切地知道哪些书会让附近的每个孩子开心。
随着这本书的展开,比阿特丽斯被迫决定是否有“魔法”这种东西,或者这个“图书管理员”是否知道一些世界上其他人不知道的事情。Beatrice 花了一整天的时间记录和分析她的每个朋友对 Florence 问题的回答,发现并爱上了数据科学的预测能力。
“有些人可能认为她作弊了,但她没有,”威廉说。“她运用自己的技能,观察其他孩子的结果,找到一种模式,这样她就能得到她想要的东西。那不是作弊,那是数据科学。"
此外,威廉说他喜欢书中动物的生活方式。他还认为这本书很好地解释了如何在日常生活中使用数据科学。
“威廉想成为一名兽医,”津内尔说。“他不仅想让动物——家养的和野生的——健康安全,他还想在动物和社区之间架起一座桥梁。”
威廉补充说,拥有数据科学技能可以帮助他开发更好的更持久的解决方案,以改善动物福利。
“我知道波特斯维尔中学也会以他为荣,”齐塞尔说。"尤其是他的图书管理员穆迪女士,她努力帮助她的学生取得成功."
“我希望我们能提供给威廉的大学基金能帮助他追随他的激情,”莱恩·凯利说,她是《数据科学家弗洛伦斯和她的神奇的移动图书》的作者。“以同样的方式激励他,我希望这本书也能丰富许多其他孩子的梦想,让他们对解决问题充满热情,这样他们就可以继续让这个世界变得更好。”
数据科学家利用过去的数据建立模型,预测未来可能发生的事情。他们用笔记本、表格和图表彻底记录数据,然后用他们的数学和推理技能寻找模式。
想帮助孩子了解记录和分析数据的模式如何有助于预测未来吗?加入比阿特丽斯的行列,她会通过下载一本电子书或者从亚马逊订购一份硬拷贝。
对于物联网来说,东西越多越好
原文:https://www.dominodatalab.com/blog/for-the-internet-of-things-the-more-things-the-merrier
这是德克萨斯州奥斯汀数据科学论坛上众多精彩会议之一。不要错过 2016 年 9 月 14 日在洛杉矶数据科学弹出窗口向世界领先的数据科学家学习的下一次机会。查看演讲者阵容并立即获取门票。
前微软 Azure ML 高管和 Forrester 分析师加入 Domino 数据实验室
克里斯·劳伦(Chris Lauren)和杰尔·卡尔松(Kjell Carlsson)博士 帮助达美乐的客户群战略性地扩展他们对数据科学的使用
Domino Data Lab 自豪地宣布,来自企业技术领域两个最大品牌的 MLOps 专家已加入其团队。Chris Lauren 已经加入 Domino,担任微软产品副总裁,在那里他领导 Azure 机器学习产品团队;前 Forrester 分析师 Kjell Carlsson 博士加入该公司,担任数据科学战略负责人&布道者。
Lauren 将领导 Domino 的产品团队进一步定义和执行 Domino Enterprise MLOps 平台的愿景和战略,以更好地帮助客户利用机器学习的力量加速数字化转型。
在他的新角色中,Carlsson 将为 Domino 客户和潜在客户提供人工智能转型战略方面的建议;就企业如何大规模释放数据科学的商业价值提供战略建议。他还将在提高人们对 Domino 市场领先能力的认识方面发挥重要作用,并在战略和开发方面与 Lauren 的产品团队密切合作。
Domino Data Lab 的首席执行官兼联合创始人 Nick Elprin 表示:“Chris 和 Kjell 拥有广泛的行业知识,这对我们的团队和客户来说是一笔不可思议的财富。“Chris 是云计算和机器学习方面的专家,拥有数十年为企业客户提供产品的经验。随着数据科学和机器学习的成熟,Kjell 有幸为各行各业的数百家组织提供建议。丰富的经验使他非常适合宣传我们释放数据科学的使命。他们的加入让我激动不已。”
“在帮助许多企业大规模采用机器学习的同时,我看到了 MLOps 在加快模型速度以增加业务影响方面的关键作用,”劳伦说。Domino 是唯一一个以开放和灵活的方式满足最苛刻的企业工作负载需求的 MLOps 平台。我希望将 Domino 打造成适用于所有云和内部环境的市场领先企业 MLOps 平台,并在支持医疗保健、保险和金融服务等关键监管行业的客户方面取得成功。"
Carlsson 说:“Domino 是唯一一家真正支持现代专业数据科学家的公司,也是让企业能够扩展并推动其数据科学团队在整个组织中的影响力的最佳选择。与这样伟大的企业合作是一种荣幸,这些企业正在彻底转变自己,并使用 Domino 的 enterprise MLOps 平台实施最新的机器学习创新。”
拥有数十年大规模交付产品经验的真正的云 MLOps 专家
Lauren 在微软工作了 20 多年,利用大数据和机器学习的力量,领导团队交付产品并大规模赢得企业客户。他是云计算领域的专家,有能力与工程、设计、研究、营销、销售、客户和合作伙伴密切合作,推动产品定义和上市战略。
最近,他一直在 Azure Machine Learning 领导一个产品管理团队,以加速企业客户的增长,MAU 和 NPS 主要专注于使 ML 专业人员和工程师能够在云和大规模边缘培训、打包、部署和管理机器学习模型,并集成监控、警报和再培训,以促进完整的 MLOps 生命周期。
推动 Domino 客户迈向模型驱动业务的数据科学社区倡导者
卡尔森撰写了数十份报告,主题涵盖对话智能、MLOps、计算机视觉和 autoML,以及增强智能、下一代人工智能技术和数据科学最佳实践。他在无数的主题演讲、小组讨论和网络研讨会上发表过演讲,并被媒体频繁引用。
在加入 Domino 之前,Carlsson 是专注于 NLU 的初创公司 Stratifyd 的产品和战略副总裁,他在那里领导产品团队并重新设计公司战略。此前,Kjell 是 Forrester Research 的首席分析师,他领导了人工智能、人工智能、数据科学和高级分析方面的研究,就推动业务成果所需的技术、战略、能力和最佳实践向企业和供应商提供建议。卡尔松在哈佛商学院获得商业经济学博士学位。
Forrester TEI 研究:Domino 在 6 个月内实现了 542%的投资回报率和投资回报
Forrester 最近调查了数千名业务和技术决策者,以深入了解他们对数据和分析的使用,以及影响他们购买决策的因素。当被问及他们的组织在使用人工智能(AI)技术时期望获得什么好处时:
- 30%的受访者预计会“增加收入增长”
- 30%的受访者期望“提高运营效率和有效性”
- 30%的人希望“提高内部流程的自动化程度”
- 27%的人希望“提高员工的工作效率”
不幸的是,15%的受访者还表示,“对人工智能的明确投资回报没有统一的信念”是阻碍他们公司采用人工智能技术的最大挑战之一。21%的人最关心“他们人工智能投资的机会成本”。显然,组织对人工智能有很高的期望(他们应该如此),但难以量化人工智能投资对其业务的深远好处。难怪有 17%的人认为“缺乏高管支持来推动人工智能的使用”是他们组织面临的最大挑战之一。
Forrester 就组织如何实现采用人工智能和数据科学的好处提供了许多建议。例如,根据 Forrester Wave:基于笔记本的预测分析和机器学习,2020 年第三季度,“基于笔记本的 PAML 产品通过使个人数据科学家显著提高生产力,特别是通过为团队提供协作能力,将基于笔记本的数据科学推向了一个新的水平。”
我们很早就知道 Domino 使数据科学团队更有生产力。我们记录了他们的许多不可思议的故事,在某些情况下,已经能够衡量令人印象深刻的好处。例如,洛克希德·马丁公司将每年节省的 2000 万美元的成本归功于他们使用我们的平台,这要归功于降低的 IT 成本、提高的入职效率以及 10 倍的数据科学家工作效率。
但有些人看到这样不可思议的数字,自然会产生怀疑。其他人不确定在数据科学和 MLOps 解决方案上投资什么,因为目前市场上存在着混乱的状态,许多供应商推出了针对不同类型用户的截然不同的方法,并有着不同的规模目标。我们认为,购买者必须权衡企业 MLOps 的潜在影响和他们在人员、流程和技术方面的投资,然后衡量投资回报,这一点至关重要。
量化 Domino 的商业价值
为了消除一些疑虑和困惑,我们委托了一项独立的 Forrester Consulting 研究:Domino Enterprise MLOps 平台的总体经济影响(TEI)。Forrester 对几个 Domino 客户进行了详细的采访,以了解他们如何使用我们的平台,并深入了解他们获得的好处。基于这些采访,他们建立了一个由 50 名数据科学家组成的复合组织,预计团队增长与我们的许多客户在使用 Domino 的前三年中的经历一致。
结果不言自明:Forrester 预测,使用 Domino 的组织在三年时间内实现了近 3000 万美元的总经济效益,投资回报率为 542%,T2 为 542%。他们还得出结论,在 T4 投资多米诺不到六个月就收回了成本。
“如果我们没有投资 Domino,首先,我根本不可能建立一个团队,因为如果不为他们提供最先进的工作环境,你就无法雇用高技能的数据科学家。”–保险首席分析官
综合组织在三年内实现的平台预期收益包括:
减少了 980 万美元的计算资源配置时间
根据客户访谈,Domino 通过提供对基础架构和托管环境的自动化访问,允许数据科学家几乎立即开始研究新模型,平均每个实例节省 70 个小时。受访者报告说,以前调配基础架构、创建环境以及安装/维护单个软件包的过程通常需要几天到几周的时间,具体取决于构建的复杂程度。综合组织的净时间节省估计为三年 980 万美元。
对强大计算资源的自助式访问也减少了对工程部门的支持呼叫;管理人员估计,工程师在响应数据科学家的请求上节省了大约 30%的时间。
“在 Domino 出现之前,可能需要两到三周的时间来了解和启动基础架构,然后开始工作。有了 Domino,这需要几周时间,只需点击一下按钮。”–制药行业数据平台和隐私总监
运营效率提高了 850 万美元
数据科学经理报告说,使用 Domino,他们的数据科学团队可以利用更多的工具,花更少的时间等待模型和实验运行,并利用高级协作和可视化功能以新的方式与他人分享他们的工作。
管理人员估计每个数据科学家每年可以节省 200 个小时,对于复合组织来说,三年可以节省 510 万美元。
组织还实现了与新团队成员更快入职、更高效的模型验证、部署和维护相关的好处。对于综合组织而言,这些节省总计增加了 340 万美元。
“我们当然正在实施更精确的模型,甚至是我们以前在更复杂的工作流程中无法实现的模型。这可能比我们可能达到的水平提高了约 20%。”–金融服务首席顾问
520 万美元的增量利润
Domino 客户报告说,能够在开发周期中更有效地协作已经产生了更好地符合业务需求的数据科学解决方案,并且可以直接影响收入。他们能够生产更强大的模型,并受益于更高的模型部署成功率,从而对底线产生重大影响。对于本研究中使用的复合组织,增量利润估计接近 520 万美元。
“我们使用 Domino 对收入产生了巨大的影响,收入高达数百万美元,实际上是数千万美元。”–金融服务首席顾问
了解弗雷斯特·TEI 研究的详细信息
这些数字和报价只是您将在Domino Enterprise MLOps Platform的总体经济影响(TEI)中找到的细节的开始。查看这项研究,了解受访者在实施 Domino 之前面临的挑战,并深入了解 Domino 为他们带来的好处。
2021 年 6 月 7 日更新:我刚刚主持了一场网络研讨会,Forrester 首席分析师 Kjell Carlsson 博士和《TEI》的作者 Mary Barton 出席了会议。Kjell 描述了组织在扩展数据科学时面临的一些关键挑战,我们就 TEI 结果本身以及他们的访谈和 Domino 案例研究中的实际例子进行了热烈的讨论。你现在可以观看网上研讨会的重播。
基数:美国、加拿大、英国、法国和德国的 2,456 名数据和分析决策者;来源:Forrester Analytics 商业技术图表数据和分析调查,2020 年。
信号处理基础
原文:https://www.dominodatalab.com/blog/fundamentals-of-signal-processing
数字信号处理基础
信号被定义为任何随时间、空间或任何其他独立变量而变化的物理量。此外,科学和工程中遇到的大多数信号本质上都是模拟信号。也就是说,信号是连续变量的函数,例如时间或空间,并且通常取连续范围内的值。为了以数字方式执行处理,需要模拟信号和数字处理器之间的接口。这个接口被称为模数转换器。
通过以称为采样周期的特定间隔对信号进行采样,将模拟信号转换为数字信号。采样周期的倒数称为采样率(赫兹;秒^(-1) ),并且必须至少两倍于模拟信号中的最大频率,以防止混叠(参考奈奎斯特-香农采样定理)。实际上,采样率要高得多。常见的采样频率有 8kHz、16kHz、32kHz。
特征抽出
音频信号,特别是语音信号,通常在时域、频域和倒谱域进行分析。信号的频域表示由 DFT(离散傅立叶变换)完成。假设信号 X[N]具有范围在 0nN-1 之间的 N 个样本,信号 X[k]的 DFT 由 bey 给出
这里 k 是离散化的频率变量,跨度从 0kN-1。
快速傅立叶变换(FFT)是一种高效的 DFT 计算方法(请参考 cp-algorithms 的文档)。考虑到语音信号的随机特性,FFT 很少一次应用于整个信号,而是以帧为单位。通常,一种称为短时傅立叶变换(STFT)的傅立叶变换被应用于每个单独的帧。
下面示出了对信号 x[n]的样本的 FFT 算法
来源: 维基百科
假设表示语音信号的信号 x[n]和窗口函数 w[n]
人类的语言几乎总是在框架中被分析。语音信号碰巧是非平稳信号,但是在跨度为 20-40 毫秒长的帧中,假设信号是平稳的。原因是在这段时间内,声道特性不会发生太大的变化。这一点很重要,因为只有当信号稳定时,才能假设先验分布。在说话人确认的情况下,分布是高斯分布。
每帧之间有 10ms 的重叠。出现这种重叠是因为三角形窗口被应用于每一帧
(请参考这篇关于信号语音处理的文章)。
窗口可以被认为是索引上的非零值的数组,其中帧的样本在别处是 1 和 0。当该帧的每个帧样本乘以 1 时,它是一个矩形窗口。对于三角形窗口,靠近帧末端的样本被“去加重”(即乘以 0 和 1 之间的数字),而位于中心的样本由于窗口的三角形形状而被加重。执行帧的重叠,以便补偿在每帧结束时样本的去加重。(请参考栈交换提出的问题)
此外,几乎从不使用矩形窗口。在矩形窗口的情况下,信号的样本乘以 1。因为时域中两个信号的相乘等于频域中信号的卷积。矩形窗口的傅立叶变换是正弦函数。该函数在 x=0 处有一个主瓣,在π的整数倍处有旁瓣,随着 x x 的绝对值不断增加,旁瓣值不断减小。
(资料来源: 【维基百科】 )
当这个函数乘以语音信号的傅立叶变换时,在旁瓣处发生频谱泄漏,这是不理想的。当非整数数量的信号周期被发送到 DFT 时,发生频谱泄漏。频谱泄漏使单音信号在 DFT 操作后分散在几个频率上。
(来源: DSP 图文并茂 )
在上图中,我们假设一个目标信号,即左边的三角周期信号乘以红色矩形窗口。这些信号的卷积如上图右侧所示。两个信号卷积由下式给出
简而言之,两个信号的卷积是指其中一个信号反转,另一个信号乘以样本。为了理解信号
正如你所看到的,在上面的蓝色图中,“窗口”信号(卷积的结果)在旁瓣上有频谱泄漏。红色信号是矩形窗口的变换。
为了减少频谱泄漏,使用三角形窗口,如汉宁窗口、汉明窗口和三角形窗口。
(资料来源: 【维基百科】 )
汉宁窗函数由下式给出
三角形窗口由下式给出
语音信号的成帧可以如下图所示:
(来源: 阿尔托大学 )
梅尔频率倒谱系数
MFCCs 顾名思义就是倒谱域的系数和特征。(ceps 反过来是“spec”)这些特性在语音处理和 MIR(音乐信息检索)应用中无处不在。与 DFT 不同,频率是对数标度或 mel 标度。梅尔标度类似于人的听觉标度。低频的毛细胞数量远远高于高频。因此,随着年龄的增长,我们辨别更高频率的能力逐渐减弱。分辨率向更高频率的降低是通过 Mel 标度实现的。
简而言之,在时域信号的帧上,应用 STFT,并且对该信号应用 mel 标度中的重叠三角窗,即,应用一种对数标度。然后应用离散余弦变换,前 13 个系数称为 MFCCS。从每一帧中提取δ系数和双δ系数,一起构成 39 维数组。因此,如果一个音频信号有 100 帧,MFCC 阵列的维数将为(100,39)
mel 标度和线性标度之间的关系由下式给出
其中 f 表示以 Hz 为单位的物理频率,fMel 表示感知频率
Mel 滤波器组看起来像这样
要提取 MFCCs,需要完成以下步骤
- 预加重-这是一个高通滤波器,用于平衡在高频区域有陡峭滚降的浊音频谱。本项目使用的系数为 0.97。该值通常在 0.9 和 1 之间变化
- 框架和窗口——如上所述
- 频谱的 DFT 执行信号帧的帧
Mel 谱-幅度谱 X(k)的 Mel 谱通过将幅度谱乘以每个三角形 Mel 加权滤波器来计算。
其中 M 是三角形 Mel 加权滤波器的总数。
Hm(k)是给予对第 m 个输出频带有贡献的第 k 个^个能谱箱的权重,表示为:
其中 M 的范围从 0 到(M-1)。
- Mel 频谱的离散余弦变换(DCT)用于将 Mel 频率系数的对数变换成一组倒谱系数。
- 动态 MFCC 特征:倒谱系数是静态特征。从这些导出的δ系数是一阶导数,δ-δ系数是二阶导数。这些分别代表语速和语音加速度。
模糊匹配救援
原文:https://www.dominodatalab.com/blog/fuzzy-matching-to-the-rescue
詹妮弗·申是 8 Path Solutions 的创始人&首席数据科学家。Jennifer 是加州大学伯克利分校数据科学研究生项目的教师,纽约城市大学数据分析硕士项目的顾问委员会成员,并在 NYU 大学的研究生项目中教授业务分析和数据可视化。在一次数据科学的弹出式活动中,Jennifer 介绍了近似字符串匹配或模糊匹配。这篇博客文章包括一个会议总结,一个整个会议的视频,和一个演示文稿的视频抄本。如果你有兴趣参加未来的数据科学 Popup,下一个活动将于 11 月 14 日^日在芝加哥举行。
Session Summary
在这个数据科学的弹出式会议中,8 Path Solutions 的创始人兼首席数据科学家 Jennifer Shin 介绍了模糊匹配或近似字符串匹配。
该演示的几个主要亮点包括:
- 通过量化一个字符串与另一个字符串的接近程度,深入研究模糊匹配如何找到几乎相同但不完全相同的字符串。
- 模糊匹配的用例从基于相关性搜索列表到提供替换可能拼错的搜索词的建议。在替代拼写、不一致的格式和拼写错误会限制大型数据集中包含的信息的可用性和价值的情况下,这种方法尤其有用。
- 使用示例来说明模糊匹配如何成为实体和名称匹配的理想选择,但是对于医疗数据却不太理想,因为医疗数据的误差幅度太大。
要了解更多关于本次会议的见解,请观看视频或通读文字记录。
https://fast.wistia.net/embed/iframe/4c1hktg66n
获得对 Domino 实例的 Shell 访问
原文:https://www.dominodatalab.com/blog/gain-shell-access-domino-instances
注意:请注意,对于 4.x 以上的 Domino 版本,不赞成通过 SSH 直接访问容器。通过工作区终端(例如 JupyterLab、VSCode 等)间接访问 SSH。)在所有 Domino 版本中仍然可用。
Domino 提供了一个可管理的、可伸缩的计算环境,为数据科学家提供了方便,无论他们是对探索 Python 笔记本中的数据感兴趣,还是对使用 R 脚本训练模型感兴趣。虽然 Domino 为团队提供了许多定制和共享环境的机会,但是有些问题最好通过 shell 访问来解决。通过 Domino 的最新版本,用户可以做到这一点。
一旦启动了交互式会话,您将能够按照运行细节中的说明使用 SSH 访问正在运行的实例。看看这个短片:
基因组范围:基因组数据使用简介
原文:https://www.dominodatalab.com/blog/genomic-ranges-an-introduction-to-working-with-genomic-data
基因组测序的进步甚至超过了人们对他们的高度期望。我们现在有能力以不到 1000 美元的价格对一个人的整个基因组进行测序——这要归功于 Illumina 的 HiSeq X Ten 测序仪。在这篇文章中,我将介绍 GenomicRanges 软件包,它为表示基因组数据提供了一个方便的结构,并提供了许多操作这些数据的内置函数。
用坐标系统表示基因组
人类基因组由大约 30 亿个碱基对组成,线性排列在 23 对染色体上。因此,表示我们基因组的直观方式是使用坐标系:“染色体 id”和“沿染色体的位置”。像 chr1:129-131 这样的注释代表 1 号染色体上的第 129 到 131 个碱基对。
让我们加载 GenomicRanges 并创建一个示例对象来表示一些基因组片段:
# Installation source("https://bioconductor.org/biocLite.R") biocLite("GenomicRanges") The code below is how to create the an example GRanges object. The code entered here will create 8 segments on either chr1 or chr2, each with defined start and end points. Each read will also have strand information, indicating which direction the sequence is in. seglengths informs us the maximum length of chr1 and chr2. suppressMessages(library(GenomicRanges)) example = GRanges(seqnames=c(rep("chr1", 4), rep("chr2", 4)), ranges = IRanges(start = c(10, 32, 59, 79, 11, 22, 23, 41), end=c(42, 51, 76, 89, 12, 31, 46, 49)), strand = rep(c("+", "-"), 4), seqlengths=c(chr1=120, chr2=70) )
现在让我们来看看 R 控制台表示的例子:
example
## GRanges object with 8 ranges and 0 metadata columns:
## seqnames ranges strand
## <Rle> <IRanges> <Rle>
## [1] chr1 [10, 42] +
## [2] chr1 [32, 51] -
## [3] chr1 [59, 76] +
## [4] chr1 [79, 89] -
## [5] chr2 [11, 12] +
## [6] chr2 [22, 31] -
## [7] chr2 [23, 46] +
## [8] chr2 [41, 49] -
## -------
## seqinfo: 2 sequences from an unspecified genome
现在让我们想象一下这些作品的样子:
格兰奇斯物品估价员
一个 GRanges 对象可以作为一个数组和一个子集来处理,也可以这样修改:
example[1]
## GRanges object with 1 range and 0 metadata columns:
## seqnames ranges strand
## <Rle> <IRanges> <Rle>
## [1] chr1 [10, 42] +
## -------
## seqinfo: 2 sequences from an unspecified genome
该软件包还提供了访问和修改信息的功能:
seqnames(example)
## factor-Rle of length 8 with 2 runs
## Lengths: 4 4
## Values : chr1 chr2
## Levels(2): chr1 chr2
width(example)
## [1] 33 20 18 11 2 10 24 9
end(example)
## [1] 42 51 76 89 12 31 46 49
start(example[1])
## [1] 10
start(example[1]) = 11 example
## GRanges object with 8 ranges and 0 metadata columns:
## seqnames ranges strand
## <Rle> <IRanges> <Rle>
## [1] chr1 [11, 42] +
## [2] chr1 [32, 51] -
## [3] chr1 [59, 76] +
## [4] chr1 [79, 89] -
## [5] chr2 [11, 12] +
## [6] chr2 [22, 31] -
## [7] chr2 [23, 46] +
## [8] chr2 [41, 49] -
## -------
## seqinfo: 2 sequences from an unspecified genome
还可以将每个部分的附加信息存储到 GRanges 对象中:
example$exon_id = 1:8 example
## GRanges object with 8 ranges and 1 metadata column:
## seqnames ranges strand | exon_id
## <Rle> <IRanges> <Rle> | <integer>
## [1] chr1 [11, 42] + | 1
## [2] chr1 [32, 51] - | 2
## [3] chr1 [59, 76] + | 3
## [4] chr1 [79, 89] - | 4
## [5] chr2 [11, 12] + | 5
## [6] chr2 [22, 31] - | 6
## [7] chr2 [23, 46] + | 7
## [8] chr2 [41, 49] - | 8
## -------
## seqinfo: 2 sequences from an unspecified genome
单个范围的操作
GenomicRanges 还提供了许多有用的方法来对范围进行“算术运算”:
移位:
要将所有 10 个碱基对的片段移向染色体末端,可以这样做:
shift(example, 10)
## GRanges object with 8 ranges and 1 metadata column:
## seqnames ranges strand | exon_id
## <Rle> <IRanges> <Rle> | <integer>
## [1] chr1 [21, 52] + | 1
## [2] chr1 [42, 61] - | 2
## [3] chr1 [69, 86] + | 3
## [4] chr1 [89, 99] - | 4
## [5] chr2 [21, 22] + | 5
## [6] chr2 [32, 41] - | 6
## [7] chr2 [33, 56] + | 7
## [8] chr2 [51, 59] - | 8
## -------
## seqinfo: 2 sequences from an unspecified genome
要将所有片段向染色体的起始端移动 5 个碱基对,可以使用:
shift(example, -5)
## GRanges object with 8 ranges and 1 metadata column:
## seqnames ranges strand | exon_id
## <Rle> <IRanges> <Rle> | <integer>
## [1] chr1 [ 6, 37] + | 1
## [2] chr1 [27, 46] - | 2
## [3] chr1 [54, 71] + | 3
## [4] chr1 [74, 84] - | 4
## [5] chr2 [ 6, 7] + | 5
## [6] chr2 [17, 26] - | 6
## [7] chr2 [18, 41] + | 7
## [8] chr2 [36, 44] - | 8
## -------
## seqinfo: 2 sequences from an unspecified genome
要单独移动每一块,可以使用一个矢量:
shift(example, 1:8)
## GRanges object with 8 ranges and 1 metadata column:
## seqnames ranges strand | exon_id
## <Rle> <IRanges> <Rle> | <integer>
## [1] chr1 [12, 43] + | 1
## [2] chr1 [34, 53] - | 2
## [3] chr1 [62, 79] + | 3
## [4] chr1 [83, 93] - | 4
## [5] chr2 [16, 17] + | 5
## [6] chr2 [28, 37] - | 6
## [7] chr2 [30, 53] + | 7
## [8] chr2 [49, 57] - | 8
## -------
## seqinfo: 2 sequences from an unspecified genome
侧面
侧翼用于恢复输入集旁边的区域。对于示例上游的 3 个碱基延伸:
flank(example, 3)
## GRanges object with 8 ranges and 1 metadata column:
## seqnames ranges strand | exon_id
## <Rle> <IRanges> <Rle> | <integer>
## [1] chr1 [ 8, 10] + | 1
## [2] chr1 [52, 54] - | 2
## [3] chr1 [56, 58] + | 3
## [4] chr1 [90, 92] - | 4
## [5] chr2 [ 8, 10] + | 5
## [6] chr2 [32, 34] - | 6
## [7] chr2 [20, 22] + | 7
## [8] chr2 [50, 52] - | 8
## -------
## seqinfo: 2 sequences from an unspecified genome
输入负值表示向下游看,值可以是向量。注意,上游和下游是相对于每个片段的链信息而言的。
调整大小
resize 方法从相对于股方向的最上游位置开始,将片段调整到所需的输入长度:
resize(example, 10)
## GRanges object with 8 ranges and 1 metadata column:
## seqnames ranges strand | exon_id
## <Rle> <IRanges> <Rle> | <integer>
## [1] chr1 [11, 20] + | 1
## [2] chr1 [42, 51] - | 2
## [3] chr1 [59, 68] + | 3
## [4] chr1 [80, 89] - | 4
## [5] chr2 [11, 20] + | 5
## [6] chr2 [22, 31] - | 6
## [7] chr2 [23, 32] + | 7
## [8] chr2 [40, 49] - | 8
## -------
## seqinfo: 2 sequences from an unspecified genome
还有许多其他方法非常有用。看到了吗?格兰奇
对一组范围的操作
GenomicRanges 还包括聚合特定 GRanges 实例中所有片段的信息的方法。以下 3 种方法最有用:
分离
Disjoin 将范围缩减为组成原始集合的唯一的、不重叠的片段的最小集合。默认情况下,它是链特异性的,这意味着第一个和第二个片段不被认为是重叠的,除非另有说明:
disjoin(example)
## GRanges object with 8 ranges and 0 metadata columns:
## seqnames ranges strand
## <Rle> <IRanges> <Rle>
## [1] chr1 [11, 42] +
## [2] chr1 [59, 76] +
## [3] chr1 [32, 51] -
## [4] chr1 [79, 89] -
## [5] chr2 [11, 12] +
## [6] chr2 [23, 46] +
## [7] chr2 [22, 31] -
## [8] chr2 [41, 49] -
## -------
## seqinfo: 2 sequences from an unspecified genome
disjoin(example, ignore.strand=T)
## GRanges object with 11 ranges and 0 metadata columns:
## seqnames ranges strand
## <Rle> <IRanges> <Rle>
## [1] chr1 [11, 31] *
## [2] chr1 [32, 42] *
## [3] chr1 [43, 51] *
## [4] chr1 [59, 76] *
## [5] chr1 [79, 89] *
## [6] chr2 [11, 12] *
## [7] chr2 [22, 22] *
## [8] chr2 [23, 31] *
## [9] chr2 [32, 40] *
## [10] chr2 [41, 46] *
## [11] chr2 [47, 49] *
## -------
## seqinfo: 2 sequences from an unspecified genome
减少
类似地,reduce 创建唯一的、不重叠的片段的最小合并集合,这些片段覆盖了原始集合所覆盖的所有碱基。默认情况下也会考虑线束信息,并且可以将其关闭:
reduce(example)
## GRanges object with 8 ranges and 0 metadata columns:
## seqnames ranges strand
## <Rle> <IRanges> <Rle>
## [1] chr1 [11, 42] +
## [2] chr1 [59, 76] +
## [3] chr1 [32, 51] -
## [4] chr1 [79, 89] -
## [5] chr2 [11, 12] +
## [6] chr2 [23, 46] +
## [7] chr2 [22, 31] -
## [8] chr2 [41, 49] -
## -------
## seqinfo: 2 sequences from an unspecified genome
reduce(example, ignore.strand=T)
## GRanges object with 5 ranges and 0 metadata columns:
## seqnames ranges strand
## <Rle> <IRanges> <Rle>
## [1] chr1 [11, 51] *
## [2] chr1 [59, 76] *
## [3] chr1 [79, 89] *
## [4] chr2 [11, 12] *
## [5] chr2 [22, 49] *
## -------
## seqinfo: 2 sequences from an unspecified genome
新闻报道
如果一个人需要知道每个碱基被一个阅读/片段覆盖了多少次,覆盖函数是非常有用的:
coverage(example)
## RleList of length 2
## $chr1
## integer-Rle of length 120 with 9 runs
## Lengths: 10 21 11 9 7 18 2 11 31
## Values : 0 1 2 1 0 1 0 1 0
##
## $chr2
## integer-Rle of length 70 with 9 runs
## Lengths: 10 2 9 1 9 9 6 3 21
## Values : 0 1 0 1 2 1 2 1 0
coverage(example)$chr1
## integer-Rle of length 120 with 9 runs
## Lengths: 10 21 11 9 7 18 2 11 31
## Values : 0 1 2 1 0 1 0 1 0
范围集合之间的运算
发现重叠
GenomicRanges 还提供了一种有用的方法来查找两组范围之间的重叠。让我们假设我们感兴趣的任何部分与我们感兴趣的目标部分重叠:
target = GRanges(seqnames="chr1", range=IRanges(start=5, 40)) ol = findOverlaps(target, example) ol
## Hits object with 2 hits and 0 metadata columns:
## queryHits subjectHits
## <integer> <integer>
## [1] 1 1
## [2] 1 2
## -------
## queryLength: 1
## subjectLength: 8
为了查看示例中与目标重叠的部分,我们访问了存储在 ol:
example[subjectHits(ol)]
## GRanges object with 2 ranges and 1 metadata column:
## seqnames ranges strand | exon_id
## <Rle> <IRanges> <Rle> | <integer>
## [1] chr1 [11, 42] + | 1
## [2] chr1 [32, 51] - | 2
## -------
## seqinfo: 2 sequences from an unspecified genome
为了查看示例中与目标重叠的部分,我们访问了存储在 ol:
example[subjectHits(ol)]
## GRanges object with 2 ranges and 1 metadata column:
## seqnames ranges strand | exon_id
## <Rle> <IRanges> <Rle> | <integer>
## [1] chr1 [11, 42] + | 1
## [2] chr1 [32, 51] - | 2
## -------
## seqinfo: 2 sequences from an unspecified genome
应用示例-检测基因组缺失
现在,让我们把这篇文章中看到的所有内容汇总起来,看看我们能否在一些更真实的生成数据中检测到删除的存在。
利用现代测序技术,整个基因组并不是一片一片的测序。DNA 通常在随机过程中准备好并切成更小的片段,以便对整个序列进行测序。然后,这些小片段被送入一台机器,从这些片段的随机位置开始产生读数。在最流行的 Illumina 机器的情况下,产生的读数是 100 个碱基对长。这些读数被映射回参考基因组,以找到它们的来源,位置信息可以通过 GenomicRanges 加载到 R 中进行评估。
如果基因组中有一个缺失,人们可能会发现没有来自某个特定区域的读数。让我们看一下 GRanges 对象,它包含来自个人的 2000 次模拟读取的位置信息。这类似于在对参考文献中长度为 1000 个碱基对的虚构染色体 Z 进行测序后可能存储在 GRanges 对象中的内容:
set.seed(1337) # Ensure reproducibility starts = floor(runif(2000)*900)+1 reads = GRanges(seqname="chrZ", ranges=IRanges(start=starts, end=starts+99)) reads
## GRanges object with 2000 ranges and 0 metadata columns:
## seqnames ranges strand
## <Rle> <IRanges> <Rle>
## [1] chrZ [519, 618] *
## [2] chrZ [509, 608] *
## [3] chrZ [ 67, 166] *
## [4] chrZ [409, 508] *
## [5] chrZ [336, 435] *
## ... ... ... ...
## [1996] chrZ [181, 280] *
## [1997] chrZ [224, 323] *
## [1998] chrZ [499, 598] *
## [1999] chrZ [ 63, 162] *
## [2000] chrZ [ 15, 114] *
## -------
## seqinfo: 1 sequence from an unspecified genome; no seqlengths
我们可以使用 reduce 来查看读取覆盖了 chrZ 的哪些部分:
reduce(reads)
## GRanges object with 1 range and 0 metadata columns:
## seqnames ranges strand
## <Rle> <IRanges> <Rle>
## [1] chrZ [1, 999] *
## -------
## seqinfo: 1 sequence from an unspecified genome; no seqlengths
让我们也看看这组读数中每个碱基的覆盖范围
plot(coverage(reads)$chrZ, ty="l", main="Coverage of Reads of ChrZ", xlab="Coordinates along ChrZ", ylab="Coverage")
请注意 chrZ 沿线相对稳定的覆盖范围。这似乎表明沿 chrZ 没有删除。现在让我们看看另一个数据集 reads_2,它来自一个单独的个体:
starts = c(floor(runif(1000)*300), floor(runif(1000)*400)+500)+1 reads_2 = GRanges(seqname="chrZ", ranges=IRanges(start=starts, end = starts+99)) reduce(reads_2)
## GRanges object with 2 ranges and 0 metadata columns:
## seqnames ranges strand
## <Rle> <IRanges> <Rle>
## [1] chrZ [ 1, 399] *
## [2] chrZ [501, 999] *
## -------
## seqinfo: 1 sequence from an unspecified genome; no seqlengths
plot(coverage(reads_2)$chrZ, ty="l", main="Coverage of Reads_2 of ChrZ", xlab="Coordinates along ChrZ", ylab="Coverage")
请注意图中低覆盖到无覆盖的区域以及序列中来自 reduce 的间隙-这似乎表明在第二个受试者中碱基 400 和 500 之间删除了一段 chrZ。现在我们希望发现这种缺失是否与参考基因组中的任何注释区域重叠。这可以使用 findOverlaps 和包含注释信息的 GRanges 对象来实现。已经创建了许多这样的注释,可以加载到 r 中。对于我们的示例,我们可以使用下面的 annotation GRanges 对象注释:
annotation
## GRanges object with 4 ranges and 1 metadata column:
## seqnames ranges strand | Gene_id
## <Rle> <IRanges> <Rle> | <character>
## [1] chrZ [100, 150] * | Gene_1
## [2] chrZ [200, 250] * | Gene_2
## [3] chrZ [400, 550] * | Gene_3
## [4] chrZ [700, 750] * | Gene_4
## -------
## seqinfo: 1 sequence from an unspecified genome; no seqlengths
ol = findOverlaps(GRanges(seqnames="chrZ", ranges=IRanges(start=500, end=600)), annotation) annotation[subjectHits(ol)]
## GRanges object with 1 range and 1 metadata column:
## seqnames ranges strand | Gene_id
## <Rle> <IRanges> <Rle> | <character>
## [1] chrZ [400, 550] * | Gene_3
## -------
## seqinfo: 1 sequence from an unspecified genome; no seqlengths
因此,在第二个受试者中,Gene_3 似乎被删除了——这一信息可以传递给下游的实验室科学家进行验证和一般编目。
祝贺您学习了使用 GenomicRanges 在 R 中处理基因组读取数据的基础知识。在以后的文章中,我将更详细地回顾一些已经报道的需要调整的测序技术工件。例如,基因组产生的读数在整个基因组中并不一致。此外,我们将研究一些更先进的方法来检测基因读取数据中的突变。
用 R 的 ggmap 实现地理可视化
原文:https://www.dominodatalab.com/blog/geographic-visualization-with-rs-ggmaps
你曾经处理过一些涉及空间位置的数据吗?如果答案是否定的,那么男孩,你错过了!要分析的空间数据如此之多,而时间却如此之少。
因为您的时间很宝贵,所以您知道尝试用 Matlab 等语言或 Excel 等应用程序创建空间图可能是一个冗长乏味的过程。令人欣慰的是,有许多新的 R 库正在被创建,以使空间数据可视化成为一项更令人愉快的工作。在这些新选项中,一个有用的包是 ggmap :
ggmap 入门
install.packages("ggmap")
library(ggmap)
就是这样。
最快的方法是使用qmap
类,它代表“快速地图绘制”。使用不同类型的参数调用来渲染不同的绘图类型。
以下是一些例子:
qmap(location = "boston university")
qmap(location = "boston university", zoom = 14)
qmap(location = "boston university", zoom = 14, source = "osm")
它是这样工作的:qmap 是get_map
和 ggmap 的包装器。get_map
是一个智能包装器,它查询您选择的地图服务器——Google Maps、OpenStreetMap 或 Stamen Maps——并返回指定位置的地图。(抱歉,苹果和必应地图的粉丝们,目前还不支持这些 API。)
如上例所示,没有必要添加特定的纬度或经度。创建地图时,ggmap 接受带有“位置”参数的文本搜索输入。
可视化集群
空间绘图功能对于那些在某些精算行业(如医疗或汽车保险)中运行分析的人很有帮助。
例如,让我们直观地调查各州的机动车碰撞数量。首先,我从死亡分析报告系统(FARS)百科全书中找到了 2012 年致命车祸的 Excel 文件。
(一个干净。数据集的 csv 版本可在Domino 的数据科学平台上的这个公共项目中获得。)
加载完 ggmap 库之后,我们需要加载和清理数据。以下代码行加载一个 CSV 文件,将 State 列转换为字符数据类型,并将机动车碰撞量从整数变为双精度。最后,我们删除夏威夷和阿拉斯加,以获得更紧密的地图视图。(抱歉!)
mydata = read.csv("vehicle-accidents.csv")
mydata$State <- as.character(mydata$State)
mydata$MV.Number = as.numeric(mydata$MV.Number)
mydata = mydata[mydata$State != "Alaska", ]
mydata = mydata[mydata$State != "Hawaii", ]
接下来,我们使用 geocode 通过 Google Maps API 查找纬度和经度,只使用mydata$State
中的字符串。
下面是一个简单的 for 循环,它遍历每个州并返回纬度/经度坐标:
for (i in 1:nrow(mydata)) {
latlon = geocode(mydata[i,1])
mydata$lon[i] = as.numeric(latlon[1])
mydata$lat[i] = as.numeric(latlon[2])
}
由于我们不考虑数据的其他方面,如非机动或修复对象碰撞,因此我们可以创建一个新的数据框来简化数据集:
mv_num_collisions = data.frame(mydata$MV.Number, mydata$lon, mydata$lat)
colnames(mv_num_collisions) = c('collisions','lon','lat')
现在让我们用不同大小的圆来画出每个州的碰撞次数,看看最大的机动车碰撞肇事者。
我们获得美国的地理编码,然后创建一个覆盖从东海岸到西海岸的谷歌地图:
usa_center = as.numeric(geocode("United States"))
USAMap = ggmap(get_googlemap(center=usa_center, scale=2, zoom=4), extent="normal")
我们使用+
操作符在地图上添加 ggplot2 几何对象和其他样式选项。
将 ggmap 和 ggplot2 功能相结合的能力对于使用热点图、等值线图或其他空间绘图类型可视化数据来说是一个巨大的优势。这种叠加功能大部分源于 ggplot2 的 geoms 或几何对象,它们决定了所创建的地块的形状。
接下来,我们将 geom_point geom 添加到地图中,并使用 aes 生成美学映射,描述数据中的变量如何映射到 geom 的视觉属性(美学)。
最后,每个圆的大小和比例基于每个状态的碰撞量的最小和最大值范围。
USAMap +
geom_point(aes(x=lon, y=lat), data=mv_num_collisions, col="orange", alpha=0.4, size=mv_num_collisions$collisions*circle_scale_amt) +
scale_size_continuous(range=range(mv_num_collisions$collisions))
运行 ggmap-demo-circles。多米诺骨牌中的 r脚本产生了一张罪犯最多的漂亮地图:加州、佛罗里达州、得克萨斯州和纽约州。
震撼?不好玩吗?是啊!
热图
让我们尝试另一种绘图类型——热图。继续以保险洞察的数据可视化为主题,下一个数据集着眼于一个地区的住宅集中度以及这些住宅的建造时间。
我们可以用get_map
下载底图,然后在上面画一个gg_map
。然后我们加上:
geom_density2d
:使用 kde2d 进行 2D 核密度估计,并用等高线显示结果。stat_density2d
: 2D 密度估计scale_alpha
:设置透明度的 alpha 值。
运行 ggmap-demo-heat。R 脚本给出了结果:
额外资源
- 如果你想了解更多,请参见 ggmap 参考手册并阅读由利兹大学研究人员编写的R 空间数据可视化简介。还可以看到其他令人惊叹的软件包,如 tmap ,它可以创建有用的专题地图。
- Plotly 在 ggplot2 的基础上拥有自己的增强地图功能。
- 2015 年 7 月 14 日,Jack Parmer(plotly 首席执行官)将在波士顿数据挖掘会议上讨论 plotly 的制图能力。
- 最后但同样重要的是,您可以使用 Domino 在大规模数据集上运行这样的分析,而不需要等待缓慢的计算时间,也不需要下载包。
让数据科学迅速进入企业规模:与 CSL Behring 的 John K. Thompson 的对话
随着领先的采用者提高个性化服务和客户体验的标准,数据科学的影响在每个行业都变得越来越明显。IDC 最近对人工智能的调查发现,早期采用者报告说,客户体验提高了 25%,创新速度加快,竞争力增强,还有其他好处。
然而,大多数领导者正在意识到,要将人工智能规模化,他们需要一个包括以下内容的企业战略:
- 为他们如何管理拥抱数据科学所必需的人员和文化变革创建一个规程。
- 在端到端数据科学生命周期中建立可扩展和可重复的流程。
- 确保数据科学团队拥有促进生产力和协作的技术基础。
以全球领先的生物制药公司 CSL Behring 为例,该公司专门治疗罕见疾病,如血友病和免疫疾病。2018 年,公司高管开始将数据科学转化为核心能力,帮助科学家:
- 发现新的救命疗法
- 更快地将产品推向市场,以及
- 帮助减少患者接受准确诊断的时间,这可能需要数年时间,因为患者和护理人员要努力弄清楚各种模糊症状,这些症状往往与其他更常见的疾病重叠。
在构建能力的过程中,高管们希望快速行动,这体现了他们的承诺
"工作吧,就像生活依赖于它一样,因为它们确实如此."
为了实现他们的愿景,他们聘请了在商业智能和高级分析领域拥有 30 年经验的 John K. Thompson 作为该公司第一位高级分析&人工智能的全球负责人。
在短短两年内,John 在业务的所有领域(从研究和药物安全到制造到供应链到运营)创建了一个蓬勃发展和成功的高级分析和人工智能实践,为患有罕见疾病的患者带来了不可估量的利益以及顶线和底线商业价值。
我们最近采访了约翰,他有能力在相对较短的时间内取得如此大的成就。以下是经过编辑的我们对话的文字记录。
当你加入 CSL Behring 时,你是从哪里开始的?
当我第一次进来时,我建立了一个卓越中心(COE ),雇用了一组数据科学家,并增加了数据可视化专家和开发人员,他们可以到公司的任何地方,为任何感兴趣的业务线或运营领域进行高级分析项目。
一旦我组建了这个团队,我就需要把消息传出去。我们开始通过内部邮件进行宣传,然后安排会议。在第一年,我与从首席执行官到工厂一线工人的所有人举行了 1100 多次会议,讨论高级分析和人工智能以及它可以做什么。
第一年,400 多人注册成为我们邮件列表的一部分,我们联系了 80 名已经在从事数据科学工作的不同业务部门的人员。
从那时起,我们开始寻找定期聚会的方式。我们在瑞士伯尔尼为该公司举办了有史以来第一次数据科学峰会,来自 CSL 各地的人们讨论了他们正在做什么、如何做以及他们想要做什么。
我们还根据收到的反馈创建了特殊兴趣小组(SIG)。我们有从使用人工智能进行药物安全到图像分析到 R 和 Python 的 SIGs。对于这些小组中的每一个,都有一个“所有者”,他们定期开会——通常在每个月到每个季度之间。
现在,这些小组将他们的兴趣反馈给 COE,我们将这些反馈给实践社区,以创建一个生态系统来指导组织中需要发生的事情。这三种结构允许人们进行足够小的、有凝聚力的对话,从而取得进步,以及足够大的、有影响力的社区。
为什么是咖啡?
卓越中心是一个伟大的概念,适用于许多不同类型的组织。
首先,它让组织明确了他们可以在哪里提问。许多高管、运营经理和主题专家来问我:
“哎,我在考虑做 x,我们有这方面的技术吗?我们以前做过吗?我们做过类似的事情吗?”
拥有一个 COE 可以让人们清楚地知道他们可以去哪里问这些问题。
其次,它提供了对技术的关注,以帮助组织了解人工智能的可能和不可能。有些事情人工智能目前可以非常确定地预测,有些事情则不能。所以这是一个专业导航的地方。
最后,COE 提供了一个定位点,有助于将 IT、运营和其他领域的人员聚集在一起,这对完成这项工作至关重要。
业务线员工有时会对集中式团队持怀疑态度。你是如何为你的 COE 赢得支持的?
我们从一开始就非常明确地表示,我们很乐意以顾问的身份帮助他人独立完成项目,但我们也很乐意为那些已经在做数据科学项目的人提供建议和支持。因此,有人来找我们,要求一名数据科学家或数据可视化人员来填补空缺,我们可以从我们的团队中借调一些人给他们。他们向我们寻求专家建议,用最好的技术来解决一个具有挑战性的问题。
招聘总是充满挑战。你是如何白手起家建立起一个团队的?
你需要慢慢来,知道自己在寻找什么。我的观点是,你需要一个由一些资深的、博士级别的数据科学家组成的团队,其余的可以是有才华的后起之秀。所以,我们刚刚开始把它放在那里,我们对前来表示希望与我们合作的人的质量和数量感到非常惊喜。
我们任何时候都有五六名实习生和我们一起工作,因为我们喜欢从本科生或研究生层次招聘人才。我们与许多大学有合作关系:密歇根大学、德克萨斯大学奥斯汀分校、德雷克塞尔大学和俄克拉荷马州立大学等等。在做出招聘决定之前,我们会让实习生回来两三次。我们想让人们长期留在身边,以确保这是一个很好的适应。这是值得的。例如,在我们 2018 年招聘的前六名员工中,有五人今天仍在团队中。
你如何设定你的优先事项?
从用例的角度来看,我们关注业务,以及此时最大的需求是什么,以便为患者和我们的公司带来改变。例如,在新冠肺炎,我们不得不转移我们的重点,以帮助确保我们有足够的血浆捐赠。由于我们所做的一切都来自人类血浆,任何导致人们不离开他们的房子来到捐赠中心的事情都可能给该行业的所有领域带来挑战。因此,在过去的六个月里,我们几乎完全专注于血浆业务,了解捐赠者和他们的担忧以及如何应对。
从流程的角度来看,我们通常专注于构建进入生产环境的系统和容器。一旦新模型投入生产,IT 部门就会接管,处理基础架构、合规性和法规合规性。我们保留对模型本身的权力和责任,监控模型性能,并在需要时重新训练模型。
你会给开始构建 COE 的其他人什么建议?
首先,正如我前面提到的,你必须雇佣好员工。你需要团队中能合作的人。不能与其他团队成员合作的人会削弱团队的凝聚力和生产力。所有人都需要有谦卑感。如果有什么不对劲,我们需要举手纠正。
其次,我认为 COE 是一个适合创意专业人士的环境。它不是一个技术团队,也不是一个 It 团队(考虑到这种差异,我认为 Coe 向 it 部门报告不是一个好主意)。我们不是在构建下一个 ERP 系统或 CRM 系统。我们收集了许多来源的数据,并把它们混合在一起,我们试图围绕可能性提出新的见解。将数据科学视为一种创造性的努力,可以让数据科学家调查他们感兴趣的事情。有时你会一无所获。但是其他时候你改变了企业的运作方式。因此,在我们集团内部,虽然我们不断努力满足业务线用户和高管的需求,但我们有一个非常自由流动、基于实验的方法。
最后,卓越中心必须能够有效地设定主题专家、经理和高管的期望,他们可能不知道高级分析项目涉及哪些内容,也不知道完成项目需要什么。因此,设定期望,让他们得到他们想要的开创性工作是很重要的,但这需要时间。
尽管如此,我们仍然希望成为一个敏捷的组织,帮助主题专家以新的方式尽快了解他们的业务。我想告诉大家,这些事情并不需要花费几周甚至几个月的时间。因此,我们与主题专家一起快速迭代,然后一旦构建了模型,我们就减缓治理和生产流程的周期。我确实相信,使用灵活的方法来构建模型不仅会给数据科学团队带来快乐和兴奋,也会给业务人员带来快乐和兴奋。
了解更多信息
- 阅读约翰的书-分析:如何用智慧取胜和建立分析团队
- 收听 John 与 Domino 首席客户官 Dave Cole 的炉边谈话,话题是建立您最好的数据科学团队。
用美汤获取数据
原文:https://www.dominodatalab.com/blog/getting-data-with-beautiful-soup
数据无处不在,从我们每天分析的电子表格,到我们每天早上依赖的天气预报或我们阅读的网页。很多时候,我们消费的数据只是简单的给了我们,简单的一瞥就足以做出决定。比如,知道今天全天下雨的几率是 75%,就让我带上伞。在许多其他情况下,提供的数据是如此丰富,我们需要卷起袖子,我们可能会使用一些探索性的分析来解决这个问题。我们已经在 的前一篇文章中讨论了一些有用的包来进行这种探索。
然而,我们需要的数据可能并不总是以一种适合于立即操作的格式提供给我们。可能的情况是,数据可以从应用编程接口(API)获得。或者我们可以直接连接到数据库来获取我们需要的信息。
另一个丰富的数据来源是网络,你可能已经从中获得了一些有用的数据。只要访问你最喜欢的维基百科页面,你就会发现每个国家在最近的东京奥运会上获得了多少枚金牌。网页也有丰富的文本内容,虽然你可以复制和粘贴这些信息,甚至输入到你选择的文本编辑器中,网络抓取可能是一种可以考虑的方法。在之前的另一篇文章中,我们谈到了自然语言处理,并从一些网页中提取了文本。在本帖中,我们将使用一个名为 Beautiful Soup 的 Python 模块来简化数据采集过程。
网页抓取
我们可以创建一个程序,使我们能够抓取我们感兴趣的页面并获得我们想要的信息。这就是所谓的网络抓取,我们编写的代码要求我们获取包含信息的网页的源代码。换句话说,我们需要解析组成页面的 HTML 来提取数据。简单地说,我们需要完成以下步骤:
- 用我们需要的信息识别网页
- 下载源代码
- 识别包含我们需要的信息的页面元素
- 提取和清理信息
- 格式化并保存数据以供进一步分析
请注意,并不是所有的页面都让你抓取它们的内容,其他的也不会提供一个清晰的观点。我们建议您检查您正在寻找的页面的条款和条件,并遵守它们。可能有这样一种情况,您可以使用一个 API 来获取数据,使用它而不是直接抓取数据通常会有额外的好处。
HTML 入门
如上所述,我们需要理解 HTML 文件的结构来找到解决方法。网页呈现其内容的方式是通过 HTML(或超文本标记语言)来描述的,HTML 提供了指示页面的格式、样式和结构的详细指令,以便浏览器可以正确地呈现内容。
HTML 使用标签来标记关键结构元素。标签通过使用<
和>
符号来表示。我们还需要指出标记元素的开始和结束位置。对于名为mytag
的标签,我们用<mytag>
表示标签内容的开始,用</mytag>
表示结束。
最基本的 HTML 标签是<html>
标签,它告诉浏览器标签之间的一切都是 HTML。因此,最简单的 HTML 文档被定义为:
<html>
</html>
上面的文件是空的。让我们看一个更有用的例子:
<html>
<head>
<title>My HTML page</title>
</head>
<body>
<p>
This is one paragraph.
</p>
<p>
This is another paragraph. <b>HTML</b> is cool!
</p>
<div>
<a href="https://blog.dominodatalab.com/"
id="dominodatalab">Domino Datalab Blog</a>
</div>
</body>
</html>
我们可以看到之前的 HTML 标签。这一次,我们有其他的标签在里面。我们把另一个标签里面的标签叫做“孩子”,正如你所想象的,标签可以有“父母”。在上面的文档中, <head>
和 <body>
是 <html>
的子节点,依次是兄弟节点。一个美好的家庭!
这里有几个标签:
<head>
包含网页的元数据,例如页面标题<title>
是页面的标题<body>
定义了页面的正文<p>
是一段文字<div>
是页面的一个分部或区域<b>
表示加粗字体-粗细<a>
是一个超链接,在上面的例子中,它包含两个属性href
,表示链接的目的地和一个名为id
的标识符。
好了,现在让我们试着解析这一页。
美味的汤
如果我们保存上面描述的 HTML 文档的内容,并在浏览器中打开它,我们将看到类似这样的内容:
这是一个段落。
这又是一段。HTMLT5【酷炫!
但是,我们有兴趣提取这些信息以供进一步使用。我们可以手动复制和粘贴数据,但幸运的是我们不需要这样做——我们有美丽的汤来帮助我们。
Beautiful Soup 是一个 Python 模块,它能够理解 HTML 和 XML 文档中的标签。你可以在这里看一下 模块的页面。
让我们用 HTML 的内容创建一个字符串。稍后,我们将看到如何从实时网页中读取内容。
my_html = """
<html>
<head>
<title>My HTML page</title>
</head>
<body>
<p>
This is one paragraph.
</p>
<p>
This is another paragraph. <b>HTML</b> is cool!
</p>
<div>
<a href="https://blog.dominodatalab.com/"
id="dominodatalab">Domino Datalab Blog</a>
</div>
</body>
</html>"""
我们现在可以导入美丽的汤,并读取字符串如下:
from bs4 import BeautifulSoup
html_soup = BeautifulSoup(my_html, 'html.parser')
让我们看看html_soup
的内容,正如你所看到的,它看起来很正常:
print(html_soup)
<html>
<head>
<title>My HTML page</title>
</head>
<body>
<p>
This is one paragraph.
</p>
<p>
This is another paragraph. <b>HTML</b> is cool!
</p>
<div>
<a href="https://blog.dominodatalab.com/" id="dominodatalab">Domino Datalab Blog</a>
</div>
</body>
</html>
但是,事情远比你想象的要复杂。看看 html_soup 变量的类型,可以想象,它不再是字符串。相反,它是一个漂亮的组合对象:
type(html_soup)
bs4.BeautifulSoup
正如我们之前提到的,Beautiful Soup 帮助我们理解 HTML 文件中的标签。它解析文档并定位相关的标签。例如,我们可以直接询问网站的标题:
print(html_soup.title)
<title>My HTML page</title>
或者对于 title 标签内的文本:
print(html_soup.title.text)
'My HTML page'
同样,我们可以看看儿童的身体标记:
list(html_soup.body.children)
['\n',
<p>
This is one paragraph.
</p>,
'\n',
<p>
This is another paragraph. <b>HTML</b> is cool!
</p>,
'\n',
<div>
<a href="https://blog.dominodatalab.com/" id="dominodatalab">Domino Datalab Blog</a>
</div>,
'\n']
从这里,我们可以选择第一段的内容。从上面的列表中,我们可以看到它是列表中的第二个元素。记住 Python 从 0 开始计数,所以我们感兴趣的是第 1 个元素:
print(list(html_soup.body.children)[1])
<p>
This is one paragraph.
</p>
这很好,但美丽的汤可以帮助我们更多。例如,我们可以通过参考如下的p
标签找到第一段:
print(html_soup.find('p').text.strip())
'This is one paragraph.'
我们还可以查找所有段落实例:
for paragraph in html_soup.find_all('p'):
print(paragraph.text.strip())
This is one paragraph.
This is another paragraph. HTML is cool!
让我们获得例子 HTML 中引用的超链接。我们可以通过请求所有包含一个href
的a
标签来做到这一点:
links = html_soup.find_all('a', href = True)
print(links)
[<a href="https://blog.dominodatalab.com/" id="dominodatalab">Domino Datalab Blog</a>]
在这种情况下,列表链接的内容就是标签本身。我们的列表包含一个元素,我们可以看到它的类型:
print(type(links[0]))
bs4.element.Tag
因此,我们可以如下请求属性href
和id
:
print(links[0]['href'], links[0]['id'])
('https://blog.dominodatalab.com/', 'dominodatalab')
读取网页的源代码
我们现在准备开始研究从实际的网页中请求信息。我们可以在请求模块的帮助下做到这一点。让我们来看看之前的一篇博文的内容,例如,关于“使用 Pandas Profiler 和 D-Tale 进行数据探索”的那篇
import requests
url = "https://blog.dominodatalab.com/data-exploration-with-pandas-profiler-and-d-tale"
my_page = requests.get(url)
成功的页面请求将返回响应 200:
my_page.status_code
200
用my_page.content
可以看到页面的内容。我不会展示这一点,因为这将是这篇文章的一个混乱的条目,但是你可以在你的环境中继续尝试。
我们真正想要的是将这个信息传递给 Beautiful Soup,这样我们就可以理解文档中的标签:
blog_soup = BeautifulSoup(my_page.content, 'html.parser')
让我们看看包含页面标题的标题标签h1
:
blog_soup.h1
<h1 class="title">
<span class="hs_cos_wrapper hs_cos_wrapper_meta_field hs_cos_wrapper_type_text" data-hs-cos-general-type="meta_field" data-hs-cos-type="text" id="hs_cos_wrapper_name" style="">
Data Exploration with Pandas Profiler and D-Tale
</span>
</h1>
我们可以看到它有几个属性,我们真正想要的是标签内的文本:
heading = blog_soup.h1.text
print(heading)
'Data Exploration with Pandas Profiler and D-Tale'
博文作者在author-link
类的div
中标识,我们来看看:
blog_author = blog_soup.find_all('div', class_="author-link")
print(blog_author)
[<div class="author-link"> by: <a href="//blog.dominodatalab.com/author/jrogel">Dr J Rogel-Salazar </a></div>]
注意,我们需要引用class_
(带下划线)以避免与 Python 保留字class
冲突。从上面的结果中我们可以看到,div
有一个超链接,作者的名字在那个标签的文本中:
blog_author[0].find('a').text
'Dr J Rogel-Salazar '
正如您所看到的,我们需要熟悉我们页面的源代码内容。你可以使用你最喜欢的浏览器提供的工具来检查网站的元素。
假设我们现在有兴趣获得博文中给出的目标列表。信息在一个无序列表的<ul>
标签中,每个条目在一个列表项的<li>
标签中。无序列表没有类或角色(与页面中的其他列表不同):
blog_soup.find('ul', class_=None, role=None)
<ul>
<li>Detecting erroneous data.</li>
<li>Determining how much missing data there is.</li>
<li>Understanding the structure of the data.</li>
<li>Identifying important variables in the data.</li>
<li>Sense-checking the validity of the data.</li>
</ul>
好了,我们现在可以提取 HTML 列表的条目,并将它们放入 Python 列表中:
my_ul = blog_soup.find('ul', class_=None, role=None)
li_goals =my_ul.find_all('li')
goals = []
for li_goal in li_goals:
v goals.append(li_goal. string)
print(goals)
['Detecting erroneous data.',
'Determining how much missing data there is.',
'Understanding the structure of the data.',
'Identifying important variables in the data.',
'Sense-checking the validity of the data.']
如前所述,我们可能对获取博客文章的文本进行一些自然语言处理感兴趣。我们可以用get_text()
方法一次性完成。
blog_text = blog_soup.get_text()
我们现在可以用 spaCy 来使用早先关于自然语言的文章中描述的一些技术。在这种情况下,我们显示每个条目、其词性(POS)、对词性的解释以及该条目是否被视为停用词。为方便起见,我们只展示第一个10 个条目。
import spacy
nlp = spacy.load("en_core_web_sm")
doc = nlp(blog_text)
for entry in doc[:10]:
print(entry.text, entry.pos_,
spacy.explain(entry.pos_),
entry.is_stop)
SPACE space False
Data PROPN proper noun False
Exploration PROPN proper noun False
with ADP adposition True
Pandas PROPN proper noun False
Profiler PROPN proper noun False
and CCONJ coordinating conjunction True
D PROPN proper noun False
- PUNCT punctuation False
Tale PROPN proper noun False
读取表格数据
最后,让我们利用目前所学的知识,得到可以用表格形式显示的数据。我们在这篇文章的开头提到,我们可能希望看到不同国家在东京奥运会上获得的金牌数量。我们可以从维基百科的相关条目中读到这些信息。
url = 'https://en.wikipedia.org/wiki/2020_Summer_Olympics_medal_table'
wiki_page = requests.get(url)
medal_soup = BeautifulSoup(wiki_page.content, 'html.parser')
使用浏览器的 inspect 元素功能,我可以看到数据所在的表有一个类。查看我的浏览器截图:
medal_table = medal_soup.find('table',
class_='wikitable sortable plainrowheaders jquery-tablesorter')
在这种情况下,我们需要遍历每一行(tr
),然后将它的每个元素(td
)赋给一个变量,并将其追加到一个列表中。一个例外是含有th
元素的表格标题。
让我们找到所有的行。我们将挑选出第一个来提取标题,并将奖牌信息存储在一个名为allRows
的变量中:
tmp = medal_table.find_all('tr')
first = tmp[0]
allRows = tmp[1:-1]
让我们来看一个 first
的排:
print(first)
<tr><th scope="col">Rank</th><th scope="col">Team</th><th class="headerSort" scope="col" style="width:4em;background-color:gold">Gold</th><th class="headerSort" scope="col" style="width:4em;background-color:silver">Silver</th><th class="headerSort" scope="col" style="width:4em;background-color:#c96">Bronze</th><th scope="col" style="width:4em">Total</th></tr>
如您所见,我们需要找到所有的 th
标签并获取文本,此外,我们将使用 strip()
方法去掉标题和结尾空格。我们在一个列表理解语法中完成所有这些:
headers = [header.get_text().strip() for
header in first.find_all('th')]
print(headers)
['Rank', 'Team', 'Gold', 'Silver', 'Bronze', 'Total']
酷!我们现在把注意力转向奖牌:
results = [[data.get_text() for
data in row.find_all('td')]
for row in allRows]
print(results[:10])
[['1', '39', '41', '33', '113'],
['2', '38', '32', '18', '88'],
['3', '27', '14', '17', '58'],
['4', '22', '21', '22', '65'],
['5', '20', '28', '23', '71'],
['6', '17', '7', '22', '46'],
['7', '10', '12', '14', '36'],
['8', '10', '12', '11', '33'],
['9', '10', '11', '16', '37'],
['10', '10', '10', '20', '40']]
坚持下去...这看起来很棒,但它没有国名。让我们看看 的内容allRows
:
allRows[0]
<tr><td>1</td><th scope="row" style="background-color:#f8f9fa;text-align:left"><img alt="" class="thumbborder" data-file-height="650" data-file-width="1235" decoding="async" height="12" src="//upload.wikimedia.org/wikipedia/en/thumb/a/a4/Flag_of_the_United_States.svg/22px-Flag_of_the_United_States.svg.png" srcset="//upload.wikimedia.org/wikipedia/en/thumb/a/a4/Flag_of_the_United_States.svg/33px-Flag_of_the_United_States.svg.png 1.5x, //upload.wikimedia.org/wikipedia/en/thumb/a/a4/Flag_of_the_United_States.svg/44px-Flag_of_the_United_States.svg.png 2x" width="22"/> <a href="/wiki/United_States_at_the_2020_Summer_Olympics" title="United States at the 2020 Summer Olympics">United States</a> <span style="font-size:90%;">(USA)</span></th><td>39</td><td>41</td><td>33</td><td>113</td></tr>
啊哈!国家的名称在一个 th
标签中,实际上我们可以从超链接里面的字符串中提取出来:
countries = [[countries.find(text=True) for countries in
row.find_all('a')]
for row in allRows ]
countries[:10]
[['United States'],
['China'],
['Japan'],
['Great Britain'],
['ROC'],
['Australia'],
['Netherlands'],
['France'],
['Germany'],
['Italy']]
你可以从网站的表格中看到,一些国家的金牌、银牌和铜牌数量相同,因此排名相同。例如,见给予希腊和乌干达的第 36 位。这对我们的数据搜集策略有一些影响,让我们看看条目 35 到 44 的结果:
results[33:44]
[['34', '2', '4', '6', '12'],
['35', '2', '2', '9', '13'],
['36', '2', '1', '1', '4'],
['2', '1', '1', '4'],
['38', '2', '1', '0', '3'],
['39', '2', '0', '2', '4'],
['2', '0', '2', '4'],
['41', '2', '0', '1', '3'],
['42', '2', '0', '0', '2'],
['2', '0', '0', '2'],
['44', '1', '6', '12', '19']]
我们的行有五个条目,但是具有相同排名的行实际上有四个条目。这些条目都有一个 rowspan
属性如截图所示为排名36如下:
让我们找到具有 rowspan
属性的条目,并计算具有相同等级的国家的数量。我们将记录条目编号、 td
编号、共享相同等级和等级分配的国家数量:
rowspan = []
for num, tr in enumerate(allRows):
tmp = []
for td_num, data in enumerate(tr.find_all('td')):
if data.has_attr("rowspan"):
rowspan.append((num, td_num, int(data["rowspan"]), data.get_text()))
print(rowspan)
[(35, 0, 2, '36'),
(38, 0, 2, '39'),
(41, 0, 2, '42'),
(45, 0, 2, '46'),
(49, 0, 2, '50'),
(55, 0, 2, '56'),
(58, 0, 4, '59'),
(62, 0, 3, '63'),
(71, 0, 2, '72'),
(73, 0, 3, '74'),
(76, 0, 6, '77'),
(85, 0, 8, '86')]
我们现在可以通过在缺少值的行中插入正确的等级来修复我们的 results
:
for i in rowspan:
# tr value of rowspan is in the 1st place in results
for j in range(1, i[2]):
# Add value in the next tr
results[i[0]+j].insert(i[1], i[3])
让我们检查一下这是否有效:
print(results)[33:44]
[['34', '2', '4', '6', '12'],
['35', '2', '2', '9', '13'],
['36', '2', '1', '1', '4'],
['36', '2', '1', '1', '4'],
['38', '2', '1', '0', '3'],
['39', '2', '0', '2', '4'],
['39', '2', '0', '2', '4'],
['41', '2', '0', '1', '3'],
['42', '2', '0', '0', '2'],
['42', '2', '0', '0', '2'],
['44', '1', '6', '12', '19']]
我们现在也可以插入国名:
for i, country in enumerate(countries):
results[i].insert(1, country[0])
最后,我们可以用我们的数据创建一个熊猫数据框架:
import pandas as pd
df = pd.DataFrame(data = results, columns = headers)
df['Rank'] = df['Rank'].map(lambda x: x.replace('\n',''))
df['Total'] = df['Total'].map(lambda x: x.replace('\n',''))
cols = ['Rank','Gold', 'Silver', 'Bronze', 'Total']
df[cols] = df[cols].apply(pd.to_numeric)
df.head()
军阶 | 组 | 金色的 | 银 | 青铜 | 总数 | |
---|---|---|---|---|---|---|
Zero | one | 美国 | Thirty-nine | Forty-one | Thirty-three | One hundred and thirteen |
one | Two | 中国 | Thirty-eight | Thirty-two | Eighteen | Eighty-eight |
Two | three | 日本 | Twenty-seven | Fourteen | Seventeen | Fifty-eight |
three | four | 大不列颠 | Twenty-two | Twenty-one | Twenty-two | Sixty-five |
four | five | 皇家对空观察队 | Twenty | Twenty-eight | Twenty-three | Seventy-one |
df['Gold'].mean()
3.6559139784946235
df['Total'].mean()
11.612903225806452
摘要
我们已经看到了如何解析一个 HTML 文档,并在 Beautiful Soup 的帮助下理解其中的标签。你可能想用你在这里学到的一些东西来获取一些数据,否则这些数据可能只能在网页上找到。请记住,您应该注意您正在获取的材料的权利。阅读您感兴趣的页面的条款和条件,如果有疑问,最好谨慎行事。最后一句话,网页抓取取决于你正在解析的网页的结构。如果页面发生变化,您的代码很可能会失败。在这种情况下,准备好卷起袖子,重新检查 HTML 标签,并相应地修改代码。
获取分类度量的误差界限
原文:https://www.dominodatalab.com/blog/getting-error-bounds-on-classification-metrics
误差范围,或缺乏误差范围
由于多种原因,计算源自非常大的数据集的度量的误差界限一直是有问题的。在更传统的统计学中,人们可以对大多数度量(例如,平均值)、参数(例如,回归中的斜率)或分类(例如,混淆矩阵和 Kappa 统计)设置置信区间或误差界限。
对于许多机器学习应用来说,误差界限可能非常重要。考虑一家公司开发获取客户的方法。关于如何继续,哪个陈述给了 CEO 更恰当的信息,是没有误差范围的答案,还是有误差范围的答案?
“通过该渠道获得的客户的平均预期终身价值为“”、25 美元或“”、【25 美元正负 75 美元。
谢天谢地,我不是首席执行官,但我想知道分析的弱点是否表明可能存在负值。为了明确区分,有一个宽的误差范围与有一个完全错误的分析是完全不同的;误差范围不会保护你免受坏数据、坏假设或坏模型的影响。
下面我将讨论机器学习项目中通常不使用误差界限的一些原因,介绍 bootstrap,little-bag-of-bootstrap 及其优点。然后我将给出估计线性回归的 R² 和手写数字的支持向量机分类的 F1 分数周围的误差界限的例子。
缺少它
有几个原因我认为误差界限通常不应用在机器学习中。
- 许多技术没有正式的方法。如果有人知道一种在神经或深度信念网络上计算置信区间的正式方法,我想知道它。
- 大多数计算置信区间的方法都依赖于分析中的假设。除非一个人接受过一些统计培训(自我培训是可以的),否则他们不太可能知道这些的细节。
- 使用机器学习的项目通常以一种非正式和探索性的方式进行,这种方式不太适合计算正式的置信区间。
- 使用大数据时,计算误差范围的额外工作量可能太大了。
- 在某些情况下,特别是对于非常大的样本,统计显著性很容易获得,但并不意味着模型是有用的。
- 所用数据的维度通常比统计学家在开发大多数统计方法时所设想的要大。
我怀疑在某些情况下,误差范围是可以计算出来的,但是没有报告出来,仅仅是因为这不是标准。不过,我愿意接受不同的意见。
拔靴带
Bootstrapping 是一种基于近似的代表性样本来推导精确度或分布测量的方法。这是一种重采样技术,从可用数据中提取带有替换的重复重采样,并用于计算所需的度量。人们可以看看 Efron (1973)的开创性论文或许多其他描述基本自举及其变体的出版物。引导是非常计算密集型的,需要对潜在的大部分数据进行多次迭代计算。
对于我们的目的来说,这是一种在我们只有一个样本的分布上计算度量和误差界的方法。
小自举的误差界限
凯鹏华盈。艾尔。发表了两篇关于“Little-Bag-Of-Bootstraps”(LBOB)的论文,这是一种用于海量数据的可扩展引导。这是传统自举的一个变种,它更适合在非常大的数据集上使用,并且更容易在机器之间分发。他们将 LBOB 与更传统的自举进行了比较,并表明它比其他自举方法更快、更一致地收敛于正确的误差界限。
克莱纳等人。艾尔。使用两阶段引导技术。在第一次或外部引导中,无需替换即可获取样本。该样本被传递到第二级或内部自举,该第二级或内部自举通过替换重复采样。内部样本大小相当于完整数据集的大小。对每个内部样本计算度量或分数。该度量可以是平均值、标准偏差、R² 、F1、AUC 或许多其他度量之一。对每个内部样本计算的指标进行汇总,通常是平均。这个值被传递回外部循环。然后外部循环继续该过程。当外部循环完成时,它可能有 3 到 50 个或更多的度量估计。通常,平均值作为“真实”指标的估计值,估计值的第 5 和第 95 个百分点形成可能的界限。
提高效率的关键之一是内部样本可以使用频率加权样本。本质上,这允许用更少的实际值来表示完整的数据集。任何接受频率加权数据集的例程都可以利用这一点。许多指标或评分程序将接受这种形式的数据(例如,许多 scikit learn 的score()
函数)。
博客反馈的一个激励性例子
我将使用 blog feedback 数据集的一个子集来估计可能的博客反馈。这些是由 Krisztian Buza 整理的,并从加州大学欧文分校机器学习库下载(Bache & Lichman,2013)。一分钟之内,假设数据集如此之大,以至于我们根本无法全部处理。然而,我们想知道我们的预测器工作得有多好。最初,仅使用前 20%的数据进行回归。结果将使用小启动包进行评估,它可以估计实际值和该值的一些界限。
使用样本外测试数据估计决定系数(R² )。估计值为 0.3112,可能的范围从 0.129 到 0.5193
使用 90%的数据进行培训,10%的数据进行测试,实际得分为 0.3476
虽然结果是随机的,但是完整数据集中的“真实”R² 总是在小部分数据确定的范围内,至少在我运行它的时候是这样。如果有的话,默认情况下使用的第 5 和第 95 个百分点的界限有点松。这很容易改变。
算法是如何工作的
在内部,这个小小的引导程序生成它将要计算的分数的重复样本。使用lbob.scores()
运行评估后,可以访问这些分数。分数的数量将等于子样本的数量。通常,人们会使用这些的平均值作为估计值,并将第 5 个和第 95 个百分位数作为界限。
下面的直方图显示了从每个外部引导或子样本中得出的各个估计值(l.scores
)的分布。使用了具有 100,000 个点的标准正态分布,并且估计的度量是第 97.5 百分位。因为只有 10 个子样本,所以结果有点不完整。蓝色虚线显示了估计值。估计的界限是灰色虚线。根据完整数据集计算的真正的 97.5%由较粗的红线给出。
内部采样的平均值收敛于一个适当的值。收敛速度取决于样本大小和分布的良好表现。下图显示了一些预测先前生成的标准正态分布平均值的试验。通常使用的平均值是每行的最后一个。请注意,该值存在一些差异。随着取样越来越多,回报也越来越少。
评分功能
该软件允许您定义任意评分或度量函数。虽然它默认计算平均值,但也可以在运行自举之前分配其他函数。
许多 scikit-learn 评分函数可以采用频率或权重向量。在这种情况下,您可以在运行引导之前使用类似下面的语句。
#Define classifier
clf = linear_model.MultiTaskLasso(alpha=0.1)
<h1>Assign its score func</h1>
lbob.score_func = lambda x, y, freq: clf.score(x, y, freq)
#Run the bootstrap
lbob_big_bootstrap(lbob)
#You can certainly define your own scoring function and use it.
#When the arguments match the order and count expected, you can skip the lambda function.
# Define score func
def my_scoring_func(x, y, weights):
return score
# Assign score func
lbob.score_func = my_scoring_func
最后一个例子
这个例子使用了一个由 Alpaydin 和 Kaynak 组装的手写数字数据集。它是 scikit 中数据的超集——通过运行sklearn.datasets.load_digits()
可以了解到这一点。这些数据将手写数字表示为灰度图像的向量。
使用具有参数网格搜索的支持向量机来分类字符。使用 F1 分数评估结果。首先对完整的训练数据集(N=3823)进行分类,以获得“真”F1。然后在不同大小的子集上执行。网格搜索是对每组数据分别进行的。这个例子的一个缺点是基本分类太好了,以至于在它的自举估计中没有太多的方差。
下面的直方图显示了使用 20%的数据进行训练时 F1 分数的估计值(蓝色条)。红色条显示“真实”F1,它完全在灰色线所示的估计范围内。
我觉得有趣的是,大多数错误分类的数字似乎并不难阅读。下面的第一张图是正确分类的数字,第二张图是错误分类的数字。
In the lists below, the top row shows how each digit was classified and the bottom row shows the true class.
Classification [9 1 1 1 1 9 5 9 9 9 9 9 9 8 9 8 1 0 3 8]
True Value [5 2 2 2 8 7 7 5 7 7 7 7 7 6 7 1 8 6 9 9]
使用项目
整个项目都可以在 Domino 上获得。要克隆整个项目:
- 下载并安装 Domino 客户端
- 在命令提示符下,运行:
domino get CassonStallings/bootstraps
参考
- Bache 和 m . lich man(2013 年)。 UCI 机器学习知识库。加州欧文:加州大学信息与计算机科学学院。
- 埃夫龙,B. (1979)自助方法:对折刀法的另一种看法。统计年鉴,7(1):1–26。
- Kaynak,C. (1995)组合多分类器的方法及其在手写数字识别中的应用。博加齐齐大学科学与工程研究生院硕士论文。(这个相关的出版物可能更容易接触到。)
- Kleiner,a .,Talwalkar,a .,Sarkar,p .,和 Jordan,M. I. (2012)大数据引导,第 29 届年会会议录。马赫上。学习,苏格兰爱丁堡。
- Kleiner,A .、Talwalkar,A .、Sarkar,p .和 Jordan,M. I. (2012)海量数据的可扩展引导,2012 年 5 月。https://arxiv.org/pdf/1112.5016v2.pdf
Python 中 k-means 聚类入门
原文:https://www.dominodatalab.com/blog/getting-started-with-k-means-clustering-in-python
假设您是一名成功的营销人员,正在为一种产品开展新的营销活动,并希望找到合适的目标细分市场;或者您是一名律师,对根据不同文档的内容对其进行分组感兴趣;或者您正在分析信用卡交易以确定相似的模式。在所有这些情况下,以及更多情况下,数据科学可以用来帮助对数据进行聚类。聚类分析是无监督学习的一个重要领域,它帮助我们将数据分组在一起。我们已经在这个博客中讨论过监督学习和非监督学习的区别。提醒一下,当标记数据不可用于我们的目的,但我们希望探索数据中的共同特征时,我们使用无监督学习。在上面的例子中,作为一名营销人员,我们可能会在目标受众中发现共同的人口统计特征,或者作为一名律师,我们会在相关文档中建立不同的共同主题,或者作为一名欺诈分析师,我们会建立共同的交易,这些交易可能会突出某人账户中的异常值。
在所有这些情况下,聚类都有助于找到那些共同的痕迹,并且有各种各样的聚类算法。在之前的帖子中,我们讨论了基于密度的聚类,其中我们讨论了它在异常检测中的使用,类似于上面的信用卡交易用例。在那篇文章中,我们认为其他算法可能更容易理解和实现,例如 k-means,这篇文章的目的就是要做到这一点。
我们将首先建立一个簇的概念,并确定 k 实现中的一个重要部分——意为:质心。我们将看到 k -means 如何处理相似性问题,以及如何在每次迭代中更新组,直到满足停止条件。我们将通过 Python 实现来说明这一点,并通过查看如何通过 Scikit-learn 库来使用该算法来结束。
如果你安装了 Python 3.x,你可以在你自己的机器上使用这篇文章中的代码。或者,您可以注册免费试用 Domino MLOps 平台,并直接访问本文中使用的代码(使用本文末尾的 Access Project 按钮)。让我们开始吧。
K-Means -什么意思?
我们提到过,我们对找出数据观察的共性很感兴趣。确定共性或相似性的一种方法是通过测量数据点之间的距离。距离越短,观察结果越相似。我们可以用不同的方法来测量距离,很多人都很熟悉的一种方法是欧几里德距离。没错!也是我们在学习勾股定理时学到的。让我们看一看并考虑对两个属性(a)和(b)的两个数据观察。点(P1 )有坐标((a1,B1))和点(p2 =(a2,B2))。
距离(\overline{p_1 p_2 })由下式给出:
$ $ \ overline { p _ 1 p _ 2 } = \ sqrt {(a _ 2-a _ 1 )^2+(b_2-b_1 )^2 } $ $
上面的表达式可以扩展到两个以上的属性,并且可以测量任意两点之间的距离。对于具有(n)个观察值的数据集,我们假设有(k)个组或聚类,我们的目标是确定哪个观察值对应于这些(k)个组中的任何一个。这是需要强调的重要一点:算法不会给我们聚类的数目,相反我们需要预先定义数目(k)。我们可以用不同的(k)值来运行算法,并确定最佳的可能解决方案。
简而言之,(k )-意味着聚类试图最小化属于一个聚类的观察值之间的距离,并最大化不同聚类之间的距离。通过这种方式,我们在属于一个组的观察值之间有了内聚力,而属于不同组的观察值被进一步分开。请注意,正如我们在这篇文章中解释的那样,(k)-means 是详尽的,因为数据集中的每一个观察值都将被迫成为假设的(k)个聚类之一的一部分。
现在应该清楚了(k)-means 中的(k)来自哪里,但是“means”部分呢?事实证明,作为算法的一部分,我们也在寻找每个聚类的中心。我们称之为质心,当我们将观测值分配给一个或另一个星团时,我们更新星团质心的位置。这是通过取该聚类中包含的所有数据点的平均值(如果愿意,也可以取平均值)来实现的。轻松点。
k-means 的配方
(k)-means 的方法非常简单。
- 决定您想要多少个集群,即选择 k
- 为 k 个簇中的每一个随机分配一个质心
- 计算所有观测到 k 个质心的距离
- 将观测值指定给最近的质心
- 通过取每个聚类中所有观察值的平均值,找到质心的新位置
- 重复步骤 3-5,直到质心不再改变位置
就这样!
看看下面的示意图,其中以示意的方式描述了二维空间的步骤。相同的步骤可以应用于更多的维度(即更多的特征或属性)。为简单起见,在示意图中我们只显示了到最近质心的距离,但实际上需要考虑所有距离。
入门指南
出于实现的目的,为了简单起见,我们将查看一些具有 2 个属性的数据。然后我们将看一个更多维度的例子。为了让我们开始,我们将使用一个我们已经准备好的数据集,它可以在这里获得,名称为 kmeans_blobs.csv 。数据集包含 4 列,包含以下信息:
- ID :观察的唯一标识符
- x:x 坐标对应的属性
- y:y 坐标对应的属性
- Cluster :观察所属的簇的标识符
在我们的分析中,我们将放弃第 4 列,但它可能有助于检查应用(k)均值的结果。我们将在后面的第二个例子中这样做。让我们从读取数据集开始:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
%matplotlib inline
blobs = pd.read_csv('kmeans_blobs.csv')
colnames = list(blobs.columns[1:-1])
blobs.head()
让我们看看数据集中的观察结果。我们将使用 Cluster 列来显示数据集中存在的不同组。我们的目标将是看看该算法的应用是否再现了密切的分组。
customcmap = ListedColormap(["crimson", "mediumblue", "darkmagenta"])
fig, ax = plt.subplots(figsize=(8, 6))
plt.scatter(x=blobs['x'], y=blobs['y'], s=150,
c=blobs['cluster'].astype('category'),
cmap = customcmap)
ax.set_xlabel(r'x', fontsize=14)
ax.set_ylabel(r'y', fontsize=14)
plt.xticks(fontsize=12)
plt.yticks(fontsize=12)
plt.show()
现在让我们看看我们的食谱。
步骤 1 和 2 -定义(k)并初始化质心
首先,我们需要 1)决定我们有多少组,2)随机分配初始质心。在这种情况下,让我们考虑(k=3\ ),至于质心,它们必须与数据集本身在同一范围内。因此,一种选择是随机选取(k)个观察值,并使用它们的坐标来初始化质心:
def initiate_centroids(k, dset):
'''
Select k data points as centroids
k: number of centroids
dset: pandas dataframe
'''
centroids = dset.sample(k)
return centroids
np.random.seed(42)
k=3
df = blobs[['x','y']]
centroids = initiate_centroids(k, df)
centroids
第 3 步-计算距离
我们现在需要计算每个质心和数据点之间的距离。我们将把数据点分配给误差最小的质心。让我们创建一个函数来计算平方误差的根:
def rsserr(a,b):
'''
Calculate the root of sum of squared errors.
a and b are numpy arrays
'''
return np.square(np.sum((a-b)**2))
让我们挑选一个数据点并计算误差,这样我们就可以看到它在实践中是如何工作的。我们将使用点 ,它实际上是我们上面选择的质心之一。因此,我们期望该点和第三个质心的误差为零。因此,我们会将该数据点分配给第二个质心。我们来看看:
for i, centroid in enumerate(range(centroids.shape[0])):
err = rsserr(centroids.iloc[centroid,:], df.iloc[36,:])
print('Error for centroid {0}: {1:.2f}'.format(i, err))
Error for centroid 0: 384.22
Error for centroid 1: 724.64
Error for centroid 2: 0.00
步骤 4 -指定质心
我们可以使用步骤 3 中的想法来创建一个函数,帮助我们将数据点分配给相应的质心。我们将计算与每个质心相关的所有误差,然后选择具有最低值的一个进行分配:
def centroid_assignation(dset, centroids):
'''
Given a dataframe `dset` and a set of `centroids`, we assign each
data point in `dset` to a centroid.
- dset - pandas dataframe with observations
- centroids - pa das dataframe with centroids
'''
k = centroids.shape[0]
n = dset.shape[0]
assignation = []
assign_errors = []
for obs in range(n):
# Estimate error
all_errors = np.array([])
for centroid in range(k):
err = rsserr(centroids.iloc[centroid, :], dset.iloc[obs,:])
all_errors = np.append(all_errors, err)
# Get the nearest centroid and the error
nearest_centroid = np.where(all_errors==np.amin(all_errors))[0].tolist()[0]
nearest_centroid_error = np.amin(all_errors)
# Add values to corresponding lists
assignation.append(nearest_centroid)
assign_errors.append(nearest_centroid_error)
return assignation, assign_errors
让我们在数据中添加一些列,包含质心分配和产生的误差。此外,我们可以使用它来更新显示质心(用正方形表示)的散点图,并根据它们被分配到的质心对观察值进行着色:
df['centroid'], df['error'] = centroid_assignation(df, centroids)
df.head()
fig, ax = plt.subplots(figsize=(8, 6))
plt.scatter(df.iloc[:,0], df.iloc[:,1], marker = 'o',
c=df['centroid'].astype('category'),
cmap = customcmap, s=80, alpha=0.5)
plt.scatter(centroids.iloc[:,0], centroids.iloc[:,1],
marker = 's', s=200, c=[0, 1, 2],
cmap = customcmap)
ax.set_xlabel(r'x', fontsize=14)
ax.set_ylabel(r'y', fontsize=14)
plt.xticks(fontsize=12)
plt.yticks(fontsize=12)
plt.show()
让我们通过将所有贡献相加来看总误差。我们将把这个误差作为收敛的一个度量。换句话说,如果误差不变,我们可以假设质心已经稳定了它们的位置,我们可以终止迭代。在实践中,我们需要注意找到一个局部最小值(超出了本文的范围)。
print("The total error is {0:.2f}".format(df['error'].sum()))
The total error is 11927659.01
步骤 5 -更新质心位置
现在,我们已经第一次尝试定义我们的簇,我们需要更新 k 质心的位置。我们通过计算分配给每个质心的观测值位置的平均值来实现这一点。让我们看看:
centroids = df.groupby('centroid').agg('mean').loc[:, colnames].reset_index(drop = True)
centroids
我们可以验证位置是否已经更新。让我们再次看看我们的散点图:
fig, ax = plt.subplots(figsize=(8, 6))
plt.scatter(df.iloc[:,0], df.iloc[:,1], marker = 'o',
c=df['centroid'].astype('category'),
cmap = customcmap, s=80, alpha=0.5)
plt.scatter(centroids.iloc[:,0], centroids.iloc[:,1],
marker = 's', s=200,
c=[0, 1, 2], cmap = customcmap)
ax.set_xlabel(r'x', fontsize=14)
ax.set_ylabel(r'y', fontsize=14)
plt.xticks(fontsize=12)
plt.yticks(fontsize=12)
plt.show()
步骤 6 -重复步骤 3-5
现在,我们返回来计算到每个质心的距离,分配观察值并更新质心位置。这需要一个函数来封装循环:
def kmeans(dset, k=2, tol=1e-4):
'''
K-means implementationd for a
`dset`: DataFrame with observations
`k`: number of clusters, default k=2
`tol`: tolerance=1E-4
'''
# Let us work in a copy, so we don't mess the original
working_dset = dset.copy()
# We define some variables to hold the error, the
# stopping signal and a counter for the iterations
err = []
goahead = True
j = 0
# Step 2: Initiate clusters by defining centroids
centroids = initiate_centroids(k, dset)
while(goahead):
# Step 3 and 4 - Assign centroids and calculate error
working_dset['centroid'], j_err = centroid_assignation(working_dset, centroids)
err.append(sum(j_err))
# Step 5 - Update centroid position
centroids = working_dset.groupby('centroid').agg('mean').reset_index(drop = True)
# Step 6 - Restart the iteration
if j>0:
# Is the error less than a tolerance (1E-4)
if err[j-1]-err[j]<=tol:
goahead = False
j+=1
working_dset['centroid'], j_err = centroid_assignation(working_dset, centroids)
centroids = working_dset.groupby('centroid').agg('mean').reset_index(drop = True)
return working_dset['centroid'], j_err, centroids
好了,我们现在准备应用我们的函数。我们将首先清理数据集,然后让算法运行:
np.random.seed(42)
df['centroid'], df['error'], centroids = kmeans(df[['x','y']], 3)
df.head()
让我们看看最终质心的位置:
centroids
以图形方式,让我们看看我们的集群:
fig, ax = plt.subplots(figsize=(8, 6))
plt.scatter(df.iloc[:,0], df.iloc[:,1], marker = 'o',
c=df['centroid'].astype('category'),
cmap = customcmap, s=80, alpha=0.5)
plt.scatter(centroids.iloc[:,0], centroids.iloc[:,1],
marker = 's', s=200, c=[0, 1, 2],
cmap = customcmap)
ax.set_xlabel(r'x', fontsize=14)
ax.set_ylabel(r'y', fontsize=14)
plt.xticks(fontsize=12)
plt.yticks(fontsize=12)
plt.show()
正如我们所看到的,已经获得了三个组。在这个具体的例子中,数据表明各组之间的区别是明显的。然而,我们可能不会在所有情况下都这么幸运。所以关于还有多少组织的问题仍然存在。我们可以使用一个屏幕图来帮助我们将误差最小化,方法是查看以序列(k=1,2,3,4,...)并在图中寻找指示要使用的群集数量的“弯头”:
err_total = []
n = 10
df_elbow = blobs[['x','y']]
for i in range(n):
_, my_errs, _ = kmeans(df_elbow, i+1)
err_total.append(sum(my_errs))
fig, ax = plt.subplots(figsize=(8, 6))
plt.plot(range(1,n+1), err_total, linewidth=3, marker='o')
ax.set_xlabel(r'Number of clusters', fontsize=14)
ax.set_ylabel(r'Total error', fontsize=14)
plt.xticks(fontsize=12)
plt.yticks(fontsize=12)
plt.show()
我们现在可以应用“肘规则”,这是一种帮助我们确定聚类数量的启发式方法。如果我们认为上面显示的线条描绘的是一只手臂,那么“肘部”就是拐点。在这种情况下,“肘部”位于 2 到 4 个集群之间,这表明选择 3 是一个很好的选择。
使用 Scikit-learn
我们已经看到了如何对算法进行初步实现,但在很多情况下,你可能希望站在巨人的肩膀上,使用其他经过尝试和测试的模块来帮助你进行机器学习工作。在这种情况下,Scikit-learn 是一个不错的选择,它有一个非常好的(k)-means 实现。如果你想了解更多关于该算法及其评估的信息,你可以看看第 5 章用 Python 进行数据科学和分析,在那里我使用了一个葡萄酒数据集进行讨论。
在这种情况下,我们将展示如何使用众所周知的 Iris 数据集在几行代码中实现 k-means。我们可以直接从 Scikit-learn 加载它,我们将打乱数据以确保这些点没有按任何特定的顺序列出。
from sklearn.cluster import KMeans
from sklearn import datasets
from sklearn.utils import shuffle
# import some data to play with
iris = datasets.load_iris()
X = iris.data
y = iris.target
names = iris.feature_names
X, y = shuffle(X, y, random_state=42)
我们可以调用 KMeans 实现来实例化一个模型并对其进行拟合。参数 n_clusters 为聚类数(k)。在下面的示例中,我们请求 3 个集群:
model = KMeans(n_clusters=3, random_state=42)
iris_kmeans = model.fit(X)
就是这样!我们可以查看算法提供的标签,如下所示:
iris_kmeans.labels_
array([1, 0, 2, 1, 1, 0, 1, 2, 1, 1, 2, 0, 0, 0, 0, 1, 2, 1, 1, 2, 0, 1,
0, 2, 2, 2, 2, 2, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0,
0, 1, 1, 2, 1, 2, 1, 2, 1, 0, 2, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0,
1, 2, 0, 1, 1, 0, 1, 1, 1, 1, 2, 1, 0, 1, 2, 0, 0, 1, 2, 0, 1, 0,
0, 1, 1, 2, 1, 2, 2, 1, 0, 0, 1, 2, 0, 0, 0, 1, 2, 0, 2, 2, 0, 1,
1, 1, 1, 2, 0, 2, 1, 2, 1, 1, 1, 0, 1, 1, 0, 1, 2, 2, 0, 1, 2, 2,
0, 2, 0, 2, 2, 2, 1, 2, 1, 1, 1, 1, 0, 1, 1, 0, 1, 2], dtype=int32)
为了进行比较,让我们对标签重新排序:
y = np.choose(y, [1, 2, 0]).astype(int)
y
array([2, 1, 0, 2, 2, 1, 2, 0, 2, 2, 0, 1, 1, 1, 1, 2, 0, 2, 2, 0, 1, 0,
1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 1, 1, 0, 2, 1, 1, 1, 0, 2, 2, 1,
1, 2, 0, 0, 2, 0, 2, 0, 2, 1, 0, 2, 1, 1, 1, 2, 0, 1, 1, 1, 2, 1,
2, 0, 1, 2, 0, 1, 0, 0, 2, 2, 0, 2, 1, 2, 0, 1, 1, 2, 2, 1, 0, 1,
1, 2, 2, 0, 2, 0, 0, 2, 1, 1, 0, 0, 1, 1, 1, 2, 0, 1, 0, 0, 1, 2,
2, 0, 2, 0, 1, 0, 2, 0, 2, 2, 2, 1, 2, 2, 1, 2, 0, 0, 1, 2, 0, 0,
1, 0, 1, 2, 0, 0, 2, 0, 2, 2, 0, 0, 1, 2, 0, 1, 2, 0])
我们可以检查有多少观察结果被正确分配。我们在混淆矩阵的帮助下做到这一点:
from sklearn.metrics import confusion_matrix
conf_matrix=confusion_matrix(y, iris_kmeans.labels_)
fig, ax = plt.subplots(figsize=(7.5, 7.5))
ax.matshow(conf_matrix, cmap=plt.cm.Blues, alpha=0.3)
for i in range(conf_matrix.shape[0]):
for j in range(conf_matrix.shape[1]):
ax.text(x=j, y=i,s=conf_matrix[i, j], va='center',
ha='center', size='xx-large')
plt.xlabel('Predictions', fontsize=18)
plt.ylabel('Actuals', fontsize=18)
plt.title('Confusion Matrix', fontsize=18)
plt.show()
正如我们所看到的,大多数观察结果都被正确识别。特别是,群集 1 的那些似乎都已被捕获。
让我们看看最后几个集群的位置:
iris_kmeans.cluster_centers_
array([[5.006 , 3.428 , 1.462 , 0.246 ],
[5.9016129 , 2.7483871 , 4.39354839, 1.43387097],
[6.85 , 3.07368421, 5.74210526, 2.07105263]])
我们可以看一些 3D 图形。在这种情况下,我们将绘制以下特征:
花瓣宽度
萼片长度
花瓣长度
如您所见,两个图之间有一些颜色不同的观察结果。
fig = plt.figure(figsize=(20, 10))
ax1 = fig.add_subplot(1, 2, 1, projection='3d')
ax1.scatter(X[:, 3], X[:, 0], X[:, 2],
c=iris_kmeans.labels_.astype(float),
edgecolor="k", s=150, cmap=customcmap)
ax1.view_init(20, -50)
ax1.set_xlabel(names[3], fontsize=12)
ax1.set_ylabel(names[0], fontsize=12)
ax1.set_zlabel(names[2], fontsize=12)
ax1.set_title("K-Means Clusters for the Iris Dataset", fontsize=12)
ax2 = fig.add_subplot(1, 2, 2, projection='3d')
for label, name in enumerate(['virginica','setosa','versicolor']):
ax2.text3D(
X[y == label, 3].mean(),
X[y == label, 0].mean(),
X[y == label, 2].mean() + 2,
name,
horizontalalignment="center",
bbox=dict(alpha=0.2, edgecolor="w", facecolor="w"),
)
ax2.scatter(X[:, 3], X[:, 0], X[:, 2],
c=y, edgecolor="k", s=150,
cmap=customcmap)
ax2.view_init(20, -50)
ax2.set_xlabel(names[3], fontsize=12)
ax2.set_ylabel(names[0], fontsize=12)
ax2.set_zlabel(names[2], fontsize=12)
ax2.set_title("Actual Labels for the Iris Dataset", fontsize=12)
fig.show()
摘要
在这篇文章中,我们解释了(k)-means 算法背后的思想,并提供了这些思想在 Python 中的简单实现。我希望你同意这是一个非常简单易懂的算法,如果你想使用一个更健壮的实现,Scikit-learn 将为我们提供帮助。考虑到它的简单性,(k)-means 是开始聚类分析的一个非常流行的选择。
要访问本文中的代码/数据,请使用下面的 Access Project 按钮。
OpenCV 入门
原文:https://www.dominodatalab.com/blog/getting-started-witn-open-cv
在本文中,我们将讨论计算机视觉的基础、OpenCV 框架的历史和功能,以及如何使用 Python 和 OpenCV 迈出访问和可视化图像的第一步。
介绍
人工智能的最终目标之一是获得理解物理世界状态的能力,并具有与人类相似的对周围环境刺激做出反应的能力。在人类中,这些反应是包括视觉在内的认知功能的产物。这些功能允许人类观察周围环境,并理解和解码视觉感知为上下文信息。
计算机视觉 (CV),作为人工智能的一个跨学科子领域,旨在模仿人类的认知功能,提供类似人类视觉的能力。这些包括理解数字图像的内容、对象的类型以及它们之间的关系。我们认为这个领域是跨学科的,因为不同的学科对 CV 的发展都有贡献。例如,神经科学一直是一个关键的贡献者,因为它能够解码人类的视觉。CV 本质上是计算机科学的一部分,因为机器学习方法和算法理论对于 CV 开发也是必不可少的。
作为人类,我们可以瞬间并以高精度从图像中理解和提取信息。人类可以识别物体及其关系,并可以通过语言交流他们对视觉世界的感知。例如,在检查图 1 中描绘的图像时,我们可以识别出一只狗和所描绘的动作,即这只狗正在跳过一个有条纹的跨栏。我们能识别颜色(黑、白、蓝、黄等)。)和组成对象的特征(形状、边缘等)。).另外,背景中有两个人,一个站着,一个坐着。
根据不同的物体和相关的动作,我们可以推断这张照片可能是一场狗展。然而,对于人工智能算法来说,获取和应用这种看似简单的人类能力存在一系列困难,特别是对于需要上下文理解的复杂图像[1]。
简而言之,视觉系统中有两个主要组件:a)感测/捕捉和 b)解释/转换组件。在人类中,我们的眼睛充当着传感装置,通过捕捉从物体反射的光,通过虹膜接收,并投射到视网膜上。从那里,专门的细胞将通过神经元向大脑传输信息。这些信息随后被大脑的视觉皮层解码成意义。
图一。人类对图像的视觉感知导致对物体及其关系的即时检测。来源:Flickr8K 数据集
我们可以识别出这个图像包含许多对象,并描绘了一个活动(狗跳过一个障碍)。这些信息也让我们推断这可能是一场狗展。
对于计算机,相机可以充当传感/捕捉组件,以像素的形式存储和传输图像信息。CV 环境中的解释组件是一个 AI 代理,这就是 CV 仍然落后于自然视觉系统的地方。将像素转换为意义是 CV 对于计算机来说仍然是一项艰巨任务的首要原因。例如,图 1 中的图像是 500 x 497 像素,具有红色、绿色和蓝色(RGB)通道。将这些像素转换成有意义的信息和准确的图像描述对于人工智能代理来说仍然是一项艰巨的任务。
人类视觉系统可以快速感知和解释图像,据报道可以在 150 毫秒内将动物从自然场景中分类出来[3]。人类也可以自然地在解释图像时涉及上下文。例如,我们可以使用我们的先验知识推断,图 1 中的图像可能说明了一个狗展事件。这是一个显著的优点,但是很难结合到 CV 算法中。我们视觉系统中内置的注意力机制也是有利的,但这也意味着我们的大脑不倾向于集中注意力的图像部分的修改可能不会被捕捉和注意到。
计算机视觉在许多领域提供了不同的应用。它允许娱乐行业中的特殊效果,并为图像分类、对象识别和跟踪、人脸检测、基于内容的图像检索、自动驾驶汽车、机器人、医疗、安全和教育提供能力。
深度学习的最新进展,加上这些方法利用图形处理单元(GPU)进行加速训练的能力,以及大型标签数据集的可用性,彻底改变了简历的前景。他们利用神经网络的优势来解决传统机器学习无法有效解决的 CV 任务。传统的方法依赖于提取图像特征来解决包括图像分类在内的各种任务。这个特征提取步骤是费力且有偏见的,因为它可能无法提取准确结果所需的所有足够的特征。深度学习方法通过自动和无偏见地提取图像特征来绕过这一步。
有多种 Python 工具可用于 CV 相关任务,其中之一是开源计算机视觉(OpenCV);一个免费的开源库,广泛应用于学术和商业领域,包括谷歌、英特尔、微软和 IBM。OpenCV 由 Intel 于 2000 年 6 月在 BSD 许可下发布,用 C++编写,具有对不同编程语言的 API 支持,包括 Python、Java 和 MATLAB [4]。
OpenCV-Python 是 OpenCV 的一个 API,利用 Python 和 OpenCV C++ API 的优势。对于 Python 来说,这是一个绑定库,旨在解决以 CV 为中心的任务。它利用 NumPy 及其数组结构,允许与其他库(包括 SciPy 和 Matplotlib)无缝集成。它支持不同的平台,允许它在 Windows、Linux 和 macOS 以及移动操作系统上运行。
OpenCV 已用于图像预处理、对象检测、分割、人脸检测和识别、人脸姿态估计和对准、增强现实、导航和跟踪等各种领域支持应用[5-12]。此外,OpenCV 包括丰富的预定义函数,并提供了一系列机器学习库,包括 boosting、决策树、 KNN 、朴素贝叶斯、随机森林、支持向量机和深度神经网络。
在下面的章节中,我们将介绍 OpenCV 提供的一些功能,包括对象检测、特征提取和分类。
安装 OpenCV
第一步是安装 OpenCV-Python。最初的要求是安装 Python 和 pip (一个包管理系统)。要安装 OpenCV,请运行以下命令行命令:
pip install opencv-python
要在 Jupyter 笔记本中成功运行这段代码,需要一个感叹号(!)需要在 pip 之前使用:
!pip install opencv-python
这将启动下载 OpenCV 和安装依赖项(NumPy)。完成后,将显示确认成功安装的消息。随后可以导入该库:
import cv2
打开并显示图像文件
OpenCV 允许读取不同类型的图像(JPG,PNG 等),可以是灰度或彩色图像。读取图像的内置函数是 cv2.imread() ,语法结构如下:
image = cv2.imread(filename, flags)
在上面的例子中,“image”是存储“filename”信息的变量。我们可以看到有两个输入:“文件名”和“标志”:
- filename :必需的参数和图像的位置,可以作为相对或绝对路径提供。
- flags :这是一个可选参数,用于读取特定格式的图像。例如,灰度、彩色或 alpha 通道。默认值为 cv2。IMREAD_COLOR 或 1,它将图像加载为彩色图像,下面更详细地描述了这些标志:
- cv2。im read _ gray 或 0:以灰度模式加载图像。
- cv2。IMREAD_COLOR 或 1:加载彩色图像的默认标志。图像的任何透明度都将被忽略。
- cv2。IMREAD_UNCHANGED 或-1:加载包含 alpha 通道的图像。
为了显示一个图像文件,我们可以利用 imshow() 内置函数来显示 NumPy 2D 数组的表示,该数组是在使用 imread() 函数读取图像后产生的。需要强调的是,OpenCV 库使用不同的格式来存储频道信息;BGR 而不是 RGB 顺序。为了正确地显示 RGB 中的原始彩色图像,我们需要交换通道的顺序。这可以通过 NumPy 切片或者 cv2.cvtColor() 内置函数来实现。下面的代码块演示了整个过程,输出图像如图 2 所示。
f = plt.figure(figsize=(25, 20))
f.add_subplot(1, 4, 1)
# The return from imread is numpy 2D array representing the image
img_gray = cv2.imread("Resourcimg/face.jpg", 0)
# We can use imshow to display a representation of the numpy 2D array. To display an image defining an appropriate colormap is required. For grascale image the colormap is "gray"
plt.imshow(img_gray, cmap="gray");
plt.grid(None)
plt.title("Image in gray");
# OpenCV library uses different format for storing channel information; BGR order convention instead of RGB order. To properly show the original colour image in RGB, we need to swap the order of channels.
f.add_subplot(1, 4, 2)
img_bgr = cv2.imread("Resourcimg/face.jpg", 1)
plt.imshow(img_bgr);
plt.grid(None)
plt.title("Image in BGR");
# A way to reorder the channels to RGB:
f.add_subplot(1, 4, 3)
img_rgb = img_bgr[:, :, ::-1]
plt.imshow(img_rgb);
plt.grid(None)
plt.title("Image in RGB, manual swap");
图二。使用 OpenCV 内置函数读取和显示 RGB 格式的图像。
摘要
在这篇文章中,我们讨论了计算机视觉——人工智能领域,使计算机能够从图像中获取有意义的信息。我们还讨论了 OpenCV 的历史和功能——这是一个免费的跨平台库,用于解决广泛的计算机视觉问题。
在本文的第二部分中,我们将探讨各种特征提取和图像分类技术(例如 SIFT、ORB 和 FAST ),并展示使用深度神经网络的对象分类。
额外资源
您可以查看以下附加资源:
- OpenCV 上的免费在线课程-https://opencv.org/opencv-free-course/
- OpenCV 官方文档-https://docs.opencv.org/4.x/
- 有一个附带的项目,其中包含本文的所有代码,您可以通过注册免费的 Domino MLOps 试用环境来访问它:
参考
[1] N. Sharif、U. Nadeem、S. A. A. Shah、M. Bennamoun 和 W. Liu,“从视觉到语言:方法、度量和数据集”,载于《机器学习范例:施普林格》,2020 年,第 9-62 页。
[2] C. Rashtchian、P. Young、M. Hodosh 和 J. Hockenmaier,“使用亚马逊的土耳其机器人收集图像注释”,载于 NAACL HLT 2010 年关于使用亚马逊的土耳其机器人创建语音和语言数据的研讨会会议录,2010 年,第 139-147 页。
[3] S. Thorpe、D. Fize 和 C. Marlot,“人类视觉系统的处理速度”,《自然》,第 381 卷,第 6582 期,第 520-522 页,1996 年。
[4] G. Bradski,“openCV 库”,Dobb 博士的杂志:专业程序员的软件工具,第 25 卷,第 11 期,第 120-123 页,2000 年。
[5] A. A. Chaaraoui,P. Climent-Pérez 和 F. Flórez-Revuelta,“使用关键姿势序列进行基于轮廓的人体动作识别”,《模式识别快报》,第 34 卷,第 15 期,第 1799-1807 页,2013 年。
[6] N. Marku,M. Frljak,I. S. Pandž,j .阿尔贝里和 R. Forchheimer,“决策树中组织的像素强度比较的对象检测”,arXiv 预印本 arXiv:1305.4537,2013 年。
[7] N. Marku,M. Frljak,I. S. Pandž,j .阿尔贝里和 R. Forchheimer,“用随机树集合进行瞳孔定位”,《模式识别》,第 47 卷,第 2 期,第 578-587 页,2014 年。
[8] F. Timm 和 E. Barth,“通过梯度实现精确的眼睛中心定位”,Visapp,第 11 卷,第 125-130 页,2011 年。
[9] D. S. Bolme、B. A. Draper 和 J. R. Beveridge,“合成精确滤波器的平均值”,2009 年 IEEE 计算机视觉和模式识别会议,2009 年:IEEE,第 2105-2112 页。
[10] X. Cao,Y. Wei,F. Wen,和 J. Sun,“基于显式形状回归的人脸对齐”,国际计算机视觉杂志,第 107 卷第 2 期,第 177-190 页,2014 年。
[11] M. Danelljan、g . hger、F. Khan 和 M. Felsberg,“鲁棒视觉跟踪的精确比例估计”,英国机器视觉会议,诺丁汉,2014 年 9 月 1-5 日,2014: Bmva 出版社。
[12] K. Zhang,L. Zhang,M.-H. Yang,“快速压缩跟踪”,IEEE 模式分析与机器智能汇刊,第 36 卷,第 10 期,第 2002-2015 页,2014 年。
Domino 5.0:轻松利用 Git 存储库来提高模型速度
在 Domino 5.0 中利用 Git 支持的项目
由五月胡,达美乐高级产品经理,于 2022 年 2 月 14 日在 进行产品更新
Domino 自动跟踪所有实验工件,因此数据科学工作是可再现的、可发现的和可重用的——提高 模型速度 并降低监管风险。这些工件可以记录为 Domino 文件系统(DFS)的一部分,但许多公司现在更喜欢使用集中式 Git 代码存储库(例如, GitHub , GitLab , Bitbucket ),以便数据科学代码可以与公司 CI/CD 工作流的其余部分集成,从而提高一致性和治理。
Domino 支持常见的 Git 工作流,比如拉最新内容、推送更改、浏览文件等等——所有这些都是在 Domino 工作区内与您选择的 Git 服务提供商之间进行的。这种 Git-first 的体验让用户能够更好地控制复杂工作流的同步和版本控制,并使他们能够轻松地与其他团队成员进行版本控制、基于代码的协作。
Domino 5.0 通过简化切换分支所需的步骤,并通过指导用户通过一致的流程来解决将代码合并到他们选择的存储库时的冲突(而不是在不同环境之间手工跳转),改进了现有的功能。
切换工作区中的分支
分支允许数据科学家开发特性、修复 bug,或者在其存储库的封闭区域中安全地试验新想法。为了最大限度地提高工作效率,数据科学家可以在他们的工作区内快速切换主代码存储库和任何其他导入存储库的分支。
数据科学家可以轻松地从下拉菜单中列出的多达 10 个分支中进行选择。如果存储库有 10 个以上的分支,可以选择搜索更多的分支。
解决合并冲突
当对代码行甚至整个文件进行竞争性更改(例如删除文件)时,会发生合并冲突。未能正确管理冲突会导致组织的存储库被破坏——这将需要数据科学家花费时间来确定存储库中错误的原因。
当将工作区中的更改同步到 Git 存储库,或者将最新的更改从存储库拉入工作区时,Domino 首先从远程分支获取最新的内容(git fetch)。接下来,在更新的分支之上应用变更(git rebase)。如果检测到冲突,Domino 会引导用户通过基于 UI 的工作流,在将代码合并到他们选择的存储库时一致地解决冲突。
它是如何工作的
切换工作区中的分支
- 遵循 这篇文章 在 Domino 中创建一个基于 Git 的项目。
- 使用所需的 IDE 创建并启动工作区。
- 无需离开工作区,轻松在分支之间切换。
提取文件时解决冲突
- 为主代码库或导入的库选择“Pull”。
- 如果存在合并冲突,将出现以下警告:
“使用远程更改”将放弃工作区中的更改,并用远程更改覆盖工作区中的文件。
【手动解决】将引导用户通过文件名解决冲突。对于每个有冲突的文件,用户可以选择以下选项之一:
- “标记为已解决”假设文件已被编辑以解决冲突标记。
- “使用我的更改”将用工作区中的更改覆盖远程文件。
- “使用原始存储库更改”将放弃工作区中的更改,并用远程更改覆盖文件。
同步更改时解决冲突
- 对于主代码库或导入的库,单击“Sync”。
- 如果检测到冲突,用户将收到以下警告和选项:
- “强制我的更改”将用您工作区中的更改覆盖远程文件。这意味着远程上的提交历史将与您的工作区中的提交历史相匹配。
- “手动解决”将引导用户通过文件名解决冲突。
结论
Domino 继续帮助数据科学家变得更加高效,同时帮助组织在成为模型驱动的过程中提高一致性和效率。Domino 5.0 允许数据科学家轻松地满足利用集中式代码存储库的企业级需求。由于能够在工作区的分支之间轻松切换,数据科学家可以专注于改进代码和运行实验。管理冲突的新步骤有助于数据科学家更有效地检入代码,并确保组织的存储库可以被信任和维护。
Domino 是 企业 MLOps 平台,它无缝集成了代码驱动的模型开发、部署和监控,以支持快速迭代和最佳模型性能,因此公司可以确保从其数据科学模型中实现最大价值。
关于作者
| | May Hu 是一名高级产品经理,在 ML 平台和云技术领域拥有多年经验。她目前领导 Domino 数据实验室的协作和自动化宪章的产品战略。 |
Domino 中的 Git 集成
我们最近发布了新的功能,提供了 Domino 和 git 之间的一流集成。这篇文章描述了这个新特性,并描述了我们对数据科学(不同于软件工程)工作流环境中版本控制的独特需求的观点。
问题是
在一条现在很有名的推特上,艾萨克·沃尔克斯托弗曾经说过:“一旦你有了分支是映射希尔伯特空间子流形的同胚内函子的基本概念,事情就变得简单了。”虽然他在 Quora 的一个回答中澄清说,这种说法完全是在开玩笑,但通过模因的扩散和人们在搜索该字符串时找到的数千个谷歌结果,很明显答案引起了共鸣。
在最近一次对数据科学家的调查中,超过 85%的人肯定地回答说他们正在他们的工作流程中利用 git。绝大多数的数据科学家直接接触并分享了他们使用 git 的感受,但只是以一种货物崇拜的方式。命令被记忆和重复,作为对再现神的咒语,他们可能会对这个项目微笑,让结果和发现存活和茁壮成长。我们认为有更好的方法。
Domino 的 Git 集成
Domino 数据科学平台的集成充分利用了 git 的能力和我们的再现性引擎技术。这种集成支持许多工作流,目前正被财富 50 强客户用来让他们的数据科学团队从软件、管道和 git 基础设施的现有投资中获得价值。
这一集成的三个亮点包括:
能够以精确的提交散列检查多个存储库
任何只让你处理单个分支或者只能检查头部的 git 集成都是非常有限的,没有实际用途。Domino 允许您添加任意数量的存储库,每个存储库都可以独立启用或禁用,并且可以在签出时指定确切的提交散列或分支。
与再现性引擎集成
对于您在 Domino 中执行的每一个实验,reproducibility engine 都会准确地记录启用了哪些存储库,以及它们的开始和结束提交状态。如果在项目过程中,您必须提交和推回存储库中的更改,Domino 会跟踪这些信息,并使其在实验的 details 选项卡中立即可用。
该功能扩展了我们跟踪导入到项目、环境等中的规范数据集的信息的能力。客户可以利用这些信息对他们正在使用的内部工具做出明智的决定,并且更容易地提供他们的团队每天使用的依赖项和包的鸟瞰图。
未保存的工作验证
如果一个项目与 git 集成,并且用户在他们的存储库中有变更,如果他们试图在没有保存和提交他们的变更的情况下关闭实验,Domino 将提供有用的提醒。
数据科学家不一定是 git 用户专家。例如,我们从与数据科学团队的合作中了解到,对于何时将工作真正保存到 git 存储库中存在混淆。
Domino 的集成不仅仅是提供一个可用的 git 存储库,它还包括理解数据科学家如何使用 git 工作,并提供工具和工作流来尽可能容易地利用企业代码库。
结论
数据科学家的工作很复杂,通常跨越多个学科。从软件工程到数学和统计、运筹学、物理学和许多其他领域,数据科学家都需要快速、可重复地完成工作。
版本控制系统在再现性的工具箱中提供了一个重要的工具,但是它们被设计用来跟踪软件工件。它们不足以处理数据科学家每天使用的代码、数据、环境、包以及外部和内部存储库之间的复杂交互。
数据科学家终于拥有了围绕他们工作方式设计的版本控制和再现性。无论是从事实验、管道、可视化、生产中的模型还是其他任何工作,Domino 的 reproducibility engine 及其一流的 git 集成提供了科学家信任的工具和安全数据,以保护他们自己和未来合作者的工作。
Google 的 Kozyrkov 告诉 Rev 3,“数据科学的宇宙正在扩张”,“不可思议的”MLOps 工具正在出现
在关于数据科学 及其在全球范围内改变世界的影响的 Rev 3 会议的第二天,谷歌首席决策科学家 Cassie Kozyrkov 对 700 多名观众说:“数据科学的宇宙正在扩张,”这些观众主要由数据科学家、数据科学领导者和 IT 主管组成。如此众多的与会者——在活动的最后一个上午,会议总注册人数超过了 1000 人——证明了该行业的规模、权力和声望都在增长。
摇滚明星主题演讲人的名单也是如此,他们为与会者提供了各种建议,从职业发展和进步,到开发更少噪音和偏见的模型,到制药和其他行业的 IT-数据科学合作,以及如何不断改进,随着时间的推移,最终带来翻天覆地的变化。观众显然很喜欢它,在演讲结束后,演讲者们蜂拥而至,希望听到更多。
科济尔科夫在主题演讲后回答问题。
数据科学家正处于优势地位——多米诺的“不可思议的,可爱的”MLOps 支持他们
Kozyrkov 告诉热情的观众,数据科学家的优势和最近的成功导致了对他们的期望的爆炸。
“许多数据科学家有冒名顶替综合症,因为他们自己不能完成整个任务,”她说。
但是,Kozyrkov 说,一个积极的迹象是,公司正在押注于他们的数据科学团队,这是专为帮助他们获得工作所需的 MLOps 资源而设计的工具的出现。她将奥运会游泳池制造商的增长进行了类比,这些制造商最初认为,用于休闲游泳的游泳池也可以为冠军服务。随着时间的推移,随着竞技游泳运动员的数量和重要性日益增加,奥林匹克游泳池被定义并推向市场。
Kozyrkov 说,类似地,数据科学家拥有的用于提供资源和检测模型衰退等事情的原始工具相当原始,难以使用,因为它们是为其他技术职业设计的,而不是为数据科学家和他们的领导者设计的,甚至不是为试图假设他们的 IT 专业人员设计的..
但是随着数据科学变得越来越受重视,像多米诺数据实验室这样的公司正在投资工具来支持这个年轻的职业。
“我们的 Rev 3 主机,Domino 数据实验室,为数据科学家 制作了 工具,这些工具令人难以置信,非常有用,非常可爱,”她告诉观众。"这就是我们数据科学社区的宣传看起来的样子。"
卡斯·桑斯坦“督促”数据科学家实现更好的模型准确性
随着更大的权力而来的是更大的责任,哈佛大学教授卡斯·桑斯坦(Cass Sunstein)和《纽约时报》《星球大战的世界》 和 敦促观众提防两个可能使他们的模型脱轨的问题:偏见和噪音。
“偏见是错误的来源,噪音是它更安静、更年轻的兄弟,”他说。“噪音导致不公平,败坏组织的名声,成本,成本,成本,”他警告说。
例如,在医疗保健领域,Sunstein 噪音和偏见可能会导致对不需要接受心脏病等疾病测试的人进行测试,而对应该接受测试的人进行测试失败,这可能会导致负面的健康影响。
当好的模型变坏时
此外,桑斯坦说,当 人工智能和人工智能模型变坏 时的暴露会导致对所有人工智能和人工智能增强模型的恐惧增加。
“比起原谅模型,人们更容易原谅人为错误,”桑斯坦说。
Sunstein 建议将模型和决策分解成更小的部分以改善结果。
“超级预测者[预测高度准确的人和模型]将决策分解成组成部分,”Sunstein 说。
虽然 Sunstein 的演讲侧重于模型可能出错的方式——以及模型缓解措施的建议——但他总体上非常乐观,认为在未来几年,数据科学从业者可以比以往任何时候都更好地促进人类的最佳利益。
“在过去的 100 年里,我们有机会减少偏见和噪音,从而延长寿命,改善健康和福祉。但我们还没有看到任何东西,”桑斯坦总结道。
首席信息官吉姆·斯旺森:“公司押注数据科学来推动决策”
该行业的未来在其他方面看起来也很光明,整个活动的发言者都提到了过去三年需求的飞速增长。
“现在在数据科学领域有更多的机会。强生公司的首席信息官吉姆·斯旺森对听众说:“公司正押注于数据科学来推动决策。
斯旺森还承认,由此带来的对专业人士需求的增加使其成为一个热门的劳动力市场,各公司为争夺人才而激烈竞争 。在谈到科济尔科夫之前的讲话时,他提到无形资产——比如加入抗击疾病和促进人类健康的使命的愿望——往往是决定性因素。
“我不能支付凯西(在谷歌)所能支付的工资,但我可以在任务中竞争,”他对人群说,这指的是该公司作为制药和医疗保健领导者的地位。
Swanson 还表示,未来需要拥有更广泛技能的数据科学家。
“我们需要更多双语数据科学家——一部分是数据科学家,一部分是领域专家的人,”他说。
当谈到在其组织内推广数据科学时,重要的是了解公司最关心的指标,并动员数据科学的努力来支持这些目标。
“如果他们关心管道的净现值(NPV),我们会询问一切,‘我们是否将数据科学与此相关联’,”他说。
“当他们看到对他们所关心的措施很重要的结果时,我们得到了极大的鼓舞,”Swanson 说,资源和认可更加自由地流动。这对数据科学家和整个行业都有好处。
James Clear 建议数据科学家和他们的团队养成“原子习惯”
最后,会议以 NYT 畅销书《原子习惯》的作者 James Clear 的数据驱动的励志演讲结束。他说,考虑一下在一些相关指标上提高 1%对任何团队或个人的绩效的影响,这相当于提高了 37 倍。接下来,将它与同样时间内做了 1%的坏事进行比较;一年结束时,绩效接近于零。
Clear 说,诀窍在于建立能带来小进步的仪式,并奖励自己坚持下去。从获胜的运动队到成功的企业,Clear 说,胜利者是那些能够凭借习惯的力量保持许多小进步的人。
基于 PyTorch 的 GPU 加速卷积神经网络
原文:https://www.dominodatalab.com/blog/gpu-accelerated-convolutional-neural-networks-with-pytorch
卷积神经网络(CNN 和 ConvNets)是一类通常用于图像分类(将图像数据映射到类值)的神经网络。在高层次上,CNN 可以简单地视为前馈网络的变体,但是与用于分析视觉图像的更传统的算法相比,它们具有许多优势。
- CNN 利用了视觉合成的层次性,从简单的图元开始,将它们组合起来产生越来越复杂的模式。这最终实现了特性选择阶段的自动化,使 ConvNets 比其他依赖手工特性的技术更有优势。
- 作为神经网络,CNN 也受益于可扩展的架构,并且也适合 GPU 加速的训练。这使得它们成为处理大型数据集的好选择。
- 经典的前馈神经网络是完全连接的,这意味着它们计算量很大,并且随着其参数数量的增加,容易过拟合。另一方面,ConvNets 的卷积层和汇集层在将数据馈送到完全连接的层之前减少了原始维度,从而使网络的计算量更小,并且不太可能过度拟合。
卷积图像
CNN 的核心是卷积——通过对图像的每个像素及其邻居应用内核(另一个矩阵)来转换输入图像(一个矩阵)的过程。从数学的角度来看,卷积运算产生的函数显示了第二个函数如何修改第三个函数。在不涉及数学细节的情况下,使用卷积进行图像处理背后的直觉如下:原始图像被视为矩阵,其中每个元素表示单个像素。这些可以是 0 或 1(对于单色图像)或给定范围内的整数(例如,0-255 表示灰度图像中的强度)。对于彩色图像,我们通常使用多个矩阵,每个通道一个矩阵,事情变得稍微复杂一些,但原理是相同的。
CNN 中的卷积层使用核或滤波器,它只是另一个更小维度的矩阵(例如 3×3、5×5 等)。).内核滑过图像,在相同大小的小块上运行。然后,通过执行逐元素的矩阵乘法并将结果元素加在一起以产生单个标量,来卷积当前面片和内核。这个过程如下图所示。
本例中的内核大小为 3x3,因此我们从原始图像的左上角开始获取一个 3x3 的补丁。图像块和内核被卷积以产生单个标量值- 25。然后,我们将选择滑动到右边,并采用第二个补丁来产生第二个输出元素。我们重复该操作,直到我们用尽原始图像中所有可能的补片。请注意,使用 3x3 的补丁,我们可以在水平方向上做四张幻灯片,在垂直方向上做另外四张幻灯片。因此,在 6x6 图像上应用 3x3 内核的结果是 4x4 输出矩阵。这也展示了卷积如何实现降维,但这通常不是我们减少输出大小所依赖的主要机制。
让我们观察用两个内核卷积随机图像的效果。首先,我们从原始图像开始——漂亮的 Atari 800 8 位家用电脑的照片。
用下面的内核卷积这个图像
| one | one | one |
| one | one | one |
| one | one | one |
导致图像稍微模糊。
这种转变不容易发现,但结果并不总是那么微妙。例如,我们可以用下面的内核对原始图像进行卷积。
| Zero | one | Zero |
| one | -4 | one |
| Zero | one | Zero |
这会产生以下输出图像:
这种变换对于边缘检测非常有用。还要注意,在这种情况下,我们保留了原始图像的尺寸。最简单的方法是在原始图像的边界周围填充零,这样我们就可以得到许多与其原始分辨率相同的补片。我们提到这一点只是为了清楚起见,因为这对于理解图像与内核的卷积并不重要。
现在,如果你后退一步,想想应用滤波器的输出结果,你会意识到你可以把滤波器看作特征检测器。例如,在上面的图像中,我们可以看到每个图像块有多少类似于边缘的东西。通过使用各种只能检测水平或垂直边缘的内核,可以更加精确。你可以使用内核来检测拱门,对角线等等。在图像上滑动图像补丁窗口并使用适当的内核本质上是一种模式检测机制。
卷积神经网络的体系结构
既然我们已经了解了卷积是如何被用作 CNN 的构建模块的,那么让我们来讨论一下典型的网络架构是什么样子的。一般来说,CNN 网络具有两个功能上不同的元件,一个负责特征提取,另一个负责基于提取的特征执行分类。
网络的特征提取(或特征学习)部分采用一系列卷积和汇集层。
-
每个卷积层应用一个滤波器,它与输入卷积以创建一个激活图。正如我们在上一节中已经展示的,滤波器在图像上滑动(水平和垂直),并且为每个空间位置计算输出标量。如果图像包含关于颜色的数据,典型的方法是分别处理每个颜色通道,产生张量而不是简单的 2D 矩阵。
-
卷积层通常保持输入的维度。这可能是有问题的,因为相同的特征(例如,边缘或直线)如果出现在图像中的不同位置,会导致不同的特征图。共享层是 ConvNets 用来应对这一挑战的。这些图层对影像进行下采样以降低分辨率,同时保留要素地图中存在的要素。
上图显示了一个 max pooling 图层,该图层汇总了 4x4 要素地图中最活跃的要素。您会看到池层将特征地图划分为四个区域,并为每个面片创建一个具有最大值的标量。这是一个所谓的最大池层 的例子。还有其他类型的池,例如 平均池层 。在这种情况下,池层不是从每个区域中取最大值,而是生成给定区域中所有数字的平均值。
请注意,没有硬性要求成对使用卷积层和池层。例如,在 CNN 架构中,多个卷积层之后是单个 max 池层。其他架构在每个卷积层之后添加 RELU 层,依此类推。
网络的这一部分负责执行实际的分类,其输出数量对应于数据集中的类的数量。输出通常在 softmax 函数之后进行评估,soft max 函数用于将原始分数压缩为加起来等于 1 的标准化值。这是处理分类问题的经典前馈网络的标准配置。
一种用于图像分类的简单 CNN
现在我们知道了足够多的理论,让我们看看使用 PyTorch 和 GPU 加速(如果可用的 GPU 硬件可用)训练卷积神经网络的过程。我们从导入我们需要的所有 Python 库开始:
import torch
import torchvision
import torchvision.transforms as transforms
import numpy as np
import matplotlib.pyplot as plt
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
import time
现在让我们看看 CUDA 是否可用,并为 PyTorch 设置合适的设备,以便我们的网络可以使用它。
if torch.cuda.is_available():
print("CUDA available. Using GPU acceleration.")
device = "cuda"
else:
print("CUDA is NOT available. Using CPU for training.")
device = "cpu"
我们现在开始加载数据集并定义 10 个可能的对象类。
cifar10 = np.load("/domino/datasets/CIFAR10/cifar10.npz")
X_train = cifar10["X_train"]
y_train = cifar10["y_train"].flatten()
X_test = cifar10["X_test"]
y_test = cifar10["y_test"].flatten()
classes = ("plane", "car", "bird", "cat", "deer", "dog", "frog", "horse", "ship", "truck")
现在让我们把所有的图片分成 255,这将把它们从 0-255 重新调整到 0-1。我们还将把它们从整型转换成浮点型,这使得计算更加方便。
X_train = X_train.astype("float32") / 255
X_test = X_test.astype("float32") / 255
让我们从我们的训练集中挑选出前 10 幅图像,并把它们画出来,这样我们就能知道我们在处理什么了。
最后,我们将当前保存图像的 NumPy 数组转换为 PyTorch 张量,并将它们发送到适当的设备(如果 CUDA 可用,则发送到 GPU,否则发送到普通内存)。
X_train = torch.tensor(X_train, device=device).permute(0, 3, 1, 2).float()
y_train = torch.tensor(y_train.flatten(), device=device)
这是我们网络的定义。您可以看到,它由两个卷积层、两个池层、一个批量标准化层(用于稳定学习)和三个执行线性变换的全连接层组成。
class Net(nn.Module):
def __init__(self):
super().__init__()
self.conv1 = nn.Conv2d(3, 6, 5)
self.pool = nn.MaxPool2d(2, 2)
self.conv2 = nn.Conv2d(6, 16, 5)
self.batch_norm = nn.BatchNorm2d(16)
self.fc1 = nn.Linear(16 * 5 * 5, 120)
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, 10)
def forward(self, x):
x = self.pool(F.relu(self.conv1(x)))
x = self.pool(F.relu(self.conv2(x)))
x = self.batch_norm(x)
x = torch.flatten(x, 1) # flatten all dimensions except batch
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = self.fc3(x)
return x
net = Net()
net.to(device)
我们可以绘制训练损失图,并确认它随着训练而减少。
fig = plt.figure(figsize=(6,4))
plt.plot(loss_hist)
plt.xlabel("Iterations")
plt.ylabel("Loss")
plt.title("Global loss for the CNN model")
plt.show()
现在让我们用一些看不见的数据来测试这个模型。我们将使用保留集进行预测,绘制前十幅图像及其各自的预测标签。
outputs = net(torch.tensor(X_test, device=device).permute(0, 3, 1, 2).float())
_, predicted = torch.max(outputs, 1)
fig, ax = plt.subplots(1,10,figsize=(15,2))
for i in range(10):
ax[i].imshow(X_test[i])
ax[i].axes.xaxis.set_ticks([])
ax[i].axes.yaxis.set_ticks([])
ax[i].title.set_text(classes[predicted[i]])
plt.show()
总的来说还不错,考虑到简单的网络架构和我们没有在超参数调优上花费任何时间的事实。
摘要
在本文中,我们介绍了卷积神经网络(CNN ),并提供了一些关于它们如何提取特征和降低维数的直觉。CNN 主要用于解决计算机视觉问题,但它们也应用于其他机器学习领域:
- 推荐系统——CNN 常用于推荐系统(参见杨等,2019;Krupa 等人,2020),尤其擅长处理非结构化数据(如视频和图像)。它们是很好的特征提取器,可以帮助缓解冷启动问题。
- 自然语言处理-CNN 可用于情感分析和问题分类(Kim,2014)、文本分类(张、赵、乐存,2015)、机器翻译(Gehring et al .,2016)等
- 时间序列分析(雷,吴,2020)等
如果您想研究本文中的示例代码,请注册一个免费的 Domino 帐户,您将可以立即访问一个笔记本和一个 Python 脚本来进行实验。项目名称为sample-project-2 _ GPU-trained-CNNs,会自动出现在您的项目部分。
参考
使用两级 CNN 的情绪感知智能音乐推荐系统。2020 年第三届智能系统和发明技术国际会议(ics it)(2020 年):1322-1327。https://ieeexplore.ieee.org/document/9214164
丹阳,张箐,王史风,张学东,“一个时间感知的基于 CNN 的个性化推荐系统”,复杂性,2019 卷,文章 ID 9476981,11 页,2019。https://doi.org/10.1155/2019/9476981
张,项,赵军波,杨乐存。2015.用于文本分类的字符级卷积网络。https://papers . nips . cc/paper/5782-character-level-convolutionary-networks-for-text-class ification . pdf
乔纳斯·格林,迈克尔·奥利,大卫·格兰吉尔,扬·多芬。2016.一种用于神经机器翻译的卷积编码器模型,
雷、、吴。"基于统计特征的时间序列分类."EURASIP 无线通信和网络杂志 2020 (2020): 1-13。https://www . semantic scholar . org/paper/Time-series-class ification-based-on-statistical-Lei-Wu/529 f 639407 CB 6b 3 b 591 b 69 a 93 de 9 c 7124 c 826 fa 7
利用 GPU 和 Theano 实现更快的深度学习
原文:https://www.dominodatalab.com/blog/gpu-computing-and-deep-learning
Domino 最近增加了对 GPU 实例的支持。为了庆祝这一发布,我将向您展示如何:
- 配置 Python 库 Theano 来使用 GPU 进行计算。
- 用 Python 构建和训练神经网络。
使用 GPU ,我将展示我们可以比只使用 CPU 快 15 倍地训练深度信念网络,将训练时间从几小时缩短到几分钟。
GPU 为什么有用?
当你想到高性能显卡的时候,首先想到的可能不是数据科学。然而,计算机图形学和数据科学有一个重要的共同点:矩阵!
图像、视频和其他图形被表示为矩阵,当您执行某个操作时,例如相机旋转或放大效果,您所做的只是对矩阵应用一些数学变换。
这意味着,与 CPU(中央处理器)相比,GPU 更擅长执行矩阵运算和其他高级数学转换。在某些情况下,当一个算法在 GPU 上运行时,我们会看到它有 10 倍的加速。
从基因组学到流行病学,基于 GPU 计算已经被广泛应用于各种科学领域。
最近,由于深度学习算法越来越受欢迎,机器学习中的 GPU 加速算法有所增加。深度学习是针对机器学习中的各种问题,训练基于神经网络的模型的算法集合。深度学习算法涉及计算密集型方法,如卷积、傅立叶变换和其他基于矩阵的运算,GPU 非常适合计算。占代码约 5%的计算密集型函数在 GPU 上运行,其余代码在 CPU 上运行。
来源:英伟达
随着 GPU 性能和通用库中对 GPU 支持的最新进展,我建议任何对深度学习感兴趣的人都拥有一个 GPU。
现在我已经彻底激发了 GPU 的使用,让我们看看如何用它们来训练 Python 中的神经网络。
Python 中的深度学习
Python 中实现神经网络最流行的库是 Theano 。然而,严格来说,Theano 不是一个神经网络库,而是一个 Python 库,它使得实现各种各样的数学抽象成为可能。正因为如此,Theano 有很高的学习曲线,所以我将使用构建在 Theano 之上的两个神经网络库,它们的学习曲线更平缓。
第一库是千层面。这个库提供了一个很好的抽象,允许您构建神经网络的每一层,然后将这些层堆叠起来构建完整的模型。虽然这比 Theano 更好,但构建每一层然后将它们附加在另一层之上变得乏味,所以我们将使用 Nolearn 库,它提供了一个 Scikit-Learn 风格的千层面 API 来轻松构建多层神经网络。
因为这些库不是 Domino 硬件的默认库,所以您需要用下面的文本创建一个 requirements.txt :
pip install -r https://raw.githubusercontent.com/dnouri/nolearn/master/requirements.txt git+https://github.com/dnouri/nolearn.git@master#egg=nolearn==0.7.git
设置 Theano
现在,在我们可以导入千层面和 Nolearn 之前,我们需要[配置 Theano,以便它可以利用 GPU 硬件。为此,我们创建了一个。我们的项目目录中的 anorc 文件,内容如下:
[global]
device = gpu
floatX = float32
[nvcc]
fastmath = True
。文件必须放在主目录中。在您的本地机器上,这可以手动完成,但是我们无法访问 Domino 机器的主目录,所以我们将使用以下代码将文件移动到主目录:
import os
import shutil
destfile = "/home/ubuntu/.theanorc"
open(destfile, 'a').close()
shutil.copyfile(".theanorc", destfile)
上面的代码创建了一个空的。主目录下的 theanorc 文件,然后复制的内容。将我们项目目录下的 anorc 文件放到主目录下的文件中。
将硬件层更改为 GPU 后,我们可以使用 Theano 文档中提供的测试代码来测试 Theano 是否检测到 GPU。
from theano import function, config, shared, sandbox
import theano.tensor as T
import numpy
import time
vlen = 10 * 30 * 768 # 10 x #cores x # threads per core
iters = 1000
rng = numpy.random.RandomState(22)
x = shared(numpy.asarray(rng.rand(vlen), config.floatX))
f = function([], T.exp(x))
print(f.maker.fgraph.toposort())
t0 = time.time()
for i in xrange(iters):
r = f()
t1 = time.time()
print('Looping %d times took' % iters, t1 - t0, 'seconds')
print('Result is', r)
if numpy.any([isinstance(x.op, T.Elemwise) for x in f.maker.fgraph.toposort()]):
print('Used the cpu')
else:
print('Used the gpu')
如果 Theano 检测到 gpu,上述功能将需要大约 0.7 秒的时间运行,并将显示“已使用 GPU”。否则,运行和打印“已用 cpu”将需要 2.6 秒。如果它输出这个,那么你忘了把硬件层改成 GPU。
数据集
对于这个项目,我们将使用包含来自 10 个不同类别的 60,000 张 32x32 彩色图像的 CIFAR-10 图像数据集。
幸运的是,数据是以腌制的格式来的,所以我们可以使用 helper 函数加载数据,将每个文件加载到 NumPy 数组中,以产生训练集(Xtr)、训练标签(Ytr)、测试集(Xte)和测试标签(Yte)。[以下代码]的功劳归于斯坦福大学的 cs 231n课程工作人员。
import cPickle as pickle
import numpy as np
import os
def load_CIFAR_file(filename):
'''Load a single file of CIFAR'''
with open(filename, 'rb') as f:
datadict= pickle.load(f)
X = datadict['data']
Y = datadict['labels']
X = X.reshape(10000, 3, 32, 32).transpose(0,2,3,1).astype('float32')
Y = np.array(Y).astype('int32')
return X, Y
def load_CIFAR10(directory):
'''Load all of CIFAR'''
xs = []
ys = []
for k in range(1,6):
f = os.path.join(directory, "data_batch_%d" % k)
X, Y = load_CIFAR_file(f)
xs.append(X)
ys.append(Y)
Xtr = np.concatenate(xs)
Ytr = np.concatenate(ys)
Xte, Yte = load_CIFAR_file(os.path.join(directory, 'test_batch'))
return Xtr, Ytr, Xte, Yte
多层感知器
多层感知器是最简单的神经网络模型之一。该模型由数据的输入层、应用某种数学变换的隐藏层和生成标注(分类的分类标注或回归的连续标注)的输出层组成。
在使用训练数据之前,我们需要对其进行灰度化,并将其展平为二维矩阵。此外,我们将每个值除以 255,然后减去 0.5。当我们对图像进行灰度处理时,我们将每个(R,G,B)元组转换为 0 到 255 之间的浮点值。通过除以 255,我们将灰度值归一化为区间[0,1]。接下来,我们减去 0.5 以将值映射到区间[-0.5,0.5]。现在,每个图像由一个 1024 维的数组表示,其中每个值在-0.5 和 0.5 之间。训练分类网络时,通常会将输入要素标准化为区间[-1,1]。
X_train_flat = np.dot(X_train[...,:3], [0.299, 0.587, 0.114]).reshape(X_train.shape[0],-1).astype(np.float32)
X_train_flat = (X_train_flat/255.0)-0.5
X_test_flat = np.dot(X_test[...,:3], [0.299, 0.587, 0.114]).reshape(X_test.shape[0],-1).astype(np.float32)
X_test_flat = (X_test_flat/255.0)-.5
使用 Nolearn 的 API,我们可以很容易地创建一个具有输入、隐藏和输出层的多层感知器。 hidden_num_units = 100 意味着我们的隐藏层有 100 个神经元,而 output_num_units = 10 意味着我们的输出层有 10 个神经元,每个标签一个。在输出之前,网络应用一个 softmax 函数来确定最可能的标签。如果网络被训练了 50 个历元,并且 verbose = 1 ,则模型打印出每个训练历元的结果以及该历元花费的时间。
net1 = NeuralNet(
layers = [
('input', layers.InputLayer),
('hidden', layers.DenseLayer),
('output', layers.DenseLayer),
],
#layers parameters:
input_shape = (None, 1024),
hidden_num_units = 100,
output_nonlinearity = softmax,
output_num_units = 10,
#optimization parameters:
update = nesterov_momentum,
update_learning_rate = 0.01,
update_momentum = 0.9,
regression = False,
max_epochs = 50,
verbose = 1,)
顺便说一句,这个 API 使得构建深度网络变得很容易。如果我们想添加第二个隐藏层,我们所要做的就是将它添加到 layers 参数中,并指定新层中有多少个单元。
net1 = NeuralNet(
layers = [
('input', layers.InputLayer),
('hidden1', layers.DenseLayer),
('hidden2', layers.DenseLayer), #Added Layer Here
('output', layers.DenseLayer),
],
#layers parameters:
input_shape = (None, 1024),
hidden1_num_units = 100,
hidden2_num_units = 100, #Added Layer Params Here
现在,正如我之前提到的 Nolearn 的 Scikit-Learn 风格 API,我们可以用 fit 方法来拟合神经网络。
net1.fit(X_train_flat, y_train)
当网络在 GPU 硬件上训练时,我们看到每个训练时期通常需要 0.5 秒。
另一方面,当 Domino 的硬件设置为 XX-Large (32 核,60 GB RAM)时,每个训练周期通常需要 1.3 秒。
通过在 GPU 上训练这个网络,我们看到训练网络的速度大约提高了 3 倍。正如预期的那样,GPU 训练的网络和 CPU 训练的网络产生了类似的结果。两者都产生大约相似的 41%的验证准确率和相似的训练损失。
我们可以根据测试数据测试网络:
y_pred1 = net1.predict(X_test_flat)
print("The accuracy of this network is: %0.2f" % (y_pred1 == y_test).mean())
我们在测试数据上取得了 41%的准确率。
卷积网络
卷积神经网络是一种更复杂的神经网络架构,其中一层中的神经元连接到前一层的神经元子集。因此,卷积用于汇集来自每个子集的输出。
来源:http://colah.github.io/posts/2014-07-Conv-Nets-Modular/
卷积神经网络由于其学习不同问题的灵活性和可扩展性,在工业和竞赛中很受欢迎。
同样,在构建卷积神经网络之前,我们必须首先对数据进行灰度转换。这一次,我们将保持图像的 32x32 形状。我修改了矩阵的行的顺序,所以每个图像现在表示为(颜色,x,y)。我再一次将特征除以 255,减去 0.5 来映射区间(-1,1)内的特征。
X_train_2d = np.dot(X_train[...,:3], [0.299, 0.587, 0.114]).reshape(-1,1,32,32).astype(np.float32)
X_train_2d = (X_train_2d/255.0)-0.5
X_test_2d = np.dot(X_test[...,:3], [0.299, 0.587, 0.114]).reshape(-1,1,32,32).astype(np.float32)
X_train_2d = (X_train_2d/255.0)-0.5
现在我们可以构建卷积神经网络。该网络由输入层、3 个卷积层、3 个 2x2 池层、一个 200 个神经元的隐藏层以及最后的输出层组成。
net2 = NeuralNet(
layers = [
('input', layers.InputLayer),
('conv1', layers.Conv2DLayer),
('pool1', layers.MaxPool2DLayer),
('conv2', layers.Conv2DLayer),
('pool2', layers.MaxPool2DLayer),
('conv3', layers.Conv2DLayer),
('pool3', layers.MaxPool2DLayer),
("hidden4", layers.DenseLayer),
("output", layers.DenseLayer),],
#layer parameters:
input_shape = (None, 1, 32, 32),
conv1_num_filters = 16, conv1_filter_size = (3, 3), pool1_pool_size = (2,2),
conv2_num_filters = 32, conv2_filter_size = (2, 2) , pool2_pool_size = (2,2),
conv3_num_filters = 64, conv3_filter_size = (2, 2), pool3_pool_size = (2,2),
hidden4_num_units = 200,
output_nonlinearity = softmax,
output_num_units = 10,
#optimization parameters:
update = nesterov_momentum,
update_learning_rate = 0.015,
update_momentum = 0.9,
regression = False,
max_epochs = 5,
verbose = 1,
)
同样,我们可以使用拟合方法来拟合模型。
net2.fit(X_train_2d, y_train)
与多层感知器相比,卷积神经网络需要更长的训练时间。在启用 GPU 的情况下,大多数训练周期需要 12.8 秒才能完成。然而,卷积神经网络实现了约 63%的验证损失,击败了多层感知器的 40%的验证损失。因此,通过合并卷积层和池层,我们可以将精确度提高 20%。
在 Domino 的 XX-Large 硬件层上只有 CPU 的情况下,每个训练周期需要大约 177 秒,或者说接近 3 分钟才能完成。因此,通过使用 GPU 进行训练,我们看到训练时间加快了约 15 倍。
我们再次看到,与在 GPU 上训练的卷积神经网络相比,在 CPU 上训练的卷积神经网络具有相似的结果,具有相似的验证精度和训练损失。
当我们在测试数据上测试卷积神经网络时,我们达到了 61%的准确率。
y_pred2 = net2.predict(X_test_2d)
print("The accuracy of this network is: %0.2f" % (y_pred2 == y_test).mean())
使用 GPU 来训练深度神经网络导致运行时加速,在这个项目中速度从 3 倍到 15 倍不等。在工业和学术界,我们经常使用多个 GPU,因为这将深度网络的训练运行时间从几周缩短到几天。
额外资源
NVIDIA 推出了一个关于 GPU 和深度学习的免费在线课程,所以那些有兴趣了解更多关于 GPU 加速的深度学习的人可以看看这个课程!
此外, Udacity 为那些对通用 GPU 和 CUDA 编程感兴趣的人提供了一个免费的在线课程 CUDA 编程和并行编程。
如果你对卷积神经网络更感兴趣,神经网络和深度学习电子书最近发布了关于卷积神经网络的一章。
我想特别感谢 Reddit 用户 sdsfs23fs,感谢他们对我在这篇博文最初版本中的错误陈述的批评和纠正。此外,这位 Reddit 用户为我提供了图像预处理步骤的代码,这大大提高了神经网络的准确性。
编辑:我已经更新了这个项目的 requirements.txt 文件,以克服一个由 Python 库引起的错误。新的 requirements.txt 在上面的 Python 中的深度学习一节中列出。
对 AI 认真?你需要一个 GPU 策略
当谈到扩展你的人工智能能力时,你需要更多的图形处理单元(GPU)。它们是训练你的深度学习模型的最快和最具成本效益的方式,这些模型为你的人工智能应用提供动力。GPU 的并行处理能力提升了人工智能用例的性能,从自然语言理解(NLU)——如语音识别、文本分析和虚拟代理——到计算机视觉——如缺陷检测、对象识别和面部分析。事实上,它们对于几乎所有基于非结构化和半结构化数据的人工智能应用都至关重要。
借助 GPU,您可以更快地为新的创新型人工智能应用开发更准确的深度学习模型。它们帮助您的数据科学家交付更好的业务成果,利用最新的人工智能创新,并减少在沮丧中等待模型训练工作完成的时间。然而,为了有效和大规模地利用 GPU,您需要一个 GPU 策略。这篇博客文章解释了为什么,并列出你的 GPU 策略应该解决的五个关键要素。
在企业范围内提供 GPU 基础设施既困难又昂贵
虽然启动云 GPU 实例和交付概念验证深度学习项目是微不足道的,但几乎所有企业都难以提供他们的数据科学团队目前需要的甚至是适度的 GPU 功能,更不用说他们在不久的将来需要的功能了。很少有数据科学家能够访问 GPU 集群,那些能够访问的科学家也陷入了耗时且容易出错的手动工作中。
公司对云供应商收取的高额 GPU 实例费和在云之间传输所需的大量数据的费用望而却步,但他们很少(如果有的话)有人才来构建和维护本地 GPU 集群。更糟糕的是,随着人工智能应用的激增、边缘计算的起飞以及非结构化数据量的指数级增长,成本和管理方面的难题将会增加。
高效企业 GPU 战略的五大支柱
如果这个故事听起来耳熟,那是因为它确实如此。为数据科学家提供 GPU 基础设施的挑战类似于为应用程序开发人员提供 CPU 基础设施的历史挑战,只是难度更大。人工智能工作负载增长更快,甚至比典型的应用程序更不规则,并涉及新的硬件和软件堆栈。
此外,该堆栈正在扩展,企业需要支持越来越多的机器学习库和分布式计算框架,以满足其数据科学家的需求。企业可以解决现有的挑战,并领先于未来的挑战,但就像人工智能本身一样,它不会自动发生。你需要一个 GPU 策略来利用 GPU 的机会。以下是您的策略应该解决的关键要素:
- 领导力。单个数据科学团队往往在没有 IT 支持的情况下创建 GPU 功能,这种情况屡见不鲜,要么是因为他们受实验欲望的驱使,要么是因为他们别无选择,无法完成工作。然而,这是创建孤立 GPU 功能的方法,这些功能只提供给一小部分需要它们的用户,并且在成本和工作方面是浪费的。为了构建可扩展的 GPU 能力,领导者必须拥有创建、交付和持续升级这些能力的人员、预算和责任。他们也必须得到奖励,并对结果负责。
- 混合能力。本地和云 GPU 各有利弊。本地 GPU 更便宜,但不灵活,而云 GPU 可以伸缩,以满足高度可变的人工智能模型训练工作。虽然访问云 GPU 一直很简单,但由于英伟达 DGX 系统等新的融合基础设施解决方案,企业现在也可以更轻松地部署和管理自己的内部 GPU 集群。迟早,每个企业都需要内部和云 GPU,并且需要实施一个集成平台来动态支持两者上的工作负载。
- 自动化和自助服务。 AI 工作负载起伏不定,项目断断续续地开始和进展。此外,用户需要的能力和环境——语言、库和框架——可能因项目而异。这足以让管理集群的人和等待其环境被调配的用户发疯。解决方案在于平台(如 Domino Data Lab ),这些平台可以自动配置和取消配置环境,并使按需访问民主化。
- 治理和可复制性。您的管理员需要治理工具来管理、优化您的 GPU 基础设施的使用,并防止用户无意中关闭集群或产生失控的成本。从长远来看,更重要的是通过捕获所使用的环境、数据、代码和库的所有细节来实现解决方案,以确保您的模型在部署后很长时间内都是可再现的。这些信息不仅对监管机构和客户信任至关重要,对诊断问题和持续改进也至关重要。
- 一个开放的、面向未来的建筑。在人工智能的概率世界中,没有什么是确定的,除了明天的框架、库和硬件将与今天不同。事实上,趋势不是巩固,而是向相反的方向扩散。你应该尽可能尝试并标准化你的 GPU 工具集,但你的 GPU 战略将需要一个计划来支持已经 广泛的 AI 工具 ,并且需要足够开放、模块化和灵活,以便在开发新组件时进行交换。
速度对模型训练和竞争优势至关重要
对于每一个计划通过数据科学和人工智能实现转型的组织来说,这不是一个“如果”你的组织需要快速增长其 GPU 能力的问题,而是一个“何时”的问题。对于在人工智能应用方面走得更远的公司来说,那个“时间”已经来了又走了。这些公司要么实施战略,提供他们的数据科学团队需要的 GPU 硬件和软件,要么发现他们的人工智能雄心受到了限制。
幸运的是,现在有一些产品提供了在混合环境中利用 GPU 所必需的编排、自动化甚至自助服务功能——例如 Domino 数据实验室和 NVIDIA 之间的新 合作。然而,为了有效地使用它们,并确保您为现在和未来的 GPU 需求建立一个面向未来的基础,您需要开始破解您的 GPU 策略。
有关使用 MLOps 和 GPU 平台扩展 AI 的更多信息:
- 下载 利用 MLOps 大规模运营人工智能,了解专门构建的人工智能基础设施和 MLOps 平台的关键考虑因素。
- 阅读关于 Domino 和 NVIDIA 2022 年春季 GTC 公告 ,包括对 NVIDIA 舰队司令部、NVIDIA NGC 和 LaunchPad 策展实验室的新支持。
- 参见 英伟达 2022 年春季 GTC 发布会上的多米诺会议 。
将数据科学家培养成经理
原文:https://www.dominodatalab.com/blog/growing-data-scientists-manager-roles
在这篇文章中,Lyft 的研究科学经理 Ricky Chachra 为那些希望将有前途的个人贡献者(ICs)培养成高效管理者的公司提供了见解。他回顾了自己在 Lyft 的经历,在那里,他开始是一名数据/研究科学家,后来转变为一名科学管理人员。在他的新职位上,里基正在帮助编纂 Lyft 科学经理的职责。这篇文章与 Joshua Nguyen 即将发表的一篇文章相关,因为他们比较了基于他们个人经验的框架。
成为 Lyft 的第八位数据科学家
我于 2015 年 6 月加入 Lyft,成为他们的第八名数据科学家。当年,Lyft 是一家拥有约 350 名员工的公司,坐落在旧金山时尚街区的一栋小楼里。现在已经超过 3500 人,在美国几个主要城市都有工作人员。看到我自己和公司都经历了我们不断成熟的各个阶段,我有一个独特的优势,从这里我得出了以下关于将 IC 培养成经理的思考。
最初驱使我去 Lyft 的东西,也是三年多后的今天让我留在那里的东西。我们有许多共同的性格特征,这些特征可以概括为友好、快速成长、有社会和道德意识、有远见和追求卓越。我很自豪地承认,2015 年 3 月在 Lyft 面试后,我感受到了这样的吸引力,出于考虑,我立即放弃了其他公司。
我在 2015 年年中的个人生活也可以说是 Lyft 当时的表现:我们都是社会阶层中相对年轻的人,对我们的存在理由没有决定性的确定,对我们的近期前景不太确定,并且仍在学习如何在这个混乱的世界中立足。现在,2018 年即将过去,Lyft 和我仍然相互辉映:我们更加自信,不再“年轻”,我们的网络已经扩展,我们在重要问题上有发言权,我们的目标明确,以及实现我们目标的路线图。
回想起来,令人难以置信的是,在我作为个人贡献者的角色开始时,我被安排在高度可见的市场团队中,并被委托独自推动我们的动态定价算法的开发。这些算法响应并调节我们平台上至关重要的供需平衡,许多公司高管和总经理都非常关注它们。在支持我的同事们的鼓励下,我充满了想法,决心要有所作为,我开足马力进入了蜜月期。我不知道的是,在高层和跨职能经理圈子里,动荡正在幕后酝酿。几个月之内,我就陷入了关于度量标准、项目优先级以及工程和产品方面严重的人员配备问题的富有挑战性的辩论中。一些事件的发生让我对自己和他人有了更多的了解,影响了我的职业决策,并迅速改变了我对管理实践的看法。
为了跟上员工人数的爆炸性增长,数据科学和工程领域一些最优秀的 IC 转向了管理层。在特定背景下,这是最理性的做法,任何快速增长的初创公司都会这么做。然而,回过头来看,我们没有意识到技术能力上的优秀并不一定转化为管理上的优秀。如今,Lyft 没有人会否认,管理是一个更类似于艺术的独特领域。理解管理来自于经验、正规教育、指导、对行为榜样的敏锐观察以及自学。
看到经理的行为并不总是积极地影响我的团队的绩效、我们的福祉和职业发展,我向自己承诺,我将绘制自己的道路,以找到在管理方面取得成功所需的条件。管理对我来说并不完全陌生。在加入 Lyft 之前,我是 IBM 首席分析办公室的内部管理顾问。朝着这个方向进一步发展似乎是一个自然的过程。然而,当我专注于更广泛的数据科学领域的管理时,一个更大的问题出现了。
对数据科学经理不断增长的需求
如果你看看数据科学家(DS)人数持续攀升的速度,你会情不自禁地意识到,这种爆炸式的增长肯定已经给经验丰富的高管敲响了警钟。毕竟,在最近的历史中,有没有另一个新的职业发展得如此之快?数据科学的进步给我们带来了多方面的选择。从不断增加的数据捕获、存储和建模手段到算法和复杂的伦理问题,高管们需要做出许多严肃的选择。然而,两个因素,这个行业的相对婴儿期和每个公司情况的独特性,排除了通过所谓的“遵循最佳实践”的方法彻底解决这个领域的问题──我们不能只是模仿其他人的做法。在规范开始扎根之前,可能会经过几轮迭代,如果它们真的扎根的话,会导致公司从头开始就地寻找问题的解决方案。这一切都很好,但随着竞争的继续,谁将领导寻找解决方案呢?
寻找有远见卓识的 DS 经理的公司已经开始着手解决问题。整个行业都缺乏 DS 经理。我们在 Lyft 强烈感受到了这种短缺,由于快速增长,在 2015 年年中至 2017 年末期间,DS IC 人数增加了五倍以上,而经理人数保持稳定,导致 IC 与经理的平均比例达到惊人的 15:1!实际上,经理们,不是由于他们自己的任何过错,被分散得太分散了。每周一对一的会议感觉像长时间的站立;几乎没有任何职业讨论或双向反馈的时间。如果你问一个经理(甚至是 IC),他们认为经理的目的是什么:IC 关系,我不确定你会对答案的范围感到满意。如果你想一想,一段关系在各方对其目的达成更高层次的理解之前,还能是健康的吗?Lyft 在我们现在如何进行管理方面已经走了很长的路。随着对细节的关注比以往任何时候都多,几个忠诚的人正在推动我们的流程快速改进。至少可以说,我们越来越自下而上,并致力于加速集成电路的增长。
随着 Lyft 的领导越来越关注填补 DS 经理职位,我向管理层过渡的决心正在形成。我没有很大的自信,所以我开始时只冒一点点“风险”,比如当我看到问题时更频繁地说出来,当我注意到我的经理变得不知所措时主动提出帮助他。随着时间的推移,我变得越来越自信,这要归功于我从同龄人那里得到的积极强化。他们听取了我的意见,并开始鼓励我考虑管理之路!我对管理的兴趣曾带我去过 IBM,然后一直处于休眠状态,所以当它回来的时候又焕发了活力。在一个非常支持的环境中,我最终在 2018 年 7 月过渡到 Lyft 的管理途径。在这里,我分享了我在转型过程中的一些见解,旨在帮助那些希望将其商业头脑融入管理角色的公司。我也希望对管理感兴趣的 IC 们能够阅读并思考他们在规划自己的道路时需要整合的部分。
从数据科学家 IC 成长为数据科学经理
到 2017 年底,当我确定我想过渡到管理层时,我向我的经理表达了我的意图。他表示支持,并指出了 Lyft 过渡协议中规定的两个重要步骤。
首先,作为一名 IC 获得晋升,这样我就有资格晋升为经理。获得晋升意味着在下一个级别展示我的能力,并在令人信服的晋升申请中总结我的影响。在 2017 年初升职失败后,我没有想当然,Lyft 有严格的标准。我减少了大部分社交活动,并更加努力地开展正在进行的项目,以便在 2018 年初的评估周期之前完成任务。因为晋升的决定是秘密做出的,所以在消息正式公布之前,我一直很焦虑。
第二,作为两名直接下属的代理经理,进入为期 10 周的试用期,进行管理能力评估。根据评估人员最后给我的“强烈推荐”评级,公司最终决定让我进入管理层。我花了相当多的时间来计划我在评估期间的表现。我的过程总结如下。
为数据科学经理职业道路中的评估阶段做准备
我很幸运有一个深思熟虑、训练有素、目标导向的外部导师,我是通过订阅指导平台 Everwise 认识他的。我向他求助,让他明白我应该采取什么步骤来增加我在向管理层过渡的过程中获得成功的机会。按照他的建议,我阅读了他给我介绍的博客,写下了我的个人优势和发展领域,并对我过去的管理经历进行了大量反思。我还采访了 Lyft 的两位科学经理,询问他们对其他经理的期望。在进入评估阶段之前,我通过确定经理候选人应该展示优势的四个领域来提炼我的理解:导师、人际关系、沟通技能和商业技能。虽然我不知道 Lyft 使用的正式的健康评估指标,但评估者关注这四个方面似乎是合理的。
指导技能
在我的生活中,我欠了很多伟大的导师。与此同时,我也经历过成为糟糕的导师的接受方——无论是在学术界还是在工业界。我的个人优秀标准强烈反对在这个至关重要的问题上的任何妥协。早期经理可能会承担初级 ICs 作为直接下属的责任。为了有效地指导初级 IC,DS 经理不仅必须拥有远高于基础水平的有效 IC 技能,还必须有能力指导和培养初级技术人才。我很幸运,在 Lyft 担任 IC 的三年时间里,我指导了两名博士生作为实习生,他们都对他们的项目产生了强烈的影响。我的实习生给了我的经理很多关于我的反馈,这让他充满信心,鼓励我走上管理之路。
出色的人际关系管理
无数的机会让我近距离研究了我自己和我的队友的士气是如何受到影响的,这种影响是由于对经理-经理关系的普遍看法所导致的。通过个人时间的阅读和思考,我总结出以下理解,并在我与 Lyft 分享的一份文件中详细阐述了这些理解:要在管理方面出类拔萃,个人需要不断发展情商,这种情商来自于不断提高的自我意识水平。对于经理来说,工作场所中至少有四种关系受到关注:与直接下属的以授权为中心的关系,与领导和其他 ds 经理的依赖关系,与跨职能经理的合作促进关系,以及最重要的,强烈的自我关系,在这种关系中,任何残余的威权倾向都被不断否定。有目的的工作关系只能通过明确的意图来培养。
与技术和非技术受众有效沟通
数据科学文献中充斥着微妙的术语,包括各种实验和建模方法、算法设计、指标及其含义中的细微差别。数据科学经理经常不得不讨论他们的选择,并与非科学家(产品和工程)合作,以便产生有意义的任务、现实的期望以及路线图和冲刺计划。除了沟通技巧之外,激发理解不同观点的真正兴趣的能力在这一职能中也至关重要。我再次感到幸运的是,作为项目团队中唯一的 DS IC,我经常与业内一些最有耐心和最优秀的产品和工程经理进行定期和富有成效的互动。据我所知,这些同事也支持我竞选管理层。
纵观全局,因为它与业务相关
除了绩效评估、晋升决策和薪酬校准之外,数据科学经理还会参加各种规划会议,在会上制定与他们一致的业务战略或路线图。自然,精通业务的 DS ICs 将更多地参与此类会议,并对他们将帮助制定的路线图产生更大的影响。由于我长期以来对商业的兴趣,在获得工程学博士学位的过程中,我在康奈尔商学院学习了很多课程。这些课程帮助我熟悉了常见的业务框架和高管沟通风格。我精明的经理可能已经注意到了,因为有几次他让我代表他参加重要的计划会议。
为管理层培养感兴趣的 IC
一旦公司确定了技能要求和过渡标准,经理们将确定他们认为有管理潜力的 IC,或者感兴趣的 IC 将自己站出来。培训可能是一个漫长的过程,但它必须达到一个信任的地方,在评估期间有很高的成功机会。由于每个人的成长起点不同,经理、导师和 IC 可能希望共同制定一个个性化的技能发展计划。为了以系统的方式做到这一点,管理者可能必须有目的地创造环境或扰乱现有的流程,以允许梳理。我的经理开始要求我拥有低风险项目,这些项目为我提供了一些我现在作为经理所需的经验。例如,我连续两年负责实习生的招聘和人员配置,并且是一些新员工的加速合伙人。
自从我开始工作以来,Lyft 已经实现了显著的多元化。让崭露头角的经理参与进来的新的可能性正在被正式化。特别是,我们最近投资的两项计划——学习和发展计划以及多元化和包容性计划——为 ICs 在公司事务中变得更加全面提供了机会,无论他们是否打算走上管理道路。
一旦个人的候选资格得到充分确立,并且追求向管理层过渡的共同利益正在形成,经理们可以考虑将这些候选人与现任经理配对进行指导。我的外部导师是帮助我在适当的时候专注于正确的事情的关键资源。此外,我的经理为我联系了一位善良的软件工程总监,他慷慨地给了我宝贵的指导,并分享了对 Lyft 内部管理流程的坦诚见解。人们可以想象,内部导师不仅可以指导学员,还可以为公司领导层把脉,了解他们的学员在个人发展计划中的进展情况。
结束语
由于每个公司和每个集成电路的故事和旅程都是独一无二的,我当然不期望以上的思考能够开箱即用。尽管如此,他们应该鼓励对话和行动,以帮助创建一个健康的数据科学管理环境。不可否认的是,曾经在同一家公司担任 ICs 的数据科学经理可以为他们感到缺乏的领域提供实施改进的动力。他们也可能被证明是从其他公司聘用的经理的重要合作者,这些经理会带来新观点和新想法。
用 Python 构建具有交叉验证的健壮模型
原文:https://www.dominodatalab.com/blog/guide-to-building-models-with-cross-validation
所以,你有了一个机器学习模型!恭喜你!现在怎么办?正如我经常提醒同事的那样,没有完美的模式,只有足够好的模式。考虑到这一点,自然要做的是确保你训练的机器学习模型是稳健的,可以很好地推广到看不见的数据。一方面,我们需要确保我们的模型没有欠拟合或过拟合,另一方面,我们需要优化模型中存在的任何超参数。换句话说,我们对模型验证和选择感兴趣。
在这篇博文中,我们将看到交叉验证技术如何帮助我们使我们的模型像橡树一样健壮结实。
交叉验证-是什么?
我们在上面提到过,交叉验证可以帮助我们改进我们的模型,并在给定可用数据的情况下选择最佳模型。毕竟,我们知道没有完美的模型。交叉验证技术允许我们评估机器学习模型的性能,特别是在数据可能有限的情况下。
在模型验证方面,在之前的帖子中,我们已经看到了模型训练如何受益于我们数据的巧妙使用。通常,我们将数据分为训练集和测试集,以便我们可以使用训练数据来创建模型,然后用测试集来评估它。模型验证是工作流程的一个重要部分,我们之前在这个博客中也讨论过它的一些方面。
关于模型选择,通常情况下,我们使用与上述相同的技术来避免过度拟合。当我们有大量数据时,它工作得最好。或者,我们可以使用正则化技术,如果参数变得太大(即可能存在过拟合),该技术会向模型引入有效的惩罚。当引入正则化时,我们可以选择用于惩罚的值。然而,这些值不一定能从数据中学习到。我们称之为超参数,交叉验证技术可用于优化它们,而不是手动更改值。我们已经在的博客文章中介绍了超参数调整。
我们可以认为交叉验证不仅是一种防止过度拟合 T2 的方法,也是一种比较不同模型的方法,以确定哪种模型最适合解决特定的预测问题。让我们举一个例子:假设我们的任务是将数据拟合为多项式曲线,我们决定使用回归模型。对于给定的数据集,多项式模型的阶数决定了自由参数的数量,从而决定了其复杂性。如果我们使用正则化,超参数(\lambda) 增加了我们模型的复杂性。我们的任务在于确定模型的参数以及(\λ)。
让我们生成一些人工数据,让这个例子变得生动起来。假设有一个我们未知的信号(f(x)) ,给定输出数据我们尝试确定一个模型使得(y(x)= f(x)+【ε),其中(\ε)呈正态分布。
考虑由(f(x)= 0.1x^3 -0.5x^2-0.3x+3.14 )给出的真实信号。在这种情况下,我们感兴趣的是仅从数据观测中恢复这个多项式。我们可以使用 Python 来创建我们的人工数据。首先让我们创建一个函数来获取我们的真实信号:
import numpy as np
from matplotlib import pyplot as plt
import pandas as pd
np.random.seed(14)
def f(x):
return 0.1*x**3 - 0.5*x**2 - 0.3*x + 3.14
我们的样本可以通过抽样一个随机的均匀分布并加上一些具有标准差的高斯噪声得到(\sigma) 。让我们考虑一个范围([0,5]) ,(\sigma=0.25) 并创建(N=100) 个样本:
N = 100
sigma = 0.25
a, b = 0, 5
# N samples from a uniform distribution
X = np.random.uniform(a, b, N)
# N sampled from a Gaussian dist N(0, sigma)
eps = np.random.normal(0, sigma, N)
# Signal
x = np.linspace(a, b, 200)
signal = pd.DataFrame({'x': x, 'signal': f(x)})
# Creating our artificial data
y = f(X) + eps
obs = pd.DataFrame({'x': X, 'y': y})
一张图片抵得上一千个 NumPy 数组,所以让我们来看看我们生成的数据:
x = np.linspace(a, b, 200)
fig, ax = plt.subplots(figsize=(10,8))
ax.plot(signal['x'], signal['signal'], '--', label='True signal', linewidth=3)
ax.plot(obs['x'], obs['y'], 'o', label='Observations')
ax.legend()
plt.xlabel(r'$x$')
plt.ylabel(r'$y$')
如果我们有上图中点所示的数值,我们能确定虚线吗?我们可以利用所有的观察结果,提出一个模型。然而,我们如何评估模型是否足够好呢?如果我们有足够的数据,我们可以将数据分成两组,一组用于训练模型,另一组用于评估。即使在这种情况下,模型在训练数据上的表现也不足以建立一个稳健的模型,因为我们可能已经记住了数据,并欺骗自己认为我们有一个完美的模型。
我们可以做得更好:我们可以将集合分成几个训练和验证集合(不仅仅是一个!),然后我们使用不同的训练集来训练模型。正如在的第 3 章使用 Python 进行数据科学和分析中所讨论的,这是可行的,因为我们用不同的数据片段来呈现模型,因此它“看到”不同的数据观察。用每个不同的分裂获得的一般化误差预计是不同的。然后,我们可以取例如所有训练模型的结果的平均值,从而获得更好的预测器。现在让我们讨论一些使用 Python 的有用的交叉验证技术。
验证集
让我们从考虑使用单个验证集来估计通过拟合不同模型获得的错误率开始。
在这种情况下,我们简单地将数据分成两部分:训练集和测试集。训练集专门用于训练模型,为我们提供了评估训练误差的机会。反过来,测试集用于评估模型,我们可以从中获得泛化误差。最后,我们可以对新数据使用该模型,并观察样本外误差。我们在下图中描述了这种情况:
让我们将上述步骤应用于我们的 obs 数据。在这种情况下,我们简单地将数据分成两组,一组用于训练,一组用于测试。让我们采取拆分:
from sklearn import model_selection
x_train, x_test, \
y_train, y_test = model_selection.train_test_split(obs['x'], obs['y'],
test_size=0.2, random_state=14)
x_train= x_train.values.reshape(-1, 1)
x_test= x_test.values.reshape(-1, 1)
在上面的代码中,我们使用 Scikit-learn 的 train_test_split 函数来创建我们的两个数据集。我们只需提供要分割的数组和测试数据集的大小。在这种情况下,我们持有 20%的数据进行测试。
我们继续使用 Scikit-learn 对训练集中的数据进行线性回归:
from sklearn import linear_model
lm = linear_model.LinearRegression()
vs_lm = lm.fit(x_train, y_train)
我们可以查看我们的预测,并估计均方误差:
vs_pred = vs_lm.predict(x_test)
from sklearn.metrics import mean_squared_error
vs_mse = mean_squared_error(y_test, vs_pred)
print("Linear model MSE: ", vs_mse)
Linear model MSE: 0.41834407342049484
我们知道,考虑到我们之前所做的可视化,线性模型可能不是最好的。让我们比较一下二次多项式和三次多项式。在这种情况下,我们将使用多项式特性函数:
from sklearn.preprocessing import PolynomialFeatures
# Quadratic
qm = linear_model.LinearRegression()
poly2 = PolynomialFeatures(degree=2)
x_train2 = poly2.fit_transform(x_train)
x_test2 = poly2.fit_transform(x_test)
vs_qm = qm.fit(x_train2, y_train)
vs_qm_pred = vs_qm.predict(x_test2)
print("Quadratic polynomial MSE: ", mean_squared_error(y_test, vs_qm_pred))
# cubic
cm = linear_model.LinearRegression()
poly3 = PolynomialFeatures(degree=3)
x_train3 = poly3.fit_transform(x_train)
x_test3 = poly3.fit_transform(x_test)
vs_cm = cm.fit(x_train3, y_train)
vs_cm_pred = vs_cm.predict(x_test3)
print("Cubic polynomial MSE: ",mean_squared_error(y_test, vs_cm_pred))
Quadratic polynomial MSE: 0.08791650686920466
Cubic polynomial MSE: 0.051152012599421336
我们可以看到,将单个样本分成训练集和验证集可以帮助我们确定三种模型的错误率,即线性、二次和三次模型。我们可以看到,立方的均方误差较小,我们可以看到获得的系数:
print('Cubic Coefficients:', cm.coef_)
Cubic Coefficients: [ 0\. -0.30748612 -0.50263565 0.10141443]
我们可以看到,我们很好地恢复了真实信号的参数!
prediction = pd.DataFrame({'x': x_test[:,0], 'y': vs_cm_pred}).sort_values(by='x')
fig, ax = plt.subplots(figsize=(10,8))
ax.plot(signal['x'], signal['signal'], '--', label='True signal', linewidth=3)
ax.plot(obs['x'], obs['y'], 'o', label='Observations')
ax.plot(prediction['x'], prediction['y'], '-', label='Cubic Model', lw=2)
ax.legend()
plt.xlabel(r'$x$')
plt.ylabel(r'$y$')
k 倍交叉验证
在上一节中,我们看到了拆分数据如何帮助我们评估模型。然而,这种划分可能有点生硬,我们最终可能会忽略一些重要的信息,从而增加模型中的偏差或过度拟合。为了避免这一点我们可以采用(k )-折叠交叉验证。
在这种情况下,我们不是将数据分成两部分,而是将其分成(k) 子集。我们使用(k-1) 子集来训练模型,并保留一个用于之前使用的相同过程中的验证。不同的是,现在我们重复过程(k) 次,逐个使用每个(k) 子集进行验证。我们最终得到(k) 经过训练的模型,其结果被汇总。在下图中,我们描述了 4 个-折叠交叉验证的情况:
让我们把这个想法用在我们的 obs 数据上。在这个例子中,我们将使用(k=15)和 Scikit-learn,用 KFold 函数:可以很容易地创建我们的(k)折叠
from sklearn.model_selection import KFold
kcv = KFold(n_splits=15, random_state=14, shuffle=True)
在这种情况下,我们将使用 14 个子集来训练一个模型,并针对一个模型进行测试。在上面的代码中,我们传递了一个随机状态以保证再现性,并且我们确保了在应用分割之前数据是混洗的。我们现在对使用多项式特征的模型感兴趣,范围从线性模型到 8 次多项式。在每种情况下,我们使用我们的(k)折叠来训练我们的模型并评估分数。这里我们将使用 Scikit-learn 中的 cross_val_score 函数,它让我们通过交叉验证来评估分数。我们使用一个等于负均方误差的评分参数。这相当于均方误差,但较低的返回值比较高的更好。
from sklearn.model_selection import cross_val_score
for d in range(1, 9):
poly = PolynomialFeatures(degree=d)
X_now = poly.fit_transform(obs['x'].values.reshape(-1, 1))
model = lm.fit(X_now, obs['y'])
scores = cross_val_score(model, X_now, obs['y'], scoring='neg_mean_squared_error', cv=kcv, n_jobs=1)
print(f'Degree-{d} polynomial MSE: {np.mean(np.abs(scores)):.5f}, STD: {np.std(scores):.5f}')
Degree-1 polynomial MSE: 0.43271, STD: 0.26384
Degree-2 polynomial MSE: 0.13131, STD: 0.06729
Degree-3 polynomial MSE: 0.06907, STD: 0.04105
Degree-4 polynomial MSE: 0.07014, STD: 0.04125
Degree-5 polynomial MSE: 0.07012, STD: 0.04215
Degree-6 polynomial MSE: 0.07141, STD: 0.04332
Degree-7 polynomial MSE: 0.07146, STD: 0.04248
Degree-8 polynomial MSE: 0.07224, STD: 0.04419
太好了!我们使用 对我们的数据进行不同的分割,评估了 模型。从以上结果来看,3 次多项式似乎是最好的。
留一交叉验证
在留一法交叉验证方法(或简称为 LOOCV)中,我们简单地将一个数据观察值从训练中剔除——因此得名。这是(k) 的一个特例——其中(k) 等于观察次数。在这种情况下,我们最终在训练中使用所有可用的数据,降低了模型的偏差。执行时间更长,因为我们必须重复这个过程(k) 次。让我们来看看:
from sklearn.model_selection import LeaveOneOut
loocv = LeaveOneOut()
for d in range(1, 9):
poly = PolynomialFeatures(degree=d)
X_now = poly.fit_transform(obs['x'].values.reshape(-1, 1))
model = lm.fit(X_now, obs['y'])
scores = cross_val_score(model, X_now, obs['y'], scoring='neg_mean_squared_error', cv=loocv, n_jobs=1)
print(f'Degree-{d} polynomial MSE: {np.mean(np.abs(scores)):.5f}, STD: {np.std(scores):.5f}')
Degree-1 polynomial MSE: 0.42859, STD: 0.63528
Degree-2 polynomial MSE: 0.13191, STD: 0.15675
Degree-3 polynomial MSE: 0.07011, STD: 0.10510
Degree-4 polynomial MSE: 0.07127, STD: 0.10677
Degree-5 polynomial MSE: 0.07165, STD: 0.10693
Degree-6 polynomial MSE: 0.07302, STD: 0.10871
Degree-7 polynomial MSE: 0.07326, STD: 0.11076
Degree-8 polynomial MSE: 0.07397, STD: 0.11213
离开 P-Out (LPOCV)
我们可以考虑这样一种情况,而不是将一个单独的数据观察排除在训练之外,我们根据一组(p)观察来评估我们的模型。这意味着对于具有(n)个观察值的数据集,我们将使用(n-p)个数据点进行训练。在 Python 中,我们可以使用 Scikit-learn 中的 LeavePOut 函数来创建拆分。请注意,省略(p)观察并不等同于使用(k )-fold withk = int(n/p),因为后者不会创建重叠集。
请注意,使用 LPOCV 创建的样本数量以组合方式增长,因此成本可能非常高。让我们来看看我们将为 obs 数据集生成的样本数量,其中有 100 个观测值:
from sklearn.model_selection import LeavePOut
for p in range(1,11):
lpocv = LeavePOut(p)
print(f'For p={p} we create {lpocv.get_n_splits(X)} samples ')
For p=1 we create 100 samples
For p=2 we create 4950 samples
For p=3 we create 161700 samples
For p=4 we create 3921225 samples
For p=5 we create 75287520 samples
For p=6 we create 1192052400 samples
For p=7 we create 16007560800 samples
For p=8 we create 186087894300 samples
For p=9 we create 1902231808400 samples
For p=10 we create 17310309456440 samples
我们可以看到,对于(p=1) 我们追回了 LOOCV 案。当我们不考虑 2 个 时,我们需要 4950 个 样本,而对于(p=3) 我们需要超过 161000 个 样本。
对于大型数据集,最好使用混合分裂或分层-褶皱。让我们来看看。
洗牌拆分
我们可以采用一种策略,像在 中一样生成给定数量的分裂,而不是将 的观察结果排除在外,让我们面临一项非常耗时的任务。折叠交叉验证,但样本首先被打乱,然后分成一对训练集和测试集。我们可以用一个随机数种子来控制随机性。
from sklearn.model_selection import ShuffleSplit
ss = ShuffleSplit(n_splits=40, test_size=0.2, random_state=14)
for d in range(1, 9):
poly = PolynomialFeatures(degree=d)
X_now = poly.fit_transform(obs['x'].values.reshape(-1, 1))
model = lm.fit(X_now, obs['y'])
scores = cross_val_score(model, X_now, obs['y'], scoring='neg_mean_squared_error', cv=ss, n_jobs=1)
print(f'Degree-{d} polynomial MSE: {np.mean(np.abs(scores)):.5f}, STD: {np.std(scores):.5f}')
Degree-1 polynomial MSE: 0.42941, STD: 0.13004
Degree-2 polynomial MSE: 0.13789, STD: 0.03389
Degree-3 polynomial MSE: 0.07390, STD: 0.02189
Degree-4 polynomial MSE: 0.07531, STD: 0.02177
Degree-5 polynomial MSE: 0.07636, STD: 0.02215
Degree-6 polynomial MSE: 0.07914, STD: 0.02174
Degree-7 polynomial MSE: 0.07806, STD: 0.02154
Degree-8 polynomial MSE: 0.07899, STD: 0.02257
超参数调谐
我们提到,在我们的模型中,可以对调整超参数使用交叉验证。让我们考虑使用岭回归,其中我们使用 L2 范数来惩罚我们的模型。我们可以为λ选择一个值,并用不同的值逐个训练多个模型。
相反,我们可以让机器为我们工作,并请求对指定的参数值进行彻底的搜索。让我们考虑λ∈[0.1,100],我们有兴趣为我们的模型找到最佳值。
让我们从创建我们要搜索的数值网格开始:
lambda_range = np.linspace(0.1, 100, 100)
lambda_grid = [{'alpha': lambda_range}]
我们现在可以使用 GridSearchCV 创建我们的管道,它需要一个模型估计器,一个值网格来搜索,我们能够提供交叉验证分割。
让我们使用我们在本帖中创建的初始分割来获得一个数据集,以检验我们的模型,换句话说,我们将使用 x_train 和 y_train 来训练模型:
from sklearn.model_selection import GridSearchCV
from sklearn.linear_model import Ridge
poly = PolynomialFeatures(degree=3)
X_now = poly.fit_transform(x_train)
kcv = KFold(n_splits=15, random_state=14, shuffle=True)
model_ridge = Ridge(max_iter=10000)
cv_ridge = GridSearchCV(estimator=model_ridge, param_grid=lambda_grid,
cv=kcv)
cv_ridge.fit(x_train, y_train)
GridSearchCV(cv=KFold(n_splits=15, random_state=14, shuffle=True),
estimator=Ridge(max_iter=10000),
param_grid=[{'alpha': array([ 0.1 , 1.10909091, 2.11818182, 3.12727273,
4.13636364, 5.14545455, 6.15454545, 7.16363636,
8.17272727, 9.18181818, 10.19090909, 11.2 ,
12.20909091, 13.21818182, 14.22727273, 15.23636364,
16.24545455, 17.25454545, 18.26363636, 19.27272727,
20.2818181...
68.71818182, 69.72727273, 70.73636364, 71.74545455,
72.75454545, 73.76363636, 74.77272727, 75.78181818,
76.79090909, 77.8 , 78.80909091, 79.81818182,
80.82727273, 81.83636364, 82.84545455, 83.85454545,
84.86363636, 85.87272727, 86.88181818, 87.89090909,
88.9 , 89.90909091, 90.91818182, 91.92727273,
92.93636364, 93.94545455, 94.95454545, 95.96363636,
96.97272727, 97.98181818, 98.99090909, 100\. ])}])
让我们看看所选的超参数:
cv_ridge.best_params_['alpha']
20.28181818181818
我们现在可以使用这个参数来创建我们的模型,并查看系数:
best_ridge = Ridge(alpha=cv_ridge.best_params_['alpha'], max_iter=10000)
best_ridge.fit(X_now, y_train)
print('Cubic Coefficients:', best_ridge.coef_)
Cubic Coefficients: [ 0\. -0.22246329 -0.47024996 0.0916242 ]
我们可以用给出的数据值来可视化我们的模型结果,即 x_test :
ridge_pred = best_ridge.predict(poly.fit_transform(x_test))
prediction = pd.DataFrame({'x': x_test[:,0], 'y': ridge_pred}).sort_values(by='x')
fig, ax = plt.subplots(figsize=(10,8))
ax.plot(signal['x'], signal['signal'], '--', label='True signal', linewidth=3)
ax.plot(obs['x'], obs['y'], 'o', label='Observations')
ax.plot(prediction['x'], prediction['y'], '-', label='Regularised Ridge Model', lw=2)
ax.legend()
plt.xlabel(r'$x$')
plt.ylabel(r'$y$')
其他交叉验证实现
Scikit-learn 有许多其他交叉验证策略,可用于数据具有特定特征的情况。例如,当我们有一个分类问题并且类别标签不平衡时,建议使用分层方法来确保相对类别频率在每个折叠中大致保持不变。在这些情况下,我们可能会考虑使用 StratifiedKFold 或 StratifiedShuffleSplit 。前者是(k)-fold 的变体,返回分层折叠,换句话说,每个集合包含与完整数据集大致相同百分比的每个目标类的样本。后者是返回分层拆分的混合拆分的变体。
如果我们需要使用的数据是分组的,例如在一项医学研究中,从每个患者身上重复收集数据,交叉验证需要确保在给定组上训练的模型推广到看不见的组。我们可以使用 GroupKFold 来确保同一个组不会同时出现在测试集和训练集中。 StratifiedGroupKFold 实际上是stratified fold与group fold的组合,以便在将每个组放在单个分割中的同时保持每个分割中的等级分布。可以想象,也有 LeaveOneGroupOut 和 LeavePGroupsOut 以及 GroupShuffleSplit 。
另一个有趣的例子是时间序列的交叉验证。与上面使用的示例不同,在时间序列中,我们不能简单地使用随机样本来分配给训练集和测试集。这是因为我们可能不想用未来的值来“预测”过去的值。一个简单的解决方案是使用验证集,用过去的值训练模型,用未来的值进行测试。但是我们能做得比这更好吗?
答案是肯定的,选择的方法是在滚动的基础上应用交叉验证,我们从数据集的一部分开始,然后立即预测一小部分观察值,并评估模型。然后,我们在下一次培训中包括一小部分预测观察,等等。这在时代周刊的 Scikit-learn 中得到了很好的实现。它是(k)-fold 的变体,其中我们使用第一个(k )fold 进行训练,然后(k+1 是我们的测试集:
from sklearn.model_selection import TimeSeriesSplit
X = np.array([[10, 20], [30, 40], [10, 20], [30, 40], [10, 20], [30, 40]])
y = np.array([100, 200, 300, 400, 500, 600])
tscv = TimeSeriesSplit(n_splits=4)
for train_index, test_index in tscv.split(X):
print("TRAIN:", train_index, "TEST:", test_index)
#To get the indices
X_train, X_test = X[train_index], X[test_index]
y_train, y_test = y[train_index], y[test_index]
print(X_train, y_train)
TRAIN: [0 1] TEST: [2]
[[10 20]
[30 40]] [100 200]
TRAIN: [0 1 2] TEST: [3]
[[10 20]
[30 40]
[10 20]] [100 200 300]
TRAIN: [0 1 2 3] TEST: [4]
[[10 20]
[30 40]
[10 20]
[30 40]] [100 200 300 400]
TRAIN: [0 1 2 3 4] TEST: [5]
[[10 20]
[30 40]
[10 20]
[30 40]
[10 20]] [100 200 300 400 500]
摘要
这就对了,将我们的数据分成训练和测试子集的想法似乎比最初看起来要有用得多。将这种想法扩展到交叉验证,不仅有助于我们更有效地利用数据,还为我们提供了一些不可否认的好处。它帮助我们:
- 评估我们模型的质量
- 避免过紧或过紧
- 选择更好的型号
然而这也不是没有代价的。交叉验证的使用使得我们的过程需要更长的时间,我们希望这些额外的时间和努力是值得的,因为模型更加健壮。
迁移学习及其工作原理的详细指南
原文:https://www.dominodatalab.com/blog/guide-to-transfer-learning-for-deep-learning
对于数据科学团队来说,如果数据不足或数据过多,并且没有足够的时间或资源来处理这些数据,迁移学习可能是机器学习模型开发中的一条重要捷径。最常与深度学习和神经网络相关联,它也正被用来取代传统的机器学习 模型训练技术 作为加速开发的方法。
什么是迁移学习?
迁移学习是一种机器学习技术,它重用为一项任务开发的完整模型,作为新模型完成新任务的起点。第一模型使用的知识因此被转移到第二模型。“迁移学习”一词来自人类心理学,例如,一个知道如何弹钢琴的人比一个毫无经验的人更容易学会拉小提琴。
迁移学习的子集
迁移学习的运用取决于三个因素:需要迁移什么,如何迁移,何时迁移。因为迁移学习设置中的源数据集和目标数据可以在它们的领域或它们的任务中变化,所以有三个不同的迁移学习 子集 。
- 归纳学习:任务是不同的,不管源域和目标域之间有什么相似之处。
- 直推式学习:任务相同,但特征空间或领域间的边际概率分布不同。
- 无监督学习:没有可用于训练的标记数据时。
为什么要用迁移学习?
当训练一个新模型时,迁移学习可以加快进度和提高性能,所以当时间是一个因素或者训练一个模型需要大量资源时,主要使用它。出于这些原因,你会经常看到迁移学习用于深度学习项目,包括用于解决自然语言处理(NLP)或计算机视觉(CV)任务的神经网络。当概念漂移可能成为一个问题时,或者当第二个模型需要多任务学习时,也可以使用迁移学习。
另一个使用迁移学习的时间是当可用的 训练数据不足 时。在这些情况下,来自预训练模型的权重可以用于初始化新模型的权重。
只有当第一个模型在其第一个任务中学习的特征被概括并可以转移到第二个任务时,迁移学习才是成功的。出于同样的原因,第二次训练中使用的数据集需要与第一次训练中使用的数据集相似。
机器学习中的迁移学习与深度学习
迁移学习是深度学习模型中的一个增长趋势,也是传统机器学习过去使用时的一种替代方法。传统的 机器学习模型 通常被设计用来执行特定的任务,并使用为模型需求定制的数据集进行训练。一旦他们被训练和测试,他们就被放入模拟训练环境的环境中,以实现他们被训练的目的。这可以描述为一种 孤立的机器学习方法 。
机器学习中迁移学习的不同之处在于不鼓励孤立。目标是利用来自预训练模型的知识来训练后续模型。其结果是一个学习的菊花链,通常导致更快和更有效的模型开发。用一个人类的比喻来说,考虑一下高中的数学和科学老师正在培养未来的科学家、医生、牙医和数据科学家。
在深度迁移学习的情况下,用于像自然语言处理 (NLP)和计算机视觉等领域的复杂模型,模型所需的任务可能是单一的,然而,训练数据集可能是不够的。可能是数据太少,也可能是数据标注不充分。当获取或配置高质量数据集的前景需要太多时间时,深度迁移学习可能会更快、更有效。
迁移学习方法
迁移学习的使用可以通过几种不同的方法来实现:
在相似的领域上训练模型
这种方法包括在相似的域上训练一个模型。比如,假设你需要解决问题 A,但是你没有足够的数据。问题 B 类似于问题 B,你有足够的数据来解决这个问题。因此,您可以针对问题 B 训练一个模型,然后使用这个成功的模型引导一个新的模型来处理问题 a
特征抽出
迁移学习方法涉及特征提取。在这种情况下,数据科学团队将训练一个深度神经网络,用作自动特征提取器。一旦应用于预训练模型,其表示就可以导出到新模型中。
开发预先训练的模型
最后,这种方法包括开发考虑迁移学习的预训练模型。在开发模型方面有丰富背景的组织可能经常有一个模型库可以使用。当需要一个新的动作或需要解决一个问题时,可以采用一个预先训练好的模型,对其进行调整以解决手边的问题,然后用于训练一个新的模型。
迁移学习过程
无论采用哪种方法,下面概述的流程都是迁移学习如何开发和实施的高级概述:
- 获得预先训练的模型:这些模型可以从您组织自己的模型库中获得,也可以从其他存储库中获得,例如位于 PyTorch Hub 或 TensorFlow Hub 的模型。
- 冻结层:这是为了防止模型中的权重被重新初始化。如果它们被重新初始化,模型将会丢失所有的学习。
- 训练新层:新层需要添加到模型中,将其特征转化为新数据集上的 新预测 。
- 通过微调改善模型:并非总是需要,微调基础模型可以改善模型性能。这包括解冻部分基础模型,然后在新的数据集上以较低的学习速率再次训练它。
行动中的迁移学习
今天有许多迁移学习的应用,更多的应用即将出现。使用迁移学习的一个常见场景是使用图像数据作为数据输入的预测建模。基于图像的数据集问题的预训练模型的例子包括 牛津 VGG 模型谷歌盗梦空间模型 和 微软 ResNet 模型 。
迁移学习的另一个流行领域是当模型需要处理语言数据时,包括使用文本的自然语言处理。基于语言的数据问题的预训练模型的例子有 谷歌的 word2vec 模型 ,以及 斯坦福的 GloVe 模型 。
开发和实施迁移学习
虽然迁移学习可以减少处理要求和开发时间,但如果算法、预先训练的模型和数据集不容易访问和很好地记录,以及模型驱动的组织所需的治理要求,这就没有什么意义了。
如果您准备好开始迁移学习,请参见我们的使用 Keras 和 HuggingFace 进行迁移学习的实践教程。
黑客马拉松是为每个人准备的
原文:https://www.dominodatalab.com/blog/hackathons-are-for-everyone
这些是 Domino 数据实验室为期三天的跨公司黑客马拉松中的 21 个项目中的一部分。
我现在已经在 Domino 工作了四个月——完全远程——担任我们的人力副总裁。在这段时间里,我一直面临着挑战——就像现在大多数组织一样——以一种我们以前从未有过的方式让我们的全球员工参与进来:在他们的家中,完全远离我们,并且受到我们从未预料到的干扰。作为一名对员工合作充满热情的人事主管,当我与全明星阵容一起将全公司的黑客马拉松和团队周活动带入生活时,我被激起了兴趣。有人可能会问:为什么要进行全公司范围的黑客攻击?我以为黑客马拉松只是为工程团队准备的?不是这样的!
我们的总裁兼首席运营官娜塔莉·麦卡洛(Natalie McCullough)说:“我们希望做一些事情,激励公司的每个人,激发创造力,解决真正的业务问题,同时让员工从日常的会议和项目中解脱出来。”。“我认为将黑客马拉松的概念扩展为一个更具包容性的项目会很有趣,可以让我们的 175 多名员工和 21 个团队参与进来——而不仅仅是工程。”
员工被要求“破解”一系列同行提名的项目,与我们的战略重点和人力战略保持一致。Domino 成功举办黑客马拉松周的一些关键因素包括:
- 项目是由我们的执行团队从 70 多个提名中挑选出来的,这些提名是基于它们与我们六个公司战略之一的一致性。
- 我们委托一个基于员工的委员会来影响黑客马拉松的形式。
- 项目涵盖广泛的技能,包括所有员工。
- 每个黑客马拉松团队都是跨职能和跨地区的。
- 我们清楚地阐明了本周的目标是转移员工的注意力,而不是分散注意力。
- 我们将此作为一种练习,深入挖掘我们的文化,创造一种传统,同时提高员工的士气和协作。
评判、奖品和投球方式都棒极了。除了第一名、第二名和第三名之外,我们还有几个类别,以培养健康的竞争意识。我们颁发了“最佳唱功”之类的奖项(是的,有歌唱!)、“最佳老师”、“最佳无演示演讲”和“最具创意演示”。我们所有的黑客马拉松参与者也获得了创意礼品!
黑客马拉松最精彩的部分之一是看到项目最终成为我们内部工具集的一部分,并在路线图上占有一席之地。许多项目不仅关注面向客户的工具,还优化了员工体验。这真是一种独特的平衡。
不仅在协作和团队建设方面取得了积极的成果,而且实际产出极具创新性、智能性和生产力。我们的首席执行官 Nick Elprin 评论道:
“我完全被这么多项目中的创造力和创新所震撼。这有力地证明了跨职能部门协作的力量,也提醒我们,在我们今天所处的远程工作环境中,找到保持这种协作的方法是多么重要。”
说够了!
全公司范围的黑客马拉松是在轻松有趣的氛围中提升公司凝聚力的好方法。他们给人们发挥创造力的空间,让他们能够与日常生活中通常不会接触的团队成员一起工作。无论是在真正的黑客马拉松中,还是在我们的拼字比赛、逃生室比赛或团队周期间的调酒活动中,我们都给人们提供了实验、修补和相互了解的空间,从而允许他们为自己和整个公司创造一些有价值的东西。
回顾这一周,工程经理 Jon Radchenko 指出:
“我有机会与其他团队的一些开发人员一起工作,并见证了我们在 Domino 的这个团队是多么热情、积极和聪明。此外,我对我们员工的不同技能留下了难以置信的印象,除了他们日常工作中的技能。我们有歌手、艺术家、电影制作人,还有很多我不知道的令人印象深刻的人才。这是非常艰难的一周,但非常充实,我等不及下一周了。”
下一个?是的,在我们的未来,达美乐肯定会有“下一个”。参加这样的黑客马拉松,成功的秘诀是什么?也许没有任何一颗子弹能让你赢得大奖,但这里有一些小技巧可以增加你成功的几率:
- 影响:创造或找到一个你认为对你或他人有益的解决方案。
- 实验:尝试,失败了再来!(或者就像我们在 Domino 上说的:“迭代至卓越!”)
- 认识到:向他人展示你的能力,并发现他人的能力。
- 向他人的想法和现实敞开心扉。
- 信任:与你的同事合作,让它发生。
- 雄心勃勃:突破界限…这是突破概念的时候了!
- 扰乱:不要太害羞,不敢走出自己的舒适区。
- 联系:随时分享你的技能,参与他人的项目。
- 创造性思考:看待事物有多种方式。
你对如何成功举办跨职能的黑客马拉松有疑问吗?不要犹豫联系我——我很想听听你的想法!最后,如果你有兴趣在达美乐了解更多职业信息,请点击这里查看我们所有的机会。
健康与生命科学:数据科学创新中心
原文:https://www.dominodatalab.com/blog/health-life-sciences-a-data-science-innovation-hub
创新是改善的神奇词汇:一个新的想法,一个不同的过程,一个方法的改变,这意味着商业价值的不同。如果您是数据科学领域的领导者或从业者,或者在医疗保健和制药行业工作或寻找相关信息,Domino 创建了一个由该领域的五位同行创新者提出的新想法的电子书。专为您量身定制!
数据科学创新者行动手册的新健康和生命科学版是 ,现在可以免费下载 。医疗保健、生命科学和医学领域的每位顶级数据科学创新领导者都分享了他们对工作、职业和数据科学专业的见解。
你将在电子书中学到的例子
作为一个引子,这里有两个来自这个电子书项目顾问的具体见解。第一个是桑杰·贾斯瓦尔(Sanjay Jaiswal),埃森哲(Accenture)北美区董事总经理兼 R&D 分析主管。第二个是雪花公司的医疗保健领域首席技术官 Murali Gandhirajan。
降低成本:迎接制药行业最大的创新挑战
克服开发新产品和治疗方法的巨大、不断上升的成本障碍——并使它们获得批准使用——继续困扰着该行业。通常情况下,这一成本从 26 亿美元到 67 亿美元不等,其中包括资本成本和故障成本,具体取决于具体的使用案例。Jaiswal 说:“这个巨大的成本必须以指数形式下降,从几十亿下降到几百万。”
Jaiswal 说:“数据科学在这一转变中发挥着关键作用,而生产率取决于 R&D 在每项获批的新治疗上的支出比例。Jaiswal 说,提高生产率的一种组织模式是“敏捷实验室”。在四至六周的冲刺阶段工作的职能团队,加上诸如 Domino Enterprise MLOps 平台等技术的加速能力,是改进的独特使能因素。
他说:“快速访问数据和能够非常快速地启动具备必要先决条件和优先级参数的环境,可以加快实现价值的速度。”。“如果你想大规模地进行机器学习,你需要大规模地持续监控你的模型。”这就是企业 MLOps 的作用。
获得足够的数据来正确训练模型
这个老问题可以通过更快地访问数据来迅速解决,这些数据存在于一个组织内,但可能分散在世界各地——通常隐藏在需要的合作者看不到的筒仓中。Gandhirajan 说:“对于研究人员来说,以可控的方式获得所有相关数据并能够有意义地使用这些数据至关重要。他指出,这些障碍包括限制外部和/或国际共享的法规。他建议使用一种叫做“联合学习”的方法来应对这一挑战。“想知道更多吗?该电子书在 NVIDIA 的 Mona Flores 上的 简介解释了这一切!
这些顾问还指出了对所有模型进行可解释性审查的重要性。这使得监管者和利益相关者更容易理解模型的好处。这些福利是在企业 MLOps 的帮助下提供的。
结识更多创新领袖
这本电子书包括来自数据科学领域顶尖创新者、顾问和行业专家的见解。所有人都描述了他们的数据科学部门在团队规模和回答业务关键问题的中心地位方面的巨大增长。被描述的领导者包括:
-
卢卡·福斯基尼博士—EVI dation联合创始人兼咨询首席数据科学家
-
Najat Khan, 博士——首席数据科学官兼全球战略负责人&让桑制药公司 强生&强生研发运营部&
-
安迪·尼科尔斯, 理学硕士——高级总监,统计数据科学负责人, GSK
-
莫娜·g·弗洛雷斯,医学博士——全球医疗 AI 负责人 英伟达
-
John k . Thompson——分析思想领袖、畅销书作家、数据创新者&分析和建立高绩效团队
结论
那些 下载电子书 的人可以免费获得这些简单而创新的想法,并享受我们的特色行业专家分享的其他见解。有一句老话说,85%的难题是由具有丰富经验的主题专家解决的,大约 15%是用适当的工具处理的。您可能拥有专业知识,但扩展数据科学还需要在指导下使用企业 MLOps 平台,让您的团队和组织越过终点线。我们邀请您阅读新的健康和生命科学版 数据科学创新者行动手册 ,了解如何加入创新者的圈子。
按行业划分的顶级高效机器学习应用
原文:https://www.dominodatalab.com/blog/high-impact-machine-learning-use-cases
在过去的十年中,机器学习(ML)模型已经使世界各地和各行各业的组织变得更有生产力、更有利可图,并且能够更好地服务于他们的客户。
按行业划分的机器学习应用
当涉及到在运营中开发和采用机器学习时,每个组织都有自己的挑战。但是,这些挑战中的大部分以前在他们的业务部门或 it 部门之外都遇到过。通过借鉴数据科学领域领导者的最佳实践,组织可以在竞争中脱颖而出,成为模型驱动型组织。
金融服务
在机器学习的帮助下,金融机构可以为客户提供更加个性化的服务、产品和推荐。例如, 全球财富 500 强企业 使用 ML 来改善呼叫中心的客户体验和客户沟通。他们还使用 ML 对人力资源部门的招聘人员工作量进行优先排序,以提高他们填补难以填补的职位空缺的成功率。
金融组织也使用 ML 来识别可能代表风险的异常情况,如异常交易模式,这可以提醒风险经理注意问题或触发立即解决方案。穆迪分析公司的 RiskCalc 模型 套件用于估计一家公司债务违约的概率。这些模型在全球范围内使用,基于行业标准,但针对不同情况进行了定制,考虑了地区差异以及不同保险公司和贷款机构所需的不同风险容忍度。
保险
如果开发和部署得当,机器学习模型可以完美地满足保险公司的承保需求。 模型驱动的保险公司 正在扰乱保险市场,以行动缓慢的现有公司为代价增加市场份额。
作为一家模型驱动的保险公司,意味着整体风险状况将受到显著影响。然而,正如法国巴黎银行保险分支机构所证明的那样,如果在强有力的治理框架下开发、部署和监控模型,这种影响会非常有益。BNP Paribas 在 35 个国家拥有 10,000 多名员工,为全球 1 亿名保单持有人提供服务,在整个组织中部署了 ML/AI 项目,不仅提高了模型开发的生产率,还在风险意识最强的利益相关者中建立了信誉。
另一家保险提供商 TopDanmark 能够使用 Domino 的 MLOps 平台开发和部署基于 ML 的应用程序,以显著提高其索赔处理的速度和准确性,允许 65%的案件实现自动化。如今,客户批准只需 1-2 秒,比人工理赔快近 800 倍。
媒体和技术
媒体和技术行业 有许多影响数据科学的机会,但该行业也有自己的挑战,其中大部分是由其最大的优势造成的——互联网、分散的劳动力和不断变化的技术,仅举几例。留住团队尤其困难,保持率只有两年。拥有一个能够访问尖端技术和内置协作工具的一流平台,已经成为数百家技术和媒体客户不可或缺的资产。
在一个著名的案例研究中,Red Hat 使用 Domino 的产品来团结其全球多样化的劳动力,以创建机器学习模型,通过更有效的销售分析来改善收入预测,同时将公司数据科学社区的效率提高 10 倍。
健康和生命科学
在 健康和生命科学领域 工作的数据科学团队面临诸多挑战,多样化的全球劳动力和保护敏感知识产权的需求只是其中两个。Domino 内置的企业级安全预防措施和丰富的协作特性已经帮助一些顶级公司开发出成功的基于 ML 的应用程序,以构建创新的解决方案和研究。
拜耳 最近启动了一项为期多年的研究项目,旨在开发能够提高作物产量、保护作物免受昆虫和除草剂侵害的种子。 Evidation 正在使用 Domino 来加快模型速度,在短短 8 周内实现生产级模型,帮助客户更好地管理他们的健康,使他们不会成为病人。
让桑 ,约翰逊&约翰逊的一个部门,正在用 Domino 和 Nvidia GPUs 训练速度快 10 倍的深度学习模型,通过全切片图像分析准确诊断和表征癌细胞。这使得他们能够增加临床试验资格筛选的患者数量。
制造业
多年来, 制造业 由于复杂的运营、众多的法规和笨拙的物流,已经落后于采用 ML 的其他行业。这些仍然是今天的挑战;然而,许多制造商已经成功地使用预测性和规范性模型来简化库存管理、优化营销支出并帮助确定最佳定价和促销。
市场领导者正在将目光从操作应用转向突破性的机器学习用例。就在去年, 洛克希德·马丁 成功构建了一个 基于 ML 的应用程序 ,模拟与 F-16 的空战,在所有五次交战中击败了人类飞行员。
机器学习对社会的影响
机器学习已经被证明是一个巨大的好处,不仅对企业和消费者,而且对整个社会都是如此。ML 模型有助于诊断疾病和癌症,预测交通模式,保护儿童和社区的安全,还有许多其他好处。
一个值得注意的例子是,Audubon 使用 Domino 的数据科学平台创建了 180,000 个模型 ,这些模型分析了超过 1 . 4 亿次观察,以预测不同气候变化可能性对鸟类的影响。
气候公司雇佣了大约 200 名使用 Domino 数据科学平台的数据科学家和数据工程师。他们使用机器学习、深度学习和其他复杂的分析方法来帮助农民种植更好的作物。这些模型能够确定种植什么种子或杂交品种,如何种植,如何培育以及何时收获作物以实现产量最大化。
机器学习在行动
如果你的组织还没有像这些公司那样在机器学习应用上取得成功,也许是时候重新审视你正在使用的工具了。财富 100 强公司中有 20 家现在使用 Domino 的企业 MLOps 平台来驱动他们的机器学习项目。无论您使用 R、Python 还是 MATLAB,Domino 都有您需要的库和协作工具。
用 Amazon 的 X1 实例实现高性能计算-第二部分
原文:https://www.dominodatalab.com/blog/high-performance-computing-amazons-x1-instance-part-ii
当您拥有 128 个内核和 2TB 的 RAM 时,很难不进行实验,并尝试找到利用触手可及的能力的方法。我们很高兴地提醒我们的读者,我们在 Domino 中支持 Amazon 的 X1 实例,您可以在具有 128 个内核和 2TB RAM 的机器上进行数据科学研究——只需单击一下:
X1 硬件层在我们的云托管环境中可用,并且可以提供给在 VPC 中使用 Domino 的客户。不用说,有了这种前所未有的计算能力,我们继续享受我们第一篇文章的乐趣。在业内一些联系人的鼓励下,我决定看看其他算法是否可以利用 X1 的能力。特别是一个深度学习神经网络和一些随机森林。
深度学习
虽然深度学习神经网络最常在 GPU 上训练,但 H2O.ai 有一个深度学习模型,在 CPU 上运行得很好。使用 H2O 的h2o.deeplearning
模型和带有两个隐藏层的整流器激活函数,每个隐藏层有 200 个神经元,我能够在短短 4 分钟内在航空数据集的 1000 万行上训练一个网络!深度学习模型没有扩展到所有 128 个核心(更准确地说,是 AWS vCPUs),但利用了近 50%的可用 CPU 容量,并在验证测试集上生成了非常可观的 AUC 0.7255915。
随机森林
众所周知,随机森林的训练速度很慢。它们具有令人印象深刻的性能特征和真实世界的行为,但构建起来可能会很慢,尤其是对于大型数据集。与 GBM 不同,随机森林训练更具并行性。对于第一个测试,我使用了 H2O 的随机森林实现,过去在 Kaggle 比赛和客户解决方案中都使用过,发现它表现良好。对于这个测试,我在 X1 实例的 1000 万行数据上训练了一个有 1000 棵树的随机森林。该算法能够利用 X1 实例的几乎所有处理能力。
如前所述,训练一个随机的森林模型可能很耗时。X1 花了近 3 个小时完成培训。然而,相对于验证数据,模型的 AUC 为 0.7699968,这说明了对非常大的数据集使用随机森林的预测能力。
对于第二个测试,我决定试试 scikit-learn 的RandomForestClassifier
,因为它已经证明自己是随机森林算法的一个成熟且健壮的实现。为了在 128 个内核上并行训练 RandomForestClassifier,我需要做的就是将参数n_jobs=-1
传递给构造函数。Scikit-learn 不是并行重采样和交叉验证,而是单个RandomForestClassifier
对象的实际构造。
scikit-learn RandomForestClassifer
比 H2O 兰登森林多花了一个多小时训练,用了 4 个多小时完成。该实施方案的 AUC 为 0.759779,低于 H2O 模型。所有的随机森林算法并不相同,在这种情况下,H2O 的算法提供了比 scikit-learn 实现更快的性能和更高的精度。
scikit-learn 的RandomForestClassifier
也比 H2O 的算法使用了更多的内存:训练 scikit-learn 分类器使用了 540GB 的内存,接近峰值时 24GB H2O 随机森林的 20 倍。这两种内存占用都非常适合 X1 实例的巨大可寻址内存空间。也就是说,540GB 的内存是 X1 的内存。人们可以想象 scikit-learn 的内存使用严重限制了可以使用它的RandomForestClassifier
训练的模型的大小。
在接下来的几个月里,我们将继续撰写关于高性能机器学习的文章,探索 X1,亚马逊的新 P2 GPU 实例(16 个 NVIDIA K80 GPUs,64 个 vCPUs,732GB RAM),以及我们可以找到的任何其他东西。值得注意的是,这些博客帖子不应该被视为关于我们使用的任何库或算法的性能的权威帖子。相反,它们对于理解利用如此巨大的计算能力所面临的挑战非常有用。我们希望我们的客户和其他供应商将开始发布类似的帖子,描述社区如何利用这些新平台的力量并推动艺术向前发展。
Loren Kerns 制作的标题为“森林”的横幅图片。2.0 下 CC 授权
亚马逊 X1 实例的高性能计算
原文:https://www.dominodatalab.com/blog/high-performance-computing-with-amazons-x1-instance
我们很高兴宣布支持亚马逊的 X1 实例。现在,在 Domino 中,您可以在具有 128 个内核和 2TB RAM 的机器上进行数据科学研究——只需点击一下:
X1 硬件层在我们的云托管环境中可用,并且可以提供给在自己的 VPC 中使用 Domino 的客户。
不用说,使用这种前所未有的计算能力,我们得到了一些乐趣。请继续阅读我们对使用 X1 实例进行数据科学的一些思考。
处理能力:使用 128 个内核
几年前,在一台机器上访问 128 个内核几乎是闻所未闻的,更不用说在一个可以按分钟租赁的平台上了。这种规模的核心数量以前只是分布式和 HPC 系统的领域。
将机器学习工作负载分布到 128 个内核的能力是一个重要的问题,但两种常见的技术是(1)并行化机器学习本身和(2)并行化跨多种可能配置的算法拟合(即,网格搜索)。
并行化网格搜索相当简单,像 scikit-learn 和 caret 这样的包为此提供了很好的解决方案。然而,机器学习算法的并行化是一个具有挑战性的问题。这种方法有许多天然的限制,尤其是许多机器学习算法核心的大规模矩阵运算。这些对有益的并行性的数量有自然的限制。
为了探索这些限制,我对两个现代机器学习工具包 H2O 和 XGBoost 进行了简短而不完整的分析,以在规范的航空数据集上拟合具有 1000 棵树的 GBM。我不承担验证生成的模型的拟合优度的任务。在这种情况下,我只是想知道在给定大量内核的情况下,这两个包能够利用多少并行性。
使用 3.10.0.6 H2O 的 R 包版本,并在航空公司数据集的 10 万行上进行训练,该系统能够在 813 秒内训练一个具有 1000 棵树的单一模型。理论上,处理器的全部利用率为 12,800%,即每个内核的利用率为 100%。在训练期间,处理器利用率达到大约 5,600%的峰值,这意味着使用了 56 个内核。
鉴于 GBM 算法的性质,这种限制是可以理解的。对于由算法输入的形状所确定的可能用于训练的并行量有明确的限制。有趣的是,虽然 46GB 的峰值内存使用对于 GBM 来说很高,但它在 X1 上仍然只占总可用 RAM 的很小一部分。尽管 H2O 的 GBM 算法提供了出色的性能,但它无法利用 X1 实例的大部分处理能力和可用内存。
当拟合多个模型并试图搜索大的超参数空间时,X1 实例类型和 H2O 网格工具的能力显示了价值。使用 H2O 的网格搜索示例的修改版本,H2O 的软件包能够利用几乎所有的 128 个内核!
虽然使用 H2O 网格搜索生成任何单个模型受到 GBM 算法的限制,但搜索巨大的超参数空间并利用 X1 为 GBM 找到最佳超参数的能力不应被低估,因为这通常是一项耗时且乏味的任务。
当使用 XGBoost 包为 r 训练类似的单个 GBM 模型时,结果更好。XGBoost 能够利用系统可用处理器能力的近 9300%,即 93 个内核。虽然这仍然使一些处理器没有得到充分利用,但 XGBoost 能够在 117 秒内训练一个有 1000 棵树的 GBM,不到 H2O GBM 所需时间的 1/7。
XGBoost 的作者 Tianqi Chen 广泛地谈到了他利用大规模并行性的许多技巧和方法。XGBoost 专注于提供高性能的 GBM 实现,这表明:它的微调方法能够充分利用 X1 的硬件,训练模型所需的时间比使用 Domino 平台上以前最大的 36 核硬件选项所需的时间少⅓。
同样值得注意的是,XGBoost 在内存使用方面非常高效,在与 H2O 相同的数据集上仅使用了 286 兆字节的内存。这大约是 H2O 实现及其运行时分配的内存的 0.5%。尽管在 X1 实例上这不是问题,但考虑到它们巨大的可寻址内存量,这是一个有趣的发现。
足够的处理能力侵入分布式系统
利用 AWS X1 到 Domino 为数据科学家提供的处理能力远远超过了单台机器通常提供的能力。虽然并非所有的处理能力都可以立即简单地获得,并且需要一些智能应用程序,但是例如,当在 XGBoost 内部训练 GBM 时,能够利用 90 多个内核,这拓展了需要分布式系统解决哪些问题的界限。
以前需要 Apache Spark 之类的分布式系统,并需要在可能不熟悉的工具上重新实现和重新培训的问题,现在可以相对简单地解决。使用数据科学家已经知道并喜爱的工具来训练 GBM 和进行大规模并行网格搜索的能力将迫使许多分布式系统的追随者质疑他们真正需要在多大规模上支付分布式系统的代价。当一个人可以在 3 分钟内在 100 万行数据上训练 1,000 棵树时,标杆已经移动了相当大的距离。需要注意的是,这不是模型性能的基准。如果读者对模型性能的深入分析感兴趣,Szilard Pafka 的这份工作受到高度评价,并比较了本文和其他文章中使用的库。
内存:使用 2TB 的内存存在挑战
2TB 的内存是一个荒谬的数量。信封背面的计算表明,在 X1 实例上,可以在 RAM 中加载 420 亿行数据,用于实时交互探索。类似地,当从图形数据的角度考虑这个问题时,可以加载一个比 LiveJournal 图形数据集大 8000 倍的图形。
这种规模的挑战相当令人惊讶:如何将 2TB 的数据加载到 RAM 中,这需要多长时间?利用以前博客文章中的数据,我们发现data.table
fread
是一种非常快速的从磁盘读取数据的方式。一些快速基准测试表明,对于来自readr
包的单线程read_csv
来说,70MB/s 的读取速度是合理的预期。这意味着 2TB 数据的总读取时间接近 8 小时!虽然有许多多核 CSV 解析器可用,但用户可能仍需要等待一个小时才能完成数据加载。
这是处理如此大的数据集的一个相当出乎意料的方面。
结论
利用 Domino 的 X1 实例为数据科学家提供了真正的“机箱中的超级计算机”体验。以前需要移植到复杂的分布式计算环境(如 Apache Spark)和使用不熟悉的语言(如 Scala)的问题,现在可以通过数据科学家熟悉和喜爱的工具来处理:R 和 Python。
传统上可并行化的任务,如网格搜索或蒙特卡罗模拟,可以轻松地利用大量的可用内核。虽然许多现代机器学习库确实利用了并行性,但它们不会立即利用所有内核,并且需要一些工作来充分利用 X1 的能力。
拥有 2TB 的可用 RAM 允许全新类别的“整个数据集”分析,以前这需要昂贵的磁盘访问,并不断计算访问长期存储的对数延迟损失。然而,天下没有免费的午餐:从磁盘快速读取数据到 RAM 仍然是一个有趣的挑战。
我们很高兴有机会在这种规模的硬件上支持您的分析,并迫不及待地想看看这个平台允许您创建什么样的新分析和新模型。X1 实例现在可以在 Domino 的云生产环境中使用,我们将很乐意与任何感兴趣的 VPC 客户合作,将 X1 实例提供到他们的环境中。
好奇还有哪些算法可以受益于 X1 的强大功能?我在第二部中得到了一些乐趣。
Nic McPhee 制作的标题为“书立”的横幅图片。持牌下 CC 乘 2.0
具有深度检查的高标准 ML 验证
原文:https://www.dominodatalab.com/blog/high-standard-ml-validation-with-deepchecks
在 之前,我们已经在 的博客中谈到了模型验证的重要性,这是一个确保模型按照预期的方式运行并解决其设计要解决的问题的过程。验证和测试是构建您可以信任的机器学习管道的关键要素。我们还谈到了 将测试 整合到你的管道中,许多数据科学家发现这是有问题的。这些问题源于这样一个事实,即并非所有的数据科学家都对传统的代码测试方法充满信心,但更重要的是,数据科学不仅仅是代码。在验证管道时,我们需要考虑验证数据完整性、检查其分布、验证数据分割、模型评估、模型比较等。但是,我们如何应对这种复杂性并保持管道的一致性呢?进入deep checks——一个用于测试和验证机器学习模型和数据的开源 Python 包。
请注意,深度检查可以在模型生命周期的多个阶段插入——您可能希望在接收数据后立即检查数据,但也要确保在预处理完成后,您的训练和测试集没有问题。深度检查还通过提供对模型性能的洞察来促进模型评估阶段。
这个包最初是用表格数据创建的,但最近已经扩展到支持计算机视觉用例。据其创建者称,NLP 功能目前也正在开发中。
深度检查入门
安装包很容易,因为它已经是 PyPI 的 部分。表格数据支持是使用
pip install deepchecks --upgrade
并且具有计算机视觉支持的味道是使用
pip install "deepchecks[vision]" --upgrade
唯一需要注意的是 CV 支持还需要 Pytorch,您必须单独安装它。
该框架引入了三种不同的范例,为了有效地使用深度检查,您需要理解这三种范例:
- 检查 -这些是主要的构建模块,它们使您能够探测数据/模型的不同方面。一般来说,有三种类型的检查,根据其目标 ML 管道的阶段进行分类:数据完整性、训练测试验证和模型性能评估。运行检查的结果可以是可视的人工产物(表格、图表等)。)或返回值,您可以将它们与条件一起使用(见下文)
- 条件 -可以添加到带有通过/失败/警告输出的检查中的功能。Deepchecks 提供的大多数开箱即用的检查都带有预先实现的条件,但是您可以轻松地添加、删除和自定义这些条件。
- Suites -带有相应条件的有序支票集合。套件使您能够一次运行多个检查,还可以显示一个摘要报告,以便您可以看到完整的结果集合。Deepchecks 提供了许多预构建的套件,但也让您能够通过定制现有套件或从头开始创建新套件来构建自己的套件。
一个(不那么)简单的保险欺诈用例
现在我们知道了深度检查的一些基础知识,让我们看看如何使用这个框架来分析一个有问题的数据集。我们将使用涉及车辆的欺诈性保险索赔数据集的修改版本。这个数据集在很多层面上都存在问题,看看 Deepchecks 如何捕捉并帮助解决这些问题是很有趣的。请注意,下面的代码片段摘自端到端演示笔记本,可在此处获得。
数据接收和验证
我们首先从熊猫数据框架中获取原始数据。
data_df = pd.read_csv("insurance_fraud.csv")
data_df.head()
数据集包含各种列,包括数字列、字符串分类列和日期时间相关列。
Deepchecks 可以提供帮助的第一步是当数据“刚出炉”时,即您第一次加载数据时。使用 Deepchecks 的第一种方式是运行包含多个检查的预构建套件。每个检查测试数据或模型的一个方面,可以独立地失败或通过其预定义的“条件”。
现在,我们将加载 single_dataset_integrity 套件,并使用它来检测加载的数据框的完整性问题。
from deepchecks.tabular.suites import
single_dataset_integrity
result = single_dataset_integrity().run(data_df)
result
....
结果显示顶部的条件摘要会立即提醒我们进行三次检查,看看谁的条件失败了。第一个(用失败条件的 x 标记)告诉我们在“PastNumberOfClaims”列中有几种类型的空值。单击该表的 check 列中的链接,我们将看到 Check 显示,它让我们知道该列既有字符串“none ”,又有 numpy NaN 值,标记了该特性中的缺失值。
第二个失败条件(标有黄色的“警告”符号,让我们知道这不是一个严重的失败)让我们知道我们在两列中有混合的数据类型。进一步的检查表明,我们有一个单一的样本,在这些列包含零。
data_df['DayOfWeekClaimed'][data_df['DayOfWeekClaimed'].str.isnumeric()]
1146 0
Name: DayOfWeekClaimed, dtype: object
data_df['MonthClaimed'][data_df['MonthClaimed'].str.isnumeric()]
1146 0
Name: MonthClaimed, dtype: object
最后,字符串不匹配检查提醒我们,单个类别(月份)在字符串值中有几种不同的表示方式。
data_df['Month'].value_counts()
Jan 1014
May 975
Mar 949
Jun 937
Dec 925
Oct 923
Apr 917
Feb 913
Sep 908
Jul 907
Nov 864
Aug 806
5 53
10 50
11 49
3 46
12 45
8 45
6 44
9 44
4 42
1 42
2 36
7 31
数据预处理和数据验证
我们现在可以在前进之前处理所有这些完整性问题,而不是在建模时(或者更糟,以后)捕捉所有这些问题。
data_clean_df = data_df.copy()
data_clean_df['PastNumberOfClaims'] = data_clean_df['PastNumberOfClaims'].fillna('none')
data_clean_df.drop(index=1146, inplace=True)
data_clean_df['Month'] = data_clean_df['Month'].replace({str(i): datetime.date(1900, i, 1).strftime('%b') for i in range(1, 13)})
data_clean_df['DayOfWeek'] = data_clean_df['DayOfWeek'].str.lower()
我们现在可以重新运行 Deepchecks 套件,看看我们是否已经解决了所有这些完整性问题。
single_dataset_integrity().run(data_clean_df)
安全了。我们可以继续为模型训练准备数据。
现在我们做一些额外的特征预处理,以帮助模型。我们注意到一些属性包含丢失的值。让我们执行一个简单的特性工程步骤,根据特定的属性类型,用适当的缺失值来替换字符串“none”和“new”。为此,我们将使用以下函数:
import re
def str_to_mean(str_val):
if isinstance(str_val, (int, float)):
return str_val
if str_val.lower() == 'none':
return np.nan
if str_val == 'new':
return 0
parts = re.findall(r'\d+', str_val)
parts = list(map(int, parts))
if len(parts) < 1:
raise ValueError(str_val)
return np.mean(parts)
现在让我们将它应用到正在讨论的属性中:
data_clean_df['VehiclePrice'] = data_clean_df['VehiclePrice'].apply(str_to_mean)
data_clean_df['Days_Policy_Accident'] = data_clean_df['Days_Policy_Accident'].apply(str_to_mean)
data_clean_df['Days_Policy_Claim'] = data_clean_df['Days_Policy_Claim'].apply(str_to_mean)
data_clean_df['AgeOfVehicle'] = data_clean_df['AgeOfVehicle'].apply(str_to_mean)
data_clean_df['AgeOfPolicyHolder'] = data_clean_df['AgeOfPolicyHolder'].apply(str_to_mean)
data_clean_df['NumberOfCars'] = data_clean_df['NumberOfCars'].apply(str_to_mean)
data_clean_df['PastNumberOfClaims'] = data_clean_df['PastNumberOfClaims'].apply(str_to_mean)
我们还需要处理“AddressChange_Claim”属性,要么将其解包为二进制变量,要么用数字表示持续时间。为了简单起见,我们将采用后者。
data_clean_df['AddressChange_Claim'] = data_clean_df['AddressChange_Claim'].replace(
{
'no change': 10,
'4 to 8 years': 6,
'2 to 3 years': 2.5,
'1 year': 1,
'under 6 months': 0.5
})
最后,我们需要将数据分成训练集和测试集。不过,在我们开始之前,让我们先来看看样本是如何在数据集中每年的每个类中分布的。这样,我们可以根据年份进行拆分,这是当数据具有时间成分时处理拆分的正确方式。
data_clean_df[['Year', 'FraudFound_P', 'Month']].groupby(['Year', 'FraudFound_P']).count()
我们现在以这样一种方式分割数据,即 1994 年的所有观测数据将用于训练模型,而其他所有数据将用于评估。
train_df = data_clean_df[data_clean_df.Year == 1994]
test_df = data_clean_df[data_clean_df.Year > 1994]
通常在这一步之后,我们将直接尝试用一些模型进行实验,谁能责怪我们呢!但是 Deepchecks 提供了一个特殊的预建检查套件,旨在检测数据集分割方式的问题。我们会运行这个套件以确保。
为了访问 Deepchecks 更高级的功能,我们必须告诉它更多关于我们的数据集的信息。标签是什么?分类特征是什么?为了做到这一点,我们使用 Deepchecks Dataset 对象来包装我们的数据帧,并包含这些元数据信息。
我们首先创建一个包含所有分类变量的列表。
from deepchecks.tabular import Dataset
cat_cols = ['Month',
'WeekOfMonth',
'DayOfWeek',
'Make',
'AccidentArea',
'DayOfWeekClaimed',
'MonthClaimed',
'WeekOfMonthClaimed',
'Sex',
'MaritalStatus',
'Fault',
'PolicyType',
'VehicleCategory',
'PoliceReportFiled',
'WitnessPresent',
'AgentType',
'NumberOfSuppliments',
'BasePolicy']
我们还需要告诉 Deepchecks 我们的日期时间指示器是什么。这里,是年份栏。然后,Deepchecks 可以在拆分包含时间泄漏的情况下发出警报,尽管在这种情况下,我们知道我们正确地进行了拆分,因此测试数据在时间上在训练数据之后。注意,我们还指出了分割中使用的目标变量。
train_ds = Dataset(train_df, label='FraudFound_P', datetime_name='Year', cat_features=cat_cols)
test_ds = Dataset(test_df, label='FraudFound_P', datetime_name='Year', cat_features=cat_cols)
我们现在运行 train_test_validation 套件,它正是为了验证我们的分割而构建的。由于正在运行一些更复杂的逻辑,这可能比完整性检查需要更多的时间。
from deepchecks.tabular.suites import train_test_validation
res = train_test_validation().run(train_ds, test_ds)
res
报告摘要如下所示:
我们经历了许多失败。更深入地看,我们在我们的分歧中看到两个问题:
-
旨在检测训练和测试数据集之间单个特征分布变化的特征漂移检查偶然发现了一个完全不同的问题——我们忽略了 PolicyNumber 列实际上是保险单的运行索引,完全不适合用作特征。
-
类别不匹配训练测试检查提醒我们,分类特征“Make”在测试数据中有一些训练数据中不存在的新类别。如果输入到模型中,这肯定会引起一些混乱,如果不是彻头彻尾的例外的话。
让我们快速解决这些问题。首先,我们删除测试集中出现的额外类别。
test_df = test_df[~test_df.Make.isin(['Ferrari', 'Lexus'])]
我们还可以通过显式地将 PolicyNumber 作为 index_name 传递来告诉 deep checks policy number 是我们的索引列,而不是一个特性。对于额外的非特性列,我们可以通过向 Dataset 对象的特性参数传递一个列表来明确定义哪些列将被视为特性。
train_ds = Dataset(train_df, label='FraudFound_P', datetime_name='Year', index_name='PolicyNumber', cat_features=cat_cols)
test_ds = Dataset(test_df, label='FraudFound_P', datetime_name='Year', index_name='PolicyNumber', cat_features=cat_cols)
让我们再次运行验证,看看我们的更改是否解决了有问题的发现。
res = train_test_validation().run(train_ds, test_ds)
res
或者,我们可以做一些更 Pythonic 化的事情,而不是再次检查整个输出——我们可以检查每个单独检查的结果(在由名为。结果)并确保他们的条件已经通过。
all(res.results[i].passed_conditions() for i in range(len(res.results)))
True
再说一遍,一切正常!我们终于可以继续训练我们的模型了。
模型训练和验证
为了拟合模型,我们将使用 CatBoost,这是一个高性能的开源库,用于决策树的梯度提升。我们将创建一个 CatBoostClassifier 实例,用于训练和应用分类问题的模型。该类还提供了与 scikit-learn 工具的兼容性。
from catboost import CatBoostClassifier
model = CatBoostClassifier(iterations=100, random_seed=42, verbose=0)
model.fit(train_df.drop(columns=['FraudFound_P', 'Year', 'PolicyNumber']), train_df['FraudFound_P'],
cat_features=cat_cols)
<catboost.core.CatBoostClassifier at 0x7f4e436614f0>
现在我们有了一个训练好的模型,让我们看看深度检查如何帮助模式评估。
from deepchecks.tabular.suites import model_evaluation
res = model_evaluation().run(train_ds, test_ds, model)
res
总结表明我们的模型有些问题。例如,我们看到它与常数模型相比具有几乎相同的性能,常数模型总是输出类 0。这是两个阶层高度失衡造成的。
让我们重新训练模型,以解决不平衡的阶级。
model = CatBoostClassifier(iterations=100, random_seed=42, verbose=0,
scale_pos_weight=np.sqrt(len(train_df[train_df['FraudFound_P']==0]) / len(train_df[train_df['FraudFound_P']==1])))
model.fit(train_df.drop(columns=['FraudFound_P', 'Year', 'PolicyNumber']), train_df['FraudFound_P'],
cat_features=cat_cols)
<catboost.core.CatBoostClassifier at 0x7fa92f1e5640>
我们在开始时提到 Deepchecks 也支持定制套件——一个接一个运行的检查列表,其结果将一起显示。让我们使用此功能来定义一个自定义套件,它执行以下操作:
- 运行检查,验证测试性能与列车相比下降不超过 0.1%
- 为模型生成混淆矩阵,并将其包含在报告中
- 检查因在梯度增强模型中使用过多迭代而导致的过度拟合
- 使用简单的模型试探法来建立基线,并验证模型的性能相对于基线至少提高了 10%
设置和运行定制套件的代码非常简单明了。
from deepchecks.tabular import Suite
from deepchecks.tabular.checks import PerformanceReport, BoostingOverfit, SimpleModelComparison, ConfusionMatrixReport
custom_suite = Suite('My Custom Performance Suite',
PerformanceReport().add_condition_train_test_relative_degradation_not_greater_than(0.1),
ConfusionMatrixReport(),
BoostingOverfit(alternative_scorer=['f1', 'f1']).add_condition_test_score_percent_decline_not_greater_than(0.01),
SimpleModelComparison().add_condition_gain_not_less_than(),
)
custom_suite.run(train_ds, test_ds, model)
我们看到有三项检查失败了。其中一个指示模型过度拟合,这也可能是其他两个被触发的原因。让我们重新训练该模型,并改变一些可以缓解过度拟合问题的参数。例如,我们可以减少训练迭代的次数,限制其深度等。
model = CatBoostClassifier(iterations=50, random_seed=42, verbose=0, learning_rate=0.2, colsample_bylevel=0.03, subsample=0.5,
depth=4,
scale_pos_weight=len(train_df[train_df['FraudFound_P']==0]) / len(train_df[train_df['FraudFound_P']==1]))
model.fit(train_df.drop(columns=['FraudFound_P', 'Year', 'PolicyNumber']), train_df['FraudFound_P'],
cat_features=cat_cols)
这一次,我们看到增压过量检查变成了绿色。我们还可以看到,训练和测试中的 F1、精度和召回指标都得到了提高。就性能而言,我们还没有达到这一水平,但这主要是由于数据不平衡(这可以很容易地在简单的模型比较细节中看出)。然而,纠正这一点是通过其他技术实现的(参见 合成少数过采样(SMOTE)技术 ),不在本文讨论范围之内。
摘要
在本文中,我们研究了 deep checks——一个开源包,它使您能够为数据和模型验证构建测试套件。我们展示了它的一些核心功能,并看到了该框架在模型生命周期的不同阶段是多么有用。这里我们使用深度检查来:
- 评估不熟悉的新数据集
- 确保训练/测试集被正确分割,没有数据泄漏
- 检查我们模型的性能
我们没有探索任何 计算机视觉特有的功能 ,这听起来肯定很有希望。同样值得注意的是,Deepchecks 背后自称为“机器学习极客”的团队正在积极增加新功能。例如,模型比较和模型可解释性是 Deepchecks 路线图上听起来特别有趣的两个项目。
Deepchecks 已经有了很多像 DataDudes 这样的企业客户。@ Datadudes 的联席首席执行官 Nathaniel Shimoni 说:“我们一直在使用 Deepchecks 来验证我们的数据,每次我们得到一个新的测试集,以及在我们部署到生产之前。我和我的团队喜欢这个包,我们计划将它的使用扩展到其他阶段。
开源也是 Deepchecks 的优势。将框架与 H2O 模型、气流 CI/CD 管道、pytest 测试用例 HuggingFace Transformers 以及当然还有Domino Enterprise MLOps Platform结合起来相当简单。
马里兰数据科学会议的亮点:图像和文本的深度学习
人工智能和数据科学咨询公司 Miner & Kasch 的联合创始人 尼尔斯·卡斯奇,提供了在马里兰州数据科学大会上举行的深度学习会议的见解。
介绍
这篇博客概述了 Miner & Kasch 在 UMBC 举办的首届马里兰数据科学大会,并深入探讨了由 Florian Muellerklein 和 Bryan Wilkinson 主持的 关于图像和文本的深度学习演讲。
数据科学是一个令人兴奋、快速发展和充满挑战的领域,因此在一所名列全国最具创新性学校第九位的顶尖学校举办这次会议似乎是合适的。(你可能还记得 2018 年 NCAA 锦标赛奇迹中的 UMBC。)和耶...Miner & Kasch 由 UMBC 校友创办。
在这次会议上,我们将工业界和学术界聚集在一起,讨论机器学习、人工智能和数据平台方面的最新发展和前沿科学。我们聚焦于行业从业者——数据科学家、业务经理、企业家、ML 工程师以及学生——来展示和讨论人们在行业和学术界前沿研究中面临的现实问题。
会议并不是一帆风顺的。首先,一场巨大的冰雪风暴迫使我们取消了原定的活动。但是,尽管因为下雪取消了行程,接下来又做了重新安排的噩梦(如果你想听更多关于我们从错过的午餐中优雅恢复的事情,请 PM me),我们还是让 UMBC 全新的表演艺术和人文建筑的音乐厅坐满了人。
会议主题和发言人阵容包括:
- 前沿的深度学习技术,来自 UMBC 的 Frank Ferraro 博士讲述了用于平易近人的事实预测和验证的神经语义方法,谷歌的 Marc Pickett 博士讲述了持续学习。
** 行业对话,如 TRowe 的 Erik von Heijne 关于量化金融研究中的文本数据以及地理空间情报初创公司 GeoSpark 的 Serena Kelleher-Vergantini 和 Brendan Slezak 关于 用机器学习和开源数据 衡量地缘政治风险。* 数据平台讲座,包括 Databricks 的 Jordan Martz 关于使用 Apache Spark 进行大规模数据分析的讲座、Miner & Kasch 的蒂姆·伯克关于在云端进行数据科学的讲座、Corey Nolet 关于 NVidia 最新的 DL 框架** 展望,有贾斯汀·勒托、 大数据& AI:行业现状、劳动力趋势及未来展望
*## 图像和文本的深度学习
在社交时间,Florian Muellerklein 和 Bryan Wilkinson 博士以深度学习为重点的演讲吸引了观众的注意力,并引发了许多后续讨论。他们的 talk 关于图像和文本的深度学习 顾名思义,专注于处理图像和文本数据的深度学习的最新进展。
这个演讲特别有趣,因为:
- 公司拥有大量文本数据,从合同和法律文件到员工调查和社交媒体。公司通常不知道如何开始分析这些数据并从中获取价值。
- 图像和视频数据是公司增长最快的数据来源之一,最近的进步使安全、质量控制和零售智能等许多使用案例成为可能。
- 该演讲对最新技术以及机器学习实践者如何将这些技术应用于他们的问题提供了一个很好的概述。
意象的深度学习
深度学习现在经常用于图像分类、对象检测、图像分割和图像生成等任务。Florian 在他们的谈话中表示,这些任务是通过深度学习模型学习训练数据的多阶段表示的能力来实现的。这些多阶段表示是提高模型准确性的核心,它们适用于各种用例。那么 DL 中的表征学习是如何工作的呢?
一个深度学习模型,在基础层面,由输入层、隐藏层、输出层组成。在输入,你输入模型数据,也就是图像。负责学习表示的隐藏层“使用多层非线性处理单元的级联进行特征提取和转换。每个后续层都使用前一层的输出作为输入。”输出层通常为图像生成一个类标签,或者关于图像或图像中的一些其他有用的东西,这取决于您的问题设置。
研究人员正在更好地理解和表征模型组件,例如在隐藏层中的不同卷积运算如何对学习表示做出贡献。例如,可以识别为边、直线和曲线等概念激活的网络部分。然而,你在网络中走得越深,网络学习的抽象表示就越多。这是由于网络的设计,其中卷积操作假设图像像素之间的空间相关性,这当然是一个合理的假设。线之所以只是线,是因为空间相关的像素形成了线。由于网络可以保持较低层次概念的空间依赖性,较深层次能够学习高层次的概念,如什么使脸成为脸。
如下面的动画所示,您可以通过网络的不同层跟踪学习到的表示。在可视化中,每个色块代表一个图像类别,您可以看到更深的层如何更好地识别这些组件的本质。这使得用正确的分类适当地标记每个图像变得微不足道。
我们如何在实践中使用它?
首先,关于模型结构的现有研究和见解使我们能够知道哪些模型组件允许我们学习空间/图像数据的良好表示。我们可以将模型组件视为加速创建新模型的构建模块。例如,简单地替换输出层并将不同类型的层附加到‘主干’层的末端,允许我们在不同类型的任务上训练模型。这是迁移学习中的常见做法。
Florian 展示了一些预先训练的模型,如 ResNet、Inception V3,以及如何利用这些模型学习的表示来完成自己的定制机器视觉任务,而无需从头开始重新训练这些网络的时间和成本。他使用无人机镜头中实时检测汽车的令人印象深刻的视频展示了这些能力。他基本上是让一架无人机在一个街区上空飞行,并在无人机的视频流中找到所有的汽车。令人印象深刻,但你自己看吧。
文本深度学习
虽然图像在计算机世界中有一种固有的表现形式——图像只是像素值的矩阵,而 GPU 在处理矩阵方面非常出色——但文本却没有这种固有的表现形式。那么问题就变成了,- 如何表示深度学习的文本。
Bryan 研究了各种编码方案,以处理与不同自然语言处理(NLP)任务相关的特殊文本。一种广泛使用的表示方法是将单词编码为向量(见下文),其中每个单词都被转换为一个向量,该向量包括关于单词本身(例如,大写模式)及其周围上下文的信息(例如,单词是前面是大象,后面是喝酒)
文本中的图像之间的区别因素之一是特定句子中的文本具有不同的长度。长短期记忆(LSTM)神经网络很好地处理了这个问题,因为它们可以应用于任意大小的序列。时序数据也是有序的,LSTMs 在这方面也有帮助。
在当今文本丰富的世界中,您可以在 NLP 的所有领域中找到 LSTMs,包括:
- 机器翻译
- 问题回答
- 情感分析
- 语法纠正
- 信息提取
- 信息检索
- 文件分类
- 基于内容的推荐系统
- 更多的
这些字段之间的区别在于 LSTMs 的使用方式。例如,在词性标注中,当您试图识别句子中的单词是动词、名词还是另一个词类时,LSTM 节点会为序列中的每个单词生成一个输出。
在情感分析等其他应用中,您可能对一条推文是正面、负面还是中性的情感感兴趣,LSTMs 将它们的输出传播到推文中的整个单词序列,以产生单个输出。
然而,在语言建模和文本生成中,当您试图预测序列中的下一个单词时,LSTMs 在对单词周围的上下文进行建模时非常有用。
对文本的深度学习有它自己的迁移学习形式——嗯,不完全是迁移学习,而是在大量文本上预先训练一个大型网络,就像对 BERT 所做的那样。这里的想法是从容易获得的文本来源(如维基百科)创建一个通用语言模型,然后将该模型用于您的特定任务。
Brian 提到,预训练模型“不仅提高了性能”,而且“可以减少所需训练实例的数量。”这对从业者有严重的实际好处!作为一个实际的例子,“一个预训练的 ULMFIT 模型只需要 100 个带标签的情感数据的例子,就可以达到与在 10,000 个带标签的例子上从头学习的模型相同的性能。”
下一步是什么
深度学习社区在马里兰州很强大。我们的会议取得了巨大的成功,从与会者的人数到他们不同的背景。UMBC 的学生与公司和行业从业者进行了一天的交谈。我们希望许多学生找到了实习机会和/或收到了工作邀请。*
平行实验的水平缩放
原文:https://www.dominodatalab.com/blog/horizontal-scaling-parallel-experimentation
科学家等待实验结果所花费的时间数据量,就是做出渐进式改进和取得重大进步的区别。通过并行实验,数据科学家可以更快地进行更多实验,从而有更多时间尝试新颖和非正统的方法——这种方法可以带来指数级的改进和发现。
在上一篇文章中,我们展示了微观层面上的并行实验:使用 R 和 Python 包来利用多核处理器的硬件。在本文中,我们解释了如何在宏观层面上进行并行实验,以便在云中使用水平扩展更快地获得结果。
什么是水平缩放?
数据科学中的横向扩展是按需添加和删除计算环境以支持多个并发实验的能力。假设您有一个模型训练任务或模拟,即使在高端硬件上运行也需要一个小时,您想尝试它的一些变体。也许你正在测试一个交易策略,你想在多只股票上测试它,或者你正在运行蒙特卡罗模拟,你想为一个随机种子尝试多个值。
在微观层面上,通过播种具有多个参数的模型并将负载分布在多个内核上,可以更快地找到最佳解决方案。但是,如果您想要并行测试多个独立的方法,您可以使用水平缩放来实现。
水平扩展计算资源的能力可以让您尝试多种类型的模型,甚至是工程管道,而不会牺牲性能或灵活性。这在利用基于模拟和代理的方法作为近似和启发式方法时是非常强大的,在这种情况下,集合多个策略可以提供比任何单个策略更好的解决方案,无论调整得多么完美。
数据科学团队经常使用水平可伸缩性,他们需要训练数千个(如果不是数百万个)模型,并对大量独立的例子进行评分。
一个示例用例是广告技术或社交网络公司,它们希望开发一个按用户推荐或预测的模型。模型可以在大型用户群中并行训练具有水平扩展模型训练的能力允许这些团队构建针对每个特定用户的偏好和特质定制的模型。对这些模型的评分是分批进行的,其中响应被序列化到后端缓存中,以便进行亚毫秒级查找。这种大规模并行评分步骤还可以利用水平可伸缩性,因为缓存基础设施可以支持大量并行插入和更新。
*## 挑战
不幸的是,许多数据科学家无法利用水平扩展。原因如下:
如果他们在本地硬件上运行实验,他们必须连续完成这些任务,或者与同事竞争固定的计算资源。
如果他们在云中运行实验,理论上,他们可以创建多个并行运行的实例,但是这样做所需的时间、精力和知识是令人望而却步的。
(有多禁止?一个流行教程包含了在 EC2 上启动 Jupyter 笔记本的 15 个步骤,所有 15 个步骤都充满了潜在的错误。此外,这些步骤依赖于开源软件,这些软件可能会随时更新,带来意想不到的后果。)
无法使用横向扩展进行平行实验伤害了公司。它制造了一个瓶颈,不仅减缓了进步,也从根本上改变了数据科学家对好奇心和探索的容忍度。没有动力去尝试更有可能带来更大改进、变革性见解和竞争优势的大胆、非传统的方法。
解决办法
虽然看起来只有拥有无限资源和 DevOps 支持的大型组织才可以进行并行实验的水平扩展,但现在情况已经不同了。
像 Domino 这样的数据科学平台充当抽象层,让数据科学家直接从命令行按需启动云计算环境,而不需要 DevOps 帮助或漫长而脆弱的配置步骤。Domino 将为每个实验启动一个 AWS EC2 实例(在每个实验指定的机器类型上),当运行完成时关闭它,并自动检测和存储每个实验的结果。
并行运行几个实验很好,但是真正的可伸缩性不止于此。想象一下,你的团队可以启动数百个并行运行的并发实验,每个实验都在他们自己的 AWS 机器上进行。同样,这在理论上是可以在 AWS 中自己设置的,但是配置和维护这样一个基础设施的成本和工作量可能会很快抵消生产力的任何提高。有了 Domino 这样的平台,数据科学家可以通过一个命令或一个 API 来完成这项工作。
从 CLI 进行水平缩放的示例
我们希望在分类和回归任务上对 100 多种模型类型进行基准测试。在本地硬件或自我管理的云上训练数百个模型可能需要几个小时,但是利用水平可伸缩性(使用 Domino ),可以在命令行中用一个简单的“runner 脚本”并行训练模型:
input_file=$1
for object in cat $input_file
do
domino run --title "batch: $input_file model: $object" --no-sync
build_classification_models.R $object
done
这个脚本将所有实验排队,并让我们生成所有结果。
结论
将横向扩展交给数据科学家可以让他们更快地创新。云使得所有数据科学团队都可以进行水平扩展,Domino 使这变得很容易。
如果您有兴趣让您的团队能够进行具有水平可伸缩性的并行实验,那么学习更多关于在 AWS 之上使用 Domino 的知识。*
一家 90 岁的保险公司如何推动创新
原文:https://www.dominodatalab.com/blog/how-a-90-year-old-insurer-is-pushing-the-innovation-pedal
好事达的模式驱动之旅
编者按:这篇文章是分享公司在成为模型驱动的道路上的最佳实践的系列文章的一部分。一些文章将包含关于他们使用 Domino 的信息。
许多人可能会对好事达对模型的大量创新使用感到惊讶。拥有如此深厚根基和根深蒂固的经营方式的公司往往不愿改变现状。
但是,这家美国领先的保险公司并没有默认一切照常,而是利用数据科学取得了重大进展,推动首席数据和分析官 Eric Huls 所说的好事达服务的 1600 多万家庭的能力“逐步改变”。
“我们正在为我们的客户创造更加一致、积极的互动,并从根本上改变保险业,”胡尔斯说。“我们的愿景是,从仅仅在坏事发生时把事情做好,转变为首先找到预防这些不利事件的方法。”
该公司已经使用模型来通知营销工作,支持索赔处理,帮助生成报价,并预测整个组织每个部分(包括产品、销售、运营、营销和索赔)的数千个决策行为。
那么好事达的数据科学团队是如何如此成功地推动创新的呢?
根据 Huls 的说法,两项努力是关键:
- 通过与业务部门建立牢固的关系,打破变革的障碍。
- 为数据科学团队提供工具,让他们更轻松地测试新想法和开发模型。
让商业领袖参与分析
好事达追求一个积极务实的过程,使业务成为模型驱动的。这是一项广泛的、多方面的努力,其中包括:
- 投资员工培训并扩大招聘标准 确保好事达的数据科学专家具备“软技能”和业务知识,以对业务有意义的方式展示他们的工作。
- 投资商业领袖教育。 “我们在全公司推出了教育机会和社区,”霍尔斯说。“我们还安排了与行业专家的非正式会谈,这样好事达的管理人员可以了解前沿的数据科学技术,以及他们如何推进公司的战略。”
- 雇佣业务分析顾问来支持计划。 这一新设立的角色让数据科学团队能够直接了解核心业务问题和前景,以确保他们能够解决对业务有意义的问题。
- 整合业务部门内的数据科学团队。 好事达的集中分析团队(公司内部称为 D3——数据、发现和决策科学团队)反映并整合了好事达更大的组织结构。每个数据科学团队对其分配的业务部门都有虚线责任,团队领导积极参与高级领导讨论。
- 与各业务部门共同创建愿景、计划和路线图。 这种联合所有权强化了数据和分析在好事达未来的重要性,并确保在将模型投入生产时获得业务采纳和支持。
- 将分析计划与业务成果和结果联系起来。 “在任何项目的开始,我们都会问我们将如何衡量一个模型是否有预期的效果,”Huls 解释道。“如果我们不能用商业术语来衡量价值,我们就不会推进这个项目。”
- 造产品,不造模型。 数据科学团队考虑部署所需的所有功能,例如创建反馈循环以使报告和跟踪模型性能管理对业务来说更容易。“我们发现,当我们着眼于更广阔的前景时,采用率会大幅上升,一旦我们建立了模型,人们就会对改进和完善这些模型产生更大的兴趣,”Huls 说。
有效管理模型研究和开发
随着 Allstate 对模型需求的增长,D3 团队的数据科学专家从 30 人增加到 300 人,他们需要一种工具来帮助更好地管理模型研究和开发。“我们花在重新学习或重新创造结果上的时间越少,我们就能花更多的时间创造额外的价值,我们就能支持更多的项目,”Huls 说。
在这里,Domino 平台提供了他们需要的功能,包括:
- 确保数据科学家能够快速访问工具和技术资源。 大部分数据科学团队都知道这个演练。提交对软件工具或计算资源的请求,然后等待。有了 Domino,该公司的数据科学家现在可以一键访问他们需要的计算基础设施和软件工具,包括 R、Python 和 SAS。所以他们不用等了。新团队成员可以利用预先构建的计算和工具环境,这样他们可以更快地开始工作。
- 改善数据科学家之间的协作。 好事达的数据科学家使用 Domino 协作进行代码开发、共享反馈和迭代,Huls 可以轻松跟踪他们的工作进度。
- 将知识、见识、神器制度化。 在 Domino 中,现在一切都被记录下来——代码、环境细节、数据等等,用于研究和法规遵从性。因此,员工可以在过去工作的基础上,快速回答合规性查询,并查看所有过去的结果。最终,通过消除耗时的流程和加强协作,好事达的 D3 团队可以将他们的时间和专业知识集中到重要的地方:找到为客户带来改变的方法。
了解更多信息
观看 Huls 的演讲,在保守的行业中推动创新踏板,最初于 2019 年 5 月在 Rev 2 数据科学领袖峰会上发表。
https://www.youtube.com/embed/NPU9H7CcqVc
查看案例研究了解更多关于 Domino 如何帮助好事达推动创新的信息。
新冠肺炎是如何感染人工智能模型的
原文:https://www.dominodatalab.com/blog/how-covid-19-has-infected-ai-models
冠状病毒在全球 188 个国家的野火蔓延是灾难性的。迄今为止,它已经感染了 7400 万人,导致 160 万人死亡,预计将导致 2020 年全球国内生产总值收缩 4.5%至 5.2%至 5.2%之间,约为 4 万亿至 5 万亿美元。
新冠肺炎效应最难观察到的一点是它对人工智能模型的影响。尽管人工智能提供了很多优势,但人工智能应用并不是绝对可靠的。可以说,随着时间的推移,机器学习模型失败的最常见方式是当它们被训练的数据不再反映世界的现状。虽然大多数人工智能模型会逐渐退化,但新冠肺炎在从网上购物到预测航空客运量,再到正确理解图像描述的内容等应用中,突然退化了人工智能模型。
机器学习模型如何工作
人工智能模型通过识别将输入与输出匹配的模式(如“if x then y”)来自动化决策过程。为了以概括的方式学习这些模式,人工智能模型需要在大型数据集(称为训练集)上进行训练,有时结合专家的人工输入。通过这种方式,人工智能模型被训练来做出人类专家在相同数据集下会做出的决定。通常,可用于训练人工智能模型的数据集越大,它就越准确。
什么是漂移,它如何影响人工智能模型?
数据漂移或模型漂移是一个概念,是指模型的准确性随着时间的推移而下降。熵总是随着时间的推移而增加,因此每个模型的性能都会随着时间的推移而下降,而不管模型的质量指标如何——平均错误率、准确性或其他。对于某些型号,环境足够隔离和/或稳定,可以持续数年而无需校正漂移。然而,对于大多数模型来说,再培训需要更频繁地进行,有时是每天一次。
新冠肺炎如何迅速感染全球人工智能模型
如果人工智能只是和用于训练它的数据一样好,那么当一个黑天鹅事件发生时,它会改变人类的行为,这必然会使人工智能模型中的数据集变得多余。COVID 对数据科学模型影响的一些显著例子包括:
Instacart 的 instaproblem
在线杂货购物服务 Instacart 使用了一个数据科学模型,该模型通常拥有 93%的准确率,用于预测特定产品在给定商店是否可用。2020 年 3 月,面对新生的疫情,顾客彻底改变了他们的购物行为,准确率突然下降到 61%。
杂货店购物者通常只会偶尔购买卫生纸之类的东西。在大约一周的时间里,他们吃光了商店里的商品供应,如卫生纸、洗手液、鸡蛋、面粉和其他家庭必需品,因为市民们开始储备,以防供应链中断。
Instacart 通过将输入其人工智能模型的购物数据的时间尺度从数周改为仅 10 天进行了调整,使其模型对快速变化的购物习惯更加敏感。Instacart 的机器学习主管 Sharath Rao 告诉《财富》杂志,他们在用于训练模型的数据量和数据的“新鲜度”之间进行了权衡。
航空客运量
通常情况下,人工智能模型可以高度精确地预测未来的全球航空客运量。但是随着新冠肺炎造成灾难性的数据漂移,没有模型能够预测到 2020 年 4 月客运航空运输同比下降 90%。虽然航班略有恢复,但总体而言,今年对航空业来说是灾难性的。整个民航机队都被封存起来,数百万工人被暂时解雇。
来源:http://www . OECD . org/coronavirus/policy-responses/新冠肺炎-航空-工业-影响-政策-反应-26d521c1/
看图看错
Getty Images 向创意专业人士、新闻媒体和公司出售库存图像、照片和视频,并维护着超过 2 亿资产的图书馆。为了让客户找到合适的图片,Getty 使用广泛的标签和精确的分类法来支持客户的搜索。但新冠肺炎从根本上改变了数亿人的工作、娱乐和着装方式,导致计算机视觉模型难以理解新的社会和文化规范,并恰当地标记新场景和新情况的描述。
Getty Images 数据科学负责人 Andrea Gagliano 向 TechCrunch 提出了这个问题。假设你有一张父亲在家用笔记本电脑工作的照片,而他的儿子在旁边玩耍。Getty 的人工智能模型将此归类为“休闲”或“放松”,而不是“工作”或“办公室”,尽管绝大多数白领现在在家工作。或者想想面具——现在有这么多张脸戴着面具,人工智能模型正在努力准确识别和分类戴面具的人。他们将只检测脸部的上半部分,或者将面具和眼睛识别为两张不同的脸。
人工智能模型能像新冠肺炎一样对黑天鹅事件做出反应吗?
预测所有相关的未来事件并建立一个对黑天鹅事件有弹性的人工智能模型是不可能的。
你能做的是检测一个模型何时误入歧途,并创建一个决定它是否需要立即再培训或退役的过程。这样,它就不会默默地继续做出表面上消息灵通但实际上不准确的预测。
大多数数据科学团队不会主动监控漂移,尽管有些团队会进行零星和临时的测试。最近,一些数据科学团队已经开始使用专用模型监控工具来自动执行检测漂移、重新训练模型和部署更新模型的过程。这些工具不仅能检测出不良模型,还能立即通知数据科学家,以便他们采取纠正措施。
数据科学如何更快地超越失败
原文:https://www.dominodatalab.com/blog/how-data-science-can-fail-faster-to-leap-ahead
当今数据科学面临的最大挑战之一是找到合适的工具来完成工作。同类最佳选项的快速变化使得这尤其具有挑战性——只要看看当新语言出现时 R 是如何迅速失宠的就知道了。如果数据科学要在企业中尽可能快地发展,科学家需要工具来快速运行多个实验,丢弃不起作用的方法,并迭代剩余的最佳选项。数据科学家需要一个工作空间,在那里他们可以轻松地进行实验,快速地失败,并在通过认证和部署运行模型之前确定最佳的数据解决方案。
让我感到惊讶的一件事是数据科学生态系统有多么庞大。R 大概有 13000 个包,Python 有几十万个。但是如果你看一下的 Kaggle 调查,四年来使用 R 的数据科学家的百分比下降了超过 40 个百分点——从 64%下降到 23%。与此同时,使用 Python 的数据和业务分析师的比例从 61%急剧增加到 87%。去年 Python 跃居编程语言榜首,在 TIOBE 索引 上超过 Java 和 C,而 Swift 稍有异动,Julia 和 Dart 节节败退。变化如此之大,很难知道采取什么方法。一个高效的数据科学家不应该必须做出选择——他们应该能够尝试多种方法。
有一点我并不感到惊讶,那就是 it 部门需要多长时间才能推出一个新的更新。我要表扬他们,他们在验证、检查许可和使用权、安排服务器时间、部署集群等方面任务繁重。但是我听到许多客户说,他们需要六个月的时间才能获得 it 团队部署的新 Python 包,所以有些人只是将他们的个人笔记本电脑偷偷带到办公室来运行他们的工作。人们是有创造力的,他们会找到方法,但是数据科学家不应该绕过他们的 IT 部门来完成他们的工作。
这里的最后一个大挑战是,如果数据科学家在他们可以使用的工具方面受到基础设施或 IT 要求的限制,那么他们将把他们的研究、实验和结果框定在软件框架内,这给可以带来最大进步的创造性思维类型增加了一个人为的限制。就像他们说的,如果你只有一把锤子,所有的东西看起来都像钉子。
解决方案是扩展您的工具集,构建一个沙箱,您可以在其中快速尝试多种方法,这样您只需为最终部署寻求 IT 帮助。如果调配新工具花费太多时间,it 障碍将限制结果、创造力,并排除可能提供更好解决方案的选项。没有更好的软件工具和新框架,数据科学家不得不选择权宜之计而不是洞察力。
当研究人员有一个定义良好的沙箱(或 MLOps 平台 )时,他们可以通过使尝试一种新方法比花时间在细微的改进上更有效和更便宜来最小化沉没成本。他们可以尝试四种不同的方法,其中一种可能会产生更显著的性能提升,而不是花费一个月的时间来调整超参数以获得 0.25%的改善。
敏捷开发、迭代编程、最小可行产品——这就是今天软件的制作方式,也是聪明的企业的工作方式。这都是关于快速原型,迭代和快速失败。但对于大多数数据科学家来说,他们更担心 IT 没收他们的笔记本电脑,而不是他们如何利用更好的工具做更多的事情。
有了合适的平台,研究人员将有比笔记本电脑更好的选择,他们将有办法旋转集群,部署多个模型,并利用 GPU 加速。它会知道开发人员有他们自己的安全的沙箱,并且受到管理。我不能强调更多的需要——55%的数据科学家向 Kaggle 报告说,他们在 Kaggle 的《机器学习和数据科学的状态 2021 报告中没有企业机器学习工具。没有更多的结构,我们只能凭感觉飞行。
为什么没有更多的公司采取更结构化的方法?有几个很好的理由,主要集中在遗留和治理问题上。
- 银行、保险和医疗保健等受到严格监管的行业担心,部署不完美的东西会给监管机构带来问题。但是在部署之前进行试验的时间很长,并且在过程结束时花时间对有效的模型进行认证比对每个更新进行认证更有意义。
- 沉没成本理论导致公司坚持使用他们拥有的旧工具,并继续追求同样的方式来完成工作。但是这并没有给数据科学家自由去迅速放弃一种方法,并使用最新的语言。
- 确保您所采用的平台将允许科学家在他们自己的时间(而不是他们自己的笔记本电脑)部署测试项目。他们需要能够启动集群、弃用集群、回滚到早期版本,所有这一切都在一个能够解决 IT 问题的治理环境中进行。
- 不要让完美成为进步的敌人——确保你的利益相关者、你的团队领导和业务主管理解迭代开发是如何工作的。他们需要明白,一波又一波的改进结果比等待一年的完美模型要好。因为到明年,那个模型,甚至那个语言,可能都不相关了。
通过利用支持快速实验的工作台,数据科学团队可以更快地交付更好的结果,因为他们能够更快地失败并找到更好的途径。
MLOps 平台的一些潜在优势包括:
- 改进对最新工具的访问——不仅能够使用最新的工具,还可以自由地为每个项目使用正确的工具,从而更快地交付有意义的结果。
- 改善招聘——数据科学家热爱自由和创新,不想在研究中受到阻碍。如果一家公司想要吸引最优秀的人才,求职者需要知道他们可以使用最新的工具,在通往成功的道路上可以自由地犯错误。
- 改进的治理——数据科学家确实希望有一个安全网来捕捉这些失败的实验,并需要能够追溯代码更改和不同的包版本,以便通过更容易地跟踪路径来消除快速失败的风险。但是今天大多数团队做不到这一点,所以他们需要更好的治理方式。
- 更好的结果——除了使用最新的软件找到更独特的解决方案之外,更快的失败也使得在以前的工作基础上创建新的项目变得更容易,因为实验和结果会被存储起来,供将来搜索。
如今身处数据科学领域真的很令人兴奋——我们看到这一学科的价值得到了世界各地公司的认可,数据科学团队比以往任何时候都更加重要。但是,如果公司可以创建一个数据科学基础设施,支持团队更快地失败并获得更好的结果,他们就可以建立一个世界级的数据科学组织。他们的团队将提供最相关的结果。他们的数据科学家将能够使用领先的技术。公司可以鼓励创新,同时保持治理。
我认为这些都是重要的好处,也是推进数据科学的下一步,可以通过更快地失败来实现。
*本文由 TDS 原创并发布。
数据科学如何改变金融业
原文:https://www.dominodatalab.com/blog/how-data-science-is-transforming-the-finance-industry
金融服务公司一直是数据科学的早期热心采纳者,并在此后为推动该学科的艺术和科学走向前沿做出了巨大贡献。
保险、银行和投资公司都从数百甚至数千个数据点中获取大量数据,以构建旨在实现最大增长和最小风险的模型。因此,在过去十年中,数据科学工具、技术和流程出现了爆炸式增长。
在 Domino,我们很自豪能够通过与世界上许多顶级金融机构合作,在推动数据科学发展方面发挥自己的作用,如 Moody's Analytics、BNP Paribas Cardif、好事达、S&P 全球和劳埃德银行集团。因此,我们有机会亲眼目睹这些公司开发的最佳实践。
这些公司和金融服务行业的其他公司正在使用机器学习、人工智能和机器人流程自动化来打破运营现状,创造竞争优势。为了帮助您更好地理解它们的影响,让我们看看这些新工具和技术是如何使用的,以及在实施过程中要注意的挑战。
机器学习
描述性和预测性分析在金融服务领域有着悠久的成功历史。它们帮助组织了解信贷客户的潜在风险,评估现有资产的表现,或通过合并和收购帮助模拟新资产的潜力。
金融服务所使用的基础数据集呈指数级增长,这意味着在许多情况下,基于回归的风险模型不再强大到足以提供最高级别的准确性。这导致了对机器学习技术的大量投资,这些技术可以使机构能够跨多元和大容量数据源工作。
然而,许多组织很难看到他们的投资回报,因为在生产中部署有意义的模型存在挑战,或者无法更改底层业务流程以支持模型部署后的采用。寻求利用机器学习的主要挑战之一是能够跟踪模型的完整发展历史,并对预测的原因和方式以及内容保持透明。
另一个挑战是需要专业数据科学家和新系统的专业能力,以使机器学习任务有效运行。向 GPU 和 APU 处理技术的转移意味着许多企业无法跟上其数据科学团队的需求,他们需要自由探索和试验这些新技术。
为了成功部署机器学习模型,机构需要将数据科学领域的专业知识和高水平的能力与一个平台相结合,该平台可以更容易地解释和描述模型是如何构建的,使用了哪些数据,以及为什么算法会做出任何给定的决定。
机器人过程自动化
机器人流程自动化(RPA)技术使企业能够自动化许多原本需要人工干预的手动和琐碎流程。对于金融服务组织来说,RPA 通过验证是否输入了所有标准和关键信息,降低了处理文档的成本,同时自动化了资产负债表上支出和收入的编码过程。
自然语言处理(NLP)能力的提高意味着机器能够阅读和解释文档中甚至是转录的电话中的单词的意思。随着决策的改进,这意味着 RPA 比以往任何时候都更有能力自动化某些人工智能任务。在成功的实施中,RPA 降低了数据输入的失败率,降低了处理文档和贷款申请的管理费用,并提高了客户记录的完整性。
RPA 的一个明显风险是,它变成了掩盖破碎的流程或系统集成的绷带。当法规和法规遵从性要求更新流程和系统时,需要正确识别自动化按预期工作的人工流程与使用 RPA 作为框架来避免正确的系统集成或修复底层业务流程之间的差异,这可能会导致巨大的成本。
通过关注清晰的端到端业务流程映射,您可以确保任何 RPA 活动都不会用于解决中断的流程中的问题或底层系统集成和软件问题。这有助于您的企业取得更好的总体成果,同时降低潜在的未来风险。
人工智能
数字助理、聊天机器人和次优行动系统的兴起是金融机构内部人工智能(AI)用例最常见的例子。人工智能最好被描述为决策系统的组合,如机器学习、过程自动化技术和新的数字接口。当两者结合起来时,它们为顺序任务的完全自动化提供了潜力,否则这些任务将需要人工干预。
通过使用人工智能应用程序,在消费者家中为他们提供完整的银行柜员式体验的潜力令人瞩目。它允许消费者即时访问他们需要的信息和服务,同时降低为该客户服务的管理费用。
然而,许多解决方案在市场上被夸大了,导致部署失败。将这些系统部署到组织中可能具有挑战性和复杂性,这在很大程度上是因为需要对现有的业务流程和底层记录系统进行大量的返工。
要使人工智能解决方案有用,它必须能够代表客户行事。这通常需要微服务来做一些事情,比如开立一个新账户,从一个账户向另一个账户转账,或者根据命令提供费用汇总。在许多情况下,企业在表现不佳的遗留系统和流程之上放置了一个看起来很智能的数字前端,期待一个银弹解决方案。正如任何曾经陷入聊天机器人无休止循环的人可以告诉你的那样,这可能会导致令人沮丧的客户体验——这正是你最初试图解决的问题。
把所有的放在一起
这些新技术的颠覆性潜力是毋庸置疑的。能够提供更好、更具吸引力的客户体验,能够即时评估潜在贷款候选人的全部风险状况,或者能够自动处理大量交易中涉及的许多日常任务,这些都可以为金融服务运营带来显著的底线收益。
但是,管理这些新数字资产的开发需要一种新的方法来确保它们是透明的、可解释的和可复制的。显然需要一个平台作为整个开发过程的记录系统。一个平台应该为专家提供一个共同的地方来协作、开发和部署他们的系统到生产中。一个平台也可以给利益相关者一个地方来寻求这些系统的底层行为是如何运作的,以及如何寻求关于系统已经做出决策的个别案例的更多信息。
需要明确定义企业利用这些技术的先决条件,这对于成功的部署至关重要。这包括确定有才华的专业人员的正确组合,找到正确的平台来实现有效和高效的运营,并将变革管理嵌入到组织的原则中,以确保采用这些新的数字资产。正如好事达的首席数据和分析官 Eric Huls 所说,
“我们正在将基于事实的决策融入组织结构,不仅要改善我们的运营方式,还要改变行业本身。
数据科学家如何避免三种常见的协作挑战
对于绝大多数数据科学团队来说,仅有数学和编码能力是不够的。除非你在做一个深奥的学术项目,否则如果你不能与最终会使用你的产品的同事合作,你的技能将会浪费。最大的挑战通常出现在数据科学工作流程的开始和结束阶段:理解您正在解决的问题,并确保结果得到应用。
在今年早些时候举行的第一届年度Rev 峰会上,Domino 邀请了三位数据科学领导者分享他们关于改善协作的建议,以确保您团队的辛勤工作产生影响,无论是在小型初创公司还是大型公司。以下是他们的建议,通过升级工具、流程和组织结构来避免三种最常见的协作挑战:
你重新发明了轮子
也许当一个关键团队成员离开时,您不得不从头开始,没有留下他们如何存储数据或构建模型的记录。也许你在一个项目上花了几个星期,却发现一个同事也在做类似的事情。或者你发现自己一遍又一遍地重写相同的功能。创建机构记忆是数据科学团队最常见的挑战之一,尤其是当他们快速移动或面临高流动率时。
Wellio 副总裁兼数据科学主管 Sivan Aldor-Noiman 表示,拥有正确的工具是确保知识不会丢失的关键,Wellio 是一家将人工智能应用于营养的初创公司。她说,即使是小公司也应该使用维基或 Python 笔记本来保存记忆。奥尔多-诺伊曼说,在更大的组织中,像 Domino Data lab 这样的工具对于确保模型的可重复性而言至关重要。“我们分享信息、记录和复制信息的过程应该变得更容易,”她说。“如果您的组织不这么认为,那么您的组织就没有使用最新的技术。”
S&P 全球数据科学副总监 Patrick Harrison 建议,另一种节省时间和避免重复的方法是为常用功能创建内部库。“第一次或第二次做某事时,多花一点时间和精力来建立你自己的小软件库,”他说。“这需要一些训练,但很值得。”
工具本身不足以加强记录保存;领导人还需要澄清这是一个优先事项。Airbnb 数据科学主管埃琳娜格雷瓦尔表示:“我见过一些非常反对文档化的人……他们会说,‘这太花时间了,而且很官僚。我们把它放在我们的绩效评估里。"
你想出了一个很棒的答案…对一个错误的问题
对于数据科学团队来说,没有什么比发现一个出色的解决方案,却发现它无法解决手头的问题更令人沮丧的了。帮助利益相关者达成共识的一个技巧是“五个为什么”“你以一句话开始,(比如)AirBnB 用户需要能够分期付款’,然后问‘为什么?’“一次又一次地去真正理解你试图解决的问题的根源,”格雷瓦尔说。
在大型组织中,Harrison 建议使用“矩阵方法”,即数据科学家向单一领导汇报(在 S&P 全球,就是他),但围绕一个项目或产品与领域专家和业务利益相关者组成小组。即使没有正在进行的项目,他也鼓励他的团队给其他部门的人打电话,了解他们的工作和数据。
在奥尔多-诺伊曼这样的小公司,她建议领导在周会上强调业务优先事项,并在面试中关注潜在雇员的沟通技巧。另一个想法是建立一个“模型策略团队”,其角色是在让数据科学家参与项目之前,了解一个给定的问题是否值得解决。
你和其他利益相关者说着不同的语言
理解上的差距也有另一面:其他部门经常难以理解数据科学家做什么,这使得他们很难找出应该一起解决什么项目。在 S&P 全球,Harrison 和他的团队敦促全公司的同事参加关于数据科学的开放式在线课程,并领导引导式讨论会议;两周内有 100 人报名。该公司还创建了一个关于人工智能和机器学习(ML)的内部课程,有 1 万名员工参加了该课程。“这真的为许多人播下了种子,所以他们现在知道这是什么,并知道这是该组织的战略重点,”他说。
AirBnB 甚至创建了自己的数据大学,通过营销视频、海报和赠品在内部推广。全公司有 1000 多人参加了从实验到 ML 的各种课程。
奥尔多-诺伊曼说,除了正规教育,仅仅给人们以自己的方式探索数据和可视化的机会是有效的。“如果你有合适的工具,它们让事情变得简单,人们就不再害怕数据科学,”她说。“你会惊讶地发现,人们有多么渴望了解。”
数据科学家如何充分利用强制在家工作政策
在 Domino,我们有幸与领先全球公司的许多令人惊叹的数据科学家合作。因此,我们了解了数据科学家在家工作的最佳实践。本着帮助您的组织适应新冠肺炎疫情的精神,我们希望与您分享我们的一些经验。
许多政府和公司正在推行在家工作的政策,以保护他们的员工,并“拉平”新冠肺炎的曲线。对于许多数据科学家来说,这可能是他们第一次处理完全远程的工作环境,这带来了许多问题:
- 面对面的接触对生产力和文化有多重要?
- 完全远程工作团队将如何影响生产力?
- 同事们能够像面对面一样高效地协作和解决问题吗?
- 团队如何保持动力继续为他们的组织交付成果?
- 您的内部系统的设置方式是否支持在家办公?
在与世界领先的金融、医疗保健和生命科学公司的合作中,我们从高绩效团队中收集了最佳实践,使他们能够承受当前疫情带来的挑战。这些团队经常依靠 Domino 等数据科学平台来支持他们不断增长的数据科学实践,特别关注协作、可再现性和提高个人研究人员的生产力——无论在哪里。
这里有一些提示和技巧,可以帮助你的团队在今年春天远程工作时最大限度地提高工作效率。请考虑以下情况:
连通性
- 确保你家里有稳定的高速互联网,可以接入公司的 VPN。
规划
- 在家工作时,自我激励可能会有点困难,所以用你想用的任何方法来设定你的一天会让你按计划进行。尽量减少分心,建立一个舒适的工作站。每隔几个小时就起来走走。
- 确保您有正确的数据和环境设置用于您的研究实验。
- 不要害怕问问题。
合作
-
尽可能经常地与同事分享你的工作,而不仅仅是代码。不要把这些结果写在一个难以理解的脚本或笔记本上,只给你看。花额外的时间清理分析;添加一些标题和注释,并将结果发送给同事进行反馈和检查。”
-
考虑日常单口相声。就“过去 24 小时我做了什么,接下来 24 小时我有什么计划,我遇到了什么阻碍或问题?”进行一次快速的“圆桌会议”。这些单口相声应该是快速的,并不意味着深入问题,但可以帮助取代你习惯于在办公室进行的快速日常互动,以此了解你的同事正在做什么,以及哪里有进一步合作的机会。
-
尽早并经常寻求反馈。偏远意味着你与同事和利益相关者见面的时间和机会更少。寻找其他互动方式。你总是需要知道什么对企业来说是最重要的。
-
使用版本控制系统。留下评论,把其他人拉进讨论。
-
在电话会议期间,打开您的视频并共享屏幕。
提示:远程视频通常需要与面对面不同的说话风格。你必须多注入一点能量,多停顿,多提问,以保证参与度。在电话会议上,人们很容易一心多用或者分心。
-
当共享工件时,使用超链接。不要让你的同事疲于应付通过电子邮件发送 Jupyter 笔记本或简历的过程。相反,发送一个指向 Github repo、Domino project 或 Google Drive 文档的链接。
跟踪
- 使用一个系统来跟踪你和你的团队的进展。工作流管理工具,如 Trello、吉拉、Asana 和 Domino 的数据科学平台——特别是 Domino 为数据科学领导者(如 Assets Manager 和 Activity Feed)提供的项目管理功能——可以帮助您了解其他人正在做什么以及他们在哪里被阻止了。尽可能帮助队友移除障碍物,保持参与和联系。
云中的生产力
- 与您的 IT 和 DevOps 团队合作找出最佳方式,以便在您远程办公时随时随地访问数据并进行计算。
- 尝试将繁重的数据科学工作从本地转移到基于云的系统。
- 接受这样一个事实,如果没有和同事在办公室一样的日常生活节奏,你可能会对项目失去兴趣。然后,当你的团队以比平时更分散的方式工作时,想办法回到正轨。
- 即使你们不在同一地点,也不要忘记你们仍然是团队的一员。如果你需要帮助,在 Slack 或其他论坛上举起你的虚拟手。
- 如上所述,使用工作流管理工具或数据科学平台与他人分享您的工作以供审查。
- 灵活适应远程工作的动态特性。当你有空闲时间的时候,如果其他同事需要休息的话,就接手他们负责的工作。
- 解决现实问题。
- 从中了解什么可行,什么不可行。
- 调整工作并考虑模型漂移。
领导技巧
- 优先化比以往任何时候都更重要;让团队专注于重要的事情,并尽早、经常地与他们沟通。
- 在所有情况下都设定明确的期望,尤其是在远程工作环境中;现在是一个很好的时间来看看团队如何跟踪自己-重新建立你的 okr 并感觉检查它们。
- 随时可用:快速响应团队请求,帮助消除许多远程员工在沟通中感觉到的“滞后”。
- 请耐心等待:许多组织可能没有足够的设备来处理完全远程的工作环境,这意味着您的数据科学家可能不会像他们希望的那样高效。帮助他们解决连接和系统问题,并寻找让他们更容易高效工作的方法。
- 保持精力充沛:你有多少次看到有人在视频会议中打哈欠,或者注意到精力水平下降?站起来,就像你面对观众一样;你的参与和能量会导致他们的参与和能量。
- 请注意:用文字写的东西通常不能传达你想要表达的语气。当你觉得某个观点可能被误解时,避免打电子邮件乒乓球,经常使用视频会议。
- 人性化:对许多人来说,远程工作通常意味着比在办公室工作更长的时间。此外,鉴于新冠肺炎如此迅速地提出这个问题,许多人仍然在考虑如何在学校关闭的情况下高效地处理孩子的问题。为你的团队设定明确的期望和目标,但是让他们在过渡期间以适合他们个人情况的方式实现。
文化
- 关注人际关系:利用你的聊天和视频会议系统来主持午餐和学习会议,或者只是一起吃午餐,继续发展强大的团队纽带。
- 主持定期的日常聊天,纯粹是为了团队之间的聊天和非正式谈话。
- 增加其他沟通的节奏,特别是在项目团队中,以保持高积极性,并强调以团队为基础的方法来解决问题。
利益相关者参与
- 成功的关键是关键业务部门利益相关方和数据科学团队之间的沟通。强调与利益相关者的持续联系,并经常分享信息。
- 为他们检查项目进展提供清晰的途径;像吉拉这样的系统是有用的,但是对于商业利益相关者来说可能是令人畏惧的。您需要为他们翻译,还是专门为涉众创建视图?
- 把他们带进团队;当主持会议甚至是文化社交活动时,邀请你的利益相关者一起参加;他们也可能很冷漠,可能欢迎同志情谊。
冲洗并重复
这些只是我们看到的许多客户从其数据科学投资中获得最大价值的一些方式,即使在远程工作时也是如此。我们在不断学习和建立自己的最佳实践库。您可以为远程工作的数据科学团队推荐哪些其他最佳实践?请在此评论其他想法或问题。
Domino 数据科学平台是专门构建的,其核心是服务于这些最佳实践,最终目标是帮助复杂的团队加速研究和创新。试试 Domino 的数据科学平台,看看它是否能帮助你的团队。
用户故事:Domino 如何帮助数据科学家创建“独角兽级别的可交付成果”
我们要求用户告诉我们他们如何使用 Domino 的故事。这是我们从 stock upT3 的数据科学家劳拉·洛伦茨那里听到的。
我最近读了《数据科学家的 22 项技能》,我记得我当时想,这种令人难以置信的多样化技能一定只存在于神话中的独角兽身上,而不是生活和工作在现实中的人。然而,我的 JIRA 董事会遇到的许多任务都需要这样一只神话中的独角兽,尽管这可能是不可能的。
由于我不是这样的独角兽,我发现有必要利用服务和框架来帮助我完成繁重的工作。Domino 提供了越来越多的工具,数据科学家需要这些工具来执行跨学科数据问题的解决方案。我发现非常有用的一个工具是启动器,我将根据自己的经验用两个例子来说明它。
自助式按需报告生成
我在 Stockup 的工作之一是为内部报告或外部客户提供间歇性的数据提取和汇总统计。这些报告通常是一次性请求。然而,偶尔我会收到下游的相关请求,要求向新的部门或客户提供更新或类似的报告。举个例子,我正在为完成一个大的 web 应用进行紧张的冲刺,但是对数据拉取的定期更新的需求因为更紧急而打断了它。这种干扰和分心会对生产力产生毁灭性的影响。
Django 已经是一个很好的框架,可以快速整合基于 Python 的 web 应用。我最初考虑使用 Django 为涉众创建一个接口,以便在我们更大的 Django 项目中参数改变时,他们自己运行报告脚本。然而,我们的 sprint 中的工作在接下来的两周内不会部署,我需要定义一个表单,在一个模板中显示它,并将我的脚本移动到一个视图中,以便他们与之交互
Domino 中的启动器特性为我解决了所有这些问题。我所要做的就是将我未修改的代码上传到我的 Domino 项目,并构建一个指向我的脚本的启动器,暴露出我想要的参数。Domino 处理所有的前端开发(我将内置在 Django 中),在它们的服务器上进行作业排队,并通过电子邮件发送结果。启动器也有一个我的利益相关者喜欢的无缝界面。
计算密集型报告
启动器的另一个好处是能够改变运行脚本的底层硬件。我收到了另一个请求,要求我为一个计算量特别大的报告构建一个自助报告工具。与第一种情况类似,我可以几乎不加修改地插入我的脚本,指定这个新的启动器应该使用高功率硬件(32 个内核,60GB 的 RAM),我就一切就绪了。
Domino 将所有的 web 开发从为非技术利益相关者部署简单的接口中解放出来,因为您不希望不断地重复运行和交付脚本。您可以快速将您的一次性脚本转换为 web 表单,快速生产您的数据,以便非技术利益相关者可以自己操作—并且您可以比部署自己的 web 框架更快地交付这些内容。同样,您可以改变您的硬件层,并利用比您内部可能访问的更强大的服务器。Launchers 和 Domino 的其他数据科学工具可以将神话般的项目变成实际可以完成的东西,通常简单而快速。
企业 MLOps 如何支持扩展数据科学
原文:https://www.dominodatalab.com/blog/how-enterprise-mlops-supports-scaling-data-science
对于投资数据科学的公司来说,赌注从未如此之高。根据 New Vantage Partners (NVP)最近的一项调查,62%的公司已经在大数据和人工智能方面投资了超过 5000 万美元,其中 17%的公司投资超过 5 亿美元。期望值与投资水平一样高,来自 Data IQ 的一项调查显示,四分之一的公司预计数据科学将增加 11%或更多的收入。
虽然大多数公司在数据科学方面取得了一些成功,但扩展并不容易,也不是因为技术原因。根据 NVP 的数据,由于企业文化,92%的受访者在扩展数据科学方面面临重大挑战,特别是与数据科学相关的人员、流程、组织和变革管理。
这是一个重大问题,因为在埃森哲最近的一项调查中,75%的受访高管认为,如果他们不能在未来五年内成功扩展数据科学,他们的公司很可能会倒闭。
扩展数据科学的挑战
显然,扩展数据科学至关重要。如果做得不成功,成本和风险都会增加。重要的数据科学和 IT 资源被困在重复的手动任务中,时间线拉长,新的业务机会来来去去都没有被发现。
正如早期的每一项新兴业务能力一样,数据科学是有机发展的。虽然这带来了令人兴奋的发现和无限的机会,但也带来了三大挑战:复杂的模型操作流程、知识孤岛以及工具和基础设施的蛮荒。
复杂的过程
数据科学不同领域的有机增长为将模型从数据科学生命周期(DSLC)的一个阶段转移到另一个阶段创造了复杂、不一致的程序。当将测试过的模型从开发转移到部署时,这一点尤其明显。当数据科学家与开发人员和基础设施工程师一起临时部署模型时,模型基本上被束之高阁,导致了重大且代价高昂的延迟。
这种治理和标准化的缺乏会在每个项目中产生技术债务,增加风险,并且无法创建可重复的——并且可测量的——商业模型。
知识孤岛
有机增长也会导致孤岛。每个团队都处理项目,然后进入下一个项目。获得的知识通常不会被保留或分享以使更广泛的组织受益。事实上,如果一个团队成员离开,它经常会丢失。协作是有限的,团队经常从零开始或者重复以前做过的工作,仅仅因为他们没有办法发现以前的结果
这也限制了项目顺利通过 DSLC 的能力。每个团队成员都必须了解所做工作的最新情况,这非常耗时,而且会限制工作效率。如果项目搁置了一段时间,关于它们是如何开发的知识就会消失。
工具和基础设施的“蛮荒西部”
当数据科学有机增长时,它不可避免地导致在定制的笔记本电脑或本地维护的基础设施上使用混乱的工具组合。这造成了很多摩擦,增加了成本,降低了生产率和协作。它还产生了各种各样的技术问题,增加了 It 支持需求,并为各种各样的安全威胁打开了大门。
企业 MLOps 在扩展数据科学中的作用
为了正确扩展数据科学,公司需要一种整体方法,允许他们大规模开发、部署、监控和管理其模型,所有这些都由数据科学的记录系统提供支持。我们将这种方法称为企业 MLOps。它连接了整个 DSLC 的人员、流程和技术,以加速和扩展组织内的数据科学。
MLOps 作为一种实践并不新鲜。但是组织发现在企业级实现 mlop 比仅仅为几个模型或单个团队实现 mlop 要复杂得多。在整个企业中快速、安全、成功地扩展数据科学和 MLOps 最佳实践需要一个涵盖整个数据科学生命周期的广泛版本,并满足各个团队现在和未来的要求。
为了成功实施企业 MLOps,组织需要能够为所有数据科学工件提供记录系统、实现流程标准化和自动化、提供协作和管理项目的简便方法,并使数据科学家能够轻松访问他们开展工作所需的工具和计算的支持技术。这就是 Domino 的企业 MLOps 平台所提供的。
筒仓被拆除
打破孤岛是扩展数据科学的关键。这就是为什么 Domino work bench 提供了一个基于笔记本的环境,数据科学家可以在这里协作、共享知识并在一个地方执行所有的模型研究和开发。这意味着一个数据科学家更喜欢使用哪种特定工具并不重要,他们都可以无缝地协同工作。知识得以保留,并以此为基础推动创新。
实践和模式是标准化的
当每个项目都利用相同的模式和实践时,不管它是如何构建的,也不管它将部署在哪里,它都消除了摩擦和来自数据科学的支持负担。
Domino 的 Enterprise MLOps 平台提供了易于导航的工具,DSLC 的每个团队成员都可以使用这些工具来构建、部署、监控和管理模型。安全和管理集中化,释放了 IT 资源。自动化提高了生产率,减少了技术债务。例如,可以在开始时建立监控阈值,以便自动分析模型的性能和数据漂移。
工具和基础设施是集中供应的
数据科学家不应该每次需要新工具或需要访问 GPU 等基础架构资源时都向 DevOps 提交申请。Domino 让团队中的每个人都可以访问他们需要的工具,并能够按需扩展资源。这不仅加快了研究速度,还通过最大限度地减轻 it 支持负担来提高整体生产力。此外,由于所有可用的工具都经过预先批准并由 IT 部门管理,这大大降低了风险和安全顾虑,同时不会抑制创新。
Domino 的企业级功能是按比例构建的
正如一个蓬勃发展的公司在扩大其销售团队的规模和服务的客户数量时需要扩展其 CRM 一样,一个蓬勃发展的模型驱动的组织需要能够根据需要扩展其工具和资源。使用 Domino,数据科学团队可以根据需要增加其平台的大小和范围,以适应:
- 增加团队的规模
- 向组织中添加多个团队
- 不断变化的治理或行业合规性要求
- 促进审计要求
- 不断变化的安全要求
- 加强与关键利益相关方的合作
通过在整个 DSLC 协调这些类型的变化,而不是一次一个阶段,消除了使用不同系列工具的需要——或者从一个团队向另一个团队口头传递重要信息——以及这种变通办法总是带来的所有额外的不一致和瓶颈。
采用企业 MLOps 平台
数百万美元危在旦夕,公司的未来岌岌可危,成为一个模型驱动的组织将是成功的关键。尽早采用企业 MLOps 来扩展数据科学将降低成本并提高效率。它会让你变得更有竞争力,更有创新性,让你在新的机会出现时就抓住它,而不是关注错过的最后期限。
David Weedmark 是一位出版作家,曾担任过项目经理、软件开发人员和网络安全顾问。
企业 MLOps 如何加速数据科学:4 个真实使用案例
今天的企业正在大力投资数据科学——据 IDC预测,到 2024 年,软件、硬件和服务的支出将突破 5000 亿美元大关。具有机器学习(ML)和人工智能(AI)技术的数据科学模型已经证明了它们在打造新的收入流和颠覆整个行业方面的价值。对于一个模型驱动的企业来说,来自这种用例的新收入可以从几亿到几十亿美元不等。在成功的公司,领导者已经建立了一个润滑良好的分析飞轮,以创造稳定的模型流,可以利用这一新的淘金热。
在激烈的竞争压力下,从业务领导者的角度来看,推动扩展数据科学用例是有意义的。但是,如果您感到压力,值得探索企业 MLOps 原则如何通过加快数据科学生命周期的每个阶段来实现更好的模型以满足您公司的需求。
借助企业 MLOps 加速数据科学生命周期:4 个使用案例
在我们与企业 MLOps 项目的广泛合作中,我们注意到四种用例构成了企业需要加速的最常见功能。本博客定义了企业 MLOps,并描述了这四个企业 MLOps 使用案例,这些案例阐释了对数据科学生命周期的四个阶段至关重要的关键原则:
- 管理数据科学项目
- 为业务用例开发模型
- 为生产部署模型
- 监控模型组合的持续性能
让我们看一些真实的 MLOps 示例,这些示例说明了企业 MLOps 在数据科学生命周期的每个阶段可能带来的收益。
什么是企业 MLOps?它如何帮助扩展数据科学?
Domino Data Lab 与许多公司合作——跨越许多行业,包括金融和保险——建立了大规模创收的数据科学机器。它们的一个共同点是采用整体方法,在数据科学生命周期的所有阶段(包括研发的前端阶段)寻找规模效率。我们将这种方法称为 企业 MLOps :一套技术和最佳实践,可在多元化企业中大规模简化数据科学模型的管理、开发、部署和监控。企业 MLOps 是旧术语 MLOps 的扩展,它指的是对模型的后端部署和维护的更狭隘的关注。
企业 MLOps 的 4 个使用案例
在 数据科学生命周期 的每个阶段都可以找到企业 MLOps 的原则。总共有 19 条原则——对于这个博客来说太多了!你可以阅读我们关于这个主题的白皮书了解详情。现在,让我们在白皮书中的四个 MLOps 用例中说明使用这些原则的结果,每个用例代表数据科学生命周期的一个阶段。
用例 1:SCOR 如何通过协作更好地管理模型
世界第四大再保险公司 SCOR 帮助客户控制和管理风险——自然风险、气候风险、健康风险、地缘政治风险、网络风险等等。他们帮助人们在逆境中重建家园。
为了提高管理阶段的效率,SCOR 专注于可以从一个项目重用到另一个项目的协作最佳实践,并在创建应用程序或 API 的早期阶段引入了系统方法。SCOR 利用新技术来确保企业实现他们设想的那种知识共享。
SCOR 数据科学主管 Antoine Ly 描述了这一努力及其结果。
“为了共享知识、实践和代码,我们必须共享工具。为此,我们实施了一个多云计算战略和平台,”Ly 说。
“例如,我们发起了一项仪表板倡议,”他说。“我们正在扩展一些现有的仪表板,以监控数据和控制一些不同的模型,以便其他市场可以利用它们。我们已经向欧洲和美国市场推出了一款在澳大利亚开发的产品。我们还利用该平台扩展了在欧洲开发的 API 的使用,使其在全球范围内可用。”
用例 MLOps 如何帮助一家财富 500 强全球金融服务领导者更快地开发模型
建模是数据科学工作的核心职能。开发需要使用工具和基础设施,如强大的计算资源、高价值和敏感的数据,以及最新的开源工具和软件包,以支持各种实验。使用这些资源的障碍正在减缓一家财富 500 强全球金融服务领导者在整个企业中扩展其数据科学实践的努力。
在这个 MLOps 示例中,该公司的卓越分析中心优先考虑减少模型开发的总体时间。该公司采用了企业 MLOps 平台,以简化分布在不同地理位置的团队对模型的协作开发。随着企业 MLOps 的采用,这家金融服务公司在不影响 IT 安全要求的情况下实现了更快的大规模开发。
结果呢?
这家金融服务公司的一名高级 IT 架构师表示:“企业 MLOps 帮助我们以协作的方式将分散的团队聚集在一起,以便我们能够在整个公司范围内大规模实施数据科学。
用例 3:企业 MLOps 帮助 Moody's Analytics 部署生产机器基于学习的风险模型
Moody's Analytics 是一家总部位于纽约的公司,它提供专业知识和工具,如数据、模型、软件和专业服务,以帮助客户高效增长和管理金融风险。“改进或更换模型的成本太高,”银行运营部门总经理雅各布·格罗塔(Jacob Grotta)说。在竞争激烈的行业中,该公司需要一种标准化的方式来部署模型。
通过将企业 MLOps 的技术和原则用于模型部署,数据科学家能够开发一个 API,并在几天内与客户共享以进行 beta 测试。在这个 MLOps 示例中,他们使用反馈来进行调整,并几乎立即重新部署模型,最终将其嵌入到产品发布中。Grotta 说:“这个过程只需几个月,而不是一年,而且部署成本也低得多。”。这是 6 倍的性能加速。
Moody's Analytics 现在可以高效地提供定制的风险和其他分析模型,帮助运营大规模企业,并根据客户偏好经济高效地部署它们,无论是在本地、在云中还是作为 SaaS。银行的数据科学家现在可以自行部署新模型,从而节省时间并增加业务价值。
用例 4:大型欧洲保险公司 Topdanmark 使用 MLOps 来监控和检测数据和模型漂移
提高其模型监控能力是 Topdanmark 转向企业 MLOps 的一个动机。Topdanmark 是一家总部位于丹麦的大型欧洲保险公司。它将数据科学融入其运营中,为消费者提供更好、更快的保险体验。
该公司采用了企业 MLOps 技术和实践,以实时了解模型的表现,并在模型投入生产后检测数据和模型漂移。
“数据漂移会对预测产生关键影响,最终影响我们的业务,”该公司机器学习负责人斯蒂格·彼得森(Stig Pedersen)说。他指出,他们的新方法“节省了我们以前花费在维护和调查上的大量时间;使我们能够实时监控模型性能,并将其与我们的预期进行比较。”在一个案例中,该团队能够自动检测漂移,而以前需要三个月才能手动识别。
在您的组织中开始使用企业 MLOps:“分析飞轮”的使用案例
在这些 MLOps 示例中,我们看到了企业 MLOps 如何让模型驱动的业务为分析飞轮提供动力,从而让领导者能够积极果断地采取行动,利用宝贵的见解并收获不断增长的集体智慧流。如果您的组织渴望获得大规模数据科学研究的回报,我们邀请您阅读我们的白皮书或查看我们的 MLOps 最佳实践指南。
它详细介绍了构成数据科学生命周期四个阶段的 19 项原则。它还载有上述四个案例研究的更多背景资料。
企业 MLOps 在数据科学生命周期中的工作方式
原文:https://www.dominodatalab.com/blog/how-enterprise-mlops-works-throughout-the-data-science-lifecycle
数据科学生命周期(DLSC)被定义为一个迭代过程,从问题的提出到探索、算法分析和数据清理,再到获得可用于决策的可验证解决方案。对于创建规模模型的公司来说,企业机器学习操作(MLOps) 平台不仅需要支持企业级开发和生产,还需要遵循数据科学家使用的相同标准流程。
企业 MLOps 如何融入数据科学生命周期
数据科学生命周期可分为四个步骤或阶段:管理、开发、部署和监控。像任何生命周期一样,这些阶段都是相互依赖的。它们不仅可以在每个项目的生命周期中重复,这些阶段也可以在创建它们的组织的生命周期中从一个 ML 项目重复到另一个 ML 项目。
每个阶段完成得越有效,组织就能越快、越有效地扩展其运营。例如,有效的管理会导致更快、更有效的开发。有效的监测导致更好的管理。高效的开发会带来更成功的部署。
虽然每个新项目通常从管理阶段开始,但它通常也会在该阶段结束。
从项目中获得的信息集将被带到后续的项目中。这包括资产,如新的算法和新的数据源,以及从事这些工作的团队所吸取的经验教训。正如项目、数据和 ML 模型本身会发生变化一样,在任何企业环境中从事这些项目的个人也会发生变化。
数据科学家、分析师和 ML 工程师可能会从一个项目转到另一个项目,或者在新团队成员加入时离开组织。然而,尽管有这些变化,整个 DSLC 产生的信息需要保留,以避免重复劳动..
1.管理阶段
业务环境中的数据科学流程始于管理阶段。这是建立项目需求的地方,以便参与的每个人都清楚地了解项目需求和目标。在开始任何研究和开发之前,已经分配了角色并确定了工作优先级。
在 ML 模型被部署和监控之后,基于企业的团队应该重新访问管理阶段,以评估项目的成功或失败。成功孕育成功,从一个项目中吸取的经验教训可以应用到未来的项目中,减少未来的错误,从而提高效率。
Domino 的知识中心是企业组织所有这些关键知识的中央存储库,推动复合知识的发展。它是跟踪和管理工作的地方,以便以后可以很容易地找到它,然后根据需要重用或复制,每个阶段都有相关的注释。验证人员和审计人员可以使用知识中心来确保模型是安全和可信的,从而减少潜在的风险。
2.发展阶段
开发阶段是数据科学家基于各种不同的建模技术构建和评估模型的阶段。快速自由创新的能力是关键,因为这是研究、讨论、测试、提炼和再研究想法的地方。
工作台是 Domino 基于笔记本的环境,数据科学家可以在这里进行 R&D 和实验。耐用的工作空间使数据科学家能够自助访问他们运行、跟踪和比较实验所需的所有工具和基础设施。
由于数据科学家知道他们需要什么,Workbench 为他们提供了一个选择所需工具和资源的地方,当他们需要时,只需点击几下鼠标,而无需开发运维。这意味着他们可以独立完成以下任务:
- 同时运行并比较数百个实验的进度
- 按需扩展 CPU、GPU 和其他资源
- 访问多个工具和工作区,如 Jupyter、 RStudio 、Zeppelin、 SAS Studio
- 根据需要添加库、工具和算法
- 链接到基于 Git 的存储库,快速集成现有代码
- 轻松跟踪代码、数据、工具、包和计算环境,找到并重现过去的结果
由于 Workbench 从一个集中管理的环境中提供了所有这些特性,数据科学家可以在其组织的治理框架内灵活地使用他们需要的工具和基础设施。
3.部署阶段
当一个开发的模型被认为是成功的,它就准备好从开发阶段进入部署阶段,在那里它可以被用于生产——通常在一个业务流程中,它被用于决策制定。高效的部署需要一个健壮的平台,该平台可以使用开发中的相同工具和资源轻松发布模型。
在 Domino 的 Enterprise MLOps Enterprise platform 中,处于部署阶段的模型能够创建它们设计的业务价值。业务用户可以通过嵌入到同一基础设施中的 API 来利用该模型,该基础设施允许从现有程序、web 浏览器或作为应用程序进行访问。
Domino 平台用于模型部署的另一个重要组件是容器的使用,它允许根据需要轻松地移动和复制模型,因此相同的模型可以根据需要进行多次缩放。容器化模型的关键是 Kubernetes,这是一个开源系统,被证明是管理多个容器化模型的自动化部署的复杂需求的理想选择。
4.监控阶段
监控阶段紧跟在部署之后,因为这是组织需要确保模型按照预期执行,并且提供预期的业务价值的时候。由于企业组织往往在不同的基础设施上拥有数百个生产模型,如果没有合适的平台,同时监控所有这些模型将是一项挑战。
Domino 的模型监控提供了一个单一的平台,可以用来监控整个组织中生产的所有模型,同时自动检测任何问题,并在模型需要更新、暂停或替换时主动提醒适当的团队成员。
由于监控还需要来自业务部门的非技术用户的分析,因此 Model Ops 还允许您根据模板创建交互式应用,用于在不同的用例场景中运行推测性分析。同时,数据科学家和工程师可以使用 Model Ops 来安排性能漂移的自动检查,以及从单个用户界面快速分析和诊断漂移。
数据科学生命周期中的 MLOps
对于任何开发和部署 ML 模型的受利润驱动的组织来说,接受 DSLC 被证明是减少低效和成功扩展 ML 模型的重要组成部分。将运营与围绕 DSLC 构建的企业级 MLOps 平台相集成,可确保您组织的所有资源在多个项目中得到高效利用——从自有数据集和算法到繁忙的数据科学家和开发人员的日程安排。
如果您的公司计划成为 ML/AI 未来的一部分,并打算将一个成功的项目堆叠在另一个之上,请花几分钟时间查看我们的 MLOps 最佳实践文章或观看 Domino Enterprise MLOps 平台的演示。
哈佛的案例方法如何弥合商业和数据科学之间的差距
随着公司加大模型开发的力度,数据科学团队正全力以赴,以更好地与商业领袖联系和沟通。公司正在启动数据扫盲计划,举办数据科学市政厅,举办每月学习会议,以及其他活动,以帮助业务团队更好地了解什么是数据科学以及它可以做什么。
但是,随着公司努力在数据科学、机器学习和分析等主题上教育他们的业务领导者,一个大问题是:
他们如何最有效地帮助非技术人员“了解”数据科学?
根据哈佛大学的 Yael Grushka-Cockayne 的说法,教学的“案例方法”——哈佛近一个世纪以来的教学核心——提供了一种强有力的方法来吸引业务经理并帮助他们在业务环境中理解数据科学。Yael 是一位获奖教师,被评为数据科学领域“21 位思想领袖教授”之一。她的研究和教学活动侧重于数据科学、预测、项目管理和行为决策。
在这篇博客中,我们分享了我们与 Yael 关于 case 方法以及数据科学团队如何使用它的对话的编辑版本。
什么是案例法?
Yael Grushka-Cockayne: 案例教学法是一种以学生为主导的苏格拉底式教学体系,学生们回顾一个案例(一个关于组织如何面对特定业务问题的故事),并思考可能的解决方案以及在相同情况下他们会怎么做。
与其他教学方法不同,案例教学法没有讲课。我们向学生提出关于这个案例的尖锐问题,当他们辩论和测试可能采取的不同行动方案时,通过学生的讨论,我们学到了很多东西。哈佛在最大限度地运用案例教学法方面处于领先地位。
你为什么提倡用这种方法向管理者教授数据科学?
Yael Grushka-Cockayne: 我认为案例教学法是教授数据科学的最佳方法之一,因为你是在直接将数据科学与公司试图解决的业务问题联系起来。
学生们走进教室,热烈讨论他们认为公司应该做些什么。他们需要什么数据?有哪些模式可以解决挑战?你如何利用从分析中获得的洞察力来推动事情向前发展?
它鼓励头脑风暴和现实世界问题解决,因为参与者必须找出最佳解决方案。当参与者一起发现如何克服一个商业问题时,它变得更令人难忘,一旦他们回到办公室,他们将更容易利用这些记忆。
它为企业领导人提供了一个安全的空间来测试想法,并从房间里的同事那里了解其他观点。通常没有对错之分。解决一个问题会有不同的方法。有些错误是我们想要避免的,但是有很多解决商业问题的好方法,这些在课堂上都是受欢迎的。
这有助于他们了解他们在流程中的角色,以及他们如何为数据科学团队做出贡献并与之互动以推进工作。这包括从他们如何思考业务问题到他们在收集数据、测试假设和将模型投入生产中的角色。
最后,它帮助参与者在与其他学科合作时更好地沟通。有多少次你和一个业务人员和一个程序员在一个房间里,而他们却一事无成?有效的沟通需要一些练习和技巧,案例教学法环境鼓励更多地关注如何与他人互动、如何提问以及如何回答这些问题,以培养这些技巧。
鉴于这种非结构化的形式,您如何确保推进对话?
Yael Grushka-Cockayne: 案例教学法鼓励我们所称的四个 p,它们对解决问题的过程至关重要:
- 准备。讨论的质量取决于参与者的准备。上课前,他们必须阅读案例,运行我们分配的代码,并准备好谈论前一天晚上代码做了什么。
- 参与。学员必须准备好发表意见,认真倾听对方,并发表评论以推进讨论。参与者必须积极主动,而不是消极被动。
- 在场。房间内单人对话,所有人都参与其中。为此,我们定期拜访学生,向他们询问有关案例的问题和其他人分享的想法,以确保每个人都保持警觉。
- 专业精神。我们要求参与者不同意观点,而不是个人观点。他们应该准备好以一种容易理解和专业的方式引导每个人进行分析、辩论和论证。
那么,如果一个数据科学团队想要将案例方法整合到其教育计划中,他们该如何着手呢?
Yael Grushka-Cockayne: 数据科学团队可以通过多种方式应用这些想法:
-
Conduct a case review. I’ve been doing this for a long time, and just bringing business and data science teams together for a half-day or day-long session to go over one or more case examples can make a significant difference. Harvard has many cases that companies can draw from to help data science teams demonstrate how managers can use data science in a variety of contexts—marketing, finance, manufacturing, talent management, and so on.
这些案例回顾会议可以由内部员工或外部讲师主持。聘请外部讲师有一些好处,因为他们通常被视为不偏不倚,因此他们可以用内部人员无法做到的方式推动对话,但这不是必需的。
在哈佛,我们使用 Domino 作为协作的切入点。学生登录 Domino 平台获取他们的作业和案例。他们可以从 Domino 内部启动 Python 或 Jupyter 笔记本,使用我们提供给他们的一些初始代码。即使他们除了一个启动代码之外什么也不做,他们也会洞察到业务问题。
我们还在课堂上使用缩放,这样参与者可以在讨论案例和运行代码时共享他们的屏幕。他们通过这一过程直接看到了数据科学的动态性,以及如何利用每个人的丰富经验,获得他们自己可能无法获得的新见解。
-
一起研究一个下午的数据科学问题。邀请一位业务同事在某个下午与您一起解决一个数据科学问题。例如,让他们在您编码时与您一起工作,这样他们就可以看到分析一些基本的业务问题需要什么。虽然他们可能不需要在日常工作中编写代码,但他们确实需要熟悉代码,并能够将人的方面(例如,员工、客户或合作伙伴的需求)与机器推荐的内容结合起来。我发现,提供一点点编程的机会对缩小差距大有帮助。
-
创建在线社区技术和业务人员可以在这里提问和分享想法。在哈佛,我们鼓励项目参与者通过 Slack 和 LinkedIn 相互分享和学习。我发现这对学生来说是一次转变的经历。
除了内部努力,管理者应该追求什么类型的培训?
Yael Grushka-Cockayne:
- 当前和新兴技术。例如,参与者学习基础定量分析(如概率、统计推断和预测以及线性模型),以及编程数据科学系统(使用 SQL、R、Python)、基于云的解决方案和下一代人工智能技术的基础知识,所有这些都是在解决业务挑战的背景下进行的。
- 数据科学的运营应用。我们开设了专注于数据驱动型营销、运营、供应链管理和人员分析的课程,以便企业领导能够了解如何利用这些技术来改进分析供应链流程、帮助人力资源团队进行与员工相关的讨论以及管理员工生命周期等。
- 领导力。我们希望确保领导者能够在业务的最高层面整合这些概念,因此我们还提供如何大规模推动创新和组织变革的课程。例如,这包括为他们的数字化转型制定成功的战略,创建动态能力和组织架构,当然,还包括管理这些创新带来的所有变化。
了解更多信息
观看 Yael 于 2019 年 11 月 7 日在波士顿 Domino Data Science Pop-up 上发表的演讲, 向管理人员 教授数据科学。
让桑如何利用数据科学改善人类健康轨迹
原文:https://www.dominodatalab.com/blog/how-janssen-is-leveraging-data-science-to-improve-health
当医学科学遇到数据科学时,神奇的事情就会发生。
强生公司让桑制药公司首席数据科学官兼研发战略和运营全球负责人、强生数据科学委员会联***纳贾特·汗博士最近与达美乐合作伙伴负责人托马斯·罗宾逊坐在一起,讨论数据科学对改善患者疗效的影响,以及组织如何最有效地释放数据科学的力量。
在他们的讨论中,Khan 博士分享了推动数据科学持续改进的最佳实践,包括推动影响所需的基础和文化变革。
以下文章是对话的编辑文字稿,对话发生在 2022 年 1 月 26 日 Domino 的虚拟活动期间,“释放卓越性能”
释放数据科学的力量
托马斯·罗宾逊:感谢您今天的参与。
纳贾特·汗博士:非常感谢邀请我来到这里。很高兴来到这里。
托马斯·罗宾逊:给我们介绍一下 J & J 的数据科学,以及你的团队如何影响 J & J 的使命。
【Najat Khan 博士:J&J 的数据科学使命与我们的首要使命相同:改善人类健康的轨迹。在制药行业,我们正在利用数据科学来提高治疗或创新成为患者转型药物的可能性,并更好更快地做到这一点。在医疗器械领域和消费者健康领域,我们利用数字手术、机器人技术和以客户为中心的个性化服务来改善患者和客户的体验和结果。这是端到端跨越 J & J。
想象一个不幸被诊断患有癌症的病人。 随着我们向精准医疗迈进,针对癌症特定突变患者的更好治疗方法正在研发之中。现在想象一下,这位患者有一种特定的突变,有针对性的治疗方法——能够为正确的患者提供正确的治疗方法是医学中的圣杯。然而,目前,这些突变没有以常规方式被发现,因为它们是新的,因此没有定期测序。但是每个患者都会进行肿瘤活检——所以我们所做的是使用数据科学来数字化这些活检切片,然后我们使用机器学习模型来预测患者可能会从这些图像中发生什么突变。这样做的效果是发现——并且更早地发现——可能从靶向治疗中获益而可能被遗漏的患者。这转化为对患者的重大影响。
将协作作为优先事项
托马斯·罗宾逊:你是如何在团队中形成协作的?
【Najat Khan 博士:首先,对于每一个用例,我总是说,“退后一步,确保每一个行动都为患者带来了一些东西,不管你在团队中的角色或经历如何。”这确保了每个人都在为一个集体目标服务——这对数据科学这样的新学科来说尤其真实和重要。如果你停留在理论上太久,许多这些新学科就会失去动力,因为人们说,“你不能把它应用到医疗保健上。”但你可以,我们就是。
第二是确保数据科学家和科学家或该领域的其他人是共同公民;他们围坐在桌子旁,思考问题到底是什么——迭代、解释分析,然后执行。这很重要,因为你不希望这些新兴的数据科学观点被淡化。在决策过程中,你需要有一种包容性的文化。因为如果你的输入没有到达决策点,那么我们就没有取得真正的进展。
第三,不管你是高级副总裁还是分析师,也不管你是在让桑还是在外面,聪明的想法可以来自任何地方。谦逊和思想开放是我在团队中极力推行的东西。这是你们真正合作的唯一方式,敞开心扉接受不同的想法,这样你们就能竞争获胜并为整体的集体目标服务,而不是简单地做一些事情,因为你在打勾。
从理论到行动到影响
托马斯·罗宾逊:你如何构建数据科学团队和利益相关方的文化,并管理变革?
纳贾特·汗博士:当我第一次担任这个角色时,很多人说,“花一年时间,做一次倾听之旅,建立一个战略,打好基础。”所有这些都非常重要,但同样重要的是,在早期,将数据科学或任何新学科从理论转变为行动,进而产生影响。你不能等一两年,因为到那时,有影响力的机会可能会与你擦肩而过。
我在让桑大学领导 R&D 的数据科学、战略和运营团队,这意味着我和同事们都深深地沉浸在管道和科学中。管道是驱动任何制药公司的引擎。这一点很重要,因为了解你的渠道意味着你可以说,“对业务结果有影响的优先事项是什么”,无论是新冠肺炎疫苗还是我们渠道中的其他许多罕见和慢性疾病问题。接下来,“使用数据科学可以解决多少问题?什么可行?”
你需要一个短期和长期用例的投资组合,并且它需要跨越一组不同的机会,因为你不知道什么会起作用。尽早解决短期用例。这就是创造动力的原因。它使您能够从数据科学的“推动”转变为组织的“拉动”。人们看到它创造了不同,我们处于领先地位。每个人都喜欢成为获胜团队的一员,因此让人们采用数据科学的最佳方式是做艰苦的工作——选择正确的问题,灵活地解决它,并展示具体的影响。
我们还注重引进精通数据科学和医学的双语人才。这建立了与科学家和运营领导之间所需的可信度和连接性,因此你们是作为一个团队工作的,而不是孤立的。我认为这种真正的整合和嵌入是至关重要的。寻找双语人才并不容易。这个学科是新的,所以你也必须发展才能。我们有更多站在科学一边的人,他们现在也是数据科学家,或者是已经学会科学语言的数据科学家。这对于在组织中获得认同和吸引力也至关重要。
为大规模数据科学奠定基础
托马斯·罗宾逊:技术在提高您的数据科学团队的绩效方面发挥了什么作用?
【Najat Khan 博士:你必须有一个非常好的端到端平台来进行大规模的数据科学研究,并确保正确的内部和外部协作。
把它想象成一座房子的地基。第一步是数据集,在任何大型组织中,数据集通常都非常分散。当我担任这个角色时,我说,“我们需要查看我们拥有的所有不同的数据集,不只是将它们放在数据湖中,而是将它们链接并连接在一个地方,这些数据集是链接和管理的,可复制的模型和应用程序都在一个地方——类似于 GitHub。”这使您能够构建您需要的模型,并确保它们可重复且易于访问,以便数据科学家不必从头开始。你需要正确的监管平台,你需要有一个可以构建所有应用程序的相同平台,以便不仅是数据科学家使用它,而是所有科学家都使用它。
我们有一个端到端的平台,叫做 med.ai,在这里我们整合了我们的临床前和现实世界的数据:成像、实验室结果、临床试验数据。我们在一个地方有超过 2tb 的数据。我们构建模型的平台 Domino 是能够扩展的基础之一。我们从 10 个项目发展到大约 150 多个项目,除非你有一个标准化的方法将所有的数据、模型和应用程序放在一个地方,否则你无法做到这一点。从招聘的角度来看,这是一个巨大的问题,因为数据科学家不想做的一件事是将他们所有的时间用于搜索数据、模型、 Excel 表格以及他们应该与谁交谈!
增加模型速度
托马斯·罗宾逊:有什么建议可以给 exe cutives 和数据科学的领导者来提高他们的模型速度?
纳贾特·汗博士:从问“你想解决什么问题”开始你必须考虑你试图实现的业务成果,真正了解管道并制定策略是起点之一。
同时,你不想花太多时间在理论上,你想付诸行动。接受几个重要的挑战并解决它们。去年我们已经完成了超过 35 次合作。在让桑,我们非常重视寻找最聪明的想法,不管是内部的还是外部的。但是你必须有一个很好的团队来辨别什么是好的外观。建立双语数据科学家团队,拥有能够扩展的平台,所有这些都很重要。但这首先归结于在早期获得一些做得好的快速成功,然后利用这种势头在整个组织中建立这种势头。
最后,变革管理很难,因此从数据科学家到领导层,每个人都必须保持弹性并坚持到底。每次你被别的事情分心,都会有摩擦成本。对于领导力来说,如果你打算这么做,那就意味着你每天都要靠过来。数据科学家也一样。从一个角色跳到另一个角色很容易,但当你的使命是帮助病人时,你会有一种自豪感。这不需要几个月,只需要稍微长一点的时间。不仅仅是算法或者出版物。但是奖励是值得的。当第一个病人因为你的所作所为而被早期诊断时,没有什么比这种感觉更强烈的了。
了解更多信息
观看虚拟活动,“ 释放卓越性能、“与著名外科医生、作家和性能改进专家、 Atul Gawande 和首席数据科学官兼强生公司让桑制药公司研发战略&全球负责人 Najat Khan 博士& Johnson。
晨星的数据科学和 IT 团队正在为规模化做准备
编者按:这是一系列文章的一部分,分享公司在成为模型驱动的道路上的最佳实践。一些文章将包含关于他们使用 Domino 的信息。
就在五年前,晨星的 Quant 研究团队(该公司的集中式数据科学职能部门)由少数数据科学家组成,他们每年推出几个模型。当时,领导晨星定量研究团队的李·戴维森(Lee Davidson)表示,最大的挑战之一是确定数据科学可以解决的问题,并获得解决该问题的预算。
现在不再是这样了。该业务在各个方面都变得越来越受模型驱动。戴维森的团队目前由近 70 名定量研究人员、数据科学家和研究工程师组成,去年他们将 50 多个新模型投入生产。他们现在最大的挑战之一?如何大规模部署和维护这些模型。
晨星公司的量化研究副总监 Madison Sargis 在最近于芝加哥举行的 Domino Data Science Pop-up 会议上与 T2 戴维森和 T4 的技术、数据和分析主管杰夫赫希坐在一起,讨论他们如何更有效地开发、部署和管理大规模模型。
以下是该会议期间讨论的几个要点的摘要。
保持一致
Jeff Hirsch: 从工作关系来看,对我来说,关键是我们的接触点,以及我们如何尽早、经常地融合。我认为,为如何构建模型和数据将驻留在哪里设置约定,并在移交时保持一致,将会带来好处。例如,我们已经开发了一个清单,用于模型投入生产时的交接。作为我们 2020 年路线图的一部分,我们正在考虑如何创建一种基于惯例的编码方法,以更有效地分离或扩展事物。
Lee Davidson: 我们也开始定义项目阶段。我们开发了一个内部术语,包含五个项目阶段:
- 探索和积极研究
- 模型开发
- 走向市场
- 生产化
- 启动和维护
我们试图将每个项目归入这五个类别中的一个,并且我们管理这些项目的方式根据阶段而变化。我们也采用了敏捷。当我们处于第一阶段(探索和研究)时,我们正在做敏捷术语中所说的“尖峰”:数据科学家可以用一两个月的时间研究某样东西,如果它看起来很有前景,我们想继续下去,我们可以这样做。一旦我们确定了我们想要开发的解决方案,那就是我们开始以敏捷的方式前进,并使用大量软件工程原则和最佳实践的时候了。我们试图在流程的早期让更多具有工程背景的人加入进来,在项目的前四个阶段,我们有一名数据工程师、一名数据科学家和一名软件工程师一起解决一个问题。
移交给它
Lee Davidson: 任何在过去几年中从事数据科学的人都知道,如果他们有一个成功的项目,你的模型很有可能会走出实验室,现在你必须维护它。几年前,我们凭感觉飞行,这给研究人员保持他们的成果带来了很大的压力。今天,我们试图预先澄清研究人员应该做什么,移交看起来像什么,是交给不同的人还是不同的团队。例如,研究人员是负责交付产品级的、经过全面测试的代码,还是只需要提供一个别人将要实现的原型?我们还分解了劳动分工,确定了谁维护什么,模型运行的频率,以及他们是如何被训练的。
Jeff Hirsch: 如果从 IT 组织的角度来看支持工作,通常会有三个层次。
- 第 1 层是技术运营中心;
- 第二层是某种开发人员,具有更多特定于应用程序的专业知识;和
- 在这种情况下,第三层属于模型的开发人员或定量人员。
我们越是能推进到第 1 层和第 2 层,这就是我们一直采取的方法。我们一直在做的事情之一是建立关系,分享 Jupyter 笔记本,并确保我们的 QA 了解笔记本的结果。总体精神是,it 组织需要向量化组织靠拢,学习他们的一些技能,量化组织需要向开发和工程靠拢,学习其中的一些技能。
优先考虑新项目
Lee Davidson: 我们以典型的方式与 IT 合作,你会看到各部门在一起工作。一起做路线图计划,我们坐在作战室里,在图表上画东西,看资源之类的,我们提前几个月就把这些都讨论清楚了。此外,每月杰夫[美国好施集团]、我自己和 P&L 的领导都会谈论我们正在做的事情和优先事项,并讨论任何变化。
Jeff Hirsch: 各种产品套件的商业主管,如我们的风险模型,也在月度会议上提供反馈。例如,他们可能希望风险模型包含固定收入数据。那么接下来的问题是,我们如何优先将数据放入数据湖并更新模型以利用它?我们以敏捷的方式回应这种反馈,并尝试调整我们的路线图。绝对是合作。
再现性和可审计性
Lee Davidson: 当我们重新训练模型或运行健康检查时,我们的 QA 实践之一是保存结果以供以后查询。我们的许多客户希望独立地验证模型,因此我们经常需要结合洞察力和分析来提供那些模型统计数据。预先有一个好的特定于您的用例的 QA 计划是至关重要的。另一个方面是跟踪所有的数据转换。我们试图不让研究人员维护他们建立的模型。这意味着没有构建它们的人正在维护他们不太熟悉的东西,所以我们在不同的转换步骤中构建过程来保存输出。
Jeff Hirsch: 对于我们的数据湖,我们想知道湖中的哪些文件被哪些模型所利用。我们坚持某些原则;不变性就是其中之一。一旦某样东西进入数据湖,它就永远不会改变;我们只是不断添加新的文件或增量,因此跟踪这是一件大事。从模型的角度来看,我心目中的审计线索对于调试是必不可少的。你正在采取措施确保一个模型按照它应该的方式工作,并且把信息写到磁盘上并保存下来,这是你在做的时候可以增加价值的事情,然后作为副作用,它成为它的一部分。
了解更多信息
在芝加哥 Domino Data Science 弹出窗口聆听晨星的完整小组讨论,了解数据科学和 IT 团队有效合作的更多方式。
如何在 R 中做因子分析
原文:https://www.dominodatalab.com/blog/how-to-do-factor-analysis
什么是因子分析?
p 值。t 型测试。分类变量。所有这些都是最被滥用的统计技术或数据科学工具的竞争者。然而,因素分析是一个完全不同的球赛。尽管远未被过度使用,但它无疑是最有争议的统计技术,因为它在关于一般智力的辩论中发挥了作用。你不认为统计技术会造成分裂,是吗?[不算加州大学伯克利分校统计部门离开安德鲁·盖尔曼的那一次。]
在数据科学教科书中,因子分析是一种总是与 PCA 一起被提及的技术,但后来被忽略了。这就像量子力学的多重世界解释,不,这是数据科学的星球大战假日特辑。大家都模模糊糊的熟悉,但似乎没人真正了解。
因素分析旨在洞察人们行为和选择背后的潜在变量。另一方面,主成分分析是通过选择捕捉最大差异的维度来最紧凑地表示数据集。这种区别可能很微妙,但一个显著的区别是,PCA 假设数据中没有测量误差或噪声:所有的“噪声”都包含在方差捕获中。另一个重要的区别是,研究人员的自由度(T1)的数量,或者说一个人必须做出的选择,比 PCA 要多得多。不仅要选择要提取的因子的数量(大约有 10 个很少收敛的理论标准),还要决定提取的方法(大约有 7 个),旋转的类型(也有 7 个),以及是否使用方差或协方差矩阵,等等。
因素分析的目标是弄清楚用户的许多个人行为是否不能用较少数量的潜在特征来解释。更具体地说,想象你经营一家餐馆。虽然你的一些顾客吃得很健康,但你注意到许多人经常点一份布丁配他们的营养甘蓝沙拉。作为一个好奇和以数据为导向的餐馆老板,你提出了一个假设——每一份订单都可以用一个“健康”维度来解释,同时点 Poutine 和 kale 沙拉的人处于一个维度的中间,这个维度的一端是“只吃 Kale 和壁球”,另一端是“只吃培根”。
然而,你注意到这可能无法解释客户实际下单方式的差异,所以你提出了另一个维度——也许有两个维度,一个是关于人们有多爱或讨厌羽衣甘蓝,另一个是关于人们有多爱或讨厌 Poutine。你认为,也许这些维度是正交的。也许它们有些负相关。也许还有一个维度与你的顾客有多喜欢菜单上的其他竞争菜品有关。
你开始注意到你自己的假设中的趋势,并意识到可能存在任何数量的理论化维度。您真正想知道的是解释客户下单方式最大差异的最小维度数量。大概是吧,这样你就可以把更多的郁闷留给自己了。(因为那东西很好吃)。
从更专业的角度来说,进行因子分析在数学上相当于问一个精通统计学的甲骨文:“假设有 N 个潜在变量影响着人们的选择——告诉我每个变量对我看到的每个项目的影响有多大,假设所有东西都存在测量误差”。通常,被分析的“行为”或回答是以人们如何回答调查中的问题的形式出现的。
从数学上来说,对于人 i ,项目 j 和行为 Y[ij,因子分析寻求确定以下内容:]
y[ij]= W[J1]* F[i1]+W[J2]* F[I2]+…+U[ij]
其中,W 是因子权重或载荷,F 是因子,U 是测量误差/方差,不能用等式中的其他项来解释。创建因子分析的人的见解是,这个方程实际上是一个矩阵简化问题。
就像任何技术一样,它不会盲目运行——您必须确定要提取的因子数量,类似于使用 PCA 选择要减少的维度数量。关于你应该选择哪个数字,有许多指标;我过会儿会检查最好的。我提到这一点是因为当你阅读关于因子分析的指南和论文时,最大的关注点是恰当地提取正确数量的因子。毫无疑问,这是需要担心的事情。然而,最重要的部分因素或所有数据分析,唉,几乎从来没有提到。在进行数据或因素分析时,要注意的第一件事是,你的大脑有向你撒谎的倾向。考虑到因子分析中涉及的研究人员自由度惊人的数量,很容易证明做出不同选择的合理性,因为结果不符合你的直觉。
不相信我?试试这个:杰克、乔治和安妮是一个晚宴的客人。杰克看着安妮,安妮看着乔治。杰克结婚了,乔治没有。已婚的人在看未婚的人吗?
a)是
B)否
C)信息不足。
大多数人在阅读这个问题时,意识到其中有一个技巧,并抓起一张纸来找出答案。然后他们选择 c。这似乎是合乎逻辑的。然而,正确答案是 A——安妮结婚与否并不重要。雷诺真的在洛杉矶的西边。斗争仍在继续。
除非你有意识地反对它,否则你的大脑会试图将其先入为主的观念合理化到你的分析中。这通常采取向上或向下舍入因子负载的形式,或者证明要提取多少因子。记住:你要相信数据所说的你应该相信的。
R 中的因子分析入门
预处理
在你做因素分析之前,你需要一些东西。
第一:如果你还没有 R 和 RStudio,下载它们。然后获得' Psych '包。它是无与伦比的免费因素分析软件。通过键入library(psych)
来加载它
接下来:获取数据。在我这边,我将使用心理软件包附带的数据集。这些数据是以人格问题回答的形式存在的,被称为“五大清单”。然而,任何类型的行为记录都可以——在一天结束时,你需要能够制作一个完整的关联矩阵。样本量越大越好。400-500 的样本量通常被认为是一个好的经验法则。
现在好戏开始了。心理软件包是一个方便的功能。(注意:每一对字母数字代表一种性格‘特质’,用 6 分制的李克特量表表示。)
> describe(bfi)
vars n mean sd median trimmed mad min max range skew kurtosis se
A1 1 2784 2.41 1.41 2 2.23 1.48 1 6 5 0.83 -0.31 0.03
A2 2 2773 4.80 1.17 5 4.98 1.48 1 6 5 -1.12 1.05 0.02
A3 3 2774 4.60 1.30 5 4.79 1.48 1 6 5 -1.00 0.44 0.02
A4 4 2781 4.70 1.48 5 4.93 1.48 1 6 5 -1.03 0.04 0.03
A5 5 2784 4.56 1.26 5 4.71 1.48 1 6 5 -0.85 0.16 0.02
C1 6 2779 4.50 1.24 5 4.64 1.48 1 6 5 -0.85 0.30 0.02
C2 7 2776 4.37 1.32 5 4.50 1.48 1 6 5 -0.74 -0.14 0.03
C3 8 2780 4.30 1.29 5 4.42 1.48 1 6 5 -0.69 -0.13 0.02
C4 9 2774 2.55 1.38 2 2.41 1.48 1 6 5 0.60 -0.62 0.03
C5 10 2784 3.30 1.63 3 3.25 1.48 1 6 5 0.07 -1.22 0.03
E1 11 2777 2.97 1.63 3 2.86 1.48 1 6 5 0.37 -1.09 0.03
E2 12 2784 3.14 1.61 3 3.06 1.48 1 6 5 0.22 -1.15 0.03
E3 13 2775 4.00 1.35 4 4.07 1.48 1 6 5 -0.47 -0.47 0.03
E4 14 2791 4.42 1.46 5 4.59 1.48 1 6 5 -0.82 -0.30 0.03
E5 15 2779 4.42 1.33 5 4.56 1.48 1 6 5 -0.78 -0.09 0.03
N1 16 2778 2.93 1.57 3 2.82 1.48 1 6 5 0.37 -1.01 0.03
N2 17 2779 3.51 1.53 4 3.51 1.48 1 6 5 -0.08 -1.05 0.03
N3 18 2789 3.22 1.60 3 3.16 1.48 1 6 5 0.15 -1.18 0.03
N4 19 2764 3.19 1.57 3 3.12 1.48 1 6 5 0.20 -1.09 0.03
N5 20 2771 2.97 1.62 3 2.85 1.48 1 6 5 0.37 -1.06 0.03
O1 21 2778 4.82 1.13 5 4.96 1.48 1 6 5 -0.90 0.43 0.02
O2 22 2800 2.71 1.57 2 2.56 1.48 1 6 5 0.59 -0.81 0.03
O3 23 2772 4.44 1.22 5 4.56 1.48 1 6 5 -0.77 0.30 0.02
O4 24 2786 4.89 1.22 5 5.10 1.48 1 6 5 -1.22 1.08 0.02
O5 25 2780 2.49 1.33 2 2.34 1.48 1 6 5 0.74 -0.24 0.03
gender 26 2800 1.67 0.47 2 1.71 0.00 1 2 1 -0.73 -1.47 0.01
education 27 2577 3.19 1.11 3 3.22 1.48 1 5 4 -0.05 -0.32 0.02
age 28 2800 28.78 11.13 26 27.43 10.38 3 86 83 1.02 0.56 0.21
这个数据集中包含了一些人口统计数据,我将对这些数据进行修剪,以便进行因子分析。
df <- bfi[1:25]
虽然因子分析适用于协方差和相关矩阵,但推荐的做法是使用相关矩阵。没错——你真正需要的只是一个不同行为指标的关联矩阵(即使那个行为是‘点击一个按钮’、‘以某种方式回答一个问题’,或者‘实际上给了我们钱’)。
确定因子的数量
尽管有无数的指标来确定要提取的“适当”数量的因子,但除了检查各种因子解决方案并解释结果的悠久传统之外,还有两种主要的技术。第一个是检查一个 scree 图,或一个“特征值与因子/成分数”的图表。(另一方面,整平地块通常涉及大量水泥)
>scree(df)
在某一点之后,每一个额外的因素或分量将导致特征值的微小减少。(翻译:每个额外的因素并不能解释太多的差异。)通常会有一些“肘”,这个想法是你选择最后一个仍然减少方差的因素。这是主观的吗?是的。直觉可以围绕这个规则建立吗?是的。
提醒一句:有一种倾向是只取特征值大于 1 的因子的个数。这是一个近乎普遍的错误。不要这样做。已经警告过你了。此外,这有助于确保您以全尺寸查看 scree 图,而不仅仅是在小 RStudio 图窗口中查看。
在这种情况下,如果我们严格遵循“找到手肘”规则,看起来“6”是一个人可以逃脱的最高数字。还有更复杂的方法来仔细检查要提取的因子的数量,比如平行分析。对平行分析的描述,承蒙 《植物科学杂志》 :“在此过程中,来自旋转前数据集的特征值与来自相同维度(p 个变量和 n 个样本)的随机值矩阵的特征值进行比较。”这个想法是,任何低于随机产生的特征值都是多余的。
>fa.parallel(bfi)
平行分析表明因子数= 6,组分数= 6
以下是绘图输出:
通过知道你在想“好的,我们已经决定了要提取的因子的数量。我们能快点结束吗?我的朋友正在做 PCA,她已经离开去吃她的甘蓝和 Poutine 午餐。”没那么快。我们必须弄清楚如何提取 6 个因素,然后我们是否以及如何旋转它们来帮助我们的解释。
因子提取
有太多的因素提取技术,其中大部分的优点在这篇激动人心的论文中进行了比较。
以下是你需要知道的。有三种主要的因子提取技术:普通最小二乘法(也称为“最小残差”,简称“Minres”)、最大似然法和主轴因子分解法。已经发现 OLS /明里斯在各种情况下优于其他方法,并且通常给出的解决方案接近于使用最大似然法时得到的结果。最大似然法很有用,因为你可以计算置信区间。主轴因子分解是一种广泛使用的方法,它将大部分方差放在第一个因子上。与所有数据分析一样,如果您的数据中有来自新方法或实验的可靠的、有意义的结果或信号,那么您所关心的应该是不受因子提取技术影响的。但是,如果你的工作对因素加载分数和解释的微小差异很敏感,那么就值得花时间找出哪种工具最适合你。对于 bfi 数据的探索性分析,ols / minres 方法就足够了
旋转
因素提取是一回事,但它们通常很难解释,这可以说挫败了这项工作的全部意义。为了对此进行调整,通常是“旋转”,或者在 n 因子子空间中选择稍微不同的轴,以便您的结果更易于解释。本质上,轮换牺牲了一些可以解释的差异,以实际了解正在发生的事情。(这有点手动波动,但是大多数,如果不是所有著名的 20 世纪心理测量学家都强烈推荐旋转。)
与羽衣甘蓝完全不同,轮换有两种不同的味道。正交旋转假设因子不相关,而倾斜旋转假设它们相关。正交和斜交的选择取决于您的特定用例。如果您的数据包含来自一个大域的项目,并且您没有理由认为某些行为可能完全不相关,请使用倾斜旋转。如果你想了解更多,请点击这里查看简要概述,点击这里查看更深入的内容。
两种常见的旋转类型是 Varimax(正交)和 Oblimin(倾斜)。鉴于我正在分析的数据是基于个性项目的,我将选择 oblimin 旋转,因为有很好的先验理由假设个性因素不是正交的。
因子分析在 R 中有一个非常简单的命令:
> fa(df,6,fm='minres',rotate='oblimin')
Factor Analysis using method = minres
Call: fa(r = df, nfactors = 6, rotate = "oblimin", fm = "minres")
Standardized loadings (pattern matrix) based upon correlation matrix
MR2 MR1 MR3 MR5 MR4 MR6 h2 u2 com
A1 0.10 -0.11 0.08 -0.56 0.05 0.28 0.33 0.67 1.7
A2 0.04 -0.03 0.07 0.69 0.00 -0.06 0.50 0.50 1.0
A3 -0.01 -0.12 0.03 0.62 0.06 0.10 0.51 0.49 1.2
A4 -0.07 -0.06 0.20 0.39 -0.11 0.15 0.28 0.72 2.2
A5 -0.16 -0.21 0.01 0.45 0.12 0.21 0.48 0.52 2.3
C1 0.01 0.05 0.55 -0.06 0.18 0.07 0.35 0.65 1.3
C2 0.06 0.13 0.68 0.01 0.11 0.17 0.50 0.50 1.3
C3 0.01 0.06 0.55 0.09 -0.05 0.04 0.31 0.69 1.1
C4 0.05 0.08 -0.63 -0.07 0.06 0.30 0.55 0.45 1.5
C5 0.14 0.19 -0.54 -0.01 0.11 0.07 0.43 0.57 1.5
E1 -0.13 0.59 0.11 -0.12 -0.09 0.08 0.38 0.62 1.3
E2 0.05 0.69 -0.01 -0.07 -0.06 0.03 0.55 0.45 1.1
E3 0.00 -0.35 0.01 0.15 0.39 0.21 0.48 0.52 2.9
E4 -0.05 -0.55 0.03 0.19 0.03 0.29 0.56 0.44 1.8
E5 0.17 -0.41 0.26 0.07 0.22 -0.02 0.40 0.60 2.9
N1 0.85 -0.09 0.00 -0.06 -0.05 0.00 0.70 0.30 1.0
N2 0.85 -0.04 0.01 -0.02 -0.01 -0.08 0.69 0.31 1.0
N3 0.64 0.15 -0.04 0.07 0.06 0.11 0.52 0.48 1.2
N4 0.39 0.44 -0.13 0.07 0.11 0.09 0.48 0.52 2.5
N5 0.40 0.25 0.00 0.16 -0.09 0.20 0.35 0.65 2.8
O1 -0.05 -0.05 0.08 -0.04 0.56 0.03 0.34 0.66 1.1
O2 0.11 -0.01 -0.07 0.08 -0.37 0.35 0.29 0.71 2.4
O3 -0.02 -0.10 0.02 0.03 0.66 0.00 0.48 0.52 1.1
O4 0.08 0.35 -0.02 0.15 0.38 -0.02 0.25 0.75 2.4
O5 0.03 -0.06 -0.02 -0.05 -0.45 0.40 0.37 0.63 2.1
MR2 MR1 MR3 MR5 MR4 MR6
SS loadings 2.42 2.22 2.04 1.88 1.67 0.83
Proportion Var 0.10 0.09 0.08 0.08 0.07 0.03
Cumulative Var 0.10 0.19 0.27 0.34 0.41 0.44
Proportion Explained 0.22 0.20 0.18 0.17 0.15 0.07
Cumulative Proportion 0.22 0.42 0.60 0.77 0.93 1.00
With factor correlations of
MR2 MR1 MR3 MR5 MR4 MR6
MR2 1.00 0.25 -0.18 -0.10 0.02 0.18
MR1 0.25 1.00 -0.22 -0.31 -0.19 -0.06
MR3 -0.18 -0.22 1.00 0.20 0.19 -0.03
MR5 -0.10 -0.31 0.20 1.00 0.25 0.15
MR4 0.02 -0.19 0.19 0.25 1.00 0.02
MR6 0.18 -0.06 -0.03 0.15 0.02 1.00
Mean item complexity = 1.7
Test of the hypothesis that 6 factors are sufficient.
The degrees of freedom for the null model are 300 and the objective function was 7.23 with Chi Square of 20163.79
The degrees of freedom for the model are 165 and the objective function was 0.36
The root mean square of the residuals (RMSR) is 0.02
The df corrected root mean square of the residuals is 0.03
The harmonic number of observations is 2762 with the empirical chi square 660.84 with prob < 1.6e-60
The total number of observations was 2800 with MLE Chi Square = 1013.9 with prob < 4.4e-122
Tucker Lewis Index of factoring reliability = 0.922
RMSEA index = 0.043 and the 90 % confidence intervals are 0.04 0.045
BIC = -295.76
Fit based upon off diagonal values = 0.99
Measures of factor score adequacy
MR2 MR1 MR3 MR5 MR4 MR6
Correlation of scores with factors 0.93 0.89 0.88 0.87 0.85 0.77
Multiple R square of scores with factors 0.87 0.80 0.78 0.77 0.73 0.59
Minimum correlation of possible factor scores 0.73 0.59 0.56 0.53 0.46 0.18
这个输出中有很多内容,我不会全部展开——您可以在 psych 包的文档中找到更多细节。打印输出中包括模型与数据拟合程度的指标。标准的经验法则是 RMSEA 指数应该小于 0.06。为了方便起见,我把它突出显示了出来。其他指标可能是有价值的,但每个都有一个或三个不适用的具体案例,rmsea 适用于所有情况。仔细检查以确保这个值不是太高。然后,有趣的部分——通过打电话来粗略检查这些因素
> print(fa(df,6,fm='minres',rotate='oblimin')$loadings,cut=.2)
Loadings:
MR2 MR1 MR3 MR5 MR4 MR6
A1 -0.558 0.278
A2 0.690
A3 0.619
A4 0.392
A5 -0.207 0.451 0.208
C1 0.548
C2 0.681
C3 0.551
C4 0.632 0.300
C5 0.540
E1 0.586
E2 0.686
E3 0.349 0.391 0.207
E4 -0.551 0.288
E5 -0.405 0.264 0.224
N1 0.850
N2 0.850
N3 0.640
N4 0.390 0.436
N5 0.403 0.255 0.202
O1 0.563
O2 -0.367 0.352
O3 0.656
O4 0.354 0.375
O5 -0.451 0.400
MR2 MR1 MR3 MR5 MR4 MR6
SS loadings 2.305 1.973 1.925 1.700 1.566 0.777
Proportion Var 0.092 0.079 0.077 0.068 0.063 0.031
Cumulative Var 0.092 0.171 0.248 0.316 0.379 0.410
请务必查看最后一个因素—在这种情况下,最后一个因素上的负载都不是最高的,这表明它是不必要的。因此,我们转向 5 因素解决方案:
> fa(df,5,fm='minres','oblimin')
Factor Analysis using method = minres
Call: fa(r = df, nfactors = 5, n.obs = "oblimin", fm = "minres")
Standardized loadings (pattern matrix) based upon correlation matrix
MR2 MR3 MR5 MR1 MR4 h2 u2 com
A1 0.20 0.04 -0.36 -0.14 -0.04 0.15 0.85 2.0
A2 -0.02 0.09 0.60 0.01 0.03 0.40 0.60 1.1
A3 -0.03 0.03 0.67 -0.07 0.04 0.51 0.49 1.0
A4 -0.06 0.20 0.46 -0.04 -0.15 0.29 0.71 1.7
A5 -0.14 0.00 0.58 -0.17 0.06 0.48 0.52 1.3
C1 0.06 0.53 0.00 0.05 0.16 0.32 0.68 1.2
C2 0.13 0.64 0.11 0.13 0.06 0.43 0.57 1.2
C3 0.04 0.56 0.11 0.08 -0.06 0.32 0.68 1.1
C4 0.12 -0.64 0.06 0.04 -0.03 0.47 0.53 1.1
C5 0.14 -0.57 0.01 0.16 0.10 0.43 0.57 1.4
E1 -0.09 0.10 -0.10 0.56 -0.11 0.37 0.63 1.3
E2 0.06 -0.03 -0.09 0.67 -0.07 0.55 0.45 1.1
E3 0.06 -0.02 0.30 -0.34 0.31 0.44 0.56 3.0
E4 0.00 0.01 0.36 -0.53 -0.05 0.52 0.48 1.8
E5 0.18 0.27 0.08 -0.39 0.22 0.40 0.60 3.1
N1 0.85 0.01 -0.09 -0.09 -0.05 0.71 0.29 1.1
N2 0.82 0.02 -0.08 -0.04 0.01 0.66 0.34 1.0
N3 0.67 -0.06 0.10 0.14 0.03 0.53 0.47 1.2
N4 0.41 -0.16 0.09 0.42 0.08 0.48 0.52 2.4
N5 0.44 -0.02 0.22 0.25 -0.14 0.34 0.66 2.4
O1 -0.01 0.06 0.02 -0.06 0.53 0.32 0.68 1.1
O2 0.16 -0.10 0.21 -0.03 -0.44 0.24 0.76 1.9
O3 0.01 0.00 0.09 -0.10 0.63 0.47 0.53 1.1
O4 0.08 -0.04 0.14 0.36 0.38 0.26 0.74 2.4
O5 0.11 -0.05 0.10 -0.07 -0.52 0.27 0.73 1.2
MR2 MR3 MR5 MR1 MR4
SS loadings 2.49 2.05 2.10 2.07 1.64
Proportion Var 0.10 0.08 0.08 0.08 0.07
Cumulative Var 0.10 0.18 0.27 0.35 0.41
Proportion Explained 0.24 0.20 0.20 0.20 0.16
Cumulative Proportion 0.24 0.44 0.64 0.84 1.00
With factor correlations of
MR2 MR3 MR5 MR1 MR4
MR2 1.00 -0.21 -0.03 0.23 -0.01
MR3 -0.21 1.00 0.20 -0.22 0.20
MR5 -0.03 0.20 1.00 -0.31 0.23
MR1 0.23 -0.22 -0.31 1.00 -0.17
MR4 -0.01 0.20 0.23 -0.17 1.00
Mean item complexity = 1.6
Test of the hypothesis that 5 factors are sufficient.
The degrees of freedom for the null model are 300 and the objective function was 7.23 with Chi Square of 20163.79
The degrees of freedom for the model are 185 and the objective function was 0.63
The root mean square of the residuals (RMSR) is 0.03
The df corrected root mean square of the residuals is 0.04
The harmonic number of observations is 2762 with the empirical chi square 1474.6 with prob < 1.3e-199
The total number of observations was 2800 with MLE Chi Square = 1749.88 with prob < 1.4e-252
Tucker Lewis Index of factoring reliability = 0.872
RMSEA index = 0.055 and the 90 % confidence intervals are 0.053 0.057
BIC = 281.47
Fit based upon off diagonal values = 0.98
Measures of factor score adequacy
MR2 MR3 MR5 MR1 MR4
Correlation of scores with factors 0.93 0.88 0.88 0.88 0.85
Multiple R square of scores with factors 0.86 0.77 0.78 0.78 0.72
Minimum correlation of possible factor scores 0.73 0.54 0.56 0.56 0.44
these me丰富 而【h】上的美国
> print(fa(df,5,fm='minres',rotate='oblimin')$loadings,cut=.2)
Loadings:
MR2 MR3 MR5 MR1 MR4
A1 0.204 -0.360
A2 0.603
A3 0.668
A4 0.456
A5 0.577
C1 0.532
C2 0.637
C3 0.564
C4 -0.643
C5 -0.571
E1 0.565
E2 0.667
E3 0.303 -0.342 0.315
E4 0.362 -0.527
E5 0.274 -0.394 0.223
N1 0.852
N2 0.817
N3 0.665
N4 0.413 0.420
N5 0.439 0.223 0.247
O1 0.534
O2 0.211 -0.441
O3 0.633
O4 0.357 0.378
O5 -0.522
MR2 MR3 MR5 MR1 MR4
SS loadings 2.412 1.928 1.922 1.839 1.563
Proportion Var 0.096 0.077 0.077 0.074 0.063
Cumulative Var 0.096 0.174 0.250 0.324 0.387
马上,这个装载表看起来干净多了——物品显然装载在一个主要因素上,并且物品似乎被神奇地按字母分组。剧透:正是这种分析最初导致心理测量学家和个性研究人员得出结论,人际差异有五个主要维度:宜人性、责任心、外向性、神经质(有时称为情绪稳定性)和开放性。这些术语中的每一个都有精确的技术定义,通常与你在对话中使用这些词的方式不同。但那是一个完全不同的故事。
现在是因素分析最有意义的部分——为因素或结构找出一个简洁的名字,它可以解释人们是如何以及为什么做出选择的。顺便说一句,如果您没有指定最适合该数据的因素的数量,这就很难做到。
*有趣的是,似乎只有心理测量学家认为因素分析是“有益的”。
这实际上只是冰山一角——在特殊类型的旋转和因子提取、双因子解决方案中涉及到更多的复杂性...别让我从因素得分开始。因素分析是一种强大的技术,也是解释用户行为或观点的好方法。从这种方法中最重要的收获是,因子分析揭示了研究在利用统计工具时必须做出的选择数量,选择数量与大脑将其自身投射到数据上的机会数量成正比。其他看起来更简单的技术只是在幕后做出了这些选择。然而,没有一个有因子分析的传奇历史。
如何开始使用数据科学碗
原文:https://www.dominodatalab.com/blog/how-to-get-started-with-the-data-science-bowl
我很高兴分享我们用 R 和 Python 的起始代码创建的 Domino 项目,用于参加数据科学碗。
介绍
数据科学碗是一场 Kaggle 比赛,奖金为 175,000 美元,有机会帮助改善我们海洋的健康状况,对浮游生物的图像进行分类。
Domino 是一个数据科学平台,可以让您使用 R、Python 和其他语言更快地构建和部署模型。为了帮助 Data Science Bowl 的竞争者,我们将一些示例代码打包到一个 Domino 项目中,您可以轻松地在自己的工作中使用这些代码。
这篇文章描述了我们的示例项目如何帮助你在碗中竞争,或者做其他开放式机器学习项目。首先,我们概述一下我们打包的代码。然后我们描述 Domino 提供的三种能力:易于扩展的基础设施;强大的实验工作流程;以及将您的模型转化为自助式 web 表单的方法。
内容
- 三个入门脚本 你可以用:一个 IPython 笔记本用于交互工作,一个 Python 脚本用于长时间运行训练,一个 R 脚本用于长时间运行训练。
- 可扩展的基础设施 和并行性更快地培养模型。
- 并行试验,同时跟踪你的工作 这样你可以更快地迭代你的模型。
- 构建自助式 Web 诊断工具 测试训练好的模型。
- 如何分叉我们的项目 并自己使用它来启动自己的工作。
R & Python starter scripts
IPython 笔记本
我们把 Aaron Sander 的神奇教程变成了一个真正的 IPython 笔记本。
Python 批处理脚本
接下来,我们提取了 Aaron 教程中的关键训练部分,并将其转换为批处理脚本。大部分代码与 IPython 笔记本中的代码相同,但是我们排除了用于可视化样本图像的诊断代码。
r 批处理脚本
举个例子,我们使用了杰夫·赫伯特的浮游生物分类项目。
训练更快
只需点击一下鼠标,Domino 就可以通过扩展硬件来更快地训练模型。例如,您可以使用 8 核、16 核甚至 32 核机器。为了利用这一点,我们需要对一些代码进行归纳,以更好地利用多核。
基于我们运行的不同实验,我们获得了一些显著的速度提升。例如:
- Python 代码在单核机器上耗时 50 分钟。对于我们的并行版本,在 32 核机器上需要 6.5 分钟
- R 代码在单核机器上耗时 14 分钟。对于我们的并行版本,在 32 核机器上只需 4 分钟
计算机编程语言
在 IPython 笔记本和 train.py 批处理脚本中,我们修改了实际训练RF
分类器的调用。最初的代码使用了三个内核的n_jobs=3
。我们将其改为n_jobs=-1
,它将使用机器上的所有内核。
原始的非并行代码
kf = KFold(y, n_folds=5)
y_pred = y * 0
for train, test in kf:
X_train, X_test, y_train, y_test = X[train,:], X[test,:], y[train], y[test]
clf = RF(n_estimators=100, n_jobs=3)
clf.fit(X_train, y_train)
y_pred[test] = clf.predict(X_test)
print(classification_report(y, y_pred, target_names=namesClasses))
我们的平行版本
kf = KFold(y, n_folds=5)
y_pred = y * 0
for train, test in kf:
X_train, X_test, y_train, y_test = X[train,:], X[test,:], y[train], y[test]
clf = RF(n_estimators=100, n_jobs=-1)
clf.fit(X_train, y_train)
y_pred[test] = clf.predict(X_test)
print(classification_report(y, y_pred, target_names=namesClasses))
稀有
R 代码中有两个地方受益于并行性。
首先,训练随机森林分类器。我们使用带有doParallel
后端的foreach
包来并行训练森林的各个部分,并将它们组合在一起。它看起来像是更多的代码,但是大部分都是加载和初始化并行库的昙花一现。
原始的非并行代码
plankton_model <- randomForest(y = y_dat, x = x_dat)
我们的平行版本
library(foreach)
library(doParallel)
library(parallel)
numCores <- detectCores()
registerDoParallel(cores = numCores)
trees_per_core = floor(num_trees / numCores)
plankton_model <- foreach(num_trees=rep(trees_per_core, numCores), .combine=combine, .multicombine=TRUE, .packages='randomForest') %dopar% {
randomForest(y = y_dat, x = x_dat, ntree = num_trees)
}
R 代码的第二部分也很耗时,并且很容易并行化:在生成测试统计数据之前,处理测试图像以提取它们的特征。我们使用并行 for 循环来处理所有内核上的图像。
原始的非并行代码
test_data <- data.frame(image = rep("a",test_cnt), length=0,width=0,density=0,ratio=0, stringsAsFactors = FALSE)
idx <- 1
#Read and process each image
for(fileID in test_file_list){
working_file <- paste(test_data_dir,"/",fileID,sep="")
working_image <- readJPEG(working_file)
# Calculate model statistics
working_stats <- extract_stats(working_image)
working_summary <- array(c(fileID,working_stats))
test_data[idx,] <- working_summary
idx <- idx + 1
if(idx %% 10000 == 0) cat('Finished processing', idx, 'of', test_cnt, 'test images', 'n')
}
我们的平行版本
[code lang="R"]
# assumes cluster is already set up from use above
names_placeholder <- data.frame(image = rep("a",test_cnt), length=0,width=0,density=0,ratio=0, stringsAsFactors = FALSE)
#Read and process each image
working_summaries <- foreach(fileID = test_file_list, .packages='jpeg') %dopar% {
working_file <- paste(test_data_dir,"/",fileID,sep="")
working_image <- readJPEG(working_file)
# Calculate model statistics
working_stats <- extract_stats(working_image)
working_summary <- array(c(fileID,working_stats))
}
library(plyr)
test_data = ldply(working_summaries, .fun = function(x) x, .parallel = TRUE)
# a bit of a hack -- use the column names from the earlier dummy frame we defined
colnames(test_data) = colnames(names_placeholder)
实验和跟踪结果
Domino 通过让您并行实验,同时保持结果被自动跟踪,来帮助您更快地开发模型。无论何时运行代码,Domino 都会保留一份代码记录,并保留一份您生成的结果记录,因此您可以随时跟踪您的过程并重现过去的工作。
例如,因为我们的 R 代码在运行时会保存一个submission.csv
文件,所以每当我们运行代码时,都会自动记录我们生成的每个提交。如果我们需要回到一个旧的,我们可以找到相应的运行,并查看其结果,其中将有提交的副本。
您在 Domino 上开始的每次运行都有自己的机器(无论您选择什么硬件类型),因此您可以并行尝试多种不同的技术或参数。
构建自助服务工具
你有没有被非技术人员打断过,他们要求你为他们运行程序,因为他们自己不能使用你的脚本?我们使用 Domino 的启动器特性来构建一个自助式 web 表单,对不同的浮游生物图像进行分类。它是这样工作的:
- “浮游生物图像分类”启动程序会弹出一个表格,让你从电脑上传文件。
- 当您选择一个文件并单击“Run”时,Domino 会将您的图像传递给一个分类脚本(它使用 Python 代码训练的 RF 模型)来预测图像中浮游生物的类别。分类只需一秒钟,完成后您将看到结果,包括诊断图像和预测类的打印输出。例如:
履行
为了实现这一点,我们对 Python 训练脚本做了一些额外的修改。具体来说,当训练任务完成时,我们将模型(和类名)打包,以便以后可以加载它们。
joblib.dump(clf, 'dump/classifier.pkl')
joblib.dump(namesClasses, 'dump/namesClasses.pkl')
然后,我们创建了一个单独的classify.py
脚本,它加载 pickled 文件并使用它们进行预测。该脚本还会生成诊断图像,但其本质是这样的:
file_name = sys.argv[1]
clf = joblib.load('dump/classifier.pkl')
namesClasses = joblib.load('dump/namesClasses.pkl')
predictedClassIndex = clf.predict(image_to_features(file_name)).astype(int)
predictedClassName = namesClasses[predictedClassIndex[0]]
print("most likely class is: " + predictedClassName)
注意,我们的 classify 脚本希望在命令行中传递一个图像文件名。这让我们可以轻松地构建一个启动器,围绕这个脚本公开一个 UI web 表单:
实施说明
- 我们的项目包含压缩的数据集,但是它明确地忽略了解压缩的内容(您可以在。dominoignore 文件)。因为每当运行代码时 Domino 都会跟踪更改,所以拥有大量的文件(本例中有 160,000 个图像)会降低速度。为了加快速度,我们存储 zip 文件,并让代码在运行前解压缩它们。解压缩需要很少的时间,所以这不会影响整体性能。
- 在 Python 代码中,scikitlearn 在幕后使用 joblib 来并行化其随机森林训练任务。反过来,joblib 默认使用
/dev/shm
来存储选取的数据。在 Domino 的机器上,/dev/shm
可能没有足够的空间来存放这些训练集,所以我们在项目设置中设置了一个环境变量,告诉 joblib 使用/tmp
,这将有足够的空间
想让你的数据科学家不被挖走吗?考虑这些顶级专家建议
原文:https://www.dominodatalab.com/blog/how-to-retain-your-data-scientists
由达美乐内容总监丽莎·斯台普顿于 2022 年 4 月 20 日在 透视
如果你试图利用数据获得竞争优势,那么在“大辞职”之后,数据科学家的高流动率无疑是一个睡眠杀手。数据科学家已经有很高的需求和高薪,Burtch Works 的报告称,该领域很可能在 2022 年经历高就业率。这种对数据科学人才的激烈竞争很可能会持续一段时间。但是数据科学家和他们的经理们要应对的一些因素是令人惊讶的,而且根据一个关于从数据科学家那里获得最大收益的专家圆桌会议,对这些问题的一些“修复”花费惊人的低。
全球最大的生物制药公司之一 CSL Behring 的高级分析和人工智能全球主管约翰·k·汤普森表示:“当然,数据科学家希望获得报酬——这是一个热门市场,对他们的技能有很多竞争——但你可以做很多非金钱的事情,让他们在工作中感到快乐和满意。”“如果你给他们创新的自由,实验的自由,有时失败的自由。他说:“把它变成一个他们想来尝试的地方,他们几乎是不可挖走的。”
Thompson 还撰写了大量关于如何有效领导数据科学团队的文章,并撰写了《构建分析团队:利用分析和人工智能促进业务发展》。 他还是由哈佛商业评论撰稿人兼管理思想领袖 Tom Davenport 主持的圆桌讨论会的专家之一,该讨论会着眼于什么对数据科学领导者及其团队的有效性真正重要。
数据科学环境很重要
数据科学家使用他们最熟悉的工具的能力对许多数据科学家的工作满意度至关重要,这一事实往往是他们工作满意度中令人遗憾的未被充分重视的因素。
“在这一点上,数据科学更像是一门艺术,而不是一门科学,你希望让这些艺术家尽可能地多产,”汤普森说。他说,诀窍在于“像对待真正的工匠一样对待他们。”
“我店里几乎所有的数据科学家都有自己的环境设置和定制,这样他们就可以以最具创造性和创新性的方式工作,”他补充道。“所以,如果他们说他们喜欢 R,我们就给他们提供一个很好的 R 环境。如果是 Python,我们为他们设置所有他们想要的 Python 工具。我们不要求他们标准化——我们给他们需要的东西,让他们有创造力、创新力和最高的创造力。”
MLOps 技术有助于让数据科学家满意
幸运的是,让团队中的个人选择他们知道的工具——以实现他们的最高生产率——的能力现在是一个更容易管理的提议,因为工具不可知的 MLOps 技术,如 Domino 数据实验室的。与每个数据科学家都必须使用与团队或组织的其他成员完全相同的工具的时代完全不同,正如最近德勤报告所述,MLOps“结合并自动化了 ML 模型开发和操作,旨在加速整个模型生命周期过程”。如果操作得当,MLOps 还能让数据科学家自由选择他们的环境。
汤普森并不是唯一一个理解易于使用、自由选择的定制建模环境与鼓励数据科学家尽最大努力、最具创造性工作之间的联系的人。正如 Arthur D. Little 人工智能和机器学习全球主管迈克尔·艾登(Michael Eiden)解释的那样,这对数据科学家本身和他们的领导人都很重要。
“我们希望为处于其学科前沿的数据科学专业人员提供一个数据科学平台。其他平台对于核心数据科学家来说太简单了。我们的数据科学家在 Domino [Enterprise MLOps]平台上感觉就像在家里一样,并且很欣赏他们在实验中的自由度。它们不受 CPU、硬件限制或工具的约束。他们的灵活性越大,就越有创造力。”
强生公司的企业首席信息官吉姆·斯旺森(Jim Swanson)了解让数据科学家使用任何工具来提高个人生产力的价值。企业 MLOps 可以成为创造力的强大推动者。“我们认为这是非常聪明的人的促成因素,”Swanson 在这段视频中说。
这是数据驱动型业务中一个令人惊讶的常见障碍
开发一个更具协作性的环境也很关键。数据科学越来越不仅仅是数据科学家团队内部的协作;相反,这通常是跨部门的努力,有时有些令人担忧。
例如,数据科学家和 IT 之间的关系令人惊讶地存在问题。最近的 DataIQ 调查发现,大约三分之一(33.7%)的受访组织将“数据科学和 IT 之间的冲突”视为最大的挑战之一。就数据和分析的采用水平而言,即使是将自己评为“先进”或“即将成熟”的公司也无法避免冲突。对于这两个群体来说,“数据科学和 IT 之间的冲突”是他们最大的挑战(分别为 52.4%和 50%)。
“数据科学和 IT 之间的冲突表现在许多方面,它通常是因为它像对待其他软件项目一样对待数据科学模型而开始的,”Thompson 说。缓解冲突的一部分来自于分析 IT 和数据科学部门面临的不同压力和要求。IT 专家并不总是理解建模与软件开发有多么不同。
“模型需要重新训练,以实验的方式开发,并使用许多不同的软件工具制作。他说:“没有必要‘再培训’软件代码,但(数据科学)生产模型需要经常再培训。”。
这种情况的部分补救措施可能是认识到数据科学和数据科学家并不完全适合现有的结构。出于这个原因,有必要重新思考一系列相关的实践和关于数据科学家做什么和他们如何工作的既定思维方式。
“实现数据科学最大价值的公司明白,模型是一种新型的数字生活,需要不同的人、流程和平台(而不是它通常支持的那些),”汤普森说。
有关在 2022 年雇佣和留住数据科学家的更多信息,请查看这个有用的页面,管理数据科学团队。此外,在 Rev 3 上,微软首席数据分析官 John Kahan 讨论了赢得数据科学人才竞赛的话题。
如何通过熊猫概况来增强数据探索
原文:https://www.dominodatalab.com/blog/how-to-supercharge-data-exploration-with-pandas-profiling
从原始数据中获得洞察力是一个耗时的过程。预测建模工作依赖于数据集概况,无论是由汇总统计数据还是描述性图表组成。熊猫概况,,一个利用熊猫数据框架的开源工具,是一个可以简化和加速此类任务的工具。
这篇博客探讨了与手动完成此类工作相关的挑战,讨论了使用 Pandas Profiling 软件来自动化和标准化该过程的好处,并触及了此类工具在完全包含数据科学专业人员和统计研究人员所需的核心任务的能力方面的局限性。
探索性分析在数据科学生命周期中的重要性
探索性分析是数据科学生命周期的重要组成部分。结果成为理解给定建模任务的解决方案空间(或“可能的领域”)的基础。这种特定于数据的领域知识为后续的方法提供了信息,以生成有差异且有价值的预测模型。
例如:
- 通过观察数据集特征中缺失数据的频率,通常可以知道哪些特征可以用于开箱即用的建模目的(例如,对于 MVP),或者可以表明业务利益相关者建议作为预测指标的关键指标的特征需要进一步处理才能发挥作用(例如,缺失值的插补)。
- 在成对的基础上计算所有特征的相互作用可以用于选择或取消选择,用于进一步的研究。减少候选数据集中的特征数量可以减少训练和调整过程中的处理时间和/或所需的计算资源。这两个考虑因素都会影响数据科学项目的整体回报,因为它们会加快“实现价值”的时间,或者降低与培训相关的成本。
tot = len(data['CANCELLATION_CODE'])
missing = len(data[~data['CANCELLATION_CODE'].notnull()])
print('% records missing, cancellation code: ' + str(round(100*missing/tot, 2)))
% records missing, cancellation code: 97.29
取消代码可能是航班延误的一个很好的指标,但如果它只出现在 2-3%的数据中,它有用吗?
回报是显而易见的- 正确分析的数据集会更快地产生更好的模型。
但是“适当地”这样做所涉及的成本呢?
有三个关键的考虑因素:
- 手动完成这项工作非常耗时。每个数据集都具有保证生成特定统计数据或图表的属性。
- 没有明确的结束状态。人们通常不知道哪些信息将是最重要的,直到他们沿着他们的分析之路走下去,并且被认为合适的粒度级别经常是由那些做工作的人突发奇想决定的。
- 存在注射偏倚的风险。在有限的时间和无数可用的分析途径下,如何确定他们没有关注他们知道的,而不是他们不知道的?
因此,探索性分析本质上是迭代的,并且难以确定的范围。工作被重复或扩充,直到一组清晰的见解对项目涉众可用,并被认为是充分的。
出于这篇博客的目的,我们将重点关注如何使用名为 Pandas Profiling 的开源 Python 包来减少生成数据集概要所需的时间,并增加结果可传播的可能性。
熊猫简介:名字里有什么?
我们为什么关注这个特定的工具?
首先,Python 仍然是数据科学研究的主导语言。许多数据科学专业人士对熊猫的使用颇有心得,熊猫的数据帧数据结构是熊猫档案使用的基础。
此外,面对数据科学领域的新技术,Python 生态系统充满了保持该语言相关性的开源开发项目。
ref: https://pypl.github.io/PYPL.html
值得注意的是,以商业智能的名义致力于产生描述性分析的专有工具有很多。虽然这些工具对于创建精致的、可重用的、可视化的仪表板来呈现数据驱动的见解非常有用,但它们在生成形成预测建模任务的基础所需的信息的能力方面远没有那么灵活。
换句话说,数据科学管道有特定的需求,开源社区在支持这些需求方面最为敏捷。
另一方面,一些研究人员可能会说强调可视化这样的结果是不必要的,比如,“如果你知道你在找什么,pandas.describe()就是你所需要的”。
pandas.describe() example on the canonical BTS domestic flights dataset
最终,专家们对什么是重要的有他们自己的想法,这些意见影响他们探索性分析的方法:当在研究中低头时,有效地向他人传达他们的见解的可视化可能不是首要任务。
同样真实的是,可视化统计数据是一项非常重要的工作:需要时间来格式化、标记和组织图表,使之对普通观众来说是一致的。如果你不相信我,看看市场上的工具就知道了:从 matplotlib 到 ggplot2,再到 bokeh、seaborn 和 Lux 等更现代的解决方案,选择很多。
Data visualization blog posts are a dime a dozen.
ref: https://mode.com/blog/python-data-visualization-libraries/
在研究组织中,这种工具标准的缺乏通常会导致在交流数据洞察力方面的挑战:研究人员对以非专家可以理解的方式格式化他们的结果的重要性存在误解;另一方面,非专家可能不理解这样做所需要的努力!
输入 Pandas Profiling -一种为位于 Pandas 数据框架中的任何数据集生成综合统计数据和可视化数据的简单方式。
在我自己的一系列项目中使用了 pandas profiling 之后,我很高兴地说,这个软件包从一开始就是为了易用性和灵活性而设计的:
- 它有使用的最低先决条件:Python 3、Pandas 和一个网络浏览器是访问基于 HTML 的报告所需要的。
- 专为 Jupyter 设计:输出报告可以直接以内联方式呈现为交互式小部件,或者保存为 HTML 文件。值得注意的是,HTML 文件可以是“内联的”(即独立的),或者以一种更传统的方式生成一组支持文件,这是人们对 HTML 资源的期望。
- ..但是也可以在批处理模式下工作。csv 或原始文本文件转换成“熊猫友好”格式,终端中的一行代码就可以用来生成基于文件的报告。
- 让我重申一遍,以防你没有明白:一行代码生成一个数据配置文件!
- 最后但同样重要的是:它是可定制的。无论是通过配置短手添加或删除内容(或考虑大型或敏感数据集),精细调整控制的粒度变量设置,还是全面的配置文件,pandas 配置文件的定制消除了许多 ds 自动化工具所具有的“玩具”感觉,并真正使其成为各种数据和领域的专业级选项。
在 Domino 中演示熊猫概况
为了展示这些关键特性,我在 try.dominodatalab.com的建立了一个公共演示项目。
我已经将 Pandas Profiling 包添加到我们的 Domino Analytics 发行版中,该发行版预装了 Python 3.7 以供使用。
Domino Workspace Details
我们将使用来自运输统计局的 canonical airlines 数据集。
首先,我加载数据集,并快速检查我们正在处理的数据的大小:
data = pd.read_csv('../../domino/datasets/flight_data/airlines_2016_2017_2018.csv')
data.shape
(300000, 29)
注:从 1987 年开始收集数据的完整数据集远远大于 300,000 个样本。出于演示目的,对其进行了取样。
在不使用 Pandas Profiling 的情况下,常见的下一步是使用 Pandas 的 dataFrame.describe()。让我们来看看这里的输出示例:
*pd.describe() will default to displaying summaries of numerical features only. If you’d like to include categorical features, add the argument “include=’all’”. *
好的,所以我们用原生熊猫工具很快地得到一些基本的特征汇总统计。但内容和格式都不利于分享或讨论。
让我们试着创建一个熊猫档案:
from pandas_profiling import ProfileReport
ProfileReport(data).to_notebook_iframe()
HBox(children=(HTML(value='Summarize dataset'), FloatProgress(value=0.0, max=43.0), HTML(value='')))
大约 1 分 30 秒后,我们的笔记本中出现了个人资料报告:
Pointing out the key elements of a Pandas Profile Report
很快,我们看到概要文件以一种清晰而有逻辑的方式组织结果:
- 主要报告部分:概述;变量;互动;相关性;缺少值;样本。
- 警告:关于数据集中变量的快速信息
- 再现:创建日期、执行时间和配置文件配置。
因此,我们能够立即收集一些见解。例如:
- 有两个变量是先前处理的伪像,可以被去除。
- 我们的数据集中有大量缺失数据
- 变量 Origin & Destination 具有很高的基数:我们应该花时间考虑这些特性在我们最终模型中扮演的角色,因为它们可能会影响模型训练的成本和复杂性。
更仔细地看报告,我们还看到了进一步分析的机会,以及为向其他角色传达这些结果添加上下文的机会。
例如:
- 数据集中基于时间的要素具有奇数分布,在特定于变量的直方图中可见。也许我们可以调整直方图中的箱数来解释它们。
- 变量缺乏描述。作为一名领域专家,我熟悉大多数变量代表什么,但这可能会给与我的同事交流这些结果带来问题。
让我们试着根据这些见解定制报告。
首先,我们将从数据框架中删除那些不受支持的功能:
data = data.drop(columns=['Unnamed: 27', 'UNNAMED___27'])
然后,我们将获取一份默认配置文件的副本,并用一些关于我们报告的描述性信息对其进行编辑:
A Pandas Profiling Configuration File
在此期间,我对报告的内容做了一些实质性的修改:
- 提高可读性:将变量顺序设置为升序
- 简化缺失数据部分:显示条形&矩阵风格的缺失数据图,移除热图&树状图(对该数据集没有用)
- 减少相关量&交互结果:
- 包括 spearman 相关图,排除其余部分(五个其他选项)
- 简化交互图部分:将交互图限制为模拟航班延误的两个感兴趣的特征:起飞延误和到达延误
- 微调可视化效果:
- 将包含饼图的分类变量的不同级别的最大数量调整为 18(包含航空公司/承运商变量)
- 我已经将直方图的最大箱数设置为 24——这将清除我们观察到的时间相关分布中的噪声。
为了简洁起见,这些配置设置没有相关的截图,但是如果您想自己查看的话,可以在公共项目中找到 YAML 文件。
然后,我们将概要文件加载到我们的 ProfileReport 的新实例中:
profile = ProfileReport(sample, config_file="flight_conf.yaml")
最后但同样重要的是,我已经将从 BTS 网站获取的变量描述放入字典中,并将它们注入到配置文件配置中:
data_dict = {
'FL_DATE' : 'Flight Date',
'OP_CARRIER' : 'IATA_CODE_Reporting_Airline',
'OP_CARRIER_FL_NUM' : 'Tail number of aircraft',
'ORIGIN' : 'Origin Airport (Three letter acronym)',
'DEST' : 'Destination Airport',
'CRS_DEP_TIME' : 'Scheduled .. departure time',
'DEP_TIME' : 'DepTime (Actual Departure Time (local time: hhmm))',
'DEP_DELAY' : 'Difference in minutes between scheduled and actual departure time. Early departures show negative numbers.',
'TAXI_OUT' : 'Time spent taxiing out (minutes)',
'WHEELS_OFF' : 'Wheels Off Time (local time: hhmm)',
'WHEELS_ON' : 'Wheels On Time (local time: hhmm)',
'TAXI_IN' : 'Taxi In Time, in Minutes',
'CRS_ARR_TIME' : 'CRS Arrival Time (local time: hhmm)',
'ARR_TIME' : 'Actual Arrival Time (local time: hhmm)',
'ARR_DELAY' : 'Difference in minutes between scheduled and actual arrival time. Early arrivals show negative numbers,',
'CANCELLED' : 'Cancelled Flight Indicator, 1=Yes, 0=No',
'CANCELLATION_CODE' : 'IF CANCELLED == "1"; Specifies The Reason For Cancellation: "A","Carrier", "B","Weather", "C","National Air System", "D","Security"',
'DIVERTED' : 'Diverted Flight Indicator, 1=Yes, 0=No',
'CRS_ELAPSED_TIME' : 'CRS Elapsed Time of Flight, in Minutes',
'ACTUAL_ELAPSED_TIME' : 'Elapsed Time of Flight, in Minutes',
'AIR_TIME' : 'Flight Time, in Minutes',
'DISTANCE' : 'Distance between airports (miles)',
'CARRIER_DELAY' : 'Carrier Delay, in Minutes',
'WEATHER_DELAY' : 'Weather Delay, in Minutes',
'NAS_DELAY' : 'National Air System Delay, in Minutes',
'SECURITY_DELAY' : 'Security Delay, in Minutes',
'LATE_AIRCRAFT_DELAY' : 'Late Aircraft Delay, in Minutes'}
profile.set_variable('variables.descriptions', data_dict)
这里有两点需要注意:
- 如果愿意,这些变量描述可以嵌入到配置文件中
- 变量描述自动呈现在它们自己的摘要部分中,但是有一个设置使它们能够包含在每个变量的结果中。我已经打开了。
结果呢?我们定制的配置文件,包括关键元数据和变量描述。
- 通过减少指定的相关性和相互作用图,我们将 30 万个样本(每个样本包含 27 个变量)的处理时间减少到了 40 秒。
- 数据集部分提供了有助于与内部利益相关者共享和交流的报表属性。
- 变量描述与结果一致
- 依赖于时间的分布更容易解释(每小时 1 个面元)
Customized Pandas Profile with improved histogram binning and embedded variable descriptions
处理非结构化数据和未来发展机会
Pandas Profiling 最初是一个仅为表格数据设计的工具。从表面上看,最新版本包括对描述非结构化文本和图像数据的支持,这是一个好消息。
公开评估这些,图像分析的说法有点牵强。从上面的例子可以看出,Pandas Profiling 处理图像数据的能力仅限于文件属性本身。
此外,处理文本数据要求数据已经格式化为结构化(基于文本的)要素。如今,人们无法从原始文本中获取有意义的信息。
也许有一天,自然语言处理的预处理将变得足够一般化,以至于可以快速地分析原始文本数据集的语言特征(例如,词性或词频等)。).对于图像分析,支持基于图像和文件的异常值识别(例如,彩色数据集中的灰度图像,反之亦然;或者文件大小出乎意料的大)将是有价值的。
最终,Pandas 对非结构化数据的分析能力的现状并不令人惊讶——它们公开依赖(结构化)数据帧作为分析数据的底层结构。
更一般地说,对非结构化数据进行机器学习的核心挑战之一是,预处理通常直接从原始的非结构化状态(例如文件)转换为非人类可读的表示形式,如 word2vec 或“扁平化”RGB 图像矩阵。这些表述完全不符合熊猫概况所采用的标准统计解释方法。
关于改进的机会,有两项工作值得一提:
- 通过实现可扩展的后端来支持大数据分析:正在考虑开发 Spark、modin 和 dask。
- 通过 Visions 库进一步增强数据类型分析/标准化。这里的目标是为数据分析提供一套调优 Python 数据类型的工具。
你的分析工具中的一个有价值的工具
Pandas Profiles 有助于在开始建模之前加速访问数据集的描述性细节:
- 拓宽网络:通过简化和标准化数据档案,Pandas Profiling 让更多的人参与早期 DS 管道工作。这个过程是可重复的,而且结果很容易分享&沟通。
- 提高模型质量:在开发过程中,对数据集的特征了解得越多,建模工作就越有可能成功和与众不同。随后,高性能模型推动更好的业务决策并创造更多价值。
- 达成共识:简化数据集关键方面的沟通将自然地导致对最终产品的更多信任,通知关键的模型验证流程,该流程将您的模型部署到生产环境中。
如果你喜欢你在这里看到的,你可以去 try.dominodatalab.com。注册并搜索“熊猫剖析”项目,你可以亲自尝试一下!
如何使用 GPU 和 Domino 5.3 实现深度学习推理
深度学习是机器学习和人工智能(AI)的一种类型,通过例子模仿人类如何学习。虽然这听起来很复杂,但深度学习背后的基本思想很简单。深度学习模型被教会对来自图像(如“猫对狗”)、声音(喵对吠)、或文本(斑猫对雪纳瑞)的数据进行分类。这些模型构建了一个层次结构,其中每一层都基于从前一层获得的知识,并且迭代继续,直到达到其准确性目标。深度学习模型通常可以在很短的时间内达到人类可以确定的精确度。
我们的客户在他们的工作中应用了这些相同的概念,但他们没有使用深度学习来区分猫和狗,而是使用先进的技术来分析病理图像,以识别恶性肿瘤和良性肿瘤,或者分析无人机镜头,以发现冰雹后屋顶的损坏。如果你曾经接到信用卡公司的电话,要求核实最近的交易,那就是深度学习在工作,实时分析数百万笔交易,寻找可能表明欺诈的模式。
Domino 已经为训练高级深度学习模型提供了最好的环境,并且有无数的例子,例如来自和 Topdanmark 的这些用例。借助 Domino 5.3,我们正在扩展我们在训练深度学习模型方面的优势,以支持模型驱动的企业生产实现大规模深度学习,无需开发运维技能。
Domino 5.3 实现了更快的基于 GPU 的模型推理
使用 Domino 5.3,您可以部署最先进的深度学习模型,并利用GPU的计算能力,而不是必须依赖较慢的 CPU。采用这种方法的人实现了深度学习和其他大规模并行计算应用程序的显著性能提升。 研究 表明,在类似的成本下,GPU 对深度学习应用的推理速度是 CPU 的五到十五倍。
通过整合 GPU 进行模型推理,公司可以部署依赖于先进框架(如【tensor flow】)和高性能 GPU 加速平台(如英伟达 V100 和英伟达 T4)的模型。通常,为深度学习模型设置 REST 端点需要相当多的 DevOps 技能来配置计算资源(如 GPU)以处理预期的负载和处理需求。Domino 5.3 将这种复杂性抽象化,因此数据科学家只需几个步骤就可以将他们的深度学习模型部署到 Domino 模型 API。正如您将在下面看到的,他们可以选择计算实例的数量以及要分配的资源,只需点击几下鼠标。
如何用 GPU 在 Domino 中部署模型
Domino 为管理员提供了一个简单的界面来定义资源层,数据科学家可以用它来调整部署。从配置了 GPU 的节点池开始,管理员可以定义多个层,每个层指定模型 API 实例的内存和计算配置。
Domino 提供了一个简单的两步过程来将模型部署为 REST 端点(模型 API)。当用户想要部署模型 API 时,他们需要做的只是选择要执行的计算环境和文件,然后选择包含 GPU 的硬件层。就是这样!您无需学习复杂的 DevOps 技能或让 IT 人员参与配置 Kubernetes 节点和 pods 以使 GPU 可用于托管模型,只需单击一下即可完成所有这一切。
如果用户想要扩展他们的部署,他们可以选择多个实例。Domino 确保每个扩展实例都部署了自己的 GPU 资源,正如管理员设置的资源配额中所定义的那样。
一旦用户发布了模型 API,他们就可以从 Domino 中的一个集中仪表板上查看和管理它,该仪表板提供了一个单一面板来观察和管理他们部署的所有模型。
从模型 API 生成预测
一旦运行,模型 API 就准备好接受请求并让 GPU 工作。模型 API 已经设置为执行用户定义的代码,这些代码利用优化的硬件(如 GPU)来加速复杂的工作负载,如深度学习的推理(预测)。
利用 GPU+Domino 5.3 进行深度学习创新
Domino 5.3 通过将 GPU 与部署的模型相关联来加速复杂的推理处理,从而帮助企业组织实施深度学习。通过抽象出 DevOps 的复杂性,并提供一种利用开源社区最新创新的途径,Domino 为数据科学家提供了一个简单的工作流,以实现他们深度学习项目的商业价值。
围绕深度学习的开源社区正在发生惊人的创新,包括关于 拥抱脸 的 BERT 项目和预训练的图像检测框架,如 OpenMMLab 检测工具箱 。我的 Domino 同事已经发表了许多关于这些主题的详细博客;我最喜欢的一些博客是今年早些时候关于 Tensorflow、PyTorch 和 Keras 的博客,以及关于金融服务公司如何使用深度学习的博客。无论你是刚刚开始深度学习的初学者,还是寻找前沿应用和想法的高级用户,我都鼓励你访问 Domino 数据科学博客 了解更多信息。
您的数据科学团队如何改进知识管理,以及它为何如此重要
数据科学家经常带着一种恐惧来迎接知识管理的话题。一些人认为这是从他们“真正的”工作中耗费时间的分心;其他人不完全理解它的含义。甚至许多看到这个概念价值的人也发现这个过程是痛苦的。
但是,根据 Point72 的首席市场情报官 Matthew Granade 和 Domino Data Lab 的产品主管 Mac Steele 的说法,知识管理能力将成为公司竞争优势的关键来源。在 2018 年 Rev 峰会上,两人阐述了知识管理为什么重要,以及企业应该如何将其作为优先事项。
什么是知识管理?
根据 Granade 的说法,知识管理的目标是获取洞察力,他将其定义为“更好的理解”。因此,洞察力是相对的——它是关于不断改进以前的想法。从爱因斯坦到弗洛伊德,洞察力通常被视为“孤独的天才”的权限。格兰纳德认为,事实上,大多数洞察力来自于与他人合作和对现有想法的扩展。Granade 说:“当我建立数据科学组织和 quants 团队时,我试图让他们站在前人的肩膀上。
创造这种“合成机器”需要一种获取知识的方式,一个用户遵循的框架和通过反馈改进的机制。Granade 认为,公司的未来将越来越取决于他们在这方面的表现。随着越来越多的算法和基础设施广泛可用,数据科学人才库不断增长,共享数据的需求不断扩大,捕捉和增强独特见解的能力将成为一项关键优势。
为什么知识管理这么难?
斯蒂尔指出,一些知识管理挑战困扰着每个行业:
提前组织知识很难。分类往往过于死板,因为你不知道什么在未来会很重要。
参与的动机很少。正如一位数据科学家告诉斯蒂尔的那样,“我因今年构建的东西而获得报酬,而不是维护去年构建的东西。”
这是一个经典的集体行动问题。没有人想成为第一个花时间在文档上的人。当知识被获取时,可能很难知道如何对其采取行动。
制度总是落后于现实。如果知识管理需要额外的时间,并且是在与核心工作不同的系统中完成的,那么它的质量就会受到影响。
其他障碍是数据科学团队特有的:
人们使用不同的工具。当一些团队成员用 R 工作,另一些用 Python 工作,当一些人在 GitHub 上存储代码,另一些人在电子邮件中存储代码时,知识管理变得更加困难。由于人员流动率高,培训人们使用相同的系统很困难。
单个项目的组成部分是分散的。工件和见解可以分布在 Docker 商店、wiki、PowerPoint 演示等中。
如果你有代码,并不意味着你可以重新运行它。对 600 篇计算研究论文的元分析发现,只有 20%的代码可以重新运行;在这个份额中,许多第二次尝试产生了稍微不同的结果。
你如何改进知识管理?
Granade 和 Steele 确定了可以帮助数据科学领导者改善其组织中知识管理的四个步骤,并分享了实际测试来帮助您衡量自己的表现:
1.在一个地方获取尽可能多的知识。
“里面的东西越多,你与它们之间的联系就越多,价值也就越大,”斯蒂尔说。“你不希望人们在边缘地带行动。”一个包含核心工作和知识管理的通用平台是确保完成工作并最大限度减少负担的关键。如果你不能囊括一切,从最有价值的模型或知识开始,围绕它建立一个系统。
测试:分别询问你公司的五位数据科学家,“你认为这个团队现在正在做多少个项目?”他们可能会有不同的答案。
2.选择一个知识管理系统,该系统允许:
发现:数据科学家花费大量时间搜索信息,降低了生产力。团队必须决定是管理知识(雅虎的方法)还是索引知识(谷歌的方法)。“当领域相对稳定时,监管是有意义的,”斯蒂尔说。当“领域是流动的,我不可能预先知道分类法应该是什么样子”时,索引和搜索是最好的
测试:让一个新员工做一个主题,并记录他们收集正确的工件需要多长时间。如果是几周或几个月,这是一个危险信号。
来源:让人们关注知识管理中重要的方面。使用一个平台,让人们可以综合他们的工作,而不必跟踪他们使用的软件版本。
测试:事先写下你认为你的团队成员应该花在文档上的时间百分比。然后问一些人他们实际花了多长时间。这可能令人大开眼界。
斯蒂尔说:“如果它不运行,就不会被重用。”。这不仅需要访问代码,还需要访问数据集的历史版本。
测试:要求一名新员工重现另一名数据科学家六个月前所做的工作,最好是已经离开团队或组织的人。请他或她用最新的数据更新它。如果需要一周或一个月,那就麻烦了。
分解和模块化:确保人们有动力和工具来创建可以重用和构建的构件。
测试:让两个在类似项目中工作过的团队做一次事后分析,找出重叠的工作。
3.识别正确的知识单元。
Granade 说,复合系统依赖于知识单元。在学术界,那些是书和论文;在软件中,它是代码。“在数据科学中,我们的观点是,模型是组织起来的正确的东西,因为它是数据科学家制造的东西……它是一个完全可操作的单元,”他说。该模型包括数据、代码、参数和结果。
4.超越技术思考。
人员和流程级别的变化也很重要。Granade 建议重新定义人们如何看待他们的工作:他们应该花更少的时间做,花更多的时间整理和学习。他还建议,在招聘(通过在面试中关注合作)和薪酬(通过跟踪和奖励那些记录他们的工作并构建其他人可以使用的模块)时,将合作作为优先事项。最后,虽然知识管理应该被视为每个人的工作,Granade 建议一些组织为管理或促进知识创造新的角色。
循环中的人类
人类和机器:科幻还是已经司空见惯?
想象一下,你有一个几乎自动化的系统,在这个系统中,人和机器一起合作完成一些工作。这听起来可能有点科幻……某种电子人,某种未来的 T2。假设几年后你正处于繁忙的通勤交通中,高速公路上挤满了自动驾驶汽车和开车的人。人工智能专家,如加州大学伯克利分校的 Anca Dragan 正朝着这个方向努力:看看她最近的 “与人协调的汽车” 。
人和机器合作的场景已经司空见惯:几乎任何电子商务网站,在客户服务团队的支持下大规模运行——合格。然而,一个迫在眉睫的挑战是,我们能否超越死记硬背的任务。除了简单地运行代码库,机器还能在复杂的情况下做出困难的决定和判断吗?我们能否建立这样的系统,让不是人工智能专家的人“教”机器处理需要更多智慧的工作?最好是基于真实世界的例子,而不是抽象的编程?
另一方面,我们必须建立制度,让相关人员也发挥重要作用*。或者,正如大卫·拜尔所说的那样,需要极端的认知拥抱才能让人工智能在工作场所得到有效采用。阅读:管理人工智能的影响,使其不那么突然,更有用。
作为合作者的机器学习:半监督学习之旅
机器学习的两种变体已经变得普遍。一个叫做 监督学习 : 有一个数据集,数据中的每个例子都有一个标签。例如,猫和鸟的数字图像可以是数据,而注释【猫】或【鸟】将是它们的标签。通常,机器学习专家使用数据集的一部分来训练 ML 模型——因此它们基于输入来预测标签——然后调整参数,以便模型在剩余数据中准确预测。现在流行的深度学习方法就是一个很好的例子。深度学习需要大量仔细标注的训练数据才是有用的。
另一种常见的变体是 无监督学习 :通过算法运行大量数据,弹出【结构】。例如,在线营销中的客户细分经常使用聚类算法,如 K-means 这种无人监管的算法。利用人工智能的无监督方法是一个热门的研究领域,尽管这是一个悬而未决的问题。
一个不太常见的变体叫做 【半监督】 ,一个重要的特例叫做 【主动学习】 。想法很简单:假设你有一个 ML 模型的集合。模型“投票”决定如何标记每种情况的输入数据,当他们达成一致时,他们的共识就会被使用——在大多数情况下,这是一种自动化的方法。当模型不同意或缺乏信心时,把决定权踢给人类专家。让人们处理棘手的边缘案件。无论专家选择什么,反馈那个判断来迭代训练 ML 模型。
主动学习:方法和用例
当你有大量廉价的、未标记的数据时,主动学习方法非常有效——大量的数据,其中标记本身的成本是一项主要支出。假设你是底特律一家汽车制造商的高管。谷歌比你的团队有多年的优势,将标记的数据集组装成规模,这对训练无人驾驶汽车所需的 ML 模型至关重要。底特律?没有那么多。随着行业开始拥抱人工智能应用,大规模标签数据的缺乏构成了一个主要障碍。在某些垂直领域,如安全领域,当权者不鼓励收集带有标签的开放数据。现在,随着人工智能应用的承诺,这些优先事项发生了转变。汽车制造商目前正在争相标记重要的数据集,以便能够在自动驾驶市场上竞争。
扩展主动学习的实践,人在回路是现在出现的一种如何管理人工智能项目的设计模式。一个很好的案例是 “建立一个结合人类专家和数据科学 的企业”,作者是 Eric Colson 在 Stitch Fix 。除了数据集的标签,我们如何最好地利用这两个词——人做得更好,辅之以机器做得更好?这是埃里克的一句名言:
“机器不能做的是认知周围的事情,与周围信息有关的事情,或者审美,甚至与另一个人相关的能力”
在我看来,Stitch Fix 是旧金山最有趣的人工智能增强初创公司之一。作为一个“个人风格的伙伴”,他们融合了人类时尚专家和机器学习的建议,来选择和运送男女服装。这些服务适应个人偏好,是人机有效合作的一个令人惊叹的例子。
如果你想更多地了解人类和机器之间的互补性,请查看这些额外的案例研究:如何创建一个双边市场,让机器和人在一系列相关专业知识和能力上展开竞争;众包专业知识的 Flash 团队;以及B12的人工辅助 AI。当然,你也可以顺便看看我在 JupyterCon 的演讲。
带 Jupyter 的人在回路人工智能
奥赖利媒体公司使用人工智能应用,这些应用利用了人在回路的设计模式。我们与各种学习体验中的大量内容和媒体合作:电子书、教学视频、会议讨论、在线直播培训、播客采访、案例研究等。媒体主动学习的一个几乎理想的用例是重叠上下文的消歧。假设有人出版了一本使用术语IOS
的书:他们是在谈论苹果 iPhone 的操作系统,还是在谈论思科路由器的操作系统?我们处理大量关于这两者的内容。消除这些上下文的歧义对于个性化学习中良好的 UX 很重要。在我们能够利用深度学习之前,我们还需要为我们的数据(来自 200 多家出版商的学习内容)提供良好的标签。
我们的消歧 NLP 管道利用 Project Jupyter 来实现我们的人在回路方法。总体而言,流程很简单:
- 人类专家提供书籍章节、视频片段等示例。,用于一组重叠的上下文:例如, Go 编程语言中的
go
的例子,一些go
的例子,如 AlphaGo 的例子,其他的go
的例子都是空的——以上都不是 - 机器基于这些例子建立集合 ML 模型
- 机器试图注释数百万条内容,例如,作为
AlphaGo
、Golang
,或者不太有趣的“go”用法 - 通过与 Apache Spark 的集成,该流程大部分是自动、大规模并行运行的
- 在群体意见不一致的情况下,NLP 管道会遵从做出判断的人类专家,提供进一步的例子
- 这些例子用于训练 NLP 管道以构建更好的模型
- 冲洗、涂肥皂、重复自然语言理解上下文
有趣的是,在我们的消歧过程中,NLP 管道是基于 Jupyter 笔记本的。每个歧义术语(如go
、ios
、r
等)。)有不同的笔记本。专家调整笔记本中的参数,以及内容示例的链接。机器创建和评估 ML 模型,更新笔记本中的结果。笔记本还允许人类专家在 ML 模型没有达成共识时进行访问,因此人们可以快速加入。Jupyter 笔记本作为一部分配置文件,一部分数据样本,一部分结构化日志,一部分数据可视化工具。
O'Reilly Media 使用 Juypter 启动了一个小型的机器和人类合作开源项目,即人在回路。它叫做nbtransom
——在 GitHub 和 PyPi 上都有。换句话说,机器和人都成为共享文档的合作者。想想“谷歌文档”。这项工作预测了 JupyterLab 中即将出现的协作文档功能-参见加州大学伯克利分校 Ian Rose 的“ 使用 Google Drive 为 JupyterLab 进行实时协作” 。
我们将在即将于 8 月 24 日在纽约举行的 JupyterCon 上举行的演讲中介绍更多相关内容。
希望在那里见到你!
^(Domino 注:一键启动 Domino 的数据科学平台中的 Jupyter。)*
超视:贝叶斯超参数优化
原文:https://www.dominodatalab.com/blog/hyperopt-bayesian-hyperparameter-optimization
本文介绍了如何使用 HyperOpt Python 包中实现的基于顺序模型的优化(SMBO)技术来执行超参数优化。有一个补充的多米诺项目可用。
介绍
特征工程和超参数优化是两个重要的建模步骤。多年来,我和许多同事争论过哪一步对模型的准确性影响更大。虽然这一争论尚未解决,但很明显,超参数优化在机器学习生命周期的模型构建阶段占用了相当多的计算资源和时间。超参数优化有六种主要方法,包括手动搜索、网格搜索、随机搜索、进化算法、贝叶斯优化和基于梯度的方法。
虽然经验和理论表明,像随机搜索这样的流行方法比网格搜索更有效,但这些方法在如何探索超参数的搜索空间方面并不智能。训练人工智能需要变得更加节能,超参数优化是一个适合关注的领域,因为它是计算密集型。与手动、网格和随机搜索相比,贝叶斯优化不是一种强力算法,因此它是以高效方式执行超参数优化的良好选择,同时不会影响结果的质量。
在领先的政府、学术和私人机构的支持下开发的hyperpt包提供了一种有前途且易于使用的贝叶斯超参数优化算法的实现。在本文的剩余部分,我们将介绍如何使用 HyperOpt Python 包中实现的基于顺序模型的优化(SMBO)技术来执行超参数优化。
基于贝叶斯序列模型的优化(SMBO)
基于序列模型的优化是一种贝叶斯优化技术,它使用来自过去试验的信息来通知下一组要探索的超参数,并且在实践中使用这种算法的两种变体:一种基于高斯过程,另一种基于树 Parzen 估计器。HyperOpt 包实现了 Tree Parzen 估计算法来执行优化,这将在下一节中描述。
了解树 Parzen 估计量
树形 Parzen 估计器用一组非参数分布代替了以树形方式从搜索空间选择参数的生成过程。它将参数分布的选择替换为截断高斯混合、指数截断高斯混合或重新加权分类,以形成两个密度-一个密度用于损失函数,其中损失低于特定阈值,另一个密度用于损失函数,其中损失函数高于超参数空间中值的特定阈值。对于评估的密度中的每个采样配置,密度被更新以使它们更精确地代表真实的损失表面。
如何优化超参数
在这里,我们演示了如何从 Domino 的 Jobs dashboard 中优化逻辑回归、随机森林、支持向量机和 k-最近邻分类器的超参数。除了启动超参数作业之外,还可以在作业控制面板中查看作业日志和最佳超参数的结果。
为了运行超参数优化作业,我们创建一个 Python 文件( hpo.py ),该文件将模型名称作为参数,并使用 Domino 中作业仪表板中的 run 选项启动作业。
下面的步骤显示了相关的代码片段。完整的项目是可用的,可以从 try.dominodatalab.com的远视项目分叉。
步骤 1:通过将以下内容添加到 docker 文件中来安装项目所需的依赖项
RUN pip install numpy==1.13.1
RUN pip install hyperopt
RUN pip install scipy==0.19.1
您还可以在 try.dominodatalab.com 的使用 HyperOpt Domino Analytics 发行版 Py3.6 R3.5 环境。它拥有所需的所有依赖项,还包括库,以防您希望使用 HyperOpt 来优化使用 Keras/Tensorflow 的深网的超参数。
Installing the required dependencies to the environment in a Domino environment
步骤 2:创建一个 Python 文件(在try.dominodatalab.com的 HyperOpt 项目中作为 hpo.py 存在)并加载所需的库
from hyperopt import hp, tpe, fmin, Trials, STATUS_OK
from sklearn import datasets
from sklearn.neighbors import KNeighborsClassifier
from sklearn.svm import SVC
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble.forest import RandomForestClassifier
from sklearn.preprocessing import scale, normalize
from sklearn.model_selection import cross_val_score
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
步骤 3:指定要优化超参数的算法
models = {
'logistic_regression' : LogisticRegression,
'rf' : RandomForestClassifier,
'knn' : KNeighborsClassifier,
'svc' : SVC
}
步骤 4:为每个算法设置超参数空间
def search_space(model):
model = model.lower()
space = {}
if model == 'knn':
space = {
'n_neighbors': hp.choice('n_neighbors', range(1,100)),
'scale': hp.choice('scale', [0, 1]),
'normalize': hp.choice('normalize', [0, 1]),
}
elif model == 'svc':
space = {
'C': hp.uniform('C', 0, 20),
'kernel': hp.choice('kernel', ['linear', 'sigmoid', 'poly', 'rbf']),
'gamma': hp.uniform('gamma', 0, 20),
'scale': hp.choice('scale', [0, 1]),
'normalize': hp.choice('normalize', [0, 1]),
}
elif model == 'logistic_regression':
space = {
'warm_start' : hp.choice('warm_start', [True, False]),
'fit_intercept' : hp.choice('fit_intercept', [True, False]),
'tol' : hp.uniform('tol', 0.00001, 0.0001),
'C' : hp.uniform('C', 0.05, 3),
'solver' : hp.choice('solver', ['newton-cg', 'lbfgs', 'liblinear']),
'max_iter' : hp.choice('max_iter', range(100,1000)),
'scale': hp.choice('scale', [0, 1]),
'normalize': hp.choice('normalize', [0, 1]),
'multi_class' : 'auto',
'class_weight' : 'balanced'
}
elif model == 'rf':
space = {'max_depth': hp.choice('max_depth', range(1,20)),
'max_features': hp.choice('max_features', range(1,3)),
'n_estimators': hp.choice('n_estimators', range(10,50)),
'criterion': hp.choice('criterion', ["gini", "entropy"]),
}
space['model'] = model
return space
步骤 5:定义模型的损失度量
在这一步中,我们定义了一个 5 倍交叉验证分数作为损失,由于 HyperOpt 的优化器执行最小化,我们给交叉验证分数添加了一个负号。
def get_acc_status(clf,X_,y):
acc = cross_val_score(clf, X_, y, cv=5).mean()
return {'loss': -acc, 'status': STATUS_OK}
步骤 6:为 HyperOpt 优化器构建目标函数
在这一步中,我们传入超参数并返回由一组超参数的损失函数计算的值。
def obj_fnc(params):
model = params.get('model').lower()
X_ = scale_normalize(params,X[:])
del params['model']
clf = models[model](**params)
return(get_acc_status(clf,X_,y))
步骤 7:创建一个试用对象来存储每次评估的结果,并打印找到的最佳结果
hypopt_trials = Trials()
best_params = fmin(obj_fnc, search_space(model), algo=tpe.suggest,
max_evals=1000, trials= hypopt_trials)
print(best_params)
print(hypopt_trials.best_trial['result']['loss'])
步骤 8:将找到的模型名称、精确度和最佳超参数写入 dominostats.json
一旦数据被写入dominostats.json,
,结果将在 Domino 的 Jobs dashboard 中可见。
with open('dominostats.json', 'w') as f:
f.write(json.dumps({"Algo": model, "Accuracy":
hypopt_trials.best_trial['result']['loss'],"Best params" : best_params}))
步骤 9:从作业仪表板启动超参数优化作业
使用左侧的导航面板导航到 Jobs dashboard,然后单击 Run 选项,以型号名称作为参数执行 hpo.py。
Execute the hyperparameter optimization jobs
步骤 10:在作业仪表板上查看结果
结果显示,支持向量分类器具有最好的准确度(0.993,并且能够相当快地找到好的分离超平面),而随机森林具有最低的准确度(0.966)。
Jobs dashboard with results of the different hyperparameter optimization runs
结论
贝叶斯超参数优化是执行超参数优化的智能方式。它有助于节省计算资源和时间,并且通常显示与随机搜索相同或更好的结果。HyperOpt 库使运行贝叶斯超参数优化变得容易,而不必处理通常伴随贝叶斯方法的数学复杂性。HyperOpt 还有一个充满活力的开源社区,为使用 Keras 构建的 sci-kit 模型和深度神经网络贡献助手包。
此外,当使用 Jobs dashboard 在 Domino 中执行时,超参数优化运行的日志和结果是可用的,这使得可视化、排序和比较结果变得容易。
图像差分与 CSS 技巧
原文:https://www.dominodatalab.com/blog/image-diffing-with-css-tricks
我们一直在努力在 Domino 中提供令人兴奋的新特性。我们的最新版本包含了很多内容,包括跨项目导入/共享数据集的能力,更简单的管理用户组织的方法,以及对我们托管 Jupyter 笔记本电脑方式的改进,以及使管理 Domino 内部部署更容易的变化。
在这篇文章中,我想分享一个仍在开发中的测试功能的预览:更直观地比较图像的能力。
背景和使用案例
Domino 提供了对您运行的不同分析实验进行比较的能力,因此您可以并排看到您的实际结果,而不仅仅是源代码中的变化。如果您要生成图表或其他诊断图像,并改变实验的技术或参数,这将非常有用。
如果您的图像有明显的差异,这种方法效果很好。但是,如果差异更细微,目测可能还不够。
基于 CSS 的图像差分
我们借用了我们在中读到的一项技术,在这里中为我们的图像比较视图添加了一个新功能。您可以将一个图像叠加在另一个图像上查看,而不是并排查看两个不同版本的图像,这样更容易发现差异。看看这个:
新版本的图像覆盖在旧版本上,我们提供了一些旋钮和转盘进行比较:
- 滑块控制顶部图像的不透明度。来回移动它可以让您轻松地以交互方式探索变化。
- 最初,选择“反转颜色”选项。这将反转顶部图像的颜色。当顶部图像的不透明度约为 50%时,顶部图像的反转颜色会与底部图像的颜色“抵消”。结果是,任何图像相同的地方都变成灰色,只有差异突出。
履行
这里的 CSS 非常简单。我们用-webkit-filter: invert(...) opacity(...)
做我们需要做的一切。滑块和按钮被连接以在改变时调用该功能:
function changeTopImage() {
var opacity = $("#opacity-slider").val();
var invert = $("#invert-checkbox").is(":checked") ? 100 : 0;
$("#top-image").css("-webkit-filter", "invert(" + invert + "%) opacity(" + opacity + "%)")
}
基于采样的数据集类别不平衡处理方法
假设你是一名医学专业人员,正在训练一个分类器来检测一个人是否患有极其罕见的疾病。你训练你的分类器,它在你的测试集上产生 99.9%的准确率。您对这些结果欣喜若狂,但是当您检查分类器输出的标签时,您会看到它总是输出“无疾病”,而不管患者数据如何。这是怎么回事?!
因为这种疾病非常罕见,与数千名未患病的患者相比,在您的数据集中只有少数患者患有这种疾病。因为在你的数据集中超过 99.9%的患者没有疾病,任何分类器都可以通过简单地向每个新患者返回“没有疾病”来实现令人印象深刻的高准确性。
这是类不平衡问题的一个例子,其中属于少数类(在我们的例子中为“疾病”)的数据点的数量远小于属于多数类(“无疾病”)的数据点的数量。除了医学诊断,这个问题也出现在其他领域,如欺诈检测和异常检测。
在这篇博文中,我将向您展示基于采样的方法来解决数据中的类不平衡问题。
取样技术概述
数据重采样通常用于数据科学中,以验证机器学习模型。如果你在建立模型的时候曾经进行过交叉验证,那么你就进行过数据重采样(虽然人们很少称之为数据重采样法)。例如,如果您正在运行 5 重交叉验证,那么您正在重新采样您的训练数据,这样每个数据点现在都属于五重之一。
现在,让我们讨论一种最流行的数据重采样方法: Bootstrapping 。
我有一个关于 2011 年各州家庭互联网使用情况的数据集。该数据集有 52 行(每个州、哥伦比亚特区和整个美国各一行),具有与互联网使用相关的特征。下面是该州/地区拥有家庭互联网的家庭百分比直方图。
我们可以看看这个直方图,问自己一个基本问题:这些百分比的平均值是多少?我们可以很容易地计算出美国家庭拥有家庭互联网的平均比例为 76.7%。
现在让我们问一个更难的问题:均值的分布是什么样的?这似乎是一个奇怪的问题,但是当我们计算数据的平均值时,我们实际上创建了一个平均值的单样本数据集。
如果我们旅行到一个平行宇宙,收集 2011 年各州的互联网使用数据,我们会看到完全相同的平均值 76.7%吗?大概不会!我们会看到不同含义。如果我们去几个更平行的宇宙,在每个宇宙中收集这些数据,我们可能会得到不同的家庭互联网平均百分比值。
实际上,我们无法前往平行宇宙(...然而)并重新收集这些数据,但是我们可以使用自举方法来模拟这种情况。bootstrap 背后的想法很简单:如果我们用替换数据中的重新采样点,我们可以将重新采样的数据集视为我们在平行宇宙中收集的新数据集。
下面是我用 Python 实现的 bootstrap。
def bootstrap(X, n = None, iterations = 1):
if n == None:
n = len(X)
X_resampled = np.random.choice(X, size = (iterations, n), replace = True)
return X_resampled
使用 bootstrap 方法,我可以从原始数据中创建 2000 个重新采样的数据集,并计算每个数据集的平均值。现在,我们有一个 2000 个样本的数据集,用于计算拥有家庭互联网的家庭的平均百分比。
你可能会注意到上面的直方图类似于高斯分布。如果我将重新采样的数量从 2,000 增加到 100,000,得到的直方图将与高斯分布更加相似。
在传统的统计分析中,我们有一些感兴趣的人群,我们收集样本数据来执行以下形式的统计推断:样本- >人群。通过 bootstrap,我们将原始样本数据视为我们感兴趣的总体,并收集重采样数据以执行以下形式的统计推断:重采样数据- >原始样本。
不平衡学习
不平衡学习是一个 Python 库,包含各种处理不平衡数据集以及产生不平衡数据集的算法。该库可以轻松安装 pip :
pip install -u imbalanced-learn
让我们来探索第二组数据,它们与 2004 年至 2012 年美国立法者的净资产有关。对于这个例子,我们看看 2012 年参议员和众议员的最低净值和最高净值。2012 年,我们有 516 名众议员和 113 名参议员的净资产数据。
尽管数据中的众议员人数几乎是参议员人数的五倍,但这种不平衡程度还不足以严重影响我们的预测模型。幸运的是,不平衡学习库包含了一个make _ unbalance方法来加剧给定数据集中的类不平衡程度。
让我们使用这种方法将数据中参议员的数量从大约 20%减少到 5%。
from imblearn.datasets import make_imbalance
X_resampled, y_resampled = make_imbalance(X,y, ratio = 0.05, min_c_ = "Senate", random_state = 249)
现在,数据中的参议员人数已经从 113 人减少到 25 人,因此新的数据集严重偏向众议院议员。
当使用基于抽样的方法来调整类别不平衡时,我们可以采取两种不同的方法:
- 增加来自少数类的采样点的数量。
- 从多数类中减少采样点的数量。
让我们检查这两种方法...
过采样:SMOTE
对于第一种方法,我们将增加少数类的采样点数量,以匹配多数类的数据点数量。对于我们的问题,这将意味着重新采样以将数据中的参议员数量从 25 个增加到 516 个。
因为 bootstrap 方法将抽样与替换结合在一起,所以我们可以对 25 个参议员重新抽样,直到我们有一个包含 516 个参议员的新数据集。您可能会注意到这种方法的一个潜在问题:如果我们从 25 个参议员中替换取样,直到我们有 516 个数据点,我们将在结果数据集中多次看到一些相同的参议员!
我们希望使用 bootstrap 的一般原理从我们的少数类中进行替换采样,但是我们希望调整每个重新采样的值,以避免与原始数据完全相同。这就是 合成少数过采样技术(SMOTE) 算法的用武之地。
SMOTE 算法可以分为四个步骤:
- 从少数民族类中随机选取一个点。
- 计算该点的k-最近邻(对于一些预先指定的 k )。
- 在选择的点和它的每个邻居之间的某个地方添加 k 个新点。
比如让 k = 5。然后我们从少数民族类中随机选择一个点。接下来,我们从也属于少数类的点计算它的 5 个最近邻。最后,对于每个邻居,我们计算连接所选点到其邻居的线段,并沿着该线的某个位置添加一个新点。
每个新的合成子点都基于其父点(选定的点和它的一个邻居),但子点永远不会是其父点的精确副本。启发性地,SMOTE 通过在少数类倾向所在的一般子空间中创建新的数据点来工作。
因为不平衡学习库是建立在 Scikit-Learn 之上的,使用 SMOTE 算法只有几行代码。
from imblearn.over_sampling import SMOTE
smote = SMOTE(kind = "regular")
X_sm, y_sm = smote.fit_sample(X_resampled, y_resampled)
上面的代码产生 491 个合成参议员,所以 X_sm 和 y_sm 中的参议员总数是 516;与众议员人数相同。
正如你所看到的,我们现在有了更多的参议员数据点,它们似乎都落在原始参议员数据的总趋势线上。
欠采样:Tomek 链接
在解决类别不平衡的第二种方法中,我们将做与第一种方法相反的事情:不是为少数类别创建新的数据点,而是从多数类别中移除数据点。
我们可以从多数类中随机删除点,但我们应该专注于删除那些给我们带来更多麻烦的数据点。这些点被称为到的链接。
Tomek 链接是成对的点( A 、 B ),使得 A 和 B 是彼此最近的邻居,并且它们具有相反的标签。
正如你在上面的图像中看到的, Tomek 链接(用绿色圈出)是最近邻的红色和蓝色数据点对。直觉上,这些是会给大多数分类算法带来最大麻烦的点。通过移除这些点,我们扩大了两个类之间的分离,因此我们的算法对其输出更“有信心”。
同样,不平衡学习使得实例化 Tomek 链接模型并使其适合我们的数据变得简单。
from imblearn.under_sampling import TomekLinks
tLinks = TomekLinks(return_indices = True)
X_tl, y_tl, id_tl = tLinks.fit_sample(X_resampled, y_resampled)
return _ indexes允许我们获取被移除的数据点的索引,因此我们可以分别绘制这些索引。在下图中,我绘制了房屋数据以及移除的数据点。
总共有 14 个被移除的数据点(蓝色),它们大多位于红色点的簇中。因为参议员和众议员的数据在这个聚类中有很大的重叠,所以从这里移除点是有意义的,以便增加两个类之间的分离级别。
结论
类别不平衡是许多应用数据科学和机器学习问题中的常见问题。虽然我只讨论了减轻不平衡问题的基于采样的方法,但是还有其他类型的方法来处理不平衡,比如特殊的代价函数,它以不同的方式处理正面和负面的例子。
需要记住的一点是,这些方法并不是解决阶级不平衡问题的灵丹妙药。这些方法的工作原理是在数据中引入一种特殊的偏差;这使得预测模型更容易学习可推广的模式。如果您确实使用这些方法,了解这种特殊偏差如何影响您的模型的结果是很重要的。
关于这个主题的进一步阅读,我推荐 2009 年的从不平衡数据中学习(PDF) 论文。虽然它最先进的部分已经过时,但它仍然是一篇关于阶级不平衡的伟大调查论文。
社区主导的开源的重要性
原文:https://www.dominodatalab.com/blog/importance-community-led-open-source
大熊实验室主任、熊猫项目创建者韦斯·麦金尼(Wes McKinney)在 Rev 发表主题演讲“通过开源推进数据科学”。McKinney 的主题演讲涵盖了开源与数据科学的共生关系,以及社区主导的开源的重要性。这篇博文包括精华部分、完整视频和主题演讲的文字记录。
基调总结
Wes McKinney 在 Rev 的“通过开源推进数据科学”主题演讲中,对过去十年开源的发展、开源对现代数据科学堆栈的贡献,以及为什么社区主导的开源正处于关键点提供了深刻见解。McKinney 倡导数据科学家、工程师和组织为社区主导的开源做出贡献。
主题演讲的几个亮点包括
- 了解 Python、Hadoop 和 Spark 开源项目中的代码重用、协作和“许可”如何与现代数据科学的发展联系起来
- 深入研究“客户”与受益于开源的个人和组织
- 开源如何提供额外的透明度,并增加学术、科学和研究成果可复制性的期望
- 社区主导的开源项目与单个公司或小型公司联盟主导的项目有何不同
- 通过贡献时间、提供开发者认可或资助面向开发者的贡献来影响开源
要了解更多关于本次会议的见解,请观看视频或通读文字记录。
视频抄本
本部分提供了主题演讲的书面记录以及主题演讲后的问答。为了便于阅读,本文经过了编辑。
主旨
韦斯·麦金尼:
这个演讲是过去两三年中一直在进行的一个重要讨论,但它对我来说也是非常个人化的,因为我做过很多事情,但在很大程度上,我的职业是构建开源软件。我现在已经是构建开源的第九个年头了。我想说这个演讲的问题比答案多,但是这些是我想了很多关于我们如何生产开源软件以及我们如何更好地支持开源开发者的事情。
演讲的副标题是“社区主导的开源和你”,我会解释我所说的社区主导的开源是什么意思,我们会深入探讨。从近十年的角度来看开源世界,所发生的一切都非常令人惊讶。GitHub 今年已经十岁了,当你想到十年前开源开发者合作的方式时,这有点令人难以置信。人们过去常常发送补丁文件,然后他们会以电子邮件的形式发送代码评论。通过在 GitHub 上以一种非常轻量级的方式将人们聚集在一起的协同作用,开始开源项目和协作并让真正有趣的事情发生变得比以往任何时候都更容易。
开源在我们现在称之为现代数据科学栈的发展中扮演了一个非常重要的角色。想想如果没有在 Python 世界、R 世界、Apache Hadoop 生态系统、Spark 世界中开发的所有开源项目,数据科学领域可能会发生什么真的很有趣,但有趣的是,一个项目并没有真正导致另一个项目。有些人会说,“嗯,你知道,也许开源项目促进了数据科学领域的快速发展,或者相反。”
现实远比这复杂得多。
这真的是一种共生关系,因为人们正在收集和分析越来越多的数据。他们需要软件来分析这些数据,而开源世界社区奇迹般地在关键时刻满足了这一需求。其中很大一部分是协作和代码重用方面,你可以选择你的陈词滥调,无论是“最好的代码是你不必写的代码”还是“伟大的艺术家偷窃”,我相信还有许多其他类似的关于重用代码的格言。事实上,许可允许项目能够以一种安全的方式剪切和粘贴代码,并构建新的项目,并且能够以一种非常快的方式将自己从其他人的工作中引导出来,这有助于进展的发生,发生得非常,非常,非常快。
显然,随着移动和社交网络的兴起,公司争相让更多人点击广告,并利用他们的应用程序来收集海量数据,需要能够收集、管理、分析、可视化和制作模型的软件来处理所有这些数据。他们只是需要快速扩展,不能坐等商业软件供应商开发软件来解决这些问题。这就是为什么当雅虎还是一个东西的时候,你会看到 Apache Hadoop 从雅虎出来。脸书是在 Hadoop 上使用 SQL 的 Apache Hive 的创始人。许多大型互联网公司在非常重要的开源项目中创建了这些项目,因为他们必须快速解决摆在他们面前的问题,他们认为将这些项目作为开源项目发布将有助于加快进步和创新。
我思考很多的另一个因素是闭源许可模式和云计算之间的相互作用。过去,你会有一个服务器机房,无论服务器机房里有什么,你都必须打电话给你的 IT 人员说,“嘿,你知道我们需要购买更多的服务器机架来增加我们处理工作负载的能力,”但有了 AWS 和云计算,你可以非常轻松地从十个节点增加到一百或一千个节点。你能想象如果你不得不打电话给 MathWorks 或 SAS Institute 并购买一堆许可证才能在云中扩展你的分析吗?拥有开源软件,能够按照你自己的自由意志,安装你想要的软件,而不必在一条摩擦的高速公路上,这是推动数据科学走向开源的一个重要因素。
另一个主要因素是科学上可重复研究结果的问题。现在已经出现了许多引人注目的案例,在这些案例中,分析中出现了错误,无论是导致次贷危机的 Excel 错误,还是再现影响公共政策或影响医学或其他领域决策的主要结果的不同类型的问题。在学术界和科学界,在研究实验室,有一股增加透明度和使尽可能多的科学可复制的推动力。无论是“这里有一个 Jupyter 笔记本”,从上到下什么都有。“我是这样得到这些数据的。以下是我用来加载和预处理数据的库。这是我的模型。这是我的结果和数据可视化。”我真的希望我们越来越多地看到,科学界有这样的社会期望,你想发表一份分析,你的 Docker 文件在哪里?你的数据文件在哪里?我怎么能自己复制你的结果,看看你是怎么摘樱桃的?或者你的分析有什么问题使你的结果不那么令人信服?
另一个影响开源软件发展的主要趋势是让开源软件在企业中工作的挑战。你可能会说这是我们所有人坐在 Domino Data Labs 的房子里的主要原因,Domino Data Labs 是许多帮助大公司实现开源的公司之一。我们需要所有这些工具来实现治理、合作和审计。如果有人做了一堆研究,然后他们退出了,他们的工作在哪里,我们如何保持跟踪呢?所有这些问题都发生在大公司,并且在很大程度上发生在开源开发者身上,这些不是很多开源开发者会在空闲时间自己解决的问题类型,特别是当你考虑到很多开源开发者在哪里以及他们正在试图自己解决什么样的问题时。
考虑到这一切,我想了很多,我和很多公司谈过,只是想更多地考虑软件来自哪里。谁建造它?编写代码的人是谁?谁在维护这些项目?谁在管理来自外部贡献者的代码流,发出拉请求的人,以及谁决定什么代码在主分支中结束?谁在管理发布?本质上,香肠是怎么做的?这是其中之一,你越是...这有点像肉类工业。对肉类行业了解越多,就越不想吃肉。你对开源软件了解得越多,嗯,我不确定什么是正确的类比,但是你了解得越多,你就越关心它们是如何结合在一起的。
一部分是谁出钱?如果有人在这个项目上花了时间,他们会因此得到报酬吗?是他们的夜晚和周末吗?我只是想在付费的东西周围加上一些引号,因为这最终会成为一个复杂的主题。有很多种开源项目。不是每个开源项目都是平等的,我不知道还有什么合适的词来描述这些项目,但我有点宽泛,这是一种过于简化,把项目分为两个不同的类别,行业或公司主导的项目和社区主导的项目。
行业或公司主导的项目通常是由一家公司或一个小的公司联盟启动的项目。有时代码库开始是一个专有的代码库,后来是开源的,每当有市场需求或者开源项目出现威胁到专有项目时,他们就决定开源它。也许这个项目从一开始就被认为是一个开源项目。这类项目的一个很好的例子是谷歌的 TensorFlow,TensorFlow 在谷歌内部使用,作为谷歌统治世界计划的一部分。他们觉得让每个人都使用 TensorFlow 进行机器学习和深度学习,并让它在谷歌云上易于使用是他们发展战略的一部分。
社区主导的项目则不同。有时他们有非常不同的起源故事。有时,它们是由雄心勃勃的人发起的,他们渴望有所作为或有某种远见。我把自己归为这一类。其中一些是由政府资助的研究实验室的人发起的,比如 scikit-learn for Python 是由法国政府资助的研究机构和许多其他机构发起的,但这只是它开始的地方。Matplotlib 和许多其他 Python 项目是由不同的政府研究项目资助的。有时这项工作已经在大学里完成了。当你看 R 世界时,最初的 R 世界来自于统计学家的间接支持,他们希望构建 S 编程语言的免费替代品,而 S 编程语言是专有的。这很有趣,因为在任何不同的生态系统中,你都可能有更高比例的社区主导的项目,或来自有机增长的项目,或由具有特定议程的公司主导的项目。
其中一个挑战,也有很多挑战,是你考虑是什么激励软件开发者创造高质量的软件?开源软件项目经常会面临对其项目专业水平的批评,无论是打包的问题,文档的问题,测试的问题,打包,持续交付。有许多不同的问题。我发现,在社区主导的项目中,人们在专业企业级软件工程方面考虑的许多事情都被搁置了,问题是激励结构不支持这项工作。当您可以在添加新功能和修复一些关键错误之间进行选择时,如果我们有无限的人员和无限的资源,有许多不同类型的工作可以做得非常好,但这些工作都被搁置了。
然而,如果你有一个商业软件项目或者甚至是行业主导的项目...比方说,你考虑 TensorFlow 与脸书、微软和其他主要科技公司领导的所有其他竞争人工智能框架的对比。他们有动力开发 TensorFlow,脸书有动力开发 PyTorch,开发最专业的文档,最好的测试,人们可以信赖的软件,但考虑到他们的资源水平,一个项目要做到这一点并不总是那么容易。
对于构建数据科学或数据处理项目的人来说,另一件使事情变得复杂的事情是世界上围绕数据隐私的所有问题。对软件的信任和透明是越来越多的期望,如果你要建立一个数据科学项目,你希望你使用的所有软件都是开源的,这样你就可以,如果你需要,看看它是如何实现的,并理解它。
你可以看到你的数据是否以某种方式被不当使用,如果你将敏感数据发送到一个你一无所知的黑盒中,这可能会引起一些关注,所以对于像我这样的人和以开发开源软件为生的人来说,我们可能希望开发更多的闭源软件,以便能够产生收入来支持我们的工作, 但是在许多情况下,人们不希望大量的软件被关闭源代码或有一个与之相关的商业模型,因为这些问题围绕着信任和透明性以及重用软件和做出改变的自由。
没有一种项目是没有问题的。在主要由单个公司或多个公司领导的项目中,你确实会看到一些问题。你会看到公司改变策略,基本上放弃项目,或者他们将开发人员转移到另一个团队。如果一家初创公司正在构建一个开源项目,你可能会看到该初创公司被收购,或者该初创公司失败,项目也同样被放弃,还有其他问题可能会发生。
在社区主导的项目中出现的问题更为隐蔽,涉及到开发人员和维护人员因为没有足够的支持来让他们跟上项目建设的进度而精疲力竭的问题。项目越受欢迎,这些问题就越严重。你可能会认为用户越多,维护人员和核心开发人员就越多...根据我的经验,这不是真的。你确实得到了更多的核心开发者,但这不是线性增长。你可能会认为像 Pandas 这样拥有数百万用户的项目,我们会有 100 名核心开发人员或维护人员来完成项目,但实际上只有个位数。不到 10 个人在一周接一周、一个月接一个月地辛苦工作。
其中一部分是这样的情况,使得一个人成为项目的维护者,或者一个核心开发人员,他们花费 50%或更多的时间,这是非常特殊的情况,很难出现。最近有一条推文在网上疯传。这张幻灯片甚至有点过时了,在分析 Pandas 项目、NumPy 项目和 Matplotlib 项目时,如果你看看谁实际上在漏斗的底部,谁在管理进入项目并使项目工作的代码,这是一个令人震惊的少数人。
标题是“我们依靠 15 个人来做我们的科学。没有他们,这些项目基本上无法维持。”这是那种让我们夜不能寐的东西。虽然我们有一个庞大的数字,但贡献者的长尾已经大大增长,我们已经有超过 1000 个熊猫的独特贡献者,仅仅是一个人,但真正使这个项目工作的实际人数是令人震惊的少数人,而且这个数字增长不是很快。
这也因为用户和开发者之间的关系而变得复杂,这也可能变得相当有害,特别是当一个项目变得越来越受欢迎的时候。我们有趣地发现,用户不再把开发软件的人当成人。他们只是假设软件是存在的,并且是按照他们的满意程度构建的。前段时间和熊猫邮件列表上的一个用户有过交流,他用“客户”这个词来形容自己。我不得不盯着它,尽量不要反应过度,我想,“嗯,我要休息一下,暂时不回复这封邮件。”我确实以一种更文明的语气结束了回答,但是我想我最初的反应是,“先生,我相信你弄错了。”
围绕这些社区主导的项目有许多神话。一个是有机增长和有机贡献的概念,如果你想看到项目的进步和创新...你们公司中的许多人,你们并没有使用你们现在使用的所有这些开源项目,你们没有参与它们的创建。你在某个时候开始使用开源,你会想,“哦,好吧,我应该用什么呢?好的,我要安装所有这些东西,”或者“安装所有这些东西的点包。”
如果你希望事情变得更好,也许你所要做的就是等待,等待开源的有机过程让事情变得更好,神奇地从地球上冒出来。我发现构建软件的过程不是非常随机的,坦率地说是非常可重复的,因此被吸引到 Python 生态系统或 R 生态系统中工作的人与十年前当事物不流行时被吸引到生态系统中的人是非常不同的。当时有一种绿地开发和锻造新地面的感觉。从无到有。现在生成软件的过程已经完全不同了。
我看到的另一个问题是,这种观点认为,职业倦怠是一种夸张的说法,或者并不像报道的那样是一个大问题。如果维护人员或开发人员筋疲力尽,那也没关系,因为如果他们筋疲力尽,其他维护人员会作为随机过程的一部分涌现出来取代他们。这可能是因为如果一些糟糕的维护者筋疲力尽,其他人将会进入领导角色,但更多的情况是,他们将会进入一个已经负担过重的角色,因此他们将会发现自己处于最初导致筋疲力尽的相同情况。实际上,我们要弄清楚的是如何在这些项目中拥有五倍数量的核心开发人员和维护人员。
我认为另一个问题来自企业软件工程的态度,工程师被认为是可替代的资产,如果你计划一个总线因子为 1 的软件项目,或者如果这个人离开公司,整个项目都将失败,所以我们需要能够适应人们来,进入和离开项目。诚然,许多企业项目与开源项目相比,它们可能更直接,比如建立一个网站或建立一些关于如何建立它的非常明确的计划,而构建一些新的和创新的开源项目需要不同类型的工程师来真正推动前进。
可悲的现实是,这是 Tidelift 公司收集的一些数据,今天许多开源工作没有资金,或者人们被资助了大约 20%的时间来从事社区主导的项目,作为他们工作的一部分。即使这样也会很复杂。这里的另一个问题是开源项目中维护工作和创新工作之间的分裂。项目以这种快速的创新和变化开始,在某个时候,当它们变得非常受欢迎时,维护者,核心开发人员变成了维护者,他们本质上是踩水来维持现状。这也可能成为开发人员负担过重和精疲力竭的原因。
这是几年前带给福特的,可能是三年前,福特基金会写了一份名为“道路和桥梁:我们数字基础设施背后看不见的劳动力”的报告它谈到了 Heartbleed bug 和 OpenSSL 以及许多其他项目。许多人都震惊于 OpenSSL 的维护,它是互联网工作方式中的一个关键组件,可能会有令人震惊的错误,导致人们的安全信息暴露给互联网上的恶意团体。如果有更严格的测试和模糊测试,这些是可能出现的错误,如果投入足够的努力,这些问题可以在项目中被识别出来。
有一点,我不希望说服你,但我相信,社区主导的项目对你来说非常重要。你可能会使用由一家主要技术公司制作的许多项目,但社区主导的项目的运作方式是不同的,它给你更多的机会来影响项目的路线图和方向,以做出有意义的贡献,并帮助推动它们以有利于你未来工作的方式向前发展。
开发人员确实试图找到资助他们工作的方法。最主要的是找到一个企业赞助人,如果这个赞助人决定让你从事一个不同的项目,而不是奖励你的开源工作,这在某些方面可能会失败。开发人员会做咨询来支持他们的工作,这造成了一种紧张,我也这样做过。它在争取咨询合同以支付账单和在底层开源上花费时间之间制造了一种紧张关系,这种紧张关系在某种程度上推动了咨询工作。我的经验是,你最终没有足够的时间关注底层的开源项目。
在过去的几年里,我一直积极参与 Apache 软件基金会的工作。今年年初刚成为会员,挺有声望的。我是 Apache Software Foundation 的忠实粉丝,因为它为公司领导或行业领导的项目提供了一个框架,将社区治理和社区过程引入到可能由单个组织主导的项目中。通过采用 Apache 流程并加入基金会,那些一开始可能不是社区主导的项目也可以成为社区主导的项目。
ASF 运作的关键原则是如何以一种公开透明的方式做出决策。我们在协商一致的基础上运作。我们允许人们通过做出贡献来获得项目的影响力。如果您想在特定的 Apache 项目中变得有影响力,有一个非常直接的方法。你可以通过为项目做贡献来做到这一点。在许多项目中,特别是当项目由...如果你想在 TensorFlow 中做出重大改变,在很多情况下,你会去谷歌工作,以便能够对 TensorFlow 做出重大改变,而在一个社区主导的项目中,如果你做出了很大贡献,并在项目中获得了影响力,你就可以获得一个席位,成为一流的开发人员。
我确实担心,也许我们正处于这个临界点,事情可能会朝这个或那个方向发展。也许所有社区主导的开源项目都将消失,新的模式将是所有新的开源项目都由十大科技公司生产。这实际上是一个非常现实的未来可能性,开源开发者说,“我们不能让任何人资助我们的工作。”真的,只有谷歌和脸书,微软和网飞和亚马逊会生产我们使用的开源软件。这种前景确实让我有点难过。在 1995 年的电影《拆迁人》中,所有的餐馆都变成了塔可钟。我希望这不会发生在开源软件上,但我知道我的时间不多了,但我可能会占用你两三分钟的时间。
你有很多方法可以帮忙。你可以帮助开源开发者做得更好的两个主要方法。首先是付出你的时间。如果你的工程师有一个他们正在使用的项目,他们想为这个项目做贡献,他们对这个项目充满热情,给他们时间去做这件事...不仅要给他们时间,而且要奖励他们的工作和他们对项目的贡献,就像奖励他们的工作一样,建立内部项目。我见过的一个问题是,有时人们会说,“嘿,你可以在这个开源项目上工作,但有一个对业务非常重要的项目,所以你可以做出你的选择,但这个项目会让你得到提升,这种开源的东西,嗯,风险由你自己承担。”不要那样做。
另一种方法是,如果你没有工程师来做贡献,那就给钱。事实证明,向开源项目捐款是很复杂的,只需要知道在 Python 世界和 Python 之外的地方把钱给哪里,但是从 Python 世界开始,在过去几年里有一个新的组织,NumFOCUS,它提供了一个捐款的金融渠道,以支持像熊猫这样的项目,这帮助我们做了很多事情。我刚刚创建了一个名为 Ursa Labs 的新组织,来筹集资金进行面向数据科学世界的 Apache Arrow 开发。过去三年左右,我一直在从事 Arrow 项目。我们正处于一个转折点,我们真的需要建立一个更大的和专门的团队来建设。更好的数据科学计算基础设施,所以我认为在未来几年我们会看到更多这样的组织,为拥有它的组织提供更直接的资金渠道,为我们可以让人们工作的团队提供资金,全职开发开源软件。
最后一件事,因为我完全没时间了。他们会把我赶下台的原因是,有许多成功的故事和证明,即使是少量的资金和个人也可以产生巨大的影响。我真的很喜欢 Nathaniel Smith 的这个故事,他是 Python 的长期开发者。他得到了 Berkeley BIDS 两年的资助,从事 NumPy 和许多其他 Python 项目。靠着微薄的资金独自工作了两年。他本可以在旧金山市中心的一家科技公司工作赚更多的钱,但他选择了为伯克利投标公司工作,因为那是他的激情所在。只有他能够在这个领域做出巨大贡献。我们梦想着如果我们能做过去五年中十倍于我们所能做的事情,那将会是什么样子。
感谢您的关注。感谢使用开源软件。
问题和答案
演讲者 2: 非常感谢你的演讲和伟大的工作。我的问题是,你是否认为,我看到许多公司现在都有开发者支持者,他们在开源项目上工作,你认为这是帮助开源社区的一种方式吗,继续维护所有的软件和所有的工作?
韦斯·麦金尼 : 我想是的。当公司为开源项目做贡献时,它不仅仅是慈善。我认为建立贵公司的技术品牌还有其他好处。这是感觉良好的一部分,我们正在使开源世界变得更好,但这也是对你的组织的营销,你在世界上做得很好,你支持这些项目。这是双赢。我认为开发商主张,就游说而言...因为想要为开源项目做贡献的工程师可能不是最好的倡导者,他们会向管理层争论为什么这些贡献很重要,这会让他们更开心,更不容易跳槽到不同的公司。我认为开发者倡导者确实帮了大忙。
演讲者 3: 以熊猫为例,它已经发展了多年,我和一些对开源感兴趣的人谈过,但他们实际上不知道如何开始,这类事情可能需要多少启动时间。你对如何开始帮助这些类型的项目有什么建议吗?
韦斯·麦金尼: 耶。每个项目都不一样,比如入门的难易程度。我知道,特别是在熊猫方面,我们试图策划问题跟踪,并确定新手可以参与的工作,以帮助人们开始。有黑客马拉松,所以会议上会有黑客马拉松或短跑。这是一个很好的地方,在那里你可以见到参与这些项目的开发人员,通常 sprints 或 hackathons 将致力于帮助新的贡献者,并帮助人们编写他们的第一个 pull 请求。最近,我们为熊猫进行了一次全球文档冲刺,在 24 小时内产生了数百个拉取请求。这有助于获得某种形式的指导,或者至少参与开发团队。我总是告诉人们,如果他们不确定从哪里开始,可以联系邮件列表,或者如果你发现了一个看起来很有趣的问题,只需联系开发人员,然后说,“嘿,我很乐意做这个。怎么才能入门?”因项目而异。也许 Linux 内核可能有点难,但我认为许多项目通常都是受欢迎的,并且愿意帮助人们做出他们的第一份贡献并参与进来,即使是很小的贡献。没有贡献太小。
演讲者 3: 谢谢,韦斯。
韦斯·麦金尼: 谢谢。
改善数据科学和 IT 之间的合作关系
原文:https://www.dominodatalab.com/blog/improving-the-partnership-between-data-science-and-it
编者按:这是一系列文章的一部分,分享公司在成为模型驱动的道路上的最佳实践。一些文章将包含关于他们使用 Domino 的信息。
数据科学和 IT 之间的关系可能很复杂。虽然最终目标可能是相同的——帮助企业通过模型驱动的创新取得成功——但在如何实现这一目标的问题上常常存在矛盾。
一方面,数据科学家通过构建自动化或告知业务流程的模型来推动创新。为了做好工作,他们需要一个开放的环境,其中包含尖端工具、可扩展计算和探索。
另一方面,它提供并管理使这一切成为可能的技术环境。他们负责确保平台的安全性、可控性、可扩展性、合规性和成本效益。他们服务于许多内部客户,而不仅仅是数据科学。
由于这些独立的工作流程和优先级,摩擦可能会很快出现。考虑到它们的差异,数据科学和 IT 如何在构建模型驱动的组织中更无缝地合作?
最近几个月,数据科学的领导者在 Domino 数据科学弹出窗口和其他活动中分享了他们应对这一挑战的经验。在这篇博客中,我们分享了他们的一些策略,其中包括使数据科学变得真实和相关,认识并解决它所面临的问题和限制,以及积极准备一起进行模型“移交”。
让数据科学变得真实和相关
数据科学团队面临的一个持续挑战通常是让 IT 部门分配资源来实施和监控新模型。为了解决这一问题,Gap 前数据运营和工具高级总监 Matt Cornett 在任何资源请求中都包括了项目的业务背景,分享了模型如何集成到现有工作流中并为客户提供价值。“我不想让它变得抽象,”科内特说,“我喜欢把它与业务成果和客户体验联系起来。”
在视频托管服务公司 Vevo,数据科学总监 Eyal Golshani 特别指出了解决 IT 问题的用例。他说,这是展示数据科学和必要流程的价值的好方法。“一旦它看到这个过程是什么样子,以及它如何帮助他们实现目标,他们就会变得更受欢迎,更愿意帮助和宣传这个过程,”Golshani 解释说。
认识到 IT 问题和限制
是什么让您的 IT 团队夜不能寐?根据 Cornett 的说法,了解“它可能来自哪里”有助于他的团队提前解决潜在的问题,并在数据科学和 IT 之间建立更加集成的工作。例如,it 团队很容易想要锁定数据以保护客户信息和隐私。在任何项目开始时解决数据隐私和安全问题都有助于扫清道路,特别是当数据科学家寻求访问新的数据类型时。
科内特还建议寻找方法来减轻 IT 部门昂贵、耗时的活动。例如,Cornett 的团队通常会在要求 IT 部门构建一个新平台(如数据集市)之前创建一个原型。“这是一个帮助 It 降低成本和继续推进项目的机会,”Cornett 说。“我们的团队不用让 IT 部门花六个月的时间收集需求,而是可以利用这段时间进行迭代,然后为 IT 部门构建一组清晰的需求。”
此外,使用 Domino,Cornett 已经看到数据科学团队在几分钟内将模型投入生产,而不是等待数月并花费数万美元重新创建模型以在生产系统上运行。
同样,Trupanion 的数据科学总监 David Jaw 在最近接受 Domino 采访时分享了他的团队如何使用 Domino 数据科学平台将 IT 从资源调配或创建 API 等活动中解放出来,从而改善了协作。Jaw 说:“如果没有这种能力,我们就会一直用它来来回回。“相反,我们可以无缝地共同推进我们的共同使命。”
一起准备交接
随着模型从创新的实验室实验过渡到现实世界的产品,数据科学和 IT 团队必须协调一系列活动,从如何将模型集成到下游系统到监控模型漂移。领导晨星定量研究团队的李·戴维森和公司技术和产品分析主管杰夫·赫希密切合作,确保他们的团队“尽早并经常地整合”以生产新模型。以下是他们采取的几个步骤:
- 从一开始就概述项目阶段、接触点和合作方式。在晨星,团队根据五个阶段跟踪项目:
- 探测
- 积极研究
- 模型开发
- 生产化
- 启动和维护
Quant 团队在项目进行到每个阶段时都会定期更新它,让他们了解进展情况。在开发阶段,当需要积极的 IT 支持时,Quant 团队从其更加开放的、以研究为导向的过程转变为 IT 团队使用的敏捷方法。
- 勾勒出移交将如何进行。例如,研究人员将负责交付生产级和经过全面测试的代码,还是只需要提供一个原型?随着时间的推移,需要什么过程来帮助那些没有建立模型的人维护模型性能?“几年前,我们主要是凭直觉来做这件事,结果带来了一些挑战和压力,”戴维森说。“我们现在对这些问题越来越清楚了。”
- 创建移交期间所需活动的清单,例如执行 QA 测试或共享 Jupyter 笔记本,并确保员工具备密切合作的技能。“在交接发生的地方有一个灰色区域,”赫希说。“两个团队都需要更多地向中间靠拢:例如,IT 组织需要确保其 QA 人员能够解释 Jupyter 笔记本的结果,而数据科学家需要学习 IT 工程师的一些技能。”
在成为模型驱动的过程中有很多移动的部分。正如这些数据科学和技术领导者发现的那样,花时间改善沟通、讨论挑战和明确责任可以在减少摩擦和帮助他们更快更有效地实现目标方面带来丰厚的回报。
了解更多信息
- 在芝加哥多米诺数据科学展上聆听晨星的专题讨论,了解数据科学和 IT 合作的更多方式。
- 听 Matt Cornett 和 Eyal Golshani 在旧金山的 Domino Data Science Pop-up 上发言,听听他们关于与 IT 合作的完整演示。
- 阅读 David Jaw 关于 Trupanion 的工作成为模型驱动的博客或查看他的演讲,在 Trupanion 自动裁定兽医索赔,最初于 2019 年 5 月在 Rev 2 数据科学领袖峰会上发表。
追逐紫色独角兽
原文:https://www.dominodatalab.com/blog/in-pursuit-of-purple-unicorns
我们认识的许多分析经理称他们最大的挑战是招聘数据科学家。既然“数据科学家”是“21 世纪最热门的工作”,他们经常将问题归咎于需求过多
这是一个方便的解释,但它低估了经理们自己对这个问题的责任。在我看来,这个问题的最大原因之一是设计了一个有太多技能要求的角色,这几乎是不可能的。
无论你是否接受这种解释,有几个创造性的策略可以让分析经理希望数据科学家发挥的各种功能变得更容易。下面我描述三个。
问题:所有东西和厨房水槽
虽然具体情况因地而异,但我们认识的一位分析经理希望他的数据科学家具备以下技能和能力:
- 统计数字
- 算法(例如机器学习)
- 编程语言(例如 Python、R)
- 数据技术(如数据库)
- 工程/基础设施(例如 EC2、web 服务)
- 领域知识(尽管这是可以获得的)
不幸的是,他发现几乎不可能招到这样的角色。我想那是因为他为一只紫色的独角兽设计了一个角色。什么是紫色独角兽?一些我们都希望存在但却不存在的东西(或者是如此罕见以至于不存在)。
我的观点是,所谓的数据科学家往往是一个设计拙劣的想法。技能和能力过于广泛和多样,永远不会有足够的数据科学家。高管们没有阐明角色、流程设计或技术,而是简单地将更多必需的技能堆积到工作规范中。这里有一个“一切都是厨房水槽”方法的典型例子。对于那些想跳过链接的人来说,职位描述包括从 SQL 到“编程的高度熟练”到分析大型数据集的经验到统计和特殊数据的经验。
高管们没有阐明角色、流程设计或技术,而是简单地将更多必需的技能堆积到工作规范中。
例如,对工程和基础设施技能的要求,使得工作所需的工程知识大幅提升。有百分之多少的统计专家也有那种工程能力?即使有百分之三十或四十的人这样做了(这不太可能),当更好的技术可以轻松解决这个问题时,公司也不必要地限制了他们的候选人。
当然,这是在巨大需求的背景下发生的。我不会重复我们反复阅读的所有统计数据,但值得记住的是,在给角色增加更多要求的同时,公司正在寻找比以往更多的数据科学家。
让狩猎变得更容易
这里有三种方法可以缓解数据科学家是紫色独角兽的问题:
-
角色分解。最成功的分析公司不是将越来越多的技能集中在一个单一的角色上,而是考虑他们在一个项目中需要哪些特定的技能和能力。然后,他们可以为一个拥有在野外更频繁(自然)出现的技能组合的团队组合角色。
也许你需要一个在统计技术和解决问题方面有深厚功底的分析师。那应该更容易找到。然后,您雇用一名知道如何访问、清理和管理数据源的数据专家,以及一名可以编码和设置基础设施的技术人员。
总的来说,随着【数据工程师】角色与【数据科学家】角色的区分,我们越来越频繁地看到这种情况。他们都有对目标的坚定承诺,但是分类技能更容易找到。
角色分解需要更多的协作。我们看到这种情况发生在文化层面——数据科学家正在离开他们的孤岛,与他人合作——以及技术层面,这使得数据科学家更容易在项目上合作。 -
Provide data analysts and scientists with technology and tools to automate parts of their work. Why require a data scientist to spin up an EC2 cluster, for instance, when that process can be automated? By not automating it, you are adding a new skill set to the job requirements for your data scientists, in this case infrastructure management. Given how hard data scientists are to find, you want to keep these additional skill sets to a minimum and tools and technology are a key way of doing that. (Imagine if to be a taxi driver you had to be able to build a car.)
这需要在工具和技术上的投资,这让太多的公司感到不舒服。根据我们的经验,在数据科学方面做得最好的公司会将分析师工资的 30%到 40%用于装备他们的工作。
-
Hire data scientists and analysts based on the abilities that matter most for the job. Don’t create a laundry list of everything required to overcome every obstacle between data and impact on the enterprise.
而是寻找深度的好奇心和强大的问题结构化/解决能力,以及统计学、数据科学算法和一些编程能力——足以用 r .排除较重的工程技能(如基础设施、数据工程)。不要被编程能力冲昏头脑,因为这些是可以补充的。换句话说,在我的职业生涯中帮助雇佣了很多这样的人,我的一个主要观察是,一些核心能力比具体技能更重要。技能是可以学习的。能力往往更与生俱来,也更有力量——它们是真正推动一个人前进的引擎。在这些能力中,可能最重要的是以一种聪明的方式提问,帮助你找到答案。
技能是可以学习的。能力往往更与生俱来,也更有力量——它们是真正推动一个人前进的引擎。
我认为 Rob 在采访的最后很好地说明了这一点。
我们认为这些方法一起使用比无休止地寻找更多的紫色独角兽更好。简而言之,主题是从一个更加功能化的角度来看待您希望数据科学家实现的目标,并使用各种工具而不仅仅是一个角色来为此进行设计。
通过利用混合管道、并行化和 GPU 加速来提高复杂模型的速度
原文:https://www.dominodatalab.com/blog/increasing-model-velocity-for-complex-models
数据科学正面临着对 CPU 周期的巨大需求,因为科学家们试图处理复杂性增长速度超过摩尔定律的数据集。考虑到快速迭代和重新训练的需要,几年来,模型复杂性已经超过了可用的计算资源和 CPU,并且这个问题正在快速增长。数据科学行业将需要采用并行化和 GPU 处理来高效利用日益复杂的数据集。
鉴于最新模型越来越复杂,任何在大型数据集上进行机器 学习(ML)的企业最终都将面临这一挑战。像 AlexNet 这样的模型有 61M 的参数和超过 600M 的连接。尝试将其与 ImageNet 中的 120 万幅图像进行对比,你会遇到一个巨大的计算挑战。AlexNet 是下图中最简单的模型之一——想想今天的 SOTA 模型需要什么。
问题是计算需求——这是减缓模型训练的原因。计算需求是基于模型复杂性和数据集大小的函数,用于训练复杂模型的 CPU 需求的增长速度超过了摩尔定律。如果我们看看从 AlexNet 到 AlphaGo Zero 的计算需求,我们会看到一个指数级的增长,三至四个月翻一番。相比之下,摩尔定律有两年的倍增期。自 2012 年以来,最新模型的计算需求增长了 300,000 倍以上——摩尔定律只会产生 7 倍的增长。
从 2013 年的 AlexNet 到今天的 AlphaGo Zero,计算需求不断增长的图示;数据点的指数拟合给出了 3.43 个月的倍增时间,如 Kozma,Robert & Noack,Raymond & Siegelmann,Hava。(2019).受大脑能量管理启发的情境智能模型。567–572.10.1109/SMC.2019.8914064
为任务找到合适的框架
当您训练预测模型时,您会经历从预处理到模型训练、模型验证和操作化的阶段。传统的方法是端到端地使用 Spark ,投入更多的计算资源来解决问题,然后等待结果。但是,如果您为管道的不同部分使用不同的框架,您可以划分工作,并为每个工作使用最好的工具来处理每个阶段。
混合管道应对现代挑战
如果您试图围绕一个单一的工具来编排您的整个模型生命周期,您将会受到“这个工具能做什么?”心态。切换到混合管道可以让您自由地为每个阶段选择最佳和最有效的工具。维护集群也非常昂贵。如果您有一个包含 50 个工作节点的本地 Spark 集群,您的管理员会希望将尽可能多的工作负载放在该集群上,因为企业需要支付其计算和维护费用。这反过来意味着群集可能会被大量利用并且资源有限。
另一方面,如果您每周或每月都在重新培训您的模型,而不是维护那些在您需要之前会耗尽资金的资产,您可以寻找一些方法来加速运行,然后根据需要取消集群的供应。例如,如果您每天收集数据,每周重新训练模型,您可以设置一个 GPU 加速的 Spark 集群,该集群在周日自动供应,执行管道,并在完成后取消供应。这不仅可以节省资金,因为您只需在需要时为集群付费,更重要的是,使用 GPU 加速可以保证集群在更短的时间内完成流水线,从而节省更多资金。
Spark 是由加州大学伯克利分校创建的通用计算引擎,是并行大数据处理领域的公认领导者。SparkSQL 引擎是其他任何引擎都无法比拟的。但是 Spark 的 ML 库不像其他框架那样先进,而且由于其特定的数据处理范例和 API,Spark 的学习曲线有些陡峭。从这个意义上说,Spark 生活在自己的世界里,而像 Dask 和 Ray 这样的挑战者一直在稳步增长。
与 Spark 相反,Dask 最初的设计原则是“不要发明任何东西”。这个决定背后的想法是,一直使用 Python 进行数据分析的开发人员应该对使用 Dask 感到熟悉,并且加速时间应该是最短的。Ray 是加州大学伯克利分校的另一个项目,由两个主要组件组成——Ray Core,这是一个分布式计算框架,以及 Ray 生态系统,广义而言,这是许多与 Ray 打包在一起的特定于任务的库(例如,Ray Tune——一个超参数优化框架,用于分布式深度学习的 RaySGD,用于强化学习的 RayRLib 等。)
Spark 仍然非常适合 ETL 工作负载,但 Ray 更适合强化学习等特定任务,Dask 在对 Pandas DataFrames 和 NumPy 数组的开箱即用支持方面处于领先地位。你需要能够挑选最好的。
关于框架之间的差异,请参见: Spark、Dask 和 Ray:选择正确的框架
加速速度
由于大多数公司使用的是遗留的基础设施,使用多种工具和框架还不是一种常见的做法。如果您有一个 Spark 集群需要它来管理,那么您可能不得不使用 Spark——获取其他任何资源都是一个 IT 难题。但是在数据科学中,你需要敏捷,如果到了紧要关头,要有快速失败的自由。
数据科学是一个非常动态的领域。如果您想尝试一种新的并行处理框架,您不希望等待 6–7 周的时间来调配和配置集群。最糟糕的情况是,如果你的想法在使用 IT 资源并等待数周后仍未成功,你将失去所有的时间,并且你在公司的信誉可能会受到影响。你想让尝试新方法变得容易。
此外,要解决计算量大的问题,不能只依靠快速 CPU 和混合流水线。对于像网格搜索和超参数调整这样的任务,一般来说,你需要成百上千次地重新训练你的模型。你可以并行计算,或者使用 GPU 加速,或者两者都用。如果不使用并行,您将需要越来越大的计算实例。不是一天重新训练你的模型,而是一个月。这对模型速度不好。
转向并行和 GPU 处理
对于 ML 项目,许多问题是基于矩阵的代数计算,有大量简单的数学计算。GPU 的一个优势是,它不是有十几个或二十几个核心来计算值,而是有数百个核心,可以非常快速地进行非常基本的计算。这是一个非常适合 ML 工作负载的解决方案——您可以将矩阵数学卸载到 GPU,同时使用 CPU 进行更多的顺序计算。麻省理工学院的 Neil C. Thompson 和 Kristjan Greenewald 在 深度学习的计算极限中讲述了 CPU 的挑战和 GPU 的优势。
人们使用 GPU 进行模型训练已经有一段时间了。但是,试图建立一个可以协调多台机器和 GPU 加速的基础设施是非常复杂的——编写代码来分布和管理多台机器上的 GPU 执行真的很难。这里的创新在于,我们创建了特定的加速器来管理分布式并行化框架。NVIDIA 为 Apache Spark 推出了 RAPIDS 加速器,为 Spark 增加了 GPU 加速。Dask 和 Ray 等框架现在可以处理并行化,并与 Tensorflow 和 PyTorch 等 GPU 框架集成,以提供并行化的 GPU 执行。我们能够以前所未有的方式将并行化和 GPU 加速结合起来。驾驭 GPU 加速的分布式处理的能力对于在合理的时间内打破训练复杂模型的限制变得至关重要。
结论
展望未来,模型的规模和复杂性只会增加。这一领域的公司并不是因为新的和新奇的东西而试图获得模型驱动,他们这样做是因为竞争压力让他们别无选择。
如果您想成为一家领先的公司,您应该采取一种方法,通过对您的数据进行分区,使用 GPU 设置多台机器以闪电般的速度处理代数,并部署一种支持您轻松供应和管理不同框架和工具的能力的基础架构,来充分利用当前和新兴的工具。
当您准备好采取下一步措施来加速您的数据科学计划时,请考虑您将如何实现一个由 GPU 加速支持的分布式处理混合管道。当您着手下一个项目时,您可以考虑每种方法的不同功能,并考虑在没有太多管理或 IT 难题的情况下合并多个框架的方法。通过考虑我上面讨论的要点,您将能够使用越来越复杂的模型交付及时的结果。
解读凯特·克劳福德的《偏见的烦恼》
原文:https://www.dominodatalab.com/blog/ingesting-kate-crawfords-trouble-with-bias
凯特·克劳福德 在最近的旧金山城市艺术和演讲讲座上讨论了偏见,讨论的录音将于 5 月 6 日在 KQED 和当地分支机构播出。多米诺的成员是城市艺术讲座的现场观众。这篇 Domino 数据科学领域笔记提供了从 Crawford 的城市艺术演讲和她的 NIPS 主题演讲中摘录的见解,为我们的数据科学博客读者提供了额外的广度、深度和背景。这篇博客文章涵盖了 Crawford 的研究,其中包括作为社会技术挑战的偏见、系统在接受有偏见的数据时的含义、模型的可解释性以及解决偏见的建议。
凯特·克劳福德的《偏见的烦恼》
去年,达美乐的首席执行官在全公司的行业新闻讨论帖中发布了一个链接,链接到凯特·克劳福德的“偏见带来的麻烦”NIPS 主题演讲。整个公司的多米诺骨牌每天都在讨论行业动向,一些团队成员还参加了 Kate Crawford 最近在三月份与 Indre Viskontas 的 AI 讨论。5 月 6 日将在 KQED 和当地分支机构播出城市艺术与讲座讨论的录音。这篇博客文章涵盖了演讲的主要亮点,包括当系统训练和接受有偏见的数据时的影响,偏见作为一种社会技术挑战,模型可解释性(或缺乏可解释性),以及如何认识到数据不是中立的,作为解决偏见的关键步骤。这篇文章还引用了凯特·克劳福德(Kate Crawford)在 NIPS 上的主题演讲,以了解更多背景信息,并提出了三条解决偏见的建议。这些额外的建议包括使用公平辩论,与机器学习以外的人合作创建跨学科系统,以及“更努力地思考分类的伦理”。
接受过去偏见的系统培训:意义
在城市艺术讲座的早期,Indre Viskontas 要求 Kate Crawford 提供关于算法如何影响人们的额外背景。克劳福德提供了红线作为一个例子,说明当任何系统被训练并接受基于过去偏见的数据时会发生什么。她讨论了 20 世纪 30 年代和 40 年代美国抵押贷款行业的红线是如何不给居住在以非洲裔美国人为主的社区的人贷款的,以及如何
“我们看到财富从黑人人口向白人人口的巨大转移……非常深远……这是民权运动的关键部分。最终通过了《公平住房法案》。
然而,当有系统可能在数据集上训练,但仍然有过去的偏见,那么就有可能在今天看到过去偏见的回声。Crawford 还提到了关于亚马逊当天送达服务的彭博报告如何表明“低收入黑人社区,即使在市中心,他们也无法获得当天送达……这几乎就像是这些旧红线地图的复制”。克劳福德表示,她过去住在波士顿,当时在她的社区里,有许多服务,但后来
“如果你在岩石街那边,那就没有服务。这是一个非凡的时刻,你意识到这些长期的种族歧视历史成为我们的算法系统摄取的数据模式,然后成为现在和未来的决策者。因此,这是一种方式,我们开始看到这些基本形式的歧视变成了这些存在于今天人工智能基础设施中的幽灵。”
这促使讨论转向围绕中性数据以及数据是否有可能是中性的辩论。
中性数据?一个社会技术问题。
维斯康塔斯指出,“计算机不可能有偏见”。这是客观的。”存在。维斯康塔斯还提到了 Twitter 机器人,这些机器人已经从他们的 Twitter 环境中学会了种族主义,并问克劳福德,“在训练这些算法方面,我们需要考虑什么?”Crawford 回应说,“该做什么”正在像 FATML、这样的会议上进行辩论,人们在那里讨论“我们是如何开始看到这些偏见模式的?以及如何实际纠正它们”。然而,克劳福德也指出,即使定义什么是“中立”也不容易,特别是如果偏见背后有“几十年,如果不是几百年”的历史,然后“你在重置什么?底线在哪里?”克劳福德主张将这些偏见和系统视为社会技术。克劳福德还在她的“偏见的麻烦”主题演讲中讨论了作为社会技术问题的偏见,其中偏见是“与分类更一致的问题”。
在“偏见带来的麻烦”主题演讲中,她还举例说明了分类是如何与特定时代或文化的社会规范联系在一起的。克劳福德引用了一位 17 世纪的思想家是如何指出有十一种性别的,包括女人、男人、神、女神、无生命的物体等等。这在今天看来可能有些武断和可笑。然而,
“分类工作总是文化的反映,因此它总是有点武断,它的时代和现代机器做出的决定从根本上把世界分成几部分,我们对这些部分的去向所做的选择将会产生后果”。
作为性别分类的现代对比,Crawford 还在 NIPS 主题演讲中指出,与四年前提到两种性别相比,脸书在 2017 年提到了五十六种性别。然而,在城市艺术讲座中,克劳福德指出,认识到数据不是中性的,是解决偏见的一大步。
模型可解释性或缺乏可解释性
在 City Arts talk 中,Viskontas 提出了一些后续问题,这些问题涉及根据有偏见的数据训练的算法可能会犯代价高昂的错误,以及是否有机会重新思考输入算法的数据。Crawford 讨论了模型的可解释性,引用了一个丰富的 Caruana 研究,他们创建了两个系统,一个是不可解释的,另一个是更可解释的。一个更容易解释的方法让研究小组看到他们是如何达到这一点的。例如,Crawford 表示,他们能够发现为什么算法会将一个本应立即被送入重症监护的高风险群体送回家。因为该团队有一个可解释的系统,他们能够看到,从历史上看,有一个极高风险的群体总是“被分成重症监护病房,因此没有数据可供[算法]学习”,因此,该算法表明高风险的人应该被送回家。
根据 Rich Caruana 等人的论文,“可理解的医疗保健模型:预测肺炎风险和住院 30 天再入院”
在机器学习中,通常必须在准确性和可理解性之间进行权衡。更精确的模型(如提升树、随机森林和神经网络)通常是不可理解的,但更可理解的模型(如逻辑回归、朴素贝叶斯和单决策树)通常具有明显更差的准确性。这种权衡有时会限制模型的准确性,而这些模型可以应用于医疗保健等任务关键型应用中,在这些应用中,理解、验证、编辑和信任学习到的模型非常重要。在肺炎风险预测案例研究中,可理解模型揭示了数据中令人惊讶的模式,这些模式以前阻止了复杂的学习模型在该领域中的应用,但因为它是可理解的和模块化的,所以允许这些模式被识别和删除。”
克劳福德引用卡鲁纳的研究作为人们应该“对数据代表的东西更加挑剔”的原因,以及这是“真正的一大步”的原因。“要意识到数据从来都不是中立的。数据总是来自一段人类历史。”
解决偏见的三个建议:“偏见的麻烦”NIPS 主题演讲
虽然克劳福德讨论了数据在城市艺术和 NIPS 会谈中如何从来都不是中立的,但在 NIPS 会谈中,她提出了三个关键建议供从事机器学习的人考虑:使用公平辩论,创建跨学科系统,以及“更加努力地思考分类的道德问题”。克劳福德将公平取证定义为测试我们的系统,“从建立预发布试验开始,在这些试验中,你可以看到一个系统如何在不同的人群中工作”,以及考虑“我们如何跟踪训练数据的生命周期,以实际了解谁建立了它以及人口统计偏差可能是什么。”Crawford 还讨论了如何需要与机器学习行业之外的领域专家合作,以创建测试和评估高风险决策系统的跨学科系统。克劳福德提倡的第三条建议是“更加努力地思考分类的伦理”。克劳福德指出,研究人员应该考虑是谁要求将人类分为特定的群体,以及他们为什么要求进行分类。克劳福德列举了历史上的人们,像雷内·卡米尔,如何面对这些问题。卡米尔决定破坏二战中从死亡集中营拯救人们的人口普查系统。
https://www.youtube.com/embed/fMym_BKWQzk?feature=oembed
摘要
Domino 团队成员每天都审查、吸收和讨论行业研究。Kate Crawford 对偏见的研究包括“偏见带来的麻烦”NIPS keynote 和城市艺术和讲座讲座深入探讨了偏见如何影响开发、训练、解释和评估机器学习模型。虽然城市艺术和讲座是一个“面对面”的现场活动,但的录音将于 5 月 6 日周日在 KQED 和当地分支机构播出。
^(Domino 数据科学领域笔记提供数据科学研究、趋势、技术等亮点,支持数据科学家和数据科学领导者加快工作或职业发展。如果您对本博客系列中涉及的数据科学工作感兴趣,请发送电子邮件至 writeforus(at)dominodatalab(dot)com。)
Red Hat 关于利用数据专家的见解
原文:https://www.dominodatalab.com/blog/insights-from-red-hat-on-leveraging-data-experts
By Karina Babcock, Director, Corporate Marketing, Domino on October 29, 2019 in Perspective
编者按:这是一系列文章的一部分,分享公司在成为模型驱动的道路上的最佳实践。一些文章将包含关于他们使用 Domino 的信息。
近年来,数据科学家的角色已经成为摇滚明星。随着企业竞相成为模型驱动型企业,数据科学家的需求量很大。尽管越来越多的人认识到数据科学家的重要性和必要性,但许多企业领导人对数据科学家做什么以及他们如何建立模型的理解模糊不清。例如,他们可能知道模型涉及代码,但不明白构建模型需要不同于传统软件开发的技术和工具。
因此,市场上经常出现角色和工作期望不一致的情况。一家公司的数据分析师在另一家公司可能被称为数据科学家。对“公民数据科学家”(通常是才华横溢的软件工程师和分析师,他们使用直观的拖放工具来构建模型)的大肆宣传增加了混乱。当涉及到一些用例时,公民数据科学家是宝贵的资源,例如增强销售预测或重新设计营销活动,其中数据是干净地准备好的,并且结构一致。但在构建能够真正推动创新或创造核心竞争优势的先进模型方面,数据科学专家是无可替代的。
不幸的是,所有这些混乱让公司很难根据需要跨职能调动人才,造成开发先进模型所需的深层统计、编程和科学专业知识的巨大缺口,并影响人才的获取和保留。
公司能做些什么来解决这个问题呢?最近,我们就此话题采访了 Red Hat 的企业数据和分析副总裁 Heidi Lanford。Heidi 已经带领一些世界上最大的品牌(哈雷戴维森和 Avaya,仅举两个例子)成功地利用了他们的数据。现在,她正在帮助 Red Hat 这个最大的企业开源软件提供商走上模型驱动的快车道。她的工作重点之一是标准化所有数据专家的工作定义和职业道路,包括数据科学家、数据分析师和数据工程师,以解决这些问题。
以下是我们就红帽之旅采访海蒂的编辑版本。
Domino:是什么推动了您在 Red Hat 中标准化数据科学角色的工作?
Heidi Lanford: 我们有一个分析领导团队,每月召开一次会议。它包括每个职能部门(例如,我们的人员团队、财务、销售、营销、产品和客户体验)中最资深的数据和分析负责人。在每次会议上,角色和责任的话题都会不断出现。一个人从一个职能部门去面试另一个部门的空缺职位,团队成员发现不同团队的职位名称、职位级别和工作经历之间存在差异。(我们有两条路线——商业路线和技术路线。)这导致技能、培训、学位、经验和责任基本相同的人有不同的薪酬结构,并使人才跨职能流动变得很困难。
你是从哪里开始定义不同的职业道路的?
Heidi Lanford: 我们首先从标准化数据科学家角色开始。这些专家创建复杂的分析模型,并从数据中获得新的见解。一名团队成员绘制了一张网格图,建议在六个专业水平上进行角色升级。每个级别概述了八个不同领域知识的预期广度和深度:
- 数据科学背景
- 商业头脑
- 协作技能
- 通讯技能
- 创新技能
- 独立工作的能力
- 领导技能
- 编程语言,包括 R、SAS 和 SPSS 等统计语言,以及 Python 和 JavaScript 等脚本语言
鉴于我们的开源传统,我们高度重视协作和社区主导的努力。一旦分析领导团队成员完成这一初步映射,我们就发布一份形式文档,并征求团队其他成员的反馈。然后,我们查看了每个职能部门内的示例,讨论了特定个人将满足的标准,然后确认我们都同意这是一个准确的评估。
我们还在早期从我们的人员团队中引进了专家。他们帮助确保我们的工作符合 Red Hat 的工作描述,并为我们的工资级别提供行业基准数据。
然后,我们对我们的数据分析师做了同样的事情,他们使用数据分析技术来解决问题并收集跨功能领域的见解。我们再次为我们的数据工程师重复了这一过程,他们与数据科学家或数据分析师并肩工作,帮助处理、操作和准备数据。
有重叠吗?
Heidi Lanford: 数据科学家的角色和数据分析师的角色有些重叠。我们希望数据分析师有一些编程经验。然而,他们的工具将更多地用于商业智能和数据可视化方面,并具有一些 SQL/Adobe 分析经验。
我们还创建了一个新角色,称为分析解决方案主管,其工作是帮助最终用户采用新的模型输出。当然,我们正在努力让我们的技术专家,如数据科学家和数据分析师,提前销售这些概念。但是我们知道不是每个人都擅长这个。因此,我们有一个解决方案领导角色,负责帮助用例变得生动,传达模型输出的价值和好处。
您是否为您的数据分析师配备了自动化机器学习工具来支持建模工作?
Heidi Lanford: 通常,我发现组织所做的大部分分析都是数据分析,很少是预测建模、机器学习和人工智能用例。在进行数据分析时,有一些自动化的机器学习工具会很有帮助。然而,当您进入高级统计建模时,例如在我们的销售预测流程中,当专家数据科学家开发模型时,业务领导对模型输出更有信心。
听起来,现在每个角色都在相互补充,而不是像经常发生的那样相互竞争。你发现情况是这样的吗?
海蒂·兰福特:当然。理想的团队有一名数据分析师、一名数据科学家和一名数据工程师,他们与解决方案负责人一起并肩工作。数据分析师将需要更多的业务技能,并需要投入大量时间来了解业务中正在发生的事情。因此,如果你是人力资源方面的数据分析师,你不仅需要理解这些数字的含义,还需要了解如何根据这些信息改进或改变人力资源业务流程。相反,数据科学家将对他们使用的统计算法有深入的了解。
如此重大的变革很难获得认同。你是怎么做到的?
Heidi Lanford: 正如我前面提到的,Red Hat 有一种非常协作的文化。因此,当我们开始这项任务时,邀请分析社区的每个人,而不仅仅是几个人,来提供意见是非常重要的。在我们的分析领导团队就每个角色的职业道路达成共识后,我们与全球 100 多名社区成员分享了这些文档,征求他们的反馈。我们收到了一些很好的建议,例如分享 Red Hat 之外的数据科学方法知识(即演讲和发表文章),要求数据分析师具备演示技能,以及添加一些我们团队正在使用的其他语言。
我们还希望确保不在这些职业道路中的业务人员仍然具有基本的数据素养;例如,他们了解预测模型可以为他们做什么,样本大小如何影响输出,什么是置信区间,等等。我们意识到,如果我们把事情藏在心里,我们就不会得到我们想要的那种采纳和改变游戏规则的商业行为。
最终,标准化角色给你带来了什么好处?
Heidi Lanford: 明确员工的职业发展道路可以提高员工的满意度。数据专家可以从一个职能部门转移到另一个职能部门来接受新的挑战,而有了 Domino,我们就有了一个标准平台,他们可以使用这个平台与其他业务领域的同事进行协作。
在业务方面,标准化这些角色,让每个人都处理类似的数据,并将数据科学与各个职能部门联系起来,为我们提供了业务的企业视图,因此我们可以更有效地降低风险。零零星星地研究数据科学的组织无法跨职能部门建立联系。然而,从企业的角度来看,如果销售预测显示几个季度后某个地区出现问题,营销团队可以更快地采取行动来影响该轨迹,人员团队可以确保我们招聘到足够多的合适人员,并且我们可以调整我们的销售策略或解决产品问题。
了解更多信息
-
观看视频,了解更多关于 Red Hat 成为模型驱动的工作:
-
阅读 eWeek 案例研究了解 Domino 如何帮助 Red Hat 提高数据科学家的效率。
Domino 5.0:快速更新生产模型以获得最佳性能
原文:https://www.dominodatalab.com/blog/integrated-model-monitoring
在 Domino 5.0 中引入集成模型监控
作者 Patrick Nussbaumer,Domino 产品营销总监,2022 年 1 月 31 日, 产品更新
持续的漂移和精度监控对于 维持推动您业务发展的有效模型 至关重要。事实上,行业估计显示,不进行监控会导致大约 30%的业务价值损失。然而,DataIQ 进行的一项调查显示,只有 10.5% 的组织拥有针对漂移和质量的自动化模型监控。
事实证明,开发企业模型监控解决方案以确保所有模型都以最佳性能运行对于许多组织来说都是一项挑战。为什么?常见的挑战包括:
- 构建数据管道进行比较的复杂性
- 带有训练数据的预测数据,以及
- 基于真实数据的模型推理
- 创建仪表板以查看监控性能
- 分析大量特征以识别模型退化的来源
- 在修复开发中复制生产模型非常耗时
一些公司已经解决了这些问题中的一个或多个,但是当他们不得不一遍又一遍地重复这个过程时,他们面临着挑战,特别是当更多的模型进入生产时。这种从部署到监控到补救再到重新部署过程中的摩擦严重限制了 模型速度 。如果您有兴趣了解您的组织如何达到标准,请查看 模型速度评估 ,这是一种免费且简单的方法,可以确定您可能存在问题的地方。
Domino 是 企业 MLOps 平台,它无缝集成了代码驱动的模型开发、部署和监控,以支持快速迭代和最佳模型性能,因此公司可以确保从其数据科学模型中实现最大价值。
它是如何工作的
唯一的闭环开发-部署-监控-补救-部署流程
集成监控使构建监控管道变得简单。Domino 自动为部署的模型设置预测数据捕获管道和模型监控,以确保模型性能达到峰值。
开发-部署-监控
只需两行代码,数据科学家就可以保存特征、训练数据和预测,以便进行分析和监控。在训练期间需要一行代码来捕获训练数据,在 API 调用中需要另一行代码来捕获预测数据。
一旦部署了模型,监控的配置就很简单了。
只需选择培训数据,即可启用适当的版本和监控。
接下来,为数据和模型漂移配置检查和自动警报。
Domino 随后将连接到实时预测数据,并自动化一个连续的监控管道。一旦做出预测,Domino 将显示监控统计数据。
该模型在一个集中的仪表板中可见,该仪表板为模型、概要和漂移细节提供了一个单一的控制台。用户能够深入了解细节,并针对漂移特征和模型质量问题配置警报。
补救-部署
当一个模型的性能下降时,可以轻松地深入模型性能以了解更多详细信息。
当模型准确性出现问题时,Domino 会生成一个模型质量报告,其中包含可操作的见解,突出模型和数据中的问题。该报告包括大量分析,以帮助数据科学家了解和诊断漂移。
当您准备好修复您的模型时,可以使用您的模型的原始重构状态轻松地启动开发环境。
一旦您的工作空间启动,它将包含用于构建模型的原始代码、笔记本、培训数据和 docker 映像。还将加载调试、分析和与原始培训数据进行比较所需的生产数据。
一旦模型经过重新培训和性能补救,只需点击几下鼠标,即可重新部署和监控新的模型版本。
结论
Domino 专注于帮助组织提高模型速度,发布了第一个集成的闭环体验功能,以推动模型速度并保持数据科学模型的最高性能。具有帮助自动建立监控和预测数据管道的功能,与仪表板无缝集成;警报,以及生成可操作的洞察报告;以及快速设置开发环境以修复模型并使其重新投入生产的能力,组织能够专注于开发新模型,同时确保部署的模型能够提供业务价值。
安装或升级到 Domino 5.0 的新客户和现有客户将自动访问特定容量的监控数据,这样他们就可以开始使用闭环监控系统。客户可以与其销售团队合作,根据需要预测和购买更多容量。
关于作者
| | Patri****CK Nuss baumer 是多米诺数据实验室的产品营销总监。他拥有伊利诺伊大学香槟分校的电气工程学士学位和加州大学欧文分校的 MBA 学位。Patrick 在数据和分析行业拥有近 30 年的经验。 |
英特尔的 Python 发行版正在飞速发展,现在它已经进入了 Domino
原文:https://www.dominodatalab.com/blog/intels-python-distribution-is-smoking-fast-and-now-its-in-domino
多米诺刚刚完成基准测试英特尔的 Python 发行,而且速度很快,非常快。Intel 的 Python 发行版可以在 Domino 中使用。
英特尔的 Python 发行版
人们可能不知道英特尔有一个 Python 发行版。基于 Anaconda 发行版,英特尔的工程师使用英特尔数学内核库和英特尔数据分析加速库优化了流行的数学和统计软件包,如 NumPy 、 SciPy 和 scikit-learn 。英特尔继续与包括 Anaconda 在内的所有主要 Python 发行版合作,让所有 Python 用户都能广泛使用这些 IA 优化和性能加速。
英特尔性能指标评测结果表明,以前可能需要一个多小时才能完成的批量运行,现在仅需两分钟即可完成。当在 Jupyter 笔记本上工作时,由此产生的加速意味着过去需要几分钟才能计算的单元现在只需几秒钟。
Domino 基准测试英特尔的 Python 发行版
在 Domino,我们想在几个不同的场景中运行基准测试,看看加速会如何影响真实世界的数据科学程序。对于每个基准测试,我们运行了相同的实验,其中唯一改变的变量是所使用的 Python 发行版。
在 Domino 中很容易改变环境和硬件,所以改变环境来运行基准只需要几秒钟。
一旦我们有了一个采用英特尔 Python 的环境,我们就可以同时启动所有的基准测试,并且知道我们正在将环境作为变量进行隔离。此外,我们可以在越来越小的机器上运行复杂的作业,看看这是如何改变结果的。
我们运行的第一个基准测试使用 scikit-learn 从向量数组计算距离矩阵中的距离。每个基准测试在一个 16 核/120GB RAM 的机器上运行三次。
分配 | 平均完成时间 |
---|---|
标准 Python 2.7 | 12 米 17 秒 |
--- | --- |
英特尔 Python 3.6 | 2 米 17 秒 |
--- | --- |
英特尔 Python 始终以不到标准 Python 发行版 20%的时间完成运行。
我们运行的第二个测试在一个更小的共享盒子上使用了 Black Scholes 基准。该服务器有四个 CPU 和 16 GB 的内存。
分配 | 平均完成时间 |
---|---|
标准 Python 2.7 | 9m 21s |
--- | --- |
英特尔 Python 3.6 | 2m 50s 秒 |
--- | --- |
同样,使用英特尔的 Python 发行版节省了大量时间。即使每个实验节省七八分钟,也会导致研究结果的实质性改进。更快的结果允许更多的迭代,也确保研究人员不会在工作中分心和分心。当跑步时间从几小时缩短到几分钟时,这种差异就更有价值了。
Domino 中可用的英特尔 Python 环境
Domino 客户可以立即从英特尔的 Python 发行版中受益。我们已经在试用环境和云生产环境中创建了英特尔 Python 环境。
Plotly 和 Domino 的交互式图表
原文:https://www.dominodatalab.com/blog/interactive-charts-with-plotly-and-domino
我们使用了一台 IPython 笔记本,它使用 Plotly 的小部件来创建漂亮的交互式图表。请继续阅读,了解如何通过将 Domino 作为中央笔记本引擎,在您自己的笔记本中使用交互式图表——在防火墙后或云中。
我们做了什么
Domino 允许您在强大的云硬件上运行 IPython 笔记本会话,无需任何设置。我们在 Plotly 的朋友给了我们一个很棒的笔记本示例,展示了他们的笔记本小部件,我们把它上传到 Domino,这样你就可以玩了。
亲自尝试一下:
-
开始新的 IPython 笔记本会话
-
打开会话
-
打开笔记本
-
评估细胞和周围玩耍!
反光
我们的核心工程原则之一是尽可能利用现有技术,而不是重新发明轮子。这对我们有好处,因为它节省了我们做大量的工作!但这对我们的用户也有好处,因为这意味着他们可以获得现有工具的所有灵活性,并从整个生态系统的改进中受益。
在这种情况下:我们选择使用 IPython 笔记本,而不是构建我们自己的笔记本功能。因此,我们的用户可以利用 Plotly 交互式小部件,而无需我们进行任何额外的工程设计。现在我们有一个关于如何使用 Domino 创建交互式笔记本的好故事!
使用 jupiter 构建交互式仪表盘
原文:https://www.dominodatalab.com/blog/interactive-dashboards-in-jupyter
欢迎来到的第二部分“高级 Jupyter 笔记本技巧”在第一部分中,我描述了 magics,以及如何在“批处理”模式下计算笔记本以将其用作报告或仪表板。在这篇文章中,我描述了 Jupyter 笔记本的另一个强大特性:使用交互式小部件构建交互式仪表盘的能力。包含的示例托管在 Domino 数据科学平台上。
类固醇上的商业智能
为什么我们要给笔记本增加交互性?一个原因是使用更强大的工具来处理传统的商业智能用例。如果您在 SQL 之上构建仪表板,传统的 BI 工具非常有用,但是如果您想要可视化由一些更复杂的逻辑生成的信息,它们通常会有所欠缺。
通过笔记本中的交互式小部件,您可以使用 Python 的全部功能来表达计算和生成可视化——同时向最终用户展示“旋钮和转盘”,以便他们可以控制可视化的各个方面。从这个意义上说,你可以把笔记本作为任何人的轻量级“应用”。
ipywidgets 简介
添加小部件的功能驻留在 ipywidgets 包中,所以我们想从导入开始:
from ipywidgets import widgets
导入之后,您可以添加各种类型的 UI 元素。您可以将一个小部件想象成由两部分组成:
- 在输出单元格(例如,文本框)中呈现的 UI/HTML 元素
- 一个事件处理程序,让您指定当值改变时应该发生什么。在大多数情况下,您会希望定义一个 Python 函数,当用户更改输入时调用该函数,这样您就可以相应地更新笔记本的其他元素(例如,可视化)。
小部件的基本类型
- 文本输入:您可以使用
widgets.Text()
创建一个文本输入字段。.on_submit()
监听活动并调用一个函数来处理活动。
- 按钮:按钮部件的工作方式类似于文本输入部件。
- Interact:除了默认的小部件,还有“interact ”,它会根据您使用的参数自动生成一个小部件。
第一个参数是处理第二个参数的选定值的函数。第二个参数的类型将决定交互的形式。正如你所看到的:一个整数导致一个滑块。给出一个布尔值(interact(f, x=True)
)创建一个复选框。
您可以将小部件存储在笔记本的变量中,就像任何其他类型的值一样。这允许您将一个小部件的输入绑定到另一个小部件的值——中间可能有某种计算/操作。举个简单的例子:
我们创建了两个小部件,一个输入和一个输出。当输入小部件的值改变时,我们采用新值并更新输入小部件的值。通过这种方式,您可以创建更加复杂的交互。
交互式可视化
小部件的强大之处在于,当用户更改输入值时,您可以连接自己的 Python 函数来运行。除此之外,它还能让你对用户输入的变化做出动态响应。例如,
这种核心灵活性释放了将笔记本电脑用作仪表板的巨大潜力。例如,您可以公开小部件来过滤、分组或排序数据;然后,您的 Python 代码可以查询数据源、计算派生数据、使用 pandas 和其他优秀的包进行内存操作,然后使用任意数量的优秀 Python 可视化包呈现结果。
*这里有一个教程,让你开始使用交互式小工具。你也可以通过访问我在 Domino 平台上的项目,旋转一个 Jupyter 笔记本会话(在“笔记本”按钮下),并打开widgets
笔记本来玩我上面的例子。
把它放在一起
最后,我想将我上一篇文章中的概念(魔法、数据管道)与上面描述的交互式小部件结合起来。结果是笔记本中的一个迷你“应用程序”:用户可以提供一个域名,笔记本将 ping 该域名,并在图表上绘制响应时间。
下面是创建它的代码。你也可以通过访问我的多米诺项目,旋转 Jupyter 笔记本会话(在“笔记本”按钮下),并打开jupyter_demo
笔记本来自己运行它。
%matplotlib notebook
import pandas as pd
import matplotlib.pyplot as plt
from ipywidgets import *
from IPython.display import display
from IPython.html import widgets
plt.style.use("ggplot")
NUMBER_OF_PINGS = 4
# displaying the text widget
text = widgets.Text(description="Domain to ping", width=200)
display(text)
# preparing the plot
data = pd.DataFrame()
x = range(1,NUMBER_OF_PINGS+1)
plots = dict()
fig, ax = plt.subplots()
plt.xlabel("iterations")
plt.ylabel("ms")
plt.xticks(x)
plt.show()
# preparing a container to put in created checkbox per domain
checkboxes = []
cb_container = widgets.HBox()
display(cb_container)
# add button that updates the graph based on the checkboxes
button = widgets.Button(description="Update the graph")
# function to deal with the added domain name
def handle_submit(sender):
# a part of the magic inside python : pinging
res = !ping -c {NUMBER_OF_PINGS} {text.value}
hits = res.grep("64 bytes").fields(-2).s.replace("time=","").split()
if len(hits) == 0:
print("Domain gave error on pinging")
else:
# rebuild plot based on ping result
data = hits
data = data.astype(float)
plots, = ax.plot(x, data, label=text.value)
plt.legend()
plt.draw()
# add a new checkbox for the new domain
checkboxes.append(widgets.Checkbox(description = text.value, value=True, width=90))
cb_container.children=[i for i in checkboxes]
if len(checkboxes) == 1:
display(button)
# function to deal with the checkbox update button
def on_button_clicked(b):
for c in cb_container.children:
if not c.value:
plots.set_visible(False)
else:
plots.set_visible(True)
plt.legend()
plt.draw()
button.on_click(on_button_clicked)
text.on_submit(handle_submit)
plt.show()
所以我结束了这篇博客,但并不是因为这就是我要讲述和展示的全部内容。我可以继续,但我更希望你能试一试。请在评论中分享你在自己的项目中工作时发现了什么新奇的笔记本选项。
带有 knitr 和 htmlwidgets 的交互式仪表盘
原文:https://www.dominodatalab.com/blog/interactive-dashboards-with-knitr-and-html-widgets
介绍
R 的 htmlwidgets 是一个漂亮的 R 包,可以让你轻松地生成交互式可视化。已经有了用于交互式时间序列图、3D 图、地图和网络图的小部件。
对于那些不知道的人来说,Domino 是一个运行、共享和部署分析模型的平台(用 R、Python 或其他语言)。除此之外,Domino 允许您在功能强大的机器上运行代码,并将存储您的结果,以便您可以与其他人共享。
因为 Domino 将存储代码运行时生成的任何结果(图像、HTML 文件等),并且 htmlwidgets 可以嵌入到 HTML 文件中,所以我们可以在 Domino 上运行 R 代码来生成完全托管的交互式仪表板,比如网络图或时序图。
这意味着您的仪表板现在可以直接由您的代码驱动,并且计算和可视化在同一个地方发生。
可视化计算结果而不是原始数据
随着公司将更复杂的数据科学用于内部分析,他们发现传统的商业智能工具不足以满足他们的可视化需求。这些传统工具是基于这样一个假设而设计的,即您希望可视化数据库中的现有数据,而不是可视化来自模型的计算结果。Domino 通过将代码执行与结果可视化结合起来解决了这个问题。
Domino 的可视化方法只是呈现代码生成的任何文件,无论是 png、pdf 还是整个 HTML 文件。这种灵活性使得从代码中生成丰富的可视化非常容易。对于下面的例子,我们简单地使用了knitr
来编织一些利用了htmlwidget
示例代码的 R 代码。Domino 中每次不同运行的结果都是不同的 HTML 文件,Domino 知道如何将其显示为交互式仪表板。
实施细节
我们只遇到了一个小问题。当您从交互式 R 会话中使用 htmlwidget 时,它将生成一个自包含的 HTML 页面,该页面包含呈现该 widget 所需的所有 JS 文件。但是当您编织一个呈现 htmlwidget 的 HTML 文件时,您必须在 HTML 中显式地包含支持的 JS/CSS 文件。例如,对于 dygraph 小部件“prettyprint lang-html ”,只需将lib
目录及其内容包含在 Domino 项目文件夹中,一切都将完美运行。
结论
htmlwidgets 将是数据科学家武器库中的强大武器,尤其是在与非技术利益相关者共享工作时。将 htmlwidgets 与 knitr 和 Domino 等工具相结合,您可以轻松地将您的 R 代码转换为托管的交互式仪表盘,并解决复杂的分析用例,这在使用简单的商业智能工具和技术时是不可能的。
烧杯和竞技表演带来更好的交互式数据科学
原文:https://www.dominodatalab.com/blog/interactive-data-science
Domino 提供对 IPython/Jupyter 的支持已经有一段时间了,但是我们最近增加了对两个更新的、新兴的交互式数据科学工具的支持: Beaker Notebooks 和 Rodeo 。这篇文章简要概述了每个工具,并描述了如何在 Domino 上使用它们。
触手可及的电动工具
Domino 背后的动机是让数据科学家专注于他们的分析,而不用担心基础设施和配置,从而提高他们的工作效率;通过在一个中心位置组织和跟踪工作,促进团队之间的协作和共享。
为此,Domino 现在允许您在大型机器上进行竞技或烧杯会话,并集中存储您的文件和笔记本,以便更容易跟踪、共享和评论它们。
烧杯
Beaker Notebook 是来自 Two 适马开源团队的笔记本应用,在某些方面类似于 Jupyter/IPython 笔记本。但是除了支持许多不同语言的内联代码、文档和可视化之外,Beaker 还允许你混合语言。没错:一个笔记本可以混合他们支持的任何语言的代码,Beaker 的灵活互操作功能可以无缝地在语言之间翻译数据。这甚至适用于数据帧和更复杂的类型。
在引擎盖下有很多东西在起作用——这是相当神奇的。
这使得 Beaker 成为那些相信“使用最佳工具完成工作”的人的终极武器:一个单一的分析工作流可以使用 Python 进行数据准备,使用 R 进行复杂的统计分析,使用 HTML 和 D3,或者使用 Latex 进行漂亮的可视化和演示。
Beaker 支持 R、Python、Julia、Scala、HTML、Javascript、NodeJS Latex、Java、Groovy、Clojure、Ruby 和 Kdb——尽管目前 Domino 对 Beaker 的支持只包括其中的一些。想看别人就告诉我们!
你可以在 SciPy 2015 上观看 Beaker 的一位创造者的视频。您还可以在 Domino 上自己使用 Beaker,而无需任何安装或设置。为此,您可以创建自己的项目。
- 点击“运行”仪表板上的“笔记本”菜单,开始烧杯会话。
2. When the server is ready, click the "Open session" button in the right pane.
3. Create a new notebook, or import one of Beaker's examples, or use the file menu to browse to "/mnt" and choose one of the files in our project ( viz.bkr
or interop.bkr
)
项目中的viz.bkr
笔记本展示了一个使用 Python 计算一个图形,然后用 HTML/D3/Javascript 在笔记本中可视化的例子。
interop.viz
笔记本展示了 Beaker 在语言间翻译数据的灵活性的一些很好的例子。
竞技
Rodeo 是来自 yHat 的人们的开源 Python IDE。它回答了这样一个问题,“Python 有没有类似 RStudio 的东西?”
Rodeo 就是这样:它是一个用于编辑 Python 文件的基于 web 的 IDE,在一个界面中为您提供了代码编辑器、绘图查看器和文件浏览器。与为构建大型软件系统而设计的 Python 编辑器不同,Rodeo 是为用 Python 进行数据科学而定制的——尤其是通过其内置的绘图查看器。
你可以在我们的帮助网站上阅读更多关于我们对竞技表演的支持。
数据科学家访谈:来自 Filepicker 的 Jason Toy
原文:https://www.dominodatalab.com/blog/interview-with-jason-toy-from-filepicker
我们最近采访了面向开发者的云文件管理平台 filepicker.io 的 CEO Jason Toy。此前,Jason 是话题影响者平台 Socmetrics 的首席技术官和联合创始人。作为 Socmetrics 的首席技术官,Jason 和他的团队为客户提供商业智能,使他们能够从现有客户身上获取更多价值。
你是如何对数据科学产生兴趣的?
我有相当的技术背景,已经写了将近 15 年的软件。我开发了软件;我做过基础设施、DevOps 和一大堆网站建设。但是对我来说最有趣的东西一直是数据。我们将如何利用数据来改进我们的产品和服务?我们如何更好地从数据中学习?数据分析是当今任何业务中最重要的部分之一。有如此多的数据涌入,我们需要工具来跟踪所有这些数据,还需要工具来获得洞察力。通过 Socmetrics,我们非常关注客户细分和社交媒体,将这两个数据集结合起来,然后进行分析。所以我花了很长时间思考和建立分析平台。
日常工作中需要哪些技能?
处理数据的首要能力是数学。你需要对数学概念有非常强的理解,优秀的编程技能,以及分析思维。数据科学有很多不同的名称:数据科学、机器学习、分析、大数据、人工智能、统计学等。
我们经常听说,要成为数据科学家,你需要成为独角兽,你同意这种说法吗?
你不需要成为独角兽,但如果你能成为独角兽,你将处于非常有利的地位。通常大多数人选择进入数据科学的一个特定领域。有工程方面;您可以将专门清理数据和移动数据作为一项全职工作。然后是分析部分,数据科学家正在处理数据,寻找见解,并测试不同的假设。第三个是理论上的,这是数据科学家实际上提出算法的时候。这种用例在学术界和拥有大型研究团队的大公司中更常见,在较小的企业中你不会看到它被大量使用。你可以把田地分割成不同的部分。成为独角兽固然很好,但我建议专注于自己的优势,在那个特定的领域深入钻研。
在你过去的分析工作中,哪一项技能是你运用得最多的?
我在“应用”或实践方面的技能更强,从构建系统到处理数据到进行实际分析的任何地方。我有一个计算机科学的本科学位,但没有一个可以真正提出新算法的博士学位。那是一个艰难的领域。有很多人在研究这个问题;谷歌、微软和所有其他大公司都有庞大的研究团队。一般来说,大多数数据科学家不会从事研究工作。
有没有什么作品可以和我们分享,个人视角?
我在以前的公司开发了一些有趣的产品。我之前提到的其中一个是 Socmetrics,另一个是 Truelens 。我还在 filepicker.io 建立了不少基于机器学习的内部营销工具,以帮助我们在营销方面做出更好的决策。
在复杂的企业环境中,数据科学面临哪些挑战?
大型企业面临的挑战之一是,为他们的所有数据找到一个集中的位置。大型企业有如此多的数据“孤岛”,通常没有足够的知识共享。如果您可以将所有数据放在一个地方,并与 Spark 或 Hadoop 同步,您可以获得更多交叉分析。除此之外,选择正确的工具可能很困难。数据科学已经存在了相当长一段时间,但机器学习-数据科学运动是相当新的。在过去几年中,像 Hadoop 这样的产品引起了人们的热议。自从我全职处理数据以来,事情发生了很大的变化,Spark 是现在最热门的东西,我还没有用过它。
*## 你如何在分析中利用技术?
我用的一个工具是 R,各种严格做分析和机器学习的 R 包。还有 scikit-learn,这是一个 python 库,许多数据科学家使用它来将其集成到自己的流中进行分析。同样是 Hadoop,我在亚马逊的 EMR 平台上编程了很多 Hadoop 项目。
对于那些试图决定是否使用 Hadoop 的组织,你有什么建议吗?
这完全取决于你有多少数据,如果你试图通过注入更多的数据来获得更多的见解,我会首先尝试看看你是否真的可以用更小的数据集来解决问题。还有另一种趋势是所谓的“小数据”,它说,不要陷入拥有太多数据的宣传中。除非你是 Google scale,你有这样的数据,在大多数情况下,你可以用更少的数据做得更好,因为开发算法和实际将数据注入这些系统所需的处理和时间是一个漫长而乏味的过程。即使几千兆或几十千兆的数据实际上也是“小数据”,所以我会首先尝试这样做。很多人认为他们拥有大数据,但他们实际上没有。
如果你可以挥动魔杖,让今天的数据科学有所不同,那会是什么?
我不会说魔杖,因为技术总是在变化,但有时我确实希望我们有工具来简化数据科学家的生活。有一些平台,包括我见过的做这个的 Domino。但我一直梦想着这个神奇的 API,你只需输入数据,它就会自动为你运行所有不同的算法,运行所有不同类型的回归测试和统计显著性测试,以确保你选择了正确的算法,并确保你的数据不会过度拟合。当您选择要使用的算法时,您有时会发现,例如,使用这一组特定的功能和这些算法,使用这一数据集时,它的性能会更好,但使用其他算法和其他因素时,它的性能却不会更好。这常常会给我们错误的答案,因为我们没有正确地分割数据,没有正确地测试数据,所以我们引入了偏见,系统没有正确地学习,它只是学习特定的数据集。作为一名数据科学家,你必须做大量的工作,以确保你的系统得到适当的训练。我希望有一种算法或 API 可以自动为你做到这一点。这是我正在做的一个小秘密小项目:)。
对于初入这行的人,你有什么建议?
就像我之前说的,确保你有很强的数学背景,因为数据科学是非常数学化的。您可以通过使用不同的库来解决这个问题,但是我会尝试手工学习和实现一些基本算法,以便您对它们的工作原理有一个基本的了解。网上有很多数据集可供你使用。我还会尝试与 Kaggle 一起参加这些较小的数据科学竞赛。你可以和其他人竞争,或者下载数据,自己做分析,稍后比较你的结果。这将让你知道你在进步方面所处的位置,以及你在整个数据科学市场中所处的位置。位置也很重要;开启数据科学家职业生涯的最佳地点是硅谷和旧金山。然而,网上也有一个大数据科学社区,大多数主要城市都有数据科学聚会。如果没有数据科学小组,就会有人工智能小组,这是一个略有不同但相似的领域。
我们非常感谢 Jason 的时间和洞察力。可以关注杰森 @jtoy 。*
数据科学成熟度模型简介
原文:https://www.dominodatalab.com/blog/introducing-the-data-science-maturity-model
许多组织对他们在数据科学上的投资回报不感兴趣。这是由于狭隘地关注工具,而不是更广泛地考虑数据科学团队如何工作以及他们如何适应更大的组织。为了帮助数据科学从业者和领导者确定他们现有的差距并指导未来的投资,Domino 开发了一个名为数据科学成熟度模型(DSMM) 的框架。
DSMM 评估数据科学团队为其组织创造价值的可靠性和可持续性。该模型包括四个成熟度级别,并分为适用于所有分析组织的五个维度。根据设计,该模型并不特定于任何给定的行业——它既适用于制造业中的数据科学,也适用于保险业中的数据科学。下面的矩阵显示了我们如何绘制 DSMM。
除了描述成熟度框架之外,本文还展示了这四个成熟度级别的团队案例研究,并为改进数据科学团队的功能提供了可行的建议。
重要的是要记住,成为一个成熟的数据科学组织没有现成的解决方案。任何提出这种解决方案的人都是幼稚或误导的。我们所观察到的在最高水平上运作的团队拥有远见卓识的拥护者,并在人员、流程和技术方面进行了多年的严格投资。此外,随着该领域的发展,满足于现有的成就是不够的。
技术降低了进入数据科学的成本和壁垒,消除了有远见的公司所依赖的护城河。未来,我们相信数据科学的竞争优势将来自过程和结构,而不仅仅是工具。从业者和管理者都应该考虑他们当前的策略是否正在朝着一个成熟的组织发展。
如果您对我们如何改进框架有任何反馈或建议,请不要犹豫联系我们。我们希望在第一稿的基础上进行迭代,并融入数据科学界的见解。
如何使用预测建模进行数据驱动的预测
原文:https://www.dominodatalab.com/blog/introduction-to-predictive-modeling
当你听到机器学习(ML)或人工智能(AI)这样的词时,首先想到的事情之一是正确预测未来的发生或根据过去的事件回答关于现在的困难问题。从本质上讲,这就是预测建模的意义所在。
什么是预测建模?
预测建模是一种机器学习技术,它基于历史和当前数据预测或预测可能的未来结果。预测模型可以用来预测任何事情,包括贷款风险和天气预报,以及你下一个最喜欢的电视节目。通常,预测会描述一些情况,比如一笔 信用卡交易是否是欺诈性的 或者一个病人是否有心脏病。
预测建模是如何工作的?
在开发和部署机器学习解决方案时,模型驱动的组织遵循 四阶段数据科学生命周期 :管理、开发、部署和监控。
经营
预测建模通常从一个需要解决的问题或问题陈述开始。这些问题千差万别,而且不乏此类问题,例如:
- 我们应该订购多少存货?
- 我们应该什么时候投资?
- 我们需要多少张病床?
一旦你明确了你的问题,你就需要收集一个与这个问题相关的数据集。例如,如果您正在建立销售预测模型,您需要销售数据。该项目应优先于其他项目,以将数据科学资源集中在最有价值的地方。
发展
在开发阶段,您首先要探索哪些预测算法最适合用您现有的数据来回答您的问题。
与此同时,您需要清理和分析数据,以确保它可供您的算法使用。清理数据包括删除重复数据、无关变量以及确保数据标准化。例如,来自不同来源的数据通常会有不同的格式,常见的例子有州缩写或产品 SKU。您还需要检查空值、异常值,并确保占位符出现在需要的地方。
将数据分为训练集和测试或验证集,可以让您在一组数据上训练模型,然后在另一组数据上测试它,从而避免削弱或过度拟合。在将数据分成两组后对其进行预处理有助于避免数据泄漏。
在相同的训练数据集上测试每个候选模型。然后使用测试集再次运行每个模型。有了这些测试的结果,您就可以评估模型结果,以确定哪个模型的性能最好。这一步总是高度迭代的,因此在选择最终模型之前,您可能会多次循环查找数据、准备数据、构建模型和测试模型。
部署
一旦您有了一个为您提供满意结果的模型,您就可以进入部署阶段,将模型迁移到一个真实的环境中。这可能涉及到构建应用程序、使用 API 或在数据库中部署模型。在这一点上,最终用户被介绍到模型中,并被训练以任何形式使用其结果。
班长
模型部署后,需要对其进行监控以确保其在预期参数内继续运行。如果模型开始漂移,可能需要将其移除并重新部署。同样重要的是监控模型所输入的数据。如果数据的类型或格式与训练数据不同,则模型可能会开始生成意外的结果。
一旦模型被认为运行不正常,迅速采取措施补救这种情况并重新部署模型是至关重要的。
不准确或不可接受的预测
无论使用何种技术,模型的预测或预报能力都受到它必须处理的数据的限制。例如,这经常是预测流行病的问题。当一种新病毒出现时,或现有病毒的变种出现时,预测模型会受到现有数据的限制。如果关于类似病毒或变种的现有数据不能反映新毒株的实际情况,那么对医院床位需求的预测,或者对关闭的结果的预测,就不会准确。
在其他情况下,模型可能是准确的,但由于模型偏差,提供的结果会产生比它们解决的问题更多的问题。美国刑事司法系统使用的预测模型在预测社区犯罪热点或未来违反假释时,经常向执法部门提供带有种族偏见的结果。即使当种族作为一个数据变量被删除,其他相关变量如地理或收入也可能无意中把种族预测带回到结果中。
预测模型的重要性
成千上万的组织正在使用 Domino 的企业 MLOps 平台来改进他们的预测建模方法,在欺诈检测方面取得了进步,确定了早期癌症 的新 预测因子,甚至帮助农民 更高效地种植作物 并提高产量。
想象一下,例如,以 99.9%的准确率知道你的投资将会盈利的可能性,或者如果你的汽车发动机今天不维修,明天就会出故障。成功的数据科学项目需要在准确性、可靠性、成本和盈利能力之间找到恰当的平衡点。能够在规模上平衡这些变量是一个盈利的数据模型组织的区别。
预测建模用例
当预测建模做得正确时,不可否认它会带来巨大的回报。成功的一个关键因素是在 MLOps 平台上工作,该平台可为您的数据科学团队提供所需的工具和资源,以便在协作和记录完善的环境中出色完成工作。
Domino 数据实验室的预测建模
Forrester 的一项新研究显示,通过使用 Domino 的数据科学平台,公司可以实现 542%的投资回报率。2021 年 2 月,洛克希德·马丁公司宣布,通过使用 Domino 数据科学平台扩展其 AI/ML 解决方案,该公司已经实现了超过2000 万美元的年价值。
最重要的是,要记住预测建模是一门科学。成功的、模型驱动的组织就是这样对待它的,而那些不这样做的组织只会在碰运气的基础上取得成功。为了找出史蒂夫·沃兹尼亚克说“多米诺数据实验室机器学习操作正在改变世界”的原因, 观看一个演示 它的行动。你也可以用一个 免费试用 开始探索它的特性。
David Weedmark 是一位出版作家,曾担任过项目经理、软件开发人员和网络安全顾问。
强化学习导论:基础与应用
原文:https://www.dominodatalab.com/blog/introduction-to-reinforcement-learning-foundations
介绍
当我们想到学习的时候,我们经常倾向于关注发生在童年和青春期的正规教育。我们通常认为课本、讲座、作业和考试是获取新知识、技能和理解过程的组成部分。然而,学习能力并不是人类独有的能力,当然也不局限于严格的学术环境或一个人生命中的某个时期。事实上,学习能力普遍存在于人类、动物甚至植物中(Karban,2015),并且是一个持续发生的过程。另一方面,学习是一种假设的建构。正如 Gross (2010)指出的那样,“学习无法直接观察到,只能从可观察到的行为中推断出来。”
多年来,心理学家提出了几种不同的理论来解释学习过程是如何发生的。最早的学习理论之一是由俄罗斯生理学家伊凡·巴甫洛夫(1849-1936)在研究狗的消化系统时提出的。巴甫洛夫注意到,当狗看到负责喂养它们的技术人员时,它们会分泌唾液,但在它们看到任何真正的食物之前。在进行了一系列实验后,巴甫洛夫发现了一种被称为经典条件反射的基本行为机制。本质上,当受试者学会将先前的中性刺激(如铃声)与生物学上强有力的刺激(如食物)联系起来时,经典条件反射就发生了。图 1 概述了巴甫洛夫开发的方法,以证明一个强大的条件刺激可以用来产生一个自动的,生物内置的反应。
经典和操作条件反射——强化学习的基础
行为主义者 B. F .斯金纳的书《有机体的行为:实验分析》(斯金纳,1938)提出了一种不同类型的联想学习过程,称为操作性条件作用。在他的书中,斯金纳认为,由特定刺激引发的行为不能单独解释一切。相反,他研究了动物和人类如何与他们的环境互动,以及他们执行某些操作的后果如何驱动重复行为的可能性。斯金纳使用他创造的一种实验室设备进行了一系列实验,这种设备现在被称为操作性条件反射室。这个小室的设置使实验者能够研究动物对某些刺激的反应,如光或声音。它还为动物提供了采取特定行动的机制,例如通过按压杠杆,并且可以分发奖励(例如食物)或进行惩罚(例如电击)。这个房间通常用于老鼠或鸽子。重要的是要强调,使用操作性条件反射室进行实验与巴甫洛夫的经典条件反射实验有本质的不同。与自动和反射性发生的应答行为不同,操作性行为受主体的意识控制。操作性条件反射理论表明,某些类型的行为可以通过强化和惩罚来改变。强化可以是积极的,也可以是消极的,但它们总是以强化或增加未来行为的方式起作用。
图 1: 经典条件反射:(a)条件反射前,食物的存在自然会让狗狗流涎;(b)选择正常情况下不会产生唾液分泌反应的刺激(如铃声);(c)在调理过程中,看到食物的同时会发出铃声。重复这一过程,直到调节发生;(d)在条件反射之后,仅铃声就引发了流涎反应,现在称之为条件反射。
- 积极强化涉及愉快刺激的调用。例如,当老鼠按下控制杆时,它会得到一份奖励。这种奖励起到了积极强化的作用,促使老鼠更频繁地按压杠杆。
- 消极强化包括在表现出想要的行为后,消除不利的事件。例如,如果学生在课堂上达到了某个目标,老师可以取消那天晚上的作业。在这里,家庭作业起到了消极强化课堂作业行为的作用,因为学生们想消除晚上必须做家庭作业的不良刺激。
上面的例子表明,强化总是导致期望行为的增加(或强化)。在第一个例子中,老鼠被训练得更频繁地按下控制杆,在第二个例子中,学生被训练得在课堂上更加努力。另一方面,惩罚是为了削弱一种行为。它们也可以分为消极和积极两种,消极惩罚涉及取消一个有利的事件(如拿走孩子的玩具),积极惩罚涉及引入一个不愉快的因素(如给没有按时交作业的学生分配额外的工作)。
什么是强化学习?
强化学习(RL)是机器学习的一个领域,涉及各种技术,使智能代理能够通过与其环境的交互来学习。这个过程很大程度上是基于试错法,代理人学习采取特定的行动,最大化与一些期望的行为相关的回报。
我们可以很容易地看到这种定义与在操作性条件反射室中进行实验的相似之处。房间里的动物(代理人)检查它的周围环境(感知它的环境),激活离开者(采取行动),并接受食物颗粒(奖励)。尽管与动物互动可能很有趣,或者很有挑战性,但当我们在机器学习的背景下谈论强化学习时,我们将把自己局限于程序形式的智能代理。这种程序的简单实现可以遵循如图 2 所示的基本交互循环。然而,我们需要小心,不要只从机器人或执行具有长期目标的复杂任务的系统的角度来考虑智能代理。一个智能的、自我学习的恒温器可以从它的环境中获得温度读数,采取行动调节加热,并根据实际温度和期望温度之间的差值获得奖励,这是智能代理的一个完美可行的例子。
图 2 :简单强化学习循环——代理读取环境的状态;代理基于当前状态采取行动;代理人收到报酬;环境现在进入了一个新的状态,并且该过程重复进行。
强化学习和机器学习
说到机器学习,我们还需要指定强化学习和其他已建立的训练方法(如监督和非监督学习)之间的差异。
- 在监督学习中,目标是学习从输入 x 到输出 y 的映射,给定一组标记的输入-输出对(D = {(x_i,y_i)}_{i=1}^N)(墨菲,2013)。使用监督学习学习的模型通常被称为预测模型,因为它们输出某些输入 x 的目标变量 y。这里的关键点是,标记数据的可用性是必要的-监督学习无法在没有标记数据的情况下学习输入-输出映射,标记数据通常是从人类专家或传感器收集的测量值中收集的。这种要求在强化学习中是不存在的;报酬足以让代理人了解自己的表现。从某种意义上说,代理通过与环境交互来生成自己的训练数据,因此它不需要专家训练器。
- 无监督学习的目标是在数据中找到“有趣的模式”(Murphy,2013)。在这种情况下,我们没有被提供预先分配的输出,也没有被告知什么是有趣的模式。因为这种模型不输出目标变量,所以它们通常被称为描述性模型。严格地说,这不是强化学习的目的——代理人的目标是最大化奖励信号,而不是明确地暴露其经验中的模式或描述现有的数据。
考虑到以上情况,我们可以清楚地看到为什么强化学习通常被认为是机器学习领域中的一个独立领域。是的,很像无监督学习,强化学习在训练期间不需要监督,但这是相似之处的终点。代理的最终目标是做出一系列决策,这些决策将导致在复杂且经常动态变化的环境中在不确定性下操作时实现某个目标。此外,代理使用一种“尝试结束错误”的方法,与监督学习相反,次优动作不会被显式纠正。
此外,强化学习具有更广泛的范围,并且不仅仅局限于机器学习领域。神经经济学跨学科领域的研究表明,大脑依赖无模型生物算法进行操作性学习(Montague et al .,2004)。无模型强化学习已被用于计算精神病学领域,用于诊断神经疾病(Maia & Frank,2011;Yechiam 等人,2005 年)。也有人提出,基于分层模型的机制可能在人类决策中发挥关键作用(Botvinick & Weinstein,2014)。强化学习在行为博弈论中被用作行为预测的建模框架(阿尔巴巴巴和伊尔迪兹,2021)。运筹学的目标是对信息随时间的不确定性进行建模,运筹学的问题可以利用强化学习技术,如马尔可夫决策过程。有专门的强化学习软件库解决运筹学问题(Hubbs 等人,2020)。此外,马尔可夫决策过程在最优控制理论中被大量使用,甚至来自强化学习的一些术语也在最优控制任务中被互换使用。强化学习还与动态规划、随机规划、模拟优化、随机搜索和最优停止密切相关(Powell,2012)。
强化学习的用例
来自不同领域的许多基本元素构成了强化学习理论的基础,这一事实导致了强化学习技术在现实世界中的广泛应用。以下是一些常见用例的非详尽列表。
- 强化学习可用于各种各样的物理系统和机器人控制任务(Kober 等人,2013 年)。
- 许多工业过程以自动化子系统为特征,这些子系统通常是基于强化学习的控制和优化的良好候选对象。有专门的强化学习算法用于产品制造优化,如 SMART (Mahadevan & Theocharous,1998 年),并且已经表明,在化学反应优化等任务中,强化学习优于最先进的黑盒模型(Zhou 等人,2017 年)。
- 内容推荐是另一个具有挑战性的问题。已建立的模型倾向于主要关注对当前回报(即点击率)的建模,它们针对非常狭窄的目标(即点击/不点击)进行训练,最重要的是,它们的推荐受相似类型内容的吸引。另一方面,像(Zheng et al .,2018)这样的强化学习模型明确地对未来的回报进行建模,并且由于强化学习与生俱来的探索能力,可以发现新的和有吸引力的内容来保持用户的参与。
- 强化学习可以成功解决自然语言处理(NLP)中的问题,如文本摘要(Paulus 等人,2017)、机器翻译(Grissom II 等人,2014)和对话生成(Li 等人,2016)
- 强化学习在时间序列分析和建模交易游戏方面具有优势,因为在这样的背景下,采取高价值的行动通常取决于未来的行动和状态。对于使用传统监督学习方法的建模来说,这样的设置可能非常具有挑战性(高,2018)。
- 视频游戏是强化学习引起相当大关注的一个领域,主要是因为强化学习模型在大量游戏中一直取得了超人的表现(Shao et al .,2019)。
上面的列表绝不是详尽的,但它证明了使用强化学习可以解决的任务的广度。事实上,有无数的框架实现了不同数量的强化学习算法。值得一提的一些框架有RL lib多巴胺tensor forceKeras-RL稳定基线 。
Domino Enterprise MLOps 平台的一个关键价值主张是,它通过自助式可伸缩计算和工具加速了研究。由于该平台提供了一种添加和更新库、工具和算法包的直接方式,所有前述框架,包括【RLlib】,都可以轻松访问并用于解决强化学习任务,这有助于在多节点集群上进行 GPU 加速的模型训练。
进一步阅读和资源
- 阅读我们之前关于 深度强化学习 的帖子
- 强化学习:萨顿和巴尔托的《T2》介绍被认为是强化学习的“圣经”,网上免费提供。
RLlib 是一个用于强化学习的开源库,它原生支持 TensorFlow 、TensorFlow Eager 和 PyTorch ,并被认为是可伸缩性最强的库之一,因为它由 Ray 支持。
参考文献
格罗斯河(2010 年)。心理学:精神和行为科学第 6 版(第 6 版。).泰勒和弗朗西斯。
卡尔班河(2015 年)。植物传感和通信。芝加哥大学出版社
斯金纳 B. F. (1938)。生物的行为:实验分析。阿普尔顿世纪克罗夫特。
墨菲,K. P. (2013 年)。机器学习:概率观点。麻省理工出版社。
Maia,T. V .,& Frank,M. J. (2011 年)。从强化学习模型到精神和神经疾病。自然神经科学,14(2),154–162 页。
Montague,p .,Hyman,s .,和 Cohen,J. (2004 年)。多巴胺在行为控制中的计算角色。自然,431(7010),760–767。https://doi.org/10.1038/nature03015
Yechiam,e .,Busemeyer,J. R .,Stout,J. C .,& Bechara,A. (2005 年)。使用认知模型绘制神经心理障碍和人类决策缺陷之间的关系。心理科学,16(12),973–978。
Botvinick 和 a . w Einstein(2014 年)。基于模型的分层强化学习和人体动作控制。英国皇家学会哲学汇刊 B:生物科学,369(1655),20130480。https://doi.org/10.1098/rstb.2013.0480
阿尔巴巴,文学学士,纽约州伊尔迪兹市(2021 年)。通过深度强化学习和行为博弈理论的驾驶员建模。ArXiv,abs/2003.11071。
哈布斯、C. D .、佩雷斯、H. D .、萨瓦尔、o .、萨希尼迪斯、N. V .、格罗斯曼、即和瓦西克、J. M. (2020)。Or-gym:运筹学问题的强化学习库。
鲍威尔(2012 年)。技术报告:人工智能或控制理论:随机优化的罗塞塔石碑。技术报告(技术。代表)。普林斯顿大学。
德国多云,有机会进行快速、高效和安全的数据科学
几年前,一位高管和我们分享了一个故事。他谈到他是如何通过装甲卡车将公司的数据从一个公司站点运输到另一个站点,以确保没有数据泄露。没有一种电子数据传输方式被认为是足够安全的。但或许更有趣的一点是,这种安全措施在德国是多么普遍。
作为德国数据云公司 GTS 的创始人和产品管理负责人,我们不能不把安全性放在首位。随着人工智能的日益普及,我们听到了许多关于 MLOps 生命周期中数据保护和基础设施安全的担忧,特别是当云数据中心位于其他国家和大陆时。
这也是我们推出位于德国数据中心的GTS d ready 云的原因之一。通过在国内达到严格的标准,我们可以满足德国尚未满足的对安全云服务的需求,并在欧洲内外建立信任。
我们的 DSready 云平台汇集了云中的工具、技术、计算和协作功能,以解决组织在大规模部署数据科学功能时必须跨越的许多障碍。我们已经捆绑了 Domino Data Lab 的企业 MLOps 平台作为 DSready 云的核心组件,帮助客户加快模型速度,并将创新的人工智能驱动的产品和应用更快地推向市场。
为什么是多米诺?
在选择 Domino 作为 DSready 的基础之前,我们考察了许多数据科学平台——kube flow、H20.ai、Anaconda 和 Dataiku。其他工具都无法与 Domino 的企业功能、易用性以及更重要的安全性相媲美。
除了仅使用德国数据中心作为我们的硬件,DSready 还解决了企业难以应对的云安全的三个关键领域:数据所有权、服务器安全性和加密。借助 DSready 云和 Domino:
- 公司保留对其数据的完全控制权。许多云解决方案需要客户将数据存储在云中的本地驱动器上,这实质上是将数据控制权交给了云提供商。但像德国或瑞士这样的国家对他们的数据非常保护,不能使用这样的服务。使用 Domino 中的 S3 连接特性,我们能够在不拥有数据所有权的情况下将他们的 S3 存储桶与我们的系统连接起来。他们可以使用我们的基础设施。他们可以使用我们的机器。他们可以使用 Domino 环境。数据从他们的数据中心传输到我们的数据中心,然后再传输回来,但它从未真正存储在我们的计算节点中。这是 Domino 带来的巨大优势。
- 公司获得最高级别的访问保护。 Domino 的认证服务提供了两个至关重要的功能。首先,其 Keycloak 集成使公司能够建立一系列安全标准,必须满足这些标准才能访问平台。此功能允许组织对其身份验证和授权进行精细控制,以满足最严格的密码、多因素身份验证等要求。如果没有这种级别的安全性,许多组织将不会放心使用基于云的平台。第二个是 SSL/TLS 连接,这当然很常见,但是在这个例子中,Domino 将它带到了一个更深的层次。有了 Domino,公司可以通过 mutual TLS 保护 Kubernetes 集群内的互连,这样,即使是我们这些在 GTS 对 Kubernetes 集群拥有管理权限的人也无法在我们的系统内查看数据流量或他们的 Domino 平台而不被检测到。这是我们从其他数据科学平台提供商那里没有看到的功能,从我们的角度来看,它有助于使平台更加完整。最重要的是,我们将 Domino 的日志记录和监控功能集成到我们的内部云监控系统中,并向客户提供报告来验证这些安全机制是否有效。
- 公司获得超强加密。在 Domino 中,数据在“静态”时、在用户机器之间传输时以及在 Domino 平台的所有部分之间都使用行业标准加密技术进行加密。我们还通过几层加密来保护我们的服务器,其中一些加密层使用 4000 位密钥。许多人可能认为 4000 位的密钥有点过分。但是任何了解我们的人都知道我们对加密有点着迷,我们认为向我们的客户表明我们认真对待他们数据的安全性是很重要的。
Domino 的企业级安全性是我们喜欢 Domino 平台的众多原因之一(在这里我们不会轻易使用“爱”这个词)。Domino 不仅像我们一样痴迷于安全性,他们也像我们一样痴迷于帮助公司解决他们的数据科学挑战。Domino 在平台的前端和后端都投入了大量的精力,前者让团队使用起来更容易、更直观,后者提供了数据科学家、it 和业务用户加速模型开发和部署所需的全套功能。不管我们在 DSready 生态系统中添加了什么工具和功能,我们都知道我们有一个安全、健壮的 Domino 平台供团队工作,这样他们就可以将时间花在解决业务挑战上,而不是克服技术挑战上。
了解更多信息
- 收听网络研讨会:安全云中的下一代数据科学。
- 要了解更多关于 Domino 企业级安全性的信息,请阅读博客" Domino 4.3 反映了我们对企业级安全性的专注。
- 要了解更多关于 GTS DSready 云的信息,请访问: dsready.cloud
用于调查分析 R 中的项目反应理论
原文:https://www.dominodatalab.com/blog/item-response-theory-r-survey-analysis
在这篇客座博文中,Derrick Higgins 介绍了项目反应理论(IRT)以及数据科学家如何在项目中应用该理论(T2)。作为对客座博文的补充,Domino 中还有一个演示。
介绍
我在美国家庭保险公司(American Family Insurance)领导一个数据科学团队,最近有机会在一个有点新奇的环境中使用心理测量学的工具——项目反应理论(IRT)。许多数据科学家听说过 IRT 工具,但没有太多实际经验,所以我认为分享我在这个项目上的经验是值得的。
美国家庭对威斯康星州金融不安全感的调查
美国家庭保险,总部设在威斯康星州麦迪逊,是负债和参与我们的当地社区。我们渴望通过慈善捐赠和针对贫困地区的特殊项目成为社区的积极力量。最近,我被要求领导一个项目,应用我们的数据科学能力来促进对我们家乡金融不安全的驱动因素的理解。
我的团队与主题专家合作开发了一项调查,包括 72 个问题,涉及财务健康、人口统计、就业、住房、交通、心理健康、社会支持和其他主题。我们在 2017 年秋季对整个州的威斯康星州居民进行了调查。我想在这里把重点放在方法论上,但是你可以在下面提供的链接中阅读更多关于整个项目和我们的发现。
项目反应理论
在我们的调查中,我们想看的一件事是相对舒适的参与者和高度财务不安全的参与者之间的反应有什么不同。这意味着我们需要一个单一的措施来衡量所有受访者的不安全感。虽然我们的调查包括许多财务指标,如收入、房屋所有权和收入波动性,但根据单一的不安全感综合指标对参与者进行排名,或将他们分组进行分析,这并不是一件小事。
项目反应理论为这类问题提供了一个完美的解决方案,在这种情况下,我们需要将大量关于个人的离散观察(在这种情况下,是调查反应)整合到一个单一的整体量表中。IRT 是心理测量学(许多成就测试背后的应用心理学)中常用的一系列潜在变量模型,因此使用它来汇总与财务不安全相关的调查回答是一种有点新颖的应用。
IRT 模型是生成模型,其中每个调查或测试响应χ [ij] 的概率有条件地基于相关个体 j 的θ[j]的潜在特征分数建模,并且每个响应的概率有条件地独立于给定潜在特征θ[j]的其他响应:**
。所以在一个十项测试中,一个给定的候选人 j 产生一个给定的反应向量χ [j] 的概率简单地通过乘以十个单独的反应概率得到
对于那个能力等级的候选者来说θ[j]。
许多 IRT 模型类型限于二分项目类型,其中 X 只能取二进制值(例如,正确或不正确)。因为我们为财务不安全感量表选择的调查项目是有序的类别(如非常有信心/中度有信心/稍微有信心/完全没有信心),所以我们使用了更一般的分级响应模型,其中属于类别 k 或以上的响应的累积概率被建模为
。拟合模型包括将模型参数(特质分数 θ ,辨别参数 α 和难度参数 β )设置为它们的最大似然估计,并且对新个体的调查响应进行推断包括在给定其他参数和χ [j] 的情况下找到 θ[j] 的 MLE。
为了创建我们的财务不安全感量表,我们选择了 17 个(原始的或改造过的)我们认为符合这一概念的调查问题。这些问题涉及收入、债务、失业、房屋所有权、银行准入和实际金融挑战等领域。(一些项目进行了反向编码,以便与比例尺正确对齐。比如,收入与财务不安全感负相关,而收入可变性与之正相关。)
估计 IRT 参数
一旦我们收集了调查数据,使用 R:
library(ltm)
library(feather)
# We use the feather format to store survey data for cross-language
# compatibility. It preserves ordered factors, which we need for our IRT model.
RawSurvey <- read_feather("financial_insecurity_wi_irt.feather")
# Remove ID column before scale construction
Survey <- subset(RawSurvey, select=-c(id))
# Fit graded response model
GrmModel = grm(Survey)
# Test goodness of fit (following standard cutoff of 3.5 for residuals)
margins(GrmModel, rule=3.5)
# Output model details
GrmModel$coefficients
print(paste("Model log likelihood:", GrmModel$log.Lik))
# Plot item characteristic curves
plot(GrmModel, xlab="Theta", cex.main=0.85)
# Get theta (IRT estimate of financial insecurity)
# for every possible response pattern
GrmScores <- factor.scores(GrmModel)
print(GrmScores)
# Get thetas for each actual survey respondent
ThetaTable <- factor.scores(GrmModel, resp.patterns = data.frame(lapply(Survey, as.numeric)))[["score.dat"]]
ThetaTable[["id"]] <- RawSurvey[["id"]]
实际上,这一过程更具迭代性,因为如果存在不匹配的问题,表明这些项目可能无法衡量感兴趣的概念,我们可能必须从我们的量表中删除这些项目。一旦我们对规模感到满意,我们就可以为整个调查对象群体保存财务安全级别(theta 估计值)。这段代码还创建了一些工件,让我们能够深入了解单个项目是如何对规模产生影响的。例如,下面的项目特征曲线显示了与问题的不同回答相关联的概率,“您有多大信心认为您的家庭正在采取必要的措施来确保您将有足够的钱来实现您的长期财务目标?”。表示“非常自信”的受访者很可能具有较低的θ得分(因此具有较高的财务不安全感),而那些表示“稍微自信”的受访者的θ分布处于中上范围(高于平均不安全感)。
金融不安全感量表
鉴于这种程度的金融不安全,我的团队不仅能够总结威斯康星州居民的特定人口统计群体对我们的调查的反应(例如,城市男性与农村男性),还能够观察在整个安全等级的范围内反应如何变化。特别是,我们选择了总体财务安全最差的 10%威斯康星州居民进行深入分析。(这个 10%的数字大致与整个州的联邦成人贫困率一致。)
例如,我们能够深入调查数据,以确定最脆弱的威斯康星州居民在过去一年中遭遇特定类型金融冲击的频率:
也许令人惊讶的是,最常见的财务中断不是医疗或就业相关问题,而是受访者财产的意外必要维修。这种洞察力可以帮助组织定制支持计划,以应对经济不安全家庭最常见和最关键的需求。
我们还能够建立一个预测模型,将在调查人群中构建的财务不安全等级转化为整个威斯康星州。(详见我们的白皮书。)这种衍生量表使我们能够对威斯康辛州金融不安全的地理和人口轮廓进行更精细的分析,而使用其他高水平的数据集是不可能的。例如,下面的互动地图截图显示了该州 2268 个人口普查区块组中每个区块组的中值金融不安全水平,每个区块组约有 600-3000 名居民。财务安全性较低的区域显示为紫色,而财务安全性较高的区域显示为绿色。
结论
我希望你喜欢这个关于美国家庭在分析威斯康辛州金融不安全方面所做工作的简要概述,我也希望你能考虑在你自己的一些数据科学项目中使用项目反应理论。当您的数据包含许多噪声变量,并且您事先知道它们都与一个单一的潜在特征相关(以及它们是正相关还是负相关)时,这是一个强大的工具。虽然测试是最常见的用例,但我希望我已经展示了它也可以应用于调查数据,也许您在自己的工作中有一些更有创造性的应用!
如需了解有关威斯康辛州金融不安全项目的更多信息,我建议您访问我们的网站,在那里您可以访问白皮书、一些交互式可视化内容,甚至原始调查数据本身。该项目的登陆页面是这里。
数据科学的“乔尔测试”
原文:https://www.dominodatalab.com/blog/joel-test-data-science
这是乔尔·斯波尔斯基的“乔尔测试”16 周年纪念日,他将该测试描述为“对软件团队的质量进行评级的非常不负责任、草率的测试。”
当时(20 世纪 90 年代末),软件开发是:
- 被各行各业公认为改善业务成果的宝贵能力;
- 经历从单打独斗、小团队到大协作团队的转变;
- 经历最佳实践和工具的快速发展以支持其从业者;
- 需求量大,为有能力的从业者创造了有利可图的就业机会;
- 食天下。
我们认为数据科学正在经历一个类似的进化和成熟阶段,所以我们认为编写类似 Joel Test 的东西来评估您的数据科学程序 的成熟度会有所帮助。这是我们的“对数据科学团队质量进行评级的不负责任的草率测试。”
这是我们的初稿,让我们知道你的想法:
数据科学的“乔尔测试”
- 新员工可以在第一天就在环境中进行分析吗?
- 数据科学家能否在没有 IT 帮助的情况下利用最新的工具/包?
- 数据科学家能否在没有 IT/开发运营部门帮助的情况下使用按需和可扩展的计算资源?
- 数据科学家能否使用原始代码、数据、参数和软件版本找到并重现过去的实验和结果?
- 协作是通过电子邮件以外的系统进行的吗?
- 预测模型可以在没有定制工程或基础设施工作的情况下部署到生产中吗?
- 是否有一个单一的地方来搜索过去的研究和可重用的数据集,代码等?
- 您的数据科学家是否使用了金钱可以买到的最佳工具?
这些并不是决定数据科学项目成功的唯一因素。例如,上面的问题没有涵盖任何与数据科学工作和业务驱动因素之间的联系相关的内容(“您的所有数据科学项目都有明确的业务目标和参与的业务利益相关方吗?”).你的团队仍然需要优秀的人才。
然而,如果你对以上所有或大部分问题回答“是”,那么你的工作方式更有可能取得好的结果。
1.新员工可以在第一天就在环境中进行分析吗?
我们看到一些组织中,一名新的数据科学家甚至需要一个多月的时间才能开始做出贡献。入职可能会推迟,因为新员工需要花时间在电脑上安装合适的软件;找到并获得内部资源(代码、数据集)的正确版本以供使用;以及学习如何遵循内部流程。
2.数据科学家能否在没有 IT 帮助的情况下利用最新的工具/包?
有一个蓬勃发展的数据科学开源工具生态系统。没有一种工具是万灵药——相反,当组织足够敏捷地尝试新的工具和技术时,他们将是最有效的。为此,尝试一个新的包应该是可能的,在你的自然研究过程的速度,而不是成为一个官僚的 IT 审批过程。
3.数据科学家能否在没有 IT/开发运营部门帮助的情况下使用按需和可扩展的计算资源?
随着数据量的增长和数据科学算法变得更加计算密集型,访问可扩展的计算资源变得至关重要。与上面关于包的观点一样,如果 IT 或开发运营流程不是数据科学家的瓶颈,研究将会进展得更快。
4.数据科学家能否使用原始代码、数据、参数和软件版本找到并重现过去的实验和结果?
最初 Joel 测试的第一个问题是“你使用源代码控制吗?”根据我们的经验,源代码控制是必要的,但对于健壮的数据科学来说还不够,因为单靠源代码不足以复制过去的工作。相反,我们认为记录下实验——包括结果、参数、数据来源、和用来产生它们的代码是很重要的。最成熟的组织也将能够重新实例化底层软件环境(例如,哪个版本的语言、包)以再现过去的结果。
5.协作是通过电子邮件以外的系统进行的吗?
数据科学是一项团队运动。在项目过程中,你可能会从技术同事和非技术利益相关者那里得到反馈。您如何分享结果并记录反馈和对话?如果是通过电子邮件,这些对话和你积累的组织知识很有可能会丢失。以后回头看作品的新人就没有了;如果项目成员离开组织,它将会丢失;以后就无法搜索或发现了。
一个好的数据科学协作平台将保持工作和讨论的集中化,使其可搜索,等等。有很多方法可以做到这一点,电子邮件是将工作引入这样一个平台的便捷方式,但电子邮件不应该成为协作发生的主要方式。
6.预测模型可以在没有定制工程或基础设施工作的情况下部署到生产中吗?
如果工程师必须参与将数据科学输出集成到业务流程中,您将延迟上市时间,从而降低数据科学工作的价值。基础设施和平台可以让数据科学家快速“生产”他们的工作,而不需要额外的(有时非常长的)步骤。
7.是否有一个单一的地方来搜索过去的研究和可重用的数据集,代码等?
许多数据科学家认为,当他们回答一个问题、制作一个模型或创建一份报告时,他们会产生最大的影响。实际上,当他们的工作对组织的集体知识有所贡献,并且这种贡献可以在未来建立起来时,就会产生更持久、更有影响力的影响。因此,重要的是,随着研究的进展,它以一种可以在以后被发现和重用的方式持续存在——硬币的另一面是,人们有一种简单的方法来找到和重用过去的工作。
在数十个网络文件夹、Sharepoint 网站和存储库中进行搜索并不是保存组织知识的有效方式。应该有一个单一的记录系统,即使这样会产生与辅助系统相联系的结果。
8.您的数据科学家是否使用了金钱可以买到的最佳工具?
我们直接从乔尔的单子上拿了这个。数据科学家是昂贵的增值人员,为他们配备好设备是一项巨大的投资。
标题为“Portobello(Dublin)街头涂鸦&的横幅图片,由威廉·莫菲创作。在CC BY-SA 2.0T5 下授权
加入我们:在生产中使用 k-NN 的介绍
原文:https://www.dominodatalab.com/blog/join-us-introduction-using-k-nn-production
下周三,10 月 5 日,请加入我们的首席数据科学家主持的网络研讨会,该研讨会将涵盖在生产中使用 k -NN 的最佳实践。
k-最近邻( k -NN)算法是一种流行的模式识别方法。它通常是初露头角的数据科学家学习的第一批算法之一。尽管它很受欢迎并且看起来很简单,但是在生产数据中使用 k -NN 可能会很棘手。
Domino 的首席数据科学家 Eduardo ario de la Rubia 将在 10 月 5 日太平洋时间上午 11 点举行的网络研讨会上讨论在生产中实施k【NN】的最佳实践。您可以 在此 注册现场活动,如果您无法参加,我们将向您发送一个录制链接。
讲座将涵盖:
- k-NN 在 R 和 Python 中的实现;
- k-NN 在产品场景中的表现特点;
- 制作中使用 k -NN 的常见陷阱,以及如何避免。
我们希望下周三,即 10 月 5 日,能见到您!
合理的算法宽恕?
原文:https://www.dominodatalab.com/blog/justified-algorithmic-forgiveness
上周,帕科·内森引用了 朱莉娅·安格温最近的 Strata 主题演讲,其中涵盖了算法偏差。这篇 Domino 数据科学领域的笔记更深入地研究了一些关于算法问责和宽恕的公开研究,特别是围绕一个专有的黑盒模型,该模型用于预测累犯的风险,或者某人是否会“重新陷入犯罪行为”。
介绍
模型是数据科学和成功的模型驱动型企业的核心。作为模型的构建者和管理者,数据科学家经常处于关于适当的度量、准确性和潜在偏差的公共辩论的前沿,因为这些方面直接影响模型的开发、部署和评估方式。这种对彼此工作的公开辩论和重复继续推动数据科学领域的所有人进行严格的分析并不断改进。这篇文章提供了关于围绕算法问责、宽恕和偏见的现有辩论和研究的额外背景,上周 Paco Nathan 报道了这些。
识别算法宽恕
在过去的几年里,Julia Angwin 放大了 ProPublica 关于 COMPAS(矫正罪犯管理和描述替代制裁)中的偏见的调查结果,COMPAS 是一种预测累犯风险的专有商业算法。虽然 Paco Nathan 在 9 月引用了 Angwin 的以算法偏差为导向的 Strata 主题演讲,但在本文发表时,整个主题演讲尚未公开。
然而,类似的发现出现在麻省理工学院媒体实验室 2018 年 3 月公开发表的“量化宽恕:与朱莉娅·安格温和伊藤的对话”以及本文引用的其他研究中。在研究和谈话中,安格温提出了一些问题,以揭示黑盒模型中的机器学习(ML)偏差,“谁可能被归类为累犯风险较低?”、“谁更容易被原谅?”,以及审查 ML 结果。安格温和 ProPublica 在 2016 年的几项重要发现包括
- “黑人被告经常被预测比他们实际上有更高的再犯风险。我们的分析发现,与白人被告相比,两年内没有再犯的黑人被告被误判为高风险的可能性几乎是白人被告的两倍(45%比 23%)。
- “白人被告通常被认为没有他们那么危险。我们的分析发现,在接下来的两年内再次犯罪的白人被告被错误地标记为低风险的几率几乎是黑人再次犯罪的两倍(48%对 28%)。
这些发现表明,白人被告更有可能成为算法宽恕的接受者。然而,这些发现也引发了关于 T2 在分析数据时应该考虑哪些指标的讨论。需要比迄今为止提供的更深入的关于识别算法宽恕的见解的数据科学家可能会考虑观看麻省理工学院媒体实验室 MLTalk 的视频剪辑(根据知识共享署名许可进行了改编和重用),
https://dominodatalab.wistia.com/medias/hswxg6kalp?embedType=async&videoFoam=true&videoWidth=640
阅读“我们如何分析 COMPAS 累犯算法”以及下载数据。安格温被列为这项研究的合著者。
算法问责:需要考虑哪些措施?
2016 年,ProPublica 的 Angwin 等人主张关注假阳性和假阴性的错误率。COMPAS 的所有者 north pointe反驳了,因为它关注的是该程序是否准确地预测了累犯。然后,的一群学者在华盛顿邮报上争辩说,正在考虑的措施真的是“公平”的
Northpointe 拒绝披露其专有算法的细节,因此无法全面评估这种不公平的程度,不管这种不公平是多么的无意。这是可以理解的:Northpointe 需要保护自己的底线。但这引发了依赖盈利性公司开发风险评估工具的问题。”
然而,讨论、辩论和分析并没有在 2016 年结束。2018 年, Ed Yong 报道了来自达特茅斯学院的朱莉娅·德雷塞尔和哈尼·法里德关于“COMPAS 在预测个人再犯风险方面并不比从互联网上招募的随机志愿者更好”的研究 Yong 指出,Dressel 还确定了另一项需要考虑的措施:
她意识到这掩盖了一个不同的问题。她说,对话中有一个潜在的假设,即算法的预测天生就比人类的预测好,但我找不到任何证明这一点的研究。所以她和法里德做了他们自己的。"
在研究和论文中,Dressel 和 Farid 指出
当关于算法公平性的争论还在继续的时候,我们考虑一个更基本的问题,即这些算法是否比未经训练的人类更好地以公平和准确的方式预测累犯。我们描述了一项研究的结果,该研究表明,来自一个受欢迎的在线众包市场的人——可以合理地假设,他们在刑事司法方面几乎没有专业知识——在预测累犯方面与 COMPAS 一样准确和公平。….我们还表明,尽管 COMPAS 可以使用多达 137 个特征来进行预测,但仅使用两个特征就可以达到相同的预测精度,并且更复杂的分类器不会提高预测精度或公平性。总的来说,这些结果对算法累犯预测的整体努力提出了重大质疑。”
真实世界中的机器学习模型含义
虽然关于选择合适的方法来评估模型的争论是重要的,但是一旦“模型在野外”了,评估现实世界的影响也是重要的。数据科学家熟悉“在野外”表现不同的模型,以及他们的模型被用于特定的用例,而这些用例不是他们最初开发的。例如,COMPAS 的创始人之一 Tim Brennan,最初并没有设计 COMPAS 用于判决。然而,COMPAS 已经被援引用于判决。
判决
2013 年,斯科特·霍恩法官在考虑对埃里克·卢米斯进行适当量刑和缓刑时引用了孔波司。卢米斯提出上诉,理由是使用专有算法违反了正当程序。威斯康辛州最高法院驳回了上诉,以下摘录摘自威斯康辛州诉埃里克·卢米斯
"18 在判决时,州认为巡回法院在确定适当的刑期时应使用 COMPAS 的报告:
此外,本案中完成的 COMPAS 报告确实显示了被告的高风险和高需求。暴力风险高,再犯风险高,审前风险高;所以所有这些都是决定量刑的因素。
19 最终,巡回法院参考了 COMPAS 风险评分和其他判决因素,排除了缓刑:
通过 COMPAS 评估,您被认定为对社区具有高风险的个人。
在权衡各种因素的基础上,我排除了缓刑,因为罪行的严重性,因为你的历史,你的监管历史,以及已经使用的风险评估工具,表明你再次犯罪的风险极高。"
谁更容易被原谅?
ProPublica 强调了一个对比例子,两个人因小偷小摸被捕,作为偏见的证据。虽然以下是有限的细节,你认为哪个人会有更高的累犯分数?
如果加上年龄和性别属性,你会改变你的评估吗?
下表包括种族属性和分配的风险评估分数。
根据 COMPAS 预测风险评估模型,B 人再犯的可能性较高。作为 ProPublica 研究的一部分,研究人员在分类两年后审查了数据,以评估结果是否与预测相符。分类两年后, ProPublica 指出
“我们知道计算机算法得到了完全相反的结果。博登[B 人]没有被指控任何新的罪行。prater(A 人)因随后闯入一个仓库并窃取了价值数千美元的电子产品,正在服刑八年。"
人 B 是假阳性。人 A 是假阴性。或者,人 A 比人 b 更有可能被算法原谅。在麻省理工学院媒体实验室 MLTalk 的剪辑中提供了额外的细微差别,并根据知识共享署名许可进行了重用,
https://dominodatalab.wistia.com/medias/mi5p4pboae?embedType=async&videoFoam=true&videoWidth=640
当被问及在麻省理工学院媒体实验室 ML Talk 上分析数据集时要考虑的各种措施时,安格温指出
这是一个语义上的争论。我们指出,他们选择了一个对错误率有不同影响的公平定义,他们说,“嗯,这不是一件公平的事情,因为如果你改变错误率,你会改变预测准确性的公平优化。“,但我觉得在刑事司法的背景下,当正当程序的整个要点实际上是默认无罪时,你完全可以接受假阳性。”
结论
模型是最成功企业的核心。当数据科学家制作模型时,他们解决了许多涉及多个学科的技术和非技术挑战。应对涉及多个方面的挑战,包括人员、流程和技术,需要深入数据杂草并摆脱数据杂草的能力,以实现更广泛的影响。现代数据科学家在开发、部署和评估模型时面临的一些挑战包括识别算法偏差、决定是否信任他们的模型,考虑模型准确性与模型可解释性之间的权衡、再现性,以及偏差的真实世界影响。这篇博文关注的是研究、见解以及在开发预测性风险评估模型时需要考虑的影响。如果您对其他资源感兴趣,以下是这篇文章的参考资料:
公共研究
- 数据
- 安格温,朱莉娅。"让算法变得可靠"。ProPublica,2016 年 8 月。
- 安格温,朱莉娅和拉森,杰夫。研究人员称,犯罪风险分数的偏差在数学上是不可避免的。ProPublica,2016 年 12 月。
- Angwin,Julia 等.机器偏差。ProPublica,2016 年 5 月。
- Larson,Jeff 等人,“我们如何分析 COMPAS 累犯算法”。ProPublica,2016 年 5 月。
会谈
- 安格温,朱莉娅。量化原谅。奥莱利媒体,2018 年 9 月。注意:整个视频都在一个付费的门后面。
- 安格温,朱莉娅。“什么算法教会了我宽恕”。MozFest 2017。公开成绩单,2017 年 10 月。
- 安格温,朱莉娅和伊藤,约伊。量化宽恕:曼梯·里与朱莉娅·安格温和伊藤约伊的谈话。麻省理工学院媒体实验室,2018 年 3 月。
文章、论文和案例
- 一个用于保释和判决的计算机程序被贴上了歧视黑人的标签。其实也没那么清楚。《华盛顿邮报》,2016 年 10 月。
- Dieterich,William 等人。 COMPAS 风险等级:证明准确性、公平性和预测性的均等性。NorthPointe Inc 研究部,2016 年 7 月。
- 假阳性、假阴性和假分析:对“机器偏见:全国各地都有用来预测未来罪犯的软件”的回应。而且对黑人有偏见。“2017。
- 监督学习中的机会均等。2016.
- 斯皮尔卡姆,马提亚斯。“检查算法的偏差”。麻省理工科技评论,2017 年 6 月。
- 威斯康星州诉埃里克·卢米斯案。美国威斯康星州最高法院。2016.案件编号:2015AP157-CR。
- 永,编辑。一个流行的算法在预测犯罪方面并不比随机选择的人更好。《大西洋》,2018 年 1 月。
^(Domino 数据科学领域笔记提供数据科学研究、趋势、技术等亮点,支持数据科学家和数据科学领导者加快工作或职业发展。如果你对本博客系列中涉及的数据科学工作感兴趣,请给我们发电子邮件至 writeforus@dominodatalab.com。)
强化学习:K 臂强盗问题
原文:https://www.dominodatalab.com/blog/k-armed-bandit-problem
在之前的 博文 中,我们谈到了强化学习的基础。我们讨论了经典和操作性条件反射、奖励、状态和动作,并回顾了一些常见的强化学习用例。这篇文章是这个系列的续篇。在这篇文章中,我们提出了 k 臂强盗问题——一个非常简单的设置,它使我们能够介绍强化学习的一些关键组件之间的相互作用。
K 臂土匪问题是什么?
K 臂土匪(也称为多臂土匪问题)是一个简单的,但强大的例子,随着时间的推移,在不确定的情况下分配有限的资源。Thompson (1933)首先对其进行了研究,他提出了一种解决勘探开发困境的启发式方法。这个问题在计算机科学、运筹学、概率论和经济学领域也有研究,并且非常适合用强化学习的工具来探索。
在其基本形式中,该问题考虑一个赌徒站在一排 K 吃角子老虎丨机(也称为独臂土匪)前,试图构思一个策略,玩哪台机器,玩多少次,以及何时换机,以增加获利的机会。这个前提的有趣之处在于,每一个强盗都根据概率分布来分配奖励,这个概率分布对于强盗来说是特定的,而对于赌徒来说是未知的。因此,最优策略将包括在学习更多关于个体概率分布的知识(探索)和基于目前获得的信息最大化利润(利用)之间取得平衡。
形式化 K 臂强盗问题
现在让我们将 k 臂土匪问题形式化,这样我们就可以用它来介绍一些强化学习中使用的工具和技术。假设我们在玩(K \in \mathbb{N})强盗游戏,每场游戏由(T \in \mathbb{N})回合组成。设(\mathcal{A})是游戏中所有可能动作的集合。由于有(K)个臂可供选择,显然(|\mathcal{A}| = K)。我们还将使用(A_{t})来表示在时间(t \in [1,T])采取的来自(\mathcal{A})的动作。请注意,我们使用的时间这个术语是离散的,可以和话轮互换。
每个土匪按照一个对应的未知分布分配奖励,这个未知分布叫做奖励分布,每个行动的奖励是独立同分布的(IID)。这个设定的正式目标是在
游戏过程中最大化总奖励。现在让我们来看一个例子,它将帮助我们发展一种直觉,了解强化学习如何处理 k 臂土匪问题。
我们首先探索问题的一个变体,其中每个强盗根据从(\mathcal{D} = {\mathcal{D}_1,\mathcal{D}_2,\dots,\mathcal{D}_K})分配的伯努利分布分配奖励。换句话说,每个臂的回报是 in ({0,1}),并且由下面的概率质量函数给出
$ $ \ begin { equation * } f(n;p _ K)= \ left \ { \ begin { array } { cc } p _ K & \ text { } \ mathrm { if \ } n = 1 \ \ 1-p _ K & \ text { } \ mathrm { if \ } n = 0 \ \ \ end { array },k \in {1,2,\dots,K} \right。\end{equation*} $$
其中每个 bandit 都有一个固定的初始未知参数(p_k)。这种类型的强盗通常被称为伯努利强盗。请记住,我们选择发行版类型是为了方便起见,除非另有说明,否则我们将涉及的分析和策略并不局限于特定的发行版。
注意,每个奖励分配是固定的,因为参数在(T)轮游戏中保持不变。每回合(t \in [1,T])玩家通过选择并拉动第(k)只手来执行一个动作(A_t\ ),产生一个奖励
$ $ \ begin { equation } R _ t \ sim \ mathcal { D } _ k \ end { equation } $ $
arm (k)的平均报酬则由(\mathcal{D}_k)的期望值给出
$ $ \ begin { equation } \ mu(k)= \ mathbb { E }[\ mathcal { D } _ k]\ end { equation } $ $
很明显,选择期望值较高的分布的操作应该是首选的。为了能够量化可能行动的价值,我们可以定义一个行动价值函数(q(\cdot)\,它返回关于任意行动的预期回报(a):
$ $ \ begin { equation } q(A)= \ mathbb { E }[R _ t | A _ t = A],a \in A \end{equation} $$
不幸的是,奖励分布的参数及其期望值在游戏开始时是未知的。否则,玩家将能够应用贪婪的方法,并且总是选择提供最高期望奖励的手臂。然而,我们可以想出一个演伯努利强盗的算法,并把它作为基线。一个这样的策略采取随机行动,并在算法 1 中给出。
Algorithm 1: Standard stochastic bandit
我们看到随机算法相当 naïve——它一直随机地拉臂,直到它到达终端状态。这是可以理解的,因为算法不知道单个动作的值。但是,它会将累积奖励(G)计算为
$ $ \ begin { equation } g = r _ 1+r _ 2+\ dots+r _ t = \sum_{t=1}^t r _ t \ end { equation } $ $
最大化累积奖励是强化学习的核心目标之一,因为它得到奖励假设的支持,奖励假设认为“最大化奖励的一般目标足以驱动表现出自然和人工智能中研究的大多数(如果不是所有)能力的行为”(Silver 等人,2021)。这句话的意思是,追求一个单一的目标可能会导致复杂的行为和多种能力,从而促进目标的实现。
用 Python 实现 K 臂强盗问题
回到我们的随机强盗。我们可以编写一个简单的 Python 实现,使用指定的参数(p)从 Bernoulli bandit 生成合成数据
class BernoulliBandit:
def __init__(self, p, verbose=True):
self.p = p
if verbose:
print("Creating BernoulliBandit with p = {:.2f}".format(p))
def pull(self):
return np.random.binomial(1, self.p)
。接下来,我们定义一个 BanditsGame 类,该类使用具有随机初始化的(p)值和超过(T)回合的(K)强盗来运行模拟。在每一轮,我们拉一个随机臂(k)并按照算法 1 存储结果奖励。
class BanditsGame:
def __init__(self, K, T, verbose=True):
self.T = T
self.K = K
self.bandits = [BernoulliBandit(np.random.uniform(), verbose) for i in range(K)]
self.verbose = verbose
def run_stochastic(self):
results = np.zeros((self.T))
for t in range(self.T):
k = random.randrange(self.K)
results[t] = self.bandits[k].pull()
if self.verbose:
print("T={} \t Playing bandit {} \t Reward is {:.2f}".format(t, k, results[t]))
return results
让我们运行一个简单的游戏,在 20 个时间步骤中有 3 个强盗。
game = BanditsGame(K=3, T=20)
game.run_stochastic()
Creating BernoulliBandit with p = 0.21
Creating BernoulliBandit with p = 0.35
Creating BernoulliBandit with p = 0.21
T=0 Playing bandit 1 Reward is 0.00
T=1 Playing bandit 0 Reward is 0.00
T=2 Playing bandit 1 Reward is 1.00
T=3 Playing bandit 2 Reward is 0.00
T=4 Playing bandit 0 Reward is 0.00
T=5 Playing bandit 2 Reward is 0.00
T=6 Playing bandit 0 Reward is 0.00
T=7 Playing bandit 1 Reward is 0.00
T=8 Playing bandit 1 Reward is 0.00
T=9 Playing bandit 1 Reward is 0.00
T=10 Playing bandit 0 Reward is 1.00
T=11 Playing bandit 1 Reward is 1.00
T=12 Playing bandit 1 Reward is 0.00
T=13 Playing bandit 1 Reward is 0.00
T=14 Playing bandit 1 Reward is 0.00
T=15 Playing bandit 2 Reward is 0.00
T=16 Playing bandit 0 Reward is 0.00
T=17 Playing bandit 1 Reward is 1.00
T=18 Playing bandit 2 Reward is 1.00
T=19 Playing bandit 0 Reward is 0.00
我们观察随机方法如何在每个时间步玩随机土匪,我们也看到相应的奖励。现在让我们创建一个函数,玩(N)个游戏,运行每个游戏给定的次数,并平均每个游戏的累积奖励(n \in N)。这里的目标是对每个(n)使用一组不同的伯努利分布,但是通过平均(n)内的累积回报来了解每次运行的总体性能。这应该给我们一个关于随机 bandit 方法的一般性能的好主意。
def run_simulation(n_runs, runs_per_game, K, T):
results = np.zeros((K,T))
for run in range(n_runs):
run_results = np.zeros((K,T))
for run in range(runs_per_game):
game = BanditsGame(K=K, T=T, verbose=False)
run_results += game.run_stochastic()
results += run_results / runs_per_game
results = results / n_runs
return results
现在让我们运行十个不同的(\mathcal{D})的模拟,每组运行 100 次,使用 3 个土匪和 1000 个回合的持续时间。
stochastic_results = run_simulation(n_runs=10, runs_per_game=100, K=3, T=1000)
stochastic_results = stochastic_results.mean(axis=0)
print("Mean reward: {:.2f}".format(stochastic_results.mean()))
print("G: {:.2f}".format(stochastic_results.sum()))
Mean reward: 0.49
G: 492.48
我们看到平均回报非常接近 0.5,这在我们的预期之内。毕竟我们知道对于一个伯努利随机变量(X) (\mathbb{E} [X] = p)。如果查看 BanditsGame 的构造函数,您会注意到(p)是从([0,1))中的均匀分布中采样的,因此(\ mathbb { E }[P]= \ frac { 0+1 } { 2 } = 0.5 )。
为了更好地了解算法的性能,我们还可以绘制算法 1 实现的平均回报。我们再次观察到,平均回报在 0.5 左右波动。
另一方面,累积奖励值的合理性无助于我们的算法类似于掷硬币的事实。这并不是特别伟大。然而,我们将使用这个结果作为基线,在本系列的下一篇博文中,我们将探索几个性能明显优于基线的半统一策略。
参考
汤普森,W. R. (1933)。根据两个样本的证据,一个未知概率超过另一个未知概率的可能性。生物计量学,25(3-4),285–294。https://doi.org/10.1093/biomet/25.3-4.285
西尔弗博士、辛格博士、普雷科普博士和萨顿博士(2021 年)。奖励就够了。人工智能,299,103535。https://doi . org/https://doi . org/10.1016/j . artint . 2021.103535
额外资源
您可以获得对企业 Domino MLOps 平台的 14 天免费试用,运行 JupyterLab、RStudio 和 VScode 等 ide,并了解如何快速轻松地部署 ML 模型和应用程序。
KNN 用 Python 写的例子
原文:https://www.dominodatalab.com/blog/knn-with-examples-in-python
在本文中,我们将介绍并实现 k 近邻(KNN)作为一种有监督的机器学习算法。KNN 用于解决分类和回归问题。 我们将提供足够的背景知识,并使用免费提供的数据集演示 KNN 在解决 Python 中的分类问题中的效用。
什么是 K-最近邻?(KNN)
各种机器学习算法(ML)被用来解决不同领域的问题,以识别可操作的见解。这些问题大多属于两类之一:有人监督的或无人监督的。前者是任务驱动的,训练数据伴随着监督输出标签,用于包括分类和回归在内的许多任务,而后者是数据驱动的,不伴随着监督标签,通常用于从这些数据中学习关系和识别聚类。
监督学习问题可以用来解决回归和分类问题。这两个问题之间的差异是由于回归和分类的输出变量分别是数字或分类的事实[1]。
KNN 于 1951 年由 Fix 和 Hodges [2]提出,并由 Cover 和 Hart [3]进一步完善,是最常用的监督学习方法之一。它主要用于解决分类问题。KNN 的主要概念是基于计算测试和训练数据样本之间的距离,使用距离函数来识别它们最近的邻居。测试样本随后被分配到其最近邻的类别。因此,KNN 是一种基于距离的 ML 算法[4]。
最初开发基于距离的方法是为了使用单一数据类型来度量数据点之间的相似性。真实世界的数据是不同数据类型的混合,因此对这些方法的后续修改允许使用异构数据集。使用各种距离函数测量数据点之间的距离,包括欧几里德距离、曼哈顿距离、闵可夫斯基距离、城市街区距离和切比雪夫距离;KNN 算法最常用的函数是欧几里德函数[5]。
KNN 经常被认为是一种“懒惰”的算法,因为它将大量的计算推迟到测试时间。因此,这表明 KNN 模型训练涉及存储训练子集,而测试未知数据点涉及搜索 K 个最近邻的训练数据集。
对于 KNN,给定一个正整数(K)和一个测试观察值(x_0\ ), KNN 分类器首先确定训练数据中最接近(x _ 0 )的点的数量(K\ ),并将它们存储在(N_0)中。随后,使用如上所述的距离函数之一来计算测试样本和训练数据点之间的距离。
对这些距离进行排序,并确定基于第(k)个最小距离的最近邻居。本质上,KNN 将根据下面的等式,将类别 j 的条件概率估计为(n0 )中响应值等于(j)的点的分数:
$ $ \ begin { equation } Pr(Y = j | X = X _ 0)= \ frac { 1 } { K } \ sum _ { I \ in N _ 0 } I(Y _ I = j)\ end { equation } $ $
随后,KNN 将测试观察值(x_0)分配给使用上述等式[1]计算出的概率最大的类别。
如何选择最优的 K 值?
在 KNN,(K)值代表最近邻的数量。该值是该分类器的核心决定因素,因为(k )-值决定有多少邻居影响分类。当(K=1)时,新的数据对象被简单地分配给它最近的邻居的类。邻居取自一组训练数据对象,其中正确的分类是已知的。KNN 天生会处理数字数据[5]。
图 1 直观地展示了 KNN 以及(K)的值如何影响决策界限。在图 1A 中,绘制了来自包括三个类的多类数据集的两个特征。用黑色、橙色和黄色描绘的类别在黑色和其他两个类别之间有明显的分隔。红色和黄色类别之间的边界区域有一些重叠。
由绿色十字表示的数据点被示出,目的是识别该数据点属于哪一类。围绕这个感兴趣的点画一个圆,并计算圆内的点数。这个十字周围总共有 19 个点,其中 11 个红色,8 个黄色。因此,如果选择(k=19\ ),则该点属于红色类别,因为属于红色和蓝色类别的概率分别为 11/19 和 8/19。
Figure 1: The KNN implementation uses different values for K. A) Simple manual decision boundary with immediate adjacent observations for the datapoint of interest as depicted by a green cross. B-D) Decision boundaries determined by the K values as illustrated for K values of 2, 19 and 100. As evident, the highest K value completely distorts decision boundaries for a class assignment.
在随后的图(图 1B-D)中,进行了系统的搜索,以确定产生最高预测精度的最优值(K)。通过使用 GridSearchCV,使用交叉验证,在(X1)和(X2)(所用特征)的所有可能值下,在(K)s (1-30)的范围内对最佳(K)进行系统搜索。这些面板中描绘了 2、19 和 100 的(K)的代表性图像。结果表明(K=19)产生最高的准确度和最低的标准偏差。
如图 1 所示,选择(K)会显著改变预测的结果。例如,使用(K=2)(图 1B)感兴趣点属于深蓝色类,这是一个错误分类,噪声对结果的依赖性会更高。模型的过拟合是小(K)的一个可能结果。此外,使用(K=19),兴趣点将属于绿松石类。此外,如较低的 K 所示,可以观察到决策边界中的一些灵活性,而当 K=19 时,这种灵活性会降低。相反,使用(K=100)时,决策边界变成一条直线,导致预测精度显著降低。
综上所述,这些观察表明,选择由(K)的值选择产生的决策边界的灵活度是显著影响预测结果的关键步骤。因此,有必要系统地进行这种选择,例如,使用交叉验证方法。
用 Python 实现 KNN 解决分类问题
在这里,我们将实现 KNN 使用常用的和免费提供的虹膜数据集[6]。鸢尾属是一种开艳丽花朵的开花植物。该数据集中包括 3 种鸢尾属植物;Setosa,Versicolor 和 Virginica 拥有相似的颜色:深紫色/蓝色。视觉上区分它们的一种方法是通过测量花瓣和萼片的尺寸(长度和宽度)。提供的特征是萼片和花瓣的长度和宽度,单位为厘米。
在这个过程中有两个主要步骤:1)数据预处理和探索性数据分析,以允许检查数据集和探索性可视化,以及 2)建立 KNN 模型并评估训练和测试子集的预测性能。
3.1 数据预处理和探索性数据分析
这里的目标是理解和可视化数据集,并为下一步做准备。Iris 数据集作为数据帧从 Seaborn 库中加载。没有观察到缺失值或数据不平衡。
图 2 显示了使用 Seaborn 的 pairplot 函数对所有可能的特征组合的直方图分布和散点图。
这将使我们能够看到每个子情节中绘制的两个不同变量之间的关系。例如,图 2 显示了花瓣的长度允许将 Setosa 与其他两种花分开。此外,在花瓣长度对宽度的图中,花被充分分开。
Figure 2: Pair plots and histograms to identify relationships between features and data distribution.
随后,绘制花瓣长度和宽度以及萼片宽度的 3D 散点图,以更好地显示基于这些特征的类别分离(图 3)。
Figure 3: 3D scatter plot of petal length/width and sepal width.
在训练和测试子集上建立 KNN 模型并评估预测性能
在本节中,我们将训练 KNN 模型,评估训练子集的性能,并测试测试子集的泛化性能。采取了以下步骤:
- 定义了特征和输出变量。要素被缩放。
- 数据集被分成训练和测试子集,其中 70%用于训练,其余部分用于测试。前者用于训练模型,后者用于测试未知数据的泛化性能。
- 最佳(K)值的选择至关重要,因此我们进行交叉验证,以确定产生最高准确度的(K)值
- 为了可视化的目的,我们绘制了由不同的(K)值产生的决策边界
- 然后,我们用上一步中确定的最佳值\( K \)启动 KNN 算法
- 执行 KNN 模型的训练
- 接下来,我们计算训练子集的预测,并评估
模型的性能 - 最后,我们使用测试子集测试泛化并评估结果
建立 KNN 模型的最关键的方面是确定和使用最佳的 K 值。为此,进行了 30 倍交叉验证。结果如图 4 所示。(K)的最佳值是 19,它允许 98%的准确度。在这个值之后,精确度继续降低,在最高的(K)值处达到最低。
Figure 4: Cross-validation to identify the best (K) value
为了说明(K)选择的重要性,我们绘制了由 2、19、40、60、80 和 100 这 6 个不同 K 值产生的决策边界。当 K=100 时,随着 K 的增加,决策边界的灵活性显著降低,几乎是线性的。
Figure 5: The effect of (K) selection on decision boundary and class prediction.
我们随后评估了 KNN 模型在训练子集上的性能,发现它产生了 98%的总准确性,对 Setosa 的预测是 100%正确的,对 Versicolor 和 Virginica 的预测几乎是完美的。
Figure 6: Confusion matrix illustrating the performance of the KNN model on the training subset.
最后,对测试子集的泛化性能的评估揭示了与训练子集相比,Setosa 类具有相同的高性能,而 Versicolor 和 Virginica 的性能有所下降。
Figure 7: Confusion matrix illustrating the generalisation performance of the KNN model on the testing subset
摘要
在本文中,我们研究了 k-最近邻——一种具有广泛应用的非参数分类方法。我们讨论了算法的内部原理和选择最佳 K 值的问题。在文章的最后,我们还通过混淆矩阵看了结果解释。
本文有一个附带的项目,包含数据、Python 代码和绘图。你可以通过注册一个免费多米诺试用来获得它。
参考
[1] G. James、D. Witten、T. Hastie 和 R. Tibshirani,《统计学习导论》。斯普林格,2013。
[2] E. Fix 和 J. Hodges,“非参数判别分析和密度估计的重要贡献”,《国际统计评论》,第 3 卷,第 57 期,第 233-238 页,1951 年。
[3] T. Cover 和 P. Hart,“最近邻模式分类”,IEEE 信息论汇刊,第 13 卷,第 1 期,第 21-27 页,1967 年。
[4] D. T .拉罗斯,数据挖掘和预测分析。约翰·威利父子公司,2015 年。
[5] D. T. Larose 和 C. D. Larose,《发现数据中的知识:数据挖掘导论》。约翰·威利父子公司,2014 年。
[6] B. V. Dasarathy,“邻近区域的探测:部分暴露环境中识别的新系统结构和分类规则”,IEEE 模式分析和机器智能汇刊,第 1 期,第 67-71 页,1980 年。
kubernetes-原生 Domino 为未来奠定基础
原文:https://www.dominodatalab.com/blog/kubernetes-native-domino-sets-the-foundation-for-the-future
拥抱未来,Domino 现在是 Kubernetes-native,并准备好流畅地支持即将到来的创新。Kubernetes 的好处和 Domino 的核心价值是一致的——灵活性、可靠性、成本降低以及避免供应商和工具锁定。了解到 Kubernetes 在未来五年及以后将在企业 IT 架构中扮演的重要角色,我们的工程团队承担了全面移植 Domino 的任务。
我们认识到,数据科学的支持和 IT 战略的协调绝非易事。好消息是,Kubernetes 的容器编排的灵活性可以支持数据科学家和未来 IT 战略的需求。如果您与许多 IT 团队交谈,您会听到对云原生的关注,以及实施多云或混合云战略的未来目标。Kubernetes 将在这些战略中发挥巨大作用,并将日益成为支持数据科学家需求的关键。
有了 Kubernetes-native Domino,我们在开放性和对所有企业基础设施的支持方面加倍努力- AWS、GCP、Azure 以及内部部署。此外,Domino 可以帮助企业 IT 提供商避免云锁定并实现多云策略,同时利用他们现有的监控和操作基础设施。
正如 National Oilwell Varco 的数据科学运营经理 Joshua Cluff 所说:“Kubernetes 上的 Domino 为我们的数据科学团队提供了所需的灵活性,同时让我们的 IT 合作伙伴高枕无忧。我们现在可以跨不同的基础设施运行 Domino,包括内部和基于云的环境,同时还可以插入我们的 IT 团队了解和信任的现有监控、日志记录和企业安全工具。在让数据科学成为与企业 It 一致的一等公民的道路上,这是向前迈出的一大步。”
Kubernetes 上的 Domino 允许为您和您的团队带来许多好处:
- 启用多云数据科学: Kubernetes 支持 Domino 的多云策略,允许 Domino 在任何云或本地环境中本机运行,并具有异构数据科学工作负载弹性扩展的全部优势;
- 降低数据科学工作负载的成本:通过弹性地扩展工作负载,并跨底层硬件资源智能地打包它们,Domino 更高效地运行数据科学工作负载,降低计算成本;和
- 运营效率: Domino 现在可以安装到公司现有的 Kubernetes 集群中,通过与现有的 devops 堆栈集成,减少管理表面积并简化管理。
我们很高兴地宣布,Domino 使 it 比以往任何时候都更容易成功地支持他们的数据科学家。借助 Kubernetes 上的 Domino,高瞻远瞩的 IT 组织可以在行业领先的 orchestrator Kubernetes 上提供可扩展的多云支持,从而简化和增强他们的数据科学基础架构。
展望未来,Kubernetes-native Domino 将“让世界在模型上运行”,无论这些模型在哪里运行。
有关更多信息:
- 阅读新闻稿: Domino Data Lab 推出全面的 Kubernetes-Native 数据科学平台,为 IT 提供支持,并实现多云数据科学
- 阅读 VentureBeat 的故事: Kubernetes:加速当今数据科学所需的关键要素
- 查看 Domino 4.0 管理员指南中的技术文档
canvasXpress 中的大型可视化
原文:https://www.dominodatalab.com/blog/large-visualizations-canvasxpress
康尼布雷特博士是聚合天才的拥有者。Connie Brett 博士为 Bristol-Myers Squibb 的转化生物信息学团队提供定制可视化工具开发和支持,同时也是 canvasXpress 的 CRAN 软件包的维护者。该团队开发和支持包括 canvasXpress 在内的工具,以帮助打破科学研究和开发的障碍。如果你对此感兴趣,可以考虑加入团队。
canvasXpress 简介
每个人都有自己喜欢的数据可视化包——无论是 ggpot、plotly 还是其他任何一个。然而,一旦图表上有成千上万的可视化对象(例如,点),经常遇到的一个问题是,那些常见的可视化工具将停滞不前,性能受到影响。但是,正如您可能已经听说的那样,有一个解决这个问题的软件包 canvasXpress。
CanvasXpress 是百时美施贵宝公司开发的生物信息学和系统生物学分析的核心可视化组件。在这个库中创建图表非常直观,通过简单的配置更改,您可以创建丰富的、可扩展的和可广泛移植的图表。该库支持大量的可视化类型,并在可视化上包括一组简单而不显眼的用户界面功能,允许用户缩放、过滤、转换、聚集、下载等等。该库由 Isaac Neuhaus 积极维护和开发,包括一个由我维护的完整文档化的配套 CRAN R 包。R 包将广泛的 API 选项包装到一个 htmlwidget 中——这意味着可以在 RStudio 中使用 canvasXpress 在控制台中生成绘图,或者将它们无缝嵌入到 RMarkdown 或 Shiny web 应用程序中。
在这篇文章中,我将带你从原始数据中创建和定制一个大图表,并把它放到 RMarkdown 或 Shiny 应用程序中。
数据注释
CanvasXpress 可轻松处理多维和大型数据集进行可视化。浏览器中的 canvasXpress 功能通常要求数据具有较宽的格式,并利用列名和行名来交叉引用和访问制作图表所需的各种数据,因此有必要花一点时间来定义 canvasXpress 中的一些常用术语。
变量是主数据框中的数据行,变量名取自行名。
样本是主数据框中的数据列,样本名称取自列名。
注释是额外的信息或特征。这些数据点增加了有关样本或变量的信息,但不是主数据集的一部分。注释可以出现在行(变量)或列(样本)或两者上。
建筑图
现在我们已经介绍了常用术语,让我们从头开始使用一个 R 函数调用在 canvasXpress 中构建图表。出于说明的目的,我们正在构建的图表基于来自世界银行的两个可下载数据集。虽然 canvasXpress 是为可视化生物数据而构建的,但它将适用于任何数据集主题。R 中的 canvasXpress 函数调用使用命名变量,因此选项的顺序并不重要——事实上,当您使用这个包时,您将开发自己喜欢的选项和顺序。当我们构建函数调用时,代码块将使用粗体指出变化。
首先,我们将数据读入两个 R 对象:y 和 x。y 对象将包含我们正在为每个国家构建的世界人口图表的主要数据集。这个数据集的样本是国家(列),这个数据集中只有一个变量(行)——人口。第二个数据集被读入 x 对象,并将保存每个国家的样本注释或附加信息,如 GNI(国民总收入)。
我们对这些数据的第一次可视化非常简单——我们只想看到按国家划分的人口柱状图:
y <- read.table("http://www.canvasxpress.org/data/cX-stacked1-dat.txt",
header = TRUE, sep = "\t", quote = "", row.names = 1,
fill = TRUE, check.names = FALSE, stringsAsFactors = FALSE)
x <- read.table("http://www.canvasxpress.org/data/cX-stacked1-smp.txt",
header = TRUE, sep = "\t", quote = "", row.names = 1,
fill = TRUE, check.names = FALSE, stringsAsFactors = FALSE)
library(canvasXpress)
canvasXpress(data = y, graphType = "Bar")
您已经拥有内置的工具提示和所有的 canvasXpress 工具栏功能(过滤、下载等。)除了你的条形图之外——并且在一个单独的调用中只指定 graphType。现在,让我们通过更改方向、添加标题、旋转标签和移除图表中的图例来改进这个条形图:
canvasXpress(data = y,
graphType = "Bar",
graphOrientation = "vertical",
title = "Country Population",
smpLabelRotate = 45,
showLegend = FALSE)
在左侧截图中,您可以看到右上角的 canvasXpress 图表工具栏。该图表还有一个上下文菜单(右键单击),在右边的屏幕截图中用于选择数据排序所依据的变量。这些工具都不需要任何设置配置,并且是图表本身的一个功能-无论是托管在 RStudio 的视图窗格、闪亮的应用程序、RMarkdown 文档中,还是直接在 html 网页上。花几分钟时间探索这些丰富的工具,用于下载、过滤、格式化、更改图表类型、属性,甚至数据本身!
进入下一个图表级别很容易——将过渡直接添加到图表本身。下面的代码在图表中添加了一个排序转换——您必须尝试一下,因为屏幕截图是静态的!这些转换不仅执行某些功能(例如,对数据进行排序),而且还可以为您的用户提供关于数据和图表如何操作的附加上下文。此外,他们还增加了一些眼睛糖果几乎没有你的工作!
canvasXpress(data = y,
graphType = "Bar",
graphOrientation = "vertical",
title = "Country Population",
smpLabelRotate = 45,
showLegend = FALSE,
sortDir = "descending",
showTransition = TRUE,
afterRender = list(list("sortSamplesByVariable",
list("population"))))
好了,现在我们对现有的数据有了一个概念,让我们用国民总收入给图表着色,让图表更有用。这是数据集中样本的“注释”或额外信息(如国家)。我们已经在 x 对象中加载了一个包含所有国家信息的数据集,让我们将它添加到 smpAnnot 中的图表中,并根据 GNI 进行着色。我们还将通过注释掉 showLegend = FALSE 行来重新打开图例,并向图表添加一个副标题来枚举数据集的添加。
canvasXpress(data = y,
smpAnnot = x,
graphType = "Bar",
graphOrientation = "vertical",
title = "Country Population",
smpLabelRotate = 45,
#showLegend = FALSE,
subtitle = "(by Gross National Income)",
colorBy = list("GNI"),
sortDir = "descending",
showTransition = TRUE,
afterRender = list(list("sortSamplesByVariable",
list("population"))))
最后,我想把各大洲的数据组合成一个堆叠的条形图,以便于阅读。如果把它显示成一个树形图而不是一个简单的堆叠条形图就太好了——它只有两个额外的选项:
canvasXpress(data = y,
smpAnnot = x,
graphType = "Stacked",
graphOrientation = "vertical",
title = "Country Population",
smpLabelRotate = 45,
#showLegend = FALSE,
subtitle = "(by Gross National Income)",
colorBy = list("GNI"),
treemapBy = list("ISO3"),
groupingFactors = list("continent"),
sortDir = "descending",
showTransition = TRUE,
afterRender = list(list("sortSamplesByVariable",
list("population"))))
现在,我的图表中有了一个非常丰富的数据集,包括工具提示、可视化转换和丰富的交互性。无论我在哪里部署此图表,我的用户都将获得每个 canvasXpress 图表内置的所有功能,以进行过滤、排序、缩放、平移、下载等,而无需编写任何额外代码,只需一次函数调用。我可以将这个图表的代码放入一个闪亮的应用程序或 RMarkdown 中任何可以使用 htmlwidget 的地方,图表的性能可以扩展到数万个数据点。
这是一个一页纸的闪亮应用程序,展示了这个图表——ui 调用中的一个CanvasXpress output与服务器调用中的一个renderCanvasXpressreactive 配对,该服务器调用包含我们上面创建的完全相同的 canvasXpress 函数调用:
library(shiny)
library(canvasXpress)
ui <- fluidPage(
flowLayout(canvasXpressOutput("exampleChart", width = "800px"))
)
server <- function(input, output) {
y <- read.table("http://www.canvasxpress.org/data/cX-stacked1-dat.txt",
header = TRUE, sep = "\t", quote = "", row.names = 1,
fill = TRUE, check.names = FALSE, stringsAsFactors = FALSE)
x <- read.table("http://www.canvasxpress.org/data/cX-stacked1-smp.txt",
header = TRUE, sep = "\t", quote = "", row.names = 1,
fill = TRUE, check.names = FALSE, stringsAsFactors = FALSE)
output$exampleChart <- renderCanvasXpress({
canvasXpress(data = y,
smpAnnot = x,
graphType = "Stacked",
graphOrientation = "vertical",
title = "Country Population",
smpLabelRotate = 45,
#showLegend = FALSE,
subtitle = "(by Gross National Income)",
colorBy = list("GNI"),
treemapBy = list("ISO3"),
groupingFactors = list("continent"),
sortDir = "descending",
showTransition = TRUE,
afterRender = list(list("sortSamplesByVariable",
list("population"))))
})
}
shinyApp(ui = ui, server = server)
总结
canvasXpress 网站在网站的示例部分有数十种类型的数百个图表的 R 代码。您可以将 R 代码复制/粘贴到 RStudio 的控制台中,并创建图表,探索数据是如何设置的,以及各种定制选项等。这是熟悉您感兴趣的确切图表类型的好方法!此外,在 Shiny 中有三个使用 canvasXpress 可视化的预构建示例应用程序,您可以使用 cxShinyExample()函数启动它们。通过使用广泛的 API 选项(在网站上也有详细介绍)进行简单的配置更改,您的图表可以是丰富的、可伸缩的和广泛可移植的。
“精益”数据科学
在本次数据科学弹出式会议中,Pivotal 首席数据科学家 Noelle Sio 解释了如何将精益方法应用于数据科学。
在 Rev 2 从对冲基金领导者那里了解投资的未来
By Karina Babcock, Director Corporate Marketing, Domino on April 25, 2019 in
Coatue Management 联合创始人兼高级董事总经理 Thomas Laffont 将与他的数据科学主管Alex Izydorczyk一起登上 Rev 2 的舞台,这肯定是一场由 Point72 首席市场情报官兼董事总经理 Matthew Granade 主持的精彩讨论。(充分披露:马修·格拉纳达也是达美乐的联合创始人和董事会成员,Coatue Management 同时也是达美乐的投资者和客户。)
根据福布斯的说法,Coatue 一直“走在人工智能革命的前面”,大量持有英伟达、谷歌和 Equinix 等创新公司的股票。他们最近也在私人市场引起了轰动,被机构投资者称为“最激进的对冲基金投资者之一”,在 Instacart、Lyft、Box.com、jet.com、优步和 Snapchat 都有值得关注的投资。他们在 2018 年推出了两只风险投资基金,今年 2 月,创始人兼首席投资官 Philippe Laffont 宣布 Coatue 将推出其首只量化对冲基金,该基金将完全系统化,保持市场中立。
Point72 还将投资重点放在由模式驱动的创新推动的行业,其中超过 22%投资于医疗保健,21%投资于技术,16%投资于能源。该公司去年扩大了其地理足迹,最近在悉尼开展业务,专注于宏观投资。该对冲基金在 2018 年筹集了超过 40 亿美元的外部资本,使管理的总资产达到约 130 亿美元(截至 2018 年 11 月)。
Coatue 和 Point72 都认识到数据科学作为一种组织能力的力量;根据彭博的说法,他们成功地将量化投资和自主投资结合起来。
但是金融公司依赖模型已经有几十年了。只是被称为“定量研究”而不是“数据科学”,对吗?那么,在数据科学行业中,新的建模方法和发展带来了什么变化呢?
在 Rev 的讨论中,三位对冲基金领袖将交换观点并解决以下问题:
- 对冲基金如何利用模型来推动整个行业的创新和新战略?
- 随着数据科学和建模实践的发展,公共和私人市场的投资策略如何变化?
- 金融公司量化研究经验中的哪些教训和概念对融入新的数据科学体系很有价值?反过来,对冲基金必须从过去的操作方式中“忘却”什么?
- 将数据科学整合到您的基金中的一些具体策略和技术是什么?其中哪些可以应用于金融部门以外的业务?
- 如何整合数据科学家与传统分析师和投资组合经理?
全体会议讨论将于 5 月 24 日星期五在纽约万豪酒店举行。要了解更多关于 Rev 2 或查看完整议程,请访问rev.dominodatalab.com。请注意,4 人以上的团队一起注册可以获得门票费用的 50%折扣。
1。https://www . Nasdaq . com/quotes/institutional-portfolio/point 72-asset-management-LP-931797?sort name = shares held&sort type = 1<a href = " https://www . Nasdaq . com/quotes/institutional-portfolio/point 72-asset-management-LP-931797?sort name = shares held&sort type = 1 "
学习如何在 Rev 2 中做出更少的错误决策
原文:https://www.dominodatalab.com/blog/learn-how-to-make-fewer-bad-decisions-at-rev-2
By Karina Babcock, Director, Corporate Marketing, Domino on March 21, 2019 in
第二届数据科学领袖年度峰会 Rev 2 即将召开。今年的会议将于 5 月 23 日至 24 日在纽约市举行。
早鸟定价本月底到期!
数据科学领导者将参加今年的活动,与观众分享他们的经验、知识和建议,这让我们感到无比荣幸和激动。本着这种精神,我们将每周花几分钟时间介绍我们的演讲者在这里——没有特定的顺序——让你了解他们是谁,他们来自哪里,以及为什么你可能有兴趣在 Rev。
让我们首先强调一位今年将重返舞台的 Rev 校友:Eric Colson,他以 Stitch Fix 首席算法官的身份管理着一个由 100 多名数据科学家组成的团队。在 Stitch Fix 之前,Eric 在网飞担任数据科学和工程副总裁。Eric 富有洞察力的演示反映了他在颠覆行业的真正模型驱动型公司中管理数据科学组织的经历。如果你还没有,你应该看看他最近在 HBR 发表的文章《为什么数据科学团队需要通才而不是专家》,或者看看他和数据科学经理 Hoda Eydgahi 写的关于如何“成为一家全栈数据科学公司”的博客。
在 Rev,Eric 将与 Stitch Fix 的数据科学总监 Daragh Sibley 同台。他们将一起讨论领导者如何通过深入了解我们大脑的连接方式和我们直觉中的谬误来做出更好的商业决策,这些谬误通常是通过实证 A/B 测试发现的。这个演讲将是丹尼尔·卡内曼当天早些时候关于直觉判断和选择心理学的主题演讲的引人注目的后续。
下面您可以查看 Eric 和 Daragh 在 Rev .的会议的完整详细信息。
如何减少错误决策
5 月 23 日星期四 2:40-3:10
越来越流行的 A/B 测试揭示了一个强大的,但很少讨论的洞察力:我们的直觉是非常糟糕的!然而,我们大多数人要么不知道,要么选择不相信这一点。一次又一次,随机对照试验表明,我们对商业决策结果的预测是非常容易出错的:实验表明,我们对新功能的乐观往往是被误导的;我们以为会有帮助的东西实际上是有害的;我们认为的下一件大事彻底失败了。我们的直觉甚至会导致比我们单独从随机机会中预期的更糟糕的结果。
这不是关于 A/B 测试的讨论,而是经验主义揭示了我们的直觉。我们描述了领域专家犯的一些错误。我们讨论这些系统性错误是如何从启发式推理过程中产生的,这种推理过程在进化的时间尺度上对我们很有用,但现在却损害了我们的判断。通过互动的观众演示,我们展示了认知启发法是如何影响决策及其评估的。
虽然我们不能改变我们大脑的构造,但了解它们的工作方式可以给我们带来优势。有几种机制可以减轻这些人类的局限性,并改善我们的决策。我们相信,较少做出错误决策的企业将拥有明显的竞争优势。
从科学的再现性危机中吸取教训
原文:https://www.dominodatalab.com/blog/learn-reproducibility-crisis-science
关键亮点来自 Clare Gollnick 的演讲《推论的极限:数据科学家能从科学中的再现性危机中学到什么》,在这篇多米诺数据科学领域笔记中有所涉及。完整视频可在这里观看。
介绍
在 Clare Gollnick 的圣何塞演讲“推理的极限:科学家可以从科学的再现性危机中学到什么”中,Gollnick 讨论了如何将数据转化为见解是一项挑战。虽然推理是数据科学家可能用来揭示洞察力的工具,但通过持续搜索、 p-hacking ,以及机器学习中的过度拟合,有可能打破推理。这潜在地导致了科学界的再现性危机。Gollnick 是一名前数据科学家,现在是铽实验室的首席技术官,他提倡数据科学家从科学中的再现性危机中吸取教训,认识到推理的局限性,并将推理作为解决适当问题的工具。
再现危机
在 2011 年,一位风险投资人提到,一条“潜规则是至少 50%的研究发表在顶级学术期刊——《科学》、《自然》、《细胞》、《PNAS》等...——工业实验室不能重复得出同样的结论”。在 Gollnick 的演讲中,Gollnick 引用了多项研究,包括拜耳 2011 年研究、安进研究,以及许多实验室复制项目,指出了科学中的再现性危机。这种可复制性危机可能已经导致数百人在可能并不存在的重大影响下学习和创造职业。正如演讲的标题所言,数据科学家有机会从科学的再现性危机中吸取教训。Gollnick 还指出“我们用来从数据中进行推断的逻辑系统中的一个根本缺陷”导致了科学中的再现性危机。
推理的局限性
Gollnick 在谈话中指出“推理被搜索打破”。例如,Gollnick 提到“假设检验中的 p 值是对惊奇的量化”。人们寻找惊喜的次数越多,就越容易看到惊喜。或者,有人越频繁地运行和重新运行相同数据的模型,直到他们得到他们想要的重要结果,打破推理,这也被称为 p-hacking 。另一个打破推理的例子是机器学习中的过拟合。当有人“搜索太多模型,当[他们]愿意一次考虑太多假设,当[他们]搜索太多参数,或给模型太多自由度”时,过度拟合就会发生。然而,交叉验证在机器学习中被用来修复过度拟合。交叉验证包括“分离你的训练数据,在此基础上生成假设和模型,然后测试一次”。Gollnick 在演讲中还建议数据科学家设计问题,这样他们就可以“尽可能少地进行物理推断……依靠从尽可能少的数据中学习,因为演绎法是比归纳法强得多的逻辑体系。
假阳性的潜在影响
在演讲中,Gollnick 谈到,理解推理的局限性会导致“对数据作为一种工具的强大理解,你可以利用它成为一名更好的数据科学家。”例如,Gollnick 引用了过去十年中广泛的癌症筛查是如何导致假阳性的。筛查方案已经变得不那么频繁,并考虑该人是否属于高危人群。虽然有些人可能更喜欢假阳性,但 Gollnick 也要求观众考虑“我们可能正在治疗他们没有患的癌症的可能性。想想化疗的作用……人们可能会死于癌症治疗。”Gollnick 提到“寻找更少和更有针对性的人群”的方法目前正在使用,“因为当你的搜索更有针对性时,数据和证据会更好地发挥作用。”
结论
在 Strata talk 中,Gollnick 讲述了数据和推断是如何成为工具的。有潜力有效解决正确问题的工具。然而,工具也有局限性。例如,Gollnick 提到了那些没有考虑如何“理解数据,推断的极限”的科学家是如何导致再现性危机的。Gollnick 在结束讲话时重申,数据是一种工具,“当你是数据科学的从业者时,如果你有选择,就选择正确的问题。”
^(Domino 数据科学领域笔记提供数据科学研究、趋势、技术等亮点,支持数据科学家和数据科学领导者加快工作或职业发展。如果您对本博客系列中涉及的数据科学工作感兴趣,请发送电子邮件至 writeforus(at)dominodatalab(dot)com。)
高级 Jupyter 笔记本技巧
原文:https://www.dominodatalab.com/blog/lesser-known-ways-of-using-notebooks
我喜欢 Jupyter 笔记本!它们非常适合试验新的想法或数据集,虽然我的笔记本“操场”开始时一片混乱,但我用它们来为我的最终项目建立一个清晰的想法。
Jupyter 非常适合交互式探索性分析,因此很容易忽略它的一些其他强大功能和用例。我想写一篇博文,介绍一些鲜为人知的使用 Jupyter 的方法——但是太多了,所以我把这篇博文分成了两部分。
在今天的第 1 部分中,我将描述如何使用 Jupyter 创建管道和报告。在下一篇文章中,我将描述如何使用 Jupyter 创建交互式仪表盘。
本博客的配套项目可以在 多米诺数据科学平台 上找到。
魔法
你可能知道你可以用不同的内核启动笔记本(比如 R,Julia)——不仅仅是 Python。您可能不知道的是,即使在笔记本中,您也可以在不同的单元中运行不同类型的代码。有了“魔法”,就有可能使用不同的语言。然而,不同的笔记本内核有不同的魔法。
通过在单元格中运行% lsmagic
,你会得到所有可用魔法的列表。您可以使用%
启动一个单行表达式来运行 magics 命令。或者你可以使用一个双%%
来运行一个多行表达式。
我最喜欢的一些是:
% env
列出你的环境变量。!
:运行 shell 命令。例如! pip freeze | grep pandas
看熊猫装的是什么版本。% matplotlib inline
在笔记本内显示 matplotlib 图。- 将代码上传到 pastebin 并获取返回的 url。
% bash
在子进程中用 bash 运行 cell。
%time
无论你评价什么,时间都会%%latex
将单元格内容渲染为乳胶
%timeit
将你评价的任何东西多次计时,给你最好的和平均的次数
%prun
、%lprun
、%mprun
可以给你一个函数或者脚本中时间和内存使用的逐行细分。Pynash 提供了一个很好的教程来教你如何使用它们。%% HTML
:将单元格渲染为 HTML。因此,您甚至可以在笔记本中嵌入图像或其他媒体:
你甚至可以使用魔法在一个笔记本中混合不同的语言。例如, rmagics 让你在 Python 笔记本中运行 R 代码——包括绘图。注意,首先需要加载rmagics
扩展。
正如在 rmagics 文档中所描述的,您可以使用%Rpush
和%Rpull
在 R 和 Python 之间来回移动值:
你可以在网上找到其他语言魔法的例子,包括 SQL 魔法和 cython 魔法。你可以在这里阅读更多常见的魔法。说真的,你可以花一整天来学习这些!
管道
魔法本身是很方便的,但是当你把它们结合在一起时,它们真的会发光。这些函数可以通过组合不同语言的步骤,帮助您在一个可视化流程中创建管道。熟悉 magics 可以让你在每个子任务中使用最有效的解决方案,并为你的项目将它们结合在一起。
当以这种方式使用时,Jupyter 笔记本变成了为数据科学工作量身定制的“可视外壳脚本”。每个单元可以是管道中的一个步骤,可以直接使用高级语言(例如 R、Python)或低级 shell 命令。同时,您的“脚本”还可以包含格式良好的文档和流程中各个步骤的可视化输出。它甚至可以记录自己的性能,在其输出中自动记录 CPU 和内存的使用情况。
批处理、调度和报告
像任何其他 Python 脚本一样,也可以在批处理模式下运行您的笔记本。通过使用 nbconvert ,你可以非交互地计算整个笔记本,将其保存在适当的位置或保存为各种其他格式。
这种能力使笔记本成为 ETL 和报告的强大工具。对于报告,只需安排您的笔记本自动重复运行,并更新其内容或通过电子邮件将其结果发送给同事。或者使用上述 magics 技术,笔记本也可以实现数据管道或 ETL 任务,以便按自动计划运行。
预定仪表板
假设你要定期给同事的邮箱发一张叶子图,上面有过去一天的所有地震。
要做到这一点,你首先需要一个定期更新(至少每天)的地震数据集。有一个每 5 分钟更新一次的数据馈送。然后,您可以使用 Jupyter 编写代码来加载这些数据并创建地图。
Domino 让你安排任何脚本定期运行,这对于 ipynb 文件和其他文件一样有效。当它运行预定的执行batchdemo.ipynb
时,Domino 将计算笔记本并用最新的结果更新它的单元格。
合作者可以访问该页面,在浏览器中查看更新的笔记本——无需运行 Jupyter 服务器。因此,您的笔记本已经成为一个随时更新的仪表板。
带有 magics 和 HTML 导出的预定仪表板
更进一步的是结合 magics 的流水线技术,将整个笔记本变成一个 HTML 报告。下一个示例展示了如何首先使用一个 shell 脚本来检索一个网页(https://www.sfgate.com ),这个网页是用 Python 在 wordcloud 中可视化的。然后,作为计划运行的一部分,它被转换为包含运行结果的 HTML 页面。您可以设置您的计划运行,以自动通过电子邮件将任何结果(例如,您的笔记本呈现为 HTML)发送给您的同事。
当您用内联可视化完成笔记本时,创建一个类似于以下内容的 shell 脚本:
ipython nbconvert --to html pipelinedashboard.ipynb
在调度这个 shell 脚本之后,结果将是您的笔记本上一次运行的常规 HTML 版本。
为您的 Jupyter 笔记本寻找更多技巧?请参阅我们的指南,了解如何在 Jupyter 笔记本中创建交互式仪表盘。
20 个数据科学团队的经验教训
原文:https://www.dominodatalab.com/blog/lessons-from-20-data-science-teams
如果你观察 20 家大公司的数据科学团队,你能学到什么?
我向多米诺数据实验室的产品总监 Mac Steele 寻求答案。Mac 将他从观察数据科学团队中学到的经验与来自 CRISP-DM 和敏捷的概念相结合,创建了 Domino 数据科学生命周期。这是在一份 25 页的白皮书《大规模管理数据科学实用指南》中定义的。
创造不同方法的动机
在他职业生涯的早期,Mac 意识到像 Scrum 这样的软件方法论在应用于数据科学时“并不那么有效,因为事情不会以同样的方式在两周内神奇地发生……你没有可以交付的、可以被用户每两周观察到的增量功能。”他发现“一个非常传统的强制 Scrum 过程在数据科学工作流程的评分中似乎更多的是无益的,而不是有益的。”
最近在 Domino 工作时,他同样发现一些客户在努力成功地执行数据科学项目。项目的“书立”,即开始时的初始阶段和结束时的监测阶段,特别具有挑战性,部分原因是现有的方法没有适当地定义这些阶段。此外,缺乏团队角色定义。总的来说,这导致了无效的场景,其中“数据科学做了一些事情,然后有一堵硬墙,他们将他们的工作交给 IT 部门,后者最终重写了它”,但不了解如何监控和维护产品化的模型。为了取得成功,“你应该从一开始就让 IT、数据科学和业务参与进来”,每个团队从构思到产品退役都承担明确的角色。
Mac 承认,Domino 的方法、CRISP-DM、微软的团队数据科学过程(T1)和其他方法“并没有什么不同,因为数据科学中有几个不可协商的方面。区别在于人们在哪里添加了重点,以及他们带来的不同维度。我们试图引入的维度是人员、流程和技术维度。”
Domino 数据实验室的生命周期方法。查看他们的白皮书的最后一页,获取完整版本。
未来趋势
我问 Mac,如果他重新写一份更新版本的方法论和白皮书,他会有什么不同的做法。他回应说,“去年,我看到和听到了更多关于更好地检查偏见和公平的内容,如良好的数据科学道德检查,这将成为标准的操作实践,不管它们是否受到监管,因为消费者将越来越多地要求这样做。”
此外,当被问及数据科学项目管理的未来时,他回答说,“人们将从学术界和研究机构学到更多东西,因为他们将开始意识到他们所做的事情从根本上来说是研究[…和…]你正在进行的项目可能不会成功,这没关系。像制药公司和其他医学研究公司这样的公司已经做了很长时间,我敢打赌人们会从他们那里学到更多。”
同样,他认为产品管理的概念作为数据科学功能的一个独特的子学科正在成熟,就像它在软件工程中一样。“软件领域的产品管理在很大程度上负责将问题概念化,提出解决方案的形式,然后在后端处理用户采用和用户参与,并推动您希望的价值。现在,我们有数据科学家扮演开发者和产品经理的角色,我认为这种情况不会持续下去。”
时间会证明一切,但我认为他是对的。
生命科学团队:在通往云计算的道路上避免这些常见的陷阱
许多生命科学组织正在进行数字化转型。其中的一个关键部分是将现有的内部 IT 平台、统计计算环境(SCEs) 以及相关的编程语言和工具迁移到云中。研究和数据科学职能代表着这些云迁移的唾手可得的成果,因为它们的工作流需要动态访问计算基础架构和集中访问不同的工具集。
集中数据科学功能及其相关工具的流程提供了两个重要机会:解决传统数据中心和基于桌面的分析环境随着时间推移而增长的挑战,以及通过自动化和底层技术将最佳实践“硬编码”到流程中。
在云中运行数据科学的好处是巨大的:
- 如果您的组织能够在需要时访问高性能计算资源,但只需为所用资源付费,那么就有可能节省大量成本。
- 工具访问的标准化和集中化意味着 IT 可以有效地管理和治理跨团队的技术环境,从而提高安全性和合规性。
- 将最佳实践融入底层技术带来的巨大生产力提升可以在三个层面上实现:研究和相关工件的自动再现加速了员工入职,减少了手动文档记录,并促进了跨团队协作和对过去工作的可访问性。
但是,迁移到云仍然在许多生命科学组织的“待办事项”列表中是有原因的。这是一个复杂的过程,需要时间。SCE 通常由许多不同技术的许多不同部署组成,所有这些部署都必须满足有关安全性和法规遵从性的内部和外部要求,例如 HIPAA。
如果你的团队开始踏上云之路,这里有一些我们在这个领域看到的常见陷阱。通过让人们意识到这些挑战,我们希望您能够提前制定缓解策略,并更快地实现云计算。我们还鼓励您阅读我们的白皮书,该白皮书根据我们与成功实现数字化转型的企业的合作经验,提供了生命科学数字化转型的最佳实践。
1.研究人员无法访问他们需要的计算资源。
由于在获取大型服务器环境的访问权限方面存在开发运维难题,研究人员最终只能在笔记本电脑上完成大部分工作,难以跟上呈指数级增长的数据量。
研究人员感到沮丧,浪费了宝贵的时间来跨越基础架构的重重障碍,组织的研究环境变成了一个由“影子 IT”和分散的孤岛组成的复杂网络。
2.数据科学工具的技术前景在不断变化,在新技术可用和研究人员可以使用它们之间产生了一个延迟。
研究人员希望——也完全有权利——使用最新、最好的工具来完成手头的任务。这个领域正在发生大量的创新。几乎每天都有新的和改进的工具推出,其中许多是开源的。与此同时,有许多用户希望使用更传统的专有技术,如 SAS 和 T2 MATLAB。
每种工具都推动商业价值,但每种工具都有其局限性,特别是如果它没有集成到企业范围的数据科学战略中。SAS 和 MATLAB 功能强大,在受监管的环境中受到大型企业的信任,但是它们与开源技术合作的能力有限。他们还经常复制数据,这可能需要昂贵的数据存储基础架构。
另一方面,R 和 Python 等开源工具通过利用容器和编排工具来简化部署和管理,从而降低存储成本。他们也可以接触到更广泛的人才基础。但开源工具面临着相对较慢的数据访问、重新编码和版本控制方面的挑战,并且无法提供与专有工具相同的数据、模型和流程治理能力。
数据科学家不能浪费时间等待第三方或系统管理员做出更改或获得新技术,但 IT 需要确保新技术安全地引入组织,并进行必要的治理。
IT 部门如何提供对各种技术的访问,同时确保这些技术符合公司指令和法规要求?他们如何提供一个环境,让研究人员可以在不引起问题的情况下,跨不同工具组合一系列作业执行?团队如何维护跨越 SAS、Python、R 和其他库的可重复的工作流链,以支持各种涉众和业务案例?
积压不可避免地累积起来,导致研究人员和 IT 之间的挫折感,并导致“影子 IT”情况,即研究人员不仅局限于他们笔记本电脑上的计算资源,而且他们还运行多个 SAS、R、Python 和 MATLAB 孤岛。
3.它无法跟上基于云的软件发布的现代交付模式。
尤其是在处理敏感数据的生命科学环境中,IT 部门通常需要花费四至八个月的时间来验证内部部署系统的每个新版本的软件升级。他们习惯了这种可预测的升级周期;他们可以为此做计划。但是,基于云的软件供应商并不局限于旧的运营方式,现在每年部署几次新的软件版本已经司空见惯。
IT 团队还没有想出如何适应新的节奏,并且每次升级都要消耗多名支持人员、管理资源或能力,否则这些资源或能力将被花费在宝贵的研究工作流程上。
更糟糕的是,IT 部门无法很好地控制在许多孤立的系统中使用的每个工具的版本。试图跟上并为分布式团队提供支持会导致巨大的支持开销。我们经常听到 IT 领导评论说,他们有一个团队专门支持整个组织中所有商业工具安装的滚动升级。
4.不必要的摩擦和重复的工作来自于活动的竖井和不一致的版本控制。
特别是对于地理上分散的团队,人们在没有意识到的情况下在每个组织的口袋里重新创建相同的工作。由于无法看到过去已经创造了什么,研究人员从零开始每个项目,或者在一次性设置中向他人询问过去的工作。
当研究人员要求其他人参与同行评审时,几乎不可能知道给定的分析使用了什么版本的 R、Python 和/或 SAS。这也使得重现过去的工作成为一项复杂的任务。
5.半手工版本控制浪费大量时间。
花费在手动或半手动流程上的时间转化为花费在进一步分析或转移到下一个项目上的时间更少。即使研究人员实现了手动版本控制方法,它也存在于源代码级别,而不存在于实验级别;软件版本等。,没有被捕获。满足模型起源的需求是痛苦的,需要大量的特别工作来手动审计工作文档和导致特定分析和结果的工具的特定版本。
6.数据科学领导者努力将资源高效地分配给可见性有限的项目。
数据科学领导者负责为项目分配合适的数据科学家,但这通常是心血来潮,或者基于来自研究人员和业务线利益相关者的轶事般的临时输入。数据科学领导者很难获得透明度并了解他们团队和/或更广泛组织的工作状态。
此外,如果他们确定需要将资源重新分配给不同的项目,那么让新的贡献者跟上进度的工作很少是值得的。最终需要更长的时间来交付高质量的成果,并且难以衡量数据科学团队的效率。
隧道尽头的光。
许多行业领先的组织在向云发展的过程中成功应对了这些挑战。意识到这些挑战并将其作为集中研究和数据科学功能的更大战略的一部分非常重要,利用技术可以让研究人员使用他们喜欢的工具,在需要时访问计算,并自动执行可能导致大规模不一致和低效率的手动工作。
要深入了解在云中实施面向未来的数据科学实践的成功生命科学企业所采用的最佳实践,请阅读白皮书:
闪电般快速的基于 CPU 的图像字幕管道,具有深度学习和光线
骨架公式和 InChI 标签之间的转换是一个具有挑战性的图像字幕问题,尤其是当它涉及大量的噪声数据时。在这篇博文中,我们分享了 BMS 分子翻译挑战赛的经验,并展示了基于 CPU 的分布式学习可以显著缩短模型训练时间。
背景
在 2000-2004 年期间,国际纯粹与应用化学联合会(IUPAC)开发了 InChI 标签系统-一种化学物质的文本标识符,旨在提供一种编码分子信息的标准方法。InChI 标签本质上是一长串字母和符号,用于识别化学物质,并便于在数据库和网络上搜索。记住,InChI 标准于 2005 年正式发布,可以理解的是,早于化学文献发布了描述化学物质的其他方法。遗留文档中采用的最常见的方法是结构公式的纯图形表达式(也称为骨架公式)。
图 1 :英制表示(上)对比骨骼公式(下)
百时美施贵宝(BMS)是一家美国跨国制药公司,总部设在纽约市。BMS 拥有 30,000 多名员工,2021 年收入超过 410 亿美元。鉴于该公司 135 年的历史,很容易想象这些年来 BMS 积累了大量包含分子信息的研究文献。处理这种类型的数据具有挑战性,因此毫不奇怪,BMS 发布了一个公开的 Kaggle challenge ,旨在采用机器学习来实现骨架公式和 InChI 标签之间的自动化翻译。
应对 BMS 挑战
Domino 数据实验室的现场数据科学服务团队决定尝试 Bristol-Myers Squibb 挑战,特别是在尝试可以利用按需分布式计算的新工具和框架的背景下。支持大规模数据科学(包括按需分布式计算)是 Domino Enterprise MLOps 平台的关键价值主张之一,因此该团队希望研究该平台提供的 devops 自动化与 Ray 等分布式计算框架的流行之间的协同作用。
这个项目的原始代码,受使用 COCO(上下文中的公共对象)数据集 的图像字幕工作的启发,利用了标记图像的技术。我们使用了几个计算机视觉算法来消除斑点,锐化和清洁图像,然后将它们输入管道。像在 COCO 数据集上的早期工作一样,我们使用迁移学习和自然语言生成进行图像标记。在完成初级图像处理后,我们注意到训练时间长度的潜在问题。在 Domino Data Lab,我们知道长时间的模型训练是实现 高模型速度 和将组织转变为成功的模型驱动型企业的关键障碍。
我们注意到,由于数据的规模和问题的复杂性,一些 Kaggle 竞争对手花了一周多的时间来训练他们的图像标记系统,尽管使用了 GPU 或加速计算。这种方法在现实世界中并不实用,因为很难访问 GPU 以及相关的基础设施成本。我们想知道使用分布式系统——在这个例子中是 Ray——是否能够在减少训练时间的同时使用 CPU。
图像识别和标记在过去七年中一直是计算机视觉中的规范技术(Voulodimos A 等人, 2018 )。BMS 面临的挑战是,旧文献中创建的许多图像质量较差;斑点和模糊。我们在这个项目中的第一个目标是纠正这个问题。
比赛数据集由超过 250 万张图像组成,每个示例都是带有相应标签的斑点和非锐化图像。大约 250 万张图像的测试数据集也没有标签。因为所提供的数据集只显示了每个标签一次,所以我们在类似于半监督框架的框架内将此作为标签问题来处理。我们训练了所有的数据,并留出了一个从训练数据中随机选择的验证数据集供将来使用。在目前的工作中,我们只专注于加快训练时间。
我们的总体目标是确定仅使用 CPU 在 Ray 上训练一个基本的图像标记算法架构需要多长时间。选择 CPU 比选择 GPU 或者 TPU 有很多优势。首先是 CPU 在云计算平台上更容易获得。已知 GPU 可用性不足。第二是成本。与 GPU 相比,云计算每小时对 CPU 的使用显著减少。我们进行这个实验的第三个也是最重要的原因是确定我们是否可以减少基本图像标记架构的训练时间。
我们的第一步是完成图像处理。为此,我们使用了 OpenCV ,一个基于 Python 的计算机视觉库,结合 Ray 来加速处理时间。我们发现解压缩和处理 250 万张图像需要大约 6 个小时(相比之下,我们之前的尝试需要几天)。我们的图像处理流程包括利用 OpenCV 进行图像去斑,然后进行图像锐化。我们后来使用干净的存储图像进行深度学习。
我们的工具箱
Ray 是一个开放的框架,数据科学家可以使用它进行并行和分布式计算。它使用起来很简单,因为将一个简单的函数转换成一个射线函数所需要的只是一个修饰符“@ray.remote”。然后,数据科学家可以使用远程功能将数据放入内存,并行处理数据,或将数据处理分配给工作人员并获得结果。下面的代码是一个我们转换成 Ray 的函数及其运行时间的例子。
%%time
@ray.remote
def build_captions(data):
captions = Field(sequential=False, init_token='', eos_token='')
all_captions = data['InChI'].tolist()
all_tokens = [[w for w in c.split()] for c in all_captions]
all_tokens = [w for sublist in all_tokens for w in sublist]
captions.build_vocab(all_tokens)
return captions
captions = ray.get(build_captions.remote(data))
@ray.remote
def build_vocab(captions):
class Vocab:
pass
vocab = Vocab()
captions.vocab.itos.insert(0, '')
vocab.itos = captions.vocab.itos
vocab.stoi = defaultdict(lambda: captions.vocab.itos.index(''))
vocab.stoi[''] = 0
for s,i in captions.vocab.stoi.items():
vocab.stoi[s] = i+1
return vocab
vocab = ray.get(build_vocab.remote(captions))
CPU times: user 10.6 ms, sys: 4.12 ms, total: 14.7 ms
Wall time: 1.73 s
清单 1: 一个使用 Ray decorator 将没有并行化或分布式的函数转换成可以以并行或分布式方式运行的函数的例子。Ray decorator 将函数更改为远程函数,简单的 put 和 get 命令将对象放入存储并检索处理后的结果。我们看到,处理 250 万个样本标识符的挂钟时间不到 5 秒。
关于 Ray 的全面“入门”指南,请看一下博客上的 Ray 教程 。如果你想知道 Ray 与 Spark 和 Dask 等其他分布式框架相比如何,请查看我们的帖子 Spark、Dask 和 Ray:选择正确的框架 。
除了利用 OpenCV 满足我们的计算机视觉需求,我们还广泛使用了另外两个库。其中包括用于图像识别和标记的 PyTorch 和用于算法堆栈训练的 Ray 的 SGD 库。
实验
一旦我们处理了图像的训练集,我们的第一个任务是执行,即在图像标签上进行标记化。对于这个过程,我们选择了 PyTorch 库之一 TorchText。我们创建了一个通用的标记器来处理图像标签,然后创建了 PyTorch 文本库来嵌入标签。一旦标签被嵌入以匹配它们的图像,我们就创建了图像训练管道。这条流水线由一个编码器和一个解码器组成。编码器利用 转移学习 对带有各自标签的图像进行编码。我们针对预训练的模型 Resnet50 执行迁移学习。为了获得模型的输出以提供给解码器,我们移除了 Resnet50 模型的最后一层,并将特征提供给我们的解码器。
LSTM 包括我们的图像和标签解码器。解码器获取编码器(一个使用转移学习训练的卷积神经网络)的输出,并为每个图像创建一组标签。通过 Levenshtein 评分,可以对结果进行评估。我们使用 Levenshtein 分数来确定两个字符串的相似程度(即,实际图像标签和预测图像标签)。从 Levenshtein 分数计算的相似性分数的一个小子集,我们发现相似性的范围在 43%和 84%之间。我们没有计算所有 250 万样本的总体相似性得分,但这是未来目标的计划。我们当前的目标是模拟主要的图像标记管道,并确定是否可以使用 Ray 和一组 CPU 来改进训练。我们选择的工作流程如下所示。
图 2 :创建图像标注系统的流程。注意:在 200 万个训练样本中,每个图像都是唯一的 InChi,并且只表示一次。然而,同一分子的图像可以旋转,事实上,在测试数据集中是随机旋转的。为此,训练集中的每个图像只表示一次。IC 包括一个编码器(经过迁移学习训练——基本完成/编码完成)和一个解码器(RNN 或 LSTM ),用于根据图像的成分创建“字幕”。
我们的实验计划在过程的早期就改变了。最初,我们计划在培训过程中利用两种先进的技术。这些包括注意机制和光束搜索。我们发现,当我们优化基本标记实验时,优化这两种技术是不实际的。因为我们的总体目标是确定我们是否可以对训练时间进行基准测试,所以我们决定在第一个实验中省略激活函数和光束搜索。
图 3: 我们原本打算使用一种注意力机制和光束搜索(高级计算机视觉技术)。然而,我们的第一个目标是对一个规范的图像标记管道进行基准测试,所以我们决定省去注意力机制和光束搜索,只关注 Ray 的基准测试。左边是我们决定使用的算法堆栈,右边是原始的算法堆栈。
结果
我们的模型是图像标记管道的基本版本,就像在(Kishore,V,2020)中使用的那样。它非常接近(只缺少一个注意力机制)Kaggle 比赛的第二名冠军。这个团队的工作花了七天多的时间在单个 GPU 上进行训练。我们发现我们的培训需要大约一天半的时间,大大减少了时间。虽然我们没有使用注意机制,但我们对 Resnet50 使用了相同的数据传输学习机制,并使用 LSTM 作为我们的解码器。
总之,我们的训练管道包括标记化、使用 Resnet50 的编码器和利用 LSTM 的解码器,并显著减少了训练时间。在 Domino Enterprise MLOps 平台上运行这样的实验非常简单,因为系统抽象了基础设施的复杂性,从而使我们能够利用各种 CPU 后端计算实例。此外,Domino 提供的自助服务功能使得动态安装包变得很容易,开箱即用的 Ray 支持使得只需单击一个按钮就可以启动多节点 Ray 集群。
未来的实验
未来,我们计划复制第二名 Kaggle 获胜者使用的流程,在我们的管道中添加一个关注机制。然后,我们将再次测试 Ray workers 的使用,这次同时使用 CPU 和 GPU。我们也可以用波束搜索来研究技术的优化。现在,我们关注的是加快训练时间的优势。
参考
- 第二名获奖者的参赛作品:https://www . ka ggle . com/yasufuminakama/inchi-resnet-lstm-with-attention-starter
- 来自 Kaggle 分子翻译黑客马拉松的获奖解决方案,2021 年 6 月 17 日,URL:https://analyticsindiamag . com/winning-Solutions-from-ka ggles-Molecular-Translation-Hackathon/
- 现代计算机视觉与 Pytorch:探索深度学习概念并实现超过 50 个真实世界的图像应用。
- 计算机视觉的深度学习:简要综述。Voulodimos A,Doulamis N,Doulamis A,Protopadakis,e .计算智能与神经科学,2018。
用 Luigi 和 Domino 编排管道
原文:https://www.dominodatalab.com/blog/luigi-pipelines-domino
建立数据管道听起来可能是一项艰巨的任务。在本文中,我们将研究如何使用 Luigi——一个专门设计来帮助管道构建的库——来构建一个与 Domino 协同工作的数据管道。
什么是数据管道?
数据管道是进程(“任务”)的集合,每个进程对其他任务输出的数据进行操作。随着管道的转换,信息在管道中“流动”。
例如,统计模型开发的管道可能如下所示:
clean data -> extract features -> fit model -> predict
更复杂的集合模型可能如下所示:
clean data -> extract features -> fit models -> combine models -> predict
最简单的管道就是脚本中的一系列步骤。这通常就足够了,但并不总是如此。
例如,如果您后来添加了新的数据源或任务,并使管道的依赖结构变得复杂,您的脚本可能无法很好地伸缩。
此外,当任务失败时,最好不要重复前面的步骤,尤其是当任务快要结束时。一个失败的阶段可能会留下不完整或部分的输出,如果其他任务无意中使用了损坏的数据,这可能会引起连锁反应。
最后,脚本化管道可能没有考虑硬件限制,或者它可能无法充分满足某些任务对额外资源的需求(GPU、多个 CPU、额外内存等)。
路易吉
Luigi 是一个 Python 库,它通过解决这些和其他相关问题简化了数据管道的创建和执行。它起源于 Spotify,也被 Foursquare、Stripe、Asana 和 Buffer 等公司使用。它可以管理各种任务,包括用其他编程语言的操作,这使得它对于现代数据科学中典型的多语言项目非常有用。
使用 Luigi,您可以根据数据依赖性(其他任务的输出)来定义每个任务。在运行时,中央调度程序会自动为您选择执行顺序。Luigi 还支持原子文件操作(有助于确保可再现性)和自动缓存先前运行的管道步骤(可以真正节省时间)。
如果你对学习 Luigi 感兴趣,从官方文档中的概述开始。然后继续讨论执行模型和通用模式。你可能也想看看这个项目原作者的幻灯片概述。
Domino 上的多机管道
即使在单台机器上,Luigi 也是一个有效的工具。将它与 Domino API 的功能结合起来,通过允许管道在任意多个运行之间伸缩,赋予了它更大的能力。这可以通过添加几个额外的类来实现。
例如,您可以在混合的 GPU 和高内存实例上并行训练一组模型,然后收集生成的模型文件用于比较或其他用途——所有这些都通过一个命令启动。
远程执行
DominoRunTask
是luigi.Task
的子类,表示在不同的 Domino 机器上的远程执行。只需告诉命令远程运行,给它预期的输出位置,并指定硬件层。在运行时,DominoRunTask
将启动一个新的 Domino 运行,等待它完成,然后将输出复制回主管道运行,以便后续任务可以使用。
这里有一个简单的例子:
import luigi
from domino_luigi import DominoRunTask
class Hello(luigi.Task):
def output(self):
return luigi.LocalTarget('hello_world_pipeline/hello.txt')
def run(self):
with self.output().open('w') as f:
f.write('hello\n')
class DominoHelloWorld(luigi.Task):
def requires(self):
return DominoRunTask(
domino_run_command=['example_pipeline.py', 'Hello'], # --workers N
domino_run_tier='Small',
output_file_path=Hello().output().path,
)
def output(self):
return luigi.LocalTarget('hello_world_pipeline/hello_world.txt') def run(self):
def run(self):
with self.input().open('r') as in_f:
with self.output().open('w') as out_f:
out_f.write(in_f.read() + 'world\n')
这将开始第二次运行,创建输出文件hello_world_pipeline/hello.txt
。这个文件然后被初始运行检索,并且文件的内容被用来创建hello_world_pipeline/hello_world.txt
。
注意事项:
- 按照 Luigi 模式,外部运行的输出必须是单个文件。这是为了保证每个任务的原子性,可以防止数据损坏,有利于可复制性。如果您的外部作业创建了许多文件,只需创建一个 zip 存档,并将其作为输出。
DominoRunTask
接受一个名为commit_id
的参数,该参数指示 Domino 项目的状态,该状态将被用作运行的输入。如果没有提供这个参数,它默认为当前 Domino 运行的输入commit_id
。使用 UI 的文件浏览器时,可以在 URL 中看到commit_id
,例如https://app.dominodatalab.com/u/domino/luigi-multi-run/browse?commitId=1dee27202efaabe0baf780e6b67a3c0b739a2f4c
。
多机系综
DominoRunTask
可应用于预测模型开发。以这组模型为例:
- 用 R 写的随机森林,带有 H2O 图书馆。
- 使用 scikit-learn python 库的渐变增强模型。
- 用 nolearn 构建的神经网络(建立在千层面和 theano 之上)。
每个模型都可以在自己的机器上训练。随机森林模型可能在 X-Large 硬件层 上运行,而神经网络使用 GPU 层。由于每个训练任务都是它自己的运行,它们可以被单独检查。
您可以使用一个 Domino 命令开始训练和评估模型的整个过程:
domino run example_ensemble.py ScoreReport --workers 3
这对于按照时间表重新训练来说很方便。
在开发过程中,您可以通过运行不同的任务来处理管道的子组件:
domino run example_ensemble.py TrainRForest
成功完成后,生成的模型文件可用于管道的后续运行,而无需重新训练。
注意事项:
- 在这个示例项目中,随机森林训练和预测代码在
forest_train.R
和forest_predict.R
中找到。请注意压缩包含 H2O 模型的目录所采取的额外步骤;添加这些是为了确保任务的原子性。 - 这些模型尚未调整。目的是以可扩展的方式说明概念验证,而不是呈现最佳匹配。
用 GPU 启动机器学习
无论您是机器学习爱好者,还是为各种应用程序训练模型的忍者数据科学家,您都可能听说过需要使用图形处理单元(GPU),以便在训练和扩展模型时获得最佳性能。这可以概括为,如果不使用 GPU,当移动到更大的数据集时,在 CPU 上需要几分钟才能完成的基于小数据集的训练任务可能需要几个小时、几天甚至几周。GPU 加速是我们之前讨论过的一个话题;参见“ 用 GPU 和 Theano 更快的深度学习”。
在这篇文章中,我们将探索为什么 GPU 是机器学习和深度学习的最好朋友的一些原因,以及这种友谊是如何产生的。一个很好的起点是查看中央处理器,或 CPU,并建立我们对 GPU 加速如何发生的理解。然后我们将讨论一些使用库的开发,比如 NVIDIA 的 CUDA 和 RAPIDS。
中央处理器(CPU),或计算机的大脑
你可能已经看过一些描述计算机的照片,它们占据了一两个房间,而不是放在你的手中。以电子数字积分器和计算机(【ENIAC】)为例,它在 20 世纪 40 年代中期是最早的可编程通用计算机之一。像这样的计算机实际上是专门建造的:ENIAC 是一台十进制计算机(不是二进制的!),用 20 个电子累加器作为存储中间运算结果的寄存器,占地 167 平方米。从那时起,计算机的中央处理器发生了很大的变化,公平地说,我们许多人都不会再考虑处理器的容量,这些处理器不仅为我们的计算机供电,也为电话、电视、汽车和自动售货机供电。如果我们停下来考虑一下,我们可以看到 CPU 实际上是这些设备的大脑,告诉其他组件做什么和什么时候做,并遵循软件提供的指令。如果没有 CPU,你可能无法像现在这样轻松地阅读这篇帖子。
20 世纪 70 年代初微处理器的出现标志着计算机使用的大脑发生了变化。几乎就在 50 年前的今天,随着英特尔 4004 芯片的发布,我们开始了一段延续至今的旅程。英特尔 4004 实际上是世界上第一个通用可编程处理器,这一成就之后,英特尔发布了 8 位 8080 微处理器,使我们能够表示 128 到+127 范围内的有符号数字。这听起来可能不是很多,但它足以执行算术计算,而不需要一个自己的房间。除了英特尔,其他著名的 8 位竞争对手包括 Zilog Z80 和摩托罗拉的 6800 微处理器。16 位设计出现后,32 位版本很快出现,如英特尔 i386 芯片能够表示+/-2x10^9.范围内的有符号数 32 位芯片的另一个著名例子是摩托罗拉的 MC68000,用于 苹果丽莎 以及 雅达利 ST 和Commodore Amiga。从 20 世纪 90 年代开始,标准就是使用 64 位处理器。值得一提的是 AMD64 以及英特尔的 x86-64 芯片。两者都能够向后兼容 32 位遗留应用程序和 64 位本机应用程序。
故事还在继续,例如最近宣布的 2020 年苹果 M1 的,接着是 2021 年的【M1 Pro】和 。让我们以 M1 为例:它被设计为用于苹果平板电脑、手机和笔记本电脑的 CPU 和 GPU 组合,它被宣传为“低功耗硅中最快的 CPU 核心,世界上最好的 CPU 性能功耗比,世界上最快的个人电脑集成显卡,以及苹果神经引擎的突破性机器学习性能。”现在你知道了,多亏了芯片,机器学习加速了。
众所周知的“摩尔定律”概括了思考微处理器及其功能演变的一种方式,该定律表明,与成本相比,集成电路的复杂性大约每两年翻一番。自 20 世纪 70 年代以来,这一经验观察一直很有效。因此,摩尔定律的自我实现预言不仅影响了电子行业,还影响了任何其他需要跟上增长的行业。尽管如此,保持这种指数曲线变得越来越难,甚至戈登·摩尔 在 2015 年公开表示 同名法律可能在未来几年内不再流行。
无论如何,CPU 不是计算机中唯一的动力。虽然您可以使用 CPU 做很多事情,包括内核数量、时钟速度和线程,但其他组件可能更适合一些任务。带来强大的图形处理单元。
图形处理器是计算机的灵魂
如果说 CPU 是我们电脑的大脑,有人说 GPU 就是它的灵魂。在这里,我认为 GPU 是机器学习任务的核心。GPU 是电子组件,它让我们加速在计算机随机存取存储器(RAM)中用于驱动视频显示器的部分创建图像。RAM 的这一部分被称为帧缓冲区,典型的显卡包含帧缓冲电路,可以让我们在显示器上显示内容。可以想象,在相当长的一段时间里,视频游戏中 GPU 的使用一直是一个重要的应用。在早期的 arcades 中,用于帧缓冲的 RAM 并不是最便宜的东西,并且不是添加更多的内存,而是使用专门的电路来帮助 CPU 完成这项任务。这些早期灵魂的一个很好的例子是雅达利使用的 电视接口适配器 。
你可能熟悉甚至用过一些 20 世纪 80 年代早期的单色显示器。如果是这样,你可能已经使用了日立的 ARTC HD63484 处理器,支持令人印象深刻的 4K 分辨率。我们在谈论 CPU 时提到了 Amiga 准将。嗯,你不会惊讶地听到,它还附带了自定义图形硬件,加速位图操作。如果你不是那个年代的人,你肯定听说过视频图形阵列(VGA ),它是由 IBM 在 80 年代末推出的,多年来一直被用作显示标准。你可以使用这样的硬件以加速的方式渲染二维图形,但计算机和主机游戏对 3D 渲染的需求提供了创建电路板的途径,如 世嘉 1 型和 2 型 或 Namco System 22 。
这些例子实际上都不叫 GPU。 这个术语据说是索尼 首先使用的,指的是 1994 年 12 月发布的 PlayStation One 中使用的 32 位东芝图形芯片。其他人认为这个术语应该归功于英伟达的 GeForce 256 的营销。GeForce 256 的一个重要方面是从 CPU 卸载几何计算等任务。GeForce 256 能够在 220 纳米光刻工艺中实现 50 千兆浮点运算性能,而 GeForce RTX 2080 Ti GPU 等更现代的同类产品支持 14.2 万亿次浮点运算,并基于 12 纳米工艺构建。换句话说,游戏玩家是一群快乐的人,他们拥有 GPU,可以让他们充分体验旗舰游戏,使用阴影体积,高程映射和其他许多东西的精确折射。然而,这种加速并没有被拥有同样引人注目的应用程序的其他用户所忽视。
以重新利用一些旧的游戏机 来建造一台研究黑洞的超级计算机为例。据报道,在游戏控制台 中使用 cell 处理器和 Tesla CUDA GPU有助于将传统计算机的计算速度提高近 10 倍,以模拟引力波。从游戏和计算机图形向其他应用的转移并非偶然。当你比较 CPU 和 GPU 时,原因就很明显了。例如,CPU 的内存需求高于 GPU,GPU 具有更高的处理速度,并且可以并行处理指令,这与 CPU 的串行特性相反。相当长一段时间以来,英伟达等公司一直在从战略上思考这些应用,包括机器学习。
深度学习的核心 GPU
可以用机器学习和深度学习算法解决的各种问题一直在增长,随着对更大和更多样化数据集的访问,这些模型的复杂性也在增加。因此,GPU 提供的加速是一个受欢迎的功能,许多机器学习实践者和数据科学家都热衷于利用这一功能。例如,考虑典型的简单神经网络的训练,该神经网络具有包括一个输入层和一个输出层的结构。如果输入层有 4 个单元,输出层有 2 个单元,则需要计算 8 个连接或参数。这应该是一个即使用手也很容易解决的问题。随着层和单元数量的增加,我们有越来越多的参数需要计算和跟踪,特别是当我们将反向传播应用于我们的神经网络时。对于成千上万的参数,一个强大的 CPU 可能会有所帮助,但随着我们继续深入深度学习中使用的神经网络的隐藏层,参数的数量增长到 数百亿 。
来源:英伟达
如果我们不使用 CPU,而是使用 GPU,那么我们的计算速度会加快,这要归功于更多的内核和它们支持的并行化。NVIDIA 通过创建一个名为 Compute Unified Device Architecture(简称 CUDA)的并行计算平台和编程模型,让程序员能够直接、自由地访问 GPU 的并行计算元素,从而使驾驭 GPU 的能力成为可能。CUDA 旨在与 Fortran 和 C/C++等强大的编程语言一起工作,让“开发人员表达大量的并行性,并将编译器引导到应用程序中映射到 GPU 的部分”,正如 NVIDIA 自己所说的。因此,并行化在许多应用中都可以实现,不仅是机器学习,还包括使用高性能计算的领域,如物理、科学建模、医学,甚至创意艺术。
特定应用程序的专门化甚至可能运行到 GPU 的核心,这绝对是故意的。就拿泰坦 RTX 来说吧,用来“驱动人工智能、机器学习和创造性工作流”,相比之下,GTX 1080Ti 就是 #GameReady 。类似地,支持这些设备的库也是专门化的。例如,CUDA-X AI 的库带来了 RAPIDS 等实现,让数据科学和数据工程师合作构建完全在 GPU 上运行的端到端管道:从数据准备任务到 cuML 中流行的机器学习算法的实现,包括一个名为 cuDF 的类似熊猫的数据报库,甚至还有一个名为 cuGraph 的网络分析库。RAPIDS 能够与其他深度学习库集成,甚至支持基于 Python 的可视化库,使数据科学家更容易专注于他们最了解的东西。Domino MLOps 平台全面集成了上述技术,并且由于 Domino/NVIDIA 的合作关系,可以利用 GPU 加速计算,无缝使用 RAPIDS,并利用开箱即用的 NVIDIA 容器 。你可以通过观看 Domino/NVIDIA 联合举办的名为 如何使用 Domino & NVIDIA 简单运行复杂的 AI 训练&推理工作负载的网络研讨会的录像来了解更多信息。
摘要
在这篇文章中,我们讨论了为什么 GPU 加速是增加模型复杂性时要考虑的事情。CPU 是计算机的重要组成部分,而 GPU 执行更专业的任务。CPU 适用于延迟或每核心性能非常重要的任务,以便快速执行任务。GPU 是一种通用并行处理器,它可能已经开始为适用于游戏的图形和 3D 渲染任务提供动力,但今天我们能够利用它来使机器学习任务更加高效和快速。
借助 NVIDIA 的 CUDA、CUDA-X AI 等专用库,我们能够更好地利用我们的 GPU。此外,专门的高级库和 API(如 RAPIDS)使我们比以往任何时候都更容易入门。NVIDIA 有许多资源,包括一些关于深度学习、加速计算和数据科学的在线课程。
生产中的机器学习:软件架构
原文:https://www.dominodatalab.com/blog/machine-learning-in-production-software-architecture
特别感谢Addison-Wesley Professional允许从书中摘录以下“软件架构”章节,生产中的机器学习。本章节选为数据科学家提供了在将机器学习模型应用于生产时需要考虑的见解和权衡。另外,如果您有兴趣了解 Domino 如何为您的模型提供 API 端点,请查看 Domino 支持站点上的视频教程。
介绍
在 Domino T1,我们与各行各业的数据科学家合作,从保险和金融到超市和航空航天。我们收到的最常见的问题之一是,“我如何将我的模型投入生产?“这是一个很难回答的问题,没有软件是如何架构的背景。作为数据科学家,我们需要知道我们的代码,或者代表我们代码的 API,如何适应现有的软件栈。只有到那时,我们才能开始与我们的工程师就将模型整合到产品中进行严肃的讨论。
为了给与工程师的对话打下基础,我与 Domino 的内容负责人合作,请求Addison-Wesley Professional(AWP)允许从书中摘录以下“软件架构”章节, 生产中的机器学习 。非常感谢 AWP 的适当许可。
17.1 软件架构:章节介绍
如果您考虑构建和运行给定应用程序或数据管道的总成本,您会发现有两个主要因素。首先是研发成本。构建应用程序本身本质上是人的力量。第二个是托管应用程序的成本,即基础设施成本。存储数据要花多少钱?运行响应查询或构建模型的服务器需要多少成本?
你从第 15 章[中对硬件瓶颈的理解有助于预测基础设施成本,因为避免不同的瓶颈会产生不同的影响。开发的成本呢?除了行政、管理和程序实践之外,软件架构还可以帮助减轻一些生产成本,并平衡代码的可读性和组织与硬件瓶颈。
有许多软件体系结构可供选择,这些体系结构导致应用程序的不同粒度或模块化级别。每种方法都有所取舍,平衡认知开销的节省和基础设施成本的节省。下面几节将讨论其中的几个。
17.2 客户端-服务器架构
在最基本的客户机-服务器应用程序中,有两个组件:客户机和服务器。客户端向服务器发送请求,服务器监听并响应这些请求。
在绝大多数应用程序中,客户机和服务器之间的通信是在套接字上进行的。套接字有很多种,但您最常使用的是 UNIX 域套接字和 Internet 套接字。
UNIX 套接字通过在单个节点上的操作系统缓冲区中写入和读取信息来进行通信。互联网套接字从网络接口读取和写入信息。套接字是底层操作系统功能上的 API,而底层操作系统功能本身是硬件功能的 API。
使用 Internet 套接字的客户机的一些例子有:您最喜欢的 web 浏览器、像 Napster 这样的点对点下载工具、您用来登录远程机器的 OpenSSL 客户机,或者您用来从 API 主机与远程数据库交互的数据库客户机。
您可能熟悉的几个 web 服务器是 nginx、apache 和 lighttpd。一些数据库服务器是 mysqld、postgresql 和 mongod。还有许多其他的服务器,例如 OpenVPN、openssh-server 和 nsqd 等等。
您可能会注意到许多服务器以 d 结尾,这是守护进程的缩写,它是一个长期运行的进程,只要应用程序运行,它就(几乎)不会停止。例外情况与维护有关,例如更新服务器软件、更新主机硬件或在更改后重新加载配置。一般来说,大多数(如果不是全部的话)服务器都是守护进程。
另一方面,客户端通常是短命的进程。它们打开与套接字服务器的连接,监听并在连接结束时关闭这些连接。以你的浏览器为例。当您从 web 服务器请求网页时,浏览器会在端口 80 (HTTP)上建立连接,或者在端口 443 (HTTPS)上建立加密连接。它向服务器发送请求,请求组成网页的数据并显示给你。当您关闭浏览器时,客户端会关闭,但服务器会继续运行。
要完成一个请求,客户端必须首先将它发送到服务器。一旦服务器收到请求,它必须处理请求,然后发送响应。这如图 17.1 所示。请求到达服务器并被发回所需的时间称为延迟。
Figure 17.1 A simple client-server interaction
由于客户端和服务器倾向于使用套接字,它们会受到影响延迟的硬件和/或网络瓶颈的影响,正如我们在本书的前一章中所讨论的。
17.3 多层/面向服务的架构
基本服务器-客户机体系结构的一个更复杂的版本是 n 层或面向服务的体系结构。该层旨在表明存在许多级别的服务器和客户端,每一级都可能提供服务并发送请求。层可以是第三方服务,也可以是在本地网络中运行的服务。
典型的 web 应用程序就是一个例子,其中浏览器向 web 服务器发送请求,底层数据库客户端向数据库服务器发送请求以实现该请求。这增加了一层必须连续完成的交互,从而使基本的服务器-客户端交互变得复杂。现在,您不只是拥有从客户端到服务器的往返行程(以及由此产生的延迟)。您需要在客户端和服务器之间往返。
由于数据库结果是满足客户机请求所必需的,所以它通常必须在服务器开始响应请求之前发生。这如图 17.2 所示。
Figure 17.2 A client-server interaction backed by a database
如您所见,每一层的客户机和服务器之间的延迟给应用程序增加了一层延迟,因为请求是连续发生的。这可能是面向服务的体系结构的一个主要缺点,尤其是当有许多相互依赖的请求连续发生时。
通常,服务是由一些关注点划分的。例如,您可能有一个服务负责与用户记录(姓名、地址、电子邮件等)的基本交互,而另一个第三方服务可能负责提供这些用户的人口统计信息。
如果您想用该用户及其人口统计信息填充网页,您的 web 应用程序必须查询用户服务和人口统计信息服务。因为人口统计服务是第三方服务,所以它使用与应用程序商店不同的查找关键字。为此,您必须在查询第三方之前查找用户记录。
因为您的应用程序可能使用许多第三方服务,所以更新您的应用程序以使用第三方用户 ID 通常不是一个合理的解决方案。仍然有一些方法可以让这个过程更快。
意识到应用程序中的大部分延迟都花在了等待读取套接字上,您可以实现对用户和人口统计数据的异步请求。现在,总延迟大约是两者中较大的一个,而不是两者之和。
加快速度的第二种方法是将两个服务分解成一个。您可以为所有用户发出一次请求,并随数据库中的用户记录一起查询,而不是向第三方查询人口统计数据。这使得两个请求合并为一个,增加了额外的存储开销(图 17.3)。
Figure 17.3 A client-server interaction backed by multiple services
17.4 微服务
微服务类似于 n 层架构,只是它们没有严格的分层。服务可以与它们需要的任何服务进行交互,具有任何需要的相互依赖性。图 17.4 描述了一个示例网络图。
Figure 17.4 An example microservice architecture
微服务软件架构通常被组织为一大组独立的应用程序,每个应用程序尽可能独立运行。对于所有的应用程序(当代码库不太大时)或产品关注点,代码被放置在根目录下。
对于数百甚至数千个小型应用程序,微服务软件架构最常见的抱怨是可维护性和可读性。这种代码组织方法与整体架构形成对比。
整体式
如果微服务是尽可能最小的应用程序,被分解以将它们的业务关注点彼此分离,那么整体架构在组织方面接近于相反。
当可以避免样板文件或重复的代码,以利于在现有代码库中实现新功能时,开发就变得容易了。这是单片架构如此受欢迎的原因之一,也是它们被采用的自然原因。
当一个深度嵌套的依赖项需要改变它的函数签名时,整体架构的一个问题就来了。要么必须更新实现该特性的所有代码以匹配签名,要么必须构建一个桥以使遗留代码兼容。这两种结果都不可取。
一方面,整体架构中的代码可以根据对象和功能效用(例如,用户对象、认证、数据库路由)来组织,从而易于查找和扩展。另一方面,将您可能需要的所有工具放在您面前可能会导致溜溜球问题,您必须在调用堆栈中爬上爬下来找出错误或添加新功能,这增加了许多认知开销。
17.6 实际案例(混搭架构)
根据您正在构建的应用程序,这种或那种架构可能最适合您。
如果您的代码库有明确的产品分离,微服务架构可能是最好的。
如果您的应用程序被期望为一个共同的、复杂的产品目的重用许多共同的数据访问组件,那么您可以选择一个整体架构。
如果这两件事都是真的,你可以选择一个架构的组合,如图 17.5 所示。在左边,您可以看到 web 页面的组件,在右边是服务于这些组件的服务的图表。
Figure 17.5 An example polyglot architecture
17.7 结论
在这一章中,我们讨论了几种软件架构,它们可以帮助你随着应用程序的增长来组织你的代码。每一种都有一些优点和缺点。不管你选择什么架构,都应该是一种选择。默认情况下通常是一个整体,这并不适合每一个场合。
了解 n 层、微服务、monoliths 和基本客户机-服务器应用程序之间的区别,您对架构的选择肯定是明智的。
机器学习模型部署指南
原文:https://www.dominodatalab.com/blog/machine-learning-model-deployment
机器学习(ML)部署包括将一个工作 ML 模型放入一个环境中,在这个环境中它可以完成它被设计要做的工作。模型部署和监控的过程需要大量的计划、文档和监督,以及各种不同的工具。
什么是机器学习模型部署?
机器学习模型部署是将完成的机器学习模型放置到真实环境中的过程,在真实环境中,机器学习模型可以用于其预期目的。模型可以部署在广泛的环境中,并且它们通常通过 API 与应用程序集成,以便最终用户可以访问它们。
虽然部署是数据科学生命周期(管理、开发、部署和监控)的第三阶段,但模型创建的每个方面都是在考虑部署的情况下进行的。
模型通常是在精心准备的数据集环境中开发的,在那里它们被训练和测试。在开发阶段创建的大多数模型都没有达到预期的目标。很少有模型通过他们的测试,那些确实代表了相当大的资源投入。因此,为了项目的成功,将一个模型移动到一个动态环境中可能需要大量的计划和准备工作。
如何将机器学习模型部署到生产中
机器学习模型部署需要各种技能和才能一起工作。一个数据科学团队开发模型,另一个团队验证模型,工程师负责将其部署到生产环境中。
准备部署 ML 模型
在部署模型之前,需要对其进行培训。这包括选择一种算法,设置其参数,并根据准备好的、干净的数据对其进行训练。所有这些工作都是在培训环境中完成的,培训环境通常是一个专门为研究设计的平台,拥有实验所需的工具和资源。当一个模型被部署时,它被转移到一个生产环境中,在这个环境中,为了安全和高效的性能,资源被简化和控制。
在完成开发工作的同时,部署团队可以分析部署环境,以确定完成后什么类型的应用程序将访问模型、它将需要什么资源(包括 GPU/CPU 资源和内存)以及它将如何获得数据。
验证 ML 模型
一旦模型被训练并且其结果被认为是成功的,它需要被验证以确保它的一次性成功不是异常的。验证包括 在新数据集上测试模型 ,并将结果与其初始训练进行比较。在大多数情况下,几个不同的模型被训练,但只有少数是足够成功的验证。在经过验证的模型中,通常只部署最成功的模型。
验证还包括审查培训文档,以确保该方法符合组织的要求,并且所使用的数据符合最终用户的要求。大部分验证通常是为了满足法规遵从性或组织治理要求,例如,这些要求可能规定可以使用哪些数据以及必须如何处理、存储和记录这些数据。
部署 ML 模型
实际部署模型的过程需要几个不同的步骤或操作,其中一些将同时进行。
首先,模型需要移动到它的部署环境中,在那里它可以访问它需要的硬件资源以及它可以从中提取数据的数据源。
第二,模型需要集成到流程中。例如,这可以包括使用 API 从最终用户的笔记本电脑访问它,或者将它集成到最终用户当前使用的软件中。
第三,将使用该模型的人需要接受如何激活它、访问它的数据和解释它的输出的培训。
监控 ML 模型
数据科学生命周期的监控阶段在模型成功部署后开始。
模型监控 确保模型工作正常,预测有效。当然,不仅仅是模型需要被监控,尤其是在早期的运行中。部署团队需要确保支持软件和资源按要求运行,并且最终用户已经过充分的培训。部署后可能会出现许多问题:资源可能不足,数据馈送可能没有正确连接,或者用户可能没有正确使用他们的应用程序。
一旦您的团队确定模型及其支持资源运行正常,仍然需要继续监控,但是大部分监控可以自动进行,直到出现问题。
监控模型的最佳方式是定期评估其在部署环境中的性能。这应该是一个自动化的过程,使用工具来跟踪指标,以自动提醒您其准确性、精确度或 F 分数是否有变化。
由于以下问题,每个部署的模型都有可能随着时间的推移而降级:
- 部署数据的差异。通常,在部署中给予模型的数据不会像训练和测试数据那样被清理,从而导致模型部署中的变化。
- 数据完整性的变化。在数周、数月或数年内,输入模型的数据变化会对模型性能产生负面影响,如格式变化、重命名字段或新类别。
- 数据漂移。人口统计、市场变化等的变化会导致时间漂移,使得训练数据与当前情况的相关性降低,因此模型的结果也不精确。
- 观念漂移。最终用户对正确预测的预期会随着时间的推移而改变,从而降低模型预测的相关性。
使用企业数据科学平台,您可以使用各种监控工具自动监控中的每一个问题,并且一旦在模型中检测到差异,就向您的数据科学团队发出警报。
模型部署和监控
成功部署和监控一个机器学习模型需要多种多样的技能以及不同团队中许多不同人员之间的协作。它还需要经验和工具的使用,以帮助这些团队有效地合作。成功部署模型的模型驱动的组织依赖于工具和资源,所有这些都在一个单一的 ML 操作平台中。
David Weedmark 是一位出版作家,曾担任过项目经理、软件开发人员和网络安全顾问。
机器学习产品管理:经验教训
原文:https://www.dominodatalab.com/blog/machine-learning-product-management-lessons-learned
这份多米诺数据科学领域笔记涵盖了皮特·斯科莫洛赫最近的地层伦敦谈话。它侧重于他的 ML 产品管理的见解和经验教训。如果你有兴趣听到更多关于 ML 或 AI 产品管理的实际见解,那么考虑参加 Pete 即将在 Rev. 举行的会议
机器学习项目很难:从确定性过程转变为概率性过程
多年来,我听数据科学家和机器学习(ML)研究人员讲述了阻碍他们工作的各种痛点和挑战。不幸的是,许多行业人士面临的一个共同挑战包括对抗“模型神话”,或者认为因为他们的工作包括代码和数据,他们的工作“应该”被像软件工程一样对待。我很幸运地在 2018 年 11 月的奥莱利雷达会议上看到了皮特·斯科莫洛赫的 ML 产品管理演示的早期版本。Pete 指出,ML 项目困难的原因之一是因为“机器学习将工程从确定性过程转变为概率性过程。”不出所料,这次演讲充满了针对许多痛点的实用见解。
Pete Skomoroch, O’Reilly Radar Conference, San Francisco, November 2018
当皮特发布他的 ML 产品管理演讲的最新版本时,来自伦敦地层的“为什么管理机器比你想象的更难”,我联系他请求允许报道和摘录他的作品。虽然这次演讲既提供了机器学习的组织基础,也提供了在发布 ML 项目时要考虑的产品管理见解,但在这篇博客文章中,我将重点关注后者。然而,如果你想回顾前者,那么完整的甲板是可用的在这里。非常感谢 Pete 的许可和在这篇文章上与我的合作。如果你有兴趣现场观看 Pete 的下一次演讲,那么考虑参加他在 Rev。
面向机器学习的产品管理
Pete 在他的 2018 年 11 月和 Strata London 会谈中指出,ML 需要比传统软件工程更具实验性的方法。它更具实验性,因为它是“一种涉及从数据中学习的方法,而不是以编程方式遵循一套人类规则。”因为 ML 项目的性质和方法更具实验性,行业人士和他们的公司在尝试之前不会知道会发生什么(即,更多的概率性而不是确定性)。这可能会给产品管理带来挑战,因为许多产品经理(PM)都接受过关于运输项目的确定性方法的培训。
为了帮助解决这些挑战,Pete 建议项目经理获得一些额外的技能,包括发展对 ML 如何工作的直觉,从 ML 的角度理解什么是可行的,以及“知道简单、困难和不可能的机器学习问题之间的区别。”
PMs 可以利用这种直觉,根据他们公司的数据“以及如何使用这些数据来解决客户问题”来校准各种方法的权衡。Pete 建议在流程的早期引入 ML 专家和数据科学家,并且在迭代优先考虑哪些功能或项目时“创建一个影响和易用性的图表,然后根据 ROI 对项目进行排序”。对公司数据的深刻理解、数据如何解决客户问题、ML 直觉和领域专业知识的结合,有助于项目经理确保他们致力于对业务至关重要的正确问题。Pete 概述了运送大多数 ML 项目的 5 个步骤,并指出步骤 2-4 占用了大部分时间。这些步骤也反映了 ML 产品管理的实验性质。
Pete 认为,提高模型准确性的最重要的价值之一是特征工程,即发现你在原始数据中发现的创造性信号,从原始数据中提取它们,然后将其转换为适合你的机器学习模型的格式(或更好的输入)。他建议尽快将算法的第一个版本发布给用户,这样可以进行迭代改进以支持业务影响。Pete 建议 PMs 记住,大约 80%的工作发生在第一个版本发布之后。这项工作包括模型的改进以及向模型中添加新的信号和特征。他还建议项目经理在将产品展示给用户之前,不要对 ML 项目进行“无休止的 UI 更改”,因为“看似很小的 UI 更改可能会导致大量的后端 ML 工程工作”,这可能会将整个项目置于风险之中。PM 的最后一步是“使用来自系统的派生数据来构建新产品”,因为这提供了另一种方法来确保整个业务的 ROI。
解决 ML 给产品路线图带来的不确定性
由于 ML 项目本质上更具实验性和概率性,它们有可能“增加产品路线图的不确定性”在这里,Pete 概述了项目经理需要考虑的常见挑战和关键问题。
然后,他建议项目经理使用适当的用户输入表格收集数据,这些表格将收集他们需要的正确数据,“对你想要预测的潜在现象进行建模,并且项目经理需要仔细平衡详尽数据收集的愿望和用户体验。”
Pete 还建议项目经理重新考虑他们的测试方法,因为 ML 系统运行在基础输入数据上,这些数据经常以不可预测的方式随时间变化。他主张由真正的使用者使用,因为“阳光是最好的消毒剂”。这也强化了他早先提出的尽快发布 1.0 版本的建议。
Pete 还强调了他之前提到的“看似很小”的变化会产生“意想不到的后果”虽然早些时候,他警告 PMs,看似很小的 UI 更改可能会导致重大的后端工程,看似很小的产品更改,如“改变问题的措辞”,可能会导致用户给出的数据发生变化,并可能在历史数据中添加时间依赖性。这导致在训练 ML 模型中使用历史数据的潜在复杂性。
结论
Pete Skomoroch 在他的 Strata London talk 中提出了务实的建议和见解,重点是如何制造和运输成功的 ML 产品。再次非常感谢 Pete 允许摘录他的 Strata London 演讲,并抽出时间合作撰写这份 Domino 数据科学领域笔记,重点关注他的 ML 产品管理见解和经验教训。如果你有兴趣听到更多关于 ML 或 AI 产品管理的实际见解,那么考虑参加 Pete 即将在 Rev。
^(多米诺数据科学领域笔记提供数据科学研究、趋势、技术等亮点,支持数据科学家和数据科学领导者加快工作或职业发展。如果您对本博客系列中涉及的数据科学工作感兴趣,请发送电子邮件至 content(at)dominodatalab(dot)com。)
机器学习项目:挑战和最佳实践
原文:https://www.dominodatalab.com/blog/machine-learning-projects-challenges-best-practices
这篇博客文章提供了关于为什么机器学习团队在管理机器学习项目方面面临挑战的见解。他还提供了如何应对这些挑战的最佳实践。本文由卢卡斯提供,最初出现在媒体上。
为什么机器学习项目这么难管理?
我看到许多公司试图部署机器学习——有些大获成功,有些惨败。一个不变的是,机器学习团队很难设定目标和设定预期。这是为什么呢?
事先真的很难分辨什么是难,什么是容易。
下棋赢卡斯帕罗夫难还是拿起棋子物理移动难?二十多年前,计算机打败了国际象棋世界冠军,但可靠地抓取和举起物体仍然是一个未解决的研究问题。人类不擅长评估什么对 AI 来说会很难,什么会很容易。即使在一个域中,性能也会有很大差异。预测情绪有什么好的准确性?在电影评论上,有很多文字,作者往往对他们的想法相当清楚,现在 90-95%的准确性是预期的。在 Twitter 上,两个人可能 80%的时候都同意一条推文的观点。通过总是预测情绪将是负面的,对关于某些航空公司的推特情绪可能有 95%的准确性。
度量也可能在项目早期增加很多,然后突然碰壁。我曾经举办过一次 Kaggle 比赛,世界各地成千上万的人参加比赛,为我的数据建模。在第一周,准确率从 35%到 65%,但在接下来的几个月里,准确率从未超过 68%。68%的准确率显然是最好的最新机器学习技术对数据的限制。那些参加 Kaggle 比赛的人非常努力地工作,以达到 68%的准确率,我确信这是一个巨大的成就。但是对于大多数用例来说,65% vs 68%是完全无法区分的。如果这是一个内部项目,我肯定会对结果感到失望。
我的朋友 Pete Skomoroch 最近告诉我,作为一名从事机器学习的数据科学家,单口相声是多么令人沮丧。工程项目一般会向前推进,但是机器学习项目可能会完全停滞。花一周的时间对数据建模却没有任何改进,这是可能的,甚至是常见的。
机器学习容易以意想不到的方式失败
只要你有大量的训练数据和你在生产中运行的数据看起来很像你的训练数据,机器学习通常就能很好地工作。人类如此擅长从训练数据中归纳,以至于我们对此有可怕的直觉。我建造了一个小机器人,它有一个摄像头和一个视觉模型,这个模型是根据 ImageNet 网站上的数百万张图片训练出来的。我对我的机器人相机上的图像进行了预处理,使其看起来像来自网络的图像,但准确性比我预期的要差得多。为什么?网络上的图片倾向于框定所讨论的对象。我的机器人不一定会像人类摄影师那样正确地看待一个物体。人类可能甚至没有注意到这种差异,但现代深度学习网络遭受了很多痛苦。有很多方法可以处理这种现象,但是我注意到这一点是因为性能的下降太不和谐了,所以我花了很多时间来调试它。
更致命的是导致性能下降的细微差别,这一点很难发现。在《纽约时报》上训练的语言模型不能很好地推广到社交媒体文本。我们可能预料到了。但显然,在 2017 年的文本上训练的模型在 2018 年写的文本上表现下降。上游分布随时间以多种方式转移。随着对手适应欺诈模型的作用,欺诈模型会完全崩溃。
机器学习需要大量的相关训练数据
每个人都知道这一点,但这是一个巨大的障碍。计算机视觉可以做令人惊讶的事情,只要你能够收集和标记大量的训练数据。对于某些用例,数据是某些业务流程的免费副产品。这是机器学习非常有效的地方。对于许多其他用例来说,训练数据非常昂贵,收集起来非常困难。许多医疗用例似乎非常适合机器学习——具有大量微弱信号和明确结果的关键决策——但这些数据由于重要的隐私问题而被锁定,或者最初没有一致地收集。
许多公司不知道从哪里开始投资收集培训数据。这是一项重大努力,很难事先预测该模型的效果如何。
处理这些问题的最佳实践是什么?
非常注意你的训练数据。
看看算法对其接受训练的数据进行错误分类的情况。这些几乎总是错误的标签或奇怪的边缘情况。不管怎样,你真的想了解他们。让每个参与构建模型的人查看训练数据,并自己标记一些训练数据。对于许多用例来说,一个模型不太可能比两个独立的人达成一致的速度更好。
立即让一些东西端到端地工作,然后一次改进一件事情。
从可能有效的最简单的东西开始,并部署它。你会从这件事中学到很多。过程中任何阶段的额外复杂性都会改进研究论文中的模型,但很少改进现实世界中的模型。证明每一个额外的复杂性。将某些东西交到最终用户手中,有助于你提前了解模型的工作情况,还会带来一些关键问题,比如模型优化的内容和最终用户想要的内容之间的分歧。这也可能让你重新评估你正在收集的训练数据。快速发现那些问题要好得多。
寻找优雅的方式来处理算法失败的不可避免的情况。
几乎所有的机器学习模型在相当长的时间内都会失败,如何处理这一点是绝对关键的。模型通常有一个可靠的置信度,您可以使用它。通过批处理,您可以构建人在回路系统,向操作员发送低置信度预测,使系统端到端可靠地工作,并收集高质量的训练数据。对于其他用例,您可能能够以标记潜在错误或减少最终用户烦恼的方式来呈现低置信度预测。
这里有一个失败的例子,它没有被很好的处理。微软没有预测到他们的 Tay 机器人会多快从 Twitter 上的巨魔那里学会不良行为。
Image captured from Sophie Kleeman's article on Gizmodo
下一步是什么?
机器学习的最初目标主要是围绕智能决策,但我们越来越多地试图将机器学习应用到我们使用的产品中。随着我们开始越来越依赖机器学习算法,机器学习不仅成为一个研究课题,也成为一门工程学科。我对有机会构建全新类型的产品感到非常兴奋,但也担心缺乏工具和最佳实践。以至于我开了一家名为“重量与偏见”的公司来帮助解决这个问题。如果您有兴趣了解更多信息,请查看我们正在进行的活动。
感谢 Yan-David Erlich 、 James Cham 、 Noga Leviner 和 Carey Phelps 阅读本书的早期版本,感谢 Peter Skomoroch 让我思考这个话题。
机器学习再现性危机
原文:https://www.dominodatalab.com/blog/machine-learning-reproducibility-crisis
我们又回到黑暗时代了吗?没有源代码管理?
我最近和一个朋友聊天,他的初创公司的机器学习模型非常混乱,导致了严重的问题,因为他的团队试图建立在彼此的工作基础上,并与客户分享。即使是原作者有时也无法训练出相同的模型,得到相似的结果!他希望我有一个可以推荐的解决方案,但是我不得不承认,我在自己的工作中也遇到了同样的问题。这很难向没有与机器学习合作过的人解释,但在跟踪变化和从头重建模型方面,我们仍然回到了黑暗时代。这太糟糕了,有时感觉就像回到了没有源代码控制的时候。
当我在 90 年代中期开始专业编程时,跟踪和协作源代码的标准是微软的 Visual SourceSafe。为了让您体验一下这种体验,它没有原子签入,因此多人无法处理同一个文件,网络副本需要每夜扫描以避免神秘的损坏,即使这样也不能保证数据库在早上完好无损。不过我觉得很幸运,我面试过的一个地方有一整面墙的便利贴,树中的每个文件都有一个便利贴,编码人员在修改文件时会把它们拿下来,完成后再放回去!
走进黑暗的中心:在 ML 模型上的合作
这就是说,在版本控制方面,我不是一个害羞的人。我经历过一些糟糕的系统,如果有必要,我仍然可以使用 rsync 和 chicken wire 拼凑出一个解决方案。即使所有这些都过去了,我可以用手捂着心口说,机器学习是迄今为止我发现的最糟糕的合作和跟踪变化的环境。
为了解释为什么,这里有一个机器学习模型的典型生命周期:
- 一名研究人员决定尝试一种新的图像分类架构。
- 她复制并粘贴了以前项目中的一些代码,以处理她正在使用的数据集的输入。
- 该数据集位于网络上她的一个文件夹中。这可能是 ImageNet 下载的一个,但不清楚是哪一个。在某个时候,有人可能删除了一些实际上不是 JPEGs 的图像,或者做了其他小的修改,但没有这方面的历史记录。
- 她尝试了许多略有不同的想法,修复错误并调整算法。这些变化发生在她的本地机器上,当她想要开始完整的训练运行时,她可能只是将源代码的大量文件拷贝到她的 GPU 集群。
- 她执行许多不同的训练运行,经常在作业进行的同时改变本地机器上的代码,因为它们需要几天或几周才能完成。
- 在大型集群上运行到最后可能会有一个 bug,这意味着她在恢复作业之前修改了一个文件中的代码,并将其复制到所有机器上。
- 她可以从一次跑步中获得部分训练的重量,并使用它们作为不同代码的新跑步的起点。
- 她保存了所有运行的模型权重和评估分数,并在没有时间进行更多实验时选择发布哪些权重作为最终模型。这些权重可以来自任何一次运行,并且可能是由与她当前在开发机器上的代码非常不同的代码产生的。
- 她可能将最终代码签入到源代码管理中,但是是在一个个人文件夹中。
- 她公布了自己的结果,包括代码和经过训练的重量。
对于一个有责任心的研究人员来说,这是一个乐观的情景,但是你已经可以看到,对于其他人来说,重复所有这些步骤并得出相同的结果是多么困难。这些要点中的每一个都是不一致的机会。让事情更加混乱的是, ML 框架用精确的数字确定性来换取性能。因此,如果奇迹发生,有人成功地复制了这些步骤,最终结果仍然会有微小的差异!
在许多现实世界的案例中,研究人员不会做笔记或确切地记得她做了什么,所以即使她也无法重现模型。即使她可以,模型代码所依赖的框架也会随着时间的推移而改变,有时会彻底改变,因此她还需要对她所使用的整个系统进行快照,以确保事情正常运行。我发现,当我联系 ML 研究人员要求他们帮助复制模型结果时,他们非常慷慨,但即使有原作者的帮助,这通常也是长达数月的任务。
为什么再现性很重要
为什么这些都很重要?我有几个朋友联系我,告诉我他们在复制已发表的模型作为自己论文的基线时遇到的困难。如果他们不能获得与原作者相同的准确性,他们如何判断他们的新方法是否有所改进?如果您没有办法重建模型来应对变化的需求或平台,那么依赖生产系统中的模型显然也是值得关注的。在这一点上,你的模型从技术债务的高息信用卡变成了更像高利贷的东西。这也令人窒息的研究实验;由于对代码或训练数据进行更改可能很难回滚,所以尝试不同的变化会有更大的风险,就像没有源代码控制的编码会增加尝试更改的成本一样。
这并不完全是悲观的,在社区中有一些值得注意的关于再现性的努力。我最喜欢的一个是 Toby Boyd 领导的 TensorFlow 基准测试项目(T1)。他让他的团队的任务不仅是准确地规划如何在许多不同的平台上以高训练速度从头开始训练一些领先的模型,而且还要确保模型训练达到预期的精度。我见过他拼命想让模型达到那个精度,因为我上面列出的任何步骤的变化都会影响结果,而且没有简单的方法来调试潜在的原因,即使有作者的帮助。这也是一项永无止境的工作,因为 TensorFlow、GPU 驱动程序甚至数据集的变化都可能以微妙的方式损害准确性。通过做这项工作,Toby 的团队帮助我们发现并修复由他们覆盖的模型中 TensorFlow 的变化引起的错误,并追踪由外部依赖性引起的问题,但很难扩展到相对较小的平台和模型集之外。
我还知道其他团队,他们认真对待在生产中使用模型,投入了类似的时间和精力来确保他们的培训可以被复制,但问题是这仍然是一个非常手工的过程。关于如何将培训过程存档,以便将来可以成功地重新运行,没有与源代码控制等同的东西,甚至没有公认的最佳实践。我心中也没有解决方案,但在这里开始讨论的是一些原则,我认为任何方法都需要遵循这些原则才能成功:
- 研究人员必须能够轻松地提出新想法,而不必支付高额的“过程税”。如果这不是真的,他们就不会使用它。理想情况下,该系统实际上会提高他们的生产率。
- 如果一名研究人员被一辆公交车撞了,但却创建了自己的创业公司,其他人应该可以在第二天介入并训练他们迄今为止创建的所有模型,并获得相同的结果。
- 应该有某种方法来打包你训练一个特定模型所需要的东西,以一种可以公开分享的方式,而不透露作者不希望的任何历史。
- 为了重现结果,需要准确地记录代码、训练数据和整个平台。
我已经看到开源和创业界围绕这些挑战的解决方案出现了一些有趣的动向,就我个人而言,我迫不及待地想花更少的时间来处理所有相关的问题,但我不期望在短期内看到完全的解决方案。无论我们想出什么,都需要改变我们使用模型的方式,就像源代码管理意味着我们所有个人编码过程的巨大改变一样。就最佳实践达成共识并对社区进行教育就像我们提出的工具一样重要。我迫不及待地想看看会出现什么!
^(编辑注:本文由皮特提供,最初出现在皮特的博客。)
让机器学习的可解释性更加严谨
原文:https://www.dominodatalab.com/blog/make-machine-learning-interpretability-rigorous
这份 Domino 数据科学领域笔记涵盖了机器学习可解释性的拟议定义,可解释性为何重要,以及考虑对可解释性进行严格评估的理由。见解来自于的压轴多希-维勒兹的演讲,“可解释性严谨科学的路线图”以及论文“迈向可解释机器学习的严谨科学”。这篇论文是由压轴 Doshi-维勒兹和 Been Kim 共同撰写的。finale Doshi-维勒兹是哈佛大学鲍尔森工程学院计算机科学助理教授,Been Kim 是谷歌大脑的研究科学家。
介绍
数据科学家做模型。模型,特别是基于概率评估提出建议或规定行动的算法,有能力改变,并被“重新训练”(有时会产生意想不到的后果)。这导致数据科学家考虑评估超出预期任务性能的模型的方法。数据科学家能够使用可解释性(以及对其不断增长的研究)来满足辅助标准,包括被信任(人类用户的信心)、避免不可量化的偏见、隐私、提供解释权等等。然而,对于“可解释性”的定义是否有共识?还是“评估可解释性”?这篇博客文章涵盖了机器学习可解释性的拟议定义以及对可解释性的严格评估。这篇博客文章中涉及的见解来自终曲 Doshi-维勒兹的演讲,“可解释性的严格科学的路线图”以及论文“迈向可解释机器学习的严格科学”。论文由压轴多希-维勒兹和 Been Kim 共同撰写。
定义:机器学习环境中的可解释性
金和多希-维勒兹认为,“对于机器学习中的可解释性是什么以及如何评估它以进行基准测试,人们几乎没有共识”,并提出“在 ML 系统的背景下,我们将可解释性定义为以人类可理解的术语解释或呈现的能力。”多希-维勒兹在演讲中指出,“解释”是可解释性的词根,字典对“解释”的定义是解释或提供意义。多希-维勒兹还指出,“解释”这个词是一个“比可解释性更能让人感觉到的词”,并允许人们思考“什么是好的解释?我向你解释过什么吗?”并要求观众思考“这个解释的质量如何”作为一种手段来引入评估可解释性的严谨性概念。
为什么是可解释性
不是所有的 ML 系统都需要可解释性。当“不可接受的结果没有重大后果”或当 ML“在实际应用中经过充分研究和验证,我们相信系统的决定,即使系统并不完美”时,不需要可解释性。当不满足辅助标准,并且出现关于偏见、信任、安全、道德和不匹配目标的问题时,需要可解释性。金和多希-维勒兹“认为,对可解释性的需求源于问题形式化的不完全性,这为优化和评估制造了一个根本性的障碍”,例如,“不完全性会产生某种无法量化的偏差”。
当前对可解释性的评估:两类
金和多希-维勒兹指出,目前对可解释性的评估通常分为两类,这两类都基于“当你看到它时你就会知道”的观点。第一类“评估应用环境中的可解释性:如果系统在实际应用或其简化版本中有用”,那么它是可解释的。第二类
“通过可量化的代理评估可解释性:研究人员可能首先声称某些模型或类(例如,稀疏线性模型、规则列表、梯度提升树)是可解释的,然后在该类中提出算法进行优化。”
虽然多希-维勒兹和金都指出这些分类是合理的,但他们质疑“是否所有定义为可解释的模型类中的所有模型都是同样可解释的?”虽然“稀疏性等可量化的代理允许进行比较”,但这也适用于“将特征稀疏的模型与原型稀疏的模型进行比较”吗并非所有的应用程序都有相同的可解释性需求。两人都主张对可解释性的评估要更加严格。他们引用 GDPR 和越来越多的关于可解释性的研究作为提出额外严格性的理由。他们还建议“研究的主张应该与评估的类型相匹配”。
提议的可解释性评估
多希-维勒兹和金提出了一个可解释评估方法的分类法:基于应用的评估、基于人的度量和基于功能的评估。
基于应用的评估
多希-维勒兹在演讲中指出,当研究人员心中有一个明确的目标,可解释性在实际应用中得到评估,可解释性提供了确凿的证据,并使研究人员能够执行更高层次的任务时,这种度量就会出现。然而,“执行这些评估可能会很昂贵,因为你必须在真实的应用程序环境中进行,你可能会好奇它是否具有普遍性。”在论文中,金和多希-维勒兹引用了一个基于应用的评估的例子,即“与医生一起诊断患有特定疾病的患者——展示模型工作的最佳方式是根据任务评估它:医生执行诊断”…。并确定“它是否导致更好地识别错误、新的事实或更少的歧视”。
以人为基础的度量
金和多希-维勒兹将这一指标详细描述为“进行更简单的人体实验,保持目标应用的本质”。当领域专家的实验非常昂贵或者访问目标社区很困难时,这可能是有用的。一个更简单的人类受试者实验的例子包括二元强制选择,或者当“人类面对成对的解释,必须选择他们认为质量更高的一个(量化的基本面部有效性测试)”。
基于功能的评估
多希-维勒兹和金指出,这一指标不包括人类实验,而是使用“可解释性的正式定义作为解释质量的代理”。这个评估是“一旦我们有了一类已经被验证的模型或规则,例如基于人类的实验,这是最合适的”。“或者人体实验不道德的时候”。
结论
虽然这篇博客文章涵盖了关于金和多希-维勒兹提出的机器学习可解释性定义和对可解释性进行更严格评估的分类法的精华,但更多见解和深度可在论文中获得。多希-维勒兹谈话的完整视频也可供观看。
^(Domino 数据科学领域笔记提供数据科学研究、趋势、技术等亮点,支持数据科学家和数据科学领导者加快工作或职业发展。如果您对本博客系列中涉及的数据科学工作感兴趣,请发送电子邮件至 writeforus(at)dominodatalab(dot)com。)
让 PySpark 与 spaCy 一起工作:克服序列化错误
原文:https://www.dominodatalab.com/blog/making-pyspark-work-spacy-overcoming-serialization-errors
在这篇客座博文中, Holden Karau , Apache Spark Committer ,提供了关于如何使用 spaCy 处理文本数据的见解。 Karau 是谷歌的开发者拥护者,也是“高性能火花”和“学习火花”的合著者。她在 Twitch 和 YouTube 上有一个关于她的演讲、代码评审和代码会议的知识库。她还在从事分布式计算和儿童 T21 的工作。
spaCy 能帮上什么忙?
你是一名数据科学家,需要用 Python 并行化你的 NLP 代码,但却不断遇到问题吗?这篇博文展示了如何克服使用流行的 NLP 库空间时出现的序列化困难。(虽然这些技术有点复杂,但是您可以将它们隐藏在一个单独的文件中,假装一切正常。)这篇文章关注的是 spaCy 的使用,我还有另外一篇关于 NLTK 的文章,我将在我的博客上发表。如果你是 Scala 或 Java 用户,请尽快寻找 JVM 上的帖子。
不过,在你过于兴奋之前,有一个警告——如果你认为调试 Apache Spark 很难,那么调试这些序列化技巧会更难,所以你应该看看我的调试 Spark 视频,并关注 Safari 上的深度课程,当它可用时。
当然是字数统计
现在,如果我们不把重点放在字数上,这就不是一篇关于大数据的博文,但是我们要做一点改变。就像我的第一份工作一样,在某些时候,老板(或客户或其他影响你支付租金能力的人)可能会找到你,要求你“本地化”你激动人心的 WordCount**项目。在这一点上,如果你从小到大只说英语和法语,你可能会回答,“那很好;所有语言都使用空格来分隔单词”,但是您可能会很快发现 split 函数对于像日语这样的语言来说并不是一个通用的标记器。
在意识到标记化其他语言实际上是多么复杂之后,我们可能会开始对我们承诺的两周交付时间感到紧张,但幸运的是,标记化是 NLP 工具的一个基本部分,许多现有的库可以在多种人类(非计算机)语言上工作。
常规(非箭头)Python UDFs
我们将要使用的 Python 库是 spaCy ,这是一个世界级的自然语言处理工具。虽然你不需要了解 spaCy 来理解这篇博文,但是如果你想了解更多关于 spaCy 的知识,这里有一个的精彩文档集。
首先,我们将弄清楚如何在 PySpark 内部使用 spaCy,而不用担心跨语言管道的细节。在 PySpark 的旧版本中,用户注册了 UDF,如:
def spacy_tokenize(x):
# Note this is expensive, in practice you would use something like SpacyMagic, see footnote for link; which caches
# spacy.load so it isn’t happening multiple times
nlp = spacy.load(lang)
# If you are working with Python 2 and getting regular strings add x = unicode(x)
doc = nlp(text)
return [token.text for token in doc]
tokenize = session.udf.register("tokenize", spacy_tokenize)
这给了我们一个可以在 Python 中调用的函数,它将使用 spaCy 来标记输入,尽管是用英语,因为我真的不懂其他任何东西。以标准的 Spark SQL 字数为例,我们可以修改它以避免 Spark RDDs:
df = spark.read.format("text").load("README.md")
tokenized = df.select(explode(split(df.value, " ")))
result = tokenized.groupBy(tokenized.col).count()
result.show() # Or save
然后,我们可以换入新函数,并使用 spaCy 进行标记化:
tokenized = df.select(explode(spacy_tokenize(df.value, ' ')))
如果我们运行这个,它会因为几个不同的原因而变得相当慢。首先,spaCy.load 是一个昂贵的调用;在我自己的系统上,导入和加载空间几乎只需要一秒钟。第二个原因是在 Java 和 Python 之间来回复制数据的序列化开销。
火花之箭 UDFs
Spark 的基于箭头的 UDF 通常更快,原因有几个。Apache Arrow 的核心为我们提供了一种 JVM 和 Python、以及许多其他语言都能理解的格式,并且以一种有利于矢量化操作的方式进行组织。在 Spark 中创建基于箭头的 UDF 需要一点重构,因为我们操作的是批处理而不是单个记录。新的基于箭头的 PySpark 矢量化 UDF 可以注册如下:
@pandas_udf("integer", PandasUDFType.SCALAR) # doctest: +SKIP
def pandas_tokenize(x):
return x.apply(spacy_tokenize)
tokenize_pandas = session.udf.register("tokenize_pandas", pandas_tokenize)
如果您的集群还没有为基于 Arrow 的 PySpark UDFs(有时也称为 Pandas UDFs)设置,那么您需要确保您的所有机器上都安装了 Spark 2.3+和 PyArrow 的匹配版本。(查看 setup.py,了解您的 Spark 版本所需的版本)。
使用 PySpark UDFs(常规和箭头)
两者的用法看起来很相似。
在 SQL 中:
spark.sql("SELECT tokenize(str_column) FROM db")
spark.sql("SELECT tokenize_pandas(str_column) FROM db")
使用 Dataframe API:
dataframe.select(tokenize(dataframe.str_column))
dataframe.select(tokenize_pandas(dataframe.str_column))
我们当然可以用它们来做 Python 中的(强制)字数统计示例:
dataframe.select(explode(tokenize_pandas(dataframe.str_column)).alias("tokens")).groupBy("tokens").sum("*").collect()
虽然这两个看起来非常相似,但它们实际上可能具有非常不同的性能含义,因此我们自然会关注第二个更快的示例,在本例中是熊猫/箭头驱动的示例。
处处超越“spacy.load()”
序列化问题是 PySpark 面临的最大性能挑战之一。如果你试图通过将spacy.load()
移到函数调用之外来优化它,spaCy 会尝试自己序列化,这可能会很大,包括 cdefs 。Cdefs 不能被 pickle 序列化,尽管通过一些小心的包装,我们仍然可以使用依赖于它们的代码。这甚至可能不起作用,而是通过使用一个全局变量(对不起!)和一个包装函数,我们可以确保重用空间:
# spaCy isn't serializable but loading it is semi-expensive
NLP = None
def get_spacy_magic_for(lang):
global NLP
if NLP is None:
NLP = {}
if lang not in NLP:
NLP[lang] = spacy.load(lang)
return NLP[lang]
然后在我们的代码中,我们通过我们的朋友get_spacy_magic
访问空间。如果您在常规文件中工作,而不是在笔记本/REPL 中工作,您可以使用更干净的基于类的方法,但是由于深奥的序列化原因,在带有 PySpark 的 REPL 中使用类有一些问题。
由于这段代码不够漂亮,您可能会问自己减少负载有多重要。举个例子,在我的 X1 Carbon 上加载 en 语言大约需要一秒钟,如果每个元素增加一秒钟的开销,我们就很容易失去并行化这个工作负载的好处。
spaCy load prefork 在 spaCy load 方面有一些新的有趣的技巧,但这是另一篇博客文章的主题。(请再次关注我的博客 / 媒体 / 推特,我会在那里分享我的博客。)
包扎
这种方法对于 WordCount 来说已经足够好了(我的意思是,哪个大数据系统不行呢?),但它仍然让我们缺少一些想要的信息。例如,在这种情况下和未来的 NLTK 文章中,Python 中收集的信息比我们目前在标量转换中可以轻松返回的信息多得多,但在 SPARK-21187 中围绕这一点的工作仍在继续。如果您尝试直接返回 spaCy 文档,您将遇到序列化问题,因为它引用了 cloud pickle 不知道如何处理的内存块。(参见云泡菜#182 了解一些背景)。
如果这对你来说是令人兴奋的,并且你想有所贡献,那么非常欢迎你加入我们的 Sparkling ML 项目,Apache Arrow 或通用改进版 Apache Spark Python 集成。此外,如果你有兴趣看到这篇文章的幕后,你可以看看这个现场编码会议和相应的闪闪发光的 ml 回购。
^(作者注:SpacyMagic link 这里的是。)
为衰退中的 DS/ML 和 Domino 辩护
原文:https://www.dominodatalab.com/blog/making-the-case-for-ds-ml-and-domino-in-a-recession
衰退?数据科学来拯救我们!
一场衰退即将来临。作为一名数据科学领导者,你最近可能会遇到更难的问题。我们可以在哪里削减成本?x,y 或 z 的值是多少?近几十年来,我自己也经历过几次衰退。作为客户执行发起人、销售团队的积极推动者、定价委员会和执行客户顾问委员会的领导,我亲眼目睹了经济衰退可能带来的压力。幸运的是,我也代理过一些像多米诺这样的大公司,它们帮助客户恢复活力,甚至在经济低迷时期也能创造巨大的经济价值。
乍一看,数据科学可能是一个潜在的目标。数据科学家要求高薪。他们使用大量的数据和计算。许多 IT 和业务领导不了解数据科学的完整投资回报。
数据领导者在低迷时期投资
然而,深入挖掘,许多领导人在经济衰退中实际上更依赖数据科学。分析对于确定增加收入和节约成本的方法至关重要。经济低迷也是在数据科学人才争夺战中领先的好机会。继续投资并为复苏做好准备是明智之举。
最近的几篇文章:
提高生产力,从顶尖人才那里获得更多价值(并留住他们)
我和很多高管交谈过,比如 CDO 和 CDAOs。通常薪酬是他们成本的绝大部分,在经济衰退的情况下,他们仍然在争夺顶尖的数据科学人才。因此,留住顶尖人才并确保他们高效工作一如既往地至关重要。幸运的是,对于数据科学和 IT 来说,Domino 可以改变生产率的游戏规则。因此,Domino 客户成功团队正在努力帮助客户确保他们从 Domino 的投资中获得最大回报。例如,通过:
- 最大限度地减少一次性请求,依靠自助式基础架构来自动化耗时的开发运营任务,例如配置服务器、移动数据和管理环境
- 消除“重新发明轮子”自动跟踪和再现工作
- 每个模型节省数周时间使用交钥匙模型监控,无需构建监控管道
- 将多种工具 (Jupyter、RStudio、SAS、MATLAB)整合到一个平台上——不再有重复的孤岛和支持/维护负担
一个 Domino 客户通过简化对数据科学基础架构的支持,将 IT 部门的 18 名全职员工重新用于更具战略性的工作。投资顶尖人才,让他们做更有趣、更有商业价值的工作,是应对衰退的良方!
基础设施成本呢?
经常听说云计算账单可以有多不可预测,多贵(来)。这些账单的第一个解药是像 Domino 一样保持开放、灵活和客户选择的哲学。作为一个 kubernetes 原生平台,Domino 可以运行在任何云或内部。这是为了在最具成本效益的地方支持工作负载。
Domino 的另一个根本区别是,它是唯一一家不根据计算使用量收费的 MLOps 提供商。事实上,Domino 有助于减少您的云支出,而其他供应商则有动力增加支出。一些 Domino 客户报告说,他们的基础设施成本降低了 40%或更多,节省了 100 多万美元。怎么会?(我知道你会问):
-
与竞争解决方案不同,Domino 很容易暂停和恢复工作,所以机器不会仅仅为了方便而持续运行
-
Domino 给出警告,并且能够自动关闭长时间运行的工作负载
-
与云平台和数据块不同,客户使用无加价的商用计算
-
你可以设置限制谁可以使用什么类型的硬件,以及有多少台机器可以同时运行
-
每台机器多项工作负载更有效地利用资源
-
按项目、数据科学家或工作负载类型列出的可操作的支出报告发现了降低成本的最大机会
通过数据科学扩大利润
如果您将数据科学视为成本中心,您可能没有意识到它的价值。在经济衰退时期,数据科学团队最有价值的方式是交付影响收入和成本的项目,并增加利润。归根结底,数据科学可以通过以下方式实现变革:
- 自动化产品体验,提高客户保留率和竞争优势
- 自动化业务流程
- 更快地将新创新推向市场
- 找到并完善你的目标客户群
- 改善销售线索评分和管理,提高销售效率
- 通过更好的客户分析改进营销活动
- 预测哪些潜在客户更有可能购买或哪些客户可能流失
- 通过分析过去的购买、网络浏览和其他意图信号,个性化营销内容
机会是无穷的!这就是为什么随着经济衰退的逼近,公司投资于成熟的数据科学,以获得更大的价值和影响。幸运的是,Domino 在帮助客户从实验项目转向更全面的系统方面大放异彩,这种系统可以扩展数据科学的速度、质量和影响。
在客户最需要的时候证明节约和影响
当然,有很多选择,您应该咨询同行(希望还有 Domino 客户!)关于他们如何扩展数据科学。Forrester 在总经济影响中采访了六位 Domino 客户,发现对 Domino 的投资平均实现了 542%的投资回报率,不到 6 个月就收回了投资,并从更高的生产率、降低的基础设施成本和增加的利润中获得了超过 2200 万美元的收益。这是他们发现节约的地方:
- 减少配置计算资源的时间(970 万美元)
- 在共享工具环境中改进协作(> 510 万美元)
- 通过提高模型速度和部署成功率增加利润(510 万美元)
- 更快的模型验证(140 万美元)
- 加速新团队成员的加入(98.4 万美元)
- 更高效的模型维护(> 34.3 万美元)
- 退役的传统服务器(14.1 万美元)
经济衰退意味着艰难的选择,因为企业要想在复苏后取得成功。幸运的是,对于 Domino 及其客户来说,数据科学是一个可以在近期和未来推动增长、效率和成功的投资领域。许多年后,希望您会回顾这次衰退,以及它如何进一步将您的组织从基于数据科学人才、成熟度和规模的明智投资的“群体”中分离出来。
来自软件工程的管理经验
原文:https://www.dominodatalab.com/blog/management-lessons-from-engineering
随着我从一名个人软件开发人员发展到管理团队和创办公司— 一个数据科学平台—我不断注意到优秀工程原则和优秀管理原则之间的相似之处。我对这里的新奇事物不抱幻想,但这是一个有趣的话题,涉及面很广,所以我计划在接下来的几个月里写更多这方面的内容。现在,我想把重点放在一个特殊的相似性上:“某人”不能做要求他们做的事情的情况。
首先,让我简单地承认软件和公司之间的基本相似性:好的组织设计“看起来”像好的软件设计。也就是说,“单元”应该有明确的职责,以及它们如何与其他单元连接的明确的“契约”(或接口)。就其本身而言,这并不是特别有见地,但考虑到这一点,让我们再深入一点...
例外和升级
一个更微妙的相似之处是软件开发中的异常概念,以及在管理环境中的类似概念。
我的前雇主对升级有一个正式的概念(记录在公司公开的管理手册中)。有几个不同的场景,其中一个可能“升级”的东西,但最常见的是当你“无法实现你的责任。”
乍一看,这听起来很明显,但这是一个微妙而强大的概念。这个想法适用于组织中的每一个人——无论是初级还是高级——它要求他们有自我意识和无我意识,以认识到他们是否/何时无法履行自己的职责,不管是什么原因。这可能包括因为丢了钥匙而不能打扫办公室的看门人;一个工程经理不能按时交付一个版本,因为她的业务涉众没有对早期版本提供足够的反馈;或者是一位高级经理,他无法让一个部门走上正轨,因为他认识到自己没有经验或概念能力来解决他所面临的大规模问题。所有这些情况都需要升级。
在软件工程中,异常本质上是同一件事:一个代码单元在无法完成其职责时应该引发异常。(微软的。NET 框架指南实际上使用了非常相似的语言:“当一个成员不能成功地做它被设计去做的事情时,异常被抛出”。)
完成类比
我们可以将例外和升级之间的这种相似性集成到我们首先观察到的更明显的相似性中:
-
组织单位
-
设计良好的公司都有职责明确的部门和团队。
-
设计良好的软件有明确职责的模块和类
-
做事的人
-
在一个公司中,部门和团队只有一个经理,他向一个“更高”的经理报告,并负责利用自己的报告来实现部门或团队的责任。
-
在软件中,一个函数被其他函数调用,并且有其他可用的函数可以调用,以实现其签名的承诺。
-
例外和升级
-
在一家公司,如果一个人不能做要求她做的事情,她应该向上级汇报,让她的经理恰当地处理这一事实。
-
在软件中,如果一个函数不能做它被要求做的事情,它应该抛出一个异常,让调用函数适当地处理这个因素。
请注意,就像函数负责处理它调用的任何其他函数的异常一样,经理负责处理来自其报告的升级。“处理”异常或升级可能需要解决根本问题并“重试”;这可能需要通过一些不同的方式来实现相同的责任(例如,调用不同的功能,将任务交给不同的人或组);或者它可能涉及将异常/升级向上传递到下一层(即,堆栈上的上一个功能,或者链上的下一个管理器)。
这是一个简化的组织结构和简化的软件架构的例子,展示了一些可能的例外和升级的例子。红色箭头代表“某人”(一个人或一个功能)说,“我不能做要求我做的事情。”
反光
就像学习一门外语可以加深对你的母语的理解一样,我发现在两个不同的领域看到同样的概念帮助我更好地理解它们。
在软件开发环境中,这种思考清楚地表明了什么时候抛出异常是合适的:当且仅当函数不能支持其签名的承诺时。
在管理环境中,我越来越清楚地认识到,要使升级方案发挥作用,组织中的每个人都必须理解它,并根据协议进行操作。如果出现问题升级,但经理不知道如何“处理”,系统就会失败。或者,如果人们不知道在无法履行职责时应该上报,那么这个系统就失败了。(写好代码的类比应该是不言而喻的,这里。)
将数据科学作为一种能力来管理
原文:https://www.dominodatalab.com/blog/managing-data-science-as-a-capability
Domino 首席执行官 Nick Elprin 举办了一个 3 小时的培训研讨会,名为“在企业中管理数据科学”,提供了实用的见解和互动的突破。研讨会上分享的知识、趣闻和最佳实践基于多年来与客户就管理和加速数据科学工作进行的坦诚讨论。研讨会还展示了可重复使用的模板,包括飞行前数据科学项目清单以及用于招聘和入职数据科学家的规划模板。我们根据与会者的反馈分享分组讨论材料。如果你错过了 Strata,并有兴趣加入类似的讨论,那么考虑参加 Rev 。
管理数据科学的已知挑战
与招聘、建立、管理和领导数据科学团队相关的挑战已经讨论了多年。一个例子包括早期数据科学团队在从集中式团队结构切换到嵌入式团队结构时所经历的痛苦。每个公司都有独特的需求和要求。拥有早期数据科学团队的公司尝试了不同的团队结构,以便将数据科学工作与其整体战略愿景或业务价值要求保持一致。这种已知的斗争今天仍然存在。许多数据科学领导者及其组织仍在讨论如何使数据科学工作符合关键利益相关者的需求和整体组织商业价值。然而,如果受产品管理启发的见解和模板可以用来支持人们管理数据科学,那会怎样?这种贡献有帮助吗?这些只是我们在 Domino 问自己的几个问题。
分享最佳实践和受产品管理启发的模板
随着数据科学作为一门学科的成熟,我们作为一个整体行业,能够向前人学习。这使我们能够分享关于在企业组织内构建、管理和发展数据科学能力的实用最佳实践。在最近的一次行业会议上,Domino 的首席执行官 Nick Elprin 举办了一个 3 小时的培训研讨会,“管理企业中的数据科学”,提供了实用的见解和交互式突破。研讨会上分享的知识、趣闻和最佳实践基于多年来与客户就管理和加速数据科学工作进行的坦诚讨论。研讨会还展示了可重复使用的交互式分组讨论模板,包括飞行前数据科学项目清单以及招聘和入职数据科学家的规划模板。
在深入研讨会上分享的一些见解包括
- 考虑使用一个框架来管理数据科学,这是一种基于人员、流程、技术和 x 因素的能力。
- 根据与客户的讨论,我们了解到将产品管理原则应用于数据科学项目将节省开发和生产时间。
- 使用启动或飞行前项目清单等工件,将有助于最大限度地提高数据科学工作与业务价值和整体成功保持一致的可能性。该清单受产品管理中使用的 PRD(产品需求文档)的启发。
- 为您的数据科学团队寻找、培训和留住人才。管理和发展数据科学团队需要多种因素。考虑利用招聘和入职计划模板中提供的一系列问题来培养符合贵公司战略愿景的合适团队。
虽然研讨会培训基于 Domino 的“大规模数据科学管理实用指南”,但互动研讨会还提供了可重复使用的模板(飞行前清单以及招聘和入职计划模板)。根据与会者要求与他们的团队成员分享更多副本的请求,我们提供了可供下载的模板。这些模板是帮助当前和有抱负的数据科学领导者在其组织内发展数据科学能力的工具。此外,如果您错过了 Strata 的研讨会,并希望参与类似深度和范围的讨论,您可能有兴趣参加即将举行的 Rev 。
使用 dplyr 操作数据
原文:https://www.dominodatalab.com/blog/manipulating-data-with-dplyr
特别感谢Addison-Wesley Professional允许从本书中摘录以下“用 dplyr 操纵数据”章节,数据科学编程技巧:开始编写代码,用 R 辩论、分析和可视化数据。Domino 创建了一个补充项目。
介绍
数据科学家花费无数时间争论数据。这不是一次愉快的经历。然而,数据科学家可以使用像dplyr
这样的工具来帮助加速数据科学工作。Domino 的内容负责人联系了Addison-Wesley Professional(AWP),请求允许从书中摘录以下dplyr
章节, 数据科学的编程技巧:开始编写代码,用 R 、讨论、分析、可视化数据,以帮助支持数据科学家加速他们的工作。非常感谢 AWP 的适当许可。Domino 还创建了一个互补的用 dplyr 操作数据的项目,与摘录的书章节配对。
使用 Dplyr 操作数据:章节简介
dplyr
【dee-ply-er】(“dee-ply-er”)包是 R(也许更一般地说是数据科学)中数据争论的卓越工具。它为程序员提供了执行数据管理和分析任务的直观词汇表。学习和使用该软件包将使您的数据准备和管理过程更快、更容易理解。本章介绍了包背后的原理,并概述了如何使用包通过其富有表现力和高效的语法来处理数据框。
11.1 数据操作的语法
这个dplyr
包的最初创造者 Hadley Wickham 恰如其分地将其称为数据操作的语法。这是因为该包提供了一组动词(函数)来描述和执行常见的数据准备任务。编程中的核心挑战之一是从关于数据集的问题映射到具体的编程操作。数据操作语法的出现使得这个过程更加顺畅,因为它使您能够使用相同的词汇来提问和编写程序。具体来说,dplyr
语法让您可以轻松地谈论和执行如下任务:
- 从数据集中选择感兴趣的特定特征(列)
- 过滤掉不相关的数据,只保留感兴趣的观察值(行)
- 通过添加更多的特征(列)来改变数据集
- 按特定顺序排列个观察值(行)
- 根据平均值、中间值或最大值汇总数据
- 将多个数据集连接到一个数据框中
您可以在描述用于询问数据的算法或过程时使用这些词语,然后使用dplyr
来编写代码,这些代码将严格遵循您的“普通语言”描述,因为它使用共享相同语言的函数和过程。事实上,关于数据集的许多现实问题归结为将数据集的特定行/列隔离为“感兴趣的元素”,然后执行基本的比较或计算(例如,平均值、计数、最大值)。虽然可以用 base R 函数来执行这样的计算(在前面的章节中已经描述过了),但是dplyr
包使得编写和读取这样的代码更加容易。
11.2 核心 dplyr 功能
dplyr
包提供了镜像前面提到的动词的函数。使用这个包的功能将允许您快速有效地编写代码来询问数据集的问题。
由于dplyr
是一个外部包,您将需要安装它(每台机器一次)并在您想要使用函数的每个脚本中加载它。加载软件包后,您可以调用任何函数,就好像它们是您已经熟悉并喜欢的内置函数一样。
为了展示dplyr
包作为询问真实数据集问题的工具的有用性,本章将这些函数应用于美国总统选举的历史数据。presidentialElections
数据集包含在pscl
包中,因此您需要安装并加载该包来访问数据:
# Install the `pscl` package to use the `presidentialElections` data frame
install.packages("pscl") # once per machine
library("pscl") # in each relevant script
# You should now be able to interact with the data set
View(presidentialElections)
这个数据集包含了从 1932 年到 2016 年的每次总统选举中,每个州投票给民主党候选人的百分比。每一行都包含state
、year
、民主党选票的百分比(demVote),以及内战期间每个州是否是前南部邦联的成员。更多信息,参见pscl
包装参考手册,或使用?presidentialElections
查看 RStudio 中的文档。
选择
**select()**
函数允许您从数据框中选择和提取感兴趣的列,如图 11.1 所示。
# Select `year` and `demVotes` (percentage of vote won by the Democrat)
# from the `presidentialElections` data frame
votes <- select(presidentialElections, year, demVote)
select()
函数将从中选择的数据框作为参数,后跟您希望选择的列的名称(不带引号)!
select()的这种用法相当于使用 base R 语法简单地提取列:
# Extract columns by name (i.e., "base R" syntax)
votes <- presidentialElections[, c ("year", "demVote")]
虽然这种 base R 语法达到了同样的目的,但是 dplyr 方法提供了一种更具表达性的语法,更易于读写。
还记得吗:在 dplyr
函数的函数参数列表(括号内)内,你指定的数据框列没有引号——也就是说,你只是给列名作为变量名,而不是字符串。这就是所谓的 非标评测 (NSE) 。虽然这种能力使 dplyr
代码更容易编写和阅读,但当试图使用存储在变量中的列名时,它有时会带来挑战。如果在这种情况下遇到错误,您可以并且应该使用 base R 语法(例如,美元符号和括号符号)。
Figure 11.1 Using the select()
function to select the columns year and demVote
from the presidentialElections
data frame. Figure 11.2 Percentage of votes cast for Democratic Party candidates in U.S. presidential elections, built with the ggplot2
package.
如图 11.2 所示,这些数据可以用来探索各州投票模式的趋势。
请注意,select()
函数的参数也可以是列名的向量——您可以完全按照您在括号符号中指定的那样来写,只是不需要调用c()
。因此,您既可以使用:运算符选择一系列列,也可以使用-运算符排除列:
# Select columns `state` through `year` (i.e., `state`, `demVote`, and `year`)
select(presidentialElections, state:year)
# Select all columns except for `south`
select(presidentialElections, -south)
注意:与使用括号符号不同,使用 select()
选择单个列将返回数据帧,而不是向量。如果要从数据框中提取特定的列或值,可以使用 dplyr
包中的 pull()
函数,或者使用 base R 语法。一般来说,使用 dplyr
来操作数据帧,然后使用 base R 来引用该数据中的特定值。
过滤器
**filter()**
函数允许您从数据框中选择并提取感兴趣的行(与提取列的select()
相反),如图 11.3 所示。
# Select all rows from the 2008 election
votes_2008 <- filter(presidentialElections, year == 2008)
filter()
函数接收要过滤的数据帧,后面是一个逗号分隔的条件列表,每个返回的行都必须满足这些条件。同样,必须指定不带引号的列名。前面的filter()
语句相当于使用下面的 base R 语法提取行:
# Select all rows from the 2008 election
votes_2008 <- presidentialElections[presidentialElections$year == 2008, ]
filter()
函数将提取符合所有给定条件的行。因此,您可以指定您想要为满足第一个条件和第二个条件的行过滤数据框(以此类推)。例如,你可能很好奇科罗拉多州在 2008 年是如何投票的:
# Extract the row(s) for the state of Colorado in 2008
# Arguments are on separate lines for readability
votes_colorado_2008 &amp;amp;amp;amp;amp;amp;lt;- filter(
presidentialElections,
year == 2008,
state == "Colorado"
)
Figure 11.3 Using the filter()
function to select observations from the presidentialElections
data frame in which the year column is 2008.
在使用多个条件的情况下——因此可能会编写很长的代码——为了可读性,应该将单个语句分成多行(如前面的示例所示)。因为函数参数的圆括号还没有括起来,R 会把每一个新的行当作当前语句的一部分。详见 tidyverse 风格指南。
注意:如果您正在处理一个有行名的数据框( presidentialElections
没有),则 dplyr
函数将移除行名。如果您需要保留这些名称,请考虑将它们作为数据的一列(特征),从而允许您在争论和分析中包含这些名称。您可以使用 mutate 函数(在第 11.2.3 节中描述)将行名添加为一列:
# Add row names of a dataframe `df` as a new column called `row_names`
df <- mutate(df, row_names = rownames(df))
变异
mutate()
功能允许您为数据框创建额外的列,如图 11.4 所示。例如,在presidentialElections
数据框中添加一列来存储其他候选人的投票百分比可能会很有用:
# Add an `other_parties_vote` column that is the percentage of votes
# for other parties
# Also add an `abs_vote_difference` column of the absolute difference
# between percentages
# Note you can use columns as you create them!
presidentialElections <- mutate(
presidentialElections,
other_parties_vote = 100 - demVote, # other parties is 100% - Democrat %
abs_vote_difference = abs(demVote - other_parties_vote)
)
mutate()
函数接受要变异的数据框,后跟一个逗号分隔的列列表,使用从头开始创建列表或数据框时使用的相同的name = vector
语法来创建。与往常一样,数据框中的列名称不带引号。同样,为了保持间距和可读性,通常将每个新列声明放在单独的一行上。
注意:顾名思义, mutate()
函数实际上并不改变数据帧;相反,它会返回一个添加了额外列的新数据框。您通常希望用这个新值替换旧的数据框变量(如前面的代码所示)。
Figure 11.4 Using the mutate()
function to create new columns on the presidentialElections
data frame. Note that the mutate()
function does not actually change a data frame (you need to assign the result to a variable).
提示:如果您想重命名一个特定的列而不是添加一个新列,您可以使用 dplyr
函数 rename()
,这实际上是将一个命名参数传递给 select()
函数来选择别名不同的列的一种变体。
安排
arrange()
函数允许您根据某些特征(列值)对数据框的行进行排序,如图 11.5 所示。例如,您可能希望按年份对presidentialElections
数据帧进行排序,然后在每一年内,根据民主党候选人获得的选票百分比对行进行排序:
# Arrange rows in decreasing order by `year`, then by `demVote`
# within each `year`
presidentialElections <- arrange(presidentialElections, -year, demVote)
Figure 11.5 Using the arrange()
function to sort the presidentialElections
data frame. Data is sorted in decreasing order by year (-year), then sorted by the demVote
column within each year.
如前面的代码所示,您可以向arrange()
函数传递多个参数(除了要排列的数据帧之外)。数据框将按照作为第二个参数提供的列进行排序,然后按照作为第三个参数提供的列进行排序(在“平局”的情况下),依此类推。和mutate()
一样,arrange()
函数实际上并不修改自变量数据帧;相反,它会返回一个新的数据框,您可以将其存储在变量中以供以后使用。
默认情况下,arrange()
函数将按照增加的顺序对行进行排序。要按相反(递减)顺序排序,请在列名前加一个减号(-)(如-year)。也可以使用desc()
辅助函数;例如,你可以通过desc(year)
作为参数。
总结
**summarize()**
函数(相当于使用英式拼写的summarise()
)将生成一个新的数据框,其中包含一列的“摘要”,从该列的多个元素中计算出一个值。这是一个聚合操作(也就是说,它会将整个列缩减为一个值——考虑取一个和或平均值),如图 11.6 所示。例如,您可以计算民主党候选人的平均投票百分比:
# Compute summary statistics for the `presidentialElections` data frame
average_votes <- summarize(
presidentialElections,
mean_dem_vote = mean(demVote),
mean_other_parties = mean(other_parties_vote)
)
summarize()
函数接收要聚合的数据框,然后是将为生成的汇总表计算的值。这些值是使用name = value
语法指定的,
Figure 11.6 Using the summarize()
function to calculate summary statistics for the presidentialElections
data frame.
类似于使用mutate()
或者定义一个列表。您可以使用多个参数在同一个语句中包含多个聚合。这将返回一个数据框,对于该函数计算的每个值,该数据框只有一行和不同的列,如图 11.6 所示。
summarize()
函数产生汇总值的数据框(表格)。如果您想要引用这些单独的聚合,您将需要使用 base R 语法或dplyr
函数pull()
从这个表中提取它们。
您可以使用summarize()
函数通过任何以向量作为参数并返回单个值的函数来聚合列。这包括许多内置的 R 函数,如mean()
、max(),
和median()
。或者,您可以编写自己的汇总函数。例如,使用presidentialElections
数据帧,您可能想要找到最不接近的 选举(即demVote
距离绝对值 50%最远的那个)。下面的代码构造了一个函数来查找距离向量中的 50 最远的值,然后使用summarize()
将该函数应用于presidentialElections
数据帧:
# A function that returns the value in a vector furthest from 50
furthest_from_50 <- function(vec) {
# Subtract 50 from each value
adjusted_values <- vec - 50
# Return the element with the largest absolute difference from 50
vec[abs(adjusted_values) == max(abs(adjusted_values))]
}
# Summarize the data frame, generating a column `biggest_landslide`
# that stores the value furthest from 50%
summarize(
presidentialElections,
biggest_landslide = furthest_from_50(demVote)
)
当您处理已经分组的数据时,summarize()
函数的真正威力变得显而易见。在这种情况下,每个不同的组将在汇总表中汇总为不同的行(见第 11.4 节)。
11.3 执行顺序操作
如果您想要进行更复杂的分析,您可能想要组合这些函数,将一个函数调用的结果传递给另一个函数,这是一个非常常见的工作流。执行这一系列操作的一种方法是创建中间变量用于您的分析。例如,在处理presidentialElections
数据集时,您可能想问一个类似如下的问题:
“2008 年民主党候选人(巴拉克·奥巴马)的得票率最高的是哪个州?”
回答这个看似简单的问题需要几个步骤:
- 过滤将数据集过滤为 2008 年的观测数据。
- 在 2008 年的百分比中,将过滤到一个民主党人得票百分比最高的百分比。
- 选择符合上述标准的州名。
然后,您可以按如下方式实现每个步骤:
# Use a sequence of steps to find the state with the highest 2008
# `demVote` percentage
# 1\. Filter down to only 2008 votes
votes_2008 <- filter(presidentialElections, year == 2008)
# 2\. Filter down to the state with the highest `demVote`
most_dem_votes <- filter(votes_2008, demVote == max(demVote))
# 3\. Select name of the state
most_dem_state <- select(most_dem_votes, state)
虽然这种方法可行,但它会使工作环境变得混乱,因为您不需要再次使用这些变量。它确实有助于可读性(每一步的结果都是显式的),但是那些额外的变量使得以后修改和改变算法更加困难(你必须在两个地方改变它们)。
除了将每个步骤保存为不同的命名变量之外,还可以使用匿名 变量和嵌套其他函数中所需的语句。虽然这是可能的,但它很快会变得难以读写。例如,您可以按如下方式编写上述算法:
# Use nested functions to find the state with the highest 2008
# `demVote` percentage
most_dem_state <- select( # 3\. Select name of the state
filter( # 2\. Filter down to the highest `demVote`
filter( # 1\. Filter down to only 2008 votes
presidentialElections, # arguments for the Step 1 `filter`
year == 2008
),
demVote == max(demVote) # second argument for the Step 2 `filter`
),
state # second argument for the Step 3 `select`
)
这个版本使用匿名变量——结果值不赋给变量(因此是匿名的)——而是直接用作其他函数的参数。您已经在print()
函数和过滤器(那些真值和假值的向量)中频繁使用了这些匿名变量——甚至在步骤 2 过滤器中的max(demVote)
也是一个匿名变量!
这种嵌套方法与上一个示例在不创建额外变量的情况下获得了相同的结果。但是,即使只有三个步骤,阅读起来也会非常复杂——很大程度上是因为您必须“从里到外”地考虑它,首先评估中间的代码。对于更复杂的操作,这显然将变得不可理解。
管道操作员
幸运的是,dplyr
提供了一种更干净、更有效的方法来执行相同的任务(也就是说,使用一个函数的结果作为下一个函数的参数)。管道操作符(写作 % > % )从一个函数中获取结果,并将其作为第一个参数传递给下一个函数!您可以使用管道运算符更直接地回答前面提出的问题,如下所示:
# Ask the same question of our data using the pipe operator
most_dem_state <- presidentialElections %>% # data frame to start with
filter(year == 2008) %>% # 1\. Filter down to only 2008 votes
filter(demVote == max(demVote)) %>% # 2\. Filter down to the highest `demVote`
select(state) # 3\. Select name of the state
这里,presidentialElections
数据帧作为第一个filter()
调用的第一个参数被“输送”进来;因为参数已经通过管道传入,filter()
调用只接受剩余的参数(例如,year == 2008)。然后,该函数的结果作为第一个参数传递给第二个filter()
调用(只需要指定其余的参数),依此类推。额外的参数(如过滤条件)继续正常传入,就像不需要数据框参数一样。
因为本章中讨论的所有dplyr
函数都将要操作的数据帧作为第一个参数,然后返回一个被操作的数据帧,所以可以使用管道将这些函数“链接”在一起!
是的,%>%操作符可能很难输入,需要一些时间来适应(特别是与命令行使用的| to pipe 相比)。但是,您可以使用 RStudio 键盘快捷键 cmd+shift+m 来简化输入。
提示:导航到工具>键盘快捷键帮助菜单就可以看到所有的 RStudio 键盘快捷键,也可以使用键盘快捷键 alt+shift+k (没错,这就是显示键盘快捷键菜单的键盘快捷键!).
管道操作符在你加载dplyr
包时被加载(只有在你加载那个包时才可用),但是它将与任何函数一起工作,而不仅仅是dplyr
函数。这种语法虽然有点奇怪,但可以极大地简化您编写代码来询问有关数据的问题的方式。
趣闻:很多包加载其他包(称为依赖)。例如,管道操作符实际上是 [magrittr](https://cran.r-project.org/web/packages/magrittr/vignettes/)
包的一部分,它作为 dplyr.
的依赖项被加载
请注意,与前面的示例一样,最佳实践是将管道序列的每个“步骤”放在自己的行上(缩进两个空格)。这允许您轻松地重新安排步骤(简单地通过移动行),以及“注释掉”特定的步骤来测试和调试您的分析。
11.4 按组分析数据帧
函数是强大的,但是当你将它们应用到一个数据集内的行组时,它们才是真正令人敬畏的。例如,前面描述的summarize()
的用法并不是特别有用,因为它只是给出了给定列的一个摘要(使用 base R 函数可以很容易地做到这一点)。然而,分组操作将允许您为多组行自动计算相同的汇总度量(例如 mean, median, sum
),使您能够对您的数据集提出更细微的问题。
**group_by()**
函数允许您在数据框中的行的组之间创建关联,以便您可以轻松地执行此类聚合。它以要进行分组的数据框作为参数,后跟要用于对数据进行分组的列-表中的每一行都将与该列中具有相同值的其他行进行分组。例如,您可以将presidentialElections
数据集中的所有数据分组到行共享相同状态值的组中:
# Group observations by state
grouped <- group_by(presidentialElections, state)
group_by()
函数返回一个 tibble ,这是一个版本的数据帧,由“ tidyverse ”系列的包(包括dplyr
)使用。您可以将此视为一种“特殊”的数据框,它能够跟踪同一变量中的“子集”(组)。虽然这种分组在视觉上并不明显(即,它不对行进行排序),但是 tibble 会跟踪每一行的分组以进行计算,如图 11.7 所示。
group_by()
函数很有用,因为它让您可以对数据组应用操作,而不必显式地将数据分成不同的变量(有时称为箱或块)。一旦您使用group_by()
对数据框的行进行分组,您可以将其他动词(例如summarize(), filter()
)应用于该表,它们将自动应用于每个组的(就好像它们是单独的数据框)。您不需要将不同的数据集明确提取到单独的数据帧中并对每个数据帧运行相同的操作,而是可以使用group_by()
函数通过一个命令来完成所有这些操作:
Figure 11.7 A tibble—created by the group_by()
function—that stores associations by the grouping variable (state). Red notes are added.
# Compute summary statistics by state: average percentages across the years
state_voting_summary <- presidentialElections %>%
group_by(state) %>%
summarize(
mean_dem_vote = mean(demVote),
mean_other_parties = mean(other_parties_vote)
)
前面的代码将首先按州将行分组,然后计算每个组(即每个州)的汇总信息(mean()
值),如图 11.8 所示。组的摘要仍然会返回一个表,其中每一行都是不同组的摘要。您可以使用美元符号或括号符号从表格中提取值,或者使用as.data.frame()
函数将其转换回普通数据框。
Figure 11.3 Using the group_by()
and summarize()
functions to calculate summary statistics in the presidentialElections
data frame by state.
这种分组形式可以让您快速比较不同的数据子集。这样做,你就重新定义了你的分析单位。分组可以让你通过比较组观察,而不是单个观察来构建你的分析问题。这种形式的抽象使得询问和回答关于数据的复杂问题变得更加容易。
11.5 将数据框连接在一起
当处理真实世界的数据时,您经常会发现数据存储在多个文件或数据框中。这样做有很多原因,比如减少内存使用。例如,如果您有一个包含跟踪捐款的筹款活动信息(例如,金额、日期)的数据框,您可能会将每个捐款人的信息(例如,电子邮件、电话号码)存储在一个单独的数据文件中(因此也是数据框)。参见图 11.9,这是一个关于这种结构的例子。
这种结构有许多好处:
- 数据存储:你可以一次存储一次信息,而不是每次捐款时都复制每个捐款人的信息。这将减少数据占用的空间。
- 数据更新:如果您需要更新捐赠人的信息(如捐赠人的电话号码变更),您可以在单个位置进行变更。
这种数据的分离和组织是关系数据库设计中的核心问题,这将在本书第 13 章中讨论。
在某些情况下,您会想要访问来自两个数据集的信息(例如,您需要向捐赠者发送电子邮件,告知他们的捐赠情况),因此需要一种方法来同时引用来自两个数据框架的值——实际上是将数据框架的合并。此过程称为连接(因为您将数据框“连接”在一起)。当您执行一个连接时,您识别两个表中都存在的列,并使用这些列将相应的行相互“匹配”。这些列值被用作标识符来确定每个表中的哪些行相互对应,因此将被组合成结果(连接)表中的一行。
Figure 11.9 An example data frame of donations (left) and donor information (right). Notice that not all donors are present in both data frames.
left_join() 函数就是一个连接的例子。此函数查找两个数据框之间的匹配列,然后返回一个新的数据框,该数据框是第一个(“左”)参数,并添加了第二个(“右”)参数中的额外列-实际上是“合并”表。您可以通过指定一个 by 参数来指定想要“匹配”的列,该参数采用一个列名向量(作为字符串)。
例如,因为图 11.9 中的两个数据框都有一个donor_name
列,所以您可以通过该列将捐赠者表中的行与捐赠表进行“匹配”,并将它们合并在一起,从而生成图 11.10 中所示的连接表。
# Combine (join) donations and donors data frames by their shared column
# ("donor_name")
combined_data <- left_join(donations, donors, by = "donor_name")
当您像前面的代码那样执行左连接时,该函数将执行以下步骤:
- 它遍历表中“左边”的每一行(第一个参数;例如,
donations
),考虑来自共享列的值(例如,donor_name
)。 - 对于左侧表中的每个值,该函数在右侧表中查找在指定列中具有与相同的值的行(例如
donors
)。 - 如果找到这样一个匹配行,它会将捐赠者中但不在捐赠中的列中的任何其他数据值添加到结果表中左边的行。
- 它对左侧表格中的每一行重复步骤 1-3,直到所有行都从右侧的匹配项(如果有)中获得了值。
您可以在图 11.10 中看到,左边表格中的元素(donations
)与右边表格中的行(donors
)不匹配。这可能是因为一些捐赠的捐赠者没有联系信息(没有匹配的donor_name
条目):这些行将被赋予 NA ( 不可用)值,如图 11.10 所示。
记住:左连接返回第一个表中的所有行,以及两个表中的所有列。
对于要匹配的行,它们需要在所有指定的共享列中有相同的数据。但是,如果您的列名不匹配,或者如果您想只匹配特定的列,您可以使用一个名为 vector (带有类似于列表的标签)的来表示每个数据框的不同名称。如果不指定 by 参数,该连接将在上匹配所有的共享列名。
# An example join in the (hypothetical) case where the tables have
# different identifiers; e.g., if `donations` had a column `donor_name`,
# while `donors` had a column `name`
combined_data <- left_join(donations, donors, by = c("donor_name" = "name"))
Figure 11.10 In a left join, columns from the right hand table ( Donors
) are added to the end of the left-hand table ( Donations
). Rows are on matched on the shared column ( donor_name
). Note the observations present in the left-hand table that don’t have a corresponding row in the right-hand table ( Yang Huiyan
).
注意:因为连接是如何定义的,所以参数顺序很重要!例如,在一个 left_join()
中,得到的表格只有左(第一个)表格中的元素的行;第二个表中任何不匹配的元素都将丢失。
如果您改变参数的顺序,您将保留捐赠者数据框中的所有信息,并添加捐赠的可用信息(见图 11.11)。
# Combine (join) donations and donors data frames (see Figure 11.11)
combined_data <- left_join(donors, donations, by = "donor_name")
由于一些donor_name
值在右侧(捐赠)表中出现多次,捐赠者的行最终会重复出现,这样信息就可以与捐赠的每组值“合并”。同样,请注意,右侧表中缺少匹配项的行不会获得任何附加信息(代表向组织提供了联系信息但尚未进行捐赠的“捐赠者”)。
因为参数的顺序很重要,dplyr
(以及一般的关系数据库系统)提供了几种不同的连接,每一种都会影响最终表中包含哪些行。请注意,在所有联接中,两个表中的列都将出现在结果表中,联接类型决定了包括哪些行。参见图 11.12 中这些连接的示意图。
left_join
:返回第一个(左)数据帧的所有行。也就是说,您从左边的表中获取所有数据,并从右边的表中添加额外的列值。没有匹配项的左侧行将在右侧列中显示 NA。
Figure 11.11 Switching the order of the tables in a left-hand join (compared to Figure 11.10) returns a different set of rows. All rows from the left-hand table ( donors
) are returned with additional columns from the right-hand table ( donations
). Figure 11.12 A diagram of different join types.
right_join
:返回第二个(右)数据帧的所有行。也就是说,您从右边的表中获取所有数据,并从左边的表中添加额外的列值。没有匹配项的右侧行将在左侧列中显示 NA。这是一个left_join
的“反义词”,相当于交换参数的顺序。inner_join:
只返回两个数据框中的行。也就是说,您将获得在两个表中具有匹配观察值的任何行,以及两个表中的列值。连接不会产生额外的 NA 值。来自左边的观察结果与右边的不匹配,或者来自右边的观察结果与左边的不匹配,都不会被返回——参数的顺序无关紧要。full_join
:返回两个数据帧的所有行。也就是说,无论是否匹配,任何观察都会得到一行。如果恰好匹配,两个表中的值将出现在该行中。没有匹配的观察值将在另一个表的列中有 NA——参数的顺序无关紧要。
决定这些连接的关键是考虑您想要哪组数据作为您的观察值(行),以及如果记录丢失,您可以接受哪列为 NA。
提示: Jenny Bryan 为 dplyr
join 函数创建了一个优秀的 cheatsheet ,可以参考。
更进一步:这里讨论的所有连接都是变异连接,将一个表中的列添加到另一个表中dplyr
还提供过滤连接,根据它们在另一个表中是否有匹配的观察值来排除行,以及集合操作,将观察值组合起来,就像它们是集合元素一样。参见包文档中关于这些选项的更多细节——但是开始时,您可以主要关注变异连接。
11.6 dplyr
行动中:分析飞行数据
在本节中,您将了解如何使用dplyr
函数来询问更复杂数据集的有趣问题(该分析的完整代码也可以在书的代码库中在线获得)。您将使用 2013 年从纽约市机场(包括纽瓦克机场、约翰·肯尼迪机场和拉瓜迪亚机场)出发的航班数据集。该数据集也在 简介dplyr
简介 中在线展示,并取自运输统计局数据库。要加载数据集,您需要安装并加载nycflights13
包。这将把航班数据集加载到您的环境中。
# Load the `nycflights13` package to access the `flights` data frame
install.packages("nycflights13") # once per machine
library("nycflights13") # in each relevant script
在开始询问数据集的目标问题之前,您需要更好地理解数据集的结构:
# Getting to know the `flights` data set
?flights # read the available documentation
dim(flights) # check the number of rows/columns
colnames(flights) # inspect the column names
View(flights) # look at the data frame in the RStudio Viewer
图 11.13 显示了 RStudio 查看器中的航班数据框的子集。
根据这些信息,您可能会有兴趣询问如下问题:
- 哪家航空公司的出发航班延误数量最高?
- 平均日,最早到达的航班有哪些机场?
- 哪个月的航班最容易出现最长的延误?
您在这里的任务是将这些问题映射到特定的过程,以便您可以编写适当的dplyr
代码。
你可以从问第一个问题开始:
“哪家航空公司的航班延误次数最多?”
此问题涉及到比较具有特定特征(航空公司)的观测值(航班),因此您需要执行如下分析:
Figure 11.13 A subset of the flights data set, which is included as part of the nycflights13
package.
提示:当你试图找到合适的操作来回答你感兴趣的问题时,短语“找到那个……的条目”通常对应一个filter()
操作!
一旦你建立了这个算法,你可以直接把它映射到dplyr
函数:
# Identify the airline (`carrier`) that has the highest number of
# delayed flights
has_most_delays <- flights %>% . # start with the flights
group_by(carrier) %>% # group by airline (carrier)
filter(dep_delay > 0) %>% # find only the delays
summarize(num_delay = n()) %>% # count the observations
filter(num_delay == max(num_delay)) %>% # find most delayed
select(carrier) # select the airline
记住:往往很多方法可以用来解决同一个问题。前面的代码显示了一种可能的方法;或者,您可以在分组前过滤延迟出发的航班。重点是考虑如何根据数据操作的语法(手工)解决问题,然后将其转换成dplyr
!
遗憾的是,这个问题的最终答案似乎是一个缩写:UA
。为了减小flights
数据帧的大小,关于每个airline
的信息被存储在一个叫做航空公司的单独的数据帧中。由于您对组合这两个数据框(您的答案和航空公司信息)感兴趣,您可以使用一个连接:
# Get name of the most delayed carrier
most_delayed_name <- has_most_delays %>% # start with the previous answer
left_join(airlines, by = "carrier") %>% # join on airline ID
elect(name) # select the airline name
print(most_delayed_name$name) # access the value from the tibble
# [1] "United Air Lines Inc."
在这一步之后,你将会了解到延误绝对次数最大的航空公司是联合航空公司。然而,在过于强烈地批评航空公司之前,请记住,你可能会对航班延误的比例感兴趣,这需要进行单独的分析。
接下来,你可以评估第二个问题:
"平均来说,哪个机场的航班最早到达?"
要回答这个问题,可以遵循类似的方法。因为这个问题与航班提前到达的时间有关,所以感兴趣的结果(特征)是arr_delay
(注意,负的延迟量表示航班提前到达)。您会希望按照航班到达的目的地机场 (dest)对这些信息进行分组。然后,由于您对平均到达延迟感兴趣,您会希望汇总这些组来汇总它们:
# Calculate the average arrival delay (`arr_delay`) for each destination
# (`dest`)
most_early <- flights %>%
group_by(dest) %>% # group by destination
summarize(delay = mean(arr_delay)) # compute mean delay
在执行分析的每一步时检查你的工作总是一个好主意——不要写一长串的操作并希望你得到正确的答案!通过在此时打印出 most_early 数据帧,您会注意到它有许多 NA 值,如图 11.14 所示。
在进行数据编程时,这种意想不到的结果经常发生——解决问题的最好方法是逆向工作。通过仔细检查arr_delay
列,您可能会注意到一些条目具有 NA 值——到达延迟不适用于该记录。因为您无法获得 NA 值的mean()
,所以您决定从分析中排除这些值。您可以通过向mean()
函数传递一个na.rm = TRUE
参数(“NA remove”)来实现这一点:
# Compute the average delay by destination airport, omitting NA results
most_early <- flights %>%
group_by(dest) %>% # group by destination
summarize(delay = mean(arr_delay, na.rm = TRUE)) # compute mean delay
Figure 11.14 Average delay by destination in the flights
data set. Because NA values are present in the data set, the mean delay for many destinations is calculated as NA. To remove NA values from the mean()
function, set na.rm = FALSE
.
移除 NA 值会返回数值结果,您可以继续使用您的算法:
# Identify the destination where flights, on average, arrive most early
most_early <- flights %>%
group_by(dest) %>% # group by destination
summarize(delay = mean(arr_delay, na.rm = TRUE)) %>% # compute mean delay
filter(delay == min(delay, na.rm = TRUE)) %>% # filter for least delayed
select(dest, delay) %>% # select the destination (and delay to store it)
left_join(airports, by = c("dest" = "faa")) %>% # join on `airports` data
select(dest, name, delay) # select output variables of interest
print(most_early)
# A tibble: 1 x 3
# dest name delay
# <chr> <chr> <dbl>
# 1 LEX Blue Grass -22
回答这个问题遵循与第一个问题非常相似的结构。前面的代码通过在管道操作序列中包含left_join()
语句,将步骤减少到一条语句。请注意,包含机场代码的列在flights and airports
数据帧中有不同的名称(分别是dest
和faa
,因此您使用 by 参数的命名向量值来指定匹配。
结果,您了解到肯塔基州列克星敦的蓝草机场是平均到达时间最早的机场(提前 22 分钟!).
最后一个问题是:
“哪个月的航班延误时间最长?
这些类型的汇总问题都遵循类似的模式:按感兴趣的列(特性)对数据进行分组,为每个组计算感兴趣的(另一个)特性的汇总值,将过滤为感兴趣的行,然后选择回答您的问题的列
# Identify the month in which flights tend to have the longest delays
flights %>%
group_by(month) %> # group by selected feature
summarize(delay = mean(arr_delay, na.rm = TRUE)) %>% # summarize delays filter(delay == max(delay)) %&amp;amp;amp;amp;amp;amp;gt;% # filter for the record of interest
select(month) %>% # select the column that answers the question
print() # print the tibble out directly
# A tibble: 1 x 1
# month
# <int>
#1 7
如果您不介意结果是 tibble 而不是 vector 的形式,您甚至可以将结果直接传送到print()
函数,以便在 R 控制台中查看结果(答案是 July )。或者,你可以使用一个包,比如ggplot2
(见第 16 章)来可视化地传达每月的延迟,如图 11.15 所示。
# Compute delay by month, adding month names for visual display
# Note, `month.name` is a variable built into R
delay_by_month <- flights %>%
group_by(month) %>%
summarize(delay = mean(arr_delay, na.rm = TRUE)) %>% select(delay) %
mutate(month = month.name)
# Create a plot using the ggplot2 package (described in Chapter 17)
ggplot(data = delay_by_month) +
geom_point(
mapping = aes(x = delay, y = month),
color = "blue",
alpha = .4,
size = 3
)+
geom_vline(xintercept = 0, size = .25) +
xlim(c(-20, 20)) +
scale_y_discrete(limits = rev(month.name)) +
labs(title = "Average Delay by Month", y = "", x = "Delay (minutes)")
总的来说,了解如何制定问题,将它们转化为数据操作步骤(遵循数据操作的语法),然后将它们映射到dplyr
函数,将使您能够快速有效地了解关于您的数据集的相关信息。用dplyr
包练习扯皮数据,见一套随书练习。
Figure 11.15 Average flight arrival delay in each month, calculated using the flights
data set. The plot is built using ggplot2
(discussed in Chapter 16).
Domino 编辑评论:最初印刷版本中的脚注显示为叙述性超链接,以方便阅读。
手动特征工程
原文:https://www.dominodatalab.com/blog/manual-feature-engineering
非常感谢 AWP·皮尔森允许从马克·e·芬纳的书中摘录“手动特征工程:操纵数据以获得乐趣和利润。还有一个互补的多米诺项目可用。
介绍
许多数据科学家通过映射,开发和部署适当的 ML 解决方案来解决业务问题,从而为他们的组织交付价值。当评估关于他们的 ML 模型的影响的权衡决策时,特征工程对数据科学家是有用的。它是一个处理最大似然的框架,也提供了从原始数据中提取特征的技术,这些特征可以在模型中使用。当 Domino 寻求帮助数据科学家加速他们的工作时,我们联系 AWP·皮尔森,请求允许我们从《用 Python 为每个人进行机器学习》一书中摘录“手动特征工程:操纵数据以获得乐趣和利润,作者是马克·e·芬纳。非常感谢AWP·皮尔森提供摘录作品的许可,并使我们能够提供一个补充的公开可见的多米诺骨牌项目。如果有兴趣运行项目中的例子,那么登录。
章节介绍:手动特征工程
# setup
from mlwpy import *
%matplotlib inline
iris = datasets.load_iris()
(iris_train, iris_test,
iris_train_tgt, iris_test_tgt) = skms.train_test_split(iris.data,
iris.target,
test_size=.25)
#remove units ' (cm)' from names
iris.feature_names = [fn[:-5] for fn in iris.feature_names]
# dataframe for convenience
iris_df = pd.DataFrame(iris.data, columns=iris.feature_names)
iris_df['species'] = iris.target_names[iris.target]
10.1 特征工程术语和动机
我们将把我们的注意力从扩大我们的模型目录上转移开[如之前在本书中提到的】,取而代之的是仔细查看数据。特征工程是指对特征的操作——添加、删除、组合、变异。请记住,特性是属性-值对,因此我们可以从数据表中添加或删除列,并修改列中的值。特征工程有广义和狭义之分。
我将从广泛、包容的意义上使用它,并指出一些问题。以下是一些具体的例子:
- 缩放和归一化意味着调整数据的范围和中心,以便于学习和改进对结果的解释。您可能还记得
sklearn
中的一书中的糖尿病数据集(第 4.1 节)是在标准化之前提供给我们的,这是一种缩放形式。 - 填充缺失值。由于收集完整数据集的困难以及数据收集过程中的错误,真实世界的数据集可能会丢失值。缺失值可以基于专家知识、试探法或通过一些机器学习技术来填充。
- 特征选择意味着移除特征,因为它们不重要、多余或者对学习完全起反作用。有时候,我们只是拥有太多的功能,而我们需要更少的。适得其反的特征的一个例子是无助于泛化的标识变量。我们在第 8.2 节[ 在本书中看到,对于每个训练示例,唯一标识符可以引导决策树从根一直到唯一叶。问题是一个测试实例的新的唯一标识符不会出现在树的任何地方。失败。
- 特征编码包括选择一组符号值来代表不同的类别。我们早在[书中]第一章就讨论过这个问题。 WithPartner 的概念可以用单列取值 WithPartner 或 Single 来捕获,也可以用两列 WithPartner 和 Single 来捕获,其中一列为真,另一列为假。严格来说,这是一种特征构建的形式。
- 特征构建从一个或多个其他特征创建新特征。例如,从花的萼片长度和宽度,我们可以创建花的萼片面积。
- 特征提取意味着从不适合学习的低级特征——实际上,我们得到的测试结果很差——转移到对学习有用的高级特征。通常,当我们有特定的数据格式(如图像或文本)需要转换为表格行列格式(例如要素格式)时,特征提取很有价值。特征提取和特征构造在它们所进行的变换的复杂性方面有所不同,但是在概念上它们做的是相同的事情。
10.1.1 为什么是工程特性?
特征工程的两个驱动因素是(1)来自任务领域的背景知识和(2)数据值的检查。第一种情况包括医生对重要血压阈值的了解或会计师对税级水平的了解。另一个例子是医疗提供者和保险公司使用身体质量指数(身体质量指数)。虽然它有局限性,但身体质量指数可以根据体重和身高快速计算出来,并作为一个很难精确测量的特征的替代物:瘦体重的比例。检查某个特性的值意味着查看其分布直方图。对于基于分布的特征工程,我们可能会看到多峰分布——具有多个峰的直方图——并决定将峰分成多个区间。
10.1.2 工程何时发生?
我们在特征工程中可以做出的一个主要区别是它何时发生。我们这里的主要问题是特性工程是否在交叉验证循环中执行。在建模过程中完成的特征工程通常在交叉验证循环中完成。交叉验证可以保护我们避免过度拟合。
我们还可以在开始建模过程之前修改特征。通常,这些修改是从存储系统(如数据库)导出数据的一部分。我的使用数据库的读者将熟悉提取-转换-加载(ETL)范式。特征工程也可以是数据清理的一部分,作为导出/导入数据和学习之间的中间步骤。如果我们在建立模型之前处理数据,我们需要非常小心,不要偷看预测特征和目标之间的关系。我们还需要小心,这样我们就不会无意中引入了一个原始数据中不存在的关系。有很多很多方式我们会犯错和失败。
因此,如果我们要执行预建模特征工程,我们应该非常小心,在开始处理数据之前,先存放一个坚持测试集。测试集将允许我们评估预建模特征工程和直接建模步骤的结果。我们可以使用拒绝测试集来保护我们免受交叉验证循环之外的危险特性工程的影响。我们照常进行,看看我们的训练和测试错误会发生什么。如果我们的训练错误是好的,但是我们看到我们的测试错误没有改善——或者甚至变得更差—那么我们可以假设我们过度拟合了。在这种情况下,我们可能希望将一些特征工程转移到交叉验证循环中,以便更早地检测过度拟合。
现在,我们有两个相互竞争的问题。如果你的特性工程需要在交叉验证循环中,最简单的编程钩子意味着你可能想要用sklearn
来执行它。但是如果你的特征工程很复杂并且还没有在sklearn
中实现,你可能不想使用sklearn
——你可能想使用pandas
或者其他定制的 Python 工具。现在真正的难题是:如果你有复杂的特征工程需要在 CV 循环中,我最美好的祝愿与你同在。同时满足这两种需求是困难的。说真的,你可能想把一些最复杂的部分分解出来作为预处理。尽管如此,您还是可以编写可以放在 CV 循环中的助手代码。在本书第 9.3.1 节中,我们定义了一个自定义学习者。您还可以定义一个定制的转换器,我们很快就会看到。
对特征工程的时间的实际把握给了我们一个总体时间表:
- 从外部来源提取数据,可能使用用 Python 编写的帮助器代码,并利用包与数据库等其他系统接口。
- 分离出一个保留测试集。不要偷看。
- 使用外部系统和/或 pure Python 执行任何初始数据清理。
- 将数据放入熊猫
DataFrame
中,并做任何额外的预建模数据辩论。数据争论是在学习步骤之前进行的特征工程的常用术语。 - 用
sklearn
设计学习和 CV 内循环特征工程步骤。 - 将数据从
pandas
传输到sklearn
并按下 Go 。 - 评估结果。
10.1.3 特征工程是如何发生的?
另一个问题是特征工程是如何发生的。本章的重点是明确定义和手动应用的特征工程。明确定义的特征工程任务的一个示例是创建身高和体重之间的比率,该比率可创建身体质量指数值。如果我们是字面上的负责计算该值并向我们的数据集添加一列,我称之为手动应用的特征工程——在这种情况下,是手动特征构造。如果我们建立一个管道(在下一章中),构建所有可能的特征对之间的比率,我称之为自动应用的。**
有一些学习方法将特征工程作为其操作的一部分。其中一些方法——如支持向量机(第 13.2.4 节)[一书中的[——在幕后使用重新设计的功能,无需我们的干预。其他的——像主成分分析(第 13.3 节)]一书中的——要求我们利用它们的输出作为另一个学习步骤的输入。在这两种情况下,我们执行的步骤类似于我们已经看到的学习算法:我们将模型拟合到训练数据,然后我们转换测试数据。
10.2 特征选择和数据简化:清除垃圾
我们在特征工程中最笨拙的工具之一是删除数据。我们可能会因为冗余、不相关或过载而删除数据。(快速补充说明:我是从从我们的数据集中移除特征的角度来讨论这个问题的。我们同样可以考虑从我们的数据集中删除示例——即行而不是列。)
冗余是一个问题,这有实际和技术上的原因。我们将在本章后面看到一些技术原因。从实际的角度来看,如果两列表示相同的概念——或者,更糟的是,相同的文字值——那么我们就要四处移动并存储比我们需要的更多的数字。学习系统可以通过多种形式获得信息。一些学习系统不能有效地处理这一点。
不相关的功能更差。它们不仅占用空间,还会把我们引向在测试时表现不佳的训练路径。想象几列随机数据。我们可以在数据集中放入足够多的随机列来唯一地标识每个例子。然后,我们可以从这些伪标识符中记忆一个查找表来校正目标。但是接下来,我们怎么处理一个新的例子呢?如果我们只是填入几个随机值,目标也会同样随机。在有用的特征——非随机的特征——和目标之间没有任何关系。我们在本书的第 8.2 节中讨论了决策树的困难。
我所说的过载只是指在非常大的数据集中(包含许多许多要素),由于处理时间和内存限制,我们可能别无选择,只能减少考虑的要素数量。那么,如果我们需要转储一些数据,我们该怎么做呢?有三种主要策略:基于我们对问题和数据的知识的手动技术,使用抛硬币来保留或丢弃数据的随机采样技术,以及试图保留与我们的学习模型良好交互的特征的基于模型的技术。有时这些方法会结合起来:我们可以使用随机特征选择来建立模型,然后将得到的模型结合起来。我们将在本书第 12 章中讨论这个问题。
手动随机特征选择在概念上很简单。从表中删除一列——要么基于原则论点(我们知道这两列测量的是同一事物),要么基于随机性。完成了。我这里没有而是。基于学习模型选择或丢弃数据弥补了其他两个选项的简单性。有大量关于这个主题的书籍和文章。我们只能触及表面。然而,这里有一些例子。
一些特征选择策略是学习技术的内部组成部分。例如,决策树必须在每个节点选择一个特征进行分割。一种类型的决策树使用称为信息增益的度量来决定一个好的特征。我们可以将这种想法扩展到对更大数据集的特征进行分级。我们还可以使用建模的结果来评估特性。例如,我们可以查看线性回归系数较低的特征,并声明它们对整个模型相对不重要。这不一定会节省我们在第一个建模过程中的工作,但是它可能会在未来的模型中节省大量的时间。我们还可以建立许多模型,并询问这些模型之间的共性是什么。在许多模型中出现的特征可能对与目标的关系更重要。
我们线性回归的一种正则化形式——L1——正则化回归或拉索——有将学习到的系数推向零的趋势。结果是使用套索构建的模型可能会遗漏一些特征。因此,我们说套索方法是作为其操作的隐含部分来执行特征选择的。我们可以使用套索作为我们的最终模型,或者我们可以在使用其他模型之前使用它作为特征选择阶段。
10.3 特征缩放
我们将讨论两种不考虑与其他要素或目标之间任何关系的要素重缩放和重居中的方法。重新调整意味着我们转换这些值,使极端值不同,中间值以某种一致的方式移动。将数据重新置于中心位置意味着我们要转换这些值,使极端值不同,中间值以某种一致的方式移动。通常,重新缩放也会导致数据重新居中。重新调整的两种主要方式是在固定标度上改变,或者改变根据数据计算出的某些统计值。哇,马克是不是太激动了?没关系。我们会把它带回来的。
这里有一个固定重缩放的例子。如果您在华氏温度和摄氏温度之间转换,您会将 220 华氏度转换为 100 摄氏度,将 32 华氏度转换为 0 摄氏度。中间的温度(比如 104 华氏度转换为 40 摄氏度)遵循一个固定的规则。
至少这更具体一点,但是我们用来转换这些的固定值是什么呢?嗯,这来自转换温度的公式:
一点代数就把它变成了
也就是我们友好的老 y = mx + b 换个形式。如果你从来没有注意到,用线性公式转换值只是拉伸和移动值; m 负责拉伸, b 负责移位。
fig, ax = plt.subplots(1,1,figsize=(4,3))
f_temps = np.linspace(0, 212, 100)
c_temps = (5/9) * (f_temps - 32)
plt.plot(f_temps, f_temps, 'r', # F -&gt; F
f_temps, c_temps, 'b'); # F -&gt; C
注意上面的红线是如何在下面的蓝线上从 0 到 212 垂直压缩到大约 18 到 100 的。中心值也从 106 移动到 59。除了单位转换(摄氏度到华氏度或米到英尺)之外,最常见的固定缩放是将{min,max}值映射到{0,1}或{ 1,1},并将其他值平均分布在它们之间。
标准化,一种统计尺度调整,有点棘手。它不是基于一个固定的先验值(如将华氏温度转换为摄氏温度的 5/9)从源值延伸到目标值,而是基于源值的范围(通过方差或标准差测量)来压缩值。这种差异可能最好用图表来解释。这里我们使用sklearn
的StandardScaler
来完成繁重的工作。fit_transform 评估训练数据并一次性修改它。它类似于我们通常的model.fit().predict()
,除了它在fit()
步骤中不使用单独的目标。它只是学习——在这种情况下,是均值和标准差——然后应用于它们。经过拟合,还可以转换测试数据。我给数据点的盒子涂了颜色,这样你就可以看到这些点是如何由于变换而移动的。
fig, ax = plt.subplots(1,1,figsize=(4,3))
original = np.random.uniform(-5, 5, 100)
scaled = skpre.StandardScaler().fit_transform(original.reshape(-1,1))[:,0]
bins = np.floor(original).astype(np.uint8) + 5
df = pd.DataFrame({'original':original,
'scaled':scaled,
'hue':bins})
df = pd.melt(df, id_vars='hue', var_name='scale')
sns.swarmplot(x='scale', y='value', hue='hue', data=df).legend_.remove()
这里,度量单位不是华氏温度或摄氏温度:它是标准差的单位。标准差告诉我们数据的分布。我们的数据越分散,标准差就越大。我们标准化后还是线性规模。这可能会令人惊讶。公式如下:
有一个 y = mx + b 藏在里面。我们数据的新中心是零。
奇怪的是,标准化并没有改变数据的整体形状——乍一看可能不一样,但这里有另一个例子。在我们的例子中,我们有来自一个均匀或平坦分布的数据。当我们把它标准化的时候,它仍然是统一的。从视觉上看,该形状具有相对平坦的侧面。只是碰巧被压缩的更厉害而已。再举一个例子——你自己试试——如果数据看起来像一只双峰骆驼,我们对它进行标准化,它仍然有两个驼峰。基本上,我们可以均匀地拉伸或挤压数据的图形,但我们不能比这更扭曲它。
让我们看看如何扩展。下面是MinMaxScaler
和StandardScaler
的简单例子。为了在示例点移动时跟踪它们,我将按照它们的百分位数给它们着色。我用熊猫切的方法来做这个。我不想纠结于此,只是知道这类似于我们在第 9.3 节【本书中制作我们的分段常数回归模型时使用的编码技术。这里,我们利用熊猫的分类能力来创建一个着色值:
iris_df = pd.DataFrame(iris.data, columns=iris.feature_names)
bins = pd.cut(iris_df['sepal width'],
np.percentile(iris_df['sepal width'],
[25, 50, 75, 100])).cat.codes
df = pd.DataFrame({'orig':iris_df['sepal width'],
'hue':bins})
scalers = [('std', skpre.StandardScaler()),
('01' , skpre.MinMaxScaler()),
('-1,1', skpre.MinMaxScaler((-1,1)))]
for name, scaler in scalers:
# ugly: [[]] to keep 2D for sklearn
# reshape(-1) to go back to 1D for seaborn :(
df[name] = scaler.fit_transform(df[['orig']]).reshape(-1)
df = pd.melt(df, id_vars='hue', var_name='scale')
sns.swarmplot(x='scale', y='value', hue='hue', data=df).legend_.remove()
重定尺度最常见的动机是我们不希望任意的测量尺度影响我们的结果。例如,如果我们用米而不是纳米来测量一个人的身高,这个值会小得多——一米是一大堆纳米。但是这不应该真正影响测量中的基本信息。在非常不同的尺度上测量的值之间保持公平的最简单的方法是将它们重新调整到一个大致相同的尺度。另一个例子发生在同一模型中不同类型的测量。例如,家庭收入通常是数万美元,但每户家庭的汽车数量通常是个位数。从数字上看,这些值具有非常不同的权重。我们把它们放在一个共同的尺度上来抵消。当我们超越预测模型,开始进行统计或因果断言时,重新标度的一些好处变得更加突出。
10.4 离散化
当我们实现分段常数回归时,我们已经看到了离散化——将一系列连续值排序为一些有限的或离散的值的过程。在这里,我们必须根据输入值的存储桶选择一个输出值——一个线段。离散化也显示为决策树值分割的一部分: height > 5'7 "为真或假。有许多用于离散化数据的自动化方法;其中一些研究了要素值、理想值分割点和这些分割点对良好分类的价值之间的关系。在交叉验证中使用这些方法以防止对训练数据的过度拟合是至关重要的。你可以把足够高级的离散化策略想象成他们自己的微型学习者——想象一下如果他们能把正确的离散化到正确的分类桶中!现在,让我们考虑一些用 iris 数据进行离散化的手动方法。
iris_df = pd.DataFrame(iris.data, columns=iris.feature_names)
iris_df['species'] = iris.target_names[iris.target]
display(iris_df.iloc[[0,50,100]])
如果我们观察萼片长度的平滑图,我们会看到它是一个相当好的隆起。
plt.subplots(1,1,figsize=(4,3))
ax = sns.distplot(iris_df['sepal length'], hist=False, rug=True)
ax.set_ylabel("Approximate %");
一种简单的离散化方法是在平均值或中值处将值分为低和高。
# apply binary threshold to numeric with sklearn is tricky
column = iris_df[['sepal length']] # keep 2Dness because sk complains
col_mean = column.mean().values # and sk fails with Series/DF
both = column.copy()
both['&gt; Mean'] = skpre.binarize(column, col_mean).astype(np.bool)
print('Column Mean:', col_mean)
display(both.iloc[[0,50,100]])
Column Mean: [5.8433]
我们还可以使用一两分钟前展示过的pd.cut
函数进行同样的离散化。
sep_len_series = iris_df['sepal length']
breaks = [sep_len_series.mean(),
sep_len_series.max()]
# ugly to extract
print(pd.cut(sep_len_series, breaks).cat.codes[[0, 50, 100]])
0 -1
50 0
100 0
dtype: int8
但是,坦率地说,使用原始 np 会产生一个相当可读的解决方案,其中包含最少的幕后魔术。
# an easy button:
np.where(column &gt; column.mean(), True, False)[[0,50,100]]
array([[False],
[ True],
[ True]])
即使我们完成了计算,在中间破坏这样良好的数据有意义吗?两个非常相似的萼片长度值——平均值加一点和平均值减一点——被强制放入不同的桶中。大峰也意味着大多数值都在平均值附近的区域。我们希望他们在一起还是分开?只有我们的预测问题可以肯定地告诉我们。但是,就个人而言,我更愿意把中间的放在一起,把特别长的和特别短的放在它们自己的桶里。因此,我们会有短期、中期和长期,其中大多数例子都属于中期。
如果我们有领域知识,我们可能有其他的理由来选择某些分割点。例如,会计师可能会在税级阈值处引入分割点。在这里,有强大的信息可用,我们可能不需要担心过度拟合。我们总是可以交叉验证和比较。如果我们没有专家信息的来源,我们可能会尝试一系列的分割点可能性,并交叉验证它们,以确保我们不会过度拟合。
让我们实际一会儿。你应该使用哪种技术?现在,我要开始玩我的老把戏了。答案是视情况而定。你可能不是一个 NumPy 忍者,所以最后一个选项可能对你没有意义。但是如果您有更复杂的数字数据,您可能会通过使用 NumPy 获得一些其他的优势。熊猫和sklearn
选项之间有更多的权衡。Pandas 选项放在交叉验证循环中不会非常方便。sklearn
方法将使用管道直接插入交叉验证。但是,如果您需要进行数据探索和处理来得出分割点,请坚持使用 Pandas。
10.5 分类编码
到目前为止,我们一直在使用 iris 数据集的精确形式:我们从花朵的数字测量中预测物种。但是我们可以重新整理数据,做其他的学习任务。例如,假设我们想要根据其他特征(包括物种)来预测花瓣长度。现在,我们把物种作为已知的输入特征,花瓣长度作为未知的目标。数据看起来是这样的:
# close your eyes Francis, this is about to get ugly
# this pandas voodoo is simply to produce a labeled dataframe
# so you can *see* the learning problem I am describing in the text
new_iris_df = pd.DataFrame(iris_df, columns=['petal length',
'petal width',
'species'])
new_iris_df.columns = pd.MultiIndex([['input ftrs', 'target ftr'],
new_iris_df.columns],
[[1, 0, 0], [0,1,2]])
new_iris_df.sort_index(axis='columns', inplace=True)
display(new_iris_df.iloc[[0,50,100]])
物种没有直接的数字解释。没有一个定义好的顺序,我们可以用它来表示 setosa = 1 < versicolor = 2. We could use numbers to represent categories—think class 0, class 1, class 2. However, if we pass this column to linear regression, what would it mean for a species coefficient to be multiplied by these different values? We’d be treating the categories 为数值,而它们实际上只是类标识符。我们不希望将数值差 1 解释为预测花瓣长度的加减。
我们编码离散数据的一般技术称为编码分类变量。几分钟后,我们将在更广泛的背景下研究它。现在,让我们从一个让老派统计学家满意的有用技术开始:一键编码。它将具有多个值的单个列转换为具有一个且只有一个 on 值的多个列。示例的 on 值通常是二进制 1(或 True ),其他列值是 0(或 False)。以下是一次性编码的鸢尾物种:
# start with category numbers
print("Numerical categories:",
iris.target[[0, 50, 100]], sep='\n')
# produces sparse representation
sparse = skpre.OneHotEncoder().fit_transform(iris.target.reshape(-1,1))
# densify it
print("One-hot coding:",
sparse[[0,50,100]].todense(), sep="\n")
Numerical categories:
[0 1 2]
One-hot coding:
[[1\. 0\. 0.]
[0\. 1\. 0.]
[0\. 0\. 1.]]
这里有几个技术点值得一提。OneHotEncoder
需要数值输入。它不喜欢弦乐。它还需要一个 2D 输入—因此调用了reshape
。最后,如果我们一步到位,结果中会有很多很多的零。记住,在所有展开的列中,每个示例只有一个值是打开的。即使只有几个合法值的源列也会导致大量的零——除了一个选项之外,其他选项并没有在每个示例中使用。因此,sklearn
很聪明,它以一种压缩格式存储数据,这种格式很好地处理了稀疏性——这是一个技术术语,指含有大量零的数据。它不是到处记录值,而是只记录非零项,并假设其他所有项都为零。
有一些学习方法可以有效地处理稀疏数据;他们知道许多值是零,并且聪明地不做额外的工作。如果我们想以通常的、完整的形式查看数据,我们必须要求使数据变得密集。您可以想象,当我们填写稀疏表单时,我们有一个有点像瑞士奶酪的表:它有许多洞。我们必须用实际的零来填补这些漏洞——这些值被认为是零。这样我们就有了一个坚固的——密集的——表,到处都是条目。我们通过最后一行中的.todense()
调用来实现。
我们也可以用pandas
进行一键编码。一个好处是,我们可以要求它给一个热点列提供漂亮的标签。
# can use drop_first to get treatment coding
# can request sparse storage
encoded = pd.get_dummies(iris_df, prefix="is")
encoded.iloc[[0,50,100]]
我们可以用原始数据来娱乐和获利。我们可能希望将编码和原始物种值之间的关系可视化。这是:
# splicing dataframes together by merging
# recall `iris.target` is in terms of 0, 1, 2, not symbolic (setosa, etc).
encoded_species = pd.get_dummies(iris.target)
encoded_df = pd.merge(iris_df, encoded_species,
right_index=True, left_index=True)
encoded_df.iloc[[0,50,100]]
10.5.1 编码的另一种方式和遗漏截取的奇怪情况
这是实现一键编码的另一种方法。在统计领域,一键编码被称为处理或虚拟编码。有些细节我会绕着跳踢踏舞,但我会在这一章的结尾多留几条注释。patsy
是一个很好的系统,它允许我们以一种方便的方式指定一些特征工程和建模思想。这是我们马上要用到的一个长版本:
import patsy.contrasts as pc
levels = iris.target_names
coding = (pc.Treatment(reference=0)
.code_with_intercept(list(levels)))
print(coding)
ContrastMatrix(array([[1., 0., 0.],
[0., 1., 0.]
[0., 0., 1.]]),
['[setosa]', '[versicolor]', '[virginica]'])
我提出另一个选择的原因不是让你不知所措。实际上,我想继续讨论一些我们可以用patsy
完成的有用的特性工程任务,并加深你对分类编码含义的理解。现在,我声称这是一个很好的系统,可以做一些像一次性编码这样的事情。但是,大声哭出来,以前的细胞是可怕的。让我们按下简单按钮。
encoded = patsy.dmatrix('species-1',
iris_df,
return_type='dataframe')
display(encoded.iloc[[0,50,100]])
'species-1
中的-1 发生了什么?让我们看看当我们忽略它时会发生什么。
encoded = patsy.dmatrix('species',
iris_df,
return_type='dataframe')
display(encoded.iloc[[0,50,100]])
我们得到两个显式编码的特性,并得到一列名为 Intercept 的所有特性。顺便说一下,patsy
实际上为我们执行了+1 技巧,并将其命名为 Intercept。那么,为什么我们必须做-1
来得到简单的结果呢?为什么species
的dmatrix
给我们一列和——貌似!—忽略其中一个物种(没有针对 setosa 的列)?我们一会儿会回到这个话题。
Patsy 型号
让我们用手电筒照一下刚才发生的事情。我们正在构建设计矩阵— dmatrix
生物——有两个主要元素:(1)建模思想的一些规范,以及(2)我们希望通过该模型运行的数据。设计矩阵告诉我们如何从原始数据获得我们想要的数据形式,以通过建模过程的底层数字处理。绝对是范例时间。
我们可以指定我们想要从花瓣宽度和种类预测花瓣长度——我们对虹膜数据的回归扭曲。如果我们的列名有下划线(petal_length
)而不是空格(petal length
),那么规范将被写成(petal_length - petal_width + C(species. Treatment)'
。该规范要求运行线性回归,将波浪号~
的左侧作为目标,将右侧项作为输入特征。C()
表示我们希望在运行线性回归之前对species
进行编码。名称中有空格会使事情稍微复杂一些,但是我们马上会解决这个问题。
下面是我们可以用patsy
公式做的基本事情的快速参考:
tgt ~ ftr_1 + ftr_2 + ftr_3:
型号tgt
来自右手边的特征- 注意时髦的名字
tgt ~ ftr_1 + C(cat_ftr, Some_Coding):
模型tgt
上的ftr_1
和分类编码cat_ftr.
ftr_1
上的tgt ~ ftr_1 - 1:
型号没有截击。默认情况下,公式包含一个截距:我们必须手动删除它。我们也可以从 RHS 中移除特征:tgt ~ ftr_1 + ftr_2 - ftr_1M\
等价于 Mtgt ~ ftr_2.
这里有一些移除特征的有用案例。
现在,我想研究包含或不包含某些变量编码会发生什么。为了做到这一点,我们需要一些我们可以在头脑中处理的琐碎数据。我们开始吧:
pet_data = pd.DataFrame({'pet' :['cat', 'cat', 'dog'],
'cost':[20.0, 25.0, 40.0]})
pet_df = pd.get_dummies(pet_data)
display(pet_df)
在本例中,卡特彼勒成本为 20 英镑和 25 英镑。单身狗的例子成本为 40。快速记住平均猫成本是 22.50 英镑。
(貌似)无拦截模式
我们几乎从未具体研究过工厂机器上设置的旋钮值。让我们在这儿做那件事。在我们fit
之后,线性回归将选择特定的旋钮值,ws 或 m,b。在下面,你可能会注意到我在线性回归构造函数中加入了一个fit_intercept=False
。它有一个非常好的理由,我将在几分钟后回到它。它与默认的dmatrix
密切相关,默认的【】有一列全是 1,没有明确地编码所有三个物种。请记住,我们没有明确地适合一个b
项(常数或截距)。
def pretty_coeffs(sk_lr_model, ftr_names):
' helper to display sklearn results in a nice dataframe '
lr_coeffs = pd.DataFrame(sk_lr_model.coef_,
columns=ftr_names,
index=['Coeff'])
lr_coeffs['intercept'] = sk_lr_model.intercept_
return lr_coeffs
让我们做一点数据处理,让我们的建模步骤更愉快:
# massage
sk_tgt = pet_df['cost'].values.reshape(-1,1)
sk_ftrs = pet_df.drop('cost', axis='columns')
# build model
sk_model = (linear_model.LinearRegression(fit_intercept=False)
.fit(sk_ftrs, sk_tgt))
display(pretty_coeffs(sk_model, sk_ftrs.columns))
我们没有安装截距—这相当于将其值固定为零。对解释pet
条目的快速评论。两个特征值(对于pet_cat
和pet_dog
)中有且仅有一个不为零。基本上,我们选择其中一列,结果选择我们的成本。您可能还注意到,cat 值是两个 cat 案例的平均值;狗值就是单身狗值。对于这两者,我们已经将 0 和 1 的虚拟编码变成了可切换的权重——其中只有一个是开启的——以添加到我们的宠物护理成本模型中。
回到我的主要故事。这里有另一种方法来生成相同的模型和旋钮设置。
import statsmodels as sm
import statsmodels.formula.api as smf
# patsy formula that explicitly removes an intercept
formula = 'cost ~ pet - 1'
sm_model = smf.ols(formula, data=pet_data).fit()
display(pd.DataFrame(sm_model.params).T)
这两种方法得出了相同的系数——我们对此非常高兴。让我们回到丢失截击的问题。在sklearn
示例中,我省略了fit_intercept=False
。如果你开始摆弄这些patsy
公式,你会发现很难为物种和得到一个显式的三列伪编码,为截距得到一列全 1。我最后来回答:
- 为什么编码一个分类变量,默认情况下,似乎遗漏了一个变量值?
- 为什么默认公式包含截距?
10.5.1.3 具有明确截距的模型
让我们重新创建 sklearn 模型,这次使用截距:
sk_tgt = pet_df['cost'].values.reshape(-1,1)
sk_ftrs = pet_df.drop('cost', axis='columns')
sk_model = (linear_model.LinearRegression() # fit_intercept=True by default!
.fit(sk_ftrs, sk_tgt))
display(pretty_coeffs(sk_model, sk_ftrs.columns))
现在,让我们用patsy
和statsmodels
做同样的模型搭建。我们必须做一些诡计来说服statsmodels
(1)为宠物使用完全显式的一键编码,以及(2) 和使用全 1 的列。我们将这样做:(1) pet - 1
用猫和狗对宠物进行编码,以及(2)我们将使用一个人造的ones
列来强制拦截。
pet[cat] pet[dog] ones
10.5 Categorical Coding 339
pet_data_p1 = pet_data.copy() # don't muck the original data
pet_data_p1['ones'] = 1.0 # manual +1 trick
# remove coding intercept ..... add manual ones == add manual intercept
formula = 'cost ~ (pet - 1) + ones'
sm_model = smf.ols(formula, data=pet_data_p1).fit()
display(pd.DataFrame(sm_model.params).T)
好像有点不对劲,汤姆少校。系数不一样。让我们快速浏览一下这两个模型的预测:
# row-slicing is annoying, but have to get to single-D things
# and .flat gives a warning in the DF constructor
df = pd.DataFrame({'predicted_sk' : sk_model.predict(sk_ftrs)[:,0],display(df)
'predicted_sm' : sm_model.predict(pet_data_p1),
'actual' : sk_tgt[:,0]})
display(df)
然而预测是一样的。到底是怎么回事?
解开谜语
让我们看看当我们指定一个没有截距的 pet 公式时会发生什么。这是我们的数据,包括一栏:
display(pet_data_p1)
这些数据的编码——没有从分类编码中截取——给了我们。
print('pet - 1 coding')
print(patsy.dmatrix('pet - 1', data=pet_data_p1))
pet - 1 coding
[[1\. 0.]
[1\. 0.]
[0\. 1.]]
如果我们将所有编码创建的列加起来,我们可以验证每个示例只有一个“on”值:
# what happens when we add up the coding columns
print("column sum:")
full_coding = patsy.dmatrix('pet - 1',
data=pet_data_p1,
return_type='dataframe')
display(pd.DataFrame(full_coding.sum(axis='columns')))
column sum:
如果我们将包含两个 pet 列的完全显式编码的列相加,我们会得到一个全为 1 的列。此外,我们的两个模型——默认情况下sklearn
有fit_intercept=True
,而我们的statsmodels
有明确的 1 列——其中已经有了 1 列。所以,我们在数据中隐藏了一个冗余的 1 列。这种冗余正是为什么有截距的回归模型有两种不同但预测等价的答案。当我们移除截距但保留完整编码时,我们仍然具有来自编码列之和的类似截距的项。**
对于线性模型,有一些关于什么构成冗余的规则。如果某些列的线性组合等于其他列的线性组合,则存在冗余。那么,对于我们的线性回归系数,我们不能准确地得到一个且只有一个答案:有许多——无限个——同样正确的答案。我们可以在一个系数上加一点,在另一个系数上减一点,它们就会平衡。你会注意到,就预测而言,这对我们来说似乎不是什么大问题。在更大的画面中,冗余问题被称为共线性,当你超越预测的水平,开始进入统计和因果推理的领域时,它更令人担忧。正如我所提到的,我们在本书中将这些问题一笔带过。然而,这些问题正是为什么statsmodels
让你大费周章地包含完整编码和显式拦截。
10.6 关系和互动
特征构造非常强大。事实上,它是如此强大,它实际上可以取代我们通常在模型构建中执行的步骤。适当构造的特征可以模拟我们用模型预测时产生的目标。这里有两个例子:
- 在我们的分段常数回归示例中,最困难的步骤是确定每个输入值属于哪个区域或切片。这样做之后,我们只需选择适当的常数。这几乎就像使用带有复杂键的 Python 字典一样。困难的工作是生成密钥——查找几乎是微不足道的。如果我们将数据预处理到正确的箱中,我们的模型几乎没有什么可做的了。我们可以用一个稍微复杂的预处理步骤和一个琐碎的模型构建步骤来代替我们更复杂的模型构建过程。
- 要从线性回归过渡到多项式回归(使用曲线形状建模),我们可以花费大量精力定义一种自定义方法来将多项式拟合到数据,或者我们可以简单地创建多项式要素并将其传递给标准线性回归拟合器。
许多复杂的学习方法可以实现为(1)复杂的方法或(2)特征构造加基本方法。通常,后者的劳动强度较小。如果我们分离出特征工程,我们需要确保用评估独立方法的同样方式评估组合方法——通常是交叉验证。
手动特征构造
我认为特征工程可以非常强大,因为它可以消除学习的需要。足够强大的离散化和特征构造方法可以从本质上为我们解决学习问题。让我们停止挥臂,让那个想法更加明确。这里有一个经典的很麻烦的学习例子。我将为 xor 函数创建一个非常简单的示例表。xor 是一个布尔函数,只有当它的一个或另一个输入为真时才为真,而不是两个都为真。数据如下:
xor_data = [[0,0,0],
[0,1,1],
[1,0,1],
[1,1,0]]
xor_df = pd.DataFrame(xor_data,
columns=['x1','x2','tgt'])
display(xor_df)
如果我们试图用一个简单的线性分类器来模拟 xor,事情就不那么顺利了。我们在训练集上预测样本中的数据时遇到了问题——我们甚至还没有看到任何新的 T2 测试数据。
model = linear_model.LogisticRegression().fit(xor_df[['x1', 'x2']],
xor_df['tgt'])
model.predict(xor_df[['x1', 'x2']])
array([0, 0, 0, 0])
我们怎么会这么坏?好吧,让我们来看一个用输出颜色表示的数据值的图表。
fig, ax = plt.subplots(1,1,figsize=(2,2))
ax.scatter('x1', 'x2', data=xor_df, c='tgt')
ax.set_xlim(-1, 2)
ax.set_ylim(-1, 2);
从根本上说,不可能用一条线把这些点分开,只把它们放在类似的类中。至少,我们需要两条线来隔离一条对角线上的点和另一条对角线上的点。但是如果我们能创造一个巧妙的特征呢?
xor_df['new'] = (-1)**xor_df['x1'] * (-1)**xor_df['x2']
print(xor_df)
现在事情看起来相当不错:即使是一个超级简单的规则,xor_df['new'] < 0 == True,也能给出我们的目标。事情是这样的:
model = linear_model.LogisticRegression().fit(xor_df[['new']],
xor_df['tgt'])
model.predict(xor_df[['new']])
array([0, 1, 1, 0])
有时候,我们需要发明一个新的词汇——像new
这样构造的栏目——来让我们的学习系统学习。
互动
一种特定类型的构造特征是现有特征之间的相互作用。功能交互有两种主要方式:(1)通过像字典中的键一样一起工作来选择类或目标值,以及(2)通过基于它们的乘积(乘法)而不是它们的总和(加法)一起行动。第二是一种非常复杂的说法,即当我们将两个特征相乘时,我们在考虑它们相互作用的方式。多级交互可以包括越来越多的特征。
这里我们考虑数字特征之间的双向交互——所有数字特征对——与sklearn
:
# parameters:
# degree: degree of terms
# interaction_only: no x**2, only x*y (and x,y)
# include_bias: constant term
quad_inters = skpre.PolynomialFeatures(degree=2, # degree of terms
interaction_only=True, # no x**2, only x*y
include_bias=False) # constant term
subset = iris_df.loc[[0, 50, 100], ['sepal length', 'sepal width']]
new_terms = pd.DataFrame(quad_inters.fit_transform(subset),
index=[0, 50, 100])
new_terms.set_axis(['sep length', 'sep width', 'sep area'],
axis=1, inplace=True)
# note: creating the interaction *also*
# includes the base terms in the interaction
display(new_terms)
这种表示可能已经足够好了,特别是如果我们想让这些步骤成为sklearn
管道的一部分。然而,我们可以使用patsy
获得更精细的控制。
10.6.2.1 通过 Patsy 公式进行交互
现在,我们可以通过使用 patsy 公式获得重大胜利。Patsy 让我们指定与:
或*
的交互。不同的是,:
只包括两者之间的交互——sepal_width * sepal_length
——像skpre.PolynomialFeatures
中的 interaction_only=True。
design_df = patsy.dmatrix("Q('sepal length'):Q('sepal width') - 1",
data=iris_df.iloc[[0, 50, 100]],
return_type='dataframe')
design_df
如果我们使用 patsy *
来连接两个特性ftr_1 & ftr_2
,我们将得到三列:ftr_1
、ftr_2
和产品ftr_1 x ftr_2
。在两个分类特征之间,一个 patsy *
意味着我们取笛卡尔乘积——每个值的所有可能组合。让我们构建一个可能用到它的场景。
在我们讨论了萼片长度和宽度一段时间后,你可能会开始想,作为一种近似,我们可以将两者相乘得到一个萼片面积。实际上,我们正在讨论创建一个新的特征 s 萼片面积=萼片宽度×萼片长度。当从长轴和短轴计算时,我们可以通过诉诸矩形的面积或椭圆的近似面积来证明这一点。我们很乐意将宽度和长度这两个原始概念与一个更具表现力的概念联系起来。如果我们与一位植物学家交谈,他说以她的专家观点来看,是的,近似值足够有效和区域在确定物种方面更有用,我们可能会更高兴。这种方法是由背景知识驱动的——所以我们可能不需要费很大力气来交叉验证它。然而,我们会想要一个坚持测试集来确保我们不会在面积的价值上误导自己。不像中世纪的经院哲学家们满足于在没有证据的情况下争论和辩论,我们坚持用数据和评估来证明我们的主张。
让我们也将花区域的概念与离散化结合起来,找到大的区域。最后,我们将创建较小和较大的花瓣和萼片的组合。
# create some areas
sepal_area = iris_df['sepal length'] * iris_df['sepal width']
petal_area = iris_df['petal length'] * iris_df['petal width']
# discretize
iris_df['big_sepal'] = sepal_area &gt; sepal_area.median()
iris_df['big_petal'] = petal_area &gt; petal_area.median()
display(iris_df.iloc[[0,50,100]])
design_df = patsy.dmatrix("big_sepal:big_petal - 1",
data=iris_df.iloc[[0, 50, 100]],
return_type='dataframe')
# breaking up the long column names
display(design_df.iloc[:, :2])
display(design_df.iloc[:,2: ])
例 50 和例 100 都有大萼片和花瓣。例 0 有一个大萼片和一个小花瓣。
当我们在分类特征和数字特征之间创建交互时,我们实际上为我们考虑的每个类别的数字特征获得了一个权重:
# we (Q)uote sepal length because it has a space in the name
design_df = patsy.dmatrix("C(species,Treatment):Q('sepal length') - 1",
data=iris_df.iloc[[0, 50, 100]],
return_type='dataframe')
# breaking up the long column names
display(design_df.iloc[:,[0]])
display(design_df.iloc[:,[1]])
display(design_df.iloc[:,[2]])
如果我们深入研究数据,我们会看到这些值来自哪里——当萼片长度在该类别中时,列值正好是萼片长度的选定值。它是(1)物种的一键编码乘以 (2)萼片长度的基本乘法。
print(iris_df.iloc[[0, 50, 100]]['sepal length']
0 5.1000
50 7.0000
100 6.3000
Name: sepal length, dtype: float64
10.6.2.2 从 Patsy 到 sklearn
我们还可以看一个连接patsy
公式和sklearn
模型的快速例子。本质上,我们手工构建设计矩阵,即原始特征和我们用来学习参数的数据之间的映射,手工应用它,然后运行模型。
import statsmodels as sm
import statsmodels.formula.api as smf
# we can build a design matrix and send it to sklearn
design = "C(species,Treatment):petal_area"
design_matrix = patsy.dmatrix(design, data=iris_df)
# intercept is already in design matrix
lr = linear_model.LinearRegression(fit_intercept=False)
mod = lr.fit(design_matrix, iris_df['sepal width'])
print(mod.coef_)
[ 2.8378 1.402 -0.0034 0.0146]
# hey, we get the same results!
formula = "Q('sepal width') ~ C(species,Treatment):petal_area"
res1 = smf.ols(formula=formula, data=iris_df).fit()
print(res1.params)
Intercept 2.8378
C(species, Treatment)[setosa]:petal_area 1.4020
C(species, Treatment)[versicolor]:petal_area -0.0034
C(species, Treatment)[virginica]:petal_area 0.0146
dtype: float64
幸运的是,我们得到了相同的结果——这里面有一些舍入——无论我们做一些手动破解来将数据输入到sklearn
还是使用自包含的statsmodels
方法。
10.6.3 使用变压器添加功能
如果我们想要与 sklearn 更紧密地集成,我们可以使用FunctionTransformer
为独立函数定义特性转换,或者使用TransformerMixin
为类继承。如果从训练集到测试集,我们不需要记住或学习任何东西——如果转换是完全自包含的,比如取数据绝对值的对数——那么我们就不需要增加基于类的方法的复杂性。我们将开始重新创建一个干净的DataFrame
的初始区域特征。
iris_df = pd.DataFrame(iris.data, columns=iris.feature_names)
iris_df['species'] = iris.target_names[iris.target]
area_df = pd.DataFrame({"sepal_area" : iris_df['sepal length'] *
iris_df['sepal width'],
"petal_area" : iris_df['petal length'] *
iris_df['petal width']})
现在,如果我们只想与整个数据集的中值进行比较,而不是训练和测试差异,我们可以像下面这样快速地制作一个转换器:
def median_big_small(d):
return d &gt; np.median(d)
transformer = skpre.FunctionTransformer(median_big_small)
res = transformer.fit_transform(area_df)
print("Large areas as compared to median?")
print(res[[0, 50, 100]])
Large areas as compared to median?
[[ True False]
[ True False]
[ True True]]
如果我们想学习训练数据的中位数,然后将我们基于学习到的中位数的离散化应用于测试数据,我们需要更多一点的支持。我们必须计算训练数据的中位数,然后将这些中位数作为训练或测试数据的阈值。
from sklearn.base import TransformerMixin
class Median_Big_Small(TransformerMixin):
def __init__(self):
pass
def fit(self, ftrs, tgt=None):
self.medians = np.median(ftrs)
return self
def transform(self, ftrs, tgt=None):
return ftrs &gt; self.medians
使用模式与内置的 transformer 相同,并且非常类似于标准的学习模型。由于我们使用了一个train_test_split
,这里我们得到了随机选择的例子。
# training-testing split
training, testing = skms.train_test_split(area_df)
# create and run the transformer
transformer = Median_Big_Small()
train_xform = transformer.fit_transform(training)
test_xform = transformer.transform(testing)
# the dataframes survived!
print('train:')
display(train_xform[:3])
print('test:')
display(test_xform[ :3])
train:
test:
10.7 手动特征工程:操纵数据以获取乐趣和利润
在线性回归模型中,您可能会听到以下建议:
- 对输入要素进行变换主要是为了校正输入要素和目标之间的非线性关系。
- 变换目标值可纠正输入要素和目标之间未说明差异的问题。
我补充几点意见。校正非线性意味着特征和目标之间的基本关系不是线性的。线性回归模型正在特别是寻找一条最佳直线。超越好线的约束意味着解决线性回归的偏差。
无法解释的差异问题是我们的预测和现实之间的误差特征。这些都是本书中第 7.3.2 节的残差。我们可能会看到的两种模式是(1)系统行为,如输入 x 值越大,误差越大,以及(2)以非正态方式分布。非正态性意味着预测线上下的误差可能不平衡,或者误差不会迅速减小。
我们可以大胆地把这些翻译出来,给出处理建模问题的一般经验法则。
- 在我们的模型中,操纵输入主要是解决偏差。
- 操纵目标主要是解决噪声如何影响输入和目标之间的关系。这个噪声出现在关系中——它不是我们估计参数的变化。
操作输入空间
让我们通过观察第一条规则——校正非线性关系,或者更一般地说,偏差——如何发挥作用来使这些想法更加具体。
x = np.linspace(1,10,50)
n1 = np.random.normal(size=x.shape)
comparison = pd.DataFrame({"x" : x,
"d1" : 2*x+5 + n1,
"d2" : 2*x**2+5 + n1})
comparison['x'] = x
melted = pd.melt(comparison, id_vars=['x'])
两个数据列中的一个与另一个不同:
sns.lmplot(x='x', y='value',
data=melted, col='variable', ci=None,
size=3);
从下面看,为关联d1
和x
而构建的模型表现良好。它的残差看起来有点正常——尽管我们只使用了 50 个数据点,所以我们不会看到一个超级平滑的正常形状。来自d2
模型的残差与正常曲线没有明显的关系。
fig, axes = plt.subplots(1,2,figsize=(8,3))
for ax, variable in zip(axes, ['d1', 'd2']):
predicted = (smf.ols("{} ~ x".format(variable), data=comparison)
.fit()
.predict())
actual = comparison[variable]
sns.distplot(predicted - actual, norm_hist=True, rug=True, ax=ax)
ax.set_xlabel(variable)
ax.set_ylabel('residual')
fig.tight_layout();
在我们恐慌之前,让我们看看当我们试图将稍微不同版本的x
、x2 与d2
联系起来时会发生什么。我们还会看看残差。
magic = pd.DataFrame({"d2" : 2*x**2+5+n1,
"x_sq" : x**2})
melted = pd.melt(magic, id_vars=['x_sq'])
fig, (ax1, ax2) = plt.subplots(1,2,figsize=(8,3))
sns.regplot(x='x_sq', y='value',
data=melted, ci=None, ax=ax1)
predicted = (smf.ols("d2 ~ x_sq", data=magic)
.fit()
.predict())
actual = comparison['d2']
sns.distplot(predicted - actual, rug=True,
norm_hist = True, ax=ax2)
ax2.set_title('histogram')
ax2.set_xlim(-3,3)
ax2.set_ylim(0,.45)
ax2.set_ylabel('residual');
残差看起来很棒。 Et voilà !或者像英国人说的,“鲍勃是你的叔叔。”通过操纵特征,我们可以调整特征和目标之间不寻常的非线性关系。
操纵目标
我们可以做一个类似的练习,让我们清楚什么时候应该试图操纵目标。在这里,我们将为我们的关系注入截然不同的噪音:
x = np.linspace(1,10,50)
n1 = np.random.normal(size=x.shape)
n2 = .5*x*np.random.normal(size=x.shape)
comparison = pd.DataFrame({"x" : x,
"d1" : 2*x+5+n1,
"d2" : 2*x+5+n2})
comparison['x'] = x
melted = pd.melt(comparison, id_vars=['x'])
同样,其中一个与另一个不同:
sns.lmplot(x='x', y='value',
data=melted, col='variable', ci=None,
size=3);
右侧的图d2
似乎明显有问题。我没有评论我们是如何产生数据的——但是让我们关注我们看到的。误差——从点到线的垂直距离——随着x
的增加而增加。下面是d1
和d2
的残差直方图:
fig, axes = plt.subplots(1,2,figsize=(8,3))
for ax, variable in zip(axes, ['d1', 'd2']):
predicted = (smf.ols("{} ~ x".format(variable), data=comparison)
.fit()
.predict())
actual = comparison[variable]
sns.distplot(predicted - actual, norm_hist=True, rug=True, ax=ax)
ax.set_xlabel(variable)
ax.set_ylabel('residual')
fig.tight_layout();
再说一遍,我们尽量不要惊慌。相反,让我们试着通过取目标的对数来施展一点魔法:
magic = pd.DataFrame({"log_d2" : np.log(comparison['d2']),
"x" : x})
melted = pd.melt(magic, id_vars=['x'])
fig, (ax1, ax2) = plt.subplots(1,2,figsize=(8,3))
sns.regplot(x='x', y='value', data=melted, ci=None, ax=ax1)
predicted = (smf.ols("log_d2 ~ x", data=magic)
.fit()
.predict())
actual = magic['log_d2']
sns.distplot(predicted - actual, rug=True, ax=ax2)
ax2.set_title('histogram')
ax2.set_xlim(-.7, .7)
ax2.set_ylim(0,3)
ax2.set_ylabel('residual');
残差现在表现得相当好。这些例子有些做作;你不会总是从简单的转换中看到这种改进。但是它们很容易尝试——你可能会从中获得一些改进。
10.8 EOC 总结
我们以一种非常不同的方式增加了我们的工具箱。我们现在可以解决数据本身的问题。这些方法非常有用:不管我们使用什么样的学习方法,这些特征工程步骤都是必要的。然而,这些方法也有局限性。它们需要人工干预,我们需要小心不要过度拟合它们,它们只是随意地解释目标和特征之间的关系。当我们开始处理明显非表格的数据时,如图像和文本,这些方法也需要补充。
注释
sklearn
有一个标准化函数,其目的是使行总和为 1。这与我们一直在做的事情不同:我们一直在谈论列的规范化。
我们简要讨论了稀疏数据存储。可以编写一些学习方法来利用稀疏性:它们将知道未填充的值是零,并避免对这些条目进行不必要的数学运算。我还没有在sklearn
中找到一个方便的稀疏感知方法列表。你必须在文档中找到面包屑。
我们已经讨论了一键编码,也称为虚拟编码或治疗编码。还有其他编码分类变量的方法可以避免截距问题。这些方法被称为对比编码方案。他们不是依赖一对一,而是以一个值作为基线,并与其他值进行比较。通过采用隐式基线,他们没有我们上面讨论的共线性问题。
用谷歌快速搜索会得到关于patsy
和statsmodels
的文档:
- https://patsy.readthedocs.org/en/latest/quickstart.html
- http://statsmodels.sourceforge.net/devel/example_formulas.htmlhttp://statsmodels.sourceforge.net
您将在统计文献中找到大量关于数据转换(特征工程)的信息。它通常仅限于讨论线性回归。这里有几个例子:
- 数据转换来自【https://onlinecourses.science.psu.edu/stat501/node/318】T2。
- 第八章现实回归与方差分析在 R by 远方
- Shalizi 的第 2.2.4 节从初级角度进行高级数据分析
10.8.3 练习
- 当我们试图预测目标时,我们可能会以哪些方式将无意的关系引入我们的特征,从而给自己带来不适当的优势?换句话说,我们该如何处理那些在训练中可能有效,但在实践中却很失败的严重过度拟合的特征呢?
- 有哪些可能引导我们手动从数据集中选择特征的知识示例?在大型数据集中,我们可能会遇到许多不同的预测问题,从不同的特征集到不同的目标。根据目标的不同,我们可能会受到逻辑、法律、科学或其他因素的不同约束。要有创意!
- 研究基于一种方法的特征选择在用于其他方法的学习时是如何工作的。使用套索回归( L1 正则化)执行特征选择,然后使用不基于线性回归的东西建模,例如 k -NN-R 或决策树回归器。
- 假设您有多模态数据,也就是说,要素的值形成一个双峰(或更多峰)。将这些数据标准化后会发生什么?动手吧!您可以通过合并两个不同正态分布的结果来创建双峰值(比如,一个平均值为 5,另一个平均值为 10)。
- 我们对虹膜数据做了一些非常基本的离散化处理。你能做得更好吗?这里有一个提示:尝试构建一个决策树分类器,并查看它使用的分裂点。手动应用其中一些,然后尝试不同的分类器。
- 使用
mystery_df
(如下),对照其他每个特征绘制x
。现在,尝试取 x 的对数(np.log
),另一个变量,或者两者都取,然后把这些值用图形表示出来。您应该能够直观地评估线性回归是否适合这些图表。线性回归何时会成功?
x = np.linspace(1,8,100)
n1 = np.random.normal(size=x.shape)
n2 = x * np.random.normal(size=x.shape)
mystery = {'m1':5 + n1,
'm2':5 + n2,
'm3':x + n1,
'm4':x + n2,
'm5':np.log2(x) + n1,
'm6':np.log2(x) + n2,
'm7':np.exp2(x + n1),
'm8':np.exp2(x + n2)}
mystery_df = pd.DataFrame(mystery)
mystery_df['x'] = x
衡量数据科学团队的商业价值和成功
原文:https://www.dominodatalab.com/blog/measuring-data-science-business-value
这篇博文涵盖了帮助数据科学领导者确保他们团队的工作与商业价值保持一致的指标。
数据科学经理和高管,无论是来自技术部门还是经理部门,都在努力为他们的团队提供可见性,以及团队的工作如何与业务价值保持一致。很难主动管理您的团队以及他们与业务的互动。当你发现一个项目交付了一个不相关的发现,或者企业已经做出了决定,因为工作交付得不够快时,你通常已经太晚了。在这篇博文中,我提供了一些指标来帮助数据科学领导者确保他们团队的工作符合商业价值。这些指标是基于我从领导和建立数据科学团队中学到的东西以及从我的同事那里获得的经验。
为什么指标有帮助
正如任何其他部门使用运营指标来衡量其组织的效率和有效性一样,数据科学也需要这样做。销售团队使用漏斗指标来衡量他们的团队将潜在客户转化为成交客户的效率。工程团队使用 sprint burndown 和团队速度来衡量他们的团队在给定时间内完成工作的效率。监控领先指标使这些团队能够在错过收入数字或产品功能延迟之前快速调整。
对于数据科学团队来说,识别关键信息非常重要,例如当数据科学家花费宝贵的时间复制别人已经完成的东西时。或者在项目交付为“完成”之前,业务利益相关者没有得到反馈。领先指标是一个有用的工具,我用它来了解我的团队在整个数据科学生命周期中所做的工作。
数据科学生命周期的非传统指标
正如构建销售指标是为了衡量和跟踪销售漏斗的不同阶段一样,数据科学指标也应该衡量和跟踪数据科学生命周期的不同阶段。但与销售漏斗的线性流动不同,数据科学生命周期可以遵循非常非线性的路径。这意味着您不能使用传统的度量来跟踪从一个阶段到另一个阶段的转换。因此,了解您试图在团队中推动哪些行为以及这些行为如何映射到任何数据科学项目将经历的生命周期非常重要:
您可以使用这个生命周期作为一个框架来定义重要的接触点和要跟踪的活动。然后,根据我们团队的目标,制定可操作的衡量标准,使您能够尽早纠正错误,并学习改进您团队的运作方式。
三种类型的指标
为您的团队选择正确的 KPI 应该从明确团队的目标开始。根据我管理数据科学团队的经验,衡量数据科学组织的产出有三个主要目标:管理团队的生产力和可见性;管理个人的生产力和可见性;并报告团队对商业价值的贡献。
在团队层面管理生产力和可见性
管理您的数据科学团队的生产力和成功在很大程度上依赖于您对团队正在进行的项目的洞察力。这意味着了解项目在数据科学生命周期中所处的位置、一段时间内每个项目中正在进行的活动类型,以及团队成员和利益相关方之间的协作。您的 KPI 应该帮助您衡量正在产生的洞察力的 质量 和 比率 。
衡量正在产生的洞察力的质量
您需要有领先的指标来帮助您尽早发现问题,根据新学到的知识或不断变化的业务需求重新确定项目方向,或者根据反馈快速迭代。您团队的信誉取决于您为组织提供的工作的质量和有用性。以下是一些建议:
| | 公制 | 如何使用 |
| 质量 | 重用已有工作的项目数量 | 团队是否协作并重用现有的高质量工作?防止有人重新发明轮子。 |
| 团队成员对每个活动项目的审核次数 | 代码评审和反馈在你的团队中发生了吗?了解谁需要更多反馈,谁没有提供反馈。 |
| 利益相关者对每个活动项目进行的审核数量 | 在这个项目中有多少风险承担者进行了检查?尽早从业务部门获得更多信息,防止事情走向错误的方向。 |
在下面的例子中,您可以看到一个活动项目的列表、构建它们的现有父项目,以及对每个项目进行的审核的数量和不同类型。在这种情况下,当我看到新项目直邮目标没有从现有的父项目中分支出来时,我会主动调查为什么该项目没有重用现有的工作。或者,我可以看到在那个项目上没有发生涉众评审。这使我能够通过获得早期反馈,潜在地为数据科学家节省大量时间,同时确保他们利用我们已经完成的高质量工作。
衡量见解产生的速率
这些指标应该帮助您优化团队的工作方式,以便您更快地向企业交付成果。这意味着不要错过推动影响,因为业务已经向前发展了。或者,扩大你的影响范围,因为你能够更快地获得对业务的更多见解。以下是一些建议:
| | 公制 | 如何使用 |
| 息 | 按预期交付日期列出的项目数 | 你期望什么时候向企业交付工作或里程碑?确保你没有对你的团队承诺过多或过少。 |
| 未分配的项目数 | 企业正在等待的积压有多大?我们达到容量了吗?确保当你计划做重要的事情时,它还没有变得无关紧要。 |
| 生命周期每个阶段的数据科学家人数以及每个阶段的时间 | 我看到我的团队中有很多人停留在实验阶段吗?主动取消阻止处于某个阶段时间过长的项目。 |
在下面的例子中,您可以看到团队可能过度承诺在第 6/15 周的星期二交付工作。由此,我可以进一步深入了解工作是什么(例如,它只是一个里程碑检入还是一个最终产品),团队中的谁正在处理它,以及业务中的谁依赖于该工作,以便我可以有效地重新确定优先顺序并转移工作。我还可以看到在第 6/22 周交付很少,并找出是什么阻止我们在那一周拥有接触点或向业务交付迭代。
在个人层面管理生产力和可见性
如果个人工作效率不高,项目和数据科学团队的工作就不会成功。你不希望你的数据科学家走进密室,几个月不露面。管理团队的工作,了解每个团队成员在一段时间内所做的活动类型。这将使站立和状态更新更有成效,用更少的时间谈论正在做什么,用更多的时间解决如何解决问题的实质。这里有一些建议:
| | 公制 | 如何使用 |
| 团队状态 | 每个团队成员在一段时间内积极参与的项目数量 | 每个团队成员的产量是多少?随着时间的推移,产量趋势如何?知道谁需要更多的指导,如何让他们和团队其他成员一样做出贡献。 |
| 每位团队成员的新评论数量 | 谁与团队合作最多,并帮助提升质量标准?蔻驰:那些不为他人做出贡献或帮助他人的人。 |
| 每个团队成员新发布的工件数量 | 谁在为企业提供可交付成果?推动您的团队发布他们的工作,供利益相关者使用。 |
在这个例子中,我可以看到我的团队中每个人在过去一个月中参与的活动项目的数量。根据其他团队成员的评论历史,我还可以看到谁最积极地做出贡献并与他们合作。在团队中并排比较这些数字有助于我积极地管理生产力,并尽早解决潜在的问题。例如,Mac 可能没有很多活跃的项目,但他对团队的贡献非常大。另一方面,John Joo 对团队和项目工作的贡献很小,所以这将是一个深入了解情况的机会。
报告团队工作与业务目标的一致性
数据科学领导者最重要的工作之一是报告数据科学团队为企业带来的价值。衡量团队工作的投资回报率非常困难。第一步是了解您的团队已经发布的哪些工件正被业务中的不同涉众积极使用。除了衡量回报,提供团队资源使用的可见性也同样重要。这些类型的测量将帮助您向高层领导提供有意义的更新,展示您的团队为企业带来的价值,并更好地帮助您的 CIO/ DevOps 支持您的团队。以下是一些建议:
| | 公制 | 如何使用 |
| 向领导汇报 | #按部门或业务线发布的工件 | 你对整个企业的贡献有多大?谁从您团队的工作中受益? |
| 与项目相关的成功指标/KPI 的变动 | 项目影响的 KPI 的基线测量与 KPI 中的预期/实际提升 |
| 每天的资源使用和成本 | 谁消耗的资源最多?什么商业项目最贵?将成本归因于用户或团队,以实施成本控制策略。 |
在这个例子中,我可以通过跟踪我的团队消耗的资源、团队中谁消耗的最多,以及业务的哪些项目推动了这些成本,来提高我的 DevOps 团队的透明度。这些信息可以帮助他们实施智能成本控制策略,并更准确地进行预测。
数据科学领导者面临越来越大的压力,需要提供证据证明他们团队的工作提供了商业价值。是的,很难,但不是不可能。这篇博文中涵盖的指标是一个很好的起点,可以用来衡量您的数据科学团队的效率以及它对组织的贡献。跟踪团队的生产力、可见性以及报告工作的价值是耗时的,但是收益是巨大的。
大型组织的 5 种最佳实践
原文:https://www.dominodatalab.com/blog/mlops-best-practices-for-large-organizations
机器学习操作(MLOps)不仅仅是人工智能(AI)和机器学习(ML)社区的最新流行语。许多公司意识到他们需要一套实践来有效地建立模型并投入生产,而 MLOps 正好做到了这一点。
MLOps 在整个 数据科学生命周期 中,简化、标准化和自动化 ML 模型的开发和部署,包括 ML 模型的部署后监控和维护。
目前,数据科学家的组织中有几款 工具支持 MLOps 。然而 由于与模型开发和部署相关的技术挑战以及高层组织挑战,87%的机器学习模型从未投入生产 。 如果你想在你的 ML 项目中取得成功,你需要整合 MLOps 最佳实践来帮助你快速高效地前进。
在本文中,您将了解 MLOps 团队的五种最佳实践,以及知名组织使用的 MLOps 实践示例。
为什么您应该采用 MLOps 最佳实践?
将一个 ML 模型从构思到部署和监控是一个复杂而耗时的过程。此外,当组织试图 扩展数据科学 时,这种复杂性会迅速增加。如果没有 MLOps 实践和支持基础架构,组织将被迫手动开发、验证、部署、监控和管理模型。这是一项大规模的工作,涉及多个团队、涉众和技能集,并且经常陷入困境,因为每个模型都是根据用例以不同的方式创建和部署的。
MLOps 创建了由技术支持的标准实践,简化了数据科学生命周期中的步骤。没有 MLOps 需要几个月才能完成的任务可以在几天内完成。
一个关键要素是自动监控模型,以确保它们继续按预期执行或快速得到补救。最终结果是生产中的模型更加准确、健壮和可靠。
MLOps 团队的最佳实践
实现数据科学和机器学习的全部承诺是复杂的,并伴随着许多挑战。
以下列出的 MLOps 最佳实践可通过支持自动化和减少在生产中管理、开发、部署和监控 ML 模型所花费的时间来帮助缓解挑战。
数据集验证
数据验证是构建高质量 ML 模型的关键第一步。为了改进 ML 模型的预测,验证数据集以及训练模型以生成值并提供更好的结果是很重要的。从长远来看,检测数据集中的错误是至关重要的,并且直接对 ML 模型的性能负责。
在实践中,您可以从识别重复项、处理缺失值、过滤数据和异常并清理它开始。这样做提高了 ML 模型 的 精度,减少了整体花费的时间。。
当数据集变得非常大和复杂,具有不同的来源和格式时,验证数据集的最大挑战就出现了。
自动化数据验证确保 ML 系统的整体性能不会受到负面影响。例如,TensorFlow 有助于在 规模下进行详细的 数据验证。
促进协作文化
推动 ML 创新突破的创意来自自发的互动和非线性的工作流程。团队在开发模型时各自为政,进而面临效率低下的问题,包括同事之间的重复工作、浪费时间搜索过去的脚本/硬件配置,以及启动时间短。
通过消除 MLOps 流程中的协作障碍,团队可以同步工作,同时管理层可以监督项目阻碍因素。拥有一个集中的中心,无论 ML 使用什么工具或语言,都可以轻松地共享工作、协作项目和共享上下文,从而合成知识并提高模型速度。但这不会一蹴而就。它依赖于培养一种协作流程的文化以及使能技术。确保您的数据科学家融入到您的业务中,并交流来自不同领域的想法,这将使全球团队能够采用有益的实践,而这些实践是他们原本不会意识到的。
在实践中,全球最大的保险公司之一 SCOR 通过他们的数据科学卓越中心开发了一种协作文化,这使得客户至上模式的开发只需通常所需时间的一小部分。
应用程序监控
ML 模型依赖于干净和一致的数据,当输入数据集容易出错或偏离其训练数据的特征时,将无法做出准确的预测。因此,在采用 MLOps 时,监控管道是重要的一步。
更进一步,自动化连续监控(CM) 可以给你在生产中发布模型所需的信心,同时确保模型性能降级被快速捕获和补救。s .根据用例,客户或员工可以实时利用 ML 模型的输出,以便快速做出决策。因此,还需要监控操作指标,如延迟、停机时间和响应时间。
例如,如果网站上有一个巨大的销售,而 ML 提供了不相关的推荐,那么将用户的搜索查询转化为购买的成功率就会降低,并影响整个业务。部署后的数据审计和模型性能监控有助于运营顺畅的 ML 管道,从而减少人工干预的需求。
在现实世界中,企业公司部署这种策略的一个例子是 DoorDash 的监控框架,用于收集洞察和统计数据, 生成要监控的指标 。
再现性
ML 中的再现性是一项具有挑战性的任务,需要跟踪模型工件,如代码、数据、算法、包和环境配置。众所周知,许多数据科学家在 Jupyter 笔记本上手动开始模型开发,手动跟踪版本。这种方法通常缺乏对精确模型工件的文档化,并且使得它不可能在另一个系统上重现。
为了容易地再现模型,需要有一个中央存储库来捕获所有的工件及其版本。关键是要能够旋转出一个精确的复制品,这个模型将提供完全相同的结果。虽然这对于一些建模项目来说是可能的,但是如果没有合适的技术来简化这些细节,随着项目数量的增加,这就变得不可能了。无法重现模型使得数据科学家更难展示模型如何传递输出,验证团队也更难重现结果。这也使得遵守法规要求变得困难。此外,如果一个不同的团队不得不接手一个模型的工作,或者想要将它作为工作的起点,那么快速地重新创建工作可以确保工作不会被浪费。
Airbnb 使用一个名为 ML Automator 的内置框架,帮助实现可复制的模型。
实验跟踪
通常,数据科学团队会同时为各种业务用例开发多个模型。在确定和验证用于生产的候选模型之前,要进行大量的实验。对脚本、数据集、模型、模型架构、超参数值、不同实验及其结果的各种组合进行跟踪和版本控制,是跟踪模型中发生的事情以及生产中应该使用哪个模型的核心要求。构建可重复的 ML 模型。
有效管理数据集和实验是一项基本要求,可以由 MLOps 团队使用各种工具有效协调,如Domino Enterprise MLOps Platform。
结论
对大多数公司来说,投资 MLOps 是必要的。它可以使模型高效地投入生产,并确保它们继续可靠地运行。MLOps 帮助各种规模的组织简化和自动化其数据科学生命周期的流程,并解决大型复杂数据集、模型、管道和基础架构的可扩展性问题。
采用 MLOps 的诸多好处中,提高生产率、可靠性和更快地部署 ML 模型只是其中的一部分。实施前面提到的最佳实践将有助于组织从 ML 模型中获得更多的投资回报。
如果您正在寻找企业级 MLOps 平台,请查看 Domino 企业 MLOps 平台 。它是领先的 MLOps 解决方案,帮助 J & J 和 Lockheed Martin 等许多大型企业解决可伸缩性问题,并通过提供 ML 工具、基础设施、可审计性和治理来加速开发和部署——所有这些都具有集成的安全性。
MLOps vs DevOps:有什么区别?
机器学习操作(machine Learning Operations)(MLOps)是一个在过去十年中变得流行的术语,通常用于描述一系列旨在可靠、高效地在生产中部署和维护机器学习(ML)模型的实践。
然而,这个定义一次又一次地被证明是过于狭隘的,因为它忽略了数据科学生命周期的关键方面,包括 ML 模型的管理和开发。
面对当今的业务挑战,模型驱动的业务应该以采用企业 MLOps 为目标。我们将企业 MLOps 定义为“大规模端到端数据科学生命周期的流程系统。它为数据科学家、工程师和其他 It 专业人员提供了一个场所,使他们能够在机器学习(ML)模型的开发、部署、监控和持续管理方面与支持技术高效地合作。它允许组织在整个组织内快速高效地扩展数据科学和 MLOps 实践,而不会牺牲安全性或质量。”
但是,值得注意的是,只有在学习了另一个学科:开发运营(DevOps)的成功和最佳实践之后,这种对 MLOps 的整体看法才是可能的。
顾名思义,DevOps 是软件开发(Dev)和运营(Ops)的结合,旨在加快应用和服务的开发周期。DevOps 引入的最重要的变化是摆脱孤岛,促进软件开发和 IT 团队之间的协作,以及实施最佳实践和工具,以实现利益相关者之间的流程自动化和集成的目标。
虽然 DevOps 和 MLOps 的目标相似,但它们并不相同。本文将探讨 MLOps 和 DevOps 之间的差异。
为什么是 MLOps
ML 模型是由数据科学家构建的。然而,模型开发只是组成企业 ML 生产工作流程的一小部分。
为了操作 ML 模型并使模型为生产做好准备,数据科学家需要与其他专业人员密切合作 ,包括数据工程师、ML 工程师以及软件开发人员。然而,在不同的职能部门之间建立有效的沟通和协作是非常具有挑战性的。每个角色都有独特的职责。例如,数据科学家开发 ML 模型,ML 工程师部署这些模型。
任务的性质也不同。例如,处理数据比软件开发更具有研究性。有效的协作是具有挑战性的,沟通不畅会导致最终产品交付的重大延误。
因此,MLOps 可以解释为一系列技术和最佳实践,有助于大规模管理、开发、部署和监控数据科学模型。Enterprise MLOps 采用这些相同的原则,并将其应用于大规模生产环境,这些环境的模型更依赖于安全、治理和合规性系统。
MLOps 和 DevOps 之间的区别
MLOps 和 DevOps 之间有几个主要区别,包括:
数据科学模型是概率性的,而不是确定性的
ML 模型产生概率预测。这意味着它们的结果可能因输入数据和底层算法及架构而异。如果用于训练模型的环境发生变化,模型性能会迅速降低。例如,在新冠肺炎疫情期间,当输入数据的性质发生剧烈变化时,大多数 ML 模型的性能都会受到影响。
软件系统是确定性的,并且将以相同的方式执行,直到底层代码被改变,例如在升级期间。
数据科学的变化率更高
DevOps 允许您通过一套标准的实践和过程来开发和管理复杂的软件产品。数据科学产品和 ML 产品也是软件。然而,它们很难管理,因为除了代码之外,它们还涉及数据和模型。
您可以将 ML 模型视为一种数学表达式或算法,经过训练可以识别所提供数据中的特定模式,并根据这些模式生成预测。使用 ML 模型的挑战在于其开发所必需的活动部分,例如数据集、代码、模型、超参数、管道、配置文件、部署设置和模型性能指标等等。这就是为什么 MLOps 是必要的,模型不仅仅是软件,而且需要不同的策略来进行开发、监控和大规模部署。
不同的责任
MLOps 源于 DevOps。但是,每个人的责任不同。
DevOps 的职责包括以下内容:
- 持续集成,持续部署(CI/CD): CI/CD 是指将软件开发的不同阶段自动化的过程,包括构建、测试和部署。它允许您的团队不断地修复错误、实现新特性,并将代码交付到产品中,这样您就可以快速高效地交付软件。
- 正常运行时间: 这是指您的服务器保持可用的总时间,是一个通用的基础设施可靠性指标。DevOps 专注于维持高正常运行时间,以确保软件的高可用性。它帮助企业方便地运营关键业务,而不会面临重大服务中断。
- 监控/记录: 监控让您可以分析应用程序在整个软件生命周期中的性能。它还允许您有效地分析基础设施的稳定性,并涉及几个过程,包括日志记录、警报和跟踪。日志记录提供了关于关键组件的数据。您的团队可以利用这些信息来改进软件。相比之下,预警有助于您提前发现问题。它包含帮助您快速解决问题的调试信息。跟踪提供性能和行为信息洞察。您可以使用这些信息来增强生产应用的稳定性和可伸缩性。
相比之下,MLOps 的职责包括以下内容:
- 管理阶段。 这个阶段围绕着识别要解决的问题,定义预期要获得的结果,建立项目需求,以及分配角色和工作优先级。一旦模型被部署到生产中,在监控阶段获得的结果将被审查,以评估所获得的成功程度。此审查的成功和错误可用于改进当前项目和未来项目。换句话说,这一阶段包括以下方面:
- Project management: Access control of resources such as information, snapshot of central repository, status tracking, and more.
- Enterprise-wide knowledge management: It is very important to improve efficiency by reusing key knowledge. Domino Knowledge Center is a good example of this type of central knowledge base.
- Technical resource governance: includes cost tracking capability, role-based information access rights, tools and computing resource management.
- 发育阶段。 在此阶段,数据科学家基于各种不同的建模技术构建和评估各种模型。这意味着在开发阶段,数据科学家可以使用诸如 Domino 的数据科学工作台之类的环境来试验和执行 R & D,在那里他们可以轻松地访问数据、计算资源、Jupyter 或 RStudio 之类的工具、库、代码版本控制、作业调度等等。
- 部署阶段。 一旦一个模型被证明是成功的,它就可以被部署到生产中,并通过帮助业务流程决策来交付价值。为此,这一阶段涉及的方面包括:
- Flexible hosting of allows data scientists to freely deploy licensed model APIs, web applications and other data products to various hosting infrastructures quickly and efficiently.
- Packaging the model in a container is convenient for the external system to consume on a large scale.
- A data pipeline that supports the ingestion, arrangement and management of the data.
- 监视阶段。 这是负责测量模型性能的阶段,从而检查它是否如预期的那样运行。换句话说,它评估模型是否向业务交付了预期的价值。理想情况下,此阶段为 MLOps 团队提供的功能包括:
- Verify that the pipeline is allowed to pass the CI/CD principle.
- Testing and deploying scoring pipeline. These tools are helpful for A/B testing of model versions in production and tracking the results to inform business decisions.
- Model library, which collects all model APIs and other assets in order to know their health, usage, history and so on. It can be evaluated. Tools like Domino's integrated model monitoring can comprehensively monitor all models of an organization immediately after deployment, and can also proactively detect any problems and alert you.
- A mechanism that uses the history and context of the original model to help retrain and rebuild the model.
MLOps 和 DevOps:职责重叠
虽然 MLOps 和 DevOps 有所不同,但它们也有一些重叠的职责:
- 这两个学科广泛地使用版本控制系统来跟踪对每个工件的变更。
- DevOps 和 MLOps 大量使用监控来检测问题、测量性能,并对它们各自的工件执行优化。
- 两者都使用 CI/CD 工具,尽管在 DevOps 中,这些工具旨在自动化应用程序的创建。另一方面,在 MLOps 中,它们被用来建立和训练 ML 模型。
- DevOps 和 MLOps 鼓励持续改进各自的流程。同样,DevOps 和 MLOps 促进不同学科之间的协作和集成,以实现共同的目标。
- 这两个规程都需要所有涉众的深度承诺,以在整个组织中实施它们的原则和最佳实践
包扎
在本文中,您了解了 MLOps 团队的职责与 DevOps 团队的职责有何不同,以及它们之间的重叠之处。数据科学团队需要高水平的资源和灵活的基础架构,而 MLOps 团队提供并维护这些资源。
MLOps 是成功的关键。它允许你通过克服约束来实现你的目标,包括有限的预算和资源。此外,MLOps 还能帮助您提高敏捷性和速度,从而更好地适应模型。
MNIST 扩展:新增 50,000 个样品
原文:https://www.dominodatalab.com/blog/mnist-expanded-50000-new-samples-added
这篇文章提供了关于在 MNIST 数据集中重新发现 50,000 个样本的概要。
MNIST:过度拟合的潜在危险
最近, Chhavi Yadav (NYU)和 Leon Bottou (脸书 AI Research 和 NYU)在他们的论文《悬案:丢失的 MNIST 数字》中指出,他们如何重建 MNIST (修改后的美国国家标准与技术研究所)数据集,并向测试集添加 50,000 个样本,总共 60,000 个样本。20 多年来,许多数据科学家和研究人员一直使用包含 10,000 个样本的 MNIST 测试集来训练和测试模型。然而,行业意识到 MNIST(和其他流行数据集)的流行和使用也可能增加过度拟合的潜在危险。这导致研究人员通过重建数据集、测量准确性,然后分享他们的过程来寻找解决日益增长的过度拟合危险的方法。共享过程增加了可再现性的可能性,并在整个行业内建立现有的工作。
例如,在 Yadav 和 Bottou 的论文中,他们指出
“数百份出版物报道了相同测试集[10,000 个样本]上越来越好的性能。他们是否对测试集进行了过度调整?我们能相信从这个数据集中得出的任何新结论吗?”....以及“5 万份样本是如何丢失的”
MNIST 重建步骤
为了解决这些关于过度拟合的潜在危险的问题,Yadav 和 Bottou 重建了 MNIST 数据集。当论文深入到关于过程的细节时,github 上的自述文件提供了他们采取的步骤的摘要:
“1。根据在介绍 MNIST 数据集的【独立】论文中找到的信息,从第一重建算法开始。
2。使用匈牙利算法找到 MNIST 训练数字和我们重建的训练数字之间的最佳成对匹配。直观地检查最差的匹配,试图理解 MNIST 的作者可以做什么不同的事情来证明这些差异,同时不改变现有的接近匹配。
3。尝试重建算法的新变体,将它们的输出与 MNIST 训练集中它们的最佳对应物进行匹配,并重复该过程。"
这种过程共享有助于支持研究的可重复性,并有助于推动行业向前发展。
找到的 MNIST 数字
通过这项工作,Yadav 和 Bottou 重新发现了丢失的 50,000 个样本
“本着与【Recht et al .】、 2018 、 2019 相同的精神,5 万个丢失的 MNIST 测试数字的重新发现为量化官方 MNIST 测试集在四分之一世纪的实验研究中的退化提供了一个机会。”
他们也能够
“跟踪每个 MNIST 数字到其 NIST 源图像和相关元数据”...“这些新的测试样本使我们能够精确地调查标准测试集上报告的结果如何受到长时间重复实验的影响。我们的结果证实了 Recht 等人[ 2018 , 2019 ]观察到的趋势,尽管是在不同的数据集上,并且是在更加可控的设置中。所有这些结果本质上表明“测试集腐烂”问题是存在的,但远没有人们担心的那么严重。虽然重复使用相同测试样本的做法会影响绝对性能数字,但它也提供了配对优势,有助于长期的模型选择。”
然而,潜在影响仍在继续。Yadav 和 Battou 的工作也在 Yann LeCun 的 twitter 上分享。
MNIST 重生了,恢复了,扩张了。
现在有了额外的 50,000 个训练样本。如果你多次使用原始的 MNIST 测试集,你的模型很可能会超出测试集。是时候用这些额外的样本来测试它们了。https://t.co/l7QA1u94jF
— Yann LeCun (@ylecun) May 29, 2019
由 Kubernetes 支持的模型部署
原文:https://www.dominodatalab.com/blog/model-deployment-kubernetes
在本文中,我们将解释如何使用 Kubernetes 来支持数据科学家将预测模型部署为生产级 API。
背景
Domino 允许用户将 R 或 Python 模型作为 REST APIs 发布,因此他们可以轻松地将数据科学项目集成到现有的应用程序和业务流程中,而无需工程师或 devops 资源的参与。我们称这种 模式部署 。
我们从 2015 年就有这个功能了。第一个版本是一个更简单的特性,为 Domino 中托管的 R 和 Python 模型创建 API 端点,允许 web 服务使用它们。
这是一个在我们的许多小用户和初创用户中很受欢迎的功能,比如 8tracks,他们使用它将他们的预测模型与面向用户的应用程序集成在一起,而不需要从 R 或 Python 移植这些模型。
然而,这个版本重用了我们为在 Domino 中运行模型而构建的基础设施的大部分。虽然一次运行可能持续几个小时,但一个 API 端点可能会启动并运行数周,如果不是月。此外,该基础设施并不支持水平可伸缩性,这使得确保每个 API 端点在负载下保持响应变得非常困难。
随着越来越多的企业用户开始使用 Domino,对更健壮的模型部署功能的需求迅速增长。这时,我们抓住机会,用 Kubernetes 彻底重建了它。
使用 Kubernetes 重建模型部署
作为 Domino 2.0 发布的一部分,我们着手完全重新设计 API 端点功能,以更低的延迟支持大规模用例,同时还添加了更高级的功能,如 A/B 测试模型变体。
Kubernetes 是一个用于自动化部署、扩展和管理容器化应用的开源系统,这是一个自然的选择,因为它允许我们在共享基础设施上独立启动我们的每个模型,并根据需要单独扩展它们。
体系结构
模型由取自 Domino 项目的所有代码和数据组成,并结合了一个公开调用用户代码的 web 服务的工具。每个模型都被构建到 Docker 映像中,这确保了模型被打包在一起并被版本化。
一旦构建了模型版本,就可以使用 Kubernetes 部署和服务将其部署到 Kubernetes 上。该部署使我们能够确保负责运行模型的每个 Kubernetes 单元保持健康,旋转新单元以替换不健康的单元,并使我们能够轻松地扩展和缩减。服务是公开模型的东西。
使用入口资源将模型暴露在 Kubernetes 之外。这允许我们使用不同的路径访问同一个模型的不同版本。
然而,入口资源本身仅仅充当路由表。为了确保这些服务被公开,我们使用 Traefik 作为入口控制器。Traefik 是一个类似于 nginx 的反向代理,但是为 Kubernetes 提供第一方支持。这确保了对我们的入口资源的任何更新迅速得到反映。
最后,创建一个弹性贷款平衡器 (ELB)来确保模型可以从内部网络外部访问。
这种架构的早期版本没有使用 Kubernetes 或 Traefik 内部的入口。相反,我们使用 Nginx 作为服务,通过配置映射提供动态加载的配置文件。这作为概念验证效果很好,但是有两个主要问题:
- 我们所有的路由都依赖于一个单一的配置文件。
- 配置更新和 Nginx 刷新之间的延迟非常慢,这让人感觉系统中什么都没发生。
入口资源允许我们让每个模型拥有自己的路由,而 Traefik 使用 Kubernetes 观察器(通知您集群发生的不同变化)能够在 Kubernetes 集群上发生相关事件时进行自我刷新。
我们遇到的另一个挑战是找到一种方法来保持 Kubernetes 和我们的数据库之间的模型信息同步和重复数据删除。
最初,我们将关于部署的元数据存储在数据库中。我们自己使用 Kubernetes Watchers 来保持这些信息是最新的,但是保持这些信息同步的逻辑是复杂的。
我们开始更自由地使用 Kubernetes 注释和标签,将大部分元数据转移到 Kubernetes 本身,这允许我们最终确保关于特定模型部署的所有信息都保存在一个地方。
为了避免过于频繁地调用 Kubernetes 来检索这些元数据,我们将这些数据保存在缓存中,并通过 Kubernetes watcher 进程进行更新。这个过程在 Kubernetes 上运行,以确保在 Domino 应用程序维护期间不会丢失来自 Kubernetes 的消息。
为了让用户了解模型的当前状态,我们构建了一个系统来异步监控我们的部署状态。这是由一组 Kubernetes 观察器提供的,它为我们提供了 Kubernetes 部署的状态转换的原始事件流。
最后,为了使这个流更持久(错过的消息将永远丢失),我们使用 RabbitMQ 将其重定向到消息总线。我们还在内部使用 RabbitMQ 来支持我们的系统,在我们的模型部署特性中管理各种长时间运行的用户操作。
结果
与最初的 API 端点相比,新的模型部署架构允许我们以更快的速度执行模型,这使得它非常适合生产使用。我们用 R 和 Python 对流行的机器学习模型进行了基准测试,发现<每分钟处理 6000 个请求的延迟为 50ms。
(请注意,性能基于内部测试,并不代表性能保证。模型延迟取决于许多因素,如外部服务依赖性、网络拓扑和硬件配置。)
使用 Kubernetes 还允许我们为部署的模型提供 A/B 测试和版本控制功能。例如,数据科学家可以控制在生产中使用哪个模型版本,这意味着他们可以测试同一模型的不同版本,并且只在某个版本准备就绪时才将其提升到生产中。
最后但同样重要的是,这种架构的另一个好处是增加了可靠性;因为这个特性与运行执行是分离的,所以部署的模型对 Domino 平台本身发生的问题更有弹性。
模型评估
这份多米诺数据科学领域笔记提供了 Alice Zheng 的报告“评估机器学习模型”的一些亮点,包括监督学习模型的评估指标和离线评估机制。全面深入的报告还涵盖了离线与在线评估机制、超参数调整和潜在的 A/B 测试缺陷可供下载。作为报告补充的精选幻灯片也可供使用。
为什么模型评估很重要
数据科学家做模型。我们经常会听到数据科学家讨论他们如何负责建立一个模型作为产品或者建立一系列相互依赖的影响商业战略的 T2 模型。机器学习模型开发的一个基本且具有挑战性的方面是评估其性能。与假设数据分布保持不变的统计模型不同,机器学习模型中的数据分布可能会随时间漂移。评估模型和检测分布漂移使人们能够识别何时需要重新训练机器学习模型。在 Alice Zheng 的“评估机器学习模型”报告中,Zheng 主张在任何项目开始时考虑模型评估,因为它将有助于回答诸如“我如何衡量这个项目的成功?”并避免“在好的度量是模糊的或不可行的情况下,在不完善的项目上工作”。
监督学习模型的评价指标
郑指出“开发一个机器学习模型有多个阶段…..因此,我们需要在多个地方对模型进行评估”。郑主张在原型阶段,或“我们尝试不同的模型以找到最好的一个(模型选择)”时考虑模型评估。郑还指出,“评估指标与机器学习任务相关联”,“任务有不同的指标”。郑在报告中涉及的一些评估指标包括监督学习的分类、回归和排名。郑还提到要考虑的两个包包括 R 的度量包和 scikit-learn 的模型评估。
分类
关于分类,郑提到,用于测量分类性能的最流行的度量包括准确度、混淆矩阵、对数损失和 AUC(曲线下面积)。虽然准确性“衡量分类器做出正确预测的频率”,因为它是“正确预测的数量与预测的总数(测试集中的数据点数量)之间的比率”,但混淆矩阵(或混淆表)显示了每个类别的正确和错误分类的更详细的细分。郑指出,当想要了解类之间的区别时,使用混淆矩阵是有用的,特别是当“两个类的错误分类的成本可能不同,或者一个类的测试数据可能比另一个多得多”时。“例如,在癌症诊断中做出假阳性或假阴性的后果是不同的。
至于对数损失(对数损失),郑指出,“如果分类器的原始输出是数字概率,而不是 0 或 1 的类别标签,则可以使用对数损失。概率可以被理解为信心的衡量标准…..因为它是一个“软”的准确性度量,包含了概率置信度的思想。至于 AUC,郑将其描述为“一种将 ROC 曲线总结成一个数字的方法,这样它就可以容易地和自动地进行比较”。ROC 曲线是一条完整的曲线,并且“提供了分类器的细微细节”。关于 AUC 和 ROC 的更多解释,郑推荐本教程。
等级
郑指出,“一个主要的排名指标,精确召回,也是分类任务的流行”。虽然这是两个指标,但它们通常一起使用。郑指出“在数学上,精度和召回率可以定义如下:
- precision = #快乐的正确答案/# ranker 返回的项目总数
- 回忆= #快乐正确答案/ #相关项目总数。"
此外,“在底层实现中,分类器可以向每个项目分配数字分数,而不是分类类标签,并且排序器可以简单地通过原始分数对项目进行排序。”郑还指出,个人推荐可能是排名问题或回归模型的另一个例子。郑注意到“推荐者既可以作为排名者,也可以作为分数预测者。在第一种情况下,输出是每个用户的排序项目列表。在分数预测的情况下,推荐器需要返回每个用户-项目对的预测分数——这是回归模型的一个例子”。
回归
对于回归,郑在报告中指出,“在回归任务中,模型学习预测数字分数。”如前所述,个性化推荐是指我们“试图预测用户对某个项目的评分”。郑还指出,“回归任务最常用的指标之一是(均方根误差),也称为(均方根偏差)。然而,郑警告说,虽然 RSME 是普遍使用的,但也有一些挑战。RSMEs 对大的异常值特别敏感。如果回归器在单个数据点上表现很差,平均误差可能很大”或者“平均值不是稳健的(对于大的异常值)”。郑指出,真实数据中总会有“异常值”,“模型对它们的表现可能不会很好”。因此,寻找不受较大异常值影响的稳健估计值非常重要。”郑提议查看中值绝对百分比是有用的,因为它“为我们提供了典型误差的相对度量”
离线评估机制
郑在文中主张
模型必须在一个数据集上进行评估,该数据集在统计上独立于它被训练的数据集。为什么?因为它在训练集上的性能是对其在新数据上的真实性能的过于乐观的估计。训练模型的过程已经适应了训练数据。一个更公平的评估将衡量模型在它尚未看到的数据上的表现。从统计学的角度来说,这给出了泛化误差的估计值,它衡量了模型对新数据的泛化能力。
郑还指出,研究人员可以使用保留验证作为生成新数据的一种方式。保留验证,“假设所有数据点都是独立同分布的(独立同分布),我们只是随机保留部分数据进行验证。我们在较大部分的数据上训练模型,并在较小的保留集上评估验证指标。”郑还指出,当需要一种生成额外数据集的机制时,也可以使用重采样技术,如自举或交叉验证。“自举”通过从单个原始数据集中采样来生成多个数据集。每个“新”数据集可用于估计感兴趣的数量。由于有多个数据集,因此有多个估计值,人们也可以计算估计值的方差或置信区间等内容。”郑指出,交叉验证“在训练数据集如此之小,以至于人们无法承受仅出于验证目的而保留部分数据时是有用的。”虽然交叉验证有许多变体,但最常用的一种是 k 倍交叉验证,它
“将训练数据集分成 k 倍…k 个折叠中的每一个都轮流作为拒绝验证集;在剩余的 k -1 个褶皱上训练一个模型,并在保持褶皱上测量。整体性能是所有 k 倍性能的平均值。对所有需要评估的超参数设置重复此过程,然后选择产生最高 k 倍平均值的超参数。”
郑还指出 sckit-learn 交叉验证模块可能是有用的。
摘要
由于数据科学家在制作模型上花费了大量时间,因此尽早考虑评估指标可能有助于数据科学家加快工作速度,并为项目的成功做好准备。然而,评估机器学习模型是一个已知的挑战。这篇 Domino 数据科学领域笔记提供了摘自郑报告的一些见解。完整的深度报告可从下载。
^(Domino 数据科学领域笔记提供数据科学研究、趋势、技术等亮点,支持数据科学家和数据科学领导者加快工作或职业发展。如果您对本博客系列中涉及的数据科学工作感兴趣,请发送电子邮件至 writeforus(at)dominodatalab(dot)com。)
用 TCAV 的模型可解释性(用概念激活向量测试)
原文:https://www.dominodatalab.com/blog/model-interpretability-tcav-testing-concept-activation-vectors
这份多米诺数据科学领域笔记提供了来自 Been Kim 最近的 MLConf 2018 talk 和 research 关于使用概念激活向量(TCAV)进行测试的非常精炼的见解和摘录,这是一种可解释性方法,允许研究人员理解和定量测量他们的神经网络模型用于预测的高级概念,“即使概念不是训练的一部分。如果对这篇博文中没有提供的其他见解感兴趣,请参考 MLConf 2018 视频、 ICML 2018 视频和论文。
介绍
如果有一种方法可以定量地衡量你的机器学习(ML)模型是否反映了特定领域的专业知识或潜在的偏见,会怎么样?有培训后的讲解?在全球层面上而不是在当地层面上?业内人士会感兴趣吗?这是谷歌大脑高级研究科学家金在 MLConf 2018 演讲、“特征归因之外的可解释性:用概念激活向量(TCAV)进行测试”中提出的问题。ml conf 演讲基于 Kim 合著的论文并且代码可用。这份 Domino 数据科学领域笔记提供了一些关于 TCAV 的精华见解,这是一种可解释性方法,允许研究人员理解和定量测量他们的神经网络模型用于预测的高级概念,“即使该概念不是训练的一部分”( Kim Slide 33 )。TCAV“使用方向导数来量化用户定义的概念对分类结果的重要程度”( Kim et al 2018 )。
引入概念激活向量(CAV)
所以。什么是概念激活向量或 CAV?CAVs =研究人员创造的名称,用于将高层概念表示为向量,“激活”是“价值观的方向”。
在研究中, Kim 等人指出
“一个概念的 CAV 只是该概念的示例集的值(例如,激活)方向上的一个向量…我们通过在概念的示例和随机反例之间训练一个线性分类器,然后取垂直于决策边界的向量,来导出 CAV。”
在 MLConf 演讲中,Kim 转述道,“嗯,这个向量只是意味着一个方向指向远离随机的方向,更像是这个概念。拥有这样一个载体的想法并不新鲜,因为性别方向在 word2vec 的一篇论文中讨论过。金还指出骑士队“只是找回那个载体的另一种方式”。
用概念激活向量测试(TCAV):斑马
在研究中用来展示 TCAV 的一个突出的图像分类例子是“斑马的预测对条纹的存在有多敏感”。在 MLConf 会谈中,Kim 解开获得 TCAV 分数的量化解释
“TCAV 的核心思想是对 logit 层进行方向求导,即斑马纹相对于我们刚刚得到的向量的概率……直观地说,这意味着如果我让这幅图更像这个概念,或者更不像这个概念,斑马的概率会有多大变化?如果变化很大,这是一个重要的概念,如果变化不大,这不是一个重要的概念。我们对很多很多的斑马图片都是这样做的,以获得更有力和可靠的解释。最后的分数,TCAV 分数,仅仅是斑马图片的比率,其中条纹积极地增加了斑马的概率。换句话说,如果你有 100 张斑马的图片,其中有多少张返回了正方向导数?就是这样。”
如 MLConf 讲座的第 38 张幻灯片所示,同样需要注意的是
“当且仅当你的人际网络了解了一个概念,TCAV 才提供了这个概念的数量重要性”。
为什么考虑 TCAV?
在 MLConf 的演讲中,Kim 主张将可解释性作为一种工具,致力于“更负责、更安全地”使用 ML。在的论文内,金等人指出
“TCAV 是朝着创建对深度学习模型内部状态的人类友好的线性解释迈出的一步,以便关于模型决策的问题可以根据自然的高级概念来回答”。
当向不是 ML 专家的涉众翻译看似黑箱的模型时,使用高层概念可能是有用的。例如,当构建一个模型来帮助医生进行诊断时,使用医生友好的高级概念来测试您的模型以消除偏见或领域专业知识水平可能会有所帮助。这篇博客文章提供了最近关于 TCAV 研究的精华和摘录。如果有兴趣了解更多信息,请参考以下在撰写本文时参考和回顾的资源。
密码
MLConf 2018
ICML 2018: TCAV 相关链接
其他相关文件和幻灯片
^(Domino 数据科学领域笔记提供数据科学研究、趋势、技术等亮点,支持数据科学家和数据科学领导者加快工作或职业发展。如果您对本博客系列中涉及的数据科学工作感兴趣,请发送电子邮件至 writeforus(at)dominodatalab(dot)com。)
模型可解释性:对话继续
原文:https://www.dominodatalab.com/blog/model-interpretability-the-conversation-continues
这个 Domino 数据科学领域的笔记涵盖了可解释性的定义和 PDR 框架的概述。见解来自郁彬、w .詹姆斯·默多克、钱丹·辛格、卡尔·库姆伯和雷扎·阿巴西-阿西最近的论文《可解释机器学习的定义、方法和应用》。
介绍
模型的可解释性继续在工业界引发公众讨论。我们之前已经讨论过模型可解释性,包括提出的机器学习(ML)可解释性的定义。然而,郁彬、詹姆斯·默多克、钱丹·辛格、卡尔·库姆伯和礼萨·阿巴西-阿西在他们最近的论文《可解释机器学习的定义、方法和应用》中指出,早期的定义还不够。Yu 等人主张“在机器学习的背景下定义可解释性”,并使用预测性、描述性和相关性(PDR)框架,因为“关于可解释性的概念存在相当大的混乱”。
数据科学工作是实验性的、反复的,有时令人困惑。然而,尽管复杂(或因为复杂),数据科学家和研究人员策划并使用不同的语言、工具、包、技术和框架来解决他们试图解决的问题。业界一直在评估潜在的组件,以确定集成组件是否会有助于或妨碍他们的工作流程。虽然我们提供了一个平台即服务,行业可以使用他们选择的语言、工具和基础设施来支持模型驱动的工作流,但我们在这个博客中涵盖了实用技术和研究,以帮助行业做出自己的评估。这篇博客文章提供了对提议的 PDR 框架的简要概述,以及一些供业界考虑的额外资源。
为什么要迭代可解释 ML 的定义?
虽然包括Finale Doshi-维勒兹和 Been Kim 在内的研究人员已经提出了可解释性的定义,但于等人在最近的论文中认为先前的定义还不够深入,而且
这导致了对可解释性概念的相当大的混淆。特别是,不清楚解释某个东西意味着什么,不同的方法之间存在什么共同点,以及如何为特定的问题/受众选择一种解释方法。”
和主
“作为更大的数据科学生命周期的一部分,我们专注于使用解释从 ML 模型中产生洞察力,而不是一般的可解释性。我们将可解释的机器学习定义为从机器学习模型中提取相关知识,涉及包含在数据中或由模型学习的关系。在这里,我们认为知识是相关的,如果它为特定的受众提供了对所选问题的洞察力。这些见解通常用于指导沟通、行动和发现。它们可以以可视化、自然语言或数学方程式等形式生成,具体取决于上下文和受众。”
Yu 等人还认为以前的定义关注 ML 可解释性的子集,而不是整体性的,并且说明性的、描述性的、相关的(PDR)框架,加上词汇表,旨在“完全捕捉可解释的机器学习、其益处及其对具体数据问题的应用。”
规范性、描述性、相关性(PDR)框架
Yu 等人指出,在“如何针对特定问题和受众选择和评估解释方法”以及 PDR 框架如何应对这一挑战方面缺乏明确性。PDR 框架包括
为特定问题选择解释方法的三个要素:预测准确性、描述准确性和相关性。
于等人还认为,要使一个解释可信,实践者应该寻求预测和描述准确性的最大化。然而,在选择模型时需要考虑权衡。举个例子,
“基于模型的解释方法的简单性产生了一致的高描述准确性,但有时会导致复杂数据集的预测准确性较低。另一方面,在图像分析等复杂设置中,复杂模型可以提供较高的预测准确性,但更难分析,导致描述准确性较低。”
预测准确性
Yu 等人将预测精度定义为在解释的上下文中,关于与模型的基础数据关系的近似值。如果近似性很差,那么提取的洞察力也会受到影响。在构建模型时,可能会出现类似这样的错误。
“在标准的监督 ML 框架中,通过测试集精度等措施,评估模型拟合的质量已经得到了很好的研究。在解释的上下文中,我们将这种误差描述为预测准确性。请注意,在涉及可解释性的问题中,人们必须适当地衡量预测的准确性。特别是,用于检查预测准确性的数据必须与感兴趣的人群相似。例如,对一家医院的病人进行评估可能不能推广到其他医院。此外,问题通常需要超出平均准确度的预测准确度的概念。预测的分布很重要。例如,如果某个特定类别的预测误差非常高,就会出现问题。”
描述准确性
Yu 等人定义了描述准确性,
“在解释的上下文中,解释方法客观地捕捉由机器学习模型学习的关系的程度。
Yu 等人指出,当关系不明显时,描述准确性对于复杂的黑盒模型或神经网络是一个挑战。
关联
于等人认为,在口译的语境中,相关性的定义是“如果它为特定受众提供了对所选领域问题的洞察力。”岳等人还指出,相关性有助于关于准确性的权衡决策,并强调观众是人类观众。
根据手头问题的背景,从业者可能会选择关注其中一个而不是另一个。例如,当可解释性被用于审计模型的预测时,比如为了加强公平性,描述的准确性可能更重要。相比之下,可解释性也可以单独用作提高模型预测准确性的工具,例如,通过改进特征工程。”
结论和资源
这篇 Domino 数据科学领域笔记提供了 Yu 等人对 ML 可解释性和 PDR 框架的定义的简要概述,以帮助研究人员和数据科学家评估是否将特定的技术或框架集成到他们现有的工作流程中。有关可解释性的更多信息,请查阅以下资源
- 郁彬等人。《可解释的定义、方法和应用》【门控】
- 郁彬等人。可解释的机器学习:定义、方法和应用
- 多米诺。“数据伦理:质疑真理,重新安排权力”
- 多米诺。"让机器学习更严谨"
- 多米诺。"TCAV 模型的可解释性"
- 多米诺。"凯特·克劳福德的《偏见的烦恼》"
- 多米诺。“对石灰的信任:是,不是,也许是?”
- 乔希·波杜斯卡。 SHAP 系列。
- 乔希·波杜斯卡。可解释的 ML/AI 的数据科学剧本
- 帕科·内森。临近模型可解释性的新兴线索
^(多米诺数据科学领域笔记提供数据科学研究、趋势、技术等亮点,支持数据科学家和数据科学领导者加快工作。如果您对本博客系列中涉及的数据科学工作感兴趣,请发送电子邮件至 writeforus(at)dominodatalab(dot)com。)
模型管理和模型驱动的商业时代
原文:https://www.dominodatalab.com/blog/model-management-and-the-era-of-the-model-driven-business
在过去的几年里,我们看到了一个新的数据科学领导者群体的出现。
不管他们属于哪个行业,我们已经听到三个主题反复出现:1)公司正在认识到数据科学是一个竞争优势。2)人们担心他们的公司落后了,而其他公司在数据科学方面做得更好。3)数据科学家和数据科学领导者正在努力向高管解释为什么数据科学不同于其他类型的工作,以及这些差异对如何配备和组织数据科学团队的影响。
我们最近在 Rev 召集了这个数据科学领袖社区。在那里,我们分享了我们对“模型管理”的愿景,这是一套允许公司从大规模数据科学中获得竞争优势的流程和技术。这篇文章是那次演讲的摘要,你可以点击这里观看,或者点击这里下载白皮书。
介绍
自从我们五年前创立 Domino 以来,我们已经与数百家投资数据科学的公司进行了交谈,了解了他们的成功和挑战。
在那段时间的不同点上,我们关注了数据科学家和数据科学团队面临的挑战的不同方面。
- 当我们在 2014 年首次推出 Domino 时,我们专注于自动化数据科学家必须做的许多“开发运营”工作,以加快他们的工作。
- 2015 年,我们拓宽了口径,以满足数据科学家跟踪和组织其研究的需求。
- 2016 年,我们增加了部署模型的功能,创建了一个统一的平台来支持从开发到部署的数据科学生命周期。
- 2017 年,我们强调协作、可再现性和可重用性是数据科学团队有效扩展的基础。
在这个过程中的每一点上,我们都觉得有更重要的事情想要说,但我们不知道如何说。就像盲人描述大象不同部分的寓言一样,我们知道我们描述的是一部分,而不是全部。
所以大约一年前,我们后退了一步。我们与客户进行了长时间的讨论,以提炼和综合数据科学的不同之处,以及最有效应用数据科学的公司的不同之处。
数据科学家做什么?
当我们问自己:“数据科学家做什么?”时,我们有了重大的发现
除了对人工智能和机器学习的大肆宣传,数据科学的核心是一种叫做 模型 的东西。所谓“模型”,我指的是一种基于概率评估做出预测或建议或规定一些行动的算法。
模型可以自主地做出决定并采取行动,其速度和复杂程度是人类通常无法比拟的。这使得模型成为一种新型的数字生活。
数据科学家做模型。
如果你看看世界上最成功的公司,你会发现他们的商业核心模式推动了成功。
大家都熟悉的一个例子是网飞推荐模型。它提高了网飞的用户参与度、保留率和运营效率。2016 年,网飞表示他们的推荐模式是价值超过每年1B 美元。
可口可乐使用一个模型来优化橙汁生产。Stitch Fix 利用模特向顾客推荐服装。保险公司开始使用模型从事故照片中自动估算损失,减少对理赔人员的依赖。
模特神话
虽然从某种意义上来说是显而易见的,但认识到数据科学家制造模型是强有力的,因为它解释了公司在有效利用数据科学方面面临的大多数挑战。
从根本上说,公司在数据科学上苦苦挣扎的原因都源于对模型与他们过去建立的其他类型资产有何不同的误解。
许多公司试图像开发和部署软件一样开发和部署模型。许多公司试图用技术装备数据科学家,就像他们装备业务分析师进行查询和构建商业智能仪表板一样。
很容易理解为什么公司会陷入这个陷阱:模型涉及代码和数据,因此很容易将它们误认为软件或数据资产。
我们称之为 模型神话 :这是一种误解,因为模型涉及代码和数据,公司可以像传统上对待软件或数据资产一样对待它们。
模型在三个方面有着根本的不同:
- 用来开发它们的材料不一样。它们涉及代码,但是它们使用了不同于软件工程的技术和工具。它们使用更多计算密集型算法,因此受益于可扩展计算和 GPU 等专用硬件。他们使用的数据远远多于软件项目。他们利用每天都在创新的充满活力的开源生态系统的软件包。因此,数据科学家需要极其敏捷的技术基础设施来加速研究。
- 构建它们的过程是不同的。数据科学是研究,它是实验性的、反复的和探索性的。在得到有用的东西之前,你可能会尝试几十或几百个想法。因此,数据科学家需要允许快速探索和迭代的工具,以使他们富有成效并促进突破。
- 模特的行为是不同的。模型是概率性的。他们没有“正确”的答案——一旦他们生活在现实世界中,他们只有更好或更差的答案。虽然没有人需要“重新培训”软件,但模型可以随着周围世界的变化而变化。因此,组织需要不同的方法来审查、质量控制和监控它们。
模型管理
最有效地利用数据科学的公司——那些通过数据科学持续推动竞争优势的公司——是那些认识到模型不同并以不同方式对待它们的公司。
我们研究了这些公司对待模型的不同方式,并将其组织成一个框架,我们称之为 模型管理 。
从历史上看,“模型管理”狭义地指的是一旦模型在生产中运行,就对其进行监控的实践。我们指的是更广泛的东西。
模型管理包含一系列流程和技术,使公司能够持续、安全地从大规模数据科学中获得竞争优势。
模型管理有五个部分:
- 模型开发允许数据科学家快速开发模型、进行实验并推动突破性研究。
- 模型生产是数据科学家的工作得以运作的方式。它如何从一个很酷的项目变成一个集成到业务流程中的活产品,从而影响真正的决策。
- 模型技术包括计算基础设施和软件工具,为数据科学家提供开发和部署创新模型所需的灵活性。
- 模型治理是指公司如何掌握数据科学工作在其整个组织中的活动和影响,以了解项目、生产模型以及支持它们的底层基础架构的进展情况。
- 模型环境是这些功能的核心。它是在构建或使用模型时产生的所有知识、见解和所有工件。这通常是公司最有价值的知识产权,找到、重用和构建知识产权的能力对于推动快速创新至关重要。
管理模型的每个方面都需要独特的流程和产品。当整合在一起时,它们为组织释放了数据科学的全部潜力。##计算机革命将赢家和输家区分开来
数据科学是计算的新时代。第一个时代是硬件,工程师做芯片和电路板。第二个时代是软件时代,工程师做应用。第三个时代,数据科学家做模型。
和过去的计算革命一样,数据科学时代有两件事是真实的:
- 公司采用和有效应用新方法的能力将决定它们在未来几年的竞争力。正如“软件吃掉了世界”和“每个公司都需要成为软件公司”,如果每个公司想要保持竞争力,它们都需要成为数据科学公司。
- 适用于前一个时代的方法、工具和流程将不适用于这个新时代。软件工程的兴起带来了新的方法、新的职称和新的工具——对开发、交付和管理硬件有效的东西对软件无效。数据科学也是如此:适用于软件的东西不适用于模型。
模型管理是公司将模型置于其业务核心所需的一系列过程和技术。这是必需的,因为模型不同于软件,所以它们需要新的方法来开发、交付和管理它们。通过采用模型管理,组织可以释放数据科学的全部潜力,成为模型驱动的企业。
模型管理和模型驱动的商业时代
原文:https://www.dominodatalab.com/blog/model-management-era-model-driven-business
在过去的几年里,我们看到了一个新的数据科学领导者群体的出现。
无论属于哪个行业,我们都听到三个主题反复出现:1)公司正在认识到数据科学是一项竞争优势。2)人们担心他们的公司落后了,而其他公司在数据科学方面做得更好。3)数据科学家和数据科学领导者正在努力向高管解释为什么数据科学不同于其他类型的工作,以及这些差异对如何配备和组织数据科学团队的影响。
我们最近在 Rev 聚集了这个数据科学领袖社区。在那里,我们分享了我们对“模型管理”的愿景,这是一套允许公司从大规模数据科学中获得竞争优势的流程和技术。这篇文章是那次演讲的摘要,你可以在这里观看。
介绍
自从我们五年前创立 Domino 以来,我们已经与数百家投资数据科学的公司进行了交谈,了解了他们的成功和挑战。
在那段时间的不同点上,我们关注了数据科学家和数据科学团队面临的挑战的不同方面。
- 当我们在 2014 年首次推出 Domino 时,我们专注于自动化数据科学家必须做的许多“开发运营”工作,以加快他们的工作。
- 2015 年,我们拓宽了口径,以满足数据科学家跟踪和组织其研究的需求。
- 2016 年,我们增加了部署模型的功能,创建了一个统一的平台来支持从开发到部署的数据科学生命周期。
- 2017 年,我们强调协作、可再现性和可重用性是数据科学团队有效扩展的基础。
在这个过程中的每一点上,我们都觉得有更重要的事情想要说,但我们不知道如何说。就像盲人描述大象不同部分的寓言一样,我们知道我们描述的是一部分,而不是全部。
所以大约一年前,我们后退了一步。我们与客户进行了长时间的讨论,以提炼和综合数据科学的不同之处,以及最有效应用数据科学的公司的不同之处。
数据科学家做什么?
当我们问自己:“数据科学家做什么?”时,我们有了重大的发现
除了对人工智能和机器学习的大肆宣传,数据科学的核心是一种叫做 模型 的东西。所谓“模型”,我指的是一种基于概率评估做出预测或建议或规定一些行动的算法。
模型可以自主地做出决定并采取行动,其速度和复杂程度是人类通常无法比拟的。这使得模型成为一种新型的数字生活。
数据科学家做模型。
如果你看看世界上最成功的公司,你会发现他们的商业核心模式推动了成功。
大家都熟悉的一个例子是网飞推荐模型。它提高了网飞的用户参与度、保留率和运营效率。2016 年,网飞表示他们的推荐模式是每年价值超过$1B。
可口可乐使用一个模型来优化橙汁生产。Stitch Fix 利用模特向顾客推荐服装。保险公司开始使用模型从事故照片中自动估算损失,减少对理赔人员的依赖。
模特神话
虽然从某种意义上来说是显而易见的,但认识到数据科学家制造模型是强大的,因为它解释了公司在有效利用数据科学方面面临的大多数挑战。
从根本上说,公司在数据科学上苦苦挣扎的原因都源于对模型与他们过去建立的其他类型资产有何不同的误解。
许多公司试图像开发和部署软件一样开发和部署模型。许多公司试图用技术装备数据科学家,就像他们装备业务分析师进行查询和构建商业智能仪表板一样。
很容易理解为什么公司会陷入这个陷阱:模型涉及代码和数据,因此很容易将它们误认为软件或数据资产。
我们称之为 模型神话 :这是一种误解,因为模型涉及代码和数据,公司可以像传统上对待软件或数据资产一样对待它们。
模型在三个方面有着根本的不同:
- 用来开发它们的材料不一样。它们涉及代码,但是它们使用了不同于软件工程的技术和工具。它们使用更多计算密集型算法,因此受益于可扩展计算和 GPU 等专用硬件。他们使用的数据远远多于软件项目。他们利用每天都在创新的充满活力的开源生态系统的软件包。因此,数据科学家需要极其敏捷的技术基础设施来加速研究。
- 构建它们的过程是不同的。数据科学是研究,它是实验性的、反复的和探索性的。在得到有用的东西之前,你可能会尝试几十或几百个想法。因此,数据科学家需要允许快速探索和迭代的工具,以使他们富有成效并促进突破。
- 模特们的行为是不同的。模型是概率性的。他们没有“正确”的答案——一旦他们生活在现实世界中,他们只有更好或更差的答案。虽然没有人需要“重新培训”软件,但模型可以随着周围世界的变化而变化。因此,组织需要不同的方法来审查、质量控制和监控它们。
模型管理
最有效地利用数据科学的公司——那些通过数据科学持续推动竞争优势的公司——是那些认识到模型不同并以不同方式对待它们的公司。
我们研究了这些公司对待模型的不同方式,并将其组织成一个框架,我们称之为 模型管理 。
从历史上看,“模型管理”狭义地指的是一旦模型在生产中运行,就对其进行监控的实践。我们指的是更广泛的东西。
Model Management 包含一组流程和技术,这些流程和技术使公司能够一致而安全地从大规模数据科学中获得竞争优势。
模型管理有五个部分:
- 模型开发允许数据科学家快速开发模型、进行实验并推动突破性研究。
- 模型生产是数据科学家的工作得以运作的方式。它如何从一个很酷的项目变成一个集成到业务流程中的活产品,从而影响真正的决策。
- 模型技术包括计算基础设施和软件工具,为数据科学家提供开发和部署创新模型所需的灵活性。
- 模型治理 是指公司如何掌握数据科学工作在其整个组织中的活动和影响,以了解项目、生产模型以及支持它们的底层基础架构的进展情况。
- 模型环境是这些功能的核心。它是在构建或使用模型时产生的所有知识、见解和所有工件。这通常是公司最有价值的知识产权,找到、重用和构建知识产权的能力对于推动快速创新至关重要。
管理模型的每个方面都需要独特的流程和产品。当整合在一起时,它们为组织释放了数据科学的全部潜力。
计算机革命区分了赢家和输家
数据科学是计算的新时代。第一个时代是硬件,工程师做芯片和电路板。第二个时代是软件时代,工程师做应用。第三个时代,数据科学家做模型。
和过去的计算革命一样,数据科学时代有两件事是真实的:
- 公司采用和有效应用新方法的能力将决定它们在未来几年的竞争力。正如“软件吃掉了世界”和“每个公司都需要成为软件公司”,如果每个公司想要保持竞争力,它们都需要成为数据科学公司。
- 适用于前一个时代的方法、工具和流程将不适用于这个新时代。软件工程的兴起带来了新的方法、新的职称和新的工具——对开发、交付和管理硬件有效的东西对软件无效。数据科学也是如此:适用于软件的东西不适用于模型。
模型管理是公司将模型置于其业务核心所需的一系列过程和技术。这是必需的,因为模型不同于软件,所以它们需要新的方法来开发、交付和管理它们。通过采用模型管理,组织可以释放数据科学的全部潜力,成为模型驱动的企业。
模型监控最佳实践
原文:https://www.dominodatalab.com/blog/model-monitoring-best-practices-maintaining-data-science-at-scale
通过模型监控大规模维护数据科学
本文涵盖了模型漂移,如何识别退化的模型,以及在生产中监控模型的最佳实践。关于本文之外的其他见解和最佳实践,包括纠正模型漂移的步骤,请参见模型监控最佳实践:大规模维护数据科学。”
越来越多的决策和关键业务流程依赖于通过机器学习和其他统计技术生成的模型。(例如,索赔处理、欺诈检测和贷款审批)。这些模型本质上是概率性的,每个模型的行为都是从数据中学习的。
一旦进入生产环境,如果生产数据与用于定型模型的数据不一致,模型的行为可能会发生变化。换句话说,模型的行为是由它“训练”的世界图景决定的,但现实世界的数据可能会与它“学习”的图景有所不同这类似于你如何训练一只老鼠完美地通过一个迷宫;当老鼠被放入一个它以前没有见过的新迷宫中时,它的表现不会那么好。
模型通常依赖于跨越多个团队的数据管道和上游系统,这带来了额外的风险。这些上游系统中的变化或错误会改变流入模型的数据的性质,通常是以无声但重要的方式。
模型性能下降的现象称为“漂移”不管是什么原因,漂移的影响都可能是严重的,导致财务损失、客户体验下降,甚至更糟。
模型会随着时间而退化
模型会因为各种原因而退化:产品或政策的变化会影响客户的行为;敌对行动者可以调整他们的行为;数据管道可能会断裂;有时候世界只是在进化。最常见的原因属于数据漂移和概念漂移这两类。
数据漂移:当生产数据偏离模型的原始训练数据时,就会发生数据漂移。数据漂移可能因各种原因而发生,包括不断变化的业务环境、不断变化的用户行为和兴趣、对来自第三方来源的数据的修改、数据质量问题,甚至上游数据处理管道中的问题。例如,如果工业传感器的读数由于机械磨损而开始随时间变化,这将导致数据漂移。
概念漂移:即使输入数据的分布没有改变,当构成正确预测的预期随时间改变时,也会发生概念漂移。例如,去年(创建训练数据集时)被认为是有吸引力的潜在客户的贷款申请人可能不再被认为有吸引力,因为银行的战略或对未来宏观经济条件的展望发生了变化。同样,在 COVID 疫情期间,人们对产品类别的兴趣发生了变化,导致库存失败,因为许多零售预测模型继续根据 COVID 之前消费者兴趣的训练数据进行预测。
作为概念漂移的说明性示例,考虑三十年前创建的情感模型如何错误地对各种单词和短语的情感进行分类,因为我们说话的方式、我们使用的单词和我们开发的俚语随着时间不断变化:
为了使模型在这种情况下工作,有必要根据对其结果的预期来监控模型的性能,因为它们是通过最近的地面真实数据捕获的,而不是根据模型的旧训练数据集的过去预期。
识别模型退化的方法
鉴于模型降级的潜在重大负面影响(例如,考虑银行可能因降级的贷款违约模型而亏损的速度),尽快检测模型漂移至关重要。这里有一些在过时的模型对您的业务造成严重影响之前检测模型退化的建议。
检查模型预测:检测模型退化的一种常见方法包括检查模型预测是否不再有效或准确。例如,一家大型保险公司发现,它发现的欺诈性索赔比过去少得多。一旦实际结果(即地面真实数据)可用,异常结果导致公司更仔细地审查准确性。
在输出端,许多模型产生某种分数或一组分数,它们通常代表一个概率估计。如果模型产生的分数分布发生意外变化,这意味着模型退化。这可能是由反映外部世界的一些变化的模型输入的变化,或者模型所依赖的系统的变化(例如,用于特征提取)引起的。在这两种情况下,观察分数分布的变化是识别问题的第一步。
在评估一个模型时,评估是否可以使用基础数据也很重要。尽管实时的基本事实反馈可能很好,但一些用例需要数月或数年的滞后时间来了解预测的基本事实,如果它们确实可用的话。例如,你可能不知道被预测会拖欠 30 年期抵押贷款的客户实际上是否会拖欠很多年。但是,如果使用地面真实数据不可行,您可以使用分布分析和上面概述的其他技术。
检查(输入)数据漂移:检测模型退化的最有效方法之一是监控呈现给模型的输入数据,以查看它们是否已经改变;这解决了数据漂移和数据流水线问题。有几种检查输入数据的有效方法,包括:
- 查看描述性统计数据、数据类型(例如,字符串、整数等。)、数据范围和数据稀疏性/缺失数据,然后将它们与原始训练数据进行比较。输入数据分布的剧烈变化可能会突出严重的模型退化。
- 定义度量来跟踪用于训练模型的数据与呈现给模型进行评分的数据之间的差异。如果差异超过阈值或显著漂移,这是模型漂移和退化的强烈指示。
请注意,有些特征比其他特征更重要(更具预测性)。发生少量漂移的重要特征可能是重新训练的原因,而预测能力低/无预测能力的特征可能会发生很大漂移,对整个模型的影响可以忽略不计。设置监控时,确定模型的最重要特征非常重要,因此您可以密切跟踪它们。
检查概念漂移:与数据漂移分布分析类似,您可以使用相同的方法分析概念漂移。通常,您会实时比较训练集的标签分布与生产数据的标签分布。您还可以检查 a) 输入值是否在允许的集合或范围内,以及 b) 集合内每个值的频率是否与您过去看到的一致。例如,对于“婚姻状况”的模型输入,您将检查输入是否在期望值范围内,如“单身”、“已婚”、“离婚”等。
监控模型的组织最佳实践
模型监控的方法在不同的公司之间差异很大——甚至在一个公司的数据科学部门内部也是如此!通常,数据科学领导者承担监控模型漂移和模型健康状况的责任,因为他们的团队最终要对模型做出的预测的质量负责。然后,数据科学家花费大量时间分析生产中的模型,而不是进行新的研究。一些数据科学家为了减少手动工作,然后为每个模型开发特定的监控解决方案,导致分散、不一致、维护不佳和半生不熟的监控解决方案激增。
其他公司要求 IT 部门负责生产模型监控。这给已经不堪重负的 IT 部门增加了时间和教育负担。传统的 IT 工具和经验适用于监控基础架构、正常运行时间和延迟,并不能很好地转化为模型监控,后者更依赖于统计方法。
另一种方法要求在组织内部创建一个新的角色。ML 工程师既是数据科学家,又是软件工程师,需要精通 DevOps 和模型监控最佳实践,以减轻数据科学和 IT 团队的负担。随着生产模型数量的增长,公司需要雇佣和保留的 ML 工程师的数量也在增长。
用 Domino 进行模型监控
鉴于数据科学模型对您业务的重要性,您需要有一个生产监控系统。没有可观察性,维护端到端的模型生命周期是不可能的。你不希望被抓到不知道关键生产模型恶化超过可接受的水平。
Domino Model Monitor (DMM) 为所有生产模型的自动化模型监控和主动警报提供单一平台。有了这个模型运行状况控制面板,it 承担监控数据科学模型的大部分责任是合理的。DMM 可以向 IT 团队、数据科学家以及其他相关方发送警报,以便将模型退化识别集成到您的工作流程中。
DMM 检测并跟踪模型输入特征和输出预测中的数据漂移。如果您有模型的基本事实数据,DMM 可以接收这些数据,使用标准度量(如准确度、精确度等)来计算和跟踪模型的预测质量。
DMM 检查用于训练模型的预测数据与目标数据的特征是否有显著差异。DMM 还跟踪用于训练模型的数据与提供给模型进行评分的数据之间的差异。
通过设置计划检查、使用 API 接收数据以及在 DMM 中配置警报通知接收者,您可以在整个组织中以标准化的方式持续监控数百个模型。API 能够集成到现有的业务流程中,也是自动再培训的编程选项。DMM 使您的 IT 部门和数据科学家在模型监控方面更加高效和主动,而不需要过多的数据科学家时间。
结论
随着您的公司将更多的机器学习系统投入生产,有必要更新您的模型监控实践,以一致、高效的方式对模型健康和您的业务成功保持警惕。对 ML 车型进行监控就像你对年度体检或定期换油的想法一样。模型监控是一项至关重要的操作任务,它允许您检查您的模型是否发挥了最佳性能。
除了为建立模型监控的最佳实践提供建议之外,模型监控最佳实践:大规模维护数据科学还就如何估计其影响、分析根本原因以及采取适当的纠正措施提供了建议。
模型速度:加速模型驱动业务的关键
大部分数据科学家都会告诉你,成功在于迭代开发模型,但是仅仅迭代开发是不够的。如果您的模型被部署了一次,并且再也没有接触过(或者,正如经常发生的,根本没有部署),那么再多的迭代开发也不会驱动持续的业务成果。不仅你的模型在投入生产的那一刻就会退化,而且更多的时候,你只有在人们使用生产版本的时候才会发现你的模型真正的业务需求,也就是说,在 你的模型被部署之后的 。当你迟早面临数据的系统性变化时——例如,由于疫情——无论开发过程中进行了多少次迭代,你都需要抛弃你的模型。
模型速度对于模型值和体积是必须的
推动变革性影响的关键在于你在模型的整个生命周期中迭代的能力。你能多快、多有效地做到这一点是对你的模型速度的衡量,它如何随着时间的变化帮助你追踪你成为模型驱动的企业的进程。Model Velocity 捕捉您快速、重复且一致地遍历端到端模型开发和部署流程的能力——从数据工程、功能工程、算法选择、超参数调整、验证、部署到监控。它评估您实现新模型的能力,就像特性速度帮助开发团队评估他们交付新特性的能力一样。
您需要保持并加快您的模型速度,以抓住每一个利用新模型推动商业价值的机会,但同样重要的是,保持您的模型是最新的,以便它们反映当前的市场条件、客户偏好等。您需要不断调整您的模型,用额外的训练数据改进它们,并针对漂移对它们进行调整。您的模型速度跟踪您在数据科学生命周期中持续迭代的速度。综合起来,您的模型速度决定了您处理新的模型驱动项目的速度,您可以同时支持多少个项目,以及您如何有效地保持成功的结果。
测量您的模型和模型速度
每个数据科学团队都在努力衡量他们的效率、跟踪进展和自我基准测试。衡量模型性能(如精确度、召回率或 F1 分数)或由此产生的业务成果虽然极其重要,但只能提供对您能力的有限洞察。模型性能的下降很容易掩盖强大的功能,因为如果团队没有部署更新的模型,下降会更大。
测量完成的项目或部署的模型的数量也同样有问题。人们通常认为越多越好,但是如果你不维护这些模型,那么更多的模型就意味着更多的风险,这也可能表明你的团队过于分散,无法支持当前的投资组合,更不用说采取新的举措了。
度量模型速度为您提供了数据科学能力、成熟度和性能的更完整视图,因为它度量了进入这些模型的活动的成功。因此,它受外部因素(例如业务条件或 It 系统的变化)的影响更小,并且为您提供了一个更好的视图,不仅是您已部署项目的健康状况,而且是您需要为未来计划的容量、能力、时间和摩擦的前瞻性视图。
加速您的模型驱动型业务
今天有哪家公司不想更加模型驱动?挑战在于超越特定的项目和孤立的成功,扩展到可靠的、可重复的能力,以在整个组织中增长、维护和管理模型驱动的项目。前进的道路布满了减速带和坑洞,限制了你的模型速度,可能会完全阻碍你的模型驱动的野心。数据科学家往往最终无法获得足够的数据、工具过时、计算能力不足,并且将模型投入生产并长期维护的手动流程缓慢。加快您的模型速度需要企业级机器,以支持端到端生命周期的最新工具和基础架构来推动协作和自动化。
模型速度为我们提供了一种全面衡量模型生命周期的新方法——捕捉决定成功的人员(角色和技能)、流程(协作)和技术(集成平台)因素。模型速度是一个新概念——您需要根据您的需求调整确切的公式,它不能取代我们今天使用的大多数指标,但有了它,我们现在有了一个用于模型驱动的旅程的加速度计。
GSK 介绍如何实现临床试验分析和报告的现代化,以加速创新
原文:https://www.dominodatalab.com/blog/modernize-clinical-trial-analytics-reporting-with-gsk
为了永无止境地加快创新,世界各地的医疗保健和制药公司一直在努力实现统计计算环境的现代化,简化临床试验,并处理所需的分析和报告。
我们最近与葛兰素史克 举行的 网络研讨会探讨了这家制药巨头最近是如何进行这种现代化的,显然,电话会议上的数百名与会者非常关注葛兰素史克的故事。许多与会者提出了许多有见地的问题,以下是一些,包括我们的回答。如果您错过了现场直播, 查看录音 。
https://www.youtube.com/embed/HJqqY1cvn8c?feature=oembed
问:你提到 Domino 用于 GxP 和非 GxP 环境。这是如何工作的,Domino 中内置了可追溯性工作流吗?
答:Domino 环境是一个容器映像,其中包含开发和执行代码的软件,例如,您在分析中需要的 R 包。对于更严格的 GxP 环境,包含的软件已经过验证,并被认为适合用于 GxP 活动,如临床试验分析和报告。例如,如果您使用 Domino 项目进行临床研究,您可以拥有一个经过验证的 R 环境和一个 SAS 环境,您可以在研究中使用这两个环境。另一个团队可能使用 Domino 项目进行探索,或者实际验证一个特定的 R 包,在这种情况下,该项目将包含使用非 GxP 环境的能力。管理员可以限制某些环境的使用。例如,临床程序员可以被限制为只能使用经验证的 R 环境和 SAS 环境,而另一个需要灵活性的组可以使用经验证的环境和非经验证的环境。
工作流独立于此,并且可追溯性和可再现性被集成到 Domino 项目中,而不管项目中使用的环境如何。作业的可追溯性和可再现性在 GxP 之外是有用的,并且没有任何限制。
问:你如何从一个探索性的、非 GxP 环境转移到 GxP 环境?例如,您开始在非 GxP 上构建您的 Ext Control Arm,然后想转移到 GxP 上提交给权威机构。
答:无论是 GxP 过程还是非 GxP 过程,每个项目中都包含了 GxP 工作所需的 Domino 审计跟踪、可追溯性和可再现性能力。在 Domino 中,灵活性和 GxP 控件都是内置的,而不会影响任何一个。在做出改变之前,关键的考虑是您是否已经验证了您的标准工具和包将在 GxP 环境中使用。
问:从 GxP 的角度来看,你是如何验证系统的,需要多少努力来管理变更并保持系统处于验证状态?
答:我们最近在 GSK 进行的鉴定和验证 Domino for SCE 的工作(GxP 工作)就是一个很好的例子。我们制定了一个验证计划,其中包括方法和将要生成的文档列表。每当对系统进行更改时,我们都会再次执行验证流程,在适用的情况下更新现有文档,并在需要时生成新文档。因此,与正在进行的更改相比,在系统的初始验证中要付出更大的努力。
问:审计追踪是否向用户公开并用于质量保证?
答:每个项目自始至终都有活动的审计跟踪。该活动随时可用,以了解事件的时间线。Domino 提供了一个 PDF 格式的数据访问管理审计跟踪,以及一个 API 来检索项目中发生的所有作业执行的审计跟踪。Domino 自动对创建的数据、代码和输出进行版本化,并可以创建一个. CSV 审计报告,作为审查的证据或向审计人员展示。
问:数据的安全性是如何控制的?你如何处理一些数据或分析的盲目?
答:在 Domino 中有几种方法可以实现这一点。Domino 中的数据存储在我们所谓的 Domino datasets 中,它本质上是一个数据集库。这意味着在一个 Domino 项目中可以有多个 Domino 数据集。您还可以在多个项目上挂载一个 Domino 数据集。
访问是在 Domino 项目级别和 Domino 数据集级别(在 Domino 5.4 或更高版本中)进行管理的。访问级别可以是禁止访问、只读访问或读写访问。所有的访问更改都被审计跟踪。取消隐藏包含敏感数据的数据集只需更改个人或团队对该数据的访问级别。不需要移动或移植需要在其上执行的数据或代码。
例如,在一个项目中,只有非盲程序员可以访问敏感数据集、非敏感数据集和敏感分析(输出),而在另一个项目中,盲程序员只能访问非敏感数据。敏感数据集可以装载到该项目中,但是在所有者授予他们访问权限之前,他们仍然无法查看或使用它。
问:使用什么 CDR,或者 Domino 作为 CDR?
答:Domino 不是一个临床数据存储库,但是它可以作为 Domino 中通过执行代码创建的数据和输出的记录系统。Domino 可以连接到各种数据源,包括保存原始数据的 CDR(如果它支持 API ),并且可以直接访问。Domino 允许您使用来自 CDR 的数据作为输入来生成分析数据和输出,或者执行其他任务,比如建模或监控。Domino 还允许您以编程方式连接到 MDR,无论它是集中管理的 Excel 电子表格、数据库还是可以通过 API 访问的 MDR 系统,以便利用元数据使用标准或非标准代码生成输出。
如何使自己组织的 SCE 现代化以加速创新
正如本次网络研讨会所表明的,合适的分包商可以在制药公司如何加快临床试验提交方面发挥重要作用。你可以在这里 观看重播 。然后, 了解更多关于 Domino 如何帮助 GSK 和其他医疗保健和生命科学公司实现 SCE 现代化的信息。
数据科学家访谈:来自 Ingram 的 Eduardo Arino de la Rubia
原文:https://www.dominodatalab.com/blog/monthly-data-science-interview-eduardo-arino-de-la-rubia
我们最近采访了 Eduardo Arino de la Rubia,他是英格拉姆内容集团的主要开发人员,在该公司担任两个职位。在这两个角色的第一个中,Eduardo 与按需印刷提供商 Lightning Source 合作。按需制造图书有各种有趣的数据科学应用,从试图预测停机时间和使用机器视觉和图像处理进行质量控制,一直到自然语言处理,再到理解通过他们设施的内容。爱德华多还与英格拉姆的首席风险投资官合作,资助有趣的初创公司。他大力支持在早期到中期风险投资的尽职调查过程中使用数据科学。
你是如何开始从事数据科学的,你认为是什么让你在整个职业生涯中取得成功?
Considering yourself a student allows you to not become too rigid within a single orthodoxy and encourages you to expect new and interesting approaches that will surprise you.
在 90 年代,我对 HPC 非常感兴趣,尤其是并行处理。我爱上了可用的工具包,PVM 和 MPI。我非常幸运,我就读的大学为学生提供了一台 SIMD 超级计算机,并鼓励有兴趣的学生探索和学习这种方式。例如,这是我第一次介绍 GPU 目前采用的方法。我的一位教授还向我介绍了遗传算法和软计算,我很快就被这些生物启发的优化和解决问题的方法迷住了。老实说,在那之后的几年里,我放弃了数据科学和机器学习雷达。网络热潮和“网络平台”确实吸引了我,因此占用了我大量的时间。然而,在过去的十年里,我花了越来越多的时间学习图像处理,这在本质上是令人惊讶的数字。这也是一个自然的渠道,让我回到机器学习的最新进展,因为我已经将它们融入了我的日常工作。我还认为,我在计算机领域取得成功的“秘密”之一是我如何积极地重塑自己作为一名学生的形象。例如,我报名参加了可用的大会数据科学课程,我报名参加了可用的 Coursera/Johns Hopkins 数据科学专业,等等……将自己视为一名学生可以让你不要在单一正统观念中变得过于僵化,并鼓励你期待会让你惊讶的新的有趣方法。永远愿意接受和享受惊喜,即使惊喜是你的先入之见是错误的,并且感谢给了你学习和惊喜的机会。
我还参与了围绕数据科学主题的精彩 meetup 社区,度过了一段美好的时光,我非常幸运,在洛杉矶我们有一个活跃而热情的社区。我的一个合作者 Szilard Pafka 在近 5 年前发起了一个数据科学会议——名义上是一个 R 会议,但主题显然是 DS——随着时间的推移,这已经培养了一个非常友好的大学环境。我们推出了数据科学。今年早些时候,LA 帮助保持社区的学习和发展,帮助对该领域感兴趣的人了解更多,并吸引有趣的演讲者。重要的是,你要自愿奉献自己的时间,在聚会上发言,鼓励他人,因为这是你学习最多、建立最牢固关系的时候。
你在分析中使用什么工具?你最感兴趣的新工具或新技术是什么?
While R is indeed a programming language and can be judged as one, to do so is to completely miss the point of the language.
我首先是一名程序员,我已经做了很长时间了。这应该会转化为一个优势,但老实说,我认为这是我采用现代数据科学工具期间最大的劣势之一。刚接触 R 生态的时候,我是作为一个程序员来判断的。虽然 R 确实是一种编程语言,并且可以被视为一种编程语言,但这样做完全没有抓住语言的要点。r(和 RStudio)是一个交互式环境,是一些世界上最先进的分析算法的接口。
不用说,我现在是一个彻底的皈依者,也是一个活跃的 R 用户。具体来说,我喜欢 r studio IDE 和 IPython 笔记本。他们都很强大,可以互相学习。我主要使用 RStudio,当我在 R 中工作时,我是 Hadleyverse 的支持者,这是由 Hadley Wickham 构建的一系列 API,它们使分析和可视化现代化。
我最感兴趣的“工具和技术”是可重复性工具的发展。Domino Data Labs 所做的工作在这个领域是非常前沿的,他们的工具是任何人的工具箱中的一个极好的补充。我也是 Yihui Xie 的knitter package的支持者,因为它是构建 markdown 文档的一个极好的工具,该文档以一种可重复的、易于交流的方式封装了分析结果。
无论是从商业角度还是个人角度,你能与我们分享一个令人兴奋的数据科学应用吗?
我认为教育将会是数据科学带来革命的最大的行业。数据和预测分析的正确应用可以帮助教育的许多方面。相反,非营利领域的数据科学正在飞速发展,可以帮助我们解决我们目前面临的一些最大的社会问题。
我知道几周前你在 Strata,所以我们来谈谈这个吧...
你在 Strata+Hadoop World 上注意到了哪些趋势?
I understand that Big Data is exciting and sexy, but to pretend these tools are ready for production and available as a turnkey solution is disingenuous and distracting from the issues still at hand.
《地层》既令人兴奋又令人失望。我明白像 Strata 这样的会议的目的是为了宣传一个生态系统的未来,但我确实觉得这是以牺牲当前的能力为代价的。例如,市场过于分散,提供部分解决方案的参与者太多。此外,我在 Strata 亲身经历了承诺过多和交付不足的问题。我知道大数据是令人兴奋和性感的,但假装这些工具已经准备好投入生产并作为交钥匙解决方案提供是不真诚的,并且会分散人们对仍然存在的问题的注意力。我们在大数据方面做得很好的事情已经变得更好了,批处理、ETL 等…这些事情肯定是坚实的。围绕数据的“交互式实时访问”的故事情节,即向 BI 分析师开放组织的整个数据世界的承诺,仍然有点像白日梦。
最大的故事无疑是 Spark 。在我看来,毫无疑问,Spark 将消费整个大数据世界,对于那些真正需要 Spark 的流处理和内存计算能力的组织来说,这一未来不会很快到来。
我们听到许多公司在谈论 Hadoop...从你一个行业从业者的角度来看,有多少是炒作,有多少是真实的?
Make sure you really have pushed the limits of conventional approaches first and are not merely jumping on the latest bandwagon.
很不幸,这是 90%的炒作。让我澄清一下,如果你的公司需要 Hadoop,那么它就是你做生意的唯一最核心的组件。然而,许多组织希望将 Hadoop 生态系统作为其工具集的一部分,但很少有人需要它。如果你需要像 Hadoop 这样的东西,拥有海量数据的组织确实需要,那么你已经在使用它,并且已经意识到了它的局限性和复杂性。如果你可以用商业 MPP 或专栏商店解决你的问题,不要用复杂的生态系统让你未来的自己负担过重。确保你真的首先突破了传统方法的极限,而不仅仅是在赶时髦。
你是否发现了任何新的创新公司和/或解决方案?为什么你认为这些新玩家对分析的未来很重要?
我在 Strata 没有【找到他们】,但是看到他们真的很棒。我是 h2o 和他们正在做的工作的超级粉丝。他们真的在构建可扩展的尖端机器学习算法,并提供干净直观的界面。我认为天空是他们的极限。
当有看似无穷无尽的选择和组合时,组织如何知道他们将需要投资于哪些技术?
这可能是我能给出的最不受欢迎的答案,但最快的电脑是你明天就能买到的。纯粹的技术很少是一个组织能够获得最大价值的地方。除非您当前的工具真的已经用尽,并且您正在触及真正的限制,否则请好好审视一下您的方法和过程。你是否在遵循一种会产生结果的分析方法,或者说是虚荣的衡量标准?
Don’t start with the data, start with genuine impactful questions a human would ask.
不要从数据开始,从人类会问的真正有影响力的问题开始。购买能让你的现有员工尽可能高效工作的技术,确保他们拥有工作中实际需要的东西,并让他们进行原型制作和游戏。我的雇主在这方面做得很好——如果我们想测试一系列新技术,我们可以很快建立一个沙盒基础设施,并在现实世界中测试声明。如果你让人们参与进来,并给予他们创新的能力,他们会带着基于合理原则的可靠方法回来,而不是违背供应商的承诺。
你对明年圣何塞的 at Strata 有什么预测?
我希望看到成熟的生态系统,少谈辉煌的未来,多讨论当前的成功。我认为分析和 BI 领域的传统公司正在努力寻找立足点,即将在圣何塞举行的会议将提供透明度,将那些能够表明他们【明白】的人和那些将被落在后面的人区分开来。我认为到那时 Spark 平台将会稳定下来,所以期待看到大量的供应商谈论他们的平台现在是如何支持 Spark 的。Strata 不再是一个小小的数据科学会议;这在很大程度上是一个有大量行业参与者的主流会议,观看它的调整会很有趣。
对于试图将新的分析和大数据能力引入组织的公司,你有什么建议?
除非您 100%确定您拥有大数据并且需要大数据功能,否则不要轻易采用大数据工具链。任何大数据实施都会带来大量的技术债务,您只希望在绝对必要时才开始支付利息。
There is a great deal of technical debt that comes with any big data implementation, and you only want to start paying on that interest when it’s absolutely necessary.
至于分析,公司需要有正确的问题。几乎每个公司都希望有一个神奇的黑匣子,能够给出能够推动决策和指导总体业务的答案,但为了做到这一点,组织的数据必须足够丰富,领导层必须愿意在证据面前做出改变。无论你如何努力,方钉都插不进圆孔,所以确保你的组织真正准备好挑战关于它与客户、供应商的关系及其对周围世界的影响的基本假设。
对于想在数据科学领域发展事业的新人,你有什么建议?
我首先会问,“你为什么想成为一名数据科学家?”事实是,尽管这个领域现在很性感,数据科学是一个跨学科的领域,需要大量的努力,并且没有一条清晰的道路标明你走向数据科学家的头衔。
你的数据不会是干净的,你的大部分分析将是错误的和不确定的,当你发现一些有趣的东西时,你将不得不把你的发现展示给可能持怀疑态度的决策者。你是一个真正喜欢不断学习的人吗?我不是说,“你愿意被教导吗,”但是你是一个不断寻找新信息来源的人吗?这是第一部分。你有数学头脑吗?你不一定要有数学博士学位,但是如果没有统计学和线性代数的基础,作为一名数据科学家的生活将会很艰难。你很挑剔吗?你有能力看到关于标点错位的奇怪的错误信息,并从中找到一些反常的快乐吗?你怀疑吗?当有人递给你一个他们声称代表 X 的数据文件时,你是相信他们的话,还是质疑数据是否被正确地捕获、记录并交给你?
当你向一个在概念上难以理解的听众解释一些你觉得很基本的东西时,你会感到快乐吗?你可以拥有上面列出的每一项技能,但是如果你不能冷静、友好、友善地交流,这将是一个很难让你成功的领域。
This is a fantastically complex, wonderfully open, spectacularly interdisciplinary and rewarding field.
我不想听起来太消极,但这不是一个微不足道的领域,也不是一个可以掉以轻心的努力。这是一个极其复杂、极其开放、跨学科且回报丰厚的领域。如果你选择了它,并且成功了,你将会做一些(对外行人来说)和魔法没什么区别的事情。你将预测未来,你将发现谎言,你将告诉某人他们喜欢什么口味的冰淇淋,甚至在他们有机会思考这个问题之前。基础已经做好,基础已经打好,数据的秘密就等着解锁了。
我们非常感谢爱德华多抽出时间。可以跟着他@ earino
Domino 开放数据科学平台的更大灵活性:现在支持 Visual Studio 代码
By Chuck Head, Director, Customer Onboarding, Domino on October 14, 2019 in Product Updates
支撑 Domino 的核心原则之一是对开放性和灵活性的坚定承诺。我们的数据科学平台旨在为数据科学家提供协作和迭代工作的灵活性,而无需担心如何访问他们构建最佳模型所需的工具或基础架构。这种灵活性一直是 Domino 用户采用率增长和我们产品路线图发展的驱动力。
考虑到这一点,并根据客户的反馈,我们很高兴地分享 Domino 平台最近的一项增强,它为数据科学家提供了更多的灵活性: VS 代码现在作为标准环境中的一种新的工作空间类型受到支持。
对于寻求真正的 Python IDE 来支持 Jupyter 笔记本中没有的工作流(如调试 Python 代码)的客户来说,VS 代码是一个很好的选择。(有趣的事实:“‘标准环境’和‘vs code’”是 6 月份 Domino 客户支持站点中的前 10 大搜索查询。)
欲了解更多信息
- 这里有一个循序渐进的指南告诉你如何今天就去看看。
- 如果您是 Domino 的新手,您可以免费尝试一下数据科学平台。
- 你还想在多米诺里看到什么?在product@dominodatalab.comping 我们。
将学术研究人员带入企业数据科学世界
原文:https://www.dominodatalab.com/blog/moving-academic-researchers-corporate-data-science-world
本次网络研讨会录制于 2016 年 5 月 25 日
学术和企业环境中的数据科学实践存在巨大的文化差异。对于向企业数据科学转型的学术界人士,以及从学术界聘用人员的企业数据科学家来说,理解这些差异是成功转型的第一步。
在本次网络研讨会中,John Joo 博士解释了为什么数据科学与众不同,以及当人们从大学实验室转向数据驱动型企业时需要思考的问题。
https://player.vimeo.com/video/169579499?title=0&byline=0&portrait=0
关于演讲者
数据科学传道者 John Joo 负责公司的思想领导计划,并与 Domino 的客户交流最佳实践,以帮助他们改进数据科学计划。John 深厚的技术知识和他对行业需求和机会的透彻理解非常适合 Domino 充满活力的管理团队。
在加入 Domino 之前,John 在 Insight Data Science 担任了三年的项目总监和产品总监,在那里他开发并领导了数据科学项目的会议,还负责发展 Insight Data Science 社区。约翰拥有哈佛大学应用物理学博士学位。
更快发展:现代统计计算环境如何促进创新和加速临床试验?
采用新的工具和方法会促进更大的创新和更快地为有需要的患者开发新的疗法吗?这可能是 FDA 越来越接受在临床试验提交的统计分析和报告中使用 R 编程语言的结果,这长期以来几乎是 SAS 的专有领域。
Experis 的高级技术经理 Brian Varney 最近在 Bio-IT Worl d 中写道,这种接受已经到来了很长时间。
“模拟、期刊文章和其他类型的研究利用了 FDA 也将 R 用于各种任务,如检查公司的 SAS 生成的结果,”他在今年早些时候的一篇文章中写道。
“很明显,十多年来,人们对在临床提交工作中使用 R 的兴趣一直在慢慢增长;现在增长达到了历史最高水平,”他补充道。
越来越多的人接受 R 可以促进制药企业更大的灵活性
这种灵活性为使用 R 和 SAS 来制定监管提交文件提供了可能性,允许临床程序员使用最佳工具来完成工作,并加快为有需要的患者带来新治疗所需的分析。它也满足了临床编程组织的需要,即吸引并留住越来越多的精通并渴望利用 r。
是什么阻碍了临床编程组织急需的创新?
在我们的行业能够利用这种新的灵活性实现更大的创新和加速之前,必须解决几个相对重要的问题。有多少组织准备用两种语言进行临床试验分析和报告?更重要的是,统计计算环境 (SCE)需要具备哪些能力才能让组织发展和利用这种灵活性?
要回答这些问题,我们需要看看是什么抑制了制药创新。Domino 与许多领先的制药公司合作过,这些公司经常遇到三大挑战:不灵活的基础设施、协作困难和效率的普遍问题,尤其是在利用现代技术和 r。
例如,我们已经看到一些公司为了能够利用 R Studio 提供的所有功能而努力为 R 和 sa 需要单独的环境。这留下了一个集成问题,它使技术解决方案和业务流程变得复杂,导致许多方面的延迟,阻止了预期的高质量临床提交的加速。
现代 SCE 解决方案如何提供帮助
制药公司需要的是一个灵活的多语言、多 IDE 统计计算环境,它允许临床编程团队在一个研究分析项目中在统一的用户体验下使用 R Studio 和 SAS Studio。这有助于:
- 研究团队能够在通用工作流程中轻松利用每个人的优势和技能,让每个团队更快地前进。
- 临床程序员以他们自己的速度变得更加精通 R,而不影响团队的速度。
- 临床程序员可以在熟悉的用户体验中轻松利用开源社区并为之做出贡献。
- 临床程序员可以在研究中轻松使用 R Shiny 应用程序,以最大限度地减少工作量
灵活的新环境为创新铺平了道路
为了最大限度地提高临床试验的速度,Domino 通过让临床程序员能够最佳地利用 SAS 和 R,以及在有意义的时候轻松地整合新语言和工具的能力,来满足创新的需求。此外,Domino 允许配置不同的工作流来最大限度地满足某个目的,无论是研究分析和报告、运行特定的分析、开发模型,还是开发和部署闪亮的应用程序,等等。此外,Domino 健壮的 API 允许它很容易地集成到端到端的临床研究工作流中,以实现流线化和端到端加速。
要了解更多关于如何刺激制药行业创新的信息,请于 9 月 19 日至 21 日访问 PHUSE CSS 的 Domino 数据实验室,或阅读我们的白皮书,解释为什么成功的数字化转型需要灵活的 SCE。
使用 R 和 Python 的多核数据科学
原文:https://www.dominodatalab.com/blog/multicore-data-science-r-python
这篇文章展示了许多不同的包和方法,用于利用 R 和 Python 的并行处理。
R 和 Python 中的多核数据科学
时间是宝贵的。数据科学涉及越来越苛刻的处理要求。从训练越来越大的模型,到特征工程,到超参数调整,处理能力通常是实验和构思的瓶颈。
利用云上的大型机器实例,数据科学家可以在更大的数据集、更复杂的模型和要求更高的配置上使用他们已经知道并喜欢的统计编程环境,如 R 和 Python。拥有 128 个内核和 2tb 内存的大规模硬件,如 AWS X1 instances ,已经突破了不需要复杂、难以管理、不熟悉的分布式系统就能完成的极限。
利用更大的数据集和更强的处理能力,数据科学家可以进行更多实验,对解决方案更有信心,并为业务构建更准确的模型。并行处理过去需要专业的技能和理解,利用细粒度多线程和消息传递的基本构建块。现代数据科学堆栈提供了高级 API,数据科学家可以利用大型计算实例,同时在他们最高效的抽象级别工作。
在关于 R 和 Python 视频的多核数据科学中,我们介绍了许多 R 和 Python 工具,这些工具允许数据科学家利用大规模架构来收集、写入、转换和操作数据,以及在多核架构上训练和验证模型。您将看到样本代码、真实世界的基准测试,以及使用 Domino 在 AWS X1 实例上运行的实验。
对于 R,我们涵盖了并行包、数据表、插入符号和 multidplyr。在 Python 中,我们涵盖了 paratext、joblib 和 scikit-learn。
最后,我们展示了数据科学家可以利用多核架构的强大语言无关工具。在视频中,我们使用了 H2O.ai 和 xgboost——这两个尖端的机器学习工具可以通过设置单个参数来利用多核机器。
https://www.youtube.com/embed/6RwPR4OzwaI?feature=oembed
下面是完整视频中包含的材料示例。
r 包
平行包装
Package parallel 最初包含在 R 2.14.0 中,它为 apply 的大部分功能提供了嵌入式并行替代,集成了随机数生成处理。并行可以在许多不同层次的计算中完成:这个包主要关注“粗粒度并行化”。关键的一点是,这些计算块是不相关的,不需要以任何方式进行通信。
在这个示例代码中,我们利用 parallel 从一个文件夹中并行读取一个包含 100 个 csv 文件的目录。这可以让我们利用多核架构来更快地解析和接收磁盘上的数据。
library(parallel)
numCores <- detectCores() # get the number of cores available
results <- mclapply(1:100,
FUN=function(i) read.csv(paste0("./data/datafile-", i, ".csv")),
mc.cores = numCores)
这段代码中引入的第一个多核概念在第 3 行,在这里我们调用 detectCores()函数来检索该进程可用的内核数。这将查询底层操作系统,并返回一个表示处理器数量的整数。值得注意的是,最佳并行性通常并不意味着使用所有可用的内核,因为它可能会使其他资源饱和并导致系统崩溃,因此请记住进行实验和基准测试。
在第 5 行,我们调用从并行包导入的 mclapply()(或多核 lapply)函数。这几乎是 R 的古老的 lapply 功能的替代物。
从业者应该意识到两个不同之处:
- mc.cores 参数为用户提供了一种设置要利用的内核数量的方法(在我们的示例中,只需检测到所有内核)。
- FUN 中的代码是在一个单独的 R 进程中执行的,因此继承了分叉语义。
主要的要点是,访问全局变量和处理全局状态必然与所有代码在单个进程中执行时不同。
Parallel 提供了一个很好的工具,通过一些小的调整就可以快速扩展现有的代码。随着内核数量的增加,衡量真正的性能非常重要,并且要记住,如果使用全局变量,分叉语义将需要对代码进行一些重组,但是如果您想将代码速度提高 100 倍以上,这一切都是值得的!
数据表
Data.table 是一个古老而强大的包,主要由 Matt Dowle 编写。它是 R 的数据帧结构的高性能实现,具有增强的语法。有无数的基准测试展示了 data.table 包的强大功能。它为最常见的分析操作提供了高度优化的表格数据结构。
Matt Dowle 警告不要在多核环境中使用 data.table,那么为什么要在多核网络研讨会和博客文章中讨论它呢?在 2016 年 11 月宣布,data.table 获得了 fwrite 的完全并行化版本!允许 R 以显著的加速写出数据!
在这个示例代码中,我们使用 data.table fwrite 包来编写一个利用多核架构的大型 CSV。
library(parallel)
library(data.table)
numCores <- detectCores()
nrows_mult <- 1000
ncols_mult<- 1000
big_data <- do.call("rbind", replicate(nrows_mult, iris, simplify = FALSE))
big_data <- do.call("cbind", replicate(ncols_mult, big_data, simplify = FALSE))
fwrite(big_data, "/tmp/bigdata.csv", nThread=numCores)
在第 6-10 行中,我们多次复制 iris 数据集,使其成为一个非常大的内存数据结构。使用标准工具写入磁盘会花费大量时间。
为了利用多个内核,在第 12 行,我们使用参数 nThread 调用 fwrite()函数,参数是我们在第 4 行检测到的内核数量。在这种情况下,并行性的数量是有限制的,因为 io 子系统可能无法跟上大量的线程,但正如视频中的基准测试所示,它可以产生重大影响;有时候,写出文件的速度快 50%是成功与失败的区别。
脱字号
caret 包(分类和回归训练)是一组功能,用于简化创建预测模型的过程。该软件包包含用于数据分割、预处理、特征选择、模型调整使用重采样、变量重要性估计和其他功能的工具。
r 中有许多不同的建模函数。有些函数有不同的模型训练和/或预测语法。该包最初是作为一种为函数本身提供统一接口的方式,以及标准化常见任务,如参数调整和变量重要性。
caret 包无缝、轻松地利用多核功能。它利用了模型训练中的许多操作(例如使用不同超参数的训练和交叉验证)是并行的这一事实。
在示例代码中,我们利用 caret 的多核能力来训练 glmnet 模型,同时进行超参数扫描和交叉验证:
library(parallel)
library(doMC)
library(caret)
numCores <- detectCores()
registerDoMc(cores = numCores)
model_fit<- train(price ~ ., data=diamonds, method="glmnet", preProcess=c("center", "scale"), tuneLength=10)
这段代码现在应该看起来很熟悉了。主要的区别出现在第 2 行,这里我们包含了 doMC 包。这个包为 caret 包提供了一个多核“后端”,并处理所有内核间的任务分配。
在第 6 行,我们记录了 doMC 集群可用的内核数量。
在第 8 行,我们训练模型,对值做一些预处理。
不需要将核心数量传递给 caret,因为它会自动从已经创建的集群中继承该信息。
有许多参数可以传递给 caret。在本例中,我们传递的 tuneLength 为 10,这创建了一个由超参数组成的大型调整网格。这将创建几十个甚至几百个具有不同配置的模型,并在优化最有意义的指标的基础上为我们提供最佳模型,在本例中为 RMSE。
多层
Multidplyr 是一个用于将数据帧划分到多个内核的后端。您告诉 multidplyr 如何用 partition()分割数据,然后数据会保留在每个节点上,直到您用 collect()显式检索它。这最大限度地减少了移动数据所花费的时间,并最大限度地提高了并行性能。
由于与节点间通信相关的开销,对于少于 1000 万次观察的基本 dplyr 动词,您不会看到太多的性能改进。但是,如果您使用 do()进行更复杂的操作,您会发现改进速度会更快。
在示例代码中,我们使用 multidplyr 在数据集上训练大量 GAM 模型:
library(multidplyr)
library(dplyr)
library(parallel)
library(nycflights13)
numCores <- detectCores()
cluster <- create_cluster(cores)
by_dest <- flights %>%
count(dest) %>%
filter(n >= 365) %>%
semi_join(flights, .) %>%
mutate(yday = lubridate::yday(ISOdate(year, month, day))) %>%
partition(dest, cluster = cluster)
cluster_library(by_dest, "mgcv")
models <- by_dest %>%
do(mod = gam(dep_delay ~ s(yday) + s(dep_time), data = .))
这段代码比我们前面的例子稍微复杂一些。主要区别在于,在第 8 行中,我们使用第 6 行中检测到的内核数量来显式初始化集群。
multidplyr 包可以处理启动集群的所有潜在挑战,并通过简化的界面以透明的方式为我们处理这些挑战。
第 10-15 行我们获取航班数据集,对其进行一些特征工程,然后将其划分到第 15 行的集群中。
这意味着我们获取数据集的子集,并将其发送到每个内核进行处理。这种抽象比其他抽象(如 caret 的抽象)处于更低的层次,但它确实让我们有相当大的能力来决定代码如何在多个内核之间准确分布。
在第 17 行,我们向集群广播,为了执行下面的管道,它将需要“mgcv”库。
最后,在第 18 行和第 19 行,我们跨集群并行训练了大量 GAM 模型,每个模型都按目的地进行了划分。
Multidplyr 仍然是一个早期的包,Hadley 和他的团队正在使用它来研究和理解如何将多核技术引入 tidyverse。它现在对许多用例都很有用,并且是未来事物的一个激动人心的预览。
Python 包
副档名
读取 CSVs can 是一项耗时的任务,通常会成为数据处理的瓶颈。如果您正在利用具有几十个内核的大规模硬件,那么当您在读取 CSV 文件时,看到您的服务器大部分时间处于空闲状态,因为一个内核的利用率为 100%,这可能会令人感到羞愧。
paratext 库为 CSV 读取和解析提供了多核心处理。ParaText 是一个 C++库,用于在多核机器上并行读取文本文件。alpha 版本包括一个 CSV 阅读器和 Python 绑定。除了标准库之外,库本身没有依赖关系。
根据我们的基准,ParaText 是世界上最快的 CSV 阅读库。
在示例代码中,我们使用 paratext 读取一个非常大的 CSV,同时利用所有可用的内核。
import paratext
import pandas as pd
mydf = paratext.load_csv_to_pandas("data/big_data.csv")
在这段极其简单的代码中,我们加载 paratext 库并使用 load_csv_to_pandas 函数从 big_data.csv 创建 pandas 数据帧。该函数将自动利用最佳数量的内核并提供显著的加速。
paratext 的惟一挑战是在您的特定环境中构建它并不容易。然而,在安装之后,它以最小的努力提供了显著的性能。
Joblib
Joblib 是一组用于 Python 中轻量级管道的工具。特别是,joblib 提供:
- 输出值的透明磁盘缓存和惰性重新评估(记忆模式)
- 简单易行的并行计算
- 记录和跟踪执行
Joblib 经过优化,特别是在处理大型数据时,速度更快、更健壮,并且针对 numpy 数组进行了特定的优化。Joblib 是 Python 中并行处理的基本构建块,不仅用于数据科学,还用于许多其他分布式和多核处理任务。
在示例代码中,joblib 用于查找哪些线段完全包含在群体中的其他线段中,这是一项令人尴尬的并行任务:
import numpy as np
from matplotlib.path import Path
from joblib import Parallel, delayed
## Create pairs of points for line segments
all_segments = zip(np.random.rand(10000,2), np.random.rand(10000,2))
test_segments = zip(np.random.rand(800,2),np.random.rand(800,2))
## Check if one line segment contains another.
def check_paths(path):
for other_path in all_segments:
res='no cross'
chck = Path(other_path)
if chck.contains_path(path)==1:
res= 'cross'
break
return res
res = Parallel(n_jobs=128) (delayed(check_paths) (Path(test_segment)) for test_segment in test_segments)
直到第 19 行的所有代码都在设置我们的环境。生成要验证的线段和线段,并创建一个名为 check_paths 的函数来遍历线段并检查其中是否包含其他线段。
第 19 行是我们对 joblib 的调用,其中我们创建了一个有 128 个线程的并行对象(这是在 AWS X1 实例上运行的)。它遍历 test_segments 中的值,为该 test_segment 创建一个 path 对象,然后为创建的对象调用 check_paths 函数。
注意,对 check_paths 的调用包装在 delayed()中,这允许 joblib 调度它,而不是立即执行它。
Scikit-learn
Scikit-learn 是一个免费的 Python 编程语言的机器学习库。它具有各种分类、回归和聚类算法,包括支持向量机、随机森林、梯度推进、k-means 和 DBSCAN。它旨在与 Python 数字和科学库 NumPy 和 SciPy 进行互操作。
Scikit-learn 通过简单使用 n_jobs 参数使利用大型多核服务器变得容易。这适用于多模型、网格搜索、交叉验证等。
在示例代码中,我们训练了一个 RandomForestClassifier 来利用多个并行内核预测 iris 数据集中的物种:
from sklearn.ensemble import RandomForestClassifier
from sklearn import metrics, datasets
iris = datasets.load_iris()
X = iris.data[:, :2] # we only take the first two features.
Y = iris.target
md = RandomForestClassifier(n_estimators = 500, n_jobs = -1)
md.fit(X, y)
scikit-learn 多核功能的强大之处在 online 8 中展示:为了利用任何系统上可用的所有内核,我们只需将值-1 传递给 n_jobs 参数。
没有必要建立一个集群,自省机器,或任何其他东西...这个简单的参数通常可以在 scikit-learn 的机器学习模型的训练中提供 100 倍的加速。
不是所有的模型都提供 n_jobs 参数,但是 scikit-learn 文档提供了一种方法来确定您的特定分类器是否支持这种简单的并行化。
了解更多,包括 H2O 和 Xgboost
观看关于 R 和 Python 的多核数据科学的完整视频,了解 h2o 和 xgboost 中的多核功能,这是当今最流行的两个机器学习包。
在超级计算机级别的硬件上使用世界上最尖端的软件是一种真正的特权。看到这些工具在我的数据科学实践中让我变得更有效率是令人兴奋的,并且希望以类似的方式影响你。
Domino Enterprise MLOps platform通过强大的环境管理工具提供对大规模计算环境的访问,使得在大型硬件上测试该软件和管理这些包的多个版本的配置变得容易。
如果你有兴趣了解更多,你可以请求一个 Domino 的演示。
用 Python 进行 n 次射击和零次射击学习
原文:https://www.dominodatalab.com/blog/n-shot-and-zero-shot-learning-with-python
介绍
在之前的一篇帖子中,我们谈到了深度学习神经网络的进步如何使学习性能得到了显著改善,从而导致它们在计算机视觉等一些领域占据主导地位。我们还指出了一些阻碍复杂机器学习模型更广泛采用的障碍。在许多情况下,训练模型需要大型的带注释的数据集,这在某些领域(例如医学领域)中可能并不总是可用的。此外,在多类别分类中,类别不平衡带来了额外的挑战。此外,由于输入要素和要素分布的差异,在一个数据集上训练的模型在另一个数据集上可能表现不佳。最重要的是,最先进模型的增长的计算需求经常阻止我们从头开始训练复杂的模型。为了避免这些问题,并利用神经网络的能力,一种简单的方法是利用日益流行的传递函数方法。该函数允许使用来自预训练模型的权重来构建新模型,该预训练模型已经在一个任务(例如,分类)和一个数据集(例如,作为最大的开源数据集之一的 ImageNet)上被训练过,并且允许在类似的任务和不可见的数据集上使用新模型。
迁移学习背后的直觉是,如果两个问题中的数据集包含相似的数据点,它们的特征表示也是相似的,因此从一个训练中获得的权重可以用于解决后续的相似问题,而不是使用随机权重和从头开始的模型训练。预训练模型可以更快地适应第二个任务,因为它们已经包含来自第一个任务的训练权重。我们已经向展示了使用预先训练好的模型(通过拥抱脸)来解决 NLP 问题。现在,让我们看看如何在缺乏例子或根本没有标记数据的情况下应用迁移学习。
什么是 N-shot 学习?
大型数据集的可用性,包括超过 1000 个类的 ImageNet,对 GPU 和云计算的访问,以及深度学习的进步,允许开发高度精确的模型来解决许多领域的问题。如前所述,这些模型可以通过迁移学习重复使用,以解决类似数据的问题。
迁移学习的主要要求是可获得大规模数据用于培训。这并不总是可能的,一些现实世界的问题受到数据稀缺的困扰。例如,大约有 369,000 种维管植物是已知的开花植物。其中之一是尸体百合,它是已知最大的花。这是一种罕见的植物,因此在给定的计算机视觉分类任务中,与更常见的开花植物相比,这种植物的图像要少得多。
迁移学习方法的变体旨在解决围绕数据可用性的这一关键问题,以及培训时间和高基础设施成本等其他挑战。这些变体中的一些旨在用少量的例子实现学习,试图模仿人类的过程。N-shot 学习(NSL)旨在使用训练集(D_{train})建立模型,该训练集由输入(x_i)及其输出(y _ I )[1-3]组成。这种方法已经被用来解决各种问题,包括对象识别[1],图像分类[4]和情感分类[5]。在分类任务中,该算法学习一个分类器(h)来预测相应(x_i)的标签(y_i)。通常,人们考虑的是 N -way-K-shot 分类,其中(D_train)包含来自(N)个类的(I = KN)个示例,每个类具有(K)个示例。少量回归估计一个回归函数(h),仅给定从该函数中采样的几个输入-输出样本对,其中输出(y_i)是因变量(y)的观察值,而(x_i)是记录自变量(x)的观察值的输入。此外,NSL 已被用于强化学习,只有有限的国家行动对轨迹,以确定最佳政策【6,7】。
一个镜头本质上是一个用于训练的例子,用(N)定义数据点的数量。NSL 主要有三种变体:少射、单射和零射。少量发射是最灵活的变体,具有用于训练的少量数据点,零发射是最受限制的,没有用于训练的数据点。我们将为零起点学习提供额外的背景和例子。
什么是零投学习?
零触发学习是迁移学习的一种变体,在培训期间没有要学习的标记示例。这种方法使用附加信息来理解看不见的数据。在这种方法中,学习三个变量。它们是输入变量(x)、输出变量(y)和描述任务的附加随机变量(T)。该模型因此被训练以学习(P(y | x,T)) [8]的条件概率分布。
在这里,我们将使用 Halder 等人(2020)提出的句子的任务感知表示(TARS)作为一种简单有效的方法,用于文本分类的少镜头甚至零镜头学习。这意味着您可以在没有很多训练示例的情况下对文本进行分类。该模型由 TARSClassifier 类[9]在 Flair 中实现。
下面我们将利用 TARS 进行零镜头分类和命名实体识别(NER)任务。在本教程中,我们将向您展示使用 TARS 的不同方式。我们将提供输入文本和标签,TARS 的 predict_zero_shot 方法将尝试将这些标签中的一个与文本进行匹配。
使用零触发学习进行文本分类
# Loading pre-trained TARS model for English
tars: TARSClassifier = TARSClassifier.load('tars-base')
# the sentence for classification
sentence = Sentence("The 2020 United States presidential election was the 59th quadrennial presidential election, held on Tuesday, November 3, 2020")
classes = ["sports", "politics", "science", "art"]
# predict the class of the sentence
tars.predict_zero_shot(sentence, classes)
# Print sentence with predicted labels
print("\n",sentence)
输出打印 TARS 分类器识别的类别:
Sentence: "The 2020 United States presidential election was the 59th quadrennial presidential election , held on Tuesday , November 3 , 2020" [− Tokens: 21 − Sentence-Labels: 'sports-politics-science-art': [politics (1.0)]”
使用零射击学习进行命名实体识别(NER)
# 1\. Load zero-shot NER tagger
tars = TARSTagger.load('tars-ner')
# 2\. Prepare some test sentences
sentences = [
Sentence("The Humboldt University of Berlin is situated near the Spree in Berlin, Germany"),
Sentence("Bayern Munich played against Real Madrid"),
Sentence("I flew with an Airbus A380 to Peru to pick up my Porsche Cayenne"),
Sentence("Game of Thrones is my favorite series"),
]
# 3\. Define some classes of named entities such as "soccer teams", "TV shows" and "rivers"
labels = ["Soccer Team", "University", "Vehicle", "River", "City", "Country", "Person", "Movie", "TV Show"]
tars.add_and_switch_to_new_task('task 1', labels, label_type='ner')
# 4\. Predict for these classes and print results
for sentence in sentences:
tars.predict(sentence)
print(sentence.to_tagged_string("ner"))
下面打印的输出标识了与每个实体相关联的 NER,而没有对模型进行显式训练来标识它。例如,我们正在寻找实体类,如“电视节目”(权力的游戏)、“车辆”(空中客车 A380 和保时捷卡宴)、“足球队”(拜仁慕尼黑和皇家马德里)和“河流”(施普雷)
The Humboldt <B-University> University <I-University> of <I-University> Berlin <E-University> is situated near the Spree <S-River> in Berlin <S-City> , Germany <S-Country>
Bayern <B-Soccer Team> Munich <E-Soccer Team> played against Real <B-Soccer Team> Madrid <E-Soccer Team>
I flew with an Airbus <B-Vehicle> A380 <E-Vehicle> to Peru <S-City> to pick up my Porsche <B-Vehicle> Cayenne <E-Vehicle>
Game <B-TV Show> of <I-TV Show> Thrones <E-TV Show> is my favorite series
什么是一次性学习?
术语“一次性”是由飞飞等人(2006)在一篇开创性的论文中创造的,该论文提出了一种用于对象分类的表征学习的贝叶斯框架的变体[1]。一次性学习允许从数据点的一个实例进行模型学习。这使得模型能够表现出与人类相似的学习行为。例如,一旦孩子观察到一个苹果的整体形状和颜色,他就能很容易地辨认出另一个苹果。在人类中,这可以通过一个或几个数据点来实现。这种能力非常有助于解决现实世界中的问题,在现实世界中,访问许多带标签的数据点并不总是可能的。
单次学习通常基于相似性、学习和数据来实现。在这个例子中,我们将使用基于相似性的连体网络(用于区分两个看不见的类)。连体神经网络是一类包含两个或更多相同子网的神经网络架构。相同在这里是指它们具有相同的配置,具有相同的参数和权重。两个子网络输出一个编码来计算两个输入之间的差异。same 网络的目标是使用相似性得分来分类两个输入是相同还是不同。
让我们使用 MNIST 数据集和 Keras 创建一个简单的一次性学习示例。
我们首先导入所有需要的 Python 模块,加载 MNIST 数据集,并对数据进行归一化和整形。
import numpy as np
from keras.datasets import mnist
import matplotlib.pyplot as plt
from tensorflow.keras import layers, models
# import keras as ks
import tensorflow as tf
import pickle
from tensorflow.keras.layers import Activation
from tensorflow.keras.layers import Flatten
from tensorflow.keras.layers import Dense
from tensorflow.keras.layers import Reshape
from tensorflow.keras.layers import Input
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Dot
from tensorflow.keras.layers import Lambda
from tensorflow.keras import backend as K
# import keras
import random
import tensorflow_addons as tfa
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
(X_train, Y_train), (X_test, Y_test) = mnist.load_data()
# We need to normalise the training and testing subsets
X_train = X_train.astype('float32')
X_train /= 255
X_train = X_train.reshape((len(X_train), np.prod(X_train.shape[1:])))
X_test = X_test.astype('float32')
X_test /= 255
X_test = X_test.reshape((len(X_test), np.prod(X_test.shape[1:])))
# Printing data shape
print("The shape of X_train and Y_train: {} and {} ".format(X_train.shape, Y_train.shape))
print("The shape of X_test and Y_test: {} and {} ".format(X_test.shape, Y_test.shape))
The shape of X_train and Y_train: (60000, 784) and (60000,)
The shape of X_test and Y_test: (10000, 784) and (10000,)
接下来,我们需要创建图像对。由于暹罗网络有两个输入通道,我们必须将输入数据成对排列。正对将包含属于同一类的两个图像,负对将包含属于不同类的两个图像。
class Pairs:
def makePairs(self, x, y):
num_classes = 10
digit_indices = [np.where(y == i)[0] for i in range(num_classes)]
pairs = list()
labels = list()
for idx1 in range(len(x)):
x1 = x[idx1]
label1 = y[idx1]
idx2 = random.choice(digit_indices[label1])
x2 = x[idx2]
labels += list([1])
pairs += [[x1, x2]]
label2 = random.randint(0, num_classes-1)
while label2 == label1:
label2 = random.randint(0, num_classes-1)
idx2 = random.choice(digit_indices[label2])
x2 = x[idx2]
labels += list([0])
pairs += [[x1, x2]]
return np.array(pairs), np.array(labels)
让我们组成一对。
p = Pairs()
pairs_train, labels_train = p.makePairs(X_train, Y_train)
pairs_test, labels_test = p.makePairs(X_test, Y_test)
labels_train = labels_train.astype('float32')
labels_test = labels_test.astype('float32')
接下来,我们定义距离度量(我们使用欧几里德距离)、损失函数(对比损失)和用于计算模型准确度的函数。
def euclideanDistance(v):
x, y = v
sum_square = K.sum(K.square(x - y), axis=1, keepdims=True)
return K.sqrt(K.maximum(sum_square, K.epsilon()))
def eucl_dist_output_shape(shapes):
shape1, shape2 = shapes
return (shape1[0], 1)
def contrastive_loss(y_original, y_pred):
sqaure_pred = K.square(y_pred)
margin = 1
margin_square = K.square(K.maximum(margin - y_pred, 0))
return K.mean(y_original * sqaure_pred + (1 - y_original) * margin_square)
def compute_accuracy(y_original, y_pred):
pred = y_pred.ravel() < 0.5
return np.mean(pred == y_original)
def accuracy(y_original, y_pred):
return K.mean(K.equal(y_original, K.cast(y_pred < 0.5, y_original.dtype)))
我们现在可以继续构建和编译模型了。我们将使用(786)输入层,它对应于一个 28x28 像素的矩阵,然后是三个具有 ReLU 激活的全连接层,以及两个 L2 归一化层。我们将编译模型并打印其层和参数的摘要。
input = Input(shape=(784,))
x = Flatten()(input)
x = Dense(64, activation='relu')(x)
x = Dense(128, activation='relu')(x)
x = Dense(256, activation='relu')(x)
x = Lambda(lambda x: K.l2_normalize(x,axis=1))(x)
x = Lambda(lambda x: K.l2_normalize(x,axis=1))(x)
dense = Model(input, x)
input1 = Input(shape=(784,))
input2 = Input(shape=(784,))
dense1 = dense(input1)
dense2 = dense(input2)
distance = Lambda(euclideanDistance, output_shape=eucl_dist_output_shape)([dense1, dense2])
model = Model([input1, input2], distance)
# Compiling and printing a summary of model architecture
model.compile(loss = contrastive_loss, optimizer="adam", metrics=[accuracy])
model.summary()
Model: "functional_47"
__________________________________________________________________________________________________
Layer (type) Output Shape Param # Connected to
==================================================================================================
input_36 (InputLayer) [(None, 784)] 0
__________________________________________________________________________________________________
input_37 (InputLayer) [(None, 784)] 0
__________________________________________________________________________________________________
functional_45 (Functional) (None, 256) 91584 input_36[0][0]
input_37[0][0]
__________________________________________________________________________________________________
lambda_35 (Lambda) (None, 1) 0 functional_45[0][0]
functional_45[1][0]
==================================================================================================
Total params: 91,584
Trainable params: 91,584
Non-trainable params: 0
我们现在可以对网络进行 10 个时期的训练,并捕捉训练期间训练和测试损失的变化。
# Prediction and printing accuracy
y_pred_te = model.predict([pairs_test[:, 0], pairs_test[:, 1]])
te_acc = compute_accuracy(labels_test, y_pred_te)
print("The accuracy obtained on testing subset: {}".format(te_acc*100))
The accuracy obtained on testing subset: 97.13000000000001
我们还可以绘制两个损失随时间的变化曲线,并检查曲线是否有过度拟合的迹象。
# Plotting training and testing loss
plt.figure(figsize=(20,8));
history_dict = history.history;
loss_values = history_dict['loss'];
val_loss_values = history_dict['val_loss'];
epochs = range(1, (len(history.history['val_accuracy']) + 1));
plt.plot(epochs, loss_values, 'y', label='Training loss');
plt.plot(epochs, val_loss_values, 'g', label='Testing loss');
plt.title('Model loss for one-shot training and testing subset of MNIST dataset');
plt.xlabel('Epochs');
plt.ylabel('Loss');
plt.legend();
结论
迁移学习及其变体(包括一次学习和零次学习)旨在解决一些基本障碍,如机器学习应用中面临的数据稀缺。从更少的数据中智能学习的能力使人工智能类似于人类学习,并为更广泛的采用铺平了道路。
参考
[1] L .飞飞、r .弗格斯和 p .佩罗娜,“对象类别的一次性学习”,《IEEE 模式分析和机器智能汇刊》,第 28 卷,第 4 期,第 594-611 页,2006 年。
[2]例如,Miller、N. E. Matsakis 和 P. A. Viola,“通过变换的共享密度从一个例子中学习”,IEEE 计算机视觉和模式识别会议论文集。CVPR 2000(目录。第 PR00662 号),2000 年,第一卷:电气和电子工程师学会,第 464-471 页。
[3] C. M. Bishop 和 N. M. Nasrabadi,《模式识别和机器学习》(第 4 期)。斯普林格,2006 年。
[4] O. Vinyals,C. Blundell,T. Lillicrap,D. Wierstra,“一次学习的匹配网络”,神经信息处理系统进展,第 29 卷,2016 年。
[5] M. Yu 等,“基于多种度量的多元少镜头文本分类”,arXiv 预印本 arXiv:1805.07513,2018。
[6] A. Grover,M. Al-Shedivat,J. Gupta,y .布尔达和 H. Edwards,“多智能体系统中的学习策略表示”,载于 2018 年机器学习国际会议:PMLR,第 1802-1811 页。
[7] Y. Duan 等,“一次性模仿学习”,神经信息处理系统进展,第 30 卷,2017。
[8] I .古德费勒、y .本吉奥和 a .库维尔,《深度学习》。麻省理工学院出版社,2016 年。
[9] K. Halder,A. Akbik,J. Krapac 和 R. Vollgraf,“用于一般文本分类的句子的任务感知表示”,载于第 28 届计算语言学国际会议论文集,2020 年,第 3202-3213 页。
使用 BiLSTM-CRF 网络构建命名实体识别模型
原文:https://www.dominodatalab.com/blog/named-entity-recognition-ner-challenges-and-model
在这篇博文中,我们提出了命名实体识别问题,并展示了如何使用免费的带注释的语料库和 Keras 来拟合 BiLSTM-CRF 模型。该模型实现了相对较高的准确性,文章中的所有数据和代码都是免费提供的。
什么是命名实体识别?
命名实体识别(NER)是一个自然语言处理问题,它涉及命名实体(人、地点、组织等)的定位和分类。)在非结构化文本中提到。这个问题在许多处理机器翻译、信息检索、聊天机器人等用例的 NLP 应用程序中使用。
命名实体所属的类别是预定义的,通常包含位置、组织、工作类型、个人姓名、时间等条目。
呈现给 NER 系统的非结构化文本的例子可以是:
“乔·拜登总统首次总统海外之旅访问欧洲”
处理完输入后,NER 模型可能会输出如下内容:
【总统】[头衔]【拜登】[姓名]出访【欧洲】[地理]总统首次海外之行
从这个例子可以看出,NER 任务可以分解成两个独立的任务:
- 首先,我们需要建立每个实体的边界(例如,我们需要对输入进行标记)
- 其次,我们需要将每个实体分配给一个预定义的类
处理命名实体识别(NER)问题
NER 问题通常可以用两种不同的方法来处理:
- 基于语法的技术 -这种方法涉及经验丰富的语言学家,他们手动定义实体识别的特定规则(例如,如果实体名称包含标记“John ”,则它是一个人,但如果它也包含标记“University ”,则它是一个组织)。这种手工制作的规则产生非常高的精度,但是它需要大量的工作来定义实体结构和捕获边界情况。另一个缺点是,保持这样一个基于语法的系统更新需要不断的人工干预,并且是一项费力的任务。
- 基于统计模型的技术 -使用机器学习,我们可以精简和简化构建 NER 模型的过程,因为这种方法不需要预定义的详尽命名规则集。统计学习过程可以从训练数据集中自动提取所述规则。此外,保持 NER 模型的更新也可以以自动化的方式进行。基于统计模型的技术的缺点是,自动提取一组全面的规则需要大量带标签的训练数据。
如何建立统计命名实体识别(NER)模型
在这篇博文中,我们将重点关注构建一个统计 NER 模型,使用免费提供的带注释的语料库进行命名实体识别。该数据集基于 GMB ( 格罗宁根字义库)语料库,并经过标记、注释和专门构建,以训练分类器来预测命名实体,如名称、位置等。数据集中使用的标签遵循 IOB 格式,我们将在下一节介绍这种格式。
IOB 格式
内-外-始(IOB)是计算机语言学中标记实体的常见格式,尤其是在 NER 上下文中。该方案最初由 Ramshaw 和 Marcus (1995)提出,IOB 标签的含义如下:
- I 前缀表示标签在组块内(即名词组、动词组等)。)
- O 前缀表示该令牌不属于任何块
- B 前缀指示该标签在一个组块的开始,该组块跟随另一个组块,在两个组块之间没有 O 标签
示例数据集中使用的实体标记如下:
| 标签 | 意为 | 例子 |
| 长狭潮道 | 地理 | 不列颠,英国 |
| (同 organic)有机 | 组织 | 国际原子能组织(International Atomic Energy Agency) |
| 每个 | 人 | 托马斯 |
| gpe | 地缘政治实体 | 巴基斯坦的 |
| 定时(timing 的缩写) | 时间 | 星期三 |
| 艺术 | 假象 | Pentastar |
| 前夕 | 事件 | 停战 |
| 精灵 | 自然现象 | H5N1 |
以下示例显示了 IOB 在类别标签上的应用:
| 令牌 | 标签 | 意为 |
| 乔治 | B-PER | 块的开始(B 标签),分类为人 |
| 是 | O | 令牌不属于任何区块 |
| 旅行 | O | 令牌不属于任何区块 |
| 到 | O | 令牌不属于任何区块 |
| 英格兰 | I-GEO | 在块(I 标签)内部,分类为地理 |
| 在 | O | 令牌不属于任何区块 |
| 星期日 | I-TIM | 块内,分类为时间 |
通用报告格式模型
条件随机场(CRF)是一种非常适合处理 NER 问题的统计模型,因为它考虑了上下文。换句话说,当 CRF 模型进行预测时,它通过将预测建模为图形模型,将相邻样本的影响考虑在内。例如,线性链 CRF 是一种流行类型的 CRF 模型,其假设当前单词的标签仅依赖于前一个单词的标签(这有点类似于隐马尔可夫模型,尽管 CRF 的拓扑是无向图)。
Figure 1 : A simple linear-chain conditional random fields model. The model takes an input sequence x (words) and target sequence y (IOB tags)
线性链 CRF(图 1)的一个问题是,它们只能捕获向前方向的标签之间的依赖性。如果模型遇到类似“约翰霍普金斯大学”的实体,它可能会将霍普金斯令牌标记为名称,因为模型对下游出现的大学令牌“视而不见”。解决这个挑战的一个方法是在输入(字)和 CRF 之间引入一个双向 LSTM (BiLSTM)网络。双向 LSTM 由两个 LSTM 网络组成,一个正向接收输入,另一个反向接收输入。组合两个网络的输出产生了提供关于围绕每个单独令牌的样本的信息的上下文。BiLSTM 的输出然后被馈送到线性链 CRF,该线性链 CRF 可以使用这种改进的上下文来生成预测。CRF 和 BiLSTM 的这种组合通常被称为 BiLSTM-CRF 模型(Lample 等人,2016 年),其架构如图 2 所示。
Figure 2 - Architecture of a BiLSTM-CRF model
数据探索和准备
我们首先导入摄取、探索性数据分析和模型构建所需的所有库。
import pickle
import operator
import re
import string
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from plot_keras_history import plot_history
from sklearn.model_selection import train_test_split
from sklearn.metrics import multilabel_confusion_matrix
from keras_contrib.utils import save_load_utils
from keras import layers
from keras import optimizers
from keras.models import Model
from keras.models import Input
from keras_contrib.layers import CRF
from keras_contrib import losses
from keras_contrib import metrics
接下来,我们阅读并浏览注释数据集。
data_df = pd.read_csv("dataset/ner_dataset.csv", encoding="iso-8859-1", header=0)
data_df.head()
这些属性的含义如下:
- 句子编号-句子 ID
- 单词-包含构成单个句子的所有单词
- POS -每个单词的词性标签,如 Penn Treebank 标签集中所定义
- Tag -每个单词的 IOB 标签
查看数据,我们看到每个句子只给出一次句子 ID(使用块的第一个单词),而“句子#”属性的其余值被设置为 NaN。我们将通过为所有剩余的单词重复 ID 来解决这个问题,这样我们就可以计算出有意义的统计数据。
data_df = data_df.fillna(method="ffill")
data_df["Sentence #"] = data_df["Sentence #"].apply(lambda s: s[9:])
data_df["Sentence #"] = data_df["Sentence #"].astype("int32")
data_df.head()
现在我们来计算一些关于数据的统计。
print("Total number of sentences in the dataset: {:,}".format(data_df["Sentence #"].nunique()))
print("Total words in the dataset: {:,}".format(data_df.shape[0]))
Total number of sentences in the dataset: 47,959
Total words in the dataset: 1,048,575
data_df["POS"].value_counts().plot(kind="bar", figsize=(10,5));
我们注意到语料库中的前 5 个词类是:
- 名词(如桌子)
- NNP -专有名词(如约翰)
- 介词 in(如 IN,of,like)
- DT 限定词
- JJ -形容词(如绿色)
data_df[data_df["Tag"]!="O"]["Tag"].value_counts().plot(kind="bar", figsize=(10,5))
根据上面的情节,我们了解到我们的许多句子都是以地理、时间、组织或人物开头的。
我们现在可以看看每个句子的单词分布。
word_counts = data_df.groupby("Sentence #")["Word"].agg(["count"])
word_counts = word_counts.rename(columns={"count": "Word count"})
word_counts.hist(bins=50, figsize=(8,6));
我们看到数据集中的平均句子包含大约 21-22 个单词。
MAX_SENTENCE = word_counts.max()[0]
print("Longest sentence in the corpus contains {} words.".format(MAX_SENTENCE))
Longest sentence in the corpus contains 104 words.
longest_sentence_id = word_counts[word_counts["Word count"]==MAX_SENTENCE].index[0]
print("ID of the longest sentence is {}.".format(longest_sentence_id))
ID of the longest sentence is 22480.
longest_sentence = data_df[data_df["Sentence #"]==longest_sentence_id]["Word"].str.cat(sep=' ')
print("The longest sentence in the corpus is:\n")
print(longest_sentence)
The longest sentence in the corpus is:
Fisheries in 2006 - 7 landed 1,26,976 metric tons , of which 82 % ( 1,04,586 tons ) was krill ( Euphausia superba ) and 9.5 % ( 12,027 tons ) Patagonian toothfish ( Dissostichus eleginoides - also known as Chilean sea bass ) , compared to 1,27,910 tons in 2005 - 6 of which 83 % ( 1,06,591 tons ) was krill and 9.7 % ( 12,396 tons ) Patagonian toothfish ( estimated fishing from the area covered by the Convention of the Conservation of Antarctic Marine Living Resources ( CCAMLR ) , which extends slightly beyond the Southern Ocean area ).
all_words = list(set(data_df["Word"].values))
all_tags = list(set(data_df["Tag"].values))
print("Number of unique words: {}".format(data_df["Word"].nunique()))
print("Number of unique tags : {}".format(data_df["Tag"].nunique()))
Number of unique words: 35178
Number of unique tags : 17
现在我们对数据稍微熟悉了一些,我们可以继续实现必要的特性工程。第一步是构建一个字典(word2index ),为语料库中的每个单词分配一个惟一的整数值。我们还构建了一个反向字典,将索引映射到单词(index2word)。
word2index = {word: idx + 2 for idx, word in enumerate(all_words)}
word2index["--UNKNOWN_WORD--"]=0
word2index["--PADDING--"]=1
index2word = {idx: word for word, idx in word2index.items()}
让我们看看字典里的前 10 个词条。请注意,我们在开头包含了两个额外的条目——一个用于未知单词,一个用于填充。
for k,v in sorted(word2index.items(), key=operator.itemgetter(1))[:10]:
print(k,v)
--UNKNOWN_WORD-- 0
--PADDING-- 1
truck 2
87.61 3
HAMSAT 4
gene 5
Notre 6
Samaraweera 7
Frattini 8
nine-member 9
让我们确认单词到索引和索引到单词的映射如预期的那样工作。
test_word = "Scotland"
test_word_idx = word2index[test_word]
test_word_lookup = index2word[test_word_idx]
print("The index of the word {} is {}.".format(test_word, test_word_idx))
print("The word with index {} is {}.".format(test_word_idx, test_word_lookup))
The index of the word Scotland is 15147.
The word with index 15147 is Scotland.
现在让我们为各种标签构建一个类似的字典。
tag2index = {tag: idx + 1 for idx, tag in enumerate(all_tags)}
tag2index["--PADDING--"] = 0
index2tag = {idx: word for word, idx in tag2index.items()}
接下来,我们编写一个自定义函数,它将迭代每个句子,并形成一个由每个标记、标记代表的词性及其标签组成的元组。我们将这个函数应用于整个数据集,然后看看语料库中第一个句子的转换版本是什么样子。
def to_tuples(data):
iterator = zip(data["Word"].values.tolist(),
data["POS"].values.tolist(),
data["Tag"].values.tolist())
return [(word, pos, tag) for word, pos, tag in iterator]
sentences = data_df.groupby("Sentence #").apply(to_tuples).tolist()
print(sentences[0])
[('Thousands', 'NNS', 'O'),
('of', 'IN', 'O'),
('demonstrators', 'NNS', 'O'),
('have', 'VBP', 'O'),
('marched', 'VBN', 'O'),
('through', 'IN', 'O'),
('London', 'NNP', 'B-geo'),
('to', 'TO', 'O'),
('protest', 'VB', 'O'),
('the', 'DT', 'O'),
('war', 'NN', 'O'),
('in', 'IN', 'O'),
('Iraq', 'NNP', 'B-geo'),
('and', 'CC', 'O'),
('demand', 'VB', 'O'),
('the', 'DT', 'O'),
('withdrawal', 'NN', 'O'),
('of', 'IN', 'O'),
('British', 'JJ', 'B-gpe'),
('troops', 'NNS', 'O'),
('from', 'IN', 'O'),
('that', 'DT', 'O'),
('country', 'NN', 'O'),
('.', '.', 'O')]
我们使用这个转换后的数据集来提取模型的特征(X)和标签(y)。我们可以看到 X 和 y 中的第一个条目是什么样子的,在这两个条目中已经填充了单词和标签。我们可以丢弃该部分语音数据,因为该特定实现不需要它。
X = [[word[0] for word in sentence] for sentence in sentences]
y = [[word[2] for word in sentence] for sentence in sentences]
print("X[0]:", X[0])
print("y[0]:", y[0])
X[0]: ['Thousands', 'of', 'demonstrators', 'have', 'marched', 'through', 'London', 'to', 'protest', 'the', 'war', 'in', 'Iraq', 'and', 'demand', 'the', 'withdrawal', 'of', 'British', 'troops', 'from', 'that', 'country', '.']
y[0]: ['O', 'O', 'O', 'O', 'O', 'O', 'B-geo', 'O', 'O', 'O', 'O', 'O', 'B-geo', 'O', 'O', 'O', 'O', 'O', 'B-gpe', 'O', 'O', 'O', 'O', 'O']
我们还需要用字典中相应的索引替换每个单词。
X = [[word2index[word] for word in sentence] for sentence in X]
y = [[tag2index[tag] for tag in sentence] for sentence in y]
print("X[0]:", X[0])
print("y[0]:", y[0])
X[0]: [19995, 10613, 3166, 12456, 20212, 9200, 27, 24381, 28637, 2438, 4123, 7420, 34783, 18714, 14183, 2438, 26166, 10613, 29344, 1617, 10068, 12996, 26619, 14571]
y[0]: [17, 17, 17, 17, 17, 17, 4, 17, 17, 17, 17, 17, 4, 17, 17, 17, 17, 17, 13, 17, 17, 17, 17, 17]
我们看到数据集现在已经被索引了。我们还需要将每个句子填充到语料库中的最大句子长度,因为 LSTM 模型期望固定长度的输入。这就是字典中额外的"- PADDING -"键发挥作用的地方。
X = [sentence + [word2index["--PADDING--"]] * (MAX_SENTENCE - len(sentence)) for sentence in X]
y = [sentence + [tag2index["--PADDING--"]] * (MAX_SENTENCE - len(sentence)) for sentence in y]
print("X[0]:", X[0])
print("y[0]:", y[0])
X[0]: [19995, 10613, 3166, 12456, 20212, 9200, 27, 24381, 28637, 2438, 4123, 7420, 34783, 18714, 14183, 2438, 26166, 10613, 29344, 1617, 10068, 12996, 26619, 14571, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
y[0]: [17, 17, 17, 17, 17, 17, 4, 17, 17, 17, 17, 17, 4, 17, 17, 17, 17, 17, 13, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
我们需要执行的最后一个转换是对标签进行一次性编码。:
TAG_COUNT = len(tag2index)
y = [ np.eye(TAG_COUNT)[sentence] for sentence in y]
print("X[0]:", X[0])
print("y[0]:", y[0])
X[0]: [19995, 10613, 3166, 12456, 20212, 9200, 27, 24381, 28637, 2438, 4123, 7420, 34783, 18714, 14183, 2438, 26166, 10613, 29344, 1617, 10068, 12996, 26619, 14571, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
y[0]: [[0\. 0\. 0\. ... 0\. 0\. 1.]
[0\. 0\. 0\. ... 0\. 0\. 1.]
[0\. 0\. 0\. ... 0\. 0\. 1.]
...
[1\. 0\. 0\. ... 0\. 0\. 0.]
[1\. 0\. 0\. ... 0\. 0\. 0.]
[1\. 0\. 0\. ... 0\. 0\. 0.]]
最后,我们将得到的数据集分成一个训练集和一个保留集,这样我们就可以测量分类器对未知数据的性能。
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.1, random_state=1234)
print("Number of sentences in the training dataset: {}".format(len(X_train)))
print("Number of sentences in the test dataset : {}".format(len(X_test)))
Number of sentences in the training dataset: 43163
Number of sentences in the test dataset : 4796
我们还可以将所有内容转换成 NumPy 数组,因为这使得向模型提供数据变得更加简单。
X_train = np.array(X_train)
X_test = np.array(X_test)
y_train = np.array(y_train)
y_test = np.array(y_test)
系统模型化
我们从计算最大单词长度开始。我们还设置了以下模型超参数:
- 稠密嵌入-稠密嵌入的维数
- LSTM 输出空间的 LSTM 单位维数
- LSTM_DROPOUT -为递归状态的线性变换而丢弃的 LSTM 单位的分数
- DENSE_UNITS -每个时间片的完全连接单元的数量
- BATCH_SIZE -训练批次中的样本数
- MAX_EPOCHS -训练时期的最大数量
WORD_COUNT = len(index2word)
DENSE_EMBEDDING = 50
LSTM_UNITS = 50
LSTM_DROPOUT = 0.1
DENSE_UNITS = 100
BATCH_SIZE = 256
MAX_EPOCHS = 5
我们从定义模型的架构开始。我们添加了一个输入层、一个嵌入层(将索引转换为密集矢量)、一个双向 LSTM 层和一个时间分布层(将密集输出层应用于每个时态切片)。然后,我们通过管道将其传输到 CRF 层,最后通过将其输入定义为输入层,将其输出定义为 CRF 层的输出来构建模型。
我们还设置了一个损失函数(对于线性链条件随机场,这只是负对数似然),并指定“准确性”作为我们将监控的度量。优化器设置为 Adam(金玛和巴,2015),学习率为 0.001。
input_layer = layers.Input(shape=(MAX_SENTENCE,))
model = layers.Embedding(WORD_COUNT, DENSE_EMBEDDING, embeddings_initializer="uniform", input_length=MAX_SENTENCE)(input_layer)
model = layers.Bidirectional(layers.LSTM(LSTM_UNITS, recurrent_dropout=LSTM_DROPOUT, return_sequences=True))(model)
model = layers.TimeDistributed(layers.Dense(DENSE_UNITS, activation="relu"))(model)
crf_layer = CRF(units=TAG_COUNT)
output_layer = crf_layer(model)
ner_model = Model(input_layer, output_layer)
loss = losses.crf_loss
acc_metric = metrics.crf_accuracy
opt = optimizers.Adam(lr=0.001)
ner_model.compile(optimizer=opt, loss=loss, metrics=[acc_metric])
ner_model.summary()
Model: "model_1"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_1 (InputLayer) (None, 104) 0
_________________________________________________________________
embedding_1 (Embedding) (None, 104, 50) 1759000
_________________________________________________________________
bidirectional_1 (Bidirection (None, 104, 100) 40400
_________________________________________________________________
time_distributed_1 (TimeDist (None, 104, 100) 10100
_________________________________________________________________
crf_1 (CRF) (None, 104, 18) 2178
=================================================================
Total params: 1,811,678
Trainable params: 1,811,678
Non-trainable params: 0
_________________________________________________________________
history = ner_model.fit(X_train, y_train, batch_size=BATCH_SIZE, epochs=MAX_EPOCHS, validation_split=0.1, verbose=2)
我们的模型有 180 万个参数,所以预计训练需要一段时间。
Train on 38846 samples, validate on 4317 samples
Epoch 1/5
- 117s - loss: 0.4906 - crf_accuracy: 0.8804 - val_loss: 0.1613 - val_crf_accuracy: 0.9666
Epoch 2/5
- 115s - loss: 0.1438 - crf_accuracy: 0.9673 - val_loss: 0.1042 - val_crf_accuracy: 0.9679
Epoch 3/5
- 115s - loss: 0.0746 - crf_accuracy: 0.9765 - val_loss: 0.0579 - val_crf_accuracy: 0.9825
Epoch 4/5
- 115s - loss: 0.0451 - crf_accuracy: 0.9868 - val_loss: 0.0390 - val_crf_accuracy: 0.9889
Epoch 5/5
- 115s - loss: 0.0314 - crf_accuracy: 0.9909 - val_loss: 0.0316 - val_crf_accuracy: 0.9908
评估和测试
我们可以从模型训练中检查损失和准确度图。它们看起来都可以接受,而且模型似乎没有过度拟合。模型训练肯定可以从一些超参数优化中受益,但这种类型的微调超出了本文的范围。
plot_history(history.history)
我们还可以通过测量保留集的预测精度来测试模型的泛化能力。
y_pred = ner_model.predict(X_test)
y_pred = np.argmax(y_pred, axis=2)
y_test = np.argmax(y_test, axis=2)
accuracy = (y_pred == y_test).mean()
print("Accuracy: {:.4f}/".format(accuracy))
Accuracy: 0.9905
看起来这个模型做得很好,但是这有点误导。这是一个高度不平衡的数据集,因为在训练和测试数据中存在非常大量的 O 标签。在包括各种标签类别的样本之间存在进一步的不平衡。更好的检查是为每个标签构建混淆矩阵,并基于这些矩阵判断模型性能。我们可以构造一个简单的 Python 函数来帮助检查单个标签的混淆矩阵。我们使用两个随机选择的标签来让我们了解单个标签的混淆矩阵是什么样子的。
def tag_conf_matrix(cm, tagid):
tag_name = index2tag[tagid]
print("Tag name: {}".format(tag_name))
print(cm[tagid])
tn, fp, fn, tp = cm[tagid].ravel()
tag_acc = (tp + tn) / (tn + fp + fn + tp)
print("Tag accuracy: {:.3f} \n".format(tag_acc))
matrix = multilabel_confusion_matrix(y_test.flatten(), y_pred.flatten())
tag_conf_matrix(matrix, 8)
tag_conf_matrix(matrix, 14)
Tag name: B-per
[[496974 185]
[ 441 1184]]
Tag accuracy: 0.999
Tag name: I-art
[[498750 0]
[ 34 0]]
Tag accuracy: 1.000
最后,我们通过构建一个样本句子并获得对检测到的实体的预测来运行一个手动测试。我们将所有单词标记、填充并转换成索引。然后我们调用模型并打印预测的标签。我们在测试中使用的句子是“奥巴马总统成为第一位访问广岛的在任美国总统”。
sentence = "President Obama became the first sitting American president to visit Hiroshima"
re_tok = re.compile(f"([{string.punctuation}“”¨«»®´·º½¾¿¡§£₤‘’])")
sentence = re_tok.sub(r" ", sentence).split()
padded_sentence = sentence + [word2index["--PADDING--"]] * (MAX_SENTENCE - len(sentence))
padded_sentence = [word2index.get(w, 0) for w in padded_sentence]
pred = ner_model.predict(np.array([padded_sentence]))
pred = np.argmax(pred, axis=-1)
retval = ""
for w, p in zip(sentence, pred[0]):
retval = retval + "{:15}: {:5}".format(w, index2tag[p])" + "\n"
print(retval)
President : B-per
Obama : I-per
became : O
the : O
first : O
sitting : O
American : B-gpe
president : O
to : O
visit : O
Hiroshima : B-geo
摘要
在这篇博文中,我们讨论了命名实体识别的用例及挑战,并使用 BiLSTM-CRF 模型给出了一个可能的解决方案。拟合的模型表现相当好,能够以相对较高的精度预测未知数据。
参考
Ramshaw 和 Marcus,使用基于转换的学习进行文本分块,1995 年, arXiv:cmp-lg/9505040 。
Guillaume Lample,Miguel Ballesteros,Sandeep Subramanian,Kazuya Kawakami,克里斯·戴尔,命名实体识别的神经架构,2016 年,计算语言学协会北美分会 2016 年会议记录:人类语言技术,第 260-270 页,https://www.aclweb.org/anthology/N16-1030/
Diederik P. Kingma 和 Jimmy Ba,Adam:一种随机优化方法,第三届学习表示国际会议,圣地亚哥,2015,https://arxiv.org/abs/1412.6980
使用 spaCy 的 Python 自然语言处理:简介
原文:https://www.dominodatalab.com/blog/natural-language-in-python-using-spacy
本文简要介绍了在 Python 中使用 spaCy 和相关库的自然语言。
介绍
行业中的数据科学团队必须处理大量文本,这是机器学习中使用的四大类数据之一。通常,它是人类生成的文本,但并不总是如此。
想一想:企业的“操作系统”是如何工作的?通常,有合同(销售合同、工作协议、合伙关系),有发票,有保险单,有法规和其他法律,等等。所有这些都表示为文本。
你可能会碰到几个缩略词:自然语言处理 (NLP),n 自然语言理解 (NLU),自然语言生成(NLG)——大致分别讲“读文本”、“理解意思”、“写文本”。这些任务越来越多地重叠,很难对任何给定的功能进行分类。
Spacy 是什么?
数据科学团队如何着手处理非结构化文本数据?团队经常求助于 Python 中的各种库来管理复杂的 NLP 任务。sPacy 是一个开源的 Python 库,它提供了进行高级自然语言处理分析和构建模型的能力,这些模型可以支持文档分析、聊天机器人功能和所有其他形式的文本分析。
spaCy 框架——以及范围广泛且不断增长的插件和其他集成——为广泛的自然语言任务提供了功能。它已经成为 Python 中用于行业用例的最广泛使用的自然语言库之一,并拥有相当大的社区——随着该领域的持续快速发展,对研究商业化的支持也在不断增加。
本文简要介绍了如何使用和相关库在 Python 中使用自然语言(有时称为“文本分析”)。
*## 入门指南
我们已经在 Domino 中配置了默认的计算环境,以包含本教程所需的所有包、库、模型和数据。查看 Domino 项目来运行代码。
如果您对 Domino 的计算环境如何工作感兴趣,请查看支持页面。
现在让我们加载空间并运行一些代码:
import spacy
nlp = spacy.load("en_core_web_sm")
那个nlp
变量现在是你通向所有事物空间的大门,并且装载了英语的en_core_web_sm
小模型。接下来,让我们通过自然语言解析器运行一个小“文档”:
text = "The rain in Spain falls mainly on the plain."
doc = nlp(text)
for token in doc:
print(token.text, token.lemma_, token.pos_, token.is_stop)
The DET True
rain rain NOUN False
in in ADP True
Spain Spain PROPN False
falls fall VERB False
mainly mainly ADV False
on on ADP True
the DET True
plain plain NOUN False
. . PUNCT False
首先,我们从文本创建了一个 doc ,它是一个文档及其所有注释的容器。然后我们遍历文档,看看空间解析了什么。
很好,但是信息太多,读起来有点困难。让我们将该句子的空间解析重新格式化为熊猫数据帧:
import pandas as pd
cols = ("text", "lemma", "POS", "explain", "stopword")
rows = []
for t in doc:
row = [t.text, t.lemma_, t.pos_, spacy.explain(t.pos_), t.is_stop]
rows.append(row)
df = pd.DataFrame(rows, columns=cols)
print(df)
可读性强多了!在这个简单的例子中,整个文档仅仅是一个简短的句子。对于句子中的每个单词,spaCy 已经创建了一个令牌,我们访问每个令牌中的字段来显示:
接下来,让我们使用 displaCy 库来可视化该句子的解析树:
from spacy import displacy
displacy.render(doc, style="dep")
这让我想起了小学时代吗?坦率地说,对于我们这些更多地来自计算语言学背景的人来说,这个图表激发了喜悦。
但是让我们先回顾一下。你如何处理多个句子?
句子边界检测(SBD)——也称为句子分割——基于内置/默认句子分析器的特征有:
text = "We were all out at the zoo one day, I was doing some acting, walking on the railing of the gorilla exhibit. I fell in.
Everyone screamed and Tommy jumped in after me, forgetting that he had blueberries in his front pocket. The gorillas just went wild."
doc = nlp(text)
for sent in doc.sents:
print(">", sent)
> We were all out at the zoo one day, I was doing some acting, walking on the railing of the gorilla exhibit.
> I fell in.
> Everyone screamed and Tommy jumped in after me, forgetting that he had blueberries in his front pocket.
> The gorillas just went wild.
当 spaCy 创建文档时,它使用了一个非破坏性标记化的原则,意味着标记、句子等。只是一个长数组的索引。换句话说,它们不会将文本流分割成小块。所以每个句子都是一个跨度,以开始和结束索引到文档数组中:
for sent in doc.sents:
print(">", sent.start, sent.end)
> 0 25
> 25 29
> 29 48
> 48 54
我们可以对文档数组进行索引,以提取一个句子的标记:
doc[48:54]
The gorillas just went wild.
或者简单地索引到一个特定的标记,比如最后一句中的动词went
:
token = doc[51]
print(token.text, token.lemma_, token.pos_)
went go VERB
此时,我们可以解析文档,将文档分割成句子,然后查看每个句子中标记的注释。这是一个好的开始。
获取文本
既然我们可以解析文本,那么我们从哪里获取文本呢?一个快速的来源是利用互联网。当然,当我们下载网页时,我们会得到 HTML,然后需要从中提取文本。美丽的汤是一种受欢迎的套餐。
首先,做一点家务:
import sys
import warnings
warnings.filterwarnings("ignore")
在下面的函数get_text()
中,我们将解析 HTML 以找到所有的<p/>
标签,然后提取这些标签的文本:
from bs4 import BeautifulSoup
import requests
import traceback
def get_text (url):
buf = []
try:
soup = BeautifulSoup(requests.get(url).text, "html.parser")
for p in soup.find_all("p"):
buf.append(p.get_text())
return "".join(buf)
except:
print(traceback.format_exc())
sys.exit(-1)
现在让我们从网上获取一些文本。我们可以比较开源倡议网站上托管的开源许可证:
lic = {}
lic["mit"] = nlp(get_text("https://opensource.org/licenses/MIT"))
lic["asl"] = nlp(get_text("https://opensource.org/licenses/Apache-20"))
lic["bsd"] = nlp(get_text("https://opensource.org/licenses/BSD-3-Clause"))
for sent in lic["bsd"].sents:
print(">", sent)
> SPDX short identifier: BSD-3-Clause
> Note: This license has also been called the "New BSD License" or "Modified BSD License"
> See also the 2-clause BSD License.
…
自然语言工作的一个常见用例是比较文本。例如,使用这些开源许可证,我们可以下载它们的文本,解析,然后比较它们之间的相似性度量:
pairs = [
["mit", "asl"],
["asl", "bsd"],
["bsd", "mit"]]
for a, b in pairs:
print(a, b, lic[a].similarity(lic[b]))
mit asl 0.9482039305669306
asl bsd 0.9391555350757145
bsd mit 0.9895838089575453
这很有趣,因为 BSD 和 T2 麻省理工学院的执照看起来是最相似的文件。事实上,它们是密切相关的。
诚然,由于页脚中的 OSI 免责声明,每个文档中都包含了一些额外的文本,但这为比较许可证提供了一个合理的近似值。
自然语言理解
现在让我们深入了解一下 NLU 的一些空间特征。假设我们有一个文档解析,从纯语法的角度来看,我们可以提取名词块,即每个名词短语:
text = "Steve Jobs and Steve Wozniak incorporated Apple Computer on January 3, 1977, in Cupertino, California."
doc = nlp(text)
for chunk in doc.noun_chunks:
print(chunk.text)
Steve Jobs
Steve Wozniak
Apple Computer
January
Cupertino
California
还不错。句子中的名词短语通常提供更多的信息内容——作为一个简单的过滤器,用于将一个长文档简化为一个更“精炼”的表示。
我们可以进一步采用这种方法,并在文本中识别出命名实体,即专有名词:
for ent in doc.ents:
print(ent.text, ent.label_)
Steve Jobs PERSON
Steve Wozniak PERSON
Apple Computer ORG
January 3, 1977 DATE
Cupertino GPE
California GPE
displaCy 库提供了一种可视化命名实体的极好方法:
displacy.render(doc, style="ent")
如果您正在使用知识图应用程序和其他链接数据,您的挑战是在文档中的命名实体和实体的其他相关信息之间构建链接,这被称为实体链接。识别文档中的命名实体是这种特定人工智能工作的第一步。例如,根据上面的文本,可以将Steve Wozniak
命名实体链接到 DBpedia 中的查找。
更一般地说,人们也可以将词条链接到描述其含义的资源。例如,在前面的部分中,我们分析了句子The gorillas just went wild
,并且能够表明单词went
的引理是动词go
。在这一点上,我们可以使用一个名为 WordNet 的古老项目,它提供了一个英语词汇数据库——换句话说,它是一个可计算的词库。
有一个针对 WordNet 的 spaCy 集成,叫做 spacy-wordnet ,作者是自然语言和知识图谱工作专家。
然后我们将通过 NLTK 加载 WordNet 数据(这些事情会发生):
import nltk
nltk.download("wordnet")
[nltk_data] Downloading package wordnet to /home/ceteri/nltk_data...
[nltk_data] Package wordnet is already up-to-date!
True
请注意,空间作为一个“管道”运行,并允许使用定制管道部件的方法。这对于支持数据科学工作中真正有趣的工作流集成非常有用。这里我们将添加来自 spacy-wordnet 项目的wordnet 注释器:
from spacy_wordnet.wordnet_annotator import WordnetAnnotator
print("before", nlp.pipe_names)
if "WordnetAnnotator" not in nlp.pipe_names:
nlp.add_pipe(WordnetAnnotator(nlp.lang), after="tagger")
print("after", nlp.pipe_names)
before ['tagger', 'parser', 'ner']
after ['tagger', 'WordnetAnnotator', 'parser', 'ner']
在英语中,有些词因有多种可能的含义而臭名昭著。例如,在 WordNet 搜索中点击搜索结果,找到与单词withdraw
相关的意思。
现在让我们使用 spaCy 来自动执行查找:
token = nlp("withdraw")[0]
token._.wordnet.synsets()
[Synset('withdraw.v.01'),
Synset('retire.v.02'),
Synset('disengage.v.01'),
Synset('recall.v.07'),
Synset('swallow.v.05'),
Synset('seclude.v.01'),
Synset('adjourn.v.02')
Synset('bow_out.v.02'),
Synset('withdraw.v.09'),
Synset('retire.v.08'),
Synset('retreat.v.04'),
Synset('remove.v.01')]
token._.wordnet.lemmas()
[Lemma('withdraw.v.01.withdraw'),
Lemma('withdraw.v.01.retreat'),
Lemma('withdraw.v.01.pull_away'),
Lemma('withdraw.v.01.draw_back'),
Lemma('withdraw.v.01.recede'),
Lemma('withdraw.v.01.pull_back'),
Lemma('withdraw.v.01.retire'),
…
token._.wordnet.wordnet_domains()
["astronomy",
"school",
"telegraphy",
"industry",
"psychology",
"ethnology",
"ethnology",
"administration",
"school",
"finance",
"economy",
"exchange",
"banking",
"commerce",
"medicine",
"ethnology",
"university",
…
同样,如果你正在使用知识图表,那些来自 WordNet 的“词义”链接可以和图表算法一起使用,来帮助识别特定单词的意思。这也可以用来通过一种叫做摘要的技术为较大的文本部分开发摘要。这已经超出了本教程的范围,但是这是目前自然语言在业界的一个有趣的应用。
反过来说,如果你知道先验一个文档是关于一个特定领域或一组主题的,那么你可以限制从 WordNet 返回的意思。在下面的示例中,我们希望考虑金融和银行业中的 NLU 结果:
domains = ["finance", "banking"]
sentence = nlp("I want to withdraw 5,000 euros.")
enriched_sent = []
for token in sentence:
# get synsets within the desired domains
synsets = token._.wordnet.wordnet_synsets_for_domain(domains)
if synsets:
lemmas_for_synset = []
for s in synsets:
# get synset variants and add to the enriched sentence
lemmas_for_synset.extend(s.lemma_names())
enriched_sent.append("({})".format("|".join(set(lemmas_for_synset))))
else:
enriched_sent.append(token.text)
print(" ".join(enriched_sent))
I (require|want|need) to (draw_off|withdraw|draw|take_out) 5,000 euros .
这个例子看起来很简单,但是如果你使用domains
列表,你会发现在没有合理约束的情况下,结果会有一种组合爆炸。想象一下,有一个包含数百万元素的知识图:您希望尽可能地限制搜索,以避免每个查询都需要花费数天/数周/数月/数年的时间来计算。
使用空间和散点图进行文本比较
有时候,当试图理解一个文本时遇到的问题——或者更好的是当试图理解一个语料库(一个包含许多相关文本的数据集)——变得如此复杂,以至于你需要首先将它可视化。这里有一个理解文本的交互式可视化:散射文本,是杰森·凯斯勒天才的产物。
让我们来分析 2012 年美国总统选举期间的政党大会的文本数据。注意:这个单元可能需要几分钟来运行,但是所有这些数字运算的结果是值得等待的。
import scattertext as st
if "merge_entities" not in nlp.pipe_names:
nlp.add_pipe(nlp.create_pipe("merge_entities"))
if "merge_noun_chunks" not in nlp.pipe_names:
nlp.add_pipe(nlp.create_pipe("merge_noun_chunks"))
convention_df = st.SampleCorpora.ConventionData2012.get_data()
corpus = st.CorpusFromPandas(convention_df, category_col="party", text_col="text", nlp=nlp).build()
准备好corpus
之后,生成一个 HTML 格式的交互式可视化:
html = st.produce_scattertext_explorer(corpus, category="democrat",
category_name="Democratic",
not_category_name="Republican",
width_in_pixels=1000,
metadata=convention_df["speaker"])
现在我们将渲染 HTML——给它一两分钟来加载,这是值得等待的:
from IPython.display import IFrame
file_name = "foo.html"
with open(file_name, "wb") as f:
f.write(html.encode("utf-8"))
IFrame(src=file_name, width = 1200, height=700)
想象一下,如果您有过去三年中您组织中特定产品的客户支持文本。假设您的团队需要了解客户是如何谈论产品的?这个散文本库可能会派上用场!你可以根据 NPS 得分(一个客户评估指标)进行聚类(k=2),然后用聚类中的前两个部分替换民主党/共和党维度。
摘要
五年前,如果你问关于自然语言的 Python 开源,许多从事数据科学的人的默认答案会是 NLTK 。那个项目包括除了厨房水槽以外的所有东西,并且有相对学术性的组成部分。另一个流行的自然语言项目是斯坦福大学的 CoreNLP 。虽然 CoreNLP 很强大,但也很学术,尽管 CoreNLP 在与其他软件集成以供生产使用方面存在挑战。
几年前,世界上这个自然语言的角落开始发生变化。《太空》()的两位主要作者、马修·洪尼巴尔和伊娜丝·蒙塔尼于 2015 年启动了该项目,该项目很快被业界采纳。他们专注于一种固执己见的方法(做需要做的事情,做好它,不多不少),这种方法提供了到 Python 中数据科学工作流的简单、快速的集成,以及比替代方案更快的执行速度和更好的准确性。基于这些优先级, spaCy 成为了 NLTK 的对立面。自 2015 年以来, spaCy 一直专注于成为一个开源项目(即依靠其社区获得方向、集成等。)并且是商业级软件(不是学术研究)。也就是说, spaCy 已经迅速将 SOTA 的进步融入到机器学习中,有效地成为将研究转移到工业的渠道。
值得注意的是,随着谷歌开始赢得国际语言翻译比赛,自然语言的机器学习在 2000 年代中期得到了很大的推动。另一个巨大的变化发生在 2017-2018 年期间,在深度学习的许多成功之后,这些方法开始超越以前的机器学习模型。例如,看看艾伦·艾(Allen AI)的 ELMo 关于语言嵌入的工作,接着是谷歌的 BERT,以及最近百度的ERNIE——换句话说,世界上的搜索引擎巨头给我们其他人提供了基于深度学习的开源嵌入式语言模型的芝麻街剧目,这是目前的艺术水平(SOTA)。说到这里,要跟踪自然语言的 SOTA,请留意代码为的 NLP-Progress 和论文。
在深度学习技术脱颖而出之后,自然语言的用例在过去两年中发生了巨大的变化。大约在 2014 年,Python 中的自然语言教程可能会显示字数或关键词搜索或情感检测,而目标用例相对来说并不令人印象深刻。大约在 2019 年,我们正在讨论分析工业供应链优化中数以千计的供应商合同文档...或者为保险公司的投保人提供数亿份文档,或者关于财务披露的大量文档。更多的当代自然语言工作倾向于在 NLU 进行,通常是为了支持知识图表的构建,并且越来越多地在 NLG 进行,在那里大量相似的文档可以在人类尺度上进行总结。
spaCy Universe 是一个很好的地方,可以深入研究特定的用例,看看这个领域是如何发展的。从这个“宇宙”中选择的一些包括:
此外,还有几个超级新项目值得一提:
- spacy-py torch-transformers微调(即使用转移学习)芝麻街人物和朋友:伯特、GPT-2、XLNet 等。
- spaCy IRL 2019 会议–查看会议视频!
关于空间*,我们可以做的事情太多了——希望这篇教程只是一个介绍。我们祝你在自然语言工作中一切顺利。**
需要打破模型驱动决策的阻力?
原文:https://www.dominodatalab.com/blog/need-to-break-down-resistance-to-model-driven-decision-making
By Karina Babcock, Director Corporate Marketing, Domino on May 14, 2019 in Perspective
在 Rev 2 加入我们,聆听好事达的 Eric Huls 讨论他如何在保守行业推动数据科学创新
在数据和分析方面,您多久会遇到一次来自业务人员和最终用户的阻力?许多数据科学领导者说,他们许多最重要的工作在模型开发开始之前就已经开始了;因为虽然数据科学可能令人兴奋,但也有很多来自企业和最终用户的怀疑。
对于企业领导来说,质疑模型驱动的价值、模型输出的准确性甚至数据科学建议的适用性并不奇怪。毕竟,他们深厚的行业知识和密切的客户关系,经过多年的磨练,已经成功地引导了他们公司过去的增长。组织孤岛和传统的绩效衡量系统通常会将业务团队的注意力放在短期目标而不是长期机会上,从而使问题复杂化。
当您的数据科学团队与业务团队分享新的机会和想法时,他们会听到这样的评论吗:
- “我们通过这种方式取得了成功;为什么要改变?”
- 这些模型没有反映出我们的经验告诉我们的东西
- “我知道什么对我的业务部门最有利。”
- “我不需要你关注这个更大的问题;我只是需要数据来支持这个决定。”
如果答案是肯定的,可以考虑参加下周在纽约举行的 Eric Huls 的 Rev 2 发布会。美国最大的保险公司之一好事达保险公司(Allstate)的首席数据和分析官 Eric 将深入探讨变革的话题,并分享他的团队在转变公司文化以在业务的各个方面采用模型方面的策略。
Eric 在这个问题上有很好的观点,特别是在推动大型保守公司的创新方面(当涉及到最终用户阻力时,这些公司可以说是最具挑战性的领域之一)。19 年前,当 Eric 作为精算定价分析师加入好事达时,该公司主要使用分析来预测风险和通知费率。现在,将近 20 年过去了,Eric 领导着一个 300 多人的团队,构建数据和分析解决方案来创建数百万个有针对性的数字媒体印象,处理数万个索赔,生成数万个报价,并预测组织各个部门(从产品、销售、运营、营销到索赔)的数千个决策行动。
埃里克是如何取得成功的?请于 5 月 23 日星期四在纽约参加 Rev 2,聆听 Eric 的演讲。
您将了解到:
- 是什么阻止了老牌公司全面采用分析技术
- 推动分析采用和打破长期信念的正确和错误方式
- 以分析为核心重建公司文化的建议
- 为什么创建一个以目标为导向的数据和分析团队很重要,以及 Eric 如何使他的团队成为好事达的强大代表
今年的会议将于 5 月 23 日至 24 日在纽约举行,60 多位行业领袖分享了对当今数据科学最大挑战的见解,从扩展模型和建立模型驱动的文化到确保负责任的人工智能,会议为从业者和领导者定制。
AWS 中的新 G3 实例——机器学习值得吗?
原文:https://www.dominodatalab.com/blog/new-g3-instances-in-aws-worth-it-for-ml
我们对 AWS 的新 G3 实例进行了深度学习任务的基准测试,发现它们明显优于旧的 P2 实例。新的 G3 实例现在可以在 Domino 中使用了。
AWS 最近宣布一个新的 GPU 驱动的 EC2 实例类型,G3。这些新的 G3 实例现在在 Domino 上可用,因此您可以使用它们来运行您的数据科学工作负载,只需一次点击和零设置。
AWS 中基于 GPU 的 EC2 实例
根据 AWS 的说法, G3 实例是为 3D 可视化等图形密集型应用而构建的,而 P2 实例是为机器学习和计算金融等通用 GPU 计算而构建的。我们想知道 G3 实例与 P2 实例相比表现如何。对于一些深度学习应用程序来说,价格更高的 G3 实例值得吗?我们将回顾 AWS 基于 GPU 的实例的规范,根据卷积神经网络和递归神经网络对实例进行基准测试,并查看性能与其成本的对比情况。
我们首先比较了支持 G3 实例和 P2 实例的 GPU 的规格。G3 实例由 NVIDIA Tesla M60 GPUs 提供支持。M60 GPUs 拥有比 k80 或 K520 GPUss 更新的架构,k80 或 K520 GPU 分别支持 AWS P2 和 G2 实例,因此您可以期待更好的性能。但是,神经网络中的 GPU 性能是许多因素的组合:
- 大量的 CUDA 内核将会增加计算的并行性。
- 当您训练神经网络时,GPU 上的大内存大小将让您拥有更大的批处理大小。
- 高内存带宽将允许您快速与 CPU 通信。如果你拥有世界上最高性能的 GPU,却不能将 GPU 上的信息快速传回 CPU,那么你最终将为每一批付出巨大的成本,并减缓训练过程。
- 时钟速度是一个 CUDA 内核每秒的计算次数,因此时钟速度越高越好。
下面是驱动 AWS 上不同 EC2 实例的 GPU 的规格。
EC2 实例类型 | GPU 卡 | GPU 总数 | # CUDA 核心 | 存储容量 | 存储带宽 | 时钟速度 |
---|---|---|---|---|---|---|
G2 Esports 电子竞技俱乐部 | NVIDIA GRID K520 | 2 个开普勒 | Three thousand and seventy-two | 8 GB 的 GDDR5 | 320 GB/秒 | 800 兆赫 |
P2 | 英伟达特斯拉 K80 | 2 个开普勒 | Four thousand nine hundred and ninety-two | 24 GB 的 GDDR5 | 480 GB/秒 | 875 兆赫 |
自交第三代 | 英伟达特斯拉 M60 | 2 个麦克斯韦 | Four thousand and ninety-six | 16 GB 的 GDDR5 | 320 GB/秒 | 930 兆赫 |
我们使用已经在 Domino 中设置好的计算环境对新的 G3 实例进行了测试,并预装了 CUDA 驱动程序和 Tensorflow。我们通过改变硬件层来迭代使用 G3、P2 和 G2 实例,同时选择GPU tools
计算环境来运行我们的代码。
卷积神经网络基准
我们使用 Tensorflow 中的 AlexNet 基准来比较所有 3 个实例的性能。尽管 CUDA 内核数量更少,内存大小更小,内存带宽更小,但 G3 实例的性能仍然优于 P2 实例。
新的 G3 实例在训练 AlexNet 方面显然更快,Alex net 是卷积神经网络的标准基准。在价格上值得吗?
我们研究了性能的相对提高和价格的相对提高,答案似乎是肯定的从长远来看,G3 实例值得更高的成本,特别是如果你要训练一些大型卷积神经网络。
实例类型 | 向前-向后 | AWS 小时价格 | 相对性能改进 | 相对成本增加 | 相对性能/相对成本 |
---|---|---|---|---|---|
G2 Esports 电子竞技俱乐部 | One point four one | $0.65 | one | one | one |
P2 | Zero point six six | $0.90 | Two point one four | One point three eight | One point five four |
自交第三代 | Zero point four seven | $1.14 | Three point zero two | One point seven five | One point seven two |
递归神经网络基准
我们还想看看 Tensorflow 中的递归神经网络,以及它们如何在 3 个可用的 GPU 实例中使用 RNN,一个流行的基准来执行。
实例类型 | 向前+向后(每秒采样数) | AWS 小时价格 | 相对性能改进 | 相对成本增加 | 相对性能/相对成本 |
---|---|---|---|---|---|
G2 Esports 电子竞技俱乐部 | One thousand eight hundred and thirty-four | Zero point six five | one | one | one |
P2 | Two thousand six hundred and seventy-five | Zero point nine | One point four six | One point three eight | One point zero five |
自交第三代 | Four thousand one hundred and seventy-seven | One point one four | Two point two eight | One point seven five | One point three |
同样,G3 实例在训练 RNN 方面明显比 G2 和 P2 实例更快,所有新实例增加的成本是值得的…勉强。因此,根据 RNN 基准测试,如果你要运行一个大型的 RNN 模型,使用 G3 实例很可能会为你省下一大笔钱。
我们的 A 系列非公告公告
原文:https://www.dominodatalab.com/blog/non-announcing-our-series-a-round
我们中断这个节目...
今天,我们很高兴地宣布我们的首轮融资,由 Zetta Venture Partners 领投,彭博 Beta 和 In-Q-Tel 参与。
我们在 Domino 的偏执狂重点是创建一个平台,让数据科学家更有生产力,并促进协作、可重复、可重用的研究。
我们有点鄙视如今初创公司对融资的极度关注。通过阅读新闻,你可以原谅某些人认为创业公司是为了筹集资金而存在,而不是为了生产和向客户销售产品。在 Domino,我们坚信相反的观点:对我们来说,成功就是交付客户喜爱的优秀产品。
所以我们要暂停一下——简短地——告诉你我们为什么要筹集资金,这对谁有什么影响。非常明确地说:我们将加薪视为达到目的的手段,而不是目的本身。之后,回到产品和客户。
我们为什么这么做
两年来,我们启动了 Domino——这意味着我们主要使用收入和创始人的一些小额投资来为业务融资。我们写了我们从这种方法中获益多少。因此,一个显而易见的问题是:为什么现在接受传统风险投资?
几周前,当我们收到第一份投资意向书时,我们写了一份预算,看看仅根据预计收入,我们可以支持多少招聘(我们最大的支出)。该分析表明,该业务可以轻松地继续依靠收入运营,我们可以承担额外工程师和销售主管的少量投资。
然而,我们进行融资有两个原因:
- 我们准备加速前进,而“火上浇油”需要外部投资。我们目前有 40 多个客户和试点,处于不同的阶段,包括十几家财富 500 强公司。他们都看到了基于 Domino 的业务的真正改进,我们将投资为他们开发更好的产品。我们还想找到更多这种善于分析的客户。所有这些都需要比我们目前的收入水平(实际上是一个跟踪指标)所能支持的更多的投资。
- 我们认为,与我们合作的三家投资公司将有意义地改变我们的业务轨迹。需要说明的是,这是一个假设,我们将在几年后对此进行报告,这也是我们最初持怀疑态度的假设。但我们努力让我们最终合作的公司尽职尽责,就像他们尽职尽责一样。当我们发现自己与一家非常成功的初创公司的第四任首席执行官交谈时,他像前三任一样说,“这些人对我们的成功至关重要,”我们得出结论,要么 1)我们对风险投资家带来的额外价值的总体看法是错误的,要么 2)我们发现了例外。这也有助于所有三家公司都是我们领域(分析)的专家。
出于这两个原因,我们做了这笔交易。
这改变了什么
到处都是好消息:
对于我们的客户来说,产品将会比以往发展得更快。我们将工程团队的规模扩大了三倍,因此可以期待看到巨大的发展几乎马上开始。
对于创业求职者来说,达美乐正在招聘。我们正在寻找工程师、数据科学家和销售主管,他们希望承担重大责任,帮助我们在发展轨迹的关键点上实现增长。
对于那些观察分析空间的人来说,现在是注意 Domino 的企业分析平台的好时机,我们认为它将很快成为每个分析先进企业的关键基础设施。
最后一点:非常重要的是要感谢所有帮助 Domino 发展到今天的人,尤其是我们早期的员工和客户。
现在回到正题(字面上)...
马修,尼克,克里斯
现接受第二版多样性旅行资助的申请
原文:https://www.dominodatalab.com/blog/now-accepting-applications-for-rev-2-diversity-travel-grant
By Jade Hayes, Software Engineer on February 19, 2019 in
达美乐重视包容和多元化的文化。我们知道,多样性丰富了创造过程,建立了更强大的团队,并使卓越的分析解决方案的发现。我们希望在 Rev 分享、交流和体验不同的观点。
作为其消除多样性进入数据科学专业世界的障碍的承诺的一部分,Domino Diversity & Inclusion Club 提供了一笔旅行补助金,允许三名申请人参加 2018 年首届数据科学领袖 Rev 峰会。基于去年节目在的成功,我们很高兴在 Rev 2 为第二轮带来多样性旅行资助!
多米诺的多样性和包容性俱乐部为 Rev 2 提供四项旅行资助,包括旅行、住宿和会议费用。与会者将向世界领先的模型驱动型组织学习,并与各行业和公司的数据科学领导者交流。鼓励被选中的候选人与行业同行和领导者分享他们不同的技能、知识和想法。
欢迎所有背景的人申请 Rev 多样性旅行资助。
有问题吗?联系杰德·海斯。
nteract:一个开源的、基于桌面的交互式计算应用程序
今天,我们与 Plot.ly 的合作伙伴一起,宣布对开源项目interact的重大投资。nteract 是一个基于桌面的交互式计算应用程序。
在 Domino,我们是 Jupyter 笔记本项目的超级粉丝。我们广泛使用 Jupyter,从探索销售、营销和运营数据,到与团队分享分析和可视化。Domino 数据科学平台消除了部署笔记本服务器和管理多语言笔记本环境的复杂性。因此,我们的大量客户也在使用 Jupyter。
对于很多用例来说,Jupyter 并不理想。基于浏览器的客户机-服务器模型不容易创建利用本机桌面集成并支持脱机使用的丰富交互式计算应用程序。使用 nteract,您可以创建如下所示的文档,其中包含可执行代码、文本内容和图像,并传达计算叙事。与 Jupyter 不同,您的文档是独立的、跨平台的桌面应用程序,提供无缝的桌面体验和脱机使用。
由于易于使用,nteract 成为向业务用户和数据科学家、研究人员以及其他具有数据科学技术经验的人部署富数据应用程序的理想环境。
nteract 可以运行你现有的 Jupyter 笔记本,无需任何修改,并且支持多种 Jupyter 内核:Python、R、Julia 和 JavaScript。作为一个本地 Jupyter 笔记本,nteract 应用程序可以轻松地保存到 Domino、版本化、共享,并且如果需要,可以在云、VPC 或本地的高性能机器上运行。
这是 nteract 团队和社区贡献者旅程的开始。计划中的增强包括实时、多用户协作,以及连接到远程内核的能力(例如,使用 Domino 的可伸缩计算)。
感谢凯尔、萨菲娅和团队为开发 nteract 付出的所有辛勤工作。我们期待着与您合作,在您已经开发的伟大平台上继续发展。
如果您想尝试、了解更多信息或参与项目,请访问 GitHub 上的interact 项目。
Numenta 异常基准:流异常检测的基准
原文:https://www.dominodatalab.com/blog/numenta-anomaly-benchmark
随着传感器侵入我们的日常生活,我们看到流式时序数据的可用性呈指数级增长。在这些数据中发现异常或不寻常的行为可能非常有价值,但是可靠地做到这一点是非常困难的。文献中有几十种异常检测算法,但几乎不可能对它们进行流式评估,因为现有的基准侧重于非流式批量数据。我们创建了开源的 Numenta 异常基准(NAB) 来填补这个漏洞[1]。NAB 允许我们测试和改进我们自己的算法[2],还可以与其他公布的算法进行比较。
问题是
流媒体应用对机器学习模型提出了一些特殊的限制和挑战。这些应用包括分析实时发生的连续数据序列。与批处理相反,完整的数据集是不可用的。当数据到达时,系统按顺序观察每个数据记录,任何处理或学习必须以在线方式进行。
看看下面的图 1,一个来自传感器的时间序列数据的例子。该图显示了未知指标随时间变化的标量值。您能猜出这个指标是糖尿病患者的血糖水平、财富 500 强公司的股票数量还是其他什么吗?很难判断,但很明显,该图显示数据异常,或偏离正常模式。
图 1:来自 NAB 语料库的示例数据文件;监控大型、昂贵的工业机器的内部组件温度的数据。红点表示实际的异常。有关这些和其他 NAB 组件的详细信息,请浏览 NAB 存储库。
纵观整个图,这些异常很容易在事后识别,但在异常发生很久之后才识别是不可接受的。真实世界的异常检测器必须处理流数据,不断学习,并尽快做出准确的检测。
在 NAB 中,我们将实时异常检测算法的理想特征定义如下:
- 检测必须在线进行;即,在看到未来之前,算法必须将当前状态识别为正常或异常。
- 该算法必须连续学习,而不需要存储 entire stream.
- 该算法必须以无人监管的自动化方式运行,即无需数据标签或手动调整参数。
- 该算法必须适应动态环境和概念漂移,因为数据流的基本统计可能会改变。
- 该算法应该尽可能早地检测到异常。
- 该算法应该最小化假阳性和假阴性(对于批处理场景也是如此)。
逮捕
NAB 是用于评估实时异常检测算法的标准开源框架。NAB 由两个主要部分组成:一个带有标记的真实世界时间序列数据的数据集,以及一个为流数据设计的评分系统。该数据集包含来自 IT、工业机器传感器、社交媒体等各种来源的 58 个标记文件(约 365,000 个数据点)。该评分系统是对典型的假阳性假阴性指标的扭曲。它奖励准确的检测器,但也优先考虑那些比其他算法更早检测到异常的检测器。
此外,NAB 储存库现在包括来自大约十种不同异常检测算法的结果。表 1 显示了最新的 NAB 排行榜(详情请参见资源库)。
探测器 | 标准配置文件 | 奖励低 FP | 奖励低 FN |
---|---|---|---|
完美的 | One hundred | One hundred | One hundred |
HTM·艾尔 | Seventy point one | Sixty-three point one | Seventy-four point three |
凯德·OSE | Sixty-nine point nine | Sixty-seven | Seventy-three point two |
NBA-康特 | Sixty-four point six | Fifty-eight point eight | Sixty-nine point six |
KNN CAD | Fifty-eight | Forty-three point four | Sixty-four point eight |
相对熵 | Fifty-four point six | Forty-seven point six | Fifty-eight point eight |
HTM PE | Fifty-three point six | Thirty-four point two | Sixty-one point nine |
Twitter ADVec | Forty-seven point one | Thirty-three point six | Fifty-three point five |
Etsy 地平线 | Thirty-five point seven | Twenty-seven point one | Forty-four point five |
滑动阈值 | Thirty point seven | Twelve point one | Thirty-eight point three |
贝叶斯变点 | Seventeen point seven | Three point two | Thirty-two point two |
揭露 | Sixteen point four | Three point two | Twenty-six point nine |
随意 | Eleven | One point two | Nineteen point five |
空 | Zero | Zero | Zero |
表 1。NAB 记分板显示了 NAB 1.0 版上每个算法的结果。
图 2 显示了在一个数据文件上运行一些检测器的两个示例。第一个例子显示了持续学习的价值。第二个演示了使用时间流的早期检测。
图 2:该图显示了两个示例 NAB 数据流的检测器结果。在这两种情况下,我们都显示了完整数据流的子集。绘制的形状对应于七种不同检测器的检测:Numenta HTM(圆形)、多元相对熵(菱形)、Twitter ADVec(方形)、Skyline(十字形)、滑动阈值(三角形向上)、贝叶斯在线变点(六边形)和 EXPoSE(三角形向下)。为了清楚起见,对应于相同数据点的形状被垂直隔开。每个窗口(红色阴影区域)内的真阳性检测用黑色标记。所有的误报检测都是红色的。(a)生产服务器 CPU 指标的检测结果。第二个异常显示了一个持续的转变,需要算法来适应新的正常行为。(b)数据流的结果,其中我们看到在数据中的大的、明显的尖峰之前的微妙的时间异常。大多数探测器探测到了大峰值,但有两个探测器能够提供更有价值的早期预警。
我们如何使用 Domino
我们在测试各种异常检测算法的过程中广泛使用了 Domino 。对于大多数机器学习算法来说,通常有大量的参数需要测试。对于每个参数组合,我们需要在整个语料库上运行该算法。所有算法和所有参数的叉积是一个相当大的空间。Domino 允许我们非常容易地并行探索云中的空间,并跟踪所有结果。图 3 显示了一个样例截图,其中我们并行运行了四种不同的算法。通常每个算法需要几天时间的参数调整反而花了我们几个小时。
图 3:这个截图展示了一个使用 Domino 和 NAB 的例子。我们能够轻松地并行运行多个算法。我们使用 X-Large 硬件层,这样每次运行可以使用 16 个内核。我们使用 Domino 的诊断统计特性在单个笔记本中查看每次运行的结果。
上述许多算法的代码也可以在存储库中获得,因此开发人员可以很容易地复制结果,并在自己的数据上尝试各种检测器。随着时间的推移,我们希望 NAB 将被证明是致力于流式异常检测的数据科学家的一个有价值的开放资源。
参考
- 评估实时异常检测算法 Numenta 异常基准。第 14 国际。糖膏剂马赫。学习。应用程序(IEEE ICMLA'15)。佛罗里达州迈阿密:IEEE2015.出发地:http://arxiv.org/abs/1510.03336
- 流分析的实时异常检测。2016;出发地:http://arxiv.org/abs/1607.02480
英伟达的 Mona Flores:医疗人工智能和联邦学习力如何创新
如果分散在世界各地的机器学习和数据掌握着治愈各种罕见或新疾病的关键,会怎么样?直到最近,使用这些数据几乎是不可能的,部分原因是世界各地对数据隐私的限制。这种情况正在开始改变,这要归功于联合学习和医生的创新工作,例如英伟达医疗人工智能主管莫娜·弗洛雷斯。
“能够证明我们可以使用联合学习并仍然保护隐私,将真正改变我们在医学中可以利用人工智能和人工智能做的事情,并将引领未来的许多进步,”她说。
弗洛雷斯博士是一名外科医生,他在医疗人工智能的应用方面做了开创性的工作,包括在 20 家医院进行的联合学习试点,证明了使用带有隐私保护数据的联合学习来训练模型识别新冠肺炎等疾病的优势。结果呢?预测哪里需要哪些治疗的能力,这有助于决定在哪里和何时部署救命的治疗。
多米诺采访弗洛雷斯和其他顶尖创新者
Domino 最近为我们的新电子书采访了 Flores, 【数据科学创新者的剧本】, 涵盖了数据科学在推动创新中的崛起,这是一个通过采访七位顶级数据科学创新者讲述的故事,他们在 5 月的 Rev 3 中被同行选出。她是三位著名的医学创新者之一,也是唯一一位除了引领医学数据科学领域的进步之外,还是一名出色的外科医生的人。
所有这些创新者都在解决一些世界上最棘手的问题,其中许多问题——如 COVID——给医疗保健行业带来了特别困难的挑战。但是,Flores 说,新的工具正在加强数据科学,所以这个新兴学科越来越有能力处理世界抛给它的任何挑战。
**说到医疗保健,数据科学家和医学研究人员面临的困难之一是如何以保护隐私、符合监管法律和指导方针的方式使用患者数据,并帮助训练机器学习模型,其结果可以为数百万潜在患者带来新的治疗方法和更好的结果。联合学习在这一领域显示出巨大的前景,无疑将继续推动医疗保健和许多其他领域的新创新。
从医学博士 Mona Flores 那里了解更多信息,以及 NVIDIA 如何帮助克服这些挑战。
其他特色创新者对数据科学的优势进行了权衡
免费电子书讨论了许多数据科学创新,还包括职业建议和关于数据科学中角色变化的观点。下载数据科学创新者行动手册阅读 Flores 的更多见解,以及来自以下网站的许多其他主题、战略、战术和见解:
** 凯西·科兹尔科夫——谷歌首席决策科学家
- Andy Nicholls——GSK PLC 统计数据科学部高级总监
- najat Khan——强生公司让桑制药公司首席数据科学官兼研发战略与运营全球总监
- Robert Nishi hara——Ray 的联合创始人,Anyscale 的联合创始人兼首席执行官
- John k . Thompson—分析思想领袖、畅销书作家、数据创新者&分析
- Glenn Hofmann—纽约人寿保险公司首席分析官。
论模型驱动:度量和监控
原文:https://www.dominodatalab.com/blog/on-being-model-driven-metrics-and-monitoring
本文涵盖了在生产中跟踪机器学习模型时要考虑的几个关键机器学习(ML)生命体征,以确保模型未来的可靠性、一致性和性能。非常感谢 Don Miner 在本文中与 Domino 合作。欲了解本文之外的其他生命体征和见解,请参加网络研讨会。
机器学习模型:疯狂奔跑
许多数据科学家、ML 研究人员和他们的模型驱动组织开发了一个模型来解决一个特定的问题。当模型在生产中“工作”时,他们也可能会感到轻松。然而,当有数百个模型在生产中运行并与现实世界交互时,会发生什么呢?当没有人跟踪模型在实时数据上的表现时会发生什么?不幸的是,随着时间的推移,偏差和方差可能会渗入模型,这可能会导致它们变得毫无价值。这些结果对于产生积极的业务影响并不理想。
在 Domino 寻求加速研究和加强数据科学家对其公司的积极影响时,我们联系了 Don Miner,与他合作举办了一场网络研讨会,“机器学习的重要标志:生产中的度量和监控模型”,该研讨会详细介绍了度量和监控,或生产中机器学习模型的跟踪,以确保模型的可靠性、一致性和未来的性能。Miner 之前作为数据科学家、工程师和首席技术官的经历造就了他独特而务实的观点。这篇博客文章包括幻灯片摘录和几个关键的 ML 生命体征,包括准确性和输出分布,您可以参加完整的网络研讨会,了解更多生命体征和深入见解。
什么是 ML 生命体征?
Miner 提倡使用一个生命体征或一个来自生产化模型的可以随时间测量的指标。这超出了传统的衡量标准“模型有效吗?是或否。”这个额外的指标有助于确定随着时间的推移,模型是否在做它们应该做的事情。
ML 生命体征:准确性
准确性是一个核心的“生命体征”。它解决的问题包括:模型是否准确?正确吗?它正在做它应该做的事情吗?是对的多过错的吗?当根据新数据重新训练模型时,精确度可能会提高,特别是如果 ML 研究人员已经建立了一个系统,每个月左右重新训练模型。然而,随着时间的推移,模型的准确性可能会逐渐降低。
该模型的准确性可能会下降,因为研究人员围绕超参数调整所做的决定以及初始开发期间使用的模型类型可能会随着时间的推移而不再合适。此外,任何时候准确性出现大幅下降或大幅上升,都可能预示着发生了一些事情。
ML 生命体征:准确性挑战
对准确性的挑战使得它在某些情况下非常有用,但在其他情况下却没有用。例如,我们如何衡量我们得到的是对还是错?模型产生了一个输出。然而,这个模型预测了一些我们不知道的事情。如果我们不知道在某个时间点的输出应该是多少,那么我们就无法真正测量精度。Miner 引用了一个 HR 员工流失用例作为例子。一家公司试图预测一名员工在未来 18 个月内是否有离职风险。在这 18 个月内,员工离职的可能性百分比以及他们可能离职的时间。18 个月后,公司将知道 18 个月前的模型是否准确。从实用主义的角度来看,18 个月太长了,不能确定你的模型有问题。这是仅依赖某些用例或工作流的准确性所面临的挑战的一个例子。当准确性不够时,可以考虑替代的生命体征。
ML 生命体征:输出量分布
准确性生命体征的一个替代方法是输出分布。输出分布是计算或总结模型从给定的输入中返回的内容。在分类模型中,这是对模型在生产中输出的输出标签进行计数。在回归模型中,这可能是更复杂的分布、分位数分析或简单的平均值。如果先前模型的输出分布有显著变化,此指标有助于检测问题。要么是世界变化太大导致产出分布改变,要么是模型变化太大导致产出分布改变。无论哪种方式,这都是值得研究的,以确保模型仍然表现良好。这些都是在实际上不知道模型是否正确的情况下完成的,但是仅仅观察行为的变化就可以表明人类应该调查一些事情。
结论
由于 Domino 寻求支持数据科学家和研究人员加快他们的工作,我们联系了 Don Miner,以合作举办一场网络研讨会“机器学习的重要特征:生产中的度量和监控模型”。虽然这篇博客文章包括幻灯片摘录和一些关键的 ML“生命体征”,包括准确性和输出分布,但要了解更多生命体征和深入见解,请参加完整的网络研讨会或阅读我们的关于模型监控的白皮书。
完整的网上研讨会涵盖
- 为什么您应该投资时间来监控您的机器学习模型。
- 现实世界中关于不关注模型性能如何随时间变化的一些危险的轶事。
- 您应该为每个模型收集的指标,以及它们通过生命体征列表告诉您的内容,它们提供的价值以及如何衡量它们。
- 生命体征,包括分类标签随时间的分布、回归结果的分布、偏差的测量、方差的测量、先前模型的输出变化以及准确性随时间的变化。
- 监视模型随时间漂移的实现策略。
借助分析的力量优化芝加哥的服务
原文:https://www.dominodatalab.com/blog/optimizing-chicagos-services-with-the-power-of-analytics
为了减少公众对食源性疾病的暴露,芝加哥市与好事达定量研究和分析部门合作开发了一个预测模型,以帮助确定该市食品检测人员的优先顺序。
该模型根据实时、公开的数据计算了超过 15000 家芝加哥食品企业的个性化风险分值。这个预测模型的结果是通过一个使用闪亮的 R 包在 R 中开发的 web 应用程序交付的。该项目在芝加哥的[数据科学弹出窗口]上进行了展示(点击此处观看视频)。这是所有这一切是如何走到一起的背景故事。下面的故事是由数据智能城市解决方案最初发布的一篇文章。
想想看:芝加哥,一个拥有近 300 万人口和 15000 多家食品企业的城市,只有不到 36 名检查员负责每年检查整个城市。
当检查员检查整个批次时,平均来说,15%的这些机构都严重违规。
严重违规通常与食品温度控制有关,会大大增加餐厅引发或传播食源性疾病的几率。由于这可能对人群产生明显的负面影响,高效和有效地打击严重违规的食品企业是公共卫生的重中之重。
芝加哥快速定位和解决这些违规行为的挑战性任务是使用高级分析进行优化的主要候选对象。这也是一个机会,芝加哥的分析团队作为该市使用数据的先驱,肯定会抓住这个机会。
芝加哥承诺建立有史以来第一个市政开源预测分析平台,并被选为[彭博慈善机构首届市长挑战赛]的五个城市之一,该比赛鼓励城市提出创新想法,以解决重大挑战并改善城市生活。该市的目标是汇总和分析信息,以帮助领导者做出更明智、更快速的决策,并在问题出现之前加以预防。
芝加哥致力于构建首个市政开源预测分析平台
该市最近完成了优化该市食品检查流程的试点项目,该项目由芝加哥创新与技术部(DoIT)与公共卫生部(CDPH)以及与公民咨询联盟和好事达保险公司的研究合作伙伴共同实施,是一个里程碑,取得了显著的成果。使用基于分析的程序时,芝加哥能够比使用传统检查程序平均提前七天发现严重违规。
这些结果不仅对芝加哥有意义,对任何希望使用高级分析优化检查流程的城市也有意义。此外,芝加哥发起这一倡议的合作和开放方法为其他希望启动自己的分析项目的地方提供了借鉴。
了解试点项目
芝加哥的首席数据官汤姆·申克(Tom Schenk)长期以来一直在考虑食品检验问题。大约两年前,申克与 CDPH 就两个部门如何围绕该市不断增长的分析项目进行合作进行了讨论。该市的目标是建立第一个市政开源预测分析平台,并获得了彭博慈善市长挑战赛的 100 万美元奖金,随后该市开始构建智能数据平台。为了测试预测分析的可操作性应用,该市还推出了第一个分析试点项目,该项目使用高级分析来增强街道和卫生局 灭鼠工作。
申克和 CDPH 联系了公民咨询联盟(CCA),这是一个当地组织,将企业与芝加哥市的部门配对,以参与有意义的公益项目。通过 CCA,芝加哥会见了好事达保险公司(Allstate),这是一家总部设在芝加哥的保险巨头,拥有参与社区活动的历史(T3)。好事达以前曾与芝加哥合作过,特别是作为芝加哥 Get 的主要成员,这是一个跨部门的倡议,旨在改善整个城市的社区安全。
在 CCA 的帮助下,该市专门与好事达保险公司的数据科学团队合作,这是双方的一种新型关系。好事达保险公司运营着灯泡项目,该项目将 10%的团队成员投入到公益项目中。通常,这些项目包括志愿者的机会,如领养高速公路项目或在施粥所的服务。然而,这个项目提供了一个机会,让好事达的数据科学家将他们的技能应用到一个具有新的影响水平的研究项目中。
随着联盟的建立,申克和他的团队开始采访 CDPH 检查员,以便更好地了解他们工作的后勤,并了解他们如何与数据交互。芝加哥将食品检验报告、311 服务数据和天气数据确定为探索食品检验结果预测器的首选。该团队还使用了城市开放数据门户网站上的其他信息,如社区和犯罪信息,来支持该模型。
芝加哥开放数据项目对这个项目的重要性不可低估。在多方参与的情况下,芝加哥联盟需要使用一个集中的、全面的、普遍可访问的数据源。符合这一要求,门户能够为合作伙伴提供一种在项目工作时轻松交流研究和分析的方式。如果没有数据门户,芝加哥的关键数据集将位于不同的系统中,这将非常耗时且困难。
在处理和分析数据的过程中,芝加哥发现了几个关键的预测变量,当观察到这些变量时,表明一家餐馆很有可能会受到严重违反。这些预测变量包括:
- 持有烟草和/或附带酒精消费许可证
- 持有烟草和/或附带酒精消费许可证
- 机构运营的时间长度
- 自上次检查以来的时间长度
- 机构所在地
- 附近的垃圾和卫生投诉
- 附近的盗窃案
- 三天平均高温
然后将这些预测因子整合到一个模型中,通过双盲后检测分析对照食品检测程序进行测试。换句话说,在收集了一组数据后,芝加哥大学进行了一次模拟,利用过去的数据来预测在数据优化条件下未来的结果。
那么,当在政府环境中付诸实践时,这一过程意味着什么呢?
2014 年 9 月和 10 月,CDPH 使用传统方法进行食品检验,然后将详细的检验信息交给芝加哥分析团队。在试验期间,CDPH 的视察员总共视察了 1,637 家食品企业。在这些检查中,CDPH 发现有 258 家企业——约占总数的 15%——至少有一项严重违规。
请记住,试点的目标是让分析帮助更快地提供检查结果,以便可以更早地检测到严重违规。这就是为什么数据是在两个月的时间内收集的;9 月和 10 月的数据被用作对比来源。9 月,CDPH 检查人员发现上述机构中有一半以上存在违规行为——准确地说,有 141 家,占 55%。10 月,该总数的剩余部分(45%)被找到。
如果在正常运营的上半年发现了 55%的严重违规,那么在分析优化运营的上半年发现的严重违规百分比是多少?
值得注意的是,CDPH 检查员第一个月表现不错——在给定时间段的前半个月内发现超过 50%的违规行为总是一个好迹象。但是,如果检查员不是通过标准程序检查这些食品机构,而是首先访问所有符合上面列出的关键预测变量的地点,会怎么样呢?
为了找到答案,分析团队根据每个机构满足的预测变量的数量,为每个受检食品机构分配了一个获得严重违规的概率。例如,如果一个机构符合 10 个预测因素中的 8 个,那么它将被分配比符合 10 个预测因素中的 2 个的机构更高的概率。由于这个新排名的“预测”列表是使用试验期数据汇编的,它为两种检验方法之间的比较提供了一个理想的来源。
当使用基于分析的方法时,芝加哥能够发现严重违规;平均来说,比使用传统的检查程序要早 7 天。
芝加哥的分析团队发现,与传统程序的列表相比,数据优化的预测列表可以更有效地分配检查。在模拟中,上半年发现了 178 家食品企业,占严重违规检查的 69%。
这些数字意味着,如果检查员使用数据优化的预测列表,在第一个月就可以发现另外 37 家严重违规的企业。通过及早发现这些场所,CDPH 能够防止餐馆顾客成为食源性疾病的潜在受害者。
将传统程序与数据优化程序进行比较以检查食品企业时,试点结果导致上半年发现的严重违规数量增加了 25%。鉴于前半个月是一个月,这 25%的增长时间表明,使用数据优化程序检查食品企业导致发现严重违规,平均提前 7 天。
这一切意味着什么?
芝加哥食品检查试点的成功并不意味着发现了更多的严重违规行为,也不意味着 CDPH 会在一夜之间改变他们的检查流程。相反,该试点是将高级分析持续应用于城市运营的关键一步。虽然仍然发现平均 15%的一般严重违规,但发现的速度比以前更快,这给城市带来了公共卫生方面的好处。这些结果——以及获得它们的过程——类似于芝加哥前述的啮齿动物诱饵分析工作。
当芝加哥的啮齿动物试点在 2014 年早些时候结束时,其啮齿动物诱饵工作人员的主要收获是工作人员能够花费在实际捕鼠上的时间增加了 20%(相对于找出在哪里捕鼠)。芝加哥的街道和卫生部门已经在他们的业务中采用了分析方法,定期将经过数据优化的老鼠位置列表发送给捕鼠队。
这两个案例都表明,高级分析并不是对当前运营的控诉,而是一种增强。试点完成后,食品检查用例正在成为 CDPH 境内更具操作性的机制。
预测和未来
芝加哥的新用例是 SmartData 平台持续发展的一个关键标志。每一个完成的试点项目都提供了一个新的算法模型,该模型有可能被复制应用到其他城市服务和运营中。
此外,随着每个用例的出现,Chicago 用于高级分析计划的协作式多合作伙伴系统变得越来越熟练和有经验。
啮齿动物控制试点主要来自一个数据来源——311 电话——而食品检验试点包括更广泛的数据集,需要开发更复杂的模型。为了适应这种情况,芝加哥扩大了它的工作基础,以包括更多的项目合作伙伴。通过利用好事达数据工程师无偿工作的才能,芝加哥得以发展——甚至帮助形成——一个以合作为中心的工作计划。这使得该市能够承担一些原本没有资源完全靠自己完成的项目。这项新的工作计划也激起了其他城市的兴趣。
最后,根据其合作方式,Chicago 在代码共享网站 GitHub 上创建了一个开源库来共享用于试点的代码,以及评估信息。这意味着其他有兴趣采用自己类似项目的城市可以以芝加哥的分析工作为起点,而不是从头开始整个过程。
芝加哥用于开发其食品检测预测模型的所有数据都来自其公开可用的数据门户。通过发布该模型的源代码,芝加哥实质上放弃了它用来更快地定位关键食品机构违规的工具和建筑材料,并邀请其他人使用这些材料并做同样的事情。这项努力希望促进城市间的创新发展和合作。
了解更多信息
观看芝加哥数据科学展上的演示,来自芝加哥市分析团队的吉恩·莱恩斯和来自好事达公司的加文·斯马特和史蒂芬·柯林斯讨论了技术模型开发、应用程序设计和部署,以及成功研究合作关系的模型。
投资使每个公司都是模型驱动的
原文:https://www.dominodatalab.com/blog/our-100m-series-f-funding-round
我很高兴地宣布,达美乐已经筹集了 1 亿美元的资金,由 Great Hill Partners、现有投资者 Coatue Management、Highland Capital Partners 和 Sequoia Capital 以及另一个新投资者 NVIDIA 牵头。这笔资金将让我们加速整个公司的增长,特别是在产品开发方面,因此我们可以继续构建世界上最好的企业 MLOps 平台。
例如,利用这笔资金,Domino 计划加强与 NVIDIA 的集成:建立一个团队,专门支持我们的客户利用 NVIDIA 加速计算解决方案建立竞争优势。这项投资还将帮助我们继续雇佣最优秀的人才来支持我们的客户,因为他们将模型放在了业务的核心位置。
这项投资真正让我兴奋的是,它让 Domino 能够帮助成千上万家公司解决目前业务中发生的两件截然不同的事情。
模型驱动的统治
首先,越来越多的 e 企业正在将他们的业务转变为模型驱动。迄今为止,超过五分之一的 财富 100 强公司使用 Domino 作为管理模型驱动活动的平台,在过去的两年中,我们帮助的全球 2000 强公司的数量翻了一番。 这些企业正在将数据科学融入其业务的方方面面。福特汽车公司和洛克希德·马丁公司就是很好的例子。利用数据科学,他们正在做一些尖端的事情,如建造自动驾驶汽车和人工智能试点软件。他们还在幕后做了大量工作来改善客户体验和运营效率。
成为模型驱动也是关于你能解决的问题类型。我们与英伟达的深度集成使许多公司能够使用加速计算和人工智能优化软件作为构建日益复杂模型的竞争优势。从预测性供应链的自然语言处理到能源基础设施的预测性维护,我们在任何事情上都可以看到这一点。进一步深化我们与 NVIDIA 的合作伙伴关系,通过增强的 IT 治理实现自助 GPU 访问的民主化,提供协作、可重复的模型开发和培训——不受开发运维或基础设施的限制。
提升数据科学人才的技能
其次,以这种方式进行转型需要大幅扩展您的数据科学团队,许多公司都被困在这里,因为他们无法雇用足够的数据科学家。看看数字就知道了。根据我们委托 对企业数据高管进行的一项研究,数据高管对扩展数据科学最常见的担忧是:44%的人说他们根本没有招聘到足够的人。但是他们雇佣的人也没有得到有效的利用。超过五分之二的数据高管表示,他们的数据科学资源过于孤立,无法构建有效的模型。 超过三分之二的数据主管(68%)表示,将模型投入生产以影响业务决策至少有些困难,37%的人表示非常困难或极其困难。
由于缺乏数据科学家之间的合作以及缺乏支持这项工作的软件基础设施,这些项目很难启动。
例如,在洛克希德·马丁公司,在使用 Domino 之前,他们的数据科学家 65%的时间花在工程和管理上,而不是模型开发上,而模型开发才是他们真正的价值所在。与 Domino 的合作有助于最大限度地提高洛克希德·马丁公司数据科学团队的生产力和产出。正如他们告诉华尔街日报的那样,Domino 使其数据科学家的工作效率提高了 20%到 25%,这意味着节省了数千小时的时间——确实如此。数据科学家不应该把时间花在令人头疼的工程上;他们应该花时间做他们最擅长的事情:建立模型。
我们的许多客户都通过提高技术含量较低的分析师的技能来增加数据科学人口,并利用技术让他们的数据科学从业者更容易提高生产力和效率,从而取得了成功。有了多米诺骨牌,这些公司已经迅速将数百名生产性数据科学家加入到生产难以置信的复杂模型的团队中,以解决世界上最重要的问题。
基于模型运行的企业表现更好,这是每个企业在这十年从数字到模型驱动的转变。随着 NVIDIA 的加速计算平台和 Domino 的企业 MLOps 的深度集成,每个企业都有一个理想的平台来推动这一转型。
熊猫种类
免责声明:类别是由熊猫开发团队而不是我创建的。
速度比并行性更重要
我通常写的是平行。因此,人们问我如何并行化他们缓慢的计算。答案通常是用更好的方式使用熊猫
- 问:如何用并行技术让我的熊猫编码更快?
- 答:不需要并行,用熊猫更好
这几乎总是比使用多核或多台机器更简单、更有效。只有在对存储格式、压缩、数据表示等做出明智的选择之后,才应该考虑并行性..
今天我们将讨论熊猫如何用数字表示分类文本数据。这是一个廉价且未被充分利用的技巧,可以使普通查询的速度提高一个数量级。
绝对的
我们的数据通常包含具有许多重复元素的文本列。示例:
- 股票代码–谷歌、APPL、MSFT、...
- 性别–女性,男性,...
- 实验结果——健康、患病、无变化,...
- 州——加利福尼亚州、德克萨斯州、纽约州、...
我们通常将这些表示为文本。Pandas 用包含普通 Python 字符串的对象 dtype 表示文本。这是导致代码缓慢的一个常见原因,因为对象数据类型是以 Python 的速度运行的,而不是以熊猫正常的 C 速度。
Pandas categoricals 是一个新的强大的特性,它用数字编码分类数据,这样我们就可以在这种文本数据上利用 Pandas 的快速 C 代码。
>>> # Example dataframe with names, balances, and genders as object dtypes
>>> df = pd.DataFrame({'name': ['Alice', 'Bob', 'Charlie', 'Danielle'],
... 'balance': [100.0, 200.0, 300.0, 400.0],
... 'gender': ['Female', 'Male', 'Male', 'Female']},
... columns=['name', 'balance', 'gender'])
>>> df.dtypes # Oh no! Slow object dtypes!
name object
balance float64
gender object
dtype: object
通过使用类别,我们可以更有效地表示具有许多重复的列,比如性别。这将我们的原始数据存储为两部分
- 原始资料
Female, Male, Male, Female
1。将每个类别的索引映射到一个整数
Female: 0
Male: 1
...
2。正常的整数数组
0, 1, 1, 0
这个整数数组更加紧凑,现在是一个普通的 C 数组。这允许在以前较慢的对象数据类型列上正常的 C 速度。对列进行分类很容易:
df['gender'] = df['gender'].astype('category')
# Categorize!
让我们看看结果
df
# DataFrame looks the same
name balance gender
0 Alice 100 Female
1 Bob 200 Male
2 Charlie 300 Male
3 Danielle 400 Female
df.dtypes
# But dtypes have changed
name object
balance float64
gender category
dtype: object
df.gender # Note Categories at the bottom
0 Female
1 Male
2 Male
3 Female
Name: gender, dtype: category
Categories (2, object): [Female, Male]
df.gender.cat.categories # Category index
Index([u'Female', u'Male'], dtype='object')
df.gender.cat.codes # Numerical values
0 0
1 1
2 1
3 0
dtype: int8 # Stored in single bytes!
请注意,我们可以将我们的性别更紧凑地存储为单个字节。我们可以继续添加性别(不止两个),熊猫会在必要时使用新的值(2,3,…)。
我们的数据帧看起来和感觉起来都和以前一样。熊猫内部将平滑用户体验,这样你就不会注意到你实际上是在使用一个紧凑的整数数组。
表演
让我们看一个稍微大一点的例子来看看性能差异。
我们从纽约市的出租车数据集中抽取一小部分,并根据 medallion ID 进行分组,以找到在某一段时间内行驶距离最长的出租车司机。
import pandas as pd
df = pd.read_csv('trip_data_1_00.csv')
%time
df.groupby(df.medallion).trip_distance.sum().sort(ascending=False,inplace=False).head()
CPU times: user 161 ms, sys: 0 ns, total: 161 ms
Wall time: 175 ms
medallion
1E76B5DCA3A19D03B0FB39BCF2A2F534 870.83
6945300E90C69061B463CCDA370DE5D6 832.91
4F4BEA1914E323156BE0B24EF8205B73 811.99
191115180C29B1E2AF8BE0FD0ABD138F 787.33
B83044D63E9421B76011917CE280C137 782.78
Name: trip_distance, dtype: float64
大约需要 170 毫秒。我们差不多同时归类。
%time df['medallion'] = df['medallion'].astype('category')
CPU times: user 168 ms, sys: 12.1 ms, total: 180 ms
Wall time: 197 ms
现在我们有了数字类别,我们的计算运行 20 毫秒,提高了大约一个数量级。
%time
df.groupby(df.medallion).trip_distance.sum().sort(ascending=False,
inplace=False).head()
CPU times: user 16.4 ms, sys: 3.89 ms, total: 20.3 ms
Wall time: 20.3 ms
medallion
1E76B5DCA3A19D03B0FB39BCF2A2F534 870.83
6945300E90C69061B463CCDA370DE5D6 832.91
4F4BEA1914E323156BE0B24EF8205B73 811.99
191115180C29B1E2AF8BE0FD0ABD138F 787.33
B83044D63E9421B76011917CE280C137 782.78
Name: trip_distance, dtype: float64
在我们完成用类别替换对象数据类型的一次性操作后,我们看到速度几乎提高了一个数量级。该列上的大多数其他计算也同样快。我们的内存使用也急剧下降。
结论
熊猫分类有效地编码重复的文本数据。类别对于股票代码、性别、实验结果、城市、州等数据非常有用..类别易于使用,并极大地提高了此类数据的性能。
当处理不方便的大数据或慢数据时,我们有几种选择来提高性能。在存储格式、压缩、列布局和数据表示方面的良好选择可以极大地改善查询时间和内存使用。这些选择中的每一个都和并行性一样重要,但是没有被过分夸大,所以经常被忽视。
跟随 @mrocklin 并访问 continuum.io
面向 SAS 用户的 python:Pandas 数据分析库
原文:https://www.dominodatalab.com/blog/pandas-for-sas-users-part-1
这篇文章是兰迪·贝当古的 Python 为 SAS 用户准备的 快速入门指南的章节。Randy 写这个指南是为了让 SAS 用户熟悉 Python 和 Python 的各种科学计算工具。
熊猫简介
本章介绍熊猫库(或包)。pandas 为 Python 开发者提供了高性能、易于使用的数据结构和数据分析工具。这个包是基于 NumPy(读作“numb pie”)构建的,NumPy 是一个基础科学计算包,它提供了一个用于数组运算的高性能对象ndarray
。我们将举例说明一些有用的数字对象,以此来说明熊猫。
对于数据分析任务,我们经常需要将不相似的数据类型分组在一起。例如,使用带有频率的字符串对分类数据进行分组,使用整数和浮点数对连续值进行计数。此外,我们希望能够将标签附加到列、透视数据等。
我们首先引入Series
对象作为DataFrame
对象的组件。系列可以被认为是一个带索引的一维数组,类似于一列值。数据帧可以被认为是一个由行和列索引的二维数组。一个很好的类比是通过行和列位置可寻址的 Excel 单元格。
换句话说,数据帧看起来很像 SAS 数据集(或关系表)。下表比较了熊猫组件和 SAS 中的组件。
熊猫 | SAS |
---|---|
数据帧 | SAS 数据集 |
排 | 观察 |
圆柱 | 可变的 |
群组依据 | 按组 |
圆盘烤饼 | 。 |
薄片 | 子集 |
轴 0 | 观察 |
轴 1 | 圆柱 |
DataFrame
和Series
索引在第 6 章“理解索引”中有详细介绍。
导入包
为了开始利用 pandas 对象,或者任何其他 Python 包中的对象,我们首先通过名称将库导入到我们的名称空间中。为了避免重复输入完整的包名,请使用标准别名np
表示 NumPy,使用pd
表示 pandas。
import numpy as np
import pandas as pd
from numpy.random import randn
from pandas import Series, DataFrame, Index
from IPython.display import Image
系列
一个Series
可以被认为是一个带有标签的一维数组。该结构包括一个标签索引,用作定位值的键。Series
中的数据可以是任何数据类型。熊猫数据类型在这里有详细介绍。在 SAS 示例中,我们使用数据步长ARRAY
s 作为Series
的模拟。
首先创建一个随机值Series
:
s1 = Series(randn(10))
print(s1.head(5))
0 -0.467231
1 -0.504621
2 -0.122834
3 -0.418523
4 -0.262280
dtype: float64
请注意,索引起始位置从 0 开始。大多数 SAS 自动变量像_n_
都用 1 作为索引开始位置。SAS DO loop 0 to 9
结合ARRAY
的迭代产生数组下标越界错误。
在下面的 SAS 示例中,DO
循环用于遍历数组元素来定位目标元素。
SAS 中的数组主要用于一起迭代处理类似的变量。SAS/IML 更类似于 NumPy 阵列。 SAS/IML 不在这些例子的范围内。
0.4322317772
0.5977982976
0.7785986473
0.1748250183
0.3941470125
一个Series
可以有一个索引标签的列表。
s2 = Series(randn(10), index=["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"])
print(s2.head(5))
a -1.253542
b 1.093102
c -1.248273
d -0.549739
e 0.557109
dtype: float64
Series
由整数值索引,起始位置为 0。
print(s2[0])
-1.25354189867
SAS 示例使用一个DO
循环作为数组的下标。
0.4322317772
返回Series
中的前 3 个元素。
print(s2[:3])
a -1.253542
b 1.093102
c -1.248273
dtype: float64
0.4322317772
0.5977982976
0.7785986473
该示例有两个操作。s2.mean()
方法计算平均值,然后进行小于该计算平均值的布尔测试。
s2[s2 < s2.mean()]
a -1.253542
c -1.248273
d -0.549739
h -2.866764
i -1.692353
dtype: float64
Series
而其他对象都有使用点(.)链式语法。.name
是Series
对象的多个属性之一。
s2.name="Arbitrary Name"
print(s2.head(5))
a -1.253542
b 1.093102
c -1.248273
d -0.549739
e 0.557109
Name: Arbitrary Name, dtype: float64
DataFrames
如前所述,DataFrames
是带有标签的类似关系的结构。或者,一个单列的DataFrame
是一个Series
。
和 sa 一样,DataFrames
有不同的创作方法。可以通过从其他 Python 对象加载值来创建数据帧。还可以从一系列非 Python 输入源加载数据值,包括。csv 文件、DBMS 表、Web API,甚至 SAS 数据集(. sas7bdat)等。细节在第 11 章-熊猫读者中讨论。
从读取UK_Accidents.csv
文件开始。它包含从 2015 年 1 月 1 日到 2015 年 12 月 31 日在英国发生的交通事故数据。的。csv 文件位于这里。
一年中的每一天都有多个报告,其中的值大部分是整数。另一个。CSV 文件在这里找到将值映射到描述性标签。
阅读。csv 文件
下面的示例中使用了默认值。pandas 为许多读者提供了用于控制缺失值、日期解析、行跳转、数据类型映射等的参数。这些参数类似于 SAS 的INFILE/INPUT
处理。
注意附加的反斜杠\\
来规范化窗口的路径名。
file_loc2 = "C:\Data\uk_accidents.csv"
df = pd.read_csv(file_loc2, low_memory=False)
PROC IMPORT
用来读同。csv 文件。这是 SAS 读取. csv 文件的几种方法之一。这里我们采用了默认值。
NOTE: The file 'c:\data\uk_accidents.csv' is:
File Name 'c:\data\uk_accidents.csv',
Lrecl=32760, Recfm=V
NOTE: 266776 records were read from file 'c:\data\uk_accidents.csv'
The minimum record length was 65
The maximum record length was 77
NOTE: Data set "WORK.uk_accidents" has 266776 observation(s) and 27 variable(s)
与 SAS 不同,Python 解释器在正常执行时主要是静默的。在调试时,调用方法和函数来返回关于这些对象的信息是很有帮助的。这有点类似于在 SAS 日志中使用PUT
语句来检查变量值。
下面显示了size
、shape
和ndim
属性(分别为单元格数、行数/列数和维数)。
print(df.size, df.shape, df.ndim)
7202952 (266776, 27) 2
读取验证
读完一个文件后,你常常想了解它的内容和结构。DataFrame .info()
方法返回 DataFrame 属性的描述。
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 266776 entries, 0 to 266775
Data columns (total 27 columns):
Accident_Severity 266776 non-null int64
Number_of_Vehicles 266776 non-null int64
Number_of_Casualties 266776 non-null int64
Day_of_Week 266776 non-null int64
Time 266752 non-null object
Road_Type 266776 non-null int64
Speed_limit 266776 non-null int64
Junction_Detail 266776 non-null int64
Light_Conditions 266776 non-null int64
Weather_Conditions 266776 non-null int64
Road_Surface_Conditions 266776 non-null int64
Urban_or_Rural_Area 266776 non-null int64
Vehicle_Reference 266776 non-null int64
Vehicle_Type 266776 non-null int64
Skidding_and_Overturning 266776 non-null int64
Was_Vehicle_Left_Hand_Drive_ 266776 non-null int64
Sex_of_Driver 266776 non-null int64
Age_of_Driver 266776 non-null int64
Engine_Capacity__CC_ 266776 non-null int64
Propulsion_Code 266776 non-null int64
Age_of_Vehicle 266776 non-null int64
Casualty_Class 266776 non-null int64
Sex_of_Casualty 266776 non-null int64
Age_of_Casualty 266776 non-null int64
Casualty_Severity 266776 non-null int64
Car_Passenger 266776 non-null int64
Date 266776 non-null object
dtypes: int64(25), object(2)
memory usage: 55.0+ MB
在 SAS 中,同样的信息通常可以在PROC CONTENTS
的输出中找到。
检查
pandas 有用于检查数据值的方法。DataFrame .head()
方法默认显示前 5 行。默认情况下,.tail()
方法显示最后 5 行。行计数值可以是任意整数值,例如:
# display the last 20 rows of the DataFrame
df.tail(20)
SAS 使用FIRSTOBS
和OBS
选项和程序来确定输入观测值。打印 uk _ accidents 数据集的最后 20 个观察值的 SAS 代码是:
df.head()
5 rows × 27 columns
OBS=n
在 SAS 中确定用作输入的观察值的数量。
The output from PROC PRINT is not displayed here.
下面的单元格中显示了按列划分的范围输出。列列表类似于PROC PRINT
中的VAR
语句。注意这个语法的双方括号。此示例说明了按列标签进行切片。切片机也是成排工作的。方括号[]
是切片操作符。详细说明这里
df[["Sex_of_Driver", "Time"]].head(10)
司机的性别 | 时间 | |
---|---|---|
Zero | one | seven o'clock pm |
one | one | seven o'clock pm |
Two | one | half past six p.m. |
three | Two | half past six p.m. |
four | one | half past six p.m. |
five | one | ten to six p.m. |
six | one | ten to six p.m. |
seven | one | five past seven |
eight | one | five past seven |
nine | one | half past twelve |
请注意 DataFrame 默认索引(从 0 到 9 递增)。这类似于 SAS 自动变量 n 。稍后,我们将说明如何使用数据帧中的其他列作为索引。
下面是 SAS 程序,打印数据集的前 10 个观察值以及变量 Sec_of_Driver 和 Time。
The output from PROC PRINT is not displayed here.
处理缺失数据
在分析数据之前,一个常见的任务是处理缺失数据。pandas 使用两个名称来表示丢失的数据,NaN
(不是数字)和 Python None
对象。
下面的单元格使用 Python None
对象来表示数组中缺少的值。反过来,Python 推断数组的数据类型是对象。不幸的是,对数组使用带有聚合函数的 Python None
对象会引发错误。
s1 = np.array([32, None, 17, 109, 201])
s1
array([32, None, 17, 109, 201], dtype=object)
s1.sum()
---------------------------------------------------------------------------
TypeError Traceback (most recent call last) in <module>
----> 1 s1.sum()
/opt/anaconda3/envs/reporting_env/lib/python3.8/site-packages/numpy/core/_methods.py in _sum(a, axis, dtype, out, keepdims, initial, where)
45 def _sum(a, axis=None, dtype=None, out=None, keepdims=False,
46 initial=_NoValue, where=True):
---> 47 return umr_sum(a, axis, dtype, out, keepdims, initial, where)
48
49 def _prod(a, axis=None, dtype=None, out=None, keepdims=False,
TypeError: unsupported operand type(s) for +: 'int' and 'NoneType'
为了减少上面提到的错误,在下面的数组示例中使用np.nan
(缺失值指示器)。另请注意,与上面两个单元格的相同示例相比,Python 是如何为数组选择浮点(或向上转换)的。
s1 = np.array([32, np.nan, 17, 109, 201])
print(s1)
s1.dtype
[ 32\. nan 17\. 109\. 201.]
dtype('float64')
并非所有使用NaN
的算术运算都会产生NaN
。
s1.mean()
nan
将上面单元格中用于计算数组元素平均值的 Python 程序与下面的 SAS 示例进行对比。SAS 排除缺失值,并利用剩余的数组元素来计算平均值。
89.75
缺失值标识
回到我们的数据框架,我们需要分析所有列的缺失值。Pandas 提供了四种检测和替换缺失值的方法。它们是:
isnull()
生成一个布尔掩码来指示缺失值
| 方法 | 采取的行动 |
| notnull()
| 与isnull()
相反 |
| dropna()
| 返回数据的筛选版本 |
| fillna()
| 返回填充或估算缺失值的数据副本 |
我们将在下面详细讨论其中的每一个。
解决缺失数据分析的典型 SAS 编程方法是编写一个程序,使用计数器变量通过IF
/ THEN
测试缺失值来遍历所有列。
这可以遵循下面输出单元格中的示例。df.columns 返回数据帧中的列名序列。
for col_name in df.columns:
print(col_name, end="---->")
print(sum(df[col_name].isnull()))
Accident_Severity---->0
Number_of_Vehicles---->0
Number_of_Casualties---->0
Day_of_Week---->0
Time---->24
Road_Type---->0
Speed_limit---->0
Junction_Detail---->0
Light_Conditions---->0
Weather_Conditions---->0
Road_Surface_Conditions---->0
Urban_or_Rural_Area---->0
Vehicle_Reference---->0
Vehicle_Type---->0
Skidding_and_Overturning---->0
Was_Vehicle_Left_Hand_Drive_---->0
Sex_of_Driver---->0
Age_of_Driver---->0
Engine_Capacity__CC_---->0
Propulsion_Code---->0
Age_of_Vehicle---->0
Casualty_Class---->0
Sex_of_Casualty---->0
Age_of_Casualty---->0
Casualty_Severity---->0
Car_Passenger---->0
Date---->0
虽然这给出了期望的结果,但是还有更好的方法。
另外,如果你发现自己正在考虑使用迭代处理来解决 pandas 操作(或者 Python ),停下来花点时间做研究。很有可能,一个方法或函数已经存在了!
典型的例子如下图所示。它将.sum()
属性链接到.isnull()
属性,以返回数据帧中的列的缺失值的计数。
对于缺少的值,.isnull()
方法返回True
。通过将.sum()
方法链接到.isnull()
方法,它为每一列产生缺失值的计数。
df.isnull().sum()
Accident_Severity 0
Number_of_Vehicles 0
Number_of_Casualties 0
Day_of_Week 0
Time 24
Road_Type 0
Speed_limit 0
Junction_Detail 0
Light_Conditions 0
Weather_Conditions 0
Road_Surface_Conditions 0
Urban_or_Rural_Area 0
Vehicle_Reference 0
Vehicle_Type 0
Skidding_and_Overturning 0
Was_Vehicle_Left_Hand_Drive_ 0
Sex_of_Driver 0
Age_of_Driver 0
Engine_Capacity__CC_ 0
Propulsion_Code 0
Age_of_Vehicle 0
Casualty_Class 0
Sex_of_Casualty 0
Age_of_Casualty 0
Casualty_Severity 0
Car_Passenger 0
Date 0
dtype: int64
为了识别缺失值,下面的 SAS 示例使用PROC
格式来绑定缺失值和非缺失值。缺省情况下,缺失值表示为()。)表示数值,空白(“”)表示字符变量。因此,这两种类型都需要用户定义的格式。
PROC FREQ
与自动变量_CHARACTER_
和_NUMERIC_
一起使用,为每个变量类型生成一个频率列表。
只显示了 SAS 输出的一部分,因为为每个变量产生了单独的输出。与上面的 Python for
循环示例一样,time
变量是唯一缺少值的变量。
另一种检测缺失值的方法是使用链接属性.isnull().any()
的axis=1
参数按列进行搜索。然后沿着列执行操作。
null_data = df[df.isnull().any(axis=1)]
null_data.head()
5 rows × 27 columns
缺失值替换
下面的代码用于并排呈现多个对象。它来自杰克·范德普拉斯的《数据处理的基本工具》。它显示对象更改的“之前”和“之后”效果。
class display(object):
"""Display HTML representation of multiple objects"""
template = """<div style="float: left; padding: 10px;">
<p style="font-family: 'Courier New', Courier, monospace;">{0}</p> {1}</div>"""
def __init__(self, *args):
self.args = args
def _repr_html_(self):
return "\n".join(self.template.format(a, eval(a)._repr_html_()) for a in self.args)
def __repr__(self):
return "\n".join(a + "" + repr(eval(a)) for a in self.args)
为了说明.fillna()
方法,考虑下面创建一个数据帧。
df2 = pd.DataFrame([["cold","slow", np.nan, 2., 6., 3.],
["warm", "medium", 4, 5, 7, 9],
["hot", "fast", 9, 4, np.nan, 6],
["cool", None, np.nan, np.nan, 17, 89],
['"cool","medium",, 16, 44, 21, 13],
["cold","slow", np.nan, 29, 33, 17]],
columns=["col1", "col2", "col3", "col4", "col5", "col6"],
index=(list('abcdef')))
display("df2")
df2
col1 | 第二栏 | col3 | col4 | col5 | col6 | |
---|---|---|---|---|---|---|
a | 寒冷 | 慢的 | 圆盘烤饼 | Two | Six | Three |
b | 温暖的 | 媒介 | Four | Five | Seven | Nine |
c | 热的 | 快的 | Nine | Four | 圆盘烤饼 | Six |
d | 凉爽的 | 没有人 | 圆盘烤饼 | 圆盘烤饼 | Seventeen | Eighty-nine |
e | 凉爽的 | 媒介 | Sixteen | Forty-four | Twenty-one | Thirteen |
f | 寒冷 | 慢的 | 圆盘烤饼 | Twenty-nine | Thirty-three | Seventeen |
df_tf = df2.isnull()
display("df2", "df_tf")
df2
col1 | 第二栏 | col3 | col4 | col5 | col6 | |
---|---|---|---|---|---|---|
a | 寒冷 | 慢的 | 圆盘烤饼 | Two | Six | Three |
b | 温暖的 | 媒介 | Four | Five | Seven | Nine |
c | 热的 | 快的 | Nine | Four | 圆盘烤饼 | Six |
d | 凉爽的 | 没有人 | 圆盘烤饼 | 圆盘烤饼 | Seventeen | Eighty-nine |
e | 凉爽的 | 媒介 | Sixteen | Forty-four | Twenty-one | Thirteen |
f | 寒冷 | 慢的 | 圆盘烤饼 | Twenty-nine | Thirty-three | Seventeen |
col1 | 第二栏 | col3 | col4 | col5 | col6 | |
---|---|---|---|---|---|---|
a | 错误的 | 错误的 | 真实的 | 错误的 | 错误的 | 错误的 |
b | 错误的 | 错误的 | 错误的 | 错误的 | 错误的 | 错误的 |
c | 错误的 | 错误的 | 错误的 | 错误的 | 真实的 | 错误的 |
d | 错误的 | 真实的 | 真实的 | 真实的 | 错误的 | 错误的 |
e | 错误的 | 错误的 | 错误的 | 错误的 | 错误的 | 错误的 |
f | 错误的 | 错误的 | 真实的 | 错误的 | 错误的 | 错误的 |
默认情况下,.dropna()
方法会删除找到空值的整行或整列。
df3 = df2.dropna()
display("df2", "df3")
df2
col1 | 第二栏 | col3 | col4 | col5 | col6 | |
---|---|---|---|---|---|---|
a | 寒冷 | 慢的 | 圆盘烤饼 | Two | Six | Three |
b | 温暖的 | 媒介 | Four | Five | Seven | Nine |
c | 热的 | 快的 | Nine | Four | 圆盘烤饼 | Six |
d | 凉爽的 | 没有人 | 圆盘烤饼 | 圆盘烤饼 | Seventeen | Eighty-nine |
e | 凉爽的 | 媒介 | Sixteen | Forty-four | Twenty-one | Thirteen |
f | 寒冷 | 慢的 | 圆盘烤饼 | Twenty-nine | Thirty-three | Seventeen |
df3
col1 | 第二栏 | col3 | col4 | col5 | col6 | |
---|---|---|---|---|---|---|
b | 温暖的 | 媒介 | Four | Five | Seven | Nine |
e | 凉爽的 | 媒介 | Sixteen | Forty-four | Twenty-one | Thirteen |
.dropna()
方法也适用于列轴。axis = 1
或axis = 'columns'
相当。
df4 = df2.dropna(axis="columns")
display("df2", "df4")
df2
col1 | 第二栏 | col3 | col4 | col5 | col6 | |
---|---|---|---|---|---|---|
a | 寒冷 | 慢的 | 圆盘烤饼 | Two | Six | Three |
b | 温暖的 | 媒介 | Four | Five | Seven | Nine |
c | 热的 | 快的 | Nine | Four | 圆盘烤饼 | Six |
d | 凉爽的 | 没有人 | 圆盘烤饼 | 圆盘烤饼 | Seventeen | Eighty-nine |
e | 凉爽的 | 媒介 | Sixteen | Forty-four | Twenty-one | Thirteen |
f | 寒冷 | 慢的 | 圆盘烤饼 | Twenty-nine | Thirty-three | Seventeen |
df4
col1 | col6 | |
---|---|---|
a | 寒冷 | Three |
b | 温暖的 | Nine |
c | 热的 | Six |
d | 凉爽的 | Eighty-nine |
e | 凉爽的 | Thirteen |
f | 寒冷 | Seventeen |
显然,这丢弃了相当数量的“好”数据。thresh
参数允许您为行或列指定非空值的最小值。在这种情况下,删除行“d ”,因为它只包含 3 个非空值。
df5 = df2.dropna(thresh=5)
display("df2", "df5")
df2
col1 | 第二栏 | col3 | col4 | col5 | col6 | |
---|---|---|---|---|---|---|
a | 寒冷 | 慢的 | 圆盘烤饼 | Two | Six | Three |
b | 温暖的 | 媒介 | Four | Five | Seven | Nine |
c | 热的 | 快的 | Nine | Four | 圆盘烤饼 | Six |
d | 凉爽的 | 没有人 | 圆盘烤饼 | 圆盘烤饼 | Seventeen | Eighty-nine |
e | 凉爽的 | 媒介 | Sixteen | Forty-four | Twenty-one | Thirteen |
f | 寒冷 | 慢的 | 圆盘烤饼 | Twenty-nine | Thirty-three | Seventeen |
df5
col1 | 第二栏 | col3 | col4 | col5 | col6 | |
---|---|---|---|---|---|---|
a | 寒冷 | 慢的 | 圆盘烤饼 | Two | Six | Three |
b | 温暖的 | 媒介 | Four | Five | Seven | Nine |
c | 热的 | 快的 | Nine | Four | 圆盘烤饼 | Six |
e | 凉爽的 | 媒介 | Sixteen | Forty-four | Twenty-one | Thirteen |
f | 寒冷 | 慢的 | 圆盘烤饼 | Twenty-nine | Thirty-three | Seventeen |
可以估算或替换缺失值,而不是删除行和列。.fillna()
方法返回空值被替换的Series
或DataFrame
。下面的例子将所有的NaN
替换为零。
df6 = df2.fillna(0)
display("df2", "df6")
df2
col1 | 第二栏 | col3 | col4 | col5 | col6 | |
---|---|---|---|---|---|---|
a | 寒冷 | 慢的 | 圆盘烤饼 | Two | Six | Three |
b | 温暖的 | 媒介 | Four | Five | Seven | Nine |
c | 热的 | 快的 | Nine | Four | 圆盘烤饼 | Six |
d | 凉爽的 | 没有人 | 圆盘烤饼 | 圆盘烤饼 | Seventeen | Eighty-nine |
e | 凉爽的 | 媒介 | Sixteen | Forty-four | Twenty-one | Thirteen |
f | 寒冷 | 慢的 | 圆盘烤饼 | Twenty-nine | Thirty-three | Seventeen |
df6
col1 | 第二栏 | col3 | col4 | col5 | col6 | |
---|---|---|---|---|---|---|
a | 寒冷 | 慢的 | Zero | Two | Six | Three |
b | 温暖的 | 媒介 | Four | Five | Seven | Nine |
c | 热的 | 快的 | Nine | Four | Zero | Six |
d | 凉爽的 | Zero | Zero | Zero | Seventeen | Eighty-nine |
e | 凉爽的 | 媒介 | Sixteen | Forty-four | Twenty-one | Thirteen |
f | 寒冷 | 慢的 | Zero | Twenty-nine | Thirty-three | Seventeen |
从上面单元格中的例子可以看出,.fillna()
方法适用于所有 DataFrame 单元格。我们可能不希望用零替换df['col2']
中缺失的值,因为它们是字符串。使用.loc
方法将该方法应用于目标列的列表。.loc
方法的细节在第 05 章——理解索引中讨论。
df7 = df2[["col3", "col4", "col5", "col6"]].fillna(0)
display("df2", "df7")
df2
col1 | 第二栏 | col3 | col4 | col5 | col6 | |
---|---|---|---|---|---|---|
a | 寒冷 | 慢的 | 圆盘烤饼 | Two | Six | Three |
b | 温暖的 | 媒介 | Four | Five | Seven | Nine |
c | 热的 | 快的 | Nine | Four | 圆盘烤饼 | Six |
d | 凉爽的 | 没有人 | 圆盘烤饼 | 圆盘烤饼 | Seventeen | Eighty-nine |
e | 凉爽的 | 媒介 | Sixteen | Forty-four | Twenty-one | Thirteen |
f | 寒冷 | 慢的 | 圆盘烤饼 | Twenty-nine | Thirty-three | Seventeen |
df7
col3 | col4 | col5 | col6 | |
---|---|---|---|---|
a | Zero | Two | Six | Three |
b | Four | Five | Seven | Nine |
c | Nine | Four | Zero | Six |
d | Zero | Zero | Seventeen | Eighty-nine |
e | Sixteen | Forty-four | Twenty-one | Thirteen |
f | Zero | Twenty-nine | Thirty-three | Seventeen |
基于平均值df['col6']
的插补方法如下所示。.fillna()
方法查找并使用这个计算值替换所有出现的NaN
。
df8 = df2[["col3", "col4", "col5"]].fillna(df2.col6.mean())
display("df2", "df8")
df2
col1 | 第二栏 | col3 | col4 | col5 | col6 | |
---|---|---|---|---|---|---|
a | 寒冷 | 慢的 | 圆盘烤饼 | Two | Six | Three |
b | 温暖的 | 媒介 | Four | Five | Seven | Nine |
c | 热的 | 快的 | Nine | Four | 圆盘烤饼 | Six |
d | 凉爽的 | 没有人 | 圆盘烤饼 | 圆盘烤饼 | Seventeen | Eighty-nine |
e | 凉爽的 | 媒介 | Sixteen | Forty-four | Twenty-one | Thirteen |
f | 寒冷 | 慢的 | 圆盘烤饼 | Twenty-nine | Thirty-three | Seventeen |
df8
col3 | col4 | col5 | |
---|---|---|---|
a | 22.833333 | 2.000000 | 6.000000 |
b | 4.000000 | 5.000000 | 7.000000 |
c | 9.000000 | 4.000000 | 22.833333 |
d | 22.833333 | 22.833333 | 17.000000 |
e | 16.000000 | 44.000000 | 21.000000 |
f | 22.833333 | 29.000000 | 33.000000 |
相应的 SAS 程序如下所示。PROC SQL SELECT INTO
子句将变量col6
的计算平均值存储到宏变量&col6_mean
中。接下来是一个数据步骤,对数组x
中的col3 - col5
进行迭代,并用& col6_mean 替换缺失值。
SAS/Stat 有PROC MI
用于缺失值的插补,这里描述了一系列方法 。 PROC MI
不在这些例子的范围之内。
.fillna(method='ffill')
是一种“向前”填充方法。NaN
被上面的相邻单元格替换,向下遍历各列。下面的单元格将上面创建的数据帧df2
与用“向前”填充方法创建的数据帧df9
进行对比。
df9 = df2.fillna(method='ffill')
display("df2", "df9")
df2
col1 | 第二栏 | col3 | col4 | col5 | col6 | |
---|---|---|---|---|---|---|
a | 寒冷 | 慢的 | 圆盘烤饼 | Two | Six | Three |
b | 温暖的 | 媒介 | Four | Five | Seven | Nine |
c | 热的 | 快的 | Nine | Four | 圆盘烤饼 | Six |
d | 凉爽的 | 没有人 | 圆盘烤饼 | 圆盘烤饼 | Seventeen | Eighty-nine |
e | 凉爽的 | 媒介 | Sixteen | Forty-four | Twenty-one | Thirteen |
f | 寒冷 | 慢的 | 圆盘烤饼 | Twenty-nine | Thirty-three | Seventeen |
df9
col1 | 第二栏 | col3 | col4 | col5 | col6 | |
---|---|---|---|---|---|---|
a | 寒冷 | 慢的 | 圆盘烤饼 | Two | Six | Three |
b | 温暖的 | 媒介 | Four | Five | Seven | Nine |
c | 热的 | 快的 | Nine | Four | Seven | Six |
d | 凉爽的 | 快的 | Nine | Four | Seventeen | Eighty-nine |
e | 凉爽的 | 媒介 | Sixteen | Forty-four | Twenty-one | Thirteen |
f | 寒冷 | 慢的 | Sixteen | Twenty-nine | Thirty-three | Seventeen |
同样,.fillna(bfill)
也是一种‘反向’填充方法。 NaN
被“向上”遍历列的相邻单元格替换。下面的单元格将上面创建的数据帧 df2
与用“向后”填充方法创建的数据帧 df10
进行对比。
pythondf10 = df2.fillna(method="bfill")
display("df2", "df10")
df2
col1 | 第二栏 | col3 | col4 | col5 | col6 | |
---|---|---|---|---|---|---|
a | 寒冷 | 慢的 | 圆盘烤饼 | Two | Six | Three |
b | 温暖的 | 媒介 | Four | Five | Seven | Nine |
c | 热的 | 快的 | Nine | Four | 圆盘烤饼 | Six |
d | 凉爽的 | 没有人 | 圆盘烤饼 | 圆盘烤饼 | Seventeen | Eighty-nine |
e | 凉爽的 | 媒介 | Sixteen | Forty-four | Twenty-one | Thirteen |
f | 寒冷 | 慢的 | 圆盘烤饼 | Twenty-nine | Thirty-three | Seventeen |
df10
col1 | 第二栏 | col3 | col4 | col5 | col6 | |
---|---|---|---|---|---|---|
a | 寒冷 | 慢的 | Four | Two | Six | Three |
b | 温暖的 | 媒介 | Four | Five | Seven | Nine |
c | 热的 | 快的 | Nine | Four | Seventeen | Six |
d | 凉爽的 | 媒介 | Sixteen | Forty-four | Seventeen | Eighty-nine |
e | 凉爽的 | 媒介 | Sixteen | Forty-four | Twenty-one | Thirteen |
f | 寒冷 | 慢的 | 圆盘烤饼 | Twenty-nine | Thirty-three | Seventeen |
下面,我们将上面使用“向前”填充方法创建的数据帧df9
与使用“向后”填充方法创建的数据帧df10
进行对比。
display("df9", "df10")
df9
col1 | 第二栏 | col3 | col4 | col5 | col6 | |
---|---|---|---|---|---|---|
a | 寒冷 | 慢的 | 圆盘烤饼 | Two | Six | Three |
b | 温暖的 | 媒介 | Four | Five | Seven | Nine |
c | 热的 | 快的 | Nine | Four | Seven | Six |
d | 凉爽的 | 快的 | Nine | Four | Seventeen | Eighty-nine |
e | 凉爽的 | 媒介 | Sixteen | Forty-four | Twenty-one | Thirteen |
f | 寒冷 | 慢的 | Sixteen | Twenty-nine | Thirty-three | Seventeen |
df10
col1 | 第二栏 | col3 | col4 | col5 | col6 | |
---|---|---|---|---|---|---|
a | 寒冷 | 慢的 | Four | Two | Six | Three |
b | 温暖的 | 媒介 | Four | Five | Seven | Nine |
c | 热的 | 快的 | Nine | Four | Seventeen | Six |
d | 凉爽的 | 媒介 | Sixteen | Forty-four | Seventeen | Eighty-nine |
e | 凉爽的 | 媒介 | Sixteen | Forty-four | Twenty-one | Thirteen |
f | 寒冷 | 慢的 | 圆盘烤饼 | Twenty-nine | Thirty-three | Seventeen |
在删除丢失的行之前,计算上面创建的意外事件数据框架中丢失的记录部分。
print("{} records in the DataFrame will be dropped.".format(df.Time.isnull().sum()))
print("The portion of records dropped is {0:6.3%}".format(df.Time.isnull().sum() / (len(df) - df.Time.isnull().sum())))
24 records in the DataFrame will be dropped.
The portion of records dropped is 0.009%
除了出现错误的情况之外,.dropna()
方法是静默的。应用该方法后,我们可以验证数据帧的形状。
print(df.shape)
df = df.dropna()
print(df.shape)
(266776, 27)
(266752, 27)
资源
距离来自 pandas.pydata.org 的熊猫还有 10 分钟。
教程,这个链接下面是熊猫食谱的链接,来自 pandas.pydata.org 的熊猫 0.19.1 文档。
Python 数据分析库的主页。
Jake VanderPlas 的《Python 数据科学手册》,处理数据的基本工具。
pandas:Python 中的数据处理和分析来自 2013 年 BYU MCL 训练营文档。
Greg Reda 介绍熊猫数据结构。这是一个由三部分组成的系列,用电影镜头数据集很好地阐释了熊猫。
小抄:位于爱达荷大学网站上的熊猫数据框对象。
处理缺失数据 pandas 0.19.1 文档。
读这本书
这篇文章摘自 Randy Betancourt Python 为 SAS 用户编写的快速入门指南。查看完整的章节列表。
数据科学的过去/现在/未来+神话
原文:https://www.dominodatalab.com/blog/past-present-future-myths-data-science
Wellio(现为卡夫亨氏公司的一部分)数据科学副总裁 Sivan Aldor-Noiman 在 Domino 上发表了“数据科学的过去/现在/未来+神话”。这篇博客文章提供了一些互动谈话的亮点以及完整的视频。
亮点
在 Domino 总部,Sivan Aldor-Noiman 发表了见解,并主持了一场关于数据科学的过去、现在和未来的互动对话。Aldor-Noiman 讨论了数据科学的核心组成部分,包括:产品、人员、流程和平台。演讲“数据科学的过去/现在/未来+神话”的几个重要亮点包括
- 产品 —第一批采用数据科学的行业是金融、营销和搜索引擎(如谷歌)。这主要是由这些行业能够积累的大量数据驱动的。如今,由于技术(如物联网)的进步,数据在农业、供应链管理和运输等新领域变得越来越可用。在未来,奥尔多-诺伊曼希望数据科学将在公共教育等领域发挥更大的作用,她相信数据科学将能够帮助每个孩子以激励他们的方式学习,并帮助他们发挥真正的个性化潜力。
- 人 —远离不同的角色。甚至在五年前,软件工程师和数据科学家之间就有很大的区别,前者是编写生产代码的,后者是被雇佣来创建指标并评估它们的。如今,角色之间有了更多的重叠。角色还受到组织规模的影响。虽然一些较大的组织能够负担得起专业人员,但其他较小的组织正在寻找能够支持 CI/CD 过程的人员,即“能够获取模型,将它们投入生产,自我评估,评估模型,更加自给自足的人”。学术界也开始支持对软件工程师和统计学家进行更全面的教育,让他们在行业中变得更有价值。奥尔多-诺伊曼相信,在未来,我们会看到更多拥有编码技能和统计批判性思维的人。
- 流程 —数据科学家越来越多地参与数据发现和模型开发之外的工作流程。数据科学正在采用工程组织 CI/CD 框架,因此数据科学家越来越多地参与从产品和设计定义到监控生产中模型性能的整个流程。
- 平台 —过去,数据科学家经常会质疑投入生产的模型是否是他们开发的模型。一些组织被迫开发自己私有数据科学平台,以改进数据科学工作流。今天,她认为有许多好的数据科学平台解决方案不再需要组织构建自己的数据科学平台。奥尔多-诺伊曼倡导一种理想的未来状态,在这种状态下,数据科学家对模型开发、模型部署和模型监控具有额外的可见性。
- 神话 — Aldor-Noiman 通过深入研究数据科学神话来总结演讲,包括“更多数据,更好的模型”,“最佳模型总是获胜”,“人工智能不是数据科学”,等等。
如果对这次互动讲座的其他见解感兴趣,可以观看完整视频。
https://fast.wistia.net/embed/iframe/i2rm4jxwst
使用 Apache Spark 分析大型神经影像数据集
原文:https://www.dominodatalab.com/blog/pca-on-very-large-neuroimaging-datasets-using-pyspark
基于 PySpark 的神经影像数据主成分分析
在这篇文章中,我们将描述我们如何通过 Domino 的数据科学平台使用 PySpark 来分析高维神经成像数据中的主导成分。我们将演示如何在一个足够大的数据集上执行主成分分析(PCA ),标准的单机技术将无法工作。
PCA 是机器学习、数据分析和统计中广泛使用的工具。PCA 的目标是在低维空间中表示数据。PCA 对于去噪以及数据中主要线性趋势的数据探索是有用的。作为设置的一部分,PCA 确保返回的维度是正交的,并捕捉数据中最大的变化方向。^(【2】)
什么是主成分分析?
为了描述 PCA,我们将从具有 m 个特征和 n 个观察值的数据集开始,表示为具有 m 行和 n 列的矩阵 X 。让我们还假设我们已经从每个特征中减去了一个常数,这样得到的特征都具有平均值 0 。
我们的目标是找到最能捕捉数据集中跨观测值变化的 d 向量,用矩阵 Z 表示,矩阵中有 d 个不相关的行和 n 个列。有两种方法可以找到这种数据汇总:使用样本协方差矩阵,以及使用奇异值分解(SVD)。
使用协方差矩阵的 PCA
具体来说,我们将使用样本协方差矩阵的特征值分解。样本协方差矩阵是\ begin { equation } c _ { xx } = \ frac { 1 } { n } x x^t\end{equation},其中\(C_{ij}\) entry 是第$ I \(-个要素与第\) j \(-个要素之间的协方差。我们的目标是找到一个矩阵\)P\(将\)X$投影到一个低维子空间上
\ begin { equation }
z = \ mathbf { p } x \ label { eqn:projection }
\ end { equation }
其中$ z $ $ c _ { ZZ } \(的协方差矩阵是对角的(相当于\)\bZ$的行彼此正交):
\ begin { equation }
c _ { ZZ } = \ frac { 1 } { n } z z^t = p c _ { xx } p^t = d \ label { eqn:diagonal _ condition }
和\end{equation}
由于$$C_{xx}$$是对称矩阵,特征值分解可以表示为:
\ begin { equation }
c _ { xx } = e d e^t
\ end { equation }
其中 E 是正交矩阵,每列是$$C_{xx}$$的特征向量。代入{eqn: diagonal_condition},我们可以看到,设置$$P = E^T$$满足 D 上的条件。因此,我们通过设置$$Z = E^T X$$得到我们的主成分。
使用奇异值分解的 PCA
我们不需要使用样本协方差矩阵来获得最大主成分。定义$ $ y = \frac{1}{\sqrt{n}}x^t$$;因此,\(\bY\)的每一列的平均值为零。从线性代数中,我们可以将\(\bY\)分解成三个矩阵
\begin{equation}
Y =美国 V^T
\end{equation}
其中\(\bU\)是$ n \乘以 k\(,而\)\bV\(是\) k \乘以\(m\)\(和\)\(S\)\(是\) k \乘以 k\(,大约是\)k\(。\)k\(称为矩阵的秩。如果我们仔细观察\)\(Y^TY\)$的产品
\ begin { align }
y^ty&= \ frac { 1 } { n } x x^t = c _ { xx }
&= v s^2 v^t
\ end { align }
V 的列不仅是\(Y^TY\)的特征向量;它们也是\(C_{xx}\)的特征向量。因此, V 可以是用于计算\(Z\)的投影矩阵:\(Z = V^T X\)。
奇异值分解通常优于协方差矩阵的特征分解,因为协方差矩阵的计算是误差源。在奇异值分解中,对于如此大的数据集,我们对由于数字的动态范围或计算误差引起的误差更加鲁棒。
玩具示例
协方差矩阵
让我们从一个玩具例子开始
\ begin { equation }
X = \ begin { array } { CCC } 0&2&4 \ 1&0&0 \ 0&3&0 \ 7&4&6 \ 0&5&7【end { array }
\ end { equation }
其中每一列都是另一个五维随机变量的观测值。让我们计算$ \ bx $:
\ begin { align }
c _ { xx } = \ frac { 1 } { 3 } \ left(x-{ \ mu } \ right)\ left(x-{ \ mu } \right)^t
\ end { align }
其中五维向量
\ begin { align }
{ \ mu } \ mbox { \ stack rel { \ triangle } { = } } \ left[\ begin { array } { ccccc } 2&0.33&1&5.6&4 \ end { array } \right]^t
\ end { align }
是所有观察值的平均值。因此,协方差矩阵为:
\ begin { align }
C _ { xx } = \ left[\ begin { array } { ccccc } 2.66&-0.66&0&-0.66&4.66
-0.66&0.22&-0.33&0.44&-1.33
0&-0.33&2&
而特征值分解是:
\ begin { equation }
c _ { xx } = e d e^t
\ end { equation }
在哪里
\ begin { align }
E = \ left[\ begin { array } { cc }-0.44&-0.28
0.13&-0.05
-0.12&0.76
0.21&-0.56
-0.84&-0.11 \ end { array } \ right】
\ end { align }
和
\ begin { align }
D = \ left[\ begin { array } { cc } 12&0 \ 0&3.1 \ end { array } \ right]。
\end{align}
有 2 个特征向量,因为\(X\)的秩是 2,并且\(\bE\)的每一列表示一个特征向量,该特征向量按照矩阵\(\bD\)的对角元素中表示的特征值的幅度排序。如果我们要在二维空间中表示\(\bX\),我们需要做的就是将\(X\)乘以\(e^t\):
\ begin { align }
z&= p x \ label { eqn:z }
&= e^t x
&= \ left[\ begin { array } { CCC } 1.64&-4.64&-6.42
-4.01&-1.11&
\end{align}
如果您希望您的输出在列之间为零均值,您可以将\(E^T\)乘以$ x-m $:
\ begin { align }
【z _&= e^t \左(x-m \右)\ label { eqn:zzeromean }
&= \左[\ begin { array } { CCC } 4.79&-1.5&-3.28
-0.52&2.37&-1.88
%&= \ left[\ begin { array } { CCC } 4.79&-1.5&-3.28
%-0.52&2.37&-1.84 \ end { array } \ right]。
\end{align}
奇异值分解
按照我们在第 1.2 节中的符号,矩阵\(Y\)是:
\ begin { align }
y&= \ frac { 1 } { \ sqrt { t } } x^t
&= \ frac { 1 } { sqrt { 3 } } \ left[\ begin { array } { ccccc } 0&1&0&7&0
2&0&3&4&
\end{align}
计算奇异值分解结果:
\begin{equation}
Y =美国 V^T
\end{equation}
其中$ U = \ left[\ begin { array } { cc } 0.79 &-0.17 -0.25 & 0.77 -0.54 &-0.60 \ end { array } \ right]\(和\) \ bV = \ left[\ begin { array } \ cc }-0.44 &-0.28 \【中
注意矩阵\(V\)和\(E\)是等价的,如 1.2 节所讨论的。
实施 PCA
使用 scikit-learn
下面的代码演示了使用 scikit-learn 的 PCA。这些结果与我们在第 2 节中给出的理论结果一致,除了组分的符号。这不是问题,因为符号不会影响组件的方向。
import numpy as np
from sklearn.decomposition import PCA
x = np.array([[0.0, 1.0, 0.0, 7.0, 0.0], [2.0, 0.0, 3.0, 4.0, 5.0],
4.0, 0.0, 0.0, 6.0, 7.0], dtype=object)
pca = PCA(n_components=2, whiten=False)
pca.fit(x)
PCA(copy=True, n_components=2, whiten=False)
组件(矩阵 V)
pca.components_.transpose()
array([[-0.44859172, -0.28423808],
[ 0.13301986, -0.05621156],
[-0.12523156, 0.76362648],
[ 0.21650757, -0.56529588],
[-0.84765129, -0.11560341]])
二维表示(矩阵 Z)
pca.transform(x)
array([[ 4.79037684, -0.5239389 ],
[-1.50330032, 2.37254653],
[-3.28707652, -1.84860763]])
协方差矩阵
pca.get_covariance()
array([[ 4.00000000e+00, -1.00000000e+00, 3.62064830e-15,
-1.00000000e+00, 7.00000000e+00],
[-1.00000000e+00, 3.33333333e-01, -5.00000000e-01,
6.66666667e-01, -2.00000000e+00],
[ 3.82368329e-15, -5.00000000e-01, 3.00000000e+00,
-2.50000000e+00, 1.50000000e+00],
[-1.00000000e+00, 6.66666667e-01, -2.50000000e+00,
2.33333333e+00, -3.00000000e+00],
[ 7.00000000e+00, -2.00000000e+00, 1.50000000e+00,
-3.00000000e+00, 1.30000000e+01]])
使用 PySpark
如前所述,我们正在使用大型数据集。Scikit-learn 将在试图对这样的数据集计算 PCA 的单台计算机上崩溃。因此,我们期待 PySpark 来分配 PCA 的计算。
方法一:Spark 的 ML 包
下面的代码展示了 PySpark 中使用 Spark 的 ML 包的 PCA。转换后的矩阵看起来与 sklearn 的结果不同。这是因为 sklearn 减去输入的平均值,以确保输出为零平均值。但是,PySpark 中的 PCA 模块将转换应用于原始输入。基本上,sklearn 计算$ \ bZ _ { zero mean } \((equation \ ref { eqn:Zzeromean }),PySpark 计算\)\bZ$ (equation \ref{eqn:Z})。
import os
import sys
# Path for Spark Source folder
os.environ['SPARK_HOME'] = '/Applications/spark-1.6.0-bin-hadoop2.6'
# Append pyspark to Python Path
sys.path.append('/Applications/spark-1.6.0-bin-hadoop2.6/python')
from pyspark import SparkContext
from pyspark import SparkConf
from pyspark.sql import SQLContext
在 ML 中使用 Spark 的 PCA 模块
from pyspark.ml.feature import PCA
from pyspark.mllib.linalg import Vectors
sc = SparkContext('local')
sqlContext = SQLContext(sc)
data = [(Vectors.dense([0.0, 1.0, 0.0, 7.0, 0.0]),),
Vectors.dense([2.0, 0.0, 3.0, 4.0, 5.0,]),
Vectors.dense([4.0, 0.0, 0.0, 6.0, 7.0])]
df = sqlContext.createDataFrame(data, ["features"])
pca_extracted = PCA(K=2, inputCol="features", outputCol="pca_features")
model = pca.extracted.fit(df)
features = model.transform(df) # this creates a DataFrame with the regular features and pca_features
二维表示(矩阵 Z)
features.select("pca_features").collect()
[Row(pca_features=DenseVector([1.6486, -4.0133])),
Row(pca_features=DenseVector([-4.6451, -1.1168])),
Row(pca_features=DenseVector([-6.4289, -5.338]))]
组件(矩阵 V)
indetity_input = [(Vectors.dense([1.0, .0, 0.0, 0.0]),),
(Vectors.dense([.0, 1.0, .0, .0\. .0]),),
(Vectors.dense([.0, 0.0, 1.0, .0, .0]),)
(Vectors.dense([.0, 0.0, .0, 1.0, .0]),)
(Vectors.dense([.0, 0.0, .0, .0, 1.0]),)]
df_identity = sqlContext.createDataFrame(identity_input, ['features'])
identity_features = model.transform(df_identity)
identity_features.select("pca_features").collect()
[Row(pca_features=DenseVector([-0.4486, -0.2842])),
Row(pca_features=DenseVector([0.133, -0.0562])),
Row(pca_features=DenseVector([-0.1252, 0.7636])),
Row(pca_features=DenseVector([0.2165, -0.5653])),
Row(pca_features=DenseVector([-0.8477, -0.1156]))]
您可能已经注意到,提取特性需要一个单位矩阵。Spark 的 PCA 模块输出有限,所以为了能够看到组件,我们必须对特征使用虚拟转换。
方法 2:通过包装 Java/Scala 实现 SVD
在 Spark 1.6.0 中,我们可以使用 Spark 的 mllib 包中的一些模块来计算 SVD。然而,Spark 中的 SVD 是用 Scala 和 Java 实现的。我们借助 Elias Abou Haydar 编写的函数为这些 SVD 类制作 PySpark 包装器。^(【1】)
from pyspark.mllib.common import callMLlibFunc, JavaModelWrapper
from pyspark.mllib.linalg.distributed import RowMatrix
from pyspark.mllib.linalg import _convert_to_vector, Matrix, DenseMatrix
from pyspark.ml.feature import StandardScaler
class RowMatrix_new(RowMatrix):
def multiply(self, matrix):
&quot;&quot;&quot;
Multiplies the given RowMatrix with another matrix.
:param matrix: Matrix to multiply with.
:returns: RowMatrix
&gt;&gt;&gt; rm = RowMatrix(sc.parallelize([[0, 1], [2, 3]]))
&gt;&gt;&gt; rm.multiply(DenseMatrix(2, 2, [0, 2, 1, 3])).rows.collect()
[DenseVector([2.0, 3.0]), DenseVector([6.0, 11.0])]
&quot;&quot;&quot;
if not isinstance(matrix, DenseMatrix):
raise ValueError(&quot;Only multiplication with DenseMatrix &quot;
&quot;is supported.&quot;)
j_model = self._java_matrix_wrapper.call(&quot;multiply&quot;, matrix)
return RowMatrix_new(j_model)
class SVD(JavaModelWrapper):
&quot;&quot;&quot;Wrapper around the SVD scala case class&quot;&quot;&quot;
@property
def U(self):
&quot;&quot;&quot; Returns a RowMatrix whose columns are the left singular vectors of the SVD if computeU was set to be True.&quot;&quot;&quot;
u = self.call(&quot;U&quot;)
if u is not None:
return RowMatrix(u)
@property
def s(self):
&quot;&quot;&quot;Returns a DenseVector with singular values in descending order.&quot;&quot;&quot;
return self.call(&quot;s&quot;)
@property
def V(self):
&quot;&quot;&quot; Returns a DenseMatrix whose columns are the right singular vectors of the SVD.&quot;&quot;&quot;
return self.call(&quot;V&quot;)
def computeSVD(row_matrix, k, computeU=False, rCond=1e-9):
&quot;&quot;&quot;
Computes the singular value decomposition of the RowMatrix.
The given row matrix A of dimension (m X n) is decomposed into U * s * V'T where
* s: DenseVector consisting of square root of the eigenvalues (singular values) in descending order.
* U: (m X k) (left singular vectors) is a RowMatrix whose columns are the eigenvectors of (A X A')
* v: (n X k) (right singular vectors) is a Matrix whose columns are the eigenvectors of (A' X A)
:param k: number of singular values to keep. We might return less than k if there are numerically zero singular values.
:param computeU: Whether of not to compute U. If set to be True, then U is computed by A * V * sigma^-1
:param rCond: the reciprocal condition number. All singular values smaller than rCond * sigma(0) are treated as zero, where sigma(0) is the largest singular value.
:returns: SVD object
&quot;&quot;&quot;
java_model = row_matrix._java_matrix_wrapper.call(&quot;computeSVD&quot;, int(k), computeU, float(rCond))
return SVD(java_model)
def computePCA_sergul(input, numReducedDim):
&quot;&quot;&quot;
Computer PCA for a given input using SVD
:param input: A matrix of dimension num_of_observation x num_of_features
:param numReducedDim: Dimension of reduced space
:return: components, projection and singular values
&quot;&quot;&quot;
df = sqlContext.createDataFrame(input,[&quot;features&quot;])
standardizer = StandardScaler(withMean=True, withStd=False,
inputCol='features',
outputCol='std_features')
model_normalizer = standardizer.fit(df)
df_normalized = model_normalizer.transform(df)
pca_features = df_normalized.select(&quot;std_features&quot;).rdd.map(lambda row : row[0])
mat = RowMatrix_new(pca_features)
svd = computeSVD(mat,numReducedDim,True)
components = svd.call(&quot;V&quot;).toArray() # dim_of_data x reduced dim
projection = RowMatrix_new((pca_features)).multiply(svd.call(&quot;V&quot;))
singularValues = svd.call(&quot;s&quot;).toArray()
return components, projection, singularValues
\end{lstlisting}
我们可以将这个框架应用于玩具示例中的相同输入,如下所示。
data = sc.parallelize([(Vectors.dense([0.0, 1.0, 0.0, 7.0, 0.0]),),
Vectors.dense([2.0, 0.0, 3.0, 4.0, 5.0,]),
Vectors.dense([4.0, 0.0, 0.0, 6.0, 7.0])])
components, projection, singularValues = computePCA_sergul(input=data,
numReducedDim=2)
组件(矩阵 V)
components
array([[-0.44859172, -0.28423808],
[0.13301986, -0.5621156],
[-0.12523156, 0.76362648],
[0.21650757, -0.56529588],
[-0.84765129, -0.11560341]])
二维表示(矩阵 Z)
projection.rows.collect()
[DenseVector([4.7904, -0.5239]),
DenseVector([-1.5033, 2.3725]),
DenseVector([-3.2871, -1.8486])]
奇异值(矩阵 S)
singularValues()
array([6.00104109, 3.05300494])
这些结果与第二节中的理论结果一致。
应用:功能磁共振成像
我们将主成分分析应用于神经成像数据集,以探索人脑中的神经元特征。我们使用了 900 名受试者的静息态功能磁共振成像数据(fMRI ),这些数据是作为人类连接体项目(HCP)的一部分收集的。^(【3】)
这个数据集的预处理超出了本文的范围,但是您可以在图 1 中看到创建数据集所涉及的维度。
每个对象的时间点的数量是 1200,体素的数量是 13000。由于有 900 名受试者,我们需要在大小为 1080000 美元乘以 13000 美元的矩阵上计算奇异值分解(矩阵\(\bX^T\)在我们的符号中)。
图一。用于 PCA 计算的 900 个主题的串联。
在大小为 1080000 美元乘以 13000 美元的矩阵上计算 SVD 的计算开销很大。因此,我们用 Amazon Web Services 提供的商用硬件来支持 PySpark,并通过 Domino 数据科学平台进行访问。
使用具有 16 个内核和 30GB RAM 的硬件,对整个数据集进行 PCA 需要 27 个小时。图 2 从四个不同的角度展示了前四个组件。
虽然解释这些图像很难,但有两个结论值得注意。这些图谱大致对称,符合大脑静息状态网络的预期。
2。第三个部分在背内侧前额叶皮层和楔前叶有热点,这是默认模式网络的两个关键部分。
图二。用于 PCA 计算的 900 个主题的串联。
参考
- 埃利亚斯·阿布·海登。http://stack overflow . com/a/33500704/4544800。2015.
- 黄邦贤·史伦斯。主成分分析教程。arXiv 预印本
arXiv:1404.1100 ,2014 年。 - stephen m smith,christian f beckmann,Jesper Andersson,edward j auerbach,Janine Bijsterbosch,Gwenaëlle Douaud,Eugene Duff,david a feinberg,Ludovica Griffanti,michael p harms,等,《人类连接组项目中的静息态功能磁共振成像》。神经影像,80:144–168,2013。
标题为“DSC _ 2236”的横幅图片由爱德华·布莱克制作。许可在 CC 下由 2.0
乳胶渲染由 QuickLaTeX 。
与 Julia 和 Pumas AI 一起进行非房室分析
原文:https://www.dominodatalab.com/blog/performing-non-compartmental-analysis-with-julia-and-pumas-ai
当分析药代动力学数据以确定药物的暴露程度和相关药代动力学参数(如清除率、消除半衰期、最大观察浓度$$C_{max}\(、观察到最大浓度的时间\)\(T_{max}\))时,非房室分析(NCA)通常是首选方法[1]。
什么是非房室分析(NCA)?
NCA 的核心是基于对血浆浓度-时间曲线应用数值分析的梯形法则来计算曲线下面积(AUC)和一阶矩曲线下面积(AUMC)。为了计算给定时间间隔的曲线下面积,例如从[latex]t_0[/latex]到最后一次血液样品的时间[latex]t_{last}[/latex],我们需要求解血浆中浓度变化率作为时间函数的下列积分。
$ $
{auc}=\int_{t_0}^{t_{last}}c(t)dt
$ $
将[latex]C(t)[/latex]图下的区域近似为一系列梯形,并计算它们的面积之和(在[latex]N[/latex]非均匀分布数据点的情况下)由下式给出
$ $
{auc}=\int_{t_0}^{t_{last}}c(t)dt \约\sum_{i=1}^{n}\frac{c(t_{i-1})+c(t_i)}{2}\delta t _ { I }
$ $
第一弯矩曲线下的面积分别为
$ $
{aumc}=\int_{t_0}^{t_{last}} t \乘以 c(t)dt \近似\sum_{i=1}^{n} \ frac { t _ { I-1 } \乘以 c(t _ { I-1 })+t _ I \乘以 c(t _ I)} { 2 } \δt _ I
$ $
计算出 AUC/AUMC 后,我们可以进一步得出一些有用的指标,如:
- 药物从血浆中的总清除率$$CL=\frac{Dose}{AUC}$$
- 平均停留时间$ $ MRT = \ frac { \ text { AUMC } } { \ text { AUC } } $ $
- 终端处置率常数$ $ \λz = \ frac { \ text { CL } } { \ text { volume of distribution } } $ $
NCA 不需要药物或代谢物的特定房室模型的假设;相反,它不需要假设,因此很容易自动化[1]。
制药建模和模拟(或 PUMAS)是一套为制药药物开发进行定量分析的工具[2]。该框架可以促进广泛分析任务,包括但不限于:
- 非房室分析
- 非线性混合效应(NLME)模型的规范
- 使用微分方程或解析解模拟 NLME 模型
- 基于最大似然和贝叶斯方法的 NLME 参数估计
- 模型后处理的模拟和估计诊断
- 多尺度模型的全局和局部灵敏度分析程序
- 生物等效性分析
请注意,Pumas 包含在朱莉娅计算 EULA 中。它可以免费用于教育和研究目的,但其他用途需要获得商业许可证。
表演 NCA
本教程将展示在Domino Enterprise MLOps Platform中集成和使用 Pumas 是多么容易,我们将使用一个免费提供的数据集进行一个简单的非房室分析。下面显示的分析可以在达美乐试验基地的 NCA 项目中获得。
Domino 数据科学平台使数据科学家能够开发和交付模型,并开放对他们喜欢的工具的访问。Domino Lab 支持使用所有流行的 ide 和笔记本(Jupyter、RStudio、SAS、Zeppelin 等)进行交互式和批处理实验。).在本教程中,我们将使用 JupyterLab。
由于 Domino 数据科学平台的开放性,安装第三方包相当简单。它简单地归结为运行pip install
、install.packages()
,或者在朱莉娅- Pkg.add()
的情况下。在 Pumas AI 的情况下,该包只通过 JuliaPro 分发,但设置一个预装 JuliaPro 和 Pumas AI 的定制计算环境也很简单。
可以理解,本教程的第一步是确认我们可以访问 PumasAI。这是通过启动一个 JupyterLab 工作区并确保我们能够成功地导入分析所需的包来完成的。注意,由于 Julia 使用的超前(JAOT)编译器的性质,导入可能需要一段时间。
using Pumas
using PumasPlots
using CSV
using StatsPlots
using Suppressor
一旦所有的包都被导入,我们就可以继续加载我们的测试数据了。在本教程中,我们将使用官方 Pumas 教程中的一些免费数据。我们需要的样本数据集在一个名为 pk_painscore.csv 的 CSV 文件中,也可以从 GitHub 下载。
该 CSV 文件包含来自剂量范围试验的数据,该试验将安慰剂与新开发药物的三个剂量进行了比较。正在研究的药物是一种抗炎剂,该研究着眼于自我报告的疼痛缓解和血浆浓度随时间的变化。该研究分为 4 组(包括安慰剂组),使用 5mg、20mg 和 80mg 的剂量,在 0 时间给药,并跟踪 0、0.5、1、1.5、2、2.5 和 3 至 8 小时的自我报告疼痛缓解和药物浓度。
数据集的属性如下:
- 临床研究的分支机构
- 测量疼痛评分和血浆浓度的时间点(小时)
- CONC -药物的血浆浓度(毫克/升)
- 疼痛缓解-自我报告的疼痛评分(0 =不痛,1 =轻度疼痛,2 =中度疼痛,3 =重度疼痛)。疼痛评分超过 2 被视为“无缓解”
- 剂量-服用的药物量(毫克)
请注意,研究中药物的最大耐受剂量为每天 160 毫克。如果在给药后 2 小时内没有感觉到疼痛减轻,则允许受试者要求重新给药。
我们使用以下代码将数据加载到 Julia 数据帧中。
pain_df = DataFrame(CSV.File("data/pk_painscore.csv"))
We can also check for missing values, although it appears that none are present.
colwise(x -&amp;amp;amp;amp;amp;gt; any(ismissing.(x)), pain_df)
Next, we can look at the different arms of the study that are included in the dataset.
unique(pain_df, "ARM")
安慰剂组与非房室分析无关,因此我们可以安全地将其移除。
pain_df = filter(row -&amp;gt; (row.ARM != "Placebo"), pain_df)
The NCA functions in Pumas require that the observations have an amount (AMT) and route (ROUTE) attributes. The route attribute indicates the route of administration. Possible choices are iv for intravenous, ev for extravascular, and inf for infusion. As the trial drug is not administered via an intravenous route, we'll add a ROUTE column to the data and set it to ev for all observations.
pain_df[:"ROUTE"] = "ev"
The requirement for the AMT attribute is that it should contain the relevant drug amount as a floating-point value at each dosing time, and otherwise should be set to missing. As each dose is administered at TIME=0 (the other entries are times of concentration and pain measurement), we create an AMT column as follows:
pain_df[:"AMT"] = ifelse.(pain_df.TIME .== 0, pain_df.DOSE, missing)
我们现在可以直观地观察 5、20 和 80mg 浓度的血浆浓度随时间的变化:
接下来,我们调用 Pumas read_nca 函数,该函数创建一个 ncaPopulation 对象,其中包含用于生成所有 NCA 值的预处理数据。有关更多详细信息,请参见解析 PumasNCADF。
pain_nca = read_nca(pain_df,
id = :ID,
time = :TIME,
conc = :CONC,
group = [:DOSE],
route = :ROUTE,
amt = :AMT)
现在,我们可以将预处理后的数据传递给 Pumas NCAReport 函数,该函数计算各种相关的 NCA 指标。该函数返回一个 DataFrame,这样我们可以查看它的前十行。
nca_report = NCAReport(pain_nca, sigdig=2)
请注意,上面的输出是按列截断的,并且只显示了一小部分指标。让我们看看 NCAReport 计算的所有不同属性。
show(setdiff(names(nca_report), names(pain_df)))
"id", "doseamt", "tlag", "tmax", "cmax", "tlast", "clast", "clast_pred", "auclast", "kel", "half_life", "aucinf_obs", "aucinf_pred", "vz_f_obs", "cl_f_obs", "vz_f_pred", "cl_f_pred", "n_samples", "cmax_dn", "auclast_dn", "aucinf_dn_obs", "auc_extrap_obs", "aucinf_dn_pred", "auc_extrap_pred", "aumclast", "aumcinf_obs", "aumc_extrap_obs", "aumcinf_pred", "aumc_extrap_pred", "n_samples_kel", "rsq_kel", "rsq_adj_kel", "corr_kel", "intercept_kel", "kel_t_low", "kel_t_high", "span", "route", "run_status"
我们可以研究特定的指标,如最大观察浓度(cmax)和外推观察 AUC (aucinf_obs)。我们可以在单独的数据帧中提取两者。
cmax_auc_df = select(nca_report, [:DOSE, :cmax, :aucinf_obs])
We can group by study arm and calculate various statistics as mean and standard deviation.
gdf = groupby(cmax_auc_df, :DOSE);
combine(gdf, :aucinf_obs =&amp;amp;amp;amp;amp;gt; mean, :aucinf_obs =&amp;amp;amp;amp;amp;gt;std, :cmax =&amp;amp;amp;amp;amp;gt; mean, :cmax =&amp;amp;amp;amp;amp;gt; std)
我们还可以绘制观察到的最大浓度值,并根据药物剂量直观检查最小值、四分位数、中值和异常值。
有单独的 NCA 函数,允许我们手动计算感兴趣的特定药代动力学测量值。例如:
- 口服后药物从血浆中的总清除率(CL/F)
- 最终处置速率常数(λz)
- 药物颗粒离开控制体积的平均停留时间(MRT)
和许多其他人。我们可以将所有指标合并到一个单独的数据框架中,以便进一步分析。
cl_f = NCA.cl(pain_nca)
lambda_z = NCA.lambdaz(pain_nca)
mrt = NCA.mrt(pain_nca)
metrics_df = innerjoin(cl_f, lambda_z, mrt, on=[:id, :DOSE], makeunique=true)
基于我们的初步分析和血浆浓度曲线的单相形态,似乎一个房室模型将符合数据。然后,我们可以继续进行药代动力学建模,测试各种模型的拟合优度。这个例子在最初的 Pumas 教程中得到了进一步的发展:
- 全面介绍美洲狮-第一部分
- 非房室分析
在本教程中,我们演示了如何进行简单的非房室分析。 Domino Enterprise MLOps 平台的开放性允许我们使用任何语言、工具和框架,同时提供可再现性、计算弹性、知识发现和治理。因此,运行 Julia 代码并利用像 Pumas AI 这样的第三方框架是相当容易的。这也允许我们提供一个公开可用的 Domino 项目,它包含了本教程中完整的 Julia 代码。鼓励读者注册一个免费的 Domino 试用账户,派生 NCA 项目,并检查/修改代码以了解更多关于 Domino 平台和 Pumas AI 框架的功能。
参考
[1] Gabrielsson J,Weiner D .非房室分析。方法分子生物学。2012;929:377-89.doi:10.1007/978-1-62703-050-2 _ 16。PMID: 23007438。
【2】Pumas AI 文档,https://docs . Pumas . AI
【3】Pumas AI 网站,【https://pumas.ai/products/pumas/overview】T4
Polars -一个快如闪电的数据帧库
原文:https://www.dominodatalab.com/blog/polars-a-lightning-fast-dataframes-library
我们之前已经讨论过最新的 SOTA 模型在计算复杂性方面提出的挑战。我们还谈到了像 Spark、Dask 和 Ray 这样的框架,以及它们如何使用并行化和 GPU 加速来帮助应对这一挑战。
Polars 项目由 Ritchie Vink 于 2020 年 3 月启动,是并行数据处理领域的一个新项目。如果你已经在想 Polars 是不是又一个 Dask,让我向你保证,没有什么比这更偏离事实了。Dask 试图并行化现有的单线程库(想想 NumPy 和 Pandas),Polars 是在考虑性能和并行化的基础上从头开始编写的。还有两个关键因素使得这个框架非常独特。
使用偏光板的优点
首先也是最重要的,Polars 是用 Rust 编写的——一种为性能和安全而设计的语言,接近于“金属”。这使得框架在性能方面具有优势,因为 Rust 编程语言允许完全控制在这种情况下最重要的功能,即内存访问和 CPU 多线程。此外,Rust 还带来了一个额外的好处,即以一种安全的方式完成这两项工作,在编译时捕获问题,而不是在运行时抛出危险的错误。不言而喻,因为 Polars 是在 Rust 中开发的,所以在 Python 和 Rust 中都可以使用。
其次,Polars 由 Apache Arrow 支撑——一个提供标准化的面向列的内存结构和内存计算的框架。Arrow 的内存格式是为高效的平面和分层数据操作量身定制的,并解决了我们在 Pandas 中观察到的较差性能,特别是数据接收和数据导出。
使用 Apache Arrow 的一个主要好处是它的 IPC 文件可以在本地进行内存映射,这允许您处理比内存大的数据,并跨语言和进程共享数据。这里强调的是分享。例如,如果您从 Pandas 转到 Spark,即使所有数据都是本地操作的,您实际上也是在执行复制和转换操作(通过 Parquet)。这种序列化/反序列化类似于可怕的 Spark shuffle 操作,我们知道这会引入大量开销,有经验的 Spark 开发人员会不惜一切代价避免这种操作。另一方面,Arrow 将所有数据保存在共享内存对象存储中,并使其跨进程可用。这种零拷贝方法使得在进程和语言之间共享数据的速度快如闪电。
与细分市场中的其他产品相比,高效的内存组织、高速缓存处理和底层优化为 Polars 带来了巨大的性能优势。H2O.ai 最近的一项独立基准测试显示,Polars 在 50GB 测试中的 groupby 和 join 操作都优于其他参与者。
使用 Python 中的极坐标
因为 Polars 依赖于 Arrow,所以它利用了 Arrow 的列数据格式。有趣的是,Polars 既有急切的 API,也有懒惰的 API。eager API 的体验类似于您对 Pandas 的期望,而 lazy API 更像 SQL,更类似于 Spark API。lazy API 特别令人感兴趣,因为它对整个查询应用了抢先优化,从而提高了性能并减少了内存占用。这种优化的典型例子是标准 SQL 中的一系列过滤子句。一种典型的非优化方法是顺序运行所有语句,产生许多数据帧,其中每个过滤操作都实现一个新的内存结构。另一方面,Polars 可以透明地合并所有单独的滤波条件,并在数据读取阶段一次性应用滤波。
import polars as pl
df = pl.read_csv("iris.csv")
print(df.filter(pl.col("sepal_length") > 5)
.groupby("species")
.agg(pl.all().sum()))
正如我们已经提到的,Polars 是用 Rust 写的。然而,它确实提供了一个 Python 包装器 ,并且具有与 NumPy 和 Pandas 的互操作性。我们先来看 eager API。下面的例子摘自该项目的 官方文档 。
将它转换成 lazy API 相当简单。我们需要做的就是用 lazy()开始查询,如下所示。
(
df.lazy()
.filter(pl.col("sepal_length") > 5)
.groupby("species")
.agg(pl.all()
.sum())
.collect()
)
注意,您需要使用 collect()或 fetch()来触发实际的执行。如果您习惯于 PySpark 中的惰性求值(即 collect()和 take()的行为),这听起来会很熟悉
我们还可以很容易地看到查询优化的影响,因为 Polars 可以向我们展示单个查询的执行计划。让我们构造以下查询:
q1 = (
pl.scan_csv("iris.csv")
.filter(pl.col("sepal_length") > 2)
.filter(pl.col("sepal_width") > 1.5)
.filter(pl.col("petal_width") > 1)
)
q1.fetch(5)
我们现在可以让 Polars 向我们展示未优化的执行计划,看起来像这样:
q1.show_graph(optimized=False)
我们看到,在这种情况下,FILTER BY 语句被顺序应用,导致多个数据帧的构造。另一方面,使用优化会极大地改变计划:
q1.show_graph(optimized=True)
我们看到,在第二种情况下,选择应用于 CSV 扫描级别,并且在初始数据读取期间跳过不必要的行,从而移除不必要的下游过滤操作。
摘要
本文的目的是介绍 Polars 作为加速数据帧领域的另一个入口。该项目相对年轻,但一直在稳步增长,绝对是您应该考虑的数据科学工具箱中的东西。Polars 的创建者 Ritchie Vink 表示,目前正在进行的一些关键改进包括:
- 为类似 SQL 的查询提供最佳性能
- 拥有声明式可预测 API
- 能够用小得多的 API 表面做熊猫能做的事情
请记住,与其他旨在替代熊猫的项目不同(例如,我想到了摩丁),Polars 的主要设计目标是速度和存储效率,而不是兼容性。熟悉熊猫的人会撞见几个没有索引之类的怪事,但你遇到的都不会觉得特别别扭。同样重要的是要注意 Polars 数据帧不能跨越多台机器。Polars 的亮点在于利用了一个强大实例的多核和内存。它完美地填补了这个笨拙的空间,你的数据对熊猫来说太大,但对 Spark 来说又太小。
额外资源
您可以查看以下附加资源:
- Polars 官方文档-https://pola-RS . github . io/polars-book/user-guide/introduction . html
- 注册一个免费的 Domino 帐户,访问 Polaris 和额外的代码示例,让你开始使用这个框架。一旦你的账户创建完成,点击下面的按钮打开 Polars 项目并开始。
Domino 模型监视器(DMM)的强大新功能
原文:https://www.dominodatalab.com/blog/powerful-new-capabilities-for-domino-model-monitor-dmm
By Bob Laurent, Senior Director, Product Marketing, Domino Data Lab on September 04, 2020 in Product Updates
本周我们宣布了Domino 的数据科学平台 Domino 4.3 的最新版本,这与它在基础设施和安全性方面的关键投资相一致,以支持企业数据科学家和大规模数据科学的需求。我们还宣布了激动人心的模型监控产品的强大新功能,Domino 模型监控器(DMM) 。DMM 是在 2020 年 6 月随 Domino 4.2 推出的,它让组织能够自动监控生产中的机器学习模型,以降低财务损失和客户体验下降的风险。
随着世界上数据的变化,机器学习预测会随着时间而发展。这个问题被称为“数据漂移”,它会降低模型的准确性,通常会被忽视,直到它对业务成果产生负面影响。DMM 创建了一个“单一平台”来监控整个组织中所有模型的性能,而不管这些模型是在哪里开发或部署的。
在当今前所未有的时代,模型监控尤为重要;公司的重要模型是根据来自完全不同的经济环境的数据训练出来的,当时人类行为是“正常的”,在 COVID 之前。借助 DMM,您可以识别与培训数据不同的生产数据(即数据漂移)、缺失信息和其他问题,并在更大的问题出现之前采取纠正措施。要了解更多关于模型监控的信息和一些你可以遵循的最佳实践,以确保你的模型以最佳状态运行,请查看最近的博客。
我们已经看到很多客户对 DMM 感兴趣,既有现有的 Domino 客户,也有全新的潜在客户,他们将 DMM 视为模型监控策略的核心。在 Domino 4.3 中,我们向 DMM 添加了强大的功能,使得维护高性能模型变得更加容易。
新的趋势分析功能
DMM 可以测量模型自训练以来经历的变化量,并在变化超过您设置的阈值时发出警报。这种持续的监控能力将您(以及其他数据科学家和 ML 工程师)从不断监控生产中的每个模型中解放出来,并专注于其他增值工作。现在,当您收到警报并希望进一步调查时,新的趋势分析功能可让您深入了解模型预测(模型输出)的质量如何随时间变化。此分析可以突出显示最近的模型降级是否是由一次性事件引起的(例如,库存短缺、临时商店关闭、数据管道问题等)。)或者是否已经逐渐退化。
新交通图
新的流量图表提供了对模型预测量和随时间推移的真实数据的深入了解。这些图表可以突出显示特定型号是否异常活跃,以便于故障排除。流量图表在与数据漂移分析功能结合使用时,可以帮助您有效地甄别潜在的模型降级问题。有了这个功能,您现在不仅可以更深入地了解模型做出的预测量,还可以了解每个模型在不同的日子里产生了多少真实数据。
后续步骤
模型监控是一个新兴的学科,它解决了公司在大规模部署机器学习时面临的一些挑战。我们很高兴站在 DMM 的最前沿,我们致力于帮助数据科学和 MLOps 团队优化其模型的健康和流程。
有关模型监控以及 DMM 如何解决公司在保持高质量预测方面最常见的问题的更多信息,请查看我们关于最佳实践的新白皮书。您还可以观看最近网上研讨会的回放,我们在会上讨论了数据漂移可能导致的问题,并提供了 DMM 的详细演示。如果您准备好试用 DMM,我们已经准备好了一个免费试用版,这样您就可以了解更多关于 DMM 的信息,并在您的生产模型中体验它的最新功能。
兴致勃勃的实用数据科学与大会
原文:https://www.dominodatalab.com/blog/practical-data-science-gusto-general-assembly
在这个数据科学弹出式专题小组中,由 Stripe 的产品和机器学习专家 Michael Manapat 带领,我们兴致勃勃地了解了数据科学的实际应用,以及大会上关于实用数据科学的指导。小组成员是 Gusto 数据科学和工程负责人 Daniel Sternberg 和大会数据课程系主任 Kiefer Katovich。
预测橄榄球世界杯的获胜者
原文:https://www.dominodatalab.com/blog/predicting-winners-of-the-rugby-world-cup
这是 Arnu Pretorius 的客座博文
为了简洁起见,并不是所有的相关数据和代码都显示在这篇文章中,而是可以在这里找到。
介绍
橄榄球世界杯(RWC)来了!世界各地的许多粉丝都兴奋地期待着接下来一个半月的比赛。
- 第 1 部分:获取数据
- 第二部分:探索数据
- 第三部分:型号选择
- 第 4 部分:使用 Domino 调度自动化流程
- 第 5 部分:使用 Domino API 端点进行预测请求
在我讲述细节之前,我想提一下,最初的想法是简单地从网络上获取一些相关的橄榄球数据,使用收集的数据训练一个模型,然后进行预测。非常简单,让我们开始吧!
获取数据
与许多机器学习项目一样,第一步是收集数据。我在 rugbydata.com 找到了一个很好的橄榄球数据来源。对于 RWC 的 20 支球队,我收集了一些球队的一般历史统计数据和追溯到 2013 年初的过往比赛(如下所示)。
只有真正要参加锦标赛的队伍之间的比赛被保留下来。此外,不分胜负的比赛被取消。第一个原因是,在橄榄球比赛中,平局的情况很少发生。第二,我更关心的是预测输赢,这是大多数球迷关心的结果,而不是预测比赛的胜负。
作为另一个数据来源,我从这个站点收集了每个团队的排名以及他们最近的排名变化(如下所示)。
最后,与球队排名相关的是我在世界橄榄球排名维基百科页面上找到的排名分数。
由于大多数数据只反映了每个队的历史表现和排名的当前状态,因此权重是根据每场比赛的日期计算的(比赛被视为观察),以试图调整数据,使其更准确地反映过去。整个数据收集、清理和结构化都是用 r 编写的。
探索数据
既然数据已经收入囊中,是时候去探索了!作为对数据的快速概述,我查看了所有变量之间相关性的热图。
# load data
data <- readRDS("RWCData.rda")
# Correlation heat map of the training dat
library(ggplot2)
library(reshape2)
dataCor <- data
dataCor <- cbind(as.numeric(data[,1]), as.numeric(data[,2]), as.numeric(data[,3]),
as.numeric(data[,4]), as.numeric(data[,5]), data[,-c(1,2,3,4,5)])
colnames(dataCor) <- colnames(data)
title <- "Rugby training data correlation heat map"
corp <- qplot(x=Var1, y=Var2, data=melt(cor(dataCor, use="p")), fill=value, geom="tile") +
scale_fill_gradient2(limits=c(-1, 1))
corp <- corp + theme(axis.title.x=element_blank(), axis.text.x=element_blank()
, axis.ticks=element_blank())
corp <- corp + ggtitle(title)
corp
深蓝色方块表示两个变量之间的强正相关,深红色方块表示强负相关。正如我所料,许多变量似乎是相互关联的(如主场对阵一支球队的平均得分和球队主场输掉的比赛数量)。然而,在热图的第一列中,我能够找到所有变量(按行索引)与匹配结果之间的相关程度。与其他变量相比,主客场球队的排名似乎与比赛结果相当相关。所以我仔细看了看。
ggplot(data, aes(RankAway, RankHome, color=Outcome)) + geom_point() + geom_smooth()
由于结果变量被编码来指示主队是赢还是输,我可以清楚地看到更多的获胜比赛与排名更高的球队在主场比赛有关。经过进一步的探索(此处未显示),我希望在模型中使用时,至少有一些变量可能有一些辨别能力。
型号选择
我首先将数据分成训练集和测试集。由于目标是预测在 2015 年下半年举行的世界杯中发生的比赛,所以我选择了从 2015 年初到最近一场比赛的每第二场比赛作为我的测试集。剩下的比赛全部用于训练。
# create training and test set
testIndex <- seq(360,400,2)
train <- data[-testIndex,]
test <- data[testIndex,]
由于其良好的性能、易于训练和适合并行处理,像许多其他人一样,我选择了随机森林 (RF)分类器作为一个好的起点。用于分类的随机森林是分类树的集合,每个分类树都是使用观测值的引导样本构建的,并且只允许在每个节点分裂处选择变量的随机子集。最终分类采取多数投票的形式。关于分类树和随机森林的精彩介绍,请看托马斯·富克斯的幻灯片。另外,我还考察了斜向随机森林 (ORF)的性能。
通常随机森林中使用的分类树使用正交(垂直于变量轴)分裂来分裂变量空间,而倾斜随机森林使用变量的一些线性组合来分裂。斜树更适合分割由许多相关变量组成的空间,因此我认为斜随机森林可能在橄榄球数据上表现更好。此外,可以使用许多不同的线性分类器来产生用于分裂的线性组合。我最后用了偏最小二乘法 (PLS)。
与随机森林和倾斜随机森林相关联的调整参数是在每个节点分裂时使用的随机选择变量子集的大小。以下代码设置了一个由该子集的几个不同大小组成的调整网格,并指定了用于训练模型的方法,在本例中为 5 重交叉验证(CV) 。
# Train classifiers
library(doParallel)
cl <- makeCluster(8)
registerDoParallel(cl)
# Load libraries
library(caret)
library(randomForest)
# Model tuning grids
rfGrid <- expand.grid(mtry = c(1, 7, 14, 27, 40, 53))
# Tune using 5-fold cross-validation
fitControl <- trainControl(method = "cv",
number = 5,
repeats = 1)
为了训练模型,我使用了 r 中的分类和回归训练(caret)包中的训练函数。这是一个极其强大和方便的包,能够执行许多机器学习任务,从数据预处理和分割到模型训练、调整和变量选择。为了训练随机森林,将方法参数设置为“rf ”,对于带有 PLS 节点分割的倾斜随机森林,将其设置为“ORFpls”。下面是使用 1000 棵树的 RF 的代码(有额外的代码位来存储训练模型所花费的时间)。
# Random Forests
start.time <- Sys.time()
set.seed(2)
rf <- train(x=train[,-1], y=train[,1], method="rf", ntree=200, trControl=fitControl, tuneGrid=rfGrid, importance=TRUE)
end.time <- Sys.time()
time.taken.rf <- end.time - start.time
Model | Training time
--------------------- | -------------
Random Forest | 14.32 secs
Oblique RF pls | 6.93 mins
RF 的训练时间为 14.32 秒,ORF 的训练时间为 6.93 分钟,这意味着 ORF 的训练时间大约要长 29 倍。这是因为在 ORF 的每个分裂处,拟合 PLS 模型,而不是 RF 中使用的计算强度较低的正交分裂。下图显示了随机选择变量的不同子集大小以及标准偏差范围的每个模型的 CV 精确度。
RF 的最佳子集大小为 1,当子集大小对每个模型都是最佳时,ORF 1 的 RF 优于 or f1。但是,以这种方式(仅使用训练数据)计算的精度并不能真实反映模型对未知数据进行归纳的能力。因此,为了更好地了解模型的性能,我绘制了一条 ROC 曲线。
RF 和 ORF 都为属于某一类的观察值产生(在考虑数据之后)后验概率。在二元情况下,例如一个队将输掉还是赢得一场比赛,可以设置一个阈值(比如 0.5),如果后验概率高于该阈值,我们将其分类为“赢”类,否则,如果低于该阈值,我们将其分类为“输”类。ROC 曲线显示了从 0 到 1 的一系列阈值的假阳性率(一个队赢的比赛被错误分类为输的分数)和真阳性率(一个队赢的比赛被正确分类为赢的分数)。简而言之,具有相应 ROC 曲线的分类器被认为具有最高的预测能力,该 ROC 曲线最紧密地拥抱图的左上角,因为它从左下角到右上角成弧形。所以这两个模型看起来非常相似。最后,保持测试集用于获得每个模型的测试准确性,如下所示。
Model | Test set accuracy
----------------- | -----------------
Random Forest | 80.95%
Oblique RF pls | 76.19%
RF 跑赢 ORF 大约 4.76%。
就这样,我有了我的模型!准备好我训练有素的随机森林在我身边,我要预测橄榄球世界杯的未来。但后来我想,如果我能找到一些方法来做我刚才做的事情,但在每场比赛之间纳入锦标赛的最新结果,这不是很酷吗?换句话说,在比赛发生后立即收集比赛结果,将其添加到我的数据中,重新训练模型,并用新的最新模型预测下一场比赛。除此之外,有没有可能以某种自动化的方式来完成呢?然后多米诺骨牌出现了!
使用 Domino 调度自动化流程
我第一次听说多米诺是在这个由周若辉写的博客文章中,这篇文章向你展示了如何在一场 Kaggle 比赛中使用 R、 H2O 和多米诺。简而言之,Domino 是一个企业级平台,使您能够运行、缩放、共享和部署分析模型。这篇文章还包括一个关于如何开始使用 Domino 的教程,从启动和运行到在云中运行您的第一个 R 程序!对于 Domino 新手来说,我推荐这是一个很好的起点。
因此,我需要做的第一件事就是上传我的 R 脚本,以实现数据收集和模型再训练过程的自动化。首先,脚本( GetRWCData。R )负责获取和清理数据,输出包含新数据的. csv 文件。第二,我必须上传脚本( RWCPrediction。R )用于根据输出的数据训练模型,将模型保存为. rda 文件。
因为我决定使用 RF 而不是 ORF,所以模型训练脚本 RWCPrediction。R 包含以下代码。
### International Rugby world cup match prediction model ###
# load libraries
library(caret)
library(randomForest)
# load data
data <- readRDS("RWCData.rda")
# tune Grid
rfGrid <- expand.grid(mtry = c(1, 7, 10, 15, 20, 25, 30, 35, 40, 45, 50))
# Tune using 5-fold cross-validation
fitControl <- trainControl(method = "cv",
number = 5,
repeats = 1)
# train classifier
model <- train(x=data[,-1], y=data[,1], method="rf", ntree=1000,trControl=fitControl, tuneGrid=rfGrid)
# save model
saveRDS(model, file = "RWC_Prediction_Model.rda")
现在使用 Domino 的调度功能实现自动化!要做到这一点,我只需进入 schedule 选项卡,插入我的脚本来获取数据,作为运行的命令,设置一个循环时间,然后点击 schedule 。(下面的例子稍微简化了一些,因为我不得不微调时间表,在每场比赛之间运行,而不仅仅是在每天的固定时间运行。)
数据脚本成功运行后,模型脚本可以使用新数据来重新训练模型。因此,类似地,我插入了用于训练模型的脚本,作为运行的命令,设置循环时间(数据收集后的一个小时),并点击计划。注意,在这种情况下,我还勾选了负责重新发布 API 的完成后发布框(稍后会详细介绍)。
就这么简单,我有一个自动化的数据收集、清理和模型训练管道!然而,从这个项目的一开始,我就不是一个人在工作,所以当我获取数据和建立模型的时候,我的一个好朋友道格正在建立一个网络应用程序来显示预测。一旦应用程序启动并运行,我们需要做的就是弄清楚它如何获得模型预测。输入 Domino API 端点。
使用 API 端点进行按需预测
Domino 的 API 端点允许您将 R(或 Python)预测模型部署为 API,以便其他软件系统可以使用它们。这篇来自 ProgrammableWeb 的帖子和尼克在发表的关于 Revolution Analytics 的帖子是我将预测模型转化为 API 所需要的全部内容。第一步是在 R 脚本(下面给出)中编写一个预测匹配函数,该函数将两个团队作为参数,并将预测作为字符串返回。
## Load Library
library(caret)
library(randomForest)
library(lubridate)
## Load Pre-trained model
model<- readRDS(file = "RWC_Prediction_Model.rda")
## Load predictors
teamStats <- readRDS(file="teamStats.rda")
rank <- readRDS("rank.rda")
rankScore <- readRDS("rankScore.rda")
rankChange <- readRDS("rankChange.rda")
teams <- readRDS("teamNames.rda")
## Create a function to take team name inputs
## and then return a prediction for the match
predict_match <- function(homeTeam, awayTeam) {
homeIndex <- which(teams == homeTeam)
awayIndex <- which(teams == awayTeam)
swap <- awayTeam == "England"
if(swap){
temp<- homeTeam
homeTeam <- awayTeam
awayTeam <- temp
temp <- homeIndex
homeIndex <- awayIndex
awayIndex <- temp
}
homeTeamStats <- c(teamStats[[homeIndex]], rank[homeIndex], rankScore[homeIndex], rankChange[homeIndex])
awayTeamStats <- c(teamStats[[awayIndex]], rank[awayIndex], rankScore[awayIndex], rankChange[awayIndex])
date<- Sys.Date()
levelsx <- levels(factor(teams))
levelsy <- levels(factor(c("loose","win")))
newCase <- readRDS("newCase.rda")
newCase[1,2] <- homeTeam
newCase[1,3] <- awayTeam
newCase[1,4] <- factor(month(date))
newCase[1,5] <- factor(year(date))
newCase[1,6:29] <- homeTeamStats
newCase[1,30:53] <- awayTeamStats
## Return the predicted class probabilities
if(swap){
y_probs <- predict(model, newCase, type="prob")
return(as.character(rev(y_probs)))
} else if(homeTeam == "England") {
y_probs <- predict(model, newCase, type="prob")
return(as.character(y_probs))
} else {
y_probs1 <- predict(model, newCase, type="prob")
temp <- homeIndex
homeIndex <- awayIndex
awayIndex <- temp
homeTeamStats <- c(teamStats[[homeIndex]], rank[homeIndex], rankScore[homeIndex], rankChange[homeIndex])
awayTeamStats <- c(teamStats[[awayIndex]], rank[awayIndex], rankScore[awayIndex], rankChange[awayIndex])
date<- Sys.Date()
levelsx <- levels(factor(teams))
levelsy <- levels(factor(c("loose","win")))
newCase <- readRDS("newCase.rda")
newCase[1,2]<- homeTeam
newCase[1,3]<- awayTeam
newCase[1,4]<- factor(month(date))
newCase[1,5]<- factor(year(date))
newCase[1,6:29]<- homeTeamStats
newCase[1,30:53]<- awayTeamStats
y_probs2<- predict(model, newCase, type="prob")
looseProb<- round((y_probs1[1] + y_probs2[2])/2,4)
winProb<- round((y_probs1[2] + y_probs2[1])/2,4)
return(as.character(c(looseProb, winProb)))
}
}
现在,我必须记住的一点是,在数据中有一个隐含的主团队优势,因此团队在函数的输入字符串中的顺序很重要。由于英格兰是世界杯的主办国,我设定他们的预测总是展示这种主队优势。对于所有其他球队,我做了两个预测,两支球队都有机会成为主队。最终概率是两次预测的平均值。下一步是上传这个脚本(在我的例子中称为 model_API。R )到我的 Domino 项目。
最后一步是发布 API(这对于 Domino 来说非常容易)。我只需导航到 API 端点选项卡,输入包含预测函数的 R 脚本的名称,输入预测函数名称,然后点击发布按钮!
它还活着!!(弗兰肯斯坦的声音)
这就是这个项目目前的情况。既然所有必要的难题都已解决,那么每天都要收集数据,使用一些与下面给出的代码非常相似的 Python 代码发送模型重新训练和预测请求。
import unirest
import json
import yaml
homeTeam = 'South Africa'
awayTeam = 'New Zealand'
response = unirest.post("https://app.dominodatalab.com/u/v1/Arnu/rwcPrediction/endpoint",
headers={"X-Domino-Api-Key": "MY_API_KEY",
"Content-Type": "application/json"},
params=json.dumps({
"parameters": [homeTeam, awayTeam]}))
## Extract information from response
response_data = yaml.load(response.raw_body)
## Print Result only
print("Predicted:")
print(response_data['result'])
结论
所以你有它。
总之,使用 Domino 和 R,我能够:
- 编写脚本以收集相关橄榄球数据,进行探索性分析并选择合适的模型。
- 当新的比赛结果可用时,每天自动进行数据收集。
- 每天收集数据后,自动进行模型训练。
- 使用 API 端点将定型模型转换为能够接收预测请求的 API。
- 当计划预测模型的训练时,通过勾选完成框后的发布来自动重新发布 API。
夏季分析:预测大肠杆菌和西尼罗河病毒
原文:https://www.dominodatalab.com/blog/predictive-analytics-e-coli-and-west-nile-virus
来自芝加哥市的 吉恩·莱恩斯(高级数据科学家)和尼克·卢修斯(高级分析)讨论了两个预测分析项目,这两个项目预测了密歇根湖中的大肠杆菌和蚊子传播的西尼罗河病毒的潜在风险。
会话摘要
在最近的数据科学弹出窗口上,来自芝加哥市高级分析团队的 Gene Leyes 和 Nick Lucius 提供了对两个预测分析项目所涉及的数据收集、分析和模型的见解。
会议重点包括
- 使用广义线性混合效应模型,并纳入季节和区域偏差。78%的时间提前一周预测到西尼罗河病毒的可能性。这个预测有 65%是正确的。
- 研究小组发现线性模型无法预测密歇根湖中的大肠杆菌,因为没有明确的相关性。团队实施了易变海滩的快速测试,预测海滩的战略选择,使用“k-means 聚类算法将海滩分成不同的组,然后使用该信息来决定我们的模型预测。”
对西尼罗河项目感兴趣?在 Github 上查看西尼罗河项目,下载西尼罗河数据。大肠杆菌项目怎么样?然后在 Github 上查看清水项目,在数据门户上下载数据。要从演示中获得更多见解,请查看视频和演示文稿。
演示文稿
你好。我是吉恩·莱恩斯。
我是芝加哥市的数据科学家。我们将开始下一次演示。我们已经很好地结合了技术和更高层次的会谈。今天我将谈论几个我们在这个城市进行的项目,这些项目在今年夏天首次亮相。在任何给定的时间,我们有相当多的不同的倡议正在芝加哥市进行。我们一直在做不同的数据科学项目来优化运营,并努力做到事半功倍。我们就像其他公司一样。我们面临着预算缩减的问题,我们总是试图找到更明智的方法来进一步扩展我们的资源。在我们的数据科学团队中,有数据库管理员,也有商业智能专家。Nick 和我是高级分析团队的代表,我们直接向首席数据官 Tom Schenk 报告,如果您从事任何与数据有关的工作并且居住在芝加哥,您可能已经见过 Tom,因为他无处不在。我们今天要谈论的两个项目是西尼罗河病毒预测和水质预测。
我将以一张幻灯片开始——这是一匹死于西尼罗河病毒的马的脑组织……这是敌人,这是蚊子。这就是人类,马,婴儿,老人…这就是我们如何得到西尼罗河。
这是一个非常有趣的项目。在工作中我学到了很多。我不是瘟疫的狂热爱好者,但同时这是一个非常令人愉快的项目。这真的很令人惊讶和有趣。
谁能猜猜西尼罗河在美国的什么地方,或者它起源于哪里?你会想到哪些州?佛罗里达,加利福尼亚,北卡罗来纳,那是个好地方。在这些地方有一点。它始于皇后区。这其实是一个非常城市化的问题。这是一件非常不寻常的事情。它于 1999 年来到皇后区,很快在美国传播开来。到 2001 年或 2002 年,它已经在伊利诺伊州。我们是美国第五大腐败州——我不知道该用什么词来形容。就西尼罗河病毒病例而言,我们实际上处于首位。所以,这让我非常惊讶。
不过,有一些好消息。尽管它无处不在,但通常也没那么糟糕。大多数感染西尼罗河病毒的人甚至不知道他们曾经被感染过。大约 80%的人完全没有任何症状。在 20%出现症状的人中,他们有类似流感的症状,他们甚至很少去医院或急诊室。在这些人中,1%的人有神经侵袭性疾病的严重症状,这就是情况变糟的地方。这是人们瘫痪、慢性疼痛和死亡的地方。但这确实是一个很小的数字。
例如,今年,我想,我们已经有了最终的统计结果——他们还在进来。在孵化和测试之间有大约 60 天的间隔,30 天孵化,30 天测试。数字实际上还在增加,但我想整个伊利诺伊州今年只有三到四个病例。但奇怪的是,这实际上是一个非常重要的公共卫生问题,因为疫情可能在任何地方爆发,而且非常不可预测。
例如,有一年在科罗拉多州,大约有 2500 个病例。我不知道为什么。我不认为科罗拉多知道原因。但是,提前发现这些病例并采取行动减少西尼罗河的传播和减少蚊子数量是非常重要的。
另一个需要知道的重要事情是,并不是每一种蚊子都会传播西尼罗病毒;是 restuans 库蚊和尖音库蚊。这些不是通常在后院烧烤时叮咬你的讨厌的蚊子。芝加哥的很多人——这很有趣……芝加哥的南部真的希望我们喷洒杀虫剂,而北部真的不希望我们喷洒杀虫剂,因为他们想要他们的蜂箱,他们更注重自然主义。你会有这种二分法,比如谁想被喷,谁不想。这实际上并不重要,因为我们并不是在为困扰你的事情喷,至少在大多数情况下是这样。
理解这一点很重要。这基本上是疾病的生命周期。西尼罗河主要在蚊子和鸟类之间传播。鸟类迁徙并在全国传播。这就是它在美国传播如此迅速的原因。蚊子在鸟与鸟之间传播它。感染鸟类的蚊子实际上并不喜欢人类。人类和马的案例几乎都溢出来了。
所以,不要再扫兴了(我将使用我在 Chi Hack 之夜使用的相同语言。如果你在那里,我很抱歉,但这就是我要做的)。我想谈谈我们在芝加哥市为预防西尼罗河病毒所做的工作;我们真的做三件事。
第一件事是我们消灭了雨水管道中的幼虫,这是一个令人难以置信的数字。我还是有点不敢相信。我必须亲眼目睹才会相信。但是我们消灭了芝加哥市周围 150,000 条下水道的幼虫。他们让实习生或其他人扔球。[笑声]所以他们把这些颗粒扔进雨水管的收集盆里,这基本上可以防止蚊子在雨水中繁殖。
我们做的第二件事是 DNA 测试。我们有这些重力陷阱,里面有特殊化学配方的糖水,可以吸引我们想要的蚊子种类。有一个小风扇,因为蚊子是可怕的飞行者,它只是把它们吹到网里。我们活捉蚊子。我们有-我应该知道号码…整个城市大概有 40 个陷阱。我们收获这些蚊子,抖掉它们,然后分批磨碎蚊子,每批不超过 50 只,因为超过 50 只,西尼罗河的 DNA 会变得太稀而无法测量。我们将每批不到 50 只的蚊子磨碎,在西边的疾病控制中心实验室用 DNA 测试来检测西尼罗河病毒。
接下来我们要做的第三件事是,如果西奈尔斯出现在我们测试的特定区域,我们几乎覆盖了整个城市,如果我们连续两周看到它,我们就会为它喷药。这个项目的重点是将时间从两周减少到一周,当我们确实有这些问题时,真正将它扼杀在萌芽状态,并立即减少蚊子数量。这就是数据的样子。这不是一张奇特的 ESRI 地图…这只是我的地图。[笑声]
所以-哦,还有,这是个好时机。我应该指出我们使用了很多开源工具。我们的很多项目,包括这个项目,都在 GitHub 上。数据本身在开放数据门户上。我在模型中使用的数据与您可以使用的数据完全相同,至少就测试结果而言是如此。
我确实有一些我们不能公开的秘密数据。这是精确的陷阱位置,因为我们不能公开。这些是大概的陷阱位置,因为我们不希望有人篡改陷阱。但是你可以非常接近。我们在开放数据门户网站上公布了所有陷阱的大致位置。我想我的数字错了。大约有 60 个。我写了这些幻灯片,但是我忘记了,因为已经有一段时间了。我们在全市大约有 60 个这样的陷阱来收集这些蚊子。它们通常一周采集一次,也可能一周采集两次。我们在数据门户上发布实际实验室结果方面的数据。
这是芝加哥蚊子季节的形状。蓝线代表蚊子的平均数量。等等,让我看看这个。其实我觉得是总数。反正不是,这是每个诱捕器捕获的蚊子总数。橙色线是感染西尼罗河病毒的平均人数。你可以看到在五月,我们开始收集。我们还没有把所有的陷阱都放出来,因为在五月从来没有西尼罗河。六月,天气开始好转。我们开始得到第一个积极的结果。七月,天气越来越热了。八月是真正沉重的月份。到今年年底或 10 月,它就没了。那里有一点点,但是到十月底就真的没了。
与我个人一起参与这个项目的另一件事是,我们可以真正看到气候变化的影响。许多这种媒介传播的疾病,我说的媒介,是指蚊子媒介或扁虱媒介,在美国不同的气候下确实在增加。季节变得越来越长,因为我们错过了杀死病媒的真正寒冷的冬天。这是一个将继续成为问题或者继续恶化的问题。但是很抱歉。但这肯定是我强化了的东西。
所以,在我之前的那个人——对不起——可能比我更能解释这个模型。我们使用了一个通用的混合效应模型,它使用贝叶斯优化来校正季节形状的偏差,以及逐个陷阱的偏差。有些陷阱更有可能产生积极的结果。我们输入到模型中的其他变量包括天气和陷阱上周是否有正面结果,以及陷阱在整个赛季中的累计结果数。我们试图了解这是否是一个糟糕的赛季,上周发生了什么,天气如何,然后整合这个赛季的整体形状。
我们尝试了很多不同的模型。我们尝试了梯度增强[模型]/GBM,我们尝试了随机森林,我们实际上——再次支持,这整个事情始于一个 Kaggle 竞赛,它使用非常复杂的贝叶斯模型来计算整个赛季。这很有趣。Kaggle 比赛的结果对我们来说并不是特别有用,因为他们赢得了比赛,但每个赛季都有调整。直到季节发生后你才知道季节。所以,他们没有作弊,但这不是我们可以立即从架子上拿下来,用于下周预测的东西。顺便说一句,在所有这些数据科学问题中,对我来说最困难的事情通常是弄清楚——对东西建模很容易——很难弄清楚如何为你的 t+1 时间步长将其投影出来,以及如何将东西放回你的模型中,以便你对下周进行预测。这是课本上没有的东西,这是橡胶遇到路面的地方,这总是棘手的部分。我们模型的结果是一个介于 0 和 1 之间的数字。让我想一想。大多数情况下,结果在 14 左右。我想这是平均水平。我们选择了 0.39 的临界值。任何超过 0.39 的,我们说“这是一个积极的”。有了这个截止值,我们能够预测 78%的真实阳性结果,而我们的阳性结果有 65%是正确的。我手边没有 f 分数。你当然可以在 GitHub 页面找到它。它真的在那里。一些更倾向于机器学习的人可能会喜欢看到这些统计数据和老式的混淆矩阵,但这使得与公众、管理层、流行病学家和芝加哥市内的其他人沟通变得容易得多。
一旦我们有了这些预测,我们就把它们放入我们的情境感知程序。我会给你一个大概的概念。我们有这样的东西,你可以找到数据,然后选择你想要的数据集。这是一个预加载的查询,我们基本上说,任何超过 0.39,颜色是红色的。下面的任何东西,都涂上绿色。这是仲夏某个特定的星期,我们的地图看起来是这样的。这些是在那个陷阱里实际发生的一些细节。下面,我想我没有展示这一部分,但是这里有一个小东西,你可以查看原始数据,如果你想要的话可以下载。因此,不幸的是,由于陷阱位置的原因,这个特定的数据集只能在 Windy Grid 内部获得,这是我们的情况感知计划。但是我们也有一个叫做开放网格的东西,里面有我们大部分的其他数据集。我认为它确实有西尼罗河的测试结果,但它本身没有预测,因为预测也有最高机密的位置。
我希望这能让你对我们的一个项目有所了解。我将让尼克接手,告诉你们我们正在做的另一个非常酷的项目。谢了。
谢谢大家。
我期待着向你们介绍芝加哥市的另一个项目。这涉及到相似的情况,湖水中的大肠杆菌。因此,我们再次关注一种病原体,一种可以导致疾病的东西,以及一种使用预测分析的方法,以帮助人们了解问题并尝试减轻疾病。对于这张幻灯片我真的很抱歉。鉴于今年的时间,我考虑过不把它包括在内。但是如果没有这个,要讲述大肠杆菌和芝加哥海滩的故事是不可能的,因为这就是这个项目存在的原因。
夏季,芝加哥的海滩是居民和游客的一大享受。人们去游泳。人们去野餐。人们去骑自行车。我们拥有如此令人惊叹的便利设施。所以再多说一点——当我开始这个项目时,我没有意识到这一点,但是每年有超过 2000 万人参观芝加哥海滩。我认为这只是一个令人震惊的数字,因为芝加哥市甚至没有三百万居民。我认为这也是一个及时的数字,因为我想,昨天或前天刚刚有消息说芝加哥创下了旅游记录。每年有超过 5500 万人参观芝加哥。所以,是的,这太神奇了。其中 2000 万人来到了海滩。
现在,每年在我们拥有的 27 个芝加哥海滩,大约有 150 个水质超标。这意味着水中的细菌,大肠杆菌,达到了一定的水平,研究表明,如果人们在那个水平的水游泳,他们会生病。把这 150 个数字放在上下文中,每年大约有 2000 个海滩日。当你把海滩的数量乘以游泳的天数,大约有 2000 天。所以这种情况真的是屈指可数。但当它真的发生时,通知公众是非常重要的,准确的通知,这样人们就可以决定是否要游泳。海滩不会关闭。通常,当这种情况发生时,会发出一个建议。如果一个人的免疫系统很弱,或者是一个孩子或老人,他们可以决定是否下水。
现在,最后,检查水质的海滩技术是这样的。有这些传统的培养测试,他们在培养皿中培养细菌,大约 18 小时后回来检查有多少细菌生长。这些太慢了。这些是缓慢的测试。由于大肠杆菌数量在一天中的变化速度,一旦你得到这些结果,它就不再反映当时水中发生的情况。
由于 18 小时的滞后时间,用这些测试结果建立的模型从来没有真正准确地通知人们。我知道这可能会令人不安。但在前几年,如果你去海滩,你看到一个咨询,它说,“嘿,这里有一个问题,”它告诉你昨天。那天在海滩可能不会有什么问题。
另一种全新的检测海滩上大肠杆菌的方法是快速 DNA 检测。现在,这些都是在过去几年里研究和开发的。今年,刚刚过去的夏天是芝加哥第一次在每个海滩使用它们。世界各地的许多市政当局都在关注芝加哥在快速检测方面所做的工作,以便有可能将其带到他们的社区,并用于海滩监测。
但是这些快速 DNA 测试方法的一个主要缺点是它们非常昂贵。主要是它所需要的机械。这些样本每天早上在湖边被采集,然后被送到 UIC,在那里它们被放进机器里进行测试。虽然这是在夏季发生的,但这占用了该地区所有的能力,甚至进行这种测试。如果有人想说,“嘿,我也想在上午 11:00 做这些测试中的一个,”在夏天的任何一天,那么你必须等待。所以,这就是现在存在的供给和需求。
所有这些都促使人们使用预测模型,以便能够获得任何特定时间任何海滩的水质的经济、准确读数。预测模型有能力预防疾病,并在通知公众是否应该下水的同时,为政府节省数百万美元。
现在我要告诉你的这个项目是关于我们所做的,它是如何产生的真的很有趣。它实际上来自 Chi Hack Night,一群人注意到数据门户网站上有海滩水质在线,他们认为也许他们可以制作一个预测模型,并接近了这座城市。芝加哥市与这些开发者一起工作,在 Chi Hack 之夜与这些数据科学家一起工作——实际上我在今晚的人群中看到了一些——在志愿者的基础上为了开发模型,还与来自德保罗大学的学生一起工作,为了开发数据可视化和做一些模型改进。我实际上是志愿者之一。在 Chi Hack 之夜发生的时候,我并不为芝加哥市工作。所以真的很酷。我成为了 Chi Hack 之夜的志愿者,提高我的数据科学技能,然后作为一名数据科学家在芝加哥工作。这是一次很棒的经历。
我现在给你讲一点这个模型。最初开发的模型使用水传感器。这就是左上方的内容。水中有一个水传感器,它正在不断地读取水的云量、浪高、水温等信息,然后将其发送到芝加哥的一个数据门户网站。该小组使用了气象传感器数据。它还使用了前几天、前一天、前一周的大肠杆菌测试结果来为模型提供动力。
然后有很多有趣的一次性数据集。就像水闸打开的时候,污水被注入密歇根湖,如果你不知道的话,实际上每年都会发生几次,通常是在有大暴雨的时候,整个芝加哥地区都会被淹没。他们会打开闸门,让水流入湖中。在这种情况下,海滩将立即关闭,直到这种情况消失。但当时的想法是,在接下来的几天里,可能会有一些影响,可能会导致一个更好的模型。
在底部,你看到的是一个海滩一年中的大肠杆菌水平。我认为这向你展示了水质不好的日子有多罕见。这个特殊的海滩在 2015 年只有一天,没有太多预警。它不知从哪里冒出来的。它马上就消失了。这些异常罕见的事件很难预测,这就是研究小组马上注意到的。
志愿者投入全部时间的所有建模工作,最终得出的结论是,无论我们能够获得多少环境数据,我们似乎都无法确定是什么导致了大肠杆菌,因此在自然界中,你可以用什么来预测大肠杆菌。模型的准确率从来没有超过某个阈值。这是一次令人沮丧的经历。但是这项工作以及所有这些个人对这个团体的贡献引起了一场讨论,围绕着我们可以用什么其他方法来看待这个问题。
我们最终开发了一种新的方法来模拟海滩水质,到目前为止,这显示了一些很大的希望。它的工作方式是,不是使用这些环境变量来试图找出水中发生了什么与空气中发生了什么,这个想法是这样的。今天支付一些昂贵的测试,然后用这些测试预测今天该地区的其他海滩会发生什么。这实际上更像是一个价值缺失的问题。你正在测试一些海滩。那你就可以推断出一些海滩。密歇根湖存在区域效应,一些海滩会随着其他海滩移动。所以你可以预测一个海滩的大肠杆菌水平和另一个的。但它仍然不是——你不能用线性模型来描述它。没有明显的关联。
我们所做的是,我们使用了 k-means 聚类算法,以便将海滩分成不同的组,然后使用该信息来决定模型的预测值。我们要做的是,我们说,好的,这些是我们要付费测试的海滩,这些是我们要测试的。这些就是我们要预测的海滩。
Now, for the finer details on that, I'll refer you to a paper that's forthcoming. There's a draft version on our GitHub page already. It really goes into the details of all the modeling. So, I won't go into that here.
我想做的是展示一个我们制作的公共网站,让人们了解这个模型,了解这个项目,也可以创建他们自己的模型。因为这个模型中的一个关键结构是选择你使用的海滩,你选择去测试的海滩。所以,一个人可以在这里选择-他们看到一个海滩列表。你可以选择任何你想说的海滩,好的,我要测试这些,建立一个模型。
在这个闪亮的应用程序的背景中,有一个 R 脚本正在运行,它将构建这个模型。也许我应该在开始之前做一个演示。我想我只需要重新装弹。让我再选几个海滩。后台要建立和验证一个模型。你将能够看到你的模型做得如何,并将其与芝加哥市的模型进行对比。
让我给它几秒钟来开始。这条虚线显示了芝加哥市模型的真实阳性率。然后那个柱状图表明我刚刚做的那个真的不行——它有 15%的真实阳性率,相比之下这个城市的模型是 38%。人们可以去尝试建立自己的海滩,看看他们是否能想出一个有用的海滩组合。
你也可以把假阳性率搞乱。我把假阳性率提高了不少,这意味着现在模型会发出警告,而实际上湖中并没有问题。但正因为如此,它得到了更好的真阳性率。当我们去评估模型时,我们决定将它投入生产。因为,就像 Gene 说的,我们面临的最困难的部分之一是模型的可操作性,并让它在真实的数据上实时工作。
在 2017 年,也就是刚刚过去的这个夏天,尽管芝加哥市正在对每一个海滩进行快速测试,但我们创建了一个模型,选择了几个海滩,然后预测了其他海滩,这样我们就可以看到它是如何做到的。在使用这种混合方法的过程中,我们发现公众被告知我们的流程的时间增加了约 60 天,而使用旧模式时,公众不知道这个问题。其中很多确实来自于我们的过程实际上会做快速测试。这样你会赢得一些胜利。但是这个模型本身也做得更好。
预测模型本身与先前的预测模型相比,其准确性大约是前者的三倍。我有一张幻灯片,精确度是之前模型的三倍。就像我说的,我们已经做的是,我们已经有了一篇论文来发表这个模型。我去和水质专家交谈过,他们实际上是定期进行科学研究的人,向他们展示,以确保一切对他们都有意义,并希望能在他们可能需要的任何地方把它送到海滩水质监测员的手中。这就是这次展示的清水和西尼罗河病毒部分的结束。
但我们只是想告诉你更多关于芝加哥市和我们所做的事情。这些项目实际上实现了——它们是实现一些核心承诺的一部分,这个城市称之为科技计划。该市市长在上任伊始就发布了一项科技计划。它向芝加哥市承诺,除其他事项外,我们将与市政技术创新者合作,开发应对城市挑战的创造性解决方案。这个项目正是这样做的。我们不仅一起工作,而且个人志愿者作为一个团体最终为此贡献了 1000 小时的时间。在周二晚上看到人们是一件很棒的事情。现在,每个人都有工作。每个人都过着忙碌的生活,一起坐在这栋大楼的一个房间里,致力于这项工作,试图找到一种方法让这个城市对每个人都更好。我有证据,以防你不想相信我的话。我们在 GitHub 上查看了历史记录,并且能够将这些记录放在一起,这样你就可以看到人们实际工作的时间。我不知道周六凌晨两点这里发生了什么。但在周二晚上,你可以看到正在进行的工作大幅增加。当你回顾这个项目的整个历史时,Chi Hack 之夜志愿者真的真的做到了。该市的计划中的另一个承诺是,这两个项目都将利用数据和新技术使政府更加高效、有效和开放。
最后,我要提一下 Gene 的项目的其他一些东西,这个项目真的很酷。他发布了开放网格,这个城市的态势感知地图平台,为你做了一个演示。但他的项目实际上增强了那个平台,并为它创造了新的发展。为西尼罗河项目制作的一些地图实际上进入了开放网格,不仅供芝加哥居民使用,而且任何其他使用开放网格的市政当局现在都将内置这些功能。对我们来说就是这样。如果你有任何问题,我相信吉恩可以提出来,我们可以回答你可能有的任何问题。
人工智能的产品管理
原文:https://www.dominodatalab.com/blog/product-management-for-ai
皮特·斯科莫罗奇在 Rev .上发表了“人工智能的产品管理”这篇文章提供了一个摘要、视频和完整的文字记录。
会话摘要
Pete Skomoroch 在 Rev 举办的“人工智能产品管理”会议提供了产品经理和领导者需要了解的关于运输机器学习(ML)项目以及如何应对关键挑战的“速成班”。Skomoroch 认为管理 ML 项目对组织来说是具有挑战性的,因为交付 ML 项目需要一种实验性的文化,这种文化从根本上改变了许多公司构建和交付软件的方式。然而,这一挑战并非不可克服。Skomoroch 提倡组织考虑任命具有数据专业知识和面向 ML 的直觉(即什么是可能的,什么是不可能的)的产品领导者来应对这些挑战。
本次会议的一些亮点包括
- 拥有成功的 ML 项目的公司通常已经有了一种实验文化,以及能够让他们从数据中学习的分析方法。
- 确保产品经理从事对业务至关重要的项目和/或与公司战略指标保持一致。
- 不幸的是,许多从业务方面冒出来的面向 ML 的想法是不可行的。因此,管理 ML 项目的产品领导需要有良好的直觉,知道什么是可能的,什么是不可能的,就优先级进行艰难的务实对话。优秀的产品经理“知道容易的、困难的和不可能的问题之间的区别”。
- 请注意,机器学习通常涉及到不一定有效的工作。这类似于研发。因此,Skomoroch 主张尽快让“设计师和数据科学家、机器学习人员聚在一起,使用真实数据、原型和测试”。
要了解更多关于本次会议的见解,请观看视频或通读文字记录。
https://www.youtube.com/embed/iMaqGHkUKgI?feature=oembed
副本
你好,我是彼得·斯科莫洛奇。这个演讲将是一个速成班,内容是产品经理和领导者需要了解的关于运输机器学习项目的顶级知识。了解如何应用机器学习的公司将在未来十年中最有可能扩大规模并赢得各自的市场。也就是说,人工智能产品管理比大多数人意识到的要难。没有大量的标记训练数据,解决大多数人工智能问题是不可能的。沟通产品设计、机器学习、研究和用户体验所需的人才和领导力非常稀缺。有些人就在这个房间里。这个房间里有多少人现在在做产品?有多少人担任机器学习数据科学家的角色?有多少人是设计师?可能不多。这将关系到房间里的每个人。所有这些人都需要聚在一起完成这项工作。这个演讲将描述你如何应对你将要面临的所有这些挑战,并建立一个每个产品交互都受益于你在机器学习上的投资的企业。
在我们深入学习速成课程之前,让我给你介绍一下我自己背景。我最近是一家名为 SkipFlag 的人工智能初创公司的联合创始人兼首席执行官,该公司于去年年初被 Workday 收购。SkipFlag 是一个知识库,它是从你的企业通信、电子邮件、Slack、Wiki 信息和内容中构建的。它使用深度学习来建立一个自动问答系统和一个基于这些信息的知识库。它就像谷歌知识图一样,拥有所有的智能卡片,并且能够用你自己的数据创建你自己的卡片。
此前,我是 LinkedIn 数据团队的早期成员,我和我的 SkipFlag 联合创始人 Sam Shah 建立并扩展了一系列创新的数据和机器学习产品,你可能会使用这些产品,如 LinkedIn 技能、你可能认识的人以及查看我个人资料的人。我们还在幕后做了一系列由机器学习驱动的事情,帮助销售导航器和 LinkedIn 的其他产品。我最近还参与主持了 O'Reilly AI Bots 播客,在那里我们采访了许多领先的研究人员、平台和初创公司,他们正在构建对话式人工智能和服务。在我的职业生涯中,我参与了大量的机器学习项目,有些成功,有些不太成功。
基于那次经历,我总结了一些经验教训。希望对你有用。
我说的 AI 产品具体指的是什么?人工智能产品是自动系统,收集和学习数据,通过机器学习做出面向用户的决策。在这次演讲中,我有时会互换使用“人工智能”和“机器学习”这两个术语。我们不会深入研究机器学习实际上是如何工作的数学或工程细节。我想在座的很多人都有相当多的背景知识。就目前而言,你需要知道的是,机器学习是人工智能的一个领域,它使用统计技术,通过对过去的例子进行训练,赋予计算机系统基于数据进行学习的能力。
在过去十年中,许多消费公司,如 LinkedIn、脸书、谷歌、网飞,已经大规模部署了机器学习,以支持朋友推荐、推荐电影、个性化广告和支持搜索结果。这一切都是由谷歌的 MapReduce paper 和开源项目 Hadoop 带来的早期大数据技术浪潮推动和加速的。现在很多人都在用 Spark。我们已经转移到 PyTorch 和 TensorFlow,在那里我们大部分时间都在编码。但所有这些都是建立在过去 20 年消费者互联网浪潮的基础上的。
如果机器学习如此神奇,为什么不是每个公司都应用它并彻底改造自己呢?事实证明,即使是基本的机器学习也很难,在真实的商业中管理这些人工智能项目比大多数人意识到的要困难得多。机器学习不是你可以撒在你现有产品上的仙尘,“给我弄点 AI 来”。即使收购一家公司,也不会让你瞬间成为一家 AI 公司。你不能使用云 API 就把它从货架上插上来。云 API 很棒,但它们只是拼图的一部分,不会神奇地让你的整个产品变得智能。几个月前,我在推特上说过,根据经验,你可以预计你的企业公司向机器学习的过渡将比你向移动设备的过渡难 100 倍。
有多少人参与以某种形式为他们的公司运送移动应用程序?
这里的一个基本区别是....对于移动设备,底层工程堆栈与您正在构建的非常相似。你以更小的尺寸展示它。有了机器学习,就像拆掉了所有的管道。你正在从根本上改变构建和发布软件的方式。我们看到成功项目出现的一个模式是,它们发生在已经有实验文化的公司中...和分析,他们已经开始从数据中学习。
在机器学习方面取得成功的公司往往会建立在现有的分析用例基础上。当谈到人工智能时,这些痴迷于测量的公司具有优势。谷歌、脸书和其他领导者,他们真的建立了一种极端测量的文化,他们产品体验的每一部分都被用来优化点击和提高用户参与度。事实证明,这种水平的测量和跟踪是你需要扔掉所有数据和标签,你需要建立机器学习产品。这也意味着,如果你还没有以那种方式改变你的文化,我提到的 100 倍的数字可能是低估了。我与之交谈或提供建议的许多公司、许多初创公司或更大的公司都刚刚开始这一旅程,他们对构建一些很酷的人工智能功能感兴趣,但结果是他们没有任何跟踪数据。他们没有以任何方式跟踪搜索、印象、点击或结果。然后你必须告诉他们一个艰难的消息,他们还有大约两年的时间来做任何真正的事情。
现在我们来谈谈一些组织要求。在接下来的演讲中,我主要关注的是一位致力于发布人工智能产品的产品经理。对于那些不太熟悉产品经理工作的人来说,人工智能产品经理大概是这样的。你有用户经验,UX 背景,一些技术能力,和一些商业世界的知识。维恩图代表传统的产品管理,其中产品经理是产品所有者。制定战略、定义你正在玩的市场游戏规则的人,他们与企业内所有这些不同的团队和职能部门合作,确定项目的优先次序,并根据路线图执行以交付这些项目。
成为产品领导者是一个艰难的角色。你是四分卫,确保事情按时完成。对于这个角色中的许多人来说,没有任何数据或机器学习背景,被扔进或推进这样的东西会更难。他们可能缺乏这个房间里的许多人在数据、机器学习以及这些模型如何工作方面的专业知识。连接这些世界的社会问题是最难做的事情之一。如果你的产品负责人有这样的背景,那你就很幸运了。一个好的数据 PM 最重要的要求之一是,他们需要对机器学习如何工作以及什么是可能的和不可能的有良好的直觉。很多来自商业方面的想法实际上是不可行的。有多少人已经有了一些东西,作为一个项目提出来,而你不得不告诉他们一个难以接受的消息,那就是用你现有的数据是不可能的?好吧。所以这种情况经常发生。你真的需要这个。当人们提出这些想法时,当事情被优先化时,这个房间里的人需要在做出决定的那个房间里。
关于机器学习构建这些产品,产品经理应该知道什么?理想情况下,如果你要雇佣一个新的项目经理,你会想要一个以前做过这个的人。有人在一个有反馈回路的公司工作过,在那里他们发运了一个产品,他们看到了迭代的过程以使模型工作,他们处理所有这些问题,一旦有东西是活的。那种经历是无法替代的。你真的需要经历一下。但是希望接下来的演讲能给你一个你需要知道的大纲。
一个好的数据产品经理知道简单、困难和不可能的问题之间的区别。自动文本摘要就是一个很好的例子。这似乎是我们当前机器学习算法力所能及的事情。你总是在 Twitter 上看到有趣的故事,关于新算法,它可以像人一样总结文本或像人一样写故事。但现实是,如果你给一些东西,一篇任意的新闻文章,并要求它做一个生成性总结,出来的往往不是事实上正确的,有时甚至是不明智的。只是看起来像似是而非的英语。如果你有一个高优先级的项目需要这样的东西,那就是一个技术飞跃。这可能不可行,至少在近期是这样。知道这些事情之间的区别,我称之为“可能的艺术”。知道什么可行,什么不可行。这是最重要的事情之一。
另一件要考虑的事情是,即使有些东西是可行的,也不等同于产品适合市场。你能做某件事并不意味着这就是人们想要的。即使它是客户想要的,并且可能有效,它也不一定是你投入时间和资源的最佳选择。它可能需要太长的时间来建立,可能有其他的东西会有更大的影响。我在优秀的项目经理身上看到的另一个模式是,他们非常受指标驱动。他们已经对自己公司的数据了如指掌,这通常意味着能够运行 SQL 查询,了解跟踪、日志、数据覆盖和质量。他们可以在公司里跑来跑去,帮助你的团队获得他们没有的数据,或者访问这些数据,或者以一种 it 可以获得这些数据的方式改变产品或业务。
如果你有一个好的项目经理,你有一个数据团队,现在你必须把他们聚集在一起,你必须优先考虑这些想法。你能认出那些不可行的。你把它归结为一个更小的集合。如果你有一群聪明人,并把他们聚集在一起,应该不缺乏做什么的想法。问题更多的是,并不是所有的想法都值得追求。你必须弄清楚如何优先考虑你的人工智能项目列表。数据科学家和机器学习工程师应该避免在不符合最终用户需求的事情上花费时间。解决人们并不真正拥有的问题的聪明方法并不那么有用。这很容易,尤其是当人们来自学术界的时候。你有你喜欢的算法,或者项目,你对它感兴趣,你想为之努力,但是通常它不会直接映射到业务上。我自己也做过。每个人都有自己喜欢的项目或想做的事情,并试图把它硬塞进生意中。这是一种应该避免的模式。
运送任何机器学习项目都需要大量的组织和数据工程工作。最终的回报需要与投资相匹配。这意味着,如果你试图不兑现承诺,过多地为企业赢得一个不会推动核心指标的小胜利,你实际上可能会破坏你的团队作为领导者的地位。那是另一种模式。人们想尝试做一个小样本项目。存在的危险是,这个小样本项目也很难推广。然后你要做很多工作才能把它弄出来,最后就没有投资回报了。
为了区分优先次序,我们如何做到这一点?我会从你的公司任务开始。思考你的使命和近期战略目标。例如,在 LinkedIn,我们的使命是联系世界各地的专业人士,让他们更有效率、更成功。我们在任何时候都有一套战略目标,其中一个主要目标就是成为有记录的专业人士。你想成为记录系统。基本上,现在每个人的简历都在 LinkedIn 上。但这不是一朝一夕的事。有很多工作要做,填写这些个人资料,并让人们联系起来。
如果您知道这是您的总体目标,那么您可以开始采纳您的数据科学家或您的产品人员提出的各种想法,并开始按主题排列它们。然后,从主题上来说,如果它们与那些重要的目标之一相一致,那么你就可以做评估努力程度的深入工作。我喜欢使用 t 恤尺寸的想法,比如保持它,远离杂草,并使用小,中,大的努力。然后做同样的影响。当你对这些东西进行 stack rank 时,你会看到一些难度很高、影响很小的东西。这些并不能激发快乐。如果可以的话,把它们处理掉。这可能是一个有趣的练习。我想最后,我经常发现没有太多的分歧。人们通常可以在这些事情上达成共识。
我能给机器学习产品经理的最重要的建议是,确保你做的事情对业务很重要。产品经理的基本工作是确保你在解决正确的问题。了解你的核心业务和产品是如何运作的,以及你的战略目标是什么。然后,你要做的是将你的机器学习应用程序直接与其中一个目标配对,这样当你改变模型中的一个数字时,就像人们在跟踪准确性一样,就会出现误报。你有所有的机器学习指标,但理想情况下,无论你的机器学习团队在增加或改进什么,都会对你业务中的另一个指标产生直接影响....你可以看到这一点。我记得在 LinkedIn,在左边,你可以看到 LinkedIn 会员增长的图表。在右边,我们有全部的支持,你可能认识的人可能是 LinkedIn 最成功的例子。
我之前提到过,我们的使命是连接全世界的专业人士。你可能认识的人与此直接配对。当我们发布算法更新时,当我们改进模型时,你会看到增长中的阶跃函数变化。越来越多的人被连接起来,越来越多的人来到这个网站,带来更多的成员,几个月后,当你可能认识的人发起时,它产生了巨大的影响,然后它创造了一个飞轮。那些进来的人也使用它,它推动了巨大的增长。
另一个例子是我在 LinkedIn 想到的一个产品,LinkedIn 背书。当目标是成为档案记录时,这意味着人们需要填写档案。很多人会在早期注册,你只需要创造...你写上你的名字,你写上你的职位,你工作的地方。侧写上没有更多的信息。这对于寻找求职者、你想做的其他事情或广告来说都不是很有用。我们想把这些资料填好。背书使用机器学习推荐来促进你的网络中的人的社交标签,这驱动了大量的个人资料完成。我想,我们在产品推出的头六个月就有了十亿次的支持。
如果你能做到这一点,那就太好了。如果你能找到一个与直接业务指标相关的机器学习应用,那将是非常神奇的。问题是有很多工作要做。要做像代言这样的事情,有很多前端用户体验工作。有许多管道和管道使用不同的系统,这些系统已经存在,还有新的机器学习模型,所有这些都必须逐步淘汰。这不是一夜之间发生的。这件事发生了很多很多个月。你优先考虑的项目,可能是分阶段放在一起的子项目,成为你的项目路线图。当谈到机器学习时,传统产品路线图的问题是,大多数产品经理本质上不喜欢昂贵且成功概率不确定的想法。
我忽略的一件事是,在机器学习中,你经常会做一些你从未做过的事情。你不知道它是否真的有用。你在估计难度。但是在这条路的尽头,它实际上可能不会按照你想要的方式工作。那是非常不舒服的。它更接近 R&D,而不是一个知名的项目。大多数项目经理不知道如何开始证明人工智能路线图的费用是合理的。你将很难在大多数组织中证明前期研究投资所需的成本。
有多少人是带着一堆研究和摆弄模型开始一个项目的?来自网飞的 Eric Colson 以前来自网飞,现在在 Stitch Fix]以前也说过类似的话。你想开始处理数据。你不希望只是构思和提出想法,用瀑布式的方法来做这件事。你希望尽快召集设计师、数据科学家、机器学习人员,使用真实数据、原型制作和测试。
对这样的路线图感到满意的产品经理真的很有价值。他们将成为你在组织中与其他非机器学习项目经理合作的倡导者。你如何区分你现在可以产品化的人工智能技术和在某人特定时间范围内可行的东西?同样,我认为这只是来自经验。不幸的是,人工智能中大多数有趣的事情都处于我们可以用工程做的最前沿,这使得它们对于规划目的来说是不可预测的。
让你的公司采用机器学习很难的原因之一是,它代表了软件工程方法的根本转变。当数据发生变化时,软件工程的许多经典项目规划和瀑布方法就会失效。数据是不断变化的。如果你有一个面向用户的产品,当你建立模型的原型时,你所拥有的数据可能与你在生产中实际拥有的数据有很大的不同。这确实让公司受益于一种实验性的文化,在这种文化中,他们可以承担明智的风险,并对这些不确定性感到舒适。
我喜欢杰夫·贝索斯的一句名言,“如果你只做事先知道答案的事情,你的公司就会消失”。在许多方面,这种对实验文化的需求意味着机器学习现在更适合消费者领域,而不是许多企业公司。企业产品管理传统上是自上而下的。你与你最大的客户交谈,你形成想法和未来的想法和路线图,这些需求以这种方式驱动,而消费者更多的是自下而上。你有这些战略目标,你实际上在跟踪许多非常细粒度的数据,而事情往往是由数据驱动的,这使得数据科学家、机器学习和工程师的想法更容易被接受。
正如我所提到的,我认为这就是为什么像谷歌和脸书这样的公司在这个领域真的有优势。他们有数据基础设施的基础。我在这次演讲中没有提到,但是 Monica Rogati 有一个很好的图表,数据科学的需求金字塔,有许多基础设施和日志记录,特征提取,所有这些你需要做的事情来使这些模型工作。这通常是新公司旅程的头一两年。通常,人工智能或数据项目经理只是在最初几年做这些工作。
一旦你完成了这项工作,现在你就进入了这样一种模式,你选择了一个想法,你想把这个想法付诸实施。这就是它的典型外观。这些是运送机器学习产品的一些关键步骤。这里需要理解的一个关键点是,第二步到第四步占用了大部分时间。关键是你要做好前期工作,正确选择问题。最大的时间消耗通常是在数据收集、标记和清理方面。假设这是正确的,下一个提高模型准确性和度量的最大增值是围绕特征工程的,聪明的特征工程经常决定项目的成败。提出那些可以从原始数据中提取的创造性信号,以用作机器学习模型的更好输入,这绝对是值得投资的事情。
当你建造这些东西时,要记住的另一件事是,完美是完成的敌人。这适用于算法和设计。你想尽快推出第一版。这可能是因为 80%的工作,真正的工作发生在你的产品上线之后。一旦它出来了,你将会学到更多的东西,你将会得到数量级的数据,如果你设计正确的话,可能会有更多的训练数据,这样你就能得到反馈。想象一下,评分和评论。你启动这个功能,你得到这些信号,然后你可以把它们作为新的训练数据反馈回来。请注意最后一步是如何利用从您的模型构建过程中获得的数据来驱动其他机器学习系统。那很了不起...这是这里最高层次的实现。一旦你开始运输产品,你就可以开始结合从这些不同的产品中获得的数据来做你以前不能做的新事情,
背书来自我们用技能推荐建立的东西。对于个人用户,我们推断你可能有什么技能,我们可以展示给你。更活跃的用户会自己添加它们。但是你的绝大多数用户并不经常访问这个网站。你实际上可以把你可能认识的人的算法和技能建议算法结合在一起,建立类似背书的东西。当你能做到这一点时,那是非常强大的。
我之前提到过,设计至关重要。产品经理需要记住,当他们与设计师合作时,机器学习驱动的解决方案或界面所需的一些关键数据可能会丢失。你可能没有这些数据。很多时候,设计是在缺乏现实的情况下完成的。你会想出一些很酷的想法或概念,关于你可以用机器学习做什么。很多设计师对机器学习理解不深。甚至你拥有的训练数据也可能不如你的设计者最初假设的信息丰富,或者有一些算法上的飞跃,就像我提到的技术总结例子。你真的需要让这些人聚在一个房间里。让机器学习人员、设计师和产品人员聚在一起,以一种支持的方式讨论什么是真正可能的。
如果可能的话,你要为你的设计师提供真实的样本数据。可以使用 Framer 或者 Figma 之类的工具。你现在看到的是一个 Figma,它是一个合作设计工具,但是你可以建造真正的原型。你可以像 Flask 应用程序一样连接起来,这是一个 web 应用程序,它将向你的设计师显示真实的数据,并帮助他们直观地感受数据将会是什么样子,以及它对于不同的用户将会是什么样子。然后,您可以直接将其连接到这些原型工具中,在构建整个产品之前,您可以看到并感受到产品的样子和建议的质量。
数据质量是我一直在谈论的事情,重要的是要强调,无论你在构建什么,你都需要在数据质量上花费大量的时间。右边的引用来自 Salesforce 的前工程副总裁 Ruslan Belkin,他说,“我工作过和交谈过的每一家公司都有同样的问题,到目前为止没有一个例外——数据质量差,特别是跟踪数据。“要么有不完整的数据,缺少跟踪数据,要么有重复的跟踪数据,诸如此类。
PMs 最重要的工作之一就是在正确的时间收集正确的数据。你想以某种方式构建面向用户的产品,类似于....物理学家。作为一名物理学家,他们建造了像超级对撞机这样的东西来更好地测量这个世界。在某种程度上,当你在制造一个产品时,你就像在制造一个超级对撞机。您正在构建一个同时收集数据的系统,该系统支持您将要构建的所有未来产品。在收集时,您希望确保您的系统正在准确地收集数据。在这个阶段犯下的错误是很难纠正的。你不想事后纠正它。
测试。我们已经接近产品生命周期的尾声了。测试至关重要。不幸的是,你在 QA 中做的许多传统的单元任务和其他确定性的事情将与机器学习决裂。因为模型在变化,下面的数据,也就是训练模型的数据,也在变化。很难有稳定的测试。首先要知道,阳光是最好的消毒剂。一个算法工作拖拖拉拉,没有集成到最终产品中,而最终结果是可以测试的,这是非常危险的。你应该专注于证明产品的核心概念,如果可能的话,像模型的简单版本一样推出,然后进行测试,这样你就可以知道你是否在进步,对吗,或者你是否在退步,或者你是否在破坏东西。
您希望了解看似微小的产品变化带来的意想不到的后果。如果你想在你的网站上改变一个问题的措辞,它可以改变正在收集的数据的性质。对于设计师或项目经理来说,这似乎是一个小小的变化,但对于机器学习团队来说,这将破坏他们所有的数据。或者创造一些时间艺术品。另一件要记住的事情是原型不是产品。如果你运行的是样本数据,那么那些在设计中看起来不错的东西,记住那是样本数据。你必须完成这个过程,这样你才能用真实数据测试它看起来是什么样子。来自真实用户、真实客户的真实生产数据,然后 QA 可以真正开始为我们工作。
我提到了使用原型应用程序,这样你就可以看到设计,看到产品如何与机器学习模型结合在一起。我认为,你还需要更精细的窗口,在你的模型中,你的系统内部的更详细的窗口。我的意思不仅仅是像度量仪表板一样显示你的模型做得如何。你在这里看到的是一个我提到的技能推荐的查看器应用程序的例子。在 LinkedIn,我们可以输入任何会员 ID,这里有一个按钮可以随机选择会员,所以你可以看到它是如何工作的。你可以看到,请记住,几乎每个人都有一个公开的个人资料。你可以利用这些信息,看看可以推断出什么样的技能。在这种情况下,这些是从我身上推断出来的技能。这大概是九年前的事了。但是这非常有价值,因为我们可以看到...在早期,它对老师和医生都不起作用。在这些领域或其他问题上,数据覆盖面不够。或者可能只是这些领域有一些模型上的困难。但是我们可以对此进行评估,我们可以迭代,我们可以调整我们的路线图来改进模型以按时发货。
与人类互动的机器学习产品是根本不同的,因为这些是复杂的系统,一切都在变化。您需要在数据和模型中有这些窗口,并且能够可视化地测试和更改它们。如果你已经完成了调试的艰苦工作,你已经进入了产品阶段,它正在以公制前进,真正强大的事情是你会得到这些被称为飞轮效应的东西。用户生成数据是使用大多数软件产品的副作用,而这些数据反过来可以改进产品算法,并实现新类型的推荐,从而产生更多的数据。这些人工智能飞轮变得越来越好,越来越多的客户使用它们,它们导致了这些竞争护城河。
最近有一点关于数据护城河是否真实的争议。我认为,在消费类公司中,它们肯定是真实存在的。我认为我们还没有在企业中广泛地看到这种明显的联系。但是我认为当这些点连接起来时,它将在你的组织中变得非常强大。微软、谷歌和亚马逊等公司认识到了这一现实。他们正在围绕机器学习重组整个公司和组织结构,由高级管理人员推动全公司的努力。亚马逊现在有了强大的 AI 飞轮。史蒂文·利维写了一篇关于这个的好文章。
我将留给你一些最终的想法,以成功地运送机器学习产品。您希望投资于数据基础设施培训以及用于快速迭代的日志记录和工具。使小团队中的人能够走到一起,在整个公司范围内使用您的数据。实现这一切的一些最大挑战是组织和文化上的,而不是技术上的。确保你在高层有真正的高管支持,并配备理解这一需求的优秀产品领导者,同时广泛投资于人工智能人才,包括产品经理、数据工程师、数据科学家和拥有一些数据能力的设计师。最后,找到一个与战略公司指标有直接联系的机器学习问题,然后发货。谢谢你。
编者按:为了可读性,本文经过了编辑。此外,Skomoroch 还展示了这个演讲的不同版本和早期版本。有关早期迭代的更多信息,请阅读这篇文章。
生产数据科学:用 R Markdown 交付模型
原文:https://www.dominodatalab.com/blog/production-data-science-delivering-models-with-r-markdown
R Markdown 是数据科学家工具箱中不可或缺的工具之一,它提供了将您的工作投入生产的最后一英里问题的速度和灵活性。速度来自于主持和安排 R Markdown 报告的容易程度。灵活性来自生产输出的广泛选择。无论是制作一个中间结果的原型,还是产生高质量的输出,让你的工作展现出最好的一面,R Markdown 都能提供很多。
在本帖中,我们提供了在部署模型和构建 MLOps 管道时,拥有各种部署选项的动机。在项目进展太远之前,我们为原型模型做一个论证。我们鼓励在这两种情况下使用 R Markdown。最后,我们浏览了使用 R Markdown 构建新冠肺炎报告所需的代码,该报告计划定期运行,并在报告完成时自动向利益相关者发送电子邮件。
部署 MLOps 解决方案时的选项和原型制作
考虑以下假设场景。你会见你的商业利益相关者。你会听到他们解释对客户有特别的洞察力是多么的重要。你知道最好不要相信他们的话,所以你让他们量化“极其重要”。在验证假设和计算数据后,事实证明他们是对的。如果你能生产出合适的模型,那么会有很大的投资回报。你开始创建一个漂亮的模型,提供完全符合要求的见解。这是事情开始解开的地方。首先,您将模型交给中央 IT 部门,一个月后,他们已经构建了一个可以集成到任何应用程序中模型 API。然后,业务涉众再花一个月的时间就集成 API 的最佳方式达成一致,这样对他们的决策者就有用了。最后,拥有最终用户应用程序的业务部门的 it 人员会涉及到将新 API 集成到他们的应用程序中的各种繁文缛节。啊!几个月过去了,热情已经消退,所有的投资回报率仍然舒适地坐在桌子上。哪里出了问题?
有两件事。首先是显而易见的。第二,也许没有那么多。明显的错误是在开始项目工作之前忽略了可交付物的详细范围。那应该是每个 数据科学家 飞行前清单的一部分。在此范围界定过程中,了解 R Markdown 的可能性非常重要,因为它扩展了您对模型交付外形的选择。如果 R Markdown 满足了实际需要,它可以减轻 it 人员的负担,避免构建一个一应俱全的应用程序。如果需要大量的 IT 参与,范围界定工作将增加 IT 工作说明书的清晰度和准确性。
第二个错误是错过了与用户/模型客户进行项目中期检查的机会。在进入下一阶段工作之前,早期原型是验证假设的好方法。有经验的数据科学家通常会使用 web 应用程序、轻量级模拟和 R Markdown 出版物来构建他们模型交付的原型。在我们假设的例子中,首席数据科学家可能已经创建了一个 R Markdown 参数化的 HTML 页面,该页面接受用户的输入并在 HTML 页面上返回预测。R Markdown 在原型制作中很有用,因为它允许详细的评论和背景信息,这将有助于框定用户在原型中看到的内容。
使用 R Markdown 构建新冠肺炎报告
让我们从假设转向更具体的东西,通过一个编码示例来演示 R Markdown 的速度和灵活性。在这个例子中,我们想要创建一个简单的新冠肺炎 HTML 报告,比较疫情战争前后美国的死亡率。我们将在所有工作中使用 R。我们将涵盖的步骤有:
- 使用 CDC FluView 图书馆下载美国死亡率数据
- 使用 R 数据帧和 dplyr 库处理数据
- 使用 ggplot2 库构建图形
- 将代码转换成 R Markdown 文档
- 从 RStudio 以 HTML 格式呈现报告
- 创建一个以 HTML 格式呈现报告的 R 脚本,以帮助安排报告
- 计划每月运行一次数据处理和报告生成
- 创建报告后,通过电子邮件将结果发送给风险承担者
1.使用 CDC FluView 图书馆下载美国死亡率数据
美国国家卫生统计中心(NCHS)收集和传播国家官方生命统计数据。NCHS 从各州生命统计办公室收集美国几乎所有死亡的死亡证明数据。这些数据可以使用 cdcfluview 库 下载到 R 脚本中。
install.packages('cdcfluview')
library(cdcfluview)
mypath = './data/'
mortality <- pi_mortality()
write.csv(mortality, paste(mypath,"mortality.csv", sep=''), row.names = FALSE)
2.使用 R 数据帧和 dplyr 库处理数据
将下载的 csv 文件读入数据帧后,需要将日期格式化为 R 日期格式。
library(dplyr)
# Bring in CDC US mortality data
df <- read.csv('./data/mortality.csv', header = TRUE, stringsAsFactors = FALSE)
df <- df[c('total_pni','all_deaths','week_start', 'week_end')]
df$week_end <- as.Date(df$week_end, format = "%Y-%m-%d")
df$week_start <- as.Date(df$week_start, format = "%Y-%m-%d")
df <- df %>% arrange(desc(week_end))
head(df)
由于 NCHS 需要一些时间来汇编所有的死亡证明,如果你需要一个完整的记录,建议删除最近三周的数据。
exc_date <- df$week_start[3]
df <- subset(df, week_start < exc_date)
head(df)
3.使用 ggplot2 库构建图形
在试图量化新冠肺炎在美国的影响时,一些人认为超额死亡率是大多数美国人都同意的标准。
假设新冠肺炎是自 2020 年春季以来几乎所有额外死亡的原因,下图允许人们通过查看自疫情开始以来各种原因导致的死亡增加来评估新冠肺炎的相对影响。
# trend line
library(ggplot2)
p <- ggplot(df, aes(x=week_start, y=all_deaths)) +
scale_x_date(date_breaks = "1 year", date_labels = "%Y") +
geom_line(color="#69b3a2") +
xlab("") +
ylab("weekly deaths") +
theme(axis.text.x=element_text(angle=60, hjust=1)) +
ggtitle("Weekly US Deaths Due to Any Cause")
p
# bar plot
# sum by year first
df$year <- format(as.Date(df$week_start, format="%d/%m/%Y"),"%Y")
df_year <- df %>%
group_by(year) %>%
summarise(deaths = sum(all_deaths)) %>%
as.data.frame()
df_year$deaths_label <- paste(round(df_year$deaths / 1000000,2), "M")
df_year <- df_year[df_year$year != 2013,]
head(df_year)
# calculate y axis limits
y_min <- round(min(df_year$deaths)*0.75,0)
y_max <- round(max(df_year$deaths)*1.05,0)
# plot
b <- ggplot(df_year, aes(x=year, y=deaths)) +
geom_bar(stat="identity", fill="steelblue") +
coord_cartesian(ylim = c(y_min, y_max)) +
geom_text(aes(label=deaths_label), vjust=1.6, color="white",
position = position_dodge(0.9), size=3.0) +
gtitle("Yearly US Deaths Due to Any Cause")
b
4.将代码转换成 R Markdown 文档
创建标题并指定输出类型。添加一些描述性文本和一些断行。使用{r, include=FALSE}
运行数据处理代码,使用{r, echo=FALSE}
显示图表。
---
title: "US Mortality Report"
output:
html_document
---
In seeking to quantify the impact of COVID-19 in the United States, some have argued that
**excess mortality** is the metric upon which most Americans can agree.
Assuming that COVID-19 is the cause for nearly all the extra deaths since the Spring of 2020,
the following graphs allow one to assess the relative impact of COVID-19 by looking at the
increase in deaths from all causes since the onset of the pandemic.
<br>
<br>
```{r setup, include=FALSE}
# knitr::opts_chunk$set(echo = TRUE)
library(dplyr)
library(ggplot2)
tinytex::install_tinytex()
Bring in CDC US mortality data
df <- read.csv('../data/mortality.csv', header = TRUE, stringsAsFactors = FALSE)
df <- df[c('total_pni','all_deaths','week_start', 'week_end')]
df$week_end <- as.Date(df$week_end, format = "%Y-%m-%d")
df$week_start <- as.Date(df$week_start, format = "%Y-%m-%d")
df <- df %>% arrange(desc(week_end))
# Exclue the most recent rows as it seems to take the CDC several weeks to update
# total death numbers
exc_date <- df$week_start[3]
exc_date
df <- subset(df, week_start < exc_date)
```py
```{r, echo=FALSE}
# plot US deaths due to any cause - trend line
p <- ggplot(df, aes(x=week_start, y=all_deaths)) +
scale_x_date(date_breaks = "1 year", date_labels = "%Y") +
geom_line(color="#69b3a2") +
xlab("") +
ylab("weekly deaths") +
theme(axis.text.x=element_text(angle=60, hjust=1)) +
ggtitle("Weekly US Deaths Due to Any Cause")
print(p)
```py
```{r, include=FALSE}
# plot US deaths due to any cause - bar plot
df$year <- format(as.Date(df$week_start, format="%d/%m/%Y"),"%Y")
df_year <- df %>%
group_by(year) %>%
summarise(deaths = sum(all_deaths)) %>%
as.data.frame()
df_year$deaths_label <- paste(round(df_year$deaths / 1000000,2), "M")
df_year <- df_year[df_year$year != 2013,]
head(df_year)
y_min <- round(min(df_year$deaths)*0.75,0)
y_max <- round(max(df_year$deaths)*1.05,0)
```py
```{r, echo=FALSE}
b <- ggplot(df_year, aes(x=year, y=deaths)) +
geom_bar(stat="identity", fill="steelblue") +
coord_cartesian(ylim = c(y_min, y_max)) +
geom_text(aes(label=deaths_label), vjust=1.6, color="white",
position = position_dodge(0.9), size=3.0) +
ylab("year-to-date deaths") +
ggtitle("Yearly US Deaths Due to Any Cause")
print(b)
```py
5.使用 RStudio 以 HTML 格式呈现报表
在 RStudio IDE 中呈现 R Markdown 很简单。出现时,单击“编织”按钮。Rmd 文件在当前编辑窗口中。
6.创建一个以 HTML 格式呈现报告的 R 脚本,以帮助安排报告
在 R 脚本中以编程方式呈现 R Markdown 报告只需要一行代码。中的所有数据处理代码。当这个脚本被调用时,Rmd 文件将被执行。在下一步中,我们将安排该脚本每月运行一次。
rmarkdown::render("./code/mortality_report.Rmd")
这是在网络浏览器中看到的最终报告。
7.计划每月运行一次数据处理和报告生成
我们可以使用几个工具来安排数据收集。在这篇博客中,我将使用 Domino 数据实验室的企业 MLOps 平台。你可以免费试用 Domino 来 安排你自己的工作 。
在包含您的文件的项目中,选择左侧导航窗口中的计划作业。创建两个计划作业;一个运行下载最新 CDC 死亡率数据的脚本,另一个运行呈现 R Markdown 文档的单行脚本。数据下载脚本应该首先启动,然后运行呈现脚本。Domino 管理软件环境,因此您可以确保您的生产管道使用与您在开发工作中使用的库组合和版本相同的 docker 映像。
8.创建报告后,通过电子邮件将结果发送给风险承担者
mailR 库 具有通过 R 脚本发送电子邮件的能力。然而,让这个库适用于所有情况并不容易。从公司的电子邮件服务器发送电子邮件可能很难设置,可能需要 IT 部门的帮助。根据电子邮件客户端的类型,电子邮件收件人的体验可能会有所不同。由于 CSS 错误是常见的,发送正文 HTML 文档可能会很麻烦。另一种方法是使用 MLOps 平台,使电子邮件更加无缝。例如,在 Domino 中,您可以很容易地在同一个调度作业向导中包含一个电子邮件地址列表。作业完成后,列出的收件人将收到一封电子邮件,其中包含 R Markdown 报告的链接。
包扎
当进行为期一周的背包旅行时,任何人都会喜欢瑞士军刀,而不是标准的小刀。最好有选择。在将模型投入生产时也是如此。在我们确定数据科学交付成果的范围时,我们永远不知道会遇到什么样的客户和 IT。R Markdown 是帮助您满足可能出现的各种需求的重要工具。此外,在我们深入项目之前,我们已经讨论了 R Markdown 在原型模型输出方面的能力。这篇文章分享了构建一个简单的 HTML 报告并使用 R Markdown 呈现它的代码示例。使用 Domino 安排数据捕获、数据处理和呈现管道,并在完成后自动将报告通过电子邮件发送给利益相关者。如果您有兴趣了解有关其他灵活模型部署选项的更多信息,您可能会喜欢在生产中使用数据科学 Web 应用程序的网络研讨会。
提供数字出处:从建模到生产
原文:https://www.dominodatalab.com/blog/providing-digital-provenance-modeling-production
在上周的用户!在 R User 大会上,我谈到了数字起源、可重复研究的重要性,以及 Domino 如何解决数据科学家在尝试这种最佳实践时面临的许多挑战。关于这个话题的更多信息,请听下面的录音。
你正在做什么来确保你正在减轻与出处(或缺少出处)相关的许多风险?
https://player.vimeo.com/video/175955786?title=0&byline=0&portrait=0
谈话摘要
在整个数据科学过程中,再现性非常重要。最近的研究表明,项目探索性分析阶段的潜意识偏见会对最终结论产生巨大影响。管理生产中模型的部署和生命周期的问题是巨大的和多样的,并且再现性通常停留在单个分析师的水平上。虽然 R 对可重复研究有最好的支持,有像 KnitR to packrat 这样的工具,但是它们的范围有限。
在本次演讲中,我们将展示一个我们在 Domino 开发的解决方案,它允许生产中的每个模型从 EDA 到训练运行和用于生成的精确数据集都具有完全的再现性。我们讨论如何利用 Docker 作为我们的再现引擎,以及这如何允许我们提供无可辩驳的模型出处。
使用 Okera 和 Domino 提供对企业数据集的细粒度可信访问
Domino 和 Okera——让数据科学家能够在可再生和即时调配的计算环境中访问可信数据集。
在过去几年中,我们看到了两种趋势的加速发展——组织存储和利用的数据量不断增加,随之而来的是对数据科学家的需求,他们需要帮助理解这些数据,以做出关键的业务决策。数据量和需要访问数据的用户数量的激增带来了新的挑战,其中最主要的挑战是如何提供对大规模数据的安全访问,以及如何让数据科学家能够一致、可重复且方便地访问他们所需的计算工具。
这些模式出现在多个行业和用例中。例如,在制药业,有大量的数据是为临床试验和新药物及治疗方法的商业生产而产生的,而这种情况在新冠肺炎出现后更是加速了。这些数据支持组织内的各种用例,从帮助生产分析师了解生产进展情况,到允许研究科学家查看不同试验和人群横截面的一组治疗结果。
Domino 数据实验室是世界领先的数据科学平台,允许数据科学家轻松访问可重复且易于配置的计算环境。他们可以处理数据,而不用担心设置 Apache Spark 集群或获得正确版本的库。他们可以轻松地与其他用户共享结果,并创建重复作业,以便随着时间的推移产生新的结果。
在当今日益注重隐私的环境中,越来越多类型的数据被视为敏感数据。这些数据集必须按照行业特定的法规进行保护,如 HIPAA,或一系列新兴的消费者数据隐私法规,包括 GDPR、CCPA 和不同司法管辖区的其他法规。这可能成为数据消费者的障碍;尽管 Domino Data Lab 使访问计算资源变得很容易,但是访问他们需要的所有数据却是一个真正的挑战。
传统上,解决这个问题的方法是完全拒绝访问这些数据(这种情况并不少见),或者通过省略特定用户不允许查看的数据(例如 PII、PHI 等),为每个可能的用例创建和维护许多数据集的多个副本。这种创建数据副本的过程不仅需要花费大量时间(通常需要几个月)并增加存储成本(当谈到数 Pb 的数据时,存储成本会迅速增加),而且还会成为一场管理噩梦。数据经理需要跟踪所有这些副本以及创建它们的目的,并记住它们需要与新数据保持同步,甚至更糟的是,由于新类型的数据被认为是敏感的,未来可能会进行修订和转换。
安全数据访问和数据治理的领先提供商 Okera ,允许您使用基于属性的访问策略定义细粒度的数据访问控制。结合 Domino Data Labs 和 Okera 的强大功能,您的数据科学家只能访问允许的列、行和单元格,轻松删除或编辑与训练模型无关的敏感数据,如 PII 和 PHI。此外,Okera 连接到公司现有的技术和业务元数据目录(如 Collibra),使数据科学家能够轻松发现、访问和利用新的、经批准的信息源。
对于法规遵从性团队来说,Okera 和 Domino 数据实验室的结合是极其强大的。它不仅允许法规遵从性管理可以访问的信息,还允许审核和了解数据的实际访问方式——何时、由谁、通过什么工具、查看了多少数据等。这可以识别数据泄露,并找出应该进一步减少数据访问的地方,例如通过删除对不常用数据的访问来降低暴露风险。
那么这看起来像什么?考虑一个例子,一个数据科学家想要从亚马逊 S3 将一个 CSV 文件加载到 pandas 数据帧中进行进一步的分析,例如为下游的 ML 过程建立一个模型。在 Domino Data Lab 中,用户将使用他们有权访问的环境之一,并拥有一些类似于下面这样的代码:
import boto3
import io
s3 = boto3.client('s3')
obj = s3.get_object(Bucket='clinical-trials', Key='drug-xyz/trial-july2020/data.csv')
df = pd.read_csv(io.BytesIO(obj['Body'].read()))
上述片段中嵌入的一个关键细节是数据科学家如何获得访问文件的许可的问题。这可以通过 IAM 权限来实现,既可以将用户凭证存储在 Domino 内部的安全环境变量中,也可以使用 keycloak 功能在 Domino 和 AWS 之间进行凭证传播。
最后,如果不允许数据科学家查看 CSV 文件中的某些列、行或单元格,就没有办法授予对该文件的访问权限。
当 Domino Data Lab 与 Okera 集成时,相同的代码看起来就像这样:
import os
from okera.integration import domino
ctx = domino.context()
with ctx.connect(host=os.environ['OKERA_HOST'], port=int(os.environ['OKERA_PORT'])) as conn:
df = conn.scan_as_pandas('drug_xyz.trial_july2020')
Domino Data Lab 中当前用户的身份被自动透明地传播到 Okera,并应用了所有必需的细粒度访问控制策略。这意味着,如果执行用户仅被允许查看某些行(例如,来自美国参与者的试验结果,以遵守数据位置法规)或查看某些列,但不公开 PII(例如,通过不公开参与者的姓名,但仍然能够有意义地创建聚合),这将反映在返回的查询结果中,而不会向数据科学家公开底层敏感数据。最后,这种数据访问也要经过审计,审计日志可以作为数据集用于查询和检查。
除了能够在维护细粒度访问控制策略的同时安全访问数据的好处之外,数据科学家现在更容易找到他们需要访问的数据。以前,这涉及到筛选对象存储,如亚马逊 S3 或 Azure ADLS,但通过 Okera 和 Domino Data Lab 的结合,数据科学家可以轻松地检查和搜索 Okera 的元数据注册表,以找到他们有权访问的数据,这些数据已经过主题专家的验证、鉴定和记录,预览这些数据,并获得如何在 Domino Data Lab 环境中访问这些数据的简单说明。
随着您的组织在数据方面的投资和数据科学家工作效率的提高,他们拥有正确的工具和访问正确数据的权限变得至关重要。有了 Okera 和 Domino Data Lab 的结合,整体就不仅仅是各部分的总和了。如果您已经在利用 Domino Data Lab,添加 Okera 可以允许您解锁数据进行分析,这在以前是由于隐私和安全问题而被禁止的。如果您已经在使用 Okera,那么添加 Domino Data Lab 可以提高您的数据科学家的工作效率,让他们能够轻松地访问可重复且易于配置的计算环境。
有关 Okera 及其与 Domino 的合作关系的更多信息,请参见 Okera 的博客文章或关于整合 Okera 与 Domino 的文档。
如何提升数据科学的生产力?重新想象你的工作台!
原文:https://www.dominodatalab.com/blog/pump-up-data-science-productivity-with-a-modern-workbench
高效地进行数据科学研究类似于大师级工匠的工作:高效地完成高质量的工作完全依赖于拥有一套独特的工具,以及一个允许熟练、系统地使用这些工具来定制成品的工作台。
作为数据科学从业者的无价助手,工作台的想法非常有意义,数据科学从业者将数据、代码和参数结合在一起,生成能够生成预测结果的模型。这些排列带来了巨大的复杂性,如果没有数据科学工作台,这是不可能管理的。
数据科学家面临的最大挑战是大规模开展这项工作,将模型部署到生产中。一个数据科学家,甚至一个小团队,都可以利用适度的工作台功能。但是,由数十名数据科学家组成的大型团队处理多个企业级问题是一个完全不同的挑战。该场景中的利益相关者需要数据科学工作台中的专门功能。对于新兴的模型驱动型企业,Domino 重新设计了数据科学工作台,专门用于大规模创建和部署模型。
数据科学工作台的三大支柱
我们的新白皮书“利用现代工作台提升数据科学生产力”,描述了实现大规模生产数据科学的三大能力支柱。这些是一致性、上下文和协调。每一种都需要工作台中的特定特性,以便进行大规模的生产性数据科学。通过一个可扩展的工作台来解决这些问题,允许所有利益相关者即时访问所有工具和基础设施,以支持不同的实验。工作台还打破了数据科学家通常工作的孤岛,为所有利益相关者提供了每个实验所有方面的深入可见性和可重复性。这三大支柱使企业能够将模型投入全面部署,并管理算法性能的持续改进。
使用模型所需的任何工具或过程的一致性
这个支柱是关于用于进行数据科学的工具和流程的一致应用。一致性有助于确保结果的逻辑性、准确性和公平性,这是模型的创建和部署。一致的模式和实践推动生产力和成本节约。它们还支持对模型的信任,由输出的按需再现性支持。
协作和知识加速的环境
协作是数据科学的一个重要元素,从业者在进行实验和开发模型时相互合作。数据科学家相互协作,因为随着障碍被更快地克服,它可以加快进展。解决问题的不同方法可以引发更好的问题解决。当实践者互相学习时,分享知识可以带来新的和创新的想法。
协调项目以解决复杂的业务问题
很多时候,组织无法完成数据科学项目的转变,模型也无法投入生产。根据 Gartner 的说法,“到 2021 年,75%的人工智能项目将停留在原型水平,因为人工智能专家和组织功能无法进行富有成效的对话。”这一失败的最大元凶是缺乏与业务的协调,以及没有能力随着计划规模的扩大而治理一个大的项目组合。工作台内的协调能力对于大规模的项目管理和项目组合治理是必不可少的。
模型驱动的业务依赖于工具和流程的基础,这些工具和流程使数据科学家团队能够高效地创建和调整这些转换引擎。为了应对这一生产力挑战,数据科学从业者需要帮助他们轻松使用完成工作所需的任何工具,并协调团队工作,以便业务领导者能够理解和依赖预测建模的结果。这就是可扩展数据科学工作台的作用。
要了解有关数据科学工作台三大支柱的更多信息,请阅读我们的白皮书,“用现代工作台提升数据科学生产力”,,其中包括大规模工作台生产力的主要功能清单,以帮助团队评估各种选项。
将模型置于业务流程的核心
原文:https://www.dominodatalab.com/blog/put-models-core-business-processes
在 Rev ,达美乐首席执行官,根据多年来与客户的坦诚讨论,继续提供关于管理数据科学的见解。他还深入研究了数据科学领导者如何利用模型管理,并帮助他们的公司成为成功的模型驱动型组织。这篇博客文章提供了白皮书“介绍模型管理”的摘要。这份白皮书是他演讲的附录,也可以从下载。
模特神话
Domino 的最新白皮书“介绍模型管理”涵盖了模型管理如何成为希望将模型置于业务流程核心的公司的一种新的组织能力。由于模型是数据科学的核心产出,它们拥有巨大的力量来改变公司、行业和社会。然而,尽管拥有模型驱动的优势,企业仍在努力实现这一目标。麻省理工学院斯隆管理学院最近的一项研究发现,只有 5%的公司在其业务中广泛使用模型。为什么会这样?公司对待模型就像对待软件一样,而事实上,它们是非常不同的——这就是模型神话。尽管模型看起来像软件并且涉及数据,但是模型有不同的输入材料、不同的开发过程和不同的行为。
用模型管理克服模型神话
为了克服模型神话,公司需要开发一种新的组织能力,称为模型管理。以前,模型管理指的是监控生产模型。然而,它应该包含更广泛的能力。正如公司已经建立了销售、营销、人员管理、财务等方面的能力一样,它们也需要数据科学方面的同等能力。模型管理是一种新的技术和流程类别,这些技术和流程协同工作,使公司能够可靠、安全地开发、验证、交付和监控能够创造竞争优势的模型。
随着更多模型带来更好的客户体验和更高的利润,成功构建模型管理能力的数据科学领导者和组织将获得指数级回报。随着模型的建立,更多的模型也意味着更多的数据和能力,组织可以投资新的和更好的模型。这些组织还将更好地应对阻碍道德和合规风险等模型影响的常见陷阱。最终,下一个计算时代的富人和穷人将由组织的模型管理质量决定。
指南“模型管理”综合了 Domino 的经验,提炼出问题,并提出了实现数据科学全部潜力的前进道路。第一部分描述了什么是模型,并讨论了模型如何驱动商业价值。第二部分关注问题的本质——模型不同于迄今为止构建的任何东西,组织可以像管理其他资产一样管理它们是一个神话。第三部分深入到一个提议的模型管理框架的细节,包括 5 个支柱,它解决了模型的独特属性。
PyCaret 2.2:模型开发的高效管道
原文:https://www.dominodatalab.com/blog/pycaret-2-2-efficient-pipelines-for-model-development
数据科学是一个令人兴奋的领域,但它可能会令人生畏,尤其是对那些编码新手来说。即使对于有经验的开发人员和数据科学家来说,开发一个模型的过程也可能涉及到将许多包中的许多步骤串联起来,其方式可能不像人们希望的那样优雅或高效。R 中 Caret 库的创建者是一位名叫 Max Kuhnwho 的软件工程师,他试图通过创建一个更有效的、开发模型的“流线型”过程来改善这种情况。最终,数据科学家 Philip Goddard 从 R 转到了 Python,为了带来 Caret 的“平滑和直观”的工作流,他创建了第一个名为 pycaret 的包作为个人项目。然而,我们现在知道的 PyCaret 包的诞生是在 2019 年,当时数据科学家 Moez Ali 认识到公民数据科学家需要更好的工具,并创建了 PyCaret 来满足这一需求。
Image from github.com/pycaret
PyCaret 是什么?
PyCaret 是进入机器学习的便利入口,也是有经验的从业者的生产力工具。它为科学家和分析师提供了一个简单、简洁、低代码的接口,可以访问数据科学生态系统中许多最受欢迎和最强大的机器学习库,从而可以轻松地开始探索新技术或数据集。PyCaret 用户生成的清晰、简洁的代码也易于合作者和队友阅读和适应,无论这些同事是该领域的新手还是有经验的数据科学家。
PyCaret 的构建模块
PyCaret 最初是为了将许多有用的 Python 库和常见任务包装成简洁的可重复组件而构建的,这使得用最少的语句构建管道变得很容易。今天,PyCaret 仍然使用许多 Pythonistas 熟悉的模块:用于数据辩论的 Pandas 和 Numpy、用于可视化的 Matplotlib、 Plotly 和 Seaborn、用于建模的 scikit-learn 和 XGBoost、用于自然语言处理的 Gensim、Spacy 和 NLTK 等等。
Image from pycaret.org
建设管道
虽然从第一个版本到 PyCaret 2.2,内部结构和用法有了很大的变化,但是体验仍然植根于同一个目标:整个模型开发生命周期的简单效率。这意味着您可以利用 PyCaret 从原始数据到训练、调整、可解释性分析,再到模型选择和实验记录,所有这些都只需要几行代码。
Training and comparing models in just a few lines of code
让我们浏览一下在 PyCaret 中构建分类管道的每一步。
装置
您可以在这里的预配置示例项目中快速试用 PyCaret:Domino 上的 py caret 项目。如果您想将它安装在另一个 Domino 计算环境中,或者在其他地方使用 Docker 映像,您可以添加以下 RUN 语句来添加 PyCaret 2.2.2(以及本演练所需的依赖项):
RUN sudo apt-get purge python-numpy -y
&& sudo apt-get autoremove --purge python-numpy -y
&& sudo pip uninstall numpy -y
&& sudo pip install numpy==1.17 && sudo pip install pycaret==2.2.2 && sudo pip install shap==0.36.0
或者你可以用 pip 安装(尽管如果你没有使用 Docker,你可能想在虚拟环境中这样做): pip install pycaret
对于这个例子,我从 Domino Analytics 发行版环境开始。根据您的启动环境,您可能还需要安装 Pandas 和 Domino Analytics 发行版附带的一些附加依赖项。
您可以通过导入软件包来验证是否安装了所有内容,如下所示:
import pycaret
print('Using PyCaret Version', pycaret.__version__)
print('Path to PyCaret: ', pycaret.__file__)
import os
import pandas as pd
from pycaret.classification import *
from pycaret import datasets
访问数据
有两种方法可以将您的数据注册到 PyCaret 中:通过存储库或 Pandas 数据框架。让我们来看看每种方法。
加载带有熊猫的数据框
将数据放入 PyCaret 的第一种方法是加载一个 Pandas 数据帧,然后将其传递给 PyCaret。
data_path = os.path.join(os.environ['DOMINO_WORKING_DIR'], 'mushrooms.csv')
print('Data path: ', data_path)
data = pd.read_csv(data_path)
data.head()
使用数据仓库
PyCaret 教程中使用的第二种获取数据的方法是从 PyCaret 数据存储库中提取一个精选的数据集。该存储库包含了用于分类、回归、聚类、NLP 等的流行样本数据集,非常有用。(据我所知,该存储库包含 56 个数据集,这里显示了其中的一个示例。)您可以列出存储库中所有可用的数据集,并查看相关的元数据:
all_datasets = pycaret.datasets.get_data('index')
all_datasets = pycaret.datasets.get_data('index')
dataset_name = 'heart_disease' # Replace with your desired dataset.
data = pycaret.datasets.get_data(dataset_name)
注意 : PyCaret 2.2 期望数据作为数据帧加载到内存中。如果您使用的是大型数据集,PyCaret 在项目的探索和原型阶段可能会很有用,前提是您可以将足够多的数据样本加载到内存中进行有意义的探索。如果您的数据集既大又宽,使得您的要素数量接近或大于您可以加载到内存中的样本数量,那么预处理以减少要素数量或利用其他工具将是更好的选择。
实验设置
PyCaret 自动处理许多繁琐的预处理步骤,它将基本的数据准备步骤标准化并方便地打包到可重复的省时工作流中。用户能够自动清理(例如,使用各种可用的插补方法处理缺失值),分成训练集和测试集,以及特征工程和训练的某些方面。虽然在这个过程中创建的许多对象没有明确地显示给用户(比如训练和测试集,或者标签向量),但是如果更有经验的从业者需要或者希望的话,它们是可以访问的。
clf1 = setup(data,
target = target_variable_name, # Use your target variable.
session_id=123,
log_experiment=True,
experiment_name='experiment1', # Use any experiment name.
silent=True # Runs the command without user input.
)
比较基线模型
在这里,我们开始看到 PyCaret 的全部功能。在一行代码中,我们可以训练和比较数据集上所有可用模型的基线版本:
T2best_model = compare_models()
这将训练每个可用模型类型的基线版本,并产生训练模型的度量的详细比较,并突出显示跨模型的最佳结果。
best_model = compare_models()
请注意,我们不需要手动准备任何数据——我们只需要以 CSV 格式提供数据,并运行 setup 函数。在这两个设置步骤的幕后,数据被传递到 PyCaret,并被转换到训练和评估可用模型所必需的程度。要查看 PyCaret 了解哪些模型,我们可以运行
T2models()
它返回所有可用模型的数据框架、它们的专有名称、它们所来自的参考包(例如 sklearn.linear_model。_ 后勤。LogisticRegression),以及是否支持 Turbo(一种限制模型训练时间的模式,对于快速比较可能是可取的)。
models()
训练和调整特定模型
从 compare_models 中,我们可以轻松地看到每个指标的最佳基线模型,并选择它们进行进一步的研究。例如,如果我们要寻找上面 AUC 最高的模型,我们会选择继续使用随机森林。然后,我们可以使用 create_model 和 tune_model 函数保存并微调我们的模型。
rf = create_model('rf', fold = 5)
Tuned_rf = tune_model(rf)
组合模型(可选)
我们可以用各种方式组合我们训练好的模型。首先,我们可以使用 bagging(引导聚合)和 boosting 等方法创建集成模型。装袋和增压均由系综 _ 模型函数调用。我们可以进一步应用混合和堆叠方法来组合不同的模型或估计器——估计器的列表可以传递给 blend_models 或 stack_models 。如果需要,可以创建集合模型,并通过混合或堆叠将它们组合在一起,所有这些都在一行代码中完成。为了清楚起见,我们将展示一个例子,其中这四个方法中的每一个都在它自己的单元格中顺序显示,这也允许我们看到当使用这些方法中的每一个时 PyCaret 的默认输出。
创建袋装决策树集成模型:
bagged_dt = ensemble_model(dt)
创建增强决策树集成模型:
boosted_dt = ensemble_model(dt, method = ‘Boosting’)
混合估计量:
blender = blend_models(estimator_list = [boosted_dt, bagged_dt, tuned_rf], method = 'soft')
堆叠袋装、增强和调谐估值器;
stacker = stack_models(estimator_list = [boosted_dt,bagged_dt,tuned_rf], meta_model=rf)
AutoML (Optional)
使用 AutoML 特性可以快速、轻松地调整特定指标。
# Select the best model based on the chosen metric
best = automl(optimize = 'AUC')
best
AutoML 技术通常减少了对模型选择过程的人工监督,这在许多情况下可能是不理想或不合适的,它们可以是一种有用的工具,用于快速识别特定目的的最高性能选项。
用图分析模型
一旦选择了首选模型,无论采用何种方法,其性能都可以通过内置的绘图选项进行可视化。例如,您可以简单地在随机森林模型上调用 plot_model 来返回每个类的重叠 ROC 曲线:
plot_model(best)
用 SHAP 解释模型(对于兼容的模型类型)
越来越多的情况是,仅仅有一个性能良好的模型是不够的——在许多行业和应用中,模型还必须是可解释的。我们的首席数据科学家 Josh Poduska 在两部分系列中写了关于 SHAP 和其他可解释工具的精彩概述,第一部分讨论了 SHAP 的利弊,第二部分讨论了 t 2 在多米诺骨牌中使用 SHAP 的问题。PyCaret 提供与 SHAP 的无缝集成,因此您可以轻松地将解释图添加到您的模型分析中。
interpret_model(best)
interpret_model(best, plot = 'correlation')
interpret_model(best, plot = 'reason', observation = 12)
预测
正如我们现在所期望的,根据我们的测试数据生成预测是轻而易举的事情:
predict_model(best)
保存并加载模型
一旦我们对选择的模型感到满意,我们就可以轻松地保存它:
save_model(best, model_name='best-model')
最后,我们可以加载我们保存的模型以供使用:
loaded_bestmodel = load_model('best-model')
print(loaded_bestmodel)
如果您想了解我们如何将所有这些整合到一个可复制、可共享的 Domino 项目中,请查看下面的参考项目。它包括上面讨论的所有内容,以及一些其他的例子和资源。任何人都可以浏览项目并下载代码文件。您必须登录(免费 do to - 在此注册)才能在 Domino 中运行代码。
我们很想听听您对 PyCaret 的使用案例和体验。让我们知道它是否对您有所帮助,以及您是否希望在这个领域看到更多关于工具的项目和片段。给我们留言或者把你的问题和反馈带到多米诺社区(也是免费的- 在这里注册)。
Domino 参考项目
Domino 上的 PyCaret 项目
这篇文章附带了一个参考项目,为您提供了一种快速的方法来尝试我们的 PyCaret 并跟随这个演练。该项目包括一个分类管道模板笔记本,它解决了上述问题并展示了附加功能。
如何使用 Domino 在 32 核集群上运行 PySpark
在本帖中,我们将向您展示使用 Spark 的两种不同方式。第一种是使用 Domino,它在功能强大的 AWS 机器上预装和配置了 Spark。第二种选择是使用您自己的本地设置——我将指导您完成安装过程。
Spark 概述
Spark 是一个快速通用的集群计算平台,非常适合数据科学家每天需要执行的多种类型的并行任务。Spark 扩展了只有两个操作符的 MapReduce,使其包含更广泛的交互式分析查询和流处理选项。Spark 最大的优势可能是它能够在内存中运行计算。Spark 网站称,它在内存上运行程序的速度比 Hadoop MapReduce 快 100 倍,在磁盘上快 10 倍。
Spark 如此强大有两个原因。首先,它为表达并行计算任务提供了一个很好的语法。其次,它极大地简化了跨集群扩展作业。Spark 让我们更接近实时分析数字处理。作为在物联网领域工作的人,这种可能性不仅有趣,而且对基于传感器的触发器、警报和可操作智能的未来至关重要。许多应用程序的未来取决于以快速方式对多种数据类型进行“实时”处理,以便更快地向客户交付结果。
多米诺骨牌中的火花
Domino 允许您在任何类型的 EC2 机器上运行您自己的代码(或者在您自己的硬件上,当安装在本地时)。这让我们可以在一台多达 32 个内核的机器上运行 Spark 代码,而无需任何设置或配置。在 Domino 端,一切都是预先配置好的,所以您不需要安装任何东西。
在本文中,我们将使用一种现成的 MLlib 算法来测试 Spark 的核心并行化能力。
让我们跳过大数据的 Hello 世界——计算单词——直接进入更有趣的话题。如果您想知道,Spark 支持两种用于二进制分类的线性方法:支持向量机(SVM)和逻辑回归。为了更好地了解 PySpark 中的 SVM 和对数回归,请查看加州大学洛杉矶分校的 Mevlut Turker Garip 的教程。
在 Python 中,我们从导入适当的 Spark 库开始。
from pyspark import SparkContext
from pyspark.mllib.regression import LabeledPoint
from pyspark.mllib.classification import LogisticRegressionWithSGD
第一个,SparkContext,是 Spark 最重要的组件。为什么?SparkContext 是到 Spark 集群的连接,可以用来创建我们前面讨论过的非常重要的 rdd。
尊重公园背景
现在我们可以开始我们的火花了:
sc = SparkContext(appName="PythonLR")
接下来,我们需要确保每个数据点的特征和标签以 MLlib 喜欢的方式格式化。注意:如果您习惯于用-1 和 1 标记二进制分类,那么您必须在 MLlib 中将-1 标记切换到 0。幸运的是,进行这种转换很简单。如果你分叉这个项目,一定要格式你的数据“正确”第一!以下函数拆分数据集中的值(逐行),将任何-1 转换为 0,然后以 LabeledPoint 格式返回一组标注/要素。
def parsePoint(line):
values = [float(s) for s in line.split(' ')]
if values[0] == -1: # Convert -1 labels to 0 for MLlib
values[0] = 0
return LabeledPoint(values[0], values[1:])
下一行很长。它使用我们选择的数据集创建我们的 RDD,然后执行地图转换。在本例中,我们已经用 parsePoint()函数创建了所需的 map 过程。
points = sc.textFile("sample_svm_data.txt").map(parsePoint)
最后,我们设置迭代次数,用随机梯度下降训练我们的逻辑回归模型,打印一些最终权重和截距值,然后在最后关闭我们的 Spark 集群。
iterations = 5
model = LogisticRegressionWithSGD.train(points, iterations)
print("Final weights: " + str(model.weights))
print("Final intercept: " + str(model.intercept))
sc.stop()
拥有一个可以从 Spark 强大的数据处理中受益的大数据集?转到 Domino 项目设置中的“硬件层,并根据需要进行扩展。Spark + Domino 是一个非常棒的组合。这里我只演示了一个小的数据集用例,但是我强烈建议在用您自己的数据扩展硬件时测试一下 Domino 的性能变化。有趣的是 Spark 在多达 32 个内核的“集群”上运行时是多么强大...当集群实际上只在一台机器上运行时。这并不是说你不能在 8 台各有 4 个内核的机器上使用 Spark,但是如果你在一台机器上有 32 个内核,为什么不让它们唱歌呢,对吗?
让我们看看使用不同硬件层设置的输出。
硬件层 | 持续时间 |
---|---|
小型(双核,8GB) | 26s |
中型(4 核,16GB) | 22s |
超大(16 核,30GB) | 35s |
XX-大型(32 个内核,60GB) | 19 岁 |
GPU (8 色,15GB) | 14s |
这里有一些令人惊讶的结果。首先,16 核机器(EC c3.4xlarge)比预期慢得多。我们不确定这是为什么——这不是我们第一次在特定类型的 EC2 机器上看到奇怪的配置。第二个令人惊讶的结果是 GPU 实例有多快(一个 EC2 g2.2xlarge),尽管它的内核较少)。这个故事的寓意是,越大并不总是越好=)
顺便说一下,如果您已经建立了自己的 Spark 集群,Domino 也可以连接到它并在那里运行代码。
本地安装
如果你有一天带着笔记本电脑被困在荒岛上,无法上网,以下是如何在你自己的环境中安装 Spark 的方法。JSpark 是建立在 Scala 之上的,但是如果你对如何用 Scala 编码有一点模糊的了解,并且更喜欢 Python 这样的语言,那么你就没问题了。事实上,从最新的 Spark 版本(1.4.0)开始,你可以使用 R。就我个人而言,如果你计划创建可部署的应用程序/产品,我发现 Python 或 Java 是更好的 Scala 选择,但是如果你只需要在 R 中运行“一次性”脚本,那么 Spark 会工作得非常好。
Spark 文档给出了一个不太令人满意的安装指南,所以如果你是 Mac 用户,我强烈推荐这个教程。Linux 用户应该看看的这个教程。不管是什么操作系统,安装 Spark 都是一个相当轻松的体验。接下来的过程主要是这样的:
- 确保您安装了 Java 开发工具包的版本 7 或 8
- 安装 Scala
- 从https://spark.apache.org/downloads.html下载火花
- 光盘放入 Spark 下载目录并运行:
sbt/sbt clean assembly
- 用
./bin/pyspark
从 Python 运行 Spark
我不知道你,但我总是忘记给我的生活增加新的内容。zshrc 或者。bashrc 文件。我相信你们大多数人都走在了这条曲线的前面,但是对于像我这样容易分心的人来说,下面是我在我的。zshrc 文件。请确保根据您独特的安装路径进行更改,否则您的 shell 会向您抛出错误。
prettyprint lang-sh
export JAVA_HOME=$(/usr/libexec/java_home)
export SCALA_HOME=/usr/local/bin/scala
export PATH=$PATH:$SCALA_HOME/bin
export SPARK_HOME=~/spark-1.4.0
export PATH=$PATH:$SPARK_HOME/bin
export PYTHONPATH=$SPARK_HOME/python:$SPARK_HOME/build:$PYTHONPATH
另一个小提示。火花太健谈了,我不喜欢。告诉我最基本的,伙计!我通过将信息打印转换为如下警告,使 Spark 不那么冗长:
cd ~/spark-1.4.0/conf
cp log4j.properties.template log4j.properties
编辑 log4j.properties 并更改下面一行,通过将 INFO 改为 WARN,将 log4j.rootCategory 设置为只记录警告和错误。保存并关闭文件,一切都准备好了。
您可以在 Spark 安装中的 examples 部分找到我们之前在 Domino 中运行的逻辑回归示例。Spark 附带了一些非常好的 MLlib 示例,您可以在下面找到:
$SPARK_HOME/examples/src/main/python/mllib/. Spark also provides some basic datasets to start with under $SPARK_HOME/data/mllib/.
进一步阅读
既然您有了一个可以轻松扩展工作的平台,那么在 Spark 的核心之上自然会有 Apache 支持的包,以便使整个数据路由、存储和处理过程更加容易。下图显示了当前的 Spark 生态系统,其中包括用于数据查询的 Spark SQL、用于实时流处理的 Spark Streaming、用于开箱即用的机器学习算法的 MLlib 以及面向所有图论爱好者的 GraphX。
Spark 中有很多值得学习的内容,会让您忙碌一段时间。如果你想深入兔子洞,我推荐你去拿奥莱利的书学习火花。