为什么吴安德为什么更喜欢使用SVD而不是协方差矩阵的EIG来进行PCA?


29

我正在从Andrew Ng的Coursera课程和其他材料中学习PCA。在斯坦福大学自然语言处理课程中,cs224n的第一次作业,以及安德鲁·伍演讲视频(,他们进行奇异值分解而不是协方差矩阵的特征向量分解,而且吴还说SVD在数值上比特征分解更稳定。

根据我的理解,对于PCA,我们应该对(m,n)大小的数据矩阵进行SVD ,而不是对大小的协方差矩阵进行SVD (n,n)。以及协方差矩阵的特征向量分解。

为什么他们使用协方差矩阵而不是数据矩阵的SVD?


8
对于平方对称正半定矩阵(例如协方差矩阵),特征值分解和奇异值分解完全相同。
变形虫说莫妮卡(Monica)恢复职权

5
我的意思是它们在数学上是相同的。从数字上讲,他们可能确实使用了不同的算法,并且一个算法可能比另一个算法更稳定(如Ng所说)。知道更多有关+1的知识会很有趣。
变形虫说莫妮卡(Monica)恢复职权

4
有关此信息,请访问:de.mathworks.com/matlabcentral/newsreader/view_thread/21268。但是请注意,关于为什么一种算法比另一种算法更稳定的任何解释都是非常技术性的。
变形虫说莫妮卡(Monica)恢复职权

2
x=randn(10000); x=x'*x; tic; eig(x); toc; tic; svd(x); toc;我的机器上的Matlab中,eig()输出12s,svd()输出26s。如果速度太慢,至少必须更稳定!:-)
变形虫说莫妮卡(Monica)恢复职权是

4
这可能基于不正确的认识:做数据矩阵的SVD 更稳定的比使用eigsvd对协方差矩阵,但据我所知,使用之间没有大的区别eig还是svd在协方差矩阵---他们是两种向后稳定算法。如果有的话,我会花更多的钱在eig上,因为它执行的计算量更少(假设两者均使用最新算法来实现)。
Federico Poloni

Answers:


17

变形虫已经在评论中给出了很好的答案,但是如果您需要正式的论点,那就可以了。

矩阵的奇异值分解= û Σ V Ť,其中的列V是特征向量Ť和的对角项Σ平方根它的特征值,即σ = 一种一种=üΣVŤV一种Ť一种Σσ一世一世=λ一世一种Ť一种

如您所知,主要成分是变量在经验协方差矩阵1的特征向量空间上的正交投影。。各成分的方差通过它的特征值给出,λ11个ñ-1个一种Ť一种λ一世1个ñ-1个一种Ť一种

考虑任何方阵α ∈ [R和矢量v,使得v = λ v。然后α[Rvv=λv

  1. ķv=λķv
  2. λα=αλ

让我们定义S的SVD将计算STS=1的本征分解小号=1个ñ-1个一种Ť一种小号产生小号Ť小号=1个ñ-1个2一种Ť一种一种Ť一种

  1. 的特征向量,其性质1是A T A的特征向量一种Ť一种Ť一种Ť一种=一种Ť一种一种Ť一种一种Ť一种
  2. 平方根的本征值的,其通过属性2,则1,然后再次参考图2,是1个ñ-1个2一种Ť一种一种Ť一种1(n1)2λi(ATAATA)=1(n1)2λi2(ATA)=1n1λi(ATA)=λi(1n1ATA

瞧!

关于数值稳定性,需要弄清楚所使用的算法是什么。如果您愿意的话,我相信这些是numpy使用的LAPACK例程:

更新:关于稳定性,SVD实现似乎使用了分而治之的方法,而本征分解则使用普通的QR算法。我无法从我的机构获得一些相关的SIAM论文(怪异的研究削减),但是我发现了一些可以支持SVD程序更稳定的评估方法。

Nakatsukasa,Yuji和Nicholas J.Higham。“用于对称特征值分解和SVD的稳定高效的频谱划分和征服算法。” SIAM科学计算期刊35.3(2013):A1325-A1349。

他们比较了各种特征值算法的稳定性,似乎分治法(在一项实验中使用与numpy相同的方法!)比QR算法更稳定。这与其他地方声称D&C方法确实更稳定的说法一起,支持了Ng的选择。


我从关于协方差的svd和在平均居中数据的svd中获得的特征值不相同。
GD

但是,分数X * V(其中V是从[U,S,V] = svd(x)或svd(covx)获得)。
GD

1
@theGD的特征值cov(X)和奇异值(X)不相同,请参见 stats.stackexchange.com/questions/134282
变形虫说莫妮卡(Reonica Monica)

无需失望即可获得SIAM期刊:您引用的论文在这里:opt.mist.iu-tokyo.ac.jp/~nakatsukasa/publishedpdf/pub13.pdf
Dima

2
@broncoAbierto技术。报告在此处:cpsc.yale.edu/sites/default/files/files/tr932.pdf(由于cpsc.yale.edu/research/technical-reports标题中的“ Symetric”拼写错误,可能无法轻易找到它/ 1992-technical-reports :-))
Dima Pasechnik

12

@amoeba对PCA问题有很好的答案,包括关于SVD与PCA的关系这一问题。回答您的确切问题,我将提出三点意见:

  • 在数学上,您是直接在数据矩阵上还是在其协方差矩阵上计算PCA都没有区别
  • 差异完全是由于数值精度和复杂性。在数值上直接应用SVD比在协方差矩阵上更稳定
  • SVD可以应用于协方差矩阵以执行PCA或获取特征值,实际上,这是我最喜欢的解决特征问题的方法

事实证明,SVD比典型的特征值分解过程更稳定,尤其是对于机器学习而言。在机器学习中,很容易得出高度共线性的回归变量。在这些情况下,SVD效果更好。

这是演示这一点的Python代码。我创建了一个高度共线性的数据矩阵,得到了它的协方差矩阵,并试图获得后者的特征值。SVD仍在工作,而普通的本征分解在这种情况下会失败。

import numpy as np
import math
from numpy import linalg as LA

np.random.seed(1)

# create the highly collinear series
T = 1000
X = np.random.rand(T,2)
eps = 1e-11
X[:,1] = X[:,0] + eps*X[:,1]

C = np.cov(np.transpose(X))
print('Cov: ',C)

U, s, V = LA.svd(C)
print('SVDs: ',s)

w, v = LA.eig(C)
print('eigen vals: ',w)

输出:

Cov:  [[ 0.08311516  0.08311516]
 [ 0.08311516  0.08311516]]
SVDs:  [  1.66230312e-01   5.66687522e-18]
eigen vals:  [ 0.          0.16623031]

更新资料

回答费德里科·波洛尼(Federico Poloni)的评论,以下是对SVD与Eig进行稳定性测试的代码,这些代码针对上述相同矩阵的1000个随机样本。在许多情况下,Eig的特征值较小,为0,这将导致矩阵的奇异性,而SVD在此不这样做。在小的特征值确定中,SVD的精度大约高出两倍,根据您的问题,此精度可能不重要。

import numpy as np
import math
from scipy.linalg import toeplitz
from numpy import linalg as LA

np.random.seed(1)

# create the highly collinear series
T = 100
p = 2
eps = 1e-8

m = 1000 # simulations
err = np.ones((m,2)) # accuracy of small eig value
for j in range(m):
    u = np.random.rand(T,p)
    X = np.ones(u.shape)
    X[:,0] = u[:,0]
    for i in range(1,p):
        X[:,i] = eps*u[:,i]+u[:,0]

    C = np.cov(np.transpose(X))

    U, s, V = LA.svd(C)

    w, v = LA.eig(C)

    # true eigen values
    te = eps**2/2 * np.var(u[:,1])*(1-np.corrcoef(u,rowvar=False)[0,1]**2)
    err[j,0] = s[p-1] - te
    err[j,1] = np.amin(w) - te


print('Cov: ',C)
print('SVDs: ',s)
print('eigen vals: ',w)
print('true small eigenvals: ',te)

acc = np.mean(np.abs(err),axis=0)    
print("small eigenval, accuracy SVD, Eig: ",acc[0]/te,acc[1]/te)

输出:

Cov:  [[ 0.09189421  0.09189421]
 [ 0.09189421  0.09189421]]
SVDs:  [ 0.18378843  0.        ]
eigen vals:  [  1.38777878e-17   1.83788428e-01]
true small eigenvals:  4.02633695086e-18
small eigenval, accuracy SVD, Eig:  2.43114702041 3.31970128319

这里的代码代码有效。我不是生成随机协方差矩阵来测试例程,而是生成具有两个变量的随机数据矩阵:

x1=ux2=u+εv
u,v
(σ12σ12+ερσ1σ2σ12+ερσ1σ2σ12+2ερσ1σ2+ε2σ22σ2)
σ12,σ22,ρ -方差制服以及它们之间的相关性的coeffient。

λ=12(σ22ε2σ24ε4+4σ23ρσ1ε3+8σ22ρ2σ12ε2+8σ2ρσ13ε+4σ14+2σ2ρσ1ε+2σ12)
ε
λσ22ε2(1ρ2)/2

j=1,,mλ^jej=λλ^j


4
是的,但在这里OP是询问SVD VS EIG应用于两个协方差矩阵。
变形虫说莫妮卡(Reonica)Monica

1
@amoeba,我澄清了SVD和PCA的关系
Aksakal

这是一个很好的答案。但是,我希望提及的是,svd在存在负值并且您想要查看它们时不能检测到负特征值(如果协方差矩阵不是原始的,而是以某种方式进行了平滑或估计的,或者推断出来或来自成对删除)缺失值)。而且,cov矩阵上的eig仍然比svd快一点。
ttnphns

@ttnphns,非正定矩阵当然是个问题
Aksakal

1
@FedericoPoloni,关于FP算法,不知道确切的答案,我不同意。在这种情况下,我确实知道此任务的答案足够准确。在2x2上,您有一个公平的认识。我会考虑的。
阿克萨卡尔州

6

对于Python用户,我想指出的是,对于对称矩阵(例如协方差矩阵),最好使用numpy.linalg.eigh函数而不是通用numpy.linalg.eig函数。

eigheig我的计算机快9到10倍(无论矩阵大小如何),并且精度更高(基于@Aksakal的精度测试)。

我不相信具有小特征值的SVD的准确性优势的证明。@Aksakal的测试对随机状态的敏感性比对算法的敏感性高1-2个数量级(请尝试绘制所有错误,而不是将其减少到一个绝对最大值)。这意味着,与选择本征分解算法相比,协方差矩阵中的小误差对精度的影响更大。同样,这与有关PCA的主要问题无关。PCA中忽略了最小的组件。

关于数值稳定性,可以提出类似的论点。如果必须对PCA使用协方差矩阵方法,可以使用eigh代替进行分解svd。如果失败(此处尚未证明),那么在开始寻找更好的算法之前,可能值得重新考虑您要解决的问题。



2

要回答您问题的最后一部分,“为什么要对协方差矩阵而不是数据矩阵进行SVD​​?” 我相信这是出于性能和存储原因。通常, 将是一个非常大的数字,即使 ñ 很大,我们期望 ñ

对于相同的结果,在这些条件下计算协方差矩阵然后执行SVD比在完整数据矩阵上计算SVD快得多。

即使对于很小的值,性能提升也可以达到数千倍(毫秒与秒)。我在计算机上进行了一些测试,以使用Matlab进行比较: enter image description here

那只是CPU时间,但是存储需求也同样重要,甚至更多。如果您在Matlab中以百万分之一千的矩阵尝试SVD,则默认情况下会出错,因为它需要7.4TB的有效阵列大小。


这没有回答关于cov矩阵的EIG与协方差矩阵的 SVD 的问题
变形虫说恢复莫妮卡

1
最后,他的问题以粗体突出显示:“为什么要对协方差矩阵而不是数据矩阵进行SVD​​?” 我回答了。
Gruff

我将编辑开头的句子,以使我清楚地回答了OP的那部分问题。我知道这可能会造成混淆。谢谢。
Gruff

如果您在Matlab中对百万分之一千的矩阵尝试SVD,则默认情况下会出错,在这种情况下,良好的数值做法是使用薄的SVD。这将大大改善存储大小和性能。
Federico Poloni
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.