[譯] 支持向量機(SVM)教程

支持向量機(SVM)教程

從例子中學習 SVM

Statsbot 團隊發佈關於時間序列異常檢測的帖子以後,許多讀者要求咱們告訴他們有關支持向量機的方法。如今是時候在不涉及複雜數學知識的狀況下向您介紹SVM,並分享有用的庫和資源以幫助您入門了。html


若是您已經使用機器學習來執行分類,您可能據說過支持向量機(SVM)。50 多年前被引入,它們隨着時間的推移而發展,而且已經適應了各類其餘問題,如迴歸分析、異常值分析排名前端

SVM 是許多機器學習從業者的最佳工具。在[24]7,咱們也使用它們來解決各類問題。node

在這篇文章中,咱們將嘗試深刻了解 SVM 的工做原理。我會專一於創建直覺而並不追求嚴謹。這基本上意味着咱們將盡量多地跳過數學並創建起對工做原理的直覺理解。android

分類問題

假設您的大學提供機器學習(ML)課程。課程導師觀察到,若是學生擅長數學或統計學,他們將得到最大的收益。隨着時間的推移,他們記錄了這些科目的入學學生的分數。此外,對於其中的每個學生,他們都有一個描述他們在 ML 課程中表現「好」或「差」的標籤。ios

如今,他們想要肯定數學和統計學分數與 ML 課程中的表現之間的關係。也許,根據他們發現的內容,他們但願指定入學課程的先決條件。git

狀況會怎麼樣呢? 讓咱們從表示他們擁有的數據開始。咱們能夠繪製一個二維圖,其中一個軸表明數學分數,而另外一個表明統計分數。具備特定分數的學生在圖表上顯示爲一個點。github

點的顏色——綠色或紅色——表明他在 ML 課程中的表現:分別爲「好」或「差」。web

繪出來的圖有多是這樣的:算法

當學生要求報名時,咱們的教師會要求她提供她的數學和統計學分數。根據他們已有的數據,他們會對 ML 課程中的表現作出有根據的的猜想。後端

咱們本質上想要的是某種「算法」,你能夠在其中輸入表格的「得分元組」(math_score,stats_score)。它會告訴你某個學生是圖形上的紅點仍是綠點(紅色/綠色也可稱爲標籤)。固然,該算法以某種方式體現了咱們已經擁有的數據中存在的模式,也稱爲訓練數據

在這種狀況下,找到穿過紅點即和綠點集之間的直線,而後肯定得分元組落在該線的哪一側,是一個很好的算法。咱們採起一方——綠色方面或紅色方面——做爲她在課程中最有可能表現的一個指標。

這裏的直線就是咱們的分割邊界(separating boundary)(由於它分隔了標籤)或分類器(咱們用它來對點進行分類)。該圖展現了在咱們的問題中兩種都有可能的產生的分類器。

好的 vs 壞的分類器

這是一個有趣的問題:上面的兩條線均可以將紅色和綠色的數據集分開。咱們是否有充分的理由選擇其中一個而不是另外一個?

請記住,分類器的價值不在於它如何區分訓練數據。咱們最終但願它對還沒有看到的數據點進行分類(稱爲測試數據)。鑑於此,咱們但願選擇一條線來捕獲訓練數據中的基本模式,所以頗有可能它在測試數據上表現良好。

上面的第一條直線看起來有點「傾斜」。在它的下半部分附近,它彷佛太靠近紅點色數據集了,而在它的上半部分它太靠近綠色數據集了。固然,它能夠完美地分離訓練數據,可是若是測試點離數據集稍遠一點,那麼它極可能會獲得一個錯誤的標籤。

第二條直線沒有這個問題。例如,看看下圖中已正方形顯示的測試點以及分類器指定的標籤。

第二條直線儘量遠離兩個數據集,同時使訓練數據正確分離。它經過兩個數據集的中間部分,它不那麼「冒險」,能夠爲每一個類提供一些空間來佈置數據分佈,從而很好的適用於測試數據。

SVM 試圖找到這第二種線。咱們經過視覺選擇了更好的分類器,但咱們須要更精確地定義基礎原理以便在通常狀況下應用它。這是 SVM 的簡化版本:

  1. 找到可以正確分類訓練數據的直線。
  2. 在全部這些直線中,選擇與它最近的點距離最遠的直線。

距離這條直線的最近那些點稱爲支持向量(support vectors)。他們圍繞這條線定義的區域稱爲間隔(margin)

下面顯示的是第二條直線的支持向量:帶有黑色邊緣的點(有兩個)和間隔(陰影區域)。

支持向量機爲您提供了一種在許多可能的分類器之間進行選擇的方法,以確保以更高的正確率標記測試數據。這種方法很簡潔吧?

雖然上圖顯示了在二維空間中的直線和數據,但必須注意 SVM 在任意數量的維度上均可以運行; 在這些維度中,他們找到了二維直線的類比。

例如,在三維空間中,他們尋找平面(plane)(咱們將很快看到這個例子),而且在更高的維度中,他們尋找超平面(hyperplane) ——二維直線和三維平面到任意數量的維度的推廣。

可由直線(或一般爲超平面)分隔的數據稱爲線性可分(linearly separaterable) 數據。超平面充當線性分類器(linear classifier)

容錯

咱們在最後一節中查看了徹底線性可分離數據的簡單狀況。然而,真實世界的數據一般是混亂的。你幾乎總會遇到一些線性分類器沒法正確分隔的實例。

如下是此類數據的示例:

顯然,若是咱們使用線性分類器,咱們永遠沒法徹底分離標籤。咱們也不想徹底拋棄線性分類器,由於除了一些錯誤的點以外,它看起來彷佛很適合這個問題。

SVM 如何處理這個問題?它們容許您指定您願意接受的錯誤數量。

您能夠爲 SVM 提供一個名爲「C」的參數;這容許你決定如下二者之間的權衡:

  1. 有很大的間隔。
  2. 正確分類訓練數據。較高的 C 值意味着您但願訓練數據上的錯誤較少。

值得重申的是,這是一個 權衡(tradeoff) 辦法。您能夠在 代價(expense) 範圍內爲訓練數據選擇更好地分類器。

下面的圖顯示了當咱們增長 C 的值時,分類器和間隔是如何變化的(支持向量未顯示):

注意當咱們增長 C 的值時,直線如何「傾斜」。在高值時,它會嘗試容納圖表右下方存在的大多數紅點。這可能不是咱們想要的測試數據。C=0.01 的第一個圖彷佛更好地捕捉了整體趨勢,儘管與 較高 C 值的結果相比,訓練數據的準確度較低。

因爲這是一個權衡辦法,請注意當咱們增長 C 的值時,間隔的寬度會縮小。

在前面的例子中,間隔是數據點的「無人之地」。在這裏,咱們看到不可能有這樣一種情況,既有一個良好的分割邊界,又在間隔中不存在任何點。實際上一些點進入到了間隔裏面。

一個重要的實際問題是爲 C 肯定一個好的值。因爲現實世界的數據幾乎從不可分離,所以這種需求常常出現。咱們一般使用像 交叉驗證(cross-validation) 這樣的技術爲 C 選擇一個好的值。

非線性可分離數據

咱們已經看到支持向量機如何系統地處理完美/幾乎線性可分離的數據。它如何處理絕對不可線性分離的數據的狀況呢?畢竟,不少現實世界的數據屬於這一類。固然,尋找超平面已再也不適用。鑑於 SVM 在這項任務上表現出色,這彷佛很不幸。

如下是非線性可分數據的示例(這是着名的 XOR 數據集的變體),與線性分類器 SVM 一塊兒顯示:

你必定會認爲這看起來不太好。咱們在訓練集上的準確率只有 75% ——這是隻用一條直線進行分隔所能達到的最優性能。更重要的是,這條直線很是靠近一些數據。最優的準確度也並非很好,並且爲了達到平衡,這條線幾乎徹底跨過了一些點。

咱們須要作得更好

這就是我對 SVM 最喜歡的一點。這是咱們到目前爲止所擁有的:咱們有一種很是擅長尋找超平面的技術。可是,咱們也有不可線性分離的數據。那麼咱們該怎麼辦?將數據投影到一個能夠線性分離的空間,並在這個空間中找到一個超平面!

我將一步一步地講解這個想法。

咱們從上圖中的數據集開始,並將其投影到三維空間中,其中新座標爲:

這就是投影數據的樣子。你看到咱們能夠在平面上滑動的平面嗎?

讓咱們運行 SVM 吧:

好啦!咱們完美地將標籤分離!讓咱們將平面投射回原始的二維空間,看看分割邊界是什麼樣的:

在訓練數據集上有 100% 的精度而且分隔邊界不會太靠近數據!好極了!

原始空間中分割邊界的形狀取決於投影。在投影空間中,這每每是一個超平面。

請記住,投影數據的主要目的是爲了利用 SVM 發現分隔超平面的能力。

將其映射回原始空間時,分割邊界再也不是直線。對於間隔和支持向量也是如此。就咱們的視覺直覺而言,它們在投射空間中是有意義的。

看看它們在投影空間中的樣子,而後是原始空間。3D 間隔是分離超平面上方和下方的平面之間的區域(沒有陰影以免視覺混亂)。

