📐 1. 定义

给定两个非零向量 a 和 b ∈ ℝⁿ,余弦相似度定义为它们夹角的余弦值:

cosine_similarity(a,b)=a⋅b∥a∥2 ∥b∥2=∑i=1naibi∑ai2⋅∑bi2 \text{cosine\_similarity}(\mathbf{a}, \mathbf{b}) = \frac{\mathbf{a} \cdot \mathbf{b}}{\|\mathbf{a}\|_2 \, \|\mathbf{b}\|_2} = \frac{\sum_{i=1}^n a_i b_i}{\sqrt{\sum a_i^2} \cdot \sqrt{\sum b_i^2}} cosine_similarity(a,b)=∥a∥2​∥b∥2​a⋅b​=∑ai2​​⋅∑bi2​​∑i=1n​ai​bi​​

  • 取值范围:[-1, 1]
    • 1:完全同向(最相似)
    • 0:正交(无关)
    • -1:完全反向(最不相似)

🔔 实际中,若向量为非负(如图像特征、词频),则范围退化为 [0, 1]。


↔️ 2. 余弦距离(Cosine Distance)

为适配“距离越小越相似”的惯例,常将其转换为余弦距离:

cosine_distance(a,b)=1−cosine_similarity(a,b) \text{cosine\_distance}(\mathbf{a}, \mathbf{b}) = 1 - \text{cosine\_similarity}(\mathbf{a}, \mathbf{b}) cosine_distance(a,b)=1−cosine_similarity(a,b)

  • 取值范围:[0, 2](非负向量时为 [0, 1])
  • 满足非负性、对称性,但 不满足三角不等式 → 不是严格度量(non-metric),不能用于某些要求度量公理的算法(如某些层次聚类)。

🧭 3. 几何意义(关键!)

✅ 余弦相似度只关注方向,忽略幅值(模长)。

向量对欧氏距离余弦相似度说明
(1, 0), (100, 0)991.0幅值差大,但同方向 → 余弦认为完全相似
(1, 0), (0, 1)√2 ≈ 1.410.0正交 → 不相关
(1, 1), (-1, -1)2√2 ≈ 2.83-1.0完全反向

👉 这一特性使其天然适配归一化特征(如 L2 归一化的深度学习特征)。


🧪 4. 何时使用余弦相似度?✅(结合你的背景)

场景为什么适合余弦?
深度学习视觉特征
(如 DINOv2, CLIP, NetVLAD)
特征通常 L2 归一化,此时:
cosine_sim=a⊤b,L2_dist2=2(1−cosine_sim)\text{cosine\_sim} = \mathbf{a}^\top \mathbf{b},\quad \text{L2\_dist}^2 = 2(1 - \text{cosine\_sim})cosine_sim=a⊤b,L2_dist2=2(1−cosine_sim)
→ 余弦与 L2 等价,但计算更快(无需开方)
Place Recognition / VPR
(视觉定位、回环检测)
环境光照/曝光变化导致特征幅值不稳定,方向更鲁棒
文本/词袋模型(TF-IDF)文档长度差异大,余弦消除长度影响,专注词分布方向
SLAM 中的全局描述子匹配如使用 SuperPoint + SuperGlue,其 descriptor 常归一化,余弦匹配更稳定

✅ 在 FAISS、Annoy 等近似最近邻库中,IndexFlatIP(内积)常配合 L2 归一化实现高效余弦搜索。


⚠️ 5. 何时避免使用?

场景问题
原始像素/未归一化特征幅值含重要信息(如亮度),忽略它会丢失判别性
需要严格度量的空间如构建度量树(Ball Tree)、某些聚类算法要求三角不等式
二进制描述子(ORB/BRIEF)汉明距离更合理;余弦对二进制向量退化为相关性,效果差且慢

🛠️ 6. 代码示例(Python)

import numpy as np
from sklearn.metrics.pairwise import cosine_similarity

a = np.array([1, 2, 3])
b = np.array([4, 5, 6])

# 手动计算
cos_sim = np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))
cos_dist = 1 - cos_sim

print(f"余弦相似度: {cos_sim:.4f}")   # → 0.9746
print(f"余弦距离:   {cos_dist:.4f}")   # → 0.0254

# sklearn(支持批量)
sim_matrix = cosine_similarity([a, b])

🔍 加速技巧:若所有向量已 L2 归一化(x /= np.linalg.norm(x)),则 cosine_similarity = a @ b.T(纯矩阵乘),可用 BLAS/GPU 加速。


📊 7. 与其他距离对比(归一化后)

距离公式(a,b L2 归一化)计算量适用性
L2 距离2(1−cos⁡θ)\sqrt{2(1 - \cos\theta)}2(1−cosθ)​高(开方)通用
余弦距离1−cos⁡θ1 - \cos\theta1−cosθ低(仅内积)✅ 归一化特征首选
汉明距离∣a−b∣1|a - b|_1∣a−b∣1​(二进制)极低二进制描述子

✅ 总结一句话:

余弦相似度衡量“方向一致性”,是处理归一化高维特征(尤其是深度学习特征)的黄金标准——快、鲁棒、与人类直觉一致。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