深度 | 詳解可視化利器t-SNE算法:數(shù)無形時(shí)少直覺

大數(shù)據(jù)

T?分布隨機(jī)近鄰嵌入(T-Distribution?Stochastic?Neighbour?Embedding)是一種用于降維的機(jī)器學(xué)習(xí)方法,它能幫我們識(shí)別相關(guān)聯(lián)的模式。t-SNE?主要的優(yōu)勢(shì)就是保持局部結(jié)構(gòu)的能力。這意味著高維數(shù)據(jù)空間中距離相近的點(diǎn)投影到低維中仍然相近。t-SNE?同樣能生成漂亮的可視化。

當(dāng)構(gòu)建一個(gè)預(yù)測(cè)模型時(shí),第一步一般都需要理解數(shù)據(jù)。雖然搜索原始數(shù)據(jù)并計(jì)算一些基本的統(tǒng)計(jì)學(xué)數(shù)字特征有助于理解它,但沒有什么是可以和圖表可視化展示更為直觀的。然而將高維數(shù)據(jù)擬合到一張簡(jiǎn)單的圖表(降維)通常是非常困難的,這就正是?t-SNE?發(fā)揮作用的地方。

在本文中,我們將探討?t-SNE?的原理,以及?t-SNE?將如何有助于我們可視化數(shù)據(jù)。

t-SNE?算法概念

這篇文章主要是介紹如何使用?t-SNE?進(jìn)行可視化。雖然我們可以跳過這一章節(jié)而生成出漂亮的可視化,但我們還是需要討論?t-SNE?算法的基本原理。

t-SNE?算法對(duì)每個(gè)數(shù)據(jù)點(diǎn)近鄰的分布進(jìn)行建模,其中近鄰是指相互靠近數(shù)據(jù)點(diǎn)的集合。在原始高維空間中,我們將高維空間建模為高斯分布,而在二維輸出空間中,我們可以將其建模為?t?分布。該過程的目標(biāo)是找到將高維空間映射到二維空間的變換,并且最小化所有點(diǎn)在這兩個(gè)分布之間的差距。與高斯分布相比?t?分布有較長(zhǎng)的尾部,這有助于數(shù)據(jù)點(diǎn)在二維空間中更均勻地分布。

控制擬合的主要參數(shù)為困惑度(Perplexity)。困惑度大致等價(jià)于在匹配每個(gè)點(diǎn)的原始和擬合分布時(shí)考慮的最近鄰數(shù),較低的困惑度意味著我們?cè)谄ヅ湓植疾M合每一個(gè)數(shù)據(jù)點(diǎn)到目標(biāo)分布時(shí)只考慮最近的幾個(gè)最近鄰,而較高的困惑度意味著擁有較大的「全局觀」。

因?yàn)榉植际腔诰嚯x的,所以所有的數(shù)據(jù)必須是數(shù)值型。我們應(yīng)該將類別變量通過二值編碼或相似的方法轉(zhuǎn)化為數(shù)值型變量,并且歸一化數(shù)據(jù)也是也十分有效,因?yàn)闅w一化數(shù)據(jù)后就不會(huì)出現(xiàn)變量的取值范圍相差過大。

T?分布隨機(jī)近鄰嵌入算法(t-SNE)

Jake?Hoare?的博客并沒有詳細(xì)解釋?t-SNE?的具體原理和推導(dǎo)過程,因此下面我們將基于?Geoffrey?Hinton?在?2008?年提出的論文和?liam?schoneveld?的推導(dǎo)與實(shí)現(xiàn)詳細(xì)介紹?t-SNE?算法。如果讀者對(duì)這一章節(jié)不感興趣,也可以直接閱讀下一章節(jié)?Jake?Hoare?在實(shí)踐中使用?t-SNE?進(jìn)行數(shù)據(jù)可視化。

liam?schoneveld?推導(dǎo)與實(shí)現(xiàn)地址:https://nlml.github.io/in-raw-numpy/in-raw-numpy-t-sne/論文地址:http://www.jmlr.org/papers/volume9/vandermaaten08a/vandermaaten08a.pdf

