2011-09-13 16 views
13

आर -5-क्रॉस-सत्यापन के लिए आर का उपयोग करके स्वचालित रूप से एक मैट्रिक्स कैसे विभाजित करें? मैं वास्तव में 5 test (test_matrix_indices, ट्रेन matrix_indices) उत्पन्न करना चाहता हूं।क्रॉस-सत्यापन के लिए सेट जेनरेट करें

+0

कृपया अपने प्रश्न में उत्तर मिश्रण न करें। यह भ्रमित हो जाता है। यदि आप अपने प्रश्न का उत्तर देना चाहते हैं, तो कृपया एक नए उत्तर में ऐसा करें। – Andrie

+0

के गुना क्रॉस-सत्यापन के लिए आपको के-1 सबसेट को प्रशिक्षण सेट के रूप में विलय करना होगा और एक को परीक्षण के रूप में छोड़ना होगा (इसे के बार दोहराएं), इसलिए यह आपकी समस्या का पूरा समाधान नहीं है। –

+0

मैंने अपना उत्तर उत्तर अनुभाग में डाल दिया है। विभाजन के लिए – Delphine

उत्तर

15
f_K_fold <- function(Nobs,K=5){ 
    rs <- runif(Nobs) 
    id <- seq(Nobs)[order(rs)] 
    k <- as.integer(Nobs*seq(1,K-1)/K) 
    k <- matrix(c(0,rep(k,each=2),Nobs),ncol=2,byrow=TRUE) 
    k[,1] <- k[,1]+1 
    l <- lapply(seq.int(K),function(x,k,d) 
       list(train=d[!(seq(d) %in% seq(k[x,1],k[x,2]))], 
        test=d[seq(k[x,1],k[x,2])]),k=k,d=id) 
    return(l) 
} 
+0

यह एक सुरुचिपूर्ण समाधान है। धन्यवाद। – Delphine

+0

इसके अलावा, यह समाधान set.seed (n) – Delphine

+2

जोड़कर निर्धारक बन सकता है क्या आईडी डी? मुझे यह नहीं मिला। – LoveMeow

23

मुझे लगता है कि आप चाहते हैं कि मैट्रिक्स पंक्तियों को विभाजित करने के मामले हों।

X <- matrix(rnorm(1000),ncol=5) 
id <- sample(1:5,nrow(X),replace=TRUE) 
ListX <- split(x,id) # gives you a list with the 5 matrices 
X[id==2,] # gives you the second matrix 

मैं, सूची के साथ काम करेंगे के रूप में यह आप की तरह कुछ करने के लिए अनुमति देता है::,

names(ListX) <- c("Train1","Train2","Train3","Test1","Test2") 
mean(ListX$Train3) 

जो कोड को पढ़ने के लिए आसान है कि के लिए बनाता है और फिर आप सभी की जरूरत sample और split है आपको अपने कार्यक्षेत्र में कई मैट्रिस बनाने से रोकता है। यदि आप अपने वर्कस्पेस में व्यक्तिगत रूप से मैट्रिक्स डालते हैं तो आप गड़बड़ कर सकते हैं। सूचियों का प्रयोग करें!

मामले में आप, परीक्षण मैट्रिक्स छोटे या अन्य लोगों की तुलना में बड़ा होना चाहता हूँ sample की prob तर्क का उपयोग करें:

id <- sample(1:5,nrow(X),replace=TRUE,prob=c(0.15,0.15,0.15,0.15,0.3)) 

आप एक परीक्षण मैट्रिक्स ट्रेन मैट्रिक्स के दोहरे आकार है कि देता है।

यदि आप मामलों की सटीक संख्या निर्धारित करना चाहते हैं, तो sample और prob सर्वोत्तम विकल्प नहीं हैं। आप एक चाल की तरह इस्तेमाल कर सकते हैं:

indices <- rep(1:5,c(100,20,20,20,40)) 
id <- sample(indices) 

क्रमशः 100, 20, ... और 40 मामलों के साथ मैट्रिक्स प्राप्त करने के लिए। विभाजन के बिना

+0

