Я хочу выполнить выбор штрафа для алгоритма LASSO и предсказать результаты, используя tidymodels
. Я буду использовать набор данных о жилье в Бостоне, чтобы проиллюстрировать проблему.
library(tidymodels)
library(tidyverse)
library(mlbench)
data("BostonHousing")
dt <- BostonHousing
Сначала я разделил набор данных на подмножества поездов / тестов.
dt_split <- initial_split(dt)
dt_train <- training(dt_split)
dt_test <- testing(dt_split)
Определение предварительной обработки с использованием пакета recipe
.
rec <- recipe(medv ~ ., data = dt_train) %>%
step_center(all_predictors(), -all_nominal()) %>%
step_dummy(all_nominal()) %>%
prep()
Инициализация модели и рабочего процесса. Я использую двигатель glmnet
. mixture = 1
означает, что я выбираю штраф LASSO, а penalty = tune()
означает, что позже я буду использовать перекрестную проверку, чтобы выбрать лучший параметр штрафа lambda
.
lasso_mod <- linear_reg(mode = "regression",
penalty = tune(),
mixture = 1) %>%
set_engine("glmnet")
wf <- workflow() %>%
add_model(lasso_mod) %>%
add_recipe(rec)
Подготовка стратифицированной 5-кратной перекрестной проверки и штрафной сетки:
folds <- rsample::vfold_cv(dt_train, v = 5, strata = medv, nbreaks = 5)
my_grid <- tibble(penalty = 10^seq(-2, -1, length.out = 10))
Запустим перекрестную проверку:
my_res <- wf %>%
tune_grid(resamples = folds,
grid = my_grid,
control = control_grid(verbose = FALSE, save_pred = TRUE),
metrics = metric_set(rmse))
Теперь я могу получить лучший штраф из сетки и обновить свой рабочий процесс для этого оптимального наказания:
best_mod <- my_res %>% select_best("rmse")
print(best_mod)
final_wf <- finalize_workflow(wf, best_mod)
print(final_wf)
== Workflow ===================================================================================================================
Preprocessor: Recipe
Model: linear_reg()
-- Preprocessor ---------------------------------------------------------------------------------------------------------------
2 Recipe Steps
* step_center()
* step_dummy()
-- Model ----------------------------------------------------------------------------------------------------------------------
Linear Regression Model Specification (regression)
Main Arguments:
penalty = 0.0278255940220712
mixture = 1
Computational engine: glmnet
Все идет нормально. Теперь я хочу применить рабочий процесс к обучающим данным, чтобы получить окончательную модель:
final_mod <- fit(final_wf, data = dt_train) %>%
pull_workflow_fit()
Теперь вот в чем проблема.
final_mod$fit
- это объект elnet
и glmnet
. Он содержит полный путь регуляризации в сетке из 75 значений параметра штрафа. Следовательно, предыдущий шаг настройки штрафа практически бесполезен. Итак, шаг предсказания не удался:
predict(final_mod, new_data = dt)
возвращает ошибку:
Error in cbind2(1, newx) %*% nbeta :
invalid class 'NA' to dup_mMatrix_as_dgeMatrix
Конечно, я мог бы использовать glmnet::cv.glmnet
, чтобы получить наилучшее наказание, а затем использовать метод predict.cv.glmnet
, но мне нужен общий рабочий процесс, способный работать с несколькими моделями машинного обучения с использованием одного и того же интерфейса. В документации parsnip::linear_reg
есть следующее примечание относительно механизма glmnet:
Для моделей glmnet полный путь регуляризации всегда подходит, независимо от значения, присвоенного штрафу. Кроме того, в аргумент штрафа можно передать несколько значений (или без значений). При использовании метода predic () в этих случаях возвращаемое значение зависит от значения штрафа. При использовании pred () можно использовать только одно значение штрафа. При прогнозировании нескольких штрафов можно использовать функцию multi_predict (). Он возвращает тиббл со столбцом списка с именем .pred, который содержит тиббл со всеми результатами штрафа.
Однако я не понимаю, как мне поступить, чтобы получить прогнозы настроенной модели LASSO с использованием tidymodels
фреймворка. Функция multi_predict
выдает ту же ошибку, что и predict
.
predict(final_mod, new_data = dt)
. - person desertnaut   schedule 15.03.2021