在R中创建堆叠预测模型

时间:2015-08-19 22:47:04

标签: r prediction r-caret ensemble-learning

我正在努力学习如何创建一个专门训练基础模型输出的混合模型。根据在线发现的建议(来自Johns Hopkins DataScience课程),我可以在一个简单的案例中成功地做到这一点,即能够在我预测的相同标记测试数据上训练我的模型。

理论上,这个过程相对简单。

  1. 构建基础模型
  2. 对于每个模型,预测测试数据
  3. 结合newDF中的预测,将来自testingData的标记结果作为附加列包含。
  4. 在newDF上训练一个组合的,或者“'”模型。这个模型应该学习"说"类似于:"当mod1预测0,mod2预测1等等时,最可能的真实结果是0"
  5. 重复步骤2& 3关于验证数据
  6. 使用组合模型对验证数据进行最终预测。
  7. 下面显示了一个有效的流程:

    library(caret)
    library(gbm)
    set.seed(3433)
    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)
    modRF <- train(diagnosis ~., method = "rf", data = training)
    modGBM <- train(diagnosis ~., method = "gbm", data = training) 
    modLDA <- train(diagnosis ~., method = "lda", data = training, preProcess=c("center","scale")) 
    
    # STACK THE PREDICTIONS
    # make predictions
    predRF <- predict(modRF,testing)
    predGBM <- predict(modGBM, testing)
    predLDA <- predict(modLDA, testing)
    
    # Fit a model that combines all (both of the predictors)
    predDF <- data.frame(predRF,predGBM,predLDA,diagnosis=testing$diagnosis)
    #train a new model on the predictions
    combModFit <- train(diagnosis ~.,method="rf",data=predDF)
    predComb <- predict(combModFit,testing)
    

    然而,下面的代码似乎表明组合模型不会产生新的预测,它只是回收它的培训信息。有效的代码之间的具体差异(上图)&amp;不起作用的代码(下面)是前者有效地训练和预测相同大小的标记数据帧,而后者训练1大小的DF并且预测另一大小的未标记DF。

    #create a sudo holdout set by modifying the existing test set
    library(dplyr)
    otherTest <- testing %>% select(-diagnosis) #remove diagnosis so df is unlabled
    otherTest <- otherTest[1:70,] # remove rows so that the test set changes size
    newPreds <- predict(combModFit, otherTest) 
    # Warning message: 'newdata' had 70 rows but variables found have 82 rows 
    # newPreds now has 82 rows, but there were only 70 rows in otherTest to predict on. 
    
    identical(predComb,newPreds) #TRUE
    

    我完全相信我错过了一个简单的概念,我只是不确定它是什么。

2 个答案:

答案 0 :(得分:3)

我搜索了predict.train的源代码,到目前为止,这是我能搞定的

predict.train <- function (object, newdata = NULL, type = "raw", 
na.action = na.omit, ...) 

在你的函数调用中

newPreds <- predict(combModFit, otherTest)

参数设置

object <- combModFit
newdata <- otherTest

predict.train函数中是行

newdata <- as.data.frame(newdata)
rn <- row.names(newdata)
Terms <- delete.response(object$terms)
m <- model.frame(Terms, newdata, na.action = na.action, 
      xlev = object$xlevels)

Terms来自combModFit$terms并且

diagnosis ~ predRF + predGBM + predLDA

在删除回复之前,它成为公式

~ predRF + predGBM + predLDA

现在,回到model.frame调用,这些列名称都不在testing数据框中

c("predRF", "predGBM", "predLDA") %in% names(testing)

[1] FALSE FALSE FALSE

但是,在代码的前面,您已将对象predRFpredGBMpredLDA定义为长度为82的因子。因此,model.frame不会返回调用时出错。相反,它只是从以前返回这三个因素。

结果,对象m成为具有这三个对象(作为列)和82行的数据框。

换句话说,model.frame旨在从名为testingpredRFpredGBM的{​​{1}}数据框中提取列,但可以' t(因为那些列不存在)。相反,它返回您之前定义的对象。因此,无论predLDA是什么,只要它们没有必需的列名,您就会得到相同的结果。

编辑:要从评论中回答您的问题

newdata中的所有变量名都不对应于您环境中的对象。

modRF$terms

因此,当您尝试使用table(all.vars(delete.response(modRF$terms)) %in% ls()) FALSE 130 预测modRF时会出现错误

cars

找不到predict(modRF, cars) Error in eval(expr, envir, enclos) : object 'ACE_CD143_Angiotensin_Converti' not found 中的第一个字词

modRF$terms

但是,all.vars(delete.response(modRF$terms))[1] [1] "ACE_CD143_Angiotensin_Converti" 中的术语与环境中对象的名称相匹配。

combModFit

因此,当您尝试预测时没有错误,尽管这是一个意外的结果。

如果您在运行table(all.vars(delete.response(combModFit$terms)) %in% ls()) TRUE 3 之前从环境中删除了predRFpredGBMpredLDA,则会收到错误。

predict(combModFit, cars)

请注意,# before deleting predict(combModFit, cars) [1] Control Control Impaired .... # after deleting the three objects you get an error rm(list = c("predRF", "predGBM", "predLDA")) predict(combModFit, cars) Error in eval(expr, envir, enclos) : object 'predRF' not found 是来自predRF

的第一个字词
combModFit

因此all.vars(delete.response(combModFit$terms))[1] [1] "predRF" 函数的行为是一致的。您的情况很不寻常,因为caret中的某些术语名称与环境中的其他对象相对应。

希望有所帮助。

答案 1 :(得分:2)

caretEnsemble包可以为您完成所有这些操作。