Função para Tunar modelo de XGBoost
Motivação
Este material foi feito inspirado pelo curso de R para Machine Learning, ministrado pela Curso-R, em que mostra uma heurística sobre a tunagem do Modelo de XGBoost. O material está disponível para qualquer pessoa neste link, baixando o arquivo exemplos/12-xgboost.Rmd.
O que é XGBoost?
O modelo de XGBoost é uma extensão do Gradiente Boost, que é um modelo baseado em árvores. Se você deseja entender melhor o que é isso, sugiro este material e o repositória que está exposto nele.
Bom, o XGBoost conta com sete hiperparâmetros para encontrarmos a melhor combinação de um modelo. De que forma fazemos isso? Através da tunagem dos hiperparâmeros. Porém, quanto maior o número destes, mais demorado será a execução do modelo e maior capacidade computacional você vai precisar.
Se tivéssemos uma máquina com memória infinita, poderíamos testar infinitas possibilidades de hiperparâmetros para encontrarmos os melhores possíveis. No entando, sabemos que: uma máquina infinita custa infinitos dinheiros (R$) e ainda sim não conseguiria testar infinitas combinações e; se rodarmos em nuvem infinitamente isso, pode nos gerar também uma quantia absurda.
Com isso, foram criadas diversar maneiras de executar essa tunagem, e aqui, vou expor, em forma de função, a maneira que aprendi no curso que fiz, como falei anteriormente.
Porque uma função para tunar XGBoost?
Muitas vezes, no nosso dia a dia, estamos bem atarefados com nossos afazeres. Na minha experiência pessoal, sempre gosto de entender melhor qualquer situação problema que vem até mim, cada particularidade e cada circunstância. No entando, isso nem sempre é possível. Com isso, algo que me facilite a execução deste processo de tunagem foi bem pertinente.
Outro motivo que me fez montar essa função, foi o fato de que sempre é bom ter um “chute inicial” para os nossos trabalhos. Como já dizia o filósofo: Nada se cria, tudo se copia. Resumindo, com esta função tenho bons hiperparâmetros iniciais para que, caso eu queira, posteriormente, conseguir ajustar meu modelo.
Modelagem
Sem mais delongas, agora vamos a um teste de modelagem com a função de tunagem do XGBoost. Caso queira ter acesso a ela, só baixar o script e utilizar a função source("nome do arquivo") no seu script de modelagem.
Base trabalhada
Como sou da área de People Analytics, trabalharei com uma base que utilizo sempre de funcionários de uma empresa, onde contém informações de colaboradores desligados e ativos da mesma. Como este não é o foco deste material, não vamos nos aprofundar nas questões fora da função de tunagem.
Abaixo temos as variáveis trabalhadas e suas informações de estrutura:
| Name | Piped data |
| Number of rows | 14999 |
| Number of columns | 8 |
| _______________________ | |
| Column type frequency: | |
| numeric | 8 |
| ________________________ | |
| Group variables | None |
Variable type: numeric
| skim_variable | n_missing | complete_rate | mean | sd | p0 | p25 | p50 | p75 | p100 | hist |
|---|---|---|---|---|---|---|---|---|---|---|
| nivel_satisfacao | 0 | 1 | 0.61 | 0.25 | 0.09 | 0.44 | 0.64 | 0.82 | 1 | ▃▅▇▇▇ |
| ultima_avaliacao | 0 | 1 | 0.72 | 0.17 | 0.36 | 0.56 | 0.72 | 0.87 | 1 | ▂▇▆▇▇ |
| atuacao_projetos | 0 | 1 | 3.80 | 1.23 | 2.00 | 3.00 | 4.00 | 5.00 | 7 | ▇▆▃▂▁ |
| horas_trabalhadas | 0 | 1 | 201.05 | 49.94 | 96.00 | 156.00 | 200.00 | 245.00 | 310 | ▃▇▆▇▂ |
| tempo_empresa | 0 | 1 | 3.50 | 1.46 | 2.00 | 3.00 | 3.00 | 4.00 | 10 | ▇▃▁▁▁ |
| licenca_medica | 0 | 1 | 0.14 | 0.35 | 0.00 | 0.00 | 0.00 | 0.00 | 1 | ▇▁▁▁▂ |
| desligado | 0 | 1 | 0.24 | 0.43 | 0.00 | 0.00 | 0.00 | 0.00 | 1 | ▇▁▁▁▂ |
| promocao_ultimos_3_anos | 0 | 1 | 0.02 | 0.14 | 0.00 | 0.00 | 0.00 | 0.00 | 1 | ▇▁▁▁▁ |
| Name | Piped data |
| Number of rows | 14999 |
| Number of columns | 2 |
| _______________________ | |
| Column type frequency: | |
| character | 2 |
| ________________________ | |
| Group variables | None |
Variable type: character
| skim_variable | n_missing | complete_rate | min | max | empty | n_unique | whitespace |
|---|---|---|---|---|---|---|---|
| area | 0 | 1 | 2 | 11 | 0 | 10 | 0 |
| salario | 0 | 1 | 4 | 7 | 0 | 3 | 0 |
Em um processo normal de estudo, jamais passaria para a próxima etapa sem antes fazer uma boa análise exploratória, a fim de entender as variáveis que estão na base e trabalhar possíveis tratamentos das mesmas.
Pré processamento
Nesta etapa faremos a transformação da variável independente, dividiremos a base de treino e teste e trataremos possíveis problemas que as variáveis dependentes tenham.
base <- base %>%
mutate(
desligado = as.factor(desligado)
)
set.seed(100)
treino_teste <- base %>% initial_split(0.7, strata = desligado)
base_treino <- training(treino_teste)
base_teste <- testing(treino_teste)
# Data prep
base_recipe <- recipe(
desligado ~., data = base_treino
) %>%
step_zv(all_predictors()) %>%
step_modeimpute(all_nominal(), -all_outcomes()) %>%
step_medianimpute(all_numeric()) %>%
step_novel(all_nominal(), -all_outcomes()) %>%
step_dummy(all_nominal(), -all_outcomes())No final do processo nossa base ficará assim:
| nivel_satisfacao | ultima_avaliacao | atuacao_projetos | horas_trabalhadas | tempo_empresa | licenca_medica | promocao_ultimos_3_anos | desligado | area_comercial | area_executivos | area_financeiro | area_marketing | area_medica | area_pessoas | area_producao_ac | area_supply | area_TI | area_new | salario_baixo | salario_mediano | salario_new |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0.10 | 0.77 | 6 | 247 | 4 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
| 0.89 | 1.00 | 5 | 224 | 5 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
| 0.38 | 0.54 | 2 | 143 | 3 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
| 0.41 | 0.46 | 2 | 128 | 3 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
| 0.09 | 0.62 | 6 | 294 | 4 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
| 0.38 | 0.49 | 2 | 151 | 3 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 0 |
Carregamento da função
Agora vamos carregar a função que está em um script em meu diretório.
Após isso, basta utilizarmos a função {tunagem_xgb()}, que tem os argumentos base_treino e base_recipe (esta é a base pré-processada). Ela pedirá o número de folds que você deseja repartir sua base para validação cruzada.
Obs: para este exemplo já deixei selecionada o número de folds fixo em 5, mas no script é o usuário quem define.
[1] "Agora vamos rodar os hiperparâmetros!"
[1] "Melhores hiperparâmetros: "
[1] "Lean_rate = 0.05"
[1] "Trees = 100"
[1] "Tree_depth = 6"
[1] "Min_n = 5"
[1] "Loss_reduction = 0.1"
[1] "Sample_size = 1"
[1] "Mtry = 0.3"
[1] "Seu modelo está pronto para ser testado!"
[1] "Utilize o objeto xgb_wk para o teste do modelo"
Como podem ver, esta função vai retornar os valores dos melhores hiperparâmetros e salvar o objeto xgb_wkf, que nada mais é que o workflow (objeto que carrega todos os elementos do modelo) utilizado na modelagem. Precisaremos deste objeto para tetar nosso modelo.
Teste do modelo
Após utilização da função, vamos testar nosso modelo com o objeto xgb_wkf, como disse anteriormente:
Resultados do modelo
Agora saberemos as métricas do nosso modelo e a verificação da curva ROC. Aqui utilizei acurácia e auroc, mas claro que isso fica a critério de cada um:
| .metric | .estimator | .estimate | .config |
|---|---|---|---|
| accuracy | binary | 0.9639248 | Preprocessor1_Model1 |
| roc_auc | binary | 0.9744340 | Preprocessor1_Model1 |
# curva roc
xgb_last_fit %>%
collect_predictions() %>%
roc_curve(desligado,`.pred_1`) %>%
autoplot() +
coord_flip()Também conseguimos verificar a importância das variáveis do modelo:
Após este processo todo, você pode salvar este modelo e utilizar como quiser!
Considerações
Este material serve para quem deseja aplicar o processo de tunagem dos hiperparâmetros do modelo de XGBoost de maneira mais simples e quem sabe conseguir um bom chute inicial destes argumentos. Não recomendo aplicar a função diretamente a uma base, sem a análise exploratória e sem conhecimento prévio dos hiperparâmetros. No mais, aceito contribuições, sugestões e críticas! Pode acessar meu Github ou meu Linkedin.