Cómo dividir un conjunto de datos para hacer una validación cruzada 10 veces

14

Ahora que tengo un Rmarco de datos (capacitación), ¿alguien puede decirme cómo dividir aleatoriamente este conjunto de datos para hacer una validación cruzada 10 veces?

user22062
fuente
2
Asegúrese de repetir todo el proceso 100 veces para lograr una precisión satisfactoria.
Frank Harrell
Asegúrese de muestrear el caso y la muestra de control por separado y luego combinarlos en cada bloque.
Shicheng Guo
Si usa caret :: train, ni siquiera necesita preocuparse por esto. Se hará internamente, puede elegir la cantidad de pliegues. Si insiste en hacer esto "a mano", use un muestreo estratificado de la clase tal como se implementa en caret :: createFolds.
marbel
He bloqueado este hilo porque cada una de las muchas respuestas lo trata solo como una pregunta de codificación en lugar de una de interés estadístico general.
whuber

Respuestas:

22

caret tiene una función para esto:

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

Entonces cada elemento de fldses una lista de índices para cada conjunto de datos. Si se llama a su conjunto de datos dat, dat[flds$train,]obtiene el conjunto de entrenamiento, dat[ flds[[2]], ]el segundo conjunto de plegado, etc.

Ari B. Friedman
fuente
12

Aquí hay una manera simple de realizar 10 veces sin paquetes:

#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
fuente
-1: las funciones de caret hacen un muestreo estratificado que no estás haciendo. ¿Cuál es el punto de reinventar el weel si alguien ha hecho las cosas más simples para ti?
marbel
10
¿Estás bromeando? El propósito completo de la respuesta es realizar 10 veces sin tener que instalar el paquete completo de caret. El único punto bueno que haces es que las personas deben entender lo que su código realmente hace. Saltamontes jóvenes, el muestreo estratificado no siempre es el mejor enfoque. Por ejemplo, da más importancia a los subgrupos con más datos que no siempre es deseable. (Esp si no sabes que está sucediendo). Se trata de utilizar el mejor enfoque para sus datos. Troll con precaución mi amigo :)
Jake Drew
@JakeDrew Me doy cuenta de que esta es una publicación antigua ahora, pero ¿sería posible pedir alguna guía sobre cómo usar los datos de prueba y entrenamiento para obtener el error promedio promedio de un modelo VAR (p) para cada iteración?
usted acaba de leer este
@JakeDrew imho ambas respuestas merecen un plus 1. Una con un paquete, la otra con el código ...
natbusa
2

Probablemente no sea la mejor manera, pero aquí hay una forma de hacerlo. Estoy bastante seguro de que cuando escribí este código, tomé prestado un truco de otra respuesta aquí, pero no pude encontrar el enlace.

# 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
fuente
1

a continuación encontrará otro código que uso (prestado y adaptado de otra fuente). Lo copié directamente de un guión que acabo de usar yo mismo, dejado en la rutina rpart. La parte probablemente más interesante son las líneas sobre la creación de los pliegues. Alternativamente, puede usar la función de cruce del paquete 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
Wouter
fuente
1
# Evaluate models uses k-fold cross-validation
install.packages("DAAG")
library("DAAG")

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

¡Todo hecho por ti en una sola línea de código!

?cv.lm for information on input and output
usuario1930111
fuente
0

Como no incluí mi enfoque en esta lista, pensé que podría compartir otra opción para las personas que no tienen ganas de instalar paquetes para una validación cruzada rápida

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

Tenga en cuenta que el código anterior supone que los datos ya están barajados. Si este no fuera el caso, podría considerar agregar algo como

folds <- sample(folds, nrow(data))
Mr Tsjolder
fuente