Tanto el Análisis Factorial (AF) como el Análisis de Componentes Principales (PCA) son técnicas multivariadas de “interdependencia”, ya que analizan la relación mutua entre un conjunto de variables. Su finalidad principal no es el análisis de relaciones causales, sino la agrupación de variables, en función de la variabilidad que cada variable comparte con otras variables (ya sea varianza o covarianza).
El objetivo del análisis de componentes principales es la reducción de un conjunto original de variables en un conjunto más pequeño de componentes no correlacionados que representen la mayor parte de la información encontrada en las variables originales.La técnica es útil cuando la base de datos tiene una dimensión n grande (es decir, cuando hay muchas variables) ya que esto impide una interpretación eficaz de las relaciones entre los objetos. De esta manera se pueden encontrar un número de factores m < n que expliquen aproximadamente lo mismo que las n variables originales y esto facilite la interpretación de los datos posteriormente.
En el método de ACP, cada una de las componentes principales corresponde a un eigenvector, y el orden del mismo es establecido de manera decreciente según el eigenvalor asignado. Es decir, la primer componente será aquel eigenvector cuyo eigenvalor asociado sea el más alto y que a la vez sea el que aporte mayor varianza.
Por otro lado, los loadings son los pesos que tiene cada variable en cada componente principal y es de esta manera que se puede conocer el tipo de información que contiene cada una de las componentes; de tal manera que se tiene lo siguiente:
\(v_{11}\) es el loading de la variable X1 de la primera componente principal.
\(v_{n1}\) es el loading de la variable Xn de la primera componente principal.
La principal diferencia entre esta técnica y la de AF es que el análisis de componentes principales (ACP) analiza la varianza total del conjunto de variables observadas y , con base en ellas, trata de determinar las dimensiones básicas (o cantidad de “componentes”) que las definen. En el análisis factorial (AF) el estudio de las interrelaciones entre las variables se restringe, en cambio, a la varianza común (o covarianza), es decir, a la búsqueda de un número reducido de “factores” que expresen lo que es “común” al conjunto de variables observadas. Es decir, el análisis factorial es usado para encontrar variables que se correlacionan mucho entre sí, resumidas dentro de un conjunto grande de variables.
En el AF la varianza se descompone en varianza común (comunalidad) y varianza específica. La comunalidad de cada variable expresa la porción de la varianza total de la variable “x” que es compartida con las n-1 variables observadas restantes. La varianza específica es, por el contrario, la porción de la varianza total de la variable que no es explicada por los “factores comunes” (que está compuesta por la varianza específica y el error). En palabras simples, en el AFC los factores explican las variables, y en el ACP las variables explican los factores.
Es importante mencionar que el objeto que recibe la función es una base de datos; de preferencia un data frame. Además, al realizar el Análisis de Componentes Principales lo primero que se tiene que verificar es que no haya ninguna variable categórica en la base de datos que se introduce a la función. Esto es debido a que las variables categóticas requieren otro tipo de análisis llamado CATPCA, mismo que no se vio en clase. Otro punto importante a mencionar es que se prefiere no manejar bases de datos que contengan valores faltantes, ya que la función que yo cree los elimina automáticamente y eso podría generar pérdidas grandes de información.
Es por ello que lo primero que realiza la función es quitar todas las variables categóricas y los valores faltantes. Después lo que se realizará será la creación de una lista que contenga todas las características de los Componentes Principales de la base de datos que haya ingresado el usuario y, análogamente, se devolverán las salidas necesarias del Análisis Factorial de los datos ingresados. La función exporta dos tipos de documento, un html con la posibilidad de ocultar el código y un PDF y recibe los parámetros especificados por el usuario.
La lista que contiene las características de los componentes principales contiene los siguientes elementos:
summary muestra la proporción de la varianza explicada por cada componente y la proporción acumulada, las cuales son graficadas porteriormente.
eigenvectores imprime los eigenvectores asociados a las componentes principales; solo para ilustrar la composición de los datos.
varianza_explicada muestra la varianza explicada por cada componente por medio de una gráfica de codo
proporcion_varianza_explicada muestra la proporción de la varianza que exlican cada uno de los componentes con un diagrama de codo
primeros_dos_componentes ilustran la gráfica del PC1 contra la del PC2 que son los componentes que explican en mayor proporción la varianza
ultimos_dos_componentes permite visualizar las dos últimas componentes principales en donde se encuentran los outliers de la muestra
Biplot grafica las observaciones y las direcciones de cada una de las variables. Dicha gráfica puede llegar a verse bastante llena de información si la base de datos tiene muchas observaciones o si tiene muchas variables
Importancia_relativa va a imprimir dos gráficas: el porcentaje de varianza explicada por cada componente y otra gráfica que explica la proporción de varianza por cada variable de la muestra (nos interesan aquellos valores cuya longitud sea mayor)
Numero_componentes indica la cantidad de componentes principales que se consideran óptimos a usar en la base de datos de tal manera que se conserve la misma cantidad de información proporcionada al principio
pesos muestra la gráfica de los pesos asignados a cada una de las variables originales en los actuales componentes principales (considerando solamente la cantidad de componentes proporcionadas por Numero_componentes)
La lista que contiene las características del analisis factorial contiene los siguientes elementos:
mat_correlacion es la matriz de correlacion de todas las variables no categóricas.
scree_plot es la representacion gráfica de los eigenvalores en una matriz de correlación. Sirve tambien para determinar la dimensión de los factores a utilizar en el modelo de analisis factorial.
puntuaciones es una representacion grafica de los pesos que son considerados como las saturaciones por cada observación de las variables ingresadas al cálculo del AF.
cor_fact es la correlacion entre los pesos factoriales. Los scores son el peso para el cálculo de un índice que explica por cada i-ésima fila la variabilidad de todo el conjunto de datos.
factores_none indica la cantidad de factores ideal, sin haber aplicado ninguna rotacion tal que el p-value > 0.5
factanal es la salida del modelo ‘factanal’ con el número de factores ideal (tales que el p-value>0.5), sin aplicar ninguna rotacion y con el tipo de score que ingreso el usuario.
heatmap_modelo_usuario indica la cantidad de factores ideal, tras haber aplicado la rotacion que el usuario especifico
heatmap_modelo1 es un heatmap del modelo ingresado por el usuario, utilizando el numero de factores que indique el usuario, con la rotacion y tipo de scores que se indique.
heatmap_none , heatmap_varimax, heatmap_quarti y heatmap_oblimin son los heatmaps de los 4 modelos con rotaciones distintas para identificar agrupamiento de los datos según el metodo factorial especificado por el usuario
Yo decidí implementar la función creada anteriormente con la base ‘SAheart’ que es una muestra de aquellos hombres con alto riesgo de contraer alguna enfermedad cardiaca en Western Cape, South Africa. La muestra contiene 462 observaciones con 10 variables; de las cuales una es de tipo categórica y es por ello que la eliminé de mi base de datos para evitar generar incongruencias en el análisis.
#D1<-read.csv(params$data, sep="")
D1<- read.csv(file.choose(),header = T,sep=",")
data<-as.data.frame(D1)
source("funciones_PCA_FA.R")
PCA.analisis(data)
## Importance of components:
## PC1 PC2 PC3 PC4 PC5 PC6
## Standard deviation 2.3177 1.4518 1.1935 0.82290 0.65540 0.50918
## Proportion of Variance 0.4883 0.1916 0.1295 0.06156 0.03905 0.02357
## Cumulative Proportion 0.4883 0.6799 0.8094 0.87098 0.91003 0.93360
## PC7 PC8 PC9 PC10 PC11
## Standard deviation 0.48806 0.42719 0.38561 0.31268 0.25141
## Proportion of Variance 0.02165 0.01659 0.01352 0.00889 0.00575
## Cumulative Proportion 0.95526 0.97185 0.98537 0.99425 1.00000
## $rotation
## PC1 PC2 PC3 PC4 PC5
## X0.48 0.3828017 -0.12670267 0.014814238 -0.01659580 0.45534745
## X5.234 0.3840070 0.03414927 -0.018907388 0.12421263 0.49798539
## X2.62 -0.1104791 0.07562008 -0.747423170 -0.27720934 0.14887064
## X2.857 -0.3154218 -0.37696772 0.031215076 -0.28744588 0.19542277
## X0.803 -0.2522924 -0.30795991 -0.464006528 0.03791647 0.17315452
## X13.897 0.2991748 -0.44365930 0.015065989 -0.06191874 0.01564676
## X0.326 0.2983227 -0.35523786 -0.005408489 -0.32668683 -0.47919433
## X0.902 -0.1951335 -0.57215510 0.167160253 0.04445242 -0.02918783
## X0.164 0.2294520 -0.23857627 -0.332964726 0.74706395 -0.21921127
## X0.183 0.3428061 0.16561657 -0.288869323 -0.26114955 -0.37789250
## X4.155 0.3793551 -0.07335835 0.044670282 -0.29077503 0.18098054
## PC6 PC7 PC8 PC9 PC10
## X0.48 -0.14023648 0.01614663 0.07233625 -0.690757215 0.35486068
## X5.234 0.39147661 0.09986979 -0.20985462 0.129737539 -0.59737990
## X2.62 0.07346313 0.45344434 -0.18936449 0.118928950 0.24664817
## X2.857 -0.43867505 0.17595013 -0.05295181 -0.136091977 -0.45044926
## X0.803 0.14392505 -0.73072015 0.13404705 -0.048901492 -0.08294699
## X13.897 0.31605757 0.09297374 0.44155931 0.343301414 0.24354310
## X0.326 0.21705220 -0.13477063 -0.58583221 -0.196716193 -0.01720446
## X0.902 0.08413003 0.34978154 0.15803101 0.009342654 -0.02707277
## X0.164 -0.35845402 0.11403176 -0.13383272 0.026980354 -0.05943208
## X0.183 -0.11372540 0.05623636 0.55150096 -0.211725645 -0.41401039
## X4.155 -0.55948912 -0.23221330 -0.09425910 0.518430389 0.10635860
## PC11
## X0.48 -0.03663325
## X5.234 -0.08145749
## X2.62 -0.05079530
## X2.857 0.43473113
## X0.803 -0.11349242
## X13.897 0.47819965
## X0.326 0.03100766
## X0.902 -0.66975516
## X0.164 0.09872011
## X0.183 -0.15532593
## X4.155 -0.27475567
## [1] "La cantidad de componentes que se van a considerar son 3 ya que son aquellos asociados a eigenvalores mayores a 1"
## [1] "La cantidad de factores ideal son 4 sin aplicar ninguna rotación"
##
## Call:
## factanal(x = data, factors = z, scores = c(params$type_scores), rotation = "none")
##
## Uniquenesses:
## X0.48 X5.234 X2.62 X2.857 X0.803 X13.897 X0.326 X0.902 X0.164
## 0.21 0.24 0.19 0.00 0.31 0.09 0.33 0.05 0.53
## X0.183 X4.155
## 0.24 0.14
##
## Loadings:
## Factor1 Factor2 Factor3 Factor4
## X5.234 0.70 0.49
## X2.857 -1.00
## X0.803 -0.62 0.54
## X0.902 -0.79 0.41 -0.38
## X0.183 0.70 0.44
## X0.48 0.52 0.67
## X13.897 0.93
## X0.326 0.77
## X4.155 0.51 0.62 0.39
## X2.62 -0.32 0.64 0.53
## X0.164 0.33 0.46 0.38
##
## Factor1 Factor2 Factor3 Factor4
## SS loadings 3.73 3.08 0.97 0.90
## Proportion Var 0.34 0.28 0.09 0.08
## Cumulative Var 0.34 0.62 0.71 0.79
##
## Test of the hypothesis that 4 factors are sufficient.
## The chi square statistic is 23.13 on 17 degrees of freedom.
## The p-value is 0.145
## [1] "La cantidad de factores ideal son 4 usando la rotacion que ingreso el usuario"
## $xyz.convert
## function (x, y = NULL, z = NULL)
## {
## xyz <- xyz.coords(x, y, z)
## if (angle > 2) {
## temp <- xyz$x
## xyz$x <- xyz$y
## xyz$y <- temp
## }
## y <- (xyz$y - y.add)/y.scal
## return(list(x = xyz$x/x.scal + yx.f * y, y = xyz$z/z.scal +
## yz.f * y))
## }
## <bytecode: 0x0000000021e30320>
## <environment: 0x000000003438d0a0>
##
## $points3d
## function (x, y = NULL, z = NULL, type = "p", ...)
## {
## xyz <- xyz.coords(x, y, z)
## if (angle > 2) {
## temp <- xyz$x
## xyz$x <- xyz$y
## xyz$y <- temp
## }
## y2 <- (xyz$y - y.add)/y.scal
## x <- xyz$x/x.scal + yx.f * y2
## y <- xyz$z/z.scal + yz.f * y2
## mem.par <- par(mar = mar, usr = usr)
## if (type == "h") {
## y2 <- z.min + yz.f * y2
## segments(x, y, x, y2, ...)
## points(x, y, type = "p", ...)
## }
## else points(x, y, type = type, ...)
## }
## <bytecode: 0x0000000021e327b8>
## <environment: 0x000000003438d0a0>
##
## $plane3d
## function (Intercept, x.coef = NULL, y.coef = NULL, lty = "dashed",
## lty.box = NULL, draw_lines = TRUE, draw_polygon = FALSE,
## polygon_args = list(border = NA, col = rgb(0, 0, 0, 0.2)),
## ...)
## {
## if (!is.atomic(Intercept) && !is.null(coef(Intercept))) {
## Intercept <- coef(Intercept)
## if (!("(Intercept)" %in% names(Intercept)))
## Intercept <- c(0, Intercept)
## }
## if (is.null(lty.box))
## lty.box <- lty
## if (is.null(x.coef) && length(Intercept) == 3) {
## x.coef <- Intercept[if (angle > 2)
## 3
## else 2]
## y.coef <- Intercept[if (angle > 2)
## 2
## else 3]
## Intercept <- Intercept[1]
## }
## mem.par <- par(mar = mar, usr = usr)
## x <- x.min:x.max
## y <- 0:y.max
## ltya <- c(lty.box, rep(lty, length(x) - 2), lty.box)
## x.coef <- x.coef * x.scal
## z1 <- (Intercept + x * x.coef + y.add * y.coef)/z.scal
## z2 <- (Intercept + x * x.coef + (y.max * y.scal + y.add) *
## y.coef)/z.scal
## if (draw_polygon)
## do.call("polygon", c(list(c(x.min, x.min + y.max * yx.f,
## x.max + y.max * yx.f, x.max), c(z1[1], z2[1] + yz.f *
## y.max, z2[length(z2)] + yz.f * y.max, z1[length(z1)])),
## polygon_args))
## if (draw_lines)
## segments(x, z1, x + y.max * yx.f, z2 + yz.f * y.max,
## lty = ltya, ...)
## ltya <- c(lty.box, rep(lty, length(y) - 2), lty.box)
## y.coef <- (y * y.scal + y.add) * y.coef
## z1 <- (Intercept + x.min * x.coef + y.coef)/z.scal
## z2 <- (Intercept + x.max * x.coef + y.coef)/z.scal
## if (draw_lines)
## segments(x.min + y * yx.f, z1 + y * yz.f, x.max + y *
## yx.f, z2 + y * yz.f, lty = ltya, ...)
## }
## <bytecode: 0x0000000021e33b78>
## <environment: 0x000000003438d0a0>
##
## $box3d
## function (...)
## {
## mem.par <- par(mar = mar, usr = usr)
## lines(c(x.min, x.max), c(z.max, z.max), ...)
## lines(c(0, y.max * yx.f) + x.max, c(0, y.max * yz.f) + z.max,
## ...)
## lines(c(0, y.max * yx.f) + x.min, c(0, y.max * yz.f) + z.max,
## ...)
## lines(c(x.max, x.max), c(z.min, z.max), ...)
## lines(c(x.min, x.min), c(z.min, z.max), ...)
## lines(c(x.min, x.max), c(z.min, z.min), ...)
## }
## <bytecode: 0x0000000021e3e358>
## <environment: 0x000000003438d0a0>
##
## $contour3d
## function (f, x.count = 10, y.count = 10, type = "l", lty = "24",
## x.resolution = 50, y.resolution = 50, ...)
## {
## if (class(f) == "lm") {
## vars <- all.vars(formula(f))
## }
## else vars <- c("z", "x", "y")
## for (x1 in seq(x.range.fix[1], x.range.fix[2], length = x.count)) {
## d <- data.frame(x1, seq(y.range.fix[1], y.range.fix[2],
## length = y.resolution))
## names(d) <- vars[-1]
## if (class(f) == "lm") {
## d[vars[1]] <- predict(f, newdata = d)
## }
## else d[vars[1]] <- f(d[[1]], d[[2]])
## xyz <- xyz.coords(d)
## if (angle > 2) {
## temp <- xyz$x
## xyz$x <- xyz$y
## xyz$y <- temp
## }
## y2 <- (xyz$y - y.add)/y.scal
## x <- xyz$x/x.scal + yx.f * y2
## y <- xyz$z/z.scal + yz.f * y2
## mem.par <- par(mar = mar, usr = usr)
## if (type == "h") {
## y2 <- z.min + yz.f * y2
## segments(x, y, x, y2, ...)
## points(x, y, type = "p", ...)
## }
## else points(x, y, type = type, lty = lty, ...)
## }
## for (x2 in seq(y.range.fix[1], y.range.fix[2], length = y.count)) {
## d <- data.frame(seq(x.range.fix[1], x.range.fix[2], length = x.resolution),
## x2)
## names(d) <- vars[-1]
## if (class(f) == "lm") {
## d[vars[1]] <- predict(f, newdata = d)
## }
## else d[vars[1]] <- f(d[[1]], d[[2]])
## xyz <- xyz.coords(d)
## if (angle > 2) {
## temp <- xyz$x
## xyz$x <- xyz$y
## xyz$y <- temp
## }
## y2 <- (xyz$y - y.add)/y.scal
## x <- xyz$x/x.scal + yx.f * y2
## y <- xyz$z/z.scal + yz.f * y2
## mem.par <- par(mar = mar, usr = usr)
## if (type == "h") {
## y2 <- z.min + yz.f * y2
## segments(x, y, x, y2, ...)
## points(x, y, type = "p", ...)
## }
## else points(x, y, type = type, lty = lty, ...)
## }
## }
## <bytecode: 0x0000000021e404e0>
## <environment: 0x000000003438d0a0>
##
## $par.mar
## $par.mar$mar
## [1] 5.1 4.1 4.1 2.1
rmarkdown::render(input="Analisis_Factorial_y_PCA.Rmd", output_format = "html_document", params = "ask")
## Error: params object already exists in knit environment so can't be overwritten by render params
#library(ElemStatLearn);X=SAheart
#PCA.analisis(X)
#FA.analisis(X)
#if (!isKnownParamsObject) { stop("params object already exists in knit environment ", "so can't be overwritten by render params", call. = FALSE)}