Introducción:

En el aprendizaje estadístico hay un componente importante que nos permite realizar segmentaciones de grupos de datos basados en características o comportamientos semejantes, en un conjunto de variables aleatorias, este es conocido como aprendizaje no supervisado, existen varios algoritmos que nos permiten realizar este agrupamiento tal como k-means, Hierarical clustering, etc. cada uno tiene una estructura y un acercamiento a los datos diferente. En este trabajo solo se realizará uno de estos algoritmos. Algo que cabe aclarar es que este tipo de aprendizaje estadístico no tiene soluciones cerradas, lo ideal es encontrar las características más relevantes que nos permitan diferenciar los grupos. El siguiente trabajo se realizará sobre una base de datos que contiene información de clientes corporativos de una empresa cuyos clientes son empresas, en esta se mostraran variables de comportamiento de los clientes en canales y productos, incluyendo cantidad de transacciones y valores de tickets promedio de entrada y salida por canales de la empresa, además de variables de estados financieros y características de los clientes [3]. El objetivo será obtener una segmentación que permita un entendimiento de los clientes, identificando patrones en cuanto al uso de canales y productos y su relación con los estados financieros, debido a la falta de información sobre la empresa en cuestión, se tendrá en cuenta un enfoque general que sería aplicable para múltiples tipos de empresas.

Objetivos:

Objetivo general

  • Se va a proponer una segmentación para los clientes de tal manera que la empresa pueda comprender de una mejor manera sus comportamientos con relación a los estados financieros, patrones de uso de productos y canales de cada uno.

Objetivos específicos

  • Analizar cuáles son las variables más relevantes de la colección de datos para usarlas como base para la segmentación por grupos de los clientes.
  • Utilizar diferentes métodos para la selección de grupos y de qué manera se deben dividir.
  • Comparar los grupos obtenidos para definir si son pertinentes o no, dándoles una descripción a los mismos para que sea de más facilidad a la empresa distinguir los tipos de clientes que maneja.

Retos

Partiremos de la información suministrada en la base de datos presentada por la empresa para el análisis de sus clientes, permitiendo así analizar los tipos de variable que tenemos, su significado y su relevancia a la hora de realizar la segmentación. Estos significados los obtendremos del documento presentado donde están los lineamientos del problema y con estas variables y sus tipos podremos definir cuál es el método más apropiado para realizar la segmentación. [3]

La descripción de las variables presentadas en la base de datos son:

nombre tipo
en_vm_canal1 numérica
en_vm_canal2 numérica
en_vm_canal3 numérica
en_vm_canal4 numérica
en_vm_canal5 numérica
en_vm_canal6 numérica
en_vm_canal7 numérica
en_vm_canal8 numérica
en_vm_canal9 numérica
en_vm_canal10 numérica
en_vm_otros numérica
en_tx_canal1 numérica
en_tx_canal2 numérica
en_tx_canal3 numérica
en_tx_canal4 numérica
en_tx_canal5 numérica
en_tx_canal6 numérica
en_tx_canal7 numérica
en_tx_canal8 numérica
en_tx_canal9 numérica
en_tx_canal10 numérica
en_tx_otros numérica
sal_vm_canal5 numérica
sal_vm_canal2 numérica
sal_vm_canal8 numérica
sal_vm_otros numérica
sal_tx_canal5 numérica
sal_tx_canal2 numérica
sal_tx_canal8 numérica
sal_tx_otros numérica
impo_cv categórica ordinal
expo_vt categórica ordinal
cxp categórica ordinal
cxc categórica ordinal
totalinventory categórica ordinal
pagos_pj porcentaje
pagos_pn porcentaje
tiene_ventas_fisicas binaria
tiene_ventas_electronicas binaria
recaudos_pj porcentaje
recaudos_pn porcentaje
rotacion_inventarios categórica ordinal
rotacion_cxc categórica ordinal
rotacion_cxp categórica ordinal
ciclo_negocio categórica ordinal
ciclo_financiero categórica ordinal

Tabla 1. Variables [3].

Luego de ver las variables, fue necesaria una selección de las más importantes y eliminación de las que tenían una correlación muy grande para tener así una mejor selección. También se buscaron datos que tuvieran columnas nulas, pero para esta base de datos en específico no se encontraron datos nulos; también se normalizaron las variables para poder hacer una buena comparación entre ellas, sin embargo, antes que esto se separaron las variables según su categoría.

Materiales y métodos:

Materiales:

Se utilizará una base de datos que fue provista por una fuente anónima del profesor, la cual representa los patrones de usos de productos y de canales en relación a los estados financieros para clientes corporativos de una empresa.

Métodos:

El método utilizado es agrupamiento jerárquico, para realizar una buena selección de las variables y eliminar el ruido, eliminamos las variables que estuvieran altamente correlacionadas para realizar el cálculo de las matrices de distancias. también se realiza una separación entre variables categóricas (nominales y ordinales) y numéricas para realizar el cálculo de la matriz de distancias, realizando una matriz de distancias para cada conjunto-tipo de variables y finalmente se sumarán estas matrices, finalmente será utilizaremos diferentes funciones de enlace tales como complete, Ward, etc. para seleccionar los grupos. [1]

A continuación el código:

library(kableExtra)
library(tidyverse)
## -- Attaching packages --------------------------------------- tidyverse 1.3.0 --
## v ggplot2 3.3.3     v purrr   0.3.4
## v tibble  3.0.6     v dplyr   1.0.4
## v tidyr   1.1.2     v stringr 1.4.0
## v readr   1.4.0     v forcats 0.5.1
## -- Conflicts ------------------------------------------ tidyverse_conflicts() --
## x dplyr::filter()     masks stats::filter()
## x dplyr::group_rows() masks kableExtra::group_rows()
## x dplyr::lag()        masks stats::lag()
setwd("~/9/TAE/Trabajo 2 segmentacion")
datos <- read.csv('base_trabajo_segmentacion.csv', sep = ';')
any(is.na(datos)) # no hay NA
## [1] FALSE
# kable(summary(datos))
# str(datos)

Agrupamiento jerarquico:

Para realizar este agrupamiento [1], es necesario hallar las matrices de distancia con el propósito de realizar los correspondientes calculos para su clasificación. Dado la composición de la base de datos, entre variables numéricas, categóricas binarias y categóricas ordinales; así se decide separar las variables por su tipo, para hallar sus matrices de distancia:

# separamos los datos en categorigos ordinasles, catego. binarios y numericos 
datos_cat <- datos[,c(32:47)] # todos los catego.
datos_cat <- datos_cat[,-c(6,7,10,11)] # estaban incluidos estos numericos
datos_cat_bin <- datos_cat[,c(6,7)] # extraemos los binarios aparte
datos_cat <- datos_cat[,-c(6,7)] # eliminamos los binarios de los ordinales
# str(datos_cat_bin) # para comprobar que se se seleccionaron las variables de interes:
# str(datos_cat)
datos_num <- datos[,c(2:31, 37, 38,41,42)]  #todo slos numericos
# str(datos_num)
# kable(summary(datos_num))

Correlación entre variables numéricas:

Se verificará las variables correlacionadas con el objetivo de eliminar las que puedan estar altamente correlacionadas, a fin de disminuir la redundancia de dichas variables en los cálculos y de esta manera utilizar las restantes en el cálculo de la matriz de distancias para el agrupamiento jerarquico.

library(ggcorrplot)

# Cálculo de la matriz de correlaciones
cor_mat <- cor(datos_num,use = "everything")
# Visualización de la matriz de correlaciones:
ggcorrplot(cor_mat,method = "circle")

# con el fin de eliminarlas para realizar el calculo de las matrices de distancia.
library(caret)
## Loading required package: lattice
## 
## Attaching package: 'caret'
## The following object is masked from 'package:purrr':
## 
##     lift
# calculate correlation matrix over numerical data:
correlationMatrix <- cor(datos_num)

# find attributes that are highly corrected (ideally >0.75)
highlyCorrelated <- findCorrelation(correlationMatrix, cutoff=0.75, names = F, exact = T)
# print indexes of highly correlated attributes
# print(highlyCorrelated)
#' Observamos las variables que tienen una correlacion mayor a 0.75 las cuales pueden ser redundantes tenerlas en nuestra base de datos, por lo cual procedemos a eliminarlas. 
datos_num <- datos_num[,-c(23,5,3,7,4,12,27,31,25)]

Podemos observar que existen varaibles altamente correlacionadas, tanto de manera positiva como negativa vistos como los colores rojos y azules respectivamente.El criterio que se utilizó para definir alta correlación es que esta sea superior al \(75\%\). Ahora removemos estas varaibles y obtenemos:

correlationMatrix <- cor(datos_num)
# find attributes that are highly corrected (ideally >0.75)
highlyCorrelated <- findCorrelation(correlationMatrix, cutoff=0.75, names = F, exact = T)
# print indexes of highly correlated attributes
# print(highlyCorrelated)
# Cálculo de la matriz de correlaciones
cor_mat <- cor(datos_num,use = "everything")
# Visualización de la matriz de correlaciones:
ggcorrplot(cor_mat,method = "circle")

Podemos notar el cambio en la intensidad del color rojo y la no aparacion del color azul, al remover dichas variables; serán estas las variables a utilizar.

Normalización de variables categoricas ordinales:

Con el proposito de calcular las distancia de una manera adecuada de las variables categoricas ordinales, realizamos una normalización que consta de asignar los valores de cada variable entre cero y uno para esto utilizamos la función \(x_i = \frac{x_i-min(\underline{X})}{max(\underline{X})-min(\underline{X})}\) donde \(x_i\) es una observación de la varibale \(\underline{X}\). Al estar normalizados los datos podremos realizar el calculo de las distancias con la distancia euclidiana. Alguno de los resultados de las variables normalizadas se observarán acontinuación:

normalizedRanks <- function(x){(x-min(x))/(max(x)-min(x))}

max(datos_cat[c('rotacion_cxp')])
## [1] 4
#!!!!!!rotacion_cxc y rotacion_cxp tienen como máximo valo 4 pero en el enunciado dicen que están categorizados con 6 niveles, hacemos la normalizacióncon 6 o con 4? 

