为什么不能通过XX'和X'X的特征值分解来获得X的有效SVD?


9

我正在尝试手工制作SVD:

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)

但是最后一行不会返回m。为什么?似乎与这些特征向量的迹象有关...还是我误解了该过程?



我一再被告知,在SVD中信号并不重要...就像这样
— 失败的统计师,

@Amoeba谢谢您的澄清。我专注于英语问题而不是代码。Failedstatistician:查看D=diag(c(-1,1,1)*sqrt(eigen(m%*%t(m))$values))操作并记住平方根(以及任何归一化的特征向量)仅定义为正负号。要获取更多信息,请更改m为,m <- matrix(-2,1,1)并,1,1)在每次致电末尾添加diag。这是一个示例,它会产生相同的问题-但如此简单,问题的本质将变得十分明显。1×1
— ub

1
得到它了。谢谢!您是否有确定向量c(-1,1,1)的一般规则?还是应该将两个分解的符号联系起来?
— 失败的统计师,2017年

1
请注意,@ whuber的把戏c(-1,1,1)确实可以使用,但是这样D定义并不能给您单值。根据定义,奇异值必须全部为正。如何联系起来的迹象问题U和V好,我没有答案。您为什么不只做SVD?:-)
— amoeba '02

Answers:


13

问题分析

矩阵的SVD永远都不是唯一的。设矩阵维数为,其SVD为n × kAn×k

A=UDV′

对于具有正交列的矩阵,具有非负项的对角矩阵和具有正交列的矩阵U p × p D k × p Vn×pUp×pDk×pV

现在,任意选择对角线上有 s的任何对角线矩阵,使得是身份。然后S ± 1 S 2 = I p × p I pp×pS±1S2=Ip×p一世p

一个=üdV′=ü一世d一世V′=ü(小号2)d(小号2)V′=(ü小号)(小号d小号)(V小号)′

也是一个的SVD因为演示具有正交列相似的计算表明具有正交列。此外,由于和是对角线,所以它们通勤,因此表示仍然具有非负项。(û 小号)'(Ù 小号)= 小号' ü ' Ù 小号= 小号' 我p小号= 小号'小号= 小号2 = 我p Ü 小号V 小号小号d 小号d 小号= d 小号2 = d d一个

(ü小号)′(ü小号)=小号′ü′ü小号=小号′一世p小号=小号′小号=小号2=一世p
ü小号V小号小号d
小号d小号=d小号2=d
d

在代码中找到SVD的方法将找到一个对角化A的,类似地,对角化的 它前进到计算中的特征值方面中发现。 问题在于,这不能确保的列与的列始终匹配。甲甲' = (û d V ')(Û d V ' )' = Ü d V ' V d ' Ù ' = û d 2 ü “ V 甲'甲= V d 2 V '。D D 2 U Vü

一个一个′=(üdV′)(üdV′)′=üdV′Vd′ü′=üd2ü′
V
一个′一个=Vd2V′。
dd2üV

一个解法

相反,找到这样的和这样的,用它们来计算VüV

ü′一个V=ü′(üdV′)V=(ü′ü)d(V′V)=d

直接有效地。 该的对角线值不一定为正。d (这是因为对角化或的过程没有什么可以保证的,因为这两个过程是分别进行的。)通过选择对角线中的项使它们为正等于项的符号,因此具有所有正值。弥补这种由右乘用:甲甲'小号d 小号d ù 小号一个′一个一个一个′小号d小号dü小号

一个=üdV′=(ü小号)(小号d)V′。

那是一个SVD。

例

令且。SVD是ñ=p=ķ=1个一个=(-2)

(-2)=(1个)(2)(-1个)

其中,和。ü=(1个)d=(2)V=(-1个)

如果对角化您自然会选择和。同样,如果将A对角化,则可以选择。不幸的是,相反,计算 因为这是负数,所以设置。这将调整为,将为。您已经获得了它是两个可能的SVD之一(但与原始的不一样!)。一个′一个=(4)ü=(1个)d=(4)=(2)一个一个′=(4)V=(1个)

üdV′=(1个)(2)(1个)=(2)≠一个。
d=ü′一个V=(1个)′(-2)(1个)=(-2)。
小号=(-1个)üü小号=(1个)(-1个)=(-1个)d小号d=(-1个)(-2)=(2)
一个=(-1个)(2)(1个),

码

这是修改后的代码。其输出确认

  1. 该方法m正确地重新创建。
  2. ü和实际上仍然是正交的。V
  3. 但是结果与所返回的SVD不同svd。(两者同等有效。)
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

1
+1。这很清楚。我只会在实践中添加一个,即足以计算U或V,然后通过与相乘获得另一个矩阵A。这样,一个人仅执行一个(而不是两个)本征分解,并且信号会正确显示。
— amoeba'2

2
@Amoeba是的:按照手工计算SVD的精神,这显然是一种教育活动,在这里没有关注效率。
— 胡伯

2
谢谢你的热心帮助!我想我(最终)理解了这个问题。
— 失败的统计师,

3
@Federico谢谢您的提醒。您是完全正确的-我隐式地假设所有特征值都是不同的,因为实际上在统计应用中几乎肯定会是这种情况,并且摆脱了考虑“退化”特征空间的歧义的习惯。
— ub

3
您是正确的,这只是一个极端情况,确实是一个棘手的情况。从某种意义上讲,这是您在答案中概述的同一问题的另一种体现,即该方法不能确保和列之间的“匹配” 。从特征分解开始计算SVD仍然是一个很好的学习示例。üV
— Federico Poloni'2

5

正如我在@whuber答案的评论中所概述的那样,这种计算SVD的方法不适用于每个矩阵。问题不仅限于迹象。

问题在于可能存在重复的特征值,在这种情况下,和A的特征不是唯一的,并且并非所有的和选择都可用于检索SVD的对角因子。例如,如果您采用任何非对角正交矩阵(例如),则。在特征向量矩阵所有可能选择中,将返回,因此在这种情况下,不是对角线。一个′一个一个一个′üV一个=[3/54/5-4/53/5]一个一个′=一个′一个=一世一世eigenü=V=一世ü′一个V=一个

直观上,这是@whuber概述的同一问题的另一种体现,即和的列之间必须存在“匹配” ,并且单独计算两个本征分解不能确保这一点。üV

一个一个′一个一个一个′‖一个‖2üü≈2×10-1610-8

从两个特征分解中计算SVD是一个很好的学习示例,但是在现实生活中,应用程序始终使用R svd函数来计算奇异值分解。


1
此评论是很好的建议。但是请注意,该线程并不关心计算SVD的正确方法(我相信没有人会反对您的建议)。OP隐式接受该svd工作。的确,他们将其用作比较手算的标准,目的是检查理解,而不svd是以任何方式代替。
— ub

@whuber正确观察;我改写了最后一段。
— Federico Poloni'2
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.