+1 - मैं वास्तव में क्रॉसविलिडेशन के लिए मैट्रिस उत्पन्न करने के बारे में सोच रहा था, और यह सही है। – richiemorrisroe

+0

joris महान कोड धन्यवाद। क्रॉस सत्यापन के साथ विचार नहीं है कि आप सभी सेटों के माध्यम से लूप करते हैं और कम से कम एक बार परीक्षण डेटा के रूप में प्रत्येक समूह का उपयोग करते हैं जो सूची का उपयोग करने और इसे नाम देने के उद्देश्य को हरा देगा? – appleLover

+0

@appleLover सूचियों का उपयोग केवल आपके कार्यक्षेत्र में व्यक्तिगत मैट्रिक्स उत्पन्न करने से बचने के लिए है। यह सब कुछ एक साथ रखना है। सत्यापन और बूटस्ट्रैपिंग पार करने के लिए कई दृष्टिकोण हैं, और दृष्टिकोण के आधार पर आपको अपने आंकड़ों पर विभिन्न सुधारों की आवश्यकता होगी। मैंने बस उन मैट्रिक्स को व्यवस्थित तरीके से बनाने के लिए एक विधि दी है। –

4

समाधान:

set.seed(7402313) 
X <- matrix(rnorm(999), ncol=3) 
k <- 5 # number of folds 

# Generating random indices 
id <- sample(rep(seq_len(k), length.out=nrow(X))) 
table(id) 
# 1 2 3 4 5 
# 67 67 67 66 66 

# lapply over them: 
indicies <- lapply(seq_len(k), function(a) list(
    test_matrix_indices = which(id==a), 
    train_matrix_indices = which(id!=a) 
)) 
str(indicies) 
# List of 5 
# $ :List of 2 
# ..$ test_matrix_indices : int [1:67] 12 13 14 17 18 20 23 28 41 45 ... 
# ..$ train_matrix_indices: int [1:266] 1 2 3 4 5 6 7 8 9 10 ... 
# $ :List of 2 
# ..$ test_matrix_indices : int [1:67] 4 19 31 36 47 53 58 67 83 89 ... 
# ..$ train_matrix_indices: int [1:266] 1 2 3 5 6 7 8 9 10 11 ... 
# $ :List of 2 
# ..$ test_matrix_indices : int [1:67] 5 8 9 30 32 35 37 56 59 60 ... 
# ..$ train_matrix_indices: int [1:266] 1 2 3 4 6 7 10 11 12 13 ... 
# $ :List of 2 
# ..$ test_matrix_indices : int [1:66] 1 2 3 6 21 24 27 29 33 34 ... 
# ..$ train_matrix_indices: int [1:267] 4 5 7 8 9 10 11 12 13 14 ... 
# $ :List of 2 
# ..$ test_matrix_indices : int [1:66] 7 10 11 15 16 22 25 26 40 42 ... 
# ..$ train_matrix_indices: int [1:267] 1 2 3 4 5 6 8 9 12 13 ... 

लेकिन तुम लौट सकते हैं मैट्रिक्स भी:

matrices <- lapply(seq_len(k), function(a) list(
    test_matrix = X[id==a, ], 
    train_matrix = X[id!=a, ] 
)) 
str(matrices) 
List of 5 
# $ :List of 2 
    # ..$ test_matrix : num [1:67, 1:3] -1.0132 -1.3657 -0.3495 0.6664 0.0762 ... 
    # ..$ train_matrix: num [1:266, 1:3] -0.65 0.797 0.689 0.484 0.682 ... 
# $ :List of 2 
    # ..$ test_matrix : num [1:67, 1:3] 0.484 0.418 -0.622 0.996 0.414 ... 
    # ..$ train_matrix: num [1:266, 1:3] -0.65 0.797 0.689 0.682 0.186 ... 
# $ :List of 2 
    # ..$ test_matrix : num [1:67, 1:3] 0.682 0.812 -1.111 -0.467 0.37 ... 
    # ..$ train_matrix: num [1:266, 1:3] -0.65 0.797 0.689 0.484 0.186 ... 
