機器學習中的嵌入:使復雜數據變得簡單

已發表: 2022-03-11

即使對於經驗豐富的數據科學家來說,使用非數值數據也很困難。 典型的機器學習模型期望其特徵是數字,而不是單詞、電子郵件、網站頁面、列表、圖表或概率分佈。 為了有用,必須首先將數據轉換為向量空間。 但是怎麼做?

一種流行的方法是將非數字特徵視為 categorical 。 如果類別的數量很少(例如,如果數據表明一個專業或一個國家),這可能會很有效。 但是,如果我們嘗試將此方法應用於電子郵件,我們可能會獲得與樣本一樣多的類別。 沒有兩封電子郵件完全相同,因此這種方法毫無用處。

另一種方法是定義數據樣本之間的距離,這個函數告訴我們任意兩個樣本有多接近。 或者我們可以定義一個相似性度量,它會給我們相同的信息,除了兩個接近的樣本之間的距離很小而相似性很大。 計算所有數據樣本之間的距離(相似度)會給我們一個距離(或相似度)矩陣。 這是我們可以使用的數字數據。

但是,這些數據的維度與樣本的數量一樣多,如果我們想將其用作特徵(參見維度詛咒)或將其可視化(雖然一個圖甚至可以處理 6D,但我還沒有),這通常不是很好查看 100D 圖)。 我們能否將維度的數量減少到合理的數量?

答案是肯定的! 這就是我們嵌入的目的。

什麼是嵌入以及為什麼要使用它?

嵌入是高維數據的低維表示。 通常,嵌入不會捕獲原始數據中包含的所有信息。 然而,一個好的嵌入將足以解決手頭的問題。

存在許多針對特定數據結構量身定制的嵌入。 例如,您可能聽說過用於文本數據的 word2vec,或用於形狀圖像數據的傅立葉描述符。 相反,我們將討論如何將嵌入應用於可以定義距離或相似性度量的任何數據。 只要我們可以計算距離矩陣,數據的性質就完全無關緊要了。 無論是電子郵件、列表、樹還是網頁,它的工作原理都是一樣的。

在本文中,我們將向您介紹不同類型的嵌入,並討論一些流行的嵌入是如何工作的,以及我們如何使用嵌入來解決涉及復雜數據的實際問題。 我們還將介紹這種方法的優缺點,以及一些替代方法。 是的,有些問題可以通過其他方式更好地解決,但不幸的是,機器學習沒有靈丹妙藥。

讓我們開始吧。

嵌入如何工作

所有嵌入都試圖降低數據的維度,同時保留數據中的“基本”信息,但每個嵌入都以自己的方式進行。 在這裡,我們將介紹一些可以應用於距離或相似度矩陣的流行嵌入。

我們甚至不會嘗試覆蓋所有嵌入。 至少有十幾個眾所周知的嵌入可以做到這一點,還有更多鮮為人知的嵌入及其變體。 他們每個人都有自己的方法,優點和缺點。

如果您想看看還有哪些其他嵌入,您可以從這裡開始:

  • Scikit-learn 用戶指南
  • 統計學習的要素(第二版),第 14 章

距離矩陣

讓我們簡要介紹一下距離矩陣。 為數據找到合適的距離需要對問題有很好的理解,需要一些數學知識,有時還需要運氣。 在本文描述的方法中,這可能是影響項目整體成功或失敗的最重要因素。

您還應該牢記一些技術細節。 許多嵌入算法會假設距離(或相異)矩陣 $\textbf{D}$ 在其對角線上有零並且是對稱的。 如果它不是對稱的,我們可以使用 $(\textbf{D} + \textbf{D}^T) / 2$ 代替。 使用核技巧的算法還將假設距離是一個度量,這意味著三角不等式成立:

\[\forall a, b, c \;\; d(a,c) \leq d(a,b) + d(b,c)\]

此外,如果算法需要相似度矩陣,我們可以應用任何單調遞減函數將距離矩陣轉換為相似度矩陣:例如,$\exp -x$。

主成分分析 (PCA)

