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?
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?
Risposte:
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.
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...
}
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
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
# 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
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))