3.萨蒙映射(非线性)
4.等距映射(非线性)
5.局部线性嵌入(非线性)
6.规范相关分析(非线性)
7.SNE(非线性)
8.最小方差无偏估计(非线性)
9.拉普拉斯特征图(非线性)
线性降维算法的一个主要问题是它们集中将不相似的数据点放置在较低维度区域时,数据点相距甚远。 但是为了在低维、非线性流型上表示高维数据,我们也需要把相似的数据点靠近在一起展示,这并不是线性降维算法所能做的。
局部方法寻求将流型上的附近点映射到低维表示中的附近点。
全局方法试图保留所有尺度的几何形状,即将附近的点映射到附近的点,将远处的点映射到远处的点
除t-SNE之外的大多数非线性技术都不能同时保留数据的局部和全局结构。
from time import time
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d.axes3d import Axes3D
from sklearn import manifold, datasets, decomposition, ensemble, random_projection
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis as lda
加载数据,显示数据
digits = datasets.load_digits(n_class=5) # 只加载0-4
X = digits.data
y = digits.target
(901, 64) (901,)
n_img_per_row = 20
img = np.zeros((10 * n_img_per_row, 10 * n_img_per_row))
for i in range(n_img_per_row):
ix = 10 * i + 1
for j in range(n_img_per_row):
iy = 10 * j + 1
img[ix:ix + 8, iy:iy + 8] = X[i * n_img_per_row + j].reshape((8, 8))
plt.imshow(img, cmap=plt.cm.binary)
plt.title('A selection from the 64-dimensional digits dataset')
# LLE,Isomap,LTSA需要设置n_neighbors这个参数
n_neighbors = 30
# 将降维后的数据可视化,2维
def plot_embedding_2d(X, title=None):
#坐标缩放到[0,1]区间
x_min, x_max = np.min(X,axis=0), np.max(X,axis=0)
X = (X - x_min) / (x_max - x_min)
#降维后的坐标为(X[i, 0], X[i, 1]),在该位置画出对应的digits
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
for i in range(X.shape[0]):
ax.text(X[i, 0], X[i, 1],str(digits.target[i]),
color=plt.cm.Set1(y[i] / 10.),
fontdict={'weight': 'bold', 'size': 9})
if title is not None:
plt.title(title)
#将降维后的数据可视化,3维
def plot_embedding_3d(X, title=None):
#坐标缩放到[0,1]区间
x_min, x_max = np.min(X,axis=0), np.max(X,axis=0)
X = (X - x_min) / (x_max - x_min)
#降维后的坐标为(X[i, 0], X[i, 1],X[i,2]),在该位置画出对应的digits
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1, projection='3d')
for i in range(X.shape[0]):
ax.text(X[i, 0], X[i, 1], X[i,2],str(digits.target[i]),
color=plt.cm.Set1(y[i] / 10.),
fontdict={'weight': 'bold', 'size': 9})
if title is not None:
plt.title(title)
随机映射
print("Computing random projection")
rp = random_projection.SparseRandomProjection(n_components=2, random_state=42) # n_components降到几维
X_projected = rp.fit_transform(X)
print(X_projected.shape)
plot_embedding_2d(X_projected, "Random Projection")
plt.show()
PCA
t0 = time()
X_pca = decomposition.TruncatedSVD(n_components=3).fit_transform(X)
print(X_pca.shape)
plot_embedding_2d(X_pca[:,0:2],"PCA 2D")
plot_embedding_3d(X_pca,"PCA 3D (time %.2fs)" %(time() - t0))
plt.show()
LDA
LDA是一种监督学习的降维技术,也就是说它的数据集的每个样本是有类别输出的。
这点和PCA不同。PCA是不考虑样本类别输出的无监督降维技术。LDA的思想可以用一句话概括,就是“投影后类内方差最小,类间方差最大”。
X2 = X.copy()
X2.flat[::X.shape[1] + 1] += 0.01 # Make X invertible
t0 = time()
X_lda = lda(n_components=3).fit_transform(X2, y)
plot_embedding_2d(X_lda[:,0:2],"LDA 2D" )
plot_embedding_3d(X_lda,"LDA 3D (time %.2fs)" %(time() - t0))
plt.show()
Isomap
流形学习的最早方法之一是 Isomap 算法,等距映射(Isometric Mapping)的缩写。
Isomap 可以被视为多维缩放(Multi-dimensional Scaling:MDS)或核主成分分析(Kernel PCA)的扩展。
Isomap 寻求一个较低维度的嵌入( 译注:嵌入(embedding),在此处,可以理解为高维数据到低维数据的一种映射转换,数据间的固有结构不变化 ),
它保持了所有点之间的原有的测地距离( 译注:测地距离(geodesic distance)是指在图中连接某两个顶点的最短距离(shortest path) )。
https://sklearn.apachecn.org/docs/0.21.3/21.html
t0 = time()
X_iso = manifold.Isomap(n_neighbors, n_components=2).fit_transform(X)
plot_embedding_2d(X_iso,"Isomap (time %.2fs)" %(time() - t0))
plt.show()
standard LLE
局部线性嵌入(LLE)通过保留局部邻域内的距离来寻求数据的低维投影。
它可以被认为是一系列的局部主成分分析在全局范围内的相互比较,找到最优的局部非线性嵌入。
clf = manifold.LocallyLinearEmbedding(n_neighbors, n_components=2,method='standard')
t0 = time()
X_lle = clf.fit_transform(X)
print("Done. Reconstruction error: %g" % clf.reconstruction_error_)
plot_embedding_2d(X_lle,"Locally Linear Embedding (time %.2fs)" %(time() - t0))
plt.show()
modified LLE
clf = manifold.LocallyLinearEmbedding(n_neighbors, n_components=2,method='modified')
t0 = time()
X_mlle = clf.fit_transform(X)
print("Done. Reconstruction error: %g" % clf.reconstruction_error_)
plot_embedding_2d(X_mlle,"Modified Locally Linear Embedding (time %.2fs)" %(time() - t0))
plt.show()
HLLE
黑塞特征映射 (也称作基于黑塞的 LLE: HLLE )是解决 LLE 正则化问题的另一种方法。
在每个用于恢复局部线性结构的邻域内,它会围绕一个基于黑塞的二次型展开。虽然其它的实现表明它对数据大小进行缩放的能力较差,
但是 sklearn 实现了一些算法改进,使得在输出低维度时它的损耗可与其他 LLE 变体相媲美。
clf = manifold.LocallyLinearEmbedding(n_neighbors, n_components=2,method='hessian')
t0 = time()
X_hlle = clf.fit_transform(X)
print("Done. Reconstruction error: %g" % clf.reconstruction_error_)
plot_embedding_2d(X_hlle,"Hessian Locally Linear Embedding (time %.2fs)" %(time() - t0))
plt.show()
LTSA
尽管,严格意义上来说,局部切空间对齐(LTSA) 并不是LLE的变体,
但是,从算法角度来说,它们俩又是足够接近的,所以把它放在该目录下。
与 LLE 算法关注于保持临点距离不同,LTSA 寻求通过切空间来描述局部几何形状,
并(通过)实现全局最优化来对其这些局部切空间,从而得知对应的嵌入。
clf = manifold.LocallyLinearEmbedding(n_neighbors, n_components=2,method='ltsa')
t0 = time()
X_ltsa = clf.fit_transform(X)
print("Done. Reconstruction error: %g" % clf.reconstruction_error_)
plot_embedding_2d(X_ltsa,"Local Tangent Space Alignment (time %.2fs)" %(time() - t0))
plt.show()
MDS
寻求数据的低维表示,而这些低维数据间的距离保持了它们在初始高维空间中的距离。
一般来说,(MDS)是一种用来分析在几何空间距离相似或相异数据的技术。
MDS 尝试在几何空间上将相似或相异的数据进行建模。这些数据可以是物体间的相似等级,也可是分子的作用频率,还可以是国家简单贸易指数。
MDS算法有2类:度量和非度量。在 scikit-learn 中, MDS 类具有上述两者的实现。
在度量 MDS 中,输入相似度矩阵源自度量(并因此遵从三角形不等式),输出两点之间的距离被设置为尽可能接近相似度或相异度的数据。
在非度量版本中,算法尝试保持距离的控制,并因此寻找在所嵌入空间中的距离和相似/相异之间的单调关系。
clf = manifold.MDS(n_components=2, n_init=1, max_iter=100)
t0 = time()
X_mds = clf.fit_transform(X)
print("Done. Stress: %f" % clf.stress_)
plot_embedding_2d(X_mds,"MDS (time %.2fs)" %(time() - t0))
plt.show()
Random Trees
hasher = ensemble.RandomTreesEmbedding(n_estimators=200, random_state=0,max_depth=5)
t0 = time()
X_transformed = hasher.fit_transform(X)
pca = decomposition.TruncatedSVD(n_components=2)
X_reduced = pca.fit_transform(X_transformed)
plot_embedding_2d(X_reduced,"Random Trees (time %.2fs)" %(time() - t0))
plt.show()
Spectral
谱嵌入是计算非线性嵌入的一种方法。scikit-learn 执行拉普拉斯特征映射,该映射是用图拉普拉斯的谱分解的方法把数据进行低维表达。
这个生成的图可认为是低维流形在高维空间里的离散近似值。基于图的代价函数最小化确保了流形上彼此临近的点被映射后在低维空间也彼此临近,
低维空间保持了局部距离。
embedder = manifold.SpectralEmbedding(n_components=2, random_state=0,eigen_solver="arpack")
t0 = time()
X_se = embedder.fit_transform(X)
plot_embedding_2d(X_se,"Spectral (time %.2fs)" %(time() - t0))
plt.show()
t-SNE
tsne = manifold.TSNE(n_components=3, init='pca', random_state=0)
t0 = time()
X_tsne = tsne.fit_transform(X)
print(X_tsne.shape)
plot_embedding_2d(X_tsne[:,0:2],"t-SNE 2D")
plot_embedding_3d(X_tsne,"t-SNE 3D (time %.2fs)" %(time() - t0))
plt.show()