在64位Linux机器上使用R 3.2.0 with caret 6.0-41和randomForest 4.6-10。
尝试在predict()
使用公式randomForest
包中使用train()
函数训练的对象上使用caret
方法时,该函数会返回错误。
通过randomForest()
和/或使用x=
和y=
而不是公式进行培训时,一切都顺利进行。
这是一个有效的例子:
library(randomForest)
library(caret)
data(imports85)
imp85 <- imports85[, c("stroke", "price", "fuelType", "numOfDoors")]
imp85 <- imp85[complete.cases(imp85), ]
imp85[] <- lapply(imp85, function(x) if (is.factor(x)) x[,drop=TRUE] else x) ## Drop empty levels for factors.
modRf1 <- randomForest(numOfDoors~., data=imp85)
caretRf <- train( numOfDoors~., data=imp85, method = "rf" )
modRf2 <- caretRf$finalModel
modRf3 <- randomForest(x=imp85[,c("stroke", "price", "fuelType")], y=imp85[, "numOfDoors"])
caretRf <- train(x=imp85[,c("stroke", "price", "fuelType")], y=imp85[, "numOfDoors"], method = "rf")
modRf4 <- caretRf$finalModel
p1 <- predict(modRf1, newdata=imp85)
p2 <- predict(modRf2, newdata=imp85)
p3 <- predict(modRf3, newdata=imp85)
p4 <- predict(modRf4, newdata=imp85)
在最后4行中,只有第二行p2 <- predict(modRf2, newdata=imp85)
返回以下错误:
Error in predict.randomForest(modRf2, newdata = imp85) :
variables in the training data missing in newdata
此错误的原因似乎是predict.randomForest
方法使用rownames(object$importance)
来确定用于训练随机林object
的变量的名称。而且,当看着
rownames(modRf1$importance)
rownames(modRf2$importance)
rownames(modRf3$importance)
rownames(modRf4$importance)
我们看到:
[1] "stroke" "price" "fuelType"
[1] "stroke" "price" "fuelTypegas"
[1] "stroke" "price" "fuelType"
[1] "stroke" "price" "fuelType"
所以,不知何故,当使用带有公式的caret
train()
函数时,会更改importance
对象的randomForest
字段中的(因子)变量的名称。 / p>
插入符train()
函数的公式和非公式版本之间是否真的不一致?或者我错过了什么?
答案 0 :(得分:27)
首先,几乎从未使用$finalModel
对象进行预测。使用predict.train
。这是一个很好的例子。
某些函数(包括randomForest
和train
)如何处理虚拟变量之间存在一些不一致。 R中使用公式方法的大多数函数会将因子预测变量转换为虚拟变量,因为它们的模型需要数据的数字表示。对此的例外是基于树和规则的模型(可以分类为分类预测变量),朴素贝叶斯和其他一些模型。
因此randomForest
不会在您使用randomForest(y ~ ., data = dat)
时创建虚拟变量,但train
(以及大多数其他人)将使用train(y ~ ., data = dat)
之类的调用。
发生错误是因为fuelType
是一个因素。由train
创建的虚拟变量具有相同的名称,因此predict.randomForest
无法找到它们。
将非公式方法与train
一起使用会将因子预测变量传递给randomForest
,一切都会有效。
TL; DR
如果您想要相同级别或使用train
predict.train
一起使用
最高
答案 1 :(得分:0)
出现此错误的原因有两个。
1。列车和测试集中的分类变量类别不匹配。要检查这一点,您可以运行以下内容。
首先,将自变量/特征保留在列表中是一种好习惯。说该列表是“vars”。并且说,您将“数据”分为“训练”和“测试”。我们走吧:
for (v in vars){ if (class(Data[,v]) == 'factor'){ print(v) # print(levels(Train[,v])) # print(levels(Test[,v])) print(all.equal(levels(Train[,v]) , levels(Test[,v]))) } }
找到不匹配的分类变量后,您可以返回,并将测试数据的类别强加到Train数据上,然后重新构建模型。在类似于上面的循环中,对于每个nonMatchingVar,您可以执行
levels(Test$nonMatchingVar) <- levels(Train$nonMatchingVar)
2。一个愚蠢的人。如果您不小心将因变量保留在自变量集中,则可能会遇到此错误消息。我犯了那个错误。解决方案:要小心点。
答案 2 :(得分:0)
另一种方法是使用model.matrix
显式编码测试数据,例如
p2 <- predict(modRf2, newdata=model.matrix(~., imp85))
答案 3 :(得分:0)
这不是你问题的答案,但我相信它会帮助别人,因为它帮助了我。如果您在训练数据列中使用的测试数据列中缺少任何NA,则预测将不起作用。您需要首先估算这些值。