Predição de Saídas — Parte 4/4

Feature engineering, feature selection, otimização dos hiperparâmetros, validação cruzada e conclusão do projeto

Higor Gomes
13 min readAug 24, 2022
Figura 1 — Capa: Fonte: o autor.

Caso você já tenha lido este artigo, aqui você encontra as outras partes: análise básica, análise intermediária e análise avançada.

Introdução

Nos artigos anteriores dessa série (Predição de Saídas — Parte 1, Predição de Saídas — Parte 2 e Predição de Saídas — Parte 3) vimos toda a etapa de importação das bibliotecas, conexão e observação da base de dados, limpeza completa, análise exploratória, normalização e padronização dos dados, correlação, testes estatísticos, análise de sobrevivência, construção de modelos preditivos, feature importance e métricas de avaliação. Caso você não tenha lido os artigos anterior, recomendo fortemente a leitura antes de seguirmos.

Recapitulando:

  • Estamos analisando uma base de dados fictícia disponibilizada aqui [1] cujo tema central é analisar as alavancas que impulsionam as saídas dos colaboradores
  • Contamos com 34 variáveis preditoras (features) e 1 variável target binária (binária, indicando se a pessoa saiu ou não)
  • A base é significantemente desbalanceada (84% de ativos, 16% de inativos)

Conforme você deve imaginar, chegamos (finalmente) ao último artigo da nossa série chamada Predição de Saídas, em que iremos aplicar algumas técnicas de refinamento das nossas respostas. Podemos traçar um paralelo com as duas primeiras partes: a segunda foi um refinamento da nossa análise descritiva, enquanto que esta edição será um refinamento da terceira (análise preditiva).

Aqui serão apresentadas algumas alternativas para alcançar uma maior assertividade com o nosso modelo preditivo, e veremos na prática que a construção de um projeto de analytics dificilmente é linear (descritivo → diagnóstico → preditivo → prescritivo). Voltaremos para observações descritivas mesmo estando na etapa mais “avançada” do nosso projeto.

Neste artigo iremos cobrir os seguintes tópicos:

  • Feature engineering: construção de novos atributos a partir dos atributos já existentes, buscando reduzir dimensão e aumentar o poder explicativo/preditivo
  • Recapitulação da descrição: iremos observar as novas variáveis com algumas técnicas utilizadas na análise exploratória dos dados
  • Feature selection: iremos escolher as melhores variáveis para criar um modelo preditivo, a fim de torná-lo mais otimizado e assertivo
  • Avaliação do novo dataset: reconstruiremos, a partir da nova base de dados, os quatro modelos finalistas elegidos no artigo anterior e avaliaremos seu resultado
  • Otimização dos hiperparâmetros: será feita a busca pelos melhores parâmetros do modelo final, a fim de obter o maior valor possível para a métrica de sucesso recall
  • Finalização do projeto: realizaremos a avaliação do modelo otimizado, observaremos a importância dos atributos, e fecharemos com a validação cruzada e probabilidade de ocorrência das classes

No artigo anterior, chegamos à conclusão de que nossa métrica de sucesso deve ser o recall em função da natureza do nosso problema (detecção de anomalia), e optamos pelo uso do algoritmo ExtraTreesClassifier, um ensemble de árvores (floresta) que apresenta bons resultados e boa explicabilidade. O modelo com os hiperparâmetros default nos trouxe um recall de aproximadamente 20%.

A seguir, buscaremos melhorar esse valor, a fim de obter um modelo preditivo confiável, com boa capacidade de generalização e que traga insights sobre seu funcionamento.

Feature Engineering

O primeiro passo rumo à otimização do nosso modelo preditivo é a construção de novos atributos. Essa etapa é fundamental em um processo de predição, uma vez que nem sempre as variáveis coletadas diretamente dos sistemas de informação estarão dispostas da melhor maneira possível. Por exemplo, sistemas de folha de pagamento podem apresentar a variável “Data de Admissão”, porém é muito mais interessante (e viável para um modelo de machine learning) trabalhar com o “Tempo de Casa”.

Além disso, vale ressaltar a importância do conhecimento de negócio ao construir novas variáveis. Aqui, mais um vez salientamos as importância do People agindo em conjunto com o Analytics, a fim de que as novas variáveis tenham relação com a variável alvo (se a pessoa sai ou não) e sejam úteis para descrever o fenômeno.

O snippet de código a seguir traz combinações de features, assim como funções para construção de outras.

