Как разбить данные на обучающие/тестовые наборы, используя функцию выборки
Я только начал использовать 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,]
Теперь мои данные разбиты на две части без возможности повторной выборки. Быстро и просто.