查看原文
其他

小红书推荐系统迭代:AB测试架构的高效与稳定性策略

赵单栋 DataFunSummit
2024-09-11

导读 本文将从策略评估的角度分享小红书实验平台在推荐系统迭代中面临的挑战和解法。

主要内容包括:

1. 推荐 AB 的诉求和挑战

2. 推荐 AB 架构和变更稳定性

3. 单实验精度提升

4. 多策略打包结算

分享嘉宾|赵单栋 小红书 实验平台leader 

编辑整理|肖迪

内容校对|李瑶

出品社区|DataFun


01

推荐 AB 的诉求和挑战

小红书实验平台在和推荐算法一起进行迭代的过程中面临的主要诉求和挑战包括:

1. 变更稳定性

推荐算法和推荐策略在公司中的使用非常广泛,变更频率高,影响范围大。例如,线上调参可能会对模型资源提出特殊要求,导致实验变更后直接影响线上效果,造成 CTR(点击率)或曝光率下降,甚至可能因为参数未经充分测试就上线,直接导致线上事故。因此,变更的稳定性是一个重要的问题。

2. 单实验精度要求高

算法团队面临很大的业务压力,对单次实验的精度要求很高。为了确保精度,团队可能会进行 AA 实验,即在策略不变的情况下,观察指标之间的差异,希望这些差异尽可能小。然而,由于调参和观测指标众多,自然存在一些差异,如何减少这些差异成为一个重要挑战。

3. 多策略打包结算

传统的预实验较为简单,单个策略自我迭代,策略之间正交。然而,当策略之间存在冲突时,例如精排和粗排在一个互斥的流量域内一起进行实验,可能会产生问题。此外,团队希望度量整体和子团队的产出,需要对多个策略进行统一结算。结算周期可能会比较长,需要保证实验的质量和稳定性,原则上希望核心收益指标只增不减,且希望整体和分方向都可度量。

接下来将逐一介绍我们针对上述三大挑战的解决方案。

02

推荐 AB 架构和变更稳定性

一般的推荐 AB 架构如上图所示。小红书的 AB 平台采用 SDK 分流的方式,实验的分流逻辑是内置在推荐服务中的。一个请求通过网关后,会打到推荐服务上,实验 SDK 通过一个设定好的机制定期拉取实验配置,并做一些打点采集的工作。

推荐算法和推荐策略的变更稳定性保障包括两层:平峰期和高峰期的管控。例如,在高峰期进行变更需要通过审批,并进行灰度放量检测。灰度检测支持服务维度,在不同机房按比例放量,确保变更对整体系统的影响最小。实验变更后,通过质量指标打灯(红灯、绿灯、黄灯)来决定是否上线。红灯为强制卡点,绿灯说明没问题可以自动生效,生效会把配置在线上全量,黄灯的话可能需要一些人工的介入。

03

单实验精度提升

问题背景是,算法团队在进行 AA 实验时,经常会遇到指标波动的问题。AA 实验是指在不改变策略的情况下,观察两个组(控制组和实验组)之间的指标差异。尽管两个组在理论上没有任何实质性的差异,但在实际操作中,仍会出现一些显著的指标差异。这种现象在实验平台上是普遍存在的。

上图展示了一些从 AA 实验中截取的指标,这些指标的具体名称和含义并不重要,重要的是展示出即使在没有实际差异的实验组和控制组之间,某些指标仍会出现显著差异。例如,有一个指标的差异达到了负向的 0.7%。

为什么会有这种差异?首先,为什么这种差异会显著?其次,为什么某些差异会如此之大,比如达到 0.7% 甚至 5%?对于算法工程师或实验同学来说,当他们看到这样的结果时,可能会认为在随机分组和初始化后,一些对象指标已经被劣化了。例如,如果一个实验的优化目标在初始化时已经下降了 0.7%,那么在实验正式开始前,需要先把这个负向的 0.7% 打平到 0,然后才能继续优化。实验同学的诉求是需要一个平的 starting_point,即“一开始不比别人吃亏”。

