Mahalanobis距离

来源:互联网 发布:杨氏模量实验数据图 编辑:程序博客网 时间:2024/05/19 23:12

Mahalanobis距离是表示数据的协方差距离。它是一种有效的计算两个未知样本集的相似度的方法。与欧氏距离不同的是它考虑到各种特性之间的联系

与欧氏距离不同的是它考虑到各种特性之间的联系(例如:一条关于身高的信息会带来一条关于体重的信息,因为两者是有关联的)并且是尺度无关的(scale-invariant),即独立于测量尺度。

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

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

对于一个均值为μ=(μ1,μ2,μ3,,μp)T,协方差矩阵为Σ的多变量向量x=(x1,x2,x3,,xp)T,其马氏距离为 

DM(x)=(xμ)TΣ1(xμ)

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

Mahalanbis距离与Euclidean距离类似,只不过它还需要除以空间的协方差矩阵,通过方差归一化,变量之间的关系便会更加符合实际情况。

对于两个变量,xy的协方差计算公式:Cov(x,y)=E(xE(x))(yE(y)) 
对于多个列向量,协方差矩阵计算公式:Σij=cov(Dimi,Dimj) 
即,Covij表示第i维和第j维的协方差,举4维例子来说,设4个维度分别为a,b,c,d

Σij=cov(a,a)cov(b,a)cov(c,a)cov(d,a)cov(a,b)cov(b,b)cov(c,b)cov(d,b)cov(a,c)cov(b,c)cov(c,c)cov(d,c)cov(a,d)cov(b,d)cov(c,d)cov(d,d)

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

DM(x)=i=1p(xiyi)2σ2i

其中σixi的标准差。                                                                                                                                                                                                     

opencv

计算协方差矩阵函数

void   cvCalcCovarMatrix( const CvArr** vects, 

                                          int                  count,
                                          CvArr*           cov_mat, 

                                          CvArr*           avg, 

                                          int                  flags

                                           );

计算逆矩阵函数

double  cvInvert( const CvArr* src,  

                           CvArr*           dst,
                           int method CV_DEFAULT  =CV_LU

                           );
计算Mahalanobis距离:

double   cvMahalanobis(const  CvArr*  vec1,

                                      const  CvArr*  vec1,

                                      CvArr*    mat

                                      );  
Mahalanobis距离 = Euclidean距离 * 空间协方差矩阵的逆矩阵

计算Mahalanobis距离时,用cvInvert函数计算逆矩阵时,参数method做好用CV_SVD_SYM。使用该参数虽速度较慢,但可计算更精确的逆矩阵。

计算时间大部分由cvCalcCovarMatrix()消耗,所以稍微多花点时间计算精确的逆矩阵是明智的。

0 0
原创粉丝点击