因?yàn)?t-SNE?是基于隨機(jī)近鄰嵌入而實(shí)現(xiàn)的,所以首先我們需要理解隨機(jī)近鄰嵌入算法。

隨機(jī)近鄰嵌入(SNE)

假設(shè)我們有數(shù)據(jù)集?X,它共有?N?個(gè)數(shù)據(jù)點(diǎn)。每一個(gè)數(shù)據(jù)點(diǎn)?x_i?的維度為?D,我們希望降低為?d?維。在一般用于可視化的條件下,d?的取值為?2,即在平面上表示出所有數(shù)據(jù)。

SNE?通過將數(shù)據(jù)點(diǎn)間的歐幾里德距離轉(zhuǎn)化為條件概率而表征相似性(下文用?p_j|i?表示):

大數(shù)據(jù)

如果以數(shù)據(jù)點(diǎn)在?x_i?為中心的高斯分布所占的概率密度為標(biāo)準(zhǔn)選擇近鄰,那么?p_j|i?就代表?x_i?將選擇?x_j?作為它的近鄰。對(duì)于相近的數(shù)據(jù)點(diǎn),條件概率?p_j|i?是相對(duì)較高的,然而對(duì)于分離的數(shù)據(jù)點(diǎn),p_j|i?幾乎是無窮小量(若高斯分布的方差σ_i?選擇合理)。

其中σ_i?是以數(shù)據(jù)點(diǎn)?x_i?為均值的高斯分布標(biāo)準(zhǔn)差,決定σ_i?值的方法將在本章后一部分討論。因?yàn)槲覀冎粚?duì)成對(duì)相似性的建模感興趣,所以可以令?p_i|i?的值為零。

現(xiàn)在引入矩陣?Y,Y?是?N*2?階矩陣,即輸入矩陣?X?的?2?維表征?;诰仃?Y,我們可以構(gòu)建一個(gè)分布?q,其形式與?p?類似。

對(duì)于高維數(shù)據(jù)點(diǎn)?x_i?和?x_j?在低維空間中的映射點(diǎn)?y_i?和?y_j,計(jì)算一個(gè)相似的條件概率?q_j|i?是可以實(shí)現(xiàn)的。我們將計(jì)算條件概率?q_i|j?中用到的高斯分布的方差設(shè)置為?1/2。因此我們可以對(duì)映射的低維數(shù)據(jù)點(diǎn)?y_j?和?y_i?之間的相似度進(jìn)行建模:

大數(shù)據(jù)

我們的總體目標(biāo)是選擇?Y?中的一個(gè)數(shù)據(jù)點(diǎn),然后其令條件概率分布?q?近似于?p。這一步可以通過最小化兩個(gè)分布之間的?KL?散度(損失函數(shù))而實(shí)現(xiàn),這一過程可以定義為:

大數(shù)據(jù)

因?yàn)槲覀兿M茏钚』摀p失函數(shù),所以我們可以使用梯度下降進(jìn)行迭代更新,我們可能對(duì)如何迭代感興趣,但我們會(huì)在后文討論與實(shí)現(xiàn)。

使用?NumPy?構(gòu)建歐幾里德距離矩陣

計(jì)算?p_i|j?和?q_i|j?的公式都存在負(fù)的歐幾里德距離平方,即-||x_i?–?x_j||^2,下面可以使用代碼實(shí)現(xiàn)這一部分:

def neg_squared_euc_dists(X): ? ?"""Compute matrix containing negative squared euclidean ? ?distance for all pairs of points in input matrix X ? ?# Arguments: ? ? ? ?X: matrix of size NxD ? ?# Returns: ? ? ? ?NxN matrix D, with entry D_ij = negative squared ? ? ? ?euclidean distance between rows X_i and X_j ? ?""" ? ?# Math? See https://stackoverflow.com/questions/37009647 ? ?sum_X = np.sum(np.square(X), 1) ? ?D = np.add(np.add(-2 * np.dot(X, X.T), sum_X).T, sum_X) ? ?return -D

