主要參考資料: http://scikit-learn.org/stable/modules/svm.html#
SVM優點:
高維空間有效性;
資料次元遠大于樣本數量時的有效性;
決策函數實際使用訓練集的子集(也叫支援向量),記憶體使用高效;
多樣性:核函數可選,也可自己定義。
SVM缺點:
特征數大于樣本數,SVM方法不太适用了。
沒有直接提供誤差估計,計算需花很大代價;
scikit-learn中的SVM輸入支援諸如numpy.ndarray (或者可以轉化為numpy.asarray形式) 的密集資料及類似scipy.sparse的稀疏資料。然而,用SVM給稀疏資料做預測,需要有合适的資料。最好是,密集資料用numpy.ndarrsy形式,稀疏資料用scipy.sparse.csr_matrix形式,資料格式均用dtype=float64。
SVC和NuSVC是相似的方法,但是輸入參數和數學公式不一樣。另一方面,LinearSVC是另一種線性核的SVM方法。注意,LinearSVC不用給定參數kernel,從命名可以看出其預設為linear核,對比SVC和NuSVC,缺少support_參數。
SVC, NuSVC和linearSVC接受兩個數組為輸入,X大小為[ n_samples, n_features],是訓練樣本;y的大小是 [n_samples],是類标簽,可以是strings或者integers。
>>> from sklearn import svm
>>> X= [[0,0], [1,1]]
>>> y= [0,1]
>>> clf= svm.SVC()
>>> clf.fit(X, y)
SVC(C=1.0, cache_size=200,class_weight=None, coef0=0.0,
decision_function_shape=None, degree=3, gamma='auto', kernel='rbf',
max_iter=-1, probability=False, random_state=None, shrinking=True,
tol=0.001, verbose=False)
在fiitted之後,模型就能進行預測了。
>>> clf.predict([[2.,2.]])
array([1])
SVMs的決策函數依賴于訓練集的子集,稱之為支援向量。這些支援向量的屬性能在成員support_vectors, support_和n_support中看到:
>>> # get support vectors
>>> clf.support_vectors_
array([[ 0., 0.],
[ 1., 1.]])
>>> # get indices of support vectors
>>> clf.support_
array([0, 1]...)
>>> # get number of support vectors for each class
>>> clf.n_support_
array([1, 1]...)
SVC和NuSVC在處理多分類問題上采用的是“1 vs 1”的政策。若n_class是類别數,那需要訓練的模型數量就是 n_class*(n_class-1)/2 ,每次訓練使用兩個類别的資料。為了提供跟其他分類器類似的接口,decision_funxtion_shape選項能将 “1 vs 1”分類器的結果組合成形如(n_samples, n_classes)的決策器。
>>> 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
另一方面,LinearSVC采用的是“1vs 其他”多分類政策,是以訓練n_class 個模型即可。如果隻有兩類,那隻需要訓練一個模型:
>>> lin_clf= svm.LinearSVC()
>>> lin_clf.fit(X, Y)
LinearSVC(C=1.0, class_weight=None, dual=True, fit_intercept=True,
intercept_scaling=1, loss='squared_hinge', max_iter=1000,
multi_class='ovr', penalty='l2', random_state=None, tol=0.0001,
verbose=0)
>>> dec= lin_clf.decision_function([[1]])
>>> dec.shape[1]
4
注意LinearSVC配置了多分類政策,也就是所謂的Crammer和Singer公式中的所分類SVM方法,實作中使用參數multi_class=’crammer_singer’。這種方法是固定的,但是不太适用于“1 vs其他”的情況。實踐中,“1vs其他”分類适用較多,因為結果簡單,運作周期短。
在“1 vs其他”情況下,LinearSVC的coef_和intercept_屬性的大小分别是[n_class, n_features]和 [n_class],系數矩陣的每一行是“1 vs其他”中的一個分類器,順序與類别的順序相同。
SVC中的“1 vs 1”模式在屬性中有點差異。當核函數選擇Linear時,coef_和intercept_的數值與LinearSVC中相同,但是coef_的大小是 [n_class*(n_class-1)]/2, n_features],對應于二分類器。分類器的順序是“0 vs 1”,“0 vs 2”……“0 vs n”,“1 vs 2”,“1 vs 3”……
“n-1 vs n”。
Deal_coef_的大小是 [n_class-1, n_SV],支援向量的列在任意一個“1 vs 1”分類器中,每個支援向量都在n_class-1個分類器中使用到了。
【scores 和 probabilities】
SVC方法decision_function會給每個樣本一個屬于某個類别的機率。如果構造器probability=True,則會啟用類成員機率估計(用predict_proba或者predict_log_proba)。二分類情況下,機率通過Platt-scalling校準,比如用svm分數進行線性回歸,用額外的訓練集的十字交叉驗證法實作。
不用說,Platt-scalling校準中的十字交叉驗證在大資料集下是個費時費力的操作。另外,用scores做的機率估計是不穩定的,參數argmax并不是機率的argmax。Platt方法也存在理論問題,如果要求可信的scores,但不必要是機率,那可以設probability=False,而且用decision_function來代替predict_proba。
【unbalabced problems】
如果要更加關注類别和參數,可以使用參數class_weight和sample_weight。
SVC(注意不是NuSVC)的fit方法中有個很重要的關鍵字class_weight,是字典類型{class_label : value},其中value是>0的浮點類型,那麼此時class_label的C參數就成了C*value。
SVC、NuSVC、SVR、NuSVR和OneClassSVM同樣也有通過參數sample_weight給單個樣本添權重重,此時類别class_label的C參數就成了C*value。
【回歸】
SVM方法同樣可以做回歸,此時叫做SVR。
如上所述,SVM模型的建立隻與訓練資料中的一部分子集有關,因為建立模型的代價函數不關心遠離超平面的訓練點。類似的,SVR模型也隻與訓練集的一部分有關,因為代價函數忽略訓練集中靠近模型預測的點。
SVR有三種不同的實作方式,SVR、NuSVR和LinearSVR,其中LinearSVR的實作比SVR更快,但是隻支援線性核,NuSVR的實作使用明顯不同于SVR和LinearSVR的公式,可在官網檢視細節。
>>> from sklearn import svm
>>> X = [[0, 0], [2, 2]]
>>> y = [0.5, 2.5]
>>> clf = svm.SVR()
>>> clf.fit(X, y)
SVR(C=1.0, cache_size=200, coef0=0.0, degree=3, epsilon=0.1, gamma='auto',
kernel='rbf', max_iter=-1, shrinking=True, tol=0.001, verbose=False)
>>> clf.predict([[1, 1]])
array([ 1.5])
【scores 和 probabilities】
SVC方法decision_function會給每個樣本一個屬于某個類别的機率。如果構造器probability=True,則會啟用類成員機率估計(用predict_proba或者predict_log_proba)。二分類情況下,機率通過Platt-scalling校準,比如用svm分數進行線性回歸,用額外的訓練集的十字交叉驗證法實作。
不用說,Platt-scalling校準中的十字交叉驗證在大資料集下是個費時費力的操作。另外,用scores做的機率估計是不穩定的,參數argmax并不是機率的argmax。Platt方法也存在理論問題,如果要求可信的scores,但不必要是機率,那可以設probability=False,而且用decision_function來代替predict_proba。
【unbalabced problems】
如果要更加關注類别和參數,可以使用參數class_weight和sample_weight。
SVC(注意不是NuSVC)的fit方法中有個很重要的關鍵字class_weight,是字典類型{class_label : value},其中value是>0的浮點類型,那麼此時class_label的C參數就成了C*value。
SVC、NuSVC、SVR、NuSVR和OneClassSVM同樣也有通過參數sample_weight給單個樣本添權重重,此時類别class_label的C參數就成了C*value。
【回歸】
SVM方法同樣可以做回歸,此時叫做SVR。
如上所述,SVM模型的建立隻與訓練資料中的一部分子集有關,因為建立模型的代價函數不關心遠離超平面的訓練點。類似的,SVR模型也隻與訓練集的一部分有關,因為代價函數忽略訓練集中靠近模型預測的點。
SVR有三種不同的實作方式,SVR、NuSVR和LinearSVR,其中LinearSVR的實作比SVR更快,但是隻支援線性核,NuSVR的實作使用明顯不同于SVR和LinearSVR的公式,可在官網檢視細節。