H0에서 부트 스트랩을 사용하여 두 가지 방법의 차이에 대한 테스트 수행 : 그룹 내 또는 풀링 된 샘플 내에서 교체


18

두 개의 독립적 그룹이있는 데이터가 있다고 가정하십시오.

g1.lengths <- c (112.64, 97.10, 84.18, 106.96, 98.42, 101.66)

g2.lengths <- c (84.44, 82.10, 83.26, 81.02, 81.86, 86.80, 
                     85.84, 97.08, 79.64, 83.32, 91.04, 85.92,
                     73.52, 85.58, 97.70, 89.72, 88.92, 103.72,
                     105.02, 99.48, 89.50, 81.74)

group = rep (c ("g1", "g2"), c (length (g1.lengths), length (g2.lengths)))

lengths = data.frame( lengths = c(g1.lengths, g2.lengths), group)

g1에 6 개의 관측치가 있고 g2에 22 개의 관측치 있는 경우 그룹당 샘플 크기가 바이어스 됨이 분명합니다 . 전통적인 분산 분석은 임계 값이 0.05 (p 값은 0.0044 )로 설정 될 때 그룹마다 다른 평균을 갖도록 제안합니다 .

summary (aov (lengths~group, data = lengths))  

저의 목표는 평균 차이를 비교하는 것이므로 이러한 불균형 및 작은 표본 데이터는 전통적인 접근 방식으로 부적절한 결과를 제공 할 수 있습니다. 따라서 순열 테스트와 부트 스트랩을 수행하고 싶습니다.

퍼미션 테스트

귀무 가설 (H0)은 그룹의 평균이 동일하다는 것을 나타냅니다. 순열 테스트에서 이러한 가정은 그룹을 하나의 샘플로 풀링하여 정당화됩니다. 이렇게하면 두 그룹에 대한 표본이 동일한 분포에서 추출됩니다. 풀링 된 데이터에서 반복 샘플링 (또는보다 정확하게-셔플 링)을 수행하면 새로운 방식으로 관측치가 샘플에 재 할당 (셔플)되고 테스트 통계가 계산됩니다. 이 n 번 수행하면 H0이 참인 가정하에 테스트 통계의 샘플링 분포가 제공됩니다. 마지막으로, H0 하에서 p 값은 검정 통계량이 관측 값과 같거나이를 초과 할 확률입니다.

s.size.g1 <- length (g1.lengths)
s.size.g2 <- length (g2.lengths)

pool <- lengths$lengths
obs.diff.p <- mean (g1.lengths) - mean (g2.lengths)
iterations <- 10000
sampl.dist.p <- NULL

set.seed (5)
for (i in 1 : iterations) {
        resample <- sample (c(1:length (pool)), length(pool))

        g1.perm = pool[resample][1 : s.size.g1]
        g2.perm = pool[resample][(s.size.g1+1) : length(pool)]
        sampl.dist.p[i] = mean (g1.perm) - mean (g2.perm) 
}
p.permute <- (sum (abs (sampl.dist.p) >= abs(obs.diff.p)) + 1)/ (iterations+1)

순열 테스트의보고 된 p 값은 0.0053 입니다. OK, 올바르게 수행하면 순열과 파라 메트릭 ANOVA는 거의 동일한 결과를 제공합니다.

병줄

우선, 샘플 크기가 너무 작을 때 부트 스트랩이 도움이되지 않는다는 것을 알고 있습니다. 이 포스트는 더 나쁘고 오해의 소지가 있음을 보여 주었다 . 또한 두 번째 는 가설 검정이 주요 목표 일 때 순열 검정이 일반적으로 부트 스트랩보다 낫다는 점을 강조했습니다 . 그럼에도 불구하고이 은 컴퓨터 집약적 인 방법들 사이의 중요한 차이점을 다룹니다. 그러나 여기서 나는 다른 질문을 제기하고 싶습니다 (믿습니다).

가장 일반적인 부트 스트랩 접근 방식을 먼저 소개하겠습니다 (Bootstrap1 : 풀링 된 샘플 내에서 리샘플링 ).

s.size.g1 <- length (g1.lengths)
s.size.g2 <- length (g2.lengths)

pool <- lengths$lengths
obs.diff.b1 <- mean (g1.lengths) - mean (g2.lengths)
iterations <- 10000
sampl.dist.b1 <- NULL

set.seed (5)
for (i in 1 : iterations) {
        resample <- sample (c(1:length (pool)), length(pool), replace = TRUE) 
        # "replace = TRUE" is the only difference between bootstrap and permutations

        g1.perm = pool[resample][1 : s.size.g1]
        g2.perm = pool[resample][(s.size.g1+1) : length(pool)]
        sampl.dist.b1[i] = mean (g1.perm) - mean (g2.perm) 
}
p.boot1 <- (sum (abs (sampl.dist.b1) >= obs.diff.b1) + 1)/ (iterations+1)