為了更高的計(jì)算效率,該函數(shù)使用矩陣運(yùn)算的方式定義,該函數(shù)將返回一個(gè)?N?階方陣,其中第?i?行第?j?列個(gè)元素為輸入點(diǎn)?x_i?和?x_j?之間的負(fù)歐幾里德距離平方。

使用過神經(jīng)網(wǎng)絡(luò)的讀者可能熟悉?exp(?)/∑exp(?)?這樣的表達(dá)形式,它是一種?softmax?函數(shù),所以我們定義一個(gè)?softmax?函數(shù):

def softmax(X, diag_zero=True): ? ?"""Take softmax of each row of matrix X.""" ? ?# Subtract max for numerical stability ? ?e_x = np.exp(X - np.max(X, axis=1).reshape([-1, 1])) ? ?# We usually want diagonal probailities to be 0. ? ?if diag_zero: ? ? ? ?np.fill_diagonal(e_x, 0.) ? ?# Add a tiny constant for stability of log we take later ? ?e_x = e_x + 1e-8 ?# numerical stability ? ?return e_x / e_x.sum(axis=1).reshape([-1, 1])

注意我們需要考慮?p_i|i=0?這個(gè)條件,所以我們可以替換指數(shù)負(fù)距離矩陣的對(duì)角元素為?0,即使用?np.fill_diagonal(e_x,?0.)?方法將?e_x?的對(duì)角線填充為?0。

將這兩個(gè)函數(shù)放在一起后,我們能構(gòu)建一個(gè)函數(shù)給出矩陣?P,且元素?P(i,j)?為上式定義的?p_i|j:

困惑度

在上面的代碼段中,Sigmas?參數(shù)必須是長(zhǎng)度為?N?的向量,且包含了每一個(gè)σ_i?的值,那么我們?nèi)绾稳〉眠@些σ_i?呢?這就是困惑度(perplexity)在?SNE?中的作用。條件概率矩陣?P?任意行的困惑度可以定義為:

大數(shù)據(jù)

其中?H(P_i)?為?P_i?的香農(nóng)熵,即表達(dá)式如下:

大數(shù)據(jù)

在?SNE?和?t-SNE?中,困惑度是我們?cè)O(shè)置的參數(shù)(通常為?5?到?50?間)。我們可以為矩陣?P?的每行設(shè)置一個(gè)σ_i,而該行的困惑度就等于我們?cè)O(shè)置的這個(gè)參數(shù)。直觀來說,如果概率分布的熵較大,那么其分布的形狀就相對(duì)平坦,該分布中每個(gè)元素的概率就更相近一些。

困惑度隨著熵增而變大,因此如果我們希望有更高的困惑度,那么所有的?p_j|i(對(duì)于給定的?i)就會(huì)彼此更相近一些。換而言之,如果我們希望概率分布?P_i?更加平坦,那么我們就可以增大σ_i。我們配置的σ_i?越大,概率分布中所有元素的出現(xiàn)概率就越接近于?1/N。實(shí)際上增大σ_i?會(huì)增加每個(gè)點(diǎn)的近鄰數(shù),這就是為什么我們常將困惑度參數(shù)大致等同于所需要的近鄰數(shù)量。

搜索σ_i

為了確保矩陣?P?每一行的困惑度?Perp(P_i)?就等于我們所希望的值,我們可以簡(jiǎn)單地執(zhí)行一個(gè)二元搜索以確定σ_i?能得到我們所希望的困惑度。這一搜索十分簡(jiǎn)單,因?yàn)槔Щ蠖?Perp(P_i)?是隨σ_i?增加而遞增的函數(shù),下面是基本的二元搜索函數(shù):

