Teoría

El Market Basket Analysis es una técnica en el ámbito de análisis y minería de datos en el campo del comercio.

Su objetivo principal es descubrir patrones de asociación entre productos que suelen ser comprados juntos por los clientes.

Las 3 métricas principales para evaluar reglas de asociación son:

Confidence (Confianza): Probabilidad de comprar B sabiendo que se compró A. Ej. Pan –> Mantequilla 0.8. De cada 100 clientes que compraron pan, 80 compraron mantequilla también.

Lift (Elevación): Cuánto más probable es comprar B cuando se compra A en comparación con la probabilidad de comprar B sin saber si se compró A. Ej. Lift > 1: Compra A impulsa B. Lift = 1: No tienen relación de compra. Lift < 1: A reduce la compra de B.

Support (Soporte): Popularidad del producto dentro de las transacciones. Ej. Pan y Mantequilla 0.05. El 5% de todas las transacciones compraron estos dos productos juntos.

Contexto

Instacart es una plataforma de súper a domicilio en Estados Unidos. La base de datos contiene más de 3 millones de órdenes de alrededor de 200,000 clientes, con casi 50,000 productos distintos organizados en pasillos (aisles) y departamentos.

La base viene partida en varios archivos: el detalle de las órdenes está dividido en dos archivos (order_products__prior.csv y order_products__train.csv) que hay que concatenar para tener todas las transacciones, y los nombres de los productos, pasillos y departamentos vienen en catálogos aparte que hay que pegar.

El objetivo es limpiar la base de forma estratégica y posteriormente aplicar MBA para descubrir patrones de compra y diseñar promociones que aumenten las ventas.

Instalar paquetes y llamar librerías

# install.packages("tidyverse")
library(tidyverse)

# install.packages("janitor")
library(janitor)

# install.packages("Matrix")
library(Matrix)

# install.packages("arules")
library(arules)

# install.packages("arulesViz")
library(arulesViz)

# install.packages("plyr")
library(plyr)

Importar la base de datos

El detalle de órdenes viene partido en dos archivos, así que primero se concatenan con rbind() y después se agregan los catálogos.

# Detalle de órdenes
prior <- read.csv("/Users/kamilahchaidez/Downloads/archive/order_products__prior.csv")

train <- read.csv("/Users/kamilahchaidez/Downloads/archive/order_products__train.csv")

# Concatenar los dos archivos
order_products <- rbind(prior, train)

rm(prior, train)
gc()
##            used (Mb) gc trigger   (Mb) limit (Mb)  max used   (Mb)
## Ncells  2732315  146    8618279  460.3         NA   6090501  325.3
## Vcells 77724478  593  214001252 1632.7      24576 262489948 2002.7
# Revisar número de renglones
nrow(order_products)
## [1] 33819106
# Catálogos
products <- read.csv(
  "/Users/kamilahchaidez/Downloads/archive/products.csv"
)

aisles <- read.csv(
  "/Users/kamilahchaidez/Downloads/archive/aisles.csv"
)

departments <- read.csv(
  "/Users/kamilahchaidez/Downloads/archive/departments.csv"
)

orders <- read.csv(
  "/Users/kamilahchaidez/Downloads/archive/orders.csv"
)


# Pegar los catálogos
products <- products %>%
  left_join(aisles, by = "aisle_id") %>%
  left_join(departments, by = "department_id")


# Crear una sola tabla
df <- order_products %>%
  left_join(
    products[, c(
      "product_id",
      "product_name",
      "aisle",
      "department"
    )],
    by = "product_id"
  ) %>%
  left_join(
    orders[, c(
      "order_id",
      "user_id",
      "order_dow",
      "order_hour_of_day",
      "days_since_prior_order"
    )],
    by = "order_id"
  )


