Pesquisa em grade e otimização de hiperparâmetros bayesiano usando pacotes {tune} e {caret}

cupom com desconto - o melhor site de cupom de desconto cupomcomdesconto.com.br


[Esteartigofoipublicadopelaprimeiravezem[Thisarticlewasfirstpublishedon Programação R – DataScience +, e gentilmente contribuiu para os R-blogueiros]. (Você pode relatar um problema sobre o conteúdo desta página aqui)


Deseja compartilhar seu conteúdo com R-blogueiros? clique aqui se você tiver um blog ou aqui se não tiver.

Você está interessado em postar comentários? Publique no DataScience + através do seu editor RStudio.

Categoria

  • Modelagem Avançada

Tag

  • Otimização Bayesiana
  • acento circunflexo
  • classificação
  • Machine Learning
  • Programação R

A priori, não há garantia de que o hiperparâmetro de ajuste (HP) melhore o desempenho de um modelo de aprendizado de máquina disponível.
Neste blog, os métodos Grid Search e otimização bayesiana implementados no pacote {tune} serão usados ​​para realizar o ajuste do hiperparâmetro e verificar se a otimização do hiperparâmetro fornece melhor desempenho.

Também conduziremos a otimização do hiperparamater usando o pacote {caret}, isso permitirá comparar o desempenho dos dois pacotes {tune} e {caret}.

Fluxo de trabalho de alto nível

A figura a seguir mostra o fluxo de trabalho de alto nível para executar o ajuste do hiperparâmetro:

Métodos de otimização de hiperparâmetros

Ao contrário dos parâmetros do modelo, descobertos pelo algoritmo de aprendizado do modelo ML, o chamado hiperparâmetro (HP) não é aprendido durante o processo de modelagem, mas é especificado antes do treinamento.

O ajuste do hiperparâmetro é a tarefa de encontrar o (s) hiperparâmetro (s) ideal (is) para um algoritmo de aprendizado para um conjunto de dados específico e, no final do dia, para melhorar o desempenho do modelo.

Existem três métodos principais para ajustar / otimizar hiperparâmetros:

a) Método de pesquisa em grade: uma pesquisa exaustiva (pesquisa cega / pesquisa não guiada) sobre um subconjunto especificado manualmente do espaço do hiperparâmetro. Esse método é uma opção computacionalmente cara, mas garantida para encontrar a melhor combinação em sua grade especificada.

b) Método de busca aleatória: uma alternativa simples e semelhante ao método de busca em grade, mas a grade é selecionada aleatoriamente. Esse método (também pesquisa cega / pesquisa não guiada) é mais rápido na obtenção de um modelo razoável, mas não obtém o melhor da sua grade.

c) Método de pesquisa informada:
Na pesquisa informada, cada iteração aprende desde a última, os resultados de um modelo ajuda a criar o próximo modelo.

O método de pesquisa informado mais popular é a Otimização Bayesiana. A otimização bayesiana foi originalmente projetada para otimizar as funções da caixa preta. Para entender o conceito de otimização bayesiana, este artigo e isso são altamente recomendados.

Neste post, focaremos em dois métodos para ajuste automatizado de hiperparâmetros, Grid Search e otimização bayesiana.
Otimizaremos o hiperparâmetro de uma máquina florestal aleatória usando a biblioteca de sintonização e outros pacotes necessários (fluxos de trabalho, mostradores …).

Preparando os dados

O problema de aprendizagem (como exemplo) é o problema de classificação binária; prever rotatividade de clientes. Usaremos o conjunto de dados Telco Customer Churn também disponível aqui.

Carregue as bibliotecas necessárias.

# Needed packages  
library(tidymodels)   # packages for modeling and statistical analysis
library(tune)         # For hyperparemeter tuning
library(workflows)    # streamline process
library(tictoc)       # for timimg

Carregue dados e explore-os.

# load data
Telco_customer <- read.csv("WA_Fn-UseC_-Telco-Customer-Churn.csv")
# Get summary of the data
skimr::skim(Telco_customer)
Nome Telco_customer
Numero de linhas 7043
Numero de colunas 21
_______________________
Frequência do tipo de coluna:
fator 17
numérico 4
________________________
Variáveis ​​de grupo Nenhum

Tipo de variável: fator

