算法比较相似的数字列表?

时间:2012-01-12 20:10:29

标签: python algorithm

很抱歉,如果这是一个总的noob问题,但我想尝试在列表中找到类似的值。实际上更具体地说,我想知道是否有一种方法可以对这些项目进行评分。

我知道在python中我可以只取一个列表并执行'=='来查看它是否相同,但如果它们不是完全相同的话,而是有一些相似的值(或不相同)。

以下是一个例子:

#Batch one 
[1, 10, 20]
[5, 15, 10]
[70, 19, 15]
[50, 40, 20]


#Batch two 
[46, 19, 8]
[6, 14, 8]
[2, 11, 44]

假设我想根据它们彼此之间的相似程度对两个批次进行评分/排名。我想我可以添加所有数字,然后将它们与总值进行比较,但我认为这不起作用,因为[5,6,1000] [600,200,211]看起来很相似。在这个例子中,[5,15,10]和[6,14,8]应该得到最高分。

我想要划分每个值并查看百分比差异,但如果列表变大且包含许多变量(我最终可能有数千个列表,每个变量超过800个),这似乎真的很贵,我怀疑可能更好方法

有什么建议吗?

5 个答案:

答案 0 :(得分:3)

如何使用Euclidean distance

在列表理解中:

def distance(lista, listb):
    return sum( (b - a) ** 2 for a,b in zip(lista, listb) ) ** .5

或写得更多:

def distance(lista, listb):
    runsum = 0.0
    for a, b in zip(lista, listb):
        # square the distance of each
        #  then add them back into the sum
        runsum += (b - a) ** 2  

    # square root it
    return runsum **.5

答案 1 :(得分:2)

a = [1, 10, 20]
b = [5, 15, 10]
c = [70, 19, 15]
d = [50, 40, 20]

def sim(seqA, seqB):
    return sum([abs(a - b) for (a, b) in zip(seqA, seqB)])


print sim(a, a) # => 0
print sim(a, b) # => 19
print sim(a, c) # => 83
print sim(a, d) # => 79

数字越小意味着越相似。 0表示相同。

答案 2 :(得分:1)

如果我理解你的话,你基本上想看看你有多么紧张?

那么,如果您将数据视为3D中的点集,那么您是否试图找到每个集群的点差?

(换句话说,你想比较内部两个批次的相似之处?)

在这种情况下,请考虑以下内容(使用numpy加快速度):

import numpy as np

def spread(group):
    return group.var(axis=0).sum()

group1 = np.array([[1, 10, 20],
                   [5, 15, 10],
                   [70, 19, 15],
                   [50, 40, 20]], dtype=np.float)
group2 = np.array([[46, 19, 8],
                   [6, 14, 8],
                   [2, 11, 44]], dtype=np.float)

print spread(group1), spread(group2)

因此,在这种情况下,group2是内部最多的

相反,如果您有兴趣找到两个群组与每个其他的“接近”,那么您可以比较他们的中心之间的距离

legs = group1.mean(axis=0) - group2.mean(axis=0)
distance = np.sqrt(np.sum(legs**2))

或者你想找到每组中最接近的两个“点”? (在这种情况下,你使用距离矩阵(或更有效的算法获得更多点......)。

答案 3 :(得分:1)

显而易见的解决方案已经存在。基本上它们对应于计算每组的| x-mean(x)| ^ p(如果p = 2,这相当于计算方差)。

既然你提到了[1,2,3]和[101,103,105]的百分比,你更喜欢哪一个作为最终答案?如果答案是'第一',那就别担心。如果是第二个,则必须将方差标准化为均值。

解是:(SquareMean - Mean ^ 2)/ Mean ^ 2,其中SquareMean =(a ^ 2 + b ^ 2 + c ^ 2)/ 3,Mean =(a + b + c)/ 3。

答案 4 :(得分:0)

我不知道如何但我正在考虑尝试使用标准差,因为类似的值(理论上)会有类似的偏差?

在这种情况下[5,15,10]的标准偏差为5 [6,14,18]获得6.1101