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

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

数据域和数据产品

原文:https://towardsdatascience.com/data-domains-and-data-products-64cc9d28283e?source=collection_archive---------5-----------------------

行业笔记

实践中的数据网格

我接触的所有客户要么对下一代现代数据平台感兴趣,要么正在规划。在这一转变中,数据网格体系结构获得了很大的吸引力。与此同时,对这一概念的解释也存在一些担忧:缺乏实际指导。

关于数据网

Data mesh 提倡将数据视为一种产品,将所有权更深入地推向生产团队。这背后的理论是所有权与数据创建更好地结合,这为数据带来了更多的可见性和质量。这种责任的左移解决了数据爆炸的问题,数据爆炸使得不堪重负的中央数据团队为了更大的利益负责清理、协调和集成数据。将特定数据集的职责委托给数据域意味着企业被拆分为小型企业,每个企业负责构建抽象、提供数据、维护相关元数据、提高数据质量、应用生命周期管理、执行代码控制等等。尤其是传统的大规模企业很难适应这种现代方法,因为数据通常在域之间共享,或者一个域的数据可能依赖于另一个域。这使得实施变得困难,所以让我提出我的观点并分享一些实用的指导。

指导

标准化和清晰的原则是实现成功的关键。例如,数据产品不应该成为实验的对象。它们也不应该引发标准、文件类型、协议格式等等的激增。因此,我建议任何组织采纳以下十八项原则:

1。 明确界定你的领域边界

每个人都使用他们自己的域、子域或有界上下文的定义。这种模糊性是一个问题。没有明确的指导,领域变得过于相互关联,所有权成为解释的主题,复杂性将被其他领域推入其他领域。

我对域管理的建议是明确和严格的边界。每个域的边界必须清晰明确。属于一起的业务关注点、流程、解决方案领域和数据必须保持在一起,并在域内进行维护和管理。理想情况下,每个领域属于一个敏捷或 DevOps 团队,因为当有一个团队时,耦合点的数量是可管理的,并且容易被所有团队成员理解。在一个域内,紧耦合是允许的;然而,当跨越边界时,到其他域的所有接口必须使用互操作性标准来解耦。这就是数据产品发挥作用的地方。

话虽如此,对于数据管理,我鼓励您将您的领域具体化。这避免了长时间的(政治)讨论,也禁止团队根据他们自己的需要自由地解释边界。向面向领域结构的转变是一种过渡。当您将新的提供者和消费者加入到您的体系结构中时,您可以有组织地制定您的域列表,而不是预先规划好一切。

例如,对于数据域列表,您可以使用列出所有数据域的存储库,包括每个域的命名和适用性。您可以使用相同的存储库来描述团队组织、使用和共享,以及物理表现:应用程序和数据库的列表。

另一篇以边界和粒度为特色的博文可以在这里找到:https://towardsdatascience . com/data-domains-where-do-I-start-a 6d 52 fef 95d 1

2。 具体阐述您的数据产品和互操作性标准

下一个建议是定义什么是数据产品。数据产品是数据架构的一个单元或组件,它封装了使读取优化数据集可供其他域使用的功能。这需要你明确定义自己不同的发布类型(例如,面向批处理、面向 API、面向事件)、元数据标准等等。具体说明数据产品是什么样子的。例如,批量数据产品被定义为拼花文件,并且总是必须包含一个用于元数据的 YML 文件,该文件包含这些 X 属性。例如,我不相信报告和仪表板是数据产品,因为它们解决特定的客户需求,因此与底层用例紧密耦合。

3。 没有原始数据!

数据产品与原始数据相反,因为公开原始数据需要所有消费领域的返工。因此,在任何情况下,您都应该封装遗留或复杂的系统,隐藏技术应用程序数据。这也意味着域将拥有如何转换数据以提高可读性的转换逻辑。

没有原始数据的原则,你也可以申请外部数据提供者:在你的企业生态系统的逻辑边界之外运作的外部方。它们通常位于独立的、不受控制的网络位置。要求您的合作伙伴遵守您的标准或通过额外的域应用中介:消费团队通过抽象复杂性和保证稳定和安全的消费来充当提供者。

原始或未经修改的数据没有保证。如果你坚持让它可用,比如机器学习,确保它被标记。

4。 为重叠域定义模式

如我所说,对于跨域共享的数据,事情变得复杂了。对于数据域的粒度和逻辑分段,您可以利用来自域数据存储的指导:

当域比较大,或者域需要通用的——可重复的——集成逻辑时,分解域尤其重要。在这种情况下,拥有一个通用域会有所帮助,它可以提供集成逻辑,允许其他子域标准化并从中受益。一个基本规则是保持子域间的共享模型较小,并始终与无处不在的语言保持一致。

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

由 Piethein Strengholt 创建的图像

对于重叠的数据需求,您可以使用不同于领域驱动设计的模式。以下是对这些模式的简短总结:

  • 如果复制的相关成本优先于可重用性,那么作为一种设计模式,可以使用单独的方法。当为了更高的灵活性和敏捷性而牺牲可重用性时,这种模式通常是一种选择。
  • 如果一个领域很强大,并且愿意拥有下游消费者的数据和需求,那么可以使用客户-供应商模式。这种模式的缺点是相互冲突的关注点,迫使下游团队协商可交付成果和安排优先级。
  • 伙伴关系模型中,集成逻辑在新创建的域中以特别的方式进行协调。所有团队都相互合作,尊重彼此的需求。每个人都需要一个大的承诺,因为每个人都不能自由地改变共享的逻辑。
  • 一个符合模式可以被用来使所有的域符合所有的需求。这种模式可以是一种选择:1)当集成工作极其复杂时;2)不允许任何其他方拥有控制权;3)或者当使用供应商包时。

在任何情况下,您的域都必须遵守您的互操作性标准。因此,为其他域生成新数据的合作伙伴域必须像任何其他域一样公开它们的数据产品。

5.数据产品包含可供广泛消费的数据。

不同的领域团队和各种用例很可能会重复使用相同的数据。因此,您的团队不应该让他们的数据产品符合数据消费者的特定需求。主要的设计原则应该是最大化领域生产力和促进消费。另一方面,数据产品基于用户反馈而发展,并为其生成相关的工作,因此团队可能会很想合并消费性的特定需求。你在这里应该非常小心!如果消费者将特定于消费者的业务逻辑推进到所有数据产品中,就会迫使所有数据产品同时发生变化。这可能引发所有团队成员之间激烈的冲刺目标交叉协调和积压谈判。我的建议是引入一些争议管理:一个监管机构,监督数据产品不是针对消费者的。这个机构可以介入指导领域团队,组织预约和知识共享会议,提供实际的反馈并解决团队之间的问题。

6。 创建关于缺失值、默认值和数据类型的具体指南

我经历过关于必须如何解释缺失和默认数据的激烈辩论。例如,数据确实丢失并且无法导出,但是运营部门仍然期望由员工提供强制数据值。如果不提供指导,将会产生大量的描述和指导。有些可能始终提供不正确的值,有些可能提供随机值,而有些可能根本不提供指导。这同样适用于详细的局部参考值和数据类型。因此,您可能希望引入有关数据的指导,这些数据必须在整个数据集中具有一致的默认值和格式。这也意味着相同的十进制精度、符号和语法,解决了数据消费者不必应用(复杂的)应用程序逻辑来获得正确数据的问题。您可以将这些原则设置为面向系统或面向领域的,但是我也看到大型企业在所有数据产品中必须使用什么数据格式和类型方面提供通用指导。

7。 数据产品在所有交付方法中都是语义一致的:批处理、事件驱动和基于 API 的

对我来说,这听起来是显而易见的,但我仍然看到今天的公司为面向批处理、事件和 API 的数据制定单独的指南。由于所有分布模式的数据来源都是相同的,所以我鼓励您使所有的指南对所有的模式都一致。你可以要求你的所有领域使用一个单一的数据目录来描述所有的术语和定义。这一单一来源成为链接(映射)所有不同数据产品的基线。

8。 数据产品继承了无处不在的语言

了解数据创建的背景是非常重要的。这就是无处不在的语言的用途:一种构建的、形式化的语言,由利益相关者和设计师达成一致,服务于我们的设计需求。无处不在的语言应该与领域保持一致:业务功能和目标。我看到一些公司要求域使用该域语言中人类友好的列名。对我来说,这并不重要,只要提供了从物理数据模型到业务数据模型的映射。这使得您的领域能够将业务概念从无处不在的语言转换成数据。

9。 数据产品属性是原子的

数据产品属性是原子的,必须表示最低级别的粒度,并具有精确的含义或精确的语义。在理想状态下,这些数据属性与数据目录中的项目一一对应。这样做的好处是,数据消费者不会被迫拆分或连接数据。

10。 数据产品从创建的那一刻起就保持兼容

数据产品保持稳定,并与运营/交易应用程序分离。这意味着模式漂移检测,所以没有破坏性的变化。它还意味着版本控制,在某些情况下,独立管道并行运行,让您的数据消费者有时间从一个版本迁移到另一个版本。

11。 将易变参考数据抽象为更小粒度的值范围

您可能希望提供关于如何将复杂的参考值映射到更抽象的数据产品友好的参考值的指导。该指南还要求对敏捷性不匹配有一个细微的差别:1)如果使用方的变更速度很快,您的指导原则必须是在使用方维护复杂的映射表。2)如果变化的速度在提供方,指导原则是要求数据产品所有者将详细的本地参考值抽象或汇总为更通用的消费者不可知参考值。这也意味着消费者可能执行额外的工作,例如,将更通用的参考值映射到消费特定的参考值。

12。 为可读性而优化(转换):抽象出复杂的应用模型。

不断重新训练、不断读取大量数据的分析模型。这个读取方面会影响应用程序和数据库设计,因为我们需要优化数据可读性。同样,您可以引入优化和数据可读性的原则。例如,要求领域定义子产品:围绕主题领域有逻辑组织和混乱的数据。面向资源的架构(ROA)可能是一个很好的灵感。指南还将包括,过于标准化或过于技术化的物理模型必须转化为更可重用和逻辑有序的数据集。必须对复杂的应用程序逻辑进行抽象,并且必须以足够的粒度获取数据,以服务尽可能多的消费者。这也可能意味着交叉引用和外键关系必须是整数,并且在整个数据集中以及与来自同一数据产品提供商的所有其他数据集中保持一致。消费域不应该操纵键来连接不同的数据集!

13。 数据产品是从源头直接捕获的

不应该允许域封装来自不同数据所有者的其他域的数据,因为这将混淆数据所有权。因此,数据产品必须直接从原始领域(源)创建。

14。 新创建的数据意味着新的数据产品

由于业务转换(使用业务逻辑的语义变化)而创建和分发的任何数据都被认为是新的,并导致新的数据和数据所有权。因此,您希望实施相同的数据分布原则。这意味着新创建的共享数据必须遵循这篇博文中概述的相同原则。

另一个关注点是可追溯性:知道数据发生了什么。为了降低透明度的风险,要求数据消费者对他们的获取以及他们应用于数据的操作和转换序列进行编目。这种沿袭元数据应该集中发布。

15。 为了安全封装元数据

对于包括细粒度消费在内的数据安全性,您需要定义一种数据过滤方法:保留的列名、封装的元数据、产品元数据等。例如,我看到一些公司在他们的数据产品中使用保留的列名。如果这样的保留列名存在于任何这些数据集中,它可以用于细粒度过滤。因此,只能允许访问非敏感数据,或者可以过滤数据。例如,可以为消费者创建虚拟视图。分类或标签也是如此。

16。 你可能想介绍一些企业一致性

有些人会认为这一指导无助于真正的数据网格实现,但我看到一些公司重视企业一致性。我想强调的是,您不应该构建企业规范数据模型,就像在大多数企业数据仓库架构中看到的那样。在一个大规模的组织中,引入一些企业一致性可能会有所帮助,在这样的组织中,许多域依赖于相同的参考值。因此,您可以考虑引入包含企业参考值的指南。例如,货币代码、国家代码、产品代码、客户细分代码等等。如果适用,您可以要求您的数据产品所有者将其本地参考值映射到企业列表中的值。

您可能会对主标识号给出相同的指导,它将主数据和来自本地系统的数据链接在一起。这些数据元素对于跟踪哪些数据已经被掌握以及哪些数据属于一起是至关重要的,因此您可以要求您的本地域在其数据产品中包含这些主标识符。

最后,只有当企业数据非常稳定并且确实重要时,才考虑使用本指南。企业数据元素的列表有限。是一打,不是几百。

17。 解决时变和非易失性问题

我看到一些公司通过规定数据产品必须如何交付以及如何在下游消费来解决时变和非易失性问题。例如,产品到达后会被版本化、比较、分叉为读取优化的文件格式,并转换为缓慢变化的维度,从而保留以前数据产品的所有历史数据。在所有情况下,数据仍然是面向领域的,因此在任何消费发生之前,不允许应用跨领域集成。

18。 使用数据产品蓝图

创建数据产品的策略是什么?应该通过一个平台来促进它,还是必须由域名来满足它们自己的需求?我的观点是,创造是一个互动的过程,可以得到最好的促进。如果您分散工作并努力实现领域自治,那么您可以通过设计和提供蓝图来实现平衡,这些蓝图包含集成和向不同领域提供数据所需的最基本的服务,同时为数据产品优化提供自治。您的蓝图可以为每个域或共享一些内聚力的一组域实例化。下面的模型是允许创建可伸缩数据产品的参考模型。

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

Piethein Strengholt 的形象设计

如果做得正确,这些蓝图可以被设计成这样一种方式,血统被自动下推到目录中。对于组合服务的粒度级别,可以使用不同的网状拓扑。一些公司重视高效的计算资源使用,或者认为大型数据消费者存在数据重力问题,因此更喜欢单一平台,同时仍然通过不同的容器隔离域。其他公司使用协调网状方法,并允许组织内的域运行自己的平台,同时遵守共同的政策和标准,就像上面的模型一样。有些采用能力复制来确保完全隔离。这很可能会增加成本,也是一个口味问题。

困难

按领域构建数据产品是一个很有前途的概念,最近得到了很多关注。它试图解决一些可伸缩性问题,但是企业需要意识到其中的陷阱。构建适当的数据抽象不适合胆小的人。技术上很难,应该很好的促成。以下检查表确保更好的数据所有权、数据可用性和数据平台使用:

  • 定义数据互操作性标准,例如协议、文件格式和数据类型。
  • 定义所需的元数据:模式、分类、业务术语、属性关系等。
  • 定义数据过滤方法:保留的列名、封装的元数据等。
  • 确定域、应用程序、组件等的划分粒度级别。
  • 新数据的设置条件:数据质量标准、数据结构、外部数据等。
  • 为数据分组、参考数据、数据类型等定义数据产品指南。
  • 定义需求契约或数据共享存储库。
  • 定义治理角色,例如数据所有者、应用程序所有者、数据管家、数据用户、平台所有者等。
  • 建立沿袭接收能力+定义沿袭交付程序+数据沿袭的唯一散列键。
  • 为每个域定义应用程序级、表级和列级的沿袭粒度级别。
  • 确定分类、标签、扫描规则
  • 定义数据消费的条件,例如通过安全视图、安全层、ETL 等。
  • 如何使用容器、文件夹、子文件夹等来组织数据湖。
  • 定义数据分析和生命周期管理标准,例如 7 年后移动等。
  • 为关键标识符、丰富过程等定义企业参考数据。
  • 为交易数据、主数据和参考数据定义日志和历史数据处理方法
  • 定义重新交付和协调的过程:数据版本化
  • 在技术选择上与企业架构保持一致:哪些领域允许哪些服务;哪些服务只保留给平台团队。

最后,分布式体系结构还将管理和所有权分布在整个组织中。您的团队变得端到端负责。做出有意识的选择,并非常详细地了解将要发生的事情。精确地说明哪些活动仍然是核心,以及对团队的期望是什么。

如果这是你喜欢的内容,我让你看看《规模化数据管理》这本书。

数据域—我从哪里开始?

原文:https://towardsdatascience.com/data-domains-where-do-i-start-a6d52fef95d1?source=collection_archive---------0-----------------------

行业笔记

设计企业级数据网络的战略途径

在我与企业进行的所有数据网格讨论中,数据域的主题最受关注。客户发现面向领域的数据所有权是数据网格中最难的部分。通常,对领域驱动设计缺乏基本的理解(DDD)。其他数据从业者发现 DDD 的概念太难理解,或者很难将来自软件架构或面向对象编程的例子投射到他们的数据领域。在这篇博文中,我将试着去掉复杂的词汇,为你提供实用的指导。

领域驱动设计

让我们从理论部分开始:领域驱动设计(DDD)是一种支持软件开发的方法,有助于描述大型组织的复杂系统,最初是由 Eric Evans 描述的。DDD 很受欢迎,因为它的许多高级实践对现代软件和应用程序开发方法(如微服务)产生了影响。

DDD 区分了有界上下文、域和子域。领域是我们试图解决的问题空间。它们是知识、行为、法律和活动汇集的地方。它们是我们看到语义耦合的领域:组件或服务之间的行为依赖。为了更好地管理复杂性,域通常被分解成子域。一个常见的例子是分解一个域,使每个子域对应一个特定的业务问题。

并非所有的子域都是相同的。例如,您可以将域分类为核心、通用或支持。核心子域是最重要的。它们是秘方,是配料,让生意变得独一无二。通用子域名是非特定的,通常很容易用现成的产品解决。支持子域名并不能提供竞争优势,但却是保持组织运转所必需的。通常,它们没有那么复杂。

有界上下文是逻辑(上下文)边界。他们关注解决方案空间:系统和应用程序的设计。在这一领域,关注解决方案空间是有意义的。在 DDD,这可以是代码、数据库设计等等。在域和有界的上下文之间,可以有对齐,但是将它们绑定在一起并没有硬性规定。有界上下文本质上通常是技术性的,并且可以跨越多个域和子域。

DDD 在数据管理方面的困难在于,DDD 最初的用例是在软件开发的背景下对复杂系统建模。最初,它从未被创造出来用于建模企业数据,这使得数据管理从业者的方法非常抽象和技术性。所以让我打个比方。把一个领域想象成一个共同感兴趣的领域。以你的房子和街道为例。街道是一个域,每个房子代表一个子域。每栋房子都有自己的房子,都有栅栏,这也意味着一栋房子不会占据整个房子。栅栏代表有界的上下文(责任模型)。房主负责维护他们的房子,并可以在他们的范围内做任何他们想做的事情。然而,当跨越边界(栅栏)时,有一些规则需要遵守。例如,当离开或进入你的房子时,总是使用公共车道。

