18

我在一个大数据问题中使用随机森林,它有一个非常不平衡的响应类,所以我阅读了文档,发现了以下参数:

strata 

sampsize

这些参数的文档很少(或者我没有运气找到它)而且我真的不明白如何实现它。我正在使用以下代码:

randomForest(x=predictors, 
             y=response, 
             data=train.data, 
             mtry=lista.params[1], 
             ntree=lista.params[2], 
             na.action=na.omit, 
             nodesize=lista.params[3], 
             maxnodes=lista.params[4],
             sampsize=c(250000,2000), 
             do.trace=100, 
             importance=TRUE)

响应是具有两个可能值的类,第一个比第二个出现的频率更高(10000:1 或更多)

list.params是一个具有不同参数的列表(呃!我知道......)

好吧,问题(再次)是:我如何使用'strata'参数?我正确使用 sampsize 吗?

最后,有时我会收到以下错误:

Error in randomForest.default(x = predictors, y = response, data = train.data,  :
  Still have fewer than two classes in the in-bag sample after 10 attempts.

对不起,如果我做了这么多(也许是愚蠢的)问题......

4

4 回答 4

7

您应该尝试使用将不平衡程度从 1:10,000 降低到 1:100 或 1:10 的抽样方法。您还应该减小生成的树的大小。(目前这些是我仅凭记忆重复的建议,但我会看看我是否能找到比我的海绵状皮质更多的权威。)

减小树大小的一种方法是将“nodesize”设置得更大。有了这种程度的不平衡,您可能需要使节点大小非常大,例如 5-10,000。这是 rhelp 中的一个线程: https ://stat.ethz.ch/pipermail/r-help/2011-September/289288.html

在您遇到的问题的当前状态下,sampsize=c(250000,2000),我认为像 sampsize=c(8000,2000) 这样的东西更符合我的建议。我认为您正在创建样本,其中没有任何仅使用 2000 个样本的组。

于 2012-01-02T20:09:52.340 回答
4

抱歉,我不知道如何对较早的答案发表评论,所以我将创建一个单独的答案。

我认为问题是由数据集的高度不平衡引起的(其中一类的案例太少)。对于 RF 中的每棵树,该算法都会创建引导样本,这是该树的训练集。如果您的数据集中某一类的示例太少,那么引导抽样将只选择一个类(主要类)的示例。因此,树不能仅在一个类示例上生长。似乎对 10 次不成功的采样尝试有限制。因此,DWin 将不平衡程度降低到较低值(1:100 或 1:10)的提议是最合理的。

于 2012-01-03T08:50:05.817 回答
4

有几个选项。

如果您有大量数据,请留出数据的随机样本。在一组上构建您的模型,然后使用另一组使用 ROC 曲线确定类别概率的适当截止值。

您还可以对少数类中的数据进行上采样。SMOTE 算法可能会有所帮助(请参阅下面的参考资料和函数的 DMwR 包)。

您还可以使用其他技术。rpart()还有一些其他功能可以允许对错误产生不同的成本,因此您可以更偏爱少数类。您可以打包这种类型的rpart()模型来近似随机森林的工作。

ksvm()在 kernlab 包中也可以使用不平衡成本(但是当你这样做时概率估计不再好)。许多其他包都有设置先验的参数。您也可以对此进行调整,以更加强调少数族裔。

最后一个想法:基于准确性最大化模型不会让您有任何帮助(您可以立即获得 99.99% 的收益)。插入符号可以根据 Kappa 统计量调整模型,在您的情况下这是一个更好的选择。

于 2012-01-03T05:28:41.743 回答
1

很确定我不同意从您的样本中删除观察结果的想法。

相反,您可以考虑使用分层样本在每次重新采样时设置每个类的固定百分比。这可以通过 Caret 包来完成。这样,您就不会通过减少训练样本的大小而忽略观察结果。它不会让你过度代表你的班级,但会确保每个子样本都有一个代表性样本。

这是我发现的一个例子:

len_pos <- nrow(example_dataset[example_dataset$target==1,])
len_neg <- nrow(example_dataset[example_dataset$target==0,])

train_model <- function(training_data, labels, model_type, ...) {
  experiment_control <- trainControl(method="repeatedcv",
                                     number = 10,
                                     repeats = 2,
                                     classProbs = T,
                                     summaryFunction = custom_summary_function)
  train(x = training_data,
        y = labels,
        method = model_type,
        metric = "custom_score",
        trControl = experiment_control,
        verbose = F,
        ...)
}

# strata refers to which feature to do stratified sampling on.
# sampsize refers to the size of the bootstrap samples to be taken from each class. These samples will be taken as input
# for each tree. 

fit_results <- train_model(example_dataset
                           , as.factor(sprintf("c%d", as.numeric(example_dataset$target)))        
                           ,"rf"
                           ,tuneGrid = expand.grid(mtry = c( 3,5,10))
                           ,ntree=500
                           ,strata=as.factor(example_dataset$target)
                           ,sampsize = c('1'=as.integer(len_pos*0.25),'0'=as.integer(len_neg*0.8))
)
于 2018-05-24T14:34:00.887 回答