#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 aPO
еще не реализовано ( github.com/mlr-org/mlr3pipelines/issues/537 )