TowardsDataScience 博客中文翻译 2021(一百一十五)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

将设计和敏捷思维应用到您的数据科学项目中—第 1 部分

原文:https://towardsdatascience.com/applying-design-and-agile-thinking-to-your-data-science-project-part-1-ef945c558181?source=collection_archive---------22-----------------------

了解如何将设计思维应用于任何数据科学案例

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

罗斯·斯奈登在 Unsplash 上的照片

把世界想象成一个由数百万块碎片组成的巨大拼图。拼图仍未完成,一些碎片已经放置,但仍有空间放置新的碎片。我们想让我们的解决方案成为这个巨大拼图中的一块拼图,但是我们不知道怎么做。设计和敏捷思维帮助我们将我们的解决方案整合成一个拼图,放入这个巨大的拼图中。

创建一个数据产品可能是混乱和困难的。我的建议是,当一开始看起来似乎没有解决方案时,不要轻易放弃,而是要继续尝试构建这些部分!

遵循设计和敏捷思维作为您旅途中的向导,可以使您的解决方案的设计、实现和到达变得更加容易。

你可能听说过设计和敏捷思维方法,因为它们在许多组织中被广泛使用。本文简要介绍了这两种方法,并解释了如何在一个数据科学案例中应用设计思想

如果你对如何在一个数据科学案例中应用敏捷思维更感兴趣,请查看本文的 第二部分 ,否则,继续阅读!

设计还是敏捷思维?

差异#1

如果你对实际问题和切实可行的解决方案不清楚,那么你可以使用设计思维方法的步骤来帮助你度过难关。

如果你处在一个问题已经明确的情况下,并且你需要管理你的方式直到你按时达成解决方案,那么你可以遵循敏捷思维方法。

差异#2

设计思维用于重新定义问题,理解用户,尝试新颖的概念,并交付解决方案的最优和创新设计。

敏捷思维是一种项目管理方法,将解决方案的设计(设计思维过程的结果)转化为实际的解决方案。

类似

两者有相似之处,例如:

  • 以人为中心,优先考虑最终用户和利益相关者的需求,
  • 迭代,由多个循环组成,并在每次迭代中根据提供的反馈进行改进。
  • 聚焦选项,列举探索的可能性

这两种方法的结合可以确保高质量地解决组织内部的实际问题。

设计思维:没有数据的数据科学

在大多数情况下,大量的数据是可用的,如果我们立即开始查看数据,我们可能会在试图理解数据列和字段时迷失,并忘记最初的问题。因此,我们应该后退一步,脱离细节,尝试创建一个组织的流程及其瓶颈的整体概述。

在此阶段,我们期望的结果识别问题并设计解决方案。因为我们想要带来一个数据驱动的解决方案,所以设计应该包括数据需求的初始草案和数据产品的第一个概念。在这个阶段,我们还应该定义最终产品的用户,并让他们参与设计过程。

设计思维方法包括三个步骤:问题理解,发散,收敛,如下图所示。

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

设计思维,埃琳娜·斯塔马特卢素描

第一步:理解问题

这一阶段主要是为了更深入地了解组织内部的现状。

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

设计思维:第一步,Elena Stamatelou 的草图

A.面谈

安排与组织中不同人员的面谈,有助于我们深入了解他们的流程、沟通方式和愿景。从数据科学家的角度来看,预期的关键成果是发现组织的数据成熟度级别,这显示了数据科学在其组织中的当前角色。为了达到这种理解水平,我们为受访者列出了一系列问题。

个人问题

  1. 你的背景是什么?
  2. 你在公司的角色是什么?你在哪个部门工作?
  3. 你对数据科学了解多少?

团队问题

  1. 你是团队的一员还是管理团队?
  2. 与你密切合作的同事的角色是什么?
  3. 你的团队的职能是什么?
  4. 从规模和层级来看,团队的结构如何?
  5. 您在团队内部以及与其他部门沟通的频率如何?

商业问题

  1. 你的组织最具挑战性的问题是什么?
  2. 你的团队最具挑战性的问题是什么?

数据科学问题

  1. 您的组织中有数据科学相关项目的例子吗?如果是,这些项目是关于什么的?
  2. 您的组织中有数据科学家吗?如果是,能否举例说明它们的影响?
  3. 对于数据科学如何应对贵组织内部的挑战,您有什么想法或建议吗?

数据管道问题

  1. 您目前是否收集或拥有任何数据?
  2. 您是否执行涉及数据处理或分析的任务?
  3. 数据是如何存储和提取的?
  4. 数据的大小是多少?

技术

  1. 您使用哪种类型的控制面板进行数据可视化/分析?
  2. 您使用哪种数据库系统来存储数据?
  3. 你使用云技术吗?
  4. 对于数据分析/建模,你有什么偏好的编程语言吗?

视觉问题

  1. 您认为您的组织在未来十年内会朝着更加数据驱动的方向发展吗?
  2. 员工适应新技术的难易程度如何,比如一个新的软件或数据产品?

B.主要调查结果演示

演示应该包括对访谈结果的总结,并总结组织面临的主要挑战。

为了增加数据科学视角,定义组织的数据成熟度级别对于将数据使用推进到下一个级别至关重要。成熟度各不相同,从不使用任何数据的公司到信任数据并根据数据洞察力做出决策的公司。

下图显示了迈向数据驱动型组织的旅程。

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

数据成熟度级别,由 Elena Stamatelou 绘制

  1. **数据拒绝:**主动拒绝数据使用
  2. **数据冷漠:**对数据的使用缺乏兴趣
  3. **数据感知:**数据收集和历史数据的可视化,用于了解过去的事件(描述性分析)
  4. **数据通知:**基于历史数据的模型,用于未来事件预测(预测分析)
  5. **数据驱动:**基于预测的决策建议(说明性分析)

在了解了关键挑战和组织的数据成熟度后,演示文稿还应包括一些示例,说明数据科学如何帮助组织应对一些挑战并转变为更加数据驱动的组织。

第二步:发散

如果一切皆有可能呢?我们应该带着这个问题度过这个阶段,并探索每一种可能性。该阶段由两部分组成;利益相关者地图初稿和集思广益会议。

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

设计思维:第二步,Elena Stamatelou 的草图

A.利益相关方地图(初稿)

在问题理解阶段之后,我们对项目中涉及的各方有了很好的了解。为了组织不同利益相关者的视图以及他们的参与和影响,我们需要创建一个利益相关者地图的初稿,如下所示。

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

利益相关者地图,Elena Stamatelou 绘制

区分不同类型的利益相关者的两个主要变量是他们的兴趣和他们在我们项目中的影响水平,这两个变量的所有组合都是可能的。

目前,我们不需要绘制所有利益相关者的详细地图,但一个初稿就足以继续设计思维方法的下一步。

B.头脑风暴

完成利益相关者图后,我们从图的不同部分选择最具代表性的利益相关者,这样我们就有了具有不同影响和兴趣水平的利益相关者的合适组合。然后,我们邀请这些利益相关者参加我们的集思广益会议。

在头脑风暴期间,我们与不同的利益相关者创建两到三个小组。我们将会议分为两部分:挑战思维和解决方案思维。

挑战创意部分,我们询问参与者他们面临的两大挑战,将他们分组,让他们投票选出最重要的挑战。然后,对于投票最多的挑战,我们要求他们确定受其影响的利益相关者,并将他们分组。

之后,我们选择三个投票最多的挑战及其最受影响的利益相关方,并开始解决方案的构思部分。随后,我们要求参与者为密切相关的利益相关者设想理想的情况,并找出阻碍组织达到这一理想情况的瓶颈。然后,我们让他们就管理这些瓶颈的方法进行头脑风暴,并根据相似性对他们进行分组。

第三步:融合

在分散和探索了各种挑战及其可能的解决方案之后,没有添加任何限制,是时候收敛了。这里的目的是定义一个具体的用例,并向涉众提出一个数据驱动的设计概念。

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

设计思维:第三步,Elena Stamatelou 的草图

A.概念创造:

我们在这里的首要任务是总结集思广益会议期间产生的所有挑战和解决方案,并重点关注那些似乎对组织影响最大、负担更重的挑战和解决方案。对于每一个项目,我们都致力于定义数据需求的初稿、数据产品的概念和高级数据驱动的数据管道。

对于数据需求的初稿,我们考虑数据可用性、可能的数据收集和数据隐私问题。在那之后,我们开始制作最终数据产品的第一份草图,包含了最初的数据需求。考虑到数据需求和最终产品,我们设计了一个数据管道的概述,其中包括从数据收集到最终产品部署及其交付给利益相关方的整个流程。

在头脑风暴期间,我们对定义的关键挑战的解决方案有了一个良好的初步设计,然后安排与主要利益相关者的会议。我们利用这些会议的时间来讨论这些设计,并汇聚到一个解决用例的设计,这个用例对他们来说似乎更有趣,也更现实。

B.利益相关者地图细化

在定义了解决方案的第一个设计和一个具体的用例之后,是时候回顾利益相关者地图的第一个草案了,它是在头脑风暴会议之前创建的。

这一步的主要目的是细化不同的涉众群体并创建三个团队;数据、反馈和管理 团队。这些团队对于产品开发的共同创造过程以及实现与他们的有效协作是必不可少的。

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

团队,草图由 Elena Stamatelou 绘制

数据团队将包括与数据密切相关的利益相关者,如数据或业务分析师。该团队将帮助收集数据和保护数据隐私。反馈团队将由最终用户组成,他们将对原型和最终产品进行实验并提供反馈。在管理团队中,将包括层级较高的利益相关者。这个团队将作为指导委员会,对项目方向的决策有很高的影响。

C.工程计划

实施设计前的最后一步是制定项目管理计划。这是设计思维和敏捷思维方法之间的过渡步骤。

有必要回顾在设计思考过程中创建的所有信息,包括数据需求、解决方案的设计以及不同的利益相关者群体。基于这个评审,我们创建一个敏捷计划,在它的执行之后将交付数据产品。

包扎

使用设计思维作为指导,使合适解决方案的形成变得更加容易。在设计之后,实施就来了,敏捷思维可以在这个过程中做我们的向导。

阅读本文的 第二部分 ,了解如何在您的数据科学案例中应用敏捷思维。

将设计和敏捷思维应用到您的数据科学项目中—第 2 部分

原文:https://towardsdatascience.com/applying-design-and-agile-thinking-to-your-data-science-project-part-2-d11ce96275f6?source=collection_archive---------35-----------------------

了解如何将敏捷思维应用于任何数据科学案例

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

汉斯-彼得·高斯特在 Unsplash 上拍摄的照片

把数据驱动的解决方案想象成一块拼图。这一块需要有一个合适的形状和颜色,以适应一个更大的拼图。我们的世界就是这个拼图,还没有完成。我们想做一个合适的拼图块,然后放入拼图中,使其更加完整。换句话说,我们想给这个世界带来一个合适的解决方案。设计和带来合适的解决方案可能很复杂。设计思维做出解决方案的形状,而敏捷思维确保其实施,取得设计思维的成果。

这是文章的第 2 部分,重点是如何将敏捷思维应用到数据科学项目中。如果您对将设计思维应用于数据科学案例或了解两种方法的异同更感兴趣,请阅读本文的第 1 部分 ,否则,请继续阅读!

敏捷思维:数据科学与数据

鉴于解决方案的设计是设计思维的结果,敏捷思维方法促进了设计的实现过程,并确保了最终数据产品的及时交付。虽然在设计思维阶段,数据的使用不是必须的,但是在敏捷思维阶段,数据的使用是必须的,但不一定从一开始就需要。此时,我们期望的结果是在一个时间框架内发布数据产品。

敏捷思维是一种迭代方法,由多个阶段组成。每个阶段都将逐步建立在前一个阶段的基础上,以产品发布为最终目标。我们从我们产品的一个非常基本的轮廓开始,那就是交互式线框(第一阶段)我们不断地添加功能,每次都是最新版本。从基本的第一个版本开始,我们迅速发布了一个最小可行产品(第 2 阶段),然后是 beta 产品版本(第 3 阶段)。最后,我们在产品发布(阶段 4)期间交付我们的最终数据产品。

每个阶段由相同的五个组成部分组成;设计、预处理、建模、可视化和部署。各阶段及其基本组件在下图中显示为金字塔。每个阶段都考虑相同的方面,但是每次都在它们的基础上进行改进,使它们更加完整。

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

敏捷思维的生命周期,Elena Stamatelou 的草图

在每个阶段的开始,都有一些空间来重新定义我们的解决方案方法,考虑从上一阶段学到的知识。这提供了结合变化的灵活性的可能性,以及对我们最初方向的执着,这是设计思维方法的结果。在每个阶段的末尾,需要与数据产品的最终用户(反馈团队)一起计划反馈会议。该反馈提供了关于他们的需求和他们对产品当前版本的满意程度的知识。因此,这有助于定义需要在下一阶段应用的必要修改。

阶段 1:交互式线框

这个阶段包括项目启动,还没有数据。主要的可交付成果是产品大纲交互线框,这将是一个非常基本的用户界面,将使用户对我们的方向有第一印象。

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

敏捷思维:交互式线框(第一阶段),Elena Stamatelou 的草图

设计

我们使用设计思维方法的结果来定义解决方案的初始架构、任务以及该阶段的方向。我们还创建了用户故事的初始草图,我们将在这个阶段使用它作为指南。

预处理

**数据要求:**由于没有数据,这里的主要目的是定义数据要求。我们考虑两个相反的方向。一方面,通过想象没有关于数据可用性的限制,我们定义必要的数据来解决挑战。从另一方面来说,通过考虑现有的数据及其限制,我们想到了实现最终项目目标的方法。然后,我们得到一个包含所有必需数据的列表。

数据保护影响评估(DPIA) :在获取数据之前,我们需要准备并与组织签署协议,以确保数据保护。我们致力于 DPIA 流程,以识别并最大限度地降低可能的数据保护风险。

建模

**文献研究:**在开始任何建模方法之前,我们需要做一个文献回顾。我们的目标是创建一个包含所有可能的建模方法的列表,从最佳实践到最先进的技术

形象化

线框:牢记用户故事中描述的用户视角和需求,我们创建可视化的格式和一般结构。我们还制作了一些高层次的草图,并将它们组合成一个交互式线框,该线框将用于该阶段结束时的反馈会议。

部署

**数据基础设施了解:**我们收集有关组织基础设施的信息,如数据存储或 BI 工具。我们的目标是找出我们将使用哪些工具来部署我们的数据产品。使用员工熟悉的工具比尝试引入新工具更具成本效益,也更容易。

反馈

在这个阶段的最后,我们组织一个反馈会议,在这个会议中,我们向用户展示交互式线框,让他们使用它,并向他们提问以获得他们的反馈。

阶段 2:最低可行产品

在这里,我们的目标是为利益相关者和最终用户提供解决方案的基础,这将是最小可行产品。从我们的角度来说,我们希望收集最大数量的反馈和学习,这样我们就可以确保我们最终的工作原型能够满足用户和利益相关者的期望和需求。

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

敏捷思维:最小可行产品(第二阶段),Elena Stamatelou 的草图

设计

我们使用前一阶段收集的反馈来提炼用户故事,重塑我们的设计,并规划当前阶段。我们通过添加更多细节来更新初始架构

预处理

数据收集设计:有了数据需求列表,我们就设计了获取数据的方法。如果数据已经存在于他们的系统中,那么请求和接收数据是很容易的。如果数据尚不存在,我们应该定义一个数据收集流程。

数据生成:由于数据收集需要一些时间,为了节省时间,我们根据数据需求生成合成数据**、**。在这个阶段,我们使用生成的数据。

建模

**基本特征工程:**在拥有真实数据之前,我们使用合成生成的数据来创建我们认为最有影响力的基本特征。我们还清楚地定义了目标变量。

**基本建模:**使用基本特征,我们应用简单模型来预测我们的目标变量。

形象化

**模型:**使用前一阶段的线框作为起点,我们基于更新的用户故事添加数据可视化。我们的重点是制作一个用户友好的交互式模型,让用户感受到我们的方向,并为我们提供建设性的反馈。

部署

**部署要求:**根据对组织基础设施的了解,我们指定部署要求,并检查可行性和所涉及的成本。

**本地部署:**在这个阶段,我们在本地服务器上运行模型,

反馈

在这个阶段结束之前,我们会安排一次与用户的会议,通过向他们展示我们的最小可行产品,与他们分享我们的概念和预测的数据可视化。

阶段 3:测试产品版本

这个阶段的重点是交付一个 beta 产品版本,其中包括真实的模型预测,并在一个用户友好的交互式仪表盘中显示出来。在这个阶段的最后,用户和涉众将测试产品以识别 bug 和其他缺陷,以便进入产品交付阶段。

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

敏捷思维:Beta 产品版本(第 3 阶段),Elena Stamatelou 的草图

设计

在开始该阶段之前,我们重新考虑所有的知识,并通过将数据存储的细节添加到模型部署中来更新架构。这个阶段离实际产品更近了一步,因为我们将使用真实数据。

预处理

**数据收集:**根据数据收集设计和数据需求,我们从组织中收集数据。

**数据探索:**收到真实数据后,我们检查完整性(缺失值)和及时性(最新数据)以确保数据质量,以便我们可以进一步使用它进行建模。为了更好地理解数据的意外行为,我们寻找异常值(异常),这些异常值是错误的或非常重要的值,显示了数据的奇怪行为。

建模

**特征工程:**为了继续使用相同或相似的建模方法,我们检查所提供的数据在多大程度上可以替代合成数据。然后,我们将合成数据的特征与真实数据的特征进行匹配,并且如果我们认为来自真实数据的更多特征会改进预测结果,则添加这些特征。

**高级建模:**有了真实数据的特征,我们首先应用前一阶段的简单模型,以确保真实数据的特征可以替代合成的特征。如果简单的模型不再适用,我们会用更合适或更复杂的模型来代替它。在这里,我们还可以尝试不同的建模方法或超参数调整,并比较不同模型或同一模型变体的性能。

形象化

**原型:**从上一阶段的交互式模型过渡到原型,需要进一步改进数据可视化和仪表板的前端开发。这里的重点是制作一个可以为最终用户服务的功能性和交互性的仪表板。

部署

**云/内部部署:**根据前一阶段定义的部署需求,我们应该将解决方案从本地运行转移到我们的设备上,在组织的云或内部服务器上运行。在这一部分中,我们部署预测模型,而不是定型模型。如果一切顺利,在下一阶段,我们还将部署培训模型。

反馈

这个阶段产生了一个类似于实际产品的 Beta 产品版本,因为我们同时在前端(仪表板)和后端开发(部署)上工作。在这一点上,我们给出了在产品发布之前从用户那里获得反馈的最后机会。

第 4 阶段:产品发布

在这个阶段,我们应用最后的改进。当不需要改进时,我们通过使持续验证成为可能来部署训练和预测模型,然后推出数据产品。我们的目标是向涉众和用户交付一个功能性的、可靠的和可用的产品。

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

敏捷思维:产品发布(第 4 阶段),Elena Stamatelou 的草图

