Partimos primero definiendo los conceptos antes de jugar con el código.

¿Que es un modelo RFM?

Es una técnica para segmentar una carta de clientes analizando el historial de compras, la siglas hacen referencia a variables claves que definen un comportamiento de cliente, que son:

Recency (Recencia) : Tiempo en días de la ultima compra realizada del cliente.

Frequency (Frecuencia) : Nro de compras o tickers u Ordenes del cliente.

Monetary Value (Monto) : Importe total de las compras realizadas por el cliente.

¿Para que sirve un modelo RFM?

La utilidad son diversas como aumento de las conversiones, fidelización y retención de clientes, incremento de los ingresos.

¿Cómo segmentas a nuestra cartera de clientes?

Una vez que logramos tener la cartera de clientes con los datos, vamos dividir los datos en 4 grupos iguales para para obtener 64 segmentos diferentes, veamos un ejemplo

Recencia (R) Frecuencia (F) Monto (M) Quartile 1 (R=1) Quartile 1 (F=1) Quartile 1 (M=1) Quartile 2 (R=2) Quartile 2 (F=2) Quartile 2 (M=2) Quartile 3 (R=3) Quartile 3 (F=3) Quartile 3 (M=3) Quartile 4 (R=4) Quartile 4 (F=4) Quartile 4 (M=4)

La tabla debemos leerla de la siguiente manera:

Si el cliente se encuentra en el grupo de mayor Recencia = R1

Si el cliente se encuentra en el grupo de mayor Frecuenta = F1

Si el cliente se encuentra en el grupo de mayor Monto = M1

Entonces, podemos considerar que el cliente esta en el segmento de “Mejores Clientes” porque tiene un RFM = 111

Veamos una tabla descriptiva de los segmentos según el valor del RFM

Segmento RFM Descripción Marketing Mejores clientes 111 – Compra recientemente

– Regresa a menudo

– Compra por importes elevados – No reacionan a la variación de precios

– Valoran nuevos productos

– Ideales para los programas de fidelización Leales X1X – Regresa a menudo – Usar los valores R y M para futuras segmentaciones dependiendo del negocio Gastadores XX1 – Compra por importes elevados -Market your most expensive products Casi perdidos 311 – No tiene compras recientes

– Compra a menudo

– Compras por importes elevados -Reaccionan al incentivo de precios / promociones / ofertas Perdidos 411 – No tiene compras recientes

– Compra a menudo

– Compras por importes elevados -Reaccionan al incentivo de precios / promociones / ofertas Perdidos sin retorno 444 – No regresa desde hace mucho tiempo

– Compra poco

– Compra por importes bajos -No invertir mucho recuperarlos

Para el ejemplo, estaré trabajando con Python y como editor Jupyter, en realidad puedes usar el que mejor te acomode:

Importamos las librerías

import pandas as pd import warnings

Importamos nuestro maestro de clientes

En este punto, previamente he preparado la info en SQL, en mi caso manejo 324,576 mil registros por 8 columnas, la cantidad de columnas puede variar de acuerdo a la cantidad de columnas descriptivas quieras manejar para un mejor análisis.

El archivo debe tener mínimo los siguientes campos: Nombre Cliente | Días Ultima Compra | Cantidad de Ticket | Importe Compra

orders = pd.read_csv('clientes.csv',sep=',')

orders.head()

Nombre Cliente Días Ultima Compra Cantidad de Tickets Importe 0 Cliente A 11 59 51649.29625 1 Cliente B 207 71 22176.45321 2 Cliente C 31 21 16562.88967 3 Cliente D 11 57 15727.93637 4 Cliente E 32 47 11809.29653

Ahora vamos a copiar los datos en un otro dataframe y en mi caso voy a eliminar alumnas campos numericos que no deben entrar en el análisis.

Por otro lado, renombro los campos para una mejor denominación.

rfmTable = orders rfmTable = rfmTable . drop ( 'codigo_cliente' , 1 ) rfmTable . rename ( columns = { 'Días Ultima Compra ' : 'recency' , 'Cantidad de Tickets ' : 'frequency' , 'Importe' : 'monetary_value' }, inplace = True )

Pandas cuenta con un método para partir los datos en cuantiles según el valor porcentual indicado, para mi caso, en este punto es importante que analices tus datos para dar con los valores correcto, se recomienda partir los datos en 25% 50% y 85% en mi caso queda mejor así:

q1=0.25 q2=0.85 q3=0.95 quantiles = rfmTable.quantile(q=[q1,q2,q3])

miramos los resultados

quantiles

recency frequency monetary_value 0.25 136.0 1.0 82.457627 0.85 686.0 3.0 442.796609 0.95 863.0 6.0 944.561011

