t-SNE 演算法
前言
t-SNE(t-distributed stochastic neighbor embedding) 是用於降維的一種機器學習演算法,由 Laurens van der Maaten 和 Geoffrey Hinton在 08 年提出。t-SNE 作為一種非線性降維演算法,非常適用於高維資料降維到 2 維或者 3 維,便於進行視覺化。在實際應用中,t-SNE 很少用於降維,主要用於視覺化,可能的原因有以下幾方面:
- 當發現資料需要降維時,一般是特徵間存在高度的線性相關性,此時一般使用線性降維演算法,比如 PCA。即使是特徵之間存在非線性相關,也不會先使用非線性降維演算法降維之後再搭配一個線性的模型,而是直接使用非線性模型;
- 一般 t-SNE 都將資料降到 2 維或者 3 維進行視覺化,但是資料降維降的維度一般會大一些,比如需要降到 20 維,t-SNE 演算法使用自由度為 1 的 t 分佈很難做到好的效果,而關於如何選擇自由度的問題,目前沒有研究;
- t-SNE 演算法的計算複雜度很高,另外它的目標函式非凸,可能會得到區域性最優解;
在視覺化的應用中,t-SNE 的效果要好於 PCA,下面是對手寫數字視覺化的一個結果對比。對視覺化的效果衡量,無非是兩方面:相似的資料是不是離得近,不相似的資料是不是離得遠。從這兩方面來講,t-SNE 的效果要明顯優於 PCA。
SNE
基本思想
t-SNE 演算法由 SNE 改進而來,所以先來介紹 $\mathrm{SNE}_{\circ}$ 給定 $ \mathrm{n}$ 個高維資料 $ x_{1}, x_{2}, \ldots, x_{n} $,若將其降維至 2 維,SNE 的基本思想是若兩個資料在高維空間中是相似的,那麼降維至 2 維空間時它們應該離得很近。
相似性計算
SNE 使用條件概率來描述兩個資料之間的相似性,假設 $ x_{i}, x_{j}$ 是高維空間中的兩個點,那麼以點 $ x_{i}$ 為中心構建方差為 $ \sigma_{i}$ 的高斯分佈,使用 $ p_{j \mid i}$ 表示 $ x_{j}$ 是 $ x_{i}$ 鄰域的概率,如果 $ x_{j}$ 離 $ x_{i}$ 很近,那麼 $ p_{j \mid i}$ 很大,反之, $ p_{j \mid i}$ 很小,$ p_{j \mid i}$ 定義如下:
$p_{j \mid i}=\frac{\exp \left(-\left\|x_{i}-x_{j}\right\|^{2} /\left(2 \sigma_{i}^{2}\right)\right)}{\sum_{k \neq i} \exp \left(-\left\|x_{i}-x_{k}\right\|^{2} /\left(2 \sigma_{i}^{2}\right)\right)}$
由於只關心不同點對之間的相似度,所以設定 $p_{i \mid i}=0$ 。
當把資料對映到低維空間後,高維資料點之間的相似性也應該在低維空間的資料點上體現出來。這裡同樣用條件概率的形式描述,假設 $ x_{i}, x_{j}$ 對映到低維空間後對應 $ y_{i}, y_{j}$,$y_{j}$ 是 $ y_{i}$ 鄰域的條件概率為 $ q_{j \mid i}$ :
$q_{j \mid i}=\frac{\exp \left(-\left\|y_{i}-y_{j}\right\|^{2}\right)}{\sum \limits _{k \neq i} \exp \left(-\left\|y_{i}-y_{k}\right\|^{2}\right)}$
低維空間中的方差直接設定為 $ \sigma_{i}=\frac{1}{\sqrt{2}} $ ,方便計算,同樣 $q_{i \mid i}=0$ 。
目標函式
此時就很明朗了,若 $y_{i}$ 和 $y_{j}$ 真實反映了高維資料點 $x_{i}$ 和 $x_{j}$ 之間的關係,那麼條件概率 $p_{j \mid i}$ 與 $q_{j \mid} $ 應該完全相等。這裡我們只考慮了 $x_{i}$ 與 $x_{j}$ 之間的條件概率,若考慮 $x_{i}$ 與其他所有點之間的條件概率,則可構成一個條件概率分佈 $P_{i}$ , 同理在低維空間存在一個條件概率分佈 $Q_{i}$ 且應該與 $P_{i}$ 一致。如何衡量兩個分佈之間的相似性? 當然是用經典的 KL 距離(Kullback-Leibler Divergence),SNE 最終目標就是對所有資料點最小化這個 KL 距 離,我們可以使用梯度下降演算法最小化如下代價函式:
$C=\sum\limits_{i} K L\left(P_{i}|| Q_{i}\right)=\sum \limits _{i} \sum \limits_{j} p_{j \mid i} \log \frac{p_{j \mid i}}{q_{j \mid i}}$
似乎到這裡問題就漂亮的解決了,代價函式都寫出來了,剩下的事情就是利用梯度下降演算法進行訓練。但事情遠沒有那麼簡單,因為 KL 距離是一個非對稱的度量。最小化代價函式的目的是讓 $p_{j \mid i}$ 和 $q_{j \mid i}$ 的值儘可能的接近,即低維空間中點的相似性應當與高維空間中點的相似性一致。但是從代價函式的形式就可以看出,當 $p_{j \mid i}$ 較大,$q_{j \mid i}$ 較小時,代價較高;而 $p_{j \mid i}$ 較小,$ q_{j \mid i}$ 較大時,代價較低。什麼意思呢? 很顯然,高維空間中兩個資料點距離較近時,若對映到低維空間後距離較遠,那麼將得到一個很高的懲罰,這當然沒問題。反之,高維空間中兩個資料點距離較遠時,若對映到低維空間距離較近,將得到一個很低的懲罰值,這就有問題了,理應得到一個較高的懲罰才對。換句話說,SNE的代價函式更關注區域性結構,而忽視了全域性結構。
SNE缺點
通過以上的介紹,總結一下SNE的缺點:
- 不對稱導致梯度計算複雜,對目標函式計算梯度如下,由於條件概率 $p_{j \mid i}$ 不等於 $p_{i \mid j}$,$q_{j \mid i}$ 不等於 $q_{i \mid j} $,因此梯度計算中需要的計算量較大。
$\frac{\delta C}{\delta y_{i}}=2 \sum \limits _{j}\left(p_{j \mid i}-q_{j \mid i}+p_{i \mid j}-q_{i \mid j}\right)\left(y_{i}-y_{j}\right)$
這個梯度還有一定的物理意義,我們可以用分子之間的引力和斥力進行解釋。低維空間中點 $y_{i}$ 的位置是由其他所 有點對其作用力的合力所決定的。其中某個點 $y_{j}$ 對其作用力是沿著 $y_{i}-y_{j}$ 方向的,具體是引力還是斥力佔主導就 取決於 $y_{j}$ 與 $y_{i}$ 之間的距離了,其實就與 $\left(p_{j \mid i}-q_{j \mid i}+p_{i \mid j}-q_{i \mid j}\right)$ 這一項有關。
- Crowing 問題。就是不同類別的簇擠在一起,無法區分開來。擁擠問題的出現與某個特定演算法無關,而是由於高維空間距離分佈和低維空間距離分佈的差異造成的。比如有一種情況,高維度資料在降維到10維下,可以有很好的表達,但是降維到兩維後無法得到可信對映,比如降維如 10 維中有 11 個點之間兩兩等距離的,在二維下就無法得到可信的對映結果(最多3個點)。進一步的說明,假設一個以資料點 $x_i$ 為中心,半徑為 $r$ 的 $m$ 維球(三維空間就是球),其體積是按 $r^m$ 增長的,假設資料點是在m維球中均勻分佈的,我們來看看其他資料點與 $x_i$ 的距離隨維度增大而產生的變化。
從上圖可以看到,隨著維度的增大,大部分資料點都聚集在 $m$ 維球的表面附近,與點 $x_i$ 的距離分佈極不均衡。如果直接將這種距離關係保留到低維,就會出現擁擠問題。
View Codeimport matplotlib.pyplot as plt import numpy as np from numpy.linalg import norm npoints = 1000 # 抽取1000個m維球內均勻分佈的點 plt.figure(figsize=(20, 4)) for i, m in enumerate((2, 3, 5, 8)): # 這裡模擬m維球中的均勻分佈用到了拒絕取樣,即先生成m維立方中的均勻分佈,再剔除m維球外部的點 accepts = [] while len(accepts) < 1000: points = np.random.rand(500, m) accepts.extend([d for d in norm(points, axis=1) if d <= 1.0]) # 拒絕取樣 accepts = accepts[:npoints] ax = plt.subplot(1, 4, i+1) ax.set_xlabel('distance') # x軸表示點到圓心的距離 if i == 0: ax.set_ylabel('count') # y軸表示點的數量 ax.hist(accepts, bins=np.linspace(0., 1., 50), color='green') ax.set_title('m={0}'.format(str(m)), loc='left') plt.show()
t-SNE
SNE演算法的思路是不錯的,但是它的視覺化效果大家也看到了,存在很大改進空間。如何改進它呢?
對稱 SNE
原始 SNE 中,在高維空間中條件概率 $p_{j \mid i}$ 不等於 $p_{i \mid j}$ , 低維空間中 $q_{j \mid i}$ 不等於 $q_{i \mid j} $,於是提出對稱 $\mathrm{SNE} $,採用更加通用的聯合概率分佈代替原始的條件概率,使得 $p_{i j}=p_{j i}, \quad q_{i j}=q_{j i} $
優化 $p_{i} \mid j$ 和 $q_{i} \mid j$ 的 KL 散度的一種替換思路是,使用聯合概率分佈來替換條件概率分佈,即 $P$ 是高維空間裡各個點的聯合概率分佈, $Q$ 是低維 空間下的,目標函式為:
$C=K L(P \| Q)=\sum \limits_{i} \sum \limits _{j} p_{i, j} \log \frac{p_{i j}}{q_{i j}}$
簡單來講,在低維空間中定義 $ q_{i j} $ :
$q_{i j}=\frac{\exp \left(-\left\|y_{i}-y_{j}\right\|^{2}\right)}{\sum_{k \neq l} \exp \left(-\left\|y_{k}-y_{l}\right\|^{2}\right)}$
當然,在高維空間我們也可以定義 $p_{i j} $:
$p_{i j}=\frac{\exp \left(-\left\|x_{i}-x_{j}\right\|^{2} / 2 \sigma^{2}\right)}{\sum \limits_ {k \neq l} \exp \left(-\left\|x_{k}-x_{l}\right\|^{2} / 2 \sigma^{2}\right)}$
但是在高維空間中這樣的定義會帶來異常值的問題,怎麼理解呢? 假設點 $x_{i}$ 是一個噪聲點,那麼 $\left\|x_{i}-x_{j}\right\|$ 的平方會很大,那麼對於所有的 $\mathrm{j}, p_{i j}$ 的值都會很小,導致在低維對映下的 $y_{i}$ 對整個損失函式的影響很小,但對於異常值,我們顯然需要得到一個更大的懲罰,於是對高維空間中的聯合概率修正為:
$p_{i j}=\frac{p_{i l}+p_{p_{j i}}}{2}$
這樣就避免了異常值的問題,此時的梯度變為:
$\frac{\delta C}{\delta y_{i}}=4 \sum_{j}\left(p_{i j}-q_{i j}\right)\left(y_{i}-y_{j}\right)$
相比於原始 SNE,對稱 SNE 的梯度更加簡化,計算效率更高。但對稱SNE的效果只是略微優於原始SNE的效果。
引入 t 分佈
$t$-分佈(t-distribution)用於根據小樣本來估計呈正態分佈且方差未知的總體的均值。如果總體方差已知(例如在樣本數量足夠多時),則應該用正態分佈來估計總體均值。
$t$分佈曲線形態與 $n$(確切地說與自由度df)大小有關。與標準正態分佈曲線相比,自由度 df 越小,$t$ 分佈曲線愈平坦,曲線中間愈低,曲線雙側尾部翹得愈高;自由度 df 愈大,$t$ 分佈曲線愈接近正態分佈曲線,當自由度 $df=∞$ 時,$t$分佈曲線為標準正態分佈曲線。
假設 $X$ 服從標準正態分佈 $N (0,1)$, $Y$ 服從 $ \chi^{2}(n) $分佈, 那麼 $Z=\frac{X}{\sqrt{Y / n}} $ 的分佈稱為自由度為 $n$ 的分佈,記為 $Z \sim t(n) $ 。
分佈密度函式 $f_{Z}(x)=\frac{\operatorname{Gam}\left(\frac{n+1}{2}\right)}{\sqrt{n \pi} \operatorname{Gam}\left(\frac{n}{2}\right)}\left(1+\frac{x^{2}}{n}\right)^{-\frac{n+1}{2}} $
其中,$ \operatorname{Gam}(\mathrm{x}) $ 為伽馬函式。
對稱SNE實際上在高維度下 另外一種減輕”擁擠問題”的方法:在高維空間下,在高維空間下我們使用高斯分佈將距離轉換為概率分佈,在低維空間下,我們使用更加偏重長尾分佈的方式來將距離轉換為概率分佈,使得高維度下中低等的距離在對映後能夠有一個較大的距離。
t 分佈是一種長尾分佈,從圖中可以看到,在沒有異常點時,t 分佈與高斯分佈的擬合結果基本一致。而在第二張圖中,出現了部分異常點,由於高斯分佈的尾部較低,對異常點比較敏感,為了照顧這些異常點,高斯分佈的擬合結果偏離了大多數樣本所在位置,方差也較大。相比之下,t 分佈的尾部較高,對異常點不敏感,保證了其魯棒性,因此其擬合結果更為合理,較好的捕獲了資料的整體特徵。
那麼如何利用 t 分佈的長尾性來改進 SNE 呢?看下圖,注意這個圖並不準確,主要是為了說明 t 分佈是如何發揮作用的。
圖中有高斯分佈和 $\mathrm{t}$ 分佈兩條曲線,表示點之間的相似性與距離的關係,高斯分佈對應高維空間,$\mathrm{t}$ 分佈對應低維空間。那麼對於高維空間中相距較近的點,為了滿足 $p_{i j}=q_{i j}$ , 低維空間中的距離需要稍小一點; 而對於高維空間中相距較遠的點,為了滿足 $p_{i j}=q_{i j} $, 低維空 間中的距離需要更遠。這恰好滿足了我們的需求,即同一簇內的點(距離較近)聚合的更緊密,不同簇之間的點(距離較遠)更加疏遠。
引入 t 分佈之後,在低維空間中,用自由度為 1 的 t 分佈重新定義 :
$q_{i j}=\frac{\left(1+\left\|y_{i}-y_{j}\right\|^{2}\right)^{-1}}{\sum \limits _{k \neq l}\left(1+\left\|y_{i}-y_{j}\right\|^{2}\right)^{-1}}$
然後與原始 SNE 一樣,我們使用 K-L 散度定義目標函式進行優化,從而求解。至此,關於 t-SNE 演算法的原理部分,我們就介紹完了。
t-SNE 演算法過程
- $Data: X=x_{1}, \ldots, x_{n}$
- 計算 cost function 的引數: 困惑度 Perp
- 優化引數:設定迭代次數 $ \mathrm{T}$ , 學習速率$ \eta$ ,動量 $ \alpha(t)$
- 目標結果是低維資料表示 $ Y^{T}=y_{1}, \ldots, y_{n}$
- 開始優化 結束結束
- 計算在給定 Perp下的條件概率 $ p_{j \mid i}$ (參見上面公式)
- 令 $ p_{i j}=\frac{p_{j\left|i+p_{i}\right| j}}{2 n}$
- 用 $ N\left(0,10^{-4} I\right)$ 隨機初始化 $ \mathrm{Y}$
- 迭代,從 $ \mathrm{t}=1$ 到 $ \mathrm{T}$, 做如下操作:
- 計算低維度下的 $ q_{i j}$ (參見上面的公式)
- 計算梯度(參見上面的公式)
- 更新 $ Y^{t}=Y^{t-1}+\eta \frac{d C}{d Y}+\alpha(t)\left(Y^{t-1}-Y^{t-2}\right)$
- 結束
優化過程中可以嘗試的兩個 trick:
- 提前壓縮 (ear1y compression) : 開始初始化的時候,各個點要離得近一點。這樣小的距離,方便各個聚類中心的移動。可以通過引入 $L2$ 正則項 (距離的平方和) 來實現。
- 提前誇大(ear1y exaggeration):在開始優化階段, $ p_{i j}$ 乘以一個大於 1 的數進行擴大, 來避免因為 $ q_{i j}$ 太小導致優化太慢的問題。比如前 50 次迭代, $ p_{i j} $ 乘以 4。
優化的過程動態圖如下:
不足
主要不足有四個:
- 主要用於視覺化,很難用於其他目的。比如測試集合降維,因為他沒有顯式的預估部分,不能在測試集合直接降維;比如降維到10維,因為 t 分佈偏重長尾,1個自由度的t分佈很難儲存好區域性特徵,可能需要設定成更高的自由度。
- t-SNE 傾向於儲存區域性特徵,對於本徵維數(intrinsic dimensionality)本身就很高的資料集,是不可能完整的對映到 2-3 維的空間
- t-SNE 沒有唯一最優解,且沒有預估部分。如果想要做預估,可以考慮降維之後,再構建一個迴歸方程之類的模型去做。但是要注意,t-SNE中距離本身是沒有意義,都是概率分佈問題。
- 訓練太慢。有很多基於樹的演算法在 t-SNE 上做一些改進