设计

在这个最后的设计周期中,我们从最后的反馈会议中收集反馈,并在发布之前将最后的改进添加到产品架构中。

预处理

**预处理验证:**我们从组织中收集新数据,并将其与用于测试产品版本的数据进行比较,以检测差异。

**健全性检查:**基于对新数据预处理验证的观察,我们创建健全性检查,以确保输入数据具有合适的和期望的格式。

建模

**建模验证:**使用新数据,我们验证 beta 产品版本,并在需要时应用最后的更改。

形象化

**仪表板:**根据前一阶段的原型,我们构建了一个更稳定的仪表板,在其中我们应用了最后的改进。

部署

**持续部署:**如果测试产品版本的预测模型在云或内部基础设施中顺利运行,我们可以更进一步部署我们的模型。首先,我们还部署了我们的训练模型,以便在代码更新或新数据的情况下重新运行。我们的目标是为我们的预测模型实现持续集成(CI)、持续交付(CD)和持续培训(CT)。这意味着,对于任何新的数据或代码更新,模型都会被重新训练并提供更新的预测。

包扎

终于,我们的产品可以上市了!

随着不断的集成、开发和训练,我们的预测模型会随着新的输入而改进。提供这种灵活性使我们的数据产品能够适应变化。通过将它暴露给新的和更多的数据来改进数据产品的预测。

敏捷思维通过将来自设计思维的设计概念作为输入,创建了创建数据产品的指导方针。

如果你对如何在数据科学案例中应用设计思维感兴趣,请阅读本文的 第一部分

将改善和 5S 原则应用于外部数据采集

原文:https://towardsdatascience.com/applying-kaizen-principles-to-external-data-acquisition-c7c377300a64?source=collection_archive---------39-----------------------

解决任何分析问题的关键是拥有正确的数据。数据是一种资产。有远见的组织会像寻找收入流或新客户一样积极地寻找。有了相关数据,组织可以做出更明智的决策,解决关键的业务挑战。如今,“良好的分析”意味着远远超越一些常用的算法或仪表板来展示内部数据。

希望充分利用智能革命的企业必须不断发展,超越他们的四面墙,以获取他们需要的数据。获得相关的外部数据是一种竞争优势。公司必须制定有效的策略来寻找、获取、部署和理解新的替代数据资产。外部数据获取策略有助于更快地解决复杂问题,让企业真正成为数据驱动型企业。

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

图片由 格尔德 转自 Pixabay

那么,如果外部数据是竞争优势的来源,企业如何才能更好地获取外部数据呢?事实证明,90 年代制造业中流行的持续改进过程同样可以应用于现代数据工程。具体有两个:Kaizen 质量框架(为什么、什么、哪里、谁、什么时候和如何)可以帮助规划你的数据采集计划;而 5S 技术提供了一个可以用来管理和组织外部数据的框架。

改善质量框架

Kaizen 对持续改进的关注集中在六个基本问题上:为什么、什么、哪里、谁、何时和如何。让我们探讨它们与外部数据采集的关系。

我们为什么需要外部数据?

关键是从定义你最终想要解决的问题开始。你要么有一个需要回答的特定问题(为此你需要新的、更好的或补充的数据)。您正在努力优化现有的解决方案(微调模型并提高预测的准确性。)

我们需要什么数据?

第一步是寻找有助于你发现真知灼见的相关数据。外部数据,如客流量、定价、公司图、技术图以及其他营销和财务属性,可以改善预测模型和业务成果。

从哪里获取数据?

寻找正确的数据本身就存在一系列挑战。有成千上万的主要和公共数据源。为您的用例搜索和评估数据可能需要一些时间。及时访问数据是组织敏捷性的关键。

谁将使用这些数据?

有各种各样的外部数据用例,这意味着用户的类型各不相同。用户有不同的需求和技能。用户范围从市场营销和销售运营成员到客户洞察团队、欺诈和风险官、业务分析师和数据科学家。了解他们的需求并提供他们可以快速评估和消费的数据,对于从您的数据投资中获得最大投资回报至关重要。

数据应该什么时候刷新?

根据您的用例及其所需的数据信号,需要确定刷新数据的频率。确保您有正确的数据入职频率,以保持您的数据是最新的、准确的和相关的。还应持续监控预测模型的性能或漂移,以查看模型是否仍按照业务预期运行。如果发生任何信号丢失(例如丢失第三方 cookies),您应该立即为您的业务连续性寻找替代数据源。

如何利用这些数据进行分析和机器学习?

在获取、准备和整合外部数据之后,下一步是评估您将如何在您的分析或机器学习平台中使用这些数据。有多种连接选项可供考虑。看看您是否可以通过导出、API 和与存储(如 S3 或雪花)的连接功能来访问数据。此外,根据您的业务需求,规划与 Google Big Query、Databricks 和 Salesforce 等平台或应用程序的连接。

5S 技巧

5S 指的是下面这些可以让你的数据程序高效有效的日语单词:

  1. Seiri(排序)—对所有项目进行排序,并删除那些不必要的项目
  2. Seiton(订单)—将所有必需的物品放在最佳位置,以实现其功能
  3. Seis(清洁)—定期清洁和检查
  4. Seiketsu(标准化)—标准化用于分类、订购和清洁的流程
  5. Shitsuke(过程)—规程和过程导向

很多时候会加上第六个 S——安全。你可能已经看到链接了。让我们看看如何将这个框架用于外部数据。在您开始购买外部数据之前,请考虑:

Seiri (Sort)消费数据准备

利用外部数据的一个主要挑战是,外部数据通常不适合消费。数据准备过程可能包括数据清理、数据转换以及正确组织数据以供使用。

Seiton(订单)数据匹配与整合

要使用外部数据来解决您的特定业务问题,您需要将它与您的内部或培训数据集相匹配。匹配或身份解析是一项复杂的活动。如果您没有合适的工具,这可能会非常耗费资源。计划如何在数据中下订单,以便可以消费。

seis(Clean)数据质量和验证

了解数据源、其数据质量、覆盖范围、差距、新近性、更新频率、风险,以及最重要的与您的业务环境的相关性至关重要。数据购买的另一个风险是缺乏投资回报。确保您知道您的数据投资将带来的回报。在投资数据产品之前了解质量和风险

Seiketsu(标准化)标准化分拣、排序和清洁流程

数据采集不是一蹴而就的事情。数据获取、评估、清理、匹配和整合方法的标准化将有助于持续有效地使用数据。

Shitsuke(工艺规程)——工艺导向、监控和改进

建立一些机制,以便您可以监控预测模型漂移的数据。使数据获取成为您整体数据管理策略的一部分,并确保在购买之前对数据的相关性、质量、覆盖范围、风险和准备情况进行评估。

安全——隐私、合规、法规

考虑隐私、安全和法规遵从性要求。GDPR 和 CCPA 等隐私法规使得外部数据管理比以往更加困难。检查外部数据的合规性,保护政策,并纳入最佳实践,以消除将数据投入使用的风险。合规数据将帮助您更快实现高级分析和 ML 目标。

分析现在是竞争绩效的基础,就像数字化转型之前的制造能力一样。用于增强制造过程的技术可以直接应用于提高组织的分析能力。具体来说,5S 和 Kaizen 等技术提供了每个组织应该提出的战略问题,以增强其外部数据获取流程。生产方式正在发生变化,但这些学科在当今以 ML 和分析为动力的组织中仍然适用。

将机器学习应用于核反应堆动力学

原文:https://towardsdatascience.com/applying-machine-learning-and-exploratory-data-analysis-to-nuclear-reactor-kinetics-d1dae16fb081?source=collection_archive---------26-----------------------

使用 Python 进行核物理、反应堆操作和预测建模的初级读本

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

图一。2 兆瓦特特里加反应堆满功率。来源:我(沃克·佩恩)

根据核管理委员会的数据,美国有 31 个核研究反应堆。我碰巧有操作其中一个的许可证,在这篇文章中,我将演示我如何应用机器学习和通用数据分析技术来预测脉冲功率水平并提高我们实验的可重复性。

背景

一个裂变核反应堆利用裂变原子的能量工作。当铀-235 吸收一个中子时,它有机会裂变和分裂,释放裂变产物、中子和动能。这种能量加热冷却介质,冷却介质通常通过管道输送到热交换器,然后输送到蒸汽涡轮机,从而产生电能。我的设施是 TRIGA 反应堆的所在地,它不产生任何电力——它纯粹用于研究和实验。

有趣的事实:一公斤的铀-235 比一公斤的煤多 300 万倍的能量。哦,裂变反应不会产生碳排放。(我一点也不偏心。)

与商用反应堆相比, TRIGA 反应堆在许多方面都是独一无二的,其中之一就是其执行“脉冲”的能力。燃料的高度负反应性系数意味着随着温度的升高,反应性——从而裂变链式反应的速率——降低。这意味着反应堆在功率水平方面是自我限制的,并且由于燃料的设计,在没有操作者输入的情况下,在脉冲之后会物理地自我关闭。(所以他们才会让我这样的人来操作!)

脉冲通过气动方式(使用压缩空气)从反应堆堆芯中弹出一根控制棒来工作,这导致功率水平迅速增加。以下情况发生在几毫秒的时间跨度内:

  • 控制棒垂直向上射出堆芯。
  • 功率水平从大约 50 W 增加到高达 2000 MW。
  • 在这种高功率水平下,燃料的即时负反馈效应为堆芯提供了负反应性,从而使堆芯自动关闭。

在这一点上,控制棒可能仍在离开堆芯的途中,但随后会由于重力而回落。你最终得到一个功率响应函数 P(t) ,看起来有点像下面的图 2 功率随着控制棒被弹出而增加,然后随着负反应性的增加而迅速减少。

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

**图二。**脉冲期间反应堆功率、反应性和能量随时间的变化。来源:m .拉夫尼卡

虽然脉冲有许多研究应用,但它特别适合在非常小的规模上模拟核爆炸发出的辐射。具体来说,我们正在观察中子和伽马射线如何在原子水平上与电子相互作用。假设你正在设计一个新的电子元件,用来控制核武器系统的某个部分。你有多大把握你的电子设备会在附近的核爆炸中幸存下来?集成电路放在放射性弹头旁边储存 10 年会受到什么损害?这种损坏将如何影响组件的功能?或者,如果你正在设计一个用于新型战斗机的 CPU 芯片呢?当暴露在一定量的辐射下时,由你的 CPU 启动的飞行控制系统会失效吗?你可以看到这些问题是多么的重要。结合这一事实,即真正的核爆炸是一个考验,并有一系列问题(更不用说被全面禁止核试验条约禁止),你很快就会同意反应堆脉冲是一项关键能力。

注意:值得说明的是,这个脉冲只产生辐射。在这种类型的实验中,没有东西被爆炸。我们只是将一个样本暴露在一个高度受控的环境中,这个环境是为完成这样的任务而设计的。

操作员可以根据控制棒的反应性“价值”选择脉冲达到的最大功率水平。对于许多核反应堆来说,这种价值是以美元为单位来衡量的,由于解释我们为什么使用这种看似怪异的单位超出了本文的范围,如果你愿意,你可以在这里阅读所有相关内容

根据即将进行的实验,可能需要特定的脉冲功率水平。控制棒在堆芯中的位置决定了任何给定时间的功率水平。我从自己在这个反应堆的工作中编译的数据集由这些值和一些其他值组成,如下所述:

  • 日期。脉冲发生的特定日期时间格式的日期。
  • 估计反应性估计的脉冲的反应性插入量,单位为美元。这个估计是通过查阅某个控制棒的积分值找到的。例子:一个实验者将要求一个价值 2.00 美元的脉冲。操作员将根据所述控制棒的总积分值找到放置控制棒的位置。
  • 杆位置。堆芯中有四根控制棒—瞬态、垫片 1、垫片 2 和调节棒。在我的数据集中,标记为“跨,S1,S2,注册”,这些值与控制棒在堆芯中的物理位置有关。范围从 0 到 960,其中 0 完全插入内核,960 完全移除。
  • 峰值功率。单位为 MW。
  • **总能量。**以毫瓦秒计量。
  • 峰值温度。以摄氏度测量,这是仪表化燃料元件(IFE)达到的峰值温度。一些燃料棒内部嵌有热电偶,用来监测堆芯的温度。
  • 计算出的反应性。这是“真实的”反应性值,通常与估计的反应性有一定的差异。它是由反应堆控制台自动计算的。

在这篇文章的其余部分,我将分析数据集,看看我能收集到什么见解。此外,我将应用线性回归机器学习模型,根据估算的反应性棒位置,预测计算的反应性 。这个预测模型将帮助我们更准确地使用脉冲功率(在一定程度上——稍后会有更多的想法),并提高我们实验的有效性和准确性。我的最终目标是使我们的脉冲在特定样品的辐射暴露量方面更加准确和可重复。

探索性数据分析(EDA)

我提前清理了数据,所以我就不告诉你细节了。在大多数情况下,清理过程包括从数据集中移除不正确或不完整的条目。我必须识别和清理大量的手工输入错误(打字错误),以及一些丢失的数据点,我要么完全删除,要么用平均值替换。

一旦我有了干净的数据,我要做的第一件事就是导入相关的库并加载我的数据框架:

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as npfrom sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn import metrics
from sklearn.metrics import r2_scoredf = pd.read_excel('Pulse_Data_2021_NO_NULL.xlsx', )

之后,我总是喜欢使用三个主要函数来学习我的数据的一般特征— 。头()。info() 和*。描述()。*

。head() 只显示了数据帧的前几行,我们可以看到数据的一般结构:

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

图 3 。df.head()输出

。info() 输出数据帧中的条目数、列名、每列中的空条目数以及每列的数据类型:

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

图 4 。df.info()输出

还有*。describe()* 提供数据本身的一些汇总分析—均值、标准差、四分位数等。每列的。为了可读性,我喜欢把它调换一下:

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

图 5 。df.describe()输出

我的 EDA 的下一步是开始绘制任何可能有意义的东西。例如,我认为观察计算的反应性和峰值功率之间的关系会很有趣,所以我做了一个简单的散点图:

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

图 6 。计算反应性与峰值功率的散点图。

这两个变量之间存在明显的指数关系,这与驱动该操作的反应器动力学原理一致。该图也很有用,因为它可以识别潜在的异常点——要么是反应器的怪异行为,要么更有可能是不正确的输入。从这个图表中,我发现了其他需要清理或删除的粗手指条目。

关联热图是另一种可应用于大多数数值数据集的有用工具。下面的图 7 描述了哪些列彼此密切相关,值的范围从-1 到 1。

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

**图七。**关联热图。

要解释此热图,请寻找高值(接近 1)。1 的对角线是热图布局的人工产物,它告诉我每个特性都与自身直接相关。有道理。S1 和 S2 的相关性为 0.99,这也是有道理的,因为这两个控制棒在脉动时几乎总是处于完全相同的垂直位置。我最感兴趣的特性是计算反应性,它与峰值温度、总能量和峰值功率高度相关。这似乎也是合乎逻辑的,因为随着反应性的增加,我预计这些特性也会增加。

由于我试图提高估计反应性值的预测准确性,我的下一步是比较它的分布与计算的反应性。为了做到这一点,我叠加了两个直方图,并做了一些格式化,使它看起来很好:

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

图 8 。反应性直方图。

当决定我们想要多大的脉冲时,我们通常使用离散的脉冲反应性值。图 8 清楚地反映了这一点,显示$1.50、$2.00、$2.50 和$3.00 是常见的估计值。人们可能会认为,计算出的反应性值在每个估计反应性值周围呈某种正态分布,如蓝色图表所示(尽管不严格)。

再次查看**图 8,**似乎估算的反应性略高于计算的反应性。这意味着,一般来说,如果你请求一个 2.00 美元的脉冲,你实际上得到的值会比这个值少一点。我可以通过简单地减去两列数据并求平均值来量化这一点:

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

图九。反应性值的平均差异。

这表明,平均而言,“真实”计算的反应性比估计的反应性低 0.16 美元。

最后,我生成了一个图表,作为反应堆利用率随时间变化的有趣代理。该反应堆于 1992 年首次启动(又名“进入临界”),从那时起每年的脉冲数图表提供了一些深入的兔子洞:

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

**图 10。**反应堆脉冲频率每年一次。

图 10 中可能出现的问题包括:

  • 为什么 1994-1996 年和 2013-2014 年的脉搏如此之少?
  • 是否有管理上的变化影响了在该工厂进行的实验类型?
  • 是否有任何新的国家或大学研究发展需要额外的脉冲?
  • 在 2000 年和 2020-20201 年(现在)发生了什么需要如此多脉冲的实验,为什么在这期间没有这样的实验?

令人惊讶的是,从一些小图表中可以获得如此多的洞察力。

预测建模

预测计算反应性的任务适合(双关语)线性回归模型。这被认为是有监督的机器学习模型,因为数据已经被标记(提供 x 和 y 值来训练模型)。它在技术上是一个多元回归模型(其定义包含线性回归),因为使用多个独立变量( Est_Reactivity,Trans,S1,S2,Reg )来预测因变量( Calc_Reactivity )的结果。

注:这个线性回归模型假设因变量和自变量之间的关系是**线性的。**估计反应性与计算反应性明显呈线性相关,但我们的其他独立变量(反式、S1、S2、注册)却并非如此。独立变量之间也存在明显的多重共线性,因为杆的位置(S1、S2、Reg)高度相关。由于这些原因,线性回归模型可能不是最佳选择。需要进一步探索独立变量才能确定,但多项式回归或岭回归可能是一个不错的选择。底线是理解模型的假设和限制以及它们在不同技术中的变化是很重要的。

我首先将数据分为训练集和测试集,以确保对模型进行公正的评估。然后,我实例化模型并拟合数据:

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

**图 11。**演示训练测试分割和模型拟合的代码。

一旦模型被拟合,我就使用测试数据将模型输出与期望值进行比较。完全直线表示完美的模型:

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

**图 12。**展示模型输出与真实数据的散点图。

除了一些显著的异常值,该模型在准确预测方面做得很好。根据模型的用例,可能值得进一步调查数据,以确定这些异常值来自哪里,以及如何减轻它们以提高模型的准确性。在我的情况下,这个模型就足够了。我甚至可以通过计算模型的 R 平方值来量化“拟合优度”:

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

图 13。 R 平方值为 0.91。

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

**图 14。**残差图。

r 平方是自变量中可预测的因变量方差的比例。以百分比表示,任何给定脉冲的估计反应性的 91%的变化可以用我们的输入值来解释。要点是,这是一个非常适合我们目的的模型。也就是说,我还可以再做一次检查来了解这个模型。图 14 左边是残差直方图,或任何给定数据点和最佳拟合回归线之间的距离。该图表明,随机误差在零附近呈正态分布,这很好。如果不是这样,那么我们的模型和/或数据集可能有问题。同样也有值得注意的异常值,但当用我们令人印象深刻的 R 平方分数来支持时,没什么可担心的。

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

**图 15。**慢动作记录的脉冲(最初为 240fps)。来源:我(沃克·佩恩)

