En primer lugar, cargamos las librerías necesarias.
## Loading required package: readxl
Cargamos la base de datos que necesitaremos para el primer ejercicio.
El análisi exploratorio lo comenzaremos con la instrucción dim() para conocer el número de variables (5) y de muestras (97) de la base de datos. A continucación, la variable summary() nos ofrece información sobre las medidas de cada variable.
## [1] 97 5
## lcavol lweight lbph lcp
## Min. :-1.3471 Min. :2.375 Min. :-1.3863 Min. :-1.3863
## 1st Qu.: 0.5128 1st Qu.:3.376 1st Qu.:-1.3863 1st Qu.:-1.3863
## Median : 1.4469 Median :3.623 Median : 0.3001 Median :-0.7985
## Mean : 1.3500 Mean :3.629 Mean : 0.1004 Mean :-0.1794
## 3rd Qu.: 2.1270 3rd Qu.:3.876 3rd Qu.: 1.5581 3rd Qu.: 1.1787
## Max. : 3.8210 Max. :4.780 Max. : 2.3263 Max. : 2.9042
## lpsa
## Min. :-0.4308
## 1st Qu.: 1.7317
## Median : 2.5915
## Mean : 2.4784
## 3rd Qu.: 3.0564
## Max. : 5.5829
Para comparar las medias y las variaznas de las variables usamos la función apply que nos permite aplicar otras funciones, en este caso mean y var a cada variable.
## lcavol lweight lbph lcp lpsa
## 1.3500096 3.6289427 0.1003556 -0.1793656 2.4783869
Respecto a la media, podemos observar que hay mucha diferencia entre unos datos y otros. Así, por ejemplo, observamos que la variables lweight es puntúa 36 veces más alto que lbph.
## lcavol lweight lbph lcp lpsa
## 1.3891566 0.1835362 2.1048399 1.9551020 1.3324756
También se observan diferencias muy notables entre las varianzas de las diferentes variables.
Por estos motivos resulta importante estandarizar las variables para que tengan media cero y desviación típica uno antes de realizar el Análisis de Componentens Principales.
Tal como hemos visto en el apartado anterior, comenzamos estandarizando las variables. Por defecto, con la función prcomp() se centran las variables para que tengan media cero. En la formulación, usando la opción scale = TRUE, escalamos las variables para que tengan una desviación estándar de uno.
## [1] "sdev" "rotation" "center" "scale" "x"
Observamos la matriz de rotación que nos proporciona las cargas de los componentes principales. Cada columna de pr.out$rotation contiene el vector de carga del componente principal correspondiente.
## PC1 PC2 PC3 PC4 PC5
## lcavol 0.5473154 -0.2587215 -0.01397918 -0.2490854 0.75582412
## lweight 0.3603542 0.5456492 0.62576090 0.4185211 0.07533353
## lbph 0.1770236 0.7197733 -0.65703021 -0.1204011 0.06636225
## lcp 0.4787795 -0.3406613 -0.39098637 0.6619246 -0.25239953
## lpsa 0.5567976 -0.0347343 0.15384681 -0.5569164 -0.59577285
A través de la función biplo() graficamos los resultados.
Se puede observar que los pacientes con una alta puntuación en el Componente 1, como el 97 o el 89, tienen un alto nivel de antígeno prostático específico, mientras que pacientes como el 1 o el 3 que puntuaron muy bajo en el Componente 1 tienen un bajo nivel de antígeno prostático específico.
Una vez más usamos la función summary para que nos de los diferentes datos del Análisis de Componentes Principales que hemos realizado. Así podemos estudiar la desviación estandar de cada componente.
## Importance of components:
## PC1 PC2 PC3 PC4 PC5
## Standard deviation 1.5911 1.1489 0.7301 0.62405 0.47531
## Proportion of Variance 0.5063 0.2640 0.1066 0.07789 0.04518
## Cumulative Proportion 0.5063 0.7703 0.8769 0.95482 1.00000
Sin embargo,. de esta manera redondéa los resultados. Así pues, para obtener la numeración completa podemos llamar a dicho dato.
## [1] 1.5910606 1.1489468 0.7301351 0.6240472 0.4753054
En cualquier caso, tal como podemos obervar, la SD va disminuyendo con cada componente
La varianza explicada por cada componente principal se obtiene mediante sus cuadrados
## [1] 2.5314738 1.3200787 0.5330972 0.3894350 0.2259153
Al igual que la SD, la vairanza explicada por cada componente principal va disminuyendo
Si bien la función summary() ya nos ofreció proporción de la varianza explicada por cada componente principal, esta estaba redondeada. Para obtener el dato completo simplemente dividimos la varianza explicada por cada componente principal por la varianza total explicada por los cuatro componentes principales
## [1] 0.50629476 0.26401575 0.10661944 0.07788699 0.04518305
Tal como se puede observar, el primer componente ofrece el 50.63% de la varianza de los datos, el siguiente el 26.40%, el siguiente el 10.66%, el cuarto el 7.78% y el último el 4.52%
Para trazar el PVE explicado por cada componente, así como el PVE acumulado, lo realizamos de la siguiente manera
par(mfrow = c(1, 2))
plot(pve , xlab = "Componente Principal", ylab = "Proporción de Varianza Explicada", ylim = c(0, 1), type = "b")
plot(cumsum(pve), xlab = "Componente Principal", ylab = "Proporción de Varianza Explicada Acumulada", ylim = c(0, 1), type = "b")Cargamos la base de datos que necesitaremos para el segundo ejercicio.
Para poder realizar el resto del ercicio observamos la base de datos
## [1] 25 10
Arreglamos la base de datos para que el nombre del pais sea el nombre de la fila y no solo una variable
EUROEMPLEO1 <- EUROEMPLEO
row.names (EUROEMPLEO1) <- c("Belgium", "Denmark", "France", "Germany", "Ireland",
"Italy", "Luxembourg","Netherlands", "United Kingdom",
"Austria","Finland","Greece","Norway","Portugal","Spain",
"Sweden","Switzerland","Turkey","Bulgaria","Czechia",
"Hungary","Poland","Romania","Russia", "Serbia")## Warning: Setting row names on a tibble is deprecated.
Al igual que en el ejercicio anterior, vamos a comparar la mediana y la varianza
## Agr Min Man PS Con SI Fin SPS TC
## 19.728 1.188 26.440 0.892 8.188 13.028 4.112 19.940 6.472
## Agr Min Man PS Con SI
## 242.1062667 0.8627667 42.4266667 0.1407667 2.8069333 21.6712667
## Fin SPS TC
## 7.8652667 48.3991667 1.8679333
Observamos que hay mucha diferencia entre las diferentes variables. Por tanto normalizamos esos datos con la función scale()
Si bien en el ejercicio ya nos marca cuantos cluster debemos hacer, para ampliar conocimientos analizaré según diversos estadísticos cuantos clusters sería lo más adecuado. Para ello instalamos el paquete “NbClust”
## Loading required package: NbClust
library(NbClust)
resnumclust<-NbClust(EUROEMPLEO2, distance = "euclidean", min.nc=2, max.nc=10, method = "kmeans", index = "alllong")## Warning in pf(beale, pp, df2): NaNs produced
## *** : The Hubert index is a graphical method of determining the number of clusters.
## In the plot of Hubert index, we seek a significant knee that corresponds to a
## significant increase of the value of the measure i.e the significant peak in Hubert
## index second differences plot.
##
## *** : The D index is a graphical method of determining the number of clusters.
## In the plot of D index, we seek a significant knee (the significant peak in Dindex
## second differences plot) that corresponds to a significant increase of the value of
## the measure.
##
## *******************************************************************
## * Among all indices:
## * 9 proposed 2 as the best number of clusters
## * 12 proposed 3 as the best number of clusters
## * 1 proposed 5 as the best number of clusters
## * 1 proposed 6 as the best number of clusters
## * 2 proposed 8 as the best number of clusters
## * 1 proposed 9 as the best number of clusters
## * 2 proposed 10 as the best number of clusters
##
## ***** Conclusion *****
##
## * According to the majority rule, the best number of clusters is 3
##
##
## *******************************************************************
Tal como podemos obervar, lo más adecuado swería hacer un cluster de 3 grupos ya que hay 12 esradísticos que así lo indican. EN cualquier caso, otros 9 estadísticos consideran que 2 cluster es adecuado
Con la función kmenas realizamos el clúster
La asignaciones de cluster están contenidas km.out$cluster.
## [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 2
A continuación podemos ver graficamente la dsitribución
plot(EUROEMPLEO2, col = (km.out$cluster+1),
main = "Resultados de la agrupación K-Means con K = 2",
xlab = "", ylab = "", pch = 20, cex = 2)Para mejorar la represención gráfica, usaremos la biblioteca “factoextra” y la instrucción fviz_cluster
## Loading required package: factoextra
## Loading required package: ggplot2
## Welcome! Want to learn more? See two factoextra-related books at https://goo.gl/ve3WBa
fviz_cluster(km.out, data =EUROEMPLEO2,repel = TRUE,star.plot = TRUE, palette = "Set2", main = "Cluster con 2 grupos")Con la función kmenas realizamos el clúster
La asignaciones de cluster están contenidas km.out$cluster.
## [1] 1 1 1 1 1 1 1 1 1 1 1 3 1 1 1 1 1 2 3 3 3 3 3 3 2
A continuación podemos ver graficamente la dsitribución.
plot(EUROEMPLEO2, col = (km.out$cluster + 1),
main = "Resultados de la agrupación K-Means con K = 3",
xlab = "", ylab = "", pch = 20, cex = 2)Al igual que antes, graficaremos con fviz_cluster.
fviz_cluster(km.out, data =EUROEMPLEO2,repel = TRUE,star.plot = TRUE, palette = "Set2", main = "Cluster con 3 grupos")Para realizar la comparativa, realizaremos los diferentes cluster.
## [1] 155.1147
## [1] 155.1147
## [1] 155.1147
En este caso observamos que no las diferentes nstart realizadas siempre nos ofrece el mismo valor.
Para realizar la agrupación jerárquica usamos la función hclust(). Para prácticar, usaremos las tres propuestas que ofrece el manual.
A continuación podemos graficar el dendograma
par(mfrow = c(1, 3))
plot(hc.complete , main = "Complete Linkage",
xlab = "", sub = "", cex = .9)
plot(hc.average , main = "Average Linkage",
xlab = "", sub = "", cex = .9)
plot(hc.single, main = "Single Linkage",
xlab = "", sub = "", cex = .9)Para determinar las etiquetas de los clústers para cada observación asociada con un corte dado del dendrograma utilizaremos la función cutree() con k=2 que es el número de clusters realizados.
## [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 2
## [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 2
## [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1
Finalmente, graficamos todo.
Al igual que se presenta en el manual, la distancia basada en la correlación puede calcularse utilizando la función as.dist(), que convierte una matriz simétrica cuadrada arbitraria en una forma que la función hclust() reconoce como una matriz de distancia.Sería de la siguiente manera
set.seed (3)
dd <- as.dist (1 - cor(t(EUROEMPLEO2)))
plot(hclust(dd, method = "complete"),
main = "Complete Linkage with Correlation -Based Distance", xlab = "", sub = "")