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值和置信区间


相关文章
|
8天前
|
存储 关系型数据库 测试技术
玩转n8n测试自动化:核心节点详解与测试实战指南
n8n中节点是自动化测试的核心,涵盖触发器、数据操作、逻辑控制和工具节点。通过组合节点,测试工程师可构建高效、智能的测试流程,提升测试自动化能力。
|
1月前
|
Web App开发 人工智能 JavaScript
主流自动化测试框架的技术解析与实战指南
本内容深入解析主流测试框架Playwright、Selenium与Cypress的核心架构与适用场景,对比其在SPA测试、CI/CD、跨浏览器兼容性等方面的表现。同时探讨Playwright在AI增强测试、录制回放、企业部署等领域的实战优势,以及Selenium在老旧系统和IE兼容性中的坚守场景。结合六大典型场景,提供技术选型决策指南,并展望AI赋能下的未来测试体系。
|
1月前
|
存储 人工智能 算法
AI测试平台实战:深入解析自动化评分和多模型对比评测
在AI技术迅猛发展的今天,测试工程师面临着如何高效评估大模型性能的全新挑战。本文将深入探讨AI测试平台中自动化评分与多模型对比评测的关键技术与实践方法,为测试工程师提供可落地的解决方案。
|
29天前
|
人工智能 缓存 测试技术
Playwright进阶指南 (6) | 自动化测试实战
2025企业级测试解决方案全面解析:从单元测试到千级并发,构建高可用测试体系。结合Playwright智能工具,解决传统测试维护成本高、环境依赖强、执行效率低等痛点,提升测试成功率,内容从测试架构设计、电商系统实战框架、高级测试策略、Docker化部署、CI/CD集成及AI测试应用,助力测试工程师掌握前沿技术,打造高效稳定的测试流程。
Playwright进阶指南 (6) | 自动化测试实战
|
14天前
|
人工智能 数据可视化 测试技术
AI 时代 API 自动化测试实战:Postman 断言的核心技巧与实战应用
AI 时代 API 自动化测试实战:Postman 断言的核心技巧与实战应用
198 11
|
1月前
|
资源调度 前端开发 JavaScript
Jest 测试实战指南
本文系统讲解如何使用 Jest 进行高效的 JavaScript 函数测试,涵盖环境搭建、测试用例编写、模拟函数与快照测试等内容,帮助开发者提升代码质量与测试效率。
|
5月前
|
监控 测试技术 数据库连接
RunnerGo API 性能测试实战:从问题到解决的全链路剖析
API性能测试是保障软件系统稳定性与用户体验的关键环节。本文详细探讨了使用RunnerGo全栈测试平台进行API性能测试的全流程,涵盖测试计划创建、场景设计、执行分析及优化改进。通过电商平台促销活动的实际案例,展示了如何设置测试目标、选择压测模式并分析结果。针对发现的性能瓶颈,提出了代码优化、数据库调优、服务器资源配置和缓存策略等解决方案。最终,系统性能显著提升,满足高并发需求。持续关注与优化API性能,对系统稳定运行至关重要。
|
1月前
|
人工智能 缓存 监控
大模型性能测试实战指南:从原理到落地的全链路解析
本文系统解析大模型性能测试的核心方法,涵盖流式响应原理、五大关键指标(首Token延迟、吐字率等)及测试策略,提供基于Locust的压测实战方案,并深入性能瓶颈分析与优化技巧。针对多模态新挑战,探讨混合输入测试与资源优化
|
3月前
|
Java 测试技术 容器
Jmeter工具使用:HTTP接口性能测试实战
希望这篇文章能够帮助你初步理解如何使用JMeter进行HTTP接口性能测试,有兴趣的话,你可以研究更多关于JMeter的内容。记住,只有理解并掌握了这些工具,你才能充分利用它们发挥其应有的价值。+
732 23
|
2月前
|
人工智能 JavaScript 前端开发
Playwright自动化测试系列课(5) | ​​调试神器实战:Trace Viewer 录屏分析 + AI 辅助定位修复​
Playwright 的 Trace Viewer 提供录屏级追踪,还原测试全过程,帮助定位偶发故障。结合 AI 实现自动修复,大幅提升调试效率,成为自动化测试利器。