En este artículo, propondré una alternativa a las técnicas comunes de análisis de la cesta de la compra que puede ayudar a los profesionales a encontrar patrones de alto valor en lugar de los más comunes. Obtendremos algo de intuición sobre diferentes problemas de minería de modelos y veremos un ejemplo del mundo real. El código completo se puede encontrar aquí. Todas las imágenes son creadas por el autor.
escribi uno mas artículo introductorio sobre explorar patrones ya; Si no está familiarizado con algunos de los conceptos que aparecen aquí, no dude en consultarlo primero.
En resumen, la minería de patrones intenta encontrar patrones en los datos (duuh). La mayoría de las veces, estos datos se encuentran en forma de (multi)conjuntos o secuencias. En mi último artículo, por ejemplo, analicé la secuencia de acciones que realiza un usuario en un sitio web. En este caso, nosotros sería preocuparse por el orden de los artículos.
En otros casos, como el que veremos a continuación, no nos importa el orden de los artículos. Solo enumeramos todos los artículos que fueron objeto de la transacción y con qué frecuencia aparecieron.
Entonces, por ejemplo, la transacción 1 contenía 🥪 3 veces y 🍎 una vez. Como vemos, perdemos información sobre el orden de los elementos, pero en muchos escenarios (como el que cubriremos a continuación) no existe un orden lógico de los elementos. Esto suena como una bolsa de palabras en PNL.
Análisis de la canasta de consumo. (MBA) es una técnica de análisis de datos comúnmente utilizada en el comercio minorista y el marketing para descubrir relaciones entre productos que los clientes tienden a comprar juntos. Su objetivo es identificar tendencias en los carritos o transacciones de los clientes mediante el análisis de su comportamiento de compra. La idea central es comprender la coexistencia de artículos en las transacciones de compra, lo que ayuda a las empresas a optimizar sus estrategias de colocación de productos, ventas cruzadas y campañas de marketing dirigidas.
Extracción frecuente de elementos. (FIM) es el proceso de encontrar patrones frecuentes en bases de datos de transacciones. Podemos examinar la frecuencia de un patrón (es decir, un conjunto de elementos) calculando su soporte. En otras palabras, el soporte para un modelo X es el número de transacciones T que contienen X (y que están en la base de datos D). Es decir, simplemente estamos viendo la frecuencia con la que aparece el modelo X en la base de datos.
En FIM, luego queremos encontrar todas las secuencias que tengan un soporte mayor que un cierto umbral (a menudo llamado minuto arriba). Si el soporte de una secuencia es mayor que minsup, se considera frecuente.
Límites
En FIM sólo nos fijamos en la existencia de un elemento en una secuencia. Es decir, no importa si un elemento aparece dos o 200 veces, simplemente lo representamos como un único elemento. Pero a menudo tenemos casos (como MBA) en los que no sólo es relevante la existencia de un artículo en una transacción, sino también el número de veces que apareció en la transacción.
Otro problema es que la frecuencia no siempre implica relevancia. En este sentido, FIM asume que todos los elementos de la transacción son igualmente importantes. Sin embargo, es razonable suponer que alguien que compre caviar podría ser más importante para una empresa que alguien que compre pan, porque el caviar es potencialmente un elemento de alto retorno de la inversión y ganancias.
Estas limitaciones nos llevan directamente a Conjuntos de artículos de alta utilidad para minería (HUIM) y Extracción de conjuntos de características cuantitativas de alta utilidad. (HUQIM) que son generalizaciones de FIM que intentan resolver algunos de los problemas del FIM normal.
Nuestra primera generalización es que los elementos pueden aparecer más de una vez en una transacción (es decir, tenemos un conjunto múltiple en lugar de un conjunto único). Como se dijo antes, en la minería normal de conjuntos de elementos, transformamos la transacción en un conjunto y solo miramos si el elemento existe en la transacción o no. Entonces, por ejemplo, las dos transacciones siguientes tendrían la misma representación.
t1 = [a,a,a,a,a,b] # repr. as {a,b} in FIM
t2 = [a,b] # repr. as {a,b} in FIM
Arriba, estas dos transacciones se representarían como [a,b] en la FIM clásica. Rápidamente vemos que en algunos casos es posible que nos falten detalles importantes. Por ejemplo, si a y b fueran artículos en el carrito de compras de un cliente, sería muy importante que tuviéramos A (por ejemplo, una barra de pan) cinco veces o sólo una vez. Por tanto, representamos la transacción como un multiset en el que escribimos cuántas veces apareció cada elemento.
# multiset representation
t1_ms = {(a,5),(b,1)}
t2_ms = {(a,1),(b,1)}
Este método también es eficaz si los elementos pueden aparecer en una gran cantidad de elementos (por ejemplo, 100 o 1000 veces). En este caso no necesitamos escribir cada a o b, sólo la frecuencia con la que aparecen.
La generalización que hacen los métodos cuantitativos y no cuantitativos es atribuir una utilidad a cada elemento de la transacción (por ejemplo, beneficio o tiempo). A continuación tenemos una tabla que asigna a cada posible artículo una ganancia unitaria.
Luego podemos calcular la utilidad de un patrón específico como {🥪, 🍎} sumando la utilidad de estos elementos en las transacciones que los contienen. En nuestro ejemplo, tendríamos:
(3🥪 * $1 + 1🍎 * $2) +
(1🥪 * $1 + 2🍎 * $2) = $10
Entonces obtenemos que este patrón tiene una utilidad de $10. Con FIM, nuestra tarea era encontrar patrones frecuentes. Ahora necesitamos encontrar patrones de gran utilidad. Esto se debe principalmente a que asumimos que la frecuencia no implica importancia. En el FIM clásico, es posible que hayamos pasado por alto patrones raros (poco comunes) que brindan una gran utilidad (por ejemplo, diamante), lo que no es el caso con HUIM.
También debemos definir la noción de utilidad de transacción. Es simplemente la suma de la utilidad de todos los elementos de la transacción. Para nuestra transacción 3 en la base de datos, esto sería
1🥪 * 1$ + 2🦞*10$ + 2🍎*2$ = 25$
Tenga en cuenta que resolver este problema y encontrar todos los elementos de alta utilidad es más difícil que en el FPM clásico. Esto se debe a que la utilidad no sigue la propiedad a priori.
La propiedad a priori
Sean X e Y dos modelos que aparecen en una base de datos de transacciones D. La propiedad a priori dice que si X es un subconjunto de Y, entonces el soporte de X debe ser al menos tan grande como el de Y.
Esto significa que si un subconjunto de Y es poco frecuente, Y mismo debe serlo porque debe tener un apoyo menor. Digamos que tenemos X = {a} e Y = {a,b}. Si Y aparece 4 veces en nuestra base de datos, entonces X debe aparecer al menos 4 veces, por lo que corresponderá a menos transacciones. Esta propiedad se utiliza en la mayoría de los algoritmos porque implica que si {a} es poco frecuente, todos los superconjuntos también lo son y podemos eliminarlos del espacio de búsqueda. [3].
Esta propiedad no es válida cuando hablamos de utilidad. Un superconjunto Y de la transacción X podría tener más o menos utilidad. Si tomamos el ejemplo anterior, {🥪} tiene una utilidad de $4. Pero eso no significa que no podamos observar superconjuntos de este modelo. Por ejemplo, el superconjunto que vimos {🥪, 🍎} tiene una utilidad mayor de $10. Al mismo tiempo, un superconjunto de un modelo no siempre será más útil porque es posible que ese superconjunto no aparezca con mucha frecuencia en la base de datos.
La idea detrás de HUIM
Como no podemos usar directamente la propiedad a priori para HUIM, necesitamos encontrar otro límite superior para reducir el espacio de búsqueda. Tal límite se llama Uso ponderado por transacciones (UTU). Para calcularlo sumamos la utilidad transaccional de las transacciones que contienen el motivo X de interés. Cualquier superconjunto Y de X no puede tener una utilidad mayor que TWU. Aclaremos esto con un ejemplo. El TWU de {🥪,🍎} es $30 ($5 de la transacción 1 y $5 de la transacción 3). Cuando observamos un modelo de superconjunto Y como {🥪 🦞 🍎}, podemos ver que no hay forma de que tenga más utilidad ya que todas las transacciones que contienen Y también contienen X.
Hoy en día existen diferentes algoritmos para resolver HUIM. Todos reciben una utilidad mínima y producen los modelos que tienen al menos esa utilidad como resultado. En este caso utilicé el EFIM algoritmo porque es rápido y eficiente en memoria.
Para este artículo, trabajaré con el Análisis de la canasta de consumo. Conjunto de datos de Kaggle (utilizado con permiso del autor del conjunto de datos original).
Arriba podemos ver la distribución de los valores de las transacciones que se encuentran en los datos. Hay un total de aproximadamente 19,500 transacciones con un valor de transacción promedio de $526 y 26 artículos distintos por transacción. En total hay alrededor de 4.000 artículos únicos. También podemos hacer un Análisis ABC donde colocamos los artículos en diferentes compartimentos según su participación en la facturación total. Podemos ver que alrededor de 500 de los 4000 artículos representan aproximadamente el 70% de los ingresos (artículos A). Luego tenemos una larga cola de artículos (alrededor de 2250) que representan alrededor del 5% de los ingresos (artículos C).
Pretratamiento
Los datos iniciales están en un formato largo donde cada línea corresponde a un artículo de una factura. Desde el número de factura podemos ver a qué transacción pertenece el artículo.
Después del preprocesamiento, obtenemos los datos en el formato requerido por PAMI ¿Cuál es la biblioteca de Python que usaremos para aplicar el algoritmo EFIM?
data['item_id'] = pd.factorize(data.Itemname)[0].astype(str) # map item names to id
data["Value_Int"] = data["Value"].astype(int).astype(str)
data = data.loc[data.Value_Int != '0'] # exclude items w/o utilitytransaction_db = data.groupby('BillNo').agg(
items=('item_id', lambda x: ' '.join(list(x))),
total_value=('Value', lambda x: int(x.sum())),
values=('Value_Int', lambda x: ' '.join(list(x))),
)
# filter out long transactions, only use subset of transactions
transaction_db = transaction_db.loc[transaction_db.num_items < 10].iloc[:1000]
Luego podemos aplicar la EFIM algoritmo.
import PAMI.highUtilityPattern.basic.EFIM as efim obj = efim.EFIM('tdb.csv', minUtil=1000, sep=' ')
obj.startMine() #start the mining process
obj.save('out.txt') #store the patterns in file
results = obj.getPatternsAsDataFrame() #Get the patterns discovered into a dataframe
obj.printResults()
Luego, el algoritmo devuelve una lista de modelos que cumplen con este criterio de utilidad mínima.