(Herramienta para estrategias de marketing personalizado en mejoramiento del hogar)
Eres el Director de Marketing de PROMART, la cadena líder en mejoramiento del hogar en Perú con más de 30,000 clientes activos. La gerencia general te ha solicitado:
“Desarrollar una estrategia de segmentación avanzada que permita identificar 3 grupos homogéneos de clientes para optimizar nuestras campañas de marketing, personalizar promociones y mejorar la experiencia de compra en tiendas físicas y online.”
(Clientes_promart.csv)
Se trabajará con una base de datos de 30,000 clientes con 12 variables clave:
Gasto_Anual_Total: Monto anual en soles gastado en PROMART (S/1,000 - S/15,000)
Frecuencia_Compras: Número de visitas/compras al año (1 a 20 veces)
Ticket_Promedio: Gasto promedio por visita (S/50 - S/500)
Antigüedad_Cliente: Años desde el primer registro (1 a 10 años)
Productos_Comprados: Número promedio de productos por compra (1 a 15 unidades)
Distancia_Tienda: Distancia en km a la tienda más cercana (1 a 20 km)
Satisfacción_Global: Evaluación del servicio (1=Muy insatisfecho a 5=Muy satisfecho)
Lealtad_Marca: Probabilidad de seguir comprando (1=Baja a 4=Alta)
Interés_Proyectos: Interés en proyectos de remodelación (1=Bajo a 3=Alto)
NPS: Probabilidad de recomendar PROMART (1=Nunca a 5=Definitivamente)
Tienda física
Online
Ambos
Hogar
Contratista
Empresa
Segmentación Automatizada:
Perfiles Accionables:
Caracterizar cada segmento con:
Comportamiento de compra.
Preferencias de canal.
Nivel de satisfacción/lealtad.
Visualización Interactiva:
Recomendaciones Estratégicas:
library(clustMD)
## Warning: package 'clustMD' was built under R version 4.4.3
##
##
## __ __ __ ________
## ______/ /_ ________ / /_ / \/ / __ \
## / ____/ / / / / ____// __// /\_/ / / / /
## / /___/ / /_/ /\___ // /__/ / / / /__/ /
## \____/_/\____//____//____/_/ /_/______/ version 1.2.1
##
##
library(dplyr)
## Warning: package 'dplyr' was built under R version 4.4.3
##
## Adjuntando el paquete: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(ggplot2)
## Warning: package 'ggplot2' was built under R version 4.4.3
clientes= read.csv("Clientes_promart.csv")
head(clientes)
## Gasto_Anual_Total Frecuencia_Compras Ticket_Promedio Antiguedad_Cliente
## 1 3313 2 209 1
## 2 7244 13 226 9
## 3 7602 13 299 6
## 4 3222 7 349 3
## 5 4571 5 62 7
## 6 5352 14 72 4
## Productos_Comprados Distancia_Tienda Satisfaccion_Global Lealtad_Marca
## 1 10 14 3 1
## 2 1 5 3 4
## 3 2 9 3 2
## 4 7 12 5 2
## 5 11 2 3 1
## 6 2 17 3 3
## Interes_Proyectos NPS Canal_Preferido Tipo_Cliente
## 1 2 1 Tienda Hogar
## 2 1 1 Tienda Hogar
## 3 2 1 Tienda Hogar
## 4 2 4 Online Hogar
## 5 2 1 Tienda Contratista
## 6 1 2 Tienda Hogar
datos_prep <- clientes %>%
mutate(
# Convertir nominales a numéricas (MANTENIENDO NOMBRES)
Canal_Preferido_num = as.numeric(factor(Canal_Preferido)),
Tipo_Cliente_num = as.numeric(factor(Tipo_Cliente))
) %>%
select(
# Variables cuantitativas (6)
Gasto_Anual_Total, Frecuencia_Compras, Ticket_Promedio,
Antiguedad_Cliente, Productos_Comprados, Distancia_Tienda,
# Variables ordinales (4)
Satisfaccion_Global, Lealtad_Marca, Interes_Proyectos, NPS,
# Variables nominales (conservando nombres)
Canal_Preferido_num, Tipo_Cliente_num
)
# Estandarizar solo variables cuantitativas (columnas 1-6)
datos_mat <- as.matrix(datos_prep)
datos_mat[, 1:6] <- scale(datos_mat[, 1:6])
# Verificar estructura
head(datos_mat)
## Gasto_Anual_Total Frecuencia_Compras Ticket_Promedio Antiguedad_Cliente
## [1,] -1.3419371 -1.4603454 -0.5141630 -1.5638776
## [2,] 0.6104308 0.4383441 -0.3838433 1.2185339
## [3,] 0.7882348 0.4383441 0.1757650 0.1751296
## [4,] -1.3871331 -0.5973047 0.5590584 -0.8682747
## [5,] -0.7171396 -0.9425210 -1.6410455 0.5229311
## [6,] -0.3292487 0.6109523 -1.5643868 -0.5204733
## Productos_Comprados Distancia_Tienda Satisfaccion_Global Lealtad_Marca
## [1,] 0.4699702 0.6041388 3 1
## [2,] -1.6143260 -0.9623404 3 4
## [3,] -1.3827375 -0.2661274 3 2
## [4,] -0.2247952 0.2560323 5 2
## [5,] 0.7015587 -1.4845001 3 1
## [6,] -1.3827375 1.1262985 3 3
## Interes_Proyectos NPS Canal_Preferido_num Tipo_Cliente_num
## [1,] 2 1 3 3
## [2,] 1 1 3 3
## [3,] 2 1 3 3
## [4,] 2 4 2 3
## [5,] 2 1 3 1
## [6,] 1 2 3 3
Conservación de nombres:
Creamos columnas nuevas (_num
) para
las nominales, manteniendo los nombres originales en el data
frame.
Usamos factor()
para preservar las
categorías al convertirlas a números.
Estandarización:
Solo aplicamos scale()
a las
variables cuantitativas (columnas 1-6).
Las ordinales (7-10) y nominales (11-12) quedan sin modificar.
# --- Paso 3.1: Ajuste del modelo ---
res <- clustMD(
X = datos_mat, # Matriz de datos
G = 3, # Número de clusters a probar
CnsIndx = 6, # 2 variables continuas (columnas 1-6)
OrdIndx = 10, # 2 variables ordinales (columnas 7-10)
Nnorms = 10000, # Número de simulaciones
MaxIter = 500, # Máximo de iteraciones
model = "EVI", # Modelo de covarianza (EVI = Volumen variable, forma variable, orientación fija)
store.params = FALSE, # No almacenar todos los parámetros intermedios
scale = TRUE, # Ya estandarizados
startCL = "kmeans", # Inicialización con k-means
autoStop = TRUE, # Detener si converge
ma.band = 30, # Parámetro de ajuste
stop.tol = 0.0001 # Tolerancia para convergencia
)
## | | | 0% | |======= | 10% | |======================================================================| 100%
# Asignar clusters
clientes$Segmento <- res$cl
library(reshape2)
## Warning: package 'reshape2' was built under R version 4.4.3
# Preparar datos para heatmap
heatmap_data <- clientes %>%
group_by(Segmento) %>%
summarise(
Gasto = mean(Gasto_Anual_Total),
Frecuencia = mean(Frecuencia_Compras),
Ticket = mean(Ticket_Promedio),
Satisfacción = mean(Satisfaccion_Global),
Online = mean(Canal_Preferido == "Online")*100
) %>%
melt(id.vars = "Segmento")
# Heatmap interactivo
ggplot(heatmap_data, aes(x = variable, y = factor(Segmento), fill = value)) +
geom_tile(color = "white") +
geom_text(aes(label = round(value, 1)), color = "black") +
scale_fill_gradient(low = "#f7fbff", high = "#08519c") +
labs(title = "Mapa de Calor: Comportamiento por Segmento",
x = "Métrica",
y = "Segmento") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
resumen <- clientes %>%
group_by(Segmento) %>%
summarise(
`Gasto Promedio (S/.)` = mean(Gasto_Anual_Total),
`Frecuencia` = mean(Frecuencia_Compras),
`% Online` = mean(Canal_Preferido == "Online")*100,
`Satisfacción` = mean(Satisfaccion_Global),
`NPS` = mean(NPS),
.groups = 'drop'
)
knitr::kable(resumen, digits = 1, caption = "Perfil Integrado de Segmentos")
Segmento | Gasto Promedio (S/.) | Frecuencia | % Online | Satisfacción | NPS |
---|---|---|---|---|---|
1 | 6041.4 | 10.4 | 20.1 | 3.1 | 3 |
2 | 5967.2 | 10.6 | 21.0 | 3.1 | 3 |
3 | 6034.7 | 10.4 | 20.4 | 3.1 | 3 |
Rango mínimo: S/5992.8 a S/6026.7 (diferencia de solo S/33.9)
Interpretación: Los clientes en los tres segmentos tienen prácticamente el mismo nivel de gasto
Todos los segmentos: Entre 10.4 y 10.5 visitas/compras
Implicación: Ningún grupo es más recurrente que otro
Mínima variación: 20.3% a 21.0%
Hallazgo: Comportamiento digital casi idéntico
Valores idénticos: 3.1 (Satisfacción) y 3 (NPS) en los tres segmentos
Problema: No se detectan diferencias en experiencia del cliente