Market Basket Analysis - Parte 2




Definição do problema

Esta é a parte 2 de um dos projetos de conclusão do módulo Business Analytics da Formação Cientista de Dados da Data Science Academy (DSA), e pode ser considerada uma extensão da análise exploratória que eu fiz na parte 1. A parte 1 você encontra nesse link:

https://midoritoyota.github.io/Market_Basket_Analysis_1.html

Nessa primeira fase farei a análise exploratória dos dados de um aplicativo de compras para entender o perfil de compra dos usuários.

“The Instacart Online Grocery Shopping Dataset 2017”, Accessed from:

https://www.instacart.com/datasets/grocery-shopping-2017 on 25/05/2020.

Post do VP da Instacart definindo o problema em detalhes:

https://tech.instacart.com/3-million-instacart-orders-open-sourced-d40d29ead6f2?gi=41f7b19cd164

Pacotes e dados

Utilizarei o pacole arules, que cria as regras segundo o algorítimo APRIORI e o pacote arulesViz, que permite a visualização de objetos da classe transactions.

In [ ]:
# Carregando pacotes
library("arules")
library("arulesViz")
library("tidyverse")
library("knitr")
library("lubridate")
library("plyr")
library("RColorBrewer")
library("repr")
library("sqldf")
library("treemap")
In [2]:
# Carregado datasets
orders = read.csv("data/orders.csv", sep = ",")
products = read.csv("data/products.csv", sep = ",")
aisles = read.csv("data/aisles.csv", sep = ",")
departments = read.csv("data/departments.csv", sep = ",")
train = read.csv("data/order_products__train.csv", sep = ",")

Pré Processamento

Para transformar um dataframe em um objeto do tipo transactions é necessário criar uma coluna onde todos os produtos de uma mesma compra estarão em uma mesma linha, apenas separados por vírgula. Sendo assim:

In [3]:
# Inserir o nome do produto nos dados de treino
data = merge(train, products, by = "product_id")

# Remover colunas desnecessárias
data = subset(data, select = -c(product_id, reordered, aisle_id, department_id))

# Trasnformar factors em characters
data$product_name = as.character(data$product_name)

# Remover vírgulas e ponto e vírgula do nome dos itens (se houver)
data$product_name = gsub(',', '-', data$product_name) 
data$product_name = gsub(';', '-', data$product_name)

# Colocando itens em ordem de compra (importante não deixar em ordem aleatória!)
data = data[order(data$order_id, data$add_to_cart_order),]

head(data)
A data.frame: 6 × 3
order_idadd_to_cart_orderproduct_name
<int><int><chr>
137514011Bulgarian Yogurt
27744812Organic 4% Milk Fat Whole Milk Cottage Cheese
25714613Organic Celery Hearts
138316814Cucumber Kirby
119490515Lightly Smoked Sardines in Olive Oil
33185616Bag of Organic Bananas
In [4]:
# Agrupar os dados por Order id e colapsar produtos
transacoes = ddply(data, "order_id", function(order) paste(order$product_name, collapse = ","))
                   
