Logotipo de Zephyrnet

Sistema de recomendación de productos mediante análisis RFM

Fecha:

Este artículo fue publicado como parte del Blogatón de ciencia de datos.

Introducción al análisis RFM

Este artículo tiene como objetivo guiarlo a través del importante concepto de segmentación de clientes mediante el análisis RFM y cómo se puede hacer mediante el aprendizaje automático. Los algoritmos que usaremos son el análisis RFM y lo compararemos con los grupos formados usando el algoritmo de agrupamiento de K-means. Para mejores recomendaciones personalizadas, he utilizado Market Basket Analysis utilizando el algoritmo Apriori para el mismo. Además, utilicé el filtrado colaborativo basado en artículos y comparé el rendimiento del análisis de la cesta de la compra y el filtrado colaborativo basado en artículos al final.

Tomemos un concepto a la vez y comencemos con el análisis RFM. El análisis RFM es el análisis de actualidad, frecuencia y monetario en Marketing Analytics, donde el factor 'R' se refiere a cuándo fue la última vez que un cliente realizó una compra, el factor 'F' se refiere a la cantidad de compras realizadas en un período determinado y el El factor 'M' es la cantidad total de dinero gastado por el cliente en el tiempo dado.

Supongo que ya está familiarizado con los conceptos del algoritmo de agrupamiento de K-means, Análisis de la cesta de la compra utilizando el algoritmo Apriori y el filtrado colaborativo basado en elementos. En este blog voy a tomar los clústeres o segmentos formados con la ayuda del análisis RFM y aplicar el análisis de la cesta de la compra utilizando el algoritmo Apriori y el filtrado colaborativo basado en elementos para obtener recomendaciones de productos mejores y más personalizadas de acuerdo con el segmento asignado al cliente. .
Usaré Python para la implementación, lo que le brindará una experiencia práctica. ¡Saltamos!

Importación de bibliotecas necesarias

En esta sección importaremos pandas, numpy, matplotlib, seaborn, StandardScaler, Kmeans, etc. Estas librerías son necesarias para procesamiento de datos, visualización y las dos últimas para algoritmos de aprendizaje automático respectivamente.

# importar biblioteca importar numpy como np # álgebra lineal importar pandas como pd # procesamiento de datos, E/S de archivo CSV (por ejemplo, pd.read_csv) importar fecha y hora como dt #Para visualización de datos importar matplotlib.pyplot como plt importar seaborn como sns #Para máquina Algoritmo de aprendizaje de sklearn.preprocessing import StandardScaler de sklearn.cluster import KMeans import os

Carga del conjunto de datos y búsqueda de detalles al respecto

Debe cargar el conjunto de datos utilizando una biblioteca panda. Después de cargar los datos, puede verificar la información sobre los tipos de datos de los datos y ver el resumen del marco de datos utilizando la función .info(). Además, puede usar las funciones .describe(), .shape() para tener una comprensión general de los datos.

df = pd.read_excel(r'D:ProjectOnline_Mart_Dataset.xlsx') df.head(5) df.info()

Preprocesamiento de datos

Eliminar valores nulos y duplicados

Como los datos son datos transaccionales, es muy importante realizar un procesamiento previo de los datos para que sean adecuados para un análisis posterior. Se descubrió que faltaban algunas de las identificaciones y descripciones de los clientes. Podría coincidir con el código de stock y completar el valor, pero se descubrió que faltaba el precio unitario de estas filas y, por lo tanto, se eliminaron. Incluso después de eliminar todas estas filas, aún faltaban algunos ID de clientes y fueron reemplazados por el ID de cliente del marco de datos. Las entradas duplicadas fueron revisadas y eliminadas. Esto no afectará nuestro análisis de la canasta de mercado.

df.isnull().sum() df= df.dropna(subconjunto=['CustomerID']) df.duplicated().sum() df = df.drop_duplicates()

Análisis exploratorio de datos

Después del procesamiento previo de los datos, el siguiente paso fue realizar el Análisis exploratorio de datos (EDA). Al importar la biblioteca de nubes de palabras, trazamos la nube de palabras para encontrar los artículos más populares comprados primero por los clientes. Se encontraron los artículos más vendidos. A continuación se muestra el código de la nube de palabras.

