使用支持向量機(SVM) 算法進行分類


1 支持向量機(SVM)的基本概念

  SVM是一種分類算法,其側重於模式識別方面。使用SVM可以大大提高分類的准確性。

  分類相當於模式識別的子集合,模式識別重點在於對已知數據進行特征發現與提取。

  SVM重點在於解決線性可分的問題。但很多時候,實際的問題是線性不可分的。SVM的思想就是將線性不可分的問題轉化線性可分的問題。那么如何來是實現呢?就是將空間映射到多維空間。如把二維空間映射到三維空間。以增加維數來減少方程的次數。

  比如,在二維空間中,不得不用 f(x)=ax2+b+c 這個曲線將兩類樣本分開,而不是用一條直線將它們分開,這樣就是一個線性不可分的問題。為了解決這個問題,我們可以使用換元法將即 x^2=y1 , x=y2 , 這樣一來替換為 z=a'y1+b'y2+c' 這個線性方程,從而轉換到了高維空間,代價是維度的增加引入了更多的變量。這樣我們就完成了從線性不可分問題到線性可分問題的轉換。

  所謂支持向量,即在每一類樣本集中,過離separating hyper plane 最近的樣本做一個與separating hyper plane 平行的線/超平面。有幾個分類,就有幾個這種直線/超平面,這樣的直線/超平面就叫做支持向量(Support Vector)。

2 核函數

  那么找到一個線/超平面來完成二分類成為問題的關鍵。這個線/超平面的函數被我們成為“核函數”。常見的核函數有:

  • 線性核函數————linear
  • 多項式核函數————poly
  • 徑向基核函數————rbf(用得較多)
  • Sigmoid核函數————sigmoid

  那么如何來選擇合適的核函數呢?答案就是比較不同核函數的分類的准確率。在實際處理分類問題時,分別計算幾種核函數的分類性能,將准確率最高的核函數作為最終用於預測分類的核函數即可。在本文的例子中,我們使用畫圖的方式來判斷分類性能的好壞。

  使用模型不同,轉換的方式不同,在多維空間中的圖形就不同,分類的效果就不同。

  網上關於SVM、線性可不可分、核函數的博文很多,如http://www.cnblogs.com/LeftNotEasy/archive/2011/05/02/basic-of-svm.html 。這里就不再贅述。

3 比較分類效果與子圖的划分

  為了比較不同分類器的准確性,我們采用繪制散點圖,然后人工觀察來判斷。我們將兩個類的點在坐標系中用不同顏色表示出來,同時標出訓練數據,看預測點與訓練點的在圖中的重疊情況。重疊越緊密,說明分類的效果越准確。

  在繪圖的時候,我們希望在一個平面中同時展現多幅圖片,這時使用matplotlib模塊的子圖(subplot)來展現。

subplot的參數

	subplot(橫向划分個數,縱向划分個數,當前定位)

  第一個參數代表的是橫向要划分的子圖個數,第二個參數代表的是縱向要划分的子圖的個數,第三個參數表示當前的定位。

使用示例一:

使用示例二:

使用示例三:

4 源碼

應用場景

  假設在第一象限有10個點,它們分別是[0, 0], [1, 1], ... , [9, 9]。它們[0,0],[1,1],[2,2],[3,3]屬於“0”這個類(類標簽為0),另外6個點屬於“1”這個類(類標簽為1)。
  現在第一象限構造900*900個點,縱橫坐標方向上相鄰的點距離為0.01。

[ 0.00, 0.00],[ 0.01, 0.00], [ 0.02, 0.00],..., [ 8.97, 8.99], [ 8.98, 8.99],[ 8.99, 8.99]

  這樣,布滿區間的點作為預測數據,用各種分類模型進行二分類。最后通過繪圖模塊給不同類的點上色以判斷分類性能。

import numpy as npy
import matplotlib.pyplot as plt
from sklearn import svm
x=[]#存儲樣本數據
y=[]#存儲類標號
for i in range(0,10):#構造10個點作為訓練數據
    if(i<=3):#if(i<=3 or i>=8):
        x.append([i,i])
        y.append(0)
    else:
        x.append([i,i])
        y.append(1)

train_x=npy.array(x)#轉換為數組
train_y=npy.array(y)


