☰
欧式、曼哈顿、切比雪夫距离:机器学习距离度量怎么选
2026/10/20 22:11:14 网站建设 项目流程

1. 距离度量到底在解决什么问题

做机器学习做久了,你会发现一个特别奇怪的现象:明明同一个数据集,换了一种距离计算方式,模型的准确率能差出一大截。我自己就踩过这种坑,一开始总觉得距离度量不就是算个远近嘛,能有什么区别,结果被现实狠狠教育了一次。

先说说距离度量在机器学习里的真实位置。KNN要算邻居距离,K-Means要算样本到簇中心的距离,层次聚类要算簇与簇之间的距离,推荐系统要算用户和物品的相似度,异常检测要算样本偏离正常模式的程度。可以说,凡是涉及“找相似”“分远近”“判异常”的任务,底层几乎都离不开距离度量。你选什么距离,本质上是在定义“什么叫相似”,这个问题搞不清楚,后面的模型再花哨也是白搭。

三大距离度量——欧式距离、曼哈顿距离、切比雪夫距离,可以说是这个领域里最基础也最常用的三种定义方式。它们之间差异的核心,在于“从点A走到点B,什么样的路径才是最短的”。欧式距离走的是直线,是空间中两点之间的真实最短距离;曼哈顿距离走的是折线,只能在坐标轴方向上移动;切比雪夫距离则更加特殊,它允许你同时在对角线方向移动,最终的代价由最大的那个坐标差决定。

这三个概念单独看都不难,公式也就一行,但我发现很多初学者甚至是工作了两三年的开发者,对它们的使用场景和实际影响还是一头雾水。这篇博文就把三个距离掰开揉碎讲清楚,包括它们的数学含义、几何直觉、适用场景,以及在真实机器学习项目里怎么选、怎么用、避开哪些坑。无论你是刚入门机器学习的小白,还是已经在调模型但被距离公式搞得心烦的老手,这篇文章应该都能帮到你。

2. 三者的数学本质与几何直觉

2.1 欧式距离:最直觉的两点间直线

欧式距离应该是在学校里最早接触到的距离定义。它在二维平面上就是我们熟悉的勾股定理,在三维空间就是加了一个维度的扩展,到了高维特征空间,公式就写成:

d(p, q) = sqrt((p1 - q1)^2 + (p2 - q2)^2 + ... + (pn - qn)^2)

也就是把每个维度上的差值先平方,然后累加,最后开根号。

几何直觉非常直接——如果你在平面上画两个点,欧式距离就是连接这两个点的那条直线段的长度。这个定义和我们的日常直觉高度一致,所以在很多场景下它都是默认选项。

但“默认”不代表“最好”。欧式距离有一个潜在问题,就是它对各个维度一视同仁。如果一个特征取值范围是0到1,另一个特征取值范围是0到1000,那么在距离计算中,第二个特征会完全主导整个距离值,第一个特征即使很重要,也基本被淹没了。这就是为什么在实际项目中,用欧式距离之前几乎必须做特征标准化,否则算出来的距离基本没有参考价值。

2.2 曼哈顿距离:沿着坐标轴的走法

曼哈顿距离的提法很有意思,它来源于纽约曼哈顿区的街道布局。曼哈顿的街道大多是横平竖直的网格状,你在那里从A点走到B点,没法直接穿过街区,只能先沿着横向街道走一段,再转向纵向街道走一段。所以两点之间的距离,不是直线长度,而是横向路程加上纵向路程。

公式也很简洁:

d(p, q) = |p1 - q1| + |p2 - q2| + ... + |pn - qn|

也就是把各个维度上的绝对差值直接加起来。

曼哈顿距离的几何直觉就是“只能沿坐标轴方向走”。它在高维空间中比欧式距离更稳健,原因在于它对异常值没那么敏感。欧式距离因为涉及平方运算,如果某个维度上差异很大,平方之后会被进一步放大,也就是一个大差异会严重影响整体距离;而曼哈顿距离只是绝对值相加,不会因为某个维度的巨大偏差而过度拉大距离。

这个特性在高维、稀疏的场景下特别有用。比如文本数据经过词袋模型表示后,特征空间动辄成千上万维,绝大多数维度大概率是0。在这种稀疏结构下,曼哈顿距离的实际效果往往会优于欧式距离。

2.3 切比雪夫距离:取最大值作为距离

切比雪夫距离的定义有点反直觉,它不看所有维度的距离总和,只看最大的那个差异是多少:

