如何在R中使用PCA进行降维


30

我有一个大数据集,我想执行降维。

现在到处都有我可以使用PCA的信息。但是,在计算/执行PCA之后,我似乎仍然无所适从。在R中,可以通过命令轻松完成princomp

但是计算完PCA后该怎么办?如果我决定要使用前主要成分,如何精确减少数据集?100


这个问题不是很清楚(100个PC 维数减少的数据集),但是具体关于重构原始变量(已接受答案的主题),另请参见:如何反转PCA并从多个主要成分重构原始变量?
变形虫说恢复莫妮卡

Answers:


35

我相信您所遇到的问题与使用少量主成分(PC)进行数据截断有关。对于这样的操作,我认为该功能prcomp更具说明性,因为它更易于可视化重建中使用的矩阵乘法。

首先,给出一个综合数据集,然后Xt执行PCA(通常将样本居中,以描述与协方差矩阵有关的PC:

#Generate data
m=50
n=100
frac.gaps <- 0.5 # the fraction of data with NaNs
N.S.ratio <- 0.25 # the Noise to Signal ratio for adding noise to data

x <- (seq(m)*2*pi)/m
t <- (seq(n)*2*pi)/n

#True field
Xt <- 
 outer(sin(x), sin(t)) + 
 outer(sin(2.1*x), sin(2.1*t)) + 
 outer(sin(3.1*x), sin(3.1*t)) +
 outer(tanh(x), cos(t)) + 
 outer(tanh(2*x), cos(2.1*t)) + 
 outer(tanh(4*x), cos(0.1*t)) + 
 outer(tanh(2.4*x), cos(1.1*t)) + 
 tanh(outer(x, t, FUN="+")) + 
 tanh(outer(x, 2*t, FUN="+"))

Xt <- t(Xt)

#PCA
res <- prcomp(Xt, center = TRUE, scale = FALSE)
names(res)

在结果或中prcomp,您可以看到PC的(res$x),特征值(res$sdev)提供有关每台PC的大小以及负载(res$rotation)的信息。

res$sdev
length(res$sdev)
res$rotation
dim(res$rotation)
res$x
dim(res$x)

通过对特征值求平方,可以得到每台PC解释的方差:

plot(cumsum(res$sdev^2/sum(res$sdev^2))) #cumulative explained variance

最后,您可以仅使用领先的(重要的)PC创建数据的截断版本:

pc.use <- 3 # explains 93% of variance
trunc <- res$x[,1:pc.use] %*% t(res$rotation[,1:pc.use])

#and add the center (and re-scale) back to data
if(res$scale != FALSE){
	trunc <- scale(trunc, center = FALSE , scale=1/res$scale)
}
if(res$center != FALSE){
    trunc <- scale(trunc, center = -1 * res$center, scale=FALSE)
}
dim(trunc); dim(Xt)

您可以看到结果是一个稍微平滑的数据矩阵,其中过滤出了小范围的特征:

RAN <- range(cbind(Xt, trunc))
BREAKS <- seq(RAN[1], RAN[2],,100)
COLS <- rainbow(length(BREAKS)-1)
par(mfcol=c(1,2), mar=c(1,1,2,1))
image(Xt, main="Original matrix", xlab="", ylab="", xaxt="n", yaxt="n", breaks=BREAKS, col=COLS)
box()
image(trunc, main="Truncated matrix (3 PCs)", xlab="", ylab="", xaxt="n", yaxt="n", breaks=BREAKS, col=COLS)
box()

在此处输入图片说明

这是您可以在prcomp函数之外执行的一种非常基本的方法:

#alternate approach
Xt.cen <- scale(Xt, center=TRUE, scale=FALSE)
C <- cov(Xt.cen, use="pair")
E <- svd(C)
A <- Xt.cen %*% E$u

#To remove units from principal components (A)
#function for the exponent of a matrix
"%^%" <- function(S, power)
     with(eigen(S), vectors %*% (values^power * t(vectors)))
Asc <- A %*% (diag(E$d) %^% -0.5) # scaled principal components

#Relationship between eigenvalues from both approaches
plot(res$sdev^2, E$d) #PCA via a covariance matrix - the eigenvalues now hold variance, not stdev
abline(0,1) # same results

现在,确定要保留哪些PC是一个单独的问题- 不久前我对此很感兴趣。希望能有所帮助。


2
马克(Marc),您无需明确记录中心和缩放比例,prcomp而是为您完成。看看res$centerres$scale。恕我直言,使用这些错误的可能性较小(显式调用scaleprcomp调用之间关于居中与否/缩放/不存在意外差异)。
cbeleites支持Monica

1
此答案需要扩展,因为它不能回答OP关于what to do after calculating the PCAhow do I reduce my dataset exactly?的问题。鉴于OP对他的样本进行了PCA,他的问题是如何处理它,以及该子样本的实际情况;没有PCA怎么办。我们不妨建议采取E <- eigen(cov(Sample)); A<- scale(scale=F, Sample) %*% E$vectors另一种方法来获得分数(这实际上是princomp所做的stats:::princomp.default)。
usεr11852恢复单胞菌说,

1
@ user11852-该问题专门涉及减少数据集(即我在此处演示的截断)。我将由他来决定这是否是他想要的。
2013年

1
@Marc,感谢您的回复。我想我可能需要退后一步,然后重新阅读所有内容,因为我坚持上面的任何答案如何处理降维。因为如您所示,dim(trunc)= dim(Xt)。它的好处是什么,尺寸并没有减少。
B_Miner

2
@B_Miner-请记住,截断用于关注数据中的主要模式并过滤出小规模的模式和噪声。截断后的数据在尺寸上不是更小,而是“更干净”。但是,截断确实会减少数据量,因为仅需几个向量即可重建整个矩阵。一个很好的例子是使用PCA进行图像压缩,其中可以使用较少数量的PC来重建图像。向量的较小子集占用较少的内存,但重构会在小规模细节上有所损失。
2013年

3

这些其他答案非常好而且很详尽,但是我想知道您是否实际上是在问一个更基本的问题:拥有PC后该怎么办?

每台PC只是成为一个新变量。假设PC1占总变化的60%,PC2占总变化的30%。由于这是总变化量的90%,因此您可以简单地将这两个新变量(PC)作为原始变量的简化版本。这就是说,如果您对此感兴趣,就可以将它们拟合为模型。当需要解释结果时,您需要在与每台PC相关的原始变量的上下文中进行解释。

抱歉,我低估了问题的范围!


2

一世λ一世Σķ=1个pλķpp=784λ

实际上,在PCA中,您将PC的投影(“分数”)用作原始样本的替代数据。您需要对所有分数进行分析,然后再使用PC重新构造原始样本,以找出原始空间中发生了什么(基本上是主成分回归)。显然,如果您能够有意义地解释特征向量(“载荷”),那么您将处于一个更好的位置:您可以通过对该载荷直接进行推论来描述该载荷所呈现的变异模式下样品的变化。根本不关心重建。:)

通常,“计算PCA之后”您要做什么取决于分析目标。PCA只是为您提供数据的线性独立子样本,这在RSS重建标准下是最佳的。您可以将其用于分类或回归,或同时用于两者,或者如我提到的那样,您可能想识别样本中有意义的正交变化模式。

注释:我认为最好的幼稚决定部件保留数量的办法是立足于样本变化的某个阈值,你想你的降维样品中保留,而不仅仅是一些任意数量例如,您的估计。3、100、200。如user4959所述,您可以通过检查$loadings由产生的列表对象中的字段下的列表的相关字段来检查累积变化princomp


1
正如您提到的主成分回归,它由R包pls提供。至于要保留的组件数量,我认为确定%方差而不是%并没有任何真正的优势。组件(也许是因为我处理的噪声水平非常不同。如@ Marc-in-the-box所述,有很多不同的方法来确定合适的PC数量,该策略将(应该)取决于类型数据和随后的数据分析类型
cbeleites支持Monica

plsprincomp {stats}ķķdd

1
是的,这很幼稚。我不同意设置任意的解释方差百分比具有任何其他任意截止值的固有优势。但这绝对不值得为此作斗争,因为a)OP从未征求选择No的建议。b)我认为我们同意无论如何都要对PCA模型进行适当的检查。
cbeleites支持Monica

没问题; 无论如何,这只是我发表之前的评论。(我把我的意见最后一段,因为我觉得它困扰,而不是澄清我想说的是什么)
usεr11852恢复单胞菌说,

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.