A/B测试应用场景:在网站和APP的设计、产品的运营中,经常会面临多个设计/运营方案的选择。小到按钮的位置、文案的内容、主题的颜色,再到注册表单的设计、不同的运营方案,都有不同的选择。A/B test可以帮助我们做出选择,消除客户体验(UX)设计中不同意见的争执。
A/B测试原理:类似于初中生物说的对照试验。对用户分组,每个组使用一个方案(方案应遵从单变量前提),在相同的时间维度上去观察用户的反应(体现在业务数据和用户体验数据上)。需要注意的是各个用户群组的组成成分应当尽量相似,譬如新老用户很有可能表现出较大的偏好差异。最后根据假设检验的结果,判断哪些版本较之原版有统计意义上的差异,并根据效应量选出其中表现最好的版本。
本项目背景:以支付宝营销活动为例,通过广告点击率指标比较两组营销策略的广告投放效果
2.数据集来源数据集来源于阿里云天池:数据集-阿里云天池
3.数据集介绍数据集包含三张表:
emb_tb_2.csv: 用户特征数据集effect_tb.csv: 广告点击情况数据集seed_cand_tb.csv: 用户类型数据集
主要使用广告点击情况数据,字段如下:
dmp_id:营销策略编号(1:对照组,2:营销策略一,3:营销策略二)user_id:支付宝用户IDlabel:用户当天是否点击活动广告(0:未点击,1:点击) 二、数据清洗和处理 1.数据清洗
import pandas as pd import numpy as np import matplotlib.pyplot as plt %matplotlib inline
导入数据
data=pd.read_csv('effect_tb.csv',header=None)
data.head()
设置行索引名称,并清除有问题的列
data.columns=['dt','user_id','label','dump_id'] data=data.drop(columns='dt') data.head()
数据描述性统计
data.describe()
重复值处理
data.shape data.nunique() #检查重复数据 data[data.duplicated(keep=False)].sort_values(by=['user_id']) #删除重复值 data=data.drop_duplicates() data[data.duplicated(keep=False)]
缺失值处理-无缺失值
data.info(null_counts=True)
异常值处理-无异常值
#数据透视表
data.pivot_table(index='dump_id',columns='label',values='user_id',
aggfunc='count',margins=True)
数据类型转换-无需转换
data.dtypes
2.样本容量检验
在进行A/B测试前,需检查样本容量是否满足试验所需最小值。这里借助Evan Miller的样本量计算工具:Sample Size Calculator (Evan’s Awesome A/B Tools)
设置广告投放效果的最小提升比例,将对照组的点击率设为基准线
#对照组点击率计算 data[data['dump_id']==1]['label'].mean()
0.012551012429794775
分析:
对照组点击率为1.26%,假定我们希望新的营销策略能让广告点击率至少提升1个百分点,则算得所需最小样本量为:2167。
#不同策略组的样本量统计 data['dump_id'].value_counts()
1 1905663 2 411107 3 316205 Name: dump_id, dtype: int64
分析:
两组营销活动的样本量分别为41.11万和31.62万,满足最小样本量需求。 3.保存数据结果
data.to_csv('data_output.csv')
三、假设检验过程
1.观察三组数据的点击率情况
print("对照组的点击率为:",data[data['dump_id']==1]["label"].mean())
print("策略组一的点击率为:",data[data['dump_id']==2]['label'].mean())
print("策略组二的点击率为:",data[data['dump_id']==3]['label'].mean())
对照组的点击率为: 0.012551012429794775 策略组一的点击率为: 0.015314747742072015 策略组二的点击率为: 0.026191869198779274
分析:策略一提升0.2个百分点,策略二提升1.3个百分点,只有策略二满足了前面我们对点击率提升最小值的要求。
2.零假设和备择假设记对照组点击率为p1,策略二点击率为p2,则:
零假设 H0: p1 ≥ p2备择假设 H1: p1 < p2
3.分布类型,检验类型和显著性水平确定
样本服从二点分布,独立双样本,样本大小n>30,总体均值和标准差未知,根据中心极限定理,样本量足够大时,总体方差可以看成样本方差值,所以可采用Z检验。显著性水平α取0.05。
4.验证过程一:公式计算
# 用户数
n_old = len(data[data.dump_id == 1]) # 对照组
n_new = len(data[data.dump_id == 3]) # 策略二
# 点击数
c_old = len(data[data.dump_id ==1][data.label == 1])
c_new = len(data[data.dump_id ==3][data.label == 1])
# 计算点击率
r_old = c_old / n_old
r_new = c_new / n_new
# 总和点击率
r = (c_old + c_new) / (n_old + n_new)
print("总和点击率:", r)
总和点击率: 0.014492310074225832
# 计算检验统计量z
z = (r_old - r_new) / np.sqrt(r * (1 - r)*(1/n_old + 1/n_new))
print("检验统计量z:", z)
检验统计量z: -59.44168632985996
# 查α=0.05对应的z分位数
from scipy.stats import norm
z_α = norm.ppf(0.05)
z_α
-1.6448536269514729
# 用户数 n_old = len(data[data.dump_id == 1]) # 对照组 n_new = len(data[data.dump_id == 3]) # 策略二
# 点击数 c_old = len(data[data.dump_id ==1][data.label == 1]) c_new = len(data[data.dump_id ==3][data.label == 1])
# 计算点击率 r_old = c_old / n_old r_new = c_new / n_new
# 总和点击率
r = (c_old + c_new) / (n_old + n_new)
print("总和点击率:", r)
# 计算检验统计量z
z = (r_old - r_new) / np.sqrt(r * (1 - r)*(1/n_old + 1/n_new))
print("检验统计量z:", z)
# 查α=0.05对应的z分位数 from scipy.stats import norm z_α = norm.ppf(0.05) z_α
分析:
z_α = -1.64, 检验统计量z = -59.44,该检验为左侧单尾检验,拒绝域为{z<z_α}。
我们可以得出结论:原假设不成立,策略二点击率的提升在统计上是显著的。
5.验证过程二:Python计算
import statsmodels.stats.proportion as sp
z_score,p=sp.proportions_ztest([c_old,c_new],[n_old,n_new],alternative='smaller')
print("检验统计量z:",z_score,",P值为",p)
检验统计量z: -59.44168632985996 ,P值为 0.0
import statsmodels.stats.proportion as sp
z_score,p=sp.proportions_ztest([c_old,c_new],[n_old,n_new],alternative='smaller')
print("检验统计量z:",z_score,",P值为",p)
p值约等于0,p < α,与方法一结论相同,拒绝原假设。
检查策略一点击率是否提升
c_new2=len(data[data.dump_id ==2][data.label == 1])
n_new2=len(data[data.dump_id == 2])
z_score, p = sp.proportions_ztest([c_old,c_new2] ,[n_old,n_new2 ], alternative = "smaller")
print("检验统计量z:",z_score,",p值:", p)
检验统计量z: -14.165873564308429 ,p值: 7.450121742737582e-46
c_new2=len(data[data.dump_id ==2][data.label == 1])
n_new2=len(data[data.dump_id == 2])
z_score, p = sp.proportions_ztest([c_old,c_new2] ,[n_old,n_new2 ], alternative = "smaller")
print("检验统计量z:",z_score,",p值:", p)
p值约等于7.45e-46,p < α,但因为前面我们设置了对点击率提升的最小值要求,这里仍只选择第二组策略进行推广。 五、结论
两种营销策略中,策略二对广告点击率有显著提升效果,且相较于对照组点击率提升了近一倍,因而在两组营销策略中应选择第二组进行推广。



