向量的模长与余弦相似度
上一章的点积同时包含了长度和方向的信息。
本章把它们拆开:模长单独衡量大小,余弦相似度单独衡量方向一致性。
模长:向量有多长?
模长就是向量从原点到终点的「直线距离」——勾股定理在高维空间的推广。
L1 范数
\( \|\mathbf{v}\|_1 = \sum |v_i| \)
曼哈顿距离:沿街道走
(3,4) 的 L1 = 7
L2 范数(默认)
\( \|\mathbf{v}\|_2 = \sqrt{\sum v_i^2} \)
直线距离:空中飞
(3,4) 的 L2 = 5
未特别说明时,「模长」或 \( \|\mathbf{v}\| \) 默认指 L2 范数。
单位向量:扔掉长度,只留方向
任何非零向量除以自己的模长,得到长度为 1 的 单位向量:
\[ \hat{\mathbf{v}} = \frac{\mathbf{v}}{\|\mathbf{v}\|} \]归一化后向量方向不变,但模长变为 1。
余弦相似度:只看方向,不看大小
余弦相似度 = 把两个向量都归一化为单位向量后,再做点积:
\[ \text{cosine\_sim}(\mathbf{a}, \mathbf{b}) = \frac{\mathbf{a}\cdot\mathbf{b}}{\|\mathbf{a}\|\|\mathbf{b}\|} = \cos\theta \]方向一致
方向垂直
方向相反
余弦相似度只关心方向,不关心长度。
v = (3,4) 和 w = (6,8)(w = 2v),长度差一倍,但余弦相似度 = 1——因为它们方向完全相同。
生活例子
模长:距离的度量
你家到学校直线距离 5 公里(L2 = 5),但沿街道走要绕 7 公里(L1 = 7)。
两种度量方式各有用途,AI 中主要用 L2。
余弦相似度:音乐品味匹配
张三听了 100 首歌,李四听了 10 首歌。用点积的话,张三的分数天然更高。
但用余弦相似度,只看品味方向是否一致——张三(活跃用户)和李四(新用户)也能公平比较。
数学定义
拆解核心公式
\[ \mathbf{a} \cdot \mathbf{b} = \|\mathbf{a}\| \|\mathbf{b}\| \cos\theta \]点积 = 长度乘积 × 方向一致性。反过来可以求出:
\[ \cos\theta = \frac{\mathbf{a} \cdot \mathbf{b}}{\|\mathbf{a}\| \|\mathbf{b}\|} \]Python 动手实践
实例
v_runoob = np.array([3, 4, 0])
w_runoob = np.array([6, 8, 0]) # v 的 2 倍
# 模长
norm_v = np.linalg.norm(v_runoob) # L2 默认
norm_w = np.linalg.norm(w_runoob)
print(f"||v|| = {norm_v:.1f}, ||w|| = {norm_w:.1f}") # 5, 10
# 归一化
unit_v = v_runoob / norm_v
unit_w = w_runoob / norm_w
print("v 归一化:", unit_v) # [0.6, 0.8, 0.]
print("w 归一化:", unit_w) # [0.6, 0.8, 0.] 完全相同!
# 余弦相似度
cos_sim = np.dot(v_runoob, w_runoob) / (norm_v * norm_w)
print(f"余弦相似度 = {cos_sim:.4f}") # 1.0
# 批量计算余弦相似度矩阵
embeddings = np.array([
[0.2, 0.5, 0.1, 0.8, 0.3],
[0.3, 0.6, 0.2, 0.7, 0.4],
[0.9, 0.1, 0.8, 0.1, 0.9],
])
norms = np.linalg.norm(embeddings, axis=1, keepdims=True)
normalized = embeddings / norms
sim_matrix = normalized @ normalized.T
print("\n余弦相似度矩阵:")
print(np.round(sim_matrix, 3))
||v|| = 5.0, ||w|| = 10.0 v 归一化: [0.6 0.8 0. ] w 归一化: [0.6 0.8 0. ] 余弦相似度 = 1.0000 余弦相似度矩阵: [[1. 0.996 0.146] [0.996 1. 0.182] [0.146 0.182 1. ]]
AI 中的应用场景
语义搜索与推荐系统
将查询词和文档分别编码为向量后,用余弦相似度排序——找最相关的文档。Google 的语义搜索、RAG(检索增强生成)中的向量检索都依赖余弦相似度。
相比点积,余弦相似度不受向量模长影响——一篇长文章的向量模长可能很大,但用余弦相似度能公平地与短查询比较方向一致性。
人脸识别:余弦相似度 > 欧氏距离
FaceNet 等面部识别模型将人脸映射为 128 维嵌入向量。两个人脸是否匹配,用余弦相似度判断——它对照明条件、照片亮度(影响向量模长)不敏感。
两张同一个人不同光照下的照片,嵌入向量方向几乎一致(cos ≈ 0.95+),但模长可能差很多。
L2 正则化防止过拟合
损失函数中加入 \( \lambda\|\mathbf{w}\|^2 \)(权重衰减),惩罚权重模长过大。权重模长大意味着模型对某些特征过度信任,泛化能力差。L2 正则化将其拉向原点附近。
Batch Normalization 中的归一化
BN 对每层激活值做归一化:减均值后除以标准差,将数据变为模长稳定的分布。这用到了 L2 范数的概念来控制各层输出的尺度。
