Problemas na função prep e tunagem de hiperparâmetro - ML

Bom dia!
Tudo bom?

Estou fazendo a atividade final do curso de introdução a machine learning e algumas dúvidas estão surgindo na parte usar o pacote recipes. Tentei buscar ajuda por meio desse link. Mas ainda restam dúvidas.

Segue o código. Suprimi a parte de análise exploratória para diminuir o código

library(tidymodels); library(skimr); library(vip); library(naniar)

# configurando ambiente ---------------------------------------------------

setwd("~/Curso/R/Machine Learning/TCC do curso")

adult <- readRDS("~/Curso/R/Machine Learning/TCC do curso/adult.rds")

adult <- adult %>% select(-id)

# Separando treino e teste ------------------------------------------------

adult_initial_split <- initial_split(adult, strata = "resposta", p = 0.75)

adult_train <- training(adult_initial_split)
adult_test  <- testing(adult_initial_split)

# Data prep ---------------------------------------------------------------

adult_receita <- recipe(resposta ~ ., data = adult_train) %>%
  step_impute_bag(workclass, occupation, native_country) %>%
  step_zv(all_predictors()) %>%
  step_normalize(all_numeric()) %>%
  step_dummy(all_nominal(), -all_outcomes()) 

receita_treinada <- prep(adult_receita)

################ Regressão logística 

# Modelos Regressão logística ----------------------------------------------

adult_model <- logistic_reg(penalty = tune(), mixture = tune()) %>%
  set_mode("classification") %>%
  set_engine("glmnet")

adult_workflow <- workflow() %>% 
  add_model(adult_model) %>% 
  add_recipe(adult_receita)

# Tunagem Regressão Logística ---------------------------------------------

adult_resamples <- vfold_cv(adult_train, v = 5)

adult_lr_tune_grid <- tune_grid(
  adult_workflow,
  resamples = adult_resamples,
  metrics = metric_set(
    accuracy, 
    kap, # KAPPA 
    roc_auc, 
    precision, 
    recall, 
    f_meas, 
    mn_log_loss),
    control = control_grid(verbose = TRUE, allow_par = FALSE)
)

Dúvidas:

  1. Quando eu rodo a linha que tem a função prep meu R demora muito e não gera resultado. Já tentei reiniciar, mas sem sucesso.

  2. Após ver alguns exemplos de scripts das aulas, vi que precisava apenas do resultado da função recipe (adult_receita, nesse caso). Portanto, como consegui gerar o objeto adult_receita a partir do pacote recipe, segui para a criação do workflow. Porém, quando chego na tunagem de hiperparâmetros, também não consigo avançar. A barrinha do control_grid não sai do lugar.

  3. Como o resultado do prep (receita_treinada) não foi usado no workflow não consegui entender bem para que eu utilizaria o prep.

Desde já, obrigado pelo suporte!

Daniel, consegui reproduzir aqui exatamente o seu problema. Solucionei com

step_impute_bag(workclass, occupation, native_country, impute_with = imp_vars(age, fnlwgt))

Ou seja: é melhor escolher com quais variáveis explicativas vc vai construir os imputadores. O problema tava acontecendo pq o imputador tava usando todas as variáveis e provavelmente alguma delas estava fazendo o modelo ficar muito pesado e demorado.

Coloquei age e fnlwgt como exemplo, mas vc pode experimentar outras variáveis lá!!

OBS1: suspeito que a variável vilã seja a variável native_country que tem 42 categorias diferentes. Talvez valha a pena passar um step_other() nela antes pra diminuir o número de categs! Ou até fazer embed como por exemplo embed::step_woe().

OBS2: também há maneiras mais leves de imputação como o recipes::step_impute_linear() e etc.

Sobre o prep:

Você tem razão. Você não precisa rodar o prep() durante o workflow de modelagem. Mas ela serve para você dar uma olhadela em como a base de dados vai entrar nos seus modelos durante os ajustes de modelos.

A função prep(receita) é “treinar” a receita, ou seja, calcular de fato o que será feito de mudanças na base. Por exemplo: qdo vc define que quer o step_zv(all_predictors()), a receita ainda não sabe quais colunas serão excluídas. Depois do prep(), ela passará a saber pq já estará “preparada” (ou “treinada”).

Olha a diferença nos outputs:

receita
# Bagged tree imputation for workclass, occupation, native_country
# Zero variance filter on all_predictors()
# Centering and scaling for all_numeric()
# Dummy variables from all_nominal(), -all_outcomes()
prep(receita)
# Bagged tree imputation for workclass, occupation, native_country [trained]
# Zero variance filter removed no terms [trained]
# Centering and scaling for age, fnlwgt, education_num, capital_gain, capital_loss, hours_per_week [trained]
# Dummy variables from workclass, education, marital_status, occupation, relationship, race, sex, native_country [trained]

A função bake()

A função bake() serve para voce olhar a base final depois que tiver uma receita treinada pelo prep():

base_final <- bake(prep(adult_receita), new_data = NULL)
glimpse(base_final)
Rows: 24,420
Columns: 98
$ age                                       <dbl> 0.82882643~
$ fnlwgt                                    <dbl> -1.0055563~
$ education_num                             <dbl> 1.1343629,~
$ capital_gain                              <dbl> -0.146853,~
$ capital_loss                              <dbl> -0.2168958~
$ hours_per_week                            <dbl> -2.2021553~
$ resposta                                  <fct> <=50K, <=5~

Se você quiser aplicar a receita em uma outra base (que seja diferente da base de treino usada pra treinar a receita) vc pode usar o argumento new_data pra isso:

base_final <- bake(prep(adult_receita), new_data = base_nova)

A função juice()

A função juice() sugiro deixar pra lá. Na prática ela é um atalho. As duas linhas abaixo são idênticas:

bake(prep(adult_receita), new_data = NULL)
juice(prep(adult_receita))

No fundo, juice() é o bake(), mas sempre usando a base de treino como a base de dados a ser processada.

Vamos falando!

Muito bem observado, Athos! Obrigado! Vou testar após os ajustes! Valeu! :wink:

1 Curtida