วิธีการคำนวณส่วนประกอบหลักหมุน varimax ใน R?


13

ฉันวิ่ง PCA เมื่อวันที่ 25 ตัวแปรและเลือกด้านบน 7 prcompเครื่องคอมพิวเตอร์ใช้

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

ฉันได้ทำการหมุน varimax กับส่วนประกอบเหล่านั้นแล้ว

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

และตอนนี้ฉันต้องการ varimax หมุนข้อมูลที่หมุน PCA (เนื่องจากไม่ได้เป็นส่วนหนึ่งของวัตถุ varimax - เฉพาะเมทริกซ์การโหลดและเมทริกซ์การหมุน) ฉันอ่านว่าการทำเช่นนี้คุณคูณทรานสปอนของเมทริกซ์การหมุนโดยทรานสโพสของข้อมูลดังนั้นฉันจะทำสิ่งนี้:

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

แต่นั่นก็ไม่สมเหตุสมผลเนื่องจากขนาดของเมทริกซ์ทรานส์ข้างต้นคือคูณและตามลำดับดังนั้นฉันจะเหลือเมทริกซ์เพียงแถวแทนที่จะเป็นแถว ... ไม่มีใครรู้ สิ่งที่ฉันทำผิดที่นี่หรือสิ่งสุดท้ายของฉันควรเป็นอย่างไร ฉันต้องเปลี่ยนกลับในภายหลังไหม?7×77 169337×16933716933

คำตอบ:


22

"การหมุน" เป็นวิธีการที่พัฒนาขึ้นในการวิเคราะห์ปัจจัย มีการหมุน (เช่น e กรัม varimax) ถูกนำไปใช้กับการโหลดไม่ใช่ eigenvectors ของเมทริกซ์ความแปรปรวนร่วม การรับน้ำหนักจะถูกปรับขนาดด้วยค่ารากที่สองของค่าลักษณะเฉพาะ หลังจากการหมุน varimax เวกเตอร์การโหลดจะไม่เป็นมุมฉากอีกต่อไป (แม้ว่าการหมุนจะเรียกว่า "orthogonal") ดังนั้นเราจึงไม่สามารถคำนวณการประมาณมุมฉากของข้อมูลบนทิศทางการโหลดแบบหมุนได้

@ คำตอบของ FTusell สมมติว่าการหมุน varimax นั้นถูกนำไปใช้กับ eigenvector (ไม่ใช่การโหลด) นี่คงจะแปลกแหวกแนว โปรดดูรายละเอียดบัญชี PCA + varimax ของฉันสำหรับรายละเอียด: PCA ตามด้วยการหมุน (เช่น varimax) ยังเป็น PCA หรือไม่ สั้น ๆ ถ้าเราดู SVD ของ data matrixการหมุน loadings หมายถึงการแทรกสำหรับเมทริกซ์การหมุนบางตัวดังนี้ : R R R X = ( U R ) ( R S V )X=USVRRRX=(UR)(RSV).

หากการหมุนถูกนำไปใช้กับการโหลด (ตามปกติแล้ว) มีวิธีง่าย ๆ อย่างน้อยสามวิธีในการคำนวณพีซีแบบหมุนรอบตัว varimax ใน R:

  1. พวกเขาพร้อมใช้งานผ่านฟังก์ชั่นpsych::principal(แสดงให้เห็นว่านี่เป็นแนวทางมาตรฐาน) โปรดทราบว่ามันส่งคืนคะแนนมาตรฐานเช่นพีซีทุกเครื่องมีความแปรปรวนของหน่วย

  2. หนึ่งสามารถใช้varimaxฟังก์ชั่นเพื่อหมุนการโหลดด้วยตนเองแล้วใช้การโหลดแบบหมุนใหม่เพื่อให้ได้คะแนน; เราต้องการข้อมูลจำนวนมากด้วยการหลอก - ผกผันของการโหลดแบบหมุน (ดูสูตรในคำตอบนี้โดย @ttnphns ) สิ่งนี้จะทำให้ได้คะแนนมาตรฐาน

  3. หนึ่งสามารถใช้varimaxฟังก์ชั่นการหมุนแรงแล้วใช้เมทริกซ์หมุนหมุนคะแนนมาตรฐานที่ได้รับด้วย$rotmatprcomp