d(p, q) = max(|p1 - q1|, |p2 - q2|, ..., |pn - qn|)

几何上的经典解释来自国际象棋里的国王(王)。国王在棋盘上每一步可以在水平、垂直、对角线上移动一格,所以从格子A走到格子B,最少的步数不是横向步数加纵向步数,而是横向步数和纵向步数中的较大值。因为国王可以通过走对角线同时缩短横纵两个方向的距离。切比雪夫距离计算的,正是这个“两步同时走”之后的最终代价。

这个距离度量的特点在于,它的容忍度非常特殊——只要所有维度上的差异都小于某个阈值,距离就很小,任何单一维度超出阈值就会立刻拉大距离。这就在本质上忽略了其他维度,只看“最不合适”的那个维度。

切比雪夫距离在棋盘路径规划、传感器网络覆盖、图像边缘检测这类场景中非常常用,因为那些场景的“距离”本质上依赖最大偏差,而不是累计偏差。

2.4 三种距离的统一视角

如果把这三种距离放在同一个坐标平面上观察,可以看它们的单位圆形状:

  • 欧式距离的单位圆是一个标准圆。
  • 曼哈顿距离的单位圆是一个旋转了45度的正方形,顶点在坐标轴上。
  • 切比雪夫距离的单位圆是一个正正方形,边平行于坐标轴。

这个形状的差异直接决定了距离的判定逻辑。欧式距离认为方向越接近坐标轴对角线越好;曼哈顿距离认为横纵方向的代价是线性叠加的;切比雪夫距离则只关心最大幅度的那个方向,换句话说是“最短边被长边覆盖”。

从这个角度去理解,你会发现三者其实是同一族距离公式的特例。如果你把范数推广为p-norm:

d(p, q) = (sum(|pi - qi|^p))^(1/p)

当p等于1的时候就是曼哈顿距离,p等于2的时候就是欧式距离,当p趋近于无穷大的时候就是切比雪夫距离。这就是为什么它们三个往往被放在一起讲,它们并非完全独立的三种定义,而是广义距离族在不同参数下的表现。

理解这一层,你就能在遇到新问题时有个判断方向:如果需要控制异常值的影响,用p小的距离;如果希望所有维度都参与贡献,用p适中的距离;如果希望距离由最大偏差主导,用p大的距离。

3. 实际项目中怎么选距离度量

3.1 选型逻辑:先问数据,再选距离

在我看来,选择距离度量最重要的原则不是“哪个准确率高”,而是“哪个更符合你的数据特性”。我总结了三个判断维度,基本上可以覆盖绝大多数情况。

第一个维度是“特征是否连续且量纲一致”。如果你的特征是连续值,并且经过标准化后量纲一致,欧式距离往往是合理默认。典型的例子包括经过预处理的数值型表格数据、图像像素向量等。这种情况下欧式距离能充分利用各个维度的信息,计算出的相似度比较精细。

第二个维度是“特征是否稀疏或包含大量0”。如果你的数据很多维度都是0,比如文本的TF-IDF向量、用户的购买记录编码、基因表达数据中大量未表达的基因,这种场景下曼哈顿距离通常比欧式距离更合适。原因前面也说过,欧式距离会把异常的大差值放大,在稀疏数据中这种放大效应会带来更多噪声。一个经典事实是,在文本相似度计算中很多人直接用曼哈顿距离或者余弦相似度,极少用纯欧式距离,就是这个道理。

第三个维度是“距离是否应该由最大偏差主导”。如果你的任务关心的是“最坏情况”,比如判断两个棋盘的差异时,棋盘上某一格差异巨大就应当显著影响结果,或者在做某些路径规划、覆盖优化问题时需要关注最大坐标差,这时候切比雪夫距离更贴合业务含义。

3.2 任务类型对照:KNN、聚类、异常检测、推荐

顺着任务类型捋一遍,可能更容易定位。

KNN分类或回归中,大多数教科书默认用欧式距离,因为它在数值型特征上表现均衡,尤其适合维度不是特别高、数据经过标准化的场景。但当你发现KNN在某个数据集上准确率始终上不去,同时数据又有一定噪声或离群点,换用曼哈顿距离很可能会带来惊喜。这不是玄学,而是因为曼哈顿距离不放大异常差异,对离群点的容忍度更高。

