Làm thế nào để phù hợp với một chức năng bước mạnh mẽ cho một chuỗi thời gian?


7

Tôi có một chuỗi thời gian hơi ồn ào dao động xung quanh các cấp độ khác nhau.

Ví dụ: dữ liệu sau:

nhập mô tả hình ảnh ở đây

Tôi có sẵn dữ liệu đường thẳng và tôi muốn có được ước tính cho đường đứt nét. Nó nên được liên tục piecewise.

Những thuật toán thích hợp để thử ở đây?

Ý tưởng của tôi cho đến nay vẫn xoay quanh các P-splines 0 độ (nhưng làm thế nào để tìm ra nơi đặt các nút thắt?) Hoặc các mô hình phá vỡ cấu trúc. Cây hồi quy là ý tưởng tốt nhất tôi hiện có, nhưng lý tưởng nhất là tôi sẽ tìm kiếm một phương pháp có tính đến thực tế là hai mức tại y = 250 có giá trị y bằng nhau. Nếu tôi hiểu chính xác, một cây hồi quy sẽ chia hai khoảng này thành hai nhóm khác nhau, mỗi nhóm có một giá trị trung bình khác nhau.

Mã R đã tạo ra nó là:

set.seed(20181118)
true_fct = stepfun(c(100, 200, 250), c(200, 250, 300, 250))
x = 1:400
y = true_fct(x) + rt(length(x), df=1)
plot(x, y, type="l")
lines(x, true_fct(x), lty=2, lwd=3)

2
Nếu dữ liệu của bạn thực sự trông giống như dữ liệu mô phỏng, thì bạn khó có thể làm tốt hơn việc tính toán một trung vị cửa sổ với một cửa sổ rất nhỏ: điều đó sẽ phát hiện tất cả các bước nhảy một cách đáng tin cậy. Ước tính mức độ bằng cách sử dụng trung bình của các câu trả lời trong mỗi khoảng thời gian như vậy được phát hiện. Do đó, bạn có thể chỉ ra liệu các giả định ngầm định của mô phỏng - bước nhảy lớn, trung vị không đổi và các lỗi của Sinh viên - có chính xác là các giả định chúng ta nên thực hiện không?
whuber

1
Cám ơn bạn đã góp ý! Tôi có hai nhận xét: (1) Làm thế nào tôi có thể nhận được các khoảng từ trung vị cửa sổ? (2) Các giả định là trung vị không đổi, và các bước nhảy đáng chú ý, nhưng tôi không biết gì về phân phối lỗi, ngoài thực tế là các ngoại lệ lớn có thể xảy ra.
Alexander Engelhardt

Đôi khi các phương pháp không tham số đơn giản hoạt động khi vấn đề đơn giản. Tôi muốn bạn mô phỏng một tập dữ liệu thực tế / thách thức hơn trong đó có cấu trúc arima nhúng và có thể là một hoặc hai xung theo mùa. Phương pháp tiếp cận toàn diện cho các vấn đề như thế này cần phải xem xét và cách ly cấu trúc tự phát và sự bất thường trong khi xử lý. Bạn có thể đăng một câu hỏi khác và bao gồm tập dữ liệu thực tế hơn một chút.
IrishStat

Tôi cũng nên thêm khi độ dịch chuyển của cấp / bước quá lớn, quá trình lỗi không phải là tham số có thể đóng vai trò hữu ích và ít hơn để tỷ lệ đó nhỏ hơn
IrishStat 16/11/18

Câu trả lời:


7

Một phương pháp đơn giản, mạnh mẽ để xử lý nhiễu như vậy là tính toán trung vị.

Một dải trung vị lăn trên một cửa sổ ngắn sẽ phát hiện tất cả trừ các bước nhảy nhỏ nhất, trong khi các dải trung bình của phản ứng trong khoảng thời gian giữa các lần nhảy được phát hiện sẽ ước tính mạnh mẽ mức độ của chúng. (Bạn có thể thay thế ước tính sau này bằng bất kỳ ước tính mạnh mẽ nào không bị ảnh hưởng bởi các ngoại lệ.)

Bạn nên điều chỉnh phương pháp này với dữ liệu thực hoặc mô phỏng để đạt được tỷ lệ lỗi chấp nhận được. Ví dụ, đối với mô phỏng trong câu hỏi tôi thấy thật tốt khi sử dụng phân vị thứ hai và thứ 98 để đặt ngưỡng để phát hiện các bước nhảy. Trong các trường hợp khác - chẳng hạn như khi nhiều bước nhảy có thể xảy ra - phần trăm trung tâm sẽ hoạt động tốt hơn.

Dưới đây là kết quả cho thấy (a) ba lần nhảy là các chấm đỏ và (b) bốn mức ước tính là các đường màu xanh nhạt.

Nhân vật

Các bước nhảy được ước tính xảy ra ở các chỉ số 100, 200, 250 (chính xác là nơi mô phỏng khiến chúng xảy ra) và các mức kết quả được ước tính là 199,6, 249,8, 300,0 và 250,2: tất cả trong vòng 0,4 giá trị cơ bản thực sự.

Hành vi tuyệt vời này vẫn tồn tại với các mô phỏng lặp đi lặp lại (loại bỏ set.seedlệnh ở đầu).

Đây là Rmã.

#
# Rolling medians.
#
rollmed <- function(x, k=3) {
  n <- length(x)
  x.med <- sapply(1:(n-k+10), function(i) median(x[i + 0:(k-1)]))
  l <- floor(k/2)
  c(rep(NA, l), x.med, rep(NA, k-l))
}
y.med <- rollmed(y, k=5)
#
# Changepoint analysis.
#
dy <- diff(y.med)
fourths <- quantile(dy, c(1,49)/50, na.rm=TRUE)
thresholds <- fourths + diff(fourths)*2.5*c(-1,1)
jumps <- which(dy < thresholds[1] | dy > thresholds[2]) + 1

points(jumps, y.med[jumps], pch=21, bg="Red")
#
# Plotting.
#
limits <- c(1, jumps, length(y)+1)
y.hat <- rep(NA, length(jumps)+1)
for (i in 1:(length(jumps)+1)) {
  j0 <- limits[i]
  j1 <- limits[i+1]-1
  y.hat[i] <- median(y[j0:j1])
  lines(x[j0:j1], rep(y.hat[i], j1-j0+1), col="skyblue", lwd=2)
}

+1, nhưng phần "phân tích thay đổi" của mã có thể không hoàn toàn rõ ràng đối với một số người dùng, vì vậy có lẽ bạn có thể nhận xét những gì đang xảy ra ở đó?
Tim

@Tim Cảm ơn bạn đã gợi ý. Mục đích của đoạn đầu tiên là để giải thích thuật toán đó. Tôi muốn hạ thấp các chi tiết thực hiện vì chúng không quan trọng: nên áp dụng bất kỳ phương pháp sàng lọc ngoại lệ mạnh mẽ nào cho phần dư.
whuber

Bạn có thể muốn xem xét zoo::rollmedianhoặc một chức năng tương tự để đơn giản hóa mã của bạn.
usεr11852

@ usεr11852 Cảm ơn bạn. Tôi nhận thức đượczoo nhưng bầu không sử dụng nó vì tôi lười biếng! Nó nhanh hơn và dễ viết rollmedhơn là xem lại các cuộc gọi đối số đến bất kỳ chức năng nào có thể đã có sẵn. Ngoài ra, tôi thích cách rollmedminh họa rõ ràng những gì tôi đang làm hơn là che giấu các chi tiết đằng sau một hộp đen.
whuber

Không vấn đề gì. :) (Tôi chắc chắn bạn biết về zoo, tôi đã không chắc chắn nếu bạn không sử dụng nó bằng cách lựa chọn một cách tình cờ hoặc câu trả lời tốt trong bất kỳ trường hợp 1.)
usεr11852

3

Nếu bạn vẫn quan tâm đến việc làm mịn với các hình phạt L0, tôi sẽ xem qua tài liệu tham khảo sau: "Trực quan hóa các thay đổi gen bằng cách làm mịn phân đoạn bằng cách sử dụng hình phạt L0" - DOI: 10.1371 / tạp chí.pone.0038230 (một đoạn giới thiệu hay về Whittaker mượt hơn có thể được tìm thấy trong giấy P. Eilers "A mượt hoàn hảo hơn" - DOI: 10.1021 / ac034173t). Tất nhiên, để đạt được mục tiêu của bạn, bạn phải làm việc một chút xung quanh phương pháp.

Về nguyên tắc, bạn cần 3 thành phần:

  1. Nhẹ nhàng hơn - Tôi sẽ sử dụng Whittaker mượt mà hơn. Ngoài ra, tôi sẽ sử dụng phép tăng ma trận (xem Eilers và Marx, 1996 - "Làm mịn linh hoạt với B-splines và Penalies", tr.101).
  2. Hồi quy lượng tử - Tôi sẽ sử dụng gói lượng tử R (rho = 0,5) cho sự lười biếng :-)
  3. Hình phạt L0 - Tôi sẽ theo dõi "Trực quan hóa các thay đổi gen bằng cách làm mịn phân đoạn bằng cách sử dụng hình phạt L0" - DOI: 10.1371 / tạp chí.pone.0038230