# Remover coluna order_id (só usada para agrupar)                   
transacoes$order_id = NULL
head(transacoes)
A data.frame: 6 × 1
V1
<chr>
1Bulgarian Yogurt,Organic 4% Milk Fat Whole Milk Cottage Cheese,Organic Celery Hearts,Cucumber Kirby,Lightly Smoked Sardines in Olive Oil,Bag of Organic Bananas,Organic Hass Avocado,Organic Whole String Cheese
2Grated Pecorino Romano Cheese,Spring Water,Organic Half & Half,Super Greens Salad,Cage Free Extra Large Grade AA Eggs,Prosciutto- Americano,Organic Garnet Sweet Potato (Yam),Asparagus
3Shelled Pistachios,Organic Biologique Limes,Organic Raw Unfiltered Apple Cider Vinegar,Organic Baby Arugula,Organic Hot House Tomato,Green Peas,Bunched Cilantro,Flat Parsley- Bunch,Fresh Dill
4Roasted Turkey,Organic Cucumber,Organic Grape Tomatoes,Organic Pomegranate Kernels,Organic Raspberries,Organic Whole Strawberries,Organic Blueberries
5Natural Spring Water,Organic Orange Juice With Calcium & Vitamin D,Whole Milk Greek Blended Vanilla Bean Yogurt,Bag of Organic Bananas,Organic Chocolate Almondmilk Pudding,Organic Sliced Provalone Cheese,Tomatoes- Crushed- Organic,Organic Unsweetened Almond Milk,Crackers- Oyster,Uncured Applewood Smoked Bacon,Organic Seasoned Yukon Select Potatoes Hashed Browns,Organic Extra Virgin Oil Olive,Organic Raspberries,Unsalted Cultured Butter,Guacamole,Black Beans,Raspberry Sorbet Pops,Geranium Liquid Dish Soap,Baby Swiss Slices Cheese,Organic Whole Grassmilk Milk,Organic Raw Kombucha Gingerade,Organic Hothouse Cucumbers,Black Beans No Salt Added,Organic Cinnamon Apple Sauce,Uncured Genoa Salami,Queso Fresco,Natural Chicken & Maple Breakfast Sausage Patty,Sliced Pepperoni,Organic Garlic,100% Organic Unbleached All-Purpose Flour,Lavender Scent Laundry Detergent,Organic Italian Parsley Bunch,Organic 2% Buttermilk,Organic Yellow Onion,Organic Free Range Chicken Broth,Organic Stringles Mozzarella String Cheese,Garbanzo Beans,Organic Ketchup,Organic Zucchini,Mild Diced Green Chiles,Pinto Beans No Salt Added,Organic Lemonade,Corn Maize Tortillas,Organic Corn Starch,Olive Oil & Aloe Vera Hand Soap,Plastic Spoons,Aluminum Foil,Plastic Wrap,Organic Coconut Milk
6Fresh Cauliflower,I Heart Baby Kale,Sea Salt Baked Potato Chips,Marinara Pasta Sauce,Organic Hass Avocado,Organic Lemon,Coconut Water Kefir,Premium Epsom Salt,Umcka Elderberry Intensive Cold + Flu Berry Flavor,Hickory Honey Barbeque Baked Potato Chips,Baked Sea Salt & Vinegar Potato Chips
In [ ]:
# Transformar itens para formato "transactions" (arquivo próprio do algorítimo)
write.csv(transacoes,"./data/transacoes.csv", quote = FALSE, row.names = FALSE)
data_trans = read.transactions('./data/transacoes.csv', format = 'basket', sep=',')

# Classe do objeto
class(data_trans)

Classe transactions

O pacote APRIORI lê um tipo diferente de arquivo. O arquivo é da classe transactions, e não dá para visualizar com head, pois não é um dataframe nem uma matriz.

Comando Inspect

O comando inspect pertence ao pacote arulesViz e é uma forma de visualizar o conteúdo de um objeto da classe transactions. Abaixo, vemos a aplicação do comando inspect, que mostra um índice identificador da ordem de compra e dentro de cada ordem de compra há uma lista de itens comprados, como se fossem os itens de um cupom fiscal. Lembre-se de utilizar o comando head antes de utilizar o inspect nos dados ou seu código irá tentar mostrar todos os itens e irá travar!

In [6]:
inspect(head(data_trans,3))
    items                                          
[1] {V1}                                           
[2] {Bag of Organic Bananas,                       
     Bulgarian Yogurt,                             
     Cucumber Kirby,                               
     Lightly Smoked Sardines in Olive Oil,         
     Organic 4% Milk Fat Whole Milk Cottage Cheese,
     Organic Celery Hearts,                        
     Organic Hass Avocado,                         
     Organic Whole String Cheese}                  
[3] {Asparagus,                                    
     Cage Free Extra Large Grade AA Eggs,          
     Grated Pecorino Romano Cheese,                
     Organic Garnet Sweet Potato (Yam),            
     Organic Half & Half,                          
     Prosciutto- Americano,                        
     Spring Water,                                 
     Super Greens Salad}                           

Estrutura da classe transaction

O objeto da classe transaction é dividido em 3 componentes @data, @itemInfo e @itemsetInfo:

  • O @data é uma matriz que contém 2 listas: data_trans@data@i (lista completa dos itens comprados do primeiro ao último cliente, por código do produto) e data_trans@data@p (lista com os índices que dividem uma compra de outra). Dim e Dinames são apenas informações sobre a natureza do objeto.
  • O @itemInfo é um dataframe com os labels (que tem o nome de cada produto).
  • O @itemsetInfo é uma dataframe vazio que só será preenchido quando rodarmos a função apriori
In [7]:
# Estrutura da Classe transaction
str(data_trans)
Formal class 'transactions' [package "arules"] with 3 slots
  ..@ data       :Formal class 'ngCMatrix' [package "Matrix"] with 5 slots
  .. .. ..@ i       : int [1:1297002] 46503 3212 5441 11429 22400 27774 28410 31007 33280 2854 ...
  .. .. ..@ p       : int [1:131211] 0 1 9 17 26 33 82 93 110 115 ...
  .. .. ..@ Dim     : int [1:2] 48927 131210
  .. .. ..@ Dimnames:List of 2
  .. .. .. ..$ : NULL
  .. .. .. ..$ : NULL
  .. .. ..@ factors : list()
  ..@ itemInfo   :'data.frame':	48927 obs. of  1 variable:
  .. ..$ labels: chr [1:48927] "#2 Coffee Filters" "#2 Cone White Coffee Filters" "#2 Mechanical Pencils" "#4 Natural Brown Coffee Filters" ...
  ..@ itemsetInfo:'data.frame':	0 obs. of  0 variables

Podemos visualizar o conteúdo do objeto se quisermos:

In [10]:
# Visualizar nome dos produtos
data_trans@itemInfo$labels[1:10]
  1. '#2 Coffee Filters'
  2. '#2 Cone White Coffee Filters'
  3. '#2 Mechanical Pencils'
  4. '#4 Natural Brown Coffee Filters'
  5. '& Go! Hazelnut Spread + Pretzel Sticks'
  6. '\\Constant Comment\\ Black Tea'
  7. '\\Constant Comment\\ Decaffeinated Black Tea Blend'
  8. '\\Darn Good\\ Chili Mix'
  9. '\\Im Pei-nut Butter\\ Double Chocolate Cookie & Peanut Butter Ice Cream'
  10. '\\Mies Vanilla Rohe\\ Ice Cream Bars'

Resumo dos dataset

In [144]:
# Resumo do arquivo
summary(data_trans)
transactions as itemMatrix in sparse format with
 131210 rows (elements/itemsets/transactions) and
 48927 columns (items) and a density of 2e-04 

most frequent items:
                Banana Bag of Organic Bananas   Organic Strawberries 
                 18154                  15054                  10337 
  Organic Baby Spinach            Large Lemon                (Other) 
                  9395                   7794                1236268 

element (itemset/transaction) length distribution:
sizes
   1    2    3    4    5    6    7    8    9   10   11   12   13   14   15   16 
7799 8237 8773 8771 9342 9083 8690 8119 7239 6525 5949 5249 4654 4215 3617 3320 
  17   18   19   20   21   22   23   24   25   26   27   28   29   30   31   32 
