在很多领域需要进行向量相似度的计算。本篇文章主要介绍一些常见的方法:
- 曼哈顿距离
- 欧几里得距离
- 切比雪夫距离
- 闵可夫斯基距离
- 标准欧式距离
- 余弦相似度
- 点积相似度
1. 曼哈顿距离
曼哈顿距离指的是两个向量在各个维度上的距离相加。
- x、y 表示待计算的两个向量
- N 表示向量的维度
def manhattan_distance(x, y): distance = 0.0 for v1, v2 in zip(x, y): distance += abs(v1 - v2) return distance if __name__ == '__main__': x = [3, 5] y = [4, 9] print('distance:', manhattan_distance(x, y))
2. 欧几里得距离
欧几里得度量(欧氏距离)是经常使用的距离方法,在二维和三维空间中的欧氏距离就是两点之间的实际距离。
- x、y 表示待计算的两个向量
- N 表示向量的维度
import math def euclidean_distance(x, y): distance = 0.0 for v1, v2 in zip(x, y): distance += math.pow(v1 - v2, 2) return math.sqrt(distance) if __name__ == '__main__': x = [3, 5] y = [4, 9] print('distance:', euclidean_distance(x, y))
3. 切比雪夫距离
切比雪夫距离是两个向量的各维度数值差绝对值的最大值。
import math def chebyshev_distance(x, y): max_distance = 0.0 for v1, v2 in zip(x, y): if abs(v1 - v2) > max_distance: max_distance = abs(v1 - v2) return max_distance if __name__ == '__main__': x = [3, 5, 9] y = [4, 9, 1] print('distance:', chebyshev_distance(x, y))
4. 闵可夫斯基距离
闵式距离其公式如下:
其中 p 是一个常数:
当 p = 1, 该公式为曼哈顿距离计算公式
当 p = 2, 该公式为欧式距离计算公式
当 p = ∞, 该公式为切比雪夫距离
5. 标准化欧氏距离
标准化欧氏距离是针对欧氏距离的缺点而作的一种改进,它将各个分量都标准化到均值、方差相等。
- σ 表示各个维度的标准差
- N 表示维度的个数
6. 余弦相似度
- ||x||、||y|| 表示向量的模
- x·y 表示两个向量的点乘
- 余弦相似度取值范围为 [-1,1],值越大说明两个向量的夹角越小,两个向量越相似
import numpy as np def cosine_similarity(x, y): x = np.array(x) y = np.array(y) a = x @ y b = np.sqrt(x @ x) * np.sqrt(y @ y) return a / b if __name__ == '__main__': x = [0, 1] y = [0, 2] print('distance:', cosine_similarity(x, y)) x = [0, 1] y = [0, 5] print('distance:', cosine_similarity(x, y)) x = [0, 1] y = [0, -1] print('distance:', cosine_similarity(x, y)) x = [0, 1] y = [0, -5] print('distance:', cosine_similarity(x, y))
输出结果:
distance: 1.0 distance: 1.0 distance: -1.0 distance: -1.0
通过程序发现,余弦相似度只和两个向量的夹角有关,和两个向量的模大小无关。
7. 点积相似度
- ||x|| 表示向量的模
- θ 表示两个向量的夹角
- 点积相似度公式中,向量夹角和模的长度都会影响到相似程度
- 相对于余弦相似度,点积相似度需要更少的计算量
- 点积值越大,则说明两个向量越相似
- 关于点积的有一种直接理解为: 点积考虑了两个向量的夹角、和一个向量在另外一个向量的投影