t-SNE完整筆記


http://www.datakit.cn/blog/2017/02/05/t_sne_full.html

t-SNE(t-distributed stochastic neighbor embedding)是用於降維的一種機器學習算法,是由 Laurens van der Maaten 和 Geoffrey Hinton在08年提出來。此外,t-SNE 是一種非線性降維算法,非常適用於高維數據降維到2維或者3維,進行可視化。

t-SNE是由SNE(Stochastic Neighbor Embedding, SNE; Hinton and Roweis, 2002)發展而來。我們先介紹SNE的基本原理,之后再擴展到t-SNE。最后再看一下t-SNE的實現以及一些優化。

目錄

1.SNE

1.1基本原理

SNE是通過仿射(affinitie)變換將數據點映射到概率分布上,主要包括兩個步驟:

  • SNE構建一個高維對象之間的概率分布,使得相似的對象有更高的概率被選擇,而不相似的對象有較低的概率被選擇。
  • SNE在低維空間里在構建這些點的概率分布,使得這兩個概率分布之間盡可能的相似。

我們看到t-SNE模型是非監督的降維,他跟kmeans等不同,他不能通過訓練得到一些東西之后再用於其它數據(比如kmeans可以通過訓練得到k個點,再用於其它數據集,而t-SNE只能單獨的對數據做操作,也就是說他只有fit_transform,而沒有fit操作)

1.2 SNE原理推導

SNE是先將歐幾里得距離轉換為條件概率來表達點與點之間的相似度。具體來說,給定一個N個高維的數據 x1,...,xNx1,...,xN(注意N不是維度), t-SNE首先是計算概率pijpij,正比於xixi和xjxj之間的相似度(這種概率是我們自主構建的),即:

pji=exp(∣∣xixj2/(2σ2i))kiexp(∣∣xixk2/(2σ2i))pj∣i=exp⁡(−∣∣xi−xj∣∣2/(2σi2))∑k≠iexp⁡(−∣∣xi−xk∣∣2/(2σi2))

這里的有一個參數是σiσi,對於不同的點xixi取值不一樣,后續會討論如何設置。此外設置pxx=0px∣x=0,因為我們關注的是兩兩之間的相似度。

那對於低維度下的yiyi,我們可以指定高斯分布為方差為12√12,因此它們之間的相似度如下:

qji=exp(∣∣xixj2)kiexp(∣∣xixk2)qj∣i=exp⁡(−∣∣xi−xj∣∣2)∑k≠iexp⁡(−∣∣xi−xk∣∣2)

同樣,設定qii=0qi∣i=0.

如果降維的效果比較好,局部特征保留完整,那么 pij=qijpi∣j=qi∣j, 因此我們優化兩個分布之間的距離-KL散度(Kullback-Leibler divergences),那么目標函數(cost function)如下:

C=iKL(Pi∣∣Qi)=ijpjilogpjiqjiC=∑iKL(Pi∣∣Qi)=∑i∑jpj∣ilog⁡pj∣iqj∣i

這里的PiPi表示了給定點xixi下,其他所有數據點的條件概率分布。需要注意的是KL散度具有不對稱性,在低維映射中不同的距離對應的懲罰權重是不同的,具體來說:距離較遠的兩個點來表達距離較近的兩個點會產生更大的cost,相反,用較近的兩個點來表達較遠的兩個點產生的cost相對較小(注意:類似於回歸容易受異常值影響,但效果相反)。即用較小的 qji=0.2qj∣i=0.2 來建模較大的 pji=0.8pj∣i=0.8, cost=plog(pq)plog⁡(pq)=1.11,同樣用較大的qji=0.8qj∣i=0.8來建模較大的pji=0.2pj∣i=0.2, cost=-0.277, 因此,SNE會傾向於保留數據中的局部特征

思考:了解了基本思路之后,你會怎么選擇σσ,固定初始化?

下面我們開始正式的推導SNE。首先不同的點具有不同的σiσi,PiPi的熵(entropy)會隨着σiσi的增加而增加。SNE使用困惑度(perplexity)的概念,用二分搜索的方式來尋找一個最佳的σσ。其中困惑度指:

Perp(Pi)=2H(Pi)Perp(Pi)=2H(Pi)

這里的H(Pi)H(Pi)是PiPi的熵,即:

H(Pi)=jpjilog2pjiH(Pi)=−∑jpj∣ilog2⁡pj∣i

困惑度可以解釋為一個點附近的有效近鄰點個數。SNE對困惑度的調整比較有魯棒性,通常選擇5-50之間,給定之后,使用二分搜索的方式尋找合適的σσ

那么核心問題是如何求解梯度了,目標函數等價於plog(q)∑∑−plog(q)這個式子與softmax非常的類似,我們知道softmax的目標函數是ylogp∑−ylog⁡p,對應的梯度是ypy−p(注:這里的softmax中y表示label,p表示預估值)。 同樣我們可以推導SNE的目標函數中的i在j下的條件概率情況的梯度是2(pijqij)(yiyj)2(pi∣j−qi∣j)(yi−yj), 同樣j在i下的條件概率的梯度是2(pjiqji)(yiyj)2(pj∣i−qj∣i)(yi−yj), 最后得到完整的梯度公式如下:

