Segmentar clientes paso a paso

Anteriormente escribí sobre las redes neuronales (click aca para verlo). Las redes neuronales y todos los otros «métodos supervisados» son utilizados cuando posee una muestra de valores predecir, pero cuando sabes lo que quieres lograr, pero no tienes una muestra del valor a predecir, se utilizan los llamados «métodos no supervisados»

Un clásico problema donde se aplica esta clase de métodos es en la Segmentación de Clientes, donde a priori no se conocen los segmentos/grupos, dentro de los métodos, uno de los más famosos es K-Means.

K-Means es un algoritmo utilizado para encontrar grupos de individuos con características similares. Donde similar o distinto, será calculado según la distancia euclidiana de sus atributos numéricos.

A continuación seguiremos un ejemplo paso a paso sobre como segmentar clientes en un caso simplificado.

Para hacer este ejemplo, generaremos una muestra aleatoria de datos en dos dimensiones por caso: trafico de datos (megas) y de voz (minutos). Cada caso ha sido simulado de modo que tengan un patrón de comportamiento similar a un grupo.

Con K-Means intentaremos encontrar estos cuatro grupos, los cuales existen, pero no los conocemos.

A continuación un gráfico de los cuatro grupos:

Problema Real:

Somos el Data Scientist de una prestigiosa compañía de Celulares (experiencia personal del escritor) donde se nos encomienda la tarea de segmentar/clasificar a los clientes (nuevamente algo nada alejado de la realidad del escritor). Al revisar la base de datos, nos damos cuenta que solo disponemos de los consumos mensuales de Datos y Voz de cada cliente. (pueden ser muchos mas como: recargas, mensajes de texto llamadas al call center, etc…).

Como las escalas de consumo de datos (MB) y Voz (Minutos) son muy distintas y K-Means mide la similitud por distancia euclidiana entre casos, escalaremos los valores entre 0 y 1, obteniendo los siguientes datos:

Ya estamos listos para comenzar, como K-Means no determina el número de grupos, se ejecuta para distintas cantidades procediendo a comparar los resultados de cada caso. Las elección del número de grupos se mueve entre las matemáticas y el criterio.

Realizaremos K-Means desde 1 a 6 grupos y utilizaremos el método matemático y el método de «criterio» para determinar el numero de grupos.

Lo primero observar es ver el nivel de ajuste para cada caso, este consiste en el porcentaje de varianza explicado por cada segmentación, calculado como between_SS / total_SS (no quiero entrar en detalle). Cuando se ve que la segmentación ya no mejora considerablemente  al incrementar los grupos, significa que el grupo nuevo grupo es similar a uno ya existente, por lo que deberían el mismo.

A continuación el gráfico de ajuste para cada caso.

Al parecer, más de 4 grupos no hace sentido, ahora comparemos los valores agregados de cada grupo, veremos sus valores promedio y el numero de elementos en cada grupo.

Ahora procederemos a realizar el análisis no numérico, el cual consiste en darle nombre a los grupos, cuando no se pueden diferenciar 2 grupos, significa que no tiene sentido separarlos (solo por curiosidad, los contrastaremos con los grupos «reales»).

1 Grupo

grupo_numero min mb numero
1) Promedio de todos 71 447 120

2 Grupos

grupo_numero min mb numero
1) Poco Minutos 9 538 60
2) Muchos Minutos 134 356 60

3 Grupos

grupo_numero min mb numero
1) Poco Trafico 13 111 31
2) Muchos Minutos 134 356 60
3) Muchos Megas y pocos Minutos 5 994 29

4 Grupos

grupo_numero min mb numero
1) Muchos Megas 5 994 29
2) Muchos Minutos 148 23 30
3) Poco Trafico 13 111 31
4)Mucho Trafico 120 690 30

5 Grupos

grupo_numero min mb numero
1) Alto Trafico 111 699 22
2) Alto Trafico, en especial minutos* 143 666 8
3)Muchos Megas 5 994 29
4)Muchos Minutos 148 23 30
5) Poco Trafico 13 111 31
  • El grupo 1 y 2 son muy similares y el grupo 2 son muy pocos clientes, no tiene sentido separarlos.

6 Grupos

