曼哈顿距离与欧几里得距离:选型指南与实战对比
曼哈顿距离与欧几里得距离——这对概念在我实际的项目里踩过的坑比想象中多得多。最近在做一个基于位置特征的相似度匹配系统,数据点散布在高维特征空间里,一开始无脑选了欧几里得距离,结果召回结果差到怀疑人生。后来逐个排查才发现,问题恰恰出在距离度量的选择上。这个经历让我意识到,两种距离看起来只是公式差了一点点,但背后的几何直觉、适用场景、对数据的敏感度都完全不同。这篇就系统梳理一下两者的差异、应用思路和实战中的坑,给正在做机器学习、数据挖掘、路径规划或者图像处理的朋友一个参考。
1. 两种距离的定义与直观理解
1.1 从公式到直觉:一维到n维
先说最朴素的定义。假设有两个点,在二维平面上表示为 P1(x1, y1) 和 P2(x2, y2)。欧几里得距离是我们从小到大最熟悉的那条"直线距离",公式是:
d_euclidean = sqrt((x1 - x2)^2 + (y1 - y2)^2)而曼哈顿距离,也叫 L1 距离、街区距离,计算方式则是:
d_manhattan = |x1 - x2| + |y1 - y2|两者推广到 n 维空间时,形式也一脉相承:
- 欧几里得(L2):对所有维度上的差值平方求和,再开根号
- 曼哈顿(L1):对所有维度上的差值取绝对值,直接求和
很多人看一眼公式就觉得:"不就是差一点点吗?"但实际差得远了。我举个例子,点 A(1, 2) 到点 B(4, 6):
- 欧几里得距离:sqrt((4-1)^2 + (6-2)^2) = sqrt(9 + 16) = 5
- 曼哈顿距离:|4-1| + |6-2| = 3 + 4 = 7
数值差了 2,但这只是最简单的例子。在高维空间、在稀疏特征下、在数据分布不均匀的场景里,这两种距离给出的排序结果可能天差地别。后面我会慢慢拆。
1.2 城市街区与乌鸦飞行:两种生活化类比
理解这两种距离最直观的方式就是类比。
曼哈顿距离,名字本身就取自纽约曼哈顿的街区布局——方方正正的棋盘式街道。你想从 A 点走到 B 点,不能穿楼过墙,只能沿着街道横平竖直地走,最后走的实际路程就是曼哈顿距离。所以我经常叫它"出租车距离",导航软件里如果设定"最短步行路径",在理想街区网格下计算出来的就是它。
欧几里得距离则是"乌鸦距离"——天空中没有建筑物阻挡,乌鸦从 A 点直线飞到 B 点,那就是欧几里得。凡是能用尺子直接量的物理空间中的直线距离,基本都是它。
为什么这个类比重要?因为现实中的很多问题,天然决定了该用哪种距离。城市路网导航用曼哈顿更合理(除非你开的是直升机);计算两个 GPS 坐标点的实际空间远近用欧几里得(或者更精确的球面距离);但如果是比较两份文档的语义特征向量,那两种距离都可能有道理,需要具体分析。
有一个细节我经历过很多次才真正意识到:曼哈顿距离对坐标系的旋转是敏感的,而欧几里得距离具有旋转不变性。也就是说,如果你把整个坐标系旋转 45 度,重新计算两个固定物理点的距离,欧几里得距离不变,曼哈顿距离变。这一点在图像特征匹配、空间变换任务里会直接导致结果差异,后面讲几何性质时再展开。
2. 几何性质与数学本质的差异
2.1 单位圆与"距离空间"的形状
在数学上,一种距离度量定义了空间中的"球面"。欧几里得空间中的单位圆是标准的圆形:所有到原点距离等于 1 的点构成一个圆。但曼哈顿空间中的单位圆是什么形状?
很多人第一次算这个问题会愣一下:满足 |x| + |y| = 1 的点,画出来是一个旋转了 45 度的正方形(顶点在坐标轴上),更像一个菱形。如果继续沿着这个思路,切比雪夫距离(L∞,取各维度差值绝对值的最大值)的单位圆就是正儿八经的正方形。
这个几何直觉极其重要。它直接决定了:
- 距离度量对异常值的容忍度
- 嵌套空间下的体积对比
- 高维空间中的行为差异
我来举个例子说明高维的影响。设特征维度是 d,所有特征值均匀分布在 [-1, 1] 之间。计算任意两点之间的欧几里得距离和曼哈顿距离,随着维度升高,前者会受"平方求和"的影响,使得距离的绝对值分布更集中,而后者是绝对值求和,分布更分散。在实际模型中,这就意味着用曼哈顿距离时,最近邻的区分度可能更明显,而欧几里得距离在高维下所有距离都趋同——这就是"维度灾难"的一种体现。
很多做推荐系统的人都有体会:特征向量维度上百后,点积和欧几里得距离的检索效果明显退化,换曼哈顿或者余弦,往往能找到意外惊喜。
2.2 性质对比:关于旋转、可微与三角不等式
为了更清楚地说明,我把关键性质整理成一个对照表:
| 性质 | 曼哈顿距离 (L1) | 欧几里得距离 (L2) |
|---|---|---|
| 旋转不变性 | 无,依赖坐标系方向 | 有,任意旋转不改变距离 |
| 可微性 | 在差值等于 0 的点不可微 | 处处可微(除零点外) |
| 对异常值敏感度 | 低(绝对值抑制) | 高(平方放大) |
| 三角不等式 | 成立,但等号条件更多 | 成立,等号条件更严格 |
| 单位圆形状 | 菱形(正方形旋转45度) | 圆形 |
| 坐标轴相关性 | 隐含坐标轴方向假设 | 纯几何空间距离 |
先说可微性的影响。机器学习的损失函数里,L1 正则化和 L2 正则化的本质差异,就在于这俩距离度量在优化时的行为。L1 的不可微点在零点处会产生稀疏解,把很多特征的系数压成 0,而 L2 会均匀地缩小系数。很多做特征选择的朋友应该都体会过:Lasso(L1)能直接把无关特征系数剃掉,Ridge(L2)则保留全部特征但压缩数值。这就是距离度量数学性质在算法层面的直接映射。
三角不等式这一点也藏了很多坑。欧几里得距离满足三角不等式:d(A,C) ≤ d(A,B) + d(B,C),而且通常严格小于。曼哈顿距离也满足三角不等式,但它有一个特征——当中间点 B 恰好位于 A 到 C 的某种"阶梯路径"上时,等号条件非常容易满足。什么意思?就是曼哈顿距离在某些数据布局下会丧失"中介辨别能力",三个点看起来都差不多远。这在聚类算法中可能导致边界样本归属不稳定。
在实际业务里,如果你发现聚类结果总是边界模糊,不同算法反复调整初始化都差不多,可以考虑是否是因为曼哈顿距离的等号条件太容易成立,让点与点之间缺乏区分度。
3. 应用场景选择与实战经验
3.1 特征空间中的相似度计算:KNN 与聚类的选型思路
先说最常见的场景:K近邻算法(KNN)、K-means 聚类、层次聚类等等,这些基于距离度量的算法,完全依赖你选择哪种距离定义"相似"。
我有一个经历印象挺深。某次做用户行为聚类,特征向量是用户在几个类目下的行为计数。数据经过标准化后,我试了欧几里得距离,聚类结果把高频行为和低频行为用户混在一起,分不出层次。后来换曼哈顿距离,结果清晰很多。
为什么?因为计数类特征往往带有明显的偏态分布和异常值——有少数用户行为量大得离谱。欧几里得距离会放大这些异常维度上的差异,导致个别极端用户把聚类中心拉偏。曼哈顿距离对每个维度的差异只取绝对值,虽然也会受影响,但不像平方那样放大。
在这个场景下,我的选型建议是:
- 特征是计数、频率类数据:优先考虑曼哈顿,对偏态分布更稳健
- 特征是连续物理量(坐标、长度、温度):欧几里得更自然
- 特征经过 L2 归一化(向量长度归一化到单位范数):欧几里得排序结果和余弦相似度一致,可以直接用
- 高维稀疏特征:曼哈顿往往比欧几里得更可用,实在不行试余弦
3.2 路径规划与网格地图中的启发函数
如果你做过基于栅格地图的路径规划,比如 A* 算法,距离度量的选择直接影响搜索效率和路径质量。这里的逻辑很清晰:
- 4 连通网格(只能上下左右走):曼哈顿距离是完美的启发函数
- 8 连通网格(还能斜着走):切比雪夫距离更合适
- 任意角度自由移动:用欧几里得距离
启发函数有一个核心约束:它必须不大于真实代价,才能保证 A* 找到最优解(即"可采纳性")。在四连通网格中,两点之间最短真实路径就是横平竖直的曼哈顿距离,所以用曼哈顿距离作为启发函数既不会低估也不会高估,属于"完美启发"。而如果你在四连通网格里用了欧几里得距离,由于斜线距离总是小于实际路径的曼哈顿距离,启发函数会严重低估代价,导致搜索需要扩展大量节点,效率大幅下降。
反过来,在可以自由移动的连续空间,曼哈顿又显得太保守了,启发函数给出的估值太低,搜索范围变得很大。我踩过这个坑:第一版路径规划 A* 的启发式用了曼哈顿,结果在一张没有障碍物的 200x200 地图上搜索节点数爆炸,后来改成欧几里得,节点数缩小了一个数量级。
路径规划问题的关键,是让你的距离度量尽量贴近真实运动代价。
3.3 图像处理与直方图匹配
图像处理和计算机视觉里也存在这两种距离的鲜明对照。
拿直方图匹配来说。两幅图像的颜色直方图可以看作高维空间中的向量,衡量它们之间的差异,可以用欧几里得距离,也可以用曼哈顿距离。但在实际应用中,曼哈顿距离在直方图相似度上经常表现得更好。原因是直方图本身就是"计数"的产物,颜色分箱后每个箱子的值代表像素数量,欧几里得距离会对大差异箱子过度加权,比如一个箱子差了 100 和差了 10,欧几里得会认为前者的权重是后者的 100 倍,而曼哈顿只认为是 10 倍。对颜色分布相似性判断来说,后者往往更符合直觉。
另一个经典例子是模板匹配中的 SAD(绝对差值和)与 SSD(差值平方和)。SAD 就是曼哈顿距离,SSD 就是欧几里得距离的平方。在光照变化较大的场景,SAD 通常更稳健,因为平方项对亮度突变更敏感。很多实时视觉跟踪的框架里,默认用 SAD 计算块匹配代价,就是这个原因。
如果做图像处理时发现匹配结果老是"过拟合"到某些强梯度区域,试试换 SAD 或曼哈顿类距离,常常能平滑掉这种偏差。
3.4 归一化之前必须想清楚的事
这个经验我觉得比选哪种距离本身更重要。不管用哪种距离,如果特征之间的量纲差异巨大,计算出的距离都会被大数值维度主导,那么"距离"就失去了比较多个维度的意义。
举个例子。两个特征维度,一个是用户年龄(0-100),一个是用户月消费金额(0-20000)。如果不归一化直接用欧几里得距离计算两个用户的相似度,年龄维度的贡献可以忽略不计,距离实际上变成了消费金额的绝对值差。而曼哈顿距离遇到类似问题时,至少每个维度只贡献绝对值,但大数维度依然占主导。
所以我的铁律是:先归一化,再谈距离度量。常见的做法包括 Min-Max 归一化、Z-score 标准化,针对稀疏特征还有 unit vector 归一化。归一化之后,两种距离度量的对比才有意义。
但要注意一个隐蔽的坑:Z-score 标准化后,曼哈顿距离和欧几里得距离的选择会显著影响KNN的表现。因为 Z-score 把每个维度的方差都变成 1,欧几里得距离等于"所有维度上距离平方和的平方根",意味着每个维度的重要性完全对等;而曼哈顿则对每个维度的绝对差异直接求和,在高维且很多特征属于噪声的情况下,噪声维度的贡献会被线性累加,反而可能压过有效信号。这个场景下,如果你知道特征里噪声维度较多,欧几里得相对更能抑制噪声(平方和开方后大值被稀释),而曼哈顿则会把噪声直接加进去。
这类问题没有万能的答案,得结合数据情况实验对比。
4. 代码实现、常见问题与排坑实录
4.1 距离计算的工程实现
实际工程中用 Python 实现这两种距离非常简单,numpy 几行就搞定:
import numpy as np def euclidean_distance(a, b): return np.linalg.norm(a - b) def manhattan_distance(a, b): return np.sum(np.abs(a - b)) # 示例 p1 = np.array([3.0, 4.0, 2.0]) p2 = np.array([1.0, 7.0, 6.0]) print(euclidean_distance(p1, p2)) # sqrt(4 + 9 + 16) = 5.385 print(manhattan_distance(p1, p2)) # 2 + 3 + 4 = 9.0批量计算距离矩阵时,scipy.spatial.distance 提供 cdist 和 pdist,效率高且自带多种度量:
from scipy.spatial.distance import cdist X = np.random.rand(100, 10) Y = np.random.rand(50, 10) d_euclidean = cdist(X, Y, metric="euclidean") d_manhattan = cdist(X, Y, metric="cityblock")工程上有几个小提示:
- 计算欧几里得距离时,直接用 np.linalg.norm 会触发 sqrt,如果只是比较谁更近,可以省略 sqrt,直接比较平方距离,省一次开方计算
- 高维批处理中,cdist 默认会分配一个大矩阵(M 行 N 列),样本量大时注意内存,必要时分块处理
- 对稀疏矩阵,scipy.spatial.distance 的 cdist 支持有限,建议自己用稀疏矩阵乘法实现曼哈顿距离的加速版本
4.2 真实项目中的踩坑与排查
距离度量选错这件事,往往不是立即暴露的,而是藏在效果指标后面。
第一个坑:未归一化直接算距离。我见过一个推荐系统项目,特征里有一个维度是"购买次数",另一个是"客单价",两者量纲差了上百倍。结果模型学到的近邻关系几乎完全由客单价决定,购买次数的信号完全被淹没。排查时用特征重要性分析看不出问题,后来打印了几组最近邻样本才发现距离被某个维度主导。解决方案是 Min-Max 归一化 + 重训模型,效果立刻改善。
第二个坑:在高维稀疏向量里用欧几里得距离。一个文本分类项目,特征向量用 TF-IDF 表示,维度上万,向量稀疏度 90% 以上。一开始用欧几里得距离做 KNN,准确率非常不稳定。换成曼哈顿距离后,稳定提升了几个百分点。原因很简单:TF-IDF 向量的稀疏性使得大部分维度差值都是 0,但有少量维度差值很大,欧几里得对这些大差值平方放大,容易让个别异常特征主导;而曼哈顿线性累加更平滑,保留了"多个维度共同贡献相似度"的信息。在稀疏高维特征场景下,距离度量的选择影响非常明显。
第三个坑:坐标系变换后曼哈顿距离的意义发生漂移。某次做几何特征的相似度匹配,特征向量是物体在图像中的位置 (x, y)。我用曼哈顿距离计算两个检测框位置相似度,一开始效果还行,后来把图像坐标做了旋转增强,曼哈顿距离的相似度排序就乱了。原因正如前面所讲——曼哈顿距离依赖坐标轴方向,旋转坐标系后曼哈顿距离变了,但物理上的空间距离没有变。这个场景必须回归欧几里得,或者对特征空间进行对齐后再用曼哈顿。
这三个坑如果能在项目早期识别出来,能省大量调试时间。
4.3 距离度量选择的决策清单
经过这些实践,我整理了一个适合自己的选型逻辑,供参考:
1. 任务是空间/物理量相关? → 欧几里得优先 (坐标定位、距离估算、几何匹配等) 2. 特征是计数/频率/稀疏向量? → 曼哈顿优先 (TF-IDF、直方图、行为计数等) 3. 对异常值敏感度高? → 曼哈顿优先 (欧几里得的平方会放大异常影响) 4. 特征维度高 + 噪声维度多? → 测试对比,优先欧几里得试跑 (平方和开方能稀释噪声;曼哈顿线性累加噪声) 5. 路径规划网格地图? (4连通用曼哈顿,8连通用切比雪夫,自由移动用欧几里得) 6. 不确定? → 归一化后,在验证集上直接 A/B 对比这只是一个起点,不是金科玉律。真实数据往往比这些直觉复杂得多,很多项目里我会同时算两种距离,放进模型里做特征,甚至把两种距离同时作为相似度特征交给下游模型去学习权重,效果经常会比二选一更好。
在 KNN 和聚类这类强依赖距离的算法里,一个更进阶的做法是直接用"加权混合距离":d_mix = α * d_manhattan + (1-α) * d_euclidean,通过网格搜索确定 α。这个技巧我试过几次,在处理混合类型特征时往往能得到比单一度量更好的效果。
4.4 常见问题速查
| 问题现象 | 可能原因 | 建议方案 |
|---|---|---|
| 近邻样本不符合业务直觉 | 特征量纲差异大 | 归一化后重算距离 |
| 高维特征下所有距离接近 | 维度灾难 | 换曼哈顿/余弦,或降维 |
| 聚类边界模糊不清晰 | 曼哈顿等号条件易成立 | 换欧几里得并检查特征冗余 |
| 匹配结果被个别维度过拟合 | 平方项放大异常维度 | 换曼哈顿或对特征做降权 |
| 旋转/缩放后结果不一致 | 曼哈顿依赖坐标轴 | 空间对齐或换欧几里得 |
| TF-IDF 场景 KNN 效果差 | 稀疏向量 + 欧几里得 | 换曼哈顿或余弦 |
这个表是我在几次项目的复盘记录里提炼出来的,并非理论推导的产物,大家遇到类似问题时可以直接对照排查。
4.5 关于数据预处理的一点心得
最后再补充一个容易忽略的点:无论选择哪种距离,数据预处理必须和距离度量配套设计。
如果选了欧几里得距离,特征最好做 Z-score 标准化,让每个维度的方差一致,这样欧几里得距离才不会语义漂移。如果选了曼哈顿距离,特征可以做 Min-Max 归一化,再到单位区间,曼哈顿距离等于各维度绝对差之和,含义清晰,也方便解释结果。
另外,对于含有缺失值的数据,两种距离的处理难度也不同。欧几里得距离在缺失值较多时,通常需要填充或删除样本;曼哈顿距离对缺失值更宽松,某些实现允许跳过失控维度,只计算有效维度上的绝对差。sklearn 的 pairwise_distances 对带缺失值的数组支持有限,通常需要自己写掩码。如果数据中缺失率较高,曼哈顿距离更容易做出"部分匹配"的工程方案。
我自己的习惯是:预处理管线先定型,再在固定管线上对比不同距离度量,而不是先选距离再调整预处理,否则两者互相干扰,很难定位问题。
曼哈顿和欧几里得的对比,说到底不是"哪个更正确",而是"哪个更适合当前的数据和问题"。数学定义只是起点,真正有价值的是理解每种距离在数据中的行为倾向,然后在实验里反复验证。建议你下次做相似度、聚类、检索或者路径规划时,花几分钟想一想自己数据的形态,再决定选哪一种。多数情况下,这一步能避免你后面花几十倍的时间在调参和排查上。