NA в растрах и randomForest :: pred ()

Новинка, дайте мне знать, если вам нужна дополнительная информация.

Моя цель: я использую климатические данные Rehfeldt и данные о присутствии / отсутствии eBird для создания нишевых моделей с использованием моделей случайного леса.

Моя проблема: я хочу спрогнозировать нишевые модели для всей Северной Америки. Климатические растры Rehfeldt содержат значения данных для каждой ячейки на континенте, но они окружены АП в «ячейках океана». См. График здесь, где я раскрасил НА темно-зеленые. randomForest :: Forest () не запускается, если независимый набор данных содержит NA. Таким образом, я хочу обрезать свои климатические растры (или установить рабочий экстент?), Чтобы функция прогнозирования () работала только с ячейками, содержащими данные.

Устранение неполадок:

  1. Я запустил модель случайного леса, используя меньший экстент, который не включает «океаны Северной Америки» растров, и модель работает нормально. Итак, я знаю, что проблема в НП. Однако я не хочу предсказывать свои нишевые модели только для прямоугольной части Северной Америки.

  2. Я использовал подход Flowla здесь для обрезки и маскирования растров с использованием шейп-файла многоугольника для севера. Америка. Я надеялся, что это удалит НП, но этого не произошло. Есть ли что-то подобное, что я могу сделать, чтобы удалить NA?

  3. Я прочитал кое-что, но не могу придумать, как настроить сам код случайного леса, чтобы pred () игнорировал NA. Этот пост выглядит актуальным, но я Не уверен, поможет ли это в моем случае.

Данные

Мои растры, входной текстовый файл наличия / отсутствия и код для дополнительных функций находятся здесь . Используйте с основным кодом ниже для воспроизводимого примера.

Код

require(sp)
require(rgdal)
require(raster)
library(maptools)
library(mapproj)
library(dismo)
library(maps)
library(proj4)
data(stateMapEnv)

# This source code has all of the functions necessary for running the Random Forest models, as well as the code for the function detecting multi-collinearity
source("Functions.R")

# Read in Rehfeldt climate rasters
# these rasters were converted to .img and given WGS 84 projection in ArcGIS

d100 <- raster("d100.img")
dd0 <- raster("dd0.img")
dd5 <- raster("dd5.img")
fday <- raster("fday.img")
ffp <- raster("ffp.img")
gsdd5 <- raster("gsdd5.img")
gsp <- raster("gsp.img")
map <- raster("map.img")
mat <- raster("mat_tenths.img")
mmax <- raster("mmax_tenths.img")
mmin <- raster("mmin_tenths.img")
mmindd0 <- raster("mmindd0.img")
mtcm <- raster("mtcm_tenths.img")
mtwm <- raster("mtwm_tenths.img")
sday <- raster("sday.img")
smrpb <- raster("smrpb.img")

# add separate raster files into one big raster, with each file being a different layer.
rehfeldt <- addLayer(d100, dd0, dd5, fday, ffp, gsdd5, gsp, map, mat, mmax, mmin, mmindd0, mtcm, mtwm, sday, smrpb)

# plot some rasters to make sure everything worked
plot(d100)
plot(rehfeldt)

# read in presence/absence data
LAZB.INBUtemp <- read.table("LAZB.INBU.txt", header=T, sep = "\t")
colnames(LAZB.INBUtemp) <- c("Lat", "Long", "LAZB", "INBU")
LAZB.INBUtemp <- LAZB.INBUtemp[c(2,1,3,4)]
LAZB.INBU <- LAZB.INBUtemp

latpr <- (LAZB.INBU$Lat)
lonpr <- (LAZB.INBU$Long)
sites <- SpatialPoints(cbind(lonpr, latpr))
LAZB.INBU.spatial <- SpatialPointsDataFrame(sites, LAZB.INBU, match.ID=TRUE)

# The below function extracts raster values for each of the different layers for each of the eBird locations
pred <- raster::extract(rehfeldt, LAZB.INBU.spatial)
LAZB.INBU.spatial@data = data.frame(LAZB.INBU.spatial@data, pred)
LAZB.INBU.spatial@data <- na.omit(LAZB.INBU.spatial@data)

# ITERATIVE TEST FOR MULTI-COLINEARITY
# Determines which variables show multicolinearity
cl <- MultiColinear(LAZB.INBU.spatial@data[,7:ncol(LAZB.INBU.spatial@data)], p=0.05)
xdata <- LAZB.INBU.spatial@data[,7:ncol(LAZB.INBU.spatial@data)]  
for(l in cl) {
  cl.test <- xdata[,-which(names(xdata)==l)]
  print(paste("REMOVE VARIABLE", l, sep=": "))
  MultiColinear(cl.test, p=0.05)    
}

# REMOVE MULTI-COLINEAR VARIABLES
for(l in cl) { LAZB.INBU.spatial@data <- LAZB.INBU.spatial@data[,-which(names(LAZB.INBU.spatial@data)==l)] }


################################################################################################

# FOR LAZB
# RANDOM FOREST MODEL AND RASTER PREDICTION

require(randomForest)

# NUMBER OF BOOTSTRAP REPLICATES
b=1001

# CREATE X,Y DATA

# use column 3 for LAZB and 4 for INBU
ydata <- as.factor(LAZB.INBU.spatial@data[,3])
xdata <- LAZB.INBU.spatial@data[,7:ncol(LAZB.INBU.spatial@data)]