如果我们将数据网格作为数据民主化的一个概念,并实现面向领域的数据所有权原则以获得更大的灵活性,这在实践中会如何工作?从企业数据建模到领域驱动设计建模的转变会是什么样的?我们可以从 DDD 的数据管理中学到什么?

对你的问题空间进行功能性业务分解

在允许团队端到端地操作他们的数据之前,我的第一个建议是查看范围并理解您试图解决的问题空间。在进入技术实现的细节之前,先做这个练习很重要。正如 DDD 所主张的,在这些问题空间之间设定逻辑界限是有帮助的,因为责任更加清晰,也将得到更好的管理。

为了对你的问题空间进行分组,我鼓励你看看你的业务架构。在业务架构中,有业务能力:业务可能拥有或交换以实现特定目的或结果的能力。这种抽象将数据、过程、组织和技术打包在一个特定的上下文中,与组织的战略业务目标和目的相一致。业务能力图显示了哪些功能区域被认为是实现您的使命和愿景所必需的。

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

一家虚构的航空公司的业务能力图

上面,我对一家虚构的航空公司进行了分解: Oceanic Airlines ,为了取得成功,它需要掌握业务能力图中列出的所有功能领域。例如,大洋航空公司必须能够作为在线或离线机票管理系统的一部分销售机票,或者由于飞行员管理计划而有飞行员驾驶飞机。该公司可以外包一些活动,同时保持其他活动作为其业务的核心。

你将在实践中观察到,你的大多数人都是围绕这些能力组织起来的。从事相同业务能力的人共享相同的词汇。这同样适用于您的应用程序和流程;基于它们需要支持的活动的内聚性,它们通常被很好地对齐并紧密地连接在一起。因此,业务能力映射是一个很好的起点,但是故事并没有到此结束。

将业务能力映射到您的应用和数据

为了更好地管理您的企业架构,业务能力、有限的上下文和应用程序都应该保持一致。这样做时,遵循一些基本规则是很重要的。至关重要的是,业务能力停留在业务层面上,并保持抽象。它们代表了一个组织所做的事情,并以问题空间为目标。当一个业务能力被实现时,一个特定上下文的实现——能力实例——被创建。在解决方案空间的这种界限内,多个应用程序和组件协同工作来交付特定的业务价值。

与特定业务功能相关的应用程序和组件与其他业务功能相关的应用程序保持分离。这允许更大的灵活性,也是领域和有界环境发挥作用的地方,就像边界围栏和我们的房子一样。您可以设置明确的原则:有界上下文是从业务功能中派生出来的,并且专门映射到业务功能。它们代表了业务功能实现的边界,表现得像一个域。如果业务能力改变,有界的上下文也会改变。优选地,您期望域和相应的有界上下文之间完全一致,但是现实——您将在接下来的部分中了解到——可能是不同的。

如果我们将能力映射投射到 Oceanic Airlines,您的有界上下文边界和域实现可能如下所示。

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

域之间的数据分布(作者:Piethein Strengholt)

在上面的“域间数据分布”示例中,客户管理建立在主题专业知识的基础上,因此有权决定向其他域提供什么数据。客户管理的内部架构是分离的,因此这些边界内的所有应用程序组件可以使用特定于应用程序的接口和数据模型直接通信。然而,使用数据产品和清晰的互操作性标准将数据分发到其他域是正式的。这是进入或离开你家的普通车道!在这种方法中,所有的数据产品都与领域保持一致,并继承了无处不在的语言:一种构建的、形式化的语言,由来自同一领域的利益相关者和设计者达成一致,以服务于该领域的需求。

多能力实现产生额外的域

当使用业务功能图时,理解一些业务功能可以被实例化多次是很重要的。例如,海洋航空公司,我们到目前为止一直使用的例子,可以有多个本地化的“行李处理和丢失项目”的实现。例如,某项业务仅在亚洲运营。在这种情况下,“行李处理和遗失物品”是亚洲相关飞机的一项功能。不同的业务线可能以欧洲市场为目标,因此在这种情况下使用另一种“行李处理和丢失物品”功能。这种多实例的场景可能会导致使用不同技术服务的多个本地化实现,以及操作这些服务的不相关团队。吸取的教训是,业务能力和能力实例(实现)的关系是一对多的,这也意味着您最终会有额外的(子)领域。

共享功能和共享数据

更重要的是你应该如何处理共享的业务能力。这种功能通常集中实现——作为服务模型——并提供给不同的业务部门。例如,“客户管理”可能就是这样一种能力。就海洋航空公司而言,亚洲和欧洲的业务部门对其客户使用相同的管理。问题是:如何将领域数据所有权投射到共享功能上?很可能多个业务代表对坐在同一个共享管理中的客户负责。**总结一下,有一个应用域和一个数据域!**从数据产品的角度来看,您的领域和有界上下文并不完全一致。相反,你可以认为从业务能力的角度来看,仍然有一个单一的数据问题。

**数据产品:**数据产品是数据架构的一个单元或组件,它封装了使读优化数据集可供其他域使用的功能。

对于您共享的功能,比如复杂的供应商包、SaaS 解决方案和遗留系统,我建议在您的领域数据所有权方法上保持一致。一种技术是通过数据产品分离数据所有权,这也可能需要应用程序的改进。在“客户管理”的例子中,来自应用领域的不同管道可以生成多个数据产品:一个数据产品用于所有与亚洲相关的客户,另一个用于所有与欧洲相关的客户。这意味着多个数据域来自同一个应用程序域。

处理共享数据的另一种技术是要求您的应用程序域设计一个单独的数据产品,该产品封装了元数据,用于区分数据产品内部的数据所有权。例如,您可以为所有权使用保留的列名,将每一行映射到一个特定的数据域。下面你会看到一个使用域列的例子。

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

封装元数据如何促进共享所有权的示例(作者:Piethein Strengholt)

共享功能的复杂性在于数据域与应用程序域重叠。理想情况下,您拥有业务能力的团队与您的应用程序域一致,因此软件所有权和数据所有权也是一致的。如果无法拆分您的域,您需要区分应用程序所有权和数据所有权。因此,在“客户管理”的例子中,您将有一个负责底层技术服务、管道和应用程序组件的应用程序所有者。接下来,您将有多个数据所有者(业务代表)负责不同的数据集,包括元数据注册、隐私、安全性等等。

关注服务于多种业务能力的复杂应用

另一个需要注意的地方是满足多种业务能力的应用程序,这在大型和传统企业中很常见。例如,大洋航空公司使用一个软件包来促进“成本管理”和“资产和融资”。这种共享应用程序通常很大而且很复杂:提供尽可能多的功能的供应商业务套件或遗留系统。这种情况下的应用领域预计会更大。这同样适用于共享所有权,这意味着多个数据域驻留在一个应用程序域中。

与来源一致、重新交付和与消费者一致的领域的设计模式

在映射您的域时,您将了解到基于数据的创建、消费或重新交付有不同的模式。我建议设计架构蓝图来支持您的领域,基于它们所具有的特征。

源对齐域与数据来源的源系统对齐。这些通常是交易或操作系统。目标必须是直接从这些黄金来源系统中获取数据。源自提供域的数据产品应该针对密集数据消费进行读取优化,因此您希望使用标准化服务来促进域的数据转换和共享。这些服务,包括预配置的容器结构,使您的面向源代码的领域团队能够更容易地发布数据;这是阻力最小的路径,以最小的干扰和成本做正确的事情。例如,如果设计正确,您的架构看起来像下面的模型:

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

源对齐域数据共享(作者:Piethein Strengholt)

消费者对齐的域与来源对齐的域相反,因为它们与需要来自其他域的数据的特定最终用户用例对齐。他们消费和转换数据,以适应他们的业务用例。为了满足这些消费需求,您应该考虑为数据转换和消费提供共享数据服务,例如处理数据管道、存储基础设施、流服务、分析处理等的与域无关的数据基础设施功能。

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

使用数据的消费一致领域(作者:Piethein Strengholt)

**再交付领域:**另一个不同且更困难的场景是数据的可重用性。例如,多个下游消费者可能对来自不同领域的数据组合感兴趣。数据产品的指导将有助于做出正确的决策。

对于您的架构,我鼓励您松散地耦合数据产品的创建和您的分析用例。在下面的模型中,域同时拥有聚合数据、可重用数据和分析用例。然而,这两个问题是不相关的。使用这种方法,数据消费者可以安全地消费新的数据产品,而不会与同一领域的分析用例紧密相连。这种情况下的聚合数据是分析用例的输入。

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

共享汇总数据(作者:Piethein Strengholt)

另一个选项可以是新生成的数据,这些数据将成为其他域的候选数据。在这种情况下,数据消费者变成了数据提供者,并将遵循相同的数据分发路径。这种情况下的架构如下所示:

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

分享新创建的分析数据(作者:Piethein Strengholt)

应对复杂集成挑战的标准化模式

当将您的企业环境分解成更细粒度的领域结构时,您会遇到复杂的集成挑战。如果我们以海洋航空公司为例,不同的其他领域可能需要来自“客户管理”的数据。或者"飞行计划和概述
管理"必须在"飞行员管理"中知道一名飞行员是否还存在,才能计划一次飞行。你会如何解决这个问题?

最佳实践是在通用车道模式上实现跨域边界集成的标准化。例如,在执行大型数据处理时,您可以应用 CQRS 来构建面向域的读取数据存储。这允许域从其他域集中读取数据,而不需要不断复制数据。例如,对于高度一致的读取(和命令),推荐使用 API 模式。以下关于设计模式的概述可以在您的过渡中为您提供支持:

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

领域间复杂集成的公共车道模式

如果您的公共车道模式设计正确,它们也可以与您的数据管理功能集成。这允许您捕获元数据,以获得安全性、可观察性、可发现性、沿袭和链接、质量监控、编排、通知等方面的透明度和洞察力。

解耦的粒度级别

现在我们知道了如何识别和促进数据域,我们来看下一点:设计正确的域粒度级别和分离规则。当分解您的架构时,有两个重要的方面发挥作用:

首先,功能域和设置有界上下文的粒度:符合工作方式,确保数据对所有域可用,利用共享服务,遵守元数据标准,等等。我对数据分布的建议是设置边界,在可能的情况下,设置精细的边界,因为成为数据驱动就是让数据可用于密集(重复)使用数据。如果您将您的域边界定义得太粗,您将在许多应用程序之间强加不期望的耦合,并且数据可重用性会丧失。因此,每次数据跨越业务能力的边界时,都要努力实现解耦。这意味着在一个域中,紧耦合是允许的。然而,当跨越边界时,域必须保持解耦,并分发读取优化的数据产品,以便与其他域共享数据。因此,例如,如果大洋航空公司的“预订&佣金”和“客户管理”需要交换数据,它们必须使用通用的车道模式。

第二,对于技术领域和基础设施利用率,有粒度。想象一个现代分布式数据平台,它使用不同的分散区域来实现服务数据集成和数据产品的敏捷性。这样一个区域,下面有共享的基础设施和服务,您将如何向您不同的领域团队提供这些呢?我的经验是,许多不同的方面触发了哪些功能域将被逻辑地分组在一起,并成为共享平台基础设施的候选。这里有几个例子:

  • 工作和共享数据方式的内聚力和效率。这与数据重力密切相关:在域之间不断共享大型数据集的趋势。
  • 区域界限可能会导致实现相同的业务功能和蓝图。
  • 所有权、安全性或法律界限可能会迫使域被分离。例如,某些数据不允许被其他域看到。
  • 灵活性和变化速度是重要的驱动因素。在几个领域内可以有创新的速度,而其他领域强烈重视稳定性。
  • 功能边界可以将团队分开,例如面向源/面向消费者。也许你的领域团队中有一半人认为特定的服务比其他服务更重要。
  • 一个原因可能是您希望出售或分离您的功能,因此与来自其他领域的共享服务紧密集成是不明智的。
  • 团队规模、技能和成熟度可能是一个因素。高技能和成熟的团队希望运营他们自己的服务和基础设施。
  • 不幸的是,政治界限也可能是一种驱动力。当业务能力与组织结构不一致时,我尤其会看到这一点。

业务能力建模的好处在于,它可以帮助您更好地识别和组织数据网格架构中的领域。它提供了数据和应用程序如何为您的企业带来价值的整体视图。与此同时,您可以优先考虑并关注您的数据策略和实际业务需求。除了只需要数据之外,您还可以使用这个模型。例如,如果可伸缩性是一个问题,您可以确定您最关键的核心能力,并为这些能力开发一个策略。

当将所有域和基础架构区域拼接在一起时,数据网格体系结构在概念上应该是这样的:

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

数据网格架构中域如何组织、利用基础设施和交互的示例架构(作者:Piethein Strengholt)

在上面的模型中,域被逻辑地组织并有效地共享基础设施,同时使用公共车道模式集成和分布数据。每个数据产品团队作为一个子域,负责他们生产和服务的数据。当跨越域边界时,团队利用基础设施区域蓝图提供的共享数据服务进行数据转换和消费。

有些人可能会担心,通过预先规划一切来构建这样一个目标状态架构是一项密集的工作。建议的替代方法是在将域加入到架构中的同时,有机地识别它们。因此,你不是自上而下地定义你的目标状态,而是自下而上地工作:探索、试验和将你的当前状态向目标状态过渡。这种方法可能会更快,但是当东西开始损坏时,会暴露出进入复杂的移动或改造操作的风险。一个更微妙的方法可能是在两个方向都起作用,然后在中间会合。

最后,设计大规模的分布式架构也需要你大规模地思考。业务能力建模和映射您的关键战略支柱将平滑您的领域分解。如果这是你喜欢的内容,我让你看看《规模化数据管理》这本书。

感谢 @mchesbro@mihail.tatarnikov@bashyrogerRichard RotellaKlaudia GoweroJan Meskens 提供反馈!此外, @roger.stoffers 分享了他的著作《数字化转型实地指南》中的见解

数据漂移第 1 部分:数据漂移的类型

原文:https://towardsdatascience.com/data-drift-part-1-types-of-data-drift-16b3eb175006?source=collection_archive---------12-----------------------

导致模型性能下降的不同类型的数据漂移

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

作者图片

在这一系列文章中,我计划解释数据漂移的概念以及它如何导致模型性能下降,如何识别数据漂移,以及如何提出一个监控计划来帮助尽早识别数据漂移和性能下降。

让我们考虑这样一个场景,你开发了一个模型,预测客户贷款违约的概率,它有很好的性能。简单地说,性能指标是准确性,您的模型有 86%的准确性。但是部署后几个月,你的模型表现不佳。业绩下滑到 70%。或者,项目批准和模型部署中的延迟,导致训练好的模型仅仅停留在那里几个月,而没有部署到生产中。当它最终被部署时,性能并不好。这是否意味着你当时开发的模型实际上并不好?不一定,“shift happens”(明白吗?).在这一系列文章中,我将讨论数据漂移(或数据偏移)如何导致性能下降,不同类型的数据漂移,如何识别数据漂移,整体模型监控实践,以便这些变化不会让您措手不及,以及最后如何在识别数据漂移后克服并修复您的模型。

在这篇文章(第 1 部分)中,让我们看看不同类型的数据漂移,以及它们是如何发生的一些例子。这将有助于我们理解数据漂移如何导致模型性能下降。

数据转移、数据漂移、概念转移、变化的环境、数据断裂都是描述同一现象的类似术语:训练和测试/生产数据之间的不同数据分布

当这些变化发生时,我们正在打破机器学习模型的基本假设。假设过去的(训练)数据代表未来的(测试/生产)数据。

数据移位的类型

1)协变量移位(自变量的移位):

协变量移位是一个或多个独立变量(输入特征)的分布变化。这意味着由于一些环境变化,即使特征 X 和目标 Y 之间的关系保持不变,特征 X 的分布也已经改变。下图可能有助于更好地理解这一点。

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

作者图片

在我们上面的违约概率示例中,这可能意味着由于疫情,许多企业关闭或收入减少,他们不得不裁员,但他们决定继续支付贷款,因为他们担心银行可能会没收他们的资产(X 变量的分布不同,但 Y 的分布相同)。

另一个例子是,随着用户群的增长,你投入生产的模型开始看到一个新时代的人口统计。你可能会对年轻用户进行培训,但是随着时间的推移,你也可能会有很多老用户。因此,你会看到均值和方差增加,因此数据漂移。

当这种变化发生在模型的一个或多个主要变量中时,性能下降会更加明显。您还应该在模型开发过程中验证输入特性是稳定的(例如,检查训练集和测试集内部和之间的这种变化),然后在部署后通过模型监控继续这样做。要学习如何识别协变班次,请看以下帖子: 第二部分 & 我的博文

在更正式的定义术语中,协变量移位是指 Ptrain(Y|X)=Ptest(Y|X)但 Ptrain(X) ≠Ptest(X) 的情况

其中 Ptest 可能是模型部署后的测试集或数据。

2)先验概率转移(目标变量的转移):

通过先验概率转移,输入变量的分布保持不变,但目标变量的分布发生变化。例如,可能是这样的:

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

作者图片

在我们上面的违约概率示例中,可能有一些公司没有真正受到锁定的影响,也没有遭受任何收入损失,但他们故意选择不偿还贷款分期付款,以利用政府补贴,并可能节省这笔钱,以防未来情况恶化(相同的 X 分布,但不同的 Y)。

在更正式的定义术语中,协变量移位是指 Ptrain(X|Y)=Ptest(X|Y)但 Ptrain(Y) ≠Ptest(Y) 的情况

其中 Ptest 可能是模型部署后的测试集或数据。

3)观念转变

随着概念漂移,输入和输出变量之间的关系发生变化。这意味着输入变量的分布(例如用户人口统计、单词频率等。)甚至可能保持不变,我们必须转而关注 X 和 y 之间关系的变化。

在更正式的定义术语中,概念转换是指 Ptrain(Y|X) ≠ Ptest(Y|X) 的情况

其中 Ptest 可能是模型部署后的测试集或数据。

概念漂移更可能出现在依赖于时间的领域,如时间序列预测和季节性数据。在一个月内学习一个模型不会推广到另一个月。概念漂移有几种不同的表现方式。

逐渐的概念漂移

渐进式或渐进式漂移是我们可以观察到的随时间推移而发生的概念漂移,因此可以预期。随着世界的不同变化,我们的模式逐渐变得过时,导致其性能逐渐下降。

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

