Estaba utilizando el Análisis Discriminante Lineal (LDA) del scikit-learn
biblioteca de aprendizaje automático (Python) para la reducción de la dimensionalidad y tenía un poco de curiosidad por los resultados. Ahora me pregunto qué es el LDA en scikit-learn
está haciendo para que los resultados se vean diferentes de, por ejemplo, un enfoque manual o un LDA hecho en R. Sería genial si alguien pudiera darme algunas ideas aquí.
Lo más preocupante es que la scikit-plot
muestra una correlación entre las dos variables donde debería haber una correlación 0.
Para hacer una prueba, utilicé el conjunto de datos Iris y los 2 primeros discriminantes lineales tenían este aspecto:
IMG-1. LDA mediante scikit-learn
Esto es básicamente consistente con los resultados que encontré en el scikit-learn la documentación aquí.
Ahora, he revisado el LDA paso a paso y he obtenido una proyección diferente. Probé diferentes enfoques para averiguar qué estaba pasando:
IMG-2. LDA en datos brutos (sin centrado, sin normalización)
Y aquí estaría el paso a paso si estandarizara (normalización de la puntuación z; varianza unitaria) los datos primero. Hice lo mismo sólo con el centrado de la media, lo que debería conducir a la misma imagen de proyección relativa (y que de hecho lo hizo).
IMG-3. LDA paso a paso tras el centrado de la media, o estandarización
IMG-4. LDA en R (configuración por defecto)
LDA en IMG-3 donde centré los datos (que sería el enfoque preferido) también se ve exactamente igual que el que encontré en un Post de alguien que hizo el LDA en R
Código de referencia
No quería pegar todo el código aquí, pero lo he subido como un Cuaderno IPython aquí desglosado en los diversos pasos que utilicé (ver más abajo) para la proyección LDA.
-
Paso 1: Cálculo de los vectores medios d-dimensionales $$\mathbf m_i = \frac{1}{n_i} \sum\limits_{\mathbf x \in D_i}^n \; \mathbf x_k$$
-
Paso 2: Cálculo de las matrices de dispersión
2.1 La matriz de dispersión dentro de la clase $S_W$ se calcula mediante la siguiente ecuación:
$$S_W = \sum\limits_{i=1}^{c} S_i = \sum\limits_{i=1}^{c} \sum\limits_{\mathbf x \in D_i}^n (\mathbf x - \mathbf m_i)\;(\mathbf x - \mathbf m_i)^T$$2.2 La matriz de dispersión entre clases $S_B$ se calcula mediante la siguiente ecuación:
$$S_B = \sum\limits_{i=1}^{c} n_i (\mathbf m_i - \mathbf m) (\mathbf m_i - \mathbf m)^T$$ donde $\mathbf m$ es la media global. -
Paso 3. Resolver el problema de valores propios generalizado para la matriz $S_{W}^{-1}S_B$
3.1. Clasificación de los vectores propios por valores propios decrecientes
3.2. Elección de k vectores propios con los mayores valores propios. Combinando los dos vectores propios con los valores propios más altos para construir nuestro $d \times k$ -matriz eigenvectorial de dimensiones $\mathbf W$
-
Paso 5: Transformación de las muestras en el nuevo subespacio $$\mathbf y = \mathbf W^T \times \mathbf x.$$
0 votos
No he repasado para buscar las diferencias, pero puedes ver exactamente lo que hace scikit-learn en la fuente .
0 votos
Parece que también están estandarizando (centrando y luego escalando mediante la división por la desviación estándar). Esto, yo esperaría un resultado similar al de mi tercer gráfico (y el de R)...hmm
0 votos
Raro: el gráfico que has obtenido con scikit (y el que muestran en su documentación) no tiene sentido. El LDA siempre arroja proyecciones que tienen correlación cero, pero obviamente hay un muy fuerte correlación entre las proyecciones de scikit en los ejes discriminantes 1 y 2. Algo está claramente mal ahí.
0 votos
@ameoba Sí, yo también lo creo. Lo que también es raro es que la misma trama que muestro para scikit está en la documentación del ejemplo: scikit-learn.org/stable/auto_examples/decomposition/ Eso me hace pensar que mi uso de scikit es correcto, pero que hay algo impar en la función LDA
0 votos
@SebastianRaschka: Sí, me he dado cuenta. Es extraño, en efecto. Sin embargo, fíjate en que el primero de tus gráficos de LDA (no de Scikit) también muestra una correlación distinta de cero y, por lo tanto, algo debe estar mal en él también. ¿Has centrado los datos? La proyección en el segundo eje no parece tener media cero.
0 votos
Creo que es el efecto del escalado de los ejes en la primera foto. Si subes/bajas la foto para darle más altura, verás lo mismo que en las otras fotos. Eso espero. Es probable que scikit haga algún escalado (innecesario) de las puntuaciones del discriminante a los valores propios (que son muy diferentes para los dos discriminantes en tu caso).
0 votos
No soy usuario de R, pero creo que la única salida original y correcta de R entre las dos es la segunda (Pic No.3). Variables centradas o estandarizadas, no importa, el pic debería ser el mismo. Los discriminantes como variables están centrados y no correlacionados. La imagen 2 se parece a la imagen 3, a la que se han añadido constantes (niveles), diferentes para los distintos grupos.
0 votos
@ttnphns: ¡Pero seguramente ninguna cantidad de escala puede convertir la correlación cero en una correlación fuerte!
0 votos
@amoeba, las puntuaciones discriminantes no están correlacionadas sólo cuando se muestran correctamente, es decir, con la nube de datos centrada. La imagen 2 es extraña. ¿Hubo diferentes desplazamientos aplicados a las clases por el eje Y, o hubo algún tipo de rotación? No lo sé (y no me importaría mucho).
0 votos
@amoeba, realmente puede ser la rotación (más la adición de constand). Los resultados a veces se rotan en LDA. Acabo de hacer el análisis en SPSS con rotación varimax de los coeficientes; y el gráfico de las puntuaciones se parece bastante al del OP.
0 votos
Gracias por todos sus comentarios. He pensado que lo más fácil sería añadir títulos descriptivos a las imágenes donde todo el mundo pueda verlo. Esto también debería responder a la pregunta sobre la normalización y el centrado :). @ameoba Sería estupendo si pudieras añadir los resultados del SPSS como 5ª imagen a como editar a mi pregunta o como una respuesta separada. Creo que sería muy útil para esta discusión
0 votos
@SebastianRaschka, yo había mostrado los resultados del LDA de los datos del iris, obtenidos en SPSS, aquí: stats.stackexchange.com/a/83114/3277
0 votos
@SebastianRaschka, respecto a tu segunda cifra: No creo que tenga sentido proyectar los datos sin centrarlos primero. Los ejes del LDA se encuentran a través de las matrices de covarianza, y para calcularlas se restan las medias. Por lo tanto, también deberías restar las medias antes de proyectar los datos (aunque la estandarización es opcional, ese es otro tema). En su lugar, yo sustituiría la figura 2. En cuanto al análisis de scikit, deberíamos ponernos en contacto con los desarrolladores y preguntarles (o buscar en el código). Puede que lo haga más tarde. Estoy seguro de que es no sobre la rotación varimax, por cierto.
0 votos
@SebastianRaschka: Además, he encontrado tu pregunta en StackOverflow. El cross-posting es muy desanimado en la red StackExchange. Por favor, considera la posibilidad de eliminar una de tus preguntas o modificar una de ellas para que ya no sean casi idénticas. ¿Tal vez pueda dejar esta pregunta tal como está (es decir, sobre qué análisis es correcto) y redactar la de StackOverflow como un breve informe de error (que conste de los primeros párrafos, la figura 1 y un enlace aquí)? Es sólo una idea.
0 votos
Tenga en cuenta que también hay un problema de visualización en esta figura. Por tanto, la correlación dentro de la clase en los discriminantes lineales debería ser mínima. Y esta propiedad se cumple aunque parezca que los LD1 y LD2 están correlacionados para cada clase, ¡pero no lo están! Es sólo que el LD1 tiene un rango 5 veces mayor que el LD2, por lo que las distribuciones de clase no parecen esféricas.
0 votos
@VahidMir: No estoy seguro de entender lo que quieres decir. Si una distribución es esférica, después de escalarla puede parecer elíptica, pero no se estira en diagonal ¡! Ciertamente es una correlación entre LD1 y LD2 dentro de cada clase en la Figura 1.
0 votos
@ameoba: He cambiado el post en StackOverflow por completo ahora. Lo crucé inicialmente porque pensé que la audiencia podría ser muy diferente: estadísticos, gente de aprendizaje automático aquí, y más programadores en StackOverflow: No sabía que estaba desaconsejado y definitivamente me abstendré de hacer publicaciones cruzadas en el futuro.
0 votos
Para mayor comodidad: aquí está la discusión de StackOverlow .
0 votos
Como actualización en 2018 - todavía hay un error abierto con la implementación de Sklearn en el caso de más de 2 clases. github.com/scikit-learn/scikit-learn/issues/6848 Y no estoy obteniendo los resultados correctos para 3 clases en el conjunto de datos IRIS.