主成分分析(PCA)可能是迄今為止使用最廣泛的嵌入。 這個想法很簡單:找到最大化捕獲方差或(等效地)最小化二次重建誤差的特徵的線性變換

具體來說,讓特徵是一個樣本矩陣 $\textbf{X} \in \mathbb{R}^{n \times p}$ 有 $n$ 個特徵和 $p$ 個維度。 為簡單起見,我們假設數據樣本均值為零。 我們可以通過將 $\textbf{X}$ 乘以正交矩陣 $\textbf{V}_q \in \mathbb{R}^{p \times q}$ 將維數從 $p$ 減少到 $q$ :

\[\hat{\textbf{X}} = \textbf{X} \textbf{V}_q\]

那麼,$\hat{\textbf{X}} \in \mathbb{R}^{n \times q}$ 將是新的特徵集。 要將新特徵映射回原始空間(此操作稱為重建),我們只需將其再次乘以 $\textbf{V}_q^T$。

現在,我們要找到最小化重構誤差的矩陣 $\textbf{V}_q$:

\[\min_{\textbf{V}_q} ||\textbf{X}\textbf{V}_q\textbf{V}_q^T - \textbf{X}||^2\]

矩陣$\textbf{V}_q$ 的列稱為主成分方向,$\hat{\textbf{X}}$ 的列稱為主成分。 在數值上,我們可以通過對 $\textbf{X}$ 應用 SVD 分解來找到 $\textbf{V}_q$,儘管還有其他同樣有效的方法可以做到這一點。

PCA 可以直接應用於數值特徵。 或者,如果我們的特徵是非數值的,我們可以將其應用於距離或相似度矩陣。

如果你使用 Python,PCA 是在 scikit-learn 中實現的。

這種方法的優點是計算速度快,並且對數據中的噪聲具有很強的魯棒性。

缺點是它只能捕獲線性結構,因此原始數據中包含的非線性信息很可能會丟失。

內核 PCA

內核 PCA 是 PCA 的非線性版本。 這個想法是使用內核技巧,如果您熟悉支持向量機 SVM,您可能聽說過。

具體來說,有幾種不同的方法來計算 PCA。 其中之一是計算 gram 矩陣 $\textbf{X} \textbf{X}^T \in \mathbb{R}^{n \times n}$ 的雙中心版本的特徵分解。 現在,如果我們為我們的數據計算一個核矩陣$\textbf{K} \in \mathbb{R}^{n \times n}$,Kernel PCA 將把它當作一個 gram 矩陣來查找主成分。

令 $x_i$, $i \in {1,..,n}$ 為特徵樣本。 核矩陣由核函數 $K(x_i,x_j)=\langle \phi(x_i),\phi(x_j) \rangle$ 定義。

一個流行的選擇是徑向內核:

\[K(x_i,x_j)=\exp -\gamma \cdot d(x_i,x_j)\]

其中 $d$ 是距離函數。

內核 PCA 要求我們指定距離。 例如,對於數值特徵,我們可以使用歐幾里德距離:$d(x_i,x_j)=\vert\vert x_i-x_j \vert \vert ^2$。

對於非數字特徵,我們可能需要發揮創造力。 要記住的一件事是,該算法假設我們的距離是一個度量。

如果你使用 Python,Kernel PCA 是在 scikit-learn 中實現的。

Kernel PCA 方法的優點是它可以捕獲非線性數據結構。

缺點是對數據中的噪聲敏感,距離和核函數的選擇會對結果產生很大影響。

多維縮放 (MDS)

多維縮放(MDS)試圖在全局範圍內保持樣本之間的距離。 這個想法非常直觀,並且適用於距離矩陣。

具體來說,給定特徵樣本 $x_i$、$i \in {1,..,n}$ 和距離函數 $d$,我們計算新的特徵樣本 $z_i \in \mathbb{R}^{q}$, $i \in {1,..,n}$ 通過最小化應力函數

\[\min_{z_1,..,z_n} \sum_{1 \leq i < j \leq n} (d(x_i, x_j) - ||z_i - z_j||)^2\]