作者图片

概念逐渐漂移的一些例子有 :

  • 推出替代产品 —在培训期间无法获得的产品(例如,如果该产品是市场上同类产品中的唯一产品)可能会对该型号产生不可预见的影响,因为它以前从未见过类似的趋势
  • 经济变化——利率的变化及其对更多贷款人拖欠贷款的影响可能会引起变化。

随着时间的推移,这些情况的影响会累积起来,导致更剧烈的漂移效应。

突发的概念漂移

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

作者图片

顾名思义,这些观念的转变来得很突然。一些最明显的例子出现在新冠肺炎首次在全球范围内出击的时候。需求预测模型受到严重影响,供应链跟不上,突然出现了像 2020 年卫生纸大短缺(不是官方术语,只是我的叫法😆)

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

作者图片

但是这种变化也可能发生在公司的正常运作过程中,而不会发生疫情 。

**道路网络的重大变化:**新道路的突然开放和其他道路的关闭或新公共铁路系统的增加可能会给交通预测模型带来麻烦,直到它收集了一些数据来处理,因为它以前从未见过类似的配置。

**生产线增加新设备:**新设备提出新问题,减少老问题。所以这个模型不确定如何做出好的预测。

一般来说,环境中的任何重大变化都会使模型陷入不熟悉的领域,从而导致性能下降。

重复出现的概念漂移

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

作者图片

反复出现的概念漂移相当于“季节性”。但季节性在时间序列数据的机器学习中是常见的,我们也意识到了这一点。因此,如果我们预期这种漂移,例如在周末或一年中的某些假期出现不同的模式,我们只需要确保我们用代表这种季节性的数据来训练模型。只有当模型不熟悉的新模式出现时,这种数据漂移通常会成为生产中的一个问题。

实际上,确定数据漂移的确切类型并不重要。通常,这种漂移可能是这些东西的组合,而且很微妙。重要的是识别对模型性能的影响并及时捕捉偏差,以便尽早采取措施,如重新训练模型。

既然您怀疑存在数据漂移,那么如何识别模型性能下降背后的数据漂移发生在哪里呢?要了解如何识别数据集中的数据漂移,请阅读本系列的第二部分

【https://practicalml.net】点击 查看我的博客 获取更多即将发布的帖子

参考

[1] Sarantitis,G. (2021 年 6 月 24 日)。机器学习中的数据移位:是什么,如何检测。圣乔治·萨兰蒂斯。https://gsarantitis . WordPress . com/2020/04/16/data-shift-in-machine-learning-what-it-and-how-to-detect-it/。

[2]萨穆伊洛娃,E. (2021 年 6 月 22 日)。生产中的机器学习:为什么要关心数据和概念漂移。中等。https://towards data science . com/machine-learning-in-production-why-you-should-care-data-and-concept-drift-d 96d 0 BC 907 FB

https://gsarantitis.wordpress.com/2020/04/16/data-shift-in-machine-learning-what-is-it-and-how-to-detect-it/

数据漂移—第 2 部分:如何检测数据漂移

原文:https://towardsdatascience.com/data-drift-part-2-how-to-detect-data-drift-1f8bfa1a893e?source=collection_archive---------18-----------------------

识别模型中数据漂移的指南

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

图片由卢克·切瑟 | Unsplash 拍摄

在本帖中,我们将介绍一些用于识别任何可能发生的数据漂移的技术。

假设您已经将一个模型部署到生产中,并且您注意到性能正在下降。性能下降背后有几个可能的原因:

  1. 模型输入数据本身存在错误:
  • 由于数据源的问题,输入数据可能是错误的。前端问题意味着写入数据库的数据不正确
  • 特征工程计算中可能存在错误。来源处的数据是正确的,但在管线中或特征工程期间存在错误,这意味着输入到特定特征的模型中的数据是不正确的

这些问题通常需要进一步的人工调查,并且可以通过代码审查、调试等来解决。

2.当外部因素导致数据发生真实变化时。这就是数据漂移,在本系列的第 1 部分中,我们了解了不同类型的数据漂移(协变量漂移、先验概率漂移&概念漂移)和一些例子。

假设经过一些检查后,您怀疑模型性能下降确实是由于数据漂移。那么,我们如何验证这一点,并确定数据漂移发生在数据的哪个位置呢?

测量漂移有三种主要技术:

  1. 统计:这种方法使用数据集上的各种统计指标来得出关于训练数据的分布是否不同于生产数据分布的结论。我们已经有了数据,所以它通常涉及到每次运行相同的计算,并可能绘制结果以便于分析。
  2. 基于模型:这种方法包括训练分类模型,以确定某些数据点是否与另一组数据点相似。如果模型很难区分数据,那么就没有任何显著的数据漂移。如果模型能够正确地分离数据组,那么可能存在一些数据漂移。
  3. 自适应窗口(ADWIN):这种方法用于流数据,在这种情况下,有大量的无限数据流入,不可能全部存储。与此同时,数据可能会变化得非常快。

1.统计法

这些方法中有许多是比较分布的。比较需要一个参考分布,它是我们用来比较生产数据分布的固定数据分布。例如,这可能是训练数据的第一个月,或者是整个训练数据集。这取决于你试图检测漂移的背景和时间范围。但是显然,参考分布应该包含足够的样本来表示训练数据集。让我们考虑一个使用 2019 年的数据训练的分类模型,其性能在 2020 年一直在缓慢下降。在这种情况下,我们可以开始尝试使用以下方法来检测顶级功能中的数据漂移。

**注意:**因为我们想观察数据随时间的漂移,我们想按时间聚合或划分数据,可以是每月、每周等,这取决于您的数据和监控频率。在本例中,我们将按月汇总数据。

下面我将解释一些用于检测漂移的不同统计方法。要查看使用真实数据集的完整代码示例,请参考我的博文这里

平均

我们可以考虑的第一个也是最简单的一个衡量标准是我们特征的方法。如果平均值在几个月内逐渐向某一特定方向移动,那么可能发生了数据漂移。

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

作者图片

我们可以从迷你图中看到,功能 A 处于下降趋势。迷你图不是识别趋势的最佳工具,因为它们会使细微的变化看起来有些夸张。平均值不是检查漂移的最可靠的方法,但却是一个很好的起点。

统计距离度量

有许多不同的统计距离度量可以帮助量化分布之间的变化。不同的距离检查在不同的情况下是有用的。

人口稳定指数

PSI 常用于金融行业,是一种衡量变量在两个样本之间或一段时间内的分布变化程度的指标。顾名思义,它有助于测量两个人口样本之间的人口稳定性。

Equation: PSI = (Pa — Pb)ln(Pa/Pb)

ln(Pa/Pb)项意味着,与具有大百分比分布的仓中的大变化相比,代表小百分比分布的仓中的大变化对 PSI 的影响更大。

应该注意的是,群体稳定性指数仅仅表示特征的变化。但是,这不一定会导致性能下降。因此,如果您确实注意到性能下降,您可以使用 PSI 来确认总体分布确实发生了变化。PSI 检查也可以添加到您的监控计划中。

库尔巴克-莱布勒散度

KL 散度衡量两个概率分布之间的差异,也称为相对熵。如果一个分布与另一个分布有很高的方差,KL 散度是有用的。

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

KL 公式来自维基百科

KL 散度也是不对称的。这意味着,与 PSI 不同,如果参考和生产(比较)分布对被交换,结果会有所不同。所以 KL(P || Q)!= KL(Q || P)。这对于涉及 Baye 定理的应用或当您有大量训练(参考)样本,但在比较分布中只有一小组样本(导致更多方差)时非常有用。

KL 分数的范围从 0 到无穷大,其中 0 分意味着两个分布是相同的。如果 KL 公式采用以 2 为底的对数,结果将以位为单位,如果使用自然对数(底 e),结果将以“nats”为单位。

詹森-香农(JS)散度

JS 散度是量化两个概率分布之间差异的另一种方式。它使用我们上面看到的 KL 散度来计算对称的标准化得分。这使得 JS 散度分数更有用,也更容易解释,因为当使用对数基数 2 时,它提供了 0(相同分布)和 1(最大不同分布)之间的分数。

使用 JS,不存在被零除的问题。当一个分布在某些区域有值而另一个没有值时,就会出现被零除的问题。

瓦瑟斯坦距离度量

Wasserstein 距离,也称为推土机距离,是给定区域内两个概率分布之间距离的度量。Wasserstein 距离对于非重叠数值分布移动和高维空间(例如图像)的统计是有用的。

Kolmogorov-Smirnov 检验(K-S 检验或 KS 检验)

KS 检验是连续/不连续一维概率分布相等的一种非参数检验,可用于比较样本与参考概率分布(单样本 K–S 检验),或比较两个样本(双样本 K–S 检验)。

2.基于模型

上述统计方法的替代方法是建立一个分类器模型,尝试区分参考分布和比较分布。我们可以通过以下步骤做到这一点:

  1. 将用于构建当前生产模型的批中的数据标记为 0。
  2. 将我们从那时起收到的那批数据标记为 1。
  3. 开发一个模型来区分这两个标签。
  4. 评估结果,必要时调整模型。

如果开发的模型可以很容易地区分两组数据,那么协变量发生了变化,模型需要重新校准。另一方面,如果模型难以区分两组数据(其精确度约为 0.5,与随机猜测一样好),则没有发生显著的数据偏移,我们可以继续使用该模型。

3.ADWIN 自适应滑动窗口

如前所述,当我们有一个输入数据流时,上述技术不是很合适。在某些情况下,数据可能漂移得如此之快,以至于当我们收集数据并训练模型时,趋势可能已经发生了变化,我们的模型已经过时了。但是计算出训练的最佳时间框架也不是那么简单。这就是自适应滑动窗口技术有用的地方。它能适应不断变化的数据。例如,如果发生变化,窗口大小将自动缩小,否则,如果数据是静止的,窗口大小将增大以提高准确性。

这些技术可以根据其适用性来检测数据漂移。但是我们希望避免等到发现模型中的性能显著下降时才开始调查数据漂移。这就是拥有一个模型监控计划变得非常有用的地方。查看本系列文章的第 3 部分(即将发布),了解如何创建有效的模型监控计划。

原载于 2021 年 6 月 10 日【https://practicalml.net】

https://practicalml.net查看我的博客,将来会有更多帖子

参考

[1] Dhinakaran,A. (2020 年 10 月 19 日)。使用机器学习可观察性的统计距离度量。中等。https://towards data science . com/using-statistical-distance-metrics-for-machine-learning-observability-4c 874 cded 78。

[2]维基媒体基金会。(2021 年 6 月 21 日)。库尔贝克-莱布勒散度。维基百科。https://en.wikipedia.org/w/index.php?title = kull back % E2 % 80% 93 lei bler _ divergence&oldid = 1029607529。

进一步阅读

PSI:https://towards data science . com/using-statistical-distance-metrics-for-machine-learning-observability-4c 874 cded 78。

kull back-lei bler(KL)divergence:https://towardsdatascience . com/light-on-math-machine-learning-intuitive-guide-to-understanding-KL-divergence-2b 382 ca 2 B2 a 8

詹森-香农(JS)散度:https://medium . com/datalab-log/measuring-the-statistical-similarity-between-two-samples-using-Jensen-Shannon-and-kull back-lei bler-8d 05 af 514 b 15

瓦瑟斯坦距离度量:(https://towardsdatascience . com/earth-movers-distance-68 fff 0363 ef2)

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

Kolmogorov–Smirnov 测试:https://en . Wikipedia . org/wiki/Kolmogorov % E2 % 80% 93 Smirnov _ test # Discrete _ and _ mixed _ null _ distribution

基于模型:https://www . arango db . com/2020/11/arango ml-part-4-detecting-co variate-shift-in-datasets/

数据驱动调度优化方法

原文:https://towardsdatascience.com/data-driven-approach-for-schedule-optimizations-60fdcba1376e?source=collection_archive---------21-----------------------

如何使用 Google 或-Tools 来调度问题,并用 Plotly 可视化输出

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

Pablo Merchán Montes 在 Unsplash 上拍摄的照片

从餐馆开始…

想象你是一家餐馆的经理。今天正好是忙碌的一天,你现在缺少人手来完成客户的订单。菜要洗,鸡要切,同时,菜要做……菜做好了,还要有人上菜,收钱。看到待办事项列表越来越长,现在你有点焦虑:你应该分配谁去做什么任务,这样你才能在最短的时间内完成所有的订单?我刚才描述的场景本质上实际上是一个调度问题。或者在更高层次上,是 Or(运筹学)课题的子集。运筹学是一门运用先进的分析方法来帮助做出更好决策的学科。有大量的开源库可供用户用来解决调度问题。其中,Google OR-Tools 是最受欢迎的开源库之一,用于解决包括车辆路径、调度、整数规划、线性规划和约束编程问题在内的问题。更多详情,你可以参考他们的官方网站超过这里

尽管链接中给出了大量例子来演示如何利用这个库来解决优化问题,但是如果您对它完全陌生,最初的学习曲线可能会有点深。今天,我将向你展示一个为餐厅员工制定时间表的例子,希望它能让你更容易理解其中的概念。让我们开始吧!

问题设置

现在,让我们为餐厅调度问题添加更多的细节,以更好地模拟实际的餐厅环境。为了便于跟踪,让我们假设餐厅里总共有三名员工帮助完成任务。为了完成来自客户的订单,通常有三种类型的任务要处理:

  1. 准备配料。这一步可能包括洗菜、切鸡肉等。
  2. **做饭。**根据不同种类的食物,烹饪时间可能会更长或更短。
  3. 服务客户。这一步可能包括诸如上菜、收款等任务。

同样,在现实中,整个过程可以进一步细分,这里为了简单起见,我们只采取这 3 个步骤。这里需要注意的另一点是,工作人员实际上需要按顺序完成这 3 个步骤,即只有在准备工作完成后才能做饭。除非饭菜做好了,否则不可能给顾客上菜。在调度问题的上下文中,这些被称为“优先约束”。我们将在后面的编码部分再次讨论这个概念。设定 3 个主要处理步骤后,下一步是确定哪个员工负责哪个处理步骤,以及他/她完成该步骤需要多少时间。实际上,这里的任务安排可能相当灵活,因为一些员工可能既能处理配料准备又能烹饪,而其他人可能只专注于服务客户。在我们的例子中,为了简单起见,我们将预先安排分配给每个员工的任务。在编码部分有更多的细节。

使用 Google 或工具进行日程安排

有了这些设置,我们就可以开始实际的编码了。如前所述,我会使用 Google 或-Tools 作为支持库来优化我们餐厅的时间表。要安装 Google 或-Tools for python,只需在命令行中键入以下内容:

python -m pip install --upgrade --user ortools

值得一提的是,如果你使用的是 C++,C#,或 Java,Google 或-Tools 也有可用的包装器。Google OR-Tools 中有几个针对不同用例的解算器。对于调度,我们将使用 CP-SAT 求解器:

from ortools.sat.python import cp_model

在程序开始时,我们需要首先定义订单信息,由分配的员工和完成该步骤所需的时间组成。这里,订单数据被定义为一个元组列表,其中每个元组对表示分配的人员和所需的处理时间。下图中可以找到一个示例。

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

作者图片

horizon ”变量定义了在最终计划中分配的可能值的上限。通过计算每项任务所需时间的总和,如果每件事情都按顺序一个接一个地完成,它会返回最坏情况下所需的总时间。在接下来的部分中,您将看到这个“horizon”参数是如何出现的。

horizon = sum(task[1] for job in jobs_data for task in job)

在下一部分代码中,我们使用嵌套的 for 循环遍历所有 3 个订单的每个处理步骤,然后相应地创建开始、结束和间隔变量。注意这里 start_var 被定义为模型。NewIntVar(0,horizon,’ start’+suffix) —这里 horizon 定义了 start_var 可以达到的上限。通过创建所有这些变量,稍后将更容易定义问题的相关约束。

for job_id, job in enumerate(jobs_data):
    for task_id, task in enumerate(job):
        staff = task[0]
        duration = task[1]
        suffix = '_%i_%i' % (job_id, task_id)
        start_var = model.NewIntVar(0, horizon, 'start' + suffix)
        end_var = model.NewIntVar(0, horizon, 'end' + suffix)
        interval_var = model.NewIntervalVar(start_var, duration, end_var, 'interval' + suffix)
        all_tasks[job_id, task_id] = task_type(start=start_var,
                                               end=end_var,
                                               interval=interval_var)
        staff_to_intervals[staff].append(interval_var)

在定义了所有相关变量之后,下一步是定义问题的约束。在我们的示例中,我们有以下 3 个主要约束:

  1. 一名员工在给定时间内只能处理一项任务,不允许同时处理多项任务(我肯定你不希望你的员工在忙着做饭的时候给客户上菜)。在调度的上下文中,这被称为析取约束
  2. 正如我们之前已经提到的,需要按照步骤顺序来完成订单->准备,烹饪,然后上菜。这在调度问题中称为优先约束
  3. 最后,总体目标当然是在最少的时间内完成所有订单。
# Create and add disjunctive constraints.
for staff in all_staffs:
    model.AddNoOverlap(staff_to_intervals[staff])

# Precedences inside a job.
for job_id, job in enumerate(jobs_data):
    for task_id in range(len(job) - 1):
        model.Add(all_tasks[job_id, task_id + 1].start >= all_tasks[job_id, task_id].end)#Minimize the total time spent
obj_var = model.NewIntVar(0, horizon, 'total_time')
model.AddMaxEquality(obj_var, [all_tasks[job_id, len(job) - 1].end for job_id, job in enumerate(jobs_data)])
model.Minimize(obj_var)

配置好这些东西后,我们只需要让 Google 或-Tools 在后端做优化工作,看看返回的输出是什么。如果稍后找到最佳解决方案,状态变量将返回“最佳”

solver = cp_model.CpSolver()
status = solver.Solve(model)

可视化输出时间表

因此,现在模型在运行求解程序后返回“最优”状态。太棒了。现在我们应该如何可视化时间表?基本上,我们将需要检索我们之前定义的相关开始和结束时间变量的最终值,然后用一些条形图将其可视化。Plotly 为我们提供了一个方便的功能,只要输入的数据按照所需的格式进行格式化,我们就可以自动创建甘特图。关于 Plotly 库的用法,我不会讲太多细节,你可以随时参考在线教程或我的完整代码。

def visualize_schedule(assigned_jobs,all_staffs,plan_date):
    final = []
    for staff in all_staffs:
        #print("This is for staff: ", staff)
        assigned_jobs[staff].sort()
        for assigned_task in assigned_jobs[staff]:
            name = 'Order_%i' % assigned_task.job
            temp = dict(Task=staff,Start=plan_date + pd.DateOffset(minutes = assigned_task.start),
                        Finish= plan_date + pd.DateOffset(minutes = (assigned_task.start + assigned_task.duration)),
                        Resource=name)
            final.append(temp)
    final.sort(key = lambda x: x['Task'])
    return final

使用 Plotly 可视化的最终输出如下图所示。我们可以看到,完成所有三个订单总共花费了 18 分钟。通过这种可视化,您可以非常直观地了解相关的约束条件是否得到满足。

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

用 Plotly 可视化的餐厅工作时间表(图片由作者提供)

添加附加约束

我们刚刚定义的问题实际上是调度的一个非常基本的例子。在现实世界中,我们可能需要考虑许多其他类型的约束。这里我们可以添加另一个约束来说明:为了确保更好的客户满意度,餐馆要求所有的菜都应该在烹饪完成后的 3 分钟内提供给客户。换句话说,现在步骤 2 和步骤 3 之间的时间差应该在 3 分钟以内。正如我们在前面的计划输出中所观察到的,现在订单 1 没有满足这个约束,步骤 2 和步骤 3 之间有很大的差距。我们如何将这个约束添加到模型中呢?实际上,通过添加下面的粗体中突出显示的条件,可以很容易地做到这一点,我希望这是不言自明的:

for job_id, job in enumerate(jobs_data):
    for task_id in range(len(job) - 1):
        model.Add(all_tasks[job_id, task_id + 1].start >= all_tasks[job_id, task_id].end)
        # Make sure the time gap of task 2 and task 3 are less then 3 mins
        **if task_id == 1:
            model.Add(all_tasks[job_id, task_id + 1].start <= all_tasks[job_id, task_id].end + 3)
        else:
            continue**

添加此约束并重新运行模型后,更新后的明细表显示在下图中。虽然总的完成时间保持不变,但现在所有 3 个订单都满足了我们设置的新约束(从烹饪完成到上菜不超过 3 分钟)。虽然在这个例子中这个解决方案看起来很简单,但是当员工人数和订单数量增加时,使用这个工具的好处将会更加明显。

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

带有附加约束的更新时间表(图片由作者提供)

最后的想法和未来的工作

对于这个用例,我们有很多可以改进的地方。例如,我们可以用不同的人处理相同任务的方式来配置它,而不是为不同的人预先定义单独的任务。根据他们对不同任务的熟练程度,可能会有不同的相关处理时间。这样,调度程序可以给出更动态的输出。

为了进一步增强它,我们可以将这个日程安排程序作为一个 web 应用程序,用户可以通过前端 UI 简单地输入人员和订单信息,然后最终的日程安排将作为输出显示出来。如果您对此感兴趣,请随意尝试!

参考

这篇文章中的例子很大程度上遵循了与他们的官方网站相同的结构。关于用 Google 或-Tools 实现其他约束的更多例子,你可以参考他们的 Github 页面讨论组

最后,你可以在我的 Github 页面这里找到我在这篇文章中使用的全部代码。感谢阅读!

附言

如果您有兴趣加入中等会员计划,您可以使用以下链接注册!提前感谢大家的帮助:)

https://medium.com/@tianjie1112/membership

数据驱动审计| #1 使用 Python 自动采样

原文:https://towardsdatascience.com/data-driven-audit-1-automated-sampling-using-python-52e83347add5?source=collection_archive---------23-----------------------

使用 Python 自动化审计流程

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

克里斯里德在 Unsplash 上的照片

你将从这篇文章中学到什么

  • 将取样时间从一小时减少到一分钟
  • 如何将文件转换为最佳格式的示例代码
  • 步骤背后的基本原理

你可以在下面找到脚本。

设置

您从需要制作样本的客户处接收群体文件。

在创建示例之前,您需要执行以下步骤:

  1. 在 Python 中加载群体
  2. 移除不在范围内的实体
  3. 创建一个随机样本
  4. 导出到 excel

第一步

加载您从客户端收到的填充。你可以在这里下载数据集。

如您所见,客户为每个月(2015 年 1 月、2015 年 2 月……)创建了一个单独的表。对于我们的抽样过程,我们需要一个包含所有这些月份的合并表。

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

population.xlsx 数据集的屏幕截图

用以下参数读入所有纸张:

  • sheet_name = 0 |将所有工作表作为字典读入
  • dtype = str |读入所有数据类型为“string”的列
population = pd.read_excel("population.xlsx", sheet_name = None, dtype = str)

将不同的工作表连接成一个合并的工作表。

population = pd.concat( population , ignore_index = True)

现在您有了一个合并的工作表,但是您会注意到它还不是一个干净的格式。您需要执行以下清洁步骤:

  1. 删除空白的行和列

  2. 分配列名

  3. 删除不包含帐户值的行

  4. 转换为压缩格式

  5. 删除空白行

使用以下参数:

  • axis = 0 |删除具有 NA 值的行
  • how = ‘all’ |仅当所有值都是 NA 时才删除一行
  • subset = ‘all’ |只考虑从 1 开始的列(因此不包括第一列)
population = population.dropna( axis = 0 , how = 'all' , subset = population.columns[1:] )

现在,通过指定 axis = 1 删除没有任何值的列,并重置索引。

population = population.dropna (axis = 1 , how = 'all').reset_index( drop = True)

2.分配列名

您可以从文件的第一行获取列名。使用 iloc 函数将第一行的值存储在变量“columns”中。

columns = population.iloc[0]population.columns = columns

3.删除不包含帐户值的行

仍有不包含相关信息的行,例如实体行。您需要排除所有不以数字开头的行。

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

标题需要删除,因为我们已经分配了它们

population = population.loc[ population['Financial Row'].str[:1].str.isnumeric()]

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

输出示例

干得好!开始有点像了。

4.转换为压缩格式

最佳实践是将数据帧转换为压缩格式。请记住,行很便宜,但列很贵。这使得以后的过滤更加容易。

population = population.melt( id_vars = 'Financial Row', var_name='Entity', value_name='Amount')

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

示例输出

第 2 步:排除帐户

以下客户不在范围内:

  • 400XXX
  • 500XX
  • 800XXX

我们使用。loc 函数过滤数据帧,排除以这些帐户开头的行。通过指定“~”符号,您可以让 python 知道您想要排除满足条件的记录。

account_list = ["400", "500" , "800"]population_1 = population.loc[ ~ population['Financial Row'].str[:3].isin(account_list)]

第三步:制作样品

你现在想做一个样品。审计中常见的样本量是 20 条必须随机选择的记录。

在示例函数中使用以下参数:

  • n = 20 |样本量为 20
  • random_state = 1 |这允许您复制您的结果。
population_1 = population_1.reset_index( drop = True)population_sample = population_1.sample( n = 20, random_state = 1).reset_index()

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

抽样输出

步骤 4:将其全部导出到合并工作簿

您可以使用 excelwriter 函数将所有内容导出到合并工作簿中

with pd.ExcelWriter("sample.xlsx") as writer:
   population.to_excel(writer, sheet_name = "population_source")   
   population_1.to_excel(writer, sheet_name = "population_scoped")
   population_sample.to_excel(writer, sheet_name = "sample")

干得好!您已经成功实现了采样过程的自动化。

明年,只要再次运行这个脚本,去享受阳光吧!;)

在这里下载脚本

注:这是一系列博客中的第一篇。敬请关注更多内容。

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

照片由扎克·杜兰特Unsplash 上拍摄

数据驱动的客户细分

原文:https://towardsdatascience.com/data-driven-customer-segmentation-c16062741a7c?source=collection_archive---------7-----------------------

使用 k 均值聚类创建和分析客户群

“为了看清事物,站在一个人的外面可能是必要的.”

――彼得·霍格,《夜的故事》

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

布鲁克·拉克Unsplash 拍摄的照片

介绍

我相信学习营销数据科学的最好方法是通过例子来工作。在这篇博文中,我想谈谈

  • 客户细分以及了解这一点的重要性
  • 建立 k-means 聚类模型,用肘法和剪影系数选择最佳聚类数
  • 营销语境下的 k-均值聚类解读

客户细分

客户细分是根据共同特征将客户分成不同群体的过程,这使得公司能够有效且恰当地对每个群体进行营销[1]。

我们为什么需要客户细分?

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

腾雅特Unsplash 上拍照

鉴于目前市场竞争激烈,了解客户行为、类型和兴趣至关重要。尤其是在目标营销中,对客户进行分类和了解是形成有效营销策略的关键一步。通过创建客户细分,营销人员可以一次专注于一个细分市场,并定制他们的营销策略。例如,你有一个酒店业务,你可能会针对即将举行周年纪念的夫妇,为他们提供一个特别的浪漫套餐。

总的来说,客户细分是成功的目标市场营销的关键,通过客户细分,您可以针对特定的客户群体进行不同的促销、价格选择和产品放置,以最具成本效益的方式抓住目标受众的兴趣[2]。

数据

我使用的是 UCI 机器学习库中的公共数据集,该数据集记录了一家总部位于英国的注册无店铺在线零售商在 2010 年 1 月 12 日至 2011 年 9 月 12 日之间发生的交易。数据集可以在这里找到。该公司主要销售独特的适合各种场合的礼品。这家公司的许多客户都是批发商。

功能:

  • 发票号:发票号。名义上,分配给每笔交易的 6 位整数。如果该代码以字母“c”开头,则表示取消
  • 库存代码:产品(物品)代码。名义上,一个 5 位数的整数,唯一分配给每个不同的产品。
  • 描述:产品(物品)名称。名义上的
  • 数量:每笔交易每种产品(物品)的数量。数字的
  • InvoiceDate:发票日期和时间。数字,每笔交易生成的日期和时间
  • 单价:单价。数字,单位为英镑的产品价格
  • CustomerID :客户编号。名义上,一个唯一分配给每个客户的 5 位整数
  • 国家:国家名称。名义上,每个客户居住的国家的名称。

数据争论

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline

df = pd.read_excel('online_retail_dataset.xlsx', sheet_name='Online Retail')

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

数据清理

至于数据清理,我做了以下操作:

  • CustomerID 有*空记录。*让我们删除包含空值的行
  • 数量栏有负值,可能是采购后退货造成的。让我们删除数量为负的行
  • 单价栏也有负记录。我也决定放弃负价格的唱片
  • 购买记录的时间段为 2010 年 1 月 12 日至 2011 年 9 月 12 日。上个月数据不完整。让我们忽略不完整月份的记录。
# Let's drop rows containing NULL values
df.dropna(subset=['CustomerID'], inplace=True)

# Remove negative quantity
df = df.loc[df['Quantity'] > 0]

# Remove rows with negative price
df = df.loc[df['UnitPrice'] > 0]

# Handle incomplete data
df = df.loc[df['InvoiceDate'] < '2011-12-01']

数据转换

# Calculate total sales
df['Sales'] = df['Quantity'] * df['UnitPrice']

# Create per-customer data
df_customers = df.groupby('CustomerID').agg({'Sales': sum,
                                             'InvoiceNo': lambda x: x.nunique()})
df_customers.columns = ['TotalSales', 'OrderCount']
df_customers['AvgOrderValue'] = df_customers['TotalSales'] / df_customers['OrderCount']

# Rank the data
df_rank = df_customers.rank(method='first')

# Let us normalize the data to center around the mean 
# and have a mean of 0 and a standard deviation of 1
df_normalized = (df_rank - df_rank.mean()) / df_rank.std()

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

现在,您可以看到这些值以 0 为中心,标准偏差为 1。让我们使用这些数据进行聚类分析。

k 均值聚类

k-means 聚类是最简单也是最常用的算法之一。它试图找到代表特定数据区域的聚类中心。该算法包含两个步骤:

  1. 将每个数据点分配到最近的聚类中心
  2. 将每个聚类中心设置为分配给它的数据点的平均值。

一旦实例到聚类的分配不再改变,k-means 聚类就结束计算。

我们应用 k-means 聚类时,我们必须记住

  • 每个簇由其中心定义,这意味着一个簇具有凸起的形状。因此,k 均值捕捉具有相同“直径”的相对简单的形状
  • k-means 假设所有方向对于每个聚类都是同等重要的
  • 该算法在聚类中心之间的中间绘制聚类之间的边界[3]。

定义最佳聚类数

使用 k-means 聚类进行客户细分的一个缺点是,您必须事先知道聚类的数量。让我们探索两种定义数据集中聚类数量的方法:

  • 轮廓系数
  • 肘法

轮廓系数

剪影系数是一种用于估计聚类技术好坏的度量。

剪影系数的公式:

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

其中 b 是一个点与其最近的聚类之间的平均距离,而 a 是同一聚类内的数据点之间的平均距离。轮廓系数的范围从-1 到 1,其中值越接近 1 越好。

基本上,轮廓系数测量与其他聚类【2】相比,数据点与其聚类有多接近。

肘法

肘方法用于验证 k-means 聚类中的聚类数。肘方法的思想是对数据集运行 k-means 聚类,得到一系列值 k (比如说 k 从 1 到 10),并对每个值 k 计算:

  • 失真,这是距各个聚类的聚类中心的平方距离的平均值(使用欧几里德距离度量)
  • 惯性,它是样本到它们最近的聚类中心的平方距离之和[4,5]。

利用 k 均值聚类进行客户细分

from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
from sklearn import metrics 
from scipy.spatial.distance import cdist

# Calculate Silhouette coefficient
for n_cluster in [2, 3, 4, 5, 6, 7, 8]:
    kmeans = KMeans(n_clusters=n_cluster,
                    max_iter=400,
                    n_init=20).fit(df_normalized[['TotalSales',
                                                  'OrderCount',
                                                  'AvgOrderValue']])
    silhouette_avg = silhouette_score(df_normalized[['TotalSales',
                                                     'OrderCount',
                                                     'AvgOrderValue']],
                                      kmeans.labels_) 
    print('Silhouette coefficient for %i clusters: %0.3f' % (n_cluster,
                                                             silhouette_avg))

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

不同簇数的轮廓系数值

# Calculate inertias and distortions for customers dataset
# Link to original code: https://www.geeksforgeeks.org/elbow-method-for-optimal-value-of-k-in-kmeans/
distortions = [] 
inertias = []
K=range(1, 11)

for k in K: 
    kmeanModel = KMeans(n_clusters=k, max_iter=400, n_init=20).fit(df_normalized[['TotalSales',
                                                                                  'OrderCount',
                                                                                  'AvgOrderValue']]) 
    kmeanModel.fit(df_normalized[['TotalSales', 'OrderCount', 'AvgOrderValue']])
    distortions.append(sum(np.min(cdist(df_normalized[['TotalSales',
                                                       'OrderCount',
                                                       'AvgOrderValue']],
                                        kmeanModel.cluster_centers_,
                                        'euclidean'),axis=1)) / df_normalized[['TotalSales',
                                                                               'OrderCount',
                                                                               'AvgOrderValue']].shape[0]) 
    inertias.append(kmeanModel.inertia_)

# Plot distortions
plt.plot(K, distortions, 'bx-',  linewidth=2.5, color='dodgerblue') 
plt.xlabel('Values of K', fontsize=14) 
plt.ylabel('Distortion', fontsize=14) 
plt.title('The Elbow Method using Distortion', fontsize=16) 
plt.xticks(np.arange(1, 11))
plt.show()

# Plot inertias
plt.plot(K, inertias, 'bx-', linewidth=2.5, color='dodgerblue') 
plt.xlabel('Values of K', fontsize=14) 
plt.ylabel('Inertia', fontsize=14) 
plt.title('The Elbow Method using Inertia', fontsize=16) 
plt.xticks(np.arange(1, 11))
plt.show()

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

查看肘部曲线和轮廓系数,我选择聚类数=4,因为轮廓系数相对较高,惯性和扭曲不会随着聚类数的增加而发生显著变化。

现在我们知道了聚类的数量,让我们建立一个 k-means 聚类模型。

# Build k-means clustering model
kmeans = KMeans(n_clusters=4,
                max_iter=400,
                n_init=20).fit(df_normalized[['TotalSales',
                                              'OrderCount',
                                              'AvgOrderValue']])

cluster_centres = kmeans.cluster_centers_
df_cluster_centres = pd.DataFrame(cluster_centres,
                                  columns=['TotalSales', 
                                           'OrderCount',
                                           'AvgOrderValue'])
df_cluster_centres['Cluster'] = df_cluster_centres.index

df_four_clusters = df_normalized[['TotalSales',
                                  'OrderCount',
                                  'AvgOrderValue']].copy(deep=True)
df_four_clusters['Cluster'] = kmeans.labels_

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

每个客户都标有其聚类/细分

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

每个细分市场的客户数量

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

每个聚类中心的值

让我们仔细看看各组的中心。聚类#1 在所有三个属性中的数值最低。这意味着分类#1 包含销售额最小、订单数量最少和每订单平均价值最低的客户。这组客户是低价值客户之一。另一方面,簇#0 在所有属性中具有最高数量。因此,集群#0 中的客户购买昂贵的产品,给企业带来最高的收入。您通常希望将营销工作集中在这部分高价值客户上,因为这将带来最高的回报。

集群#2 中的客户相当有趣。他们购买相对频繁,因为订单数量相对较高,但他们的平均每单价值较低。这些是经常购买低值物品的顾客。所以,给这个细分市场推荐便宜的产品就太好了。集群#3 中的客户也很有趣,因为他们对收入和订单数量的贡献处于中低水平。然而,他们的平均每单价值相对较高,这意味着他们偶尔会购买昂贵的商品。因此,向该细分市场销售昂贵的产品是合适的。

让我们将这些片段形象化

plt.scatter(df_four_clusters.loc[df_four_clusters['Cluster'] == 0]['OrderCount'], 
            df_four_clusters.loc[df_four_clusters['Cluster'] == 0]['TotalSales'],
            c='mediumvioletred')

plt.scatter(df_four_clusters.loc[df_four_clusters['Cluster'] == 1]['OrderCount'], 
            df_four_clusters.loc[df_four_clusters['Cluster'] == 1]['TotalSales'],
            c='dodgerblue')

plt.scatter(df_four_clusters.loc[df_four_clusters['Cluster'] == 2]['OrderCount'], 
            df_four_clusters.loc[df_four_clusters['Cluster'] == 2]['TotalSales'],
            c='gold')

