Noviembre 2018

Yo estuve allí !!

imagen

Antonio también !!

antonio

Qué usamos

  • sparklyr hace fácil el big data
  • No siempre necesitamos todas las filas. Usar frecuencias
  • Análisis geométrico de datos FactoMineR y factoextra nos ayudan a extraer información útil.
  • Centrarse en las variables importantes

Ejemplo

¿La satisfacción de nuestros clientes está relacionada con dónde viven, qué edad tienen o de dónde vienen ? Consideramos 4 variables

  • Satisfacción cliente: Nex promotor Score. 3 categorías: Detractor, Neutro, Promotor
  • Provincias: 52 categorías más NA’s
  • Entrada. Nuevas entradas, portabilidades desde otros operadores
  • Edad del cliente. Grupos de edad

Enfoques

  • Análisis de correspondencias múltiples. Igual importancia de todas las variables
  • Análisis de correspondencias simples. Filas: NPS, Columnas: Resto de variables

Spark

library(sparklyr)
library(tidyverse)
library(FactoMineR)
library(factoextra)
library(cowplot)
sc <- spark_connect(master = "local")

Spark

Ejemplo de datos

Dplyr y spark

datos_tbl <- datos_tbl  %>%
    mutate(
        tiene_incidencia = ifelse(is.na(tiene_incidencia), "Sin_incidencia", "Incidencia"),
        tiene_alguna_porta = ifelse(is.na(tiene_alguna_porta), "no porta", "porta"),
        entrada = ifelse(
            is.na(entrada) |
                entrada == "" | entrada == "NA" ,
            "Sin_porta",
            entrada
        ),
        prov = ifelse(is.na(prov) |
                          prov == "" |
                          prov == "NA", "Prov_desconocida", prov),
        edad = case_when(
            edad < 0 ~ "Edad_desconocida",
            edad < 35 ~ "18-35",
            edad < 45 ~ "35-44",
            edad < 55 ~ "45-54",
            edad < 65 ~ "55-64",
            edad >= 65 ~ ">64",
            TRUE ~ "Edad_desconocida"
        )
    )

Datos agrupados

dat_agrup <-
    datos_tbl %>% group_by(nps_cat, prov, entrada, edad) %>% count() 

dat_agrup

MCA con FactoMiner y factoextra

La tabla con las frecuencias es suficientemente pequeña para tratarla en local. Con FactoMineR podemos usar las frecuencias como ponderación de las filas.

dat_mca <- dat_agrup %>% collect() # traemos a local

dat_mca <- dat_mca %>% 
    filter(prov != "Prov_desconocida", edad!="Edad_desconocida")

res_mca <- MCA(dat_mca[1:4], ncp = 100, row.w = dat_mca$n, graph = FALSE)

MCA con FactoMiner y factoextra

  • ¿Relación entre Porta_Comp_C , 18-35 y detract?
  • Poca variabilidad explicada por las dos primeras dimensiones
fviz_mca_var(res_mca, repel=TRUE, select.var = list(contrib = 20))

Correspondencias simple

En vez de considerar la tabla multivía construimos una tabla a 2 vías

  • Filas: Categorías de la variable de satisfacción, nps_cat
  • Columnas: Categorías del resto de las variables
  • Valores: Porcentajes por columna.

De esta forma estandarizamos

Correspondencias simple

Construimos las tablas de contingencia que necesitamos en spark, usando la función sdf_pivot

tabla_edad <- datos_tbl %>% 
    select(nps_cat, edad, prov) %>% 
    sdf_pivot(nps_cat ~ edad , 
              fun.aggregate = list(edad = "count")) 

tabla_edad <- collect(tabla_edad)

tabla_edad

Correspondencias simple

  • Todos los datos de la tabla en la misma escala. Porcentajes por columnas
  • Podemos aplicar análisis de correspondencias

Correspondencias simple

res_ca <- CA(mat_final, ncp = 10, graph = FALSE)
fviz_screeplot(res_ca)

Coordenadas filas

 fviz_ca_row(res_ca)

Coordenadas columnas

Interpretación

  • Las dimensiones hay que interpretarlas en base a la contribución
  • Hay relación entre ser “detractor” y haber tenido “incidencia”. Obvio
  • Se detectan provincias dónde el % de detractores es mayor que en otras, así como provincias dónde hay más % de neutros.

Contribución de columnas

fviz_contrib(res_ca , choice = "col", axes = c(1,2))

Biplots

  • El biplot por defecto “mapa simétrico” no permite interpretar las distancias entre filas y columnas, lo que se debe interpretar es el ángulo.
  • A menor ángulo mayor relación,

fviz_ca_biplot(res_ca, repel = TRUE, 
               select.col = list(contrib = 20 ),
               col.col = "contrib", 
               gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
               arrows = c(TRUE, FALSE))

fviz_ca_biplot(res_ca, repel = TRUE,
               select.col = list(name = c("18-35","35-44","45-54","55-64",
                       "Incidencia",
                       "Sin_incidencia" ,"Porta_Comp_A","Porta_Comp_B","Porta_Comp_C")),
               arrows = c(TRUE, FALSE))