| title: “Market Basket Analysis” |
| author: “Federico Colyer” |
| date: “2026-08-18” |
| output: |
| html_document: |
| toc: TRUE |
| toc_float: TRUE |
| code_download: TRUE |
| theme: cosmo |
EL Market Basket Analysis es una tecnica en el ambito de analisis y mineria de datos en el campo del comercio. Su objetico prinicipal es descubrir patrones de asociacion entre productos que suelen ser comparados juntos por los clientes.
Las tres metricas principales para evaluar reglas de asociacion son:
Una cadena de tiendas de convenencia tiene 5 tiendas ubicadas en distintas cuidades de México. La base de datos “abarrotes” contienen un mes de transacciones, pero presenta errores de calidad que impiden realizar analisis confiables. El objetivo es limpiar la bas de datos de forma estrategica y posteriormente aplicar MBA para descubrir patrones de compra y diseñar promociones que aumenten
#install.packages("tidyverse") #Paquete global para manipulacion de datos
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.2.1 ✔ readr 2.2.0
## ✔ forcats 1.0.1 ✔ stringr 1.6.0
## ✔ ggplot2 4.0.3 ✔ tibble 3.3.1
## ✔ lubridate 1.9.5 ✔ tidyr 1.3.2
## ✔ purrr 1.2.2
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
#install.packages("janitor") #Examinar y limpiar bases de dato sucias
library(janitor)
##
## Attaching package: 'janitor'
##
## The following objects are masked from 'package:stats':
##
## chisq.test, fisher.test
#install.packages("Matrix") #Trabajar matrices
library(Matrix)
##
## Attaching package: 'Matrix'
##
## The following objects are masked from 'package:tidyr':
##
## expand, pack, unpack
#install.packages("arules") #Genera reglas de asociacion
library(arules)
##
## Attaching package: 'arules'
##
## The following object is masked from 'package:dplyr':
##
## recode
##
## The following objects are masked from 'package:base':
##
## abbreviate, write
#install.packages("arulesViz") #Visualizar reglas de asociacion
library(arulesViz)
#install.packages("plyr")
library(plyr)
## ------------------------------------------------------------------------------
## You have loaded plyr after dplyr - this is likely to cause problems.
## If you need functions from both plyr and dplyr, please load plyr first, then dplyr:
## library(plyr); library(dplyr)
## ------------------------------------------------------------------------------
##
## Attaching package: 'plyr'
##
## The following objects are masked from 'package:dplyr':
##
## arrange, count, desc, mutate, rename, summarise, summarize
##
## The following object is masked from 'package:purrr':
##
## compact
# file.choose()
df_T <- read.csv("/Users/fedecolyerjr/Desktop/abarrotes.csv")
summary(df_T)
## ClaveTienda DescGiro Codigo.Barras PLU
## Length :200625 Length :200625 Min. :8.347e+05 Min. : 1.000
## N.unique : 5 N.unique : 3 1st Qu.:7.501e+12 1st Qu.: 1.000
## N.blank : 0 N.blank : 0 Median :7.501e+12 Median : 1.000
## Min.nchar: 5 Min.nchar: 8 Mean :5.950e+12 Mean : 2.112
## Max.nchar: 5 Max.nchar: 10 3rd Qu.:7.501e+12 3rd Qu.: 1.000
## Max. :1.750e+13 Max. :30.000
## NAs :199188
## Fecha Hora Marca Fabricante
## Length :200625 Length :200625 Length :200625 Length :200625
## N.unique : 195 N.unique : 52145 N.unique : 540 N.unique : 241
## N.blank : 0 N.blank : 0 N.blank : 0 N.blank : 0
## Min.nchar: 10 Min.nchar: 8 Min.nchar: 3 Min.nchar: 3
## Max.nchar: 10 Max.nchar: 8 Max.nchar: 30 Max.nchar: 40
##
##
## Producto Precio Ult.Costo Unidades
## Length :200625 Min. :-147.00 Min. : 0.38 Min. : 0.200
## N.unique : 3406 1st Qu.: 11.00 1st Qu.: 8.46 1st Qu.: 1.000
## N.blank : 0 Median : 16.00 Median : 12.31 Median : 1.000
## Min.nchar: 4 Mean : 19.42 Mean : 15.31 Mean : 1.262
## Max.nchar: 40 3rd Qu.: 25.00 3rd Qu.: 19.23 3rd Qu.: 1.000
## Max. :1000.00 Max. :769.23 Max. :96.000
##
## F.Ticket NombreDepartamento NombreFamilia NombreCategoria
## Min. : 1 Length :200625 Length :200625 Length :200625
## 1st Qu.: 33964 N.unique : 9 N.unique : 51 N.unique : 174
## Median :105993 N.blank : 0 N.blank : 0 N.blank : 0
## Mean :193990 Min.nchar: 6 Min.nchar: 3 Min.nchar: 2
## 3rd Qu.:383005 Max.nchar: 20 Max.nchar: 25 Max.nchar: 37
## Max. :450040
##
## Estado Mts.2 Tipo.ubicación Giro
## Length :200625 Min. :47.0 Length :200625 Length :200625
## N.unique : 5 1st Qu.:53.0 N.unique : 3 N.unique : 2
## N.blank : 0 Median :60.0 N.blank : 0 N.blank : 0
## Min.nchar: 7 Mean :56.6 Min.nchar: 7 Min.nchar: 9
## Max.nchar: 12 3rd Qu.:60.0 Max.nchar: 12 Max.nchar: 10
## Max. :62.0
##
## Hora.inicio Hora.cierre
## Length :200625 Length :200625
## N.unique : 3 N.unique : 3
## N.blank : 0 N.blank : 0
## Min.nchar: 5 Min.nchar: 5
## Max.nchar: 5 Max.nchar: 5
##
##
str(df_T)
## 'data.frame': 200625 obs. of 22 variables:
## $ ClaveTienda : chr "MX001" "MX001" "MX001" "MX001" ...
## $ DescGiro : chr "Abarrotes" "Abarrotes" "Abarrotes" "Abarrotes" ...
## $ Codigo.Barras : num 7.5e+12 7.5e+12 7.5e+12 7.5e+12 7.5e+12 ...
## $ PLU : int NA NA NA NA NA NA NA NA NA NA ...
## $ Fecha : chr "19/06/2020" "19/06/2020" "19/06/2020" "19/06/2020" ...
## $ Hora : chr "08:16:21" "08:23:33" "08:24:33" "08:24:33" ...
## $ Marca : chr "NUTRI LECHE" "DAN UP" "BIMBO" "PEPSI" ...
## $ Fabricante : chr "MEXILAC" "DANONE DE MEXICO" "GRUPO BIMBO" "PEPSI-COLA MEXICANA" ...
## $ Producto : chr "Nutri Leche 1 Litro" "DANUP STRAWBERRY P/BEBER 350GR NAL" "Rebanadas Bimbo 2Pz" "Pepsi N.R. 400Ml" ...
## $ Precio : num 16 14 5 8 19.5 16 14 5 8 19.5 ...
## $ Ult.Costo : num 12.3 14 5 8 15 ...
## $ Unidades : num 1 1 1 1 1 1 1 1 1 1 ...
## $ F.Ticket : int 1 2 3 3 4 1 2 3 3 4 ...
## $ NombreDepartamento: chr "Abarrotes" "Abarrotes" "Abarrotes" "Abarrotes" ...
## $ NombreFamilia : chr "Lacteos y Refrigerados" "Lacteos y Refrigerados" "Pan y Tortilla" "Bebidas" ...
## $ NombreCategoria : chr "Leche" "Yogurt" "Pan Dulce Empaquetado" "Refrescos Plástico (N.R.)" ...
## $ Estado : chr "Nuevo León" "Nuevo León" "Nuevo León" "Nuevo León" ...
## $ Mts.2 : int 60 60 60 60 60 60 60 60 60 60 ...
## $ Tipo.ubicación : chr "Esquina" "Esquina" "Esquina" "Esquina" ...
## $ Giro : chr "Abarrotes" "Abarrotes" "Abarrotes" "Abarrotes" ...
## $ Hora.inicio : chr "08:00" "08:00" "08:00" "08:00" ...
## $ Hora.cierre : chr "22:00" "22:00" "22:00" "22:00" ...
#count(df_T, ClaveTienda, sort=TRUE)
#count(df_T, DescGiro, sort=TRUE)
#count(df_T, Fecha, sort=TRUE)
#count(df_T, Hora, sort=TRUE)
#count(df_T, Marca, sort=TRUE)
#count(df_T, Fabricante, sort=TRUE)
#count(df_T, Producto, sort=TRUE)
#count(df_T, NombreDepartamento, sort=TRUE)
#count(df_T, NombreFamilia, sort=TRUE)
#count(df_T, NombreCategoria, sort=TRUE)
#count(df_T, Estado, sort=TRUE)
#count(df_T, Tipo.ubicación, sort=TRUE)
#count(df_T, Giro, sort=TRUE)
#count(df_T, Hora.inicio, sort=TRUE)
#count(df_T, Hora.cierre, sort=TRUE)
head(df_T, 10)
## ClaveTienda DescGiro Codigo.Barras PLU Fecha Hora
## 1 MX001 Abarrotes 7.501021e+12 NA 19/06/2020 08:16:21
## 2 MX001 Abarrotes 7.501032e+12 NA 19/06/2020 08:23:33
## 3 MX001 Abarrotes 7.501000e+12 NA 19/06/2020 08:24:33
## 4 MX001 Abarrotes 7.501031e+12 NA 19/06/2020 08:24:33
## 5 MX001 Abarrotes 7.501026e+12 NA 19/06/2020 08:26:28
## 6 MX001 Abarrotes 7.501021e+12 NA 19/06/2020 08:16:21
## 7 MX001 Abarrotes 7.501032e+12 NA 19/06/2020 08:23:33
## 8 MX001 Abarrotes 7.501000e+12 NA 19/06/2020 08:24:33
## 9 MX001 Abarrotes 7.501031e+12 NA 19/06/2020 08:24:33
## 10 MX001 Abarrotes 7.501026e+12 NA 19/06/2020 08:26:28
## Marca Fabricante
## 1 NUTRI LECHE MEXILAC
## 2 DAN UP DANONE DE MEXICO
## 3 BIMBO GRUPO BIMBO
## 4 PEPSI PEPSI-COLA MEXICANA
## 5 BLANCA NIEVES (DETERGENTE) FABRICA DE JABON LA CORONA
## 6 NUTRI LECHE MEXILAC
## 7 DAN UP DANONE DE MEXICO
## 8 BIMBO GRUPO BIMBO
## 9 PEPSI PEPSI-COLA MEXICANA
## 10 BLANCA NIEVES (DETERGENTE) FABRICA DE JABON LA CORONA
## Producto Precio Ult.Costo Unidades F.Ticket
## 1 Nutri Leche 1 Litro 16.0 12.31 1 1
## 2 DANUP STRAWBERRY P/BEBER 350GR NAL 14.0 14.00 1 2
## 3 Rebanadas Bimbo 2Pz 5.0 5.00 1 3
## 4 Pepsi N.R. 400Ml 8.0 8.00 1 3
## 5 Detergente Blanca Nieves 500G 19.5 15.00 1 4
## 6 Nutri Leche 1 Litro 16.0 12.31 1 1
## 7 DANUP STRAWBERRY P/BEBER 350GR NAL 14.0 14.00 1 2
## 8 Rebanadas Bimbo 2Pz 5.0 5.00 1 3
## 9 Pepsi N.R. 400Ml 8.0 8.00 1 3
## 10 Detergente Blanca Nieves 500G 19.5 15.00 1 4
## NombreDepartamento NombreFamilia NombreCategoria
## 1 Abarrotes Lacteos y Refrigerados Leche
## 2 Abarrotes Lacteos y Refrigerados Yogurt
## 3 Abarrotes Pan y Tortilla Pan Dulce Empaquetado
## 4 Abarrotes Bebidas Refrescos Plástico (N.R.)
## 5 Abarrotes Limpieza del Hogar Lavandería
## 6 Abarrotes Lacteos y Refrigerados Leche
## 7 Abarrotes Lacteos y Refrigerados Yogurt
## 8 Abarrotes Pan y Tortilla Pan Dulce Empaquetado
## 9 Abarrotes Bebidas Refrescos Plástico (N.R.)
## 10 Abarrotes Limpieza del Hogar Lavandería
## Estado Mts.2 Tipo.ubicación Giro Hora.inicio Hora.cierre
## 1 Nuevo León 60 Esquina Abarrotes 08:00 22:00
## 2 Nuevo León 60 Esquina Abarrotes 08:00 22:00
## 3 Nuevo León 60 Esquina Abarrotes 08:00 22:00
## 4 Nuevo León 60 Esquina Abarrotes 08:00 22:00
## 5 Nuevo León 60 Esquina Abarrotes 08:00 22:00
## 6 Nuevo León 60 Esquina Abarrotes 08:00 22:00
## 7 Nuevo León 60 Esquina Abarrotes 08:00 22:00
## 8 Nuevo León 60 Esquina Abarrotes 08:00 22:00
## 9 Nuevo León 60 Esquina Abarrotes 08:00 22:00
## 10 Nuevo León 60 Esquina Abarrotes 08:00 22:00
tail(df_T,10)
## ClaveTienda DescGiro Codigo.Barras PLU Fecha Hora
## 200616 MX005 Depósito 7.62221e+12 NA 07/08/2020 19:30:13
## 200617 MX005 Depósito 7.62221e+12 NA 25/07/2020 18:42:24
## 200618 MX005 Depósito 7.62221e+12 NA 18/07/2020 22:45:58
## 200619 MX005 Depósito 7.62221e+12 NA 12/07/2020 00:36:34
## 200620 MX005 Depósito 7.62221e+12 NA 12/07/2020 01:08:25
## 200621 MX005 Depósito 7.62221e+12 NA 23/10/2020 22:17:37
## 200622 MX005 Depósito 7.62221e+12 NA 10/10/2020 20:30:20
## 200623 MX005 Depósito 7.62221e+12 NA 10/10/2020 22:40:43
## 200624 MX005 Depósito 7.62221e+12 NA 27/06/2020 22:30:19
## 200625 MX005 Depósito 7.62221e+12 NA 26/06/2020 23:43:34
## Marca Fabricante Producto Precio
## 200616 TRIDENT XTRA CARE CADBURY ADAMS Trident Xtracare Freshmint 16.32G 9
## 200617 TRIDENT XTRA CARE CADBURY ADAMS Trident Xtracare Freshmint 16.32G 9
## 200618 TRIDENT XTRA CARE CADBURY ADAMS Trident Xtracare Freshmint 16.32G 9
## 200619 TRIDENT XTRA CARE CADBURY ADAMS Trident Xtracare Freshmint 16.32G 9
## 200620 TRIDENT XTRA CARE CADBURY ADAMS Trident Xtracare Freshmint 16.32G 9
## 200621 TRIDENT XTRA CARE CADBURY ADAMS Trident Xtracare Freshmint 16.32G 9
## 200622 TRIDENT XTRA CARE CADBURY ADAMS Trident Xtracare Freshmint 16.32G 9
## 200623 TRIDENT XTRA CARE CADBURY ADAMS Trident Xtracare Freshmint 16.32G 9
## 200624 TRIDENT XTRA CARE CADBURY ADAMS Trident Xtracare Freshmint 16.32G 9
## 200625 TRIDENT XTRA CARE CADBURY ADAMS Trident Xtracare Freshmint 16.32G 9
## Ult.Costo Unidades F.Ticket NombreDepartamento NombreFamilia
## 200616 6.92 1 106411 Abarrotes Dulcería
## 200617 6.92 1 104693 Abarrotes Dulcería
## 200618 6.92 1 103856 Abarrotes Dulcería
## 200619 6.92 1 103087 Abarrotes Dulcería
## 200620 6.92 1 103100 Abarrotes Dulcería
## 200621 6.92 1 116598 Abarrotes Dulcería
## 200622 6.92 1 114886 Abarrotes Dulcería
## 200623 6.92 1 114955 Abarrotes Dulcería
## 200624 6.92 1 101121 Abarrotes Dulcería
## 200625 6.92 1 100879 Abarrotes Dulcería
## NombreCategoria Estado Mts.2 Tipo.ubicación Giro Hora.inicio
## 200616 Gomas de Mazcar Quintana Roo 58 Esquina Mini súper 08:00
## 200617 Gomas de Mazcar Quintana Roo 58 Esquina Mini súper 08:00
## 200618 Gomas de Mazcar Quintana Roo 58 Esquina Mini súper 08:00
## 200619 Gomas de Mazcar Quintana Roo 58 Esquina Mini súper 08:00
## 200620 Gomas de Mazcar Quintana Roo 58 Esquina Mini súper 08:00
## 200621 Gomas de Mazcar Quintana Roo 58 Esquina Mini súper 08:00
## 200622 Gomas de Mazcar Quintana Roo 58 Esquina Mini súper 08:00
## 200623 Gomas de Mazcar Quintana Roo 58 Esquina Mini súper 08:00
## 200624 Gomas de Mazcar Quintana Roo 58 Esquina Mini súper 08:00
## 200625 Gomas de Mazcar Quintana Roo 58 Esquina Mini súper 08:00
## Hora.cierre
## 200616 21:00
## 200617 21:00
## 200618 21:00
## 200619 21:00
## 200620 21:00
## 200621 21:00
## 200622 21:00
## 200623 21:00
## 200624 21:00
## 200625 21:00
# Tabla de Tienda y Departamento
tabyl(df_T, ClaveTienda, NombreDepartamento)
## ClaveTienda Abarrotes Bebes e Infantiles Carnes Farmacia Ferretería Mercería
## MX001 95415 515 1 147 245 28
## MX002 6590 21 0 4 10 0
## MX003 4026 15 0 2 8 0
## MX004 82234 932 0 102 114 16
## MX005 10014 0 0 0 0 0
## Papelería Productos a Eliminar Vinos y Licores
## 35 3 80
## 0 0 4
## 0 0 0
## 32 5 20
## 7 0 0
# Tabla de Estado y Hora de Inicio
tabyl(df_T, Estado, Hora.inicio)
## Estado 07:00 08:00 09:00
## Chiapas 4051 0 0
## Jalisco 0 0 6629
## Nuevo León 0 96469 0
## Quintana Roo 0 10021 0
## Sinaloa 83455 0 0
#Eliminar columnas
df_T <- subset(df_T, select=-c(PLU))
#Eliminar renglones
df_T <- df_T[df_T$Precio>0, ]
df_T <- distinct(df_T)
df_T$Unidades <- ceiling(df_T$Unidades)
df_T$Fecha <- as.Date(df_T$Fecha, format="%d/%m/%Y")
#Borrar todos los NA´s
#df_T <- na.omit(df_T)
#Remplazar los NA´s con CEROS
# df_T[is.na(df_t)] <- 0
#Remplazar los NA´s con el promedio
#df_t$altura([df_T$ALTURA]) <- MEAN(df_T$altura, na.rn=TRUE)
boxplot(df_T$Precio, horizontal = TRUE)
boxplot(df_T$Unidades, horizontal = TRUE)
# Ordenar de menor a mayor la columna ticket
df_T <- df_T[order(df_T$F.Ticket), ]
# Genera basket
basket <- ddply (df_T, c("F.Ticket"), function(df_T)paste(df_T$Marca, collapse = ","))
# Eliminar numero de ticket
basket$F.Ticket <- NULL
# Cambiar el titulo de lla columna V1 por marca
colnames(basket) <- c("Marca")
# Explorar market
write.csv(basket, "basket.csv", row.names=FALSE, quote=FALSE)
#file.choose()
tr <- read.transactions("/Users/fedecolyerjr/basket.csv", format = "basket", sep=",")
reglas.asosiacion <- 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: 115
##
## set item appearances ...[0 item(s)] done [0.00s].
## set transactions ...[604 item(s), 115031 transaction(s)] done [0.01s].
## sorting and recoding items ... [207 item(s)] done [0.00s].
## creating transaction tree ... done [0.02s].
## checking subsets of size 1 2 3 done [0.00s].
## writing ... [11 rule(s)] done [0.00s].
## creating S4 object ... done [0.00s].
# summary(reglas.asosiacion)
# inspect(reglas.asosiacion)
reglas.asosiacion <- sort(reglas.asosiacion,by = "confidence",decreasing = TRUE)
# summary(reglas.asosiacion)
# inspect((reglas.asosiacion))
top10reglas <- head(reglas.asosiacion, n = 10, by = "confidence")
plot(top10reglas,method="graph",engine = "htmlwidget")