skim_variable n_missing complete_rate ordenou n_unique top_counts
Identificação do Cliente 0 0 1 FALSO 7043 000: 1, 000: 1, 000: 1, 001: 1
gênero 0 0 1 FALSO 2 Mal: 3555, Fem: 3488
Parceiro 0 0 1 FALSO 2 Não: 3641, Sim: 3402
Dependentes 0 0 1 FALSO 2 Não: 4933, Sim: 2110
PhoneService 0 0 1 FALSO 2 Sim: 6361, Não: 682
MultipleLines 0 0 1 FALSO 3 Não: 3390, Sim: 2971, Não: 682
Serviço de internet 0 0 1 FALSO 3 Fib: 3096, DSL: 2421, No: 1526
OnlineSecurity 0 0 1 FALSO 3 Não: 3498, Sim: 2019, Não: 1526
OnlineBackup 0 0 1 FALSO 3 Não: 3088, Sim: 2429, Não: 1526
Proteção de dispositivo 0 0 1 FALSO 3 Não: 3095, Sim: 2422, Não: 1526
Suporte técnico 0 0 1 FALSO 3 Não: 3473, Sim: 2044, Não: 1526
StreamingTV 0 0 1 FALSO 3 Não: 2810, Sim: 2707, Não: 1526
StreamingMovies 0 0 1 FALSO 3 Não: 2785, Sim: 2732, Não: 1526
Contrato 0 0 1 FALSO 3 Seg: 3875, Dois: 1695, Um: 1473
PaperlessBilling 0 0 1 FALSO 2 Sim: 4171, Não: 2872
Forma de pagamento 0 0 1 FALSO 4 Ele: 2365, Mai: 1612, Ban: 1544, Cre: 1522
Churn 0 0 1 FALSO 2 Não: 5174, Sim: 1869

Tipo de variável: numérico

skim_variable n_missing complete_rate significar SD p0 p25 p50 p75 p100 hist
SeniorCitizen 0 0 1 0,16 0,37 0,00 0,00 0,00 0,00 1,00 ▇▂
posse 0 0 1 32,37 24,56 0,00 9,00 29,00 55,00 72,00 ▇▃▃▃▆
Mensalmente 0 0 1 64,76 30.09 18,25 35,50 70,35 89,85 118,75 ▇▅▆▇▅
Custos totais 11 1 2283,30 2266.77 18,80 401,45 1397,47 3794.74 8684,80 ▇▂▂▂ ▇▂▂▂
# Make copy of Telco_customer and drop the unneeded columns
data_set %dplyr::select(-"customerID")
# Rename the outcome variable (Churn in my case) to Target
data_in_scope % plyr::rename(c("Churn" = "Target"))
# Drop rows with missing value(11 missing values, very small percentage of our total data)
data_in_scope % plyr::rename(c("Churn" = "Target"))%>%drop_na()

Verifique a gravidade do desequilíbrio de classe.

round(prop.table(table(data_in_scope$Target)), 2)
## 
##   No  Yes 
## 0.73 0.27

Para os dados disponíveis, não há necessidade de realizar downsampling ou upsampling, mas se você precisar equilibrar seus dados, poderá usar a função step_downsample () ou step_upsample () para reduzir o desequilíbrio entre a maioria e a classe minoritária.

Abaixo, dividiremos os dados em dados de treinamento e teste e criaremos novas amostras.
Os dados do teste são salvos para avaliação do modelo e os usaremos duas vezes, uma vez para avaliar o modelo com hiperparâmetro padrão e no final do processo de ajuste para testar os resultados do ajuste (avaliar o modelo ajustado final).

Durante o processo de ajuste, lidaremos apenas com as novas amostras criadas nos dados de treinamento. No meu exemplo, usaremos a validação cruzada de dobras em V para dividir os dados de treinamento em 5 dobras e a repetição consiste em 2 iterações.

# Split data into train and test data and create resamples for tuning
set.seed(2020)
train_test_split_data <- initial_split(data_in_scope)
data_in_scope_train <- training(train_test_split_data)
data_in_scope_test <-  testing(train_test_split_data)
# create resammples
folds <- vfold_cv(data_in_scope_train, v = 5, repeats = 2)

Pré-processando os Dados

Criamos a receita e atribuímos as etapas para o pré-processamento dos dados.

#  Pre-Processing the data with{recipes}
  set.seed(2020)
  rec %   # Fomula
  step_dummy(all_nominal(), -Target) %>%          # convert nominal data into one or more numeric.
  step_corr(all_predictors()) %>%                 # remove variables that have large absolute 
                                                     # correlations with other variables.
  step_center(all_numeric(), -all_outcomes())%>%  # normalize numeric data to have a mean of zero.
  step_scale(all_numeric(), -all_outcomes())         # normalize numeric data to have a standard deviation of one.
  # %>%step_downsample(Target)                    # all classes should have the same frequency as the minority 
                                                     # class(not needed in our case)

