距离度量与其简单实现

欧几里得距离

在数学中,欧几里得距离或欧几里得度量是欧几里得空间中两点间“普通”(即直线)距离。使用这个距离,欧氏空间成为度量空间。相关联的范数称为欧几里得范数。较早的文献称之为毕达哥拉斯度量。

def euclid(x, y):
    """
    欧几里得距离
    :param x:
    :param y:
    :return:
    """
    return np.linalg.norm(x - y)

计算方式的局限。

比如说计算两个点的距离,点A(10,10000)、点B(1,500),第二个维度对于距离d的贡献是远远超过第一个维度的。在这里我们只是向量中的各个因素分别进行了处理,并没有考虑维度之间的相互关系,以及不同维度对于距离d的贡献程度。另外一点局限是,从距离角度来看,它认为两点之间,始终是可以通过直线距离到达的(更适用于欧氏空间)。

这是非常重要的一个基础,以后的几种距离都会与欧氏距离进行对比。

曼哈顿距离

计程车几何(Taxicab geometry)或曼哈顿距离(Manhattan distance or Manhattan length)或方格线距离是由十九世纪的赫尔曼·闵可夫斯基所创辞汇,为欧几里得几何度量空间的几何学之用语,用以标明两个点上在标准坐标系上的绝对轴距之总和。

def manhattan(x, y):
    """
    曼哈顿距离
    :param x:
    :param y:
    :return:
    """
    return np.sum(np.abs(x-y))

切比雪夫距离

国际象棋玩过么?国王走一步能够移动到相邻的8个方格中的任意一个。那么国王从格子(x1,y1)走到格子(x2,y2)最少需要多少步?自己走走试试。你会发现最少步数总是max( | x2-x1 | , | y2-y1 | ) 步 。有一种类似的一种距离度量方法叫切比雪夫距离。

闵可夫斯基距离

明氏距离又叫做明可夫斯基距离,是欧氏空间中的一种测度,被看做是欧氏距离和曼哈顿距离的一种推广。

其中p是一个变参数。

  • 当p=1时,就是曼哈顿距离
  • 当p=2时,就是欧氏距离
  • 当p→∞时,就是切比雪夫距离
    根据变参数的不同,闵氏距离可以表示一类的距离。
    (2)闵氏距离的缺点
      闵氏距离,包括曼哈顿距离、欧氏距离和切比雪夫距离都存在明显的缺点。
      举个例子:二维样本(身高,体重),其中身高范围是150~190,体重范围是50~60,有三个样本:a(180,50),b(190,50),c(180,60)。那么a与b之间的闵氏距离(无论是曼哈顿距离、欧氏距离或切比雪夫距离)等于a与c之间的闵氏距离,但是身高的10cm真的等价于体重的10kg么?因此用闵氏距离来衡量这些样本间的相似度很有问题。简单说来,闵氏距离的缺点主要有两个:(1)将各个分量的量纲(scale),也就是“单位”当作相同的看待了。(2)没有考虑各个分量的分布(期望,方差等)可能是不同的。
def minkowski(x, y, p):
    """
    闵式距离
    :param x:
    :param y:
    :param p:
    :return:
    """
    return np.linalg.norm(x - y, ord=p)

标准化欧氏距离 (Standardized Euclidean distance )

(1)标准欧氏距离的定义
  标准化欧氏距离是针对简单欧氏距离的缺点而作的一种改进方案。标准欧氏距离的思路:既然数据各维分量的分布不一样,好吧!那我先将各个分量都“标准化”到均值、方差相等吧。均值和方差标准化到多少呢?这里先复习点统计学知识吧,假设样本集X的均值(mean)为m,标准差(standard deviation)为s,那么X的“标准化变量”表示为:

def std_euclid(x, y):
    """
    标准化的欧氏距离
    :param x:
    :param y:
    :return:
    """
    std=np.vstack([x,y])
    return np.sqrt(((x-y)**2/np.var(std)).sum())

余弦距离

def cos_dis(x, y):
    """
    余弦相似度
    :param x:
    :param y:
    :return:
    """
    return np.dot(x, y)/(np.linalg.norm(x)*np.linalg.norm(y))

你可能感兴趣的:(距离度量与其简单实现)