La descomposición en valores singulares (SVD) de una array es una factorización de esa array en tres arrays. Tiene algunas propiedades algebraicas interesantes y transmite importantes ideas geométricas y teóricas sobre transformaciones lineales. También tiene algunas aplicaciones importantes en la ciencia de datos. En este artículo, intentaré explicar la intuición matemática detrás de SVD y su significado geométrico.
Matemáticas detrás de SVD
La SVD de la array A mxn viene dada por la fórmula:
dónde:
- U: array mxn de los autovectores ortonormales de
.
- V T : transpuesta de una array nxn que contiene los vectores propios ortonormales de A^{T}A.
- W: una array diagonal nxn de los valores singulares que son las raíces cuadradas de los valores propios de
.
Ejemplos
- Encuentre el SVD para la array A =
- Para calcular el SVD, primero, necesitamos calcular los valores singulares encontrando los valores propios de AA^{T}.
- La ecuación característica de la array anterior es:
por lo que nuestros valores singulares son:
- Ahora encontramos los vectores singulares correctos, es decir, un conjunto ortonormal de vectores propios de A T A. Los valores propios de A T A son 25, 9 y 0, y dado que A T A es simétrico, sabemos que los vectores propios serán ortogonales.
Para
que puede ser fila-reduce a:
Un vector unitario en la dirección de la misma es:
De manera similar, para \lambda = 9, el vector propio es:
Para el tercer vector propio, podríamos usar la propiedad de que es perpendicular a v1 y v2 tal que:
Resolviendo la ecuación anterior para generar el tercer vector propio
Ahora, calculamos U usando la fórmula u_i = \frac{1}{\sigma} A v_i y esto da U = . Por lo tanto, nuestra ecuación SVD final se convierte en:
Aplicaciones
- Cálculo de la pseudo-inversa: la pseudo-inversa o la inversa de Moore-Penrose es la generalización de la array inversa que puede no ser invertible (como las arrays de bajo rango). Si la array es invertible, su inversa será igual a Pseudo inversa, pero existe pseudo inversa para la array que no es invertible. Se denota por A + .
Supongamos que necesitamos calcular la pseudo-inversa de una array M:
Entonces, la SVD de M se puede dar como:
Multiplica ambos lados por M^{-1}.
Multiplica ambos lados por V:
Multiplica por W^{-1}. Dado que W es la array singular, la inversa de W es
Multiplicar por
La ecuación anterior da la pseudo-inversa.
- Resolviendo un conjunto de Ecuaciones Lineales Homogéneas (Mx =b): si b=0, calcular SVD y tomar cualquier columna de V T asociada a un valor singular (en W ) igual a 0.
si ,
Multiplicar por
Por la Pseudo-inversa, sabemos que
Por eso,
- Rango, rango y espacio nulo:
- El rango de la array M se puede calcular a partir de SVD por el número de valores singulares distintos de cero.
- El rango de la array M es Los vectores singulares izquierdos de U correspondientes a los valores singulares distintos de cero.
- El espacio nulo de la array M es Los vectores singulares rectos de V correspondientes a los valores singulares puestos a cero.
- Problema de ajuste de curvas: se puede utilizar la descomposición de valores singulares para minimizar el error de mínimos cuadrados. Utiliza el pseudo inverso para aproximarlo.
- Además de la aplicación anterior, la descomposición de valores singulares y la pseudo-inversa también se pueden usar en el procesamiento de señales digitales y el procesamiento de imágenes.
Implementación
- En este código, intentaremos calcular la descomposición del valor Singular usando Numpy y Scipy. Estaremos calculando SVD, y también realizando pseudo-inversa. Al final, podemos aplicar SVD para comprimir la imagen.
Python3
# Imports import numpy as np from scipy.linalg import svd """ Singular Value Decomposition """ # define a matrix X = np.array([[3, 3, 2], [2,3,-2]]) print(X) # perform SVD U, singular, V_transpose = svd(X) # print different components print("U: ",U) print("Singular array",s) print("V^{T}",V_transpose) """ Calculate Pseudo inverse """ # inverse of singular matrix is just the reciprocal of each element singular_inv = 1.0 / singular # create m x n matrix of zeroes and put singular values in it s_inv = np.zeros(A.shape) s_inv[0][0]= singular_inv[0] s_inv[1][1] =singular_inv[1] # calculate pseudoinverse M = np.dot(np.dot(V_transpose.T,s_inv.T),U.T) print(M) """ SVD on image compression """ import numpy as np import matplotlib.pyplot as plt from skimage import data from skimage.color import rgb2gray cat = data.chelsea() plt.imshow(cat) # convert to grayscale gray_cat = rgb2gray(cat) # calculate the SVD and plot the image U,S,V_T = svd(gray_cat, full_matrices=False) S = np.diag(S) fig, ax = plt.subplots(5, 2, figsize=(8, 20)) curr_fig=0 for r in [5, 10, 70, 100, 200]: cat_approx =U[:, :r] @ S[0:r, :r] @ V_T[:r, :] ax[curr_fig][0].imshow(256-cat_approx) ax[curr_fig][0].set_title("k = "+str(r)) ax[curr_fig,0].axis('off') ax[curr_fig][1].set_title("Original Image") ax[curr_fig][1].imshow(gray_cat) ax[curr_fig,1].axis('off') curr_fig +=1 plt.show()
Producción:
[[ 3 3 2] [ 2 3 -2]] --------------------------- U: [[-0.7815437 -0.6238505] [-0.6238505 0.7815437]] --------------------------- Singular array [5.54801894 2.86696457] --------------------------- V^{T} [[-0.64749817 -0.7599438 -0.05684667] [-0.10759258 0.16501062 -0.9804057 ] [-0.75443354 0.62869461 0.18860838]] -------------------------- # Inverse array([[ 0.11462451, 0.04347826], [ 0.07114625, 0.13043478], [ 0.22134387, -0.26086957]]) ---------------------------
Imagen k original frente a SVD