支持向量機:原理與python案例

語言: CN / TW / HK

本文已參與「新人創作禮」活動,一起開啟掘金創作之路

支持向量機淺析

支持向量機(SVM,support vector machine)是一種二類分類模型,其基本模型定義為特徵空間上的間隔最大的線性分類器,其學習策略便是間隔最大化,最終可轉化為一個凸二次規劃問題的求解。

線性分類器

線性迴歸模型的公式為: $ y=w^T X +b$

廣義線性迴歸模型的公式為: $ y=g(w^T X +b)$

分類任務的預測值是離散的,比如二分類問題,可以用0和1來表示兩個類別,通過樣本訓練,即可得到線性分類器

間隔最大超平的含義

我們的任務是找到一個線性分類器($w^T X +b$),將樣本分開,以圖中二維座標為例,能完成分割任務的有無數條線,如何確定一個最近的線性分類器呢?

泛化性能是分類器好壞的一個重要指標。圖中所觀察到的樣本都是訓練樣本,我們希望面對未來的樣本數據,分類器也有良好性能。

image.png

一般而言,相同類別樣本的距離較近,同時根據結構風險最小化原則,線性分類器的決策邊界最大,則邊界的泛化誤差最小。圖中B2的決策邊界到B2的距離明顯小於B1,泛化性能較差。尋找間隔最大的超平面,實際上是找部分關鍵樣本點,使得它們到超平面的距離最大。

439b610bc71159702f3089d15ce4ad0.jpg

線性支持向量機原理

訓練數據集: D={(x_1,y_1),(x_2,y_2),...,(x_n,y_n)},y{-1,+1}

線性分類器決策邊界的線性方程:$ y=w^T X +b$,其中w表示超平面的法向量,決定了決策邊界的方向,b表示位移量,決定了決策邊界與原點間的距離。

訓練數據集中的樣本點,如果為正類,那麼$y_i = +1$,$ w^T X +b > 0$;如果為負類,那麼$y_i = -1$,$ w^T X +b < 0$;

在訓練過程中,我們可以不斷的調整決策邊界的超參數w和b,總可以得到: $\begin{cases}w^T x_i +b >=+1 , y_i=+1;\w^T x_i +b <=-1 , y_i=-1, \end{cases}$

此時,距離決策邊界最近的樣本點,剛好使得上式中等號成立,這些關鍵樣本點,就叫做支持向量,兩個異類支持向量(關鍵樣本點)之間的距離(margin)稱為決策邊界的“邊緣”,這個邊緣的距離就是我們要找的最大間隔,決策邊界B1對應的一組平行的超平面(b11,b12)之間的距離,將間隔記為$\gamma$。

將樣本點$x_1,X_2$ 帶入上式,得: $\begin{cases}b11: w^T x_1 +b =1 ;\ b12:w^T x_2 +b =-1 , \end{cases}$兩式相減得:$ w^T(x_1-x_2)=2$, ($x_1-x_2就是x_1x_2$的模乘上夾角餘弦值),這裏再變換最終得到 $\parallel w\parallel \times\gamma=2$

支持向量機的學習就是,尋找參數w,b,使得$\frac {2}{\parallel w\parallel}$取得最大值。等價於尋找參數w,b,使得$\frac {1}{2}\parallel w\parallel^2$取得最小值,優化函數為:$ y_i(w^T x_i +b)>=1,i =1,2,...,n$,具體優化函數的求解可以使用拉格朗日乘子法求解。

66ef1af5275657373b0a27637e10149.jpg

案例

案例根據y=0.5x+0.5,y=2.1x+6.5兩個函數為基準,引入了較大的隨機誤差後,各生成了100個樣本點。生成的樣本有明顯的線性邊界,我們嘗試使用支持向量機模型,找出決策邊界,並進行繪製軟間隔分類決策邊界。

image.png ```python from sklearn.svm import LinearSVC import numpy as np import pandas as pd import random import matplotlib.pyplot as plt #類似 MATLAB 中繪圖函數的相關函數 import seaborn as sns

np.random.seed(2) count=100 data=[] for i in range(count): x1=np.random.normal(0.00,0.55) res1=x1*0.1+0.5+np.random.normal(0.00,0.9) data.append([x1,res1,1])

x2=np.random.normal(0.00,0.55)
res2=x2*2.1+6.5+np.random.normal(0.00,0.9)
data.append([x2,res2,0])

data =pd.DataFrame(data)

print(data[data[2]==1])

x1_data=np.array(data[0]) x2_data=np.array(data[1]) plt.scatter(x1_data,x2_data,c=data[2]) plt.show()

Pipeline通過將這些數據處理步驟結合成一條算法鏈,以更加高效地完成整個機器學習流程

svm_clf = Pipeline(( ("scaler", StandardScaler()), ("linear_svc", LinearSVC(C=1, loss="hinge")) ,))

調用linear_svc

svm_clf = svm_clf.fit(data.iloc[:,:2], data[2])

SVC求解可視化函數

def decision_boundary( model) : # 取出兩個座標軸的上下限 xmin, xmax, ymin, ymax =x1_data.min(), x1_data.max(), x2_data.min(), x2_data.max()

# 座標軸等分為50份,共可創建50x50=2500個點
xloc = np.linspace(xmin, xmax, 50)
yloc = np.linspace(ymin, ymax, 50)

# 相當於一個數據複製的作用,將shape=(n,)的數據變為shape=(n,n)
xloc, yloc = np.meshgrid(xloc, yloc)

# 組合座標點coordinate, 將(n, n)的數據展開成(n*n, )的數據在組合為座標
coo = np.vstack([xloc.ravel(), yloc.ravel()]).T

# 通過decision_function函數計算出每個點到決策邊界的距離
dis = model.decision_function(coo)

# contour要求X,Y,Z具有相同的維度,所以需要將預測結果reshape
dis = dis.reshape(xloc.shape)

# 畫出原始數據的散點圖
plt.scatter(x1_data,x2_data, c=y)

# 添加決策邊界和兩個超平面
plt.contour(xloc, yloc, dis, alpha=.8, linestyles=['-', '--', '-'], levels=[-1, 0, 1])

plt.show()

decision_boundary(svm_clf)

```