数据科学家教你如何科学地利用A/B测试快速迭代产品
最新资讯 • 行业资讯数据训练营
2940
2020-3-12
摘要:
在快速的A/B测试后统计到的显著性结果,可能仅仅是当时的用户行为模式下的显著结果。但这也正是目前移动生态发生急剧变化的情况下,广大移动互联网企业需要的。

作者:友盟+数据科学家 杨玉莲、陆子骏


冠状病毒来袭牵动着每个人的心,但是病毒影响的不仅仅是我们的健康,也以极快的速度极深远地影响了整个移动互联网的发展。主流阵地原本在线下的需求,如医疗和生鲜电商,快速地转到了线上,而人们对在线内容/商品/服务的消费需求也达到了高点。这对于移动互联网企业来讲,是挑战也是机会。


疫情期间大部分的互联网企业新用户激增。如何在疫情期间及之后,快速将这些新用户转化为粘性用户,是这些企业最大的挑战。而对于那些用户下跌的企业,快速地自我迭代抓住已有用户,同时苦练内功开拓新的业务也是迫在眉睫。特殊时期,如何科学有效地“快”步进行业务升级,产品迭代,是当下移动互联网企业的绝对刚需,“快”成了企业前进的关键字。


做为数据界的码农,今天小编就带你学习一下如何科学地利用A/B测试快速迭代产品,提高用户体验,高效实现用户留存。


读者朋友可能要问了,A/B测试,谁不知道啊。不就是将实验对象分流成为两组或者更多组,监测产品某一变量的改变对于业务指标的影响吗。恭喜你答对了一小部分。然而,你是否100%相信只进行了一天或几小时的A/B测试结果,进而决定一次产品的快速迭代?以下图为例,我们看到一个进行了一周的A/B实验,某些天A的指标好于B,某些天B的指标好于A,但实验期间整体的指标A好于B。这时候,你会面临一些问题:似乎目前的结果还不能得出结论,是否需要继续观察几天?实验的样本量是不是太小了?再观察两天就能得出确定性的结论了吗?产品的迭代速度不允许更久的观察期怎么办。



图 1: 效果差异不太显著的A/B测试


如果你还不能很好地回答上面的问题,那就跟着小编一起了解一下:如何利用贝叶斯学派的A/B测试既快又准地进行产品迭代吧!


在介绍贝叶斯学派的A/B测试之前,先简单地介绍下传统的频率学派的A/B测试方法(补充一下,A/B测试,目前市面上的主流方法,就是频率学派和贝叶斯学派这两种)。


频率学派A/B测试方法


频率学派A/B测试在实验进行前要进行实验设计,包括确定实验样本数。对于使用传统t-test的频率派A/B测试,我们可以通过显著性水平(一般设定为5%),统计功效(至少为80%,工业界一般选择90%),指标最小相对变化(比如转化率最少在原有基础上提高10%),还有指标基准值,来预估一个样本数,如果可能的话再根据流量大小来预估一个实验时长。在确定了实验的观察指标,用户分组等业务相关事项后,我们就可以启动频率学派AB测试,然后等待观察样本累积到预定值之后,根据P-VALUE来确定实验结果的显著性。当P-VALUE低于预设的显著性水平时,我们就可以放心地用实验方案替代对照方案了。


疫情对A/B测试带来了哪些影响


疫情期间用户行为变化很快,同时产品的迭代速度也变得更快,一般以周为单位的频率学派A/B测试没法适应疫情期的快速变化。为什么呢?


在互联网生态本身发生剧烈变化的时期,我们很难复用过去的经验预先确定A/B测试的指标基准值及期待的指标最小相对变化值,于此同时流量的不稳定也很难让我们提前预估一个合理的实验时长。 指标最小相对变化值越小,频率学派的A/B测试需要的样本量就更大。这意味着,如果新的产品功能是一个小版本迭代,对业务指标的影响不是特别显著,就需要较长时间的观察才能确认此次迭代的最终效果。因此会影响产品的迭代速度。 频率学派的方法在实验进行时无法得到实验结果(频率学派的no peeking),须要等到实验结束获得预先设计的样本量,才能得到可信的实验结果。该方法的理论基础决定了实验中间观察到的正向结果,并不一定表示实验版本就一定优于对比版本,因此无法在实验过程中做变更或决策。 A/B测试之前需要进行有效的A/A测试。 有可能以前A/A测试出来没有差别的分组,在疫情时期由于用户行为发生变化出现指标有差异的情况,这就需要重新并且尽量快地进行A/A测试。


以上的这些变化都要求能够更快更灵活地进行A/B测试,从而助力产品改版。今天小编在这里就跟大家分享一种新的AB测试方法:基于贝叶斯理论的A/B测试。


为什么贝叶斯学派的A/B测试可以更快?


我们首先来了解一下贝叶斯的A/B测试的主要特点:


贝叶斯方法可以灵活地根据实验观察数据本身的分布选取不同的Likelihood分布,基于贝叶斯的A/B测试本质上是基于先验,Likelihood分布和实验观察结果不断计算实验指标后验概率的过程。 相比于频率学派的方法需要样本数更少。 贝叶斯方法可以实时观察和评估实验结果。而频率学派需要等待实验结束,否则在实验期间评估并采纳实验结果会使得第一类错误率(type-I error rate)上升。 贝叶斯方法的结果更加具有解释性,更方便业务人员去理解。


贝叶斯A/B测试的以上特点,可以有效缩短A/B测试的周期:


首先,针对用户活跃变化大难以预估样本量和实验时长的问题,只要确定了实验观察变量及其先验,贝叶斯A/B测试可以不用预估样本量就开始观察,能很好地解决频率学派A/B测试实施之前诸多的实验设置问题,同时也为前期实验设计节省了工作量。


其次,与频率学派A/B测试必须要等到实验结束才能评估结果不同,贝叶斯的方法可以实时地观测和评估实验结果。这样,基于贝叶斯的A/B测试就可以根据实验的实时评估结果灵活决定是要继续实验还是停止实验做出决策。


此外,贝叶斯A/B测试相对于频率学派的A/B测试可以只要更少的样本得到结论,这样就可以更快的进行A/B测试的迭代。对于那些采用频率学A/B测试需要耗时很久,且提升效果不是非常显著的版本更新实验,我们可以采用贝叶斯A/B测试更快地得出结论,从而可以快速实验众多小的产品改进,最终实现大的版本迭代。


贝叶斯AB测试怎么做?


那么如何利用贝叶斯学派的A/B测试,快速迭代你的产品呢?


 实验设计


实验定义阶段主要是需要确定实验假设,实验优化目标和实验方案。这是实验中最关键的一步,没有意义的假设,不清晰的优化目标还有有缺陷的实验方案设计,都是人力物力的大量浪费。那我们在这一步具体需要确定什么呢?


本次实验的名字(独特命名,可考虑业务+实验条件+日期形式,这样便于区分不同的实验) 和本次实验直接相关的业务目标是什么?间接业务目标是什么? 本次实验的假设是什么? 用什么指标监控和衡量本次实验结果?如有多个指标,最重要的是哪个? 本次实验测试的一个变量是什么? 实验人群如何定义?如果同时进行多组实验,实验人群如何分组分层(正交互斥原则)? 本次实验可以结束的标准?


实验的结束标准很重要。在频率学派的A/B实验里,实验结束主要是由实验是否达到了最小的样本量来判定,之后根据P-VALUE来确定实验方案是否优于基准方案。但在实际操作中,实验过程中有必要随时关注一些核心KPI是否发生大规模下降,这样可以及时终止那些对整体业务或用户体验带来太大负面影响的实验。


对于贝叶斯A/B测试,可以在实验过程中,通过实时计算实验结果,决定是否停止实验。 我们可以通过Expected Loss的大小来判断是否可以停止一次贝叶斯A/B测试的实验。通常我们会从业务需求出发,权衡实验速度和实验结果精度选择一个合适的Expected Loss阈值(如果两组方案在核心指标的差别越小,需要区分这个差别的实验样本量就越大,速度就越慢。反之,需要的样本就越小,速度越快),通过实时计算贝叶斯A/B测试实验的Expected Loss,选择Expected Loss的值小于设定阈值的方案作为最终胜出的方案。


那什么是Expected Loss呢? 它是你选择的实验组相对于基准组指标损失的期望值 AVG(MAX(基准组指标-实验组指标,0))。举个例子,如果基准组的转化率为10%,实验组相对基准组的Expected Loss是1%,意思是说如果采纳实验组的方案,会让转化率平均减少1%。


需要指出的是使用Expected Loss并不是唯一的贝叶斯AB测试实验的结束判据,由于贝叶斯方法输出的是主要指标的概率分布,读者完全可以结合得到的实际指标分布来判断实验是否可以停止,比如另外一种叫做ROPE+HDI的方法。


实验运行


实验进入了运行阶段,可以关注两个组的主要指标和次要指标的分布的实时变化。如果出现了关键指标明显下降的情况,是需要及时排查问题,甚至及时回滚止血的。


但也要非常注意的是不要过早的停止实验,由于改版带来的新奇效应(novelty effect),可能在改版的开始时一部分用户使用时长增加了,转化率也增加了,但是新鲜感过去后又恢复到正常的效应。也有一部分用户由于不熟悉新的版本,导致使用这个APP的频次下降,但是熟悉了以后发现真香,于是长期的使用时长增加了,转化率也增加了。


因此,一次A/B测试实验是否可以终止观察,除了要遵守理论上的实验终止标准之外,其实还需要关注两个点。


