Ir al contenido

IDEAS PRÁCTICAS · ASIMOV INGENIERÍA

Algoritmo de Descomposición SVD: Teoría, Implementación y Ejemplos en Python

Guía completa sobre la descomposición en valores singulares (SVD), su fundamento matemático, aplicaciones prácticas y ejemplos detallados en Python con NumPy y SciPy.

Imagen ilustrativa · Brecht Corbeel / Unsplash.

Table of contents

No titles in the blog post

Introducción

La descomposición en valores singulares (Singular Value Decomposition, SVD) es una herramienta fundamental en álgebra lineal que permite factorizar cualquier matriz real o compleja \(A\) en el producto de tres matrices:

Computadora portátil encendida en un escritorio
Imagen ilustrativa · AltumCode / Unsplash.

A = U Σ VT

Donde:

  • U – matriz ortogonal de dimensiones \(m \times m\) cuyas columnas son los vectores singulares izquierdos.
  • Σ – matriz diagonal \(m \times n\) con los valores singulares (no negativos) ordenados de mayor a menor.
  • V – matriz ortogonal de dimensiones \(n \times n\) cuyas columnas son los vectores singulares derechos (transpuesta en la fórmula).

Esta factorización es única (exceptuando signos) y sirve como base para PCA, compresión de imágenes, recomendación de sistemas, filtrado de ruido y más.

Fundamento matemático

El cálculo de la SVD se basa en la relación entre la matriz original y sus matrices de covarianza:

  • \(A^T A = V Σ^2 V^T\) – los valores singulares al cuadrado son los eigenvalores de \(A^T A\).
  • \(A A^T = U Σ^2 U^T\) – los mismos valores singulares aparecen en la descomposición de \(A A^T\).

Por tanto, la SVD puede obtenerse mediante dos eigen‑decompositions, aunque los algoritmos modernos (Lanczos bidiagonalization, QR) son mucho más estables y eficientes para matrices grandes.

Aplicaciones típicas

  • Reducción de dimensionalidad (PCA y Truncated SVD).
  • Compresión de imágenes: representación de una imagen mediante los k valores singulares más importantes.
  • Sistemas de recomendación: factorizar la matriz de usuarios‑items.
  • Resolución de sistemas lineales mal condicionados mediante pseudo‑inversa.

Implementación en Python

Python ofrece varias librerías para calcular la SVD de forma eficiente:

  • numpy.linalg.svd – interfaz simple, utiliza LAPACK bajo el capó.
  • scipy.linalg.svd – permite especificar modos de cálculo (full, reduced, econ).
  • scipy.sparse.linalg.svds – algoritmo de Lanczos para matrices dispersas y truncated SVD.

A continuación, un ejemplo paso a paso con numpy:

import numpy as np

# Matriz de ejemplo (4x3)
A = np.array([[1, 0, 0],
              [0, 2, 0],
              [0, 0, 3],
              [0, 0, 0]], dtype=float)

# Descomposición completa
U, s, VT = np.linalg.svd(A, full_matrices=True)

# Convertir el vector de valores singulares a matriz diagonal
Sigma = np.zeros((U.shape[1], VT.shape[0]))
np.fill_diagonal(Sigma, s)

# Reconstrucción para validar
A_rec = U @ Sigma @ VT
print('A reconstruida:\n', np.round(A_rec, 6))

Salida esperada:

A reconstruida:
 [[1. 0. 0.]
 [0. 2. 0.]
 [0. 0. 3.]
 [0. 0. 0.]]

Comparativa: SVD vs Eigen‑decomposition vs PCA

SVD
  • Aplica a cualquier matriz (no necesita ser cuadrada).
  • Siempre devuelve valores singulares no negativos y ortogonales.
  • Mayor estabilidad numérica para matrices mal condicionadas.
  • Computacionalmente costosa O(min(mn², m²n)).
Eigen‑decomposition
  • Requiere matrices cuadradas y, preferiblemente, simétricas.
  • Los eigenvalores pueden ser negativos o complejos.
  • Más rápida O(n³) para matrices pequeñas, pero inestable en casos no simétricos.
  • Base para SVD a través de AᵀA o AAᵀ.
PCA (basada en SVD)
  • Utiliza la SVD de la matriz centrada para obtener componentes principales.
  • Escala bien a datos de alta dimensión cuando se usa truncated SVD.
  • Requiere pre‑procesamiento (centrado, a veces escalado).
Truncated SVD (Sparse PCA)
  • Calcula solo los k mayores valores singulares.
  • Ideal para matrices dispersas (texto, recomendación).
  • Complejidad O(k·nnz) donde nnz es el número de elementos no cero.

Rendimiento y escalabilidad

Para matrices muy grandes (≥10⁶ × 10⁶) la SVD completa es inviable. Las estrategias habituales son:

  • Truncated SVD con scipy.sparse.linalg.svds (algoritmo Lanczos).
  • Uso de randomized SVD (sklearn.utils.extmath.randomized_svd) que reduce la complejidad a O(mn log k).
  • Distribución del cálculo con Dask o Spark MLlib para entornos de cluster.

Ejemplo de SVD aleatorizado:

from sklearn.utils.extmath import randomized_svd
U, s, VT = randomized_svd(A, n_components=5, n_iter=5, random_state=42)

Este método es particularmente útil en procesamiento de lenguaje natural (TF‑IDF) y análisis de redes.

Buenas prácticas y consideraciones de seguridad

  • Tipo de dato: use float64 para precisión numérica; evite float32 cuando los valores singulares varíen en varios órdenes de magnitud.
  • Normalización: escale la matriz (por ejemplo, dividir por su norma) para evitar overflow en matrices muy grandes.
  • Gestión de memoria: al trabajar con matrices dispersas, convierta a formato csr_matrix antes de llamar a svds para minimizar la huella de memoria.
  • Seguridad: nunca cargue datos sin validar su origen; la SVD puede exponer patrones sensibles (por ejemplo, en datos de pacientes) si los valores singulares se comparten sin anonimizar.

Solución de problemas comunes

ProblemaCausaSolución recomendada
Convergencia lenta en svdsValor de k demasiado cercano al rango efectivoAumentar n_iter o reducir k. Verificar la distribución de valores singulares.
Resultado con valores NaNDatos con valores faltantes o infinidadesImputar o eliminar filas/columnas, o usar np.nan_to_num antes de la descomposición.
Desbordamiento de memoriaUso de SVD completa en matriz densa grandePasar a formato disperso y usar svds o randomized SVD.

Conclusión

La descomposición SVD es una herramienta versátil que, bien entendida y aplicada, permite resolver problemas de reducción de dimensionalidad, compresión, y cálculo de pseudo‑inversas con alta estabilidad numérica. Con las librerías modernas de Python (NumPy, SciPy, scikit‑learn) y técnicas de truncamiento aleatorio, es posible escalar la SVD a conjuntos de datos masivos sin sacrificar precisión.

Dominar su teoría y sus implementaciones prácticas es esencial para cualquier profesional de datos, ingeniero de Machine Learning o desarrollador que trabaje con grandes matrices.