Come dividere un set di dati per eseguire la convalida incrociata 10 volte


14

Ora ho un Rframe di dati (training), qualcuno può dirmi come dividere casualmente questo set di dati per fare una validazione incrociata di 10 volte?


2
Assicurati di ripetere l'intero processo 100 volte per ottenere una precisione soddisfacente.
Frank Harrell,

Assicurati di campionare il caso e di controllarlo separatamente, quindi combinali per ciascun blocco.
Shicheng Guo,

Se usi caret :: train, non devi nemmeno preoccupartene. Sarà fatto internamente, puoi scegliere la quantità di pieghe. Se insisti nel fare questo "a mano" usa il campionamento stratificato della classe come implementato in caret :: createFolds.
Marbel,

Ho bloccato questa discussione perché ognuna delle molte risposte la tratta solo come una domanda di codifica piuttosto che di interesse statistico generale.
whuber

Risposte:


22

caret ha una funzione per questo:

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

Quindi ogni elemento di fldsè un elenco di indici per ciascun set di dati. Se viene chiamato il set di dati dat, dat[flds$train,]viene visualizzato il set di allenamento, il set dat[ flds[[2]], ]di seconda piega, ecc.


12

Ecco un modo semplice per eseguire 10 volte senza pacchetti:

#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...
}

-1: le funzioni del cursore eseguono un campionamento stratificato che non si sta eseguendo. Che senso ha reinventare il weel se qualcuno ti ha semplificato le cose?
Marbel,

10
Stai scherzando? Lo scopo della risposta è quello di eseguire 10 volte senza dover installare l'intero pacchetto di inserimento. L'unico aspetto positivo che fai è che le persone dovrebbero capire cosa fa realmente il loro codice. Giovane cavalletta, il campionamento stratificato non è sempre l'approccio migliore. Ad esempio, dà maggiore importanza ai sottogruppi con più dati che non sono sempre desiderabili. (Esp se non sai che sta succedendo). Si tratta di utilizzare l'approccio migliore per i tuoi dati. Troll con cautela amico mio :)
Jake Drew l'

@JakeDrew Mi rendo conto che questo è un vecchio post ora, ma sarebbe possibile chiedere alcune indicazioni su come utilizzare i dati di test e di training per ottenere l'errore medio medio di un modello VAR (p) per ogni iterazione?
tu sei il


@JakeDrew imho entrambe le risposte meritano un plus 1. Uno con un pacchetto, l'altro con codice ...
natbusa

2

Probabilmente non è il modo migliore, ma ecco un modo per farlo. Sono abbastanza sicuro quando ho scritto questo codice che avevo preso in prestito un trucco da un'altra risposta qui, ma non riuscivo a trovarlo a cui collegarmi.

# 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

1

Di seguito troverai alcuni altri codici che utilizzo (presi in prestito e adattati da un'altra fonte). L'ho copiato direttamente da una sceneggiatura che ho appena usato, lasciato nella routine di rpart. La parte probabilmente più interessante sono le linee sulla creazione delle pieghe. In alternativa, è possibile utilizzare la funzione crossval dal pacchetto bootstrap.

#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

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

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

Tutto fatto per te in una riga di codice!

?cv.lm for information on input and output

0

Poiché non ho adottato il mio approccio in questo elenco, ho pensato di poter condividere un'altra opzione per le persone che non hanno voglia di installare pacchetti per una rapida convalida incrociata

# 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
}

Si noti che il codice sopra presuppone che i dati siano già mescolati. Se così non fosse, potresti considerare di aggiungere qualcosa di simile

folds <- sample(folds, nrow(data))
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.