结论(和局限性)

有了这个模型,我现在可以根据控制棒位置和棒价值等反应堆参数准确预测脉冲反应性值。可重复性对于所有类型的实验都很重要,这个模型将有助于收紧我们的脉冲值,并确保每个受辐射的组件都有相似的辐射暴露。

注意:该模型确实有一些限制,这些限制对于那些具有反应器动力学和操作知识的人来说可能是显而易见的。也就是说,模型不知道以前的操作和极其重要的裂变产物毒物的积累。随着反应堆的运行,氙-135 随着时间的推移而产生(并被烧掉),并显著影响中子吸收和反应堆行为。

编辑:在脉冲前用全新的数据测试模型后,预测的反应性与反应堆控制台计算的“真实”反应性相差不到 3%。成功!

如果你喜欢这篇文章,请随意看看我的其他文章,并在评论中告诉我你的想法。感谢阅读!

应用机器学习评估佛罗里达气候驱动的房地产风险(上)

原文:https://towardsdatascience.com/applying-machine-learning-to-assess-floridas-climate-driven-real-estate-risk-part1-60e9a8913b85?source=collection_archive---------39-----------------------

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

图片由作者创作,灵感来源:https://sealevelrise.org/states/florida/:自 1950 年以来,佛罗里达群岛周围的海平面已经上升了 8 英寸。它的上升速度在过去的十年里加快了,现在每三年上升一英寸。科学家们知道这一点,因为海平面每 6 分钟测量一次,使用卫星、沿海浮动浮标和验潮仪等设备来精确测量当地海平面的加速和变化

佛罗里达州短暂的气候变化沙皇,首席恢复官 Julia Nesheiwat,为该州设定了一个明确的优先事项:保护房地产市场。

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

图片来源: JNW21 885,CC BY-SA 4.0https://creativecommons.org/licenses/by-sa/4.0通过维基共享

Nesheiwat 2020 年 1 月的[未发表的]报告 T11 载有旨在保持佛罗里达州最重要的产业房地产的提案。

她的计划提出了更严格的建筑法规,但也提出了更具争议的措施,如向购房者披露洪水风险,提供国家资助的房屋收购,并要求对城市和县进行脆弱性研究。

“佛罗里达州的沿海社区和地区没有时间可以浪费,需要一个最高级别的合作伙伴来帮助管理和应对迫在眉睫的威胁,”Nesheiwat 写道。

麦肯锡的一项案例研究呼应了 Nesheiwat 对该州大部分地区的可怕预测,包括佛罗里达群岛,但也包括亚特兰蒂斯北部的许多沿海地区。

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

佛罗里达州维罗海滩的住宅。水下海堤和码头,以及海水浸泡的草坪已经变得司空见惯

“在近三个月的时间里,斯蒂尔赖特角(Florida Keys neighborhood)215 个家庭的居民被迫仔细计划他们的出游,并找到临时的变通办法来处理难闻的死水——这不是因为下雨,而是因为海平面上升——这使他们的红树林街道看起来更像运河。”— 《纽约时报》

麦肯锡报告的作者说,他们估计潮汐洪水频率的预计增加可能导致暴露的房地产在 2030 年贬值 100-300 亿美元,到 2050 年贬值 300-800 亿美元。他们说,到 2050 年,受影响房屋的平均影响预计将增加 15-35%,高于今天的 5%。

“这是一个保守的估计”,麦肯锡全球研究所高级研究员,案例研究的合著者 Mekala Krishnan 说。

根据像麦肯锡这样的报告,普遍的看法似乎是,买家会慢慢地意识到易受洪水影响的房产是糟糕的投资 ,而不是一下子放弃受灾严重的地区,如果飓风在与飓风季节重叠的秋季大潮季节袭击,这很容易发生。

“佛罗里达的抵押贷款和市场会继续运转吗?”— 克里希南说 ,前提是该邦 确实做了Nesheiwat 的气候报告中建议的那种事情。

“如果我们这样做了,我认为风险是可以控制的,”她说。但这并不意味着该州的每一个口袋都会成功。

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

图片由作者创作,灵感来源:https://sealevelrise.org/states/florida/

数据集和机器学习方法

有许多优秀的媒体文章概述了如何将 ML 应用于房地产估价,因此为了提供原创内容,本文的剩余部分将探索一种新的方法,使用一个前所未见的房地产数据集。这样做的目的是确认或否认南佛罗里达房地产价格已经受到海平面上升(SLR)驱动的气候风险的打击。

“我们的结果表明,佛罗里达州沿海房地产出现了脱节:从 2013 年到 2018 年,受海平面上升(SLR)影响最大的社区的房屋销量相对于受 SLR 影响较小的地区下降了 16%至 20%,尽管它们的销售价格同步增长。然而,在 2018—2020 年间,这些风险市场的相对价格最终比峰值下降了约 5%。贷款人的行为无法调和这些模式,因为我们表明,全现金和抵押贷款融资的购买都出现了类似的收缩,几乎没有证据表明贷款拒绝或证券化有所增加。”—国家经济研究局最近发表报告

我们想要预测的目标是“给定物业的物业价值变化率与附近类似物业的变化率的差异”。理论上,对于具有高度差异的属性,我们应该发现这种差异的很大一部分可以用洪水风险来解释。

为了计算目标值,我们将使用以下等式:

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

简而言之,我们希望预测每项资产与其相邻资产(可比资产)之间的价格变化率差异。

上述等式实际上可以用以下等式实现:

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

在数据集中,大约 66%的物业具有较低的洪水风险(在洪水因子评分表上小于 5 分),大约。33%有很高的洪水风险。

我们将通过构建一个 ML 模型,然后对其应用各种模型解释工具(如要素重要性和 SHAP ),来测试高洪水风险分数是财产价值变化率差异的强预测因素这一假设。

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

使用 EvalML AutoML 库,突出训练有素的 XGBOOST 管道的重要性。作者图片

本博客使用的所有代码和数据都可以在 github 上获得,这里

收集数据

除了标准的房地产功能,如卧室,浴室,面积等。,数据还包括:

  • 每个酒店 3 张图片(也包含在 Github repo 中)
  • 2 份公布的洪水风险评级,一份来自联邦应急管理局,一份来自第一街的洪水评分
  • 截至 2021 年 2 月(上周)的第三周,每处房产均在 realtor.com 挂牌出售,并公布了要价
  • 每处房产都附有最匹配的 Zillow 房屋价值指数 ZHVI(根据邮政编码+卧室数量进行汇总和合并),从而得出附近房屋的月度时间序列指数价格,可追溯到 1996 年
  • 此外,许多其他公共数据集,如相关地区的人口普查数据,都被附加到每个属性中

该数据集包括 1600 多处南佛罗里达房地产的记录,每处都有 650 多列,还包括洪水风险信息、人口统计信息、列表图像、列表描述、房地产上市时间、销售历史以及许多其他相关信息。

要素的推断数据类型

加载属性数据

在建立模型之前,我们需要清理原始数据。因为清理所有东西很费时间,所以我们在这里做一个“快速通过”,但是为了获得更多的训练数据,还会有额外的数据需要清理。请随时这样做,并提供一个链接!

import pandas as pd
import evalml
from evalml.preprocessing import load_dataproperty_data = pd.read_csv('../data/raw/property.csv').reset_index() 

加载人口统计数据

geo codeio提供了一些数据集,我们可以轻松地将其添加到我们的酒店数据中,以供其他研究和使用:

  • The US Census Bureau
  • Local city, county, and state datasets from OpenAddresses
  • OpenStreetMap
  • GeoNames
  • CanVecPlus by Natural Resources Canada
  • StatCan
  • Legislator information from the UnitedStates project on GitHub
demographics_data = pd.read_csv('../data/raw/demographics.csv', low_memory=False).reset_index()

合并数据

数据已经过预排序和重新索引,因此我们可以简单地根据索引 id 进行合并。

merged = pd.merge(property_data, demographics_data, on='index')

注意单词sqft包含在列Area中,因此我们将识别所有包含sqft的行,忽略不包含的行。注意:不包含sqft的行将需要在单独的工作流中进行清理。就目前而言,我们将只关注清理大部分数据,稍后我们可以回来清理那些掉队的数据。

word = 'sqft'
new_df = merged[merged["Area"].str.contains(word) == True]

其他立柱需要类似的清洁,例如BedsFloodInfoYearBuilt

word = 'bed'
new_df = new_df[new_df["Beds"].str.contains(word) == True]word = 'Year Built'
new_df = new_df[new_df["YearBuilt"].str.contains(word) == True]word = 'Flood Factor'
new_df = new_df[new_df["FloodInfo"].str.contains(word) == True]

Style栏完全是一团乱麻,因为许多/大部分列表都不包含这些信息。现在,我们将简单地放弃它,以节省解析混乱的时间。

new_df = new_df.drop('Style',axis=1)

使用特征工具加速数据清理。

Featuretools 库有一些很棒的数据清理工具,我们将使用它们来节省时间。具体来说:

  • remove_low_information_features:仅保留至少有两个唯一值且不全为空的特征
  • remove_highly_null_features:从特征矩阵中删除高于空值阈值的列。
  • remove_single_value_features:删除特征矩阵中所有值都相同的列…
  • remove_highly_correlated_features:删除特征矩阵中与另一列高度相关的列。
from featuretools.selection import remove_low_information_features, remove_highly_null_features, remove_single_value_features, remove_highly_correlated_featuresdf = new_df.copy()"""Select features that have at least 2 unique values and that are not all null"""df_t = remove_low_information_features(df)"""Removes columns from a feature matrix that have higher than a set threshold"""df_t = remove_highly_null_features(df_t)"""Removes columns in feature matrix where all the values are the same."""df_t = remove_single_value_features(df_t)"""Removes columns in feature matrix that are highly correlated with another column."""df_t = remove_highly_correlated_features(df_t)

清理洪水风险数据

Flood Risk Data是这项研究的一个突出特点,所以我们想稍微清理一下格式。

df_t[['FemaInfo','FloodFactorInfo']] = df_t.FloodInfo.str.split(' • ', expand=True) 
df_t['FloodFactorInfo'] = df_t['FloodFactorInfo'].astype(str).str.replace('/10 New','').str.replace('Flood Factor ','')
df_t['FemaInfo'] = df_t['FemaInfo'].astype(str).str.replace('FEMA Zone ','').str.replace('(est.)','')

清理数字特征

我们不能重新格式化像AreaBathsYear BuiltDays on Realtor.com这样的东西,只要它们包含文本字符,所以我们需要删除它们以便正确地格式化数据集来训练我们的模型。

df_t['Beds'] = df_t['Beds'].str.replace('bed','')
df_t['Baths'] = df_t['Baths'].str.replace('bath','')
df_t['Noise'] = df_t['Noise'].str.replace('Noise:','')
df_t['PropertyType'] = df_t['PropertyType'].str.replace('Property Type','')
df_t['DaysOnRealtor'] = df_t['DaysOnRealtor'].str.replace('Days on Realtor.com','').str.replace('Days','')
df_t['Area'] = df_t['Area'].str.replace('sqft','').str.replace(',','')
df_t['Price'] = df_t['Price'].str.replace('$','').str.replace(',','').str.replace(',','')
df_t['PricePerSQFT'] = df_t['PricePerSQFT'].astype(str).str.replace(',','')
df_t['YearBuilt'] = df_t['YearBuilt'].astype(str).str.replace('Year Built','')

拆分LastSoldAmtLastSoldYear功能

这些列一起包含在抓取的数据中,因此我们需要相应地将它们分开,以便正确地将它们格式化为模型特征。

df_t[['LastSoldAmt','LastSoldYear']] = df_t.LastSold.str.split(' in ', expand=True) 

清理LastSoldAmt

LastSoldAmt数据使用文本字符来表示千和百万,然而,为了我们的目的,我们需要用它们的数字亲属来替换它们。

df_t['LastSoldAmt'] = df_t['LastSoldAmt'].astype(str).str.replace('k','000')
df_t['LastSoldAmt'] = df_t['LastSoldAmt'].astype(str).str.replace('M','000000').str.replace('.','').str.replace('Last Sold','').str.replace('$','').str.replace('000000','0000')

删除不必要的列并保存预处理数据

df_t = df_t.drop('LastSold',axis=1)
df_t = df_t.drop('index',axis=1)
df_t = df_t.reset_index()
drop_cols = [col for col in df_t.columns if 'url' in col.lower() or ' id' in col.lower()]
X_t = df_t
X_t = X_t.drop(drop_cols,axis=1)
t_datapath = '../data/processed/preprocessed.csv'
X_t.to_csv(t_datapath,index=False)

下载属性图像供以后使用

数据集中的每个属性都有 3 个包含图片列表的 URL。虽然这些图像并不直接相关,但我们将在以后的博客文章中使用它们。现在,我们将简单地下载它们。

import requestsdef download_images(indx):
    file_name = str(indx)+'.png'
    urldata = df_t[df_t['index']==indx]
    url1 = df_t['Image_URL'].values[0]
    url2 = df_t['Image_URL1'].values[0]
    url3 = df_t['Image_URL2'].values[0]
    urls = [url1,url2,url3]
    ct=0
    for url in urls:
        response = requests.get(url)
        with open('../data/images/_'+str(ct)+'_'+file_name, "wb") as file:
            file.write(response.content)
            file.close()
        ct+=1

df_t['index'].apply(download_images)

合并 Zillow 数据

ZHVI 用户指南

Zillow 最常引用的指标之一是 ZHVI,Zillow 房屋价值指数。它告诉我们在给定的地理区域(大城市,城市,邮政编码等)典型的房屋价值。),现在和将来,针对特定的资产类型和规模。关于 ZHVI 的一般信息,请参考这个方法指南和这个轻松的视频。

我们将合并所创建的键,该键连接了区域邮政编码和zipbeds中的房产卧室数量:

zillow1beds = pd.read_csv('../data/raw/zillow1bed.csv')
zillow1beds['zipbeds'] = zillow1beds['RegionName'].astype(str)+'_'+str(1)zillow2beds = pd.read_csv('../data/raw/zillow2bed.csv')
zillow2beds['zipbeds'] = zillow2beds['RegionName'].astype(str)+'_'+str(2)zillow3beds = pd.read_csv('../data/raw/zillow3bed.csv')
zillow3beds['zipbeds'] = zillow3beds['RegionName'].astype(str)+'_'+str(3)zillow4beds = pd.read_csv('../data/raw/zillow4bed.csv')
zillow4beds['zipbeds'] = zillow4beds['RegionName'].astype(str)+'_'+str(4)zillow5beds = pd.read_csv('../data/raw/zillow5bed.csv')
zillow5beds['zipbeds'] = zillow5beds['RegionName'].astype(str)+'_'+str(5)zillowdata = pd.concat([zillow1beds, zillow2beds, zillow3beds, zillow4beds, zillow5beds])# load preprocessed data
t_datapath = '../data/processed/preprocessed.csv'target = 'Price'#set to None for production / actual use, set lower for testing
n_rows=None#set the index
index='index'X, y = load_data(t_datapath, index=index, target=target, n_rows=n_rows)y = y.reset_index().drop('index',axis=1).reset_index()[target]
X_t = X.reset_index().drop('index',axis=1).reset_index()
X_t[target]=ydf_t['LastSoldDate'] = '1/31/' + df_t['LastSoldYear'].astype(str).str[2:4]
df_t['zipbeds'] = df_t['Zip'].astype(str).str.replace('zip_','')+'_'+df_t['Beds'].astype(str)
zipbeds = list(set(df_t['zipbeds'].values))
zillowdata['zipbeds'] = zillowdata['zipbeds'].astype(str)
df_t['zipbeds'] = df_t['zipbeds'].astype(str)Number of Features
Categorical                  60
Numeric                     640Number of training examples: 1071
Targets
325000     1.49%
450000     1.21%
350000     1.21%
339000     0.93%
349900     0.84%
           ...  
245000     0.09%
5750000    0.09%
74995      0.09%
2379000    0.09%
256000     0.09%
Name: Price, Length: 567, dtype: object Columns (5,9,23,700) have mixed types.Specify dtype option on import or set low_memory=False.df_t = pd.merge(df_t, zillowdata, on='zipbeds')

计算每个属性的变化率及其comparables

在房地产中,comparable是附近具有相似特征的房产,例如相同数量的卧室。在我们的案例中,对于我们在zipbeds合并的每一处房产,我们希望训练一个模型来预测价格变化率与附近可比价格变化率之间的差异。为此,我们将找到目标资产的LastSoldDate列,并查找从该日期到现在相应的 ZHVI 变化率。

X_t = df_t.copy()time_series_cols = [col for col in X_t.columns if '/' in col and 'Percentage' not in col and 'Value' not in col and 'Margin of error' not in col and 'Metro' not in col and col != '1/31/21']l = []
for ct in range(len(X_t)):
    try:
        indx = X_t['index'].values[ct]
        last_sold_date = X_t['LastSoldDate'].values[ct]
        zillow_price = X_t[last_sold_date].values[ct]
        X_ts = X_t[X_t['index']==indx]
        X_ts['zillow_price'] = zillow_price
        X_ts['zillow_price_change'] = X_ts['1/31/21'].astype(float) - X_ts['zillow_price'].astype(float)
        X_ts['zillow_price_change_rate'] = X_ts['zillow_price_change'].astype(float) / float(2021.0 - X_ts['LastSoldYear'].astype(float))
        X_ts['zillow_price_change_percent'] = X_ts['zillow_price_change'].astype(float) / X_ts['zillow_price'].astype(float)
        l.append(X_ts)
    except: pass

df = pd.concat(l)df['last_sold_price_change'] = df['Price'].astype(float) - df['LastSoldAmt'].astype(float)
df['last_sold_price_change_percent'] = (df['Price'].astype(float) - df['LastSoldAmt'].astype(float)) / df['LastSoldAmt'].astype(float)
df['last_sold_price_change_rate'] = df['last_sold_price_change'].astype(float) / float(2021.0 - X_ts['LastSoldYear'].astype(float))
df['yearly_price_delta'] = df['last_sold_price_change_rate'].astype(float) - df['zillow_price_change_rate'].astype(float)

定义我们将训练模型预测的目标变量。

对于我们最初的博客条目,我们将使用特性yearly_price_delta_percent作为我们的目标变量。其定义如下:

df['yearly_price_delta_percent'] = df['last_sold_price_change_percent'].astype(float) -  df['zillow_price_change_percent'].astype(float)

最终清理和保存

在一些数字列中还有一些零散的文本字符,所以请删除它们,然后保存。

df = df.drop(time_series_cols, axis=1)
df =df[df['LastSoldAmt'] != 'Property TypeTownhome']
df = df[df['LastSoldAmt'] != 'Property TypeSingle Family Home']
df.to_csv('../data/processed/zillow_merged.csv',index=False)

使用 AutoML 进行基准测试

虽然原始数据集要大得多,但出于本文的目的,我们将重点关注较小的要素样本。

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

作者图片

在深入研究 ColorFrame 之前,有必要使用传统的表格建模算法(如 XGBOOST)获得目标数据可预测性的基线,以便我们可以比较 color frame 的性能。但是我们的目标特征是什么呢?

记住,为了计算目标值,我们使用以下等式:

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

简而言之,我们希望预测每项资产与其相邻资产(可比资产)之间的价格变化率。

上述等式实际上可以用以下等式实现:

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

国家经济研究局最近发表了一份报告,我们将用它作为规划我们的方法的起点和参考。可以肯定的是,这里的目的是从一个非常普遍的意义上看他们做了什么,而不是重复他们的研究。我们的研究将使用完全不同的方法和数据。**

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

佛罗里达邮政编码。图片由作者创作,灵感来自来源

假设

我们的假设是,如果确实存在与高洪水风险相关联的强大/重要的价格影响,那么公布的洪水风险评级/分数,例如第一街的洪水因素,应该是高洪水风险房产的最重要的预测特征之一。

为了测试这个假设,我们开始使用 EvalML 的 AutoML 特性构建一个基本的管道。

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

通过 EvalML 进行 AutoML。作者图片

特征重要性

*best_pipeline.feature_importance*

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

功能重要性。作者图片

我们可以获得与最终管道的每个特征相关联的重要性。

很容易看出,正如所料,第一街的洪水因子分数实际上显示在最重要的要素顶部附近!哇!

我们还可以计算和绘制管线的排列重要性

*from evalml.model_understanding.graphs import graph_permutation_importance
graph_permutation_importance(best_pipeline, X_holdout, y_holdout, 'MAE')*

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

排列重要性。作者图片

解释排列的重要性

“排列特征重要性是一种模型检验技术,当数据为表格形式时,可用于任何符合 估计器。这对于非线性或不透明的估计器尤其有用。置换特征重要性被定义为当单个特征值被随机打乱 1 时模型得分的减少。该过程打破了特征和目标之间的关系,因此模型分数的下降指示了模型对特征的依赖程度。这种技术受益于模型不可知,并且可以用特征的不同排列进行多次计算。”— sklearn

在解释排列的重要性时,顶部的值被认为是最重要的特征,底部的值最不重要,这些值表明每个特征的随机排列会降低多少模型性能(在这种情况下,使用“平均绝对误差”作为性能度量)。

在上图中,我们立即看到了 FloodFactorInfo 特性的负值。虽然这可能意味着我们在上面看到的高特征重要性只不过是随机的,但重要的是要注意排列重要性非常容易受到特征相关性的影响。

为了解决相关性干扰的可能性,让我们用布尔类型的FloodFactorHigh=True/False替换FloodFactorInfo_flood_factor_high/low特性。让我们也放弃FemaInfo功能,因为它可能会干扰FloodFactorHigh。然后,让我们进行相关性研究,以消除任何其他潜在的冲突。

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

使用木工数据表的 mutual_information()工具进行特征关联研究。作者图片

在上面的相关性表中,我们可以看到一些要素的相关性超过 50%,因此,要深入了解排列图中发生的情况,让我们尝试移除 City_x 和 County,这应该会移除所有大于 50%的相关性。

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

移除 City_x 和 County 要素后,修改了要素的重要性,以降低要素之间的相关性。作者图片

我们可以在修改后的特征重要性图表中看到,FloodFactorHigh成为 XGBOOST 模型中最重要的特征,但是排列重要性呢?

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

移除 City_x 和 County 要素后,修改了排列重要性,以降低要素之间的相关性。作者图片

在修改后的排列图中,我们可以看到虽然FloodFactorHigh仍然接近底部,但它不再是负的,这比之前的情况有所改善。现在,最重要的排列是Area后接Longitude.,这个结果看起来至少是合理的,但就个人偏好而言,我倾向于避免过度依赖排列,因为它对特征相关性非常敏感,在处理房地产特征时,这在很大程度上是不可避免的,尤其是在使用较小的数据样本时。

让我们转向 SHAP 图书馆,看看我们是否能获得关于我们的模型及其特性重要性的任何其他见解…

带有 TreeExplainer 的树集成示例(XGBoost/light GBM/CatBoost/scikit-learn/py spark 模型)

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

图片来源: SHAP

SHAP 可以解释任何机器学习模型的输出,它的超快速 C++实现支持 XGBoost,LightGBM,CatBoost,scikit-learn 和 pyspark tree 模型,所以让我们试试吧:

*import xgboost
import shap# load JS visualization code to notebook
shap.initjs()# train XGBoost model
model = xgboost.train(best_pipeline.parameters['XGBoost Regressor'], xgboost.DMatrix(X_ttrain, label=y_train.to_series()))# explain the model's predictions using SHAP
# (same syntax works for LightGBM, CatBoost, scikit-learn and spark models)
explainer = shap.TreeExplainer(model)
shap_values = explainer.shap_values(X_ttest)*

现在我们已经创建了解释器对象,让我们制作一些可解释的情节…

*# visualize the first prediction's explanation (use matplotlib=True to avoid Javascript)
shap.force_plot(explainer.expected_value, shap_values[0:1], X_ttest.iloc[0:1])*

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

SHAP 情节。作者图片

上面的解释显示了将模型输出从基础值(我们传递的训练数据集的平均模型输出)推送到模型输出的每个功能。将预测推高的特征显示为红色,将预测推低的特征显示为蓝色(关于力图的细节可以在这里找到:自然 BME 论文)。

*# visualize the test set predictions
shap.force_plot(explainer.expected_value, shap_values, X_ttest)*

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

SHAP 情节。作者图片

为了了解哪些特征对模型最重要,我们可以绘制每个样本的每个特征的 SHAP 值。下图按所有样本的 SHAP 量值总和对要素进行排序,并使用 SHAP 值显示每个要素对模型输出的影响分布。颜色代表特征值(红色高,蓝色低)。例如,这表明高FloodFactorInfo_flood_factor_high会增加目标房屋和 Zillow 房屋价值指数之间的预测价格差异。

*# summarize the effects of all the features
shap.summary_plot(shap_values, X_ttest)*

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

SHAP 情节。作者图片

要了解单个要素如何影响模型的输出,我们可以绘制该要素的 SHAP 值与数据集中所有示例的要素值的关系。由于 SHAP 值表示要素对模型输出变化的责任,因此下图表示随着DaysOnRealtor.com的变化,预测房价的变化。单一值DaysOnRealtor.com的垂直离差表示与其他特征的相互作用效应,在本例中为FloodFactorInfo_flood_factor_high

*shap.dependence_plot("DaysOnRealtor.com", shap_values, X_ttest, 
                     interaction_index="FloodFactorInfo_flood_factor_high"
                    )*

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

SHAP 情节。作者图片

关键要点

  1. ****flood factor info功能是预测给定资产与其可比资产之间价格变化率差异的最重要功能之一。这种重要性意味着佛罗里达房地产价格已经受到气候变化风险的影响。
  2. ****因为用于计算 FloodFactorInfo 特征的方法特定于每个物业,而 FEMA 洪水等级则不是,因此 FEMA 洪水等级的预测性较低是有道理的。请注意,联邦应急管理局计划大约在 2014 年发布第一个变更。50 年后的 2021 年秋天,对未来有什么想法?
  3. ****FloodFactorInfo 特征是否有其他可能的关联,可以间接解释这些结果,比如靠近海洋或运河?因为我们已经包含了纬度+经度和其他位置感知功能,所以我们认为这些功能几乎同样重要,如果是这样的话。

最后的想法

更多使用该数据集的相关帖子即将发布!留意使用 彩色框架 的额外分析,这是一种受 SuperTML……启发的新颖的计算机视觉方法

房地产投资者一定要注意这一点和相关的研究结果。在大多数情况下,投资者会根据当地的发展趋势来考虑位置、当前资产估值和潜在上涨空间等因素。但是,越来越多的精明投资者开始分析环境事件和影响,这些类型的考虑正在迅速正式成为标准,如由气候相关财务信息披露(TCFD)任务组(T8)提出的标准。重要的是要意识到这些变化和事件对房地产投资的影响。

海平面上升和野火等气候风险对住宅和商业建筑构成重大威胁,并对房地产估价产生负面影响。除了造成财产损失,气候事件还会导致昂贵的保险、维护和运营成本。在最坏的情况下,自然灾害可能导致完全的财产损失和破产的保险供应商。令人欣慰的是,在整个房地产投资行业,围绕气候风险的意识似乎有所增强。

识别气候风险的最佳实践

如果还没有,投资者和投资经理需要实施切实可行的策略来应对气候风险的潜在影响。当考虑在投资组合中增加新资产时,谨慎的做法是探索任何形式的气候风险敞口。积极主动的投资者已经在分析堆积如山的气候数据和其他可用信息,以做出最明智的决策,他们将成为明天的赢家。这里有一些要点可以帮助指导房地产投资决策:

将评估气候风险的流程正式化,作为您更广泛的投资决策的一部分。

自学缓解和适应策略(更高的海堤、暖通空调、更高的海拔等)。).

联系您的保险提供商,了解他们的未来计划。

旨在应对气候风险的研究法规。

气候风险不应该让房地产投资者感到恐惧,但在现在和可预见的未来,它们应该是一个考虑因素。

将机器学习应用于井字游戏

原文:https://towardsdatascience.com/applying-machine-learning-to-tic-tac-toe-47d954671c73?source=collection_archive---------20-----------------------

我创建了一个程序,通过一段时间的模拟来学习如何玩井字游戏

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

图片由作者提供

简介:

在制作了一个可以玩 Connect 4 的 MATLAB 程序后,我决定下一步是设计一个可以学习如何玩井字游戏的程序。毕竟它只是 Connect 4 的简化版,所以机器学习的时间应该会更少,并增加它的胜率。

井字游戏机 V1.0

它始于两个完全随机的井字游戏发生器互相游戏。一个游戏结束后,其中一台机器从游戏中收集所有决策数据,并将其放入数据库。如果这步棋赢了,这步棋得 3 分。如果移动导致损失,它失去 1 点。平局比赛的结果是加 1 分。在 100,000 场游戏中,每一个独特的场景都记录在它的数据库中,以及它在那之后选择的移动。在下一局游戏中,得分较高的棋更有可能被选中,而得分较低的棋则不太可能被选中。

这个想法是,在几千场比赛中,赢或平的棋会得到更多的分数,更有可能被选中。由此产生了一个包含 2000 多种独特游戏场景的数据库,每一步都有不同的权重。下面是 100,000 场比赛中数据库中独特场景的总量图。

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

图片由作者提供

正如你所看到的,数量收敛于值 2,423,在这一点上,机器开始看到重复出现的场景,并为 9 个可能的移动中的每一个调整权重。

但是在 10 万场比赛中,TTT-M1 的胜率如何呢?下面左边是所有模拟的总胜率,右边是前几千个游戏的放大部分。

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

图片由作者提供

由于 TTT-M1 和它的随机移动对手都是在对游戏一无所知的情况下开始的,所以在前 2000 场游戏中,胜率波动很大。到了某个时候,它开始下沉,形成一条平滑的线,随着时间的推移慢慢增加。这是因为机器现在已经看到了所有可能的场景,并且现在正在细化每个移动的权重。

正是在这一点上,我认为我有一个完整的项目。任何人都不可能打败一台有 10 万次井字游戏经验的机器。嗯,我想错了。

事实证明,虽然 100,000 场游戏很多,但当它与随机移动生成器对战时,它真的没有任何意义。一个真实的人是有直觉的,这是我的机器的对手没有的。因此,击败这台机器是相当容易的,或者至少打平它。这并不意味着机器在阻挡它的对手时没有学到一些技术。它肯定做出了明智的决定,只是没有考虑到一个具有良好逻辑的人类对手。

井字游戏机 V2.0

解决这个问题的方法很简单。让另一台机器在没有任何游戏逻辑的情况下启动,并让它面对我的井字游戏机器 1.0 版(TTT-M1)。使用与以前相同的代码,这台新机器(TTT-M2)将学习超过 150,000 场如何玩井字游戏,但它将学习如何对抗具有相当技能的对手。理论上,TTT-M2 应该比 TTT-M1 更聪明,因为它有成千上万场比赛来暴露它的弱点,同时还能制定新的策略。

我感兴趣的一个特殊情况是第一步决策。TTT-M1 率先行动,我预计它会集中在中间位置,这是最好的。事实上,它更喜欢角落,因为它是起点。这给第二个玩家留下了空档,导致 TTT-M1 输掉了很多对真人的比赛。我想看看 TTT-M2 是否会抓住这个弱点,如果轮到它了,就开始瞄准中间的位置。

以下是 TTT-M2 对 TTT-M1 的学习率:

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

图片由作者提供

正如你所看到的,胜率开始时非常低,因为它面对的是一个有一些游戏知识的对手。随着模拟的进行,它了解了 TTT-M1 的弱点,直到它收敛到 0.50 左右的胜率。考虑到它没有第一步棋,这是非常好的。

它还了解到,如果 TTT-M1 在第一步没有采取中间路线,那么它应该采取它。这证明了一个众所周知的事实,即在井字游戏中,中间点是最好的位置。

现在我有了一个像样的对手,我开发了 TTT-M3。

井字游戏机 3.0 版

我的井字游戏机器学习项目的最终演变是 TTT-M3。这台机器在 150,000 场比赛中对阵 TTT-M2,学习最佳策略,同时也在最佳数据库中找到当前的漏洞。经过 150,000 场比赛,结果如下:

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

图片由作者提供

这说明这个井字游戏机器学习项目的最后一代一开始非常弱。在最初的 1000 场比赛中,它的胜率徘徊在 25%左右,但后来开始腾飞,达到了 74%左右。这是对一个同样有井字游戏逻辑的对手(TTT-M2)。下面是我和 TTT-M3 博弈的一个例子(“2”是 TTT-M3 的棋,“1”是我的棋):

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

图片由作者提供

我马上注意到它已经发展出一种策略来引诱我选择中心点。一旦我这样做了,每次都是平局,在计算机看来,这是一个好结果。

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

图片由作者提供

我扮演了中间的角色,落入了圈套。然后,它设置我采取左上角。

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

图片由作者提供

在顶上挡住它的水平尝试后,它又把我放在最右边的一栏。

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

图片由作者提供

这是第二排第一列的下一步棋,决定了这场比赛的命运。

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

图片由作者提供

结论:

经过 3 代的进化,这个程序已经发展出一种策略来建立联系,阻止对手,并争取胜利。总的来说,这个项目是成功的,因为创建了一个程序,可以学习新的技能,并在与其他对手玩井字游戏时变得更好。

如果你对这类内容感兴趣,我有一些基于棋盘游戏和数据科学的文章:

强化学习在自动驾驶汽车中的应用

原文:https://towardsdatascience.com/applying-of-reinforcement-learning-for-self-driving-cars-8fd87b255b81?source=collection_archive---------7-----------------------

马尔可夫决策过程(MDP)和寻找自动驾驶发展的整体政策

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

Denys Nevozhai 在 Unsplash 上拍摄的照片

自动驾驶汽车的人工智能应用的一种广泛方法是监督学习方法,最重要的是,用于解决感知要求。但是自动驾驶汽车在强化学习(RL)方法中非常类似于机器人和代理。我们能用强化学习方法代替监督学习方法吗?监督方法的缺点是,从数据收集到模型部署,整个人工智能过程都存在人为偏见。

与环境互动是自动驾驶汽车最重要的任务。感知是第一步,目前是基于人工智能的,并应用了监督的方法。在这种方法中,**你需要考虑车辆是在一个开放的情境环境中行驶,你需要用现实世界中所有可能的场景和情景来训练你的模型。**场景和场景的多样性是特斯拉、Waymo、Cruise 必须通过收集越来越多的数据,并根据收集到的数据验证系统运行来解决的主要困难。如何确保自动驾驶汽车已经学习了所有可能的场景,并安全地掌握了每一种情况?

强化学习

强化学习可以解决这个问题。**RL 方法意味着代理收集环境信息,并基于定义的策略从一个状态切换到下一个状态,以最大化回报。**智能体作为自动驾驶汽车的大脑,采取哪些行动?简单来说,加速、减速和转向这三个动作是影响车辆动力学和道路安全的最关键动作。最危险的决定是转向,最不关键的决定是刹车。我们如何在强化学习过程中为作为驾驶员的代理定义一个策略和一个奖励函数?

奖励函数

为了定义奖励函数,我们可以考虑各种方面,例如功耗、所有道路使用者的安全,或者更快到达目的地且仍然安全驾驶的最佳导航方式。我们应该区分安全驾驶等短期奖励和提前到达目的地等长期奖励。一个智能体,在这种情况下,一辆自动驾驶汽车,需要监控环境,并意识到哪个新状态可以获得最大回报,例如加速、减速或转向,以及所有其他相关参数和变量。

社会不接受自动驾驶汽车过于缓慢和保守的驾驶或频繁制动。有两种应对安全关键事件的解决方案。一个是回到旧的安全状态,第二个是寻找新的“安全状态”由于不清楚较早的“安全状态”是否仍然安全,因此找到新的“安全状态”是唯一可靠的解决方案,而较旧的安全状态是所有其他可能情况中的一个解决方案。然而,如果一个代理决定回复到过去的状态,这个代理将需要一个新的奖励评估,而现有的奖励将不再有效。

挑战将是找到与其他代理活动并行执行新的奖励评估的时间间隔。奖励随时间变化,取决于情况和驾驶动态。**一般来说,在道路交通中与其他车辆保持安全距离可以获得较高的奖励值。**这个论证类似于不必要的刹车缩短了跟在自动驾驶汽车后面的汽车的距离。

环境监测

自动驾驶汽车通过车载传感器收集相关的环境信息,如道路或交通标志的类型,或者从其他车辆或基础设施远程接收这些信息。自动驾驶汽车的所有必要信息都可以测量吗?不,不是全部,至少没有驾驶风格等历史数据。如何衡量自动驾驶汽车在混合交通道路或其他自动驾驶车辆上是否与其他驾驶员配合?

在设计任何基于强化学习方法的自动驾驶智能体之前,我们必须回答这些问题。社会不会接受代理人长期不合作,我们需要衡量和控制这种行为。

使用监督学习进行环境监测似乎仍然是正确的解决方案。我们需要通过分离感知部分和决策部分来降低代理决策的复杂性。由环境传感器收集的所有数据都应被标记并与适当的策略相关联,以促进强化学习设计过程。

为代理选择策略

由于许多可能的情况,为作为自动车辆的代理选择优化的策略是复杂的。代理应该根据流量情况解决不同的问题,并根据这种情况找到适当的响应或策略。如果有多个有效策略,代理应灵活地在其他合适的策略之间切换,或者组合多个策略来计算以下可能状态的奖励。

如本论文、**中所述,找到最佳策略的一个可能解决方案是使用有经验的驾驶员的行为和相关分布作为参考,并尝试通过代理再现这种行为。**然而,本文分析了一个特殊的场景,即具有深度强化学习的类人驾驶的“静态避障”,需要讨论如何将其扩展到所有可能的场景。