#Debido a que el dato máximo en la columna impo_cv es 5 y en expo_vt es 3, estas 2 presentan diferentes escalas, la distancia de las variablestiene_ventas_fisicas y tiene_ventas_electronicas se manejara con otro método para mantener su estado categorico
datos_cat[c('impo_cv')] <- normalizedRanks(datos_cat[c('impo_cv')])
datos_cat[c('expo_vt')] <- normalizedRanks(datos_cat[c('expo_vt')])
datos_cat[c('cxp')] <- normalizedRanks(datos_cat[c('cxp')])
datos_cat[c('cxc')] <- normalizedRanks(datos_cat[c('cxc')])
datos_cat[c('totalinventory')] <- normalizedRanks(datos_cat[c('totalinventory')])
datos_cat[c('rotacion_inventarios')] <- normalizedRanks(datos_cat[c('rotacion_inventarios')])
datos_cat[c('rotacion_cxc')] <- normalizedRanks(datos_cat[c('rotacion_cxc')])
datos_cat[c('rotacion_cxp')] <- normalizedRanks(datos_cat[c('rotacion_cxp')])
datos_cat[c('ciclo_negocio')] <- normalizedRanks(datos_cat[c('ciclo_negocio')])
datos_cat[c('ciclo_financiero')] <- normalizedRanks(datos_cat[c('ciclo_financiero')])
kable(str(datos_cat))
## 'data.frame':    2233 obs. of  10 variables:
##  $ impo_cv             : num  0 0 0 0.25 0 0 0 0.25 0.25 0.25 ...
##  $ expo_vt             : num  0 0 0 0.5 0 0 0 0.5 0.5 0.5 ...
##  $ cxp                 : num  1 0.2 0.4 0 0.2 0 0 0.2 0.4 0.4 ...
##  $ cxc                 : num  1 1 0 0 0.2 0.4 0.6 0 0 1 ...
##  $ totalinventory      : num  1 0.2 0.2 0 0.2 0 0 1 0.6 0.4 ...
##  $ rotacion_inventarios: num  1 0 0.2 0.8 0.2 0 0.2 1 1 0 ...
##  $ rotacion_cxc        : num  0.333 0.667 0 0.333 0.333 ...
##  $ rotacion_cxp        : num  0.333 0 0.333 0.667 0 ...
##  $ ciclo_negocio       : num  0.8 0.4 0.2 0.8 0.4 0.8 1 1 1 0.6 ...
##  $ ciclo_financiero    : num  1 0.6 0 0.8 0.4 0.8 1 1 0.8 0.6 ...

Escalamos las varaibles numéricas:

Con el propósito de que el cálculo de las distancias no se vea afectado por las diferentes escalas en que se encuentras los datos, se realiza una normalización:

# escalamos los datos numericos
datos_num_scaled <- scale(datos_num, center = TRUE, scale = TRUE)

Posteriormente realizamos el cálculo de las distancias según el tipo de variable, para el caso de las variables binarias utilizamos el método binario y para las variables numéricas y ordinales normalizadas realizamos la distancia euclidiana:

D_cat_bin <- dist(datos_cat_bin, method="binary",diag=TRUE)
D_cat <- dist(datos_cat, method="euclidean",diag=TRUE)
D_num <- dist(datos_num_scaled, method="euclidean", diag=TRUE)
N <- dim(datos_cat_bin)[1]
# Por temas de optimización, las gráficas se realizaron, se guardarón y se cargaron al documento.
# image(t(as.matrix(D_cat_bin)[,N:1]), main="Distancias según las variables binarias")
# image(t(as.matrix(D_cat)[,N:1]), main="Distancias según las variables categoricas \\n ordinales transformadas")
# image(t(as.matrix(D_num)[,N:1]), main="Distancias según las variables numericas")

Ahora podemos observar las matrices de distacias:

Suma de matrices:

Dado que los datos numéricos, estaban afectando de una manera importante los resultados para hallar grupos significativos, se opta por reducir la matriz de los datos numéricos a tan solo un 1%. para el cálculo de la matriz de distancias final; es decir la mayor parte de la clasificación está basada en los datos categóricos:

Dis_tot <- 0.01* D_num + D_cat_bin + D_cat 
# image(t(as.matrix(Dis_tot)[,N:1]), main="Distancias totales")

Ahora observamos la matriz de distancias total:

Agrupamientos con sus diferentes funciones likage:

Con el fin de encontrar un metodo que mejor agrupe nuestros datos, realizamos todas las posibles calculos ofrecidos por el software, de esta manera se realizan 8 operaciones diferentes observados acontinuación:

Con el fin de encontrar un método que mejor agrupe nuestros datos, realizamos todas los posibles cálculos ofrecidos por el software, de esta manera se realiza la agrupación jerárquica con cada uno de los métodos de la función ‘Hclust’. El objetivo agrupar clusters para formar uno nuevo o bien separar alguno ya existente para dar origen a otros dos, de tal forma que, si sucesivamente se va efectuando este proceso de aglomeración o división, se minimice alguna distancia o bien se maximice alguna medida de similitud.[2]

cluster_jerar_complete <- hclust(Dis_tot,method = "complete")
cluster_jerar_single <- hclust(Dis_tot,method = "single")
cluster_jerar_average <- hclust(Dis_tot,method = "average")
cluster_jerar_centroid <- hclust(Dis_tot,method = "centroid")
cluster_jerar_ward.D <- hclust(Dis_tot,method = "ward.D")
cluster_jerar_ward.D2 <- hclust(Dis_tot,method = "ward.D2")
cluster_jerar_mcquitty <- hclust(Dis_tot,method = "mcquitty")
cluster_jerar_median <- hclust(Dis_tot,method = "median")

Visulizamos los dendogramas para cada metodo Linkage:

complete:

Se considera que la distancia o similitud entre dos clusters hay que medirla atendiendo a sus elementos más dispares, o sea, la distancia o similitud entre clusters viene dada, respectivamente, por la máxima distancia (o mínima similitud) entre sus componentes. [1]

plot(cluster_jerar_complete)

Podemos observar para el metodo “complete” un comportamiento algo balanceado, dado su capacidad de encontrar clusters similares al momento de enlazar los datos. Este podrá ser un buen candidato para agrupar los clientes de la empresa.

Single:

En este método se considera que la distancia o similitud entre dos clusters viene dada, respectivamente, por la mínima distancia (o máxima similitud) entre sus componentes. [1]

plot(cluster_jerar_single)

Este adopta el metodo de “nearest neighbour”, para este caso no se notan grupos especificos, por lo que será descartado como candidato a agrupar.

Average:

En esta estrategia la distancia, o similitud, del cluster \(C_i\) con el \(C_j\) se obtiene como la media aritmética entre la distancia, o similitud, de las componentes de dichos clusters. [1]

plot(cluster_jerar_average)

Observamos en este dendograma una forma mas o menos balanceada pero en este metodo, algunos grupos solo tienen un usuario, por lo que lo descartaremos.

Centroid:

En estos métodos, la semejanza entre dos clusters viene dada por la semejanza entre sus centroides, esto es, los vectores de medias de las variables medidas sobre los individuos del cluster. [1]

plot(cluster_jerar_centroid)

Similar al método “linkage”, es claro que no se realizan agrupaciones claras por lo que se descartará como opción. Además que puede no funcionar por que el centroide puede ser diferente para todo los usuarios por lo que selecciona varios grupos que no se ven claros.

ward.D:

El método de Ward es un procedimiento jerárquico en el cual, en cada etapa, se unen los dos clusters para los cuales se tenga el menor incremento en el valor total de la suma de los cuadrados de las diferencias, dentro de cada cluster, de cada individuo al centroide del cluster. [2]

plot(cluster_jerar_ward.D)

Este tipo de enlace esta direccionado a un problema de agrupamiento basado en varianza. Para el caso podemos notar una agrupación excelente, es lo que todo cientifico de datos quisiera ver en sus proyectos de clusters, pero no es recomendable utilizar el metodo de ward basado en su dendograma, ya que se basa en calcular la de la suma de cuadrados de errores entre grupos de forma aditiva no promediada y esto causa que los grupos posteriores sean más grandes, mostrando engañosamente un mejor árbol, de esta manera genera una ilusión así que no es recomendable seleccionarlo.

ward.D2:

plot(cluster_jerar_ward.D2)

Este método es una variación del anterior, por lo que gráficamente muestra este comportamiento ideal pero no es muy conveniente seleccionar este método basado en su gráfica. [2]

mcquity:

plot(cluster_jerar_mcquitty)

Este es un metodo que tiene la bondad de poder ser aplicado a datos tanto continuos como discretos, pero tiene el defecto de ser muy laborioso. En este método podemos notar que habran grupos que tendran solo un usuario, como el 825 o el 1534, por ello se considerará descartar este método, ya que se desea realizar una mayor generalización de los grupos.

median:

plot(cluster_jerar_median)

Similar al método de centroide, no se pueden apreciar graficamente agrupaciones claras, por lo cual se descarta este método.

Conclusión: Los dendogramas que muestran agrupaciones más adecuadas son los que corresponden a las funciones de enlace “complete” , “Ward.D” y “ward.D2”, de las cuales se seleccionará el método complete, por mostrar un agrupamiento balanceado y que no presentara el inconveniente que se pueden tener los demás(como se aclaró anteriormente).

Buscamos los grupos basado en su dendograma:

Seleccionaremos los tamaños los grupos para un \(k = 2,3,4, \quad y \quad 5\):

plot(cluster_jerar_complete)
rect.hclust(cluster_jerar_complete, k = 2, border = c(1:3)+1)

Se pueden observar claramente dos grupos muy bien definidos. Se probaran con más grupos para verificar como se comportan.

K=3:

plot(cluster_jerar_complete)
rect.hclust(cluster_jerar_complete, k = 3, border = c(1:3)+1)

Se puede observar claramente 3 grupos separables, dos de tamaños realtivamente grandes y uno pequeño.

k=4

plot(cluster_jerar_complete)
rect.hclust(cluster_jerar_complete, k = 4, border = c(1:4)+1)

Este caso es similar al anterior con la diferencia de que se observa un grupo bastante pequeño en el marco de color azul.

k=5

plot(cluster_jerar_complete)
rect.hclust(cluster_jerar_complete, k = 5, border = c(1:5)+1)

Para este caso vemos que se forma un grupo enmarcado en color verde entre los dos grupos más grandes observados anteriormente.

conclusión: Se considera conveniente seleccionar tres grupos, basado en el razonamiento de que estos generalizan un poco mejor que k = 3 y 4, y que es más específico que k=2. Sin embargo se considera prudente revisar los resultados de estos grupos en posteriores estudios.

Breve analisis de resumen para k = 3 grupos:

etiqueta_grupo <- cutree(cluster_jerar_complete, k=3)
kable(summary(datos[etiqueta_grupo==1,]) )
nit en_vm_canal1 en_vm_canal2 en_vm_canal3 en_vm_canal4 en_vm_canal5 en_vm_canal6 en_vm_canal7 en_vm_canal8 en_vm_canal9 en_vm_canal10 en_vm_otros en_tx_canal1 en_tx_canal2 en_tx_canal3 en_tx_canal4 en_tx_canal5 en_tx_canal6 en_tx_canal7 en_tx_canal8 en_tx_canal9 en_tx_canal10 en_tx_otros sal_vm_canal5 sal_vm_canal2 sal_vm_canal8 sal_vm_otros sal_tx_canal5 sal_tx_canal2 sal_tx_canal8 sal_tx_otros impo_cv expo_vt cxp cxc totalinventory pagos_pj pagos_pn tiene_ventas_fisicas tiene_ventas_electronicas recaudos_pj recaudos_pn rotacion_inventarios rotacion_cxc rotacion_cxp ciclo_negocio ciclo_financiero
Length:1150 Min. :0.000e+00 Min. :0.000e+00 Min. :0.000e+00 Min. :0 Min. :0.000e+00 Min. :0.000e+00 Min. :0.000e+00 Min. : 0 Min. : 0 Min. : 0 Min. : 0 Min. : 0.000 Min. : 0.000 Min. : 0.000 Min. :0 Min. : 0.000 Min. : 0.000 Min. : 0.0000 Min. : 0.000 Min. : 0.000 Min. :0.00000 Min. : 0.0000 Min. :0.000e+00 Min. :0.000e+00 Min. :0.00e+00 Min. : 0 Min. : 0.000 Min. : 0.00 Min. : 0.0000 Min. : 0.0000 Min. :1.00 Min. :1.00 Min. :1.000 Min. :1.000 Min. :1.000 Min. :0.0000 Min. :0.0000 Min. :0 Min. :0 Min. :0.000000 Min. :0.00000 Min. :1.000 Min. :1.000 Min. :1.000 Min. :1.000 Min. :1.000
Class :character 1st Qu.:1.203e+07 1st Qu.:1.276e+08 1st Qu.:0.000e+00 1st Qu.:0 1st Qu.:0.000e+00 1st Qu.:0.000e+00 1st Qu.:0.000e+00 1st Qu.: 0 1st Qu.: 0 1st Qu.: 0 1st Qu.: 0 1st Qu.: 1.805 1st Qu.: 3.308 1st Qu.: 0.000 1st Qu.:0 1st Qu.: 0.000 1st Qu.: 0.000 1st Qu.: 0.0000 1st Qu.: 0.000 1st Qu.: 0.000 1st Qu.:0.00000 1st Qu.: 0.0000 1st Qu.:0.000e+00 1st Qu.:0.000e+00 1st Qu.:0.00e+00 1st Qu.: 0 1st Qu.: 0.000 1st Qu.: 0.00 1st Qu.: 0.0000 1st Qu.: 0.0000 1st Qu.:1.00 1st Qu.:1.00 1st Qu.:1.000 1st Qu.:2.000 1st Qu.:2.000 1st Qu.:0.3390 1st Qu.:0.1568 1st Qu.:0 1st Qu.:0 1st Qu.:0.000000 1st Qu.:0.00000 1st Qu.:1.000 1st Qu.:1.000 1st Qu.:1.000 1st Qu.:3.000 1st Qu.:2.000
Mode :character Median :1.558e+08 Median :6.948e+08 Median :2.472e+05 Median :0 Median :0.000e+00 Median :3.470e+06 Median :0.000e+00 Median : 436034 Median : 137667 Median : 0 Median : 0 Median : 10.523 Median : 15.542 Median : 1.000 Median :0 Median : 0.000 Median : 2.000 Median : 0.0000 Median : 1.000 Median : 1.000 Median :0.00000 Median : 0.0000 Median :0.000e+00 Median :3.933e+08 Median :0.00e+00 Median : 0 Median : 0.000 Median : 74.25 Median : 0.0000 Median : 0.0000 Median :2.00 Median :2.00 Median :2.000 Median :3.000 Median :3.000 Median :0.5500 Median :0.4245 Median :0 Median :0 Median :0.000000 Median :0.00000 Median :2.000 Median :2.000 Median :2.000 Median :4.000 Median :4.000
NA Mean :1.100e+09 Mean :3.141e+09 Mean :5.591e+07 Mean :0 Mean :7.654e+08 Mean :6.370e+07 Mean :4.394e+07 Mean : 9717143 Mean : 5044195 Mean : 313494 Mean : 265016 Mean : 146.465 Mean : 62.151 Mean : 66.737 Mean :0 Mean : 4.079 Mean : 8.386 Mean : 0.8736 Mean : 3.319 Mean : 3.281 Mean :0.05142 Mean : 0.1292 Mean :7.331e+08 Mean :2.501e+09 Mean :4.38e+05 Mean : 611777 Mean : 3.976 Mean : 482.43 Mean : 0.3355 Mean : 0.9807 Mean :1.93 Mean :1.67 Mean :2.685 Mean :3.298 Mean :3.101 Mean :0.5564 Mean :0.4071 Mean :0 Mean :0 Mean :0.009055 Mean :0.01964 Mean :2.992 Mean :2.428 Mean :2.112 Mean :4.083 Mean :3.849
NA 3rd Qu.:7.379e+08 3rd Qu.:2.538e+09 3rd Qu.:3.025e+06 3rd Qu.:0 3rd Qu.:1.513e+08 3rd Qu.:2.128e+07 3rd Qu.:0.000e+00 3rd Qu.: 4068879 3rd Qu.: 3490127 3rd Qu.: 0 3rd Qu.: 0 3rd Qu.: 84.500 3rd Qu.: 62.417 3rd Qu.: 3.096 3rd Qu.:0 3rd Qu.: 2.833 3rd Qu.: 6.479 3rd Qu.: 0.0000 3rd Qu.: 1.857 3rd Qu.: 2.000 3rd Qu.:0.00000 3rd Qu.: 0.0000 3rd Qu.:1.515e+08 3rd Qu.:1.810e+09 3rd Qu.:0.00e+00 3rd Qu.: 0 3rd Qu.: 2.741 3rd Qu.: 371.56 3rd Qu.: 0.0000 3rd Qu.: 0.0000 3rd Qu.:2.00 3rd Qu.:2.00 3rd Qu.:3.000 3rd Qu.:5.000 3rd Qu.:5.000 3rd Qu.:0.8060 3rd Qu.:0.6238 3rd Qu.:0 3rd Qu.:0 3rd Qu.:0.000000 3rd Qu.:0.00000 3rd Qu.:5.000 3rd Qu.:4.000 3rd Qu.:3.000 3rd Qu.:6.000 3rd Qu.:6.000
NA Max. :9.792e+10 Max. :1.439e+11 Max. :9.628e+09 Max. :0 Max. :6.875e+10 Max. :1.443e+10 Max. :1.344e+10 Max. :893743670 Max. :290161391 Max. :35000000 Max. :73344178 Max. :17190.250 Max. :1891.500 Max. :12791.250 Max. :0 Max. :519.167 Max. :634.917 Max. :203.0000 Max. :348.000 Max. :221.111 Max. :5.00000 Max. :22.2500 Max. :6.943e+10 Max. :1.291e+11 Max. :2.32e+08 Max. :387036296 Max. :516.500 Max. :17038.17 Max. :155.4167 Max. :579.2121 Max. :5.00 Max. :3.00 Max. :6.000 Max. :6.000 Max. :6.000 Max. :1.0000 Max. :1.0000 Max. :0 Max. :0 Max. :1.000000 Max. :1.00000 Max. :6.000 Max. :4.000 Max. :4.000 Max. :6.000 Max. :6.000

Como se puede observar en el resumen mostrado anteriormente, este grupo no tiene ventas fisicas ni ventas electrónicas. Las variables “en_vm_canal4” y “en_tx_canal4” nos indican la ausencia de uso del canal 4 en las entradas para este grupo. Se puede observar claramente que aunque son utilizados los canales 7, 8, 10 y otros, estos datos nos indican que son muy poco utilizados ya que el 75% de los datos está en 0. El canal que más ingresos tiene es el 2 ya que es el promedio más alto de movimientos para este grupo, de la misma manera este canal es el que más cantidad de transacciones tiene. De la misma manera el canal 2 tambien es el que más salidas tiene. Por otro lado se puede decir que los recaudos por personas juridicas y naturales son más pequeños que en los otros 2 grupos.

Los canales que tienen el tercer cuartil en cero son:

  • en_vm_canal7
  • en_vm_canal10
  • en_vm_otros
  • en_tx_canal7
  • en_tx_canal10
  • sal_vm_canal8
  • sal_vm_otros
  • sal_tx_canal8
  • sal_tx_otros
kable(summary(datos[etiqueta_grupo==2,]) )
nit en_vm_canal1 en_vm_canal2 en_vm_canal3 en_vm_canal4 en_vm_canal5 en_vm_canal6 en_vm_canal7 en_vm_canal8 en_vm_canal9 en_vm_canal10 en_vm_otros en_tx_canal1 en_tx_canal2 en_tx_canal3 en_tx_canal4 en_tx_canal5 en_tx_canal6 en_tx_canal7 en_tx_canal8 en_tx_canal9 en_tx_canal10 en_tx_otros sal_vm_canal5 sal_vm_canal2 sal_vm_canal8 sal_vm_otros sal_tx_canal5 sal_tx_canal2 sal_tx_canal8 sal_tx_otros impo_cv expo_vt cxp cxc totalinventory pagos_pj pagos_pn tiene_ventas_fisicas tiene_ventas_electronicas recaudos_pj recaudos_pn rotacion_inventarios rotacion_cxc rotacion_cxp ciclo_negocio ciclo_financiero
Length:951 Min. :0.000e+00 Min. :0.000e+00 Min. :0.000e+00 Min. :0.000e+00 Min. :0.000e+00 Min. :0.000e+00 Min. :0.000e+00 Min. :0.000e+00 Min. :0.000e+00 Min. : 0 Min. :0.000e+00 Min. : 0.00 Min. : 0.00 Min. : 0.00 Min. : 0.00 Min. : 0.000 Min. : 0.000 Min. : 0.00 Min. : 0.000 Min. : 0.000 Min. : 0.0000 Min. : 0 Min. :0.000e+00 Min. :0.000e+00 Min. :0.000e+00 Min. : 0 Min. : 0.000 Min. : 0.00 Min. : 0.000 Min. : 0.0000 Min. :1.000 Min. :1.000 Min. :1.0 Min. :1.000 Min. :1.000 Min. :0.0000 Min. :0.0000 Min. :1 Min. :0 Min. :0.00000 Min. :0.0000 Min. :1.000 Min. :1.000 Min. :1.000 Min. :1.000 Min. :1.000
Class :character 1st Qu.:1.503e+08 1st Qu.:3.654e+08 1st Qu.:4.392e+05 1st Qu.:0.000e+00 1st Qu.:0.000e+00 1st Qu.:2.872e+06 1st Qu.:0.000e+00 1st Qu.:6.760e+05 1st Qu.:4.266e+05 1st Qu.: 0 1st Qu.:0.000e+00 1st Qu.: 28.38 1st Qu.: 24.42 1st Qu.: 1.00 1st Qu.: 0.00 1st Qu.: 0.000 1st Qu.: 2.500 1st Qu.: 0.00 1st Qu.: 1.000 1st Qu.: 1.000 1st Qu.: 0.0000 1st Qu.: 0 1st Qu.:0.000e+00 1st Qu.:1.577e+08 1st Qu.:0.000e+00 1st Qu.: 0 1st Qu.: 0.000 1st Qu.: 10.83 1st Qu.: 0.000 1st Qu.: 0.0000 1st Qu.:1.000 1st Qu.:1.000 1st Qu.:2.0 1st Qu.:2.000 1st Qu.:2.000 1st Qu.:0.3160 1st Qu.:0.2315 1st Qu.:1 1st Qu.:0 1st Qu.:0.00000 1st Qu.:0.0000 1st Qu.:1.000 1st Qu.:1.000 1st Qu.:1.000 1st Qu.:3.000 1st Qu.:3.000
Mode :character Median :5.808e+08 Median :1.224e+09 Median :2.430e+06 Median :3.746e+06 Median :1.874e+07 Median :2.000e+07 Median :0.000e+00 Median :3.466e+06 Median :3.050e+06 Median : 0 Median :0.000e+00 Median : 121.58 Median : 76.17 Median : 3.00 Median : 5.91 Median : 1.300 Median : 8.417 Median : 0.00 Median : 2.200 Median : 2.400 Median : 0.0000 Median : 0 Median :1.127e+07 Median :8.607e+08 Median :0.000e+00 Median : 0 Median : 1.000 Median : 182.33 Median : 0.000 Median : 0.0000 Median :2.000 Median :2.000 Median :3.0 Median :3.000 Median :3.000 Median :0.5080 Median :0.4900 Median :1 Median :0 Median :0.00000 Median :0.0000 Median :3.000 Median :2.000 Median :2.000 Median :4.000 Median :4.000
NA Mean :2.144e+09 Mean :4.557e+09 Mean :2.771e+08 Mean :3.468e+08 Mean :1.718e+09 Mean :1.850e+08 Mean :1.352e+09 Mean :3.642e+07 Mean :1.780e+07 Mean : 1485462 Mean :2.202e+08 Mean : 660.44 Mean : 165.65 Mean : 1260.13 Mean : 1716.12 Mean : 6.522 Mean : 27.819 Mean : 15.94 Mean : 36.048 Mean : 15.011 Mean : 0.2521 Mean : 1126 Mean :1.729e+09 Mean :5.144e+09 Mean :3.704e+06 Mean : 1291315 Mean : 6.672 Mean : 738.10 Mean : 5.329 Mean : 0.7671 Mean :2.179 Mean :1.777 Mean :3.2 Mean :3.735 Mean :3.564 Mean :0.5352 Mean :0.4617 Mean :1 Mean :0 Mean :0.03688 Mean :0.0872 Mean :3.124 Mean :2.434 Mean :2.307 Mean :4.141 Mean :3.925
NA 3rd Qu.:1.647e+09 3rd Qu.:3.313e+09 3rd Qu.:1.694e+07 3rd Qu.:8.350e+07 3rd Qu.:4.300e+08 3rd Qu.:8.255e+07 3rd Qu.:0.000e+00 3rd Qu.:1.411e+07 3rd Qu.:1.008e+07 3rd Qu.: 0 3rd Qu.:0.000e+00 3rd Qu.: 352.12 3rd Qu.: 175.38 3rd Qu.: 23.12 3rd Qu.: 222.92 3rd Qu.: 5.833 3rd Qu.: 28.458 3rd Qu.: 0.00 3rd Qu.: 7.917 3rd Qu.: 7.261 3rd Qu.: 0.0000 3rd Qu.: 0 3rd Qu.:4.540e+08 3rd Qu.:2.992e+09 3rd Qu.:0.000e+00 3rd Qu.: 0 3rd Qu.: 5.750 3rd Qu.: 653.62 3rd Qu.: 0.000 3rd Qu.: 0.0000 3rd Qu.:3.000 3rd Qu.:2.000 3rd Qu.:4.0 3rd Qu.:6.000 3rd Qu.:6.000 3rd Qu.:0.7650 3rd Qu.:0.6820 3rd Qu.:1 3rd Qu.:0 3rd Qu.:0.00000 3rd Qu.:0.0000 3rd Qu.:5.000 3rd Qu.:4.000 3rd Qu.:3.000 3rd Qu.:5.000 3rd Qu.:5.000
NA Max. :1.783e+11 Max. :2.696e+11 Max. :4.391e+10 Max. :6.435e+10 Max. :3.627e+11 Max. :1.452e+10 Max. :4.212e+11 Max. :2.184e+09 Max. :5.408e+09 Max. :180475245 Max. :3.790e+10 Max. :79438.17 Max. :4638.83 Max. :203139.25 Max. :99369.67 Max. :203.750 Max. :657.083 Max. :2446.50 Max. :5492.667 Max. :1722.667 Max. :11.8333 Max. :466385 Max. :3.627e+11 Max. :4.683e+11 Max. :1.971e+09 Max. :622080714 Max. :336.667 Max. :21440.33 Max. :4586.000 Max. :145.5864 Max. :5.000 Max. :3.000 Max. :6.0 Max. :6.000 Max. :6.000 Max. :1.0000 Max. :0.9880 Max. :1 Max. :0 Max. :1.00000 Max. :1.0000 Max. :6.000 Max. :4.000 Max. :4.000 Max. :6.000 Max. :6.000

Como se puede observar en el resumen mostrado anteriormente, este grupo no tiene ventas electrónicas pero si tiene ventas fisicas, y además de eso todas las ventas que realiza son por medio fisico, lo que lo hace el grupo que más recibe transacciones de manera fisica. Se puede observar claramente que aunque son utilizados los canales 7, 10 y otros, estos datos nos indican que son muy poco utilizados para las entradas, ya que el 75% de los datos está en 0, además ocurre lo mismo para las salidas del canal 8 y otros. El canal que más ingresos tiene es el 2 ya que es el promedio más alto de movimientos para este grupo, mientras que el canal 4 es el que más cantidad de transacciones tiene. De la misma manera el canal 2 tambien es el que más salidas tiene. Por otro lado se puede decir que los recaudos por personas juridicas y naturales son mayores que en el grupo 1 pero menores que en el grupo 3.

Los canales que tienen el tercer cuartil en cero son:

  • en_vm_canal7
  • en_vm_canal10
  • en_vm_otros
  • en_tx_canal7
  • en_tx_canal10
  • en_tx_otros
  • sal_vm_canal8
  • sal_vm_otros
  • sal_tx_canal8
  • sal_tx_otros
