写点什么

滴滴数据驱动利器:AB 实验之分组提效

  • 2020-06-05
  • 本文字数:3398 字

    阅读完需:约 11 分钟

滴滴数据驱动利器:AB实验之分组提效

1 AB 实验概述

互联网公司中,当用户规模达到一定的量级之后,数据驱动能够帮助公司更好的决策和发展。在滴滴各个团队中,我们经常会面临不同的产品设计方案的选择或者多个算法方案的决策,比如顶部导航栏的排序方案一二三,派单算法一二三等等。传统的解决方法通常是由该领域经验丰富的专家来决定,或者由团队成员讨论决定,有时候甚至是随机选择一个方案上线。虽然在某些情况下传统解决办法也是有效的,但是让 AB 实验后的数据说话,会让方案选择更加有信服力。


滴滴 Apollo AB 实验平台,支持了滴滴诸多业务的功能优化、策略优化以及运营活动,提供了在线实验以及离线实验的能力,并行实验数达到 6000+ / 周。在分组方法上提供随机分组以及时间片分组来应对不同的实验场景。效果分析方面,我们对基础指标、率指标、均值指标、留存指标等多种类型的指标提供了均值检验、VCM、Bootstrap 等多种分析手段。

2 分组的问题

一次完整的 AB 实验可以分为以下几步:



第一步


设计实验方案,包括确定实验对象,划分实验组,确定实验提升目标等。


第二步


进行人群分组,一般是一个空白组加一个或多个实验组


第三步


将需要实验的策略,方案或者功能施加到各个组,收集数据


第四步


对实验关心的指标进行分析观察


本文主要讨论其中第二步的实现。业界在进行实验对象分组的时候,最常用的是随机分组方式。这也是滴滴诸多实验中占比最大的分组方式。随机分组的做法可以实现为对实验对象的某个 ID 字段进行哈希后对 100 取模,根据结果值进入不同的桶,多个不同的组分别占有一定比例的桶。实验对象在哈希取模之后,会得到 0 ~ 99 的一个数,即为该实验对象落入的桶。这个桶所属的组就是该实验对象的组。



上述的这种分组方式称为 CR(Complete Randomization)完全随机分组。进行一次 CR,能将一批实验对象分成对应比例的组。但是由于完全随机的不确定性,分完组后,各个组的实验对象在某些指标特性上可能天然就分布不均。均值,标准差等差异较大。如果分组不均,则将会影响到第四步的实验效果分析的进行,可能遮盖或者夸大实验的效果。


待分流的个体具备一定的内在特点,比如就 GMV 这个指标来说,人群中会存在高 GMV,中等 GMV,低 GMV 等不同层次的用户。如下图所示,对于实验人群进行完全随机分流的方式,存在一定概率的不均匀,比如高 GMV 人群在某个组中的分配比例偏高,导致两个组的 GMV 相对差异较大。比如一次实验中,希望提升北京市的 GMV 1%,在进行分组之后,实验组的人群 GMV 天然就比对照组的人群 GMV 高 2%。这样实验进行的结果就变的无法比较。如果没有注意到实验前的组间不均情况,甚至可能验证出错误的结论。



随机分流人群分组不均示意图


基于 CR 的风险较大的情况,一般会对 CR 进行简单的一步优化,即进行 RR(Rerandomization)。RR 是在每次跑 CR 之后,验证 CR 的分组结果组间的差异是否小于实验设定的阈值。当各组的观察指标小于阈值或者重新分组次数大于最大允许分组次数后,停止分组。



相比于 CR,RR 通过牺牲计算时间,能在一定概率上得到符合要求的分组。重分组次数与输入的实验对象样本大小相关。样本量越大,需要进行重分的次数一般较少。但是 RR 分组能得到符合要求的分组有一定的概率,且需要花更多的时间。所以,我们希望通过对分组算法的改进,在一次分组过程中分出观察指标均匀的分组结果,如下图所示。



分流人群分组均匀示意图

3 自适应分组

