(Acest articol a fost publicat pentru prima dată pe R pe Jason Bryerși a contribuit cu drag la R-Bloggers). (Puteți raporta problema despre conținutul de pe această pagină aici)
Doriți să vă împărtășiți conținutul pe R-Bloggers? Faceți clic aici dacă aveți un blog sau aici dacă nu.
În timpul unei clase recente, un student a întrebat dacă intervalele de încredere în bootstrap au fost mai robuste decât intervalele de încredere estimate folosind eroarea standard (adică (Se = frac {s} { sqrt {n}} )) Pentru a răspunde la această întrebare am scris o funcție pentru a simula luarea unei grămadă de eșantioane aleatorii dintr -o populație, calculați intervalul de încredere pentru acel eșantion folosind abordarea standard de eroare ( t Distribuția este utilizată în mod implicit, consultați cv
parametru. Pentru a utiliza distribuția normală, de exemplu, setată cv = 1.96
.), și apoi, de asemenea, calculând un interval de încredere folosind boostrap.
library(dplyr) library(ggplot2) #' Simulate random samples to estimate confidence intervals and bootstrap #' estimates. #' #' @param pop a numeric vector representing the population. #' @param n sample size for each random sample from the population. #' @param n_samples the number of random samples. #' @param n_boot number of bootstrap samples to take for each sample. #' @param seed a seed to use for the random process. #' @param cv critical value to use for calculating confidence intervals. #' @return a data.frame with the sample and bootstrap mean and confidence #' intervals along with a logical variable indicating whether a Type I #' error would have occurred with that sample. bootstrap_clt_simulation <- function( pop, n = 30, n_samples = 500, n_boot = 500, cv = abs(qt(0.025, df = n - 1)), seed, verbose = interactive() ) { if(missing(seed)) { seed <- sample(100000) } results <- data.frame( seed = 1:n_samples, samp_mean = numeric(n_samples), samp_se = numeric(n_samples), samp_ci_low = numeric(n_samples), samp_ci_high = numeric(n_samples), samp_type1 = logical(n_samples), boot_mean = numeric(n_samples), boot_ci_low = numeric(n_samples), boot_ci_high = numeric(n_samples), boot_type1 = logical(n_samples) ) if(verbose) { pb <- txtProgressBar(min = 0, max = n_samples, style = 3) } for(i in 1:n_samples) { if(verbose) { setTxtProgressBar(pb, i) } set.seed(seed + i) samp <- sample(pop, size = n) boot_samp <- numeric(n_boot) for(j in 1:n_boot) { boot_samp(j) <- sample(samp, size = length(samp), replace = TRUE) |> mean() } results(i,)$seed <- seed + i results(i,)$samp_mean <- mean(samp) results(i,)$samp_se <- sd(samp) / sqrt(length(samp)) results(i,)$samp_ci_low <- mean(samp) - cv * results(i,)$samp_se results(i,)$samp_ci_high <- mean(samp) + cv * results(i,)$samp_se results(i,)$samp_type1 <- results(i,)$samp_ci_low > mean(pop) | mean(pop) > results(i,)$samp_ci_high results(i,)$boot_mean <- mean(boot_samp) results(i,)$boot_ci_low <- mean(boot_samp) - cv * sd(boot_samp) results(i,)$boot_ci_high <- mean(boot_samp) + cv * sd(boot_samp) results(i,)$boot_type1 <- results(i,)$boot_ci_low > mean(pop) | mean(pop) > results(i,)$boot_ci_high } if(verbose) { close(pb) } return(results) }
Distribuție uniformă pentru populație
Să începem cu o distribuție uniformă pentru populația noastră.
pop_unif <- runif(1e5, 0, 1) ggplot(data.frame(x = pop_unif), aes(x = x)) + geom_density()
Media populației este 0,4999484. Acum putem simula probe și estimările lor de bootstrap corespunzătoare.
results_unif <- bootstrap_clt_simulation(pop = pop_unif, seed = 42, verbose = FALSE)
4% din eșantioanele noastre nu au conținut media populației în intervalul de încredere (adică rata de eroare de tip I) în comparație cu r
Media (rezultate_unif $ boot_type1) * 100`% din estimările bootstrap. Următorul tabel compară erorile de tip I pentru fiecare eșantion în comparație cu bootstrap -ul estimat din acel eșantion.
tab <- table(results_unif$samp_type1, results_unif$boot_type1, useNA = 'ifany') tab ## ## FALSE TRUE ## FALSE 477 3 ## TRUE 0 20
În general, comiterea unei erori de tip I este aceeași, indiferent de metodă, deși au existat 3 cazuri în care bootstrap -ul ar fi dus la o rată de eroare de tip I în care abordarea standard de eroare nu ar fi.
Următoarele parcele arată relația dintre media estimată (stânga) și lățimea intervalului de condamnare (dreapta) pentru fiecare eșantion și bootstrap -ul corespunzător.
results_unif |> ggplot(aes(x = samp_mean, y = boot_mean)) + geom_vline(xintercept = mean(pop_unif), color = 'blue') + geom_hline(yintercept = mean(pop_unif), color = 'blue') + geom_abline() + geom_point() + ggtitle("Sample mean vs bootstrap mean")
results_unif |> dplyr::mutate(samp_ci_width = samp_ci_high - samp_ci_low, boot_ci_width = boot_ci_high - boot_ci_low) |> ggplot(aes(x = samp_ci_width, y = boot_ci_width)) + geom_abline() + geom_point() + ggtitle('Sample vs boostrap confidence interval width')
Distribuție înclinată pentru populație
Vom repeta aceeași analiză folosind o distribuție pozitivă înclinată.
pop_skewed <- rnbinom(1e5, 3, .5) ggplot(data.frame(x = pop_skewed), aes(x = x)) + geom_density(bw = 0.75)
Media populației pentru această distribuție este 2.99792
results_skewed <- bootstrap_clt_simulation(pop = pop_skewed, seed = 42, verbose = FALSE) mean(results_skewed$samp_type1) # Percent of samples with Type I error ## (1) 0.05 mean(results_skewed$boot_type1) # Percent of bootstrap estimates with Type I error ## (1) 0.052 # CLT vs Bootstrap Type I error rate table(results_skewed$samp_type1, results_skewed$boot_type1, useNA = 'ifany') ## ## FALSE TRUE ## FALSE 473 2 ## TRUE 1 24 results_skewed |> ggplot(aes(x = samp_mean, y = boot_mean)) + geom_vline(xintercept = mean(pop_skewed), color = 'blue') + geom_hline(yintercept = mean(pop_skewed), color = 'blue') + geom_abline() + geom_point() + ggtitle("Sample mean vs bootstrap mean")
results_skewed |> dplyr::mutate(samp_ci_width = samp_ci_high - samp_ci_low, boot_ci_width = boot_ci_high - boot_ci_low) |> ggplot(aes(x = samp_ci_width, y = boot_ci_width)) + geom_abline() + geom_point() + ggtitle('Sample vs boostrap confidence interval width')
Putem vedea că rezultatele sunt foarte asemănătoare cu cea a distirubului uniform. Explorarea unui caz în care bootstrap -ul ar fi dus la o eroare de tip I în care abordarea standard de eroare nu ar dezvălui că este foarte aproape, diferența este mai mică de 0,1.
results_differ <- results_skewed |> dplyr::filter(!samp_type1 & boot_type1) results_differ ## seed samp_mean samp_se samp_ci_low samp_ci_high samp_type1 boot_mean ## 1 443 3.866667 0.4516466 2.942946 4.790388 FALSE 3.924733 ## 2 474 3.933333 0.4816956 2.948155 4.918511 FALSE 3.956800 ## boot_ci_low boot_ci_high boot_type1 ## 1 3.044802 4.804665 TRUE ## 2 3.018549 4.895051 TRUE set.seed(results_differ(1,)$seed) samp <- sample(pop_skewed, size = 30) boot_samp <- numeric(500) for(j in 1:500) { boot_samp(j) <- sample(samp, size = length(samp), replace = TRUE) |> mean() } cv = abs(qt(0.025, df = 30 - 1)) mean(pop_skewed) ## (1) 2.99792 ci <- c(mean(samp) - cv * sd(samp) / sqrt(30), mean(samp) + cv * sd(samp) / sqrt(30)) ci ## (1) 2.942946 4.790388 mean(pop_skewed) < ci(1) | mean(pop_skewed) > ci(2) ## (1) FALSE ci_boot <- c(mean(boot_samp) - cv * sd(boot_samp), mean(boot_samp) + cv * sd(boot_samp)) ci_boot ## (1) 3.044802 4.804665 mean(pop_skewed) < ci_boot(1) | mean(pop_skewed) > ci_boot(2) ## (1) TRUE
Adăugarea unui mai vechi
Să luăm în considerare un eșantion care obligă cea mai mare valoare din populație să fie în eșantion.
set.seed(2112) samp_outlier <- c(sample(pop_skewed, size = 29), max(pop_skewed)) boot_samp <- numeric(500) for(j in 1:500) { boot_samp(j) <- sample(samp, size = length(samp), replace = TRUE) |> mean() } ci <- c(mean(samp_outlier) - cv * sd(samp_outlier) / sqrt(30), mean(samp_outlier) + cv * sd(samp_outlier) / sqrt(30)) ci ## (1) 1.647006 4.952994 mean(pop_skewed) < ci(1) | mean(pop_skewed) > ci(2) ## (1) FALSE ci_boot <- c(mean(boot_samp) - cv * sd(boot_samp), mean(boot_samp) + cv * sd(boot_samp)) ci_boot ## (1) 2.905153 4.781381 mean(pop_skewed) < ci_boot(1) | mean(pop_skewed) > ci_boot(2) ## (1) FALSE
În acest exemplu, vedem că președintele celor mai vechi are un impact mai mare asupra intervalului de încredere, cu intervalul de încredere în bootstrap fiind mult mai mic.