计算两个无序集之间的“距离”

时间:2012-07-03 17:59:52

标签: python collections set distance set-theory

假设有两组(无序,无重复元素):

A = set(["z", "x", "c"])
B = set(["x", "z", "d", "e"])

这些集合有两个共同的元素:“z”和“x”,以及一些特定于集合的元素:c,d,e。

如何为每组提供分数,就像字符串距离一样,而

  • 无视元素的排序和
  • 强加无重复 每个孤立集的约束

正如您在示例中所看到的,每组的大小可能不同。

此算法的非关键要求是:

  • 插入>如果可能的话,删除(缺少元素的集合意味着比具有太多的元素更高的成本),或者只是INS = DEL
  • 交换:0(免费,因为订购对距离没有影响)

目前我一直在计算一个设定距离得分:

score_A = len(common(a,b)) / len(a)    # common(...) calculates intersection
score_B = len(common(a,b)) / len(b)

quadratic_score = sqrt(score_A * score_B)

您如何建议解决此问题或改进我的解决方案?

是否有任何算法可以指定成本?


现在我要为集修改定义一个简单的代数:

def calculate_distance( a, b, insertion_cost=1, deletion_cost=1 ):
    """
    Virtually, a programmer-friendly set-minus.

    @return     the distance from A to B, mind that this is not
                a commutative operation.
    """
    score = 0
    for e in a:
        if e not in b: # implies deletion from A
            score += deletion_cost

    for e in b:
        if e not in a: # implies insertion into A
            score += insertion_cost

    return score

我如何规范化这个值并反对什么?

3 个答案:

答案 0 :(得分:3)

集合交叉点的大小与较大集合的大小有何关系?所以:

float(len(A.intersection(B)))/max(len(A),len(B))

它会给你一个在0.0到1.0范围内缩放的数字,这通常是可取的。 1.0表示完全相等,0.0表示没有共同点。

答案 1 :(得分:3)

对于这个问题,这个答案当然是过时的,但希望未来的访问者能够接受。

使用Jaccard distance,两组之间对称差异的基数(集合大小)除以其并集的基数。换句话说,联合减去交集全部除以联合。

这假设元素可以以离散的方式进行比较,即它们是否相等。一个理想的属性是Jaccard距离是metric

答案 2 :(得分:2)

this one

类似的问题

假设OP要求某个东西作为“距离”,我认为根据the general requirements of a distance function

,当两个集合相同时,最好使其 0

对称三角不等式

也很好

对称是直观的,三角不等式表示d(A,C)≤d(A,B)+ d(B,C)

我建议像:

C = A.intersection(B)
Distance = sqrt(len(A-C)*2 + len(B-C)*2)

但是我不知道如何证明三角形不等式


要标准化OP的更新功能结果,只需执行score = score / (len(a) + len(b))

a未与b相交时为1,而a == b时为0