J'ai déjà posé cette question à StackOverflow, mais il semble que cela conviendrait mieux ici, étant donné que cela n'a pas donné de réponse à SO. C'est un peu à la croisée des statistiques et de la programmation.
J'ai besoin d'écrire du code pour faire PCA (analyse en composantes principales). J'ai parcouru les algorithmes bien connus et mis en œuvre celui-ci , qui pour autant que je sache est équivalent à l'algorithme NIPALS. Cela fonctionne bien pour trouver les 2-3 premières composantes principales, mais semble ensuite devenir très lent à converger (de l'ordre de centaines à des milliers d'itérations). Voici les détails de ce dont j'ai besoin:
L'algorithme doit être efficace pour traiter un grand nombre de caractéristiques (ordre de 10 000 à 20 000) et des tailles d'échantillon de l'ordre de quelques centaines.
Il doit être raisonnablement implémentable sans une bibliothèque matricielle d'algèbre linéaire, car le langage cible est D, qui n'en a pas encore, et même s'il en possédait un, je préférerais ne pas l'ajouter comme dépendance du projet en question. .
En passant, sur le même jeu de données, R semble trouver toutes les composantes principales très rapidement, mais il utilise une décomposition en valeurs singulières, ce que je ne veux pas coder moi-même.
Réponses:
J'ai mis en œuvre la SVD randomisée comme indiqué dans "Halko, N., PG Martinsson, Y Shkolnisky, et M. Tygert (2010). Un algorithme pour l'analyse en composantes principales de grands ensembles de données. Arxiv preprint arXiv: 1007.5510, 0526. Extrait le 1 er avril 2011 de http://arxiv.org/abs/1007.5510 . ". Si vous voulez obtenir des fichiers SVD tronqués, cela fonctionne vraiment beaucoup plus rapidement que les variations de DVD dans MATLAB. Vous pouvez l'obtenir ici:
Pour le tester, créez simplement une image dans le même dossier (juste comme une grande matrice, vous pouvez créer la matrice vous-même)
Lorsque je l'exécute sur mon bureau pour une image de taille 635 * 483, je reçois
Comme vous pouvez le constater, pour les faibles valeurs de
k
, il est plus de 10 fois plus rapide que l’utilisation de Matlab SVD. En passant, vous aurez peut-être besoin de la fonction simple suivante pour la fonction de test:Je n'ai pas ajouté la méthode PCA car il est facile de l'implémenter avec SVD. Vous pouvez vérifier ce lien pour voir leur relation.
la source
vous pouvez essayer d'utiliser plusieurs options.
1- Décomposition de la matrice pénalisée . Vous appliquez des contraintes de pénalité sur les u et v pour obtenir un peu de parcimonie. Algorithme rapide utilisé pour les données génomiques
Voir Whitten Tibshirani. Ils ont aussi un R-pkg. "Une décomposition matricielle pénalisée, avec des applications pour les composantes principales éparses et l'analyse de corrélation canonique."
2- SVD randomisée . Comme la SVD est un algorithme maître, il peut être souhaitable de disposer d’une approximation très rapide, en particulier pour une analyse exploratoire. À l’aide de la SVD randomisée, vous pouvez effectuer une PCA sur d’énormes jeux de données.
Voir Martinsson, Rokhlin et Tygert "Un algorithme randomisé pour la décomposition de matrices". Tygert a un code pour une implémentation très rapide de la PCA.
Vous trouverez ci-dessous une implémentation simple de SVD randomisée dans R.
la source
Il semble que vous souhaitiez peut-être utiliser l’ algorithme Lanczos . Sinon, vous voudrez peut-être consulter Golub & Van Loan. Une fois, j'ai codé un algorithme SVD (en SML, dans toutes les langues) à partir de leur texte, et cela a fonctionné assez bien.
la source
Je suggérerais d'essayer la PCA du noyau dont la complexité spatio-temporelle dépend du nombre d'exemples (N) plutôt que du nombre de fonctionnalités (P), ce qui, à mon avis, conviendrait mieux dans votre contexte (P >> N)). Le noyau PCA fonctionne essentiellement avec la matrice de noyau NxN (matrice de similitudes entre les points de données), plutôt que la matrice de covariance PxP, qui peut être difficile à gérer pour les grands P. Un autre avantage de la PCA noyau est qu'il peut apprendre des projections non linéaires. ainsi si vous l'utilisez avec un noyau approprié. Voir cet article sur la PCA du noyau .
la source
Il me semble rappeler qu'il est possible d'effectuer une ACP en calculant la décomposition propre de X ^ TX plutôt que de XX ^ T, puis de la transformer pour obtenir les PC. Cependant, je ne me souviens pas des détails, mais c'est dans le livre (excellent) de Jolliffe et je le vérifierai quand je serai au travail. Je translittérerais les routines d'algèbre linéaire de Numericical Methods in C, par exemple, plutôt que d'utiliser un autre algorithme.
la source
Il existe également la méthode bootstrap de Fisher et al , conçue pour plusieurs centaines d’échantillons de grande dimension.
L'idée principale de la méthode est formulée comme suit: "le rééchantillonnage est une transformation de faible dimension". Ainsi, si vous avez un petit nombre (plusieurs centaines) d'échantillons de grande dimension, vous ne pouvez pas obtenir plus de composants principaux que le nombre d'échantillons. Il est donc logique de considérer les échantillons comme une base parcimonieuse, de projeter les données sur le sous-espace linéaire couvert par ces vecteurs et de calculer la PCA dans ce sous-espace plus petit. Ils fournissent également plus de détails sur la manière de traiter le cas lorsque tous les échantillons ne peuvent pas être stockés dans la mémoire.
la source
Voir l'article de Sam Roweis, EM Algorithms for PCA et SPCA .
la source