【问题标题】:pairwise similarity comparison matlab两两相似度比较matlab
【发布时间】:2014-07-18 11:50:40
【问题描述】:

我有一个矩阵 A,其中包含事件及其发生的相关概率。 例如

A= [1, 0.6; 5, 0.3; 4, 0.1]

事件 1 发生的概率为 60%,事件 5 发生的概率为 30%,事件 4 发生的概率为 1%。

然后我有一系列相似的矩阵(事件-概率)

B = [1,0.5; 3,0.4; 2,0.1]
C = [2,0.9; 4,0.1; 3,0]
D = [1,0.6; 5,0.3; 4,0.1]

我想找到一个向量来显示 A 与其他每个矩阵的相似性。

SIM = [?,?,1]

前 2 个元素包含 A 和 B 以及 A 和 C 之间的相似性。 第 3 个元素表示 A 和 D 之间的相似性(1 因为它们相同)。

您对如何实现该函数以在矩阵之间进行成对比较有什么建议吗?

非常感谢!!!

请同时考虑 A 为 A = [3,1;5,0;2,0](等于拥有A=[3,1;2,0;1,0] 等...)

【问题讨论】:

  • 您将使用什么相似度指标? RSME?绝对差?
  • 我编辑了我的问题以给出一个更通用的例子......
  • 那么问题是您需要对每组行进行排序以便相应的事件排成一行吗?如果我们可以假设所有条件都出现在所有分布中,我们根本不需要第一列 - 只需保留 [Avals, Aix] = sort(A(:,1)); Aprobs = A(Aix,2) 之类的内容,然后将 Aprobs、Bprobs 等与 pdist([Aprobs';Bprobs';Cprobs';Dprobs]) 之类的内容进行比较
  • 只是语法修正:也许你想要像B = [1,0.5; 3,0.4; 2,0.1] 这样的矩阵(否则你会得到cat 错误)
  • 我所说的条件就是你所说的事件。因此,每个矩阵将具有相同的行数,在第一列中具有相同的值集。否则,您可以使用 Acanonical(A(:,1)) = A(:,2) 之类的方法对它们进行规范化

标签: matlab probability similarity


【解决方案1】:

AB之间的相似度计算函数

function SIM = SIMcalc(A,B)

%// Get joint unique events for A and B
unq_events = unique([A(:,1);B(:,1)]).'; %//'

%// Presence of events across joint unique events
event_tagA = bsxfun(@eq,A(:,1),unq_events);
event_tagB = bsxfun(@eq,B(:,1),unq_events);

%// Probabilities corresponding to each joint event
tagged_probA = sum(bsxfun(@times,A(:,2),event_tagA));
tagged_probB = sum(bsxfun(@times,B(:,2),event_tagB));

%// Set not-shared events as NaN
tagged_probA(~any(event_tagA))=nan;
tagged_probB(~any(event_tagB))=nan;

%// Get the similarity factors for each shared event. This is based on the
%// assumption that probabilities far apart must have a low shared
%// similarity factor. This factor would be later on used to scale the
%// individual probabilties for A and B.
sim_factor = 1-abs(tagged_probA-tagged_probB);
tagged_probA_sim_scaled = tagged_probA.*sim_factor;
tagged_probB_sim_scaled = tagged_probB.*sim_factor;

%// Get a concatenated matrix of scaled probabilities
tagged_probAB_sim_scaled = [tagged_probA_sim_scaled;tagged_probB_sim_scaled];

%// Get a hybrid array of probabilities based on the mean of probabilities
%// across A and B. Notice that for cases with identical probabilities, the
%// hybrid values would stay the same.
hybrid_probAB = mean(tagged_probAB_sim_scaled);

%// Get the sum of hybrid values. Notice that the sum would result in a
%// value of 1 when we have identical probabilities for identical events
SIM = nansum(hybrid_probAB);

return;

用于测试相似度计算的样本输入

%// Case 1 - First exammple from the question with D replacing B.
%// The SIM value must be 1 as mentioned in the question
disp('------------- Case 1 -----------------')
A= [1, 0.6; 5, 0.3; 4, 0.1]
B = [1,0.6; 5,0.3; 4,0.1]
SIM = SIMcalc(A,B)

%// Case 2 - Slight change to the first example with event 5 being
%// replaced by event 2 in B
%// The SIM value must be lesser than 1 as mentioned in the question
disp('------------- Case 2 -----------------')
A= [1, 0.6; 5, 0.3; 4, 0.1]
B = [1,0.6; 2,0.3; 4,0.1]
SIM = SIMcalc(A,B)

%// Case 3 - As presented in the comments by OP, that the SIM value must be 0
disp('------------- Case 3 -----------------')
A =[3,1;2,0;1,0]
B =[2,1;1,0;4,0]
SIM = SIMcalc(A,B)

%// Case 4 - As asked by me and replied by OP that SIM must be 1
disp('------------- Case 4 -----------------')
A =[3,1;2,0;1,0]
B =[3,1;2,0;1,0]
SIM = SIMcalc(A,B)

%// Case 5 - Random case added on my own.
%// As can be seen event 3 is common between A and B. Apart from event3,
%// only event 2 is common, but the probabilities arew far apart, so the
%// net SIM value must be slightly more than the identical probability of
%// event 3, i.e. slightly more than 0.55
 disp('------------- Case 5 -----------------')
A =[3,0.55;2,0.95;1,0]
B =[3,0.55;2,0.05;4,0.4]
SIM = SIMcalc(A,B)

结果

------------- Case 1 -----------------
A =
    1.0000    0.6000
    5.0000    0.3000
    4.0000    0.1000
B =
    1.0000    0.6000
    5.0000    0.3000
    4.0000    0.1000
SIM =
     1
------------- Case 2 -----------------
A =
    1.0000    0.6000
    5.0000    0.3000
    4.0000    0.1000
B =
    1.0000    0.6000
    2.0000    0.3000
    4.0000    0.1000
SIM =
    0.7000
------------- Case 3 -----------------
A =
     3     1
     2     0
     1     0
B =
     2     1
     1     0
     4     0
SIM =
     0
------------- Case 4 -----------------
A =
     3     1
     2     0
     1     0
B =
     3     1
     2     0
     1     0
SIM =
     1
------------- Case 5 -----------------
A =
    3.0000    0.5500
    2.0000    0.9500
    1.0000         0
B =
    3.0000    0.5500
    2.0000    0.0500
    4.0000    0.4000
SIM =
    0.6000

说明

让我们以case 5 来详细解释决定衡量AB 之间相似性的最终标量值的基本原理。建议运行此案例的代码并观察变量的值。

输入

A =
    3.0000    0.5500
    2.0000    0.9500
    1.0000         0
B =
    3.0000    0.5500
    2.0000    0.0500
    4.0000    0.4000

第 1 步

AB的事件对应的概率标记为NaNs。因此,我们将拥有tagged_probAtagged_probB,它们的值如下所示 -

Event 1  Event 2  Event 3  Event 4
   0      0.95     0.55     NaN
  NaN     0.05     0.55     0.4

第 2 步

计算概率之间的差,然后从1 中减去结果。因此,更接近1 的数字表示相似度。例如,在这个event 3 的示例中,我们将得到1 的结果。这构成了找到AB 之间相似性标准的基础,因为我们得到1 的相同概率和较小的值,因为概率在[0 1] 的范围内相距甚远。这存储到sim_factor -

sim_factor =
       NaN    0.1000    1.0000       NaN

第 3 步

使用sim_factor 缩放AB 的标记概率。因此,我们根据AB 之间的相似性对标记概率进行了缩放。这些是——

tagged_probA_sim_scaled =
       NaN    0.0950    0.5500       NaN
tagged_probB_sim_scaled =
       NaN    0.0050    0.5500       NaN

第 4 步

由于最终值应该只是一个标量值,我们可以得到标记和缩放概率的平均值。结果值将具有与相同概率情况下的单个概率相同的值,如本例中的event 3。对于不相同的情况,它会根据AB 概率之间的差异来缩小概率。这是hybrid_probAB,如下图-

hybrid_probAB =
       NaN    0.0500    0.5500       NaN

第 5 步

对来自hybrid_probAB 的非NaN 元素求和,得到最终的标量相似度值,对于这种特定情况,它小于1。对于具有相同概率的情况,它会给我们一个完美的1

结束语

查看SIM 值,它们确实遵循预期趋势。因此,希望它适用于您的其他情况。要计算A 和其他数组之间的相似度值,请将它们作为输入运行函数。

【讨论】:

  • 嗨,谢谢,但这并不完全正确...确实您不考虑事件...如果您将 D 更改为 D =[1,0.6; 2,0.3; 4,0.1] A和D的相似度仍然是1,但是事件5和2完全不同。我同意@fyts 的直觉,我们应该首先创建包含所有事件的“完整向量”..
  • @gabboshow 但是在你问题的最后一句话中,你说 - 'A = [3,1;5,0;2,0] (that would be equal to have A=[3,1;2,0;1,0]',所以我认为这些事件只是为了同名。
  • 事件 3 有 100% 的概率发生
  • 请考虑 A =[3,1;2,0;1,0] 和 B =[2,1;1,0;4,0] 的情况。在这种情况下,A和B之间的相似度应该是0
  • @gabboshow 添加了说明部分以方便您使用。希望这可以帮助你。根据您在问题和 cmets 中提出的要求,这完全是家常便饭。如果发现与任何外部资源有任何相似之处,请将其视为巧合。我正在考虑在我未来的答案中使用这个免责声明:)
【解决方案2】:

好的,所以你选择一个接受两个矩阵并输出一个标量的函数,这样你就可以使用bsxfun

similarity = @(x,y)(mean(mean(x./y)));
M = cat(3,B,C,D); %//Combine into a single 3D matrix
squeeze(sum(mean(bsxfun(similarity, A, M),2)))

请注意,我使用的相似度函数可能不是最适合您的数据的函数,因为如果第二个矩阵中包含 0 并且它不是对称的,它会返回 Inf。重点是说明它必须取一个二维矩阵并输出一个标量。

【讨论】:

  • 我试图运行你的代码,确实我得到了错误使用 bsxfun 无效的输出尺寸......我不确定我明白了......你能解释一下如何使用欧几里德距离
【解决方案3】:

您是否考虑过形成 5 个事件的完整概率直方图?比方说:

Ah=[0.6 0 0 0.1 0.3];
Bh=[0.5 0.1 0.4 0 0];
Ch=[0 0.9 0 0.1 0];
Dh=[0.6 0 0 0.1 0.3];

然后您可以将它们作为向量进行比较,将它们连接成一个矩阵并使用 pdist:

m=[Ah; Bh; Ch; Dh];
sim=squareform(pdist(m,'cityblock'));

【讨论】:

  • 嗨,为什么 sim 是 4x4 矩阵?它代表什么?
  • 它是一个成对距离矩阵,对于 m 的每一对可能的行。每个元素 sim(ii,jj) 表示 m 的 ii 和 jj 行之间的距离之间的距离。请注意,它的对角元素为零(一行与自身的距离)。
猜你喜欢
  • 1970-01-01
  • 2011-09-30
  • 2019-09-18
  • 2019-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-07
  • 1970-01-01
相关资源
最近更新 更多