【问题标题】:Similarity between two signals: looking for simple measure两个信号之间的相似性:寻找简单的度量
【发布时间】:2014-01-05 19:57:43
【问题描述】:

我在 A 组中有 20 个信号(时间进程),在 B 组中有 20 个信号。我想找到一个度量来表明 A 组与 B 组不同。例如,我为每个信号中的信号运行 xcorr团体。但现在我需要以某种方式比较它们。我试图取每个 xcorr 对的最大振幅,这是最大相似度的一种度量。然后我比较了两组之间的所有这些值,但没有区别。我还可以做些什么?我也可以比较频谱,但是我又不知道该采用什么频率箱。 任何建议/参考都非常感谢!

我在每组中大约有 20 个信号。这些是我的样品。我不知道先验可能有什么区别。在这里,我为每个组带来了 9 个样本信号,以及它们对信号子集的自相关和互相关(第 1 组与第 1 组、第 2 组与第 2 组、第 1 组与第 2 组)。我没有看到任何明显的区别。我也不明白你建议如何比较互相关,我应该取什么峰?所有信号都经过去趋势和 z 评分。

【问题讨论】:

  • 您能告诉我们每个波形中的样本数吗?有没有明显的周期性?信号与其自身的自相关(功率谱)通常可以很好地指示存在的信号种类。并且 A 中不同信号(“相似”)之间的互相关可能高于相应的 AB 相关。您期望它们有何不同?最终测试应该是:取两个随机信号(可能来自A,可能来自B)。进行测试。如果测试值相同,否则->不同?显示统计差异。
  • 这里我将详细信息添加到我的原始帖子中。
  • 您说您对它们进行了去趋势化和 z 评分。也许趋势线的斜率或信号的均值和方差是您需要的。现在它们看起来都像噪音。
  • 我必须去趋势,因为趋势是由测量设备引入的。当我比较两组之间的简单标准时,它也没有什么不同。显然,信号是相似的——否则我会太简单了:)问题我还能尝试什么措施?
  • 我认为您的图片标记不正确?我不认为不对称信号应该是自相关。

标签: matlab signals signal-processing


【解决方案1】:

参考上面 Brian 的回答,我编写了一个 Python 函数来计算时间序列信号的相似度,如下所示;

def compute_similarity(ref_rec,input_rec,weightage=[0.33,0.33,0.33]):
    ## Time domain similarity
    ref_time = np.correlate(ref_rec,ref_rec)    
    inp_time = np.correlate(ref_rec,input_rec)
    diff_time = abs(ref_time-inp_time)

    ## Freq domain similarity
    ref_freq = np.correlate(np.fft.fft(ref_rec),np.fft.fft(ref_rec)) 
    inp_freq = np.correlate(np.fft.fft(ref_rec),np.fft.fft(input_rec))
    diff_freq = abs(ref_freq-inp_freq)

    ## Power similarity
    ref_power = np.sum(ref_rec**2)
    inp_power = np.sum(input_rec**2)
    diff_power = abs(ref_power-inp_power)

    return float(weightage[0]*diff_time+weightage[1]*diff_freq+weightage[2]*diff_power)

【讨论】:

    【解决方案2】:

    嗯,这可能是一个过于简单的答案,过于复杂的衡量标准,但也许它值得。

    为了比较信号,我们确实必须建立一些标准来比较它们。这可能是很多事情。如果我们想要看起来相似的信号,我们执行时域分析。如果我们谈论的是听起来相似的音频信号,我们关心的是频率或时频分析。如果信号应该代表噪声,那么信号方差应该是一个很好的衡量标准。一般来说,我们可能希望使用各种措施的组合。我们可以使用加权指数来做到这一点。

    首先让我们确定我们所拥有的:有两组信号:A 组和 B 组。我们需要一些测量来显示 A 组与 B 组不同。信号是去趋势的。

    我们在 A 中获取信号 a,在 B 中获取信号 b。我们可以比较的事物列表:

    • 时域相似度(静态):就地相乘并求和。

    • 时域相似性(带移位*):对每个信号取 fft, 乘法,并且IFFT。 (我相信这相当于matlab的xcorr。)

    • 频域相似度(静态**):对每个信号取 fft, 相乘,相加。

    • 频域相似度(带移位*):将两者相乘 信号并采取fft。这将显示信号是否共享相似 光谱形状。

    • 能量的相似性(或不同长度的功率):将两者平方 信号并对每个信号求和(除以信号长度以获得功率)。 (自从 信号没有趋势,这应该是信号方差。)然后 减去并取绝对值以测量信号方差 相似度。

    *(带移位)——您可以选择对整个相关向量求和以测量总的一般相关性,您可以选择仅对相关向量中超过某个阈值的值求和(就好像您期望一个信号在另一个信号中),或者只是从相关向量中取最大值(其中它的索引是第二个信号中的偏移,导致与第一个信号的最大相关性)。此外,如果达到最大相关性所需的偏移量很重要(即,如果信号相似,仅当它需要相对较小的偏移才能达到最大相关点时),那么您可以结合索引位移的度量。

    **(频域相似性)——您可能想要屏蔽您不关心的部分频谱,例如,如果您只关心更高频率的结构(fs/4 及以上),你可以这样做:

    mask = zeros(1,n); mask(n/4):
    freq_static = mean(fft(a) .* fft(b) .* mask);
    

    此外,我们可能希望像这样实现循环关联:

    function c = circular_xcorr(a,b)
    c = xcorr(a,b);
    mid = length(c) / 2;
    c = c(1:mid) + c(mid+1:end);
    end
    

    最后,我们选择重要或相关的特征,并创建一个加权指数。示例:

    n = 100;
    a = rand(1,n); b = rand(1,n);
    time_corr_thresh = .8 * n; freq_corr_thresh = .6 * n;
    time_static = max(a .* b);
    time_shifted = circular_xcorr(a,b);    time_shifted = sum(time_shifted(time_shifted > time_corr_thresh));
    freq_static = max(fft(a) .* fft(b));
    freq_shifted = fft(a .* b);     freq_shifted = sum(freq_shifted(freq_shifted > freq_corr_thresh));
    w1 = 0; w2 = 1; w2 = .7; w3 = 0;
    index = w1 * time_static + w1 * time_shifted + w2 * freq_static + w3 * freq_shifted;
    

    我们为每对信号计算这个索引。

    我希望这个信号表征大纲能有所帮助。如果有任何不清楚的地方,请发表评论。

    【讨论】:

    • 非常感谢您的回答!我会努力的,并会在这里更新你。仅就总体框架而言。据我了解,有三种可能的方法来确定效果: 1. 比较每组内所有可能的配对,并使用 t 检验表明我的相似性度量在两组之间存在显着差异。 2.比较每个组内和两组之间的所有可能对,并表明我在组内的相似性度量大于组间。
    • 3.如果对于每个信号我有两个测量值(两个示例),那么我可以计算每组的每个样本的这两个示例之间的相似性,然后使用 t 检验比较组之间的结果(如 [1] 中)。这个结果也将给我一个可重复性的衡量标准。有意义吗?
    • 哦,是的!我认为这会很好。很高兴你问这个问题,因为我可能很快就会对我的闪烁研究进行类似的组相似性测试:)
    • 这篇文章很古老。你还在追吗?您描述的方法非常接近我需要做的,但我对信号分析和 Matlab 的熟悉程度低于你们中的任何一个。有没有机会,你能帮我提供一个链接,让我更完整地解释如何加权互相关和 FFT 的频率,最好用 Matlab、R 或 python 中的一些代码?
    • @JohnStrong 你有没有得到任何地方?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-11-17
    • 2021-10-12
    • 1970-01-01
    • 2016-09-01
    相关资源
    最近更新 更多