数据分析实战 | A/B测试探寻哪种广告点击率更高?

简介: 数据分析实战 | A/B测试探寻哪种广告点击率更高?

场景描述


某个促销活动每个月都会开展一次,但和公司其他类似的促销活动相比,该促销活动的用户购买率比较低。通过调查用户购买率低的原因,发现问题可能出在促销广告上。

于是我们准备了两个不同的广告,来验证哪种广告能够带来更高的用户购买率。

A/B测试

A/B 测试能够在多个选项中找出那个能够带来最佳结果的选项。在本例中,我们只要同时投放广告 A 和广告 B,就可以排除其他外部因素的干扰,但要注意用户分组必须遵循随机原则。

image.png

在测试过程中,我们收集到了两组广告的曝光数据和点击数据,接下来就可以开始数据分析!


数据描述


ab_test_imp

广告曝光次数信息,87924 行。

字段 类型 含义
log_date str 广告曝光日期
app_name str 应用名
test_name str 测试名
test_case str 测试用例(A/B)
user_id numpy.int64 用户 ID
transaction_id numpy.int64 事务 ID
ab_test_goal

广告点击次数信息,8598 行。

字段 类型 含义
log_date.g str 广告点击日期
app_name str 应用名
test_name.g str 测试名
test_case.g str 测试用例(A/B)
user_id.g numpy.int64 用户 ID
transaction_id numpy.int64 事务 ID


数据分析


数据读取

读取两个数据集。

import pandas as pd
imp_df = pd.read_csv('ab_test_imp.csv')
goal_df = pd.read_csv('ab_test_goal.csv')
复制代码


修改两个数据集的列名。

imp_df.columns = ['广告曝光日期', '应用名', '测试名', '测试用例(A/B)', '用户ID', '事务ID']
goal_df.columns = ['广告点击日期', '应用名', '测试名', '测试用例(A/B)', '用户ID', '事务ID']
复制代码


显示 ab_test_imp 数据集后五行。

imp_df.tail()
复制代码

image.png

显示 ab_test_goal 数据集后五行。

goal_df.tail()
复制代码

image.png

以曝光数据作为主数据集,连接两个数据集。

all_df = imp_df.merge(goal_df, how='left', on='事务ID', suffixes=('', '_goal'))
all_df.tail()
复制代码

image.png

增加标记列,判断用户是否点击

all_df['是否点击'] = all_df['用户ID_goal'].apply(lambda x:0 if pd.isnull(x) else 1)
复制代码

提取分析所需的列数据。

all_df = all_df.loc[:, ['广告曝光日期', '测试用例(A/B)', '用户ID',  '事务ID', '是否点击']]
all_df.tail()
复制代码

image.png


A/B点击率

数据处理好后,接下来统计一下 A/B 两个广告的点击率。

pivot = all_df.pivot_table(index='测试用例(A/B)',
                           columns=None,
                           values='是否点击',
                           aggfunc=(lambda x: sum(x)/len(x))).reset_index()
pivot
复制代码

image.png

A 的点击率为 是 8% 左右,而 B 的点击率 11.5%。


卡方检验

在讨论二者的差异时,一般采用卡方检验,我们先获取 A/B 广告的点击次数。

import numpy as np
pivot = all_df.pivot_table(index='测试用例(A/B)',
                           columns='是否点击',
                           values='用户ID',
                           aggfunc=np.count_nonzero)
pivot
复制代码

image.png

chi2_contingency 用于列联表中变量独立性的卡方检验。chi2_contingency(observed, correction=True, lambda_=None)


参数

  • observed:列联表,本例中为二维数组。
  • correction :如果为True,并且自由度为1,则应用Yates校正以保持连续性。校正的效果是将每个观察值向相应的期望值调整0.5
  • lambda_ :float或str,可选。默认情况下,此测试中计算的统计量是Pearson的卡方统计量。 lambda_允许使用Cressie-Read功率散度族的统计量来代替。


