Skip to content

度量与范数

范数衡量单个向量的大小;度量衡量两个向量之间的距离。本章涵盖 L1、L2 和 L-无穷范数、欧几里得距离与余弦距离,以及为什么在机器学习中的 kNN、聚类和检索任务中选择合适的距离函数至关重要。

  • 我们知道向量有大小和方向。但如何实际测量“单个向量有多大”,或者“两个向量相距多远”?这正是范数度量发挥作用的地方。

  • 对于标量,我们知道 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} = \mathbf{0}\)\(\|\mathbf{v}\| = 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})\)。直接走永远不会比绕道更长。

  • 那么两者之间的关系是什么?范数衡量一个向量,度量衡量两个向量之间的间隙。每个范数自然产生一个度量(通过测量差值),但并非每个度量都来自一个范数。

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

  • 在机器学习中,选择合适的范数或度量很重要。

  • 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:.2f}, 曼哈顿距离: {manhattan}")