跳转至

# 度量与范数

范数衡量单个向量的大小；度量衡量两个向量之间的距离。本文涵盖 L1、L2 和 L-无穷范数、欧几里得距离和余弦距离，以及为什么为 kNN、聚类和 ML 中的检索选择合适的距离函数至关重要。

- 我们知道向量有模长和方向。但我们如何实际衡量单个向量"有多大"，或者两个向量"有多远"？这就是范数和度量发挥作用的地方。

- 对标量而言，我们知道 10 > 5，因为它们的值对它们进行了量化，但是我们如何量化一个向量？它的范数衡量单个向量的大小。

- 最熟悉的范数是欧几里得范数（L2），它就是我们已知的模长公式：

\[\|\mathbf{v}\|_2 = \sqrt{v_1^2 + v_2^2 + \cdots + v_n^2}\]

- 但还有其他衡量大小的方法。想象你在一个街道呈网格状的城市中。你不能斜穿建筑物，所以你旅程的"长度"是沿着每条街道行走的总街区数。这就是曼哈顿范数（L1）：

\[\|\mathbf{v}\|_1 = |v_1| + |v_2| + \cdots + |v_n|\]

- 或者你可能只关心单个最大的分量，忽略其余部分。这就是最大范数（L-无穷）：

\[\|\mathbf{v}\|_\infty = \max(|v_1|, |v_2|, \ldots, |v_n|)\]

- 这三个都是一般 Lp 范数的特例：

\[\|\mathbf{v}\|_p = (|v_1|^p + |v_2|^p + \cdots + |v_n|^p)^{1/p}\]

- 设置 \(p = 2\) 得到欧几里得，\(p = 1\) 得到曼哈顿，而当 \(p \to \infty\) 时得到最大范数。随着 \(p\) 增大，最大分量贡献越来越大，直到最终只有它重要。

- 每个范数必须遵守三条规则：

  - 非负性：\(\|\mathbf{v}\| \geq 0\)，且 \(\|\mathbf{v}\| = 0\) 仅当 \(\mathbf{v} = \mathbf{0}\)。大小从不为负，只有零向量的大小为零。

  - 缩放性：\(\|c\mathbf{v}\| = |c| \cdot \|\mathbf{v}\|\)。将向量加倍，其大小也加倍。

  - 三角不等式：\(\|\mathbf{u} + \mathbf{v}\| \leq \|\mathbf{u}\| + \|\mathbf{v}\|\)。捷径永远不会比绕远路更长。

- 现在，度量衡量两个向量之间的距离。把它想象成问："这两个点相距多远？"

- 获得度量的最简单方法是使用差值的范数：\(d(\mathbf{u}, \mathbf{v}) = \|\mathbf{u} - \mathbf{v}\|\)。减去两个向量，然后测量剩余部分的大小。

- 使用欧几里得范数，我们得到熟悉的欧几里得距离：

\[d(\mathbf{u}, \mathbf{v}) = \sqrt{(u_1 - v_1)^2 + (u_2 - v_2)^2 + \cdots + (u_n - v_n)^2}\]

- 使用曼哈顿范数得到曼哈顿距离，沿着每个轴的总差异，就像计算两个位置之间的城市街区数。

- 每个度量必须遵守四条规则：

  - 非负性：\(d(\mathbf{u}, \mathbf{v}) \geq 0\)。距离从不为负。

  - 同一性：\(d(\mathbf{u}, \mathbf{v}) = 0\) 当且仅当 \(\mathbf{u} = \mathbf{v}\)。零距离意味着同一点。

  - 对称性：\(d(\mathbf{u}, \mathbf{v}) = d(\mathbf{v}, \mathbf{u})\)。从 A 到 B 的距离与从 B 到 A 的距离相同。

  - 三角不等式：\(d(\mathbf{u}, \mathbf{w}) \leq d(\mathbf{u}, \mathbf{v}) + d(\mathbf{v}, \mathbf{w})\)。直接走永远不会比绕路更长。

- 那么两者之间的关系是什么？范数衡量一个向量，度量衡量两个向量之间的差距。每个范数自然地创建一个度量（通过测量差值），但并非每个度量都来自范数。

- 例如，汉明距离计算两个向量不同的位置数量。它是一个有效的度量，但并非来自任何范数。

- 在 ML 中，选择合适的范数或度量很重要。

- L2 距离在求和前对每个差值平方，因此单个大的差值会主导结果。

- L1 距离对绝对差值求和，平等对待每个差值。与 L2 相比，单个大的差值影响较小。

## 编程练习（使用 CoLab 或 notebook）

1. 计算同一向量的 L1 和 L2 范数。尝试更改值，注意哪个范数对大的分量最敏感，哪个对许多小分量最敏感。然后尝试计算 p 值递增（例如 1、2、5、10、50、100）时的 Lp 范数，观察它如何收敛到 L-无穷值。

       import jax.numpy as jnp

       v = jnp.array([3.0, -4.0, 1.0])

       l1 = jnp.sum(jnp.abs(v))
       l2 = jnp.sqrt(jnp.sum(v ** 2))

       print(f"L1: {l1}, L2: {l2:.2f}")

2. 计算两个向量之间的欧几里得距离和曼哈顿距离。尝试让向量彼此靠近或远离，观察每种距离如何不同地响应。

       import jax.numpy as jnp

       u = jnp.array([1.0, 2.0, 3.0])
       v = jnp.array([4.0, 0.0, 1.0])

       euclidean = jnp.sqrt(jnp.sum((u - v) ** 2))
       manhattan = jnp.sum(jnp.abs(u - v))

       print(f"Euclidean: {euclidean:.2f}, Manhattan: {manhattan}")