이러한 방식으로 수행 된 부트 스트랩의 P 값은 0.005 이다. 이것이 파라 메트릭 ANOVA 및 순열 테스트와 합리적이고 거의 동일하게 들리더라도, 우리가 후속 샘플을 추출한 샘플풀링 했음을 기반으로이 부트 스트랩에서 H0를 정당화하는 것이 적절 합니까?

여러 과학 논문에서 찾은 다른 접근법. 특히, 연구원들은 부트 스트랩 이전에 HO를 충족시키기 위해 데이터를 수정하는 것을 보았습니다. CV 에서 @ jan.s 가 두 가지 수단을 비교하는 것이 목적인 게시물 질문에서 부트 스트랩의 특이한 결과를 설명 하는 매우 흥미로운 게시물을 발견했습니다 . 그러나 해당 게시물에서는 부트 스트랩 이전에 데이터가 수정 될 때 부트 스트랩을 수행하는 방법을 다루지 않습니다. 부트 스트랩 이전에 데이터가 수정되는 방식은 다음과 같습니다.

  1. H0는 두 그룹의 평균이 동일하다는 것을 나타냅니다.
  2. 풀링 된 표본의 평균에서 개별 관측 값을 빼면 H0이 적용됩니다.

이 경우, 데이터의 수정은 그룹 평균에 영향을 주어야하며, 그 차이는 있지만 그룹 내 (및 그룹 간)의 변동에는 영향을 미치지 않습니다.

  1. 수정 된 데이터는 추가 부트 스트랩의 기초가되며 샘플링은 각 그룹 내에서 별도로 수행된다는 경고가 있습니다.
  2. g1과 g2의 부트 스트랩 평균 간의 차이가 계산되고 그룹 간의 관찰 된 (수정되지 않은) 차이와 비교됩니다.
  3. 관찰 된 값을 반복 횟수로 나눈 값보다 크거나 같은 극단적 인 값의 비율은 p 값을 제공합니다.

다음은 코드입니다 (Bootstrap2 : 수정 후 그룹 내에서 리샘플링 ( H0이 TRUE 임)).

s.size.g1 <- length (g1.lengths)
s.size.g2 <- length (g2.lengths)

pool <- lengths$lengths
obs.diff.b2 <- mean (g1.lengths) - mean (g2.lengths)

# make H0 to be true (no difference between means of two groups)
H0 <- pool - mean (pool)

# g1 from H0 
g1.H0 <- H0[1:s.size.g1] 

# g2 from H0
g2.H0 <- H0[(s.size.g1+1):length(pool)]

iterations <- 10000
sampl.dist.b2 <- NULL

set.seed (5)
for (i in 1 : iterations) {
        # Sample with replacement in g1
        g1.boot = sample (g1.H0, replace = T)

        # Sample with replacement in g2
        g2.boot = sample (g2.H0, replace = T)

        # bootstrapped difference
        sampl.dist.b2[i] <- mean (g1.boot) - mean (g2.boot)  
}
p.boot2 <- (sum (abs (sampl.dist.b2) >= obs.diff.b2) + 1)/ (iterations+1)

이러한 수행 된 부트 스트랩은 p의 0.514 값을 제공 하며 이는 이전 테스트와 크게 다릅니다. 나는 이것이 @ jan.s의 설명 을 다루어야한다고 생각 하지만, 열쇠가 어디에 있는지 알 수 없다 ...


1
재미있는 문제와 멋지게 발표되었습니다. 부트 스트랩은 원래 표본이 모집단을 잘 나타내지 않을 가능성이 높기 때문에 표본 크기가 매우 작은 경우 문제가 있습니다. 부트 스트랩이 작동하기 위해 샘플 크기가 매우 클 필요는 없습니다. 6과 22의 표본 크기는 그렇게 나쁘지 않을 수 있습니다. Efron (1983)의 논문에서 부트 스트랩은 각 훈련 표본 크기가 10보다 작은 2 가지 클래스의 분류 문제에서 선형 판별 함수에 대한 오류율을 추정하기 위해 CV 형식과 비교되었습니다. 2007).
Michael R. Chernick

2
저의 책에는 또한 부트 스트랩이 실패 할 때의 장이 있으며 작은 샘플 크기 문제에 대한 토론이 포함되어 있습니다.
Michael R. Chernick

