r - 预测 AUC 1 的集成模型

标签 r r-caret xgboost auc ensemble-learning

我正在尝试将 3 个模型组合成一个整体模型:

  1. 模型 1 - XGBoost
  2. 模型 2 - 随机森林
  3. 模型 3 - 逻辑回归

注意:这里的所有代码都使用 caret 包的 train() 函数。

> Bayes_model

No pre-processing
Resampling: Cross-Validated (10 fold) 
Summary of sample sizes: 75305, 75305, 75306, 75305, 75306, 75307, ... 
Resampling results:

  ROC        Sens  Spec
  0.5831236  1     0   

>linear_cv_model

No pre-processing
Resampling: Cross-Validated (10 fold) 
Summary of sample sizes: 75306, 75305, 75305, 75306, 75306, 75305, ... 
Resampling results:

  ROC        Sens  Spec
  0.5776342  1     0   

>rf_model_best

No pre-processing
Resampling: Cross-Validated (10 fold) 
Summary of sample sizes: 75305, 75305, 75306, 75305, 75306, 75307, ... 
Resampling results:

  ROC        Sens  Spec
  0.5551996  1     0   

这 3 个模型的 AUC 在 55-60 范围内非常差,但相关性并不非常高,所以我希望将它们集成起来。这是 R 中的基本代码:

Bayes_pred = predict(Bayes_model,train,type="prob")[,2]
linear_pred = predict(linear_cv_model,train,type="prob")[,2]
rf_pred = predict(rf_model_best,train,type="prob")[,2]
stacked = cbind(Bayes_pred,linear_pred,rf_pred,train[,"target"])

因此,这会产生一个包含 4 列、三个模型预测和目标的数据框。我认为现在的想法是在这三个预测变量上运行另一个元模型,但是当我这样做时,无论我尝试什么 XGBoost 超参数组合,我都会得到 AUC 1,所以我知道出了问题。

这个设置在概念上是不正确的吗?

meta_model = train(target~ ., data = stacked,
               method = "xgbTree",
               metric = "ROC",
               trControl = trainControl(method = "cv",number = 10,classProbs = TRUE,
                                        summaryFunction = twoClassSummary
                                        ),
               na.action=na.pass,
               tuneGrid = grid
               )

结果:

>meta_model

No pre-processing
Resampling: Cross-Validated (10 fold) 
Summary of sample sizes: 75306, 75306, 75307, 75305, 75306, 75305, ... 
Resampling results:

  ROC  Sens  Spec
  1    1     1   

我觉得 CV 折叠完美的 AUC 肯定表明存在数据错误。当在这个元模型上尝试逻辑回归时,我也得到了完美的分离。这根本没有意义。

> summary(stacked)
   Bayes_pred       linear_pred         rf_pred        Target
 Min.   :0.01867   Min.   :0.02679   Min.   :0.00000   No :74869  
 1st Qu.:0.08492   1st Qu.:0.08624   1st Qu.:0.01587   Yes: 8804  
 Median :0.10297   Median :0.10339   Median :0.04762              
 Mean   :0.10520   Mean   :0.10522   Mean   :0.11076              
 3rd Qu.:0.12312   3rd Qu.:0.12230   3rd Qu.:0.07937              
 Max.   :0.50483   Max.   :0.25703   Max.   :0.88889 

我知道这不是可重现的代码,但我认为这是一个不依赖于数据集的问题。如上所示,我有三个不同的预测,并且单独的 AUC 值肯定不高。结合起来,我应该看到一些改进,但不是完美的分离。


编辑:使用 T. Scharf 的非常有用的建议,以下是我如何获取折叠预测以在元模型中使用的方法。预测将存储在模型中的“pred”下,但预测不按原始顺序排列。您需要重新排序它们才能正确堆叠。

使用dplyr的arrange()函数,这就是我获得贝叶斯模型预测的方法:

Bayes_pred = arrange(as.data.frame(Bayes_model$pred)[,c("Yes","rowIndex")],rowIndex)[,1]

在我的例子中,“Bayes_model”是插入符序列对象,“Yes”是我正在建模的目标类。

最佳答案

这就是发生的事情

当你这样做

Bayes_pred = predict(Bayes_model,train,type="prob")[,2]
linear_pred = predict(linear_cv_model,train,type="prob")[,2]
rf_pred = predict(rf_model_best,train,type="prob")[,2]

这就是问题

您需要折叠预测或测试预测作为训练元模型的输入。

您当前正在使用已训练的模型以及训练模型所依据的数据。这将产生过于乐观的预测,您现在将这些预测提供给元模型进行训练。

A good rule of thumb is to NEVER call predict on data with a model that has already seen that data, nothing good can happen.

这是您需要执行的操作:

当您训练最初的 3 个模型时,请使用 method = cvsavePredictions = TRUE 这将保留折叠外预测,这些预测可用于训练元模型。

为了让自己相信元模型的输入数据非常乐观,请计算该对象的 3 列的单独 AUC:

stacked = cbind(Bayes_pred,linear_pred,rf_pred,train[,"目标"])

与目标相比 --- 它们会非常高,这就是为什么你的元模型如此优秀。它使用了非常好的输入。

希望这有帮助,元建模很难......

关于r - 预测 AUC 1 的集成模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45094131/

相关文章:

python - 在 H2O 的 XGBoost 上使用网格搜索时陷入 Python 困境

machine-learning - 过度拟合总是一件坏事吗?

R Shiny 选择 : How to set the minimum number of options in selectizeInput

r - 将数据框传递到函数中并按列传递到 ggplot

R:插入符包预处理()

r - 在 R 中暂停和恢复插入符训练

python - c++ 中的 xgboost 负载模型(python -> c++ 预测分数不匹配)

R - 将列表类型的列转换为 str 类型

r - 无法在 ggplot2 geom_text 中添加带有两位小数的百分比标签

r - trainControl 中的 p 参数