【问题标题】:How can I build partial dependence plots with brt shapes?如何构建具有 brt 形状的部分依赖图?
【发布时间】:2020-03-25 15:58:12
【问题描述】:

我没有在 R 中练习,我需要一些帮助。我是一名生态学家,我有一个变量矩阵,其中“TD0”、“TD1”、“TD2”是响应变量,“Chao”、“age”、“slope”是解释变量。

ID.plot TD0    TD1    TD2      Chao age slope
1 GS_Ci01N  20  8.898  6.488 0.6521390  26     2
2 GS_Ci03N  26  7.788  4.883 0.2335441  26     2
3 GS_Ci04N  31 10.482  7.282 0.5234748  26     0
4 GS_Ci05N  47 18.108 11.989 0.3110385  26     3
5 GS_Ci06N  47 16.332 10.107 0.4529010  26     0
6 GS_Ci07N  31  9.478  5.725 0.5524426  26     1

db.chao <- read.table(text=db.chao, header = TRUE)

我构建了增强回归树 (BRT) 来定义解释性响应形状的阈值。我使用了“dismo”和“gbm”包。

mod0

mod1

mod2

我得到了三个模型:

  • “mod0”描述TD0与解释变量的关系
  • “mod1”描述TD1与解释变量的关系
  • “mod2”描述TD2与解释变量的关系

我为每个人构建了如下面板图(这些只是示例): enter image description here

enter image description here

enter image description here

对于每个响应变量,我有三个图表,每个解释变量一个。

我用这个脚本获得了它们:

gbm.plot(mod.TD0, n.plots = 3, write.title= FALSE, main = "TD0", rug = T, smooth = TRUE, plot.layout=c(1,3), common.scale = T)

gbm.plot(mod.TD1, n.plots = 3, write.title= FALSE, main = "TD1", rug = T, smooth = TRUE, plot.layout=c(1,3), common.scale = T)

gbm.plot(mod.TD2, n.plots = 3, write.title= FALSE, main = "TD2", rug = T, smooth = TRUE, plot.layout=c(1,3), common.scale = T)

实际上我想要三个图表,每个解释变量一个,然后,如果可能的话,我希望在每个图表中重叠三个响应变量的形状 strong>(具有三种不同的线条或颜色)。

我想我应该使用“pdp”包来构建部分依赖图,但我不能这样做。

如果有人可以帮助我,我将不胜感激。

非常感谢!

【问题讨论】:

    标签: r plot


    【解决方案1】:

    我不太确定 gbm 是如何工作的,以及为什么它需要树的数量来预测输出,但这里有一个使用 pdpgridExtra 包的工作示例:

    library(pdp)
    ntrees <- 250 # Number of trees to use to predict data
    pred <- function(object, newdata) {
      pred <- predict(object, newdata, n.trees = ntrees)
      mean(pred)
    }
    pdps1 <- pdps2 <- pdps3 <- list()
    for (i in 1:3) {
      pdps1[[i]] <- partial(mod0, pred.var = names(db.chao)[i+4], 
                           train = db.chao, plot = TRUE, 
                           pred.fun = pred, recursive = F)
      pdps2[[i]] <- partial(mod1, pred.var = names(db.chao)[i+4], 
                           train = db.chao, plot = TRUE,
                           pred.fun = pred, recursive = F)
      pdps3[[i]] <- partial(mod2, pred.var = names(db.chao)[i+4], 
                           train = db.chao, plot = TRUE,
                           pred.fun = pred, recursive = F)
    }
    gridExtra::grid.arrange(grobs = pdps1, nrow = 1) # For the first model
    gridExtra::grid.arrange(grobs = pdps2, nrow = 1) # For the second model
    gridExtra::grid.arrange(grobs = pdps3, nrow = 1) # For the third model
    

    希望这会有所帮助!

    编辑

    按照 OP 的要求,仅在三个地块中获取所有 pdps,并使用不同数量的树来预测值:

    library(pdp)
    ntrees1 <- 150 # Number of trees to use to predict data with model1
    ntrees2 <- 250 # Number of trees to use to predict data with model2
    ntrees3 <- 50 # Number of trees to use to predict data with model3
    pred1 <- function(object, newdata) {
      pred <- predict(object, newdata, n.trees = ntrees1)
      mean(pred)
    }
    pred2 <- function(object, newdata) {
      pred <- predict(object, newdata, n.trees = ntrees2)
      mean(pred)
    }
    pred3 <- function(object, newdata) {
      pred <- predict(object, newdata, n.trees = ntrees3)
      mean(pred)
    }
    # Function to obtain legend to plot later in grid.arrange
    get_legend<-function(myggplot){
      tmp <- ggplot_gtable(ggplot_build(myggplot))
      leg <- which(sapply(tmp$grobs, function(x) x$name) == "guide-box")
      legend <- tmp$grobs[[leg]]
      return(legend)
    }
    # Obtain partial dependence data instead of plot
    pdps1 <- pdps2 <- pdps3 <- list()
    plotlist <- list()
    
    for (i in 1:3) {
      # Create local environment to prevent ggplot to overwrite the plots with the iterator 
      local({
        i <- i
        pdps1[[i]] <<- partial(mod0, pred.var = names(db.chao)[i+4], 
                              train = db.chao, plot = FALSE, 
                              pred.fun = pred1, recursive = F)
        pdps2[[i]] <<- partial(mod1, pred.var = names(db.chao)[i+4], 
                              train = db.chao, plot = FALSE,
                              pred.fun = pred2, recursive = F)
        pdps3[[i]] <<- partial(mod2, pred.var = names(db.chao)[i+4], 
                              train = db.chao, plot = FALSE,
                              pred.fun = pred3, recursive = F)
        pdp <- rbind(pdps1[[i]],pdps2[[i]],pdps3[[i]])
        pdp <- cbind(pdp,rep(c("y1","y2","y3"), each = nrow(pdps1[[i]])))
        names(pdp)[3] <- "#output"
    
        plotlist[[i]] <<- ggplot(pdp) +
          geom_line(aes(x = pdp[,1], y = pdp[,2], 
                        group = pdp[,3], color = pdp[,3])) +
          xlab(names(pdp)[1]) + ylab("yhat") + 
          ggtitle(paste0("PDP of ",names(pdp)[1])) +
          labs(color = "#output")
    
      })
      legend <- get_legend(plotlist[[i]])
      plotlist[[i]] <- plotlist[[i]] + theme(legend.position = "none")
    }
    plotlist[[4]] <- legend
    
    gridExtra::grid.arrange(grobs = plotlist, nrow = 1, widths=c(2.3, 2.3, 2.3, 0.8))
    

    【讨论】:

    • 您好,非常感谢。实际上,通过这种方式,我将获得九张图(每个模型三张)。但我只想构建三个图表,每个解释变量一个,在每个解释变量中,我希望看到三个响应变量的形状重叠在一起。你可以帮帮我吗?此外,每个模型都有不同数量的树。我不能只使用一个“ntrees”值。最后,为什么要使用 [i+4]? 4 是什么意思?
    • 查看编辑以对每个模型使用不同的 n.trees,并且仅在三个图中使用所有 pdps。 [i+4] 只是因为您构建数据框架的方式是您的解释变量是第 5、第 6 和第 7 个,由于迭代器从 1 到 3,您需要在计算时添加 4 来选择解释变量for loop中的 pdp
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-23
    • 1970-01-01
    • 2023-03-18
    相关资源
    最近更新 更多