Aqui foram propostas a criação de algumas novas features, porém essa etapa tem um potencial muito grande. Vale a pena investir um bom tempo aqui para garantir que tenhamos bons atributos na nossa base.

Observando as Novas Variáveis

Conforme adiantado no início deste artigo, um projeto de análise de dados dificilmente seguirá a escalada linear do analytics. Assim, iremos fazer uma breve análise exploratória dos novos dados disponíveis.

Algumas features foram criadas como uma saída binária, então focaremos nas variáveis contínuas e categóricas. O snippet de código a seguir representa essa etapa.

Os Gráficos 1 a 7 ilustram os resultados obtidos. Nota: todos os gráficos apresentados neste artigo são interativos.

Gráfico 1 — Distribuição de New_TotalSatisfactionMean. Fonte: o autor.
Gráfico 2 — Distribuição de New_RelSatisfMean. Fonte: o autor.
Gráfico 3 — Distribuição de New_YearsPerCompanyMean. Fonte: o autor.
Gráfico 4 — Distribuição de New_JobSatisfMean. Fonte: o autor.
Gráfico 5 — Barras de New_TotalSatisfactionMean. Fonte: o autor.
Gráfico 6— Barras de New_JobSatisfMean. Fonte: o autor.
Gráfico 7 — Barras de New_RelSatisfMean. Fonte: o autor.

Conforme discutido no primeiro artigo dessa série, variáveis relacionadas a satisfação têm um alto poder preditivo, de acordo com a literatura [1]. Isso fica evidenciado com as nossas novas variáveis, em que níveis abaixo de 2 para as variáveis “New_RelSatisfMean”, “New_JobSatisfMean” e “New_TotalSatisfactionMeanapresentam uma proporção maior de saídas.

Um outro fato interessante é o resultado obtido com as combinações das variáveis de satisfação. A Figura 2, apresentada à seguir, mostra as distribuições das 5 variáveis originais de satisfação.

Figura 2 — Distribuições das variáveis de satisfação. Fonte: o autor.

Combinando as variáveis por meio de uma média aritmética, obtemos a “New_TotalSatisfactionMean”, ou “Satisfação Total”. A Figura 3 mostra a distribuição dessa nova variável.

Figura 3 — Distribuições da média das variáveis de satisfação. Fonte: o autor.

O formato é satisfatoriamente similar a uma distribuição normal (que será comprovada nas próximas etapas), o que implica em uma expansão considerável nas análises (testes estatísticos, simetrias, proporcionalidades, entre outros). Assim, identificamos mais uma poderosa vantagem em realizar a etapa de feature engineering, possibilitando obter features distribuições muito mais interessantes a partir de atributos que antes não tinham padrão aparente.

Seguindo a nossa análise descritiva para as novas features, iremos abordar mais duas etapas: a matriz de correlação e a avaliação da normalidade dos novos dados, por meio dos histogramas e dos qq-plots.

O snippet de código abaixo traz a etapa de construção da nova matriz de correlação, seguido do Gráfico 8 que apresenta os resultados obtidos.

Gráfico 8 — Nova matriz de correlação para as novas features. Fonte: o autor.

O snippet de código abaixo traz a etapa de avaliação da normalidade dos novos dados, seguido dos Gráfico 9 a 16 que apresentam os resultados obtidos.

Gráfico 9 — Histograma da variável New_TotalSatisfactionMean. Fonte: o autor.
Gráfico 10 — Histograma da variável New_RelSatisfMean. Fonte: o autor.
Gráfico 11 — Histograma da variável New_YearsPerCompanyMean. Fonte: o autor.
Gráfico 12 — Histograma da variável New_JobSatisfMean. Fonte: o autor.
Gráfico 13 — Q-Q Plot da variável New_TotalSatisfactionMean. Fonte: o autor.
Gráfico 14 — Q-Q Plot da variável New_RelSatisfMean. Fonte: o autor.
Gráfico 15 — Q-Q Plot da variável New_YearsPerCompanyMean. Fonte: o autor.
Gráfico 16 — Qq-plot da variável New_JobSatisfMean. Fonte: o autor.

Aqui, por meio dos histogramas e dos qq-plots, confirmamos a normalidade dos dados da variável “New_TotalSatisfactionMean”, conforme inferido anteriormente.

A próxima etapa será focada na seleção das features, que consiste em diminuir o número de atributos que nosso modelo preditivo irá utilizar. Para isso, já iremos gerar a primeira versão do dataset final, de acordo com o snippet de código a seguir, realizando a inclusão das novas features e sua normalização.

