Как на самом деле работает самозагрузка в R?

22

Я изучал загрузочный пакет в R, и хотя я нашел несколько хороших учебников по его использованию, мне еще предстоит найти что-то, что точно описывает то, что происходит "за кулисами". Например, в этом примере руководство показывает, как использовать стандартные коэффициенты регрессии в качестве отправной точки для регрессии начальной загрузки, но не объясняет, что на самом деле делает процедура начальной загрузки для получения коэффициентов регрессии начальной загрузки. Похоже, что происходит какой-то итерационный процесс, но я не могу понять, что именно происходит.

zgall1
источник
3
Прошло много времени с тех пор, как я последний раз открывал его, поэтому я не знаю, ответит ли он на ваш вопрос, но загрузочный пакет основан, в частности, на методах, подробно описанных в Davison, AC, & Hinkley, DV (1997). Методы начальной загрузки и их применение. Кембридж: издательство Кембриджского университета. (Ссылка также указана в файле справки для загрузочного пакета.)
Gala

Ответы:

34

Есть несколько «разновидностей» или форм начальной загрузки (например, непараметрическая, параметрическая, остаточная повторная выборка и многие другие). Начальная загрузка в примере называется непараметрической начальной загрузкой или повторной выборкой регистра (см. Здесь , здесь , здесь и здесь для приложений в регрессии). Основная идея заключается в том, что вы рассматриваете свою выборку как популяцию и неоднократно вытягиваете из нее новые образцы с заменой . Все исходные наблюдения имеют одинаковую вероятность попадания в новую выборку. Затем вы вычисляете и сохраняете статистику (и), представляющую интерес, это может быть среднее значение, медиана или коэффициенты регрессии с использованием вновь созданной выборки., Это повторяется раз. На каждой итерации некоторые наблюдения из вашей исходной выборки составляются несколько раз, тогда как некоторые наблюдения могут не отображаться вообще. После n итераций у вас есть n сохраненных оценок начальной загрузки интересующей статистики (ий) (например, если n = 1000 и статистика интереса является средним значением, у вас есть 1000 загрузочных оценок среднего значения). И, наконец, вычисляются сводные статистические данные, такие как среднее значение, медиана и стандартное отклонение n оценок начальной загрузки.NNNNзнак равно1000N

Самозагрузка часто используется для:

  1. Расчет доверительных интервалов (и оценка стандартных ошибок)
  2. Оценка смещения точечных оценок

Существует несколько методов для расчета доверительных интервалов на основе примеров начальной загрузки (в этом документе представлены пояснения и рекомендации). Один очень простой метод для вычисления 95-процентного доверительного интервала - это просто расчет эмпирического 2,5-го и 97,5-го процентилей выборок начальной загрузки (этот интервал называется интервалом начальной загрузки; см. Код ниже). Метод простого процентиля с интервалом редко используется на практике, так как существуют более эффективные методы, такие как скорректированная на смещение и ускоренная начальная загрузка (BCa). Интервалы BCa корректируются как для смещения, так и для асимметрии в распределении начальной загрузки.

Смещения просто оценивается как разница между средней из сохраненных выборок начальной загрузки и первоначальной оценки (ов).N

Давайте повторим пример с веб-сайта, но воспользуемся собственным циклом, включающим идеи, которые я изложил выше (рисуем несколько раз с заменой):

#-----------------------------------------------------------------------------
# Load packages
#-----------------------------------------------------------------------------

require(ggplot2)
require(pscl)
require(MASS)
require(boot)

#-----------------------------------------------------------------------------
# Load data
#-----------------------------------------------------------------------------

zinb <- read.csv("http://www.ats.ucla.edu/stat/data/fish.csv")
zinb <- within(zinb, {
  nofish <- factor(nofish)
  livebait <- factor(livebait)
  camper <- factor(camper)
})

#-----------------------------------------------------------------------------
# Calculate zero-inflated regression
#-----------------------------------------------------------------------------

m1 <- zeroinfl(count ~ child + camper | persons, data = zinb,
               dist = "negbin", EM = TRUE)

#-----------------------------------------------------------------------------
# Store the original regression coefficients
#-----------------------------------------------------------------------------

original.estimates <- as.vector(t(do.call(rbind, coef(summary(m1)))[, 1:2]))

#-----------------------------------------------------------------------------
# Set the number of replications
#-----------------------------------------------------------------------------

n.sim <- 2000

#-----------------------------------------------------------------------------
# Set up a matrix to store the results
#-----------------------------------------------------------------------------

store.matrix <- matrix(NA, nrow=n.sim, ncol=12)

