乾貨 詳解支持向量機(附學習資源)

2021-02-23 機器之心

選自The Yhat 

作者:Greg

機器之心編譯

參與:Jane W、蔣思源

支持向量機(SVM)已經成為一種非常流行的算法。本文將嘗試解釋支持向量機的原理,並列舉幾個使用 Python Scikits 庫的例子。本文的所有代碼已經上傳 Github。有關使用 Scikits 和 Sklearn 的細節,我將在另一篇文章中詳細介紹。


什麼是 支持向量機(SVM)?

SVM 是一種有監督的機器學習算法,可用於分類或回歸問題。它使用一種稱為核函數(kernel)的技術來變換數據,然後基於這種變換,算法找到預測可能的兩種分類之間的最佳邊界(optimal boundary)。簡單地說,它做了一些非常複雜的數據變換,然後根據定義的標籤找出區分數據的方法。

為什麼這種算法很強大?

在上面我們說 SVM 能夠做分類和回歸。在這篇文章中,我將重點講述如何使用 SVM 進行分類。特別的是,本文的例子使用了非線性 SVM 或非線性核函數的 SVM。非線性 SVM 意味著算法計算的邊界不再是直線。它的優點是可以捕獲數據之間更複雜的關係,而無需人為地進行困難的數據轉換;缺點是訓練時間長得多,因為它的計算量更大。

牛和狼的分類問題

什麼是核函數技術?

核函數技術可以變換數據。它具備一些好用的分類器的特點,然後輸出一些你無需再進行識別的數據。它的工作方式有點像解開一條 DNA 鏈。從傳入數據向量開始,通過核函數,它解開並組合數據,直到形成更大且無法通過電子表格查看的數據集。該算法的神奇之處在於,在擴展數據集的過程中,能發現類與類之間更明顯的邊界,使得 SVM 算法能夠計算更為優化的超平面。

現在假裝你是一個農夫,那麼你就有一個問題——需要建立一個籬笆,以保護你的牛不被狼攻擊。但是在哪裡築籬笆合適呢?如果你真的是一個用數據說話的農夫,一種方法是基於牛和狼在你的牧場的位置,建立一個分類器。通過對下圖中幾種不同類型的分類器進行比較,我們看到 SVM 能很好地區分牛群和狼群。我認為這些圖很好地說明了使用非線性分類器的好處,可以看到邏輯回歸和決策樹模型的分類邊界都是直線。

重現分析過程

