0
点赞
收藏
分享

微信扫一扫

AB test之必知必会

古月无语 2022-04-14 阅读 111
ab测试

文章目录

1. A/B测试的基础知识

1.1 总体流程

标准的ab实验在数据层面至少要有两个对照组,一个实验组,因此至少要拿来自三个分流的实验数据进行分析
对两个对照组做aa实验,若不显著进行3,否则可能是实验层面出现问题,可以修改实验或者选择做did分析
任取一个对照组和实验组做ab实验
在这里插入图片描述

1.2 数据准备

  • 实验至少要有3个分流池,两个base组,一个exp组;
  • 一个user一条数据,包括组label,user_id,对比的y变量(因变量),y变量可以取周期内的该用户的日均值;
  • 如果base组和实验组数据量过大,可以随机采样;如果还要做交互项分析,随机采样时可以根据交互项groupby采样。

1.3 aa实验

当我们在实验评估系统上开启一个实验组和对照组配置一摸一样的实验时,我们称之为aa实验。aa实验是保证ab实验可靠性的前提,aa实验通常用来辅助观察指标在产品不做改变时的偏差范围。我们通常会在实验里加一个和对照组一模一样的base组来观察这个偏差,而如果这个偏差很大,通常ab实验也容易结果不置信。

aa实验显著差异的原因:

  1. 统计层面:一般样本较少时候容易出现,即容易出现数据波动,解决方法:扩量、去掉异常数据;
  2. 埋点层面:埋点侧出现问题,导致实验数据异常;
  3. 实验层面:比如实验重叠导致的base组之间配置不相等;滞后效应导致的base组还在受上一个实验的后续影响等等,解决方案:需要重新设计实验

aa实验检验方法:独立样本t检验

1.4 ab实验

如果aa实验得到结论为不显著,那么我们就可以放心的进行这一步的ab实验了,ab实验是假设base组和exp组无显著差异,并做检验的假设实验,零假设为无显著差异,备选假设为有显著差异,最后根据接受零假设的概率p值来确定结果。我们做ab实验的时候主要分两步计算:

  1. 通过独立样本t检验,计算base组合exp组之间是否存在显著差异。如果差异不显著,则证明实验组的策略没有带来显著变化,则实验结束;如果差异显著,说明实验组策略有一定效果,至于是正向效果还是负向效果还要进行下一步计算。
  2. 如果差异显著,那么说明得到的p值<0.05,那么我们可以进一步分析政策的影响是正向还是负向,变化量为多大。可以通过对y变量做回归的方式得到X为实验组的时候与X为对照组的差异,对y取log再做回归可以得到差异的百分比;除了回归也可以直接对比两组之间y的总体均值进行分析。

1.5 独立样本t检验

独立样本t检验是t检验的一种,一般的总体标准差未知且满足正态分布,或者近似于正态分布的总体数据都可以用t检验。ab实验中,由于base组和exp组都是随机分流,是独立样本,并且是对比两个样本之间的差异显著性,因此适用独立样本t检验,业界内,大部分ab实验都采用了独立样本t检验进行差异显著性假设检验。

t值和自由度d.f.的计算方法:

  • 方差齐性检验不显著差异:
    在这里插入图片描述

根据计算出的t值和自由度,可以在t值边界表中查询到p值得大小,进而得到差异显著性。

  • 方差齐性检验显著差异:
    在这里插入图片描述
    如果方差齐性检验显著差异,则t检验变为修正的Welch’s t-test,t值的计算和自由度的计算如上所述。

1.6 简单的ab实验代码

数据源截图:
在这里插入图片描述
基础AB实验案例:

#导入路径内的DID包和需要的pandas包
import sys
sys.path.append('/home/public/benyuansong')
from DID import preprocessing
from DID import ttest
import pandas as pd       
                             
#读取分析文件
file = pd.read_csv('文件path')   
                          
#对file进行预处理,参数从左到右依次为dataframe数据、分析的y变量、组别字段名、user字段名、group_name字段中base组的值(因为至少有两个base组,所以是列表形式表示)、group_name中exp组的值
# 此预处理一个目的是面板数据转化为用户粒度的截面聚合数据;
# 再一个目的是处理缺失值。如果这两组已经满足,则可以不用做预处理,直接做后面的ttest。
base1,base2,exp = preprocessing.ttest_preprocessing(file, 'A', treatment_col = 		'group_name', name_col = 'user_id',basename=['base','base1'],expname='exp')

# 打印ttest结果,包括差异是否显著,如果显著,那么差异是多少(base-base1)。
# 参数从左到右依次为:base1数据源、base2数据源、exp数据源、分析的y变量
ttest.ttest(base,base1,exp,'A')

结果示例:
A: ab_pvalue:0.0,difference(exp-base):0.007144186774656516,Percentage of increase:7.96%
结果解读:因为pvalue为0,因此相对于base组,实验组的A指标显著增长0.007,相对显著提升7.96%

2. A/B测试的进阶教程

低渗透率:一般指分流实验后,实验组中的策略影响的user只有很小的一部分比例,比如说实验组中开放了一个新功能,而通过接口使用功能的人只是很小一部分,那么往往不会很大程度影响大盘的变化,导致整体上做ab实验得到的结果差异一般都是不显著的,无法客观评价产品功能上或者策略的好坏,仅仅有可能是入口做的糟糕,所以我们这里需要一些方法可以评价使用产品或者策略的用户与其他用户的对比,从而得到渗透率低的情况的分析结果。

