Implementaciones eficientes en memoria de descomposiciones parciales de valores singulares (SVD)

10

Para la reducción del modelo, quiero calcular los vectores singulares izquierdos asociados a los - digamos 20 - valores singulares más grandes de una matriz , donde y . Desafortunadamente, mi matriz será densa sin ninguna estructura. N 10 6 k 10 3 AARN,kN106k103A

Si solo llamo a la svdrutina desde el numpy.linalgmódulo en Python para una matriz aleatoria de este tamaño, me encuentro con un error de memoria. Esto se debe a la asignación de para la descomposición . A = V S UVRN,NA=VSU

¿Existen algoritmos que eviten esta trampa? Por ejemplo, configurando solo los vectores singulares asociados con valores singulares distintos de cero.

Estoy listo para comerciar en tiempo de cálculo y precisión.

ene
fuente
1
Interesante, parece que Numpy no sabe cómo hacer una SVD delgada ...
JM
Gracias por la pista. De hecho, numpy.linalg.svd tiene la opción de full_matricesestablecerse en False para que solo se calculen las partes 'distintas de cero'. Sin embargo, ¿hay alguna manera de reducir el cálculo aún más?
Jan
3
El numpybackend usa código fortran, la LAPACKE_dgesvdrutina para svd estándar. Sin embargo, normalmente su matriz es C_CONTIGOUS(consulte con matrix.flags). Por lo tanto, copia los datos para una alineación fortran. Además, mientras se ejecuta la rutina dsvd de lapack, se necesita otra copia de su matriz (o al menos la memoria para ello). Puede deshacerse de una copia si se asegura de que la alineación de la memoria es para un estilo desde el principio.
Bort

Respuestas:

6

Si solo desea unos pocos valores / vectores singulares, ARPACK debería hacer el truco. Los documentos SVD no son geniales, y esta distribución está más actualizada.

EDITAR: Si quieres hacer esto en python, SciPy tiene un contenedor . Como su matriz es densa, puede probar el formato de fila dispersa de bloque (BSR).

Max Hutchinson
fuente
Voy a echar un vistazo, cómo ARPACK se integra con python ...
Jan
1
Parece que scipy tiene envoltorios. Los agregaré para responder al cuerpo.
Max Hutchinson
2

Eche un vistazo a sklearn.decomposition.TruncatedSVD en scikit-learn 0.14-rc.
(Creo que la gente de scikit-learn sigue stackoverflow.com/questions/tagged/scikit-learn , así que haría preguntas detalladas allí).

(¿Cuánta memoria tienes? 10 dobles ya es 8G.)6+3

denis
fuente
Gracias por tu respuesta. Por ahora, me va bien con las rutinas de scipy. Además, no he ido hasta todavía, pero a la mitad de lo que todavía es factible para mi computadora portátil. Si es necesario, puedo usar una máquina que funcione con 32 GB de RAM. 106×103
Jan
2

Quizás puedas probar esto.

https://github.com/jakevdp/pypropack

Este es un contenedor de Python para el paquete PROPACK, que implementa descomposiciones de valores singulares parciales eficientes de matrices dispersas grandes y operadores lineales.

Mass Zhou
fuente
2

Intel MKL implementa el nuevo algoritmo Jacobi-SVD. Aquí están los detalles de implementación: http://www.netlib.org/lapack/lawnspdf/lawn169.pdf http://www.fernuni-hagen.de/MATHPHYS/veselic/downloads/j02.pdf

Y la rutina LAPACK: http://software.intel.com/sites/products/documentation/hpc/mkl/mklman/GUID-732F9EE1-BCEC-4D9B-9B93-AF5499B21140.htm#DRMAC08-1

El tamaño del trabajo es, por supuesto, ajustable. Puede llamar a las funciones C desde Python fácilmente usando Cython, SWIG o cualquier otro mecanismo de ajuste.

Tolga Birdal
fuente