介绍
马氏距离是由印度统计学家马哈拉诺比斯(P. C. Mahalanobis)提出的,表示数据的协方差距离。它是一种有效的计算两个未知样本集的相似度的方法。与欧氏距离不同的是它考虑到各种特性之间的联系(例如:一条关于身高的信息会带来一条关于体重的信息,因为两者是有关联的)并且是尺度无关的(scale-invariant),即独立于测量尺度,广泛用于分类和聚类分析。
相关概念
方差:方差是标准差的平方,而标准差的意义是数据集中各个点到均值点距离的平均值。反应的是数据的离散程度。
协方差:标准差与方差是描述一维数据的,当存在多维数据时,我们通常需要知道每个维数的变量中间是否存在关联。协方差就是衡量多维数据集中,变量之间相关性的统计量。比如说,一个人的身高与他的体重的关系,这就需要用协方差来衡量。如果两个变量之间的协方差为正值,则这两个变量之间存在正相关,若为负值,则为负相关。
相同向量的协方差计算公式:
不同向量的协方差计算公式:
协方差的性质:
协方差矩阵:当变量多了,超过两个变量了。那么,就用协方差矩阵来衡量这么多变量之间的相关性。假设 X 是以 n个随机变数(其中的每个随机变数是也是一个向量,当然是一个行向量)组成的列向量:
马氏距离
定义
马氏距离计算示例
#include<iostream>
#include<Eigen\dense>
#include<vector>
using namespace std;
using namespace Eigen;
struct myvector
{
double x;
double y;
};
void main()
{
vector<myvector> data;
myvector p1, p2, p3, p4;
p1.x = 3; p1.y = 4;
p2.x = 5; p2.y = 6;
p3.x = 2; p3.y = 2;
p4.x = 8; p4.y = 4;
data.push_back(p1);
data.push_back(p2);
data.push_back(p3);
data.push_back(p4);
MatrixXd m(2, 1), mt(1, 2);
vector<double> Xarr, Yarr;
double sumX = 0;
double sumY = 0;
for (int i = 0; i < data.size(); i++)
{
sumX = sumX + data[i].x;
sumY = sumY + data[i].y;
Xarr.push_back(data[i].x);
Yarr.push_back(data[i].y);
}
double xmean = sumX / data.size();
double ymean = sumY / data.size();
double covxx = 0;
for (int i = 0; i < Xarr.size(); i++)
{
covxx = covxx + (Xarr[i] - xmean)*(Xarr[i] - xmean);
}
double covxy = 0;
for (int i = 0; i < Yarr.size(); i++)
{
covxy = covxy + (Xarr[i] - xmean)*(Yarr[i] - ymean);
}
double covyy = 0;
for (int i = 0; i < Xarr.size(); i++)
{
covyy = covyy + (Yarr[i] - ymean)*(Yarr[i] - ymean);
}
MatrixXd cov(2, 2);
double length = data.size() - 1;
cov << covxx / length, covxy / length, covxy / length, covyy / length;
cout << "协方差矩阵:" << endl << cov << endl << endl;
cout << "逆矩阵" << endl << cov.inverse() << endl << endl;
//计算(3,4)与(5,6)之间的马氏距离
MatrixXd mm(2, 1);
mm << -2, -2;
MatrixXd temp(0, 0);
temp = mm.transpose()*cov.inverse()*mm;
cout << "(3,4)与(5,6)之间的马氏距离为:" << endl << sqrt(sqrt(temp(0, 0))) << endl;
system("pause");
}