Utilisation d’une matrice clairsemée par rapport à un tableau numpy

Juil 20, 2021
admin

Le paquet de matrice clairsemée scipy, et les similaires dans MATLAB, a été basé sur des idées développées à partir de problèmes d’algèbre linéaire, tels que la résolution de grandes équations linéaires clairsemées (par exemple, les implémentations de différences finies et d’éléments finis). Ainsi, des choses comme le produit matriciel (le produit dot pour les tableaux numpy) et les solveurs d’équation sont bien développés.

Mon expérience approximative est qu’un produit matriciel csr clairsemé doit avoir une sparsité de 1% pour être plus rapide que l’opération dot dense équivalente – en d’autres termes, une valeur non nulle pour 99 zéros. (mais voir les tests ci-dessous)

Mais les gens essaient aussi d’utiliser des matrices éparses pour économiser de la mémoire. Mais gardez à l’esprit qu’une telle matrice doit stocker 3 tableaux de valeurs (au moins dans le format coo). Ainsi, la sparsité doit être inférieure à 1/3 pour commencer à économiser de la mémoire. Évidemment, vous n’allez pas économiser de la mémoire si vous construisez d’abord le tableau dense, et créez le tableau clairsemé à partir de celui-ci.

Le paquet scipy implémente de nombreux formats clairsemés. Le format coo est le plus facile à comprendre et à construire. Construisez-en un selon la documentation et regardez ses attributs .data, .row et .col (3 tableaux 1d).

csr et csc sont généralement construits à partir du format coo, et compressent un peu les données, ce qui les rend un peu plus difficiles à comprendre. Mais ils ont la plupart des fonctionnalités mathématiques.

Il est également possible d’indexer le format csr, bien qu’en général cela soit plus lent que le cas équivalent de matrice/rayon dense. D’autres opérations comme le changement de valeurs (notamment de 0 à non zéro), la concaténation, la croissance incrémentale, sont également plus lentes.

lil (listes de listes) est également facile à comprendre, et le meilleur pour la construction incrémentale. dok est en fait une sous-classe de dictionnaire.

Un point clé est qu’une matrice clairsemée est limitée à 2d, et à bien des égards se comporte comme la classe np.matrix (bien que ce ne soit pas une sous-classe).

Une recherche d’autres questions utilisant scikit-learn et sparse pourrait être le meilleur moyen de trouver les pour/contre de l’utilisation de ces matrices. J’ai répondu à un certain nombre de questions, mais je connais mieux le côté ‘sparse’ que le côté ‘learn’. Je pense qu’elles sont utiles, mais j’ai l’impression que l’ajustement n’est pas toujours le meilleur. Toute personnalisation est du côté de learn. Jusqu’à présent, le paquet sparse n’a pas été optimisé pour cette application.

Je viens d’essayer quelques tests de produits matriciels, en utilisant la méthode sparse.random pour créer une matrice éparse avec une sparsité spécifiée. La multiplication de matrices éparses s’est mieux comportée que ce à quoi je m’attendais.

In : M=sparse.random(1000,1000,.5)In : timeit M1=M*M1 loops, best of 3: 2.78 s per loopIn : timeit Ma=M.toarray(); M2=Ma.dot(Ma)1 loops, best of 3: 4.28 s per loop

C’est un problème de taille ; pour les petites matrices, la dot dense est plus rapide

In : M=sparse.random(100,100,.5)In : timeit M1=M*M100 loops, best of 3: 3.24 ms per loopIn : timeit Ma=M.toarray(); M2=Ma.dot(Ma)1000 loops, best of 3: 1.44 ms per loop

Mais comparez l’indexation

In : timeit M.tocsr()10 loops, best of 3: 86.4 ms per loopIn : timeit Ma1000000 loops, best of 3: 318 ns per loopIn : timeit Ma=M.toarray();Ma10 loops, best of 3: 23.6 ms per loop

.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.