Introducción

En este ejercicio se propone segmentar a los clientes de una determinada oficina de una entidad financiera que mantienen depósitos en tal oficina. El objetivo de la segmentación es encontrar distintos perfiles de depositantes a fin de establecer campañas de promoción de nuevos productos de depósito más personalizadas en el enfoque. Para ello se ha extraído una muestra aleatoria compuesta por 30 clientes, y se les ha preguntado sobre sus ingresos brutos mensuales y su edad.

Información muestral (datos)

Los datos se han generado aleatoriamente de acuerdo a ciertas distribuciones de probabilidad, para una muestra compuesta por 30 casos (clientes).

Variables del Trabajo

Las variables clasificadoras utilizadas son las siguientes:

  • INGRESO: Ingresos bruto medio mensual del cliente depositario.
  • EDAD: Edad del cliente depositario en el momento de la encuesta.

Descripción general de las variables clasificadoras.

head(datos)
##           INGRESOS EDAD
## cliente 1     1766   37
## cliente 2     1754   35
## cliente 3     1583   46
## cliente 4     1192   49
## cliente 5     1314   48
## cliente 6     1441   37
summary(datos)
##     INGRESOS           EDAD      
##  Min.   : 545.0   Min.   :19.00  
##  1st Qu.: 665.2   1st Qu.:26.50  
##  Median : 755.5   Median :45.00  
##  Mean   : 985.3   Mean   :44.00  
##  3rd Qu.:1333.5   3rd Qu.:59.25  
##  Max.   :1981.0   Max.   :80.00

Aquí podemos ver un pequeño resumen de los datos, encontramos 30 observaciones correspondientes a 30 clientes en las que estudiamos dos variables; ingresos, que se sitúa entre 545€ y 1981€, con una media de 755,5€, y la otra variable, edad, la cual se encuentra en un rango comprendido entre 19 y 80 años, con una media de 44 años.

par(mfrow = c(1, 2))
hist(datos$INGRESOS,breaks="Sturges",labels=TRUE, main = "Ingresos", xlab = "Euros", ylab="Frecuencias",col = "gold",
     border="tomato1")
hist(datos$EDAD,col = "gold",
     border="tomato1", main = "Edad",labels=TRUE, xlab = "Años",ylab="Frecuencias")

Representando los histogramas sobre nuestras dos variables podemos hacernos una idea de cómo se distribuyen estos datos. La variable ingresos tiene más observaciones en el intervalo 500-1000 €, lo que podríamos considerar como un perfil de clientes de ingresos bajos. Si nos centramos en la variable edad, el tramo de edad que más observaciones aglutina es de 20-30 años, donde encontramos 8 clientes, seguido de cerca del tramo 60-70 años, con 6 clientes.

par(mfrow = c(1, 2))
boxplot(datos$INGRESOS,border="steelblue", col="gold",main = "Ingresos",ylab="Euros")
boxplot(datos$EDAD,col="gold",border="steelblue",main = "Edad",ylab="Años")

Estos boxplots muestran como nueva información que existe una mayor dispersion en la variable ingresos en compraración con la variable edad. También podemos observar que no existe ningún outlier en ninguna de nuestras dos variables. Vemos como los datos están expresados en diferentes escalas, motivo que supone la posibilidad de que necesitemos escalarlos según el análisis que necesitemos realizar con ellos.

Gráfico de dispersión (una vez tipificadas las variables) que dé una idea de cómo se disponen los distintos casos (empresas) en relación a las dos variables agrupadoras.

Zdatos <- scale(datos)
library(scales)
par(mfrow = c(1, 1))
plot(Zdatos, col = alpha("steelblue", 0.4), pch = 19, las = 1)
text(Zdatos, rownames(Zdatos), pos = 3, cex = .6)

Así, en un primer momento se escalan los datos, y posteriormente realizamos el gráfico de dispersión. A primera vista parece que lo óptimo será establecer tres grupos, el primero de baja edad y bajos ingresos, el segundo de bajos ingresos y alta edad y el tercero de altos ingresos y edad intermedia, aunque no obligatoriamente en este orden. Es necesario y aconsejable realizar algunos análisis adicionales para confirmar esta división de los grupos.

Análisis clúster jerárquico basado en la “distancia euclídea” mediante el método “Ward”. Se comentan sus principales características y proponen un número de grupos a formar; teniendo en cuenta que un número muy bajo de grupos podría hacer que la campaña de promoción fuera menos efectiva al estar enfocada a clientes más heterogéneos; pero que un exceso de grupos podría encarecer mucho la campaña.