解决思路:筛选使用功能的人,看一下他们的分布情况,如果依然符合正态分布或者近似正态分布,那么可以接着用ab实验的方法,即实验组筛选使用功能的人,两个base组做一下随机采样,按照前面提到的ab实验标准流程作分析即可。

如果使用功能的人不符合正态分布,那么我们需要进行matching,通过匹配控制变量,从base组中找到与使用功能相似的人,然后进行did分析。

2.1 split sample

split sample实现的是相当于一个filter的作用,ab实验除了分析总体的变化情况,我们可能也会关心不同的群体有什么影响,这就是交互项分析回答的问题。举个例子,主播连麦功能实验中,a是开放功能的样本,b是为开放功能的群体,那么除了前面基础分析中,我们得到的总体的差异,我们还想得知:男主播开放功能会有什么影响、年纪较大的主播开放功能会有什么影响、粉丝量比较少的主播开放功能会有什么影响等等。这个就是通过split sample的方式进行分析,顾名思义就是通过划分筛选样本的方式来计算子样本的t检验。

causal inference package中的实现——class filter
工具包中可以通过filter类中的filter_ttest函数来进行分析,这其中filter类可以支持多种方式的筛选,比如

  1. filter=‘gender’:代表既要看男性的变化影响,又要看女性的变化影响。
  2. filter=[‘gender’,‘age’,‘fans_range’]:先后分别查看性别、年龄以及粉丝范围带来的影响。
  3. filter={‘gender’:‘F’,‘age’:‘18-23’,‘fans_range’:‘1w+’}:以字典形式给出时,代表这三个条件同时满足的群体开放功能有什么影响。

代码示例

import sys
sys.path.append('/home/public/benyuansong')
from DID import preprocessing
import pandas as pd
from DID import filter
    
#读取数据
file = pd.read_csv('文件path')
  
#数据预处理
base1,base2,exp = preprocessing.ttest_preprocessing(file,'total_watching_duration', treatment_col = 'treatment', name_col = 'user_id',basename=['base1','base2'],expname='exp1')
  
#自定义filter
myfilter = filter('gender')
  
#输出各个base组与实验组的filter后的sample size
filter.filter_sample_size(base1,myfilter)
filter.filter_sample_size(base2,myfilter)
filter.filter_sample_size(exp,myfilter)
  
#输出filter后的交互项分析
filter.filter_ttest(base1,base2,exp,myfilter,'total_watching_duration')

2.2 交互项interaction

跟split sample不同,interaction分析的是不同群体之间的差异,打个比方split sample是开发功能后,男性的差异变化;而interaction分析的是开放功能后,男性相对于女性的差异变化。split sample就是根据简单的样本筛选后再做基础分析得到;而interaction需要用到交互项回归,具体原理如下:

假设我们分析的变化量为y,X为组别差距即treatment,在ab实验中,令X=1为exp组,X=0为base组,那么根据最小二乘法ols线性回归,可以做如下回归,其中a为自变量的系数,b为截距,a就是反应变化量的parameter,则 y = a X + b y = aX+b y=aX+b

而如果我们加入交互项,比如说female,那么female=1代表是女性,female=0代表不是女性(在gender没有’未知’的值的情况下,就代表是男性),那么回归变为如下表示,这里c就是我们要求的系数,d是截距,则 y = a X + b f e m a l e + c X ∗ f e m a l e + d y = aX+bfemale+cX*female+d y=aX+bfemale+cXfemale+d
原因如下面的矩阵表示:

treatment=1treatment=0
female=1 a + b + c + d a+b+c+d a+b+c+d b + d b+d b+d
female=0 a + d a+d a+d d d d

interaction想求得就是开放功能后,女性相对于男性的变化量的差距,即 ( ( a + b + c + d ) − ( b + d ) ) − ( ( a + d ) − d ) = c ((a+b+c+d)-(b+d))-((a+d)-d)=c ((a+b+c+d)(b+d))((a+d)d)=c

用案例来说明:即开放连麦功能后,女性开播时长提升5% 男性提升10%,那么交互项得到的就是: 相对于男性,女性提升-5%

import sys
sys.path.append('/home/public/benyuansong')
from DID import preprocessing
import pandas as pd
from DID import ttest
 
#读取数据
file = pd.read_csv('文件path')
 
#数据预处理
base1,base2,exp = preprocessing.ttest_preprocessing(file, 'total_watching_duration', treatment_col = 'treatment', name_col = 'user_id',basename=['base1','base2'],expname='exp1')
 
#交互项分析,第4个参数只支持字典,代表交互项的选择,method='log',返回变化百分比,默认是None,返回变化绝对值
ttest.inter_ttest(base1,exp,'total_watching_duration',{'gender':'F'},method=None)

结果示例:
gender id F: param is -300.2654, p_value is 0.92768654

解读:表示的是相对于M, F的指标降低了300.2654, 而由于p_value是0.9>0.05,因此差异不显著。

举报

相关推荐

0 条评论