Een sparse matrix gebruiken versus numpy array
Het scipy
sparse matrix pakket, en soortgelijke in MATLAB, is gebaseerd op ideeën ontwikkeld vanuit lineaire algebra problemen, zoals het oplossen van grote sparse lineaire vergelijkingen (bijv. eindige verschillen en eindige elementen implementaties). Dus dingen zoals matrix product (het dot
product voor numpy arrays) en vergelijkingsoplossers zijn goed ontwikkeld.
Mijn ruwe ervaring is dat een sparse csr
matrix product een 1% sparsity moet hebben om sneller te zijn dan de equivalente dense dot
operatie – met andere woorden, één niet-nul waarde voor elke 99 nullen. (maar zie de tests hieronder)
Maar mensen proberen ook om sparse matrices te gebruiken om geheugen te besparen. Maar bedenk wel dat zo’n matrix 3 matrices met waarden moet opslaan (althans in het coo
formaat). Dus de sparsity moet minder dan 1/3 zijn om geheugen te besparen. Het is duidelijk dat je geen geheugen gaat besparen als je eerst de dichte matrix bouwt, en van daaruit de sparse maakt.
Het scipy
pakket implementeert vele sparse formaten. Het coo
formaat is het gemakkelijkst te begrijpen en te bouwen. Bouw er een volgens de documentatie en kijk naar de .data
, .row
, en .col
attributen (3 1d arrays).
csr
en csc
zijn typisch gebouwd vanuit het coo
formaat, en comprimeren de data een beetje, waardoor ze iets moeilijker te begrijpen zijn. Maar ze hebben de meeste wiskundige functionaliteit.
Het is ook mogelijk om het csr
formaat te indexeren, hoewel dit in het algemeen langzamer is dan het equivalente dichte matrix/array geval. Andere operaties zoals het veranderen van waarden (vooral van 0 naar niet-nul), aaneenschakeling, incrementele groei, zijn ook langzamer.
lil
(lijsten van lijsten) is ook gemakkelijk te begrijpen, en het beste voor incrementele opbouw. dok
is eigenlijk een subklasse van een woordenboek.
Een belangrijk punt is dat een sparse matrix beperkt is tot 2d, en zich in veel opzichten gedraagt als de klasse np.matrix
(hoewel het geen subklasse is).
Een zoekopdracht naar andere vragen met scikit-learn
en sparse
is misschien de beste manier om de voors en tegens van het gebruik van deze matrices te vinden. Ik heb een aantal vragen beantwoord, maar ik ken de ‘sparse’ kant beter dan de ‘learn’ kant. Ik denk dat ze nuttig zijn, maar ik krijg het gevoel dat de fit niet altijd de beste is. Alle aanpassingen zijn aan de learn
kant. Tot nu toe is het sparse
pakket niet geoptimaliseerd voor deze toepassing.
Ik heb zojuist wat matrix product tests geprobeerd, waarbij ik de sparse.random
methode heb gebruikt om een sparse matrix te maken met een gespecificeerde sparsity. Sparse matrixvermenigvuldiging presteerde beter dan ik had verwacht.
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
Het is een kwestie van grootte; voor kleinere matrices is de dichte dot
sneller
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
Maar vergelijk de indexering
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