def binary_search(eval_fn, target, tol=1e-10, max_iter=10000,  ? ? ? ? ? ? ? ? ?lower=1e-20, upper=1000.): ? ?"""Perform a binary search over input values to eval_fn. ? ?# Arguments ? ? ? ?eval_fn: Function that we are optimising over. ? ? ? ?target: Target value we want the function to output. ? ? ? ?tol: Float, once our guess is this close to target, stop. ? ? ? ?max_iter: Integer, maximum num. iterations to search for. ? ? ? ?lower: Float, lower bound of search range. ? ? ? ?upper: Float, upper bound of search range. ? ?# Returns: ? ? ? ?Float, best input value to function found during search. ? ?""" ? ?for i in range(max_iter): ? ? ? ?guess = (lower + upper) / 2. ? ? ? ?val = eval_fn(guess) ? ? ? ?if val > target: ? ? ? ? ? ?upper = guess ? ? ? ?else: ? ? ? ? ? ?lower = guess ? ? ? ?if np.abs(val - target) < = tol: ? ? ? ? ? ?break ? ?return guess

為了找到期望的σ_i,我們需要將?eval_fn?傳遞到?binary_search?函數(shù),并且將σ_i?作為它的參數(shù)而返回?P_i?的困惑度。

以下的?find_optimal_sigmas?函數(shù)確實(shí)是這樣做的以搜索所有的σ_i,該函數(shù)需要采用負(fù)歐幾里德距離矩陣和目標(biāo)困惑度作為輸入。距離矩陣的每一行對(duì)所有可能的σ_i?都會(huì)執(zhí)行一個(gè)二元搜索以找到能產(chǎn)生目標(biāo)困惑度的最優(yōu)σ。該函數(shù)最后將返回包含所有最優(yōu)σ_i?的?NumPy?向量。

def calc_perplexity(prob_matrix): ? ?"""Calculate the perplexity of each row  ? ?of a matrix of probabilities.""" ? ?entropy = -np.sum(prob_matrix * np.log2(prob_matrix), 1) ? ?perplexity = 2 ** entropy ? ?return perplexitydef perplexity(distances, sigmas): ? ?"""Wrapper function for quick calculation of  ? ?perplexity over a distance matrix.""" ? ?return calc_perplexity(calc_prob_matrix(distances, sigmas))def find_optimal_sigmas(distances, target_perplexity): ? ?"""For each row of distances matrix, find sigma that results ? ?in target perplexity for that role.""" ? ?sigmas = []  ? ?# For each row of the matrix (each point in our dataset) ? ?for i in range(distances.shape[0]): ? ? ? ?# Make fn that returns perplexity of this row given sigma ? ? ? ?eval_fn = lambda sigma:  ? ? ? ? ? ?perplexity(distances[i:i+1, :], np.array(sigma)) ? ? ? ?# Binary search over sigmas to achieve target perplexity ? ? ? ?correct_sigma = binary_search(eval_fn, target_perplexity) ? ? ? ?# Append the resulting sigma to our output array ? ? ? ?sigmas.append(correct_sigma) ? ?return np.array(sigmas)

對(duì)稱?SNE

現(xiàn)在估計(jì)?SNE?的所有條件都已經(jīng)聲明了,我們能通過降低成本?C?對(duì)?Y?的梯度而收斂到一個(gè)良好的二維表征?Y。因?yàn)?SNE?的梯度實(shí)現(xiàn)起來比較難,所以我們可以使用對(duì)稱?SNE,對(duì)稱?SNE?是?t-SNE?論文中一種替代方法。

在對(duì)稱?SNE?中,我們最小化?p_ij?和?q_ij?的聯(lián)合概率分布與?p_i|j?和?q_i|j?的條件概率之間的?KL?散度,我們定義的聯(lián)合概率分布?q_ij?為:

大數(shù)據(jù)

該表達(dá)式就如同我們前面定義的?softmax?函數(shù),只不過分母中的求和是對(duì)整個(gè)矩陣進(jìn)行的,而不是當(dāng)前的行。為了避免涉及到?x?點(diǎn)的異常值,我們不是令?p_ij?服從相似的分布,而是簡(jiǎn)單地令?p_ij=(p_i|j+p_j|i)/2N。