import matplotlib.pyplot as plt import seaborn as sns from wordcloud import WordCloud plt.rcParams['figure.figsize'] = (10, 10) wordcloud = WordCloud(background_color = 'white', width = 1200, height = 1200, max_words = 20).generate(str(newsales['Description'])) plt.imshow(wordcloud) plt.axis('off') plt.title('Artículos más populares comprados primero por los clientes', tamaño de fuente = 40) plt. mostrar()

El siguiente código le dará los artículos vendidos con más frecuencia.

freqprod= newsales.groupby(["StockCode", "Description"])["Description"].count().sort_values(axis= 0,ascending =False) freqprod.head(5) top5freq = freqprod[:5,] .sort_values(ascending = True) top5freq.plot(kind = "barh") plt.ylabel('Productos') plt.xlabel('Cantidades vendidas') plt.title('Productos vendidos con mayor frecuencia')

El siguiente código le dará el mes en el que se realizó el número máximo de transacciones.

m.plot(tipo = "barh") plt.xlabel("Número de transacciones") plt.ylabel("Mes") plt.title("Meses con la mayoría de las transacciones")

Se pueden encontrar tipos similares de información según los requisitos, como cuáles fueron las horas pico, los productos más costosos, etc.

Construcción del modelo

Análisis RFM

El análisis RFM se realizó después de realizar el análisis exploratorio de datos. El análisis RFM respalda el proverbio de marketing de que "el 80% del negocio proviene del 20% del cliente". Se encontraron puntuaciones de RFM para los clientes y se agruparon en cuartiles/segmentos de RFM. Esto segmentó a los clientes en tres segmentos, a saber, oro, plata y bronce. Esto ayuda a comprender los patrones de compra del cliente y a qué clientes apuntar. Por lo tanto, el análisis de RFM básicamente brinda una instantánea de los clientes y ayuda a orientar mejor a los clientes para obtener ganancias y mantener la lealtad del cliente. La siguiente tabla proporciona los segmentos de clientes en función de la puntuación RFM calculada.

Rango de segmento Rango de puntuación de RFM
Gold >9
Silver > 5 y <= 9
Bronce > = 5

El siguiente fragmento de código muestra cómo crear los segmentos de RFM.

#Construcción de segmentos RFM r_labels =rango(4,0,-1) f_labels=rango(1,5) m_labels=rango(1,5) r_cuartiles = pd.qcut(rfm['Recency'], q=4, etiquetas = r_etiquetas) f_cuartiles = pd.qcut(rfm['Frecuencia'],q=4, etiquetas = f_etiquetas) m_cuartiles = pd.qcut(rfm['Valor monetario'],q=4,etiquetas = m_etiquetas) rfm = rfm.assign( R=r_cuartiles,F=f_cuartiles,M=m_cuartiles) # Construir segmento RFM y puntaje RFM def add_rfm(x) : return str(x['R']) + str(x['F']) + str(x[ 'M']) rfm['RFM_Segment'] = rfm.apply(add_rfm,axis=1 ) rfm['RFM_Score'] = rfm[['R','F','M']].sum(axis= 1) rfm.cabeza()

Uso de la puntuación RFM para agrupar a los clientes en los segmentos Oro, Plata y Bronce:

def segmentos(df): si df['RFM_Score'] > 9 : devuelve 'Oro' elif (df['RFM_Score'] > 5) y (df['RFM_Score'] <= 9 ): devuelve 'Silver' otra cosa: return 'Bronce' rfm['General_Segment'] = rfm.apply(segmentos,eje=1) rfm.groupby('General_Segment').agg({'Recency':'mean','Frequency':'mean', ' MonetaryValue':['media','recuento']}).ronda(1)

Luego viene el paso principal en el que fusionamos los segmentos RFM con el marco de datos principal para llevar a cabo nuestro análisis posterior. Los fusionamos sobre la base de CustomerId.

MergedRFM=pd.merge(df,rfm,on='ID de cliente') MergedRFM

Así que creamos 3 marcos de datos separados de acuerdo con los segmentos de Oro, Plata y Bronce para realizar un análisis de canasta de mercado adicional en cada uno de los marcos de datos.

