作者:阿泽,复旦大学,Datawhale成员
“A/B测试不一定是最好的评估方法。它不是万能的,但不会A/B测试肯定是不行的。”
—— 字节跳动副总裁杨震原
这边文章是按照对A/B测试的思考过程来写的,不难,希望能帮助大家理解什么是A/B测试。
假设我们做了一个 A/B 实验,然后我们会想知道自己的实验是否能得到显著的效果。你可以通过经验判断,但更严谨的方法是通过统计学公式计算 p 值是否小于设定的显著性水平
,从而判断实验结果是否显著。
举个?,我们有以下四格表:
对照组 | 实验组 | 合计 | |
---|---|---|---|
转换 | 15 | 8 | 23 |
不转换 | 35 | 42 | 77 |
合计 | 50 | 50 | 100 |
通过以上统计结果我们来尝试计算一下 p 值。
于是我得到了 z 值的计算公式:
其中,
分别为转换 A/B 测试的转换数和样本总数。
然后屁颠的将统计值(
)带入到公式中并计算出 z 值为 1.66,
然后用 excel 来计算:
,大于 0.05 不显著。
NORMSDIST 可以计算标准正态分布的累积概率。
以上便完成了 A/B 测试的计算。
如果事情到此就结束,那岂不是太浅薄了。
这边问几个简单的问题:
为了搞清楚这些问题,我们继续探究。
假设检验是研究如何根据抽样后获得的样本来检查抽样前所作假设是否合理,A/B Test 从本质上来说是一个基于统计的假设检验过程,它首先对实验组和对照组的关系提出了某种假设,然后计算这两组数据的差异和确定该差异是否存在统计上的显著性,最后根据上述结果对假设做出判断。
我们再用上面的数据走下流程。
首先,我们做一个假设:
:实验组和对照组无显著差异;
:实验组和对照组存在显著差异。
假设检验的核心是证伪,所以原假设是统计者想要拒绝的假设,无显著差异我们也可以理解为:实验组和对照组的统计差异是由抽样误差引起的(误差服从正态分布)。
然后,我们需要选一个检验方法来对我们做的假设进行验证。
常用的假设检验方法有 z 检验、t 检验和卡方检验等,不同的方法有不同的适用条件和检验目标。比如我们常说 z 检验适用大样本而 t 检验适用于小样本。实验组的样本容量 > 30,所以我们这里采用 z 检验。又由于我们检验的目标是两组样本(区别于单组样本),所以其 z 值的计算公式为:
由于我们的数据是转换/不转换,所以我们可以令转换的样本为 1,不转换的样本为 0,从而算出 ,(通过正态分布的累积概率分布)得到单边概率 P(0<x<1.67)=0.4525。</x<1.67)=0.4525
x1 = np.array([1]*15 + [0]*35)
x2 = np.array([1]*8 + [0]*42)
# ddof = 1 用于计算样本标准差,区别于总体标准差
z = (x1.mean() - x2.mean()) / np.sqrt(x1.var(ddof = 1)/50 + x2.var(ddof = 1)/50)
z
"""
1.6699
"""
以上便是假设检验的基本步骤。我可能还会有一些疑问,比如说:
检验方式分为两种:双侧检验和单侧检验。单侧检验又分为两种:左侧检验和右侧检验。
这几种检验方式的划分很简单:
我们的备择假设:实验组和对照组存在显著差异。其实就是在说是实验组 ≠ 对照组。所以是双侧检验(此时原假设也成为零假设)。
然后我们根据检验方式不同,得到不同的 p 值计算方式。(p 值其实就是计算拒绝域的概率值,放一张图,方便大家更好的理解)
我们来看下假设检验的原假设:实验组和对照组无显著差异。那么该怎么去描述两组实验有差异呢?我们需要一个统计量来描述两组实验。
在 A/B 测试中我们关注的两组实验转换率的差异,所以我们可以通过样本的转换率
来衡量两组实验的差异。所以原假设可以翻译为:
(两者转换率没差别)。
转换率是样本统计量的一种,此外还可以用均值、方差等作为样本统计量。
我们引入检验统计量的概念:根据样本观测结果计算得到的,并据以对原假设和备择假设做出决策的某个样本统计量,称为检验统计量。所以本次 A/B 测试中检验统计量为
。
检验统计量是用于假设检验计算的统计量,实际上是对总体参数的点估计量,但点估计量不能直接作为检验统计量,只有将其标准化后,才能用于度量它与原假设的参数值之间的差异程度。所以我们将检验统计量标准化:
为独立地抽自总体
的一个容量为
的样本的均值。则变量
的均值和方差为:
样本均值的方差:
总体的均值为我们的原假设,即为 0(
),当样本容量较大(n>30)时,我们可以用样本标准差
来表示总体标准差
,此时我们便得到了 z 检验统计量:
z 检验虽然能够进行样本统计量的差异性检验,但是它要求样本容量足够大,这是不一定能够做到。
这时候 t 检验就粉墨登场了,在两独立样本均值检验中,t 值计算公式如下(推导略):
根据自由度
,查 t 值表,找出规定的 t 理论值并进行比较,然后确定显著性水平。
t 检验在使用前需要注意三点:
t 检验统计量较 z 检验统计量多了一个自由度的变量,用来惩罚小样本,增加其拒绝
的难度,因而小样本下采用 t 检验,优于 z 检验。
当样本数量增加时,t 检验会快速收敛于 z 检验。(所以这里用 t 检验算出来也是 1.67)
我们再看下假设检验的原假设:实验组和对照组无显著差异。这一小节我们来讲下显著的概念。
我们统计出的实验组的转化率为 0.3,而对照组的转换率为 0.16。我们是否可以说明实验组比对照组的转换效果要好 0.14?其实更准确的说法是:实验组比对照组的转换效果要好 0~0.28 (
),置信度为 90%。
[0, 0.28] 是我们所说的置信区间 [
],这里的第一个 0.14 是两组样本的均值(
)第二个 0.14 是统计误差,计算方式为
,置信度是我们的算出接受域的概率值 90%。我们可以说:我们有 90% 的把握实验组比对照组的转换效果要好 0~0.28。从概率的角度来解释:我们做 100 次实验,有 90 次的转换率差异是在 0~0.28 之间。
置信区间是一个区间,使得重复实验 n 次具有一定概率(这个概率就是置信度)的结果都落在此区间内。根据置信区间的不同表现,我们可以来判断试验结果显著与否:如果置信区间的上下限同为正/负,则说明试验结果是统计显著的;如果置信区间为一正一负,则说明版本间差异不大。
值得注意的是,置信区间同为正或负时,只能说明试验是统计显著的(也就是试验组和对照组有差异),但是这个差异有可能是非常小,在实际应用中微不足道的。因此,只有兼备统计显著和效果显著两个特征的结果,才能说明该实验是可用,并且值得发布的。
中心极限定理是概率论的重要定理,我们来复习下:
中心极限定理指的:是给定一个任意分布的总体。每次从这些总体中随机抽取 n 个抽样,一共抽 m 次。然后把这 m 组抽样分别求出平均值,这些平均值的分布接近正态分布。
我们注意总体本身的分布不要求正态分布,下图很形象的表达这个点:
从上图我们看到:随着抽样次数增多,样本均值的抽样分布趋向于服从正态分布,且其均值越接近于总体的平均值。
所以正是因为有了中心极限定律,我们才能使用 A/B 测试:通过样本均值来估计总体均值。
而检验统计量这块,我们可以看到当抽样次数达到 30 时,样本均值可以视为总体均值。这也是为什么 z 检验和 t 检验以样本量为 30 做个分界。(当然划分界线没那么严格,29 次也可以用 z 检验)
补充学习大数定律:在无数次独立同分布的随机事件中,事件的频率趋于一个稳定的概率值,这是大数定律。两者在不同的维度上。
上面是通过手算检验统计量,更简单的方法是写个 python 脚本:
x1 = 15
x2 = 8
n1 = n2 = 50
import numpy as np
from statsmodels.stats.proportion import proportions_ztest as ztest
ztest(np.array([x1, x2]), np.array([n1, n2]))
"""
# 源代码计算方式,和评估组同学给出的计算方式一致
输出:(1.663369597, 0.09623847)
"""
x1 x2 顺序倒过来只影响 z 值(相反数),不影响 p 值。
我们知道假设检验的有两类错误:
H0 正确(真实情况) | H0 错误(真实情况) | |
---|---|---|
拒绝 H0(研究结论) | I 类错误 | 正确 |
接受 H0(研究结论) | 正确 | II 类错误 |
I 类错误称之为弃真:实验组和对照组没有显著差异,但我们接受了方案推了全量。减少这种错误的方法就是提高显著性水平,比如 p 值小于 0.05 才算显著,而不是小于 0.1,显著性水平是人为给定的犯一类错误的可以接受的上限(p 值为犯 I 类错误的概率
)。
如果在实验刚开始时,统计显著性的波动非常明显,这可能受到**新奇效应(Novelty Effect)**的影响。对于用户有感知的 A/B 测试,如 UI 改版、新的运营方案、新功能上线等,实验组做的任何改变都可能引起用户的注意,好奇心驱使他们先体验一番,从而导致 A/B 测试中实验组效果一开始优于对照组,p 值极小,实验效果非常显著。但是一段时间过去后,用户对于新的改版不再敏感,实验组效果回落,显著性可能会下降,最后趋于稳定。所以我们可以通过增加实验周期从而避免这种新奇效应的影响。
II 类错误称之为存伪:实验组和对照组有显著差异,但我们没有接受方案。
II 类错误和统计功效 (power) 有关,统计功效可以简单理解为真理能被发现的可能性。统计功效 =
,而
为犯第二类错误的概率。影响统计功效的因素有很多,主要的有三个:统计量、样本量和 I 类错误的概率
。
下图展示了两类错误的联系(这里的
为单边假设,区别于 AB 测试中的双边假设):
一般来说,I 类错误的危害要比 II 类错误的危害要大。
增加样本容量可以同时减少两类错误,那么我们应该需要多少样本容量呢?
统计学里给出了最小样本量计算的公式:
其中,
为 II 类错误的概率,
为 I 类错误的概率,Z 为正态分布的分位数函数,σ 为标准差,Δ 为两组数值的差异(
)。从这个公式可以知道,在其他条件不变的情况下,如果实验两组数值差异越大或者数值的波动性越小,所需要的样本量就越小。
实际 A/B 测试中,我们关注的较多的一类是比例类的数值,如点击率、转化率、留存率等,也就是说结果非 A 即 B。比例类数值的假设检验在统计学中叫做两样本比例假设检验。其最小样本量计算的公式为:
通常设定
为 0.05,
为 0.2。
用 python 算一下:
from statsmodels.stats.power import zt_ind_solve_power
from statsmodels.stats.proportion import proportion_effectsize as es
zt_ind_solve_power(effect_size=es(prop1=0.3, prop2=0.16), alpha=0.05, power=0.8, alternative="two-sided")
"""
138.8426
"""
可以看到,我们应该需要准备 139 个样本。
以上便是 AB 测试的全部内容,才疏学浅,如有错误,还望指证。