赞
踩
TSNE(t-Distributed Stochastic Neighbor Embedding )是对SNE的改进,SNE最早出现在2002年,改变了MDN和ISOMAP中基于距离不变的思想,将高维映射到低维的同时,尽量保证相互之间的分布概率不变,SNE将高维和低维中的样本分布都看作高斯分布,而TSNE将低维中的坐标当作T分布,这样的好处是为了让距离大的簇之间距离拉大,从而解决了拥挤问题。
将高维空间中的数据映射到低维空间中,并保留数据集的局部特性。当我们想对高维数据集进行分类,但又不清楚这个数据集有没有很好的可分性(同类之间间隔小、异类之间间隔大)时,可以通过t-SNE将数据投影到2维或3维空间中观察一下:如果在低维空间中具有可分性,则数据是可分的;如果在低维空间中不可分,则可能是因为数据集本身不可分,或者数据集中的数据不适合投影到低维空间。
占用内存较多、运行时间长,t-SNE的计算复杂度很高,在数百万个样本数据集中可能需要几个小时,而PCA可以在几秒钟或几分钟内完成。
算法是随机的,具有不同种子的多次实验可以产生不同的结果。虽然选择loss最小的结果就行,但可能需要多次实验以选择超参数。
当数据维数过高时,这两个矩阵的计算量是很大的。所以一般来说,我们会先用 PCA 降维到 10 维左右,再使用 t-SNE 降维到 2 或 3 维空间进行可视化。
tSNE实际上只能嵌入到2维或3维中,是一种降维和可视化技术。另外t-SNE的输出可以作为其他分类算法的输入特征。
t-SNE 更加注重保留原始数据的局部特征。
t-SNE:将数据点之间的相似度转换为概率。原始空间中的相似度由高斯联合概率表示,嵌入空间的相似度由“t分布”表示。
第一步:计算数据集中每行与其他行的距离(默认为欧式距离),转换为概率向量;
第二步:对每一行重复操作,得到概率矩阵;
第三步:沿两条新轴用t分布对数据随机化;
第四步:逐渐迭代,通过最小化KL散度,使得二维空间的新概率矩阵尽可能接近原高维空间的。
sklearn中文文档
流形学习降维:就是找到一个从流形到欧式空间的映射
局部线性嵌入(LLE)、等距离映射(Isomap)、多维标度法(MDS)
import numpy as np import matplotlib.pyplot as plt from sklearn import datasets from sklearn.manifold import TSNE # 加载数据 def get_data(): """ :return: 数据集、标签、样本数量、特征数量 """ digits = datasets.load_digits(n_class=10) data = digits.data # 图片特征 label = digits.target # 图片标签 n_samples, n_features = data.shape # 数据集的形状 return data, label, n_samples, n_features # 对样本进行预处理并画图 def plot_embedding(data, label, title): """ :param data:数据集 :param label:样本标签 :param title:图像标题 :return:图像 """ x_min, x_max = np.min(data, 0), np.max(data, 0) data = (data - x_min) / (x_max - x_min) # 对数据进行归一化处理 fig = plt.figure() # 创建图形实例 ax = plt.subplot(111) # 创建子图 # 遍历所有样本 for i in range(data.shape[0]): # 在图中为每个数据点画出标签 plt.text(data[i, 0], data[i, 1], str(label[i]), color=plt.cm.Set1(label[i] / 10), fontdict={'weight': 'bold', 'size': 7}) plt.xticks() # 指定坐标的刻度 plt.yticks() plt.title(title, fontsize=14) # 返回值 return fig # 主函数,执行t-SNE降维 def main(): data, label, n_samples, n_features = get_data() # 调用函数,获取数据集信息 print('Starting compute t-SNE Embedding...') ts = TSNE(n_components=2, init='pca', random_state=0) # t-SNE降维 reslut = ts.fit_transform(data) # 调用函数,绘制图像 fig = plot_embedding(reslut, label, 't-SNE Embedding of digits') # 显示图像 plt.show() # 主函数 if __name__ == '__main__': main()
那么既然有了 PCA,为什么我们还要去提出 t-SNE 呢?这就需要提到 PCA 的一个局限性。在降维的目的中,除了节约内存,还有一个最最重要的就是“对数据进行可视化”。我们希望将高维数据降维到 2 或 3 维,从而能够在图上直观地展现出来。
PCA 固然能够满足可视化的要求,但是人们发现,如果用 PCA 降维进行可视化,会出现所谓的“拥挤现象”。对于橙、蓝两类数据,如果我们用 PCA 降维后呈现在二维平面上,那么两类数据的边界并不明显,仿佛蓝色的数据“嵌入”了橙色数据一般。而反观右图,蓝色与橙色两类数据明显没有了交集。并且从右图中我们还能看出,数据点仿佛是每 4 个凝聚成一个“小团体”,每 4 个“小团体”凝聚中一个“中团体”,这表明 t-SNE 更加注重保留原始数据的局部特征。
from sklearn.manifold import TSNE from sklearn.datasets import load_iris,load_digits from sklearn.decomposition import PCA import matplotlib.pyplot as plt import os digits = load_digits() X_tsne = TSNE(n_components=2,random_state=33).fit_transform(digits.data) X_pca = PCA(n_components=2).fit_transform(digits.data) ckpt_dir="images" if not os.path.exists(ckpt_dir): os.makedirs(ckpt_dir) plt.figure(figsize=(10, 5)) plt.subplot(121) plt.scatter(X_tsne[:, 0], X_tsne[:, 1], c=digits.target,label="t-SNE") plt.legend() plt.subplot(122) plt.scatter(X_pca[:, 0], X_pca[:, 1], c=digits.target,label="PCA") plt.legend() plt.savefig('images/digits_tsne-pca.png', dpi=120) plt.show()
sklearn.manifold.TSNE(n_components=2, perplexity=30.0, early_exaggeration=12.0, learning_rate=200.0, n_iter=1000, n_iter_without_progress=300, min_grad_norm=1e-07, metric=’euclidean’, init=’random’, verbose=0, random_state=None, method=’barnes_hut’, angle=0.5)
n_components:int,可选(默认值:2)嵌入式空间的维度。
perplexity:float,可选(默认:30)较大的数据集通常需要更大的perplexity。考虑选择一个介于5和50之间的值。由于t-SNE对这个参数非常不敏感,所以选择并不是非常重要。
early_exaggeration:float,可选(默认值:4.0)这个参数的选择不是非常重要。
learning_rate:float,可选(默认值:1000)学习率可以是一个关键参数。它应该在100到1000之间。如果在初始优化期间成本函数增加,则早期夸大因子或学习率可能太高。如果成本函数陷入局部最小的最小值,则学习速率有时会有所帮助。
n_iter:int,可选(默认值:1000)优化的最大迭代次数。至少应该200。
n_iter_without_progress:int,可选(默认值:300,必须是50倍数)在我们中止优化之前,没有进展的最大迭代次数。
0.17新版功能:参数n_iter_without_progress控制停止条件。
min_grad_norm:float,可选(默认值:1E-7)如果梯度范数低于此阈值,则优化将被中止。
metric:字符串或可迭代的,可选,计算特征数组中实例之间的距离时使用的度量。如果度量标准是字符串,则它必须是scipy.spatial.distance.pdist为其度量标准参数所允许的选项之一,或者是成对列出的度量标准.PAIRWISE_DISTANCE_FUNCTIONS。如果度量是“预先计算的”,则X被假定为距离矩阵。或者,如果度量标准是可调用函数,则会在每对实例(行)上调用它,并记录结果值。可调用应该从X中获取两个数组作为输入,并返回一个表示它们之间距离的值。默认值是“euclidean”,它被解释为欧氏距离的平方。
init:字符串,可选(默认值:“random”)嵌入的初始化。可能的选项是“随机”和“pca”。 PCA初始化不能用于预先计算的距离,并且通常比随机初始化更全局稳定。
random_state:int或RandomState实例或None(默认)
伪随机数发生器种子控制。如果没有,请使用numpy.random单例。请注意,不同的初始化可能会导致成本函数的不同局部最小值。
method:字符串(默认:‘barnes_hut’)
默认情况下,梯度计算算法使用在O(NlogN)时间内运行的Barnes-Hut近似值。 method ='exact’将运行在O(N ^ 2)时间内较慢但精确的算法上。当最近邻的误差需要好于3%时,应该使用精确的算法。但是,确切的方法无法扩展到数百万个示例。0.17新版功能:通过Barnes-Hut近似优化方法。
angle:float(默认值:0.5)
仅当method ='barnes_hut’时才使用这是Barnes-Hut T-SNE的速度和准确性之间的折衷。 ‘angle’是从一个点测量的远端节点的角度大小(在[3]中称为theta)。如果此大小低于’角度’,则将其用作其中包含的所有点的汇总节点。该方法对0.2-0.8范围内该参数的变化不太敏感。小于0.2的角度会迅速增加计算时间和角度,因此0.8会快速增加误差。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。