机器算法:马氏距离(Mahalanobis Distance)

马氏距离(Mahalanobis Distance)是度量学习中一种常用的距离指标,同欧氏距离、曼哈顿距离、汉明距离等一样被用作评定数据之间的相似度指标。但却可以应对高维线性分布的数据中各维度间非独立同分布的问题。

从数学上来看,Mahalanobis距离是表示数据的协方差距离。它是一种有效的计算两个未知样本集的相似度的方法。Mahalanobis距离与欧氏距离不同的是它考虑到各种特性之间的联系(例如:一条关于身高的信息会带来一条关于体重的信息,或者关于电脑价格的信息会带来一条关于电脑自带软件的信息,因为两者是有关联的),并且是尺度无关的(scale-invariant),即独立于测量尺度。

为了更好地理解马氏距离,下面列举生活中常见的两个案例:

案例1:坐飞机从上海到北京和坐普快从上海到北京,由于速度的差异,会让人觉得距离也有变化,坐飞机可能觉得,好快啊,没多远,一下就到了,坐火车,时常会感觉好慢,怎么这么远。

案例2:小时候买菜都用杆秤,假如物品和秤砣恰好相等且分别放在秤的两端,那么提纽应该恰好在正中间。但随着物品的重量增大,而秤砣的重量不变,那么这时候,提纽就应该向物品一侧靠近,才能继续保持平衡。马氏距离,就是一个找到两个物体之间平衡点的方法。(说白了就是体现一种杠杆原理的物理过程)


image.png

单个数据点的马氏距离

数据点x, y之间的马氏距离(这里的x,y是多维的一个数据集或者向量)

其中Σ是多维随机变量的协方差矩阵,μ为样本均值,如果协方差矩阵是单位向量,也就是各维度独立同分布,马氏距离就变成了欧氏距离。

下面简要说明马氏距离的推导过程:

首先要对数据点进行旋转,旋转至主成分,维度间线性无关,假设新的坐标为

F

又变换后维度间线性无关且每个维度自己的方差为特征值,所以满足:

sigma

马氏距离是旋转变换缩放之后的欧式距离,所以马氏距离的计算公式为:

image.png

这就是之前提到的马氏距离的公式。

注意事项:

  • 协方差矩阵必须满秩

协方差矩阵里面有求逆矩阵的过程,不满秩不行,要求数据要有原维度个特征值,如果没有可以考虑先进行主成分分析(PCA),因为这种情况下PCA不会损失信息。

  • 不能处理非线性流形(manifold)上的问题

只对线性空间有效,如果要处理流形,只能在局部定义,可以用来建立KNN图

Python实现马氏距离的计算:

# encoding: utf-8
#马氏距离的计算:以函数的方式调用
from __future__ import division
import sys
import numpy as np
def mashi_distance(x,y):
    print(x)
    print(y)
    #马氏距离要求样本数要大于维数,否则无法求协方差矩阵
    #此处进行转置,表示10个样本,每个样本2维
    X=np.vstack([x,y])
    print(X)
    XT=X.T
    print(XT)
    #方法一:根据公式求解
    S=np.cov(X)   #两个维度之间协方差矩阵
    SI = np.linalg.inv(S) #协方差矩阵的逆矩阵
    #马氏距离计算两个样本之间的距离,此处共有4个样本,两两组合,共有6个距离。
    n=XT.shape[0]
    d1=[]
    for i in range(0,n):
        for j in range(i+1,n):
            delta=XT[i]-XT[j]
            d=np.sqrt(np.dot(np.dot(delta,SI),delta.T))
            print(d)
            d1.append(d)

if __name__ == '__main__':
    # 第一列
    x = [3, 5, 2, 8]
    # 第二列
    y = [4, 6, 2, 4]
    mashi_distance(x,y)
image.png

你可能感兴趣的:(机器算法:马氏距离(Mahalanobis Distance))