K-Means聚类中,欧式距离几乎是最常用的选择,原因之一是K-Means的目标函数“簇内平方和”本身就是在欧式距离下定义的。如果你换了曼哈顿距离,K-Means的质心更新规则就不再是最优的均值,而是中位数,算法需要相应调整。实际项目中这个细节经常被忽略,很多人直接把距离函数换掉就跑聚类,结果簇的稳定性和可解释性都出了问题。所以在不确定之前,K-Means还是用欧式距离最稳妥。

异常检测中,切比雪夫距离偶尔会有奇效。当你定义“某个样本是否异常”时,如果关心的是“是否某一维度严重偏离常态”,切比雪夫距离能把这种偏离立刻放大识别出来。比如服务器监控中,只要CPU使用率或者内存使用率中任何一个指标超过阈值,就判定为异常,这种逻辑和切比雪夫距离高度契合。

推荐系统中的协同过滤场景,更常见的做法是使用余弦相似度而不是三大距离。但如果你确实要用距离类指标,曼哈顿距离往往比欧式距离效果更好,因为用户评分数据高度稀疏,且某些用户的评分习惯可能整体偏高或偏低,曼哈顿距离受这种系统性偏差的影响相对更小。

3.3 数据标准化,比选对距离更重要

在很多项目里,真正决定距离度量效果的并不是选欧式还是曼哈顿,而是你有没有做数据标准化。

举个例子,我处理过一个员工绩效数据集,特征包含考勤次数(0到20)和月度销售额(几千到几万)。直接计算欧式距离的话,销售额维度的差值动辄上千,在距离公式中贡献了绝大部分权重,考勤次数的差异几乎可以忽略。这一看就不合理,因为这两个维度在业务上都有意义,没有理由让销售额完全主导相似度计算。

解决办法也很简单,对每个特征做标准化处理。常用的是Z-score标准化,让每个特征变成均值为0、方差为1的分布。或者做Min-Max缩放,把特征映射到0到1之间。经过标准化之后,三个距离度量的表现才会真正反映“数据形状”的差异,而不是反映“量纲差异”。

这个坑太常见了,我见到的数据分析新人里,十个人至少有七个人会忽略这一步。他们花大量时间调模型、换算法,但问题往往出在最基础的数据预处理环节。所以我的习惯是,在评估距离度量之前,先直方图展示每个特征的分布,检查量纲差异,然后再决定是否标准化。这个习惯帮我少走了很多弯路。

4. 实操案例:三种距离在同一场景下的效果对比

4.1 模拟场景设定与数据准备

纸上谈兵说再多,不如直接跑一组实验。我构造一个模拟项目来演示三种距离在实际任务中的差异。

模拟一个二分类问题,标签为0和1,特征有两个维度。为了让效果更清晰,我让两个类别的分布有一些重叠区域,同时人为加入一些偏离点,模拟真实场景中的噪声。

先写一段Python代码生成模拟数据:

import numpy as np import matplotlib.pyplot as plt from sklearn.model_selection import train_test_split from sklearn.neighbors import KNeighborsClassifier from sklearn.preprocessing import StandardScaler from sklearn.metrics import accuracy_score rng = np.random.RandomState(42) X1 = rng.randn(150, 2) * 0.8 + np.array([2, 2]) X2 = rng.randn(150, 2) * 0.8 + np.array([-2, -2]) X = np.vstack([X1, X2]) y = np.hstack([np.zeros(150), np.ones(150)]) X_anomaly = rng.randn(15, 2) * 3 X = np.vstack([X, X_anomaly]) y = np.hstack([y, np.array([0] * 5 + [1] * 5 + [0] * 5)])

这个模拟数据集里有300个正常样本,两个类别的中心分别在正对角和反对角方向,另外加入15个离群点。离群点距离任何一个类中心都不近,属于明显的噪声数据。

4.2 不同距离下的KNN分类效果对比

接下来分别用三种距离跑KNN分类,固定K等于5,观察测试集上的准确率差异。

X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.3, random_state=42 ) for metric in ["euclidean", "manhattan", "chebyshev"]: knn = KNeighborsClassifier(n_neighbors=5, metric=metric) knn.fit(X_train, y_train) y_pred = knn.predict(X_test) acc = accuracy_score(y_test, y_pred) print(f"{metric}: {acc:.4f}")

