可以检验两组或者多组样本的均值是否具备显著性差异;由四个前提假设:
方差分析的核心思想®:差异是不是显著性,关键是要看这个差异是采样的偶然性引起的,还是分布本身引起的;
我们假设只有两种算法 a 和 b 参与了 A/B 测试。为了检验这些算法导致的转化率,是不是存在显著的差异,我们进行一个为期 10 天的测试,每天都为每种算法获取一个转化率,如下表:
我们就算了**SST、SSM 和 SSE。**计算公式如下:
SST 表示所有采样数据的因变量方差;
由此可以看出,SST 是由 SSM 和 SSE 构成的。
如果在 SST 中,SSM 的占比更大,那么说明因素对因变量的差异具有更显著的影响。
如果 SSE 的占比更大,那么说明采样误差对因变量的差异具有更显著的影响。
我们使用这两部分的比例来衡量显著性,并把这个比例称为 F 值.具体公式如下:
在这个公式中,s是水平的个数,n为样本的总数量,s-1为分布的自由度;n-s为误差的自由度;
在我们的案例中,F=(0.00018/(2-1))/(0.01652/(20-2))=0.196125908。有了 F 值,我们需要根据 F 检验值的临界表来查找对应的的P 值。我列出了这张表的常见内容,你可以看看。
在咱们的案例中,n=20,m=s-1=1,所以对应的 F 值4.414。而我们计算得到的 F 值为 0.196,远远小于 4.414,因此说明差异没有显著性。
虽然算法 a 所导致的平均转化率要比算法 b 的相对高出约2%(要注意,2% 的相对提升在转化率中已经算很高了),但是由于差异没有显著性,所以这个提升的偶然性很大,并不意味着算法 a 比算法 b 更好。
除了手动计算外,我们可以用python的代码来验证手动计算的正确性。
首先,我们要确保自己安装了python的扩展包statsmodels,如果没有安装采用下面的命令:
pip install -U statsmodels
我们可以把下列数据输入一个 oneway.csv 文件。
algo,ratio
a,0.29
a,0.36
a,0.32
a,0.29
a,0.34
a,0.24
a,0.27
a,0.29
a,0.31
a,0.27
b,0.29
b,0.33
b,0.31
b,0.30
b,0.31
b,0.26
b,0.25
b,0.30
b,0.28
b,0.29
安装完了 statsmodels,并建立了数据文件 oneway.csv,我们就可以运行下面这段 Python 代码来进行 F 检验了。
import pandas as pd
from statsmodels.formula.api import ols
from statsmodels.stats.anova import anova_lm
import scipy.stats as ss
# 读取数据,d1 对应于算法 a,d2 对应于算法 b
df = pd.read_csv("/Users/shenhuang/Data/oneway.csv") # 设置为你自己的文件路径
d1 = df[df['algo'] == 'a']['ratio']
d2 = df[df['algo'] == 'b']['ratio']
# 检测两个水平的正态性
print(ss.normaltest(d1))
print(ss.normaltest(d2))
# 检测两个水平的方差齐性
args = [d1, d2]
print(ss.levene(*args))
# F 检验的第一种方法
print(ss.f_oneway(*args))
# F 检验的第二种方法
model = ols('ratio ~ algo', df).fit()
anovat = anova_lm(model)
print(ano
我们假设用于 A/B 测试的两个算法是相互独立且随机的,所以这里只检测了正态分布性和方差齐性。
其中,ss.normaltest 分别测试了两个水平的正态分布:
NormaltestResult(statistic=0.16280747339563784, pvalue=0.9218214431590781)
NormaltestResult(statistic=0.4189199849120419, pvalue=0.8110220857858036)
ss.normaltest 的原假设是数据符合正态分布,两次验 P 值都是远远大于 0.05 的,所以原假设成立,这两者都符合正态分布;
而 ss.levene 分析了两者的方差齐性,同样 P 值都都是远远大于 0.05,因此符合方差齐的前提。
LeveneResult(statistic=0.7944827586206901, pvalue=0.38450823419725666)
ss.f_oneway 和 anova_lm 都可以进行F 检验。ss.f_oneway 给出的结果比较简洁。
F_onewayResult(statistic=0.19612590799031476, pvalue=0.663142430745588)
而 anova_lm 提供了更多的信息,但是两种 F 检验函数都证明了我们之前的手动推算结果是正确的。
df sum_sq mean_sq F PR(>F)
algo 1.0 0.00018 0.000180 0.196126 0.663142
Residual 18.0 0.01652 0.000918 NaN NaN
方差分析可以帮助我们检测差异的显著性,它分析的内容是受一个或多个因素影响的因变量在不同水平分组的差异。不过单因素的方差分析要去因变量属于正态分布,并具有方差齐性。如果因变量的分布明显非正态分布,或者方差的差异很显著,那么我们就不能直接使用这种方法;
对于方差不齐的情况,我们可以选择适当的函数,例如对数,倒数等等,对原始数据进行转换,直到方差齐性显著;或者剔除明显属于”均值±标准差"之外的数据。
对于非正态分布的数据,我们也可以使用非参数的分析;非参数检验是在总体的方差知道很少的情况下,利用样本的数据对总体的分布形态等进行推断的方法。名字中的“非参数”的由来,就是因为这种检验方法在推断过程中不涉及有关总体分布的参数,而是只进行分布位置,分布形状之间的比较,因此不受总体分布的限定,使用范围比较广,常见的非参数检验包括二项分布检验。k-s检验,卡方检验等等;