'''
創建svm分類器的格式:
svm.SVC(kernel=某個核函數).fit(訓練樣本,類標簽)
'''
#linear
linear_svc=svm.SVC(kernel="linear").fit(train_x,train_y)

#poly 要定義維度,degree決定了多項式的最高次冪.關於SVC參數的意義請參見文章后頭的內容。
poly_svc=svm.SVC(kernel="poly",degree=4).fit(train_x,train_y)

#徑向基核函數(這時SVC默認的核函數)
rbf_svc=svm.SVC().fit(train_x,y)

#Sigmoid
sigmoid_svc=svm.SVC(kernel="sigmoid").fit(train_x,train_y)

#下面就可以進行預測了
x1,x2=npy.meshgrid(npy.arange(train_x[:,0].min(),train_x[:,0].max(),0.01),npy.arange(train_x[:,1].min(),train_x[:,1].max(),0.01))

#先生成各個點。定義最小值和最大值后,定義隔多少值建立一個點。
#npy.arange(train_x[:,1].min(),train_x[:,1].max(),0.01))返回的是900個元素的數組
#meshgrid函數用來產生矩陣。上面的語句也是就是numpy.meshgrid(numpy.arange(0,9,0.01),numpy.arange(0,9,0.01))

'''
x1是矩陣 
      [[ 0.  ,  0.01,  0.02, ...,  8.97,  8.98,  8.99],
       [ 0.  ,  0.01,  0.02, ...,  8.97,  8.98,  8.99],
       [ 0.  ,  0.01,  0.02, ...,  8.97,  8.98,  8.99],
       ..., 
       [ 0.  ,  0.01,  0.02, ...,  8.97,  8.98,  8.99],
       [ 0.  ,  0.01,  0.02, ...,  8.97,  8.98,  8.99],
       [ 0.  ,  0.01,  0.02, ...,  8.97,  8.98,  8.99]]

x2是矩陣
      [[ 0.  ,  0.  ,  0.  , ...,  0.  ,  0.  ,  0.  ],
       [ 0.01,  0.01,  0.01, ...,  0.01,  0.01,  0.01],
       [ 0.02,  0.02,  0.02, ...,  0.02,  0.02,  0.02],
       ..., 
       [ 8.97,  8.97,  8.97, ...,  8.97,  8.97,  8.97],
       [ 8.98,  8.98,  8.98, ...,  8.98,  8.98,  8.98],
       [ 8.99,  8.99,  8.99, ...,  8.99,  8.99,  8.99]]
       
'''
splocation=1
for i in [linear_svc,poly_svc,rbf_svc,sigmoid_svc]:#遍歷各個模型以便繪圖,以看哪個核函數的准確率更高
    rst = i.predict(npy.c_[x1.ravel(),x2.ravel()])#橫坐標和縱坐標的組合。x1.ravel()和x2.ravel()都是長度為810000的數組。c_[]用來將前后兩個數組串聯成一個810000行、2列的矩陣。

    #因為上面用到了四種分類模型,那么一個2×2的圖就能夠顯示完全了。
    plt.subplot(2,2,splocation)#第一個參數代表的是橫向要划分的子圖個數,第二個參數代表的是縱向要划分的子圖的個數,第三個參數表示當前的定位
    plt.contourf(x1,x2,rst.reshape(x1.shape))#contourf用來填充顏色。(當前橫坐標,當前縱坐標,預測的分類結果(轉為x1的規模維數))

    #訓練數據的點也繪制出來
    for j in range(0,len(y)):
        if(int(y[j])==0):
            plt.plot(train_x[j:j+1,0],train_x[j:j+1],"yo")#y代表黃色,o代表散點圖
        else:
            plt.plot(train_x[j:j+1,0],train_x[j:j+1],"ko")#類別為1填充為黑色。k代表黑色
    splocation+=1
plt.show()

運行結果:

  可見,在比較這種分布下,徑向基核函數表現出更好的分類性能。

5 SVC的參數

  具體參數的意義與使用請參見鏈接:http://scikit-learn.org/stable/modules/generated/sklearn.svm.SVC.html

  • C:目標函數的懲罰系數C,用來平衡分類間隔margin和錯分樣本的,default C = 1.0;