Em seguida, treinaremos os dados da receita. Os dados treinados (train_data e test_data) serão usados ​​para modelar e ajustar o modelo usando o hiperparâmetro padrão do modelo em questão. O desempenho do modelo é determinado pela AUC (Área sob a Curva ROC), que será calculada através da função roc_auc {critério}. Esse valor da AUC será usado como valor de referência para verificar se a otimização dos hiperparâmetros leva a um melhor desempenho ou não.

trained_rec<-  prep(rec, training = data_in_scope_train, retain = TRUE)
# create the train and test set 
train_data <- as.data.frame(juice(trained_rec))
test_data  <- as.data.frame( bake(trained_rec, new_data = data_in_scope_test))

O modelo

Usaremos a função {parsnip} rand_forest () para criar um modelo de floresta aleatório e adicionar o pacote r ranger “ranger” como o mecanismo computacional.

# Build the model (generate the specifications of the model) 
model_spec_default %set_engine("ranger", verbose = TRUE)

Ajuste o modelo nos dados de treinamento (train_data preparado acima)

set.seed(2020) 
tic()
# fit the model
model_fit_default %fit(Target ~ . , train_data )
toc()
## 2.37 sec elapsed
# Show the configuration of the fitted model
model_fit_default
## parsnip model object
## 
## Fit time:  1.5s 
## Ranger result
## 
## Call:
##  ranger::ranger(formula = formula, data = data, verbose = ~TRUE,      num.threads = 1, seed = sample.int(10^5, 1), probability = TRUE) 
## 
## Type:                             Probability estimation 
## Number of trees:                  500 
## Sample size:                      5274 
## Number of independent variables:  23 
## Mtry:                             4 
## Target node size:                 10 
## Variable importance mode:         none 
## Splitrule:                        gini 
## OOB prediction error (Brier s.):  0.1344156

Preveja os dados de teste (test_data) e extraia o desempenho do modelo. Como esse modelo é executado em relação aos dados de validação (dados_de_teste, não vistos antes)?

# Performance and statistics: 
set.seed(2020)
 test_results_default %
   select(Target) %>%
   as_tibble() %>%
   mutate(
     model_class_default = predict(model_fit_default, new_data = test_data) %>% 
       pull(.pred_class),
     model_prob_default  = predict(model_fit_default, new_data = test_data, type = "prob") %>% 
       pull(.pred_Yes))

A AUC computada é apresentada aqui:

# Compute the AUC value
auc_default % roc_auc(truth = Target, model_prob_default) 
cat("The default model scores", auc_default$.estimate, " AUC on the testing data")
## The default model scores 0.8235755  AUC on the testing data
# Here we can also compute the confusion matrix 
conf_matrix %conf_mat(truth = Target, model_class_default)

Como podemos ver, o modelo padrão não apresenta desempenho ruim, mas o modelo ajustado ofereceria melhor desempenho?

Leia Também  Obrigado "Por que R?" por ser anfitriões impressionantes

Ajuste do hiperparâmetro usando {tune}.

O ajuste do hiperparâmetro usando o pacote {tune} será executado para o modelo de pastinaga rand_forest e usaremos o ranger como o mecanismo computacional. A lista de modelos {parsnip} pode ser encontrada aqui

Na próxima seção, definiremos e descreveremos os elementos necessários para a função de ajuste tun _ * () (tune_grid () para Pesquisa em Grade e tune_bayes () para Otimização Bayesiana)

Especificação dos ingredientes para a função de sintonia

Preparando os elementos necessários para a função de ajuste tune _ * ()

  1. modelo a ser ajustado: construa o modelo com o pacote {parsnip} e especifique os parâmetros que queremos ajustar. Nosso modelo possui três hiperparâmetros importantes:
    • mtry: é o número de preditores que serão amostrados aleatoriamente em cada divisão ao criar os modelos de árvore. (Os valores padrão são diferentes para classificação (sqrt (p) e regressão (p / 3) em que p é o número de variáveis ​​no conjunto de dados))
    • trees: é o número de árvores contidas no conjunto (padrão: 500)
    • min_n: é o número mínimo de pontos de dados em um nó (valor padrão: 1 para classificação e 5 para regressão)
      Os parâmetros mtry, trees e min_n criam o hiperparâmetro configurado para ajustar.
