SVD

Basic

SVD | Descomposición en valores singulares

La SVD factoriza cualquier matriz rectangular como rotaciones y escalados. Es la base de PCA, compresión de imágenes y sistemas de recomendación.


1. Motivación #

  • Toda matriz (A) puede escribirse como (U\Sigma V^\top); truncando (\Sigma) obtenemos la mejor aproximación de bajo rango.
  • La SVD es estable numéricamente y ampliamente disponible en SciPy/NumPy.

2. Definición #

Para (A \in \mathbb{R}^{m \times n}):

$$A = U \Sigma V^\top$$

  • (U): vectores singulares izquierdos.
  • (\Sigma): valores singulares (\sigma_1 \ge \sigma_2 \ge \dots).
  • (V): vectores singulares derechos.

3. Preparar una imagen #

import numpy as np
import matplotlib.pyplot as plt
import japanize_matplotlib
from scipy import linalg
from PIL import Image

img = Image.open("./sample.png").convert("L").resize((163, 372)).rotate(90, expand=True)
img

4. Calcular la SVD #

X = np.asarray(img)
U, Sigma, VT = linalg.svd(X, full_matrices=True)

print(f"A: {X.shape}, U: {U.shape}, Σ:{Sigma.shape}, V^T:{VT.shape}")

5. Compresión de bajo rango #

for rank in [1, 2, 3, 4, 5, 10, 20, 50]:
    U_i = U[:, :rank]
    Sigma_i = np.matrix(linalg.diagsvd(Sigma[:rank], rank, rank))
    VT_i = VT[:rank, :]
    temp_image = np.asarray(U_i * Sigma_i * VT_i)

    plt.title(f"rank={rank}")
    plt.imshow(temp_image, cmap="gray")
    plt.show()

Con unos pocos valores singulares ya recuperamos la imagen con buena calidad.


6. Interpretar los vectores singulares #

total = np.zeros((163, 372))
for rank in [1, 2, 3, 4, 5]:
    U_i = U[:, :rank]
    Sigma_i = np.matrix(linalg.diagsvd(Sigma[:rank], rank, rank))
    VT_i = VT[:rank, :]

    if rank > 1:
        for ri in range(rank - 1):
            Sigma_i[ri, ri] = 0

    temp_image = np.asarray(U_i * Sigma_i * VT_i)
    total += temp_image

    plt.figure(figsize=(5, 5))
    plt.suptitle(f"Aporte de $u_{rank}$")
    plt.subplot(211)
    plt.imshow(temp_image, cmap="gray")
    plt.subplot(212)
    plt.plot(VT[0])
    plt.show()

Cada par (u_i, v_i) codifica un patrón específico.


7. Consejos #

  • Elige (k) observando (\sum_{i=1}^k \sigma_i / \sum_j \sigma_j).
  • Ignorar valores pequeños actúa como filtro de ruido.
  • PCA no es más que aplicar SVD sobre datos centrados.
  • Para matrices enormes utiliza SVD truncada o aleatoria.

Resumen #

  • La SVD descompone matrices en bases ortogonales y escalados.
  • Truncarla produce la mejor aproximación de bajo rango.
  • Es omnipresente: PCA, LSA, recomendadores, compresión.