假设有两组(无序,无重复元素):
A = set(["z", "x", "c"])
B = set(["x", "z", "d", "e"])
这些集合有两个共同的元素:“z”和“x”,以及一些特定于集合的元素:c,d,e。
如何为每组提供分数,就像字符串距离一样,而
正如您在示例中所看到的,每组的大小可能不同。
此算法的非关键要求是:
目前我一直在计算一个设定距离得分:
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
我如何规范化这个值并反对什么?
答案 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)
假设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