C越大,相當於懲罰松弛變量,希望松弛變量接近0,即對誤分類的懲罰增大,趨向於對訓練集全分對的情況,這樣對訓練集測試時准確率很高,但泛化能力弱。C值小,對誤分類的懲罰減小,允許容錯,將他們當成噪聲點,泛化能力較強。

  • kernel :核函數,默認是rbf,可以是‘linear’, ‘poly’, ‘rbf’, ‘sigmoid’, ‘precomputed’

  • degree :多項式poly函數的維度,默認是3,選擇其他核函數時會被忽略。

  • gamma : ‘rbf’,‘poly’ 和‘sigmoid’的核函數參數。默認是’auto’,則gamma=1/n_features

  • coef0 :核函數的常數項。對於‘poly’和 ‘sigmoid’有用。

  • probability :是否采用概率估計。默認為False。要采用的話必須先於調用fit,這個過程會增加用時。

  • shrinking :是否采用shrinking heuristic方法,默認為true

  • tol :停止訓練的誤差值大小,默認為1e-3

  • cache_size :核函數cache緩存大小,默認為200

  • class_weight :類別的權重,字典形式傳遞。設置第幾類的參數C為weight*C(C-SVC中的C)

  • verbose :允許冗余輸出。跟多線程有關系。默認為False。

  • max_iter :最大迭代次數。-1為無限制。

  • decision_function_shape :是否返回模型中每一個類別的樣本的ovr決策函數,或者ovo決策函數。 默認為None

  • random_state :數據洗牌時的種子值,int值

主要調節的參數有:C、kernel、degree、gamma、coef0。

6 推廣

  官方文檔是學習的絕佳利器。傳送門:http://scikit-learn.org/dev/modules/svm.html

6.1 多分類

  SVM算法最初是為二值分類問題設計的,當處理多類問題時,就需要構造合適的多類分類器。目前,構造SVM多類分類器的方法主要有兩類:一類是直接法,直接在目標函數上進行修改,將多個分類面的參數求解合並到一個最優化問題中,通過求解該最優化問題“一次性”實現多類分類。這種方法看似簡單,但其計算復雜度比較高,實現起來比較困難,只適合用於小型問題中;另一類是間接法,主要是通過組合多個二分類器來實現多分類器的構造,常見的方法有one-against-one和one-against-all兩種。

  1. 一對多法(one-versus-rest,簡稱1-v-r SVMs)。訓練時依次把某個類別的樣本歸為一類,其他剩余的樣本歸為另一類,這樣k個類別的樣本就構造出了k個SVM。分類時將未知樣本分類為具有最大分類函數值的那類。
  2. 一對一法(one-versus-one,簡稱1-v-1 SVMs)。其做法是在任意兩類樣本之間設計一個SVM,因此k個類別的樣本就需要設計k(k-1)/2個SVM。當對一個未知樣本進行分類時,最后得票最多的類別即為該未知樣本的類別。Libsvm中的多類分類就是根據這個方法實現的。
  3. 層次支持向量機(H-SVMs)。層次分類法首先將所有類別分成兩個子類,再將子類進一步划分成兩個次級子類,如此循環,直到得到一個單獨的類別為止。 對c和d兩種方法的詳細說明可以參考論文《支持向量機在多類分類問題中的推廣》(計算機工程與應用。2004)
  4. 其他多類分類方法。除了以上幾種方法外,還有有向無環圖SVM(Directed Acyclic Graph SVMs,簡稱DAG-SVMs)和對類別進行二進制編碼的糾錯編碼SVMs。

6.2 回歸

  支持分類的支持向量機可以推廣到解決回歸問題,這種方法稱為支持向量回歸。

  支持向量分類所產生的模型僅僅依賴於訓練數據的一個子集,因為構建模型的成本函數不關心在超出邊界范圍的點,類似的,通過支持向量回歸產生的模型依賴於訓練數據的一個子集,因為構建模型的函數忽略了靠近預測模型的數據集。

  有三種不同的實現方式:支持向量回歸SVR,nusvr和linearsvr。linearsvr提供了比SVR更快實施但只考慮線性核函數,而nusvr實現比SVR和linearsvr略有不同。
作為分類類別,訓練函數將X,y作為向量,在這種情況下y是浮點數


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM