Comment diviser un ensemble de données pour effectuer une validation croisée 10 fois

14

Maintenant que j'ai une Rtrame de données (formation), quelqu'un peut-il me dire comment diviser au hasard cet ensemble de données pour effectuer une validation croisée 10 fois?

user22062
la source
2
Assurez-vous de répéter le processus entier 100 fois pour obtenir une précision satisfaisante.
Frank Harrell
Veillez à échantillonner le cas et à contrôler l'échantillon séparément, puis à les combiner à chaque bloc.
Shicheng Guo
Si vous utilisez caret :: train, vous n'avez même pas besoin de vous en soucier. Cela se fera en interne, vous pouvez choisir le nombre de plis. Si vous insistez pour le faire "à la main", utilisez un échantillonnage stratifié de la classe tel qu'implémenté dans caret :: createFolds.
marbel
J'ai verrouillé ce fil parce que chacune des nombreuses réponses le traite uniquement comme une question de codage plutôt que comme un intérêt statistique général.
whuber

Réponses:

22

caret a une fonction pour cela:

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

Ensuite, chaque élément de fldsest une liste d'index pour chaque ensemble de données. Si votre jeu de données est appelé dat, dat[flds$train,]vous obtenez le jeu d'entraînement, dat[ flds[[2]], ]vous obtenez le deuxième jeu de plis, etc.

Ari B. Friedman
la source
12

Voici un moyen simple d'effectuer 10 fois sans utiliser de packages:

#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
la source
-1: les fonctions de curseur font un échantillonnage stratifié que vous ne faites pas. Quel est l'intérêt de réinventer le weel si quelqu'un vous a simplifié les choses?
marbel
10
Est-ce que vous plaisantez? Le but de la réponse est de réaliser 10 fois sans avoir à installer l'ensemble complet du curseur. Le seul bon point que vous faites est que les gens devraient comprendre ce que fait réellement leur code. L'échantillonnage stratifié de jeunes sauterelles n'est pas toujours la meilleure approche. Par exemple, il donne plus d'importance aux sous-groupes avec plus de données, ce qui n'est pas toujours souhaitable. (Surtout si vous ne savez pas que cela se produit). Il s'agit d'utiliser la meilleure approche pour vos données. Troll avec prudence mon ami :)
Jake Drew
@JakeDrew Je me rends compte que c'est un ancien article maintenant, mais serait-il possible de demander des conseils sur la façon d'utiliser les données de test et de formation pour obtenir l'erreur moyenne moyenne d'un modèle VAR (p) pour chaque itération?
youjustreadthis
@JakeDrew à mon humble avis, les deux réponses méritent un plus 1. L'une avec un package, l'autre avec le code ...
natbusa
2

Probablement pas la meilleure façon, mais voici une façon de le faire. Je suis presque sûr que lorsque j'ai écrit ce code, j'avais emprunté une astuce à une autre réponse ici, mais je n'ai pas trouvé de lien.

# 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
la source
1

veuillez trouver ci-dessous un autre code que j'utilise (emprunté et adapté d'une autre source). Copié directement à partir d'un script que je viens d'utiliser moi-même, laissé dans la routine rpart. La partie probablement la plus intéressante est les lignes sur la création des plis. Alternativement - vous pouvez utiliser la fonction crossval du package 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
la source
1
# Evaluate models uses k-fold cross-validation
install.packages("DAAG")
library("DAAG")

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

Tout est fait pour vous en une seule ligne de code!

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

Parce que je n'ai pas mon approche dans cette liste, j'ai pensé que je pourrais partager une autre option pour les personnes qui n'ont pas envie d'installer des packages pour une validation croisée rapide

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

Notez que le code ci-dessus suppose que les données sont déjà mélangées. Si ce n'était pas le cas, vous pourriez envisager d'ajouter quelque chose comme

folds <- sample(folds, nrow(data))
M. Tsjolder
la source