为满足上述诉求,一个朴素的想法就是,基于 AA 实验的结果让用户进行选择。比如先进行一段时间的 AA 实验,然后从中选择指标差异较小的组作为最终的实验组。但是 AA 实验存在一个劣势,即它是一个真实的实验,需要一定的等待时间来获取结果,可能是两天、三天,甚至更长。此外,实际进行的 AA 实验数量有限,不能无限制地进行分组。

为了解决这些问题,我们开发了一个回溯 AA 实验功能,可以利用数据进行虚拟 AA。标准的做法是实验同学会先配置一个实验的流量,说明需要 10 个 10% 的组,并约定实验的核心指标,希望核心指标在这些分组的表现是比较持平的。实验平台可以多次遍历分流,因为分流的成本很低。这使得平台可以尝试不同的哈希种子,用不同的方式将用户随机分组,生成许多不同的结果供实验同学选择。实验同学可以自行挑选最合适的分组。整个流程是支持重跑的,也就是说,平台会提供多个版本的分组结果,实验同学可以检查这些版本。如果某个版本通过了他们的检查,实验同学可以选择采用。如果不满意,实验同学可以继续重跑,重复这个过程,直到找到合适的分组。这就是整体的流程。

然而,这种方法虽然简单,但细节问题往往会带来一些挑战。首先,不限制条件的分组选择可能会导致样本的偏倚。此外,虚拟 AA 实验的结果在真实实验中可能并不完全适用。

因此,平台在内部进行了大量模拟测试,以验证这两个问题。

例如,图里展示了一个模拟结果。左边一列显示的是虚拟 AA 实验中的结果,会发现图中有一部分被抠掉了,这部分表示我们选分组的策略。例如,第一个左上角的策略是基于虚拟 AA 实验选择那些最极端的情况,即差异最大的结果,而将中间差异较小的结果排除。右边一列则显示了 1000 个虚拟 AA 实验的前七天和后七天的结果。

通过这种模拟,我们可以看到用户选择了一个虚拟 AA 实验的结果后,开始了一个真实的线上 AA 实验,前后结果的变化情况。上面的策略选择更极端的结果,下面的策略则选择相对中间的结果。核心点在于,尽管我们希望选择那些不靠近零点的实验数据,但在真实实验中,这些结果仍有可能变得靠近零。这证明了 PreAA 满足条件的分流结果,在真实流量 AA 开始之后,仍旧可能变得不平。

另外,测试结果也证明了不限制条件的选分组可以造成一个有偏的样本。有偏的意思是指,例如有两个不同的用户,一个永远选择最差的结果,另一个永远选择最好的结果,如果他们带着这些选择去进行真实的 AA 实验,那么第二个星期的结果将会有显著差异,他们之间的差距会非常大。通俗地说,如果你一开始选择了好的结果,那么下个星期你这个组的指标很可能仍然会很好。

这个问题会带来一些挑战,因为算法同学的优化目标是不同的,你优化的目标可能是别人的防守指标,在这种情况下,防守方测量你的实验对他们的影响时,结果总是偏大的或偏小的,导致测不准。

以上是 PreAA 实验带来的两个主要问题,另外还存在两个问题。

平太难得。从成功率上讲,万里挑一并且持续提升。加入的指标越来越多,每一个指标和选择的逻辑,例如希望让它离 0 多近,都会对最终的成功率产生很大影响。最初可能是从一千个中挑一个,后来可能是从一万个中挑一个,最后甚至可能是从十万个中挑一个,这使得选择的难度越来越大,纯粹是计算成本或等待成本的问题。

使用 PreAA 选分组的实验,不能用通常的 T 检验计算显著性。准确的计算方式非常贵,工程上没有落地的可能性。

