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

时间:2018-01-10 12:27:58

标签: r tree classification prediction rpart

我有关于rpart和overfitting的问题。我的目标只是做好预测。我的数据集很大,差不多有20000点。使用大约2.5%的这些点作为训练我得到约50%的预测误差。但是使用97.5%的数据作为训练我得到了大约30%。由于我使用了大量的训练数据,我猜有过度拟合的风险。

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

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

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

当我绘制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 个答案:

答案 0 :(得分:0)

问题非常复杂,全面回答将非常困难。我将尝试为进一步阅读提供一些见解和参考。

  • 相关特征对于基于树的方法不会造成严重问题,因为它们对于使用超平面作为分类边界的模型也是如此。当存在多个相关特征时,树将只选择一个,其余的将被忽略。然而,相关特征通常会掩盖这种模型的可解释性,掩模交互等等。基于树的模型也可以从删除这些变量中受益,因为它们必须搜索较小的空间。 Here是一种体面的树木资源。另请查看这些视频123以及ISLR本书。

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

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

在你的情况下我会用

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

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

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

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

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

等,详见上述链接。

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