# Build the model to tune and leave the tuning parameters empty (Placeholder with the tune() function)
model_def_to_tune % # min_n is the minimum number of data points in a node 
                                                        #that are required for the node to be split further. 
                                 set_engine("ranger") #  computational engine
  1. Crie o objeto do fluxo de trabalho {workflows}
    O fluxo de trabalho é um objeto de contêiner que agrega informações necessárias para ajustar e prever a partir de um modelo. Essas informações podem ser uma receita usada no pré-processamento, especificada por meio de add_recipe () ou a especificação do modelo a ser ajustada, especificada por meio de add_model ().

No nosso exemplo, combinamos a receita (rc) e o model_def_to_tune em um único objeto (model_wflow) por meio da função workflow () do pacote {workflows}.

# Build the workflow object
model_wflow %
  add_model(model_def_to_tune) %>%
  add_recipe(rec)

Obtenha informações sobre todos os argumentos possíveis de ajuste no fluxo de trabalho definido (model_wflow) e verifique se eles são realmente ajustáveis ​​ou não.

tune_args(model_wflow)
## # A tibble: 3 x 6
##   name  tunable id    source     component   component_id
##                            
## 1 mtry  TRUE    mtry  model_spec rand_forest         
## 2 trees TRUE    trees model_spec rand_forest         
## 3 min_n TRUE    min_n model_spec rand_forest 
  1. Finalize o conjunto de hiperparâmetros a ser ajustado.
    A atualização dos parâmetros será feita através da função finalize {dials}.
# Which parameters have been collected ?
HP_set <- parameters(model_wflow)
HP_set
## Collection of 3 parameters for tuning
## 
##     id parameter type object class
##   mtry           mtry    nparam[?]
##  trees          trees    nparam[+]
##  min_n          min_n    nparam[+]
## 
## Model parameters needing finalization:
##    # Randomly Selected Predictors ('mtry')
## 
## See `?dials::finalize` or `?dials::update.parameters` for more information.
# Update the parameters which denpends on the data (in our case mtry)
without_output <- select(data_in_scope_train, -Target)
HP_set <- finalize(HP_set, without_output)
HP_set
## Collection of 3 parameters for tuning
## 
##     id parameter type object class
##   mtry           mtry    nparam[+]
##  trees          trees    nparam[+]
##  min_n          min_n    nparam[+]

Agora, temos todo o material necessário para executar o processo de otimização, mas antes de avançarmos e iniciarmos o processo de Pesquisa em grade, uma função de empacotador (my_finalize_func) será criada, é necessário o resultado do processo de ajuste, o objeto de receita, para ajustar como argumentos, finalize a receita e o modelo ajustado e retorne o valor da AUC, a matriz de confusão e a curva ROC. Esta função será aplicada nos resultados da pesquisa em grade e no processo de otimização bayesiana.

cupom com desconto - o melhor site de cupom de desconto cupomcomdesconto.com.br
# Function to finalliaze the recip and the model and returne the AUC value and the ROC curve of the tuned model.  

my_finalize_func <- function(result_tuning, my_recipe, my_model) {

# Accessing the tuning results
  bestParameters <- select_best(result_tuning, metric = "roc_auc", maximize = TRUE)

# Finalize recipe
  final_rec %
    finalize_recipe(bestParameters) %>%
    prep()

# Attach the best HP combination to the model and fit the model to the complete training data(data_in_scope_train) 
  final_model %
    finalize_model(bestParameters) %>%
    fit(Target ~ ., data = juice(final_rec))

# Prepare the finale trained data to use for performing model validation. 
  df_train_after_tuning <- as.data.frame(juice(final_rec)) 
  df_test_after_tuning <- as.data.frame(bake(final_rec, new_data = data_in_scope_test))

  # Predict on the testing data 
set.seed(2020)
  results_ %
    select(Target) %>%
    as_tibble()%>%
    mutate(
      model_class = predict(final_model, new_data = df_test_after_tuning) %>% 
        pull(.pred_class),
      model_prob  = predict(final_model, new_data = df_test_after_tuning, type = "prob") %>% 
        pull(.pred_Yes))
# Compute the AUC  
  auc % roc_auc(truth = Target, model_prob)
# Compute the confusion matrix
  confusion_matrix <- conf_mat(results_, truth= Target, model_class)
# Plot the ROC curve
  rocCurve %
    ggplot(aes(x = 1 - specificity, y = sensitivity)) +
    geom_path(colour = "darkgreen", size = 1.5) +
    geom_abline(lty = 3, size= 1, colour = "darkred") +
    coord_equal()+
    theme_light()

    new_list <- list(auc, confusion_matrix, rocCurve)  
return(new_list)
}

