2013-05-23 11 views
5

In einer Zuweisung werden wir aufgefordert, eine Kreuzvalidierung für ein CART-Modell durchzuführen. Ich habe versucht, die cvFit Funktion von cvTools zu verwenden, aber eine merkwürdige Fehlermeldung erhalten. Hier ist ein minimales Beispiel:Kreuzvalidierung eines CART-Modells

library(rpart) 
library(cvTools) 
data(iris) 
cvFit(rpart(formula=Species~., data=iris)) 

Der Fehler ich sehe ist:

Error in nobs(y) : argument "y" is missing, with no default 

Und die traceback():

5: nobs(y) 
4: cvFit.call(call, data = data, x = x, y = y, cost = cost, K = K, 
     R = R, foldType = foldType, folds = folds, names = names, 
     predictArgs = predictArgs, costArgs = costArgs, envir = envir, 
     seed = seed) 
3: cvFit(call, data = data, x = x, y = y, cost = cost, K = K, R = R, 
     foldType = foldType, folds = folds, names = names, predictArgs = predictArgs, 
     costArgs = costArgs, envir = envir, seed = seed) 
2: cvFit.default(rpart(formula = Species ~ ., data = iris)) 
1: cvFit(rpart(formula = Species ~ ., data = iris)) 

Es sieht aus, dass y für cvFit.default obligatorisch ist. Aber:

> cvFit(rpart(formula=Species~., data=iris), y=iris$Species) 
Error in cvFit.call(call, data = data, x = x, y = y, cost = cost, K = K, : 
    'x' must have 0 observations 

Was mache ich falsch? Welches Paket würde mir erlauben, eine Kreuzvalidierung mit einem CART-Baum durchzuführen, ohne es selbst programmieren zu müssen? (Ich bin sooo faul ...)

+3

Wenn Sie in der Dokumentation ** cvTools graben ** es erscheint Die meisten dieser Tools wurden mit kontinuierlichen Antwortvariablen erstellt und nicht diskret. Sie könnten es wahrscheinlich zum Funktionieren bringen, aber es sieht so aus, als müssten Sie Ihre eigene Funktion für die Berechnung des Klassifikationsfehlers bereitstellen. – joran

+0

@joran: Genau - danke! Siehe [meine eigene Antwort] (http://stackoverflow.com/a/16724706/946850). – krlmlr

Antwort

15

Das Caret-Paket macht Kreuzvalidierung zu einem Kinderspiel:

> library(caret) 
> data(iris) 
> tc <- trainControl("cv",10) 
> rpart.grid <- expand.grid(.cp=0.2) 
> 
> (train.rpart <- train(Species ~., data=iris, method="rpart",trControl=tc,tuneGrid=rpart.grid)) 
150 samples 
    4 predictors 
    3 classes: 'setosa', 'versicolor', 'virginica' 

No pre-processing 
Resampling: Cross-Validation (10 fold) 

Summary of sample sizes: 135, 135, 135, 135, 135, 135, ... 

Resampling results 

    Accuracy Kappa Accuracy SD Kappa SD 
    0.94  0.91 0.0798  0.12  

Tuning parameter 'cp' was held constant at a value of 0.2 
+1

Wow. Sehen Sie sich die Liste der unterstützten Methoden in 'train' an. Das nenne ich umfassend ... Hier passiert viel "Magie". Ist es möglich, nur auf die Kreuzvalidierungsroutine zuzugreifen, ohne die Modellparameter tatsächlich zu optimieren? – krlmlr

+0

Ich glaube nicht, aber Sie können Ihr eigenes Raster von Parametern definieren. Wenn Sie nicht mehrere Modelle testen möchten, könnten sie einfach auf statische Werte gesetzt werden. Ich werde das illustrieren, indem ich mein Beispiel oben bearbeite. – David

+0

Was ist Caret? Ich sehe das nicht in deiner Antwort. – stackoverflowuser2010

4

Schließlich konnte ich es an die Arbeit. Wie Joran bemerkte, muss der Parameter cost angepasst werden. In meinem Fall verwende ich 0/1 Verlust, was bedeutet, dass ich eine einfache Funktion verwende, die != anstelle von - zwischen y und yHat auswertet. Außerdem muss predictArgsc(type='class') enthalten, andernfalls wird der intern verwendete predict Aufruf einen Vektor von Wahrscheinlichkeiten anstelle der wahrscheinlichsten Klassifizierung zurückgeben. Fazit:

library(rpart) 
library(cvTools) 
data(iris) 
cvFit(rpart, formula=Species~., data=iris, 
     cost=function(y, yHat) (y != yHat) + 0, predictArgs=c(type='class')) 

(Dieser verwendet eine andere Variante cvFit Zusätzliche args rpart kann durch Setzen des args= Parameter übergeben werden..)