自举分层/多级数据(重采样群集)

时间:2012-12-30 14:47:52

标签: r hierarchical-clustering statistics-bootstrap

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

根据戴维森和欣克利的教科书[1],我进行了一个简单的线性回归,并采用了一个基本的非参数程序,用于从iid观察引导,即对重新取样

原始样本的格式为:

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] Davidson,A。C.,Hinkley,D。V.(1997)。 Bootstrap方法及其应用。剑桥大学出版社。

2 个答案:

答案 0 :(得分:7)

如果我理解正确,那么您尝试使用c.data作为输入:

  • 使用替换重新取样群集
  • 保持随机样本中每个群集与原始数据集中的点之间的关联(即c.data)
  • 使用采样群集创建引导程序

这是一个实现此目的的脚本,您可以将其包装到函数中重复R次,其中R是引导复制的数量

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

# get a vector with all clusters
c <- sort(unique(c.data$cluster))

# group the data points per cluster
clust.group <- function(c) {
    c.data[c.data$cluster==c,]
}

clust.list <- lapply(c,clust.group)

# resample clusters with replacement
c.sample <- sample(c, replace=T)

clust.sample <- clust.list[c.sample]

clust.size <- 6

# combine the cluster list back to a single data matrix
clust.bind <- function(c) {
    matrix(unlist(c),nrow=clust.size)
}

c.boot <- do.call(rbind,lapply(clust.sample,clust.bind))

# Just to maintain columns name
colnames(c.boot) <- names(c.data)

# the new data set (single bootstrap replicate)
c.boot

答案 1 :(得分:0)

我试图通过以下方式解决问题。 虽然它有效,但它在速度和“优雅”方面可能有所改进。此外,如果可能的话,我宁愿找到使用-boot-包的方法,因为它允许通过boot.ci自动计算一些自举置信区间......

为简单起见,起始数据集包含18个嵌套在6个实验室中的猫(“低级”观察结果)(聚类变量)。数据集是平衡的(每个群集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

  }

最终的自举标准错误是:

 boot_se_x <- sum(b.sample[,3])/(B-1) 
 boot_se_x

有没有办法采用-boot-包来做这件事?

另外,关于在集群级别采用固定效果而不是简单的线性回归,我的主要疑问是,在某些模拟样本中,我们可能没有选择一些初始集群,因此无法识别相关的特定于群集的拦截。如果您查看我发布的代码,从“机械”的角度来看它应该不是问题(在每次迭代时我们都可以使用不同的有限元模型,只有采样的集群的截距)。

我想知道所有这些

是否存在统计问题