kable(summary(datos[etiqueta_grupo==3,]))
nit en_vm_canal1 en_vm_canal2 en_vm_canal3 en_vm_canal4 en_vm_canal5 en_vm_canal6 en_vm_canal7 en_vm_canal8 en_vm_canal9 en_vm_canal10 en_vm_otros en_tx_canal1 en_tx_canal2 en_tx_canal3 en_tx_canal4 en_tx_canal5 en_tx_canal6 en_tx_canal7 en_tx_canal8 en_tx_canal9 en_tx_canal10 en_tx_otros sal_vm_canal5 sal_vm_canal2 sal_vm_canal8 sal_vm_otros sal_tx_canal5 sal_tx_canal2 sal_tx_canal8 sal_tx_otros impo_cv expo_vt cxp cxc totalinventory pagos_pj pagos_pn tiene_ventas_fisicas tiene_ventas_electronicas recaudos_pj recaudos_pn rotacion_inventarios rotacion_cxc rotacion_cxp ciclo_negocio ciclo_financiero
Length:132 Min. :0.000e+00 Min. :0.000e+00 Min. :0.000e+00 Min. :0.000e+00 Min. :0.000e+00 Min. :0.000e+00 Min. :0.000e+00 Min. :0.000e+00 Min. :0.000e+00 Min. : 0 Min. :0.000e+00 Min. : 0.00 Min. : 0.00 Min. : 0.0 Min. : 0 Min. : 0.00 Min. : 0.000 Min. : 0.000 Min. : 0.000 Min. : 0.000 Min. : 0.000 Min. : 0.00 Min. :0.000e+00 Min. :0.000e+00 Min. :0.000e+00 Min. : 0 Min. : 0.00 Min. : 0.0 Min. :0.0000 Min. : 0.000 Min. :1.000 Min. :1.000 Min. :1.000 Min. :1.00 Min. :1.000 Min. :0.0150 Min. :0.0000 Min. :0.0000 Min. :0.0000 Min. :0.00000 Min. :0.0000 Min. :1.000 Min. :1.000 Min. :1.000 Min. :1.000 Min. :1.000
Class :character 1st Qu.:3.867e+08 1st Qu.:7.553e+08 1st Qu.:9.912e+05 1st Qu.:0.000e+00 1st Qu.:6.210e+05 1st Qu.:5.687e+06 1st Qu.:0.000e+00 1st Qu.:1.313e+06 1st Qu.:1.883e+06 1st Qu.: 0 1st Qu.:4.335e+06 1st Qu.: 91.46 1st Qu.: 22.27 1st Qu.: 2.0 1st Qu.: 0 1st Qu.: 1.00 1st Qu.: 4.784 1st Qu.: 0.000 1st Qu.: 1.625 1st Qu.: 2.000 1st Qu.: 0.000 1st Qu.: 3.09 1st Qu.:0.000e+00 1st Qu.:6.416e+08 1st Qu.:0.000e+00 1st Qu.: 0 1st Qu.: 0.00 1st Qu.: 140.3 1st Qu.:0.0000 1st Qu.: 0.000 1st Qu.:1.000 1st Qu.:1.000 1st Qu.:2.000 1st Qu.:2.00 1st Qu.:2.000 1st Qu.:0.2338 1st Qu.:0.4195 1st Qu.:1.0000 1st Qu.:1.0000 1st Qu.:0.00000 1st Qu.:0.0000 1st Qu.:2.000 1st Qu.:1.000 1st Qu.:1.000 1st Qu.:4.000 1st Qu.:3.000
Mode :character Median :1.328e+09 Median :2.650e+09 Median :3.911e+06 Median :2.911e+07 Median :2.836e+08 Median :4.046e+07 Median :0.000e+00 Median :6.854e+06 Median :7.512e+06 Median : 0 Median :1.917e+07 Median : 297.62 Median : 121.08 Median : 5.9 Median : 86 Median : 3.75 Median : 20.667 Median : 0.000 Median : 5.000 Median : 5.188 Median : 0.000 Median : 14.79 Median :2.739e+08 Median :2.213e+09 Median :0.000e+00 Median : 0 Median : 3.75 Median : 718.5 Median :0.0000 Median : 0.000 Median :2.000 Median :2.000 Median :2.000 Median :3.00 Median :4.500 Median :0.3795 Median :0.6205 Median :1.0000 Median :1.0000 Median :0.00000 Median :0.0000 Median :4.000 Median :2.000 Median :2.000 Median :5.000 Median :5.000
NA Mean :6.323e+09 Mean :2.562e+10 Mean :8.661e+08 Mean :4.890e+09 Mean :1.682e+10 Mean :2.010e+08 Mean :7.919e+09 Mean :1.415e+08 Mean :3.884e+07 Mean : 3251597 Mean :2.761e+09 Mean : 4496.26 Mean : 329.04 Mean : 4949.3 Mean : 32020 Mean : 13.85 Mean : 46.107 Mean : 9.859 Mean : 63.965 Mean : 41.779 Mean : 0.427 Mean : 3222.45 Mean :1.695e+10 Mean :2.898e+10 Mean :1.819e+08 Mean : 677776 Mean : 13.75 Mean : 3401.8 Mean :0.4931 Mean : 1.196 Mean :1.909 Mean :1.636 Mean :3.061 Mean :3.75 Mean :4.152 Mean :0.4190 Mean :0.5811 Mean :0.8409 Mean :0.8485 Mean :0.08772 Mean :0.2380 Mean :3.742 Mean :2.098 Mean :1.955 Mean :4.417 Mean :4.447
NA 3rd Qu.:4.228e+09 3rd Qu.:1.144e+10 3rd Qu.:2.861e+07 3rd Qu.:3.309e+08 3rd Qu.:1.723e+09 3rd Qu.:1.991e+08 3rd Qu.:0.000e+00 3rd Qu.:3.513e+07 3rd Qu.:2.169e+07 3rd Qu.: 376308 3rd Qu.:1.443e+08 3rd Qu.: 926.44 3rd Qu.: 269.21 3rd Qu.: 42.2 3rd Qu.: 694 3rd Qu.: 12.44 3rd Qu.: 46.354 3rd Qu.: 0.000 3rd Qu.: 21.188 3rd Qu.: 19.273 3rd Qu.: 1.000 3rd Qu.: 159.83 3rd Qu.:1.709e+09 3rd Qu.:8.809e+09 3rd Qu.:3.968e+05 3rd Qu.: 0 3rd Qu.: 12.29 3rd Qu.: 1581.3 3rd Qu.:1.0000 3rd Qu.: 0.000 3rd Qu.:2.000 3rd Qu.:2.000 3rd Qu.:5.000 3rd Qu.:6.00 3rd Qu.:6.000 3rd Qu.:0.5805 3rd Qu.:0.7662 3rd Qu.:1.0000 3rd Qu.:1.0000 3rd Qu.:0.00000 3rd Qu.:0.4798 3rd Qu.:6.000 3rd Qu.:3.000 3rd Qu.:3.000 3rd Qu.:6.000 3rd Qu.:6.000
NA Max. :2.511e+11 Max. :6.953e+11 Max. :5.208e+10 Max. :4.051e+11 Max. :8.070e+11 Max. :3.314e+09 Max. :7.705e+11 Max. :1.004e+10 Max. :2.012e+09 Max. :84786054 Max. :1.600e+11 Max. :289252.33 Max. :3712.58 Max. :438619.6 Max. :3510700 Max. :114.17 Max. :669.667 Max. :333.000 Max. :1547.250 Max. :1763.778 Max. :10.222 Max. :156440.83 Max. :8.070e+11 Max. :8.562e+11 Max. :2.393e+10 Max. :59081394 Max. :104.25 Max. :73057.6 Max. :9.3333 Max. :95.083 Max. :4.000 Max. :3.000 Max. :6.000 Max. :6.00 Max. :6.000 Max. :1.0000 Max. :0.9850 Max. :1.0000 Max. :1.0000 Max. :1.00000 Max. :1.0000 Max. :6.000 Max. :4.000 Max. :4.000 Max. :6.000 Max. :6.000

Al observar el summary para la identificación y caracterización de este grupo encontramos que hay un mayor flujo de movimientos en los canales de entrada, donde el valor medio anual maximo de entrada lo tiene el canal 10. Se oberva que hay mayor flujo de transacciones promedio en este grupo presentandose mayor flujo de transacciones el canal 4. En general observamos que igualmente hay flujo de importaciones catgorizadas y exportaciones categorizadas. Presenta tanto pagos para personas júridicas como para personales. Hay flujo de ventas físicas y electrónicas.

Se verifican las variables con mayor varianza entre grupos:

Se imprimirá un porción de los datos con el fin de mostrar estos cálculos:

etiqueta_grupo <- cutree(cluster_jerar_complete, k=3)
datos_para_var <- datos[,-1] # elimino la identificacion del cliente
datos_para_var['grupo'] <- etiqueta_grupo
datos_para_var <- datos_para_var %>% group_by(grupo) %>% summarise_all(mean)
kable(head(datos_para_var[,1:7]))
grupo en_vm_canal1 en_vm_canal2 en_vm_canal3 en_vm_canal4 en_vm_canal5 en_vm_canal6
1 1099822967 3141106522 55909715 0 765379470 63698201
2 2144074968 4557013014 277094410 346833680 1718011463 185043438
3 6323456098 25621847625 866142204 4889556795 16821937313 201005390

Podemos observar el resultados del promedio de cada varaible por grupo seleccionado, ahora calculamos la varianza entre estos promedios, para obtener las varaibles que tienen mayor disperción entre estos grupos, y seleccionarlas para realizar su correspondiente analisis, serán:

var_ordenadas <- sort(apply(datos_para_var, 2, var), decreasing = T)
kable(names(var_ordenadas)[1:11])
x
sal_vm_canal2
en_vm_canal2
sal_vm_canal5
en_vm_canal5
en_vm_canal7
en_vm_canal1
en_vm_canal4
en_vm_otros
en_vm_canal3
sal_vm_canal8
en_vm_canal6

Pero surge un problema y es que los datos no se encuentran en la misma escala, esto hace que el resultado este sesgado, por lo que realizamos una normalización de tal manera que los valores de cada variable estarán entre cero y uno:

etiqueta_grupo <- cutree(cluster_jerar_complete, k=3)
datos_para_var <- as.data.frame(apply(datos[,-1], 2, normalizedRanks))
datos_para_var['grupo'] <- etiqueta_grupo
datos_para_var <- datos_para_var %>% group_by(grupo) %>% summarise_all(mean)
kable(head(datos_para_var[,1:7]))
grupo en_vm_canal1 en_vm_canal2 en_vm_canal3 en_vm_canal4 en_vm_canal5 en_vm_canal6
1 0.0043802 0.0045177 0.0010736 0.0000000 0.0009485 0.0043858
2 0.0085390 0.0065542 0.0053209 0.0008562 0.0021290 0.0127408
3 0.0251838 0.0368509 0.0166321 0.0120701 0.0208459 0.0138399

Ahora podemos observar que los resultados son diferentes:

var_ordenadas <- sort(apply(datos_para_var, 2, var), decreasing = T)
kable(names(var_ordenadas)[1:11])
x
grupo
tiene_ventas_fisicas
tiene_ventas_electronicas
recaudos_pn
totalinventory
pagos_pn
rotacion_inventarios
pagos_pj
ciclo_financiero
rotacion_cxc
rotacion_cxp

Observaremos graficamente sus resultados:

df_var <- data.frame(variables = names(var_ordenadas), varianzas = var_ordenadas)

ggplot(df_var[-1,], aes(x = reorder(variables, -varianzas), y=varianzas))+
  geom_bar(stat='identity', fill='white', color='blue' )+