Apollo 实验平台实现了滴滴 AI LAB 团队设计的 Adaptive(自适应)分组算法。Adaptive 分组方法可以在只分组一次的情况下,让选定的观测指标在分组后每组分布基本一致,可以极大的缩小相对误差。相比于传统的 CR 分组,Adaptive 分组的算法更加复杂,在遍历人群进行分组的同时,每个组都需要记录目前为止已经分配的样本数,以及已经分配的样本在选定的观测指标上的分布情况。从分流人群中拿到下一个要分的对象后。会对实验的各个组进行计算,计算该对象如果分配到本组。本组的观测指标分布得分情况。然后综合各个组的预分配得分情况,得到最终各个组对于该实验对象的分配概率。



Adaptive 分组流程

4 系统设计

系统交互流程如下:



Adaptive 分组方案的设计与实现复用了 Apollo AB 实验已有离线分组架构的能力。用户在实验平台通过 API 接口或者页面创建完 Adaptive 实验之后,实验平台会将分组需求发送到分组任务管理系统,生成分组任务存入数据库中。Adaptive 分组执行分为以下几个步骤:


首先分组任务管理系统从数据库中获取需要进行分组的任务。然后根据任务类型调用不同的分组服务。Adaptive 分组服务从数据库中获取实验对应的计算信息。根据实验计算信息中的观察指标,从 HIVE 中获取指标数据,根据人群信息的地址获取人群数据。执行完分组算法之后,将分组结果写入 HDFS。

5 算法介绍

样本打乱 &随机分配

将人群 shuffle 打乱之后,对于人群的前 2 * K(K 是组数)的人进行随机分组,保证每个组中至少有两个样本之后再开始进行 Adaptive 分组。


组参数初始化

根据实验的组以及每个组的人群比例计算出各个组的直接分配概率和间接分配概率。每个组上的直接分配概率和间接分配概率,分别表示了在直接分配以及间接分配情况下,选中该组后,样本分配到各个组的概率。根据已经分配的样本数据,初始化观测指标分布情况。


判断直接或间接分配

计算各组已分配样本数和组所占比例之间的关系,得到各个组的平衡系数 BS,如果各个组的比例平衡系数相差较大,则进行直接分配。选用 BS 最小的组的直接分配概率来分配接下来的一个样本。通过直接分配来粗粒度的调整各组的分配比例。如果平衡系数相差不大,则走接下来的指标分布计算,来决定使用哪个组的间接分配概率。

计算各组预分配得分


计算将要分配的一个样本,如果分配到组 k 后,组 k 的指标分布得分 MS k,MS 是根据 ANOVA 模型计算出来的每个组在各个观察指标上的均值,方差情况。通过比较各组的 MS,选出向下偏离平均水平的组,以该组的间接分配概率作为各个组本样本的分配概率。

更新指标分布

通过上述的流程,无论使用直接分配还是间接分配,最终得到一个样本的实际分组后。用这个样本在各个观测指标上的数据更新分配到的组的指标分布数据。如此遍历,直到分配完所有样本。

6 方案效果

使用 Adaptive 分组之后,1 次分组得到符合要求的分组概率超过 95%。


而不同算法间对于组间差异的实际优化情况不仅是与算法有关,也和进行分组的人群的大小,人群的分布特性相关。一般来说,人群大小越大,分布越均匀,使用随机分组的分组结果就会越好。组间差异会越小。下面进行测试的数据人群规模不大,所以直接随机分组的差异会显得比较大,并不代表所有情况。



如上图所示,是对一个大小为 10000 的司机人群进行分组测试,并观察分组后的结果在 7 日 GMV,7 日在线时长,全兼职三个指标上的分布情况,并取每次分组结果中三个指标上差异最大百分比作为本次分组的差异。其中 CR(Complete Randomization)是指一次随机分组,RR(每次是跑 CR100 次,取最优结果得到),CAR(Covariates Adaptive Randomization)是指一次 Adaptive 分组。图中的纵坐标是该区间的次数,横坐标是差异的百分比。


每种方式均执行了 400 次,统计指标的组间最大差异。CR 方式的差异最大,最大差异可能达到 14%以上。RR 在 CR 的基础上,通过时间换准确性,较大的降低了组间差异,最大组间差异能在 2.7%以下,但是这个差异依然在实验中不能被接受。CAR 通过算法的优化,进一步降低了组间的差异。95%的情况下能把差异控制在 0.8%以下。

7 总结