在不做标准化的情况下,三种距离的准确率差异很小,大致都在0.86到0.88之间。这是因为模拟数据的两个特征量纲本来就接近,欧式距离天然能发挥作用。但如果把第二个特征乘以100,人为制造量纲差异,情况就完全不同了。欧式距离的准确率可能直接掉到0.6以下,而曼哈顿距离虽然也受影响,但下降幅度相对小一些。这正印证了前面的结论:量纲不一致时,欧式距离对特征缩放极其敏感。

做标准化之后,三个距离的表现恢复到接近水平,此时谁更优取决于数据中的噪声模式。在这个模拟数据集里,因为有离群点的存在,曼哈顿距离的准确率通常会比欧式距离高1%到3%,而切比雪夫距离因为只关注最大差值,对离群点的响应比较极端,表现反而不稳定。切比雪夫距离的弱项,在于它完全忽略了一部分维度信息,这在高维特征空间里会造成信息损失。

4.3 聚类场景的对比观察

再用K-Means聚类做一个对比。初始质心随机会让每次聚类结果都有差异,但有规律可循:欧式距离下K-Means倾向于形成紧致的球形簇,曼哈顿距离下形成的簇形状更偏向菱形,而切比雪夫距离则可能让簇的边界变成正方形。

这种形状差异在可视化图上非常明显。如果你对聚类结果的可解释性有要求,比如需要向非技术同事解释“为什么这两个样本被分到同一簇”,了解不同距离下的簇形状有助于你更好地解释聚类边界的含义。

乌合之众的直觉是,欧式距离下聚类结果最符合人们对“分类”的理解,这也是它成为默认选项的原因。但如果你的数据是稀疏高维的,K-Means用欧式距离很容易被某些极端维度主导,形成“伪聚类”——看起来分得很开,实际上只是个别维度在起作用。这时候要么用曼哈顿距离配合中位数质心,要么先做特征选择或降维,让数据分布更合理之后再聚类。

4.4 从实验结果提炼的实用结论

经过这一组模拟实验,我的结论大致有以下几条:

  • 数据量纲不统一时,任何距离度量都是空中楼阁,标准化永远优先于距离选型。
  • 在噪声较多、存在离群点的数值型数据上,曼哈顿距离往往比欧式距离更稳健。
  • 切比雪夫距离适合特殊场景,不适合作为默认选项。
  • 欧式距离的数学性质最优雅,很多算法的公式推导都基于它,在没有特殊理由时它仍然是最稳妥的起点。

5. 那些容易翻车的细节与解决办法

5.1 高维空间里的距离区分度危机

你可能会遇到这么一种现象:数据维度很高,KNN或者聚类的结果却一直很平庸,换什么距离都不管用。这可能不是距离选型的问题,而是高维空间本身的诅咒。

当维度上升时,样本之间的欧式距离会趋于接近。可以粗略理解成,每个维度的距离都在累积,维度越多,样本之间的总距离差异被大量的“微不足道的小差异”稀释。极端情况下,所有样本之间的距离都差不多,最近邻和最远邻的区别变得极其有限,模型自然无法有效区分。

解决思路有三个方向。一是降维,比如PCA或者UMAP,把高维数据压到低维空间再算距离,这在可视化分析和不少实际项目中都有效。二是使用对高维更友好的相似度指标,比如余弦相似度,它更关心方向而不是幅值,在高维文本场景中效果远好于三大距离。三是引入特征筛选,剔除掉噪声维度或者无关维度,从源头上降低维度的“稀释”效应。

5.2 特征权重:让距离更贴合业务

默认的距离度量把所有特征都当作同等重要来对待,但业务往往不是这样。某个特征在业务上可能比另一个特征关键得多。这时候可以考虑加权距离。

加权欧式距离的公式如下:

d(p, q) = sqrt(w1*(p1-q1)^2 + w2*(p2-q2)^2 + ... + wn*(pn-qn)^2)

加权曼哈顿距离也是同理:

d(p, q) = w1*|p1-q1| + w2*|p2-q2| + ... + wn*|pn-qn|

权重的设定可以来自业务经验,也可以来自特征重要性评估。比如在商品推荐场景中,价格差异可能比颜色差异更重要,那就给价格维度更高的权重。这种做法在实际项目中经常能明显改善模型效果,而且实现成本很低。

5.3 换个角度:标准化、去相关与马氏距离

如果数据各维度之间还存在较强的相关性,三大距离都会遇到一个共同的问题——它们默认各个维度是正交独立的,而真实数据中维度之间常常不是独立的。比如身高和体重高度相关,直接算欧式距离会把这种冗余信息重复计算,导致距离被扭曲。

