Bagaimana saya bisa menyelaraskan / menyinkronkan dua sinyal?

21

Saya sedang melakukan beberapa penelitian tetapi telah terjebak pada tahap analisis (seharusnya lebih memperhatikan kuliah statistik saya).

Saya telah mengumpulkan dua sinyal simultan: laju aliran terintegrasi untuk volume dan perubahan ekspansi dada. Saya ingin membandingkan sinyal dan akhirnya berharap untuk mendapatkan volume dari sinyal ekspansi dada. Tetapi pertama-tama saya harus menyelaraskan / menyinkronkan data saya.

Karena perekaman tidak dimulai tepat pada waktu yang sama dan ekspansi dada ditangkap untuk periode yang lebih lama, saya perlu menemukan data yang sesuai dengan data volume saya dalam set data ekspansi dada dan memiliki ukuran seberapa baik mereka disejajarkan. Saya tidak yakin bagaimana cara melakukannya jika kedua sinyal tidak mulai pada waktu yang sama, atau antara data pada skala yang berbeda dan pada resolusi yang berbeda.

Saya telah melampirkan contoh dari dua sinyal ( https://docs.google.com/spreadsheet/ccc?key=0As4oZTKp4RZ3dFRKaktYWEhZLXlFbFVKNmllbGVXNHc ), beri tahu saya jika ada hal lain yang bisa saya berikan.

orang157
sumber
Saya tidak tahu ini cukup baik untuk memberikan jawaban, dan saya tidak yakin ini menjawab pertanyaan, tetapi satu pendekatan menyinkronkan sinyal disebut "pendaftaran", yang merupakan bagian dari analisis data fungsional. Topik ini dibahas dalam buku FDA Ramsey dan Silverman. Ide dasarnya adalah bahwa sinyal yang diamati mungkin "bengkok" (misalnya jika kita tertarik pada mekanisme cara orang mengunyah tetapi kita memiliki data tentang orang yang mengunyah dengan kecepatan yang berbeda - sumbu waktu "bengkok" dalam kasus ini) dan pendaftaran mencoba untuk mendefinisikan sinyal yang mendasarinya pada skala umum, "tidak beralasan".
Makro
1
Sudahkah Anda mengumpulkan semua data Anda? Apakah ini subjek uji coba? Jika Anda baru memulai, saya akan melihat memisahkan sinyal dari ikat pinggang Anda dan menggunakannya sebagai pemicu (atau bahkan hanya untuk menandai cap waktu) rekaman aliran Anda. Biasanya sistem akuisisi memiliki kemampuan ini dengan port bantu atau pemicu. Saya yakin ada beberapa cara untuk membedakannya hanya dengan menggunakan data Anda seperti yang disarankan Macro, tetapi menambahkan langkah ekstra ini akan menghilangkan banyak dugaan.
jonsca
1
Saya pikir, Anda ingin memperkirakan hanya penundaan yang tetap. Anda dapat menggunakan korelasi-silang seperti diuraikan di sini: stats.stackexchange.com/questions/16121/…
thias
1
Anda mungkin ingin mengajukan pertanyaan ini pada dsp.SE di mana mereka juga berpikir tentang sinkronisasi sinyal.
Dilip Sarwate
1
@ Tias benar, tetapi tampaknya satu seri pertama harus diresampled sehingga mereka memiliki interval yang sama.
Whuber

Jawaban:

24

Pertanyaannya adalah bagaimana menemukan jumlah yang satu seri waktu ("ekspansi") tertinggal dari yang lain ("volume") ketika seri sampel pada interval reguler tetapi berbeda .

Dalam hal ini kedua seri menunjukkan perilaku yang cukup berkelanjutan, seperti yang ditunjukkan oleh gambar. Ini menyiratkan (1) sedikit atau tidak ada pemulusan awal mungkin diperlukan dan (2) resampling dapat sesederhana interpolasi linier atau kuadratik. Kuadrat mungkin sedikit lebih baik karena kehalusannya. Setelah melakukan resampling, lag ditemukan dengan memaksimalkan korelasi silang , seperti yang ditunjukkan dalam utas, Untuk dua seri data sampel offset, apa estimasi terbaik offset di antara mereka? .


Untuk mengilustrasikannya , kita dapat menggunakan data yang disediakan dalam pertanyaan, yang digunakan Runtuk kodesemu. Mari kita mulai dengan fungsionalitas dasar, korelasi silang dan resampling:

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

Ini adalah algoritma kasar: perhitungan berbasis FFT akan lebih cepat. Tetapi untuk data ini (melibatkan sekitar 4.000 nilai) cukup baik.

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
}

