Quels algorithmes rapides existent pour calculer la SVD tronquée?

14

Peut-être hors sujet ici, mais il existe déjà plusieurs ( une , deux ) questions liées.

En fouillant dans la littérature (ou une recherche google pour les algorithmes SVD tronqués), on trouve beaucoup d'articles qui utilisent les SVD tronqués de diverses manières et prétendent (frustrant, souvent sans citation) qu'il existe des algorithmes rapides pour le calculer, mais personne semble indiquer quels sont ces algorithmes.

La seule chose que je puisse trouver est un seul algorithme randomisé , utilisé dans la bibliothèque redSVD .

Ce que j'aimerais voir, c'est un ensemble d'algorithmes exacts et inexacts, adaptés pour comprendre comment les systèmes fonctionnent (mais pas nécessairement pour les implémenter, bien sûr!).

Quelqu'un at-il une bonne référence pour ce genre de chose?

John Doucette
la source
Si je veux bien stocker les données, j'utilise un b-tree (ou rb-tree) dans le hachage (pensez à ram). Si j'avais un arbre b pour les données, je pourrais alors en O (log (n)) quantiles d'échantillons de temps et autres. Je parie qu'avec de grandes données, un tel échantillonnage pourrait être utilisé pour calculer une approximation clairsemée décente des matrices svd en peu de temps. Vous pouvez également rechercher la «détection compressée» qui est une approche très statistique de la compression de données extrême.
EngrStudent
Par SVD tronquée, vous voulez dire que vous n'êtes intéressé que par la recherche de plusieurs vecteurs / valeurs singuliers principaux, par opposition à tous?
amoeba dit Réintégrer Monica le
@amoeba Oui, c'est l'idée.
John Doucette

Réponses:

16

