नमूना फ़ंक्शन का उपयोग करके डेटा को प्रशिक्षण / परीक्षण सेट में कैसे विभाजित किया जाए


160

मैंने अभी R का उपयोग करना शुरू किया है और मुझे यकीन नहीं है कि निम्नलिखित नमूने कोड के साथ अपने डेटासेट को कैसे शामिल किया जाए:

sample(x, size, replace = FALSE, prob = NULL)

मेरे पास एक डेटासेट है जिसे मुझे प्रशिक्षण (75%) और परीक्षण (25%) सेट करने की आवश्यकता है। मुझे यकीन नहीं है कि मुझे x और आकार में कौन सी जानकारी चाहिए? क्या डेटासेट फ़ाइल x है, और मेरे पास कितने नमूने हैं?


1
xआपके सूचकांक (पंक्ति / कॉल नं। कहते हैं) हो सकता है datasizeहो सकता है 0.75*nrow(data)sample(1:10, 4, replace = FALSE, prob = NULL)यह देखने की कोशिश करो कि यह क्या करता है।
harkmug

जवाबों:


255

डेटा विभाजन प्राप्त करने के लिए कई दृष्टिकोण हैं। अधिक संपूर्ण दृष्टिकोण के createDataPartitionलिए caToolsपैकेज में फ़ंक्शन पर एक नज़र डालें ।

ये रहा एक सरल उदाहरण:

data(mtcars)

## 75% of the sample size
smp_size <- floor(0.75 * nrow(mtcars))

## set the seed to make your partition reproducible
set.seed(123)
train_ind <- sample(seq_len(nrow(mtcars)), size = smp_size)

train <- mtcars[train_ind, ]
test <- mtcars[-train_ind, ]

मैं थोड़ा उलझन में हूँ कि इस कोड ने एक अनोखी परीक्षा और ट्रेन df की क्या गारंटी दी है? यह काम करने लगता है, मुझे गलत मत समझो। बस यह समझने में परेशानी हो रही है कि सूचकांकों को कैसे घटाया जाए, यह अद्वितीय टिप्पणियों की ओर जाता है। उदाहरण के लिए, यदि आपके पास 10 पंक्तियों और एक कॉलम के साथ df था, और एक कॉलम में 1,2,3,4,5,6,7,8,9,10 और आप इस कोड का पालन करते हैं, तो ट्रेन को रोकने से क्या होता है सूचकांक 4 और परीक्षण होने -6 -> 10 - 6 = 4 भी?
सोना

1
धन्यवाद देता हूं। मैंने कोशिश की mtcars[!train_ind]और जब तक यह विफल नहीं हुआ, यह उम्मीद के मुताबिक काम नहीं किया। मैं कैसे का उपयोग कर सकता है !?
user989762

@ user989762 !का उपयोग तार्किक ( TRUE/FALSE) के लिए किया जाता है न कि सूचकांकों के लिए। यदि आप उपयोग को कम करना चाहते हैं !, तो mtcars [ !seq_len(nrow(mtcars)) %in% train_ind,] (परीक्षण नहीं किया गया) जैसी कुछ कोशिश करें ।
डिकॉआ

1
@VedaadShakib जब आप उपयोग करते हैं "-" यह आपके डेटा से train_ind में सभी सूचकांक को छोड़ देता है। Adv-r.had.co.nz/Subsetting.html पर एक नज़र डालें । आशा है कि यह मदद करता है
डिकोआ

1
ना createDataPartitionमें caretऔर नहीं caTools?
जे। मिनी

93

यह आसानी से किया जा सकता है:

set.seed(101) # Set Seed so that same sample can be reproduced in future also
# Now Selecting 75% of data as sample from total 'n' rows of the data  
sample <- sample.int(n = nrow(data), size = floor(.75*nrow(data)), replace = F)
train <- data[sample, ]
test  <- data[-sample, ]

CaTools पैकेज का उपयोग करके :

require(caTools)
set.seed(101) 
sample = sample.split(data$anycolumn, SplitRatio = .75)
train = subset(data, sample == TRUE)
test  = subset(data, sample == FALSE)

4
मैंने हाल ही में MIT के साथ एक कोर्स किया था और उन्होंने caTools का उपयोग करके दृष्टिकोण का उपयोग किया। धन्यवाद
चेतन शर्मा

1
sample = sample.split(data[,1], SplitRatio = .75)एक कॉलम नाम रखने की आवश्यकता को दूर करना चाहिए।
बेंजामिन जिपर

