Skip to content

Latest commit

 

History

History
2011 lines (1622 loc) · 82.9 KB

06-em.md

File metadata and controls

2011 lines (1622 loc) · 82.9 KB

Variables latentes y algoritmo EM

En esta sección estudiaremos modelos de variable latente y el algoritmo de esperanza-maximización.

Recordatorio de datos faltantes

  1. El modelo para los datos completos está parametrizado con $\theta$: $$p_{\theta}(y)$$

  2. El proceso de censura lo incluimos mediante el vector $I$ de indicadores de faltantes ($I_{j}=1$ cuando el dato $j$ está censurado faltante), entonces si el modelo para el mecanismo de faltantes está parametrizado con $\psi$: $$p_{\psi} (I|y)$$

  3. Entonces generamos los datos según (1) y luego censuramos observaciones según (2). Así, el modelo completo para nuestras observaciones es: $$p_{\theta,\psi} (y,I)=p_{\theta}(y)p_{\psi}(I|y).$$

  4. Escribimos $y=(y_{obs},y_{falta})$ para denotar por separado datos observados y datos faltantes. De tal manera que la verosimilitud para nuestros datos observados está dada por $$p_{\theta,\psi}(y_{obs},I),$$ pues sabemos los valores de las variables observadas y qué datos faltan. Para hacer máxima verosimilitud calculamos esta conjunta. $$p_{\theta,\psi} (y_{obs},I)=\int p_{\theta,\psi} (y_{obs}, y_{falta},I)d y_{falta}$$ $$=\int p_{\psi}(I|y_{obs},y_{falta})p_{\theta} (y_{obs}, y_{falta})d y_{falta}.$$ Nótese que esta integral (o suma, dependiendo del caso), promedia los valores faltantes según el modelo de los datos $p_{\theta}$ De la ecuación de arriba, vemos que en general tendríamos que modelar también el mecanismo de datos faltantes y estimar todos los parámetros. Esto es difícil no solamente porque hay más parámetros, sino porque en la práctica puede ser difícil proponer un modelo razonable para datos faltantes. Preferimos hacer un supuesto (MCAR, MAR).

  5. Si se cumple MAR, entonces tenemos que $$p_{\psi}(I|y_{obs},y_{falta})=p_{\psi}(I|y_{obs}),$$ y por tanto, $$p_{\theta,\psi} (y_{obs},I)= p_{\psi}(I|y_{obs})\int p_{\theta} (y_{obs}, y_{falta})dy_{falta}.$$ notamos que los parámetros $\psi$ y $\theta$ están en factores separados y para encontrar los estimadores de máxima verosimilitud, no es necesario trabajar con $\psi$ ni el mecanismo al azar. El mecanismo de faltantes es entonces ignorable.

Algoritmo de Esperanza-Maximización (EM)

Recordemos que el problema de maximización de verosimilitud se vuelve más difícil en la presencia de datos faltantes.

Ejemplo. Escogemos al azar una moneda y luego tiramos un volado con esa moneda (modelo Moneda -> Sol):

ej_1 <- data.frame(moneda = c('A', 'A', 'B', 'B', 'B', NA), 
  sol = c(1, 0, 0, 0, 1, 0))
ej_1
#>   moneda sol
#> 1      A   1
#> 2      A   0
#> 3      B   0
#> 4      B   0
#> 5      B   1
#> 6   <NA>   0

Si parametrizamos con $\theta=P(moneda=A)$, $\theta_A=P(sol|moneda=A)$ y $\theta_B=P(sol|moneda=B)$, la log verosimilitud para los datos completos es $$\log (\theta\theta_A) + \log(\theta(1-\theta_A)) + 2\log((1-\theta)(1-\theta_B))+ \log((1-\theta)\theta_B)$$ $$= 2\log\theta+3\log(1-\theta)+\log\theta_A+\log(1-\theta_A)+2\log(1-\theta_B)+\log\theta_B$$ En este caso es fácil encontrar los estimadores de máxima verosimilitud. Ahora, para incluir la contribución del caso con faltante suponemos MAR y promediamos los valores faltantes (como indica la fórmula en (5), cambiando la integral por suma):

$$p_{\theta}(x^{6}{sol}=0 )=p{\theta}(x^{6}{sol}=0 |x^{6}{moneda}=A) p_{\theta}(x^{6}{moneda}=A) + p{\theta}(x^{6}{sol}=0 |x^{6}{moneda}=B) p_{\theta}(x^{6}{moneda}=B),$$ y ahora buscamos maximizar $$p{\theta}(y_{obs})=2\log\theta+3\log(1-\theta)+\log\theta_A+\log(1-\theta_A)+2\log(1-\theta_B)+\log\theta_B + \log((1-\theta_A)\theta + (1-\theta_B)(1-\theta)).$$

Notemos que esta expresión es más difícil de maximizar. El algoritmo EM da un algoritmo iterativo para encontrar máximos locales de la verosimilitud $p_{\theta} (y_{obs})$. Este algoritmo sigue una estrategia de optimización motivada por la noción misma de datos faltantes y considerando la distribución condicional de los faltantes dado lo observado.

El algoritmo de **esperanza-maximización (EM)** es un proceso iterativo para maximizar verosimilitud en presencia de datos faltantes. Cada iteración consiste de dos pasos:
  • Calcular el valor esperado de la log-verosimilitud promediando sobre datos faltantes con una aproximación de la solución ($\theta^{(t)}$).

  • Obtener una nueva aproximación maximizando la cantidad resultante en el paso previo.

Podemos ver que el algorimto EM que el paso de esperanza consiste en un soft assignment de cada valor faltante de acuerdo al modelo de los datos y los datos observados.

Denotemos por $\theta^{(t)}$ el maximizador estimado en la iteración $t$ ($t=0,1,...$). En lugar de tratar directamente con $\log p_{\theta}(y_{obs})=\log p(y_{obs}\theta)$ el algoritmo EM trabaja sobre $Q(\theta \vert \theta^{(t)})$ que definimos como la esperanza de la log-verosimilitud de los datos completos $y=(y_{obs},y_{falta})$ condicional a los datos observados $y_{obs}$:

$$Q(\theta \vert \theta^{(t)})=E\big[\log\mathcal{L}(\theta|y) \big|y_{obs}, \theta^{(t)}\big]$$

$$=E \big[\log p(y|\theta) \big |y_{obs}, \theta^{(t)}\big]$$

$$=\int_{y_{falta}} [\log p(y|\theta)] p(y_{falta}|y_{obs}, \theta^{(t)})dy_{falta}.$$

Es así que en el paso esperanza calculamos $$Q(\theta|\theta^{(t)})$$ y en el paso maximización: $$\theta^{(t+1)} = argmax_{\theta}Q(\theta|\theta^{(t)})$$

Ejemplo. En nuestro ejemplo anterior, haríamos lo siguiente. Primero definimos la función que calcula el esperado de la log verosimilitud:

# logLik: verosimilitude de datos completos
logLik <- function(theta){
  2 * log(theta[1]) + 3 * log(1 - theta[1]) + log(theta[2]) + log(1 - theta[2]) +
    log(theta[3]) + 2 * log(1 - theta[3]) 
}

pasoEsperanza <- function(theta_ant){
  function(theta){
    # a = p(moneda=A|sol=1, theta_ant)
    # b = p(moneda=B|sol=1, theta_ant)
    a_0 <- theta_ant[1] * (1 - theta_ant[2])
    b_0 <- (1 - theta_ant[1]) * (1 - theta_ant[3])
    a <- a_0 / (a_0 + b_0)
    b <- b_0 / (a_0 + b_0)
    logLik(theta) + log(theta[1] * (1 - theta[2])) * a + 
      log((1 - theta[1]) * (1 - theta[3])) * b
  }
}

Ahora escogemos una solución inicial y calculamos el esperado

theta_0 <- c(0.1, 0.1, 0.1)
esperanza_0 <- pasoEsperanza(theta_0)

Optimizamos este valor esperado:

max_1 <- optim(c(0.5, 0.5, 0.5), esperanza_0, control = list(fnscale = -1))
theta_1 <- max_1$par
theta_1
#> [1] 0.3499568 0.4761239 0.2563899
esperanza_1 <- pasoEsperanza(theta_1)
max_2 <- optim(c(0.5, 0.5, 0.5), esperanza_1,control=list(fnscale=-1) )
theta_2 <- max_2$par
theta_2
#> [1] 0.3791749 0.4396194 0.2683535
esperanza_2 <- pasoEsperanza(theta_2)
max_3 <- optim(c(0.5, 0.5, 0.5), esperanza_2,control=list(fnscale=-1) )
theta_3 <- max_3$par
theta_3
#> [1] 0.3864616 0.4313841 0.2715459

Y vemos que recuperamos la misma solución que en el caso de maximizar usando la función optim.

Veamos porque funciona trabajar con $Q(\theta|\theta^{(t)})$. Si escribimos: $$ p(y_{obs}|\theta)=\frac{p(y|\theta)}{p(y_{falta}|y_{obs},\theta)}.$$

Tomando logaritmos, $$\log{p}(y_{obs}|\theta)=\log{p}(y|\theta)-log{p}(y_{falta}|y_{obs}, \theta).$$

Y tomando el valor esperado con respecto la distribuión de $y_{falta}|y_{obs}$ con parámetro $\theta^{(t)}$ (que consideramos como una aproximación de los verdaderos parámetros), obtenemos:

$$E\big[\log p(y_{obs}|\theta)\big | y_{obs}, \theta^{(t)}\big]= E\big[\log p(y|\theta)\big | y_{obs}, \theta^{(t)}\big] - E\big[\log p(y_{falta}|\theta)\big | y_{obs}, \theta^{(t)}\big]$$

$$=\int_{y_{falta}}[\log p(y|\theta)] p(y_{falta}|y_{obs}, \theta^{(t)})dy_{falta} - \int_{y_{falta}}[\log{p}(y_{falta}| y_{obs},\theta)]p(y_{falta}|y_{obs},\theta^{(t)})dy_{falta}$$ $$= Q(\theta|\theta^{(t)}) - H(\theta|\theta^{(t)})$$

La igualdad anterior es cierta para cualquier valor de $\theta$, en particular, $\theta=\theta^{(t)}$ por lo que: $$\log{p}(y_{obs}|\theta) -\log{p}(y_{obs}|\theta^{(t)})= Q(\theta|\theta^{(t)}) - Q(\theta^{(t)}|\theta^{(t)}) - [H(\theta|\theta^{(t)}) - H(\theta^{(t)}|\theta^{(t)})]$$ utilizando la desigualdad de Jensen se puede demostrar que $H(\theta|\theta^{(t)}) \leq H(\theta^{(t)}|\theta^{(t)})$, por lo que (en términos de la verosimilutd) $$\log\mathcal{L}(\theta|y_{obs}) -\log\mathcal{L}(\theta^{(t)}|t_{obs}) \geq Q(\theta|\theta^{(t)}) - Q(\theta^{(t)}|\theta^{(t)})$$ y vemos que si incrementamos $Q(\theta|\theta^{(t)})$ entonces también incrementamos $\mathcal{L}(\theta|y_{obs})$.

