Användning av en sparsam matris jämfört med numpy array

jul 20, 2021
admin

Paketet scipysparsam matris, och liknande paket i MATLAB, baserades på idéer som utvecklades från problem med linjär algebra, t.ex. att lösa stora sparsamma linjära ekvationer (t.ex. finita differens- och finita element-implementationer). Så saker som matrisprodukt (dot-produkten för numpy-matriser) och ekvationslösare är välutvecklade.

Min grova erfarenhet är att en sparsam csr-matrisprodukt måste ha en sparsamhet på 1 % för att vara snabbare än den motsvarande täta dot-operationen – med andra ord, ett värde som inte är noll för varje 99 nollor. (men se tester nedan)

Men folk försöker också använda glesa matriser för att spara minne. Men kom ihåg att en sådan matris måste lagra 3 matriser med värden (åtminstone i coo-formatet). Så sparsamheten måste vara mindre än 1/3 för att börja spara minne. Det är uppenbart att du inte kommer att spara minne om du först bygger den täta matrisen och skapar den glesa matrisen utifrån den.

Paketet scipy implementerar många glesa format. Formatet coo är lättast att förstå och bygga. Bygg ett enligt dokumentationen och titta på dess attribut .data, .row och .col (3 1d matriser).

csr och csc byggs vanligtvis från coo-formatet och komprimerar data lite, vilket gör dem lite svårare att förstå. Men de har de flesta matematiska funktionerna.

Det är också möjligt att indexera csr-formatet, även om detta i allmänhet är långsammare än det motsvarande fallet med täta matriser/arrayer. Andra operationer som att ändra värden (särskilt från 0 till icke-noll), concatenation, inkrementell tillväxt, är också långsammare.

lil (listor av listor) är också lätt att förstå, och bäst för inkrementell uppbyggnad. dok är faktiskt en underklass för ordböcker.

En viktig punkt är att en sparse matrix är begränsad till 2d, och på många sätt beter sig som klassen np.matrix (även om det inte är en underklass).

En sökning på andra frågor som använder scikit-learn och sparse kan vara det bästa sättet att hitta för- och nackdelar med att använda dessa matriser. Jag har svarat på ett antal frågor, men jag känner till ”sparse”-sidan bättre än ”learn”-sidan. Jag tror att de är användbara, men jag får känslan är att anpassningen inte alltid är den bästa. Alla anpassningar sker på learn-sidan. Hittills har sparse-paketet inte optimerats för denna tillämpning.

Jag provade just några tester av matrisprodukter med hjälp av sparse.random-metoden för att skapa en sparsam matris med en angiven sparsamhet. Sparsam matrismultiplikation fungerade bättre än vad jag förväntade mig.

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 är en storleksfråga; för mindre matriser är den täta dot snabbare

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 jämför 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

.

Lämna ett svar

Din e-postadress kommer inte publiceras.