Enviamos los quantiles a un diccionario

quantiles = quantiles.to_dict() quantiles

{‘frequency’: {0.25: 1.0, 0.84999999999999998: 3.0, 0.94999999999999996: 6.0}

,’monetary_value’: {0.25: 82.457627000000002, 0.84999999999999998: 442.79660899999999,0.94999999999999996: 944.56101110000066},

‘recency’: {0.25: 136.0,0.84999999999999998: 686.0,0.94999999999999996: 863.0}}

Creamos un nuevo dataframe donde trabajemos los resultados finales

rfmSegmentation = rfmTable

Definimos 2 funciones para validar los resultados para formar el patrón RFM

def RClass(x,p,d): if x <= d[p][q1]: return 1 elif x <= d[p][q2]: return 2 elif x <= d[p][q3]: return 3 else: return 4 # Arguments (x = value, p = recency, monetary_value, frequency, k = quartiles dict) def FMClass(x,p,d): if x <= d[p][q1]: return 4 elif x <= d[p][q2]: return 3 elif x <= d[p][q3]: return 2 else: return 1

Ahora lo bueno, estas son las lineas donde hacemos la comparativo de cada variables y el quantil según el porcentaje definido

rfmSegmentation['R_Quartile'] = rfmSegmentation['recency'].apply(RClass, args=('recency',quantiles,)) rfmSegmentation['F_Quartile'] = rfmSegmentation['frequency'].apply(FMClass, args=('frequency',quantiles,)) rfmSegmentation['M_Quartile'] = rfmSegmentation['monetary_value'].apply(FMClass, args=('monetary_value',quantiles,))

Concatenamos las columnas para obtener el patrón RFM

rfmSegmentation['RFMClass'] = rfmSegmentation.R_Quartile.map(str) \ + rfmSegmentation.F_Quartile.map(str) \ + rfmSegmentation.M_Quartile.map(str)

Le damos un vistazo a los datos

rfmSegmentation.head()

Cliente Nombre recency frequency monetary_value R_Quartile F_Quartile M_Quartile RFMClass 0 CLIENTE A 11 59 51649.29625 1 1 1 111 1 CLIENTE B 207 71 22176.45321 2 1 1 211 2 CLIENTE C 31 21 16562.88967 1 1 1 111 3 CLIENTE D 11 57 15727.93637 1 1 1 111 4 CLIENTE E 32 47 11809.29653 1 1 1 111

Luego de ello por un tema de comodidad para trabajar los gráficos en Tableau o Power BI, agrego la descripción de la segmentación según la tabla lineas arriba.

rfmSegmentation.loc[rfmSegmentation.RFMClass == '111', 'RFMName']='Los Mejores' rfmSegmentation.loc[rfmSegmentation.RFMClass == '311', 'RFMName']='Casi perdido' rfmSegmentation.loc[rfmSegmentation.RFMClass == '411', 'RFMName']='Perdidos' rfmSegmentation.loc[rfmSegmentation.RFMClass == '444', 'RFMName']='Perdidos sin retorno' rfmSegmentation.loc[(rfmSegmentation.F_Quartile==1 ) & \ (rfmSegmentation.RFMClass != '111') & \ (rfmSegmentation.RFMClass != '311') & \ (rfmSegmentation.RFMClass != '411') & \ (rfmSegmentation.RFMClass != '444') , 'RFMName'] = 'Leales' rfmSegmentation.loc[(rfmSegmentation.M_Quartile==1 ) & \ (rfmSegmentation.RFMClass != '111') & \ (rfmSegmentation.RFMClass != '311') & \ (rfmSegmentation.RFMClass != '411') & \ (rfmSegmentation.RFMClass != '444') , 'RFMName'] = 'Gastadores' rfmSegmentation.loc[(rfmSegmentation.RFMClass != '111') & \ (rfmSegmentation.RFMClass != '311') & \ (rfmSegmentation.RFMClass != '411') & \ (rfmSegmentation.RFMClass != '444') & \ (rfmSegmentation.F_Quartile !=1 ) & \ (rfmSegmentation.M_Quartile !=1 ), 'RFMName'] = 'Otros'

Puedes darle un vistazo a la info, por ejemplo:

rfmSegmentation[rfmSegmentation['RFMClass']=='212'].head(5)

Finalmente exporto la info en el formato xlsx para comodidad de transportarlo e importarlo a un sistema de visualización

writer = pd.ExcelWriter('clientes_rfm.xlsx', engine='xlsxwriter') rfmSegmentation.to_excel(writer, sheet_name='Sheet1') writer.save()

Fuente: https://joaocorreia.io/blog/rfm-analysis-increase-sales-by-segmenting-your-customers.html