R에서 가변 최대 회전 주성분을 계산하는 방법은 무엇입니까?


13

25 개의 변수에서 PCA를 실행하고을 사용하여 상위 7 개의 PC를 선택했습니다 prcomp.

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

그런 다음 해당 구성 요소에서 varimax 회전을 수행했습니다.

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

이제 varimax는 PCA 회전 데이터를 (varimax 객체의 일부가 아니기 때문에-로딩 행렬과 회전 행렬 만) varimax 회전하고 싶습니다. 이 작업을 수행하려면 회전 행렬의 전치에 데이터의 전치를 곱하면이 작업을 수행 할 수 있습니다.

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

그러나 위의 행렬 전치의 크기가 각각 및 이므로 행이 아닌 행 의 행렬로 남을 것이므로 의미 가 없습니다. 내가 여기서 뭘 잘못하고 있거나 내 마지막 줄은 무엇입니까? 나중에 다시 바꾸어야합니까?7 × 16933 7 169337×77×16933716933

답변:


22

"회전"은 요인 분석에서 개발 된 접근 방식입니다. 공분산 행렬의 고유 벡터가 아닌 부하에 회전 (예 : varimax)이 적용됩니다 . 하중은 각 고유 값의 제곱근에 의해 스케일링 된 고유 벡터입니다. 바리 맥스 회전 후, 로딩 벡터는 더 이상 직교하지 않으며 (회전이 "직교"라고하더라도) 회전 된 로딩 방향으로의 데이터의 직교 투영을 단순히 계산할 수는 없다.

@FTusell의 답변은 가변 벡터 회전이 고유 벡터에 적용되는 것으로 가정합니다 (부하가 아닌). 이것은 매우 전통적인 일이 아닙니다. 자세한 내용은 PCA + varimax에 대한 자세한 설명을 참조하십시오. PCA와 회전 (varimax 등)이 여전히 PCA입니까? 요약하면, 우리는 데이터 행렬의 SVD 보면 후 삽입 로딩 수단을 회전, R R ⊤ 일부 회전 행렬 R 로서 다음과 같다 : X = ( U R ) ( R ⊤ S V ⊤ ) .X=USV⊤RR⊤RX=(UR)(R⊤SV⊤).

회전이 하중에 적용되는 경우 (보통 그대로), R에서 varimax-rotated PC를 계산하는 쉬운 세 가지 방법이 있습니다.

  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

참고 :varimax R 의 함수는 normalize = TRUE, eps = 1e-5기본적으로 매개 변수를 사용합니다 ( 문서 참조 ). eps결과를 SPSS와 같은 다른 소프트웨어와 비교할 때 이러한 매개 변수를 변경 ( 공차 감소 및 카이저 정규화 관리) 할 수 있습니다. 이 문제에 관심을 가져 주셔서 @GottfriedHelms에게 감사드립니다. [참고 :이 매개 변수는 varimax함수에 전달 될 때 작동하지만 함수에 전달 될 때는 작동하지 않습니다 psych::principal. 수정 될 버그 인 것 같습니다.]


1
나는 지금 이것을보고, 당신이 옳다고 생각합니다. 불일치의 원인을 추적하기 위해 원래 답변을 편집하거나 다른 답변을 추가합니다. 나는 당신과 @ttnphns가 매우 완전하고 이해하기 쉬운 답변을 좋아하여 책에서 일반적으로 찾을 수없는 자세한 설명을 제공했습니다.
— F. Tusell

@amoeba 나는 PCA + VARIMAX 사용을하려고하고 principal, prcomp하고 princomp있지만 결과 하중 / 연구의 결론은 서로 매우 다르다. 내가 이해하는 것에 대해 prcomp 및 princomp는 표준화 된 점수 또는 하중을 반환하지 않습니다. 내 질문은 : 가장 좋은 방법은 무엇입니까? 표준화 된 결과를 정말로 원합니까? 내 코드 pca_iris <- prcomp(irisX, center=T, scale=T)와 varimax(pca_iris$rotation)$loadings위의 코드가 맞지 않습니까?
— JMarcelino

@JMarcelino, 아니요, 코드는 로딩이 아닌 고유 벡터에서 varimax-rotation을 수행합니다. 이것은 varimax 회전이 일반적으로 이해되거나 적용되는 방식이 아닙니다.
— amoeba는 Reinstate Monica

1
X=USV⊤RR⊤RX=URR⊤SV⊤L=VSR/n−1T=URn−1
X=TL⊤.
XLT
T=X(L⊤)+=X(L+)⊤.

1
Revelle 교수의 관리자에 대한 답변을 받았습니다. principal항상 Kaiser 정규화 및 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 일 현재 수정 :

n×mX

X=USVT
VX′X
X=(UST)(TTVT)=U∗V∗
TV∗V∗U∗X(V∗)Tk<mkX
X≈(UkSk)(VkT)
X≈(UkSkTk)(TkTVkT)=Uk∗Vk∗
Vk∗k×nXVk∗그러나 @amoeba가 설명 한 솔루션 중 하나에 의지해야합니다.

즉, 내가 제안한 솔루션은 쓸모없고 무의미한 특정 경우에만 정확합니다.

이 문제를 명확하게 해주신 @amoeba에게 진심으로 감사드립니다. 나는이 오해와 함께 몇 년 동안 살고 있습니다.

SVLVSviTX (i=1,…,m)‖vi‖=1. 어느 쪽이든 내가 생각하는 것은 받아 들일 수 있으며, 사이의 모든 것 (biplot 분석에서와 같이).

추가 편집 2015 년 2 월 12 일

@amoeba가 지적한 것처럼 가 직사각형이지만 제안한 솔루션은 여전히 ​​수용 가능할 수 있습니다. 는 단위 행렬을 제공하고 . 그래서 그것은 모두 선호하는 점수의 정의에 달려 있습니다.Vk∗Vk∗(Vk∗)TX(Vk∗)T≈Uk∗


1
아 맞다. prcomp의 로딩을 "rotation"이라고 부르기 때문에 혼란스러워 도움을 더 잘 읽었을 것입니다. prcomp 메소드에서 "center = TRUE, scale = TRUE"를 사용하고 있기 때문에 데이터에 varimax $ loadings를 곱하기 전에 데이터를 중앙에 배치하고 스케일링해야합니까?
— Scott

1
예, 좋은 지적입니다. 제 실수입니다. 중심점은 점만 이동하는 것처럼 중요하지 않지만 스케일은 스케일링에 영향을 미치지 않는 주성분을 계산하는 데 사용 된 것과 동일해야합니다.
— F. Tusell

2
함수 팩 터널을 보지 않았다면 언급하지 않았을 것입니다. 주요 구성 요소가 아닌 요인 분석을 수행하지만 점수를 직접 반환합니다.
— F. Tusell

2
-1. 나는이 답변이 정확하지 않다고 생각하고 그것을 설명하기 위해 내 자신의 답변을 게시했습니다. 회전 하중에 대한 직교 투영으로 회전 점수를 얻을 수 없습니다 (더 이상 직교하지 않기 때문에). 정확한 점수를 얻는 가장 간단한 방법은를 사용하는 것 psych::principal입니다. [그 외에, 위의 의견에서 논의한 것처럼 스케일링을 삽입하기 위해 귀하의 답변을 편집했습니다.]
— amoeba는 Reinstate Monica가

1
미안 내 실수. 나는 의미 입니다 . 이제 바로 잡겠습니다. 그리고 ... 네, 이제 보았습니다. 에는 직교 열이 있으므로 여전히 단위 행렬을 얻을 수 있습니까? 그렇다면 나는 원래의 포스터를 잘못 인도하지 않았으므로 내 영혼에서 짐을 들어 올리십시오! k × n V ( T T k V T k ) ( V k T k )Vk∗k×nV(TkTVkT)(VkTk)
— F. Tusell 17

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에 작성

이 도움을 바랍니다!


답을 위해이 공간을 사용해야합니다.
— Michael R. Chernick

완전성에 대한 답변을 추가하는 것이 타당하다고 생각되었습니다. 이 질문과 마찬가지로 stackoverflow.com/questions/6862742/draw-a-circle-with-ggplot2 . 필요한 경우 제안을 드리겠습니다.
— Alain Danet

답 중 하나의 오류를 수정하는 것처럼 들리기 때문에 오해했습니다. 특정 소프트웨어 패키지 ad4에 추가 된 것으로 확인되었습니다. Cross Validated는 코드에 관한 질문이나 답변을 보지 않습니다. 스택 오버플로는 소프트웨어 문제가 해결되는 곳입니다.
— Michael R. Chernick
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.