Jak podzielić zestaw danych, aby wykonać 10-krotną weryfikację krzyżową

14

Teraz mam Rramkę danych (szkolenie). Czy ktoś może mi powiedzieć, jak losowo podzielić ten zestaw danych, aby wykonać 10-krotną weryfikację krzyżową?

użytkownik22062
źródło
2
Powtórz cały proces 100 razy, aby osiągnąć zadowalającą precyzję.
Frank Harrell,
Pamiętaj, aby pobrać próbkę i kontrolować próbkę osobno, a następnie połączyć je z każdym blokiem.
Shicheng Guo
Jeśli używasz caret :: train, nawet nie musisz się tym przejmować. Odbędzie się to wewnętrznie, możesz wybrać liczbę fałd. Jeśli nalegasz na wykonanie tego „ręcznie”, użyj warstwowego próbkowania klasy zaimplementowanego w caret :: createFolds.
marbel
Zamknąłem ten wątek, ponieważ każda z wielu odpowiedzi traktuje go jako pytanie kodujące, a nie ogólne.
whuber

Odpowiedzi:

22

caret ma do tego funkcję:

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

Następnie każdy element fldsjest listą indeksów dla każdego zestawu danych. Jeśli Twój zestaw danych zostanie wywołany dat, dat[flds$train,]otrzymasz zestaw treningowy, zestaw dat[ flds[[2]], ]drugiego pasowania itp.

Ari B. Friedman
źródło
12

Oto prosty sposób na wykonanie 10-krotności bez użycia pakietów:

#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
źródło
-1: funkcje karetki wykonują próbkowanie warstwowe, którego nie wykonujesz. Jaki jest sens odkrywania na nowo koła, jeśli ktoś uprościł Ci sprawę?
marbel
10
Żartujesz? Całkowitym celem odpowiedzi jest wykonanie 10-krotności bez konieczności instalowania całego pakietu Caret. Jedyną dobrą rzeczą jest to, że ludzie powinni zrozumieć, co faktycznie robi ich kod. Młody konik polny, próbkowanie warstwowe nie zawsze jest najlepszym podejściem. Na przykład przywiązuje większą wagę do podgrup z większą ilością danych, co nie zawsze jest pożądane. (Zwłaszcza jeśli nie wiesz, że to się dzieje). Chodzi o stosowanie najlepszego podejścia do danych. Ostrożnie trolluj mój przyjaciel :)
Jake Drew,
@JakeDrew Zdaję sobie sprawę, że jest to stary post, ale czy można poprosić o wskazówki, jak korzystać z danych testowych i szkoleniowych, aby uzyskać średni średni błąd modelu VAR (p) dla każdej iteracji?
Właśnie to przeczytałeś
@JakeDrew imho obie odpowiedzi zasługują na plus 1. Jedna z
paczką
2

Prawdopodobnie nie najlepszy sposób, ale tutaj jest jeden sposób, aby to zrobić. Jestem prawie pewien, że kiedy napisałem ten kod, pożyczyłem sztuczkę z innej odpowiedzi tutaj, ale nie mogłem znaleźć linku.

# 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.
źródło
1

poniżej znajdziesz inny kod, którego używam (pożyczony i przystosowany z innego źródła). Skopiowałem go prosto ze skryptu, którego sam używałem, pozostawionego w procedurze rpart. Częścią, która prawdopodobnie najbardziej interesuje, są linie tworzenia zagięć. Alternatywnie - możesz użyć funkcji crossval z pakietu 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
źródło
1
# Evaluate models uses k-fold cross-validation
install.packages("DAAG")
library("DAAG")

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

Wszystko zrobione dla Ciebie w jednym wierszu kodu!

?cv.lm for information on input and output
użytkownik1930111
źródło
0

Ponieważ nie podjąłem takiego podejścia na tej liście, pomyślałem, że mogę udostępnić inną opcję osobom, które nie chcą instalować pakietów w celu szybkiej weryfikacji krzyżowej

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

Zauważ, że powyższy kod zakłada, że ​​dane są już tasowane. Jeśli tak nie jest, możesz rozważyć dodanie czegoś takiego

folds <- sample(folds, nrow(data))
Pan Tsjolder
źródło