En este capítulo buscamos respuestas a las relaciones entre productos, sin tener en cuenta ninguna otra variable más que los diferentes productos que compra el cliente; algo similar al estudio de series temporales, donde se analiza la evolución de la variable en en tiempo sin tener en cuenta nada más. Lo que nos interesa de la cesta para nuestro caso concreto es “que más se adquiere con el seguro de accidentes” (si es que se adquiere algo más), o “que tiene el cliente antes de comprar el seguro de accidentes”.
Es un algoritmo muy usado en banca (por ejemplo para decidir si el cliente tiene crédito o no) analizando sus datos y ratios en comparación con los de otros clientes. De forma muy sencilla, se trata de incluir en una lista todos los articulos (servicios en este caso) que compran los clientes en diferentes fechas Tendremos diferentes listas de la compra para cada cliente como:
“azúcar”
“aceite, pan, sal”
“azúcar, café, fruta”,
“café, pan,”azucar, leche”,
“leche, café, azúcar”, pan, fruta”
Un grupo frecuente seria {azúcar, café}, y también {azúcar, café, leche}
Una regla de asociación será {azúcar -> café} o bien {café -> azúcar}; esto nos puede dar una pista de porque los articulos en un supermercado están colocados como lo están, por caótico que parezca a veces…
Para que el algoritmo sea efectivo se necesitan miles de transacciones, a fin de tener un objeto tipo “lista” para que los algoritmos puedan ejecutar sus cálculos, que son bastante sencillos, ya que están basados en tres medidas :
Supongamos ahora por ejemplo, 900 clientes tienen seguro de accidentes (a), de los cuales 300 tienen seguro de accidentes (a) y también seguro de hogar (b), de un total de 3900 clientes): a y b será el conjunto frecuente.
Soporte (support) a->b: las veces que el conjunto aparece en el total de transacciones. Si el seguro de accidentes y el seguro de hogar aparecen en 300 veces de 3900 transacciones, el soporte de (acd, hogar) es 300/3900 = 0.0769
Confianza (confidence) a->b: mide la exactitud de la predicción: las 300 veces que parece (acd, hogar) dividido entre las 900 veces que aparece el seguro de accidentes: 0.3333
Lift: cuanto aumenta la razón de venta: es la confianza de (a->b) dividido entre el soporte de b: 0.3333/0.0769 = 4.3342. un lift de 1 o por debajo anula la regla (se considera azar). Mientas más alto, más razón de venta.
En la regla a->b la parte izquierda (a) se denomina LHS y la parte derecha de la regla (b) es RHS. El soporte de a->b es igual que el soporte de b->a, pero no la confianza o el lift.
El algoritmo, basándose en las transacciones que le proporcionamos, ira creando subconjuntos de elementos de 1, 2, 3, 4 … pero si un elemento, por ejemplo, el seguro de salud, no es valorado como un ítem frecuente, ningún subconjunto que contenga la salud será evaluado. Asi que vamos a hacer esto a ver que nos aparece en nuestra base de datos. Creamos un código que extrae de cada registro los servicios contratados por cada cliente (sin ninguna otra información):
library(arules)
Cargando paquete requerido: Matrix
Adjuntando el paquete: 'arules'
The following objects are masked from 'package:base':
abbreviate, write
Rows: 3900 Columns: 17
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr (11): e_civil, nacionalidad, pago, seguro_gratuito, seguro_voluntario, s...
dbl (6): ...1, cliente, CP, edad, gasto, hijos
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
clientes <- BBDD_clientes
################## market basket #######################lista vacia para almacenar los valoreslista <-list()#miramos cada fila y creamos un vector con cada valor encontradofor (i in1:nrow(clientes)) { fila <- clientes[i, ] tiene_seguro <-unlist (fila[fila =="gratuito"| fila =="voluntario"| fila =="accidente"| fila =="vida"| fila =="hogar"| fila =="auto"| fila =="salud"| fila =="decesos"]) lista[[paste0("tr",i)]] <- tiene_seguro }# y borramos las filas vacias (si es que las hay)lista <-Filter (function(x) length(x) >0, lista)options ("arules.check"=FALSE) # Convertimos a objeto tipo transactiontransaciones <-as(lista, "transactions")# Visualizamos estadásticas básicas sobre nuestro conjunto de transaccionessummary(transaciones)
transactions as itemMatrix in sparse format with
3850 rows (elements/itemsets/transactions) and
8 columns (items) and a density of 0.3076299
most frequent items:
gratuito voluntario accidente auto decesos (Other)
3822 1755 1363 585 585 1365
element (itemset/transaction) length distribution:
sizes
1 2 3 4 5 6 7 8
1154 1498 374 251 317 179 76 1
Min. 1st Qu. Median Mean 3rd Qu. Max.
1.000 1.000 2.000 2.461 3.000 8.000
includes extended item information - examples:
labels
1 accidente
2 auto
3 decesos
includes extended transaction information - examples:
transactionID
1 tr1
2 tr2
3 tr3
Lo primero que vemos es que hemos pasado de 3900 clientes a una lista anónima de 3850 items, lo que significa que 50 clientes no tenian ningún seguro.
Los item más frecuentes aparecen por orden y son el seguro gratuito, el seguro voluntario, seguido del seguro de accidentes, auto y decesos. La categoría (Other) engloba el resto de items de la lista (salud, hogar, vida…)
La distribución nos dice que hay 1154 items con un artículo, 1498 items con 2 artículos, 374 items con 3 artículos…. y así sucesívamente. Un dato importante es que los item de 2 articulos pueden estar englobados en subconjuntos más grandes , los de 3 pueden estar en los de 4 o 5, y asi sucesivamente.
La media de articulo por cliente es de 2,461, y su mediana de 2.
Lo que se corresponde con la cesta de seguros de cada cliente (omitidos los que no tienen ningun seguro, ya que no hay “transacción”).
Nuestro objetivo es el estudio del seguro de accidentes, que además hemos visto que es el tercer item más frecuente en la cesta de seguros.
Creamos las reglas de asociación. Vamos a ver ahora el conjunto total de reglas para un soporte de 0.1 y confianza de 0.5; no mostrará ninguna regla de asociación por debajo de esos parámetros. Si ponemos unos valores muy bajos creará demasiadas reglas (que no servirán, serán por azar) y con valores demasiado altos, quizas no encuentre ninguna, por lo que hay que ir probando valores: (y aqui mostramos un ejemplo concreto con esos valores). Otros valores generan otras reglas que habrá que valorar.
#generación de reglas (jugar con soporte y confianza) reglas <-apriori(transaciones, parameter =list(supp =0.1, conf =0.5, target ="rules"))
set of 69 rules
rule length distribution (lhs + rhs):sizes
1 2 3 4 5
1 15 28 20 5
Min. 1st Qu. Median Mean 3rd Qu. Max.
1.000 3.000 3.000 3.188 4.000 5.000
summary of quality measures:
support confidence coverage lift
Min. :0.1195 Min. :0.5066 Min. :0.1195 Min. :0.9918
1st Qu.:0.1226 1st Qu.:0.8281 1st Qu.:0.1242 1st Qu.:1.0073
Median :0.1242 Median :0.9746 Median :0.1499 Median :1.8185
Mean :0.1589 Mean :0.9052 Mean :0.1817 Mean :2.9192
3rd Qu.:0.1473 3rd Qu.:0.9893 3rd Qu.:0.1519 3rd Qu.:3.5164
Max. :0.9927 Max. :1.0000 Max. :1.0000 Max. :6.4215
count
Min. : 460.0
1st Qu.: 472.0
Median : 478.0
Mean : 611.8
3rd Qu.: 567.0
Max. :3822.0
mining info:
data ntransactions support confidence
transaciones 3850 0.1 0.5
call
apriori(data = transaciones, parameter = list(supp = 0.1, conf = 0.5, target = "rules"))
Nos indica que ha encontrado 69 reglas de asociación en las condiciones indicadas (soporte y confianza), y nos indica también el tamaño total de los conjuntos a la izquierda y a la derecha de la regla (LHS + RHS). Asi mismo, nos dice los estadísticos descriptivos básicos.
Ya encontramos el objetivo de nuestro estudio en una de esas reglas, la número [3] que se leería de esta forma:
[3]“con un soporte de 0,14 y una confianza de 0.92 la cobertura de clientes con seguro de decesos que compran el seguro de accidentes es de un 15%”
Es una regla “por la derecha” porque acidentes está en la derecha del grupo, RHS) asi que accidentes sería una consecuencia de tener decesos.
Como buscamos saber la relación del seguro de accidentes con el resto de los servicios y si hay reglas de asociación, no vamos a mirar las 69 reglas encontradas, si no que vamos a filtrar las reglas, buscando en la izquierda (LHS) y en la derecha (RHS) de las reglas de asociación nuestro seguro de accidentes en los subconjuntos:
Como hemos dicho, si el seguro de accidentes está a la derecha, en RHS, la lectura será que el seguro de accidentes lo ha contratado el cliente que ya tiene otro producto:
#RHS accidentes: el seguro de acd como consecuencia de tener otros seguros reglas_acd_rhs <-apriori(transaciones, parameter =list (supp=0.01, conf =0.4), appearance =list (default ="lhs", rhs ="accidente"), target ="rules")
set of 62 rules
rule length distribution (lhs + rhs):sizes
2 3 4 5 6 7
5 15 20 15 6 1
Min. 1st Qu. Median Mean 3rd Qu. Max.
2.000 3.000 4.000 4.081 5.000 7.000
summary of quality measures:
support confidence coverage lift
Min. :0.01558 Min. :0.5066 Min. :0.01558 Min. :1.431
1st Qu.:0.02539 1st Qu.:0.9882 1st Qu.:0.02662 1st Qu.:2.791
Median :0.05143 Median :0.9929 Median :0.05143 Median :2.805
Mean :0.06742 Mean :0.9561 Mean :0.07751 Mean :2.701
3rd Qu.:0.11032 3rd Qu.:1.0000 3rd Qu.:0.12026 3rd Qu.:2.825
Max. :0.23091 Max. :1.0000 Max. :0.45584 Max. :2.825
count
Min. : 60.00
1st Qu.: 97.75
Median :198.00
Mean :259.58
3rd Qu.:424.75
Max. :889.00
mining info:
data ntransactions support confidence
transaciones 3850 0.01 0.4
call
apriori(data = transaciones, parameter = list(supp = 0.01, conf = 0.4), appearance = list(default = "lhs", rhs = "accidente"), target = "rules")
El algoritmo encuentra 60 reglas de asociación con un soporte superior a 0.1 y una confianza superior a 0.4. Nos ofrece también el tamaño total de los 62 subconjuntos, agrupados por ítems, y los 5 estadísticos básicos de los subconjuntos. Importante recordar que los 62 subconjuntos son redundantes (algunos de los más pequeños estarán también incluidos en los más grandes).
Podemos elegir, para filtrar las reglas, el ordenarlas por alguna de sus características. O bien por el número de veces que aparecen, o por el mayor soporte o confianza, o una combinación de ambos, lo que más nos interese, o investigando al respecto. Aquí es sencillo establecer reglas, ya que todo son seguros. En un supermercado, una regla que asocia lejía con café no parece una regla que tenga cierta lógica (y puede sucecer por azar, pero para eso esta el “lift”).
Vamos a ordenar por número de veces que aparece la transacción, después por confianza y después por lift:
#ordenando reglas_acd_rhs_ord <-sort(reglas_acd_rhs,by =c("count", "lift", "confidence"),decreasing =TRUE) #ver las mejores (por count, lift y confidence) inspect(reglas_acd_rhs_ord[1:5])
Y esta información tambien la vemos en forma de gráfico:
# mirando en html plot (reglas_acd_rhs_ord[1:5], method ="graph", engine ="html")
Vemos por ejemplo como partiendo de los clientes que tienen un seguro gratuito, pueden optar por la regla [5] {gratuito, auto} => {acd} o por la regla [2] {gratuito, voluntario} => {acd}, cada uno con sus parámetros. Aunque no vemos los datos aquí, pero visualmente se ven muy bien las relaciones y también lo que estábamos comentando de subconjuntos y reglas redundantes. Ahora bien, podría ser al revés (tener accidentes lleva al auto).
Haríamos lo mismo para el seguro de accidentes, pero ahora incluyéndolo en la parte izquierda de la transacción (es decir que los clientes que han comprado el seguro de accidentes compraron “cierto servicio”):
#mirando en html plot (reglas_acd_lhs, method ="graph", engine ="html")
Aparecen menos reglas que en el apartado anterior, pero hay dos de ellas interesantes. De los clientes que tienen en su cesta el seguro de accidentes, algunos adquirieron el seguro del hogar y otros el seguro de auto. (recordatorio: tenemos menos de 4000 transacciones y ademas son “ficticias”). Tambien podiamos haber cambiado lso parámetros anteriormente comentados.