首页 文章

使用randomForest,Caret和factor变量预测栅格时出错

提问于
浏览
2

我试图用randomForest和插入符号包预测栅格图层,但在引入因子变量时失败 . 没有因素,一切正常,但一旦我带来一个因素,我得到错误:

Error in predict.randomForest(modelFit, newdata) : Type of predictors in new data do not match that of the training data.

我在下面创建了一些示例代码来完成他的过程 . 我提出了透明度的几个步骤并提供了一个工作示例 .

(To skip the set-up code, jump from here on down...)

首先是创建样本数据,拟合RF模型,以及预测涉及NO因素的栅格 . 一切正常 .

# simulate data
x1p <- runif(50, 10, 20) # presence
x2p <- runif(50, 100, 200)
x1a <- runif(50, 15, 25) # absence
x2a <- runif(50, 180, 400)
x1 <- c(x1p, x1a)
x2 <- c(x2p,x2a)
y <- c(rep(1,50), rep(0,50)) # presence/absence
d <- data.frame(x1 = x1, x2 = x2, y = y)

# RF Classification on data with no factors... works fine
require(randomForest)
dRF <- d
dRF$y <- factor(ifelse(d$y == 1, "present", "absent"),
                levels = c("present", "absent"))
rfFit <- randomForest(y = dRF$y, x = dRF[,1:2], ntree=100) # RF Classfication

# Create sample Rasters
require(raster)
r1 <- r2 <- raster(nrow=100, ncol=100)
values(r1) <- runif(ncell(r1), 5, 25 )
values(r2) <- runif(ncell(r2), 85, 500 )
s <- stack(r1, r2)
names(s) <- c("x1", "x2")

# raster::predict() with no factors, works fine.
model <- predict(s, rfFit, na.rm=TRUE, type="prob", progress='text')
spplot(model)

接下来的步骤是创建一个因子变量,以添加到训练数据并创建具有预测匹配值的栅格 . 请注意,栅格是常规的旧整数,而不是 as.factor 栅格 . 一切都还行不错......

# Create factor variable
x3p <- sample(0:5, 50, replace=T)
x3a <- sample(3:7, 50, replace=T)
x3 <- c(x3p, x3a)
dFac <- dRF
dFac$x3 <- as.factor(x3)
dFac <- dFac[,c(1,2,4,3)] # reorder

# RF model with factors, works fine
rfFit2 <- randomForest(y ~ x1 + x2 + x3, data=dFac, ntree=100)

# Create new raster, but not as.factor()
r3 <- raster(nrow=100, ncol=100)
values(r3) <- sample(0:7, ncell(r3), replace=T)
s2 <- stack(s, r3)
names(s2) <- c("x1", "x2", "x3") 
s2 <- brick(s2) # brick or stack, either work

# RF, raster::predict() from fit with factor
f <- levels(dFac$x3) # included, but not necessary
model2 <- predict(s2, rfFit2,  type="prob", 
          progress='text', factors=f, index=1:2)
spplot(model2) # works fine

完成上述步骤后,我现在有了一个RF模型,该模型使用包含因子变量的数据进行训练,并在包含类似值的整数栅格的栅格砖上进行预测 . 这是我的最终目标,但我希望能够通过 caret 包工作流程来实现 . 下面我介绍 caret::train() 没有因素,一切运作良好 .

# RF with Caret and NO factors
require(caret)
rf_ctrl <- trainControl(method = "cv", number=10,
           allowParallel=FALSE, verboseIter=TRUE, 
           savePredictions=TRUE, classProbs=TRUE) 
cFit1 <- train(y = dRF$y, x = dRF[,1:2], method = "rf", 
         tuneLength=4, trControl = rf_ctrl, importance = TRUE)
model3 <- predict(s2, cFit1,  type="prob", 
          progress='text', factors=f, index=1:2) 
spplot(model3) # works with caret and NO factors

(...to here. This is where the issues begin)

事情就是失败的地方 . 插入符号训练的Rf模型与因子变量有效,但在 raster::predict() 失败 .

# RF with Caret and FACTORS
rf_ctrl2 <- trainControl(method = "cv", number=10,
            allowParallel=FALSE, verboseIter=TRUE, 
            savePredictions=TRUE, classProbs=TRUE)
cFit2 <- train(y = dFac$y, x = dFac[,1:3], method = "rf", 
         tuneLength=4, trControl = rf_ctrl2, importance = TRUE)
model4 <- predict(s2, cFit2,  type="prob", 
          progress='text', factors=f, index=1:2) 
# FAIL: "Type of predictors in new data do not match that of the training data."

尝试与上面相同,但不是使用与因子级别具有相同值的整数栅格,而是使用 as.factor() 并指定级别将栅格转换为因子 . 这也失败了 .

#trying with raster as.factor()
r3f <- raster(nrow=100, ncol=100)
values(r3f) <- sample(0:7, ncell(r3f), replace=T)
r3f <- as.factor(r3f)
f <- levels(r3f)[[1]]
f$code <- as.character(f[,1])
levels(r3f) <- f
s2f <- stack(s, r3f)
names(s2f) <- c("x1", "x2", "x3")
s2f <- brick(s2f)

model4f <- predict(s2f, cFit2,  type="prob", 
           progress='text', factors=f, index=1:2)
# FAIL "Type of predictors in new data do not match that of the training data."

上述步骤的错误和进展清楚地表明我的方法存在问题, caret:train()raster::predict() . 我已经完成了调试(尽我所能)并解决了我注意到的问题,但没有吸烟枪 .

任何和所有的帮助将不胜感激 . 谢谢!

Added: 我继续乱搞,意识到如果 caret::train() 中的模型是用公式形式写的,它就可以工作 . 查看模型对象的结构,很容易看出为因子变量创建了对比 . 我想这也意味着 raster::predict() 认识到了对比 . 这很好,但是因为我的方法没有设置为使用基于公式的预测,这是一个无赖 . 任何额外的帮助仍然受到赞赏 .

#with Caret WITH FACTORS as model formula!
rf_ctrl3 <- trainControl(method = "cv", number=10,
            allowParallel=FALSE, verboseIter=TRUE, savePredictions=TRUE, classProbs=TRUE)
cFit3 <- train(y ~ x1 + x2 + x3, data=dFac, method = "rf", 
            tuneLength=4, trControl = rf_ctrl2, importance = TRUE)

model5 <- predict(s2, cFit3,  type="prob", progress='text') # prediction raster
spplot(model5)

1 回答

  • 3

    这需要进行一些测试,但答案是 raster::predict() 仅适用于包含因子的 caret::train() 生成的模型,如果模型显示为公式( y ~ x1 + x2 + x3 )而不是 y = y, x = x (作为矩阵或data.frame) . 只有通过公式接口,模型才能创建正确的对比或虚拟变量 . 无需通过 as.factor() 将栅格图层设置为因子 . 预测功能将为您做到这一点 .

相关问题