此外,如果使用 PreAA 选分组,那么就不能用通常的 T 检验来计算显著性。因为真实计算显著性的方式非常昂贵,目前没有公司能够完全实现。如果你在公司中使用 PreAA 选分组,可以问一下实验平台的同学,他们是如何计算显著性的。如果他们使用的是一般的计算方法,那结果很可能是错误的。

这个问题在学术界也有一些背景。PreAA 选分组的概念在一些论文中有详细讨论,可以参考相关论文获取更多信息。

如果我们不能选组,但对单次实验精度仍有要求,还有其他方法可以考虑,比如DID 或 CUPED。这些方法在一些论文中有详细讨论。DID 的方法是在 PreAA 阶段,如果两组之间有 1% 的差异,在实验期间进行调整,补偿这一差异。

DID 其实是 CUPED 的一种特殊场景。CUPED 的核心思想是使用线性修正方式将 PreAA 的数据整合到实验结果中,并动态选择修正参数。而 DID 则是将这个修正参数固定为 1。因此,CUPED 相比 DID 有更大的灵活性和更好的效果。

另一个问题是,是否可以将 CUPED 和 DID 结合起来以获得更好的效果。

通过模拟实验可以发现,当使用 CUPED 进行修正后,两组之间的差距几乎消失,达到了消除偏差的效果。

另外,PreAA 选组的逻辑不影响后验分布,只要经过 CUPED 修正,最终的分布形状总是一样的。这意味着,如果已经使用了 CUPED,PreAA 选组实际上不能提供额外的价值,因为它对精度的提升仅仅是对分布的修正,分布越窄,精度越高。因此,有了 CUPED,就不需要额外的选组策略。

这里介绍一些我们在单实验精度不足指标踩过的坑。

首先,即使我们有了许多工具,可以进行选组并使用 CUPED 修正,有些指标的精度仍然不足。举个例子,关于留存类指标,如 LT28,这个指标非常不敏感,每个单独的策略对它的提升有限。然而,它是业务的核心指标,整体算法的优化目标是提升用户的活跃度。因此,我们非常关注这个指标。在单策略实验中,我们发现 LT28 的假阳率很高。假阳率指的是,如果同样的实验进行两遍,第一遍结果上升,第二遍是否也能保持上升。我们发现,这个指标的假阳率一度超过了 50%。相比之下,消费类指标的假阳率很低,通常只有 10% 左右。这两个指标之间存在显著的差异。

这个现象可以用显著性检验带来的一些系统性问题来解释。上图展示了这一现象:对于某个策略提升来说,例如优化目标是 LT28,在线上 100 个实验中只有 5% 的实验能够真正提升这个效果,剩下的 95% 则没有提升。然而,在这 95% 的实验中,由于显著性工具有一定的概率将 AA 实验的效果误判为显著差异。因此,会发现实验平台报告的显著性结果(黑色部分)实际上来自两个来源:第一个是实际有效的效果,第二个是假效果被误判为真效果。

黑色和黄色部分的比例大致反映了假阳率。如果一个策略很难提升,其精度很差,那么假阳率就会很高,甚至可能接近 70%。这意味着尽管实验平台报告了显著性,但其中大部分可能是误判的结果。

这个问题在论文中也有详细讨论,感兴趣的读者可以根据论文题目查阅相关文献。

我们最后的结论是,对于单实验精度不足的指标,只能将其放到打包实验中来看。接下来就来介绍打包策略。

04

多策略打包结算

小红书打包实验策略经历了两个版本的迭代。第一个版本采用了一个简单的层域模型。我们会隔离一部分用户,这部分用户不参加平时的单个算法策略迭代。比如,我们在线上隔离出 10% 的流量,这部分流量相对纯净,然后将推荐域划分为一个独立的层域模型。在这个模型中,我们会圈出一些垂直打通的流量层,让这些用户能够获取到每一个推荐算法的策略。这部分用户的流量用于做贯穿层,进行牵涉到多个不同实验层的策略打包实验。同时,其他部分则进行普通的实验,彼此之间保持正交。

如果某个策略需要全量推送,我们会有一个特殊的设置,称为推全层。推全层会无视预留流量的存在,因此可以将推全配置推送给所有用户。第一版上线后效果不错,我们按照双月的节奏迭代,每个双月进行一次打包实验,观察所有推全策略叠加后的效果。

观察发现:

多策略叠加效果显著:虽然很多单个策略看似对留存目标没有显著提升,但将多个这样的策略叠加在一起,可以显著撬动整体 LT28(28 天内用户来访天数)的增长。

时间效应:LT 留存类指标的增长效果会随着时间放大。例如,一个双月实验的配置在两月底静止不动,到三月底观察时,LT28 的涨幅会有自然增长。

同时也发现了一些问题:

策略累积误判:随着时间的延长,打包实验不断有新策略加入,每个策略都有可能被误判为有效,或者在优化核心指标的同时劣化了其他防守指标。因此,时间拉得太长后,某些大盘指标可能出现无法解释的下跌。这需要高效的策略止损手段,以便在问题发生时能够及时查找并解决。

团队扩展与子方向打包:随着团队扩大,我们希望在大的方向下,各子方向也能有自己的小打包策略。这样既有整体的策略打包,也能兼顾各个子方向的特定需求。

基于这些经验和问题,我们开发了第二版的模型,进一步优化策略打包的实现。

在第一版模型的基础上,第二版模型保留了层域模型,仍然有一些纯净的贯穿垂直域流量用于策略打包。同时,在普通流量中引入了父子实验的概念,支持二层打包的思路。例如,视频和图文这两个方向希望各自有一个小打包,每个方向会建立一个互斥层,用于分割子方向的流量。在互斥层中,一部分用于子方向的垂直流量,另一部分用于日常迭代流量。所有普通实验都在日常迭代的方向里进行,最终将这些实验的参数分别叠加到子方向和大方向的打包中。

LR + Reverse 实验模型

每个叠加打包的策略在线上保留一个小的反转流量(reverse 或 hold back)。如果大盘指标出现异动,通过遍历所有反转实验,可以快速定位是哪个实验导致了指标下跌。

有了反转实验后,可以帮助我们进行假阳率的测算。每个策略都有两个观察点:一个是正向实验的观察点,另一个是反向实验的观察点。通过比较这两个观察点的结果,如果不一致,则定义为假阳性。

Reverse 实验的效果再可以帮助进行敏感型指标建模,帮助发现和 LT 高度相关但更敏感的潜在实验观测指标。

虽然单个策略可能无法直接观察到长期指标(如 LT),但我们可以通过简单的建模或相关性分析,将所有指标与核心方向指标进行关联建模,发现与 LT 相关性高且更敏感的指标。例如,某些用户时长超过 30 分钟的占比与 LT 的相关性很高,这可以帮助我们在单个实验中做出更好的决策。

以上就是本次分享的内容,谢谢大家。


分享嘉宾

INTRODUCTION


赵单栋

小红书

实验平台leader

当下在小红书负责实验平台。之前在谷歌做过 DS,统计学 PhD。

活动推荐

往期推荐


数据治理体系建设与落地探索

企查查的数据降本增效之路

小红书训推异构引擎的设计与应用

基于 tugraph-analytics 的实时业务数据异常归因诊断

大语言模型在图推荐系统中的融合与优化策略

Data+LLM:金融真实场景的技术创新实践

京东广告稀疏大模型训练与推理 GPU 优化实践

好的数据治理怎么做?

销售易基于 Lakehouse 的实时分析提升用户数据体验实践分享

Velox内存管理深度解析:从基础到高级特性


点个在看你最好看

SPRING HAS ARRIVED

继续滑动看下一个
DataFunSummit
向上滑动看下一个

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存