另一个解决方案是分层方法,正如在这篇论文中所描述的。选择支持的机动动作,例如在车道内行驶,换到右侧车道,换到左侧车道。每个机动都有它的策略和状态,应该单独训练,并且应该有一个主策略来选择正确的机动。该解决方案描述了一个多代理 RL,在任何单个时间点只有一个代理是活动的,我们需要额外的智能在所有代理之间切换。

然而,机动动作的分离并没有解决自动驾驶的复杂性,因为我们还必须证明,所有的机动动作,包括所有的变化,都已经在设计和测试过程中考虑到了,并且机动动作之间的切换也是安全进行的。因此,这种方法不太可能提供一种完全自动驾驶的汽车,在每种情况和场景下进行竞争。

驾驶汽车是一项复杂的任务,需要最低水平的智能来确保安全驾驶,因为我们已经有了关于如何获得驾照的规定。许多参数,如车辆动力学参数如速度、加速度、位置、倾斜度等。以及环境参数影响驾驶策略。一个 操作设计域(奇数) **应该指定影响强化学习方法的参数。**多种驾驶动作只是设计领域中的一个方面,我们需要基于 ODD 考虑所有参数来训练 RL。

https://medium.com/subscribe/@bhbenam

我的推荐页面:https://medium.com/@bhbenam/membership

使用 Python

原文:https://towardsdatascience.com/applying-smote-for-class-imbalance-with-just-a-few-lines-of-code-python-cdf603e58688?source=collection_archive---------3-----------------------

用几行 python 代码实现类平衡

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

https://unsplash.com/photos/-9eNCP979zY

类别不平衡是一个经常出现的问题,表现在欺诈检测、入侵检测、可疑活动检测等等。在二元分类法的上下文中,出现频率较低的类称为少数类,出现频率较高的类称为多数类。你可以在这里查看我们关于同一主题的视频。

这有什么问题?

大多数机器学习模型实际上被多数类淹没了,因为它期望类在某种程度上是平衡的。这就像要求一个学生同样学好代数和三角学,但只给他 5 个已解决的三角学问题,而给他 1000 个已解决的代数问题。少数阶级的模式被埋没了。这实际上变成了从干草堆里找一根针的问题。

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

https://unsplash.com/photos/9Mq_Q-4gs-w

评价也是去折腾,我们更关心的是少数民族类召回而不是别的。

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

根据合意性使用颜色的混淆矩阵

假阳性是可以的,但假阴性是不可接受的。诈骗类作为正类。

本文的目标是实现,理论上的理解可以参考 SMOTE 的详细工作原理这里

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

阶层失衡策略(来源:作者)

当然,最好是有更多的数据,但那也太理想了。在基于采样和基于采样的策略中,SMOTE 属于生成合成样本策略。

步骤 1:创建样本数据集

from sklearn.datasets import make_classification
X, y = make_classification(n_classes=2, class_sep=0.5,
weights=[0.05, 0.95], n_informative=2, n_redundant=0, flip_y=0,
n_features=2, n_clusters_per_class=1, n_samples=1000, random_state=10)

make_classification 是一个非常方便的函数,可以为您创建一些实验数据。这里重要的参数是权重,确保 95%来自一个类,5%来自另一个类。

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

可视化数据(图片来源:作者)

可以理解为红色阶级是多数阶级,蓝色阶级是少数阶级。

步骤 2:创建训练、测试数据集、拟合和评估模型

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

对基于原始不平衡数据训练的测试集模型的评估(图片来源:作者)

这里的主要问题是,当原始不平衡数据用于训练模型时,少数类的召回率非常低。

步骤 3:用合成样本创建数据集

from imblearn.over_sampling import SMOTE
sm = SMOTE(random_state=42)
X_res, y_res = sm.fit_resample(X_train, y_train)

我们可以用三行代码创建一个平衡的数据集

步骤 4:在修改的数据集上拟合和评估模型

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

对在修改的平衡数据上训练的测试集模型的评估(图片来源:作者)

我们可以直接看到,召回从. 21 提升到. 84。这就是三行代码的力量和魅力。

SMOTE 的工作方式是选择一对少数类观测值,然后创建一个位于连接这两个观测值的线上的合成点。选择少数点是相当自由的,最终可能会选择异常的少数点。

ADASYN、BorderLine SMOTE、KMeansSMOTE、SVMSMOTE 是选择更好的少数点的一些策略。

尾注:

类不平衡是一个很常见的问题,如果不处理,会对模型性能产生明显的影响。模型性能对于少数民族阶层尤为关键。

在这篇文章中,我们概述了如何用几行代码,可以像一个奇迹。

引用:

[1]https://www.kaggle.com/saptarsi/smote-notebook

[2]https://machine learning mastery . com/tactics-to-combat-unbalanced-classes-in-your-machine-learning-dataset/

[3]https://www.kaggle.com/qianchao/smote-with-imbalance-data

基于 SVM 的主动学习在多类数据集上的应用

原文:https://towardsdatascience.com/applying-svm-based-active-learning-on-multi-class-datasets-ba6aacdb52d1?source=collection_archive---------18-----------------------

实践教程

基于主动学习和半监督学习的多类分类问题标记策略

在新时代,大量的数据被收集和处理,以提取有价值的信息。同样,机器学习模型也在不断改进,新的方法也在不断提供。显然,基于监督学习的方法对于数据驱动的问题会产生更好的准确性。然而,他们不可或缺地需要每个样品的标签。标签信息对于设计更多的实体模型和获得更好的结果至关重要。不幸的是,这些发展中唯一缺乏的是获得正确的标签信息。给数据加标签通常是一个耗时且令人信服的过程。

主动学习背后的想法是,考虑到标记所有样本是很困难的,找到要标记的最有信息量的样本。因此,通过标记整个样本的一个小子集,模型的准确性可能会显著提高。此时,一个简单的问题出现了。如何从整个集合中选择最具信息性的样本?我提到了一种在多类数据集中决定最有信息量的样本的方法。此外,我将提到一个简单的基于半监督的方法来增加样本集中的标签数量。以及如何在同一数据集中同时利用主动学习和半监督学习。

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

克里斯汀娜·帕普Unsplash 上拍摄的照片

为了揭示最丰富的样本,大多数研究受益于概率方法。在这篇文章中,我使用了基于 SVM 的方法,而不是典型的概率模型。众所周知,支持向量机(SVM)旨在找出 N 维空间中使不同类别点之间的距离最大化的超平面。请看图 1,这是一个只包含两个特征的数据集。SVM 基本上是看着这边的样点来决定上课的。类似地,点到超平面的距离(裕度)是样本属于该类有多强的一种度量。因此,SVM 评论说样品 34 分别属于蓝色和红色类的概率比样品 12 高。

那么,我们如何在主动学习中使用这些信息,换句话说,找出信息量最大的样本?

以简单的方式,靠近超平面的样本比远离超平面的样本更能提供信息。SVM 为离超平面最远的样本做出具有更高置信度的预测。另一方面,越靠近超平面的样本的类别就越不确定。出于这个原因,拥有更接近超平面的样本的基础事实比其他样本更有价值。

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

图 1 —二维空间中的 SVM 描述(图片由作者提供)

但是,对于多类分类问题,就没那么简单了。我使用https://scikit-learn.org/stable/modules/generated/sklearn.multiclass.OneVsRestClassifier.html多类策略,这是多类分类任务最常用的方法之一。原则上,每个分类器的每个类都与 OvR 中的所有其他类相匹配。因此,与其替代的 OneVsOneClassifier(OvO)相比,它的解释相对容易。

作为 OvR 的结果,您期望每个类都有一个预测。为了更清楚,假设我们有 4 个类;a、B、C 和 d。在这样的例子中,您获得 4 个不同的二元分类器结果,它们是

A vs (B,C,D);

B vs (A,C,D);

C vs (A,B,D);

D vs (A,B,C);

同样,这意味着 4 个不同的距离测量,如果你在 OvR 上应用 SVM。距离的符号简单地说明了等级;例如,如果上述示例中第一个分类器的距离(A vs (B,C,D))为正,则分类器返回 class A,如果为负,则返回 not A。

正如所料,1 个正距离测量值和 3 个负距离测量值的组合是最有把握的预测,这是图 2 中的 Sample_4 。OvR 声明样本属于作为 4 个不同分类器的结果的具有正距离值的类别。另一方面,4 个正的或 4 个负的距离测量是不确定预测的例子。在主动学习中,我们对这些最不自信的样本感兴趣。我没有遇到 Sample_5 对应的情况。最有可能的情况是,您遇到像 Sample_1 这样的场景作为最不自信的样本。在样本 _1* 之后,样本 _2 可以被定义为第二大信息量样本。它也代表了一种歧义情况。预测声明 Sample_2 可能是任何 B、C 或 D 类的成员,但不是 a。*

然后,如果您还有手动标记样品的空间,您可以考虑像 Sample_3 这样的样品。此时,首先计算两个正距离值之差的绝对值。差异越小,样本的预测就越模糊。因此,您可以选择差值较小的样本。我试图在图 2 中总结一个 4 类数据集的 OvR 组合。同样的想法可以扩展到所有多类数据集,只需稍加修改。

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

图 2-在 4 类数据集上应用 OVR(SVM)-距离值符号的组合(图片由作者提供)

你也可以看看下面的代码片段,它是上述方法的实现。

*# It calculates the difference of distance results of only positive 2 distance value
def posit_diff(a,b,c,d):
    lst = list([a,b,c,d])
    print(lst)
    index_lst = [lst.index(i) for i in lst if i>0]
    print(index_lst)
    if len(index_lst) != 2:
        print('Warning! Expecting only 2 positive distance values')
        return -1
    else:
        return abs(lst[index_lst[0]] - lst[index_lst[1]])MODEL = LinearSVC(penalty='l2',dual=False, multi_class='ovr', class_weight = 'balanced', random_state=1709)
ACTIVE_LEARNING_BATCH_SIZE = 100 # lets say I am looking for 100 most informative samples from the data set 
# FEATURES = [...]def active_learning(df_train_set, df_unlabelled_set):
    """
    Applying active learning to an example of 4 classes classification problem. 
    """
    ovr = OneVsRestClassifier(MODEL)
    ovr.fit(df_train_set[FEATURES], df_train_set['LABEL'])
    pred = ovr.predict(df_unlabelled_set[FEATURES])dec_func = (ovr.decision_function(df_unlabelled_set[FEATURES]))df_dec_func = pd.DataFrame(dec_func, columns = ['1','2','3','4'])
    df_dec_func = pd.concat([df_dec_func, df_unlabelled_set],axis=1)df_dec_func['positives'] = df_dec_func[['1', '2', '3', '4']].gt(0).sum(axis=1)
    df_dec_func['negatives'] = df_dec_func[['1', '2', '3', '4']].lt(0).sum(axis=1)df_dec_func_posit_0 = df_dec_func.loc[df_dec_func['positives']==0] # the most informative ones
    df_dec_func_posit_3 = df_dec_func.loc[df_dec_func['positives']==3] # the second most informative ones
    df_dec_func_posit_2 = df_dec_func.loc[df_dec_func['positives']==2] # the third most informative onesdf_dec_func_posit_2['posit_diff'] = df_dec_func_posit_2[['1','2','3','4']].apply(lambda x: posit_diff(*x), axis=1)
    df_dec_func_posit_2 = df_dec_func_posit_2.sort_values(by=['posit_diff'], ascending = True)
    df_dec_func_posit_2.reset_index(drop=True, inplace=True)
    rest_needed = (ACTIVE_LEARNING_BATCH_SIZE) - (df_dec_func_posit_0.shape[0] + df_dec_func_posit_3.shape[0])

    if rest_needed > 0:
        df_dec_func_posit_2_al = df_dec_func_posit_2.iloc[0:rest_needed,:]
        df_act_learn = pd.concat([df_dec_func_posit_0, df_dec_func_posit_3, df_dec_func_posit_2_al], axis=0)
    else:
        df_act_learn = pd.concat([df_dec_func_posit_0, df_dec_func_posit_3], axis=0)
        df_act_learn = df_act_learn.sort_values(by=['positives'], ascending=True)
        df_act_learn = df_act_learn.iloc[0:ACTIVE_LEARNING_BATCH_SIZE,:]
    df_act_learn.reset_index(drop=True, inplace=True)

    return df_act_learn*

更进一步,聚类可以应用于推断为最有信息的样本的样本集。通过从聚类的质心和边界选择样本(等于类的数量),可以确保最终集合中的变化。

半监督学习

增加数据集中标签数量的另一种方法是以自动方式标记最有把握的样本。换句话说,如果预测样本高于预定的阈值,则可以迭代地标记样本。并且阈值可以在每次迭代中增加。

假设,分类器预测一个样本属于 A 类的概率为 87%,高于阈值 85%。因此,在接下来的步骤中,它可能被评估为 A 类成员。训练集和未标记集在每次迭代结束时被更新。注意,事实上,它可能不是类 A 的成员,这是基于半监督的方法的一个非常严重的缺点。我在下面的代码片段中分享了这种方法的一个简单代码示例:

*MODEL = RandomForestClassifier(max_depth=4, n_estimators=200, class_weight='balanced', random_state=1709)
LIST_LABELLED_SAMPLES = df_train_set.shape[0]
SS_LEARNING_LABELLING_THRESHOLD = 0.80
SS_THRESHOLD_INCREASE = 0.01
MAX_SS_ITERATION = 10
# FEATURES = [...]def ss_iterations(df_train_set, df_unlabelled_set):  
    """
    It covers all steps of semi supervised learning.
    It uses a simple Ranfom Forest to fit df_train_set and predict df_unlabelled_set 
    to determine the most confident samples 
    those are predicted with a higher accuracy than SS_LEARNING_LABELLING_THRESHOLD. 
    """
    pred_threshold = SS_LEARNING_LABELLING_THRESHOLD

    ovr = OneVsRestClassifier(MODEL)
    print('Before iterations, size of labelled and unlabelled data', df_train_set.shape[0], df_unlabelled_set.shape[0])for i in range (0, MAX_SS_ITERATION):ovr.fit(df_train_set[FEATURES], df_train_set['LABEL'])
        preds = ovr.predict_proba(df_unlabelled_set[FEATURES])df_pred = pd.DataFrame({'1': preds[:, 0], '2': preds[:, 1], '3': preds[:, 2], '4': preds[:, 3]})
        df_pred_ss= pd.concat([df_unlabelled_set, df_pred], axis=1)df_pred_ss['MAX_PRED_RATIO'] = df_pred_ss[['1', '2', '3', '4']].max(axis=1)
        df_pred_ss['LABEL'] = df_pred_ss[['1', '2', '3', '4']].idxmax(axis=1)
        df_pred_ss['LABEL'] = df_pred_ss['LABEL'].astype(int)
        df_pred_ss_up = df_pred_ss[df_pred_ss['MAX_PRED_RATIO'] >= pred_threshold]
        print('The number of samples predicted with high confidence level:', df_pred_ss_up.shape)if len(df_pred_ss_up) > 0:# deleting from unlabelled set
            df_unlabelled_set.drop(index=df_pred_ss_up.index.tolist(),inplace=True)
            df_unlabelled_set.reset_index(drop=True,inplace=True)# adding to train set as if they are ground truths
            df_train_set = pd.concat([df_train_set, df_pred_ss_up[df_train_set.columns]],axis=0)
            df_train_set.reset_index(drop=True, inplace=True)print('Threshold ratio', pred_threshold)
            print('Remaining unlabelled data', df_unlabelled_set.shape[0])
            print('Total labelled data', df_train_set.shape[0])
            print('Iteration is completed', i)pred_threshold += SS_THRESHOLD_INCREASE
        else:
            print('No improvement!')
            breakdf_train_set.reset_index(drop=True,inplace=True)
    df_unlabelled_set.reset_index(drop=True,inplace=True)

    return df_train_set, df_unlabelled_set*

标签增强——主动学习 vs 半监督学习

总之,标签增加背后的原因非常简单。实际上,主动学习背后的推理与半监督学习相反。

在主动学习中,我们的目标是找到以低概率预测的信息量最大的样本。在找到它们之后,这些样本被分享给专家进行人工标记。如果您有大量未标记的数据,而标记这些数据的资源有限,那么这是一种非常有效的方法。另一方面,预测概率高(信息量最少)的样本被自动标记,就好像它们是基本事实一样,并被添加到下一次迭代的训练集中。

主动学习和半监督学习都可以顺序地应用于相同的数据集。首先,应用多个半监督迭代,直到不再有概率高于阈值的预测。然后主动学习的单次迭代可以应用于前一步骤的结果,并且推断的信息样本可以与要标记的领域专家共享。可能会重复一定数量的迭代集。

有用的链接

* *

构建实时 ML 系统的方法

原文:https://towardsdatascience.com/approaches-for-building-real-time-ml-systems-79ea0e340269?source=collection_archive---------4-----------------------

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

来源:https://unsplash.com/photos/p3Pj7jOYvnM

理解大数据

以毫秒为单位响应预测请求

作为 Zynga 的应用数据科学家,我已经开始着手构建和部署数据产品。随着我探索越来越多的机器学习用例,对实时机器学习(ML)系统的需求越来越多,其中系统执行特征工程和模型推理,以在几毫秒内响应预测请求。虽然我以前使用过 AWS SageMaker 等工具进行近实时的模型推理,但我只是最近才探索了为 ML 系统进行动态特征工程的选项。

广告技术是需要实时 ML 来构建在广告市场中表现良好的系统的领域之一。在广告的需求方面,实现 OpenRTB 规范的实时竞价者需要预测哪些广告印象最有可能驱动转换事件。在供应方,广告中介平台需要实时确定广告库存的投标底价,以便优化广告收入。

在实时 ML 部署中,系统会在请求发出后的几毫秒内回复请求。使用实时系统进行预测请求有两种常规工作流程:

  1. Web 请求
  2. 流式工作流

在第一种情况下,需要预测的系统或客户端向一个端点发出 HTTP 请求,该端点使用预测直接响应请求。其他协议,如 gRPC,可以用于这种类型的工作流。

第二个工作流程可以通过多种方式实现。例如,可以向 Kafka 主题发出一个请求,在那里用 Spark 流处理该请求,并将结果发布到一个单独的主题。其他流框架,如 Flink 或 GCP 数据流,可用于近实时响应预测请求。

在过去的一年里,我和 Golang 一起开发了实时 ML 系统。虽然 Python 可以用来实现这些类型的系统,但 Golang 通常能够在固定数量的机器上每秒响应更多的请求。此外,Golang 还有一些优雅的特性,可以在构建实时 ML 系统时使用 NoSQL 数据存储。对于请求量非常大的用例,为了提高效率,我选择了纯 Go 实现。

在这篇文章中,我将讨论构建实时执行特征工程和模型推理的 ML 系统的一些可用选项。我将讨论纯 Go 方法和 Python 混合方法的选择。

特征工程

在应用模型之前,通常需要将预测请求转换成可以传递给 ML 模型的特征向量。例如,对于 OpenRTB bid 请求,在预测转换事件之前,需要将 web 请求中传递的 JSON 转换为特征向量。另一个用例是检索移动游戏的用户简档,并将简档转换为特征向量,以进行终身价值(LTV)预测。在这些用例中,基于请求中的信息实时执行特征工程,或者在移动应用中使用先前存储的关于用户的信息。

特征工程需要进行重大转变,从矢量预先计算的批处理过程转变为针对每个传入请求即时进行特征工程的实时系统。在广告技术中,系统可以接收投标请求,然后在执行特征工程之前用额外的数据点(例如来自数据管理平台(DPM)的信息)来扩充该请求。所有这些都需要以最小的延迟来完成,这限制了可以使用的方法的类型。以下是我探索过的一些方法:

  1. 经常预先计算特征并存储在 NoSQL
  2. 使用 NoSQL 存储和更新特征向量
  3. 使用 NoSQL 存储配置文件,并使用自定义应用程序代码进行翻译
  4. 使用 NoSQL 存储配置文件,并使用 DSL 进行翻译
  5. 为特征工程调用远程端点

这些解决方案大多依赖于使用 NoSQL 数据存储,因为它需要快速响应请求。对于使用哪种工具,需要考虑几个权衡因素,例如要存储的数据点数量、读/写请求以及最大延迟。Redis 是入门时的一个很好的选择,大多数云平台都有托管服务。

预计算功能

这种方法最接近于传统的批处理预测工作流,在这种工作流中,同时为大量用户进行预测,并将结果缓存到应用程序数据库中,如 Redis。这实际上不是实时地执行特征工程,而是可以以这样一种方式来实现,即对于在应用中活跃的用户,特征向量被频繁地更新。例如,您可以使用 Spark 作业每 15 分钟查询一次关系数据库,使用 SQL 将用户活动转换为特征向量,并将结果存储到 NoSQL 商店。对于许多用例来说,从用户在应用程序中执行操作到该活动出现在用于模型推断的特征向量中有 15 分钟的延迟可能不是问题。然而,这对于关系数据库来说是一项繁重的工作,只有在需要创建向量的用户数量相对较少的情况下才推荐使用。这种方法不适用于系统需要在特征生成过程中使用来自预测请求的上下文的问题,并且通常应该仅用作后备。

在 NoSQL 直接存储媒介

使用 NoSQL 实时执行特征工程的另一种方法是提前确定应用所需的特征向量的形状,并在系统接收到新的跟踪事件时实时更新这些值。例如,特征向量可以具有跟踪用户已经进行的会话总数的属性,并且每当用户开始新的会话时更新该值。对于移动应用程序,具有实时回调事件的 MMP 可用于设置这种跟踪事件功能。

对于这种方法,像用户 ID 这样的键被用作 NoSQL 商店的键,值是特征向量,它可以用多种方式实现。在 Redis 中,散列可以用来实时更新计数器值。向量也可以存储为 JSON,这很简单,但通常会占用更多空间。您可以使用特定于编程语言的库进行序列化,比如 Java 的 kryo 。我通常使用的方法是 Google 协议缓冲区,以可移植的方式序列化数据。

这种方法是基本的,这使得它更容易实现,但是它有一些主要的限制。首先,您需要一个固定的特征向量定义,因为向量是在收到新数据时直接更新的,而不是即时聚合数据,我们将在后面的方法中讨论。第二个大的限制是特性必须能够增量更新,而不是在过去的事件上聚集。这意味着可以使用诸如计数器和标志之类的功能,但不可能使用诸如中位数之类的聚合或其他需要历史数据的计算。

配置文件和自定义应用程序代码

为了在可为特征工程执行的操作类型中获得更大的灵活性,一种选择是在 NoSQL 中存储用户简档,并使用存储在简档中的数据来动态执行特征工程以创建矢量。该方法使用与之前相同的过程,其中当接收到新数据时,实时更新 NoSQL 存储中的值,但是该方法不是更新特征向量,而是更新概括用户活动的用户简档。例如,简档可以存储用户在游戏中玩的过去 3 种游戏模式,或者跟踪用户最近使用了哪些加电项目。

当使用这种方法接收到预测请求时,该请求在请求中传递用户 ID,预测端点从 NoSQL 获取配置文件,然后自定义应用程序代码将该配置文件转换为特征向量。在 Golang 中,这可以实现为一个函数,该函数将 protobuf 对象作为输入,并返回一个特征向量([]float64)作为结果。这种方法通常是计算效率最高的方法,但是每次特征向量的定义改变时都需要系统的新部署。这对于只需要为少量模型提供服务并且定义很少改变的系统来说很有效,但是对于为各种模型提供预测的系统来说可能是有问题的。

配置文件和领域特定语言(DSL)

为了消除每次特征向量定义改变时部署系统的需要,我们需要系统更新特征变换的更灵活的方法。一种方法是使用数据驱动或配置驱动的方法,在这种方法中,转换被定义为数据结构或配置文件,可以在每次进行更新时由系统加载。例如,可以将系统设置为接收一个 JSON 文件,该文件定义了 OpenRTB bid 请求的哪些属性和值要进行 1-hot 编码。这使得数据科学家能够在单独的运行时(如 PySpark)中定义模型管道,而模型在 Go 中提供服务。

随着时间的推移,团队可能希望定义更复杂类型的操作来对请求数据和用户配置文件执行操作,以将这些数据点转换为特征向量。针对这个问题,我探索了小型的特定领域语言(DSL ),比如在比较值时允许≥和≤操作符,以及添加操作符来检查列表中的某项。这很快变得复杂起来,并成为系统部署的新驱动力,因为新的操作符是为您的定制 DSL 定义的。我已经开始使用谷歌的通用表达式语言 (CEL)将用户资料翻译成特征向量,而不是为每个新系统从头开始构建。该语言支持各种可以在 protobuf 对象上执行的操作,在输入对象上运行的 CEL 程序的输出是一个特征向量。当使用这种方法时,特征工程翻译被定义为 CEL 程序,它可以作为字符串传递。

特征工程终点

如果延迟不是问题,并且您希望在如何将用户配置文件转换为特征向量方面有很大的灵活性,那么您可以设置一个端点来执行该转换。这可以通过 AWS Lambda 等无服务器功能或部署到 Kubernetes 实例的 docker 映像来实现。这种方法在构建原型时很有用,但是会导致额外的云基础设施,并且具有定制应用程序代码方法的所有缺点。它仍然使用这种方法,但提供了一个选项,当更新特征工程定义时,只需要重新部署无服务器功能,而不是整个系统。

模型推理

一旦有了预测请求的特征向量,就需要在响应实时请求时应用 ML 模型。实现这一功能有多种选择,但是使用 Golang 确实会使事情变得更加复杂。以下是我探索过的方法。

  1. 推理终点
  2. 自定义应用程序代码
  3. 跨运行时算法
  4. 便携式模型格式

我曾经开发过数据产品,其中训练环境是 PySpark,运行时环境是 Golang,这使得使用标准数据科学堆栈(如 sklearn、XGBoost、SparkML 和 TensorFlow)训练的模型变得很棘手。我将介绍一些处理这些限制的方法,但是纯粹的 Go 实现仍然有一定的局限性。

推理终点

支持各种模型推理算法的最简单方法之一是使用该问题的现有解决方案,如 AWS SageMaker、BentoML 或 fast.ai。这些解决方案使用 Python 运行时为模型提供服务,并支持预测模型的标准 ML 工作台。当使用这种方法时,系统首先在当前过程中执行特征生成,调用端点来执行模型推断,然后用推断端点产生的值来响应预测请求。

这种方法适用于大多数用例,但是有一些注意事项。如果系统正在响应大量的请求,那么像 SageMaker 这样的托管解决方案会变得非常昂贵。另一个问题是延迟,调用远程进程会增加延迟,并会影响系统的 SLA,这对广告技术等领域来说是个问题。

自定义应用程序代码

如果系统需要运行的算法相对简单,例如线性模型,那么编写自定义应用程序代码来实现该模型可能是有利的。在 Golang 中,线性回归和逻辑回归相对容易实现,但是您需要定义一种格式来序列化 Python/PySpark to Go 的模型,这取决于您的培训环境。对于更复杂的算法,这种方法可能会很快导致技术债务,并最终导致错误。

这种方法非常有用的地方是当构建具有非常宽的特征向量的系统时,例如成千上万的特征。如果向量非常稀疏,那么在处理这种规模的数据时,可以使用查找表(如哈希映射)来高效地执行模型推断。

跨运行时算法

我经常为 Golang ML 系统使用的一种方法是使用在 Python 和 Golang 中都有实现的算法。LightGBM 是一个很好的 ML 算法的例子,它在 Python 中运行良好,并与叶库相匹配。在 Python 和 Go 中,库与积极支持的实现的交集很小,但有望随着时间的推移而增长。TensorFlow 确实有 Golang API,但目前还不稳定。

便携式模型格式

为了帮助解决只有少数 ML 库在 Golang 中得到适当支持的事实,我探索的另一种方法是可移植的模型格式,如 PMML 和 ONNX。PMML 是使 ML 模型可以跨不同运行时移植的最初提议,但是只有有限的几个关键 ML 框架采用了它。前提是你可以用 Python 训练一个模型,用 PMML 格式保存结果,然后在不同的运行时加载模型,进行模型推断。Golang 实现了用于推理的 PMML,例如 goscore ,但是目前还不支持流行的算法,例如 XGBoost。

ONNX 是使 ML 模型跨运行时可移植的下一代建议。它最初是为深度学习而设计的,但已经扩展到支持经典算法。理论上,您可以使用 SparkML、XGBoost、sklearn、Tensorflow 和其他工具来训练模型,并使用 ONNX 实现在任何运行时运行模型推理。目前的情况是,许多这些框架对导出到 ONNX 的支持有限,Golang 实现的领先者对经典 ML 算法的支持也有限。对 ONNX 导出和运行时的支持有望随着时间的推移而改进,使 ML 系统的纯 Go 实现成为一个可靠的选择。

结论

对于数据产品,从批量转换到实时 ML 预测需要新的方法来执行特征工程和潜在的模型推断。我发现对实时特征工程最有用的方法是在 NoSQL 数据存储中存储一个用户级概要对象,并使用自定义应用程序代码或通用表达式语言对每个请求动态执行特征工程。对于模型推理,我使用了可用于模型训练和模型服务环境的算法和实现。

让我们的团队能够构建能够在数毫秒内响应预测请求的 ML 管道,这开启了各种新的用例。

本·韦伯是 Zynga 应用科学总监。我们正在招聘

交易数据中的异常检测方法

原文:https://towardsdatascience.com/approaching-anomaly-detection-in-transactional-data-744d132d524e?source=collection_archive---------9-----------------------

交易数据中的异常检测可能很难,但它带来了在大量数据中发现未知的好处,否则这是不可能的。

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

查尔斯·德鲁维奥在 Unsplash 上拍摄的照片

1 导言

通常,当人们谈论交易数据**时,他们指的是金融交易。**然而,根据维基百科,“交易数据是描述一个事件(作为交易结果的变化)的数据,通常用动词来描述。交易数据总是有一个时间维度,一个数值,并涉及一个或多个对象”。在本文中,我们将使用向服务器发出请求的数据(互联网流量数据)作为示例,但是所考虑的方法可以应用于前述事务性数据定义下的大多数数据集。

异常检测,简而言之,就是在一个生成数据的系统中,找到正常情况下不应该出现的数据点。交易数据中的异常检测有许多应用,下面是几个例子:

  • 金融交易中的欺诈检测。
  • 制造中的故障检测。
  • 计算机网络中的攻击或故障检测(本文涉及的情况)。
  • 预测性维护的建议。
  • 健康状况监控和警报。

2 数据

2.1 数据描述

我们将用作示例的数据如下所示:

具有如下所述的列:

  • 时间戳:事件发生的时间。
  • serverId: 被访问的服务器的唯一标识符。
  • ip :客户端的 IPv4 地址或 IPv6 地址。
  • timeMs :请求和服务器响应之间经过的时间,以毫秒为单位。
  • clientSSLProtocol :用于请求的 SSL 加密协议。
  • clientHTTPMethod : POST,GET,PUT,PATCH,DELETE。
  • clientRequestHTTPProtocol:HTTP 协议的版本,例如 HTTP/1、HTTP/2。
  • clientRequestPath :请求的路径,例如。/v3/article/。
  • userAgent :一个特征字符串,让服务器和网络对等点识别应用程序、操作系统、供应商和/或发出请求的用户代理的版本。

2.2 数据探索

这里我们不是在进行经典的 EDA(探索性数据分析),而是试图从几个给定的例子中理解如何使用数据。

现有功能(列)分为 3 类,并补充了使用它们的方法:

  • 实数(timeMs,…) 。这些可以直接使用(在基于树的模型的情况下)或者在输入模型之前用标准化
  • 基数低的分类变量(clientSSLProtocol,clientHTTPScheme,clientHTTPMethod,…) 可以编码(one hot,target 等…)或者嵌入式。
  • 具有高基数和文本数据的分类变量(clientRequestPath,userAgent,… )。这些方法比较棘手,一种方法是解析文本并尝试推断基数较低的类别,或者,例如,使用文本嵌入

2.3 特征工程

2.3.1 时间特征

时间戳可以被编码成如下特征:

  • 一小时中的分钟
  • 一天中的小时
  • 星期几
  • 等等…

为了摆脱隐式排序(即周一和周日之间的距离与其他连续日期之间的距离相同,但如果它们分别编码为 1 和 7,则该属性不成立),通常使用归一化值的正弦和余弦。

2 . 3 . 2 IP 地址的处理

可以使用字典查找将 IP 地址转换为地理位置。这个位置可以被视为一个分类变量。

此外,可以检查 IP 地址是否是众所周知的代理服务器,并将其标记为众所周知的代理服务器(这对于应用 3.1.1 中的规则很有用)

用户代理标志

userAgent 值可以被解析以提取关于特定子字符串存在的信息,如“torrent”、“iphone”、“chrome”等,然后相应的标志“uaTorrent”、“uaIphone”、“uaChrome”等被设置为 1。

然而,解析规则可能需要维护,因为相关的关键字往往会随着时间而变化。

2.3.4 clientRequestPath 标志

用户代理相同,但是搜索类似“登录”、“管理”等模式…

2.4 标签

数据集中的记录没有按照“坏的”和“好的”参与者进行标记,但是我们假设在下一节中数据集可以具有用于监督建模方法的那些标签。

3 建模

在本节中,我们回顾了几种异常流量检测器的建模方法,从最简单到最先进,考虑它们的优缺点。

3.1 检测个别异常

3.1.1 简单规则集

在这个简单的检测器中,一组规则被应用于每个单独的记录,并且在以下情况下发生警报,例如:

  • 时间> X
  • uaTorrent == 1

以及规则的逻辑组合(与、或……)

优点:

  • 很容易推理
  • 易于实现和测试
  • 警报是可以解释的
  • 一个相当复杂的规则集是最快的选择

缺点:

  • 难以维护,尤其是当规则集变得复杂时
  • 不能(快速)适应变化的行为
  • 可能会遗漏不明显的病例,因此召回率可能较低

3.1.2 记录的监督分类

这种方法假设标签对于数据是可用的,并且问题可以被构造成一个二元分类。几乎所有的分类模型都可以在这里应用,将特征(2.1)作为输入向量。这些模型可以是简单的,如逻辑回归,也可以是复杂的,如神经网络,输出一个介于 0 和 1 之间的“异常分数”。然而,树集成在这里似乎是一个最佳选择,它结合了自然的可解释性、良好的预期预测性能、无需显式编码的分类变量支持以及可接受的推理速度。如果数据量很大,后者非常重要。

优点:

  • 分类是一个众所周知的 ML 问题,有许多成功应用的例子
  • (潜在的)高检测性能(也见缺点)
  • 大多数模型都是可以解释的

缺点:

3.1.3 无监督异常检测

高质量的标签并不总是可用的,因此无人监管的方法可能会很方便。异常检测方法/模型通常学习数据中最流行的模式,然后预测新示例的“异常性”。

优点:

  • 模型训练不需要标签

缺点:

  • 标签对于模型验证仍然很方便
  • 需要用于模型(重新)训练和存储的基础设施

3.2 使用时态数据(“行为”分析)

使用时间可以使模型不断适应潜在恶意行为者不断变化的行为,但这需要对数据进行更多的预处理。这种预处理将是在滚动时间窗口上的聚合,并且可以用类似这样的伪火花码来完成:

df
 …
 .groupBy(window(col(“timestamp”), 1.minute), col(“ip”))
 .agg(
   count(col(“*”)) as ‘num_reqs,
   avg(col(“timeMs”)) as ‘avgTimeMs,
   skew(col(“timeMs”)) as ‘skewTimeMs,
   count(when(col(“clientRequestPath”).contains(“login”)) as ‘num_logins),
 …
)

**注意:**数据按“ip”分组,但根据使用案例,按国家和/或地区组合(从 IP 地址解码)分组可能更好。

通过这个查询,我们可以将数据转换成一组时间序列,并应用下面描述的特定于时间序列的方法。

3.2.1 对比历史统计

为了增加规则“模型”的适应性,我们可以使用数据的时态特征和简单的规则集来修改规则,如下所示:

currentTimeMs > avgTimeMs + someConstant

其中“avgTimeMs”是在最后 N 个时间戳上度量的连续更新的平均值。

对于分类特征,可以使用比较当前时刻分类变量的分布和来自相同的最后 N 个时间戳的一些聚集分布。

优点:

  • 不需要模型(重新)训练,但仍然提供适应性

缺点:

  • 需要附加的预处理步骤

**注:**其他利弊同简单规则集。

3.2.2 异常检测任务的时间序列预测

该方法的工作方式如下:基于某个时间窗口,模型预测下一个值,并将预测值与实际观察值进行比较。潜在的预测方法可能会有所不同,从更传统的东西,如 SARIMA 到深度学习。概率预测由于不利因素列表中描述的因素而成为首选。

优点:

  • 是一种自我监督的方法,因此不需要标签
  • 当超出正常值的指标被返回为异常时,可以解释多变量预测的情况,可选地,与正常值的距离为异常分数,数据列用于分组依据
  • 例如,在胶子-ts 中提供的概率模型的情况下,不需要设置阈值,只需要设置百分位数,超出百分位数的观察将被视为异常

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

关于胶子-ts 的概率预测例子

缺点:

  • 需要用于模型(重新)训练、验证和存储的基础设施
  • 推理时间可能很长,尤其是对于概率模型

3.3 解释预测

可解释的预测对于识别检测的根本原因非常重要,这对于调试和调查攻击可能非常有用。所以不推荐像神经网络这种不易解释的模型。

就工具而言,例如 SHAP ,它是从黑盒模型中推断特性重要性的最佳软件包之一。

4 额外资源

这两个存储库是异常检测和时序预测的研究和工具的重要信息源:

https://github.com/yzhao062/anomaly-detection-resources https://github.com/cuge1995/awesome-time-series

5 结论和后续步骤

在本文中,我们回顾并总结了应用于交易数据的异常检测任务的数据预处理、特征工程和建模的几种选择。根据系统要求,选项的数量可以缩小:例如,如果推理时间应该是微秒——深度学习模型最有可能出局。可行的方案应进行离线和在线测试,并根据项目开始时选择的成功标准确定最佳方案。该指标可以是 precision (如果担心误报),或者 recall (如果错过攻击代价高昂),甚至是某种综合指标,可以是这两者与各种指标(如推理时间、训练时间、计算负载、错误成本等)的加权组合

像科学家一样对待数据科学项目

原文:https://towardsdatascience.com/approaching-data-science-projects-like-a-scientist-86dcb9e4d6dc?source=collection_archive---------22-----------------------

入门

在数据科学项目中使用科学方法

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

萨特西什·桑卡兰Unsplash 上的照片

介绍

一个科学家用 的科学方法 进行研究。科学方法一词指的是进行实验的过程,这一过程始于观察,始于提出问题、进行假设、进行实验、观察和分析、得出结论。

使用科学方法的方法不仅适用于科学家进行实验,还可以用于我们的日常生活中解决问题,通过这种方法,我们可以学习如何提出问题、收集信息、基于证据进行分析、使用逻辑得出结论,并在生活中做出更好的决定。

在本文中,我们将探索和学习什么是科学方法,以及如何在数据科学项目中使用科学方法。

什么是科学方法?

当人们开始通过显微镜进行研究时,弗朗西斯·培根爵士首先介绍了这种科学方法。培根为哲学家创造了科学方法,以确保结果的真实性,并主张哲学家在确认真理之前必须怀疑他们的主张。科学方法由一系列步骤组成,首先是观察、提出问题、形成假设、进行实验以检验假设、分析结果,以及确定假设是正确还是不正确。

科学用来获得基于观察的知识的方法,通过实验制定定律和理论、检验理论或假设

—科学方法的定义:摘自牛津参考文献

现在,让我们从数据科学的角度更深入地理解“科学方法”的方法。

理解科学方法

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

科学方法流程(图片由作者提供)

第一步:观察和理解

在开始一个机器学习项目之前,我们首先需要观察、执行一些研究并了解项目所属的业务。在这个阶段,你可能会或可能不会得到一组数据。如果没有提供数据,那么你需要调查类似的案例,进行研究,寻找现有的数据,并进行调查,以获得更好的理解。如果提供了数据,观察、探索并确定哪些是与您的用例相关的信息。

一家电信公司找我们建立一个机器学习模型,来预测和识别在接下来的一个月中可能流失的客户。—这个阶段的观察和理解是什么?

  • 理解用例、业务问题和目标/结果的大背景。
  • 与利益相关者交流,了解更多关于电信行业的信息。
  • 了解以前识别和防止客户流失的方法。
  • 浏览数据以更好地理解可用信息。
  • 观察在数据集中是否可以看到任何模式。

在观察、理解和探索之后,你会开始有问题浮现在你的脑海中,这使我们进入科学方法过程的下一步——从一个问题开始。

第二步:从一个问题开始

在这一阶段,根据前面的观察、理解和探索步骤,提出问题。列出问题是为了更好地理解哪些领域可以用当前的信息集来回答。从 7w 开始提问——“什么”、“为什么”、“如何”、“哪个”、“什么时候”、“谁”或“哪里”。

可能的问题是什么?

  • 流失率是多少?
  • 客户流失前是否有异常行为或迹象?
  • 大多数流失的客户都有类似的移动计划吗?
  • 哪些套餐流失率最低?
  • 哪个客户下个月会离开?

有了初步的问题列表和对用例的更好理解后,问题将被转化为假设。

第三步:提出假设

在机器学习项目中,假设生成就像是通过识别可能影响企业正在解决的问题的因素来进行“有根据的猜测”。开发假设是数据科学项目中的一个重要过程,因为它有助于识别信息/驱动因素,这些信息/驱动因素有助于模型更准确地预测,并了解需要收集哪些额外数据,或者如果在早期阶段没有提供数据,需要收集哪些额外数据。

例如:

  • 搅动的客户通常属于类似的移动计划。
  • 搅动的顾客远离联系较弱的城市。
  • 与在职成年人相比,老年人的流失率往往更高。

作为一名数据科学家,您必须能够进行批判性思考,并具备识别不同因素和生成相关假设的领域专业知识,以便从模型中获得成功的结果。

假设生成后的下一步是执行实验和测试假设。

步骤 4:进行实验来测试假设

在此阶段,您将根据生成的假设收集相关数据,并构建一个探索图表来支持假设,然后在训练机器学习模型时将它们作为因素/驱动因素添加进来。

例如,在制定了假设— 之后,经常翻炒的客户属于一个类似的移动计划 ,然后我们将需要查看数据集,以确定我们的假设是否得到数据的支持。这个过程可以通过将结果制成表格或构建可视化视图来实现。

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

构建一个图表来调查移动计划的流失率(图片由作者提供)

上图显示,计划 A 中的客户流失率最高,这符合我们的假设。因此,在模型训练数据集中具有每个客户移动计划的信息可以导致更好的预测结果。或者,如果数据不支持我们的假设,那么这表明假设不应该被接受。

对生成的每个假设重复这一步,在将它们作为模型训练的因素/驱动因素添加之前,我们测试和验证假设。

假设检验后的下一步是分析和解释结果,这也意味着评估我们的模型性能。

第五步:分析和解释结果

在此阶段,我们将根据上一步中训练的模型来评估我们的模型性能。机器学习模型通常会经历模型调整的迭代步骤,但拥有一组经过测试并得到数据支持的强大假设将会导致更好的模型性能。模型定型后,将对照验证集和维持集来验证模型性能。(如果你想了解更多关于验证集和维持集的区别——参考本文 )。)

在验证模型性能时,有几个问题需要回答,例如:

  • 该模型在识别流失客户方面有多准确?错误率是多少?
  • 有什么新的假设可以被检验并作为一个特征添加到模型中吗?

有了回答问题陈述的最终模型后,下一步是得出结论,并将结果反馈给涉众。

第六步:沟通

最后一步是能够以可理解的格式传达结果,并提供利益相关者可以采纳的建议*(例如,提供下个月可能流失的客户列表,以及营销团队如何根据这些信息采取行动。)*

以可理解的格式向观众展示你的发现的一个很好的方式是通过交互式图表或演示幻灯片的可视化。

结论

数据科学不仅仅关注不同的机器学习模型(深度学习、神经网络、聚类等。)但也要考虑到科学方法。就像进行科学实验一样,数据科学中的科学方法可以帮助我们避免得出错误的结论,并根据我们的假设建立一个有偏见的模型。随着组织在项目中采用科学方法,他们将能够理解最终导致构建更健壮的模型和做出更好的决策的数据。

感谢您阅读我的文章,如果您喜欢并愿意支持我:

参考文献&链接:

[1]https://open StAX . org/books/biology/pages/1-1-the-science-of-biology

[2]科学方法。*牛津参考。*2021 年 11 月 1 日检索,来自https://www . Oxford reference . com/view/10.1093/oi/authority . 20110803100447727

[3]https://search business analytics . tech target . com/feature/The-data-science-process-6-key-steps-on-analytics-applications

逼近 KL 散度

原文:https://towardsdatascience.com/approximating-kl-divergence-4151c8c85ddd?source=collection_archive---------26-----------------------

无偏的低方差样本估计

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

阿图尔·尤奇卡在 Unsplash 上的照片

在本文中,我将讨论 KL 散度的一个样本近似值。我将讨论正向和反向 KL 偏差,所以如果你不熟悉这些概念,在这里查看我关于主题 的文章 可能会有帮助。

如果你想要一些关于如何用代码实现这一点的指导(来自 open ai联合创始人 John Schulman 的评论)!!)查看我的拉动请求 此处 为稳定基线 3。

为什么一开始要近似?

  1. 无解析解:KL 散度的完整形式解析解可能未知。例如,高斯混合分布就是这种情况。
  2. 高计算复杂度:计算完整的 KL 散度经常需要对整个分布空间求和。使用不需要这样做的近似是有用的,因为它可以更快。

近似值的标准

KL 散度是“真实”分布和“预测”分布之间差异的度量。“真实”分布 p(x) 被认为是固定的,而“预测”分布 q(x) 是我们可以控制的。我们将从 q(x) 中抽取样本作为近似函数的输入,使其成为一个随机变量。如果 p(x) 是已知的,您可以从那里取样本,但有时情况并非如此,因此概括起来,我们将坚持使用 q(x)

直觉上,近似应该具有与被近似的原始度量相似的行为。我们可以用两种方法来衡量这种相似性:

  1. 偏差:理想情况下,近似值应该是无偏的;也就是说,近似值的期望值应该等于原始度量。
  2. 方差:方差为 0 的无偏近似值(确定性的)将完全等于原始度量!当然,这是不现实的,但理想情况下,方差应该尽可能低,从而增加获得更接近原始度量的值的可能性。

近似向前 KL 发散

让我们首先提醒自己完整的分析形式:

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

作者图片:KL 向前发散

首先,让我们考虑一下偏见的情况。我们想要:

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

作者图片

其中 approxKL 是我们想要得到的近似值。让我们看看下面的解决方案:

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

作者图片

因此:

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

作者图片:向前 KL 发散的无偏近似

但是这个方差仍然很高,因为它可以取负值,而实际 KL 散度不能。改善这种情况的一种方法是添加一个期望值为 0 的项,该项与上面的原始近似值负相关。我们提出以下解决方案:

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

作者图片

这是可行的,因为 p(x) 被假定为有效的概率分布。因此,我们可以将近似值更新为:

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

作者图片

其中我们可以求解 λ 来找到最小方差。不幸的是,这取决于具体情况,很难分析计算。但是,我们仍然可以通过选择值-1 来找到一个很好的折衷方案。这在任何情况下都导致一个正定的近似!如果我们将比率 p(x)/q(x) 作为自己的变量,并将其与近似值 λ=-1 相对照,我们会得到以下正定图:

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

作者图片

因此,前向 KL 散度近似的最终形式是:

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

作者图片:最终缩减方差无偏正向 KL 散度近似值

近似反向 KL 散度

我们可以采取同样的步骤来得到反向 KL 散度和正向 KL 散度的近似值!

让我们提醒自己完整的分析形式:

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

作者图片:反向 KL 发散

再次,我们需要首先获得一个简单的无偏近似;下面给出了一个解决方案:

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

作者图片

因此:

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

作者图片:反向 KL 发散的无偏近似

这遭受与前向 KL 散度的无偏近似完全相同的问题:这可能取负值,这导致大的方差。我们可以用和上次一样的术语来反驳这一点:

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

作者图片

同样,我们现在可以求解 λ 以找到最小方差,尽管这取决于具体情况。这次一个很好的折中办法是选择 λ=1 ,以 p(x)/q(x) 的比值作为自己的变量,对照这个近似值作图,我们得到如下正定图:

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

作者图片

因此,反向 KL 散度近似的最终形式是:

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

作者图片:最终缩减方差无偏反向 KL 散度近似值

下次你试图通过抽样来测量两个分布之间的差异时,请记住这些近似值!

如果您觉得这篇文章有用,请考虑:

推广的方式,我真的希望你觉得这篇文章有趣,让我知道你的想法!!

参考

http://joschu.net/blog/kl-approx.html约翰·舒尔曼的《逼近 KL 散度》

接近 Neo4j 的中间中心性分数——对速度的需求

原文:https://towardsdatascience.com/approximating-neo4js-betweenness-centrality-scores-the-need-for-speed-27371d37a559?source=collection_archive---------54-----------------------

现在,我把我的 96,000 核心超级计算机放在哪里了?

想象一下,有一天早上你醒来,你对自己说:

嗯,如果我可以计算昨天我们加载到 Neo4j 中的 100 个 mio 节点的中间中心性得分,这不是很棒吗,它代表了我们公司的电子邮件流量。天哪,从信息流的角度来看,这肯定有助于我们识别关键员工。
是的,让我们开始工作吧!

你可能会问自己的下一个问题是:“现在,我把我的 96,000 核心超级计算机放在哪里了?”除非你是 Ziyad AlGhamdi(T4)研究团队的一员,否则你会很快记起你所拥有的是 16 个内核。

许多组织经常用 1 亿甚至几十亿个节点来编制图表,这些节点代表产品网络、共同购买、电子邮件流量等。并且在这些图形上执行中心性分析的能力是必不可少的。

然而,对于许多中心性指标,如中间中心性接近中心性得分,精确算法的计算复杂性 非常昂贵
例如,Cohen 等人在*”*计算经典接近中心性中说明,在规模中,使用标准计算资源计算 2400 万个节点的网络上的接近中心性需要惊人的 44222 个小时,或者大约 5 年来计算。

*https://dl.acm.org/doi/abs/10.1145/2660460.2660465

在这篇文章中, Mark Needham 和我将说明如何使用一个 定制机器学习模型 来近似 Neo4j 中大型图的中间中心性分数。

使用 Neo4j

Neo4j 图形数据科学库有不少于 7 个中心性得分,其中有一个重要但昂贵的中间中心性。该算法应用了 Brandes 算法,可以使用以下命令从 GDS 库中调用该算法:

CALL gds.betweenness.stream(
{ nodeProjection: "Node", relationshipProjection: "EDGE" }) 
YIELD nodeId, score 
RETURN nodeId, score 
ORDER BY score DESC

使用这些 Neo4j 中心性算法,正如我们在以前的文章中所阐述的; “启动你的中心性度量引擎:Neo4j vs NetworkX——各种形式的短程加速赛… *”,*仍然是计算中心性得分的最有效方式之一,但正如所强调的,当图的大小增加时,运行时间也以指数方式增加,因此需要速度。

使用机器学习模型

近似中心性度量的另一种方法是使用机器学习方法,其中我们在一个小图上训练一个模型,然后将其应用于更大的图

假设如下:通常,许多组织的数据库中会有一个图,它或者是一个更大的图的样本,或者是这样一个更大的图的代表。

这种设置的一个例子是对等网络;Gnutella。
这些数据集可以在斯坦福 SNAP 存储库中找到,由 9 个已发布的网络组成,节点数量从 6300 个到 63000 个不等。
同样,我们的目标是预测介数中心性,在这个实验中,我们将使用最小的 Gnutella 网络进行训练,一旦我们有了训练好的模型,就可以预测该数据集中更大图形的介数中心性得分。

基本原理是,这种方法不是生成一组随机训练图,而是使用一个与测试图具有相同拓扑属性的真实世界图,并使用留一交叉验证 (LOOCV)作为模型学习映射的重采样方法。

模型架构

我们的首要任务是通过神经网络为处理“准备”图表。为此,我们使用了 NetworkX Python 包,这是一个构建和分析图的有效工具,如提取邻接矩阵等。

一旦我们对图表进行了预处理,我们就可以把它输入到我们的神经网络中。

概括地说,(人工)神经网络由人工神经元组成,这些神经元通过链接连接,而链接又以数字权重为特征。然后,一个神经网络通过反复调整这些权重来学习

我们部署的神经网络是一个简单的多层感知器(MLP),但有一个转折:模型的输入变量是一个嵌入矩阵,我们使用了戴等人建立的 Struc2Vec 节点嵌入技术

在我们的例子中,嵌入矩阵由节点嵌入组成,由向量表示。一旦这样的嵌入矩阵被编译,我们通过两个完全连接的层运行它,并使用 Keras 早期停止方法来控制历元的数量。我们可以这样设想:

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

图片摘自 Aqib 等人

所有代码都在 TensorFlow 2.2.3 & Keras 中,可以在下面找到:

https://colab.research.google.com/drive/1m3FBa2KgYxmkLo182wNiOzKF0C3Qbki3?usp=sharing

从 Neo4j 加载图形

我们假设图形在 Neo4j 中,并调用 Neo4j Python 驱动程序通过以下命令获取图形:

from neo4j import GraphDatabase 
import networkx as nx driver = GraphDatabase.driver 
("bolt://localhost:7687", auth=("neo4j", "<password>")) query = "MATCH (n)-[r]->(c) RETURN *"results = driver.session().run(query) G = nx.DiGraph() nodes = list(results.graph()._nodes.values()) 
for node in nodes: 
    G.add_node(node.id, labels=node._labels) rels = list(results.graph()._relationships.values()) 
for rel in rels: 
    G.add_edge(rel.start_node.id, rel.end_node.id, key=rel.id,
              type=rel.type) print(nx.info(G))

如代码片段所示:一旦我们在本地机器上加载了图,我们就调用 NetworkX 来构造一个图,从这里我们可以开始我们的工作。

首先,对于 Struc2Vec 方法,我们产生了归一化度中心性值,它与图的邻接矩阵相结合,允许每个节点由一个嵌入向量来表示。也就是说,它需要一个节点的特定信息,它的,以及这个特定节点的邻居的嵌入来构造这样一个向量。我们可以将工作流程可视化如下:

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

模型工作流程(图片摘自德门多卡等人)

用数学术语来说,该工作流形式化为:

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

其中 d 是度向量W 是权重矩阵 。然后,最后出来的香肠是一个嵌入矩阵, H ,它将为我们的神经网络提供输入。

至于神经网络,没有什么特别奇特的:我们有一个简单的输入层,接受形状(6301 x 512)的嵌入矩阵,还有一个输出层,中间有两个完全连接的层,它们创建权重矩阵,其中每一层都使用***【Relu】***激活函数。由于它是一个 单变量回归模型 ,我们将一个只有一个神经元的全连接层作为最终层。

训练模特

如前所述,在这个实验中,我们使用了不同的训练协议

我们没有生成旨在捕捉真实世界图的拓扑结构的随机训练图,而是使用一个更小的真实世界图(要么是一个样本,要么是一个简化的表示),并使用留一交叉验证 (LOOCV)方法来训练模型。

LOOCV 方法包括将观察值集合分割成元组,其中单个观察值、 (x1,y1) 用于验证集合,而剩余的观察值 {(x2,y2)…。、(x_n,y_n)} 组成训练集。

然后,将该模型拟合到 n-1 个训练观测值上,并使用其值 x 1 对排除的观测值进行预测 y 。在我们的例子中, x1 表示使用 Struc2Vec 方法获得的嵌入向量

这种方法的好处是它捕获了我们想要预测的图的精确拓扑。一旦我们对模型进行了训练,我们就可以计算任何新的、更大的图上的嵌入矩阵,为此我们想要估计节点的中间中心度

该模型的训练被证明是非常有效的,其中使用 Keras Earlystopping 回调在 30 个时期停止训练,对于 Gnutella 网络中最小的图(具有 6,301 个节点),只需要不到 10 分钟的训练(在 Google Colab 上),并且导致了较低的丢失率,如下图所示。

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

有多准确?

为了测量预测的归一化介数值(和节点的排序)产生可信的结果,我们使用了肯德尔τ距离度量。此指标比较两个列表的相似程度,1 分表示两个列表完全匹配。

经过 30 个纪元的训练,我们获得了 0.783 的肯德尔 Tau 分数。

