看了很多关于马氏距离(Mahalanobis Distance)的介绍,但是总感觉有一些地方不太清晰,所以结合数学公式、机器学习中的应用案例,从头梳理一下。

马氏距离实际上是欧氏距离在多变量下的“加强版”,用于测量点(向量)与分布之间的距离。

在具体介绍马氏距离之前,首先需要了解下协方差的概念、欧式距离的概念。

什么情况下适用马氏距离?

当需要度量点(向量)与多变量分布之间的距离时,如果直接采用欧式距离,衡量的是两点之间的直接距离(点与分布之间的欧式距离,指的是向量x与变量空间中心的距离),而没有考虑数据的分布特性。

而采用马氏距离,在计算中对协方差进行归一化,则可以规避欧式距离对于数据特征方差不同的风险,从而使所谓的“距离”更加符合数据分布特征以及实际意义。1

什么是多变量分布(Multivariate Distributions)呢?
我们知道,当一个分布中随机变量的个数超过两个的时候,我们称之为多变量分布。与单个随机变量相比,多变量分布在实际应用中应用更广。
以二维随机变量为例:若对Ω中的每一个样本点ω都有一对有序实数(X(ω),Y(ω))与其对应,则称(X,Y)为二维随机变量或二维随机向量,称(X,Y)的取值范围为它的值域,记为Ω(X,Y)。
设(X,Y)为二维随机变量,对任意的(x,y)∈R2,称F(x,y)=P(X≤x,Y≤y)为随机变量(X,Y)的分布函数2

下面举一个具体例子,说明欧式距离在多变量距离度量方面的局限性。

当我们想要对多变量数据使用欧式距离,可能会遇到一个常见的问题:如果多变量(比如数据集中的列)之间相互关联(这在实际数据集中通常是这种情况),则点与点中心(分布)之间的欧几里得距离会具有误导性,无法真实反映一个点与分布之间的实际距离。3

如下图所示,这是是两个变量的简单散点图。左图是两个变量之间不相关,Point 1和Point 2与分布中心的距离相等。右图是两个变量之间呈正相关。即随着一个变量(x轴)的值增加,另一变量(y轴)的值也增加。

从几何上说,Point 1和Point 2两个点与分布中心的距离相等(欧几里得距离)。但是,即两点到分布的欧几里得距离相等,但实际上只有Point 1(蓝色)更接近该分布。

这是因为,欧几里得距离仅是两点之间的距离,它不考虑数据集中的其余点的分布情况。因此,它不能用来真正判断一个点实际上与点的分布有多接近。所以我们需要的是更健壮的距离度量标准,该度量标准可以精确地表示一个点与分布之间的距离。

马氏距离(Mahalanobis Distance)

马氏距离实际上是欧氏距离在多变量下的“加强版”,用于测量点(向量)与分布之间的距离。

计算公式