d <- dist(Zdatos, method = "euclidean")
fit <- hclust(d, method="ward.D")
plot(fit, cex = .6, xlab = "", ylab = "Distancia entre grupos", sub = "Cluster jerárquico por el método de Ward para los clientes") 
Numgrupos <- 3
library(RColorBrewer)
plot(fit, cex = .6, xlab = "", ylab = "Distancia entre grupos", sub = "Cluster jerárquico por el método de Ward para los clientes") 
rect.hclust(fit, k = Numgrupos, border = brewer.pal(Numgrupos, "Dark2"))

Atendiendo a este gráfico, que sigue el criterio de las distancias euclídeas y el método de Ward parece una buena decisión dividir la muestra en tres grupos, como ya habíamos supuesto, quedando recogidos 10 clientes en cada grupo.

Composición de cada uno de los grupos formados.

grupos <- cutree(fit, k = Numgrupos)
grupos
##  cliente 1  cliente 2  cliente 3  cliente 4  cliente 5  cliente 6 
##          1          1          1          1          1          1 
##  cliente 7  cliente 8  cliente 9 cliente 10 cliente 11 cliente 12 
##          1          1          1          1          2          2 
## cliente 13 cliente 14 cliente 15 cliente 16 cliente 17 cliente 18 
##          2          2          2          2          2          2 
## cliente 19 cliente 20 cliente 21 cliente 22 cliente 23 cliente 24 
##          2          2          3          3          3          3 
## cliente 25 cliente 26 cliente 27 cliente 28 cliente 29 cliente 30 
##          3          3          3          3          3          3
datos$GRUPO <- factor(grupos)

palette(brewer.pal(Numgrupos, "Dark2"))
plot(INGRESOS ~ EDAD, col = alpha(GRUPO, 0.75), pch = 19, data = datos, las = 1)
text(datos, rownames(datos), pos = 3, cex = .6)

Como se comenta en apartados anteriores encontramos tres grupos. Uno de ellos con ingresos bajos, en este caso el grupo 2, con unos ingresos situados entre 545 € y 754 €, una edad mínima de 19 años y una máxima de 30 años. El grupo de bajos ingresos y alta edad, en este caso es el grupo 3, los ingresos se sitúan entre los 557 y los 913 €, mientras la edad mínima es de 52 años y la máxima de 80. Por tanto, el último grupo, que corresponde con el de altos ingresos y edad intermedia, será el grupo 1, en nuestro caso concreto. Con unos ingresos mínimos de 1192 € y unos máximos de 1981 €, la edad estará entre los 35 y 54 años.

Adicionalmente, vamos a intentar una nueva división de grupos para comparar la anteriormente calculada y ver si existen cambios de grupos de algunos de los clientes. Se hará realizando la agrupación mediante el método de la vinculación inter-grupos en lugar de utilizar el método de Ward.

fit2 <- hclust(d, method = "average")
plot(fit2, cex=.6)
Numgrupos <- 3    
rect.hclust(fit2, k = Numgrupos, border = "red")

datos$GRUPO2 <- cutree(fit2, Numgrupos) 
datos
##            INGRESOS EDAD GRUPO GRUPO2
## cliente 1      1766   37     1      1
## cliente 2      1754   35     1      1
## cliente 3      1583   46     1      1
## cliente 4      1192   49     1      1
## cliente 5      1314   48     1      1
## cliente 6      1441   37     1      1
## cliente 7      1499   50     1      1
## cliente 8      1981   38     1      1
## cliente 9      1653   54     1      1
## cliente 10     1340   44     1      1
## cliente 11      557   23     2      2
## cliente 12      664   22     2      2
## cliente 13      663   20     2      2
## cliente 14      649   21     2      2
## cliente 15      732   19     2      2
## cliente 16      589   30     2      2
## cliente 17      754   28     2      2
## cliente 18      545   24     2      2
## cliente 19      672   26     2      2
## cliente 20      747   23     2      2
## cliente 21      770   80     3      3
## cliente 22      871   60     3      3
## cliente 23      741   65     3      3
## cliente 24      826   67     3      3
## cliente 25      913   69     3      3
## cliente 26      646   64     3      3
## cliente 27      557   52     3      3
## cliente 28      757   57     3      3
## cliente 29      715   67     3      3
## cliente 30      669   65     3      3
palette(brewer.pal(Numgrupos, "Dark2"))
plot(INGRESOS ~ EDAD, col = alpha(GRUPO2, 0.75), pch = 19, data = datos, las = 1)
text(datos, rownames(datos), pos = 3, cex = .6)

Se observa como, aunque cambiemos el método de agrupación, ninguna observación cambia de grupo, lo que puede significar que los grupos están muy bien definidos, es decir, los grupos son muy distintos unos de otros, y los clientes (observaciones) que hay dentro de cada grupo son muy parecidos entre sí.

Con el número de grupos seleccionado, se realiza también un clúster de k-medias y detalla la composición de cada grupo.

Data.km <- kmeans(Zdatos, Numgrupos)
Data.km
## K-means clustering with 3 clusters of sizes 10, 10, 10
## 
## Cluster means:
##     INGRESOS        EDAD
## 1 -0.5462543  1.14310698
## 2 -0.7504992 -1.13200885
## 3  1.2967535 -0.01109813
## 
## Clustering vector:
##  cliente 1  cliente 2  cliente 3  cliente 4  cliente 5  cliente 6 
##          3          3          3          3          3          3 
##  cliente 7  cliente 8  cliente 9 cliente 10 cliente 11 cliente 12 
##          3          3          3          3          2          2 
## cliente 13 cliente 14 cliente 15 cliente 16 cliente 17 cliente 18 
##          2          2          2          2          2          2 
## cliente 19 cliente 20 cliente 21 cliente 22 cliente 23 cliente 24 
##          2          2          1          1          1          1 
## cliente 25 cliente 26 cliente 27 cliente 28 cliente 29 cliente 30 
##          1          1          1          1          1          1 
## 
## Within cluster sum of squares by cluster:
## [1] 2.0994027 0.6050381 3.9808276
##  (between_SS / total_SS =  88.5 %)
## 
## Available components:
## 
## [1] "cluster"      "centers"      "totss"        "withinss"    
## [5] "tot.withinss" "betweenss"    "size"         "iter"        
## [9] "ifault"
datasize <- Data.km$size
datasize
## [1] 10 10 10
ZDatag <- data.frame(Zdatos, GRUPO = factor(Data.km$cluster))     
plot(EDAD ~ INGRESOS, col = alpha(GRUPO, 0.75), pch = 19, data = ZDatag, las = 1)
text(ZDatag, rownames(ZDatag), pos = 3, cex = .6)
points(Data.km$centers, pch = 17,col = 1:Numgrupos, cex = 2)

Se puede observar como tampoco se modifica la composición de los grupos si lo hacemos a través del método de las k-medias con un número predefinido de 3 grupos. Seguimos encontrando los mismos perfiles, el primero de baja edad y bajos ingresos, el segundo de bajos ingresos y alta edad y el tercero de altos ingresos y edad intermedia.

Composición de los grupos obtenidos en los apartados anteriores.

datos$GRUPO3 <- factor(Data.km$cluster)
datos
##            INGRESOS EDAD GRUPO GRUPO2 GRUPO3
## cliente 1      1766   37     1      1      3
## cliente 2      1754   35     1      1      3
## cliente 3      1583   46     1      1      3
## cliente 4      1192   49     1      1      3
## cliente 5      1314   48     1      1      3
## cliente 6      1441   37     1      1      3
## cliente 7      1499   50     1      1      3
## cliente 8      1981   38     1      1      3
## cliente 9      1653   54     1      1      3
## cliente 10     1340   44     1      1      3
## cliente 11      557   23     2      2      2
## cliente 12      664   22     2      2      2
## cliente 13      663   20     2      2      2
## cliente 14      649   21     2      2      2
## cliente 15      732   19     2      2      2
## cliente 16      589   30     2      2      2
## cliente 17      754   28     2      2      2
## cliente 18      545   24     2      2      2
## cliente 19      672   26     2      2      2
## cliente 20      747   23     2      2      2
## cliente 21      770   80     3      3      1
## cliente 22      871   60     3      3      1
## cliente 23      741   65     3      3      1
## cliente 24      826   67     3      3      1
## cliente 25      913   69     3      3      1
## cliente 26      646   64     3      3      1
## cliente 27      557   52     3      3      1
## cliente 28      757   57     3      3      1
## cliente 29      715   67     3      3      1
## cliente 30      669   65     3      3      1

Se está comparando la composición de los grupos según los 2 métodos jerárquicos (Ward y average) y el método no jerárquico (K-means), pero no hay trasvase entre grupos sea cual sea el método utilizado, lo que reafirma la teoría anteriormente expuesta de que los grupos son muy distintos unos de otros, y los clientes que hay dentro de cada grupo son muy parecidos entre sí. Podríamos afirmar que diferenciar en tres grupos estas observaciones tiene una gran utilidad y que ésta es la división óptima.

Con base en la solución aportada por el método de k-medias, se caracteriza cada uno de los grupos atendiendo a las coordenadas de sus centros, y a partir de los diagramas de caja para cada variable clasificadora y grupo; comparando a partir de esta información el comportamiento de tales grupos.

aggregate(cbind(INGRESOS, EDAD) ~ GRUPO3, data = datos, FUN = mean)
##   GRUPO3 INGRESOS EDAD
## 1      1    746.5 64.6
## 2      2    657.2 23.6
## 3      3   1552.3 43.8

