随机森林分类器是否需要验证集?

数据挖掘 随机森林
2021-09-21 23:26:57

使用随机森林分类器时是否需要训练、测试和验证集?

我知道它对神经网络很重要,但我不理解它对 RF 的重要性。我理解拥有第三组看不见的数据进行测试的想法很重要,因为知道模型不会过度拟合,尤其是神经网络,但使用 RF 时,您似乎甚至几乎没有测试或验证数据(我知道实际上这不是真的)但在理论上,因为森林的每棵树都使用训练数据集的随机样本(有替换)。

目前我错过了大约 250 个样本,因为它们从训练和测试集中看不到,我知道模型会随着额外的数据而改进,所以是否可以只训练和测试而不指定单独的验证集,同时仍然有一个可靠的模型?

3个回答

如果您缺少数据,您可以使用 Out-of-bag 错误作为验证错误。

您可能知道,随机森林适合多棵决策树,而对于每棵树,它只适合数据的一个子集。因此,尚未用于拟合给定树的数据称为 Out of Bag 数据,它可以用作您的验证集1

Python中的Sklearn有一个Out-of-bag错误的超参数

是否可以只进行训练和测试而不指定单独的验证集,同时仍然拥有可靠的模型?

当然!您可以在训练集上训练 RF,然后在测试集上进行测试。只要模型在训练期间没有看到任何测试数据,这就是完全有效的。(或者,更好的是,您可以运行交叉验证,因为 RF 可以快速训练)

但是,如果您想调整模型的超参数或进行任何正则化(如修剪),那么您将需要一个验证集。使用训练集进行训练,使用验证集进行调整,然后使用测试集生成准确度估计。

现有的答案非常好,但这里有更多细节。他发明随机森林的论文中,Breiman 吹捧袋外计算作为交叉验证的替代方案:

因此,使用袋外误差估计消除了对预留测试集的需要。

在同一篇论文中,他加倍强调,OOB 比 CV 更可取:

...与存在偏差但程度未知的交叉验证不同,袋外估计是无偏的

这是一个更具体的例子。让我们根据来自 Kaggle的数据集训练一个随机森林。

library(conflicted)
library(tidyverse)
library(tidymodels)
library(ranger)
col_factor <- readr::col_factor
telco_raw <- read_csv(
  "archive.zip",
  col_types = cols(
    Churn = col_factor(levels = c("Yes",
                                  "No")),
    Dependents = col_factor(levels = c("Yes",
                                       "No")),
    PaperlessBilling = col_factor(levels = c("Yes",
                                             "No")),
    Partner = col_factor(levels = c("Yes",
                                    "No")),
    PhoneService = col_factor(levels = c("Yes",
                                         "No")),
    SeniorCitizen = col_factor(levels = c("0",
                                          "1")),
    customerID = col_skip(),
    gender = col_factor(levels = c("Female",
                                   "Male"))
  )
) %>% 
  na.omit()

telco <- initial_split(telco_raw, prop = 0.8, strata = Churn)
telco_train <- training(telco)
# Since we're only running this once, we can combine testing and assessment
telco_test <- rbind(testing(telco), assessment(telco))

model_ranger <- ranger(Churn ~ ., data = telco_train)

袋外数据的准确性如何?换句话说,使用从每棵树的训练中排除的数据的模型的准确性是多少?

# OOB accuracy
1 - model_ranger$prediction.error
#0.7965168

80%左右。

模型在整个训练数据集上的准确性如何?

# Training data accuracy
accuracy_vec(truth = telco_train$Churn, estimate = model_ranger$predictions)
#0.7965168

完全一样!好的,但是最重要的交叉验证的准确性呢?

# CV accuracy
accuracy_vec(truth = telco_test$Churn, predict(model_ranger, data = telco_test)$predictions)
#0.7921708

它稍微低一点,但与我们在训练数据中看到的非常接近。

如果您只训练一次模型而不尝试对其进行调整,则可以使用所有数据来训练随机森林。当我在工作时,我仍然使用 CV 有以下三个原因:

  1. 我以特定于训练数据的方式调整模型。
  2. 通常,我正在对较旧的数据进行培训,并希望我的模型能够处理将来生成的数据。我拿出最新的数据点进行测试。例如,我可能会使用 3 到 24 个月前的数据进行训练,并使用最后两个月进行测试/验证。在这种情况下,我想说明坚持数据中“存在偏差但其程度未知”的事实。
  3. 我喜欢能够逐个比较模型,所以我对我制作的每个模型都使用相同的保留数据和相同的测试。很高兴能够在所有模型类型中获得完全相同的指标。