Conheça a Market Basket Analysis e o algoritmo APRIORI por trás dela. Veja como isso ajuda varejistas a impulsionar resultados prevendo itens comprados juntos.
Você é um cientista de dados (ou está se tornando um!) e recebe um cliente que tem uma loja de varejo. Esse cliente te entrega os dados de todas as transações — os itens comprados na loja por diversos clientes ao longo do tempo — e pede para você usar essas informações para impulsionar o negócio. As suas descobertas vão orientar não só ajustes no estoque (incluir/retirar/atualizar produtos), mas também mudanças no layout da loja física ou do e-commerce. Para gerar insights que ajudem seu cliente, você vai usar a Market Basket Analysis (MBA), que aplica mineração de regras de associação sobre os dados de transações.
Neste tutorial você vai aprender:
O que é mineração de regras de associação e onde aplicar
O que é o algoritmo APRIORI
Como implementar MBA/mineração de regras de associação em R com visualizações
Mineração de regras de associação
A mineração de regras de associação é usada quando queremos identificar associações entre diferentes objetos em um conjunto, encontrar padrões frequentes em um banco de transações, bancos relacionais ou qualquer outro repositório de informações. Suas aplicações aparecem em Marketing, análise de cesta (Market Basket Analysis) no varejo, clusterização e classificação. Ela mostra que itens os clientes costumam comprar juntos, gerando um conjunto de regras chamadas regras de associação. Em palavras simples, o resultado são regras no formato se isso, então aquilo. Os clientes podem usar essas regras em várias estratégias de marketing, como:
Mudar o layout da loja conforme as tendências
Analisar o comportamento do cliente
Desenho de catálogo
Cross marketing em lojas online
Identificar itens em alta entre os clientes
E-mails personalizados com ofertas complementares
Considere o exemplo a seguir:
Temos um conjunto de dados de transações numeradas de 1 a 5. Cada transação lista os itens comprados. Note que fralda é comprada com cerveja em três transações. De forma parecida, pão é comprado com leite em três transações — ambos são conjuntos de itens frequentes. As regras de associação são escritas no formato abaixo:
$A=>B[Support,Confidence]$
A parte antes de $=>$ é o se (antecedente) e a parte depois é o então (consequente).
Onde A e B são conjuntos de itens nas transações. A e B são conjuntos disjuntos.
Ou seja, o número de transações com A e B dividido pelo total de transações que têm A.
$Confidence(Bread=>Milk)=\frac{3}{4}=0.75=75\%$
Agora calcule a confiança de Milk=>Diaper.
Observação: Suporte e confiança medem o quão interessante é a regra. Definimos limites mínimos (min_support e min_confidence). Esses thresholds, definidos pelo cliente, ajudam a comparar a força das regras. Quanto mais próximos ou acima do limite, mais útil a regra tende a ser.
Itemsets frequentes: Conjuntos de itens cujo suporte é maior ou igual ao suporte mínimo (min_sup). No exemplo acima, min_sup=3. Esse valor é definido pelo usuário.
Regras fortes: Se uma regra A=>B[Support, Confidence] atende min_sup e min_confidence, ela é considerada forte.
Lift: O lift indica a correlação entre A e B na regra A=>B. A correlação mostra como o itemset A afeta o itemset B.
$Lift(A=>B)=\frac{Support}{Supp(A)Supp(B)}$
Por exemplo, para a regra {Bread}=>{Milk}, o lift é calculado assim:
$support(Bread)=\frac{4}{5}=0.8$
$support(Milk)=\frac{4}{5}=0.8$
$Lift(Bread=>Milk)=\frac{0.6}{0.8*0.8}=0.9$
Se o lift for 1, A e B são independentes e não há regra útil entre eles.
Se o lift for > 1, A e B são dependentes, e o grau dessa dependência é dado pelo valor do lift.
Se o lift for < 1, a presença de A tem efeito negativo sobre B.
Objetivo da mineração de regras de associação
Ao aplicar a mineração de regras de associação a um conjunto de transações T, seu objetivo é encontrar todas as regras com:
Suporte maior ou igual a min_support
Confiança maior ou igual a min_confidence
Algoritmo APRIORI
Nesta parte do tutorial, você vai conhecer o algoritmo por trás das bibliotecas de R para Market Basket Analysis. Isso ajuda a entender melhor o problema do cliente e a analisar com mais precisão. Se você já conhece o algoritmo APRIORI e como ele funciona, pode pular direto para a parte de código.
A mineração de regras de associação é vista como um processo em duas etapas:
Geração de itemsets frequentes: encontrar todos os itemsets frequentes com suporte >= min_support pré-definido
Geração de regras: listar todas as regras de associação a partir dos itemsets frequentes. Calcular suporte e confiança de todas as regras. Podar as regras que não atendem os thresholds de min_support e min_confidence.
Gerar itemsets frequentes é a etapa mais custosa computacionalmente porque exige varrer todo o banco de dados.
Entre as etapas acima, a geração de itemsets frequentes é a mais pesada em termos de computação.
Acima vimos um exemplo com apenas 5 transações, mas na prática os dados de varejo podem chegar a GBs e TBs — por isso é preciso um algoritmo otimizado para descartar itemsets que não ajudarão nas etapas seguintes. É aí que entra o algoritmo APRIORI. Ele estabelece que:
Qualquer subconjunto de um itemset frequente também deve ser frequente. Em outras palavras, não devemos gerar ou testar supersets de um itemset infrequente.
Isso é representado no itemset lattice, uma representação gráfica do princípio do APRIORI. Ele consiste em nós de k-itemsets e as relações de subconjuntos desse k-itemset.
No diagrama acima, a base são todos os itens nos dados de transação; depois vamos subindo criando subconjuntos até o conjunto vazio. Para d itens, o tamanho do lattice será $2^d$. Isso mostra como seria custoso gerar itemsets frequentes calculando suporte para cada combinação. A figura seguinte mostra quanto o APRIORI ajuda a reduzir o número de conjuntos a gerar:
Se o itemset {a,b} é infrequente, não precisamos considerar nenhum de seus supersets.
Vamos entender com um exemplo. No exemplo a seguir, você verá por que o APRIORI é eficaz e também como gerar regras de associação fortes passo a passo. Pegue seu caderno e venha junto!
Como você vê, começamos criando a lista de candidatos para os 1-itemsets, que inclui individualmente todos os itens presentes nos dados. Considerando dados reais de varejo, dá para imaginar o custo de gerar candidatos. Aqui o APRIORI ajuda a reduzir a lista de candidatos e, ao final, regras úteis são geradas. Nos próximos passos, veremos como chegar ao fim da geração de itemsets frequentes — a primeira etapa da mineração de regras de associação.
O próximo passo é listar todos os itemsets frequentes. Você vai pegar o último itemset frequente não vazio, que neste exemplo é L2={I1, I2},{I2, I3}. Em seguida, gerar todos os subconjuntos não vazios dos itemsets presentes nessa lista de itemsets frequentes. Acompanhe como na ilustração abaixo:
Acima vemos quatro regras fortes. Por exemplo, ${I2}=>I3$ com confiança de 75% indica que 75% das pessoas que compraram I2 também compraram I3.
Pronto: você aprendeu o algoritmo APRIORI, um dos mais usados em mineração de dados. Bora para o código!
Implementando MBA/mineração de regras de associação em R
Neste tutorial, vamos usar um dataset do UCI Machine Learning Repository. O conjunto se chama Online-Retail e pode ser baixado aqui. Ele contém transações de 01/12/2010 a 09/12/2011 de um varejista online sem loja física registrado no Reino Unido. O motivo de usar este, e não um dataset nativo do R, é que você provavelmente receberá dados de varejo neste formato e terá que fazer pré-processamento.
Descrição do dataset
Número de linhas: 541909
Número de atributos: 08
Informações dos atributos
InvoiceNo: número da nota. Nominal; inteiro de 6 dígitos único por transação. Se começar com a letra "c", indica cancelamento. +StockCode: código do produto (item). Nominal; inteiro de 5 dígitos único por produto.
Description: nome do produto (item). Nominal.
Quantity: quantidades de cada produto (item) por transação. Numérico.
InvoiceDate: data e hora da nota. Numérico; dia e hora da geração da transação. Ex.: 12/1/2010 8:26
UnitPrice: preço unitário. Numérico; preço por unidade em libras esterlinas.
CustomerID: número do cliente. Nominal; inteiro de 5 dígitos único por cliente.
Country: país. Nominal; país de residência do cliente.
Carregando bibliotecas
Primeiro, vamos carregar as bibliotecas necessárias. Uma breve descrição (retirada daqui) está na tabela a seguir para você saber o que cada uma faz:
Package
Description
arules
Fornece a infraestrutura para representar, manipular e analisar dados de transações e padrões (itemsets frequentes e regras de associação).
arulesViz
Estende o pacote 'arules' com várias técnicas de visualização para regras de associação e itemsets. Inclui visualizações interativas para explorar regras.
tidyverse
Conjunto opinativo de pacotes R voltados a ciência de dados
readxl
Ler arquivos Excel no R
plyr
Ferramentas para dividir, aplicar e combinar dados
ggplot2
Criar gráficos e visualizações
knitr
Geração de relatórios dinâmicos no R
lubridate
O lubridate facilita trabalhar com datas e horas no R.
#install and load package arules#install.packages("arules")
library(arules)#install and load arulesViz#install.packages("arulesViz")
library(arulesViz)#install and load tidyverse#install.packages("tidyverse")
library(tidyverse)#install and load readxml#install.packages("readxml")
library(readxl)#install and load knitr#install.packages("knitr")
library(knitr)#load ggplot2 as it comes in tidyverse
library(ggplot2)#install and load lubridate#install.packages("lubridate")
library(lubridate)#install and load plyr#install.packages("plyr")
library(plyr)
library(dplyr)Tecnologia
Pré-processamento dos dados
Use read_excel(path to file) para ler o arquivo baixado no R. Informe o caminho completo, incluindo o nome do arquivo, em read_excel(path-to-file-with-filename)
#read excel into R dataframe
retail <- read_excel('D:/Documents/Online_Retail.xlsx')#complete.cases(data) will return a logical vector indicating which rows have no missing values. Then use the vector to get only rows that are complete using retail[,].
retail <- retail[complete.cases(retail),]#mutate function is from dplyr package. It is used to edit or add new columns to dataframe. Here Description column is being converted to factor column. as.factor converts column to factor column. %>% is an operator with which you may pipe values to another function or expression
retail %>% mutate(Description = as.factor(Description))Tecnologia
#Converts character data to date. Store InvoiceDate as date in new variable
retail$Date <- as.Date(retail$InvoiceDate)#Extract time from InvoiceDate and store in another variable
TransTime<- format(retail$InvoiceDate,"%H:%M:%S")#Convert and edit InvoiceNo into numeric
InvoiceNo <- as.numeric(as.character(retail$InvoiceNo))Tecnologia
Agora o dataframe retail terá 10 atributos, com dois adicionais: Date e Time.
Antes de aplicar MBA/mineração de regras de associação, precisamos converter o dataframe em dados de transação, de forma que todos os itens comprados juntos em uma mesma nota fiquem em uma única linha. No output do glimpse dá para ver que cada transação está em formato atômico — todos os produtos de uma nota estão atomizados como em bancos relacionais. Esse formato também é chamado de singles.
Você precisa agrupar os dados do retail por CustomerID, CustomerID e Date, ou agrupar por InvoiceNo e Date. Vamos aplicar uma função nesse agrupamento e salvar a saída em outro dataframe. Isso pode ser feito com ddply.
As linhas abaixo combinam todos os produtos de um mesmo InvoiceNo e Date em uma linha, com cada item separado por ,
library(plyr)#ddply(dataframe, variables_to_be_used_to_split_data_frame, function_to_be_applied)
transactionData <- ddply(retail,c("InvoiceNo","Date"),function(df1)paste(df1$Description,
collapse =","))#The R function paste() concatenates vectors to character and separated results using collapse=[any optional charcater string ]. Here ',' is usedTecnologia
Em seguida, como InvoiceNo e Date não serão úteis na mineração de regras, podemos definir como NULL.
#set column InvoiceNo of dataframe transactionData
transactionData$InvoiceNo <-NULL#set column Date of dataframe transactionData
transactionData$Date <-NULL#Rename column to items
colnames(transactionData)<- c("items")#Show Dataframe transactionData
transactionDataTecnologia
Nota: página 1 de 100.
Esse formato de dados de transação é chamado de formato basket. Agora, salve esses dados em um arquivo .csv (Comma Separated Values) usando write.csv()
write.csv(transactionData,"D:/Documents/market_basket_transactions.csv", quote =FALSE, row.names =FALSE)#transactionData: Data to be written#"D:/Documents/market_basket.csv": location of file with file name to be written to#quote: If TRUE it will surround character or factor column with double quotes. If FALSE nothing will be quoted#row.names: either a logical value indicating whether the row names of x are to be written along with x, or a character vector of row names to be written.Tecnologia
Confira se os dados ficaram no formato correto:
Agora vamos carregar esse CSV em um objeto da classe transaction. Use a função read.transactions do pacote arules.
O código abaixo lê o arquivo D:/Documents/market_basket_transactions.csv no formato basket e converte em um objeto da classe transaction.
tr <- read.transactions('D:/Documents/market_basket_transactions.csv', format ='basket', sep=',')#sep tell how items are separated. In this case you have separated using ','Tecnologia
Ao executar, você pode ver várias mensagens EOF within quoted string — não se preocupe.
Se você já tem os dados de transação em um dataframe, use a linha abaixo para converter em transaction:
transactions in sparse format with
22191 transactions (rows) and
7876 items (columns)
transactions as itemMatrix in sparse format with
22191 rows (elements/itemsets/transactions) and
7876 columns (items) and a density of 0.001930725
most frequent items:
WHITE HANGING HEART T-LIGHT HOLDER REGENCY CAKESTAND 3 TIER
18031709
JUMBO BAG RED RETROSPOT PARTY BUNTING
14601285
ASSORTED COLOUR BIRD ORNAMENT (Other)1250329938
element (itemset/transaction) length distribution:
sizes
12345678910111213141516173598159411419088617586966766635936245375165315515224641819202122232425262728293031323334441483419395315306272238253229213222215170159138142353637383940414243444546474849505113410911190113949387886563676360594964525354555657585960616263646566676840414943362939302728172525202724226970717273747576777879808182838485152019131616111512791415128911868788899091929394959697989910010110211148656116443652424103104105106107108109110111112113114116117118120121432263432131333121221231251261271311321331341401411421431451461471502132211211221121115415716817117717818020220422823624925028532040041932221111111111111
Min. 1st Qu. Median Mean 3rd Qu. Max.
1.003.0010.0015.2121.00419.00
includes extended item information - examples:
labels
11 HANGER
210 COLOUR SPACEBOY PEN
312 COLOURED PARTY BALLOONSTecnologia
summary(tr) é um comando bem útil que traz informações sobre o objeto de transações. O que esse output diz:
Existem 22191 transações (linhas) e 7876 itens (colunas). Note que 7876 são as descrições de produtos no dataset e 22191 transações são combinações desses itens.
Densidade indica a porcentagem de células não nulas na matriz esparsa. Dá para ver como o total de itens comprados dividido pelo total possível de células. Você pode estimar quantos itens foram comprados usando a densidade: 22191x7876x0.001930725=337445
Informação! Matriz esparsa: é uma matriz em que a maioria dos elementos é zero. Em contraste, se a maioria for diferente de zero, a matriz é densa. A razão entre elementos zero e o total é a esparsidade (que é 1 menos a densidade).
O summary também mostra os itens mais frequentes.
Distribuição do tamanho dos itemsets/transações: quantas transações existem com 1 item, 2 itens e assim por diante. A primeira linha mostra o nº de itens e a segunda, o nº de transações.
Por exemplo, há 3598 transações com um único item, 1594 com 2 itens, e existe uma transação com 419 itens — a mais longa.
Você pode gerar um itemFrequencyPlot (gráfico de barras) para ver a distribuição dos objetos com base em um itemMatrix (ex.: >transactions ou itens em >itemsets e >rules), que é o nosso caso.
# Create an item frequency plot for the top 20 itemsif(!require("RColorBrewer")){# install color package of R
install.packages("RColorBrewer")#include library RColorBrewer
library(RColorBrewer)}
itemFrequencyPlot(tr,topN=20,type="absolute",col=brewer.pal(8,'Pastel2'), main="Absolute Item Frequency Plot")Tecnologia
o primeiro argumento é o objeto de transações a ser plotado, tr. topN define quantos itens mais frequentes exibir. type pode ser type="absolute" ou type="relative". Em absoluto, plota as frequências numéricas de cada item. Em relativo, mostra quantas vezes os itens aparecem em comparação aos demais.
itemFrequencyPlot(tr,topN=20,type="relative",col=brewer.pal(8,'Pastel2'),main="Relative Item Frequency Plot")Tecnologia
Esse gráfico mostra que 'WHITE HANGING HEART T-LIGHT HOLDER' e 'REGENCY CAKESTAND 3 TIER' são os mais vendidos. Para aumentar as vendas de 'SET OF 3 CAKE TINS PANTRY DESIGN', o varejista pode posicioná-lo perto de 'REGENCY CAKESTAND 3 TIER'.
set of 49122 rules
rule length distribution (lhs + rhs):sizes
234567891010521116854164241485561021937613121
Min. 1st Qu. Median Mean 3rd Qu. Max.
2.0005.0005.0005.4996.00010.000
summary of quality measures:
support confidence lift count
Min. :0.001036 Min. :0.8000 Min. :9.846 Min. :23.001st Qu.:0.0010821st Qu.:0.83331st Qu.:22.2371st Qu.:24.00
Median :0.001262 Median :0.8788 Median :28.760 Median :28.00
Mean :0.001417 Mean :0.8849 Mean :64.589 Mean :31.453rd Qu.:0.0015323rd Qu.:0.92593rd Qu.:69.2003rd Qu.:34.00
Max. :0.015997 Max. :1.0000 Max. :715.839 Max. :355.00
mining info:
data ntransactions support confidence
tr 221910.0010.8Tecnologia
apriori recebe tr como o objeto de transações a ser minerado. Em parameter você define min_sup e min_confidence. Os valores padrão são suporte mínimo 0.1, confiança mínima 0.8 e até 10 itens por regra (maxlen).
summary(association.rules) mostra:
Parâmetros: min_sup=0.001 e min_confidence=0.8, com no máximo 10 itens por regra.
Total de regras:49122 regras
Distribuição do tamanho das regras: regras com 5 itens são a maioria: 16424; regras com 2 itens são as menos numerosas: 105
Resumo das medidas de qualidade: valores mínimos e máximos de suporte, confiança e lift.
Informações da mineração: dados, suporte e confiança usados.
Como são 49122 regras, vamos imprimir só as 10 primeiras:
A partir desse output, você pode concluir, por exemplo:
100% dos clientes que compraram 'WOBBLY CHICKEN' também compraram 'METAL'.
100% dos clientes que compraram 'BLACK TEA' também compraram 'SUGAR JARS'.
Limitando o número e o tamanho das regras
Como limitar a quantidade e o tamanho das regras geradas? Ajustando os parameters no apriori. Aumente conf para regras mais fortes e maxlen para permitir regras mais longas.
which(): retorna as posições dos elementos TRUE em um vetor.
colSums(): soma por coluna em dataframes e arrays numéricos.
is.subset(): determina se elementos de um vetor contêm todos os elementos de outro.
Encontrando regras relacionadas a itens específicos
Às vezes você quer focar em um produto específico. Para descobrir o que influencia a compra do item X, use a opção appearance em apriori. Com appearance você define o LHS (parte SE) e o RHS (parte ENTÃO) da regra.
Por exemplo, para descobrir o que os clientes compram antes de comprar 'METAL', rode:
# Here lhs=METAL because you want to find out the probability of that in how many customers buy METAL along with other items
inspect(head(metal.association.rules))Tecnologia
Apriori
Parameter specification:
confidence minval smax arem aval originalSupport maxtime support minlen maxlen target
0.80.11 none FALSETRUE50.001110 rules
ext
FALSE
Algorithmic control:
filter tree heap memopt load sort verbose
0.1TRUETRUEFALSETRUE2TRUE
Absolute minimum support count:22
set item appearances ...[1 item(s)] done [0.00s].
set transactions ...[30066 item(s),22191 transaction(s)] done [0.10s].
sorting and recoding items ...[2324 item(s)] done [0.02s].
creating transaction tree ... done [0.02s].
checking subsets of size 12 done [0.01s].
writing ...[1 rule(s)] done [0.00s].
creating S4 object ... done [0.01s].Tecnologia
# Here lhs=METAL because you want to find out the probability of that in how many customers buy METAL along with other items
inspect(head(metal.association.rules))Tecnologia
lhs rhs support confidence lift count
[1]{METAL}=>{DECORATION}0.0022531661443.8250Tecnologia
Visualizando regras de associação
Como os dados podem gerar centenas ou milhares de regras, você precisa de boas formas de apresentar seus achados. Já falamos do ItemFrequencyPlot, ótimo para ver os itens mais vendidos.
Vamos ver as seguintes visualizações:
Dispersão (scatter plot)
Dispersão interativa
Representação individual de regra
Scatter plot
Uma visualização direta das regras é o scatter plot usando plot() do arulesViz. Os eixos usam suporte e confiança; o lift colore os pontos (tons de cinza por padrão).
# Filter rules with confidence greater than 0.4 or 40%
subRules<-association.rules[quality(association.rules)$confidence>0.4]#Plot SubRules
plot(subRules)Tecnologia
O gráfico acima mostra que regras com lift alto costumam ter suporte baixo. Você pode usar as opções abaixo:
O two-key plot usa suporte (x) e confiança (y). A cor representa a ordem — o número de itens na regra.
Scatter plot interativo
Uma visualização interativa excelente combina arulesViz e plotly. Você pode passar o mouse sobre cada regra e ver todas as métricas (suporte, confiança e lift).
'plotly_arules' is deprecated.
Use 'plot' instead.
See help("Deprecated")plot: Too many rules supplied. Only plotting the best 1000 rules using measure lift (change parameter max if needed)To reduce overplotting, jitter is added! Use jitter =0 to prevent jitter.Tecnologia
Visualizações baseadas em grafos
Técnicas baseadas em grafos representam regras com vértices e arestas: vértices rotulados com nomes de itens e um segundo conjunto de vértices para itemsets ou regras. Itens se conectam a itemsets/regras por setas direcionadas. Setas de itens para vértices de regra indicam LHS; de regra para item indicam RHS. Tamanho e cor dos vértices costumam representar medidas de interesse.
Gráficos em grafo são ótimos, mas ficam poluídos com muitas regras. Então é melhor visualizar menos regras nesses casos.
Vamos selecionar 10 regras de subRules com maior confiança.
top10subRules <- head(subRules, n =10, by ="confidence")Tecnologia
Agora, plote um grafo interativo:
Observação: Você pode tornar todos os gráficos interativos usando engine=htmlwidget em plot
No arulesViz, grafos de conjuntos de regras de associação podem ser exportados em GraphML ou como Graphviz dot-file para ferramentas como o Gephi. Por exemplo, para exportar as 1000 regras com maior lift:
saveAsGraph(head(subRules, n =1000, by ="lift"), file ="rules.graphml")Tecnologia
Representação individual de regra
Também chamada de parallel coordinates plot. Útil para visualizar quais produtos, combinados com outros itens, influenciam certos resultados de venda.
Como citado, o RHS é o consequente — o item que sugerimos que o cliente comprará; as posições no LHS mostram que 2 é a adição mais recente ao carrinho e 1 é o item previamente adicionado.
# Filter top 20 rules with highest lift
subRules2<-head(subRules, n=20, by="lift")
plot(subRules2, method="paracoord")Tecnologia
Veja a seta superior: quando tenho 'CHILDS GARDEN SPADE PINK' e 'CHILDS GARDEN RAKE PINK' no carrinho, é provável que eu compre também 'CHILDS GARDEN RAKE BLUE'.
Conclusão
Parabéns! Você aprendeu o APRIORI, um dos algoritmos mais usados em mineração de dados. Viu os fundamentos da mineração de regras de associação, suas aplicações e como isso se traduz no varejo com a Market Basket Analysis. Você também já está pronto para implementar Market Basket Analysis em R e apresentar suas regras com visualizações de impacto. Bons estudos!
Neste tutorial, você aprenderá a usar o R PCA (Principal Component Analysis) para extrair dados com muitas variáveis e criar visualizações para exibir esses dados.
Você é um cientista de dados (ou está se tornando um!) e recebe um cliente que tem uma loja de varejo. Esse cliente te entrega os dados de todas as transações — os itens comprados na loja por diversos clientes ao longo do tempo — e pede para você usar essas informações para impulsionar o negócio. As suas descobertas vão orientar não só ajustes no estoque (incluir/retirar/atualizar produtos), mas também mudanças no layout da loja física ou do e-commerce. Para gerar insights que ajudem seu cliente, você vai usar a Market Basket Analysis (MBA), que aplica mineração de regras de associação sobre os dados de transações.
Neste tutorial você vai aprender:
Mineração de regras de associação
A mineração de regras de associação é usada quando queremos identificar associações entre diferentes objetos em um conjunto, encontrar padrões frequentes em um banco de transações, bancos relacionais ou qualquer outro repositório de informações. Suas aplicações aparecem em Marketing, análise de cesta (Market Basket Analysis) no varejo, clusterização e classificação. Ela mostra que itens os clientes costumam comprar juntos, gerando um conjunto de regras chamadas regras de associação. Em palavras simples, o resultado são regras no formato se isso, então aquilo. Os clientes podem usar essas regras em várias estratégias de marketing, como:
Considere o exemplo a seguir:
Temos um conjunto de dados de transações numeradas de 1 a 5. Cada transação lista os itens comprados. Note que fralda é comprada com cerveja em três transações. De forma parecida, pão é comprado com leite em três transações — ambos são conjuntos de itens frequentes. As regras de associação são escritas no formato abaixo:
$A=>B[Support,Confidence]$
A parte antes de $=>$ é o se (antecedente) e a parte depois é o então (consequente).
Onde A e B são conjuntos de itens nas transações. A e B são conjuntos disjuntos.
$Computer=>Anti-virus Software[Support=20\%,confidence=60\%]$
Essa regra diz que:
Na próxima seção você vai ver os conceitos básicos de mineração de regras de associação:
Conceitos básicos de mineração de regras de associação
Itemset (conjunto de itens): Coleção de um ou mais itens. K-itemset é um conjunto com k itens.
Contagem de suporte: Frequência de ocorrência de um itemset.
Suporte (s): Fração de transações que contêm o itemset "X"
$Support(X)=\frac{frequency(X)}{N}$
Para uma regra A=>B, o suporte é dado por:
$Support(A=>B)=\frac{frequency(A,B)}{N}$
Observação: P(A∪B) é a probabilidade de A e B ocorrerem juntos. P denota probabilidade.
Tente calcular o suporte para Milk=>Diaper como exercício.
$Confidence(A=>B)=\frac{P(A\cap B)}{P(A)}=\frac{frequency(A,B)}{frequency(A)}$
Ou seja, o número de transações com A e B dividido pelo total de transações que têm A.
$Confidence(Bread=>Milk)=\frac{3}{4}=0.75=75\%$
Agora calcule a confiança de Milk=>Diaper.
Observação: Suporte e confiança medem o quão interessante é a regra. Definimos limites mínimos (min_support e min_confidence). Esses thresholds, definidos pelo cliente, ajudam a comparar a força das regras. Quanto mais próximos ou acima do limite, mais útil a regra tende a ser.
Itemsets frequentes: Conjuntos de itens cujo suporte é maior ou igual ao suporte mínimo (min_sup). No exemplo acima, min_sup=3. Esse valor é definido pelo usuário.
Regras fortes: Se uma regra A=>B[Support, Confidence] atende min_sup e min_confidence, ela é considerada forte.
Lift: O lift indica a correlação entre A e B na regra A=>B. A correlação mostra como o itemset A afeta o itemset B.
$Lift(A=>B)=\frac{Support}{Supp(A)Supp(B)}$
Por exemplo, para a regra
{Bread}=>{Milk}, o lift é calculado assim:$support(Bread)=\frac{4}{5}=0.8$
$support(Milk)=\frac{4}{5}=0.8$
$Lift(Bread=>Milk)=\frac{0.6}{0.8*0.8}=0.9$
Se o lift for 1, A e B são independentes e não há regra útil entre eles.
Se o lift for > 1, A e B são dependentes, e o grau dessa dependência é dado pelo valor do lift.
Se o lift for < 1, a presença de A tem efeito negativo sobre B.
Objetivo da mineração de regras de associação
Ao aplicar a mineração de regras de associação a um conjunto de transações T, seu objetivo é encontrar todas as regras com:
Algoritmo APRIORI
Nesta parte do tutorial, você vai conhecer o algoritmo por trás das bibliotecas de R para Market Basket Analysis. Isso ajuda a entender melhor o problema do cliente e a analisar com mais precisão. Se você já conhece o algoritmo APRIORI e como ele funciona, pode pular direto para a parte de código.
A mineração de regras de associação é vista como um processo em duas etapas:
Geração de itemsets frequentes: encontrar todos os itemsets frequentes com suporte >= min_support pré-definido
Geração de regras: listar todas as regras de associação a partir dos itemsets frequentes. Calcular suporte e confiança de todas as regras. Podar as regras que não atendem os thresholds de min_support e min_confidence.
Gerar itemsets frequentes é a etapa mais custosa computacionalmente porque exige varrer todo o banco de dados.
Entre as etapas acima, a geração de itemsets frequentes é a mais pesada em termos de computação.
Acima vimos um exemplo com apenas 5 transações, mas na prática os dados de varejo podem chegar a GBs e TBs — por isso é preciso um algoritmo otimizado para descartar itemsets que não ajudarão nas etapas seguintes. É aí que entra o algoritmo APRIORI. Ele estabelece que:
Isso é representado no itemset lattice, uma representação gráfica do princípio do APRIORI. Ele consiste em nós de k-itemsets e as relações de subconjuntos desse k-itemset.
No diagrama acima, a base são todos os itens nos dados de transação; depois vamos subindo criando subconjuntos até o conjunto vazio. Para d itens, o tamanho do lattice será $2^d$. Isso mostra como seria custoso gerar itemsets frequentes calculando suporte para cada combinação. A figura seguinte mostra quanto o APRIORI ajuda a reduzir o número de conjuntos a gerar:
Se o itemset {a,b} é infrequente, não precisamos considerar nenhum de seus supersets.
Vamos entender com um exemplo. No exemplo a seguir, você verá por que o APRIORI é eficaz e também como gerar regras de associação fortes passo a passo. Pegue seu caderno e venha junto!
Como você vê, começamos criando a lista de candidatos para os 1-itemsets, que inclui individualmente todos os itens presentes nos dados. Considerando dados reais de varejo, dá para imaginar o custo de gerar candidatos. Aqui o APRIORI ajuda a reduzir a lista de candidatos e, ao final, regras úteis são geradas. Nos próximos passos, veremos como chegar ao fim da geração de itemsets frequentes — a primeira etapa da mineração de regras de associação.
O próximo passo é listar todos os itemsets frequentes. Você vai pegar o último itemset frequente não vazio, que neste exemplo é L2={I1, I2},{I2, I3}. Em seguida, gerar todos os subconjuntos não vazios dos itemsets presentes nessa lista de itemsets frequentes. Acompanhe como na ilustração abaixo:
Acima vemos quatro regras fortes. Por exemplo, ${I2}=>I3$ com confiança de 75% indica que 75% das pessoas que compraram I2 também compraram I3.
Pronto: você aprendeu o algoritmo APRIORI, um dos mais usados em mineração de dados. Bora para o código!
Implementando MBA/mineração de regras de associação em R
Neste tutorial, vamos usar um dataset do UCI Machine Learning Repository. O conjunto se chama Online-Retail e pode ser baixado aqui. Ele contém transações de 01/12/2010 a 09/12/2011 de um varejista online sem loja física registrado no Reino Unido. O motivo de usar este, e não um dataset nativo do R, é que você provavelmente receberá dados de varejo neste formato e terá que fazer pré-processamento.
Descrição do dataset
Informações dos atributos
Carregando bibliotecas
Primeiro, vamos carregar as bibliotecas necessárias. Uma breve descrição (retirada daqui) está na tabela a seguir para você saber o que cada uma faz:
arulesarulesViztidyversereadxlplyrggplot2knitrlubridatePré-processamento dos dados
Use
read_excel(path to file)para ler o arquivo baixado no R. Informe o caminho completo, incluindo o nome do arquivo, emread_excel(path-to-file-with-filename)Agora o dataframe retail terá 10 atributos, com dois adicionais:
DateeTime.Antes de aplicar MBA/mineração de regras de associação, precisamos converter o dataframe em dados de transação, de forma que todos os itens comprados juntos em uma mesma nota fiquem em uma única linha. No output do
glimpsedá para ver que cada transação está em formato atômico — todos os produtos de uma nota estão atomizados como em bancos relacionais. Esse formato também é chamado de singles.Você precisa agrupar os dados do
retailporCustomerID,CustomerIDeDate, ou agrupar porInvoiceNoeDate. Vamos aplicar uma função nesse agrupamento e salvar a saída em outro dataframe. Isso pode ser feito comddply.As linhas abaixo combinam todos os produtos de um mesmo
InvoiceNoeDateem uma linha, com cada item separado por,Em seguida, como InvoiceNo e Date não serão úteis na mineração de regras, podemos definir como
NULL.Esse formato de dados de transação é chamado de formato basket. Agora, salve esses dados em um arquivo .csv (Comma Separated Values) usando
write.csv()Confira se os dados ficaram no formato correto:
Agora vamos carregar esse CSV em um objeto da classe transaction. Use a função
read.transactionsdo pacotearules.O código abaixo lê o arquivo
D:/Documents/market_basket_transactions.csvno formato basket e converte em um objeto da classe transaction.Ao executar, você pode ver várias mensagens
EOF within quoted string— não se preocupe.Se você já tem os dados de transação em um dataframe, use a linha abaixo para converter em transaction:
Veja o objeto
tr:summary(tr)é um comando bem útil que traz informações sobre o objeto de transações. O que esse output diz:Existem 22191 transações (linhas) e 7876 itens (colunas). Note que 7876 são as descrições de produtos no dataset e 22191 transações são combinações desses itens.
Densidade indica a porcentagem de células não nulas na matriz esparsa. Dá para ver como o total de itens comprados dividido pelo total possível de células. Você pode estimar quantos itens foram comprados usando a densidade: 22191x7876x0.001930725=337445
O summary também mostra os itens mais frequentes.
Distribuição do tamanho dos itemsets/transações: quantas transações existem com 1 item, 2 itens e assim por diante. A primeira linha mostra o nº de itens e a segunda, o nº de transações.
Por exemplo, há 3598 transações com um único item, 1594 com 2 itens, e existe uma transação com 419 itens — a mais longa.
Você pode gerar um
itemFrequencyPlot(gráfico de barras) para ver a distribuição dos objetos com base em umitemMatrix(ex.:>transactionsou itens em>itemsetse>rules), que é o nosso caso.Em
o primeiro argumento é o objeto de transações a ser plotado,
tr.topNdefine quantos itens mais frequentes exibir.typepode sertype="absolute"outype="relative". Em absoluto, plota as frequências numéricas de cada item. Em relativo, mostra quantas vezes os itens aparecem em comparação aos demais.Esse gráfico mostra que 'WHITE HANGING HEART T-LIGHT HOLDER' e 'REGENCY CAKESTAND 3 TIER' são os mais vendidos. Para aumentar as vendas de 'SET OF 3 CAKE TINS PANTRY DESIGN', o varejista pode posicioná-lo perto de 'REGENCY CAKESTAND 3 TIER'.
Confira outras opções de
itemFrequencyPlotaqui.Gerando regras!
O próximo passo é minerar as regras usando o algoritmo APRIORI. A função
apriori()é do pacotearules.apriorirecebetrcomo o objeto de transações a ser minerado. Emparametervocê define min_sup e min_confidence. Os valores padrão são suporte mínimo 0.1, confiança mínima 0.8 e até 10 itens por regra (maxlen).summary(association.rules)mostra:Parâmetros: min_sup=0.001 e min_confidence=0.8, com no máximo 10 itens por regra.
Total de regras: 49122 regras
Distribuição do tamanho das regras: regras com 5 itens são a maioria: 16424; regras com 2 itens são as menos numerosas: 105
Resumo das medidas de qualidade: valores mínimos e máximos de suporte, confiança e lift.
Informações da mineração: dados, suporte e confiança usados.
Como são 49122 regras, vamos imprimir só as 10 primeiras:
A partir desse output, você pode concluir, por exemplo:
100% dos clientes que compraram 'WOBBLY CHICKEN' também compraram 'METAL'.
100% dos clientes que compraram 'BLACK TEA' também compraram 'SUGAR JARS'.
Limitando o número e o tamanho das regras
Como limitar a quantidade e o tamanho das regras geradas? Ajustando os
parametersnoapriori. Aumenteconfpara regras mais fortes emaxlenpara permitir regras mais longas.Removendo regras redundantes
Você pode remover regras que são subconjuntos de regras maiores. Use o código abaixo para filtrar essas regras:
which(): retorna as posições dos elementos TRUE em um vetor.colSums(): soma por coluna em dataframes e arrays numéricos.is.subset(): determina se elementos de um vetor contêm todos os elementos de outro.Encontrando regras relacionadas a itens específicos
Às vezes você quer focar em um produto específico. Para descobrir o que influencia a compra do item X, use a opção
appearanceemapriori. Comappearancevocê define o LHS (parte SE) e o RHS (parte ENTÃO) da regra.Por exemplo, para descobrir o que os clientes compram antes de comprar 'METAL', rode:
Da mesma forma, para responder à pergunta Clientes que compraram METAL também compraram..., deixe METAL no lhs:
Visualizando regras de associação
Como os dados podem gerar centenas ou milhares de regras, você precisa de boas formas de apresentar seus achados. Já falamos do
ItemFrequencyPlot, ótimo para ver os itens mais vendidos.Vamos ver as seguintes visualizações:
Scatter plot
Uma visualização direta das regras é o scatter plot usando
plot()doarulesViz. Os eixos usam suporte e confiança; o lift colore os pontos (tons de cinza por padrão).O gráfico acima mostra que regras com lift alto costumam ter suporte baixo. Você pode usar as opções abaixo:
rulesObject: o objeto de regras a ser plotadomeasure: medidas de interesse (Support, Confidence, lift) — ou combinações, conforme omethod.shading: medida usada para colorir os pontos (Support, Confidence, lift). Padrão: Lift.method: método de visualização (scatterplot, two-key plot, matrix3D).O two-key plot usa suporte (x) e confiança (y). A cor representa a ordem — o número de itens na regra.
Scatter plot interativo
Uma visualização interativa excelente combina
arulesVizeplotly. Você pode passar o mouse sobre cada regra e ver todas as métricas (suporte, confiança e lift).Visualizações baseadas em grafos
Técnicas baseadas em grafos representam regras com vértices e arestas: vértices rotulados com nomes de itens e um segundo conjunto de vértices para itemsets ou regras. Itens se conectam a itemsets/regras por setas direcionadas. Setas de itens para vértices de regra indicam LHS; de regra para item indicam RHS. Tamanho e cor dos vértices costumam representar medidas de interesse.
Gráficos em grafo são ótimos, mas ficam poluídos com muitas regras. Então é melhor visualizar menos regras nesses casos.
Vamos selecionar 10 regras de
subRulescom maior confiança.Agora, plote um grafo interativo:
Observação: Você pode tornar todos os gráficos interativos usando
engine=htmlwidgetemplotNo
arulesViz, grafos de conjuntos de regras de associação podem ser exportados em GraphML ou como Graphviz dot-file para ferramentas como o Gephi. Por exemplo, para exportar as 1000 regras com maior lift:Representação individual de regra
Também chamada de parallel coordinates plot. Útil para visualizar quais produtos, combinados com outros itens, influenciam certos resultados de venda.
Como citado, o RHS é o consequente — o item que sugerimos que o cliente comprará; as posições no LHS mostram que 2 é a adição mais recente ao carrinho e 1 é o item previamente adicionado.
Veja a seta superior: quando tenho 'CHILDS GARDEN SPADE PINK' e 'CHILDS GARDEN RAKE PINK' no carrinho, é provável que eu compre também 'CHILDS GARDEN RAKE BLUE'.
Conclusão
Parabéns! Você aprendeu o APRIORI, um dos algoritmos mais usados em mineração de dados. Viu os fundamentos da mineração de regras de associação, suas aplicações e como isso se traduz no varejo com a Market Basket Analysis. Você também já está pronto para implementar Market Basket Analysis em R e apresentar suas regras com visualizações de impacto. Bons estudos!
Referências:
https://datascienceplus.com/a-gentle-introduction-on-market-basket-analysis%E2%80%8A-%E2%80%8Aassociation-rules/
https://en.wikipedia.org/wiki/Sparse_matrix
https://cran.r-project.org/web/packages/arulesViz/vignettes/arulesViz.pdf
Se você quer aprender mais sobre R, faça o curso da DataCamp Importing and Managing Financial Data in R.