Curso de R:
Capitulo 9: Análisis de Componentes Principales.
El análisis de componentes principales puede encuadrarse dentro del conjunto de técnicas multivariantes conocidas como métodos factoriales (también se incluyen el análisis de factores y el análisis de correspondencias). Pretendemos sintetizar un gran conjunto de datos, crear estructuras de interdependencia entre variables cuantitativas para crear unas nuevas variables que son función lineal de las originales y de las que podemos hacer una representación gráfica. El objetivo del análisis de componentes principales será el reducir la dimensión de un conjunto de p variables a un conjunto m de menor número de variables para mejorar la interpretabilidad de los datos.
Las nuevas variables, las componentes principales, determinan lo esencial de las variables originales, son una combinación lineal de ellas que además tienen unas propiedades interesantes:
Si hay relaciones estocásticas entre las p variables originales entonces podíamos condensar esa información en otras m variables que explican sólo la variación del sistema descartando la información redundante. Geométricamente el subespacio que creamos con las m primeras componentes da el mejor ajuste posible al conjunto de datos medido mediante la suma de los cuadrados de las distancias perpendiculares desde cada punto al subespacio. El subespacio de menor dimensionalidad sería m=1 componente podíamos hacer la representación en un sólo eje pero el conjunto inicial se podía distorsionar, así introduciríamos un nuevo eje para definir un subespacio m=2, perderíamos menos información. Si m=p tendríamos el mismo número de variables, no reduciríamos la dimensión, sólo haríamos una rotación rígida del conjunto de datos.
No voy a entrar en el algoritmo matemático para la obtención de las componentes, si haré alguna reseña en algún momento a términos matemáticos pero de momento no quiero entrar en fórmulas ni ecuaciones. Lo que si es cierto que con R las componentes se obtienen mediante cálculo matricial. Vamos a ver la forma de obtenerlas mediante un ejemplo:
Ejemplo 9.1:
Partimos del siguiente conjunto de datos: Se trata de datos de coches de importación y nacionales [Douglas Montgomery and David Friedman, "Prediction Using Regession Models with Multicollinear Predictor Variables" IIE Transactions (Mayo, 1993) vol. 25 nº 3, 73-85, Montgomery D.C. & Peck E.A., Introduction to Linear Regression Analysis, 2ª edición, J. Wiley and Sons, N.Y. (1992)] bajaté el archivo. Este conjunto de datos contiene las siguientes variables:
Variable | Tipo | Columnas | Descripción añadida |
desplazamiento | numérico | 1-5 | en pulgadas cúbicas |
potencia | numérico | 7-9 | en ft-lbs |
par motor | numérico | 11-13 | en ft-lbs |
razón de compresión | numérico | 15-17 | |
razón árbol trasero | numérico | 19-21 | |
nº de carburadores | numérico | 23 | |
velocidades | numérico | 25 | cuantas |
longitud del coche | numérico | 27-31 | en pulgadas |
anchura del coche | numérico | 33-36 | en pulgadas |
peso del coche | numérico | 38-41 | en lbs |
tipo de transmisión | numérico | 43 | 0=manual 1=automático |
recorrido gasolina | numérico | 45-48 | en millas por galón de gasolina |
Tenemos 12 variables de las que sólo seleccionaremos algunas, comencemos a trabajar con R:
> conjunto.datos<-read.table("c:\\datos\\GAS.TXT") #leemos el archivo > conjunto.datos V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 1 318.0 140 255 8.5 2.7 2 3 215.3 76.3 4370 1 19.7 2 440.0 215 330 8.2 2.9 4 3 184.5 69.0 4215 1 11.2 ... 30 133.6 96 120 8.4 3.9 2 5 171.5 63.4 2535 0 23.9 |
De todas estas variables que contiene el archivo seleccionamos las que nos van a interesar y descartamos otras que no tienen mucha funcionalidad como puedan ser el número de marchas, el tipo de la trasmisión,... para quedarnos con otras características de los coches que nos permitan ver que tipos de coches tenemos e incluso clasificarlos. Nos quedamos con el desplazamiento, la potencia, el par motor, la longitud, la anchura, el peso y el recorrido en gasolina.
> attach(conjunto.datos) > conjunto<-data.frame(V1,V2,V3,V8,V9,V10,V12) > detach(conjunto.datos) > nombres<-c("desplazamiento","potencia","par","longitud","anchura","peso","recorrido") > names(conjunto)<-nombres |
Ya tenemos el conjunto de datos con el que vamos a trabajar, también en este ejemplo se puede ver la función attach función que sirve para "atacar" un conjunto de datos, de este modo nos evitamos el llamar al conjunto con el símblo $. Sobre estas tres variables vamos a realizar el análisis de componentes principales muestrales. Para llevar a cabo este análisis hemos de realizar cálculos matriciales con la matriz de correlaciones y la matriz de varianzas covarianzas, estas dos matrices determinan los dos modos de obtención de las componentes, es decir, componentes principales a partir de la matriz de correlaciones y componentes principales a partir de la matriz de covarianzas.
Componentes a partir de la matriz de correlaciones:.
Si calculamos las componentes a partir de la matriz de correlaciones tendremos las componentes sobre las observaciones tipificadas de este modo nos evitamos los problemas de escala. Para la obtención de la matriz de componentes principales a partir de la matriz de correlaciones tendremos primero que hallar la matriz de correlaciones y esto se hace con la función cor que creo que ya vimos en algún capítulo anterior:
> matriz.correlaciones<-cor(conjunto) > matriz.correlaciones desplazamiento potencia par longitud anchura desplazamiento 1.0000000 0.9406456 0.9895851 0.8670281 0.8001582 potencia 0.9406456 1.0000000 0.9643592 0.8042467 0.7105117 par 0.9895851 0.9643592 1.0000000 0.8662469 0.7881284 longitud 0.8670281 0.8042467 0.8662469 1.0000000 0.8828869 anchura 0.8001582 0.7105117 0.7881284 0.8828869 1.0000000 peso 0.9531800 0.8879129 0.9435772 0.9559969 0.8994470 recorrido -0.8718188 -0.7965605 -0.8493416 -0.7552211 -0.7624550 peso recorrido desplazamiento 0.9531800 -0.8718188 potencia 0.8879129 -0.7965605 par 0.9435772 -0.8493416 longitud 0.9559969 -0.7552211 anchura 0.8994470 -0.7624550 peso 1.0000000 -0.8526911 recorrido -0.8526911 1.0000000 |
Se aprecian unas altas correlaciones entre las variables, esto nos beneficia a la hora de realizar el análisis de componentes ya que se detectarán relaciones lineales entre variables y podemos investigar los patrones que unen las diferentes variables para crear unas nuevas variables que nos describan de forma más simple el conjunto de datos de coches con el que estamos trabajando. Ahora queda obtener las componentes, éstas son las combinaciones lineales de las variables que hacen máxima su varianza y esto se consigue obteniendo los autovalores y los autovectores de la matriz de correlaciones, no voy a explicar el razonamiento matemático, existen algunas páginas en la red donde os lo explican con bastante detalle. Sigamos trabajando con R:
> componentesI<-eigen(matriz.correlaciones) > componentesI $values [1] 6.193181539 0.400764875 0.244830693 0.094091951 0.046951262 0.015094646 [7] 0.005085034 $vectors recorrido peso anchura longitud par potencia desplazamiento -0.3926641 0.2475231 0.05234234 0.03567111 0.61407897 0.01657661 potencia -0.3733929 0.4647583 0.29963669 0.28335837 -0.65342114 -0.11954685 par -0.3914349 0.2911694 0.16717164 0.11038560 0.28865783 0.44120895 longitud -0.3744302 -0.3980948 0.31799457 -0.64622375 -0.22495520 0.33416791 anchura -0.3560523 -0.6557118 -0.12419209 0.63919813 -0.04914155 0.11797501 peso -0.3965847 -0.1523398 0.09815214 -0.17000242 0.15186737 -0.81350329 recorrido 0.3590553 -0.1621960 0.86795951 0.22620880 0.19115713 -0.05826262 desplazamiento desplazamiento 0.63495457 potencia 0.18235333 par -0.66624254 longitud 0.14256169 anchura 0.05420171 peso -0.31004382 recorrido 0.01766344 |
El objeto componentesI recoge los autovalores y los autovectores de la matriz de correlaciones, el número de autovalores no nulos proporciona la dimensión del espacio en el que se encuentran las observaciones; un autovalor nulo revelaría la existencia de una dependencia lineal entre las variables originales. Pues si Z es la matriz de datos tipificados y R es la matriz de correlaciones con pares de autovalores y autovectores (l1,e1),(l2,e2),...,(lp,ep) entonces la i-ésima componente muestral viene dada por y=ei Z=e1i z1+...+epi zp donde los autovalores son una observación genérica de las variables Z1,Z2,...Zp. La varianza total es la suma de los autovalores, y la varianza que explica la j-ésima componente es el autovalor j-ésimo dividido por el número de variables:
> componentesI$values[1]/7 [1] 0.8847402 |
Con la primera componente explica ya un 88% de la variabilidad que es una cantidad más que suficiente para explicar correctamente las variables del conjunto de datos. Si queremos saber cuanto explicamos con la primera y la segunda variable:
> (componentesI$values[1]+componentesI$values[2])/7 [1] 0.9419923 |
Con dos componentes retenidas explicamos ya un 94% de la variabilidad total. El número de componentes a retener depende de la cantidad de varianza que expliquen, en ese caso con la primera componente creo que sería suficiente. Algunas aplicaciones retienen las componentes cuyos autovalores asociados tienen un valor mayor que 1. Ahora nos queda por ver cual sería la componente:
> componetesI$vectors[1:7] desplazamiento potencia par longitud anchura -0.3926641 -0.3733929 -0.3914349 -0.3744302 -0.3560523 peso recorrido -0.3965847 0.3590553 |
Pues aquí tenemos la componente principal: Z1=-0.3926desplazamiento-0.3734potencia-0.3914par-0.3744longitud-0.356anchura-0.3966peso+0.359recorrido; toma valores muy parecidos para todas las variables excepto recorrido que es positiva esto se puede interpretar como a menor valor tome la variable componente mejor será el coche aunque hay que tener en cuenta que los coches buenos hacen un recorrido menor que los coches pequeños. Para ver como se comporta la componente hemos de introducir esta variable en el conjunto de datos para ver que valor toma para cada observación, esto lo podemos hacer introduciendo la fórmula para crear la nueva variable componente o con cálculo matricial. Lo voy a hacer con el cálculo matricial para que veáis como se trabaja con matrices en R:
> x<-as.matrix(conjunto) #x es la matriz del conjunto de datos 30x7 > y<-as.matrix(componente.vector) #y es la matriz 7x1 con los valores de la componente > x %*% y #multiplicamos matrices y obtenemos una matriz 30x1 con los valores de la componente [,1] 1 -2110.7416 2 -2143.4584 ... 29 -2262.1919 30 -1218.8272 |
Se puede ver que para realizar operaciones con matrices es necesario incluir el símbolo %, ahora nos interesa ver la evolución de la componente en el conjunto de observaciones, para ello tenemos que unir matrices:
> componete.datos<-as.matrix(x %*% y ) #matriz de componentes > conjunto.final<-cbind(conjunto,componete.datos) #unimos matrices con la función cbind > conjunto.final desplazamiento potencia par longitud anchura peso recorrido componete.datos 1 318.0 140 255 215.3 76.3 4370 19.7 -2110.7416 2 440.0 215 330 184.5 69.0 4215 11.2 -2143.4584 3 351.0 143 255 199.9 74.0 3890 18.3 -1928.3765 4 360.0 180 290 214.2 76.3 4250 21.5 -2107.2210 5 140.0 83 109 168.8 69.4 2700 20.3 -1280.0348 6 85.3 80 83 160.6 62.2 2009 36.5 -961.7679 7 350.0 165 260 200.3 69.9 3910 18.9 -1944.5619 8 96.9 75 83 162.5 65.0 2320 30.4 -1091.6923 9 351.0 148 243 215.5 78.5 4540 13.9 -2192.3495 10 440.0 215 330 231.0 79.7 5185 14.9 -2548.0378 11 171.0 109 146 170.4 66.9 2655 21.5 -1297.8304 12 302.0 129 220 199.9 74.0 3890 17.8 -1890.3878 13 350.0 155 250 196.7 72.2 3910 17.8 -1936.7795 14 318.0 145 255 197.6 71.0 3666 16.4 -1826.0833 15 231.0 110 175 179.3 65.4 3050 23.5 -1491.8465 16 96.9 75 83 165.2 61.8 2275 31.9 -1073.1790 17 500.0 190 360 224.1 79.8 5290 14.4 -2613.2788 18 231.0 110 175 179.3 65.4 3020 22.1 -1480.4516 19 350.0 170 275 199.6 72.9 3860 17.0 -1933.9594 20 250.0 105 185 196.7 72.2 3510 20.0 -1693.9764 21 225.0 95 170 194.0 71.8 3365 20.1 -1615.8603 22 89.7 70 81 155.7 64.0 1905 34.7 -917.1865 23 350.0 155 250 195.4 74.4 3885 16.5 -1927.6283 24 258.0 110 195 171.5 77.0 3375 19.7 -1641.7412 25 460.0 223 366 228.0 79.8 5430 13.3 -2669.6199 26 360.0 195 295 209.3 77.4 4215 13.8 -2102.2203 27 262.0 110 200 179.3 65.4 3180 21.5 -1566.0791 28 350.0 165 255 185.2 69.0 3660 16.5 -1838.3459 29 351.0 148 243 216.1 78.5 4715 13.3 -2262.1919 30 133.6 96 120 171.5 63.4 2535 23.9 -1218.8272 |
Vemos que los coches más potentes tienen un valor de la componente más bajo que los menos potentes, sin embargo recorren mucho menos espacio que éstos, se confirman los planteamientos que se hicieron con anterioridad. Con esta componente podemos saber que tipo de coche es cada uno sin necesidad de analizar todas las variables, si dispusiéramos de precios podíamos saber cual es más caro o más barato e incluso podemos ubicar otras observaciones.
Componentes principales a partir de la matriz de covarianzas:
Calcular las componentes a partir de la matriz de covarianzas no difiere mucho de calcularlas a partir de la matriz de correlaciones, elegir uno u otro método depende de las variables que tenemos en nuestro conjunto de datos. Variables con varianzas grandes tienden a asociarse con autovalores grandes y variables con varianzas pequeñas tiende a asociarse con autovalores pequeños, así pues sería conveniente el tipificar las unidades muestrales para que las variables sean comparables. Veamos que sucede en nuestro conjunto de datos:
> cov(conjunto) desplazamiento potencia par longitud anchura peso recorrido desplazamiento 13463.3826 4873.3970 9538.3428 2128.3800 527.21145 104071.183 -633.53025 potencia 4873.3970 1993.6885 3576.9276 759.7257 180.14897 37305.897 -222.74678 par 9538.3428 3576.9276 6900.5759 1522.3807 371.76759 73756.207 -441.86448 longitud 2128.3800 759.7257 1522.3807 447.5874 106.06593 19031.538 -100.06382 anchura 527.2114 180.1490 371.7676 106.0659 32.24510 4806.024 -27.11503 peso 104071.1828 37305.8966 73756.2069 19031.5379 4806.02414 885435.586 -5024.97931 recorrido -633.5303 -222.7468 -441.8645 -100.0638 -27.11503 -5024.979 39.22185 |
Vemos que las unidades son difícilmente comparables, sería conveniente el tipificar las observaciones. Desconozco si hay alguna función de R con la que podamos tipificar variables, por eso la mejor opción va a ser programarla:
> tipificar<-function(x){ (x-mean(x))/varianza(x)} |
No tiene mayor complicación poco que comentar, la función varianza ya la teníamos creada en el capítulo 3; a partir de aquí vamos a realizar el análisis de componentes principales sin olvidar que estamos trabajando con los datos tipificados. El proceso es el mismo que con la matriz de correlaciones:
> datos.tipificados<-tipificar(conjunto) > componentesII<-eigen(cov(datos.tipificados)) > componentesII $values [1] 578.5921014 3.1441794 1.7077434 1.2076084 1.0943170 0.5415443 0.2088097 $vectors recorrido peso anchura longitud par potencia desplazamiento 2.510359e-03 -0.019586489 0.106248291 -0.025785327 -0.982859312 0.145815869 potencia 4.687239e-05 -0.589985214 0.792848158 0.107833661 0.097845596 0.026642031 par -2.982895e-03 -0.797331687 -0.567048694 -0.061191845 -0.065755761 -0.160532844 longitud 1.175570e-03 0.016218362 -0.116217484 0.991844352 -0.041956706 -0.022501828 anchura -4.361458e-03 0.116691682 0.153377013 -0.012443462 -0.070359659 -0.668265795 peso -9.999782e-01 0.001688000 0.001079292 0.001363264 -0.001682031 0.005744282 recorrido 2.827855e-03 -0.043739740 -0.039073016 0.007117519 0.115656021 0.710731059 desplazamiento desplazamiento -0.019539430 potencia 0.037384301 par -0.094180712 longitud -0.014393132 anchura -0.714951066 peso 0.001379889 recorrido -0.691365696 |
Ahora la proporción de varianza debida a la k-ésima componente es lk/( l1 + l2 +...+ lp ) Esto traducido en R nos queda:
> componentesII$values[1]/sum(componentesII$values) [1] 0.986523 |
De nuevo espectacular el resultado obtenido con la primera componente, explicamos con sólo una componente el 98% de la variabilidad de las variables que componen el conjunto de datos. A partir de aquí el trabajo sería completamente análogo al realizado con la matriz de correlaciones si bien con este método el análisis de componentes principales es aun mejor que con la matriz de correlaciones. Nos faltaría por analizar algún gráfico de componentes, seguro que en próximos capítulos veremos más posibilidades del análisis de componentes.
Capítulo
10: Análisis
de conglomerados (cluster) I.