Observaciones del algoritmo EM

  • El algoritmo EM es una generalización natural de la estiamación por máxima verosimilitud cuando hay presencia de datos faltantes.

  • El problema de maximización que ataca EM es más complejo que el problema de máxima verosimilitud con datos completos. En el caso usual $\log p(x|\theta)$ tiene un único máximo global que muchas veces se puede encontrar de forma cerrada, por su parte la verosimilitud con datos faltantes tiene muchos máximos locales y no tiene solución cerrada.

  • El algoritmo EM reduce el problema de múltiples máximos a una secuencia de subproblemas ($Q(\theta|\theta^{(t)}$) cada uno con un único máximo global.
    Estos subproblemas son tales que se garantiza convergencia de las soluciones $\theta^{(1)}, \theta^{(2)}, ...$ a un máximo, pues a cada paso se incrementa monótonamente el valor de la log-verosimilitud de los datos observados.

  • El algoritmo EM garantiza convergencia únicamente a un máximo local pues la secuencia de $\theta^{(t)}$ depende del valor con el que se inicializa el proceso $\theta^{(1)}$. Por tanto, es conveniente repetir el algoritmo con varios valores iniciales.

  • Una manera de entender el algoritmo EM es pensar que en cada paso de esperanza imputas los faltantes, sin embargo, en lugar de una imputación dura se realiza un soft assignment de cada valor faltante. El soft assignment se calcula obteniendo la probabilidad de cada alternativa para el valor faltante (usando el parámetro $\theta^{(t)})$) para crear una base de datos ponderada que considera todos los posibles escenarios de los faltantes. Al usar los valores esperados (o datos ponderados) en lugar de realizar una imputación dura el algoritmo toma en cuenta la confianza del modelo cada vez que completa los datos.

Variables latentes

Un caso importante de datos faltantes es cuando una variable está totalmente censurada. Esto puede suceder por dos razones:

  • Alguna variable claramente importante está totalmente censurada (por ejemplo, peso en un estudio de consumo de calorías).

  • Cuando buscamos añadir estructura a nuestro modelo para simplificar su estimación, interpretación o forma. Por ejemplo: hacer grupos de actitudes ante la comida y el ejercicio para explicar con una sola variable el consumo de comida chatarra (por ejemplo, análisis de factores).

En estos casos, estas variables se llaman variables latentes, pues consideramos que tienen un efecto que observamos a través de otras variables, pero no podemos observar directamente los valores de esta variable.

![](img/manicule2.jpg) ¿Cuál es el supuesto apropiado acerca de este tipo de valores censurados (variables latentes)?

a. MCAR
b. MAR
c. MNAR
d. Ninguno de estos

La siguiente tabla es una clasificación de los modelos de variable latente de acuerdo a la métrica de las variables latentes y observadas.

Latentes/Observadas Métricas Categóricas
Métricas Análisis de factores (FA) Modelos de rasgos latentes (LTM)
Categóricas Modelos de perfiles latentes (LPM) Modelos de clases latentes (LCM)

Modelos de perfiles latentes: Mezcla de normales

El ejemplo más clásico de variables latentes es el de mezcla de normales.

Ejemplo. Modelo de mezcla de dos normales. Consideremos los siguientes datos:

library(ggplot2)
set.seed(280572)
N <- 800
n <- sum(rbinom(N, 1, 0.6))

x_1 <- rnorm(N - n, 0, 0.5)
x_2 <- rnorm(n, 2, 0.3)
qplot(c(x_1, x_2))
#> `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

Estos datos tienen una estructura bimodal. Es poco apropiado modelar estos datos con un modelo normal $(\mu,\sigma^2)$.

Podemos entonces modelar pensando que los datos vienen de dos clases, cada una con una distribución normal pero con distintos parámetros. ¿Cómo ajustaríamos tal modelo?

La variable aleatoria $X$ es una mezcla de normales si $$p(x)=\sum_{k=1}^K \pi_k \phi_{\theta_k}(x)$$ donde $\phi_{\theta_k}$ es una densidad normal con parámetros $\theta_k=(\mu_k, \sigma_k)$ y los ponderadores de la mezcla $\pi_k$ satisfacen $\sum_i \pi_i = 1$

Ahora, si vemos la mezcla Gaussiana desde la representación generativa, o formulación en variable latente, tenemos el modelo gráfico $\Delta$ -> $X$ donde $\Delta$ es una indicadora de clase. En el caso del modelo de dos clases tenemos $\delta \in {0,1}$ y sea $P(\delta=1)=\pi$, escribimos la conjunta $$p(\delta, x)=\pi^{\delta}(1-\pi)^{1-\delta}[\delta\phi_{\theta_1}(x)+(1-\delta)\phi_{\theta_2}(x)]$$

y podemos verificar que la distribución marginal es una mezcla gaussiana: $$p(x)\sum_{\delta}p(x|\delta)p(\delta)$$ $$=\phi_{\theta_1}(x) \pi + \phi_{\theta_2}(x)(1-\pi)$$

Ahora, si conocieramos la clase a la que pertenece cada observación ($\delta^i$) podríamos escribir la log-verosimilitud completa (sin censura) como $$\sum_{i=1}^N \log(\delta^i \phi_{\theta_1} (x^i)+ (1-\delta^i)\phi_{\theta_2}(x^i)) + \delta^i \log\pi + (1-\delta^i)\log(1-\pi).$$

Aquí, es fácil ver que la verosimilitud se separa en dos partes, una para $\delta^i=1$ y otra para $\delta^i=0$, y los estimadores de máxima verosimilitud son entonces:

$$\hat{\mu}_1=\frac{\sum_i\delta^i x^i}{\sum_i (\delta^i)}$$ $$\hat{\mu}_2=\frac{\sum_i(1-\delta^i) x^i}{\sum_i (1-\delta^i)}$$

$$\hat{\sigma}_1^2=\frac{\sum_i\delta^i (x^i-\mu_1)^2}{\sum_i (\delta^i)}$$ $$\hat{\sigma}_2^2=\frac{\sum_i(1-\delta^i) (x^i-\mu_2)^2}{\sum_i (1-\delta^i)},$$

y $\hat{\pi}$ es la proporción de casos tipo 1 en los datos. Este problema es entonces trivial de resolver.

En el caso de variables latentes $\delta^i$ están censuradas y tenemos que marginalizar con respecto a $\delta^i$, resultando en:

$$\sum_{i=1}^N \log(\pi \phi_{\theta_1} (x^i)+ (1-\pi)\phi_{\theta_2}(x^i)).$$

donde $\pi$ es la probabilidad de que la observación venga de la primera densidad. Este problema es más difícil pues tenemos tanto $\pi$ como $\theta_1$ y $\theta_2$ dentro del logaritmo. Podemos resolver numéricamente como sigue:

crearLogLike <- function(x){
  logLike <- function(theta){
    pi <- exp(theta[1]) / (1 + exp(theta[1]))
    mu_1 <- theta[2]
    mu_2 <- theta[3]
    sigma_1 <- exp(theta[4])
    sigma_2 <- exp(theta[5])
    sum(log(pi*dnorm(x, mu_1, sd=sigma_1)+(1-pi)*dnorm(x,mu_2,sd=sigma_2)))
  }
  logLike
}
func_1 <- crearLogLike(c(x_1,x_2))
system.time(salida <- optim(c(0.5,0,0,1,1), func_1, control=list(fnscale=-1)))
#>    user  system elapsed 
#>   0.026   0.001   0.027
salida$convergence
#> [1] 0
exp(salida$par[1]) / (1 + exp(salida$par[1]))
#> [1] 0.5857074
salida$par[2:3]
#> [1] 1.98759218 0.03046366
exp(salida$par[4:5])
#> [1] 0.2977028 0.5159818

Y vemos que hemos podido recuperar los parámetros originales.

Ahora implementamos EM para resolver este problema. Empezamos con la log-verosimilitud para datos completos (que reescribimos de manera más conveniente): $$\sum_{i=1}^N \delta^i\log\phi_{\theta_1} (x^i)+ (1-\delta^i)\log\phi_{\theta_2}(x^i) + \delta^i \log\pi + (1-\delta^i)\log(1-\pi).$$

Tomamos valores iniciales para los parámetros $\hat{\mu}1,\hat{\mu}2,\hat{\sigma}1^2, \hat{\sigma}2^2, \hat{\pi}$ y comenzamos con el paso Esperanza promediando sobre las variables aleatorias, que en este caso son las $\delta^i$. Calculamos entonces $$\hat{\gamma}^i=E{\hat{\theta}}(\delta^i|x^i)=P(\delta^i=1|x^i),$$ y usamos bayes para expresar en términos de los parámetros: $$\hat{\gamma}^i= \frac{\hat{\pi}\phi{\hat{\theta_1}}} {\hat{\pi}\phi{\hat{\theta_1}}(x_i)+(1-\hat{\pi})\phi{\hat{\theta_2}}(x_i)}$$

$\hat{\gamma}^i$ se conocen como la responsabilidad del modelo 1 para explicar la i-ésima observación.

Utilizando estas asignaciones de los faltantes pasamos al paso Maximización, donde la función objetivo es: $$\sum_{i=1}^N \hat{\gamma}^i\log \phi_{\theta_1} (x^i)+ (1-\hat{\gamma}^i)\log\phi_{\theta_2}(x^i) + \hat{\gamma}^i \log\pi + (1-\hat{\gamma}^i)\log(1-\pi).$$

La actualización de $\pi$ es fácil:

$$\hat{\pi}=\frac{1}{N}\sum_i{\gamma^i}.$$

y se puede ver sin mucha dificultad que

$$\hat{\mu}_1=\frac{\sum_i\hat{\gamma}^i x^i}{\sum_i \hat{\gamma}^i}$$ $$\hat{\mu}_2=\frac{\sum_i(1-\hat{\gamma}^i) x^i}{\sum_i (1-\hat{\gamma}^i})$$

$$\hat{\sigma}_1^2=\frac{\sum_i\hat{\gamma}^i (x^i-\mu_1)^2}{\sum_i \hat{\gamma}^i}$$ $$\hat{\sigma}_2^2=\frac{\sum_i(1-\hat{\gamma}^i) (x^i-\mu_2)^2}{\sum_i (1-\hat{\gamma}^i)},$$

Implementa EM para el ejemplo de mezcla de normales.

Mezclas gaussianas

Un caso más general es suponer que hay $K$ posibles clases y las distribuciones de la mezcla son normal multivariadas. De tal manera que $$P(\delta_k^i=1)=\pi_k, \sum_{k=1}^K \pi_k =1$$

Entonces, la distribución de los datos observados es la mezcla Gaussiana:

$$p(x)=\sum_{k=1}^K \pi_k p_{\theta_k}(x)$$

donde $p_{\theta_k}$ es normal multivariada con parámetros $\theta_k={\mu_k, \Sigma_k}$,

$$p_{\theta_k}(x)=\frac{1}{(2\pi|\Sigma_k|)^{1/2}}exp\big{\frac{1}{2}(x-\mu_k)^T \Sigma_k^{-1}(x-\mu_k)\big}$$

La estimación en el caso multivariado con $K$ clases se realiza con el algoritmo EM de manera análoga al caso de dos clases y normal univariada; sin embargo, es posible restringir el tipo de mezcla a clases de distribuciones Gaussianas determinadas por la matriz de covarianzas.

Consideremos la descomposición de espectral de la $k$-ésima matriz de covarianzas:

$$\Sigma_k=\lambda_k D_k A_k D_k^T$$

  • $A_k$ es una matriz diagonal con $det(A_k)=1$ y entradas diagonales proporcionales a los eigenvalores de $\Sigma_k$. $A_k$ controla la forma (shape) del $k$-ésimo cluster.

  • $\lambda_k$ es una constante igual al $det(\Sigma_k)$ que controla el volumen del $k$-ésimo cluster.

  • $D_k$ es la matriz ortonormal de eigenvectores y controla la orientación del $k$-ésimo cluster.

Utilizando la descomposición de arriba hay modelos de mezclas Gaussianas que se restringen a cluster con propiedades particulares, por ejemplo:

  • $\Sigma_k=\lambda I$: clusters esféricos de igual volumen.

  • $\Sigma_k=\lambda_k I$: clusters esféricos de distinto volumen.

  • $\Sigma_k=\lambda_k A$: clusters elipsoidales de distinto volumen pero misma forma , orientaciones alineadas con el eje.

...

  • $\Sigma_k=\lambda_k D_k A_k D_k^T$ modelo sin restricciones.

