Minería de Datos

Práctica 4. Reglas de asociación

Author

Dr. Jorge Párraga Álava

Facultad de Ciencias Informáticas

Contexto del problema

El Centro Deportivo Urbano Vitalidad quiere entender mejor los patrones de participación de sus miembros en diferentes actividades deportivas. El objetivo es identificar qué actividades suelen realizarse juntas, lo que podría ayudar a:

  1. Diseñar paquetes de membresía más atractivos
  2. Optimizar la programación de clases y uso de instalaciones
  3. Desarrollar estrategias de marketing cruzado

Para ello se solicita que encuentre reglas de asociacón utilizando el algoritmo A priori

Base de datos

Nuestra base de datos consiste en registros de actividades deportivas realizadas por los miembros del centro durante un mes. Cada transacción representa las actividades que un miembro realizó en una visita al centro.

Las actividades incluidas son:

  • Correr

  • Nadar

  • Ciclismo

  • Yoga

  • Fútbol

  • Baloncesto

  • Tenis

  • Gimnasio (entrenamiento con pesas)

Configuración Inicial

# Bibliotecas -------------------------------------------------------------
if(!require(tidyverse)) install.packages("tidyverse") 
if(!require(arules)) install.packages("arules") 
if(!require(arulesViz)) install.packages("arulesViz")  
if(!require(readr)) install.packages("readr")   

# Config -------------------------------------------------------------
# Para notación no numérica.
options(scipen=999) 
# Para reproducibilidad.
set.seed(2024) 

0. Dominio del problema

  1. ¿Cuál es el problema específico que estamos tratando de resolver?

    Estamos tratando de identificar patrones de actividad y asociaciones entre diferentes deportes en el Centro Deportivo Urbano Vitalidad para optimizar sus operaciones, mejorar la experiencia de los miembros y aumentar la retención de clientes.

  2. ¿Es factible lograr nuestros objetivos con los datos disponibles? ¿Cómo podemos alcanzarlos?

    Sí, es factible lograr nuestros objetivos con los datos disponibles. Podemos alcanzarlos mediante el análisis de reglas de asociación utilizando el algoritmo Apriori, que nos permitirá descubrir patrones significativos en las actividades de los miembros.

  3. ¿Cuáles son los beneficios si nuestra solución funciona y cuáles son las consecuencias si falla?

    • Si nuestra solución funciona:

      • Mejora en la utilización de las instalaciones.
      • Aumento en la satisfacción y retención de miembros.
      • Optimización de horarios y programación de actividades.
      • Desarrollo de paquetes de membresía más atractivos.
    • Si la solución falla:

      • Persistencia de la subutilización de ciertas instalaciones.
      • Continuación de la alta rotación de miembros en algunos programas.
      • Pérdida de oportunidades para mejorar la experiencia del cliente.
      • Posible desventaja competitiva frente a otros centros deportivos.
  4. ¿Qué tipo de problema se va a resolver: Predictivo/Descriptivo?

    Este es principalmente un problema descriptivo, ya que estamos buscando patrones y asociaciones en los datos existentes para entender mejor el comportamiento de los miembros.

  5. ¿El objetivo es predecir, segmentar, …?

    Nuestro objetivo principal es descubrir asociaciones entre diferentes actividades deportivas para informar decisiones operativas y estratégicas del centro deportivo.

  6. ¿De dónde vendrán los datos, cuánto cuesta conseguirlos?

    Los datos provienen de los registros de actividad de los miembros del Centro Deportivo Urbano Vitalidad durante un mes.

1. Selección

En esta etapa, se realiza la selección del conjunto de datos. Como este es proporcionado por la empresa, únicamente lo cargamos.

# Cargar datos 
actividades_deportivas <- read_csv("actividades_deportivas.csv")
# mostrar un vista previa de datos
head(actividades_deportivas)
# A tibble: 6 × 8
  correr nadar ciclismo yoga  fútbol baloncesto tenis gimnasio
  <lgl>  <lgl> <lgl>    <lgl> <lgl>  <lgl>      <lgl> <lgl>   
1 TRUE   FALSE TRUE     FALSE FALSE  FALSE      FALSE TRUE    
2 TRUE   TRUE  FALSE    FALSE TRUE   FALSE      FALSE FALSE   
3 TRUE   FALSE TRUE     TRUE  TRUE   TRUE       TRUE  TRUE    
4 TRUE   FALSE TRUE     FALSE TRUE   FALSE      TRUE  TRUE    
5 TRUE   FALSE TRUE     FALSE TRUE   FALSE      TRUE  FALSE   
6 FALSE  FALSE TRUE     FALSE TRUE   TRUE       TRUE  FALSE   

Se observa que el conjunto de datos tiene 1200 transaccciones.

2. Limpieza

Para este conjunto de datos no es necesario realizar procesos de limpieza toda vez que Centro Deportivo Urbano Vitalidad ha proporcionado el conjunto de datos limpio.

3. Transformación

En etapa convertimos actividades_deportivas en un conjunto de datos tipo transaccional.

# Leer el archivo CSV
df_transacciones <- read.csv("actividades_deportivas.csv", stringsAsFactors = FALSE)

# Convertir las columnas a lógicas
df_transacciones[] <- lapply(df_transacciones, function(x) as.logical(x == "TRUE"))

# Convertir el dataframe a un objeto de transacciones
transacciones <- as(df_transacciones, "transactions")

# Mostrar un resumen de los datos
summary(transacciones) 
transactions as itemMatrix in sparse format with
 1200 rows (elements/itemsets/transactions) and
 8 columns (items) and a density of 0.6217708 

most frequent items:
  fútbol   correr    tenis ciclismo    nadar  (Other) 
    1028      960      867      809      602     1703 

element (itemset/transaction) length distribution:
sizes
  3   4   5   6   7 
253 226 247 247 227 

   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  3.000   4.000   5.000   4.974   6.000   7.000 

includes extended item information - examples:
    labels variables levels
1   correr    correr   TRUE
2    nadar     nadar   TRUE
3 ciclismo  ciclismo   TRUE

includes extended transaction information - examples:
  transactionID
1             1
2             2
3             3

4 y 5. Modelado y validación

Aquí, se aplica el algoritmo A priori para generar reglas de asociación bajo tres escenarios con diferentes umbrales de soporte y confianza. Luego, se podan las reglas redundantes para obtener conjuntos más manejables y relevantes de reglas.

# Función para generar reglas
generar_reglas <- function(soporte, confianza) {
  apriori(transacciones, parameter = list(supp = soporte, 
                                          conf = confianza, 
                                          minlen = 2))
}

# Generar reglas para los tres escenarios
reglas_1 <- generar_reglas(0.10, 0.60)
Apriori

Parameter specification:
 confidence minval smax arem  aval originalSupport maxtime support minlen
        0.6    0.1    1 none FALSE            TRUE       5     0.1      2
 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: 120 

set item appearances ...[0 item(s)] done [0.00s].
set transactions ...[8 item(s), 1200 transaction(s)] done [0.00s].
sorting and recoding items ... [8 item(s)] done [0.00s].
creating transaction tree ... done [0.00s].
checking subsets of size 1 2 3 4 5 6 done [0.00s].
writing ... [344 rule(s)] done [0.00s].
creating S4 object  ... done [0.00s].
reglas_2 <- generar_reglas(0.15, 0.70)
Apriori

Parameter specification:
 confidence minval smax arem  aval originalSupport maxtime support minlen
        0.7    0.1    1 none FALSE            TRUE       5    0.15      2
 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: 180 

set item appearances ...[0 item(s)] done [0.00s].
set transactions ...[8 item(s), 1200 transaction(s)] done [0.00s].
sorting and recoding items ... [8 item(s)] done [0.00s].
creating transaction tree ... done [0.00s].
checking subsets of size 1 2 3 4 5 done [0.00s].
writing ... [201 rule(s)] done [0.00s].
creating S4 object  ... done [0.00s].
reglas_3 <- generar_reglas(0.20, 0.80)
Apriori

