如何在 R 中堆叠机器学习模型

机器算法验证 r 机器学习 集成学习 堆叠
2022-04-07 05:33:14

我是机器学习和 R 的新手。

我知道有一个名为caretEnsemble的 R 包,它可以方便地在 R 中堆叠模型。但是,这个包在处理多类分类任务时看起来有些问题

暂时,我写了一些代码来尝试手动堆叠模型,这是我处理的示例:

    library(caret)
    set.seed(123)
    library(AppliedPredictiveModeling)
    data(AlzheimerDisease)
    adData = data.frame(diagnosis, predictors)
    inTrain = createDataPartition(adData$diagnosis, p = 3 / 4)[[1]]
    training = adData[inTrain,]
    testing = adData[-inTrain,]

    set.seed(62433)
    modelFitRF <- train(diagnosis ~ ., data = training, method = "rf")
    modelFitGBM <- train(diagnosis ~ ., data = training, method = "gbm",verbose=F)
    modelFitLDA <- train(diagnosis ~ ., data = training, method = "lda")

    predRF <- predict(modelFitRF,newdata=testing)
    predGBM <- predict(modelFitGBM, newdata = testing)
    prefLDA <- predict(modelFitLDA, newdata = testing)

    confusionMatrix(predRF, testing$diagnosis)$overall[1]
    #Accuracy 
    #0.7682927 

    confusionMatrix(predGBM, testing$diagnosis)$overall[1]
    #Accuracy 
    #0.7926829 

    confusionMatrix(prefLDA, testing$diagnosis)$overall[1]
    #Accuracy 
    #0.7682927

现在我得到了三个模型:modelFitRFmodelFitGBMmodelFitLDA,以及对应于基于 的这三个模型的三个预测向量test set

然后我将创建一个数据框来包含这些预测向量和原始因变量test set

   predDF <- data.frame(predRF, predGBM, prefLDA, diagnosis = testing$diagnosis, stringsAsFactors = F)

然后,我只是使用这样的数据框作为一个新train set的来创建一个堆叠模型:

   modelStack <- train(diagnosis ~ ., data = predDF, method = "rf")
   combPred <- predict(modelStack, predDF)
   confusionMatrix(combPred, testing$diagnosis)$overall[1] 
   #Accuracy 
   #0.804878

考虑到堆叠模型通常应该提高预测的准确性,我想相信这可能是堆叠模型的权利。但是,我也怀疑在这里我使用了predDF由三个模型的预测创建的test set.

我不确定是否应该使用来自 的结果test set,然后将它们应用回 以test set获得最终预测(我指的是下面的这个块:)

   predDF <- data.frame(predRF, predGBM, prefLDA, diagnosis = testing$diagnosis, stringsAsFactors = F)
   modelStack <- train(diagnosis ~ ., data = predDF, method = "rf")
   combPred <- predict(modelStack, predDF)
   confusionMatrix(combPred, testing$diagnosis)$overall[1] 
1个回答

您在这里所做的是我所说的“Holdout Stacking”(有时也称为 Blending,但该术语也用于常规 Stacking),您可以在其中使用 holdout 集来生成元学习算法的训练数据(即predDF) . 我使用术语 Holdout Stacking 与常规 Stacking(或“超级学习”)区分开来,在常规Stacking(或“超级学习”)中,您从基础学习器生成交叉验证的预测值,以生成 metalearner 算法(在您的情况下为随机森林)的训练数据,而不是一个坚持集(你的testing框架)。

这里的问题不是你如何进行堆叠,而是你如何评估结果。使用testing框架生成predDF框架后,您必须丢弃该数据,而不是将其用于模型评估。在您的示例中,您还使用testing框架来评估基本模型和集成学习器的性能。

要解决这个问题,只需分割另一块数据。您应该有三个数据集 trainingvalidationtesting使用validation集合创建predDF(在堆叠术语中也称为“一级”数据集)。

# Generate level-one dataset for training the ensemble metalearner
predRF <- predict(modelFitRF, newdata = validation)
predGBM <- predict(modelFitGBM, newdata = validation)
prefLDA <- predict(modelFitLDA, newdata = validation)
predDF <- data.frame(predRF, predGBM, prefLDA, diagnosis = validation$diagnosis, stringsAsFactors = F)

# Train the ensemble
modelStack <- train(diagnosis ~ ., data = predDF, method = "rf")

然后评估你的基础学习者和你的集合,testing以更好地了解集合与单个学习者的比较。

# Generate predictions on the test set
testPredRF <- predict(modelFitRF, newdata = testing)
testPredGBM <- predict(modelFitGBM, newdata = testing)
testPredLDA <- predict(modelFitLDA, newdata = testing)

# Using the base learner test set predictions, 
# create the level-one dataset to feed to the ensemble
testPredLevelOne <- data.frame(testPredRF, testPredGBM, testPredLDA, diagnosis = testing$diagnosis, stringsAsFactors = F)
combPred <- predict(modelStack, testPredLevelOne)

# Evaluate ensemble test performance
confusionMatrix(combPred, testing$diagnosis)$overall[1]

# Evaluate base learner test performance 
confusionMatrix(testPredRF, testing$diagnosis)$overall[1]
confusionMatrix(testPredGBM, testing$diagnosis)$overall[1]
confusionMatrix(testPredLDA, testing$diagnosis)$overall[1]

最后,作为一个建议,我建议为元学习算法尝试 GLM,因为根据我的经验,它们似乎比基于树的模型表现更好,尽管情况并非总是如此。

如果您特别在 Stacking 中寻找多类支持,它将很快h2o R 包中提供。如果您不需要多类,那么您可以查看SuperLearnerh2o包,以便更轻松地进行堆叠,而不是全部手动编写。查看SuperLearner()h2o.stackedEnsemble()使用一行代码进行 Stacking 的函数。