Perché i test di ipotesi su set di dati ricampionati rifiutano lo null troppo spesso?


10

tl; dr: a partire da un set di dati generato sotto il null, ho ricampionato i casi con la sostituzione e ho condotto un test di ipotesi su ciascun set di dati ricampionato. Questi test di ipotesi respingono il nulla più del 5% delle volte.

Di seguito, una simulazione molto semplice, generi set di dati con e inserisco un modello OLS semplice per ciascuno. Quindi, per ogni set di dati, generi 1000 nuovi set di dati ricampionando le righe del set di dati originale con la sostituzione (un algoritmo specificamente descritto nel testo classico di Davison & Hinkley come appropriato per la regressione lineare). Per ognuno di questi, mi adatto allo stesso modello OLS. Alla fine, circa il 16% dei test di ipotesi all'interno dei campioni bootstrap respinge il valore nullo , mentre dovremmo ottenere il 5% (come facciamo nei set di dati originali).X~N(0,1)⨿Y~N(0,1)

Sospettavo che avesse a che fare con osservazioni ripetute che causavano associazioni gonfiate, quindi per confronto, ho provato altri due approcci nel codice qui sotto (commentato). Nel metodo 2, correggo , quindi sostituisco con residui ricampionati dal modello OLS sul set di dati originale. Nel metodo 3, disegno un sottocampione casuale senza sostituzione. Entrambe queste alternative funzionano, vale a dire che i loro test di ipotesi rifiutano il null 5% delle volte.XY

La mia domanda: ho ragione nel dire che il colpevole sono le osservazioni ripetute? In tal caso, dato che si tratta di un approccio standard al bootstrap, dove stiamo esattamente violando la teoria del bootstrap standard?

Aggiornamento n. 1: più simulazioni

Ho provato uno scenario ancora più semplice, un modello di regressione intercetta-solo per . Lo stesso problema si verifica.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)

Aggiornamento n. 2: la risposta

Diverse possibilità sono state proposte nei commenti e nelle risposte e ho fatto più simulazioni per testarle empiricamente. Si scopre che JWalker ha ragione sul fatto che il problema era che dovevamo centrare le statistiche bootstrap in base alla stima dei dati originali per ottenere la distribuzione di campionamento corretta sotto . Tuttavia, penso anche che anche il commento di Whuber sulla violazione dei presupposti del test parametrico sia corretto, anche se in questo caso riceviamo effettivamente falsi positivi nominali quando risolviamo il problema di JWalker.H0


1
Nel bootstrap standard, considereresti solo la distribuzione bootstrap del coefficiente di X1, non i suoi valori p associati. Quindi non è un problema del bootstrap. Tuttavia la tua osservazione è interessante e non intuitiva.
Michael M,

1
@MichaelM, è vero. Ma dal momento che il CDF congiunto dei dati nei campioni dovrebbe convergere in n e il numero di bootstrap scorre nel vero CDF che ha generato i dati originali, non mi aspetterei che i valori p differiscano.
passaggio

Giusto. Sono abbastanza certo che l'effetto deriva da osservazioni non indipendenti (come hai detto), che producono errori standard troppo ottimistici. Nella tua simulazione, sembra essere l'unica ipotesi violata del normale modello lineare. Forse possiamo persino derivare il corrispondente fattore di sgonfiamento della varianza.
Michael M,

2
Xidsids <- unique(ids)

2
@whuber. Vedo. E questo spiegherebbe perché il ricampionamento dei residui con la sostituzione funziona nonostante le ripetute osservazioni: i residui di quel modello sono ancora una volta indipendenti da X. Se desideri trasformare questo in una risposta, sarei felice di accettare.
passaggio di mezzo

Risposte:


5

Quando si ricampiona il valore nullo, il valore atteso del coefficiente di regressione è zero. Quando si ricampiona alcuni set di dati osservati, il valore atteso è il coefficiente osservato per tali dati. Non è un errore di tipo I se P <= 0,05 quando ricampiona i dati osservati. In effetti, è un errore di tipo II se hai P> 0,05.

È possibile ottenere alcune intuizioni calcolando la correlazione tra gli addominali (b) e la media (P). Ecco un codice più semplice per replicare ciò che hai fatto e calcolare la correlazione tra b e l'errore "tipo I" sull'insieme di simulazioni

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)

aggiornare la risposta con grand_chat non è il motivo per cui la frequenza di P <= 0,05 è> 0,05. La risposta è molto semplice e quello che ho detto sopra - il valore atteso della media di ciascun ricampionamento è la media originale osservata. Questa è l'intera base del bootstrap, che è stato sviluppato per generare errori / limiti di confidenza standard su una media osservata e non come test di ipotesi. Poiché l'aspettativa non è zero, ovviamente "l'errore di tipo I" sarà maggiore dell'alfa. Ed è per questo che ci sarà una correlazione tra l'entità del coefficiente (quanto lontano da zero) e l'entità della deviazione dell '"errore di tipo I" dall'alfa.


H0:β=β^H0:β=0

H0:β=βˆH0:β=0H0:β=0nelle prime fasi della ricerca per filtrare i colpi di fortuna quando non si conosce abbastanza per definire un'ipotesi alternativa, quando si conoscono più ipotesi potrebbe essere opportuno passare alla verifica della correttezza delle proprie conoscenze.
ReneBt

