Создание складок для k-кратного CV в R с помощью Caret

Я пытаюсь составить k-кратное резюме для нескольких методов классификации / гиперпараметров, используя данные, доступные на

http://archive.ics.uci.edu/ml/machine-learning-databases/undocumented/connectionist-bench/sonar/sonar.all-data.

Этот набор состоит из 208 строк, каждая с 60 атрибутами. Я читаю его в data.frame с помощью функции read.table.

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

test ‹- createFolds (t, k = 5)

У меня было две проблемы с этим. Первый - длины складок не располагаются рядом друг с другом:

  Length Class  Mode   

Свернуть1 29 -нет- числовой
Свернуть2 14 -не- числовой
Сложить3 7 -не- числовой
Сложить4 5 -не- числовой
Свернуть5 5 -не- числовой

Другой заключается в том, что это, по-видимому, разделило мои данные в соответствии с индексами атрибутов, но я хочу разделить сами данные. Я подумал, что, транспонировав свой data.frame, используя:

test ‹- t (myDataNumericValues)

Но когда я вызываю функцию createFolds, она дает мне что-то вроде этого:

  Length Class  Mode   

Fold1 2496 -none- numeric
Fold2 2496 -none- numeric
Fold3 2495 -none- numeric
Fold4 2496 -none- numeric
Fold5 2497 -none- numeric

Проблема с длиной была решена, но мои данные 208 по-прежнему не разделяются соответствующим образом.

Есть мысли о том, что я могу сделать? Считаете ли вы, что пакет каретки не самый подходящий?

заранее спасибо


person gcolucci    schedule 07.04.2014    source источник


Ответы (2)


Прочтите ?createFolds, чтобы понять, что делает функция. Он создает индексы, определяющие, какие данные удерживаются в отдельных свертках (см. Варианты возврата в обратном направлении):

  > library(caret)
  > library(mlbench)
  > data(Sonar)
  > 
  > folds <- createFolds(Sonar$Class)
  > str(folds)
  List of 10
   $ Fold01: int [1:21] 25 39 58 63 69 73 80 85 90 95 ...
   $ Fold02: int [1:21] 19 21 42 48 52 66 72 81 88 89 ...
   $ Fold03: int [1:21] 4 5 17 34 35 47 54 68 86 100 ...
   $ Fold04: int [1:21] 2 6 22 29 32 40 60 65 67 92 ...
   $ Fold05: int [1:20] 3 14 36 41 45 75 78 84 94 104 ...
   $ Fold06: int [1:21] 10 11 24 33 43 46 50 55 56 97 ...
   $ Fold07: int [1:21] 1 7 8 20 23 28 31 44 71 76 ...
   $ Fold08: int [1:20] 16 18 26 27 38 57 77 79 91 99 ...
   $ Fold09: int [1:21] 13 15 30 37 49 53 74 83 93 96 ...
   $ Fold10: int [1:21] 9 12 51 59 61 62 64 70 82 87 ...

Чтобы использовать их для разделения данных:

   > split_up <- lapply(folds, function(ind, dat) dat[ind,], dat = Sonar)
   > dim(Sonar)
   [1] 208  61
   > unlist(lapply(split_up, nrow))
   Fold01 Fold02 Fold03 Fold04 Fold05 Fold06 Fold07 Fold08 Fold09 Fold10 
       21     21     21     21     20     21     21     20     21     21 

Функция train используется в этом пакете для фактического моделирования (обычно вам не нужно делать разбиение самостоятельно. См. эту страницу).

Максимум

person topepo    schedule 07.04.2014
comment
Спасибо за помощь, Макс. Теперь я столкнулся с другой проблемой, на которую я указал здесь: stackoverflow.com/questions/22972854/. Надеюсь, что кто-то может помочь мне и в этом - person gcolucci; 10.04.2014
comment
Этот ответ полезен, но это неправда, что? CreateFolds предлагает ответ. В содержании? CreateFolds никогда не говорится, что он создает индексы, определяющие, какие данные хранятся в отдельных сгибах. - person lourencoj; 28.01.2020

Я не знаком с пакетом caret, но раньше писал функцию вычисления CV на основе дерева решений из пакета rpart. Конечно, функция нуждается в мотивировке, чтобы соответствовать вашим целям.

CV <- function(form, x, fold = 10, cp = 0.01) {
  # x is the data
  n <- nrow(x)
  prop <- n%/%fold
  set.seed(7)
  newseq <- rank(runif(n))
  k <- as.factor((newseq - 1)%/%prop + 1)

  y <- unlist(strsplit(as.character(form), " "))[2]
  vec.accuracy <- vector(length = fold)
  for (i in seq(fold)) {
    # It depends on which classification method you use
    fit <- rpart(form, data = x[k != i, ], method = "class")
    fit.prune <- prune(fit, cp = cp)
    fcast <- predict(fit.prune, newdata = x[k == i, ], type = "class")
    cm <- table(x[k == i, y], fcast)
    accuracy <- (cm[1, 1] + cm[2, 2])/sum(cm)
    vec.accuracy[i] <- accuracy
  }
avg.accuracy <- mean(vec.accuracy)
avg.error <- 1 - avg.accuracy
cv <- data.frame(Accuracy = avg.accuracy, Error = avg.error)
return(cv)

}

person Earo Wang    schedule 07.04.2014