我试图使用PCA来可视化一个具有5个特征的数据集。我同时使用了Matlab和R。在R中,我使用了prcomp()命令,而在Matlab中,我使用了pca()命令。两者都使用SVD来获取主成分,但我在Matlab和R中得到的主成分的方差差异很大。在Matlab中,我在第一个成分上得到了95%的方差,而在第二个成分上得到了3%的方差;而在R中,第一个成分大约有42%的方差,第二个成分大约有28%的方差。为什么它们会有这么大的差异?
我还可以提到,我计划稍后使用这些数据进行机器学习模型,并希望使用主成分来降低维度。我应该使用Matlab还是R的结果?
附注:我在R中使用fviz_eig()来显示每个成分的方差。
编辑:
R代码:
res.pca <- prcomp(dataset, scale=TRUE)fviz_eig(res.pca)
Matlab代码:
[coeff, score,~,~,var, mean] = pca(dataset,'algorithm','SVD');bar(var)
“dataset”是一个包含5个特征的csv文件,每个特征包含257493个观测值。
回答:
正如@Lyngbakr在评论中指出的那样,观察到的差异可能的原因是你指定了在R代码中对变量进行缩放,而在Matlab代码中没有这样做。
以下是在R中的一个示例:
生成不同量级的变量(具有不同量级的随机均匀噪声):
x1 <- runif(100, 200, 500)x2 <- runif(100, 20, 50)x3 <- runif(100, 2, 5)x4 <- runif(100, 0.2, 0.5)mat <- cbind(x1, x2, x3, x4)
不进行缩放的PCA:
pca1 <- prcomp(mat)pca1$sdev[1] 80.27564312 8.15330049 0.82751057 0.08491903
标准差反映了变量的不同范围
如果你只对变量进行中心化,保持方差不变,这通常被称为“基于协方差的PCA”:
cov(mat) x1 x2 x3 x4x1 6444.144562 11.149336032 9.70055864 -1.191862833x2 11.149336 66.495763487 0.06598063 -0.001822713x3 9.700559 0.065980626 0.69928547 0.007559200x4 -1.191863 -0.001822713 0.00755920 0.007560817
如果你还将变量标准化到方差=1,这通常被称为“基于相关性的PCA”。
pca2 <- prcomp(mat, scale = TRUE)pca2$sdev[1] 1.1308637 1.0205627 0.9624318 0.8679425
当数据被缩放后,主成分的标准差讲述了一个不同的故事。
cov(scale(mat)) x1 x2 x3 x4x1 1.00000000 0.017032146 0.144506324 -0.170749431x2 0.01703215 1.000000000 0.009675918 -0.002570615x3 0.14450632 0.009675918 1.000000000 0.103959503x4 -0.17074943 -0.002570615 0.103959503 1.000000000all.equal(cov(scale(mat)), cor(mat))[1] TRUE
一张图片胜过千言万语:
library(ggbiplot)library(cowplot)plot_grid(ggbiplot(pca1), ggbiplot(pca2), labels = c("未缩放", "已缩放"))
带有缩放的prcomp
应该类似于matlab
中的Weighted PCA
,在进行主成分分析时使用变量方差的倒数作为权重。
[coeff,~,latent,~,explained] = pca(dataset,...'VariableWeights','variance')
我没有Matlab来测试。