马氏距离介绍及代码实现(C++)

介绍

马氏距离是由印度统计学家马哈拉诺比斯(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");

}

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

点云实验室lab

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值