Vemos de forma númerica lo ya mostrado en apartados precedentes, como los ingresos entre el grupo 2 y 3 son parecidos pero difieren mucho en edad. El grupo 1, sin embargo, presenta una media de ingresos mucho mayor y una edad intermedia.

par(mfrow = c(1, 2))
boxplot(INGRESOS ~ GRUPO3, main = "Boxplot de los ingresos", col = 1:3, data = datos, las = 1)
boxplot(EDAD ~ GRUPO3, main = "Boxplot de la edad", col = 1:3, data = datos, las = 1)

En el boxplot de los ingresos podemos ver como es muy probable que haya diferencias significativas entre los grupos 1-3 y entre los grupos 1-2. Sin embargo, no queda tan claro que la diferencia en los grupos 2-3 sea significativa, de modo que será necesario confirmar estas diferencias de forma analítica mediante análisis de la varianza (ANOVA). En cuanto al boxplot de la edad parece mostrar diferencias significativas entre todas las combinaciones posibles de los tres grupos, aunque también trataremos de confirmarlo mediante ANOVA.

modelo.aov <- aov(INGRESOS ~ GRUPO3, data = datos)
summary(modelo.aov)
##             Df  Sum Sq Mean Sq F value   Pr(>F)    
## GRUPO3       2 4861640 2430820   96.23 5.19e-13 ***
## Residuals   27  682040   25261                     
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
TukeyHSD(modelo.aov)
##   Tukey multiple comparisons of means
##     95% family-wise confidence level
## 
## Fit: aov(formula = INGRESOS ~ GRUPO3, data = datos)
## 
## $GRUPO3
##      diff       lwr        upr     p adj
## 2-1 -89.3 -265.5332   86.93323 0.4314325
## 3-1 805.8  629.5668  982.03323 0.0000000
## 3-2 895.1  718.8668 1071.33323 0.0000000

Efectivamente y como suponíamos, para las combinaciones de grupos 1-3 y 1-2 en cuanto a ingresos se refiere el p-valor es de 0, por lo que podemos asumir que hay diferencias significativas entre estos grupos. Sin embargo, el p-valor para la combinacion de grupos 2-3 es mucho mayor a 0.05 por lo que asumimos una media de ingresos iguales para esos grupos.

modelo.aov2 <- aov(EDAD ~ GRUPO3, data = datos)
summary(modelo.aov2)
##             Df Sum Sq Mean Sq F value   Pr(>F)    
## GRUPO3       2   8406    4203   112.1 8.39e-14 ***
## Residuals   27   1012      37                     
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
TukeyHSD(modelo.aov2)
##   Tukey multiple comparisons of means
##     95% family-wise confidence level
## 
## Fit: aov(formula = EDAD ~ GRUPO3, data = datos)
## 
## $GRUPO3
##      diff       lwr       upr p adj
## 2-1 -41.0 -47.78983 -34.21017 0e+00
## 3-1 -20.8 -27.58983 -14.01017 1e-07
## 3-2  20.2  13.41017  26.98983 2e-07

En cuanto a las edades se refiere, todos los p-valores son menores a 0.05 de manera que asumiremos la media de edad distinta para todas las combinaciones de grupos.

A la vista de estos resultados del ANOVA podemos considerar que las diferencias entre grupos son más que suficientes como para asumir la utilidad de aplicar esta técnica.

Idea a aplicar para promocionar productos de ahorro para cada uno de los grupos obtenidos, a partir de los resultados de apartados anteriores.

Para el primer grupo (ingresos y edad baja), crearíamos una campaña de promoción enfocada al ahorro a largo plazo, puesto que es para gente joven y la edad del grupo está entre los 19 y los 30 años, con inversiones con algo más de riesgo puesto que el horizonte de inversión es muy grande y con un límite mínimo de ahorro muy bajo puesto que este grupo dispone de unos ingresos muy bajos, de forma que este límite mínimo de ahorro mensual sería de 30 €.

La campaña para el segundo grupo (ingresos bajos y edad alta), sería una campaña orientada a un ahorro a muy corto plazo, puesto que mucho de los clientes están muy cerca de la jubilación y necesitarán pronto este ahorro, por tanto se basaría en una campaña promocionando depósitos garantizados, también con un límite mínimo muy pequeño ya que este grupo también presenta unos ingresos muy reducidos.

Para el tercer grupo (ingresos altos y edad intermedia), se promocionaría un producto de ahorro con un límite mínimo de aportaciones mensuales mayor a los anteriores, 150 €, puesto que la media de ingresos en este grupo es mayor, y un horizonte de la inversión medio porque es un grupo que aún posee un elevado margen de tiempo para alcanzar la jubilación.