Estoy tratando de visualizar directamente la relación entre los coeficientes de detalle de la transformada wavelet discreta (DWT) y la señal original / su reconstrucción. El objetivo es mostrar su relación de forma intuitiva. Me gustaría preguntar (ver preguntas a continuación): si la idea y el proceso que se me ocurren son correctos hasta ahora, y si estoy en lo cierto, podría ser mejor restar la aproximación del primer nivel de la señal original antes de visualizar su relación .
Ejemplo mínimo
Este es el ejemplo mínimo en el que baso mi explicación, utilizando los datos de ejemplo de ECG de Pythonpywavelets
, que tiene 1024 valores, como una simple señal 1D:
import pywt
import pywt.data
import numpy as np
import matplotlib.pyplot as plt
x = pywt.data.ecg()
plt.plot(x)
plt.legend(['Original signal'])
La descomposición se realiza utilizando un Symmlet 5 con un total de 6 niveles:
w = pywt.Wavelet('sym5')
plt.plot(w.dec_lo)
coeffs = pywt.wavedec(x, w, level=6)
La reconstrucción (con pérdida) de la señal funciona como se espera cuando se omiten intencionalmente los coeficientes de detalle de los niveles superiores (las señales se trazan en una escala x uniforme [0,1] por conveniencia):
def reconstruction_plot(yyy, **kwargs):
"""Plot signal vector on x [0,1] independently of amount of values it contains."""
plt.plot(np.linspace(0, 1, len(yyy)), yyy, **kwargs)
reconstruction_plot(pywt.waverec(coeffs, w)) # full reconstruction
#reconstruction_plot(pywt.waverec(coeffs[:-1] + [None] * 1, w)) # leaving out detail coefficients up to lvl 5
#reconstruction_plot(pywt.waverec(coeffs[:-2] + [None] * 2, w)) # leaving out detail coefficients up to lvl 4
#reconstruction_plot(pywt.waverec(coeffs[:-3] + [None] * 3, w)) # leaving out detail coefficients up to lvl 3
reconstruction_plot(pywt.waverec(coeffs[:-4] + [None] * 4, w)) # leaving out detail coefficients up to lvl 2
#reconstruction_plot(pywt.waverec(coeffs[:-5] + [None] * 5, w)) # leaving out detail coefficients up to lvl 1
reconstruction_plot(pywt.waverec(coeffs[:-6] + [None] * 6, w)) # leaving out all detail coefficients = reconstruction using lvl1 approximation only
plt.legend(['Full reconstruction', 'Reconstruction using detail coefficients lvl 1+2', 'Reconstruction using lvl 1 approximation only'])
El DWT anterior produce un vector de aproximación de nivel 1 de 24 valores, un vector de coeficiente de detalles de nivel 1 de 24 valores, un vector de detalle de nivel 2 de 40 valores, el nivel 3 de 72 valores, el nivel 4 de 135 valores, el nivel 5 de 262 valores y el nivel 6 de 516 valores:
plt.stem(coeffs[1]); plt.legend(['Lvl 1 detail coefficients'])
plt.stem(coeffs[2]); plt.legend(['Lvl 2 detail coefficients'])
plt.stem(coeffs[3]); plt.legend(['Lvl 3 detail coefficients'])
plt.stem(coeffs[4]); plt.legend(['Lvl 4 detail coefficients'])
plt.stem(coeffs[5]); plt.legend(['Lvl 5 detail coefficients'])
plt.stem(coeffs[6]); plt.legend(['Lvl 6 detail coefficients'])
Parece que vemos patrones claros alrededor de los picos en las señales originales (también preste atención a la escala y de los gráficos de arriba).
Ahora a mis preguntas:
- ¿Es correcto que podamos relacionar directamente esos coeficientes con la señal? La amplitud del coeficiente corresponde a la amplitud con la que se produce la wavelet en la señal (eje y), y la posición del coeficiente corresponde al tiempo (eje x). ¿O hay algo en el medio que debemos considerar?
Después del DWT, la aproximación final lvl1 permanece. ¿Tiene sentido no visualizar la relación de los coeficientes de detalle con la señal original, sino con la señal original menos la aproximación lvl1? (Sé que lo más probable es que también vea la relación entre los coeficientes y la señal sin hacer esto, ver, por ejemplo, las gráficas a continuación. Es solo para esto tiene sentido o no. Si tiene sentido para los coeficientes de detalle lvl1, entonces también podría tener sentido para Coeficientes de detalle lvl2 para comparar con la señal original menos la aproximación lvl2, ¿verdad?). Un ejemplo:
# Reconstruction of signal using just lvl1 approximation approx_lvl1 = pywt.waverec(coeffs[:-6] + [None] * 6, w) # interpolate to original amount of samples (necessary due to numeric solution of transformation not yielding same amount of values) approx_lvl1_interp = np.interp(x=np.arange(0, 1024), xp=np.linspace(0, 1024, len(approx_lvl1)), fp=approx_lvl1) x_without_lvl1approx = x - approx_lvl1_interp
La visualización directa de la relación entre los coeficientes de detalle y la señal que uso simplemente traza tanto la señal como los coeficientes en un eje x de [0,1]. Conceptualmente, esto debería ser válido, pero no estoy seguro de si realmente necesitaría un desplazamiento hacia los márgenes (por ejemplo, el primer y el último coeficiente del vector que no se coloca al principio o al final de la señal):
def reconstruction_stem(yyy, **kwargs): """Plot coefficient vector on x [0,1] independently of amount of values it contains.""" plt.stem(np.linspace(0, 1, len(yyy)), yyy, **kwargs) reconstruction_plot(x, color='orange') reconstruction_plot(x_without_lvl1approx, color='red') reconstruction_stem(coeffs[1]) plt.legend(['Original signal', 'Original signal - lvl1 approximation', 'Detail coefficients'])
¿Existe una explicación intuitiva para los coeficientes fuertes que no están directamente en las posiciones de los picos en los datos originales (por ejemplo, en el nivel 1, el más bajo (negativo más fuerte) en alrededor de 0.25, así como el más alto (positivo más fuerte) en torno a 0.75 )? Aunque hay un patrón claro (retraso positivo + amplitud negativa, retraso negativo + amplitud positiva), me parecen un poco "lejanos". Pero probablemente haya una buena explicación para eso.
¡Gracias por responder!
fuente
Respuestas:
Es necesario distinguir claramente entre los coeficientes de aproximación y detalle en cada nivel de descomposición y los niveles de Detalles y Aproximación asociados que implican no solo los coeficientes sino también los filtros inversos en ese nivel respectivamente
fuente
Solo ahora estoy empezando a incursionar en las wavelets, y todavía estoy luchando incluso con preguntas muy básicas como "¿cómo se elige entre el grupo de wavelets disponibles" (probablemente tiene que ver con la cantidad de niveles que necesita para alcanzar "lo suficientemente bueno" representación), y "de qué se trata todo el alboroto sobre la eliminación de ruido con wavelets", porque parece que soy capaz de lograr mejores resultados para mi tipo de datos con la eliminación de ruido gaussiano directo o los filtros de mediana. Pero yo divago....
Una cosa que noté en lo anterior es que su numeración de niveles parece inconsistente con lo que creo que son las convenciones de wavelet habituales. En particular, coeffs [0] es la amplitud de aproximación en el último nivel, en su caso 6 coeffs [1] es la amplitud de detalle en el nivel 6 coeffs [2] es la amplitud de detalle en el nivel 5 ... coeffs [6] es el amplitud de detalle en el nivel 1
Por lo tanto, sus reconstrucciones son solo del nivel 5 y 6, no del nivel 1 y 2 como se indica en sus parcelas.
=========
Actualización: Me equivoqué más con su código, y creo que su idea de ilustrar la correlación entre los coeficientes y las características de la señal es sólida, pero no perfecta. He revisado un poco tu código para ilustrarlo mejor, ver más abajo. Tenga en cuenta que en cada paso vuelvo a escalar los coeficientes a la magnitud de la señal. Esto permite hablar sobre el concepto de umbral también.
fuente