Обеспечивает ли использование одного и того же объекта trainControl для перекрестной проверки при обучении нескольких моделей с помощью каретки точное сравнение моделей?

Недавно я углубился в пакет R caret и у меня возник вопрос о воспроизводимости и сравнении моделей во время обучения, который я не смог точно определить.

Мое намерение состоит в том, чтобы каждый train вызов и, следовательно, каждая результирующая модель использовали одни и те же разбиения перекрестной проверки, чтобы исходные сохраненные результаты перекрестной проверки были сопоставимы с вневыборочными оценками модели, которые вычисляются во время построения.

Один из методов, который я видел, заключается в том, что вы можете указывать семя перед каждым вызовом train как таковым:

set.seed(1)
model <- train(..., trControl = trainControl(...))
set.seed(1)
model2 <- train(..., trControl = trainControl(...))
set.seed(1)
model3 <- train(..., trControl = trainControl(...))

Однако совместное использование объекта trainControl между вызовами train означает, что они используют одну и ту же передискретизацию и индексы в целом, или я должен явно передать аргумент seeds в функцию. Имеет ли объект управления поездом случайные функции при его использовании или они задаются при объявлении?

Мой текущий метод был:

set.seed(1)
train_control <- trainControl(method="cv", ...)
model1 <- train(..., trControl = train_control)
model2 <- train(..., trControl = train_control)
model3 <- train(..., trControl = train_control)

Будут ли эти заходы поездов использовать те же разбиения и быть сопоставимыми, или мне нужно будет предпринять дальнейшие шаги для обеспечения этого? т.е. указание семян при создании объекта trainControl или вызов set.seed перед каждым поездом? Или оба?

Надеюсь, в этом есть смысл, а не полная чушь. Любая помощь


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


person willcanniford    schedule 03.10.2018    source источник


Ответы (1)


Свертки CV не создаются во время определения trainControl, если явно не указано с использованием аргумента index, который я рекомендую. Их можно создать с помощью одной из специализированных caret функций:

createFolds
createMultiFolds
createTimeSlices
groupKFold

При этом использование определенного начального числа до определения trainControl не приведет к таким же сверткам CV.

Пример:

library(caret)
library(tidyverse)

set.seed(1)
trControl = trainControl(method = "cv",
                         returnResamp = "final",
                         savePredictions = "final")

создать две модели:

knnFit1 <- train(iris[,1:4], iris[,5],
                 method = "knn",
                 preProcess = c("center", "scale"),
                 tuneLength = 10,
                 trControl = trControl)

ldaFit2 <- train(iris[,1:4], iris[,5],
                 method = "lda",
                 tuneLength = 10,
                 trControl = trControl)

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

knnFit1$pred %>%
  left_join(ldaFit2$pred, by = "rowIndex") %>%
  mutate(same = Resample.x == Resample.y) %>%
  {all(.$same)}
#FALSE

Если вы устанавливаете одно и то же начальное число перед каждым train вызовом

set.seed(1)
knnFit1 <- train(iris[,1:4], iris[,5],
                 method = "knn",
                 preProcess = c("center", "scale"),
                 tuneLength = 10,
                 trControl = trControl)

set.seed(1)
ldaFit2 <- train(iris[,1:4], iris[,5],
                 method = "lda",
                 tuneLength = 10,
                 trControl = trControl)


set.seed(1)
rangerFit3 <- train(iris[,1:4], iris[,5],
                 method = "ranger",
                 tuneLength = 10,
                 trControl = trControl)


knnFit1$pred %>%
  left_join(ldaFit2$pred, by = "rowIndex") %>%
  mutate(same = Resample.x == Resample.y) %>%
  {all(.$same)}

knnFit1$pred %>%
  left_join(rangerFit3$pred, by = "rowIndex") %>%
  mutate(same = Resample.x == Resample.y) %>%
  {all(.$same)}

те же индексы будут использоваться в складках. Однако я бы не стал полагаться на этот метод при использовании параллельных вычислений. Следовательно, чтобы гарантировать, что используются одни и те же разбиения данных, лучше всего определить их вручную, используя _14 _ / _ 15_ аргументы для trainControl.

Когда вы устанавливаете аргумент index вручную, складки будут такими же, однако это не гарантирует, что модели, созданные одним и тем же методом, будут одинаковыми, поскольку большинство методов включают в себя какой-то случайный процесс. Поэтому для полной воспроизводимости рекомендуется также устанавливать начальное число перед каждым вызовом поезда. При параллельном запуске для получения полностью воспроизводимых моделей необходимо установить seeds аргумент для trainControl.

person missuse    schedule 03.10.2018
comment
Спасибо за ответ @missuse. В вашем первом примере вы фактически не используете объявленный trainControl, но если свертки CV не установлены при объявлении объекта, это не имеет значения. Аргумент Index звучит как путь вперед. Если вы используете аргумент index, то нужно ли устанавливать начальное число перед каждым train, или это считается хорошей практикой? - person willcanniford; 03.10.2018
comment
@W. Каннифорд Вы правы, я исправил код. В общем, когда вы устанавливаете аргумент index вручную, складки будут такими же, однако это не гарантирует, что модели, созданные одним и тем же методом, будут одинаковыми, поскольку большинство методов включают в себя какой-то стохастический процесс. Поэтому для полной воспроизводимости рекомендуется также устанавливать начальное число перед каждым вызовом поезда. При параллельном запуске для получения полностью воспроизводимых моделей необходимо установить аргумент seeds для trainControl. - person missuse; 03.10.2018
comment
Еще раз спасибо @missuse! index устанавливает сгибы перекрестной проверки, seeds устанавливает начальные значения, которые будут установлены во время train, чтобы воспроизводимая работа могла выполняться параллельно, когда использование set.seed невозможно, и set.seed можно использовать вместе с index при выполнении процессов, не параллельных как в некоторых моделях есть другие случайные процессы, помимо cv-складок / разбиений. Думаю, я понял. Спасибо. - person willcanniford; 03.10.2018