Tất nhiên, bạn cũng sẽ cần một cách để chọn mức độ làm mịn tối ưu. Điều này được thực hiện bởi mắt thợ mộc của tôi cho ví dụ này. Bạn có thể sử dụng các tiêu chí trong DOI: 10.1371 / Tạp chí.pone.0038230 (trang 5, nhưng tôi đã không thử nó trong ví dụ của bạn).

Bạn sẽ tìm thấy một mã nhỏ dưới đây. Tôi để lại một số ý kiến ​​như hướng dẫn thông qua nó.

# Cross Validated example
rm(list = ls()); graphics.off(); cat("\014")

library(splines)
library(Matrix)
library(quantreg)

# The data
set.seed(20181118)
n = 400
x = 1:n
true_fct = stepfun(c(100, 200, 250), c(200, 250, 300, 250))
y = true_fct(x) + rt(length(x), df = 1)

# Prepare bases - Identity matrix (Whittaker)
# Can be changed for B-splines
B = diag(1, n, n)

# Prepare penalty - lambda parameter fix
nb = ncol(B)
D = diff(diag(1, nb, nb), diff = 1)
lambda = 1e2

# Solve standard Whittaker - for initial values
a = solve(t(B) %*% B + crossprod(D), t(B) %*% y, tol = 1e-50)    

# est. loop with L0-Diff penalty as in DOI: 10.1371/journal.pone.0038230
p = 1e-6
nit = 100
beta = 1e-5

for (it in 1:nit) {
  ao = a

  # Penalty weights
  w = (c(D %*% a) ^ 2  + beta ^ 2) ^ ((p - 2)/2)
  W = diag(c(w))

  # Matrix augmentation
  cD = lambda * sqrt(W) %*% D
  Bp = rbind(B, cD)
  yp =  c(y, 1:nrow(cD)*0)

  # Update coefficients - rq.fit from quantreg
  a = rq.fit(Bp, yp, tau = 0.5)$coef

  # Check convergence and update
  da = max(abs((a - ao)/ao))
  cat(it, da, '\n')
  if (da < 1e-6) break
}

# Fit 
v = B %*% a

# Show results
plot(x, y, pch = 16, cex = 0.5)
lines(x, y, col = 8, lwd = 0.5)
lines(x, v, col = 'blue', lwd = 2)
lines(x, true_fct(x), col = 'red', lty = 2, lwd = 2)
legend("topright", legend = c("True Signal", "Smoothed signal"), 
       col = c("red", "blue"), lty = c(2, 1))

nhập mô tả hình ảnh ở đây Tái bút Đây là câu trả lời đầu tiên của tôi về Xác thực chéo. Tôi hy vọng nó hữu ích và đủ rõ ràng :-)


1

Tôi sẽ xem xét sử dụng Outliers giấy của Ruey Tsay , thay đổi cấp độ và thay đổi phương sai trong mô hình phân biệt chuỗi thời gian với AR1 và 21 ngoại lệ.

nhập mô tả hình ảnh ở đây

nhập mô tả hình ảnh ở đây

Chúng tôi đã tắt differencng và sự thay đổi cấp độ được gọi cụ thể.

nhập mô tả hình ảnh ở đây


1
Tôi tự hỏi liệu bạn có bỏ qua sự nhấn mạnh vào "mạnh mẽ" trong tiêu đề của câu hỏi hay không, bởi vì bất kỳ phương pháp nào xác định 18 tham số giả (tương ứng với các ngoại lệ được giới thiệu trong mô phỏng) ngoài 3 lần nhảy thực tế có thể được coi là mạnh mẽ (hoặc phân tích, cho chuyện đó).
whuber

Đó là một giải pháp mạnh mẽ. Tôi không chắc tại sao bạn chống lại việc xác định và điều chỉnh các ngoại lệ, nhưng có một thế giới nghiên cứu hỗ trợ thực hiện nó và tất nhiên là kinh nghiệm của chúng tôi. Những biến khác là ngoại lệ. Tôi đã thêm một biểu đồ hiển thị dữ liệu lịch sử và phiên bản được làm sạch để tương phản sự khác biệt.
Tom Reilly

1
Bạn có thể rõ ràng về ước tính của bạn về chức năng bước là gì?
whuber

1
Có một cờ ở giai đoạn 100 (x3), 200 (x2), 250 (x4) hiển thị bước. Toán tử khác biệt làm cho nó khó nhìn hơn một chút, nhưng hiệu quả là như nhau. Tôi đã thêm một mô hình mà không có sự khác biệt.
Tom Reilly
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.