theme(axis.text.x = element_text(angle = 90, hjust = 1))+
labs(title = 'Calculo entre promedios de los grupos', y='Varianza', x = ' Variables')

Observamos claramente la lista que se imprimió anteriormente, mostrando ventas físicas y electrónicas con mayor variabilidad, seguidas de rotación de inventarios, total de inventario y así sucesivamente.

Para realizar un analisis rápido de los grupos, basados en las variables con mayor varianza, tomaremos las primeras 10 varaibles. Ahora ilustraremos un grafico para poder describirlos:

# se toman las primeras 10 variables
primeras_10_variables <- names(var_ordenadas)[1:11]

# manipulamos los datos para  graficar con ggplot2 
dff <- datos_para_var[,primeras_10_variables] %>% 
  pivot_longer(!grupo, names_to = 'variables', values_to = 'promedios') # ; dff %>% head # grupo como character:
dff$grupo <- as.character(dff$grupo)

# graficamos
ggplot(data =dff, aes(x=grupo, y=promedios, fill=variables))+
geom_bar(stat = 'identity', position = 'dodge')+
theme_minimal()+
theme(axis.text.x = element_text(angle = 0, hjust = 1))+
labs(title = 'Diferencia entre variables con mayor varianza\n entre promedios normalizados por grupo', y='Promedio')

De esta manera podemos observar diferencias entre grupos, tales como la diferencia en el incremento de la variable “recaudos_pn” que son proporción de recaudos a personas naturales, que es menor en el grupo 1, luego crece en el grupo 2 y finalmente es mayor en el grupo 3, podemos notar tambien este patron de incremento en la variable “totalinventory”,“pagos_pj”, “pagos_pn”, “rotacion_inventario”. Para el caso de “rotacion_cxc” vemos resultados muy similares para los grupos 1 y 2 y menor que estos en el grupo 3. Ahora para “rotacion_cxp” se observa que su valor maximo se encuentra en el grupo 2, luego en el grupo1 y el menor será el grupo 3. Es claro además que los siclos financientos más largos corresponden al grupo 3. Tambien podemos notar que el grupo 1 no presenta ventas fisicas ni tampoco ventas electrónicas, que el grupo 2 tien ventas físicas, y que el grupo 3 tiene tanto ventas fisicas como electrónicas. De esta manera podemos realizar una comparación de cada grupo, basados en las variables que tienen mayor varaibilidad en sus promedios, sin embargo, para poder tener una mejor visión de las demás varaibles y poder tomar un aprovechamiento de estos grupos con el fin de realizar estrategias para tratar cada tipo de agrupación segun su comportamiento, graficaremos y compararémos todas las variables en sus escalas originales.

En otro tipo de medida de tendencia central como la mediana, podemos obtener algo de diferencia entre los resultados hallados en la selección de variables del caso anterior:

Obserevemos graficamente sus resultados de las varainzas por grupos en cada variables:

datos_para_var <- as.data.frame(apply(datos[,-1], 2, normalizedRanks))
datos_para_var['grupo'] <- etiqueta_grupo
datos_para_var <- datos_para_var %>% group_by(grupo) %>% summarise_all(median)
var_ordenadas <- sort(apply(datos_para_var, 2, var), decreasing = T)
primeras_10_variables <- names(var_ordenadas)[1:11]
df_var <- data.frame(variables = names(var_ordenadas), varianzas = var_ordenadas)

ggplot(df_var[-1,], aes(x = reorder(variables, -varianzas), y=varianzas))+
  geom_bar(stat='identity', fill='white', color='blue' )+
theme(axis.text.x = element_text(angle = 90, hjust = 1))+
labs(title = 'Calculo entre promedios de los grupos', y='Varianza', x = ' Variables')

Podemos ver que como en el caso anterior, las variables con mayor variabilidad entre sus medias son tener ventas físicas y tener ventas electrónicas y algunas otras que difieren solo un poco al resultado de los promedios.

Ahora veamos las variables en sus medias normalizadas:

# manipulamos los datos para  graficar con ggplot2 
dff <- datos_para_var[,primeras_10_variables] %>% 
  pivot_longer(!grupo, names_to = 'variables', values_to = 'promedios')
# grupo como character:
dff$grupo <- as.character(dff$grupo)

# graficamos
ggplot(data =dff, aes(x=grupo, y=promedios, fill=variables))+
geom_bar(stat = 'identity', position = 'dodge')+
theme_minimal()+
theme(axis.text.x = element_text(angle = 0, hjust = 1))+
labs(title = 'Diferencia entre variables con mayor varianza\n entre medianas normalizadas por grupo', y='Mediana')

Podemos obserar que las variables de “ciclo_financiero” y “ciclo_negocio” son iguales en el grupo 1 y 2 mientras que estas son mayores para el grupo 3. Se observa que “cxp” es mayor que en el grupo 2 e igual entre 1 y 3. Para “en_tx_canal6” vemos que la entradas promedio del canal 6 son menores en grupo 1, crece levemente en grupo 2 y crece un poco más en el grupo 3. Las demás varaibles son iguales a las seleccionadas para la media, y sus conclusiones son similares.

A continuación se realizará una comparación de todas las variables, en sus escalas originales, con el proposito de conocer cual el comportamiento de cada grupo en estas, a fin de tomar desiciones y actuar estrategicamente en relación a grupo-varaible, como retención del cliente mediante ofertas o cualquier estrategia que permita a la empresa obtener el máximo provecho del estudio.

Varaibles numéricas:

Comparacion de media:

EL siguiente código manipula los datos de tal manera que nos permita realizar analisis sobres los datos sin normalizar:

# k = 3 grupos y sus sub-bases
df1 <- datos[etiqueta_grupo==1,]
df2 <- datos[etiqueta_grupo==2,]
df3 <- datos[etiqueta_grupo==3,]

# aplico la media a toda las variables, se inluyen las categoricas:
mean1 <- apply(df1[,-1], 2, mean)
mean2 <- apply(df2[,-1], 2, mean)
mean3 <- apply(df3[,-1], 2, mean)

# unificamos las medias por varaible(fila) en este nuevo data frame
df <- data.frame(row.names  = names(mean1), mean1,mean2,mean3)

datos_num <- datos[,c(2:31, 37, 38,41,42)]  #tomo todas las varaibles numericas como lo hice inicialmente
df_num <- df[names(datos_num),] # selecino las V. numericas en df
mean_data <- apply(datos_num, 2, mean) # todo la medias de todos los datos, con el proposito de conparar con cada grupo

kable(head(cbind(df_num, mean_data))) # uno los retultados
mean1 mean2 mean3 mean_data
en_vm_canal1 1099822967 2144074968 6323456098 1853339862
en_vm_canal2 3141106522 4557013014 25621847625 5073029898
en_vm_canal3 55909715 277094410 866142204 198004356
en_vm_canal4 0 346833680 4889556795 436748915
en_vm_canal5 765379470 1718011463 16821937313 2120246761
en_vm_canal6 63698201 185043438 201005390 123493933

Las variables se pueden observar como los nombres de cada fila, mean1 es el promedio del grupo 1, mean2 del grupo 2 y mean 3 del grupo 3, mean data es el promedio de todos los datos sin agrupar (esto con el fin de compararlo con los resultados de los grupos, se mensionará como “el promedio de todos los datos” o “promedio global”).

Graficos de lineas para sus promedios:

Dado que las varaibles se encuentran en diferentes escalas, será necesario observarlas por grupos (no todas estarán es un solo gráfico) con el fin de que nos permita conocer el comportamientos de los grupos, a fin de compararlos:

# aqui justo los promedio por grupos, previamente hallados con el promedio de todos los datos
dff <- cbind(df_num, mean_data)

# aqui estan las variables que pueden ser observadas en esta escala:
 dff <- dff[c(1:11, 23:26),]

fun_graph <- function(x, titulo='Promedio por grupo', y='promedios'){
  
  x['variables'] <- rownames(x)
  rownames(x) <- 1:nrow(x)

  x <- x %>% 
  pivot_longer(!variables, names_to = 'grupos', values_to = 'promedios')


  x1 <- ggplot(x, aes(x=variables, y=promedios, group = grupos, color = grupos))+
  geom_line()+
  geom_point()+
  scale_color_brewer(palette="Dark2")+
  theme_minimal()+
  theme(axis.text.x = element_text(angle = 60, hjust = 1))+
  labs(title = titulo, y=y)

  # esta grafica no se usará para los resultados finales, es un grafico de barra si quiere lo agrega al return     para verlo.
  x2 <- ggplot(data =x, aes(x=variables, y=promedios, fill=grupos))+
  geom_bar(stat = 'identity', position = 'dodge')+
  theme_minimal()+
  theme(axis.text.x = element_text(angle = 60, hjust = 1))+
  labs(title = titulo, y=y)
  
  return(list(x1))
}

fun_graph(dff)[[1]]

Se puede observar que en general el grupo 3 tiene valores en promedio más altos para cada variable, además es mayor que el promedio de todo los datos(color verde) esto nos permite ver que es un grupo con pocos ceros en comparación a los otros grupos que puedan afectar su promedio, tambien es claro que el grupo 1 tiende a ser el menor en cada varaible.

dff <- cbind(df_num, mean_data) # "en_vm_canal10"
dff <- dff[c("en_vm_canal3","en_vm_canal6"),]
fun_graph(dff)[[1]]

Podemos observar que los valores de entreada promedio de estos tikets siempres son mayores en el grupo 3, seguidos del 2 y finalmente el grupo 1. Vemos tambien el cambio del comportamiento de cada grupo respecto a el promedio globalde todos los datos.

dff <- cbind(df_num, mean_data)
dff <- dff[c("en_vm_canal8",  "en_vm_canal9"),]
fun_graph(dff)[[1]]

Para este caso podemos observar que los resultados en “en_vm_canal9” son relativamente similares, a diferencia de las otras dos variables donde podemos ver mayor dispersión.

# dff <- scale(dff, scale = T, center = T)
# dff <- as.data.frame(dff)
dff <- cbind(df_num, mean_data)
dff <- dff[c("en_tx_canal1",  "en_tx_canal3",  "en_tx_canal4", "en_tx_otros", "sal_tx_canal2" ),]
fun_graph(dff)[[1]]

