在MATLAB中使用xcorr
来交叉关联2个相关数据集时,一切都按预期工作 - 我看到一个相关峰值,报告的滞后是正确的。但是,当我使用xcorr
来交叉关联不相关的数据集时,其中两个数据集都包含1个" spikes"的集群,我看到一个相关峰值,报告的滞后是2个峰值之间的距离。
在此图片中:
x
是一个随机数据系列。 y
也是一个随机数据系列。 x
和y
都有30个随机峰序列插入序列中。从理论上讲,两个数据集之间应该没有相关性,因为它们都非常不同。但是,从第3个图可以看出,2个数据集之间存在非常强的相关性。用于生成此图的代码位于此帖的底部。
在执行xcorr
之前,我尝试使用一些不同的机制(滚动rms功率等)来过滤尖峰。这在某些情况下有效但并非全部。我觉得我需要一种不同的方法解决问题,可能是xcorr
的替代方案。我确实理解为什么x
和y
使用xcorr
进行交叉关联。我可以使用另一种互相关工具吗?注意x
和y
永远不会完全相同,它们只会大致相同,但在正常操作中,不是应该使它们相关的峰值。
有关如何判断x
和y
是否相关的任何建议,同时忽略了"峰值"?
以下是我的示例代码:
x = rand(1, 3000);
x = x - 0.5;
y = rand(1, 3000);
y = y - 0.5;
% insert the impulses into the data
impulse_width = 30;
impulse_max_height = 6;
x_impulse_start = 460;
y_impulse_start = 120;
rand_insert_x = rand(1, impulse_width);
rand_insert_x = (rand_insert_x - 0.5) * 2 * impulse_max_height;
rand_insert_y = rand(1, impulse_width);
rand_insert_y = (rand_insert_y - 0.5) * 2 * impulse_max_height;
x(1,x_impulse_start:x_impulse_start + impulse_width - 1) = rand_insert_x;
y(1,y_impulse_start:y_impulse_start + impulse_width - 1) = rand_insert_y;
subplot(3, 1, 1);
plot(x);
ylim([-impulse_max_height impulse_max_height]);
title('random data series: x');
subplot(3, 1, 2);
plot(y);
ylim([-impulse_max_height impulse_max_height]);
title('random data series: y');
[c, l] = xcorr(x, y);
subplot(3, 1, 3);
plot(l, c);
title('correlation using xcorr');
答案 0 :(得分:1)
解决这个问题的方法是使用标准化的互相关。
在归一化互相关时,当信号完全相同时,相关性为1,而当信号不相关时,相关性为1。您可以将其视为“相似性百分比”。
要在MATLAB中执行此操作,您只需要将'coeff'
作为参数添加到代码中。
因此,如果我将代码更改为[c, l] = xcorr(x, y,'coeff');
,我得到的图是嵌套:
(注意我将样本大小更改为600以使其更具可读性)
互相关在那里达到0.3,所以不多。但是,如果我们将您的代码行更改为
x(1,x_impulse_start:x_impulse_start + impulse_width - 1) = rand_insert_x;
y(1,y_impulse_start:y_impulse_start + impulse_width - 1) = rand_insert_x;
并在两个信号中插入相同的随机模式,然后我们得到:
现在,互相关变为高值,几乎为1,但不是1,因为那里的大随机模式是相同的,但信号的其余部分不是。
答案 1 :(得分:0)
互相关是两个信号的convolution。想象一下,在互相关期间,两个信号处于滞后状态,如我在此处所示(x轴标签应该被完全忽略):
x系列中的正(+)峰值(〜样本490)乘以y系列(〜样本121)中的负( - )峰值,导致xcorr中的负值很大,我们实际看到底部图(〜样本315)。由于其余信号确实是低功率噪声,因此这个较大的负值将加上接近0的值。我担心无论你使用什么样的xcorr函数,都应该得到相同的结果。实际上,如果有另一个声称是互相关器的函数,但没有给出与typedef enum AIN_Ch { AIN_CH1, AIN_CH2, AIN_CH3 } AIN_Ch_t;
相同的结果,则该函数不应被称为互相关器。我希望这会有所帮助。
答案 2 :(得分:0)
我对这个问题的理解是"如何从我的数据中删除这些峰值?"
答案是找到有关这些峰值的特征,然后测试每个时间窗口的特征。如果该测试通过,那么您已检测到尖峰,并且您应该删除该数据。
例如,您可能会说"尖峰是绝对值大于某个阈值的任何时间点。"您可以使用数据确定阈值,例如0.2。然后你做一些像
这样的事情spikeless_data = data .* (abs(data)<0.2);
在abs(data)<0.2
时复制数据,在没有时将其设置为0。
你还可以注意到尖峰的特征是它们的导数非常大,这可能比简单的阈值更强大。这与spikeless_data = data .* ([abs(diff(data)), 0] < some_threshold);
您必须四处寻找适合您数据的内容。