向量数据库中,常见的向量搜索方法:余弦相似度、欧几里得距离和曼哈顿距离分别是什么?有什么区别?
·
向量数据库中的常见搜索方法
1. 余弦相似度
定义
衡量两个向量在方向上的相似程度,计算向量夹角的余弦值。
公式
cos(θ) = (A · B) / (||A|| × ||B||)
其中:
- A · B 是向量点积
- ||A|| 是向量 A 的模(长度)
- θ 是两个向量的夹角
特点
- 范围:[-1, 1]
- 1:完全同向(最相似)
- 0:正交(不相关)
- -1:完全相反(最不相似)
- 忽略向量长度,只关注方向
- 对向量缩放不敏感
适用场景
# 文本相似度(词向量、句子嵌入)
# 推荐系统(用户偏好、物品特征)
# 语义搜索
Python 示例
import numpy as np
def cosine_similarity(a, b):
dot_product = np.dot(a, b)
norm_a = np.linalg.norm(a)
norm_b = np.linalg.norm(b)
return dot_product / (norm_a * norm_b)
# 示例
vec1 = np.array([1, 2, 3])
vec2 = np.array([2, 4, 6]) # vec1 的 2 倍
print(cosine_similarity(vec1, vec2)) # 输出: 1.0 (方向相同)
2. 欧几里得距离
定义
衡量两个向量在多维空间中的直线距离(最常用的距离度量)。
公式
d(A, B) = √Σ(ai - bi)²
即:各维度差值的平方和的平方根
特点
- 范围:[0, +∞)
- 0:完全相同
- 越大:差异越大
- 考虑向量长度和方向
- 对向量缩放敏感
适用场景
# 图像相似度(像素特征)
# 地理位置计算
# 聚类算法(K-Means)
Python 示例
import numpy as np
def euclidean_distance(a, b):
return np.sqrt(np.sum((a - b) ** 2))
# 示例
vec1 = np.array([1, 2, 3])
vec2 = np.array([4, 5, 6])
print(euclidean_distance(vec1, vec2)) # 输出: 5.196...
3. 曼哈顿距离
定义
衡量两个向量在多维空间中沿坐标轴方向的距离总和(城市街区距离)。
公式
d(A, B) = Σ|ai - bi|
即:各维度差值的绝对值之和
特点
- 范围:[0, +∞)
- 0:完全相同
- 越大:差异越大
- 计算简单,无需平方和开方
- 对异常值更鲁棒
适用场景
# 高维稀疏数据
# 网格路径规划
# 推荐系统(离散特征)
Python 示例
import numpy as np
def manhattan_distance(a, b):
return np.sum(np.abs(a - b))
# 示例
vec1 = np.array([1, 2, 3])
vec2 = np.array([4, 5, 6])
print(manhattan_distance(vec1, vec2)) # 输出: 9
三种方法的对比
| 特性 | 余弦相似度 | 欧几里得距离 | 曼哈顿距离 |
|---|---|---|---|
| 度量类型 | 相似度(越大越相似) | 距离(越小越相似) | 距离(越小越相似) |
| 取值范围 | [-1, 1] | [0, +∞) | [0, +∞) |
| 是否考虑长度 | ❌ 否 | ✅ 是 | ✅ 是 |
| 计算复杂度 | O(n) | O(n) | O(n) |
| 对缩放敏感 | ❌ 否 | ✅ 是 | ✅ 是 |
| 对异常值敏感 | 中等 | 高 | 低 |
| 几何意义 | 夹角余弦 | 直线距离 | 街区距离 |
几何直观理解
二维空间示例:
B (4, 4)
│
│ ╲
│ ╲ 欧几里得距离 = √(3² + 3²) = 4.24
│ ╲
│ ╲
│_____╲
A (1, 1) C (4, 1)
曼哈顿距离 = |4-1| + |4-1| = 3 + 3 = 6
余弦相似度:
向量 OA = [1, 1], 向量 OB = [4, 4]
cos(θ) = (1×4 + 1×4) / (√2 × √32) = 8 / 8 = 1.0
实际应用选择指南
选择余弦相似度:
✅ 文本相似度(TF-IDF、Word2Vec、BERT)
✅ 推荐系统(用户偏好向量)
✅ 语义搜索
✅ 向量长度不重要的情况
选择欧几里得距离:
✅ 图像相似度
✅ 地理位置计算
✅ 聚类分析
✅ 向量长度重要的情况
选择曼哈顿距离:
✅ 高维稀疏数据
✅ 离散特征
✅ 需要快速计算的场景
✅ 对异常值敏感的场景
向量数据库中的实际使用
# Milvus 向量数据库示例
from pymilvus import Collection, FieldSchema, CollectionSchema, DataType
# 定义索引时指定距离类型
index_params = {
"metric_type": "COSINE", # 或 "L2" (欧几里得), "IP" (内积)
"index_type": "HNSW",
"params": {"M": 16, "efConstruction": 256}
}
# 搜索时使用相同的距离类型
results = collection.search(
data=[query_vector],
anns_field="embedding",
param={"metric_type": "COSINE", "params": {"ef": 64}},
limit=10
)
关键要点
- 余弦相似度:关注方向,适合文本和推荐
- 欧几里得距离:关注绝对距离,适合图像和聚类
- 曼哈顿距离:计算简单,适合高维稀疏数据
- 选择依据:根据数据特性和业务需求选择合适的度量方式
- 一致性:索引和搜索必须使用相同的距离度量
更多推荐
所有评论(0)