δCδyi=2j(pjiqji+pijqij)(yiyj)δCδyi=2∑j(pj∣i−qj∣i+pi∣j−qi∣j)(yi−yj)

在初始化中,可以用較小的σσ下的高斯分布來進行初始化。為了加速優化過程和避免陷入局部最優解,梯度中需要使用一個相對較大的動量(momentum)。即參數更新中除了當前的梯度,還要引入之前的梯度累加的指數衰減項,如下:

Y(t)=Y(t1)+ηδCδY+α(t)(Y(t1)Y(t2))Y(t)=Y(t−1)+ηδCδY+α(t)(Y(t−1)−Y(t−2))

這里的Y(t)Y(t)表示迭代t次的解,ηη表示學習速率,α(t)α(t)表示迭代t次的動量。

此外,在初始優化的階段,每次迭代中可以引入一些高斯噪聲,之后像模擬退火一樣逐漸減小該噪聲,可以用來避免陷入局部最優解。因此,SNE在選擇高斯噪聲,以及學習速率,什么時候開始衰減,動量選擇等等超參數上,需要跑多次優化才可以。

思考:SNE有哪些不足? 面對SNE的不足,你會做什么改進?

2.t-SNE

盡管SNE提供了很好的可視化方法,但是他很難優化,而且存在”crowding problem”(擁擠問題)。后續中,Hinton等人又提出了t-SNE的方法。與SNE不同,主要如下:

  • 使用對稱版的SNE,簡化梯度公式
  • 低維空間下,使用t分布替代高斯分布表達兩點之間的相似度

t-SNE在低維空間下使用更重長尾分布的t分布來避免crowding問題和優化問題。在這里,首先介紹一下對稱版的SNE,之后介紹crowding問題,之后再介紹t-SNE。

2.1 Symmetric SNE

優化pijpi∣j和qijqi∣j的KL散度的一種替換思路是,使用聯合概率分布來替換條件概率分布,即P是高維空間里各個點的聯合概率分布,Q是低維空間下的,目標函數為:

C=KL(P∣∣Q)=ijpi,jlogpijqijC=KL(P∣∣Q)=∑i∑jpi,jlog⁡pijqij

這里的piipii,qiiqii為0,我們將這種SNE稱之為symmetric SNE(對稱SNE),因為他假設了對於任意i,pij=pji,qij=qjipij=pji,qij=qji,因此概率分布可以改寫為:

pij=exp(∣∣xixj2/2σ2)klexp(∣∣xkxl2/2σ2)    qij=exp(∣∣yiyj2)klexp(∣∣ykyl2)pij=exp⁡(−∣∣xi−xj∣∣2/2σ2)∑k≠lexp⁡(−∣∣xk−xl∣∣2/2σ2)    qij=exp⁡(−∣∣yi−yj∣∣2)∑k≠lexp⁡(−∣∣yk−yl∣∣2)

這種表達方式,使得整體簡潔了很多。但是會引入異常值的問題。比如xixi是異常值,那么xixj2∣∣xi−xj∣∣2會很大,對應的所有的j, pijpij都會很小(之前是僅在xixi下很小),導致低維映射下的yiyi對cost影響很小。

思考: 對於異常值,你會做什么改進?pipi表示什么?

為了解決這個問題,我們將聯合概率分布定義修正為: pij=pij+pji2pij=pi∣j+pj∣i2, 這保證了jpij>12n∑jpij>12n, 使得每個點對於cost都會有一定的貢獻。對稱SNE的最大優點是梯度計算變得簡單了,如下:

δCδyi=4j(pijqij)(yiyj)δCδyi=4∑j(pij−qij)(yi−yj)

實驗中,發現對稱SNE能夠產生和SNE一樣好的結果,有時甚至略好一點。

2.2 Crowding問題

擁擠問題就是說各個簇聚集在一起,無法區分。比如有一種情況,高維度數據在降維到10維下,可以有很好的表達,但是降維到兩維后無法得到可信映射,比如降維如10維中有11個點之間兩兩等距離的,在二維下就無法得到可信的映射結果(最多3個點)。 進一步的說明,假設一個以數據點xixi為中心,半徑為r的m維球(三維空間就是球),其體積是按rmrm增長的,假設數據點是在m維球中均勻分布的,我們來看看其他數據點與xixi的距離隨維度增大而產生的變化。

show png

從上圖可以看到,隨着維度的增大,大部分數據點都聚集在m維球的表面附近,與點xixi的距離分布極不均衡。如果直接將這種距離關系保留到低維,就會出現擁擠問題。

怎么解決crowding問題呢?

Cook et al.(2007) 提出一種slight repulsion的方式,在基線概率分布(uniform background)中引入一個較小的混合因子ρρ,這樣qijqij就永遠不會小於2ρn(n1)2ρn(n−1) (因為一共了n(n-1)個pairs),這樣在高維空間中比較遠的兩個點之間的qijqij總是會比pijpij大一點。這種稱之為UNI-SNE,效果通常比標准的SNE要好。優化UNI-SNE的方法是先讓ρρ為0,使用標准的SNE優化,之后用模擬退火的方法的時候,再慢慢增加ρρ. 直接優化UNI-SNE是不行的(即一開始ρρ不為0),因為距離較遠的兩個點基本是一樣的qijqij(等於基線分布), 即使pijpij很大,一些距離變化很難在qijqij中產生作用。也就是說優化中剛開始距離較遠的兩個聚類點,后續就無法再把他們拉近了。