Saya mengunduh data sebagai file CSV yang dipisah koma dan melepas header-nya. (Header menyebabkan beberapa masalah untuk R yang saya tidak mau diagnosa.)

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

NB Solusi ini mengasumsikan setiap seri data dalam urutan temporal tanpa celah di salah satu dari keduanya. Ini memungkinkannya untuk menggunakan indeks ke dalam nilai sebagai proksi untuk waktu dan untuk skala indeks tersebut dengan frekuensi temporal sampling untuk mengubahnya menjadi waktu.

Ternyata satu atau kedua instrumen ini melayang sedikit dari waktu ke waktu. Ada baiknya untuk menghapus tren seperti itu sebelum melanjutkan. Juga, karena ada pengurangan sinyal volume di bagian akhir, kita harus memotongnya.

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)

Saya menguji ulang seri yang kurang sering untuk mendapatkan hasil yang paling presisi.

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

Sekarang korelasi silang dapat dihitung - untuk efisiensi kami hanya mencari jendela keterlambatan yang masuk akal - dan kelambatan di mana nilai maksimum ditemukan dapat diidentifikasi.

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

Output memberi tahu kita bahwa ekspansi memperlambat volume sebesar 1,85 detik. (Jika 3,5 detik terakhir data tidak terpotong, output akan menjadi 1,84 detik.)

Sebaiknya periksa semuanya dengan beberapa cara, terutama secara visual. Pertama, fungsi korelasi silang :

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)

plot korelasi silang

Selanjutnya, mari kita daftarkan dua seri dalam waktu dan plot bersama pada sumbu yang sama .

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)

Plot terdaftar

Terlihat bagus! Namun, kami bisa lebih memahami kualitas pendaftaran dengan sebaran . Saya memvariasikan warna pada waktu untuk menunjukkan perkembangan.

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

Scatterplot

Kami mencari titik untuk melacak bolak-balik sepanjang garis: variasi dari yang mencerminkan nonlinier dalam respons ekspansi volume terhadap waktu yang terlambat. Meskipun ada beberapa variasi, mereka cukup kecil. Namun, bagaimana variasi ini berubah dari waktu ke waktu mungkin merupakan hal yang menarik secara fisiologis. Hal yang luar biasa tentang statistik, terutama aspek eksplorasi dan visualnya, adalah bagaimana statistik cenderung menciptakan pertanyaan dan gagasan yang baik bersama dengan jawaban yang bermanfaat .

whuber
sumber
1
Astaga, kau luar biasa. Korelasi-silang adalah persis apa yang saya bayangkan (saya tahu harus ada nama untuk itu) tetapi jawaban / penjelasan Anda melampaui dan melampaui. Terima kasih banyak!
orang157
Saya tidak punya waktu untuk penjelasan lengkap sekarang, tetapi akun yang bagus muncul di buku "Numerical Recipes". Misalnya, lihat bab 13,2, "Korelasi dan Autokorelasi Menggunakan FFT," di Numerical Recipes dalam C . Anda juga bisa melihat acffungsi R.
whuber
Baru mengenal 'r', harap berbaik hati: Fungsi 'normalisasi' yang digunakan dalam plot gabungan (plot terakhir ke-2) tidak akan berfungsi untuk saya, apakah ada pembaruan untuk fungsi ini sejak jawaban ini diposting?
CmKndy
1
@ CmKndy Saya juga baru Rketika saya memposting jawaban ini dan hanya lupa untuk memberikan definisi untuk fungsi itu. Ini aslinya: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
Sempurna, terima kasih @whuber. Jika Anda dapat memposting jawaban seperti ini ketika Anda masih baru di R, saya bahkan lebih baru dari yang saya kira;)
CmKndy