#-----------------------------------------------------------------------------
# The loop
#-----------------------------------------------------------------------------

set.seed(123)

for(i in 1:n.sim) {

  #-----------------------------------------------------------------------------
  # Draw the observations WITH replacement
  #-----------------------------------------------------------------------------

  data.new <- zinb[sample(1:dim(zinb)[1], dim(zinb)[1], replace=TRUE),]

  #-----------------------------------------------------------------------------
  # Calculate the model with this "new" data
  #-----------------------------------------------------------------------------

  m <- zeroinfl(count ~ child + camper | persons,
                data = data.new, dist = "negbin",
                start = list(count = c(1.3711, -1.5152, 0.879),
                             zero = c(1.6028, -1.6663)))

  #-----------------------------------------------------------------------------
  # Store the results
  #-----------------------------------------------------------------------------

  store.matrix[i, ] <- as.vector(t(do.call(rbind, coef(summary(m)))[, 1:2]))

}


#-----------------------------------------------------------------------------
# Save the means, medians and SDs of the bootstrapped statistics
#-----------------------------------------------------------------------------

boot.means <- colMeans(store.matrix, na.rm=T)

boot.medians <- apply(store.matrix,2,median, na.rm=T)

boot.sds <- apply(store.matrix,2,sd, na.rm=T)

#-----------------------------------------------------------------------------
# The bootstrap bias is the difference between the mean bootstrap estimates
# and the original estimates
#-----------------------------------------------------------------------------

boot.bias <- colMeans(store.matrix, na.rm=T) - original.estimates

#-----------------------------------------------------------------------------
# Basic bootstrap CIs based on the empirical quantiles
#-----------------------------------------------------------------------------

conf.mat <- matrix(apply(store.matrix, 2 ,quantile, c(0.025, 0.975), na.rm=T),
ncol=2, byrow=TRUE)
colnames(conf.mat) <- c("95%-CI Lower", "95%-CI Upper")

А вот наша сводная таблица:

#-----------------------------------------------------------------------------
# Set up summary data frame
#-----------------------------------------------------------------------------

summary.frame <- data.frame(mean=boot.means, median=boot.medians,
sd=boot.sds, bias=boot.bias, "CI_lower"=conf.mat[,1], "CI_upper"=conf.mat[,2])

summary.frame

      mean  median       sd       bias CI_lower CI_upper
1   1.2998  1.3013  0.39674 -0.0712912  0.51960   2.0605
2   0.2527  0.2486  0.03208 -0.0034461  0.19898   0.3229
3  -1.5662 -1.5572  0.26220 -0.0509239 -2.12900  -1.0920
4   0.2005  0.1986  0.01949  0.0049019  0.16744   0.2418
5   0.9544  0.9252  0.48915  0.0753405  0.03493   1.9025
6   0.2702  0.2688  0.02043  0.0009583  0.23272   0.3137
7  -0.8997 -0.9082  0.22174  0.0856793 -1.30664  -0.4380
8   0.1789  0.1781  0.01667  0.0029513  0.14494   0.2140
9   2.0683  1.7719  1.59102  0.4654898  0.44150   8.0471
10  4.0209  0.8270 13.23434  3.1845710  0.58114  57.6417
11 -2.0969 -1.6717  1.56311 -0.4306844 -8.43440  -1.1156
12  3.8660  0.6435 13.27525  3.1870642  0.33631  57.6062

Некоторые объяснения

  • Разница между средним значением оценок начальной загрузки и исходными оценками заключается в том, что называется «смещением» в результатах boot
  • Что выводит bootвызовы "стандартная ошибка" - это стандартное отклонение загруженных оценок

Сравните это с выводом из boot:

#-----------------------------------------------------------------------------
# Compare with boot output and confidence intervals
#-----------------------------------------------------------------------------

set.seed(10)
res <- boot(zinb, f, R = 2000, parallel = "snow", ncpus = 4)

res

Bootstrap Statistics :
       original       bias    std. error
t1*   1.3710504 -0.076735010  0.39842905
t2*   0.2561136 -0.003127401  0.03172301
t3*  -1.5152609 -0.064110745  0.26554358
t4*   0.1955916  0.005819378  0.01933571
t5*   0.8790522  0.083866901  0.49476780
t6*   0.2692734  0.001475496  0.01957823
t7*  -0.9853566  0.083186595  0.22384444
t8*   0.1759504  0.002507872  0.01648298
t9*   1.6031354  0.482973831  1.58603356
t10*  0.8365225  3.240981223 13.86307093
t11* -1.6665917 -0.453059768  1.55143344
t12*  0.6793077  3.247826469 13.90167954

