calcular la SVD truncada, un valor / vector singular a la vez

11

¿Existe un algoritmo SVD truncado que calcula los valores singulares uno a la vez?

Mi problema: me gustaría calcular los primeros k valores singulares (y vectores singulares) de una gran matriz densa M , pero no sé cuál sería un valor apropiado de k . M es grande, por lo que por razones de eficiencia, preferiría no evaluar la SVD completa solo para truncar las SV más pequeñas después.

Idealmente, habría una manera de calcular los valores singulares σ1,σ2, serie, de mayor ( σ1 ) a menor ( σn ). De esa manera, podría simplemente detener el cálculo después de calcular el k ésimo valor singular si σk/σ1 cae por debajo de cierto umbral.

¿Existe tal algoritmo (preferiblemente con una implementación de Python)? En mi búsqueda en Google, solo he encontrado funciones SVD truncadas que toman k como parámetro, lo que te obliga a adivinar a priori.

Súper eléctrico
fuente
¿Es tu M cuadrada o rectangular? Si es rectangular, ¿quieres los vectores singulares largos o cortos? Es decir, si M es (mxn) con m> n, ¿quiere (mxk) o (kxn)?
Max Hutchinson
M es rectangular, con muchas más filas que columnas. Quiero los vectores singulares cortos (es decir, V, en M = U S V ^ T).
SuperElectric

Respuestas:

6

Hay un par de opciones disponibles si desea una factorización aproximada de rango k.

  1. Factorizaciones QR fuertemente reveladoras de rango
  2. Descomposición interpolativa (ID) y otras técnicas aleatorias.

AMNTfactor×σk+1(A):=ϵ

Una factorización aproximada de la forma anterior se puede convertir en una descomposición estándar como QR o SVD utilizando técnicas estándar. Halko, Martinsson y Tropp pueden encontrar una buena revisión en el documento "Encontrar estructura con aleatoriedad: algoritmos probabilísticos para construir descomposiciones de matriz aproximadas"

En términos de software, una interfaz para algoritmos de ID está disponible en scipy (scipy.linalg.interpolative) http://docs.scipy.org/doc/scipy-dev/reference/linalg.interpolative.html que le permite al usuario especificar .ϵ

usuario2457602
fuente
2

(Editado, porque al principio leí mal la pregunta; ya sabes que hay rutinas disponibles para calcular los primeros valores singulares).k

Si excluye el enfoque de calcular toda la SVD, los algoritmos parciales de SVD se reducen al uso de métodos iterativos para resolver un problema relacionado con el valor propio de Hermit. Por lo tanto, una estrategia que podría tomar sería codificar manualmente este tipo de cosas usted mismo y seguir resolviendo el valor singular sin resolver más grande hasta que quiera detenerse, usando algo como una estrategia de cambio e inversión. Puede haber formas elegantes de hacer este tipo de cosas en paquetes sofisticados como SLEPc .

Otra estrategia sería la siguiente:

  • Calcule el valor singular más grande .s1
  • Establezca la tolerancia absoluta de la rutina SVD dispersa en , donde es su umbral, y es un factor de seguridad para determinar cuántos valores singulares posiblemente extraños desea calcular.τs1fτ0<f1
  • Llame a la escasa rutina SVD.

Si la escasa rutina SVD calcula una SVD delgada (y no puedo ver por qué no lo haría), entonces esta estrategia le brinda todos los valores singulares que desea (más posiblemente algunos adicionales), porque los valores por debajo de la tolerancia absoluta ser tratado como cero. En ese caso, puede usar scipy.sparse.linalg.svds , observando que es un parámetro opcional y que no tiene que especificarlo a priori .k

Geoff Oxberry
fuente
Si no especifica 'k' en scipy.sparse.linalg.svds, el valor predeterminado será k = 6, independientemente del parámetro 'tol'. No está claro si esto es un error, o si se supone que 'tol' se refiere a la precisión de los valores singulares calculados (en lugar de su tamaño)
Nick Alger