El análisis multivariado proporciona una serie de técnicas y modelos con el propósito de analizar desde un análisis exploratorio hasta la búsqueda de patrones en los datos multivariados. Esta técnica es de gran utilidad para sustentar y explicar propiedades y características relevantes de una población de individuos. Las variables con las que trabajaremos son variables medibles directamente y sus valores pueden estar en escalas nominales, ordinales, o numéricas. Tomemos como ejemplo un conjunto de clientes de los cuales se recaba la edad, el sueldo, el número de años en el trabajo y el monto de crédito solicitado, se trata entonces de estudiar cada variable y las relaciones entre ellas a fin de poder analizar si la edad o el número de años laborales pudieran influir en la posibilidad de obtener una hipoteca.
Este tipo de datos se conocen como “multivalidados” y se representan en matrices de datos conocidas como “data frames”. Observemos cómo se estructura un data frame. Aquí cada fila asignada a una observación o unidad i de la población, tiene valores característicos que van desde x 11 x 12 hasta x 1 p para cada variable x 1 mayúscula x 2 mayúscula hasta x p mayúscula.
El análisis multivariado como mencionamos permite el estudio de interrelaciones en un grupo de variables. Veamos primeramente cómo encontrar las relaciones que sirvan para explicar la variabilidad de los valores de una variable o de un grupo de variables en términos de otro grupo de variables como se hace en el análisis de regresión lineal.
Para esto suelen utilizarse dos medidas muy importantes la “covarianza” y la “correlación”. La covarianza entre dos variables se define como el valor esperado de los productos de las desviaciones de los valores de cada variable con respecto a su media. La covarianza es una relación lineal que puede existir entre los valores de dos variables numéricas.
Para un conjunto de datos multivariados tenemos una matriz de covarianza a veces llamada “matriz de varianza-covarianza”. En esta matriz las variables individuales se distribuyen a lo largo de la diagonal principal y las covarianzas fuera de la diagonal. Una de las dificultades de la covarianza está en su interpretación, no se puede indicar si la covarianza es grande o pequeña pues depende de las unidades medidas con las que se trabaje. Para evitar esto, la covarianza se expresa de manera relativa y es así como se calcula la correlación entre dos variables, que es la medida con la cual se evalúa la fuerza de la relación lineal que pudiera existir entre las variables.
La correlación ro y j entre las variables xi y yi se definen como: "La correlación es un número que va entre menos uno y uno si el valor es cercano a cero o cero no existe relación lineal entre las dos variables. A medida que se aproxima a uno o menos uno, se tiene una alta correlación entre las variables.
Cargaremos una base de datos multivariado desde la nube, un archivo con extensión .csv (separado por comas) y la denominaremos redwine. Además, header = T hace referencia a que la base de datos tiene encabezado o el nombre de cada variable, de ahí que sea igual a T de True. En caso contrario, se escribe F de False.
redwine <- read.csv("https://bit.ly/2DdpG9E", header = T)
Los datos provienen de una cosecha de vinos, es decir es una muestra tomada en un momento del tiempo y corresponde a data de corte transversal. Además, dicha data contiene una variable categorica denominada quality o calidad. Esto quiere decir que la cosecha presenta diversas calidades de vino y lo que queremos estudiar es cuáles son las característica de cada calidad. Es decir. cómo están correlacionadas las variables que permiten tener un cultivo de una calidad determinada.
Analizamos el data frame en términos de su estructura y sus características estadísticas esto lo hacemos usando los comandos str y summary La importancia de este análisis radica en que si no conocemos el tipo de variables o sus parámetros estadísticos no podremos hacer el análisis.
El comando str de structure o estructura muestra de forma compacta la estructura interna de un objeto R, en este caso un dataframe. Idealmente, solo se muestra una línea para cada estructura “básica”. Es especialmente adecuado para mostrar de forma compacta el contenido (abreviado) de listas (posiblemente anidadas). La idea es dar una salida razonable para cualquier objeto R. Esto se aprecia a continuación:
str(redwine)
## 'data.frame': 1599 obs. of 12 variables:
## $ fixed.acidity : num 7.4 7.8 7.8 11.2 7.4 7.4 7.9 7.3 7.8 7.5 ...
## $ volatile.acidity : num 0.7 0.88 0.76 0.28 0.7 0.66 0.6 0.65 0.58 0.5 ...
## $ citric.acid : num 0 0 0.04 0.56 0 0 0.06 0 0.02 0.36 ...
## $ residual.sugar : num 1.9 2.6 2.3 1.9 1.9 1.8 1.6 1.2 2 6.1 ...
## $ chlorides : num 0.08 0.1 0.09 0.08 0.08 0.08 0.07 0.07 0.07 0.07 ...
## $ free.sulfur.dioxide : num 11 25 15 17 11 13 15 15 9 17 ...
## $ total.sulfur.dioxide: num 34 67 54 60 34 40 59 21 18 102 ...
## $ density : num 1 1 1 1 1 1 1 0.99 1 1 ...
## $ pH : num 3.51 3.2 3.26 3.16 3.51 3.51 3.3 3.39 3.36 3.35 ...
## $ sulphates : num 0.56 0.68 0.65 0.58 0.56 0.56 0.46 0.47 0.57 0.8 ...
## $ alcohol : num 9.4 9.8 9.8 9.8 9.4 9.4 9.4 10 9.5 10.5 ...
## $ quality : num 5 5 5 6 5 5 5 7 7 5 ...
Nótece que R muestra el total de variables (12) y el total de observaciones de cada una. Además, tenga cuidado al interpretar la variable quality porque no se trata de una variable que define una atributo o cualidad.
La función summary por otro lado que se utiliza para producir resúmenes de los resultados de varias funciones de ajuste de modelos. La función invoca métodos particulares que dependen de la clase del primer argumento. El caso de un data Frame nos da: El valor mínimo, el máximo, el promedio, la mediana y los valores de el 1er y 3er cuantil
summary(redwine)
## fixed.acidity volatile.acidity citric.acid residual.sugar
## Min. : 4.60 Min. :0.1200 Min. :0.000 Min. : 0.900
## 1st Qu.: 7.10 1st Qu.:0.3900 1st Qu.:0.090 1st Qu.: 1.900
## Median : 7.90 Median :0.5200 Median :0.260 Median : 2.200
## Mean : 8.32 Mean :0.5284 Mean :0.271 Mean : 2.539
## 3rd Qu.: 9.20 3rd Qu.:0.6400 3rd Qu.:0.420 3rd Qu.: 2.600
## Max. :15.90 Max. :1.5800 Max. :1.000 Max. :15.500
## chlorides free.sulfur.dioxide total.sulfur.dioxide density
## Min. :0.01000 Min. : 1.00 Min. : 6.00 Min. :0.9900
## 1st Qu.:0.07000 1st Qu.: 7.00 1st Qu.: 22.00 1st Qu.:1.0000
## Median :0.08000 Median :14.00 Median : 38.00 Median :1.0000
## Mean :0.08787 Mean :15.87 Mean : 46.47 Mean :0.9985
## 3rd Qu.:0.09000 3rd Qu.:21.00 3rd Qu.: 62.00 3rd Qu.:1.0000
## Max. :0.61000 Max. :72.00 Max. :289.00 Max. :1.0000
## pH sulphates alcohol quality
## Min. :2.740 Min. :0.3300 Min. : 8.40 Min. :3.000
## 1st Qu.:3.210 1st Qu.:0.5500 1st Qu.: 9.50 1st Qu.:5.000
## Median :3.310 Median :0.6200 Median :10.20 Median :6.000
## Mean :3.311 Mean :0.6581 Mean :10.42 Mean :5.636
## 3rd Qu.:3.400 3rd Qu.:0.7300 3rd Qu.:11.10 3rd Qu.:6.000
## Max. :4.010 Max. :2.0000 Max. :14.90 Max. :8.000
Nuevamente, se debe tener cuidado con la variable quality al ser esta cualitativa.
Calculamos la VAR-COV entre vectores de toda la base de datos
cov(redwine)
## fixed.acidity volatile.acidity citric.acid
## fixed.acidity 3.031416389 -7.999457e-02 2.278200e-01
## volatile.acidity -0.079994567 3.227853e-02 -1.932831e-02
## citric.acid 0.227820004 -1.932831e-02 3.794748e-02
## residual.sugar 0.281756262 5.626896e-04 3.943427e-02
## chlorides 0.007671441 5.312920e-04 1.839191e-03
## free.sulfur.dioxide -2.800921493 -2.067362e-02 -1.242521e-01
## total.sulfur.dioxide -6.482345858 4.499208e-01 2.276973e-01
## density 0.002127618 4.563107e-05 9.200983e-05
## pH -0.183585704 6.504516e-03 -1.629758e-02
## sulphates 0.054010092 -7.941854e-03 1.032771e-02
## alcohol -0.114442221 -3.873295e-02 2.281373e-02
## quality 0.174423588 -5.665886e-02 3.561189e-02
## residual.sugar chlorides free.sulfur.dioxide
## fixed.acidity 0.2817562623 7.671441e-03 -2.800921e+00
## volatile.acidity 0.0005626896 5.312920e-04 -2.067362e-02
## citric.acid 0.0394342700 1.839191e-03 -1.242521e-01
## residual.sugar 1.9878971330 3.465161e-03 2.758611e+00
## chlorides 0.0034651607 2.219917e-03 1.400803e-03
## free.sulfur.dioxide 2.7586114522 1.400803e-03 1.094149e+02
## total.sulfur.dioxide 9.4164414790 6.980924e-02 2.297375e+02
## density 0.0006553474 2.872536e-05 -3.153547e-04
## pH -0.0186442890 -1.914959e-03 1.136531e-01
## sulphates 0.0013209414 2.942420e-03 9.159247e-02
## alcohol 0.0632245918 -1.105502e-02 -7.736191e-01
## quality 0.0156350457 -5.013244e-03 -4.279071e-01
## total.sulfur.dioxide density pH
## fixed.acidity -6.482346e+00 2.127618e-03 -0.1835857036
## volatile.acidity 4.499208e-01 4.563107e-05 0.0065045159
## citric.acid 2.276973e-01 9.200983e-05 -0.0162975823
## residual.sugar 9.416441e+00 6.553474e-04 -0.0186442890
## chlorides 6.980924e-02 2.872536e-05 -0.0019149587
## free.sulfur.dioxide 2.297375e+02 -3.153547e-04 0.1136530908
## total.sulfur.dioxide 1.082102e+03 8.759714e-03 -0.3376987925
## density 8.759714e-03 1.272072e-05 -0.0001276217
## pH -3.376988e-01 -1.276217e-04 0.0238351805
## sulphates 2.394710e-01 4.735653e-05 -0.0051461858
## alcohol -7.208968e+00 -1.977641e-03 0.0338323467
## quality -4.917237e+00 -6.069501e-04 -0.0071978223
## sulphates alcohol quality
## fixed.acidity 5.401009e-02 -0.114442221 0.1744235876
## volatile.acidity -7.941854e-03 -0.038732949 -0.0566588630
## citric.acid 1.032771e-02 0.022813734 0.0356118929
## residual.sugar 1.320941e-03 0.063224592 0.0156350457
## chlorides 2.942420e-03 -0.011055024 -0.0050132436
## free.sulfur.dioxide 9.159247e-02 -0.773619135 -0.4279070696
## total.sulfur.dioxide 2.394710e-01 -7.208968316 -4.9172370717
## density 4.735653e-05 -0.001977641 -0.0006069501
## pH -5.146186e-03 0.033832347 -0.0071978223
## sulphates 2.873262e-02 0.016906902 0.0344134084
## alcohol 1.690690e-02 1.135667879 0.4097910968
## quality 3.441341e-02 0.409791097 0.6521684000
En la diagonal principal encontramos la varianza de cada variable, mientras que los valores en los extremos es la covarianza entre dos variables. Nótece que el signo negativo o positivo indica el sentido de la relación entre las variables ya sea negativo (cuando una aumenta la otra se reduce) o positivo respectivamente, mientras que valores cercanos a 0 indican una relación débil entre las variables y en caso contrario, valores cercanos a 1 indican una relación fuerte.
También podemos calcular la matriz de correlaciones entre todas las variables
cor(redwine)
## fixed.acidity volatile.acidity citric.acid residual.sugar
## fixed.acidity 1.00000000 -0.25572948 0.67170343 0.114776724
## volatile.acidity -0.25572948 1.00000000 -0.55226229 0.002221340
## citric.acid 0.67170343 -0.55226229 1.00000000 0.143577162
## residual.sugar 0.11477672 0.00222134 0.14357716 1.000000000
## chlorides 0.09351597 0.06276362 0.20038577 0.052162455
## free.sulfur.dioxide -0.15379419 -0.01100073 -0.06097813 0.187048995
## total.sulfur.dioxide -0.11318144 0.07612811 0.03553302 0.203027882
## density 0.34262182 0.07121114 0.13243017 0.130322333
## pH -0.68297819 0.23450324 -0.54190414 -0.085652422
## sulphates 0.18300566 -0.26078190 0.31277004 0.005527121
## alcohol -0.06167907 -0.20230098 0.10989532 0.042078806
## quality 0.12405165 -0.39050903 0.22637251 0.013731637
## chlorides free.sulfur.dioxide total.sulfur.dioxide
## fixed.acidity 0.093515966 -0.153794193 -0.11318144
## volatile.acidity 0.062763615 -0.011000729 0.07612811
## citric.acid 0.200385774 -0.060978129 0.03553302
## residual.sugar 0.052162455 0.187048995 0.20302788
## chlorides 1.000000000 0.002842304 0.04504124
## free.sulfur.dioxide 0.002842304 1.000000000 0.66766645
## total.sulfur.dioxide 0.045041242 0.667666450 1.00000000
## density 0.170939059 -0.008452892 0.07466206
## pH -0.263258128 0.070377499 -0.06649456
## sulphates 0.368424679 0.051657572 0.04294684
## alcohol -0.220173780 -0.069400617 -0.20564269
## quality -0.131756039 -0.050656057 -0.18510029
## density pH sulphates alcohol
## fixed.acidity 0.342621816 -0.68297819 0.183005664 -0.06167907
## volatile.acidity 0.071211144 0.23450324 -0.260781896 -0.20230098
## citric.acid 0.132430175 -0.54190414 0.312770044 0.10989532
## residual.sugar 0.130322333 -0.08565242 0.005527121 0.04207881
## chlorides 0.170939059 -0.26325813 0.368424679 -0.22017378
## free.sulfur.dioxide -0.008452892 0.07037750 0.051657572 -0.06940062
## total.sulfur.dioxide 0.074662064 -0.06649456 0.042946836 -0.20564269
## density 1.000000000 -0.23177121 0.078331510 -0.52031459
## pH -0.231771209 1.00000000 -0.196647602 0.20563509
## sulphates 0.078331510 -0.19664760 1.000000000 0.09359460
## alcohol -0.520314592 0.20563509 0.093594599 1.00000000
## quality -0.210725598 -0.05773139 0.251397079 0.47616445
## quality
## fixed.acidity 0.12405165
## volatile.acidity -0.39050903
## citric.acid 0.22637251
## residual.sugar 0.01373164
## chlorides -0.13175604
## free.sulfur.dioxide -0.05065606
## total.sulfur.dioxide -0.18510029
## density -0.21072560
## pH -0.05773139
## sulphates 0.25139708
## alcohol 0.47616445
## quality 1.00000000
Estos resultados deben tener concordancia con lo obtenido anteriormente. Así podemos observar las correlaciones entres las variables, ya sean positivas (si tienen un valor positivo) o negativas. Los resultados corresponde a porcentajes de correlación y el signo indica si la correlación es ascendente o descendente.
También podemos extraer estas correlaciones para sola alguna de estas variables. Por ejemplo:
cor(redwine[, c("fixed.acidity", "citric.acid", "free.sulfur.dioxide")])
## fixed.acidity citric.acid free.sulfur.dioxide
## fixed.acidity 1.0000000 0.67170343 -0.15379419
## citric.acid 0.6717034 1.00000000 -0.06097813
## free.sulfur.dioxide -0.1537942 -0.06097813 1.00000000
Además, podemos ver todas las herramientas que proporciona el comando cor() escribiendo ?cor(), de tal forma que podemos ampliar el análisis. Por ejemplo, si queremos ver otros coeficientes de correlación entre las variables escribimos el siguiente comando:
cor(redwine[, c("fixed.acidity", "citric.acid", "free.sulfur.dioxide")], method = "pearson")
## fixed.acidity citric.acid free.sulfur.dioxide
## fixed.acidity 1.0000000 0.67170343 -0.15379419
## citric.acid 0.6717034 1.00000000 -0.06097813
## free.sulfur.dioxide -0.1537942 -0.06097813 1.00000000
cor(redwine[, c("fixed.acidity", "citric.acid", "free.sulfur.dioxide")], method = "kendall")
## fixed.acidity citric.acid free.sulfur.dioxide
## fixed.acidity 1.0000000 0.48427123 -0.11930091
## citric.acid 0.4842712 1.00000000 -0.04980428
## free.sulfur.dioxide -0.1193009 -0.04980428 1.00000000
cor(redwine[, c("fixed.acidity", "citric.acid", "free.sulfur.dioxide")], method = "spearman")
## fixed.acidity citric.acid free.sulfur.dioxide
## fixed.acidity 1.0000000 0.66170842 -0.17513656
## citric.acid 0.6617084 1.00000000 -0.07645158
## free.sulfur.dioxide -0.1751366 -0.07645158 1.00000000
cor(redwine[, c("fixed.acidity", "citric.acid", "free.sulfur.dioxide")],
method = c("pearson", "kendall", "spearman"))
## fixed.acidity citric.acid free.sulfur.dioxide
## fixed.acidity 1.0000000 0.67170343 -0.15379419
## citric.acid 0.6717034 1.00000000 -0.06097813
## free.sulfur.dioxide -0.1537942 -0.06097813 1.00000000
Recordemos que el coeficiente de correlación de Pearson es una medida de dependencia lineal entre dos variables aleatorias cuantitativas. A diferencia de la covarianza, la correlación de Pearson es independiente de la escala de medida de las variables.
De manera menos formal, podemos definir el coeficiente de correlación de Pearson como un índice que puede utilizarse para medir el grado de relación de dos variables siempre y cuando ambas sean cuantitativas y continuas.
Además, de acuerdo a los valores que obtengamos se puede interpretar de la siguiente manera:
Si \(r=1\), existe una correlación positiva perfecta. El índice indica una dependencia total entre las dos variables denominada relación directa: cuando una de ellas aumenta, la otra también lo hace en proporción constante.
Si \(0<r<1\) entonces existe una correlación positiva.
Si \(r=0\) entonces no existe relación lineal pero esto no necesariamente implica que las variables son independientes: pueden existir todavía relaciones no lineales entre las dos variables.
Si \(-1<r<0\) existe una correlación negativa.
Si \(r=-1\) existe una correlación negativa perfecta. El índice indica una dependencia total entre las dos variables llamada relación inversa: cuando una de ellas aumenta, la otra disminuye en proporción constante.
Podemos graficar el conjunto de variables de par en par para observar si gráficamente existe una relación lineal entre estas y su tendencia, ya sea creciente o decreciente. Además, en la primera linea de código estamos definiendo el tamaño máximo de la imagen y la posición en el centro del documento.
plot(redwine)
De igual forma, podemos graficar solo las correlaciones de las variables de interes. por ejemplo:
plot(redwine[, c("fixed.acidity", "citric.acid", "free.sulfur.dioxide")])
library(tidyverse)
ggplot(redwine, mapping = aes(x = fixed.acidity, y = pH)) +
geom_point() +
geom_smooth()
Lo importante es entender que dato que el coeficiente de correlación es una medidad de asociación LINEAL, nos interesa ver gráficamente si dicha tendencia corresponde con el valor del coeficiente obtenido.
plot(redwine$fixed.acidity, redwine$citric.acid)
plot(redwine$fixed.acidity ~ redwine$citric.acid, xlab = "Hola", ylab = "Cahu", main = "Hola mundo")
Podemos crear una nueva sub-base de datos a partir de la base redwine, a través del paquete dplyr. Por ejemplo, si queremos solo separar las observaciones de las variables con la calidad (quality) 6, escribimos el siguiente comando donde subset se usa para generar esta nueva base de datos de acuerdo a la calidad (quality) 6.
library(dplyr)
vino6 <- subset(redwine, quality == 6)
head(vino6)
Ahora bien, si queremos analizar las variables de esta nueva sub-base podemos aplicar todo lo estudiado anteriormente.
Adicional a esto podemos ver la distribución de cada variable en cuantiles de forma gráfica a través del gráfico boxplot. Supongamos que nos interesa analizar la variable fixed.acidity, entonces:
boxplot(vino6$fixed.acidity)
abline(h = 13, col = 6)
Como podemos observar, algunos datos u observaciones se encuentran fuera de los “bigotes”, por lo que podemos decir que son atípicos o errores, y procederán a ser retirados de la muestra. Además, gracias a la linea horizontal graficada podemos saber que se trata de observaciones con valores mayores a 13.
Ahora bien, para filtrar esas observaciones atípicas debemos vrear una nueva base de datos que denominaremos vino6.2
vino6.2 <- filter(vino6, fixed.acidity < 13)
head(vino6.2)
boxplot(vino6.2$fixed.acidity)
Si ahora analizamos la variable pH
boxplot(vino6.2$pH)
Aparentemente, observamos que existe una cierta simetría entre las observación de acuerdo a la mediana, lo cual podría indicar la existencia de distribución normal en esta variable. Si embargo, observamos también que existen valores por encima y debajo de lo “bogotes”, es decir valores extremos.
Analizaremos la normalidad de la variable pH. Primero filtraremos la base de datos de los valores extremos existentes.
quantile(vino6.2$pH)
## 0% 25% 50% 75% 100%
## 2.87 3.22 3.32 3.41 4.01
boxplot(vino6.2$pH)
abline(h = 3.7, col = 6)
Observamos, que existen valores extremos por encima de \(3.7\) por lo que procederemos a quitarlos.
vino6.3 <- filter(vino6.2, pH < 3.7)
boxplot(vino6.3$pH)
Luego, para hacer el análisis de normalidad a través de los cuantiles, se deben comparar los cuantiles obtenidos con los cuantiles teóricos de la siguiente manera.
qqnorm(vino6.3[,"pH"], main = "pH")
# o de forma equivalente
qqnorm(vino6.3$pH, main = "pH")
# además agregamos una linea
qqline(vino6.3$pH)
Como podemos observar, en el eje horizontal se encuentras los cauntiles teóricos de una distribución normal estandar, mientras que en el eje vertical los cuantiles de la muestra para la variable pH. Nótece que los cuantiles corresponden a una linea recta, aunque algunos pocos se encuentran fuera de la linea. Sin emabrgo, esto da indicios de una distribuición normal para la variable pH.
Podemos graficar los datos con la distribución normal y además establecer que existe o no una distribución normal a través de una prueba de normalidad.
x <- vino6.3$pH
# ahora combinamos ambas gráficas a través de una función
gfic <- function(x){
media <- mean(x)
des.stan <- sd(x)
hist(x, freq = F) #no queremos graficar la frecuencia
curve(dnorm(x, media, des.stan), add = T, col = "blue") #add para agregarlo al histograma
abline(v = media, col = "red") # agregamos una linea vertical en la media
}
#graficamos
gfic(x)
Observamos que la variable pH es una variable que se distribuye de una forma muy cercana a una distribución normal.
Una prueba conocidad es la de jarque Bera donde H0: Normalidad. En términos de P-Value, si \(p > 0.05, 0.1, 0.01 =>\) la variable tiene comportamiento normal estándar al 95%, 90% y 99% de confianza.
#install.packages("tseries")
library("tseries")
jarque.bera.test(vino6.3$pH)
##
## Jarque Bera Test
##
## data: vino6.3$pH
## X-squared = 2.2256, df = 2, p-value = 0.3286
Otra prueba de hipótesis de normalidad es la de Anderson – Darling cuya Ho: normalidad y si el P-values es mayor al 5% aceptamos la Ho. Para ello usaremos la librería nortest
#install.packages("nortest")
library("nortest")
# ralizamos la prueba
ad.test(x)
##
## Anderson-Darling normality test
##
## data: x
## A = 0.67343, p-value = 0.0783
Observamos que el p-value es mayor al 5%, 1% y 10% por lo que aceptamos la Ho y concluimos que la variable hP presenta una distribución normal.
Descargar el archivo en pdf desde aquí.