2.3 t-SNE

對稱SNE實際上在高維度下 另外一種減輕”擁擠問題”的方法:在高維空間下,在高維空間下我們使用高斯分布將距離轉換為概率分布,在低維空間下,我們使用更加偏重長尾分布的方式來將距離轉換為概率分布,使得高維度下中低等的距離在映射后能夠有一個較大的距離。

show png

我們對比一下高斯分布和t分布(如上圖,code見probability/distribution.md), t分布受異常值影響更小,擬合結果更為合理,較好的捕獲了數據的整體特征。

使用了t分布之后的q變化,如下:

qij=(1+∣∣yiyj2)1kl(1+∣∣yiyj2)1qij=(1+∣∣yi−yj∣∣2)−1∑k≠l(1+∣∣yi−yj∣∣2)−1

此外,t分布是無限多個高斯分布的疊加,計算上不是指數的,會方便很多。優化的梯度如下:

δCδyi=4j(pijqij)(yiyj)(1+∣∣yiyj2)1δCδyi=4∑j(pij−qij)(yi−yj)(1+∣∣yi−yj∣∣2)−1

t-sne的有效性,也可以從上圖中看到:橫軸表示距離,縱軸表示相似度, 可以看到,對於較大相似度的點,t分布在低維空間中的距離需要稍小一點;而對於低相似度的點,t分布在低維空間中的距離需要更遠。這恰好滿足了我們的需求,即同一簇內的點(距離較近)聚合的更緊密,不同簇之間的點(距離較遠)更加疏遠。

總結一下,t-SNE的梯度更新有兩大優勢:

  • 對於不相似的點,用一個較小的距離會產生較大的梯度來讓這些點排斥開來。
  • 這種排斥又不會無限大(梯度中分母),避免不相似的點距離太遠。

2.4 算法過程

算法詳細過程如下:

  • Data: X=x1,...,xnX=x1,...,xn
  • 計算cost function的參數:困惑度Perp
  • 優化參數: 設置迭代次數T, 學習速率ηη, 動量α(t)α(t)
  • 目標結果是低維數據表示 YT=y1,...,ynYT=y1,...,yn
  • 開始優化
    • 計算在給定Perp下的條件概率pjipj∣i(參見上面公式)
    • 令 pij=pji+pij2npij=pj∣i+pi∣j2n
    • 用 N(0,104I)N(0,10−4I) 隨機初始化 Y
    • 迭代,從 t = 1 到 T, 做如下操作:
      • 計算低維度下的 qijqij(參見上面的公式)
      • 計算梯度(參見上面的公式)
      • 更新 Yt=Yt1+ηdCdY+α(t)(Yt1Yt2)Yt=Yt−1+ηdCdY+α(t)(Yt−1−Yt−2)
    • 結束
  • 結束

優化過程中可以嘗試的兩個trick:

  • 提前壓縮(early compression):開始初始化的時候,各個點要離得近一點。這樣小的距離,方便各個聚類中心的移動。可以通過引入L2正則項(距離的平方和)來實現。
  • 提前誇大(early exaggeration):在開始優化階段,pijpij乘以一個大於1的數進行擴大,來避免因為qijqij太小導致優化太慢的問題。比如前50次迭代,pijpij乘以4

優化的過程動態圖如下:

optimise

2.5 不足

主要不足有四個:

  • 主要用於可視化,很難用於其他目的。比如測試集合降維,因為他沒有顯式的預估部分,不能在測試集合直接降維;比如降維到10維,因為t分布偏重長尾,1個自由度的t分布很難保存好局部特征,可能需要設置成更高的自由度。
  • t-SNE傾向於保存局部特征,對於本征維數(intrinsic dimensionality)本身就很高的數據集,是不可能完整的映射到2-3維的空間
  • t-SNE沒有唯一最優解,且沒有預估部分。如果想要做預估,可以考慮降維之后,再構建一個回歸方程之類的模型去做。但是要注意,t-sne中距離本身是沒有意義,都是概率分布問題。
  • 訓練太慢。有很多基於樹的算法在t-sne上做一些改進

3.變種

后續有機會補充。

  • multiple maps of t-SNE
  • parametric t-SNE
  • Visualizing Large-scale and High-dimensional Data

4.參考文檔

  • Maaten, L., & Hinton, G. (2008). Visualizing data using t-SNE. Journal of Machine Learning Research.

5. 代碼

文中的插圖繪制:

