"Rotations" est une approche développée en analyse factorielle; là des rotations (comme par exemple varimax) sont appliquées aux chargements , pas aux vecteurs propres de la matrice de covariance. Les charges sont des vecteurs propres mis à l'échelle par les racines carrées des valeurs propres respectives. Après la rotation varimax, les vecteurs de chargement ne sont plus orthogonaux (même si la rotation est appelée "orthogonale"), donc on ne peut pas simplement calculer des projections orthogonales des données sur les directions de chargement tournées.
@ La réponse de FTusell suppose que la rotation varimax est appliquée aux vecteurs propres (pas aux chargements). Ce serait assez peu conventionnel. Veuillez consulter mon compte rendu détaillé de PCA + varimax pour plus de détails: PCA suivi d'une rotation (comme varimax) est-il toujours PCA? En bref, si nous regardons la SVD de la matrice de données X=USV⊤ , alors faire tourner les chargements signifie insérer RR⊤ pour une matrice de rotation R comme suit: X=(UR)(R⊤SV⊤).
Si la rotation est appliquée aux chargements (comme c'est généralement le cas), il existe au moins trois façons simples de calculer les PC à rotation varimax dans R:
Ils sont facilement disponibles via la fonction psych::principal
(démontrant qu'il s'agit bien de l'approche standard). Notez qu'il renvoie des scores standardisés , c'est-à-dire que tous les PC ont une variance d'unité.
On peut utiliser manuellement la varimax
fonction pour faire pivoter les chargements, puis utiliser les nouveaux chargements tournés pour obtenir les scores; il faut multiplier les données avec le pseudo-inverse transposé des chargements tournés (voir formules dans cette réponse de @ttnphns ). Cela produira également des scores standardisés.
On peut utiliser la varimax
fonction pour faire pivoter les chargements, puis utiliser la $rotmat
matrice de rotation pour faire pivoter les scores standardisés obtenus avec prcomp
.
Les trois méthodes donnent le même résultat:
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
Cela donne trois sorties identiques:
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
Remarque: La varimax
fonction dans R utilise des normalize = TRUE, eps = 1e-5
paramètres par défaut ( voir la documentation ). On pourrait vouloir changer ces paramètres (diminuer la eps
tolérance et prendre soin de la normalisation de Kaiser) lors de la comparaison des résultats avec d'autres logiciels tels que SPSS. Je remercie @GottfriedHelms d'avoir porté cela à mon attention. [Remarque: ces paramètres fonctionnent lorsqu'ils sont transmis à la varimax
fonction, mais ne fonctionnent pas lorsqu'ils sont transmis à la psych::principal
fonction. Cela semble être un bug qui sera corrigé.]
principal
,prcomp
etprincomp
, mais les chargements résultants / conclusions de l'étude sont très différents les uns des autres. Pour ce que je comprends, prcomp et princomp ne renvoient pas de scores ni de charges standardisés. Ma question est: quelle est la meilleure approche? Est-ce que je veux vraiment des résultats standardisés? Mon code n'est-il paspca_iris <- prcomp(irisX, center=T, scale=T)
suivivarimax(pca_iris$rotation)$loadings
aussi correctement que le vôtre ci-dessus?principal
procédure, qui calcule toujours avec Kaiser-normalisation et eps = 1e-5. Il n'y a aucune information pour l'instant, pourquoi sur r-fiddle.org la version fonctionne correctement. Nous devons donc attendre les mises à jour - et je devrais supprimer tous les commentaires désormais obsolètes. amibe - il serait bon de mettre à jour la remarque dans votre réponse en conséquence. Merci pour toute la coopération!Vous devez utiliser la matrice
$loadings
, pas$rotmat
:La matrice
$rotmat
est la matrice orthogonale qui produit les nouveaux chargements à partir de ceux non tournés.EDIT au 12 février 2015:
Comme indiqué à juste titre ci-dessous par @amoeba (voir également son article précédent ainsi qu'un autre article de @ttnphns ), cette réponse n'est pas correcte. Considérons un matrice de données X . La décomposition en valeurs singulières est X = U S V T où V a pour colonnes (normalisé) les vecteurs propres de X ' X . Maintenant, une rotation est un changement de coordonnées et revient à écrire l'égalité ci-dessus comme: X = ( U S T ) ( T T V T )n×m X
En d'autres termes, la solution que j'ai proposée n'est correcte que dans le cas particulier où elle serait inutile et absurde.
Un grand merci à @amoeba pour m'avoir clarifié cette question; Je vis avec cette idée fausse depuis des années.
NOUVELLE MODIFICATION 12 février 2015
la source
psych::principal
. [En dehors de cela, j'ai modifié votre réponse pour insérer la mise à l'échelle, comme indiqué dans les commentaires ci-dessus.]Je cherchais une solution qui fonctionne pour PCA réalisée en utilisant ade4 .
Veuillez trouver la fonction ci-dessous:
Créé le 2020-01-14 par le package reprex (v0.3.0)
J'espère que cette aide!
la source