马氏距离

Reference

http://blog.51cto.com/tonyshen/800273

Definition

马氏距离(Mahalanobis distance)

对于$x_i$, 均值为$\mu = ( \mu_1, \mu_2, \mu_3, \dots , \mu_p )^T$,协方差矩阵为$\Sigma$的多变量向量$x = ( x_1, x_2, x_3, \dots, x_p )^T$,其与均值的马氏距离为

两个变量的马氏距离为

协方差矩阵

协方差矩阵是方阵,其维度跟样本维度一样。

对于两个变量,x和y的协方差计算公式:$Cov(x,y)=E(x-e(x))(y-E(y))$

对于多个列向量,协方差矩阵计算公式:$\Sigma _{ij}=cov(Dim_i,Dim_j) $

即,$Cov_{ij}$表示第i维和第j维的协方差

如果协方差矩阵为单位矩阵,马氏距离就简化为欧氏距离;如果协方差矩阵为对角阵,其也可称为正规化的欧氏距离。

本质

参考PCA, 相当于将变量延PCA中分析出的特征向量方向缩放, 再进行欧式空间内的距离比较.

记$X’=UX和\bar {X’}=U\bar X$,则

从距离空间看, 显然马氏距离是另一空间(以协方差矩阵单位特征向量为基)再按各方向方差归一拉伸后的新的坐标表示的欧氏距离.

从概率论角度看, 通过变换实现了$X’$各维度不相关.

马氏距离在另一个坐标系下是独立变量的距离。

如果马氏距离中各维度是不相关, 且方差相同, 这时马氏距离就为欧氏距离, 马氏距离的平方满足卡方分布.

特点

  • 标准化数据和中心化数据(即原始数据与均值之差)计算出的二点之间的马氏距离相同
  • 构成一个度量空间, 满足正定性, 对称性, 和三角不等式

马氏距离与高斯分布

注意到高斯分布以马氏距离为自变量, 且呈负相关. 距离越大, 概率越小.

实验

1

1
2
3
4
5
6
7
协方差矩阵
[[1, 0], [0, 1]]
特征值
[1. 1.]
特征向量
[[1. 0.]
[0. 1.]]

index

2

1
2
3
4
5
6
7
协方差矩阵
[[100, 0], [0, 3]]
特征值
[100. 3.]
特征向量
[[1. 0.]
[0. 1.]]

index-1

3

1
2
3
4
5
6
7
协方差矩阵
[[1, 0.4], [0.4, 1]]
特征值
[1.4 0.6]
特征向量
[[ 0.70710678 -0.70710678]
[ 0.70710678 0.70710678]]

index-2

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import numpy as np
import scipy as sp
import matplotlib.pyplot as plt
import math

def mahalanobis_distance(x, y, Sigma):
Sigma_ = np.linalg.inv(Sigma)
sub = x - y
sub_T = sub.T
delta = np.dot(np.dot(sub_T, Sigma_),sub)
return math.sqrt(delta)

def gen_clusters(means, cov, num):
return np.random.multivariate_normal(means, cov, num)

def show(X, means, Signa, num):
x = X[:,0]
y = X[:,1]
x_min = np.min(x)
x_max = np.max(x)
y_min = np.min(y)
y_max = np.max(y)

split_x = np.linspace(x_min, x_max, num)
split_y = np.linspace(y_min, y_max, num)

grid_x, grid_y = np.meshgrid(split_x, split_y)
grid_height = np.zeros((num, num))
for i in range(num):
for j in range(num):
grid_height[j,i] = mahalanobis_distance(np.array([split_x[i], split_y[j]]),np.array(means),Sigma)

plt.xlim(x_min,x_max)
plt.ylim(y_min,y_max)

plt.contourf(grid_x, grid_y, grid_height, 10, alpha = 0.5, cmap = plt.cm.hot)
C = plt.contour(grid_x, grid_y, grid_height, 10, colors = 'black')

plt.clabel(C, inline = True, fontsize = 10)
plt.plot(x,y,'o')

eigvals,eigvectors = np.linalg.eig(Sigma)
print("协方差矩阵")
print(Sigma)
print("特征值")
print(eigvals)
print("特征向量")
print(eigvectors)

eig_1_x = [eigvectors[0,0]*x+means[0] for x in range(-10,11)]
eig_1_y = [eigvectors[0,1]*y+means[1] for y in range(-10,11)]
eig_2_x = [eigvectors[1,0]*x+means[0] for x in range(-10,11)]
eig_2_y = [eigvectors[1,1]*y+means[1] for y in range(-10,11)]

plt.plot(eig_1_x,eig_1_y)
plt.plot(eig_2_x,eig_2_y)

plt.show()



means = [10, 10]
Sigma = [[10,0.5], [3,1]]
X = gen_clusters(means, Sigma, 100)
show(X,means,Sigma,100)
文章目录
  1. 1. Reference
  2. 2. Definition
    1. 2.1. 马氏距离(Mahalanobis distance)
    2. 2.2. 协方差矩阵
  3. 3. 本质
  4. 4. 特点
  5. 5. 马氏距离与高斯分布
  6. 6. 实验
    1. 6.1. 1
    2. 6.2. 2
    3. 6.3. 3
    4. 6.4. 代码
|