HarmonyOS开发者限时福利来啦!最高10w+现金激励等你拿~ 了解详情
写点什么

Twitter 的 A/B 测试实践(三):检测和避免 A/B Test 中 bucket 不平衡问题

  • 2016-03-27
  • 本文字数:3336 字

    阅读完需:约 11 分钟

【编者的话】A /B 测试曾在多个领域产生深远的影响,其中包括医药、农业、制造业和广告。 在软件开发中, A/B 测试实验提供了一个有价值的方式来评估新特性对客户行为的影响。在这个系列中,我们将描述 Twitter 的 A/B 测试系统的技术和统计现状。

本文是该系列的第三篇,介绍了一种自动检测分桶不平衡问题的实验技术。

注:本文最初发布于 Twitter 博客,InfoQ 中文站获得作者授权,对文章进行了翻译。

正文

在前面的文章中,我们讨论了 Twitter 进行产品 A/B 测试的动机, A/B 测试如何帮助我们创新,和 A/B 测试框架 DDG 是如何实现的。本文我们将介绍一种自动检测潜在“错误(buggy)”实验的简单技术:对用户进入“实验桶(experiment bucket)”的不平衡进入率进行检验。

触发分析

A/B 测试将用户映射到“实验桶(treatment bucket)”。“控制桶(control bucket)”(“A”)是当前产品体验;实验桶(“B”)实现被测试的变更。你可以构建多个实验桶。

选择展示哪个桶似乎很简单:随机和确定地将所有用户 ID 分配到一些整数空间,并指派空间到桶的映射。

但是考虑到许多实验变更只是推送给一部分用户。例如,我们可能想对 iSO 应用程序中的照片编辑体验做些变动——但是不是所有的用户都使用 iOS,同时也不是所有的 Twitter iOS 用户都编辑照片。

包括所有用户,无论他们是否“触发”实验都会造成“稀释(dilution)”。即使你的特性是在被推送用户行为之下变更的,其实大部分都不是,所以影响很难观测。因此,需要通过只观测触发变更的用户来缩小分析。但是,这么做可能有危险,因为有条件地选择进入实验的用户易使我们有偏见。由于实验配置的微妙之处,使得不同实验桶样本总量不具有可比性,进而导致结果无效。

一个简单例子

让我们想象一下,工程师需要实现特定于美国的实验。通过使用以下(伪)代码,她确保实验桶不会推送给美国之外的用户:

由于所有国家的用户会被记录进控制桶或者实验桶,但是事实上只有美国 “实验桶”用户能够看到实验桶,这就产生了稀释实验。

在这一点上不存在偏差——仅仅是稀释。但是当在代码评审中指出时,代码变成如下:

新版本看上去避免了稀释问题,因为即使用户触发了实验桶,只要他们没有看到,他们就不会被记录。但是它有一个 bug——实验存在偏差。实验桶仅仅记录美国用户,而控制桶可以记录所有国家的用户。应用程序没有被破坏,但是两个桶不具有可比性。

无偏差的解决方法如下所示:

并非所有的分桶不平衡都有如此显而易见的原因。最近我们遇到一个实验,从客户端 Javascript 触发用户分桶日志异步调用。该实验中,实验桶需要加载某些额外资源,并进行其它调用,这会导致低速连接用户的分桶日志调用不太可能成功。这就造成偏差:控制桶比实验桶更可能推送给低速连接用户,会轻微扭曲结果。

识别分桶不平衡

有效检测分桶偏差的方法是对不平衡的桶的大小进行检验。我们的实验框架会使用两种方法自动检验桶的大小是否与预期大致一致。首先,我们使用多项拟合优度检验执行整体“健壮性检查(health check)”。健壮性检查会检查观测的桶的分配是否匹配预期流量分配。如果整体健壮性检查不理想,我们还会对每个桶执行二项检验,精确查明哪个桶可能有问题,显示新分桶用户的时间序列,以防实验者希望进一步挖掘。

使用多项检验执行整体健壮性检查

想象一下,某个实验分成 _k_ 个桶,其中向第 _i_ 个桶推送 p% 的流量(不同桶之间的 _p_ 可以不一样)。假定我们知道实验中分桶用户的总量,我们可以将每个桶中的用户数量共同建模为多项分布。此外,我们可以执行拟合优度检验,观察实际观测到的计数是否偏离预期计数。如果发现流量分配显著偏离预期,这就说明流量分割有问题或者分割存在偏差。

