############################################################################################################# ############################################################################################################# ############################################################################################################# ############################################################################################################# ############################# ############################# ############################# Comenzamos ############################# ############################# ############################# ############################################################################################################# ############################################################################################################# ############################################################################################################# ############################################################################################################# ############################################################################################################# # Mundo No Supervisado versus Mundo Supervisado. # Llamamos install.packages("readxl") # Instalamos paquete library(readxl) # Corremos libreria Master <- read_excel("E:/PROYECTOS/DOCENCIA_/INAP/Versión1_/Adrian_Modulos_/Clustering_/Data_set_a_Utilizar_/Indicadores_Econo_y_Salud_.xlsx", sheet = 1) # La funcion o comando header= encabezado, al colocarle TRUE, significa que la data lleva una etiqueta o nombre de las variables. dim(Master) # Revisamos Dimensiones str(Master) # Revisamos Clase de las Variables variable.names(Master) # Respaldamos, Convertimos en tipo datframe, Indexamos, Convertimos todo en clase numeric y Eliminamos Vectores. Master_respaldo1 <- Master Master <- as.data.frame(Master) # Convierto Matriz a tipo dataframe dado que si continuo con tipo tabble, podrían presentarse problemas. str(Master) # Consulto conversión y clase. rownames(Master) <- Master$ID #Indexamos View(Master) # Consultamos Index str(Master) # Revisamos Clases # Eliminamos Variables View(Master) # Consultamos Index variable.names(Master) Master <- Master[ ,!colnames(Master)=="Pais"] Master <- Master[ ,!colnames(Master)=="ID"] variable.names(Master) # Revisamos str(Master) # Revisamos Clases View(Master) # Consultamos Index View(Master$`Tasa_Mortalidad_Muertes/1000_habitantes`) ################# ################# ################# Escalamos ################# ################# ################# Master_respaldo2 <- Master # Respaldamos # Master <- Master_respaldo2 variable.names(Master) str(Master) Master <- as.data.frame(scale(Master)) # Escalamos. Explicar el escalamiento (función scale y por que no otra) View(Master) # Revisamos str(Master) ####################################################################################################################### ####################################################################################################################### ############################## ##################################### ############################## Estudiamos las Correlaciones ##################################### ############################## ##################################### ####################################################################################################################### ####################################################################################################################### # Correspondería un estudio de correlaciones si mi objetivo es determinar cuales son las variables que están explicando la # variable dependiente. Lo que no es objeto de este estudio. Ya que es un proceso No Supervisado. # No obstante si quiero clusterizar sobre valorando el peso de la información de ciertas variables para un modelo no supervisado, dado que # la realidad que envuelve a un fenómeno determinado, presenta variables que entregan la misma información (la repite), puedo evadir # el estudio de correlaciones y dejarlas, argumentando que el fenómeno en estudio se relaciona con estas variables y son imprescindibles # conservarlas por motivo de negocio. # Para argumentar lo anterior # sería relevante volver a la etapa de análisis exploratorio y preguntarle al analista y al conocedor del negocio, por qué se # seleccionaron estas variables (y sin duda teenr claro también por que se eliminaron otras). Esta discusión entre el analista de datos # y el conocedor del negocio # es fundamental. (explicar con el ejemplo de cuando jugó Chile versus la contaminación ambiental, aquél día se dispararon todos los # índices de contaminación, influyendo en el hacinamiento de centros de urgencia) ya que muchas veces la realidad, sí # le da importancia a una determinada variable repitiendo incluso la información de otra de ellas. # Por el contrario, si el objetivo de mi estudio es "depurar", "limpiar", o buscar la parsimonia, para así determinar cuales variables # están influyendo de mayor manera en la variable dependiente o simplemente "como están determinando o sesgando el modelo de datos", # elimino aquellas variables que están correlacionadas entre ellas fuertemente (igual o superior a 0.8), dejando la que tiene mayor poder # predictivo, y en segundo termino, la que tiene mayor información. Para esto la función "cor" y la Matriz "CorrMat" es la que trabajaremos. # Para este caso, haré estudio de correlación y eliminaré aquellas que se encuentran correlacionadas, por criterio de correlación fuerte, # mayor a 80%. # Estudiamos Correlación. Preparamos. #Redundancia (no se ve correlación con las variables como están) #install.packages("corrplot") library(corrplot) str(Master) #install.packages("dplyr") library(dplyr) sum(is.na(Master)) # Reviso nuevamente que no hayan NA # Corremos funciónd de correlación variable.names(Master) str(Master) CorrMat <- cor(Master[,1:11]) #Correlación corrplot.mixed(CorrMat) # Matriz de Correlación str(CorrMat) #Matriz de Correlaciones Matriz_de_Correlaciones_ <- data.frame(CorrMat) Matriz_de_Correlaciones_respaldo <- Matriz_de_Correlaciones_ # Respaldo Matriz_de_Correlaciones_ <- abs(Matriz_de_Correlaciones_) # Dejamos en Valores Absolutos str(Matriz_de_Correlaciones_) View(Matriz_de_Correlaciones_) # Crearemos un Datframe a partir de la matriz de correlación CorrMat para identificar rapidamente # las variables correlacionadas y su grado de correlación y "con cauntas variables se correlaciona". # Reemplazamos Valores (todo lo que sea menor a 0.8 no me sirve; Ya que necesito identificar todas aquellas # variables que tienen correlación fuerte. Esas son las que necesito seleccionar para revisar cual elimino. Matriz_de_Correlaciones_[Matriz_de_Correlaciones_ < 0.8] <- NA str(Matriz_de_Correlaciones_) View(Matriz_de_Correlaciones_) # Aplicamos un ciclo FOR para eliminar la diagonal de la matriz, es decir las variables correlacionadas # consigo mismas (valor 1) # for = Esto significa Iteración o ciclo # i significa "1". Es un vector. Es un vector que comienza en el 1. Y "in 1:NROW", # me está diciendo que desde la fila 1 (ya que NROW significa eso) pase por toda la # fila de 128 filas de la Master Matriz de Correlaciones. El "[i,i]" es una cordenada # matricial. Significa lo que solemos entender como el "campo 1", es decir, el primer ciclo, # for, o iteración, comienza en la cordenada "1,1" (posición) es decir, que tome el valor #del campo intersectado por la fila 1 y la columna 1. Luego, la iteración 2 siguiría la # cordenada "2,2". Luego, la iteración 3, sigue la cordenada "3,3", y así sucecivamente. # Ojo, que todo es posible dado que sabemos que estámos en presenaic a de una matriz cuadrada (la # misma cantidad de filas es igual a la misma cantidad de columnas) ya que es una matriz de # correlación. Finalmente la salida es "N" que eso ya lo sabemos inicio <- Sys.time() # Con esto le indico que mida el inicio en tiempo del proceso for (i in 1:NROW(Matriz_de_Correlaciones_)) { Matriz_de_Correlaciones_[i,i] <- NA } fin <- Sys.time() # Con esto le indico que mida el fin en tiempo del proceso View(Matriz_de_Correlaciones_) # Contamos Frecuencia # Contar veces que un registro o etiqueta presenta información en sus siguientes variables Matriz_de_Correlaciones_$Fcorrelacion <- rowSums(!is.na(Matriz_de_Correlaciones_)) View(Matriz_de_Correlaciones_) variable.names(Matriz_de_Correlaciones_) # Eliminamos Variables Correlacionadas. Si no es por iv, ni información, aplicar criterio de negocio versus analistas # del preprocesamiento. Master_respaldo3 <- Master # Respaldamos # Master <- Master_respaldo3 # llegamos hasta aquí. Clase del 05 de agosto de 2021 Master <- Master[ ,!colnames(Master)=="Personas_vacunadas"] Master <- Master[ ,!colnames(Master)=="Muertes"] Master <- Master[ ,!colnames(Master)=="Tasa_mortalidad_en_porcentajes"] str(Master) # Volvemos a Estudiar la Correlación. sum(is.na(Master)) # Reviso nuevamente que no hayan NA # Corremos funciónd de correlación variable.names(Master) CorrMat2 <- cor(Master[,1:8]) #Correlación corrplot.mixed(CorrMat2) # Matriz de Correlación #Matriz de Correlaciones Matriz_de_Correlaciones_2 <- data.frame(CorrMat2) Matriz_de_Correlaciones_respaldo2 <- Matriz_de_Correlaciones_2 # Respaldo Matriz_de_Correlaciones_2 <- abs(Matriz_de_Correlaciones_2) # Dejamos en Valores Absolutos str(Matriz_de_Correlaciones_2) View(Matriz_de_Correlaciones_2) # Crearemos un Datframe a partir de la matriz de correlación CorrMat para identificar rápidamente # las variables correlacionadas y su grado de correlación y "con cuantas variables se correcciona". # Reemplazamos Valores (todo lo que sea menor a 0.8 no me sirve; Ya que necesito identificar todas aquellas # variables que tienen correlación fuerte. Esas son las que necesito seleccionar para revisar cual elimino. Matriz_de_Correlaciones_2[Matriz_de_Correlaciones_2 < 0.8] <- NA str(Matriz_de_Correlaciones_2) View(Matriz_de_Correlaciones_2) # Ya no hay. # Podemos verlo de otra manera #Matriz de Correlaciones Matriz_de_Correlaciones_2 <- data.frame(CorrMat2) Matriz_de_Correlaciones_respaldo2 <- Matriz_de_Correlaciones_2 # Respaldo Matriz_de_Correlaciones_2 <- abs(Matriz_de_Correlaciones_2) # Dejamos en Valores Absolutos str(Matriz_de_Correlaciones_2) View(Matriz_de_Correlaciones_2) # Aplicamos un ciclo FOR para eliminar la diagonal de la matriz, es decir las variables correlacionadas # consigo mismas (valor 1) # for = Esto significa Iteración o ciclo # i significa "1". Es un vector. Es un vector que comienza en el 1. Y "in 1:NROW", # me está diciendo que desde la fila 1 (ya que NROW significa eso) pase por toda la # fila de 128 filas de la Master Matriz de Correlaciones. El "[i,i]" es una cordenada # matricial. Significa lo que solemos entender como el "campo 1", es decir, el primer ciclo, # for, o iteración, comienza en la condenada "1,1" (posición) es decir, que tome el valor #del campo interceptando por la fila 1 y la columna 1. Luego, la iteración 2 siguiría la # cordenada "2,2". Luego, la iteración 3, sigue la cordenada "3,3", y así sucecivamente. # Ojo, que todo es posible dado que sabemos que estámos en presencia a de una matriz cuadrada (la # misma cantidad de filas es igual a la misma cantidad de columnas) ya que es una matriz de # correlación. Finalmente la salida es "N" que eso ya lo sabemos inicio <- Sys.time() # Con esto le indico que mida el inicio en tiempo del proceso for (i in 1:NROW(Matriz_de_Correlaciones_2)) { Matriz_de_Correlaciones_2[i,i] <- NA } fin <- Sys.time() # Con esto le indico que mida el fin en tiempo del proceso View(Matriz_de_Correlaciones_2) # No existe correlaciones igual o superior a 8 Master_respaldo4 <- Master # Respaldamos ################# ################# PRIMER ACERCAMIENTO ################# ################# Plotearemos a través de PCA el Modelo de Datos de Manera cuasi Natural ################# ################# antes de Probar cuál es el mejor algoritmo de Clustering ################# ################# que Utilizaremos ################# ################# ################# # El objetivo de esto es encontrar una dispersión natural del Modelo de DAtos en el espacio cartesiano. # Con el objeto de Mirar si existen clasterS CUASI-naturales. # Reducimos en dos Variables a través de la técnica de Componentes Principales. # Componentes Principales PCA = prcomp(Master) PCA # Reviso la Proporción Acumulada sobre la Varianza Total por PCA. Es decir, cuanto representa la aportación de la varianza (acumulada) # con n PCA sobre la Varianza Total del Modelo de Datos. summary(PCA) # Seleccionamos las primeras dos PCA. Podemos acceder a las PCA solicitándole a los elementos de salida llamado "rotación", # ya que es la Matriz Rotada. PCA_1_2 <- PCA$rotation str(PCA_1_2) # Seleccionamos las dos primeras PCA y convertimos en Dataframe variable.names(PCA_1_2) PCA_1_2 <- as.data.frame(PCA_1_2[,-3:-8]) str(PCA_1_2) View(PCA_1_2) # Si nos fijamos vemos la aportación de la varianza por cada variable, en la Varianza Total del Modelo de Datos. PCA_1_2$Variables <- rownames(PCA_1_2) # Desendixamos str(PCA_1_2) View(PCA_1_2) # Esto nos muestra la contribución o participación de los puntos u observaciones de la varianza de cada variable, # para la formación de las ocho componentes. Podemos ver con cuanta varianza aporta cada variable en la Varianza # Total del modelo. Pero no es nuestro objetivo. Nuestro objetivo es ver cuanto aporta cada país en cada PCA. ################# ################# ################# Ploteamos ################# ################# ################# # No obstante lo anterior, lo necesitamos por país para poder así plotearlo. # Tendremos la contribución o participación de la varianza de los países para la formación de la componente # 1 y componente 2. # Esto lo haremos para ver si aparecen cuasi Clusters Naturales o No como ya señalamos. # Traemos la contribución u observaciones para la construcción del PCA por individuo. View(Master) l <- PCA$x View(l) # Seleccionamos las dos primeras PCA, al igual que lo anterior, pero por individuo y convertimos en Dataframe. variable.names(l) l <- as.data.frame(l[,-3:-8]) str(l) View(l) # Si nos fijamos vemos la aportación de de los países, por cada país, en la Varianza Total del Modelo de Datos. l$id_paises <- rownames(l) # Desendixamos str(l) View(l) # Instalamos paquetes y corremos librerías install.packages("ggplot2") library(ggplot2) l$id_paises <- as.factor(l$id_paises) # Cambiamos a Tipo factor. # con colores. str(l) View(l) plot(x = l[,"PC1"], y = l[,"PC2"], col = l[,"id_paises"], xlab = "X", ylab = "Y") plot(x = l[,"PC1"], y = l[,"PC2"], xlab = "X", ylab = "Y") # Sino También podemos plotear sin colores. # Todo lo anterior, lo que acabamos de hacer, la función fviz_cluster de la librería factoextra lo realiza de manera instantánea. # Lo veremos más adelante para validar y representar posibles clusters. # Guardamos Mediuo ambiente a Modo de Respaldo RData.. #save.image("E:/PROYECTOS/DOCENCIA_/INAP/Versión1_/Adrian_Modulos_/Clustering_/Data_set_a_Utilizar_/Environment_1.RData") # Respaldamos Medio Ambiente Rdata. Guardar en formato RDS. #load("E:/PROYECTOS/DOCENCIA_/INAP/Versión1_/Adrian_Modulos_/Clustering_/Data_set_a_Utilizar_/Environment_1.RData") # Para cargar ####################################################################################################################### ####################################################################################################################### ############################## ##################################### ############################## Evaluamos el mejor Algoritmo de Clustering ##################################### ############################## y también el óptimo de K ##################################### ############################## ##################################### ####################################################################################################################### ####################################################################################################################### #install.packages("clValid") library(clValid) dim(Master) # Revisamos Dimensiones de la Matriz variable.names(Master) str(Master) View(Master) Master_respaldo5 <- Master #Master <- Master_respaldo3 # Ahora inicio la prueba de 2 a 16 Clusters (K). Con esto veré cuál es el algoritmo mas apropiado. inicio <- Sys.time() # Con esto le indico que mida el inicio en tiempo del proceso comparacion <- clValid(obj = Master, nClust = 2:20, # Numero de Clusters a Probar clMethods = c("hierarchical", "kmeans", "pam"), validation = c("stability", "internal")) y# Estos es por si nos pide el alto rendimiento o recurso que ocupará de nuestro hardware o máquina. Mejor entrenarlo en un servidor. summary(comparacion) fin <- Sys.time() # Con esto le indico que mida el fin en tiempo del proceso para evaluar cuanto demora sino # Clustering Methods: # hierarchical kmeans pam # # Cluster sizes: # 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 # # Validation Measures: # 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 # # hierarchical APN 0.0029 0.0096 0.0095 0.0121 0.0180 0.0349 0.0575 0.0600 0.0599 0.0639 0.1141 0.1874 0.1746 0.2959 0.3321 0.3333 0.2075 0.2396 0.2551 # AD 3.1809 3.1306 3.0167 2.9093 2.8189 2.7872 2.7106 2.6585 2.5757 2.5224 2.4949 2.4522 2.3649 2.3461 2.3007 2.2736 2.0487 2.0044 1.9380 # ADM 0.0738 0.1367 0.0999 0.1491 0.1403 0.2722 0.2572 0.2709 0.3091 0.2800 0.3676 0.5106 0.5221 0.7445 0.8360 0.8262 0.6713 0.6542 0.6850 # FOM 0.9787 0.9653 0.9622 0.9520 0.9465 0.9493 0.9412 0.9245 0.9266 0.8759 0.8778 0.8796 0.8815 0.8806 0.8808 0.8807 0.8724 0.8716 0.8727 # Connectivity 5.2869 6.7869 9.7159 14.0500 16.9790 21.1980 23.1980 28.2226 36.5579 39.4869 39.4869 45.0948 54.6813 55.1813 65.6734 67.6734 87.1310 87.1310 101.3798 # Dunn 0.4871 0.4677 0.6278 0.3490 0.4142 0.3748 0.3748 0.3748 0.2581 0.2581 0.2581 0.2581 0.1630 0.1630 0.1665 0.1665 0.1624 0.1624 0.1932 # Silhouette 0.6851 0.6665 0.6363 0.5900 0.5722 0.4763 0.4714 0.3260 0.3048 0.2437 0.2135 0.1617 0.1252 0.1183 0.1041 0.1016 0.1819 0.1665 0.1647 # kmeans APN 0.0114 0.0110 0.0131 0.0354 0.0626 0.1372 0.4609 0.3295 0.2860 0.3431 0.4193 0.4019 0.3766 0.3683 0.3587 0.3990 0.3987 0.3504 0.3832 # AD 3.1703 3.0936 2.9521 2.8787 2.7634 2.7308 2.7221 2.4122 2.2819 2.2485 2.2169 2.0929 2.0219 1.9506 1.9120 1.8786 1.8474 1.7829 1.7808 # ADM 0.0905 0.2206 0.1563 0.2073 0.2465 0.4215 1.0087 0.7706 0.7658 0.8477 0.9784 0.9032 0.8788 0.8424 0.8484 0.8470 0.8728 0.7881 0.8609 # FOM 0.9558 0.9741 0.9627 0.9479 0.9421 0.9449 0.9426 0.9396 0.9237 0.9097 0.9091 0.9124 0.9139 0.8641 0.8688 0.8679 0.8622 0.8639 0.8637 # Connectivity 5.2869 10.5976 13.5266 15.0266 24.6270 24.7270 26.7270 64.7607 90.8242 90.9429 99.9845 100.8345 114.2254 127.0992 122.5325 124.5325 118.6730 154.3385 146.1111 # Dunn 0.4871 0.1980 0.2681 0.2967 0.1563 0.1773 0.1773 0.0984 0.0976 0.1113 0.1149 0.1128 0.1248 0.1258 0.1643 0.1643 0.1550 0.1503 0.1412 # Silhouette 0.6851 0.5404 0.5453 0.5458 0.4298 0.3719 0.3670 0.2328 0.2119 0.2157 0.2042 0.1993 0.1929 0.1954 0.1956 0.1908 0.1968 0.1786 0.1838 # pam APN 0.1560 0.1473 0.2211 0.3688 0.3825 0.2662 0.3072 0.2658 0.3415 0.2957 0.2801 0.3379 0.3264 0.3526 0.3145 0.3664 0.3556 0.3657 0.3806 # AD 3.1448 3.0042 2.7910 2.7689 2.5959 2.4448 2.4369 2.2728 2.2321 2.1528 2.0671 1.9958 1.9187 1.9189 1.8528 1.8106 1.7719 1.7477 1.7343 # ADM 0.5002 0.5486 0.6220 0.9825 0.9231 0.7479 0.9731 0.7705 0.8600 0.7956 0.7198 0.7392 0.6983 0.8081 0.7316 0.7549 0.7176 0.7292 0.7603 # FOM 0.9984 0.9989 0.9605 0.9614 0.9448 0.9420 0.9424 0.9415 0.9427 0.9442 0.9444 0.9355 0.9339 0.9370 0.9398 0.9322 0.9301 0.9336 0.9355 # Connectivity 60.7095 84.0857 85.2468 87.2750 87.1750 83.0361 101.9333 110.0536 110.2536 113.1183 114.6183 115.4266 121.6313 134.3056 143.8952 145.8952 155.8357 162.0171 163.4933 # Dunn 0.0359 0.0359 0.0468 0.0449 0.0469 0.0374 0.0469 0.0469 0.0469 0.0469 0.0656 0.0976 0.0976 0.0976 0.1014 0.1284 0.1323 0.1323 0.1433 # Silhouette 0.1915 0.1254 0.1523 0.1257 0.1460 0.1760 0.1549 0.1732 0.1820 0.1852 0.1859 0.1986 0.1978 0.1894 0.1906 0.1861 0.1816 0.1808 0.1750 # # Optimal Scores: # # Score Method Clusters # APN 0.0029 hierarchical 2 # AD 1.7343 pam 20 # ADM 0.0738 hierarchical 2 # FOM 0.8622 kmeans 18 # Connectivity 5.2869 hierarchical 2 # Dunn 0.6278 hierarchical 4 # Silhouette 0.6851 hierarchical 2 # Según esta evaluación obtenemos mejores resultados con 2 K y con el algoritmo hierarchical, ya que lidera los mejores resultado para 5 índices de 7. # El segundo es kmeans y PAM de 18 a 20 K. Esto es totalmente esperable ya que la librería ClValidum siempre arrojará mejores índices para la mayor desagregación o # distancia entre clusters y menor distancia intra clusters. # Otra recomendación de negocio sería 4 K con hierarchical. # El APN debe ser lo más cercano a 0. # El AD debe ser lo más cercano a 0. # El ADM debe ser lo más cercano a 0. # El FOM debe ser lo más cercano a 0. # El CONNECTIVITY debe ser lo más cercano a 0. # El DUNN debe ser lo más alto posible # El SILHOUETTE debe ser lo más alto posible # Probaremos Nuevamente la librería pero de 2 para 7 Clusters # Ahora inicio la prueba de 2 a 16 Clusters (K). Con esto veré cuál es el algoritmo mas apropiado. inicio <- Sys.time() # Con esto le indico que mida el inicio en tiempo del proceso comparacion <- clValid(obj = Master, nClust = 2:7, # Numero de Clusters a Probar clMethods = c("hierarchical", "kmeans", "pam"), validation = c("stability", "internal")) y# Estos es por si nos pide el alto rendimiento o recurso que ocupará de nuestro hardware o máquina. Mejor entrenarlo en un servidor. summary(comparacion) fin <- Sys.time() # Con esto le indico que mida el fin en tiempo del proceso para evaluar cuanto demora sino # Clustering Methods: # hierarchical kmeans pam # # Cluster sizes: # 2 3 4 5 6 7 # # Validation Measures: # 2 3 4 5 6 7 # # hierarchical APN 0.0029 0.0096 0.0095 0.0121 0.0180 0.0349 # AD 3.1809 3.1306 3.0167 2.9093 2.8189 2.7872 # ADM 0.0738 0.1367 0.0999 0.1491 0.1403 0.2722 # FOM 0.9787 0.9653 0.9622 0.9520 0.9465 0.9493 # Connectivity 5.2869 6.7869 9.7159 14.0500 16.9790 21.1980 # Dunn 0.4871 0.4677 0.6278 0.3490 0.4142 0.3748 # Silhouette 0.6851 0.6665 0.6363 0.5900 0.5722 0.4763 # kmeans APN 0.0114 0.0110 0.0131 0.0354 0.0626 0.1372 # AD 3.1703 3.0936 2.9521 2.8787 2.7634 2.7308 # ADM 0.0905 0.2206 0.1563 0.2073 0.2465 0.4215 # FOM 0.9558 0.9741 0.9627 0.9479 0.9421 0.9449 # Connectivity 5.2869 10.5976 13.5266 15.0266 24.6270 24.7270 # Dunn 0.4871 0.1980 0.2681 0.2967 0.1563 0.1773 # Silhouette 0.6851 0.5404 0.5453 0.5458 0.4298 0.3719 # pam APN 0.1560 0.1473 0.2211 0.3688 0.3825 0.2662 # AD 3.1448 3.0042 2.7910 2.7689 2.5959 2.4448 # ADM 0.5002 0.5486 0.6220 0.9825 0.9231 0.7479 # FOM 0.9984 0.9989 0.9605 0.9614 0.9448 0.9420 # Connectivity 60.7095 84.0857 85.2468 87.2750 87.1750 83.0361 # Dunn 0.0359 0.0359 0.0468 0.0449 0.0469 0.0374 # Silhouette 0.1915 0.1254 0.1523 0.1257 0.1460 0.1760 # # Optimal Scores: # # Score Method Clusters # APN 0.0029 hierarchical 2 # AD 2.4448 pam 7 # ADM 0.0738 hierarchical 2 # FOM 0.9420 pam 7 # Connectivity 5.2869 hierarchical 2 # Dunn 0.6278 hierarchical 4 # Silhouette 0.6851 hierarchical 2 # Se obtiene resultados similares que la prueba anterior, pero con 7K # Es decir, según esta evaluación obtenemos mejores resultados con 2 K y con el algoritmo hierarchical, # ya que lidera los mejores resultado para 3-5 índices de 7. # El segundo es kmeans y PAM con 7 K. # El APN debe ser lo más cercano a 0. # El AD debe ser lo más cercano a 0. # El ADM debe ser lo más cercano a 0. # El FOM debe ser lo más cercano a 0. # El CONNECTIVITY debe ser lo más cercano a 0. # El DUNN debe ser lo más alto posible # El SILHOUETTE debe ser lo más alto posible # Este lo consideraría mi primer análisis de óptimo de K y elección de algoritmo, # para luego tomar la decisión con Negocio. # Ahora probaremos otros óptimos de K a través de funciones de ganancia de diferencia # entre clasters e intraclusters. ################################################################################################################### ################################################################################################################### ############################## ##################################### ############################## Utilizaremos Otras Medidas de ##################################### ############################## elección del óptimo de K ##################################### ############################## "Optimizando la suma de errores al cuadrado" ##################################### ############################## ##################################### ################################################################################################################### ################################################################################################################### # "Método" del Codo o Elbow Method a fin de determinar dicho valor. Básicamente, este método busca seleccionar la # cantidad ideal de grupos a partir de la optimización de la WCSS (Within Clusters Summed Squares -optimizando la suma errores # al cuadrado). # La base del algoritmo k-means, buscar optimizar la suma errores al cuadrado. La suma de errores al cuadrado es igual a la distancia # euclídea entre las observaciones. # La idea del algoritmo es agrupar cada observación (fila de una tabla) en k grupos, calcular el número de clusters óptimo. # Para ello, el algoritmo sigue los siguentes pasos: # Se inicializan k puntos aleatorios, llamados centroides. # Para cada observación se calcula la suma de errores al cuadrado de esa observación respecto a cada uno de los k centroides. # A cada observación se le asigna el centroide que menos error tenga. # Mediremos el óptimo de K con sólo el algoritmo K-Means, a partir del cual la ganancia en la reducción # en la suma total de varianza intra-cluster deja de ser sustancial. Buscamos que esta varianza sea la más pequeña. # install.packages("factoextra") library(factoextra) # Óptimo de K bajo el Método Wss y algoritmo kmeans. # Mediremos la ganancia al aumentar en un número el K o Número de Clusters. fviz_nbclust(x = Master, FUNcluster = kmeans, method = "wss") + labs(title = "Número óptimo de clusters") # Se puede apreciar que la máxima ganancia en la disminución de la varianza intra clusters es # cuando saltamos de 1 a 3 Clusters. La segunda gran disminución es cuando saltamos de 3 a 7 K, # pero si miramos de 1 a 7 la ganancia es enorme. Es la Mayor. # Desde 8 K, la ganancia en la disminución es marginal en relción a lo anterior. # Lo anterior comienza a dialogar con la primera prueba y sobre todo segunda, de cValidum. # Óptimo de K bajo el Método Silhouette y algoritmo kmeans. # Probaremos otra medida de óptimo, el silhouette que mide el grado de confianza de la asigna-ción de una observación, # con sólo K means. Su valor puede estar entre -1 y 1, siendo valores altos un indicativo de que la observación se ha # asignado al cluster correcto. fviz_nbclust(x = Master, FUNcluster = kmeans, method = "silhouette") + labs(title = "Número óptimo de clusters") # Se puede apreciar que el grado de confianza da un salto sustantivo a partir de 3 Clusters. # A partir de 3K comienza a desestabilizarse y la confíanza comienza a ser marginal. # También s coherente con lo que se indica con la función clValidum con 2K. # Óptimo de K bajo el Método wss y algoritmo pam (manhattan) # Probaremos otra medida del óptimo de K pero con el algoritmo PAM, bajo el parámetro wss # Una forma sencilla de estimar el número K óptimo de clusters cuando no se dispone de información adicional en la que # basarse es aplicar el algoritmo para un rango de valores de K, identificando aquel a partir del cual la # reducción en la suma total de varianza intra-cluster deja de ser sustancial. # La función fviz_nbclust() automatiza este proceso. En este caso, dado que se sospecha de la presencia de outliers, # se emplea la distancia de Manhattan como medida de similitud. fviz_nbclust(x = Master, FUNcluster = pam, method = "wss", diss = dist(Master, method = "manhattan")) # Utilizamos distancia Manhatan en este argumento. # Se aprecia una ganancia significativa cuando saltamos de 1 a 3 Clusters, en relación a la reducción # en la suma total de cuadrados internos y parece estabilizarse. A partir del Clusters 3, comienza a ser marginal # la ganancia. Pero la máxima ganancia es cuando saltamos de 1 a 7. # Una vez más, se relaciona con técnicas de Validación de Cluesters. # Recomendaciones: # Dados todos los análisis realizados, se recomiendan para este Modelo de Datos 3 o 7 Clusters, # Ante esto se pueden desprender dos recomendaciones: # Primera; # 3 o 4 K con el algoritmo hierarchical. # Segunda: # Si por razones de negocio necesitamos desagregar o abrir aún más los clusters, # se recomendaría hacerlo con 7 K, con PAM o Kmeans (recomendaría PAM por no ser sensible a los outliers # si hunieran muchos outliers.) # Guardamos a Modo de Respaldo. #save.image("E:/PROYECTOS/DOCENCIA_/INAP/Versión1_/Adrian_Modulos_/Clustering_/Data_set_a_Utilizar_/Environment_2.RData") # Respaldamos Medio Ambiente Rdata. Guardar en formato RDS. #load("E:/PROYECTOS/DOCENCIA_/INAP/Versión1_/Adrian_Modulos_/Clustering_/Data_set_a_Utilizar_/Environment_2.RData") # Para cargar ####################################################################################################################### ####################################################################################################################### ############################## ##################################### ############################## Generación de Clusters ##################################### ############################## con 7 hierarchical, 3 PAM y 2 Kmeans ##################################### ############################## ##################################### ####################################################################################################################### ####################################################################################################################### ############## ############## ############## Comenzaremos con 3 K, algoritmo PAM ############## ############## ############## variable.names(Master) # Corro el Clusters set.seed(123) # Fijamos la Semillas Clusters_PAM_3K_ <- pam(x = Master, k = 3, metric = "manhattan", nstart = 100) Clusters_PAM_3K_ # Revisamos los objetos que se contienen dentro class(Clusters_PAM_3K_$cluster) View(Clusters_PAM_3K_$cluster) str(Clusters_PAM_3K_) # Ploteamos las dos primeras PCA. La función fviz_cluster realiza la reducción PCA automáticamente. fviz_cluster(object = Clusters_PAM_3K_, data = Master, geom = "point", ellipse = FALSE, show.clust.cent = FALSE, pallete = "jco") + theme_bw() + theme(legend.position = "none") # Traemos los Clusters a un Datframe Clusters_PAM_3K_ <- as.data.frame(Clusters_PAM_3K_$clustering) # Creamos un Dat.frame con los Clustering (objeto) de los SS.OO. View(Clusters_PAM_3K_) Clusters_PAM_3K_$id_paises <- rownames(Clusters_PAM_3K_) # Des Indexo ID paises variable.names(Clusters_PAM_3K_) colnames(Clusters_PAM_3K_) <- c("Clusters_3K_PAM","id_paises") # Renombramos View(Clusters_PAM_3K_) variable.names(Clusters_PAM_3K_) str(Clusters_PAM_3K_) ############## ############## ############## Seguimos con 2 K, algoritmo Kmeans ############## ############## ############## # Comenzaremos con 3 K, algoritmo PAM. View(Master) # Revisamos set.seed(88) # Fijamos semilla Clusters_Kmeans_2K_ <- kmeans(x = Master, centers = 2, nstart = 1000) # El argumento nstart corresponde al número de iteraciones # # La opción nstart # intenta múltiples configuraciones iniciales e informa sobre la mejor. Por ejemplo, agregar nstart = 25 # generará 25 centroides aleatorios iniciales y elegirá el mejor para el algoritmo. También podríamos indicar el # número de iteraciones con el argumento "iter.max = N" # La base del algoritmo k-means: optimizando la suma errores al cuadrado. La suma de errores al cuadrado es igual a la distancia # euclídea entre las observaciones. # La idea del algoritmo es agrupar cada observación (fila de una tabla) en k grupos, calcular el número de clusters óptimo. # Para ello, el algoritmo sigue los siguentes pasos: # Se inicializan k puntos aleatorios, llamados centroides. # Para cada observación se calcula la suma de errores al cuadrado de esa observación respecto a cada uno de los k centroides. # A cada observación se le asigna el centroide que menos error tenga. Clusters_Kmeans_2K_ # Revisamos los objetos que se contienen dentro class(Clusters_Kmeans_2K_$cluster) View(Clusters_Kmeans_2K_$cluster) str(Clusters_Kmeans_2K_) # Ploteamos las dos primeras PCA fviz_cluster(object = Clusters_Kmeans_2K_, data = Master, geom = "point", ellipse = FALSE, show.clust.cent = FALSE, pallete = "jco") + theme_bw() + theme(legend.position = "none") # Traemos los Clusters a un Datframe Clusters_Kmeans_2K_ <- as.data.frame(Clusters_Kmeans_2K_$cluster) # Creamos un Dat.frame con los Clustering (objeto) de los SS.OO. View(Clusters_Kmeans_2K_) Clusters_Kmeans_2K_$id_paises <- rownames(Clusters_Kmeans_2K_) # Des Indexar View(Clusters_Kmeans_2K_) colnames(Clusters_Kmeans_2K_) <- c("Clusters_Kmeans_2K_","id_paises") # Renombramos View(Clusters_Kmeans_2K_) str(Clusters_Kmeans_2K_) ############## ############## ############## Seguimos con 2, 6 y 9K, hierarchica ############## ############## (Jerarquizado) ############## # Finalmente seguimos con hierarchical, bajo el criterio Dendograma con tres enlaces o Linkage; complete, single y average. # Con 2 K para la generación de Clusters. # Ahora, visualmente determinaremos si ocuparemos Linkage complete, Linkage single o Linkage average, para hierarchical. # Al aplicar un hierarchical clustering se tiene que escoger una medida de distancia (1-similitud. Es decir, euclidiana # o Manhattan para el caso de este curso) y un tipo de linkage determinado también debemos ocupar. # En este caso, emplearemos la función hclust() indicando la # distancia euclídea como medida de similitud y se comparan los linkages complete, single y average. # Posteriormente evaluaremos que linkage es el más apropiado. # Generamos primero la Matriz de distancia. # Para esto el algoritmo necesita calcular una matriz de distancia antes, en este caso euclidiana. matriz_distancias <- dist(x = Master, method = "euclidean") # Generamos los 3 Linkage o Enlaces. set.seed(56) # Fijamos la semilla para hacer el experimento reproducible. h_cluster_completo <- hclust(d = matriz_distancias, method = "complete") h_cluster_single <- hclust(d = matriz_distancias, method = "single") h_cluster_average <- hclust(d = matriz_distancias, method = "average") # Validación del Método para distinguir si utilizar "complete", "single" o "average". # Una vez creado el dendrograma, hay que evaluar hasta qué punto su estructura refleja las distancias originales # entre observaciones. # Una forma de hacerlo es empleando el coeficiente de correlación entre las distancias cophenetic del dendrograma # (altura de los nodos) y la matriz de distancias original. Cuanto más cercano es el valor a 1, # mejor refleja el dendrograma la verdadera similitud entre las observaciones. # Valores superiores a 0.75 suelen considerarse como buenos. Esta medida puede emplearse como # criterio de ayuda para escoger entre los distintos métodos de linkage. # En R, la función cophenetic() (Correlación cofenética) calcula las distancias cophenetic # de un hierarchical clustering. cor(x = matriz_distancias, cophenetic(h_cluster_completo)) # Probamos "complete" # 0.8113958 cor(x = matriz_distancias, cophenetic(h_cluster_single)) # Probamos "single" # 0.9020753 cor(x = matriz_distancias, cophenetic(h_cluster_average)) # Probamos "average" # 0.9395717 # Escogemos el Enlace promedio o Linkage Average. ################ ################ ################ Plotearemos lo anterior ################ ################ y Seleccionamos Visualmente ################ ################ donde Cortar el óptimo de K ################ ################ ################ par(mfrow = c(3,1)) plot(x = h_cluster_completo, cex = 0.6, xlab = "", ylab = "", sub = "", main = "Linkage complete") plot(x = h_cluster_single, cex = 0.6, xlab = "", ylab = "", sub = "", main = "Linkage single") plot(x = h_cluster_average, cex = 0.6, xlab = "", ylab = "", sub = "", main = "Linkage average") # Los argumentos "cex = " nos ayudarán a modificar la escala del plot para indicar la línea donde # deseo cortar. # Por Criterio Visual Corto en 53 para Obtener 3 Clusters. plot(x = h_cluster_completo, cex = 0.4, xlab = "", ylab = "", sub = "", main = "Linkage average") # 2 Clusters abline(h = 14, lty = 2) # El argumento lty indica el tipo de línea gráfica. El argumento h indica a la # altura que cortaré en el eje Y para seleccionar los Clusters. # 6 Clusters serían abline(h = 8, lty = 1) # El argumento lty indica el tipo de línea gráfica. El argumento h indica a la # 9 Clusters serían abline(h = 6, lty = 2) # El argumento lty indica el tipo de línea gráfica. El argumento h indica a la ################ ################ ################ ################ ################ Generamos 2 Clusters ################ ################ con hierarchical ################ ################ ################ set.seed(65) # Fijamos la Semillas Clusters_hierarchical_2K_ <- as.data.frame(cutree(h_cluster_completo, h = 14)) # Cutree es la función para recibir los parámetros del dendograma View(Clusters_hierarchical_2K_) Clusters_hierarchical_2K_$id_paises <- rownames(Clusters_hierarchical_2K_) # Des Indexar colnames(Clusters_hierarchical_2K_) <- c("Clusters_hierarchical_2K_","id_paises") # Renombro View(Clusters_hierarchical_2K_) str(Clusters_hierarchical_2K_) str(l) # Plot con Todas las variables (escaladas) PCA_con_Clusters <- merge(l, Clusters_hierarchical_2K_,"id_paises",all.x = TRUE) #Antes identificar en una columna o un vector en cada data.frame str(PCA_con_Clusters) # Plot PCA plot(x = PCA_con_Clusters[,"PC1"], y = PCA_con_Clusters[,"PC2"], col = PCA_con_Clusters[,"Clusters_hierarchical_2K_"], xlab = "PC1", ylab = "PC2") # Plot con variables escaladas # Ejemplo 1: str(Master) plot(x = Master[,"Tasa_Mortalidad_Muertes/1000_habitantes"], y = Master[,"Deficit_en_Millones_de_Euros"], col = PCA_con_Clusters[,"Clusters_hierarchical_2K_"], xlab = "Tasa_Mortalidad_Muertes/1000_habitantes", ylab = "Deficit_en_Millones_de_Euros") # Ejemplo 2: str(Master) plot(x = Master[,"IDH"], y = Master[,"Deficit_en_Millones_de_Euros"], col = PCA_con_Clusters[,"Clusters_hierarchical_2K_"], xlab = "Deficit_en_Millones_de_Euros", ylab = "Numero_de_Homicidios") # Ejemplo 3: str(Master) plot(x = Master[,"Deficit_en_porc_del_PIB"], y = Master[,"Suicidios"], col = PCA_con_Clusters[,"Clusters_hierarchical_2K_"], xlab = "Deficit_en_porc_del_PIB", ylab = "Suicidios") View(Master) ################ ################ ################ ################ ################ Generamos 6 Clusters ################ ################ con hierarchical ################ ################ ################ set.seed(65) # Fijamos la Semillas Clusters_hierarchical_6K_ <- as.data.frame(cutree(h_cluster_completo, h = 8)) View(Clusters_hierarchical_6K_) Clusters_hierarchical_6K_$id_paises <- rownames(Clusters_hierarchical_6K_) # Des Indexar colnames(Clusters_hierarchical_6K_) <- c("Clusters_hierarchical_6K_","id_paises") # Renombro View(Clusters_hierarchical_6K_) str(Clusters_hierarchical_6K_) str(l) # Traemos los clusters al dataset PCA PCA_con_Clusters <- merge(l, Clusters_hierarchical_6K_,"id_paises",all.x = TRUE) #Antes identificar en una columna o un vector en cada data.frame str(PCA_con_Clusters) # Plot PCA plot(x = PCA_con_Clusters[,"PC1"], y = PCA_con_Clusters[,"PC2"], col = PCA_con_Clusters[,"Clusters_hierarchical_6K_"], xlab = "PC1", ylab = "PC2") # Plot con Todas las variables (escaladas) # Ejemplo 1: str(Master) plot(x = Master[,"Tasa_Mortalidad_Muertes/1000_habitantes"], y = Master[,"Deficit_en_Millones_de_Euros"], col = PCA_con_Clusters[,"Clusters_hierarchical_6K_"], xlab = "Tasa_Mortalidad_Muertes/1000_habitantes", ylab = "Deficit_en_Millones_de_Euros") # Ejemplo 2: str(Master) plot(x = Master[,"IDH"], y = Master[,"Deficit_en_Millones_de_Euros"], col = PCA_con_Clusters[,"Clusters_hierarchical_6K_"], xlab = "Deficit_en_Millones_de_Euros", ylab = "Numero_de_Homicidios") # Ejemplo 3: str(Master) plot(x = Master[,"Deficit_en_porc_del_PIB"], y = Master[,"Suicidios"], col = PCA_con_Clusters[,"Clusters_hierarchical_6K_"], xlab = "Deficit_en_porc_del_PIB", ylab = "Suicidios") View(Master) ################ ################ ################ ################ ################ Generamos 9 Clusters ################ ################ con hierarchical ################ ################ ################ set.seed(65) # Fijamos la Semillas Clusters_hierarchical_9K_ <- as.data.frame(cutree(h_cluster_completo, h = 6)) View(Clusters_hierarchical_9K_) Clusters_hierarchical_9K_$id_paises <- rownames(Clusters_hierarchical_9K_) # Des Indexar colnames(Clusters_hierarchical_9K_) <- c("Clusters_hierarchical_9K_","id_paises") # Renombro View(Clusters_hierarchical_9K_) str(Clusters_hierarchical_9K_) str(l) # Traemos los clusters al dataset PCA PCA_con_Clusters <- merge(l, Clusters_hierarchical_9K_,"id_paises",all.x = TRUE) #Antes identificar en una columna o un vector en cada data.frame str(PCA_con_Clusters) # Plot PCA plot(x = PCA_con_Clusters[,"PC1"], y = PCA_con_Clusters[,"PC2"], col = PCA_con_Clusters[,"Clusters_hierarchical_9K_"], xlab = "PC1", ylab = "PC2") # Plot con Todas las variables (escaladas) # Ejemplo 1: str(Master) plot(x = Master[,"Tasa_Mortalidad_Muertes/1000_habitantes"], y = Master[,"Deficit_en_Millones_de_Euros"], col = PCA_con_Clusters[,"Clusters_hierarchical_9K_"], xlab = "Tasa_Mortalidad_Muertes/1000_habitantes", ylab = "Deficit_en_Millones_de_Euros") # Ejemplo 2: str(Master) plot(x = Master[,"IDH"], y = Master[,"Deficit_en_Millones_de_Euros"], col = PCA_con_Clusters[,"Clusters_hierarchical_9K_"], xlab = "Deficit_en_Millones_de_Euros", ylab = "Numero_de_Homicidios") # Ejemplo 3: str(Master) plot(x = Master[,"Deficit_en_porc_del_PIB"], y = Master[,"Suicidios"], col = PCA_con_Clusters[,"Clusters_hierarchical_9K_"], xlab = "Deficit_en_porc_del_PIB", ylab = "Suicidios") View(Master) ################ ################ ################ ################ ################ Traemos los Clusters ################ ################ a mi Master ################ ################ ################ Clusters_Kmeans_2K_ Clusters_PAM_3K_ Clusters_hierarchical_2K_ Clusters_hierarchical_6K_ Clusters_hierarchical_9K_ Master_respaldo6 <- Master #Master <- Master_respaldo6 Master$id_paises <- rownames(Master) # Des Indexar dim(Master) dim(Master) Master <- merge(Master, Clusters_Kmeans_2K_,"id_paises",all.x = TRUE) #Antes identificar en una columna o un vector en cada data.frame Master <- merge(Master, Clusters_PAM_3K_,"id_paises",all.x = TRUE) #Antes identificar en una columna o un vector en cada data.frame Master <- merge(Master, Clusters_hierarchical_2K_,"id_paises",all.x = TRUE) #Antes identificar en una columna o un vector en cada data.frame Master <- merge(Master, Clusters_hierarchical_6K_,"id_paises",all.x = TRUE) #Antes identificar en una columna o un vector en cada data.frame Master <- merge(Master, Clusters_hierarchical_9K_,"id_paises",all.x = TRUE) #Antes identificar en una columna o un vector en cada data.frame variable.names(Master) str(Master) View(Master) # Guardamos a Modo de Respaldo. #save.image("E:/PROYECTOS/DOCENCIA_/INAP/Versión1_/Adrian_Modulos_/Clustering_/Data_set_a_Utilizar_/Environment_3.RData") # Respaldamos Medio Ambiente Rdata. Guardar en formato RDS. #load("E:/PROYECTOS/DOCENCIA_/INAP/Versión1_/Adrian_Modulos_/Clustering_/Data_set_a_Utilizar_/Environment_3.RData") # Para cargar ####################################################################################################################### ####################################################################################################################### ############################## ##################################### ############################## DBSCAN ##################################### ############################## ##################################### ####################################################################################################################### ####################################################################################################################### # Usamos esta técnica cuando esperamos que la distribución espacial de los grupos no sea esférica, #install.packages("fpc") #installed.packages("dbscan") #installed.packages("factoextra") library(fpc) library(dbscan) library(factoextra) variable.names(Master) # Selección del valor óptimo de epsilon. Para esto probaremos con los K de las recoemndaciones y de # nuestros análisis. 2, 3, 6, 7 y 9 # Comenzaremos con 2 K dbscan::kNNdistplot(Master[,2:9], k = 2) # Se selecciona K # La curva tiene el punto de inflexión en torno a 3, # por lo que se escoge este valor como epsilon para DBSCAN. # Generamos el Cluster set.seed(321) # DBSCAN con epsilon = 3 y minPts = 2 dbscan_cluster <- fpc::dbscan(data = Master[,2:9], eps = 3, MinPts = 2) # El MinPts corresponde al número de K # dado que indica la distancia. # Selección de parámetros # Como ocurre en muchas otras técnicas estadísticas, en DBSCAN no existe una forma única y exacta de encontrar el # valor adecuado de epsilon (????) y ????????????????????????. A modo orientativo se pueden seguir las siguientes premisas: # ????????????????????????: cuanto mayor sea el tamaño del set de datos, mayor debe ser el valor mínimo de observaciones vecinas. # En el libro Practical Guide to Cluster Analysis in R recomiendan no bajar nunca de 3. Si los datos contienen niveles # altos de ruido, aumentar ???????????????????????? favorecerá la creación de clusters significativos menos influenciados por outliers. # epsilon: una buena forma de escoger el valor de ???? es estudiar las distancias promedio entre # las ????=???????????????????????? observaciones más próximas. # Al representar estas distancias en función de ????, el punto de inflexión de la curva suele ser un valor óptimo. # Si el valor de ???? escogido es muy pequeño, una proporción alta de las observaciones no se asignarán a ningún cluster, # por el contrario, si el valor es demasiado grande, la mayoría de observaciones se agruparán en un único cluster. # Resultados de la asignación head(dbscan_cluster$cluster) str(dbscan_cluster) # Visualización de los clusters fviz_cluster(object = dbscan_cluster, data = Master[,2:9], stand = FALSE, geom = "point", ellipse = FALSE, show.clust.cent = FALSE, pallete = "jco") + theme_bw() + theme(legend.position = "bottom") # Seguiremos con 9 K para determinar si cambia el epsilon. dbscan::kNNdistplot(Master[,2:9], k = 9) # La curva tiene el punto de inflexión en torno a 3. No cambió en # relación a la prueba anterior. Por ende es probable que se mantenga la selección no esférica. # Mientras menor sea el epsilon mayor será el traslape o detección. # Generamos el Cluster set.seed(321) # DBSCAN con epsilon = 3 y minPts = 2 dbscan_cluster <- fpc::dbscan(data = Master[,2:9], eps = 3, MinPts = 9) # Resultados de la asignación head(dbscan_cluster$cluster) str(dbscan_cluster) # Visualización de los clusters fviz_cluster(object = dbscan_cluster, data = Master[,2:9], stand = FALSE, geom = "point", ellipse = FALSE, show.clust.cent = FALSE, pallete = "jco") + theme_bw() + theme(legend.position = "bottom") # Lo interesante es que a diferencia de kmeans, detecta los outliers. # Guardamos a Modo de Respaldo. #save.image("E:/PROYECTOS/DOCENCIA_/INAP/Versión1_/Adrian_Modulos_/Clustering_/Data_set_a_Utilizar_/Environment_4.RData") # Respaldamos Medio Ambiente Rdata. Guardar en formato RDS. #load("E:/PROYECTOS/DOCENCIA_/INAP/Versión1_/Adrian_Modulos_/Clustering_/Data_set_a_Utilizar_/Environment_4.RData") # Para cargar ####################################################################################################################### ####################################################################################################################### ############################## #################################### ############################## Ploteo Sofisticad deClusters #################################### ############################## librería gganimate #################################### ############################## #################################### ####################################################################################################################### ####################################################################################################################### install.packages("plotly") install.packages("gganimate") library(plotly) library(gganimate) # Llamamos un dataframe en formato rds Clusters_para_Plotly <- readRDS(file = "E:/PROYECTOS/DOCENCIA_/INAP/Versión1_/Adrian_Modulos_/Clustering_/Data_set_a_Utilizar_/Clusters_Años_.rds") str(Clusters_para_Plotly) variable.names(Clusters_para_Plotly) View(Clusters_para_Plotly) plot1 <- ggplot(data=Clusters_para_Plotly, aes(x = Saldo_de_Credito, y = Avaluo_de_Propiedades, size = Clusters, color = Clusters, frame = Año)) + geom_point(aes(frame=Año,ids=Run_Falso)) ggplotly(plot1) ######################### ######################### # SI o sí enseñar como transitar del Mundo No Supervisado al Mundo Supervisado a través de Clustering. # Validación de Clustering. Enviar Paper a alumnos. # Mostrar visualmente SOM Redes Neuronales para el aprendizaje No supervisados. # Si queda tiempo, comentarles lo siguiente: Determinación de las Variables de clusterización o carcterización, # con Mayor poder de caracterizacióna través de un random forest, information value, o arbol decisiones . # Determinar óptimo de K en virtud del mejor Accuracy, ROC, Sensitivity and Specificity si mi problema # es de caracterización y supervisado (predictivo): Ese sería el transito del mundo no supervisado al mundo supervisado.