grupo_numero min mb numero
1) Alto consumo Minutos 148 23 30
2) Altísimo consumo Megas 3 1172 10
3) Bajo Consumo, un poco más de Megas 9 288 10
4) Alto Consumo de Megas 6 917 18
5) Bajo Consumo 13 51 22
6) Alto Consumo 120 690 30
  • El grupo 1,2 y 4 son muy similares, basicamente caracterisados por clientes que utilizan megas pero muy poca voz.

Por ende existen 4 grupos, a los cuales les daremos nombres:

grupo_numero min mb numero
Usuario de Megas 5 994 29
Usuario de Minutos 148 23 30
Bajo Consumo 13 111 31
Alto Consumo 120 690 30

Ahora que ya tenemos segmentación, comparemos los datos iniciales con los obtenidos, en el siguiente gráfico, en el color se representa el grupo encontrado por K-Means y en la forma del punto el grupo original al que correspondía el cliente (según datos generados):

Efectivamente K-Means detectó casi todos los grupos generados inicialmente.

Un corolario, así es como una operadora movil re definió sus productos, nos dimos cuenta de que la competencia tenia productos que apuntaban a los segmentos de alto consymo y bajo consumo, mientras que nosotros nos dimos cuenta que teníamos clientes que utilizaban principalmente Datos o Voz, por lo que decidimos focalizarnos en este segmento que no tenía competencia.

Si les gustó este articulo, los invito a leer sobre:

Saludos!

Si te gustó, síguenos en cualquiera de nuestros medios, allí aparecerán todas las publicaciones.

Y no olvides compartir en tus RRSS, vuestras visitas son mi motivación.

Anexo: El código R con el que se hicieron los analisis:


set.seed(1984)
library(ggplot2)
library(plyr)
library(xtable)

#Generar Muestra
muestra = rbind(
  data.frame(min = rnorm(30,10,10), mb = rnorm(30,100,100),grupo = "bajo"), #Clientes con consumo promedio
  data.frame(min = rnorm(30,120,20), mb = rnorm(30,700,100),grupo = "alto"), #Clientes con consumo promedio
  data.frame(min = rnorm(30,3,10), mb = rnorm(30,1000,200), grupo = "datos"), #Clientes con consumo alto en datos
  data.frame(min = rnorm(30,150,20), mb = rnorm(30,15,60), grupo = "voz") #Clientes con consumo alto en voz
)
muestra[,1:2] = apply(muestra[,1:2],2,function(x) ifelse(x<0,0,x))

qplot(min,mb,data=muestra,xlab = "Minutos Mensuales", ylab = "MB Mensuales",color = grupo)

#Normalización de datos
muestra = transform(muestra,n_min = min/max(min), n_mb = mb/max(mb))
qplot(n_min,n_mb,data=muestra,xlab = "Minutos Mensuales Normalizados", ylab = "MB Mensuales Normalizados")

#Ejecutar el modelo para los 6 casos
codo = data.frame()
set.seed(2016)
for(grupos in 1:6){
  modelo = kmeans(muestra[,4:5],grupos,iter.max = 100)
  codo = rbind(codo,
               data.frame(grupos = grupos, 
                          between_SS = modelo$betweenss, 
                          total_ss = modelo$totss, 
                          tot.withinss = modelo$tot.withinss, 
                          value =  modelo$betweenss/modelo$totss)
               )
  muestra[,paste0("kmeans_",grupos)] = as.character(modelo$cluster)
}

#Grafico del nivel de ajuste
qplot(x = grupos, y = value, data = codo,geom="line", ylab = "Procentaje de Ajuste", xlab = "Numero de grupos")

# resumen para cada modelo
resumen = data.frame()
for(n in 1:6){
  tabla = ddply(muestra,paste0("kmeans_",n),function(x) data.frame(min = mean(x$min),mb = mean(x$mb), numero = nrow(x)) )
  colnames(tabla)[1] = "grupo_numero"
  resumen = rbind(resumen,
                  data.frame(numero_de_grupos = n, tabla)
                  )
  print(xtable(tabla,digits = 0),type="HTML",include.rownames=FALSE)
}

print(xtable(resumen,digits = 0),type="HTML",include.rownames=FALSE)

#Grafico de cada grupo
qplot(min,mb,data=muestra,xlab = "Minutos Mensuales", ylab = "MB Mensuales",color = kmeans_6,shape = grupo)


)
Print Friendly, PDF & Email