Použití řídké matice versus numpy pole
Balík scipy
řídkých matic a podobné balíky v MATLABu byly založeny na myšlenkách vyvinutých z problémů lineární algebry, jako je řešení velkých řídkých lineárních rovnic (např. implementace konečných diferencí a konečných prvků). Takže věci jako maticový součin (součin dot
pro numpy pole) a řešiče rovnic jsou dobře vyvinuty.
Moje hrubá zkušenost je, že řídký maticový součin csr
musí mít 1% řídkost, aby byl rychlejší než ekvivalentní hustá operace dot
– jinými slovy, jedna nenulová hodnota na 99 nul. (ale viz testy níže)
Ale lidé se také snaží používat řídké matice, aby ušetřili paměť. Mějte však na paměti, že taková matice musí uchovávat 3 pole hodnot (alespoň ve formátu coo
). Takže řídkost musí být menší než 1/3, aby se začala šetřit paměť. Je zřejmé, že paměť neušetříte, pokud nejprve sestavíte hustou matici a z ní vytvoříte řídkou.
Balík scipy
implementuje mnoho řídkých formátů. Nejjednodušší na pochopení a sestavení je formát coo
. Sestavte ho podle dokumentace a podívejte se na jeho atributy .data
, .row
a .col
(3 1d pole).
csr
a csc
jsou obvykle sestaveny z formátu coo
a data trochu komprimují, takže jsou trochu hůře pochopitelné. Mají však většinu matematických funkcí.
Je také možné indexovat formát csr
, i když je to obecně pomalejší než ekvivalentní případ husté matice/ pole. Pomalejší jsou i další operace jako změna hodnot (zejména z 0 na nenulové), spojování, přírůstkový růst.
lil
(seznamy seznamů) je také snadno pochopitelný a pro přírůstkové sestavování nejlepší. dok
je vlastně podtřída slovníku.
Klíčové je, že řídká matice je omezena na 2d a v mnoha ohledech se chová jako třída np.matrix
(i když to není podtřída).
Pátrání po dalších otázkách s použitím scikit-learn
a sparse
může být nejlepší způsob, jak zjistit výhody/nevýhody použití těchto matic. Odpověděl jsem na řadu otázek, ale znám lépe stranu ‚řídkých‘ než stranu ‚učit se‘. Myslím, že jsou užitečné, ale mám pocit, že jejich fit není vždy nejlepší. Jakékoli přizpůsobení je na straně learn
. Balíček sparse
zatím nebyl pro tuto aplikaci optimalizován.
Zkoušel jsem právě nějaké testy součinu matic, kdy jsem pomocí metody sparse.random
vytvořil řídkou matici se zadanou řídkostí. Násobení řídkých matic fungovalo lépe, než jsem očekával.
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
Je to problém velikosti; pro menší matice je hustá dot
rychlejší
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 porovnejte indexování
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
.