如果你使用 Python,MDS 是在 scikit-learn 中實現的。 但是,scikit-learn 不支持樣本外點的轉換,如果我們想將嵌入與回歸或分類模型結合使用,這可能會很不方便。 但是,原則上是可以的。

MDS的優點是它的思想與我們的框架完全吻合,並且不受數據中噪聲的影響。

缺點是它在 scikit-learn 中的實現很慢,不支持樣本外轉換。

用例:貨件追踪

一個熱帶小島上的一些定居點已經開發了包裹運輸服務,以滿足當地旅遊業的需求。 其中一個定居點的一位商人決定採取行動以在競爭中獲得優勢,因此他建立了一個衛星監控系統,跟踪島上所有的包裹運輸。 收集到數據後,商家打電話給數據科學家(就是我們!)來幫助他回答以下問題:我們能否預測當前正在運送的包裹的目的地?

該數據集包含有關 200 個跟踪貨物的信息。 對於每個跟踪的貨物,都有一個 (x,y) 坐標列表,表示發現包裹的所有位置,通常在 20 到 50 個觀察值之間。 下圖顯示了這些數據的外觀。

用例:貨件追踪

這些數據看起來很麻煩——實際上是兩種不同的麻煩。

第一個問題是我們處理的數據是高維的。 例如,如果在 50 個位置發現每個包裹,我們的數據將有 100 個維度——與您處理的 200 個樣本相比,這聽起來很多。

第二個問題:不同的運輸路線實際上有不同數量的觀察,因此我們不能簡單地將列表與坐標堆疊以以表格形式表示數據(即使它們有,這仍然沒有意義)。

商人不耐煩地用手指敲著桌子,數據科學家努力不表現出任何恐慌的跡象。

這就是距離矩陣和嵌入會派上用場的地方。 我們只需要找到一種方法來比較兩條運輸路線。 Frechet距離似乎是一個合理的選擇。 通過距離,我們可以計算距離矩陣。

注意:此步驟可能需要一段時間。 我們需要計算 $O(n^2)$ 距離,每個距離都有 $O(k^2)$ 次迭代,其中 $n$ 是樣本數,$k$ 是一個樣本中的觀察數。 有效地編寫距離函數是關鍵。 例如,在 Python 中,您可以使用 numba 將這種計算加速很多倍。

可視化嵌入

現在,我們可以使用嵌入將維數從 200 減少到只有幾個。 我們可以清楚地看到,只有幾條貿易路線,所以我們可能希望即使在二維或三個維度上也能找到數據的良好表示。 我們將使用之前討論過的嵌入:PCA、Kernel PCA 和 MDS。

在下圖中,您可以看到標記的路線數據(為了演示而給出)及其通過 2D 和 3D 嵌入的表示(從左到右)。 標記的數據標記了由六條貿易路線連接的四個貿易站。 六條貿易路線中有兩條是雙向的,總共構成八個貨運組(6+2)。 如您所見,我們通過 3D 嵌入對所有八個貨運組進行了非常清晰的區分。

可視化嵌入

這是一個好的開始。

模型管道中的嵌入

現在,我們準備好訓練嵌入了。 雖然 MDS 顯示出最好的結果,但它相當慢; 此外,scikit-learn 的實現不支持樣本外轉換。 這對研究來說不是問題,但它可以用於生產,所以我們將使用 Kernel PCA 代替。 對於核 PCA,我們不應該忘記事先將徑向核應用於距離矩陣。

你如何選擇輸出維度的數量? 分析表明,即使是 3D 也可以。 為了安全起見,不要遺漏任何重要信息,我們將嵌入輸出設置為 10D。 為了獲得最佳性能,可以將輸出維度的數量設置為模型超參數,然後通過交叉驗證進行調整。

因此,我們將擁有 10 個數字特徵,我們可以將它們用作幾乎任何分類模型的輸入。 一個線性模型和一個非線性模型怎麼樣:比如邏輯回歸和梯度提升? 為了比較,讓我們也使用這兩個模型以全距離矩陣作為輸入。 最重要的是,讓我們也測試 SVM(SVM 被設計為直接使用距離矩陣,因此不需要嵌入)。

