抖音技术能力大揭密!钜惠大礼、深度体验,尽在火山引擎增长沙龙,就等你来! 立即报名>> 了解详情
写点什么

A/B 测试的技术大揭秘

2020 年 4 月 05 日

A/B测试的技术大揭秘

A/B Test 的基本框架

在大量运行 A/B Test 实验的公司,为了让各个团队,各个模块的 A/B Test 有序进行,需要设计良好的 A/B Test 实验架构。


下面以有一定代表性的一种简化的场景介绍一个 A/B Test 框架。下图所示,是一个客户端列表页从前端到后端的极其简化版的流程图。括号中表示进行 A/B Test 时候,每个层次主要关注的点。



在谷歌的那篇文章《Overlapping Experiment Infrastructure: More, Better,Faster Experimentation》中,介绍了一个很复杂的 A/B Test 框架。以下我们描述一个简化的版本。看这个图的时候,可以想象流量从上往下流动,左侧的流量不分层,它可以同时测试产品展示交互设计,产品功能点,策略算法等层次的参数组合。而右侧的流量会经过不同层次的实验。上方的是展示交互层实验,中间是排序层实验,下方是召回层实验。层与层之间,可以有几种不同的关系。多数实验会使用右侧的多层实验框架,跨层次的实验发生得比较少。



多层 A/B Test 的基本概念

1 正交实验


上图所示有 2 层实验,第一层是 P 实验,第二层是 Q 实验。


P 实验中,用户被分成 2 组,Pa 组及 Pb 组。


Q 实验中,用户也被分成 2 组,Qa 组及 Qb 组。


所谓的正交实验,就是说 Pa 组用户,在 Q 实验中被均匀分入了 Qa 组和 Qb 组,而 Pb 组用户,同样在 Q 实验中被均匀分入了 Qa 组和 Qb 组。


这样的结果就是,在 Pa 实验组且在 Qa 实验组的用户比例是 25%,在 Pa 实验组且在 Qb 实验组的用户,比例是 25%。


正交实验是最广泛使用的多层实验关系。它可以使多层实验的每一层都使用同样多的流量去做实验,并且使各层实验之间的结果不会互相干扰。注意,“各层实验之间的结果不会互相干扰”这个结论是有很强的前提的,就是,各层实验的参数之间,对实验指标没有互相增强或者抵消的效果。也就是,假设 Pa 提高了 10%效果,Qa 提高了 10%效果,Pa+Pb 叠加,提高的效果是 20%,而不是 25%(增强)或者 15%(抵消)。多数多层的实验,都是以这个假设为基础的。


比较简单的在多层实验之间实现正交关系的方法是,是在分配流量的哈希函数中把实验所在层名称作为一个参数。


mod=hash(layerName,userId)%20


2 互斥实验


上图所示,P 实验使用的流量,Q 实验不能使用,而 Q 实验使用的流量,P 实验也不能使用。这种情况叫做互斥实验。这个实验关系的好处,是不用担心正交实验里面,“各层实验之间的结果不会互相干扰”的假设不成立,而可以独立做实验。而坏处在于,一旦把各层实验做成互斥的,就会使每层实验可用的流量减少,从而使每层实验所需的时间增加,迭代效率变低。


前方高能预警!高能预警!真的是高能预警!说三遍!

下文涉及各种学科包括但不限于软件工程 高等数学 统计学可能还有运筹学等,反正是看晕了,非技术大佬请直接翻到最后一部分看总结……


实验效果跟踪方法

A/B Test 的目的是验证不同产品功能点/策略对某个或者某几个指标的影响差异,因此需要进行数据效果跟踪。和整体指标观测所需要的数据效果跟踪方案相比,A/B Test 的数据效果跟踪方案需要增加考虑的主要有 2 点:1. 标识实验的分组 2. 标识实验所在的层次。


数据效果跟踪方案一旦确定,会耦合大量的上下游系统和数据报表统计流程,甚至数据挖掘流程,修改起来异常麻烦。所以,在系统设计早期确立一套比较合理的效果跟踪方案是非常重要的,可以极大提高后续的工作效率。


