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?
r
svd
eigenvalues
estadistico
fuente
fuente
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 cambiom
am <- matrix(-2,1,1)
e incluir,1,1)
al final de cada una de las llamadas adiag
. Este es un ejemplo que crea el mismo problema, pero es tan simple que la naturaleza del problema será completamente obvia.c(-1,1,1)
funciona, peroD
definido 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 deU
yV
es buena, y no tengo una respuesta. ¿Por qué no solo haces una SVD? :-)Respuestas:
Análisis del problema
La SVD de una matriz nunca es única. Deje que la matriz tenga dimensiones y deje que su SVD sean × kA n×k
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×p U p×p D k×p V
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×p S ±1 S2=I p×p Ip
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
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
Una solución
En cambio, después de encontrar una y una , úselas para calcularU V
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 :A′A AA′ S D SD U S
Esa es una SVD.
Ejemplo
Sea con . Una SVD esn=p=k=1 A=(−2)
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!).A′A=(4) U=(1) D=(4–√)=(2) AA′=(4) V=(1)
Código
Aquí hay un código modificado. Su salida confirma
m
correctamente.svd
. (Ambos son igualmente válidos).fuente
U
o dosV
y luego obtener otra matriz al multiplicar conA
. De esta manera, uno realiza solo una (en lugar de dos) descomposiciones propias, y los signos saldrán bien.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.A′A AA′ U V A=[3/5−4/54/53/5] AA′=A′A=I I U=V=I U′AV=A
eigen
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.U V
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 - 8A A′A AA′ ∥A∥2u u≈2×10−16 10−8
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
svd
función de R para calcular la descomposición de valores singulares.fuente
svd
funciona. De hecho, lo usan como un estándar para comparar un cálculo manual, cuyo propósito es verificar el entendimiento, no reemplazarlosvd
de ninguna manera.