【问题标题】:measure similarity between 1 dimensional vectors测量一维向量之间的相似度
【发布时间】:2015-02-25 17:08:59
【问题描述】:

已编辑问题

我有 n 个长度相等的信号。

    X_signal
    Y_signal
    ...
    Z_signal

我计算这些信号的最小值并将它们的位置(及时)存储在向量中

X = [x1 x2 x3 x4 ... x100]
Y = [y1 y2 y3 y4 ... y150]
...
Z = [z1 z2 z3 z4 ... z110]

您可以将 X、Y、..Z 视为具有不同长度的时间序列。 如果它们的最小值几乎在相同的位置,我假设原始信号是相似的。

我想知道测量这种相似性的聪明方法是什么,记住 X、Y、Z 中的一些最小值可能只是噪声。

例如,如果 X = [1 5 8 12 15 20] 和 Y = [1.5 5.5 7.5 10 12 15.5 20.2] 它们应该是相似的,因为除了 Y(4) = [10 之外,几乎所有的点都具有相同的值].

如果你有 Matlab 中的时间码或伪代码,不胜感激,否则建议、链接等也很好。

谢谢

原始问题

我有 n 个不同长度的向量。

X = [x1 x2 x3 x4 ... x100]
Y = [y1 y2 y3 y4 ... y150]
...
Z = [z1 z2 z3 z4 ... z110]

向量(X Y ... Z)表示相应信号(X_energy、Y_energy 等)能量的最小值。

回顾从信号 X_signal、Y_signal ... Z_signal 开始,我计算 20 个样本的窗口中的能量,并计算得到的能量信号的最小值。

假设如果两个或多个向量具有几乎相等的值,则它们是相似的(即,如果 x1 ~= y1、x2 ~=y2 等,则 X 和 Y 相似)换句话说,我假设原始信号相似,如果它们在同一(或几乎同一)时刻具有最小能量。我想知道衡量这种相似性的聪明方法是什么。

PS。

  1. 两个向量相等几乎是不可能的,所以我想知道它们的“点”有多接近。
  2. 如果 X 和 Y 移位(即 x1~=y3、x2=~y4 等),它们也可能相似
  3. 值总是按升序排列(x1<x2<...<x100)

如果你有 Matlab 中的时间码或伪代码,不胜感激,否则建议、链接等也很好。

谢谢

【问题讨论】:

  • Mahalanobis distance 会起作用吗?这只是我脑海中的一个建议。
  • 当向量的长度不同时有什么方法?找到匹配的子向量?例如在 [1 4 5 3 7 8 6 7 8] 中找到 [3 7 8] 但要考虑它,因为它与 [3 7 8 6 7] 不太相似......似乎@987654322 @ 可以去,但要小心所有不同的尺寸......嗯,这是第一个想法......
  • @CitizenInsane 谢谢,我会尝试使用 xcorr。只是一个评论(我也编辑了这个问题)。向量的值按升序排列...您可以将它们视为时间序列
  • 虽然@kkuilla 建议的马氏距离不考虑时间变化,但阅读pdist 中的指标和squareform 中的结果格式是很有趣的
  • 由于您对每个条目的确切值的相似性感兴趣,因此您想要评估的似乎不是共线性。相反,您可以利用向量之间的差异来计算 rms 或 mean(abs(diff))。

标签: matlab vector similarity


【解决方案1】:

一种可能的方法(特别是如果您没有统计和/或信号处理工具箱)是使用 Matlab 函数 corrcoef

为所有向量生成相关矩阵

由于你的向量大小不同,你必须要么

  • 对较小的向量进行零填充,使其与最大的向量大小相同

  • 或取小于或等于数字的对齐样本 最小向量中的值,之前的每个值 计算相关性。

这取决于您的应用程序哪个程序更合适。由于您的向量是按升序排列的,因此零填充可能不合适。

然后您需要创建一个矩阵 M,其中行对应于元素,列对应于每个(零填充或采样)向量。

您可以使用 Matlab 函数 horzcat

M=horzcat(V1,V2,...Vn)

其中 V1、V2、..Vn 是每个相同大小的列向量。

最后,您可以使用 corrcoef 获得所有向量的相关矩阵:

Cmat=corrcoef(M)

this link 上用于 corrcoef 的 Matlab 文档将帮助您了解如何以统计方式解释结果。

请注意,这种方法不会考虑向量的滞后版本之间的任何相关性。

【讨论】:

  • 也许我错了,但corrcoef 仅适用于零滞后,X 和 Y 如果移动也可能相似(即 x1~=y3、x2=~y4 等) ...它也是基于协方差的,所以幅移信号会匹配,也许这不是@gabboshow想要的
  • 确实,corrcoef 仅适用于零滞后 - OP 还需要创建其向量的滞后版本才能使用该方法。目前尚不清楚幅度偏移对 OP 是否重要。这个问题可以变成时间序列分析的教程。
【解决方案2】:

修改后的答案

现在很清楚X 向量是信号“X”的所有最小值的时间位置,Y 向量是信号“Y”的所有最小值的时间位置,等等...这里有一些更新代码。

事实上这个想法还是一样的......我们从所有信号中最小值的所有时间位置构建一个线性采样的时间向量(+来自某个时间采样精度)......然后我们构建新的信号 1.0 任何地方都期望在最小时间位置(设置为 0.0)...最后我们使用与以前相同的相关代码。

NB 速度和内存优化版本现已推出here