通过提供 Adaptive 自适应分组能力,我们极大的提高了随机分组实验的数据精度。降低了无效实验的概率,缩短了实验周期。然而,对于已经通过 CR 方式完成的随机分流实验,用上述的这一套方案已经无法重新均衡。如何从这种已经完成的实验分组中抽取分布平衡的样本进行效果评估是一个更大的挑战,目前正在设计中,欢迎大家在本文留言,提宝贵意见,一起探讨实验相关问题。


作者介绍


仇科凯


滴滴出行高级研发工程师


2018 年北邮硕士毕业加入滴滴。在工程效能团队 Apollo AB 实验项目组,从事实验效果评估相关工作,负责实验科学性相关的研究。


本文转载自公众号滴滴技术(ID:didi_tech)。


原文链接


https://mp.weixin.qq.com/s?__biz=MzU1ODEzNjI2NA==&mid=2247489271&idx=1&sn=6fe0f9e7a0c311c296ee23d964e0a5b2&chksm=fc2a7850cb5df146792a2eb6d8762dc0361531a741d80c20f041c9b955e540046d7d349b886a&scene=27#wechat_redirect


2020-06-05 14:055473

评论

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

架构实战营-模块五

瓜子葫芦侠

「架构实战营」

【LeetCode】N 叉树的最大深度Java题解

Albert

算法 LeetCode 11月日更

你敢相信?我用了3个月成功破茧成蝶,从简历被拒到收割8个大厂offer

热爱java的分享家

Java 面试 程序人生 编程语言 经验分享

🏆【Alibaba中间件技术系列】「RocketMQ技术专题」让我们一起实践RocketMQ的服务搭建及配置操作

码界西柚

RocketMQ 11月日更 Apache RocketMQ 集群搭建

模块四作业-redis 存储方案设计 - 学生考试试卷

Geek_cb2b43

【高并发】深度解析ScheduledThreadPoolExecutor类的源代码

冰河

Java 并发编程 多线程 高并发 异步编程

极客时间算法训练营Week01

jjn0703

算法训练营

不可思议,阿里巴巴首发:Java核心框架指导手册,竟1小时点击量破千万

热爱java的分享家

Java 面试 程序人生 编程语言 经验分享

Elasticsearch写入数据的过程是什么?以及是如何更新索引数据的

热爱java的分享家

Java 架构 程序人生 编程语言 经验分享

Hive基本理论和常用函数

犟马骝

调优达到上限?这份尊享版性能实战套餐,让你领先别人好几个级别

热爱java的分享家

Java 面试 程序人生 编程语言 经验分享

Pulsar VS. Kafka(2): 以Segment为中心的架构

Apache Pulsar

kafka 架构 分布式 Apache Pulsar 消息中间件

System.Text.Json自定义Conveter

喵叔

11月日更

Pulsar VS. Kafka(1): 统一的消息消费模型(Queue + Stream)

Apache Pulsar

kafka 架构 云原生 Apache Pulsar 消息中间件

如何通过抓包来查看Kubernetes API流量

Robert Lu

golang #Kubernetes#

架构实战营 - 模块四作业

危险游戏

架构实战营

微服务架构中,二次浅封装实践

架构 分布式 微服务 技术栈 二次封装

nginx配置详解

小鲍侃java

11月日更

遇到了几道关于作用域的前端小题

空城机

JavaScript 大前端 11月日更

终于有人将Github星标百万的Spring技术精髓收录成册

热爱java的分享家

Java 面试 程序人生 springboot 经验分享

明道云对接企查查,一键矫正客户信息

明道云

字节跳动面试官:SpringBoot统一接口返回和全局异常处理怎么玩?

热爱java的分享家

Java 架构 程序人生 编程语言 经验分享

架构实战营模块四作业

孙志强

架构实战营

redis sentinel 设计考试试卷

云里雾花

redis sentinel

先睹为快即将到来的HTML6

devpoint

JavaScript html5 11月日更

记一次提升18倍的性能优化

捉虫大师

性能优化 Go 语言

考试试卷存储方案

天天向上

架构实战营

微博评论的高性能高可用计算架构

deng

架构实战

微博评论的高性能高可用计算架构

deng

架构实战

模块四作业

Asha

「架构实战营」

真香!Github一夜爆火,阿里性能优化不传之秘终于开源

热爱java的分享家

Java 程序人生 性能优化 编程语言 经验分享

滴滴数据驱动利器:AB实验之分组提效_架构_李斌(空堂)_InfoQ精选文章