为什么通过数据SVD进行数据PCA?


22

这个问题是关于一种计算主成分的有效方法。

  1. 关于线性PCA的许多文章都主张对个案数据使用奇异值分解。也就是说,如果我们有数据并想用主成分替换变量(其),则可以执行SVD:,奇异值(特征值的平方根)占据了主对角线,右特征向量是轴变量到轴分量的正交旋转矩阵,左特征向量像,仅在这种情况下。然后,我们可以将分量值计算为。X = û 小号V '小号V Ù V C ^ = X V = û 小号XX=USVSVUVC=XV=US

  2. 进行变量PCA的另一种方法是通过分解方阵(即可以是变量之间的相关协方差等)。分解可以是特征分解或奇异值分解:对于正方形对称正半定矩阵,它们将给出特征值与和的对角线相同的结果。组件值将为。- [R [R = V 大号V '大号V C ^ = X VR=XXR R=VLVLVC=XV

现在,我的问题是:如果数据是一个大矩阵,并且案例数(通常是一个案例)比变量数大得多,那么方法(1)比方法(2)得多),因为方法(1)将相当昂贵的算法(例如SVD)应用于大矩阵;它计算并存储巨大的矩阵,这在我们的情况下是我们真正不需要的(变量的PCA)。如果是这样,那么为什么这么多texbook似乎主张或仅提及方式(1)?也许这有效,但我缺少了什么?üXU


2
通常,我们只对少数解释大多数差异的主要成分感兴趣。可以减少SVD。例如,如果是尺寸的Ñ × p其中p < < Ñ然后的函数将计算仅第一p左和默认右奇异向量。XN×pp<<NRsvdp
M. Berk

1
@ M.Berk:但是,在两种方法中都是相同的:它们产生相等的结果(等于符号变化)。同样,例如R 仅在需要时才计算C。pC
cbeleites支持Monica 2013年

您是否有方法(1)的参考?我只知道PCA是通过SVD在协方差矩阵(即方法2)上实现的,因为这避免了一些数值问题,并且显然会随维数而不是数据集的大小进行缩放。方式(1)我将全部称为SVD,而不是PCA。我只在纯SVD上下文中看到过它,实际上它不会执行完整的分解。
Anony-Mousse 2014年

@ Anony-Mousse,仅一提,Joliffe, Principal component analysis, 2nd ed.实际上,Joliffe描述了两种方式,但是据我所记得,在PCA的核心章节中,他只谈到了方式1。
ttnphns 2014年

@ Anony-Mousse,对我而言,方法1从理论上来说很重要,因为它清楚地显示了PCA与直接对应分析之间的直接关系。
ttnphns 2014年

Answers:


7

这是我关于主题的2ct

  • 我最初学习PCA的化学计量学讲座使用的是解决方案(2),但它不是面向数字的,据我所知,我的数字讲座只是入门,没有讨论SVD。

  • 如果我正确理解《福尔摩斯:大型矩阵的快速SVD》,那么您的想法已被用来获取长矩阵的计算快速SVD。
    这意味着如果遇到合适的矩阵,一个好的SVD实现可能会在内部跟随(2)(我不知道是否还有更好的可能性)。这意味着对于高级实现,最好使用SVD(1),然后将其留给BLAS负责在内部使用哪种算法。

  • 快速实用的检查:在5e4 x 100的矩阵上,OpenBLAS的svd似乎没有区别,svd (X, nu = 0)占用中值3.5 s,而svd (crossprod (X), nu = 0)花费54 ms(从R with调用microbenchmark)。
    当然,特征值的平方是很快的,并且两次调用的结果都相等。

    timing  <- microbenchmark (svd (X, nu = 0), svd (crossprod (X), nu = 0), times = 10)
    timing
    # Unit: milliseconds
    #                      expr        min         lq    median         uq        max neval
    #            svd(X, nu = 0) 3383.77710 3422.68455 3507.2597 3542.91083 3724.24130    10
    # svd(crossprod(X), nu = 0)   48.49297   50.16464   53.6881   56.28776   59.21218    10
    

更新:看看Wu,W .;Massart,D.&de Jong,S .:适用于宽数据的内核PCA算法。第一部分:理论与算法,化学计量学和智能实验室系统,36,165-172(1997)。DOI:http://dx.doi.org/10.1016/S0169-7439(97)00010-5

本文讨论了四种不同的PCA算法的数值和计算特性:SVD,特征分解(EVD),NIPALS和POWER。

它们之间的关系如下:

computes on      extract all PCs at once       sequential extraction    
X                SVD                           NIPALS    
X'X              EVD                           POWER

本文的上下文是X 30 × 500 ,并且适用于X X '(内核PCA)-这与您所要求的情况恰好相反。因此,要回答有关长矩阵行为的问题,您需要交换“内核”和“经典”的含义。X(30×500)XX

性能比较

毫不奇怪,EVD和SVD会根据使用经典算法还是内核算法而改变位置。在这个问题的上下文中,这意味着一个或另一个可能更好,具体取决于矩阵的形状。

但是从他们的“经典” SVD和EVD的讨论,很明显,分解是计算PCA一个很平常的方式。但是,除了使用Matlab 函数外,他们没有指定使用哪种SVD算法。XXsvd ()


    > sessionInfo ()
    R version 3.0.2 (2013-09-25)
    Platform: x86_64-pc-linux-gnu (64-bit)

    locale:
     [1] LC_CTYPE=de_DE.UTF-8       LC_NUMERIC=C               LC_TIME=de_DE.UTF-8        LC_COLLATE=de_DE.UTF-8     LC_MONETARY=de_DE.UTF-8   
     [6] LC_MESSAGES=de_DE.UTF-8    LC_PAPER=de_DE.UTF-8       LC_NAME=C                  LC_ADDRESS=C               LC_TELEPHONE=C            
    [11] LC_MEASUREMENT=de_DE.UTF-8 LC_IDENTIFICATION=C       

    attached base packages:
    [1] stats     graphics  grDevices utils     datasets  methods   base     

    other attached packages:
    [1] microbenchmark_1.3-0

loaded via a namespace (and not attached):
[1] tools_3.0.2

$ dpkg --list libopenblas*
[...]
ii  libopenblas-base              0.1alpha2.2-3                 Optimized BLAS (linear algebra) library based on GotoBLAS2
ii  libopenblas-dev               0.1alpha2.2-3                 Optimized BLAS (linear algebra) library based on GotoBLAS2

因此,您的测试(3.5秒vs 54毫秒)支持我的说法,即“方法1”的速度要慢得多。对?
ttnphns

1
@ttnphns:是的。但是,由于BLAS提供的svd可能与不同的BLAS不同。我曾期望,一个好的优化BLAS可以做到这一点。但是,OpenBLAS似乎并非如此。我懒得检查其他BLAS,但是也许有几个人可以检查他们的其他BLAS,所以我们找出了哪些针对此情况进行了优化的,哪些不是。(我通过电子邮件发送给OpenBLAS开发人员,并向他发送了此问题的链接,因此也许他可以添加一些信息,例如,不将算法切换svd (X'X)为长矩阵的原因。)
cbeleites支持Monica

XXn<pXXun+1=XXun/||XXun||v1XXXX×(Xun)

XXT

我说的是您的更新,涉及Nipals。我确认Nipals没有参与Lap​​ack的SVD。关于基准实验,类似的事情microbenchmark(X <- matrix(rnorm(5e6), ncol=100), Y <- t(X), svd(X), svd(Y), control=list(order="inorder"), times = 5)也可能很有趣。
猫王2014年

18

SVD速度较慢,但​​由于其较高的数值精度而通常被认为是首选方法。

如您在问题中所述,可以通过居中数据矩阵的SVD来执行主成分分析(PCA)。X1n1XXXXnp

这是MATLAB pca()函数帮助中编写的内容:

pca用于执行主成分分析的主成分算法[...]:

'svd'-默认。X的奇异值分解(SVD)。

np

最后一句话强调了此处至关重要的速度精度折衷方案。

1000×100

X = randn([1000 100]);

tic; svd(X); toc         %// Elapsed time is 0.004075 seconds.
tic; svd(X'); toc        %// Elapsed time is 0.011194 seconds.
tic; eig(X'*X); toc      %// Elapsed time is 0.001620 seconds.
tic; eig(X*X'); toc;     %// Elapsed time is 0.126723 seconds.

npXX

XXXX

X=(111ϵ000ϵ000ϵ),
3+ϵ2ϵ2ϵ2ϵ=105
eps = 1e-5;
X = [1 1 1; eye(3)*eps];
display(['Squared sing. values of X: ' num2str(sort(svd(X),'descend').^2')])
display(['Eigenvalues of X''*X:       ' num2str(sort(eig(X'*X),'descend')')])

获得相同的结果:

Squared sing. values of X: 3       1e-10       1e-10
Eigenvalues of X'*X:       3       1e-10       1e-10

ϵ=1010

Squared sing. values of X: 3       1e-20       1e-20
Eigenvalues of X'*X:       3           0 -3.3307e-16

XX

我应该补充一点,通常是人们乐于忽略这种潜在的[微小]的精度损失,而宁愿使用更快的方法。


1
XTX

感谢您的回答以及对利弊的全面考虑。
ttnphns 2014年

变形虫,那可能是您找到时间来显示一个具体的例子,其中数值稳定性会受到影响eig()吗?(读者会受益:速度和稳定性之间需要权衡取舍。在具体的实际情况下如何做出决定?)
ttnphns

@ttnphns我重写了整个答案,提供了一个具体示例。看一看。
变形虫说恢复莫妮卡

1
@amoeba,非常感谢您回来并举一个例子!我在SPSS中尝试了两个epsilon示例,但除了最后一行外,得到了与您类似的结果:而不是3 0 -3.3307e-16spss中的eigen返回了我3 0 0。似乎该函数具有一些内置的固定公差值,超出该值会归零。在此示例中,该函数似乎通过将两个小的特征值“ 0”和“ -16”都置零来打破数字不稳定性的困扰。
ttnphns
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.