function [RMax] = MinimaCorrelation(c, ts)
%[
    % Some default resolution and time-location of minima positions
    if (nargin < 2), ts = 0.1; end
    if (nargin < 1), c = { [1 3 8 7 3 4 12]; [3 8 7 3]; [4 12]; [5 3 8 -3 12]; [1 3 8 7 3 4 12]; }; end

    % Number of channels
    n = length(c);

    % Build linearly sample time vector for all time locations
    minTime = min(cellfun(@min, c));
    maxTime = max(cellfun(@max, c));
    timeVector = minTime:ts:maxTime;
    timeVector(end+1) = timeVector(end) + ts; % just to really include min and max if step is not ok

    % Build new signals being '1' everywhere except at minima locations (set to '0')
    s = ones(n, length(timeVector));
    for ni = 1:n
        for mv = c{ni}
            [~, ind] = min(abs(timeVector - mv));
            s(ni, ind) = 0;
        end
    end

    % Correlation (copied 3 times to avoid biased effect on sides ==> circular shifting is ok this way)
    s = [s, s, s].';
    RMax = max(xcorr(s, 'coeff'), [], 1);

    % Put in R(i,j) format
    RMax = reshape(RMax, [n n]);
%]
end

使用默认数据,可以获得:

1.0000    0.9899    0.9866    0.9829    1.0000
0.9899    1.0000    0.9833    0.9865    0.9899
0.9866    0.9833    1.0000    0.9832    0.9866
0.9829    0.9865    0.9832    1.0000    0.9829
1.0000    0.9899    0.9866    0.9829    1.0000

小心,这是蛮力解决方案(时间和内存消耗随着信号数量和时间分辨率的增加而迅速增加)。现在这个问题更清楚了,也许有人会找到更聪明的答案。

原答案

这是使用cross-correlationxcorr 例程的最大值的方法的粗略代码(在信号处理工具箱中)

function [RMax] = xcorrmax(c)
%[
    % Default signals for test
    if (nargin < 1),
        c = cell(0,0);
        c{end+1} = [1 3 8 7 3 4 12];
        c{end+1} = [3 8 7 3];
        c{end+1} = [4 12];
        c{end+1} = [5 3 8 -3 12];
        c{end+1} = [1 3 8 7 3 4 12];
    end

    % Number of channels
    n = length(c);

    % Padding to have vectors all of the same length
    % See also `padarray` to do circular/symmetric padding (i don't have image toolbox)
    maxlength = max(cellfun(@length, c));
    c = cellfun(@(x)myquickpad(x, maxlength), c, 'UniformOutput', false);
    c = cell2mat(c.').';

    % Compute cross correlation (multichannel case) and keep max value
    % NB1: May also use xcov if signal mean is not important
    % NB2: Normalization at lag = 0
    RMax = max(xcorr(c, 'coeff'), [], 1);

    % Put in R(i,j) format
    RMax = reshape(RMax, [n n]);
%]
end
function [a] = myquickpad(a, maxlength)
%[
    if (length(a) < maxlength)
        a(maxlength) = 0;
    end
%]
end

对于以下信号:

(1) [1 3 8 7 3 4 12]
(2) [3 8 7 3]
(3) [4 12]
(4) [5 3 8 -3 12]
(5) [1 3 8 7 3 4 12]

它返回ithjth信号之间的以下相关矩阵R(i,j):

1.0000    0.6698    0.7402    0.8016    1.0000
0.6698    1.0000    0.8012    0.4853    0.6698
0.7402    0.8012    1.0000    0.6587    0.7402
0.8016    0.4853    0.6587    1.0000    0.8016
1.0000    0.6698    0.7402    0.8016    1.0000

一些备注:

  • 看起来是连贯的,例如信号 (1) 和 (5) 相同,相关性为 1.0
  • 由于使用了规范化,它认为 (1) 比 (2) 更接近 (3) ...因此应根据您的需要进行审查(参见 xcorrcoef 中的规范化,例如 @paisanco 所示)。李>
  • 如果信号幅度的变化并不重要,您可以使用 xcov 代替 xcorr
  • 同样,这是一种粗略的方法,根本没有优化速度/内存,也没有考虑到值已排序的事实,并且可能与您真正想要的不完全一致。

【讨论】:

  • 非常感谢您的详细回答。我不确定它是否适合我的情况,主要是因为我的问题并不完全清楚。请看一下已编辑的。我希望你能帮助我。
  • @gabboshow 不清楚你所说的最小值......你的意思是对于每个信号 Si 你都有 Ni 观察结果并且你将所有最小值存储在一个排序的 MSi 向量中(因此可以是不同的每个信号的长度)?
  • @CitizenInsane 是的。 MSi 向量的值是信号 Si 的最小值的“时间位置”。
  • @gabboshow 我认为我们不在队列中...我认为您是在告诉 X_signal 是单个观察值,并且在 X=[x1 x2 ... X110 给出的时间位置有多个最小值] ... 然后 Y_signal 在 Y=[y1, y2, ....Y150] 等给出的时间位置有其他多个最小值...与我的想法不同。
  • @Citizenlnsane 对不起,如果我仍然不清楚。 X_signal 是时间的一维信号函数,X 是包含最小值位置的向量。我认为您的最后评论澄清了误解。
猜你喜欢
  • 1970-01-01
  • 2016-05-29
  • 1970-01-01
  • 2023-03-12
  • 2017-08-22
  • 2021-04-30
  • 2011-05-09
  • 2011-08-27
相关资源
最近更新 更多