R의 rollapply PCA에서 "점프"로딩을 받고 있습니다. 수정할 수 있습니까?


20

28 개의 다른 통화에 대한 10 년 간의 일일 반품 데이터가 있습니다. 첫 번째 주요 구성 요소를 추출하고 싶지만 10 년 전체에 PCA를 운영하는 대신 통화의 동작이 발전하고이를 반영하기 위해 2 년 창을 적용하고 싶습니다. 그러나 중요한 문제가 있습니다. 즉, princomp () 및 prcomp () 함수는 종종 인접한 PCA 분석에서 양수에서 음수로 점프합니다 (즉, 1 일 간격). EUR 통화의 로딩 차트를 살펴보십시오.

여기에 이미지 설명을 입력하십시오

인접한 하중이 양에서 음으로 점프하기 때문에 이것을 사용할 수 없으므로 분명히 이것을 사용할 수 있습니다. 이제 EUR 통화 로딩의 절대 값을 살펴보십시오.

여기에 이미지 설명을 입력하십시오

문제는 상단 차트에서 로딩이 음수에서 양수로 바뀌고 때로는 되돌아가는 것을 볼 수 있기 때문에 여전히 이것을 사용할 수 없다는 것입니다.

이 문제를 해결할 수있는 방법이 있습니까? 인접한 PCA에서 고유 벡터 방향을 항상 동일하게 유지할 수 있습니까?

그런데이 문제는 FactoMineR PCA () 함수에서도 발생합니다. rollapply의 코드는 다음과 같습니다.

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

3
고유 벡터 "방향"의 의미를 설명해 주시겠습니까? 내가 아는 한, 데이터에 본질적인 것은 없습니다 . (다른 소프트웨어가 다른 정규화 된 고유 벡터를 생성하는 이유 중 하나입니다.) 존재하지 않고 의미가없는 것을 요구하는 것처럼 들립니다.
whuber

1
언젠가 나는 다음과 같은 로딩을 얻을 것이다 : EUR -0.2 ZAR +0.8 USD +0.41 ..... 28 통화. 그리고 다음날 EUR +0.21 ZAR -0.79 USD -0.4 등을 얻습니다. 따라서 PCA가 데이터를 회전시키기 위해 선택한 축은 1 일과 비교하여 2 일에 정확히 반대 방향으로 향하게됩니다. 이로드가 급격히 증가하고 그것을 피하고 싶습니다. 어쨌든 내 용어가 잘못되어 있다면 사과드립니다. PCA 코드는 하루 동안 로드 에서 일관성이있는 한 축 방향에 실제로 신경 쓰지 않는다는 것을 이해 하지만 며칠 동안 일관성이 있어야합니다.
Thomas Browne

1
일일 데이터에 대해 2 년의 롤링 기간이 주어짐에 따라 매일 매우 유사한 PCA를 가져야합니다.
Thomas Browne

문제가있는 이유는이 롤 적용 아이디어가 의미가 없기 때문이라고 생각합니다. 나는 당신의 목표를 달성하고 (그들이 무엇인지 확실하지 않은) 다른 무언가를 찾는 것 외에는 해결책이 없습니다.
Michael R. Chernick

EUR -0.2 ZAR +0.8 USD +0.41하고 EUR +0.21 ZAR -0.79 USD -0.4 있습니다 매우 매우 유사합니다. 두 결과 중 하나만 로그인하면됩니다.
ttnphns

답변:


22

플롯이 너무 많이 점프 할 때마다 방향을 반대로 바꿉니다. 효과적인 기준 중 하나는 모든 구성 요소의 총 점프 량을 계산하는 것입니다. 다음 고유 벡터가 부정되면 총 점프 량을 계산합니다. 후자가 적 으면 다음 고유 벡터를 무효화하십시오.

구현은 다음과 같습니다. (나는 익숙하지 않다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))

수정


tivi+1i+1vii11vi+1. 알고리즘이 약간 다릅니다. 같은 방식으로 작동합니까?
amoeba는 Reinstate Monica

@amoeba 비록 당신이 무엇을하고 있는지 잘 모르겠지만 David J. Harris의 답변과 그에 따른 논평에서 논의 된 아이디어 중 일부와 같습니다. 특히 stats.stackexchange.com/questions/34396/…에 대한 나의 의견을 참조하십시오 .
whuber

2
@Art, 내가 이해했듯이 외부 (PCA 외부) 환경 설정에 따라 구성 요소의 부호를 수정하려고합니다. 이것은 괜찮지 만 그것이 접근해야합니다. 먼저 슬라이딩 PCA 작업을 수행하여 표시가 일치하는지 확인하십시오. 그런 다음 몇 가지 추가 기준에 따라 전체 구성 요소를 뒤집을 지 여부를 결정하십시오. 예를 들어 유로 추세와 상관 관계가 있고 상관 관계가 음수이면 구성 요소를 뒤집습니다. 아니면 그런 것. 이는 전적으로 특정 응용 프로그램 및 도메인 지식에 따라 다릅니다.
amoeba는 Reinstate Monica

1
@amoeba의 해석과 추천에 동의합니다.
whuber

1
@amoeba : 예, 당신은 이것에 대해 옳습니다.하지만 순진하게 특정 시계열에 의존하지 않는 일반적인 해결책이있을 것이라고 생각했습니다. "벡터의 실제 방향"과 같은 것 :) 어쨌든 도움을 주셔서 감사합니다 제안
Anonymous

8

@whuber는 데이터에 본질적인 방향이 없다는 것이 맞지만 고유 벡터가 일부 참조 벡터와 양의 상관 관계를 유지하도록 강제 할 수 있습니다.

예를 들어, 모든 고유 벡터에 대해 USD의 양수를 양수로 만들 수 있습니다 (예 : USD의 양수가 음수이면 전체 벡터의 부호를 뒤집습니다). 벡터의 전반적인 방향은 여전히 ​​임의적이지만 (대신 EUR 또는 ZAR을 참조로 사용할 수 있기 때문에) PCA의 처음 몇 축은 거의 많이 움직이지 않을 것입니다. 특히 롤링 창이 너무 길기 때문에 긴.


7
좋은 생각. 나는 이것을 먼저 시도했다. (아마도이 ​​답변을 게시하는 동안 :-). 문제는 다른 하중이 도약 할 수 있다는 것입니다. 이 문제를 해결하려면 가장 큰 하중을 기준으로 부호를 선택하십시오. 여전히 주사위가 없습니다 : 적재물이 여전히 뛸 수 있습니다. 트릭은 항상 이전 시간보다 부하 벡터 에서 가장 방해가 적은 방향을 선택하는 것입니다.
whuber

4
@ whuber 좋은 일.
David J. Harris

1
맞습니다. 하중의 부호는 중요하지 않습니다 (방향). 해결되지 않은 것은 다른 소프트웨어 패키지 에서이 작업을 수행하면 패키지 간 차이점은 한 프로그램이 특정로드에 대해 음수 (긍정적) 표시가 발생하고 다른 프로그램이 동일한로드에 대해 양수 (음수) 표시가 될 수 있다는 것입니다. 따라서 다른 패키지를 사용할 때 위의 3 시리즈 플롯에서 최종 결과의 부호가 반전 될 수 있습니다. 참조 벡터 로딩도 부호가 변경 될 수 있으며이 솔루션은 올바르지 않습니다.
JoleT

@LEP : 반전과 같은 문제에 직면했을 수 있습니다. 아마도이 문제에 대한 해결책을 찾았을 것입니다. 첫 번째 벡터가 올바른지 확인하고 나머지가 올바르게 정렬되는지 확인하는 방법 -quant.stackexchange.com/questions / 3094 /… ?
익명

행렬이 특이 적이 지 않고 고유 값이 0이 아닌 한 부호의 180도 변화를 제외하고 대부분의 알고리즘 결과는 동일해야합니다.
JoleT

1

내가 한 것은 연속 고유 벡터 사이의 L1 거리를 계산하는 것이 었습니다. 이 행렬을 정규화 한 후 az score threshold (예 : 1)를 선택하여 새로운 롤링에서 변경이이 임계 값보다 높으면 롤링 창에서 일관성을 유지하기 위해 고유 벡터, 요소 및 하중을 뒤집습니다. 개인적으로 나는 매크로 드라이버에 따라 변동성이 매우 높기 때문에 어떤 상관 관계에서 주어진 부호를 강요하지 않습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.