# coding:utf-8 import numpy as np from numpy.linalg import norm from matplotlib import pyplot as plt plt.style.use('ggplot') def sne_crowding(): npoints = 1000 # 抽取1000個m維球內均勻分布的點 plt.figure(figsize=(20, 5)) 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) if i == 0: ax.set_ylabel('count') if i == 2: ax.set_xlabel('distance') ax.hist(accepts, bins=np.linspace(0., 1., 50)) ax.set_title('m=%s' %m) plt.savefig("./images/sne_crowding.png") x = np.linspace(0, 4, 100) ta = 1 / (1 + np.square(x)) tb = np.sum(ta) - 1 qa = np.exp(-np.square(x)) qb = np.sum(qa) - 1 def sne_norm_t_dist_cost(): plt.figure(figsize=(8, 5)) plt.plot(qa/qb, c="b", label="normal-dist") plt.plot(ta/tb, c="g", label="t-dist") plt.plot((0, 20), (0.025, 0.025), 'r--') plt.text(10, 0.022, r'$q_{ij}$') plt.text(20, 0.026, r'$p_{ij}$') plt.plot((0, 55), (0.005, 0.005), 'r--') plt.text(36, 0.003, r'$q_{ij}$') plt.text(55, 0.007, r'$p_{ij}$') plt.title("probability of distance") plt.xlabel("distance") plt.ylabel("probability") plt.legend() plt.savefig("./images/sne_norm_t_dist_cost.png") if __name__ == '__main__': sne_crowding() sne_norm_t_dist_cost() 

附錄一下t-sne的完整代碼實現:

# coding utf-8 ''' 代碼參考了作者Laurens van der Maaten的開放出的t-sne代碼, 並沒有用類進行實現,主要是優化了計算的實現 ''' import numpy as np def cal_pairwise_dist(x): '''計算pairwise 距離, x是matrix (a-b)^2 = a^w + b^2 - 2*a*b ''' sum_x = np.sum(np.square(x), 1) dist = np.add(np.add(-2 * np.dot(x, x.T), sum_x).T, sum_x) return dist def cal_perplexity(dist, idx=0, beta=1.0): '''計算perplexity, D是距離向量, idx指dist中自己與自己距離的位置,beta是高斯分布參數 這里的perp僅計算了熵,方便計算 ''' prob = np.exp(-dist * beta) # 設置自身prob為0 prob[idx] = 0 sum_prob = np.sum(prob) perp = np.log(sum_prob) + beta * np.sum(dist * prob) / sum_prob prob /= sum_prob return perp, prob def seach_prob(x, tol=1e-5, perplexity=30.0): '''二分搜索尋找beta,並計算pairwise的prob ''' # 初始化參數 print("Computing pairwise distances...") (n, d) = x.shape dist = cal_pairwise_dist(x) pair_prob = np.zeros((n, n)) beta = np.ones((n, 1)) # 取log,方便后續計算 base_perp = np.log(perplexity) for i in range(n): if i % 500 == 0: print("Computing pair_prob for point %s of %s ..." %(i,n)) betamin = -np.inf betamax = np.inf perp, this_prob = cal_perplexity(dist[i], i, beta[i]) # 二分搜索,尋找最佳sigma下的prob perp_diff = perp - base_perp tries = 0 while np.abs(perp_diff) > tol and tries < 50: if perp_diff > 0: betamin = beta[i].copy() if betamax == np.inf or betamax == -np.inf: beta[i] = beta[i] * 2 else: beta[i] = (beta[i] + betamax) / 2 else: betamax = beta[i].copy() if betamin == np.inf or betamin == -np.inf: beta[i] = beta[i] / 2 else: beta[i] = (beta[i] + betamin) / 2 # 更新perb,prob值 perp, this_prob = cal_perplexity(dist[i], i, beta[i]) perp_diff = perp - base_perp tries = tries + 1 # 記錄prob值 pair_prob[i,] = this_prob print("Mean value of sigma: ", np.mean(np.sqrt(1 / beta))) return pair_prob def pca(x, no_dims = 50): ''' PCA算法 使用PCA先進行預降維 ''' print("Preprocessing the data using PCA...") (n, d) = x.shape x = x - np.tile(np.mean(x, 0), (n, 1)) l, M = np.linalg.eig(np.dot(x.T, x)) y = np.dot(x, M[:,0:no_dims]) return y def tsne(x, no_dims=2, initial_dims=50, perplexity=30.0, max_iter=1000): """Runs t-SNE on the dataset in the NxD array x to reduce its dimensionality to no_dims dimensions. The syntaxis of the function is Y = tsne.tsne(x, no_dims, perplexity), where x is an NxD NumPy array. """ # Check inputs if isinstance(no_dims, float): print("Error: array x should have type float.") return -1 if round(no_dims) != no_dims: print("Error: number of dimensions should be an integer.") return -1 # 初始化參數和變量 x = pca(x, initial_dims).real (n, d) = x.shape initial_momentum = 0.5 final_momentum = 0.8 eta = 500 min_gain = 0.01 y = np.random.randn(n, no_dims) dy = np.zeros((n, no_dims)) iy = np.zeros((n, no_dims)) gains = np.ones((n, no_dims)) # 對稱化 P = seach_prob(x, 1e-5, perplexity) P = P + np.transpose(P) P = P / np.sum(P) # early exaggeration P = P * 4 P = np.maximum(P, 1e-12) # Run iterations for iter in range(max_iter): # Compute pairwise affinities sum_y = np.sum(np.square(y), 1) num = 1 / (1 + np.add(np.add(-2 * np.dot(y, y.T), sum_y).T, sum_y)) num[range(n), range(n)] = 0 Q = num / np.sum(num) Q = np.maximum(Q, 1e-12) # Compute gradient PQ = P - Q for i in range(n): dy[i,:] = np.sum(np.tile(PQ[:,i] * num[:,i], (no_dims, 1)).T * (y[i,:] - y), 0) # Perform the update if iter < 20: momentum = initial_momentum else: momentum = final_momentum gains = (gains + 0.2) * ((dy > 0) != (iy > 0)) + (gains * 0.8) * ((dy > 0) == (iy > 0)) gains[gains < min_gain] = min_gain iy = momentum * iy - eta * (gains * dy) y = y + iy y = y - np.tile(np.mean(y, 0), (n, 1)) # Compute current value of cost function if (iter + 1) % 100 == 0: if iter > 100: C = np.sum(P * np.log(P / Q)) else: C = np.sum( P/4 * np.log( P/4 / Q)) print("Iteration ", (iter + 1), ": error is ", C) # Stop lying about P-values if iter == 100: P = P / 4 print("finished training!") return y if __name__ == "__main__": # Run Y = tsne.tsne(X, no_dims, perplexity) to perform t-SNE on your dataset. X = np.loadtxt("mnist2500_X.txt") labels = np.loadtxt("mnist2500_labels.txt") Y = tsne(X, 2, 50, 20.0) from matplotlib import pyplot as plt plt.scatter(Y[:,0], Y[:,1], 20, labels) plt.show() 

 

 

 

https://yq.aliyun.com/articles/389822?utm_content=m_40767

 

假設你有一個包含數百個特征(變量)的數據集,卻對數據所屬的領域幾乎沒有什么了解。 你需要去識別數據中的隱藏模式,探索和分析數據集。不僅如此,你還必須找出數據中是否存在模式--用以判定數據是有用信號還是噪音?

這是否讓你感到不知所措?當我第一次遇到這種情況,我簡直全身發麻。想知道如何挖掘一個多維數據集? 這是許多數據科學家經常問的問題之一。 該篇文章中,我將帶你通過一個強有力的方式來實現這一點。用PCA怎么樣?

現在,一定會有很多人心里想着“我會使用PCA來降維和可視化”。 好吧,你是對的! PCA絕對是具有大量特征的數據集的降維和可視化的不錯選擇。 但是,假如你能使用比PCA更先進的東西將會怎樣呢?

如果你可以很容易地找出非線性的模式呢? 在本文中,我將告訴你一個比PCA(1933)更有效、被稱為t-SNE(2008)的新算法。 首先我會介紹t-SNE算法的基礎知識,然后說明為什么t-SNE是非常適合的降維算法。

你還將獲得在R代碼和Python語句中使用t-SNE的實踐知識。

來吧來吧!

目錄

1.什么是t-SNE?

2.什么是降維?

3.t-SNE與其他降維算法

4.t-SNE的算法細節

 4.1 算法

 4.2 時間和空間復雜性

5.t-SNE實際上做什么?

6.用例

7.t-SNE與其他降維算法相比

8.案例實踐

 8.1 使用R代碼

 

  • 超參數調試
  • 代碼
  • 執行時間
  • 結果解讀

 8.2 使用python語句

 

  • 超參數調試
  • 代碼
  • 執行時間

9.何時何地去使用

 9.1 數據科學家

 9.2 機器學習競賽愛好者

 9.3 數據科學愛好者

10.常見誤區

1.什么是t-SNE

 

e8e556e681d7318d5bc3b82af54c9dfa58ac3a0c

(t-SNE)t-分布式隨機鄰域嵌入是一種用於挖掘高維數據的非線性降維算法。 它將多維數據映射到適合於人類觀察的兩個或多個維度。 在t-SNE算法的幫助下,你下一次使用高維數據時,可能就不需要繪制很多探索性數據分析圖了。

 2.什么是降維?

為了理解t-SNE如何工作,讓我們先了解什么是降維?

簡而言之,降維是在2維或3維中展現多維數據(具有多個特征的數據,且彼此具有相關性)的技術。

有些人可能會問,當我們可以使用散點圖、直方圖和盒圖繪制數據,並用描述性統計搞清數據模式的時候為什么還需要降低維度。

好吧,即使你可以理解數據中的模式並將其呈現在簡單的圖表上,但是對於沒有統計背景的人來說,仍然很難理解它。 此外,如果你有數百個特征值,你必須研究數千張圖表,然后才能搞懂這些數據。

在降維算法的幫助下,您將能夠清晰地表達數據。

3. t-SNE與其他降維算法

現在你已經了解什么是降維,讓我們看看我們如何使用t-SNE算法來降維。

以下是幾個你可以查找到的降維算法:

 

  1. 主成分分析(線性)
  2. t-SNE(非參數/非線性)
  3. 薩蒙映射(非線性)
  4. 等距映射(非線性)
  5. 局部線性嵌入(非線性)
  6. 規范相關分析(非線性)
  7. SNE(非線性)
  8. 最小方差無偏估計(非線性)
  9. 拉普拉斯特征圖(非線性)

 

好消息是,你只需要學習上述算法中的其中兩種,就可以有效地在較低維度上使數據可視化 - PCA和t-SNE。

PCA的局限性