33

मैं इसके लिए उपयोग करूंगा dplyr, यह सुपर सरल बनाता है। यह आपके डेटा सेट में एक आईडी चर की आवश्यकता होती है, जो किसी भी तरह से एक अच्छा विचार है, न केवल सेट बनाने के लिए बल्कि इस परियोजना के दौरान पता लगाने की क्षमता के लिए भी। यदि पहले से ही शामिल नहीं है, तो इसे जोड़ें।

mtcars$id <- 1:nrow(mtcars)
train <- mtcars %>% dplyr::sample_frac(.75)
test  <- dplyr::anti_join(mtcars, train, by = 'id')

28

यह लगभग समान कोड है, लेकिन अधिक अच्छे लुक में है

bound <- floor((nrow(df)/4)*3)         #define % of training and test set

df <- df[sample(nrow(df)), ]           #sample rows 
df.train <- df[1:bound, ]              #get training set
df.test <- df[(bound+1):nrow(df), ]    #get test set

हाँ! अच्छी लग रही है!
मीनाक्षीसुंदरम

23
library(caret)
intrain<-createDataPartition(y=sub_train$classe,p=0.7,list=FALSE)
training<-m_train[intrain,]
testing<-m_train[-intrain,]

3
जबकि एक कोड-केवल उत्तर एक उत्तर है, कुछ स्पष्टीकरण प्रदान करना बेहतर है।
C8H10N4O2

m_train क्या है? मुझे लगता है कि आपका मतलब था, मूल data.frame को sub_train करें। इसलिए, संशोधित कोड प्रशिक्षण होना चाहिए <-sub_train [intrain], और परीक्षण <-sub_train [-intrain,]। मुझे आश्चर्य है कि पिछले पांच वर्षों में कोई भी आपके साथ इस प्रमुख समस्या का जवाब देने में सक्षम नहीं था!
mnm

21

मैं 'a' को ट्रेन (70%) और परीक्षण (30%) में विभाजित करूँगा

    a # original data frame
    library(dplyr)
    train<-sample_frac(a, 0.7)
    sid<-as.numeric(rownames(train)) # because rownames() returns character
    test<-a[-sid,]

किया हुआ


4
आपको dpyr पैकेज आयात करने की आवश्यकता है, (dplyr)
TheMI

इस उत्तर ने मेरी मदद की लेकिन अपेक्षित परिणाम प्राप्त करने के लिए मुझे इसे मोड़ने की आवश्यकता थी। जैसा कि, डेटासेट 'ट्रेन' में पंक्तिबद्ध नाम = अनुक्रमिक पूर्णांकों का किनारा है: 1,2,3,4, ... जबकि आप मूल डेटासेट से पंक्तिबद्ध होना चाहते हैं ',', क्योंकि वे यादृच्छिक रूप से चुने गए हैं अनुक्रमिक पूर्णांक नहीं हो। इसलिए, पहले 'a' पर id वैरिएबल बनाना आवश्यक है।
स्कॉट मूर

row.names (mtcars) <- NULL; ट्रेन <-डुप्लर :: नमूना_फ्रेक (एमटीकेआर, 0.5); परीक्षण <-mtcars [-as.numeric (row.names (ट्रेन)),] # मैंने अपने डेटा के लिए ऐसा किया, मूल कोड काम नहीं करता है यदि आपकी पंक्ति के नाम पहले से ही संख्याओं पर सेट हैं
क्रिस्टोफर जॉन

16

मेरा समाधान मूल रूप से डिकोआ के समान है लेकिन व्याख्या करने में थोड़ा आसान है:

data(mtcars)
n = nrow(mtcars)
trainIndex = sample(1:n, size = round(0.7*n), replace=FALSE)
train = mtcars[trainIndex ,]
test = mtcars[-trainIndex ,]

परिवर्तनशील स्विस क्या है?
15

7

बस एक और अधिक संक्षिप्त और सरल तरीका है dplyr पुस्तकालय का उपयोग कर :

library(dplyr)
set.seed(275) #to get repeatable data

data.train <- sample_frac(Default, 0.7)

train_index <- as.numeric(rownames(data.train))
data.test <- Default[-train_index, ]

1
क्या आपका मतलब Default[-train_index,]अंतिम पंक्ति के लिए उपयोग करना था।
मैट एल।

5

यदि आप टाइप करते हैं:

?sample

