Làm thế nào tôi có thể căn chỉnh / đồng bộ hóa hai tín hiệu?


21

Tôi đang thực hiện một số nghiên cứu nhưng đã bị mắc kẹt ở giai đoạn phân tích (nên chú ý nhiều hơn đến các bài giảng thống kê của tôi).

Tôi đã thu thập hai tín hiệu đồng thời: tốc độ dòng chảy được tích hợp cho âm lượng và thay đổi trong việc mở rộng ngực. Tôi muốn so sánh các tín hiệu và cuối cùng hy vọng sẽ lấy được âm lượng từ tín hiệu mở rộng ngực. Nhưng trước tiên tôi phải căn chỉnh / đồng bộ hóa dữ liệu của mình.

Vì việc ghi âm không bắt đầu chính xác cùng một lúc và mở rộng ngực được ghi lại trong thời gian dài hơn, tôi cần tìm dữ liệu tương ứng với dữ liệu âm lượng của mình trong bộ dữ liệu mở rộng ngực và đo lường mức độ chúng được căn chỉnh. Tôi không chắc chắn làm thế nào để giải quyết vấn đề này nếu hai tín hiệu không bắt đầu cùng một lúc hoặc giữa dữ liệu ở các tỷ lệ khác nhau và ở các độ phân giải khác nhau.

Tôi đã kèm theo một ví dụ về hai tín hiệu ( https://docs.google.com/spreadsheet/ccc?key=0As4oZTKp4RZ3dFRKaktYWEhZLXlFbFVKNmllbGVXNHc ), xin vui lòng cho tôi biết nếu có bất cứ điều gì hơn nữa tôi có thể cung cấp.


Tôi không biết rõ điều này đủ để đưa ra câu trả lời và không chắc chắn điều này giải quyết câu hỏi, nhưng một cách tiếp cận tín hiệu đồng bộ hóa được gọi là "đăng ký", là một tập hợp con của phân tích dữ liệu chức năng. Chủ đề này được thảo luận trong cuốn sách FDA của Ramsey và Silverman. Ý tưởng cơ bản là các tín hiệu quan sát có thể bị "vênh" (ví dụ: nếu chúng ta quan tâm đến cơ chế của cách mọi người nhai nhưng chúng ta có dữ liệu về những người nhai ở tốc độ khác nhau - trục thời gian bị "vênh" trong trường hợp này) và đăng ký cố gắng xác định tín hiệu cơ bản trên thang điểm chung, "không nhận biết".
Macro

1
Bạn đã thu thập tất cả dữ liệu của bạn chưa? Đây có phải là một đối tượng thí điểm? Nếu bạn chỉ mới bắt đầu, tôi sẽ xem xét tách tín hiệu khỏi vành đai của bạn và sử dụng nó làm bộ kích hoạt (hoặc thậm chí chỉ để đánh dấu dấu thời gian) ghi lại luồng của bạn. Thông thường các hệ thống thu nhận có khả năng này với một cổng phụ hoặc kích hoạt. Tôi chắc chắn có nhiều cách để phân biệt nó chỉ bằng cách sử dụng dữ liệu của bạn như Macro đã đề xuất, nhưng thêm bước bổ sung này sẽ lấy đi rất nhiều phỏng đoán.
jonsca

1
Tôi nghĩ rằng, bạn chỉ muốn ước tính một độ trễ cố định. Bạn có thể sử dụng tương quan chéo như được nêu ở đây: stats.stackexchange.com/questions/16121/iêu
thias

1
Bạn có thể muốn hỏi câu hỏi này trên dsp.SE nơi họ cũng nghĩ về việc đồng bộ hóa tín hiệu.
Dilip Sarwate

1
@Thias là chính xác, nhưng có vẻ như một loạt đầu tiên nên được ghép lại để chúng có các khoảng chung.
whuber

Câu trả lời:


24

Câu hỏi hỏi làm thế nào để tìm ra số lượng mà một chuỗi thời gian ("mở rộng") tụt lại một lần nữa ("âm lượng") khi chuỗi được lấy mẫu theo các khoảng thời gian đều đặn nhưng khác nhau .

Trong trường hợp này, cả hai loạt biểu hiện hành vi liên tục hợp lý, như các số liệu sẽ hiển thị. Điều này ngụ ý (1) ít hoặc không cần làm mịn ban đầu và (2) việc lấy lại mẫu có thể đơn giản như nội suy tuyến tính hoặc bậc hai. Quadratic có thể tốt hơn một chút do độ mịn. Sau khi lấy mẫu lại, độ trễ được tìm thấy bằng cách tối đa hóa mối tương quan chéo , như được hiển thị trong luồng, Đối với hai chuỗi dữ liệu được lấy mẫu bù, ước tính tốt nhất của độ lệch giữa chúng là gì? .


Để minh họa , chúng ta có thể sử dụng dữ liệu được cung cấp trong câu hỏi, sử dụng Rcho mã giả. Hãy bắt đầu với chức năng cơ bản, tương quan chéo và lấy mẫu lại:

cor.cross <- function(x0, y0, i=0) {
  #
  # Sample autocorrelation at (integral) lag `i`:
  # Positive `i` compares future values of `x` to present values of `y`';
  # negative `i` compares past values of `x` to present values of `y`.
  #
  if (i < 0) {x<-y0; y<-x0; i<- -i}
  else {x<-x0; y<-y0}
  n <- length(x)
  cor(x[(i+1):n], y[1:(n-i)], use="complete.obs")
}

Đây là một thuật toán thô: tính toán dựa trên FFT sẽ nhanh hơn. Nhưng đối với những dữ liệu này (liên quan đến khoảng 4000 giá trị) thì đủ tốt.

resample <- function(x,t) {
  #
  # Resample time series `x`, assumed to have unit time intervals, at time `t`.
  # Uses quadratic interpolation.
  #
  n <- length(x)
  if (n < 3) stop("First argument to resample is too short; need 3 elements.")
  i <- median(c(2, floor(t+1/2), n-1)) # Clamp `i` to the range 2..n-1
  u <- t-i
  x[i-1]*u*(u-1)/2 - x[i]*(u+1)*(u-1) + x[i+1]*u*(u+1)/2
}

Tôi đã tải xuống dữ liệu dưới dạng tệp CSV được phân tách bằng dấu phẩy và tước tiêu đề của nó. (Tiêu đề gây ra một số vấn đề cho R mà tôi không quan tâm để chẩn đoán.)

data <- read.table("f:/temp/a.csv", header=FALSE, sep=",", 
                    col.names=c("Sample","Time32Hz","Expansion","Time100Hz","Volume"))

NB Giải pháp này giả định mỗi chuỗi dữ liệu theo thứ tự tạm thời không có khoảng trống trong một. Điều này cho phép nó sử dụng các chỉ mục thành các giá trị dưới dạng proxy theo thời gian và chia tỷ lệ các chỉ mục đó theo tần số lấy mẫu tạm thời để chuyển đổi chúng thành thời gian.

Nó chỉ ra rằng một hoặc cả hai dụng cụ này trôi đi một chút theo thời gian. Thật tốt khi loại bỏ các xu hướng như vậy trước khi tiếp tục. Ngoài ra, vì có sự giảm dần của tín hiệu âm lượng ở cuối, chúng ta nên cắt nó ra.

n.clip <- 350      # Number of terminal volume values to eliminate
n <- length(data$Volume) - n.clip
indexes <- 1:n
v <- residuals(lm(data$Volume[indexes] ~ indexes))
expansion <- residuals(lm(data$Expansion[indexes] ~ indexes)

Tôi lấy mẫu lại chuỗi ít hiệu quả để có được kết quả chính xác nhất.

e.frequency <- 32  # Herz
v.frequency <- 100 # Herz
e <- sapply(1:length(v), function(t) resample(expansion, e.frequency*t/v.frequency))

Bây giờ mối tương quan chéo có thể được tính toán - để đạt hiệu quả, chúng tôi chỉ tìm kiếm một cửa sổ độ trễ hợp lý - và độ trễ nơi tìm thấy giá trị tối đa có thể được xác định.

lag.max <- 5       # Seconds
lag.min <- -2      # Seconds (use 0 if expansion must lag volume)
time.range <- (lag.min*v.frequency):(lag.max*v.frequency)
data.cor <- sapply(time.range, function(i) cor.cross(e, v, i))
i <- time.range[which.max(data.cor)]
print(paste("Expansion lags volume by", i / v.frequency, "seconds."))

Đầu ra cho chúng ta biết rằng việc mở rộng bị chậm lại âm lượng 1,85 giây. (Nếu 3,5 giây cuối cùng của dữ liệu không được cắt bớt, đầu ra sẽ là 1,84 giây.)

Đó là một ý tưởng tốt để kiểm tra mọi thứ theo nhiều cách, tốt nhất là trực quan. Đầu tiên, hàm tương quan chéo :

plot(time.range * (1/v.frequency), data.cor, type="l", lwd=2,
     xlab="Lag (seconds)", ylab="Correlation")
points(i * (1/v.frequency), max(data.cor), col="Red", cex=2.5)

âm mưu tương quan chéo

Tiếp theo, hãy đăng ký hai chuỗi thời gian và vẽ chúng cùng nhau trên cùng một trục .

normalize <- function(x) {
  #
  # Normalize vector `x` to the range 0..1.
  #
  x.max <- max(x); x.min <- min(x); dx <- x.max - x.min
  if (dx==0) dx <- 1
  (x-x.min) / dx
}
times <- (1:(n-i))* (1/v.frequency)
plot(times, normalize(e)[(i+1):n], type="l", lwd=2, 
     xlab="Time of volume measurement, seconds", ylab="Normalized values (volume is red)")
lines(times, normalize(v)[1:(n-i)], col="Red", lwd=2)

Lô đất đã đăng ký

Có vẻ khá tốt! Tuy nhiên, chúng ta có thể hiểu rõ hơn về chất lượng đăng ký với một biểu đồ phân tán . Tôi thay đổi màu sắc theo thời gian để hiển thị sự tiến triển.

colors <- hsv(1:(n-i)/(n-i+1), .8, .8)
plot(e[(i+1):n], v[1:(n-i)], col=colors, cex = 0.7,
     xlab="Expansion (lagged)", ylab="Volume")

Phân tán

Chúng tôi đang tìm kiếm các điểm để theo dõi qua lại dọc theo một dòng: các biến thể từ đó phản ánh sự phi tuyến tính trong phản ứng trễ thời gian của việc mở rộng thành âm lượng. Mặc dù có một số biến thể, chúng khá nhỏ. Tuy nhiên, làm thế nào những thay đổi này thay đổi theo thời gian có thể là một số lợi ích sinh lý. Điều tuyệt vời về thống kê, đặc biệt là khía cạnh khám phá và hình ảnh của nó, là cách nó có xu hướng tạo ra những câu hỏiý tưởng hay cùng với những câu trả lời hữu ích .


1
Thánh thần ơi, bạn thật tuyệt vời. Tương quan chéo chính xác là những gì tôi đang tưởng tượng (tôi biết rằng phải có một cái tên cho nó) nhưng câu trả lời / giải thích của bạn đã vượt lên trên cả. Cảm ơn rất nhiều!
157

Bây giờ tôi không có thời gian để giải thích đầy đủ, nhưng một tài khoản tuyệt vời xuất hiện trong sách "Công thức số". Ví dụ, nhìn vào chương 13.2, "Sự tương quan và tự tương quan Sử dụng FFT," trong Bí quyết Numerical trong C . Bạn cũng có thể xem xét acfchức năng của R.
whuber

Mới đối với 'r', vui lòng tử tế: Hàm 'bình thường hóa' được sử dụng trong âm mưu kết hợp (âm mưu thứ 2) sẽ không hoạt động với tôi, có bản cập nhật nào cho chức năng này không khi câu trả lời này được đăng?
CmKndy

1
@CmKndy Tôi cũng mới biết R, khi tôi đăng câu trả lời này và chỉ quên cung cấp một định nghĩa cho chức năng đó. Đây là bản gốc:normalize <- function(x) { x.max <- max(x); x.min <- min(x); dx <- x.max - x.min; if (dx==0) dx <- 1; (x-x.min) / dx }
whuber

Hoàn hảo, cảm ơn bạn @whuber. Nếu bạn có thể đăng câu trả lời như thế này khi bạn chưa quen với R, tôi thậm chí còn mới hơn tôi nghĩ;)
CmKndy
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.