Ajuste de hiperparâmetros via Grid Search

Para executar o processo de pesquisa em grade, precisamos chamar a função tune_grid (). O tempo de execução será estimado através do pacote {tictoc}.

# Perform Grid Search 
set.seed(2020)
tic() 
results_grid_search <- tune_grid(
  model_wflow,                       # Model workflow defined above
  resamples = folds,                 # Resamples defined obove
  param_info = HP_set,               # HP Parmeter to be tuned (defined above) 
  grid = 10,                         # number of candidate parameter sets to be created automatically
  metrics = metric_set(roc_auc),     # metric
  control = control_grid(save_pred = TRUE, verbose = TRUE) # controle the tuning process
)

results_grid_search
## #  5-fold cross-validation repeated 2 times 
## # A tibble: 10 x 6
##    splits              id      id2   .metrics          .notes           .predictions         
##  *                                                         
##  1  Repeat1 Fold1   
##  2  Repeat1 Fold2   
##  3  Repeat1 Fold3   
##  4  Repeat1 Fold4   
##  5  Repeat1 Fold5   
##  6  Repeat2 Fold1   
##  7  Repeat2 Fold2   
##  8  Repeat2 Fold3   
##  9  Repeat2 Fold4   
## 10  Repeat2 Fold5   
toc()
## 366.69 sec elapsed

Processo de Pesquisa em Grade de Resultados

Resultados do processo de Pesquisa em Grade executado:

  • Melhor combinação de hiperparâmetros obtida pelo processo de Pesquisa em grade:
# Select best HP combination
best_HP_grid_search <- select_best(results_grid_search, metric = "roc_auc", maximize = TRUE)
best_HP_grid_search
## # A tibble: 1 x 3
##    mtry trees min_n
##     
## 1     1  1359    16
  • Desempenho: valor da AUC, matriz de confusão e curva ROC (modelo ajustado via Grid Search):
# Extract the AUC value, confusion matrix and the roc vurve with my_finalize_func function
Finalize_grid <- my_finalize_func(results_grid_search, rec, model_def_to_tune)
cat("Model tuned via Grid Search scores an AUC value of ", Finalize_grid[[1]]$.estimate, "on the testing data", "n")
## Model tuned via Grid Search scores an AUC value of  0.8248226 on the testing data
cat("The Confusion Matrix", "n")
## The Confusion Matrix
print(Finalize_grid[[2]])
##           Truth
## Prediction   No  Yes
##        No  1268  404
##        Yes   19   67
cat("And the ROC curve:", "n")
## And the ROC curve:
print(Finalize_grid[[3]])

Concluímos o método Grid Search, agora vamos iniciar o processo de hiperparâmetro Bayesiano.

Ajuste de hiperparâmetro Bayesian com pacote de sintonia

Como a Otimização de hiperparâmetros bayesiana com o pacote {tune} funciona?

No vinheta 'ajuste' do pacote, a otimização começa com um conjunto de resultados iniciais, como os gerados por tune_grid (). Se não existir, a função criará várias combinações e obterá suas estimativas de desempenho. Usando uma das estimativas de desempenho como resultado do modelo, um modelo de processo Gaussiano (GP) é criado onde as combinações de parâmetros de ajuste anteriores são usadas como preditores. Uma grande grade de combinações de hiperparâmetros em potencial é prevista usando o modelo e pontuada usando uma função de aquisição. Essas funções geralmente combinam a média e a variação previstas do GP para decidir a melhor combinação de parâmetros para tentar a seguir. Para obter mais informações, consulte a documentação de exp_improve () e a vinheta de pacote correspondente. A melhor combinação é avaliada usando reamostragem e o processo continua.

Para o nosso exemplo, definimos os argumentos da função tune_bayes () da seguinte maneira:

# Start the Baysian HP search process
set.seed(1291)
tic()
search_results_bayesian <- tune_bayes(
    model_wflow,                              # workflows object defined above             
    resamples = folds,                        # rset() object defined above
    param_info = HP_set,                      # HP set defined above (updated HP set)
    initial = 5 ,                             # here you could also use the results of the Grid Search
    iter = 10,                                # max number of search iterations
    metrics = metric_set(roc_auc),            # to optimize for the roc_auc metric 
    control = control_bayes(no_improve = 8,   # cutoff for the number of iterations without better results.
                            save_pred = TRUE, # output of sample predictions should be saved.
                            verbose = TRUE))