我們可以簡(jiǎn)單地編寫這些聯(lián)合概率分布?q?和?p:

def q_joint(Y): ? ?"""Given low-dimensional representations Y, compute ? ?matrix of joint probabilities with entries q_ij.""" ? ?# Get the distances from every point to every other ? ?distances = neg_squared_euc_dists(Y) ? ?# Take the elementwise exponent ? ?exp_distances = np.exp(distances) ? ?# Fill diagonal with zeroes so q_ii = 0 ? ?np.fill_diagonal(exp_distances, 0.) ? ?# Divide by the sum of the entire exponentiated matrix ? ?return exp_distances / np.sum(exp_distances), Nonedef p_conditional_to_joint(P): ? ?"""Given conditional probabilities matrix P, return ? ?approximation of joint distribution probabilities.""" ? ?return (P + P.T) / (2. * P.shape[0])

同樣可以定義?p_joint?函數(shù)輸入數(shù)據(jù)矩陣?X?并返回聯(lián)合概率?P?的矩陣,此外我們還能一同估計(jì)要求的σ_i?和條件概率矩陣:

所以現(xiàn)在已經(jīng)定義了聯(lián)合概率分布?p?與?q,若我們計(jì)算了這兩個(gè)聯(lián)合分布,那么我們能使用以下梯度更新低維表征?Y?的第?i?行:

大數(shù)據(jù)

在?Python?中,我們能使用以下函數(shù)估計(jì)梯度,即給定聯(lián)合概率矩陣?P、Q?和當(dāng)前低維表征?Y?估計(jì)梯度:

def symmetric_sne_grad(P, Q, Y, _): ? ?"""Estimate the gradient of the cost with respect to Y""" ? ?pq_diff = P - Q ?# NxN matrix ? ?pq_expanded = np.expand_dims(pq_diff, 2) ?#NxNx1 ? ?y_diffs = np.expand_dims(Y, 1) - np.expand_dims(Y, 0) ?#NxNx2 ? ?grad = 4. * (pq_expanded * y_diffs).sum(1) ?#Nx2 ? ?return grad

為了向量化變量,np.expand_dims?方法將十分有用,該函數(shù)最后返回的?grad?為?N*2?階矩陣,其中第?i?行為?dC/dy_i。一旦我們計(jì)算完梯度,那么我們就能利用它執(zhí)行梯度下降,即通過梯度下降迭代式更新?y_i。

估計(jì)對(duì)稱?SNE

前面已經(jīng)定義了所有的估計(jì)對(duì)稱?SNE?所需要的函數(shù),下面的訓(xùn)練函數(shù)將使用梯度下降算法迭代地計(jì)算與更新權(quán)重。

def estimate_sne(X, y, P, rng, num_iters, q_fn, grad_fn, learning_rate, ? ? ? ? ? ? ? ? momentum, plot): ? ?"""Estimates a SNE model. ? ?# Arguments ? ? ? ?X: Input data matrix. ? ? ? ?y: Class labels for that matrix. ? ? ? ?P: Matrix of joint probabilities. ? ? ? ?rng: np.random.RandomState(). ? ? ? ?num_iters: Iterations to train for. ? ? ? ?q_fn: Function that takes Y and gives Q prob matrix. ? ? ? ?plot: How many times to plot during training. ? ?# Returns: ? ? ? ?Y: Matrix, low-dimensional representation of X. ? ?""" ? ?# Initialise our 2D representation ? ?Y = rng.normal(0., 0.0001, [X.shape[0], 2]) ? ?# Initialise past values (used for momentum) ? ?if momentum: ? ? ? ?Y_m2 = Y.copy() ? ? ? ?Y_m1 = Y.copy() ? ?# Start gradient descent loop ? ?for i in range(num_iters): ? ? ? ?# Get Q and distances (distances only used for t-SNE) ? ? ? ?Q, distances = q_fn(Y) ? ? ? ?# Estimate gradients with respect to Y ? ? ? ?grads = grad_fn(P, Q, Y, distances) ? ? ? ?# Update Y ? ? ? ?Y = Y - learning_rate * grads ? ? ? ?if momentum: ?# Add momentum ? ? ? ? ? ?Y += momentum * (Y_m1 - Y_m2) ? ? ? ? ? ?# Update previous Y's for momentum ? ? ? ? ? ?Y_m2 = Y_m1.copy() ? ? ? ? ? ?Y_m1 = Y.copy() ? ? ? ?# Plot sometimes ? ? ? ?if plot and i % (num_iters / plot) == 0: ? ? ? ? ? ?categorical_scatter_2d(Y, y, alpha=1.0, ms=6, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? show=True, figsize=(9, 6)) ? ?return Y