PCA是一種線性算法。 它不能解釋特征之間的復雜多項式關系。 另一方面,t-SNE是基於在鄰域圖上隨機游走的概率分布,可以在數據中找到其結構關系。

線性降維算法的一個主要問題是它們集中將不相似的數據點放置在較低維度區域時,數據點相距甚遠。 但是為了在低維、非線性流型上表示高維數據,我們也需要把相似的數據點靠近在一起展示,這並不是線性降維算法所能做的。

現在,你對PCA應該有了一個簡短的了解。

局部方法尋求將流型上的附近點映射到低維表示中的附近點。 另一方面,全局方法試圖保留所有尺度的幾何形狀,即將附近的點映射到附近的點,將遠處的點映射到遠處的點

要知道,除t-SNE之外的大多數非線性技術都不能同時保留數據的局部和全局結構。

4. t-SNE的算法細節(選讀)

該部分是為有興趣深入理解算法的人准備的。 如果您不想了解數學上面的細節,可以放心地跳過本節。

 

4.1算法

步驟1

隨機鄰近嵌入(SNE)首先通過將數據點之間的高維歐幾里得距離轉換為表示相似性的條件概率。數據點gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAA與數據點gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAA的相似性是條件概率gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAA——如果鄰域被選擇與在以gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAA為中心的正態分布的概率密度成比例,gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAA將選擇gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAA作為其鄰域的概率。

ebb1c5edd82d15ed8526e870fa5d15cb9cc90352

其中640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=是以數據點640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=為中心的正態分布的方差,如果你對數學不感興趣,以這種方式思考它,算法開始於將點之間的最短距離(直線)轉換成點的相似度的概率。 其中,點之間的相似性是: 如果在以640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=為中心的高斯(正態分布)下與鄰域的概率密度成比例地選取鄰域,則640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=會選擇640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=作為其鄰居的條件概率。

 

步驟2

對於低維數據點640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=的高維對應點640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=,可以計算類似的條件概率,其由640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=表示。

f5757ab6c47fa29665bb6e2230bca98696d60b91

需要注意的是,pi | i和pj | j被設置為零,因為我們只想對成對的相似性進行建模。

簡單來說,步驟1和步驟2計算一對點之間的相似性的條件概率。這對點存在於:

 

  1. 高維空間中
  2. 低維空間中

 

為了簡單起見,嘗試詳細了解這一點。

讓我們把3D空間映射到2D空間。 步驟1和步驟2正在做的是計算3D空間中的點的相似性的概率,並計算相應的2D空間中的點的相似性的概率。

邏輯上,條件概率640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=必須相等,以便把具有相似性的不同維空間中的數據點進行完美表示。即,640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=之間的差必須為零,以便在高維和低維中完美復制圖。

通過該邏輯,SNE試圖使條件概率的這種差異最小化。

 

步驟3

現在講講SNE和t-SNE算法之間的區別。

為了測量條件概率SNE差值的總和的最小化,在全體數據點中使用梯度下降法使所有數據點的Kullback-Leibler散度總和減小到最小。 我們必須知道,K-L散度本質上是不對稱的。

換句話說,SNE代價函數重點在映射中保留數據的局部結構(為了高斯方差在高維空間的合理性,640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=)。

除此之外,優化該代價函數是非常困難的(計算效率低)。

因此,t-SNE也嘗試最小化條件概率之差的總和值。 但它通過使用對稱版本的SNE代價函數,使用簡單的梯度。此外,t-SNE在低維空間中采用長尾分布,以減輕擁擠問題(參考下面譯者解釋)和SNE的優化問題。

*譯者注:

擁擠問題是提出t-SNE算法的文章(Visualizing Data using t-SNE,08年發表在Journal of Machine Learning Research,大神Hinton的文章)重點討論的問題(文章的3.2節)。譯者的理解是,如果想象在一個三維的球里面有均勻分布的點,如果把這些點投影到一個二維的圓上一定會有很多點是重合的。所以在二維的圓上想盡可能表達出三維里的點的信息,把由於投影所重合的點用不同的距離(差別很小)表示,這樣就會占用原來在那些距離上的點,原來那些點會被趕到更遠一點的地方。t分布是長尾的,意味着距離更遠的點依然能給出和高斯分布下距離小的點相同的概率值。從而達到高維空間和低維空間對應的點概率相同的目的。

步驟4

如果我們看到計算條件概率的方程,我們忽略了現在的討論的方差。要選擇的剩余參數是學生的t-分布的方差640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=,其中心在每個高維數據點640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=的中心。不可能存在對於數據集中的所有數據點最優的單個值640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=,因為數據的密度可能變化。在密集區域中,較小的值640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=通常與較稀疏的區域相比更合適。任何特定值640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=在所有其他數據點上誘發概率分布640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=。 這個分布有一個

c8212f64339ad90544fc67e5ddd00ea15b00c39c

該分布具有隨着gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAA增加而增加的熵。 t-SNE對gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAA的值執行二進制搜索,產生具有由用戶指定具有困惑度的gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAA2。 該困惑度定義為

45c9d6466a1c43e50e8a23013890f80ff728c240

其中H(640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=)是以比特字節測量的香農熵

4909e12dfd5d0cced685be93d24bb8c26fcc2be5

困惑度可以被解釋為對鄰域的有效數量的平滑測量。 SNE的性能對於茫然性的變化是相當穩固的,並且典型值在5和50之間。

代價函數的最小化是使用梯度下降法來執行的。並且從物理上,梯度可以被解釋為由圖上定位點640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=和所有其他圖上定位點640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=之間的一組彈簧產生的合力。所有彈簧沿着方向(640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy= - 640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=)施加力。彈簧在640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=定位點之間的排斥或吸引,取決於圖中的兩點之間的距離是太遠還是太近 (太遠和太近都不能表示兩個高維數據點之間的相似性。)由彈簧在640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=之間施加的力與其長度成比例,並且還與其剛度成比例,剛度是數據的成對相似性之間的失配(pj | i-qj | i + pi | j-qi | j) 點和地圖點 。

 *譯者補充:

步驟3和4都在講述SNE 與t-SNE之間的區別,總結如下:

區別一:將不對稱的代價函數改成對稱的代價函數。

將代價函數修改為40804d1fe52bbef8eaa03c809d365d725fe148dd,其中9e13136309580387e3b636004af8730175b79451,則可避免上述不對稱的代價函數所帶來的問題。

區別二:在低維空間中使用學生t-分布而不是高斯分布來計算點與點之間的相似度。

t-SNE在低維空間中采用長尾的學生t-分布,02b033fab3fdb6fe5caf21c57f604c9cb74d92b5以減輕擁擠問題和SNE的優化問題。

4.2 時間和空間復雜度

現在我們已經了解了算法,是分析其性能的時候了。 正如你可能已經觀察到的,該算法計算成對的條件概率,並試圖最小化較高和較低維度的概率差的總值。 這涉及大量的運算和計算。 所以該算法對系統資源相當重要。

t-SNE在數據點的數量上具有二次時間和空間復雜性。 這使得它應用於超過10,000個觀察對象組成的數據集的時候特別慢和特別消耗資源。

 5. t-SNE 實際上做了什么?

了解了 t-SNE 算法的數學描述及其工作原理之后,讓我們總結一下前邊學過的東西。以下便是t-SNE工作原理的簡述。

實際上很簡單。 非線性降維算法t-SNE通過基於具有多個特征的數據點的相似性識別觀察到的模式來找到數據中的規律。它不是一個聚類算法,而是一個降維算法。這是因為當它把高維數據映射到低維空間時,原數據中的特征值不復存在。所以不能僅基於t-SNE的輸出進行任何推斷。因此,本質上它主要是一種數據探索和可視化技術。

但是t-SNE可以用於分類器和聚類中,用它來生成其他分類算法的輸入特征值。

6. 應用場景

你可能會問, t-SNE有哪些應用場景呢?它幾乎可以用於任何高維數據。不過大部分應用集中在圖像處理,自然語言處理,基因數據以及語音處理。它還被用於提高心腦掃描圖像的分析。以下維幾個實例:

6.1 人臉識別

人臉識別技術已經取得巨大進展,很多諸如PCA之類的算法也已經在該領域被研究過。但是由於降維和分類的困難,人臉識別依然具有挑戰性。t-SNE被用於高維度數據降維,然后用其它算法,例如 AdaBoostM2, 隨機森林, 邏輯回歸, 神經網絡等多級分類器做表情分類。

一個人臉識別的研究采用了日本女性臉部表情數據庫和t-SNE結合AdaBoostM2的方法。其實驗結果表明這種新方法效果優於諸如PCA, LDA, LLE及SNE的傳統算法。

以下為實現該方法的流程圖: 

d40cdf28684eb888fc144953fb1a5f44d6a87292

6.2 識別腫瘤亞群(醫學成像)

質譜成像(MSI)是一種同時提供組織中數百個生物分子的空間分布的技術。 t-SNE,通過數據的非線性可視化,能夠更好地解析生物分子腫瘤內異質性。

以無偏見的方式,t-SNE可以揭示腫瘤亞群,它們與胃癌患者的存活和乳腺癌患者原發性腫瘤的轉移狀態具有統計相關性。 對每個t-SNE簇進行的存活分析將提供非常有用的結果。[3] 

6.3 使用wordvec的文本比較

詞向量表示法捕獲許多語言屬性,如性別,時態,復數甚至語義概念,如“首都城市”。 使用降維,可以計算出使語義相似的詞彼此臨近的2D地圖。 這種技術組合可以用於提供不同文本資料的鳥瞰圖,包括文本摘要及其資料源。 這使用戶能夠像使用地圖一樣探索文本資料。[4]

 7. t-SNE與其它降維算法的對比

下邊我們將要比較t-SNE和其它算法的性能。這里的性能是基於算法所達到的准確度,而不是時間及運算資源的消耗與准確度之間的關系。

t-SNE產生的結果優於PCA和其它線性降維模型。這是因為諸如經典縮放的線性方法不利於建模曲面的流型。 它專注於保持遠離的數據點之間的距離,而不是保留臨近數據點之間的距離。