Adicionalmente, para permitir diversas técnicas de seleção de atributos, iremos também separar a base em classe e preditores, bem como os dados de treino e teste, de acordo com o snippet a seguir.

Feature Selection

O termo maldição da dimensionalidade foi introduzido pelo matemático
americano Richard Bellman, e refere-se ao fenômeno que surge ao se analisar dados em espaços de alta dimensionalidade (centenas ou milhares de dimensões) [2]. Além disso, muitas abordagens de análise de dados tornam-se significativamente mais complexas com o aumento da dimensionalidade dos dados.

Na prática, esse termo implica que o desempenho de um classificador tende a se degradar a partir de um determinado número de características (dimensões). A Figura 4 abaixo traz uma representação desse fenômeno.

Figura 4 — Balanço entre total de features e performance do classificador. Fonte: Baeldung [3].

Quando a dimensionalidade aumenta, os dados se tornam cada vez mais esparsos no espaço que eles ocupam. Para um problema de classificação, isto significa que não há objetos de dados suficientes para permitir a criação de um modelo que atribua, de forma confiável, uma classe a todos os objetos possíveis. Como consequência, muitos algoritmos de classificação e agrupamento apresentam problemas em termos de eficácia e eficiência.

Adicionalmente, o uso demasiado de características pode causar o problema de overfitting, já que o classificador passa a aprender detalhes específicos dos dados de treinamento, mas não generaliza quando novas amostras são apresentadas.

Na prática, o processo de redução de dimensionalidade começa com a combinação de features existentes em novas, de maneira análoga ao que foi feito na nossa etapa de feature engineering. A partir de agora, focaremos na escolha dos melhores atributos, de acordo com as seguintes técnicas:

  • Baseadas em filtro: iremos especificar alguma métrica e, com base em seu valor, iremos filtrar a base de dados. Utilizaremos a Correlação Linear de Pearson como métrica para esse tipo de seleção
  • Baseadas em empacotamento: esse método consiste em selecionar apenas um conjunto de features para a resolução do problema, realizando a eliminação ou adição de features de acordo com um passo definido. Será utilizada a Eliminação Recursiva de Features (RFE) como exemplo dessa técnica
  • Baseadas em incorporação: são estratégias que utilizam algoritmos que têm métodos internos de seleção de features, como Árvores de Decisão combinado com suas feature importances

O snippet de código a seguir traz a criação das funções de seleção para cada uma das técnicas apresentadas.

Com as funções de seleção de atributos prontas, iremos criar um dataframe com alguns exemplares para classificadores diferentes, a fim de obter uma boa pluralidade de resultados. O snippet de código a seguir ilustra essa etapa.

O próximo snippet mostra a agregação adicional que soma quantas vezes cada uma das features foi eleita importante pelas técnicas. A Figura 5 ilustra o resultado.

Figura 5 — Dataframe resultante da etapa de feature selection. Fonte: o autor.

Voilà! Depois de extensas etapas de limpeza, tratamento, transformações, normalizações, combinações, chegamos à última etapa de preparação do dataset final (agora, realmente final) para obter um modelo preditivo eficaz: selecionar apenas as features mais importantes!

Utilizaremos o limiar de 3, ou seja, apenas features que foram selecionadas por mais de 3 técnicas serão parte da base de dados final. Na sequência, já é feita a divisão final entre classe e preditores, bem como os valores de treino e teste (tanto para a versão normal, quanto para a versão com oversampling). Isso tudo está representado no snippet de código a seguir.

Avaliando o Dataset Final

Agora, podemos repetir a criação dos quatro modelos preditivos finalistas elegidos no artigo anterior. Começamos com a versão simples, nos dados de treino e teste originais, sem nenhuma alteração de hiperparâmetros, de acordo com o snippet de código a seguir.

As Figuras 6 e 7 apresentam os resultados obtidos.

Figura 6 — Métricas de sucesso para os modelos preditivos simples. Fonte: o autor.
Figura 7 — Matrizes de confusão para os modelos preditivos simples. Fonte: o autor.

O próximo passo é escolher alguns hiperparâmetros para os modelos. Aqui é interessante destacar dois deles: class_weight, que essencialmente informa ao algoritmo que nossa base é desbalanceada, e max_depth, que evita o overfitting das nossas árvores de decisão. A implementação está representada no próximo snippet de código.

