AI 数学课程 · 第 43 课,共 180

距离取决于所选几何

从范数推导距离,在 L1、L2 和 L-无穷范数下比较一个微型最近邻搜索,并调试 AI 系统中的度量选择。

分享这篇文章

当工单路由器、推荐系统或检索系统寻找“最近的”已存示例时,它其实做出了一个几何选择。当每个坐标分别作出贡献时最近的点,可能会输给另一个按平方长度组合坐标时更近的点。算法并没有变得不一致;变的是“接近”的含义。

学完本课后,你将能够从范数推导距离,在多种度量下计算一个小型最近邻排序,并识别让这个排序有意义的预处理和并列处理决策。

学习目标: 从范数推导距离并比较最近邻。

本课建立在第 040 课:L1、L2 与 L-无穷范数对大小的不同理解之上;该课介绍了衡量单个向量大小的几种方式。官方 Mathematics for Machine Learning 一书的第 3.3 节提供了数学参考。这里的数据集、计算、代码、可视化和练习题均为原创。

最近的点始于位移

设 x=(x1,…,xn)x=(x_1,\ldots,x_n) 和 y=(y1,…,yn)y=(y_1,\ldots,y_n) 是 Rn\mathbb{R}^n 中的两个点。每个坐标都是一个特征位置;nn 是特征数量。要询问 xx 距离 yy 多远,先逐坐标相减:

x−y=(x1−y1,…,xn−yn).x-y=(x_1-y_1,\ldots,x_n-y_n).

这个差是一个位移向量。它表示一个点在每个坐标上需要移动多少才能到达另一个点。交换相减顺序会改变位移的符号,但两种情况下范数给出的大小相同,因为 ∥v∥=∥−v∥\lVert v\rVert=\lVert -v\rVert。

这些名称描述了不同的移动规则。L1 通常称为曼哈顿距离,把每个坐标的移动量相加。L2 衡量位移的直线长度。L-无穷范数只关注单个坐标中最大的移动量。使用其中一种度量的模型,就是在声明哪些移动类型应被视为代价高昂。

第 3.3 节的参考资料还通过 ∥v∥=⟨v,v⟩\lVert v\rVert=\sqrt{\langle v,v\rangle} 将内积与范数联系起来。在通常的点积下,这就是欧几里得范数,因此 d2(x,y)=⟨x−y,x−y⟩d_2(x,y)=\sqrt{\langle x-y,x-y\rangle}。一个有用的细节是,距离构造适用于任何范数:L1 是有效范数,即使它在通常的实向量空间意义下不是由内积诱导的,它仍会诱导出有效度量。

为什么必须先相减

距离通过一个位移来比较两个位置,而不是比较它们各自大小的差。例如,若 x=(1,1)x=(1,1) 且 y=(1,−1)y=(1,-1),两个点的 L2 范数都是 2\sqrt{2},但

x−y=(0,2),d2(x,y)=02+22=2.x-y=(0,2),\qquad d_2(x,y)=\sqrt{0^2+2^2}=2.

计算 ∥x∥2−∥y∥2=0\lVert x\rVert_2-\lVert y\rVert_2=0 会抹去这两个点在竖直方向相距两个单位这一事实。安全的思维口诀是先相减,再应用所选范数。

同一组点可以得到不同的最近邻

考虑查询点 q=(0,0)q=(0,0),以及二维表示中的三条候选记录。坐标特意取为较小的无量纲数:它们表示经过某种特征表示后的值,而不是普遍适用的相似性概念。

点描述坐标
AA轴向占优的情况(6,0)(6,0)
BB均衡的情况(4,4)(4,4)
CC混合的情况(5,2)(5,2)

排序会改变,是因为不同范数会奖励不同形状的位移。在这里,L1 偏好轴向占优的点 AA,因为它的坐标总移动量最小。L2 选中 CC:它的两个坐标组合出的直线线段比 BB 的对角线和 AA 的长水平线段都短。L-无穷范数选中 BB,因为没有任何单个坐标移动超过 44。

一次查询,三张邻居图

该表是完整的语义后备内容:距离越小,候选点就越接近查询点 q = (0, 0)。
候选点坐标L1绝对移动量之和L2直线长度L-无穷范数最大的坐标移动量
A 轴向占优(6, 0)6.000排名 16.000排名 36.000排名 3
B 均衡(4, 4)8.000排名 35.657排名 24.000排名 1
C 混合(5, 2)7.000排名 25.385排名 15.000排名 2
最近的两个候选点A → CC → BB → C

圆圈内的数字表示该度量下的排名。虚线指向最近的候选点;前两个排名带有轮廓,因此这张图不依赖颜色来传达信息。

一次查询,三张邻居图在 L1 下,顺序为 A、C、B;在 L2 下,顺序为 C、B、A;在 L-无穷范数下,顺序为 B、C、A。每个面板中的查询点都位于原点。L10246024特征 1特征 2查询 qA1B3C2L20246024特征 1特征 2查询 qA3B2C1L-无穷范数0246024特征 1特征 2查询 qA3B1C2

在 L1 下,顺序为 A、C、B;在 L2 下,顺序为 C、B、A;在 L-无穷范数下,顺序为 B、C、A。每个面板中的查询点都位于原点。

即使查询点和候选点的坐标保持不变,几何也会改变邻居图。

无需阅读 SVG,表格和排名标签就已经呈现了结论。可视化额外提供了一个空间线索:度量改变时,虚线的终点会改变,而坐标本身保持不变。

透明的 NumPy 搜索

NumPy 的 numpy.linalg.norm 文档 展示了这里所需的两个控制项:ord 选择范数阶数,axis 选择要进行归约的坐标轴。因此,包含三行候选点的批次可以通过从每一行中减去查询点,再分别对每行做归约来处理。

下面的代码复现了推导过程,而不是把它藏在最近邻对象中。代码已用 NumPy 执行;打印出的顺序与上面的例子相同。

import numpy as np

query = np.array([0.0, 0.0])
points = np.array([[6.0, 0.0], [4.0, 4.0], [5.0, 2.0]])
labels = np.array(["A", "B", "C"])

difference = points - query
for name, order in [("L1", 1), ("L2", 2), ("L-infinity", np.inf)]:
    distances = np.linalg.norm(difference, ord=order, axis=1)
    ranked = np.argsort(distances, kind="stable")
    print(
        f"{name}: "
        + ", ".join(f"{labels[i]}={distances[i]:.3f}" for i in ranked)
    )
L1: A=6.000, C=7.000, B=8.000
L2: C=5.385, B=5.657, A=6.000
L-infinity: B=4.000, C=5.000, A=6.000

有三个独立操作值得注意:

  1. points - query 在应用任何范数之前执行相减。
  2. axis=1 为每行计算一个范数,因此每个候选点得到一个距离。
  3. argsort 把距离变成排序;范数本身并不决定如何处理相等的值。

对于更大的数据集,scikit-learn 的 NearestNeighbors 类封装了同样的思想。它的 metric="minkowski" 设置使用参数 p,其中 p=1p=1 对应 L1,p=2p=2 对应 L2;它的 kneighbors 方法同时返回距离和索引。当搜索需要集成进模型管道时,估计器很有用;但 NumPy 版本更适合调试,因为每个中间数组都可见。

对于这个确切例子,等价的搜索配置是:

from sklearn.neighbors import NearestNeighbors

search = NearestNeighbors(n_neighbors=2, metric="minkowski", p=2)
search.fit(points)
distances, indices = search.kneighbors(query.reshape(1, -1))
nearest_labels = labels[indices[0]]

把 p 改为 1 或 np.inf 会改变几何,同时保持数据和 k=2k=2 的值不变。API 并没有让度量选择消失;它只是把这个选择明确写成参数。

会改变答案的边界条件

只有在特征空间、度量和搜索策略都明确之后,距离才是精确的。以下情况最容易让一个小型最近邻演示产生误导。

并列是信息,不是噪声

设 q=(0,0)q=(0,0)、u=(1,1)u=(1,1),以及 v=(2,0)v=(2,0)。两个候选点都有

d1(q,u)=∣1∣+∣1∣=2,d1(q,v)=∣2∣+∣0∣=2.d_1(q,u)=|1|+|1|=2, \qquad d_1(q,v)=|2|+|0|=2.

如果 k=1k=1,数学给出的是并列,而不是唯一胜者。生产系统应声明确定性的次级键,返回所有并列候选点,或采用适合其应用的策略。NumPy 代码中的 stable 排序让重复运行具有可复现性,但并不能证明排在第一位的并列行更相似。

相同点的距离为零

如果 x=yx=y,那么 x−y=(0,…,0)x-y=(0,\ldots,0),每个范数都会给出 d(x,y)=0d(x,y)=0。这是有效的精确匹配,不是错误。不过,在训练集查找中,对同一个已拟合集合查询一行数据,可能会把该行自身作为最近邻。在解释结果之前,先决定自匹配是否有用;一个碰巧与已存行重复的外部查询仍应得到距离零。

特征缩放是几何的一部分

假设一个坐标是以美元计的年收入,另一个是从零到十的计数。仅仅因为数值单位更大,美元坐标就可能支配 L1 或 L2 距离。标准化、重新缩放或分配领域权重都会改变几何,而不是一个无关紧要的前置步骤。任何依赖数据的缩放规则都应在训练数据上拟合,并对查询使用同一规则,否则邻居图可能从评估集泄露信息。

距离和余弦相似度回答不同问题

距离比较两个点之间的位移,因此包含它们的位置和大小。余弦相似度则在归一化长度后比较方向。对于 x=(1,1)x=(1,1) 和 y=(10,10)y=(10,10),

cos⁡(x,y)=xTy∥x∥2∥y∥2=1,\cos(x,y)=\frac{x^\mathsf{T}y}{\lVert x\rVert_2\lVert y\rVert_2}=1,

因为两个向量的方向完全相同,而

d2(x,y)=∥x−y∥2=(−9)2+(−9)2=92≈12.728.d_2(x,y)=\lVert x-y\rVert_2 =\sqrt{(-9)^2+(-9)^2}=9\sqrt{2}\approx12.728.

嵌入检索系统可能在“匹配”意味着方向时偏好余弦相似度。对尺度敏感的应用可能偏好由范数诱导的距离。没有一种选择普遍正确;而且余弦相似度还需要针对零向量制定单独策略,因为零向量的方向没有定义。

高维需要测量,而不是口号

在某些高维数据分布中,最近距离和最远距离可能变得越来越接近,使排序的区分度降低。Beyer、Goldstein、Ramakrishnan 和 Shaft 在他们关于最近邻的论文中描述了特定条件下的这种距离集中结果。这个结果提醒我们注意数据和工作负载假设,并不是说每个嵌入空间都会变得无用。在责怪搜索算法之前,应检查邻居距离间隔,在留出查询上验证度量,并考虑表示中是否包含许多无关坐标。

下一课将分离出距离有意与长度混合的方向比较:第 044 课《角度与余弦相似度》。当该课的翻译集上线后,Math for AI 英文课程页面将显示它。

检验理解

Question 1

对于 x = (5, −2) 和 y = (1, 1),计算位移以及 L1、L2 和 L-无穷范数距离。

Show the step-by-step solution

先减去两个点:x−y=(5−1,−2−1)=(4,−3)x-y=(5-1, -2-1)=(4,-3)。对这一个位移应用每个范数。L1 是 ∣4∣+∣−3∣=4+3=7|4|+|-3|=4+3=7。L2 是 sqrt(4² + (−3)²) = sqrt(16 + 9) = 5 。L-无穷范数是最大的绝对坐标,max⁡(4,3)=4\max(4,3)=4。三个距离分别是 7、5 和 4。

Question 2

为什么 ||x||₂ − ||y||₂ 不是 x 与 y 之间距离的一般公式?请用 x = (1, 1) 和 y = (1, −1) 说明。

Show the step-by-step solution

两个单独的长度都是 ∥x∥2=12+12=2\lVert x\rVert_2=\sqrt{1^{2} + 1^{2}} =\sqrt2 和 ∥y∥2=12+(−1)2=2\lVert y\rVert_2=\sqrt{1^{2} + (-1)^{2}}=\sqrt2,所以它们的差为零。实际位移为 x−y=(0,2)x-y=(0,2),其 L2 范数为 02+22=2\sqrt{0^{2} + 2^{2}}=2。距离必须先相减,因为它衡量的是连接两个位置的向量,而不是它们到原点距离的差。

Question 3

使用 q = (0, 0)、A = (6, 0)、B = (4, 4) 和 C = (5, 2),在 L-无穷范数下哪两个候选点最近?请展示三个相关距离。

Show the step-by-step solution

减去 qq 后得到候选点坐标。L-无穷范数距离保留最大的绝对坐标:d∞(q,A)=max⁡(6,0)=6d_\infty(q,A)=\max(6,0)=6、d∞(q,B)=max⁡(4,4)=4d_\infty(q,B)=\max(4,4)=4,以及 d∞(q,C)=max⁡(5,2)=5d_\infty(q,C)=\max(5,2)=5。将 4、5 和 6 排序后,BB 排第一,CC 排第二,因此两个邻居的结果是 [B,C][B,C]。

Question 4

在 L1 下,q = (0, 0)、u = (1, 1) 和 v = (2, 0) 并列。并列距离是多少,k = 1 的实现必须决定什么?

Show the step-by-step solution

计算每个点相对于原点的位移。对 uu,L1 给出 ∣1∣+∣1∣=2|1|+|1|=2;对 vv,给出 ∣2∣+∣0∣=2|2|+|0|=2。因此并列距离为 2。k=1k=1 的实现必须选择一种策略:返回两个候选点并让后续步骤解决并列,使用有文档记录的次级键,或采用应用规则。数组顺序可能让输出具有确定性,但不会让某个点在数学上更近。

Question 5

如果查询点 x 和存储点 y 都是 (2, −1),那么它们在每个范数下的距离是多少?为什么这个结果有意义?

Show the step-by-step solution

位移为 x−y=(2−2,−1−(−1))=(0,0)x-y=(2-2,-1-(-1))=(0,0)。每个范数都会把零向量映射为零,因此对于 L1、L2 和 L-无穷范数,d(x,y)=0d(x,y)=0。这就是不可分辨同一点性质:相同点没有位移。它作为精确匹配是有意义的,不过在训练集上搜索时,可能需要明确的自匹配策略。

Question 6

为什么未经缩放的特征可能支配距离?用 L2 距离比较 q = (0, 0)、a = (1, 100) 和 b = (2, 0)。

Show the step-by-step solution

位移为 a−q=(1,100)a-q=(1,100) 和 b−q=(2,0)b-q=(2,0)。它们的 L2 距离分别是 12+1002=10001≈100.005\sqrt{1^{2} + 100^{2}}=\sqrt{10001}\approx100.005 和 22+02=2\sqrt{2^{2} + 0^{2}}=2。第二个坐标让 aa 看起来远得多,尽管它的第一个坐标更近。重新缩放或标准化特征可以让各坐标的贡献更可比,但该预处理规则必须在训练数据上拟合,并一致地重复使用。

Question 7

对于 x = (1, 1) 和 y = (10, 10),为什么余弦相似度可以是 1,而 L2 距离却不是 0?

Show the step-by-step solution

点积为 1⋅10+1⋅10=201\cdot10+1\cdot10=20。长度为 ∥x∥2=2\lVert x\rVert_2=\sqrt2 和 ∥y∥2=102\lVert y\rVert_2=10\sqrt2,所以余弦相似度为 20/(2⋅102)=120/(\sqrt2\cdot10\sqrt2)=1:两个方向完全一致。距离保留了大小差异。位移为 (−9,−9)(-9,-9),因此 d2(x,y)=81+81=162=92≈12.728d_2(x,y)=\sqrt{81 + 81}=\sqrt{162} =9\sqrt2\approx12.728。这两个度量回答的是不同的相似性问题。

Question 8

在 np.linalg.norm(points − query, ord=2, axis=1) 中,当 points 的形状为 (number_of_points, number_of_features) 时,axis=1 表示什么?

Show the step-by-step solution

points − query 的每一行是一个候选位移,每一列是一个特征坐标。设置 axis=1 告诉 NumPy 沿每行的列进行归约。因此结果是每个候选点一个 L2 值,形状为 (number_of_points,) 。沿错误的轴归约会把候选点混在一起,或者返回每个特征一个值,而不是可用的邻居排序。

资料来源

  1. Mathematics for Machine Learning book PDF, Section 3.3
  2. NumPy documentation: numpy.linalg.norm
  3. scikit-learn documentation: NearestNeighbors
  4. scikit-learn documentation: pairwise metrics, affinities, and kernels
  5. Beyer, Goldstein, Ramakrishnan, and Shaft: When Is Nearest Neighbor Meaningful?