2015-05-07 8 views
9

Verwenden von R 3.2.0 mit caret 6.0-41 und randomForest 4.6-10 auf einer 64-Bit-Linux-Maschine. Fehler bei der Verwendung von predict() für ein mit caret train trainiertes randomForest-Objekt() mithilfe der Formel

Beim Versuch, die predict() Methode auf ein Objekt mit der randomForesttrain() Funktion aus dem Paket caret ausgebildeten zu verwenden, um eine Formel verwendet wird, gibt die Funktion einen Fehler zurück. Beim Training über randomForest() und/oder x= und y= anstelle einer Formel läuft alles reibungslos. Hier

ist ein funktionierendes Beispiel:

library(randomForest) 
library(caret) 

data(imports85) 
imp85  <- imports85[, c("stroke", "price", "fuelType", "numOfDoors")] 
imp85  <- imp85[complete.cases(imp85), ] 
imp85[] <- lapply(imp85, function(x) if (is.factor(x)) x[,drop=TRUE] else x) ## Drop empty levels for factors. 

modRf1 <- randomForest(numOfDoors~., data=imp85) 
caretRf <- train(numOfDoors~., data=imp85, method = "rf") 
modRf2 <- caretRf$finalModel 
modRf3 <- randomForest(x=imp85[,c("stroke", "price", "fuelType")], y=imp85[, "numOfDoors"]) 
caretRf <- train(x=imp85[,c("stroke", "price", "fuelType")], y=imp85[, "numOfDoors"], method = "rf") 
modRf4 <- caretRf$finalModel 

p1  <- predict(modRf1, newdata=imp85) 
p2  <- predict(modRf2, newdata=imp85) 
p3  <- predict(modRf3, newdata=imp85) 
p4  <- predict(modRf4, newdata=imp85) 

Unter den letzten 4 Zeilen, nur die zweite p2 <- predict(modRf2, newdata=imp85) den folgenden Fehler zurückgibt:

Error in predict.randomForest(modRf2, newdata = imp85) : 
variables in the training data missing in newdata 

Es scheint, dass der Grund für diesen Fehler ist, dass Die Methode predict.randomForest verwendet rownames(object$importance), um den Namen der Variablen zu ermitteln, die zum Trainieren der Zufallswaldstruktur object verwendet werden. Und wenn bei

rownames(modRf1$importance) 
rownames(modRf2$importance) 
rownames(modRf3$importance) 
rownames(modRf4$importance) 

suchen Wir sehen:

[1] "stroke" "price" "fuelType" 
[1] "stroke" "price" "fuelTypegas" 
[1] "stroke" "price" "fuelType" 
[1] "stroke" "price" "fuelType" 

Also irgendwie, wenn sie mit einer Formel, die die carettrain() Funktion ändert den Namen des (Faktor) Variablen im importance Feld des randomForest Objekt .

Ist es wirklich eine Inkonsistenz zwischen der Formel und der Nicht-Formel Version der Caret train() Funktion? Oder fehlt mir etwas?

+2

'modRf3 <- Random (x = Datatrain [c ("Hub", "Preis", "fuelType")], y = Datatrain [ "numOfDoors"], data = imp85) Fehler bei randomForest (x = dataTrain [, c ("stroke", "price", "fuelType")],: Objekt 'dataTrain' nicht gefunden ' –

+0

Wie bereits erwähnt, haben Sie in Ihrem Beispiel nicht 'dataTrain' definiert Problem ist nicht [reproduzierbar] (http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) Es ist nicht einfach, Ihnen zu helfen, wenn wir den Code nicht ausführen können und bekomme die gleichen Ergebnisse wie du. – MrFlick

+0

Meine schlechte, 'DataTrain' hätte' imp85' sein sollen, ich habe den Code in der ursprünglichen Frage bearbeitet.Ich habe auch die Option 'data = imp85' im Aufruf entfernt, wo' x' und ' y 'werden explizit als t erwähnt Hier nützt es nichts. –

