AB测试实战(二)

简介: AB测试是一种数据驱动的产品优化方法,用于比较不同版本的网页、应用界面或营销策略的效果。

AB测试实战(一)+https://developer.aliyun.com/article/1544766?spm=a2c6h.13148508.setting.14.22454f0eHFZZj3


3、AB测试代码实战

3.1 项目背景


UI设计师设计了最新的产品页面想通过页面更新提高转化率


  • 目前的转化率全年平均在13%左右


  • 目标转化率达到 15%。


  • 在新的页面上线之前,我们要通过一小部分用户上测试页面的效果, 所以需要进行A/B测试

3.2 设计实验


  • 提出假设


首先,我们要确保在项目开始时就制定了一个假设


鉴于我们不知道新设计的性能是否会比我们当前的设计更好或更差(或相同?),我们将选择双尾测试:


H 0 原假设 老的设计比较好, 新版设计没有用


H 1 备选假设 新的设计比较好


  • 选择变量


对照组: 看到旧的设计

实验组: 看到新的设计


虽然我们已经知道了旧的设计的转化率(13%左右), 但是我们依然要需要设计两组, 原因是为了避免其他因素带来的误差, 比如季节因素, 促销因素。这两组人在其它条件都相同的只是页面设计不同的情况下进行实验, 这样能保证两组间的差异是由于设计导致的


我们的设计的目标KPI是转化率, 所以,我们会添加一个字段来记录用户的购买情况


购买了产品的用户 值为1

未购买产品的用户值为0


  • 确定实验人数


AB测试只会选择一小部分用户来参与实验, 用小部分的实验结果来估计整体的结果,每组的人数越多,我们得到的结果就越精准,但同时我们付出的成本就越大,通过功效分析我们可以计算出满足实验条件的最小人群


检验功效 (1 — β) :一般设置为0.8


α :在设计实验的时候我们设置为0.05


效果大小:旧的页面转化率为13%,新页面我们希望转化率能提升2%,所以我们可以用13%和15%来计算预期效果大小


确定实验人数的计算过程可以通过Python代码实现


import numpy as np
import pandas as pd
import scipy.stats as stats
import statsmodels.stats.api as sms
import matplotlib as mpl
import matplotlib.pyplot as plt
import seaborn as sns
from math import ceil

%matplotlib inline


effect_size = sms.proportion_effectsize(0.13, 0.15)   

required_n = sms.NormalIndPower().solve_power(
    effect_size,
    power=0.8, 
    alpha=0.05, 
    ratio=1  
    )                                                  
#对结果向上取整
required_n = ceil(required_n)                         

print(required_n)


4720


  • 计算结果说明每组至少需要4720人
  • 在实践中将功率参数设置为 0.8 意味着如果我们的设计之间存在转化率的实际差异,假设差异是我们估计的差异(13% 对 15%),我们有大约 80% 的机会检测到它 与我们计算的样本量在我们的测试中具有统计显着性。


3.3 收集准备数据


  • 在企业场景下,我们需要与工程团队配合,收集满足要求的数据, 这里我们使用准备好的数据集, 对数据进行处理
  • 加载数据到DataFrame
  • 检查和清理数据
  • 从DataFrame中采样数据每组4720行


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



user_id
timestamp group landing_page converted
0 851104 2017-01-21 22:11:48.556739 control old_page 0
1 804228 2017-01-12 08:01:45.159739 control old_page 0
2 661590 2017-01-11 16:55:06.154213 treatment new_page 0
3 853541 2017-01-08 18:28:03.143765 treatment new_page 0
4 864975 2017-01-21 01:52:26.210827 control old_page 1


  • 查看数据基本情况


df.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 
 1   timestamp     294478 non-null  object
 2   group         294478 non-null  object
 3   landing_page  294478 non-null  object
 4   converted     294478 non-null  int64 
dtypes: int64(2), object(3)
memory usage: 11.2+ MB


数据一共294478行,每一条数据代表一次用户访问,共五列:


  • user_id - 访问的用户ID
  • timestamp - 访问的时间
  • group - 该用户被放到那一组 {control对照, treatment实验}
  • landing_page -该用户看到的是哪一种落地页 {old_page老页面, new_page新页面}
  • converted - 改次访问是否有转化 (binary, 0=无转化, 1=转化)


在后续的分析中,我们实际上主要用到的是 group 和converted 这两个字段


创建透视表, 查询是否对照组看到的都是老页面


df.pivot_table(index = 'group',columns='landing_page',values = 'user_id',aggfunc='count')


anding_page new_page old_page
group
control 1928 145274
treatment 145311 1965


  • 在我们进行后续处理之前, 还要查看是否有用户进行了多次操作


session_counts = df['user_id'].value_counts(ascending=False)
multi_users = session_counts[session_counts>1].count()
multi_users


3894


  • 说明一共有3894个用户访问了不止一次, 整体数据有20多万条, 所以我们直接把这部分数据删除


users = session_counts[session_counts < 2].index
df = df[df['user_id'].isin(users)]


数据采样


  • 接下来我们从处理后的数据中,每组采样4720条数据, 我们这里使用DataFrame的sample()方法进行简单随机采样


control_sample = df[df['group'] == 'control'].sample(n=required_n, random_state=22)
treatment_sample = df[df['group'] == 'treatment'].sample(n=required_n, random_state=22)
# 这里random_state 为随机数种子, 如果也传入22, 那么后续结果会与讲义中一样
ab_test = pd.concat([control_sample, treatment_sample], axis=0)
ab_test.reset_index(drop=True, inplace=True)
ab_test



user_id
timestamp group landing_page converted
user_id
group landing_page converted
0 763854 2017-01-21 03:43:17.188315 control old_page 0 0




1 690555 2017-01-18 06:38:13.079449 control old_page 0 1




2 861520 2017-01-06 21:13:40.044766 control old_page 0 2




3 630778 2017-01-05 16:42:36.995204 control old_page 0 3




4 656634 2017-01-04 15:31:21.676130 control old_page 0 4







9435 908512 2017-01-14 22:02:29.922674 treatment new_page 0 9435




9436 873211 2017-01-05 00:57:16.167151 treatment new_page 0 9436




9437 631276 2017-01-20 18:56:58.167809 treatment new_page 0 9437




9438 662301 2017-01-03 08:10:57.768806 treatment new_page 0 9438




9439 944623 2017-01-19 10:56:01.648653 treatment new_page 1 9439





  • 查看两组数据情况


ab_test.groupby('group')['landing_page'].value_counts()
# landing_page 落地页类型  old_page老页面 new_page 新页面
# control 控制组  treatment 对照组


group landing_page

control old_page 4720

treatment new_page 4720

Name: landing_page, dtype: int64


3.4 分析实验结果


  • 首先我们来计算一下两组的转化率和标准差


conversion_rates = ab_test.groupby('group')['converted'].mean().to_frame()
conversion_rates 

conversion_rates.style.format('{:.3f}')


group conversion_rate
control 0.123
treatment 0.126


  • 从上面的统计数据来看,旧的和新的落地页表现非常相似,新设计表现略好, 12.3% 与 12.6%


  • 从对照组的数据看, 转换率为12.3% 比之前我们的整体表现要差一些, 可能与采样人群的差异有关
  • 测试组的数据比对照组要好一些, 但是这个结果是否具有统计意义?


3.5 假设检验


  • 最后一步是假设检验, 我们的样本量比较大,可以应用Z检验来计算P值, 如果P值<0.05, 说明
  • 我们可以使用statsmodels.stats.proportion 模块来计算P值和置信区间


from statsmodels.stats.proportion import proportions_ztest, proportion_confint
control_results = ab_test[ab_test['group'] == 'control']['converted']     #获取对照组是否转化的数据
treatment_results = ab_test[ab_test['group'] == 'treatment']['converted'] #获取实验组是否转化的数据
n_con = control_results.count() # 获取对照组人数
n_treat = treatment_results.count()  # 获取实验组人数
successes = [control_results.sum(), treatment_results.sum()] # 获取实验组和对照组成功转化的人数
nobs = [n_con, n_treat]

z_stat, pval = proportions_ztest(successes, nobs=nobs)  #计算P值
(lower_con, lower_treat), (upper_con, upper_treat) = proportion_confint(successes, nobs=nobs, alpha=0.05) #计算置信区间

print(f'z statistic: {z_stat:.2f}')
print(f'p-value: {pval:.3f}')
print(f'ci 95% for control group: [{lower_con:.3f}, {upper_con:.3f}]')
print(f'ci 95% for treatment group: [{lower_treat:.3f}, {upper_treat:.3f}]')


🥂小结


AB测试的应用场景


  • 互联网行业应用广泛:页面结构调整, 换新图标,添加新功能等等
  • 实体行业应用相对复杂一些:不同优惠券效果测试


AB测试还是ABC测试


  • AB测试:一次测试一个方案
  • ABC…… 测试: 一次测试多个方案,但需要流量足够大,否则难以满足实验要求的最少人数


AB测试需要注意如下几点


  • 流量分配


  • 确定有效的最小参与人数
  • 确定基准指标和提升目标
  • 设置显著性水平α (一般是5%)和 统计功效 1-β (一般是80%)
  • 出结果之后计算P值 如果P<5% 则可以拒绝原假设算P值 如果P<5% 则可以拒绝原假设
  • 我们可以通过AB测试工具网站帮助确定人数,也可以使用statsmodels 模块来通过代码实现


  • import statsmodels.stats.api 计算需要人数
  • statsmodels.stats.proportion 计算P值和置信区间