向量x\bold{x}x到一个均值为μ\muμ,协方差为SSS的样本分布的马氏距离计算如下:
dmahal=(x−μ)S−1(x−μ)′d_{mahal} = \sqrt{(\bold{x}-\bold{\mu})\bold{S^{-1}}(\bold{x}-\bold{\mu})'} dmahal​=(x−μ)S−1(x−μ)′​

直观解释

(x−μ)(\bold{x}-\bold{\mu})(x−μ)本质上是向量与平均值的距离。然后,将其除以协方差矩阵(或乘以协方差矩阵的逆数)。

这实际上是多元变量的常规标准化(z =(x – mu)/ sigma)。也就是说,z =(x向量)–(平均向量)/(协方差矩阵)。

如果数据集中的变量高度相关,则协方差将很高。除以较大的协方差将有效缩短距离。

同样,如果X不相关,则协方差也不高,距离也不会减少太多。

因此,它有效地解决了规模问题以及前文中谈到的变量之间的相关性。

马氏距离与欧式距离的区别

从计算上来说:马氏距离与欧几里得距离相比,有以下不同步骤:

  • 首先将列转换为不相关的变量
  • 缩放列以使其方差等于1
  • 最后,计算出加强版欧几里得距离。

如果协方差矩阵为单位矩阵,即样本向量之间独立同分布,就得到欧式距离:
dEuclidean=(x−μ)(x−μ)′d_{Euclidean} = \sqrt{(\bold{x}-\bold{\mu})(\bold{x}-\bold{\mu})'} dEuclidean​=(x−μ)(x−μ)′​

马氏距离可以排除变量之间的相关性的干扰。但是在计算马氏距离过程中,要求总体样本数大于样本的维数,否则样本协方差矩阵的逆矩阵不存在。4

代码实现:

直接利用公式计算:

def mahalanobis(x=None, data=None, cov=None):"""Compute the Mahalanobis Distance between each row of x and the data  x    : vector or matrix of data with, say, p columns.data : ndarray of the distribution from which Mahalanobis distance of each observation of x is to be computed.cov  : covariance matrix (p x p) of the distribution. If None, will be computed from data."""x_minus_mu = x - np.mean(data)if not cov:cov = np.cov(data.values.T)inv_covmat = np.linalg.inv(cov)left_term = np.dot(x_minus_mu, inv_covmat)mahal = np.dot(left_term, x_minus_mu.T)return mahal.diagonal()

或者调用scipy中的scipy.spatial.distance.mahalanobis(u, v, iv)5,其中u、v都是大小为(N,)的一维向量,iv是协方差矩阵的逆。

from scipy.spatial import distance
iv = [[1, 0.5, 0.5], [0.5, 1, 0.5], [0.5, 0.5, 1]]
distance.mahalanobis([1, 0, 0], [0, 1, 0], iv)
#[out]:1.0
distance.mahalanobis([0, 2, 0], [0, 1, 0], iv)
#[out]:1.0
distance.mahalanobis([2, 0, 0], [0, 1, 0], iv)
#[out]:1.7320508075688772

马氏距离详细教程可以参考:
https://download.csdn.net/download/Bit_Coders/16757248

应用举例

它在多变量异常检测,高度不平衡的数据集分类和一类分类以及更多未开发的用例方面具有出色的应用。3

下面以一个数据集为例,看下如何应用马氏距离进行多变量异常检测(Multivariate outlier detection)。

import pandas as pd
import scipy as sp
import numpy as npfilepath = 'https://raw.githubusercontent.com/selva86/datasets/master/diamonds.csv'
df = pd.read_csv(filepath)
df.head()

数据集每行是一个样本,每列代表不同的变量:

计算数据集中的样本点距离整体分布的马氏距离:

def mahalanobis(x=None, data=None, cov=None):"""Compute the Mahalanobis Distance between each row of x and the data  x    : vector or matrix of data with, say, p columns.data : ndarray of the distribution from which Mahalanobis distance of each observation of x is to be computed.cov  : covariance matrix (p x p) of the distribution. If None, will be computed from data."""x_minus_mu = x - np.mean(data)if not cov:cov = np.cov(data.values.T)inv_covmat = sp.linalg.inv(cov)left_term = np.dot(x_minus_mu, inv_covmat)mahal = np.dot(left_term, x_minus_mu.T)return mahal.diagonal()df = df.iloc[:, [0,4,6]] # 选取类型为数值的三列
df_x = df[['carat', 'depth', 'price']].head(500)
df_x['mahala'] = mahalanobis(x=df_x, data=df[['carat', 'depth', 'price']])
df_x.head()


假设统计量服从卡方分布,则在0.01显著性水平和2自由度下的临界值计算如下(scipy.stat.chi2的文档见6):

# Critical values for two degrees of freedom
from scipy.stats import chi2
chi2.ppf((1-0.01), df=2) # 百分比点函数
#> 9.21

如果观测值的马氏距离超过9.21,则可以认为是极端样本。

也可以用P值来确定观察值是否为极值,则可以按以下方式计算P值:

# Compute the P-Values
df_x['p_value'] = 1 - chi2.cdf(df_x['mahala'], 2)# Extreme values with a significance level of 0.01
outliers = df_x.loc[df_x.p_value < 0.01]
outliers .head(10)

检测出的异常样本:

用蓝色绘制所有样本点,红色绘制检测出的异常样本点,可以看出这些样本与常规样本相比,确实是比较极端的:

小结

  • 马氏距离实际上是欧氏距离在多变量下的“加强版”,用于测量点(向量)与分布之间的距离。
  • 在计算马氏距离过程中,要求总体样本数大于样本的维数,否则无法求解。

  1. https://blog.csdn.net/qq_46098574/article/details/115875336 ↩︎

  2. 《概率论与数理统计》 ↩︎

  3. https://www.machinelearningplus.com/statistics/mahalanobis-distance/ ↩︎ ↩︎

  4. https://www.cnblogs.com/denny402/p/7027954.html ↩︎

  5. https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.mahalanobis.html ↩︎

  6. https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.chi2.html ↩︎

马氏距离详解(数学原理、适用场景、应用示例代码)相关推荐

  1. 快速排序算法详解(原理,时间复杂度,实现代码)

    快速排序算法详解(原理.实现和时间复杂度) 快速排序是对冒泡排序的一种改进,由 C.A.R.Hoare(Charles Antony Richard Hoare,东尼·霍尔)在 1962 年提出. 快 ...

  2. linux socket bind 内核详解,Socket与系统调用深度分析(示例代码)

    1. 什么是系统调用 操作系统通过系统调用为运行于其上的进程提供服务.当用户态进程发起一个系统调用, CPU 将切换到 内核态 并开始执行一个 内核函数 . 内核函数负责响应应用程序的要求,例如操作文 ...

  3. java调用wcf_详解JAVA调用WCF服务的示例代码

    这一篇将要解决java中调用WCF的问题,使用的依旧是上一篇中托管在IIS中的WCF服务,本来我是打算用axis来写这篇文章的,可就在我开始之前,无意中发现了在java包中自带的wsimport工具 ...

  4. 浅谈马氏距离【Mahalonobis Distance】

    浅谈马氏距离[Mahalonobis Distance] 1. Introduction 2. 欧式距离对于多元数据会存在一些什么问题? 3 .什么是马氏距离 4.马氏距离背后的数学和intuitio ...

  5. 马氏距离例题详解(全网最详细)

    马氏距离例题详解 定义 马哈拉诺比斯距离是由印度统计学家马哈拉诺比斯 (英语)提出的,表示数据的协方差距离.它是一种有效的计算两个未知样本集的相似度的方法.与欧氏距离不同的是它考虑到各种特性之间的联系 ...

  6. 马氏距离和欧式距离详解

    一般在机器学习模型中会涉及到衡量两个样本间的距离,如聚类.KNN,K-means等,使用的距离为欧式距离.其实,除了欧氏距离之外,还有很多的距离计算标准,本文主要介绍欧氏距离和马氏距离. 欧氏距离 最 ...

  7. 机器学习中的数学——距离定义(六):马氏距离(Mahalanobis Distance)

    分类目录:<机器学习中的数学>总目录 相关文章: · 距离定义:基础知识 · 距离定义(一):欧几里得距离(Euclidean Distance) · 距离定义(二):曼哈顿距离(Manh ...

  8. 【尚未完成,不建议参考】马氏距离,汉明距离

    本博客尚未完成,不建议参考 主要参考:马氏距离实例详解_NLP新手村成员的博客-CSDN博客_马氏距离计算实例 马氏距离例题详解(全网最详细)___Wedream__的博客-CSDN博客_马氏距离公式 ...

  9. 距离度量的方法,欧式距离,切比雪夫距离、马氏距离、巴氏距离,曼哈顿距离

    距离度量的方法有欧式距离,切比雪夫距离.马氏距离.巴氏距离,曼哈顿距离等: 用欧氏距离(也称欧几里德度量),高中所学的两点距离公式就是欧氏距离在二维空间上的公式,也就是欧氏距离的n的值为2的情况. 二 ...

最新文章

  1. #每天一种设计模式# 观察者模式
  2. 【机器学习】scikit-learn 1.0 版本重要新特性一览
  3. Java黑皮书课后题第6章:*6.4(反序显示一个整数)使用下面的方法体编写方法,反序显示一个整数…例如reverse(3456)返回6543,编写一个测试程序,提示用户输入一个整数,然后显示它的反序
  4. 分布式文件系统研究-搭建图片服务虚拟主机
  5. Java编译过程、c/c++编译过程区别
  6. 1元解锁 | Python万能代码模板 |10大必学实用技巧
  7. Game of Lines(POJ-3668)
  8. Python+Matplotlib绘制带误差线的柱状图
  9. DIV_ROUND_CLOSEST函数
  10. Ubuntu下VLC播放器安装配置以及VLC常用快捷键记录
  11. 使用谷歌浏览器下载的图片webp怎么转成jpg格式图片
  12. 基于MATLAB GUI的多算法雷达一维恒虚警检测CFAR可视化界面设计
  13. HyperAttentionDTI: improving drug–protein interaction prediction by sequence-based deep learning wit
  14. 一文搞懂 | Linux 同步管理(上)
  15. visio-制作甘特图工具
  16. 团队和过程:提升移动应用体验的根本
  17. 基于R语言、MaxEnt模型融合技术的物种分布模拟、参数优化方法、结果分析制图与论文写作
  18. MySQL连接查询的成本
  19. 如何恢复已删除的文件:终极指南
  20. YouTube 十岁了,这十年里视频网站改变了什么?

热门文章

  1. CIO常犯的五个错误
  2. 我是如何带领团队开发项目的
  3. 面试官系统精讲Java源码及大厂真题 - 25 整体设计:队列设计思想、工作中使用场景
  4. Linux 基础命令讲解--加密解密
  5. Linux——安全权限(禁止添加新用户+umask值+修改默认密码最长有效期)
  6. 学习iOS最权威的网站
  7. Mac OS修改VSCode Go的默认缩进格式
  8. 02331 数据结构 二叉树的遍历
  9. 【Vue.js 3.0】不使用根标签,Error:[vue/no-multiple-template-root] The template root requires exactly one ...
  10. 【Java】输入三角形的三边长,求三角形的面积