A continuación está el análisis de componentes principales para la base de datos “OJ”, que está en el paquete “ISLR”, la base tiene 1070 observaciones y 18 variables. Las observaciones representan compras de jugos; en las 18 variables hay una variable respuesta que indica la marca del jugo vendido (Ch ó MM), y hay otra variable que es el ID de la tienda, la cual no tomé en cuenta; también hay otra variable que indica la semana de compra, ésta tampoco la tomé en cuenta. Así, hay 16 variables, de las cuales 1 es la variable respuesta y 4 de ellas son categóricas, 11 son numéricas. La variable respuesta es una variable dummy y de las 4 variables categóricas, tres de ellas son dummies y la cuarta es una variable categórica con 5 niveles, que indican la tienda de venta.
El análisis de componentes principales está definido para observaciones de variables numéricas, por lo que quizá no sea lo más acertado usar éste método, sin embargo puedo dar una respuesta aproximada al problema usando análisis de componentes principales
Lo que hice fue: quitar a la variable respuesta, luego hice análisis de componentes principales a la base sin usar las variables categóricas y luego análisis de componentes principales con las variables categóricas transformadas a dummies, ésto para no perder información.
Para hacer el análisis de componentes principales usé la función “prcomp” que está en R. Al realizar PC sin las variables categóricas, quedaron 11 componentes principales. La varianza eplicada de los componentes 6, 7, 8, 9, 10 y 11 no fue incluida, ya que los valores son muy chicos y al redondearlos quedan iguales a cero. (ver Figura 1).
A la derecha: gráfica de los valores propios en función de los componentes sin tomar en cuenta a las variables categóricas. A la izquierda, misma gráfica tomando en cuenta las variables categóricas.
Para poder usar a las variables categóricas en el análisis de componentes principales hay que transformar las variables a dummies, en la base hay cuatro variables categóricas, de las cuales solo una no es dummy, para poder usarla hay que crear cuatro variables dummies que indiquen la pertenencia de la tienda de venta. Se usan cuatro variables dummies ya que la variable tiene 5 niveles. El resultado es una base con 18 variables, de las cuales 11 son numéricas, y las demás son dummies.
En la siguiente tabla están los valores propios (varianza explicada) de los componentes principales, usando variables dummies y usando solo las variables numéricas
| PCs | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Varianza sin categóricas | 3.92 | 2.74 | 2.05 | 1.29 | 0.95 | 0.00 | ||||||
| Varianza con dummies | 4.32 | 3.96 | 2.20 | 1.82 | 1.58 | 1.42 | 0.81 | 0.67 | 0.61 | 0.42 | 0.18 | 0.00 |
Para ambos casos del análisis de componentes principales, se calcula el procentaje de varianza acumulado y el porcentaje de varianza explicada por cada componente. Los restultados están en la siguiente tabla con: PVE=porcentaje de varianza explicada; PVA=porcentaje de varianza acumulado. Omití el PVE y el PVA de los mismos componentes cuyos valores propios son cero, ya que sus PVE y PVA también son cero al ser redondeados.
| PCs | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| PVE sin categóricas | 0.36 | 0.25 | 0.19 | 0.12 | 0.09 | 0.00 | |||||
| PVE con dummies | 0.24 | 0.22 | 0.12 | 0.10 | 0.09 | 0.08 | 0.05 | 0.04 | 0.03 | 0.02 | 0.01 |
Con esta información, puedo saber cuánto explica cada componente.
En el primer caso, donde fueron omitidas las variables categóricas: el primer componente eplica el 36 % de la varianza, el siguiente componente explica el 25 % y así hasta el quinto componente, los componentes que siguen explican tan poco que al ser redondeados, lo que explican queda igual a cero, es decir, ya no explican un porcentaje de la varianza. Por lo tanto, con cinco componentes logro explicar toda la varianza de los datos. Si quisiera reducir la dimensión de mis datos puedo usar esos cinco componentes.
En el segundo caso, con las variables dummies: el primer componente explica el 24 %, el segundo el 22 % y así hasta el componente 11, los componentes que siguen explican tan poco que al ser redondeados, su explicación de la varianza queda igual a cero.
En el primer caso me quedo con cinco componentes y en el segundo caso con 11.
Gráfica del PVE y PVA en función de los componentes, sin tomar en cuenta las variables categóricas.
El porcentaje de varianza acumulado está en la siguiente tabla:
| PCs | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| PVA sin categóricas | 0.33 | 0.61 | 0.80 | 0.91 | 1.00 | 1.00 | |||||
| PVA con dummies | 0.24 | 0.46 | 0.58 | 0.68 | 0.77 | 0.85 | 0.90 | 0.93 | 0.97 | 0.99 | 1.00 |
Gráfica del PVE y PVA usando las variables dummies
Con cuatro PCs se explica el 91 % de la varianza y con cinco PCs ya se explica toda la varianza. Así que puedo elegir cuatro ó cinco PCs y éstos son los que explican más varianza.
En el segundo caso, puedo elegir siete a 11 componentes, ya que con siete componentes la varianza explicada es 90 % y con 11 componentes ya explico toda la varianza.
En la gráfica del PC1 vs PC2, sin variables categóricas. Los datos están mezclados, a pesar de esto se ve que en la parte superior izquierda de la gráfica hay, en su mayoría, puntos azules y que en la parte derecha inferior hay más puntos rojos. Pero no se ve que haya una clara separación en las observaciones. (véase Figura 4).
En la gráfica del PC11 vs PC12, sin variables categóricas. No se ve que haya ningún patrón en los datos, de igual manera, los datos se mezclan (véase Figura 4).
A la derecha: gráfica de PC1 vs PC2. A la izquierda: gráfica de PC10 vs PC11. Sin categorías. Donde rojo:CH y azul:MM.
Ahora las gráficas de PC1 vs PC2, con variables dummies. Los datos siguen mezclados, los puntos rojos están por debajo de los puntos aules; en la parte superior de la gráfica es donde se mezclan.
A la derecha: gráfica de PC1 vs PC2. A la izquierda: gráfica de PC17 vs PC18. Con variables dummies. Donde rojo:CH y azul:MM.
La gráfica de PC11 vs PC12, con variables dummies. De igual manera los datos se mezclan, los puntos azules están por debajo de los rojos, pero no se ve una separación.
Lo que vale la pena remarcar, es la diferencia que hubo en los componentes principales al exlcuir las variables categóricas y al incluirlas como dummies.
Al excluir a las variables categóricas y graficar los dos primeros componentes no se ve separación en los datos. Además PC1 se mueve en (-6, 2) y PC2 se mueve en (-6, 2). Hay pocos puntos alejados los cuales yo no considero outliers. En la gráfica PC11 vs PC12 no se ve ningún patrón (véase Figura 4).
Al incluir a las variables dummies ya se ve separación en los datos al graficar PC1 vs PC2, lo cual no ocurre al excluir las variables categóricas. Además PC1 se mueve en (-4, 6) y PC2 se mueve en (-6, 2). No se ven outliers y en la gráfica PC17 vs PC18 también hay separación de los datos (véase Figura 5).
El análisis de componentes principales mejora al incluir a las variables dummies, ya que se ve separación de los datos al graficar los dos primeros y los dos últimos componentes y porque el rango en que se mueve PC1 es dos unidades mayor que el de PC2, ésto es normal, pero al excluir las variables categóricas, los rangos son iguales.
Un patrón importante es que los datos están mezclados y parece que no hay una separación en dos grupos más que en los extremos, ésto se puede ver en las gráficas de los primeros dos componentes, con las categorías de pertenencia pintadas sobre las gráficas. Por lo tanto, es de esperar que los métodos kmenas y jerárquicos no separen bien en dos grupos, ya que no existe dicha división.
A continuación se desarrollan los siguientes puntos:
k-means a la base sin categorías y luego k-means a los componentes principales obtenidos sin usar variables categóricas.
k-means a la base con variables dummies y luego k-means a los componentes principales obtenidos usando las variables dummies.
Gráficas de los componentes principales pintados según su cluster.
Al aplicar kmeans a la base sin variables categóricas la división en dos clusters es buena, sin embargo yo sé que los datos están mezclados, así que no es muy buena una separación total de los datos. (véase Figura 6).
k-means en dos grupos, aplicado a la base sin variables categóricas.
Sin embargo, al aplicar kmeans a los componentes principales de la base sin categorías no hay una separación en dos clusters, de hecho, el comportamiento es igual al de la gráfica PC1 vs PC2 (véase Figura 4), los datos se separan muy poco en los extremos y están mezclados en el centro (véase Figura 7).
K-means en dos grupos, con los componentes principales de la base sin variables categóricas.
| Errores | between | total whithin | total |
|---|---|---|---|
| Datos sin categorías | 151 | 241 | 392 |
| PC sin categorías | 3370 | 8389 | 11759 |
Al usar kmeans con los componentes principales de la base sin categorías no se separan mis datos, lo cual es bueno, ya que los datos están mezclados.
La separación al incluir variables dummies se ajusta más a la distribución que tienen los datos, ya que los datos se mezclan, pero en los extremos sí hay distinción. (véase Figura 8).
Kmeans aplicado a la base con variables dummies, con dos grupos.
kmeans a componentes principales usando la base con variables dummies.
Al aplicar kmeans a los componentes principales, usando las variables dummies, Se puede ver que hay dos grupos y que uno está dentro del otro, ésto no es cierto, ya que los datos se mezclan en el centro y son distintos en los extremos (véase Figura 9).
| Errores | between | total whithin | total |
|---|---|---|---|
| Datos con dummies | 561 | 1042 | 1604 |
| PC con dummies | 3584 | 15658 | 19242 |
Las separaciones que se obtienen al aplicar kmeans con variables dummies y a los componentes principales quitando variables categóricas son buenas ya que se ajustan a la distribución de los datos, es decir, mezclados en el centro y distintos en los extremos.
A la izquierda: gráfica de PC1 vs PC2, sin variables categóricas, con las observaciones pintadas según el cluster que les hayan asignado. A la derecha: gráfica de PC1 vs PC2, sin variables categóricas, con las observaciones pintadas según la clase a la que pertenecen.
Las dos gráficas de los primeros dos componentes principales indican que los datos se separan en los extremos y que en el centro están mezclados. Por lo tanto es difícil separar a los datos ya que están mezclados y la clasificación en dos grupos vía kmeans no resulta buena, porque está clasificando categorías distintas en una misma. Una vez más se ve que los datos están mezclados y que no es buena idea separarlos. Los mismo se ve con los componentes principales que tienen variables categóricas y con los que no tienen.
Gráfica de los primeros dos componenes, usando variables dummies, izquierda: observaciones pintadas según el cluster asignado. Derecha: observaciones pintadas según su clase de pertenencia.
Voy a aplicar un análisis jerárquico a los componentes principales de la base con variables dummies.
Gráfica de los primeros dos componentes según el método jerárquico.
Hacer clusters de manera jerárquica no considera que los datos estén mezclados, ya que relaciona a las observaciones con una matriz de distancia, por lo tanto separa en dos a las observaciones alejadas con las que estén muy cerca. Como ya se había mencionado, hay pocos outliers, por lanto hay pocas variables alejadas, ésta es la razón por la cual al realizar cluster de manera jerárquica se obtengan grupos de tamaño disntito. Kmeans es mejor método para separar éstos datos ya que sí toma en cuenta que los datos estén mezclados, mientras que los métodos jerárquicos no lo hacen.
El método complete sí toma en cuenta que los datos están mezclados, sin embargo lo hace de una manera no muy buena, ya que los grupos creados son de tamaño distinto. En el dendograma puedo ver, que al cortar en dos grupos, uno es muy grande y el otro no tanto (véase Figura 12).
Dendograma del método complete, con los componentes principales de la base que tiene variables dummies.
Ahora voy a aplicar el análisis jerárquico a los componentes principales usando la base que no tiene categorías.
Gráfica de los primeros dos componentes según el método jerárquico. Sin tomar en cuenta variables categóricas.
Los tres métodos dan una mala separación en dos grupos, separan a las observaciones de abajo con las de ariba, no toma en cuenta que las variables están mezcladas (véase Figura 14).
Para los métodos jerárquicos, hay que crear una matriz de distancias que mantenga la disimilaridad de los datos. Voy a usar la distancia de Gower en mis datos, ésta distancia mantiene la disimilaridad de los datos y calcula distancias en bases de datos con variables mixtas, por lo que no hay que declarar dummies ni quitar categorías.
En el paquete “cluster” hay una función que se llama “daisy” la cual calcula la distancia de Gower, una vez calculada la matriz de distancias ya puedo aplicar los tres métodos jerárquicos.
La ventaja de usar ésta métrica es que puedo mantener la información de las variables categóricas y numéricas. En la Figura 15 se puede observar que los datos en los extremos están muy pegados y que los datos en el centro, en su mayoría, están alejados pero también hay puntos que estén cerca. Sí se ven dos grupos, pero también se ve que los datos están mezclados.
Distancia de Gower entre los datos.
Los métodos complete y average crean clusters de tamaños similares, mientras que el método single link crea clusters de tamaños distintos, ésto si quisiera cortar en cinco o seis clusters, pero al cortar en dos clusters éstos no tienen tamaños similares.
Los datos están mezclados, en todos los métodos se ve que es poco plausible separar a los datos en dos grupos, aquí se puede ver de nuevo, ya que al cortar los dendogramas en dos clusters, éstos no quedan de tamaños similares, siempre queda un cluster más grande que el otro. Los resultados de los métodos tienen sentido, ya que en la base no hay separación de las observaciones más que en los extremos, ésto lo puedo ver desde que aplico componentes principales. Sin embargo puedo conlcuir que al usar las variables dummies se representa mejor la distribución de los datos, es decir, que estén mezclados y separados en los extremos.
Dendograma del método complete.
Dendograma del método average.
Dendograma del método single link
library(ISLR)
library(fastDummies) #dummies
library(factoextra) #visualización
library(cluster) #distancia gower
options(scipen=100, digits=2)
data(OJ); attach(OJ)
OJ<-OJ[,-c(2, 3)] #sin StoreID sin WeekofPurchase
col=c("red", "blue")
####### PCA sin variable respuesta
#############
####### sin categóricas, tampoco dicotómicas
OJ_C<-OJ[, -c(1, 6, 7, 12, 16)]
apply(OJ_C, 2, mean) #La variable "WeekofPurchase" tiene una media muy grande
apply(OJ_C, 2, var) #La variable "WeekofPurchase" tiene una varianza muy grande
#Por lo tanto hay que escalar.
proj<-prcomp(OJ_C, scale=TRUE)
proj$center #No escala la media
proj$scale #escala la var
proj$rotation # 11 PCs
# Varianza acumulada y varianza proporcional
prv<-proj$sdev*proj$sdev #varianza explicada por cada uno de los componentes
round(prv, 2)
plot(prv, xlab="PCs", ylab="Valores propios", type="b", col= "blue") #plot de los valores propios
prc<-prv/sum(prv) #varianza proporcional explicada por cada componente
round(prc, 2)
par(mfrow=c(1,2))
plot(prc, type = "b", ylim=c(0,1), col="blue",
xlab="PCs sin categorías", ylab="Porcentaje de varianza explicada")
plot(cumsum(prc), col="blue", xlab="PCs sin categorías",
ylab="Porcentaje de varianza acumulada")
par(mfrow=c(1, 2))
plot(proj$x, col=col[Purchase], main = "PC sin categóricas") #CH- red #MM- blue
plot(proj$x[,10], proj$x[,11], col=col[Purchase], xaxt="n", yaxt="n", ylab="PC12",
xlab="PC11", main= "PC sin categóricas")
######### Con variables dummys
# La variable "STORE" tiene 5 categorías que indican las tiendas donde ocurrieron las ventas
# La convierto en dummy, las otras ya son dummies
OJ_D<-dummy_cols(OJ, select_columns = c("STORE", "Store7"), remove_first_dummy = TRUE)
OJ_D<-OJ_D[,-c(1, 12, 16)]
OJ_D$STORE_0<-as.numeric(OJ_D$STORE_0)
OJ_D$STORE_2<-as.numeric(OJ_D$STORE_2)
OJ_D$STORE_3<-as.numeric(OJ_D$STORE_3)
OJ_D$STORE_4<-as.numeric(OJ_D$STORE_4)
OJ_D$Store7_Yes<-as.numeric(OJ_D$Store7_Yes)
# variables categóricas: "SpecialCH", "SpecialMM", "Store7", y "STORE"
apply(OJ_D, 2, mean) #La variable "WeekofPurchase" tiene una media muy grande
apply(OJ_D, 2, var) #La variable "WeekofPurchase" tiene una varianza muy grande
#Por lo tanto hay que escalar.
pr_d<-prcomp(OJ_D, scale=TRUE)
pr_d$center #No escala la media
pr_d$scale #escala la var
pr_d$rotation # 18 PCs
# Varianza acumulada y varianza proporcional
prvd<-pr_d$sdev*pr_d$sdev #varianza explicada por cada uno de los componentes
round(prvd, 2)
plot(prvd, xlab="PCs", ylab="Valores propios", type="b", col= "blue") #plot de los valores propios
prcd<-prvd/sum(prvd) #varianza proporcional explicada por cada componente
round(prcd, 2)
par(mfrow=c(1,2))
plot(prcd, type = "b", ylim=c(0,1), col="blue", xlab="PCs con dummies",
ylab="Porcentaje de varianza explicada") #proporción de varianza explicada
plot(cumsum(prcd), col="blue", xlab="PCs con dummies", ylab="Porcentaje de varianza acumulada")
par(mfrow=c(1, 2))
plot(pr_d$x, col=col[Purchase], main = "PC con dummies") #CH- red #MM- Orange
plot(pr_d$x[,17], pr_d$x[,18], col=col[Purchase], xaxt="n",
yaxt="n", ylab="PC18", xlab="PC17", main = "PC con dummies")
par(mfrow=c(1, 2))
plot(prv, xlab="PCs sin categorías", ylab="Valores propios", type="b", col= "blue")
plot(prvd, xlab="PCs con variables dummies", ylab="Valores propios",
type="b", col= "blue", ylim=c(0,5))
########################################################
########## K-MEANS ###################
##### K-MEANS sin variables categóricas
set.seed(101010)
k_c<-kmeans(OJ_C, centers=2, nstart=25)# ya sé que son dos grupos
fviz_cluster(k_c, data=OJ_C)
cbind(k_c[c("totss", "tot.withinss", "betweenss")]) # minimizar tot.whithinss
#k-means con pca, sin cate
set.seed(1010)
k_c_p<-kmeans(proj$x, centers=2, nstar=25)
fviz_cluster(k_c_p, data=proj$x)
cbind(k_c_p[c("totss", "tot.withinss", "betweenss")])
par(mfrow=c(1,2))
plot(proj$x[,1],proj$x[,2],col=(k_c_p$cluster+1),
main="K-means clustering with k=2", pch=20, cex=1, xlab="PC1", ylab="PC2")
plot(proj$x, col=col[Purchase], main = "PC sin categóricas")
###### K-MEANS con variables dummys
set.seed(101010)
k_d<-kmeans(OJ_D, centers=2, nstart=25)# ya sé que son dos grupos
fviz_cluster(k_d, data=OJ_D)
cbind(k_d[c("totss", "tot.withinss", "betweenss")])
#### K-MEANS con variables dummies y PC
set.seed(1010)
k_d_p<-kmeans(pr_d$x, centers=2, nstar=25)
fviz_cluster(k_d_p, data=pr_d$x)
cbind(k_d_p[c("totss", "tot.withinss", "betweenss")])
par(mfrow=c(1,2))
plot(pr_d$x[,1],pr_d$x[,2],col=(k_d_p$cluster+1),
main="K-means clustering with k=2", pch=20, cex=1, xlab="PC1", ylab="PC2")
plot(pr_d$x, col=col[Purchase], main = "PC con dummies")
##### Hierarchical clustering
# a los PCA con dummies
hcom<-hclust(dist(pr_d$x), method="complete")
hsin<-hclust(dist(pr_d$x), method="single")
hav<-hclust(dist(pr_d$x), method="average")
plot(hcom)
#k=2
par(mfrow = c(1,3))
plot(pr_d$x[,1], pr_d$x[,2], col = col[cutree(hcom, 2)], main = "Complete",
xlab = "PC1", ylab = "PC2")
plot(pr_d$x[,1], pr_d$x[,2], col = col[cutree(hav, 3)], main = "Average",
xlab = "PC1", ylab = "PC2")
plot(pr_d$x[,1], pr_d$x[,2], col = col[cutree(hsin, 3)], main = "Single",
xlab = "PC1", ylab = "PC2")
# pca sin datos categóricos
hcomc<-hclust(dist(proj$x), method="complete")
hsinc<-hclust(dist(proj$x), method="single")
havc<-hclust(dist(proj$x), method="average")
#k=2
par(mfrow = c(1,3))
plot(proj$x[,1], proj$x[,2], col = col[cutree(hcomc, 2)], main = "Complete",
xlab = "PC1", ylab = "PC2")
plot(proj$x[,1], proj$x[,2], col = col[cutree(havc, 3)], main = "Average",
xlab = "PC1", ylab = "PC2")
plot(proj$x[,1], proj$x[,2], col = col[cutree(hsinc, 3)], main = "Single",
xlab = "PC1", ylab = "PC2")
#Calculo la distancia de Gower con la función daisy
# variables categóricas: "SpecialCH", "SpecialMM", "Store7", y "STORE"
OJ$SpecialCH<-as.factor(OJ$SpecialCH)
OJ$SpecialMM<-as.factor(OJ$SpecialMM)
OJ$STORE<-as.factor(OJ$STORE)
OJ$Store7<-as.factor(OJ$Store7)
OJ_<-daisy(OJ[,-1], metric="gower")
fviz_dist(OJ_)
hc.complete<-hclust(OJ_, method="complete")
plot(hc.complete, xlab="observaciones")
hc.average<-hclust(OJ_, method="average")
plot(hc.average)
hc.single<- hclust(OJ_, method="single")
plot(hc.single)