我使用
prcomp
函数对 4 个变量运行 PCA。在 PCA 之前,所有变量均已归一化,平均值为零,标准差为 1(z 分数)。
prc <- prcomp(adpt.pca)
结果如下:
Standard deviations (1, .., p=4):
[1] 1.4053803 1.0682221 0.8730050 0.3488124
Rotation (n x k) = (4 x 4):
PC1 PC2 PC3 PC4
income -0.6183326 0.3817256 -0.18174425 -0.66250989
ndvi 0.1800165 0.7300110 0.65526401 0.07284918
cs_dist 0.3476116 0.5522182 -0.73234784 0.19464803
education -0.6814873 0.1281581 -0.03556312 0.71964281
然后我选择了特征值 > 1 的 PC,并执行了
varimax
旋转,如下所示:
varimax2 <- varimax(prc$rotation[, 1:2])
最大方差旋转的结果:
$loadings
Loadings:
PC1 PC2
income -0.716 0.122
ndvi -0.107 0.744
cs_dist 0.115 0.642
education -0.680 -0.137
PC1 PC2
SS loadings 1.00 1.00
Proportion Var 0.25 0.25
Cumulative Var 0.25 0.50
$rotmat
[,1] [,2]
[1,] 0.9269670 0.3751429
[2,] -0.3751429 0.9269670
如何通过方差对这些旋转的 PC 分数进行加权,以重建原始观察结果?
完整代码:
library(data.table)
library(dplyr)
wd <- "path/"
mydt <- read.table(paste0(wd, "mydt.csv"), sep = ",", header = TRUE)
# glimpse(mydt)
# Z-score normalize
adpt.pca <- as.data.frame(scale(mydt), center = TRUE, scale = TRUE)
prc <- prcomp(adpt.pca)
varimax2 <- varimax(prc$rotation[, 1:2])
下面是 20 行的原始数据集样本(Z 分数标准化之前):
dput(mydt)
structure(list(income = c(0.0001063, 0.000106, 6.72e-05, 7.97e-05,
0.0001197, 4.09e-05, 5.17e-05, 0.0001092, 8.62e-05, 7.27e-05,
0.0001034, 0.0001159, 7.24e-05, 9.17e-05, 8.06e-05, 0.0001049,
8.15e-05, 9.05e-05, 0.0001063, 5.99e-05), ndvi = c(0.434779405593872,
0.519024193286896, 0.484442293643951, 0.358367592096329, 0.613705396652222,
0.508738815784454, 0.705485105514526, 0.454894632101059, 0.396738857030869,
0.408085465431213, 0.425091296434402, 0.360570818185806, 0.455742985010147,
0.44114676117897, 0.498669385910034, 0.404618799686432, 0.51068776845932,
0.295410215854645, 0.606453955173492, 0.46584877371788), cs_dist = c(1515.64929199219,
3037.51879882812, 2663.20043945312, 1761.39184570312, 344.697448730469,
252.047805786133, 5528.3486328125, 2387.2802734375, 2771.0546875,
877.851745605469, 1342.23034667969, 3318.9130859375, 1075.06188964844,
5190.70166015625, 739.960021972656, 4005.1572265625, 684.494079589844,
426.935241699219, 1222.70263671875, 2597.5166015625), education = c(0.0001015,
9.71e-05, 6.14e-05, 8.47e-05, 9.97e-05, 5.29e-05, 4.74e-05, 0.0001464,
0.0001042, 7.53e-05, 0.0001143, 9.4e-05, 6.57e-05, 5.52e-05,
7.98e-05, 9.5e-05, 6.98e-05, 9.64e-05, 0.0001063, 6.43e-05)), row.names = c(NA,
-20L), class = c("data.table", "data.frame"), na.action = structure(c(`2402` = 2174L,
`2404` = 2176L), class = "omit"), .internal.selfref = <pointer: 0x0000023dc7801200>)
注意: 我显示的结果是使用我的完整数据集而不是我共享的 20 行时的结果。如果需要,我可以共享整个数据集。
R 4.4.0、RStudio 2024.04.2 内部版本 764、Windows 11。
这个问题有点让人困惑。这就是为什么也许还没有人解决这个问题。请注意,
varimax
适用于 FA,而不适用于 PCA。
要构建观测值,请直接使用分数和计算的主成分。这里不需要最大方差:
prc <- prcomp(mydt)
使用所有电脑进行重建:
reconstruct <- data.frame(t(t(prc$x %*% t(prc$rotation)) + prc$center))
all.equal(reconstruct, mydt, check.attributes = FALSE)
[1] TRUE
使用 PC 的子集进行重建:
n <- which(prc$sdev>1)
reconstruct2 <- data.frame(t(t(prc$x[,n] %*% t(prc$rotation[,n])) + prc$center))