可能过度拟合的分类树,但具有稳定的预测误差

Posted

技术标签:

【中文标题】可能过度拟合的分类树,但具有稳定的预测误差【英文标题】:Possibly overfitted classification tree but with stable prediction error 【发布时间】:2018-06-19 15:05:19 【问题描述】:

我有一个关于 rpart 和过拟合的问题。我的目标只是做好预测。我的数据集很大,将近 20000 个点。使用这些点中的大约 2.5% 作为训练,我得到了大约 50% 的预测误差。但是使用 97.5% 的数据作为训练,我得到了大约 30%。由于我使用大量数据进行训练,我想存在过度拟合的风险。

我使用随机训练/测试数据运行 1000 次 + 修剪树,如果我理解正确的话,这是一种交叉验证,我得到了非常稳定的结果(相同的预测误差和变量的重要性)。

即使我已经运行了 1000 次并且预测误差稳定,过拟合仍然是一个问题吗?

我还有一个关于解释变量之间相关性的问题。这可能是 CART 中的问题(与回归一样)吗?在回归中,我可能会使用套索来尝试修复相关性。如何修复与分类树的相关性?

当我绘制 cptree 时,我得到了这张图:

cptree plot

这是我正在运行的代码(我已经重复了 1000 次,每次都使用不同的随机拆分)。

set.seed(1) # For reproducability
train_frac = 0.975
n = dim(beijing_data)[1]

# Split into training and testing data
ii = sample(seq(1,dim(beijing_data)[1]),n*train_frac)
data_train = beijing_data[ii,]
data_test = beijing_data[-ii,]

fit = rpart(as.factor(PM_Dongsi_levels)~DEWP+HUMI+PRES+TEMP+Iws+
              precipitation+Iprec+wind_dir+tod+pom+weekend+month+
              season+year+day,
            data = data_train, minsplit = 0, cp = 0)

plotcp(fit)

# Find the split with minimum CP and prune the tree
cp_fit = fit$cptable[which.min(fit$cptable[,"xerror"]),"CP"]
pfit = prune(fit, cp = cp_fit)
pp <- predict(pfit, newdata = data_test, type = "class")

err = sum(data_test[,"PM_Dongsi_levels"] != pp)/length(pp)
print(err)

链接到 beijing_data(作为 RData 文件,您可以复制我的示例) https://www.dropbox.com/s/6t3lcj7f7bqfjnt/beijing_data.RData?dl=0

【问题讨论】:

【参考方案1】:

这个问题相当复杂,很难全面回答。我将尝试提供一些见解和参考以供进一步阅读。

相关特征不会像使用超平面作为分类边界的模型那样对基于树的方法造成严重问题。当有多个相关特征时,树只会选择一个,其余的将被忽略。然而,相关特征通常会影响此类模型的可解释性、掩码交互等。基于树的模型也可以从删除这些变量中受益,因为它们必须搜索更小的空间。 Here 是一个不错的树木资源。还可以查看这些视频1、2 和3 以及ISLR 书籍。

基于一棵树的模型的性能往往不如基于超平面的方法。因此,如果您主要对预测质量感兴趣,那么您应该探索基于一堆树的模型,例如 bagging 和 boosting 模型。 R 中的 bagging 和 boosting 的流行实现是 randomForest 和 xgboost。两者都可以在几乎没有经验的情况下使用,并且可以产生良好的预测。 Here 是有关如何使用流行的 R 机器学习库 caret 调整随机森林的资源。另一个资源是 R mlr 库,它为许多与 ML 相关的伟大事物提供了很好的包装器,例如 here is a short blog post 关于基于模型的 xgboost 优化。

模型验证的重采样策略因任务和可用数据而异。对于 20 k 行,我可能会使用超过 50 - 60 % 用于训练,20 % 用于验证,20 -30 % 作为测试集。我将使用 50% 的测试集通过重复的 K 折交叉验证(2-3 次重复 4-5 折或类似)来选择合适的 ML 方法、特征、超参数等。我将使用 20% 的验证集来微调内容并了解我在训练集上的交叉验证的泛化效果。当我对一切感到满意时,我会使用测试集作为最终证明,我有一个很好的模型。以下是有关重新采样的一些资源:1、2、3 和 nested resampling。

在你的情况下我会使用

z <- caret::createDataPartition(data$y, p = 0.6, list = FALSE)
train <- data[z,]
test <- data[-z,]

要将数据拆分为训练集和测试集,然后我将重复该过程以使用p = 0.5 再次拆分测试集。

在训练数据上,我将使用 this 随机森林教程来调整 mtryntree 参数(扩展插入符号部分),使用插入符号中的 5 倍重复交叉验证和网格搜索。

control <- trainControl(method = "repeatedcv", number = 5, repeats = 3)

tunegrid <- expand.grid(.mtry = c(1:15), .ntree = c(200, 500, 700, 1000, 1200, 1500))

等等,详见上述链接。

最后一点,您需要训练的数据越多,过度拟合的可能性就越小。

【讨论】:

以上是关于可能过度拟合的分类树,但具有稳定的预测误差的主要内容,如果未能解决你的问题,请参考以下文章

随机森林为啥不会过度拟合

Xgboost在做分类问题时拟合的是啥

关于决策树的预测

SkLearn 的决策树:过度拟合还是错误?

在分类树 Python 2.7 中查找预测响应的相应样本分数

10、决策树集成--随机森林