下图是我根据过往经验进行抽象总结的,我认为比较合理的数据效果跟踪方案。



  1. 我们需要给每个实验层传入用户唯一标识(uId)。用户唯一标识和层次标识(layerId),是确定用户在本层实验分组(testId)的主要参数。

  2. 我们还需要给每个实验层传入请求唯一标识(requestId)。请求唯一标识的作用,是可以串联不同实验层的数据,以计算层与层之间的转化率数据。这个设计看起来不起眼,却非常关键。有些没有采用这个方案的系统,每一层的层次标识和实验分组都需要传递到下一层及下下层,导致在系统与系统之间出现高度耦合,极大提高了团队间的沟通协调成本,这是非常惨痛的教训。

  3. 值得一提的是,我在这里设计了统一的 A/B Test 控制中心。其优点是确保专业的人去设计和维护 A/B Test 框架,确保真正实现所需要的实验层与层的关系。在不同团队各自采用 A/B Test 分流方案的公司,要做到这点恐怕沟通成本也不小。


实验效果评估方法

在介绍相关知识点之前,我们先建立一个实际应用中可能用到的场景,以便讲解的时候比较直观。


讨论场景

我们在一款 app 的首页上的一个可点击位置,设计了 1 种新的图标,我们想看看用户对这个新的图标的点击率相对原来老的是否有提高。其中图标 a 的流量组是对照组,图标 b 的流量组是实验组。


图标样式访问用户数
(UV)
点击用户数
(CK)
转化率
(CR)
a50001002%(CRa0)
b50001302.6%(CRb0)


零假设

A/B Test 本质上是统计学里面的一个假设检验的过程。假设检验里面有个概念叫零假设。在这个实验中,我们的零假设是:a 图标比 b 图标效果更好是由于随机因素造成的。


H:{CRa=CRb}


我们后面的数据分析,就是要决定拒绝或者接受这个零假设。通常,我们的目的是要用实验数据证明 CRa 和 CRb 统计上是不相等的,也就是拒绝零假设。


零假设的对立面,可以叫做实验假设,也就是我们通常要证明的假设。这个不相等是怎么个不相等法,就引出了我们下面要说的单侧检验与双侧检验。


单侧实验与双侧实验

单侧检验,是指我们只想证明 CRa<CRb,或者只想证明 CRa>CRb。其实验假设就是:


H1:{CRa<CRb}


或者


H2:{CRa>CRb}


双侧检验,是指我们想证明 CRa>CRb 或者 CRa<CRb。实验假设为:


H3:{CRa>CRb||CRa<CRb}


p 值(p-value),显著性水平

p 值定义为,在零假设成立的条件下,获得和观察到的数据一致,或者更加极端(地背离零假设)的情况的概率。p 值越小,说明零假设越有问题,因为观察到太小概率的事件发生了。


p 值的具体计算和我们希望做单侧检验还是双侧检验有关。


对于单侧检验,以对应 H1 的单侧检验为例,p 值计算如下:


p=Pr(CRB-CRA>=CRB0-CRA0|H)


对于双侧检验,对应 H3,p 值计算如下:


p= 2*min{Pr(CRB-CRA>=CRB0-CRA0|H),Pr(CRB-CRA<=CRB0-CRA0|H)}


双侧检验的 p 值理解起来比较费脑子。还好,通常我们需要的是单侧检验的情况,所以,可以先理解理解单侧检验的 p 值计算就好。


p 值越小说明零假设越有问题,也就说明实验假设越显著。所以,行业内可以设置一个 p 值的上界,比如 0.05 作为显著性的标准,这个值,就是显著性水平。目前一般的显著性水平设置为 0.05。也就是说,如果 p 值小于 0.05,就说实验假设是显著的。


前面的 p 值计算公式其实是算不出来的。实际上计算 p 值的时候,需要先计算 zscore,然后查正态分布表算出 p 值。


总结

上文太长不会算怎么办

那么复杂的计算逻辑,看着就晕了,一般人不愿意去费这个脑子。好在,已经有国外网友把一些好用的计算工具开放出来了,咱们就不用去浪费那些脑细胞来计算这些指标了。


1:http://abtestguide.com/calc/


这个网站计算的指标比较完善,p 值,z 值和其他很多本文未介绍的指标都有。这个网站还考虑了单侧实验和双侧实验的情况。不过它的问题是不太稳定(可能和我这边的网络环境有关系)。


  1. https://vwo.com/ab-split-test-significance-calculator/


