如何在Python中归一化Euclidean Distance以对比不同样本量结果?
归一化方案说明
你遇到的问题核心是:原代码计算的欧氏距离会随数据点数量n的平方根线性增长,直接对比v50和v1000没有意义,必须消除n的影响才能做相似度对比。
核心思路
先推导下距离的增长规律:
- 代码里
A和B是相关系数为0.6的标准正态分布,每个维度的差值D_i = A_i - B_i的方差为Var(A_i) + Var(B_i) - 2*Cov(A_i,B_i) = 1+1-2*0.6=0.8 n个维度的平方和期望是0.8*n,开根号后的欧氏距离期望为√(0.8n),也就是和√n成正比
所以只要把原始距离除以√n,就能消除n带来的尺度差异,得到和数据点数量无关的归一化值。
两种实现方式
1. 直接修改计算函数
在函数内部完成归一化:
import numpy as np def normalized_euclidean_distance(n): L = np.linalg.cholesky([[1.0, 0.60], [0.60, 1.0]]) uncorrelated = np.random.standard_normal((2, n)) correlated = np.dot(L, uncorrelated) A = correlated[0] B = correlated[1] raw_v = np.linalg.norm(A - B) # 除以n的平方根完成归一化 normalized_v = raw_v / np.sqrt(n) return normalized_v v50_norm = normalized_euclidean_distance(50) v1000_norm = normalized_euclidean_distance(1000)
2. 对已有结果后处理
如果已经得到了v50和v1000,直接做如下计算即可:
v50_norm = v50 / np.sqrt(50) v1000_norm = v1000 / np.sqrt(1000)
归一化后的意义
归一化后的数值可以理解为单维度平均差异的综合度量,数值越小说明A和B的整体相似度越高。此时v50_norm和v1000_norm处于同一尺度,直接对比就能反映两组数据的相似度差异。
如果需要将结果缩放到更直观的范围(比如期望为1),可以再除以理论期望的缩放因子√(2*(1-0.6))≈0.894,让归一化后的结果期望为1,方便理解:
scale_factor = np.sqrt(2 * (1 - 0.6)) v50_scaled = v50_norm / scale_factor v1000_scaled = v1000_norm / scale_factor
内容的提问来源于stack exchange,提问作者HappyPy
相关产品推荐
相关产品推荐