2894 2518 2283 1919 1675 1475 1289 1115  942  821  711  546  534  436  373  325 
  33   34   35   36   37   38   39   40   41   42   43   44   45   46   47   48 
 263  233  220  143  140  127  105   69   64   62   47   55   36   31   31   19 
  49   50   51   52   53   54   55   56   57   58   59   60   61   62   63   64 
  14   17   16   18    9    7    5    6    3    4    1    4    1    2    2    4 
  65   66   68   70   72   74   76   80 
   3    2    1    3    1    1    2    1 

   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
      1       4       8      10      13      80 

includes extended item information - examples:
                        labels
1            #2 Coffee Filters
2 #2 Cone White Coffee Filters
3        #2 Mechanical Pencils

O resumo acima nos dá algumas informações:

  • Temos um total de 131210 transações e 50052 tipos de produtos
  • A matriz gerada é esparça, ou seja, em sua maior parte está vazia.
  • O item mais comum vendido é a banana seguida de bag of organic bananas.
  • Em média, as pessoas fazem compras de 8 itens e a maior compra foi de 84 itens de uma só vez.

Produtos mais comprados

In [145]:
# Plot dos itens mais frequentemente comprados
options(repr.plot.width=12, repr.plot.height=7)
itemFrequencyPlot(data_trans, topN=15, type="absolute", col=brewer.pal(8,'Set3'), main="Absolute Item Frequency Plot")

Na análise exploratória da parte 1, vimos que existe uma variedade enorme de alimentos não saudáveis como chocolates e sorvetes. Olhando a frequência de compra dos itens acima, percebemos que os itens mais comprados são os saudáveis. Talvez isso ocorra porque como temos uma variedade enorme de tipos de sorvete, o volume de compras se dilui para cada item. No caso, se for para comprar bananas só tem Bananas (ou Bag of organic bananas). Podemos confirmar essa hitpótese mais tarde através de um gráfico.

Regras de associação

Para criar regras é necessários definir 2 parâmetros:

  • support (supp) : é o quanto um determinado set de compras apareceu na nossa amostra (em porcentagem)
  • confidence (conf) : é o quanto a regra aconteceu em todas as vezes que ela podia ter acontecido.

O maxlen é opcional. Colocamos para evitar regras muito longas.

In [25]:
# Criando regras 
rules = apriori(data_trans, parameter = list(supp=0.0001, conf=0.70, maxlen=10), control = list(verbose=FALSE))

# Resumo das regras
summary(rules)
set of 297 rules

rule length distribution (lhs + rhs):sizes
  2   3   4   5 
  1  52 188  56 

   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  2.000   4.000   4.000   4.007   4.000   5.000 

summary of quality measures:
    support            confidence        coverage              lift         
 Min.   :0.0001067   Min.   :0.7000   Min.   :0.0001067   Min.   :   5.059  
 1st Qu.:0.0001067   1st Qu.:0.7143   1st Qu.:0.0001448   1st Qu.:   6.339  
 Median :0.0001219   Median :0.7368   Median :0.0001600   Median :   7.691  
 Mean   :0.0001354   Mean   :0.7572   Mean   :0.0001804   Mean   :  74.803  
 3rd Qu.:0.0001448   3rd Qu.:0.7778   3rd Qu.:0.0001905   3rd Qu.:  35.721  
 Max.   :0.0004268   Max.   :1.0000   Max.   :0.0006021   Max.   :2112.282  
     count      
 Min.   :14.00  
 1st Qu.:14.00  
 Median :16.00  
 Mean   :17.77  
 3rd Qu.:19.00  
 Max.   :56.00  

mining info:
       data ntransactions support confidence
 data_trans        131210   1e-04        0.7

o resumo das regras acima nos mostra que foram criadas 297 regras, em sua maioria de 4 itens.

In [30]:
# Visualizar as 10 primeiras regras
options(digits=2)
rules = sort(rules, by="confidence", decreasing=TRUE)
inspect(rules[1:10])
     lhs                                               rhs                                           support confidence coverage  lift count