단일 당신이 작업을 확인하기 위해 부트 스트랩에 수정에 # 2 접근 방식이 필요하다는 줄은 하나입니다 H0 <- pool - mean (pool). 로 교체해야합니다 H0 <- c(g1.lengths - mean(g1.lengths), g2.lengths - mean(g2.lengths)). 그러면 p- 값이 0.0023이됩니다. (이것은 Zenit이 그의 답변에서 설명한 것과 동일합니다.) 이것은 코드의 간단한 버그 일뿐입니다. @MichaelChernick의 CC
amoeba는 Monica Monica

이 방법들이 압도 될 수 있습니까? 나는 그들이 그룹이 매우 클 때 모든 차이를 큰 차이로 감지 할 수 있는지 여부를 의미합니다 : 풀> 43k.
Alex Alvarez Pérez

답변:


17

다음은 Efron과 Tibshirani의 16 장 , 부트 스트랩 소개 (220-224 페이지) 의 16 장을 기반으로 합니다. 단점은 두 번째 부트 스트랩 알고리즘이 잘못 구현되었지만 일반적인 아이디어는 정확하다는 것입니다.

부트 스트랩 테스트를 수행 할 때 리샘플링 방법이 귀무 가설에 해당하는 데이터를 생성하는지 확인해야합니다. 이 게시물을 설명하기 위해 R의 수면 데이터를 사용하겠습니다. 나는 교과서에서 권장하는 평균의 차이보다는 학생 화 된 테스트 통계를 사용하고 있습니다.

t- 통계의 샘플링 분포에 대한 정보를 얻기 위해 분석 결과를 사용하는 클래식 t- 검정은 다음과 같은 결과를 산출합니다.

x <- sleep$extra[sleep$group==1] y <- sleep$extra[sleep$group==2]
t.test(x,y)
t = -1.8608, df = 17.776, p-value = 0.07939

12

# pooled sample, assumes equal variance
pooled <- c(x,y)
for (i in 1:10000){
  sample.index <- sample(c(1:length(pooled)),replace=TRUE)
  sample.x <- pooled[sample.index][1:length(x)]
  sample.y <- pooled[sample.index][-c(1:length(y))]
  boot.t[i] <- t.test(sample.x,sample.y)$statistic
}
p.pooled <-  (1 + sum(abs(boot.t) > abs(t.test(x,y)$statistic))) / (10000+1) 
p.pooled
[1] 0.07929207

H0H0H0¯

엑스~나는=엑스나는엑스¯+¯
와이~나는=와이나는와이¯+¯

엑스~/와이~¯H0

# sample from H0 separately, no assumption about equal variance
xt <- x - mean(x) + mean(sleep$extra) #
yt <- y - mean(y) + mean(sleep$extra)

boot.t <- c(1:10000)
for (i in 1:10000){
  sample.x <- sample(xt,replace=TRUE)
  sample.y <- sample(yt,replace=TRUE)
  boot.t[i] <- t.test(sample.x,sample.y)$statistic
}
p.h0 <-  (1 + sum(abs(boot.t) > abs(t.test(x,y)$statistic))) / (10000+1)  # 
p.h0
[1] 0.08049195

이번에 우리는 세 가지 접근법에 대해 비슷한 p- 값으로 끝났습니다. 도움이 되었기를 바랍니다!


1
친절하고 왜 '1'이 (가) 다음과 같이 추가되었는지 설명 (1 + sum(abs(boot.t) > abs(t.test(x,y)$statistic))) / (10000+1)하십시오. mean(abs(boot.t) > abs(t.test(x,y)$statistic))시간을 내 주셔서 감사합니다.
TG_Montana

+1. 이 부트 스트랩-온-수정-데이터-샘플 -H0 접근 방식에 특정 이름이 있습니까?
amoeba는 Reinstate Monica

3
H0V이자형=횟수 {>영형에스}

@amoeba :이 절차가 공식적이거나 합의 된 이름인지 확실하지 않지만 분포 보다는 평균의 평등에 대한 부트 스트랩 테스트 라고 할 수 있습니다 . 전체 절차를 보여주는 페이지는 Google 도서 에는 없지만 동기 부여는 223 페이지에 나타납니다.이 노트에 대한 다른 설명은 13 페이지 ( galton.uchicago.edu/~eichler/stat24600/Handouts/bootstrap) 에서 확인할 수 있습니다 . pdf ).
제니트

(+1) 훌륭한 답변. "이 알고리즘 (중심없이 데이터 자체를 리샘플링)이 실제로 x와 y의 분포가 동일한 지 여부를 테스트하고있는 이유"에 대해 자세히 설명해 주시겠습니까? 이 리샘플링 전략 분포가 동일하다는 것을 보장 하지만 왜 동일 하다는 것을 테스트 합니까?
하프 패스
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.