Podemos notar que el comportamiento es similar a lo concluido hasta ahora, la diferencia observada, son cambios entre el promedio global y el grupo 2 ena lgunas variables.

dff <- cbind(df_num, mean_data)
dff <- dff[c("en_tx_canal2","en_tx_canal5","en_tx_canal6","en_tx_canal7", "en_tx_canal8", "en_tx_canal9","sal_tx_canal5"),]
fun_graph(dff)[[1]]

La diferencia más significativa que hallamos es en la variable “en_tx_cala7” el grupo dos muestra un mayor promedio que el grupo 3. Lo demás se mantiene igual. 10, 5, sal 8 sal otro

dff <- cbind(df_num, mean_data)
dff <- dff[c("en_tx_canal10","pagos_pj",   "pagos_pn",      "recaudos_pj"   ,"recaudos_pn" ),]
fun_graph(dff)[[1]]

En este caso se observa que la proporción de los pagos a personas jurídicas (pagos_pj) es mayor par el grupo uno, y que el menor resultado lo tiene el grupo 3. Las demás variables muestran las mismas conclusiones halladas, donde el mayor el es grupo 3, luego el 2 y finalmente el grupo 1.

dff <- cbind(df_num, mean_data)
dff <- dff[c("sal_tx_canal8","sal_tx_otros" ),]
fun_graph(dff)[[1]]

Podemos notar que la variable de salida de transacciones mensual promedio del canal 8 (“sal_tx_canal8”) es mayor para el grupo 2 y que el grupo 3 ocupa el segundo lugar. Para “sal_tx_otros” notamos que el grupo 1 es el segundo mayor y no el menor como se ha venido observando.

Comparación de desviación por variable numerica:

sd1 <- apply(df1[,-1] , 2,sd) # function(x) x %>% normalizedRanks %>%  sd
sd2 <- apply(df2[,-1], 2, sd)
sd3 <- apply(df3[,-1], 2, sd)


df <- data.frame(row.names  = names(sd1), sd1,sd2,sd3)

datos_num <- datos[,c(2:31, 37, 38,41,42)]  #todo slos numericos
# names(datos_num)
df_num <- df[names(datos_num),]
sd_data <- apply(datos_num, 2,  sd)
dff <- cbind(df_num, sd_data)
dff <- dff[c(1:11, 23:26),]

dat <- c("en_vm_canal1"  ,"en_vm_canal2"  ,"en_vm_canal3",  "en_vm_canal4" , "en_vm_canal5",  
 "en_vm_canal7" , "en_vm_otros"  , "sal_vm_canal5",
"sal_vm_canal2" ,"sal_vm_canal8"  )
dff <- dff[dat,]

fun_graph(dff, 'Desviación por grupo', 'Desviaciones')[[1]]

Se puede observar en las variables representadas en el eje x que la variabilidad del grupo 3 es en general mayor y que las variables que muestran menor dispersión entre grupos son, “en_vn_canal3” y “sal_vm_canal8”, por lo que podríamos definir que las variables tienen un comportamiento variable similar en estos grupos(se distancian de la media, en promedio, de la manera similar).

dff <- cbind(df_num, sd_data)
dat <- c("sal_vm_otros" ,'en_vm_canal10')
dff <- dff[dat,]

fun_graph(dff, 'Desviación por grupo', 'Desviaciones')[[1]]

Para este caso se puede notar que en la variable “en_vm_canal10” la mayor variabilidad la tienen el grupo 3 y que visualmente los resultados se ven separados, pero en el caso de “sal_vm_otros” el grupo con mayor variabilidad es el 2 y el de menor variabilidad pasa a ser el 3. Asumimos que los resultados son significativamente diferentes ya que su eje y se encuentra en escala de millones y los punto debidamente separados.

dff <- cbind(df_num, sd_data)
dff <- dff[c( 'en_vm_canal6','en_vm_canal8', 'en_vm_canal9'),]
fun_graph(dff, 'Desviación por grupo', 'Desviaciones')[[1]]

Para este caso podemos observar que los resultados en “en_vm_canal9” son relativamente similares, a diferencia de las otras dos variables donde podemos ver mayor dispersión.

dff <- cbind(df_num, sd_data)
dff <- dff[c("en_tx_canal1",  "en_tx_canal3",  "en_tx_canal4", "en_tx_otros", "sal_tx_canal2"),]
fun_graph(dff, 'Desviación por grupo', 'Desviaciones')[[1]]

Podemos notar que los resultados para “en_tx_otro” y “sal_tx_canal2”, muestra en comparación a las demás variables, un comportamiento mas similar entre los grupos que las demás variables.

dff <- cbind(df_num, sd_data)
dff <- dff[c("en_tx_canal2","en_tx_canal5","en_tx_canal6","en_tx_canal7", "en_tx_canal8", "en_tx_canal9","sal_tx_canal5"),]
fun_graph(dff, 'Desviación por grupo', 'Desviaciones')[[1]]

Se observa que las variables “en_tx_canal5” y “sal_tx_canal5” muestran una desviación similar entre grupos. En las demás variables podemos observar que presentan mayor variabilidad intercambiando entre los grupos 2 y 3, y que a diferencia de éstos dos grupos, el grupo 1 parece casi siempre tener menor variabilidad.

dff <- cbind(df_num, sd_data)
dff <- dff[c("sal_tx_canal8" ,"sal_tx_otros","en_tx_canal5" ),]
fun_graph(dff, 'Desviación por grupo', 'Desviaciones')[[1]]

Para el caso de la variable “en_tx_canal5” observamos que los resultados entre los tres grupos son similares, incluyendo la desviación de todos los datos es menor a estos. Ahora para “sal_tx_canal8” notamos que los grupos 1 y 3 pueden observarse de manera similar pero que la variación observada en el grupo 2 es significativamente mayor a los demás y finalmente en “sal_tx_otros” notamos que los grupos 1, 2 y 3 son similares y que la desviación de todos los datos (mean_data) sería similar a estos grupos.

dff <- cbind(df_num, sd_data)
dff <- dff[c("en_tx_canal10","pagos_pj",   "pagos_pn",      "recaudos_pj"   ,"recaudos_pn" ),]
fun_graph(dff, 'Desviación por grupo', 'Desviaciones')[[1]]

De las variables observadas, tenemos que las desviaciones entre “pagos_pj” y “pagos_pn” son similares entre grupos, y la variable que presenta mayor diferencia entre la variabilidad por grupo es “en_tx_canal10”.

Comparación por mediana en variables numéricas:

df1 <- datos[etiqueta_grupo==1,]
df2 <- datos[etiqueta_grupo==2,]
df3 <- datos[etiqueta_grupo==3,]

max2 <- apply(df2[,-1], 2, median)
max3 <- apply(df3[,-1], 2, median)
max1 <- apply(df1[,-1], 2, median)

df <- data.frame(row.names  = names(max1), median1= max1,  median2 = max2, median3 = max3)

datos_num <- datos[,c(2:31, 37, 38,41,42)]  #todo slos numericos
# names(datos_num)
df_num <- df[names(datos_num),]
median_data <- apply(datos_num, 2, median)
dff <- cbind(df_num, median_data)

dat <- c("en_vm_canal1"  ,"en_vm_canal2"  ,"en_vm_canal3",  "en_vm_canal4" , "en_vm_canal5",  
 "en_vm_canal7" , "en_vm_otros"  , "sal_vm_canal5",
"sal_vm_canal2" ,"sal_vm_canal8")
dff <- dff[dat,]

fun_graph(dff, 'Mediana por grupo', 'Valores')[[1]]

La entrada y la salida del canal 2 tienen en promedio el mismo flujo.

dff <- cbind(df_num, median_data)
dat <- c("sal_vm_otros" ,'en_vm_canal10')
dff <- dff[dat,]

fun_graph(dff, 'Mediana por grupo', 'Valores')[[1]]

Para estos canales podemos observar que no son utilizados o que se utilizan poco.

dff <- cbind(df_num, median_data)
dff <- dff[c( 'en_vm_canal6','en_vm_canal8', 'en_vm_canal9'),]

fun_graph(dff, 'Mediana por grupo', 'Valores')[[1]]

Podemos ver apartir de la mediana del grupo 3, que este tiene flujo mayor en comparación a los demas canales.

dff <- cbind(df_num, median_data)
dff <- dff[c("en_tx_canal1",  "en_tx_canal3",  "en_tx_canal4", "en_tx_otros", "sal_tx_canal2"),]

fun_graph(dff, 'Mediana por grupo', 'Valores')[[1]]

A partir de la mediana del grupo se puede inferir que esta presenta mayor flujo en estos canales.

dff <- cbind(df_num, median_data)

dff <- dff[c("en_tx_canal2","en_tx_canal5","en_tx_canal6","en_tx_canal7", "en_tx_canal8", "en_tx_canal9","sal_tx_canal5"),]

fun_graph(dff, 'Mediana por grupo', 'Valores')[[1]]

A partir de la mediana del grupo se puede inferir que esta presenta mayor flujo en estos canales, siendo máximo el canal 2.

dff <- cbind(df_num, median_data)

dff <- dff[c("sal_tx_canal8" ,"sal_tx_otros","en_tx_canal5" ),]

fun_graph(dff, 'Mediana por grupo', 'Valores')[[1]]

Para la varaible en_tx_canal5 se observa el mismo comportamiento anterior. Para los demas canales no se observan diferencias entre las medianas de los grupos.

dff <- cbind(df_num, median_data)
dff <- dff[c("en_tx_canal10","pagos_pj",   "pagos_pn",      "recaudos_pj"   ,"recaudos_pn" ),]

fun_graph(dff, 'Mediana por grupo', 'Valores')[[1]]

La mediana del grupo 1 es superior a las demas en los pagos a personas juridicas, y la del grupo 3 la supera en pagos de personas naturales, podriamos suponer que debido a que el grupo 3 recibe esta proporción mayor de pagos de personas naturales se tiene mayor flujo en general en la mayoria de los canales y productos.

Graficas para analizar varaibles categoricas:

#Se vuelve a generar el grupo con variables categóricas a partir de los datos originales para tener los valores sin normalizar
datos_cat2 <- datos[,c(32:47)]
datos_cat2 <- datos_cat2[,-c(6,7,10,11)] 


dc1 <- datos_cat2[etiqueta_grupo==1,]
dc2 <- datos_cat2[etiqueta_grupo==2,]
dc3 <- datos_cat2[etiqueta_grupo==3,]

Se crea la siguiente función:

graficaCategorica <- function(x){
  
  d1 <- table(dc1[[x]])
  d2 <- table(dc2[[x]])
  d3 <- table(dc3[[x]])
#Debido a que se tratan de variables binarias y algunos grupos no tienen al menos 1 valor con cada categoría, se tratarán con casos especiales
  if (x == 'tiene_ventas_fisicas'){
  data_cate <- data.frame(frecuencias = c(d1,0,0,d2,d3), nivel_cate= rep(0:max(datos_cat2[[x]]),3), grupos=c(rep('grupo1',2),rep('grupo2',2),rep('grupo3',2))) 
  data_cate$nivel_cate <- as.character(data_cate$nivel_cate)

  ggplot(data =data_cate, aes(x=grupos, y=frecuencias, fill=nivel_cate))+
    geom_bar(stat = 'identity', position = 'dodge')+
    theme_minimal()+
    theme(axis.text.x = element_text(angle = 60, hjust = 1))+
    labs(title = paste(x, 'por grupo'))+
    geom_text(aes(label=frecuencias), vjust=-0.30, color="black", size=3.5, position = position_dodge(width = 1))
  }
  
  else if (x == 'tiene_ventas_electronicas'){
  data_cate <- data.frame(frecuencias = c(d1,0,d2,0,d3), nivel_cate= rep(0:max(datos_cat2[[x]]),3), grupos=c(rep('grupo1',2),rep('grupo2',2),rep('grupo3',2))) 
  data_cate$nivel_cate <- as.character(data_cate$nivel_cate)

  ggplot(data =data_cate, aes(x=grupos, y=frecuencias, fill=nivel_cate))+
    geom_bar(stat = 'identity', position = 'dodge')+
    theme_minimal()+
    theme(axis.text.x = element_text(angle = 60, hjust = 1))+
    labs(title = paste(x, 'por grupo'))+
    geom_text(aes(label=frecuencias), vjust=-0.30, color="black", size=3.5, position = position_dodge(width = 1))
  }
  
  #Debe manejarse con un caso en específico porque uno de los grupos  no tiene ningún valor con categoría 5
  else if (x == 'impo_cv'){
  data_cate <- data.frame(frecuencias = c(d1,d2,d3,0), nivel_cate= rep(1:max(datos_cat2[[x]]),3), grupos=c(rep('grupo1',max(datos_cat2[[x]])),rep('grupo2',max(datos_cat2[[x]])),rep('grupo3',max(datos_cat2[[x]])))) 
  data_cate$nivel_cate <- as.character(data_cate$nivel_cate)

  ggplot(data =data_cate, aes(x=grupos, y=frecuencias, fill=nivel_cate))+
    geom_bar(stat = 'identity', position = 'dodge')+
    theme_minimal()+
    theme(axis.text.x = element_text(angle = 60, hjust = 1))+
    labs(title = paste(x, 'por grupo'))+
    geom_text(aes(label=frecuencias), vjust=-0.30, color="black", size=3.5, position = position_dodge(width = 1))
  }
  
  else{
    data_cate <- data.frame(frecuencias = c(d1,d2,d3), nivel_cate= rep(1:max(datos_cat2[[x]]),3),   grupos=c(rep('grupo1',max(datos_cat2[[x]])),rep('grupo2',max(datos_cat2[[x]])),rep('grupo3',max(datos_cat2[[x]])))) 
  data_cate$nivel_cate <- as.character(data_cate$nivel_cate)
  
  ggplot(data =data_cate, aes(x=grupos, y=frecuencias, fill=nivel_cate))+
    geom_bar(stat = 'identity', position = 'dodge')+
    theme_minimal()+
    theme(axis.text.x = element_text(angle = 60, hjust = 1))+
    labs(title = paste(x, 'por grupo'))+
    geom_text(aes(label=frecuencias), vjust=-0.30, color="black", size=3.5, position = position_dodge(width = 1))
  }
}

A continuación se analizarán las distribuciones de las variables categóricas, no se realizará una descripción del comportamiento de las variables en las que se observe una distribución similar en los 3 grupos.

graficaCategorica('impo_cv') 

Al observar la distribución de empresas según el nivel de importaciones y compras de cada grupo observamos que en términos generales tienen una distribución similar, variando únicamente en que en el grupo 1 y el grupo 3 el nivel con más empresas es el 1 y en el grupo 2 el nivel más ocupado es el 2.

graficaCategorica('expo_vt')

En la distribución por ventas se observa que las distribuciones en el grupo 1 y 3 son bastante similares entre sí, sin embargo en el grupo 2 se encuentra una cantidad mucho mayor de empresas con un nivel de 2 con respecto a aquellas con nivel 1.

graficaCategorica('cxc')

En la variable cuentas por cobrar es de resaltar que a diferencia de las 2 primeras variables, esta vez son los grupos 2 y 3 los que presentan una mayor similitud entre su distribución, teniendo una mayor cantidad de empresas pertenecientes al nivel 6 a comparación del grupo 1 en el cuál la mayor cantidad se encuentran en el nivel 2.

graficaCategorica('totalinventory')

En la variable de total de inventarios ocurre un fenómeno similar al de cuentas por cobrar, solo que en este caso la superioridad en cuanto a cantidad de las empresas de nivel 6 es aún más notoria en el grupo 3 y menos notoria en el grupo 2.

graficaCategorica('tiene_ventas_fisicas') 

graficaCategorica('tiene_ventas_electronicas') 

La variable que representa el si la empresa tiene o no puntos de venta físicos parece ser bastante decisoria en cuanto la separación de los grupos al menos entre el grupo 1 y los otros 2, siendo el grupo 1 compuesto únicamente de empresas sin puntos de venta físicos y el 2 únicamente de empresas que sí los tienen, el grupo 3 compuesto en su mayoría de empresas con puestos físicos de venta pero algunas que no los poseen, sin embargo es interesante también el comportamiento de la variable que indica si la empresa tiene ventas electrónicas o no puesto que el grupo 1 entonces está compuesto de empresas que no tienen puntos de venta físicos ni electrónico, el grupo 2 de empresas que tienen puntos de ventas físicos pero no electrónicos y el grupo 3 en su mayoría por empresas que tienen tanto puestos físicos como ventas electrónicas, con algunos sin puesto físico ni ventas electrónicas y uno solo con ventas electrónicas.

graficaCategorica('rotacion_inventarios')

En la variable de rotación de inventarios el grupo 3 presenta una mayor proporción de empresas en el grupo 6 que los otros 2 grupos pero no parece ser una diferencia muy significativa ya que en los otros 2 grupos esta categoría también presenta un alto volumen de empresas.

graficaCategorica('rotacion_cxp')

La distribución de rotación de cuentas por pagar, al igual que las cuentas por cobrar no parecen ser un factor muy decisivo en cuanto a la distinción entre grupos siendo el nivel más común en los 3 grupos el 1.

graficaCategorica('rotacion_cxc')

En la variable rotación de cuentas por cobrar, al igual que al analizar el número de cuentas por cobrar se observa una distribución constante entre los 2 primeros grupos siendo diferentes estos 2 con respecto al 3, en este caso debido al número de cuentas con un nivel categórico de rotación alto en los 2 primeros grupos. Esto sugiere como era de esperarse que ambas variables están relacionadas incluso entre los 3 grupos y que tanto las cuentas por cobrar, como la rotación de estar podrían ser un factor útil al diferenciar a las empresas de grupo 3 del resto.

graficaCategorica('ciclo_negocio')

Los 3 grupos presentan una distribución muy similar, con los niveles 1, 2 y 3 de cada grupo teniendo una cantidad de empresas mucho mayor comparadas con las pertenecientes a los 3 niveles más altos.

graficaCategorica('ciclo_financiero')

De manera similar al ciclo de negocio, la distribución del ciclo financiero de los diferentes grupos es bastante proporcional, por lo que no sería un buen indicador para proyectos que busquen un grupo específico de acuerdo a la distribución de grupos propuesta, sino para aquellos que requieran un enfoque general.

Conclusiones:

Como pudo observarse en todo el desarrollo estadístico, el grupo 3 tiende a utilizar en mayor cantidad casi todos los canales. También se puede notar que existe una fuerte diferencia entre los grupos basados en la presencia o no de ventas físicas y electrónicas por lo que podríamos principalmente diferenciarlos de esta manera:

Grupo 1: Son los clientes que no realizan ni ventas físicas, ni electrónicas, y que en general utilizan en menor medida los canales y productos como puede evidenciarse en el promedio y mediana del grupo, exepto en pagos_pj donde es mayor.

Grupo 2: Son clientes que tienen ventas físicas pero no electrónicas, en general debido a su promedio y media se observa que los valores de ticket de entrada y salida son mayores que en el grupo 1, y mayores que ambos grupos en en_tx_canal2 y sal_tx_canal8 .

Grupo 3: Son clientes que tienen ventas tanto físicas como electrónicas, y que en su gran mayoría en cuanto al uso de canales y productos tienen valores significativamente mayores en sus tickets que los demás grupos.

Referencias:

[1] James, G., Witten, D., Hastie, T. y Tibshirani, R. (2021). An Introduction to Statistical Learning with Applications in R. Springer New York. https://web.stanford.edu/~hastie/ISLRv2_website.pdf

[2] Comparing hierarchical clustering dendrograms obtained by different distances & methods. (s. f.). Cross Validated. https://stats.stackexchange.com/questions/63546/comparing-hierarchical-clustering-dendrograms-obtained-by-different-distances/63549#63549

[3] Ospina, J. (2021) Lineamientos para el segundo trabajo de Aprendizaje Estadístico Departamento de Ciencias de la Computación y de la Decisión Universidad Nacional de Colombia – Semestre 01 de 2021