AB实验是什么?为什么需要使用AB实验?如何科学的进行AB实验?
一脸茫然的同学们可以先来看看一些基本概念和认知:
AB实验基础-AB是什么?AB的价值?为什么使用AB实验?
AB实验基础-专有名词
MAB多臂老虎机智能调优的基本原理
一、AB实验的冰山一角
你看到的AB实验,以及你没有看见的AB实验。你看见的AB实验仅仅是冰山一角。
AB实验中编程实验为什么是万能的? 为什么万能编程实验却让很多人望而却步? 如何真正的开启一个编程实验? 如何配置实验,如何验证白名单生效? 如何验证AB分流? 如何真的开启AB实验?
带着这些问题,字节跳动资深专家带领我们一起探寻这些问题的答案!
二、大胆假设,小心求证
从最基础的AB专有名词引入,分享进行AB应用接入,验证数据上报,AB客户端编程实验,设计实验,详细配置,验证白名单生效,验证AB分流,AB开启实验等等,带你进入AB实验的世界,让小白也能轻松上手,让我们一起大胆假设,小心求证!精彩内容就在第9期AB大讲堂!
明晚(2021.10.26)直播和大家不见不散,欢迎「飞书直播/火山引擎抖音直播」交流和咨询~
海报👇
AB直播内容:万能的编程实验为何让大家都望而却步
各位同学们和老板们,大家好,我是火山引擎AB测试的程新松,也可以叫我松宝写代码,为啥叫这个?谁还不是个宝呢。言归正传,今天我给大家带来了「万能的编程实验为何让大家都望而却步」。
今天直播聚焦到:编程实验,干货有趣。
一、奇怪问题
什么是编程实验?
为什么编程实验是万能的?
除了编程实验,还有哪些其他模式的实验?
为什么说是万能的编程实验?
编程实验难吗?
编程实验和其他模式实验的区别?
如何开启实验?
如何验证编程实验?
AB测试的道路上,大胆假设、小心求证。
二、主要内容
1、AB一些专有名词介绍。
2、AB应用接入,验证数据上报。
3、AB客户端编程实验,设计实验,详细配置,验证白名单生效,验证AB分流,AB开启实验等。
4、常见问题QA。
三、专有名词
其中一些专有名词
应用名称:应用可以是web,安卓,IOS,小程序,桌面端等,比如:抖音,今日头条等。
appId:每一个应用名称对应一个唯一的标识,表示该应用的Id。
实验: 一个AB实验Flight,一个应用可以建立多个实验。
指标: 主要是几个指标,根据上报的事件构成指标,便于数据计算统计和分析。比如:要分析注册按钮的点击率,直接在指标中可以选择按钮的点击事件和计算方式(算子)的【转化率】。
实验组: 实验组Version,每个实验组都包含配置,代表要做实验的策略。
实验层:layer,每个实验层都代表100%的线上流量。
流量:实验所占的线上流量Traffic,精度0.1%。
流量分配:产品在快速迭代中,会有很多AB测试需要同时做,而且产品的流量有限,所以需要充分对流量进行分配。同样的一群用户,我们可以可以给他划分若干域,每一个域对应多个互斥层。
过滤条件:实验过滤条件Filter,规定被实验命中的用户必须符合(或不符合)这些条件,进而达到缩小用户集群、精准找到用户的目的,只有满足条件的流量才会命中实验。
白名单:在实验正式开启之前,通常需要先选择几名用户进入测试阶段,观察实验是否能够正常获取想要收集的数据。
四、AB应用接入
1、集团应用列表
前提条件:用户注册了账号,已经在某一个集团下,开始接入应用。
火山引擎AB测试地址:https://console.volcengine.com/datarangers
集团应用列表主要是展示当前的集团和该集团下的应用列表
支持:切换集团,搜索集团,选择集团
2、接入AB新应用
2.1 创建应用
输入应用名和App Name,这两项是必填项。
说明一下:
应用名:主要是用来显示应用的中文名称,以及大多数地方展示的名称
App Name:主要是用来作为唯一标识,不支持修改
统计时区:针对你的应用对应的时区,支持搜索。
高级选项:默认不需要填写,不需要关注,web/H5/Wap的应用不需要打开,高级选项内容主要是用户规模,APP的IOS包名和Android包名。
2.2添加代码
选择Web/JS的选项
初始化SDK,在每一个接入的页面的标签前添加代码,最新的代码接入可以参考:https://www.volcengine.com/docs/6287/65803
<script>
(function(win, export_obj) {
win['TeaAnalyticsObject'] = export_obj;
if (!win[export_obj]) {
function _collect() {
_collect.q.push(arguments);
}
_collect.q = _collect.q || [];
win[export_obj] = _collect;
}
win[export_obj].l = +new Date();
})(window, 'collectEvent');
</script>
<script async src="https://lf3-data.volccdn.com/obj/data-static/log-sdk/collect/collect-autotrack-rangers.js"></script>
<script>
window.collectEvent('init', {
app_id: 000000, // 必须替换成申请的 app_id
channel:'cn', // 区域,国内还是海外
log: true, // 开启调试日志,可用于查看ssid,web_id, 和user_unique_id, 上线请关闭
enable_ab_test: true, // boolean类型,是否开启A/B实验功能
enable_ab_visual: false, // boolean类型,按需开启,默认关闭,是否开启A/B实验的可视化编辑模式功能
enable_multilink: false, //boolean类型,按需开启,默认关闭,是否开启A/B实验的多链接实验功能,默认为false
multilink_timeout_ms:3000。 //number类型,A/B实验的多链接实验中关闭遮罩层的时间,默认500毫秒
});
window.collectEvent('start');
</script>
如果应用是Vue/React的单页应用下,只需要在html页面加入即可。
2.3上报行为事件
可以在任意位置调用该函数上报事件,事件会等到添加代码中的window.collectEvent(‘start’) 调用后,才真正发出。
示例代码如下
//这里的事件 play_video、属性 video_title 只是示例,请结合自己的需求进行自定义埋点。
window.collectEvent('play_video', {
'video_title': 'the title here',
})
如果应用是Vue/React的单页应用下,
方案一(更通用):可以在html页面的window.collectEvent(‘start’)进行数据上报测试。
方案二:可以在其他页面或者在App.vue文件下的created或mounted方法下使用window.collectEvent上报行为事件。
2.4验证SDK初始化
在本地调试AB测试接入的时候,谷歌Chrome浏览器按F12,看Application下的localstorage下找teacache_tokens{appId}
说明SDK初始化成功了,SDK默认分配了ssid和user_unique_id等。只要不清除localstorage中的tea_cache_tokens等key,ssid大多数情况下是不变的。只有少数情况下ssid会变,这里我们不告诉大家,后边我们再讲这个。
2.5验证SDK数据上报
在本地调试AB测试SDK数据上报的时候,谷歌Chrome浏览器按F12,看Network下的list接口下找请求体body下的events下找自己的上报事件名称,比如之前上报行为示例写的是「事件 play_video、属性 video_title 只是示例」。
2.6下一步完成应用接入
进入到如下的页面,说明已经完成SDK初始化和SDK上报行为。
点击开始AB实验,直接进入到AB实验平台中。
2.7进入到AB测试平台
⚠️注意:把实验列表页面添加书签🔖,便于后续经常需要用到该页面。
五、AB客户端编程实验
从上一步接入AB新应用最后一步,点击开启AB实验进入到AB的实验列表。
1、简单设计AB实验
我们先来做一个AB客户端编程实验。
我们的目的:应用的留言反馈页面的AB实验。
业务地址:https://chat.chengxinsong.cn/feedback
业务背景:该留言反馈页面可以在未登录和登陆都可以看到,现在对这个页面AB,实验组使用新的UI,对照组使用之前的UI。我们来观察UI改版之后,把「点击留言按钮」的转化率设置为核心指标,观察核心指标的情况,看哪种UI下,用户的留言转化率更高,更置信,用户更偏爱。
3.1实验前VS实验后
2、留言按钮转化率核心指标
我们在代码中,留言反馈页面的提交按钮,点击的时候,上报事件feed_back_click,事件属性名submit,属性值设为ok,设置如下。
// 留言转化率 事件上报
window.collectEvent('feed_back_click', {
'submit': 'ok'
});
本地添加事件上报之后,点击提交按钮,验证事件上报是否正常。
如下截图说明事件上报正常。
3、新建AB的编程实验
点击【新建实验】按钮
有个弹窗,选择实验模式,我们先选编程实验。
3.1 第一步基本信息
点击「确定」按钮,进入到该实验的基本信息。
实验类型有客户端和服务端。我们选客户端实验。实验时长需要科学来估算的。
高级设置我们先可以忽略。
3.2 第二步新建选择关注指标
点击【下一步】按钮,进入到选择关注指标,新建指标
新建指标弹窗,根据自己的业务场景,设置指标参数。
选择指标类别:选择事件指标
输入指标名称:定一个指标名称
指标描述:指标的定义描述,更详细的说明
指标类型:选择单一指标
设置指标:留言反馈页面提交留言反馈的按钮,按钮点击的作为feed_back_click事件,统计口径使用转化率,也称为算子。
数值格式:设置为百分比,小数位数4
3.3 第三步实验版本
点击下一步进入到实验版本配置,
根据我们业务场景自行设定参数和参数值,参数设置为 poc ,对照版本使用参数值为 control ,实验版本1使用参数值为 experiment 。
3.4 第四步设置目标受众
步骤:
1、设置流量100%
2、把示例代码中Javascript中的copy到SDK初始化init方法下面
3、设置「实验版本1」白名单的ssid
4、点击「开始调试」按钮
5、进入到实验列表
如何在本地调试中获取ssid?
我们在本地调试的时候,我们初始化在F12下,Application下localstorage,key为_tea_cache_tokens{appId}的值,看到到 ssid 为 34839479-041a-4d8f-b21a-b00d8c1890fe。
3.5获取实验配置
3.5.1客户侧代码修改
「A/B 测试」通常在SDK 初始化后会向分流服务发送一个分流请求(request),在获取到分流服务的响应(response)后,客户端开发可以根据分流的结果参数完成代码分支的开发。
文档中地址:https://www.volcengine.com/docs/6287/65803#_4-%E8%8E%B7%E5%8F%96%E5%AE%9E%E9%AA%8C%E5%8F%82%E6%95%B0
文档中示例代码:
window.collectEvent('getVar', 'ab-key', 'ab-defalut-value', function(value) {
//ab-key 为实验参数的 key ,用户开发做代码分支,ab-defalut-value 为网络异常时的兜底方案,建议和对照组 value 一致
document.getElementById('id1').innerText = value;
})
根据「第四步把示例代码中Javascript中的代码」copy到SDK初始化init方法下面
3.5.2验证分流
保存代码,刷新页面
接口返回
可以看到分流接口返回的是实验组。
因为在白名单中「实验版本1」中配置了该匿名用户的ssid。
然后刷新页面,分流接口返回的命中的实验不会发生变化
然后根据分流接口返回的进组情况,展示不同用户体验。
3.5.3实际业务修改
比如是vue/react框架代码下,以接入的应用「聊天happyChat」为例子
在SDK初始化的时候,请求分流接口
然后在业务的反馈提交页面做判断。
window对象需要在data中定义。
如果是实验版本1,展示橘色背景的按钮。
否则,展示默认的蓝色背景的按钮。
页面展示上
综上所述,本地开发调试环境验证分流OK。白名单配置命中进入到对应的实验组中。
3.6登陆调用
如果您的产品体系中存在自己的用户体系,需要使用这个,如果不存在自己的用户体系,可以忽略这部分。
文档中:如果您的产品中有账户体系,当用户登录后请立即设置uuid,以便保证用户登录前后口径一致性。
实际:应用中有登陆体系,我们登陆的时候需要调用config方法设置user_unique_id,可以保证登陆前后口径一致。
3.6.1客户侧代码修改
3.6.2验证登陆之后分流
登陆的回调中,调用SDK的config方法,发现ssid没有发生变化,user_unique_id发生变化,变成你设置的用户id,唯一的标识。
如果user_unique_id之前没有被config设置过,ssid不会发生变化
如果user_unique_id之前被config设置过,ssid肯定会发生变化,变成之前user_unique_id对应的ssid。
上述「AB客户端编程实验」所有操作,新建实验,新建核心指标,确定实验版本的参数和参数值,实验流量,示例代码,获取ssid,设置白名单ssid,开始调试实验,验证白名单生效,验证实验分流。
3.7开启实验
回到实验列表页面,操作项中有「开启实验icon」。
点击开始实验有个弹窗:
开始实验后,进组用户可实时查看,指标置信度第二日产出。确实开始么?
点击确定之后,该实验就正式开启起来。
访问到应用的用户,随机分组,如果配置了白名单,会根据配置的白名单进入到相应的组中。
六、常见问题QA
1、ssid发生变化的情况
注意事项⚠️
ssid发生变化的情况:
- 清空localstorage,刷新页面,重新分配新的ssid
登陆时候调用config方法,可能会修改ssid
- 如果user_unique_id之前没有被config设置过,ssid不会发生变化
- 如果user_unique_id之前被config设置过,ssid肯定会发生变化,变成之前user_unique_id对应的ssid。
2、分流结果调用时机的情况
目前SDK初始化的时候,会调用一次分流接口,拿到分流接口返回。
分流接口调用:1、在SDK初始化的时候发生;2、登陆调用的时候发生
只要不再调用的分流接口,页面拿到还是上次分流接口的结果。3、为什么分流接口abtest_config返回的是{}
第1种情况:实验在草稿状态,或者没有创建实验
第2种情况:实验在调试中状态,并且ssid没有记录到白名单中。4、ssid,user_unique_id,webid的区别?
SDK的init初始化的时候,user_unique_id 与 web_id 相等的,ssid是根据user_unique_id等hash操作生成。
- 当用户调用config方法的时候,可能会修改ssid,这时候user_unique_id 与 web_id 不想等,判断后端表中是否有该user_unique_id对应的ssid(也就是该user_unique_id是否调用了config方法)?
- 如果有的话,返回后端表中ssid,会修改ssid。
- 如果没有的话,返回前端传给后端的ssid,并且这个ssid会和user_unique_id发生一对一绑定,写入到表中。
优选文章
1、技术文章
- 101之后,我们一起来做 TS 体操102
- Node 8 升级 12 存在 array.sort 表现不一致风险
- 我们一起来做 TS 体操101
- JavaScript数组reduce()方法详解及奇淫技巧
- Grid布局,你会了吗?
- babel背后到底执行了什么?
- npm的原理
- 快速学习Gulp并接入到项目中(一)
- diff算法深入一下?
2、AB实验
3、每日一题
4、总结
字节内推
最后
为团队建设贡献一份力量,世界会更加和平~
松宝,「松宝写代码」公众号作者,也用saucxs混迹于江湖,watermark-dom包700+ star,曾在ACM校队,在字节做AB实验,担任面试官,出校招编程题,爱好折腾,致力于全栈,喜欢挑战自己。公众号有精选文章,进阶学习,每日一题,实验室,AB实验,字节内推等模块,欢迎关注和咨询,和松宝一起写代码,冲冲冲!