Как разбить данные на обучающие/тестовые наборы, используя функцию выборки

Я только начал использовать R, и я не уверен, как включить мой набор данных со следующим примером кода:

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

У меня есть набор данных, который мне нужно ввести в тренировку (75%) и тестирование (25%). Я не уверен, какую информацию я должен положить в x и размер? Является ли x файлом набора данных и размером, сколько у меня образцов?

Ответ 1

Существует множество подходов для достижения разделения данных. Для более полного подхода взгляните на функцию 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, ]

Ответ 2

Это легко сделать:

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)

Ответ 3

Это почти тот же код, но в более приятном образе

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

Ответ 4

Я хотел бы использовать dplyr для этого, делает это очень просто. Для этого требуется переменная id в вашем наборе данных, что в любом случае является хорошей идеей не только для создания наборов, но и для отслеживаемости во время вашего проекта. Добавьте это, если не содержит уже.

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

Ответ 5

Я разделил '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,]

сделать

Ответ 6

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

Ответ 7

Мое решение в основном такое же, как dickoa, но немного легче интерпретировать:

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

Ответ 8

Просто более краткий и простой способ использования удивительной библиотеки 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, ]

Ответ 9

Если вы введете:

?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% тест.

Ответ 10

Изучив все различные методы, опубликованные здесь, я не увидел, чтобы кто-либо использовал 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 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

Ответ 11

Мое решение перетасовывает ряды, а затем принимает первые 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)),]

Ответ 12

Пакет scorecard имеет полезную функцию для этого, где вы можете указать соотношение и начальное значение

library(scorecard)

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

Данные теста и поезда хранятся в списке, и к ним можно обратиться, вызвав dt_list$train и dt_list$test

Ответ 13

Ниже функции, которая создает 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

Ответ 14

Использовать пакет caTools в R пример кода будет выглядеть следующим образом: -

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

Ответ 15

Используйте базу R. Функция runif генерирует равномерно распределенные значения от 0 до 1.При изменении значения отсечения (train.size в примере ниже) у вас всегда будет примерно одинаковый процент случайных записей ниже значения отсечки.

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

Ответ 16

Я могу предложить использовать пакет 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)

Ответ 17

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, будут скопированы в поезд и другие строки. будет скопирован в тестовый фрейм данных.

Ответ 18

Предполагая, что 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,]

Ответ 19

Я столкнулся с этим, это может помочь тоже.

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

Ответ 20

Остерегайтесь 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))

[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 и https://crypto.stackexchange.com/questions/20742/statistical-properties-of-hash-functions-when вычисляют-модулю

Ответ 21

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

Ответ 22

Мы можем разделить данные на определенное соотношение, здесь оно составляет 80% и 20% в тестовом наборе данных.

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

Ответ 23

Существует очень простой способ выбрать количество строк, используя индекс R для строк и столбцов. Это позволяет вам ЧИСТО разделить набор данных по количеству строк - скажем, первые 80% ваших данных.

В R все строки и столбцы индексируются, поэтому DataSetName [1,1] - это значение, назначенное первому столбцу и первой строке "DataSetName". Я могу выбрать строки, используя [x,] и столбцы, используя [, x]

Например: если у меня есть набор данных с удобным названием "data" с 100 строками, я могу просмотреть первые 80 строк, используя

Просмотр (данные [1:80,])

Таким же образом я могу выбрать эти строки и поднастроить их, используя:

поезд = данные [1:80,]

тест = данные [81:100,]

Теперь мои данные разбиты на две части без возможности повторной выборки. Быстро и просто.