t-SNE完整筆記

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

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

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

目錄

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之間的類似度(這種機率是咱們自主構建的),即:express

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,所以它們之間的類似度以下:markdown

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)以下:app

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)

相關文章
相關標籤/搜索