ทั้งสามวิธีให้ผลลัพธ์เหมือนกัน:

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ฟังก์ชั่นในการวิจัยใช้normalize = TRUE, eps = 1e-5พารามิเตอร์โดยค่าเริ่มต้น ( ดูเอกสารประกอบ ) หนึ่งอาจต้องการเปลี่ยนพารามิเตอร์เหล่านี้ (ลดepsความอดทนและดูแล Kaiser normalization) เมื่อเปรียบเทียบผลลัพธ์กับซอฟต์แวร์อื่นเช่น SPSS ฉันขอบคุณ @GottfriedHelms ที่ทำให้สิ่งนี้เป็นที่สนใจของฉัน [หมายเหตุ: พารามิเตอร์เหล่านี้จะทำงานเมื่อผ่านไปยังvarimaxฟังก์ชั่น แต่ไม่ทำงานเมื่อส่งผ่านไปยังpsych::principalฟังก์ชั่น ดูเหมือนว่านี่เป็นข้อบกพร่องที่จะได้รับการแก้ไข]


1
ฉันเห็นสิ่งนี้แล้วและฉันคิดว่าคุณถูกต้อง ฉันจะแก้ไขคำตอบดั้งเดิมของฉัน (หรือเพิ่มอีกคำตอบ) เพื่อติดตามแหล่งที่มาของความคลาดเคลื่อน ฉันชอบคำตอบของคุณและ @ttnphns ที่สมบูรณ์แบบมากและให้คำอธิบายที่ละเอียดอ่อนโดยให้คำอธิบายโดยละเอียดที่มักไม่พบในหนังสือ
F. Tusell

@amoeba ฉันกำลังพยายามที่จะทำ PCA A + VariMax ใช้principal, prcompและprincompแต่ส่งผลให้ภาระ / ข้อสรุปการศึกษามีความแตกต่างจากคนอื่น ๆ สำหรับสิ่งที่ฉันเข้าใจ prcomp และ princomp จะไม่ส่งคืนคะแนนหรือโหลดมาตรฐาน คำถามของฉันคืออะไรวิธีที่ดีที่สุดคืออะไร ฉันต้องการผลลัพธ์ที่ได้มาตรฐานหรือไม่ ไม่ได้รหัสของฉันpca_iris <- prcomp(irisX, center=T, scale=T)ตามมาด้วยการvarimax(pca_iris$rotation)$loadingsเป็นที่ถูกต้องเป็นของคุณไป?
JMarcelino

@ J.Marcelino, ไม่, โค้ดของคุณใช้การหมุน varimax บน eigenvector ไม่ใช่การโหลด นี่ไม่ใช่วิธีการเข้าใจหรือใช้การหมุน varimax
อะมีบาพูดว่า Reinstate Monica

1
@JMarcelino คุณถามว่าทำไมคณิตศาสตร์ถึงทำงานเหมือนที่ฉันพูดในวิธี # 2 มันง่ายถ้าคุณคุ้นเคยกับพีชคณิตเชิงเส้นประเภทนี้ PCA เป็น SVD สลายตัวXการประยุกต์ใช้การหมุนเช่น VariMax วิธีการใส่สำหรับการหมุนเมทริกซ์ดังนี้SV การโหลดแบบหมุนคือ , คะแนนมาตรฐานแบบหมุนคือ , ดังนั้นคุณรู้จักและ ; วิธีการที่จะได้รับ ? คำตอบคือ R R R X = U R R S V L = V S R / X=USVRRRX=URRSV T=URL=VSR/n1T=URn1
X=TL.
XLT
T=X(L)+=X(L+).
อะมีบาพูดว่า Reinstate Monica

1
ฉันได้รับคำตอบจากผู้ดูแลแพคเกจ Prof. Revelle ดูเหมือนว่าจะเป็นข้อบกพร่องในการจัดการพารามิเตอร์ในprincipalกระบวนการซึ่งมักจะคำนวณด้วย Kaiser-normalization และ eps = 1e-5 ยังไม่มีข้อมูลว่าทำไมบน r-fiddle.org รุ่นจึงทำงานได้อย่างถูกต้อง ดังนั้นเราควรรอการอัปเดต - และฉันควรลบความคิดเห็นที่ล้าสมัยแล้วทั้งหมด อะมีบา - มันเป็นการดีที่จะปรับปรุงหมายเหตุในคำตอบของคุณตาม ขอบคุณสำหรับความร่วมมือ!
หมวกกัน

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เป็นเมทริกซ์มุมฉากที่สร้างแรงกระทำใหม่จากวัตถุที่ไม่ได้หมุน

แก้ไข ณ วันที่ 12 ก.พ. 2558:

เป็นแหลมที่ถูกต้องด้านล่างโดย @amoeba (เห็นของเขา / เธอโพสต์ก่อนหน้านี้เช่นเดียวกับการโพสต์อื่นจาก @ttnphns ) คำตอบนี้ไม่ถูกต้อง พิจารณา Data Matrix Xการสลายตัวมูลค่าเอกพจน์คือ ที่มีคอลัมน์ของตน (ปกติ) eigenvectors ของX'Xตอนนี้การหมุนคือการเปลี่ยนแปลงของพิกัดและจำนวนการเขียนความเท่าเทียมกันข้างต้นเป็น: โดยเป็นเมทริกซ์มุมฉากที่เลือกเพื่อให้ได้ใกล้กระจัดกระจาย (ความแตกต่างสูงสุดระหว่างรายการพูดอย่างหลวม ๆ ) ทีนี้ถ้านั่นคือทั้งหมดn×mX

X=USVT
VXX
X=(UST)(TTVT)=UV
TVซึ่งไม่ใช่ใครสามารถโพสต์คูณความเท่าเทียมกันข้างต้นโดยเพื่อให้ได้คะแนนเป็นแต่แน่นอนเราไม่เคยหมุนพีซีทั้งหมด แต่เราพิจารณาเซตของซึ่งมียังคงดี rank-ประมาณของ , ดังนั้นวิธีการแก้ปัญหาที่หมุนอยู่ในขณะนี้ โดยที่ตอนนี้คือเมทริกซ์เราไม่สามารถคูณเพียงอย่างเดียวได้ด้วยการเปลี่ยนแต่เราต้องหันไปใช้วิธีแก้ปัญหาที่อธิบายโดย @amoebaVUX(V)Tk<mkXX(UkSkTk)(T T k V T k )=Uk Vk Vk k×nXVk
X(UkSk)(VkT)
X(UkSkTk)(TkTVkT)=UkVk
Vkk×nXVk

กล่าวอีกนัยหนึ่งวิธีแก้ปัญหาที่ฉันเสนอนั้นถูกต้องเฉพาะในกรณีที่ไม่มีประโยชน์และไร้สาระ

ขอบคุณอย่างจริงใจไปที่ @amoeba เพื่อชี้แจงเรื่องนี้ให้ฉันฟัง ฉันใช้ชีวิตอยู่กับความเข้าใจผิดมาหลายปีแล้ว

จุดหนึ่งที่ทราบข้างต้นออกจาก @ อะมีบาของการโพสต์ก็คือเธอ / เขาดูเหมือนว่าจะร่วมกับในLฉันคิดว่าใน PCA เป็นเรื่องธรรมดาที่จะมีคอลัมน์ปกติของและดูดซับในค่าขององค์ประกอบหลัก ในความเป็นจริงมักเหล่านั้นจะถูกนำเสนอเป็นเชิงเส้นรวมกันของเดิม (ศูนย์กลางอาจจะลดขนาด) ตัวแปรที่อาจมีการ 1 ฉันคิดว่าวิธีใดเป็นที่ยอมรับและทุกสิ่งในระหว่าง (เช่นในการวิเคราะห์ biplot)SVLVSviTX (i=1,,m)vi=1

แก้ไขเพิ่มเติมเมื่อวันที่ 12 กุมภาพันธ์ 2015

ตามที่ระบุโดย @amoeba ถึงแม้ว่าเป็นรูปสี่เหลี่ยมผืนผ้าวิธีแก้ปัญหาที่ฉันเสนออาจยังคงเป็นที่ยอมรับได้:จะให้เมทริกซ์หน่วยและ * ดังนั้นทุกอย่างดูเหมือนจะขึ้นอยู่กับความหมายของคะแนนที่เราชอบ V k ( V k ) T X ( V k ) TU kVkVk(Vk)TX(Vk)TUk


1
อ่าใช่ไหม ฉันสับสนเพราะการโหลดสำหรับ prcomp เรียกว่า "การหมุน" ควรอ่านความช่วยเหลือดีกว่า เนื่องจากฉันใช้ "center = TRUE, scale = TRUE" ในวิธีการ prcomp หมายความว่าฉันควรจะอยู่ตรงกลางและปรับขนาดข้อมูลของฉันก่อนที่จะคูณด้วยการโหลด varimax $ ของฉัน
สกอตต์

1
ใช่จุดดีความผิดพลาดของฉัน การจัดกึ่งกลางจะไม่สำคัญหากเพียง แต่เปลี่ยนคะแนน แต่สเกลควรใช้ในการคำนวณส่วนประกอบหลักซึ่งไม่แปรเปลี่ยนไปจากการปรับสเกล
F. Tusell

2
ฉันลืมที่จะพูดถึงว่าคุณอาจต้องการดูฟังก์ชั่น factanal ถ้าคุณยังไม่ได้ทำมัน มันวิเคราะห์ปัจจัยมากกว่าองค์ประกอบหลัก แต่จะส่งคืนคะแนนโดยตรง
F. Tusell

2
-1 ฉันเชื่อว่าคำตอบนี้ไม่ถูกต้องและฉันโพสต์คำตอบของตัวเองเพื่อแสดงให้เห็น หนึ่งไม่สามารถรับคะแนนหมุนได้โดยการฉายฉากมุมฉากกับโหลดที่หมุน (เพราะพวกเขาไม่ใช่มุมฉากอีกต่อไป) psych::principalวิธีที่ง่ายที่สุดที่จะได้รับคะแนนที่ถูกต้องคือการใช้งาน [นอกจากนั้นฉันได้แก้ไขคำตอบของคุณเพื่อแทรกมาตราส่วนดังที่กล่าวไว้ในความคิดเห็นข้างต้น]
อะมีบาพูดว่า Reinstate Monica

1
ขอโทษฉันไม่ดี ฉันหมายถึงเป็นn ฉันจะแก้ไขให้ถูกต้องแล้ว และ ... ใช่ตอนนี้ที่ฉันดูแล้วมีคอลัมน์มุมฉากดังนั้นจะยังได้เมทริกซ์หน่วยมาให้เราใช่ไหม ถ้าเป็นเช่นนั้นฉันไม่ได้เข้าใจผิดโปสเตอร์ต้นฉบับคุณยกภาระจากจิตวิญญาณของฉัน! k × n V ( T T k V T k ) ( V k T k )Vkk×nV(TkTVkT)(VkTk)
F. Tusell

0

ผมกำลังมองหาวิธีการแก้ปัญหาที่ทำงานสำหรับ PCA ดำเนินการโดยใช้ade4

กรุณาค้นหาฟังก์ชั่นด้านล่าง:

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

สร้างเมื่อ 2020-01-14 โดยแพ็คเกจ reprex (v0.3.0)

หวังว่าจะช่วยได้!


คุณต้องใช้พื้นที่นี้สำหรับคำตอบ
Michael R. Chernick

ฉันคิดว่ามันถูกต้องแล้วที่จะเพิ่มคำตอบเพื่อความสมบูรณ์ ไลค์สำหรับคำถามนี้: stackoverflow.com/questions/6862742/draw-a-circle-with-ggplot2 ฉันยินดีที่จะย้ายข้อเสนอหากจำเป็น
Alain Danet

ฉันเข้าใจผิดเพราะฟังดูเหมือนว่าคุณกำลังแก้ไขข้อผิดพลาดในหนึ่งในคำตอบ ฉันเห็นว่ามันเป็นส่วนเสริมสำหรับแพคเกจซอฟต์แวร์ ad4 โดยเฉพาะ การตรวจสอบข้ามไม่ได้ดูคำถามหรือคำตอบที่เกี่ยวกับรหัสอย่างเคร่งครัด Stack Overflow เป็นที่ที่ปัญหาซอฟต์แวร์ถูกแก้ไข
Michael R. Chernick
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.