如何计算2个以上个体的Jaccard相似度,1000个个体场景如何循环实现?
多个体Jaccard相似度批量计算方法
实现思路
你现有的两两Jaccard相似度计算函数可以直接复用,针对多个体场景,核心是生成所有不重复的两两配对进行循环计算,避免重复计算相同的两组(比如计算过A1&A2后无需再计算A2&A1),最终可以输出配对相似度列表或者对称的相似度矩阵两种形式的结果。
具体代码实现
基础版本:输出配对相似度列表
适合只需要查看两两配对结果的场景:
from itertools import combinations # 原有的计算函数无需修改 def jaccard_similarity(A1, A2): s1 = set(A1) s2 = set(A2) return len(s1.intersection(s2)) / len(s1.union(s2)) # 第一步:把所有个体的特征统一存到列表里,1000个个体直接往这个列表添加即可 all_samples = [ ['dog', 'cat', 'cat', 'rat'], # A1 ['dog', 'cat', 'mouse'], # A2 ['cat', 'rat', 'fish'], # A3 ['mouse', 'fish', 'bird'] # A4 ] # 给个体命名,方便后续对应结果 sample_names = [f"A{i+1}" for i in range(len(all_samples))] # 第二步:循环计算所有不重复两两配对的相似度 similarity_list = [] for (idx1, name1), (idx2, name2) in combinations(enumerate(sample_names), 2): sim = jaccard_similarity(all_samples[idx1], all_samples[idx2]) # 保留4位小数,可按需调整精度 similarity_list.append((name1, name2, round(sim, 4))) # 打印结果 for item in similarity_list: print(f"{item[0]} 和 {item[1]} 的Jaccard相似度:{item[2]}")
进阶版本:输出相似度矩阵
适合后续需要做聚类、相关性分析等场景:
import numpy as np from itertools import combinations def jaccard_similarity(A1, A2): s1 = set(A1) s2 = set(A2) return len(s1.intersection(s2)) / len(s1.union(s2)) all_samples = [ ['dog', 'cat', 'cat', 'rat'], ['dog', 'cat', 'mouse'], ['cat', 'rat', 'fish'], ['mouse', 'fish', 'bird'] ] n = len(all_samples) # 初始化n×n的矩阵,对角线默认填充1,自己和自己的相似度为1 sim_matrix = np.eye(n) for (idx1, idx2) in combinations(range(n), 2): sim = jaccard_similarity(all_samples[idx1], all_samples[idx2]) sim_matrix[idx1][idx2] = sim sim_matrix[idx2][idx1] = sim # 矩阵对称赋值 print("Jaccard相似度矩阵:") print(sim_matrix)
性能说明
1000个个体的场景下,总计需要计算$C_{1000}^2 = 499500$次,这个计算量级Python可以在秒级完成,无需额外优化。如果样本量超过10万级,可以考虑引入并行计算或者稀疏矩阵做优化。
内容的提问来源于stack exchange,提问作者user12727390
相关产品推荐
相关产品推荐