Parameter specification:
 confidence minval smax arem  aval originalSupport maxtime support minlen
        0.8    0.1    1 none FALSE            TRUE       5     0.2      2
 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: 240 

set item appearances ...[0 item(s)] done [0.00s].
set transactions ...[8 item(s), 1200 transaction(s)] done [0.00s].
sorting and recoding items ... [8 item(s)] done [0.00s].
creating transaction tree ... done [0.00s].
checking subsets of size 1 2 3 4 5 done [0.00s].
writing ... [84 rule(s)] done [0.00s].
creating S4 object  ... done [0.00s].
# Mostrar las reglas generadas
inspect(head(reglas_1))
    lhs             rhs        support   confidence coverage lift     count
[1] {gimnasio}   => {ciclismo} 0.3300000 0.6947368  0.4750   1.030512 396  
[2] {gimnasio}   => {tenis}    0.3466667 0.7298246  0.4750   1.010138 416  
[3] {gimnasio}   => {correr}   0.3833333 0.8070175  0.4750   1.008772 460  
[4] {gimnasio}   => {fútbol}   0.4166667 0.8771930  0.4750   1.023961 500  
[5] {baloncesto} => {ciclismo} 0.3233333 0.6843034  0.4725   1.015036 388  
[6] {baloncesto} => {tenis}    0.3566667 0.7548501  0.4725   1.044775 428  
inspect(head(reglas_2))
    lhs             rhs      support   confidence coverage lift     count
[1] {gimnasio}   => {tenis}  0.3466667 0.7298246  0.4750   1.010138 416  
[2] {gimnasio}   => {correr} 0.3833333 0.8070175  0.4750   1.008772 460  
[3] {gimnasio}   => {fútbol} 0.4166667 0.8771930  0.4750   1.023961 500  
[4] {baloncesto} => {tenis}  0.3566667 0.7548501  0.4725   1.044775 428  
[5] {baloncesto} => {correr} 0.3783333 0.8007055  0.4725   1.000882 454  
[6] {baloncesto} => {fútbol} 0.4091667 0.8659612  0.4725   1.010850 491  
inspect(head(reglas_3))
    lhs             rhs      support   confidence coverage  lift     count
[1] {gimnasio}   => {correr} 0.3833333 0.8070175  0.4750000 1.008772 460  
[2] {gimnasio}   => {fútbol} 0.4166667 0.8771930  0.4750000 1.023961 500  
[3] {baloncesto} => {correr} 0.3783333 0.8007055  0.4725000 1.000882 454  
[4] {baloncesto} => {fútbol} 0.4091667 0.8659612  0.4725000 1.010850 491  
[5] {yoga}       => {correr} 0.3841667 0.8144876  0.4716667 1.018110 461  
[6] {yoga}       => {fútbol} 0.4125000 0.8745583  0.4716667 1.020885 495  

El algoritmo A priori encontró 344, 201, y 84 reglas para el primero, segundo y tercer escenario, respectivamente. Ahora podamos las reglas para encontrar las más relevantes.

podar_reglas <- function(reglas) {
  # Si no hay reglas, retornar el conjunto vacío
  if(length(reglas) == 0) return(reglas)
  # Ordenar las reglas por lift en orden descendente
  reglas_ordenadas <- sort(reglas, by = "lift", decreasing = TRUE)
  # Inicializar un vector para marcar reglas a mantener
  reglas_a_mantener <- rep(TRUE, length(reglas_ordenadas))
  # Comparar cada regla con las demás
  for(i in 1:(length(reglas_ordenadas) - 1)) {
    if(reglas_a_mantener[i]) {
      for(j in (i+1):length(reglas_ordenadas)) {
        if(reglas_a_mantener[j]) {
          # Verificar si la regla j es un subconjunto de la regla i
          if(all(is.subset(reglas_ordenadas[j], reglas_ordenadas[i]))) {
            reglas_a_mantener[j] <- FALSE
          }
        }
      }
    }
  }
  
  # Retornar solo las reglas no redundantes
  return(reglas_ordenadas[reglas_a_mantener])
}


