贝叶斯a/b测试的核心是显式建模先验、似然与后验更新逻辑,而非直接调用beta.pdf计算密度值;必须通过观测数据更新先验(如beta分布),再从联合后验采样,才能回答“p_a > p_b的概率”等业务问题,否则仅为伪推断。

贝叶斯A/B测试不是“用Python跑个bayesian_ab_test函数就能出结论”,核心在于你是否明确建模了先验、似然和后验更新逻辑——否则结果只是披着概率外衣的伪推断。
为什么不能直接套用scipy.stats.beta.pdf算P值?
传统频率学派的P值检验(如ttest_ind)假设参数是固定未知值,而贝叶斯方法把转化率p本身看作随机变量,需指定其分布。直接调用beta.pdf只计算点概率密度,不构成完整推断链。
- 错误做法:对两组样本分别拟合
beta(a, b)后画图对比——没做后验采样,无法回答“A比B高5%的概率是多少” - 正确路径:用观测数据更新先验,再从联合后验中采样,计算
P(p_A > p_B)或可信区间 - 典型陷阱:用无信息先验
beta(1, 1)在样本量极小时仍会过度影响后验;小流量实验建议用历史转化率设beta(α, β),其中α = prior_rate * 100,β = (1 - prior_rate) * 100
用pymc写清三层结构:先验→似然→后验
pymc强制你显式声明变量依赖关系,避免隐式假设。关键不是代码行数,而是能否对应到统计模型:
import pymc as pm
import numpy as np
<h1>假设A组:52次转化 / 1000次曝光;B组:48次 / 1000次</h1><p>data_A = np.array([1]<em>52 + [0]</em>(1000-52))
data_B = np.array([1]<em>48 + [0]</em>(1000-48))</p><p>with pm.Model() as model:</p><h1>先验:两组转化率独立,均用beta(2, 20)——对应先验均值≈0.09</h1><pre class="brush:python;toolbar:false;">p_A = pm.Beta("p_A", alpha=2, beta=20)
p_B = pm.Beta("p_B", alpha=2, beta=20)
# 似然:二项过程,用伯努利观测建模每次曝光
obs_A = pm.Bernoulli("obs_A", p=p_A, observed=data_A)
obs_B = pm.Bernoulli("obs_B", p=p_B, observed=data_B)
# 后验差值(核心!)
delta = pm.Deterministic("delta", p_A - p_B)
trace = pm.sample(2000, tune=1000)
- 必须用
pm.Bernoulli而非pm.Binomial——后者压缩了原始数据,丢失单次曝光信息,影响收敛诊断 -
delta要定义为pm.Deterministic,否则无法直接提取后验分布 - 检查
trace["delta"]的hdi_95%是否全大于0,比看均值更稳健;若区间含0,说明证据不足
当需要快速估算时,手写后验采样比调包更可控
小规模A/B测试(如日活
# 共轭更新:beta先验 + 伯努利似然 → beta后验 a_prior, b_prior = 2, 20 success_A, trials_A = 52, 1000 success_B, trials_B = 48, 1000 <p>post_a_A = a_prior + success_A post_b_A = b_prior + trials_A - success_A post_a_B = a_prior + success_B post_b_B = b_prior + trials_B - success_B</p><h1>直接从后验beta采样(无需MCMC)</h1><p>samples_A = np.random.beta(post_a_A, post_b_A, 10000) samples_B = np.random.beta(post_a_B, post_b_B, 10000) prob_A_better = np.mean(samples_A > samples_B) # 约0.68</p>
- 此法10毫秒内完成,适合AB实验平台实时看板
- 注意:先验参数必须一致(如都用
beta(2,20)),否则prob_A_better失去可比性 - 若A组样本量远小于B组(如A:50/500,B:500/5000),先验权重会失衡——此时应按曝光量缩放先验强度,例如A组用
beta(2*0.5, 20*0.5)
贝叶斯A/B测试最易被忽略的不是代码实现,而是先验选择与业务场景的咬合度:冷启动产品用强历史先验,成熟功能用弱先验,灰度发布则需加入设备/地域分层先验。所有“自动推荐先验”的工具都在回避这个责任。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











