Örnek fonksiyonu kullanarak verileri eğitim / test setlerine bölme


160

Ben sadece R kullanmaya başladım ve aşağıdaki örnek kodla veri kümemi nasıl dahil edeceğimi bilmiyorum:

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

Eğitim (% 75) ve test (% 25) setine koymam gereken bir veri setim var. X ve boyutuna hangi bilgileri girmem gerektiğinden emin değilim? Veri kümesi dosyası x ve kaç örnek var boyutu?


1
xdizininiz (satır / sütun no. diyelim) olabilir data. sizeolabilir 0.75*nrow(data). sample(1:10, 4, replace = FALSE, prob = NULL)Ne yaptığını görmeye çalışın .
harkmug

Yanıtlar:


255

Veri bölümlemeye ulaşmak için çok sayıda yaklaşım vardır. Daha eksiksiz bir yaklaşım createDataPartitioniçin caToolspaketteki işleve bir göz atın .

İşte basit bir örnek:

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, ]

Ben biraz bu kod benzersiz bir test ve tren df döndürür garanti karıştı? İşe yarıyor gibi görünüyor, beni yanlış anlamayın. Endeksleri çıkarmanın nasıl eşsiz gözlemlere yol açtığını anlamakta zorluk çekiyorsunuz. Örneğin, 10 satır ve bir sütun içeren bir df'niz varsa ve bir sütun 1,2,3,4,5,6,7,8,9,10 içeriyorsa ve bu kodu izlediyseniz, bir trenin endeks 4 ve -6 -> 10-6 = 4 olan test?
goldisfine

1
teşekkür. Denedim mtcars[!train_ind]ve başarısız olmasa da beklendiği gibi çalışmadı. Kullanarak nasıl alt küme oluşturabilirim !?
user989762

@ user989762 dizinler için değil !, mantıksal ( TRUE/FALSE) için kullanılır . Kullanarak alt kümeye almak istiyorsanız !, mtcars [ !seq_len(nrow(mtcars)) %in% train_ind,] (test edilmedi) gibi bir şey deneyin .
dickoa

1
@VedaadShakib "-" komutunu kullandığınızda, train_ind içindeki tüm dizini verilerinizden çıkarır. Adv-r.had.co.nz/Subsetting.html adresine bir göz atın . Umut etmek o yardım etmek
dickoa

1
Is not createDataPartitioniçinde caretdeğil caTools?
J. Mini

93

Kolayca şu şekilde yapılabilir:

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 paketini kullanarak :

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

4
Son zamanlarda MIT ile bir ders yaptım ve onlar boyunca caTools kullanarak yaklaşımı kullandılar. Teşekkürler
Chetan Sharma

1
sample = sample.split(data[,1], SplitRatio = .75)Bir sütun adlandırma ihtiyacını kaldırmalısınız.
Benjamin Ziepert

33

Bunun için kullanırdım dplyr, süper basitleştirir. Veri kümenizde bir id değişkeni gerektirir, bu da sadece kümeler oluşturmak için değil, aynı zamanda projeniz sırasında izlenebilirlik için de iyi bir fikirdir. Zaten içermiyorsa ekleyin.

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

28

Bu neredeyse aynı kod, ama daha güzel bir görünümde

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

Evet! Güzel görünüm!
MeenakshiSundharam

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

3
Yalnızca kod yanıtı bir yanıt olsa da, bir açıklama yapmak daha iyidir.
C8H10N4O2

m_train nedir? Bence, orijinal veri alt çerçevesini eğitmek. Bu nedenle, revize edilmiş kod <-sub_train [intrain,] eğitimi ve <-sub_train [-intrain] test etmelidir. Son beş yıl içinde neden kimse bu büyük sorunu cevaplayamadı?
mnm

21

'A' yı trene (% 70) ve test edeceğim (% 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,]

tamam


4
dpyr paketini içe aktarmanız gerekiyor, gerekli (dplyr)
TheMI

