¿Por qué no puedo obtener una SVD válida de X a través de la descomposición de valores propios de XX 'y X'X?

9

Estoy tratando de hacer SVD a mano:

m<-matrix(c(1,0,1,2,1,1,1,0,0),byrow=TRUE,nrow=3)

U=eigen(m%*%t(m))$vector
V=eigen(t(m)%*%m)$vector
D=sqrt(diag(eigen(m%*%t(m))$values))

U1=svd(m)$u
V1=svd(m)$v
D1=diag(svd(m)$d)

U1%*%D1%*%t(V1)
U%*%D%*%t(V)

Pero la última línea no regresa m. ¿Por qué? Parece que tiene algo que ver con los signos de estos vectores propios ... ¿O entendí mal el procedimiento?

estadistico
fuente
En repetidas ocasiones me han dicho que el letrero no importa en las SVD ... como este
estadística fallida
@Amoeba Gracias por aclarar eso. Me estaba centrando en la pregunta en inglés en lugar del código. Estadístico fallido: vea qué D=diag(c(-1,1,1)*sqrt(eigen(m%*%t(m))$values))hace y tenga en cuenta que la raíz cuadrada (así como cualquier vector propio normalizado) se define solo para firmar. Para mayor comprensión, el cambio ma m <- matrix(-2,1,1)e incluir ,1,1)al final de cada una de las llamadas a diag. Este es un ejemplo que crea el mismo problema, pero es tan simple que la naturaleza del problema será completamente obvia. 1×1
whuber
1
Entendido. ¡Gracias! ¿Tiene una regla general para determinar el vector c (-1, 1, 1)? ¿O cómo se deben vincular los signos de las dos descomposiciones?
estadística fallida
1
Tenga en cuenta que el truco de @ whuber con c(-1,1,1)funciona, pero Ddefinido así no le da valores singulares. Los valores singulares deben ser todos positivos por definición. La cuestión de cómo vincular los signos de Uy Ves buena, y no tengo una respuesta. ¿Por qué no solo haces una SVD? :-)
ameba

Respuestas:

13

Análisis del problema

La SVD de una matriz nunca es única. Deje que la matriz tenga dimensiones y deje que su SVD sean × kAn×k

A=UDV

para una matriz con columnas ortonormales, una diagonal matriz con entradas no negativas y una matriz con columnas ortonormales.U p × p D k × p Vn×pUp×pDk×pV

Ahora elija, arbitrariamente , cualquier diagonal matriz tenga s en la diagonal, de modo que sea ​​la identidad . EntoncesS ± 1 S 2 = I p × p I pp×pS±1S2=Ip×pIp

A=UDV=UIDIV=U(S2)D(S2)V=(US)(SDS)(VS)

también es una SVD de porque demuestra que tiene columnas ortonormales y un cálculo similar demuestra que tiene columnas ortonormales. Además, dado que y son diagonales, conmutan, de donde muestra que todavía tiene entradas no negativas.A

(US)(US)=SUUS=SIpS=SS=S2=Ip
USVSSD
SDS=DS2=D
D

El método implementado en el código para encontrar un SVD encuentra una que diagonaliza y, de manera similar, una que diagonaliza Se procede a calcular en términos de los valores propios encontrados en . El problema es esto no asegura un juego consistente de las columnas de con las columnas de .U

AA=(UDV)(UDV)=UDVVDU=UD2U
V
AA=VD2V.
DD2UV

Una solución

En cambio, después de encontrar una y una , úselas para calcularUV

UAV=U(UDV)V=(UU)D(VV)=D

directa y eficientemente Los valores diagonales de esta no son necesariamente positivos. D (Esto se debe a que no hay nada en el proceso de diagonalización de o que garantice eso, ya que esos dos procesos se llevaron a cabo por separado). Hazlos positivos eligiendo las entradas a lo largo de la diagonal de para igualar los signos de las entradas de , de modo que tenga todos los valores positivos. Compensar esto multiplicando a la derecha por :AAAASDSDUS

A=UDV=(US)(SD)V.

Esa es una SVD.

Ejemplo

Sea con . Una SVD esn=p=k=1A=(2)

(2)=(1)(2)(1)

con , y .U=(1)D=(2)V=(1)

Si diagonaliza , naturalmente elegiría y . Del mismo modo, si diagonaliza , elegiría . Desafortunadamente, En cambio, calcule Como esto es negativo, establezca . Esto ajusta a y a . Ha obtenido que es uno de los dos SVD posibles (¡pero no el mismo que el original!).AA=(4)U=(1)D=(4)=(2)AA=(4)V=(1)

