離散ウェーブレット変換-分解された詳細係数と信号間の関係の可視化


12

離散ウェーブレット変換(DWT)詳細係数と元の信号/その再構成との関係を直接視覚化しようとしています。目標は、それらの関係を直感的な方法で示すことです。質問したい(下記の質問を参照):私が思いついたアイデアとプロセスがこれまでに正しいかどうか、そして関係を視覚化する前に元の信号から第1レベルの近似値を差し引くほうがよいと私が正しい場合。

最小限の例

これは、1024の値を持つPythonのECGサンプルデータを単純な1D信号として使用して、私が説明の基にした最小限の例です。pywavelets

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'])

元の信号

分解は、合計6レベルのSymmlet 5を使用して行われます。

w = pywt.Wavelet('sym5')
plt.plot(w.dec_lo)
coeffs = pywt.wavedec(x, w, level=6)

(不可逆)信号の再構成は、意図的に高レベルの詳細係数を除外したときに期待どおりに機能します(信号は、便宜上、均一なxスケール[0,1]にプロットされています)。

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'])

再構成された信号

上記のDWTは、24値のレベル1近似ベクトル、24値のレベル1詳細係数ベクトル、40値のレベル2詳細ベクトル、72値のレベル3、135値のレベル4、262値のレベル5、およびレベルを生成します。 516の値の6:

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'])

レベル1の詳細係数 レベル2の詳細係数 レベル3の詳細係数 レベル4の詳細係数 レベル5の詳細係数 レベル6の詳細係数

元の信号のスパイクの周りに明確なパターンが見られるようです(上記のプロットのyスケールにも注意してください)。

今私の質問に:

  1. これらの係数を信号に直接関連付けることができるのは正しいですか?係数の振幅は信号(y軸)でウェーブレットが発生する振幅に対応し、係数の位置は時間(x軸)に対応します。それとも、検討する必要がある間に何かありますか?
  2. DWTの後、最終的なlvl1近似が残ります。元の信号と詳細係数の関係を視覚化するのではなく、元の信号からlvl1近似を引いたものを視覚化することは理にかなっていますか?(私はこれを行わずに係数と信号の関係も確認する可能性が高いことを知っています。たとえば、以下のプロットを参照してください。これが意味があるかどうかはわかりません。lvl1詳細係数に意味があるとしたら、それも意味があるかもしれません。元の信号と比較するlvl2詳細係数からlvl2近似値を差し引いたものですよね?)例:

    # 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
    
  3. 詳細係数と信号の関係を直接視覚化すると、信号と係数の両方が[0,1]のx軸にプロットされます。これは概念的には有効ですが、マージンへのオフセットが実際に必要かどうかはわかりません(たとえば、ベクトルの最初と最後の係数が信号の最初または最後に配置されていないなど)。

    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'])
    

詳細係数lvl1と信号の関係 詳細係数lvl2と信号の関係 詳細係数lvl3と信号の関係 詳細係数lvl4と信号の関係 詳細係数lvl5と信号の関係 詳細係数lvl6と信号の関係

元のデータのピークの位置に直接ない強い係数についての直感的な説明はありますか(たとえば、レベル1では、0.25付近で最低のもの(最も強い負)、および0.75あたりで最高のもの(最も強い正) )?明確なパターン(正のラグ+負の振幅、負のラグ+正の振幅)がありますが、それらは少し "遠く"に見えます。しかし、それについてはおそらく良い説明があります。

回答ありがとうございます!


回答は得られませんでしたが、質問自体はPythonにウェーブレット分析を実装するための優れたチュートリアルです。ありがとうございました!
Farzad

回答:


1

各分解レベルでの近似係数と詳細係数、および関連するレベルの詳細と近似を明確に区別する必要があります。これには、係数だけでなく、そのレベルの逆フィルターも含まれます。


0

私は今、ウェーブレットに手を出し始めており、「利用可能なウェーブレットの群れからどのように選択するか」などの非常に基本的な質問でさえも苦労しています(おそらく「十分に良い」を達成するために必要なレベルの数に関係しています)表現)、そして「ウェーブレットによるノイズ除去に関するすべてのフープラは何か」です。これは、ストレートガウスノイズ除去または中央値フィルターを使用して、私のタイプのデータに対してより良い結果を達成できるようです。しかし、私は余談です...

上記で述べたことの1つは、レベルの番号付けが、通常のウェーブレットの慣習で私が信じているものと一致していないように見えることです。特にcoeffs [0]は最後のレベルでの近似振幅です。あなたの場合、6 coeffs [1]はレベル6での詳細振幅ですcoeffs [2]はレベル5での詳細振幅です... coeffs [6]はレベル1の詳細振幅

したがって、プロットに示されているように、レベル1と2ではなく、レベル5と6のみから再構築します。

=========

更新:私はあなたのコードをもっといじりました、そしてあなたは係数と信号の特徴との間の相関関係を説明するあなたの考えは確かですが完璧ではないと思います。これをよりよく説明するために、コードを少し変更しました。以下を参照してください。各ステップで係数を信号の大きさに再スケーリングすることに注意してください。これにより、しきい値処理の概念についても説明できます。

import pywt
import pywt.data
import numpy as np
import matplotlib.pyplot as plt

plt.close('all')

def reconstruction_plot(yyy, **kwargs):
    """Plot signal vector on x [0,1] independently of amount of values it contains."""
    #plt.figure()
    #plt.plot(np.linspace(0, 1, len(yyy)), yyy, **kwargs)
    ym = np.median(yyy)
    plt.plot(np.linspace(0, 1., num=len(yyy)), yyy-ym, **kwargs)


def reconstruction_stem(yyy, xmax, **kwargs):
    """Plot coefficient vector on x [0,1] independently of amount of values it contains."""
    ymax = yyy.max()
    plt.stem(np.linspace(0, 1., num=len(yyy)), yyy*(xmax/ymax), **kwargs)


x = pywt.data.ecg()
w = pywt.Wavelet('sym5')
nl = 6
coeffs = pywt.wavedec(x, w, level=nl)


'''
plt.figure()
plt.stem(coeffs[1]); plt.legend(['Lvl 6 detail coefficients'])
plt.figure()
plt.stem(coeffs[2]); plt.legend(['Lvl 5 detail coefficients'])
plt.figure()
plt.stem(coeffs[3]); plt.legend(['Lvl 4 detail coefficients'])
plt.figure()
plt.stem(coeffs[4]); plt.legend(['Lvl 3 detail coefficients'])
plt.figure()
plt.stem(coeffs[5]); plt.legend(['Lvl 2 detail coefficients'])
plt.figure()
plt.stem(coeffs[6]); plt.legend(['Lvl 1 detail coefficients'])
'''


xmax = x.max()
for i in range(nl):
    plt.figure()
    reconstruction_plot(x) # original signal 
    #reconstruction_plot(pywt.waverec(coeffs, w)) # full reconstruction 
    reconstruction_plot(pywt.waverec(coeffs[:i+2] + [None] * (nl-i-1), w)) # partial reconstruction 
    reconstruction_stem(coeffs[i+1], xmax, markerfmt ='none', linefmt='r-')
    #plt.legend(['Original', 'Full reconstruction', ('Rec to lvl %d')%(nl-i), ('Details for lvl %d')%(nl-i)])
    plt.legend(['Original', ('Rec to lvl %d')%(nl-i), ('Details for lvl %d')%(nl-i)])
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.