三维特征点与标量质心的欧氏距离计算困惑及相关算法实现咨询
三维特征点与类别质心的欧氏距离计算问题解答
首先要明确:你遇到的计算失败,核心问题不在欧氏距离函数本身,而是你的质心计算逻辑出错了,导致得到的是一个标量,而非和特征点同维度的向量——这才是欧氏距离无法正确计算的根源。
1. 质心计算的错误分析
你的__compute_centroid函数逻辑完全偏离了“类别质心”的定义:
- 现在的代码会把每个三维点的三个特征值先求和(比如点
[3.5,2.5,7.5]会被计算成3.5+2.5+7.5=13.5),然后把所有点的这个求和值加总,再除以点数,最终得到一个标量。 - 但正确的类别质心应该是每个特征维度的平均值,也就是一个和输入点同维度的向量(比如三维特征点对应的质心就是三维向量)。
举个例子:如果你的训练点是[[3.5,2.5,7.5], [1.0,2.0,3.0]],正确的质心应该是:
- 第一维度平均值:
(3.5+1.0)/2 = 2.25 - 第二维度平均值:
(2.5+2.0)/2 = 2.25 - 第三维度平均值:
(7.5+3.0)/2 = 5.25
也就是质心向量为[2.25, 2.25, 5.25],而不是你的函数计算出的(13.5+6)/2=9.75这个标量。
2. 修正后的质心计算函数
原生Python实现
def __compute_centroid(self, points): # 获取特征维度数(比如三维点就是3) feature_dim = len(points[0]) # 初始化每个维度的累加和为0 dim_sums = [0.0 for _ in range(feature_dim)] for point in points: # 对每个维度分别累加 for idx in range(feature_dim): dim_sums[idx] += point[idx] # 每个维度除以点数,得到质心向量 return [sum_val / len(points) for sum_val in dim_sums]
用Numpy简化实现(如果项目允许使用Numpy)
Numpy的mean函数可以直接按维度计算平均值,代码更简洁:
import numpy as np def __compute_centroid(self, points): # axis=0表示按列(特征维度)计算平均值 return np.mean(points, axis=0).tolist()
3. 欧氏距离函数的适配
你的__euclidean函数逻辑是正确的,但它要求输入的x和y必须是同维度的向量。当你修正质心计算,得到三维质心向量后,直接传入原函数就能正常计算:
from math import sqrt, pow def __euclidean(self, x, y): return sqrt(sum(pow(a - b, 2) for a, b in zip(x, y))) # 示例调用 feature_point = [3.5, 2.5, 7.5] corrected_centroid = [2.25, 2.25, 5.25] # 修正后的三维质心 distance = self.__euclidean(feature_point, corrected_centroid)
此时计算的就是标准的三维欧氏距离:sqrt((3.5-2.25)² + (2.5-2.25)² + (7.5-5.25)²),结果完全正确。
总结
- 核心问题:质心计算错误,生成了标量而非同维度向量,导致欧氏距离函数无法处理不同维度的输入。
- 解决步骤:先修正质心计算函数得到同维度质心向量,再用原欧氏距离函数计算即可。
内容的提问来源于stack exchange,提问作者A.L.
相关产品推荐
相关产品推荐