首先需要有一些业务的判断,以及基于实际情况的临时决策空间。这也是我们推荐贝叶斯AB测试的原因。它允许我们在实验运行的过程中根据Expected Loss的变化情况灵活决定终止条件。


其次,实验观察时间最好是一个完整的周期。这主要是为了防止一些周期性的行为加强或者削弱对比的效果,影响最后的结论。比如某些APP会在周末活跃用户才会变多,而实验如果只覆盖了周一到周五,实验结论就会有一定偏差。 但在户行为每天都有可能发生变化的疫情时期,周期性的概念其实并不存在。


实验决策


由于贝叶斯A/B测试出现的时间较晚,且贝叶斯A/B测试可以得到所关心指标的概率分布,目前没有一个唯一的标准方法来对贝叶斯A/B测试结果进行统计和评估。 以下列出一些常见的方法:


方法1: 采用实验设计部分提到的Expected Loss 和 Expected Gain(和Expected Loss相反的概念)来做决定。


比如你要测试的是一个新的算法是否能够提高某个页面的转化率,通过实验后你发现相对于基准组,Expected Gain是20%,而Expected Loss 是1%。说明实验带来了转化率的提高,你可以通过评估增加的转化率是否值得投入相应的人力和时间成本,来决定是否将这个新的算法推全。 如果实验组相对于基准组的Expected Gain 和 Expected Loss 分别是1% 和20%,说明实验带来了转化率的降低,需要对这种新的算法下线。


如下图的仿真实验,随着实验的进行,我们看到策略A和B(variant A,B)带来的Expected Loss的的变化。由于B的Expected Loss在实验进行到一定时期就下降到低于阈值(虚线),因此策略B胜出。



图2:通过仿真实验实时统计的Expected Loss。 (本仿真图片来自网络,原始网址)


方法2: ROPE+HDI的方法是根据A,B两个实验各自指标的95% credible interval是否有重合来做判断(95%credible interval指的是一个指标区间,意思是说真实的指标值落在这个区间的概率是95%)。也有实践是选用89%的credible interval来增加实验的统计power。 下图是基于94% credible interval对同时进行的三组实验(只有一个实验变量)的结果对比,我们可以看到P1的区间与P0不重合,且绝对值明显大于P0,因此P1的效果优于P0;而P2的区间在P0,P1之间,且均有重合,我们不能根据ROPE+HDI的方法确定P2和P1两个组的优劣。这时候最佳选择就是继续进行实验直到P1和P2出现差别,那么如果没法继续进行试验怎么办呢?我们还可以计算P2相对P1的Probability of Direction (pd) ,就是计算P2组大于P1组的概率,如果这个概率是可以接受的比如90%,那么我们也可以选择P2作为这个实验的优胜组。


图3:94% credible interval


当然,一次实验的结束不意味着实验的终结,我们会从实验的迭代中发现新的问题,提出新的假设,这也是我们下一个实验的基础和开始。 由此形成对产品进行A/B测试的良性循环,不断一步一步的迭代产品和改进产品,这才是数据驱动的产品发展的大道。


频率学派A/B测试 VS 贝叶斯学派A/B测试


现在已有的很多头部公司都在使用A/B测试来优化自己的产品,比如Google的Firebase, Optimizely, VWO。VWO公司就是基于贝叶斯的方法,而阿里内部的一休(yixiu)和蚂蚁金服的Darwin,Quora,Optimizely,Netflix,Testin A/B大都是使用频率学派的方法。频率学派与贝叶斯学派的A/B测试,其实各有优劣。我们在进行A/B测试的时候,可以根据实际业务的需求,选择更适合自己的A/B测试方案。



图4:频率学派与贝叶斯学派A/B测试的对比


结语

在快速的A/B测试后统计到的显著性结果,可能仅仅是当时的用户行为模式下的显著结果。但这也正是目前移动生态发生急剧变化的情况下,广大移动互联网企业需要的,因为快速的改版带来的收益可能是非常巨大的。我们希望通过介绍基于贝叶斯学派的A/B测试让广大开发者不仅仅在疫情时期可以更快的进行产品的迭代,实现用户的增长和更高的留存,也希望在后疫情时代,开发者能持续利用适合自己业务场景的数据科学技术,实现产品力的良性提升。



附:关于A/B测试的更多资料


更多关于贝叶斯A/B测试的知识,有兴趣的可以参考这篇文章


这篇文章更加详细的讨论了贝叶斯和频率学派方法的不同之处:https://www.gamasutra.com/blogs/ViktorGregor/20181105/328404/Its_time_to_rethink_AB_testing.php


这篇文章更详细的比较了贝叶斯A/B测试和频率学派中t-test的比较:https://docs.pymc.io/notebooks/BEST.html


开源的贝叶斯方法的工具:


1. stanhttps://mc-stan.org/

2. edwardhttp://edwardlib.org/edward2 https://github.com/google/edward2

3. pymchttps://pymc-devs.github.io/pymc/pymc3 https://docs.pymc.io/