news 2026/4/25 12:06:28

用Python做A/B测试:手把手教你用二项分布检验广告点击率差异(附完整代码)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
用Python做A/B测试:手把手教你用二项分布检验广告点击率差异(附完整代码)

用Python做A/B测试:手把手教你用二项分布检验广告点击率差异(附完整代码)

当产品经理拿着两组广告点击数据问你"新版广告文案真的比旧版好吗?"时,一个严谨的数据分析师不会直接比较百分比差异就下结论。本文将带你用二项分布假设检验,科学验证广告效果差异的真实性。

1. 为什么A/B测试需要统计检验

某次广告优化中,我们观察到:

  • 旧版广告:10,000次展示获得200次点击(CTR=2.00%)
  • 新版广告:10,050次展示获得230次点击(CTR=2.29%)

表面看新版表现更好,但这两个数字真的具有统计学意义吗?二项分布检验能帮我们回答三个关键问题:

  1. 观测到的差异是否可能纯属偶然
  2. 需要多少样本量才能确信差异真实存在
  3. 差异的置信区间是多少

注意:直接比较百分比是新手常见错误,就像比较北京和上海的气温而不考虑测量误差

2. 二项分布在点击率分析中的原理

每次广告展示只有两种结果:

  • 点击(概率p)
  • 未点击(概率1-p)

这正是伯努利试验的典型特征。当进行n次独立展示时,点击次数k服从二项分布:

from scipy.stats import binom n = 10000 # 展示量 p = 0.02 # 真实CTR k = 200 # 点击量 # 计算恰好获得200次点击的概率 prob = binom.pmf(k, n, p) print(f"概率:{prob:.4f}") # 输出:0.0108

关键性质:

  • 期望值:E(k) = n×p
  • 方差:Var(k) = n×p×(1-p)
  • 标准差:σ = √(n×p×(1-p))

当n足够大时(通常np>5且n(1-p)>5),二项分布近似正态分布,这是假设检验的基础。

3. 完整的两比例Z检验实现

使用Python的scipy.stats进行检验:

import numpy as np from statsmodels.stats.proportion import proportions_ztest # 原始数据 impressions_A = 10000 clicks_A = 200 impressions_B = 10050 clicks_B = 230 # 执行检验 count = np.array([clicks_A, clicks_B]) nobs = np.array([impressions_A, impressions_B]) z_stat, p_value = proportions_ztest(count, nobs, alternative='two-sided') print(f"Z统计量:{z_stat:.3f}") # -2.108 print(f"P值:{p_value:.4f}") # 0.0350

结果解读表格:

指标判断标准结论
Z值-2.108负值表示B组表现更好
P值0.0350<0.05差异显著
95%置信区间(-0.0056, -0.0002)不包含0确信B组更优

4. 实际业务中的进阶技巧

4.1 样本量预估

在测试前计算所需样本量:

from statsmodels.stats.power import zt_ind_solve_power effect_size = 0.003 # 希望检测到的最小CTR差异 alpha = 0.05 # 显著性水平 power = 0.8 # 统计功效 sample_size = zt_ind_solve_power( effect_size=effect_size, alpha=alpha, power=power, ratio=1.0 # 两组样本量相等 ) print(f"每组需要样本量:{int(sample_size)}") # 每组约17,543次展示

4.2 多重检验校正

当同时测试多个广告版本时,需要使用Bonferroni校正:

original_alpha = 0.05 num_tests = 5 # 同时测试5个广告版本 adjusted_alpha = original_alpha / num_tests print(f"校正后的显著性水平:{adjusted_alpha}") # 0.01

4.3 非参数检验方法

当样本量较小时,可以使用Fisher精确检验:

from scipy.stats import fisher_exact table = [[200, 10000-200], [230, 10050-230]] odds_ratio, p_value = fisher_exact(table, alternative='two-sided') print(f"P值:{p_value:.4f}") # 0.0398

5. 结果可视化与业务报告

用Matplotlib制作专业图表:

import matplotlib.pyplot as plt import seaborn as sns data = { 'Version': ['A', 'B'], 'CTR': [200/10000, 230/10050], 'CI_lower': [0.0173, 0.0200], 'CI_upper': [0.0227, 0.0258] } plt.figure(figsize=(8,5)) sns.pointplot(data=data, x='Version', y='CTR', capsize=0.2, markers='D', scale=0.7) plt.title('广告版本CTR对比 (95%置信区间)') plt.ylabel('点击率') plt.grid(axis='y', linestyle='--', alpha=0.7) plt.show()

向非技术团队汇报时,建议采用这个话术结构:

  1. 业务影响:"新版广告预计能带来每月额外1500次点击"
  2. 统计确定性:"我们有95%的把握认为差异真实存在"
  3. 后续行动:"建议全量上线并持续监控效果"
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/25 12:01:34

TrollInstallerX完整指南:3分钟在iOS 14-16.6.1上安全安装TrollStore

TrollInstallerX完整指南&#xff1a;3分钟在iOS 14-16.6.1上安全安装TrollStore 【免费下载链接】TrollInstallerX A TrollStore installer for iOS 14.0 - 16.6.1 项目地址: https://gitcode.com/gh_mirrors/tr/TrollInstallerX 你是否厌倦了iOS设备的限制&#xff1f…

作者头像 李华