ฉันได้รับการโหลดที่“ น่ากลัว” ใน rollapply PCA ใน R. ฉันจะแก้ไขได้ไหม?


20

ฉันมีข้อมูลส่งคืน 10 ปีต่อวันสำหรับ 28 สกุลเงินที่แตกต่างกัน ฉันต้องการแยกส่วนประกอบหลักตัวแรก แต่แทนที่จะใช้งาน PCA ตลอดทั้ง 10 ปีฉันต้องการเปิดหน้าต่างใหม่ 2 ปีเพราะพฤติกรรมของสกุลเงินมีวิวัฒนาการและฉันต้องการสะท้อนสิ่งนี้ อย่างไรก็ตามฉันมีปัญหาที่สำคัญนั่นคือทั้งฟังก์ชั่น princomp () และ prcomp () มักจะกระโดดจากการโหลดเชิงบวกถึงเชิงลบในการวิเคราะห์ PCA ที่อยู่ติดกัน (เช่น 1 วันห่างกัน) ดูแผนภูมิการโหลดสำหรับสกุลเงิน EUR:

ป้อนคำอธิบายรูปภาพที่นี่

เห็นได้ชัดว่าฉันไม่สามารถใช้สิ่งนี้ได้เพราะการโหลดที่อยู่ติดกันจะกระโดดจากบวกเป็นลบดังนั้นซีรี่ส์ของฉันที่ใช้มันจะผิดพลาด ตอนนี้มาดูค่าสัมบูรณ์ของการโหลดสกุลเงิน EUR:

ป้อนคำอธิบายรูปภาพที่นี่

ปัญหาคือแน่นอนว่าฉันยังไม่สามารถใช้สิ่งนี้ได้เพราะคุณสามารถเห็นได้จากแผนภูมิด้านบนว่าการโหลดนั้นไปจากเชิงลบเป็นบวกและย้อนกลับไปในบางครั้งซึ่งเป็นลักษณะที่ฉันต้องรักษาไว้

มีวิธีใดบ้างที่ฉันสามารถแก้ไขปัญหานี้ได้ ฉันสามารถบังคับให้การปฐมนิเทศ eigenvector เหมือนกันใน PCAs ที่อยู่ติดกันได้หรือไม่

โดยวิธีการที่ปัญหานี้เกิดขึ้นกับฟังก์ชั่น FactoMineR () รหัสสำหรับ rollapply อยู่ที่นี่:

rollapply(retmat, windowl, function(x) summary(princomp(x))$loadings[, 1], by.column = FALSE, align = "right") -> princomproll

3
คุณสามารถอธิบายสิ่งที่คุณหมายถึงโดย "ปฐมนิเทศ" eigenvector? เท่าที่ฉันรู้ไม่มีสิ่งนั้นอยู่ในตัวของข้อมูล (นั่นเป็นเหตุผลหนึ่งว่าทำไมซอฟต์แวร์ที่แตกต่างกันจะสร้างไอเก็นนักประสาทวิทยาที่มีมาตรฐานต่างกัน) ดังนั้นดูเหมือนว่าคุณกำลังถามหาบางสิ่งที่ไม่มีอยู่จริงและไร้ความหมาย
whuber

1
วันหนึ่งฉันจะได้รับการโหลดเช่นนี้: EUR -0.2 ZAR +0.8 USD +0.41 ..... 28 สกุลเงิน และในวันถัดไปฉันจะได้รับ EUR +0.21 ZAR -0.79 USD -0.4 ฯลฯ ดังนั้นแกนที่ PCA ได้เลือกที่จะหมุนข้อมูลไปยังจะถูกวางตรงข้ามในวันที่ 2 เมื่อเทียบกับวันที่ 1 การโหลดกระโดดเหล่านี้และฉันต้องการหลีกเลี่ยงมันอย่างใด ...... ขอโทษถ้าคำศัพท์ของฉันทำให้เข้าใจผิด ฉันเข้าใจว่ารหัส PCA ไม่ได้สนใจเรื่องการวางแนวแกนตราบใดที่มันสอดคล้องกันในการโหลดในหนึ่งวันแต่ฉันต้องการให้มันสอดคล้องกันในหลายวัน
โทมัสบราวน์

1
โปรดจำไว้ว่าจากวันหนึ่งไปยังอีกวันหนึ่งเนื่องจากมีข้อมูลย้อนกลับ 2 ปีเราควรมี PCA ที่คล้ายกันมาก
โทมัสบราวน์

ฉันคิดว่าเหตุผลที่คุณมีปัญหาก็คือความคิดที่คลาดเคลื่อนนี้ไม่สมเหตุสมผล ฉันไม่มีวิธีการอื่นนอกจากค้นหาสิ่งที่แตกต่างที่อาจบรรลุเป้าหมายของคุณ (ไม่แน่ใจว่าพวกเขาคืออะไร) และมีเหตุผล
Michael R. Chernick

EUR -0.2 ZAR +0.8 USD +0.41และEUR +0.21 ZAR -0.79 USD -0.4 มีลักษณะคล้ายกันมากมาก คุณเพียงแค่ย้อนกลับเข้าสู่ผลลัพธ์ใด ๆ ของทั้งสอง
ttnphns

คำตอบ:


22

เมื่อใดก็ตามที่พล็อตกระโดดมากเกินไปให้กลับการวางแนว เกณฑ์หนึ่งที่มีประสิทธิภาพคือ: คำนวณจำนวนการกระโดดทั้งหมดของส่วนประกอบทั้งหมด คำนวณจำนวนการกระโดดทั้งหมดถ้า eigenvector ตัวต่อไปถูกทำให้ไร้ผล หากหลังน้อยกว่าลบล้างไอเก็กนักแสดงคนต่อไป

นี่คือการดำเนินการ (ฉันไม่คุ้นเคยzooซึ่งอาจช่วยแก้ปัญหาได้ดีกว่า)

require(zoo)
amend <- function(result) {
  result.m <- as.matrix(result)
  n <- dim(result.m)[1]
  delta <- apply(abs(result.m[-1,] - result.m[-n,]), 1, sum)
  delta.1 <- apply(abs(result.m[-1,] + result.m[-n,]), 1, sum)
  signs <- c(1, cumprod(rep(-1, n-1) ^ (delta.1 <= delta)))
  zoo(result * signs)
}

ตัวอย่างเช่นให้ลองเดินสุ่มในกลุ่มฉากและสั่นเทาเล็กน้อยเพื่อความสนใจ:

random.rotation <- function(eps) {
  theta <- rnorm(3, sd=eps)
  matrix(c(1, theta[1:2], -theta[1], 1, theta[3], -theta[2:3], 1), 3)
}
set.seed(17)
n.times <- 1000
x <- matrix(1., nrow=n.times, ncol=3)
for (i in 2:n.times) {
  x[i,] <- random.rotation(.05) %*% x[i-1,]
}

นี่คือ PCA ที่มีการหมุน:

window <- 31
data <- zoo(x)
result <- rollapply(data, window, 
  function(x) summary(princomp(x))$loadings[, 1], by.column = FALSE, align = "right")
plot(result)

เป็นต้นฉบับ

ตอนนี้รุ่นคงที่:

plot(amend(result))

แก้ไขเพิ่มเติม


เสื้อผมโวลต์ผม+1ผม+1โวลต์ผมผม1-1vi+1. อัลกอริทึมของคุณดูเหมือนจะแตกต่างกันเล็กน้อย มันจะทำงานแบบเดียวกันได้ไหม?
อะมีบากล่าวว่า Reinstate Monica

@ amoeba แม้ว่าฉันจะไม่แน่ใจว่าสิ่งที่คุณกำลังทำมันฟังดูเหมือนความคิดบางอย่างที่กล่าวถึงในคำตอบของ David J. Harris และความคิดเห็นที่ตามมา ดูโดยเฉพาะอย่างยิ่งความคิดเห็นของฉันที่stats.stackexchange.com/questions/34396/...
whuber

2
@Art ดังนั้นเมื่อฉันเข้าใจแล้วคุณต้องการแก้ไขสัญลักษณ์ของส่วนประกอบตามการตั้งค่าภายนอก (ภายนอกไปยัง PCA) นี่เป็นเรื่องปกติ แต่นั่นเป็นวิธีที่คุณควรเข้าใกล้ ขั้นแรกให้ทำสิ่งที่เลื่อน PCA ตรวจสอบให้แน่ใจว่าสัญญาณมีความสอดคล้อง แล้วตัดสินใจตามเกณฑ์เพิ่มเติมบางประการไม่ว่าจะพลิกองค์ประกอบทั้งหมดหรือไม่ เช่นคุณสามารถสร้างความสัมพันธ์กับแนวโน้มยูโรและหากความสัมพันธ์เป็นลบให้พลิกองค์ประกอบ หรืออะไรทำนองนั้น ทั้งหมดนี้ขึ้นอยู่กับแอปพลิเคชันเฉพาะของคุณและความรู้เกี่ยวกับโดเมนของคุณ
อะมีบาพูดว่า Reinstate Monica

1
ฉันเห็นด้วยกับการตีความและคำแนะนำของ @ amoeba
whuber

1
@ amoeba: ใช่คุณพูดถูก แต่ฉันคิดอย่างไร้เดียงสาว่าอาจมีวิธีแก้ปัญหาทั่วไปที่ไม่ได้ขึ้นอยู่กับอนุกรมเวลาที่เฉพาะเจาะจงบางอย่างเช่น "การวางแนวที่แท้จริงของเวกเตอร์" :) อย่างไรก็ตามขอขอบคุณสำหรับความช่วยเหลือและ คำแนะนำ
ไม่ระบุชื่อ

8

@whuber ถูกต้องว่าไม่มีการวางแนวที่แท้จริงของข้อมูล แต่คุณยังสามารถบังคับใช้ว่า eigenvector ของคุณมีความสัมพันธ์เชิงบวกกับเวกเตอร์อ้างอิงบางส่วน

ตัวอย่างเช่นคุณสามารถทำการโหลด USD เป็นค่าบวกกับ eigenvector ของคุณทั้งหมด (เช่นถ้าการโหลดของ USD เป็นค่าลบให้เปลี่ยนสัญญาณของเวกเตอร์ทั้งหมด) ทิศทางโดยรวมของเวกเตอร์ของคุณยังคงเป็นไปตามอำเภอใจ (เนื่องจากคุณสามารถใช้ EUR หรือ ZAR เป็นข้อมูลอ้างอิงของคุณแทน) แต่แกนแรก ๆ ของ PCA ของคุณอาจจะไม่กระโดดเกือบเท่า - โดยเฉพาะอย่างยิ่งเนื่องจากหน้าต่างกลิ้งของคุณ ยาว.


7
ความคิดที่ดี. ฉันลองครั้งแรก (อาจเป็นในขณะที่คุณโพสต์คำตอบนี้ :-) ปัญหาคือโหลดอื่น ๆ สามารถกระโดดไปรอบ ๆ ในการแก้ไขปัญหานี้ให้ยึดตัวเลือกเครื่องหมายบนการโหลดที่ใหญ่ที่สุด ยังไม่มีลูกเต๋า: การโหลดยังคงสามารถกระโดดได้ เคล็ดลับคือในแต่ละครั้งเพื่อเลือกการวางแนวที่สร้างการรบกวนน้อยที่สุดในเวกเตอร์ของการโหลดจากครั้งก่อน
whuber

4
@whuber ทำงานได้ดี
David J. Harris

1
ถูกต้องสัญลักษณ์ของการโหลดไม่สำคัญ (การวางแนว) สิ่งที่ไม่ได้กล่าวถึงคือถ้าคุณดำเนินการกับซอฟต์แวร์แพ็กเกจต่างกันความแตกต่างระหว่างแพ็กเกจคือโปรแกรมหนึ่งอาจส่งสัญญาณเชิงลบ (บวก) กับการโหลดเฉพาะขณะที่อีกโปรแกรมหนึ่งส่งสัญญาณบวก (ลบ) สำหรับการโหลดเดียวกัน ดังนั้นสัญญาณของผลลัพธ์สุดท้ายในพล็อต 3 ซีรีส์ข้างต้นอาจจะกลับด้านเมื่อใช้แพ็คเกจอื่น การโหลดเวกเตอร์อ้างอิงอาจมีการเปลี่ยนแปลงเครื่องหมาย - และวิธีนี้จะไม่ถูกต้อง
JoleT

@LEP: ฉันประสบปัญหาเดียวกันกับการผกผันบางทีคุณอาจพบวิธีแก้ปัญหาสำหรับปัญหานี้แล้ว - วิธีค้นหาเวกเตอร์แรกให้ถูกต้องและตรวจสอบให้แน่ใจว่าส่วนที่เหลือนั้นจะถูกจัดให้เหมาะสม - quant.stackexchange.com/questions / 3094 / … ?
ไม่เปิดเผยตัว

ตราบใดที่เมทริกซ์ไม่เอกพจน์และไม่มีค่าลักษณะเฉพาะเป็นศูนย์ผลลัพธ์ของอัลกอริทึมส่วนใหญ่ควรเหมือนกันยกเว้นการเปลี่ยนแปลงสัญญาณ 180 องศาซึ่งไม่รับประกัน
JoleT

1

สิ่งที่ฉันทำคือการคำนวณระยะห่างของ L1 ระหว่างผู้สร้างแบบจำลองที่ต่อเนื่องกัน หลังจาก normalizing เมทริกซ์นี้ฉันเลือกขีด จำกัด คะแนน az เช่น 1 ดังนั้นหากในการกลิ้งใหม่การเปลี่ยนแปลงอยู่เหนือขีด จำกัด นี้ฉันพลิก eigenvector ปัจจัยและการโหลดเพื่อให้มีความสอดคล้องในหน้าต่างกลิ้ง โดยส่วนตัวฉันไม่ชอบที่จะบังคับให้สัญญาณในความสัมพันธ์บางอย่างเพราะพวกเขาสามารถระเหยได้มากขึ้นอยู่กับไดรเวอร์แมโคร

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.