我正试图找到一种方法来在两个不同点的数组中找到相似之处。我在具有类似模式的点周围绘制了圆圈,我想在100个点的间隔中进行某种自动比较,并告诉该间隔的相似系数。正如你所看到的那样,它可能也没有完全对齐,所以点对点比较也不是一个好的解决方案(我想)。略微错位的图案也可能意味着它们匹配模式(但显然具有较小的系数)
相似性可能意味着什么(1个系数是完美匹配,0或更小 - 根本不匹配):
系数只是我对比较函数的最终计算结果如何与给定数据看起来的想法。
我在SO上阅读了很多帖子,但似乎没有解决我的问题。我非常感谢你的帮助。谢谢
P.S。完美的答案是为函数提供伪代码,它可以接受两个数据数组作为参数(数据间隔)和返回相似系数。
答案 0 :(得分:0)
我认为HighPerformanceMarks的建议是完成这项工作的标准方式。
计算轻量级的替代措施可能是点积。
点积不会是负数。如果两个向量在它们的向量空间中是垂直的,则点积将为0(事实上,“垂直”通常是在更高维度中定义的),并且它将达到相同向量的最大值。
如果你接受垂直度的几何概念作为(dis)相似性度量,那么就去吧。
警告: 这是为计算效率选择的临时启发式算法。我不能告诉你关于过程和分离属性的数学/统计特性 - 如果你需要严格的分析,不管怎么说,你可能会更好地使用相关理论,也许应该把你的问题转发给math.stackexchange.com。
答案 1 :(得分:0)
我也认为高性能标志基本上给了你答案(互相关)。在我看来,大多数其他答案只给你一半你需要的东西(即点积加上一些阈值)。但是,这不会将信号视为与其自身的移位版本类似。你需要计算这个点积N + M - 1次,其中N,M是数组的大小。对于每次迭代,计算数组1和数组2的移位版本之间的点积。移位数组2的数量每次迭代增加一个。您可以将数组2视为通过数组1的窗口。您将要启动循环,其中数组2的最后一个元素仅与数组1中的第一个元素重叠。
此循环将为不同的班次生成数字,您对该号码的处理取决于您。也许你将它(或它的绝对值)与你定义的阈值进行比较,以便将两个信号视为“相似”。
最后,在许多情况下,信号被认为类似于自身的缩放(在幅度感,而不是时间缩放)版本,因此在计算互相关之前必须有归一化步骤。这通常通过缩放数组的元素来完成,使得点积与其自身等于1.请注意确保这对于您的应用程序在数字上有意义,即整数不能很好地扩展到0到1之间的值: - )
答案 2 :(得分:-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将返回(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
这有用吗?
答案 3 :(得分:-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为true,则对最终(差异化)数组进行排序。
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运行傅里叶变换,然后对返回的光谱采用距离度量。