基本思想:在高维空间中,有低维结构。所以在局部具有欧式空间的性质。能用欧氏距离来进行距离计算。
如在三维空间中有二维平面
所以高维中的测地线距离需要用近邻距离来近似。
先介绍向量的两种运算,一个行向量乘以一个列向量称作向量的内积,又叫作点积,结果是一个数;
一个列向量乘以一个行向量称作向量的外积,外积是一种特殊的克罗内克积,结果是一个矩阵,
两篇文章参考
参考1
参考2
1、在这种情况下变换仅仅是水平方向乘以因子2和垂直方向乘以因子0.5,使得变换矩阵A定义为
2、在一般情况下,特征向量矩阵A的特征向量 v 满足下列式子
3、如果一个方阵是不可逆的,这意味着它的行列式必须等于零。因此,要找到A的特征向量,我们只需要解决以下公式:
4、利用判别式 Δ=b2−4ac Δ = b 2 − 4 a c 来找到 λ 的值。需要注意的是大小为NxN的方阵总是具有N个特征值,每一个对应一个特征向量。特征值指定特征向量的大小。
5、将 λ 代入 公式8,找到特征向量。
局限:变换的矩阵必须是方阵
特征值分解是将一个矩阵分解为如下形式:
其中,Q是这个矩阵A的特征向量组成的矩阵,Σ是一个对角矩阵,每一个对角线元素就是一个特征值,里面的特征值是由大到小排列的,这些特征值所对应的特征向量就是描述这个矩阵变化方向(从主要的变化到次要的变化排列)。也就是说矩阵A的信息可以由其特征值和特征向量表示。
对于矩阵为高维的情况下,那么这个矩阵就是高维空间下的一个线性变换。可以想象,这个变换也同样有很多的变换方向,我们通过特征值分解得到的前N个特征向量,那么就对应了这个矩阵最主要的N个变化方向。我们利用这前N个变化方向,就可以近似这个矩阵(变换)。
参考
我们有n个样本,每个样本维度为m。我们的目标是用不同的新的k维向量 ( k<<m k << m ) 替代原来的n个m维向量,使得在新的低维空间中,所有样本相互之间的距离等于(或最大程度接近)原空间中的距离(默认欧氏距离)。
MDS接收的输入是一个距离矩阵D(已经降维后的矩阵)
不能直接转换到原始数据的原因
- 对点做平移、旋转等变化时,点之间的距离时不变的
思路是:从D->B->X
假设: X是一个n×q的矩阵,n为样本数,q是原始的维度 ;降维后的距离矩阵D
定义:内积矩阵B
B的每个元素:
数据的中心点平移到原点 ∑ni=1xik=0,for all k=1..q ∑ i = 1 n x i k = 0 , f o r a l l k = 1.. q
即B的任意行(row)之和以及任意列(column)之和都为0了 。所以我们可以得到
这样我们就可以通过矩阵D得到矩阵B了 。因为B是对称的矩阵,所以可以通过特征分解得到:
def mds(D, q):
"""
将 D 转化成内积矩阵 B:
bij=-0.5(dij^2-di.^2-d.j^2+d..^2)
将 B 转化成 X:
X=特征向量*sqrt(特征值)
:param D:距离矩阵
:param q:降维的目标
:return:降维后的目标矩阵
"""
D = np.asarray(D)
DSquare = D ** 2 # d^2
totalMean = np.mean(DSquare) # d..^2
columnMean = np.mean(DSquare, axis=0) # d.j^2
rowMean = np.mean(DSquare, axis=1) # di.^2
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) # 找到特征值和特征向量
print(eigVal, eigVec)
X = np.dot(eigVec[:, :q], np.sqrt(np.diag(eigVal[:q])))
return X
A Global Geometric Framework for Nonlinear Dimensionality Reduction. Joshua B. Tenenbaum, Vin de Silva, John C. Langford. 2000.
构造点之间的距离
对于每个点,基于欧氏距离找出其邻近点,(邻近点之间存在连接,非邻近点不存在连接),建立邻近连接图。
1.为每个数据点确定邻居 ,将它们连接起来构造带权邻接图G(复杂度: O(DN2) O ( D N 2 ) )
1.1 通过kNN(k-Nearest Neighbor)找到点的k个最近邻
1.2 把半径ϵ内的所有点作为邻居
2.通过计算同中各点之间的最短路径Dijkstra ,作为点之间的距离dij放入距离矩阵D(复杂度: O(DN2) O ( D N 2 ) )
3.将D传给经典的MDS算法,得到降维后的结果。 (复杂度: O(qN2) O ( q N 2 ) )
# -*- coding: utf-8 -*-
# @Time : 2018/7/11 14:37
# @Author : Inkky
# @Email : [email protected]
'''
isomap算法主要流程
1、找k近邻的点形成近邻图
2、找最短路径(Floyd或者Dijkstra)形成近邻矩阵
3、调用MDS降维
N :训练数据点数
D: 近邻矩阵
k :最近邻居数
q :输出尺寸
'''
import numpy as np
from sklearn import datasets
from MDS import mds
import matplotlib.pyplot as plt
def distancematirx(data):
n = len(data)
dis_matrix = np.zeros([n, n], np.float32)
for i in range(n):
for j in range(n):
dis_matrix[i, j] = np.linalg.norm(data[i] - data[j])
return dis_matrix
def dijkstra(data, start):
n = len(data)
col = data[start].copy() # 一维数组 dis 来存储 1 号顶点到其余各个顶点的初始路程
for i in range(n):
tmp = np.argpartition(col, 1)[1] # 找到第二小的值,最小为自身
dis = data[start, tmp] # 找到最短的长度
for j in range(n): # 更新距离矩阵
if data[start, j] > dis + data[i, j]:
data[start, j] = dis + data[i, j]
data[j, start] = data[start, j]
col[tmp] = float('inf')
return data
def isomap(rawdata, target, k):
inf = float('inf')
n = len(rawdata)
if k >= n:
raise ValueError('K is too large')
mat_matrix = distancematirx(rawdata) # 计算原来矩阵的距离
print(mat_matrix)
# 找到k近邻
k_near = np.ones([n, n], np.float32) * inf
for i in range(n):
temp = np.argpartition(mat_matrix[i], k)[:k + 1]
print(temp)
k_near[i][temp] = mat_matrix[i][temp]
print('找到k近邻\n', k_near)
# 调用最短路径短发计算任意两样本点之间的距离
for i in range(n):
dist = dijkstra(k_near, i)
print('调用最短路径短发计算任意两样本点之间的距离\n', dist)
# 调用mds降维
return mds(dist, target)
if __name__ == '__main__':
digits = datasets.load_digits(n_class=4)
X = digits.data[:10,:10] #只能为偶数
y = digits.target
n_samples, n_features = X.shape
print(n_samples, n_features)
print('开始降维.....')
# D = np.array([[1, 2, 3, 4], [2, 1, 5, 6], [3, 5, 1, 7], [4, 6, 7, 1], [3, 4, 5, 6], [6, 1, 2, 3]]) # test data
outcome = isomap(X, 2, 4)
print('降维完成\n')
print(outcome)
问1:降维过程中保留距离信息不变,这是不是意味着任意两点在低维空间中的测地线距离应该和高维空间中的测地线距离相同?但是如果用MDS,那么高维空间中的距离度量用的是测地线距离,而低维空间用的是欧氏距离,和目标不一致了怎么办?
答:低维空间中使用欧氏距离,是因为此时欧氏距离是测地线距离的一个近似。就像高维空间中用最短路径距离近似测地线距离一样。
ref
https://blog.csdn.net/dapanbest/article/details/78128505