# Podar las reglas redundantes
reglas_podadas_1 <- podar_reglas(reglas_1)
reglas_podadas_1
set of 13 rules 
reglas_podadas_2 <- podar_reglas(reglas_2)
reglas_podadas_2
set of 24 rules 
reglas_podadas_3 <- podar_reglas(reglas_3)
reglas_podadas_3
set of 15 rules 

Se evalúan las reglas generadas, comparando los resultados antes y después del podado. Se interpretan las reglas más significativas en términos de soporte, confianza y lift.

Luego del proceso de podado se observa que las reglas no redundantes son 13, 24 y 15, para los escenarios 1, 2, y 3, respectivamente. Denotando que hay una reducción significativa de reglas. Comparamos ahora las reglas antes y después del podado.

# Función para mostrar reglas de manera legible
mostrar_reglas <- function(reglas, titulo, n = 5) {
  cat("\n", titulo, "\n")
  cat("Número total de reglas:", length(reglas), "\n")
  
  if(length(reglas) == 0) {
    cat("No se generaron reglas con los umbrales especificados.\n")
    return()
  }
  
  cat("Mostrando las top", min(n, length(reglas)), "reglas por lift:\n\n")
  
  top_reglas <- head(sort(reglas, by = "lift"), n)
  reglas_df <- as(top_reglas, "data.frame")
  
  for(i in 1:nrow(reglas_df)) {
    cat("Regla", i, ":\n")
    cat("  Regla:", as.character(reglas_df$rules[i]), "\n") 
    cat("  Soporte:", round(reglas_df$support[i], 4), "\n")
    cat("  Confianza:", round(reglas_df$confidence[i], 4), "\n")
    cat("  Lift:", round(reglas_df$lift[i], 4), "\n\n")
  }
}

# Mostrar reglas para cada escenario antes y después del podado
mostrar_reglas(reglas_1, "Escenario 1 - Antes del podado")

 Escenario 1 - Antes del podado 
Número total de reglas: 344 
Mostrando las top 5 reglas por lift:

Regla 1 :
  Regla: {correr,ciclismo,yoga,fútbol,baloncesto} => {tenis} 
  Soporte: 0.1025 
  Confianza: 0.8311 
  Lift: 1.1503 

Regla 2 :
  Regla: {correr,ciclismo,fútbol,baloncesto} => {tenis} 
  Soporte: 0.2008 
  Confianza: 0.8282 
  Lift: 1.1463 

Regla 3 :
  Regla: {correr,ciclismo,yoga,fútbol} => {tenis} 
  Soporte: 0.2008 
  Confianza: 0.8282 
  Lift: 1.1463 

Regla 4 :
  Regla: {correr,ciclismo,yoga,fútbol,gimnasio} => {tenis} 
  Soporte: 0.1058 
  Confianza: 0.8247 
  Lift: 1.1414 

Regla 5 :
  Regla: {ciclismo,yoga,fútbol,baloncesto} => {tenis} 
  Soporte: 0.1183 
  Confianza: 0.8161 
  Lift: 1.1295 
mostrar_reglas(reglas_podadas_1, "Escenario 1 - Después del podado")

 Escenario 1 - Después del podado 
Número total de reglas: 13 
Mostrando las top 5 reglas por lift:

Regla 1 :
  Regla: {correr,ciclismo,yoga,fútbol,baloncesto} => {tenis} 
  Soporte: 0.1025 
  Confianza: 0.8311 
  Lift: 1.1503 

Regla 2 :
  Regla: {correr,ciclismo,yoga,fútbol,gimnasio} => {tenis} 
  Soporte: 0.1058 
  Confianza: 0.8247 
  Lift: 1.1414 

Regla 3 :
  Regla: {correr,nadar,fútbol,baloncesto} => {tenis} 
  Soporte: 0.1408 
  Confianza: 0.8125 
  Lift: 1.1246 

