2016-04-18 29 views
8

Sono nuovo al punto di vista del cursore, e voglio solo assicurarmi di comprendere appieno cosa sta facendo. A tal fine, ho tentato di replicare i risultati ottenuti da un modello randomForest() utilizzando la funzione train() di caret per method = "rf". Sfortunatamente, non sono stato in grado di ottenere risultati corrispondenti, e mi chiedo cosa sto trascurando.Diversi risultati con randomForest() e il caso randomForest (metodo = "rf")

Aggiungo anche che dato che randomForest utilizza il bootstrap per generare campioni per adattarsi a ciascuno dei ntrees e stima l'errore in base a previsioni out-of-bag, sono un po 'sfocato sulla differenza tra specificare "oob "e" boot "nella chiamata della funzione trainControl. Queste opzioni generano risultati diversi, ma nessuno dei due corrisponde al modello randomForest().

Anche se ho letto il sito Web del pacchetto di caret (http://topepo.github.io/caret/index.html), nonché varie domande StackOverflow che sembrano potenzialmente rilevanti, ma non sono stato in grado di capire perché il metodo di metodo caret = "rf" produce risultati diversi da randomForest(). Grazie mille per qualsiasi suggerimento che potresti essere in grado di offrire.

Ecco un esempio replicabile, utilizzando il dataset CO2 dal pacchetto MASS.

library(MASS) 
data(CO2) 

library(randomForest) 
set.seed(1) 
rf.model <- randomForest(uptake ~ ., 
         data = CO2, 
         ntree = 50, 
         nodesize = 5, 
         mtry=2, 
         importance=TRUE, 
         metric="RMSE") 

library(caret) 
set.seed(1) 
caret.oob.model <- train(uptake ~ ., 
        data = CO2, 
        method="rf", 
        ntree=50, 
        tuneGrid=data.frame(mtry=2), 
        nodesize = 5, 
        importance=TRUE, 
        metric="RMSE", 
        trControl = trainControl(method="oob"), 
        allowParallel=FALSE) 

set.seed(1) 
caret.boot.model <- train(uptake ~ ., 
        data = CO2, 
        method="rf", 
        ntree=50, 
        tuneGrid=data.frame(mtry=2), 
        nodesize = 5, 
        importance=TRUE, 
        metric="RMSE", 
        trControl=trainControl(method="boot", number=50), 
        allowParallel=FALSE) 

print(rf.model) 
print(caret.oob.model$finalModel) 
print(caret.boot.model$finalModel) 

produce i seguenti:

di stampa (rf.model)

 Mean of squared residuals: 9.380421 
       % Var explained: 91.88 

stampa (caret.oob.model $ finalModel)

 Mean of squared residuals: 38.3598 
       % Var explained: 66.81 

stampa (caret.boot.model $ finalModel)

 Mean of squared residuals: 42.56646 
       % Var explained: 63.16 

E il codice a guardare variabile importanza:

importance(rf.model) 

importance(caret.oob.model$finalModel) 

importance(caret.boot.model$finalModel) 
+0

Breve utilizzando i dati effettivi e cercando di riprodurre i modelli che costruito, hai esaminato il comportamento dei modelli di caret e randomForest? Se entrambi mostrano predittori importanti molto simili, con pesi simili, allora potresti essere meno preoccupato per altre variazioni. –

+0

Ciao Tim - Grazie per il tuo tempo e il tuo contributo. Ho esaminato l'importanza della variabile (ho aggiornato il codice sopra per riflettere questo), e sto ricevendo pesi diversi per i predittori. Anche se i pesi non fossero così diversi, comunque, vorrei ancora capire che cosa causasse le differenze. Quando non riesco a spiegare qualcosa, sono sempre preoccupato per quello che non so che non lo so! – ej5607

+1

L'uso dell'interfaccia formula in treno converte i fattori in manichino. Per confrontare con randomForest dovresti usare l'interfaccia non di formula. Ad esempio 'treno (CO2 [, -5], CO2 $ uptake, method =" rf ", ...)' –

risposta

5

Utilizzando l'interfaccia formula in treno converte fattori da manichino. Per confrontare i risultati da caret con randomForest, è necessario utilizzare l'interfaccia non di formula.

Nel tuo caso, è necessario fornire un seme all'interno di trainControl per ottenere lo stesso risultato di randomForest.

Section training nella pagina Web di accento circonflesso, ci sono alcune note sulla riproducibilità in cui spiega come utilizzare i semi.

library("randomForest") 
set.seed(1) 
rf.model <- randomForest(uptake ~ ., 
         data = CO2, 
         ntree = 50, 
         nodesize = 5, 
         mtry = 2, 
         importance = TRUE, 
         metric = "RMSE") 

library("caret") 
caret.oob.model <- train(CO2[, -5], CO2$uptake, 
         method = "rf", 
         ntree = 50, 
         tuneGrid = data.frame(mtry = 2), 
         nodesize = 5, 
         importance = TRUE, 
         metric = "RMSE", 
         trControl = trainControl(method = "oob", seed = 1), 
         allowParallel = FALSE) 

Se stai facendo il ricampionamento, è necessario fornire i semi per ogni iterazione ricampionamento e uno supplementare per il modello finale. Gli esempi in ?trainControl mostrano come crearli.

Nell'esempio seguente, l'ultimo seme è per il modello finale e l'ho impostato su 1.

seeds <- as.vector(c(1:26), mode = "list") 

# For the final model 
seeds[[26]] <- 1 

caret.boot.model <- train(CO2[, -5], CO2$uptake, 
          method = "rf", 
          ntree = 50, 
          tuneGrid = data.frame(mtry = 2), 
          nodesize = 5, 
          importance = TRUE, 
          metric = "RMSE", 
          trControl = trainControl(method = "boot", seeds = seeds), 
          allowParallel = FALSE) 

Definig correttamente l'interfaccia non formula con caret e le sementi in trainControl si vuole ottenere gli stessi risultati in tutti e tre i modelli:

rf.model 
caret.oob.model$final 
caret.boot.model$final 
+0

Grazie, Lluís! Ha funzionato perfettamente! – ej5607

+0

La media dei residui al quadrato e la varianza spiegata dal modello ora coincidono esattamente con i modelli randomForest e caret. Le stime dell'importanza del predittore% IncMSE rimangono diverse, anche se con l'interfaccia non formula. Cosa potrebbe spiegare questo? – ej5607

+0

Ottengo gli stessi risultati in 'importanza (rf.model)', 'importanza (caret.oob.model $ finalModel)' e 'importanza (caret.boot.model $ finalModel)'. –

Problemi correlati