Skip to main content
27 February 2020
Follow Us

Power BI and R: living together - parte 2

Na segunda parte deste artigo, vou demonstrar como analisar a satisfação dos clientes da Olist. Mais do que simplesmente descrever ou caracterizar, vou procurar compreender o que explica a satisfação dos clientes desta empresa e como analisar os resultados no Power BI. Para tal, vou recorrer a um algoritmo de árvores de decisão utilizando a linguagem R. Se não teve a oportunidade de ler a primeira parte deste artigo, poderá fazê-lo a partir deste link.

Feature engineering – que variáveis determinam a satisfação do cliente?

A primeira etapa começa com a exploração dos dados. Não sabemos à partida que variáveis são mais importantes para a satisfação do cliente, mas com alguma análise exploratória e com o processo de clustering realizado na fase anterior, podemos começar a levantar algumas questões.

Será que os clientes que compram produtos de maior valor tendem a pontuar melhor ou pior? E em relação ao número de produtos, terá alguma influência no grau de satisfação dos clientes? Existirá alguma relação entre os tempos de entrega e os atrasos com a pontuação?

Esta e outras perguntas são legítimas e não devemos à partida desconsiderar qualquer uma delas. O clustering revelou algumas diferenças interessantes quanto ao tempo de entrega entre clusters. Por outro lado, parece existir uma relação importante entre os comentários e o nível de satisfação dos clientes.

O algoritmo que vamos utilizar para prever a satisfação do cliente é uma árvore de decisão. De uma forma resumida, podemos caracterizar este tipo de algoritmos como uma série de nós que se subdividem em vários ramos até chegarem a folhas. O algoritmo começa com uma raiz ou nó principal e segue uma série de partições que dividem os dados em função de diversos testes lógicos.

Por exemplo, se estiver a tentar prever se um determinado cliente de um ginásio vai abandonar a empresa ao fim de um ano, poderia conceber uma árvore do género:

árvore decisão

Nesta árvore, cuja raiz começa no topo, vemos como se decompõem os dados com base nas variáveis idade, género, número de modalidades e residência no Porto. O algoritmo começa por dividir a idade em menor do que 30 anos e maior ou igual a 30 anos. Esta variável deve ser a mais importante de todas, pois é a utilizada em primeiro lugar. Com base nessa divisão, faz outras divisões subsequentes até chegar a cada uma das folhas, a verde, onde se identifica o resultado (abandona ou não abandona).

Estes algoritmos podem lidar com muitas variáveis e têm a capacidade para descartar aquelas que não são importantes. São conhecidos como algoritmos “greedy” porque começam por dividir os dados a partir das variáveis mais importantes e as divisões que fazem à cabeça condicionam todas as restantes.

Vamos colocar este algoritmo em prática na Olist e tentar prever o grau de satisfação do cliente. As variáveis que escolhemos são as seguintes por cada cliente:

  • Valor do produto (em reais)
  • Número de produtos que o cliente comprou
  • Atraso no tempo de entrega em minutos
  • Tempo de entrega em minutos
  • Número de fotografias do produto exibidas na página
  • Hora em que fez a encomenda
  • Dia da semana em que fez a encomenda
  • Se fez ou não comentários na página
  • Se o comentário tem ou não um título

Analisando a estrutura dos dados temos:

Classes ‘tbl_df’, ‘tbl’ and 'data.frame': 51309 obs. of 10 variables:
$ valor_produto : num 130 69 180 135 105 ...
$ num_produtos : num 1 1 1 1 1 1 1 1 1 1 ...
$ atraso_entrega_minutos: num -5951 -2001 -10131 -39807 45399 ...
$ tempo_entrega_minutos : num 9217 37054 18902 6290 77580 ...
$ product_photos_qty : num 1 3 3 6 1 4 2 3 1 2 ...
$ hora_compra : int 10 21 19 23 15 15 14 13 14 22 ...
$ dia_semana : num 5 6 3 7 2 1 7 6 6 3 ...
$ titulo_comentario : Factor w/ 2 levels "0","1": 2 1 1 1 1 1 1 1 1 1 ...
$ fez_comentario : Factor w/ 2 levels "0","1": 2 1 1 1 2 1 2 1 2 2 ...
$ review_score : num 5 3 5 4 1 5 5 4 4 5 ...

Até aqui o código seria:

############################################################
# Árvores de regressão #
############################################################
# Previsão de ranking

# escolha de features
resumo_por_ranking <- inner_join(resumo_por_cliente, dataset_customer,
by = "customer_unique_id") %>%
select(c(1:6, 25, 28:30, 35:36))