2

Se si campiona con la sostituzione dal campione normale originale, il campione bootstrap risultante non è normale . La distribuzione congiunta del campione bootstrap segue una distribuzione nodosa della miscela che molto probabilmente contiene record duplicati, mentre i valori duplicati hanno probabilità zero quando si prelevano campioni da una distribuzione normale.

Come semplice esempio, se il campione originale è costituito da due osservazioni provenienti da una distribuzione normale univariata, un campione bootstrap con sostituzione costituirà metà del tempo del campione originale e metà del tempo sarà costituito da uno dei valori originali, duplicato. È chiaro che la varianza del campione del bootstrap sarà mediamente inferiore a quella dell'originale - in effetti sarà metà dell'originale.

pt


Ma se questo è il caso, allora non avremmo esattamente lo stesso problema nel ricampionare i residui con la sostituzione? Eppure, in realtà, tale approccio rifiuta con probabilità nominale.
mezzo passaggio

Inoltre, un test t con n = 1000 non dovrebbe avere problemi con dati non normali.
passaggio di mezzo

0

Sono totalmente d'accordo con la risposta di @ JWalker.

C'è un altro aspetto di questo problema. Questo è nel tuo processo di ricampionamento. Ti aspetti che il coefficiente di regressione sia centrato attorno allo zero perché presumi Xe Ysei indipendente. Tuttavia, nel ricampionamento lo fai

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

che crea correlazione perché stai campionando Xe Yinsieme. Ad esempio, supponiamo che la prima riga del set di dati dsia (x1, y1), Nel set di dati ricampionato P(Y = y1|X = x1) = 1, mentre se Xe Ysono indipendenti, P(Y|X = x1)segue una distribuzione normale.

Quindi un altro modo di risolvere questo è usare

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

lo stesso codice che usi per generare d, al fine di rendere X e Y indipendenti l'uno dall'altro.

Lo stesso motivo spiega perché funziona con il ricampionamento residuo (perché Xè indipendente dal nuovo Y).


Per un po ', ho anche pensato che le osservazioni ricampionate potrebbero essere non indipendenti, ma a pensarci molto di più, in realtà non penso che sia così: stats.stackexchange.com/questions/339237/…
metà -passare l'

Il problema che sto descrivendo sopra è diverso dal tuo post. Ciò a cui hai fatto riferimento è l'indipendenza di x's. Ciò a cui ho fatto riferimento è la correlazione tra Xs e Ys.
Tianxia Zhou,

-1

Il problema più grande qui è che i risultati del modello sono spuri e quindi altamente instabili, perché il modello sta semplicemente adattando il rumore. In un senso molto letterale. Y1 non è una variabile dipendente a causa della modalità di generazione dei dati del campione.


Modifica, in risposta ai commenti. Fammi un altro tentativo di spiegare il mio pensiero.

Con un OLS l'intento generale è scoprire e quantificare le relazioni sottostanti nei dati. Con i dati del mondo reale, di solito non li conosciamo esattamente.

Ma questa è una situazione di test artificiale. Conosciamo il meccanismo di generazione dei dati EXACT, è proprio lì nel codice pubblicato da OP It's

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

Se lo esprimiamo nella forma familiare di una regressione OLS, vale a dire

Y1 = intercetta + Beta1 * X1 + Errore
che diventa
Y1 = media (X1) + 0 (X1) + Errore

Quindi, nella mia mente, questo è un modello espresso in FORM lineare, ma NON è in realtà una relazione / modello lineare, perché non c'è pendenza. Beta1 = 0.000000.

Quando generiamo 1000 punti di dati casuali, il grafico a dispersione assomiglierà al classico spray circolare per fucili da caccia. Potrebbe esserci una correlazione tra X1 e Y1 nello specifico campione di 1000 punti casuali generati, ma in tal caso si tratta di una casualità casuale. Se l'OLS trova una correlazione, vale a dire, rifiuta l'ipotesi nulla che non vi sia alcuna pendenza, poiché sappiamo definitivamente che in realtà non esiste alcuna relazione tra queste due variabili, l'OLS ha letteralmente trovato un modello nel componente Error. L'ho caratterizzato come "adatto al rumore" e "spurio".

Inoltre, uno dei presupposti / requisiti standard di un OLS è che (+/-) "il modello di regressione lineare è" lineare nei parametri ". Dati i dati, la mia opinione è che non soddisfiamo tale presupposto, quindi le statistiche dei test sottostanti per il significato sono inaccurate. La mia convinzione è che la violazione del presupposto di linearità sia la causa diretta dei risultati non intuitivi del bootstrap.

Quando ho letto questo problema per la prima volta, non è affondato il fatto che l'OP intendeva testare sotto l'ipotesi nulla.

Ma sarebbero gli stessi risultati non intuitivi se il set di dati fosse stato generato come

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


4
Y1Y1

(-1) per le stesse ragioni fornite da @whuber.
passaggio

1
Risposta all'ultima domanda nella tua modifica: sì, sicuramente. Provalo tu stesso con una simulazione. (Ma fai attenzione all'interpretazione, perché devi considerare qual è il nulla e qual è il vero stato delle cose.)
whuber
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.