Bronze_seg = MergedRFM[MergedRFM.General_Segment == 'Bronze'] Bronze_seg Silver_seg = MergedRFM[MergedRFM.General_Segment == 'Silver'] Silver_seg Gold_seg = MergedRFM[MergedRFM.General_Segment == 'Gold'] Gold_seg

Agrupación de medios K

El algoritmo de agrupación en clústeres K-Means es básicamente un algoritmo de aprendizaje automático no supervisado que se utiliza para clasificar el conjunto de datos disponible en varios clústeres. Identifica el número K de centroides y luego asigna cada punto de datos al grupo más cercano. Hay dos formas de medir la distancia entre los grupos. Se denominan Suma de cuadrados dentro de un grupo (WCSS) y Suma de cuadrados entre grupos (BCSS).

Los datos deben escalarse porque el algoritmo de agrupamiento de K-means utiliza la distancia, que es el factor de similitud. Escalar y normalizar los datos es un paso crítico en el preprocesamiento de los datos. La distribución de los valores de RFM está sesgada hacia la derecha en este proyecto. Por lo tanto, la estandarización y la normalización fueron necesarias. Los valores de RFM se escalan logarítmicamente primero y luego se normalizan. Se aplica una transformación de registro para cada valor de RFM y se usa la biblioteca StandardScaler() para la estandarización. A continuación, se utiliza el método del codo para averiguar el número correcto de clústeres que han llegado a ser 3. Los clústeres se denominan 0,1,2. Esto valida los segmentos RFM creados.

#Desinclinar los datos con la transformación de registro rfm_log = rfm[['Recency', 'Frequency', 'MonetaryValue']].apply(np.log, axis = 1).round(3) #or rfm_log = np.log(rfm_rfm ) # trazar la distribución de valores RFM f,ax = plt.subplots(figsize=(10, 12)) plt.subplot(3, 1, 1); sns.distplot(rfm_log.Recency, label = 'Recency') plt.subplot(3, 1, 2); sns.distplot(rfm_log.Frecuencia, etiqueta = 'Frecuencia') plt.subplot(3, 1, 3); sns.distplot(rfm_log.MonetaryValue, label = 'Valor monetario') plt.style.use('cinco y treinta y ocho') plt.tight_layout() plt.show()
#Normalizar las variables con StandardScaler de sklearn.preprocessing import StandardScaler scaler = StandardScaler() scaler.fit(rfm_log) #Almacenarlo por separado para agrupar rfm_normalized= scaler.transform(rfm_log)

Implementación de K-means para la segmentación de clientes

from sklearn.cluster import KMeans #Primero: obtener los mejores KMeans ks = range(1,8) inercias=[] for k in ks : # Crear un clúster de KMeans kc = KMeans(n_clusters=k,random_state=1) kc.fit (rfm_normalized) inertias.append(kc.inertia_) # Graficar ks vs inercias f, ax = plt.subplots(figsize=(15, 8)) plt.plot(ks, inercias, '-o') plt.xlabel(' Número de clústeres, k') plt.ylabel('Inertia') plt.xticks(ks) plt.style.use('ggplot') plt.title('¿Cuál es el mejor número para KMeans?') plt.show( )

Comparación del análisis de cuartiles (para RFM) con el agrupamiento de K-Means

Para la comparación de ambas técnicas de segmentación se hace uso de un gráfico de serpiente y un mapa de calor. El diagrama de serpiente es un diagrama de líneas que se usa mucho en el análisis de marketing y da la idea de la comparación de diferentes segmentos. Para que los diagramas de serpientes funcionen, los datos deben estar normalizados. Traza el valor normalizado promedio de cada atributo de cada grupo. Para un trazado efectivo, el marco de datos debe fusionarse de tal manera que las columnas métricas se dividan en dos columnas. Primero, el nombre de la métrica y segundo, el valor numérico actual.

Los mapas de calor son básicamente la representación gráfica de valores de datos utilizando un código de color. Los valores más altos se representan en colores oscuros y los valores más bajos en colores más claros. La variación entre los dos grupos se puede mostrar drásticamente con la ayuda de colores.

