当前位置: 首页 > 科技观察

大规模机器学习:将数据科学引入生产系统架构的典型模型

时间:2023-03-18 21:53:59 科技观察

在过去的几年里,数据科学的概念已经被许多行业所接受。数据科学(源于一个科学研究课题)最初来自一些科学家试图理解人类智能并创造人工智能,但现在已经证明它可以带来真正的商业价值。比如我的公司:Zalando(欧洲最大的时装零售商)。在这里,数据科学与其他工具一起用于提供数据驱动的建议。推荐本身在许多地方作为后端服务提供,包括产品页面、类别页面、时事通讯电子邮件和重定向。图1:图片来自MikioBraun的演讲页面DataDrivenRecommendations其实,数据驱动的推荐生成方式有很多种。例如,在所谓的“协同过滤”中,可以收集所有用户行为(如浏览产品、操纵想要的产品列表和购买行为)作为推荐的依据,然后分析找出哪些产品具有相似性用户行为模式。这种方法的美妙之处在于计算机根本不需要知道这些商品是什么。而它的缺点是产品必须有足够的用户行为信息数据,才能保证这种方式有效。另一种生成推荐的方法是只查看产品的属性。例如,推荐相同品牌或相同颜色的商品。当然,这些方法还有很多扩展或组合。图2:图片由AntonioFreno提供并获得许可。引用自《One-Pass Ranking Models for Low-Latency Product Recommendations》paperpublishedatKDD2015conference一种更简单的方法是仅通过计数来提出建议。但是这种方法在实践中会有很多复杂的变形。例如,对于个性化推荐,我们采用了“学习排序”的方法,即对商品集进行个性化排序。上图显示的是这种方法需要最小化的损失函数。然而,在这里画这张图的主要目的是为了展示数据科学可能引入的复杂性。该函数本身使用具有正则化条件的成对加权指标。这个函数的数学表示很简单,当然也很抽象。该方法不仅适用于电商推荐场景,也适用于商品具有足够特征时的各类排序问题。将数据科学方法引入工业界我们需要做什么才能将上述非常复杂的数学算法引入生产系统?数据科学和软件工程之间的接口应该是什么样的?什么样的组织结构和团队什么样的结构最适合使用这些数据科学方法?这些都是非常相关且合理的问题。因为这些问题的答案将决定对数据科学家或整个数据科学团队的投资最终是否会得到回报。在下文中,我将根据我作为机器学习研究人员以及在Zalando领导数据科学家和工程师团队的经验来讨论其中的一些问题。理解数据科学(系统)和生产系统之间的关系让我首先从理解数据科学系统和后端生产系统之间的关系开始,看看如何将两者结合起来。图3:图片来自MikioBraun的演示页面典型的数据科学工作流程(管道)如上图所示:第一步总是从发现问题和收集一些数据(从数据库或生产系统的日志)开始。根据组织的数据准备情况,此步骤可能很困难。首先,您可能需要弄清楚谁允许您访问所需的数据,以及谁允许您使用该数据。一旦数据可用,它们可能需要再次处理以提取特征值。您希望这些特征可以为解决问题提供有用的信息。然后将这些特征值输入学习算法,并在测试数据上评估生成的模型,以确定该模型是否擅长预测新数据。上述分析流水线通常是一项短期的一次性工作。通常所有步骤都由数据科学家手动完成。数据科学家可能会使用诸如Python之类的编程语言,其中包含许多数据分析和可视化库。根据数据量的不同,有时数据科学家也会使用Spark和Hadoop等计算框架。但一般他们一开始只会使用整个数据集的一小部分进行分析。你只从一小部分数据开始的主要原因是整个分析管道过程不是一次性的,而是一个非常迭代的过程。数据科学项目本质上是探索性的,甚至在某种程度上是开放式的命题。虽然项目目标很明确,但在项目开始时并不清楚哪些数据可用,或者可用数据是否适合分析。毕竟,选择机器学习作为方法,已经意味着不能只写代码来解决问题。相反,求助于数据驱动的方法。这些特点意味着上述分析流水线是迭代的,需要多次改进,尝试不同的特征、不同的预处理方式、不同的学习方法,甚至回到起点,寻找和试验更多的数据源。整个过程本质上是迭代的,并且通常是高度探索性的。当模型的整体性能良好时,数据科学家会将开发的分析管道应用到真实数据中。此时,我们面临与生产系统集成的问题。图4:来自MikioBraun的演示页面的图片区分生产系统和数据科学系统生产系统和数据科学系统之间的主要区别在于生产系统是一个实时、连续运行的系统。必须处理数据并且必须经常更新模型。生成的事件还经常用于计算关键业务绩效指标,例如点击率。该模型通常每隔几个小时用新数据重新训练一次,然后导入生产系统以服务新的(例如,通过REST接口发送的)数据。这些生产系统一般都是用Java等编程语言编写的,可以支持高性能和高可靠性。图5:图片来自MikioBraun的讨论页面如果将生产系统和数据科学系统并排放置,就会出现如上图所示的情况。在右上角,是数据科学部分。其典型特征是使用类Python语音或Spark系统,但一般是一次性手动触发计算任务,迭代优化整个系统。它的输出是一个模型,本质上是一堆学习过的数字。然后将该模型导入生成系统。生产系统是一个典型的企业应用系统,用Java等语言编写,持续运行。当然,上图有些简化。在现实中,模型需要重新训练,因此数据处理管道的某些版本将与生产系统集成,以不时更新生产系统中的模型。注意在生产系统中运行的A/B测试。它对应于数据科学方面的评估部分。但这两个部分往往不完全具有可比性。例如,如果不向客户展示离线推荐结果,很难模拟推荐的效果,但这样做可能会提高性能。最后,重要的是要认识到系统在安装和部署后不会“消失”。正如数据科学方面的人需要多次迭代来优化数据分析管道一样,整个实时系统也必须随着数据分布的漂移而迭代演进。结果,新的数据分析任务成为可能。对我来说,做好这个“外部迭代”是生产系统面临的最大挑战,也是最重要的一步。因为它将决定你能否持续改进生产系统,并确保你在数据科学方面的初始投资得到回报。数据科学家和程序员:协作模式到目前为止,我们主要关注的是系统在生产中的样子。当然,保证生产系统稳定高效的方法有很多。有时,直接部署用Python编写的模型就足够了,但生产系统和探索性分析部分的分离是必须存在的。您将面临的最艰巨的挑战之一是如何协调数据科学家和程序员的合作。“数据科学家”仍然是一个新角色,但他们所做的与典型的程序员有很大不同。由此产生的误解和沟通障碍是不可避免的。数据科学家的工作通常是探索性的。数据科学项目通常从一个模糊的目标开始,对哪些数据可用以及可能的算法有一些想法。但很多时候,数据科学家必须尝试多种想法并从数据中获得见解。数据科学家写了很多代码,但大部分是用来测试想法的,并没有用在最终的解决方案中。图6:图片来自MikioBraun的演示页面与数据科学家相比,程序员通常非常专注于编程。他们的目标是开发一个能够实现所需功能的系统。程序员有时会进行探索性工作,例如构建原型、验证概念或测试性能基准。但他们工作的主要目标是编写代码。它们之间的区别在代码更改中也很明显。程序员通常坚持定义非常明确的代码开发过程。一般包括创建自己工作流的分支,开发完成后做评估检查,然后将自己的分支合并到主分支中。人们可以并行开发,但他们的分支必须经过协商后合并到主分支中。然后这个过程会自己重复。整个过程是为了确保master分支以有序的方式发展。图7:图片来自MikioBraun的演示页面数据科学家也编写了大量代码。但正如我之前所说,这些代码通常用于验证想法。因此,数据科学家可能会编写版本1,但它不满足要求。然后我为了一个新的idea写了version2,接着写了2.1和2.2,直到发现无法实现需求才停止。然后写版本3和3.1以获得更新的想法。或许这时候,数据科学家意识到,如果将2.1版本的一些方法与3.1版本的一些方法结合起来,可以获得更好的解决方案。这导致版本3.3和3.4,并且可能是最终解决方案。图8:图片来自MikioBraun的讨论页面一件有趣的事情是,数据科学家实际上可能想要保留所有这些不成功的版本。因为一段时间后,也许它们会被用来测试新的想法。或许可以将某些部分放入一个“工具箱”,逐渐形成数据科学家自己的私有机器学习库。程序员更喜欢删除“坏代码”(因为他们知道如何快速取回),而数据科学家则喜欢保留代码以防万一。这两个差异意味着,实际上,直接让程序员和数据科学家一起工作可能会出现问题。标准的软件工程流程不适合数据科学家的探索性工作模式,因为他们的目标不同。引入代码审查检查和有序的分支管理、审查、合并分支工作流程并不适合数据科学家,并且会减慢他们的工作速度。同样,将探索性模式引入生产系统开发也不会成功。为此,我们如何建立合作模式来保证双方的高效工作?也许第一直觉是让它们彼此分开工作。比如,将代码库完全分离,让数据科学家独立完成需求文档,然后由一组程序员来实现。这种方法也有效,但过程通常非常缓慢且容易出错。因为重新开发和实现可能会引入错误,尤其是当程序员不熟悉数据分析算法时。同时,能否通过外部迭代来提升系统的性能,还取决于程序员是否有足够的能力去实现数据科学家的需求。图9:图片来自MikioBraun的讨论页面幸运的是,许多数据科学家实际上想成为优秀的程序员,反之亦然。因此,我们已经开始尝试一些更直接的协作模型,并有助于加快流程。例如,数据科学家和程序员的代码库仍然是分开的,但一些生产系统为数据科学家提供了明确定义的接口,以便将他们的方法嵌入到系统中。与这些生产系统接口的代码必须严格遵循软件开发实践,但这是数据科学家的工作。这样,数据科学团队可以快速迭代自己的代码,同时迭代生产系统。图10:图片来自MikioBraun的演示页面这种架构模式的一种具体实现是“微服务”方法。即让生产系统调用数据科学家团队开发的微服务来获取推荐。这样,数据科学家使用的整个离线分析管道也可以适用于A/B测试,甚至可以添加到生产系统中,而无需与程序员团队重新实现。这种模式需要数据科学家具备更多的软件工程技能,但我们看到越来越多的数据科学家已经具备这种技能。事实上,我们后来将Zalando的数据科学家头衔修改为“研究工程师(数据科学)”以反映这一现实。使用这样的方法,数据科学家可以快速实践,对离线数据进行迭代研究,并在生产系统环境中进行迭代开发。整个团队可以持续将稳定的数据分析方法迁移到生产系统中。持续适应和改进到目前为止,我已经概述了一种典型的架构模式,可以将数据科学带入生产系统。需要理解的一个关键概念是,此类系统需要不断适应和改进(类似于几乎所有基于真实数据的数据驱动项目)。能够快速迭代、尝试新方法并使用A/B测试验证结果都非常重要。根据我的经验,将数据科学家团队与程序员团队分开是不可能实现这些目标的。同时,必须承认这两个团队确实因为目标不同而工作方式不同(数据科学家更具探索性,而程序员更专注于开发软件和系统)。通过允许各自的团队以更适合他们目标的方式工作,并通过定义一些清晰的接口,可以整合两个团队并确保可以快速尝试和测试新方法。这将需要数据科学家团队拥有更多的软件工程技能,或者至少需要软件工程师来弥合这两个世界。关于作者MikioBraun是Zalando推荐和搜索系统的交付负责人。Zalando是欧洲最大的时尚电商平台之一。Mikio拥有博士学位。在将他的研究成果转化为行业应用之前,他在机器学习领域从事研究工作多年。