Создание разделов данных по выбранному диапазону данных для подачи в функцию caret :: train для перекрестной проверки - PullRequest
0 голосов
/ 16 октября 2018

Я хочу создать разделы данных jack-knife для кадра данных ниже с разделами, которые будут использоваться в caret::train (как производит caret::groupKFold()).Однако уловка заключается в том, что я хочу ограничить контрольные точки более 16 дней, используя оставшуюся часть этих данных в качестве обучающего набора.

df <- data.frame(Effect = seq(from = 0.05, to = 1, by = 0.05),
     Time = seq(1:20))

Причина, по которой я хочу это сделать, заключается в том, чтоМеня интересует только то, насколько хорошо модель предсказывает верхнюю границу, поскольку это область интереса.Я чувствую, что есть способ сделать это с помощью функции caret::groupKFold(), но я не уверен, как это сделать.Любая помощь будет принята с благодарностью.

Пример того, что будет содержать каждый сгиб CV:

TrainSet1 <- subset(df, Time != 16)
TestSet1 <- subset(df, Time == 16)

TrainSet2 <- subset(df, Time != 17)
TestSet2 <- subset(df, Time == 17)

TrainSet3 <- subset(df, Time != 18)
TestSet3 <- subset(df, Time == 18)

TrainSet4 <- subset(df, Time != 19)
TestSet4 <- subset(df, Time == 19)

TrainSet5 <- subset(df, Time != 20)
TestSet5 <- subset(df, Time == 20)

Хотя в формате, который выводит функция caret::groupKFold, чтобы сгибы могли бытьподается в функцию caret::train:

CVFolds <- caret::groupKFold(df$Time)
CVFolds

Заранее спасибо!

1 Ответ

0 голосов
/ 17 октября 2018

Для настраиваемых сгибов я считаю, что встроенные функции обычно недостаточно гибки.Поэтому я обычно делаю их, используя tidyverse.Один из подходов к вашей проблеме:

library(tidyverse)

df %>%
  mutate(id = row_number()) %>% #use the row number as a column called id
  filter(Time > 15) %>% #filter Time as per your need
  split(.$Time)  %>% #split df to a list by Time
  map(~ .x %>% select(id)) #select row numbers for each list element

пример с двумя строками каждый раз:

df <- data.frame(Effect = seq(from = 0.025, to = 1, by = 0.025),
                 Time = rep(1:20, each = 2))

df %>%
  mutate(id = row_number()) %>%
  filter(Time > 15) %>%
  split(.$Time)  %>%
  map(~ .x %>% select(id)) -> test_folds

test_folds
#output
$`16`
  id
1 31
2 32

$`17`
  id
3 33
4 34

$`18`
  id
5 35
6 36

$`19`
  id
7 37
8 38

$`20`
   id
9  39
10 40

с неравным количеством строк за раз

df <- data.frame(Effect = seq(from = 0.55, to = 1, by = 0.05),
                 Time = c(rep(1, 5), rep(2, 3), rep(rep(3, 2))))

df %>%
  mutate(id = row_number()) %>%
  filter(Time > 1) %>%
  split(.$Time)  %>%
  map(~ .x %>% select(id))

$`2`
  id
1  6
2  7
3  8

$`3`
  id
4  9
5 10

Теперь вы можете определить эти складывающиеся складки внутри trainControl с аргументом indexOut.

РЕДАКТИРОВАТЬ: чтобы получить результат, аналогичный caret::groupKFold, можно:

df %>%
  mutate(id = row_number()) %>%
  filter(Time > 1) %>%
  split(.$Time)  %>%
  map(~ .x %>%
        select(id) %>%
        unlist %>%
        unname) %>%
  unname
...