Hankel Singular Value Decompositionによる時系列データの前処理
HSVD
Hankel Singular Value Decomposition(HSVD)は時系列データを低周波と高周波の2つの成分に分解する手法です.HSVDを使用して時系列データの前処理をします.
Embedding
まず最初に,個の時系列データ を以下のような窓サイズのハンケル行列H(正確にはハンケル行列は正方行列なのでちょっと違います...)に変換します.
Decomposition
得られたハンケル行列を特異値分解して低ランク近似をして低周波成分を抽出します.
低ランク近似したハンケル行列をとします.
Unembedding
低周波成分を以下のように抽出します.
]
以下の画像のように赤い要素が低周波成分になります.
高周波成分は元のデータから低周波成分を引いたものになります.
例
例としてsin波形にノイズを加えたデータをHSVDで前処理を施します.
データ
分解
低周波
高周波
まとめ
上の画像から元のデータを低周波と高周波に分解できていることが分かると思います. 元のデータ = 低周波 + 高周波 なのでそれぞれの成分を時系列予測アルゴリズムにかけるなどの応用が可能です.
実装
def moving_window_matrix(x,window_size): # Fork from https://qiita.com/bauer/items/48ef4a57ff77b45244b6 n = x.shape[0] stride = x.strides[0] return np.lib.stride_tricks.as_strided(x, shape=(n-window_size+1, window_size), strides=(stride,stride) ).copy() def hsvd(x, window, rank): m = moving_window_matrix(x, window) u, s, vh = np.linalg.svd(m) h = u[:,:rank] @ np.diag(s[:rank]) @ vh[:rank,:] c = h[0,:] c = np.append(c, h[1:,-1]) return c, x-c
実装をgithubにあげました
Usage
import numpy as np from tfilter import hsvd N = 500 x = np.sin(np.arange(N) * np.pi/50.0) x = x + np.random.normal(0, 0.3, size=N) window = 100 rank = 2 low_freq, high_freq = hsvd(x, window, rank)