2012-02-02 13 views
8

मेरे पास लगभग 200,000 पंक्तियों का एक लंबा संख्यात्मक समय श्रृंखला डेटा है (इसे Z पर कॉल करें)।आर: इनपुट सेगमेंट में अधिकतम क्रॉस-सहसंबंध के साथ समय श्रृंखला सेगमेंट का कुशलतापूर्वक पता लगाना?

एक पाश में, मैं एक्स (लगभग 30) लगातार पंक्तियों जेड से एक समय में सबसेट और उन्हें क्वेरी बिंदु क्ष के रूप में व्यवहार करते हैं।

मैं जेडy (~ 300) सबसे सहसंबद्ध समय श्रृंखला सेगमेंट के भीतर का पता लगाने के लिए चाहते हैं लंबाई एक्स (सबसे क्ष के साथ सहसंबद्ध) की

इसे पूरा करने का एक प्रभावी तरीका क्या है?

उत्तर

5

की स्थिति को निकालने के लिए आप के लिए और रन देख रहे है मेरे किसी भी शक्तिशाली विंडोज लैपटॉप पर 8 सेकंड में, इसलिए यह आपके उद्देश्यों के लिए पर्याप्त तेज़ होना चाहिए।

सबसे पहले, यह 30-बाय -199971 मैट्रिक्स (Zmat) बनाता है, जिनके कॉलम में सभी लंबाई -30 "टाइम सीरीज़ सेगमेंट" शामिल हैं जिन्हें आप देखना चाहते हैं। cor() पर एक एकल कॉल, वेक्टर q और मैट्रिक्स Zmat पर ऑपरेटिंग, फिर सभी वांछित सहसंबंध गुणांक की गणना करता है। अंत में, परिणामी वेक्टर की जांच उच्चतम सहसंबंध गुणांक वाले 300 अनुक्रमों की पहचान करने के लिए की जाती है।

# Simulate data 
nZ <- 200000 
nq <- 30 
Z <- rnorm(nZ) 
q <- seq_len(nq) 

# From Z, construct a 30 by 199971 matrix, in which each column is a 
# "time series segment". Column 1 contains observations 1:30, column 2 
# contains observations 2:31, and so on through the end of the series. 
Zmat <- sapply(seq_len(nZ - nq + 1), 
       FUN = function(X) Z[seq(from = X, length.out = nq)]) 

# Calculate the correlation of q with every column/"time series segment. 
Cors <- cor(q, Zmat) 

# Extract the starting position of the 300 most highly correlated segments  
ids <- order(Cors, decreasing=TRUE)[1:300] 

# Maybe try something like the following to confirm that you have 
# selected the most highly correlated segments. 
hist(Cors, breaks=100) 
hist(Cors[ids], col="red", add=TRUE) 
+0

अच्छा समाधान। 'x'' cor' कॉल में 'q' होना चाहिए (और शायद' q' को 'Z [seq_len (qlen)] असाइन किया जाना चाहिए।' माइक की शब्दावली को ध्यान में रखते हुए, 'qlen' = 'x'। – jbaums

+0

धन्यवाद इसे पकड़ने के लिए। अब मैंने कोड संशोधित किया है, वेरिएबल नाम बदल रहे हैं, और कुछ और टिप्पणियां/स्पष्टीकरण जोड़ रहे हैं। सुनिश्चित नहीं है कि 'q' जरूरी है कि 'Z' के पहले 30 तत्व हों, इसलिए मैंने इसे नहीं बदला है थोड़ा। चीयर्स। –

3

अनुभवहीन समाधान वास्तव में बहुत धीमी गति से है (कम से कम कई मिनट - मैं काफी रोगी नहीं कर रहा हूँ):

library(zoo) 
n <- 2e5 
k <- 30 
z <- rnorm(n) 
x <- rnorm(k) # We do not use the fact that x is a part of z 
rollapply(z, k, function(u) cor(u,x), align="left") 

आपको अपनी ओर से सह-संबंध की गणना कर सकता पहले क्षणों और comoments से, है, लेकिन यह अभी भी कई मिनट लगते हैं।

y <- zoo(rnorm(n), 1:n) 
x <- rnorm(k) 
exy <- exx <- eyy <- ex <- ey <- zoo(rep(0,n), 1:n) 
for(i in 1:k) { 
    cat(i, "\n") 
    exy <- exy + lag(y,i-1) * x[i] 
    ey <- ey + lag(y,i-1) 
    eyy <- eyy + lag(y,i-1)^2 
    ex <- ex + x[i] # Constant time series 
    exx <- exx + x[i]^2 # Constant time series 
} 
exy <- exy/k 
ex <- ex/k 
ey <- ey/k 
exx <- exx/k 
eyy <- eyy/k 
covxy <- exy - ex * ey 
vx <- exx - ex^2 
vy <- eyy - ey^2 
corxy <- covxy/sqrt(vx * vy) 

एक बार जब आप सह-संबंध के समय श्रृंखला है, यह आसान नीचे कोड 300 खंडों पाता शीर्ष 300.

i <- order(corxy, decreasing=TRUE)[1:300] 
corxy[i] 
संबंधित मुद्दे