比较阵列之间的距离

本文关键字:距离 之间 阵列 比较 | 更新日期: 2023-09-27 17:59:17

如何比较两个数组之间的相似性?假设我有:

Base Array: [.5,0,0,0,.25,0,0,.25,0,0,0,0]
Array 1: [1,0,0,0,1,0,0,1,0,0,0,0]
Array 2: [0,0,1,0,0,0,1,0,0,1,0,0]
Array 3: [1,0,0,0,0,0,0,0,0,0,0,0]

关于上面的数组,答案应该是数组1。答案是数组1,因为数组元素在结构上与基数组的数组元素"更接近"。与数组3不同,.25更接近于1而不是0。另一个例子:

Base Array: [.75,0,0,0,0,0,0,0,.25,0,0,0]
Array 1: [1,0,0,0,1,0,0,1,0,0,0,0]
Array 2: [0,0,1,0,0,0,1,0,0,1,0,0]
Array 3: [1,0,0,0,0,0,0,0,0,0,0,0]

在这种情况下,数组3应该是答案。

然而,使用我目前的算法(我稍后会给出),答案变成了数组3。以下是我正在使用的:

for (int i = 0; i < basearray.Length; i++)
{
  temp = (basearray[i] - arrayX[i]);
  dist += temp * temp;
}

所以,我觉得我的算法有问题吗?或者,我需要使用一种"不同"的算法,而不是距离(因为本质上,.25比1更接近0,但我想要的是其他的)。

谢谢!

更新:

我找到了答案!感谢所有人的帮助。这是:

float[] pbaseArrX = new float[3];
float[] pcompArrX = new float[3];
float dist1 = 0, dist2 = 0;
for (int i = 0; i < baseArrX.Count; i++)
{
  pbaseArrX[i] = baseArrX[i] / (baseArrX[0] + baseArrX[1] + baseArrX[2]);
}
//Do the following for both compArr1 and compArr2;
for (int i = 0; i < compArrX.Count; i++)
{
  pcompArrX[i] = pcompArrX[i] / (pcompArrX[0] + pcompArrX[1] + pcompArr[2]);
}
//Get distance for both
for (int i = 0; i < pcompArrX.Count; i++)
{
  distX = distX + ((pcompArrX[i] - pbaseArrX[i])^2);
}
//Then just use conditional to determine which is 'closer'

比较阵列之间的距离

似乎您想将阵列作为射线(仅方向)进行比较,但您将它们作为矢量(方向和大小)进行比较。我建议将数组与余弦相似性进行比较,余弦相似性只是向量之间角度的余弦,因此只比较它们的方向。对于所提供的数组,基本数组和数组1之间的余弦相似性为0.94,而数组2的余弦相似度为0.82,符合您的期望。

数组3是正确答案。你使用的算法会给你正确的结果。

基本上,对我来说,阵列3比阵列1更类似于基本阵列。你要找的图案是什么?你说Array1应该是结果。。。为什么?

距离只是一种通过任意数学假设来比较两个数组的方法,它背后没有真正的"逻辑",而是我们赋予它的

如果您希望结果为Array1,则:

  • 定义为什么排列1应是逻辑术语的结果
  • 将"为什么排列1"转化为数学公式
  • 执行该公式

这里的问题是您对"相似性"的概念没有明确定义。根据数据的使用情况,有无数种方法可以定义相似性。抛开你的数组不谈,有一个简单的例子:

  • 眼镜和双目眼镜是相似的,因为你用它们来观察事物
  • 眼镜和自行车是相似的,因为它们都是由两个互相连接的圆圈组成的
  • Glasses和Grass是相似的,因为它们都以"G"开头,以"S"结尾

正如你所看到的,除非你准确地定义了你需要什么,否则任何东西都可能与任何东西相似。人类善于在正确的任务中使用正确的相似性,但除非你明确告诉计算机你想要什么,否则计算机无法做到这一点。

抛开这一点不谈,有一种常见的相似性情况,它经常用于数据挖掘中的序列数据。这被称为余弦距离,它与你所使用的没有太大区别。它被称为余弦距离。以下是算法:

for (int i = 0; i < basearray.Length; i++)
{
  temp += (basearray[i] * arrayX[i]);
  f_base += (basearray[i] * basearray[i]);
  f_array += (array[i] * array[i]);
}
dist = 1 - (temp / sqrt( f_base * f_array ));

这基本上只是计算两个阵列之间的"角度",这两个阵列被描绘为n维空间中的点。在大多数情况下都能很好地工作,并且可以很容易地用于其他需求(当需要其他类型的相似性时)。

数学上,每个数组都是一个点,距离度量称为范数。你使用的是欧几里得范数的一个版本,它是我们在三维空间距离的标准度量。它只是错过了平方根,因为你感兴趣的是哪一个距离最近,而不是测量实际距离,所以它仍然适用于你。

在你的例子中,第三个数组在欧几里得距离上肯定是最接近的,因为你的基数组比第一个数组更接近零数组。它们可能有"相似的结构",但你看错了。您的距离测量对数值距离感兴趣,0(在数组3中)比1(在数组1中)更接近0.25。

如果你在看"结构",这意味着你认为0比任何其他数字都重要得多。即,您希望奖励在同一位置具有非零的匹配数组,而不是在数字上接近0。

我不确定你想要什么样的规范,老实说,这给我的印象是,我们错过了你在一天结束时需要实现的目标——对我们目前所知的情况提出建议有点困难。