# PERCENT OF PRESENCE OBSERVATIONS
( dim(LAZB.INBU.spatial[LAZB.INBU.spatial$LAZB == 1, ])[1] / dim(LAZB.INBU.spatial)[1] ) * 100

# RUN RANDOM FORESTS MODEL SELECTION FUNCTION
# This model is using the model improvement ratio to select a final model.

pdf(file = "LAZB Random Forest Model Rehfeldt.pdf")
( rf.model <- rf.modelSel(x=xdata, y=ydata, imp.scale="mir", ntree=b) ) 
dev.off()

# RUN RANDOM FORESTS CLASS BALANCE BASED ON SELECTED VARIABLES
# This code would help in the case of imbalanced sample
mdata <- data.frame(y=ydata, xdata[,rf.model$SELVARS])
rf.BalModel <- rfClassBalance(mdata[,1], mdata[,2:ncol(mdata)], "y", ntree=b)

# CREATE NEW XDATA BASED ON SELECTED MODEL AND RUN FINAL RF MODEL
sel.vars <- rf.model$PARAMETERS[[3]]
rf.data <- data.frame(y=ydata, xdata[,sel.vars])  
write.table(rf.data, "rf.data.txt", sep = ",", row.names = F)

# This the code given to me; takes forever to run for my dataset (I haven't tried to let it finish)
# ( rf.final <- randomForest(y ~ ., data=rf.data, ntree=b, importance=TRUE, norm.votes=TRUE, proximity=TRUE) )

# I use this form because it's a lot faster
( rf.final <- randomForest(x = rf.data[2:6], y = rf.data$y, ntree=1000, importance=TRUE, norm.votes=TRUE, proximity=F) )

################################################################################################         
# MODEL VALIDATION 
# PREDICT TO VALIDATION DATA

# Determines the percent correctly classified
rf.pred <- predict(rf.final, rf.data[,2:ncol(rf.data)], type="response")
rf.prob <- as.data.frame(predict(rf.final, rf.data[,2:ncol(rf.data)], type="prob"))
ObsPred <- data.frame(cbind(Observed=as.numeric(as.character(ydata)), 
                            PRED=as.numeric(as.character(rf.pred)), Prob1=rf.prob[,2], 
                            Prob0=rf.prob[,1]) )
op <- (ObsPred$Observed == ObsPred$PRED)
( pcc <- (length(op[op == "TRUE"]) / length(op))*100 )

# PREDICT MODEL PROBABILITIES RASTER

# The first line of code says what directory I'm working, and then what folder in that directory has the raster files that I'm using to predict the range
# The second line defines the x variable, wich is my final Random Forest model

rpath=paste('~/YOURPATH', "example", sep="/")
xvars <- stack(paste(rpath, paste(rownames(rf.final$importance), "img", sep="."), sep="/"))
tr <-  blockSize(xvars)
s <- writeStart(xvars[[1]], filename=paste('~/YOURPATH', "prob_LAZB_Rehfeldt.img", sep="/"), overwrite=TRUE)                                           
for (i in 1:tr$n) {
  v <- getValuesBlock(xvars, row=tr$row[i], nrows=tr$nrows[i])
  v <- as.data.frame(v)         
  rf.pred <- predict(rf.final, v, type="prob")[,2]           
  writeValues(s, rf.pred, tr$row[i])
}
s <- writeStop(s)   

prob_LAZB <- raster("prob_LAZB_Rehfeldt.img")

# Write range prediction raster to .pdf
pdf(file="LAZB_range_pred.pdf")
plot(prob_LAZB)
map("state", add = TRUE)
dev.off()

Спасибо!!


person LCM    schedule 17.06.2014    source источник
comment
Не могли бы вы добавить данные, которые позволили бы воспроизвести вашу проблему?   -  person Paulo E. Cardoso    schedule 19.06.2014
comment
Привет @ Prophet60091, извините, но это очень старый вопрос, и я думаю, что он устарел. Насколько я помню, автор функций сказал мне, что вызов na.action = omit не работал в то время, и, возможно, это была проблема с базой R? Подробностей не помню. Я согласен с тем, что na.action = omit должно быть решением, но я думаю, что по какой-то причине это не помогло мне. Теперь я понимаю, что не разъяснил, пробовал ли я аргумент na.action; возможно, я попытался сделать это после того, как написал этот вопрос ... Я в конечном итоге применил другой подход к анализу, не вернулся в РФ.   -  person LCM    schedule 30.05.2018


Ответы (1)


Вы пробовали установить na.action при звонке на RF? Эта опция четко обозначена в руководстве randomForest R. Ваш звонок в РФ будет выглядеть так:

rf.final <- randomForest(x = rf.data[2:6], y = rf.data$y, ntree=1000, importance=TRUE, norm.votes=TRUE, proximity=F, na.action = omit)

Это скажет RF опускать строки, где существует NA, тем самым отбрасывая эти наблюдения. Это не обязательно лучший подход, но он может быть удобен в вашей ситуации.

Вариант 2: rfImpute или na.roughfix: это заполнит ваши NA, чтобы вы могли продолжить свой прогноз. Остерегайтесь, поскольку это может дать вам ложные прогнозы везде, где NAs вменяются / «фиксируются».

Вариант 3: начните с варианта 2, и после того, как вы получите прогноз, перенесите свой растр в любое программное обеспечение для обработки ГИС / изображений и замаскируйте области, которые вам не нужны. В вашем случае замаскировать водоемы было бы довольно просто.

person Prophet60091    schedule 02.04.2015