想自己繪出這些圖嗎?你可以在你的終端或你選擇的 IDE 中運行代碼,在這裡我建議使用 Rodeo(Python 數據科學專用 IDE 項目)。它有彈出製圖的功能,可以很方便地進行這種類型的分析。它也附帶了針對 Windows 作業系統的 Python 內核。此外,感謝 TakenPilot(一位編程者 https://github.com/TakenPilot)的辛勤工作,使得 Rodeo 現在運行閃電般快速。

下載 Rodeo 之後,從我的 github 頁面中下載 cows_and_wolves.txt 原始數據文件。並確保將你的工作目錄設置為保存文件的位置。

Rodeo 下載地址:https://www.yhat.com/products/rodeo

好了,現在只需將下面的代碼複製並粘貼到 Rodeo 中,然後運行每行代碼或整個腳本。不要忘了,你可以彈出繪圖選項卡、移動或調整它們的大小。

# Data driven farmer goes to the Rodeoimport numpy as npimport pylab as plfrom sklearn import svmfrom sklearn import linear_modelfrom sklearn import treeimport pandas as pddef plot_results_with_hyperplane(clf, clf_name, df, plt_nmbr):    x_min, x_max = df.x.min() - .5, df.x.max() + .5    y_min, y_max = df.y.min() - .5, df.y.max() + .5    # step between points. i.e. [0, 0.02, 0.04, ...]    step = .02    # to plot the boundary, we're going to create a matrix of every possible point    # then label each point as a wolf or cow using our classifier    xx, yy = np.meshgrid(np.arange(x_min, x_max, step), np.arange(y_min, y_max, step))    Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])    # this gets our predictions back into a matrix    Z = Z.reshape(xx.shape)    # create a subplot (we're going to have more than 1 plot on a given image)    pl.subplot(2, 2, plt_nmbr)    # plot the boundaries    pl.pcolormesh(xx, yy, Z, cmap=pl.cm.Paired)    # plot the wolves and cows    for animal in df.animal.unique():        pl.scatter(df[df.animal==animal].x,                   df[df.animal==animal].y,                   marker=animal,                   label="cows" if animal=="x" else "wolves",                   color='black')    pl.title(clf_name)    pl.legend(loc="best")data = open("cows_and_wolves.txt").read()data = [row.split('\t') for row in data.strip().split('\n')]animals = []for y, row in enumerate(data):    for x, item in enumerate(row):        # x's are cows, o's are wolves        if item in ['o', 'x']:            animals.append([x, y, item])df = pd.DataFrame(animals, columns=["x", "y", "animal"])df['animal_type'] = df.animal.apply(lambda x: 0 if x=="x" else 1)# train using the x and y position coordiantestrain_cols = ["x", "y"]clfs = {    "SVM": svm.SVC(),    "Logistic" : linear_model.LogisticRegression(),    "Decision Tree": tree.DecisionTreeClassifier(),}plt_nmbr = 1for clf_name, clf in clfs.iteritems():    clf.fit(df[train_cols], df.animal_type)    plot_results_with_hyperplane(clf, clf_name, df, plt_nmbr)    plt_nmbr += 1pl.show()

SVM 解決難題

在因變量和自變量之間的關係是非線性的情況下,帶有核函數的 SVM 算法會得到更精確的結果。在這裡,轉換變量(log(x),(x ^ 2))就變得不那麼重要了,因為算法內在地包含了轉換變量的過程。如果你思考這個過程仍然有些不清楚,那麼看看下面的例子能否讓你更清楚地理解。

假設我們有一個由綠色和紅色點組成的數據集。當根據它們的坐標繪製散點圖時,點形成具有綠色輪廓的紅色圓形(看起來很像孟加拉國的旗子)。

如果我們丟失了 1/3 的數據,那麼會發生什麼?如果無法恢復這些數據,我們需要找到一種方法來估計丟失的 1/3 數據。

那麼,我們如何弄清缺失的 1/3 數據看起來像什麼?一種方法是使用我們所擁有的 80%數據作為訓練集來構建模型。但是使用什麼模型呢?讓我們試試下面的模型:

對每個模型進行訓練,然後用這些模型來預測丟失的 1/3 數據。下面是每個模型的預測結果:

模型算法比較的實現

下面是比較 logistic 模型、決策樹和 SVM 的代碼。

import numpy as npimport pylab as plimport pandas as pdfrom sklearn import svmfrom sklearn import linear_modelfrom sklearn import treefrom sklearn.metrics import confusion_matrixx_min, x_max = 0, 15y_min, y_max = 0, 10step = .1# to plot the boundary, we're going to create a matrix of every possible point# then label each point as a wolf or cow using our classifierxx, yy = np.meshgrid(np.arange(x_min, x_max, step), np.arange(y_min, y_max, step))df = pd.DataFrame(data={'x': xx.ravel(), 'y': yy.ravel()})df['color_gauge'] = (df.x-7.5)**2 + (df.y-5)**2df['color'] = df.color_gauge.apply(lambda x: "red" if x <= 15 else "green")df['color_as_int'] = df.color.apply(lambda x: 0 if x=="red" else 1)print "Points on flag:"print df.groupby('color').size()printfigure = 1# plot a figure for the entire datasetfor color in df.color.unique():    idx = df.color==color    pl.subplot(2, 2, figure)    pl.scatter(df[idx].x, df[idx].y, color=color)    pl.title('Actual')train_idx = df.x < 10train = df[train_idx]test = df[-train_idx]print "Training Set Size: %d" % len(train)print "Test Set Size: %d" % len(test)# train using the x and y position coordiantescols = ["x", "y"]clfs = {    "SVM": svm.SVC(degree=0.5),    "Logistic" : linear_model.LogisticRegression(),    "Decision Tree": tree.DecisionTreeClassifier()}# racehorse different classifiers and plot the resultsfor clf_name, clf in clfs.iteritems():    figure += 1    # train the classifier    clf.fit(train[cols], train.color_as_int)    # get the predicted values from the test set    test['predicted_color_as_int'] = clf.predict(test[cols])    test['pred_color'] = test.predicted_color_as_int.apply(lambda x: "red" if x==0 else "green")    # create a new subplot on the plot    pl.subplot(2, 2, figure)    # plot each predicted color    for color in test.pred_color.unique():        # plot only rows where pred_color is equal to color        idx = test.pred_color==color        pl.scatter(test[idx].x, test[idx].y, color=color)    # plot the training set as well    for color in train.color.unique():        idx = train.color==color        pl.scatter(train[idx].x, train[idx].y, color=color)    # add a dotted line to show the boundary between the training and test set    # (everything to the right of the line is in the test set)    #this plots a vertical line    train_line_y = np.linspace(y_min, y_max) #evenly spaced array from 0 to 10    train_line_x = np.repeat(10, len(train_line_y)) #repeat 10 (threshold for traininset) n times    # add a black, dotted line to the subplot    pl.plot(train_line_x, train_line_y, 'k--', color="black")    pl.title(clf_name)    print "Confusion Matrix for %s:" % clf_name    print confusion_matrix(test.color, test.pred_color)pl.show()

在 Rodeo 中複製和運行上面的代碼。

結果


從這些圖中可以清楚地看出 SVM 更好。為什麼呢?如果觀察決策樹和 GLM(廣義線性模型,這裡指 logistic 回歸)模型的預測形狀,你會看到預測給出的直邊界。因為它們的輸入模型沒有任何變換來解釋 x、y 以及顏色之間的非線性關係。給定一組特定的變換,我們絕對可以使 GLM 和 DT(決策樹)得出更好的結果,但尋找合適的變換將浪費大量時間。在沒有複雜的變換或特徵縮放的情況下,SVM 算法 5000 數據點只錯誤地分類了 117 點(98%的精度,而 DT 精確度為 51%,GLM 精確度為 12%)。由於所有錯誤分類的點是紅色,所以預測的結果形狀有輕微的凸起。

不適用的場合

那為什麼不是所有問題都使用 SVM?很遺憾,SVM 的魅力也是它最大的缺點。複雜數據變換以及得到的決策邊界平面是很難解釋的。這就是為什麼它通常被稱為「黑箱」的原因。GLM 和決策樹恰恰相反,它們的算法實現過程及怎樣減少成本函數得到優良結果都很容易理解。

更多學習資源


想了解更多關於 SVM 的知識?以下是我收藏的一些好資源:

初級——SVM 教程:基礎教程,作者是 MIT 的 Zoya Gavrilov

連結地址:http://web.mit.edu/zoya/www/SVM.pdf

初級——SVM 算法原理:Youtube 視頻,作者是 Thales SehnKörting

連結地址:https://youtu.be/1NxnPkZM9bc

中級——支持向量機在生物醫學中的簡要介紹:紐約大學 & 範德堡大學提供的課件

連結地址:https://www.med.nyu.edu/chibi/sites/default/files/chibi/Final.pdf

高級——模式識別下的支持向量機教程:作者是貝爾實驗室(Bell Labs)的 Christopher Burges

連結地址:http://research.microsoft.com/en-us/um/people/cburges/papers/SVMTutorial.pdf

原文連結:http://blog.yhat.com/posts/why-support-vector-machine.html

©本文為機器之心編譯,轉載請聯繫本公眾號獲得授權

✄---

加入機器之心(全職記者/實習生):hr@jiqizhixin.com

投稿或尋求報導:editor@jiqizhixin.com

廣告&商務合作:bd@jiqizhixin.com


相關焦點

  • 機器學習實戰 | 支持向量機·sklearn 參數詳解
    接上篇的內容「一文帶你了解什麼是支持向量機」,相信大家已經對 SVM 已有些了解,關於 SVM 的公式推導可參考李航《統計學習方法
  • 支持向量機(SVM)算法總結
    ,同時兼有數度快,支持數據量級大(相對經典機器學習算法)等特點使其在工程實踐中的得到了廣泛的應用。今天我們就聊一聊支持向量機算法。要理解svm我們需要先理解什麼是間隔最大化,首先從簡單的線性二分類開始開始說起。要想對不用的樣本空間分開來,如下如所示,需要找出一條線將不同分類的樣本隔離開。
  • 從爬蟲到機器學習-淺談支持向量機(SVM)
    作者:劉澤平 來源:人工智慧學習圈支持向量機(SVM)是一個二進位分類模型,其基本模型是線性分類器。SVM還包括核技能,這使其成為實質上的非線性分類器。SVM學習算法是求解凸二次規劃的最佳算法。超平面、支持向量與間隔超平面可以理解為一維空間中的點,二維空間中的線,三維空間中平面的擴展,並且是分類決策的邊界。支持向量機(SVM)設計用於二進位分類任務。這個想法是基於一組訓練樣本D在樣本空間中找到一個分離的超平面,以分離不同類型的樣本。
  • 如何使用支持向量機學習非線性數據集
    支持向量機(SVM)什麼是支持向量機呢?支持向量機是監督機器學習模型,可對數據進行分類分析。實際上,支持向量機算法是尋找能將實例進行分離的最佳超平面的過程。那麼我們如何使用支持向量機來擬合非線性機器學習數據集呢?使用SVM進行實驗創建機器學習數據集首先創建非線性機器學習數據集。
  • 支持向量機
    但是在支持向量機這裡,把參數提到前面,用參數 C 作為 A 的參數,以 A 作為權重。支持向量機的代價函數為:有別於邏輯回歸假設函數輸出的是概率,支持向量機它是直接預測 y 的值是0還是1。也就是說其假設函數是這樣子的:二.
  • 想入門機器學習?機器之心為你準備了一份中文資源合集
    從頭開始:用Python實現帶隨機梯度下降的Logistic回歸如何通過牛頓法解決Logistic回歸問題擬合目標函數後驗分布的調參利器:貝葉斯優化支持向量機(SVM)支持向量機提供了不同的分類方法(包括線性和非線性方法)。該算法非常簡單,具備基礎幾何知識的人也可以學會。
  • 理解支持向量機
    要理解支持向量機,下面的數學知識是必不可少的:1.解析幾何中點到平面距離的計算公式2.拉格朗日對偶,包括強對偶條件、Slater條件3.KKT條件4.凸優化,Hessian矩陣在推導和證明中將會大量使用這些知識,如果對它們還不清楚,一定要沉下心來仔細學習理解。本文不對這些數學知識做專門的介紹。
  • 機器學習05:支持向量機2
    上一篇文章介紹了機器學習中支持向量機的基本原理,並且在文章末尾介紹了一種利用Python求解二項規劃問題極值的方法。這篇文章我將利用這種方法一步步求解上文中提及的$-ec{alpha}-$、$-ec{w}-$、$-b-$,藉此複習和驗證支持向量機的知識點。
  • 支持向量機(SVM)原理剖析
    這顯示出支持向量機的一個重要性質:「訓練完成後,大部分的訓練樣本都不需要保留,最終模型僅與支持向量有關」。綜合以上討論,我們可以得到「線性支持向量機」學習算法如下:「輸入」:訓練數據集 由於在線性支持向量機學習的對偶問題裡,目標函數和分類決策函數都「只涉及實例和實例之間的內積,所以不需要顯式地指定非線性變換,而是用核函數替換當中的內積」。核函數表示,通過一個非線性轉換後的兩個實例間的內積。
  • 從零推導支持向量機 (SVM) | 雷鋒網
    (LAMDA)碩士生,研究方向為計算機視覺和機器學習,特別是視覺識別和深度學習。儘管現在深度學習十分流行,了解支持向量機的原理,對想法的形式化、簡化,及一步步使模型更一般化的過程,及其具體實現仍然有其研究價值。另一方面,支持向量機仍有其一席之地。相比深度神經網絡,支持向量機特別擅長於特徵維數多於樣本數的情況,而小樣本學習至今仍是深度學習的一大難題。1.
  • 在深度學習盛行的時代,你仍需知道支持向量機這6大優勢
    20世紀90年代中期,Vapnik和他的AT&T Bell實驗室小組提出了支持向量機算法,該算法以統計學習理論為基礎,採用結構風險最小化準則設計學習機器,較好地解決了非線性、高維數、局部極小點等問題,並具有較好的推廣能力。
  • 【機器學習基礎】數學推導+純Python實現機器學習算法8-9:線性可分支持向量機和線性支持向量機
    為了處理非線性的情況,在感知機模型的基礎上有了兩個方向,一個就是上一講說到的神經網絡,大家也看到了,現在深度學習大放異彩,各種網絡功能強大。但實際上在神經網絡興起之前,基於感知機的另一種模型——支持向量機,同樣可以解決非線性問題。     支持向量機一般來說有三種任務類型:線性可分情況,近似線性可分情況以及線性不可分情況。
  • SVM | 支持向量機原理講解(一)
    深度學習(2012)出現之前,如果不考慮集成學習的算法,不考慮特定的訓練數據集,在分類算法中的表現SVM說是排第一估計是沒有什麼異議的。 SVM本來是一種線性分類和非線性分類都支持的二元分類算法,但經過演變,現在也支持多分類問題,也能應用到了回歸問題。本篇文章重點講解線性支持向量機的模型原理和目標函數優化原理。
  • 支持向量機SVM原理(參數解讀和python腳本)
    歡迎各位同學學習python信用評分卡建模視頻系列教程(附代碼, 博主錄製) :騰訊課堂報名入口
  • 【機器學習基礎】支持向量機超參數的可視化解釋
    作者 | Soner Yıldırım 編譯 | VK 來源 | Towards Datas Science支持向量機(SVM)是一種應用廣泛的有監督機器學習算法。在這篇文章中,我們將深入探討支持向量機的兩個重要超參數C和gamma,並通過可視化解釋它們的影響。所以我假設你對算法有一個基本的理解,並把重點放在這些超參數上。支持向量機用一個決策邊界來分離屬於不同類別的數據點。
  • sklearn學習(五):支持向量機原理實現及簡單參數優化(附代碼)
    支持向量機的核心在於他的優化目標,其通俗解釋為找到一條線,使得離最近的點的距離能夠最遠。現在回到我們的距離公式。為什麼叫支持向量機支持向量機,機其實是指邊界,若向量在邊界上則α大於零,若不在邊界上則統一都為零為零的向量不是支持向量,對結果半點影響都沒有。
  • 支持向量機和邏輯回歸區別
    支持向量機和邏輯回歸都是比較常用的分類模型,但是二者之間有什麼區別呢?1. 損失函數對於支持向量機,其損失函數為折頁損失函數;而邏輯回歸的損失函數為交叉熵損失函數。如果將支持向量機的折頁損失函數換為交叉熵損失函數,那麼它與帶了L2正則項的邏輯回歸將幾乎一致,這是第一點不同,損失函數不同。2. 分類方法其次使用了非線性核函數的支持向量機具備了非線性劃分的能力,邏輯回歸則通過自變量變換的方式來獲取非線性劃分的能力,這是第二點不同(本質上核變換不就是自變量變換嘛)。3.
  • 入門支持向量機1:圖文詳解SVM原理與模型數學推導
    0x00 前言 支撐向量機,SVM(Support Vector Machine),其實就是一個線性分類器。在最初接到這個算法時,我們可能會一頭霧水:這個名詞好奇怪[問號臉],怎麼「支持」?什麼「向量」,哪來的「機」?
  • 機器學習算法入門之「支持向量機」
    本文要介紹的支持向量機,也是在分類問題中被廣泛應用的一種算法,先來看一下它的定義。在機器學習領域,支持向量機(Support Vector Machine,簡稱SVM)屬於一種監督學習算法,可以用來解決分類和回歸問題,其中,在分類問題中的應用更加廣泛。
  • 一文看懂支持向量機,你懂我is吧?
    它大致經歷了以下四個階段:•1 線性分類器(Linear Classifier)•2 線性支持向量機(LSVM)•3 線性不可分問題改進(引入軟間隔,Soft Margin)•4 非線性支持向量機(核函數方法,kernal method)其中4非線性支持向量機才是現代意義上的支持向量機,因為它引入 了核函數方法,能夠將非線性問題轉化到高維空間(線性化),使得支持向量機能夠處理非線性問題