
做用戶畫像聚類的時候我拿到過一份上千維的特征表不降維直接跑聚類結(jié)果全是一團(tuán)漿糊后來做了降維再聚類幾個類別之間的邊界立馬就清楚了。從那以后我就養(yǎng)成了習(xí)慣任何高維數(shù)據(jù)到手先花十分鐘做一輪降維摸底再決定下一步怎么走。這篇文章就把降維里兩條經(jīng)典路線——MDS降維方法和線性降維方法——放在一起講透。MDS這個名詞在面試題里出現(xiàn)的頻率不低但很多人被它唬住以為是什么高深的流形學(xué)習(xí)。實(shí)際上MDS和PCA的關(guān)系比想象中近得多在歐氏距離下經(jīng)典MDS求出來的坐標(biāo)和PCA投影基本是同一套東西。把這兩塊打通你對降維的幾何直覺會上一個臺階。這篇文章適合剛接觸降維、想弄懂原理也想要能直接跑的代碼的朋友有經(jīng)驗(yàn)的讀者可以重點(diǎn)看第5節(jié)里面那些坑是我實(shí)際踩過的。1. 降維到底在解決什么問題兩條路線背后的幾何直覺1.1 為什么需要降維不是“壓縮”而是“看清結(jié)構(gòu)”高維數(shù)據(jù)的麻煩遠(yuǎn)不只是“展示不出來”這么簡單。想象你拿一把尺子去量30維空間里的點(diǎn)兩點(diǎn)之間的歐氏距離會變得非常接近這就是所謂的“維度災(zāi)難”。我見過很多人抱怨明明特征做了標(biāo)準(zhǔn)化K近鄰的效果仍然很飄其實(shí)不是算法的問題是高維空間本身就極度稀疏距離的區(qū)分度被稀釋了。類似的現(xiàn)象還會導(dǎo)致聚類不穩(wěn)定、回歸過擬合、可視化一片糊。降維要做的事不是簡單丟掉幾個無關(guān)緊要的特征而是把數(shù)據(jù)從高維空間映射到一個更低維的空間盡量保留原始數(shù)據(jù)的“結(jié)構(gòu)”——這個結(jié)構(gòu)可能是方差大的方向可能是樣本之間的相對遠(yuǎn)近也可能是類別之間的可分性。你可以把它類比成整理照片幾千張高清原圖直接看會淹沒在細(xì)節(jié)里但你把它們按“相似程度”擺到一張大白紙上關(guān)系和分組一眼就能看出來。降維就是那張大白紙。1.2 兩條路線的分岔線性映射與距離保持圍繞“保留結(jié)構(gòu)”這個目標(biāo)降維方法分成了兩個互相對應(yīng)的流派。線性降維的思路是找一組線性投影方向把高維數(shù)據(jù)直接投影到低維子空間里典型代表就是PCA和LDA。它的輸入是一張樣本特征矩陣輸出是一個投影矩陣和一份低維坐標(biāo)。線性意味著結(jié)果有很強(qiáng)的可解釋性——你能夠看到每個原始特征在投影方向上的權(quán)重新樣本過來也能直接套用同一個投影矩陣映射過去這在真實(shí)業(yè)務(wù)落地里非常方便。MDS的出發(fā)點(diǎn)完全不同。它不關(guān)心特征矩陣只關(guān)心樣本兩兩之間的“距離”或者“不相似度”輸入是一個 N×N 的距離矩陣輸出是一組低維坐標(biāo)讓這組坐標(biāo)在低維空間里重新算出來的距離盡量去逼近輸入的距離矩陣。它甚至可以接受歐氏距離以外的任意度量比如文本里的余弦距離、用戶行為里的Jaccard距離這正是它靈活的地方。這兩條路線看起來八竿子打不著但幾何上有一個漂亮的交叉點(diǎn)當(dāng)距離矩陣用的是歐氏距離時經(jīng)典MDS得到的坐標(biāo)和PCA投影出來的是同一份結(jié)果只差一個旋轉(zhuǎn)或鏡像。理解了這句話你就把線性降維和MDS之間的墻拆掉了。2. 線性降維方法核心拆解PCA、LDA與SVD的關(guān)系2.1 PCA最大方差與最小重構(gòu)誤差PCA大概是所有降維方法里最常用、也最值得先吃透的一個。它的目標(biāo)一句話概括尋找一組正交方向讓數(shù)據(jù)投影到這些方向上的方差盡可能大。為什么要最大化方差因?yàn)榉讲畲蟮姆较虺休d了樣本之間最多的差異信息反過來說數(shù)據(jù)在某個方向上幾乎不變那這個方向上的信息就可以丟掉。這個邏輯跟“最小化重構(gòu)誤差”是等價的——最大化投影方差等價于讓數(shù)據(jù)在低維空間里重構(gòu)回原空間時誤差最小。計算步驟非常清晰對數(shù)據(jù)矩陣做中心化讓每個特征的均值為0。計算協(xié)方差矩陣。對協(xié)方差矩陣做特征值分解。按特征值大小排序取前 k 個特征值對應(yīng)的特征向量組成投影矩陣。用中心化后的數(shù)據(jù)乘上投影矩陣得到低維坐標(biāo)。用 NumPy 手寫一個 PCA 大概這樣import numpy as np def pca_fit_transform(X, n_components2): # X: (n_samples, n_features)已經(jīng)中心化的數(shù)據(jù)會更好 X_centered X - X.mean(axis0) # 協(xié)方差矩陣 cov np.cov(X_centered, rowvarFalse) # 對稱矩陣用 eigh 數(shù)值更穩(wěn)定 eig_vals, eig_vecs np.linalg.eigh(cov) # 特征值從大到小排列取前 n_components 個 idx np.argsort(eig_vals)[::-1][:n_components] W eig_vecs[:, idx] # 投影后的低維坐標(biāo) Z X_centered W return Z, eig_vals[idx]這段代碼里我特意用了np.linalg.eigh而不是np.linalg.eig因?yàn)閰f(xié)方差矩陣是對稱矩陣eigh專門針對對稱矩陣做了優(yōu)化數(shù)值上更穩(wěn)。實(shí)際工程中更推薦對中心化后的數(shù)據(jù)矩陣直接做 SVD而不是先算協(xié)方差矩陣因?yàn)閰f(xié)方差矩陣會放大數(shù)值誤差SVD 一步到位還能很方便地處理大規(guī)模數(shù)據(jù)U, S, Vt np.linalg.svd(X_centered, full_matricesFalse) # Vt 的行就是主方向 W Vt[:n_components].T Z X_centered WSVD 和特征分解在這個場景下解的是同一個問題X^T X 的特征向量就是 V^T 的行主成分得分就是 X V。區(qū)別只是數(shù)值路徑不同。PCA 里還有一個容易被忽視的點(diǎn)解釋方差比例。每個主成分的特征值除以所有特征值之和就是這個主成分“解釋了”多少信息。我在實(shí)際項(xiàng)目里通常會先看一眼前兩個主成分累計解釋了多少方差如果連 50% 都不到說明數(shù)據(jù)噪聲很大或者降維本身解決不了當(dāng)前問題得換思路。2.2 LDA給線性降維加上“標(biāo)簽定向”PCA 是無監(jiān)督的它不管樣本屬于哪一類只找方差最大的方向。這在很多場景下夠用但如果你手里有標(biāo)簽而且降維的最終目的是分類PCA 不一定能幫你找到最有利于判別的方向。這時候該上 LDA。LDA 的目標(biāo)是找一個投影方向讓類間離散度盡可能大、類內(nèi)離散度盡可能小。翻譯成人話就是不同類別的點(diǎn)投影之后盡量分開同一個類別的點(diǎn)投影之后盡量聚攏。數(shù)學(xué)上定義兩個散度矩陣類內(nèi)散度矩陣 S_w衡量每個類內(nèi)部樣本離自己類中心的遠(yuǎn)近。類間散度矩陣 S_b衡量各類中心離全局中心的遠(yuǎn)近加上類別樣本數(shù)的加權(quán)。LDA 要求解的是廣義特征分解問題S_b w λ S_w w取前 k 個最大廣義特征值對應(yīng)的方向作為投影矩陣。這里有個硬性約束很多人容易踩坑LDA 最多能降到的維度不超過“類別數(shù)減一”。二分類最多降到 1 維三分類最多降到 2 維。如果你想保留更多維度LDA 幫不了你得回到 PCA。舉一個直觀的例子一批樣本是“正?!焙汀爱惓!眱深愒继卣饔?0維。直接跑PCA前兩維可能主要反映的是數(shù)據(jù)整體的分布形狀正常和異常還是重疊在一起但用LDA投影到1維重點(diǎn)變成了“怎么把兩類分得最開”分類器在這個1維特征上的表現(xiàn)通常會明顯好于直接用前兩維PCA特征。這也是LDA在特征工程里經(jīng)常作為分類前一步的原因。2.3 線性族的選型PCA、LDA、SVD與因子分析很多新手搞不清楚 PCA、SVD、因子分析這幾個東西有什么區(qū)別其實(shí)它們的關(guān)系是“兄弟工具”的關(guān)系。SVD 本身不是一種降維方法它是矩陣分解的數(shù)值工具但恰好是 PCA 最穩(wěn)定的實(shí)現(xiàn)方式。你可以把 PCA 理解成目標(biāo)SVD 理解成達(dá)成目標(biāo)的引擎。除了 PCASVD 在推薦系統(tǒng)、文本主題分析里也被廣泛使用只是目標(biāo)函數(shù)完全不同。因子分析則是另一個思路它假設(shè)觀測變量是由少數(shù)幾個不可觀測的“潛在因子”驅(qū)動的比如六門考試成績背后可能有“邏輯能力”和“記憶力”兩個潛在因子。因子分析和 PCA 看起來很像但 PCA 找的是“方差最大的方向”因子分析找的是“能解釋變量之間相關(guān)結(jié)構(gòu)的潛在因子”。如果你的目的是做可解釋性、找出隱藏結(jié)構(gòu)因子分析更合適如果只是壓縮維度PCA 更快更直接。方法是否使用標(biāo)簽輸出內(nèi)容核心目標(biāo)典型場景PCA否投影方向 低維坐標(biāo)最大化方差無標(biāo)簽數(shù)據(jù)壓縮、可視化去相關(guān)LDA是判別方向 低維坐標(biāo)最大化類間/類內(nèi)距離比分類前的特征提取經(jīng)典MDS否低維坐標(biāo)保持樣本間距離距離矩陣可視化、相似度分析非度量MDS否低維坐標(biāo)保持樣本間距離的排序用戶調(diào)研、偏好感知圖選型的時候我一般先問自己三個問題有沒有標(biāo)簽要不要對新樣本做映射距離的定義是什么。有標(biāo)簽就優(yōu)先試 LDA沒標(biāo)簽、只想快速看結(jié)構(gòu)就用 PCA如果業(yè)務(wù)方給的就是相似度矩陣或者你要用余弦距離這類非歐度量PCA 就不適用了這時候 MDS 才是正解。3. MDS降維方法核心拆解從距離矩陣到低維坐標(biāo)3.1 經(jīng)典MDS的數(shù)學(xué)骨架二次距離、雙中心化與特征分解MDS 的輸入是一張距離矩陣 DD_ij 表示樣本 i 和樣本 j 之間的距離。它不關(guān)心樣本在原始空間長什么樣只根據(jù)距離推算出“如果把這些距離保持住那么每個樣本在低維空間里應(yīng)該放在哪個位置”。經(jīng)典 MDS 的數(shù)學(xué)推導(dǎo)有幾個關(guān)鍵步驟理解了這幾個步驟你就能把 MDS 看穿。假設(shè)低維坐標(biāo)是 YN×k我們希望低維空間中樣本間的歐氏距離平方盡量等于 D 的平方。也就是說||y_i - y_j||2 ≈ D_ij2展開左邊||y_i||2 ||y_j||2 - 2 y_i^T y_j。如果直接解這個方程比較麻煩因?yàn)槎雾?xiàng)和交叉項(xiàng)混在一起。聰明的地方在于構(gòu)造一個“雙中心化”操作把它線性化。定義中心化矩陣 J I - (1/N) 11^T它的作用是把矩陣的每一列都減去列均值。然后構(gòu)造B -1/2 J D2 J其中 D2 是逐元素平方的距離矩陣??梢宰C明如果距離矩陣 D 來自中心化后的歐氏空間那么 B 正好等于低維坐標(biāo)的 Gram 矩陣 Y Y^T。換句話說B 和 Y Y^T 在數(shù)學(xué)上是同一個東西。于是求 Y 的問題就變成了對 B 做特征分解取前 k 個最大的特征值和對應(yīng)的特征向量然后開方調(diào)整尺度。代碼實(shí)現(xiàn)很直接import numpy as np def classic_mds(D, n_components2): n D.shape[0] # 距離平方 D2 D ** 2 # 雙中心化 J np.eye(n) - np.ones((n, n)) / n B -0.5 * J D2 J # 對稱矩陣特征分解 eig_vals, eig_vecs np.linalg.eigh(B) # 從大到小排序取前 n_components 個 idx np.argsort(eig_vals)[::-1][:n_components] eig_vals eig_vals[idx] eig_vecs eig_vecs[:, idx] # 特征向量是單位正交的需要乘上特征值的平方根來“伸展”坐標(biāo) Y eig_vecs * np.sqrt(eig_vals) return Y, eig_vals注意最后一步特征值分解得到的特征向量是單位向量它的長度是1但 Gram 矩陣的對角線包含了坐標(biāo)的平方范數(shù)所以必須讓每個特征向量乘以對應(yīng)特征值的平方根坐標(biāo)尺度才是對的。這一步漏了你得到的圖會被壓扁或者拉伸變形。為什么這個方法和 PCA 等價一句話解釋如果原始數(shù)據(jù) X 已經(jīng)中心化那么樣本間的歐氏距離平方 D2 可以寫成 D2 diag(G)1^T 1diag(G)^T - 2G其中 G X X^T 是 Gram 矩陣。對它做雙中心化之后B 恰好等于 X X^T。而 PCA 是在對 X^T X 做特征分解。一個是對樣本間的 Gram 矩陣分解一個是對特征間的協(xié)方差矩陣分解它們共享同一個奇異值結(jié)構(gòu)。所以最后得到的坐標(biāo)本質(zhì)上是同一個低維嵌入只是可能有左右方向的翻轉(zhuǎn)。3.2 度量MDS與非度量MDS要“數(shù)值”還是要“次序”經(jīng)典 MDS 要求距離矩陣滿足歐氏空間的度量約束而且它試圖讓低維空間的距離在數(shù)值上逼近原始距離這叫“度量 MDS”。但真實(shí)業(yè)務(wù)里很多“相似度”數(shù)據(jù)根本不滿足歐氏度量比如用戶對品牌偏好的打分差異、消費(fèi)者對不同產(chǎn)品的感知相似度。這時候強(qiáng)行用數(shù)值逼近不一定有意義排序關(guān)系反而更重要。非度量 MDS 的思路就變成了只要低維空間里樣本的相對遠(yuǎn)近順序和原始距離矩陣的排序一致就行。比如原始距離 A-B 是 1、B-C 是 2、A-C 是 100非度量 MDS 不要求低維空間里 1 和 100 的絕對比例被還原只要求 A-C 最遠(yuǎn)、A-B 最近。這種放松讓它在處理感覺打分、排序偏好這類數(shù)據(jù)時特別穩(wěn)定。數(shù)學(xué)上它通過單調(diào)回歸來擬合“距離的排序”迭代優(yōu)化一個叫“應(yīng)力”stress的目標(biāo)函數(shù)。實(shí)際使用中如果驗(yàn)證集上的經(jīng)典 MDS 出現(xiàn)大量負(fù)特征值或者得到的圖交叉得很奇怪我就會切到非度量 MDS 試試往往能得到更符合直覺的相對位置關(guān)系。3.3 MDS的實(shí)操要點(diǎn)距離度量、樣本外映射與大矩陣優(yōu)化MDS 最大的賣點(diǎn)是距離度量可換但這也是最大的坑。同樣一份數(shù)據(jù)你用歐氏距離、余弦距離、曼哈頓距離分別跑 MDS出來的圖完全不一樣。這不是代碼問題而是你在提取數(shù)據(jù)的不同側(cè)面。我在處理文本數(shù)據(jù)時喜歡用余弦距離處理數(shù)值型用戶畫像時用歐氏距離處理共現(xiàn)關(guān)系時用 Jaccard 距離。動手之前先問清楚你要刻畫的“相似”到底是什么。第二個坑是樣本外映射。PCA 訓(xùn)練完留下一個投影矩陣新樣本直接乘上去就行。但經(jīng)典 MDS 做的是特征分解沒有一個顯式的 f(x) 可以套用。新樣本來了你得重新對整個距離矩陣做一次 MDS這在生產(chǎn)環(huán)境里幾乎不可接受。常見的解決辦法是 Landmark MDS先從全部樣本里挑一小撮“地標(biāo)點(diǎn)”對地標(biāo)點(diǎn)做經(jīng)典 MDS之后的地標(biāo)坐標(biāo)固定住任何一個新樣本只要算出它到地標(biāo)點(diǎn)的距離就能通過最小二乘反推出它的低維坐標(biāo)。這個思路在精度損失不大的情況下把“部署”問題解決了。第三個坑是計算復(fù)雜度。距離矩陣是 N×N 的N 到一萬矩陣就是 800MB特征分解的時間也很可觀N 到十萬基本就別想直接 MDS 了。這時候要么抽樣要么上 Landmark 方案要么干脆退回到 PCA。我一直覺得降維方法之間不是互相取代的關(guān)系而是根據(jù)數(shù)據(jù)規(guī)模和業(yè)務(wù)約束選最合適的那一個。4. 實(shí)操過程手寫MDS與PCA并對比效果4.1 模擬數(shù)據(jù)與手寫PCA為了把原理和代碼對應(yīng)起來我構(gòu)造一個模擬數(shù)據(jù)集三類樣本原始特征 20 維其中前兩維決定了類別的分離結(jié)構(gòu)后 18 維全是噪聲。用這樣的數(shù)據(jù)能清楚看到降維到底保留了哪些信息。import numpy as np from sklearn.datasets import make_blobs X, y make_blobs(n_samples300, centers3, n_features20, random_state42) # 把后18維替換成純噪聲模擬“有效維度少、噪聲維度多”的真實(shí)場景 rng np.random.default_rng(42) X[:, 2:] rng.normal(sizeX[:, 2:].shape) Z_pca, evals pca_fit_transform(X, n_components2)跑完之后看解釋方差前兩維的方差占比通常會很低因?yàn)?18 維噪聲把總方差攤薄了。但這個低比值不代表降維失敗反而說明數(shù)據(jù)里大部分維度是噪聲真正決定類別的結(jié)構(gòu)被保留在前兩維里。可視化一下三類樣本在二維平面里分得清清楚楚這就達(dá)到了“看清結(jié)構(gòu)”的目的。4.2 手寫經(jīng)典MDS與PCA碰一碰接下來用我上面寫的classic_mds處理同樣的數(shù)據(jù)輸入直接用歐氏距離矩陣from scipy.spatial.distance import pdist, squareform D squareform(pdist(X, metriceuclidean)) Z_mds, mds_evals classic_mds(D, n_components2)把Z_pca和Z_mds放到同一個坐標(biāo)系里對比你會發(fā)現(xiàn)兩幅散點(diǎn)圖長得幾乎一樣——類別結(jié)構(gòu)、相對密集區(qū)域、離群點(diǎn)全都對得上。唯一可能不同的是某個軸的整體方向反了比如 PCA 的第一個軸指向右上MDS 的第一個軸指向左下。這非常正常因?yàn)樘卣鞣纸獬鰜淼奶卣飨蛄糠较虮旧砭蛶我庑苑柌桓淖儤颖局g的相對距離和聚類結(jié)構(gòu)。這就是我開頭說的那件事在歐氏距離下經(jīng)典 MDS 和 PCA 是同一個解的兩種表達(dá)。很多人在面試?yán)锉粏柕絻烧叩年P(guān)系時背一句“它們等價”就完事其實(shí)如果當(dāng)場能指出“經(jīng)典MDS是對雙中心化距離矩陣做特征分解PCA是對協(xié)方差矩陣做特征分解兩者共享同樣的奇異向量結(jié)構(gòu)”面試官立刻就會知道你是真動手調(diào)過代碼的。4.3 非歐距離下的MDS換一種度量立刻不同同樣的數(shù)據(jù)集我把距離度量換成余弦距離結(jié)果就不一樣了。from sklearn.metrics.pairwise import cosine_similarity # 余弦距離 1 - 余弦相似度需要保證矩陣對角線為0 sim cosine_similarity(X) D_cos 1 - sim np.fill_diagonal(D_cos, 0) Z_mds_cos, _ classic_mds(D_cos, n_components2)這一步有一個很容易踩的細(xì)節(jié)直接用1 - cosine_similarity得到的結(jié)果對角線是 1 而不是 0必須先手動把對角線置零。否則距離矩陣對角線上多了 1雙中心化之后會把原來干凈的 Gram 矩陣結(jié)構(gòu)污染掉得到的低維坐標(biāo)會整體偏斜。跑出來的坐標(biāo)和 PCA 的投影有明顯差異因?yàn)橛嘞揖嚯x只看方向不看大小它對樣本向量的“長度”免疫。這在處理文本 TF-IDF 特征時特別有用——文檔長度差異會導(dǎo)致歐氏距離被長文檔主導(dǎo)但余弦距離只看內(nèi)容方向的相似度。4.4 sklearn里怎么用MDS參數(shù)與陷阱如果不想手寫直接用sklearn.manifold.MDS也可以但它的實(shí)現(xiàn)和我手寫的經(jīng)典 MDS 有一點(diǎn)重要區(qū)別sklearn 用的是 SMACOF 迭代優(yōu)化不是直接做特征分解。默認(rèn)情況下它會隨機(jī)初始化多次挑應(yīng)力最小的解。from sklearn.manifold import MDS mds MDS(n_components2, dissimilarityprecomputed, metricTrue, n_init4, max_iter300, random_state42) Z_sk mds.fit_transform(D)幾個參數(shù)的實(shí)際含義dissimilarityprecomputed表示我傳入的是距離矩陣如果設(shè)為euclidean它會內(nèi)部先算歐氏距離。metricTrue是度量 MDSmetricFalse是非度量 MDS。n_init4是隨機(jī)初始化次數(shù)越大越容易跳出局部最優(yōu)但時間成倍增加。max_iter300是最大迭代輪數(shù)數(shù)據(jù)量大時可以適當(dāng)降低但別低于50。手寫特征分解得到的坐標(biāo)是解析解一次算出sklearn 得到的坐標(biāo)是數(shù)值優(yōu)化解多次迭代逼近。兩者最終結(jié)果基本一致但如果你要追求穩(wěn)定復(fù)現(xiàn)、或者要做大規(guī)模數(shù)據(jù)的精確計算手寫特征分解其實(shí)更直接。我個人的習(xí)慣是探索階段用 sklearn 快速出圖正式做分析時自己寫因?yàn)樽约簩懙臇|西每一行都知道在干什么。5. 常見問題與排查技巧實(shí)錄5.1 負(fù)特征值扎堆距離矩陣可能是“假歐氏”運(yùn)行經(jīng)典 MDS 時B矩陣的特征值里出現(xiàn)負(fù)數(shù)是很常見的。少量負(fù)特征值多數(shù)來自數(shù)據(jù)噪聲問題不大但如果負(fù)特征值數(shù)量很多、絕對值還特別大基本上可以斷定你輸入距離矩陣并不滿足歐氏度量所謂“距離”可能只是視覺相似度之類的主觀打分。遇到這種情況我的排查順序是先按特征值從大到小排列看有幾個正特征值明顯比其余的大。如果正特征值本身就很少而且前 k 個累計占比很低那就不要死磕經(jīng)典 MDS 了切到非度量 MDS 試試。另一個老辦法是給距離加一個常數(shù)把它“撐”成歐氏距離但這個方法現(xiàn)在用得少了因?yàn)樗鼤淖儤颖鹃g的相對比例。5.2 坐標(biāo)鏡像翻轉(zhuǎn)特征向量方向的符號問題我第一次拿 MDS 結(jié)果和別人對圖的時候差點(diǎn)以為是代碼寫錯了——明明用同一個數(shù)據(jù)集兩邊的散點(diǎn)圖形狀一模一樣但 x 軸完全反了。后來我才反應(yīng)過來特征分解給出的特征向量方向本來就是任意的v 和 -v 都是同一個特征向量。這不只是一個 學(xué)術(shù)上的小細(xì)節(jié)在實(shí)際協(xié)作里很麻煩。如果你們團(tuán)隊(duì)里有人用 sklearn有人用 R 的 cmdscale兩邊生成的圖很可能左右翻轉(zhuǎn)或上下翻轉(zhuǎn)。解決辦法是統(tǒng)一固定random_state同時在展示前做一個 Procrustes 對齊——把兩組坐標(biāo)通過旋轉(zhuǎn)、縮放、平移對齊到同一個參考坐標(biāo)系里。這不是算法的錯不要在這種問題上浪費(fèi)太多時間。5.3 大樣本算不動內(nèi)存與計算的取舍距離矩陣的規(guī)模是 O(N2)一萬樣本就是一億個浮點(diǎn)數(shù)約 800MB十萬樣本直接 80GB內(nèi)存爆掉是分分鐘的事。我在實(shí)際工作中超過兩萬樣本就不太敢直接懟經(jīng)典 MDS 了。幾個可行的替代方案隨機(jī)抽樣做一次 MDS看整體形狀然后再用其他方法驗(yàn)證細(xì)節(jié)。用 Landmark MDS選幾百個地標(biāo)點(diǎn)先嵌入再映射其余樣本。如果只是可視化用 t-SNE 或 UMAP 這類更現(xiàn)代的流形方法它們對大數(shù)據(jù)量更友好。如果業(yè)務(wù)要求可解釋、可部署直接用 PCA別折騰 MDS。5.4 坐標(biāo)軸沒有業(yè)務(wù)含義MDS落地解釋的四種做法MDS 的坐標(biāo)軸不像 PCA 那樣能直接說成“維度1代表某個特征方向”它只是一個相對位置這讓它在跨部門溝通時特別吃虧。我在給業(yè)務(wù)方解釋 MDS 結(jié)果時一般會做四件事給每個樣本按業(yè)務(wù)標(biāo)簽著色讓大家先看出“哪些樣本聚在一起”。在關(guān)鍵的點(diǎn)附近標(biāo)注原始特征的典型值反推坐標(biāo)位置背后的含義。不用坐標(biāo)軸的意義去解釋只講距離的含義“這兩個點(diǎn)離得近代表它們的行為更像”。如果非得給坐標(biāo)軸一個解釋就用特征相關(guān)性去擬合看哪個原始特征與這個軸的相關(guān)性最高?,F(xiàn)象可能原因處理方式負(fù)特征值占比高距離矩陣不滿足歐氏度量改用非度量MDS或調(diào)整距離定義兩次運(yùn)行結(jié)果軸方向相反特征向量方向符號不確定固定隨機(jī)種子或做Procrustes對齊樣本一多內(nèi)存就不夠距離矩陣O(N2)隨機(jī)抽樣、Landmark MDS、換PCA低維圖上所有點(diǎn)擠成一團(tuán)原始數(shù)據(jù)本身區(qū)分度過低檢查特征質(zhì)量考慮換距離度量新樣本無法映射到舊坐標(biāo)MDS沒有顯式投影函數(shù)預(yù)埋地標(biāo)點(diǎn)用最小二乘反推坐標(biāo)實(shí)際做數(shù)據(jù)分析這一年多我最大的體會是降維方法不要分開學(xué)要把它們當(dāng)成一整個工具箱。PCA 能快速摸清全局方差結(jié)構(gòu)LDA 能在有標(biāo)簽時幫你找到判別方向MDS 能處理各種奇怪的相似度矩陣。先跑一遍 PCA 看解釋方差再根據(jù)業(yè)務(wù)場景決定要不要換 MDS 或 LDA成本很低收益卻很直觀。最后再分享一個實(shí)用小技巧無論你最后選了哪種降維方法輸出坐標(biāo)之后都記得把坐標(biāo)均值歸零、方差歸一。這樣 Exec 匯報時不同方案的結(jié)果可以直接疊圖對比不會因?yàn)槌叨炔灰恢露`判聚類效果。這一點(diǎn)看著不起眼但能讓你的圖比大多數(shù)人做得專業(yè)一截。