【问题标题】:Compare two arrays of points [closed]比较两个点数组[关闭]
【发布时间】:2013-08-08 14:27:42
【问题描述】:

我正在尝试找到一种方法来在两个不同点的数组中找到相似之处。我在具有相似模式的点周围画了圆圈,我想以假设 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 的帖子,但似乎并没有解决我的问题。非常感谢您的帮助。谢谢

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

Click here to see original size of image

【问题讨论】:

  • 您能否澄清一下-您的point 是什么类型的数据?它代表什么? (您提供的图形太小,看不到)
  • 我认为您正在寻找一些相关或互相关的度量。对我来说太复杂了,无法尝试解释或提供伪代码 ab initio。建议您查看主题(也许在维基百科上)并返回一个尖锐的问题。
  • @Eugene 点只是一个整数:arrayA = [0,1,2,0] 和 arrayB = [0,1,2,0] 将是完美的匹配。但是 arrayA = [0,1,2,0] 和 arrayB = [0,0,1,2] 将是一个非常相似的匹配,但需要对齐。并且 arrayA = [0,1,2,0] 和 arrayB = [0,2,3,0] 也意味着非常相似或非常相似的匹配,因为模式相似。
  • 这个问题似乎是题外话,因为它是关于找到一个很好的数据相似性度量。它更适合math.stackexchange.org 或stats.stackexchange.org
  • @Chowlett 我相信如果你在Mathematics 上很活跃,你不会认为它适合那里。我不太确定Cross Validated。这个问题没有表现出对问题的最低理解,这是它不适合这里的主要原因。

标签: algorithm math pseudocode


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

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

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

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

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

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

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

    【讨论】:

    • 我想互相关是我一直在寻找的术语,尽管我不能接受 HighPerformanceMarks 的答案,因为它只是一个评论。也谢谢你,我会试试你的方法
    【解决方案3】:

    我的尝试:

    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 将返回 (m-n)*(1)。因此,当它除以 (m-n) 时,我们得到的值为 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
    

    这有用吗?

    【讨论】:

    • 请注意,如果您有一个很大的向量v,比较v || 0 和0 || v 会得到一个糟糕的结果,尽管它们非常相似。必须使用一些对齐方式。
    • 嗯..是的。这里可能需要一个更优雅的解决方案。
    【解决方案4】:

    您可以为长度为 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 运行傅里叶变换,然后对返回的光谱进行距离度量。

    【讨论】:

    • 是的。我只是想给出一些想法...如果您采用系列 0000000011111111 和 0101010101010101,它们的差值将是 0000000010000000 和 1X1X1X1X1X1X1X1X X 表示 -1,即使在排序后,差值数组也会不同。 “相似性”过程可以具有可以根据需要调整的权重
    猜你喜欢
    • 2017-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-03
    • 2010-11-09
    • 1970-01-01
    • 2010-09-18
    相关资源
    最近更新 更多