引导分层/多级数据(重采样集群)

机器算法验证 r 引导程序 固定效应模型
2022-03-22 03:44:31

我正在生成一个脚本,用于从cats数据集(来自-MASS-包)创建引导样本。

按照戴维森和欣克利的教科书 [1],我运行了一个简单的线性回归,并采用了一种基本的非参数程序来从独立同分布观察中引导,即对重采样

原始样本的形式为:

Bwt   Hwt

2.0   7.0
2.1   7.2

...

1.9    6.8

通过一个单变量线性模型,我们想通过他们的大脑重量来解释猫的壁炉重量。

代码是:

library(MASS)
library(boot)


##################
#   CATS MODEL   #
##################

cats.lm <- glm(Hwt ~ Bwt, data=cats)
cats.diag <- glm.diag.plots(cats.lm, ret=T)


#######################
#   CASE resampling   #
#######################

cats.fit <- function(data) coef(glm(data$Hwt ~ data$Bwt)) 
statistic.coef <- function(data, i) cats.fit(data[i,]) 

bootl <- boot(data=cats, statistic=statistic.coef, R=999)

现在假设存在一个聚类变量cluster = 1, 2,..., 24(例如,每只猫都属于给定的垃圾)。为简单起见,假设数据是平衡的:每个集群有 6 个观察值。因此,24 窝中的每一窝都由 6 只猫(即n_cluster = 6n = 144)组成。

可以通过以下方式创建假cluster变量:

q <- rep(1:24, times=6)
cluster <- sample(q)
c.data <- cbind(cats, cluster)

我有两个相关的问题:

如何根据(集群)数据集结构模拟样本?如何在集群级别进行重采样?我想对具有替换的集群进行采样,并将每个选定集群中的观察设置为原始数据集中的观察值(即在替换集群的情况下进行采样,而不是替换每个集群中的观察)。

这是戴维森(第 100 页)提出的策略。假设我们抽取B = 100样本。它们中的每一个都应该由 24 个可能经常出现的集群(例如cluster = 3, 3, 1, 4, 12, 11, 12, 5, 6, 8, 17, 19, 10, 9, 7, 7, 16, 18, 24, 23, 11, 15, 20, 1)组成,并且每个集群应该包含与原始数据集相同的 6 个观察值。如何做到这一点R(有或没有-boot-包裹。)你有其他建议吗?

第二个问题涉及初始回归模型。假设我采用固定效应模型,具有集群级截距。它是否改变了采用的重采样程序?

[1] 戴维森,AC,欣克利,DV(1997 年)。引导方法及其应用剑桥大学出版社。

4个回答

只要在那里使用了任何重采样方法(即自 1960 年代中期以来),就在调查统计中已知对整个集群进行重采样,因此它是一种成熟的方法。请参阅我在http://www.citeulike.org/user/ctacmo/tag/survey_resampling收集的链接boot不能这样,我不知道;当我需要使用调查引导程序时,我使用survey包,虽然我上次检查时,它没有我需要的所有功能(据我所知,比如一些小样本更正)。

我不认为应用诸如固定效应之类的特定模型会改变很多,但是,IMO,残差自举做出了很多强有力的假设(残差是独立同分布的,模型是正确指定的)。它们中的每一个都很容易被打破,而集群结构肯定会打破 iid 假设。

有一些关于野生集群引导的计量经济学文献。他们假装自己在真空中工作,没有对这个主题进行所有这 50 年的调查统计研究,所以我不知道该怎么做。

我尝试自己解决问题,并生成了以下代码。

虽然它有效,但它可能会在速度方面得到改进。此外,如果可能的话,我宁愿找到一种使用该-boot-软件包的方法,因为它允许通过boot.ci...自动计算许多自举置信区间。

为简单起见,起始数据集包含嵌套在 6 个实验室(聚类变量)中的 18 只猫(“较低级别”观察结果)。数据集是平衡的(n_cluster = 3对于每个集群)。我们有一个回归量,x,用于解释y

假数据集和存储结果的矩阵是:

  # fake sample 
  dat <- expand.grid(cat=factor(1:3), lab=factor(1:6))
  dat <- cbind(dat, x=runif(18), y=runif(18, 2, 5))

  # empty matrix for storing coefficients estimates and standard errors of x
  B <- 50 # number of bootstrap samples
  b.sample <- matrix(nrow=B, ncol=3, dimnames=list(c(), c("sim", "b_x", "se_x")))
  b.sample[,1] <- rep(1:B)

在每次B迭代中,以下循环对 6 个有放回的簇进行采样,每个簇由 3 只无放回采样的猫组成(即保持簇的内部组成不变)。回归系数及其标准误差的估计值存储在先前创建的矩阵中:

  ####################################
  #   loop through "b.sample" rows   #
  ####################################

  for (i in seq(1:B)) {

  ###   sampling with replacement from the clustering variable   

    # sampling with replacement from "cluster" 
    cls <- sample(unique(dat$lab), replace=TRUE)
    cls.col <- data.frame(lab=cls)

    # reconstructing the overall simulated sample
    cls.resample <- merge(cls.col, dat, by="lab")


  ###   fitting linear model to simulated data    

    # model fit
    mod.fit <- function(data) glm(data$y ~ data$x)

    # estimated coefficients and standard errors
    b_x <- summary(mod.fit(data=cls.resample))$coefficients[2,1]
    	se_x <- summary(mod.fit(data=cls.resample))$coefficients[2,2]

    b.sample[i,2] <- b_x
    b.sample[i,3] <- se_x

  }

希望这会有所帮助,兰多

我最近不得不这样做并使用dplyr. 该解决方案不像 with 那样优雅data.table,但是:

library(dplyr)
replicate(B, {
  cluster_sample <- data.frame(cluster = sample(dat$cluster, replace = TRUE))
  dat_sample <- dat %>% inner_join(cluster_sample, by = 'cluster')
  coef(lm(y ~ x, data = dat_sample))
})

inner_join重复具有给定值的每一行,x出现在 中cluster的次数xcluster_sample

这是使用data.table(在@lando.carlissian 的数据上)进行引导的更简单(并且几乎毫无疑问更快)的方法:

library(data.table)
setDT(dat, key = "lab")
b.sample <- 
  replicate(B, dat[.(sample(unique(lab), replace = T)),
                   glm(y ~ x)$coefficients])