यदि नमूना फ़ंक्शन के मापदंडों का मतलब समझाने के लिए एक सहायता मेनू लॉन्च करेगा।

मैं एक विशेषज्ञ नहीं हूं, लेकिन यहां मेरे पास कुछ कोड हैं:

data <- data.frame(matrix(rnorm(400), nrow=100))
splitdata <- split(data[1:nrow(data),],sample(rep(1:4,as.integer(nrow(data)/4))))
test <- splitdata[[1]]
train <- rbind(splitdata[[1]],splitdata[[2]],splitdata[[3]])

यह आपको 75% ट्रेन और 25% टेस्ट देगा।


5

यहां पोस्ट की गई सभी विभिन्न विधियों को देखने के बाद, मुझे TRUE/FALSEडेटा का चयन करने और अचयनित करने के लिए किसी का उपयोग नहीं दिखाई दिया । इसलिए मैंने सोचा कि मैं उस तकनीक का उपयोग करने वाला एक तरीका साझा करूंगा।

n = nrow(dataset)
split = sample(c(TRUE, FALSE), n, replace=TRUE, prob=c(0.75, 0.25))

training = dataset[split, ]
testing = dataset[!split, ]

व्याख्या

आर से डेटा का चयन करने के कई तरीके हैं, आमतौर पर लोग क्रमशः चयन / अचयनित करने के लिए सकारात्मक / नकारात्मक सूचकांकों का उपयोग करते हैं। हालांकि, एक ही कार्यक्षमता का उपयोग करके प्राप्त किया जा सकता हैTRUE/FALSE चुनिंदा / अचयनित ।

निम्नलिखित उदाहरण पर विचार करें।

# let's explore ways to select every other element
data = c(1, 2, 3, 4, 5)


# using positive indices to select wanted elements
data[c(1, 3, 5)]
[1] 1 3 5

# using negative indices to remove unwanted elements
data[c(-2, -4)]
[1] 1 3 5

# using booleans to select wanted elements
data[c(TRUE, FALSE, TRUE, FALSE, TRUE)]
[1] 1 3 5

# R recycles the TRUE/FALSE vector if it is not the correct dimension
data[c(TRUE, FALSE)]
[1] 1 3 5

4

मेरा समाधान पंक्तियों को फेर देता है, फिर पहले 75% पंक्तियों को ट्रेन के रूप में और अंतिम 25% को परीक्षण के रूप में लेता है। सुपर सिंपल!

row_count <- nrow(orders_pivotted)
shuffled_rows <- sample(row_count)
train <- orders_pivotted[head(shuffled_rows,floor(row_count*0.75)),]
test <- orders_pivotted[tail(shuffled_rows,floor(row_count*0.25)),]

4

मैं rsample पैकेज का उपयोग करने का सुझाव दे सकता हूं:

# choosing 75% of the data to be the training data
data_split <- initial_split(data, prop = .75)
# extracting training data and test data as two seperate dataframes
data_train <- training(data_split)
data_test  <- testing(data_split)

3

scorecard पैकेज में उसके लिए एक उपयोगी कार्य है, जहां आप अनुपात और बीज निर्दिष्ट कर सकते हैं

library(scorecard)

dt_list <- split_df(mtcars, ratio = 0.75, seed = 66)

परीक्षण और ट्रेन डेटा को एक सूची में संग्रहीत किया जाता है और इसे कॉल करके dt_list$trainऔर एक्सेस किया जा सकता हैdt_list$test


2

एक फ़ंक्शन के नीचे एक listही आकार के उप-नमूने बनाते हैं जो वास्तव में वही नहीं है जो आप चाहते थे लेकिन दूसरों के लिए उपयोगी साबित हो सकते हैं। ओवरफिटिंग का परीक्षण करने के लिए छोटे नमूनों पर कई वर्गीकरण पेड़ बनाने के लिए मेरे मामले में:

df_split <- function (df, number){
  sizedf      <- length(df[,1])
  bound       <- sizedf/number
  list        <- list() 
  for (i in 1:number){
    list[i] <- list(df[((i*bound+1)-bound):(i*bound),])
  }
  return(list)
}

उदाहरण :

x <- matrix(c(1:10), ncol=1)
x
# [,1]
# [1,]    1
# [2,]    2
# [3,]    3
# [4,]    4
# [5,]    5
# [6,]    6
# [7,]    7
# [8,]    8
# [9,]    9
#[10,]   10

x.split <- df_split(x,5)
x.split
# [[1]]
# [1] 1 2

