更多技术交流、求职机会,欢迎关注字节跳动数据平台微信公众号,回复【1】进入官方交流群
本文作者为火山引擎A/B测试团队资深研发工程师,内容主要介绍A/B实验在推荐系统中的应用,并介绍了在实践中总结的几点经验,希望对做信息流推荐、电商推荐、广告推荐等方向的同学有所启发。
AB实验,也被称为A/B测试,是一种统计学方法,通过对比两个或多个版本的事物,以确定哪个版本对目标的影响更大,目前在各大互联网公司有非常广泛的应用。例如在字节跳动,2023年中数据显示,A/B测试平台目前服务了500多条业务、在线上开的实验总量超过了240万,每天新增的实验数有4000余个,同时线上运行的实验数有5万余个 。
随着移动互联网的快速发展,用户规模和网络信息量都得到了爆炸式增长。在此背景下,信息过载导致用户产生选择焦虑,推荐系统也就应运而生。
可以说,推荐系统本质上是在用户需求不明确的情况下, 为用户从海量的内容中寻找其感兴趣的内容的技术手段,通过结合用户的基础信息(地域,年龄,性别等)、用户的历史行为(点击、播放、购买等)、以及内容本身的特征(分类、标签、价格等),利用机器学习技术构建用户的兴趣模型,再叠加一定的推荐策略,实现为用户提供精准的个性化内容服务,使流量得到充分的利用,最大限度地提高内容转化效率及用户获取信息的效率。
虽然不同推荐产品的体验和调性差异很大,但其背后的推荐系统总体技术方案大同小异,一般都由在线服务和离线处理两个模块组成:
在线服务是为用户提供内容的个性化推荐服务。其对效率要求比较高,需要在百毫秒级完成从海量备选集中筛选用户感兴趣的内容,一般由召回、粗排、精排、重排四个阶段组成。这四个阶段所处理的内容量由多到少、处理复杂度由简单到复杂、内容和用户的相关性由弱到强,随着阶段的推进逐步完成推荐。
离线处理辅助于在线服务,能够为在线服务提供内容基础和数据基础:
推荐系统中经常会有推荐算法、策略、特征、功能、UI的迭代,特别是推荐算法。但由于现在广泛应用深度学习模型,本身具有很强的黑盒属性。所以在进行调整后,用户体验如何,是否向着预期的方向发展,都无法通过经验来判断,需要通过A/B实验量化指标变化才能进行评估及后续优化。
因此,可以说A/B实验和推荐系统是相生相伴的,有推荐系统就必须有A/B实验。接下来就重点介绍A/B实验在持续改进推荐系统中的应用以及分享一些实践经验。
一个标准的A/B实验包含分析并提出假设、实验设计、实验上线、实验观测、实验决策五个环节:
在字节跳动,每天都运行着大量的推荐实验,以下分享几个我们积累的实践经验。
推荐系统的本质是连接内容和用户,这样就构成了<内容,推荐系统,用户>的三元组,A/B实验也是围绕这个三元组展开。内容侧,可以进行内容池优化、内容打标优化、视频封面模型的优化等;用户侧,可以通过A/B实验实现功能优化、性能优化、UI改进等;而在推荐系统方面,可A/B实验的维度更多,例如多路召回优化、粗排和精排模型迭代升级优化、模型多目标融合优化、重排多样性/兴趣探索优化、广告收入优化等等,可以说,在推荐系统中,万物皆可A/B实验。
需要指出的是,在进行内容侧的A/B实验时,例如信息流产品可能会做作者发布视频奖励、视频清晰度调整等,改变的是内容侧的属性,但我们通常观察的是大盘用户侧的指标。在进行这类实验时,建议转化为用户侧实验并辅助观测内容侧指标来评估,权衡用户侧和内容侧的综合收益后再决策是否上线。
比如视频带货推荐中,商家分润规则调整仅对实验用户生效,通过对比实验组与对照组的指标差异评估对大盘的影响的同时,可以创建并观察商家入驻率等内容侧指标的变化。在大盘收入指标不变、商家入驻率指标有提升,甚至大盘收入指标微跌、商家入驻率显著提升的情况下,都可以发布上线。
另外,A/B实验上线后,我们会频繁地查看分析实验指标。有的实验在开启后前几天可能出现指标下跌,这种情况下不建议立即关闭实验,因为我们遇到过很多这种指标开始下跌、后续慢慢回涨的情况,比如在内容多样性策略实验中,当增强兴趣探索后,短期可能会因为探索而出现用户不感兴趣的内容变多导致消费时长下跌,但从长期来看。探索到更多用户兴趣后,用户黏性更强,用户消费时长也会慢慢回涨,且更有益于平台生态。因此在面对实验开始指标下跌的情况,一般还是建议继续实验至少一周以上,覆盖观察一个完整周后再进行评估会更加准确。
在查看指标时,也建议多关注实验指标下钻分析结果,例如关注不同性别、不同年龄层用户的指标变化,有的产品也会关注不同活跃度用户、特别是新用户和低活用户的指标变化趋势,因为这类用户更决定了产品未来的增长。在DataTester,可以借助用户属性过滤功能,查看指标的下钻分析数据。
在推荐系统中,我们常常会想看不同算法叠加不同的策略或功能的效果,这时可以借助实验参数来做功能组合的A/B实验。实验参数,是对A/B实验中实验版本的补充,一般是一个功能控制配置项,需要开发人员获取并解析后才能生效。
借助实验参数,一方面能区分对照组和实验组,另一方面通过合理的实验配置的设计,可以在不增加开发工作量的情况下进行更灵活的实验。目前火山引擎DataTester支持Number、String、Boolean、Json类型的实验参数配置,可以帮助用户实现不同维度的A/B实验。
以视频带货推荐场景为例,我们假设商品内容展示时机不同会对用户的视频消费时长和电商GMV产生影响,因此设计如下实验:
我们可以设计实验参数goods_card_show_time=0/5/10分别对应对照组、实验组1和实验组2,然后在代码中解析goods_card_show_time参数并实现视频播放{goods_card_show_time}秒后展示商品卡片,即可完成上述实验。假如后续要实验“视频播放8秒后展示商品卡片”的效果,则无需修改代码,仅需要创建一个实验参数为goods_card_show_time=8的实验即可,甚至可以创建更多组不同参数值的实验后取最优的goods_card_show_time值全量发布。
需要注意的是,从开发同学的视角看,实验参数是一个功能控制配置,因此在进行A/B实验参数设计的时候需要避免一个误区:不要按实验设计来设计实验参数。例如如下场景:
信息流视频推荐中,想通过提高用户互动率来提升产品的用户黏性(即用户留存),因此设计通过优化推荐模型互动目标的同时,叠加在客户端展示互动引导的实验,且互动引导不同的展示时机和展示时长会对数据有较大影响,因此设计如下实验:
- 对照组:无推荐模型优化,不展示互动引导
- 实验组1:优化推荐模型互动目标,不展示互动引导
- 实验组2:优化推荐模型互动目标,且在视频播放剩10秒时展示互动引导5秒
- 实验组3:优化推荐模型互动目标,且在视频播放剩15秒时展示互动引导8秒
一个不恰当的实验参数设计方案是枚举所有实验组(如下interact_optimize_mod的设计),此时功能的控制只能通过硬编码来处理,如果涉及到实验方案调整,或者其他实验需要复用某些功能,则都需要另外开发。
"interact_optimize_mode": 0 // 0/1/2/3 分别对应对照组和实验组1/2/3
合理的实验参数应该按功能控制维度来设计,针对上面的实验,可以设计如下控制参数,然后通过这些参数的组合达到实验的效果:
"recommend_model_optimize": true // 是否进入推荐模型互动目标优化,true-是,false-否
"show_interact_guide": true, // 是否展示互动引导,true-展示,false-不展示
"show_duration": 5, // 互动引导展示时长,单位:秒,show_interact_guide=true时有效
"video_play_duration": 10, // 视频播放时长,单位:秒,show_interact_guide=true时有效
对照组:无推荐模型优化,不展示互动引导
{
"recommend_model_optimize": false,
"show_interact_guide": false
}
实验组1:优化推荐模型互动目标,不展示互动引导
{
"recommend_model_optimize": true,
"show_interact_guide": false
}
实验组2:优化推荐模型互动目标,且在视频播放剩10秒时展示互动引导5秒
{
"recommend_model_optimize": true,
"show_interact_guide": true,
"show_duration": 5,
"video_play_duration": 10
}
实验组3:优化推荐模型互动目标,且在视频播放剩15秒时展示互动引导8秒
{
"recommend_model_optimize": true,
"show_interact_guide": true,
"show_duration": 8,
"video_play_duration": 15
}
通过以上设计的实验参数,便可实现多个功能维度的A/B实验。可以说,合理利用实验参数,往往可以达到事半功倍的效果,这一点在移动端APP实验中尤为重要,因为APP一般发版周期长,无法做频繁变更,而有了实验参数,就可以在不发版的情况下,开启多组不同参数的A/B实验,筛选最优参数组合在线上生效。
当A/B实验决出优胜组后,我们便可以将优胜组的策略全量发布。那么如何发布呢?
一种做法是修改代码,将优胜组策略对应的参数对全量用户生效,同时将对照组下线,这种方式的缺点是每次全量发布都需要修改代码后发布上线,流程复杂增加了出错风险,特别是如果要全量发布客户端实验,考虑到客户端发版除了开发测试,还需要应用商店审批上线,这种方式将会严重影响迭代效率,并且这种方式难以回滚,在新特性上线时可能会造成上下游服务负载过高而影响用户体验。
基于以上可能存在的问题,一般的做法是会开发一套配置系统,将A/B实验控制逻辑配置化,当需要全量发布实验时,只需要全量发布对应实验配置即可,若发布时出现异常可通过回滚配置恢复服务。
在DataTester,除了能够为用户提供A/B实验的能力,还能为用户提供FeatureFlag功能,以满足A/B实验全量发布的诉求,用户无需再开发上述的配置服务。基于FeatureFlag功能,全量发布实验时,用户仅需要将实验配置固化为Feature,然后发布Feature即可,同时此功能支持自定义流量满足灰度发布的需求,保护上下游服务,出现异常时也支持配置秒级回滚,高效保障服务安全上线。
以上就是DataTester在推荐系统改进中的实践及其经验总结,希望对大家有所启发。火山引擎DataTester作为火山引擎数智平台VeDI旗下的核心产品,源于字节跳动长期的技术和业务沉淀。目前,DataTester已经服务了上百家企业,包括美的、得到、博西家电、凯叔讲故事等知名品牌,助力企业在业务增长、用户转化、产品迭代、策略优化以及运营提效等环节科学决策,将成熟的“数据驱动增长”经验赋能给各行业。
点击跳转火山引擎A/B测试了解更多