# agrupación en clústeres kc = KMeans(n_clusters= 3, random_state=1) kc.fit(rfm_normalized) #Cree una columna de etiqueta de clúster en el DataFrame original cluster_labels = kc.labels_ #Calcule los valores RFM promedio y el tamaño para cada clúster: rfm_rfm_k3 = rfm_rfm. asignar (K_Cluster = cluster_labels) #Calcular los valores y tamaños RFM promedio para cada clúster: rfm_rfm_k3.groupby('K_Cluster').agg({'Recency': 'mean','Frequency': 'mean', 'MonetaryValue': [ 'media', 'contar'],}).round(0)

rfm_normalizado = pd.DataFrame(rfm_normalizado,índice=rfm_rfm.índice,columnas=rfm_rfm.columnas)

rfm_normalized['K_Cluster'] = kc.etiquetas_

rfm_normalized['General_Segment'] = rfm['General_Segment']

rfm_normalized.reset_index(inplace = Verdadero)

#Fundir los datos en un formato largo para que los valores RFM y los nombres de las métricas se almacenen en 1 columna cada uno

rfm_melt = pd.melt(rfm_normalized,id_vars=['CustomerID','General_Segment','K_Cluster'],value_vars=['Recency', 'Frequency', 'MonetaryValue'],

var_name='Métrica',value_name='Valor')

rfm_melt.cabeza()

#Parcelas de serpientes y mapas de calor

f, (ax1, ax2) = plt.subplots(1,2, tamaño de figura=(15, 8))

sns.lineplot(x = 'Metric', y = 'Valor', hue = 'General_Segment', data = rfm_melt,ax=ax1)

# un diagrama de serpiente con K-Means

sns.lineplot(x = 'Métrica', y = 'Valor', tono = 'K_Cluster', datos = rfm_melt,ax=ax2)

plt.suptitle ("Gráfico de serpiente de RFM", tamaño de fuente = 24) #hacer título tamaño de fuente subtítulo

plt.show ()

# mapa de calor con RFM

f, (ax1, ax2) = plt.subplots(1,2, tamaño de figura=(15, 5))

sns.heatmap(data=relative_imp, annot=True, fmt='.2f', cmap='Blues',ax=ax1)

ax1.set(título = “Mapa de calor de K-Means”)

# un diagrama de serpiente con K-Means

sns.heatmap(prop_rfm, cmap= 'Naranjas', fmt= '.2f', annot = True,ax=ax2)

ax2.set(title = “Mapa de calor del cuantil RFM”)

plt.suptitle ("Mapa de calor de RFM", tamaño de fuente = 20) #hacer título tamaño de fuente subtítulo

plt.show ()


Análisis de la cesta de la compra utilizando el algoritmo a priori

Market Basket Analysis es un enfoque de minería de datos que se utiliza para descubrir los patrones de compra de los clientes y, a su vez, aumentar las ventas. Es un ejemplo de minería frecuente de conjuntos de elementos. Este proceso se lleva a cabo al encontrar asociaciones entre los diversos artículos que los clientes colocan en sus cestas o carritos de compras. Esto se conoce como minería de reglas de asociación y el algoritmo a priori es un algoritmo de regla de asociación de uso común en el análisis de canasta de mercado. También se considera muy preciso. Utiliza el concepto de apoyo, confianza y sustentación.

En este proyecto, se utilizó el algoritmo Apriori para encontrar los conjuntos de elementos frecuentes, pero se hizo por conglomerados, que se recibieron del análisis RFM. Así que había tres conjuntos de artículos frecuentes para tres segmentos de clientes diferentes, uno para Bronce, uno para Plata, uno para Oro. Además, para cada segmento, se calcularon conjuntos de elementos frecuentes para tres valores diferentes de apoyo mínimo, es decir, 0.01, 0.02, 0.03. Los resultados se discutirán en las próximas secciones.

Para averiguar los artículos famosos que se juntan, se creó una matriz de ID de cliente y el producto y se llama matriz de co-ocurrencia y encontrar los valores máximos nos diría qué artículos generalmente se compran juntos.

basket_bronze = (Bronze_seg.groupby(['FacturaNo', 'Descripción'])['Cantidad'] .sum().unstack().reset_index().fillna(0) .set_index('FacturaNo')) basket_bronze.head ()
def encode_units(x): si x <= 0: devuelve 0 si x >= 1: devuelve 1
basket_bronze_sets = basket_bronze.copy.applymap(encode_units) basket_bronze_sets.drop('POSTAGE', inplace=True, axis=1) basket_bronze_sets.head()
de mlxtend.frequent_patterns importar a priori de mlxtend.frequent_patterns importar Association_rules %matplotlib en línea frecuente_itemsets_bronze=apriori(basket_bronze_sets, min_support=0.03, use_colnames=True)
#Crear conjuntos de elementos frecuentes frecuentes_itemsets_bronze['longitud'] = frecuentes_itemsets_bronze['itemsets'].apply(lambda x: len(x)) frecuentes_itemsets_bronze rules_bronze = Association_rules(frequent_itemsets_bronze, metric="lift", min_threshold=1) rules_bronze

Matriz de co-ocurrencia

CID_PN_matrix = Bronze_seg.pivot_table(index = [“FacturaNo”], columnas = [“Descripción”],

                              valores = "Cantidad").fillna(0)
basket_bronze_set = CID_PN_matrix.applymap(encode_units) basket_bronze_set_int = basket_bronze_set.astype(int)
coocM_Bronce = basket_bronze_set_int.T.dot(basket_bronze_set_int)

Filtrado colaborativo basado en elementos

El filtrado colaborativo basado en elementos es un tipo de algoritmo basado en la similitud entre los elementos. Las similitudes se calculan utilizando la calificación que los usuarios han dado a los productos. Para este proyecto, la calificación es la cantidad. El filtrado colaborativo basado en artículos hace coincidir los artículos comprados y calificados de cada cliente con productos similares. Además, luego combina esos productos similares en una lista de recomendaciones.

En este proyecto se selecciona un producto (PORTALUCES CORAZÓN COLGANTE BLANCO) para comprobar qué clientes lo han comprado y su cantidad. Se calculó una matriz de correlación para el SOPORTE DE LUZ EN T CORAZÓN COLGANTE BLANCO para ver qué productos son similares y se encontró que hay muchos de ellos. Para resolver este problema y hacer que las cosas sean más específicas para el cliente, se elige un cliente y se verifican sus compras y se encuentra qué productos son los más cercanos a los que se compraron utilizando la matriz de correlación.

matrix_Bronze = Bronze_seg.pivot_table(index = [“FacturaNo”], columnas = [“Descripción”],

                              valores = "Cantidad") matrix_Bronze.head(10)
whiteHeart = matrix_Bronze["SOPORTE DE LUZ EN T CON CORAZÓN COLGANTE BLANCO"] whiteHeart.head()
ProductossimilaresW_Bronze = matrix_Bronze.corrwith(whiteHeart) ProductossimilaresW_Bronze = ProductossimilaresW_Bronze.dropna() df1 = pd.DataFrame(ProductossimilaresW_Bronze) df1.head(10)
corrMatrix_Bronze = matriz_Bronze.corr() corrMatrix_Bronze.head()
segundo_cliente_Bronce = matrix_Bronze.iloc[1].dropna() segundo_cliente_Bronce.head()
simProducts_Bronze = pd.Series() #Revise cada producto comprado por el segundo cliente para i en el rango (0, len(segundo_cliente_Bronze.index)): print("Agregando sims para " + segundo_cliente_Bronze.index[i] + "... .") #Recuperar productos similares a los comprados por el cliente 2 sims_Bronze = corrMatrix_Bronze[segundo_cliente_Bronze.index[i]].dropna() #Escalar a cuántos de los productos se compraron sims_Bronze = sims_Bronze.map(lambda x: x * second_customer_Bronze[i]) # Añadir a la lista de productos similares simProducts_Bronze = simProducts_Bronze.append(sims_Bronze) print("sorting...") simProducts_Bronze.sort_values(inplace = True, ascendente = True) print(simProducts_Bronze)

Rendimiento y comparación del modelo

El número total de patrones frecuentes y reglas de asociación para los tres segmentos (Oro, Plata, Bronce) con diferentes valores de soporte se muestran en las siguientes figuras y tablas respectivamente. Muchos patrones frecuentes se dejan de lado cuando se eleva el valor de soporte mínimo, ya que no logran satisfacer el valor de umbral. El algoritmo genera todos los patrones frecuentes para los tres segmentos y genera las reglas encontrando correlaciones entre conjuntos de elementos frecuentes con al menos un 70 % de confianza e identifica las reglas de asociación para ambos segmentos.