Nota: o classificador bayesiano não apresenta melhorias com a alteração dos hiperparâmetros, além de não ter muita margem para otimização (apenas dois hiperparâmetros).

As Figuras 8 e 9 apresentam os resultados obtidos.

Figura 8 — Métricas de sucesso para os modelos preditivos com hiperparâmetros novos. Fonte: o autor.
Figura 9 — Matrizes de confusão para os modelos preditivos com hiperparâmetros novos. Fonte: o autor.
Figura 10 — Métricas de sucesso para os modelos preditivos aprimorados. Fonte: o autor.
Figura 11 — Matrizes de confusão para os modelos preditivos aprimorados. Fonte: o autor.

Por fim, podemos comparar os modelos criados por meio das curvas ROC e AUC, de acordo com o Gráfico 17 apresentado após o snippet de código dessa etapa.

Gráfico 17 — Curvas ROC e AUC para os modelos com hiperparâmetros novos. Fonte: o autor.

Notamos que conseguimos elevar o recall da nossa ExtraTreesClassifier de 20% para 71%. Além disso, seguiremos com a base sem oversampling, uma vez que ela não apresentou expressiva melhoria nos resultados para esse tipo de classificador (o hiperparâmetros class_weight será suficiente pra lidarmos com o desbalanceamento).

Otimização dos Hiperparâmetros

Por fim, nosso projeto segue para as duas últimas etapas, sendo elas a otimização dos hiperparâmetros e a validação cruzada. Para o primeiro passo, iremos definir alguns parâmetros de interesse, que controlam a qualidade da divisão dos nós, assim como a dimensão da árvore, e buscar os melhores valores de duas maneiras: com uma busca aleatória (Random Search) e uma busca sistemática (Grid Search).

O snippet de código a seguir mostra os valores escolhidos para a busca. É fortemente recomendada a leitura da documentação da ferramenta para essa escolha, disponível aqui [4].

Conforme o nome diz, essa busca irá escolher aleatoriamente n pontos do espaço de hiperparâmetros de acordo com a variável total_iteracoes definida abaixo. É uma escolha interessante, pois não é tão custosa em termos computacionais, porém um número de iterações baixo pode levar a resultados diferentes do ótimo. O processo de busca por Random Search está ilustrado no snippet de código a seguir.

Já o Grid Search divide o espaço dos hiperparâmetros em uma grade, e a busca é feita em todos os pontos. O melhor ponto será encontrado, mas as custas de um alto tempo de processamento, a depender do tamanho da grade. Esse processo está apresentado a seguir.

Conforme observado, em ambos os casos a métrica de sucesso escolhida foi o recall, e os melhores parâmetros escolhidos pela técnica do Random Search estão representados na Figura 12 a seguir.

Figura 12 — Melhores hiperparâmetros de acordo com o Random Search. Fonte: o autor.

A seguir, o snippet de código com a implementação do modelo final, utilizando os melhores hiperparâmetros de acordo com a busca anterior.

A Figura 13, representada abaixo, traz as métricas de avaliação do modelo preditivo final, alcançando um recall de 73.5%, com uma precisão de 40%. Esse baixo valor de precisão resultará em indicar pessoas como possíveis saídas sendo que elas permanecerão na empresa. Isso será endereçado no último tópico do artigo. O Gráfico 18 traz as features mais importantes na predição da saída, de acordo com o modelo construído.

Figura 13 — Métricas de avaliação do modelo preditivo final. Fonte: o autor.
Gráfico 18 — Feature importances do modelo preditivo final. Fonte: o autor.

Concluindo a segunda e última parte da nossa etapa final, iremos realizar a validação cruzada, que consiste em dividir os dados em k partições mutuamente exclusivas de tamanhos aproximadamente iguais.

O modelo é ajustado utilizando-se k-1 partições de treinamento, enquanto a partição remanescente fica destinada à validação. Esse processo k vezes, cada vez considerando uma partição diferente para a validação. A eficácia do classificador é estimada pela média das medidas obtidas em cada uma das k partições, e o modelo cuja configuração de hiperparâmetros fornece o menor erro na validação cruzada é então treinado com todos os dados do conjunto de treinamento para se tornar o modelo final preditivo.

A Figura 14, apresentada a seguir, ilustra a metodologia de funcionamento da validação cruzada.

Figura 14 — Representação esquemática da validação cruzada. Fonte: o autor.

O snippet de código a seguir mostra como será executada a validação cruzada.

Assim, temos o seguinte resultado:

Para o recall: 0.7341394025604553 +/- 0.028372584498582036

Finalização do Projeto

Um último ponto a ser discutido é o método predict_proba(), que apresenta a probabilidade de um dado previsto pertencer a cada uma das classes. Com isso, podemos amenizar baixos valores de precisão focando os esforços nas observações com maior probabilidade de pertencerem à classe positiva (inativos).

Logo, uma maneira interessante de disponibilizar os resultados de um modelo preditivo é justamente trazer essas duas informações (ou pelo menos, a probabilidade da pessoa ser inativa), inclusive categorizando entre pessoas de baixo risco (menos de 40% de chance), risco médio (entre 40% e 60% de chance) e risco alto (mais de 60% de chance).

Vale ressaltar que, para classificadores do tipo de florestas, os picos de probabilidade são 20% e 90%, aproximadamente [5]. O snippet de código abaixo mostra como obtemos as probabilidades, seguido da Figura 15 com o resultado.

Figura 15 — Probabilidades de pertencer a cada classe. Fonte: o autor.

Conclusão

Chegamos ao final da nossa série de quatro artigos sobre Predição de Saídas. O intuito de quebrar esse problema em tantas etapas foi justamente apresentar de forma detalhada todas as etapas envolvidas na obtenção de um modelo preditivo.

Por muitas vezes, isso é tratado como o grande objetivo, ou o único foco num projeto envolvendo turnover. Porém, vimos na prática que o caminho até chegarmos ao machine learning é extenso e exige paciência, pensamento crítico, muita atenção aos detalhes e, acima de tudo, respeitar o processo.

Todas as técnicas e ferramentas apresentadas ao longo da série são um pontapé inicial, e podem servir como framework genérico na resolução de um problema similar. Entretanto, cada caso tem a sua particularidade, e buscar alternativas e complementos às técnicas aqui apresentadas é extremamente importante, para que possamos ter um repertório cada vez mais versátil e completo.

Vimos as principais técnicas utilizadas na análise exploratória dos dados, como plotagem dos gráficos de distribuição das variáveis contínuas, combinação dos gráficos de barras com linhas para variáveis categóricas, além de uma importante expansão dessa etapa com a análise de sobrevivência, em que possível aumentar o poder de explicabilidade para variáveis antes sem insights visíveis. Além disso, complementamos nossas análises iniciais com correlações e testes estatísticos, fornecendo mais duas ferramentas para entendimento do problema.

Foi também estabelecido uma importante relação entre people e analytics, em que o conhecimento de negócio potencializa muito o conhecimento técnico, principalmente no entendimento do problema, combinação das features, definição dos limites nas análises de sobrevivência, entre outros.

No âmbito das análises preditivos, vimos a importância de realizar uma boa análise descritiva, e como preparar a nossa base de dados para realizar predições. Além disso, exploramos as principais métricas de avaliação para problemas de classificação, como a matriz de confusão, precisão, revocação (recall), curva ROC e AUC, entre outras. Também vimos que, no caso de predição de saídas, a nossa métrica de interesse é justamente o recall, para que possamos minimizar o número de falso negativos.

Por fim, optamos por um modelo com boa explicabilidade e bons resultados de recall, sendo o ExtraTreesClassifier escolhido. A título de curiosidade, o snippet de código a seguir traz uma maneira de plotar uma árvore de decisão.

A Figura 16, representada a seguir, ilustra a árvore criada.

Figura 16 — Esquema da árvore de decisão. Fonte: o autor.

Assim, reforçamos que é importante construir um modelo relativamente simples de explicar, fugindo do efeito caixa preta e tangibilizando os resultados obtidos para diversos stakeholders.

Finalizamos o projeto com um modelo com 73.5% de assertividade (a cada 10 pessoas que saem, o modelo identifica mais de 7), apresentando também as features mais importantes na obtenção desse resultado, assim como as probabilidades de ocorrência de cada uma das classes em todas as observações do dataset.

Para estudos futuros, recomenda-se a reprodução do notebook do completo, referenciado ao final do artigo, juntamente com variações das técnicas aqui propostas. Será um prazer manter este projeto vivo e em processo de melhoria contínua com a sua contribuição.

No mais, agradeço imensamente pela sua companhia nessa jornada, e espero que minhas contribuições tragam algo de novo e divertido para suas análises.

O código completo do projeto está disponível aqui.

Caso você já tenha lido este artigo, fique à vontade para conferir as outras partes: análise básica, análise intermediária e análise avançada.

--

--