TSNE-原理与实现

TSNE-数据可视化降维

项目地址:https://github.com/wchstrife/Information-Visualization-and-Visual-Analytics.git

一、运行

python tsne.py

二、算法原理

2.1 SNE原理

SNE即stochastic neighbor embedding,其基本思想为在高维空间相似的数据点,映射到低维空间距离也是相似的。SNE把这种距离关系转换为一种条件概率来表示相似性。

假设高维空间中有 x i x_i xi, x j x_j xj 两个点, p j ∣ i p_{j|i} pji 表示中心为 x i x_i xi 时, x j x_j xj是其近邻点的概率: x j x_j xj 越靠近 x i x_i xi其值越大,反之概率就越小。 p j ∣ i p_{j|i} pji采用高斯分布,公式如下:

p j ∣ i = e x p ( − ∣ ∣ x i − x j ∣ ∣ 2 / 2 σ i 2 ) ∑ k ≠ i e x p ( − ∣ ∣ x i − x k ∣ ∣ 2 / 2 σ i 2 ) p_{j|i} = \frac{exp(-||x_i - x_j||^2 / 2 \sigma^2_i)}{\sum_{k \neq i}exp(-||x_i - x_k||^2 / 2 \sigma^2_i)} pji=k=iexp(xixk2/2σi2)exp(xixj2/2σi2)

对于不同的中心 x i x_i xi,其对应的高斯分布的方差 σ \sigma σ也不同,需要对每个点进行计算。

同样对于高维空间的点 x i x_i xi, x j x_j xj映射为低维空间对应的点为 y i y_i yi, y j y_j yj,其概率分布函数 q j ∣ i q_{j|i} qji如下。在这里为了方便计算,假设所有点的 σ \sigma σ都为 1 2 \frac{1}{\sqrt{2}} 2 1

q j ∣ i = e x p ( − ∣ ∣ y i − y j ∣ ∣ 2 ) ∑ k ≠ i e x p ( − ∣ ∣ y i − y k ∣ ∣ 2 ) q_{j|i} = \frac{exp(-||y_i - y_j||^2) }{\sum_{k \neq i}exp(-||y_i - y_k||^2 )} qji=k=iexp(yiyk2)exp(yiyj2)

为了让高维空间的点映射到低维空间后,尽可能保持一样的分布,即原来离得近的点还离得近,离得远的点还离得远,所以要保证两个分布尽可能相似,这里用的衡量的方法就是采用KL(Kullback-Leibler Divergence)距离。

C = ∑ i K L ( P i ∣ ∣ Q i ) = ∑ i ∑ j p j ∣ i l o g p j ∣ i q j ∣ i C = \sum_i KL(P_i || Q_i) = \sum_i\sum_j p_{j|i} log\frac{p_{j|i}}{q_{j|i}} C=iKL(PiQi)=ijpjilogqjipji

现在问题转化了如何让上面的代价函数C最小。经典方法就是梯度下降法

δ C δ y i = 2 ∑ j ( p j ∣ i − q j ∣ i + p i ∣ j − q i ∣ j ) ( y i − y j ) \frac{\delta C}{\delta y_i} = 2\sum_j(p_{j|i} - q_{j|i} + p_{i|j} - q_{i|j})(y_i-y_j) δyiδC=2j(pjiqji+pijqij)(yiyj)

在进行梯度更新时,要注意Cost Function并不是一个凸函数,所以会存在很多的局部最优解,为了防止陷于局部最优解,还需要加上一个“动量”,可以冲出局部最优解。

Y t = Y t − 1 + η δ C δ y i + α ( t ) ( Y t − 1 − Y t − 2 ) Y^{t} = Y^{t-1} + \eta\frac{\delta C}{\delta y_i} + \alpha(t)(Y^{t-1} - Y^{t-2}) Yt=Yt1+ηδyiδC+α(t)(Yt1Yt2)

其中 Y t Y^{t} Yt表示t次迭代的结果, η \eta η是学习率, α ( t ) \alpha(t) α(t)表示第t次迭代时的动量。

此时还剩下一个问题没有解决:如何为不同的 x i x_i xi选择合适的 σ \sigma σ。这里提出叫做困惑度(perplexity)的概念,来表示 x i x_i xi附近的有效近邻点的个数,通常取5-50之间。

P e r p ( P i ) = 2 H ( P i ) Perp(P_i) = 2^{H(P_i)} Perp(Pi)=2H(Pi)

H ( P i ) = − ∑ j p j ∣ i l o g 2 p j ∣ i H(P_i)= - \sum_j {p_{j|i}}log_2{p_{j|i}} H(Pi)=jpjilog2pji

给定困惑度之后,使用二分搜索寻找一个最合适的 σ \sigma σ

但是需要注意一点时,KL距离具有不对称性

  1. p j ∣ i p_{j|i} pji越大, q j ∣ i q_{j|i} qji越小时,此时的Cost越高。即高维空间的点越接近,映射到低维空间时反而越远,此时的惩罚是很大的,这是正确的情况。
  2. p j ∣ i p_{j|i} pji越小, q j ∣ i q_{j|i} qji越大时,此时的Cost越小。即高维空间的点距离远时,映射到低维空间的点接近时,此时的惩罚却很小,这时跟我们想要的结果正好相反。

因此SNE倾向于保留局部特征,即让高维离得近的点尽可能在低维时聚在一起,但是不考虑不同类间的间隔,直观理解为:整个降维后的图像会比较“拥挤”。

2.2 t-SNE原理

t-SNE是在SNE的基础上进行了以下两点改进:

  • 使用对称SNE,简化梯度公式
  • 低维空间使用t分布取代高斯分布

我们先看改进1,将非对称的SNE改为对称的SNE。

在之前的条件分布概率中,是不对称的,例如高维空间中 p i ∣ j p_{i|j} pij是不等于 p j ∣ i p_{j|i} pji的,这与我们的直觉不符合,因为无论是 x i x_i xi还是 x j x_j xj谁作为中心点,其出现在对方附近的概率应该是相等的,所以我们应该设计一个联合概率分布,使得 p i j = p j i p_{ij} = p_{ji} pij=pji.

于是在高维、低维空间中,我们重新定义一下概率分布,注意除号下面部分与之前的区别:

p i j = e x p ( − ∣ ∣ x i − x j ∣ ∣ 2 ) ∑ k ≠ l e x p ( − ∣ ∣ x k − x l ∣ ∣ 2 ) p_{ij} = \frac{exp(-||x_i - x_j||^2) }{\sum_{k \neq l}exp(-||x_k - x_l||^2 )} pij=k=lexp(xkxl2)exp(xixj2)

q i j = e x p ( − ∣ ∣ y i − y j ∣ ∣ 2 ) ∑ k ≠ l e x p ( − ∣ ∣ y k − y l ∣ ∣ 2 ) q_{ij} = \frac{exp(-||y_i - y_j||^2) }{\sum_{k \neq l}exp(-||y_k - y_l||^2 )} qij=k=lexp(ykyl2)exp(yiyj2)

对于高维空间中的点,为了避免异常值的影响,采取以下方法定义高维空间的联合分布:

p i j = p i ∣ j + p i ∣ j 2 n p_{ij} = \frac{p_{i|j} + p_{i|j}}{2n} pij=2npij+pij

此时KL距离组成的损失函数如下:

C = K L ( P ∣ ∣ Q ) = ∑ i ∑ j p i j l o g P i j q i j C = KL(P||Q) = \sum_i \sum_j p_{ij}log\frac{P_{ij}}{q_{ij}} C=KL(PQ)=ijpijlogqijPij

梯度为:

δ C δ y i = 4 ∑ j ( p i j − q i j ) ( y i − y j ) \frac{\delta C}{\delta y_i} = 4\sum_j(p_{ij} - q_{ij})(y_i-y_j) δyiδC=4j(pijqij)(yiyj)

下面继续看t-SNE的第二个改进:低维空间用t分布替换高斯分布。这样做的好处是在低维的情况下,将同类的数据的距离减少,不同类间的距离拉大,这样可视化的效果会更好。

所以低维空间上的分布函数如下:

q i j = ( 1 + ∣ ∣ y i − y j ∣ ∣ 2 ) − 1 ∑ k ≠ l ( 1 + ∣ ∣ y k − y l ∣ ∣ 2 ) − 1 q_{ij} = \frac{(1+||y_i-y_j||^2)^{-1}}{\sum_{k \neq l}(1+||y_k-y_l||^2)^{-1}} qij=k=l(1+ykyl2)1(1+yiyj2)1

此时梯度如下:

δ C δ y i = 4 ∑ j ( p j i − q j i ) ( y i − y j ) ( 1 + ∣ y i − y j ∣ ∣ 2 ) − 1 \frac{\delta C}{\delta y_i} = 4\sum_j(p_{ji} - q_{ji})(y_i-y_j)(1+|y_i -y_j||^2)^{-1} δyiδC=4j(pjiqji)(yiyj)(1+yiyj2)1

三、算法实现

输入的数据为MNIST数据集中,抽取的2500条数据,每一条数据是784维,所以输入的规模为2500*784。

为了降低TSNE执行的复杂度,在进行TSNE之前,先通过PCA对数据进行降维,减少参数量,简化TSNE计算,否则实际的执行时间过长。

算法伪代码如下:

input data set X = {x1, x2, ..., xn}
input perplexity Perp
input iterations T, learning rate n, momentum a(t)

begin
    compute p_{j|i} with perplexity Perp
    compute P_{ij}
    initial y(0) = {y1, y2, ..., yn}

    for t = 1 to T 
        compute q_{ij}
        compute gradient
        update y(t)
    end
end

四、实验结果

在这里插入图片描述

五、参考文献

  1. Van der Maaten L, Hinton G. Visualizing data using t-SNE[J]. Journal of Machine Learning Research, 2008, 9(2579-2605): 85.
  • 15
    点赞
  • 136
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值