返回值

  • chi2:float,卡方值
  • p:float,p值
  • dof:int,自由程度
  • expected:ndarray,预期频率,基于表的边际总和
from scipy.stats import chi2_contingency
kf = chi2_contingency(np.array(pivot))
kf
复制代码

image.png

根据上面结果,p值为 4.04×10−694.04×10^{-69}4.04×1069 , 是一个非常小的数值。p 值越接近于 0 差异性越大。通常来说,当 p 值 小于 0.05 时,称为“存在显著性差异”。因此我们可以说:在将两种广告分为 A/B 并 同时投放后,所得到的点击率存在显著性差异。


A/B广告点击时间序列

计算两个广告每日的点击率。

res = all_df.pivot_table(index='广告曝光日期',
                  columns='测试用例(A/B)',
                  values='是否点击',
                  aggfunc=(lambda x: sum(x)/len(x))).reset_index()
res.head()
复制代码

image.png


绘制A/B广告点击率时间序列折线图。

from pyecharts.charts import *
import pyecharts.options as opts
from pyecharts.globals import ThemeType
line_style = {
    'normal': {
        'width': 4,
        'shadowColor': 'rgba(155, 18, 184, .3)', 
        'shadowBlur': 10,
        'shadowOffsetY': 10,
        'shadowOffsetX': 10,
        'curve': 0.5  
    }
}
line = (Line(init_opts=opts.InitOpts(theme='ThemeType.CHALK', width='900px')))
line.add_xaxis(res['广告曝光日期'].tolist())
line.add_yaxis('A 广告',
        res['A'].tolist(),
        yaxis_index=0,
        is_smooth=True,
        is_symbol_show=False,
        linestyle_opts=line_style
    )
line.add_yaxis('B 广告',
        res['B'].tolist(),
        is_smooth=True,
        is_symbol_show=False,
        linestyle_opts=line_style
    )
line.set_series_opts(
        label_opts=opts.LabelOpts(
            is_show = False,
        )
    )
line.set_global_opts(
        title_opts=opts.TitleOpts(
            title = 'A / B 广告点击率时间序列变化折线图',
            pos_left = 'center',
            pos_top = '2%'
        ),
        legend_opts=opts.LegendOpts(
            pos_top = '12%',
            legend_icon = 'circle'
        ),
        xaxis_opts=opts.AxisOpts(
            axislabel_opts={'rotate':90},
            axisline_opts=opts.AxisLineOpts(
                is_show=False
            ),
        ),
        yaxis_opts=opts.AxisOpts(
            name='点击率 %',
            axisline_opts=opts.AxisLineOpts(
                is_show=False
            ),
            splitline_opts=opts.SplitLineOpts(
                is_show=True
            )
        ),
        tooltip_opts=opts.TooltipOpts(
            is_show = True,
            trigger = 'axis',
            trigger_on = 'mousemove|click',
            axis_pointer_type = 'shadow'
        )
    )
line.render_notebook()
复制代码

image.png

通过上图可知,广告 B 的点击率在大多数时候都优于广告A。所以,分析结果是,广告B比广告A更容易被用户点击。