perc.cis <- matrix(NA, nrow=dim(res$t)[2], ncol=2)
    for( i in 1:dim(res$t)[2] ) {
  perc.cis[i,] <- boot.ci(res, conf=0.95, type="perc", index=i)$percent[4:5] 
}
colnames(perc.cis) <- c("95%-CI Lower", "95%-CI Upper")

perc.cis 

      95%-CI Lower 95%-CI Upper
 [1,]      0.52240       2.1035
 [2,]      0.19984       0.3220
 [3,]     -2.12820      -1.1012
 [4,]      0.16754       0.2430
 [5,]      0.04817       1.9084
 [6,]      0.23401       0.3124
 [7,]     -1.29964      -0.4314
 [8,]      0.14517       0.2149
 [9,]      0.29993       8.0463
[10,]      0.57248      56.6710
[11,]     -8.64798      -1.1088
[12,]      0.33048      56.6702

#-----------------------------------------------------------------------------
# Our summary table
#-----------------------------------------------------------------------------

summary.frame

      mean  median       sd       bias CI_lower CI_upper
1   1.2998  1.3013  0.39674 -0.0712912  0.51960   2.0605
2   0.2527  0.2486  0.03208 -0.0034461  0.19898   0.3229
3  -1.5662 -1.5572  0.26220 -0.0509239 -2.12900  -1.0920
4   0.2005  0.1986  0.01949  0.0049019  0.16744   0.2418
5   0.9544  0.9252  0.48915  0.0753405  0.03493   1.9025
6   0.2702  0.2688  0.02043  0.0009583  0.23272   0.3137
7  -0.8997 -0.9082  0.22174  0.0856793 -1.30664  -0.4380
8   0.1789  0.1781  0.01667  0.0029513  0.14494   0.2140
9   2.0683  1.7719  1.59102  0.4654898  0.44150   8.0471
10  4.0209  0.8270 13.23434  3.1845710  0.58114  57.6417
11 -2.0969 -1.6717  1.56311 -0.4306844 -8.43440  -1.1156
12  3.8660  0.6435 13.27525  3.1870642  0.33631  57.6062

Сравните столбцы «bias» и «std. Error» со столбцом «sd» нашей собственной сводной таблицы. Наши 95% -ые доверительные интервалы очень похожи на доверительные интервалы, рассчитанные с boot.ciиспользованием метода процентилей (но не все: посмотрите на нижний предел параметра с индексом 9).

COOLSerdash
источник
Спасибо за подробный ответ. Вы в основном говорите, что коэффициенты являются средним из 2000 наборов коэффициентов, которые были сгенерированы?
zgall1
4
T
«Основная идея заключается в том, что вы рассматриваете свою выборку как совокупность и постоянно отбираете из нее новые выборки с заменой» - как определить размер новых выборок?
Sinusx
1
@Sinusx Обычно вы рисуете образцы того же размера, что и исходный образец. Важнейшая идея - нарисовать образец с заменой. Таким образом, некоторые значения из исходного образца будут отображаться несколько раз, а некоторые - вовсе нет.
COOLSerdash
6

Вы должны сосредоточиться на функции, которая передается в bootкачестве параметра «статистика», и заметить, как она построена.

f <- function(data, i) {
  require(pscl)
  m <- zeroinfl(count ~ child + camper | persons,
    data = data[i, ], dist = "negbin",
    start = list(count = c(1.3711, -1.5152, 0.879), zero = c(1.6028, -1.6663)))
  as.vector(t(do.call(rbind, coef(summary(m)))[, 1:2]))
}

Аргумент «data» будет получать весь фрейм данных, но аргумент «i» будет получать выборку индексов строк, сгенерированных «boot» и взятых из 1: NROW (data). Как видно из этого кода, «i» затем используется для создания нового образца, который передается, zeroinlа затем возвращаются только выбранные части его результатов.

Давайте представим, что «я» это {1,2,3,3,3,6,7,7,10}. Функция «[» будет возвращать только те строки с 3 копиями строки 3 и 2 копиями строки 7. Это будет основой для одного zeroinl()вычисления, а затем коэффициенты будут возвращены bootкак результат этой копии процесса. Количество таких повторов контролируется параметром «R».

Поскольку statisticв этом случае возвращаются только коэффициенты регрессии , bootфункция вернет эти накопленные коэффициенты как значение «t». Дальнейшие сравнения могут быть выполнены другими функциями загрузочного пакета.

Dwin
источник