Ahora veremos como ajustar estos modelos. En R hay varios paquetes para ajustar mezclas gaussianas, dos de ellos son mclust y mixtools. También está flexmix

Veamos un ejemplo usando mclust, en este paquete los modelos disponibles son

?mclustModelNames
Mezclas Univariadas  	
"E"	=	equal variance (one-dimensional)  
"V"	=	variable variance (one-dimensional)  
Mezclas multivariadas
"EII"	=	spherical, equal volume  
"VII"	=	spherical, unequal volume  
"EEI"	=	diagonal, equal volume and shape  
"VEI"	=	diagonal, varying volume, equal shape  
"EVI"	=	diagonal, equal volume, varying shape  
"VVI"	=	diagonal, varying volume and shape  
"EEE"	=	ellipsoidal, equal volume, shape, and orientation  
"EEV"	=	ellipsoidal, equal volume and equal shape  
"VEV"	=	ellipsoidal, equal shape  
"VVV"	=	ellipsoidal, varying volume, shape, and orientation

La nomenclatura es: E=equal, V=varying, I=identity, y las letras están ordenadas 1ra=volumen, 2a=forma, 3ra=orientación.

En todos los modelos hay $K-1$ parámetros para las probabilidades iniciales $\pi_k$ mas $Kp$ parámetros para las medias mas los parámetros de la matriz de covarianzas:

Los modelos con menos restricciones tienen más parámetros por estimar y por tanto necesitan de más datos para alcanzar la misma precisión.

Usaremos los datos wine.

library(mclust)
wine <- read.csv("data/wine.csv", stringsAsFactors=FALSE)[, -1]
w_mclust <- Mclust(wine)
summary(w_mclust)
#> ---------------------------------------------------- 
#> Gaussian finite mixture model fitted by EM algorithm 
#> ---------------------------------------------------- 
#> 
#> Mclust VVE (ellipsoidal, equal orientation) model with 3 components: 
#> 
#>  log-likelihood   n  df       BIC       ICL
#>       -3015.333 178 158 -6849.387 -6850.694
#> 
#> Clustering table:
#>  1  2  3 
#> 59 69 50

Podemos ver más detalles:

summary(w_mclust, parameters = TRUE)
#> ---------------------------------------------------- 
#> Gaussian finite mixture model fitted by EM algorithm 
#> ---------------------------------------------------- 
#> 
#> Mclust VVE (ellipsoidal, equal orientation) model with 3 components: 
#> 
#>  log-likelihood   n  df       BIC       ICL
#>       -3015.333 178 158 -6849.387 -6850.694
#> 
#> Clustering table:
#>  1  2  3 
#> 59 69 50 
#> 
#> Mixing probabilities:
#>         1         2         3 
#> 0.3300315 0.3903124 0.2796561 
#> 
#> Means:
#>                              [,1]        [,2]        [,3]
#> Alcohol.content        13.7474607  12.2884420  13.1132188
#> Malic.acid              2.0093958   1.9349628   3.2824045
#> As                      2.4524717   2.2414826   2.4395874
#> Alcalinity.in.ash      17.0056425  20.2329719  21.4025951
#> Magnesium             106.2591851  93.9990767 100.0646503
#> Total.phenols           2.8408263   2.2829349   1.6680931
#> Falavanoids             2.9836246   2.1105880   0.7895086
#> Nonflavanoid.phenols    0.2892543   0.3671547   0.4401329
#> Proantocyanins          1.8992977   1.6341503   1.1665817
#> Color.Intensity         5.5361641   3.0977312   7.2299462
#> Hue                     1.0619246   1.0596060   0.6915761
#> OD280.OD315             3.1576577   2.8052205   1.6972509
#> Proline              1116.9517345 515.2032715 633.5416560
#> 
#> Variances:
#> [,,1]
#>                      Alcohol.content    Malic.acid           As
#> Alcohol.content         0.2058329968  -0.004024864 -0.009036939
#> Malic.acid             -0.0040248637   0.490091195  0.018910721
#> As                     -0.0090369389   0.018910721  0.055228146
#> Alcalinity.in.ash      -0.0828371420   0.331081359  0.341310246
#> Magnesium               0.1068697208  -0.991646554  0.571126451
#> Total.phenols           0.0052597707  -0.023068454  0.009333359
#> Falavanoids             0.0065310325  -0.026137373  0.016676313
#> Nonflavanoid.phenols    0.0009463792   0.011285445  0.007911553
#> Proantocyanins          0.0149987005  -0.038452295 -0.006737493
#> Color.Intensity         0.1653294086  -0.148232480 -0.026834517
#> Hue                     0.0037878962  -0.022582987  0.007238772
#> OD280.OD315            -0.0121794833   0.014950157  0.014614274
#> Proline                17.4628451708 -56.678967719 -3.337718902
#>                      Alcalinity.in.ash    Magnesium Total.phenols
#> Alcohol.content           -0.082837142   0.10686972  0.0052597707
#> Malic.acid                 0.331081359  -0.99164655 -0.0230684544
#> As                         0.341310246   0.57112645  0.0093333589
#> Alcalinity.in.ash          5.971450304   2.01734719  0.0187383181
#> Magnesium                  2.017347189 139.89193989  0.9193181647
#> Total.phenols              0.018738318   0.91931816  0.0971100170
#> Falavanoids                0.131007162   0.71138669  0.0842443327
#> Nonflavanoid.phenols       0.044245330  -0.11721737 -0.0061705519
#> Proantocyanins            -0.002275193   1.30197911  0.0298378638
#> Color.Intensity           -0.255590507   1.28678476  0.0493652310
#> Hue                        0.004632895   0.21238589  0.0007562286
#> OD280.OD315                0.168893091  -0.06193507  0.0110876746
#> Proline                  -52.752038513 732.49780801 13.8868978185
#>                        Falavanoids Nonflavanoid.phenols Proantocyanins
#> Alcohol.content       0.0065310325         0.0009463792    0.014998700
#> Malic.acid           -0.0261373726         0.0112854453   -0.038452295
#> As                    0.0166763126         0.0079115530   -0.006737493
#> Alcalinity.in.ash     0.1310071620         0.0442453302   -0.002275193
#> Magnesium             0.7113866941        -0.1172173734    1.301979114
#> Total.phenols         0.0842443327        -0.0061705519    0.029837864
#> Falavanoids           0.1349705248        -0.0069115449    0.062565680
#> Nonflavanoid.phenols -0.0069115449         0.0072891701   -0.007172903
#> Proantocyanins        0.0625656802        -0.0071729033    0.164934604
#> Color.Intensity       0.1144048483        -0.0004530542    0.122825687
#> Hue                  -0.0006350309         0.0008467983    0.002076420
#> OD280.OD315           0.0226408419        -0.0092570244    0.011252864
#> Proline              10.6322090581        -3.0396915543   23.979311959
#>                      Color.Intensity           Hue  OD280.OD315
#> Alcohol.content         0.1653294086  0.0037878962 -0.012179483
#> Malic.acid             -0.1482324804 -0.0225829875  0.014950157
#> As                     -0.0268345172  0.0072387724  0.014614274
#> Alcalinity.in.ash      -0.2555905072  0.0046328950  0.168893091
#> Magnesium               1.2867847621  0.2123858908 -0.061935066
#> Total.phenols           0.0493652310  0.0007562286  0.011087675
#> Falavanoids             0.1144048483 -0.0006350309  0.022640842
#> Nonflavanoid.phenols   -0.0004530542  0.0008467983 -0.009257024
#> Proantocyanins          0.1228256872  0.0020764204  0.011252864
#> Color.Intensity         1.2827176196 -0.0181024064 -0.063963894
#> Hue                    -0.0181024064  0.0133148261 -0.001197288
#> OD280.OD315            -0.0639638945 -0.0011972880  0.137646988
#> Proline                89.6000335505  8.4888492803 -8.638897429
#>                           Proline
#> Alcohol.content         17.462845
#> Malic.acid             -56.678968
#> As                      -3.337719
#> Alcalinity.in.ash      -52.752039
#> Magnesium              732.497808
#> Total.phenols           13.886898
#> Falavanoids             10.632209
#> Nonflavanoid.phenols    -3.039692
#> Proantocyanins          23.979312
#> Color.Intensity         89.600034
#> Hue                      8.488849
#> OD280.OD315             -8.638897
#> Proline              48054.698849
#> [,,2]
#>                      Alcohol.content    Malic.acid           As
#> Alcohol.content          0.290957199   0.041494976 -0.015172597
#> Malic.acid               0.041494976   0.959616485  0.031392560
#> As                      -0.015172597   0.031392560  0.100832278
#> Alcalinity.in.ash       -0.139222786   0.557508416  0.664954718
#> Magnesium               -0.151719216  -0.652094100  1.080065801
#> Total.phenols           -0.040256458  -0.002113848  0.029119508
#> Falavanoids             -0.060147746  -0.004874673  0.039501254
#> Nonflavanoid.phenols     0.007548535   0.015915807  0.013514996
#> Proantocyanins          -0.040749045  -0.009251307 -0.006148156
#> Color.Intensity          0.125146552  -0.080664399 -0.033632185
#> Hue                      0.004211772  -0.034179000  0.007228388
#> OD280.OD315             -0.042241674   0.026423741  0.028446620
#> Proline                  8.626596290 -27.985876625 -1.659845775
#>                      Alcalinity.in.ash    Magnesium Total.phenols
#> Alcohol.content            -0.13922279  -0.15171922  -0.040256458
#> Malic.acid                  0.55750842  -0.65209410  -0.002113848
#> As                          0.66495472   1.08006580   0.029119508
#> Alcalinity.in.ash          11.66688422   4.59938073   0.047875643
#> Magnesium                   4.59938073 234.48630651   1.361037876
#> Total.phenols               0.04787564   1.36103788   0.264992918
#> Falavanoids                 0.25897013   1.05405977   0.257799261
#> Nonflavanoid.phenols        0.08314979  -0.14875746  -0.022078478
#> Proantocyanins              0.01893329   1.84347909   0.127681628
#> Color.Intensity            -0.40238687   0.53161273   0.007950886
#> Hue                         0.02452953   0.21105543  -0.002551795
#> OD280.OD315                 0.31725455   0.05715343   0.110329268
#> Proline                   -26.09488891 359.20264305   6.843821755
#>                       Falavanoids Nonflavanoid.phenols Proantocyanins
#> Alcohol.content      -0.060147746          0.007548535   -0.040749045
#> Malic.acid           -0.004874673          0.015915807   -0.009251307
#> As                    0.039501254          0.013514996   -0.006148156
#> Alcalinity.in.ash     0.258970125          0.083149785    0.018933288
#> Magnesium             1.054059766         -0.148757464    1.843479090
#> Total.phenols         0.257799261         -0.022078478    0.127681628
#> Falavanoids           0.402859513         -0.030553714    0.219205900
#> Nonflavanoid.phenols -0.030553714          0.013721881   -0.025794233
#> Proantocyanins        0.219205900         -0.025794233    0.397162067
#> Color.Intensity       0.047959574          0.003634641    0.055879900
#> Hue                  -0.004842160          0.001549258   -0.003299242
#> OD280.OD315           0.160712163         -0.021481045    0.121953613
#> Proline               5.239795551         -1.499604179   11.823144132
#>                      Color.Intensity          Hue  OD280.OD315
#> Alcohol.content          0.125146552  0.004211772 -0.042241674
#> Malic.acid              -0.080664399 -0.034179000  0.026423741
#> As                      -0.033632185  0.007228388  0.028446620
#> Alcalinity.in.ash       -0.402386869  0.024529529  0.317254548
#> Magnesium                0.531612726  0.211055426  0.057153426
#> Total.phenols            0.007950886 -0.002551795  0.110329268
#> Falavanoids              0.047959574 -0.004842160  0.160712163
#> Nonflavanoid.phenols     0.003634641  0.001549258 -0.021481045
#> Proantocyanins           0.055879900 -0.003299242  0.121953613
#> Color.Intensity          1.025931508 -0.020505202 -0.072269929
#> Hue                     -0.020505202  0.041007971 -0.002452333
#> OD280.OD315             -0.072269929 -0.002452333  0.215689168
#> Proline                 44.247495205  4.190420761 -4.267192790
#>                           Proline
#> Alcohol.content          8.626596
#> Malic.acid             -27.985877
#> As                      -1.659846
#> Alcalinity.in.ash      -26.094889
#> Magnesium              359.202643
#> Total.phenols            6.843822
#> Falavanoids              5.239796
#> Nonflavanoid.phenols    -1.499604
#> Proantocyanins          11.823144
#> Color.Intensity         44.247495
#> Hue                      4.190421
#> OD280.OD315             -4.267193
#> Proline              23730.772720
#> [,,3]
#>                      Alcohol.content    Malic.acid           As
#> Alcohol.content          0.364795175   0.064640215 -0.014255292
#> Malic.acid               0.064640215   1.202742989  0.009619805
#> As                      -0.014255292   0.009619805  0.034969282
#> Alcalinity.in.ash       -0.035993225   0.182864164  0.269439543
#> Magnesium               -0.090609764  -0.365698545  0.624920131
#> Total.phenols            0.031616437  -0.055151917  0.023026263
#> Falavanoids              0.083433862  -0.103556511 -0.009829708
#> Nonflavanoid.phenols     0.004430543   0.021256335  0.001934607
#> Proantocyanins           0.077373081  -0.072496459 -0.000510812
#> Color.Intensity          0.769007331  -0.245044458 -0.061093951
#> Hue                     -0.017715605  -0.035787308  0.004035577
#> OD280.OD315             -0.023346744  -0.013926442  0.013095158
#> Proline                  4.869717266 -15.801209810 -0.937506525
#>                      Alcalinity.in.ash    Magnesium Total.phenols
#> Alcohol.content           -0.035993225  -0.09060976   0.031616437
#> Malic.acid                 0.182864164  -0.36569855  -0.055151917
#> As                         0.269439543   0.62492013   0.023026263
#> Alcalinity.in.ash          4.687651663   2.69982780   0.034940535
#> Magnesium                  2.699827797 134.94975622   0.783495550
#> Total.phenols              0.034940535   0.78349555   0.112711973
#> Falavanoids                0.135032979   0.60843506   0.005760379
#> Nonflavanoid.phenols       0.032945039  -0.08524479   0.003875283
#> Proantocyanins             0.034275071   1.06047025   0.047307104
#> Color.Intensity            0.022939765   0.29043216   0.184482532
#> Hue                        0.005182554   0.12098019   0.000579047
#> OD280.OD315                0.123688178   0.03632290  -0.003086967
#> Proline                  -14.738807160 202.78506111   3.863769830
#>                       Falavanoids Nonflavanoid.phenols Proantocyanins
#> Alcohol.content       0.083433862         4.430543e-03   7.737308e-02
#> Malic.acid           -0.103556511         2.125633e-02  -7.249646e-02
#> As                   -0.009829708         1.934607e-03  -5.108120e-04
#> Alcalinity.in.ash     0.135032979         3.294504e-02   3.427507e-02
#> Magnesium             0.608435055        -8.524479e-02   1.060470e+00
#> Total.phenols         0.005760379         3.875283e-03   4.730710e-02
#> Falavanoids           0.179195550        -5.819478e-03   6.602239e-02
#> Nonflavanoid.phenols -0.005819478         1.605783e-02  -4.840697e-05
#> Proantocyanins        0.066022386        -4.840697e-05   1.223608e-01
#> Color.Intensity       0.584663452         2.722327e-02   4.906441e-01
#> Hue                  -0.016193650        -1.250589e-03  -1.000528e-02
#> OD280.OD315          -0.016412517        -6.006693e-03  -1.510007e-02
#> Proline               2.957297389        -8.467936e-01   6.674755e+00
#>                      Color.Intensity          Hue  OD280.OD315
#> Alcohol.content           0.76900733 -0.017715605 -0.023346744
#> Malic.acid               -0.24504446 -0.035787308 -0.013926442
#> As                       -0.06109395  0.004035577  0.013095158
#> Alcalinity.in.ash         0.02293976  0.005182554  0.123688178
#> Magnesium                 0.29043216  0.120980192  0.036322896
#> Total.phenols             0.18448253  0.000579047 -0.003086967
#> Falavanoids               0.58466345 -0.016193650 -0.016412517
#> Nonflavanoid.phenols      0.02722327 -0.001250589 -0.006006693
#> Proantocyanins            0.49064410 -0.010005284 -0.015100071
#> Color.Intensity           5.78108574 -0.166574834 -0.231453078
#> Hue                      -0.16657483  0.015609471  0.007313253
#> OD280.OD315              -0.23145308  0.007313253  0.103382839
#> Proline                  24.97418230  2.366371149 -2.409193145
#>                            Proline
#> Alcohol.content          4.8697173
#> Malic.acid             -15.8012098
#> As                      -0.9375065
#> Alcalinity.in.ash      -14.7388072
#> Magnesium              202.7850611
#> Total.phenols            3.8637698
#> Falavanoids              2.9572974
#> Nonflavanoid.phenols    -0.8467936
#> Proantocyanins           6.6747551
#> Color.Intensity         24.9741823
#> Hue                      2.3663711
#> OD280.OD315             -2.4091931
#> Proline              13399.5878181

Y podemos ver una tabla con el BIC para cada modelo, es importante tomar en cuenta que en mclust el BIC se define como:

$$BIC = 2\log l(x;\hat{\theta}) - d\log n$$

$d$ es el número de parámetros y $n$ el número de observaciones. Por tanto, buscamos maximizar el BIC.

round(w_mclust$BIC)
#> Bayesian Information Criterion (BIC): 
#>      EII    VII   EEI   VEI   EVI   VVI   EEE   EVE   VEE   VVE   EEV
#> 1 -27318 -27318 -8161 -8161 -8161 -8161 -7201 -7201 -7201 -7201 -7201
#> 2 -24478 -24297 -7534 -7553 -7440 -7496 -7138 -7099 -7077 -7027 -7328
#> 3 -23210 -22595 -7125 -7065 -7024 -7003 -7026 -6889 -6963 -6849 -7321
#> 4 -22037 -21633 -7055 -7014 -7053 -6993 -7013 -6874 -6943 -6886 -7520
#> 5 -21552 -20974 -7020 -6975 -7107 -7041 -6992 -6937 -6938 -6957 -7860
#> 6 -20777 -20285 -7061 -7006 -7175 -7122 -7000    NA -6933 -7039 -8236
#> 7 -20584 -19978 -7036 -7014 -7214 -7223 -6969    NA    NA    NA -8514
#> 8 -20511 -19167 -7009 -6988 -7194 -7227 -7018    NA    NA    NA -8815
#> 9 -19054 -18784 -6995 -7065 -7215 -7236 -7052    NA    NA    NA -9188
#>     VEV   EVV   VVV
#> 1 -7201 -7201 -7201
#> 2 -7229 -7181 -7169
#> 3 -7250 -7285 -7204
#> 4 -7484 -7563 -7555
#> 5 -7826 -7895 -7905
#> 6 -8125 -8314 -8245
#> 7 -8503    NA    NA
#> 8 -8734    NA    NA
#> 9 -9039    NA    NA
#> 
#> Top 3 models based on the BIC criterion: 
#> VVE,3 EVE,4 VVE,4 
#> -6849 -6874 -6886
w_mclust
#> 'Mclust' model object: (VVE,3) 
#> 
#> Available components: 
#>  [1] "call"           "data"           "modelName"      "n"             
#>  [5] "d"              "G"              "BIC"            "bic"           
#>  [9] "loglik"         "df"             "hypvol"         "parameters"    
#> [13] "z"              "classification" "uncertainty"

En la tabla de arriba, los renglones indican el número de conglomerados.

El paquete incluye algunas gráficas auxiliares.

plot(w_mclust, what = "BIC")

# hay 3 plots más:
# plot(w_mclust)

Y podemos hacer otras gráficas, por ejemplo podemos usar tourr para explorar los datos multivariados.

library(tourr)

w_mclust <- Mclust(wine, G = 3, modelNames = "VVI")
summary(w_mclust)

cl_p <- data.frame(cluster = w_mclust$classification, wine)

aps <- 2
fps <- 20

mat <- rescale(wine)
tour <- new_tour(mat, grand_tour(), NULL)
start <- tour(0)
proj_data <- reactive({
  invalidateLater(1000 / fps, NULL);
  step <- tour(aps / fps)
  data.frame(center(mat %*% step$proj), 
             clusters = factor(w_mclust$classification))
})
proj_data %>% ggvis(~X1, ~X2, fill = ~clusters) %>%
  layer_points() %>%
  scale_numeric("x", domain = c(-1, 1)) %>%
  scale_numeric("y", domain = c(-1, 1)) %>%
  set_options(duration = 0)

Observaciones

  • Las mezclas Gaussianas son sensibles a datos atípicos (outliers).

  • Puede haber inestabilidad si los componentes Gaussianos no están separados apropiadamente o si los datos son chicos.

  • A comparación de otros métodos de clustering el tener un modelo probabilístico explícito hace posible verificar supuestos y tener medidas de ajuste. Por ejemplo, podemos usar BIC para elegir el número de clusters.

  • k-medias es un caso particular de mezclas gaussianas donde en cada paso se realizan asignaciones duras.

  • Desventajas: los resultados dependen de la inicialización del algoritmo EM, puede ser demasiado flexible o inestable.

  • Las mezclas gaussianas se pueden extender a mezclas de modelos de regresión que pueden ser modelos lineales estándar o modelos lineales generalizados. Esto esta implementado en el paquete flexmix que utiliza el algoritmo EM.

Aplicación: Background Subtraction

Background Subtraction es una técnica de procesamiento de imágenes donde se buscan extraer los objetos en el frente de la imagen. Por ejemplo, puede ser de interés detectar autos, animales o personas de una imagen. Ejemplos:

  • Monitoreo de tráfico (contar vehiculos, detectar y seguir vehículos).

  • Reconocimiento de actividades humanas (correr, caminar, brincar).

  • Seguimiento de objetos (seguir la bola en el tenis).

Los modelos de mezclas gaussianas son populares para esta tarea: la idea básica es suponer que la intensidad de cada pixel en una imagen se puede modelar usando un modelo de mezclas Gaussianas. Después se determina que intensidades corresponden con mayor probabilidad al fondo seleccionando como fondo las gaussianas con menos varianza y mayor evidencia ($\pi_j$).

En OpencCV hay tres algoritmos implementados para sustraer fondo, estos usan variantes de mezclas gaussianas:

  1. An Improved Adaptive Background Mixture Model for Real- time Tracking with Shadow Detection

  2. Efficient Adaptive Density Estimation per Image Pixel for the Task of Background Subtraction

  3. Improved adaptive Gausian mixture model for background subtraction

PCA y Análisis de Factores

Continuamos explorando modelos de variable latente, en particular exploramos casos de variable latente continua. Una motivación para estos modelos es que muchos conjuntos de datos tienen la propiedad que los puntos caen en un variedad de dimensión mucho menor a la dimensión original de los datos.

Para entender esta idea consideremos una base de datos consrtuida con uno de los dígitos de la base de datos mnist, esta imagen esta representada por una matriz de $64 \times 64$ pixeles, ahora insertamos este dígito en una matriz más grande de $100 \times 100$ agregando espacio en blanco y variamos de manera aleatoria la orientación y ubicación del dígito.

Cada una de las imágenes resultantes está representada por un punto en el espacio de dimensión $100 \times 100 = 10,000$; sin embargo, en una base de datos construida de esta manera solamente hay 3 grados de libertad de variabilidad, estas corresponden a las rotaciones, trasalación vertical y traslación horizontal.

Para datos reales habrá más grados de libertad debido por una parte a escalamiento y por otra habrá múltiples grados adicionales debidas a deformaciones debidas a la variabilidad en la escritura de un individuo y entre individuos. Aún así, la la dimensionalidad de los grados de libertad es mucho menor que la de los datos completos.

library(deepnet)
library(RColorBrewer)

mnist <- load.mnist("data/mnist")[["train"]]
ind_tres <- mnist[[3]] == 3
data_tres <- mnist[[2]][ind_tres, ]
par(mfrow=c(1,5))

imageD <- function(vec, main = NULL){
  mat_digit <- matrix(vec, nrow = 28)[, 28:1]
  image(mat_digit, col = brewer.pal(5, "GnBu"), xaxt = "n", yaxt = "n", 
    bty = "n", asp = 1, main = main)
}

for(i in sample(1:nrow(data_tres), 5)){
  imageD(data_tres[i, ])
}

El modelo de variable latente más simple supone distribuciones Gaussianas para las variables latentes y las observadas, además de usar dependencia lineal Gaussiana entre latentes y observables. Este escenario corresponde a PCA probabilítsico y a análisis de factores.

Componentes principales

El análisis de componentes principales (PCA) es una técnica que se utiliza con distintos objetivos:

  1. Reducción de dimensionalidad.

  2. Compresión de información con pérdida (lossy).

  3. Extracción de características o (features).

  4. Visualización de datos.

Podemos ver PCA desde dos puntos de vista que nos llevan al mismo resultado:

* PCA se puede definir como una proyección de los datos en un espacio de dimensión menor (conocido como subespacio principal), tal que la varianza de los datos proyectados es máxima.
  • PCA se puede definir como la proyección lineal que minimiza el costo medio de proyección, donde el costo promedio es la distancia media al cuadrado entre los puntos y sus proyecciones.

Formulación de máxima varianza

Consideremos un vector de observaciones $(y^1,...,y^n)$ donde $y_i$ es de dimensión $d$. Nuestro objetivo es proyectar los datos en un espacio de dimensión $M&lt;D$ maximizando la varianza de la proyección.

Comencemos considerando la proyección en un espacio de dimensión uno, denotamos la dirección de este espacio por $u_1$ y por conveniencia usamos un vector unitario ($u_1^Tu_1=1$). La proyección de cada punto $y_i$ es un escalar (pues $M=1$) cuyo valor es $u_1^Ty_i$. La media de los datos proyectados es $u_1^T\bar{y}$ donde $$\bar{y}=\frac{1}{N}\sum_{i=1}^N y_i$$ por tanto la varianza de los datos proyectados es $$\frac{1}{N}\sum_{i=1}^N (u_1^Ty_i-u_1^T\bar{y})^2=u_1^TSu_1$$ donde S es la matriz de covarianzas de los datos: $$S=\frac{1}{N}\sum_{i=1}^N (y_i-\bar{y})(y_i-\bar{y})^T.$$

Ahora maximizamamos la varianza de la proyección respecto a $u_1$: $$argmax_{u_1}u_1^TSu_1 + \lambda_1(1-u_1^Tu_1)$$ Derivando encontramos un punto estacionario en $$Su_1=\lambda_1u_1$$ por lo que $u_1$ debe ser un eigenvector de S, notamos también que la varianza esta dada por: $$u_1^TSu_1=\lambda_1$$ y por tanto la varianza será máxima si igualamos $u_1$ con el mayor eigenvector de $S$, que llamamos primer componente principal.

Si elegimos $M&gt;1$, definimos los componentes de manera incremental, en cada paso seleccionamos una nueva dirección eligiendo cada nueva dirección como aquella que maximiza la varianza de la proyección sujeta a ser ortogonal a las direcciones (componentes) ya elegidos. Esto resulta en que la proyección lineal óptima para la cual la varianza de los datos proyectados es máxima esta definida por el conjunto de $M$ eigenvectores $u_1,...,u_M$ de la matriz de covarianzas $S$.

Formulación de error mínimo

Ahora discutimos el segundo punto de vista de PCA. Sea $(u_1,...,u_D)$ una base ortonormal de vectores, esto es $u_i^Tu_j = 0$ para toda $i$ distinta de $j$ y $u_i^Tu_i = 1$.

Como esta es una base de $R^D$ podemos expresar los datos observados como

$$y_i=\sum_{j=1}^D \alpha_{ij}u_j$$

Esto corresponde a una rotación en el sistema de coordenadas. Utilizando la propiedad ortonormal obtenemos $\alpha_{ij}={y_i} ^Tu_j$, por tanto:

$$y_i=\sum_{j=1}^D ({y_i} ^Tu_j) u_j$$

Ahora, como buscamos aproximar este punto ($y_i$) usando una representación que involucre un número de variables $M&lt;D$, la subespacio de dimensión $M$ se puede representar usando los primeros $M$ vectores de la base, de tal manera que podemos aproximar cada punto como:

$$\hat{y}i=\sum{j=1}^M x_{ij}{u_j} + \sum_{j=M+1}^D b_j u_j$$

donde los valores $x_{ij}$ dependen del dato que estamos proyectando y las $b_j$ son constantes para todos los datos. Buscamos $(u_1,...,u_D)$, $x_{ij}$ y $b_j$ tal que se minimice la distorsión introducida por la reducción de dimensión, donde definimos la distorsión como la distancia al cuadrado entre el punto original $y_i$ y la aproximación $\hat{y}_i$ promediada sore todos los puntos de la base de datos:

$$J=\frac{1}{N}\sum_{j=1}^N(y_j-\hat{y}_j)^T(y_j-\hat{y}_j)$$

La minimización (derivar e igualar a cero) nos lleva a:

  • $x_{ij}=y_i^Tu_j$, con $j=1,...,M$

  • $b_{j}=\bar{y}^Tu_j$, con $j=M+1,...,D$

Sustituyendo $x_{ij}$ y $b_j$ en $y_i=\sum_{j=1}^D ({y_i} ^Tu_j) u_j$ llegamos a $$y_i-\hat{y}i=\sum{j=M+1}^D [(y_n-\bar{y})^Tu_j]u_j$$

y vemos que el error mínimo ocurre en la proyección ortogonal sobre el subespacio generado por ${u1,...,u_M}$.

Usando lo anterior obtenemos

$$J=\frac{1}{N}\sum_{j=1}^N \sum_{i=M+1}^D [(y_n-\bar{y})^Tu_j]^T[(y_n-\bar{y})^Tu_j]$$ $$J=\frac{1}{D}\sum_{j=1}^D u_i^TSu_i$$

Aún falta minimizar $J$ respecto a $u_i$, esta es una minimización con la restricción $u_i^Tu_i=1$, si derivamos respecto a $u_i$ obtenemos

$$Su_i=\lambda_i u_i$$

por lo que cualquier eigenvector de S corresponde a un punto crítico. Si todos corresponden a un punto crítico ¿cómo elegimos? Notemos que si sustituimos la solución de $u_i$ en J obtenemos

$$J=\sum_{j=M+1}^D \lambda_j$$

por lo que para obtener el mínimo valor de $J$ hay que seleccionar los $D-M$ eigenvectores corresponidientes a los menores eigenvalores y por tanto los eigenvectores que definen el subespacio principal corresponden a los $M$ eigenvectores mayores.

Aplicaciones de PCA

Veamos un par de aplicaciones de PCA, comenzaremos con compresión de imágenes y luego examinaremos PCA como preprocesamiento.

Compresión de datos

Veamos un ejemplo de PCA para compresión de información usando la base de datos de mnist, en particular veamos los dígitos tres.

data_tres <- mnist[[2]][ind_tres, ]
dim(data_tres)
#> [1] 6131  784

Como cada eigenvector es un vector en el espcio original de $D$ dimensiones podemos representarlos como imágenes.

data_tres <- mnist[[2]][ind_tres, ]
tres_mean <- apply(data_tres, 2, mean)

S <- cov(data_tres)
eigen_S <- eigen(S)
lambda <- eigen_S$values
u <- eigen_S$vectors

par(mfrow=c(1,5))
imageD(tres_mean)
for(i in 1:4){
  imageD(u[, i])  
}

Podemos ver el resto de los eigenvalores en la gráfica de abajo. Graficamos también la medida de distorsión $J$ asociada a la elección del número de componentes $M$ (dada por la suma de los eigenvalores $M+1$ a $D$).

D <- length(lambda)
J <- sapply(1:D, function(i){sum(lambda[i:D])})
par(mfrow=c(1,2))
plot(lambda, type = "l")
plot(J, type = "l")

Si vemos las fórmulas de arriba podemos escribir el vector de aproximación correspondiente a una observación.

$$\hat{y}i=\sum{j=1}^M x_{ij}{u_j} + \sum_{j=M+1}^D b_j u_j$$ $$=\sum_{j=1}^M (y_i^Tu_j){u_j} + \sum_{j=M+1}^D (\bar{y}^Tu_j) u_j$$ $$=\bar{y} + \sum_{j=1}^M (y_i^Tu_j-\bar{y}^Tu_j)u_j$$

donde usamos: $$\bar{y}=\sum_{j=1}^D (\bar{y}^Tu_j)u_j$$

La compresión está en que reemplazamos cada vector de observaciones de dimensión $D$ ($y_i$) por un vector de dimensión $M$.

La siguiente figura muestra la compresión para distintos valores de $M$ del prmer dígito de la base de datos.

tres_1 <- data_tres[3, ]
par(mfrow=c(1,5))
imageD(tres_1)
for(M in c(1, 10, 50, 300)){
  u_M <- u[, 1:M]
  y_M <- tres_1 %*% u_M
  y_approx <- tres_mean + y_M %*% t(u_M)
  imageD(y_approx)
}

Comprime una imagen en blanco y negro.

Preprocesamiento {-}

Otra aplicación de componentes principales es preprocesamento, en este caso el objetivo no es reducción de dimensión sino la transformación de un conjunto de datos con el fin de estandarizar algunas de sus propiedades. Esto puede ser importante para el correcto funcionamiento de algoritmos o métodos que se desean usar después.

Veamos los datos faithful de erupciones del volcán Old Faithful.

head(faithful)
#>   eruptions waiting
#> 1     3.600      79
#> 2     1.800      54
#> 3     3.333      74
#> 4     2.283      62
#> 5     4.533      85
#> 6     2.883      55

Notamos que el tiempo entre erupciones es de un orden de magnitud mayor que la duración de la erupción. Por ejemplo, si quisieramos hacer k-medias sería natural estandarizar los datos. Sin embargo, con PCA podemos normalizar los datos para tener cero media y covarianza unitaria, de tal manera que la correlación entre distintas variables es cero.

Para hacer esto escribimos la ecuación de eigenvectores como $$SU=UL$$

donde $L$ es una matriz diagonal con los elementos $\lambda_i$ y $U$ es una matriz ortogonal cuyas columnas son los vectores $u_i$. Entonces, para cada observación $y_i$ definimos su valor transformado

$$z_i=L^{-1/2}U^T(y_i-\bar{y})$$

es claro que el conjunto $(z_1,...,z_N)$ tiene media cero, veamos ahora la covarianza:

$$\frac{1}{N}\sum_{j=1}^Nz_jz_j^T=\frac{1}{N}\sum_{j=1}^NL^{-1/2}U^T(y_j-\bar{y})(y_j-\bar{y})^TUL^{-1/2}$$

$$=L^{-1/2}U^TSUL^{-1/2}=L{-1/2}LL^{-1/2}=I$$

Esta operación se conoce como whitening o sphereing.

Implementa whitening en los datos faithful, compara las gráficas de los datos crudos y preprocesados.

PCA probabilístico y Análisis de Factores