toc()
## 425.76 sec elapsed

Processo de Otimização Bayesiana

Resultados do processo de pesquisa de otimização bayesiana executado:

  • Melhor combinação de hiperparâmetros obtida pelo processo de Pesquisa em grade:
# Get the best HP combination
best_HP_Bayesian <- select_best(search_results_bayesian, metric = "roc_auc", maximize = TRUE)
best_HP_Bayesian
## # A tibble: 1 x 3
##    mtry trees min_n
##     
## 1     2  1391    17
  • Valor da AUC abstido com o modelo final (modelo ajustado via processo de otimização bayesiano):
# Build the final model (apply my_finalize_func)
Finalize_Bayesian <- my_finalize_func(search_results_bayesian, rec, model_def_to_tune)
# Get the AUC value
cat(" Tuned model via Bayesian method scores", Finalize_Bayesian[[1]]$.estimate, "AUC on the testing data", "n")
##  Tuned model via Bayesian method scores 0.8295968 AUC on the testing data
cat("The Confusion Matrix", "n")
## The Confusion Matrix
print(Finalize_Bayesian[[2]])
##           Truth
## Prediction   No  Yes
##        No  1178  263
##        Yes  109  208
cat("And the ROC curve:", "n")
## And the ROC curve:
print(Finalize_Bayesian[[3]])

Resumo de conquistas (com pacote {tune})

vamos resumir o que alcançamos com o Grid Search e a otimização bayesiana até agora.

# Build a new table with the achieved AUC's
xyz <- tibble(Method = c("Default", "Grid Search", "Bayesian Optimization"), 
                           AUC_value = c(auc_default$.estimate, Finalize_grid[[1]]$.estimate,  Finalize_Bayesian[[1]]$.estimate))

default_value <- c(mtry = model_fit_default$fit$mtry, trees=  model_fit_default$fit$num.trees,min_n = model_fit_default$fit$min.node.size)
vy <- bind_rows(default_value, best_HP_grid_search, best_HP_Bayesian )

all_HP <- bind_cols(xyz, vy)
all_HP%>%knitr::kable(
  caption = "AUC Values and the best hyperparameter combination: we can see that the Bayesian hyperparameter using the {tune} package improved the performance (AUC) of our model, but what about using the caret package ?")
Método AUC_value mtry árvores min_n
Padrão 0,8235755 4 500 10
Pesquisa em grade 0.8248226 1 1359 16
Otimização Bayesiana 0.8295968 2 1391 17

Agora, vamos ajustar o modelo usando o pacote {caret}

Ajuste do hiperparâmetro usando {caret}

Por padrão, a função de trem do pacote de interpolação cria automaticamente uma grade de parâmetros de ajuste, se p é o número de parâmetros de ajuste, o tamanho da grade é 3p. Porém, em nosso exemplo, definimos o número de combinações de hiperparâmetros como 10.

Pesquisa em grade via pacote {caret}

## 186.69 sec elapsed
# print the trained model
ranger_fit_grid
## Random Forest 
## 
## 5274 samples
##   23 predictor
##    2 classes: 'No', 'Yes' 
## 
## No pre-processing
## Resampling: Cross-Validated (5 fold, repeated 2 times) 
## Summary of sample sizes: 4219, 4220, 4219, 4219, 4219, 4219, ... 
## Resampling results across tuning parameters:
## 
##   mtry  splitrule   ROC        Sens       Spec     
##    2    gini        0.8500179  0.9224702  0.4832002
##    2    extratrees  0.8469737  0.9280161  0.4631669
##    4    gini        0.8438961  0.9044102  0.5186060
##    4    extratrees  0.8435452  0.9031199  0.5075128
##    6    gini        0.8378432  0.8984766  0.5203879
##    6    extratrees  0.8383252  0.9004117  0.5050090
##    9    gini        0.8336365  0.8958967  0.5175243
##    9    extratrees  0.8336034  0.8946059  0.5046544
##   11    gini        0.8317812  0.8929298  0.5221736
##   11    extratrees  0.8313396  0.8918976  0.5092947
##   13    gini        0.8295577  0.8948648  0.5146633
##   13    extratrees  0.8296291  0.8900928  0.5067934
##   16    gini        0.8280568  0.8906072  0.5243203
##   16    extratrees  0.8282040  0.8893184  0.5032220
##   18    gini        0.8266870  0.8908655  0.5218139
##   18    extratrees  0.8270139  0.8891897  0.5089542
##   20    gini        0.8259053  0.8899628  0.5196672
##   20    extratrees  0.8264358  0.8884154  0.5064388
##   23    gini        0.8242706  0.8895753  0.5182373
##   23    extratrees  0.8259214  0.8884169  0.5025051
## 
## Tuning parameter 'min.node.size' was held constant at a value of 1
## ROC was used to select the optimal model using the largest value.
## The final values used for the model were mtry = 2, splitrule = gini and min.node.size = 1.
# Predict on the testing data
model_class_gr <- predict(ranger_fit_grid, newdata = test_data)
model_prob_gr <- predict(ranger_fit_grid, newdata = test_data, type = "prob")

