我正在尝试在R(quantregForest)中使用基于随机森林包构建的分位数回归林函数。我遇到类型不匹配错误,我无法理解为什么。
我使用
训练模型qrf <- quantregForest(x = xtrain, y = ytrain)
可以正常运行,但是当我尝试使用
等新数据进行测试时quant.newdata <- predict(qrf, newdata= xtest)
它出现以下错误:
Error in predict.quantregForest(qrf, newdata = xtest) :
Type of predictors in new data do not match types of the training data.
我的培训和测试数据来自单独的文件(因此是单独的数据框),但具有相同的格式。我用
检查了预测变量的类sapply(xtrain, class)
sapply(xtest, class)
这是输出:
> sapply(xtrain, class)
pred1 pred2 pred3 pred4 pred5 pred6 pred7 pred8
"factor" "integer" "integer" "integer" "factor" "factor" "integer" "factor"
pred9 pred10 pred11 pred12
"factor" "factor" "factor" "factor"
> sapply(xtest, class)
pred1 pred2 pred3 pred4 pred5 pred6 pred7 pred8
"factor" "integer" "integer" "integer" "factor" "factor" "integer" "factor"
pred9 pred10 pred11 pred12
"factor" "factor" "factor" "factor"
它们完全一样。我还检查了&#34; NA&#34;值。 xtrain和xtest都没有NA值。我在这里错过了一些小事吗?
更新I:对训练数据运行预测仍然会产生相同的错误
> quant.newdata <- predict(qrf, newdata = xtrain)
Error in predict.quantregForest(qrf, newdata = xtrain) :
names of predictor variables do not match
更新II:我将我的训练和测试集合在一起,以便从1到101的行是训练数据,其余的是测试。我将(quantregForest)中提供的示例修改为:
data <- read.table("toy.txt", header = T)
n <- nrow(data)
indextrain <- 1:101
xtrain <- data[indextrain, 3:14]
xtest <- data[-indextrain, 3:14]
ytrain <- data[indextrain, 15]
ytest <- data[-indextrain, 15]
qrf <- quantregForest(x=xtrain, y=ytrain)
quant.newdata <- predict(qrf, newdata= xtest)
它有效!如果有人可以解释为什么它以这种方式工作而不是用其他方式解释,我会感激不尽?
答案 0 :(得分:19)
我遇到了同样的问题。您可以尝试使用小技巧来均衡训练和测试集的类。将第一行训练集绑定到测试集,然后将其删除。对于您的示例,它应如下所示:
xtest <- rbind(xtrain[1, ] , xtest)
xtest <- xtest[-1,]
答案 1 :(得分:16)
@mgoldwasser一般是正确的,但predict.randomForest
中也有一个非常讨厌的错误:即使你在训练和预测集中有完全相同的等级,也有可能得到这个错误。如果您有一个将NA
嵌入为单独级别的因子,则可以执行此操作。问题是predict.randomForest
基本上执行以下操作:
# Assume your original factor has two "proper" levels + NA level:
f <- factor(c(0,1,NA), exclude=NULL)
length(levels(f)) # => 3
levels(f) # => "0" "1" NA
# Note that
sum(is.na(f)) # => 0
# i.e., the values of the factor are not `NA` only the corresponding level is.
# Internally predict.randomForest passes the factor (the one of the training set)
# through the function `factor(.)`.
# Unfortunately, it does _not_ do this for the prediction set.
# See what happens to f if we do that:
pf <- factor(f)
length(levels(pf)) # => 2
levels(pf) # => "0" "1"
# In other words:
length(levels(f)) != length(levels(factor(f)))
# => sad but TRUE
因此,它总是会丢弃训练集中的NA
级别,并且总会在预测集中看到一个额外的级别。
解决方法是在使用randomForest之前替换关卡的值NA
:
levels(f)[is.na(levels(f))] <- "NA"
levels(f) # => "0" "1" "NA"
# .... note that this is no longer a plain `NA`
现在调用factor(f)
不会丢弃该级别,并且检查成功。
答案 2 :(得分:15)
这是因为训练集和测试集中的因子变量具有不同的级别(更准确的是,测试集没有训练中存在的某些级别)。因此,您可以使用以下代码为所有因子变量解决此问题。:
levels(test$SectionName) <- levels(train$SectionName)
答案 3 :(得分:12)
扩展@ user1849895的解决方案:
common <- intersect(names(train), names(test))
for (p in common) {
if (class(train[[p]]) == "factor") {
levels(test[[p]]) <- levels(train[[p]])
}
}
答案 4 :(得分:2)
这是每个不同因素的水平问题。您需要检查以确保您的因子水平在测试和训练集之间保持一致。
这是一个奇怪的随机森林怪癖,对我来说没有意义。
答案 5 :(得分:0)
我刚刚解决了以下问题:
## Creating sample data
values_development=factor(c("a", "b", "c")) ## Values used when building the random forest model
values_production=factor(c("a", "b", "c", "ooops")) ## New values to used when using the model
## Deleting cases which were not present when developing
values_production=sapply(as.character(values_production), function(x) if(x %in% values_development) x else NA)
## Creating the factor variable, (with the correct NA value level)
values_production=factor(values_production)
## Checking
values_production # => a b c <NA>
答案 6 :(得分:0)
我试图用这种方式解决问题,并且有效。
直接从rf模型本身获取因子水平
levels(PredictData$columnName) <- rfmodels$forest$xlevels$columnName
答案 7 :(得分:0)
levels(PredictData$columnName) <- rfmodels$forest$xlevels$columnName
但是,这将更改PredictData中的原始数据。因此必须有以下代码
x<-PredictData
levels(PredictData$columnName) <- rfmodels$forest$xlevels$columnName
for (i in 1:length(x$columnName))
{
PredictData$columnName[i] <- x$columnName[i]
}
上面的代码段将解决此错误。