Tại sao các bài kiểm tra giả thuyết trên các bộ dữ liệu được lấy mẫu lại từ chối null quá thường xuyên?


10

tl; dr: Bắt đầu với một tập dữ liệu được tạo dưới dạng null, tôi đã ghép lại các trường hợp với sự thay thế và tiến hành kiểm tra giả thuyết trên mỗi tập dữ liệu được lấy mẫu lại. Các thử nghiệm giả thuyết này từ chối null hơn 5% thời gian.

Trong phần mô phỏng rất đơn giản dưới đây, tôi tạo các bộ dữ liệu với và tôi khớp một mô hình OLS đơn giản cho mỗi mô hình. Sau đó, với mỗi tập dữ liệu, tôi tạo 1000 bộ dữ liệu mới bằng cách lấy lại các hàng của tập dữ liệu gốc với sự thay thế (một thuật toán được mô tả cụ thể trong văn bản cổ điển của Davison & Hinkley là phù hợp với hồi quy tuyến tính). Đối với mỗi loại, tôi phù hợp với cùng một mô hình OLS. Cuối cùng, khoảng 16% các bài kiểm tra giả thuyết trong các mẫu bootstrap từ chối null , trong khi chúng ta sẽ nhận được 5% (như chúng ta làm trong các bộ dữ liệu gốc).XN(0,1)⨿YN(0,1)

Tôi nghi ngờ nó có liên quan đến các quan sát lặp đi lặp lại gây ra các hiệp hội bị thổi phồng, vì vậy để so sánh, tôi đã thử hai cách tiếp cận khác trong đoạn mã dưới đây (nhận xét). Trong Phương pháp 2, tôi sửa lỗi , sau đó thay thế bằng phần dư được lấy mẫu lại từ mô hình OLS trên tập dữ liệu gốc. Trong Phương pháp 3, tôi vẽ một mẫu phụ ngẫu nhiên mà không cần thay thế. Cả hai phương án này đều hoạt động, tức là các bài kiểm tra giả thuyết của họ bác bỏ null 5% thời gian.YXY

Câu hỏi của tôi: Tôi có đúng rằng những quan sát lặp đi lặp lại là thủ phạm? Nếu vậy, cho rằng đây là một cách tiếp cận tiêu chuẩn để bootstrapping, chính xác thì chúng ta đang vi phạm lý thuyết bootstrap tiêu chuẩn ở đâu?

Cập nhật # 1: Thêm mô phỏng

Tôi đã thử một kịch bản thậm chí đơn giản hơn, một mô hình hồi quy đánh chặn chỉ cho . Vấn đề tương tự xảy ra.Y

# note: simulation takes 5-10 min on my laptop; can reduce boot.reps
#  and n.sims.run if wanted
# set the number of cores: can change this to match your machine
library(doParallel)
registerDoParallel(cores=8)
boot.reps = 1000
n.sims.run = 1000

for ( j in 1:n.sims.run ) {

  # make initial dataset from which to bootstrap
  # generate under null
  d = data.frame( X1 = rnorm( n = 1000 ), Y1 = rnorm( n = 1000 ) )

  # fit OLS to original data
  mod.orig = lm( Y1 ~ X1, data = d )
  bhat = coef( mod.orig )[["X1"]]
  se = coef(summary(mod.orig))["X1",2]
  rej = coef(summary(mod.orig))["X1",4] < 0.05

  # run all bootstrap iterates
  parallel.time = system.time( {
    r = foreach( icount( boot.reps ), .combine=rbind ) %dopar% {

      # Algorithm 6.2: Resample entire cases - FAILS
      # residuals of this model are repeated, so not normal?
      ids = sample( 1:nrow(d), replace=TRUE )
      b = d[ ids, ]

      # # Method 2: Resample just the residuals themselves - WORKS
      # b = data.frame( X1 = d$X1, Y1 = sample(mod.orig$residuals, replace = TRUE) )

      # # Method 3: Subsampling without replacement - WORKS
      # ids = sample( 1:nrow(d), size = 500, replace=FALSE )
      # b = d[ ids, ]

      # save stats from bootstrap sample
      mod = lm( Y1 ~ X1, data = b ) 
      data.frame( bhat = coef( mod )[["X1"]],
                  se = coef(summary(mod))["X1",2],
                  rej = coef(summary(mod))["X1",4] < 0.05 )

    }
  } )[3]


  ###### Results for This Simulation Rep #####
  r = data.frame(r)
  names(r) = c( "bhat.bt", "se.bt", "rej.bt" )

  # return results of each bootstrap iterate
  new.rows = data.frame( bt.iterate = 1:boot.reps,
                         bhat.bt = r$bhat.bt,
                         se.bt = r$se.bt,
                         rej.bt = r$rej.bt )
  # along with results from original sample
  new.rows$bhat = bhat
  new.rows$se = se
  new.rows$rej = rej

  # add row to output file
  if ( j == 1 ) res = new.rows
  else res = rbind( res, new.rows )
  # res should have boot.reps rows per "j" in the for-loop

  # simulation rep counter
  d$sim.rep = j

}  # end loop over j simulation reps