La formulación de PCA esta fundada en una proyección lineal de los datos sobre un subespacio de dimensión menor. En esta sección veremos que PCA también se puede expresar como la solución de máxima verosimilitud de en un modelo probabilístico de variable latente.

Para formular PCA probabilístico introducimos una variable latente $X$ que corresponde al subespacio de componentes principales, suponemos $X\sim N(0, I)$. Por otra parte, la distribución de la variable aleatoria observada $Y$ condicional a la variable latente $X$ es $Y|X\sim N(Wx+\mu, \sigma^2I$

Veremos que las columnas de $W$ (dimensión $D\times M$) generan un subsepacio que correponde al subespacio de componentes principales.

El siguiente esquema explica el modelo PCA probabilístico desde el punto de vista generativo.

Desde este enfoque vemos que primero selecciona aleatoriamente un valor de la variable latente ($x$) y después muestreamos el valor observado condicional a la variable latente, en particular la variable obsevada (de dimensión $D$) se define usando una transformación lineal del espacio latente mas ruido Gaussiano aleatorio:

$$y=Wx + \mu + \epsilon$$

donde $x\sim N(0, I)$ de dimensión $M$ y $\epsilon \sim N(0, \sigma^2I)$ de dimensión $D$.

Ahora, si queremos usar máxima verosimilitud para estimar $W$, $\mu$ y $\sigma^2$, necesitamos una expresión para la distribución marginal de la variable observada:

$$p(y)=\int p(y|x)p(x)dx$$

dado que este corresponde a un modelo Gaussiano lineal su distribución marginal es nuevamente Gaussiana con media $\mu$ y matriz de covarianzas $C=WW^T+\sigma^2I.$

Entonces, la distribución $p(y)$ depende de los parámetros $W$, $\mu$ y $\sigma^2$; sin embargo hay una redundancia en la parametrización que corresponde a rotaciones en el espacio de coordenadas de las variables latentes. Para ver esto consideremos $Q$ una matriz ortonormal de dimensión $D \times D$ ($Q$ es una matriz de rotación), $$Q^T Q = Q Q^T = I$$ Al observar la igualdad $C=WW^T+\sigma^2I$, notamos que no existe una única $W$ que la satisfaga pues si definimos $\tilde{W}=WQ$ tenemos que $$\tilde{W}\tilde{W}^T=WQQ^TW^T=WW^T$$ y por tanto $C=\tilde{W}{W}^T+\sigma^2I$. Este es un aspecto que consideraremos más a fondo en la parte de estimación.

Máxima verosimilitud {-}

Consideramos la determinación de los parámetros usando máxima verosimilitud: $$ \begin{aligned} \log p(y)&=\sum_{i=1}^N\log p(y_j)\ &=-\frac{ND}{2}-\frac{N}{2}\log(2\pi)\log|C| -\frac{1}{2}\sum_{j=1}^N(y_j-\mu)^TC^{-1}(y_j-\mu) \end{aligned} $$

Derivando e igualando a cero obtenemos $\hat{\mu}=\bar{y}$, la maximización con respecto a $W$ y $\sigma^2$ es más difícil pero tiene forma cerrada (Tipping y Bishop 1999).

$$\hat{W}=U_{M}(L_M-\sigma^2I)^{1/2}R$$

donde $U_{M}$ es una matriz de dimensión $D \times M$ cuyas columnas corresponden a los $M$ eigenvectores asociados a los mayores eigenvalores de la matriz de covarianzas $S$. La matriz $L$ de dimensión $M \times M$ esta conformada por los eigenvalores correspondientes. Por último, R res cualquier matriz ortonormal de dimensión $M \times M$.

Suponemos que los eigenvectores están ordenados en orden decreciente de acuerdo a sus eigenvalores correspondientes $u_1,...,u_M$, en este caso las columnas de $W$ definen el subespacio de PCA estándar. Por su parte, la solución de máxima verosimilitud para $\sigma^2$ es:

$$\hat{\sigma^2}=\frac{1}{D-M}\sum_{j=M+1}^D \lambda_j$$

notemos que $\hat{\sigma}^2$ es la varianza promedio asociada a las dimensiones que no incluimos.

Ahora, como R es ortogonal se puede interpretar como una matriz de rotación en el espacio de variables latentes. Por ahora, pensemos $R=I$ notamos que las columnas de $W$ son los vectores de componentes principales escalados por los parámetros de varianza $\lambda_i-\sigma^2$, para ver la interpretación notemos que en la suma de Gaussianas independientes las varianzas son aditivas. Por tanto, la varianza $\lambda_i$ en la dirección de un eigenvector $u_i$ se compone de la contribución $(\lambda_i-\sigma^2)$ de la proyección del espacio latente (varianza 1) al espacio de los datos a través de la columna correspondiente de $W$ mas la contribución del ruido con varianza isotrópica $\sigma^2$.

Observaciones {-}

  • El método convencional de PCA se suele describir como una proyección de los puntos en un espacio de dimensión $D$ en un subespacio de dimensión $M$.

  • PCA probabilístco se expresa de manera más natural como un mapeo del espacio latente al espacio de los datos observados.

  • Una función importante de PCA probabilítico es definir una distribución Gaussiana multivariada en donde el número de grados de libertad se puede controlar al mismo tiempo que podemos capturar las correlaciones más importantes de los datos. En general una distribución Gaussiana multivariada tiene $p(p+1)/2$ parámetros independientes en la matriz de covarianzas por lo que el número de parámetros crece de manera cuadrática con $p$. Por otra parte si restringimos a una matriz de covarianzas diagonal tenemos solamente $p$ parámetros, sin embargo en este último caso no podemos entender las correlaciones. PCA probabilístico (y Análisis de Factores) son un punto medio en el que las $q$ correlaciones más fuertes se pueden capturar mientras que el número de parámetros crece de manera lineal con $p$. En el caso de PCA con $M$ componentes: $p\cdot M + 1 - M\cdot(M-1)/2$.

  • PCA convencional corrresponde al límite $\sigma^2 \to 0$

  • PCA probabilístico se puede escribir en términos de un espacio latente por lo que la implementación del algoritmo EM es una opción natural. En casos donde $M&lt;&lt;D$ la estimación mediante EM puede ser más eficiente.

  • Debido a que tenemos un modelo probabilitico para PCA podemos trabajar con faltantes (MCAR y MAR) marginalizando sobre la distribución de los no observados. El manejo de faltantes es otra ventaja de la implementación EM.

  • El algoritmo EM se puede extender al caso de Análisis de factores para el cuál no hay una solución cerrada.

Análisis de factores

El análisis de factores es muy similar a PCA probabilístico, la diferencia radica en que en la distribución condicional de $Y|X$ la matriz de covarianza se supone diagonal en lugar de isotrópica:

$$Y|X \sim N(Wx + \mu, \Psi)$$

Donde $\Psi$ es una matriz diagonal de dimensión $D \times D$. Al igual que en PCA probabilístico, el modelo de FA supone que las variables observadas son independientes dado las latentes. En escencia el análisis de factores está explicando la estructura de covarianza observada representando la varianza
independiente asociada a cada variable en la matriz $\Psi$ (unicidades) y capturando la varianza compartda en $W$ (comunalidades o cargas).

La distribución marginal de las variables observadas es $X\sim N(\mu, C)$ donde $$C=WW^T+\Psi.$$ Es fácil notar que de manera similar a PCA probabilístico el modelo es invariante a rotaciones en el espacio latente.

El análisis de factores suele ser criticado cuando se busca interpretar los factores (coordenadas en el espacio latente). El probema resulta de que los factores no están identificados ante rotaciones. Ante esto, Bisop explica que podemos ver el análisis de factores como un modelo de variable latente en el que nos interesa el espacio latente más no la elección particular de coordenadas que elijamos para describirlo.

Análisis de factores (descripción tradicional) {-}

Trataremos ahora con análisis de factores, los modelos que veremos se enfocan en variables observadas y latentes continuas. La idea esencial del análisis de factores es describir las relaciones entre varias variables observadas ($Y=Y_1,...,Y_p$) a través de variables latentes ($X_1,...,X_q$) donde $q &lt; p$. Como ejemplo consideremos una encuesta de consumo de hogares, donde observamos el nivel de consumo de $p$ productos diferentes. Las variaciones de los componentes de $Y$ quizá se puedan explicar por 2 o 3 factores de conducta del hogar, estos podrían ser un deseo básico de comfort, o el deseo de alcanzar cierto nivel social u otros conceptos sociales. Es común que estos factores no observados sean de mayor interés que las observaciones en si mismas.

En la gráfica inferior vemos un ejemplo en educación donde las variables vocab, reading, maze,... corresponden a las variables observadas mientras que $X_1$ y $X_2$ son las variables latentes. Observamos que añadir estructura al problema resulta en una simplificación del modelo.

En ocasiones, el análisis de factores se utiliza como una técnica de reducción de dimensión que esta basada en un modelo. Idealmente, toda la información en la base de datos se puede reproducir por un número menor de factores.

El modelo {-}

Sea $Y = (Y_1,...,Y_p)^T$ un vector de variables aleatorias observables donde todas las variables son cuantitativas. Supongamos que cada $Y_j$ en $Y$ ($j=1,...,p$) satisface: $$Y_j = \sum_{k=1}^K \lambda_{jk} X_k + u_j$$ donde

  • $X_k$ son los factores comunes (variables aleatorias continuas no observables).

  • $u_j$ son errores (aleatorios).

  • $\lambda_{jk}$ son las cargas de la variable $j$ en el factor $k$, (parámetros).

En notación matricial el modelo se escribe: $$Y_{p\times 1} = \Lambda_{p\times K} X_{K\times 1} + U_{p\times 1}$$ donde $\Lambda, X$ y $U$ no son observadas, únicamente observamos $Y$.

Adicionalmente, tenemos los siguientes supuestos:

  • $X \perp U$, esto es, los errores y los factores son independientes.

  • $E(X)=E(U)=0$.

  • $Cov(X) = I_k$ (modelo ortogonal de factores) ésto se ve en la gráfica pues no hay arcos que unan a $X_1$ y $X_2$.

  • $Cov(U) = \Psi$, donde $\Psi$ es una matriz diagonal ($p \times p$).

Típicamente, se asume que $U$ y $X$ son Normales multivariadas. ¿Cómo vemos que $Y_i \perp Y_j|X$

Lo que buscamos es explicar la relación entre las variables observadas a través de las variables latentes, las relaciones que buscamos explicar están resumidas en la matriz de varianzas y covarianzas. En nuestro ejemplo la matriz es la siguiente:

ability.cov$cov
#>         general picture  blocks   maze reading   vocab
#> general  24.641   5.991  33.520  6.023  20.755  29.701
#> picture   5.991   6.700  18.137  1.782   4.936   7.204
#> blocks   33.520  18.137 149.831 19.424  31.430  50.753
#> maze      6.023   1.782  19.424 12.711   4.757   9.075
#> reading  20.755   4.936  31.430  4.757  52.604  66.762
#> vocab    29.701   7.204  50.753  9.075  66.762 135.292

y la matriz de correlaciones es:

cov2cor(ability.cov$cov)
#>           general   picture    blocks      maze   reading     vocab
#> general 1.0000000 0.4662649 0.5516632 0.3403250 0.5764799 0.5144058
#> picture 0.4662649 1.0000000 0.5724364 0.1930992 0.2629229 0.2392766
#> blocks  0.5516632 0.5724364 1.0000000 0.4450901 0.3540252 0.3564715
#> maze    0.3403250 0.1930992 0.4450901 1.0000000 0.1839645 0.2188370
#> reading 0.5764799 0.2629229 0.3540252 0.1839645 1.0000000 0.7913779
#> vocab   0.5144058 0.2392766 0.3564715 0.2188370 0.7913779 1.0000000

Entonces, volviendo al modelo examinemos que implicaciones tiene en la matriz de varianzas y covarianzas de las variables aleatorias observables. Denotemos la matriz de varianzas y covarianzas por $\Sigma = Var(Y)$ y la expresaremos en términos de los parámetros del modelo.

$$\Sigma = \Lambda \Lambda^T + \Psi$$

Los términos en la diagonal de $\Sigma$ (varianzas de cada variable observada) son:

$$Var(Y_j) = \sum_{k= 1}^K \lambda_{jk}^2 + \Psi_{jj}$$ $$= comunalidad + unicidad$$

La comunalidad de la variable $Y_j$ dada por $\sum_{k= 1}^K \Lambda^2(j,k)$ es la varianza que comparte esta variable con otras variables por medio de los factores, mientras que la unicidad $\Psi(j,j)$ es la varianza de la variable $j$ que no comparte con el resto. Un buen análisis de factores tiene comunalidades altas y unicidades bajas (relativamente).

Los términos fuera de la diagonal están dados por:

$$Cov(Y_j, Y_i)= \sum_{k=1}^K\lambda_{jk}\lambda_{ik}$$

Sea $X \sim N(0, 1), u_1 \sim N(0,1),u_2 \sim N(0,2)$. Definimos $$Y_1 = X + u_1$$ $$Y_2 = -X+u_2$$

  • Comunalidades:

  • Unicidades:

  • Descomposición de la matriz de varianzas y covarianzas:

Ejemplo: Pruebas de habilidad.

ability_fa <- factanal(factors = 2, covmat = ability.cov, rotation = "none")
ability_fa
#> 
#> Call:
#> factanal(factors = 2, covmat = ability.cov, rotation = "none")
#> 
#> Uniquenesses:
#> general picture  blocks    maze reading   vocab 
#>   0.455   0.589   0.218   0.769   0.052   0.334 
#> 
#> Loadings:
#>         Factor1 Factor2
#> general  0.648   0.354 
#> picture  0.347   0.538 
#> blocks   0.471   0.748 
#> maze     0.253   0.408 
#> reading  0.964  -0.135 
#> vocab    0.815         
#> 
#>                Factor1 Factor2
#> SS loadings      2.420   1.162
#> Proportion Var   0.403   0.194
#> Cumulative Var   0.403   0.597
#> 
#> Test of the hypothesis that 2 factors are sufficient.
#> The chi square statistic is 6.11 on 4 degrees of freedom.
#> The p-value is 0.191

Estimación del modelo {-}

Antes de adentrarnos en la estimación vale la pena considerar dos aspectos:

  1. Rotaciones: Al observar la igualdad $\Sigma = \Lambda\Lambda^T + \Psi$, notamos que no existe una única $\Lambda$ que la satisfaga. Sea $Q$ una matriz ortonormal de dimensión $K \times K$ ($Q$ es una matriz de rotación), $$Q^T Q = Q Q^T = I$$ Si $\Lambda$ es tal que $Y = \Lambda X + U$ y $\Sigma = \Lambda\Lambda^T + \Psi$ entonces, $$Y=(\Lambda Q)(Q^TX) + U$$ $$\Sigma = (\Lambda Q) (\Lambda Q)^T + \Psi = \Lambda\Lambda^T + \Psi$$ por lo tanto, $\Lambda_1 = (\Lambda Q)$ y $X_1 = Q^TX$ también son una solución para el modelo. Esto nos dice, que cualquier rotación de las cargas nos da una solución. Hay amplia literatura en este tema, típicamente la elección de una rotación busca mejorar la interpretación.

  2. ¿Cuántos factores?: No hay una respuesta directa a la pregunta pero para aspirar a contestarla respondamos primero: ¿Cuántos factores puedo estimar? Contemos el número de parámetros que vamos a estimar y veamos los grados de libertad:

  • Parámetros en $\Sigma:p(p+1)/2$
  • Parámetros en $\Lambda$ y $\Psi:pK + p$
  • Restricciones necesarias para fijar la rotación: $K(K-1)/2$
  • Grados de libertad: $d = p(p+1)/2 - (pK + p - K(K-1)/2)$
    Si $d &lt; 0$, no podemos estimar el modelo, por lo tanto el mayor número de factores que puedo estimar depende del número de variables observadas. Por ejemplo si $p = 5$, únicamente podemos estimar modelos con 1 ó 2 factores.
    Volviendo a la pregunta original: ¿Cuántos factores debo modelar? La respuesta depende del objetivo del análisis de factores, en ocasiones se desea utilizar las variables latentes como un resumen_ de las variables observadas e incorporarlas a ánalisis posteriores, en este caso es conveniente analizar el porcentaje de la varianza en las variables observadas que se puede explicar con los factores, por ejemplo si el tercer factor no contribuye de manera importante a explicar la variabilidad observada, el modelo con dos factores sería preferible. Por otra parte, si asumimos normalidad ($X\sim N(0, I), U\sim N(0, \Psi)$) podemos comparar la verosimilitud (o AIC, BIC) de los modelos con distinto número de factores y elegir de acuerdo a este criterio.

Una vez que fijamos el número de factores, hay varios métodos de estimación, el más popular implementa el algoritmo EM, sin embargo este método requiere supuestos de normalidad. Dentro de los métodos que no requieren supuestos adicionales está el método de factores principales.

Método del factor principal {-}

En adelante utilzamos la matriz de covarianzas muestral, $$S = \frac{1}{N} \sum_{n = 1}^N(X_n-\bar{X})(X_n-\bar{X})^T$$ como la estimación de la matriz de covarianzas poblacional $\Sigma$. Usualmente no es posible encontrar matrices $\hat{\Lambda},\hat{\Psi}$ tales que la igualdad $S = \hat{\Lambda}\hat{\Lambda}^T+\hat{\Psi}$ se cumpla de manera exacta. Por tanto el objetivo es encontrar matrices tales que se minimice $traza(S-\hat{S})^T(S-\hat{S})$ donde $\hat{S} = \hat{\delta}\hat{\delta}^T+\hat{Psi}$. El algoritmo del método del factor principal funciona de la siguiente manera:

  1. Inicializa $\hat{\Psi}$ (cualquier valor)

  2. $\hat{\Psi}=$ los $K$ mayores eigenvectores de la matriz $$(\hat{S} - \hat{\Psi})$$ Nos fijamos en esta diferencia porque nos interesa explicar las covarianzas a través de los factores comunes.

  3. $\hat{\Psi} = diag(S-\hat{\Lambda}\hat{\Lambda}^T)$

Los pasos 2 y 3 se repiten hasta alcanzar convergencia. Este algoritmo no es muy popular debido a que la convergencia no está asegurada, se considera lento y los valores iniciales de $\Psi$ suelen influenciar la solución final.

Análisis de factores de máxima verosimilitud {-}

Supongamos ahora que, $$X \sim N(0, I)$$ $$U \sim N(0,\Psi)$$ Entonces la distribución del vector de variables aleatorias observables $Y$ es $$Y \sim N(\mu + \Lambda x, \Sigma)$$ donde $\Sigma = \Lambda \Lambda^T + \Psi$ (igual que antes). Es fácil ver que la distribución condicional de $Y$ es: $$Y|X \sim N(\mu + \Lambda x, \Psi)$$ por tanto, se cumple las independencias condicionales que leemos en la gráfica. Ahora, la log verosimilitud es: $$log L(\Sigma) = - \frac{np}{2} log(2\pi) - \frac{n}{2}log det(\Sigma) - \frac{n}{2}tr(\Sigma^{-1}S)$$ buscamos parámetros$\hat{\Lambda}$ y $\hat{Psi}$ que maximizen esta log-verosimilitud, sin embargo, estos parámetros no se pueden separar facilmente (es decir maximizar individualmente) ya que están relacionados a través de $det(\Sigma)$ y $\Sigma^{-1}$. No hay una forma cerrada para encontrar los parámetros de máxima verosimilitud de la expresión anterior. Recurrimos entonces al algoritmo EM, donde en el paso E rellanamos los valores de $X$ y en el paso M estimamos $\Lambda$ y $\Psi$ utilizando que éstos parámetros se pueden separar si conozco $X$.

Evaluación del modelo {-}

Volviendo al número de factores, una vez que hacemos supuestos de normalidad podemos calcular la devianza del modelo: $$D = n*(tr(\hat{\Sigma}^{-1}S) - log det(\hat{\Sigma}^{-1}S) - p)$$ y el BIC. Por tanto, podemos comparar modelos con distintos factores utilizando este criterio. $$d = p - {1}{2}((p-q)^2 - (p+q))$$ y por tanto $BIC = D + d log N$.

library(psych)
#> 
#> Attaching package: 'psych'
#> The following object is masked from 'package:mclust':
#> 
#>     sim
#> The following objects are masked from 'package:ggplot2':
#> 
#>     %+%, alpha
dev <- function(fit){
  S <- fit$correlation
  n <- fit$n.obs
  p <- nrow(S)
  Sigma <- (fit$loadings) %*% t(fit$loadings) + diag(fit$uniqueness)
  mat.aux <- solve(Sigma) %*% S
  D <- n * (tr(mat.aux) - log(det(mat.aux)) - p)
  return(D)
}
BIC <- function(fit){
  p <- nrow(fit$loadings)
  q <- ncol(fit$loadings)
  v <- p - 1/2 * ((p - q) ^ 2 - (p + q))
  D <- dev(fit)
  BIC <- D + v * log(fit$n.obs) / 2
  return(BIC)
}
ability.fa.1 <- factanal(factors = 1, covmat = ability.cov, 
  rotation = "none")
ability.fa.2 <- factanal(factors = 2, covmat = ability.cov, 
  rotation = "none")
ability.fa.3 <- factanal(factors = 3, covmat = ability.cov, 
  rotation = "none")
BIC(ability.fa.1)
#> Warning: partial match of 'uniqueness' to 'uniquenesses'
#> [1] 71.2489
BIC(ability.fa.2)
#> Warning: partial match of 'uniqueness' to 'uniquenesses'
#> [1] 11.12044
BIC(ability.fa.3)
#> Warning: partial match of 'uniqueness' to 'uniquenesses'
#> [1] 14.1555

Veamos también el porcentaje de la varianza observada que se puede explicar con los distintos modelos.

ability.fa.1
#> 
#> Call:
#> factanal(factors = 1, covmat = ability.cov, rotation = "none")
#> 
#> Uniquenesses:
#> general picture  blocks    maze reading   vocab 
#>   0.535   0.853   0.748   0.910   0.232   0.280 
#> 
#> Loadings:
#>         Factor1
#> general 0.682  
#> picture 0.384  
#> blocks  0.502  
#> maze    0.300  
#> reading 0.877  
#> vocab   0.849  
#> 
#>                Factor1
#> SS loadings      2.443
#> Proportion Var   0.407
#> 
#> Test of the hypothesis that 1 factor is sufficient.
#> The chi square statistic is 75.18 on 9 degrees of freedom.
#> The p-value is 1.46e-12
ability.fa.2 
#> 
#> Call:
#> factanal(factors = 2, covmat = ability.cov, rotation = "none")
#> 
#> Uniquenesses:
#> general picture  blocks    maze reading   vocab 
#>   0.455   0.589   0.218   0.769   0.052   0.334 
#> 
#> Loadings:
#>         Factor1 Factor2
#> general  0.648   0.354 
#> picture  0.347   0.538 
#> blocks   0.471   0.748 
#> maze     0.253   0.408 
#> reading  0.964  -0.135 
#> vocab    0.815         
#> 
#>                Factor1 Factor2
#> SS loadings      2.420   1.162
#> Proportion Var   0.403   0.194
#> Cumulative Var   0.403   0.597
#> 
#> Test of the hypothesis that 2 factors are sufficient.
#> The chi square statistic is 6.11 on 4 degrees of freedom.
#> The p-value is 0.191
ability.fa.3
#> 
#> Call:
#> factanal(factors = 3, covmat = ability.cov, rotation = "none")
#> 
#> Uniquenesses:
#> general picture  blocks    maze reading   vocab 
#>   0.441   0.217   0.329   0.580   0.040   0.336 
#> 
#> Loadings:
#>         Factor1 Factor2 Factor3
#> general  0.636   0.367   0.139 
#> picture  0.350   0.766  -0.272 
#> blocks   0.441   0.639   0.263 
#> maze     0.236   0.325   0.509 
#> reading  0.974  -0.109         
#> vocab    0.811                 
#> 
#>                Factor1 Factor2 Factor3
#> SS loadings      2.382   1.249   0.427
#> Proportion Var   0.397   0.208   0.071
#> Cumulative Var   0.397   0.605   0.676
#> 
#> The degrees of freedom for the model is 0 and the fit was 0

Finalmente, volvamos a las rotaciones. La interpretación de los factores se facilita cuando cada variable observada carga principalmente en un factor, por ello, muchos de los métodos de rotación buscan acentuar esta característica:

  • Rotación varimax: Resulta en algunas cargas altas y otras bajas para cada factor, de manera que las cargas bajas se puedan ignorar en la interpretación. Su nombre se debe a que maximiza la suma de las varianzas de las cargas al cuadrado. En términos de las observaciones (individuos) la rotación varimax busca una base que represente cada individuo de la manera más económica, esto es, cada individuo se puede describir usando una combinación lineal de únicamente unos cuantos factores.

  • Rotación promax: Esta es una rotación oblicua, lo que implica que se pierde la ortogonalidad de los factores. El resultado de esta rotación es que usualmente las cargas se vuelven incluso más extremas que con la rotación varimax.

ability.varimax <- factanal(factors = 2, covmat = ability.cov, 
  rotation = "varimax")
ability.promax <- factanal(factors = 2, covmat = ability.cov, 
  rotation = "promax")
cbind(ability.varimax$loadings, ability.promax$loadings) # cutoff = 0.1
#>           Factor1   Factor2     Factor1      Factor2
#> general 0.4994378 0.5434490  0.36421826  0.470407977
#> picture 0.1560701 0.6215380 -0.05774698  0.671196536
#> blocks  0.2057870 0.8599259 -0.09148422  0.931885105
#> maze    0.1085308 0.4677610 -0.05365717  0.507997088
#> reading 0.9562425 0.1820963  1.02337231 -0.095493703
#> vocab   0.7847682 0.2248221  0.81123097  0.009105393

Visualización {-}

Cuando realizamos componentes principales es común querer proyectar los datos en las componentes. En el caso de AF no es tan sencillo porque los factores son aleatorios, pero hay métodos para calcular puntajes (scores).

  • Método de Bartlett. Supongamos que conocemos $\Lambda$ y $\Psi$, denotemos los puntajes del individuo $i$ en los factores por $x_i$, entonces si $y_i$ es el vector de variables observables del i-ésimo individuo, tenemos que $y_i$ dada $x_i$ se distribuye $N(\Lambda x_i, \Psi)$, por lo que la log-verosimilitud de la observación $y_i$ esta dada por $$-\frac{1}{2} log|2\pi\Psi| - \frac{1}{2}(y_i- \Lambda f_i)^T \Psi^{-1}(y_i - \Lambda x_i)$$ Derivando e igualando a cero se obtiene: $$\hat{x}_i = (\Lambda^T\Psi^{-1}\Lambda)\Lambda^T\Psi^{-1}y_i$$

  • Método de Thompson. Consideramos $x_i$ aleatorio, i.e. $X\sim N(0,I)$, entonces $f|y$ se distribuye $N(\Lambda^T\Psi^{-1}y, I-\Lambda^T \Psi^{-1}\Lambda)$ por lo que un estimador natural para $x_i$ es $$\hat{x}_i = \Lambda^T\Psi^{-1}y_i$$

Ejemplo. La base de datos wine contiene medidas en 13 atributos diferentes de 180 vinos.

library(gridExtra)
#> 
#> Attaching package: 'gridExtra'
#> The following object is masked from 'package:dplyr':
#> 
#>     combine
library(ggplot2)

wine <- read.csv("data/wine.csv", header=T)
head(wine)
#>   A Alcohol.content Malic.acid   As Alcalinity.in.ash Magnesium
#> 1 1           14.23       1.71 2.43              15.6       127
#> 2 1           13.20       1.78 2.14              11.2       100
#> 3 1           13.16       2.36 2.67              18.6       101
#> 4 1           14.37       1.95 2.50              16.8       113
#> 5 1           13.24       2.59 2.87              21.0       118
#> 6 1           14.20       1.76 2.45              15.2       112
#>   Total.phenols Falavanoids Nonflavanoid.phenols Proantocyanins
#> 1          2.80        3.06                 0.28           2.29
#> 2          2.65        2.76                 0.26           1.28
#> 3          2.80        3.24                 0.30           2.81
#> 4          3.85        3.49                 0.24           2.18
#> 5          2.80        2.69                 0.39           1.82
#> 6          3.27        3.39                 0.34           1.97
#>   Color.Intensity  Hue OD280.OD315 Proline
#> 1            5.64 1.04        3.92    1065
#> 2            4.38 1.05        3.40    1050
#> 3            5.68 1.03        3.17    1185
#> 4            7.80 0.86        3.45    1480
#> 5            4.32 1.04        2.93     735
#> 6            6.75 1.05        2.85    1450
pc.wine.1 <- princomp(wine, scores = TRUE)

fa.wine <- factanal(wine, factors = 2, scores = "Bartlett")
fa.pc.wine <- data.frame(fa1 = fa.wine$scores[, 1], pc1 = pc.wine.1$scores[, 1], 
  fa2 = fa.wine$scores[, 2], pc2 = pc.wine.1$scores[, 2])


comp_1 <- ggplot(fa.pc.wine, aes(x = fa1, y = pc1)) + 
  geom_point()
comp_2 <- ggplot(fa.pc.wine, aes(x = fa1, y = pc2)) + 
  geom_point()

grid.arrange(comp_1, comp_2, ncol = 2)

pc.wine.2 <- princomp(wine, scores = T, cor = T)

fa.pc.wine <- data.frame(fa1 = fa.wine$scores[, 1], pc1 = pc.wine.2$scores[, 1], 
  fa2 = fa.wine$scores[, 2], pc2 = pc.wine.2$scores[, 2])

comp_1 <- ggplot(fa.pc.wine, aes(x = fa1, y = pc1)) + 
  geom_point()
comp_2 <- ggplot(fa.pc.wine, aes(x = fa2, y = pc2)) + 
  geom_point()

grid.arrange(comp_1, comp_2, ncol = 2)

par(mfrow=c(1,2))
biplot(pc.wine.1)
#> Warning in arrows(0, 0, y[, 1L] * 0.8, y[, 2L] * 0.8, col = col[2L], length
#> = arrow.len): zero-length arrow is of indeterminate angle and so skipped

#> Warning in arrows(0, 0, y[, 1L] * 0.8, y[, 2L] * 0.8, col = col[2L], length
#> = arrow.len): zero-length arrow is of indeterminate angle and so skipped

#> Warning in arrows(0, 0, y[, 1L] * 0.8, y[, 2L] * 0.8, col = col[2L], length
#> = arrow.len): zero-length arrow is of indeterminate angle and so skipped

#> Warning in arrows(0, 0, y[, 1L] * 0.8, y[, 2L] * 0.8, col = col[2L], length
#> = arrow.len): zero-length arrow is of indeterminate angle and so skipped

#> Warning in arrows(0, 0, y[, 1L] * 0.8, y[, 2L] * 0.8, col = col[2L], length
#> = arrow.len): zero-length arrow is of indeterminate angle and so skipped

#> Warning in arrows(0, 0, y[, 1L] * 0.8, y[, 2L] * 0.8, col = col[2L], length
#> = arrow.len): zero-length arrow is of indeterminate angle and so skipped

#> Warning in arrows(0, 0, y[, 1L] * 0.8, y[, 2L] * 0.8, col = col[2L], length
#> = arrow.len): zero-length arrow is of indeterminate angle and so skipped
biplot(pc.wine.2)

# Ejemplo simulación
x1 <- rnorm(1000)
x2 <- x1 + 0.001 * rnorm(1000)
x3 <- 10 * rnorm(1000) 

x <- data.frame(x1, x2, x3)

fact.x <- fa(x, factors = 1, covar = TRUE, fm ="ml")
pc.x <- princomp(x)
fact.x$loadings
#> 
#> Loadings:
#>    ML1  
#> x1 1.006
#> x2 1.006
#> x3 0.580
#> 
#>                  ML1
#> SS loadings    2.359
#> Proportion Var 0.786
pc.x$loadings
#> 
#> Loadings:
#>    Comp.1 Comp.2 Comp.3
#> x1         0.707  0.707
#> x2         0.707 -0.707
#> x3  1.000              
#> 
#>                Comp.1 Comp.2 Comp.3
#> SS loadings     1.000  1.000  1.000
#> Proportion Var  0.333  0.333  0.333
#> Cumulative Var  0.333  0.667  1.000

y <- scale(x)

fact.y <- fa(y, factors = 1, fm ="ml")
pc.y <- princomp(y)
fact.y$loadings
#> 
#> Loadings:
#>    ML1  
#> x1 0.999
#> x2 0.999
#> x3      
#> 
#>                  ML1
#> SS loadings    1.997
#> Proportion Var 0.666
pc.y$loadings
#> 
#> Loadings:
#>    Comp.1 Comp.2 Comp.3
#> x1  0.706         0.707
#> x2  0.706        -0.707
#> x3        -0.998       
#> 
#>                Comp.1 Comp.2 Comp.3
#> SS loadings     1.000  1.000  1.000
#> Proportion Var  0.333  0.333  0.333
#> Cumulative Var  0.333  0.667  1.000

fact.y
#> Warning: partial match of 'fa' to 'factors'
#> Warning: partial match of 'fa' to 'factors'
#> Factor Analysis using method =  ml
#> Call: fa(r = y, fm = "ml", factors = 1)
#> Warning: partial match of 'uniqueness' to 'uniquenesses'
#> Standardized loadings (pattern matrix) based upon correlation matrix
#>     ML1     h2     u2 com
#> x1 1.00 0.9975 0.0025   1
#> x2 1.00 0.9975 0.0025   1
#> x3 0.04 0.0019 0.9981   1
#> 
#>                 ML1
#> SS loadings    2.00
#> Proportion Var 0.67
#> 
#> Mean item complexity =  1
#> Test of the hypothesis that 1 factor is sufficient.
#> 
#> The degrees of freedom for the null model are  3  and the objective function was  13.8 with Chi Square of  13756.86
#> The degrees of freedom for the model are 0  and the objective function was  7.5 
#> 
#> The root mean square of the residuals (RMSR) is  0 
#> The df corrected root mean square of the residuals is  NA 
#> 
#> The harmonic number of observations is  1000 with the empirical chi square  0.01  with prob <  NA 
#> The total number of observations was  1000  with Likelihood Chi Square =  7469.84  with prob <  NA 
#> 
#> Tucker Lewis Index of factoring reliability =  -Inf
#> Fit based upon off diagonal values = 1
#> Measures of factor score adequacy             
#>                                                   ML1
#> Correlation of (regression) scores with factors     1
#> Multiple R square of scores with factors            1
#> Minimum correlation of possible factor scores       1

En el ejemplo de simulación vemos que el análisis de componentes principales se alinea con la dirección de máxima varianza $X_3$ mientras que el análisis de factores ignora el componente no correlacionado y captura el componente correlacionado $X_2 + X_1$. Debido a que en FA modelamos diferentes unicidades $u_j$ para cada $Y_j$ el análisis de factores puede verse como un modelo para la estructura de correlación de $Y_j$ en lugar de la estructura de covarianzas.