UDV=(1)(2)(1)=(2)A.
D=UAV=(1)(2)(1)=(2).
S=(1)UUS=(1)(1)=(1)DSD=(1)(2)=(2)
A=(1)(2)(1),

Código

Aquí hay un código modificado. Su salida confirma

  1. El método se recrea mcorrectamente.
  2. U y realmente todavía son ortonormales.V
  3. Pero el resultado no es el mismo SVD devuelto por svd. (Ambos son igualmente válidos).
m <- matrix(c(1,0,1,2,1,1,1,0,0),byrow=TRUE,nrow=3)

U <- eigen(tcrossprod(m))$vector
V <- eigen(crossprod(m))$vector
D <- diag(zapsmall(diag(t(U) %*% m %*% V)))
s <- diag(sign(diag(D)))  # Find the signs of the eigenvalues
U <- U %*% s              # Adjust the columns of U
D <- s %*% D              # Fix up D.  (D <- abs(D) would be more efficient.)

U1=svd(m)$u
V1=svd(m)$v
D1=diag(svd(m)$d,n,n)

zapsmall(U1 %*% D1 %*% t(V1)) # SVD
zapsmall(U %*% D %*% t(V))    # Hand-rolled SVD
zapsmall(crossprod(U))        # Check that U is orthonormal
zapsmall(tcrossprod(V))       # Check that V' is orthonormal
whuber
fuente
1
+1. Esto es muy claro. Solo agregaría que, en la práctica, es suficiente calcular uno Uo dos Vy luego obtener otra matriz al multiplicar con A. De esta manera, uno realiza solo una (en lugar de dos) descomposiciones propias, y los signos saldrán bien.
ameba
2
@Amoeba Eso es correcto: en el espíritu de la computación manual de una SVD, que evidentemente es un ejercicio educativo, aquí no se presta atención a la eficiencia.
whuber
2
¡Gracias por su amable ayuda! Creo que entiendo este problema (finalmente).
error estadístico
3
@ Federico Gracias por ese recordatorio. Tiene toda la razón: he asumido implícitamente que todos los autovalores son distintos, ya que de hecho eso seguramente será el caso en las aplicaciones estadísticas y uno deja el hábito de considerar las ambigüedades con espacios propios "degenerados".
whuber
3
Estás en lo correcto, este es solo un caso de borde, y de hecho es complicado. En cierto sentido, es otra manifestación del mismo problema que usted esboza en su respuesta, que este método no asegura una "coincidencia" entre las columnas de y . Calcular el SVD a partir de las descomposiciones propias sigue siendo un gran ejemplo de aprendizaje. UV
Federico Poloni
5

Como describí en un comentario a la respuesta de @ whuber, este método para calcular la SVD no funciona para todas las matrices . El problema no se limita a los signos.

El problema es que puede haber valores propios repetidos, y en este caso la descomposición propia de y no es única y no todas las opciones de y se pueden utilizar para recuperar el factor diagonal de la SVD. Por ejemplo, si toma una matriz ortogonal no diagonal (por ejemplo, ), entonces . Entre todas las opciones posibles para la matriz de vector propio de , devolverá , por lo tanto, en este caso, no es diagonal.AAAAUVA=[3/54/54/53/5]AA=AA=IIeigenU=V=IUAV=A

Intuitivamente, esta es otra manifestación del mismo problema que @whuber describe, que tiene que haber una "coincidencia" entre las columnas de y , y calcular dos descomposiciones propias por separado no lo asegura.UV

Si todos los valores singulares de son distintos, entonces la descomposición propia es única (hasta escala / signos) y el método funciona. Observación: todavía no es una buena idea usarlo en el código de producción en una computadora con aritmética de coma flotante, porque cuando se forman los productos y el resultado calculado puede verse perturbado por una cantidad del orden de , donde es la precisión de la máquina. Si las magnitudes de los valores singulares difieren mucho (de más de , aproximadamente), esto es perjudicial para la precisión numérica de los más pequeños.A A A A A 2 u u 2 × 10 - 16 10 - 8AAAAAA2uu2×1016108

Calcular el SVD a partir de las dos descomposiciones propias es un gran ejemplo de aprendizaje, pero en las aplicaciones de la vida real siempre se usa la svdfunción de R para calcular la descomposición de valores singulares.

Federico Poloni
fuente
1
Este comentario es un buen consejo. Sin embargo, tenga en cuenta que este hilo no está preocupado por la forma correcta de calcular SVD (y creo que nadie discutirá en contra de su recomendación). El OP acepta implícitamente que svdfunciona. De hecho, lo usan como un estándar para comparar un cálculo manual, cuyo propósito es verificar el entendimiento, no reemplazarlo svdde ninguna manera.
whuber
@whuber Observación correcta; Reescribí el último párrafo.
Federico Poloni