Regla 4 :
  Regla: {correr,nadar,yoga,fútbol} => {tenis} 
  Soporte: 0.1383 
  Confianza: 0.8098 
  Lift: 1.1208 

Regla 5 :
  Regla: {correr,ciclismo,baloncesto,gimnasio} => {tenis} 
  Soporte: 0.1083 
  Confianza: 0.8075 
  Lift: 1.1176 
mostrar_reglas(reglas_2, "Escenario 2 - Antes del podado")

 Escenario 2 - Antes del podado 
Número total de reglas: 201 
Mostrando las top 5 reglas por lift:

Regla 1 :
  Regla: {correr,ciclismo,fútbol,baloncesto} => {tenis} 
  Soporte: 0.2008 
  Confianza: 0.8282 
  Lift: 1.1463 

Regla 2 :
  Regla: {correr,ciclismo,yoga,fútbol} => {tenis} 
  Soporte: 0.2008 
  Confianza: 0.8282 
  Lift: 1.1463 

Regla 3 :
  Regla: {correr,ciclismo,baloncesto} => {tenis} 
  Soporte: 0.2133 
  Confianza: 0.8153 
  Lift: 1.1284 

Regla 4 :
  Regla: {correr,ciclismo,yoga} => {tenis} 
  Soporte: 0.2167 
  Confianza: 0.8075 
  Lift: 1.1176 

Regla 5 :
  Regla: {correr,fútbol,baloncesto,tenis} => {ciclismo} 
  Soporte: 0.2008 
  Confianza: 0.7508 
  Lift: 1.1136 
mostrar_reglas(reglas_podadas_2, "Escenario 2 - Después del podado")

 Escenario 2 - Después del podado 
Número total de reglas: 24 
Mostrando las top 5 reglas por lift:

Regla 1 :
  Regla: {correr,ciclismo,fútbol,baloncesto} => {tenis} 
  Soporte: 0.2008 
  Confianza: 0.8282 
  Lift: 1.1463 

Regla 2 :
  Regla: {correr,ciclismo,yoga,fútbol} => {tenis} 
  Soporte: 0.2008 
  Confianza: 0.8282 
  Lift: 1.1463 

Regla 3 :
  Regla: {correr,yoga,baloncesto} => {tenis} 
  Soporte: 0.15 
  Confianza: 0.8 
  Lift: 1.1073 

Regla 4 :
  Regla: {ciclismo,fútbol,tenis,gimnasio} => {correr} 
  Soporte: 0.1925 
  Confianza: 0.8851 
  Lift: 1.1063 

Regla 5 :
  Regla: {correr,nadar,baloncesto} => {tenis} 
  Soporte: 0.155 
  Confianza: 0.7983 
  Lift: 1.1049 
mostrar_reglas(reglas_3, "Escenario 3 - Antes del podado")

 Escenario 3 - Antes del podado 
Número total de reglas: 84 
Mostrando las top 5 reglas por lift:

Regla 1 :
  Regla: {correr,ciclismo,fútbol,baloncesto} => {tenis} 
  Soporte: 0.2008 
  Confianza: 0.8282 
  Lift: 1.1463 

Regla 2 :
  Regla: {correr,ciclismo,yoga,fútbol} => {tenis} 
  Soporte: 0.2008 
  Confianza: 0.8282 
  Lift: 1.1463 

Regla 3 :
  Regla: {correr,ciclismo,baloncesto} => {tenis} 
  Soporte: 0.2133 
  Confianza: 0.8153 
  Lift: 1.1284 

Regla 4 :
  Regla: {correr,ciclismo,yoga} => {tenis} 
  Soporte: 0.2167 
  Confianza: 0.8075 
  Lift: 1.1176 

Regla 5 :
  Regla: {correr,yoga,fútbol} => {tenis} 
  Soporte: 0.2717 
  Confianza: 0.801 
  Lift: 1.1086 
mostrar_reglas(reglas_podadas_3, "Escenario 3 - Después del podado")

 Escenario 3 - Después del podado 
