只有第一个主成分的 PCA 分数是 "wrong" 符号
PCA scores for only the first principal components are of "wrong" sign
我目前正在尝试进入主成分分析和回归。因此,我尝试手动计算给定矩阵的主要成分,并将其与您从 r-package rcomp 中获得的结果进行比较。
下面是手工做pca的代码
### compute principal component loadings and scores by hand
df <- matrix(nrow = 5, ncol = 3, c(90,90,60,60,30,
60,90,60,60,30,
90,30,60,90,60))
# calculate covariance matrix to see variance and covariance of
cov.mat <- cov.wt(df)
cen <- cov.mat$center
n.obs <- cov.mat$n.obs
cv <- cov.mat$cov * (1-1/n.obs)
## calcualate the eigenvector and values
edc <- eigen(cv, symmetric = TRUE)
ev <- edc$values
evec <- edc$vectors
cn <- paste0("Comp.", 1L:ncol(cv))
cen <- cov.mat$center
### get loadings (or principal component weights) out of the eigenvectors and compute scores
loadings <- structure(edc$vectors, class = "loadings")
df.scaled <- scale(df, center = cen, scale = FALSE)
scr <- df.scaled %*% evec
我将我的结果与使用 princomp-package 获得的结果进行了比较
pca.mod <- princomp(df)
loadings.mod <- pca.mod$loadings
scr.mod <- pca.mod$scores
scr
scr.mod
> scr
[,1] [,2] [,3]
[1,] -6.935190 32.310906 7.7400588
[2,] -48.968014 -19.339313 -0.3529382
[3,] 1.733797 -8.077726 -1.9350147
[4,] 13.339605 18.519500 -9.5437444
[5,] 40.829802 -23.413367 4.0916385
> scr.mod
Comp.1 Comp.2 Comp.3
[1,] 6.935190 32.310906 7.7400588
[2,] 48.968014 -19.339313 -0.3529382
[3,] -1.733797 -8.077726 -1.9350147
[4,] -13.339605 18.519500 -9.5437444
[5,] -40.829802 -23.413367 4.0916385
显然,我做得很好。计算出的分数至少在比例上相等。但是:第一主成分的分数符号不同。其他两个不是这种情况。
这引出了两个问题:
- 我读过,将载荷和主成分的分数乘以负一是没有问题的。当只有一个主成分的符号也不同时,这是否成立?
- 从计算的角度来看,我做错了什么?这个过程对我来说似乎很简单,我看不出我可以在自己的计算中改变什么来获得与 princomp-package 相同的符号。
当用 mtcars 数据集检查时,我的第一台 PC 的标志是正确的,但是现在第二和第四台 PC 的分数与包相比有不同的标志。我无法理解这一点。感谢您的帮助!
特征向量和载荷的符号是任意的,所以这里没有什么“错误”。您唯一应该期望保留的是每个加载向量中符号的整体模式,即在上面的示例中,PC1 的 princomp
答案给出 +,+,-,-,-
,而您的答案给出 -,-,+,+,+
。没关系。如果你给了例如-,+,-,-,+
那会很麻烦(因为两者乘以 -1 就不再等价了)。
然而,虽然通常符号是任意的,因此可能因算法、编译器、操作系统等而异,但在这种特殊情况下有一个简单的解决方案。 princomp
有一个 fix_sign
参数:
fix_sign:
Should the signs of the loadings and scores be chosen so that
the first element of each loading is non-negative?
尝试 princomp(df,fix_sign=FALSE)$scores
,您会发现迹象(可能!)与您的结果一致。 (通常 fix_sign=TRUE
选项很有用,因为它以特定方式打破了对称性,因此 将 在所有平台上总是产生相同的答案。)
我目前正在尝试进入主成分分析和回归。因此,我尝试手动计算给定矩阵的主要成分,并将其与您从 r-package rcomp 中获得的结果进行比较。
下面是手工做pca的代码
### compute principal component loadings and scores by hand
df <- matrix(nrow = 5, ncol = 3, c(90,90,60,60,30,
60,90,60,60,30,
90,30,60,90,60))
# calculate covariance matrix to see variance and covariance of
cov.mat <- cov.wt(df)
cen <- cov.mat$center
n.obs <- cov.mat$n.obs
cv <- cov.mat$cov * (1-1/n.obs)
## calcualate the eigenvector and values
edc <- eigen(cv, symmetric = TRUE)
ev <- edc$values
evec <- edc$vectors
cn <- paste0("Comp.", 1L:ncol(cv))
cen <- cov.mat$center
### get loadings (or principal component weights) out of the eigenvectors and compute scores
loadings <- structure(edc$vectors, class = "loadings")
df.scaled <- scale(df, center = cen, scale = FALSE)
scr <- df.scaled %*% evec
我将我的结果与使用 princomp-package 获得的结果进行了比较
pca.mod <- princomp(df)
loadings.mod <- pca.mod$loadings
scr.mod <- pca.mod$scores
scr
scr.mod
> scr
[,1] [,2] [,3]
[1,] -6.935190 32.310906 7.7400588
[2,] -48.968014 -19.339313 -0.3529382
[3,] 1.733797 -8.077726 -1.9350147
[4,] 13.339605 18.519500 -9.5437444
[5,] 40.829802 -23.413367 4.0916385
> scr.mod
Comp.1 Comp.2 Comp.3
[1,] 6.935190 32.310906 7.7400588
[2,] 48.968014 -19.339313 -0.3529382
[3,] -1.733797 -8.077726 -1.9350147
[4,] -13.339605 18.519500 -9.5437444
[5,] -40.829802 -23.413367 4.0916385
显然,我做得很好。计算出的分数至少在比例上相等。但是:第一主成分的分数符号不同。其他两个不是这种情况。
这引出了两个问题:
- 我读过,将载荷和主成分的分数乘以负一是没有问题的。当只有一个主成分的符号也不同时,这是否成立?
- 从计算的角度来看,我做错了什么?这个过程对我来说似乎很简单,我看不出我可以在自己的计算中改变什么来获得与 princomp-package 相同的符号。
当用 mtcars 数据集检查时,我的第一台 PC 的标志是正确的,但是现在第二和第四台 PC 的分数与包相比有不同的标志。我无法理解这一点。感谢您的帮助!
特征向量和载荷的符号是任意的,所以这里没有什么“错误”。您唯一应该期望保留的是每个加载向量中符号的整体模式,即在上面的示例中,PC1 的 princomp
答案给出 +,+,-,-,-
,而您的答案给出 -,-,+,+,+
。没关系。如果你给了例如-,+,-,-,+
那会很麻烦(因为两者乘以 -1 就不再等价了)。
然而,虽然通常符号是任意的,因此可能因算法、编译器、操作系统等而异,但在这种特殊情况下有一个简单的解决方案。 princomp
有一个 fix_sign
参数:
fix_sign:
Should the signs of the loadings and scores be chosen so that the first element of each loading is non-negative?
尝试 princomp(df,fix_sign=FALSE)$scores
,您会发现迹象(可能!)与您的结果一致。 (通常 fix_sign=TRUE
选项很有用,因为它以特定方式打破了对称性,因此 将 在所有平台上总是产生相同的答案。)