Почему при обучении модели выбран другой гиперпараметр, чем при передискретизации?

Во время передискретизации проверяется параметр max_depth со значениями 5 и 9. Однако при тренировке используется совсем другое значение - 10. Я ожидал, что во время обучения будет установлен параметр, возвращающий наименьшее RMSE. В данном случае было выбрано совсем другое значение параметра.

library("mlr3")
library("paradox")
library("mlr3learners")
library("mlr3tuning")
library("data.table")

set.seed(10)

x1 = 1:100
x2 = 2 * x1
y = x1^2 - x2 + rnorm(100)

data = data.table(
   x1 = x1,
   x2 = x2,
   y = y
)

task = TaskRegr$new("task", backend = data, target = "y")

lrn_xgb = mlr_learners$get("regr.xgboost")

ps = ParamSet$new(
   params = list(
      ParamInt$new(id = "max_depth", lower = 4, upper = 10)
   ))

at = AutoTuner$new(learner = lrn_xgb, 
                   resampling = rsmp("cv", folds = 2),
                   measures = msr("regr.rmse"), 
                   tune_ps = ps,
                   terminator = term("evals", n_evals = 1),
                   tuner = tnr("random_search"))

resampling_outer = rsmp("cv", folds = 2)

rr = resample(task = task, learner = at, resampling = resampling_outer)
#> max_depth = 5
#> max_depth = 9

at$train(task)
#> max_depth = 10

Информация о сеансе:

R version 3.6.1 (2019-07-05)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 8.1 x64 (build 9600)

Matrix products: default

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods  
[7] base     

other attached packages:
[1] mlr3learners_0.1.3 mlr3tuning_0.1.0   data.table_1.12.2 
[4] paradox_0.1.0      mlr3_0.1.3

loaded via a namespace (and not attached):
 [1] lgr_0.3.3        lattice_0.20-38  mlr3misc_0.1.4  
 [4] digest_0.6.21    crayon_1.3.4     grid_3.6.1      
 [7] R6_2.4.0         backports_1.1.4  magrittr_1.5    
[10] stringi_1.4.3    uuid_0.1-2       Matrix_1.2-17   
[13] checkmate_1.9.4  xgboost_0.90.0.2 tools_3.6.1     
[16] compiler_3.6.1   Metrics_0.1.4

1 ответ

Решение

Все, что происходит, правильно. Дело в следующем: AutoTuner добавляет к алгоритму обучения xgboost метод настройки, который находит (оптимальные? Хорошие? Хорошо работающие?) Гиперпараметры, затем устанавливает их в учащемся, а затем обучает модель с помощью последнего вызова обучения. алгоритм.

Вы можете представить это как

Данные -> [Split-Data] -> [Tune] -(opt.HPs, Data) -> [Train] -> Модель

Если вы хотите (лишь немного) менее уродливую картинку для этого, взгляните на мою лекцию по адресу:

https://compstat-lmu.github.io/lecture_i2ml/articles/content.html(см. Day5, настройка и вложенная передискретизация)

Теперь в вашем коде происходит 3 прохода указанного выше конвейера. 2 в вашем 2-кратном резюме, 1 в конце. В каждом проходе происходит настройка. По разным данным. Таким образом, НЕТ ГАРАНТИИ, что 3 оптимальных конфигурации HP одинаковы. Прежде всего, первые 2 представляют собой выборки данных из выборки, лежащей в основе распределения данных, и имеют одинаковый размер. Так что довольно много "одинакового", но это все еще стохастические образцы. Так что результаты могут отличаться. Особенно, когда есть много конфигураций HP с почти такой же производительностью, как оптимальная конфигурация HP. И данных мало. Да и тюнер довольно стохастичен. (NB: все это верно для вашего примера....) Для третьего прогона настройки базовое распределение данных остается прежним, но теперь обучающие данные даже немного больше (в вашем случае вдвое больше из-за 2CV). Это также может привести к разным результатам.

В общем, вы можете проверить себя на наличие хотя бы примерно таких же результатов настройки, как вы делали выше, и начать "беспокоиться" / проверять / использовать свой человеческий обучающий инструмент (мозг), почему настройка на самом деле "нестабильна". Но в вашем случае данных настолько мало, и эксперимент больше похож на "игрушечный эксперимент", что я не думаю, что есть смысл здесь обдумывать это. Почему это технически не ошибка, я объяснил выше.

Вот еще один, надеюсь, полезный аналог: забудьте про AutoTuner, запустите точно такой же код с простой линейной регрессией. Вы запускаете с ним 2CV и подгоняете его к полным данным. Для линейной модели созданы 3 вектора параметров "бета". Вы ожидаете, что они все будут одинаковыми? Нет. Вы бы беспокоились, если они все супер-разные? Потенциально.

Мой последний пример и ваш код очень сильно связаны. Свой последний пример я бы назвал "обучение 1-го уровня". И мы оптимизируем функцию риска линейной модели численно. Тюнинг - это "обучение 2-го уровня". Он по-прежнему оптимизирует параметры, гиперпараметры или параметры 2-го уровня. И это оптимизирует другой "риск": ошибку перекрестной проверки. И использует другие методы оптимизации, возможно, случайный поиск, возможно, байесовскую оптимизацию. Но на абстрактном уровне обе техники очень похожи.

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

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