假设你来到一座路网横平竖直的棋盘格城市,要去拜访三位朋友。第一位朋友家在东北角,你叫了一架直升机笔直飞过去——这就是“欧氏距离”。第二位朋友家在需要绕行商业区的地方,出租车只能沿着街道拐来拐去——这就是“曼哈顿距离”。第三位朋友住在离城很远的地方,你并不关心要开多少公里,只想知道他家在不在你正打算去的方向上——这就是“余弦相似度”。同一个城市、同一批朋友,换一种问法,答案就完全不同。 机器学习里的“距离度量”干的正是同一件事:判断两个样本有多像。KNN 要找最近的邻居,K-means 要把相近的点聚成一团,推荐系统要找出和你口味相似的用户——它们都在用某把“距离尺子”量相似度。尺子选错了,看起来最像的邻居可能根本不是你的同类。这篇文章把三把最常用的尺子——欧氏、曼哈顿、余弦——逐一拆开,讲清各自的脾气、适用场景和选择方法,让你在真实数据面前选对那一把。
距离度量是KNN、K-means、推荐系统的底层标尺,选对度量直接决定模型效果,是AI从业者做算法调优的必备基本功。
目录
可视化演示
本节配有交互动效(进入视口后自动加载,约 3KB)。
三种距离的几何直觉 欧氏:直线距离曼哈顿:格子路距离余弦:方向夹角欧氏:直线距离欧氏:直线距离曼哈顿:格子路距离余弦:方向夹角欧氏:直线距离 欧氏:直线距离曼哈顿:格子路距离余弦:方向夹角欧氏:直线距离欧氏:直线距离曼哈顿:格子路距离余弦:方向夹角欧氏:直线距离
距离度量直觉:三问定方向
走进这座横平竖直的棋盘格城市,先别急着出发,你得想清楚自己到底要问什么:朋友家直线距离多远——这该问直升机;出租车沿街道要开多久——这该问司机;朋友家在哪个方向、跟不跟我同路——这该掏指南针。三个问题答案不同,但都是“度量”。机器学习里,数据也住在这样的空间里:每个样本是一个点,每个特征是一条坐标轴。一个用户,年龄是横轴,每月消费是纵轴,注册时长是竖轴——他就稳稳地坐在某个坐标上,两个用户之间的距离,就是他们“有多像”的答案。
“距离度量”就是回答“两个点像不像、有多像”的尺子。尺子不是随便造的,任何合格的度量都得守三条规矩,数学家叫它“度量公理”:距离不能是负数;从 A 到 B 和从 B 到 A 一样远;抄近道不会比绕路更远。这三条保证尺子不闹脾气、不偏袒。
守规矩的尺子才能放心用。接下去三节,我们分别坐直升机、打出租车、掏指南针,把三把尺子的刻度看个清清楚楚。
- 非负性任意两点的距离都不可能是负数,等于 0 当且仅当两点重合——尺子量不出“负长度”。
- 对称性从 x 到 y 和从 y 到 x 的距离相同,方向不影响远近——去朋友家和朋友来你家,路程一样。
- 三角不等式直接从 x 到 z 不会比先绕到 y 再转去 z 更远——抄近道永远不亏,这也解释了下文曼哈顿为何总不小于欧氏。
欧氏距离:直升机的直线飞行
你叫来直升机,机长说得干脆:“两点之间,直线最短。”这就是欧氏距离的直觉——不绕路,笔直飞。它是我们从小最熟悉的“距离”:从家到学校的路、操场对角线的长度,都是勾股定理在二维平面上的样子。机器学习里,欧氏距离是默认选项,出场率最高的一把尺子。
把勾股定理推广到高维:两个点各有 n 个坐标,先算每个维度上的差距,再把差距平方、求和、开根号。为什么平方?因为差距有正有负,平方后统统变成正贡献,而且大的差距会被放大,让“差异大”的维度更显眼。为什么开根号?把平方造成的膨胀拉回来,让结果还原成“长度”的单位,而不是“面积的平方根”。
直升机飞得最直,但城市里到处是大楼,直线常常穿墙而过。遇到量纲混乱、稀疏高维的数据,这条直线就不那么可信了——该考虑换尺子了。
- 逐维差值先看每个坐标轴上的差距,比如年龄差几岁、消费差几元。
- 平方处理把正负差距都变成正数,同时放大大的差距——大差异在距离里更有分量。
- 逐维求和把所有维度上的平方差距累加,得到“总差异能量”。
- 开根还原开根号把平方的膨胀拉回来,结果就是两点间真正的直线长度。
曼哈顿距离:出租车的格子街道
直升机的直线可能穿过大楼,出租车却只能沿着横平竖直的街道走:先直行,再拐弯,画出一个直角折线。这种“沿坐标轴走的路线长度”就是曼哈顿距离,名字来自纽约曼哈顿区——那里的街道就是棋盘格,出租车无法斜穿街区,只能老老实实拐弯。
数学上,曼哈顿距离把每个维度的差的绝对值直接相加,不需要平方,也不需要开根号。没有平方,意味着某个维度上特别夸张的差异不会被放大成十倍百倍——这正是它对离群点更鲁棒的原因。数据里偶尔蹦出几个“极端用户”(比如某天消费突然放大一百倍),用欧氏会被这个大数带偏,用曼哈顿则稳定得多。
出租车没有直升机快,却不会被“直线穿楼”欺骗。当数据里充满噪声和异常值时,走街的尺子往往比贴身直飞的尺子更稳。
- 逐维差值同样先算每个坐标轴上的差距,这是所有距离度量的起点。
- 取绝对值去掉正负号,只保留差距的大小,体现“无论谁大谁小,差多少就是多少”。
- 直接求和不经平方直接相加,极端大差不被放大,得到出租车走街的折线总路程。
余弦相似度:指南针的方向感
第三位朋友住在城郊,离你 1 公里还是 10 公里,其实你都不在乎——你只想知道他家在不在你打算去的方向上。这时掏出指南针:只要方向都是东北,两人就算“同路”。这就是余弦相似度的直觉:不看远近,只看方向。
数学上,把两个样本想象成从原点射出的两条箭头(向量),箭头越长代表整体数值越大。余弦相似度就是两条箭头夹角的余弦:夹角 0° 时余弦为 1,方向完全相同;90° 时余弦为 0,垂直、无关;180° 时余弦为 -1,完全相反。它天生忽略长度——一个向量是另一个的 10 倍,只要方向一样,相似度照样满格。
指南针永远指向方向而非距离。在词向量、推荐系统的高维世界里,方向往往比远近更有意义。
- 点积对应维度相乘再求和,衡量两向量“同向分量”的总和。
- 模长每个向量自身的长度,由各分量平方和开根得到。
- 求比值同向分量除以两倍长度,消除长度影响,只剩夹角信息。
- 转成距离相似度是越大越像,需用 1 减相似度得到“余弦距离”,才符合“越小越近”的习惯。
度量选择:给数据选对尺子
体温计量不了身高,卷尺量不了角度。尺子必须配数据。三把尺子各有脾气,选错的结果是:KNN 找到的“最近邻居”根本不是同类,聚类聚出一锅乱炖。所以拿到数据,第一步不是跑模型,而是先看数据长什么样,再决定用哪把尺子。
三条经验法则:连续稠密的数值特征(身高、房价、温度),量的是真实差距,用欧氏;高维稀疏的向量(文本 TF-IDF、one-hot 编码),量的是方向,用余弦;特征里常有离群点(异常交易、极端消费),别让大数带偏,用曼哈顿。多数场景下,“欧氏 + 归一化”是稳妥的起点。
说到归一化,它是欧氏距离绕不开的前提:量纲不同(年龄几十岁 vs 收入几万元),收入会全面主导距离,年龄白算。最常用的方法是 min-max 归一化,把每个特征压到 [0, 1] 区间:
先给特征统一刻度,再选合适的尺子,量出来的“相似”才算数。尺子配对了,后面一切模型才有意义。
- 减最小值把特征整体平移,让最小值变成 0,消除基准差异。
- 除以极差用最大值减最小值的跨度做分母,把所有取值压缩到 [0, 1],每个特征站在同一起跑线。
算法实战:选对尺子才能找到邻居
你来到新城市,想知道自己属于哪个片区。最靠谱的办法:问最近的 K 位朋友住在哪,看哪边人多就跟哪边走。这就是 KNN 的核心思想——用距离找邻居,让邻居投票。可问题是:“最近”靠什么定义?靠的就是距离度量。
KNN 里,换一把尺子,最近邻居名单就可能整个换掉:某些样本按欧氏看数值很近,按余弦看方向却很远。K-means 聚类同理——它把每个点分给最近的簇中心,距离定义变了,聚类形状就变了。推荐系统也靠“相似用户”“相似物品”找关联,背后大多站着余弦或经过归一化的欧氏。所以调优时把“度量”当作超参数去试,是常规操作。
距离尺子决定了你的“朋友圈”是谁,进而决定模型猜得准不准。多换几把尺子对比,往往比盲目调参更见效。
- 邻居集合用选定的距离度量找出离目标点最近的 K 个样本,构成邻居名单。
- 指示计数对每个邻居检查其类别是否为 c,是则计 1,否则计 0,完成一次投票。
- 多数投票对每个类别求和取最大,票数最多的类别胜出,成为最终预测。
AI 应用场景
文本检索与新闻推荐(余弦相似度)
阶段:特征工程 / 召回排序
解决的问题:传统关键词匹配只认字面重合,“苹果手机”和"iPhone"这类语义相近但用词不同的内容匹配不上。把文章转成 TF-IDF 向量后用余弦相似度,两篇文章即便篇幅差 10 倍,只要话题方向一致,相似度就高,召回更准。
具体案例:新闻 App 的“相似推荐”模块,先把每篇文章转成上万维的 TF-IDF 向量,用户读完一篇,系统在千万文章库中逐一计算余弦相似度,取 Top-N 推荐。若改用欧氏距离,会被大量零维度和篇幅差异干扰,推荐质量明显下降。
用户画像聚类(归一化 + 欧氏/曼哈顿)
阶段:数据预处理 / 聚类分析
解决的问题:用户特征量纲混乱(年龄几十、消费上万),直接算欧氏会被消费金额主导,年龄形同虚设。先用 min-max 归一化统一刻度再聚类,每个特征才能平等发言;若用户群里有极端的“土豪”离群点,曼哈顿比欧氏更稳。
具体案例:电商平台按年龄、月消费、活跃天数三个特征聚类用户,得到“价格敏感型、品质型、高潜新客”等群体,运营针对不同群体投放不同策略。
异常交易检测(曼哈顿距离)
阶段:异常检测 / 风控
解决的问题:欺诈交易往往是“极端离群点”——偶发大额、深夜转账,特征值跳出正常范围。欧氏距离平方放大极端差,反而让正常交易显得异常;曼哈顿不放大极端差,能稳定识别真正偏离行为轮廓的交易。
具体案例:支付平台为每位用户维护历史行为特征,每笔新交易计算其与历史轮廓的曼哈顿距离,超过阈值即触发人工复核,显著降低误报率。
Python 演示
import math def euclidean(p, q): return math.sqrt(sum((a - b) ** 2 for a, b in zip(p, q))) def manhattan(p, q): return sum(abs(a - b) for a, b in zip(p, q)) def cosine_similarity(p, q): dot = sum(a * b for a, b in zip(p, q)) np_ = math.sqrt(sum(a * a for a in p)) nq = math.sqrt(sum(b * b for b in q)) if np_ == 0 or nq == 0: return 0.0 return dot / (np_ * nq) def knn_predict(X, y, x, k=3, metric="euclidean"): dists = [] for xi, yi in zip(X, y): if metric == "euclidean": d = euclidean(x, xi) elif metric == "manhattan": d = manhattan(x, xi) elif metric == "cosine": d = 1 - cosine_similarity(x, xi) else: raise ValueError("unknown metric") dists.append((d, yi)) dists.sort(key=lambda t: t[0]) votes = {} for _, yi in dists[:k]: votes[yi] = votes.get(yi, 0) + 1 return max(votes, key=votes.get) if __name__ == "__main__": X = [[1, 2], [2, 3], [8, 8], [9, 9]] y = ["A", "A", "B", "B"] x = [3, 4] print("欧氏距离预测:", knn_predict(X, y, x, k=3, metric="euclidean")) print("曼哈顿距离预测:", knn_predict(X, y, x, k=3, metric="manhattan")) print("余弦相似度预测:", knn_predict(X, y, x, k=3, metric="cosine"))
return math.sqrt(sum((a - b) ** 2 for a, b in zip(p, q)))欧氏距离核心:逐维差平方求和再开根,对应直升机直线飞行。return sum(abs(a - b) for a, b in zip(p, q))曼哈顿核心:逐维绝对差直接相加,没有平方放大,对应出租车折线路程。dot = sum(a * b for a, b in zip(p, q))余弦分子:点积衡量两向量同向分量。return dot / (np_ * nq)余弦相似度:点积除以两向量模长,长度差异被消掉,只剩方向。d = 1 - cosine_similarity(x, xi)相似度越大越像,转成 1 减相似度才符合“距离越小越近”的排序习惯。dists.sort(key=lambda t: t[0])按距离升序排序,最近的 K 个邻居排在列表最前面。votes[yi] = votes.get(yi, 0) + 1邻居投票:字典计数,每个邻居给它的类别投一票。return max(votes, key=votes.get)取票数最多的类别作为 KNN 预测结果。
常见误区
误区欧氏距离是最自然、最常用的距离,不管什么数据,先跑欧氏准没错,换别的度量差别也不大。
正解差别恰恰很大。特征量纲不同时,欧氏会被数值大的维度绑架——“收入”几万元和“年龄”几十岁放一起,年龄直接失去发言权;数据高维稀疏时,欧氏又被大量零维度稀释。余弦看方向、曼哈顿抗离群,各自救场。选度量像选鞋:跑鞋、登山鞋、凉鞋各有场合,只有一双会磨脚。
为何常见:人类对“直线距离”的直觉根深蒂固,欧氏又是教材默认选项,容易形成惯性思维。
误区两篇文章余弦相似度 0.98,那它们内容肯定差不多,篇幅和用词应该都很接近。
正解余弦只回答“方向是否一致”,不回答“长度是否相同”。同一话题,一篇 1000 字一篇 10000 字,TF-IDF 向量方向几乎相同,余弦接近 1,但篇幅差 10 倍。好比两位朋友都住东北方向,一个在 1 公里外,一个在 10 公里外——指南针可不管远近。要同时看长短,得配合向量模长或改用其他度量。
为何常见:“相似度”三个字给人“什么都像”的错觉,忽略了它只度量了夹角这一个维度。
误区曼哈顿走的折线比直线长,说明它更不精确,只是欧氏距离的粗糙近似,能不用就不用。
正解它不是近似,而是一种独立的度量,回答的是“沿坐标轴走多远”,与“直线飞多远”是两回事。欧氏在平方时放大了极端差异,曼哈顿没有,因此对离群点更鲁棒。在特征含噪声、极端的场景里,曼哈顿反而是更准的尺子——真实城市里,出租车里程就是比飞行直线更符合实际。
为何常见:人天生觉得“直线最准”,折线显得繁琐笨拙,于是被贴上“粗糙”标签。
误区不管欧氏、曼哈顿还是余弦,反正都是越小越像,排序结果应该差不多,随便选一个就行。
正解三种度量的排序可能完全不同。例如两个点长度相同但方向不同,余弦判它们“不一致”(夹角大),欧氏却可能判它们“很近”(数值接近)。KNN 换度量后,最近邻居名单会改写,分类结果随之改变。度量不是“怎么算都行”的细节,而是决定模型看到哪类相似性的世界观。
为何常见:初学时只关注“计算相似度”这个动作,忽略了不同度量定义了完全不同的几何直觉。
面试题
Q1. 二维点 (1,2) 与 (4,6) 之间的欧氏距离是?
- A.3
- B.4
- C.5← 正确答案
- D.6
答案:C。欧氏距离 = √[(4-1)² + (6-2)²] = √(9+16) = √25 = 5,相当于直升机从 (1,2) 直飞到 (4,6) 的航程。3 是两维差值直接相加的结果,4 和 6 只是单维度差值,都不对。
Q2. 余弦相似度为 1 表示两个向量?
- A.方向完全相同← 正确答案
- B.两向量互相垂直
- C.方向完全相反
- D.长度一定相等
答案:A。余弦是夹角余弦,为 1 时夹角 0°,方向完全一致——指南针上两位朋友都在东北方,余弦就说“同路”。垂直时余弦为 0,相反时为 -1,而长度与余弦无关。
Q3. 曼哈顿距离在二维平面上对应哪条路径?
- A.沿坐标轴的折线路程← 正确答案
- B.两点之间直线距离
- C.单位圆上的弧线长度
- D.任意曲线的最短长度
答案:A。曼哈顿距离只允许沿横竖方向移动,像出租车在棋盘格街道上先横后竖走折线,对应 A。B 是欧氏距离,C 是角度类度量,D 不属于这三种标准度量。
Q4. 曼哈顿距离比欧氏距离对离群点更鲁棒,主要原因是?
- A.没有平方放大差异← 正确答案
- B.计算复杂度更低
- C.不需要做归一化
- D.支持任意高维
答案:A。欧氏先平方再开根,极端大差被平方放大,一个离群维度就能主导整段距离;曼哈顿取绝对值直接相加,极端差不被放大,因此更稳。计算复杂度、归一化、维度支持都不是“鲁棒性”的原因。
Q5. 对同一对点,曼哈顿距离与欧氏距离的数值关系是?
- A.曼哈顿不小于欧氏← 正确答案
- B.欧氏不小于曼哈顿
- C.两者总是相等
- D.关系随机无规律
答案:A。折线不可能比直线短,即 |dx|+|dy| ≥ √(dx²+dy²),曼哈顿永不小于欧氏。只有两点在同一水平线或竖直线上时才相等,这正是三角不等式的直接体现。
Q6. 做文本相似度检索时首选余弦相似度,因为?
- A.方向比长度更有意义← 正确答案
- B.欧氏距离完全不可用
- C.余弦取值只有零和一
- D.文本向量全部是二维
答案:A。TF-IDF 向量上万维且稀疏,文章篇幅造成的长度差异没有语义,话题方向才代表相似,所以看夹角。欧氏并非不可用,只是会被大量零维度和长度差异干扰;余弦取值连续,文本向量也远非二维。
Q7. 关于“余弦距离 = 1 - 余弦相似度”的说法正确的是?
- A.一般不满足三角不等式← 正确答案
- B.它一定满足三角不等式
- C.它等价于曼哈顿距离
- D.它总是小于欧氏距离
答案:A。1 - cos 只是把相似度倒转成“距离感”,它一般不满足三角不等式——存在三点使 d(A,C) > d(A,B) + d(B,C)。真正的角距离 arccos 才满足三角不等式。它与欧氏、曼哈顿没有等价或恒定的数值关系。
Q8. 使用欧氏距离前,哪些做法能改善效果?
- A.对特征做归一化处理← 正确答案
- B.消除量纲差异影响← 正确答案
- C.随机打乱特征顺序
- D.任意增大特征数值
答案:AB。欧氏对量纲敏感,归一化统一刻度后各特征才能平等参与距离计算,所以 A、B 正确。打乱顺序不改变数值分布、随意增大数值只会加重量纲失衡,均无改善作用。
Q9. 以下哪些场景适合曼哈顿距离?
- A.网格化街道坐标数据← 正确答案
- B.特征含明显离群点← 正确答案
- C.高维稀疏文本词频
- D.向量方向比长度更关键
答案:AB。曼哈顿沿坐标轴走,天然契合网格街道场景(A);绝对值不放大极端差,抗离群干扰(B)。高维稀疏文本和方向敏感场景更适合余弦相似度,所以 C、D 不适合曼哈顿。
Q10. 关于三种度量的差异,下列说法正确的有?
- A.欧氏对量纲大小敏感← 正确答案
- B.余弦忽略向量长度← 正确答案
- C.曼哈顿对离群点鲁棒← 正确答案
- D.三种度量结果都一样
答案:ABC。欧氏平方会放大数值大的维度,量纲敏感(A 对);余弦由夹角决定,与长度无关(B 对);曼哈顿不做平方所以抗离群(C 对)。三种度量刻画不同几何直觉,结果通常不同,D 错。