Brug af en sparsom matrix versus numpy array

jul 20, 2021
admin

Den sparsomme matrixpakke scipy, og lignende pakker i MATLAB, var baseret på ideer udviklet fra problemer med lineær algebra, såsom løsning af store sparsomme lineære ligninger (f.eks. finite difference- og finite element-implementeringer). Så ting som matrixprodukt (dot-produktet for numpy-arrays) og ligningsløsere er veludviklede.

Min grove erfaring er, at et sparsomt csr-matrixprodukt skal have en sparsomhed på 1% for at være hurtigere end den tilsvarende tætte dot-operation – med andre ord, én ikke-nul-værdi for hver 99 nuller. (men se test nedenfor)

Men folk forsøger også at bruge sparsomme matricer for at spare hukommelse. Men husk på, at en sådan matrix skal gemme 3 arrays af værdier (i hvert fald i coo-formatet). Så sparsomheden skal være mindre end 1/3 for at begynde at spare hukommelse. Det er klart, at du ikke kommer til at spare hukommelse, hvis du først opbygger det tætte array og opretter det sparsomme array ud fra det.

scipy-pakken implementerer mange sparsomme formater. coo-formatet er nemmest at forstå og opbygge. Opbyg et i henhold til dokumentationen, og se på dets .data, .row og .col-attributter (3 1d arrays).

csr og csc er typisk bygget ud fra coo-formatet og komprimerer dataene en smule, hvilket gør dem lidt sværere at forstå. Men de har de fleste af de matematiske funktioner.

Det er også muligt at indeksere csr-formatet, selv om det generelt er langsommere end det tilsvarende tætte matrix/array-tilfælde. Andre operationer som ændring af værdier (især fra 0 til ikke-nul), sammenkædning, inkrementel vækst er også langsommere.

lil (lister af lister) er også let at forstå og er bedst til inkrementel opbygning. dok er en faktisk en underklasse til ordbøger.

En vigtig pointe er, at en sparsom matrix er begrænset til 2d, og på mange måder opfører den sig som np.matrix-klassen (selv om det ikke er en underklasse).

En søgning efter andre spørgsmål med scikit-learn og sparse er måske den bedste måde at finde fordele/ulemper ved at bruge disse matricer på. Jeg har besvaret en række spørgsmål, men jeg kender “sparse”-siden bedre end “learn”-siden. Jeg tror, at de er nyttige, men jeg får fornemmelsen er, at pasformen ikke altid er den bedste. Enhver tilpasning er på learn-siden. Indtil videre er sparse-pakken ikke blevet optimeret til denne anvendelse.

Jeg har lige prøvet nogle matrixprodukt-tests, hvor jeg brugte sparse.random-metoden til at oprette en sparsom matrix med en specificeret sparsomhed. Sparse matrixmultiplikation klarede sig bedre end jeg havde forventet.

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

Det er et størrelsesproblem; for mindre matrix er den tætte dot hurtigere

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

Men sammenlign indeksering

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

Skriv et svar

Din e-mailadresse vil ikke blive publiceret.