多维尺度法(Multidimensional Scaling,MDS)是一种经典的数据降维方法,是当我们仅能获得样本之间的相似性矩阵时,如何由此来重构它们的欧几里德坐标,即只知道高维空间中的样本之间的距离,基于此重构这些样本在低维空间的相对位置!下面一步一步地介绍MDS的神奇。
假定 m 个 n 维样本在原始空间的距离矩阵为 D∈Rm×m ,其中第 i 行 j 列的元素 dij 为样本 xi 到 xj 的距离:
为便于讨论,令降维后的样本 Z 被中心化,即 ∑mi=1zi=0 。直接由 D 确定 Z 的表达式还有点困难,不过可令 B=ZTZ ,其中 bij=zTizj ,先由 D 推出 B ,然后再由 B 便可轻松地获得 Z 。因为有:
基于上式可得 B={bij} 为:
因为 d2ij 是已知的,接下来的问题便变成利用已知的条件确定 bii 和 bjj 的表示?对 d2ij 进行一些简单的求和运算,可得:
其中 tr(⋅) 表示矩阵的迹,其为矩阵主对角线(从左上方至右下方的对角线)上各个元素的总和。由上述3个求和等式可求得:
最后可得:
已确定了矩阵 B 的值,接下来推导 Z 的结果就易如反掌。先对矩阵 B 做特征分解:
为了达到有效的降维效果,假定其中有 n′ 个非零特征值,其中 n′<n ,它们构成的对角矩阵为 Λ∗=diag(λ1,λ2,…,λn′) ,令 V∗ 为其对应的特征向量矩阵,则 Z 可表达为:
输入:距离矩阵 D∈Rm×m ,其中第 i 行 j 列的元素 dij 为样本 xi 到 xj 的距离;低维空间维数 n′ 。
输出:矩阵 Z∈Rn′×m ,其中每列是一个样本的低维坐标。
过程:
1. 根据式(1)~(3)计算 tr(B) 、 bjj 和 bii ;
2. 根据(4)计算 bij ,确定矩阵 B 的表示;
3. 对矩阵 B 进行特征值分解:求得 n 个对应的特征值和特征向量;
4. 取 Λ∗ 为 n′ 个最大特征值所构成的对角矩阵, V∗ 为其对应的特征向量矩阵;
5. 求得矩阵 Z=Λ12∗VT∗ ,得到样本集的低维表示。
scikit-learn中的MDS算法是在包manifold中,其主要的参数为n_components,它确定了降维的维数,其余参数的介绍、配置请查阅参考资料1。
# -*- coding: utf-8 -*-
from sklearn.manifold import MDS
import numpy as np
data = np.array([[1,1],[1.5,1.6],[2,2],[2.4,2.4],[1.95,1.9],[3,3],[3.3,3.1]])
mds2 = MDS(n_components=2)
newdata2 = mds2.fit_transform(data)
numdata = data.shape[0]
D1 = np.zeros([numdata,numdata])
D2 = np.zeros([numdata,numdata])
for i in range(0,numdata):
for j in range(0,numdata):
D1[i,j] = np.sqrt(np.sum(np.square(data[i,:] - data[j,:])))
D2[i,j] = np.sqrt(np.sum(np.square(newdata2[i,:] - newdata2[j,:])))
print "MDS前后样本间距离之差:\n",D1-D2
mds1 = MDS(n_components=1)
newdata1 = mds1.fit_transform(data)
print "原始数据-二维:\n", data
print "降维后数据-一维:\n", newdata1