測試集上的模型準確度如下圖所示(生成了 10 個訓練和測試數據集,因此我們可以估計模型的方差):

  • Gradient Boosting與嵌入(KernelPCA+GB)配對獲得第一名。 它在沒有嵌入 (GB) 的情況下優於梯度提升。 在這裡,Kernel PCA 被證明是有用的。
  • 邏輯回歸沒問題。 有趣的是,沒有嵌入 (LR) 的邏輯回歸比嵌入 (KernelPCA+LR) 做得更好。 這並不完全出乎意料。 線性模型不是很靈活,但相對難以過擬合。 在這裡,嵌入造成的信息丟失似乎超過了較小輸入維度的好處。
  • 最後但同樣重要的是, SVM也表現良好,儘管該模型的方差非常顯著。

模型精度

模型精度

此用例的 Python 代碼可在 GitHub 上找到。

結論

我們已經解釋了嵌入是什麼,並演示瞭如何將它們與距離矩陣結合使用來解決實際問題。 判決時間:

嵌入是數據科學家應該使用的東西嗎? 讓我們來看看故事的兩面。

使用嵌入的優缺點

優點:

  • 這種方法允許我們使用不尋常或複雜的數據結構,只要你能定義一個距離,只要有一定程度的知識、想像力和運氣——你通常可以。
  • 輸出是低維數值數據,您可以輕鬆地對其進行分析、聚類或用作幾乎所有機器學習模型的模型特徵。

缺點:

  • 使用這種方法,我們必然會丟失一些信息:

    • 在第一步中,當我們用相似度矩陣替換原始數據時
    • 在第二步中,當我們使用嵌入來降低維度時
  • 根據數據和距離函數,距離矩陣的計算可能很耗時。 這可以通過有效寫入的距離函數來緩解。
  • 一些嵌入對數據中的噪聲非常敏感。 這可以通過額外的數據清理來緩解。
  • 一些嵌入對其超參數的選擇很敏感。 這可以通過仔細分析或超參數調整來緩解。

替代方案:為什麼不使用……?

  • 為什麼不直接在數據上使用嵌入,而不是距離矩陣?
    如果您知道可以直接有效地對數據進行編碼的嵌入,請務必使用它。 問題是它並不總是存在。
  • 為什麼不在距離矩陣上使用聚類?
    如果你唯一的目標是分割你的數據集,那麼這樣做是完全可以的。 一些聚類方法也利用嵌入(例如,光譜聚類)。 如果您想了解更多信息,這裡是關於集群化的教程。
  • 為什麼不直接使用距離矩陣作為特徵?
    距離矩陣的大小為 $(n_{samples}, n_{samples})$。 並非所有模型都可以有效地處理它——有些可能過擬合,有些可能擬合緩慢,有些可能完全無法擬合。 具有低方差的模型在這裡是一個不錯的選擇,例如線性和/或正則化模型。
  • 為什麼不直接使用帶距離矩陣的 SVM?
    SVM 是一個很棒的模型,在我們的用例中表現良好。 但是,有一些警告。 首先,如果我們想添加其他特徵(可能只是簡單的數字),我們將無法直接做到這一點。 我們必須將它們合併到我們的相似性矩陣中,並且可能會丟失一些有價值的信息。 其次,與 SVM 一樣好,另一種模型可能更適合您的特定問題。
  • 為什麼不直接使用深度學習?
    的確,對於任何問題,只要搜索足夠長的時間,就能找到合適的神經網絡。 但請記住,尋找、訓練、驗證和部署這個神經網絡的過程不一定是一個簡單的過程。 所以,一如既往,用你最好的判斷。

一句話

如果您碰巧處理複雜的非數值數據,尤其是當您無法將數據直接轉換為向量空間並且希望為模型提供低維輸入時,嵌入與距離矩陣的結合是一個非常有用的工具。