代码之家  ›  专栏  ›  技术社区  ›  Hugo

具有随机森林的图像分类(光栅堆栈)(package ranger)

  •  9
  • Hugo  · 技术社区  · 7 年前

    我正在使用R包ranger拟合一个随机森林,以对光栅图像进行分类。预测函数会产生误差,下面我提供一个可重复的示例。

    library(raster)
    library(nnet)
    library(ranger)
    data(iris)
    
    # put iris data into raster
    r<-list()
    for(i in 1:4){
      r[[i]]<-raster(nrows=10, ncols=15)
      r[[i]][]<-iris[,i]
    }
    r<-stack(r)
    names(r)<-names(iris)[1:4]
    
    # multinom (an example that works)
    nn.model <- multinom(Species ~ ., data=iris, trace=F)
    nn.pred<-predict(r,nn.model)
    
    # ranger (doesn't work)
    ranger.model<-ranger(Species ~ ., data=iris)   
    ranger.pred<-predict(r,ranger.model)
    

    v[cells]中出错,<-predv:矩阵上的下标数不正确

    虽然我真实数据的错误是

    替换长度的倍数

    我唯一想到的是流浪者。预测对象包括除感兴趣的预测之外的几个元素。无论如何,如何使用ranger在光栅堆栈上进行预测?

    4 回复  |  直到 6 年前
        1
  •  6
  •   ABMoeller    3 年前

    编辑,2021 07月15日

    关于使用 clusterR

    # First train the ranger model
    
    ranger.model <- ranger(Species ~ .
                           , data = iris
                           , probability = TRUE  # This argument is needed for se
                           , keep.inbag = TRUE   # So is this one
                           )
    
    
    # Create prediction function for clusterR
    
    f_se <- function(model, ...) predict(model, ...)$se
    
    
    # Predict se using clusterR
      
    beginCluster(2)
    
    map_se <- clusterR(r
                       , predict
                       , args = list(ranger.model
                                     , type = 'se'  # Remember to include this argument
                                     , fun = f_se
                                     )
                       )
    
    endCluster()
    

    通过在插入符号包的训练功能中训练模型,可以从光栅堆栈上的ranger模型运行预测:

    library(caret)
    ranger.model <- train(Species ~ ., data = iris, method = "ranger")  
    ranger.pred <- predict(r, ranger.model)
    

    但是,如果要预测标准误差,这不起作用,因为训练对象的预测函数不接受 type = 'se'

    https://cran.r-project.org/web/packages/raster/vignettes/functions.pdf

    # Function to predict standard errors on a raster
    predfun <- function(x, model, type, filename)
    {
      out <- raster(x)
      bs <- blockSize(out)
      out <- writeStart(out, filename, overwrite = TRUE)
      for (i in 1:bs$n) {
        v <- getValues(x, row = bs$row[i], nrows = bs$nrows[i])
        nas <- apply(v, 1, function(x) sum(is.na(x)))
        p <- numeric(length = nrow(v))
        p[nas > 0] <- NA
        p[nas == 0] <- predict(object = model,
                               v[nas == 0,],
                               type = 'se')$se
        out <- writeValues(out, p, bs$row[i])
      }
      out <- writeStop(out)
      return(out)
    }
    
    # New ranger model 
    ranger.model <- ranger(Species ~ .
                           , data = iris
                           , probability = TRUE
                           , keep.inbag  = TRUE
                           )
    # Run predictions
    se <- predfun(r
                  , model = ranger.model
                  , type  = "se"
                  , filename = paste0(getwd(), "/se.tif")
                  )
    
        2
  •  4
  •   m-dz    7 年前

    在做了一点手脚之后:

    pacman::p_load(raster, nnet, ranger)
    
    data(iris)
    
    # put iris data into raster
    r<-list()
    for(i in 1:4){
      r[[i]]<-raster(nrows=10, ncols=15)
      r[[i]][]<-iris[,i]
    }
    r<-stack(r)
    names(r)<-names(iris)[1:4]
    
    # multinom (an example that works)
    nn.model <- multinom(Species ~ ., data=iris, trace=F)
    nn.pred <- predict(r,nn.model)  # predict(object, newdata, type = c("raw","class"), ...)
    
    # ranger (doesn't work)
    ranger.model <- ranger(Species ~ ., data=iris)   
    ranger.pred <- predict(ranger.model, as.data.frame(as.matrix(r)))
    

    as.data.frame(as.matrix(r))

    免责声明:我没有检查输出的正确性,因此这可能根本不会产生任何结果,但是。。。

    identical(iris$Species, ranger.pred$predictions)
    
        3
  •  2
  •   Antonios    7 年前

    如果有帮助的话,用randomForest代替ranger对我有效

    library(randomForest)
    rf.model<-randomForest(Species ~ ., data=iris)   
    rf.pred<-predict(r,rf.model)
    
        4
  •  0
  •   Dharman Aman Gojariya    4 年前

    可以在此处找到另一种解决方案: https://github.com/imbs-hl/ranger/issues/319

    如前所述,将光栅::predict()用于ranger随机森林模型将不起作用,因为光栅包不支持ranger。

    用户mnwright提到了使其工作的解决方法。您只需在代码中添加一些内容:

    ranger.pred<-predict(r,ranger.model, fun = function(model, ...) predict(model, ...)$predictions)