|
一、A/BTest是什么?二、AB系统设计与实现2.1系统介绍2.2系统架构2.3系统实现三、A/BTest实施指南3.1实验设计3.2实验埋点上报规范3.3实验决策指南3.4实验到期下线四、未来规划与展望五、总结导读在数据驱动时代,不管是在产品功能迭代还是策略决策时都需要数据的支撑。那么,当我们准备上线一个新功能或者策略时,如何评估新老版本优劣,即数据的可量化就成了问题。这个时候就需要引入A/BTest了。一、A/BTest是什么?A/BTest的概念来源于生物医学的双盲测试,双盲测试中病人被随机分成两组,在不知情的情况下分别给予安慰剂和测试用药,经过一段时间的实验后再来比较这两组病人的表现是否具有显著的差异,从而决定测试用药是否有效。在互联网行业中,在产品正式迭代发版之前,将Web或App界面或流程以同一个目的制定两个或多个方案,在同一时间维度,将流量对应分成若干个组,在保证每组用户特征相同(相似)的前提下,展示给用户不同的设计方案,收集各组的用户体验数据和业务数据,最后分析评估出最好版本,科学的进行决策。二、AB系统设计与实现2.1系统介绍转转ABTest系统的核心功能主要包含五个部分:实验管理:实验配置、上下线等操作。指标管理:分业务线创建与管理数据指标,数据指标分为「事件指标」和「复合指标」。白名单管理:各种分流标识的白名单创建与管理。数据报告:总实验用户数、流量概览、关注指标图表和实验结论数据。分流服务:供业务方调用获取实验分组结果的RPC服务。2.2系统架构2.3系统实现2.3.1实验管理实验列表:是所有实验的集合,整个实验列表分为三个区域「筛选/查询区域」、「新建实验」、「列表区域」。新建实验:要求填三个部分信息基础信息、实验配置信息、实验策略配置,状态默认为测试中。实验基本信息实验配置信息实验策略配置2.3.2指标管理指标分为「事件指标」和「复合指标」两种类型。事件指标通过埋点事件配置统计,复合指标通过基础的事件指标进行四则运算生成。2.3.3白名单管理白名单功能提供统一的白名单创建与管理,用于实验配置时给相关实验组添加白名单,作用与分流服务,方便业务实验开发测试时通过配置白名单直接进入相应的实验组。2.3.4数据报告实验报告是针对单个实验,配置的核心指标以及相关指标一个统计性的数据报告说明。基本信息实验ID:该实验的实验ID。实验名称:该实验的实验名称。开始时间:该实验正式上线的时间。运行天数:该实验从上线至今/结束前的运行天数。操作记录:记录这个实验的操作变化记录,包含流量分配、核心指标修改、实验暂停/上线等。查看配置:查看这个实验的配置信息。核心数据整体-总实验用户数:实验上线至今/结束前共参与实验的用户数,按照分流标识进行统计。分组-总实验用户数:各个分组实验上线至今/结束前共参与实验的用户数,按照分流标识进行统计。总实验用户占比:「分组-总实验用户数」/「整体-总实验用户数」*100%。流量分配:创建实验时,流量的分配比例。核心指标值:创建实验时,配置的「核心指标」对应的数值,这里会根据【指标管理】中配置的数值方式与小数位数进行显示。统计学校验:用于描述试验组指标相比于对照组的提升范围。随着参与试验的样本量逐渐增加,数据指标波动趋于稳定,置信区间会逐渐收窄。一般来说,置信区间选择95%。统计功效:统计功效用于描述通过试验能检测出试验结果真实可靠的概率;一般用于衡量实验不显著时,是否需要继续扩大样本继续实验。一般当差异不显著时,统计功效小于80%,需要继续做实验,当差异不显著是,统计功效大于80%,说明基本对照组与实验组没有差异。实验结论:实验结论根据「核心指标」与「统计功效」得出实验结论。流量概览主要目的衡量流量分配是否均匀,指标为「新进组用户数」:当天第一次参与实验的用户数。关注指标(包含核心指标)实验UV:同「分组-总实验用户数」,各个分组实验上线至今/结束前共参与实验的用户数,按照分流标识进行统计。指标名称:所选的指标对应的名称。差异绝对值:该分组对应对照组在该指标上的差异的值,举例:如对照组订单数为50,实验组为100,这里的差异绝对值为100-50=50。差异相对值:该分组对应对照组在该指标上的差异的百分比,举例:如对照组订单数为50,实验组为100,这里的差异绝对值为(100-50)/50=100%。置信区间:核心指标通过实验配置的置信水平统计计算。2.3.5分流服务分流逻辑分流服务实时同步已上线运行的实验配置,业务调用方通过实验ID+分流标识获取实验的分组结果,具体实现逻辑如下:if (白名单判断) { return "白名单组";}if (实验下线判断) { return "决策组";}if (进组不出组) { if (缓存结果判断) { return "缓存结果组"; }}// 分桶分组,用实验id + 分流标识进行hash取模100得到桶号,同一用户在不同实验中的桶号不完全一样,确保实验之间的独立性int bucketNum = BucketNumUtil.getBucketNum(testId + "_" +tokenId);// 根据桶号获取对应的实验组String groupName = getGroupName(test, bucketNum);if (进组不出组) { redisCache.set(testId, tokenId, groupName, exAt);}return groupName;分流方案结合转转业务的特点,使用了无层方案。所谓无层,就是每个实验都是单独一层,使用实验id作为种子将1-100的桶号进行洗牌打乱,具体实现方法如下:// 生成1-100的桶号,并使用testId作为种子洗牌打乱(相同的种子洗牌结果一样,从而保证同一ABTest的桶号List不变,且可根据testId预测,不同实验的桶号分布的随机性,确保实验之间的独立性)List list = Stream.iterate(1, item -> item + 1).limit(100).collect(Collectors.toList());Random rnd = new Random(testId);Collections.shuffle(list, rnd);// 根据组流量比例将桶号分配到各组for (int i = 0; i groupBucketNumList = Stream.iterate(1, item -> item + 1).limit(100).collect(Collectors.toList());Random rnd = new Random(groupId);Collections.shuffle(groupBucketNumList, rnd);// 根据互斥组流量比例将桶号分配到各实验for (int i = 0; i testBucketNumList = Stream.iterate(1, item -> item + 1).limit(100).collect(Collectors.toList());Random rnd = new Random(testId);Collections.shuffle(testBucketNumList, rnd);// 根据组流量比例将桶号分配到各组for (int i = 0; i
|
|