这个网站只计算了单侧检验的 p value。好处是比较稳定。


得不到显著的结论怎么办

对于做 A/B Test 来说,这是常见的情况。其原因,不外乎 2 点:


  1. 数据量不够,可以用这个工具看看是否实验时间不足:


https://vwo.com/ab-split-test-duration/


如果发现实验所需时间已经超出承受范围,那么,可能说明,在当前阶段并不适合做 A/B Test。


  1. 实验结论就是如此。那就需要具体分析原因,重新优化实验方案。


2020 年 4 月 05 日 16:54449

评论

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

想看新指标?教你轻松写prober插件

滴滴云

运维 滴滴夜莺 Obsuite prober插件

政府区块链招投标市场活跃 “区块链+警务”等多元化领域成​方向

CECBC区块链专委会

什么是开放艺术?探讨融合区块链技术的新艺术范式

CECBC区块链专委会

程序员成长第二十篇:刚晋升管理者,有哪些方面要注意?

石云升

程序员成长 28天写作 职场经验 管理经验 3月日更

从JVM底层原理分析数值交换那些事

云流

Java JVM 架构、

作业 - 第五周

eva

【回溯算法】组合总和升级版 ...

宫水三叶的刷题日记

LeetCode 数据结构和算法 面试数据结构与算法

瓦力量化交易系统开发|瓦力炒币机器人软件APP开发

开發I852946OIIO

系统开发

小树量化交易系统开发|小树炒币机器人软件APP开发

开發I852946OIIO

系统开发

【邀请有礼】全球视频云创新挑战赛邀请有礼:参与 100% 获得 “壕” 礼,更有机会获得 JBL 音箱、Cherry 机械键盘

阿里云视频云

阿里云 音视频 比赛

终于讲清楚了:深入理解Java 应用程序中 final 关键字的各种使用场景

老王说编程

Java final

Linkerd or Istio?哪个Service Mesh框架更适合你?

xcbeyond

Service Mesh istio 技术选型 Linkerd 3月日更

单点登录(SSO)

一个大红包

SSO 单点登录 28天挑战 3月日更

舒畅,阿里大牛终于把困扰我多年的「Spring全家桶」讲明白了!十年IT老兵亲述Spring实战经验

Java架构之路

Java 程序员 架构 面试 编程语言

女神节|深情告白季,程序员和他的浪漫

InfoQ写作平台官方

活动专区

VMware Workstation

梅花鹿鹿

虚拟机

使用 Puppet 进行配置管理

信码由缰

DevOps 配置管理

当开工季遇上采购季,云通信主播教你怎么省心又省钱

阿里云Edge Plus

云通信

JAVA学习心得

张鹤羽粑粑

28天写作 3月日更

震撼来袭!2021版全新版Java面试笔记现世,简直把所有Java知识面试题写出来了

云流

Java 架构 面试

融云CEO韩迎:飞信十年珍贵历练,做To B别有取巧的心思

融云 RongCloud

IM RTC 飞信

进程和nginx

一个大红包

28天挑战 3月日更

企业级链表设计思路:

大忽悠

3月日更

基于 Wasm 和 ORAS 简化扩展服务网格功能

阿里巴巴云原生

Docker 容器 微服务 云原生 k8s

2021“金三银四”刷爆朋友圈的“Java核心面试知识手册”这波Offer稳了

Java架构之路

Java 程序员 架构 面试 编程语言

“金三银四”面试别慌!最新阿里P8内部Java面试涨薪秘籍!全网最新已开源

Java架构之路

Java 程序员 架构 面试 编程语言

用户画像实践

Jackchang234987

DataPipeline通过华为鲲鹏兼容性认证,以自主科技创新推动中国信息产业进步

DataPipeline数见科技

大数据 数据融合

火币量化交易系统开发|火币炒币机器人软件APP开发

开發I852946OIIO

系统开发

自动炒币机器人系统开发|自动炒币机器人APP软件开发

开發I852946OIIO

系统开发

mysql常用命令

Sakura

Study Go: From Zero to Hero

Study Go: From Zero to Hero

A/B测试的技术大揭秘-InfoQ