1.SVM簡介
SVM方法建立在統計學VC維和結構風險最小化原則上,既可以用於分類(二/多分類)、也可用於回歸和異常值檢測。SVM具有良好的魯棒性,對未知數據擁有很強的泛化能力,特別是在數據量較少的情況下,相較其他傳統機器學習算法具有更優的性能。
使用SVM作為模型時,通常采用如下流程:
- 對樣本數據進行歸一化
- 應用核函數對樣本進行映射(最常采用和核函數是RBF和Linear,在樣本線性可分時,Linear效果要比RBF好)
- 用cross-validation和grid-search對超參數進行優選
- 用最優參數訓練得到模型
- 測試
sklearn中支持向量分類主要有三種方法:SVC、NuSVC、LinearSVC,擴展為三個支持向量回歸方法:SVR、NuSVR、LinearSVR。
SVC和NuSVC方法基本一致,唯一區別就是損失函數的度量方式不同(NuSVC中的nu參數和SVC中的C參數);LinearSVC是實現線性核函數的支持向量分類,沒有kernel參數,也缺少一些方法的屬性,如support_等。
2. 參數
- SVC class
sklearn.svm.
SVC
(C=1.0, kernel='rbf', degree=3, gamma='auto', coef0=0.0, shrinking=True, probability=False, tol=0.001, cache_size=200, class_weight=None, verbose=False, max_iter=-1, decision_function_shape='ovr', random_state=None)
C:
懲罰系數,用來控制損失函數的懲罰系數,類似於LR中的正則化系數。C越大,相當於懲罰松弛變量,希望松弛變量接近0,即對誤分類的懲罰增大,趨向於對訓練集全分對的情況,這樣會出現訓練集測試時准確率很高,但泛化能力弱,容易導致過擬合。 C值小,對誤分類的懲罰減小,容錯能力增強,泛化能力較強,但也可能欠擬合。
kernel:
算法中采用的和函數類型,核函數是用來將非線性問題轉化為線性問題的一種方法。參數選擇有RBF, Linear, Poly, Sigmoid,precomputed或者自定義一個核函數, 默認的是"RBF",即徑向基核,也就是高斯核函數;而Linear指的是線性核函數,Poly指的是多項式核,Sigmoid指的是雙曲正切函數tanh核;。
degree:
當指定kernel為'poly'時,表示選擇的多項式的最高次數,默認為三次多項式;若指定kernel不是'poly',則忽略,即該參數只對'poly'有用。(多項式核函數是將低維的輸入空間映射到高維的特征空間)
gamma:
核函數系數,該參數是rbf,poly和sigmoid的內核系數;默認是'auto',那么將會使用特征位數的倒數,即1 / n_features。(即核函數的帶寬,超圓的半徑)。gamma越大,σ越小,使得高斯分布又高又瘦,造成模型只能作用於支持向量附近,可能導致過擬合;反之,gamma越小,σ越大,高斯分布會過於平滑,在訓練集上分類效果不佳,可能導致欠擬合。
coef0:
核函數常數值(y=kx+b中的b值),只有‘poly’和‘sigmoid’核函數有,默認值是0。
shrinking : 是否進行啟發式。如果能預知哪些變量對應着支持向量,則只要在這些樣本上訓練就夠了,其他樣本可不予考慮,這不影響訓練結果,但降低了問題的規模並有助於迅速求解。進一步,如果能預知哪些變量在邊界上(即a=C),則這些變量可保持不動,只對其他變量進行優化,從而使問題的規模更小,訓練時間大大降低。這就是Shrinking技術。 Shrinking技術基於這樣一個事實:支持向量只占訓練樣本的少部分,並且大多數支持向量的拉格朗日乘子等於C。
probability:
是否使用概率估計,默認是False。必須在 fit( ) 方法前使用,該方法的使用會降低運算速度。
tol:
殘差收斂條件,默認是0.0001,即容忍1000分類里出現一個錯誤,與LR中的一致;誤差項達到指定值時則停止訓練。
cache_size:
緩沖大小,用來限制計算量大小,默認是200M。
class_weight : {dict, ‘balanced’},字典類型或者'balance'字符串。權重設置,正類和反類的樣本數量是不一樣的,這里就會出現類別不平衡問題,該參數就是指每個類所占據的權重,默認為1,即默認正類樣本數量和反類一樣多,也可以用一個字典dict指定每個類的權值,或者選擇默認的參數balanced,指按照每個類中樣本數量的比例自動分配權值。如果不設置,則默認所有類權重值相同,以字典形式傳入。 將類i 的參數C設置為SVC的class_weight[i]*C。如果沒有給出,所有類的weight 為1。'balanced'模式使用y 值自動調整權重,調整方式是與輸入數據中類頻率成反比。如n_samples / (n_classes * np.bincount(y))。(給每個類別分別設置不同的懲罰參數C,如果沒有給,則會給所有類別都給C=1,即前面參數指出的參數C。如果給定參數'balance',則使用y的值自動調整與輸入數據中的類頻率成反比的權重。)
verbose : 是否啟用詳細輸出。在訓練數據完成之后,會把訓練的詳細信息全部輸出打印出來,可以看到訓練了多少步,訓練的目標值是多少;但是在多線程環境下,由於多個線程會導致線程變量通信有困難,因此verbose選項的值就是出錯,所以多線程下不要使用該參數。
max_iter:
最大迭代次數,默認是-1,即沒有限制。這個是硬限制,它的優先級要高於tol參數,不論訓練的標准和精度達到要求沒有,都要停止訓練。
decision_function_shape : 原始的SVM只適用於二分類問題,如果要將其擴展到多類分類,就要采取一定的融合策略,這里提供了三種選擇。‘ovo’ 一對一,為one v one,即將類別兩兩之間進行划分,用二分類的方法模擬多分類的結果,決策所使用的返回的是(樣本數,類別數*(類別數-1)/2); ‘ovr’ 一對多,為one v rest,即一個類別與其他類別進行划分,返回的是(樣本數,類別數),或者None,就是不采用任何融合策略。默認是ovr,因為此種效果要比oro略好一點。
random_state:
在使用SVM訓練數據時,要先將訓練數據打亂順序,用來提高分類精度,這里就用到了偽隨機序列。如果該參數給定的是一個整數,則該整數就是偽隨機序列的種子值;如果給定的就是一個隨機實例,則采用給定的隨機實例來進行打亂處理;如果啥都沒給,則采用默認的 np.random實例來處理。
- NuSVC class
sklearn.svm.
NuSVC
(nu=0.5, kernel='rbf', degree=3, gamma='auto', coef0=0.0, shrinking=True, probability=False, tol=0.001, cache_size=200, class_weight=None, verbose=False, max_iter=-1, decision_function_shape='ovr', random_state=None)
nu: 訓練誤差部分的上限和支持向量部分的下限,取值在(0,1)之間,默認是0.5
- LinearSVC class
sklearn.svm.
LinearSVC
(penalty='l2', loss='squared_hinge', dual=True, tol=0.0001, C=1.0, multi_class='ovr', fit_intercept=True, intercept_scaling=1, class_weight=None, verbose=0, random_state=None, max_iter=1000)
penalty:
正則化參數,L1和L2兩種參數可選,僅LinearSVC有。
loss:
損失函數,有‘hinge’和‘squared_hinge’兩種可選,前者又稱L1損失,后者稱為L2損失,默認是是’squared_hinge’,其中hinge是SVM的標准損失,squared_hinge是hinge的平方
dual:
是否轉化為對偶問題求解,默認是True。
tol:
殘差收斂條件,默認是0.0001,與LR中的一致。
C:
懲罰系數,用來控制損失函數的懲罰系數,類似於LR中的正則化系數。
multi_class:
負責多分類問題中分類策略制定,有‘ovr’和‘crammer_singer’ 兩種參數值可選,默認值是’ovr’,'ovr'的分類原則是將待分類中的某一類當作正類,其他全部歸為負類,通過這樣求取得到每個類別作為正類時的正確率,取正確率最高的那個類別為正類;‘crammer_singer’ 是直接針對目標函數設置多個參數值,最后進行優化,得到不同類別的參數值大小
fit_intercept:
是否計算截距,與LR模型中的意思一致。
class_weight:
與其他模型中參數含義一樣,也是用來處理不平衡樣本數據的,可以直接以字典的形式指定不同類別的權重,也可以使用balanced參數值。
verbose:
是否冗余,默認是False。
random_state:
隨機種子。
max_iter:
最大迭代次數,默認是1000。
3. 屬性(Attributes)
support_:
以數組的形式返回支持向量的索引,即在所有的訓練樣本中,哪些樣本成為了支持向量。
support_vectors_:
返回支持向量,匯總了當前模型所有的支持向量。
n_support_:
比如SVC將數據集分成了4類,該屬性表示了每一類的支持向量的個數。
dual_coef_:
對偶系數,即支持向量在決策函數中的系數,在多分類問題中,這個會有所不同。
coef_:
每個特征系數(重要性),只有核函數是Linear的時候可用。
intercept_:
決策函數中的常數項(借據值),和coef_共同構成決策函數的參數值。
4. 方法(Method)
decision_function(X):
獲取數據集中樣本X到分離超平面的距離。
fit(X, y):
在數據集(X,y)上擬合SVM模型。
get_params([deep]):
獲取模型的參數。
predict(X):
預測數據值X的標簽。
score(X,y):
返回給定測試集和對應標簽的平均准確率。
5. 核函數的使用
- RBF核:高斯核函數就是在屬性空間中找到一些點,這些點可以是也可以不是樣本點,把這些點當做base,以這些base為圓心向外擴展,擴展半徑即為帶寬,即可划分數據。換句話說,在屬性空間中找到一些超圓,用這些超圓來判定正反類。
- 線性核和多項式核:這兩種核的作用也是首先在屬性空間中找到一些點,把這些點當做base,核函數的作用就是找與該點距離和角度滿足某種關系的樣本點。當樣本點與該點的夾角近乎垂直時,兩個樣本的歐式長度必須非常長才能保證滿足線性核函數大於0;而當樣本點與base點的方向相同時,長度就不必很長;而當方向相反時,核函數值就是負的,被判為反類。即,它在空間上划分出一個梭形,按照梭形來進行正反類划分。
- Sigmoid核:同樣地是定義一些base,核函數就是將線性核函數經過一個tanh函數進行處理,把值域限制在了-1到1上。
總之,都是在定義距離,大於該距離,判為正,小於該距離,判為負。至於選擇哪一種核函數,要根據具體的樣本分布情況來確定。
一般有如下指導規則:
- 如果Feature的數量很大,甚至和樣本數量差不多時,往往線性可分,這時選用LR或者線性核Linear;
- 如果Feature的數量很小,樣本數量正常,不算多也不算少,這時選用RBF核;
- 如果Feature的數量很小,而樣本的數量很大,這時手動添加一些Feature,使得線性可分,然后選用LR或者線性核Linear;
- 多項式核一般很少使用,效率不高,結果也不優於RBF;
- Linear核參數少,速度快;RBF核參數多,分類結果非常依賴於參數,需要交叉驗證或網格搜索最佳參數,比較耗時;
- 應用最廣的應該就是RBF核,無論是小樣本還是大樣本,高維還是低維等情況,RBF核函數均適用。
6. 總結
支持向量機的優點:
- 在高維空間中非常高效;
- 即使在數據維度比樣本數量大的情況下仍然有效;
- 在決策函數(稱為支持向量)中使用訓練集的子集,因此它也是高效利用內存的;
- 通用性:不同的核函數與特定的決策函數一一對應;
支持向量機的缺點:
- 如果特征數量比樣本數量大得多,在選擇核函數時要避免過擬合;
- 支持向量機不直接提供概率估計,這些都是使用昂貴的五次交叉驗算計算的。