今天我们讨论数据可视化(data visualization)算法t-SNE (t-distributed Stochastic Neighbor Embedding),该方法的目的是映射高维数据向量到低维,并保留向量的相似性或者距离。通常我们描述距离会使用类似欧式距离或黎曼距离等概念,映射的方法也多为线性,如PCA。而t-SNE不同,它是用联合概率来描述样本点的相似程度,是非线性的。

SNE算法最早由 Hinton & Roweis 在2002年提出。他们定义高维空间两个点相似度的联合概率分布,和要映射到的低维空间对应两点的联合概率. 利用Kullback-Leibler divergence衡量分布$P$和$Q$的相似性,进而最小化这一距离来确定低维空间的映射点.

考虑到SNE算法存在三个缺陷,

  1. KL-divergence 不是对称的;
  2. 从高维空间映射到低维空间,距离会发生变化;
  3. 高斯分布不是长尾的,对小概率的异常点描述能力较差;

为了解决这一问题,Van der Maaten & Hinton 在2008年提出了改进算法,利用自由度为1的t分布替换高斯分布来定义低维空间的距离,避免异常点,保留高维空间两点的距离关系;设计了具有对称性的概率分布函数。最后,分布$P$和$Q$,KL-divergence $\mathrm{KL}$ 以及对应的梯度公式如下,

高维空间分布$P$

其中,表示接受为其同类点的条件概率,相应的由下式给出,

其中$N$表示样本点的个数。

低维空间分布$Q$
KL-divergence
partial difference of KL over $\bf{y_i}$

基于以上公式,利用梯度进行优化,求解局部最优,即可对$\bf{y_i}$进行定位。

t-SNE的python实现

python的Scikit-learn提供了TSNE类,用于自动化实现数据可视化,代码样例如下,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from sklearn.manifold import TSNE
def dimension_reduction_tSNE(code,params=None):
tsne = TSNE()
for key in params.keys():
try:
setattr(tsne, key, params['key'])
except:
continue
code_dim = tsne.fit_transform(code)
return code_dim
code = xxx
params={'n_components': 2, 'learning_rate': 100}
code_dim = dimension_reduction_tSNE(code, params)

其中code表示高维空间的样本矩阵,每行对应一个样本。参数params里的n_components表示低维空间的维数。

References