Bu cevap bana yardımcı oldu ama beklenen sonuçları almak için ince ayar yapmam gerekiyordu. Olduğu gibi, 'tren' veri kümesinin rownames = sıralı tamsayıların sid değeri vardır: 1,2,3,4, ... oysa sid orijinal rastgele 'a' veri kümesinden rownumbers olmasını istiyorsunuz. sıralı tamsayılar değildir. Bu nedenle, önce 'a' üzerinde id değişkeni oluşturmak gerekir.
Scott Murff

row.names (mtcars) <- NULL; tren <-dplyr :: sample_frac (mtcars, 0.5); test <-mtcars [-as.numeric (row.names (tren)),] # Bunu verilerime yaptım, satır adlarınız zaten sayılara ayarlanmışsa orijinal kod çalışmaz
Christopher John

16

Benim çözümüm temel olarak dickoa'nınkiyle aynı ama yorumlaması biraz daha kolay:

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

Değişken İsviçre nedir?
billmccord

7

Müthiş dplyr kütüphanesini kullanarak daha kısa ve basit bir yol :

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,]Son satır için mi kullanmak istediniz?
Matt L.

5

Ben rsample paket kullanmanızı öneririz:

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

5

Eğer yazarsanız:

?sample

Eğer örnek fonksiyon parametrelerinin ne anlama geldiğini açıklamak için bir yardım menüsü açılacaktır.

Ben bir uzman değilim, ama burada bazı kod var:

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]])

Bu size% 75 tren ve% 25 test verecektir.


5

Burada yayınlanan tüm farklı yöntemleri inceledikten sonra, kimsenin TRUE/FALSEveri seçmek ve seçimini kaldırmak için kullandığını görmedim . Ben de bu tekniği kullanarak bir yöntem paylaşacağımı düşündüm.

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

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

açıklama

R'den veri seçmenin birden fazla yolu vardır, çoğu zaman insanlar sırasıyla seçmek / seçimi kaldırmak için pozitif / negatif indeksler kullanır. Bununla birlikte, aynı işlevler TRUE/FALSEseçmek / seçimi kaldırmak için kullanılarak elde edilebilir .

Aşağıdaki örneği ele alalım.

# 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

Çözümüm satırları karıştırıyor, ardından satırların ilk% 75'ini tren, son% 25'ini test olarak alıyor. Süper basitler!

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)),]

3

scorecard paket, oran ve tohumu belirtebileceğiniz yararlı bir işleve sahiptir.

library(scorecard)

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

Test ve tren verileri bir listede saklanır ve çağrı yapılarak dt_list$trainvedt_list$test


2

Tam olarak istediğiniz gibi olmayan ancak başkaları için yararlı olabilecek listaynı boyutta bir alt örnek oluşturan bir fonksiyonun altında . Benim durumumda, fazla takmayı test etmek için daha küçük numunelerde birden fazla sınıflandırma ağacı oluşturmak için:

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

Misal :

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 örnek kodunda caTools paketini kullanın aşağıdaki gibi olacaktır: -

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

2

Taban runifR'yi kullanın. İşlev 0 ile 1 arasında eşit olarak dağıtılmış değerler üretir.

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,]

Bu, eğitim ve test setlerini (yeni başlayanların sıklıkla mücadele ettiği) oluşturmak için fazladan birkaç satır göstermesi durumunda çok daha iyi bir cevap olacaktır.
Gregor Thomas

2

Varsayarsak df veri çerçevesi, ve oluşturmak istediğinizi % 75 tren ve % 25 testi

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

Ardından bir tren oluşturmak ve veri çerçevelerini test etmek

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()Fonksiyon dataframe için ekstra bir sütun 'split1' katacak ve satır 2/3 FALSE.Now olarak bu TRUE olarak değerini ve diğerlerini split1 DOĞRUDUR satırları trende kopyalanacak ve diğer satırlar testine kopyalanacaktır olacak veri çerçevesi.