plt.scatter(df_four_clusters.loc[df_four_clusters['Cluster'] == 3]['OrderCount'], 
            df_four_clusters.loc[df_four_clusters['Cluster'] == 3]['TotalSales'],
            c='lightseagreen')

plt.title('TotalSales vs. OrderCount Clusters', fontsize=16)
plt.xlabel('Order Count', fontsize=14)
plt.ylabel('Total Sales', fontsize=14);

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

plt.scatter(df_four_clusters.loc[df_four_clusters['Cluster'] == 0]['OrderCount'], 
            df_four_clusters.loc[df_four_clusters['Cluster'] == 0]['AvgOrderValue'],
            c='mediumvioletred')

plt.scatter(df_four_clusters.loc[df_four_clusters['Cluster'] == 1]['OrderCount'], 
            df_four_clusters.loc[df_four_clusters['Cluster'] == 1]['AvgOrderValue'],
            c='dodgerblue')

plt.scatter(df_four_clusters.loc[df_four_clusters['Cluster'] == 2]['OrderCount'], 
            df_four_clusters.loc[df_four_clusters['Cluster'] == 2]['AvgOrderValue'],
            c='gold')

plt.scatter(df_four_clusters.loc[df_four_clusters['Cluster'] == 3]['OrderCount'], 
            df_four_clusters.loc[df_four_clusters['Cluster'] == 3]['AvgOrderValue'],
            c='lightseagreen')

plt.title('AvgOrderValue vs. OrderCount Clusters', fontsize=16)
plt.xlabel('Order Count', fontsize=14)
plt.ylabel('Avg Order Value', fontsize=14);

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

plt.scatter(df_four_clusters.loc[df_four_clusters['Cluster'] == 0]['TotalSales'], 
            df_four_clusters.loc[df_four_clusters['Cluster'] == 0]['AvgOrderValue'],
            c='mediumvioletred')

plt.scatter(df_four_clusters.loc[df_four_clusters['Cluster'] == 1]['TotalSales'], 
            df_four_clusters.loc[df_four_clusters['Cluster'] == 1]['AvgOrderValue'],
            c='dodgerblue')

plt.scatter(df_four_clusters.loc[df_four_clusters['Cluster'] == 2]['TotalSales'], 
            df_four_clusters.loc[df_four_clusters['Cluster'] == 2]['AvgOrderValue'],
            c='gold')

plt.scatter(df_four_clusters.loc[df_four_clusters['Cluster'] == 3]['TotalSales'], 
            df_four_clusters.loc[df_four_clusters['Cluster'] == 3]['AvgOrderValue'],
            c='lightseagreen')

plt.title('AvgOrderValue vs. TotalSales Clusters', fontsize=16)
plt.xlabel('Total Sales', fontsize=14)
plt.ylabel('Avg Order Value', fontsize=14);

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

从图中可以看出,的高价值客户(紫色)在各个维度的价值最高,而的低价值客户(蓝色)则相反。

让我们来看看高价值人群最受欢迎的购买行为

pd.DataFrame(
    df.loc[df['CustomerID'].isin(high_value_cluster.index)
          ].groupby('Description').count()['StockCode'].sort_values(ascending=False).head(10))

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

高价值人群购买的最受欢迎的商品

当你瞄准高价值细分市场时,我们可以在营销策略中利用这些关于高价值细分市场购买的最受欢迎商品的信息。你可以推荐与这些畅销商品相似的商品,因为顾客对这些类型的产品最感兴趣。

摘要

  • 我们应用 k-means 聚类来理解在线零售店的细分市场
  • 使用肘方法和轮廓系数,我们找到了最佳的分段数,即 4
  • 我们从总销售额、订单数量和平均订单价值方面考察了每个细分市场之间的差异,并为每个细分市场制定了潜在的营销策略
  • 我们查看了高价值客户群购买的最受欢迎的商品,这可能有助于向这一高价值群体销售类似的商品,并提高转化率。

*感谢您的阅读,请在下面评论您对使用机器学习进行客户细分的看法。*要查看我的更多帖子,请在 Medium 和 LinkedIn 订阅。

Jupyter 笔记本可以在我的 GitHub 上找到。

参考文献

[1]客户细分定义—什么是客户细分。(未注明)。检索于 2021 年 2 月 10 日,来自https://www.shopify.com/encyclopedia/customer-segmentation

[2]黄耀辉(2019)。市场营销数据科学实践:使用 Python 和 R. Birmingham 通过机器学习改进您的市场营销策略。

[3]米勒,A. C .,圭多,S. (2018)。Python 机器学习导论:数据科学家指南。塞瓦斯托波尔,加利福尼亚州:奥赖利媒体。

[4]利用肘方法确定 k-means 聚类的最佳聚类数。(未注明)。检索于 2021 年 2 月 11 日,来自https://bl.ocks.org/rpgove/0060ff3b656618e9136b

[5]肘法求 k 的最佳值。(2021 年 02 月 09 日)。2021 年 2 月 11 日检索,来自https://www . geeksforgeeks . org/elbow-method-for-optimal-value-of-k-in-k means/

数据驱动的骑行和锻炼预测

原文:https://towardsdatascience.com/data-driven-cycling-and-workout-prediction-72c393e2542c?source=collection_archive---------14-----------------------

将旧的骑行锻炼数据转化为基于 ML 的数字私人教练,用于锻炼预测

在这篇博文中,我将分享我如何利用微软机器人框架和微软团队,将自行车练习中的数据转化为基于机器学习的智能机器人,这帮助我在训练中取得更多成绩,并始终保持动力。

概观

我在 2020 年 1 月底开始骑可折叠自行车,我爱上了骑自行车。我也喜欢处理数据,所以我用智能手表记录了我去斯特拉瓦的所有旅程。🚴🏻🚴🏻

五月底,我将我的城市自行车升级为沙砾自行车。直到秋天,我和我的新自行车在户外活动中度过了美好的时光。

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

伊斯坦布尔的户外骑行,图片由作者提供

在天气好的时候在外面练习之后,对于寒冷的天气,我在家里设置了一个疼痛洞穴,使用 Elite 阿里翁 AL13 rollerMisuro B+传感器Zwift 上进行虚拟骑行。Zwift 是一个虚拟环境,在这里你可以与你的 3D 虚拟角色连接,与其他运动员一起实时骑行。

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

室内游乐设施,作者图片

我的 Zwift 帐户与 Strava 连接,收集我所有的骑行数据,目前我已经完成了**“3700km”**的户外和室内活动🎉🎉

我决定分析我的数据,在分析之后,我决定用我的工程能力将它提升到一个新的水平。

这份报告展示了如何分析您的 Strava 数据,并使用 Jupyter 笔记本将其可视化。此外,该项目旨在预测潜在的锻炼日期和距离,以使用您自己的数据找到最佳的锻炼计划。这款数字私人教练可以作为健身伴侣使用。

这个项目最初是从 Jupyter Notebook 上现有批量数据的数据发现开始的。在数据探索阶段,我看到了一些模式,并认为,这些模式可以帮助我恢复健康。不久之后,我决定建立一个预测模型来预测我的锻炼、ride typedistance值。为了在 bot 框架中使用预测模型,该模型被导出为 pickle 文件,一个基于 FastAPI 的应用程序在 Python 中为该模型提供服务,微软团队中的一个聊天机器人调用该 API 帮助我提供一些输入,然后检索预测。

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

建筑,作者的图像

数据发现—亮点

让我们来看看我到目前为止取得的一些亮点,这里是一些关于我的数据的亮点。

  • 在 1 年的时间里,我已经完成了大约 3700 公里,包括户外和室内锻炼活动。大约 1/3 是 Zwift 上的虚拟乘坐。

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

户外和室内骑行的总距离 km,图片由作者提供

  • 2019 年,我增加了一些脂肪,但由于我的身体活动和一些健康的食物,我在这段时间里减掉了约 13 公斤(约 28 磅)。

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

一年内的总重量,图片由作者提供

  • 我喜欢下面展示一年中发生的所有重要生活事件的每周图表。

Jan-Mar:对锻炼充满热情

4 月至 6 月:疫情和土耳其的封锁

6 月至 12 月:享受户外和室内骑行

12 月:新年假期挑战#Rapha500

简:幸运地有了一个新的家庭成员:)

1 月至 3 月:试图重新找到我的老习惯,最后但并非最不重要的是,决定建立一个数字私人教练。

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

每周总距离,按作者分类的图像

  • 到目前为止,我一次骑行的最长距离是 62 公里,我喜欢这个显示我一段时间内表现的图表;

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

户外骑行与室内骑行的每次骑行距离,图片由作者提供

相互关系

当我检查乘坐类型时,我意识到在某一点后我只切换到室内虚拟乘坐,我想看看选择室内乘坐和天气之间是否有相关性,特别是与WindTemperature的相关性。为此,我在训练中使用天气 API 来检索天气状况,结果很清楚;我不喜欢在寒冷的雨天骑自行车,所以过了一会儿,我又回到了室内虚拟骑行。下图显示,在一定温度下,我选择了室内骑行。这是其中的一个特征——我已经加入到我的预测模型中。

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

游乐设备类型与温度,图片由作者提供

特征工程

我花了一些时间用 Jupyter 笔记本可视化我的乘坐数据,我发现了一些模式。这些模式要么是我有意识的决定,要么是条件使然。

我决定做一个关于特征工程的练习

1.游乐设备类型

游乐设备类型是影响训练持续时间和天数的一个因素,所以我添加了一个标志来表示游乐设备是室外还是室内

  • rideType —布尔标志

2.气候条件

正如在相关性中提到的,天气是影响我锻炼计划的因素之一:

  • Temperature -摄氏温度值为整数
  • Wind - km/h 值为整数
  • Weather Description -描述天气是否多云、晴朗、下雨等。

3.星期几和周末

当我将距离与周末或工作日进行对比时,我发现我最长的骑行时间是在周末。公共假期是另一个因素,但是现在,我决定不把它们整合在一起。

  • DayOfWeek -整数

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

一周中某一天的总距离,按作者分类的图像

但我主要选择了周二和周四作为工作日短途骑行日,并决定添加一天中的一周作为一个功能,并根据下图使用周末作为标志

  • isWeekend -布尔标志

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

工作日和周末的总距离,按作者分类的图像

4.一天中的某个时刻

在炎热的夏天,我更喜欢在温度比中午凉爽的时候进行户外骑行。基于下面的情节,一天中的某个时刻影响着我的乘坐和乘坐类型,所以我决定为一天中的某个时刻添加一个功能

  • hour -整数

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

距离与一天中的时间,作者提供的图片

预测模型

出于我个人的需要,在数据分析之后,我希望有一个输出distanceride type的预测,T3 是指我预计要骑行多少公里,而是指计划的骑行是室内还是室外。

因此,我使用之前的数据分析和工程特征来创建DistanceRide Type的预测模型。

1.乘坐类型预测

就心理准备而言,室内和室外骑行是有区别的,所以一般来说,我会根据我的骑行类型在锻炼前一天准备好我自己和我的骑行设备。我确实喜欢出去,但是我不喜欢下雨和寒冷的天气。此外,我想找到最适合我锻炼的骑行方式。

这个选择也影响了我的锻炼距离和时间。由于这是一个分类问题,我决定选择Logistic Regression来预测乘坐类型。

设置训练数据:

2.距离预测

每周,我都会设定我想要完成的每周距离目标。这个决定也受到外部因素的影响,比如“一天中的什么时候?”,“天气怎么样?”,“外面热还是外面冷?”,“风大吗?”、“是周末还是工作日?”

考虑到这些因素,我想预测一下我的预期骑行距离。这是一个Regression问题,我决定选择Linear Regression进行距离预测。