為了簡(jiǎn)化表達(dá),我們將使用?MNIST?數(shù)據(jù)集中標(biāo)簽為?0、1?和?8?的?200?個(gè)數(shù)據(jù)點(diǎn),該過程定義在?main()?函數(shù)中:

上式通過假設(shè)?q_ij?服從自由度為?1?的學(xué)生?T?分布(Student?t-distribution)而推導(dǎo)出來。Van?der?Maaten?和?Hinton?注意到該分布有非常好的一個(gè)屬性,即計(jì)數(shù)器(numerator)對(duì)于較大距離在低維空間中具有反平方變化規(guī)律。本質(zhì)上,這意味著該算法對(duì)于低維映射的一般尺度具有不變性。因此,最優(yōu)化對(duì)于相距較遠(yuǎn)的點(diǎn)和相距較近的點(diǎn)都有相同的執(zhí)行方式。

這就解決了所謂的「擁擠問題」,即當(dāng)我們?cè)噲D將一個(gè)高維數(shù)據(jù)集表征為?2?或?3?個(gè)維度時(shí),很難將鄰近的數(shù)據(jù)點(diǎn)與中等距離的數(shù)據(jù)點(diǎn)區(qū)分開來,因?yàn)檫@些數(shù)據(jù)點(diǎn)都聚集在一塊區(qū)域。

我們能使用以下函數(shù)計(jì)算新的?q_ij:

def q_tsne(Y): ? ?"""t-SNE: Given low-dimensional representations Y, compute ? ?matrix of joint probabilities with entries q_ij.""" ? ?distances = neg_squared_euc_dists(Y) ? ?inv_distances = np.power(1. - distances, -1) ? ?np.fill_diagonal(inv_distances, 0.) ? ?return inv_distances / np.sum(inv_distances), inv_distances

注意我們使用?1.?–?distances?代替?1.?+?distances,該距離函數(shù)將返回一個(gè)負(fù)的距離?,F(xiàn)在剩下的就是重新估計(jì)損失函數(shù)對(duì)?Y?的梯度,t-SNE?論文中推導(dǎo)該梯度的表達(dá)式為:

大數(shù)據(jù)

同樣,我們很容易按照計(jì)算對(duì)稱?SNE?梯度的方式構(gòu)建?t-SNE?的梯度計(jì)算方式:

def tsne_grad(P, Q, Y, inv_distances): ? ?"""Estimate the gradient of t-SNE cost with respect to Y.""" ? ?pq_diff = P - Q ? ?pq_expanded = np.expand_dims(pq_diff, 2) ? ?y_diffs = np.expand_dims(Y, 1) - np.expand_dims(Y, 0) ? ?# Expand our inv_distances matrix so can multiply by y_diffs ? ?distances_expanded = np.expand_dims(inv_distances, 2) ? ?# Multiply this by inverse distances matrix ? ?y_diffs_wt = y_diffs * distances_expanded ? ?# Multiply then sum over j's ? ?grad = 4. * (pq_expanded * y_diffs_wt).sum(1) ? ?return grad

以上我們就完成了?t-SNE?的具體理解與實(shí)現(xiàn),那么該算法在具體數(shù)據(jù)集中的可視化效果是怎樣的呢?Jake?Hoare?給出了實(shí)現(xiàn)可視化的效果與對(duì)比。

