优步在全球700多个城市运营,仅2019年第三季度的预订量就超过160亿美元,利用预测模型来确保准确的财务规划和预算管理。这些模型,源自数据科学实践和平台便于使用,帮助我们的企业用户预测他们的支出分配将如何影响关键的收入指标。
然而,任何看过天气预报的人都知道,天气预报并不总是准确的。为了更好地评估模型的性能,我们建立了一个val用于测量预测模型错误率的服务。这项服务给我们带来了双重好处:它与我们的内部业务用户建立了信任,并授权数据科学家对预测预测进行有针对性的改进。
今天,我们的服务支持所有基于python的时间序列预测模型,包括多元模型。回测服务在分布式系统中运行,允许同时运行多个模型(>10)、多个回测窗口(>20)和不同城市的模型(>200)。我们的服务已经在优步的金融机构内部对许多模型进行了回测,结果为模型开发人员和业务决策者提供了有价值的见解,使我们能够为全球用户改进我们的服务。
大规模回测
我们的数据科学团队定期创建预测模型和统计数据,以更好地了解预算支出和项目财务绩效。这些模型对我们的战略财务团队至关重要,他们依靠它们来决定未来的支出在哪里以及如何分配。毕竟,预算的好坏取决于支持它的数据。
为了确保我们的预测尽可能准确,我们需要一种支持紧密反馈循环的服务——显示预测模型的不足之处,以便数据科学家快速有效地迭代。此外,一个紧密的反馈循环确保了业务决策者对财务规划的统计数据和模型有一个全面而细致的看法。
为了重新测试我们的财务预测模型,我们需要考虑多个方面。下面的图1显示了我们在回测中必须涉及的几个维度的示例:
如图1所示,其中一个维度是回测窗口的数量。我们的数据科学家可以对月度(窗口为1个)和年度(窗口为12个)模型进行回测,以解释季节性。
在确定构建一个新的解决方案之前,我们评估了已经开发的各种现有的回测服务(例如,肚脐(我们用于需求预测的并行和语言可扩展的回测工具),最初计划利用它们。然而,由于Uber不断增长的运营规模,这些服务是为特定环境创建的,不能支持我们在1000万回测规模下编排和计算的需求。
现有的服务还缺少一些我们需要的其他功能,包括覆盖多变量模型的能力和预测模型的客观性能测量自动化的能力。他们还缺乏一种标准化的服务,让机器学习工程师和数据科学家在预测模型调整和更新的过程中跟踪模型的性能,这对我们的金融用例尤其重要。
为了解决这些和其他缺失的功能,我们开发了一种新的回测服务,它提供了一个单一的系统,使业务用户和数据科学家能够作为综合的一站式商店客观地评估模型。
测量模型精度的重要性
在构建这个服务之前,我们首先考虑的问题之一是如何表示和计算模型的准确性。为了更好地理解这个表达式是如何工作的,我们需要将预测结果与实际历史数据进行比较。第一步是将数据集分成训练集和测试集。不像交叉验证,回溯测试利用时间序列数据和非随机分割。
出于回测服务的目的,我们选择利用两种主要的回测数据分割机制,扩展窗口回测和滑动窗口回测:
在上面,我们展示了每个方法的三个窗口。每个窗口被分割为训练数据(用于训练模型)和测试数据(用于计算训练模型的错误率)。
为了测量错误率,我们新的回测服务采用了不同的方法。Uber的数据科学家最常用的方法之一是MAPE(平均绝对百分比误差):
![]()
MAPE越低,预测模型表现越好。通常情况下,数据科学家会比较同一模型使用的错误率计算方法的结果,以确保它们表达了预测中实际出现的错误。例如,虽然MAPE是标准的预测误差测量方法,但它不能处理零值的时间段(因为没有公式的分母可以是零)。在这个用例中,City A可能在2月份推出业务,但在1月份将没有出行数据,尽管仍然需要利用促销预算,但在2月份推出后,将在今年剩下的时间里支持逐月递增的出行。
除了MAPE,用户还可以使用其他误差测量方法为了更好地理解错误率。最重要的是,用户还可以使用该服务并行运行不同的回测方法(使用扩展或滑动窗口)和误差计算方法,加快预测,从而实现更快、更准确的决策。
系统架构
为了建立这个回测服务,我们利用了Uber现有的几个数据科学工具,包括数据科学工作台优步的交互式数据分析和机器学习工具箱,以及米开朗基罗优步的机器学习平台。在较高的层次上,机器学习模型通过数据科学工作台上传,并对模型数据进行回测请求使用Python库提交,该库将请求转发给用Go编写的Backtesting服务服务。一旦计算出误差测量值,它要么存储在我们的数据存储中,要么立即由数据科学团队使用,他们利用这些预测误差来优化训练中的机器学习模型。
下面的图3突出显示了回测系统的主要组件(绿色部分):一个Python库和一个Go服务:
放大这些组件,我们的Python库就像一个Python客户机。由于Uber的许多ML模型目前都是用Python编写的,因此利用这个框架进行我们的回测服务是一个很容易的选择,它允许用户无缝地在模型上进行板载、测试和迭代。
我们系统的主要回测逻辑是用Go编写的,作为一系列的Cadence工作流。节奏是一个用Go编写的开源编排引擎,由Uber构建,以可伸缩和弹性的方式执行异步长时间运行的业务逻辑。
回测服务工作流
Uber的金融技术团队使用我们的回测服务来开发预测模型并监控模型的性能。我们的服务有两个目标用户:数据科学家和机器学习工程师。让我们通过一个典型的用例来强调我们的回测服务是如何工作的,如下面的图4所示:
想象一下,一位数据科学家想要开发一个模型,根据优步在同一时间推出的促销活动数量,预测该地区在今年第一季度的乘坐次数。
我们可以将他们的活动分为两个阶段:模型开发(在轻量级Python客户端中频繁迭代)和在线模型性能测试(在该阶段,我们将大规模地对他们的可生产模型进行回测)。
当我们调用回测服务时,工作流过程可以分成四个不同的阶段,如下面的图5所示:
模型开发
在模型开发过程中,我们希望在本地机器上运行大量的实验并快速迭代模型设计。但是,访问我们的Go服务会产生额外的负载,并使用有价值的计算资源,而这些资源并不是这个目的所必需的。
首先,用户可以在Data Science Workbench中本地编写模型进行测试,也可以将其上传到机器学习平台,例如米开朗基罗.如果是后者,ML平台将向用户返回唯一的ID。然后,用户可以使用这个模型ID触发我们的服务通过Python客户机运行回测。
最初,我们将开始在一个小数据集上进行回测。例如,我们可能只想在1月份内针对纽约市测试我们的模型,并且只针对一种错误类型。这种回测通常需要不到几分钟的时间。此外,我们不需要在任何地方部署他们的模型,因为在Data Science Workbench中一切都是自包含的。他们甚至可以手动上传一个带有数据的CSV到他们的工作台或本地会话,因为我们的Python客户端库提供了相同回测算法的轻量级版本。该客户鼓励数据科学家进行实验,并不断吸收反馈,以改进他们的模型。
模型训练与预测
一旦用户完成了模型开发,他们就可以将模型部署到ML平台上,比如Uber的米开朗基罗,进行培训。一旦部署了模型,下一个阶段是用户可以将他们的回测运行提升到生产规模。
一旦我们的Go服务接收到请求,它将验证请求并向用户返回一个惟一的工作流UUID。用户可以使用该UUID检查回测过程和结果。然后,Go服务将获取数据集,并将数据拆分为多个针对不同维度(如城市、模型参数等)的并行回测窗口。
对于每个回测窗口,我们的Go服务将向机器学习平台发送一个训练请求。训练结束后,我们将发送一个预测请求,以获得该回测窗口的预测结果。
一旦回测服务得到所有的预测结果,它将计算错误并将错误结果保存到HIVE数据库中。它还将向用户发送电子邮件,通知他们回测已经完成。
模型部署
一旦模型投入生产,我们的数据科学家就可以在Go服务中触发大量的回测工作流,Go服务也可以通过Python客户机访问。我们的Go服务可以处理更大的负载,最终提供模型性能的聚合、整体视图。如前所述,回测服务的这一功能允许我们在多个城市的多个窗口上测试我们的在线模型,预测未来某个给定点的优步乘坐数量。我们甚至可以指定一个更大的训练窗口大小来准备模型,例如两年。
根据我们的需要,回测作业可以按照固定的节奏运行——比如每天、每周或每月。然后,数据科学家可以在数据科学工作台(data Science Workbench)或其他工具的仪表板中通过交互式图形和图查看和探索回测结果,如下面的图6所示:
推动
截至2020年2月,我们已经加入了6个预测模型,这些模型经常用于今年的财务规划和预算管理。我们的服务支持十多种错误测量类型,我们正在开发工具和仪表板,以可视化这些错误率随时间的变化。我们的用户喜欢知道他们的模型是如何运行的,数据科学家从这种透明度中获得信任,从而受益。除了决定是否使用模型之外,我们新的回测服务有可能从我们的预测中获得更多的见解,进而帮助我们的运营团队改善全球市场的优步体验。
如果您对ml驱动的大规模预测系统感兴趣,可以考虑申请一个角色与Uber Engineering合作!






