亚马逊AWS官方博客

在 StockX 上使用 Amazon Personalize 开创个性化用户体验

Original URL:https://aws.amazon.com/cn/blogs/machine-learning/pioneering-personalized-user-experiences-at-stockx-with-amazon-personalize/

 

本文为StockX公司Sam BeanNic Roberts II撰写的客座文章。援引他们的表述,“StockX是一家来自底特律的初创企业,通过独特的买卖双向报价市场给电子商务带来革命——我们的平台模仿纽约证券交易所的形式,将运动鞋与街头潮牌服饰视为高价值可交易商品。凭借透明的市场交易体验,StockX能够以真实的市场价格为您带来正宗且大受欢迎的各类产品。”

2019年,StockX公司正经历调整增长,我们的机器学习(ML)工程师小组也开始尝试使用Amazon Personalize在主页上添加产品推荐行。最终,这项新功能成了主页上最受欢迎的部分。在本文中,我们将分享StockX使用Amazon Personalize的整个过程,探讨如何借此提供出色的定制化用户体验。

我们的市场动态需要提供个性化的用户体验。StockX网站的流量激增,在很大程度上源自相关商品市场供应量的下降。没错,在运动鞋与街头潮牌服饰市场上,最受欢迎的一定是那些需要提前预订的限量版产品。虽然客户对于产品多样性的追求一直在增加,但最受关注的永远是那些稀缺、几乎买不到的商品。这导致我们的平台经历一波又一波类似于DDoS的合法流量,让我们意识到后端的规模伸缩能力已经成为顺利开展业务的基本前提。另外,我们的团队还计划在黑色星期五之前上线产品推荐行功能。这就需要基于强大的推荐引擎——该引擎需要具有良好的扩展能力,并可以实时变化以适应不断变化的客户意图。

在公司成立的三年当中,我们逐渐将用户体验的个性化视为核心发展目标。我们的客户群体已经从单纯的运动鞋爱好者,稳步发展拥有越来越多休闲及新潮设计服饰的客户。感恩节购物季则为我们提供绝佳机会,以更具个性化的体验吸引这些新客户,最终提高整体客户忠诚度。尽管即将到来的2019年假期给我们的计划增加了额外的限制,但Amazon Personalize切实帮助我们为不断发展的用户群体打造精心设计且引人入胜的体验,最终顺利应对季节性流量激增带来的一系列挑战。

早期阶段

我们的团队最初打算寻求第三方供应商来填补平台中的个性化缺失环节。但是,购买现成解决方案不仅成本高昂,而且对于我们独特的电商业务而言也缺少灵活性。我们需要更大的灵活施展空间,但又不太可能单纯依靠内部自建方式搞定全部难题。

接下来,我们开始考虑构建起与Amazon Personalize核心推荐引擎(分层循环神经网络,简称HRNN)类似的自定义神经网络。虽然我们的团队具备自主建模能力,但却需要考虑一系列令人头痛的因素:健壮性、可扩展性以及开发周期等等。我们需要争分夺秒地构建优质服务,为我们的客户提供引人入胜的体验并在假期购物季来临前及时将其上线。为了明确到底是自建模型还是直接选择现成解决方案,我们列举了构建机器学习微服务架构的基本要求。经过整理,我们的具体要求如下:

  1. 数据收集——建立高性能推荐程序的第一步,自然是对网站进行正确跟踪。除了通过调查、评级以及偏好设置等方式收集明确的客户喜好指标之外,我们还需要考虑从原始点击流中提取隐式证据,借此建立起更加精彩的使用体验。而收集点击流数据,也成为创建高性能推荐程序的重要基础。
  2. 数据位置——在收集到正确的数据类型之后,下一步就是为该数据确定准确的存储位置。为此,我们需要找到点击流与产品目录数据所在的位置,并获取访问权限。
  3. 数据整理与特征工程——在找到数据源与存储位置之后,接下来需要找到其中真正有价值的部分。这是一项高度依赖于经验的过程,因为在进行实际尝试之前,我们往往很难预判算法如何从数据当中提取信号。
  4. 模型开发——这一步也是整个开发生命周期当中,数据科学元素最为密集的部分。大多数团队会以notebook中的原型为起点,逐步尝试解决业务问题,而后以面向对象的方式进行模型训练。这一步骤与之前各步骤相互依存,前者中的数据可用性也将直接影响候选模型集的实际组成。
  5. 模型测试与评估——在完成模型训练之后,必须启用快速合理性检验以执行定性分析,借此补充训练指标。我们建议大家创建一款小型的可视化应用程序,用于在模型提出的推荐内容旁边提示用户正在与哪些产品进行交互。这能让我们更直观地审视不同算法及超参数设置对推荐结果产生的影响,同时结合业务经验对其进行比较。
  6. ETL开发——在确定数据中的主要特征之后,我们还应该建立一套自动化ETL体系,用于提取原始数据、执行特征工程,并将数据放置在生产训练程序能够轻松访问的位置。这一步至关重要,因为ETL中的任何细微错误都可能拉低输入数据质量、最终影响输出结果的置信度。更可怕的是,这类错误往往很难在训练结束后、输出可视化之前被检测出来。
  7. 后端服务开发——将模型推理机制与后端服务打包在一起,可以显著改善监控、稳定性与抽象性水平。对我们来说,这也是一条重要的“防护堤”,防止流量的过度涌入。我们在AWS Lambda中选择了无服务器解决方案,将getRecommendations API打包在Amazon Personalize当中。
  8. 生产部署——CI/CD等自动化流程,用于训练并部署模型的最新版本,保证推荐结果始终符合客户的实际需求。一旦这一步骤出现问题,可能导致推荐结果过时,最终降低客户参与度。在完成这一部分之后,我们的机器学习微服务架构也就构建完成了。

