Tại sao tôi không nhận được phân phối giá trị p thống nhất từ ​​hồi quy logistic với các yếu tố dự đoán ngẫu nhiên?


7

Mã dưới đây tạo ra một tập hợp dữ liệu thử nghiệm bao gồm một loạt các xác suất "tín hiệu" với nhiễu nhị thức xung quanh nó. Sau đó, mã sử dụng 5000 bộ số ngẫu nhiên làm chuỗi "giải thích" và tính toán giá trị p hồi quy logistic cho mỗi bộ.

Tôi thấy rằng loạt giải thích ngẫu nhiên có ý nghĩa thống kê ở mức 5% trong 57% các trường hợp. Nếu bạn đọc qua phần dài hơn của bài viết dưới đây, tôi cho rằng đây là sự hiện diện của tín hiệu mạnh trong dữ liệu.

Vì vậy, đây là câu hỏi chính: tôi nên sử dụng thử nghiệm nào khi đánh giá ý nghĩa thống kê của một biến giải thích khi dữ liệu chứa tín hiệu mạnh? Giá trị p đơn giản dường như khá sai lệch.

Đây là một lời giải thích chi tiết hơn về vấn đề này.

Tôi bối rối trước kết quả tôi nhận được cho các giá trị p hồi quy logistic khi bộ dự đoán thực sự chỉ là một tập hợp các số ngẫu nhiên. Suy nghĩ ban đầu của tôi là phân phối giá trị p phải bằng phẳng trong trường hợp này; mã R bên dưới thực sự cho thấy một sự tăng đột biến lớn ở các giá trị p thấp. Đây là mã:

set.seed(541713)

lseries <-   50
nbinom  <-  100
ntrial  <- 5000
pavg    <- .1  # median probability
sd      <- 0 # data is pure noise
sd      <- 1 # data has a strong signal
orthogonalPredictor <- TRUE   # random predictor that is orthogonal to the true signal
orthogonalPredictor <- FALSE  # completely random predictor

qprobs  <- c(.05,.01) # find the true quantiles for these p-values

yactual <- sd * rnorm(lseries)  # random signal
pactual <- 1 / (1 + exp(-(yactual + log(pavg / (1-pavg)))))
heads   <- rbinom(lseries, nbinom, pactual)
  ## test data, binomial noise around pactual, the probability "signal"
flips   <- cbind(heads, nbinom - heads)
# summary(glm(flips ~ yactual, family = "binomial"))

pval <- numeric(ntrial)

for (i in 1:ntrial){
  yrandom <- rnorm(lseries)
  if (orthogonalPredictor){ yrandom <- residuals(lm(yrandom ~ yactual)) }
  s       <- summary(glm(flips ~ yrandom, family="binomial"))
  pval[i] <- s$coefficients[2,4]
}

hist(pval, breaks=100)
print(quantile(pval, probs=c(.01,.05)))
actualCL <- sapply(qprobs, function(c){ sum(pval <= c) / length(pval) })
print(data.frame(nominalCL=qprobs, actualCL))

Mã này tạo ra dữ liệu thử nghiệm bao gồm nhiễu nhị thức xung quanh tín hiệu mạnh, sau đó trong một vòng lặp phù hợp với hồi quy logistic của dữ liệu đối với một tập hợp các số ngẫu nhiên và tích lũy giá trị p của các yếu tố dự đoán ngẫu nhiên; kết quả được hiển thị dưới dạng biểu đồ của các giá trị p, các lượng tử giá trị p thực tế cho các mức độ tin cậy là 1% và 5% và tỷ lệ dương tính giả thực tế tương ứng với các mức độ tin cậy đó.

Tôi nghĩ một lý do cho kết quả bất ngờ là một người dự đoán ngẫu nhiên thường sẽ có một số mối tương quan với tín hiệu thực sự và điều này chủ yếu chiếm kết quả. Tuy nhiên, nếu bạn thiết lập orthogonalPredictorđể TRUEsẽ có không tương quan giữa các yếu tố dự báo ngẫu nhiên và tín hiệu thực tế, nhưng vấn đề vẫn còn đó ở một mức độ giảm. Giải thích tốt nhất của tôi cho điều đó là vì tín hiệu thực sự không có ở bất kỳ nơi nào trong mô hình được trang bị nên mô hình bị sai và giá trị p dù sao cũng bị nghi ngờ. Nhưng đây là một cái bẫy-22 - ai đã từng có sẵn một bộ dự đoán phù hợp với dữ liệu? Vì vậy, đây là một số câu hỏi bổ sung:

  1. Giả thuyết null chính xác cho hồi quy logistic là gì? Có phải dữ liệu hoàn toàn là nhiễu nhị thức quanh mức không đổi (nghĩa là không có tín hiệu thực sự)? Nếu bạn đặt sd thành 0 trong mã thì không có tín hiệu và biểu đồ sẽ trông phẳng.

  2. Giả thuyết null ẩn trong mã là dự đoán không có sức mạnh giải thích nhiều hơn một tập hợp các số ngẫu nhiên; nó đã được kiểm tra bằng cách sử dụng định lượng 5% theo kinh nghiệm cho giá trị p như được hiển thị bởi mã. Có cách nào tốt hơn để kiểm tra giả thuyết này, hoặc ít nhất một cách không quá chuyên sâu về số lượng?

------ Thông tin thêm

Mã này bắt chước vấn đề sau: Tỷ lệ mặc định trong lịch sử cho thấy sự thay đổi đáng kể theo thời gian (tín hiệu) được điều khiển bởi các chu kỳ kinh tế; số lượng mặc định thực tế tại một thời điểm nhất định là nhị thức xung quanh các xác suất mặc định này. Tôi đã cố gắng tìm các biến giải thích cho tín hiệu khi tôi nghi ngờ các giá trị p. Trong thử nghiệm này, tín hiệu được sắp xếp ngẫu nhiên theo thời gian thay vì hiển thị các chu kỳ kinh tế, nhưng điều đó không quan trọng đối với hồi quy logistic. Vì vậy, không có sự quá mức, tín hiệu thực sự có nghĩa là một tín hiệu.


4
Điều này thật thú vị, nhưng tôi không nghĩ nó sẽ thu hút nhiều sự quan tâm bởi vì nó là mã 50%. Bạn có thể xen kẽ mã với giải thích bằng văn bản, công thức, vv? Đây không phải là Stack Overflow và không ai sẽ gỡ lỗi mã cho bạn. Ngoài ra, chắc chắn loại bỏ ít nhất 2 trong số 4 câu hỏi của bạn. Chính sách ở đây là một câu hỏi cho bài đăng: hai có thể được chấp nhận, 4 giống như đảm bảo bạn sẽ không bao giờ nhận được câu trả lời.
DeltaIV

1
Cảm ơn, tôi chưa bao giờ sử dụng Xác thực chéo trước đây. Tôi sẽ thực hiện một số chỉnh sửa.
Ron Hylton

Câu trả lời:


12

Có một số vấn đề ở đây. Cụ thể, dường như có một số nhầm lẫn về cách mô phỏng hồi quy logistic tiêu chuẩn. Tóm lại, bạn không thêm noise around... the probability "signal". Kết quả của cách bạn đã làm điều này, có một lượng lớn sự thay đổi trong dữ liệu 'nhị thức' (- esque), nhiều hơn mức cần thiết. Dưới đây là các xác suất trong bộ dữ liệu của bạn:

plot(flips[,1]/rowSums(flips))

nhập mô tả hình ảnh ở đây

Nếu các quan sát .4+ đó kết thúc ở bên này hay bên kia, chúng sẽ hoạt động như 'ngoại lệ' (chúng không thực sự) và gây ra lỗi loại 1 trong mô hình không tính đến thực tế là những dữ liệu này không thực sự nhị thức. Đây là một phiên bản sử dụng một hack đơn giản để cho phép mô hình phát hiện và giải thích cho sự quá mức:

set.seed(5082)
pval <- numeric(ntrial)
for (i in 1:ntrial){
  yrandom <- rnorm(lseries)
  s       <- summary(glm(flips ~ yrandom, family="quasibinomial"))  # changed family
  pval[i] <- s$coefficients[2,4]
}

hist(pval, breaks=100)
print(quantile(pval, probs=c(.01,.05)))
#          1%          5% 
# 0.006924617 0.046977246 
actualCL <- sapply(qprobs, function(c){ sum(pval <= c) / length(pval) })
print(data.frame(nominalCL=qprobs, actualCL))
#   nominalCL actualCL
# 1      0.05   0.0536
# 2      0.01   0.0128

nhập mô tả hình ảnh ở đây

Đây là tóm tắt mô hình từ lần lặp cuối cùng. Lưu ý rằng độ phân tán được ước tính là với giá trị nhị phân thực: 12×

s
# Call:
# glm(formula = flips ~ yrandom, family = "quasibinomial")
# 
# Deviance Residuals: 
#    Min      1Q  Median      3Q     Max  
# -5.167  -2.925  -1.111   1.101   8.110  
# 
# Coefficients:
#             Estimate Std. Error t value Pr(>|t|)    
# (Intercept) -1.96910    0.14942 -13.178   <2e-16 ***
# yrandom     -0.02736    0.14587  -0.188    0.852    
# ---
# Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
# 
# (Dispersion parameter for quasibinomial family taken to be 11.97867)
# 
#     Null deviance: 532.38  on 49  degrees of freedom
# Residual deviance: 531.96  on 48  degrees of freedom
# AIC: NA
# 
# Number of Fisher Scoring iterations: 5

Đây là một phiên bản khác, nơi tôi phù hợp với cùng một mô hình mà bạn làm, nhưng chỉ tạo dữ liệu mà không có nhiễu xung quanh tín hiệu. (Lưu ý rằng mã không giống nhau được bỏ qua cho ngắn gọn.)

set.seed(541713)
...
pactual <- 1 / (1 + exp(-(log(pavg / (1-pavg)))))  # deleted yactual
...
for (i in 1:ntrial){
  yrandom <- rnorm(lseries)
  if (orthogonalPredictor){ yrandom <- residuals(lm(yrandom ~ yactual)) }
  s       <- summary(glm(flips ~ yrandom, family="binomial"))
  pval[i] <- s$coefficients[2,4]
}

hist(pval, breaks=100)
print(quantile(pval, probs=c(.01,.05)))
#         1%         5% 
# 0.01993318 0.07027473 
actualCL <- sapply(qprobs, function(c){ sum(pval <= c) / length(pval) })
print(data.frame(nominalCL=qprobs, actualCL))
#   nominalCL actualCL
# 1      0.05   0.0372
# 2      0.01   0.0036

nhập mô tả hình ảnh ở đây


Tôi đã thêm một lời giải thích ở dưới cùng của bài viết gốc về vấn đề thực tế mà mã đang bắt chước. Tín hiệu thực sự là một tín hiệu, không phải là quá mức và vấn đề thực sự là nhiễu nhị phân xung quanh tín hiệu.
Ron Hylton

2
@RonHylton, đây là một sự hiểu lầm. Dữ liệu của bạn thực sự bị quá tải so với phân phối nhị thức. Bạn cần tính đến điều đó bằng cách nào đó (có một số cách - sử dụng quasibinomial là cách dễ nhất). Nếu bạn tính đến sự quá mức rõ ràng ở đó (điều này đúng với cách bạn đang tạo dữ liệu của mình từ quan điểm của lý thuyết thống kê, và nó cũng được chứng minh bằng thực nghiệm), thì bạn không còn bị lạm phát lỗi loại 1 nữa.
gung - Phục hồi Monica

1
@RonHylton, bạn không có hiệu quả điều trị (& bạn không có nhóm nào trong mô phỏng này - chỉ có một yếu tố dự đoán liên tục yrandom), đó là lý do tại sao đây là những lỗi loại 1, điều bạn rất lo lắng. Có sự thay đổi đáng kể hơn trong các phân phối đáp ứng có điều kiện so với dưới dạng nhị thức. Đó là định nghĩa của quá mức. Để cụ thể hơn, các bản phân phối có điều kiện của bạn là nhị phân beta , không phải nhị thức.
gung - Phục hồi Monica

1
FWIW, cơ chế tạo dữ liệu trong mã của bạn có thể không phù hợp với tình huống bạn mô tả & sẽ được giải quyết tốt hơn với lỗi không phù hợp và lỗi tự động tương thích so với sử dụng family=quasibinomial. Nhiều khả năng bạn không chỉ có quá mức, nhưng có thể là các lỗi tương quan theo thời gian.
gung - Phục hồi Monica

1
@RonHylton, tôi không biết phải nói gì ở đây. Mã của bạn mô phỏng null - không có tín hiệu. Bạn có lạm phát lỗi loại 1 b / c bạn có quá mức & mô hình không giải thích cho điều đó; nếu bạn làm, lạm phát lỗi loại 1 sẽ biến mất. Mã của bạn không khớp với mô tả của bạn ở đây hoặc trong bản chỉnh sửa của bạn; trong thực tế, mã của bạn không phải là cách mô phỏng thông thường sẽ được thiết lập. Tôi không theo suy nghĩ của bạn về cách mô tả hoặc mã của bạn liên quan đến GLMM. Tất cả những gì tôi có thể nói là bạn có quá mức & một "hồi quy logistic tiêu chuẩn" được sử dụng theo "cách hoàn toàn bình thường" không giải thích cho điều đó.
gung - Phục hồi Monica

1

Mối quan hệ của mã với mục tiêu thử nghiệm là khó hiểu. Bạn có mong đợi một công cụ dự đoán quan trọng cho bất kỳ lựa chọn orthogonalPredictor hoặc sd không? Tôi không.

