R

如何計算 R 中的 varimax-rotated 主成分?

  • May 16, 2013

我在 25 個變量上運行 PCA,並使用prcomp.

prc <- prcomp(pollutions, center=T, scale=T, retx=T)

然後我對這些組件進行了 varimax 旋轉。

varimax7 <- varimax(prc$rotation[,1:7])

現在我希望對 PCA 旋轉數據進行 varimax 旋轉(因為它不是 varimax 對象的一部分 - 只有載荷矩陣和旋轉矩陣)。我讀到要做到這一點,你將旋轉矩陣的轉置乘以數據的轉置,所以我會這樣做:

newData <- t(varimax7$rotmat) %*% t(prc$x[,1:7])

但這沒有意義,因為上面的矩陣轉置的維度是和分別所以我將只剩下一個矩陣行,而不是行…有誰知道我在這裡做錯了什麼或我的最後一行應該是什麼?之後我只需要轉回嗎?

“輪換”是因子分析中發展起來的一種方法;將旋轉(例如 varimax)應用於loadings,而不是應用於協方差矩陣的特徵向量。載荷是由各自特徵值的平方根縮放的特徵向量。在 varimax 旋轉之後,加載向量不再是正交的(即使旋轉被稱為“正交”),所以不能簡單地計算數據在旋轉加載方向上的正交投影。

@FTusell 的回答假設 varimax 旋轉應用於特徵向量(而不是加載)。這將是非常不尋常的。詳情請看我的PCA+varimax詳解:PCA後跟一個旋轉(比如varimax)還是PCA嗎?簡而言之,如果我們看一下數據矩陣的 SVD,然後旋轉載荷意味著插入對於一些旋轉矩陣如下:

如果將旋轉應用於載荷(通常是這樣),那麼至少有三種簡單的方法可以在 R 中計算 varimax-rotated PCs:

  1. 它們很容易通過函數獲得psych::principal(證明這確實是標準方法)。請注意,它返回標準化分數,即所有 PC 都有單位方差。
  2. 可以手動使用varimax函數旋轉載荷,然後使用新旋轉的載荷得到分數;需要將數據與旋轉載荷的轉置偽逆相乘(參見@ttnphns 在此答案中的公式)。這也將產生標準化的分數。
  3. 可以使用varimax函數旋轉載荷,然後使用$rotmat旋轉矩陣旋轉得到的標準化分數prcomp

所有三種方法產生相同的結果:

irisX <- iris[,1:4]      # Iris data
ncomp <- 2

pca_iris_rotated <- psych::principal(irisX, rotate="varimax", nfactors=ncomp, scores=TRUE)
print(pca_iris_rotated$scores[1:5,])  # Scores returned by principal()

pca_iris        <- prcomp(irisX, center=T, scale=T)
rawLoadings     <- pca_iris$rotation[,1:ncomp] %*% diag(pca_iris$sdev, ncomp, ncomp)
rotatedLoadings <- varimax(rawLoadings)$loadings
invLoadings     <- t(pracma::pinv(rotatedLoadings))
scores          <- scale(irisX) %*% invLoadings
print(scores[1:5,])                   # Scores computed via rotated loadings

scores <- scale(pca_iris$x[,1:2]) %*% varimax(rawLoadings)$rotmat
print(scores[1:5,])                   # Scores computed via rotating the scores

這會產生三個相同的輸出:

1 -1.083475  0.9067262
2 -1.377536 -0.2648876
3 -1.419832  0.1165198
4 -1.471607 -0.1474634
5 -1.095296  1.0949536


注意: R 中的varimax函數默認使用normalize = TRUE, eps = 1e-5參數(參見文檔)。eps在將結果與 SPSS 等其他軟件進行比較時,可能需要更改這些參數(降低容差並註意 Kaiser 歸一化)。我感謝@GottfriedHelms 讓我注意到這一點。[注意:這些參數在傳遞給varimax函數時起作用,但在傳遞給psych::principal函數時不起作用。這似乎是一個將被修復的錯誤。]

引用自:https://stats.stackexchange.com/questions/59213

comments powered by Disqus