PCA的成分真的代表方差百分比吗?它们的总和是否可以超过100%?


13

奥赖利(O'Reilly)的“黑客机器学习”说,每个主成分代表方差的百分比。我引用了以下页面的相关部分(第8章,第207页)。在与另一位专家交谈时,他们同意这是百分比。

但是,这24个组件的总和为133.2095%。这个怎么可能?

在说服自己可以使用PCA之后,我们如何在R中做到这一点?同样,这是R发挥作用的地方:整个PCA可以在一行代码中完成。我们使用princomp函数运行PCA:

pca <- princomp(date.stock.matrix[,2:ncol(date.stock.matrix)])

如果仅在R中键入pca,我们将看到主要组成部分的快速摘要:

Call:
princomp(x = date.stock.matrix[, 2:ncol(date.stock.matrix)])
Standard deviations:
Comp.1 Comp.2 Comp.3 Comp.4 Comp.5 Comp.6 Comp.7
29.1001249 20.4403404 12.6726924 11.4636450 8.4963820 8.1969345 5.5438308
Comp.8 Comp.9 Comp.10 Comp.11 Comp.12 Comp.13 Comp.14
5.1300931 4.7786752 4.2575099 3.3050931 2.6197715 2.4986181 2.1746125
Comp.15 Comp.16 Comp.17 Comp.18 Comp.19 Comp.20 Comp.21
1.9469475 1.8706240 1.6984043 1.6344116 1.2327471 1.1280913 0.9877634
Comp.22 Comp.23 Comp.24
0.8583681 0.7390626 0.4347983
24 variables and 2366 observations.

在此摘要中,标准差告诉我们数据集中有多少差异是由不同的主成分解决的。第一个组件称为Comp.1,占方差的29%,而下一个组件占20%。到最后,最后一个成分Comp.24占不到方差的1%。这表明,仅查看第一个主成分,我们就可以了解很多数据。

[代码和数据可以在github上找到。]


6
我认为作者对的解释Standard deviations略有偏离。由于标准偏差实际上是标准偏差,因此我们必须对它们求平方以查看每个分量代表多少方差。第一个分量表示总方差的 2%。100×29.1001249229.10012492++0.43479832
假定正常的2012年

4
这个问题恐怕是由两个基本错误引起的:(1)它错过了宣布数字为“标准偏差”的标题,并将它们误认为是方差;(2)假定这些数字是百分数,但不是。(它们的单位是用库存度量的单位:美元或每年的变化百分比或其他。)这里根本没有错误:@Max的注释说明了如何找到总差异的百分比。
ub

1
@whuber也许我应该使用“ typo”而不是“ bug”?:-)“ Comp.1,占方差的29% ”是错误的,应显示“ Comp.1,占方差的46%
Darren Cook

1
谢谢,达伦(Darren):我误解了书中存在的困惑,因此我选择了“错误”来指代R软件本身。发现该错误是一个很好的发现(我希望您发现对PCA真正发生的事情感到高兴)!
ub

5
是的,这无疑是本书中的错误。在某些地方,我误用了标准偏差而不是方差。(例如,在某种程度上,我们使用RMSE而不是MSE来计算R平方。)我希望我们有时间坐下来并在不久的将来更正此类错误。
约翰·迈尔斯·怀特

Answers:


11

使用summary.princomp看“变异的比例”和“累积比例”。

pca <- princomp(date.stock.matrix[,2:ncol(date.stock.matrix)])
summary(pca)

1
谢谢约书亚。因此,第一个成分实际上是方差的46%。我将向该书发送错误报告。
达伦·库克

如何计算“差异比例”?显示的数字是0.4600083。但是sqrt(pca$sdev[1]/sum(pca$sdev))(大约sqrt(29.1/133.2))给出0.4673904。
达伦·库克

3
@DarrenCook:sdev表示您正在查看标准偏差,即方差的平方根(或λipca$sdev[1]^2/sum(pca$sdev^2)

2
@DarrenCook:使用源代码…… stats:::print.summary.princomp向您展示了它对sdev成分进行平方,这stats:::princomp.default显示的是sqrt特征值的。
约书亚·乌尔里希

11

100 %.

pXΣ

tr(Σ)=σ11+σ22++σpp.

λ1λ2λp.

tr(Σ)=λ1++λp
λiΣλp0

eiXeii1λi

Var(eiX)=eiΣei=λieiei=λi
k
(λ1++λkλ1++λp100) %
100 %k=p

1
您是否看到@Max对问题的(最新)评论?他确定了答案。
ub

@whuber:我没看过,谢谢。我在评论约书亚的回答时也做了类似的评论。
MånsT

4

这是一些R代码来补充先前的答案(pca[["sdev"]]通常是写成pca$sdev,但会在下面的代码段中引起格式错误)。

# Generate a dummy dataset.
set.seed(123)
x <- matrix(rnorm(400, sd=3), ncol=4)
# Note that princomp performs an unscaled PCA.
pca1 <- princomp(x)
# Show the fraction variance of each PC.
pca1[["sdev"]]^2
cumsum(pca1[["sdev"]]^2)/sum(pca1[["sdev"]]^2)
# Perform a scaled PCA.
pca2 <- princomp(x, cor=TRUE)
pca2[["sdev"]]^2
cumsum(pca2[["sdev"]]^2)/sum(pca2[["sdev"]]^2)

因此,正如@Max指出的那样,使用方差而不是标准偏差并且不要忘记除以总方差即可解决此问题。

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.