A/B 测试使用什么统计测试?

机器算法验证 测试
2022-03-13 03:51:41

我们有两个队列,每个队列有 1000 个样本。我们对每个队列测量 2 个数量。第一个是二进制变量。第二个是遵循重尾分布的实数。我们想要评估哪个队列在每个指标上表现最好。有很多统计检验可供选择:人们建议使用 z 检验,其他人使用 t 检验,其他人则使用 Mann-Whitney U.

  • 对于我们的案例,我们应该为每个指标选择哪些测试或测试?
  • 如果一项测试表明群组之间存在显着差异,而另一项测试表明差异不显着,会发生什么?
3个回答

鉴于您的两个指标是 1)二元和 2)重尾,您应该避免假设正态分布的 t 检验。

我认为 Mann-Whitney U 是您的最佳选择,即使您的分布接近正常,也应该足够有效。

关于你的第二个问题:

如果一项测试表明群组之间存在显着差异,而另一项测试表明差异不显着,会发生什么?

如果统计差异是临界的并且数据具有“混乱”的样本分布,这种情况并不少见。这种情况要求分析师仔细考虑每个统计检验的所有假设和限制,并给予违反假设次数最少的统计检验最大权重。

假设正态分布。有各种测试正常性,但这不是故事的结尾。即使与正态性存在一些偏差,一些测试在对称分布上也能很好地工作,但在偏态分布上效果不佳。

作为一般经验法则,我建议您不要运行任何明显违反其假设的测试。

编辑:对于第二个变量,只要转换是保序的,将变量转换为正态分布(或至少接近)的变量可能是可行的。您需要对转换为两个群组产生正态分布有充分的信心。如果您将第二个变量拟合为对数正态分布,则对数函数将其转换为正态分布。但是如果分布是帕累托(幂律),那么就不会转换为正态分布。

编辑:正如此评论中所建议的,您绝对应该考虑将贝叶斯估计作为 t 检验和其他零假设显着性检验 (NHST) 的替代方法。

对于实值数据,您可能还需要考虑根据数据的引导生成自己的测试统计量。当您处理非正态总体分布或试图围绕没有方便分析解决方案的参数建立置信区间时,这种方法往往会产生准确的结果。(在你的情况下前者是正确的。我只提到后者是为了上下文。)

对于您的实值数据,您将执行以下操作:

  1. 汇集你的两个同伙。
  2. 从池中抽取两组 1000 个元素,并进行替换。
  3. 计算两组样本均值的差异。
  4. 重复步骤 2 和 3 数千次以开发这些差异的分布。

获得该分布后,计算实际样本的均值差异,并计算 p 值。

我支持@MrMeritology 的回答。实际上,我想知道 MWU 测试是否会不如独立比例测试强大,因为我学习并曾经教过的教科书说 MWU 只能应用于序数(或间隔/比率)数据。

但我的模拟结果如下图所示,表明 MWU 检验实际上比比例检验稍强,同时很好地控制了 I 类错误(第 1 组的总体比例=0.50)。

在此处输入图像描述

第 2 组的人口比例保持在 0.50。每个点的迭代次数为 10,000 次。我在没有 Yate 修正的情况下重复了模拟,但结果是一样的。

library(reshape)

MakeBinaryData <- function(n1, n2, p1){
  y <- c(rbinom(n1, 1, p1), 
        rbinom(n2, 1, 0.5))
  g_f <- factor(c(rep("g1", n1), rep("g2", n2)))
  d <- data.frame(y, g_f)
  return(d)
}

GetPower <- function(n_iter, n1, n2, p1, alpha=0.05, type="proportion", ...){
  if(type=="proportion") {
    p_v <- replicate(n_iter, prop.test(table(MakeBinaryData(n1, n1, p1)), ...)$p.value)
  }

  if(type=="MWU") {
    p_v <- replicate(n_iter, wilcox.test(y~g_f, data=MakeBinaryData(n1, n1, p1))$p.value)
  }

  empirical_power <- sum(p_v<alpha)/n_iter
  return(empirical_power)
}

p1_v <- seq(0.5, 0.6, 0.01)
set.seed(1)
power_proptest <- sapply(p1_v, function(x) GetPower(10000, 1000, 1000, x))
power_mwu <- sapply(p1_v, function(x) GetPower(10000, 1000, 1000, x, type="MWU"))