Классификация изображений (растровый стек) со случайным лесом (пакетный рейнджер)
Я подгоняю случайный лес, используя 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[ячейках, ] <- predv: неверное количество индексов в матрице
хотя ошибка с моими реальными данными
Ошибка в p[-naind, ]<- predv: количество заменяемых элементов не кратно длине замены
Единственное, что приходит мне в голову, это то, что объект ranger.prediction включает в себя несколько элементов, помимо предсказаний, представляющих интерес. В любом случае, каким образом рейнджер можно использовать для прогнозирования стека растров?
4 ответа
Вы можете запускать прогнозы из модели рейнджера в стеке растров, обучая модель в рамках функции поезда пакета каретки:
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")
)
После небольшой возни:
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)
У меня это работает с randomForest вместо Ranger, если это поможет
library(randomForest)
rf.model<-randomForest(Species ~ ., data=iris)
rf.pred<-predict(r,rf.model)
Другое решение можно найти здесь:https://github.com/imbs-hl/ranger/issues/319
Как объясняется там, использование raster ::pred() с моделью случайного леса ranger не будет работать, потому что пакет raster не поддерживает ranger.
Обходной путь, чтобы заставить его работать, упоминается пользователем mnwright. Вам просто нужно добавить в свой код несколько вещей:
ranger.pred<-predict(r,ranger.model, fun = function(model, ...) predict(model, ...)$predictions)
У меня сработало, теперь объект ranger.pred должен быть растром.