考虑到我们训练模型的速度如此之快,这是一个相当高的分数,肯定比范等人通过他们的中间性深度排名器(DrBC)模型获得的结果更好,其中前 10%的 Kendall Tau 的分数范围为 0.64 到 0.77。

近似介数分数

下一步,我们可以使用这个训练好的模型来预测 Gnutella 集合中具有 62,586 个节点的最大图的介数中心性分数。

我们需要做的唯一预处理是用 Struct2Vec 计算嵌入矩阵,它将成为我们神经网络的输入变量。

该工作流只是需要从训练工作流中复制的几个步骤:我们将图加载到模型中,并再次使用 NetworkX 包来构造图,在此基础上 Struc2Vec 函数产生嵌入矩阵。有了我们的训练模型,我们只需要进行几次 TensorFlow 调用就可以得到预测:

#re-loading model:path_model = ‘/content/drive/MyDrive/Colab_files/GN08_model.h5’model = tf.keras.models.load_model(path_model)x_new = mu_all #where mu_all is the embedding matrix computed by 
                Struc2Vecy_pred = model.predict(x_new)

将预测的中间值写回 Neo4j

现在我们已经获得了预测的介数分数,我们可以将它们写回到 Neo4j 中更大的图中。这将允许我们在 Neo4j 中进行各种图形查询,例如,帮助我们识别那些关键员工。为此,我们再次调用 Neo4j Python 驱动程序,并使用我们心爱的熊猫,执行以下 Python 代码:

from neo4j import GraphDatabase 
import pandas as pd 
import os driver = GraphDatabase.driver("bolt://localhost:7687",
                              auth=("neo4j", "<password>")) cwd = os.getcwd() 
file_path = ‘y_pred’ 
save_path = os.path.join(cwd, file_to_save) 
path = os.path.join(cwd, file_path) df = pd.DataFrame(y_pred) 
df.index.names = [‘id’] 
df.columns = [‘Betweenness’] 
df[‘NodeId’] = df.index 
df_list_nodes = df.values.tolist() q =""" 
UNWIND $nodes AS line 
MATCH (f:Node {id:toInteger(line[1])}) 
Set f.Betweenness = line[0] 
Return Count(*)"""with driver.session() as session: 
    result = session.run(q, {“nodes”: df_list_nodes })

结论

在这篇文章中, Mark Needham 和我试图说明,当速度是关键,一个好的近似就足够了,那么相对简单的机器学习模型可以部署为*&play工具,通过使用 Neo4j Python 驱动程序可以扩展当前 Neo4j 图形数据科学功能。

四月版:主题建模的冒险

原文:https://towardsdatascience.com/april-edition-adventures-in-topic-modelling-7ee9081a48a0?source=collection_archive---------23-----------------------

月刊

超越情感分析

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

照片由苏西·黑兹伍德派克斯拍摄

计算机非常擅长处理结构化数据,如电子表格和数据库表格。但由于人类大多使用语言和文字交流,这对计算机来说是不幸的。世界上的许多信息都是非结构化的,例如,英语或其他语言的原始文本。如何才能让计算机理解非结构化文本,并从中提取信息?

自然语言处理(NLP)是人工智能的子领域,专注于使计算机能够理解和处理人类语言。如果你是数据科学的新手,你会发现有大量的资料涵盖了各种与 NLP 相关的任务。我见过的最常见的 NLP 博客帖子都与情感分析有关。也就是说,检测一段文本表达的是积极的还是消极的情绪。但是存在更多的 NLP 问题。

我想提请大家注意主题建模,这是 NLP 中的一个领域,我最近开始对它产生了浓厚的兴趣。主题建模使用单词在文档集合中的分布来识别单词出现的潜在模式。输出是一组主题,由根据特定模式在这些文档中同时出现的单词簇组成。

为什么我觉得主题建模很有趣?因为现在比以往任何时候都更重要的是,它不仅关乎我们的感受,还关乎我们所说的内容。结合起来,情感分析和主题建模可以用来执行所谓的基于方面的情感分析,其目标是提取文本中描述的实体和对这些实体表达的情感。

对于企业来说,通过探索客户对您的服务或产品的特定部分的反应而获得的优势可以帮助支持业务用例,包括产品开发和质量控制、通信、客户支持和决策过程。这比仅仅知道你的客户是高兴还是不高兴要多得多的信息,它可以帮助支持你的业务不断发展和改进。

《走向数据科学》的编辑助理劳里·威廉姆斯

与 BERTopic 的交互式主题建模

使用 BERTopic 进行主题建模的深入指南

马腾·格罗登斯特 — 7 分钟读完

话题造型文章与 NMF

抽取主题是发现文本之间潜在关系的一种很好的无监督数据挖掘技术。

罗布·萨尔加多 — 12 分钟阅读

潜在狄利克雷分配(LDA)主题建模教程

这是一本实用指南,包含经过实践检验的 Python 代码。找到人们在推特上谈论的内容。

米歇尔·卡纳博士 — 5 分钟阅读

使用 Scikit 的主题建模简介-学习

探索 3 种无监督技术,从文档中提取重要主题

通过 Ng Wai Foong — 10 分钟读取

理解自然语言处理和主题建模第一部分

我们探索如何通过自然语言处理提取主题帮助我们更好地数据科学

饶彤彤 — 8 分钟读出

使用 PyCaret 在 Power BI 中进行主题建模

在这篇文章中,我们将看到如何使用 PyCaret 在 Power BI 中实现主题建模。

通过 Moez Ali — 7 分钟读取

主题建模:超越令牌输出

关于如何给题目赋予有意义的标题的调查

劳里·威廉姆斯 — 9 分钟阅读

话题造型与 PLSA

PLSA 或概率潜在语义分析是一种用于在概率框架下对信息建模的技术。

Dhruvil Karani — 5 分钟阅读

情感分析:基于方面的观点挖掘

情感分析和主题建模技术的研究。

作者劳里·威廉姆斯 — 8 分钟阅读

使用 NLTK 和 Gensim 在 Python 中进行主题建模

在本帖中,我们将学习如何识别文档中讨论的主题,这称为主题建模。

苏珊李 — 6 分钟读完

新播客

我们也感谢最近加入我们的所有伟大的新作家:薇薇安·迪法兰斯科莫尼卡·因德拉万瓦盖努尼·穆罕默德莱恩·萨德勒肯德里克·吴索罗什·萨法伊亚历山德拉·苏利甘特·拉博德阿比·塞尼https://medium.com/u/6ca0fe37eac1?source=post_page-----7ee9081a48a0-------------------------------- 马哈茂德·哈穆希阿贾伊·阿鲁纳恰拉姆马克西姆·齐亚丁诺夫萨贾德·舒马利胡安·塞缪尔塞尔希·波斯皮洛夫费尔南多·卡里略扬恩·莫里泽塞巴斯蒂安·卡里诺彭艳 https://medium.com/u/90bafa597f29?source=post_page-----7ee9081a48a0-------------------------------- 季米特里斯·戴斯朱利安·哈茨基埃文斯·多伊·奥坎西普拉瓦兰·卡兰吉特伊克巴尔·阿里斯蒂芬·赫鲁达-拉斯姆森迈克·卡萨勒马哈姆·费萨尔汗我们邀请你看看他们的简介,看看他们的工作。

关联规则学习的 Apriori 算法——如何发现事务间的清晰联系

原文:https://towardsdatascience.com/apriori-algorithm-for-association-rule-learning-how-to-find-clear-links-between-transactions-bf7ebc22cf0a?source=collection_archive---------3-----------------------

机器学习

Python 中关系数据库的频繁项集挖掘和关联规则学习的解释和示例

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

关联规则学习。由 5 个项目(A,B,C,D,E)构成的所有可能的项目集。图片由作者提供。

介绍

你们中的大多数人可能已经熟悉了聚类算法,如 K-MeansHACDBSCAN 。然而,聚类不是发现数据点之间相似性的唯一非监督方式。您还可以使用关联规则学习技术来确定某些数据点(动作)是否更有可能一起出现。

一个简单的例子是超市购物篮分析。如果有人在买碎牛肉,这是否会让他们更有可能也买意大利面?我们可以通过使用 Apriori 算法来回答这类问题。

内容

  • Apriori 算法所属的类别
  • 关联规则学习介绍和 Apriori 算法工作原理的直观解释
  • 使用真实数据的 Apriori 算法的 Python 示例
  • 结论

Apriori 属于哪一类算法?

如前所述,Apriori 是关联规则学习算法的一部分,属于机器学习的无监督分支。

这是因为先验并不要求我们为模型提供一个目标变量。相反,该算法根据我们指定的约束来识别数据点之间的关系。

下图是交互式的,所以请点击不同的类别来放大并展示更多的👇。

机器学习算法分类。由作者创建的互动图表。

如果你喜欢数据科学和机器学习 ,请 订阅 每当我发布一个新故事时,你都会收到一封电子邮件。

关联规则学习和 Apriori 算法

关联规则学习

如简介中所述,关联规则学习是一种基于规则的机器学习方法,用于发现大型数据库中变量之间的有趣关系。我们用一个简单的超市购物篮分析来说明关联规则是如何发现的。

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

购物者的超市购物清单。图片由作者提供。

假设我们分析上述交易数据,找出经常购买的商品,并确定它们是否经常一起购买。为了帮助我们找到答案,我们将利用以下 4 个指标:

  • 支持
  • 信心
  • 电梯
  • 定罪

支持

我们和算法的第一步是找到经常购买的物品。这是一个基于频率的简单计算:

**Support(A)** = Transactions(A) / Total Transactions

所以在我们的例子中:

**Support(Eggs)** = 3/6 = 1/2 = 0.5
**Support(Bacon)** = 4/6 = 2/3 = 0.667
Support(Apple) = 2/6 = 1/3 = 0.333
...
**Support(Eggs&Bacon)** = 3/6 = 0.5
...

在这里,我们可以通过告诉算法我们想要探索的最小支持级别来设置我们的第一个约束,这在处理大型数据集时非常有用。我们通常希望集中计算资源来搜索经常购买的商品之间的关联,同时忽略不经常购买的商品。

为了我们的例子,让我们将最小支持设置为 0.5 ,这使得我们在这个例子的剩余部分中处理鸡蛋和熏肉。

**重要:**虽然 Support(Eggs)和 Support(Bacon)单独满足我们的最小支持约束,但理解我们还需要它们的组合(Eggs & Bacon)来通过这个约束是至关重要的。否则,我们不会有一个条目配对来创建关联规则。

信心

现在我们已经确定了经常购买的商品,让我们来计算置信度。这将告诉我们(基于我们的数据)有多大的信心,我们可以相信一个项目将被购买,因为另一个项目已经被购买。

**Confidence(A→B)** = Probability(A & B) / Support(A)Note, confidence is the same as what is also known as conditional probability in statistics:
P(B|A) = P(A & B) / P(A) *Please beware of the notation. The above two equeations are equivalent, although the notations are in different order:* ***(A→B)*** *is the same as* ***(B|A).***

因此,让我们为我们的例子计算置信度:

**Confidence(Eggs→Bacon)** = P(Eggs & Bacon) / Support(Eggs) = (3/6) / (3/6) = 1**Confidence(Bacon→Eggs)** = P(Eggs & Bacon) / Support(Bacon) = (3/6) / (2/3) = 3/4 = 0.75

以上告诉我们,无论什么时候买鸡蛋,培根也是 100%的时候买。还有,无论什么时候买培根,75%的时候都是买鸡蛋。

电梯

鉴于不同的商品以不同的频率被购买,我们如何知道鸡蛋和培根真的有很强的关联,我们如何衡量它?你会很高兴听到我们有办法使用 lift 客观地评估这一点。

计算升力的公式有多种表达方式。让我先展示一下公式是什么样子的,然后我会描述一种直观的方式让你思考。

**Lift(A→B)** = Probability(A & B) / (Support(A) * Support(B))You should be able to spot that we can simplify this formula by replacing P(A&B)/Sup(A) with Confidence(A→B). Hence, we have:**Lift(A→B)** = Confidence(A→B) / Support(B)

让我们计算相关物品的升力:

**Lift(Eggs→Bacon)** = Confidence(Eggs→Bacon) / Support(Bacon) = 1 / (2/3) = 1.5**Lift(Bacon→Eggs)** = Confidence(Bacon→Eggs) / Support(Eggs) = (3/4) / (1/2) = 1.5

这两个项目的升力等于 1.5。注意,lift>1 表示两件商品更有可能一起买,lift<1 表示两件商品更有可能分开买。最后,lift=1 意味着这两个项目之间没有关联。

理解这一点的直观方法是首先考虑鸡蛋被购买的概率:P(Eggs)=Support(Eggs)=0.5因为 6 个购物者中有 3 个购买了鸡蛋。

然后想想每当买熏肉时买鸡蛋的概率:P(Eggs|Bacon)=Confidence(Bacon->Eggs)=0.75因为买熏肉的 4 个顾客中,有 3 个也买了鸡蛋。

现在,lift 只是一个简单的度量,它告诉我们在购买培根的情况下,购买鸡蛋的概率是增加了还是减少了。由于在这种情况下购买鸡蛋的概率从 0.5 上升到 0.75,我们看到 1.5 倍的正提升(0.75/0.5=1.5)。这意味着,如果你已经把熏肉放进篮子里,你购买鸡蛋的可能性会增加 1.5 倍(即 50%)。

*看看你的超市附近有没有这两样东西。*😜

定罪

信念是衡量联想的另一种方式,尽管要理解它有点困难。它比较了 A 在没有 B 的情况下出现的概率(如果它们是独立的)和 A 在没有 B 的情况下出现的实际频率,我们先来看看通用公式:

**Conviction(A→B)** = (1 - Support(B)) / (1 - Confidence(A→B))

在我们的示例中,这将是:

**Conviction(Eggs→Bacon)** = (1 - Sup(Bacon) / (1 - Conf(Eggs→Bacon)) = (1 - 2/3) / (1 - 1) = (1/3) / 0 = infinity**Conviction(Bacon→Eggs)** = (1 - Sup(Eggs) / (1 - Conf(Bacon→Eggs)) = (1 - 1/2) / (1 - 3/4) = (1/2) / (1/4) = 2

如您所见,在计算(鸡蛋→培根)的确信度时,我们除以 0,这是因为我们没有一个鸡蛋被购买而没有培根的实例(置信度=100%)。

一般来说,对 A→B 的高信任度和对 B 的低支持度会产生高确信度。

与解除相反,定罪是一种直接的措施。因此,虽然 lift 对于(鸡蛋→培根)和(培根→鸡蛋)来说是相同的,但两者之间的信念是不同的,Conv(鸡蛋→培根)要高得多。因此,你可以使用信念来评估你的项目之间的方向关系。

最后,与 lift 类似,confidence = 1 表示项目没有关联,而 confidence > 1 表示项目之间的关系(值越高,关系越强)。

Apriori 算法

Apriori 是一种非常简单的算法,它执行以下一系列计算:

  1. 计算大小为 1 的项集的支持度。
  2. 应用最小支持阈值并删除不符合阈值的项集。
  3. 移动到大小为 2 的项目集,重复步骤 1 和 2。
  4. 继续相同的过程,直到找不到满足最小阈值的其他项目集。

为了使该过程更加直观,下面的图表说明了该算法的作用:

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

Apriori 算法的进程树。图片由作者提供。

如您所见,本例中的大多数项目集都被删除了,因为它们没有达到 0.5 的最小支持阈值。

重要的是要认识到,通过设置更低的最小支持阈值,我们将产生更多大小为 2 的项目集。准确地说,在最小支持阈值为 0.3 的情况下,大小为 1 的项集都不会被删除,因此大小为 2 的项集总共有 15 个(5+4+3+2+1=15)。

当我们有一个小的数据集时,这不是一个问题,但是如果你正在处理一个大的数据集,这可能成为一个瓶颈。例如,1,000 个项目可以创建多达 499,500 个项目对。因此,仔细选择你的最低支持阈值。

注意,如果你想要更多的例子,你可以参考封面图片,它显示了所有可能的项目集,这些项目集可以由 5 个单独的项目组成。

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

使用真实数据的 Apriori 算法的 Python 示例

现在让我们抛开理论,用 Python 对现实生活中的数据进行分析。

设置

我们将使用以下数据和库:

让我们导入所有的库:

然后我们从 Kaggle 下载Market _ Basket _ optimization . CSV并获取数据:

数据看起来是这样的:

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

超市购物篮数据的片段。图片由作者提供。

探测

在我们运行关联规则分析之前,让我们先来看看项目的频率分布。

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

购买超市商品的频率计数片段。图片由作者提供。

我们可以看到,矿泉水(1788 英镑)是这家超市最受欢迎的商品,其次是鸡蛋(1348 英镑)、意大利面(1306 英镑)、薯条(1282 英镑)和巧克力(1230 英镑)。同时,可怜的老芦笋只被买过一次。

此外,值得注意的是,即使是最常购买的商品也只出现在略高于 6%的交易中。当设置最小支持阈值时,我们可以使用该信息作为指导。

让我们也在条形图中显示频率分布。

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

购买超市商品的频率分布。图片由作者提供。

运行 Apriori 算法

在我们运行算法之前,让我们把数据放入要求的格式中。这将是一个列表列表,其中所有你在熊猫数据帧中看到的“nan”都被删除了。

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

列表的事务列表的片段。图片由作者提供。

最后,让我们运行 Apriori 算法并保存项目集和关联规则。

该算法发现了 36 个大小为 1 的项目集和 18 个大小为 2 的项目集,它们满足 0.03 的最小支持阈值。这些显示如下。

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

满足最小支持度阈值约束的所有项目集。图片由作者提供。

现在让我们打印算法找到的关联规则。注意,一些集合在规则生成阶段被排除,因为它们不满足我们指定的最小置信度要求(在本例中,min_confidence=0.2)。

上面的代码打印了满足我们的约束条件的所有关联规则,这些约束条件按最高提升和信念排序:

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

27 关联规则产生的 Apriori 算法基于我们的约束。图片由作者提供。

正如我们所看到的,真实数据中提升最高的是碎牛肉和意大利面的组合。然而,碎牛肉的购买者更有可能同时购买意大利面条(信心:0.399,确信:1.374),而不是相反(信心:0.225,确信:1.164)。

总而言之,看起来这家超市的游客是意大利肉酱面和矿泉水的忠实粉丝。

结论

Apriori 是一种简单的算法,可以快速学习项目(数据点)之间的关联规则。虽然我已经向您介绍了它在购物篮分析中的应用,但它还有许多其他实际应用,包括生物信息学(蛋白质测序)、医学诊断(症状和疾病之间的关系)或人口普查数据分析。

在大型数据集上使用 Apriori 时需要注意的一点是最小支持阈值的选择。如果不小心的话,可能会因为大量大小为 2 的项集而很快耗尽内存。

我希望您和我一样发现了先验和关联规则学习。感谢您的阅读,如果您有任何问题或建议,请随时联系我们!

干杯!👏
索尔·多比拉斯

如果你已经花光了这个月的学习预算,下次请记得我。 我的个性化链接加入媒介是:

https://solclover.com/membership

您可能感兴趣的相关文章:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值