利用python进行A/B测试

A/B测试常用于对某个改进产生效果的评估,比如用于测试网页修改效果。A/B测试其实是一场实验,实验中分为对照组实验组。实验组是进行了某项操作的实验结果,而对照组除了没有进行该项操作外,其余的条件都和实验组相同。通过这样的设置就可以控制其他因素不变,而只关注想要验证的因素。
A/B测试的原理,来源于假设检验,大家可以看看我前面《一文详解假设检验、两类错误和p值》这篇文章了解假设检验的概念,另外《利用python进行假设假设检验》这篇文章介绍了怎么用python进行假设检验。这篇文章主要是介绍如何利用python进行A/B测试。具体的原理和python实现的细节可以参考我前面的两篇文章,接下来我会直接展示过程和结果。所使用的数据是电子商务公司设计了新网站页面,想提高用户转化率,得到的实验数据。我们的分析目标是决定是否应该使用新页面,也就是新页面是否带来了更高的用户转化。

1.数据介绍和处理

首先,我们导入相应的包和数据:


import pandas as pd
import numpy as np
import random
import matplotlib.pyplot as plt
%matplotlib inline
random.seed(42)

导入数据:


df=pd.read_csv('ab_data.csv')
df.head()

在这里插入图片描述
数据中包含用户的身份id、所属组别和是否成功转化等信息。由于不能100%保证实验用户是否真正接受到了新页面或者旧页面。我们可以通过查看group和landing_page是否一致来辨别。代码如下:

df[((df['group'] == 'treatment') == (df['landing_page'] == 'new_page')) == False].shape[0]

在这里插入图片描述
说明这种情况是存在的。所以接下来要帅选数据,只选取group和landing_page相一致的数据,代码如下:

df1=df.query('group=="control"').query('landing_page=="old_page"') 
df2=df1.append(df.query('group=="treatment"').query('landing_page=="new_page"'))

我们验证一下效果:

df2[((df2['group'] == 'treatment') == (df2['landing_page'] == 'new_page')) == False].shape[0]

在这里插入图片描述
结果为0,说明新的数据中已经不存在不一致的情况。接下来,我们分别计算一下,总体的转化率、控制组的转化率和实验组的转化率。

float(df2.query('converted==1')['user_id'].count())/float(df2['user_id'].count())

总体转化率的结果为:
0.11959708724499628


float(df2.query('group=="control"').query('converted==1')['user_id'].count())/float(df2.query('group=="control"')['user_id'].count())

控制组的转化率为:0.1203863045004612


float(df2.query('group=="treatment"').query('converted==1')['user_id'].count())/float(df2.query('group=="treatment"')['user_id'].count())

实验组的转化率为:
0.11880806551510564
从着三组的转化率来看,差别不是很大。

2.A/B测试

A/B测试的原理来源于假设检验,在本例中验证的是实验组和控制组的转化率是否相等。那么我们可以设置假设为:

H0: p_old =p_new
H1: p_old < p_new

当H0为真的情况下,实验组和控制组的转化率相等,等于总体的转化率。我们可以计算:

float(df2.query('converted==1').count()[0])/float(df2.count()[0])

值为::
0.11959708724499628
统计数据中控制组和实验组的样本量n_new和n_old:

:
df2.query('landing_page=="new_page"').count()[0]

df2.query('landing_page=="old_page"').count()[0]

n_new=145310, n_old=145274
接着我们模拟在零假设成立下,即p_new=p_old=0.1196,两样本转化率差的分布:

p_diffs=[]
for _ in range(10000):
    new_page_converted=np.random.choice([0,1],size=145310,p=[0.8804,0.1196]).mean()
    old_page_converted=np.random.choice([0,1],size=145274,p=[0.8804,0.1196]).mean()
    p_diffs.append(new_page_converted-old_page_converted)

绘制p_diffs的直方图如下:

plt.hist(p_diffs)

在这里插入图片描述
下面我们计算零假设成立下的P值,也就p_diffs的数值中,有多大比例大于 样本中观察到的实际差值。关于p值为什么是这样计算的,可以参考《利用python进行假设假设检验》

real_new_page_converted=float(df2.query('landing_page=="new_page"').query('converted==1').count()[0])/float(df2.query('landing_page=="new_page"').count()[0])  #计算样本中实验组的实际转化率
real_old_page_converted=float(df2.query('landing_page=="old_page"').query('converted==1').count()[0])/float(df2.query('landing_page=="old_page"').count()[0])   #计算样本中控制组的实际转化率
real_converted=real_new_page_converted-real_old_page_converted    #计算样本中实验组和控制组的实际转化率差值
p_diffs=np.array(p_diffs)     #转化成ndarray
(p_diffs>real_converted).mean()  #计算p值,也就是p_diffs中大于实际转化率的差值的比例

在这里插入图片描述
这个p值足够大,所以我们无法拒绝原假设。我们倾向于认为新的页面没有带来转化率的提升。另外我们也可以使用python的内置包来计算p值,代码如下:

import statsmodels.api as sm
convert_old = df2.query('landing_page=="old_page"').query('converted==1').count()[0]
convert_new = df2.query('landing_page=="new_page"').query('converted==1').count()[0]
n_old = df2.query('landing_page=="old_page"').count()[0]
n_new = df2.query('landing_page=="new_page"').count()[0
z_score, p_value = sm.stats.proportions_ztest([convert_old, convert_new], [n_old, n_new],alternative='smaller')
from scipy.stats import norm
norm.cdf(z_score)
z_score,norm.ppf(1-0.05),p_value

在这里插入图片描述
可以看到,z-score为1.31092,小于标准正太分布下的值1.6449,所以我们无法接受零假设,我们倾向于认为新页面没有带来转化率的提升。结果与上部分得出的结论一样,另外这里计算的p值和上一步计算的p值很相近。

  • 4
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值