Расслоение данных

У меня большой набор данных, и мне нравится приспосабливать различные логистические регрессии для каждого города, один из столбцов в моих данных. Следующий раздел 70/30 работает без учета группы City.

indexes <- sample(1:nrow(data), size = 0.7*nrow(data))

train <- data[indexes,]
test <- data[-indexes,]

Но это не гарантирует раскол 70/30 для каждого города.

допустим, у меня есть город A и город B, где у города A 100 рядов, а у города B 900 рядов, всего 1000 рядов. Разделение данных с помощью приведенного выше кода даст мне 700 строк для поезда и 300 для тестовых данных, но это не гарантирует, что у меня будет 70 строк для города A и 630 строк для города B в данных поезда. Как я могу это сделать?

Как только у меня будут данные тренировок, разделенные по моде 70/30 для каждого города, я проведу логистическую регрессию для каждого города (я знаю, как это сделать, когда у меня есть данные о поездах)

5 ответов

Пытаться createDataPartition от caret пакет. Его документ гласит: по умолчанию createDataPartition делает стратифицированное случайное разделение данных.

library(caret)
train.index <- createDataPartition(Data$Class, p = .7, list = FALSE)
train <- Data[ train.index,]
test  <- Data[-train.index,]

это может также использоваться для стратифицированного K-сгиба как:

ctrl <- trainControl(method = "repeatedcv",
                     repeats = 3,
                     ...)
# when calling train, pass this train control
train(...,
      trControl = ctrl,
      ...)

проверить каретный документ для более подробной информации

Пакет splitstackshape имеет приятную функцию stratified который тоже может это делать, но это немного лучше, чем createDataPartitionпотому что он может использовать несколько столбцов для стратификации одновременно. Его можно использовать с одним столбцом, например:

library(splitstackshape)
set.seed(42)  # good idea to set the random seed for reproducibility
stratified(data, c('City'), 0.7)

Или с несколькими столбцами:

stratified(data, c('City', 'column2'), 0.7)

Типичный способ с split

lapply( split(dfrm, dfrm$City), function(dd){
            indexes= sample(1:nrow(dd), size = 0.7*nrow(dd))
            train= dd[indexes, ]    # Notice that you may want all columns
            test= dd[-indexes, ]
            # analysis goes here
            }

Если бы вы делали это поэтапно, как вы пытались выше, это было бы так:

cities <- split(data,data$city)

idxs <- lapply(cities, function (d) {
    indexes <- sample(1:nrow(d), size=0.7*nrow(d))
})

train <- data[ idxs[[1]], ]  # for the first city
test <-  data[ -idxs[[1]], ]

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

Ваш код работает так же хорошо, как и сейчас, если City - это столбец, просто запустите данные обучения как train[,2]. Вы можете сделать это легко для каждого с лямбда-функцией

logReg<-function(ind) {
    reg<-glm(train[,ind]~WHATEVER)
    ....
    return(val) }

Затем бегите по вектору городских индексов.

Другой возможный способ, аналогичный ответу IRTFM (например, с использованием только base-r), заключается в использовании следующего. Обратите внимание, что этот ответ возвращает стратифицированный индекс, который можно использовать как индекс, рассчитанный в вопросе.

      p <- 0.7
strats <- your_data$the_stratify_variable

rr <- split(1:length(strats), strats)
idx <- sort(as.numeric(unlist(sapply(rr, function(x) sample(x, length(x) * p)))))

train <- your_data[idx, ]
test <- your_data[-idx, ]

Пример:

      p <- 0.7
strats <- mtcars$cyl

rr <- split(1:length(strats), strats)
idx <- sort(as.numeric(unlist(sapply(rr, function(x) sample(x, length(x) * p)))))

train <- mtcars[idx, ]
test <- mtcars[-idx, ]

table(mtcars$cyl) / nrow(mtcars)
#>       4       6       8
#> 0.34375 0.21875 0.43750 

table(train$cyl) / nrow(train)
#>    4    6    8
#> 0.35 0.20 0.45 

table(test$cyl) / nrow(test)
#>         4         6         8 
#> 0.3333333 0.2500000 0.4166667 

Мы видим, что все наборы данных all(mtcars), train и test имеют примерно одинаковое распределение классов!

Другие вопросы по тегам