[1]  {Lime Sparkling Water,                                                                                                                 
      Peach Pear Flavored Sparkling Water,                                                                                                  
      Pure Sparkling Water,                                                                                                                 
      Sparkling Water Grapefruit}                   => {Sparkling Lemon Water}                       0.00011       1.00  0.00011  97.1    14
[2]  {Low-Fat Mango on the Bottom Greek Yogurt,                                                                                             
      Peach on the Bottom Nonfat Greek Yogurt,                                                                                              
      Strawberry on the Bottom Nonfat Greek Yogurt} => {Blueberry on the Bottom Nonfat Greek Yogurt} 0.00012       0.94  0.00013 614.4    16
[3]  {Cran Raspberry Sparkling Water,                                                                                                       
      Peach Pear Flavored Sparkling Water,                                                                                                  
      Sparkling Water Berry}                        => {Sparkling Water Grapefruit}                  0.00011       0.94  0.00012  38.0    15
[4]  {Lime Sparkling Water,                                                                                                                 
      Orange Sparkling Water,                                                                                                               
      Peach Pear Flavored Sparkling Water}          => {Sparkling Lemon Water}                       0.00011       0.94  0.00012  91.1    15
[5]  {Lime Sparkling Water,                                                                                                                 
      Orange Sparkling Water,                                                                                                               
      Peach Pear Flavored Sparkling Water}          => {Sparkling Water Grapefruit}                  0.00011       0.94  0.00012  38.0    15
[6]  {Curate Cherry Lime Sparkling Water,                                                                                                   
      Passionfruit Sparkling Water,                                                                                                         
      Pineapple Strawberry Sparkling Water}         => {Blackberry Cucumber Sparkling Water}         0.00011       0.93  0.00011 248.4    14
[7]  {Blackberry Cucumber Sparkling Water,                                                                                                  
      Passionfruit Sparkling Water,                                                                                                         
      Pineapple Strawberry Sparkling Water}         => {Curate Cherry Lime Sparkling Water}          0.00011       0.93  0.00011 311.6    14
[8]  {Blueberries,                                                                                                                          
      Honeycrisp Apple,                                                                                                                     
      Organic Avocado}                              => {Banana}                                      0.00011       0.93  0.00011   6.7    14
[9]  {Lime Sparkling Water,                                                                                                                 
      Orange Sparkling Water,                                                                                                               
      Peach Pear Flavored Sparkling Water,                                                                                                  
      Sparkling Lemon Water}                        => {Sparkling Water Grapefruit}                  0.00011       0.93  0.00011  37.8    14
[10] {Lime Sparkling Water,                                                                                                                 
      Orange Sparkling Water,                                                                                                               
      Peach Pear Flavored Sparkling Water,                                                                                                  
      Sparkling Water Grapefruit}                   => {Sparkling Lemon Water}                       0.00011       0.93  0.00011  90.6    14

Foram criadas as regras acima que mostram o que as pessoas costumam comprar costumam comprar em um mesmo pedido.

Com as regras criadas podemos responder a duas perguntas principais:

People who bought Blueberry, also bought...

In [174]:
# Criação de regra para o item Blueberry (lhs = Blueberry)

blueberry_rules = apriori(data_trans, parameter = list(supp=0.0001, conf=0.50), appearance = list(lhs="Blueberry", default="rhs"), control = list(verbose=F))
inspect(blueberry_rules)
    lhs            rhs      support confidence coverage lift count
[1] {Blueberry} => {Banana} 0.00021 0.6        0.00036  4.3  28   

Pessoas que compram Blueberry compra também... Bananas Claro! Banana é vida rsrs

Também podemos fazer da maneira inversa:

Before buying Organic Strawberries, people bought...

In [32]:
# Criação da regra para o item METAL (rhs = Organic Strawberries)
strawberry_rules = apriori(data_trans, parameter = list(supp=0.0001, conf=0.80), appearance = list(rhs="Organic Strawberries", default="lhs"), control = list(verbose=F))
inspect(strawberry_rules)
    lhs                                 rhs                    support confidence coverage lift count