Dựa trên diễn giải của tôi, có vẻ như thí nghiệm không phù hợp với những gì chúng tôi đang cố gắng kiểm tra. Khi tiếng ồn được tạo ra, nó hoàn toàn được lặp đi lặp lại (tức là không ngẫu nhiên) được gắn vào các quan sát riêng lẻ, cung cấp tín hiệu cho hồi quy.

Đây là những gì tôi nghĩ đã được dự định:

lseries <-   50
nbinom  <-  100
ntrial  <- 5000
pavg    <- .1  # median probability

run_experiment <- function(sd = 0,
                           orthogonalPredictor = FALSE,
                           predictor_noise_sd = NA) {
  qprobs  <- c(.05,.01) # find the true quantiles for these p-values

  yactual <- sd * rnorm(lseries)  # random signal
  pactual <- 1 / (1 + exp(-(yactual + log(pavg / (1-pavg)))))
  heads   <- rbinom(lseries, nbinom, pactual)
  ## test data, binomial noise around pactual, the probability "signal"
  flips_expanded <- rbind(data.frame(flip_result = rep(rep(1, length(heads)), heads),
                               y_actual = rep(yactual, heads)),
                           data.frame(flip_result = rep(rep(0, length(heads)), nbinom-heads),
                                      y_actual = rep(yactual, nbinom-heads))
                               )
  summary(glm(flip_result ~ y_actual, flips_expanded, family = "binomial"))

  pval <- numeric(ntrial)

  for (i in 1:ntrial){
    flips_expanded$y <- rnorm(nrow(flips_expanded))
    if (orthogonalPredictor){ flips_expanded$y <- residuals(lm(y ~ y_actual, flips_expanded)) }
    if (!is.na(predictor_noise_sd)) {flips_expanded$y <- rnorm(nrow(flips_expanded), flips_expanded$y_actual, predictor_noise_sd)}
    s       <- summary(glm(flip_result ~ y, flips_expanded, family="binomial"))
    pval[i] <- s$coefficients[2,4]
  }

  hist(pval, breaks=100)
  print(quantile(pval, probs=c(.01,.05)))
  actualCL <- sapply(qprobs, function(c){ sum(pval <= c) / length(pval) })
  print(data.frame(nominalCL=qprobs, actualCL))
}

Những thay đổi quan trọng là:

  • Mở rộng khung dữ liệu sang định dạng theo dõi thay vì định dạng cô đọng (flips_Exanded)
  • Cũng thử nghiệm với một yếu tố dự đoán tương quan

Không có mối tương quan giữa y_actual & dự đoán của chúng tôi y:

> run_experiment()
        1%         5% 
0.01077116 0.05045712 
  nominalCL actualCL
1      0.05   0.0496
2      0.01   0.0096

nhập mô tả hình ảnh ở đây

Và tạo ra một mối tương quan khá mạnh mẽ:

> run_experiment(1,FALSE,10)
          1%           5% 
0.0001252817 0.0019125482 
  nominalCL actualCL
1      0.05   0.3002
2      0.01   0.1286

nhập mô tả hình ảnh ở đây


2
Điều này không đúng. Vấn đề không phải là các hàng được nhóm lại, điều đó có thể tốt. Hơn nữa, OP đã biết rằng nó hoạt động theo một số kết hợp cài đặt tham số. Với sd =1& orthogonalPredictor = FALSE, nó (ngây thơ) không nên hoạt động vì biến x ( yrandom) được tạo ngẫu nhiên & không liên quan đến biến y.
gung - Phục hồi Monica

Nếu không có vấn đề gì với cách thêm nhiễu vào các hàng được nhóm, tại sao tôi lại tìm thấy phân phối giá trị p thống nhất khi tách nhóm và thêm nhiễu cho mỗi lần quan sát? Dường như với tôi đó không phải là điều mà OP đang cố gắng thử nghiệm.
khol

1
Quá mức không thể phát hiện được với dữ liệu chưa được nhóm. Tuy nhiên, nếu bạn hủy kết nối dữ liệu, bạn sẽ cần chỉ ra bằng cách nào đó rằng các quan sát khác nhau đến từ cùng một đơn vị (bệnh nhân - giả sử đây là dữ liệu thực).
gung - Phục hồi Monica

Tôi đã thêm một lời giải thích ở dưới cùng của bài viết gốc về vấn đề thực tế mà mã đang bắt chước. Tôi nghĩ rằng điều này sẽ làm cho mục tiêu thử nghiệm rõ ràng hơn.
Ron Hylton

2
Bây giờ tôi đã hiểu những gì bạn đang cố gắng mô phỏng, đây không phải là câu trả lời chính xác.
khol
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.