2012-02-02 30 views
8

Tôi có một số dữ liệu dài chuỗi thời gian xấp xỉ 200.000 hàng (cho phép gọi nó là Z).R: Định vị một cách hiệu quả các phân đoạn chuỗi thời gian có tương quan chéo tối đa với phân đoạn đầu vào?

Trong một vòng, tôi tập hợp con x (khoảng 30) hàng liên tiếp từ Z tại một thời điểm và đối xử với họ như là điểm truy vấn q.

Tôi muốn xác định vị trí trong vòng Z các y (~ 300) tương quan nhất phân đoạn chuỗi thời gian chiều dài x (tương quan nhất với q). một cách hiệu quả để thực hiện điều này là

gì?

Trả lời

5

Đoạn code dưới đây tìm thấy 300 phân đoạn bạn đang tìm kiếm và chạy trong 8 giây trên máy tính xách tay Windows không quá mạnh của tôi, vì vậy nó phải đủ nhanh cho các mục đích của bạn.

Đầu tiên, nó xây dựng một ma trận 30-by-199971 (Zmat), có cột chứa tất cả các đoạn chuỗi thời gian dài 30 "mà bạn muốn kiểm tra. Một cuộc gọi duy nhất để cor(), hoạt động trên các vector q và ma trận Zmat, sau đó tính toán tất cả các hệ số tương quan mong muốn. Cuối cùng, vector kết quả được kiểm tra để xác định 300 chuỗi có hệ số tương quan cao nhất.

# 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

đẹp giải pháp. 'X' nên được' q' trong 'gọi cor' (và có lẽ 'q' nên được chỉ định' Z [seq_len (qlen)]'. Để phù hợp với thuật ngữ của Mike, 'qlen' =' x'. – jbaums

+0

Cảm ơn Bây giờ tôi đã sửa đổi mã, thay đổi tên biến và thêm một số chú thích/giải thích. Không chắc liệu 'q' có nhất thiết phải là 30 phần tử đầu tiên của' Z', vì vậy tôi chưa thay đổi chút. –

3

Giải pháp ngây thơ thực sự là rất chậm (phút ít nhất là vài - Tôi không đủ kiên nhẫn):

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") 

Bạn có thể tính toán tương quan bằng tay, từ những khoảnh khắc đầu tiên và comoments, nhưng nó vẫn mất vài phút.

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) 

Một khi bạn có chuỗi thời gian của các mối tương quan, nó rất dễ dàng để trích xuất các vị trí trong top 300.

i <- order(corxy, decreasing=TRUE)[1:300] 
corxy[i] 
Các vấn đề liên quan