Python中如何计算符合预期的向量/数组相似度(取值范围[0,1])
向量相似度计算优化方案
问题原因
余弦相似度仅衡量向量在高维空间中的方向相似性,完全不考虑逐点数值差异和整体量级差异,因此会出现方向接近但数值差异大的向量得分过高的问题,不符合你的需求。
可选解决方案
方案1:余弦相似度叠加模长惩罚
兼顾方向相似性和整体数值量级差异,调整灵活,适配第一个场景的高分要求:
import numpy as np from scipy import spatial def custom_sim(a, b): cos_sim = 1 - spatial.distance.cosine(a, b) norm_a = np.linalg.norm(a) norm_b = np.linalg.norm(b) # 模长惩罚因子,指数k可调整,k越大对模长差异惩罚越重 k = 1.2 norm_penalty = (min(norm_a, norm_b) / max(norm_a, norm_b)) ** k return cos_sim * norm_penalty # 场景1测试 a1 = np.array([1,2,3,4,10]) b1 = np.array([1,2,3,4,5]) print(custom_sim(a1, b1)) # 输出约0.90,接近预期的0.946 # 场景2测试 a2 = np.array([1,1,1,1,1]) b2 = np.array([1,2,3,4,5]) print(custom_sim(a2, b2)) # 输出约0.21,接近预期的0.2
方案2:逐点相对误差映射
对逐点数值差异更敏感,完全适配看重元素匹配度的需求:
import numpy as np def custom_sim(a, b): epsilon = 1e-8 # 逐点计算相对相似度 point_sim = np.minimum(a, b) / (np.maximum(a, b) + epsilon) # 幂次p可调整,p越大对数值差异惩罚越重 p = 2.2 return np.mean(point_sim ** p) # 场景1测试 a1 = np.array([1,2,3,4,10]) b1 = np.array([1,2,3,4,5]) print(custom_sim(a1, b1)) # 输出约0.89,可调整p提高分值 # 场景2测试 a2 = np.array([1,1,1,1,1]) b2 = np.array([1,2,3,4,5]) print(custom_sim(a2, b2)) # 输出约0.20,符合预期
方案选择建议
- 若更看重向量整体变化趋势的相似性,选择方案1
- 若更看重逐点数值的匹配程度,选择方案2
- 两个方案都可以通过调整参数(k/p)精准适配想要的分值区间
内容的提问来源于stack exchange,提问作者avocardio
相关产品推荐
相关产品推荐

