随机森林:如何处理测试集中的新因子水平?


13

我正在尝试使用R中的随机森林模型进行预测。

但是我得到了错误,因为某些因素在测试集中与训练集中具有不同的值。例如,一个因子在测试集中的Cat_234, 68, 76等不出现在训练集中。不幸的是,我无法控制测试集...我必须原样使用它。

我唯一的解决方法是使用将问题因子转换回数值as.numeric()。它的工作原理,但我不是很满意,因为这些值是没有意义的数字代码...

您是否认为还有另一种解决方案,可以从测试集中删除新值?但是,不删除1, 2, 14, 32训练和测试中所有其他因素值(比如说值等),并且包含可能对预测有用的信息。


1
我知道为什么测试中的值必须包含在训练集中的原因。分类的思想是使用训练数据来了解类条件密度的外观。您不会从密度中看到所有可能的值。我在树上的拆分中使用了一个变量,然后拆分确定了对于任何看不见的值以及已看到的值遵循哪个分支。
Michael R. Chernick

您提出了一个正确的观点,但在实际水平上,使用所询问的特定工具(R中的RF封装)是不允许的。我关于归因的回答是解决问题的一种方法,尽管它当然不是最佳解决方案。Is至少不会使代码崩溃,因此至少对于少量的工作有效。
Bogdanovist,2012年

类似于我在这里的问题:stats.stackexchange.com/questions/18004/…。我认为我可以使用GBM代替RF,因为它似乎可以更好地处理新的因子水平。另外,您是否看过派对中RF的实施?由于这些问题(以及无法无缝处理缺失值),我从未喜欢过randomForest。
B_Miner

Answers:


2

如果测试集包含很多这些具有新因子值的点,那么我不确定哪种方法最好。如果仅是少数几个要点,您也许可以摆脱一些古怪的东西,例如将错误的因子水平视为丢失的数据,并以您认为合适的任何方式进行插补。R实现有两种估算缺失数据的方法,您只需要将这些因子级别设置为NA即可指示它们缺失。


8

KingBonoit,此片段可用于协调级别:

for(attr in colnames(training))
{
  if (is.factor(training[[attr]]))
  {
    new.levels <- setdiff(levels(training[[attr]]), levels(testing[[attr]]))
    if ( length(new.levels) == 0 )
    { print(paste(attr, '- no new levels')) }
    else
    {
      print(c(paste(attr, length(new.levels), 'of new levels, e.g.'), head(new.levels, 2)))
      levels(testing[[attr]]) <- union(levels(testing[[attr]]), levels(training[[attr]]))
    }
  }
}

它还打印哪些属性已更改。我没有找到一种更好的方式(用ldply或其他方式)更好地编写它的好方法。任何提示表示赞赏。


4

这是我写的一些解决上述@King响应的代码。它修复了错误:

# loops through factors and standardizes the levels
for (f in 1:length(names(trainingDataSet))) {
    if (levels(testDataSet[,f]) > levels(trainingDataSet[,f])) {    
            levels(testDataSet[,f]) = levels(trainingDataSet[,f])       
    } else {
            levels(trainingDataSetSMOTEpred[,f]) = levels(testDataSet[,f])      
    }
}

嗨,@ ifarb,我想了解您的解决方案:什么是trainingDataSetSMOTEpred,代码中的定义是什么?
Kasia Kulma

3

测试和培训集应合并为一组,然后更改培训集的级别。我的代码是:

totalData <- rbind(trainData, testData)
for (f in 1:length(names(totalData))) {
  levels(trainData[, f]) <- levels(totalData[, f])
}

在测试中的级别数大于或小于训练的任何情况下,此方法都有效。


2

当我在R中使用randomForest时,我有一个糟糕的解决方法。从理论上讲,这听起来可能不合理,但可以正常运行。

levels(testSet$Cat_2) = levels(trainingSet$Cat_2)

或反过来。基本上,它只是告诉R,它是一个有效值,只有0种情况。所以不要再烦我了。

我不够聪明,无法对其进行编码,以至于它无法自动对所有分类功能执行操作。如果您知道如何,请将代码发送给我...


但是,如果测试中的级别数多于训练数,这将不起作用。仅当测试数据因子水平<=训练数据因子水平时才有效。
KarthikS

1

我敢肯定,如果是这种情况,您已经考虑过了,但是如果测试集具有实际值,并且您正在使用测试集进行交叉验证,则将数据帧重新拆分为训练和测试数据帧两者在这些因素上保持平衡的方法可以避免您的问题。这种方法通常称为分层交叉验证

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.