支持向量機(SVM)全稱Support Vecor Machine,談及機器學習無論迴歸還是分類,一定都會拿它進行測試,它是機器學習算法中最受關注的算法之一。
這裏本文不過多的去研究它的數學推導公式,而是淺嘗輒止的去探究一下它的原理和作用,以及在sklearn當如如何高效的使用。
想要去推導它數據公式的朋友可以去查看劉建平的博客
1、SVM是如何工作的
SVM學習的基本想法是求解能夠正確劃分訓練數據集(下圖中實心黑點與空心點)並且幾何間隔最大的分離超平面。如下圖所示, 即爲分離超平面作爲決策邊界,對於線性可分的數據集來說,這樣的超平面有無窮多個(即感知機),但是幾何間隔最大的分離超平面卻是唯一的。
注:在幾何中,超平面是一個空間的子空間,它是維度比所在空間小一維的空間。 如果數據空間本身是三維的,則其超平面是二維平面,而如果數據空間本身是二維的,則其超平面是一維的直線。在二分類問題中,如果一個超平面能夠將數據劃分爲兩個集合,其中每個集合中包含單獨的一個類別,我們就說這個超平面是數據的“決策邊界“。
SVM目標是"找出邊際最大的決策邊界",聽起來是一個十分熟悉的表達,這是一個最優化問題,而最優化問題往往和損失函數聯繫在一起。和邏輯迴歸中的過程一樣,SVM也是通過最小化損失函數來求解一個用於後續模型使用的重要信息:決策邊界。
這裏梳理一下這整個過程(當然你要死有興趣的話,可以去看論文再自己推導一下):
- 定義決策邊界的數學表達,並基於此表達定義分類函數
- 爲尋找最大邊際引出損失函數:
- 爲求解能夠使邊際最大化的和,引入拉格朗日因子α
- 引入拉格朗日對偶函數,使求解和得過程轉化爲對α的求解
- 使用SMO或梯度下降等方法求解α,再根據α解出和,最終找出最優決策邊界。
2、sklearn中的SVM
類 | 含義 |
---|---|
sklearn.svm.LinearSVC |
線性支持向量分類 |
sklearn.svm.LinearSVR |
線性支持向量迴歸 |
sklearn.svm.NuSVC |
Nu支持向量分類 |
sklearn.svm.NuSVR |
Nu支持向量迴歸 |
sklearn.svm.OneClassSVM |
無監督異常值檢測(後面會有專門模塊講) |
sklearn.svm.SVC |
支持向量分類 |
sklearn.svm.SVR |
支持向量迴歸 |
sklearn.svm.l1_min_c |
返回參數C的最低邊界,這樣對於C在(L1_min_C,無窮大)中,模型保證不爲空 |
對於SVC, NuSVC,和LinearSVC 3個分類的類,SVC和 NuSVC差不多,區別僅僅在於對損失的度量方式不同,而LinearSVC從名字就可以看出,他是線性分類,也就是不支持各種低維到高維的核函數,僅僅支持線性核函數,對線性不可分的數據不能使用。
同樣的,對於SVR, NuSVR,和LinearSVR 3個迴歸的類, SVR和NuSVR差不多,區別也僅僅在於對損失的度量方式不同。LinearSVR是線性迴歸,只能使用線性核函數。
我們使用這些類的時候,如果有經驗知道數據是線性可以擬合的,那麼使用LinearSVC去分類 或者LinearSVR去迴歸,它們不需要我們去慢慢的調參去選擇各種核函數以及對應參數, 速度也快。如果我們對數據分佈沒有什麼經驗,一般使用SVC去分類或者SVR去迴歸,這就需要我們選擇核函數以及對核函數調參了。
什麼特殊場景需要使用NuSVC分類 和 NuSVR 迴歸呢?如果我們對訓練集訓練的錯誤率或者說支持向量的百分比有要求的時候,可以選擇NuSVC分類 和 NuSVR 。它們有一個參數來控制這個百分比。
3、svm.SVC
3.1 SVC參數
sklearn.svm.SVC(C=1.0,
kernel='rbf',
degree=3,
gamma='scale',
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',
break_ties=False,
random_state=None
)
-
C
:懲罰係數C,默認爲1,一般需要通過交叉驗證來選擇一個合適的C。如果C值設定比較大,那SVC可能會選擇邊際較小的,能夠更好地分類所有訓練點的決策邊界,不過模型的訓練時間也會更長。如果C的設定值較小,那SVC會盡量最大化邊界,決策功能會更簡單,但代價是訓練的準確度。換句話說,C在SVM中的影響就像正則化參數對邏輯迴歸的影響。 -
kernel
:核函數有四種內置選擇,‘linear’即線性核函數, ‘poly’即多項式核函數, ‘rbf’即高斯核函數, ‘sigmoid’即sigmoid核函數。如果選擇了這些核函數, 對應的核函數參數在後面有單獨的參數需要調。默認是高斯核’rbf’。 -
degree
:如果我們在kernel參數使用了多項式核函數 ‘poly’,那麼我們就需要對這個參數進行調參,默認是3。 -
gamma
:如果我們在kernel參數使用了多項式核函數 ‘poly’,高斯核函數‘rbf’, 或者sigmoid核函數,那麼我們就需要對這個參數進行調參。默認爲’auto’,即 -
coef0
:如果我們在kernel參數使用了多項式核函數 ‘poly’,或者sigmoid核函數,那麼我們就需要對這個參數進行調參,默認爲0。 -
shrinking
:默認爲True,是否使用收縮啓發式計算(shrinking heuristics), 如果使用,有時可以加速最優化的計算進程(沒用過,不敢用)。 -
probability
:默認False,是否啓用概率估計。必須在調用fit之前啓用它, 啓用此功能會減慢SVM的運算速度。 -
tol
:浮點數,默認1e-3,停止迭代的容差。 -
cache_size
:在大樣本的時候,緩存大小會影響訓練速度,因此如果機器內存大,推薦用500MB甚至1000MB。默認是200,即200MB。 -
class_weight
:指定樣本各類別的的權重,主要是爲了防止訓練集某些類別的樣本過多,導致訓練的決策過於偏向這些類別。這裏可以自己指定各個樣本的權重,或者用“balanced”,如果使用“balanced”,則算法會自己計算權重,樣本量少的類別所對應的樣本權重會高。當然,如果你的樣本類別分佈沒有明顯的偏倚,則可以不管這個參數,選擇默認的"None"。 -
verbose
:默認False,啓用詳細輸出。 -
max_iter
:整數,默認=-1,最大迭代次數,輸入"-1"表示沒有限制。 -
decision_function_shape
:默認是’ovr’,OvR相對簡單,但分類效果相對略差(這裏指大多數樣本分佈情況,某些樣本分佈下OvR可能更好)。而OvO分類相對精確,但是分類速度沒有OvR快。 -
break_ties
:默認False,如果爲TRUE,Decision_Function_Shape=‘ovr’,且類別數>2,則預測結果將根據Decision_Function的置信度值打破關係,否則返回類別中的第一個類。請注意,與簡單的預測相比,打破聯繫的計算成本相對較高。 -
random_state
:隨機數種子。
3.2 SVC屬性和接口列表
屬性 | 含義 |
---|---|
support_ |
支持向量的索引 |
support_vectors_ |
支持向量本身 |
n_support_ |
每個類的支持向最數 |
dual_coef_ |
決策函數中支持向量的係數。對於多分類問題而言,是所有ovo模式分類器中的係數,多類情況下係數的佈局不是非常重要 |
coef_ |
賦予特徵的權重(原始問題中的係數),這個屬性僅適用線性內核,coef_ 是從dual_coef_ 和 support_vectors_ 派生的只讀屬性 |
intercept_ |
決策函數中的常量, 在二維平面上是截距 |
fit_status_ |
如果正確擬合, 則顯示 0, 否則爲1 (將發出警告) |
classes_ |
類標籤 |
class_weight_ |
每類參數C的乘子。根據類權重參數計算 |
接口 |
---|
decision_function(self, X) |
fit(self, X, y[, sample_weight]) |
get_params(self[, deep]) |
predict(self, X) |
score(self, X, y[, sample_weight]) |
set_params(self, \*\*params) |
4、SVM 真實案例-天氣預報
這個數據是從Kaggle上下載的,未經過預處理的澳大利亞天氣數據集。我們的目標是在這個數據集上來預測明天是否會下雨。預測天氣是一個非常非常困難的主題,因爲影響天氣的因素太多,而Kaggle的這份數據也絲毫不讓我們失望,是一份非常難的數據集,難到我們目前學過的所有算法在這個數據集上都不會有太好的結果,尤其是召回率recall,異常地低。
希望使用原數據集的朋友可以到Kaggle下載最原始版本,或者直接從我的GitHub上獲取數據。
希望使用原數據集的朋友可以到Kaggle下載最原始版本,或者直接從我的GitHub中獲取數據:
Kaggle下載鏈接在這裏
這裏就不直接展示代碼了,以後都會將代碼放進我的GitHub裏面: