Mahalanobis距离是数据所在的空间的协方差的度量,或者是任务把数据所在空间进行"扭曲拉伸"然后进行度量.如果你值得Z-score,就可以把Mahalanobis距离看作多维空间中Z-Score的类型物.图13-4(a)展示了三个数据集的初始分布,看起来竖直方向上的那两个集合比较接近.在我们根据数据协方差归一化空间之后,如果13-4(b),实际上水平方向上的两个集合比较接近.这中情况经常发生,如果我们以米为单位来测试人的身高,以天为单位测量人的年龄,我们看到身高的范围很小,而年龄的范围很大.通过方差归一化,变量之间的关系便会更加符合实际情况.像K邻近之类的算法很难处理方差相差很大的数据,但是决策树等其他算法则不受这种情况的影响.
我们通过图13-4大致了解了什么是Mahalanobis距离.测量距离的时候必须考虑数据的协方差.首先,我们回忆一下协方差的概念.给定一个列表X,X包含N个数据样本,每个数据样本有K维,每一维的均值分别为u1,...,K.它们的K*K协方差矩阵为:
其中E[.]是期望操作符.OpenCV使用下面函数来计算协方差矩阵:
cvCalcCovarMatrix( const CvArr** vects, int count, CvArr* cov_mat, CvArr* avg, int flags );这个函数有一点点迷惑性.注意,参数vects是一个指向CvArr的指针的指针.这意味着我们最多可拥有vects[0]~vects[count-1]个CvArr.到底有多少个CvArr,实际上由参数flag决定.一般有以下两种情况.
1.如果flag中CV_COV_ROWS和CV_COV_COLS都没有设置,vects则是一个指针数组,数组里的元素指向一维或二维矩阵.具体说来,每一个vects[i]可以指向一个一维或二维向量.这种情况下,如果CV_COVAR_CSCALL被设置,累积协方差计算时,将除以count指定的数据点的个数.
2.如果CV_COV_ROWS或者CV_COV_COLS其中之一被设置,那么在通常只有一个输入向量的时候,就只用vects[0],count被忽略.所有的输入都包含在向量vects[0]中.
a. CV_COV_ROWS,所有的输入向量在vects[0]中以行排列
b.CV_COV_COLS,所有的输入向量在vects[0]中以列排列.不可以同时设置行标志和列标识
Vects可以存储8UC1,16UC1,32FC1和64FC1几种数据类型.任何情况下,vects包含了一个K维数据样本的列表.cov_mat是得到的K×K协方差矩阵,它有CV_32FC1和CV_64FC1两种数据类型.Avg是否使用向量取决于flag的设置.如果使用了avg,则它与vects的数据结构一致,包含vects中的所有向量的K维均值.参数flags可以有很多种组合,总体来说,可是设置flag为下面的任何一个.
CV_COVAR_NORMAL 按照前面所示的最一般的协方差矩阵计算公式来计算.如果CV_COVAR_SCALE没有设置,则把结果用count平均,否则用vects[0]的数据点个数来平均结果
CV_COVAR_SCALE 归一化计算得出的协方差矩阵
CV_COVAR_USE_AVG 使用avg矩阵而不通过每个特征来计算均值.如果已经得到过均值(如通过调用CvAvg()),设置这个参数可以节省计算时间.否则,程序会计算均值.
通常把数据结合成一个大矩阵,假设以行排列,那么,标志将被设置为flags = CV_COVAR_NORMAL|CV_COVAR_SCALE|CV_COVAR_ROWS
现在我们有了协方差矩阵,为了计算Mahalanobix距离,我们需要除以空间的方差,所以需要计算协方差矩阵的逆矩阵.可以通过下面这个函数来计算
double cvInvert(const CvArr* src,CvArr* dst, int method = CV_LU);
在cvInvert中,源矩阵src是前面计算的协方差矩阵,dst是计算得到的逆矩阵.如果没有指定参数method,则默认为CV_LU,但是最好使用CV_SVD_SYM作为参数.
得到了协方差矩阵的逆矩阵,我们就可以求两个向量的Mahanobis距离.Euclidean距离是计算两个向量的对应数据的差的平方和,Mahalanobis距离与Euclidean距离类似,值不过它还需要除以空间的协方差矩阵:
Mahalanobis距离是一个数值.如果协方差矩阵是单位矩阵,则Mahalanobis距离退化为Euclidean距离.最后介绍OpenCV中计算Mahalanobis距离的函数,它输入两个向量(vec1,vec2)和一个逆协方差矩阵(mat),返回一个双精度的距离.
double cvMahalanobis(const CvArr* vec1, const CvArr* vec2, CvArr* mat);
Mahalanobis距离是多维空间中两点相似的度量,它本身不是聚类或者分类算法.