A segmentação de clientes é essencial para alcançar um grupo específico de público, i.e, ajuda a alcançar as pessoas com quem a marca, produto e ou serviço realmente quer conversar, aumentando as chances de encontrar leads qualificados e gerar mais vendas.
Existem diferentes tipos de segmentação de clientes, definidos de acordo com as características de suas variáveis. O seu agrupamento pode conter elementos de apenas um tipo de segmentação ou, então, até mesmo combinar mais de um modelo para se chegar no perfil ideal para o trabalho comercial (vendas).
As comuns são: geográfica (quando a localização é factor chave para a decisão de compra), demográficas (costumam ser sexo, idade, estado civil, entre outros), comportamentais (gostos pessoais, preferências, comportamentos e hábitos) e psicográficas (atributos psicológicos, como: valores, estilo de vida e opiniões sobre temas relevantes).
A segmentação de clientes por RFM é uma técnica que avalia quais clientes são de maior e menor valor para uma organização, com base no tempo de retorno, na frequência e no valor monetário da compra, a fim de prever quais clientes têm maior probabilidade de fazer novamente compras no futuro. Este conceito é baseado na premissa de marketing de que \(80\%\) da sua receita provém de \(20\%\) de seus clientes. Esta técnica responde basicamente as três seguintes questões:
Em uma situação onde uma determinada empresa representante de várias marcas de roupas e acessórios, desconhecia os seus clientes, potenciais clientes e quais clientes são valiosos para a empresa, a empresa decidiu dar um segmento a todos o seus clientes de forma a responder as seguintes questões:
Também seria interessante, para o presente caso identificar:
Estas questões podem nos levar as seguintes percepções:
Os dados em análise são referentes a compras efectuadas no período de \(2011\) a \(2013\). Estes dados são meramente hipotéticos para efeitos de demonstração da técnica RFM score Analysis. Oportunamente com dados reais far-se-á um post seja em Python ou R para demonstrar o poder da técnica em classificação e segmentação de clientes. Contudo, para o presente estudo usar-se-á R.
Parafraseando John Wilder Tukey (1977)
, a análise exploratória é uma técnica que emprega grande variedade de técnicas quantitativas e gráficas visando maximizar a obtençao de informações das variáveis em causa.
Aplica-se esta etapa de forma a se familiarizar com o conjunto de dados que se tem por analisar.
library(pander)
library(tidyverse)
## -- Attaching packages ------------------------------------------------------------------------ tidyverse 1.3.0 --
## v ggplot2 3.3.0 v purrr 0.3.4
## v tibble 3.0.0 v dplyr 0.8.5
## v tidyr 1.0.2 v stringr 1.4.0
## v readr 1.3.1 v forcats 0.5.0
## -- Conflicts --------------------------------------------------------------------------- tidyverse_conflicts() --
## x dplyr::filter() masks stats::filter()
## x dplyr::lag() masks stats::lag()
library(highcharter)
## Registered S3 method overwritten by 'quantmod':
## method from
## as.zoo.data.frame zoo
## Highcharts (www.highcharts.com) is a Highsoft software product which is
## not free for commercial and Governmental use
df_sales <- readxl::read_xlsx("Sales.xlsx")
df_sales %>% head() %>% pander()
CustomerID | Total | Date |
---|---|---|
16250 | 6295 | 2011-01-01 |
17511 | 5148 | 2011-01-01 |
13448 | 6291 | 2011-01-01 |
15012 | 4708 | 2011-01-01 |
12472 | 2360 | 2011-01-01 |
18229 | 2780 | 2011-01-01 |
Primeiro, formata-se a data de forma a calcular correctamente, em seguida fixa-se uma data de referência para análise como sendo \(01-01-2014\).
# Converter em Formato Data (yyyy-mm-dd)
df_sales$Date <-
as.Date(df_sales$Date, "%Y-%m-%d")
## Warning in as.POSIXlt.POSIXct(x, tz = tz): unknown timezone '%Y-%m-%d'
# Data de Referência
date_ref <- as.Date('2014-01-01')
df_sales$Duration <- as.numeric(
difftime(
time1 = date_ref,
time2 = df_sales$Date,
units = "days"
)
)
# Dados após transformação
df_sales %>% head() %>% pander()
CustomerID | Total | Date | Duration |
---|---|---|---|
16250 | 6295 | 2011-01-01 | 1096 |
17511 | 5148 | 2011-01-01 | 1096 |
13448 | 6291 | 2011-01-01 | 1096 |
15012 | 4708 | 2011-01-01 | 1096 |
12472 | 2360 | 2011-01-01 | 1096 |
18229 | 2780 | 2011-01-01 | 1096 |
library(sqldf)
## Loading required package: gsubfn
## Loading required package: proto
## Loading required package: RSQLite
Nesta etapa, criar-se-á colunas calculadas contendo valores específicos de Recency, Frequency e Monetary. Adicionar-se-á também uma coluna Data_Purchase que é diferença da data de referência e data que o cliente efectou a compra. E para poder-se adicionar as colunas usa-se o código SQL.
# Compute recency, frequency, and average purchase amount
cust_df = sqldf(
"SELECT CustomerID,
MIN(Duration) AS 'Recency',
MAX (Duration) AS Date_Purchase,
COUNT(*) AS 'Frequency',
SUM(Total) AS 'Monetary'
FROM df_sales
GROUP BY 1"
)
cust_df %>% head() %>% pander()
CustomerID | Recency | Date_Purchase | Frequency | Monetary |
---|---|---|---|---|
12347 | 14 | 994 | 31 | 178001 |
12348 | 156 | 1031 | 17 | 76776 |
12370 | 11 | 1093 | 91 | 502537 |
12377 | 14 | 1079 | 43 | 222580 |
12386 | 236 | 1042 | 8 | 34223 |
12395 | 4 | 996 | 31 | 159825 |
Fazendo as estatísticas descritivas (sumarização) dos dados, tem-se:
cust_df[,-1] %>% summary() %>% pander()
Recency | Date_Purchase | Frequency | Monetary |
---|---|---|---|
Min. : 1.0 | Min. : 18 | Min. : 1.00 | Min. : 556 |
1st Qu.: 13.0 | 1st Qu.: 979 | 1st Qu.: 8.00 | 1st Qu.: 37494 |
Median : 45.0 | Median :1054 | Median : 17.00 | Median : 86018 |
Mean : 108.8 | Mean : 987 | Mean : 27.82 | Mean : 143609 |
3rd Qu.: 115.0 | 3rd Qu.:1083 | 3rd Qu.: 35.00 | 3rd Qu.: 182643 |
Max. :1026.0 | Max. :1096 | Max. :644.00 | Max. :3342290 |
Para avaliar a distribuição dos parâmetros RFM usar-se-á usar o histograma.
hist(cust_df$Recency,
breaks = 50,
main = "Histograma de Recência",
xlab = "Recência",
ylab = "Frequência")
hist(cust_df$Frequency,
breaks = 50,
main = "Histograma de Frequência",
xlab = "Frequência",
ylab = "Frequência")
hist(cust_df$Monetary,
breaks = 50,
main = "Histograma de Valores Monetários",
xlab = "Monetário",
ylab = "Frequência")
Para determinar os parâmetros RFM usa-se os quartis ou percentis. No presente caso, dividir-se-á o conjunto de dados em \(05\) partes iguais, ou seja divisão em \(20\%\) cada parte. A ideia é encontrar os Top \(20\%\) clientes mais valiosos.
quantile(cust_df$Recency, probs = seq(0, 1, 0.20)) %>% pander()
0% | 20% | 40% | 60% | 80% | 100% |
---|---|---|---|---|---|
1 | 10 | 28 | 60 | 145 | 1026 |
Para o parâmetro Recency, que é a análise da compra mais recente, classificam-se os Top \(20\) clientes atráves dos primeiros \(20\%\) do percentil. Portanto, a tabela acima mostra:
quantile(cust_df$Frequency, probs = seq(0, 1, 0.20)) %>% pander()
0% | 20% | 40% | 60% | 80% | 100% |
---|---|---|---|---|---|
1 | 6 | 14 | 22 | 43 | 644 |
Quanto à frequência com que fazem as compras, pode-se observar que:
quantile(cust_df$Monetary, probs = seq(0, 1, 0.20)) %>% pander()
0% | 20% | 40% | 60% | 80% | 100% |
---|---|---|---|---|---|
556 | 29757 | 68176 | 109592 | 219327 | 3342290 |
Quanto à valor monetário gasto com as compras, pode-se observar que:
Baseando-se no príncipio de pareto de que \(80\%\) dos seus negócios vêm de \(20\%\) dos seus clientes. O RFM ajuda a identificar clientes com maior probabilidade de responder a promoções, segmentando-os em várias categorias.
Usar-se-á o percentil \(20\) para se determinar os RFM score, i.e, dividir-se-á a série de dados em \(05\) partes iguais. Assim sendo, os Top \(20\) ficam com pontuação máxima de \(05\) pontos, enquanto que os últimos \(20\%\) ficam com a pontuação mínima de \(01\) ponto. Para análise do parâmetro R (Recency), a ordem deve ser invertida, i.e, os valores baixos levam pontuação máxima (\(05\) pontos) e os valores altos pontuação mínima (\(01\) ponto).
Portanto, o melhor cliente tem a pontuação máxima de \(555\) (RFM score) e o pior com pontuação mínima de \(111\) (RFM score) pontos.
# Cálculo de RFM scores
rfm_data <- cust_df
rfm_data <-
rfm_data %>%
mutate(
R = ntile(desc(Recency), 5),
F = ntile(Frequency, 5),
M = ntile(Monetary, 5)
)
rfm_data$RFM <- rfm_data$R * 100 + rfm_data$F * 10 + rfm_data$M
rfm_data %>% head(10) %>% pander()
CustomerID | Recency | Date_Purchase | Frequency | Monetary | R | F | M | RFM |
---|---|---|---|---|---|---|---|---|
12347 | 14 | 994 | 31 | 178001 | 4 | 4 | 4 | 444 |
12348 | 156 | 1031 | 17 | 76776 | 1 | 3 | 3 | 133 |
12370 | 11 | 1093 | 91 | 502537 | 4 | 5 | 5 | 455 |
12377 | 14 | 1079 | 43 | 222580 | 4 | 4 | 5 | 445 |
12386 | 236 | 1042 | 8 | 34223 | 1 | 2 | 2 | 122 |
12395 | 4 | 996 | 31 | 159825 | 5 | 4 | 4 | 544 |
12417 | 123 | 1083 | 11 | 63296 | 2 | 2 | 2 | 222 |
12427 | 295 | 1079 | 10 | 66185 | 1 | 2 | 2 | 122 |
12429 | 16 | 1083 | 20 | 103905 | 4 | 3 | 3 | 433 |
12431 | 70 | 1095 | 24 | 130577 | 2 | 4 | 4 | 244 |
Note que, quanto menor for o parâmetro Recency maior será o R score e RFM score. Assim sendo, os clientes com maior RFM score das \(10\) primeiras observações para o caso em estudo são: CustomerID - \(12347, 12370, 12377, 12395\) e os com menor RFM score são CustomerID - \(12386\) e \(12427\).
Neste caso de estudo, aplicou-se RFM score Analysis para segmentação de clientes. Este método exige que haja cuidadosa precisão ao definir e analisar os intervalos dos RFM scores, de forma que se assegure que não haja duplicação dos clientes em vários segmentos, i.e, cada cliente deve pertence exclusivamente a um único segmento.
Em RFM a segmentação de clientes pode ser feita conforme a tabela abaixo:
Tabela 1: Classificação e Segmentação de Clientes
Em alguns artigos sugerem a definição dos segmentos com base no bom senso e na natureza do negócio, contundo usando a Tabela 1, pode-se aplicar a classificação e segmentação abaixo que é aplicável para qualquer negócio.
# Definição de segmentação dos clientes por grupos
rfm_data$Segment <- NA
rfm_data$Segment[which(rfm_data$RFM == 111)] <- 'Clientes Perdidos'
rfm_data$Segment[which(rfm_data$RFM > 111)] <- 'Hibernando'
rfm_data$Segment[which(rfm_data$RFM >= 222)] <- 'A dormir'
rfm_data$Segment[which(rfm_data$RFM >= 333)] <-'Fieis Potenciais'
rfm_data$Segment[which(rfm_data$RFM >= 444)] <- 'Campeoes'
# 2nd round
rfm_data$Segment[which(rfm_data$Segment == 'Fieis Potenciais' &
(rfm_data$F >= 4))] <- 'Clientes Fieis'
rfm_data$Segment[which(rfm_data$Segment == 'A dormir' &
(rfm_data$M >= 4))] <- 'Precisam de Atencao'
rfm_data$Segment[which(rfm_data$Segment == 'Hibernando' &
(rfm_data$F >= 4 & rfm_data$M >= 4))] <- 'Nao perder-los'
rfm_data[, -c(3, 6,7,8)] %>%
head(10) %>% pander()
CustomerID | Recency | Frequency | Monetary | RFM | Segment |
---|---|---|---|---|---|
12347 | 14 | 31 | 178001 | 444 | Campeoes |
12348 | 156 | 17 | 76776 | 133 | Hibernando |
12370 | 11 | 91 | 502537 | 455 | Campeoes |
12377 | 14 | 43 | 222580 | 445 | Campeoes |
12386 | 236 | 8 | 34223 | 122 | Hibernando |
12395 | 4 | 31 | 159825 | 544 | Campeoes |
12417 | 123 | 11 | 63296 | 222 | A dormir |
12427 | 295 | 10 | 66185 | 122 | Hibernando |
12429 | 16 | 20 | 103905 | 433 | Fieis Potenciais |
12431 | 70 | 24 | 130577 | 244 | Precisam de Atencao |
Lembre-se, um cliente não pode pertencer simultâneamente a mais de um segmento. Entrentanto, para assegurar que os critérios definidos abrangem todos os clientes e que nenhum ficou sem classificação e segmento, verifcar-se-á de seguinte forma:
rfm_data[is.na(rfm_data$Segment),]
Conforme o resultado acima, observa-se que nenhum cliente pertence a dois ou mais segmentos.
Nesta etapa, mostra-se a distribuição dos clientes por segmentos.
# Re-ordenar os segmentos em função as cenários definidos
rfm_data$Segment <-
factor(
x = rfm_data$Segment,
levels = c(
'Clientes Perdidos',
'Hibernando',
'Nao perder-los',
'A dormir',
'Precisam de Atencao',
'Fieis Potenciais',
'Clientes Fieis',
'Campeoes'
)
)
# Tabela de Frequências
freqTable <-
rfm_data %>%
count(Segment) %>%
rename(Segmento = Segment, Contagem = n)
freqTable$Racio <- prop.table(table(rfm_data$Segment))*100
freqTable %>% pander()
Segmento | Contagem | Racio |
---|---|---|
Clientes Perdidos | 119 | 12.92 |
Hibernando | 99 | 10.75 |
Nao perder-los | 2 | 0.2172 |
A dormir | 170 | 18.46 |
Precisam de Atencao | 40 | 4.343 |
Fieis Potenciais | 114 | 12.38 |
Clientes Fieis | 87 | 9.446 |
Campeoes | 290 | 31.49 |
Note que, \(31,49\%\) dos clientes estão segmentados como Campeões, esta porcentagem está acima do axioma de marketing que \(80\%\) dos seus negócios vêm de \(20\%\) dos seus clientes, o que já garante a loja grandes negócios. Um ponto de atenção está para os clintes Need Attention (Precisão de Atenção) que estão a \(4.34\%\), uma vez que estes apresentam score abaixo da média de recência (Recency), frequência (Frequency) e valor monetário (Monetary Value), este grupo, requerá um trabalho estratégico para recuperar-lós.
Aplicar-se-á 2 gráficos para visualização dos segmentos definidos nos dados em estudo.
O Treemap mostra o valor monetário médio para diferentes categorias de pontuações recentes e de frequência.
hctreemap2(
data = freqTable,
group_vars = "Segmento",
size_var = "Contagem",
color_var = "Contagem"
)
## Warning: `as_data_frame()` is deprecated as of tibble 2.0.0.
## Please use `as_tibble()` instead.
## The signature and semantics have changed, see `?as_tibble`.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_warnings()` to see where this warning was generated.
Pontuações mais altas de frequência e recência são caracterizadas por um valor monetário médio mais alto, conforme indicado pelas áreas mais escuras no treemap.
O gráfico de barras mostra o número de clientes classificados por segmento.
highchart() %>%
hc_add_series(
data = freqTable,
type = 'column',
hcaes(x = Segmento, y = Contagem),
dataLabels = list(align = "center", enabled = TRUE,
style = list(
fontWeight = "bold",
color = "#4D4D4D",
textOutline = NULL
)
),
name = 'Segmentos'
) %>%
hc_xAxis(categories = unique(freqTable$Segmento)) %>%
hc_yAxis(title = list(text = "No de Clientes"))
## Warning: `parse_quosure()` is deprecated as of rlang 0.2.0.
## Please use `parse_quo()` instead.
## This warning is displayed once per session.
No presente trabalho aplicou-se RFM score Analysis para classificar e segmentar clientes de uma determinada empresa representante de várias marcas de roupas e acessórios, usando a linguagem de programção R.
Envolvidos \(921\) clientes, com mais de \(25,000\) transações para o estudo, assim foi a segmentação usando esta técnica: \(31.49\%\) dos clientes, correspondentes as \(290\) foram classificados como Campeões, estes são clientes que tem RFM score maior e igual a 444 pontos. Outro grupo com maior porcentagem segmentada é o About To Sleep (A dormir) que apresenta \(18.46\%\) dos clientes, entretanto, esta linha, precisará de um trabalho árduo de forma a recuperar-los e oferecer uma promoção.
Uma técnica similar a esta que desafio a usarem é Cluster Analysis (Análise de Agrupamentos) para efeitos comparativos de aplicabilidade.