Python-深度学习-学习笔记(17):利用t-SNE对数据实现降维聚类

Python-深度学习-学习笔记(17):利用t-SNE对数据实现降维聚类

一、引言

由于现有的算法还不够智能,所以必须依靠人类的智慧介入分析。所以,需要通过可视化技术把高维空间中的数据以二维或三维的形式展现出来便于我们观看,展示的效果如何也就直接决定着我们分析的难度。

二、降维

降维的目的其实是将高维度下的特征能够通过某种方式降到低维度下,并且保留不同类的特征所体现出的不同规律,或者可以说是用低维度特征来表示高维度下的特征。将数据或特征的维数降低,一般分为线性降维和非线性降维:

  1. 线性降维:PCA(Principal Components Analysis)、LDA(Linear Discriminant Analysis)、MDS(Classical Multidimensional Scaling)
  2. 非线性降维:Isomap(Isometric Mapping)、LLE(Locally Linear Embedding)、LE(Laplacian Eigenmaps)大家可能对线性降维中的一些方法比较熟悉了,但是对非线性降维并不了解,非线性降维中用到的方法大多属于流形学习方法。

三、聚类

将物理或抽象对象的集合分成由类似的对象组成的多个类的过程被称为聚类。由聚类所生成的簇是一组数据对象的集合,这些对象与同一个簇中的对象彼此相似,与其他簇中的对象相异。说白了就是“物以类聚,人以群分”,在自然科学和社会科学中,存在着大量的分类问题。聚类分析又称群分析,它是研究(样品或指标)分类问题的一种统计分析方法。

四、t-SNE

4.1 t分布

Python-深度学习-学习笔记(17):利用t-SNE对数据实现降维聚类_第1张图片
从图中可以看出,t分布比正态分布要“胖一些”,尤其是尾部两端较为平缓。t分布是一种典型的长尾分布。

4.2 SNE

SNE即stochastic neighbor embedding,是Hinton在2002年提出来的一个算法,出发点很简单:在高维空间相似的数据点,映射到低维空间距离也是相似的。常规的做法是用欧式距离表示这种相似性,而SNE把这种距离关系转换为一种条件概率来表示相似性。
欧几里得度量(euclidean metric)(也称欧氏距离)是一个通常采用的距离定义,指在m维空间中两个点之间的真实距离,或者向量的自然长度(即该点到原点的距离)。在二维和三维空间中的欧氏距离就是两点之间的实际距离。
Python-深度学习-学习笔记(17):利用t-SNE对数据实现降维聚类_第2张图片
Python-深度学习-学习笔记(17):利用t-SNE对数据实现降维聚类_第3张图片
由于KL距离是一个非线性的度量,最小化代价函数的目的是让pj|iqj|i的值尽可能的接近,即低维空间中点的相似性应与高维空间中点的相似性一致。而SNE的代价函数更关注局部结构,忽略了全局结构。
SNE做的说白了就是将高维下不同类的特征体现出了不同的距离,我们将这个距离对应为一个概率,那么高维是pj|i,低维是qj|i,降维之后要求概率对应相等也就是高维体现的特征在进行降维之后仍保留其特征,只不过是用2维或3维的形式表示出来,便于可视化。

4.3 t-SNE

t-SNE(t分布随机邻域嵌入)是一种用于探索高维数据的非线性降维算法。它将多维数据映射到适合于人类观察的两个或多个维度。
t-SNE主要包括两个步骤:

  1. t-SNE构建一个高维对象之间的概率分布,使得相似的对象有更高的概率被选择,而不相似的对象有较低的概率被选择。
  2. t-SNE在低维空间里在构建这些点的概率分布,使得这两个概率分布之间尽可能的相似(这里使用KL散度(Kullback–Leibler divergence)来度量两个分布之间的相似性)。

我们看到t-SNE模型是非监督的降维,他跟kmeans等不同,他不能通过训练得到一些东西之后再用于其它数据(比如kmeans可以通过训练得到k个点,再用于其它数据集,而t-SNE只能单独的对数据做操作,也就是说他只有fit_transform,而没有fit操作)

同时t-SNE还解决了拥挤问题:对于高维空间中相距较近的点,为了满足pij=qij,低维空间中的距离需要稍小一点;而对于高维空间中相距较远的点,为了满足pij=qij,低维空间中的距离需要更远。
这恰好满足了我们的需求,即同一簇内的点(距离较近)聚合的更紧密,不同簇之间的点(距离较远)更加疏远。
再利用随机梯度下降算法训练即可。

这就是所谓的t-SNE算法,总结一下其实就是在SNE的基础上增加了两个改进:一是把SNE变为对称SNE,二是在低维空间中采用了t分布代替原来的高斯分布,高维空间不变。

下面是T-SNE算法步骤:
Python-深度学习-学习笔记(17):利用t-SNE对数据实现降维聚类_第4张图片
Python-深度学习-学习笔记(17):利用t-SNE对数据实现降维聚类_第5张图片
Python-深度学习-学习笔记(17):利用t-SNE对数据实现降维聚类_第6张图片
除t-SNE之外的大多数非线性技术都不能同时保留数据的局部和全局结构。

下面是我简单的代码实现:

from time import time
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.manifold import TSNE
import h5py
#导入训练所需的数据集
path = r'E:\my_work\研究生资料\项目2-水下目标分类识别\水下目标分类识别\数据集\1D\DemonData_1chn_max.mat'
data = h5py.File(path)
X_data = np.transpose(data['X_data'])
Y_data = np.transpose(data['Y_data'])
del data
print('data has been imported!')
index=np.random.permutation(21000)
X_data = X_data*100
X_data = X_data[index]
Y_data = Y_data[index]
Y_data = Y_data -1
X_data = X_data[0:21000,:]
Y_data = Y_data[0:21000,:]
Y_data = Y_data.reshape(21000,).astype(int)
"""
    n_components:嵌入式空间的维度(默认为2)
    init:初始化方式
    random_state:随机种子,None默认
"""
tsne = TSNE(n_components=2,init='pca',random_state=500)
t0 = time()
result = tsne.fit_transform(X_data)
print(result.shape)
result
x_min,x_max = np.min(result,0),np.max(result,0) #每列中的最小值和最大值
data = (result-x_min)/(x_max-x_min)#归一化
print(x_min)
print(x_max)
print('----')
print(data)
fig = plt.figure(figsize=(10,7))
# 表示画布整个输出,不分割成小块区域,图形直接输出在整块画布上
# print(data.shape[0])
for i in range(data.shape[0]):
    plt.text(data[i,0],data[i,1],str(Y_data[i]),color=plt.cm.Set1(Y_data[i]),fontdict={'weight':'bold','size':9})
plt.xticks([])
plt.yticks([])
plt.title('t-SNE embedding of the digits')
plt.show()

Python-深度学习-学习笔记(17):利用t-SNE对数据实现降维聚类_第7张图片
更加详细的内容请参考

http://bindog.github.io/blog/2016/06/04/from-sne-to-tsne-to-largevis/

你可能感兴趣的:(Python系列,t-SNE,SNE,t分布,降维)