Antwort

21

Zuerst fast nie Verwenden Sie das Objekt $finalModel für die Vorhersage. Verwenden Sie predict.train. Dies ist ein gutes Beispiel dafür.

Es gibt einige Unstimmigkeiten zwischen einigen Funktionen (einschließlich randomForest und train), die Dummy-Variablen verarbeiten. Die meisten Funktionen in R, die die Formelmethode verwenden, konvertieren Faktorprädiktoren in Dummyvariablen, da ihre Modelle numerische Darstellungen der Daten erfordern. Die Ausnahmen sind baum- und regelbasierte Modelle (die sich auf kategoriale Prädiktoren aufteilen können), naive Bayes und einige andere.

So randomForest wird nicht erstellen Dummy-Variablen, wenn Sie verwenden randomForest(y ~ ., data = dat) aber train (und die meisten anderen) einen Anruf wie train(y ~ ., data = dat) verwenden. Der Fehler tritt auf, weil fuelType ein Faktor ist. Die Dummy-Variablen, die von train erstellt werden, haben nicht die gleichen Namen, sodass predict.randomForest sie nicht finden können.

Mit der nicht-Formel-Methode mit train werden die Faktor-Prädiktoren an randomForest übergeben und alles wird funktionieren.

TL; DR

Verwenden Sie die Nicht-Formel-Methode mit train wenn Sie die gleichen Ebenen oderpredict.train verwenden möchten

Max

+1

Ich habe leider nicht genug Ruf, um deine Antwort zu verbessern, aber du hast meine Frage perfekt beantwortet. Ich habe mich nach all den Funktionen gefragt, die es erlauben, Formeln zu verwenden, wenn es einen Unterschied in der Art und Weise gibt, wie die Daten zwischen den Formeln und Nicht-Formel-Versionen des Funktionsaufrufs behandelt wurden. Jetzt weiß ich! Für die Verwendung von '$ finalModel' stimme ich zu, dass es im Allgemeinen keine gute Idee ist, es zu verwenden. Hier wollte ich nur das Ergebnis der 'Caret'- und' RandomForest'-Methoden vergleichen. –

0

Es gibt zwei Gründe, warum Sie diesen Fehler erhalten.

1. Die Kategorien der kategorialen Variablen im Zug und in den Testsätzen stimmen nicht überein. Um das zu überprüfen, können Sie etwas wie folgt ausführen.

Nun, zuerst ist es eine gute Übung, die unabhängigen Variablen/Features in einer Liste zu behalten. Sagen wir, diese Liste ist "vars". Und sagen Sie, Sie haben "Daten" in "Train" und "Test" getrennt. Lassen Sie uns gehen:

for (v in vars){ 
    if (class(Data[,v]) == 'factor'){ 
    print(v) 
    # print(levels(Train[,v])) 
    # print(levels(Test[,v])) 
    print(all.equal(levels(Train[,v]) , levels(Test[,v]))) 
    } 
} 

Wenn Sie die nicht passenden kategorischen Variablen finden, können Sie zurückgehen, und verhängen die Kategorien von Testdaten auf Zugdaten und dann Ihr Modell neu zu bauen. In einer Schleife ähnlich wie oben, für jede nonMatchingVar, können Sie

levels(Test$nonMatchingVar) <- levels(Train$nonMatchingVar) 

2. Ein dumm man tun. Wenn Sie die abhängige Variable versehentlich in der Menge der unabhängigen Variablen belassen, können Sie auf diese Fehlermeldung stoßen. Ich habe diesen Fehler gemacht. Lösung: Seien Sie vorsichtiger.

0

Eine andere Möglichkeit besteht darin, die Testdaten unter Verwendung von model.matrix, z.

p2 <- predict(modRf2, newdata=model.matrix(~., imp85)) 
Verwandte Themen