Eu fui desafiada a tomar o papel da nova cientista de dados na Alura Voz. Essa empresa fictícia é do ramo de telecomunicação e precisa reduzir sua taxa de evasão de clientes.
Esse desafio é dividido em quatro semanas. Para a primeira semana o objetivo é tratar o banco de dados proveniente de uma API. Em seguida, precisamos identificar clientes que são mais propensos a deixar a empresa, usando exploração e análise de dados. E então, na terceira semana, nós usamos modelos de machine learning para prever a taxa de evasão da Alura Voz. A última semana é para expor o que fizemos durante o desafio e construir nosso portfolio. Caso esteja interessado em ver o código, ele está disponível no meu repositório do GitHub.
Primeira Semana
Lendo o Banco de Dados
O banco de dados foi disponibilizado no formato JSON e num primeiro momento aparenta ser um data frame normal.
Entretanto, como pode ser observado, customer
, phone
, internet
, e account
são suas próprias tabelas. Então eu normalizei elas separadamente e depois simplesmente concatenei todas essas tabelas em uma.
Dados Faltantes
A primeira vez que eu procurei por dados faltantes nessa base nenhum foi encontrado, mas a medida que eu explorei os dados eu percebi que havia espaços em branco e vazios não sendo contados como NaN
. Então eu corrigi isso e descobri que havia 224 dados faltantes para a variável Churn
e 11 para Charges.Total
.
Eu decidi desconsiderar os dados faltantes da variável Churn
, pois este será nosso objeto de estudo e não há sentido em estudar algo que não existe. No caso dos dados faltantes de Charges.Total
, eu imagino que representa um cliente que não pagou nada ainda, pois todos eles possuem 0 meses de contrato, ou seja, eles acabaram de se tornar clientes, então eu simplesmente substitui o valor faltante por 0.
Codificação de Variáveis
A variável SeniorCitizen
foi a única que veio com 0
e 1
ao invés de Yes
e No
. Por hora eu irei trocar esses valores por “yes” e “no”, pois isto torna a análise mais simples de ser lida.
Charges.Monthly
e Charges.Total
foram renomeadas para perderem o ponto, pois isto atrapalha na hora de lidar com elas no python.
Segunda Semana
Análise de Dados
No primeiro gráfico podemos ver o quão desbalanceado nosso banco de dados é. Há mais de 5000 clientes que não deixaram a empresa e um pouco menos de 2000 que deixaram.
Eu experimentei usar técnicas de sobreamostragem (oversampling) para lidar com esse deslanceamento, mas isto fez com que os modelos de aprendizado de máquina tivessem uma performance pior. E subamostragem (undersampling) não é uma opção com um banco de dados desse tamanho, então eu decidi deixar do jeito que está, e quando for hora de separar os dados de treino e teste eu irei estratificar o banco de acordo com a variável Churn
.
Eu também gerei 16 gráficos para todas as variáveis discretas, para ver todos os gráficos olhe este notebook. O objetivo é ver se havia algum comportamento que fazia alguns cliente mais propensos a deixar a empresa. É claro que todas, exceto por gender
, parecem ter algum papel em determinar se um cliente vai ou não deixar a empresa. Mais especificamente forma de pagamento, contratos, backup online, suporte técnico, e serviço de internet.
No gráfico de tenure
, eu decidi fazer gráficos de distribuição dos meses de contrato do cliente, um gráfico para os cliente que não evadiram e um para os que evadiram. Podemos ver que clientes que evadiram o fizeram no início do seu tempo na empresa.
A cobrança mensal média para os cliente que não evadiram é de 61,27 unidades monetária, enquanto que clientes que evadiram pagam 74,44. Isso provavelmente é por conta do tipo de contrato que esses tipo de clintes preferem, mas de qualquer forma é senso comum que preços altos afastam clientes.
O Perfil de Evasão
Considerando tudo que eu pude observar através de gráficos e medidas, eu fiz um perfil de clientes que são mais propensos a evadir a empresa.
Clientes novos são mais propensos a evadir do que clientes antigos.
Clientes com poucos serviços e produtos tendem a deixar a empresa. Se eles não estão presos a um contrato mais longo eles aparentam ser mais propensos a abandonar a empresa.
Sobre os meios de pagamentos, cliente que evadem possuem uma preferência forte por cheques eletrônicos e usualmente gastam 13,17 unidades monetárias a mais que a média de clientes que não deixaram a empresa.
Terceira Semana
Preparando o Banco de Dados
Damos início fazendo variáveis dummies, de forma que teremos n-1 dummies para n variáveis. Então fazemos uma matriz de correlação para avaliar a correlação das nossas variáveis.
Podemos ver que a variável InternetService_No
possui correlações altas com diversas outras variáveis, isso se dá porque as outras variáveis depende do cliente ter ou não acesso a internet. Então irei tirar essas variáveis dependentes do modelo. A mesma coisa ocorre com PhoneService_Yes
.
tenure
e ChargesTotal
também possuem uma alta correlação, mas eu testei rodar os modelos sem uma das duas ou ambas e os modelos tiveram uma performance pior e levaram mais tempo para covergirem, então eu decidi manter elas no modelo, e elas são relevantes para o problema.
Após retirar essas variáveis eu termino de preparar o banco de dados com uma normalização das variáveis numéricas, ChargesTotal
e tenure
.
Banco de Dados de Teste e Treino
Eu dividi o banco de dados em treino e teste, 20% para teste e o resto para treino. Eu estratifiquei os dados de acordo com a variável Churn
e embaralhei os dados antes de separar. A mesma divisão de dados é usada em todos os modelos. Após separar os dados eu decidi fazer uma sobreamostragem (oversampling) dos dados de teste usando SMOTE1, pois os dados são muito desbalanceados. O motivo de eu usar essa técnica apenas nos dados de teste é que eu não quero ter um resultado viesado, se eu sobreamostrar todo o banco de dados isso quer dizer que eu vou testar meu modelo no mesmo dado que eu o treinei, e este não é meu objetivo.
Avaliação dos Modelos
Eu vou utilizar um classificador dummy para ter uma base para a medida de acurácia, e eu também vou utilizar as métricas: precision
(precisão), recall
(recordação) and f1 score
(medida f1)2. Apesar de que o modelo dummy não ter valor para essas métricas eu vou manter ele para comparar a melhora dos modelos.
Modelo Base
O modelo base foi feito através de um classificador dummy, basicamente ele diz que todos os clientes se comportam da mesma forma. Neste caso o modelo chutou que nenhum cliente iria deixar a empresa. Usando essa abordagem o modelo base obteve uma acurácia de 0,73456
.
A seguir todos os modelos terão a mesma semente aleatória (random state).
Modelo 1 - Florestas Aleatórias
Eu inicio usando uma busca no grid com validação cruzada (grid search with cross-validation) para encontrar os melhores parâmetros dentro de uma seleção de opções utilizando o recall
como estratégia para avaliar a performance. O melhor modelo encontrado pela busca foi:
|
|
Após ajustar o modelo, as medidas de avaliação foram:
- Medida Accuracy: 0,72534
- Medida Precision: 0,48922
- Medida Recall: 0,78877
- Medida F1: 0,60389
Modelo 2 - Classificação de Vetores de Suporte Linear
Neste modelo eu usei os parâmetros padrões e aumentei o teto para o máximo de iterações para 900000
.
|
|
Após ajustar o modelo, as medidas de avaliação foram:
- Medida Accuracy: 0,71966
- Medida Precision: 0,48217
- Medida Recall: 0,75936
- Medida F1: 0,58982
Modelo 3 - Rede Neural Multicamada Perceptron
Aqui eu fixei o solucionador LBFGS, pois de acordo com a documentação do scikit-learn
ele tem uma performance melhor em banco de dados pequenos 3, e também fiz uma busca no grid com validação cruzada para encontrar o melhor tamanho da camada oculta. O melhor modelo foi:
|
|
Após ajustar o modelo, as medidas de avaliação foram:
- Medida Accuracy: 0,72818
- Medida Precision: 0,49133
- Medida Recall: 0,68182
- Medida F1: 0,57111
Conclusão
Após rodar os três modelos, todos usando o mesmo random_state
. Eu encontrei as seguintes medidas de acurácia e melhorias no desempenho (comparado com o modelo base):
No fim, a Floresta Aleatória teve as melhores métricas. Este modelo consegue recordar uma grande parte dos clientes que evadem corretamente, ainda não é perfeito, mas já é um ponto de partida. A medida de acurácia não é tão alta como eu gostaria, mas para este problema em particular o objetivo é impedir os clientes de deixar a empresa e é melhor utilizar recursos para manter um cliente que não vai deixar a empresa do que não fazer nada.
No fim, eu gostei desse desafio, pois é raro eu praticar aprendizado de máquina, mas graças ao desafio eu tive a oportunidade de fazer um pequeno projeto nessa área que é tão importante e relevante. Essa foi a minha primeira vez trabalhando com redes neurais e ajuste de hiperparâmetros, e tenho certeza que na próxima vez terei resultados ainda melhores.