如何计算集合之间的成对相似性(杰卡德距离)

how to calculate pairwise similarity (Jaccard Distance) between sets

我有一个巨大的 json 文件(至少有数千个密钥),例如:

{"A": ["5-65", "5-66", "5-67", "6-12", "6-59"],
 "B": ["5-65", "5-66", "5-67", "6-12", "6-59","7-13"],
 "C": ["4-43","5-65", "5-66", "5-67", "6-59","7-12","7-13"]
}

每个列表都没有重复值。

我想计算这个 JSON 文件的两两相似度。 例如,结果应如下所示:{"A-B": similarity1, "A-C": similarity2, "B-C": similarity3} 杰卡德距离可用作相似度。

不确定你是如何定义相似度的,我们假设这是共同元素的数量。

您可以结合使用 set 方法 itertools.combinations:

d = {"A": ["5-65", "5-66", "5-67", "6-12", "6-59"],
     "B": ["5-65", "5-66", "5-67", "6-12", "6-59","7-13"],
     "C": ["4-43","5-65", "5-66", "5-67", "6-59","7-12","7-13"]
     }

## or to load fron json file
# import json
# with open('file.json') as f:
#    d = json.load(f)

from itertools import combinations

out = {(a,b): len(set(d[a]).intersection(d[b])) for a,b in combinations(d, 2)}

输出:

{('A', 'B'): 5, ('A', 'C'): 4, ('B', 'C'): 5}

为了效率,最好只计算一次集合:

d2 = {k: set(v) for k,v in d.items()}
out = {(a,b): len(d2[a]&d2[b]) for a,b in combinations(d, 2)}

杰卡德相似度

这将定义为交集的大小除以并集的大小(参见 Jaccard index):

d2 = {k: set(v) for k,v in d.items()}
{(a,b): len(d2[a]&d2[b])/len(d2[a]|d2[b]) for a,b in combinations(d, 2)}

输出:

{('A', 'B'): 0.8333333333333334, ('A', 'C'): 0.5, ('B', 'C'): 0.625}