构建本地解决方案,意味着我们需要从头开始完成以上八个具体步骤。Amazon Personalize提供自动化特征工程与模型开发(步骤3和4)功能,帮助我们快速搞定这两个最为耗时的环节。使用Amazon Personalize提供的标准HRNN(一套由Amazon 本身使用过的、经过重重考验实践模型),我们的用例只需要一套仅包含五列数据的简单数据集即可开始训练。将这两个步骤交由Amazon Personalize之后,我们得以专注于实现强大的ETL、后端与生产部署系统。此外,我们还省下了更多时间用于实现第5步中提到的可视化流程——这是以往需要开发完整技术栈时,我们根本不敢想象的。当然,直接使用Amazon Personalize也会带来一定妥协,意味着对于我们的算法,我们将无法用Amazon Forecast内置的方法以外的手段进行针对性调整。

这自然在我们的团队内部引发激烈讨论:我们到底是该承担起高昂的成本,以换取对模型的完全控制;还是以可调整性为代价,完全信任AWS提供的解决方案?最终,我们决定信任AWS在构建企业级机器学习模型方面的专业水平。我们的团队预见到,内部开发的深度学习推理引擎在可扩展性方面一定会带来巨大风险。如果不拿出时间进行负载测试,我们将很难计量估算大规模流量涌入时系统的实际弹性,这将把StockX的整体业务置于随时可能崩溃的危险境地。另外,生产型深度学习微服务架构是个相对较新的议题,与此相关的文献资料并不丰富,这也导致问题变得更加复杂。

开发

在决定将推荐程序的核心模型开发与生产推理扩展到AWS上之后,我们开始使用Amazon Personalize进行开发,并很快感受到将其集成至全扩展机器学习管道所带来的卓越便捷性。下图所示,为这套解决方案架构的基本情况。

我们将Amazon Personalize插入两部分代码库当中,这两套代码库分别用于创建数据集以及配置Amazon Personalize基础设施。以此为基础,我们成功实现了由Amazon Personalize驱动的实时推荐引擎的创建、部署与重新训练流程的全面自动化。

创建数据集

Amazon Personalize为用户提供多种选项,能够根据用户特征与推荐引擎的特定应用方式进行选择。部分配置选项允许您在模型训练过程中考量用户特征(例如HRNN元数据),另一部分配置则只关注平台上各用户间的交互(与单一特征/HRNN无关)。我们对具体配置的选择,决定了训练数据集的实际构建方式,以及最终将向Amazon Personalize提供多少训练数据集以建立模型解决方案。

我们首先开发出用于训练及测试所有三种HRNN变体(纯文本、元数据以及冷启动)的基础,并对结果做出比较。在添加元数据集时,我们刚开始并未发现推荐方面的重大改进,而且发现HRNN-冷启动在未进行额外特征工程开发的情况下并不能生成自然的推荐结果。虽然我们怀疑在元数据特征工程方面投入更多精力也许能最终提高性能,但我们仍决定尝试其他更为简单、且同样有望提供高质量推荐的解决方案。

