过拟合 XGBoost

数据挖掘 r xgboost 交叉验证 过拟合
2021-09-15 04:09:39

我尝试从包含 315 行和 17 个(真实数据)特征 (315x17) 的数据集中对数据进行分类。目标值是“好”或“坏”(二进制分类)。

我使用 XGBoost 对这些数据进行分类,但我得到了很多过度拟合。我使用 logloss 进行交叉验证来评估性能。

绿色:logloss 验证曲线

红色:logloss 训练曲线

X 轴:nrounds(最大提升迭代次数)

在此处输入图像描述

第一个模型(第一张图片是用以下方式生成的:

bst.res <- xgb.cv(nfold = 4,
               data = matrix_training_set,
               label = training_set_label,
               eta = 0.1,
               # minimum sum of instance weight(hessian) needed in a child 
               min_child_weight = 4,
               # maximum depth of a tree 
               max_depth = 14,
               objective = "binary:logistic",
               #L2 parameter 
               lambda = 1.1,
               # L1 parameter 
               alpha = 0.5, 
               gamma = 0,
               eval_metric = "logloss",
               nrounds = 2000,
               verbose = TRUE,
               subsample = 0.7,
               print_every_n = 10,
               early_stop_round = 10)

然后,我尝试了(第二张图片):

bst.res <- xgb.cv(nfold = 4,
               data = matrix_training_set,
               label = training_set_label,
               eta = 0.01,
               # minimum sum of instance weight(hessian) needed in a child 
               min_child_weight = 4,
               # maximum depth of a tree 
               max_depth = 6,
               objective = "binary:logistic",
               #L2 parameter 
               lambda = 1.1,
               # L1 parameter 
               alpha = 0.5, 
               gamma = 1,
               eval_metric = "logloss",
               nrounds = 2000,
               verbose = TRUE,
               subsample = 0.7,
               print_every_n = 10,
               early_stop_round = 10)

基本上,可以通过改变 max_depth、min_child_weight、gamma、subsample 来减少过拟合。

下面,我再次减少过度拟合(第三张图片):

bst.res <- xgb.cv(nfold = 4,
               data = matrix_training_set,
               label = training_set_label,
               eta = 0.01,
               # minimum sum of instance weight(hessian) needed in a child 
               min_child_weight = 7,
               # maximum depth of a tree 
               max_depth = 6,
               objective = "binary:logistic",
               #L2 parameter 
               lambda = 1.1,
               # L1 parameter 
               alpha = 0.5, 
               gamma = 5,
               eval_metric = "logloss",
               nrounds = 2000,
               colsample_bytree = 0.7,
               verbose = TRUE,
               subsample = 0.3,
               print_every_n = 10,
               early_stop_round = 10)

现在看来模型有偏差(红色和绿色确实很接近,注意比例)。

我也尝试过网格搜索,但验证曲线总是很高(logloss 超过 0.5,AUC 低于 0.62)。

现在我想知道是否应该创建一个更有偏见的模型(使树更简单),然后添加更多数据以减少这种偏见。

有什么想法可以让这条绿色曲线变低吗?我的目标(“好”或“坏”)与我的特征之间是否可能没有相关性,这意味着不可能从这些数据创建分类器?

2个回答

我看到的是您的数据存在很大差异。这意味着如果没有足够数量的样本(大于 315),就根本不可能描述您能想到的任何模型的数据集。

但是,如果方差不是那么大:

  1. 您可以尝试数据增强技术。

  2. 在将数据分离到训练/验证集中之前,您是否对数据进行了洗牌?也许是一个平庸的操作,但如果在验证集中有样本与训练集相差太大,它们将永远无法正确预测。

  3. 班级很不平衡吗?如果是这样,可能你的其中一个样本太少了,在这种情况下,你可以尝试一些上采样技术。

试试随机森林,或者像套索这样的正则化模型。它们不太容易被覆盖。RF 具有额外的好处,您可以使用 OOB 估计来评估性能,因此您不必将您的小数据集分割成训练和测试。

对于小数据,提升通常不是一个好的选择,并且正如您所观察到的那样,它往往会过度拟合。如果你坚持使用 boosting,robust boosting是一种经过修改的变体,专门设计用于在小型数据集上更好地工作。