01 A/B 实验应用
A/B 实验应用作为论证的黄金方法,目前已经成为一个必然的选择,但是实际上如何在企业内部去建设实验平台,还充满了很多选择。目前的实验平台,包括在线实验的数量,已经成为衡量互联网公司体量、业务量以及用户量的一个隐藏指标。一些大厂的实验平台,同时在线实验数量超过 10000,可能每个月新建的实验数量都会大于 1000。
1. A/B 实验是论证的黄金方法
上图列出了一些数据分析方法,比如案例研究、观察研究、类实验、随机控制实验,以及统合分析,即结合随机实验和观察研究去做一些强分析。
这几层分析方法中存在一些通用的因素,首先,样本是定向的样本还是随机的样本。第二个是有没有控制,比如最下面的案例研究是没有控制的,它可能针对一个群体做分析,而 A/B 实验天然会分成对照组和实验组,是有控制的。最后一个就是实验结论是否可以复现,是否科学。这三个因素的不同导致了整个分析方法可信度的差异。从下往上,可行度逐步提升。A/B 实验是分析成本最低的一个方法,可以通过工程化的方法来提效,通过 A/B 产品化的方式来降低使用门槛。
A/B 实验有三个主要的特点:
(1)第一个是先验性,用事实说话,可以通过小流量低成本来得到一些结论;
(2)第二个是科学性,实验分析时会用到假设检验的方法,相对来说是比较科学的;
(3)第三个是推断性,通过随机流量控制可以排除混杂因素的干扰,聚焦到我们的控制变量和实验策略上。
2. 实验平台选择
整个 A/B 平台的建设,主要有两个思路,第一个就是直接采购第三方平台;另外一个就是自建平台。
国内目前比较好的第三方产品,比如火山引擎,无论是产品 feature 还是整个应用情况都比较好,因为它是基于自己内部的优秀实践。另外腾讯也开放了第三方平台。热云、神策数据也提供了 SaaS 的实验平台。国外的厂商也比较多,像 VWO 实验测试平台、谷歌的 Optimize、以及 Optimizely 等等,都是一些比较有竞争力的产品。
第三方平台通常适用于用户体量比较小,数据跟分析的基建还相对比较薄弱的公司。通过第三方平台的使用,提升公司内部数据以及分析的认知。
用户行为分析和 A/B 实验是紧密联系的,因为它们都是基于用户的行为,让用户来告诉我们答案,包括底层的一些分析引擎、存储引擎的等基建也都是可以复用的,这也是火山引擎的 A/B 测试和分析能力,和用户行为分析能力都是紧密耦合在一起的原因。
对于公司自建平台,国内主流的一些互联网厂商也都有很好的实验平台,比如滴滴、美团、阿里、网易、新浪微博等,甚至有一些公司内部有多个实验平台。国外的微软、谷歌也都有非常有特色的实验平台。这些公司也都是用户体量比较大,实验场景多,数据分析基础比较强的公司。在自建实验平台的时候,如果公司业务体量大的话,不同的业务可能结合自身的需求都建过一些实验平台了,这时候还要推动平台从 N 到 1 的建设。在新建平台时,就要考虑业界的优秀实践,同时还要考虑业务方的独特诉求。这样在公司内部推行实验平台的时候才能顺畅,并且最终可能变成全公司通用的实验平台。
02 更多业务应用
接下来介绍更多业务应用。通常我们可以从实验类型切入,比如产品类的实验、服务端的实验,算法模型或者策略的实验、运营类的实验或者营销类的实验等等,这些都需要在实验平台中有比较好的支持。
1. 流量
在实验中有三个要素,第一个就是流量,没有流量也就不需要做实验了,流量代表场景参与的用户。可能不同的业务,不同的实验类型,对整个流量的抽象是不同的。第二个是干预,也就是控制。第三个是分析,所使用的业务指标能够体现出做实验的目的。
上图是谷歌重叠实验框架的一个简单示意图,分成了 ABCD 4 种不同复杂度的框架,可以结合自己的业务实际情况来选择,如果公司业务比较多,比如有电商、内容、游戏和支付等,就需要 C 或者 D 这种形态才能够比较好的满足业务需求。
2. 联合实验
接下来讲一下联合实验的几种场景。
其中一种是贯通实验,在同一个业务的上下游之间做实验,比如业务的客户端、前端、服务端、算法测,整体要做一个顺序的实验。通常的做法是,在前端做实验,通过传参的方式来拉动后端去做响应,这是一种比较简单的实验方法。
第二种是联合实验,比如搜广推场景,通常会分为召回、粗排、精排等环节。在做实验的时候都会按实验层来做实验的控制。如果想做层与层之间的组合实验,通常就叫联合实验,比如一个召回加排序的实验,可能有些排序算法针对某些召回队列是有效的,就可以做这种组合实验。如上图中的例子,层 a 和层 b 都在独立的做实验,如果想做 a 和 b 的联合实验,就需要建立一个虚拟的联合层,原有的层 a 和层 b 的流量都会缩水,这是对业务影响最小的一种实现方式。
第三种实验是跨业务的联合实验,比如搜广推场景下如果想用 1% 的用户做免广告测试,就是跨业务的联合实验。也可以通过类似于优先层,或者关联实验等方式来实现。
所以在实际的实验类型设计和实验方案设计的过程中,要灵活考虑不同的业务诉求。
3. 样本独立性
接下来介绍样本独立性。在 O2O 业务中,比如直播、短视频这种涉及到生产者和消费者双边市场的场景下,往往样本的独立性会受到一些影响,就不能很好地实现随机控制。
对于涉及到双边甚至多边的场景,比如买家、卖家以及骑手三方,如果很难满足样本独立性,我们会通过类似版本翻转实验来做一些持续的观测,也就是上个时间片用策略一,下个时间片用策略二,做足够多的翻转,然后再总体上来看策略一与策略二的优劣。比如运力调度策略,如果全局有多个调度策略同时生效,调度就乱了,可以通过给每个调度策略分一个时间片让其生效的方法来论证其优劣。
第二种是时间片轮转实验,在 O2O 场景中也比较常见,比如快递或者外卖的 ETA(Estimated Time of Arrival)场景,我们可以通过时间片翻转的方式来消除时间这种混杂因素的影响。因为在这种场景下,做 ETA 预估时,整个运力下所有的用户之间是互相争抢的,所以可以通过类似实验片轮转的方式来消除这种影响。当然也有双边控制这种实验。因为在做实验的时候会有很重的网络效应,比如分享这种没有代价的溢出效应。还有一种情况是刚才讲到的运力在乘客之间的挤占效应,也会有一些影响。
针对不太敏感的场景,我们会做一些双边的控制,如果是一些有类似挤占效应的强敏感场景,我们也会有类似于合成控制法等一些其他的方法来满足样本独立性假设,避免样本出现干扰,以至影响最后的实验结论。上面这三种案例,本质都是确保分流的随机性从而控制混杂因素对实验结论的干扰。
03 更快系统集成
这一部分将介绍如何更好地做工程集成。在做系统功能提升的时,通常有 4 个议题:
(1)实验配置怎么分发?
(2)怎么做分流的执行服务?
(3)实验的参数怎么与平台和业务代码做集成?
(4)实验日志怎么更好地支持分析师快速分析?
重点主要在后面两部分,因为前两部分的实验平台并没有太多独创的东西。关于配置,要么平台自建配置中心然后做分发;要么依托公司的配置中心做分发。分流服务这块其实没有太多差异点,既然做实验平台,比如 API、SDK、UDF 这些能力都是要具备的,下面重点讲一下参数集成和实验日志。
1. 实验参数
对参数集成的理解分为几个层面。
首先是参数如何控制。有三种控制方法,第一种是基于变体来控制,直接就是分组的名称,这种控制法比较简单,灵活性相对略差;第二种是基于参数来控制,参数有 key-value,比较适合于多选项的实验控制,而且在后续也可以很好地做实验参数的推全控制;第三种是基于配置的控制,所谓的配置是一系列参数的集合,往往基于配置来控制的时候在实验平台整合时会有一些优势。因为某些业务方过往都已经有自己的实验机制了,而且整个实验配置也打包变成了一个配置。
如果是一个新平台切入,比较好的对接方式是支持基于配置的方式来控制,这样可以把一些打包的配置放到平台上,然后分发给他,同时也可以去开发一些额外的特性,比如做一些冲突检测,或是更好的工程适配等等。
第二个层面是参数的优先级,比如实验平台的一个默认配置,再往上一个优先级可能是普通实验中的配置。如果想再增加优先级,类似于在整个流量框架里,还可以给某些层去赋一个更高的权限,在这种层上的实验参数可以有更高的权限。
当然,随着实验越来越多,会发现好多 APP 包体会越来越大,在包体瘦身的过程中,做代码推全也是一个很好的手段,我们也会做一些检测,让 APP 的包体能够有效地减小。
2. 实验日志
实验日志对分析师来说是非常重要的,我们提供了两种实验日志。
一种是分流日志,一般适用于服务端,因为服务端一般来说可以近似的理解为请求即触发,服务端也不会做太多的大规模缓存机制。
另外一种是触发日志,比较适合于客户端,一般来说为了减少实验平台的交互会采用缓存的机制,或者是我们很多实验配置,希望 APP 启动的时候就能够生效,必须要做缓存。所以在客户端会有一些缓存的机制,有缓存以后,如果我们拿到实验配置以后就上报的话,往往进组的样本量就被夸大了,所以这时候我们会做一些触发的控制。比如在做实验配置的时候,配置一些埋点事件,埋点事件触发以后,才认为这个事件被触发了,这样可以更精准的拿到实验效果。
上图是一个简单的示意图,涉及到不同实验日志类型是怎么产生的,怎么传输的,怎么汇聚的,当然涉及到日志的汇聚,包括后续的一个指标分析,大概我们就会有一个数据的管道,比如实验日志表,包括用户行为表,包括逐层聚合后有更多业务数据产生的聚合表。一般来说聚合包括到分组粒度的聚合,到用户粒度的聚合等等,支持后续不同情况的分析。
04 更好实验分析
实验分析的诉求是要保证实验分析是可信的和科学的。为了保证分析是科学可信的,除了前面讲的重叠流量框架,能够保证整个流量是均匀与置信的以外,我们也会有适合于不同指标的各种检验方法。
1. 流量质检
首先讲一下实验开始之前的 Pre AA 检验。不同流量平台整个流量的感知是不一样的,流量管理方式也不一样。如果大家用过火山引擎,会发现它其实是一种弱感知的状态。基于实验的需求,你可以创建无限的流量层,而且这个层对你是隐藏的,但一般来说内部自建的话,我们会把层都抽象出来。因为抽象出来有一些好处,比如像前面讲的联合实验那种场景,可能我们在搜广推的召回排序的时候,要做组合实验,如果没有一个很强的层感知就会无从组合。业界有些公司将流量层叫做 World/Flight/Cell 等等,又或者简单就叫作 layer。所以流量管理的强感知和弱感知,是未来大家要做实验平台迭代需要考虑的点。
对于 Pre AA 验证,上图中右侧展示了我们实现的一个截图。如果 Pre AA 流量是平的,按照统计理论,对它做重复采样,应该发现 AA 之间的 diff 显著程度,p_value 分布应该符合均匀分布。如果不平的话,就要怀疑整个分流是否是不均匀的。分流不均匀有两种情况,一种是整个 layer 在做哈希分流时,seed 是一个坏种子,这个种子不太好,这时就需要选一个新的种子来保证流量分流的均匀性;另一种是 seed 是好的,实验层上也有一些实验在跑了,在使用剩余的流量做实验的时候,又出现了 AA 不平,其实在做实验的时候,会存在实验的记忆效应,比如如果前期刚刚结束了一个实验,这个实验相对来说比较正向的组又分配到新实验的某些组里,它可能本身天然就是有偏的,这时候我们也可以做 Pre AA 的这种验证,但是这种验证其实已经不是在种子层面,而是 bucket 的层面,如果 DAU 能达到千万,分桶一般会用千分桶,这时如果实验桶是不均匀的,我们可以通过更随机的 bucket 分配来有效缩减 AA diff。
这个功能往前再走一步,就变成所谓的流量自检,我们平台可以主动对一些重点的层、重点的业务去做一些流量质检,这样我们可以事先发现问题,甚至可以干预用户去创建实验,这样就不需要用户手动触发在层、桶或者实验粒度上的检验。
同时这样也规避了一个弱势,如果不是基于实时引擎来做 Pre AA 计算,是有时间开销的,这样用户也不需要等,相当于前置计算中可以做到以空间换时间,前置做一些计算,能够让用户使用流量的时候更放心。
2. 校验方法
我们平台目前有三种检验方法,第一种是在做分组样本量均衡时的一个 SRM 检验,比如做了一个 50% VS 50% 的分组,如果分组之间进组的样本量偏移比较大,那么就认为整个分流是不均匀的,这时有可能和 Pre AA 是类似的情况,就很难拿到一个相对比较自信的结论,所以这个地方是 SRM 检验。通常来说,对于这种比率类的,我们可以通过卡方检验去做论证。
另外一种,我们在做实验分析的时候,人均时长、人均 gmv、人均订单也是经常要分析的指标,这时我们用了 Welch’s T 检验方法。
还有一种,像留存、用户转化率等转化率指标,我们是用 Z 检验去做的。之所以用 Z 检验和 Welch’s T,是在于它们对数据集的要求会有一些差异, Z 检验可以用更低的成本去做,比如可以用基于主粒度的聚合表来做 Z 检验的分析,而像 Welch’s T 最好是要基于样本粒度的表来做一些检验的计算。当然其实没有必要去追求更多的检验方法,而是应该结合业务的需求来做。
上图中右面是 Uber 实验指标分析引擎的整个流程,它从数据输入到数据离线处理,到数据分布的判断,包括针对不同的指标类型,会用到不同的检验方法或者计算方法。第一步是计算方差,后面才是应用检验方法进行显著性分析。
3. 指标管理
最后一部分简单分享一下关于指标管理的一些经验。
整个指标体系会分为关键指标,业务的北极星指标,包括护栏指标,以及一些 OEC 指标。比如内容产业,判断用户时长更重要,还是生产者上传更重要,还是广告的收益更重要,往往这时候我们就需要引入 OEC 综合评判指标来下结论。
另外,在指标设计的时候,我们需要考虑整个指标的灵敏性和鲁棒性,所谓灵敏性是当前时间它足够灵敏,能够帮我们下结论。所谓的鲁棒性就是做一些护栏指标或平台指标,也考虑一些指标的计算成本。
指标管理的实现路径有三种,也是三个不同的阶段。
第一个阶段是业务驱动。实验平台前期是搭框架,后期做功能,再后期实验平台就变成一个指标的管理平台了。实验平台指标上十万是非常正常的。在第一阶段可能并没有很多资源,更多的是做规范,有了规范以后,不同业务方依照规范把指标导入进来,就可以用我们提供的实验日志和检验方法,并且我们实验报告能够帮他做决策分析。
第二阶段是任务驱动。随着一些长尾的业务接入,可能业务方没有数据开发资源,这时我们可以去基于一些标准的模板来支持他们更快的接入。这个模板可能包括离线的模板和实时的模板,使用模板指定自己的事件、指标口径等等,能够快速的实现指标接入,包括实验报告。
最后一个阶段是基于事件驱动。这也是很多 SAAS 产品做的。主要有几个好处,首先平台抽象算子,算子用来规范指标的技术。另外业务方在定义指标的时候只需要选择事件、算子,剩下的都是平台托管的,火山引擎目前就已经达到了这一阶段。