# converter colunas comentários e cluster em variáveis numéricas
resumo_por_ranking$titulo_comentario <- ifelse(is.na(resumo_por_ranking$review_comment_title), 0,1)
resumo_por_ranking$fez_comentario <- ifelse(is.na(resumo_por_ranking$review_comment_message), 0, 1)

# eliminar colunas redundantes
resumo_por_ranking <- resumo_por_ranking %>%
select(-c(4, 9, 10 )) %>%
select(-7,7)

# retirar id do cliente
previsao_ranking <- resumo_por_ranking[,-1]

# alterar nomes e tipos de variáveis
previsao_ranking$fez_comentario <- factor(previsao_ranking$fez_comentario)
previsao_ranking$titulo_comentario<- factor(previsao_ranking$titulo_comentario)

# previsao_ranking$review_score <- factor(previsao_ranking$review_score)
previsao_ranking <- previsao_ranking %>%
rename(atraso_entrega_minutos = atraso_entrega_mins.x,
tempo_entrega_minutos = tempo_entrega_mins.x)

# analisar a estrutura dos dados
str(previsao_ranking)

Como vemos, todas as variáveis são numéricas, exceto as referentes ao comentário e ao título do comentário que são binárias. As árvores de decisão têm a vantagem de lidar bem não só com variáveis numéricas, mas também com variáveis categóricas e são igualmente eficazes em modelos preditivos de regressão e de classificação.

No R Studio, vamos carregar o algoritmo “Recursive Partitioning and Regression Trees” para resolver este modelo preditivo e dividir os dados em treino e teste. Nos dados de treino, vamos correr o algoritmo, para que este aprenda com os dados e, nos dados de teste, vamos avaliar a sua eficácia, isto é, vamos colocá-lo à prova com dados que ainda não conhece:

# dividir dados em treino e teste
set.seed(999)
vetor_sample <- sample(c(1:nrow(previsao_ranking)), 0.8*nrow(previsao_ranking))
ranking_treino <- previsao_ranking[vetor_sample,]
ranking_teste <- previsao_ranking[-vetor_sample,]

# criar árvore e treinar modelo
library(rpart)
arvore_ranking <- rpart(review_score ~., data = ranking_treino)

# sumário da árvore
arvore_ranking

# avaliar a capacidade preditiva do modelo
# calcular a soma do quadrado dos erros
calculo_SSE <-  function(real, previsoes) {
  return(sum((real - previsoes) ^ 2))
}

# fazer previsão com dados de teste
previsao_arvore <- predict (arvore_ranking, ranking_teste) 
SSE <- calculo_SSE(ranking_teste$review_score, previsao_arvore)
SSE

No sumário da árvore é possível visualizar as diferentes partições dos dados e a respetiva previsão da classificação. No primeiro nó, vemos que a divisão é efetuada pela variável que corresponde ao atraso na entrega medido em minutos. Esta variável é a mais importante e na árvore é claro que quando o atraso é superior ou igual a 3949 minutos, a classificação do cliente é de 1.98 e quando é inferior àquele valor, a classificação do cliente é de 4.25. Nãi há dúvida, que a empresa tem de prestar muita atenção à forma como gere a expetativa em termos de tempo de entrega do produto, mais até do que ao tempo de entrega em absoluto.

n= 41047
node), split, n, deviance, yval
      * denotes terminal node
 1) root 41047 69472.080 4.130582 
   2) atraso_entrega_minutos>=3949.139 2222  4409.676 1.938794 *
   3) atraso_entrega_minutos< 3949.139 38825 53777.160 4.256021 
     6) fez_comentario=1 15632 33374.740 3.933918 
      12) num_produtos>=1.5 1367  4024.871 3.202634 *
      13) num_produtos< 1.5 14265 28548.770 4.003996 *
     7) fez_comentario=0 23193 17687.490 4.473117 *

O código acima testa o modelo preditivo em dados de teste e apresenta uma classificação da ordem de importância das variáveis:

  • atraso_entrega_minutos 11288.375443
  • tempo_entrega_minutos  4970.782138
  • fez_comentario  2714.929918
  • num_produtos   809.604334
  • titulo_comentario   350.481613
  • valor_produto     2.387791

Nesta lista não figuram todas as variáveis carregadas no modelo, porque simplesmente não são importantes. Além do atraso nas entregas, a empresa deverá gerir com muita atenção o tempo de entrega, os comentários que os utilizadores colocam no site e o número de produtos que compram.


Assine a nossa newsletter e receba o nosso conteúdo diretamente no seu email