是否存在对变化不敏感的差异度量?

信息处理 离散信号 信号分析 波形相似度
2022-01-29 00:24:31

我试图找出一种对时间变化相对不敏感的差异度量。

我试过DTW(动态时间扭曲。)

这是结果:

以下

左边的信号显然比右边的信号更相似,但由于时间变化,我得到的左边比右边更大的标准化差异。

有什么措施/技术可以用来克服这个问题吗?我将调查频域,但我想要这个社区的意见。

3个回答

通过设计的时间散射产生时移不变的表示,并控制所需的不变性的量。一个优点是能够在感兴趣的频率范围内进行比较,而不是全部进行比较。

是连续小波变换,其次是模数和低通滤波;很好的讲座

在此处输入图像描述

Distance with T=2048: 0.022988
Distance with T=1024: 0.172749
Distance with T=512:  0.415810

代码

只能从开发分支运行,库正在为下一个版本进行翻新。

import numpy as np
import scipy.signal
from kymatio import Scattering1D
from kymatio.visuals import plot, imshow

def _l2(x):
    return np.sqrt(np.sum(np.abs(x)**2))

def l2(x0, x1):
    """Squared relative distance measure."""
    return _l2(x1 - x0) / _l2(x0)

#%% configure scattering & signal ############################################
N = 4096
Q = 16
J = 9
width = N//8
shift = N//8
# set amounts of invariance
T0, T1 = N//4, N//8
freq_fracs = (4, 8, 16, 32)

#%% make signal & shifted ####################################################
window = scipy.signal.tukey(width, alpha=0.5)
window = np.pad(window, (N - width) // 2)
t  = np.linspace(0, 1, N, endpoint=False)
x  = np.sum([np.cos(2*np.pi * N/ff * t) for ff in freq_fracs], axis=0
            ) * window
xs = np.roll(x, shift)

#%% visualize signals ########################################################
plot(x,  title="x, original",    show=1)
plot(xs, title="x, timeshifted", show=1)

#%% make scattering objects ##################################################
max_order = 1  # 2 yields better results but requires understanding; see docs
kw = dict(J=J, Q=Q, shape=N, average=1, out_type="array", pad_mode="zero",
          max_pad_factor=1, frontend='numpy', max_order=1)
ts0 = Scattering1D(T=T0, **kw)
ts1 = Scattering1D(T=T1, **kw)
#%% scatter 
out0_x  = ts0.scattering(x)
out0_xs = ts0.scattering(xs)
out1_x  = ts1.scattering(x)
out1_xs = ts1.scattering(xs)

#%% compute & print distances ################################################
l2_0 = l2(out0_x, out0_xs)
l2_1 = l2(out1_x, out1_xs)
print("Distance with T={}: {:.6f}".format(T0, l2_0))
print("Distance with T={}: {:.6f}".format(T1, l2_1))

#%% visualize coeffs
imshow(out0_x,  title="scattering(x), original    | T=%s" % T0, abs=1)
imshow(out0_xs, title="scattering(x), timeshifted | T=%s" % T0, abs=1)
imshow(out1_x,  title="scattering(x), original    | T=%s" % T1, abs=1)
imshow(out1_xs, title="scattering(x), timeshifted | T=%s" % T1, abs=1)

您可以对数据进行上采样以增加样本密度并在两个信号之间执行互相关以确定时间偏移。然后按照你已经存在的偏移量和差异来移动信号。

我看到两个主要选项:数据转换或广泛搜索。

首先,傅立叶变换的幅度谱对于信号中的整数偏移是不变的,并且在实践中对非整数偏移不敏感。其他变换具有类似的特征。您可以从这里构建仅基于转换的某些部分或特征的度量。其他变换称为移位不变或几乎移位不变:它们更等变,但也可以使用。

其次,当信号不是很长时,您可以测量一个(的所有变化之间的差异您甚至可以使用子整数符号。s1(k)s2(kl)

最后,这两种方法可以结合使用。在你的情况下,我会选择基本的傅立叶方法,因为信号看起来很相似。