test_data_with_pred_gr %
  select(Target)%>%as_tibble()%>%
  mutate(model_class_ca = predict(ranger_fit_grid, newdata = test_data),
  model_prob_ca = predict(ranger_fit_grid, newdata = test_data, type= "prob")$Yes)

AUC alcançada através do pacote Caret depois de ajustar o hiperparâmetro via Grid Search

# Compute the AUC
auc_with_caret_gr % yardstick::roc_auc(truth=Target, model_prob_ca)
cat("Caret model via Grid Search method scores" , auc_with_caret_gr$.estimate , "AUC on the testing data")
## Caret model via Grid Search method scores 0.8272427 AUC on the testing data

Método de Reamostragem Adaptativa

Usaremos o método de ajuste avançado, o método de Reamostragem Adaptativa. Esse método faz uma nova amostra das combinações de hiperparâmetro com valores próximos a combinações que tiveram bom desempenho. Este método é mais rápido e mais eficiente (cálculos desnecessários são evitados).

set.seed(2020)
tic()
fitControl <- trainControl(
                    method = "adaptive_cv",
                    number = 5,  repeats = 4,               # Crossvalidation(20 Folds will be created)
                    adaptive = list(min =3,                 # minimum number of resamples per hyperparameter
                                    alpha =0.05,            # Confidence level for removing hyperparameters
                                    method = "BT",# Bradly-Terry Resampling method (here you can instead also use "gls")
                                    complete = FALSE),      # If TRUE a full resampling set will be generated 
                    search = "random",
                    summaryFunction = twoClassSummary,
                    classProbs = TRUE)

ranger_fit <- train(Target ~ ., 
                    metric = "ROC",
                    data = train_data, 
                    method = "ranger", 
                    trControl = fitControl, 
                    verbose = FALSE, 
                    tuneLength = 10)                      # Maximum number of hyperparameter combinations


toc()
## 22.83 sec elapsed
## Random Forest 
## 
## 5274 samples
##   23 predictor
##    2 classes: 'No', 'Yes' 
## 
## No pre-processing
## Resampling: Adaptively Cross-Validated (5 fold, repeated 4 times) 
## Summary of sample sizes: 4219, 4220, 4219, 4219, 4219, 4219, ... 
## Resampling results across tuning parameters:
## 
##   min.node.size  mtry  splitrule   ROC        Sens       Spec       Resamples
##    1             16    extratrees  0.8258154  0.8882158  0.5262459  3        
##    4              2    extratrees  0.8459167  0.9303470  0.4617981  3        
##    6              3    extratrees  0.8457763  0.9118612  0.5238479  3        
##    8              4    extratrees  0.8457079  0.9071322  0.5310207  3        
##   10             16    gini        0.8341897  0.8912221  0.5286226  3        
##   10             18    extratrees  0.8394607  0.8972503  0.5369944  3        
##   13              8    extratrees  0.8456075  0.9058436  0.5405658  3        
##   17              2    gini        0.8513404  0.9256174  0.4892473  3        
##   17             22    extratrees  0.8427424  0.8985379  0.5453320  3        
##   18             14    gini        0.8393974  0.8989635  0.5286226  3        
## 
## ROC was used to select the optimal model using the largest value.
## The final values used for the model were mtry = 2, splitrule = gini and min.node.size = 17.
# Predict on the testing data
test_data_with_pred %
  select(Target)%>%as_tibble()%>%
  mutate(model_class_ca = predict(ranger_fit, newdata = test_data),
  model_prob_ca = predict(ranger_fit, newdata = test_data, type= "prob")$Yes)

