重采样/模拟方法:蒙特卡洛法、自举法、折刀法、交叉验证法、随机化测试和排列测试

机器算法验证 r 引导程序 重采样 折刀 置换检验
2022-02-03 22:30:50

我试图了解不同重采样方法(蒙特卡洛模拟、参数自举、非参数自举、jackknifing、交叉验证、随机化测试和置换测试)之间的区别及其在我自己的上下文中使用 R 的实现。

假设我有以下情况——我想使用Y变量 ( Yvar) 和X变量 ( Xvar) 执行 ANOVA。Xvar是分类的。我对以下内容感兴趣:

(1) p值的意义——错误发现率

Xvar(2)层次 效应大小

Yvar <- c(8,9,10,13,12, 14,18,12,8,9,   1,3,2,3,4)
Xvar <- c(rep("A", 5),  rep("B", 5),    rep("C", 5))
mydf <- data.frame (Yvar, Xvar)

您能否用明确的工作示例来解释采样差异,这些重采样方法是如何工作的?

编辑: 这是我的尝试:

Bootstrap 10个自举样本,有替换的样本数,表示样本可以重复

boot.samples <- list()
for(i in 1:10) {
   t.xvar <- Xvar[ sample(length(Xvar), length(Xvar), replace=TRUE) ]
   t.yvar <- Yvar[ sample(length(Yvar), length(Yvar), replace=TRUE) ]
   b.df <- data.frame (t.xvar, t.yvar) 
   boot.samples[[i]] <- b.df 
}
str(boot.samples)
 boot.samples[1]

置换: 10个置换样本,样本数不替换

 permt.samples <- list()
    for(i in 1:10) {
       t.xvar <- Xvar[ sample(length(Xvar), length(Xvar), replace=FALSE) ]
       t.yvar <- Yvar[ sample(length(Yvar), length(Yvar), replace=FALSE) ]
       b.df <- data.frame (t.xvar, t.yvar) 
       permt.samples[[i]] <- b.df 
    }
    str(permt.samples)
    permt.samples[1]

蒙特卡罗模拟

尽管术语“重采样”通常用于指代任何重复的随机或伪随机采样模拟,但当从已知的理论分布进行“重采样”时,正确的术语是“蒙特卡洛”模拟。

我不确定上述所有条款以及我的上述编辑是否正确。我确实找到了一些关于jacknife的信息,但我无法适应我的情况。

2个回答

我们可以找到不同的重采样方法,或者松散地称为“模拟”方法,它们取决于样本的重采样改组关于适当的术语可能存在意见分歧,但以下讨论试图概括和简化适当文献中可用的内容:

重采样方法用于(1)通过使用数据子集(例如 Jackknifing)或从一组数据点中随机抽取替换(例如 bootstrapping)来估计样本统计的精度/准确性(2)在执行显着性时交换数据点上的标签测试(排列测试,也称为精确测试、随机化测试或重新随机化测试)(3)使用随机子集验证模型(引导、交叉验证)(参见维基百科:重新采样方法

自举

Bootstrapping是一种统计方法,用于通过从原始样本中进行放回抽样来估计估计器的抽样分布”。该方法将准确性度量(根据偏差方差置信区间预测误差或其他一些此类度量定义)分配给样本估计。

自举的基本思想是从样本数据(样本→总体)推断总体可以通过对样本数据重新采样并对(重新采样→样本)执行推断来建模。由于总体是未知的,因此样本统计量与其总体值的真实误差是不可知的。在 bootstrap-resamples 中,“人口”实际上是样本,这是已知的;因此,来自重新采样数据→“真实”样本的推理质量是可测量的。”参见维基百科

Yvar <- c(8,9,10,13,12, 14,18,12,8,9,   1,3,2,3,4)

#To generate a single bootstrap sample
sample(Yvar, replace = TRUE) 

 #generate 1000 bootstrap samples
boot <-list()
for (i in 1:1000) 
   boot[[i]] <- sample(Yvar,replace=TRUE)

在单变量问题中,通常可以接受对带有替换的单个观察值进行重新采样(“案例重新采样”)。这里我们用replacement对数据进行重采样,重采样的大小必须等于原始数据集的大小。

在回归问题中, 案例重采样是指对单个案例进行重采样的简单方案 - 通常是回归问题中的数据集行,解释变量通常是固定的,或者至少观察到比响应变量具有更多控制。此外,解释变量的范围定义了可从中获得的信息。因此,重新采样案例意味着每个引导样本都会丢失一些信息(请参阅Wikipedia)。因此,对数据行进行采样是合乎逻辑的Yvar

Yvar <- c(8,9,10,13,12, 14,18,12,8,9,   1,3,2,3,4)
Xvar <- c(rep("A", 5),  rep("B", 5),    rep("C", 5))
mydf <- data.frame (Yvar, Xvar)    

boot.samples <- list()
for(i in 1:10) {
   b.samples.cases <- sample(length(Xvar), length(Xvar), replace=TRUE) 
   b.mydf <- mydf[b.samples.cases,] 
   boot.samples[[i]] <- b.mydf
}
str(boot.samples)
 boot.samples[1]

您可以看到一些案例重复出现,因为我们正在采样替换。

参数引导- 参数模型通常通过最大似然拟合数据,并从该拟合模型中抽取随机数样本。通常抽取的样本与原始数据具有相同的样本大小。然后是数量或估计, 感兴趣的是从这些数据中计算出来的。与其他 bootstrap 方法一样,这个抽样过程重复了很多次。在 bootstrap 方法的抽样阶段使用参数模型会导致程序与通过应用基本统计理论获得的程序不同推断相同的模型。”(参见维基百科)。以下是具有均值和标准偏差参数的正态分布假设的参数引导。

Yvar <- c(8,9,10,13,12, 14,18,12,8,9,   1,3,2,3,4)

# parameters for Yvar 
mean.y <- mean(Yvar)
sd.y <- sd(Yvar)

#To generate a single bootstrap sample with assumed normal distribution (mean, sd)
rnorm(length(Yvar), mean.y, sd.y)

 #generate 1000 bootstrap samples
boot <-list()
for (i in 1:1000) 
   boot[[i]] <- rnorm(length(Yvar), mean.y, sd.y)

引导程序还有其他变体,请查阅维基百科页面或任何关于重采样的好的静态书籍。

杰克尼夫

“参数的折刀估计量是通过系统地从数据集中遗漏每个观察值并计算估计值,然后找到这些计算的平均值来找到的。给定大小为 N 的样本,通过汇总每个N − 1估计值的估计值来找到折刀估计量在样本中。” 参见:wikipedia下面展示了如何将Yvar.

jackdf <- list()
jack <- numeric(length(Yvar)-1)

for (i in 1:length (Yvar)){

for (j in 1:length(Yvar)){
     if(j < i){ 
            jack[j] <- Yvar[j]
}  else if(j > i) { 
             jack[j-1] <- Yvar[j]
}
}
jackdf[[i]] <- jack
}
jackdf

“常规的 bootstrap 和 jackknife,从子样本之间的统计量的可变性而不是参数假设来估计统计量的可变性。对于更一般的 jackknife,删除-m 观察 jackknife,bootstrap 可以被视为随机近似它。两者都产生相似的数值结果,这就是为什么每个都可以被看作是另一个的近似。在 Bootstrap vs Jacknife 上查看这个问题。

随机化测试

“在参数测试中,我们从一个或多个群体中随机抽样。我们对这些群体做出某些假设,最常见的是它们以等方差正态分布。我们建立一个以参数为框架的零假设,通常形式为 m1 -m2 = 0 。我们使用我们的样本统计量作为相应总体参数的估计值,并计算检验统计量(例如在检验时)。例如:在学生的 t 检验中,当方差未知但被考虑时,均值的差异相等。感兴趣的假设是 H0: m1 = m2。替代假设之一将被表述为:HA: m1 < m2. 给定从总体 1 和 2 中抽取的两个样本,假设它们是方差相等的正态分布总体,并且样本是从每个总体中独立随机抽取的,那么可以详细说明其分布已知的统计量来检验H0

避免这些分布假设的一种方法是现在称为非参数、排名顺序、类似排名和无分布统计的方法。这些无分布统计通常被批评为不如基于假设总体呈正态分布的类似测试“有效”。

另一种替代方法是随机化方法- “随机分配等级到观察值的过程,与一个人对观察值所属样本的了解无关。随机化测试使用这样的程序,但通过对观察结果而不是联合进行操作来实现观察的排名。出于这个原因,一个类似统计量的分布(一个样本中的观察之和)不能很容易地制成表格,尽管理论上可以枚举这样的分布“(

随机化测试几乎在每个方面都与参数测试不同。(1) 不要求我们从一个或多个群体中随机抽样——事实上我们通常没有随机抽样。(2)我们很少考虑数据来自的人群,没有必要假设任何关于正态性或同方差性(3)我们的零假设与参数无关,但措辞相当模糊,因为,例如,假设治疗对参与者的表现没有影响。(4)因为我们不关心人群,所以我们不关心估计(甚至测试)这些人群的特征(5)我们确实计算了一些一种测试统计量,但是我们不会将该统计量与表格分布进行比较。反而,我们将其与我们在组间重复随机化数据时获得的结果进行比较,并计算每次随机化的相应统计量。(6) 与参数测试相比,随机化测试强调了随机分配参与者进行治疗的重要性。”

非常流行的随机化测试类型是置换测试。如果我们的样本量是 12 和 5,则可能的总排列是C(12,5) = 792如果我们的样本量为 10 和 15,那么可能有超过 320 万个安排。这是计算挑战:然后呢? 样品当可能排列的宇宙太大而无法列举时,为什么不从这个宇宙中独立地随机抽样排列呢?然后可以将这一系列样本上的检验统计量的分布制成表格,计算其均值和方差,并估计与假设检验相关的错误率。

排列测试

根据维基百科, “置换检验(也称为随机化检验再随机化检验精确检验)是一种统计显着性检验,其中通过计算所有可能值来获得零假设下的检验统计量分布在观察数据点上的标签重新排列下的检验统计量。任何检验统计量都存在置换检验,无论其分布是否已知。因此,人们总是可以自由选择最能区分假设和备选方案的统计量最大限度地减少损失。”

permutation 和 bootstrap 的区别在于bootstrap sample with replacement 和 permutations sample without replacement在任何一种情况下,观察的时间顺序都会丢失,因此波动性聚类也会丢失——从而确保样本处于无波动性聚类的零假设下。

排列总是具有所有相同的观察结果,因此它们更像原始数据而不是引导样本。期望是置换测试应该比引导测试更敏感。排列破坏了波动性聚类,但不增加任何其他可变性

请参阅关于排列与引导的问题- “排列测试最适合测试假设,引导最适合估计置信区间”。

因此,在这种情况下要执行置换,我们可以replace = FALSE在上面的引导示例中进行更改。

Yvar <- c(8,9,10,13,12, 14,18,12,8,9,   1,3,2,3,4)
     #generate 1000 bootstrap samples
       permutes <-list()
    for (i in 1:1000) 
       permutes[[i]] <- sample(Yvar,replace=FALSE)

如果有多个变量,仅选择行并重新排列顺序不会有任何区别,因为数据将保持不变。所以我们重新洗牌 y 变量。你所做的事情,但我认为我们不需要对两者进行双重洗牌(就像你所做的那样)。xy variables

Yvar <- c(8,9,10,13,12, 14,18,12,8,9,   1,3,2,3,4)
Xvar <- c(rep("A", 5),  rep("B", 5),    rep("C", 5))
mydf <- data.frame (Yvar, Xvar)

 permt.samples <- list()
    for(i in 1:10) {
       t.yvar <- Yvar[ sample(length(Yvar), length(Yvar), replace=FALSE) ]
       b.df <- data.frame (Xvar, t.yvar) 
       permt.samples[[i]] <- b.df 
    }
    str(permt.samples)
    permt.samples[1]

蒙特卡罗方法

“蒙特卡洛方法(或蒙特卡洛实验)是一类广泛的计算算法,它依赖于重复随机抽样来获得数值结果;通常,为了获得未知概率实体的分布,需要多次运行模拟。这个名字来了从技术的相似性到在真正的赌场中播放和记录结果的行为。”参见维基百科

“在应用统计中,蒙特卡罗方法通常用于两个目的:

(1) 在实际数据条件下比较小样本的竞争统计数据。尽管对于从渐近条件(即无限样本量和无限小处理效应)的经典理论分布(例如,正态曲线、柯西分布)得出的数据,可以计算统计的 I 类误差和功效特性,但实际数据通常可以没有这样的分布。

(2) 提供比精确检验(例如置换检验(通常无法计算))更有效的假设检验实现,同时比渐近分布的临界值更准确。

蒙特卡洛方法也是近似随机化和排列测试之间的一种折衷近似随机化测试基于所有排列的指定子集(这需要对已考虑的排列进行潜在的大量内务管理)。蒙特卡洛方法基于指定数量的随机绘制的排列如果排列被绘制两次或更频繁地进行交换,则精度会略有下降,从而不必跟踪已经选择了哪些排列)。”

MC 和 Permutation 测试有时统称为随机化测试不同之处在于 MC​​ 我们对置换样本进行采样,而不是使用所有可能的组合 [参见] 21

交叉验证

交叉验证之外的想法是模型应该使用未用于拟合模型的数据进行测试。交叉验证可能最常用于预测的上下文中。

“交叉验证是一种用于验证预测模型的统计方法。数据的子集被保留用作验证集;模型适合剩余数据(训练集)并用于预测验证集。平均跨验证集的预测质量产生预测准确性的整体度量。

一种形式的交叉验证一次只留下一个观察结果;这类似于折刀。另一种是K 折交叉验证,将数据拆分为 K 个子集;每个都被依次作为验证集。”参见Wikipedia。交叉验证通常使用定量数据完成。您可以以某种方式将定性(因子数据)转换为定量数据以拟合线性模型并测试该模型。以下是简单的保留策略,其中 50% 的数据用于模型预测,而其余数据用于测试。假设Xvar也是定量变量。

    Yvar <- c(8,9,10,13,12, 14,18,12,8,9,   1,3,2,3,4)
    Xvar <- c(rep(1, 5),  rep(2, 5),    rep(3, 5))
    mydf <- data.frame (Yvar, Xvar)
    training.id <- sample(1:nrow(mydf), round(nrow(mydf)/2,0), replace = FALSE)
    test.id <- setdiff(1:nrow(mydf), training.id)
   # training dataset 
    mydf.train <- mydf[training.id]
   
    #testing dataset 
    mydf.test <- mydf[test.id]

与引导和置换测试不同,用于训练和测试的交叉验证数据集是不同的。下图总结了不同方法的重采样。

在此处输入图像描述

希望这个对你有帮助。

这是我的贡献。

数据

Yvar <- c(8,9,10,13,12,
          14,18,12,8,9,
          1,3,2,3,4)
Xvar <- rep(LETTERS[1:3], each=5)
mydf <- data.frame(Yvar, Xvar)

蒙特卡洛

我将蒙特卡洛视为一种获得(结果)随机变量分布的方法,这是其他(输入)随机变量的非平凡函数的结果。我没有立即看到与当前 ANOVA 分析的重叠,可能其他论坛成员可以在这里提供他们的意见。

自举

目的是了解从观察样本计算的统计数据的不确定性。例如:我们可以计算出 Yvar 的样本均值是 8.4,但我们对 Yvar 的总体均值有多大把握?诀窍是将样本当作总体,并从该假总体中多次抽样。

n <- 1000
bootstrap_means <- numeric(length=n)
for(i in 1:n){
   bootstrap_sample <- sample(x=Yvar, size=length(Yvar), replace=TRUE)
   bootstrap_means[i] <- mean(bootstrap_sample)
}
hist(bootstrap_means)

我们只是取样,没有假设任何参数分布。这是非参数引导程序例如,如果您愿意假设 Xvar 是正态分布的,您还可以rnorm(...)使用估计的均值和标准差从正态分布 ( ) 中采样,这将是参数引导程序

其他用户可能会就Xvar关卡的影响大小给出引导程序的应用程序?

折刀

折刀似乎有点过时了。为了完整起见,您可以或多或少地将其与引导程序进行比较,但这里的策略是看看如果我们遗漏一个观察结果会发生什么(并对每个观察结果重复此操作)。

交叉验证

在交叉验证中,您将(通常很大的)数据集拆分为训练集和验证集,以查看您的估计模型能够如何预测验证集中的值。我个人还没有看到将交叉验证应用于 ANOVA,所以我更愿意将这部分留给其他人。

随机化/排列测试

请注意,术语尚未达成一致。请参阅随机化测试和排列测试之间的差异

原假设是 A、B 和 C 组的种群之间没有差异,因此我们是否随机交换 Xvar 的 15 个值的标签并不重要。如果最初观察到的 F 值(或其他统计量)与随机交换标签后获得的值不一致,那么它可能确实很重要,并且可以拒绝原假设。

observed_F_value <- anova(lm(Yvar ~ Xvar))$"F value"[1]

n <- 10000
permutation_F_values <- numeric(length=n)

for(i in 1:n){
   # note: the sample function without extra parameters defaults to a permutation
   temp_fit <- anova(lm(Yvar ~ sample(Xvar)))
   permutation_F_values[i] <- temp_fit$"F value"[1]
}

hist(permutation_F_values, xlim=range(c(observed_F_value, permutation_F_values)))
abline(v=observed_F_value, lwd=3, col="red")
cat("P value: ", sum(permutation_F_values >= observed_F_value), "/", n, "\n", sep="")

直方图

不过,在复杂设计的情况下,请注意重新分配标签的方式。另请注意,在方差不等的情况下,可交换性的原假设首先不正确,因此该置换检验不正确。

在这里,我们没有明确地遍历所有可能的标签排列,这是对 P 值的蒙特卡罗估计。使用小型数据集,您可以遍历所有可能的排列,但上面的 R 代码更容易理解。