1 min read

A/B检验Python实现

A/B testing | Python

A/B 检验,平均值的高低的单纯比较,会忽略一个问题: 计算的结果可能是受到随机严重干扰的。 无论是统计上证明,两组检验变量同分布还是同均值, 比较好的方法是,使用大数定理。 使用大数定理,实操中常见的方法是,重复抽样,也就是 Bootstrap,或者更加严密的Permutations。

两者的思想是,对A、B分布的数据,进行重复抽样,形成若干个对照组,计算同样检验变量的测试值,然后再来比较。

具体可以看Python代码来理解。

def draw_perm_reps(data_1, data_2, func, size=1):
    """Generate multiple permutation replicates."""

    # Initialize array of replicates: perm_replicates
    perm_replicates = np.empty(size)

    for i in range(size):
        # Generate permutation sample
        perm_sample_1, perm_sample_2 = permutation_sample(data_1,data_2)

        # Compute the test statistic
        perm_replicates[i] = func(perm_sample_1, perm_sample_2)

    return perm_replicates

假设函数draw_perm_repsdata_1, data_2分别代表两组数,也就是A组和B组。 func代表使用的函数,如果是均值,可以使用numpy包的np.meansize代表重复抽样次数。 permutation_sample函数定义如下:

def permutation_sample(data1, data2):
    """Generate a permutation sample from two data sets."""

    # Concatenate the data sets: data
    data = np.concatenate((data1, data2))

    # Permute the concatenated array: permuted_data
    permuted_data = np.random.permutation(data)

    # Split the permuted array into two: perm_sample_1, perm_sample_2
    perm_sample_1 = permuted_data[:len(data1)]
    perm_sample_2 = permuted_data[len(data1):]

    return perm_sample_1, perm_sample_2

假设两组数来自统一分布,一次可以直接合并。 这里隐含的条件是如果表示统一分布,最后直接拒绝原假设即可。 np.concatenate函数将两组数合并, np.random.permutation将数组随机重复抽样。 permuted_data[:len(data1)]permuted_data[len(data1):]重新分ab组。

例子如下。

假设:demsreps来自同分布。

# Construct arrays of data: dems, reps
dems = np.array([True] * 153 + [False] * 91)
reps = np.array([True] * 136 + [False] * 35)

def frac_yay_dems(dems, reps):
    """Compute fraction of Democrat yay votes."""
    frac = np.sum(dems) / len(dems)
    return frac

# Acquire permutation samples: perm_replicates
perm_replicates = draw_perm_reps(dems, reps, frac_yay_dems, 10000)

# Compute and print p-value: p
p = np.sum(perm_replicates <= 153/244) / len(perm_replicates)
print('p-value =', p)
<script.py> output:
    p-value = 0.0002

p-value = 0.0002,因此显著,可以拒绝原假设。