t-SNE?可視化

下面,我們將要展示?t-SNE?可視化高維數(shù)據(jù)的結(jié)果,第一個(gè)數(shù)據(jù)集是基于物理特征分類的?10?種不同葉片。這種情況下,t-SNE?需要使用?14?個(gè)數(shù)值變量作為輸入,其中就包括葉片的生長(zhǎng)率和長(zhǎng)寬比等。下圖展示了?2?維可視化輸出,植物的種類(標(biāo)簽)使用不同的顏色表達(dá)。

大數(shù)據(jù)

物種?Acer?palmatum?的數(shù)據(jù)點(diǎn)在右上角形成了一個(gè)橙色集群,這表明它的葉子和其他物種有很大的不同。該示例中類別通常會(huì)有很好的分組,相同物種的葉子(同一顏色的數(shù)據(jù)點(diǎn))趨向于彼此靠緊聚集在一起。左下角有兩種顏色的數(shù)據(jù)點(diǎn)靠近在一起,說明這兩個(gè)物種的葉子形狀十分相似。

最近鄰準(zhǔn)確度表明給定兩個(gè)隨機(jī)點(diǎn),它們是相同物種的概率是多少。如果這些數(shù)據(jù)點(diǎn)完美地根據(jù)不同物種而分類,那么準(zhǔn)確度就會(huì)非常接近?100%,高準(zhǔn)確度意味著數(shù)據(jù)能被干凈地分為不同的集群。

調(diào)整困惑度

下面,我們對(duì)可樂品牌做了類似的分析。為了演示困惑度(perplexity)的影響,我們首先需要將困惑度設(shè)置為較低的值?2,每個(gè)數(shù)據(jù)點(diǎn)的映射只考慮最近鄰。如下,我們將看到許多離散的小集群,并且每一個(gè)集群只有少量的數(shù)據(jù)點(diǎn)。

大數(shù)據(jù)

下面我們將?t-SNE?的困惑度設(shè)置為?100,我們可以看到數(shù)據(jù)點(diǎn)變得更加擴(kuò)散,并且同一類之間的聯(lián)系變?nèi)酢?/p>

大數(shù)據(jù)

在該案例中,可樂本身就要比樹葉更難分割,即使一類數(shù)據(jù)點(diǎn)某個(gè)品牌要更集中一些,但仍然沒有明確的邊界。

在實(shí)踐中,困惑度并沒以一個(gè)絕對(duì)的標(biāo)準(zhǔn),不過一般選擇?5?到?50?之間會(huì)有比較好的結(jié)果。并且在這個(gè)范圍內(nèi),t-SNE?一般是比較魯棒的。

預(yù)測(cè)的解釋

度量數(shù)據(jù)點(diǎn)之間的角度或距離并不能推斷出任何數(shù)據(jù)上的具體或定量的信息,所以?t-SNE?的預(yù)測(cè)更多的是用于可視化數(shù)據(jù)。

在模型搭建前期直觀地挖掘數(shù)據(jù)模式有助于指導(dǎo)數(shù)據(jù)科學(xué)下一步進(jìn)程。如果?t-SNE?能很好地分割數(shù)據(jù)點(diǎn),那么機(jī)器學(xué)習(xí)同樣也能找到一種將未知新數(shù)據(jù)投影到相應(yīng)類別的好方法。給定一種預(yù)測(cè)算法,我們就能實(shí)現(xiàn)很高的準(zhǔn)確度。

上例中每一個(gè)類別都是孤立分類的,因此簡(jiǎn)單的機(jī)器學(xué)習(xí)模型就能將該類別與其他類別分離開。但如果類別重疊,我們可能就要構(gòu)建更精細(xì)的模型做出預(yù)測(cè)。如下所示,如果我們按照某個(gè)品牌的偏好從?1?到?5?進(jìn)行分類,那么類別可能更加離散、更難以預(yù)測(cè),最近鄰精度也會(huì)相對(duì)較低。