# [[2]]
# [1] 3 4

# [[3]]
# [1] 5 6

# [[4]]
# [1] 7 8

# [[5]]
# [1] 9 10

2

R नमूना कोड में caTools पैकेज का उपयोग इस प्रकार होगा: -

data
split = sample.split(data$DependentcoloumnName, SplitRatio = 0.6)
training_set = subset(data, split == TRUE)
test_set = subset(data, split == FALSE)

2

बेस आर का उपयोग करें। फ़ंक्शन runifसमान रूप से वितरित मानों को 0 से 1. तक अलग-अलग कटऑफ मान उत्पन्न करता है (ट्रेन नीचे उदाहरण में देखें), आपके पास हमेशा कटऑफ मूल्य के नीचे यादृच्छिक रिकॉर्ड का लगभग समान प्रतिशत होगा।

data(mtcars)
set.seed(123)

#desired proportion of records in training set
train.size<-.7
#true/false vector of values above/below the cutoff above
train.ind<-runif(nrow(mtcars))<train.size

#train
train.df<-mtcars[train.ind,]


#test
test.df<-mtcars[!train.ind,]

यह एक बेहतर जवाब होगा यदि यह अतिरिक्त युगल लाइनों को वास्तव में प्रशिक्षण और परीक्षण सेट बनाने के लिए दिखाता है (जो कि अक्सर नए संघर्ष के साथ संघर्ष करते हैं)।
ग्रिगोर थॉमस

2

मान लें कि df आपका डेटा फ्रेम है, और आप 75% ट्रेन और 25% टेस्ट बनाना चाहते हैं

all <- 1:nrow(df)
train_i <- sort(sample(all, round(nrow(df)*0.75,digits = 0),replace=FALSE))
test_i <- all[-train_i]

फिर एक ट्रेन बनाने और डेटा फ़्रेम का परीक्षण करने के लिए

df_train <- df[train_i,]
df_test <- df[test_i,]

1
require(caTools)

set.seed(101)            #This is used to create same samples everytime

split1=sample.split(data$anycol,SplitRatio=2/3)

train=subset(data,split1==TRUE)

test=subset(data,split1==FALSE)

sample.split()समारोह dataframe करने के लिए एक अतिरिक्त स्तंभ 'Split1' जोड़ देगा और पंक्तियों के 2/3 FALSE.Now के रूप में सही रूप में इस मूल्य और दूसरों पंक्तियों जहां Split1 सही है ट्रेन में कॉपी किया जायेगा और अन्य पंक्तियों परीक्षण में कॉपी किया जायेगा होगा डेटा ढांचा।


1

मैं इस एक में टकरा गया, यह भी मदद कर सकता है।

set.seed(12)
data = Sonar[sample(nrow(Sonar)),]#reshufles the data
bound = floor(0.7 * nrow(data))
df_train = data[1:bound,]
df_test = data[(bound+1):nrow(data),]

1

हम डेटा को एक विशेष अनुपात में विभाजित कर सकते हैं, यह 80% ट्रेन और 20% परीक्षण डेटासेट में है।

ind <- sample(2, nrow(dataName), replace = T, prob = c(0.8,0.2))
train <- dataName[ind==1, ]
test <- dataName[ind==2, ]

0

sampleयदि आप प्रजनन योग्य परिणामों की तलाश करते हैं तो विभाजन के लिए सावधान रहें । यदि आपका डेटा थोड़ा सा भी बदलता है, तो आपके द्वारा उपयोग किए जाने पर भी विभाजन अलग-अलग होगा set.seed। उदाहरण के लिए, आपके द्वारा डेटा में आईडी की क्रमबद्ध सूची की कल्पना करें 1 और 10 के बीच की सभी संख्याएं हैं। यदि आप सिर्फ एक अवलोकन छोड़ देते हैं, तो 4 का कहना है कि स्थान के अनुसार नमूना लेने से अलग परिणाम प्राप्त होंगे क्योंकि अब 5 से 10 सभी स्थानांतरित स्थान हैं।

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

उदाहरण के लिए:

require(openssl)  # for md5
require(data.table)  # for the demo data

set.seed(1)  # this won't help `sample`

population <- as.character(1e5:(1e6-1))  # some made up ID names

N <- 1e4  # sample size

sample1 <- data.table(id = sort(sample(population, N)))  # randomly sample N ids
sample2 <- sample1[-sample(N, 1)]  # randomly drop one observation from sample1