要使用Amazon Personalize HRNN配置,我们需要为其提供单一数据集,并在其中包含任意时段之内的用户交互行为。这套交互行为数据集将包含并定义影响核心推荐算法的训练特征。对于像StockX这样的电子商务平台,这种交互行为特征可能表现为产品页面浏览量、搜索结果点击流或者与购买行为相关的操作等指标。

为了构建起交互行为数据集,我们创建了一条自动化Python ETL管道以查询我们的点击流数据源与产品目录、处理交互数据以提取所需特征,并最终执行CSV格式化操作以支持Amazon Personalize的数据提取要求。由于Amazon Personalize原生支持从Amazon Simple Storage Service (Amazon S3)导入数据集,因此创建这样的自动化管道并不困难,我们可以节省大量时间和精力来考虑如何选择最佳配置以及最佳交互时段。

自动创建Amazon Personalize基础设施

接下来,我们开始着手对Amazon Personalize整体基础设施进行自动化构建。大家当然可以在AWS管理控制台上手动创建Amazon Personalize服务,但配合AWS SDK for Java,我们能够在规模更大的推荐服务管道中实现全自动与可重复能力。在这里,我们选择Scala作为客户端以创建Amazon Personalize基础设施,具体包含以下内容:

  • 数据集组
  • 数据集
  • 导入作业
  • 解决方案
  • 解决方案版本
  • 实时营销

对于一次性训练来说,在控制台上构建基础设施确实更为简单;但要打造出一套真正的全自动可复用管道,SDK绝对是不二之选。

部署策略

更重要的是,我们的Scala客户端还可以承担对生产部署流程进行仲裁的额外职能,确保对推荐模型的重新训练不会造成停机状况。随着用户与平台的持续交互,有必要对模型进行重新训练,从而及时加入新的交互行为并据此提供新的推荐。在进行日常训练时,通过新的交互数据重新训练模型会使得营销端口处于离线状态,导致长时间服务中断。我们可以建立两个独立的实时营销端口(以及方案版本)来缓解这个问题,但代价高昂——它意味着即使不提供任何实时流量,我们都需要为各端口支付对应的AWS费用。

为了解决这种部署问题并建立更具成本效益的微服务架构,我们建立起独特的部署策略——采用Lambda函数居中调度。该函数负责访问营销端口并向前端客户端提供推荐内容。我们还将一套特殊的数据集组标签(下图最左侧的两个框体)打包成为Lambda的一个环境变量,用于标识当前处于活动状态并处理生产负载的营销端口。

每天夜间,Scala客户端会启动新的训练作业,并首先检查Lambda环境变量中的实时数据集组信息。客户端将加载新的交互数据集,重建休眠数据集组,而后在端口上执行心跳检查以保证端口创建成功。接下来,客户端会指示Lambda函数更新其营销相关环境变量并指向新的端口。最后,不再使用的Amazon Personalize基础设施将被撤销。

通过这种方式,我们的微服务架构能够自动高效对Amazon Personalize模型进行重新训练,每天更新用户推荐内容,且不会带来昂贵的冗余支出或者任何服务停机问题。另外,使用Lambda函数还允许我们启用自定义指标对系统进行跟踪与故障监控,及时发布训练问题或端口活动错误告警。这种围绕Amazon Personalize精心设计的强大的基于微服务的部署策略,使得StockX的推荐引擎即使在在公司成立至今有史以来最为繁忙的购物季期间也实现了近乎完美的可用性。具体架构如下图所示。

实时能力

在完成了训练与部署流程的设计之后,我们只剩下最后一个问题需要解决:如何在不同训练执行轮次之间,随用户兴趣的变化更新推荐内容。Amazon Personalize在这方面提供一套简单的解决方案,即事件交互数据集。我们使用Amazon Personalize putEvents API将点击流事件添加到模型当中。点击流作为源端将事件实时推送至Lambda函数,函数将事件归集为Amazon Personalize所需的特定格式。事件被添加至数据集后的几秒内,推荐内容即可获得相应体现。下图所示,为这一工作流的基本情况。

测试与部署

