"Rotaciones" es un enfoque desarrollado en el análisis factorial; allí las rotaciones (como, por ejemplo, varimax) se aplican a las cargas , no a los vectores propios de la matriz de covarianza. Las cargas son vectores propios escalados por las raíces cuadradas de los valores propios respectivos. Después de la rotación varimax, los vectores de carga ya no son ortogonales (aunque la rotación se llama "ortogonal"), por lo que no se puede calcular simplemente las proyecciones ortogonales de los datos en las direcciones de carga rotadas.
La respuesta de @ FTusell supone que la rotación varimax se aplica a los vectores propios (no a las cargas). Esto sería bastante poco convencional. Consulte mi cuenta detallada de PCA + varimax para obtener más detalles: ¿PCA seguido de una rotación (como varimax) sigue siendo PCA? Brevemente, si miramos el SVD de la matriz de datos , entonces rotar las cargas significa insertar R R ⊤ para alguna matriz de rotación R de la siguiente manera: X = ( U R ) ( R ⊤ S V ⊤ ) .X=USV⊤RR⊤RX=(UR)(R⊤SV⊤).
Si la rotación se aplica a las cargas (como suele serlo), entonces hay al menos tres formas fáciles de calcular las PC rotadas con varimax en R:
Están fácilmente disponibles a través de la función psych::principal
(lo que demuestra que este es realmente el enfoque estándar). Tenga en cuenta que devuelve puntajes estandarizados , es decir, todas las PC tienen varianza unitaria.
Se puede usar manualmente la varimax
función para rotar las cargas, y luego usar las nuevas cargas rotadas para obtener los puntajes; uno necesita multiplicar los datos con el pseudoinverso inverso de las cargas rotadas (vea las fórmulas en esta respuesta de @ttnphns ). Esto también generará puntajes estandarizados.
Se puede usar la varimax
función para rotar las cargas, y luego usar la $rotmat
matriz de rotación para rotar los puntajes estandarizados obtenidos con prcomp
.
Los tres métodos producen el mismo resultado:
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
Esto produce tres salidas idénticas:
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
Nota: La varimax
función en R usa normalize = TRUE, eps = 1e-5
parámetros por defecto ( ver documentación ). Es posible que desee cambiar estos parámetros (disminuir la eps
tolerancia y ocuparse de la normalización de Kaiser) al comparar los resultados con otro software como SPSS. Agradezco a @GottfriedHelms por llamar mi atención sobre esto. [Nota: estos parámetros funcionan cuando se pasan a la varimax
función, pero no funcionan cuando se pasan a la psych::principal
función. Esto parece ser un error que se solucionará.]
principal
,prcomp
yprincomp
, pero las conclusiones de carga / estudio resultantes son muy diferentes entre sí. Por lo que entiendo, prcomp y princomp no devuelven puntajes ni cargas estandarizadas. Mi pregunta es: ¿cuál es el mejor enfoque? ¿Realmente quiero resultados estandarizados? ¿Nopca_iris <- prcomp(irisX, center=T, scale=T)
sigue mi códigovarimax(pca_iris$rotation)$loadings
tan correcto como el tuyo anterior?principal
procedimiento, que siempre se computa con Kaiser-normalization y eps = 1e-5. Hasta el momento no hay información, por qué en r-fiddle.org la versión funciona correctamente. Por lo tanto, deberíamos esperar actualizaciones, y debería eliminar todos los comentarios ahora obsoletos. ameba: sería bueno actualizar el comentario en su respuesta en consecuencia. Gracias por toda la cooperación!Necesita usar la matriz
$loadings
, no$rotmat
:La matriz
$rotmat
es la matriz ortogonal que produce las nuevas cargas de los no rotados.EDITAR a partir del 12 de febrero de 2015:
Como señala acertadamente a continuación @amoeba (consulte también su publicación anterior y otra publicación de @ttnphns ), esta respuesta no es correcta. Considere un matriz de datos X . La descomposición de valor singular es X = U S V T donde V tiene como sus columnas los (normalizado) vectores propios de X ' X . Ahora, una rotación es un cambio de coordenadas y equivale a escribir la igualdad anterior como: X = ( U S T ) ( T T V T )n×m X
En otras palabras, la solución que propuse solo es correcta en el caso particular en el que sería inútil y sin sentido.
Agradezco sinceramente a @amoeba por aclararme este asunto; He estado viviendo con este concepto erróneo durante años.
MÁS EDITAR 12 de febrero de 2015
fuente
psych::principal
. [Aparte de eso, edité su respuesta para insertar la escala, como se discutió en los comentarios anteriores.]Estaba buscando una solución que funcione para PCA realizada con ade4 .
Encuentre la función a continuación:
Creado el 14-01-2020 por el paquete reprex (v0.3.0)
¡Espero que esto ayude!
fuente