Seite 1 von 3
k-fache Kreuzvalidierung für Random Forest
Verfasst: Sa Mär 30, 2019 12:46 pm
von Mia89
Hallo,
ich würde gerne eine k-fache Kreuzvalidierung für ein Random Forest Model durchführen um die optimale Anzahl an Bäumen zu erhalten.
Die Theorie ist mir klar, zuerst k-folds bilden mit dem Trainingsdatensatz, dann Tuning Parameter festlegen.
Dann mein Model auf k-1 folds fitten und die Werte auf dem Validierungsset vorhersagen.
Allerdings weiß ich nicht, wie ich mein Model aufstellen soll, bzw. wie ich ein Model z.b. mit k=10 dann 10 mal hintereinander fitte, damit jedes Fold einmal Validierungsset ist.
Könnte mir jemand anhand eines R-Codes die einzelnen Schritte erklären?
Vielen Dank im Voraus
Re: k-fache Kreuzvalidierung für Random Forest
Verfasst: Sa Mär 30, 2019 9:49 pm
von EDi
Willst du alles mit der Hand machen oder dürfen es auch higher-level Funktionen sein?
Für zweiteres schau dir mal caret an.
rsample ist etwas mehr low level(
https://www.google.com/amp/s/rdrr.io/a/ ... ld_cv.html), und man kann viele individuell damit anstellen.
Wennes Noch tiefer gehen soll, dann ist dir Frage vermutlich zu umfangreich und zu wage für dieses Forum.
Re: k-fache Kreuzvalidierung für Random Forest
Verfasst: So Mär 31, 2019 7:39 pm
von Mia89
Eigentlich wollte ich alles per Hand erstellen. Also das Random Forest Model habe ich schon aufgestellt, komme bei der CV leider nicht weiter.
Re: k-fache Kreuzvalidierung für Random Forest
Verfasst: Mo Apr 01, 2019 10:08 am
von bigben
Hier ein erster Ansatz für die Kreuzvalidierung "von Hand". Schau Dir das mal an und schreib, ob Du damit was anfangen kannst.
Code: Alles auswählen
pseudodaten <- data.frame(a = rnorm(98), b = runif(98))
pseudodaten$gruppe <- sample(gl(n=10, k=10, length=nrow(pseudodaten)))
for(leave_out in levels(pseudodaten$gruppe)){
print(leave_out)
training <- subset(pseudodaten, pseudodaten$gruppe != leave_out)
test <- subset(pseudodaten, pseudodaten$gruppe == leave_out)
print(nrow(training))
print(coef(lm(a ~ b, training)))
}
Mit der Funktion
gl kann man zehn verschiedene Gruppen erzeugen. Wenn Du die Funktion nicht kennst, dann lies
gl nach. Der Aufruf von
sample ist dazu da, die Zuordnung zu den Gruppen zufällig zu machen. Anschließend rufe ich eine
for-Schleife auf, in der für jede der zehn Gruppen ein Trainings- und ein Testdatensatz via
subset erstellt werden. Danach habe ich nur zwei
print-Aufrufe um zu zeigen, dass was passiert. An deren Stelle musst Du Deine Random-Forest auf Basis des Training-Datensatzes erstellen und mit dem Test-Datensatz evaluieren. Kriegst Du das selbst hin?
LG,
Bernhard
Re: k-fache Kreuzvalidierung für Random Forest
Verfasst: Mo Apr 01, 2019 10:35 am
von Mia89
Super vielen Dank, ich versuche es gleich mal.
Kannst du mir vielleicht auch noch sagen wie ich die AUC als Evaluationsmaß einstelle?
Re: k-fache Kreuzvalidierung für Random Forest
Verfasst: Mo Apr 01, 2019 10:55 am
von Mia89
Ich habe es jetzt mal versucht, allerdings funktioniert es nicht, wo mache ich denn einen Fehler?
Code: Alles auswählen
data.training$gruppe <- sample(gl(n=5, k=5, length=nrow(data.training)))
for(leave_out in levels(data.training$gruppe)){
print(leave_out)
training <- subset(data.training, data.training$gruppe != leave_out)
test <- subset(data.training, data.training$gruppe == leave_out)
print(nrow(training))
#train RF
trainrf= randomForest(
x = training
, y = as.factor(training)
, ntree = c(200, 400, 600)
, mtry = c(2, 4, 6)
, importance = TRUE
, do.trace = 20)
predirf = predict(trainrf, newdata = test)
err.vect[leave_out] =roc.area(test, predirf)
print(paste("AUC for fold", leave_out, ":", err.vect[leave_out]))
}
print(paste("Average AUC:", mean(err.vect)))
Re: k-fache Kreuzvalidierung für Random Forest
Verfasst: Mo Apr 01, 2019 12:25 pm
von bigben
Hallo Mia!
"Es funktioniert nicht" ist nie eine gute Fehlerbeschreibung. Was genau funktinioniert nicht? Ich nehme an, Du erhälst eine Fehlermeldung. Welche denn genau?
In Deinem Code fehlt zunächst einmal ein Aufruf von
Ohne das kann es nicht laufen.
Dann habe ich Deinen Datensatz nicht, kann das also bei mir nicht laufen lassen. Ins Auge sticht mir aber folgendes:
Code: Alles auswählen
trainrf= randomForest(
x = training
, y = as.factor(training)
...
Wenn
training ein Dataframe ist, dann kann dieser nicht gleichzeitig
x und
y im Aufruf sein. Du müsstest randomForest schon irgendwie mitteilen, welche Spalten in diesem Dataframe als Prädiktoren und welche als Ergebnis, anders gesagt, was die unabhängigen und was die abhängige Variable ist. Wenn ich R wäre, würde ich an dieser Stelle wahrscheinlich eine Fehlermeldung ausgeben.
LG,
Bernhard
Re: k-fache Kreuzvalidierung für Random Forest
Verfasst: Mo Apr 01, 2019 1:09 pm
von Mia89
Danke schonmal für den Tipp.
Also die Pakete habe ich alles schon geladen.
Das mit dem x und y vector ist ein guter Hinweis.
Wenn ich für y = as.factor(trainingset.mt.y) einsetze, erhalte ich dennoch die gleiche Fehlermeldung.
Ganz am Anfang habe ich meine Datensatz in verschiedene Matrix und Data.frame Versionen aufgeteilt, so dass mein normales Random Forest Model so aussieht :
Code: Alles auswählen
library(randomForest)
set.seed(1234)
RF.mod = randomForest(
x = trainingset.mt.X
, y = as.factor(trainingset.mt.y)
, ntree = 500
, mtry = 3
, importance = TRUE
, do.trace = 10)
Code: Alles auswählen
Fehler: Must use a vector in `[`, not an object of class matrix.
Call `rlang::last_error()` to see a backtrace
>
> print(paste("Average AUC:", mean(err.vect)))
Fehler in mean(err.vect) : Objekt 'err.vect' nicht gefunden
Re: k-fache Kreuzvalidierung für Random Forest
Verfasst: Mo Apr 01, 2019 1:32 pm
von bigben
Mia89 hat geschrieben: Mo Apr 01, 2019 1:09 pmDas mit dem x und y vector ist ein guter Hinweis.
Ja, da würde ich weiter nach Deinem Fehler suchen.
Wenn ich für y = as.factor(trainingset.mt.y) einsetze, erhalte ich dennoch die gleiche Fehlermeldung.
Keine Ahnung, was
trainingsset.mt.y bedeuten soll, hast Du bislang hier noch nicht definiert.
Da ich die AUC-Funktionen in randomForest nicht kenne, habe ich mal ein numerisches Beispiel gebastelt, bei dem der RSME bestimmt wird. Vielleicht hilft das ja.
Code: Alles auswählen
library(randomForest)
k <- 10
x=rnorm(304); y=runif(304); z=ifelse(x>0, jitter(2*x+y^2), x-y)
beispieldaten <- data.frame(x=x, y=y, z=z)
beispieldaten$gruppe <- sample(gl(n=k, k=1, length=nrow(beispieldaten)))
rsme <- numeric(0)
for(leave_out in levels(beispieldaten$gruppe)){
training <- subset(beispieldaten, beispieldaten$gruppe != leave_out)
test <- subset(beispieldaten, beispieldaten$gruppe == leave_out)
cat(paste0("\nDurchgang: ",leave_out," Trainingsdaten: ", nrow(training), "\n"))
#train RF
trainrf <- randomForest(z ~ x + y, data = training)
predirf = predict(trainrf, newdata = test)
rsme1 <- sqrt(mean((test$z-predirf)^2))
rsme <- append(rsme, rsme1)
cat(paste0("RSME = ", round(rsme1,3)))
}
print(paste("Average RSME:", mean(rsme)))
LG,
Bernhard
Re: k-fache Kreuzvalidierung für Random Forest
Verfasst: Mo Apr 01, 2019 9:01 pm
von EDi
Code: Alles auswählen
Fehler: Must use a vector in `[`, not an object of class matrix.
Call `rlang::last_error()` to see a backtrace
>
rlang?! Hätte ich jetzt nicht hier erwartet...
Da das randomForest keine Abhängigkeit hat und wesentlich älter als rlang ist, vermute ich das der Fehler woanders herrührt.
Vermutlich weil du tibble anstatt eine matrix übergibst. Aber ohne ein reproduzierbares Beispie ist das alles höchst spekulativ...
Generell würde ich NIE ein tibble an Funktionen übergeben die nicht aus dem tidyverse stammen (=alle Modellierungsfunktionen)...