Número total de reglas: 15 
Mostrando las top 5 reglas por lift:

Regla 1 :
  Regla: {correr,ciclismo,fútbol,baloncesto} => {tenis} 
  Soporte: 0.2008 
  Confianza: 0.8282 
  Lift: 1.1463 

Regla 2 :
  Regla: {correr,ciclismo,yoga,fútbol} => {tenis} 
  Soporte: 0.2008 
  Confianza: 0.8282 
  Lift: 1.1463 

Regla 3 :
  Regla: {ciclismo,tenis,gimnasio} => {correr} 
  Soporte: 0.215 
  Confianza: 0.8776 
  Lift: 1.0969 

Regla 4 :
  Regla: {nadar,ciclismo,tenis} => {correr} 
  Soporte: 0.2225 
  Confianza: 0.8613 
  Lift: 1.0766 

Regla 5 :
  Regla: {nadar,fútbol,tenis} => {correr} 
  Soporte: 0.2717 
  Confianza: 0.8534 
  Lift: 1.0668 

De las reglas obtenidas para el escenario 3 podemos mencionar, por ejemplo:

Regla 1:

El soporte del 20.08% indica que en el 20.08% de todas las transacciones registradas en la base de datos, se solicitaron tanto correr,ciclismo,fútbol,baloncesto como tenis. Este es un soporte sutilmente alto, lo que sugiere que la combinación de correr,ciclismo,fútbol,baloncesto y tenis es bastante común en los servicios solicitados del centro.

La confianza del 82.82% indica que, entre todos los clientes que solicita correr,ciclismo,fútbol,baloncesto, el 65.85% también solicita tenis. Esto demuestra una relación bastante fuerte entre estos servicios en el Centro Deportivo Urbano Vitalidad.

El lift de 1.14 indica que la probabilidad de solicitar tenis en una sesión aumenta ligeramente si ya se está solicitando correr,ciclismo,fútbol,baloncesto. Aunque este lift es apenas superior a 1, lo que indica una leve relación positiva, no sugiere una dependencia fuerte.

Visualización

Ahora se crean visualizaciones de las reglas de asociación utilizando gráficos de red para cada escenario, lo que permite una interpretación visual de las relaciones entre los servicios:

# Función para visualizar reglas en un gráfico de red
visualizar_reglas_red <- function(reglas, titulo) {
  if(length(reglas) == 0) {
    cat("No se pueden visualizar reglas para:", titulo, "\n")
    cat("No se generaron reglas con los umbrales especificados.\n")
    return()
  }
  plot(reglas, method = "graph", 
       control = list(type = "items"), 
       main = titulo)
}

# Visualizar reglas en gráfico de red para cada escenario después del podado
visualizar_reglas_red(head(sort(reglas_podadas_1, by = "lift"), 3), 
                      "Top 5 Reglas - Escenario 1 (Después del podado)")
Available control parameters (with default values):
layout   =  stress
circular     =  FALSE
ggraphdots   =  NULL
edges    =  <environment>
nodes    =  <environment>
nodetext     =  <environment>
colors   =  c("#EE0000FF", "#EEEEEEFF")
engine   =  ggplot2
max  =  100
verbose  =  FALSE

visualizar_reglas_red(head(sort(reglas_podadas_2, by = "lift"), 3), 
                      "Top 5 Reglas - Escenario 2 (Después del podado)")
Available control parameters (with default values):
layout   =  stress
circular     =  FALSE
ggraphdots   =  NULL
edges    =  <environment>
nodes    =  <environment>
nodetext     =  <environment>
colors   =  c("#EE0000FF", "#EEEEEEFF")
engine   =  ggplot2
max  =  100
verbose  =  FALSE

visualizar_reglas_red(head(sort(reglas_podadas_3, by = "lift"), 3), 
                      "Top 5 Reglas - Escenario 3 (Después del podado)")
