IT story

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

hot-time 2020. 6. 19. 07:58
반응형

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


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

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

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


데이터 파티셔닝을 달성하는 방법에는 여러 가지가 있습니다. 보다 완전한 접근 방법 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, ]

다음을 통해 쉽게 수행 할 수 있습니다.

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)

이것은 거의 동일한 코드이지만 더 멋지게 보입니다.

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

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

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

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

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

끝난


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

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

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

입력하면 :

?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 % 시험을 줄 것입니다.


여기에 게시 된 다른 모든 방법을 살펴본 후에 아무도 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

내 솔루션은 행을 섞은 다음 행의 처음 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)),]

scorecard package에는 유용한 기능이 있으며, 여기서 비율과 시드를 지정할 수 있습니다

library(scorecard)

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

시험 및 열차 데이터는 목록에 저장되며 전화 dt_list$traindt_list$test


정확히 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

R 샘플 코드에서 caTools 패키지를 사용하는 방법은 다음과 같습니다.

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

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

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)

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)

The sample.split() function will add one extra column 'split1' to dataframe and 2/3 of the rows will have this value as TRUE and others as FALSE.Now the rows where split1 is TRUE will be copied into train and other rows will be copied to test dataframe.


Assuming df is your data frame, and that you want to create 75% train and 25% test

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

Then to create a train and test data frames

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

I bumped into this one, it can help too.

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

Beware of sample for splitting if you look for reproducible results. If your data changes even slightly, the split will vary even if you use set.seed. For example, imagine the sorted list of IDs in you data is all the numbers between 1 and 10. If you just dropped one observation, say 4, sampling by location would yield a different results because now 5 to 10 all moved places.

An alternative method is to use a hash function to map IDs into some pseudo random numbers and then sample on the mod of these numbers. This sample is more stable because assignment is now determined by the hash of each observation, and not by its relative position.

For example:

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

sample size is not exactly 5000 because assignment is probabilistic, but it shouldn't be a problem in large samples thanks to the law of large numbers.

See also: http://blog.richardweiss.org/2016/12/25/hash-splits.html and https://crypto.stackexchange.com/questions/20742/statistical-properties-of-hash-functions-when-calculating-modulo


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

We can divide data into a particular ratio here it is 80% train and 20% in a test dataset.

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

There is a very simple way to select a number of rows using the R index for rows and columns. This lets you CLEANLY split the data set given a number of rows - say the 1st 80% of your data.

In R all rows and columns are indexed so DataSetName[1,1] is the value assigned to the first column and first row of "DataSetName". I can select rows using [x,] and columns using [,x]

For example: If I have a data set conveniently named "data" with 100 rows I can view the first 80 rows using

View(data[1:80,])

In the same way I can select these rows and subset them using:

train = data[1:80,]

test = data[81:100,]

Now I have my data split into two parts without the possibility of resampling. Quick and easy.

참고URL : https://stackoverflow.com/questions/17200114/how-to-split-data-into-training-testing-sets-using-sample-function

반응형