繁体   English   中英

在R中创建堆叠的预测模型

[英]Create a stacked predictive model in R

我正在尝试学习如何创建一个混合模型,该混合模型专门训练基本模型的输出。 遵循在线上找到的建议(来自Johns Hopkins DataScience课程),在琐碎的情况下,我能够成功地做到这一点,即能够在我随后预测的相同带标签的测试数据上训练模型。

从理论上讲,该过程相对简单。

  1. 建立基础模型
  2. 对于每个模型,预测测试数据
  3. 结合newDF中的预测,包括来自testingData的标记结果作为附加列。
  4. 在newDF上训练组合或“元”模型。 该模型应该学会“说”这样的东西:“当mod1预测为0,而mod2预测为1,等等,等等,最可能的真实结果是0”
  5. 对您的验证数据重复步骤2和3
  6. 使用组合模型对验证数据做出最终预测。

下面显示了一个有效的过程:

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)

但是,下面的代码似乎表明组合的模型并没有产生新的预测,只是在回收其训练信息。 有效的代码(上面)和无效的代码之间的具体区别是,前者有效地训练和预测大小相等的带标签数据帧,而后者则训练大小为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

我完全确定我缺少一个简单的概念,只是不确定它是什么。

我已经搜索了源代码中的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为因子,每个因子的长度model.frame 82。因此,在model.frame不会返回错误。 相反,它只是从以前返回这三个因素。

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

换句话说, model.frame旨在从testing数据框中提取名称为predRFpredGBMpredLDA ,但不能(因为这些列不存在)。 而是返回您先前定义的对象。 因此,你会得到同样的结果,无论什么newdata是,只要他们没有必要的列名。

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

modRF$terms中的变量名modRF$terms与您环境中的对象相对应。

table(all.vars(delete.response(modRF$terms)) %in% ls())
FALSE 
 130

因此,当您尝试用cars预测modRF ,会出现错误

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

因此,尽管这是意外结果,但在尝试进行预测时不会出现错误。

如果在运行predict(combModFit, cars)之前从环境中删除predRFpredGBMpredLDA ,将会收到错误消息。

# 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功能的行为是一致的。 您的情况与众不同,因为combModFit中的某些术语名称与环境中的其他对象相对应。

希望能有所帮助。

caretEnsemble软件包可以为您完成所有这些工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM