带有随机森林的图像分类(栅格堆栈)(包护林员)

时间:2017-09-21 22:30:29

标签: r raster

我使用R包护林员对随机森林进行拟合来对光栅图像进行分类。预测函数产生错误,此后我提供了一个可重现的例子。

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,]中的错误&lt; - predv:矩阵上的下标数量不正确

虽然我的真实数据的错误是

  

p [-naind,]&lt; - predv中的错误:要替换的项目数不是a   替换长度的倍数

我唯一想到的是,ranger.prediction对象包含了除感兴趣的预测之外的几个元素。无论如何,如何使用游侠来预测光栅堆栈?

4 个答案:

答案 0 :(得分:4)

经过一番摆弄:

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)

答案 1 :(得分:3)

您可以通过在插入符号包的train函数中训练模型,从栅格堆栈上的游侠模型运行预测:

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 :(得分:2)

如果有帮助,它可以使用randomForest而不是游侠

library(randomForest)
rf.model<-randomForest(Species ~ ., data=iris)   
rf.pred<-predict(r,rf.model)

答案 3 :(得分:0)

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

正如那里所解释的,将 raster::predict() 与 Ranger 随机森林模型一起使用是行不通的,因为 raster 包不支持 Ranger。

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

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

为我工作,现在对象 ranger.pred 应该是一个光栅。