[1] {Backyard Barbeque Potato Chips,                                                                 
     Organic Raspberries}            => {Organic Strawberries} 0.00011       0.88  0.00012   11    14
[2] {Bag of Organic Bananas,                                                                         
     Organic Garlic,                                                                                 
     Organic Kiwi,                                                                                   
     Organic Raspberries}            => {Organic Strawberries} 0.00012       0.80  0.00015   10    16

Backyard Barbeque Potato Chips, um pouco de comida industrializada, finalmente!

Before buying chocolate, people bought...

Você lembra que haviam 1246 tipos diferentes de chocolate no dataset? Chegamos nesse número na parte 1 do projeto. Pois bem, vamos ver está sendo comprado de chocolate em maior quantidade:

In [52]:
# Filtrando os 5 item de chocolate mais comprados 
sqldf(" SELECT product_name, COUNT(*) AS qtd 
        FROM data 
        WHERE product_name LIKE '%chocolate%' 
        GROUP BY product_name
        ORDER BY qtd DESC LIMIT 5 ")
A data.frame: 5 × 2
product_nameqtd
<chr><int>
Chocolate Ice Cream 635
Chocolate Chip Cookies 614
Almonds & Sea Salt in Dark Chocolate 461
Kids Organic Chocolate Chip ZBars 451
Chocolate Chip Cookie Dough Ice Cream418

Vou verificar então o que as pessoas compram antes de comprar Chocolate Ice Cream.

In [92]:
# Criação da regra para o item METAL (rhs = Organic Strawberries)
chocolate_rules = apriori(data_trans, parameter = list(supp=0.00002, conf=0.7), appearance = list(rhs="Chocolate Ice Cream", default="lhs"), control = list(verbose=F))
inspect(chocolate_rules)
     lhs                                        rhs                   support confidence coverage lift count
[1]  {Natural Strawberry Ice Cream,                                                                         
      Whipped Light Cream- Original}         => {Chocolate Ice Cream} 2.3e-05       1.00  2.3e-05  222     3
[2]  {Cookie Dough Ice Cream Chocolate Chip,                                                                
      Organic Tomato Cluster}                => {Chocolate Ice Cream} 2.3e-05       0.75  3.0e-05  167     3
[3]  {Seven Grain Crispy Tenders,                                                                           
      Vanilla Bean Light Ice Cream}          => {Chocolate Ice Cream} 2.3e-05       1.00  2.3e-05  222     3
[4]  {Large Grapefruit,                                                                                     
      Vanilla Bean Light Ice Cream}          => {Chocolate Ice Cream} 2.3e-05       0.75  3.0e-05  167     3
[5]  {Shredded Parmesan,                                                                                    
      Vanilla Bean Light Ice Cream}          => {Chocolate Ice Cream} 3.0e-05       0.80  3.8e-05  178     4
[6]  {Organic Black Beans,                                                                                  
      Strawberry Ice Cream}                  => {Chocolate Ice Cream} 2.3e-05       0.75  3.0e-05  167     3
[7]  {Mint Chip,                                                                                            
      Organic Brown Rice}                    => {Chocolate Ice Cream} 2.3e-05       0.75  3.0e-05  167     3
[8]  {Birthday Cake Light Ice Cream,                                                                        
      Red Velvet Ice Cream,                                                                                 
      Vanilla Bean Light Ice Cream}          => {Chocolate Ice Cream} 2.3e-05       0.75  3.0e-05  167     3
[9]  {Ice Cream Chocolate Mocha Chip,                                                                       
      Mint Chip,                                                                                            
      Peanut Butter Ice Cream Cup}           => {Chocolate Ice Cream} 2.3e-05       0.75  3.0e-05  167     3
[10] {Asparagus,                                                                                            
      Large Lemon,                                                                                          
      Vanilla Bean Light Ice Cream}          => {Chocolate Ice Cream} 2.3e-05       0.75  3.0e-05  167     3
[11] {Birthday Cake Light Ice Cream,                                                                        
      Large Lemon,                                                                                          
      Organic Blueberries}                   => {Chocolate Ice Cream} 2.3e-05       1.00  2.3e-05  222     3
[12] {Broccoli Crown,                                                                                       
      Mint Chip,                                                                                            
      Organic Avocado}                       => {Chocolate Ice Cream} 2.3e-05       0.75  3.0e-05  167     3

Com esse tanto de informação, fica um pouco difícil de visualizar as regras. Podemos melhorar isso usando um plot.

Plotagens

Associações

O pacote ArulesViz permite fazer alguns plots especificamente para visualizarmos as regras criadas. Vejamos algumas:

In [95]:
# Plot default
options(repr.plot.width=12, repr.plot.height=12)
plot(chocolate_rules, method="graph", engine = "default", main = "Cholocate Ice Cream Rules")

Dá para perceber que a compra de outros tipos de sorvete, levam as pessoas a comprarem sorvete de chocolate!

Podemos fazer o plot utilizando diferentes tipos de engine, vamos ver como fica o plot do strawberry_rules com o graphviz engine.

In [209]:
# Plot com Engine Graphviz
options(repr.plot.width=12, repr.plot.height=8)
plot(strawberry_rules, method="graph", engine = "graphviz", main = "Strawberry Rules")

O plot mais legal, na minha opinião, é com o engine = "interactive" pois cria um gráfico interativo onde você pode selecionar os itens com o mouse, porém, ele é aberto em uma janela fora do jupyter-notebook, então não inseri aqui mas fica a dica.

Categorias mais compradas

Podemos fazer o mesmo plot treemap que fizemos na parte 1, mas agora, utilizando a quantidade comprada como peso para os produtos:

In [210]:
# Inserir o nome do produto nos dados de treino
data2 = merge(train, products, by = "product_id")
data2 = merge(data2, aisles, by = "aisle_id")
data2 = merge(data2, departments, by = "department_id")

head(data2)
A data.frame: 6 × 9
department_idaisle_idproduct_idorder_idadd_to_cart_orderreorderedproduct_nameaisledepartment
<int><int><int><int><int><int><fct><fct><fct>
113725745 49489490Oreo Ice Cream Sandwiches ice cream ice frozen
2137 2361193481430Mint Chip ice cream ice frozen
313717334244885261Coffee Ice Cream ice cream ice frozen
413734329 12221441Belgian Milk Chocolate Gelato ice cream ice frozen
513728281 97006010Variety Pack Ice Cream Bars ice cream ice frozen
6152 162268425361Organic Mini Homestyle Wafflesfrozen breakfastfrozen
In [226]:
# Preparo dos dados para visualização do treemap
options(repr.plot.width=7, repr.plot.height=7)


tmp = sqldf( " SELECT department, aisle, COUNT(product_id) AS n_products
               FROM data2 
               GROUP BY department, aisle " )

# Plot treemap
treemap(tmp,index=c("department","aisle"),vSize="n_products",palette="Set2",border.col="#FFFFFF", title = "")

Pelo treemap acima, percebemos que a teorida de que mais alimentos industrializados estão sendo comprados porém como eles estão vidividos em produtos diferentes (diferentes tipos de sorvete etc), eles não aparecem nos produtos mais vendidos não está correta, pode ser em parte verdade, mas, alimentos como verduras e frutas frescas ainda são as mais compradas.

Conclusão

O APRIORI é um ótimo algorítimo para ser usado na análise exploratória. Ele dá um panorama bom do padrão de consumo dos clientes e é possível obter insights para melhorar as recomendações ao usuário ou melhorar a proximidade das categorias. A dificuldade está em calibrar os parâmetros para cada produto, o que não é nada difícil, mas um pouco trablhoso.

Nos vemos na parte 3!