在数学上,多项式优度测试相当直观。

这里 ,_O_ 代表第 _i_ 个桶中观测到的分桶用户数量,_E_ 代表每个桶预期的分桶用户数量。统计数据捕获每个桶偏离其预期值的程度,总和数据捕获总体偏差。该检验统计遵循卡方分布(自由度为 k-1),所以我们可以判断,观测的偏差是否与桶分配的当前样本 _p_ 值一致。

需要注意的是,“多项检验(multinomial test)”是泛化的二项检验(通常用于只有一个控制和实验组的测试)。过去,我们使用二项检验将每个桶与其预期的桶计数对比。但是,在实验中有多个桶的情况下,我们很快就会遇到多重假设检验问题。接下来,我们根据 1 - (1 - p)^k,其中 _p_ 是获得假阳性的概率(通常设置成 5%),将假阳性作为独立桶数量的函数,绘制获得至少一个假阳性的概率图。即使是配置合理的试验,当拥有多个桶时,其假阳性率增加得相当快:在零假设、5 个桶的情况下,其中一个桶不平衡的概率超过 20%。

假阳性会浪费很多调查时间,会降低对工具的信任。为了说明这个问题,我们对二项检验切换成多项检验的改进进行了评估。

我们对 179 个实验做了元分析,并对多项和二项检验的桶的健壮性结果进行了对比。在二项检验的情况下,至少有一个桶的 p_<_0.05,实验就被视为不健壮,而在多项检验情况下,只有整体桶的 p<0.05,实验才会标记为不健壮。

我们发现有些实验的二项检验结论是不健壮,而多项检验的结论相反。我们检验了所有此类实验,发现它们有着共同的特征:

  • 所有实验中只有一个实验,并且只有一个桶的二项检验小于 5%。剩下的桶往往拥有一致的、健壮的 _p_ 值。

  • 所有被标记的实验至少有 4 个桶。

这些特征表明,二项结果可能是假阳性。接着,我们手动验证所有实验的配置都是正确的。切换到多项检验,提高了整体实验的健壮性,降低了估计 25% 的假阳性率。

标记独立的桶

多项检验可以让我们免受多重假设检验的困扰,但是它有一个缺点:它不能告诉我们哪个桶有问题。为了提供更多的指导,我们在多项检验的情况下还进行了另外的二项检验运行。

DDG 使用二项式分布的正态逼近来执行双面二项检验。

二项检验可以检查时刻 _t_ 的流量分配是否大致均衡,当实际流量在预期流量 95% 置信区间之外时,它会标记出异常的桶。

桶计数的时间序列

在最低粒度水平下,我们的工具也能够在 8 小时的批处理时间窗下呈现桶计数的时间序列。如下两个例子:健壮的时间序列和不健壮的时间序列

实例 1:健壮的时间序列

(点击放大图像)

在上述例子中,时间序列表明,不同桶之间每个桶的用户数量是均衡的,除了一小批次(颜色标签是基于每个时间段 _t_ 的二项检验)。其中的两个不平衡的批次不会产生影响:当显著性水平设置成5% 时,每20 个测试中会有一个假阳性。多项检验影响不明显。总体而言,我们没有看到有分桶偏差的任何证据。

实例2:不健壮的时间序列

(点击放大图像)

在这个实例中,我们看到实验开始几天后,新用户的数量开始偏离预期流量,表明出现 分桶偏差。看看右上角的整体桶健壮性,多项检验也表明测试不健壮。在这种情况下,工具会提醒用户在分析之前先调查设计。

相比任何一种类型的检验单独检测,批次层级和全局检验的结合,可以让我们检测出更多精细问题。

基于用户检验,而不是印象

由于实验效果或者实现细节,合理的设计和实现的实验可以让不同的桶拥有分桶印象整体数量。与研究总触发或者总访问相比,基于特别分桶用户对比桶不平衡,是更好的检验方法。

需要注意的是,在我们的时间序列检验中,我们基于第一次用户分桶检查桶不平衡,而不是分桶事件。实验本身可以引导用户继续触发实验,或者低于控制桶。这使得后验印象数据对比不恰当。在整个检验中,我们只对整体用户分桶数量进行对比,而不是记录桶之间的整体印象。

结论