t-SNE在高維空間中采用的高斯核心函數定義了數據的局部和全局結構之間的軟邊界。對於高斯的標准偏差而言彼此臨近的數據點對,對它們的間隔建模的重要性幾乎與那些間隔的大小無關。 此外,t-SNE基於數據的局部密度(通過強制每個條件概率分布具有相同的困惑度)分別確定每個數據點的局部鄰域大小[1]。 這是因為算法定義了數據的局部和全局結構之間的軟邊界。 與其他非線性降維算法不同,它的性能優於其它任何一個算法。 

 8. 案例實踐

讓我們用MNIST手寫數字數據庫來實現t-SNE算法。 這是最被廣泛探索的圖像處理的數據集之一。

81.使用R代碼

“Rtsne”包具有t-SNE在R語言中的實現。“Rtsne”包可以通過在R控制台中鍵入以下命令安裝:

 

 
          

 

 

  • 超參數調試

 

92778a3c0a11fef479bf88d754499d588e46adca

 

  • 代碼

 

MNIST數據可從MNIST網站下載,並可用少量代碼轉換為csv文件。對於此示例,請下載以下經過預處理的MNIST數據。

 

 
          

 

 

  •  執行時間

 

 

 
          

 

可以看出,運行於相同樣本規模的數據,與PCA相比t-SNE所需時間明顯更長。

 

  • 解讀結果

 

這些圖可用於探索性分析。 輸出的x和y坐標以及成本代價值可以用作分類算法中的特征值

988c96da554ec7785592e891a13df5af07604da1

8.2使用Rython語句

一個重要的事情要注意的是“pip install tsne”會產生錯誤。 不建議安裝“tsne”包。 t-SNE算法可以從sklearn包中訪問。

 

  • 超參數調試

 

68248d6912d110f229885e0aae66c8db4c17a567

 

  • 代碼

 

以下代碼引自sklearn網站的sklearn示例。

 

 
          

 

 

  • 執行時長

 

 

Tsne: 13.40 s
PCA: 0.01 s

 

PCA結果圖(時長0.01s)

adf87ad6054d10442a04de9fe2410a2905fc4ef8

t-SNE結果圖

d1c61095726880586731041ba09c8cb97a4d69f5

9.何時何地使用t-SNE?

9.1 數據科學家

對於數據科學家來說,使用t-SNE的主要問題是算法的黑盒類型性質。這阻礙了基於結果提供推論和洞察的過程。此外,該算法的另一個問題是它不一定在連續運行時永遠產生類似的輸出。

那么,你怎么能使用這個算法?最好的使用方法是用它進行探索性數據分析。 它會給你非常明確地展示數據內隱藏的模式。它也可以用作其他分類和聚類算法的輸入參數。

9.2機器學習競賽愛好者

將數據集減少到2或3個維度,並使用非線性堆棧器將其堆棧。 使用保留集進行堆疊/混合。 然后你可以使用XGboost提高t-SNE向量以得到更好的結果。

9.3數據科學愛好者

對於才開始接觸數據科學的數據科學愛好者來說,這種算法在研究和性能增強方面提供了最好的機會。已經有一些研究論文嘗試通過利用線性函數來提高算法的時間復雜度。但是尚未得到理想的解決方案。針對各種實施t-SNE算法解決自然語言處理問題和圖像處理應用程序的研究論文是一個尚未開發的領域,並且有足夠的空間范圍。

10.常見錯誤

以下是在解釋t-SNE的結果時要注意的幾個點:

 

  1. 為了使算法正確執行,困惑度應小於數據點數。 此外,推薦的困惑度在(5至50)范圍內
  2. 有時,具有相同超參數的多次運行結果可能彼此不同。
  3. 任何t-SNE圖中的簇大小不得用於標准偏差,色散或任何其他諸如此類的度量。這是因為t-SNE擴展更密集的集群,並且使分散的集群收縮到均勻的集群大小。 這是它產生清晰的地塊的原因之一。
  4. 簇之間的距離可以改變,因為全局幾何與最佳困惑度密切相關。 在具有許多元素數量不等的簇的數據集中,同一個困惑度不能優化所有簇的距離。
  5. 模式也可以在隨機噪聲中找到,因此在決定數據中是否存在模式之前,必須檢查具有不同的超參數組的多次運算結果。
  6. 在不同的困惑度水平可以觀察到不同的簇形狀。
  7. 拓撲不能基於單個t-SNE圖來分析,在進行任何評估之前必須觀察多個圖。

 

參考資料

[1] L.J.P. van der Maaten and G.E. Hinton. Visualizing High-Dimensional Data Using  t-SNE. Journal of Machine Learning Research 9(Nov):2579-2605, 2008

[2] Jizheng Yi et.al. Facial expression recognition Based on t-SNE and AdaBoostM2.

IEEE International Conference on Green Computing and Communications and IEEE Internet of Things and IEEE Cyber,Physical and Social Computing (2013)

[3]  Walid M. Abdelmoulaa et.al. Data-driven identification of prognostic tumor subpopulations using spatially mapped t-SNE of mass spectrometry imaging data.

12244–12249 | PNAS | October 25, 2016 | vol. 113 | no. 43

[4]  Hendrik Heuer. Text comparison using word vector representations and dimensionality reduction. 8th EUR. CONF. ON PYTHON IN SCIENCE (EUROSCIPY 2015)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM