基于Target列相似度数据计算Source列元素间的相似性
问题描述
现有一张包含Source、Target、Similarity三列的表:
Source和Target为字符串类型Similarity为浮点型
该表通过计算每个Source元素与Target元素的相似度生成,每个Source对应20个最相似的Target元素。现在需要为每个Source找出最相似的5个其他Source元素,但禁止直接计算Source间的相似度(计算成本过高)。核心思路为:若两个Source元素与同一个Target元素的相似度都很高,则二者也相似。
此前尝试过两种方法,但均未充分利用所有数据:
- 按相似度降序排序每个
Source对应的Target,选取Top5 Target有重合的Source - 筛选出将选中
Source的Top1 Target纳入自身Top5 Target,且相似度超过阈值的Source
附此前尝试的代码片段:
selected_source = "Source 1" for i in range(len(Source)): if similarity_json[selected_source][Target][0] in similarity_json[Source[i]][Target][:5] and similarity_json[Source[i]][similarity]>0.5: source_similars.append(Source[i])
最优实现方案
核心方法:加权共现相似度计算
通过Source与Target的关联相似度做加权累加,量化Source间的相似性,充分利用所有现有数据,步骤如下:
构建Target到Source的反向映射
为每个Target记录所有关联的Source及其对应的相似度值,示例结构:Target_X: [(Source_A, 0.9), (Source_B, 0.85), ...]计算Source间的加权共现得分
对每个Source S,遍历它对应的20个Target(带相似度权重),对每个Target关联的其他Source,累加「S与该Target的相似度 × 其他Source与该Target的相似度」,作为两者的相似得分。
公式简化为:
得分(S1, S2) = Σ( Sim(S1, T) × Sim(S2, T) ),其中T为S1和S2共同关联的Target排序取Top5相似Source
对每个Source,将其他所有Source按计算出的得分降序排序,取前5个即为最相似的结果。
效率优化点
- 可仅保留每个
Target关联的Top10个Source,在不损失核心共现信息的前提下减少计算量 - 可选取
Source的Top10个Target参与加权计算,平衡计算效率与数据利用率
简化版代码示例
# 1. 构建Target到Source的反向映射 target_to_sources = {} for source in similarity_json: # 遍历当前source的所有Target-Similarity对 for idx, target in enumerate(similarity_json[source]['Target']): sim = similarity_json[source]['Similarity'][idx] if target not in target_to_sources: target_to_sources[target] = [] target_to_sources[target].append( (source, sim) ) # 2. 计算每个Source的相似得分并取Top5 source_similar_scores = {} for selected_source in similarity_json: scores = {} # 遍历当前source的所有Target及对应相似度 for idx, target in enumerate(similarity_json[selected_source]['Target']): s1_sim = similarity_json[selected_source]['Similarity'][idx] # 遍历该Target关联的其他Source for (other_source, s2_sim) in target_to_sources[target]: if other_source == selected_source: continue # 累加加权得分 scores[other_source] = scores.get(other_source, 0) + s1_sim * s2_sim # 按得分降序排序,取前5个相似Source sorted_similars = sorted(scores.items(), key=lambda x: x[1], reverse=True)[:5] source_similar_scores[selected_source] = [item[0] for item in sorted_similars]
内容的提问来源于stack exchange,提问作者Mitsarien
相关产品推荐
相关产品推荐

