Rのバリマックス回転主成分を計算する方法は?


13

25個の変数でPCAを実行し、を使用して上位7台のPCを選択しましたprcomp

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

次に、これらのコンポーネントでバリマックス回転を行いました。

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

そして今、私はvarimaxがPCAで回転されたデータを回転させたいと思っています(これはvarimaxオブジェクトの一部ではなく、負荷行列と回転行列のみです)。これを行うには、回転行列の転置にデータの転置を乗算することを読んだので、これを行っていました:

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

しかし、上記の行列転置の次元はそれぞれおよびあるため、それは意味がありません。したがって、行ではなく、行のみの行列がます。ここで私が間違っていることや、最終的な行はどうなりますか?後で転置するだけですか?7 × 16933 7 169337×77×16933716933

回答:


22

「回転」は、因子分析で開発されたアプローチです。共分散行列の固有ベクトルではなく、負荷(例えばvarimaxなど)に回転が適用されます。負荷は、それぞれの固有値の平方根でスケーリングされた固有ベクトルです。バリマックス回転後、ロードベクトルは(回転が「直交」と呼ばれる場合でも)直交しなくなるため、回転したロード方向へのデータの直交投影を単純に計算することはできません。

@FTusellの答えは、バリマックス回転が固有ベクトル(負荷ではなく)に適用されることを前提としています。これはかなり型破りです。詳細については、PCA + varimaxの詳細な説明を参照してください。PCAの後にローテーション(varimaxなど)が続いていますか?簡単に言えば、データ行列のSVDを見ると、負荷を回転させることは挿入することを意味します R R X=USVRR一部回転行列のための次のようにX = U R R SのV RX=(UR)(RSV).

回転が負荷に適用される場合(通常どおり)、Rでバリマックス回転PCを計算するための少なくとも3つの簡単な方法があります。

  1. 関数を介して簡単に利用できますpsych::principal(これが実際に標準的なアプローチであることを示しています)。標準化されたスコアを返すことに注意してください。つまり、すべてのPCに単位分散があります。

  2. 手動でvarimax関数を使用して負荷を回転させてから、新しい回転負荷を使用してスコアを取得できます。回転された負荷の転置された擬似逆数でデータを多重化する必要があります(@ttnphnsによるこの回答の参照)。これにより、標準化されたスコアも得られます。

  3. varimax関数を使用して負荷を回転させ、次に$rotmat回転行列を使用してで取得した標準化されたスコアを回転させることができprcompます。

3つの方法はすべて同じ結果をもたらします。

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

これにより、3つの同一の出力が生成されます。

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

注:varimax R の関数はnormalize = TRUE, eps = 1e-5デフォルトでパラメーターを使用します(ドキュメントを参照)。eps結果をSPSSなどの他のソフトウェアと比較するときに、これらのパラメーターを変更する(許容値を下げてKaiser正規化を処理する)こともできます。@GottfriedHelmsにこれを知らせてくれたことに感謝します。[注:これらのパラメーターは、varimax関数に渡されるとpsych::principal機能しますが、関数に渡されると機能しません。これは修正されるバグのようです。]


1
私は今これを見て、あなたが正しいと思う。元の回答を編集(または別の回答を追加)して、不一致の原因を追跡します。私はあなたの、そして@ttnphnsが非常に完全で、啓発的な答えが好きで、通常は本にはない詳細な説明を提供しました。
F.チューセル

@amoeba principalprcompおよびを使用してPCA +バリマックスを実行しようとしていますprincompが、結果の負荷/研究の結論は互いに非常に異なります。私の理解では、prcompとprincompは標準化されたスコアも負荷も返しません。私の質問は、最良のアプローチは何ですか?標準化された結果が本当に必要ですか?上記のコードのように私のコードのpca_iris <- prcomp(irisX, center=T, scale=T)後にvarimax(pca_iris$rotation)$loadings正しいものはありませんか?
-JMarcelino

@JMarcelino、いいえ、あなたのコードは負荷ではなく、固有ベクトルでバリマックス回転を行います。これは、バリマックス回転が通常理解または適用される方法ではありません。
アメーバは、モニカを

1
@JMarcelino、メソッド#2で言うように、数学がなぜ機能するのかと尋ねていますか?この種の線形代数に精通していれば簡単です。PCAは、SVD分解である。このようなバリマックス手段を挿入するように回転を適用R R するA回転行列Rとして、以下:X = U R R S Vを。回転荷重はL = V S R / X=USVRRRX=URRSV、標準化スコアである回転T=URL=VSR/n1、そうX=TLXLを知っています。どのように取得するにはTを?まあ、答えはT=XL+=XL+T=URn1
バツ=TL
バツLT
T=バツL+=バツL+
アメーバは、モニカを復活させる

1
Revelle教授のパッケージのメンテナーから回答を得ました。これは、principalプロシージャ内のパラメータの処理にバグがあるようです。これは、常にカイザー正規化とeps = 1e-5で計算されます。これまでのところ、r-fiddle.orgでバージョンが正しく機能する理由はありません。したがって、更新を待つ必要があります-そして、今では廃止されたコメントをすべて削除する必要があります。amoeba-回答の備考を適宜更新するとよいでしょう。すべての協力に感謝します!
ゴットフリードヘルムズ

9

あなたは、マトリックスを使用する必要は $loadings、ありません$rotmat

 x <- matrix(rnorm(600),60,10)
 prc <- prcomp(x, center=TRUE, scale=TRUE)
 varimax7 <- varimax(prc$rotation[,1:7])
 newData <- scale(x) %*% varimax7$loadings

行列$rotmatは、回転していないものから新しい負荷を生成する直交行列です。

2015年2月12日現在の編集:

以下で@amoebaが正しく指摘しているように(彼の以前の投稿@ttnphnsからの別の投稿も参照)、この答えは正しくありません。データ行列Xを考えます。特異値分解は X = U S V Tです。ここで、Vは列として(正規化された)X Xの固有ベクトルを持ちます。さて、回転は座標の変化であり、上記の等式を次のように書くことになります: X = U S T T T V Tn×mバツ

バツ=うんSVT
Vバツバツ Tを達成するように選択された直交行列である Vを*疎に近い(エントリ間の最大コントラスト、緩く言えば)。さて、それがすべてではない場合、上記の等式に V をポスト乗算してスコア U X V Tとして取得できますが、もちろんすべてのPCを回転させることはできません。むしろ、我々はのサブセット考える K < M、まだまともなrank-提供して k個の近似値 X Xを
バツ=うんSTTTVT=うんV
TVVうんバツVTk<mkバツ ので、回転解決する今 X U K S K T KT T K V TのK= U * k個の V * K V * kがあり、kは× n行列。X V kの転置を単純に掛けることはできません
バツうんkSkVkT
バツうんkSkTkTkTVkT=うんkVk
Vkk×nバツVk、しかし、@ amoebaで説明されているソリューションの1つに頼る必要があります。

言い換えれば、私が提案した解決策は、役に立たず無意味な特定の場合にのみ正しいものです。

この問題を明確にしてくれた@amoebaに心から感謝します。私は何年もの間、この誤解に生きてきました。

SVLVSvTバツ =1mv=1。どちらの方法も受け入れられると思いますし、その間にあるすべてのものは(バイプロット分析のように)。

さらなる編集2015年2月12日

VkVkVkTバツVkTうんk


1
ああ右グランド。prcompのロードは「回転」と呼ばれ、ヘルプをよりよく読んでいるはずなので、混乱しました。prcompメソッドで "center = TRUE、scale = TRUE"を使用しているので、データをvarimax $ loadingsで乗算する前に、実際にデータをセンタリングおよびスケーリングする必要があるということですか?
スコット

1
はい、良い点、私の間違い。センタリングは、ポイントをシフトするだけのように重要ではありませんが、スケールは不変ではない主成分の計算に使用されるものと同じでなければなりません。
F.チューセル

2
まだ行っていない場合は、関数の事実を見たいと思うことを忘れていました。主成分ではなく因子分析を行いますが、スコアを直接返します。
F. Tusell

2
-1。この答えは正しくないと思うので、それを示すために自分の答えを投稿しました。回転した負荷の直交射影によって回転したスコアを取得することはできません(それらはもはや直交していないため)。正しいスコアを取得する最も簡単な方法は、を使用することpsych::principalです。[それとは別に、上記のコメントで説明したように、スケーリングを挿入するようにあなたの答えを編集しました。]
アメーバは、Reinstate Monica

1
Vkk×nVTkTVkTVkTk

0

ade4を使用して実行されるPCAで機能するソリューションを探していました。

以下の機能を見つけてください:

library(ade4)

irisX <- iris[,1:4]      # Iris data
ncomp <- 2
# With ade4
dudi_iris <- dudi.pca(irisX, scannf = FALSE, nf = ncomp)

rotate_dudi.pca <- function(pca, ncomp = 2) {

  rawLoadings <- as.matrix(pca$c1[,1:ncomp]) %*% diag(sqrt(pca$eig), ncomp, ncomp)
  pca$c1 <- rawLoadings
  pca$li <- scale(pca$li[,1:ncomp]) %*% varimax(rawLoadings)$rotmat

  return(pca)
} 
rot_iris <- rotate_dudi.pca(pca = dudi_iris, ncomp = ncomp)
print(rot_iris$li[1:5,])                   # Scores computed via rotating the scores
#>        [,1]       [,2]
#> 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

reprexパッケージ(v0.3.0)によって2020-01-14に作成

この助けを願っています!


このスペースを回答に使用する必要があります。
マイケルR.チャーニック

完全を期すために答えを追加することは妥当であるように思えました。この質問のように:stackoverflow.com/questions/6862742/draw-a-circle-with-ggplot2。必要に応じて提案を移動させていただきます。
アランダネット

あなたが答えの1つでエラーを修正したように聞こえたので、私は誤解しました。特定のソフトウェアパッケージad4の追加であることがわかります。相互検証では、厳密にコードに関する質問や回答は調べません。スタックオーバーフローは、ソフトウェアの問題に対処する場所です。
マイケルR.チャーニック
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.