马氏距离与异常点检测

定义

马氏距离的定义相关资料太多了,我这里直接截图维基百科上的定义。
798143-20170502104346086-234931243.png

特点

马氏距离具有以下特点:

  • 马氏距离不受量纲的影响,两点之间的马氏距离与原始数据的测量单位无关,即独立于测量尺度。采用数据预处理中的标准化和中心化等方法所获得的马氏距离相同;
  • 马氏距离具有放大变化微小的变量的作用,这对于化学指纹图谱的分析而言是有利的特点;
  • 马氏距离在计算中考虑了各自变量之间的线性相关关系,因此可以排除变量之间相关性的干扰;
  • 马氏距离可用于鉴别离群值。一个马氏距离较大的样本必然是一个离群值;
  • 应用马氏距离的前提是各自变量均应符合正态分布。

马氏距离与欧氏距离的主要区别点在于:

  • 欧氏距离有量纲,将各自变量的差别同等对待;马氏距离无量纲;
  • 欧氏距离不考虑变量间的相关性,马氏距离根据协方差矩阵消除了相关性;
  • 如果协方差矩阵为单位矩阵,则马氏距离就简化为欧氏距离;

意义

上面的内容,很多博客也总结过了。其实看完后对马氏距离并没有一个很直观的认识。这里总结一下马氏距离的意义和解释为什么马氏距离比欧式距离更好的检测异常点。这里的内容主要总结自如何理解马氏距离,多维Mahalanobis距离是否要用到“互相关张量”来进行描述?

欧式距离是定义在两个点之间,维度的多少,不会使得欧式距离更复杂。欧氏距离认为多维空间是各向相同的,往哪个方向走,意义都一样。

马氏距离认为各向是异向的。而各向异性的具体参数,由一个协方差矩阵表示。可以把直观协方差矩阵当成一个多维正太分布的协方差阵,那么这个分布的密度函数的等高线,就是等高线常见的椭圆。从椭圆中心到椭圆上各个方向的点的马氏距离,都是相等的。

其中,椭圆的各个轴的方向,是协方差矩阵的特征向量。各个轴的长度正比于协方差矩阵的特征值的平方根。

下面用一个图来说明一下。

798143-20170502110301476-1216926607.png

左下角在二维空间中由一个分布产生的方块样本,这个分布的一条等高线如虚线的椭圆框所示,图中还有一个不属于该分布的圆圈样本。这是是一个典型的欧式距离会把分布外样本算的更近的例子,比如把绿色和蓝色样本单拎出来,就是左上角的图,蓝色小圆圈和中心的绿色方块更近了,这是因为单纯的欧式距离无法反应方块的分布。这种情况下,考虑用马氏距离。这里默认方块的分布可以由协方差矩阵很好描述。这样计算出的距离就像说的一样不再是各向同性,对于方块的分布而言有个良好性质是分布的等高线上到中心的马氏距离相等了,因为马氏距离包含了方块本身分布的信息。

进一步来理解,马氏距离可以表示为下面这样:

798143-20170502110726929-949260115.png

其实等效于做了个线性变换,然后在变换后的空间中求了下欧式距离。

转载于:https://www.cnblogs.com/-Sai-/p/6795156.html

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
马氏距离是一种用于测量向量之间的相似度的统计方法。它是基于权重的欧几里得距离,考虑了数据的协方差矩阵。在异常值检测中,使用马式距离可以将未知样本与已知样本的距离进行标准化,从而判断未知样本是否为异常值。 Python中,可以使用scipy库中的mahalanobis()函数来计算马式距离。该函数需要提供两个numpy数组x和y,分别表示未知样本和已知样本。 具体操作流程如下: 1. 假设我们有一个含有N个样本的数据集,每个样本包含M个特征值(即M维向量),可以将这个数据集表示为一个NxM的numpy数组X。 2. 我们需要计算X中每个样本与其他样本的马式距离,并将其存储在一个N×N的距离矩阵D中。 3. 对于每个样本,我们将其与其他样本的距离进行排序,取出其中前k个距离。这里的k是一个自定义的参数,可以根据实际情况进行调整。 4. 接下来,我们需要计算每个样本的马式距离得分(即异常值分数)。可以将前k个距离的平均值作为该样本的得分,得分越高表示越有可能是异常值。 5. 最后,我们可以根据设定的阈值来判断哪些样本为异常值。一般情况下,可以将得分高于某一阈值的样本判定为异常值。 在Python中,可以使用以下代码进行异常值检测: 1. 导入必要的库和数据集 import numpy as np from scipy.spatial.distance import mahalanobis from sklearn.datasets import load_iris # 加载鸢尾花数据集 iris = load_iris() X = iris.data 2. 计算距离矩阵 # 计算距离矩阵D D = np.zeros((X.shape[0], X.shape[0])) for i in range(X.shape[0]): for j in range(X.shape[0]): D[i,j] = mahalanobis(X[i], X[j], np.linalg.inv(np.cov(X.T))) 3. 计算得分 # 计算每个样本的得分 k = 10 # 取前10个距离 scores = np.zeros(X.shape[0]) for i in range(X.shape[0]): distances = sorted(D[i,:])[:k] scores[i] = np.mean(distances) 4. 判定异常值 # 判断哪些样本为异常值 threshold = 2.5 # 设定阈值为2.5 outliers = np.where(scores > threshold)[0] print(outliers) # 输出异常值的下标
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值