So teilen Sie einen Datensatz, um eine 10-fache Kreuzvalidierung durchzuführen

14

Jetzt habe ich einen RDatenrahmen (Training). Kann mir jemand sagen, wie ich diesen Datensatz zufällig aufteilen soll, um eine 10-fache Kreuzvalidierung durchzuführen?

user22062
quelle
2
Wiederholen Sie den gesamten Vorgang 100 Mal, um eine zufriedenstellende Präzision zu erzielen.
Frank Harrell
Stellen Sie sicher, dass Fall und Kontrollprobe getrennt abgetastet werden, und kombinieren Sie sie dann zu jedem Block.
Shicheng Guo
Wenn Sie caret :: train verwenden, müssen Sie sich nicht einmal darum kümmern. Es wird intern gemacht, Sie können die Anzahl der Falten wählen. Wenn Sie darauf bestehen, dies "von Hand" zu tun, verwenden Sie geschichtete Stichproben der Klasse, wie sie in caret :: createFolds implementiert sind.
Marbel
Ich habe diesen Thread gesperrt, weil jede der vielen Antworten ihn eher als Kodierungsfrage als als eine Frage von allgemeinem statistischen Interesse behandelt.
whuber

Antworten:

22

caret hat eine Funktion dafür:

require(caret)
flds <- createFolds(y, k = 10, list = TRUE, returnTrain = FALSE)
names(flds)[1] <- "train"

Dann ist jedes Element von fldseine Liste von Indizes für jeden Datensatz. Wenn Ihr Datensatz aufgerufen wird dat, erhalten dat[flds$train,]Sie den Trainingssatz, dat[ flds[[2]], ]den zweiten Falzsatz usw.

Ari B. Friedman
quelle
12

Hier ist eine einfache Möglichkeit, das 10-fache ohne Pakete auszuführen:

#Randomly shuffle the data
yourData<-yourData[sample(nrow(yourData)),]

#Create 10 equally size folds
folds <- cut(seq(1,nrow(yourData)),breaks=10,labels=FALSE)

#Perform 10 fold cross validation
for(i in 1:10){
    #Segement your data by fold using the which() function 
    testIndexes <- which(folds==i,arr.ind=TRUE)
    testData <- yourData[testIndexes, ]
    trainData <- yourData[-testIndexes, ]
    #Use the test and train data partitions however you desire...
}
Jake Drew
quelle
-1: Caret-Funktionen führen geschichtete Stichproben durch, die Sie nicht durchführen. Was bringt es, das Rad neu zu erfinden, wenn es Ihnen jemand einfacher gemacht hat?
Marbel
10
Machst du Witze? Der gesamte Zweck der Antwort besteht darin, eine 10-fache Leistung zu erbringen, ohne das gesamte Caret-Paket installieren zu müssen. Der einzig gute Punkt, den Sie machen, ist, dass die Leute verstehen sollten, was ihr Code tatsächlich tut. Eine geschichtete Beprobung junger Grashüpfer ist nicht immer der beste Ansatz. Beispielsweise werden Untergruppen mit mehr Daten wichtiger, was nicht immer wünschenswert ist. (Vor allem, wenn Sie nicht wissen, dass es passiert). Es geht darum, den besten Ansatz für Ihre Daten zu verwenden. Troll mit Vorsicht mein Freund :)
Jake Drew
@JakeDrew Mir ist klar, dass dies jetzt ein alter Beitrag ist, aber könnte man nach einer Anleitung fragen, wie man die Test- und Zugdaten verwendet, um den durchschnittlichen Fehler eines VAR (p) -Modells für jede Iteration zu ermitteln?
gerade diesen
@ JakeDrew imho beide Antworten verdienen ein Plus 1. Einer mit einem Paket, der andere mit Code ...
Natbusa
2

Wahrscheinlich nicht der beste Weg, aber hier ist ein Weg, es zu tun. Ich bin mir ziemlich sicher, dass ich mir beim Schreiben dieses Codes einen Trick von einer anderen Antwort hier ausgeliehen hatte, aber ich konnte keinen Link dazu finden.

# Generate some test data
x <- runif(100)*10 #Random values between 0 and 10
y <- x+rnorm(100)*.1 #y~x+error
dataset <- data.frame(x,y) #Create data frame
plot(dataset$x,dataset$y) #Plot the data

#install.packages("cvTools")
library(cvTools) #run the above line if you don't have this library

k <- 10 #the number of folds

folds <- cvFolds(NROW(dataset), K=k)
dataset$holdoutpred <- rep(0,nrow(dataset))

for(i in 1:k){
  train <- dataset[folds$subsets[folds$which != i], ] #Set the training set
  validation <- dataset[folds$subsets[folds$which == i], ] #Set the validation set

  newlm <- lm(y~x,data=train) #Get your new linear model (just fit on the train data)
  newpred <- predict(newlm,newdata=validation) #Get the predicitons for the validation set (from the model just fit on the train data)

  dataset[folds$subsets[folds$which == i], ]$holdoutpred <- newpred #Put the hold out prediction in the data set for later use
}

dataset$holdoutpred #do whatever you want with these predictions
Dan L
quelle
1

Nachfolgend finden Sie einen anderen Code, den ich verwende (ausgeliehen und aus einer anderen Quelle angepasst). Kopierte es direkt aus einem Skript, das ich gerade selbst verwendet habe, und blieb in der Routine rpart. Der wahrscheinlich am meisten interessierende Teil sind die Linien zur Erzeugung der Falten. Alternativ können Sie die Funktion crossval aus dem Bootstrap-Paket verwenden.

#define error matrix
err <- matrix(NA,nrow=1,ncol=10)
errcv=err

#creation of folds
for(c in 1:10){

n=nrow(df);K=10; sizeblock= n%/%K;alea=runif(n);rang=rank(alea);bloc=(rang-1)%/%sizeblock+1;bloc[bloc==K+1]=K;bloc=factor(bloc); bloc=as.factor(bloc);print(summary(bloc))

for(k in 1:10){

#rpart
fit=rpart(type~., data=df[bloc!=k,],xval=0) ; (predict(fit,df[bloc==k,]))
answers=(predict(fit,df[bloc==k,],type="class")==resp[bloc==k])
err[1,k]=1-(sum(answers)/length(answers))

}

err
errcv[,c]=rowMeans(err, na.rm = FALSE, dims = 1)

}
errcv
Wouter
quelle
1
# Evaluate models uses k-fold cross-validation
install.packages("DAAG")
library("DAAG")

cv.lm(data=dat, form.lm=mod1, m= 10, plotit = F)

Alles in einer Codezeile für Sie erledigt!

?cv.lm for information on input and output
user1930111
quelle
0

Da ich in dieser Liste nicht auf meine Vorgehensweise eingegangen bin, dachte ich, ich könnte eine andere Option für Personen empfehlen, die keine Lust haben, Pakete für eine schnelle Gegenüberstellung zu installieren

# get the data from somewhere and specify number of folds
data <- read.csv('my_data.csv')
nrFolds <- 10

# generate array containing fold-number for each sample (row)
folds <- rep_len(1:nrFolds, nrow(data))

# actual cross validation
for(k in 1:nrFolds) {
    # actual split of the data
    fold <- which(folds == k)
    data.train <- data[-fold,]
    data.test <- data[fold,]

    # train and test your model with data.train and data.test
}

Beachten Sie, dass der obige Code davon ausgeht, dass die Daten bereits gemischt sind. Wenn dies nicht der Fall wäre, könnten Sie etwas wie hinzufügen

folds <- sample(folds, nrow(data))
Herr Tsjolder
quelle