我正在努力学习如何创建一个专门训练基础模型输出的混合模型。根据在线发现的建议(来自Johns Hopkins DataScience课程),我可以在一个简单的案例中成功地做到这一点,即能够在我预测的相同标记测试数据上训练我的模型。
理论上,这个过程相对简单。
下面显示了一个有效的流程:
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
我完全相信我错过了一个简单的概念,我只是不确定它是什么。
答案 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
但是,在代码的前面,您已将对象predRF
,predGBM
和predLDA
定义为长度为82的因子。因此,model.frame
不会返回调用时出错。相反,它只是从以前返回这三个因素。
结果,对象m
成为具有这三个对象(作为列)和82行的数据框。
换句话说,model.frame
旨在从名为testing
,predRF
和predGBM
的{{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
之前从环境中删除了predRF
,predGBM
和predLDA
,则会收到错误。
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
包可以为您完成所有这些操作。