機器學習算法筆記-SVM支持向量機簡介及JAVA小實現

2021-02-12 測碼奔跑
前言

最近開始學習一些機器學習裡的主要算法,SVM支持向量機是我目前產品裡用到的核心算法,想在這裡把我學到的一些東西記錄下來。因為本人也是新手,所以我儘量用小白的語言來說,當然有說的不太對的地方請指正。

機器學習人工智慧總是給我們很高大上,很精深的感覺,事實上它確實很專業化,尤其是模型裡用到的各種數學公式很難記憶(同學當你去看專業的算法文章的時候,你暈嗎),我個人覺得其實機器學習是一種將現實世界的模型抽象成數學模型的一種方法,就是把我們想要解決的一個現實問題抽象成數學公式,該公式裡有未知的參數,然後我們要用大量的訓練數據計算出這些參數的值。拿到參數值後,當我們需要對某一個對象進行預測的時候,我們做的事情就是把對象的屬性代入到公式裡得到一個值,就是我們的預測值。

下面是SVM的一個介紹

支持向量機(support vector machine)是一種分類算法,通過尋求結構化風險最小來提高學習機泛化能力,實現經驗風險和置信範圍的最小化,從而達到在統計樣本量較少的情況下,亦能獲得良好統計規律的目的。通俗來講,它是一種二類分類模型,其基本模型定義為特徵空間上的間隔最大的線性分類器。

大概介紹下什麼是結構化風險:

機器學習本質上就是一種對問題真實模型的逼近,但毫無疑問,真實模型一定是不知道的(如果知道了直接用真實模型解決問題不就可以了,就不需要機器學習了)既然真實模型不知道,那麼我們選擇的假設與問題真實解之間究竟有多大差距,我們就沒法得知。 這個與問題真實解之間的誤差,就叫做風險(更嚴格的說,誤差的累積叫做風險)。我們選擇了一個假設之後(更直觀點說,我們得到了一個分類器以後),真實誤差無從得知,但我們可以用某些可以掌握的量來逼近它。最直觀的想法就是使用分類器在樣本數據上的分類的結果與真實結果(因為樣本是已經標註過的數據,是準確的數據)之間的差值來表示。這個差值叫做經驗風險。

統計學習認為真實風險應該由兩部分內容刻畫,一是經驗風險,代表了分類器在給定樣本上的誤差;二是置信風險,代表了我們在多大程度上可以信任分類器在未知文本上分類的結果。很顯然,第二部分是沒有辦法精確計算的,因此只能給出一個估計的區間,也使得整個誤差只能計算上界,而無法計算準確的值。

統計學習的目標從經驗風險最小化變為了尋求經驗風險與置信風險的和最小,即結構風險最小。 SVM正是這樣一種努力最小化結構風險的算法。

下面來看個最最簡單的分類問題

用一根直線把紅點跟藍點區分開來。 

 紅點跟藍點是要區分的兩個類別,在二維平面中它們的樣本如上圖所示。中間的直線就是一個分類函數,它可以將兩類樣本完全分開。一般的,如果一個線性函數能夠將樣本完全正確的分開,就稱這些數據是線性可分的,否則稱為非線性可分的。

本文僅談論線性可分的情況,包括下面我給的一個例子也是線性可分模型的,線性不可分及升維的方法我們下一次再聊,其實SVM強在於對線性不可分問題的解決,但線性可分其實可以看成是線性不可分的一種特例。

實際上,一個線性函數是一個實值函數(即函數的值是連續的實數),而我們的分類問題(例如這裡的二元分類問題——回答一個樣本屬於還是不屬於一個類別的問題)需要離散的輸出值,例如用1表示某個樣本屬於類別A,而用0表示不屬於(不屬於A也就意味著屬於B),這時候只需要簡單的在實值函數的基礎上附加一個閾值即可,通過分類函數執行時得到的值大於還是小於這個閾值來確定類別歸屬。 例如我們有一個線性函數 g(x)=wx+b 
我們可以取閾值為0,這樣當有一個樣本xi需要判別的時候,我們就看g(xi)的值。若g(xi)>0,就判別為類別A,若g(xi)<0,則判別為類別B(等於的時候我們就拒絕判斷)。此時也等價於給函數g(x)附加一個符號函數sgn(),即f(x)=sgn [g(x)]是我們真正的判別函數。

注意g(x)不是中間那條直線的表達式,中間那條直線的表達式是g(x)=0,即wx+b=0,我們也把這個函數叫做分類面。

算法的目的無非是找出一個函數f(x),這個函數能讓我們把輸入的數據x進行分類。既然是分類肯定需要一個評判的標準,比如分出來有兩種情況A和B,那麼怎麼樣才能說x是屬於A類的,或不是B類的呢?就是需要有個邊界,就好像兩個國家一樣有邊界,如果邊界越明顯,則就越容易區分,因此,我們的目標是最大化邊界的寬度,使得非常容易的區分是A類還是B類。怎麼樣得到這個最大間隔函數,是一個複雜的理論推導,其實我們的算法模型本質上就是用大量的x去計算出這個判定函數,得到一個最優解。

放出經過數學推導後的最優函數,具體推導過程可以去參閱SVM理論文章,這裡就不放了,我也沒看懂。

輸入是x,是一個數組,組中每一個值表示一個特徵。 輸出是A類還是B類。(正類還是負類)

如何用JAVA實現SVM的小例子

這個代碼是從網上找的,我只是想通過這個代碼講一下我們要用一個算法模型的大概步驟是怎樣。 該代碼需要使用libsvm,libsvm是臺灣林智仁教授開發的SVM的庫,使用起來非常方便。 你可以下載libsvm壓縮包解壓到本地然後調用(from:http://www.csie.ntu.edu.tw/~cjlin/libsvm/index.html)

先總結下使用SVM模型的幾個步驟: + 定義訓練集數據及標註 + 定義模型參數 + 調用接口訓練模型 + 定義測試集數據 + 對測試數據進行分類預測

具體實現代碼如下,後面都有加注釋。

package com.taobao.svm;import libsvm.svm;  import libsvm.svm_model;  import libsvm.svm_node;  import libsvm.svm_parameter;  import libsvm.svm_problem;public class SvmTest {    /**     * @param args     */    public static void main(String[] args) {        //定義訓練集點a{10.0, 10.0} 和 點b{-10.0, -10.0},對應lable為{1.0, -1.0}        svm_node pa0 = new svm_node();        pa0.index = 0;        pa0.value = 10.0;        svm_node pa1 = new svm_node();        pa1.index = -1;        pa1.value = 10.0;        svm_node pb0 = new svm_node();        pb0.index = 0;        pb0.value = -10.0;        svm_node pb1 = new svm_node();        pb1.index = 0;        pb1.value = -10.0;        svm_node[] pa = {pa0, pa1}; //點a        svm_node[] pb = {pb0, pb1}; //點b        svm_node[][] datas = {pa, pb}; //訓練集的向量表        double[] lables = {1.0, -1.0}; //a,b 對應的lable        //定義svm_problem對象        svm_problem problem = new svm_problem();        problem.l = 2; //向量個數        problem.x = datas; //訓練集向量表        problem.y = lables; //對應的lable數組        //定義svm_parameter對象        svm_parameter param = new svm_parameter();        param.svm_type = svm_parameter.C_SVC;        param.kernel_type = svm_parameter.LINEAR; //這裡表示我用的是線性模型        param.cache_size = 100;        param.eps = 0.00001;        param.C = 1;        //訓練SVM分類模型        System.out.println(svm.svm_check_parameter(problem, param)); //如果參數沒有問題,則svm.svm_check_parameter()函數返回null,否則返回error描述。        svm_model model = svm.svm_train(problem, param); //svm.svm_train()訓練出SVM分類模型        //定義測試數據點c        svm_node pc0 = new svm_node();        pc0.index = 0;        pc0.value = -0.1;        svm_node pc1 = new svm_node();        pc1.index = -1;        pc1.value = 0.0;        svm_node[] pc = {pc0, pc1};        //預測測試數據的lable        System.out.println(svm.svm_predict(model, pc));    }}

運行結果:

null  *optimization finished, #iter = 1  nu = 0.0033333333333333335  obj = -0.0033333333333333335, rho = 0.0  nSV = 2, nBSV = 0  Total nSV = 2  -1.0

第一行null是svm.svmcheckparameter(problem, param)的輸出,表示參數設置無誤;最後一行的-1.0表示對c點的分類預測lable是-1.0。

該代碼主要用了svm.svmtrain()做訓練,用svm.svmpredict()做預測, obj是SVM問題的最優目標值, nSV和nBSV是支持向量和有界支持向量的數目。

上面的代碼是一個最簡單的線性可分模型的建立,我們可以傳入更多的訓練數據讓預測結果更加準確。當然這個只是一個簡單的小例子,我們業務上使用的數據和模型是比這個複雜得多的,而且是非線性的,工作量比較大且複雜的是如何選擇特徵及對訓練集進行標註,後面有機會再講。


更多測試技術文章,微信掃以下二維碼,歡迎關注

測碼奔跑-讓測試技術奔跑起來

相關焦點

  • 支持向量機(SVM)算法總結
    版權所有©德塔精要,轉載請註明出處 支持向量機算法作為機器學習領域的經典算法,從被提出開始提出後快速發展,在很多場景和領域都取得了非常好的效果
  • 機器學習算法入門之「支持向量機」
    在機器學習領域,支持向量機(Support Vector Machine,簡稱SVM)屬於一種監督學習算法,可以用來解決分類和回歸問題,其中,在分類問題中的應用更加廣泛。因此,簡單理解的話,支持向量機算法是通過某種方式,找到一個最優的分類器,從而實現分類的過程。明白了這一點,下面就具體介紹一下該算法的原理。先來看一個慄子。以二分類問題為例,假設有一個1維的數據集,表示重量,現在希望用某個標準,把數據集中的樣本分成兩類,超重和正常。
  • 支持向量機(SVM)原理剖析
    1 SVM簡介支持向量機(support vector machines, SVM)是一種二分類模型,它的基本模型是定義在特徵空間上的「間隔最大的線性分類器」,間隔最大使它有別於感知機;SVM還包括「核技巧」,這使它成為實質上的非線性分類器。
  • 【典型算法】SVM算法
    小編說:機器學習算法眾多,全部掌握,一則不可能,二則沒必要。如何靈活掌握和應用機器學習算法呢?
  • 【機器學習基礎】數學推導+純Python實現機器學習算法8-9:線性可分支持向量機和線性支持向量機
    線性可分支持向量機的簡單實現     這裡我們基採取和之前感知機模型一樣的優化思想來求解線性可分支持向量機的原始問題。完整代碼文件和數據可參考筆者GitHub地址:https://github.com/luwill/machine-learning-code-writing 線性支持向量機在上一講中,我們探討了線性可分情況下的支持向量機模型。本節我們來繼續探討svm的第二種情況,線性支持向量機。何謂線性支持呢?
  • 機器學習的分類算法之SVM(支持向量機)
    引言SVM(Support Vector Machine,支持向量機)是機器學習中的有監督線性分類算法
  • 動手寫機器學習算法:SVM支持向量機(附代碼)
    ,其中:要很小,所以近似為:線性可分的,指定核函數為linear:'''data1——線性分類'''data1 = spio.loadmat('data1.mat')X = data1['X']y = data1['y']y = np.ravel(y)plot_data(X,y)model = svm.SVC
  • 關於支持向量機(SVM)的原理,你了解多少?(萬字長文 速收)
    其實Coursera的課堂上Andrew Ng講過支持向量機,但顯然他沒有把這作為重點,加上Ng講支持向量機的方法我一時半會難以完全消化,所以聽的也是一知半解。真正開始了解支持向量機就是看的這篇「三重境界」,之後才對這個算法有了大概的概念,以至如何去使用,再到其中的原理為何,再到支持向量機的證明等。總之,這篇文章開啟了我長達數月的研究支持向量機階段,直到今日。」
  • 【機器學習基礎】數學推導+純Python實現機器學習算法10:線性不可分支持向量機
    ——非線性支持向量機。下面來看基於cvxopt的非線性支持向量機快速實現方法。     以上就是本節內容,關於支持向量機的部分內容,筆者就簡單寫到這裡,下一講我們來看看樸素貝葉斯算法。實現機器學習算法6:感知機數學推導+純Python實現機器學習算法5:決策樹之CART算法數學推導+純Python實現機器學習算法4:決策樹之ID3算法數學推導+純Python實現機器學習算法3:k近鄰數學推導
  • 支持向量機SVM原理(參數解讀和python腳本)
    支持向量缺點:1.如果數據特徵(維度)大於樣本量,支持向量機表現很差2.支持向量機不提供概率區間估計C參數設置小,算法複雜度小,C參數高,追求錯誤率最低其它機器學習分類算法支持向量機,在sklearn裡面,有兩種,SVC支持向量分類,用於分類問題,SVR,支持向量回歸,用於回歸問題。
  • 機器學習實戰 | 支持向量機·sklearn 參數詳解
    支持向量在線性可分的情況下,訓練數據集的樣本點與分離超平面距離最近的樣本點稱為支持向量,而支持向量機的目的就是求取距離這個點最遠的分離超平面,這個點在確定分離超平面時起著決定性作用,所以把這種分類模型稱為支持向量機。sklearn 提供了很多模型供我們使用,包括以下幾種:
  • 如何學習SVM(支持向量機)以及改進實現SVM算法程序?
    MLNLP」,選擇「星標」公眾號重磅乾貨,第一時間送達編輯:憶臻https://www.zhihu.com/question/31211585/answer/640501555本文僅作為學術分享,如果侵權,會刪文處理如何學習SVM(支持向量機
  • 機器學習測試筆記(13)——支持向量機
    2 支持向量機原理支持向量機(Support Vector Machine,以下簡稱SVM),作為傳統機器學習的一個非常重要的分類算法,它是一種通用的前饋網絡類型,最早是由Vladimir深度學習(2012)出現之前,如果不考慮集成學習的算法,不考慮特定的訓練數據集,在分類算法中的表現SVM說是排第一估計是沒有什麼異議的。SVM本來是一種線性分類和非線性分類都支持的二元分類算法,但經過演變,現在也支持多分類問題,也能應用到了回歸問題。一些線性不可分的問題可能是非線性可分的,即特徵空間存在超曲面(hypersurface)將正類和負類分開。
  • 經典算法解讀:一文看懂支持向量機以及推導
    本文是吳恩達老師的和的筆記和代碼復現部分(支持向量機)。作者:備註:筆記和作業(含數據、原始作業文件)、視頻都在 github 中下載。我將陸續將課程筆記和課程代碼發布在公眾號「機器學習初學者」,敬請關注。
  • 一個簡單的案例帶你了解支持向量機算法(Python代碼)
    相反,「支持向量機」就像一把鋒利的刀—它適用於較小的數據集,但它可以再這些小的數據集上面構建更加強大的模型。現在,我希望你現在已經掌握了隨機森林,樸素貝葉斯算法和模型融合的算法基礎。如果沒有,我希望你先抽出一部分時間來了解一下他們,因為在本文中,我將指導你了解認識機器學習算法中關鍵的高級算法,也就是支持向量機的基礎知識。
  • Python機器學習筆記:SVM-sklearn實現 (4)FlyAI
    上面將SVM再贅述了一下,下面學習sklearn中的SVM方法,sklearn中SVM的算法庫分為兩類,一類是分類的算法庫,主要包含LinearSVC,NuSVC和SVC三個類,另一類是回歸算法庫,包含SVR,NuSVR和LinearSVR三個類,相關模塊都包裹在sklearn.svm模塊中。
  • 支持向量機(SVM)說明及示例
    支持向量機(SVM)可以解決支持分類和回歸問題,這兩個問題的解決都是通過構造函數h來實現的,該函數將輸入向量x與輸出y進行匹配:y = h(x )優缺點優點:該算法可以基於內核對線性和非線性問題的極限進行建模。它對於「過擬合」也非常可行,尤其是在大空間中。
  • 【翻譯】Sklearn 與 TensorFlow 機器學習實用指南 —— 第5章( 中)支持向量機
    Sklearn 與 TensorFlow 機器學習實用指南 —— 第5章( 上)支持向量機多項式核添加多項式特徵很容易實現,不僅僅在 SVM,在各種機器學習算法都有不錯的表現,但是低次數的多項式不能處理非常複雜的數據集,而高次數的多項式卻產生了大量的特徵,會使模型變得慢。
  • 機器學習數據分析極簡思路及sklearn算法實踐小試
    c)嵌入法則稍微複雜一點,它先使用某些機器學習的算法和模型進行訓練,得到各個特徵的權值係數,根據權值係數從大到小來選擇特徵。類似於過濾法,但是它是通過機器學習訓練來確定特徵的優劣,而不是直接從特徵的一些統計學指標來確定特徵的優劣。
  • 機器學習的金融應用第五講:懲罰回歸算法與支持向量機
    監督機器學習模型使用帶標籤的數據進行訓練,根據目標變量(Y)的性質,可以分為兩種類型:連續目標變量的回歸和有序目標變量的分類。我們接下來將討論懲罰回歸和LASSO。然後,我們將引入支持向量機(SVM)、k近鄰(KNN)和分類回歸樹(CART)算法。