我正在尝试对金融时间序列数据进行去噪(每秒)。我有一个很长的时间序列,但是我一直在处理100,000个观测值,目的只是测试小波去噪(haar)的效果。不是。
无论我做什么,重建的信号最终总是与原始信号几乎相同。显然,我想保留原始信号,但是我觉得该序列只是没有被去噪-一个金融时间序列,其唯一的噪声出现在几秒钟的分辨率内?而且,即使在最小的时间尺度上,重建的图和原始图的图也几乎相同。
我尝试更改母小波,时间序列长度,完成时间序列重构的模式(软对硬),并且很明显,我已经弄乱了阈值本身。我从建议的标准阈值sqrt(2 * log(len(signal)))开始,但这实际上对我没有任何作用,因此我逐渐提高了它,直到达到完全荒谬的2 * len(signal)* * 2-应该可以使图形平滑到无法识别的程度,但基本上什么也没做。
WAVELET = "haar"
LEVEL = 2
signal = training_series
mean = signal.mean()
mean_series = [mean] * len(signal)
signal = [a - b for a, b in zip(signal, mean_series)]
coeffs = pywt.wavedec(signal, WAVELET, level=LEVEL)
sigma = mad(coeffs[-LEVEL])
threshold = sigma * np.sqrt(2*np.log(len(signal)))
coeffs[1:] = (pywt.threshold(i, value=threshold, mode="soft" ) for i in coeffs[1:])
reconstructed_signal = pywt.waverec(coeffs, WAVELET)
我希望重建后的信号会与原始信号明显不同(例如,平滑,去噪,更少……与原始信号相同),但事实并非如此。以最小的比例(每10或20秒思考一次,在100,000秒的比例上),存在一些非常小的平滑,基本上只是忽略了大小为0.01(可能的最小变化)的峰和谷,但几乎可以忽略不计。 / p>
我期望有一个信号,去噪,不知道?我在做错什么吗?
答案 0 :(得分:0)
您的阈值可能太高。
您应该尝试根据每个级别的详细系数,而不是原始时间轨迹,通过度量标准设置它。 通常从以下位置开始:
threshold=np.std(coeff[i])
从那里开始至少要有一个开始。
答案 1 :(得分:0)
我遇到了同样的问题,我发现通过稳步增加阈值的比例因子有所帮助。
我试图对声发射信号进行降噪,但只得到了重建。通过将 sigma 乘以增加的比例因子,我可以找出停止再现信号所需的阈值。
import pywt
import numpy as np
import matplotlib.pyplot as plt
def madev(d, axis=None):
""" Mean absolute deviation of a signal """
return np.mean(np.absolute(d - np.mean(d, axis)), axis)
def wavelet_denoising(x, wavelet, level, s_factor):
"""
deconstructs, thresholds then reconstructs
higher thresholds = less detailed reconstruction
"""
coeff = pywt.wavedec(x, wavelet, mode="per")
sigma = (1/0.6745) * madev(coeff[-level])*s_factor
uthresh = sigma * np.sqrt(2 * np.log(len(x)))
coeff[1:] = (pywt.threshold(i, value=uthresh, mode='hard') for i in coeff[1:])
return pywt.waverec(coeff, wavelet, mode='per')
wav = 'db4'
level=1
for s_factor in np.arange(0,20, 2):
data = wavelet_denoising(signal, wav, level, s_factor)
plt.plot(data)
plt.title('scale factor = {}'.format(s_factor))
fname = 'wavelet_{}_sf_{}_n_{}'.format(wav, s_factor, len(signal))
plt.savefig(fname)
plt.show()