在投影空間中有 4 個支持向量,這彷佛是合理的。它們位於定義間隔的兩個平面上。在原始空間中,它們仍然處在間隔上,但到這一步彷佛還不夠。

讓咱們退一步分析發生的事情:

1.我怎麼知道將數據投射到哪一個空間?

看起來我徹底明確該怎麼作——在那裏放置一個 2 的平方根!

在這個例子中,我想展現的是向高維的投影是如何工做的,因此我選擇了一個很是具體的投影。通常來講,這一點是很難知道的。然而,咱們所知道的是,因爲 Cover 定理,當投影到更高維度時,數據更可能是線性可分的。

在實踐中,咱們嘗試一些高維投影,看看哪些有效。實際上,咱們能夠將數據投影到無限維度,而且一般效果還不錯。這值得詳細討論,也就是下一節的內容。

2. 我應該首先投影數據,而後運行 SVM 嗎?

不。爲了使上面的例子易於掌握,個人作法看起來好像咱們須要首先投影數據。事實上,你要求 SVM 爲你進行投影。這有一些好處。首先,SVM 使用一些名爲**核函數(kernel)**的東西進行這些投影,這些投影很是快(咱們很快就會看到)。

另外,還記得我在前一節提到的投射到無限維度嗎?若是你本身投影數據,你如何表示或存儲無限維度?事實證實,SVM 對此很是聰明,一樣得益於核函數。

如今是時候來看看核函數了。

核函數

最後,讓SVM 有效工做是有祕訣的。這也是咱們須要學習數學知識的地方。

讓咱們來看看到目前爲止咱們所看到的狀況:

  1. 對於線性可分的數據,SVM 表現得很是好。
  2. 對於幾乎可線性分離的數據,經過使用正確的 C 值,SVM 仍然能夠很好地運行。
  3. 對於不能線性分離的數據,咱們能夠將數據投影到徹底/幾乎可線性分離的空間,從而將問題降至第 1 步或第 2 步,咱們又從新開始處理數據。

看起來,將 SVM 廣泛適用於各類狀況的一件重要操做是是將它投射到更高的維度。這就是核函數的用處。

首先,說點題外話。

SVM 的一個很是使人驚訝的地方是,在它使用的全部數學運算中,精確投影,甚至維數的數量都沒有顯現。你能夠根據各類數據點(表示爲向量)之間的點積(dot products) 來表達全部內容。對於 p 維向量的 ij,其中第一個下標表示某一個點,第二個下標表示維度編號:

點積是這樣定義的:

若是咱們的數據集中有 n 個點,則 SVM 僅僅須要經過每對點的點積來構建分類器。僅此而已。當咱們想要將數據投影到更高維度時,也是如此。咱們不須要爲 SVM 提供精確的投影;咱們須要在投影空間中的全部點的組合之間計算點積。

這是有重大意義的,由於這正是核函數所作的。核函數(kernel function的縮寫)在原始空間中將兩個點做爲輸入,並直接在投影空間中給出點積。

讓咱們從新審視以前作過的投影,看看咱們是否能夠提出相應的核函數。咱們還將留意爲投影執行的計算次數,而後計算點積——看看如何使用核函數進行比較。

對於點 i

咱們相應的投影點是:

要計算此投影,咱們須要執行如下操做:

  • 得到新的第一維數據:1 次乘積
  • 第二維數據:1 次乘積
  • 第三維數據:2 次乘積

總共,1+1+2 = 4 次乘積

新維度中的點積是:

要計算兩個點 ij 的點積,咱們須要先計算它們的投影。所以,4 + 4 = 8 次乘積,而後點積自己須要 3 次乘法和 2 次加法。

總之,就是:

  • 乘積:8(投影)+ 3(點積)= 11 次乘積
  • 加法:2(點積)

總共是 11 + 2 = 13 次運算

我聲明這個核函數的結果是同樣的:

咱們首先在原始空間中取矢量的點積,而後對結果進行平方運算。

讓咱們展開它並檢查個人說法是否正確:

確實如此。這須要多少次運算?看看上面的第(2)步。要計算二維的點積,我須要 2 次乘法和 1 次加法。平方是另外一種乘法。

因此,總共是:

  • 乘法:2(原始空間中的點積)+ 1(對於平方結果)= 3 次乘法
  • 加法:1(原始空間中的點積)

共計 3 + 1 = 4 次運算。這只是咱們以前須要的進行的 31% 的運算量。

看起來使用核函數來計算咱們須要的點積更快。這可能看起來不是什麼大問題:咱們正在對比 4 次運算和 13 次運算,可是隨着輸入點的維度愈來愈多,而且投影空間的維度愈來愈高,大型數據集的計算節省的時間就愈來愈多。這就是使用核函數的一個巨大優點。

大多數 SVM 庫已經預先打包了一些流行的核函數,如 多項式、徑向基函數(RBF)Sigmoid函數。當咱們不使用投影時(如本文的第一個例子),咱們在原始空間中計算點積——咱們把這個稱之爲線性核函數

其中許多核函數爲您提供了額外的手段,能夠根據您的數據進一步調整它。例如,多項式核函數:

容許您選擇 cd 的值(多項式的次數)。對於上面的 3D 投影,我使用了 c = 0d = 2 的多項式核函數。

可是咱們尚未完成核函數的強大功能!

還記得我以前提到過的投射到無限維度嗎?若是您尚未猜到,其實讓它工做的方法就是擁有合適的核函數。這樣,咱們就沒必要對輸入數據進行投影,也不用擔憂存儲無限維數據的問題。

若是你有準確的投影數據,核函數將會計算點積。

RBF 核函數一般用於特定的無限維投影。咱們將不在這裏進行數學計算,請查看本文末尾的參考資料。

咱們怎樣才能在無限維度的狀況下仍然能夠計算點積?若是您發現這個問題使人困惑,請考慮咱們如何計算無窮級數的和。相似的,點積中有無限項,但剛好存在計算其總和的公式。

這回答了咱們在上一節中提出的問題。總結一下:

  1. 咱們一般不會爲咱們的數據定義具體的投影。相反,咱們從可用核函數中挑選,在某些狀況下調整它們,以找到最適合數據的核函數。
  2. 固然,沒有什麼能阻止咱們定義本身的核函數,或者本身執行投影,但在不少狀況下咱們並不須要這麼作。或者咱們至少從咱們能作的事情開始。
  3. 若是有可用於咱們想要的投影的核函數,咱們通常選擇使用核函數,由於它一般計算更快
  4. RBF 核函數能夠將點投影到無限維度。

開始使用 SVM 庫

有不少 SVM 庫供你開始練習:

scikit-learn 這樣的許多通用 ML 庫也提供 SVM 模塊,這些模塊一般是專用 SVM 庫的包裝器。個人建議是從通過試驗測試的 libSVM 開始。

libSVM 可用做命令行工具,但下載文件也捆綁了 Python、Java 和 Matlab 包裝器。只要你有一個包含 libSVM 可以理解的格式的數據文件(下載的 README 文件解釋了這個,以及其餘可用的選項)你就可以使用它。

事實上,若是你須要很是快速地瞭解不一樣的核函數和不一樣的 C 值等等是如何影響尋找分割邊界的,請在其主頁上嘗試使用「圖形界面」。標記屬於不一樣類的數據點,選擇 SVM 參數,而後點擊 Run!

我火燒眉毛地迅速標出幾個點:

是的,我不是讓 SVM 變得容易。

而後我嘗試了幾個核函數:

界面不顯示分割邊界,但顯示 SVM 學習屬於特定標籤的區域。如你所見,線性核函數徹底忽略了紅點。它認爲整個空間爲黃色(一說綠色)。可是 RBF 核函數巧妙地使用了戒指形狀的區域覆蓋了紅色標記!

有用的資源

咱們一直主要依靠視覺上的直觀理解。雖然這是得到初步理解的好方法,但我強烈建議您深刻挖掘。視覺上的直觀理解的例子可能不足以理解間隔寬度以及用於非線性可分離狀況的支持向量。

請記住,這些數量是經過優化權衡來決定的。除非你去看數學原理,不然一些結果可能看似違反直覺。

數學有用的另外一個方面是理解核函數。我在這篇短文中幾乎沒有介紹過 RBF 核函數。我但願它的「神祕」感——它與無限維投影的關係再加上最後一個數據集(「環」)上的奇妙結果——已經說服你去仔細研究它。

我推薦的資源:

  1. 視頻講座:從數據中學習。做者是 Yaser Abu-Mostafa。講座從 14 到 16 部分討論了 SVM 和核函數。若是你正在尋找 ML 的簡介,我也強烈推薦整個系列,它在數學和直覺之間保持着良好的平衡。
  2. 書:統計學習的要素。做者是 Trevor Hastie、Robert Tibshirani 和 Jerome Friedman。第 4 章介紹了 SVM 背後的基本思想,第 12 章則全面論述了它。

好好學習,每天向上!

若是發現譯文存在錯誤或其餘須要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可得到相應獎勵積分。文章開頭的 本文永久連接 即爲本文在 GitHub 上的 MarkDown 連接。


掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章
相關標籤/搜索