Scipy sparse … arrays?

Por lo tanto, estoy haciendo una clasificación de Kmeans utilizando matrices numpy que son bastante escasas: muchos y muchos ceros. Pensé que usaría el paquete ‘disperso’ de scipy para reducir la sobrecarga de almacenamiento, pero estoy un poco confundido acerca de cómo crear matrices, no matrices.

He seguido este tutorial sobre cómo crear matrices dispersas: http://www.scipy.org/SciPy_Tutorial#head-c60163f2fd2bab79edd94be43682414f18b90df7

Para imitar una matriz, solo creo una matriz 1xN, pero como puede adivinar, Asp.dot (Bsp) no funciona del todo porque no puede multiplicar dos matrices 1xN. Tendría que transponer cada matriz a Nx1, y eso es bastante escaso, ya que lo estaría haciendo para cada cálculo de punto-producto.

A continuación, intenté crear una matriz NxN donde la columna 1 == fila 1 (de modo que puede multiplicar dos matrices y tomar la esquina superior izquierda como el producto de puntos), pero resultó ser realmente ineficiente.

Me encantaría usar el paquete disperso de scipy como un sustituto mágico de la matriz de numpy (), pero aún no estoy seguro de qué hacer.

¿Algún consejo?

Use un formato scipy.sparse que esté basado en filas o columnas: csc_matrix y csr_matrix .

Éstas utilizan implementaciones eficientes de C bajo el capó (incluida la multiplicación), y la transposición es un no-op (especialmente si se llama transpose(copy=False) ), al igual que con matrices numpy.

EDITAR: algunos tiempos a través de ipython :

 import numpy, scipy.sparse n = 100000 x = (numpy.random.rand(n) * 2).astype(int).astype(float) # 50% sparse vector x_csr = scipy.sparse.csr_matrix(x) x_dok = scipy.sparse.dok_matrix(x.reshape(x_csr.shape)) 

Ahora x_csr y x_dok son 50% dispersos:

 print repr(x_csr) <1x100000 sparse matrix of type '' with 49757 stored elements in Compressed Sparse Row format> 

Y los tiempos:

 timeit numpy.dot(x, x) 10000 loops, best of 3: 123 us per loop timeit x_dok * x_dok.T 1 loops, best of 3: 1.73 s per loop timeit x_csr.multiply(x_csr).sum() 1000 loops, best of 3: 1.64 ms per loop timeit x_csr * x_csr.T 100 loops, best of 3: 3.62 ms per loop 

Así que parece que dije una mentira. La transposición es muy barata, pero no hay una implementación eficiente en C de csr * csc (en el último scipy 0.9.0). Se construye un nuevo objeto csr en cada llamada 🙁

Como hack (aunque scipy es relativamente estable en estos días), puedes hacer el producto punto directamente en los datos dispersos:

 timeit numpy.dot(x_csr.data, x_csr.data) 10000 loops, best of 3: 62.9 us per loop 

Tenga en cuenta que este último enfoque hace una multiplicación densa numpy otra vez. La dispersión es del 50%, por lo que es más rápido que el dot(x, x) en un factor de 2.

Podría crear una subclase de una de las matrices dispersas 2d existentes

 from scipy.sparse import dok_matrix class sparse1d(dok_matrix): def __init__(self, v): dok_matrix.__init__(self, (v,)) def dot(self, other): return dok_matrix.dot(self, other.transpose())[0,0] a=sparse1d((1,2,3)) b=sparse1d((4,5,6)) print a.dot(b) 

No estoy seguro de que sea mucho mejor o más rápido, pero podría hacer esto para evitar el uso de la transposición:

 Asp.multiply(Bsp).sum() 

Esto solo toma el producto elemento por elemento de las dos matrices y sum los productos. Podría hacer una subclase de cualquier formato de matriz que esté utilizando que tenga la statement anterior como el producto de puntos.

Sin embargo, es probable que sea más fácil trasladarlos:

 Asp*Bsp.T 

No parece mucho hacer, pero también podría crear una subclase y modificar el método mul ().