4

我试图找到一种在两个不同点数组中找到相似之处的方法。我在具有相似模式的点周围画了圆圈,我想以假设 100 点的间隔进行某种自动比较,并告诉该间隔的相似系数是多少。如您所见,它可能也没有完全对齐,因此点对点比较也不是一个好的解决方案(我想)。稍微未对齐的模式也可能意味着它们与模式匹配(但显然系数较小)

相似性可能意味着什么(1 个系数是完美匹配,0 或更少 - 根本不匹配):

  1. 点 640 到 660 - 非常相似(系数约为 0.8)
  2. 点 670 到 690 - 非常相似(系数为 ~0.5-~0.6)
  3. 点 720 到 780 - 假设非常相似(系数为 ~0.5-~0.6)
  4. 点 790 到 810 - 完全相似(系数为 1)

系数只是我对比较函数的最终计算结果与给定数据的看法。

我阅读了很多关于 SO 的帖子,但似乎并没有解决我的问题。非常感谢您的帮助。谢谢

PS Perfect answer将是为函数提供伪代码的答案,该函数可以接受两个数据数组作为参数(数据间隔)并返回相似系数。

比较点

点击这里查看图片的原始尺寸

4

4 回答 4

0

我也认为High Performance Mark基本上已经给了你答案(互相关)。在我看来,大多数其他答案只给你你需要的一半(即,点积加上与某个阈值进行比较)。但是,这不会认为信号类似于其自身的移位版本。您需要计算这个点积 N + M - 1 次,其中 N, M 是数组的大小。对于每次迭代,计算数组 1 和数组 2 的移位版本之间的点积。移位数组 2 的量每次迭代都会增加一。您可以将数组 2 视为您正在传递数组 1 的窗口。您将希望以数组 2 的最后一个元素仅与数组 1 中的第一个元素重叠来开始循环。

这个循环将为不同的班次生成数字,你如何处理这个数字取决于你。也许您将它(或它的绝对值)与您定义的阈值进行比较,以考虑两个信号“相似”。

最后,在许多情况下,信号被认为类似于其自身的缩放(在幅度意义上,而不是时间缩放)版本,因此在计算互相关之前必须有一个归一化步骤。这通常是通过缩放数组的元素来完成的,使点积与自身等于 1。请注意确保这在数字上对您的应用程序有意义,即整数不能很好地缩放到 0 和 1 之间的值: -)

于 2013-08-07T19:38:24.617 回答
0

我认为 HighPerformanceMarks 的建议是完成这项工作的标准方式。

计算上轻量级的替代度量可能是点积。

  • 将两个数组拆分为相同的预定义索引间隔。
  • 将每个区间中的数组元素视为高维空间中的向量坐标。
  • 计算两个向量的点积。

点积不会是负数。如果两个向量在它们的向量空间中是垂直的,则点积将为 0(实际上这就是在更高维度上通常定义“垂直”的方式),并且对于相同的向量它将达到最大值。

如果您接受垂直度的几何概念作为(不)相似性度量,那么就可以了。

警告:这是为计算效率而选择的临时启发式方法。我无法告诉您有关过程和分离属性的数学/统计属性 - 但是,如果您需要严格的分析,无论如何您可能会在相关理论方面做得更好,并且可能应该将您的问题转发给math.stackexchange.com

于 2013-08-07T10:04:06.380 回答
-1

您可以为长度为 N 的两个向量 A 和 B 定义距离度量,其中包含区间 [-1, 1] 中的数字,例如

 sum = 0
 for i in 0 to 99:
   d = (A[i] - B[i])^2  // this is in range 0 .. 4
 sum = (sum / 4) / N // now in range 0 .. 1

现在,对于完全相反的向量(一个全为 1,另一个全为 -1)返回距离 1,对于相同的向量返回 0。

您可以通过以下方式将其转换为您的系数

 coeff = 1 - sum

然而,这是一种粗略的方法,因为它没有考虑到您要比较的信号之间可能存在水平失真或偏移的事实,所以让我们看看一些应对方法。

您可以对两个数组进行排序(例如按升序),然后计算距离/系数。这比原始度量返回更多相似性,并且与信号的排列/移位无关。

您还可以计算差异并计算距离/系数,然后您也可以进行排序。使用微分的好处是它消除了垂直偏移。排序差异消除了水平偏移,但仍然比排序的原始数据点更好地识别不同的形状。

然后,您可以例如平均不同的系数。这里有更完整的代码。下面的例程计算给定大小的数组 A 和 B 的系数,并首先(递归地)取 d 个微分。如果 sorted 为真,则对最终(微分)数组进行排序。

procedure calc(A, B, size, d, sorted):
  if (d > 0):
     A' = new array[size - 1]
     B' = new array[size - 1]
     for i in 0 to size - 2:
        A'[i] = (A[i + 1] - A[i]) / 2   // keep in range -1..1 by dividing by 2
        B'[i] = (B[i + 1] - B[i]) / 2
     return calc(A', B', size - 1, d - 1, sorted)
  else:
     if (sorted):
       A = sort(A)
       B = sort(B)
     sum = 0
     for i in 0 to size - 1:
       sum = sum + (A[i] - B[i]) * (A[i] - B[i])
     sum = (sum / 4) / size
     return 1 - sum // return the coefficient

procedure similarity(A, B, size):
  sum a = 0
  a = a + calc(A, B, size, 0, false)
  a = a + calc(A, B, size, 0, true)
  a = a + calc(A, B, size, 1, false)
  a = a + calc(A, B, size, 1, true)
  return a / 4 // take average

对于完全不同的东西,您还可以使用 FFT 运行傅里叶变换,然后对返回的光谱进行距离度量。

于 2013-08-07T10:00:47.290 回答
-1

我的尝试:

Total_sum=0
1. For each index i in the range (m,n)
2.     sum=0
3.     k=Array1[i]*Array2[i]; t1=magnitude(Array1[i]); t2=magnitude(Array2[i]);
4.     k=k/(t1*t2)
5.     sum=sum+k
6. Total_sum=Total_sum+sum
Coefficient=Total_sum/(m-n)

如果所有值都相等,则 sum 在每种情况下都将返回 1,而 total_sum 将返回 (mn)*(1)。因此,当它除以 (mn) 时,我们得到的值为 1。如果图形完全相反,我们得到 -1,而对于其他变化,则返回 -1 和 1 之间的值。
当 y 范围或 x 范围很大时,这不是那么有效。但是,我只是想给你一个想法。


另一种选择是执行广泛的 xnor。

1. For each index i in the range (m,n)
2.     sum=1
3.     k=Array1[i] xnor Array2[i]; 
4.     k=k/((pow(2,number_of_bits))-1) //This will scale k down to a value between 0 and 1
5.     sum=(sum+k)/2

Coefficient=sum

这有帮助吗?

于 2013-08-07T09:32:57.500 回答