【问题标题】:How to obtain principal component % variance explained in R? prcomp() and preProcess() comparison如何获得 R 中解释的主成分百分比方差? prcomp() 和 preProcess() 比较
【发布时间】:2020-06-17 05:51:41
【问题描述】:

我知道 PCA 可以使用 base R 中的 prcomp() 函数或 caret 包中的 preProcess() 函数等进行。

首先,我是否正确地说,如果我们只对prcomp(<SOME_MATRIX>)preProcess(<SOME_MATRIX>, method = "pca") 类型的操作使用默认设置,那么我们结果的唯一区别是prcomp() 之前没有居中和缩放数据进行 PCA,而 preProcess() 呢?所以prcomp(scale(<SOME_MATRIX>))preProcess(<SOME_MATRIX>, method = "pca")输出的东西一样吗?

其次,更重要的是,我们如何从prcomp()preProcess() 的输出中获得每台PC 解释的百分比方差?从这两个输出中,我可以看到诸如均值、标准差或旋转之类的东西,但我认为这些仅指“旧”变量。关于“新”PC 的信息在哪里以及它们的差异有多大?

这可能很有用,例如,我使用preProcess(<SOME_MATRIX>, method = "pca", thresh = 0.8) 并返回 6 台 PC,但我发现前 5 台 PC 总共解释了 79.5% 的方差。那么我可能倾向于不包括所有 6 台 PC。

【问题讨论】:

  • prcomp 确实居中,但不缩放。您始终可以使用predict(preProcess(<some matrix>, method = 'pca')) 从 preProcess 获取结果
  • 感谢@Oliver 对居中和缩放的澄清。我知道使用 predict(preProcess()) 来获得结果,但这并不能告诉我每台 PC 解释了多少差异,例如PC1 占方差的 27%,PC2 占 19%,等等。你知道我在哪里可以找到这些信息吗?

标签: r pca r-caret


【解决方案1】:

由于您的第一个问题已经得到解答,这里是您第二个问题的答案prcomp。我们可以通过调用summary得到每台PC解释的%方差:

df <- iris[1:4]
pca_res <- prcomp(df, scale. = TRUE)
summ <- summary(pca_res)
summ

#Importance of components:
#                          PC1    PC2     PC3     PC4
#Standard deviation     1.7084 0.9560 0.38309 0.14393
#Proportion of Variance 0.7296 0.2285 0.03669 0.00518
#Cumulative Proportion  0.7296 0.9581 0.99482 1.00000

summ$importance[2,]
# PC1     PC2     PC3     PC4 
#0.72962 0.22851 0.03669 0.00518

据我所知,在使用 caret 包时,此信息不可用(请参阅讨论的问题 here):

mod <- train(Species ~ ., data = iris, method = "knn",
                            preProc = c("center", "scale", "pca"))
str(mod$preProcess) 


List of 22
 $ dim              : int [1:2] 150 4
 $ bc               : NULL
 $ yj               : NULL
 $ et               : NULL
 $ invHyperbolicSine: NULL
 $ mean             : Named num [1:4] 5.84 3.06 3.76 1.2
  ..- attr(*, "names")= chr [1:4] "Sepal.Length" "Sepal.Width" "Petal.Length" "Petal.Width"
 $ std              : Named num [1:4] 0.828 0.436 1.765 0.762
  ..- attr(*, "names")= chr [1:4] "Sepal.Length" "Sepal.Width" "Petal.Length" "Petal.Width"
 $ ranges           : NULL
 $ rotation         : num [1:4, 1:2] 0.521 -0.269 0.58 0.565 -0.377 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : chr [1:4] "Sepal.Length" "Sepal.Width" "Petal.Length" "Petal.Width"
  .. ..$ : chr [1:2] "PC1" "PC2"
 $ method           :List of 4
  ..$ center: chr [1:4] "Sepal.Length" "Sepal.Width" "Petal.Length" "Petal.Width"
  ..$ scale : chr [1:4] "Sepal.Length" "Sepal.Width" "Petal.Length" "Petal.Width"
  ..$ pca   : chr [1:4] "Sepal.Length" "Sepal.Width" "Petal.Length" "Petal.Width"
  ..$ ignore: chr(0) 
 $ thresh           : num 0.95
 $ pcaComp          : NULL
 $ numComp          : num 2
 $ ica              : NULL
 $ wildcards        :List of 2
  ..$ PCA: chr(0) 
  ..$ ICA: chr(0) 
 $ k                : num 5
 $ knnSummary       :function (x, ...)  
 $ bagImp           : NULL
 $ median           : NULL
 $ data             : NULL
 $ rangeBounds      : num [1:2] 0 1
 $ call             : chr "scrubed"
 - attr(*, "class")= chr "preProcess"

【讨论】:

  • 谢谢@Dominik!这看起来很简单,我真的应该尝试summary() 作为第一选择。我也在preProcess(method = "pca") 对象上尝试了summary(),但它似乎不起作用。也许其他人会知道如何从这些对象中解释 PC % 方差。
  • 不客气!请参阅更新的答案,据我所知,使用 caret 包时此信息不可用。
  • 感谢您的更新。我已经检查了链接。首先,我认为PCA.1 &lt;- prcomp(iris[,1:4], center = TRUE, scale. = TRUE) 的初始命题是错误的,PCA.1$sdev / sum(PCA.1$sdev) 不等于解释的百分比方差summary(PCA.1)$importance[2,],它必须是PCA.1$sdev^2 / sum((PCA.1$sdev)^2)。其次,trace 对象会非常有帮助!但我想既然preProcess(method = "pca") 对象中有标准偏差,那么我们可以自己进行计算,尽管这并不理想。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-18
  • 2022-08-04
  • 2019-06-08
  • 1970-01-01
  • 2019-06-20
相关资源
最近更新 更多