Verwendung einer dünnbesetzten Matrix im Vergleich zu Numpy-Arrays

Jul 20, 2021
admin

Das scipy-Paket für dünnbesetzte Matrizen und ähnliche Pakete in MATLAB basieren auf Ideen, die aus Problemen der linearen Algebra entwickelt wurden, wie z.B. das Lösen großer dünnbesetzter linearer Gleichungen (z.B. Finite-Differenzen- und Finite-Elemente-Implementierungen). Daher sind Dinge wie das Matrixprodukt (das dot-Produkt für Numpy-Arrays) und Gleichungslöser gut entwickelt.

Meine grobe Erfahrung ist, dass ein dünnbesetztes csr-Matrixprodukt eine 1 %-ige Sparsamkeit aufweisen muss, um schneller zu sein als die entsprechende dichte dot-Operation – mit anderen Worten, ein Nicht-Null-Wert für jeweils 99 Nullen. (aber siehe Tests unten)

Aber man versucht auch, spärliche Matrizen zu verwenden, um Speicher zu sparen. Dabei ist jedoch zu bedenken, dass eine solche Matrix 3 Arrays von Werten speichern muss (zumindest im coo-Format). Die Sparsamkeit muss also weniger als 1/3 betragen, um Speicherplatz zu sparen. Natürlich spart man keinen Speicher, wenn man zuerst die dichte Matrix aufbaut und daraus die dünn besetzte Matrix erstellt.

Das Paket scipy implementiert viele dünn besetzte Formate. Das coo Format ist am einfachsten zu verstehen und zu erstellen. Erstelle es gemäß der Dokumentation und schaue dir seine .data, .row und .col Attribute an (3 1d Arrays).

csr und csc werden typischerweise aus dem coo Format erstellt und komprimieren die Daten ein wenig, was sie etwas schwieriger zu verstehen macht.

Es ist auch möglich, das csr-Format zu indizieren, obwohl dies im Allgemeinen langsamer ist als der entsprechende Fall einer dichten Matrix/Array. Andere Operationen wie das Ändern von Werten (insbesondere von 0 auf ungleich Null), Verkettung, inkrementelles Wachstum sind ebenfalls langsamer.

lil (Listen von Listen) ist ebenfalls leicht zu verstehen und eignet sich am besten für inkrementellen Aufbau. dok ist eigentlich eine Wörterbuch-Unterklasse.

Ein wichtiger Punkt ist, dass eine dünn besetzte Matrix auf 2d beschränkt ist und sich in vielerlei Hinsicht wie die Klasse np.matrix verhält (obwohl sie keine Unterklasse ist).

Eine Suche nach anderen Fragen, die scikit-learn und sparse verwenden, könnte der beste Weg sein, um die Vor- und Nachteile der Verwendung dieser Matrizen zu finden. Ich habe eine Reihe von Fragen beantwortet, aber ich kenne mich mit der „sparse“-Seite besser aus als mit der „learn“-Seite. Ich denke, dass sie nützlich sind, aber ich habe das Gefühl, dass die Passung nicht immer die beste ist. Jegliche Anpassung erfolgt auf der learn-Seite. Bisher wurde das sparse-Paket nicht für diese Anwendung optimiert.

Ich habe gerade einige Tests mit Matrixprodukten durchgeführt, wobei ich die sparse.random-Methode verwendet habe, um eine dünnbesetzte Matrix mit einer bestimmten Spärlichkeit zu erstellen. Die Multiplikation einer dünnbesetzten Matrix funktionierte besser als ich erwartet hatte.

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

Es ist ein Größenproblem; für kleinere Matrizen ist die dichte dot schneller

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

Vergleiche aber die Indexierung

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

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.