分桶不平衡检测非常强大,它是一种判断实验是否正确配置的简单易行的方法。要验证实验结果,这是头等大事,将其内置到工具链中,可帮助我们节省大量的调查和分析时间。通过自动检查带有明显偏差证据的实验,大幅降低了检测问题所需的时间,同时增强了实验者对实验结果的信任度。

编后语

《他山之石》是InfoQ 中文站新推出的一个专栏,精选来自国内外技术社区和个人博客上的技术文章,让更多的读者朋友受益,本栏目转载的内容都经过原作者授权。文章推荐可以发送邮件到editors@cn.infoq.com。

查看英文原文: Detecting and avoiding bucket imbalance in A/B tests


感谢郭蕾对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们。

2016-03-27 17:558115
用户头像

发布了 92 篇内容, 共 25.0 次阅读, 收获喜欢 4 次。

关注

评论

发布
暂无评论
发现更多内容

开源工具系列1:Cloud Custodian

HummerCloud

云计算 云安全

深度!用“极速统一”,开启金融行业数据分析新范式

StarRocks

解读Java内存模型中Happens-Before的8个原则

华为云开发者联盟

Java 开发 华为云 12 月 PK 榜

教你用JavaScript实现背景图像滑动

小院里的霍大侠

JavaScript 编程入门 实战案例 图像滑动

一文掌握MyBatis的动态SQL使用与原理

华为云开发者联盟

sql 开发 华为云 12 月 PK 榜

培训学习大数据门槛低吗

小谷哥

“自动驾驶+昇腾AI” 西安交大团队解决高级辅助驾驶的关键难题

Geek_2d6073

我和 TiDB 的故事 | TiDB 仓库 commit TOP 1,PR 数超过 1000 的阿毛哥

TiDB 社区干货传送门

人物访谈

百度工程师教你玩转设计模式(装饰器模式)

百度Geek说

Java 设计模式 12 月 PK 榜 装饰器模式

Go 中这么多创建 error 的方式,你真的了解它们各自的应用场景吗

Go学堂

golang 开源 程序员 个人成长 12月月更

V8的垃圾回收和内存限制

千锋IT教育

带你玩转OpenHarmony AI:打造智能语音子系统

OpenHarmony开发者

OpenHarmony

科班出生和培训出身的前端程序员哪个好?

小谷哥

TiCDC 源码解读(2)-- TiKV CDC 模块介绍

TiDB 社区干货传送门

不止于大,如何打造优秀的折叠屏应用体验

HarmonyOS开发者

HarmonyOS

践行开源理念,统信软件开放服务器操作系统UOS V20使用授权

统信软件

操作系统 服务器 国产化 免费

一文解读机密容器的崛起和发展

云布道师

龙蜥

火山引擎DataTester上线“流程画布”功能,支持组合型A/B实验分析

字节跳动数据平台

大数据 AB testing实战 12 月 PK 榜

借力 StarRocks,"陆战之王" 大润发如何在零售业数字化转型中抢占先机?

StarRocks

数据分析 零售

TiDB Operator配置TiDB集群故障自动转移

TiDB 社区干货传送门

集群管理 管理与运维 故障排查/诊断 安装 & 部署 扩/缩容

DM 实践手册

TiDB 社区干货传送门

迁移 管理与运维

Coinbase或在不久使用Zebec发放工资,并对Web3支付赛道发展寄予厚望

鳄鱼视界

前端培训学习后好就业吗?

小谷哥

阿里云联合“产学研媒”发起BizDevOps共促计划,助力企业提升组织效能

阿里技术

研发效能 数字化转型

作为程序员,12款常用的软件!

千锋IT教育

JAVA培训学习后就业好吗

小谷哥

携手 StarRocks 打造极速统一数据底座,理想汽车获 DAMA 中国 “数据治理最佳实践奖”

StarRocks

教你用JavaScript实现随机点名器

小院里的霍大侠

JavaScript 初学者 入门实战

户外LED显示屏技术

Dylan

LED显示屏 户外LED显示屏 led显示屏厂家

Coinbase或在不久使用Zebec发放工资,并对Web3支付赛道发展寄予厚望

西柚子

大数据开发培训机构有哪些?

小谷哥

Twitter的A/B测试实践(三):检测和避免 A/B Test中 bucket不平衡问题_语言 & 开发_Robert Chang_InfoQ精选文章