De façon très générale, il existe deux approches pour calculer les décompositions de valeurs propres ou de valeurs singulières. Une approche consiste à diagonaliser la matrice et cela donne essentiellement la décomposition entière des valeurs propres / valeurs singulières (l'ensemble du spectre des valeurs propres) en même temps, voir un aperçu ici: Quels sont les algorithmes efficaces pour calculer la décomposition des valeurs singulières (SVD)? L'alternative est d'utiliser un algorithme itératif qui produit un (ou plusieurs) vecteurs propres à la fois. Les itérations peuvent être arrêtées une fois que le nombre souhaité de vecteurs propres a été calculé.

n×mB(n+m)×(n+m)

A=(0BB0).
algorithm for truncated SVDiterative algorithm for eigendecomposition.

L'algorithme itératif le plus simple est appelé itération de puissance et est en effet très simple:

  1. x
  2. xAx
  3. xx/x
  4. Passez à l'étape # 2 sauf si vous avez convergé.

Tous les algorithmes les plus complexes sont finalement basés sur l'idée d'itération de puissance, mais deviennent assez sophistiqués. Les mathématiques nécessaires sont données par les sous-espaces de Krylov . Les algorithmes sont l' itération d'Arnoldi (pour les matrices non symétriques carrées), l' itération de Lanczos (pour les matrices symétriques carrées), et des variantes de celles-ci comme par exemple "la méthode Lanczos implicitement redémarrée" et ainsi de suite.

Vous pouvez trouver cela décrit par exemple dans les manuels suivants:

  1. Golub & Van Loan, calculs matriciels
  2. Trefethen & Bau, Algèbre linéaire numérique
  3. Demmel, Algèbre linéaire numérique appliquée
  4. Saad, Méthodes numériques pour les problèmes de grandes valeurs propres

Tous les langages de programmation et packages statistiques raisonnables (Matlab, R, Python numpy, vous l'appelez) utilisent les mêmes bibliothèques Fortran pour effectuer des décompositions de valeurs propres / singulières. Ce sont LAPACK et ARPACK . ARPACK signifie ARnoldi PACKage, et il s'agit d'itérations Arnoldi / Lanczos. Par exemple, dans Matlab, il existe deux fonctions pour SVD: svdeffectue une décomposition complète via LAPACK, et svdscalcule un nombre donné de vecteurs singuliers via ARPACK et il s'agit en fait juste d'un wrapper pour un eigsappel sur la matrice "carrée".

Mise à jour

BAABA

Il existe également une bibliothèque Fortran pour ces méthodes, elle s'appelle PROPACK :

Le progiciel PROPACK contient un ensemble de fonctions pour calculer la décomposition en valeurs singulières de matrices grandes et clairsemées ou structurées. Les routines SVD sont basées sur l'algorithme de bidiagonalisation de Lanczos avec réorthogonalisation partielle (BPRO).

Cependant, PROPACK semble être beaucoup moins standard qu'ARPACK et n'est pas nativement pris en charge dans les langages de programmation standard. Il est écrit par Rasmus Larsen qui a une grande bidiagonalisation de Lanczos de 1998 de 90 pages avec une réorthogonalisation partielle avec ce qui semble un bon aperçu. Merci à @MichaelGrant via ce fil Computational Science SE .

Parmi les articles les plus récents, le plus populaire semble être Baglama & Reichel, 2005, Augmented a implicitement redémarré les méthodes de bidiagonalisation de Lanczos , ce qui correspond probablement à l'état de l'art. Merci à @Dougal d'avoir donné ce lien dans les commentaires.

Update 2

Il existe en effet une approche entièrement différente décrite en détail dans le document de synthèse que vous avez cité vous-même: Halko et al. 2009, Finding structure with randomness: Algorithmes probabilistes pour la construction de décompositions matricielles approximatives . Je n'en sais pas assez pour commenter.

amibe dit réintégrer Monica
la source
Notez qu'il existe des méthodes d'itération spécifiques à SVD; par exemple , les méthodes de bidiagonalisation Lanczos augmentées implicitement redémarrées , J. Baglama et L. Reichel, SIAM J. Sci. Comput. 2005. (Je n'ai pas lu le document pour savoir si elle est fondamentalement différente de l'approche des valeurs propres que vous avez donnée, sachez simplement que les gens aiment cette méthode.)
Dougal
1
Merci pour le lien, @Dougal. Je dois dire que je ne connais pas vraiment bien ces méthodes, je ne peux donc pas vraiment commenter cela. Ce serait formidable si quelqu'un de plus compétent expliquait la relation entre les différentes méthodes itératives. Autant que je sache, la méthode Lancilla de vanille sert à calculer les valeurs propres d'une matrice carrée et non à SVD; "Lanczos augmenté implicitement redémarré" devrait y être étroitement lié, mais vous avez raison - il semble qu'il s'agisse directement de SVD. Je ne sais pas comment tout cela s'assemble. Je mettrai à jour ma réponse si jamais je regarde de plus près.
amibe dit Réintégrer Monica le
1
@Dougal, j'ai fait une lecture superficielle et fait une mise à jour.
amibe dit Réintégrer Monica le
@amoeba "SVD tronqué" dans le contexte des moindres carrés régularisés serait-il essentiellement le même que "régression des composants principaux" ?
GeoMatt22
1
@amoeba Pouvez-vous commenter la mise en œuvre SVD aléatoire de Facebook , certaines personnes semblent dire que c'est parmi les solutions les plus rapides possibles en ce moment. Ce serait génial si vous pouviez éditer pour commenter aussi à ce sujet.
Tim
4

Je suis juste tombé sur le fil via des SVD rapides sur Google, donc j'essaie de comprendre les choses moi-même, mais vous devriez peut-être vous pencher sur l' approximation croisée adaptative (ACA).

MM=i=0kUiViTN×NO(N)

Encore une fois, cela dépend de votre problème si cela fonctionne. Dans de nombreux cas que je rencontre personnellement, l'ACA est un outil numérique très utile.

Remarque: je voulais écrire ceci en tant que commentaire, mais parce que je viens de créer ce compte, je n'ai pas assez de réputation pour les commentaires ... Mais la publication fonctionne.

oli
la source
2

Voici une technique que j'ai utilisée avec succès dans le passé pour calculer un SVD tronqué (sur l'ensemble de données Netflix). Il est tiré de cet article . Dans un paramètre de filtrage collaboratif, je dois noter que la plupart des valeurs sont manquantes et le point est de les prédire , donc pour utiliser SVD tronqué pour résoudre un tel problème, vous devez utiliser une technique qui fonctionne dans cette condition. Une brève description:

  1. Avant de faire quoi que ce soit, ajustez un modèle simple (par exemple, moyenne globale + valeurs constantes de colonne et de ligne), et ce n'est qu'une fois que vous avez fait cela que vous devez passer à l'utilisation de SVD tronqué pour ajuster les résidus.
  2. Initialisez un vecteur aléatoire de longueur k (où c'est le rang auquel vous tronquez) à chaque ligne et colonne (à chaque film et utilisateur dans le cas Netflix).
  3. Maintenez les vecteurs de ligne fixes et mettez à jour les vecteurs de colonne pour minimiser l'erreur par rapport aux entrées connues dans la matrice. La procédure est donnée en code matlab dans le papier.
  4. Maintenez les vecteurs de colonne fixes et mettez à jour les vecteurs de ligne de manière analogue.
  5. Répétez les étapes 3 et 4 jusqu'à ce que vous convergiez ou obteniez de bons résultats.
Stumpy Joe Pete
la source