一、理论
- 首先回顾以下正态分布、假设检验、置信区间:
- 若X~N( μ \mu μ, σ 2 \sigma^2 σ2), 那么均值 X ‾ \overline{X} X~N( μ \mu μ, σ 2 n \frac{\sigma^2}{n} nσ2), X ‾ − μ σ 2 n \frac{\overline{X}-\mu}{\sqrt{\frac{\sigma^2}{n}}} nσ2X−μ ~N(0,1)。
- 置信区间:若样本容量固定为n,假如对总体进行100次抽样,就得到了100个置信区间,这些区间有的包含 θ {\theta} θ的真实值,有的不包含。但假设置信度为1- α {\alpha} α=95%时,这100个区间中大约有95个区间包含了 θ \theta θ的真实值。(1%、5%、10%都是小概率事件,几乎不可能发生)
1、单样本假设检验:
- 例子:新上了一个策略,比如加入性别画像对用户的人均播放时长是否有正向影响。以往经验表明,人均播放时长1520s,标准差我70s,在该实验策略中,随机抽取了10000个用户进行测试,测得正常时间为1600s。在0.05的显著性水平下,判断该策略对人均播放时长是否有显著影响?
H0:有无策略没有显著性差异,即新策略的平均值=无策略的平均值1520
H0:u=1500,H1:u 不等于1520
在H0成立条件下, X ‾ − μ σ 2 n \frac{\overline{X}-\mu}{\sqrt{\frac{\sigma^2}{n}}} nσ2X−μ ~N(0,1),于是在 α \alpha α的显著性水平下,H0的拒绝域为:V={ X ‾ − μ σ 2 n > = z α 2 \frac{\overline{X}-\mu}{\sqrt{\frac{\sigma^2}{n}}}>=z_{\frac{\alpha}{2}} nσ2X−μ>=z2α}U{ X ‾ − μ σ 2 n < = − z α 2 \frac{\overline{X}-\mu}{\sqrt{\frac{\sigma^2}{n}}}<=-z_{\frac{\alpha}{2}} nσ2X−μ<=−z2α} (落在两边)由题意可知: σ \sigma σ=70,n=10000, x ‾ = 1600 \overline{x}=1600 x=1600, α = 0.05 \alpha=0.05 α=0.05, z α 2 = z 0 . 025 = 1.96 z_{\frac{\alpha}{2}}=z_0.025=1.96 z2α=z0.025=1.96,因为 X ‾ − μ σ 2 n \frac{\overline{X}-\mu}{\sqrt{\frac{\sigma^2}{n}}} nσ2X−μ=-8.48<-1.96,所以拒绝原假设H0。说明有无策略有显著差异。
2、双样本假设检验
如果检验来自两个两组平均数的差异性,从而判断它们各自代表的总体的差异是否显著。其Z值计算公式为:
二、python实现方法
某电商平台为了提升用户转化、带来更大收益,设计了新页面,希望通过A/B实验来评估新页面较旧页面对转化的优化效果,该项目的核心监控指标为转化率。
# 导包
import pandas as pd
import numpy as np
data = pd.read_csv('E:/a学习材料/excel +sql++/和鲸_ab测试.csv',sep=',')
data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 294478 entries, 0 to 294477
Data columns (total 5 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 user_id 294478 non-null int64 # 用户id
1 timestamp 294478 non-null object # 时间
2 group 294478 non-null object # 对照组(treatment)or实验组(control)
3 landing_page 294478 non-null object # 旧页面or新页面
4 converted 294478 non-null int64 # 是否转化
dtypes: int64(2), object(3)
memory usage: 11.2+ MB
# 重复值和异常值处理
data['user_id'].duplicated().sum() # 3894
dup=data.loc[data.user_id.duplicated(keep=False)].sort_values(by='user_id')
dup.head(4)
user_id timestamp group landing_page converted
230259 630052 2017-01-17 01:16:05.208766 treatment new_page 0
213114 630052 2017-01-07 12:25:54.089486 treatment old_page 1
22513 630126 2017-01-14 13:35:54.778695 treatment old_page 0
251762 630126 2017-01-19 17:16:00.280440 treatment new_page 0
# 可以看出,用户id重复的数据,landing_page的值不同,按照a/b实验的理论,group应和landing_page呈对应关系,即treatment--new_page,control--old_page,因此需删除不对应的数据。
data = data[((data['group']=='control') & (data['landing_page']=='old_page'))| ((data['group']=='treatment') & (data['landing_page']=='new_page'))]
data['user_id'].duplicated().sum() # 1
# 删完还存在一个重复值 我们看一下
data.loc[data.user_id.duplicated(keep=False)].sort_values(by='user_id')
user_id timestamp group landing_page converted
1899 773192 2017-01-09 05:37:58.781806 treatment new_page 0
2893 773192 2017-01-14 02:55:59.590927 treatment new_page 0
# 时间不一样, 留下最新日期的
data=data.drop(index=1899)
data.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 290584 entries, 0 to 294477
Data columns (total 5 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 user_id 290584 non-null int64
1 timestamp 290584 non-null object
2 group 290584 non-null object
3 landing_page 290584 non-null object
4 converted 290584 non-null int64
dtypes: int64(2), object(3)
memory usage: 13.3+ MB
数据处理完了,接下来可以正式进行A\B测试了
- 实验组(treatment)用户使用新页面,对照组(control)用户使用旧页面;假设旧页面转化率为p1,新页面转化率为p2。
- 1、首先进行原假设和备择假设的确定:
- 原假设:电商平台使用新页面不比旧页面带来的转化率好 H0:p1>=p2
- 备择假设:电商平台使用新页面比旧页面带来的转化率好 H1:p1< p2
- 2、确定检验类型及检验统计量: 由于样本量均大于30,因此选用z检验。
#对照组样本量
n1=data[data.group=='control'].shape[0]
#对照组样本量
n2=data[data.group=='treatment'].shape[0]
n1,n2 # (145274, 145310)
- 独立双样本,总体方差和均值未知,因此统计量z:p为转化率,pc为联合转化率即全部的转化率
- 3、z检验
# 对照组和实验组样本量
n_old=data[data.group=='control'].shape[0] # 145274
n_new=data[data.group=='treatment'].shape[0] # 145310
# 对照组和实验组转化量
convert_old = data.query('group=="control" & converted==1').shape[0] # 17489
convert_new = data.query('group=="treatment" & converted==1').shape[0] # 17872
# 旧版、新版转化率
p_old = convert_old / n_old # 0.120386
p_new = convert_new / n_new # 0.122992
print(f'对照组(旧页面)样本量:{n_old},转化量:{convert_old},转化率:{p_old}')
print(f'实验组(新页面)样本量:{n_new},转化量:{convert_new},转化率:{p_new}')
import statsmodels.stats.proportion as sp
# alternative='smaller'代表左尾 p1<p2
z_score, p_value = sp.proportions_ztest([convert_old, convert_new], [n_old, n_new], alternative='smaller')
print('检验统计量z:', z_score, ',p值:', p_value)
#p值为0.016,小于0.05,因此拒绝原假设,新页面的转化率好于旧页面;达到了优化目的。