无论是管理人员还是创业公司中的不同团队,都可能会发现数据科学项目与软件开发之间的差异并不直观。如果没有明确的说明与解释,可能会导致数据科学家与其同行之间的误解和冲突。
来自学术界(或高度研究型的行业研究小组)的研究人员在初入初创公司或小型公司时可能会面临各自的挑战。他们可能会发现将新型输入(例如产品和业务需求、更严格的基础架构和计算约束以及客户反馈)纳入其研发过程中是很有挑战性的。
这篇文章的目的是介绍我近年来在同事与我自己的工作过程中发现的特色项目流程。希望这可以帮助数据科学家和与他们合作的同事以其独特方式来构建数据科学项目。
这个流程是建立在小型初创公司的基础之上的,一小组数据科学家(通常是一到四位)一次由一个人负责管理短期中型项目。较大的团队或机器学习优先的深度科技创业公司可能也会觉得这一结构有用,但大部分时候他们的流程会更长,结构也不尽相同。
我将这个过程分为三个方面:产品、数据科学和数据工程。在许多情况下(我工作过的绝大多数地方)可能压根没有数据工程师来履行这些职责。这时数据科学家通常会与开发人员合作解决这些问题。或者,数据科学家可能会(自己)完成这些准备工作——他们就是传说中的:全栈数据科学家。根据所处环境的不同,你可以随时用数据科学家来替代数据工程师。
在时间轴上,我将这个过程分解为四个不同的阶段:
界定范围
研究
(模型)开发
部署
我会尝试按顺序引导您完成每一项操作。
1.范围界定
比起任何其他类型的项目,定义数据科学项目的范围更重要。
1.1. 产品需求
项目应始终从产品需求开始(即使最初的想法是技术或理论上的)。该产品需求需要在一定程度上由产品/业务/客户方面的关键人员进行背书。产品人员应该知道这个功能应该(大致)最终看起来如何,并且现有客户或新客户愿意为此付费(或者它将阻止用户流失/将增加订阅数量/将推动其他产品的销售等等)。
产品需求并非项目完整定义,而应该被视为问题或挑战。例如:“我们的客户需要一种方法来了解他们如何花费预算”,“我们无法让老年用户继续服用他们的药物。这导致了客户流失增加“,或”如果产品能够预测机场的高峰时段,那么客户将愿意为此支付更多费用“。
1.2. 初期解决方案构思
在这里,数据科学家与产品负责人、数据工程师以及任何其他利益相关者一起,为可能的解决方案提出了不同框架草案。这些方案会囊括项目的一般方法(例如,无监督聚类、基于提升树的分类模型还是概率推理)和要使用的数据(例如,某一数据库中的特定表、我们尚未监控或记录的某些特定用户行为还是外部数据源)。
这通常还涉及一定程度的数据探索。这里你不用太深入但一些最基本的信息都能帮我们定下思考方向。
数据科学家应该带头领导这一过程,并且通常应负责提供大多数解决方案的构思。但我会建议所有参与此过程的人都进行方案构思。我曾有幸从后端开发人员、CTO或产品负责人那里得到了最好的项目解决方案。不要先入为主假设那些并非来自理论背景的人无法参与这一阶段的贡献——新鲜的思想和观点输入总是有价值的。
1.3. 数据准备及可得性
团队现在应该很了解解决问题需要哪些数据了(或者至少是初始数据集或数据来源)。因此,在进行下一阶段的同时我们应当已经开始准备数据访问权限以及数据的使用探索了。
如果在研究阶段时间不是很关键的话,这有时可能需要将大型数据集从生产数据库转储到对应的临时/探索环境中,或转到离线存储的空间(例如,对象存储)。有的情况下,它也可能意味着将大型数据从很少访问的存储器拉回到表或文档形式,以实现快速查询和复杂计算。无论如何,这个阶段对整个项目都是很有必要的,并且经常会花费比预期更多的时间(因此这是启动该阶段的最佳时机)。
1.4. 范围和关键绩效指标
这一阶段是关于决定项目范围和关键绩效指标。
我们应首先在产品术语中定义KPI,但要比之前更详细。例如,就上述三个产品需求而言,它们可能变成“客户现在可以使用包含每个类别的CTR统计数据和预测值的数据仪表板”,或“65岁以上用户错过服用药物的天数将在接下来的两个季度中减少至少10%”,或”每周客户将收到其机场高峰时间段的预测,区间精度至少为一小时,估计误差至最多为±50%“。
然后应将这些KPI转换为可衡量的模型指标。如果顺利的话,这些将是非常量化的指标,例如“对于任何至少运行一周的广告,以及任何有超过两个月历史数据的广告客户,预测其广告在至少Y%的情况下点击率至少为X%“。但是,在某些情况下,必须使用不那么精确量化的指标,例如“与原始查询相比,用生成扩展查询进行主题探索所需的时间将被缩短,并且/或着结果将得到改善”。当模型旨在辅助一些复杂的人体功能时,情况尤其如此。
从技术上讲,即使这些指标可以被非常严格地定义(并且在学术研究中,它们通常是如此),但是如果资源和时间受限,我们可以通过使用人工反馈来近似估计。在这种情况下,每次反馈迭代可能需要更长的时间,因此我们通常会尝试寻找其他硬度量指标来指导我们完成大多数即将进行的研究迭代。往往是几次迭代或者需要重大改变时才进行一次比较大规模的反馈收集。
最后,范围界定在这里特别重要。因为当研究过程中出现新的可能性或者当下研究的方法只能解决一部分的问题时,研究项目就会容易拖延,并且自然而然地会扩大规模和范围。
范围限制1:我发现明确地界定范围更有成效。例如,如果已经确定基于多臂老虎机问题(Multi-Armed Bandit)的模型是最有效的方法,那么您可以将项目范围定义为一个两周或三周的模型开发及迭代,无论其准确性如何都要部署模型(例如只要它超过了60%)。如果提高准确性是有价值的(在某些情况下它可能没那么重要),那么接下来就可以把开发第二个模型作为一个单独的项目。
范围限制2:范围限制的另一种类型是逐步增加模型的复杂度。例如,第一个项目可能旨在部署一个模型,该模型只需要为客户服务人员提供一组备用的广告词库和颜色库;第二个则可能会尝试建立一个模型,并给出一小组建议,让户可以看到自己的选择;而最终项目可能会尝试建议一个这样的模型:突出显示单个选项,并展示排名略低于它的几个选项,并为每个选项添加点击率预测和人口覆盖范围。
这已经与软件工程有很大不同,软件工程通常只会迭代组件以扩大规模,而不是增加其复杂度。
然而,产品价值度量函数可能是一个阶梯函数,这意味着任何指标未达到X值的模型对客户来说都没用;在这些情况下,我们更倾向于使用迭代,直到收敛到最佳阈值。然而,虽然在某些情况下这个X值可能非常高,但我相信无论是产品人还是业务员,亦或是数据科学家都倾向于高估这一要求,就像很容易得出如下结论:任何准确度低于95%(95%只是举例)的东西就没有任何价值且卖不出去。然而,在许多情况下,虽然对产品假设的严格审核和挑战有益于打造出有价值的产品,但这些产品在技术指标上要求可能没那么苛刻(至少对于产品的第一次迭代而言是如此)。
1.5范围和KPI标准
最后,产品负责人需要批准界定的范围和KPI。数据科学家的工作是确保每个人都了解范围的内容和优先级顺序,以及产品KPI与指导模型开发的指标之间的关系,包括指标与KPI的接近程度。明确说明这一点可以预防出现模型的使用者(包括产品人员和业务人员)在模型已经进入开发或者开发完成后才发现,开发的东西不是自己想要的。
关于范围界定的一些意见
在许多地方,数据科学家急于开始挖掘数据并探索关于可行性解决方案的高端论文而忽略了界定范围这一环节。然而,根据我的经验,这几乎总是导致因小失大,导致花费数周或数月的时间开发出来的高端模型最终却无法满足实际需求,或者无法达标一个具体的KPI。但如果按部就班地环环相扣,这些KPI其实是可以通过一些预先说明来明确定义的。
研究阶段
2.1 数据探索
有趣的部分开始了!在确定范围之后开始这一阶段的主要优势在于,我们可以通过实际的KPI和模型性能度量指标的指导,来进行数据探索了。
在探索和开发之间总是要寻求平衡。即使在有明确KPI的情况下,探索一些看似无关的内容也是很有价值的。
到目前为止,数据工程应该已经提供了所需的初始数据集。然而,在此阶段通常会发现数据中的一些缺陷,并且可能会将其他数据源添加到数据集中。数据工程师应该为此做好准备。
最后,虽然此环节与文献和解决方案综述阶段分离,但它们通常是并行或交替进行的。
2.2 文献与解决方案综述
这一阶段回顾了学术文献和现有的代码和工具。在探索和开发之间,以及对材料研究深入和快速地有所收获、分析其使用的可能性之间,平衡同样重要。
就学术文献而言,在形式证明和前期文献等方面研究要多深入,在很大程度上取决于时间限制和项目背景:我们是否要为公司的核心能力打下坚实的基础,还是只为了设计一个一次性问题的解决方案?我们是否打算在学术论文中发表关于这一主题的内容?你是否计划成为该主题的团队专家?
举个例子,假设一个数据科学家着手一个项目来帮助销售部门更好地预测销售广告的效果或者客户流失,他感觉自己对随机过程理论只是浅薄的理解,但许多类似问题的常见解决方案都是基于这一理论的。
虽然是同样的情况,但当所处环境不同时,反应可能非常不同。如果他在一个算法交易公司工作,他理应深入研究这个理论,甚至可能参加一个关于这个主题的在线课程,因为这与他的工作非常相关;然而,如果他是为一家专注于肝脏X射线扫描中自动肿瘤检测的医学影像公司工作,我认为他应该会快速找到适用的解决方案并继续进行下一步。
在代码和实现的情况下,设定的理解深度取决于技术方面,其中一些可能仅在该过程的后期才发现,但其中许多也可以提前预测。
例如,如果生产环境仅支持Java和Scala代码为后端使用,并且因此预期解决方案将基于JVM语言,那么数据科学家将不得不深入研究他在本阶段发现的基于Python的实现。即使随着他们进入模型开发阶段,需要将它们转换为JVM语言。
最后,在回顾文献时,请记住,不应向团队的其他成员只展示所选择的一个研究方向(或几个方向)。相反,也应该对该领域和所有已经验证的解决方案进行简要回顾,并解释每个方向的优点和缺点以及选择理由。
2.3可行性分析
根据可行性解决方案的建议,数据工程师和与之相关的开发人员需要在数据科学家的帮助下,估计该解决方案在生产中的形式和复杂性。产品需求以及建议解决方案的结构和特征,都应有助于确定恰当的数据存储空间、处理方式(流与批处理)、扩展能力(水平扩展和垂直扩展),以及粗略地估算成本。
这是在此阶段要执行的一个重要检查,因为某些数据和软件工程可以与模型开发并行。此外,就工程而言,给出的建议解决方案可能是不充分的或成本太高,在这种情况下,应尽快查明和处理。在模型开发开始之前考虑技术问题时,可以使用在研究阶段获得的知识,来提出可能更适合技术约束的替代解决方案。这就是研究阶段还需对解决方案前景进行一些概述的另一个原因,而不仅仅是针对单个解决方案。
2.4 项目范围 & KPI实施
再次强调,产品经理需要对用技术语言所表述的建议解决方案是否满足项目范围及所定KPI进行审核。易监测的产品表现指标可作为待选的技术标准,包括:响应时间(以及它与计算时间的关系)、数据及偶发中间运算新鲜度(与请求和批计算频率相关)、特定域模型的域适应难度及成本(成本包括数据成本;多数情况下领域是指客户域,但也可以是行业、语言、国家等等)、解决方案可模块化性(例如:数据结构和模型结构的特性能够让国家级模型分解为其下一层区域模型,或者是指将国家级模型整合为大陆级模型),以及其他各种指标。
3 开发阶段
3.1.模型开发 & 实验框架建立
开始模型开发时所做设置的量级和复杂程度都严重依赖于基础设施与数据科学家所能获取的技术支持。在规模较小的情况下,或者在之前没有支持过数据科学研究项目的公司,需要做的设置包括数据科学家新建代码存储库、建立本地Jupyter Notebook服务器,或者申请更强大的云机器以供运算。
在别的情况下,设置工作可能从自定义代码开始,以供更复杂的功能实现,例如数据和模型版本迭代,或者实验跟踪及管理。当一些外部产品或者服务能够提供这类功能时(这样的供应商越来越多了),一些设置工作随其后而至:连接数据源、分配资源以及设置自定义软件包。
3.2. 模型开发
所需要的基础设施到位后,万众期待的数据模型开发就可以开始了。模型的开发程度随公司而异,并且依赖于数据科学家交付模型与产品实际部署的功能或服务之间的关系或区别。发现这些区别的方法有很多种,比如说谱分析。
频谱分析的一个极端是指万物皆模型:从数据整合和预处理,经过模型训练(也许是周期性的)、模型部署、实际服务(可能将规模化)到持续的监督。另一个极端,就是指模型类型和超参数的选择,常常还有后期数据预加工、特征生成,这些都被视为模型的一部分。
一个公司在谱分析上的位置取决于很多因素:数据科学家偏好的研究语言、相关的工具库和开源资源的可获取性、公司内的生产语言、专门为数据科学家提供相关代码支持的数据工程师和开发人员是否存在、数据科学家的技术水平和工作方法。
如果数据科学家拥有全栈技能,并且能够从数据工程师和开发人员那里得到足够的支持——或者另一个选项是,整个数据湖形成、整合、模型服务、规模化以及监测(可能还有版本迭代)的运行和自动化都有足够的基础设施支持——模型的定义将更加广,并且通过模型开发的迭代,能够实现端到端的解决方案。
这常常意味着首先需要建立完善的工作通道,从数据源到可规模化的模型,在整个规划中给数据预加工、特征生成以及模型本身留着位置。随后在数据科学这部分进行迭代,同时保证整体范围与现有基础设施的承载能力和部署能力契合。
这样端到端的方法需要花费更长的时间设置,并且每次模型类型和参数的迭代都需要更长的时间测试,但是在后来的生产阶段将大大节约时间,赚回成本。
我个人偏向于这种端到端的解决方案,但它在实施和维护的时候的确比较复杂,且并不总是适用。这种情况下,开始和结束阶段的一些工作可以放到生产阶段去做。
3.3 模型测试
开发模型时,需要使用预先决定的标准对其不同版本不断进行测试(数据处理工作同步进行),这能够对模型改善提供一个大致的估计,并且为数据科学家决定何时这个模型能够满足整体KPI检查提供有效输入。但是需要注意,这个检测结果会有一些误导性,比如说在大多数情况下,模型的准确性从50%上升到70%,比从70%上升到90%容易得到。
当测试结果显示模型开发已经脱离轨道,我们常常需要深入调查其内部以及其结果,以找到改进的方案。但有时,表现之间的差距实在太大,所选择的研究方向中不同的变化都达不到要求——一个方法的错误。这也许需要对研究方法做出修正,整个项目将从头再来。这是数据科学项目最难接受的:推到重来的可能性
另一个方法论错误的后果就是目标的改变。如果足够幸运,那么也许只是在产品层面的微小变动,只需要把目标更简单的表述出来就好。例如,舍弃掉生成文章的一句话总结功能,而是从文章中找出最能够总结内容的句子。
最终可能的结果之一,当然可能是项目取消。如果数据科学家确定所有的研究方法都已经尝试过,且产品经理确定根据现有的产品数据无法真正实现一个有效的产品,那么也许是时候转向下一个项目了。 不要低估一个无可救药项目出现的可能性,并且有足够的勇气结束掉这个项目:这是快速失败法的重要的一环。
3.4. KPI检查
如果事前决定的指标是唯一的KPI,并且在过程中也获取了所有产品所需要的数据,那么这一个环节形式大于实质,最终模型将呈现在大家面前,开发阶段也宣告结束。但事实上并不总是如此。
大多数情况下,事前确定的只是对真实产品需求的近似推理,但并不是最佳选项。因此,这个阶段将是一个很好的机会,使用一些无法自动检测的软性指标来看产品是否满足要求。如果这一步通过,那么产品和客户满意都能够达到。如果你能另外直接检测产品对于一个用户产生的实际价值 ——例如,和一个设计合伙人共同工作——那么测试结果将是你对模型迭代最好的输入。
比如,我们正在试图解决一个复杂的任务,包括从一个巨大的语料库中提取相关文档、发起请求。项目组也许将决定尝试着增加结果集的质量,集中注意力在返回文档的内容和话题的不同之处上,因为客户可能会觉得这个系统总是倾向于在最优结果中集中极其相似的文档。
模型开发进程中,将逐渐在结果中增加一些可量化内容变化的测试标准,每个模型以前20个返回文档之间的不同程度打分,然后发出一系列测试请求。也许你会测量在一些话题向量空间下文档话题之间的整体差别,或者仅仅只是特殊话题出现的次数,或者显著组成分布的平坦度。
甚至当数据科学家决定能够大幅改善这个指标的模型后,产品经理和客户服务人员肯定会使用大量测试。他们可能会发现难以量化但并不是不能解决的问题,例如一个模型可能会持续增加结果方差,因为总是推送不相关的话题;或者从不同渠道获取相似话题的结果(例如新闻文章和推特,两者使用的语言大不相同)。
当产品负责人确定模型已经达到了这个项目的所有目标(到达令人满意的地步),那么项目组可以继续推进,开始产品化了。
4. 开发阶段
解决方案产品化 & 监控机制
正如前面提到的,这个阶段与各公司数据科学的研究方法、模型服务,以及几个关键的技术因素密切相关。
产品化:在研究语言可以直接用于生产的情况下,我们要做的可能是调整模型代码使得代码更灵活;至于这个过程的复杂程度,则同时取决于对模型语言的分布式计算支持,以及其所使用的代码库和定制的代码。
当研发语言和生产语言不同时,这可能还要涉及在生产语言包装器中将模型代码打包,并编译为二进制文件,或是在生产语言中重现相同的逻辑(或者找到这样的重现方式)。
如果模型中不包含可伸缩数据的提取和处理方案(这是非常普遍的情况),那么就需要进行额外设置。这意味着,例如,将运行在单核上的python函数转换为管道流数据,或者将其转换为定期运行的批量处理作业。在需要多次重复使用数据的情况下,有时需要设置缓存层。
监控机制:最后,需要建立一种持续监控模型性能的机制;在极少数情况下,如果生产数据源稳定,这个步骤可以被跳过,也不会造成大麻烦,但我要说的是,在大多数情况下,并不能十分确定源数据分布的稳定性。那么,设置这样的性能检查不仅可以帮助我们发现在开发和生产过程中可能遗漏的模型问题,更重要的是,在已经运行的模型的源数据分布中的任何变化- -通常被称为协变变化-可以随时降低一个完美的模型的性能。
以我们的产品为例,那是一个通过检测皮肤斑点来评估是否推荐用户去看皮肤科医生的app。当一款流行的新手机上市时,如果它配备的摄像头与我们原有数据中的摄像头参数有很大的不同,协变变化就有可能发生。
4.2. 解决方案部署
如果一切都设置得正确,那么这个阶段就是一句话,按下按钮,新模型(以及它的任何代码)被部署到公司的生产环境中。
部分部署:然而,有时为了测试模型的有效性(例如,减少用户流失,或者是增加每个用户每月的平均支出),可能只需要对部分用户/客户进行部署。这样就可以用可测量的KPI,直接对两个(或多个)用户库之间的影响进行比较。
您可能不想将模型部署到每个人身上的另一个原因是,该模型的开发是为了满足特定客户或一组客户的需求,或者它是高级功能或特定计划的一部分。或者,模型可能对每个用户或客户都有附加一些个性化元素;这些可以通过一个考虑了客户特征的单一模型来实现,但有时也需要为每个客户训练和部署不同的模型。
无论是以上哪个场景,都会增加部署模型的复杂性,复杂程度取决于公司的现有情况(例如,您是否已经将一些产品特性部署到客户的子集中),它们可能需要后端团队进行大量的额外开发。
当模型要部署到终端产品,如用户电话或可穿戴设备上时,这个任务将变得更加复杂,在这种情况下,模型部署可能要放到下一个应用程序中进行或者是作为固件更新的一部分。
产生偏见:对于数据科学团队来说,部分部署是一个棘手的问题,因为这种部署必然会带来偏差,而且模型会持续积累这种偏差,终有一天原来的模型会依据这些具有特性的用户数据进行工作。不同的产品类型和偏差的特征,有可能会对模型的性能产生很大的、未知的影响,而且可能对那些用了在此期间积累的数据训练出来的未来模型产生很大的影响。
例如,在设备更新方面,那些较早更新应用程序/固件的用户往往属于特定的人群(更年轻、更懂技术、收入更高等等)。
4.3. KPIs check
我在这里又添加了一个KPI检查,因为我认为在一个解决方案被认定为性能达标、已解决产品设计之初的问题、满足客户需求之前,不能被认定为已交付。
这个步骤是指,在部署之后的几周内对数据结果进行筛选和分析。然而,当涉及到实际的客户时,还必须要请产品或销售人员,让他们与客户坐在一起,试图了解模型在实际使用中的效果。
解决方案交付
当用户和客户都很满意,产品人员就也成功地根据模型构建或调整了他们想要的产品。我们就成功了。祝酒,欢呼,举杯同庆。
解决方案交付,我认为此时项目已经完成。然而,它仍以一种特殊的方式存在着——维护。
维护
为模型设置了的健康检查和持续的性能监控,可能会将我们带回到项目中。
当某些东西看起来可疑时,通常我们首先查看数据(例如协变变化),并根据我们所怀疑的能引起问题的各种情况,来模拟模型的反应。根据这些检查的结果,我们可能需要花几个小时修改代码、或者重新训练模型、或者重新进入模型开发流程(如本文开头的图所示),在一些严重的情况下,我们需要返回到研究阶段,尝试完全不同的方向。
本文是对数据科学项目流程的建议。它也是非常具体的,但为了简单性和可见性并不全面。而且显然的,它不能一一覆盖在实践中存在的各种变体,它代表了我的经验。
相关报道:https://towardsdatascience.com/data-science-project-flow-for-startups-282a93d4508d