我们的发布计划现在已经成为StockX公司的内部标准——通过设置A/B测试的特征标记进行“向您推荐”主页的部署,这使得团队在初始阶段可以安全地执行金丝雀测试,将该功能仅发布给1%的用户。最终,我们的测试范围将涵盖60%的用户——其中30%的用户继续获得原有体验,30%的用户则获得个性化首页体验,另外40%用户不受测试影响。在逐步扩大功能涵盖范围的过程中,我们发现错误率或延迟并没有随之增长。为了保证万全,我们进行了为期两周的测试。

尽管“向您推荐”显示在首页中的第二行位置,但其点击率却超过了显示在最顶端的“最受欢迎”行。按百分比计算,“向您推荐”已经成为我们表现最好的购买通道。受其影响,我们整个主页的总体客户参与度提高了50%,这证明个性化、甚至只是单一页面的个性化,也足以大大提升其他商品的点击率。。

个性化始终是企业高管团队的核心战略目标之一。而我们的推荐引擎,则是其中最关键的成果。与负责产品发现体验的产品负责人共同制定战术策略。作为独角兽初创企业的我们深刻意识到个性化的重要性,并通过A/B测试实际证明了个性化的强大能力。在获得初步成果之后,困扰我们的已经不再是要不要推广个性化,而是如何保证个性化元素渗透至StockX客户体验的每一个角落。机器学习团队一直是StockX内部最具数据驱动能力的工程团队之一,通过实验也展现了基于测试KPI如何确保我们以可衡量的方式改善客户的实际体验。

总结

在项目实施期间,机器学习团队收获许多关于构建机器学习微服务架构的知识。我们将这些心得体会总结如下:

  • 尽早集成——在项目生命周期中尽早搭建可行的演示非常重要。即使是简单的推荐算法,也会给各相关方留下深刻的印象,并帮助我们顺利争取到内部资源与更高的项目优先级。
  • 可视化——可视化工具对于机器学习模型的测试至关重要。单纯将原始产品ID作为完整性检查对象还远远不够,我们需要同时提供推荐产品的图片与隐性关联证据,借此评估推荐程序的实际效果。
  • 避免过度复杂——Amazon Personalize提供多种机器学习框架选项,各选项在复杂度方面也有着巨大差异。我们也曾尝试从复杂的配置起步,并发现很难理解其为何会提出一些奇怪的推荐。而从简单的HRNN起步,我们得以快速开发出效果显著的例子。
  • 估算成本——机器学习成本高昂。请保证对于相应预算需求有明确的估计。除了云基础设施使用成本之外,开发人员为此投入的时间也是一种重要的成本构成元素。
  • 了解扩展性——要构建自己的深度学习推荐程序,请首先确保对推理作业的扩展性充分了解。发现自己辛苦搭建的解决方案不能满足流量峰值期间的业务要求是一件令人沮丧的事。
  • 彻底消除手动操作——机器学习微服务架构相较于传统后端服务架构,包含更多组成部分。自动处理管道中的各个环节——只要还有任何一部分ETL或者部署流程需要人工干预,考虑潜在的错误。机器学习的工程部分已经相当困难了,避免引入人为操作故障。

“为您推荐”成为我们团队乃至整个StockX公司的一次巨大胜利。我们开始迅速将机器学习技术整合至企业中的各个层面。而我们获得的成功,也使得企业决策者同意在更多StockX体验场景当中集成Amazon Personalize,并不断扩大我们在机器学习领域投入的精力。可以肯定地讲,个性化如今已经成为StockX内部的头等大事。

我们的团队在这次假期购物季的几周之前着手项目开发,并在购物季到来时及时将其上线。可以自豪地说,在Amazon Personalize的帮助下,我们的微服务架构在整个假期当中都表现出近乎完美的可用性。

 

本篇作者

Sam Bean

StockX公司机器学习部门创始成员兼负责人。他一直在寻找更困难的问题,并尝试使用更轻松的无服务器解决方案加以处理。Sam深深着迷于强化学习与GAN的各类最新应用。在业余时间,他是弹珠比赛选手兼弹珠锦标赛总监。

Nic Roberts II

居住在底特律的软件开发者。他对机器学习以及初创企业充满热情,从密歇根大学毕业后于2019年加入StockX。他还高度关注交通运输行业的创新,之前曾从事过自动驾驶汽车算法的开发工作,并带领学生设计团队参加了2016年SpaceX Hyperloop Pod竞赛。在业余时间,Nic喜欢旅行,在密歇根州北部滑雪以及收集运动鞋。