簡體   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