目录
打赏
0
0
0
0
2
分享
相关文章
RunnerGo API 性能测试实战:从问题到解决的全链路剖析
API性能测试是保障软件系统稳定性与用户体验的关键环节。本文详细探讨了使用RunnerGo全栈测试平台进行API性能测试的全流程,涵盖测试计划创建、场景设计、执行分析及优化改进。通过电商平台促销活动的实际案例,展示了如何设置测试目标、选择压测模式并分析结果。针对发现的性能瓶颈,提出了代码优化、数据库调优、服务器资源配置和缓存策略等解决方案。最终,系统性能显著提升,满足高并发需求。持续关注与优化API性能,对系统稳定运行至关重要。
Jmeter工具使用:HTTP接口性能测试实战
希望这篇文章能够帮助你初步理解如何使用JMeter进行HTTP接口性能测试,有兴趣的话,你可以研究更多关于JMeter的内容。记住,只有理解并掌握了这些工具,你才能充分利用它们发挥其应有的价值。+
297 23
2025接口测试全攻略:高并发、安全防护与六大工具实战指南
本文探讨高并发稳定性验证、安全防护实战及六大工具(Postman、RunnerGo、Apipost、JMeter、SoapUI、Fiddler)选型指南,助力构建未来接口测试体系。接口测试旨在验证数据传输、参数合法性、错误处理能力及性能安全性,其重要性体现在早期发现问题、保障系统稳定和支撑持续集成。常用方法包括功能、性能、安全性及兼容性测试,典型场景涵盖前后端分离开发、第三方服务集成与数据一致性检查。选择合适的工具需综合考虑需求与团队协作等因素。
340 24
基于 DIFY 的自动化数据分析实战
本文介绍如何使用DIFY搭建数据分析自动化流程,实现从输入需求到查询数据库、LLM分析再到可视化输出的全流程。基于经典的employees数据集和DIFY云端环境,通过LLM-SQL解析、SQL执行、LLM数据分析及ECharts可视化等模块,高效完成数据分析任务。此方案适用于人力资源分析、薪酬管理等数据密集型业务,显著提升效率并降低成本。
9782 16
从Postman到Apipost:我的动态参数测试实战踩坑记
作为一名全栈开发工程师,在开发用户中心模块时,我遇到了复杂参数API测试的挑战。最初使用Postman时,发现其在生成动态参数(如邮箱、手机号和日期)时存在诸多问题,导致测试效率低下甚至出错。例如,随机生成的邮箱格式无效等 后来,CTO推荐了Apipost,它提供了更智能的参数生成方式:支持真实邮箱、符合规范的手机号以及合法日期范围,极大提升了测试效率和准确性。通过对比,Apipost在处理复杂动态参数方面明显优于Postman,减少了维护成本并提高了团队协作效率。现在,我们已全面切换到Apipost,并利用其「参数组合测试」功能发现了多个边界条件bug。
Python 高级编程与实战:构建自动化测试框架
本文深入探讨了Python中的自动化测试框架,包括unittest、pytest和nose2,并通过实战项目帮助读者掌握这些技术。文中详细介绍了各框架的基本用法和示例代码,助力开发者快速验证代码正确性,减少手动测试工作量。学习资源推荐包括Python官方文档及Real Python等网站。
一个测试工程师的实战笔记:我是如何在Postman和Apipost之间做出选择的?
优秀的API测试工具应该具备: 分层设计:既有可视化操作,也开放代码层深度定制 场景感知:自动识别加密需求推荐处理方案 协议包容:不强迫开发者为了不同协议切换工具 数据主权:允许自主选择数据存储位置
137 7
基于阿里云大数据平台的实时数据湖构建与数据分析实战
在大数据时代,数据湖作为集中存储和处理海量数据的架构,成为企业数据管理的核心。阿里云提供包括MaxCompute、DataWorks、E-MapReduce等在内的完整大数据平台,支持从数据采集、存储、处理到分析的全流程。本文通过电商平台案例,展示如何基于阿里云构建实时数据湖,实现数据价值挖掘。平台优势包括全托管服务、高扩展性、丰富的生态集成和强大的数据分析工具。
接口测试新选择:Postman替代方案全解析
在软件开发中,接口测试工具至关重要。Postman长期占据主导地位,但随着国产工具的崛起,越来越多开发者转向更适合中国市场的替代方案——Apifox。它不仅支持中英文切换、完全免费不限人数,还具备强大的可视化操作、自动生成文档和API调试功能,极大简化了开发流程。
除了postman还有什么接口测试工具
最好还是使用国内的接口测试软件,其实国内替换postman的软件有很多,这里我推荐使用yunedit-post这款接口测试工具来代替postman,因为它除了接口测试功能外,在动态参数的支持、后置处理执行sql语句等支持方面做得比较好。而且还有接口分享功能,可以生成接口文档给团队在线浏览。
167 2

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问