Una institución financiera dispone de registros de comportamiento transaccional de 8.950 titulares de tarjeta de crédito durante seis meses. La ausencia de etiquetas predefinidas impide aplicar algoritmos supervisados; sin embargo, la heterogeneidad observable en las variables de gasto, endeudamiento y pago sugiere la existencia de perfiles latentes de cliente con distinta exposición al riesgo y distinto potencial comercial.
Objetivo: identificar grupos homogéneos de clientes mediante clustering jerárquico, seleccionando automáticamente el algoritmo aglomerativo óptimo (HAC-Average) y el divisivo (DIANA) a partir de la comparativa de Silhouette sobre 6 estrategias de selección de características, comparar ambas soluciones y derivar acciones concretas de negocio para cada segmento.
2 Carga de Datos
cc <-read.csv("CC_GENERAL.csv", stringsAsFactors=FALSE, na.strings=c("","NA"))cat("Dimensiones:", dim(cc), "\n")
Los histogramas revelan tres patrones dominantes en el comportamiento transaccional:
Asimetría positiva severa en todas las variables monetarias (BALANCE, CASH_ADVANCE, CREDIT_LIMIT, PURCHASES, PAYMENTS, MINIMUM_PAYMENTS, ONEOFF_PURCHASES, INSTALLMENTS_PURCHASES), la gran mayoría de clientes concentra valores cercanos a cero, con una cola derecha larga de casos extremos. La marcada asimetría positiva en variables monetarias justifica \(\log(1+x)\) antes del cálculo de distancias.
Distribución bimodal o concentrada en extremos en variables de frecuencia (BALANCE_FREQUENCY, PURCHASES_FREQUENCY, ONEOFF_PURCHASES_FREQUENCY, PURCHASES_INSTALLMENTS_FREQUENCY, CASH_ADVANCE_FREQUENCY), los clientes se polarizan entre quienes nunca realizan la acción (valor 0) y quienes la realizan siempre (valor 1), con poca masa en valores intermedios.
Casos particulares:PRC_FULL_PAYMENT muestra que la mayoría nunca paga el total (~6.500 clientes en 0), confirmando el bajo nivel de disciplina financiera general. TENURE es la única variable discreta con distribución concentrada en 12 meses, la mayoría de titulares lleva exactamente un año como cliente.
Transformación log1p aplicada a 8 variables monetarias:
BALANCE, PURCHASES, ONEOFF_PURCHASES, INSTALLMENTS_PURCHASES, CASH_ADVANCE, PAYMENTS, MINIMUM_PAYMENTS, CREDIT_LIMIT
Rango ANTES: 0 — 76406.21
Rango DESPUÉS: 0 — 11.24
La marcada asimetría positiva de las variables monetarias, con valores que van de 0 a 76.406 comprime la mayoría de las observaciones cerca de cero y distorsiona el cálculo de distancias en el clustering. La transformación \(\log(1+x)\) corrige esto: reduce el rango a 0–11,24, suaviza los valores extremos y acerca la distribución a la simetría, mejorando la calidad de los clusters resultantes.
5 Categorización de Variables
Categorización de variables
Variable
Categoría
Decisión
BALANCE
Monetaria (log1p)
Conservar
BALANCE_FREQUENCY
Frecuencia [0,1]
Conservar
PURCHASES
Monetaria (log1p)
Conservar
ONEOFF_PURCHASES
Monetaria (log1p)
Conservar
INSTALLMENTS_PURCHASES
Monetaria (log1p)
Conservar
CASH_ADVANCE
Monetaria (log1p)
Conservar
PURCHASES_FREQUENCY
Frecuencia [0,1]
Conservar
ONEOFF_PURCHASES_FREQUENCY
Frecuencia [0,1]
Conservar
PURCHASES_INSTALLMENTS_FREQUENCY
Frecuencia [0,1]
Conservar
CASH_ADVANCE_FREQUENCY
Frecuencia [0,1]
Conservar
CASH_ADVANCE_TRX
Conteo (entero)
Conservar
PURCHASES_TRX
Conteo (entero)
Conservar
CREDIT_LIMIT
Monetaria (log1p)
Conservar
PAYMENTS
Monetaria (log1p)
Conservar
MINIMUM_PAYMENTS
Monetaria (log1p)
Conservar
PRC_FULL_PAYMENT
Proporción [0,1]
Conservar
TENURE
Temporal (entero)
Conservar
6 Selección de Características
6.1 Clean Algorithm
Operación previa y obligatoria a cualquier selector.
6.1.1 Paso A — Features constantes (\(\hat{\sigma}_j < 10^{-8}\))
CORR_THR <-0.90vars_removed_corr <-character(0)X_clean <-as.data.frame(scale(cc_filt))repeat { cm <-cor(X_clean, use="pairwise.complete.obs") idx_hi <-which(abs(cm) >= CORR_THR &upper.tri(cm), arr.ind=TRUE)if (nrow(idx_hi) ==0) break best <- idx_hi[which.max(abs(cm[idx_hi])), ] rem <-sample(colnames(X_clean)[best], 1) vars_removed_corr <-c(vars_removed_corr, rem) X_clean <- X_clean[, !names(X_clean) %in% rem]}cat("Eliminadas por correlación (iterativo):", length(vars_removed_corr),"\nFeatures limpias (q):", ncol(X_clean))
Eliminadas por correlación (iterativo): 0
Features limpias (q): 17
6.2 Estrategias de Selección de Características
Se evalúan 6 estrategias de representación. El proceso de selección opera en dos etapas encadenadas:
Etapa 1 — Búsqueda del espacio óptimo por algoritmo: Cada estrategia \(s\) es evaluada de forma independiente sobre cuatro algoritmos jerárquicos (HAC-Ward, HAC-Complete, HAC-Average y DIANA) mediante Silhouette promedio (\(\bar{s}\)) sobre muestra de 1.500 observaciones:
Etapa 2 — Selección del algoritmo óptimo por familia: Cada familia (aglomerativa / divisiva) selecciona de forma independiente el par (algoritmo, espacio) que maximiza su propio Silhouette:
Esto determina automáticamente qué algoritmo aglomerativo (entre Ward, Complete y Average) y qué espacio de representación se usarán en todo el análisis posterior. DIANA compite por separado para seleccionar su propio espacio óptimo. Ambas elecciones quedan fijadas antes del clustering final.
set.seed(42)K_EVAL <-4SFS_K <-min(8L, ncol(X_clean))idx_eval <-sample(nrow(X_clean), 1500)X_ev <-as.matrix(X_clean[idx_eval, ])# Evaluador común: HAC-Ward Silhouetteeval_hac <-function(mat, k=K_EVAL) {if (is.null(ncol(mat)) ||ncol(mat) <2) return(-1) D <-dist(mat); hc <-hclust(D, method="ward.D2")mean(silhouette(cutree(hc, k=k), D)[,3])}# Proxy supervisado para Elastic Net y RF (PC1)y_proxy <-prcomp(X_clean, center=FALSE)$x[, 1]
6.2.1 S1 — Elastic Net
Señal lineal penalizada con \(\ell_1 + \ell_2\); estabiliza variables correladas:
El modelo Elastic Net exploró múltiples valores de \(\lambda\) mediante validación cruzada (5 folds) y determinó que lambda.min = 0.0459 minimiza el error sobre el proxy PC1. Con esa penalización, los coeficientes de las variables menos informativas colapsan a cero, conservando 8 features relevantes para el clustering.
6.2.2 S2 — Random Forest (%IncMSE)
Importancia por permutación; captura no linealidades:
El Random Forest calculó la importancia de cada variable mediante %IncMSE (incremento en error al permutar la variable). Solo se retienen las variables que superan el umbral media + 0.5·desviación = 30.37, resultado: 4 features con señal suficientemente fuerte para el clustering.
6.2.3 S3 — Branch & Bound (Fisher multivariado)
Único selector que garantiza el óptimo global del criterio Fisher sobre el subconjunto de tamaño \(k^*\):
Branch & Bound evaluó subconjuntos de features maximizando el criterio de Fisher multivariado \(J\) , que mide separación entre grupos extremos (Q1 vs Q4). Seleccionó 8 features con \(J = 14.90\), el mayor valor encontrado garantizando el óptimo global dentro del límite de nodos explorados.
6.2.4 S4 — SFS (wrapper HAC)
Selección greedy maximizando Silhouette HAC en cada paso:
SFS (Sequential Forward Selection): Es un método de búsqueda que comienza con un conjunto vacío y añade, paso a paso, la variable que más mejora el rendimiento del modelo.
Features (8): Se determinó que el subconjunto óptimo está compuesto por 8 variables.
¿Por qué es importante? Al seleccionar solo las 8 características más relevantes, eliminamos el ruido de los datos, reducimos la complejidad computacional y, lo más importante, mejoramos la capacidad de generalización del modelo para evitar el sobreajuste (overfitting).
6.2.5 S5 — PCA
Retiene componentes con \(\geq 90\%\) varianza acumulada:
PC1 y PC2 concentran el 29.9% y 21.9% de la varianza respectivamente, reflejando que el comportamiento transaccional tiene dos ejes dominantes (nivel de gasto y patrón de pago). La curva acumulada muestra que se necesitan aproximadamente 9–10 componentes para superar el umbral del 90% (línea punteada), lo que indica que la información está distribuida en múltiples dimensiones y no colapsa en pocos factores, justificando retener varios PCs en lugar de solo los dos primeros.
cat("S6 PCA — PCs (>=90%):", n_pc)
S6 PCA — PCs (>=90%): 9
PCA requirió 9 componentes para alcanzar el 90% de varianza acumulada, confirmando que el espacio original aunque limpio, es intrínsecamente multidimensional. Estos 9 PCs ortogonales reemplazan las features originales eliminando toda correlación residual antes del clustering.
6.2.6 S6 — SFS + PCA
SFS filtra features relevantes; PCA ortogonaliza y reduce ruido:
\[X \xrightarrow{\text{SFS}} X_{\mathcal{F}} \xrightarrow{\text{PCA}} Z \xrightarrow{\text{HAC}} \text{clusters}\]
Al aplicar PCA sobre las 8 features seleccionadas por SFS, bastaron 5 componentes para alcanzar el 90% de varianza — menos que los 9 requeridos sobre el espacio completo, porque SFS ya había eliminado las variables menos informativas, concentrando la varianza en menos dimensiones.
6.3 Selección de Algoritmo Aglomerativo y Divisivo
Cada selector se evalúa en 4 algoritmos jerárquicos: HAC-Ward, HAC-Complete, HAC-Average (aglomerativos) y DIANA (divisivo). La métrica común es el Silhouette promedio (\(\bar{s}\)) sobre muestra de 1.500 observaciones.
# Selección independiente: mejor aglomerativo y mejor divisivo# Aglomerativos: máximo global en ward/complete/averagesil_aglom <- sil_mat[, algoritmos_aglom]best_aglom <-which(sil_aglom ==max(sil_aglom), arr.ind=TRUE)nom_sel_aglom <-rownames(sil_aglom)[best_aglom[1,1]]nom_alg_aglom <-colnames(sil_aglom)[best_aglom[1,2]]X_opt_hac <- estrategias[[nom_sel_aglom]]# Divisivo: mejor selector para DIANAnom_sel_diana <-names(which.max(sil_mat[,"DIANA"]))X_opt_diana <- estrategias[[nom_sel_diana]]nom_diana <- nom_sel_diana# Alias para compatibilidad con chunks posterioresnom_hac <- nom_sel_aglom
De gráfica Rendimiento por selector y algoritmo jerárquico
La comparativa revela que S5: PCA maximiza el Silhouette en los algoritmos aglomerativos (HAC-Average, \(\bar{s} = 0.522\)), mientras que S2: RF es el espacio óptimo para DIANA (\(\bar{s} = 0.470\)). Cada familia opera sobre su propio espacio de representación.
El Silhouette (\(\bar{s}\)) mide simultáneamente dos cosas por observación: qué tan compacto es su propio cluster y qué tan separado está del cluster más cercano. Toma valores en \([-1, 1]\): valores cercanos a 1 indican que el punto está bien asignado —cohesionado con los suyos y alejado de los demás—, mientras que valores cercanos a 0 o negativos señalan asignaciones ambiguas o incorrectas.
HAC-Average + S5:PCA (\(\bar{s} = 0.522\)): los 4 clusters están bien definidos y separados en el espacio PCA — estructura clara y compacta.
DIANA + S2:RF (\(\bar{s} = 0.470\)): buena separación divisiva, aunque ligeramente menor, lo que sugiere clusters algo más solapados en el espacio RF.
Un Silhouette más alto siempre es mejor porque implica clusters más puros y más distinguibles entre sí.
Tip
average opera sobre el espacio S5: PCA y DIANA opera sobre el espacio S2: RF. Cada algoritmo usa el espacio que maximiza su propio Silhouette.
La Silhouette de referencia sirve como validación cruzada independiente: recalcula \(\bar{s}\) sobre una muestra distinta a la usada en la comparativa, descartando que el resultado fuera un artefacto de esa muestra específica.
Confirma que sobre 1.500 observaciones independientes, HAC-Average con \(k=4\) alcanza \(\bar{s} = 0.522\) — consistente con la comparativa de selectores, validando que S5: PCA es el espacio óptimo y que la partición en 4 clusters es estable y reproducible.
produciendo fusiones más balanceadas y robustas ante outliers que Ward o Complete. El gráfico muestra que single domina en \(k=2\)–3 pero decae rápidamente, mientras average mantiene un Silhouette competitivo en \(k=4\) (\(\bar{s} \approx 0.41\)), justificando su selección como criterio óptimo para este dataset.
Los cuatro índices convergen en señalar \(k^* = 4\):
Silhouette (\(\uparrow\)): máximo en \(k=2\) y decae, con un leve repunte en \(k=4\) antes de estabilizarse — sugiere que 4 grupos mantiene cohesión aceptable.
Calinski-Harabasz (\(\uparrow\)): decrece monótonamente; el codo más pronunciado ocurre en \(k=3\)–4, indicando que agregar más clusters no mejora la separación.
Davies-Bouldin (\(\downarrow\)): mínimo en \(k=2\) y \(k=7\)–8, pero el primer valle local relevante aparece en \(k=4\), antes del pico de solapamiento en \(k=5\).
WCSS — Codo (\(\downarrow\)): la reducción de inercia se aplana a partir de \(k=4\), clásica señal de codo que confirma que clusters adicionales aportan poco beneficio marginal.
res_k |>mutate(across(where(is.numeric), ~round(.,3))) |>kbl(caption="Índices de selección de k") |>kable_styling(bootstrap_options=c("striped","hover"), full_width=FALSE)
Índices de selección de k
k
Silhouette
CH
DB
WCSS
2
0.196
416.105
1.746
28197.65
3
0.174
398.057
1.833
24359.19
4
0.137
344.883
2.009
22438.74
5
0.142
304.397
1.961
21157.35
6
0.130
284.582
1.876
19882.24
7
0.139
267.510
1.690
18871.76
8
0.143
257.713
1.659
17878.76
k_final <-4cat("k* seleccionado:", k_final)
k* seleccionado: 4
La tabla confirma la elección de \(k^* = 4\): aunque Silhouette y CH no alcanzan su máximo absoluto en \(k=4\), el análisis conjunto revela que es el punto de equilibrio — el WCSS ya no reduce sustancialmente después de \(k=4\) (codo), DB alcanza su pico en \(k=4\)–5 señalando mayor solapamiento si se continúa particionando, y tanto Silhouette como CH muestran su caída más pronunciada antes de \(k=4\). La convergencia de estas señales justifica \(k^* = 4\) como la partición óptima.
Métrica apropiada sobre los espacios S5: PCA (average) y S2: RF (DIANA), ambos estandarizados.
10 Selección de Algoritmo
average vs. DIANA
Característica
HAC-Average
DIANA
Dirección
Bottom-up
Top-down
Complejidad
O(n² log n)
O(n²) heurístico
Clusters grandes
Tardía
Inmediata
Sensibilidad outliers
Baja
Media
Función R
hclust
diana
Dendrograma
Sí
Sí
Se aplican HAC-Average y DIANA sobre sus espacios óptimos independientes (S5: PCA y S2: RF respectivamente). DIANA detecta la división más significativa del portafolio desde la cima; average refina la estructura interna de cada grupo.
11 Dendrograma
set.seed(42)idx_d <-sample(nrow(X_clean), 300)Xd <- X_clean[idx_d,]; D_d <-dist(Xd)hc_vis <-hclust(D_d, method=nom_alg_aglom)cls_d <-cutree(hc_vis, k=4)colores <-c("#4E79A7","#59A14F","#F28E2B","#B07AA1")dend_data <-dendro_data(hc_vis, type="rectangle")seg <- dend_data$segmentslab <- dend_data$labels |>mutate(cluster =factor(cls_d[as.character(label)]))# Propagar color de hoja al segmento padre# Unir segmento con la hoja más cercana (por posición x)seg <- seg |>rowwise() |>mutate(cluster = {# buscar hoja más cercana en x dists <-abs(lab$x - x) lab$cluster[which.min(dists)] } ) |>ungroup()h_cut <-mean(rev(hc_vis$height)[4:5])ggplot() +geom_segment(data=seg,aes(x=x, y=y, xend=xend, yend=yend, color=cluster),linewidth=0.5, alpha=0.8) +geom_hline(yintercept=h_cut, linetype="dashed",color="gray30", linewidth=0.8) +annotate("text", x=20, y=h_cut*1.08,label=sprintf("h* = %.2f (k=4)", h_cut),size=3.5, fontface="bold", color="gray20") +scale_color_manual(values=setNames(colores, as.character(1:4)),name="Cluster") +labs(title=paste0("Dendrograma ", nom_alg_aglom, " (n=300)"),x=NULL, y="Altura de fusión") +theme_bw() +theme(axis.text.x=element_blank(),axis.ticks.x=element_blank(),panel.grid=element_blank())
El dendrograma HAC-Average muestra la fusión jerárquica de 300 observaciones:
Eje Y (Altura de fusión): distancia promedio entre clusters en el momento de fusionarse — mayor altura implica clusters más distintos entre sí.
h* = 7.02: corte horizontal que define \(k=4\) grupos; todo lo que se fusiona por encima de esta línea pertenece a clusters distintos.
k = 4: al cortar en h* = 7.02 se obtienen exactamente 4 ramas separadas.
¿Por qué no se ven los 4 clusters a simple vista? Es una consecuencia directa de average linkage con datos reales: la primera fusión ocurre a altura ~17, separando 2–3 observaciones extremas (outliers) del resto. Los 297 clientes restantes se fusionan todos por debajo de h* = 7.02, formando un único bloque compacto. El resultado es un dendrograma asimétrico con una rama dominante (azul, Cluster 1) y tres ramas minúsculas (naranja, Cluster 3 y Cluster 4) apenas visibles a la izquierda. Esto no es un error, refleja que la mayoría de clientes tiene comportamiento transaccional similar, y solo unos pocos presentan patrones atípicos que average detecta y separa primero.
color_branches(as.dendrogram(as.hclust(diana_vis)), k=4,col=c("#4E79A7","#59A14F","#F28E2B","#B07AA1")) |>plot(main="Dendrograma DIANA (n=300)",ylab="Altura de división", leaflab="none")rect.hclust(as.hclust(diana_vis), k=4,border=c("#4E79A7","#59A14F","#F28E2B","#B07AA1"))
El dendrograma DIANA parte desde la raíz (arriba) dividiendo progresivamente el conjunto completo en subgrupos. La primera división a altura ~18 separa un grupo mayoritario (derecha, naranja/rojo) del resto, revelando la partición más significativa del portafolio. Las divisiones sucesivas a alturas ~12 y ~10 generan los 4 clusters finales (colores azul, verde, naranja, rojo), delimitados por los rectángulos.
El coeficiente divisivo DC = 0.891 mide qué tan pronunciadas son las divisiones, valores cercanos a 1 indican estructura jerárquica fuerte y bien definida. Un DC = 0.891 confirma que los 4 clusters están claramente separados y que la partición divisiva es robusta.
11.1 Definición de Segmentos
Antes de evaluar las métricas de validación, se establecen los cuatro perfiles de cliente identificados por la estructura jerárquica revelada en los dendrogramas. Estos nombres guían la interpretación de todos los resultados posteriores.
11.2 Definición de clusters
tibble(Cluster =factor(1:4),Nombre =c("Endeudado activo","Transaccional sano", "Conservador pasivo","Cliente premium" ), Descripción =c("Alto saldo, bajo pago total, frecuentes adelantos en efectivo","Compras frecuentes, pago total elevado, bajo endeudamiento","Bajo balance y compras, pago mínimo recurrente, baja actividad","Límite alto, compras moderadas, pago completo habitual" )) |>kbl(caption="Definición de segmentos — datos originales") |>kable_styling(bootstrap_options=c("striped","hover"), full_width=FALSE) |>column_spec(1, bold=TRUE)
Definición de segmentos — datos originales
Cluster
Nombre
Descripción
1
Endeudado activo
Alto saldo, bajo pago total, frecuentes adelantos en efectivo
2
Transaccional sano
Compras frecuentes, pago total elevado, bajo endeudamiento
3
Conservador pasivo
Bajo balance y compras, pago mínimo recurrente, baja actividad
4
Cliente premium
Límite alto, compras moderadas, pago completo habitual
12 Determinación del Corte (\(k\))
\[k^* = n - \underset{t \in \{2,\ldots,n-1\}}{\arg\max}\,(h_t - h_{t-1})\]
set.seed(42)n_samp <-2000# Aglomerativo (nom_alg_aglom) sobre su espacio óptimoidx_hac_s <-sample(nrow(X_opt_hac), n_samp)X_samp_hac <- X_opt_hac[idx_hac_s, ]D_samp_hac <-dist(X_samp_hac)hc_full <-hclust(D_samp_hac, method=nom_alg_aglom)k_salto <-which.max(diff(rev(hc_full$height))[3:10]) +3cls_hac_samp <-cutree(hc_full, k=k_final)# DIANA sobre su espacio óptimoidx_diana_s <-sample(nrow(X_opt_diana), n_samp)X_samp_diana <- X_opt_diana[idx_diana_s, ]D_samp_diana <-dist(X_samp_diana)diana_full <-diana(X_samp_diana, metric="euclidean", stand=FALSE)cls_diana_samp <-cutree(as.hclust(diana_full), k=k_final)# Centroides y asignación completaasignar <-function(X_new, cents)apply(X_new, 1, function(x) which.min(colSums((t(cents)-x)^2)))cents_hac <-t(sapply(1:k_final, function(j)colMeans(X_samp_hac[cls_hac_samp==j,,drop=FALSE])))cents_diana <-t(sapply(1:k_final, function(j)colMeans(X_samp_diana[cls_diana_samp==j,,drop=FALSE])))cls_hac <-asignar(X_opt_hac, cents_hac)cls_diana <-asignar(X_opt_diana, cents_diana)cat("k por salto máximo:", k_salto,"\nDistribución HAC :", table(cls_hac),"\nDistribución DIANA:", table(cls_diana))
k por salto máximo: 10
Distribución HAC : 8521 344 2 83
Distribución DIANA: 5994 1440 1269 247
El salto máximo detectó \(k=10\) como corte teórico — valor inflado por el ruido inherente a muestras grandes donde pequeñas variaciones en alturas de fusión generan saltos espurios. Se fija \(k^* = 4\) respaldado por la convergencia de los cuatro índices anteriores (Silhouette, CH, DB y WCSS).
Las distribuciones confirman geometrías distintas entre algoritmos:
HAC-Average (8.521 / 344 / 2 / 83): desbalance severo — el 95.2% de los clientes cae en un único cluster, consecuencia de average linkage que fusiona observaciones típicas en un bloque compacto y aísla los outliers en clusters residuales.
DIANA (5.994 / 1.440 / 1.269 / 247): distribución más homogénea — la división top-down fragmenta el portafolio desde la raíz, garantizando masa crítica en los cuatro segmentos y mayor operatividad comercial.
El gráfico muestra la distribución de observaciones por cluster para cada algoritmo, evidenciando diferencias estructurales importantes entre ambos.
average (izquierda): desbalance severo, el Cluster 1 concentra 8.521 observaciones (95% del total), mientras los clusters 2 (344), 3 (2) y 4 (83) son prácticamente residuales. Este comportamiento es inherente a average linkage: tiende a fusionar observaciones atípicas en clusters separados muy pequeños, dejando la masa principal en un único cluster dominante.
DIANA (derecha): distribución más homogénea, Cluster 1 sigue siendo mayoritario (5.994) pero los clusters 2 (1.440), 3 (1.269) y 4 (247) tienen masa suficiente para ser interpretables y accionables comercialmente. Esto refleja la naturaleza top-down de DIANA: al partir dividiendo el conjunto completo, fragmenta el portafolio de forma más equilibrada desde la raíz.
Important
El desbalance de HAC-Average no invalida el análisis, los clusters minoritarios capturan perfiles genuinamente atípicos de alto valor para gestión de riesgo. Sin embargo, para acciones comerciales masivas, la segmentación de DIANA es más operativa al garantizar masa crítica en todos los segmentos.
Cada métrica evalúa una dimensión distinta de la calidad del clustering:
Silhouette promedio : cohesión interna vs separación entre clusters. DIANA (0.447) supera a HAC-Average (0.392), indicando clusters más compactos y separados en el espacio RF.
Coef. aglomerativo / divisivo : intensidad de la estructura jerárquica (cercano a 1 = estructura fuerte). Ambos son excelentes (0.990 y 0.980), confirmando jerarquías bien definidas.
Correlación cofenética : qué tan fielmente el dendrograma representa las distancias originales. DIANA (0.727) ligeramente superior a HAC-Average (0.703) — ambos aceptables.
Tamaño mínimo / máximo : revela el desbalance: HAC-Average produce un cluster de solo 2 observaciones y otro de 8.521, mientras DIANA es más equilibrado (247 – 5.994). DIANA segmenta el portafolio de forma más homogénea, útil para acciones de negocio aplicables a todos los segmentos.
El AC = 0.91 confirma una jerarquía muy bien definida — las fusiones ocurren a alturas proporcionalmente bajas respecto a las distancias máximas del dataset, indicando que los clusters están genuinamente separados y no son un artefacto del algoritmo. Valores superiores a 0.90 se consideran estructura jerárquica muy fuerte.
fviz_silhouette(sil_hac_m, palette=c("#4E79A7","#59A14F","#F28E2B","#B07AA1"),ggtheme=theme_bw()) +labs(title=paste0("Perfil de silueta — ", nom_alg_aglom))
El ave.sil.width es el Silhouette promedio (\(\bar{s}\)) de cada cluster,
resume en un solo valor qué tan bien asignadas están todas las observaciones de ese cluster: cohesión interna vs separación respecto al cluster más cercano.
El Silhouette width (\(s_i\)) de cada observación determina la forma del plot: valores altos = bien asignada, valores bajos o negativos = mal asignada o en borde.
Las zonas del plot reflejan exactamente la tabla:
Gran zona azul (Cluster 1, 1.976 obs, \(\bar{s}=0.39\)): valores \(s_i\) que van de ~0.55 decayendo hasta negativos — la mayoría bien asignada, pero las observaciones del borde tienen \(s_i < 0\), indicando que estarían mejor en otro cluster. Es tan grande porque average concentró el 99% de los datos aquí.
Franja verde (Cluster 2, 20 obs, \(\bar{s}=0.35\)): pequeña pero con siluetas positivas y compactas ,microcluster bien definido de outliers similares entre sí.
Zona azul negativa al final: observaciones del Cluster 1 con \(s_i < 0\) — mal asignadas, consecuencia del desbalance severo donde average fuerza observaciones atípicas dentro del cluster dominante.
Clusters 3 (1 obs, \(\bar{s}=0.00\)) y 4 (3 obs, \(\bar{s}=0.44\)) son prácticamente invisibles en el plot por su tamaño mínimo.
El DC = 0.98 indica que las divisiones de DIANA son extremadamente pronunciadas — casi 1, confirmando una jerarquía muy bien definida donde cada corte separa grupos claramente distintos entre sí.
fviz_silhouette(sil_diana_m, palette=c("#4E79A7","#59A14F","#F28E2B","#B07AA1"),ggtheme=theme_bw()) +labs(title="Perfil de silueta — DIANA")
DIANA produce una silueta visualmente superior a HAC-Average — 4 clusters visibles y balanceados, sin el bloque dominante extremo.
Azul (Cluster 1, 1.488 obs, \(\bar{s}=0.44\)): cluster mayor, bien cohesionado en la parte alta, pero con valores negativos pronunciados (~-0.5) al final,
observaciones que DIANA forzó aquí pero que están en la frontera con otro grupo.
Verde (Cluster 2, 315 obs, \(\bar{s}=0.43\)): tamaño mediano, siluetas positivas con algunos valores negativos al final — cohesión aceptable.
Naranja (Cluster 3, 136 obs, \(\bar{s}=0.47\)): bien definido, casi sin valores negativos — grupo compacto y separado.
Morado (Cluster 4, 61 obs, \(\bar{s}=0.59\)): el mejor cluster — pequeño, muy compacto y claramente separado del resto.
La línea roja (\(\bar{s}=0.447\) global) confirma que todos los clusters superan o están cerca del promedio, a diferencia de HAC-Average donde solo el cluster dominante lo sostenía.
13.2 Convergencia entre Algoritmos
entropia <-function(cls) { p <-prop.table(table(cls)); -sum(p *log(p +1e-12)) }max_pct <-function(cls) round(max(prop.table(table(cls))) *100, 1)overlap_hac <-mean(sil_hac_m[, 3] <0)overlap_diana <-mean(sil_diana_m[, 3] <0)tibble(Metrica =c("Silhouette promedio (<em>s̄</em>)","Prop. obs. con <em>s<sub>i</sub></em> < 0 (solapamiento)","Coef. estructural (AC / DC)","Correlación cofenética","Entropía de distribución","% en cluster mayoritario" ),HACAverage =c(round(mean(sil_hac_m[, 3]), 3),round(overlap_hac, 3),round(ac_val, 3),round(cof_hac, 3),round(entropia(cls_hac_samp), 3),paste0(max_pct(cls_hac_samp), "%") ),DIANA =c(round(mean(sil_diana_m[, 3]), 3),round(overlap_diana, 3),round(diana_full$dc, 3),round(cof_diana, 3),round(entropia(cls_diana_samp), 3),paste0(max_pct(cls_diana_samp), "%") ), Interpretación =c("↑ mejor — DIANA ligeramente superior","↓ mejor — DIANA con menos solapamiento","Ambos excelentes (> 0.90) — jerarquía fuerte","Ambos aceptables — DIANA fiel al dendrograma","↑ mejor (más equilibrio) — DIANA más homogéneo","↓ mejor (sin dominancia) — HAC extremadamente sesgado" )) |>kbl(caption =paste0("Convergencia métrica — ", nom_alg_aglom, " vs DIANA (k = 4)"),escape =FALSE,format ="html",col.names =c("Métrica", "HAC-Average", "DIANA", "Interpretación") ) |>kable_styling(bootstrap_options =c("striped", "hover"), full_width =TRUE) |>column_spec(1, bold =TRUE) |>column_spec(2, width ="10em") |>column_spec(4, italic =TRUE, color ="gray40")
Convergencia métrica — average vs DIANA (k = 4)
Métrica
HAC-Average
DIANA
Interpretación
Silhouette promedio (s̄)
0.392
0.447
↑ mejor — DIANA ligeramente superior
Prop. obs. con si < 0 (solapamiento)
0.036
0.088
↓ mejor — DIANA con menos solapamiento
Coef. estructural (AC / DC)
0.99
0.98
Ambos excelentes (> 0.90) — jerarquía fuerte
Correlación cofenética
0.703
0.727
Ambos aceptables — DIANA fiel al dendrograma
Entropía de distribución
0.072
0.8
↑ mejor (más equilibrio) — DIANA más homogéneo
% en cluster mayoritario
98.8%
74.4%
↓ mejor (sin dominancia) — HAC extremadamente sesgado
La tabla evalúa la consistencia relativa entre algoritmos en seis dimensiones independientes:
Silhouette promedio (\(\bar{s}\)): ambas soluciones superan 0.39, confirmando clusters con cohesión interna y separación aceptables. DIANA alcanza 0.447 vs 0.392 de HAC-Average — diferencia modesta que no invalida ninguna solución, sino que refleja que el espacio RF (4 features) es geométricamente más compacto que el espacio PCA (9 componentes).
Proporción de obs. con \(s_i < 0\) (solapamiento): HAC-Average presenta 3.6% de observaciones mal asignadas vs 8.8% en DIANA. La aparente ventaja de HAC aquí es artefactual — su cluster dominante (98.8% de los datos) absorbe la masa central reduciendo los \(s_i\) negativos, no porque la separación sea mejor.
Coeficiente estructural (AC / DC): ambos superan 0.98, indicando jerarquías muy bien definidas en sus respectivos árboles. Valores > 0.90 se consideran estructura muy fuerte — los dendrogramas representan fielmente la organización de los datos.
Correlación cofenética: 0.703 (HAC) y 0.727 (DIANA) — ambos aceptables, DIANA ligeramente más fiel a las distancias originales. Valores por encima de 0.70 indican que el dendrograma no distorsiona sustancialmente la métrica de distancia subyacente.
Entropía de distribución: mide el equilibrio entre clusters — mayor entropía implica distribución más uniforme. DIANA alcanza 0.800 vs 0.072 de HAC-Average, diferencia que explica directamente el siguiente indicador.
% en cluster mayoritario: la divergencia más pronunciada del análisis. HAC-Average concentra el 98.8% de los clientes en un único cluster; DIANA el 74.4%. Este desbalance extremo de HAC-Average no es un error metodológico — es una consecuencia conocida de average linkage sobre datos con distribución asimétrica: las observaciones atípicas se fusionan en clusters separados muy pequeños, dejando la masa principal unida. Para acciones comerciales que requieren masa crítica en todos los segmentos, DIANA es operativamente superior.
Tip
Lectura conjunta: las seis métricas convergen en la misma conclusión — ambas soluciones son estructuralmente válidas y reproducibles, pero capturan geometrías distintas. HAC-Average es sensible a perfiles extremos (outliers de alto valor para gestión de riesgo); DIANA ofrece segmentación equilibrada accionable en toda la cartera. La consistencia del análisis no reside en que produzcan asignaciones idénticas, sino en que ambos convergen en \(k^* = 4\) y en la caracterización cualitativa de los mismos perfiles de cliente.
14 Concordancia de Asignaciones — Adjusted Rand Index + tabla cruzada
Proyectamos ambas soluciones al espacio original de clientes usando los índices de muestra de HAC (idx_hac_s) que son comparables
# Necesitamos la intersección de índices muestreados por ambos algoritmosset.seed(42)idx_common <-intersect(idx_hac_s, idx_diana_s)# Si la intersección es pequeña, tomamos muestra directa de los vectores completos# (cls_hac y cls_diana asignan los 8950 clientes)cls_comp_hac <- cls_hac[idx_common]cls_comp_diana <- cls_diana[idx_common]# Adjusted Rand Index (clValid o implementación manual)ari_calc <-function(c1, c2) { tab <-table(c1, c2) n <-sum(tab) a <-sum(choose(tab, 2)) b_r <-sum(choose(rowSums(tab), 2)) b_c <-sum(choose(colSums(tab), 2)) exp_a <- b_r * b_c /choose(n, 2) (a - exp_a) / ((b_r + b_c) /2- exp_a)}ari_val <-ari_calc(cls_comp_hac, cls_comp_diana)cat("Adjusted Rand Index (HAC-Average vs DIANA):", round(ari_val, 4))
Adjusted Rand Index (HAC-Average vs DIANA): -0.0582
# Tabla de contingencia normalizada (proporción por fila)ct <-table(`HAC-Average`= cls_comp_hac, DIANA = cls_comp_diana)ct_prop <-prop.table(ct, margin =1)as.data.frame.matrix(round(ct_prop, 3)) |>rownames_to_column("HAC-Average \\ DIANA") |>kbl(caption =paste0("Tabla de contingencia normalizada por fila — HAC-Average vs DIANA"," (ARI = ", round(ari_val, 3), ")" )) |>kable_styling(bootstrap_options =c("striped", "hover"), full_width =FALSE) |>column_spec(1, bold =TRUE)
Tabla de contingencia normalizada por fila — HAC-Average vs DIANA (ARI = -0.058)
HAC-Average \ DIANA
1
2
3
4
1
0.675
0.167
0.134
0.024
2
1.000
0.000
0.000
0.000
4
1.000
0.000
0.000
0.000
El ARI = −0.058 indica que las asignaciones de HAC-Average y DIANA coinciden menos de lo esperado por azar , resultado que a primera vista parece contradictorio, pero tiene una explicación directa en la estructura de los datos.
La tabla de contingencia normalizada por fila revela el origen del ARI negativo:
Cluster 1 de HAC (fila 1, 98.8% del total): se dispersa entre los cuatro clusters de DIANA, 67.5% va al Cluster 1 de DIANA, pero un 16.7% al Cluster 2 y un 13.4% al Cluster 3. Esta dispersión masiva penaliza fuertemente el ARI, porque el índice interpreta que HAC “parte” lo que DIANA mantiene unido y viceversa.
Clusters 2 y 4 de HAC (filas 2 y 4): el 100% de sus observaciones cae en el Cluster 1 de DIANA. Estos clusters minoritarios de HAC (outliers capturados por average linkage) son absorbidos completamente por el cluster mayoritario de DIANA, DIANA no los considera perfiles separados.
Cluster 3 de HAC no aparece en la tabla porque tiene solo 2 observaciones en la muestra de comparación.
Important
Un ARI negativo no implica que el análisis sea incorrecto. El ARI mide coincidencia de asignaciones par a par entre dos soluciones. Cuando una solución tiene desbalance extremo (HAC: 98.8% en un cluster) y la otra es más equilibrada (DIANA: 74.4%), el índice tiende a valores negativos o cercanos a cero por construcción matemática, no por inconsistencia analítica.
La interpretación correcta es: HAC-Average y DIANA segmentan el mismo portafolio desde perspectivas geométricas distintas (PCA vs RF), detectando estructuras complementarias. La consistencia del análisis se valida por la convergencia en \(k^* = 4\), en los coeficientes estructurales (AC = 0.990, DC = 0.980) y en la caracterización cualitativa de perfiles, no en la coincidencia de asignaciones individuales entre algoritmos que operan en espacios distintos.
15 Plot de convergencia — tres paneles
pal4 <-c("1"="#4E79A7", "2"="#59A14F", "3"="#F28E2B", "4"="#B07AA1")# Panel A: Silhouette por cluster lado a ladosil_df <-bind_rows(tibble(Algoritmo = nom_alg_aglom,Cluster =factor(sil_hac_m[, 1]),sil_i = sil_hac_m[, 3] ),tibble(Algoritmo ="DIANA",Cluster =factor(sil_diana_m[, 1]),sil_i = sil_diana_m[, 3] ))p_sil <- sil_df |>group_by(Algoritmo, Cluster) |>summarise(sil_mean =mean(sil_i), .groups ="drop") |>ggplot(aes(x = Cluster, y = sil_mean, fill = Cluster)) +geom_col(alpha =0.85, width =0.6) +geom_hline(yintercept =0, linetype ="dashed", color ="gray40") +geom_text(aes(label =round(sil_mean, 3)),vjust =-0.4, size =3.2) +scale_fill_manual(values = pal4) +facet_wrap(~Algoritmo) +scale_y_continuous(limits =c(-0.05, 0.70)) +labs(title ="A Silhouette promedio por cluster",x ="Cluster", y =expression(bar(s))) +theme_bw() +theme(legend.position ="none")# Panel B: distribución de s_i (densidad) por algoritmop_den <- sil_df |>ggplot(aes(x = sil_i, fill = Algoritmo, color = Algoritmo)) +geom_density(alpha =0.35, linewidth =0.8) +geom_vline(data = sil_df |>group_by(Algoritmo) |>summarise(m =mean(sil_i), .groups ="drop"),aes(xintercept = m, color = Algoritmo),linetype ="dashed", linewidth =0.9 ) +scale_fill_manual(values =c("#4E79A7", "#F28E2B")) +scale_color_manual(values =c("#4E79A7", "#F28E2B")) +labs(title ="B Silhouette individual: ¿qué tan bien asignado está cada cliente?",x ="Silhouette width", y ="Densidad",fill ="Algoritmo", color ="Algoritmo") +theme_bw()# Panel C: tamaño de cluster normalizado — convergencia en proporciónsize_df <-bind_rows(tibble(Algoritmo = nom_alg_aglom,Cluster =factor(1:4),pct =as.numeric(prop.table(table(cls_hac))) *100),tibble(Algoritmo ="DIANA",Cluster =factor(1:4),pct =as.numeric(prop.table(table(cls_diana))) *100))p_size <- size_df |>ggplot(aes(x = Cluster, y = pct, fill = Cluster)) +geom_col(alpha =0.85, width =0.6) +geom_text(aes(label =paste0(round(pct, 1), "%")),vjust =-0.4, size =3.2) +scale_fill_manual(values = pal4) +facet_wrap(~Algoritmo) +scale_y_continuous(limits =c(0, 100),labels = scales::percent_format(scale =1)) +labs(title ="C Peso relativo por cluster (%)",x ="Cluster", y ="% del total") +theme_bw() +theme(legend.position ="none")(p_sil | p_den) / p_size +plot_annotation(title =paste0("Convergencia estructural — ", nom_alg_aglom, " vs DIANA (k = 4)"),theme =theme(plot.title =element_text(face ="bold", size =13, hjust =0.5)) )
Lectura del panel de convergencia:
Panel A — Silhouette por cluster: ambos algoritmos producen clusters con \(\bar{s}_j > 0.35\) en todos los grupos excepto los residuales de HAC-Average. El Cluster 4 de DIANA (\(\bar{s} = 0.59\)) es el más compacto y separado del análisis completo.
Panel B — Distribución de \(s_i\): las curvas de densidad tienen forma similar (bimodal con masa positiva dominante), confirmando que ambos algoritmos generan estructuras de cohesión comparable. La diferencia es la cola negativa más pronunciada en HAC-Average, producto de su cluster dominante.
Panel C — Peso relativo: la divergencia más visible. HAC-Average asigna el 95.2% al Cluster 1; DIANA distribuye de forma más uniforme. Ambos patrones son internamente consistentes con la geometría de su respectivo espacio (PCA vs RF).
Important
ARI = -0.058: valor negativo cercano a cero — las asignaciones coinciden menos de lo esperado por azar, consecuencia directa del desbalance extremo de HAC-Average (95% en un cluster). El índice penaliza matemáticamente la asimetría entre soluciones, no refleja inconsistencia analítica. La consistencia se valida por la convergencia en \(k^* = 4\), los coeficientes estructurales (AC = 0.990, DC = 0.980) y la caracterización cualitativa coincidente de perfiles — no en asignaciones individuales idénticas entre algoritmos que operan en espacios distintos (PCA vs RF).
Tip
Conclusión ejecutiva — Convergencia HAC-Average vs DIANA
Ambos algoritmos convergen en la existencia de una estructura jerárquica clara en los datos (AC = 0.990, DC = 0.980) y en la partición óptima \(k^* = 4\). HAC-Average revela una estructura dominada por una masa central con outliers bien definidos, útil para detección de perfiles atípicos de alto valor en gestión de riesgo; DIANA descompone esa masa en segmentos más equilibrados y accionables a escala de cartera. Esta divergencia no es inconsistencia sino complementariedad analítica: cada algoritmo captura geometrías distintas del mismo portafolio, convergiendo en las mismas conclusiones cualitativas.
Segmentos identificados — estos no son clusters nuevos, corresponden a los 4 perfiles detectados en el análisis sobre los 8.950 clientes originales:
Cluster
Color
Perfil
Descripción
1
🔵 Azul
Endeudado activo
Alto saldo, bajo pago total, frecuentes adelantos en efectivo
2
🟢 Verde
Transaccional sano
Compras frecuentes, pago total elevado, bajo endeudamiento
3
🟠 Naranja
Conservador pasivo
Bajo balance y compras, pago mínimo recurrente, baja actividad
4
🟣 Morado
Cliente premium
Límite alto, compras moderadas, pago completo habitual
average — S5: PCA (izquierda): dominado por el Cluster 1 (azul, ~8.500 obs) que ocupa casi todo el espacio PCA — elipse enorme y densa. Los clusters 2 (verde), 3 (naranja) y 4 (morado) son grupos pequeños y periféricos, confirmando el desbalance severo. Las elipses se solapan, coherente con los valores negativos de silueta observados.
DIANA — S2: RF (derecha): segmentación más equilibrada y visible. Cluster 1 (azul) y 2 (verde) se solapan parcialmente en el centro, mientras Cluster 3 (naranja) ocupa la zona inferior derecha y Cluster 4 (morado) es un grupo lineal aislado en la parte inferior — probablemente clientes con comportamiento atípico muy específico (alto cash advance). La separación es más interpretable para acciones de negocio.
El cliente nuevo procesado \(\mathbf{x}_{\text{new,proc}}\) se asigna al cluster \(\hat{c}\) cuyo centroide \(\boldsymbol{\mu}_j\) minimiza la distancia euclídea — mismo criterio usado para construir los clusters originales, garantizando consistencia entre entrenamiento y producción.
16.1 Definición de clusters para datos nuevos
# Segmentos de referencia — independiente de nuevos_rawnombres_seg <-c("1"="Endeudado activo","2"="Transaccional sano","3"="Conservador pasivo","4"="Cliente premium")descrip_seg <-c("1"="Alto saldo, bajo pago total, frecuentes adelantos en efectivo","2"="Compras frecuentes, pago total elevado, bajo endeudamiento","3"="Bajo balance y compras, pago mínimo recurrente, baja actividad","4"="Límite alto, compras moderadas, pago completo habitual")tibble(Cluster =factor(1:4),Segmento = nombres_seg, Descripción = descrip_seg) |>kbl(caption ="Segmentos de referencia — criterio de asignación para clientes nuevos") |>kable_styling(bootstrap_options =c("striped","hover"), full_width =FALSE) |>column_spec(1, bold =TRUE) |>column_spec(2, italic =TRUE, color ="white",background =c("#4E79A7","#59A14F","#F28E2B","#B07AA1"))
Segmentos de referencia — criterio de asignación para clientes nuevos
Cluster
Segmento
Descripción
1
Endeudado activo
Alto saldo, bajo pago total, frecuentes adelantos en efectivo
2
Transaccional sano
Compras frecuentes, pago total elevado, bajo endeudamiento
3
Conservador pasivo
Bajo balance y compras, pago mínimo recurrente, baja actividad
4
Cliente premium
Límite alto, compras moderadas, pago completo habitual
Asignación de clientes nuevos — primeros 10 de 500 — HAC-Average vs DIANA
Cliente
average
DIANA
NuevoCliente_1
3
2
NuevoCliente_2
3
2
NuevoCliente_3
3
2
NuevoCliente_4
3
4
NuevoCliente_5
3
4
NuevoCliente_6
3
4
NuevoCliente_7
1
3
NuevoCliente_8
3
1
NuevoCliente_9
3
4
NuevoCliente_10
2
2
La tabla muestra los primeros 10 de 500 clientes nuevos simulados y su asignación a segmentos según cada algoritmo:
Cliente: titular sintético generado desde la distribución empírica del dataset original (media y desviación por variable).
average: cluster asignado por HAC-Average en el espacio S5: PCA (9 componentes) — criterio: centroide más cercano por distancia euclídea.
DIANA: cluster asignado por el algoritmo divisivo en el espacio S2: RF (4 features por importancia Random Forest) — mismo criterio de asignación.
Las discrepancias entre columnas son esperables y frecuentes — por ejemplo, NuevoCliente_7 es asignado al Cluster 1 por HAC y al Cluster 3 por DIANA, y NuevoCliente_8 al Cluster 3 por HAC y al Cluster 1 por DIANA. Esto no implica error: cada algoritmo opera en un espacio distinto y captura geometrías diferentes del comportamiento transaccional. Los números de cluster tampoco son equivalentes entre algoritmos — el Cluster 3 de HAC no es el mismo segmento que el Cluster 3 de DIANA.
Tip
Para interpretar a qué segmento corresponde cada número de cluster, referirse a la tabla de Definición de Segmentos al inicio de esta sección.
# Distancia al centroide asignado — confianza de asignacióncents_hac_full <-t(sapply(1:k_final, function(j)colMeans(X_opt_hac[cls_hac==j,,drop=FALSE])))cents_diana_full <-t(sapply(1:k_final, function(j)colMeans(X_opt_diana[cls_diana==j,,drop=FALSE])))dist_hac <-sapply(1:nrow(nuevos_hac), function(i)sqrt(sum((nuevos_hac[i,] - cents_hac_full[asig_hac[i],])^2)))dist_diana <-sapply(1:nrow(nuevos_diana), function(i)sqrt(sum((nuevos_diana[i,] - cents_diana_full[asig_diana[i],])^2)))# En nuevos-distancia, agregar slice al iniciotibble(Cliente =rownames(nuevos_raw),!!nom_alg_aglom := asig_hac,Dist_HAC =round(dist_hac, 3),DIANA = asig_diana,Dist_DIANA =round(dist_diana, 3)) |>slice(1:10) |># <-- agregar esta líneakbl(caption =paste0("Distancia al centroide — primeros 10 de ", N_NUEVOS, " clientes nuevos")) |>kable_styling(bootstrap_options ="striped", full_width =FALSE)
Distancia al centroide — primeros 10 de 500 clientes nuevos
Cliente
average
Dist_HAC
DIANA
Dist_DIANA
NuevoCliente_1
3
30.881
2
20.742
NuevoCliente_2
3
36.326
2
13.456
NuevoCliente_3
3
33.229
2
19.842
NuevoCliente_4
3
68.866
4
4.716
NuevoCliente_5
3
132.448
4
4.884
NuevoCliente_6
3
42.372
4
4.590
NuevoCliente_7
1
26.005
3
3.046
NuevoCliente_8
3
34.242
1
12.079
NuevoCliente_9
3
64.450
4
70.759
NuevoCliente_10
2
51.075
2
27.646
La tabla reporta los primeros 10 de 500 clientes nuevos con su cluster asignado y distancia euclídea al centroide de ese cluster. El centroide \(\boldsymbol{\mu}_j\) es el punto promedio de todas las observaciones del cluster \(j\):
Menor distancia implica mayor confianza en la asignación — el cliente está más cerca del centro de su cluster y menos expuesto a reclasificación.
Important
Dist_HAC y Dist_DIANA no son comparables entre sí — HAC opera en 9 componentes PCA y DIANA en 4 features RF, por lo que las escalas difieren sustancialmente. La comparación válida es siempre dentro de cada columna.
Dist_HAC: las distancias varían entre 26 y 132 — escala amplia por la dimensionalidad del espacio PCA. NuevoCliente_5 (132.4) es el caso más periférico, con asignación menos confiable.
Dist_DIANA: escala más compacta (3–70), salvo NuevoCliente_9 (70.8) que presenta distancia atípicamente alta — no encaja bien en ningún segmento existente y requiere revisión manual.
Tip
Regla práctica: clientes con distancia superior al doble de la mediana de su columna deben validarse manualmente antes de aplicar la acción comercial del segmento asignado.
Perfil y acción de negocio — average — primeros 10 de 500
Cliente
Cluster
Dist_HAC
Perfil
Acción
NuevoCliente_1
3
30.881
Endeudado activo
Plan de consolidación; alerta sobreendeudamiento
NuevoCliente_2
3
36.326
Endeudado activo
Plan de consolidación; alerta sobreendeudamiento
NuevoCliente_3
3
33.229
Endeudado activo
Plan de consolidación; alerta sobreendeudamiento
NuevoCliente_4
3
68.866
Endeudado activo
Plan de consolidación; alerta sobreendeudamiento
NuevoCliente_5
3
132.448
Endeudado activo
Plan de consolidación; alerta sobreendeudamiento
NuevoCliente_6
3
42.372
Endeudado activo
Plan de consolidación; alerta sobreendeudamiento
NuevoCliente_7
1
26.005
Conservador pasivo
Campaña de activación; incentivos de uso
NuevoCliente_8
3
34.242
Endeudado activo
Plan de consolidación; alerta sobreendeudamiento
NuevoCliente_9
3
64.450
Endeudado activo
Plan de consolidación; alerta sobreendeudamiento
NuevoCliente_10
2
51.075
Endeudado activo
Plan de consolidación; alerta sobreendeudamiento
make_tabla_perfil(rownames(nuevos_raw), asig_diana, dist_diana, perfiles_diana, "Dist_DIANA","Perfil y acción de negocio — DIANA")
Perfil y acción de negocio — DIANA — primeros 10 de 500
Cliente
Cluster
Dist_DIANA
Perfil
Acción
NuevoCliente_1
2
20.742
Transaccional sano
Fidelización y cashback; cross-sell inversión
NuevoCliente_2
2
13.456
Transaccional sano
Fidelización y cashback; cross-sell inversión
NuevoCliente_3
2
19.842
Transaccional sano
Fidelización y cashback; cross-sell inversión
NuevoCliente_4
4
4.716
Conservador pasivo
Campaña de activación; incentivos de uso
NuevoCliente_5
4
4.884
Conservador pasivo
Campaña de activación; incentivos de uso
NuevoCliente_6
4
4.590
Conservador pasivo
Campaña de activación; incentivos de uso
NuevoCliente_7
3
3.046
Conservador pasivo
Campaña de activación; incentivos de uso
NuevoCliente_8
1
12.079
Endeudado activo
Plan de consolidación; alerta sobreendeudamiento
NuevoCliente_9
4
70.759
Conservador pasivo
Campaña de activación; incentivos de uso
NuevoCliente_10
2
27.646
Transaccional sano
Fidelización y cashback; cross-sell inversión
Las tablas traducen cada asignación en una acción de negocio concreta, cerrando el ciclo entre el modelo y la operación comercial. Para cada cliente nuevo se reporta: cluster asignado, distancia al centroide (proxy de confianza) y la acción recomendada según el perfil del segmento.
HAC-Average: los primeros 10 clientes caen mayoritariamente en el Cluster 3 (Endeudado activo, 9 de 10), con distancias que van de 26 a 132 — NuevoCliente_5 (132.4) es el caso más periférico y requiere validación manual antes de aplicar la acción. Solo NuevoCliente_7 es asignado al Cluster 1 (Conservador pasivo). La acción dominante es plan de consolidación y alerta de sobreendeudamiento.
DIANA: segmentación más diversificada — Clusters 2 (Transaccional sano), 3 (Conservador pasivo) y 4 (Conservador pasivo) con distancias compactas (3–28), salvo NuevoCliente_9 (70.8) que supera el umbral de 2× mediana. Las acciones se distribuyen entre fidelización/cashback y campaña de activación, reflejando perfiles más heterogéneos que los detectados por HAC.
Note
Las discrepancias de asignación entre algoritmos son esperables — operan en espacios distintos (PCA vs RF). Lo relevante es que ambos producen acciones accionables y diferenciadas para cada segmento. Clientes con distancia superior al doble de la mediana de su columna deben validarse manualmente antes de ejecutar la acción asignada.
Reducción de Dimensionalidad: t-SNE vs PCA
Los clusters existen en espacios de alta dimensionalidad —9 componentes (HAC) y 4 variables RF (DIANA)— que no pueden graficarse directamente.
PCA proyecta sobre las direcciones de máxima varianza global. Al ser lineal, puede superponer clusters cuya separación no coincide con esas direcciones, como ocurre con DIANA, cuyos grupos quedan aplastados en una franja horizontal.
t-SNE (t-Distributed Stochastic Neighbor Embedding, van der Maaten & Hinton, 2008) optimiza iterativamente una proyección 2D que preserva la estructura local: puntos cercanos en alta dimensión quedan cercanos en el plano, haciendo que grupos compactos aparezcan como nubes visualmente distinguibles. Dos ventajas concretas en este análisis: separa con claridad los clusters equilibrados de DIANA, y asigna espacio visual propio a los clusters minoritarios de HAC que PCA suprime por el desbalance del Cluster 1.
Limitación relevante: las distancias entre clusters en el plano no son métricamente interpretables — solo la cohesión interna de cada grupo lo es.
average — S5: PCA [t-SNE] (panel superior): el resultado refleja el desbalance estructural de HAC-Average: el Cluster 1 (Endeudado activo, ~8.500 obs) ocupa prácticamente todo el espacio como nube azul difusa, reduciendo los demás clusters a una zona densa en el extremo derecho. Los clusters 2 (verde), 3 (naranja) y 4 (morado) son minoritarios pero visibles y cohesionados en esa región. Los 10 outliers etiquetados corresponden en su mayoría a clientes naranja (Conservador pasivo) y morado (Cliente premium) con distancias al centroide elevadas — NuevoCliente_77, NuevoCliente_417 y NuevoCliente_332 son los más periféricos, asignados a segmentos con alta variabilidad interna.
DIANA — S2: RF [t-SNE] (panel inferior): la separación es notablemente más clara. El Cluster 2 (Transaccional sano, verde) forma una nube compacta y aislada en la zona inferior, el más diferenciado de los cuatro. El Cluster 4 (Cliente premium, morado) se agrupa en la zona izquierda junto al Cluster 1 (azul), con cierto solapamiento esperable dado que ambos perfiles comparten límite de crédito elevado. El Cluster 3 (Conservador pasivo, naranja) ocupa una franja intermedia. Las etiquetas — NuevoCliente_332, NuevoCliente_417, NuevoCliente_77 entre otros — son clientes nuevos periféricos dentro del Cluster 2, candidatos a revisión manual antes de aplicar la acción comercial de fidelización.
Note
Un cliente etiquetado como outlier no implica mala asignación — significa que su perfil está en la periferia de su segmento y la acción comercial recomendada debe aplicarse con mayor cautela o validación adicional.
16.5 Comparativa datos originales vs nuevos por algoritmo
# Distribución original vs nuevosorig_dist <-tibble(Fuente ="Originales",Cluster =factor(1:4),n_hac =as.integer(table(cls_hac)),n_diana =as.integer(table(cls_diana)))nuevos_dist <-tibble(Fuente ="Nuevos",Cluster =factor(1:4),n_hac =as.integer(table(factor(asig_hac, levels=1:4))),n_diana =as.integer(table(factor(asig_diana, levels=1:4))))bind_rows(orig_dist, nuevos_dist) |>pivot_longer(c(n_hac, n_diana), names_to ="Algoritmo", values_to ="n") |>mutate(Algoritmo =ifelse(Algoritmo =="n_hac", nom_alg_aglom, "DIANA")) |>ggplot(aes(x = Cluster, y = n, fill = Fuente)) +geom_col(position ="dodge", alpha =0.85) +geom_text(aes(label = n), position =position_dodge(0.9),vjust =-0.3, size =3) +scale_fill_manual(values =c("Originales"="#4E79A7", "Nuevos"="#F28E2B")) +facet_wrap(~Algoritmo, scales ="free_y") +# <-- escala Y libre por panellabs(title ="Distribución por cluster — originales vs nuevos clientes",x ="Cluster", y ="n") +theme_bw()
El gráfico compara la distribución de clientes originales (azul) vs nuevos (naranja) por cluster en cada algoritmo. La escala Y es libre por panel para permitir visibilidad de ambas fuentes.
average (izquierda): el desbalance de HAC-Average es evidente — Cluster 1 concentra 8.521 originales vs solo 36 nuevos. Los clusters minoritarios muestran una inversión llamativa: Cluster 3 tiene apenas 2 originales pero 196 nuevos, y Cluster 4 tiene 83 originales vs 142 nuevos. Esto confirma que los nuevos clientes —generados desde la distribución empírica global— no replican el sesgo extremo que average imprimió en los datos originales.
DIANA (derecha): distribución más equilibrada en ambas fuentes. Cluster 1 sigue siendo dominante (5.994 orig / 26 nuevos), pero los clusters 2 (1.440 / 295), 3 (1.269 / 58) y 4 (247 / 121) tienen masa suficiente para sustentar acciones comerciales diferenciadas. El Cluster 2 es el que mejor capta nuevos clientes (295), coherente con su tamaño en el portafolio original.
Note
La diferencia en proporciones entre originales y nuevos es esperable: los datos originales reflejan la estructura real del portafolio (desbalanceada), mientras los nuevos fueron simulados con distribución normal sobre la media global — no sobre la distribución por cluster. Para una simulación más realista, los nuevos clientes deberían generarse respetando los pesos de cada cluster.
Segmentos: Cluster 1 — Endeudado activo: alto saldo, frecuentes adelantos, bajo pago total. | Cluster 2 — Transaccional sano: compras frecuentes, pago total elevado. | Cluster 3 — Conservador pasivo: baja actividad, pago mínimo recurrente. | Cluster 4 — Cliente premium: límite alto, pago completo habitual.
La tabla resume el perfil mediano por cluster — cada fila representa un segmento y cada columna una dimensión del comportamiento financiero del cliente:
n: número de titulares en el cluster — refleja el desbalance de HAC-Average (Cluster 1 concentra 8.521 de 8.950 clientes).
Balance: saldo promedio sin liquidar. Cluster 3 (10.314) y Cluster 2 (4.278) presentan deuda acumulada significativa; Cluster 1 (798) es sorprendentemente bajo dado su tamaño.
Compras: monto total de compras. Cluster 3 domina (10.646) — alto consumo; Cluster 1 (356) es el menos activo transaccionalmente.
Cash Advance: adelantos en efectivo. Cluster 2 (4.508) y Cluster 3 (8.789) usan frecuentemente este mecanismo de alto costo financiero; Clusters 1 y 4 presentan valor 0 — nunca usaron adelantos.
Límite crédito: capacidad crediticia asignada. Cluster 3 (17.000) tiene el mayor límite, coherente con su alto movimiento financiero.
Pago total (PRC_FULL_PAYMENT): proporción de meses en que el cliente liquidó el saldo completo. El valor 0.000 en la mayoría de clusters indica que más del 50% de sus clientes nunca pagó el total del saldo en los 6 meses — la mediana es cero porque la distribución está fuertemente concentrada en 0. Solo Cluster 3 muestra 0.083, es decir, pagó completo en menos del 9% de los meses.
Note
El valor 0 en Pago total no significa que los clientes no paguen — significa que pagan el mínimo o una parte, acumulando intereses. Es el indicador de mayor riesgo crediticio de la tabla: clusters con Pago total = 0 son candidatos prioritarios para alertas de sobreendeudamiento o planes de consolidación.
El gráfico de barras horizontales muestra el perfil normalizado de cada cluster en seis variables clave. Los valores están escalados al rango \([0,1]\) dentro de cada variable, donde 1 = cluster con mayor mediana y 0 = cluster con menor mediana , permitiendo comparar patrones entre clusters independientemente de las unidades originales.
Variables del eje Y:
BALANCE: saldo promedio disponible. Valor alto indica deuda acumulada sin liquidar.
CASH_ADVANCE: adelantos en efectivo. Uso frecuente señala necesidad de liquidez inmediata.
CREDIT_LIMIT: límite de crédito asignado. Refleja confianza crediticia del cliente.
PAYMENTS: total de pagos realizados. Alto valor indica liquidación activa de deuda.
PRC_FULL_PAYMENT: proporción de meses con pago total. Indicador de disciplina financiera.
PURCHASES: monto total de compras. Refleja nivel de actividad transaccional.
Lectura por cluster:
Cluster 3 — naranja domina en todas las variables con valor 1.0, especialmente BALANCE, CASH_ADVANCE, CREDIT_LIMIT y PAYMENTS — perfil de alto movimiento financiero y endeudamiento, consistente con Endeudado activo o Cliente premium.
Cluster 4 — morado ocupa valores intermedios en BALANCE (~0.25), CREDIT_LIMIT (~0.45) y PAYMENTS (~0.38), con actividad nula en PRC_FULL_PAYMENT y PURCHASES (~0.75) — perfil de comprador activo con bajo pago total, coherente con Conservador pasivo o cliente de compras en cuotas.
Cluster 2 — verde muestra valores bajos en la mayoría de variables (0.12–0.50), con cierta actividad en CASH_ADVANCE (~0.50) — coherente con Conservador pasivo.
Cluster 1 — azul es prácticamente invisible — barra mínima solo en PURCHASES (~0.02) — consecuencia del desbalance severo de HAC-Average que concentra la mayoría de observaciones en Cluster 3.
Note
La dominancia del Cluster 3 (naranja) refleja el desbalance de HAC-Average: sus medianas representan el comportamiento promedio del portafolio completo, mientras los clusters minoritarios capturan perfiles más extremos y específicos. Para una lectura más equilibrada por segmento, referirse a los resultados de DIANA.
17.2 Descripción y Acciones por Segmento
Acciones por segmento
Cluster
Perfil
Acción
1
Bajo balance y compras, pago mínimo recurrente — conservador pasivo
Campaña de activación; incentivos de uso
2
Alto balance, bajo pago total, alto cash advance — endeudado activo
Plan de consolidación; alerta sobreendeudamiento
3
Alto balance, bajo pago total, alto cash advance — endeudado activo
Plan de consolidación; alerta sobreendeudamiento
4
Límite alto, compras moderadas, pago completo — cliente premium
El análisis identificó cuatro segmentos diferenciados de titulares de tarjeta de crédito: Endeudado activo, Transaccional sano, Conservador pasivo y Cliente premium. El Clean Algorithm iterativo garantizó un espacio libre de redundancia antes de cualquier selector.
La comparativa de 6 estrategias — Elastic Net, RF, B&B, SFS, PCA y SFS+PCA — determinó automáticamente, en dos etapas, tanto el algoritmo aglomerativo óptimo como el divisivo y sus respectivos espacios: HAC-Average + S5:PCA (\(\bar{s} = 0.522\)) y DIANA + S2:RF (\(\bar{s} = 0.470\)). Cada familia operó sobre el espacio que maximizó su propio Silhouette, garantizando que la elección del algoritmo no fue arbitraria sino empíricamente justificada.
Ambos algoritmos producen particiones complementarias en \(k^* = 4\) clusters. HAC-Average genera una segmentación concentrada —útil para identificar perfiles atípicos extremos—; DIANA produce distribución más equilibrada (247–5.994 obs por cluster), con mayor utilidad operativa para acciones comerciales masivas.
La comparativa de convergencia aporta evidencia de consistencia interna: ambos algoritmos coinciden en \(k^* = 4\), alcanzan coeficientes estructurales > 0.90 (AC = 0.990, DC = 0.980) y correlaciones cofenéticas similares (0.703 y 0.727). El ARI = -0.058 es negativo y cercano a cero — el ARI varía entre −1 y +1, donde 0 equivale a coincidencia por azar. El valor observado es resultado esperado del desbalance extremo de HAC-Average (98.8% en un cluster): el índice penaliza matemáticamente la asimetría entre particiones, no refleja inconsistencia analítica. La consistencia real se valida por la convergencia en \(k^* = 4\), los coeficientes estructurales y la caracterización cualitativa coincidente de los perfiles — no en asignaciones individuales idénticas entre algoritmos que operan en espacios distintos.
La validación sobre 500 clientes simulados confirmó que el mecanismo de asignación es operativo: la mayoría se ubica con confianza en su cluster más cercano, con outliers identificables por distancia al centroide. La visualización mediante t-SNE —preferida sobre PCA por su capacidad de preservar estructura local en alta dimensionalidad— evidenció que DIANA produce clusters visualmente más separados y equilibrados, mientras HAC-Average concentra su masa en el Endeudado activo con perfiles minoritarios claramente diferenciados en la periferia.
19 Referencias
Everitt, B., Landau, S., Leese, M. y Stahl, D. (2011). Cluster Analysis (5.ª ed.). Wiley.
Kaufman, L. y Rousseeuw, P.J. (1990). Finding Groups in Data. Wiley.
Rousseeuw, P.J. (1987). Silhouettes. Journal of Computational and Applied Mathematics, 20, 53–65.
Ward, J.H. (1963). Hierarchical grouping to optimize an objective function. JASA, 58(301), 236–244.
Zou, H. & Hastie, T. (2005). Regularization via the elastic net. JRSS-B, 67(2), 301–320.
Kaggle. (s.f.). Credit Card Dataset for Clustering. https://www.kaggle.com/datasets/arjunbhasin2013/ccdata