Comment fonctionne réellement l'amorçage dans R?

22

J'ai étudié le package de démarrage dans R et bien que j'aie trouvé un certain nombre de bonnes amorces sur la façon de l'utiliser, je n'ai encore rien trouvé qui décrive exactement ce qui se passe "dans les coulisses". Par exemple, dans cet exemple , le guide montre comment utiliser les coefficients de régression standard comme point de départ pour une régression de bootstrap mais n'explique pas ce que la procédure de bootstrap fait réellement pour dériver les coefficients de régression de bootstrap. Il semble qu'il y ait une sorte de processus itératif qui se produit, mais je n'arrive pas à comprendre exactement ce qui se passe.

zgall1
la source
3
Cela fait longtemps que je ne l'ai pas ouvert pour la dernière fois, donc je ne sais pas s'il répondra à votre question, mais le package de démarrage est basé en particulier sur les méthodes détaillées dans Davison, AC et Hinkley, DV (1997). Méthodes d'amorçage et leur application. Cambridge: Cambridge University Press. (La référence est également citée dans le fichier d'aide du package de démarrage .)
Gala

Réponses:

34

Il existe plusieurs "saveurs" ou formes de bootstrap (par exemple non paramétrique, paramétrique, rééchantillonnage résiduel et bien d'autres). Le bootstrap dans l'exemple est appelé bootstrap non paramétrique , ou rééchantillonnage de cas (voir ici , ici , ici et ici pour les applications en régression). L'idée de base est que vous traitez votre échantillon comme une population et que vous en extrayez à plusieurs reprises de nouveaux échantillons avec remplacement . Toutes les observations originales ont une probabilité égale d'être attirées dans le nouvel échantillon. Ensuite, vous calculez et stockez les statistiques d'intérêt, cela peut être la moyenne, la médiane ou les coefficients de régression en utilisant l'échantillon nouvellement tiré. Ceci est répété fois. À chaque itération, certaines observations de votre échantillon d'origine sont tirées plusieurs fois tandis que certaines observations peuvent ne pas l'être du tout. Après itérations, vous avez estimations bootstrap stockées de la ou des statistiques d'intérêt (par exemple, si et que la statistique d'intérêt est la moyenne, vous avez 1000 estimations bootstrapées de la moyenne). Enfin, des statistiques sommaires telles que la moyenne, la médiane et l'écart type des estimations bootstrap sont calculées.nnnn=1000n

Le bootstrap est souvent utilisé pour:

  1. Calcul des intervalles de confiance (et estimation des erreurs types)
  2. Estimation du biais des estimations ponctuelles

Il existe plusieurs méthodes pour calculer les intervalles de confiance sur la base des échantillons bootstrap ( ce document fournit des explications et des conseils). Une méthode très simple pour calculer un intervalle de confiance à 95% consiste simplement à calculer les 2,5e et 97,5e centiles empiriques des échantillons de bootstrap (cet intervalle est appelé intervalle de percentile de bootstrap; voir le code ci-dessous). La méthode de l'intervalle centile simple est rarement utilisée dans la pratique car il existe de meilleures méthodes, telles que le bootstrap à correction de biais et accéléré (BCa). Les intervalles BCa s'ajustent à la fois pour le biais et l'asymétrie dans la distribution bootstrap.

n

Reprenons l'exemple du site Web, mais en utilisant notre propre boucle incorporant les idées que j'ai décrites ci-dessus (dessin à plusieurs reprises avec remplacement):

#-----------------------------------------------------------------------------
# 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")

Et voici notre tableau récapitulatif:

#-----------------------------------------------------------------------------
# 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

Quelques explications

  • La différence entre la moyenne des estimations bootstrap et les estimations originales est ce que l'on appelle le "biais" dans la sortie de boot
  • Ce que la sortie des bootappels "erreur standard" est l'écart type des estimations bootstrapées

Comparez-le avec la sortie de 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

Comparez les colonnes "biais" et "erreur standard" avec la colonne "sd" de notre propre tableau récapitulatif. Nos intervalles de confiance à 95% sont très similaires aux intervalles de confiance calculés en boot.ciutilisant la méthode du centile (pas tous cependant: regardez la limite inférieure du paramètre avec l'indice 9).

COOLSerdash
la source
Merci pour la réponse détaillée. Êtes-vous en train de dire que les coefficients sont la moyenne des 2000 ensembles de coefficients qui ont été générés?
zgall1
4
t
«L'idée de base est que vous traitez votre échantillon comme une population et que vous en tirez de nouveaux échantillons à plusieurs reprises avec remplacement» - comment déterminer quelle est la taille des nouveaux échantillons?
Sinusx
1
@Sinusx Normalement, vous dessinez des échantillons de la même taille que l'échantillon d'origine. L'idée cruciale est de prélever l'échantillon avec remplacement. Ainsi, certaines valeurs de l'échantillon d'origine seront dessinées plusieurs fois et d'autres pas du tout.
COOLSerdash
6

Vous devez vous concentrer sur la fonction qui est passée en boottant que paramètre "statistique" et remarquer comment elle est construite.

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]))
}

L'argument "data" va recevoir une trame de données entière, mais l'argument "i" va recevoir un échantillon d'indices de lignes générés par le "boot" et pris dans 1: NROW (data). Comme vous pouvez le voir à partir de ce code, "i" est ensuite utilisé pour créer un néo-échantillon qui est passé à zeroinl, puis seules les parties sélectionnées de ses résultats sont renvoyées.

Imaginons que "i" soit {1,2,3,3,3,6,7,7,10}. La fonction "[" renverra uniquement ces lignes avec 3 copies de la ligne 3 et 2 copies de la ligne 7. Ce serait la base d'un zeroinl()calcul unique , puis les coefficients seront retournés à bootla suite de cette réplique du processus. Le nombre de ces répliques est contrôlé par le paramètre "R".

Étant donné que seuls les coefficients de régression sont renvoyés statisticdans ce cas, la bootfonction renverra ces coefficients accumulés en tant que valeur de "t". D'autres comparaisons peuvent être effectuées par d'autres fonctions du package de démarrage.

DWin
la source