1

Buna çarptım, bu da yardımcı olabilir.

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

Verileri belirli bir orana bölebiliriz, burada bir test veri kümesinde% 80 tren ve% 20'dir.

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

0

sampleTekrarlanabilir sonuçlar arıyorsanız bölmeye dikkat edin . Verileriniz az da olsa değişirse, bölme,set.seed . Örneğin, verilerinizdeki sıralı kimlikler listesinin 1 ile 10 arasındaki tüm sayılar olduğunu düşünün. 4'e sadece bir gözlem bıraktıysanız, konuma göre örnekleme farklı bir sonuç verir çünkü şimdi 5 ila 10 taşınan tüm yerler.

Alternatif bir yöntem, kimlikleri bazı sahte rasgele sayılara eşlemek ve daha sonra bu sayıların modunu örneklemek için bir hash işlevi kullanmaktır. Bu örnek daha kararlıdır, çünkü ödev şimdi her bir gözlemin karması ile belirlenir, göreceli konumu ile değil.

Örneğin:

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))

[1] 9999

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

[1] 5000

nrow(merge(test1, test2))

[1] 2653

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

[1] 5057

nrow(test1a)

[1] 5057

örnek boyutu tam olarak 5000 değildir, çünkü ödev olasılıklıdır, ancak çok sayıda yasa sayesinde büyük örneklerde sorun olmamalıdır.

Ayrıca bkz: http://blog.richardweiss.org/2016/12/25/hash-splits.html ve /crypto/20742/statistic-properties-of-hash-functions-when -calculating-modülo


Ayrı bir soru olarak eklendi: stackoverflow.com/questions/52769681/…
dzeltzer

Birden fazla zaman serisi verisinden auto.arima modeli geliştirmek istiyorum ve modeli oluşturmak ve test etmek için her seriden iki yıllık bir aralıkta 1 yıl veri, 3 yıl veri, 5, 7 ... kullanmak istiyorum kalan test seti. Takılan modelin istediğime sahip olması için alt ayarı nasıl yaparım? Yardımınız için teşekkür ederim
Stackuser

0
set.seed(123)
llwork<-sample(1:length(mydata),round(0.75*length(mydata),digits=0)) 
wmydata<-mydata[llwork, ]
tmydata<-mydata[-llwork, ]

-2

Satırlar ve sütunlar için R dizinini kullanarak birkaç satır seçmenin çok basit bir yolu vardır. Bu, birkaç satır verilen veri kümesini TEMİZLE bölmenizi sağlar - verilerinizin% 80'ini diyelim.

R'de tüm satırlar ve sütunlar dizine eklenir, böylece DataSetName [1,1], "DataSetName" öğesinin ilk sütununa ve ilk satırına atanan değerdir. [X,] kullanarak satır ve [, x] kullanarak sütun seçebilirim

Örneğin: 100 satırlı "veri" olarak adlandırılan bir veri kümem varsa, ilk 80 satırı şunu kullanarak görüntüleyebilirim:

Profil (veriler [1:80])

Aynı şekilde bu satırları seçebilir ve bunları kullanarak alt kümeleri oluşturabilirim:

tren = veri [1:80,]

test = veri [81: 100,]

Şimdi verilerimi yeniden örnekleme imkanı olmadan iki bölüme ayırdım. Çabuk ve kolay.


1
Ancak, verilerin bu şekilde bölünebileceği doğrudur, tavsiye edilmez. Bazı veri kümeleri, farkında olmadığınız bir değişken tarafından sıralanır. Bu yüzden ilk n satırı almak yerine hangi sıraların eğitim olarak değerlendirileceğini örneklemek en iyisidir.
user5029763

1
Test ve eğitim setine ayırmadan önce verileri karıştırırsanız, öneriniz işe yarar.
Hadij
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.