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
固有ベクトルの「方向」の意味を説明できますか?私の知る限り、データに固有のようなものはありません(これが、異なるソフトウェアが異なる正規化された固有ベクトルを生成する理由の1つです。)したがって、存在しないものや意味のないものを求めているように聞こえます。
whuber

1
まあある日、私はこのような負荷を得るでしょう:EUR -0.2 ZAR +0.8 USD +0.41 ..... 28通貨。そして、翌日にはEUR +0.21 ZAR -0.79 USD -0.4などが得られます。したがって、PCAがデータの回転先として選択した軸は、1日目と比較して2日目とまったく逆の方向になります。これらの読み込みがジャンプするので、どうにかしてそれを避けたいと思います......私の用語が誤解を招く場合はおologiesび申し上げます。PCAコードは、1日の負荷全体で一貫している限り、実際には軸の向きを気にしないことを理解していますが、複数の日で一貫している必要があります。
トーマスブラウン

1
毎日のデータの2年間のローリングウィンドウを考えると、ある日から次の日まで、非常によく似たPCAがあるはずです。
トーマスブラウン

あなたが問題を抱えている理由は、このロールアップのアイデアが意味をなさないからだと思います。私はあなたの目標を達成するかもしれない(それらが何であるかわからない)異なった何かを探す以外に解決策はありません。
マイケルR.チャーニック

EUR -0.2 ZAR +0.8 USD +0.41そして、EUR +0.21 ZAR -0.79 USD -0.4 ある非常に非常に似ています。2つの結果のいずれかの符号を反転させるだけです。
ttnphns

回答:


22

プロットがジャンプしすぎるたびに、向きを逆にします。 1つの効果的な基準は、これです。すべてのコンポーネントのジャンプの合計量を計算します。次の固有ベクトルが否定される場合、ジャンプの合計量を計算します。後者が小さい場合、次の固有ベクトルを否定します。

これが実装です。(私はに精通して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))

修正済み


tv+1+1v11v+1。あなたのアルゴリズムは少し違うようです。同じように機能しますか?
アメーバは、モニカを復活させる

@amoebaあなたが何をしているのか正確にはわかりませんが、David J. Harrisの回答とそれに続くコメントで議論されているアイデアのようです。特に、stats.stackexchange.com / questions / 34396 /…での私のコメントを参照してください。
whuber

2
@Artですので、私が理解しているように、外部(PCAの外部)の設定に基づいてコンポーネントの符号を修正する必要があります。これは問題ありませんが、それがあなたのアプローチ方法です。最初にスライドPCAを行い、兆候が一貫していることを確認します。そして、いくつかの追加基準に基づいて、コンポーネント全体を反転するかどうかを決定します。たとえば、ユーロのトレンドと相関させることができ、相関が負の場合、コンポーネントを反転します。またはそのようなもの。これは完全に特定のアプリケーションとドメインの知識に依存します。
アメーバは、モニカを復活させる

1
@amoebaの解釈と推奨に同意します。
whuber

1
@amoeba:はい、あなたはこれについて正しいですが、特定の時系列に依存しない一般的な解決策があるかもしれないと単純に考えました。「ベクトルの実際の向き」のようなものです:)とにかく、助けてくれてありがとう提案
匿名

8

@whuberは、データに固有の向きがないことは正しいですが、固有ベクトルが何らかの参照ベクトルと正の相関を持つように強制することもできます。

たとえば、すべての固有ベクトルでUSDの負荷を正にすることができます(つまり、USDの負荷が負の場合、ベクトル全体の符号を反転します)。ベクターの全体的な方向は依然として任意です(代わりにEURまたはZARを参照として使用することもできたため)が、PCAの最初のいくつかの軸は、おそらくローリングウィンドウがそうであるため、ほとんどジャンプしません。長いです。


7
良いアイデア。私はこれを最初に試しました(おそらく、あなたがこの回答を投稿している間に:-)。問題は、他のローディングが飛び跳ねることがあるということです。これを修正するには、最大の負荷に基づいて記号を選択します。まだサイコロはありません。ローディングはジャンプできます。トリックは、毎回、前回からの負荷のベクトルに最小の乱れを作成する方向を選択することです。
whuber

4
@whuberいいですね。
デビッドJ.ハリス

1
正しい、負荷の兆候は重要ではありません(向き)。対処されていないことは、異なるソフトウェアパッケージでこれを実行すると、パッケージ間の違いは、あるプログラムが特定の負荷で負(正)の兆候をもたらし、別のプログラムが同じ負荷で正(負)の兆候をもたらす可能性があることでした。したがって、別のパッケージを使用すると、上記の3シリーズプロットの最終結果の符号が反転する可能性があります。参照ベクトルの読み込みでも符号が変わる可能性があり、この解決策は正しくありません。
JoleT 14年

@LEP:私は反転で同じ問題に直面しました、おそらくあなたはすでにこの問題の解決策を見つけました-最初のベクトルが正しいことを見つけ、残りがそれに正しく整列することを確認する方法-quant.stackexchange.com/questions / 3094 /…
匿名

行列が特異でなく、どの固有値もゼロでない限り、ほとんどのアルゴリズムの結果は同じであるはずです。ただし、符号の180度の変化は保証されていません。
JoleT

1

私がしたことは、連続する固有ベクトル間のL1距離を計算することでした。このマトリックスを正規化した後、zスコアのしきい値(1など)を選択します。新しいローリングで変更がこのしきい値を超える場合、ローリングウィンドウで一貫性を保つために、固有ベクトル、因子、および負荷を反転します。個人的には、マクロドライバーによっては非常に不安定になる可能性があるため、特定の相関関係に特定の記号を強制するのは好きではありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.