##### Analyze results #####

# dataset with only one row per simulation
s = res[ res$bt.iterate == 1, ]

# prob of rejecting within each resample
# should be 0.05
mean(res$rej.bt); mean(s$rej)

Cập nhật # 2: Câu trả lời

Một số khả năng đã được đề xuất trong các bình luận và câu trả lời, và tôi đã thực hiện nhiều mô phỏng hơn để kiểm tra thực nghiệm chúng. Hóa ra JWalker đúng là vấn đề là chúng ta cần phải căn giữa số liệu thống kê bootstrap theo ước tính của dữ liệu gốc để có được phân phối lấy mẫu chính xác theo . Tuy nhiên, tôi cũng nghĩ rằng nhận xét của người đăng ký về việc vi phạm các giả định kiểm tra tham số cũng đúng, mặc dù trong trường hợp này chúng tôi thực sự nhận được kết quả dương tính giả khi chúng tôi khắc phục sự cố của JWalker.H0


1
Trong bootstrap tiêu chuẩn, bạn sẽ chỉ xem xét phân phối bootstrap của hệ số X1, không phải giá trị p liên quan của nó. Vì vậy, nó không phải là một vấn đề của bootstrap. Tuy nhiên, quan sát của bạn là thú vị và không trực quan.
Michael M

1
@MichaelM, đó là sự thật. Nhưng vì CDF chung của dữ liệu trong các mẫu sẽ hội tụ ở n và số lần khởi động lặp lại với CDF thực sự tạo ra dữ liệu gốc, tôi cũng không hy vọng giá trị p sẽ khác nhau.
một nửa vượt qua

Đúng. Tôi khá chắc chắn hiệu quả đến từ các quan sát là không độc lập (như bạn đã nói), mang lại các lỗi tiêu chuẩn quá lạc quan. Trong mô phỏng của bạn, nó dường như là giả định duy nhất bị vi phạm của mô hình tuyến tính bình thường. Có lẽ chúng ta thậm chí có thể rút ra được yếu tố làm lệch phương sai tương ứng.
Michael M

2
xidsids <- unique(ids)

2
@whuber. Tôi hiểu rồi. Và điều đó sẽ giải thích tại sao việc ghép lại các phần dư với các công việc thay thế mặc dù các quan sát lặp đi lặp lại: phần dư của mô hình đó một lần nữa độc lập với X. Nếu bạn muốn đưa ra câu trả lời, tôi rất vui lòng chấp nhận.
một nửa vượt qua

Câu trả lời:


5

Khi bạn lấy mẫu lại null, giá trị mong đợi của hệ số hồi quy bằng không. Khi bạn lấy mẫu lại một số tập dữ liệu được quan sát, giá trị mong đợi là hệ số quan sát được cho dữ liệu đó. Đây không phải là lỗi loại I nếu P <= 0,05 khi bạn lấy mẫu lại dữ liệu được quan sát. Trên thực tế, đó là lỗi loại II nếu bạn có P> 0,05.

Bạn có thể đạt được một số trực giác bằng cách tính toán mối tương quan giữa abs (b) và giá trị trung bình (P). Đây là mã đơn giản hơn để sao chép những gì bạn đã làm cộng với tính toán mối tương quan giữa lỗi b và "loại I" trong tập hợp các mô phỏng

boot.reps = 1000
n.sims.run = 10
n <- 1000
b <- matrix(NA, nrow=boot.reps, ncol=n.sims.run)
p <- matrix(NA, nrow=boot.reps, ncol=n.sims.run)
for(sim_j in 1:n.sims.run){
  x <- rnorm(n)
  y <- rnorm(n)
  inc <- 1:n
  for(boot_i in 1:boot.reps){
    fit <- lm(y[inc] ~ x[inc])
    b[boot_i, sim_j] <- abs(coefficients(summary(fit))['x[inc]', 'Estimate'])
    p[boot_i, sim_j] <- coefficients(summary(fit))['x[inc]', 'Pr(>|t|)']
    inc <- sample(1:n, replace=TRUE)
  }
}
# note this is not really a type I error but whatever
type1 <- apply(p, 2, function(x) sum(x <= 0.05))/boot.reps
# correlation between b and "type I"
cor(b[1, ], type1)

cập nhật câu trả lời của grand_chat không phải là lý do tần số của P <= 0,05 là> 0,05. Câu trả lời rất đơn giản và những gì tôi đã nói ở trên - giá trị dự kiến ​​của giá trị trung bình của mỗi mẫu lại là giá trị trung bình ban đầu được quan sát. Đây là toàn bộ cơ sở của bootstrap, được phát triển để tạo ra các lỗi tiêu chuẩn / giới hạn độ tin cậy trên một giá trị trung bình quan sát được và không phải là một thử nghiệm giả thuyết. Vì kỳ vọng không phải là không, nên dĩ nhiên "lỗi loại I" sẽ lớn hơn alpha. Và đây là lý do tại sao sẽ có mối tương quan giữa độ lớn của hệ số (bao xa từ 0) và độ lớn của độ lệch của "lỗi loại I" từ alpha.


H0:β=β^H0:β= =0

H 0 : β = 0 H 0 : β = 0H0:β= =βˆ kiểm tra tính tương đương và yêu cầu một phương pháp thiết kế nghiên cứu khác nhau. được sử dụng khi điều quan trọng là đảm bảo sự khác biệt quan sát được của bạn không bị sai lệch, tương đương khi bạn muốn đảm bảo dự đoán của mình là đúng. Thật không may, nó thường được xem là một kích thước phù hợp với tất cả, nhưng nó phụ thuộc vào rủi ro trong tình huống của bạn. Thông thường sử dụng trong nghiên cứu ở giai đoạn đầu để lọc sán khi bạn không biết đủ để xác định một giả thuyết thay thế sau đó khi biết nhiều hơn có thể thay đổi để kiểm tra tính đúng đắn của kiến ​​thức. H0:β= =0H0:β= =0
ReneBt

2

Nếu bạn lấy mẫu thay thế từ mẫu bình thường ban đầu của bạn, mẫu bootstrap kết quả không bình thường . Phân phối chung của mẫu bootstrap tuân theo phân phối hỗn hợp sởn gai ốc rất có khả năng chứa các bản ghi trùng lặp, trong khi các giá trị trùng lặp có xác suất bằng 0 khi bạn lấy mẫu iid từ phân phối bình thường.

Ví dụ đơn giản, nếu mẫu ban đầu của bạn là hai quan sát từ phân phối bình thường đơn biến, thì mẫu bootstrap có thay thế sẽ bằng một nửa thời gian bao gồm mẫu ban đầu và một nửa thời gian sẽ bao gồm một trong các giá trị ban đầu, được nhân đôi. Rõ ràng là phương sai mẫu của mẫu bootstrap trung bình sẽ nhỏ hơn so với ban đầu - thực tế nó sẽ bằng một nửa so với ban đầu.

Hậu quả chính là suy luận mà bạn đang làm dựa trên lý thuyết bình thường trả về giá trị sai khi áp dụng cho mẫu bootstrap. Đặc biệt là lý thuyết thông thường mang lại quy tắc quyết định anticonservative, bởi vì mẫu bootstrap của bạn sẽ sản xuất liệu thống kê có mẫu số nhỏ hơn sẽ được dự kiến theo lý thuyết thông thường, nhờ sự hiện diện của các bản sao. Kết quả là, bài kiểm tra giả thuyết lý thuyết bình thường cuối cùng đã bác bỏ giả thuyết khống hơn dự kiến.tpt


Nhưng nếu đây là trường hợp, thì chúng ta sẽ không có vấn đề chính xác như vậy khi lấy lại số dư với thay thế? Tuy nhiên, trên thực tế, cách tiếp cận đó bác bỏ với xác suất danh nghĩa.
một nửa vượt qua

Ngoài ra, kiểm tra t với n = 1000 sẽ không có vấn đề gì với dữ liệu không bình thường.
một nửa vượt qua

0

Tôi hoàn toàn đồng ý với câu trả lời của @ JWalker.

Có một khía cạnh khác của vấn đề này. Đó là trong quá trình lấy mẫu lại của bạn. Bạn mong đợi hệ số hồi quy sẽ tập trung quanh 0 vì bạn giả định XYđộc lập. Tuy nhiên, trong việc lấy lại mẫu của bạn, bạn làm

ids = sample( 1:nrow(d), replace=TRUE )
  b = d[ ids, ]

mà tạo ra mối tương quan bởi vì bạn đang lấy mẫu XYcùng nhau. Ví dụ: giả sử hàng đầu tiên của tập dữ liệu d(x1, y1), Trong tập dữ liệu được lấy mẫu lại P(Y = y1|X = x1) = 1, trong khi nếu XYđộc lập, P(Y|X = x1)tuân theo phân phối bình thường.

