1、欧氏距离(Euclidean Distance)
欧式距离可解释为连接两个点的线段的长度。欧式距离公式非常简单,使用勾股定理从这些点的笛卡尔坐标计算距离。
代码实现:
import numpy as np
x=np.random.random(10)
y=np.random.random(10)
#方法一:根据公式求解
d1=np.sqrt(np.sum(np.square(x-y)))
#方法二:根据scipy库求解
from scipy.spatial.distance import pdist
X=np.vstack([x,y])
d2=pdist(X)
缺点:尽管这是一种常用的距离度量,但欧式距离并不是尺度不变的,这意味着所计算的距离可能会根据特征的单位发生倾斜。通常,在使用欧式距离度量之前,需要对数据进行归一化处理。
此外,随着数据维数的增加,欧氏距离的作用也就越小。这与维数灾难(curse of dimensionality)有关。
用例:当你拥有低维数据且向量的大小非常重要时,欧式距离的效果非常好。如果在低维数据上使用欧式距离,则如 k-NN 和 HDBSCAN 之类的方法可达到开箱即用的效果。
2、余弦相似度(Cosine Similarity)
余弦相似度经常被用作抵消高维欧式距离问题。余弦相似度是指两个向量夹角的余弦。如果将向量归一化为长度均为 1 的向量,则向量的点积也相同。
两个方向完全相同的向量的余弦相似度为 1,而两个彼此相对的向量的余弦相似度为 - 1。注意,它们的大小并不重要,因为这是在方向上的度量。
代码实现:
import numpy as np
def bit_product_sum(x, y):
return sum([item[0] * item[1] for item in zip(x, y)])
def cosine_similarity(x, y, norm=False):
""" 计算两个向量x和y的余弦相似度 """
assert len(x) == len(y), "len(x) != len(y)"
zero_list = [0] * len(x)
if x == zero_list or y == zero_list:
return float(1) if x == y else float(0)
# method 1
res = np.array([[x[i] * y[i], x[i] * x[i], y[i] * y[i]] for i in range(len(x))])
cos = sum(res[:, 0])