# samples are all but identical
sample1
sample2
nrow(merge(sample1, sample2))

[१] ९९९९

# row splitting yields very different test sets, even though we've set the seed
test <- sample(N-1, N/2, replace = F)

test1 <- sample1[test, .(id)]
test2 <- sample2[test, .(id)]
nrow(test1)

[१] ५०००

nrow(merge(test1, test2))

[१] २६५३

# to fix that, we can use some hash function to sample on the last digit

md5_bit_mod <- function(x, m = 2L) {
  # Inputs: 
  #  x: a character vector of ids
  #  m: the modulo divisor (modify for split proportions other than 50:50)
  # Output: remainders from dividing the first digit of the md5 hash of x by m
  as.integer(as.hexmode(substr(openssl::md5(x), 1, 1)) %% m)
}

# hash splitting preserves the similarity, because the assignment of test/train 
# is determined by the hash of each obs., and not by its relative location in the data
# which may change 
test1a <- sample1[md5_bit_mod(id) == 0L, .(id)]
test2a <- sample2[md5_bit_mod(id) == 0L, .(id)]
nrow(merge(test1a, test2a))

[१] ५०५57

nrow(test1a)

[१] ५०५57

नमूना आकार बिल्कुल 5000 नहीं है क्योंकि असाइनमेंट संभावित है, लेकिन बड़ी संख्या के कानून के लिए धन्यवाद बड़े नमूनों में यह समस्या नहीं होनी चाहिए।

इसे भी देखें: http://blog.richardweiss.org/2016/12/25/hash-splits.html और /crypto/20742/statutic-properties-of-hash-fitions-when -calculating-सापेक्ष


एक अलग प्रश्न के रूप में जोड़ा गया: stackoverflow.com/questions/52769681/…
dzeltzer

मैं कई समय श्रृंखला डेटा से auto.arima मॉडल विकसित करना चाहता हूं और मैं मॉडल बनाने के लिए प्रत्येक परीक्षण से प्रत्येक श्रृंखला में 1 वर्ष का डेटा, 3 वर्ष का डेटा, 5, 7 ... का उपयोग करना चाहता हूं और इसमें परीक्षण कर रहा हूं शेष परीक्षण सेट। मैं सब्मिट कैसे करूं ताकि फिट किए गए मॉडल में वही हो जो मुझे चाहिए? मैं आपकी मदद के लिए सराहना करता हूं
स्टैक्यूसर


-2

पंक्तियों और स्तंभों के लिए R सूचकांक का उपयोग करके कई पंक्तियों का चयन करने का एक बहुत ही सरल तरीका है। इससे आप कई पंक्तियों को दिए गए डेटा सेट को स्पष्ट रूप से विभाजित कर सकते हैं - अपने डेटा का पहला 80% कहें।

R में सभी पंक्तियों और स्तंभों को अनुक्रमित किया जाता है इसलिए DataSetName [1,1] "DataSetName" की पहली पंक्ति और पहली पंक्ति को निर्दिष्ट मान है। मैं [x,] और कॉलम का उपयोग करके पंक्तियों का चयन कर सकता हूं [, x]

उदाहरण के लिए: यदि मेरे पास 100 पंक्तियों के साथ "डेटा" नाम का डेटा सेट है तो मैं पहली 80 पंक्तियों का उपयोग करके देख सकता हूं

देखें (डेटा [1:80,])

उसी तरह मैं इन पंक्तियों का चयन कर सकता हूं और उनका उपयोग कर उन्हें उपकृत कर सकता हूं:

ट्रेन = डेटा [1:80]

परीक्षण = डेटा [81: 100]

अब मेरे पास मेरे डेटा को दो भागों में विभाजित किया जा सकता है बिना पुनरुत्पादन की संभावना के। जल्द और आसान।


1
यह सच है कि डेटा को इस तरह विभाजित किया जा सकता है, यह सलाह नहीं दी गई है। कुछ डेटासेट एक वैरिएबल द्वारा ऑर्डर किए जाते हैं जिनके बारे में आपको जानकारी नहीं है। इसलिए इसका सबसे अच्छा नमूना है कि पहली n पंक्तियों को लेने के बजाय कौन सी पंक्तियों को प्रशिक्षण माना जाएगा।
user5029763

1
यदि आप परीक्षण और प्रशिक्षण सेट के लिए उन्हें अलग करने से पहले डेटा में फेरबदल करते हैं, तो आपका सुझाव काम करता है।
हदीज
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.