相关文章
|
10天前
|
JSON Java 测试技术
SpringCloud2023实战之接口服务测试工具SpringBootTest
SpringBootTest同时集成了JUnit Jupiter、AssertJ、Hamcrest测试辅助库,使得更容易编写但愿测试代码。
42 3
|
15天前
|
缓存 测试技术 Apache
告别卡顿!Python性能测试实战教程,JMeter&Locust带你秒懂性能优化💡
告别卡顿!Python性能测试实战教程,JMeter&Locust带你秒懂性能优化💡
31 1
|
1月前
|
机器学习/深度学习 编解码 监控
目标检测实战(六): 使用YOLOv8完成对图像的目标检测任务(从数据准备到训练测试部署的完整流程)
这篇文章详细介绍了如何使用YOLOv8进行目标检测任务,包括环境搭建、数据准备、模型训练、验证测试以及模型转换等完整流程。
1327 1
目标检测实战(六): 使用YOLOv8完成对图像的目标检测任务(从数据准备到训练测试部署的完整流程)
|
19天前
|
前端开发 数据管理 测试技术
前端自动化测试:Jest与Cypress的实战应用与最佳实践
【10月更文挑战第27天】本文介绍了前端自动化测试中Jest和Cypress的实战应用与最佳实践。Jest适合React应用的单元测试和快照测试,Cypress则擅长端到端测试,模拟用户交互。通过结合使用这两种工具,可以有效提升代码质量和开发效率。最佳实践包括单元测试与集成测试结合、快照测试、并行执行、代码覆盖率分析、测试环境管理和测试数据管理。
35 2
|
20天前
|
前端开发 JavaScript 数据可视化
前端自动化测试:Jest与Cypress的实战应用与最佳实践
【10月更文挑战第26天】前端自动化测试在现代软件开发中至关重要,Jest和Cypress分别是单元测试和端到端测试的流行工具。本文通过解答一系列问题,介绍Jest与Cypress的实战应用与最佳实践,帮助开发者提高测试效率和代码质量。
30 2
|
1月前
|
机器学习/深度学习 监控 计算机视觉
目标检测实战(八): 使用YOLOv7完成对图像的目标检测任务(从数据准备到训练测试部署的完整流程)
本文介绍了如何使用YOLOv7进行目标检测,包括环境搭建、数据集准备、模型训练、验证、测试以及常见错误的解决方法。YOLOv7以其高效性能和准确率在目标检测领域受到关注,适用于自动驾驶、安防监控等场景。文中提供了源码和论文链接,以及详细的步骤说明,适合深度学习实践者参考。
332 0
目标检测实战(八): 使用YOLOv7完成对图像的目标检测任务(从数据准备到训练测试部署的完整流程)
|
1月前
|
机器学习/深度学习 XML 并行计算
目标检测实战(七): 使用YOLOX完成对图像的目标检测任务(从数据准备到训练测试部署的完整流程)
这篇文章介绍了如何使用YOLOX完成图像目标检测任务的完整流程,包括数据准备、模型训练、验证和测试。
166 0
目标检测实战(七): 使用YOLOX完成对图像的目标检测任务(从数据准备到训练测试部署的完整流程)
|
1月前
|
机器学习/深度学习 算法 PyTorch
目标检测实战(五): 使用YOLOv5-7.0版本对图像进行目标检测完整版(从自定义数据集到测试验证的完整流程)
本文详细介绍了使用YOLOv5-7.0版本进行目标检测的完整流程,包括算法介绍、环境搭建、数据集准备、模型训练、验证、测试以及评价指标。YOLOv5以其高精度、快速度和模型小尺寸在计算机视觉领域受到广泛应用。
463 0
目标检测实战(五): 使用YOLOv5-7.0版本对图像进行目标检测完整版(从自定义数据集到测试验证的完整流程)
|
1月前
|
缓存 数据挖掘 测试技术
目标检测实战(三):YOLO-Nano训练、测试、验证详细步骤
本文介绍了YOLO-Nano在目标检测中的训练、测试及验证步骤。YOLO-Nano是一个轻量级目标检测模型,使用ShuffleNet-v2作为主干网络,结合FPN+PAN特征金字塔和NanoDet的检测头。文章详细说明了训练前的准备、源代码下载、数据集准备、参数调整、模型测试、FPS测试、VOC-map测试、模型训练、模型测试和验证等步骤,旨在帮助开发者高效实现目标检测任务。
45 0
目标检测实战(三):YOLO-Nano训练、测试、验证详细步骤
|
1月前
|
计算机视觉 异构计算
目标检测实战(四):YOLOV4-Tiny 源码训练、测试、验证详细步骤
这篇文章详细介绍了使用YOLOv4-Tiny进行目标检测的实战步骤,包括下载源码和权重文件、配置编译环境、进行简单测试、训练VOC数据集、生成训练文件、准备训练、开始训练以及多GPU训练的步骤。文章还提供了相应的代码示例,帮助读者理解和实践YOLOv4-Tiny模型的训练和测试过程。
116 0