Você é um Analista de Dados em uma empresa de telecomunicações que fornece serviços de internet e telefonia. Recentemente, você teve acesso a dados históricos que indicam que a empresa perdeu 26% dos seus clientes nos últimos trimestres. Essa perda significativa de clientes impactou negativamente as finanças da empresa, gerando um prejuízo de milhões de reais.
O seu próximo desafio como Analista de Dados é identificar a principal causa do problema, para que você possa propor um plano de ação para resolvê-lo.
Este é o link do Google Drive para a base de dados que será analisada:
Este é o link original no Kaggle:
# Importa o pandas com o apelido pd
import pandas as pd
# Importa o arquivo
df_clientes = pd.read_csv('telecom_users.csv')
# Exibe o dataframe
df_clientes
Unnamed: 0 | IDCliente | Genero | Aposentado | Casado | Dependentes | MesesComoCliente | ServicoTelefone | MultiplasLinhas | ServicoInternet | ... | ServicoSuporteTecnico | ServicoStreamingTV | ServicoFilmes | TipoContrato | FaturaDigital | FormaPagamento | ValorMensal | TotalGasto | Churn | Codigo | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1869 | 7010-BRBUU | Masculino | 0 | Sim | Sim | 72 | Sim | Sim | Nao | ... | SemInternet | SemInternet | SemInternet | 2 anos | Nao | CartaoCredito | 24.10 | 1734.65 | Nao | NaN |
1 | 4528 | 9688-YGXVR | Feminino | 0 | Nao | Nao | 44 | Sim | Nao | Fibra | ... | Nao | Sim | Nao | Mensal | Sim | CartaoCredito | 88.15 | 3973.2 | Nao | NaN |
2 | 6344 | 9286-DOJGF | Feminino | 1 | Sim | Nao | 38 | Sim | Sim | Fibra | ... | Nao | Nao | Nao | Mensal | Sim | DebitoAutomatico | 74.95 | 2869.85 | Sim | NaN |
3 | 6739 | 6994-KERXL | Masculino | 0 | Nao | Nao | 4 | Sim | Nao | DSL | ... | Nao | Nao | Sim | Mensal | Sim | BoletoEletronico | 55.90 | 238.5 | Nao | NaN |
4 | 432 | 2181-UAESM | Masculino | 0 | Nao | Nao | 2 | Sim | Nao | DSL | ... | Nao | Nao | Nao | Mensal | Nao | BoletoEletronico | 53.45 | 119.5 | Nao | NaN |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
5981 | 3772 | 0684-AOSIH | Masculino | 0 | Sim | Nao | 1 | Sim | Nao | Fibra | ... | Nao | Sim | Sim | Mensal | Sim | BoletoEletronico | 95.00 | 95 | Sim | NaN |
5982 | 5191 | 5982-PSMKW | Feminino | 0 | Sim | Sim | 23 | Sim | Sim | DSL | ... | Sim | Sim | Sim | 2 anos | Sim | CartaoCredito | 91.10 | 2198.3 | Nao | NaN |
5983 | 5226 | 8044-BGWPI | Masculino | 0 | Sim | Sim | 12 | Sim | Nao | Nao | ... | SemInternet | SemInternet | SemInternet | Mensal | Sim | BoletoEletronico | 21.15 | 306.05 | Nao | NaN |
5984 | 5390 | 7450-NWRTR | Masculino | 1 | Nao | Nao | 12 | Sim | Sim | Fibra | ... | Nao | Sim | Sim | Mensal | Sim | BoletoEletronico | 99.45 | 1200.15 | Sim | NaN |
5985 | 860 | 4795-UXVCJ | Masculino | 0 | Nao | Nao | 26 | Sim | Nao | Nao | ... | SemInternet | SemInternet | SemInternet | Anual | Nao | CartaoCredito | 19.80 | 457.3 | Nao | NaN |
5986 rows × 23 columns
df_clientes.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 5986 entries, 0 to 5985 Data columns (total 23 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Unnamed: 0 5986 non-null int64 1 IDCliente 5986 non-null object 2 Genero 5986 non-null object 3 Aposentado 5986 non-null int64 4 Casado 5986 non-null object 5 Dependentes 5985 non-null object 6 MesesComoCliente 5986 non-null int64 7 ServicoTelefone 5986 non-null object 8 MultiplasLinhas 5986 non-null object 9 ServicoInternet 5986 non-null object 10 ServicoSegurancaOnline 5986 non-null object 11 ServicoBackupOnline 5986 non-null object 12 ProtecaoEquipamento 5986 non-null object 13 ServicoSuporteTecnico 5986 non-null object 14 ServicoStreamingTV 5986 non-null object 15 ServicoFilmes 5986 non-null object 16 TipoContrato 5986 non-null object 17 FaturaDigital 5986 non-null object 18 FormaPagamento 5986 non-null object 19 ValorMensal 5986 non-null float64 20 TotalGasto 5986 non-null object 21 Churn 5985 non-null object 22 Codigo 0 non-null float64 dtypes: float64(2), int64(3), object(18) memory usage: 1.1+ MB
# Remove a coluna Unnamed: 0
df_clientes.drop('Unnamed: 0', axis='columns', inplace=True)
# Exibe o dataframe
display(df_clientes)
IDCliente | Genero | Aposentado | Casado | Dependentes | MesesComoCliente | ServicoTelefone | MultiplasLinhas | ServicoInternet | ServicoSegurancaOnline | ... | ServicoSuporteTecnico | ServicoStreamingTV | ServicoFilmes | TipoContrato | FaturaDigital | FormaPagamento | ValorMensal | TotalGasto | Churn | Codigo | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 7010-BRBUU | Masculino | 0 | Sim | Sim | 72 | Sim | Sim | Nao | SemInternet | ... | SemInternet | SemInternet | SemInternet | 2 anos | Nao | CartaoCredito | 24.10 | 1734.65 | Nao | NaN |
1 | 9688-YGXVR | Feminino | 0 | Nao | Nao | 44 | Sim | Nao | Fibra | Nao | ... | Nao | Sim | Nao | Mensal | Sim | CartaoCredito | 88.15 | 3973.2 | Nao | NaN |
2 | 9286-DOJGF | Feminino | 1 | Sim | Nao | 38 | Sim | Sim | Fibra | Nao | ... | Nao | Nao | Nao | Mensal | Sim | DebitoAutomatico | 74.95 | 2869.85 | Sim | NaN |
3 | 6994-KERXL | Masculino | 0 | Nao | Nao | 4 | Sim | Nao | DSL | Nao | ... | Nao | Nao | Sim | Mensal | Sim | BoletoEletronico | 55.90 | 238.5 | Nao | NaN |
4 | 2181-UAESM | Masculino | 0 | Nao | Nao | 2 | Sim | Nao | DSL | Sim | ... | Nao | Nao | Nao | Mensal | Nao | BoletoEletronico | 53.45 | 119.5 | Nao | NaN |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
5981 | 0684-AOSIH | Masculino | 0 | Sim | Nao | 1 | Sim | Nao | Fibra | Sim | ... | Nao | Sim | Sim | Mensal | Sim | BoletoEletronico | 95.00 | 95 | Sim | NaN |
5982 | 5982-PSMKW | Feminino | 0 | Sim | Sim | 23 | Sim | Sim | DSL | Sim | ... | Sim | Sim | Sim | 2 anos | Sim | CartaoCredito | 91.10 | 2198.3 | Nao | NaN |
5983 | 8044-BGWPI | Masculino | 0 | Sim | Sim | 12 | Sim | Nao | Nao | SemInternet | ... | SemInternet | SemInternet | SemInternet | Mensal | Sim | BoletoEletronico | 21.15 | 306.05 | Nao | NaN |
5984 | 7450-NWRTR | Masculino | 1 | Nao | Nao | 12 | Sim | Sim | Fibra | Nao | ... | Nao | Sim | Sim | Mensal | Sim | BoletoEletronico | 99.45 | 1200.15 | Sim | NaN |
5985 | 4795-UXVCJ | Masculino | 0 | Nao | Nao | 26 | Sim | Nao | Nao | SemInternet | ... | SemInternet | SemInternet | SemInternet | Anual | Nao | CartaoCredito | 19.80 | 457.3 | Nao | NaN |
5986 rows × 22 columns
# Converte os dados da coluna Total Gasto para float
df_clientes['TotalGasto'] = pd.to_numeric(df_clientes['TotalGasto'], errors='coerce')
# Obtém informações do dataframe
df_clientes.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 5986 entries, 0 to 5985 Data columns (total 22 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 IDCliente 5986 non-null object 1 Genero 5986 non-null object 2 Aposentado 5986 non-null int64 3 Casado 5986 non-null object 4 Dependentes 5985 non-null object 5 MesesComoCliente 5986 non-null int64 6 ServicoTelefone 5986 non-null object 7 MultiplasLinhas 5986 non-null object 8 ServicoInternet 5986 non-null object 9 ServicoSegurancaOnline 5986 non-null object 10 ServicoBackupOnline 5986 non-null object 11 ProtecaoEquipamento 5986 non-null object 12 ServicoSuporteTecnico 5986 non-null object 13 ServicoStreamingTV 5986 non-null object 14 ServicoFilmes 5986 non-null object 15 TipoContrato 5986 non-null object 16 FaturaDigital 5986 non-null object 17 FormaPagamento 5986 non-null object 18 ValorMensal 5986 non-null float64 19 TotalGasto 5976 non-null float64 20 Churn 5985 non-null object 21 Codigo 0 non-null float64 dtypes: float64(3), int64(2), object(17) memory usage: 1.0+ MB
Com este novo dataframe, notamos que a coluna TotalGasto possuía 10 linhas com dados incorretos (textos). Por isso, eles foram removidos.
# Remove todas as colunas que só possuem valores vazios
df_clientes.dropna(how='all', axis='columns', inplace=True)
# Remove as linhas que contém pelo menos um valor vazio
df_clientes.dropna(how='any', axis='index', inplace=True)
# Exibe o dataframe
df_clientes
IDCliente | Genero | Aposentado | Casado | Dependentes | MesesComoCliente | ServicoTelefone | MultiplasLinhas | ServicoInternet | ServicoSegurancaOnline | ... | ProtecaoEquipamento | ServicoSuporteTecnico | ServicoStreamingTV | ServicoFilmes | TipoContrato | FaturaDigital | FormaPagamento | ValorMensal | TotalGasto | Churn | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 7010-BRBUU | Masculino | 0 | Sim | Sim | 72 | Sim | Sim | Nao | SemInternet | ... | SemInternet | SemInternet | SemInternet | SemInternet | 2 anos | Nao | CartaoCredito | 24.10 | 1734.65 | Nao |
1 | 9688-YGXVR | Feminino | 0 | Nao | Nao | 44 | Sim | Nao | Fibra | Nao | ... | Sim | Nao | Sim | Nao | Mensal | Sim | CartaoCredito | 88.15 | 3973.20 | Nao |
2 | 9286-DOJGF | Feminino | 1 | Sim | Nao | 38 | Sim | Sim | Fibra | Nao | ... | Nao | Nao | Nao | Nao | Mensal | Sim | DebitoAutomatico | 74.95 | 2869.85 | Sim |
3 | 6994-KERXL | Masculino | 0 | Nao | Nao | 4 | Sim | Nao | DSL | Nao | ... | Nao | Nao | Nao | Sim | Mensal | Sim | BoletoEletronico | 55.90 | 238.50 | Nao |
4 | 2181-UAESM | Masculino | 0 | Nao | Nao | 2 | Sim | Nao | DSL | Sim | ... | Sim | Nao | Nao | Nao | Mensal | Nao | BoletoEletronico | 53.45 | 119.50 | Nao |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
5981 | 0684-AOSIH | Masculino | 0 | Sim | Nao | 1 | Sim | Nao | Fibra | Sim | ... | Nao | Nao | Sim | Sim | Mensal | Sim | BoletoEletronico | 95.00 | 95.00 | Sim |
5982 | 5982-PSMKW | Feminino | 0 | Sim | Sim | 23 | Sim | Sim | DSL | Sim | ... | Sim | Sim | Sim | Sim | 2 anos | Sim | CartaoCredito | 91.10 | 2198.30 | Nao |
5983 | 8044-BGWPI | Masculino | 0 | Sim | Sim | 12 | Sim | Nao | Nao | SemInternet | ... | SemInternet | SemInternet | SemInternet | SemInternet | Mensal | Sim | BoletoEletronico | 21.15 | 306.05 | Nao |
5984 | 7450-NWRTR | Masculino | 1 | Nao | Nao | 12 | Sim | Sim | Fibra | Nao | ... | Sim | Nao | Sim | Sim | Mensal | Sim | BoletoEletronico | 99.45 | 1200.15 | Sim |
5985 | 4795-UXVCJ | Masculino | 0 | Nao | Nao | 26 | Sim | Nao | Nao | SemInternet | ... | SemInternet | SemInternet | SemInternet | SemInternet | Anual | Nao | CartaoCredito | 19.80 | 457.30 | Nao |
5974 rows × 21 columns
df_clientes.info()
<class 'pandas.core.frame.DataFrame'> Int64Index: 5974 entries, 0 to 5985 Data columns (total 21 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 IDCliente 5974 non-null object 1 Genero 5974 non-null object 2 Aposentado 5974 non-null int64 3 Casado 5974 non-null object 4 Dependentes 5974 non-null object 5 MesesComoCliente 5974 non-null int64 6 ServicoTelefone 5974 non-null object 7 MultiplasLinhas 5974 non-null object 8 ServicoInternet 5974 non-null object 9 ServicoSegurancaOnline 5974 non-null object 10 ServicoBackupOnline 5974 non-null object 11 ProtecaoEquipamento 5974 non-null object 12 ServicoSuporteTecnico 5974 non-null object 13 ServicoStreamingTV 5974 non-null object 14 ServicoFilmes 5974 non-null object 15 TipoContrato 5974 non-null object 16 FaturaDigital 5974 non-null object 17 FormaPagamento 5974 non-null object 18 ValorMensal 5974 non-null float64 19 TotalGasto 5974 non-null float64 20 Churn 5974 non-null object dtypes: float64(2), int64(2), object(17) memory usage: 1.0+ MB
# Exibe uma contagem dos valores únicos da coluna Churn
df_clientes['Churn'].value_counts()
Nao 4387 Sim 1587 Name: Churn, dtype: int64
# Exibe a distribuição percentual dos valores únicos da coluna Churn
df_clientes['Churn'].value_counts(normalize=True)
Nao 0.734349 Sim 0.265651 Name: Churn, dtype: float64
Com esta análise inicial, concluímos que informação de que 26% dos clientes cancelaram o serviço estava correta mesmo.
Esta etapa envolve a criação de gráficos para podermos relacionar a coluna Churn com as demais colunas.
# Importa o plotly
import plotly.express as px
from plotly.offline import init_notebook_mode, iplot
init_notebook_mode(connected=True)
# Percorre a lista de colunas da tabela, comparando-as com a coluna Churn
for coluna in df_clientes.columns:
if coluna == 'IDCliente' or coluna == 'Churn':
continue
# Cria o histograma
grafico = px.histogram(df_clientes, x=coluna, color='Churn')
# Exibe o gráfico
grafico.show()
Analisando os gráficos, foi possível chegar as seguintes conclusões: