Dijkstra->MDS算法->ISOMAP降维
ISOMAP降维
(参考机器学习235页)
目标是获得一个低维的矩阵,实现类似图a到图b的过程。
问题就是我们不能简单的基于任意俩个点做它的欧式距离。
所以我们取每个点的K个近邻形成一个连通的图。
在此图的基础上计算它的任意两点的距离,形成一个距离矩阵。
将这个矩阵作为MDS算法的输入,得到降维的结果。
具体算法过程:
Dijkstra算法
单源最短路径算法。
(一些改造:在图邻接表的存储下,利用堆优化,加快距离矩阵的计算。)
初始化:
单源距离dis,标记v,小顶堆
过程:
while 堆!空
…从堆寻找一个未标记的顶点i并标记;
…对与i相邻的边ij 进行单源距离dis的更新;
…如果更新则对未标记的相应顶点j 加入到小顶堆;
MDS降维
降维的目标是保持原始空间样本之间的距离和低维空间中的距离相等。
这是MDS降维方法的前提和条件,但是在实际的应用中发现,我们并不会保证样本之间距离在降维前后保持百分之百不变,而是使得降维前后样本距离大致一致。
(多维缩放(Multiple Dimensional Scaling)过程a->b)
具体的MDS算法过程:
(输入的是距离矩阵,输出的是数据的低维映射)
…
基于PYTHON实现ISOMAP
ISOMAP 由上文说明,首先是对数据根据K-NN建立邻接表;
基于这个邻接表调用最短路算法,得到MDS算法的输入—距离矩阵;
调用MDS算法得到数据的低维缩放—降低了维度的数据矩阵。
def dijkstra(G, start): ###dijkstra算法
INF = 999999999
dis = [INF for i in range(len(G))] # start到每个点的距离
v = [0 for i in range(len(G))] # flag
pq = [] # 存放排序后的值
heapq.heappush(pq,[0,start]) # ##堆优化
while len(pq) > 0:
heapq.heapify(pq)
while v[i] == 1 and len(pq) > 0:
v_dis, i = heapq.heappop(pq) # 未访问点中距离最小的点和对应的距离
v[i] = 1
for node,distance in G[i]: # 与v直接相连的点
new_dis = dis[i] + distance
if new_dis < dis[node]:
if v[node] == 0:
heapq.heappush(pq,[new_dis,node])
dis[node] = new_dis # 更新所有点的距离
return dis
def MDS(D,q):
D = np.asarray(D)
DSquare = D ** 2
totalMean = np.mean(DSquare)
columnMean = np.mean(DSquare, axis=0) # 列均值
rowMean = np.mean(DSquare, axis=1) # 行均值
B = np.zeros(DSquare.shape)
for i in range(B.shape[0]):
for j in range(B.shape[1]):
B[i][j] = -0.5 * (DSquare[i][j] - rowMean[i] - columnMean[j] + totalMean)
eigVal, eigVec = np.linalg.eig(B) # 求特征值及特征向量
X = np.dot(eigVec[:, :q], np.sqrt(np.diag(eigVal[:q])))
return X
# MDS参考 https://blog.csdn.net/Dark_Scope/article/details/53229427
一点浅薄的思考
可以深入了解MDS算法的具体推导过程