摘要:支持向量機(Support Vector Machine:SVM)的目的是用訓練數據集的間隔最大化找到一個最優分離超平面。支持向量機(support vector machines, SVM)是一種二分類模型,它的基本模型是定義在特徵空間上的間隔最大的線性分類器,間隔最大使它有別於感知機。

Datawhale乾貨 

作者:小一,Datawhale優秀學習者

寄語:本文介紹了SVM的理論,細緻說明了“間隔”和“超平面 兩個概念;隨後, 闡述 如何最大化間隔並區分了軟硬間隔SVM;同時,介紹了SVC問題的應用。最後,用SVM 乳腺癌診斷 經典數據集,對SVM進行了深入的理解。

支持向量機(support vector machines, SVM)是一種二分類模型,它的基本模型是定義在特徵空間上的間隔最大的線性分類器,間隔最大使它有別於感知機。

SVM的的學習策略就是間隔最大化,可形式化爲一個求解凸二次規劃的問題,也等價於正則化的合頁損失函數的最小化問題。SVM的的學習算法就是求解凸二次規劃的最優化算法。

下圖爲SVM的分類效果顯示,可以發現,不管是線性還是非線性,SVM均表現良好。

學習框架

後臺回覆 SVM 可下載SVM學習框架高清導圖

SVM理論

支持向量機(Support Vector Machine:SVM)的目的是用訓練數據集的間隔最大化找到一個最優分離超平面。

下邊用一個例子來理解下間隔和分離超平面兩個概念。現在有一些人的身高和體重數據,將它們繪製成散點圖,是這樣的:

如果現在給你一個未知男女的身高和體重,你能分辨出性別嗎?直接將已知的點劃分爲兩部分,這個點落在哪一部分就對應相應的性別。那就可以畫一條直線,直線以上是男生,直線以下是女生。

問題來了,現在這個是一個二維平面,可以畫直線,如果是三維的呢?該怎麼畫?我們知道一維平面是點,二維平面是線,三維平面是面。

對的,那麼注意,今天的第一個概念:超平面是平面的一般化:

  • 在一維的平面中,它是點

  • 在二維的平面中,它是線

  • 在三維的平面中,它是面

  • 在更高的維度中,我們稱之爲超平面

注意:後面的直線、平面都直接叫超平面了。

繼續剛纔的問題,我們剛纔是通過一個分離超平面分出了男和女,這個超平面唯一嗎?很明顯,並不唯一,這樣的超平面有若干個。

那麼問題來了,既然有若干個,那肯定要最好的,這裏最好的叫最優分離超平面。如何在衆多分離超平面中選擇一個最優分離超平面?下面這兩個分離超平面,你選哪個?綠色的還是黑色的?

對,當然是黑色的,可是原理是什麼?很簡單,原理有兩個,分別是:

  • 正確的對訓練數據進行分類

  • 對未知數據也能很好的分類

黑色的分離超平面能夠對訓練數據很好的分類,當新增未知數據時,黑色的分離超平面泛化能力也強於綠色。深究一下,爲什麼黑色的要強於綠色?原理又是什麼?

其實很簡單:最優分離超平面其實是和兩側樣本點有關,而且只和這些點有關。怎麼理解這句話呢,我們看張圖:

其中當間隔達到最大,兩側樣本點的距離相等的超平面爲最優分離超平面。注意,今天的第二個概念:對應上圖,Margin對應的就是最優分離超平面的間隔,此時的間隔達到最大。

一般來說,間隔中間是無點區域,裏面不會有任何點(理想狀態下)。給定一個超平面,我們可以就算出這個超平面與和它最接近的數據點之間的距離。那麼間隔(Margin)就是二倍的這個距離。

如果還是不理解爲什麼這個分離超平面就是最優分離超平面,那你在看這張圖。

在這張圖裏面間隔MarginB小於上張圖的MarginA。當出現新的未知點,MarginB分離超平面的泛化能力不如MarginA,用MarginB的分離超平面去分類,錯誤率大於MarginA

總結一下

支持向量機是爲了通過間隔最大化找到一個最優分離超平面。在決定分離超平面的時候,只有極限位置的那兩個點有用,其他點根本沒有大作用,因爲只要極限位置離得超平面的距離最大,就是最優的分離超平面了。 

如何確定最大化間隔

如果我們能夠確定兩個平行超平面,那麼兩個超平面之間的最大距離就是最大化間隔。 看個 圖你就都明白了:

左右兩個平行超平面將數據完美的分開,我們只需要計算上述兩個平行超平面的距離即可。所以,我們找到最大化間隔:

  • 找到兩個平行超平面,可以劃分數據集並且兩平面之間沒有數據點

  • 最大化上述兩個超平面

1. 確定兩個平行超平面

怎麼確定兩個平行超平面?我們知道一條直線的數學方程是:y-ax+b=0,而超平面會被定義成類似的形式:

推廣到n維空間,則超平面方程中的w、x分別爲:

如何確保兩超平面之間沒有數據點?我們的目的是通過兩個平行超平面對數據進行分類,那我們可以這樣定義兩個超平面。

對於每一個向量x i :滿足:

或者

也就是這張圖:所有的紅點都是1類,所有的藍點都是−1類。

整理一下上面的兩個超平面:

不等式兩邊同時乘以 yi,-1類的超平面yi=-1,要改變不等式符號,合併後得

ok,記住上面的約束條件。

2. 確定間隔

如何 求兩個平行超平面的間隔呢?我們可以先做這樣一個假設:

  • 是滿足約束 的超平面

  • 是滿足約束 的超平面

  • 上的一點

到平面 的垂直距離 就是我們要的間隔。

這個間隔是可以通過計算出來的,推導還需要一些步驟,直接放結果了就:

其中||w||表示w的二範數,求所有元素的平方和,然後在開方。比如,二維平面下:

可以發現,w 的模越小,間隔m 越大

3. 確定目標

我們的間隔最大化,最後就成了這樣一個問題:

了其中w和b,我們的最優分離超平面就確定了,目的也就達到了。

上面的最優超平面問題是一個凸優化問題,可以轉換成了拉格朗日的對偶問題,判斷是否滿足KKT條件,然後求解。 上一句話包含的知識是整個SVM的核心,涉及到大量的公式推導。

此處 略過 推導的步驟,若想了解推導過程可直接百度。你只需要知道它的目的就是爲了找出一個最優分離超平面。 就假設我們已經解出了最大間隔,找到了最優分離超平面,它是這樣的:

除去上面我們對最大間隔的推導計算,剩下的部分其實是不難理解的。 從上面過程,我們可以發現,其實最終分類超平面的確定依賴於部分極限位置的樣本點,這叫做支持向量。

由於支持向量在確定分離超平面中起着決定性作用,所有將這類模型叫做支持向量機。

我們在上面圖中的點都是線性可分的,也就是一條線(或一個超平面)可以很容易的分開的。 但是實際情況不都是這樣,比如有的女生身高比男生高,有的男生體重比女生都輕, 像這種存在噪聲點分類,應該怎麼處理?

針對樣本的SVM

1. 硬間隔線性SVM

上面例子中提到的樣本點都是線性可分的,我們就可以通過分類將樣本點完全分類準確,不存在分類錯誤的情況,這種叫硬間隔,這類模型叫做硬間隔線性SVM。

2. 軟間隔線性SVM

同樣的,可以通過分類將樣本點不完全分類準確,存在少部分分類錯誤的情況,這叫軟間隔,這類模型叫做軟間隔線性SVM。

不一樣的是,因爲有分類錯誤的樣本點,但我們仍需要將錯誤降至最低,所有需要添加一個懲罰項來進行浮動,所有此時求解的最大間隔就變成了這樣:

硬間隔和軟間隔都是對線性可分的樣本點進行分類,那如果樣本點本身就不線性可分? 舉個例子: 下面這幅圖

樣本點並不是線性可分的,這種問題應該怎麼處理呢? 解決這個問題之前,先看一下這個小短視頻:

視頻中是將平面中的樣本點映射到三維空間中,使用一個平面將樣本線性可分。

所以 我們需要一種方法,可以將樣本從原始空間映射到一個更高緯的空間中,使得樣本在新的空間中線性可分,即: 核函數。 在非線性SVM中,核函數的選擇關係到SVM的分類效果。

幸好的是,我們有多種核函數:線性核函數、多項式核函數、高斯核函數、sigmoid核函數等等,甚至你還可以將這些核函數進行組合,以達到最優線性可分的效果

核函數了解到應該就差不多了,具體的實現我們在下一節的實戰再說。

多分類SVM

前面提到的所有例子最終都指向了二分類,現實中可不止有二分類,更多的是多分類問題。 那麼多 分類應該怎麼分呢? 有兩種方法: 一對多和一對一。

1. 一對多法

一對多法講究的是將所有的分類分成兩類:一類只包含一個分類,另一類包含剩下的所有分類

舉個例子:現在有A、B、C、D四種分類,根據一對多法可以這樣分:

  • ①:樣本A作爲正集,B、C、D爲負集

  • ②:樣本B作爲正集,A、C、D爲負集

  • ③:樣本C作爲正集,A、B、D爲負集

  • ④:樣本D作爲正集,A、B、C爲負集

該方法分類速度較快,但訓練速度較慢,添加新的分類,需要重新構造分 類器。

2. 一對一法

一對一法講究的是從所有分類中只取出兩類,一個爲正類一個爲父類

再舉個例子:現在有A、B、C三種分類,根據一對一法可以這樣分:

  • ①分類器:樣本A、B

  • ②分類器:樣本A、C

  • ③分類器:樣本B、C

該方法的優點是:當新增一類時,只需要訓練與該類相關的分類器即可,訓練速度較快。缺點是:當類的種類K很多時,分類器個數K(K-1)/2會很多,訓練和測試時間較慢。

SVC,Support Vector Classification

我們知道針對樣本有線性SVM和非線性SVM。 同樣的在sklearn 中提供的這兩種的實現,分別是: LinearSVC和SVC。

SVC : Support Vector Classification 用支持向量機處理分類問題

SV R : Support Vector R egressi on     用支持向量機 處理迴歸問題

1. SVC和LinearSVC

LinearSVC是線性分類器,用於處理線性分類的數據,且只能使用線性核函數。 SVC是非線性分類器,即可以 使用線性核函數進行線性劃分,也可以使用高維核函數 進行非線性劃分。

2. SVM的使用

在sklearn 中,一句話調用SVM,

from sklearn import svm

主要說一下SVC的創建,因爲它的參數比較重要

model = svm.SVC(kernel='rbf', C=1.0, gamma=0.001)
分別解釋一下三個重要參數:
  • kernel代表核函數的選擇,有四種選擇,默認rbf(即高斯核函數)

  • 參數C代表目標函數的懲罰係數,默認情況下爲 1.0

  • 參數gamma代表核函數的係數,默認爲樣本特徵數的倒數

其中kernel代表的四種核函數分別是:

  • linear:線性核函數,在數據線性可分的情況下使用的

  • poly:多項式核函數,可以將數據從低維空間映射到高維空間

  • rbf:高斯核函數,同樣可以將樣本映射到高維空間,但所需的參數較少,通常性能不錯

  • sigmoid:sigmoid核函數,常用在神經網絡的映射中

SVM的使用就介紹這麼多,來實戰測試一下。

經典數據集實戰

1. 數據集

SVM的經典數據集:乳腺癌診斷。 醫療人員採集了患者乳腺腫塊經過細針穿刺 (FNA) 後的數字化圖像,並且對這些數字圖像進行了特徵提取,這些特徵可以描述圖像中的細胞核呈現。 通過這些特徵可以將腫瘤分成良性和惡性。

本次數據一共569條 、32個字段,先來看一下具體數據字段吧

其中mean結尾的代表平均值、se結尾的代表標準差、worst結尾代表最壞值(這裏具體指腫瘤的特徵最大值)。 所有其實主要有10個特徵字段,一個id字段,一個預測類別字段。 我們的目的是通過給出的特徵字段來預測腫瘤是良性還是惡性。

2. 數據EDA

EDA:Exploratory Data Analysis探索性數據分析,來看數據的 分佈情況:

df_data.info()

一共569條、32個字段。 32個字段中1個object類型,一個int型id,剩下的都是float 類型。 另外: 數據中不存在缺失值。

大膽猜測一下,object類型可能是類別型數據,即最終的預測類型,需要進行處理,先記下 再來看連續型數據的統計數據:

df_data.describe()

好像也沒啥問題(其實因爲這個數據本身比較規整),可 直接開始特徵工程吧。

3. 特徵工程

首先就是將類別數據連續化

"""2. 類別特徵向量化"""

le = preprocessing.LabelEncoder()

le.fit(df_data['diagnosis'])

df_data['diagnosis'] = le.transform(df_data['diagnosis'])

再來觀察每一個特徵的三個指標:均值、標準差和最大值。 優先選擇均值,最能體現該指特徵的整體情況。

"""3. 提取特徵"""

# 提取所有mean 字段和label字段

df_data_X = df_data.filter(regex='_mean')

df_data_y = df_data['diagnosis']

現在還有十個特徵,我們通過熱力圖來看一下特徵之間的關係

#熱力圖查看特徵之間的關係

sns.heatmap(df_data[df_data_X.columns].corr(), linewidths=0.1, vmax=1.0, square=True,

cmap=sns.color_palette('RdBu', n_colors=256),

linecolor='white', annot=True)

plt.title('the feature of corr')

plt.show()

熱力圖是這樣的:

我們發現radius_mean、perimeter_mean和area_mean這三個特徵強相關,那我們只保留一個就行了。 這裏保留熱力圖裏面得分最高的perimeter_mean。

最後一步, 因爲是連續數值,最好對其進行標準化。 標準化之後的數據是這樣的:

df_data_X = df_data_X.drop(['radius_mean', 'area_mean'], axis=1)

"""5. 進行特徵歸一化/縮放"""

scaler = preprocessing.StandardScaler()

df_data_X = scaler.fit_transform(df_data_X)

return df_data_X, df_data_y

4. 訓練模型

上面已經做好了特徵工程,直接塞進模型看看效果怎麼樣。 因爲並不知道數據樣本到底是否線性可分,所有我們都來試一下兩種算法。 先來看看LinearSVC 的效果

"""1.1. 第一種模型驗證方法"""

# 切分數據集

X_train, X_test, y_train, y_test = train_test_split(data_X, data_y, test_size=0.2)

# 創建SVM分類器

model = svm.LinearSVC()

# 用訓練集做訓練

model.fit(X_train, y_train)

# 用測試集做預測

pred_label = model.predict(X_test)

print('準確率: ', metrics.accuracy_score(pred_label, y_test))

效果很好,簡直好的不行,在此,並沒有考慮 準確率。

ok,還有SVC的效果。 因爲SVC需要設置參數,直接通過網格搜索讓機器自己找到最優參數, 效果更好。

"""2. 通過網格搜索尋找最優參數"""

parameters = {

'gamma': np.linspace(0.0001, 0.1),

'kernel': ['linear', 'poly', 'rbf', 'sigmoid'],

}

model = svm.SVC()

grid_model = GridSearchCV(model, parameters, cv=10, return_train_score=True)

grid_model.fit(X_train, y_train)

# 用測試集做預測

pred_label = grid_model.predict(X_test)

print('準確率: ', metrics.accuracy_score(pred_label, y_test))

# 輸出模型的最優參數

print(grid_model.best_params_)

可以看出,最終模型還是選擇rbf高斯核函數,果然實至名歸。 主要是通過數據EDA+特徵工程完成了數據方面的工作,然後通過交叉驗證+網格搜索確定了最優模型和最優參數。

延伸閱讀

【1】模型評估: 一文詳盡系列之模型評估指標

【2】邏輯迴歸: 一文詳盡系列之邏輯迴歸

【3】K-means: 一文詳盡系列之K-means算法

【4】EM算法: 一文詳盡系列之EM算法

【5】CatBoost: 一文詳盡系列之CatBoost

後臺回覆 SVM 可下載SVM學習框架高清導圖

“爲沉迷學習 點贊

相關文章