Matlab:使用互协方差对齐数据
我想在Matlab中获得两个数据集之间的样本偏移量(使它们及时同步),这是一个非常常见的问题。因此,我使用互相关函数xcorr或互协方差函数xcov(这两个函数在大多数情况下都提供类似的结果)。对于人工数据,它工作得很好,但我很难处理“真实”数据,尽管它应该差不多。Matlab总是说偏移量为零。我使用的是一段简单的代码:Matlab:使用互协方差对齐数据,matlab,Matlab,我想在Matlab中获得两个数据集之间的样本偏移量(使它们及时同步),这是一个非常常见的问题。因此,我使用互相关函数xcorr或互协方差函数xcov(这两个函数在大多数情况下都提供类似的结果)。对于人工数据,它工作得很好,但我很难处理“真实”数据,尽管它应该差不多。Matlab总是说偏移量为零。我使用的是一段简单的代码: [crossCorr] = xcov(b, c); [~, peakIndex] = max(crossCorr()) offset = peakIndex - length(
[crossCorr] = xcov(b, c);
[~, peakIndex] = max(crossCorr())
offset = peakIndex - length(b)
我在pastebin上发布了一个完全可运行的示例m文件,其中包含一个下采样数据摘录:
编辑:下采样摘录似乎不完全适合评估效果。不幸的是,它对pastebin来说太大了
如图所示,通过互协方差获得偏移量应该没有任何问题。为了避免数值问题,我还尝试更好地缩放数据,但这丝毫没有改变任何事情
如果有人能告诉我我的错误,那就太好了。您的数据在5左右有一个小峰值,在101左右有一个大峰值 如果我对我的数据有所了解,那么我可能会在如下所示的可接受的偏移范围内打开窗口 初步勘探代码:
figure; clc;
subplot(2,1,1)
plot(1:numel(b), b);
hold on
plot(1:numel(c), c, 'r');
legend('b','c')
subplot(2,1,2)
plot(crossCorr,'.b-')
hold on
plot(peakIndex,crossCorr(peakIndex),'or')
legend('crossCorr','peak')
初始图像:
如果放大第一个峰值,您可以看到它不仅在5左右很高,而且是多项式“足够”允许子元素偏移。那很方便
图像显示:
以下是曲线拟合工具为立方体提供的分析:
Linear model Poly3:
f(x) = p1*x^3 + p2*x^2 + p3*x + p4
Coefficients (with 95% confidence bounds):
p1 = 8.515e-013 (8.214e-013, 8.816e-013)
p2 = -3.319e-011 (-3.369e-011, -3.269e-011)
p3 = 2.253e-010 (2.229e-010, 2.277e-010)
p4 = -4.226e-012 (-7.47e-012, -9.82e-013)
Goodness of fit:
SSE: 2.799e-024
R-square: 1
Adjusted R-square: 1
RMSE: 6.831e-013
您可以注意到,SSE适合舍入。
如果计算根(接近n=4),则使用以下matlab代码:
% Coefficients
p1 = 8.515e-013
p2 = -3.319e-011
p3 = 2.253e-010
p4 = -4.226e-012
% Linear model Poly3:
syms('x')
f = p1*x^3 + p2*x^2 + p3*x + p4
xz1=fzero(@(y) subs(diff(f),'x',y), 4)
得到的解析根是4.014204431444
编辑:
嗯,用高斯混合模型拟合卷积怎么样?扫描一个良好的组件计数范围,重复10到30次,然后找到哪个组件计数具有最佳/最低BIC。因此,将gm分布拟合到第一个图的较低子图中,然后按分量的平均值降序测试协方差
我会尝试平均值的偏移量,只看平方和误差。然后我将选择误差最小的偏移量
程序:
- 计算互相关
- 高斯混合模型的互相关拟合
- 扫掠组件的合理范围(从1-10开始)
- 使用合理的重复次数(10到30次,取决于运行到运行的变化)
- 计算每个级别的Bayes信息标准(BIC),选择最低的,因为它表明错误和参数计数的合理平衡
- 每个分量都有一个平均值,将该平均值作为一个候选偏移量进行评估,并在这样偏移时计算平方和误差(sse)
- 拾取提供最佳SSE的组件的偏移
让我知道它的效果如何。原则上,您的方法没有问题,我成功地使用了完全相同的方法,对同一信号的不同录音进行了临时对齐 然而,对于时间序列而言,相关性(或协方差)显然不是比较移位版本的正确度量——可能是因为它们包含与总长度相当的时间尺度分量。另一种方法是使用剩余方差,即移位版本之间差异的方差。下面是这个想法的一个实现(不是特别优雅):
lags = -1000 : 1000;
v = nan(size(lags));
for i = 1 : numel(lags)
lag = lags(i);
if lag >= 0
v(i) = var(b(1 + lag : end) - c(1 : end - lag));
else
v(i) = var(b(1 : end + lag) - c(1 - lag : end));
end
end
[~, ind] = min(v);
minlag = lags(ind);
对于(较长的)数据集,这将导致minlag=169
。绘制滞后的剩余方差,得出:
如果两个信号因非整数样本数(例如3.7个样本)而不对齐,则xcorr方法可能会在4个样本处找到最大值,它将无法找到准确的时间偏移。在这种情况下,您应该尝试一种称为“统一更改检测”的方法。该论文的网页链接为: [
祝你好运。你的理论数据看起来怎么样?我不完全确定,但可能是你的数据中有几个周期。假设一组数据中有一个峰值在0,另一组数据中有一个峰值在5。那么5与其他数据相比应该有非常高的相关性。但是你的数据就像一个长斜率。0处的值是comparable到5中的值。这将为您提供(正如您可能已经看到的)总的来说,相关性很低。这项技术可能无论如何都会起作用,但这是我的猜测。你可以尝试不同的理论数据并进行比较。谢谢。这是我的。我印象深刻的是,即使是与随机信号振幅相同的噪声也没有问题。真实数据不是周期性的,但他的摘录有点短,但不幸的是,为了让pastebin接受它,我不得不对其进行更多的取样。谢谢你的回答。不幸的是,这种效果似乎不是普遍适用的,它在这里是随机工作的。我已经对数据进行了取样并进行了缩短,以便将其很好地放在pastebin上,这似乎不是正确的决定此示例未显示效果。采样20000后的第一个局部最大值,而偏移量约为160。非常感谢,该方法对我有效。在该实现中,合理范围(预期)所需的时间比xcov函数长得多,但它返回了预期的结果。太好了!应该可以加快速度,但现在我还不清楚如何加快速度。