这次的更新是一个很小很小的功能实现:一个点到一个分布之间的马氏距离。
马氏距离(Mahalanobis Distance)可以说是在欧氏距离的基础上一种改进,如果说欧式距离是直接衡量两个高维空间上点之前的距离的话,马氏距离则会考虑到点所在的分布的性质。
这里是找到的一张比较清晰的示意图(图片出处由于被多次转用已经无法溯源了),首先我们看左下的散点图,如果想计算中间的绿点到右上方绿点和中间的绿点到右下方的蓝点之间的“距离”判断右侧两点哪个更“接近”中间的绿点,直接计算欧氏距离的话如左上图所示,显然中间的绿点与右下的蓝点间距离更近,但如果考虑数据的分布情况,即如右上图所示计算马氏距离发现右上的绿点更应该“接近”中间的绿点。而马氏距离的计算实际就是经过了一系列的等效变换将点投射到右下角图片所示的空间上再计算空间中的欧氏距离。
进一步来说,与欧氏距离不同,马氏距离考虑了各个维度之间的联系。具体来说通过一个多维随机变量的协方差矩阵对欧氏距离中各个维度尺度不一致且相关的修正。在几何意义上,是将高维散点按照主成分进行旋转让维度之间相互独立,再进行标准化使维度同分布。
Python的代码实现:
import numpy as npfrom scipy.spatial.distance import mahalanobisdef mahalanobis_distance(p, distr): # p: 一个点 # distr : 一个分布 # 计算分布的协方差矩阵 cov = np.cov(distr, rowvar=False) # 选取分布中各维度均值所在点 avg_distri = np.average(distr, axis=0) dis = mahalanobis(p, avg_distri, cov) return dis
源码可见:
https://github.com/ZitongLu1996/Mahalanobis_Distance