25 votos

¿Cómo puedo alinear/sincronizar dos señales?

Estoy investigando pero me he quedado atascado en la fase de análisis (debería haber prestado más atención a mis clases de estadística).

He recogido dos señales simultáneas: el flujo integrado para el volumen y el cambio en la expansión del pecho. Me gustaría comparar las señales y, en última instancia, espero obtener el volumen a partir de la señal de expansión torácica. Pero primero tengo que alinear/sincronizar mis datos.

Como la grabación no empieza precisamente al mismo tiempo y la expansión del pecho se captura durante períodos más largos, necesito encontrar los datos que corresponden a mis datos de volumen dentro del conjunto de datos de expansión del pecho y tener una medida de lo bien que están alineados. No estoy muy seguro de cómo hacer esto si las dos señales no comienzan exactamente al mismo tiempo, o entre los datos en diferentes escalas y en diferentes resoluciones.

Adjunto un ejemplo de las dos señales ( https://docs.google.com/spreadsheet/ccc?key=0As4oZTKp4RZ3dFRKaktYWEhZLXlFbFVKNmllbGVXNHc ), por favor, hágame saber si hay algo más que pueda aportar.

0 votos

No conozco esto lo suficientemente bien como para dar una respuesta, y no estoy seguro de que esto aborde la pregunta, pero un enfoque que sincroniza las señales se llama "registro", que es un subconjunto del análisis de datos funcionales. Este tema se trata en el libro de Ramsey y Silverman sobre la FDA. La idea básica es que las señales observadas pueden estar "deformadas" (por ejemplo, si estamos interesados en la mecánica de la forma en que las personas mastican, pero tenemos datos de personas que mastican a diferentes velocidades - el eje de tiempo está "deformado" en este caso) y el registro intenta definir la señal subyacente en una escala común, "no deformada".

1 votos

¿Ha recogido ya todos sus datos? ¿Se trata de un tema piloto? Si acaba de empezar, yo estudiaría la posibilidad de separar la señal de su cinturón y utilizarla como disparador (o incluso sólo para marcar una marca de tiempo) de su registro de flujo. Normalmente, los sistemas de adquisición tienen esta capacidad con un puerto auxiliar o de disparo. Estoy seguro de que hay formas de distinguirlo simplemente usando sus datos como ha sugerido Macro, pero añadir este paso extra le quitará muchas conjeturas.

1 votos

Creo que, usted quiere estimar sólo un retraso fijo. Usted podría utilizar la correlación cruzada como se indica aquí: stats.stackexchange.com/questions/16121/

28voto

jldugger Puntos 7490

La pregunta es cómo encontrar la cantidad por la que una serie temporal ("expansión") se retrasa con respecto a otra ("volumen") cuando las series se muestrean a intervalos regulares pero diferentes intervalos.

En este caso, ambas series presentan un comportamiento razonablemente continuo, como mostrarán las figuras. Esto implica (1) que puede necesitarse poco o ningún suavizado inicial y (2) que el remuestreo puede ser tan sencillo como una interpolación lineal o cuadrática. La cuadrática puede ser ligeramente mejor debido a la suavidad. Tras el remuestreo, el desfase se encuentra maximizando la correlación cruzada como se muestra en el hilo, Para dos series de datos muestreadas con desplazamiento, ¿cuál es la mejor estimación del desplazamiento entre ellas? .


Para ilustrar podemos utilizar los datos suministrados en la pregunta, empleando R para el pseudocódigo. Comencemos con la funcionalidad básica, la correlación cruzada y el remuestreo:

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

Se trata de un algoritmo rudimentario: un cálculo basado en la FFT sería más rápido. Pero para estos datos (que implican unos 4000 valores) es suficiente.

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
}

Descargué los datos como un archivo CSV separado por comas y eliminé su cabecera. (La cabecera causó algunos problemas para R que no me importó diagnosticar).

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

NB Esta solución supone que cada serie de datos está en orden temporal, sin espacios en ninguno de ellos. Esto le permite utilizar índices en los valores como sustitutos del tiempo y escalar esos índices por las frecuencias de muestreo temporal para convertirlos en tiempos.

Resulta que uno o ambos instrumentos se desvían un poco con el tiempo. Es bueno eliminar esas tendencias antes de continuar. Además, como la señal de volumen se estrecha al final, deberíamos recortarla.

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)

Vuelvo a muestrear el menos -series frecuentes para obtener la mayor precisión del resultado.

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

Ahora se puede calcular la correlación cruzada -por eficiencia buscamos sólo una ventana razonable de rezagos- y se puede identificar el rezago donde se encuentra el valor máximo.

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

La salida nos indica que la expansión va por detrás del volumen en 1,85 segundos. (Si los últimos 3,5 segundos de datos no estuvieran recortados, la salida sería de 1,84 segundos).

Es una buena idea comprobar todo de varias maneras, preferiblemente visualmente. Primero, la función de correlación cruzada :

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)

cross-correlation plot

A continuación, vamos a registrar las dos series en el tiempo y trazarlos juntos en los mismos ejes .

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)

Registered plots

Tiene muy buena pinta. Podemos tener una mejor idea de la calidad del registro con un gráfico de dispersión Sin embargo. Varía los colores por tiempo para mostrar la progresió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")

Scatterplot

Buscamos que los puntos vayan y vengan a lo largo de una línea: las variaciones de ésta reflejan las no linealidades en la respuesta temporal de la expansión al volumen. Aunque hay algunas variaciones, son bastante pequeñas. Pero.., cómo estas variaciones cambian con el tiempo puede ser de cierto interés fisiológico. Lo maravilloso de la estadística, especialmente su aspecto exploratorio y visual, es cómo tiende a crear buenas preguntas y ideas junto con útiles respuestas.

1 votos

Santo cielo, eres increíble. La correlación cruzada es exactamente lo que me imaginaba (sabía que tenía que haber un nombre para ello) pero tu respuesta/explicación ha ido más allá. Muchas gracias.

0 votos

No tengo tiempo para una explicación completa ahora, pero un gran relato aparece en los libros de "Recetas Numéricas". Por ejemplo, mire el capítulo 13.2, "Correlación y autocorrelación utilizando la FFT", en Recetas numéricas en C . También puedes buscar en R's acf función.

0 votos

Nuevo en 'r', por favor sea amable: La función "normalizar" utilizada en el gráfico combinado (2do. último gráfico) no me funciona, ¿hay alguna actualización de esta función desde que se publicó esta respuesta?

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X