测试运行的最佳方法

机器算法验证 r 非参数 kolmogorov-smirnov 测试 随机性
2022-03-31 22:48:31

我有以下示例:

x <- c(rep(1, 8), 0, 1, 0, rep(1, 5), 0, 0, 1, rep(0, 11), 1, 0, 0, 1, 0)
> x
[1] 1 1 1 1 1 1 1 1 0 1 0 1 1 1 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0

1和实际上是名义变量0因子,样本是根据隐藏变量排序的。看起来这个序列不是随机的,1 在这个序列中往往排名较低(即出现得更早)。但是,我想进行统计检验来检验这个假设。

到目前为止,我的解决方案是使用 Wald-Wolfowitz 测试,如下所示:

library(adehabitat)
wawotest(x)

它产生 0.0211 的 p 值,我认为该值足够低,可以拒绝在给定运行中 1 和 0 随机出现的假设。

但是,我读过 Kolmogorov-Smirnov 测试是一个更强大的解决方案,我想在 R 中尝试它,但我不确定我是否给出了正确的命令。这就是我正在运行的:

ks.test(x, 'punif')

这给出了 1,821e-08 的 p 值。我的命令正确吗?我应该考虑其他测试吗?

[编辑]正如@Glen_b 所说,KS 不适合这种情况,所以我会坚持使用 WW。以下是我发现运行此测试的两种最佳方法:

> library(tseries);    runs.test(as.factor(x))
> library(adehabitat); wawotest(x)

我研究了背后的算法runs.test(),它似乎正在执行 Wald-Wolfowitz,即使 p 值略有不同。

无论如何,WW 看起来并不是用于此类测试的最强大的工具,因此请随时提供其他解决方案。

3个回答

我想你把这搞混了。

(i) Kolmogorov Smirnov 检验旨在检验连续分布,而不是离散分布;实际上,您的值包含 0 和 1,但您似乎正在测试连续均匀性。

(ii) 正如所写,看起来这完全忽略了时间顺序。它不是测试你需要拿起什么。

您也许可以将 1 出现的序列中距离的分数(视为分位数)用作数据(尽管它不是连续的独立数据 - 它只出现在离散的位置,每个位置只有一个值 - 所以你'仍然需要为此调整您的空分布)。它不会是 KS 测试,但您可以使用 KS 之类的统计数据作为测试的基础。

例如,如果有n观察,i- 观察可以说发生在iαn+12α分位数0α1(我相信 R 自己的分位数函数中的 9 个备选方案中的许多都对应于具有不同值的该定义α)。然后,您可以测试 1 的分位数是否均匀分布,但您需要进行模拟以获取空值下的测试统计量的分布。

模拟零分布(可能以 0 和 1 的计数为条件)的一个简单替代方法是进行置换测试。(这将涉及聪明的算法来做完整的分布,或排列分布的采样。

但是,您似乎真的在进行趋势测试。事实上,你可能会用简单的东西来做更好的事情,比如对位置的逻辑回归,甚至是单调 GAM 类型的模型(同样,可能通过逻辑回归)。


编辑:这是在 R 中执行的先前建议的逻辑回归:

x <- c(rep(1, 8), 0, 1, 0, rep(1, 5), 0, 0, 1, rep(0, 11), 1, 0, 0, 1, 0)
t <- seq_along(x)                       # Rank order by position (1,2,3,...)
plot(x~t)                               # Show the sequence of 1's and 0's
logistfit <- glm(x~t,family=binomial)   # fit a straight line in the logits
summary(logistfit)                      # show GLM regression table output
f <- fitted(logistfit)                  # fit is estimated P(X=1|t)
lines(f~t,col=4)                        # plot that fit

这是模型的输出(删除了一些不太有趣的行):

Coefficients:
            Estimate Std. Error z value Pr(>|z|)   
(Intercept)  2.77412    1.01415   2.735  0.00623 
t           -0.15912    0.05225  -3.046  0.00232     # <=== the line we want

    Null deviance: 48.492  on 34  degrees of freedom
Residual deviance: 34.087  on 33  degrees of freedom
AIC: 38.087

glm 拟合的 p 值为0.00232. 它表明 1 的概率与 1 相对于排序变量随机放置的概率不一致。由于系数为负,因此随着位置的增加,1 的概率总体降低。

这是情节:

使用逻辑回归拟合按等级顺序绘制 1 和 0

你的既定目标是评估是否

1 往往排名较低(即出现较早)

这不是通过运行来衡量的,而是通过排名来衡量的。 使用Wilcoxon(又名Mann-Whitney)测试。


这个测试在概念上和计算上都很简单,但相当强大。数据使用数字按出现顺序排列1,2,,n(在哪里n=35在这种情况下)。每组内的排名相加:总和n0=18等级对应于零和总和n1=17等级对应的。为了补偿不同数量的 0 和 1,从每个中减去可能的最小总和(等于1+2++ni=(ni+12)团体用i,i=0,1)。如果那些真的倾向于首先出现,那么它们调整后的秩和将大大小于零的秩和。这可以通过假设统计量的渐近正态分布转换为 Z 分数,或者可以通过排列分布找到更准确的 p 值。下面的代码说明了这两种方法。

对于这些数据,零出现在等级

9 11 17 18 20 21 22 23 24 25 26 27 28 29 30 32 33 35

而那些出现在队伍中

1  2  3  4  5  6  7  8 10 12 13 14 15 16 19 31 34

调整后的等级总和为U=47. 正态近似估计其 p 值0.0002339. 在本案中,这个小值证明了这个测试的力量。估计有一百万次重复的置换分布给出的 p 值为0.000264. 它是准确的±0.000016(这是一个标准错误)。任一 p 值都为您提供了充分的基础来拒绝零和一随机散布在整个序列中的零假设。

这是排列分布的直方图U对这些数据进行统计。

数字

红色垂直线标记了实际的测试统计量。这显然是极端的。

虽然看起来可能不像,但这个测试是作为双尾测试进行的(通过取两个调整后的秩和中较小的一个)。它测试排名是否有任何差异,而不仅仅是排名是否更早。


下面是R制作图形并计算 p 值的(可重现的)代码。这个大型模拟运行大约需要十秒钟。(通常只需要几千次重复。一百万次用于表明在这种情况下正常近似效果很好。)减少第replicate25 行的第一个参数以实现更快的运行时间。

x <- c(1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0)
#
# Wilcoxon test.
#
Wilcoxon <- function(x) {
  n <- length(x)
  n0 <- sum(x==0)
  n1 <- sum(x==1)
  u0 <- sum((1:n)[x==0]) - choose(n0+1, 2)
  u1 <- sum((1:n)[x==1]) - choose(n1+1, 2)
  u <- min(u0, u1)

  m.u <- n0 * n1 / 2
  s.u <- sqrt(n0 * n1 * (n+1) / 12)
  Z <- (u - m.u)/s.u
  p <- pnorm(Z)
  return(c(U=u, Z=Z, p.value=p))
}
stats <- Wilcoxon(x)
#
# Permutation test.
#
set.seed(17)
U <- replicate(1e6, Wilcoxon(sample(x, length(x)))["U"])
hist(U, main="Permutation Distribution", )
abline(v = stats["U"], lwd=2, col="Red")
#
# Summary.
#
message("Normal approximation: ", signif(stats["p.value"], 4), 
        "  Permutation estimate: ", signif(mean(c(1, U <= stats["U"])), 4),
        " +/- ", signif(sd(c(1, U <= stats["U"])) / sqrt(1 + length(U)), 2))

您还可以使用基于最长冲程长度 (LLHR) 的测试。在您的示例中,LLHR 太大-> 您应该拒绝样本来自伯努利 B(1/2) 分布的假设。