# $ :List of 2 
    # ..$ test_matrix : num [1:66, 1:3] -0.65 0.797 0.689 0.186 -1.398 ... 
    # ..$ train_matrix: num [1:267, 1:3] 0.484 0.682 0.473 0.812 -1.111 ... 
# $ :List of 2 
    # ..$ test_matrix : num [1:66, 1:3] 0.473 0.212 -2.175 -0.746 1.707 ... 
    # ..$ train_matrix: num [1:267, 1:3] -0.65 0.797 0.689 0.484 0.682 ... 

तो फिर तुम lapply का उपयोग परिणाम पाने के लिए कर सकते हैं:

lapply(matrices, function(x) { 
    m <- build_model(x$train_matrix) 
    performance(m, x$test_matrix) 
}) 

संपादित करें: Wojc की तुलना करें iech के समाधान:

f_K_fold <- function(Nobs, K=5){ 
    id <- sample(rep(seq.int(K), length.out=Nobs)) 
    l <- lapply(seq.int(K), function(x) list(
     train = which(x!=id), 
     test = which(x==id) 
    )) 
    return(l) 
} 
0

संपादित करें: अपने जवाब के लिए धन्यवाद। मैं निम्नलिखित समाधान (http://eric.univ-lyon2.fr/~ricco/tanagra/fichiers/fr_Tanagra_Validation_Croisee_Suite.pdf) पाया है:

n <- nrow(mydata) 
K <- 5 
size <- n %/% K 
set.seed(5) 
rdm <- runif(n) 
ranked <- rank(rdm) 
block <- (ranked-1) %/% size+1 
block <- as.factor(block) 

तो मैं का उपयोग करें:

for (k in 1:K) { 
    matrix_train<-matrix[block!=k,] 
    matrix_test<-matrix[block==k,] 
    [Algorithm sequence] 
    } 

प्रत्येक पुनरावृत्तियों के लिए पर्याप्त सेट उत्पन्न करने के लिए।

हालांकि यह समाधान परीक्षण के लिए एक व्यक्ति को छोड़ सकता है। मैं इसकी अनुशंसा नहीं करता हूं।

0

नीचे अलग डेटा बनाने के बिना चाल है। फ्रेम/मैट्रिस, आपको केवल एक पूर्णांक sequnce, id रखना है जो प्रत्येक गुना के लिए शफल इंडेक्स स्टोर करता है।

X <- read.csv('data.csv') 

k = 5 # number of folds 
fold_size <-nrow(X)/k 
indices <- rep(1:k,rep(fold_size,k)) 
id <- sample(indices, replace = FALSE) # random draws without replacement 

log_models <- new.env(hash=T, parent=emptyenv()) 
for (i in 1:k){ 
    train <- X[id != i,] 
    test <- X[id == i,] 
    # run algorithm, e.g. logistic regression 
    log_models[[as.character(i)]] <- glm(outcome~., family="binomial", data=train) 
} 
+0

ध्यान दें कि जब nrow (X) के एकाधिक नहीं है तो कुछ नमूने गिरा दिए जाते हैं। – Samuel

0

sperrorest पैकेज इस क्षमता प्रदान करता है। आप एक यादृच्छिक विभाजन (partition.cv()), एक स्थानिक विभाजन (partition.kmeans()), या कारक स्तर (partition.factor.cv()) के आधार पर विभाजित के बीच चुन सकते हैं। उत्तरार्द्ध वर्तमान में केवल Github संस्करण में उपलब्ध है।

उदाहरण:

library(sperrorest) 
data(ecuador) 

## non-spatial cross-validation: 
resamp <- partition.cv(ecuador, nfold = 5, repetition = 1:1) 

# first repetition, second fold, test set indices: 
idx <- resamp[['1']][[2]]$test 

# test sample used in this particular repetition and fold: 
ecuador[idx , ] 

आप एक स्थानिक डेटा सेट (coords के साथ) है, तो आप भी अपने उत्पन्न परतों

# this may take some time... 
plot(resamp, ecuador) 
कल्पना कर सकते हैं

enter image description here

पार सत्यापन तो हो सकता है sperrorest() (क्रमिक) या parsperrorest() (समांतर) का उपयोग करके प्रदर्शन किया।

संबंधित मुद्दे