1. 程式人生 > >在python sklearn使用 SVM做分類

在python sklearn使用 SVM做分類

sklearn 之 SVM

SVC(C-Support Vector Classification)實現基於libsvm,臺灣大學林智仁教授團隊開發的一個庫。支援多分類。

1. SVM二分類

>>> import numpy as np
>>> X = np.array([[-1, -1], [-2, -1], [1, 1], [2, 1]])
>>> y = np.array([1, 1, 2, 2])
>>> from sklearn.svm import SVC
>>> clf = SVC()
>>> clf.fit(X, y) 
SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
    decision_function_shape='ovr', degree=3, gamma='auto', kernel='rbf',
    max_iter=-1, probability=False, random_state=None, shrinking=True,
    tol=0.001, verbose=False)
>>> print(clf.predict([[-0.8, -1]]))
[1]

2. SVM多分類

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


a.一對多法(one-versus-rest,簡稱1-v-r SVMs)。訓練時依次把某個類別的樣本歸為一類,其他剩餘的樣本歸為另一類,這樣k個類別的樣本就構造出了k個SVM。分類時將未知樣本分類為具有最大分類函式值的那類。

b.一對一法(one-versus-one,簡稱1-v-1 SVMs)。其做法是在任意兩類樣本之間設計一個SVM,因此k個類別的樣本就需要設計k(k-1)/2個SVM。當對一個未知樣本進行分類時,最後得票最多的類別即為該未知樣本的類別。Libsvm中的多類分類就是根據這個方法實現的。

c.層次支援向量機(H-SVMs)。層次分類法首先將所有類別分成兩個子類,再將子類進一步劃分成兩個次級子類,如此迴圈,直到得到一個單獨的類別為止。

d.其他多類分類方法。除了以上幾種方法外,還有有向無環圖SVM(Directed Acyclic Graph SVMs,簡稱DAG-SVMs)和對類別進行二進位制編碼的糾錯編碼SVMs。

對c和d兩種方法的詳細說明可以參考論文《支援向量機在多類分類問題中的推廣》(計算機工程與應用。2004)

>>> X = [[0], [1], [2], [3]]
>>> Y = [0, 1, 2, 3]
>>> clf = svm.SVC(decision_function_shape='ovo')
>>> clf.fit(X, Y) 
SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
    decision_function_shape='ovo', degree=3, gamma='auto', kernel='rbf',
    max_iter=-1, probability=False, random_state=None, shrinking=True,
    tol=0.001
, verbose=False) >>> dec = clf.decision_function([[1]]) >>> dec.shape[1] # 4 classes: 4*3/2 = 6 6 >>> clf.decision_function_shape = "ovr" >>> dec = clf.decision_function([[1]]) >>> dec.shape[1] # 4 classes 4

3. sklearn SVM中decision_function、predict與predict_proba的關係和區別

decision_function: 返回的是樣本距離超平面的距離。二分類沒什麼好說的,對於多分類ovo,得到每對分類器的輸出,n_class *(n_class - 1)/ 2個值。舉個列子,

>>> clf.decision_function(predict_this)
[[ 96.42193513 -11.13296606 111.47424538 -88.5356536 44.29272494 141.0069203 ]]

對應的分類器是 [AB, AC, AD, BC, BD, CD]
所以我們得到每對分類器的結果[A, C, A, C, B, C]
例如,96.42193513 是正的,所以AB分離器得到的label是A
因為[A, C, A, C, B, C]中有3個C,得票最多,所以C就是整個多分類模型的預測label,這個就是使用predict得到的結果

而ovr,直接選擇絕對值最大那個作為預測label

predict_proba: predict_proba涉及到Platt scaling,SVM中Platt scaling涉及到某些理論問題,如果一定要使用一個得分去表示,可以使用decision_function 去代替predict_proba