r 随机森林错误 - 新数据中的预测变量类型不匹配

Posted

技术标签:

【中文标题】r 随机森林错误 - 新数据中的预测变量类型不匹配【英文标题】:r random forest error - type of predictors in new data do not match 【发布时间】:2014-09-09 20:49:05 【问题描述】:

我正在尝试在 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" 

它们完全一样。我还检查了“NA”值。 xtrain 和 xtest 都没有 NA 值。我在这里错过了一些琐碎的事情吗?

更新 I:在训练数据上运行预测仍然给出相同的错误

> quant.newdata <- predict(qrf, newdata = xtrain)
Error in predict.quantregForest(qrf, newdata = xtrain) : 
names of predictor variables do not match

更新二:我合并了我的训练集和测试集,因此从 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)

而且它有效!如果有人能解释为什么它以这种方式工作而不是另一种方式,我将不胜感激?

【问题讨论】:

拥有两个不同类型的pred1 值似乎不是一个好主意。也许将因子一更改为“pred1.factor”? 感谢您指出。我改变了它并重新运行了sapply的。使用新数据 = xtrain 和新数据 = xtest 仍然出现相同的错误 如果您从少量预测变量开始,一次添加一个,会发生什么? 你知道你在两个集合中的因子是否包含相同的水平吗?即如果您的训练数据中有 T / F,那么您的测试数据中的相应列是否也同时具有 T 和 F? @Karan 至少有一个预测变量的因子水平不同。为什么单独的训练 - 测试数据会成为问题,而不是划分为训练和测试的单个数据集? 【参考方案1】:

这是每个不同因素的水平问题。您需要检查以确保您的因子水平在您的测试集和训练集之间保持一致。

这是随机森林的一个奇怪的怪癖,对我来说没有意义。

【讨论】:

【参考方案2】:

@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)不会丢弃关卡,检查成功。

【讨论】:

我在森林运行了 3 天左右后遇到了这个问题......我真的不想再次运行它:/ 这似乎解决了它:rf$forest$xlevels$my_factor_name[myNAlevelIdx] &lt;- "NA" 如果你在 tidyverse 中操作,forcats::fct_explicit_na 是解决这个恼人 bug 的好方法。【参考方案3】:

发生这种情况是因为您在训练集和测试集中的因子变量具有不同的级别(更准确地说,测试集没有训练中存在的某些级别)。因此,您可以通过对所有因子变量使用以下代码来解决此问题。:

levels(test$SectionName) <- levels(train$SectionName)

【讨论】:

扩展解决方案:common &lt;- intersect(names(train), names(test)) for (p in common) if (class(train[[p]]) == "factor") levels(test[[p]] ) @JamesHirschorn 太棒了! 我正在尝试您的建议:levels(test$SectionName) @JamesHirschorn,我建议添加您的评论作为答案,这样像我这样的人可以更轻松地找到它。它解决了我的问题!谢谢! @Eduaro 好主意 :) 完成!【参考方案4】:

我刚刚解决了以下问题:

## 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> 

【讨论】:

【参考方案5】:

扩展@user1849895 的解决方案:

common <- intersect(names(train), names(test)) 
for (p in common)  
  if (class(train[[p]]) == "factor")  
    levels(test[[p]]) <- levels(train[[p]]) 
   

【讨论】:

【参考方案6】:

我遇到了同样的问题。您可以尝试使用小技巧来均衡训练和测试集的类别。将第一行训练集绑定到测试集,然后将其删除。对于您的示例,它应该如下所示:

    xtest <- rbind(xtrain[1, ] , xtest)
    xtest <- xtest[-1,]

【讨论】:

这确实修复了它,我尝试了各种奇怪的复杂循环/应用/检查,这只是修复它gg 这就是我要找的。正确答案!学分! 太棒了!非常感谢这个出色的解决方案! 这很棒。您也有可能在测试中得到一个不在训练数据中的因素,因此您可以使用: test 【参考方案7】:

我尝试用这种方式解决,效果很好。

直接从 rf 模型本身获取因子水平

levels(PredictData$columnName) <- rfmodels$forest$xlevels$columnName

【讨论】:

【参考方案8】:
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]

上面这段代码可以解决这个错误。

【讨论】:

【参考方案9】:

有同样的错误,在我的情况下,它是由 tidyverse 引起的。 data.frame 设置为 tibble 并且它以某种方式与因素不匹配。应用 as.data.frame() 完成了这项工作。

【讨论】:

以上是关于r 随机森林错误 - 新数据中的预测变量类型不匹配的主要内容,如果未能解决你的问题,请参考以下文章

随机森林中的R - 19个预测变量,1个因变量

当缺少数据时,使用 R 随机森林预测新数据

将条件变量添加到 R 中的随机森林模型

R - 具有两个结果变量的随机森林

使用随机森林模型提高预测新数据的速度

R:如何使用随机森林来预测使用字符串变量的二进制结果?