对于这两种模型(预测距离乘坐类型,以下是我决定在我的模型中使用的工程特性:

*['hour','dayOfWeek','isWeekend','temp','wind','weather']*

虽然我已经决定选择Logistic Regression作为乘坐类型,选择Linear Regression作为距离,但可能会有更精确的模型。开发这些模型的过程是迭代的,通常需要更多的游乐设备数据,所以这只是第一步。

有个好看的机器学习算法小抄。您可以了解更多关于 ML 算法及其应用的信息。

模特培训

对于锻炼预测,机器学习模型训练被添加到 7 — b 预测锻炼模型训练。ipynb Jupyter 笔记本。以下是训练模型的一些步骤:

首先,我用选定的特征(X)设置训练数据:

# select features as list of array
X = data[['hour','dayOfWeek','isWeekend','temp','wind','weather']]
X = X.to_numpy()

然后我创建训练数据的标签(Y):

# set Distance values
Y_distance = data['Distance']
Y_distance = Y_distance.to_numpy()
​
# set Ride Type Values
Y_rideType = data['rideType']
Y_rideType = Y_rideType.to_numpy()
  1. 用于 RideType 预测的 Logistic 回归

对于逻辑回归,我提供所有数据用于训练,并拟合我的最终模型。该模型使用了以下特征['hour','dayOfWeek','isWeekend','temp','wind','weather']

训练数据特征:

  • hour -值在 0 - 23 之间
  • dayOfWeek -值在 0 - 6 之间
  • isWeekend -工作日 0,周末 1
  • temp -以摄氏度为单位的整数温度值
  • wind——以千米/小时为单位的整数风速值
  • weather -天气 API 提供的天气描述

训练预测值:

  • rideType -室外骑行 0,室内骑行 1
# import Logistic Regression from sci-kit learn
from sklearn.linear_model import LogisticRegression
​
# select training data and fit final model
model_lr = LogisticRegression(random_state=0).fit(X, Y_rideType)
​
# test prediction with a clear sunny Sunday weather data
result_ridetype = model_lr.predict([[8,6,1,20,3,0]])
print("Result type prediction=%s" % result_ridetype)
​
# test prediction with a cold Sunday weather data
result_ridetype = model_lr.predict([[8,6,1,10,12,1]])
print("Result type prediction=%s" % result_ridetype)

2。距离预测的线性回归

对于预测模型,我总共有 168 个锻炼数据,我想将它们全部用作训练数据。

训练数据特征:

  • hour-0-23 之间的值
  • dayOfWeek-0-6 之间的值
  • isWeekend -工作日 0,周末 1
  • temp -以摄氏度为单位的整数温度值
  • wind——以千米/小时为单位的整数风速值
  • weather -天气 API 提供的天气描述

训练预测值:

  • distance -以公里为单位的距离值。
# import Linear Regression from sci-kit learn
from sklearn.linear_model import LinearRegression
from sklearn.utils import shuffle# select training data and fit final model
model = LinearRegression()
model.fit(X, Y_distance)# test prediction with a cold Monday weather data
result_distance = model.predict([[8,0,0,10,15,0]])
print("Result distance prediction=%s" % result_distance)# test prediction with a sunny Sunday weather data
result_distance = model.predict([[6,6,1,26,3,1]])
print("Result distance prediction=%s" % result_distance)

3。将模型导出为 pickle 文件

在这个阶段,经过训练的模型被导出为 pickle 文件,以便通过 web API 使用。web API 使用来自天气 API 的数据,收集必要的数据特征进行预测,并将预测结果输出给用户。

# import pickle library
import pickle
​
# save distance model file in the model folder for prediction
distance_model_file = "../web/model/distance_model.pkl"
with open(distance_model_file, 'wb') as file:
 pickle.dump(model, file)
​
# save ride type model file in the model folder for prediction
ridetype_model_file = "../web/model/ridetype_model.pkl"
with open(ridetype_model_file, 'wb') as file:
 pickle.dump(clf, file)

解决办法

这是一个端到端的解决方案,使用 Strava 锻炼数据导出作为输入。Strava 包含室内和室外健身骑行数据。为了分析数据,Jupyter 笔记本用于Data CleaningData Pre-ProcessingModel Training和`模型导出。对于机器学习模型训练和预测,使用 scikit-learn Python 包。预测模型由 scikit-learn 导出,用于预测我的骑行类型和锻炼距离。

该模型作为 pickle 文件通过 FastAPI 应用程序托管,该应用程序提供了一个 API 来传递参数,并使用第三方天气 API 预测天气信息。模型使用这些值进行预测。

作为一个用户界面,我使用微软 Bot 框架创建了一个对话式 AI 项目,与 Fast API 进行通信。我选择微软团队作为画布,因为这是我经常用来交流的平台。

有了这个解决方案,我现在可以选择我的城市、锻炼日期和时间,我得到了一个提供distanceride type值的预测。

体系结构

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

建筑,作者的图像

文件夹结构:

  • bot - Bot 应用程序检索预测模型
  • data -数据文件夹包含 Strava 输出
  • notebooks-分析所有数据的所有笔记本
  • web -预测模型的 FastAPI
  • model -包含预测模型
  • app.py -用于预测模型的 FastAPI web 应用
  • myconfig.py -环境变量
  • utils.py -常用实用功能

运行项目

在这个示例中,使用 Python 3.8.7 版本来运行项目。

  1. 创建虚拟环境
python -m venv .venv

2.激活您的 Mac 虚拟环境:

source ./venv/bin/activate

3.安装依赖项

pip install -r notebooks/requirements.txt

4.从您的个人资料中导出您的 Strava 数据

5.创建一个Data文件夹,并将您的 Strava 数据导出到该文件夹中。

6.在本地运行Jupyter Notebook

jupyter notebook

天气 API

无法获得天气数据来将与我的锻炼相关联,所以我使用天气 API 来提取我现有锻炼日的天气信息。我已经使用了 WorldWeatherOnline API 来获取我所在地点的最新天气预报。这个 API 还提供了提前 14 天的天气预报,每小时的天气预报和天气警告,所以这对我的预测 API 也很有帮助。

python FastAPI API 的 Web 应用程序

运行 Python FastAPI 以便在本地机器上运行

cd webpython app.py

测试终点

发布 Web 应用程序

将 Python FastAPI 发布到 Azure Web App 服务

cd web
az webapp up --sku B1 --name data-driven-cycling

在 Azure 门户上更新启动命令,设置>配置>常规设置>启动命令

gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app

要重新部署和更新现有应用程序:

az webapp up

在本地测试 Bot 应用程序

先决条件:

cd bot
dotnet run

或者来自 Visual Studio

  • 启动 Visual Studio
  • 文件->打开->项目/解决方案
  • 导航到bot文件夹
  • 选择CyclingPrediction.csproj文件
  • Bots/Cycling.cs更新你的 api url
  • 如果您想使用本地 Web API 进行测试,请更改您的本地端点,例如:
string RequestURI = String.Format("[http://127.0.0.1:8000/predict?city={0}&date={1}&time={2](http://127.0.0.1:8000/predict?city={0}&date={1}&time={2)}",wCity,wDate,wTime);
  • 如果您将使用 Azure Web API 进行测试,请更改您的 Azure 端点,例如:
string RequestURI = String.Format("[https://yourwebsite.azurewebsites.net/predict?city={0}&date={1}&time={2](https://yourwebsite.azurewebsites.net/predict?city={0}&date={1}&time={2)}",wCity,wDate,wTime);

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

用于测试的模拟器上的机器人,图片由作者提供

之后,你的机器人就可以进行交互了。

微软团队中的机器人

发布 bot 后,您可以连接不同的对话用户界面。我已经连接了微软团队,并命名为Data Driven Cycling Bot

一旦您发送第一条信息,它就发送一张卡来选择CityDateTime信息,以预测健身骑行类型和最小距离。

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

微软团队中的机器人,图片由作者提供

结论

这是一次从我现有的数据中发现见解的个人旅程,然后变成了一个数字私人教练。

对于接下来我想重点介绍步骤,

  • 设定每周目标,并根据我的目标预测本周的锻炼计划。
  • 比较游乐设备指标,查看随时间推移的改进情况。
  • 支持美国指标(现在仅支持 km)

代码可在
https://github . com/ikivanc/Data-Driven-Cycling-and-Workout-Prediction获得

期待听到新的想法和开放的贡献。

谢了。

数据驱动的足球运动员技能评估

原文:https://towardsdatascience.com/data-driven-evaluation-of-football-players-skills-c1df36d61a4e?source=collection_archive---------11-----------------------

实践教程

这提供了一个通用的方法来衡量任何足球运动员的控球技术水平,并对射门技术进行了样本分析。

Wix.com 大学的数据科学家 Ofir Magdaci

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

作者图片。

先验知识

为了真正掌握要介绍的所有概念,强烈建议您熟悉 StatsBomb xG 指标。这篇伟大的 fbref.com 文章可以提供你需要的所有信息。

激励和总结

在最后两篇文章中,我既介绍了解释了两个主要模型,这两个模型让我们能够用数学方法来表示足球的语言: Action2VecPlayer2Vec 。我们研究了它们的含义、语义和动力学。我们的结论是,这些模型描述的是玩家做什么,而不是他们做得有多好。显然,玩家的技能水平在我们的建模中是一个缺失的元素,这就是这篇文章所要讲的。

足球涉及多种技巧。一些是有球技能,如传球和运球,而另一些是无球技能,如移动到死区或盯人。第二类通常更具挑战性,通常需要更丰富的数据。到目前为止,持球技能是最普遍和最被考虑的。

足球分析行业的兴起导致了无数种测量、比较和可视化球员技能的方法。然而,由于球队的战术或比赛风格,许多方法是有偏见的,通常忽略了动作的变化。这些提高了对客观的、数据驱动的测量的需求,这将为玩家评估设定标准。

在这项工作中,我提出了一种技能评估方法,它与数据科学和机器学习中的现有方法不相上下。这种方法适用于任何技能,无论是有球还是无球,只要有合适的数据。这里我就为 拍摄分析演示一下这个机制。

数据集

与之前的作品一样,本作品的数据基于 Statsbomb 开放数据集。文档可以在数据集的 Github 库站点上获得。

缩小技能水平差距

什么是技能

技能的构成可能比你想象的更难定义。字典暗示“… 执行某个动作的能力”。然而,举例来说,射击是一项复杂的任务,有许多变化和困难。此外,可以用不同的技术、角度、范围等进行拍摄。但最终,它仍然是推测性的——即使是一个顶级得分手也可能在任何一天错过一个好机会。

想想像跳高这样的运动项目。挑战明显不那么复杂——障碍越高,越难克服——然而,对于一个固定的障碍高度,结果总是一个概率事件。

因此,一项技能更好的定义可能是 在特定难度下完成特定任务的可能性 。我们可以用一个概率分布来描述一个玩家完成动作的技能“ ”一个 ”,其中 l 是难度级别。鉴于任务的难度,成功的可能性是未知的,Sₐ(L=l)。

如何衡量技能分布?

要凭经验估计一个玩家的投篮技术的分布,需要两件事:对于各种条件的**(等于 1 —难度)结果 。对于拍摄,对应的是拍摄的 xG 值及其结果。

估计每一枪的概率不是一件小事。幸运的是,Statsbomb 好心地将 https://statsbomb.com/2020/07/statsbomb-release-expected-goals-with-shot-impact-height/ 他们的 xG 度量添加到数据集中,这给了我们从枪击事件中得分的概率。因此,得分的概率越高,击球难度等级就越低。

注意:我必须澄清,xG 模型,或者我将讨论的任何其他概率模型,旨在预测击球的预期 结果。因此,这种模型忽略了个人数据(例如,球员的弱脚质量)。它是关于估计每一次击球的“净值”,而不是它的确切结果。

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

图 1:数据集中所有镜头的 xG 分布。除了惩罚的 xG 值(在 0.75-0.8 之间)之外,分布是高度偏斜的。

一旦我们估计了技能分布,Sₐ(L),我们就可以计算一些指标。

升力的概念

**提升的概念在数据科学界被广泛使用。它通过将两者相除来比较指标和基线。该比率表明计算值比基线高出多少。

xG 提升 AUC:从分配到 KPI

要生成一个数字作为 KPI(关键绩效指标),我们可以计算技能分布 AUC (曲线下的面积)。尽管如此,我发现使用比率,即 AUC 和预期得分 AUC(等于 0.5)之间的 lift、来指示球员比预期好多少,更能提供信息和交流。

图 2:xG 分布图对比。xG 转换被描述为一种分布,其中虚线表示作为基线的预期性能。“提升”指数衡量的是每个球员比他们的预期表现好多少。xG AUC 将分布缩小为单个标量,作为 KPI 使用。

图 2 显示了几个玩家的 xG 分布,与根据 StatsBomb 的 xG 指标的预期性能进行了对比。

当描述为分布时,我们可以更清楚地看到更大的画面。我们可以观察并注意到水平上的表现差异,检测心理信号,如错过重大机会(如路易斯·苏亚雷斯),并更好地理解球员之间的权衡。不出所料,梅西在任何给定的难度下都超过了基准,总体上实现了 1.15 的 xG Lift AUC。

不同拍摄类型的 xG 提升

这个 KPI 集合显示了与由 StatsBomb 的 xG 度量估计的预期性能相比,玩家在执行特定击球类型 时有多好。它的计算非常简单:

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

公式 1:xG 提升指数,表示对于任何给定的射门(例如,任意球、远射等),球员的表现超出预期的程度。)

电梯的利与弊

使用这种方法有两个主要挑战。首先,估计行动的难度通常需要非常丰富的数据,如 Statsbomb 360StatsPerform 跟踪数据。其次,计算概率是不容易的,有时也是不清楚的。例如,如何估计运球的难度?对一个对手有效的方法对另一个拥有高超拦截技术的对手可能完全无效。

为了弥补这些障碍,该指标提供了大量优势:

它简单且易于实施。

它与数据科学中的现有衡量标准——Lifts 和 AUC 相当。

直观的底线:球员比预期好多少。

它很健壮,可以应用于任何运动和技能。

但也许最大的附加值是能够只分别评估不同类型的镜头。比如我们可以只在远射、任意球、或者一对一上计算 xG 升力*。正如你可能已经知道的,我很少在没有亲自执行的情况下提出想法…***

可视化技能水平

图 3 显示了根据 StatsBomb 公开数据集估算的小内马尔技能雷达图。这些值是提升百分位数*,考虑到数据集中所有合格的玩家——那些至少有 30 次击球的玩家。*

这给了我们一个清晰、一致、标准化和规范化的尺度。或者,当所有类别都用升程衡量时,也可以使用原始升程值。

相似的类别尽可能放在一起,以避免排序偏差。玩家射击技能被分成不同的子类别和上下文。这些上下文可以应用于性能评估、玩家搜索或开发。通常情况下,球员们在与其他人斗争的同时,在某些射门类型上表现出色,当然,除非你的名字是利奥·梅西(图 4)。

图 3——不同基线下的内马尔互动技能雷达图。此分析的合格玩家至少有 30 个镜头,每个镜头类型有 10 个实例。如果玩家对一种类型的投篮次数少于 10 次,但总的投篮次数多于 30 次,那么他得到的 Lift=1,这表明他的表现符合预期,不会影响结果。

仔细看,xG 升力图类似于雷达图。事实上,它是雷达图的缩小,其中轴折叠成单个射击指数。高 xG 值当然包含子技能,比如一对一的收尾,点球,还有部分头球。然而,低 xG 值主要包括远射和任意球。然而,在这两种情况下,总音量越高,记录的技能水平越高。这是如何正确排序类别的另一个提示。

当然,这种技术既有好消息也有坏消息……好消息是我们可以将这种方法应用到任何我们可以测量的技能上,比如运球和传球!然而,这也包括坏消息,因为我们无法使用事件数据来衡量其他一些技能(例如死区覆盖或标记)。

图 4——里奥·梅西的技能雷达图,大部分技能都很出色。他的头球升力相对较低,因为它低于 1,而许多球员得到了默认值 1。其次,梅西是目前数据集中射门次数最多的球员,而大多数球员的射门次数都很少,这造成了明显的统计偏差(见下一部分)。

寻址数据偏差

Statsbomb 开放数据集本质上是二十年来数千个匹配样本的拼贴。这些比赛起源于许多比赛,各大洲,男女都有。更重要的是,它是而不是 随机收集的(参见:文档)。因此,数据非常稀疏,有偏见,并且往往集中在顶级球队和联赛,而不是足球运动员和比赛的真实分布。

因此,每个球员的投篮分布是如此的倾斜,以至于我不能很好的画出来。我宁愿用数字展示给你看:

*Mean shots per player: 5.2, STD: 46.4.
  ╔════════════╦══════════════╗
  ║ Percentile ║    #Shots    ║
  ╠════════════╬══════════════╣
  ║    25%     ║        0     ║
  ║    50%     ║        1     ║
  ║    75%     ║        1     ║
  ║    90%     ║        8     ║
  ║    95%     ║       14     ║
  ║    99%     ║       56     ║
  ║    Max     ║    2,190     ║ Messi
  ╚════════════╩══════════════╝*

由于数据集是而不是随机的,大多数玩家很少被评估击球。为了解决这个问题,我过滤掉了所有出手次数少于 30 次的玩家——然而有些托举还是太激进了(图 5)。对于拥有数百次投篮机会的球员,我们确实得到了准确、真实的数字。**

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

图 5:数据集中合格玩家的投篮命中率分布。符合条件的玩家至少有 30 发。

如何正确使用雷达图的 5 个技巧! ✍

雷达图可能是足球分析社区中最受欢迎的图表,因为他们可以在同一张画布上以非常直观的方式展示许多技能。不幸的是,它也有许多可能的故障点——这可能使它成为所有图表中被误用最多的图表。

以下是帮助您创建完美雷达图的方法:

1。观察你的变量的顺序:雷达图逻辑很简单——多边形的体积越大,玩家在所列技能中表现越好。通过连接相邻的点来创建体积。因此,交换图表中两种技能的位置可能会产生戏剧性的效果:

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

图 6:两张相同球员数据的雷达图,但类别排序不同。在右边,相邻的技能是相关的,因此排序正确。在左边,语义排序缺失,使我们无法理解每一个玩家是什么类型的。

2。避免使用依赖战术的类别——这可能是最大也是最常见的错误。在一场比赛中,计算成功运球/铲球的次数是没有意义的。这些措施在很大程度上取决于球队的质量、比赛风格或者教练的指示。相反,使用诸如“成功的一对一防守行动的百分比”这样的指标。

3。使用相对数字 —所有值都应该与有意义的基准相关。例如,我们可以用百分位数来代替显示一场比赛中一名球员运球获胜的百分比。

4。保持你的 刻度固定——比如当使用提升或百分位数时。当每个维度尺度不同时,我们可能会通过制作有偏见的图表来误导读者。

5。添加基线 —例如,相同位置球员的平均表现——这对于数据集中其他球员的全球可比性至关重要。在尺度不一致的情况下更是至关重要。

可能的附加分析

这些分析需要更大、更平衡的数据集。然而, Football2Vec 库也包含了他们的代码供你探索:

  • 比较不同维度的 xG 提升曲线— 这种分析可能揭示一些关于不同比赛位置、年龄和比赛的技能水平变化的见解。
  • 比较训练托举和比赛托举 —这可能是影响球员表现的心理或战术效果的指标。

用令人惊叹的用户界面将这一切包装起来

是时候让所有的东西都聚集在一个漂亮的流线型用户界面上了。这个超级易于使用的 Python 包已经成为我最喜欢的与我的工作进行交互的包,并使它对其他人很友好。为此,我构建了一个简单的玩家控制面板,具有以下特性:

1.情报室

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

信息区包含:(a)团队和球员选择的滑动条;(b)玩家图像,以及©元数据。图片作者。

2.玩家技能分析部分

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

“分析”参数控制面板。图片作者。

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

技能部分包含两个子部分:(1)带基线的技能雷达图。(2)徽章-对于提升值大于阈值[=1.1]的玩家,每种击球类型都有一个唯一的图标。图片作者。

3.玩家进化区(可折叠)

分析球员的技术和赛季表现。包含两个剧情动画图表:

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

各赛季玩家技能雷达图动画(plot . py**>【玩家 _ 进化】**),集成控件。图片作者。

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

各季动画动作热图(见plot . py>)带集成控件。它描述了一年中动作的频率和位置。图片作者。

4.xG 评估(可折叠)

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

xG 评估部分提供了两个图表:(1)击球转换率分布图(顶部)——绘制了如图 2 所示的单人游戏的 xG 转换率分布图*;**(2)xG Lift by body part——分析选手的头部和腿部表现。图片作者。*

5.播放器 2Vec 嵌入部分

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

播放器 2Vec 部分呈现(1)播放器 2Vec ( UMAP )嵌入图,以及通过余弦相似性以及欧几里德距离与所选播放器最相似的播放器。

所有代码都可以通过 Football2Vec Python 开源库获得。

摘要

在这篇文章中,我们揭开了技能评估的世界。从零开始,我们首先定义了什么是技能,我们如何从数学上形式化它,以及我们如何从经验上衡量它;我们了解了用于评估不同类型拍摄的升力*(公式 1) xG 升力xG 升力 AUC — 的概念。*

然后,我们将重点转移到如何正确地可视化技能,并强调重要的最佳实践;借助 Streamlit 的强大功能,我们能够将复杂的模型和统计数据转化为易于理解的交互式漂亮用户界面。

在这三篇文章中,我们经历了一个端到端的数据科学之旅,以创建足球语言的整体表示。我们的目标尚未实现,但在实现目标的持续探索中,我们刚刚成功抵达大本营。

下一步是什么?

现在我们的方法涵盖了玩家做了什么,以及他做得有多好(至少他射得有多好)。剩下的工作就是找到一个有足够数据量的下游任务来学习。当然,额外的技能可以根据需要进行建模。

我希望你觉得这三部曲读起来有趣。感谢所有的反馈,这真的很有趣!

游戏,设置和匹配。

数据驱动并没有消亡

原文:https://towardsdatascience.com/data-driven-isnt-dead-3230378e4c7a?source=collection_archive---------23-----------------------

行业笔记商业科学

问题不在于术语;而是我们不是真心的

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

资料来源:皮奥特·科诺乌,数据

每隔几年,数据科学和技术术语就会出现在商业词典中,只是变得流行、被过度宣传,然后就不再流行了。机器学习、人工智能和许多其他技术都遵循这些模式。不幸的是,即使是最基本的想法也会成为这个循环的牺牲品。

最新的受害者:数据驱动。

数据驱动意味着什么?

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

马库斯·斯皮斯克Unsplash 上拍摄

难怪人们开始厌倦大数据和术语“数据驱动”。如今,几乎每个公司都声称拥有数据驱动的衣钵。

不是无缘无故的。数据已经成为任何市场成功的关键。甚至你的本地街角熟食店也可能在利用数据做出一些商业决策。这一现实导致了意料之中的反弹。当然,并非所有所谓的数据驱动型企业都以同样的方式使用数据。

那么,数据驱动意味着什么呢?其核心是,数据驱动型公司利用他们的数据做出更好的决策,创造更佳的结果。他们从公司每天收集的大量数据中发现模式和见解,以便更有效地实现业务目标并提高 KPI。

简而言之,数据驱动型公司利用他们的数据来推动最佳结果。

一家熟食店看着某一特定专业的大量订单,决定把它作为一个常规的菜单项目,可能无法完成复杂的分析。尽管如此,如果这个决定增加了收入或者让更多的人进来,他们可能会满足“数据驱动”的最低门槛。

当然,将一次性决定等同于文化转变仍然有些牵强。真正的数据驱动型公司不会只是偶尔利用他们的数据。他们围绕决策改变了整个公司文化,通过有效利用数据来改善决策。许多公司将两者混为一谈,这无疑损害了“数据驱动”的声誉。

数据驱动危险吗?

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

万花筒Unsplash 上拍摄的照片

但是这个术语的过度应用并不足以成为抛弃数据驱动的理由。数据驱动的决策仍然是一个关键的竞争优势。

不幸的是,许多人不同意——一些最响亮的声音呼吁我们从我们的词汇中消除数据驱动:数据科学家。

我从数据科学社区的人那里听到了关于为什么数据驱动不再是正确目标的各种争论。有人说,最好是简单的“了解数据的”、“了解数据的”或“了解数据的”:我们的勇气,被做出非常糟糕的决定的数据所检验,应该推动结果。我甚至看到有人提出,数据驱动的决策是危险的,好像人类可能会失去对数据的控制。虽然大数据有其局限性,但分析中的大多数危险和偏见最终来自我们,而不是数据。

“数据驱动”公司的真正问题是

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

克里斯·利维拉尼在 Unsplash 上拍摄的照片

然而,一些反对“数据驱动”的数据科学家确实有一个令人信服的观点。数据驱动往往是不准确的。当你考虑大多数公司如何使用数据时,很难说它真的被用来推动最佳决策。

太多时候,先做一个预测,然后根据这些假设做出决定,以应对现实。例如,一位商店经理查看需求预测,预测他的商店下周将销售 10 件蓝色男士衬衫,他将订购 10 件蓝色男士衬衫来满足该需求。很少考虑销售这 10 件蓝色球衣是否是实现收入或利润目标的最佳方式。数据推动决策,但在整体业务目标的背景下,也许是错误的决策。

预测分析中的这一缺陷通常被标记为数据驱动的决策中的固有缺陷。因为预测只能告诉你可能会发生什么(假设没有危机发生),而不能告诉你在任何情况下如何实现给定的目标,所以数据驱动的思维模式通常被认为是小于。

这没有认识到真正的问题:一个预测性的,而不是指令性的方法。

我们如何用数据驱动结果?

真正的数据驱动型决策利用数据来推动成果:它使用数据向您展示实现业务目标的最佳途径。当我听到一位数据科学家说,基于数据的决策比数据驱动的决策更好时,我只能假设他们使用预测分析来解释这些数据。如果是这样,他们是对的。

在其核心,预测分析是最有用的决策支持工具。他们的存在是为了给你提供信息,给你决策的背景。当你使用它们时,它必须是一种基于数据的方法,因为否则你会冒着朝着错误的目标优化的风险。这是一个随着时间推移而加剧的错误,因为一个优秀的数据科学家会随着时间的推移改进算法,越来越高效地实现次优结果!

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

图片来源: Evo 定价 (CC 带归属)

为了实现数据驱动,您必须进行优化以获得最佳结果。这必然需要一种规定性的方法。在这种情况下,您可以定义最适合您公司的目标,然后利用这些数据帮助您实现目标,不管在此过程中会出现什么样的危机和挑战。这是用数据推动结果并最终实现数据驱动思维的唯一途径。

让数据驱动再次变得有意义

一旦你揭示了数据驱动的辩论背后隐藏的问题,很明显,人们并不喜欢这个词;他们对数据处理方法的局限性深感沮丧。幸运的是,这有一个简单的解决方案。

正确的分析——规范的分析——使得利用数据做出有意义的决策成为可能。

通过这种方式,很明显默认回到基于数据的(或者更糟,仅仅是基于数据的)决策是有局限性的。随着您更有效地利用您的数据,影响会越来越大。组织必须采取更难但最终更好的分析方法:指令性。

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

图片来源: Evo 定价 (CC 带归属)

数据驱动、规范的业务和项目是为成功而设立的。因此,不要因为简单地回到数据信息似乎就足够的时代,就低估了数据的价值。通过正确的分析,您可以有意义地转型为数据驱动型公司。希望,如果我们这样做了,人们会像我现在一样再次喜欢上“数据驱动”这个术语。

PS 更多商业科学来自我的写作:

[## 如何(不)在数据科学项目中失败

towardsdatascience.com](/how-not-to-fail-at-your-data-science-project-7e8c84305aa8)

Monthly Business Science in your inbox, new software, and University-level learning:[**Free access**](https://evouser.com/register)Questions? Please reach out on [Linkedin](https://www.linkedin.com/in/fabrizio-fantini/)

数据驱动的多点触控属性揭秘

原文:https://towardsdatascience.com/data-driven-multi-touch-attribution-demystified-3eb3486476c6?source=collection_archive---------21-----------------------

度量和测量

马尔可夫归因模型入门

有效运营企业的最宝贵信息之一是了解某项业务活动直接产生的收入。

知道哪些努力得到了回报可以让你加倍努力并扩大规模,而了解时间和金钱被浪费在哪里可以让你通过少做多做

这就是归属的问题。

营销人员正面处理这个问题,因为他们必须在多个影响渠道上花费有限的资源。潜在客户在他们的客户之旅中与企业有许多接触点。他们必须不断地问这个问题:

哪个活动/渠道真正赚钱?

这不仅仅是营销问题。你的企业和顾客之间的每一次互动都有助于购买体验,因此,拥有一部分归因难题。

归因不是纯粹的理论练习。它直接关系到你如何有效地利用资源来实现业务增长。使用复杂归因模型将支出与收入对应起来的组织,其收入增长 20%或以上的可能性是 T10 的两倍。

这篇文章将探讨传统上如何处理多触点归因,以及如何通过一点数据魔法来改进你的归因模型。

在整篇文章中,我将使用“接触点”这个词,因为这是一个非常通用的模型,但是请随意将它直接翻译到您自己的领域中。它同样适用于特定的活动、营销渠道、销售行为,甚至是在数字产品中与客户的互动。

传统多点触摸属性

你会如何运用常识为特定客户购买的每个接触点分配信用?

根据您的观点,您可能会对客户旅程中的每次体验的影响应用不同的启发法:

第一次接触
100%的荣誉归于第一次接触点,因为他们将客户带入了我们的世界。

最后一次接触
100%的信用分配给最后一次接触点,因为它让客户迈出了最后一步。

时间衰减
最近的接触点会获得更多的信任,因为最近的接触点可能会对领先优势起到更多的“预热”作用。

线性
为什么我们不能都成为朋友?只要你参与了转化之路,所有人都有同等的荣誉!

第一次接触和最后一次接触思维之间显然存在一种平衡。让我们给第一次和最后一次触摸各 40%的信任,其余的平均分配。

自定义
每个频道都是独一无二的,所以我要根据我认为的重要程度给每个频道加上权重。

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

使用传统多触点归因试探法分配的点数| 作者图片

所有这些试探法有什么共同点?

嗯… 我们编造了它们,这至少会让你感到一点点不舒服。事实上,这种观点得到了近 78%的营销人员的认同,他们不确定自己是否使用了正确的归因模式。

你还必须注意,这些也可能被扭曲,以服务于一个人的激励。例如,如果我有一个潜在客户生成业务,我只是在一个客户的网站上投放广告,那么通过第一接触模式获得 100%的信用并获得相应的报酬对我来说是最有利的💰。

我说“传统方法”,但这是一个误称,因为不幸的是,这是行业的现状。超过 90%的组织没有利用数据为他们的归因模型提供信息,其中大约 1/3 的组织甚至没有尝试跟踪支出到收入。

除了猜测这个核心业务问题,我们还能做得更好吗?

数据驱动的归因方法

我们可以让数据说话,而不是自己制定规则。

有各种类型的模型可供我们使用来解决这类问题。围绕这一主题的大量文献往往集中在 3 种主要方法上。

  1. 幸存
  2. 沙普利
  3. 马尔可夫

生存模型将生物统计学中的“某些治疗对死亡时间的影响”问题转化为“某些接触点对转化时间的影响”生存模型的设置需要几个定义,并且超出了本文的范围。

Shapley 模型来自博弈论的世界,它提供了一种公平的方式,根据参与者的贡献程度在他们之间分配收益。每个接触点都可以被视为游戏中的参与者,回报可以建模为所有客户的总购买价值。

使用匀称的价值观进行归因是一种聪明而直观的方法,具有许多有用的特性。尽管如此,计算所需的计算能力随着接触点类型的数量呈指数增长,这使得它对许多拥有复杂客户旅程的公司来说没有吸引力。值得注意的是,有效地用逼近沙普利值的算法确实存在。

最后一个模型是马尔可夫模型,它直观,抗噪声,伸缩性很好,所以这是我们今天要关注的。

无论您想使用哪种模式,您都需要首先对您的业务进行调整,以捕捉潜在客户接触点事件。这可以是作为 Salesforce 中的任务跟踪销售活动,通过自动化软件的营销活动,或定制的数据收集策略(实习生?🤨 ).

简单马尔可夫归因

一旦你的数据准备就绪,你就可以按照客户与你的业务互动的顺序,开始建立对客户旅程的理解。仅仅通过计算从一次互动到另一次互动的顾客数量,你就可以得到每个接触点的转移概率

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

所有可能转换路径的转换图****|**图片作者

现在我们知道了转移概率,我们可以通过所有可能的转化途径遵循概率链来估计给定数量的潜在客户的转化数量(就像一个漏斗)。**

例如,如果我有 100 个潜在客户,我可以计算转换数量为:

***# Conversions =** 100 ⨉ 30% Website ⨉ 30% Converted +
  100 ⨉ 30% Website ⨉ 40% Facebook ⨉ 35% Converted +
  100 ⨉ 70% Google Ads ⨉ 8% Website ⨉ 30% Converted +
  100 ⨉ 70% Google Ads ⨉ 8% Website ⨉ 40% Facebook ⨉ 35% Converted = 15.664 Conversions*

如你所见,我们只是简单地添加了多个漏斗的效果。唯一转换路径的转换次数是相加的,因此每个路径贡献的转换率也是相加的。

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

每个转换路径对整体转换的部分贡献

我们有每个路径对我们整体转换率的贡献,但是我们仍然需要计算每个接触点的贡献。要做到这一点,我们可以问,“如果我只移除一个接触点,我的总体转换率会怎么样?”**

例如,我们可以通过有效地将所有离开该节点的流量发送到一个黑洞来删除谷歌广告,并使用我们剩余的转化路径来计算我们的转化率。

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

假设从我们的客户旅程中删除谷歌广告| 作者图片

这种假设的去除产生的总转化率为 0.132

*Overall Conversion Rate **without** Google Ads =
  Conversion Rate of (**Start** > Website >**Converted**) +
  Conversion Rate of (**Start** > Website > Facebook >**Converted)**= 0.09 + 0.042
**= 0.132***

如果我们没有谷歌广告的转化率是 13.2% ,这意味着谷歌广告一定只为我们之前的整体转化率 15.6% 贡献了 2.4%

这只占总转化率的 0.024 / 0.156 = 15.38%

这个 15.38% 的值被称为谷歌广告接触点的移除效应,是计算每个节点整体属性权重的关键数字。

计算去除效果的公式可总结如下:

  • Rx =接触点 x 的移除效果
  • Cw =总转换率接触点 x
  • Cr =移除接触点 x 后的图形转换率

Rx=(Cw Cr)/Cw = 1(Cr/Cw)**

能不能用这个去除效果作为每个触点的权重就完事了?

不完全是。但是我们很亲密。

为了理解为什么我们可以看到如果我们删除网站会发生什么,并计算其删除效果。

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

假设将网站从我们的客户旅程中移除| 图片作者

每条路径都经过网站,所以删除效果当然会是 100% 。如果我们给网站一个 100% 的属性权重,其他接触点还有什么属性?

这就是为什么不直接使用移除效果,我们可以通过确定特定触摸点在所有移除效果的总和中所占的比例( RSum )来使用归一化移除效果。

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

每个触摸点的去除效果的属性权重

现在我们有重量了!我们可以通过简单地将每个接触点的归属权重乘以总转换美元金额 V 来计算我们的归属值 A 。这通常是购买金额的总和,但是如果您想了解全部情况,我强烈建议您使用客户终身价值。

A = V ⨉ ( Rx / Rsum )

例如,假设我们的客户总共花费了 100,000 美元,谷歌广告的归属价值将是 100,000 美元⨉0.1066 = 10,660 美元。如果你在谷歌广告上的营销支出少于这个数字,你就获得了正的投资回报。

马尔可夫归因假设

马尔可夫模型很方便,但是它做了一些你应该知道的假设。

第一个假设是移除一个特定的接触点不会导致客户使用转向其他渠道。这个假设在大多数时候都成立,但是你必须考虑你的业务会受到什么影响。

例如,如果你的客户通过谷歌搜索出现在你的脸书页面上,删除脸书可能会将流量转移到你的网站频道,因为它会出现在结果页面的上方。

的第二个假设是,从一个频道到下一个频道存在一些潜在的常数概率*。实际上,不同的客户有不同的隐藏转移概率。分析你对所有顾客的归因效果,确实会给你“普通顾客”的归因权重*

对不同的客户群重复这一练习并找出相似之处和不同之处可能是一个有用的实验。

有趣的是,您可以将这里使用的标准马尔可夫模型扩展为一个隐马尔可夫模型,以推断每个客户的隐藏状态(例如他们是处于“研究模式”还是“购买模式”)。

第三个假设是每个触摸点处的转移概率仅取决于先前的状态。我们知道这根本不是真的。客户的转化倾向肯定会受到客户旅程中接触点顺序的影响。

这就是为什么在实践中,你不仅要考虑先前的状态,还要考虑两个或更多先前的状态。这些叫做高阶马尔可夫模型。

高阶马尔可夫模型

对于二阶马尔可夫模型的情况,我们从观察单个接触点到成对地考虑它们。

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

2 nd 阶马尔可夫模型(仅显示转换路径)| 图片作者

一阶路径 A → B → C → D 变成了 AB → BC → CD 的二阶路径,每条高阶路径的转移概率都是沿着它所构建的低阶路径的转移概率的乘积。例如

即使我们考虑成对的接触点,我们仍然可以通过移除转移图中包含该接触点的所有节点来计算单个接触点的移除效果。**

例如,删除谷歌广告将导致下图:

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

用二阶马尔可夫模型去除效果| 图片作者

我们可以继续其他接触点。移除网站接触点会使所有节点失效,移除脸书会使底部节点失效。计算我们属性权重的数学方法和以前一样。

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

**来自第二和第二阶马尔可夫模型的去除效应和归因权重

值得注意的是,你通常不会在野外看到一阶马尔可夫模型用于多点触摸属性,因为我们确实关心对我们的触摸点有更长的“记忆”。

相反,你可能永远也不会遇到 4 阶或更高阶的马尔可夫模型,因为当你提高模型的阶次时,在某个点上你会得到递减的精度回报。

单触式转换路径

考虑下面的改装客户之旅。

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

包含单点触摸转换路径的转换图| 作者的图像

让我们计算这 3 个接触点的归因权重,但这一次,我们还将计算转化的数量。我们可以假设有 20 个客户进行了转换,并查看理想的多点触摸归因分裂与马尔可夫归因分裂相比如何。

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

单点触摸路径对马尔可夫归因的影响| 作者图片

注意到什么奇怪的事了吗?

对于脸书和网站来说,分享他们转化的部分功劳是有道理的,但是当与该渠道完全没有互动时,他们为什么要从谷歌广告转化中获得部分功劳呢?

这是使用规范化移除效果的注意事项。要在实际部署中解决这个问题,您可以从分析中移除单点接触路径,并对剩余的路径使用高阶马尔可夫模型。然后,您可以简单地添加单点触摸旅程的转换,因为它们的贡献是显而易见的,不需要建模。

现状核实

在这篇文章中,我们一直假设数据驱动的模型会比传统模型更好。虽然在大多数情况下这可能是真的,但我们能衡量他们到底有多好吗?就此而言,我们如何将一个多点触摸归因模型与另一个进行比较?

评估任何归因模型有效性的困难在于,归因权重的“基础事实”对我们来说是隐藏的,因此我们无法判断我们离现实有多远。

解决这个问题的一个有趣的方法是通过整合来自你的业务的数据和来自你的专家的领域知识来创建一个你的客户互动的模拟

通过仔细观察您的客户接触点,拟合数据的统计分布,并对变量之间的交互进行建模,您可以创建与生产数据非常相似的模拟数据。拼图的最后一块是模拟的归因权重,它可以来自您的专家,并将被用作您的归因模型的“目标”。

领域专家可能无法准确指出每个接触点的确切属性权重,但他们应该能够提供有效的 90%置信区间。假设每个场景中所有接触点的属性权重总和为 100%,您可以使用领域专家估计的属性权重分布作为蒙特卡洛模拟的输入,来计算每个属性模型的误差分布。

在这一点上,你可以把归因模型放在一起,看看哪一个更接近目标。你也可以测试许多“假设”案例,并在多个场景中对每个归因模型进行压力测试,以衡量它们如何适应你的业务特有的不同假设条件。这些模拟场景也为你调整归因模型提供了更快的反馈机制。

从这里去哪里

开始使用这个模型的最大障碍不是计算的复杂性;它为您的业务提供收集数据的工具,然后将所有数据集中在一个地方进行分析。只要有一点毅力,这个就能完成。

如果你从事市场营销,你很幸运,因为有像 BizibleAttributionRockerbox 这样的软件供应商可以帮助你连接到你的数据,并为你建立归因模型。

在某些情况下,现成的软件不够灵活,无法处理您的数据收集或建模需求。在这些情况下,你需要开始考虑推出自己的解决方案。

这里也不需要从头开始。像channel attribute这样的 Python 和 R 包只需几行代码就能适合你的模型。

归因建模是一个丰富而迷人的话题。在这篇文章中,我放大了马尔可夫模型,但是我恳求你看看 Shapley 方法,因为,尽管有计算上的挑战,它有许多令人满意的特性。

使用转换路径的自底向上建模也不是数据驱动属性的唯一方式。在某些情况下,衡量接触点可能非常困难,比如广告牌和广播广告。cookies 和数字拼接的不断变化的前景带来了一系列挑战。

营销组合建模这样的自上而下的方法提供了一种在处理汇总信息时计算属性的替代方法。这一系列模型是可解释的、可扩展的和优化友好的,但是可能需要一种实际操作的建模方法。

提到的大多数模型都提供了一种捕捉特定接触点和转换之间的相关性的方法,但是为了说明特定接触点导致了转换,您可以运行受控实验(A/B 测试)并计算该接触点的转换提升

由于在动态商业环境中运行多个实验的高成本和复杂性,这在实践中可能并不总是可行的。然而,除了受控实验之外,还有其他方法来确定因果关系,这些方法使用因果网络作为它们的基础。

正如您所看到的,这是一个热门话题,我们只是触及了表面,但开始学习使用这些数据驱动的多点归因方法中的任何一种,都有可能让您比使用传统方法的绝大多数竞争者拥有更大的竞争优势。

👏如果你喜欢这个话题,留下一些掌声来帮助其他人发现它。👏

想进一步讨论这个吗?在 Linkedin 上留言或联系我。

📕这篇文章最初发表在 Show Me The Data 博客上,在那里我讨论了更多关于数据驱动业务的话题。

简而言之,数据驱动的预测性维护

原文:https://towardsdatascience.com/data-driven-predictive-maintenance-in-a-nutshell-ccc65a13b998?source=collection_archive---------18-----------------------

基本概念和流行算法概述

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

布雷特·乔丹在 Unsplash 上的照片

对于像飞机、铁路、发电厂这样的复杂系统,维护是一个大问题,因为它确保系统在其生命周期内的可靠性和安全性。

通过利用先进的传感器功能、物联网技术和数据分析算法的力量,工业 4.0 时代的维护经历了从“被动”到“主动”的快速转变:不是只在故障已经发生时才执行维护,最先进的策略是主动预测系统降级并“及时”安排维护。这种新型维护被称为预测性维护 (PdM)。

实际上,PdM 通常是通过首先使用传感器持续监控系统的健康状态来实现的。随后,数据分析算法被用来根据最新的测量结果预测系统的剩余使用寿命。最后,相应地设计一个维护时间表来维护系统的原始预期功能。

PdM 的核心是预测技术,它能够在给定实时测量数据的情况下预测在役系统的退化趋势。这就是数据科学大放异彩的地方:机器学习模型通常用于识别系统当前健康状态的特征,并预测系统故障发生前的剩余时间。

在本帖中,让我们仔细看看执行预测任务时常用的数据驱动模型。这篇文章的结构如下:

  • 首先,为了做好准备,我们将简要回顾一下预测性维护的主要步骤。
  • 第二,我们将根据系统的特征将系统分为不同的类别,并且我们将针对每个系统类别讨论流行的机器学习模型。
  • 最后,我们将讨论交付可靠的预后分析所面临的挑战。

我们开始吧!

1.预测性维护的主要步骤

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

图 1 预测性维护的主要步骤。(图片由作者提供)

PdM 的主要步骤包括数据采集、诊断、预测和健康管理,如上图所示。

1.1 数据采集

数据采集步骤处理从传感器收集测量数据,并处理原始信号以提取可指示系统健康状态的有用特征。后一项任务通常被称为数据科学中的特征工程。

为了提取特征,信号处理技术通常用于将原始数据转换成不同域中的特征(例如,时间、频率、时间-频率)。由于 PdM 主要遇到非平稳信号,时频分析工具可以方便地提取用于诊断和预测目的的特征。在这一类别下,短时傅立叶变换、小波包分解、经验模式分解和希尔伯特-黄变换是最流行的方法。

特征提取之后的附加步骤是特征缩减。这是因为所提取的特征通常太多而无法在实践中利用。流行的降维方法,如主成分分析、核主成分分析、Isomap 等。通常用于消除冗余特征。

1.2 诊断

诊断步骤基于提取的特征值处理故障检测和故障模式识别。

故障诊断通常被公式化为一个分类问题。因此,流行的分类方法,如 k-最近邻、支持向量机、决策树、随机森林,被广泛用于预测给定特征值的系统健康状态标签。下面给出了应用决策树模型对系统故障模式进行分类的简单说明。

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

图 2 使用决策树进行故障诊断。(图片由作者提供)

1.3 预测

PdM 的下一步是预测。这里,目标是预测被监控系统的未来状态,并估计系统的剩余使用寿命(RUL),即,直到系统故障发生需要多长时间。

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

图 3 是预后分析的示意图。(图片由作者提供)

预测是推动智能 PdM 的关键技术。由于它预测系统不再执行其预期功能的时间,因此它为用户提供了在延长系统使用寿命的同时降低故障风险的机会。

自然,数据驱动的方法被大量研究以估计 RUL。因此,一系列机器学习策略被提出用于各种应用场合。在第三节中,我们将回顾一些常用的 RUL 预测方法。

1.4 健康管理

在检测到系统故障并估计出系统的剩余使用寿命之后,是时候根据所获得的结果采取一些行动了。

健康管理步骤的主要目标是以最佳方式管理维护和后勤支持,即实现增加的可用性、可靠性和安全性,以及降低的维护和后勤成本。健康管理通常被公式化为一个约束优化问题,其中采用全局优化算法来获得最佳的维护计划。

2.系统特征的分类

根据所考虑的系统类型,预测方法通常有所不同。因此,在讨论各个类别下的具体方法之前,先根据各种系统的特点对它们进行分类是一个好主意。

2.1 系统特征

一般来说,我们可以根据系统的状态是直接可观测的还是间接可观测的,以及其状态是被建模为离散过程还是连续过程来对系统进行分类。下面的决策树说明了这种分类方案。

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

图 4 预后方法的分类。(图片由作者提供)

2.2 直接或间接可观察?

第一个标准是系统状态的可观测性。

在某些情况下,监测数据可以直接描述系统的底层状态,如磨损和裂纹大小。对于这些情况,RUL 的估计可以有效地公式化为时间序列预测问题。

然而,在许多其他情况下,监测数据只能间接表明系统的基本状态,如旋转机械的振动和基于油的监测。在这些情况下,我们可以将预测问题设计为求解两个耦合方程:

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

图 5 我们可以把预测问题框架为求解两个耦合方程。这里,索引 k 表示时间标准。(图片由作者提供)

测量方程弥补了测量特征值和内部系统状态之间的差距。这里, h (。)表示测量模型, ν 表示测量噪声。

同时,我们用一个状态演化方程来描述系统的退化过程。在这里, f (。)表示退化模型, w 表示模型不确定性。引入这个不确定项是因为退化模型只能部分反映真实的物理过程。

2.3 离散或连续状态演化?

第二个标准是基于我们如何对系统的状态演化建模。

对于某些情况,我们假设系统在有限状态空间φ= { 0,1,…, N }上演化,其中 0 对应于完美健康状态, N 代表故障状态。这些离散状态可以基于实践中有意义的操作条件来导出,例如“良好”、“仅轻微缺陷”、“需要维护”,或者它们可以通过将无监督聚类技术应用于训练数据来导出。

对于其他情况,将系统演化建模为一个连续的过程可能更有意义。例如,通常作为锂离子电池健康指标的电池内阻在经历一系列充放电循环后会不断降低。

3.预测算法

在本节中,我们将讨论一些常用的用于预测目的的机器学习方法,即预测系统的剩余使用寿命(RUL)。我们根据上一节介绍的类别来组织我们的讨论。

3.1 马尔可夫模型

马尔可夫模型对于状态可以直接观察到并且以离散方式演化的系统是有用的。

一般来说,马尔可夫方法将系统退化建模为一个随机过程,该过程在一组有限的状态φ= { 0,1,…, N }之间跳跃。这里,0 对应于完美的健康状态, N 代表故障状态。状态序列构成了一个马尔可夫链

马尔可夫模型的主要假设是未来的系统状态只取决于当前的系统状态。这个性质也被称为马尔可夫性质

在马尔可夫链建模框架下,RUL 可以被定义为退化过程从当前状态第一次过渡到故障状态 N 所需的时间量。这也称为首次通过时间 (FPT)。

当然,为了使用马尔可夫方法计算 RUL,我们需要知道状态的数量和状态之间的转移概率矩阵*,其中 Aᵢⱼ 表示从一个状态 ij 的转移概率。实际上,它们是从训练数据中估计出来的。为了确定状态的数量,通常采用一种 K 均值聚类算法。*

3.2 时间序列预测

时间序列预测方法对于状态可以直接观察到并以连续方式演化的系统是有用的。在这些设置中,RUL 估计实质上是对测量的时间序列数据的估计,以达到预定的阈值。

有多种方法可以建立时间序列预测模型。例如,我们有指数平滑法,其基本形式是预测新的观测值,作为过去观测值的加权平均值,权重随时间呈指数递减。

此外,我们有 ARIMA 模型。这里,ARIMA 代表自回归综合移动平均线。ARIMA 结合了自回归模型和移动平均模型,自回归模型根据过去的观测值回归新的观测值,移动平均模型将误差项建模为同时发生和在过去不同时间发生的误差项的线性组合。最后,ARIMA 采用差分步骤(对应于模型的“综合”部分)来消除趋势的非平稳性。

除了经典的时间序列预测方法之外,我们还可以使用神经网络。近年来,递归神经网络,特别是长短期记忆(LSTM)模型,在预测方面越来越受欢迎。

3.3 隐马尔可夫模型

隐马尔可夫模型(HMM)对于那些状态只能被间接观察并且以离散方式演化的系统是有用的。

从概念上讲,HMM 由两个随机过程组成,一个是可观测过程 Y ₙ,其说明了从传感器测量中获得的观测值,另一个是系统退化过程 Z ₙ,其状态是不可观测的,并且根据有限状态空间上的马尔可夫链进行演化。

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

图 6 是隐马尔可夫模型的示意图。(图片由作者提供)

通常,条件概率 p(yₙ|zₙ=I)被用来描述这两个过程之间的关系。

基本的 HMM 只能处理离散的观测值,即可观测的过程 Y ₙ在有限的状态空间上演化。然而,在实践中,观测值 Y ₙ往往是连续的。在这些情况下,混合高斯隐马尔可夫模型 (MoG-HMM)通常被用来处理连续观测值。在那里,高斯分布的混合被用来近似 p 的概率密度(yₙ|zₙ=I)。

3.4 随机过滤方法

对于状态只能被间接观测且以连续方式演化的系统,随机滤波方法是预测 RUL 的好选择。

随机过滤方法来自一个更大的研究领域,称为数据同化。在那里,目标是通过吸收来自观察和模型预测的信息来估计系统状态的概率分布。

随着新的测量变得可用,随机滤波方法使用贝叶斯学习来迭代地更新系统状态和控制状态演变的参数。一旦状态和参数被估计,我们可以使用演化方程预测未来的系统状态。总体工作流程如下图所示。

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

图 7 使用随机滤波方法预测 RUL 的工作流程。(图片由作者提供)

对于测量方程,测量模型 h (。)通常是从训练数据导出的数据驱动模型。对于状态演化方程, f (。)可以从物理原理或监督学习方法中导出,这取决于物理退化知识和相关训练数据的可用性。

关于用于状态估计的随机滤波技术,最常用的方法是基于卡尔曼滤波器,其具有封闭形式的解并且评估非常快。但是,它只能处理线性的 f (。)带有高斯噪声项。为了克服这个限制,提出了更高级的变体,包括无迹卡尔曼滤波器、集合卡尔曼滤波器等。

最常用的滤波技术是粒子滤波,也称为顺序蒙特卡罗(SMC)方法。这种类型的过滤方法使用一组加权粒子(也称为样本)来表示系统状态和演化参数的概率分布。一旦有了新的观测数据,这些粒子的权重就会根据贝叶斯规则进行更新。由于其模拟性质,粒子滤波可以处理现实世界应用中的非线性和非高斯性。

4.预测面临的挑战

尽管预测算法发展迅速,但在现实中进行可靠的预测分析并不总是容易的。有许多挑战可能会阻碍我们实现这一目标:

  • 传感器可靠性和故障,因为传感器可能在恶劣的环境中工作;
  • 特征提取,因为分离与复杂系统退化过程相关的特征是一项重要的任务;
  • 数据可用性,采用机器学习技术进行预测通常需要大量的训练数据(尤其是运行至故障数据),由于时间和成本的原因,这些数据不容易从在役系统中获得。

除了上述问题,预测中遇到的不确定性构成了获得可靠的 RUL 估计的另一个主要挑战。

预测不确定性可能源于:

  • 输入数据:传感器数据可能包含大量噪音。此外,环境和操作负载条件也在不断变化。
  • 模型:由于训练数据有限,构建的数据驱动模型可能无法准确捕捉真实的系统退化过程,从而产生建模误差和不确定性。

由于这些不确定性会导致预测结果与实际情况的重大偏差,因此开发一个系统的不确定性管理框架对于交付有意义的 RUL 预测至关重要。要了解更多关于如何管理与基于模型的预测相关的不确定性,请查看我以前的文章:

* *

5.外卖食品

在本文中,我们讨论了预测性维护的基本概念,并介绍了一些最流行的估算系统剩余使用寿命的算法。此外,我们还讨论了在获得可靠的预后结果方面的一些挑战。

本文的主要收获包括:

  • 预测性维护(PdM)包括数据采集、诊断、预测和健康管理。
  • 预测是实现智能 PdM 的关键技术;
  • 预测的主要任务是预测系统的剩余使用寿命(RUL);
  • 根据被研究系统的特点(直接/间接可观测、离散/连续状态演化),通常采用马尔可夫模型、时间序列预测方法、隐马尔可夫方法和随机滤波方法来估计 RUL;
  • 由于传感器可靠性和故障、特征提取、数据可用性和预测不确定性方面存在挑战,因此不容易进行可靠的预测分析。

参考

[1] N. H. Kim,2017,工程系统的预测与健康管理
[2] L .廖,F. Kottig,2014,工程系统剩余使用寿命预测的混合预测方法综述,以及在电池寿命预测中的应用IEEE 可靠性交易会
[3] X. Si,W. Wang,C. Hu,D. Zhou,2011,剩余使用寿命估计—统计数据驱动方法综述欧洲运筹学杂志
[4] S. Sankararaman,K. Goebel,2015,预测与系统健康管理的不确定性国际预测与健康管理杂志

关于作者

我是一名从事航天应用不确定度量化和可靠性分析的博士研究生。统计和数据科学是我日常工作的核心。我喜欢分享我在迷人的统计学世界中学到的东西。查看我之前的帖子了解更多信息,并在 Linkedinhttps://www.linkedin.com/in/shuaiguo16/上与我联系。

如何防止完好管道中的坏数据

原文:https://towardsdatascience.com/data-engineering-101-how-to-prevent-data-downtime-c09a022aa6ff?source=collection_archive---------34-----------------------

你应该考虑的 3 个策略

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

图片由 Shutterstock 上的 RT Images 提供。

对于数据团队来说,破损的数据管道、陈旧的仪表板和凌晨 5 点的消防演习是家常便饭,尤其是当数据工作流从不同来源接收越来越多的数据时。从软件开发中汲取灵感,我们把这种现象叫做 数据宕机——但是我们如何才能主动预防坏数据在第一时间来袭呢?

最近,我的一个客户提出了这个问题:

“您如何防止数据停机?”

作为一家拥有 3000 名员工的媒体公司的数据主管,他的团队负责每天向数百名利益相关方提供数 TB 的数据。考虑到数据移动的规模和速度,数据宕机,换句话说,数据全部或部分丢失、出错或不准确的时间段,是一个非常常见的现象。

一次又一次,营销部门(或运营或销售或任何其他使用数据的业务职能部门)的某个人注意到他们的 Tableau 仪表板中的指标看起来不对,伸出手来提醒他,然后他的团队停止了他们正在做的任何事情来解决问题。在这个过程中,他的利益相关者失去了对数据的信任,宝贵的时间和资源被从实际建设中转移出来,以扑灭这一事件。

也许你能理解?

数据停机时间的增加

从制造业中的预防性维护到软件工程中的错误监控(排队可怕的 404 页……),防止停机的想法是许多行业的标准做法,这些行业依靠正常运行的系统来运行业务。

然而,许多吹嘘其数据驱动资质的公司并没有投资于防止管道破裂或在数据流向下游之前识别低质量的数据。他们不是主动应对数据停机,而是被动应对,用坏数据玩打地鼠游戏,而不是专注于在第一时间防止数据停机。

幸运的是,还有希望。一些最具前瞻性的数据团队已经开发出了最佳实践,可在您的首席执行官有机会提出一个可怕的问题之前,防止数据宕机,并阻止管道破裂和仪表盘不准确。!"

下面,我分享 3 个关键步骤,你可以采取这些步骤来防止坏数据破坏你的 好管道 :

1.测试你的数据。并进一步测试你的数据。

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

对于大多数数据团队来说,测试是抵御坏数据的第一道防线。承蒙 阿诺弗朗西斯卡 Unsplash。**

2021 年,数据测试就是表赌注。

就像软件工程师对他们的代码进行单元测试一样,数据团队应该通过端到端的测试来验证他们的数据。测试的核心是帮助您衡量您的数据和代码是否如您所想的那样运行。

模式测试和自定义固定数据测试都是常见的方法,可以帮助确认您的数据管道在预期的场景中正常工作。这些测试寻找警告信号,如空值和参照完整性,并允许您设置手动阈值和识别可能指示问题的异常值。当以编程方式应用于管道的每个阶段时,数据测试可以帮助您在问题变成数据灾难之前检测和识别问题。

2.了解数据沿袭和下游影响

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

字段和表级沿袭可以帮助数据工程师和分析师了解哪些团队正在使用受上游数据事件影响的数据资产。图片由巴尔·摩西提供。

通常,数据宕机是无意更改的意外后果,远离依赖数据资产的最终消费者,而数据团队的成员甚至都不知道。这是糟糕的数据谱系的直接结果——我称之为 “你在用那个表?!" 问题。

简而言之,数据血统是数据上游和下游依赖性的端到端映射,从摄取到分析。数据沿袭使数据团队能够理解每个依赖项,包括哪些报告和仪表板依赖于哪些数据源,以及在每个阶段发生了哪些特定的转换和建模。

当数据沿袭被整合到您的平台中时,尤其是在字段和表级别,任何更改的所有潜在影响都可以被预测,并在数据生命周期的每个阶段传达给用户,以抵消任何意外的影响。

虽然下游血统及其相关的业务用例很重要,但也不要忽视了解哪些数据科学家或工程师正在访问仓库和湖泊级别的数据。在他们不知情的情况下推动变更可能会中断耗时的建模项目或基础设施开发。

3.优先考虑元数据,并像对待元数据一样对待它

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

当应用于特定用例时,元数据可以成为解决数据事件的强大工具。图片由巴尔·摩西提供。

在防止数据停机方面,沿袭和元数据是相辅相成的。作为沿袭实践的一部分,标记数据允许您指定数据的使用方式和使用人,从而减少误用或损坏数据的可能性。

然而,直到不久前,元数据还被视为那些你发誓有一天会用到的空亚马逊盒子——被囤积起来,很快就被遗忘了。

随着公司投资于更专业的数据工具,越来越多的组织意识到元数据在日益复杂的技术堆栈中充当无缝连接点,确保您的数据在每个解决方案和管道阶段都是可靠和最新的。元数据尤其重要,它不仅有助于了解哪些消费者受到数据停机时间的影响,而且有助于了解数据资产是如何连接的,以便数据工程师能够更好地协作并快速解决可能发生的事件。

元数据根据业务应用进行应用时,您将深入了解您的数据如何推动公司其他部门的洞察和决策。

数据停机的未来

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

强大的端到端沿袭使数据团队能够跟踪其数据流,从接收、转换和测试,一直到生产、合并转换、建模和流程中的其他步骤。图片由巴尔·摩西提供。

那么,在实现我们的无数据停机世界的梦想时,这给我们留下了什么?

嗯,就像死亡和税收一样,数据错误是不可避免的。但是,当元数据被划分优先级,沿袭被理解,并且两者都被映射到测试和可观察性时,对您的业务的负面影响— 数据停机的真实成本 —在很大程度上是可以预防的。

我预测数据停机的未来是黑暗的。这是件好事。我们越是能够防止数据停机带来的麻烦和消防演习,我们的数据团队就越是能够专注于项目,以可信、可靠和强大的数据推动业绩和业务向前发展。

有一些数据宕机的故事分享吗?我洗耳恭听。联系 巴尔摩西 蒙特卡洛团队 ,并参加我们的 下一次数据可观测性网络研讨会

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值