# Liberar memoria
rm(order_products)
gc()
##             used   (Mb) gc trigger   (Mb) limit (Mb)  max used   (Mb)
## Ncells   2795739  149.4    8618279  460.3         NA   6297955  336.4
## Vcells 276277236 2107.9  618873353 4721.7      24576 550249762 4198.1
# Revisar la base
summary(df)
##     order_id         product_id    add_to_cart_order   reordered     
##  Min.   :      1   Min.   :    1   Min.   :  1.000   Min.   :0.0000  
##  1st Qu.: 855413   1st Qu.:13519   1st Qu.:  3.000   1st Qu.:0.0000  
##  Median :1710660   Median :25256   Median :  6.000   Median :1.0000  
##  Mean   :1710566   Mean   :25576   Mean   :  8.368   Mean   :0.5901  
##  3rd Qu.:2565587   3rd Qu.:37935   3rd Qu.: 11.000   3rd Qu.:1.0000  
##  Max.   :3421083   Max.   :49688   Max.   :145.000   Max.   :1.0000  
##                                                                      
##     product_name            aisle              department      
##  Length   :33819106   Length   :33819106   Length   :33819106  
##  N.unique :   49685   N.unique :     134   N.unique :      21  
##  N.blank  :       0   N.blank  :       0   N.blank  :       0  
##  Min.nchar:       3   Min.nchar:       3   Min.nchar:       4  
##  Max.nchar:     159   Max.nchar:      29   Max.nchar:      15  
##                                                                
##                                                                
##     user_id         order_dow     order_hour_of_day days_since_prior_order
##  Min.   :     1   Min.   :0.000   Min.   : 0.00     Min.   : 0.00         
##  1st Qu.: 51435   1st Qu.:1.000   1st Qu.:10.00     1st Qu.: 5.00         
##  Median :102626   Median :3.000   Median :13.00     Median : 8.00         
##  Mean   :102944   Mean   :2.737   Mean   :13.43     Mean   :11.36         
##  3rd Qu.:154412   3rd Qu.:5.000   3rd Qu.:16.00     3rd Qu.:15.00         
##  Max.   :206209   Max.   :6.000   Max.   :23.00     Max.   :30.00         
##                                                     NAs    :2078068
str(df)
## 'data.frame':    33819106 obs. of  11 variables:
##  $ order_id              : int  2 2 2 2 2 2 2 2 2 3 ...
##  $ product_id            : int  33120 28985 9327 45918 30035 17794 40141 1819 43668 33754 ...
##  $ add_to_cart_order     : int  1 2 3 4 5 6 7 8 9 1 ...
##  $ reordered             : int  1 1 0 1 0 1 1 1 0 1 ...
##  $ product_name          : chr  "Organic Egg Whites" "Michigan Organic Kale" "Garlic Powder" "Coconut Butter" ...
##  $ aisle                 : chr  "eggs" "fresh vegetables" "spices seasonings" "oils vinegars" ...
##  $ department            : chr  "dairy eggs" "produce" "pantry" "pantry" ...
##  $ user_id               : int  202279 202279 202279 202279 202279 202279 202279 202279 202279 205970 ...
##  $ order_dow             : int  5 5 5 5 5 5 5 5 5 5 ...
##  $ order_hour_of_day     : int  9 9 9 9 9 9 9 9 9 17 ...
##  $ days_since_prior_order: num  8 8 8 8 8 8 8 8 8 12 ...
# Conteos
# dplyr::count(df, order_id, sort = TRUE)
# dplyr::count(df, product_id, sort = TRUE)
# dplyr::count(df, product_name, sort = TRUE)
# dplyr::count(df, aisle, sort = TRUE)
# dplyr::count(df, department, sort = TRUE)
# dplyr::count(df, user_id, sort = TRUE)
# dplyr::count(df, order_dow, sort = TRUE)
# dplyr::count(df, order_hour_of_day, sort = TRUE)
# dplyr::count(df, add_to_cart_order, sort = TRUE)
# dplyr::count(df, reordered, sort = TRUE)


# Primeros 10 renglones
head(df, 10)
##    order_id product_id add_to_cart_order reordered
## 1         2      33120                 1         1
## 2         2      28985                 2         1
## 3         2       9327                 3         0
## 4         2      45918                 4         1
## 5         2      30035                 5         0
## 6         2      17794                 6         1
## 7         2      40141                 7         1
## 8         2       1819                 8         1
## 9         2      43668                 9         0
## 10        3      33754                 1         1
##                                             product_name
## 1                                     Organic Egg Whites
## 2                                  Michigan Organic Kale
## 3                                          Garlic Powder
## 4                                         Coconut Butter
## 5                                      Natural Sweetener
## 6                                                Carrots
## 7                       Original Unflavored Gelatine Mix
## 8               All Natural No Stir Creamy Almond Butter
## 9                                Classic Blend Cole Slaw
## 10 Total 2% with Strawberry Lowfat Greek Strained Yogurt
##                         aisle department user_id order_dow order_hour_of_day
## 1                        eggs dairy eggs  202279         5                 9
## 2            fresh vegetables    produce  202279         5                 9
## 3           spices seasonings     pantry  202279         5                 9
## 4               oils vinegars     pantry  202279         5                 9
## 5          baking ingredients     pantry  202279         5                 9
## 6            fresh vegetables    produce  202279         5                 9
## 7  doughs gelatins bake mixes     pantry  202279         5                 9
## 8                     spreads     pantry  202279         5                 9
## 9  packaged vegetables fruits    produce  202279         5                 9
## 10                     yogurt dairy eggs  205970         5                17
##    days_since_prior_order
## 1                       8
## 2                       8
## 3                       8
## 4                       8
## 5                       8
## 6                       8
## 7                       8
## 8                       8
## 9                       8
## 10                     12
# Últimos 10 renglones
tail(df, 10)
##          order_id product_id add_to_cart_order reordered
## 33819097  3421058      30316                 6         1
## 33819098  3421058      35578                 7         0
## 33819099  3421058      32650                 8         1
## 33819100  3421063      49235                 1         1
## 33819101  3421063      13565                 2         1
## 33819102  3421063      14233                 3         1
## 33819103  3421063      35548                 4         1
## 33819104  3421070      35951                 1         1
## 33819105  3421070      16953                 2         1
## 33819106  3421070       4724                 3         1
##                                                                  product_name
## 33819097                                                            Baby Brie
## 33819098 Genoa Salame with White Cheddar Cheese & Toasted Rounds Small Plates
## 33819099                                        White Giant Paper Towel Rolls
## 33819100                                                  Organic Half & Half
## 33819101     No Salt Added Gluten-Free Blue Chips Made with Organic Blue Corn
## 33819102                                               Natural Artesian Water
## 33819103                                                 Twice Baked Potatoes
## 33819104                                      Organic Unsweetened Almond Milk
## 33819105                                                 Creamy Peanut Butter
## 33819106                                                   Broccoli Florettes
##                                  aisle   department user_id order_dow
## 33819097               packaged cheese   dairy eggs  136952         3
## 33819098                 packaged meat meat seafood  136952         3
## 33819099                   paper goods    household  136952         3
## 33819100                         cream   dairy eggs  169679         0
## 33819101                chips pretzels       snacks  169679         0
## 33819102 water seltzer sparkling water    beverages  169679         0
## 33819103                prepared meals         deli  169679         0
## 33819104               soy lactosefree   dairy eggs  139822         6
## 33819105                       spreads       pantry  139822         6
## 33819106              packaged produce      produce  139822         6
##          order_hour_of_day days_since_prior_order
## 33819097                18                     15
## 33819098                18                     15
## 33819099                18                     15
## 33819100                10                      4
## 33819101                10                      4
## 33819102                10                      4
## 33819103                10                      4
## 33819104                10                      8
## 33819105                10                      8
## 33819106                10                      8
# Tabla de Departamento y Día de la semana
tabyl(df, department, order_dow)
##       department       0       1       2       3       4       5       6
##          alcohol   18150   21215   21002   23293   27100   28465   20069
##           babies   85108   75243   58526   54229   53263   53529   58845
##           bakery  236619  211500  158372  144756  143201  160173  170560
##        beverages  455671  499815  385525  358740  354296  392118  358010
##        breakfast  133781  134010   99432   90534   88797   98176   94339
##             bulk    6444    6526    4728    4408    4150    4761    4915
##     canned goods  239817  187010  138017  124363  120165  134754  170731
##       dairy eggs 1070923  989872  733935  665526  660577  740339  769895
##             deli  220115  191595  140718  126970  124428  140059  151655
##  dry goods pasta  191654  153674  115554  102895  100015  108313  133235
##           frozen  462177  374893  293978  277634  271295  303762  353119
##        household  133690  126346  104634   99909   97848  104254  107971
##    international   58723   48153   35759   32882   30848   34235   40555
##     meat seafood  159221  123398   90113   81066   80098   91659  113683
##          missing   15262   12442    9459    9233    9044   10512   11444
##            other    6459    6234    5171    4840    4764    5293    5325
##           pantry  370336  316582  250162  236784  234551  259372  289032
##    personal care   85072   75268   62543   59855   57583   60673   67699
##             pets   18039   15163   12383   13113   12922   14372   16229
##          produce 2057869 1746944 1244389 1111911 1095847 1231232 1400186
##           snacks  508562  555951  413960  375557  371904  410392  370086
# Tabla de Departamento y Recompra
tabyl(df, department, reordered)
##       department       0       1
##          alcohol   68302   90992
##           babies  185290  253453
##           bakery  455301  769880
##        beverages  971223 1832952
##        breakfast  324192  414877
##             bulk   15196   20736
##     canned goods  603540  511317
##       dairy eggs 1857344 3773723
##             deli  429309  666231
##  dry goods pasta  486874  418466
##           frozen 1068800 1268058
##        household  462205  312447
##    international  177217  103938
##     meat seafood  318889  420349
##          missing   46877   30519
##            other   22583   15503
##           pantry 1277020  679799
##    personal care  317838  150855
##             pets   40627   61594
##          produce 3455782 6432596
##           snacks 1279337 1727075

Limpiar la base de datos

Técnica 1. Eliminar valores irrelevantes

# Eliminar columna que no necesitamos
df <- subset(
  df,
  select = -c(days_since_prior_order)
)


# Contar cuántos productos tiene cada orden
tam.orden <- dplyr::count(
  df,
  order_id
)


# Eliminar órdenes que solamente tienen un producto
df <- df[
  df$order_id %in%
    tam.orden$order_id[tam.orden$n > 1],
]

Técnica 2. Eliminar valores repetidos

# Eliminar renglones duplicados
df <- distinct(df)

Técnica 3. Corregir errores tipográficos y similares

# Quitar espacios de más
df$product_name <- str_squish(
  df$product_name
)


# Quitar comas y comillas
# La coma se utiliza después como separador del basket
df$product_name <- gsub(
  "[,\"']",
  " ",
  df$product_name
)


# Volver a quitar espacios de más
df$product_name <- str_squish(
  df$product_name
)

Técnica 4. Convertir tipos de datos

# Convertir el día de la semana a factor
df$order_dow <- factor(
  df$order_dow,
  levels = 0:6,
  labels = c(
    "Domingo",
    "Lunes",
    "Martes",
    "Miercoles",
    "Jueves",
    "Viernes",
    "Sabado"
  )
)


# Convertir hora a entero
df$order_hour_of_day <- as.integer(
  df$order_hour_of_day
)


# Convertir reordered a lógico
df$reordered <- as.logical(
  df$reordered
)

Técnica 5. Tratar valores faltantes

# Eliminar registros donde no exista nombre del producto
df <- df[
  !is.na(df$product_name),
]


# Otras opciones para NA
# Estas NO se ejecutan porque tienen #

# Reemplazar NA con cero
# df[is.na(df)] <- 0

# Reemplazar NA con promedio
# df$altura[is.na(df$altura)] <-
#   mean(df$altura, na.rm = TRUE)

Técnica 6. Herramientas Estadísticas

# Boxplot del orden en que se agregaron productos al carrito
boxplot(
  df$add_to_cart_order,
  horizontal = TRUE
)

# Boxplot del tamaño de las órdenes
boxplot(
  tam.orden$n,
  horizontal = TRUE
)

Generar Basket

# Ordenar de menor a mayor por order_id
df <- df[
  order(df$order_id),
]


# Generar Basket
basket <- ddply(
  df,
  c("order_id"),
  function(df)
    paste(
      df$product_name,
      collapse = ","
    )
)


# Eliminar número de orden
basket$order_id <- NULL


# Cambiar nombre de la columna
colnames(basket) <- c(
  "Producto"
)


# Exportar el basket
write.csv(
  basket,
  "/Users/kamilahchaidez/Downloads/archive/basket.csv",
  quote = FALSE,
  row.names = FALSE
)

Market Basket Analysis

# Leer las transacciones
tr <- read.transactions(
  "/Users/kamilahchaidez/Downloads/archive/basket.csv",
  sep = ","
)
## Warning in asMethod(object): removing duplicated items in transactions
# Crear reglas de asociación
reglas.asociacion <- apriori(
  tr,
  parameter = list(
    supp = 0.001,
    conf = 0.2,
    maxlen = 10
  )
)
## Apriori
## 
## Parameter specification:
##  confidence minval smax arem  aval originalSupport maxtime support minlen
##         0.2    0.1    1 none FALSE            TRUE       5   0.001      1
##  maxlen target  ext
##      10  rules TRUE
## 
## Algorithmic control:
##  filter tree heap memopt load sort verbose
##     0.1 TRUE TRUE  FALSE TRUE    2    TRUE
## 
## Absolute minimum support count: 3182 
## 
## set item appearances ...[0 item(s)] done [0.00s].
## set transactions ...[49585 item(s), 3182491 transaction(s)] done [8.70s].
## sorting and recoding items ... [1853 item(s)] done [0.32s].
## creating transaction tree ... done [2.22s].
## checking subsets of size 1 2 3 4 done [0.84s].
## writing ... [845 rule(s)] done [0.00s].
## creating S4 object  ... done [0.19s].
# Ordenar reglas por confidence
reglas.asociacion <- sort(
  reglas.asociacion,
  by = "confidence",
  decreasing = TRUE
)


# Obtener las 10 mejores reglas
top10reglas <- head(
  reglas.asociacion,
  n = 10,
  by = "confidence"
)


# Graficar las reglas
plot(
  top10reglas,
  method = "graph",
  engine = "htmlwidget"
)

Ver las reglas

Las reglas se pueden ordenar de tres formas y cada una responde una pregunta distinta:

Reglas por Confidence

# Las 10 reglas con mayor confidence
inspect(
  head(
    reglas.asociacion,
    n = 10,
    by = "confidence"
  )
)
##      lhs                                                        rhs                                                         support confidence    coverage      lift count
## [1]  {Total 2% Lowfat Greek Strained Yogurt With Blueberry,                                                                                                               
##       Total 2% Lowfat Greek Strained Yogurt with Peach}      => {Total 2% with Strawberry Lowfat Greek Strained Yogurt} 0.001201574  0.5918588 0.002030171 61.115686  3824
## [2]  {Lime Sparkling Water,                                                                                                                                               
##       Sparkling Lemon Water}                                 => {Sparkling Water Grapefruit}                            0.001439753  0.5163399 0.002788382 20.842015  4582
## [3]  {Zero Calorie Cola}                                     => {Soda}                                                  0.001290184  0.4966134 0.002597965 45.744366  4106
## [4]  {Honeycrisp Apple,                                                                                                                                                   
##       Strawberries}                                          => {Banana}                                                0.001219799  0.4903992 0.002487360  3.190521  3882
## [5]  {Organic Hass Avocado,                                                                                                                                               
##       Organic Raspberries,                                                                                                                                                
##       Organic Strawberries}                                  => {Bag of Organic Bananas}                                0.001274473  0.4902696 0.002599536  3.979784  4056
## [6]  {Organic Fuji Apple,                                                                                                                                                 
##       Strawberries}                                          => {Banana}                                                0.001198432  0.4902314 0.002444626  3.189429  3814
## [7]  {Sparkling Lemon Water,                                                                                                                                              
##       Sparkling Water Grapefruit}                            => {Lime Sparkling Water}                                  0.001439753  0.4796399 0.003001737 31.568219  4582
## [8]  {Organic Hass Avocado,                                                                                                                                               
##       Organic Navel Orange}                                  => {Bag of Organic Bananas}                                0.001249022  0.4663851 0.002678091  3.785901  3975
## [9]  {Total 2% Lowfat Greek Strained Yogurt with Peach,                                                                                                                   
##       Total 2% with Strawberry Lowfat Greek Strained Yogurt} => {Total 2% Lowfat Greek Strained Yogurt With Blueberry}  0.001201574  0.4640214 0.002589481 69.051893  3824
## [10] {Cucumber Kirby,                                                                                                                                                     
##       Organic Fuji Apple}                                    => {Banana}                                                0.001059233  0.4628587 0.002288459  3.011343  3371

Reglas por Lift

# Las 10 reglas con mayor lift
inspect(
  head(
    reglas.asociacion,
    n = 10,
    by = "lift"
  )
)
##      lhs                                                        rhs                                                        support confidence    coverage     lift count
## [1]  {Kiwi Sandia Sparkling Water}                           => {Blackberry Cucumber Sparkling Water}                  0.001034724  0.3432711 0.003014305 93.21308  3293
## [2]  {Blackberry Cucumber Sparkling Water}                   => {Kiwi Sandia Sparkling Water}                          0.001034724  0.2809727 0.003682650 93.21308  3293
## [3]  {Lemon Sparkling Water}                                 => {Grapefruit Sparkling Water}                           0.001093169  0.3513786 0.003111085 72.44489  3479
## [4]  {Grapefruit Sparkling Water}                            => {Lemon Sparkling Water}                                0.001093169  0.2253822 0.004850289 72.44489  3479
## [5]  {Non Fat Acai & Mixed Berries Yogurt}                   => {Icelandic Style Skyr Blueberry Non-fat Yogurt}        0.001286414  0.4513284 0.002850283 72.00464  4094
## [6]  {Icelandic Style Skyr Blueberry Non-fat Yogurt}         => {Non Fat Acai & Mixed Berries Yogurt}                  0.001286414  0.2052336 0.006268046 72.00464  4094
## [7]  {Icelandic Style Skyr Blueberry Non-fat Yogurt}         => {Non Fat Raspberry Yogurt}                             0.002339048  0.3731702 0.006268046 70.11518  7444
## [8]  {Non Fat Raspberry Yogurt}                              => {Icelandic Style Skyr Blueberry Non-fat Yogurt}        0.002339048  0.4394852 0.005322246 70.11518  7444
## [9]  {Total 2% Lowfat Greek Strained Yogurt with Peach,                                                                                                                 
##       Total 2% with Strawberry Lowfat Greek Strained Yogurt} => {Total 2% Lowfat Greek Strained Yogurt With Blueberry} 0.001201574  0.4640214 0.002589481 69.05189  3824
## [10] {Nonfat Icelandic Style Strawberry Yogurt}              => {Icelandic Style Skyr Blueberry Non-fat Yogurt}        0.001480601  0.4275862 0.003462696 68.21683  4712

Reglas por Support

# Las 10 reglas con mayor support
inspect(
  head(
    reglas.asociacion,
    n = 10,
    by = "support"
  )
)
##      lhs                       rhs                      support    confidence
## [1]  {Organic Hass Avocado} => {Bag of Organic Bananas} 0.02034915 0.2941569 
## [2]  {Organic Strawberries} => {Bag of Organic Bananas} 0.02033062 0.2357807 
## [3]  {Organic Strawberries} => {Banana}                 0.01832841 0.2125605 
## [4]  {Organic Avocado}      => {Banana}                 0.01747405 0.3027388 
## [5]  {Organic Baby Spinach} => {Banana}                 0.01677774 0.2131528 
## [6]  {Organic Baby Spinach} => {Bag of Organic Bananas} 0.01653045 0.2100111 
## [7]  {Strawberries}         => {Banana}                 0.01356799 0.2909939 
## [8]  {Large Lemon}          => {Banana}                 0.01352337 0.2683385 
## [9]  {Organic Raspberries}  => {Bag of Organic Bananas} 0.01328613 0.2972965 
## [10] {Organic Raspberries}  => {Organic Strawberries}   0.01116515 0.2498365 
##      coverage   lift     count
## [1]  0.06917789 2.387832 64761
## [2]  0.08622680 1.913960 64702
## [3]  0.08622680 1.382911 58330
## [4]  0.05771988 1.969608 55611
## [5]  0.07871224 1.386765 53395
## [6]  0.07871224 1.704775 52608
## [7]  0.04662637 1.893196 43180
## [8]  0.05039669 1.745801 43038
## [9]  0.04468984 2.413318 42283
## [10] 0.04468984 2.897435 35533

Productos más vendidos

# Los 15 productos que más se compran
itemFrequencyPlot(
  tr,
  topN = 15,
  type = "relative",
  col = "steelblue",
  main = "Los 15 productos que más se compran"
)

Recomendaciones

1. El plátano no necesita descuento

El plátano está en el 15% de las compras y el plátano orgánico en el 12%. Ya se vende solo.

Ponerlo en promoción es gastar un descuento en algo que la gente probablemente iba a comprar de todos modos.

Lo que sí conviene es utilizarlo como producto gancho y colocarlo junto a otros productos que se quieran impulsar.

Muchas de las reglas más comunes terminan en plátano, lo que indica que es un producto muy presente en las compras.

2. Los paquetes de sabores son una buena oportunidad

Una de las relaciones más fuertes de la base aparece entre productos de diferentes sabores.

Quien compra agua mineral de kiwi con sandía también suele comprar otros sabores como zarzamora con pepino.

También se observan relaciones similares entre distintos sabores de yogur.

Esto indica que algunos clientes no compran solamente un sabor, sino que suelen combinar varios.

Qué hacer: crear paquetes de sabores surtidos o promociones como “lleva 3 sabores”.

3. Armar una canasta de fruta y verdura orgánica

Entre los productos más vendidos aparecen varias frutas y verduras, muchas de ellas orgánicas.

Por ejemplo:

  • Plátano
  • Fresa
  • Espinaca baby
  • Aguacate hass
  • Limón
  • Frambuesa

Además, varios de estos productos aparecen juntos en las mismas compras.

Qué hacer: crear una canasta semanal de frutas y verduras orgánicas.

De esta forma se agrupan productos que los clientes ya suelen comprar juntos.

5. Promociones de pocos productos

La mayoría de las reglas encontradas incluyen dos o tres productos.

Existen muchas menos reglas que incluyen cuatro productos.

Por esta razón, las promociones de dos productos pueden ser más fáciles de justificar con los patrones encontrados en la base.

También se pueden considerar algunas promociones de tres productos cuando exista una relación suficientemente fuerte.

6. No bajar demasiado el Support

En este análisis se utilizó:

support = 0.001

Un support muy bajo permite encontrar combinaciones que aparecen pocas veces.

Sin embargo, si se baja demasiado pueden comenzar a aparecer muchas reglas basadas en combinaciones poco frecuentes.

Esto puede hacer más difícil distinguir cuáles relaciones realmente son útiles y cuáles solamente aparecieron pocas veces en la base.