Vì vậy, một cách khắc phục khác là sử dụng

b = data.frame( X1 = rnorm( n = 1000 ), Y1 = rnorm( n = 1000 ) )

cùng một mã bạn sử dụng để tạo d, để làm cho X và Y độc lập với nhau.

Lý do tương tự giải thích lý do tại sao nó hoạt động với việc lấy mẫu dư (vì Xđộc lập với cái mới Y).


Trong một thời gian, tôi cũng nghĩ rằng các quan sát resampled có thể là không độc lập, nhưng khi suy nghĩ về nó nhiều hơn, tôi thực sự không nghĩ rằng đây là trường hợp: stats.stackexchange.com/questions/339237/...
nửa - vượt qua

Vấn đề tôi đang mô tả ở trên khác với bài viết của bạn. Những gì bạn đề cập đến là sự độc lập của x's. Những gì tôi đề cập đến là mối tương quan giữa Xs và Ys.
Tianxia Zhou

-1

Vấn đề lớn nhất ở đây là kết quả mô hình là giả và do đó rất không ổn định, bởi vì mô hình chỉ là tiếng ồn phù hợp. Trong một nghĩa rất chính xác. Y1 không phải là biến phụ thuộc do cách tạo dữ liệu mẫu.


Chỉnh sửa, để đáp lại các bình luận. Hãy để tôi thử giải thích suy nghĩ của tôi.

Với OLS, mục đích chung là khám phá và định lượng các mối quan hệ cơ bản trong dữ liệu. Với dữ liệu trong thế giới thực, chúng ta thường không biết chính xác chúng.

Nhưng đây là một tình huống thử nghiệm nhân tạo. Chúng tôi biết cơ chế tạo dữ liệu CHÍNH XÁC, nó có ngay trong mã được đăng bởi OP

X1 = rnorm (n = 1000), Y1 = rnorm (n = 1000)

Nếu chúng ta biểu thị điều đó ở dạng quen thuộc của hồi quy OLS, nghĩa là

Y1 = chặn + Beta1 * X1 + Lỗi
trở thành
Y1 = mean (X1) + 0 (X1) + Error

Vì vậy, trong suy nghĩ của tôi, đây là một mô hình được thể hiện bằng FORM tuyến tính, nhưng nó thực sự KHÔNG phải là một mối quan hệ / mô hình tuyến tính, bởi vì không có độ dốc. Beta1 = 0,000000.

Khi chúng ta tạo ra 1000 điểm dữ liệu ngẫu nhiên, biểu đồ tán xạ sẽ trông giống như bình xịt tròn súng ngắn cổ điển. Có thể có một số mối tương quan giữa X1 và Y1 trong mẫu cụ thể của 1000 điểm ngẫu nhiên đã được tạo, nhưng nếu vậy thì đó là trường hợp ngẫu nhiên. Nếu OLS không tìm thấy mối tương quan, nghĩa là bác bỏ giả thuyết khống rằng không có độ dốc, vì chúng ta biết chắc chắn rằng thực sự không có bất kỳ mối quan hệ nào giữa hai biến này, thì OLS thực sự đã tìm thấy một mẫu trong Thành phần Lỗi. Tôi đặc trưng rằng "phù hợp với tiếng ồn" và "giả mạo."

Ngoài ra, một trong những giả định / yêu cầu tiêu chuẩn của OLS là (+/-) "mô hình hồi quy tuyến tính là tuyến tính trong các tham số. Với dữ liệu, tôi cho rằng chúng tôi không thỏa mãn giả định đó. Do đó, số liệu thống kê kiểm tra cơ bản có ý nghĩa là không chính xác. Tôi tin rằng việc vi phạm giả định tuyến tính là nguyên nhân trực tiếp dẫn đến kết quả không trực quan của bootstrap.

Khi tôi lần đầu tiên đọc vấn đề này, tôi đã không nhận ra rằng OP đang có ý định thử nghiệm theo [giả thuyết] null.

Nhưng liệu các kết quả không trực quan tương tự có xảy ra nếu bộ dữ liệu được tạo ra như

X1 = rnorm (n = 1000), Y1 = X1 * .4 + rnorm (n = 1000)?


4
Y1Y1

(-1) vì những lý do tương tự @whuber đã đưa ra.
một nửa vượt qua

1
Trả lời câu hỏi cuối cùng trong chỉnh sửa của bạn: có, chắc chắn. Hãy thử nó với một mô phỏng. (Nhưng hãy cẩn thận về việc giải thích, bởi vì bạn phải xem xét null là gì và trạng thái thực sự của vấn đề là gì.)
whuber
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.