AUC obtida via pacote Caret usando o Método de Reamostragem Adaptativa

# Compute the AUC value
auc_with_caret % yardstick::roc_auc(truth=Target, model_prob_ca)
cat("Caret model via  Adaptive Resampling Method scores" , auc_with_caret$.estimate , " AUC on the testing data")
## Caret model via  Adaptive Resampling Method scores 0.8301066  AUC on the testing data

Resultados resumidos

Conclusão e Perspectivas

Neste estudo de caso, usamos os pacotes {tune} e {caret} para ajustar o hiperparâmetro.

A) Usando o pacote {tune}, aplicamos o método Grid Search e o método de otimização bayesiano para otimizar mtry, árvores e hiperparâmetro min_n do algoritmo de aprendizado de máquina “ranger” e descobrimos que:

  1. comparado ao uso dos valores padrão, nosso modelo usando valores de hiperparâmetros ajustados teve melhor desempenho.
  2. o modelo ajustado via método de otimização bayesiano tem melhor desempenho do que o método Grid Search

B) E, usando o pacote {caret}, aplicamos o método Grid Search e o Adaptive Resampling Method para otimizar mtry, splitrule, min.node.size e descobrimos que:

  1. comparado ao uso dos valores padrão, nosso modelo usando valores de hiperparâmetros ajustados teve melhor desempenho.
  2. o modelo ajustado por meio do método de reamostragem adaptativa tem um desempenho melhor que o método de pesquisa em grade.
  3. comparado ao uso do novo pacote relativo {tune}, nosso modelo usando o pacote antigo {caret} teve melhor desempenho.

Os resultados de nossos experimentos de ajuste de hiperparâmetro são exibidos na tabela a seguir:

xyz <- tibble(Method = c("Default", "Grid Search", "Bayesian Optimization", 
                         "Grid Search Caret", "Adaptive Resampling Method"), 
              AUC_value = c(auc_default$.estimate, 
                            Finalize_grid[[1]]$.estimate,  
                            Finalize_Bayesian[[1]]$.estimate, 
                            auc_with_caret_gr$.estimate, 
                            auc_with_caret$.estimate))
Método AUC_value
Padrão 0,8235755
Pesquisa em grade 0.8248226
Otimização Bayesiana 0.8295968
Caret de pesquisa em grade 0.8272427
Método de Reamostragem Adaptativa 0.8301066

Certamente, esses resultados dependem do conjunto de dados usado e da configuração definida (reamostragem, número de iterações, validação cruzada, etc.), você pode chegar a uma conclusão diferente se usar outro conjunto de dados com configuração diferente, mas independentemente disso Dependência, nosso estudo de caso mostra que o esforço de codificação feito para o ajuste de hiperparâmetros usando a biblioteca tidymodels é alto e complexo em comparação com o esforço feito usando o pacote de intercalação. O pacote de intercalação é mais eficaz e leva a um melhor desempenho.
Atualmente, estou trabalhando em um novo aplicativo brilhante, que podemos usar para ajustar o hiperparâmetro de quase todos os modelos {parsnip} usando o pacote {tune} e, dessa forma, podemos reduzir a complexidade e o esforço de codificação.

Obrigado pelo seu feedback também em [email protected]

Post relacionado

  • K-vizinho mais próximo para a previsão de diabetes no NHANES
  • Selecionando recursos categóricos na previsão de atrito do cliente usando Python
  • Explicação do modelo com o aplicativo brilhante BMuCaret usando os pacotes IML e DALEX
  • Análise de componente principal (PCA) com Python
  • K significa clustering com Python

var vglnk = {key: '949efb41171ac6ec1bf7f206d57e90b8'};

(função (d, t) {
var s = d.createElement
s.src = '//cdn.viglink.com/api/vglnk.js';
var r = d.getElementsByTagName
} (documento, 'script'));

Para Deixe um comentário para o autor, siga o link e comente no blog: Programação R - DataScience +.

R-bloggers.com oferece atualizações diárias por email sobre notícias e tutoriais do R sobre o aprendizado do R e muitos outros tópicos. Clique aqui se você deseja publicar ou encontrar um emprego em ciência da dados / R.


Deseja compartilhar seu conteúdo com R-blogueiros? clique aqui se você tiver um blog ou aqui se não tiver.



cupom com desconto - o melhor site de cupom de desconto cupomcomdesconto.com.br