Как исправить состояние PipeOP?

#mlr3

#mlr3

Вопрос:

Как мы можем исправить a PipeOp ‘s $state , чтобы его параметры или конфигурация были исправлены с самого начала и оставались неизменными как при обучении, так и при прогнозировании.

 task = tsk("iris")
pos1 = po("scale", param_vals =list(
    center = T,
    scale = T,
    affect_columns = selector_name("Sepal.Width")))

pos1$state
pos1$state$center <- c(Sepal.Width = 0) 
pos1$state$scale <- c(Sepal.Width = 2) 
 
graph <- pos1 %>>% lrn("classif.xgboost", eval_metric = "mlogloss")
gl <- GraphLearner$new(graph)
gl$train(task)
gl$state
  

В приведенном выше коде параметры center и scale from po("scale") пересчитываются на основе данных, даже когда я пытаюсь исправить их как ноль и два (не уверен, правильно ли я это сделал) соответственно.

Ответ №1:

A PipeOp ‘s $state никогда не следует изменять вручную. Т.Е. Это больше похоже на слот для регистрации, который вы можете проверить и где PipeOp находит всю информацию, необходимую для выполнения шага прогнозирования после обучения.

PipeOpScale всегда масштабирует обучающие данные до среднего значения 0 и масштабирует их по их среднеквадратичному значению (см. ?scale ) и сохраняет «изученные» параметры (т. Е. Среднее и среднеквадратичное значения обучающих данных, например, атрибуты, возвращаемые scale функцией) как $state . Во время прогнозирования данные будут преобразованы аналогичным образом, что приведет к, вероятно, другому среднему и среднеквадратичному значению.

Предполагая, что вы хотите масштабировать "Sepal.Width" до среднего значения 0 и среднеквадратичного значения 2 как во время обучения, так и при прогнозировании (как указано в вашем коде выше; но это может быть плохой идеей), вы можете использовать PipeOpColApply :

 f = function(x) {
  scale(x)[, 1] * 2   0
}

task = tsk("iris")
pos = po("colapply", applicator = f, affect_columns = selector_name("Sepal.Width"))

train_out = pos$train(list(task))[[1]]$data(cols = task$feature_names)
round(colMeans(train_out), 2)
round(apply(train_out, MARGIN = 2, FUN = sd), 2)

pos$state
  

Комментарии:

1. Мне любопытно, почему 0 ?

2. Кажется, это работает для этого конкретного po , но как насчет других.

3. Просто добавил 0 , чтобы указать, куда пойдет спецификация среднего значения результата, и вы могли бы, например, сделать scale(x)[, 1] * 2 10 , чтобы получить результат со средним значением 10 и среднеквадратичным значением 2.

4. Что касается других PipeOp s, как я уже сказал, $state$ of a PipeOp’не может быть исправлен, и это обычно имеет смысл, поскольку рабочий процесс конвейеров ML в целом выглядит следующим образом: выполните операцию с обучающими данными и сохраните изученную информацию в $state . Затем во время прогнозирования полагайтесь на $state то, что было изучено на обучающих данных (предотвращает утечку информации), чтобы выполнить операцию с данными прогнозирования. Если у вас есть другие очень специфические сценарии, вы всегда можете написать свои собственные PipeOp s, которые, например, наследуются от PipeOpTaskPreproc / PipeOpTaskPreprocSimple .

5. Я не знал о создании пользовательского PO интерфейса. Я должен это проверить. Кроме того, похоже, что исправление $state of a PO еще не реализовано ( github.com/mlr-org/mlr3pipelines/issues/537 )