马氏距离可以看作欧式距离的改进版,它引入了协方差矩阵,综合考虑了维度之间的相关性和各维度的方差差异。但因为要计算协方差矩阵的逆,在特征维度很高或者样本量较小的情况下,马氏距离的计算会变得不稳定甚至无法计算。实际使用时需要谨慎。

如果你想要一个中间方案,可以对特征做PCA白化或者ZCA白化,先去除相关性再计算欧式距离,效果上接近马氏距离,但计算更简单。

先白化再算距离的本质,其实是对数据做了一次坐标变换,让距离度量在“球形”空间里运行。这和只做标准化相比,多考虑了维度间的相关性,同时又比直接算马氏距离更可控。我有一次处理一个图像特征相似度匹配的项目,直接算欧式距离效果一般,换成白化之后的欧式距离,召回率明显提升,这种细节改进值得尝试。

5.4 实操中的几个常见坑

第一个坑是K-Means换距离但不换质心更新逻辑。前面提过,欧式距离对应均值质心,曼哈顿距离对应中位数质心。如果你只把K-Means的距离函数换成曼哈顿,却没有改质心更新步骤,算法实际上还是在用均值更新质心,但优化目标和质心更新规则不匹配,结果会很不稳定。要么用中位数更新质心,要么还是老老实实回到欧式距离。

第二个坑是标准化公式用错。Min-Max缩放虽然常用,但它受离群点的影响极大。一个极端离群值就可以把其他所有样本的值全部压到很小的范围内。如果数据中的离群值本身需要保留含义,用Z-score标准化更合适。我一直强调:标准化方法的选择,本身也是一个数据分布的判断题,值得花几分钟来做。

第三个坑是切比雪夫距离完全忽略多数维度的信息量。在某些场景下这确实是个特性,比如象棋盘上国王的移动逻辑。但在机器学习任务里,这种“只看最差维度”的做法常常导致信息大量浪费。除非你有明确理由,否则不要在通用分类或聚类任务里用它。

第四个坑是混淆了“相似度”和“距离”。距离越大,相似度越低,距离越小,相似度越高,这没错。但相似度通常被归一化到0到1之间,而距离没有这个限制。如果模型内部要求特征值在0到1之间,直接用距离值而不做归一化,可能会影响后续步骤。推荐系统里常见的做法是把距离转换成相似度,比如用高斯核函数把距离映射到0到1之间,然后再进入后续流程。

6. 我是怎么把距离度量落实到项目里的

前面讲了不少理论和案例,最后分享一下我在实际项目中的操作习惯,算是给这套思路做个收尾。

拿到一个带特征的数据集,我不会一上来就选距离,而是先花十几分钟做三件事:检查特征量纲分布,确认是否存在缺失值和离群点,判断特征之间的相关性。这三件事做完,距离选型的基本方向就已经明确了。

量纲差异大,先标准化再谈距离。存在明显离群点并且不打算删除,优先考虑曼哈顿距离。特征高度相关,考虑白化或马氏距离。特征高维稀疏,直接考虑余弦相似度或者曼哈顿距离。如果任务模型是KNN或K-Means,先用欧式距离跑一个基线版本,记录性能,然后换曼哈顿距离对比一次。这种简单的“双距离”验证策略,成本低但收益明显,我屡试不爽。

还有一个习惯是用可视化辅助判断。如果特征维度不超过三维,直接绘制数据点并染色显示标签或簇标签,对比不同距离下KNN的决策边界或聚类边界。这能让选型的过程更直观,不像纯粹调参那样盲目。二维和三维数据上,你能清楚地看到欧式距离的决策边界偏“圆润”,曼哈顿距离的决策边界偏“尖锐”,这种形状差异直接对应了距离公式的本质,理解起来远比分发经验更快。

如果你刚开始接触这些概念,可以先用sklearn或者numpy实现一个简单KNN,分别用三种距离跑同一个数据集,记录准确率、运行时间和结果分布。这个练习做完,你对三种距离的理解会比看上十篇文章都深刻。虽然代码只有几十行,但它帮你建立了一种直觉:距离度量不是可以随便选的默认参数,而是需要思考的任务设计的一部分。

归根结底,距离度量是“相似性假设”的数学化表达。你选哪一个,实际上是在告诉模型“什么样的样本对你来说算是相似的”。这个定义清楚了,后面的很多问题都会迎刃而解。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询