Nuestro análisis muestra que los valores de soporte disminuyen o se mueven hacia menos o igual a 0.01, a veces. A veces, el Algoritmo A priori no genera los patrones frecuentes. Esto se debe a que se involucra en un ciclo infinito. A medida que aumenta el soporte mínimo, disminuye el conjunto de elementos frecuentes generado.

Los siguientes gráficos muestran el número de reglas/recomendaciones con un nivel de soporte de 0.01 para los segmentos Gold, Silver y Bronze. Se realizó un procesamiento similar para los niveles de soporte mínimo de 0.02 y 0.03.

En el filtrado colaborativo basado en artículos, se utiliza una matriz de cantidad para encontrar similitudes entre artículos. Y en base a estas similitudes, se calcula la preferencia del consumidor por cualquier producto que no haya comprado. Los productos similares acumulados (recomendaciones) identificados para el segmento Oro son más en comparación con los segmentos Plata y Bronce.
Para generar reglas de asociación para conjuntos de datos tan pesados, todos los algoritmos tienen un tiempo de ejecución diferente debido a sus procesos de ejecución únicos. Según nuestro análisis, Apriori fue eficiente en términos de tiempo de ejecución. IBCF tomó mucho tiempo incluso con 8 GB de RAM y un procesador rápido.

Algoritmo Segmento Soporte mínimo Conjuntos de artículos frecuentes
Apriori Gold 0.01 NA
Silver 0.01 705
Bronce 0.01 253

Filtrado colaborativo basado en elementos mediante análisis RFM

Algoritmo Segmento Recomendaciones
IBCF Gold 4036
Silver 651
Bronce 789

En el filtrado colaborativo basado en artículos, se utiliza una matriz de cantidad para encontrar similitudes entre artículos. Y en base a estas similitudes, se calcula la preferencia del consumidor por cualquier producto que no haya comprado. Los productos similares acumulados (recomendaciones) identificados para el segmento Oro son más en comparación con los segmentos Plata y Bronce.

Comparación del algoritmo a priori y el tiempo de ejecución de IBCF wrt

Para generar reglas de asociación para conjuntos de datos tan pesados, todos los algoritmos tienen un tiempo de ejecución diferente debido a sus procesos de ejecución únicos. Según nuestro análisis, Apriori fue eficiente en términos de tiempo de ejecución. IBCF tomó mucho tiempo incluso con 8 GB de RAM y un procesador rápido.

Conclusión sobre el análisis RFM

En este proyecto, los valores del análisis RFM (Recency, Frequency, Monetary) se calcularon a partir de datos transaccionales y la segmentación de clientes se realizó con dos tipos de métodos, es decir, cuantiles RFM y el método de agrupamiento K-Means. Con la ayuda del análisis RFM, los clientes pueden dividirse en tres grupos, a saber, 'Oro', 'Plata', 'Bronce', siendo el Oro el grupo más rentable. Esto nos permite identificar en qué clientes debemos centrarnos y a quiénes se les deben ofrecer descuentos/ofertas o promociones especiales. Esto ayuda a construir relaciones con los clientes y se les hace sentir vistos y queridos. Podemos seleccionar el canal de marketing más óptimo para cada segmento y construir nuevas estrategias de marketing.

De acuerdo con esta investigación de Segmentación de Clientes, podemos decir que el algoritmo Apriori es el algoritmo más efectivo y eficiente en términos de identificación de patrones frecuentes, generación de reglas de asociación y tiempo de ejecución.

Este proyecto es diferente del resto de las soluciones de análisis de la cesta de la compra disponibles porque aquí, los clientes de los segmentos respectivos recibirán recomendaciones diferentes aunque se compre el mismo producto que activa la transacción. Por ejemplo, un cliente del segmento Gold puede comprar pan y se le recomendará un producto premium como un pastel ya que hemos analizado que este cliente es nuestro cliente reciente, frecuente y que paga mucho y, por otro lado, un cliente del segmento bronce. puede comprar pan y se le recomendará un producto menos premium como huevos o mantequilla.

Los medios que se muestran en este artículo no son propiedad de Analytics Vidhya y se utilizan a discreción del autor.

punto_img

Información más reciente

punto_img