【问题标题】:Get multiple regression coefficient values calculated by resampling获取通过重采样计算的多个回归系数值
【发布时间】:2020-03-08 20:45:45
【问题描述】:

我正在使用重采样计算多个线性模型的系数。之前我是使用boot函数,但是以后需要在分析中加​​入新的统计数据所以我觉得这种方式比较好。一个可复制的例子:

iris <- iris[,1:4]

nboots <- 100
ncol = ncol(iris)
boot.r.squared <- numeric(nboots)      
boot.p_model <- numeric(nboots)
boot.coef_p <- numeric(nboots)
boot.coef_estimate <- matrix(nrow= nboots,ncol=ncol)
boot.coef_error <- matrix(nrow= nboots,ncol=ncol)
boot.coef_t <- matrix(nrow= nboots,ncol=ncol)
boot.coef_p <- matrix(nrow= nboots,ncol=ncol)

for(i in 1:nboots){
  boot.samp <- iris[sample(nrow(iris),size = 100, replace = TRUE,), ] 
  model <- lm(boot.samp$Sepal.Length ~ .,boot.samp)
  model.sum <- summary(model)

  boot.r.squared[i] <- model.sum$r.squared
  stat <- model.sum$fstatistic
  boot.p_model[i] <- pf(stat[1], stat[2], stat[3], lower.tail = FALSE)

  boot.coef_estimate[i, 1:length(model$coefficients)] <- model$coefficients[1]
  boot.coef_error[i, 1:length(model$coefficients)] <- model$coefficients[2]
  boot.coef_t[i, 1:length(model$coefficients)] <- model$coefficients[3]
  boot.coef_p[i, 1:length(model$coefficients)] <- model$coefficients[4] 
}

但我无法正确保存矩阵形式的系数。我想保存 4 个矩阵,每个矩阵包含:参数、误差、统计 t 和 p 值。

使用此代码,所有列都相同。我尝试 put [,1] 保存第一列,但发生此错误。我该如何解决这个错误?

模型 $ 系数 [, 1] 中的错误:维数不正确

【问题讨论】:

    标签: r regression resampling statistics-bootstrap


    【解决方案1】:

    您的代码对我有效,没有错误。您可能尝试了不同的重复次数,却忘记更新循环之前定义的空对象的大小,因为当我更改为 nboots &lt;- 1000 时,我可能会重现您的错误。

    您可以不使用for 循环,而是使用replicate()(它基本上是lapply() 的包装器)。优点是它可能更简单一些,并且您不需要事先定义空对象。

    过程是,首先,定义一个引导函数,比如bootFun()第二,使用replicate()的实际引导函数产生一个数组,最后第三,将数组中的数据处理成所需的矩阵。

    # Step 1 bootstrap function
    bootFun <- function(X) {
      fit <- lm(Sepal.Length ~ ., data=X)
      s <- summary(fit)
      r2 <- s$r.squared
      f <- s$fstatistic
      p.f <- pf(f[1], f[2], f[3], lower.tail = FALSE)
      ms <- s$coefficients
      return(cbind(ms, r2, p.f))
    }
    
    # Step 2 bootstrap
    nboots <- 1e2
    set.seed(42)  # for sake of reproducibility
    A <- replicate(nboots, bootFun(iris[sample(1:nrow(iris), size=nrow(iris), replace=TRUE), ]))
    # Note: I used here `size=nrow(iris)`, but you also could use size=100 if this is your method
    
    # Step 3 process array ("de-transpose" and transform to list)
    Ap <- aperm(A, c(3, 1, 2))  # aperm() is similar to t() for matrices
    Aps <- asplit(Ap, 3)  # split the array into a handy list
    
    # or in one step
    Aps <- asplit(aperm(A, c(3, 1, 2)), 3)
    

    结果

    现在您有了一个包含所有矩阵的列表,请查看列表对象的名称。

    names(Aps)
    # [1] "Estimate"   "Std. Error" "t value"    "Pr(>|t|)"   "r2"         "p.f"
    

    所以,如果我们例如想要我们估计的矩阵,我们只需这样做:

    estimates <- Aps$Estimate
    
    estimates[1:3, ]
    #      (Intercept) Sepal.Width Petal.Length Petal.Width
    # [1,]    1.353531   0.7655760    0.8322749  -0.7775090
    # [2,]    1.777431   0.6653308    0.7353491  -0.6024095
    # [3,]    2.029428   0.5825554    0.6941457  -0.4795787
    

    请注意,F-统计和 R2 也是矩阵,并在每个系数的每一行中重复。由于您只需要一个,因此只需提取例如第一栏:

    Aps$p.f[1:3, ]
    #       (Intercept)  Sepal.Width Petal.Length  Petal.Width
    # [1,] 2.759019e-65 2.759019e-65 2.759019e-65 2.759019e-65
    # [2,] 5.451912e-66 5.451912e-66 5.451912e-66 5.451912e-66
    # [3,] 3.288712e-54 3.288712e-54 3.288712e-54 3.288712e-54
    
    Aps$p.f[1:3, 1]
    # [1] 2.759019e-65 5.451912e-66 3.288712e-54
    

    基准测试

    两种方法的速度几乎相同,replicate() 的优势很小。这是一个比较我使用nboot=1,000复制的两种方法的基准。

    # Unit: seconds
    #      expr      min       lq     mean   median       uq      max neval cld
    #   forloop 2.215259 2.235797 2.332234 2.381035 2.401933 2.700622   100   a
    # replicate 2.218291 2.240570 2.313526 2.257905 2.400532 2.601958   100   a
    

    【讨论】:

    • 谢谢!结果以它的方式变得更好,现在事情能够计算其他统计数据。我不知道 aperm,我会研究这个功能,因为它可以让事情变得更好。
    【解决方案2】:

    关于您的原始代码,您混淆了 model 和 model.sum。插入系数、误差等时需要获取汇总(模型)的系数。

    见下文:

    for(i in 1:nboots){
      boot.samp <- iris[sample(nrow(iris),size = 100, replace = TRUE,), ] 
      model <- lm(boot.samp$Sepal.Length ~ .,boot.samp)
      model.sum <- summary(model)
    
      boot.r.squared[i] <- model.sum$r.squared
      stat <- model.sum$fstatistic
      boot.p_model[i] <- pf(stat[1], stat[2], stat[3], lower.tail = FALSE)
    
      # this is the part where you need to use model.sum
      boot.coef_estimate[i, 1:length(model$coefficients)] <- model.sum$coefficients[,1]
      boot.coef_error[i, 1:length(model$coefficients)] <- model.sum$coefficients[,2]
      boot.coef_t[i, 1:length(model$coefficients)] <- model.sum$coefficients[,3]
      boot.coef_p[i, 1:length(model$coefficients)] <- model.sum$coefficients[,4] 
    }
    

    作为旁注,您想知道使用 boot 估计系数的可变性。对于其他统计数据,如 r 平方、p 值,在引导后解释这些数据并不是那么有用。所以想想你想从引导程序中知道什么。

    还可以查看@jay.sf 的答案,这是一种更简洁的方法来包装您的计算函数。

    【讨论】:

    • 你是对的,从统计的角度来看,仅这些系数的引导程序并没有增加太多。我将它们与初始统计数据进行比较并得到 p 的值
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-24
    • 2021-01-16
    • 1970-01-01
    相关资源
    最近更新 更多