Python A/B 测试的数据分析

16次阅读

用 scipy.stats.proportions_ztest 做两样本比例检验,设 correction=false 关闭连续性修正,输入 [success_a, success_b] 和[n_a, n_b],双侧 p 值需根据 zstat 符号转单侧;statsmodels 无 ab_test 函数,可用 confint_proportions_2indep 计算绝对提升的 95% 置信区间。

Python A/B 测试的数据分析

怎么用 scipy.stats 做两样本比例检验(比如点击率)

直接用 proportions_ztest,别手写 z 分数——它默认做的是双侧检验,且自动处理小样本校正(加 0.5 连续性修正),但多数 A/B 测试里你其实不需要这个修正,反而会降低统计功效。

  • 真实场景中,只要每组样本量 > 30 且成功数 / 失败数都 ≥ 5,就关掉连续性修正:correction=False
  • 注意 countnobs 的顺序:必须是 [success_A, success_B] 和 [n_A, n_B],反了结果完全不可信
  • 返回的 p 值是双侧的;如果你只关心“B 是否显著高于 A”,得自己转成单侧:p_value / 2,但前提是 zstat > 0

statsmodelsab_test 没有内置函数,别搜这个关键词

很多人在文档里翻半天找 ab_test,其实 statsmodels 根本没这玩意儿。它提供的是底层工具链,比如 proportion 模块里的 ztestconfint_proportions_2indep,用来算置信区间更稳。

  • confint_proportions_2indep 算绝对提升的 95% CI:比只看 p 值更能判断业务意义
  • 如果转化率很低(scipy.stats.fisher_exact(2×2 列联表),虽然慢点,但准确
  • statsmodels 默认用独立样本假设;如果实验是配对设计(比如用户级分流 + 前后对比),得换 mcnemar 或手动建配对差值序列

分层分析时,groupby 后直接调 proportions_ztest 会出错

因为 proportions_ztest 不接受 Series,也不支持向量化。常见错误是写成 df.groupby('country')['converted'].apply(……),结果报 ValueError: too many values to unpack

  • 正确做法:先用 agg 提取每层的 sumcount,组装成两个数组再喂给检验函数
  • 分层后样本量可能不均——某国只有 20 个用户?跳过它,别强行合并或插值,否则假阳性飙升
  • 如果要做 Bonferroni 校正,p 值阈值不是 0.05 / n_layers,而是 0.05 / (n_layers - 1)(对照组不算一层)

时间衰减效应会让当天跑的 p_value 失真

新用户和老用户行为节奏不同,第 1 天的点击率常被短期激励拉高,但第 7 天的留存才反映真实效果。直接拿首日数据跑检验,大概率早停(early stopping)误判。

立即学习Python 免费学习笔记(深入)”;

  • 至少等齐最小周期:电商看 7 日 ROI,SaaS 看 14 日激活,别卡在第 3 天就下结论
  • pandas.cut 按曝光后小时分桶,画 conversion_rate 随时间变化曲线,确认是否已收敛
  • 如果实验跑了 14 天但最后 2 天流量突降 40%,那这两天的数据权重该砍掉——不是删掉,是用 weights 参数传给检验函数

最麻烦的不是算不准,而是把分层、时序、样本依赖这几个坑叠在一起——这时候单独看任一指标都没问题,合起来却系统性偏移。盯住原始事件流,比盯汇总表安全得多。

text=ZqhQzanResources