J'utilisais l'analyse linéaire discriminante (LDA) de la scikit-learn
bibliothèque d'apprentissage automatique (Python) pour réduire la dimensionnalité et j'étais un peu curieux des résultats. Je me demande maintenant ce que fait la LDA scikit-learn
pour que les résultats soient différents, par exemple, d'une approche manuelle ou d'une LDA effectuée en R. Ce serait formidable si quelqu'un pouvait me donner quelques informations ici.
Ce qui est fondamentalement le plus préoccupant, c'est que le scikit-plot
montre une corrélation entre les deux variables où il devrait y avoir une corrélation 0.
Pour un test, j'ai utilisé l'ensemble de données Iris et les 2 premiers discriminants linéaires ressemblaient à ceci:
IMG-1. LDA via scikit-learn
Ceci est fondamentalement cohérent avec les résultats que j'ai trouvés dans la documentation scikit-learn ici.
Maintenant, j'ai parcouru la LDA étape par étape et j'ai obtenu une projection différente. J'ai essayé différentes approches afin de savoir ce qui se passait:
IMG-2. LDA sur données brutes (pas de centrage, pas de standardisation)
Et voici l'approche étape par étape si je standardisais (normalisation du score z; variance unitaire) les données en premier. J'ai fait la même chose avec le centrage moyen uniquement, ce qui devrait conduire à la même image de projection relative (et c'est effectivement le cas).
IMG-3. LDA étape par étape après centrage moyen ou standardisation
IMG-4. LDA dans R (paramètres par défaut)
LDA dans IMG-3 où j'ai centré les données (ce qui serait l'approche préférée) ressemble également exactement à celle que j'ai trouvée dans un message par quelqu'un qui a fait le LDA dans R
Code de référence
Je ne voulais pas coller tout le code ici, mais je l'ai téléchargé en tant que bloc-notes IPython ici divisé en plusieurs étapes que j'ai utilisées (voir ci-dessous) pour la projection LDA.
- Étape 1: calcul des vecteurs moyens à dimensions d
Étape 2: Calcul des matrices de dispersion
2.1 La matrice de dispersion intra-classe est calculée par l'équation suivante:
2.2 La matrice de dispersion entre classes est calculée par l'équation suivante: où est la moyenne globale.
Étape 3. Résolution du problème des valeurs propres généralisées pour la matrice
3.1. Tri des vecteurs propres en diminuant les valeurs propres
3.2. Choisir k vecteurs propres avec les plus grandes valeurs propres. Combiner les deux vecteurs propres avec les valeurs propres les plus élevées pour construire notre matrice de vecteurs propres
Étape 5: Transformer les échantillons dans le nouveau sous-espace
la source
Réponses:
Mise à jour: Grâce à cette discussion, a
scikit-learn
été mis à jour et fonctionne correctement maintenant. Son code source LDA peut être trouvé ici . Le problème d'origine était dû à un bug mineur (voir cette discussion github ) et ma réponse ne le pointait pas correctement (excuses pour toute confusion causée). Comme tout cela n'a plus d'importance (bug corrigé), j'ai modifié ma réponse pour me concentrer sur la façon dont LDA peut être résolu via SVD, qui est l'algorithme par défaut dansscikit-learn
.Après avoir défini les matrices de dispersion et -classes et , le calcul LDA standard, comme indiqué dans votre question, consiste à prendre des vecteurs propres de comme axes discriminants ( voir par exemple ici ). Cependant, les mêmes axes peuvent être calculés de manière légèrement différente, en exploitant une matrice de blanchiment:ΣW ΣB Σ−1WΣB
Calculez . Il s'agit d' une transformation blanchissante par rapport à la covariance regroupée au sein de la classe (voir ma réponse liée pour plus de détails).Σ−1/2W
Notez que si vous avez une décomposition propre , alors . Notez également que l'on calcule la même chose en faisant SVD des données regroupées au sein de la classe: .ΣW=USU⊤ Σ−1/2W=US−1/2U⊤ XW=ULV⊤⇒Σ−1/2W=UL−1U⊤
Trouvez les vecteurs propres de , appelons-les .Σ−1/2WΣBΣ−1/2W A∗
Encore une fois, notez que l'on peut le calculer en faisant SVD des données entre classes , transformées avec , c'est-à-dire des données entre classes blanchies par rapport à l'intérieur de la classe covariance.XB Σ−1/2W
Les axes discriminants seront donnés par , c'est-à-dire par les axes principaux des données transformées , transformées à nouveau .A Σ−1/2WA∗
En effet, si est un vecteur propre de la matrice ci-dessus, alors et en multipliant à partir de la gauche par et en définissant , nous obtenons immédiatement :a∗
En résumé, LDA équivaut à blanchir la matrice des moyennes de classe par rapport à la covariance intra-classe, à effectuer l'ACP sur les moyennes de classe et à retransformer les axes principaux résultants en l'espace d'origine (non blanchi).
Ceci est souligné par exemple dans Les éléments de l'apprentissage statistique , section 4.3.3. C'est
scikit-learn
la façon par défaut de calculer LDA car la SVD d'une matrice de données est numériquement plus stable que la décomposition propre de sa matrice de covariance.Notez que l'on peut utiliser n'importe quelle transformation de blanchiment au lieu de et tout fonctionnera toujours exactement de la même manière. Dans est utilisé (au lieu de ), et cela fonctionne très bien (contrairement à ce qui était écrit à l'origine dans ma réponse).Σ−1/2W L−1U⊤ UL−1U⊤
scikit-learn
la source
Juste pour fermer cette question, le problème discuté avec le LDA a été corrigé dans scikit-learn 0.15.2 .
la source