Empresas que enfrentam incertezas do mercado ou mudanças frequentes em seus produtos, serviços e processos precisar de métricas especÃficas que avaliem os diferentes momentos do ciclo de vida. E uma destas ferramentas é a Análise de Coorte (ou Análise Cohort).
Presente em muitas plataformas como o Google Analytics, o princÃpio por trás da métrica é de que clientes de perÃodos diferentes vão ter experiências diferentes, por mais sutis que aparentam ser.
Por definição, um coorte é um grupo de indivÃduos que compartilham a mesma caracterÃstica, e a métrica permite avaliar o comportamento do coorte durante o tempo e compará-lo com outros coortes. Em uma de suas aplicações no setor de marketing/comercial, a análise divide os clientes de acordo com o perÃodo de aquisição do produto ou serviço e o seu ciclo de vida em um intervalo definido.
Assim, é possÃvel analisar a retenção dos clientes durante o ciclo de vida do produto, e mais importante: durante o ciclo de vida do cliente, agrupado de acordo com o primeiro contato. Tudo isso de forma visual e intuitiva.
Desta forma, as métricas ficam bastante granulares e permitem avaliar com precisão o impacto das alterações, investimentos e campanhas, por exemplo.
Além da análise temporal, os coortes permitem dividir em outros grupos como:
E quaisquer agrupamentos que possam representar diferentes comportamentos ou necessidades dos clientes.
Para este exemplo será utilizado um conjunto de dados do repositório da UCI.
Os dados estão em uma planilha do excel (.xlsx) e representam vendas de uma loja on-line no Reino Unido. As colunas presentes no dataset são:
Número do pedido;Data do pedido;ID do cliente;Contudo, para elaboração da análise de coorte só serão utilizadas as 3 colunas em destaque.
Pacotes e bibliotecas Python utilizadas
import numpy as np
import pandas as pd
import datetime as dt
import matplotlib.pyplot as plt
import seaborn as sns
Leitura dos dados
df = pd.read_excel('Online Retail.xlsx')
df.head(5)
df.columns = ['PedidoNum', 'ProdutoCod', 'ProdutoDesc', 'Qtd', 'PedidoData', 'PrecoUnit', 'ClienteID', 'Pais']
df.info()
Na descrição do conjunto de dados é informado que os pedidos que se iniciam com C representam cancelamentos.
Portanto, estes registros serão eliminados do conjunto.
df= df[df['PedidoNum'].str[0] != 'C']
Contabilizando linhas com valores não preenchidos
df.isnull().sum()
Eliminando os registros que possuem valores não preenchidos, pois distorcem as contagems e cálculos utilizados.
df = df[df['ClienteID'].notnull()]
Verificando se existem vendas duplicadas
df.duplicated().sum()
Eliminando duplicadas
df = df.drop_duplicates()
df.duplicated().sum()
Conferindo estatÃsticas para ver se existe algum valor fora do padrão
df.describe()
Existem preços unitários com valor 0,00. Será puxado um exemplo dos registros:
df[df['PrecoUnit']==0].head()
Aparentemente são registros comuns, pode ser brindes ou promoções. Serão mantidos na análise.
Venda mais antiga
df['PedidoData'].min()
Venda mais recente
df['PedidoData'].max()
Como citado, serão utilzadas apenas 3 colunas:
A partir destas serão extraÃdos novos dados:
Neste caso a divisão dos clientes é por mês e o intervalo observado também. Em outros casos pode ser que intervalos mais curtos sejam melhores como aplicativos, sites, serviços ou campanhas, os quais necessitam uma análise mais granular.
def mes_ano(x) : return dt.datetime(x.year,x.month,1)
df['PedidoMes'] = df['PedidoData'].apply(mes_ano)
df['PrimeiroMes'] = df.groupby('ClienteID')['PedidoMes'].transform('min')
def get_month_int (dframe,column):
year = dframe[column].dt.year
month = dframe[column].dt.month
day = dframe[column].dt.day
return year, month , day
pedido_ano,pedido_mes,_ = get_month_int(df,'PedidoMes')
primeiro_ano,primeiro_mes,_ = get_month_int(df,'PrimeiroMes')
dif_ano = pedido_ano - primeiro_ano
dif_mes = pedido_mes - primeiro_mes
df['lifetime'] = dif_ano * 12 + dif_mes + 1
df
Agrupamento dos clientes por primeiro mês e ciclo de vida
agrup = df.groupby(['PrimeiroMes', 'lifetime'])
cohort = agrup['ClienteID'].apply(pd.Series.nunique)
cohort = cohort.reset_index()
cohort
A partir daqui é só pivotar (transpor) a matriz e plotar em esquema heatmap para ficar mais visual.
matriz_cohort = cohort.pivot(index='PrimeiroMes',columns='lifetime',values='ClienteID')
matriz_cohort.index = matriz_cohort.index.date
plt.figure(figsize=(15, 8))
plt.style.use('default')
plt.title('Análise Cohort - Quantidade de Clientes', pad=20)
sns.heatmap(data=matriz_cohort,annot = True,fmt = '.0f',cmap="cool", linecolor='white', linewidth=1)
plt.show()
Esta matriz diz respeito à quantidade de clientes.
Uma forma mais eficaz de visualizar a retenção é aplicando a taxa: dividindo a quantidade de clientes pelo total daquele coorte.
totaldeclientes = matriz_cohort.iloc[:,0]
retencao = matriz_cohort.divide(totaldeclientes,axis=0)
retencao.round(3) * 100
plt.figure(figsize=(15, 8))
plt.style.use('default')
plt.title('Análise Cohort - Retenção de clientes', pad=20)
sns.heatmap(data=retencao,annot = True,fmt = '.0%',cmap="BuPu", linecolor='white', linewidth=1, vmin=0, vmax=0.8)
plt.show()