Available control parameters (with default values):
layout   =  stress
circular     =  FALSE
ggraphdots   =  NULL
edges    =  <environment>
nodes    =  <environment>
nodetext     =  <environment>
colors   =  c("#EE0000FF", "#EEEEEEFF")
engine   =  ggplot2
max  =  100
verbose  =  FALSE

Los gráficos representan las reglas de asociación generadas por el algoritmo Apriori para los servicios del Centro Deportivo Urbano Vitalidad. En el caso del escenario 3 tenemos:

Nodos: Cada nodo representa una regla en análisis.

Conexiones: Las líneas que conectan los nodos representan las reglas de asociación entre estos servicios. La dirección de las flechas indica la relación entre los ítems en las reglas (de antecedente a consecuente).

Tamaño de los nodos: El tamaño de los nodos representa el soporte (support) de cada ítem. La leyenda a la derecha muestra que el soporte varía de 0.20 a 0.21. El nodo “gimnasio” es el más grande, lo que sugiere que es el servicio más frecuente en las transacciones.

Color de las conexiones: El color de las líneas representa el lift de las reglas. La escala de colores a la derecha muestra que el lift varía de aproximadamente 1.10 a 1.14. El color rojo más intenso indica un lift más alto, lo que sugiere una asociación más fuerte entre los ítems.

Interpretación de las reglas: La regla más fuerte parece ser la que conecta “fútbol, baloncesto, correr, ciclismo” con “tenis”, dado su color rojo intenso.

Finalmente podemos observar los items mas frecuentes en la base de datos:

# 
itemFrequency(transacciones, type = "absolute")
    correr      nadar   ciclismo       yoga     fútbol baloncesto      tenis 
       960        602        809        566       1028        567        867 
  gimnasio 
       570 
itemFrequencyPlot(transacciones, topN = 10, type = "relative",
                  main = "Top 10 Servicios más frecuentes")

El gráfico indica que el servicio más requerido es fútbol, mientras que el servicio yoga es el menos solicitado.

Actividad calificada

Se debe utilizar el conjunto de datos ‘Groceries’ disponible en el paquete ‘arules’ de R. Este dataset contiene transacciones de compras en un supermercado y es ideal para aplicar reglas de asociación.

Instrucciones

  1. Crear un nuevo proyecto en RStudio con el nombre Mineria_Datos. Dentro del proyecto, organizar las carpetas de la siguiente manera:

    • Scripts: Para almacenar tus scripts de código R.

    • Datos: Para almacenar cualquier dataset que utilice en la actividad.

  2. Dentro del directorio Scripts, crear un script R llamado reglas.R. En este script, codificar las siguientes tareas:

    • Preprocesamiento de Datos:

      • Cargar el conjunto de datos ‘Groceries’ usando la función data("Groceries").

      • Realizar una exploración inicial de los datos usando funciones como summary() e itemFrequency() .

      • Visualizar los items más frecuentes utilizando itemFrequencyPlot().

    • Reglas de asociación:

      • Aplicar el algoritmo Apriori para generar reglas de asociación, probando diferentes umbrales de soporte y confianza (por ejemplo 0.01, 0.05, 0.1 para soporte y 0.5, 0.7, 0.9 para confianza).
      • Podar las reglas redundantes utilizando una función similar a la proporcionada en el tutorial.
      • Visualizar las reglas más relevantes usando plot() de arulesViz.
      • Interpretar las reglas más significativas en términos de soporte, confianza y lift, enfocándose en cómo estas reglas podrían usarse para estrategias de marketing o disposición de productos en el supermercado.
    • Documentación:

      • Agregar comentarios al código explicando la funcionalidad de cada sección. Incluir al inicio del script información sobre carrera e integrantes del grupo.

Entrega

Una vez completada la actividad, subir comprimir el proyecto en formato .zip con el nombre MD_Practica_4_GrupoX. Donde X debe ser reemplazado por su número de grupo.

Criterios de Evaluación

  • Estructura y organización del proyecto (10%).

  • Reglas de asociación (80%).

  • Documentación, formato de entrega y comentarios en el código (10%).