【机器学习】(5.1)聚类--距离度量

前提

在机器学习和数据挖掘中,我们经常需要知道个体间差异的大小,进而评价个体的相似性和类别。最常见的是数据分析中的相关分析,数据挖掘中的分类和聚类算法,如 K 最近邻(KNN)和 K 均值(K-Means)等等。根据数据特性的不同,可以采用不同的度量方法。一般而言,定义一个距离函数 d(x,y), 需要满足下面几个准则

1) d(x,x) = 0                    // 到自己的距离为0
2) d(x,y) >= 0                  // 距离非负
3) d(x,y) = d(y,x)                   // 对称性: 如果 A 到 B 距离是 a,那么 B 到 A 的距离也应该是 a
4) d(x,k)+ d(k,y) >= d(x,y)    // 三角形法则: (两边之和大于第三边)

闵可夫斯基距离(Minkowski distance)

闵可夫斯基距离(Minkowski distance)是衡量数值点之间距离的一种非常常见的方法,假设数值点 P 和 Q 坐标如下:

那么,闵可夫斯基距离定义为:

该距离最常用的 p 是 2 和 1, 前者是欧几里得距离(Euclidean distance),后者是曼哈顿距离(Manhattan distance)。假设在曼哈顿街区乘坐出租车从 P 点到 Q 点,白色表示高楼大厦,灰色表示街道:

绿色的斜线表示欧几里得距离,在现实中是不可能的。其他三条折线表示了曼哈顿距离,这三条折线的长度是相等的。

当 p 趋近于无穷大时,闵可夫斯基距离转化成切比雪夫距离(Chebyshev distance):

我们知道平面上到原点欧几里得距离(p = 2)为 1 的点所组成的形状是一个圆,当 p 取其他数值的时候呢?

注意,当 p < 1 时,闵可夫斯基距离不再符合三角形法则,举个例子:当 p < 1, (0,0) 到 (1,1) 的距离等于 (1+1)^{1/p} > 2, 而 (0,1) 到这两个点的距离都是 1。

闵可夫斯基距离比较直观,但是它与数据的分布无关,具有一定的局限性,如果 x 方向的幅值远远大于 y 方向的值,这个距离公式就会过度放大 x 维度的作用。所以,在计算距离之前,我们可能还需要对数据进行 z-transform 处理,即减去均值,除以标准差:

 : 该维度上的均值
 : 该维度上的标准差

之前做归一化处理我一直不是很明白,然后我用了公式的变种,才有了一点具象概念:

从公式中可以看出,归一化相当于数据距离平均数占真个波动范围的比例。变相将同时放大的系数约去了,起到了归一化的作用,但是这是无量纲,也是无相关。

可以看到,上述处理开始体现数据的统计特性了。这种方法在假设数据各个维度不相关的情况下利用数据分布的特性计算出不同的距离。如果维度相互之间数据相关(例如:身高较高的信息很有可能会带来体重较重的信息,因为两者是有关联的),这时候就要用到马氏距离(Mahalanobis distance)了。

海明距离

海明距离是序列相同位置上数据不同的个数,比如abc和acb,海明距离是第二位和第三位不同,海明距离是2。

Jaccard距离

 

该距离可以作为深度学习分割算法的损失函数;可以用来度量深度学习检测框之间的相似度(在检测中叫做IOU)。

同时可以为某个集合例如A中的某些类别的数据指定一个权重,也就是不同类别的数据他的重要程度不同。

余弦距离

余弦距离,也称为余弦相似度,是用向量空间中两个向量夹角的余弦值作为衡量两个个体间差异的大小的度量。

向量,是多维空间中有方向的线段,如果两个向量的方向一致,即夹角接近零,那么这两个向量就相近。而要确定两个向量方向是否一致,这就要用到余弦定理计算向量的夹角。

余弦定理描述了三角形中任何一个夹角和三个边的关系。给定三角形的三条边,可以使用余弦定理求出三角形各个角的角度。假定三角形的三条边为a,b和c,对应的三个角为A,B和C,那么角A的余弦为:

如果将三角形的两边b和c看成是两个向量,则上述公式等价于:

其中分母表示两个向量b和c的长度,分子表示两个向量的内积。

举一个具体的例子,假如新闻X和新闻Y对应向量分别是:

x1, x2, ..., x6400和

y1, y2, ..., y6400

注意这两条向量从长度上看是相同的,那么这两条新闻X和Y的字符长度可以相同也可以不同。相同好理解就是内容一模一样。

但是在实际情况中我们经常碰到句子不一样长,那么此时可以构建一个词典,例如词典[你,好,我,开,明。。。]一个特别大的列表,每一个字都有对应的位置,为了符合上述例子,这里词表的长度是6400(实际根据你自身情况来),那么新闻X的向量可以这么表示:构建一个6400全0向量,然后依次遍历新闻中的字,出现某个字就在刚刚6400的向量上+1,此时将新闻X映射成了一个6400的向量。新闻Y处理方式一样,那么就能得到2个6400的向量,就可以比较余弦距离了。

