샘플 기능을 사용하여 데이터를 학습 / 테스트 세트로 분할하는 방법


160

방금 R을 사용하기 시작했으며 다음 샘플 코드와 데이터 세트를 통합하는 방법을 잘 모르겠습니다.

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

훈련 (75 %) 및 테스트 (25 %) 세트에 넣어야하는 데이터 세트가 있습니다. x와 크기에 어떤 정보를 넣을지 잘 모르겠습니다. x는 데이터 세트 파일이고 크기는 몇 개입니까?


1
x의 색인 (행 / 열 번호)이 될 수 있습니다 data. size일 수 있습니다 0.75*nrow(data). sample(1:10, 4, replace = FALSE, prob = NULL)그것이 무엇을하는지 보십시오 .
harkmug 2016 년

답변:


255

데이터 파티셔닝을 달성하는 방법에는 여러 가지가 있습니다. 보다 완전한 접근 방법 createDataPartitioncaTools패키지 의 기능을 살펴보십시오 .

다음은 간단한 예입니다.

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를 가진 테스트?
goldisfine

1
감사. 시도했지만 mtcars[!train_ind]실패하지는 않았지만 예상대로 작동하지 않았습니다. !?를 사용하여 어떻게 하위 집합을 만들 수 있습니까?
user989762

@ user989762 !TRUE/FALSE인덱스가 아닌 논리 ( )에 사용됩니다 . 을 사용하여 부분 집합을 만들고 싶다면 !mtcars [ !seq_len(nrow(mtcars)) %in% train_ind,] (테스트되지 않음) 와 같은 것을 시도하십시오 .
dickoa

1
"-"를 사용할 때 @VedaadShakib은 데이터에서 train_ind의 모든 인덱스를 생략합니다. adv-r.had.co.nz/Subsetting.html을 살펴 보십시오 . 도움이
되길 바랍니다

1
아닌가 createDataPartitioncaret하지 caTools?
J. Mini

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를 사용한 접근 방식을 사용했습니다. 감사합니다
Chetan Sharma 8

1
sample = sample.split(data[,1], SplitRatio = .75)열 이름을 지정할 필요가 없습니다.
Benjamin Ziepert

33

나는 dplyr이것을 위해 사용 하고 그것을 매우 간단하게 만듭니다. 데이터 세트에 id 변수가 필요합니다. 어쨌든 세트를 만드는 것뿐만 아니라 프로젝트 중 추적 성을 위해 좋은 아이디어입니다. 포함되지 않은 경우 추가하십시오.

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

예! 좋은 모습!
MeenakshiSundharam

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,] 및 testing <-sub_train [-intrain,]이어야합니다. 지난 5 년 동안 아무도이 주요 문제를 발견하지 못한 이유가 궁금합니다!
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 패키지를 가져 와서 require (dplyr)
TheMI

이 답변은 도움이되었지만 예상 결과를 얻으려면 조정해야했습니다. 그대로, 데이터 세트 'train'의 행 이름 = sid는 순차적 정수의 sid : 1,2,3,4, ... 반면에 sid는 원래 데이터 세트 'a'의 행 번호가되기를 원합니다. 순차 정수가 아닙니다. 따라서 먼저 'a'에 id 변수를 작성해야합니다.
Scott Murff

row.names (mtcars) <-NULL; train <-dplyr :: sample_frac (mtcars, 0.5); test <-mtcars [-as.numeric (row.names (train)),] # 행 데이터가 이미 숫자로 설정된 경우 원본 코드가 작동하지 않습니다.
Christopher John

16

내 솔루션은 기본적으로 dickoa와 동일하지만 해석하기가 조금 더 쉽습니다.

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

변수 스위스 란 무엇입니까?
billmccord

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,]마지막 줄 에 사용하려고 했습니까?
Matt L.

5

입력하면 :

?sample

If 샘플 함수의 매개 변수가 무엇을 의미하는지 설명하는 도움말 메뉴를 시작합니다.

나는 전문가가 아니지만 여기에 내가 가진 코드가 있습니다.

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

설명

R에서 데이터를 선택하는 방법에는 여러 가지가 있으며, 가장 일반적으로 사람들은 양 / 음수를 사용하여 각각 선택 / 선택 취소합니다. 그러나 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 package에는 유용한 기능이 있으며, 여기서 비율과 시드를 지정할 수 있습니다

library(scorecard)

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

시험 및 열차 데이터는 목록에 저장되며 전화 dt_list$traindt_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

기수 R을 사용합니다. 함수 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,]

실제로 훈련과 테스트 세트 (초보자가 종종 어려움을 겪는)를 만들기 위해 여분의 커플 라인을 보여 주면 훨씬 더 나은 답변이 될 것입니다.
Gregor Thomas

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()함수는 데이터 프레임에 하나의 추가 열 'split1'을 추가하고 행의 2/3는이 값을 TRUE로, 다른 행은 FALSE를 갖습니다. 이제 split1이 TRUE 인 행은 기차로 복사되고 다른 행은 테스트를 위해 복사됩니다. 데이터 프레임.


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. 예를 들어 데이터의 정렬 된 ID 목록이 1과 10 사이의 모든 숫자라고 가정합니다. 4 번의 관측치 하나만 ​​삭제 한 경우 위치별로 샘플링하면 이동 한 모든 위치가 5 ~ 10 개이므로 다른 결과가 생성됩니다.

다른 방법은 해시 함수를 사용하여 ID를 의사 난수로 매핑 한 다음 이러한 숫자의 모드를 샘플링하는 것입니다. 이 표본은 이제 상대적 위치가 아니라 각 관측 값의 해시에 의해 할당이 결정되므로 더 안정적입니다.

예를 들면 다음과 같습니다.

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

할당은 확률 적이므로 표본 크기는 정확히 5000이 아니지만 많은 수의 법칙으로 인해 큰 표본에서는 문제가되지 않습니다.

참조 : http://blog.richardweiss.org/2016/12/25/hash-splits.html/crypto/20742/statistical-properties-of-hash-functions-when 계산 모듈로


별도 질문으로 추가됨 : stackoverflow.com/questions/52769681/…
dzeltzer

여러 시계열 데이터에서 auto.arima 모델을 개발하고 각 시리즈에서 2 년 간격으로 1 년 데이터, 3 년 데이터, 5, 7 ...을 사용하여 모델을 빌드하고 테스트하고 싶습니다. 나머지 테스트 세트 피팅 된 모델이 원하는 것을 갖도록 하위 설정을 어떻게 수행합니까? 도와 주셔서 감사합니다
Stackuser


-2

행과 열에 R 인덱스를 사용하여 여러 행을 선택하는 매우 간단한 방법이 있습니다. 이를 통해 데이터의 첫 번째 80 %와 같이 여러 행이 지정된 데이터 세트를 깔끔하게 분할 할 수 있습니다.

R에서는 모든 행과 열이 색인화되므로 DataSetName [1,1]은 "DataSetName"의 첫 번째 열과 첫 번째 행에 지정된 값입니다. [x,]를 사용하여 행을 선택하고 [, x]를 사용하여 열을 선택할 수 있습니다

예를 들어, 100 개의 행을 가진 "data"라는 편리한 데이터 세트가있는 경우 다음을 사용하여 처음 80 개의 행을 볼 수 있습니다.

보기 (데이터 [1:80,])

같은 방법으로 이러한 행을 선택하고 다음을 사용하여 하위 세트를 지정할 수 있습니다.

기차 = 데이터 [1:80,]

테스트 = 데이터 [81 : 100,]

이제 데이터를 리샘플링하지 않고 두 부분으로 나눕니다. 빠르고 쉽습니다.


1
데이터를 그런 식으로 나눌 수있는 것은 사실이지만 권장하지 않습니다. 일부 데이터 세트는 사용자가 모르는 변수로 정렬됩니다. 따라서 첫 번째 n 행을 취하는 대신 어떤 행을 학습으로 간주할지 샘플링하는 것이 가장 좋습니다.
user5029763

1
테스트 및 학습 세트로 분리하기 전에 데이터를 섞으면 제안이 작동합니다.
Hadij
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.