进阶方法
问题
传统 A/B 测试有哪些局限性?有哪些进阶方法可以提升效率?
答案
方法对比总览
| 方法 | 解决的问题 | 复杂度 | 适用场景 |
|---|---|---|---|
| CUPED | 降低方差,减少样本量 | 中 | 通用 |
| 序贯检验 | 允许提前停止 | 中 | 时间敏感 |
| 贝叶斯 A/B | 直觉化结果解读 | 高 | 快速迭代 |
| Multi-Armed Bandit | 减少探索成本 | 高 | 持续优化 |
| 多变量测试(MVT) | 测多个变量组合 | 高 | 多因素同测 |
| 交叉实验 | 处理干扰效应 | 高 | 网络效应 |
CUPED(Controlled-experiment Using Pre-Experiment Data)
工业界最常用的方差缩减技术
微软在 2013 年提出,可以减少 30%-50% 的方差,等价于增加了 30%-50% 的样本量。
核心思想:利用实验前的数据消除个体差异。
其中:
- = 实验期间的指标
- = 实验前的同一指标(协变量)
import numpy as np
def cuped_adjustment(y_values, x_values):
"""CUPED 方差缩减"""
# θ = Cov(Y, X) / Var(X)
theta = np.cov(y_values, x_values)[0, 1] / np.var(x_values)
# 调整后的 Y
y_adjusted = y_values - theta * (x_values - np.mean(x_values))
variance_reduction = 1 - np.var(y_adjusted) / np.var(y_values)
print(f"方差缩减: {variance_reduction:.1%}")
return y_adjusted
序贯检验(Sequential Testing)
允许在实验过程中多次检查结果,在有足够证据时提前停止。
| 方法 | 特点 |
|---|---|
| O'Brien-Fleming | 早期检查门槛非常高,后期接近固定样本 |
| Pocock | 每次检查门槛相同 |
| Alpha Spending | 灵活分配 α 到各检查点 |
| Always Valid p-value | 任意时间点检查,保证 α |
# Alpha Spending(O'Brien-Fleming 风格)
# 分 4 次中期分析,每次的 α 边界:
checkpoints = [0.25, 0.50, 0.75, 1.00] # 信息比例
alpha_bounds = [0.0001, 0.0043, 0.0193, 0.0437] # 对应 α
# 实际使用时借助 statsmodels 的 GroupSequential
贝叶斯 A/B 测试
| 维度 | 频率派 | 贝叶斯 |
|---|---|---|
| 核心概念 | p 值 | 后验概率 |
| 回答的问题 | "在 H₀ 下观测到这个结果有多不可能?" | "B 比 A 好的概率是多少?" |
| 需要固定样本量 | 是 | 否 |
| 可随时查看 | 否(Peeking 问题) | 是 |
| 结果解读 | 技术性强 | 直觉化 |
import numpy as np
def bayesian_ab_test(n_c, x_c, n_t, x_t, n_sim=100000):
"""贝叶斯 A/B 测试(Beta-Binomial 模型)"""
# 先验:Beta(1, 1) = 均匀分布
# 后验:Beta(α + 成功数, β + 失败数)
posterior_c = np.random.beta(1 + x_c, 1 + (n_c - x_c), n_sim)
posterior_t = np.random.beta(1 + x_t, 1 + (n_t - x_t), n_sim)
# B 优于 A 的概率
prob_b_better = np.mean(posterior_t > posterior_c)
# 期望提升
lift = (posterior_t - posterior_c) / posterior_c
expected_lift = np.mean(lift)
# 95% 可信区间(Credible Interval)
ci = np.percentile(lift, [2.5, 97.5])
return {
"prob_b_better": prob_b_better,
"expected_lift": expected_lift,
"ci_95": ci
}
result = bayesian_ab_test(10000, 500, 10000, 550)
print(f"B 更好的概率: {result['prob_b_better']:.1%}")
print(f"预期提升: {result['expected_lift']:.1%}")
Multi-Armed Bandit(MAB)
在测试过程中逐步将流量倾斜到表现更好的方案,减少对差方案的暴露。
| 策略 | 做法 | 特点 |
|---|---|---|
| ε-Greedy | 以 ε 概率随机,1-ε 概率选最优 | 简单 |
| UCB | 选置信上界最大的 | 平衡探索和利用 |
| Thompson Sampling | 按后验概率采样 | 贝叶斯方法 |
MAB 的局限性
- 不适合需要严格因果推断的场景
- 对环境变化敏感(周末效应会干扰)
- 不容易计算置信区间
- 适合持续优化(如推荐位、广告素材),不适合一次性决策
多变量测试(MVT)
同时测试多个变量的组合效应:
| 方法 | 组合数 | 适用场景 |
|---|---|---|
| 全因子 | 指数级(2^k) | 变量少(≤3) |
| 分数因子 | 部分组合 | 变量多 |
| 正交 | 子集覆盖主效应 | 快速筛选 |
示例:测试按钮颜色(红/蓝)× 文案(A/B)× 位置(上/下)= 8 个组合。
常见面试问题
Q1: CUPED 为什么能缩减方差?
答案:CUPED 利用实验前后指标的相关性,消除个体固有差异。如果一个用户实验前就是高活跃用户,实验后也大概率高活跃——这部分变异不是实验导致的,可以通过回归调整去掉。,相关性越强(ρ 越大),缩减越多。
Q2: 贝叶斯 A/B 测试有什么缺点?
答案:
- 先验选择:先验分布影响结果(虽然大样本下影响很小)
- 缺少统一标准:不同公司使用不同的决策阈值(95%?99%?)
- 计算量大:需要蒙特卡洛模拟或变分推断
- 文化障碍:团队习惯 p 值,切换到贝叶斯需要培训
Q3: 什么时候用 MAB 而不是传统 A/B?
答案:
| 标准 A/B | MAB |
|---|---|
| 需要因果推断 | 只关心最优选择 |
| 一次性产品决策 | 持续优化(广告、推荐) |
| 效应需要精确估计 | 只需选出最优 |
| 有明确实验周期 | 长时间运行 |
Q4: 如何向 PM 解释为什么不能每天看 A/B 结果?
答案:
想象扔硬币:如果规定扔 100 次看结果,中间偶尔连续正面很正常。但如果每扔 10 次就看一次,某次连续正面时你可能误以为硬币有问题。A/B 测试也一样——中间波动是正常的,只有等够足够的数据量才能得出可靠结论。频繁检查并提前下结论,会让错误判断的概率从 5% 飙升到 30% 以上。