Używanie sparse matrix versus numpy array
Pakiet scipy
sparse matrix, i podobne w MATLAB, został oparty na pomysłach opracowanych z problemów algebry liniowej, takich jak rozwiązywanie dużych równań liniowych sparse (np. implementacje różnic skończonych i elementów skończonych). Tak więc rzeczy takie jak produkt macierzy (produkt dot
dla tablic numpy) i rozwiązywacze równań są dobrze rozwinięte.
Moje szorstkie doświadczenie jest takie, że sparse csr
produkt macierzy musi mieć 1% sparsity, aby być szybszym niż równoważna gęsta dot
operacja – innymi słowy, jedna niezerowa wartość na każde 99 zer. (ale zobacz testy poniżej)
Ale ludzie próbują również używać matryc sparse, aby zaoszczędzić pamięć. Ale pamiętaj, że taka macierz musi przechowywać 3 tablice wartości (przynajmniej w formacie coo
). Tak więc sparsity musi być mniejszy niż 1/3, aby zacząć oszczędzać pamięć. Oczywiście nie zaoszczędzisz pamięci, jeśli najpierw zbudujesz gęstą tablicę, a następnie utworzysz z niej sparse.
Pakiet scipy
implementuje wiele formatów sparse. Format coo
jest najłatwiejszy do zrozumienia i zbudowania. Zbuduj jeden zgodnie z dokumentacją i spójrz na jego atrybuty .data
, .row
i .col
(tablice 3 1d).
csr
i csc
są zwykle budowane z formatu coo
i nieco kompresują dane, co czyni je nieco trudniejszymi do zrozumienia. Ale mają większość funkcji matematycznych.
Możliwe jest również indeksowanie formatu csr
, chociaż ogólnie jest to wolniejsze niż równoważny przypadek gęstej macierzy/tablicy. Inne operacje, takie jak zmiana wartości (zwłaszcza od 0 do niezerowej), konkatenacja, przyrostowy wzrost, są również wolniejsze.
lil
(listy list) jest również łatwy do zrozumienia i najlepszy do budowania przyrostowego. dok
jest właściwie podklasą słownika.
Kluczowym punktem jest to, że macierz sparse jest ograniczona do 2d, i na wiele sposobów zachowuje się jak klasa np.matrix
(choć nie jest to podklasa).
Szukanie innych pytań przy użyciu scikit-learn
i sparse
może być najlepszym sposobem na znalezienie plusów / minusów używania tych macierzy. Odpowiedziałem na wiele pytań, ale znam stronę „sparse” lepiej niż stronę „learn”. Myślę, że są one przydatne, ale mam wrażenie, że dopasowanie nie zawsze jest najlepsze. Wszelkie dostosowywanie jest po stronie learn
. Do tej pory pakiet sparse
nie został zoptymalizowany pod kątem tego zastosowania.
Właśnie wypróbowałem kilka testów produktu macierzowego, używając metody sparse.random
do utworzenia nieliczbowej macierzy o określonej rozproszoności. Mnożenie macierzy sparse działało lepiej niż się spodziewałem.
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
Jest to kwestia rozmiaru; dla mniejszych macierzy gęsty dot
jest szybszy
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
Ale porównaj indeksowanie
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
.