大數(shù)據(jù)

對(duì)比?PCA

很自然我們就希望將?t-SNE?和其他降維算法做比較。降維算法中比較流行的是主成分分析法(PCA),PCA?會(huì)尋找能盡可能保留數(shù)據(jù)方差的新維度。有較大的方差的數(shù)據(jù)保留的信息就越多,因?yàn)楸舜瞬煌臄?shù)據(jù)可以提供不同的信息,所以我們最好是保留彼此分離的數(shù)據(jù)點(diǎn),因?yàn)樗鼈兲峁┝溯^大的方差。

下面是采用?PCA?算法對(duì)上文的樹葉類別進(jìn)行降維的結(jié)果,我們看到雖然左側(cè)的橙色是分離的,但其它類別都有點(diǎn)混合在一起。這是因?yàn)?PCA?并不關(guān)心局部的最近鄰關(guān)系,此外?PCA?是一種線性方法,所以它表征非線性關(guān)系可能效果并不是很好。不過?PCA?算法在壓縮數(shù)據(jù)為更小的特征向量而投入到預(yù)測(cè)算法中有很好地表現(xiàn),這一點(diǎn)它要比?t-SNE?效果更好。

大數(shù)據(jù)

結(jié)語

t-SNE?是一種可視化高維數(shù)據(jù)的優(yōu)秀算法,它經(jīng)常要比其它降維算法生成更具特點(diǎn)的可視化結(jié)果。在數(shù)據(jù)分析中,獲得數(shù)據(jù)的先驗(yàn)知識(shí)總是很重要的,正如華羅庚先生說過:數(shù)無形時(shí)少直覺,形少數(shù)時(shí)難入微,我們只有先理解了數(shù)據(jù)的大概分布,然后再能選擇具體的算法對(duì)這些數(shù)據(jù)進(jìn)一步分析。數(shù)形結(jié)合百般好,隔離分家萬事休,也許高維數(shù)據(jù)的可視化與機(jī)器學(xué)習(xí)算法的結(jié)合才是數(shù)據(jù)分析的正確打開方式。

極客網(wǎng)企業(yè)會(huì)員

免責(zé)聲明:本網(wǎng)站內(nèi)容主要來自原創(chuàng)、合作伙伴供稿和第三方自媒體作者投稿,凡在本網(wǎng)站出現(xiàn)的信息,均僅供參考。本網(wǎng)站將盡力確保所提供信息的準(zhǔn)確性及可靠性,但不保證有關(guān)資料的準(zhǔn)確性及可靠性,讀者在使用前請(qǐng)進(jìn)一步核實(shí),并對(duì)任何自主決定的行為負(fù)責(zé)。本網(wǎng)站對(duì)有關(guān)資料所引致的錯(cuò)誤、不確或遺漏,概不負(fù)任何法律責(zé)任。任何單位或個(gè)人認(rèn)為本網(wǎng)站中的網(wǎng)頁或鏈接內(nèi)容可能涉嫌侵犯其知識(shí)產(chǎn)權(quán)或存在不實(shí)內(nèi)容時(shí),應(yīng)及時(shí)向本網(wǎng)站提出書面權(quán)利通知或不實(shí)情況說明,并提供身份證明、權(quán)屬證明及詳細(xì)侵權(quán)或不實(shí)情況證明。本網(wǎng)站在收到上述法律文件后,將會(huì)依法盡快聯(lián)系相關(guān)文章源頭核實(shí),溝通刪除相關(guān)內(nèi)容或斷開相關(guān)鏈接。

  • 簡(jiǎn)版
  • 原版
  • 投稿
  • 回頂部
2017-11-15
深度 | 詳解可視化利器t-SNE算法:數(shù)無形時(shí)少直覺
T?分布隨機(jī)近鄰嵌入(T-Distribution?Stochastic?Neighbour?Embedding)是一種用于降維的機(jī)器學(xué)習(xí)方法,它能幫我們識(shí)別相

長(zhǎng)按掃碼 閱讀全文