则,它们之间的余弦距离可以用它们之间夹角的余弦值来表示:

当两条新闻向量夹角余弦等于1时,这两条新闻完全重复(用这个办法可以删除爬虫所收集网页中的重复网页);当夹角的余弦值接近于1时,两条新闻相似(可以用作文本分类);夹角的余弦越小,两条新闻越不相关。

Pearson相似系数 

X和Y为随机变量。

分子:协方差表示X和Y的相关性,如果为正值则表示正相关,负值表示负相关,0表示两者没啥关系即两者独立。

分母:X和Y的方差,表示了数据离均值的偏差程度。

该相似系数是度量两个变量是否正相关(正值),负相关(负值)还是独立的(0)。

还没有想到好的例子和使用场景(随机变量时候可以使用),后续了解了再来补充。

补充说明

相对熵KL距离

例子:

X和Y是2个随机变量,A表示他们的公有值。然后使用频率代替概率,就能得到KL距离。

注意:该距离违反了准则(3),也就是距离是非对称的,

Hellinger距离(不太懂)

马氏距离

考虑下面这张图,椭圆表示等高线,从欧几里得的距离来算,绿黑距离大于红黑距离,但是从马氏距离,结果恰好相反:

马氏距离实际上是利用 Cholesky transformation 来消除不同维度之间的相关性和尺度不同的性质。假设样本点(列向量)之间的协方差对称矩阵是 , 通过 Cholesky Decomposition(实际上是对称矩阵 LU 分解的一种特殊形式)可以转化为下三角矩阵和上三角矩阵的乘积: ,消除不同维度之间的相关性和尺度不同,只需要对样本点 x 做如下处理:处理之后的欧几里得距离就是原样本的马氏距离:为了书写方便,这里求马氏距离的平方): 

下图蓝色表示原样本点的分布,两颗红星坐标分别是(3, 3),(2, -2):

由于 x, y 方向的尺度不同,不能单纯用欧几里得的方法测量它们到原点的距离。并且,由于 x 和 y 是相关的(大致可以看出斜向右上),也不能简单地在 x 和 y 方向上分别减去均值,除以标准差。最恰当的方法是对原始数据进行 Cholesky 变换,即求马氏距离(可以看到,右边的红星离原点较近):

将上面两个图的绘制代码和求马氏距离的代码贴在这里,以备以后查阅:

# -*- coding=utf-8 -*-

# code related at: http://www.cnblogs.com/daniel-D/

import numpy as np
import pylab as pl
import scipy.spatial.distance as dist


def plotSamples(x, y, z=None):

    stars = np.matrix([[3., -2., 0.], [3., 2., 0.]])
    if z is not None:
        x, y = z * np.matrix([x, y])
        stars = z * stars

    pl.scatter(x, y, s=10)    # 画 gaussian 随机点
    pl.scatter(np.array(stars[0]), np.array(stars[1]), s=200, marker='*', color='r')  # 画三个指定点
    pl.axhline(linewidth=2, color='g') # 画 x 轴
    pl.axvline(linewidth=2, color='g')  # 画 y 轴

    pl.axis('equal')
    pl.axis([-5, 5, -5, 5])
    pl.show()


# 产生高斯分布的随机点
mean = [0, 0]      # 平均值
cov = [[2, 1], [1, 2]]   # 协方差
x, y = np.random.multivariate_normal(mean, cov, 1000).T
plotSamples(x, y)

covMat = np.matrix(np.cov(x, y))    # 求 x 与 y 的协方差矩阵
Z = np.linalg.cholesky(covMat).I  # 仿射矩阵
plotSamples(x, y, Z)

# 求马氏距离 
print '\n到原点的马氏距离分别是:'
print dist.mahalanobis([0,0], [3,3], covMat.I), dist.mahalanobis([0,0], [-2,2], covMat.I)

# 求变换后的欧几里得距离
dots = (Z * np.matrix([[3, -2, 0], [3, 2, 0]])).T
print '\n变换后到原点的欧几里得距离分别是:'
print dist.minkowski([0, 0], np.array(dots[0]), 2), dist.minkowski([0, 0], np.array(dots[1]), 2)

马氏距离的变换和 PCA 分解的白化处理颇有异曲同工之妙,不同之处在于:就二维来看,PCA 是将数据主成分旋转到 x 轴(正交矩阵的酉变换),再在尺度上缩放(对角矩阵),实现尺度相同。而马氏距离的 L逆矩阵是一个下三角,先在 x 和 y 方向进行缩放,再在 y 方向进行错切(想象矩形变平行四边形),总体来说是一个没有旋转的仿射变换。 

参考

漫谈:机器学习中距离和相似性度量方法 - daniel-D - 博客园

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值