老王是“老王拉面馆”的老板,招牌牛肉面卖了三年,回头客络绎不绝。最近,一位厨师朋友调了一款新配方,老王尝了一口,觉得汤头更醇厚。可让他直接把全店的配方换掉,他不敢:万一老顾客不买账,招牌就砸了,收入也会大打折扣。怎么办?老王想出一个主意——搞一场“科学试吃”:接下来一段时间,来的客人一半随机吃旧配方,一半随机吃新配方,最后比较两拨人的反馈,再决定要不要全量更换。这个试吃实验,正是机器学习团队验证新模型时最常用的方法:A/B测试。今天我们就全程跟着老王做这场试吃,把样本量怎么算、客人怎么分、指标怎么选、结论怎么下、坑怎么躲,一条龙讲透。
在算法工程师和数据科学家手里,A/B实验是把“拍脑袋上线”升级为“数据决策”的核心能力——掌握它,你就能在模型迭代中少踩坑、敢担责、会复盘。
可视化演示
通过交互式动画理解A/B实验的核心要素:样本量对置信区间的影响、流量分流策略、以及统计显著性检验的判断过程。
本节配有交互动效(进入视口后自动加载,约 3KB)。
样本量与置信区间 对照组(A)与实验组(B)的转化率 置信区间随样本量增大而收窄 CI = p̂ ± 1.96·√(p̂(1-p̂)/n) 拖动滑块观察样本量对精度的影响
实验设计基础
老王拉面馆的招牌牛肉面卖了三年,他最近试了朋友的新配方:加了一味丁香,汤头更醇。可老王不敢直接全店换——万一老客不买账,招牌就砸了。他决定做一次“科学试吃”:让一部分客人吃旧配方,另一部分吃新配方,最后比较两碗面的满意度。
但“科学试吃”和“随口问问”之间,隔着一个关键动作:先把要证明的事说清楚。老王的直觉是“新配方更好”,可统计学喜欢反着来——先假设“新配方没有变好”,再看数据能不能推翻它。这个等着被推翻的假设叫原假设(H0),老王真正想证明的才叫备择假设(H1)。
A/B实验的一切设计都围绕这对假设展开。裁判可能犯两种错误:本来没效果,却判有效,叫第一类错误,出错概率记为 α(显著性水平),通常定在 0.05;本来有效,却没检测出来,叫第二类错误,出错概率记为 β,1−β 即统计功效——实验“发现真实效果”的能力。
把“误判代价”和“证明目标”先谈清楚,老王才知道这场试吃该怎么设计。就像打官司要先立“无罪推定”和“举证标准”,假设检验的骨架搭好了,后面所有计算才有落点。
- 原假设 H0先假定新配方没有改善,所有证据都要先按“没差异”来解释。
- 备择假设 H1与 H0 相对,主张两个好评率确实不同,是实验真正想证明的方向。
- 真实参数 p_T 与 p_C分别代表吃新配方、旧配方的顾客群体中真实的“好评比例”,无法直接观测,只能靠抽样估计。
样本量计算
试吃要请多少客人才足够?请少了,结果全凭运气;请多了,食材成本和等待时间都扛不住。老王急需一个数:每组最少多少份。
这个数取决于四个输入:显著性水平 α(允许误判的概率)、统计功效 1−β(想抓住真实效果的概率)、效应大小 δ(新配方相对旧配方预期提升多少)、以及波动率——好评率越接近 0.5,顾客意见越分裂,需要的样本就越多。
对于好评率这类“转化率”指标,经典公式是把这四个输入串在一起:
代入老王的数据:旧好评率约 0.48,新配方预期 0.56,α=0.05,功效取 0.8,算得每组约 608 份。按每天 200 位食客、五五分流算,六天左右就能完成——比“先跑一个月再说”高效得多。
- 显著性分位数 z_{1−α/2}与显著性水平 α 对应的标准正态分位数,α=0.05 时取 1.96。
- 功效分位数 z_{1−β}与统计功效对应的分位数,功效取 0.8 时约为 0.84;想更稳妥,z 就更大。
- 波动率项 p(1−p)好评率越接近 0.5,顾客意见越分裂,此项越大,所需样本越多。
- 效应量平方 (p_T−p_C)²新老配方的真实差距越大,越容易被检测出来,所需样本越小。
分流策略
谁来吃哪碗,不能由老王说了算,更不能让客人自己选。上午排队的上班族和下午茶的闲客,客群本来就不一样;爱尝鲜的顾客若自己挑了新配方,两组的差异就被“自选择”污染了。
正确做法是随机分流:每位顾客来,掷一枚公平的硬币决定吃哪碗。线上的“硬币”是用户 ID 哈希取模——把 ID 均匀映射到 0~99,小于 50 进实验组,其余进对照组。分组对用户不可见、不可选,对运营人员也无法预知。
若用户画像差异明显,可先按特征分层再随机(分层抽样),每层内比例均衡,方差更小;同时跑多个实验时,要用互斥实验保证同一用户只进一个实验,或用正交分层设计让多个实验互不污染(重叠实验)。老王按“新客/老客、堂食/外卖”把食客分成四层,每层内再随机,两组里的老客比例、外卖比例几乎一模一样,之后的比较才真正公平。
- 哈希函数 h(u)把用户 ID 打散成一个看似随机的整数,同一用户每次进入同一组。
- 取模运算 \bmod让哈希值落回 0~99 的均匀区间,保证每个用户恰好落入一个桶。
- 分流阈值 50小于 50 进实验组 T,否则进对照组 C,正好五五分。
指标选择
两碗面的“胜负”用什么尺子量?老王起初只看好评率。但朋友提醒:客人第一次尝鲜觉得新奇,随手给个好评,隔天却可能不再上门。单一指标会骗人。
指标要分层设计:核心指标是本次实验要验证的“胜负手”;护栏指标是不能变差的底线;北极星指标则是产品长期价值的代表。把它们归一化后加权成一个总分,就是 OEC(总体评估准则)。
电商改版是典型例子:核心指标设购买转化率,护栏指标设页面加载时长与崩溃率,北极星是长期复购率。老王最终敲定:核心指标用“复购率”,护栏指标用“出餐时长、差评率”,再以 OEC 总分定输赢。尺子统一了,实验才不会公说公有理。
- 标准化指标 η_i把每个指标(好评率、时长等)减去均值再除以标准差,统一到同一量纲。
- 权重 w_i按业务优先级给每个指标分配权重,所有权重之和为 1。
- 加权求和把多目标压成一个总分,避免“转化率涨了、体验崩了”的片面结论。
显著性检验
试吃落幕:新配方好评率 56%,旧配方 48%,相差 8 个百分点。可老王心里打鼓——几百份样本的差距,会不会只是运气?
显著性检验就是用来量化“运气成分”的。对转化率这类比例指标,用 z 检验(小样本可用 t 检验):先算一个标准化的统计量 z,再换算成 p 值。p 值的含义是:如果新配方真的没效果,出现当前差距(或更极端差距)的概率有多大。p 小于事先定的 α=0.05,就有统计证据拒绝原假设。
比 p 值更直观的是置信区间:对两组的真实差计算 95% 置信区间,若区间完全不含 0,说明差异显著;区间越窄,估计越精确。老王盯着监控面板上两条渐渐收窄的置信带:起初严重重叠,看不出名堂;样本越攒越多,带子越分越开,最终完全分离——直到这一刻,他才敢把新配方端上全店菜单。
- 组间差两组样本好评率之差,是我们要评价的“领先幅度”。
- 合并比例 p̄把两组数据合起来估计总体好评率,作为标准误的基准。
- 标准误分母差值在随机抽样下的波动幅度,样本越多就越小。
常见陷阱
实验第三天,新配方领先 5%,老王兴冲冲要全店换新。朋友拦住他:你这是“中途偷看”。每偷看一次就相当于做一次检验,假阳性率被悄悄抬高,最后可能被“偶然的领先”骗了——这就是过早停止陷阱。
老王还想顺手比较 3 个配方变体,同时监控 10 个指标。比较得越多,纯靠运气撞出“显著”的概率越大,必须做多重比较校正。最简单的是 Bonferroni 校正:把 α 除以比较次数 m。
另两个坑更隐蔽:回头客反复来试吃,同一人被计入多次,样本不再独立;门口挂“新品试吃”的牌子后,老客碍于情面打感情分——霍桑效应(新奇效应)让数据失真。老王撤了牌子,限定每人只计一次,把显著性阈值按 Bonferroni 调低后再下结论。数据干净了,结论才站得住脚。
- 原始显著水平 α单次检验允许假阳性的概率,通常取 0.05。
- 比较次数 m同时比较的配方变体数,或同时监控的指标数。
- 校正后阈值 α′把 α 均分给 m 次比较,整体假阳性率仍大致控制在 α 附近。
实验流程
把每个零件组装起来,一场科学试吃就变成一套可复用的“菜谱”。老王把它写成了四步流程,每次上新照方抓药。
需求定义:写下假设、核心指标和决策标准;实验设计:算样本量、定分流方案、定指标与校正规则;运行监控:守住护栏指标、禁止中途偷看、异常时熔断;决策复盘:结合 p 值、效应量、置信区间和业务成本,决定全量、灰度还是放弃。
上线不是终点。A/B 实验的结论还要回到业务里验证:复购数据是否真的跟上、护栏指标有没有长期波动。如今老王店里每次上新都走同一套流程,他不再拍脑袋赌配方,而是让数据替顾客投票——这正是机器学习模型线上评估的金标准:用小流量实验,换取高确定性的决策。
- 统计显著 p < α差异不是运气能解释的,是显著性检验给出的入场券。
- 业务显著 Δ̂ ≥ δ_min效果量达到业务可接受的最小幅度,避免“显著但没用”的尴尬。
- 两者同时成立才上线统计显著与业务显著缺一不可,这正是 A/B 实验的决策准则。
AI 应用场景
推荐系统排序模型上线评估
阶段:模型上线前的效果验证阶段
解决的问题:新排序模型直接全量替换,一旦点击率或时长下滑,损失以亿计。传统做法靠离线指标(AUC 等)拍板,但离线指标和线上真实反馈常有偏差;AI 的做法是切成 10% 流量跑 A/B,用线上核心指标验证。
具体案例:某信息流产品每天 1 亿曝光,新排序模型先放量 10%,观察 7 天后计算核心指标:点击率提升 0.8%,护栏指标人均时长不降,再逐步灰度到全量。
风控模型策略灰度
阶段:策略调优的灰度验证阶段
解决的问题:风控模型收紧阈值会降低坏账,但也可能误伤优质客户、引发投诉。传统方式是全量切换后看大盘,风险不可控;AI 的方式是通过分层抽样把新客老客分开做 A/B,并用护栏指标守住通过率与投诉量。
具体案例:某消费金融公司对新版逾期模型做 A/B,核心指标坏账率下降 0.3%,护栏指标放款通过率、客诉率均未恶化,最终批准全量上线。
广告商业化策略实验
阶段:商业化策略的收益评估阶段
解决的问题:广告调价既要看收入,又要看用户体验,单看收入会让体验崩坏。传统做法是凭经验定权重;AI 的做法是把收入、体验指标标准化后合成 OEC,再用多重比较校正避免误判。
具体案例:某广告团队同时测试 3 种出价策略,对 6 个指标做 Bonferroni 校正后,只有一种策略同时满足收入提升且体验不降,最终被选中全量。
Python 演示
import mathimport random def normal_cdf(x): return 0.5 * (1 + math.erf(x / math.sqrt(2))) def z_test_two_proportions(n_c, n_t, k_c, k_t): p_c = k_c / n_c p_t = k_t / n_t p_bar = (k_c + k_t) / (n_c + n_t) se = math.sqrt(p_bar * (1 - p_bar) * (1 / n_c + 1 / n_t)) z = (p_t - p_c) / se p_value = 2 * (1 - normal_cdf(abs(z))) return z, p_value def needed_sample_size(p_c, p_t, alpha=0.05, power=0.8): z_alpha = 1.96 z_beta = 0.84 delta = p_t - p_c n = (z_alpha + z_beta) ** 2 * (p_c * (1 - p_c) + p_t * (1 - p_t)) / delta ** 2 return math.ceil(n) def run_one(n, p_c, p_t): k_c = sum(1 for _ in range(n) if random.random() < p_c) k_t = sum(1 for _ in range(n) if random.random() < p_t) _, p_value = z_test_two_proportions(n, n, k_c, k_t) return p_value < 0.05 if __name__ == "__main__": p_c, p_t = 0.48, 0.56 n = needed_sample_size(p_c, p_t) print("每组所需样本量: %d" % n) random.seed(42) trials = 1000 hits = sum(1 for _ in range(trials) if run_one(n, p_c, p_t)) print("1000次模拟实验检出显著的比例: %.3f" % (hits / trials)) print("该比例应接近理论功效 0.80, 说明样本量计算可靠")
n = (z_alpha + z_beta) ** 2 * (p_c * (1 - p_c) + p_t * (1 - p_t)) / delta ** 2样本量公式:四要素(α、功效、波动率、效应量)全部体现在这一行。se = math.sqrt(p_bar * (1 - p_bar) * (1 / n_c + 1 / n_t))计算两组比例差的标准误,样本量越大标准误越小。p_value = 2 * (1 - normal_cdf(abs(z)))用正态分布累积函数求双尾 p 值。hits = sum(1 for _ in range(trials) if run_one(n, p_c, p_t))模拟 1000 次实验,统计多少次能正确检出真实差异。random.seed(42)固定随机种子,保证结果可复现,方便复试。
常见误区
误区我觉得实验样本越多、时间越长就越可靠,所以每次都尽量多开流量、多跑几周,反正数据多没坏处。
正解样本量过大会把微小到没有业务意义的差异也判为“统计显著”——比如转化率提升 0.01%,统计上显著,业务上毫无价值。正确做法是事前定一个最小效应量(业务能接受的底线),样本量够到能检出来就行。老王试吃 608 份就收工,不是因为小气,而是再多就浪费了。
为何常见:人们直觉上觉得“信息越多越好”,却忽略了统计显著不等于业务显著,样本和实验时长都有边际成本。
误区我看到 p 值是 0.03,小于 0.05,立刻确定新模型一定比旧模型好,第二天就申请全量上线。
正解p 值只回答“如果没效果,出现这种数据的概率”,不回答“新模型更优的概率”,更不代表效果量有多大。上线决策还要看效应量的置信区间下限、护栏指标是否恶化、以及实现成本。p=0.049 和 p=0.0499 没有本质差别,都是“刚过线”,别把它当成圣旨。
为何常见:把 0.05 当作非黑即白的开关,是教科书的简化写法,真实业务里它只是一个预设的误判容忍度。
误区只要用了随机数把用户分到两组,分组就一定公平,不需要再做分层,也没必要考虑实验之间的重叠。
正解简单随机在用户高度异质时(新客老客、不同城市)可能造成两组画像不均衡,分层抽样能压低方差、加速收敛;多个实验同时跑时,同一用户被分进互相干扰的实验,会污染结论,必须用互斥或正交分层的重叠实验方案。
为何常见:教科书先讲掷硬币式随机,学习者容易把“示例”当成“完整方案”,忽略了工程现场的多实验并行约束。
误区实验跑了两天我看一下,第三天再看一下,最后只要 p 值小于 0.05,我就放心下结论了。
正解每次中途偷看都在做一次显著性检验,多重比较会抬高整体假阳性率。你以为 α=0.05,实际可能已经变成 0.15 甚至更高。正确的做法是预先定好样本量和停止规则,运行期间只看护栏指标,不偷看核心结论。老王第三天差点被“偶然领先”骗了,就是吃了这个亏。
为何常见:人天生对“快速看到结果”有冲动,且不知道偷看等于不断重新掷骰子,把“偶然差异”攒成了“虚假显著”。
面试题
Q1. A/B实验中,原假设(H0)通常是什么?
- A.新方案效果显著更优
- B.新旧方案效果没有差别← 正确答案
- C.实验样本量必须足够大
- D.实验组转化率一定更高
答案:B。原假设是被保护的一方,默认“没有差异”,数据足够强时才能拒绝它。就像老王先假定新配方没变好,让证据来反驳。C、D 与假设内容无关,A 是备择假设的表述。
Q2. 想要提升检验功效(1−β),以下哪个做法最直接有效?
- A.显著提升实验组样本量← 正确答案
- B.降低显著性水平阈值α
- C.不断缩短实验的运行时间
- D.增加实验中观察到的指标
答案:A。功效 = 在效果真实存在时检出的概率。增大样本量能缩小标准误、让分布更分开,是最直接的杠杆。降低 α 会让门槛更严、功效更小;缩短时间等于减少样本;增加指标只会带来多重比较问题。
Q3. 样本量公式中,若效应大小(p_T − p_C)减半,所需样本量约为原来的几倍?
- A.变为原来的两倍
- B.变为原来的四倍← 正确答案
- C.样本量基本不变
- D.变为原来的一半
答案:B。样本量与效应量的平方成反比,效应减半则分母变为原来的 1/4,所需样本量变为 4 倍。这也解释了为什么“微小优化”的模型实验特别烧流量。
Q4. 以下哪些做法可以降低A/B实验的偏差或方差?
- A.按画像分层后再随机分组← 正确答案
- B.让用户自己选择实验分组
- C.同一用户只计入一次结果← 正确答案
- D.按用户ID哈希进行随机分流← 正确答案
答案:ACD。A 分层抽样降低组间差异带来的方差;C 保证样本独立性;D 是随机分流的工程实现,防自选择。B 让用户自选会引入自选择偏差,两组画像失衡,属于典型反面操作。
Q5. 关于 p 值的含义,正确的说法是:
- A.判断实验结论为假的概率
- B.原假设真时观察到该结果的概率← 正确答案
- C.新方案真的更优的概率
- D.第二类错误发生的概率
答案:B。p 值 = 在原假设成立的前提下,观测到当前或更极端数据的概率。它不回答“结论为假的概率”,也不回答“新方案更优的概率”。D 描述的是 β,和 p 值是两回事。
Q6. 关于多重比较,以下说法正确的是:
- A.同时比较多假设会抬高假阳性风险← 正确答案
- B.Bonferroni校正会调低显著性水平← 正确答案
- C.只报告最好的一次结果就没有问题
- D.预设唯一核心指标可缓解该问题← 正确答案
答案:ABD。比较次数越多,碰运气出显著的概率越大,A 对;Bonferroni 把 α 除以比较次数,B 对;只挑最好结果报告属于“选择报告”,反而放大了偏差,C 错;预先锁定唯一核心指标能从根本上减少比较次数,D 对。
Q7. 实验过程中每天偷看结果并决定是否停止,最容易导致:
- A.实验检验功效不充分
- B.假阳性率变高造成误判← 正确答案
- C.置信区间会不断变宽
- D.实验的效应量完全消失
答案:B。每一次偷看都相当于做一次检验,多次检验后整体假阳性率被抬高,容易把“偶然波动”当成真实效果。这和多重比较是同一个病根,所以实验要预注册停止规则。
Q8. 在“点击率提升”类实验中,以下哪些指标适合作为护栏指标?
- A.接口请求耗时时延← 正确答案
- B.页面崩溃率的波动← 正确答案
- C.本次实验的目标转化率
- D.用户平均停留时长← 正确答案
答案:ABD。护栏指标是“不允许变差”的底线,时延、崩溃率、停留时长都可能因模型改动而恶化,必须守住。目标转化率是本次实验的核心指标,是“被检验的对象”,不是护栏。
Q9. 若实验组与对照组之间存在网络效应,最核心的问题是:
- A.检验统计量公式必定失效
- B.个体处理稳定假设被破坏← 正确答案
- C.观测指标会全部失真
- D.检验功效会自动提高
答案:B。A/B 实验依赖“个体处理稳定性假设”(SUTVA):一个人的结果只受自己所在组影响。网络效应下,实验组用户的行为会改变对照组用户的体验,两组互相“串味”,估计结果有偏。这是社交产品实验最难处理的问题。
Q10. 一个实验中同时监控10个指标且不做校正,α=0.05,至少出现一个假阳性的概率约为:
- A.大约百分之五左右
- B.大约百分之四十左右← 正确答案
- C.大约百分之九十五左右
- D.大约千分之五左右
答案:B。10 次独立检验至少一次假阳性的概率 = 1−(1−0.05)¹⁰ ≈ 0.40。这就是多重比较必须校正的原因:监控的指标越多,“躺枪”的概率越高,用 Bonferroni 等校正把整体假阳性率拉回可控区间。