Descomposición en valores singulares (SVD) -- La técnica para descomponer cualquier matriz

La descomposición espectral solo se aplica a matrices cuadradas, pero SVD no tiene esta limitación —Cualquier matriz puede someterse a SVD。

Es el motor matemático detrás de tecnologías como sistemas de recomendación, compresión de imágenes y ajuste fino con LoRA.

SVD: descomponer la matriz en tres partes

A
(m×n)
=
U
(m×m)
Rotación
×
Σ
(m×n)
Escalado
×
VT
(n×n)
Rotación

Intuición geométrica: cualquier transformación lineal = rotación + escalado a lo largo de los ejes de coordenadas + rotación nuevamente.

Los elementos diagonales de Σ se denominanvalores singulares, ordenados de mayor a menor, representan la 'energía' de la matriz en cada dirección ortogonal.

SVD truncado: aproximación usando los primeros k valores singulares

\[ A \approx U_k \Sigma_k V_k^T \]

Cuanto más pequeño sea k = mayor tasa de compresión = aproximación más tosca. Esta es la idea central de la reducción de dimensionalidad y la compresión.


Ejemplos cotidianos

Comprimir una imagen

Una tabla de 1000×1000 (1 millón de números), después de descomponerla con SVD, solo se usan los primeros 10 valores singulares para reconstruirla.

Solo es necesario almacenar aproximadamente 10×1000×2 = 20000 números para obtener una buena aproximación.

Este es el poder de la compresión con SVD: descartar la 'energía' irrelevante y conservar la estructura central.


Definición matemática

\[ A = U \Sigma V^T \]

Las columnas de U son los vectores singulares izquierdos (ortogonales), las filas de V son los vectores singulares derechos (ortogonales), y los elementos diagonales σ₁ ≥ σ₂ ≥ ... ≥ σ_r > 0 de Σ son los valores singulares.


Práctica con Python

Ejemplo

import numpy as np

A = np.array([[1,0,0,0,2],[0,0,3,0,0],[0,0,0,0,0],[0,4,0,0,0]])
U, S, VT = np.linalg.svd(A)
print("Valores singulares:", np.round(S, 2))  # [4. 3. 2.24 0.]
print("Número de valores singulares distintos de cero = rango =", np.sum(S > 1e-10))

# Demostración de compresión de imagen: imagen de rango 1
img = np.outer(np.array([1,2,3,2,1]), np.array([2,4,6,4,2]))
U_i, S_i, VT_i = np.linalg.svd(img)
print("\n"Valores singulares de la matriz de imagen:", np.round(S_i, 2))
# Reconstrucción perfecta con solo 1 valor singular (porque el rango = 1)
k = 1
approx = U_i[:,:k] @ np.diag(S_i[:k]) @ VT_i[:k,:]
print("Error de reconstrucción con k=1:", np.linalg.norm(img - approx))
奇异值: [4. 3. 2.24 0.]
非零奇异值个数 = 秩 = 3
图像矩阵的奇异值: [78.26 0. 0. 0. 0.]
k=1重建误差: 7.11e-14 (几乎完美)

Escenarios de aplicación en IA

Base matemática del ajuste fino con LoRA

La hipótesis de LoRA: \( \Delta W \) es de bajo rango — esto equivale a suponer que en la SVD de \( \Delta W \) solo los primeros r valores singulares son significativos, y el resto puede ignorarse. Cuanto menor sea r, menos parámetros entrenables, pero menor será la precisión de la aproximación. En la práctica, r=8 o 16 suele ser el punto óptimo entre eficacia y eficiencia, lo que proviene de la observación empírica de la velocidad de decaimiento de los valores singulares de la matriz de pesos.

Sistemas de recomendación: factorización de matrices para filtrado colaborativo

Se aplica SVD truncado a la matriz de calificaciones usuario-artículo R (m×n): \( R \approx U_k \Sigma_k V_k^T \). Cada fila de U_k es el vector latente de k dimensiones del usuario, y cada fila de V_k es el vector latente de k dimensiones del artículo. La calificación pronosticada del usuario u para el artículo i = producto punto del vector latente de u y el vector latente de i.

Compresión y destilación de modelos

Después de aplicar SVD a la matriz de pesos W de una capa totalmente conectada, se aproxima con SVD truncado: \( W \approx U_k \Sigma_k V_k^T \). La matriz original de m×n tiene mn parámetros; después de la descomposición, tiene k(m+n+1). Cuando k << min(m,n), el número de parámetros se reduce drásticamente. Esto es muy útil para implementar modelos grandes en dispositivos móviles.

Implementación de PCA mediante SVD

El PCA de sklearn no usa descomposición espectral internamente, sino SVD: se aplica SVD directamente a la matriz de datos centrada, y las columnas del vector singular derecho V son las direcciones de los componentes principales. SVD es numéricamente más estable y no requiere calcular explícitamente la matriz de covarianza.


Otras extensiones