Crear uno o varios dendogramas que den cuenta de los tipos de vehiculos que podrian ser mas adecuados para uno de los siguientes tipos de clientes considerando su experiencia con vehiculos y la información disponible en el conjunto de datos mpg de la libreria ggplot:
(https://es.wikipedia.org/wiki/Dendrograma)
Es un tipo de representación gráfica o diagrama de datos en forma de árbol que organiza los datos en subcategoras que se van dividiendo en otros hasta llegar al nivel de detalle deseado (asemejándose a las ramas de un árbol que se van dividiendo en otras sucesivamente). Este tipo de representación permite apreciar claramente las relaciones de agrupación entre los datos e incluso entre grupos de ellos aunque no las relaciones de similaridad o cercana entre categorías. Observando las sucesivas subdivisiones podemos hacernos una idea sobre los criterios de agrupación de los mismos, la distancia entre los datos según las relaciones establecidas, etc. También podramos referirnos al dendrograma como la ilustración de las agrupaciones derivadas de la aplicación de un algorítmo de clustering jerárquico.
ggplot http://ggplot2.org/
ggdendro https://cran.r-project.org/web/packages/ggdendro/vignettes/ggdendro.html
reshape2 https://www.rdocumentation.org/packages/stats/versions/3.6.2/topics/reshape
protoclust https://www.rdocumentation.org/packages/protoclust/versions/1.6.3/topics/protoclust
Usaremos el dataset pre-instalado en ggplot ‘mpg’
library(ggplot2)
#head(mpg)
Para simplificar, seleccionamos un subconjunto del año que desee trabajar y seleccione únicamente los casos completos del conjunto de datos. En casos de registros incompletos el algoritmo de clusterización podrá lanzar errores o excepciones.
# subset por año
mpg2008 <- subset(mpg,mpg$year == 2008)
# seleccionar casos con datos en todas las columnas
mpg2008 <- mpg2008[complete.cases(mpg2008),]
# mostar las primeros 3 filas
head(mpg2008,3)
## # A tibble: 3 x 11
## manufacturer model displ year cyl trans drv cty hwy fl class
## <chr> <chr> <dbl> <int> <int> <chr> <chr> <int> <int> <chr> <chr>
## 1 audi a4 2 2008 4 manual(m6) f 20 31 p compa…
## 2 audi a4 2 2008 4 auto(av) f 21 30 p compa…
## 3 audi a4 3.1 2008 6 auto(av) f 18 27 p compa…
Nuestro conjunto de datos tiene columnas numéricas en varios órdenes de magnitud. Estas diferencias pueden impactar el cálculo de la distancia, porque los órdenes de magnitud menores no tendran tanto impacto como los mayores. Para esto es conveniente normalizar los valores. La función scale() normaliza por defecto cada columna relativa a su desviacion estandar. Esta función también tiene otras formas de normalizar.
# duplico el dataset
mpg2008N <- mpg2008
# Normalizar columnas numericas
mpg2008N[,c(3,5,8,9)] <- scale(mpg2008[,c(3,5,8,9)])
# crear columna con secuencia de números
mpg2008N$ID <- seq(1,nrow(mpg2008N))
# pegar la marca al numero de sequencia creado
mpg2008N$ID <- do.call(paste0,mpg2008N[c(1,12)])
# renombrar las filas
rownames(mpg2008N) <- mpg2008N$ID
# mostar las primeros 3 filas
str(mpg2008N,3)
## tibble [117 × 12] (S3: tbl_df/tbl/data.frame)
## $ manufacturer: chr [1:117] "audi" "audi" "audi" "audi" ...
## $ model : chr [1:117] "a4" "a4" "a4" "a4 quattro" ...
## $ displ : num [1:117] -1.278 -1.278 -0.432 -1.278 -1.278 ...
## $ year : int [1:117] 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 ...
## $ cyl : num [1:117] -1.2573 -1.2573 -0.0515 -1.2573 -1.2573 ...
## $ trans : chr [1:117] "manual(m6)" "auto(av)" "auto(av)" "manual(m6)" ...
## $ drv : chr [1:117] "f" "f" "f" "4" ...
## $ cty : num [1:117] 0.813 1.06 0.32 0.813 0.567 ...
## $ hwy : num [1:117] 1.291 1.12 0.607 0.778 0.607 ...
## $ fl : chr [1:117] "p" "p" "p" "p" ...
## $ class : chr [1:117] "compact" "compact" "compact" "compact" ...
## $ ID : chr [1:117] "audi1" "audi2" "audi3" "audi4" ...
Compute las distancias (euclidiana por defecto), construya el objeto hclust y grafíquelo preliminarmente
# Calcula las distancias
matrizDistancias <- dist(mpg2008N)
# visualiza los valores de la matriz de distancias
# head(data.matrix(matrizDistancias),3)
library(reshape2)
# convierte el formato del dataframe de wide a long
matrizLong <- melt(data.matrix(matrizDistancias))
# head(matrizLong)
# Usamos ggplot para creat un heatmap
plot <- ggplot(matrizLong, aes(Var1, Var2, fill=value))
plot <- plot + geom_tile()
plot <- plot + scale_fill_viridis_c()
plot <- plot + theme(axis.text.x = element_text(angle = 90, size = 6) , axis.text.y = element_text(size = 6))
plot
La funcion hclust() de R hace el trabajo de agrupamiento. hclust() tiene varios algoritmos de agrupamiento jerárquico y métodos para calcular la distancia entre elementos. La distancia se calcula entre atributos numéricos de los elementos. Para información del objeto que retorna hclust() y las formas de cálculo de distancias digite ?hclust en la consola.
# hace el agrupamiento jerárquico
hc2008 <- hclust(matrizDistancias)
# Construye la gráfica. Si no tiene la librería instalada instale 'ggdendro' Ver: https://cran.r-project.org/web/packages/ggdendro/vignettes/ggdendro.html
library(ggdendro)
p <- ggdendrogram (hc2008, rotate=TRUE, size=2)
p
Los prototipos son los casos mas representativos de un brazo de en un dendrogarama a una profundidad de similitud. El parámetro k define en cuantos grupos se quiere simplificar el dendrograma. Esto es similar a decidir cual es el punto de corte para identificar k prototypos.
# libreria para determinar prototipos
# https://www.rdocumentation.org/packages/protoclust/versions/1.6.3/topics/protoclust
library('protoclust')
# Calcular el arbol jerarquico
jerarquia <- protoclust(matrizDistancias)
# Determinar los K prototypos
cortes <- protocut(jerarquia, k=7)
# Plotear el dendrograma
plotwithprototypes(jerarquia,imerge = cortes$imerge, col=2, hang=0, cex=0.5)
Para esta visualizacion se convierte la estructura hclust en dendrogram. El resultado es una serie de colecciones anidadas. Para asignar color es necesario navegar hasta el nodo dentro de la coleccion y asignar el color. No es un metodo eficiente pero es util en caso de querer personalizar el color.
dhc2008 <- as.dendrogram(hc2008)
# Function to color branches
colbranches <- function(n, col){
# Find the attributes of current node
a <- attributes(n)
# Color edges with requested color
attr(n, "edgePar") <- c(a$edgePar, list(col=col, lwd=2))
# Don't forget to return the node!
n
}
# Color the first sub-branch of the first branch in red,
# the second sub-branch in orange and the second branch in blue
dhc2008[[1]][[1]] = dendrapply(dhc2008[[1]][[1]], colbranches, "red")
dhc2008[[1]][[2]] = dendrapply(dhc2008[[1]][[2]], colbranches, "orange")
dhc2008[[2]][[2]][[1]][[2]][[2]] = dendrapply(dhc2008[[2]][[2]][[1]][[2]][[2]], colbranches, "blue")
# Plot
plot(dhc2008)
Qué tienen en comun los vehículos del brazo azul?
# Seleccionar un de los vehículos
azules <-mpg2008[4,]
# agrego los demas
azules <- rbind(azules,
mpg2008[60, ],
mpg2008[4, ],
mpg2008[60, ],
mpg2008[5, ],
mpg2008[87, ],
mpg2008[92, ],
mpg2008[85, ],
mpg2008[90, ])
# mostar el resultado
azules
## # A tibble: 9 x 11
## manufacturer model displ year cyl trans drv cty hwy fl class
## <chr> <chr> <dbl> <int> <int> <chr> <chr> <int> <int> <chr> <chr>
## 1 audi a4 quat… 2 2008 4 manual… 4 20 28 p compa…
## 2 hyundai tiburon 2 2008 4 manual… f 20 28 r subco…
## 3 audi a4 quat… 2 2008 4 manual… 4 20 28 p compa…
## 4 hyundai tiburon 2 2008 4 manual… f 20 28 r subco…
## 5 audi a4 quat… 2 2008 4 auto(s… 4 19 27 p compa…
## 6 subaru foreste… 2.5 2008 4 auto(l… 4 20 26 r suv
## 7 subaru impreza… 2.5 2008 4 manual… 4 20 27 r compa…
## 8 subaru foreste… 2.5 2008 4 manual… 4 20 27 r suv
## 9 subaru impreza… 2.5 2008 4 auto(s… 4 20 27 r compa…