Objetivo de la Clase:
Identificar grupos naturales de clientes con características similares
utilizando técnicas avanzadas de clustering para datos mixtos (variables
continuas, ordinales y nominales), con el fin de desarrollar estrategias
de marketing segmentadas.
Contexto:
Eres el gerente de marketing de “MarketTrend”, un retail que desea
mejorar sus campañas mediante segmentación avanzada. Dispones de datos
de 200 clientes con las siguientes variables:
Variable | Tipo | Descripción | Escala/Rango |
---|---|---|---|
Edad | Continua | Edad del cliente en años | 18-65 años |
Gasto_Mensual | Continua | Gasto promedio mensual en USD | $100-$900 |
Frecuencia | Ordinal | Frecuencia de compras | 1 (Baja), 2 (Media), 3 (Alta) |
Satisfacción | Ordinal | Nivel de satisfacción con el servicio | 1-5 (Likert: 1=Muy insatisfecho) |
Canal | Nominal | Canal de compra preferido | Tienda, Online, Ambos |
# Instalar paquete si es necesario
# install.packages("clustMD")
# Cargar librerías
library(clustMD) # Para análisis de conglomerados
## Warning: package 'clustMD' was built under R version 4.4.3
##
##
## __ __ __ ________
## ______/ /_ ________ / /_ / \/ / __ \
## / ____/ / / / / ____// __// /\_/ / / / /
## / /___/ / /_/ /\___ // /__/ / / / /__/ /
## \____/_/\____//____//____/_/ /_/______/ version 1.2.1
##
##
library(ggplot2) # Para visualización
## Warning: package 'ggplot2' was built under R version 4.4.3
library(dplyr) # Para manipulación de datos
## 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
📌 Explicación:
clustMD
permite realizar clustering
con datos mixtos (continuos, ordinales y nominales).
ggplot2
y
dplyr
ayudan en la visualización y
manipulación de datos.
Importar Base de datos “Segmentacion.csv”
# Importar base de datos
datos <- read.csv("Segmentacion.csv")
head(datos) # Ver primeras filas
## Edad Gasto_Mensual Frecuencia Satisfaccion Canal
## 1 28 238 2 5 2
## 2 39 765 2 2 1
## 3 26 143 2 3 2
## 4 44 586 1 3 1
## 5 38 653 2 5 2
## 6 33 405 1 5 3
str(datos) # Ver estructura de los datos
## 'data.frame': 300 obs. of 5 variables:
## $ Edad : int 28 39 26 44 38 33 43 39 31 37 ...
## $ Gasto_Mensual: int 238 765 143 586 653 405 567 566 656 573 ...
## $ Frecuencia : int 2 2 2 1 2 1 1 3 1 2 ...
## $ Satisfaccion : int 5 2 3 3 5 5 4 2 1 1 ...
## $ Canal : int 2 1 2 1 2 3 3 1 1 2 ...
📌 Explicación:
read.csv()
carga los datos desde un
archivo CSV.
head()
y
str()
permiten revisar la estructura y
tipos de variables.
# Convertir a matriz numérica (requerido por clustMD)
Y <- as.matrix(datos[, c(1, 2, 3, 4, 5)]) # Orden: Continuas → Ordinales → Nominales
# Estandarizar solo variables continuas (Edad y Gasto_Mensual)
Y[, 1:2] <- scale(Y[, 1:2])
# Asegurar que variables categóricas empiecen en 1 (si es necesario)
Y[, 3:5] <- Y[, 3:5] + 0 # En este caso ya están en 1, 2, 3...
📌 Explicación:
as.matrix()
convierte los datos a
formato numérico (necesario para
clustMD
).
scale()
estandariza las variables
continuas (media = 0, desviación estándar = 1).
res <- clustMD(
X = Y, # Matriz de datos
G = 3, # Número de clusters a probar
CnsIndx = 2, # 2 variables continuas (columnas 1-2)
OrdIndx = 4, # 2 variables ordinales (columnas 3-4)
Nnorms = 20000, # 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% | |============== | 20% | |======================================================================| 100%
📌 Explicación:
G = 3
indica que buscamos 3
segmentos de clientes.
CnsIndx = 2
y
OrdIndx = 4
definen cuáles columnas son
continuas y ordinales.
model = "EVI"
es un modelo flexible
que permite diferencias en forma y tamaño de clusters.
# Asignar clusters a los datos originales
datos$Segmento <- res$cl
# Ver distribución de segmentos
table(datos$Segmento)
##
## 1 2 3
## 91 104 105
# Perfiles promedio por segmento
aggregate(. ~ Segmento, data = datos, mean)
## Segmento Edad Gasto_Mensual Frecuencia Satisfaccion Canal
## 1 1 47.02198 524.0549 1.967033 3.296703 1.725275
## 2 2 34.05769 473.5192 2.211538 3.269231 2.240385
## 3 3 27.40952 494.2286 1.609524 2.676190 1.847619
Edad: 27.3 años (el más joven)
Gasto: $497.78 (medio-alto)
Frecuencia de compra: Baja-media (1.6)
Satisfacción: Neutral (2.69)
Canal: Combinado (1.85 ≈ Tienda + Online)
🔍 Insights:
Son jóvenes con gasto considerable pero compran con poca frecuencia.
Su satisfacción es la más baja, lo que sugiere oportunidades de mejora.
Prefieren una combinación de canales (omnichannel).
📌 Estrategia recomendada:
Campañas de retención con descuentos por compras recurrentes.
Mejorar experiencia de compra (satisfacción baja).
Promociones en redes sociales (canal mixto).
Edad: 33.9 años (adultos jóvenes)
Gasto: $471.53 (medio)
Frecuencia de compra: Media-alta (2.21)
Satisfacción: Alta (3.27)
Canal: Prefiere Online (2.24)
🔍 Insights:
Clientes satisfechos que compran con frecuencia.
Claramente orientados al comercio electrónico.
📌 Estrategia recomendada:
Programas de fidelización (puntos por compras online).
Email marketing con recomendaciones personalizadas.
Ofertas exclusivas para compradores frecuentes.
Edad: 47.0 años (el mayor)
Gasto: $522.25 (el más alto)
Frecuencia de compra: Media (1.97)
Satisfacción: Alta (3.27)
Canal: Prefiere Tienda (1.72)
🔍 Insights:
Gasto más alto pero frecuencia de compra media.
Prefieren la tienda física, aunque están satisfechos.
📌 Estrategia recomendada:
Servicio personalizado en tienda.
Promociones para aumentar frecuencia de compra.
Programas de beneficios exclusivos (por su alto gasto).
# Gráfico de dispersión (Edad vs. Gasto por Segmento)
ggplot(datos, aes(x = Edad, y = Gasto_Mensual, color = factor(Segmento))) +
geom_point(size = 3, alpha = 0.7) +
labs(
title = "Segmentación de Clientes por Edad y Gasto Mensual",
x = "Edad",
y = "Gasto Mensual (USD)",
color = "Segmento"
) +
theme_minimal() +
scale_color_brewer(palette = "Set1")
📌 Interpretación del gráfico:
Segmento 1 (Azul): Clientes jóvenes con gasto medio.
Segmento 2 (Rojo): Clientes mayores con alto gasto.
Segmento 3 (Verde): Clientes muy jóvenes con bajo gasto.
Segmento 1 (Jóvenes, Gasto Medio):
Campañas digitales (redes sociales, influencers).
Descuentos por frecuencia de compra.
Segmento 2 (Mayores, Alto Gasto):
Programas de lealtad (beneficios exclusivos).
Atención personalizada en tienda.
Segmento 3 (Muy Jóvenes, Bajo Gasto):
Ofertas de entrada (primeras compras con descuento).
Promociones en productos básicos.
# Boxplot de Gasto Mensual por Segmento
ggplot(datos, aes(x = factor(Segmento), y = Gasto_Mensual, fill = factor(Segmento))) +
geom_boxplot() +
labs(title = "Distribución de Gasto Mensual por Segmento") +
theme_minimal()