機器學習入門(二十二)——SVM(3)

????????SVM的本質上是一個線性分類器,并且引入了Margin區(qū)間的概念,保證Margin最大進而提高模型的準確性。Soft Margin對于SVM改善了模型泛化能力不足的問題,允許噪音、異常點的存在,但本質上仍是處理線性分割的問題。

1.0?使用多項式處理非線性數據

????????處理非線性數據最典型的思路就是使用多項式的方式:擴充原本數據,制造新的多項式特征。

? ? ? ? 使用sklearn.datasets中的make_moon數據集,創(chuàng)建經典的月牙形數據:


import numpy as np

import matplotlib.pyplot as plt

from sklearn import datasets

X, y = datasets.make_moons(noise=0.20,random_state=123)

plt.scatter(X[y==0,0], X[y==0,1])

plt.scatter(X[y==1,0], X[y==1,1])

plt.show()


? ? ? ? 使用多項式特征,建立SVM模型:


from sklearn.preprocessing import PolynomialFeatures, StandardScaler

from sklearn.svm import LinearSVC

from sklearn.pipeline import Pipeline

def PolynomialSVC(degree, C=1.0):

? ? return Pipeline([

? ? ? ? ("poly", PolynomialFeatures(degree=degree)),

? ? ? ? ("std_scaler", StandardScaler()),

? ? ? ? ("linearSVC", LinearSVC(C=C))

? ? ? ? ])

poly_svc = PolynomialSVC(degree=3)

poly_svc.fit(X, y)


? ? ? ? poly_svc的決策邊界如下圖所示??梢钥闯?,通過多項式的方式使得決策邊界不再是一條直線了,而是一條曲線。

????????對于SVM算法來說,可以不使用多項式PolynomialFeatures的方式,而是使用另一種巧妙的方法實現非線性劃分。

2.0 SVM解決非線性問題

2.1 示例1

????????上圖中有兩種情況:第一種情況是線性可分的一維數據,可以在紅藍之間找到一個閾值將二者分開,黑色豎線(非0點刻度)就是決策邊界,左右距離決策豎線最近的點是支持向量(外面套著圓圈的點)。

? ? ? ?第二種情況中,存在 紅-藍-紅 三組數據分布,不存在單一的閾值將三組數據分開。

????????對于第二種情況,SVM使用了一種非常巧妙的思路:一維空間不能解決,投影到二維空間,是數據的空間分布變成了如下的樣子:

????????x橫坐標是,縱坐標是x^2,相當于引入了一個新的維度。此時,就可以用一條線將其分開。

? ? ? ? SVM將在原始空間中無法使用線性分類的數據映射到另一空間(Feature Space)當中,使其變得容易劃分。

2.2 示例2

????????在下面的樣本數據集中,紅色點在中心,藍色點在四周,所以一條直線是肯定無法分劃開的。如果一定要在當前空間將其分開的話,可以找到一個圓圈作為決策邊界,將其分離。

? ? ? ? 同樣,通過坐標變化將其映射到新的空間中,也能夠得到線性可分的形式。將橫坐標變?yōu)?img class="math-inline" src="https://math.jianshu.com/math?formula=x_1%5E2" alt="x_1^2" mathimg="1">,縱坐標變?yōu)?img class="math-inline" src="https://math.jianshu.com/math?formula=x_2%5E2" alt="x_2^2" mathimg="1">,這樣數據在空間分布中如下圖所示:

????????可以想象,有一個內功深厚的武林高手,面對桌子上的一堆混在一起的綠豆和紅豆(數據點),一掌拍在桌子上,用內力將其逼到空中(從低維空間映射到高維空間),再它們在空中分散的時候(在高維空間上線性可分),然后再一刀將其分開(決策平面)。如下圖:

3.0 核函數

????????核函數指得是一類將數據從原始空間映射到Feature Space中的方法,就可以解決原本的線性不可分問題。一般求解最優(yōu)化問題中也常用到核函數。

3.1 多項式核函數

? ? ? ? 一種核函數映射方法:

? ??????\Phi (x)映射方法實際上是將數據維度升上去,映射到一個非常高的維度(大約有\frac{m^2}{2} 維)。

? ? ? ? 一般情況下,高維數據的運算是十分復雜的,但SVM算法的精妙之處在于:兩個向量做內積運算。這樣在原始空間中,兩個向量做內積映射到高維空間中則變成x_i·x_j=\Phi (x_i)·\Phi (x_j)。展開后相乘得到:

? ? ? ??\Phi (a)·\Phi (b)=1+2\sum_{i=1}^l a_ib_i+\sum_{i=1}^l a_i^2b_i^2+\sum_{i=1}^{l-1}\sum_{j=i+1}^l 2a_i a_jb_ib_j

? ??????數學家們神奇地發(fā)現(具體怎么發(fā)現的不用知道...),存在這樣一個表達式:

? ? ? ? 這就是SVM中最重要的一個特性,是SVM算法的精妙之處:數學家設計出一種巧妙的數學變換,使高維空間的操作等價于低維空間的操作,解決了高維空間中的計算量問題,大大減少了運算量,這被稱為Kernel Trick。

? ??????上面的K(a,b)就是所謂的多項式核函數。可以拓展為一般形式:

K(x,y)=(x·y+c)^d

????????其中d為多項式的階數,在sklearn中,階數degree的默認值為3。

3.2 高斯核函數

????????高斯核函數是SVM算法中使用最多的核函數,也被稱作是RBF核(Radial Basis Function Kernel),形式為:

K(x,y)=e^{-\lambda \vert \vert x-y \vert  \vert ^2}

? ? ? ? 高斯核函數的\gamma 與高斯函數(統(tǒng)計學中的正態(tài)分布函數)的\sigma (標準差)成反比,即\gamma 越大,高斯分布越窄;\gamma 越小,高斯分布越寬。\vert \vert x-y \vert  \vert ^2表示向量的范數,可以理解為向量的模。

? ? ? ? 通過一個例子看高斯核函數的作用:

????????將\vert \vert x-y \vert  \vert ^2原本的中的y替換成兩個固定點l_1l_2,這兩個特殊的點為地標landmark。高斯核函數升維的過程就是對于原本的每個x值,如果有兩個landmark的話,就將其升維為二維樣本點,每個樣本升維后的值是高斯核函數的值:x\Rightarrow (e^{-\lambda \vert \vert x-l_1 \vert  \vert ^2},e^{-\lambda \vert \vert x-l_2 \vert  \vert ^2})。通過這樣的映射,就可以將線性不可分數據變得線性可分。

? ? ? ? 對于地標點的選擇,若認為y地標點,那么對于每一個數據點都是landmark,有多少樣本,就有多少地標點,這樣就將m*n的數據映射成m*m的數據。

4.0 SVM最終優(yōu)化函數

????????SVM本身的優(yōu)化函數:

minL_p= \frac{1}{2} w^Tw+C\sum_{1}^l \zeta _i? ??s.t. ??y_i(w^Tx_i+b)\geq 1-\zeta _i\zeta _i\geq 0

? ? ? ? 為求解有條件的最優(yōu)化問題,使用拉格朗日乘數法構造對偶函數:

maxL_D = \sum_{i}^l a_i-\frac{1}{2} \sum_{i,j}^la_ia_jy_iy_jx_i·x_j? ??s.t.?0\leq a_i\leq C \sum_{i=1}^la_iy_i=0

? ? ? ? 引入核函數變換后的函數形式:

maxL_K = \sum_{i}^l a_i-\frac{1}{2} \sum_{i,j}^la_ia_jy_iy_jK(x_i,x_j)? ??s.t.??0\leq a_i\leq C \sum_{i=1}^la_iy_i=0

? ? ? ? 其中K(x_i,x_j)可以使用不同的核函數代入:K(x_i,x_j)=(x_i·x_j+1)^d或者K(x_i,x_j)=e^{-\lambda \vert \vert x_i-x_j \vert  \vert ^2}

5.0 sklearn中的核函數實現

????????使用本篇開頭時的示例數據(make_moons),建立核函數的SVM模型。

5.1 多項式核函數建立SVM


from sklearn.svm import SVC

def PolynomialKernelSVC(degree, C=1.0):

? ? return Pipeline([

? ? ? ? ("std_scaler", StandardScaler()),

? ? ? ? ("kernelSVC", SVC(kernel='poly', degree=degree, C=C))

? ? ? ? ])

poly_kernel_svc = PolynomialKernelSVC(degree=3)

poly_kernel_svc.fit(X, y)


? ? ? ? poly_kernel_svc的決策邊界為:

5.1.1?調整參數C


poly_kernel_svc2 = PolynomialKernelSVC(degree=3,C=200)

poly_kernel_svc2.fit(X, y)


????????poly_kernel_svc2的決策邊界如下圖??梢妳礐越大,中間的“凸起”越尖銳。而參數C是正則化項的系數,C越大,越接近于Hard Margin;C越小,容錯性越大。

5.1.2?調整參數degree


poly_kernel_svc3 = PolynomialKernelSVC(degree=4)

poly_kernel_svc3.fit(X, y)


????????poly_kernel_svc3的決策邊界如下圖。通過一些嘗試發(fā)現,degree參數為偶數時,決策邊界類似于雙曲線的形式,而為奇數時則是以直線為基礎。需要注意多項式階數degree參數越大,則越容易出現過擬合。

5.2?RBF核函數建立SVM


def RBFKernelSVC(gamma=1.0):

? ? return Pipeline([

? ? ? ? ('std_scaler', StandardScaler()),

? ? ? ? ('svc', SVC(kernel='rbf', gamma=gamma))

? ? ])

rbf_svc = RBFKernelSVC(gamma=1.0)

rbf_svc.fit(X,y)


? ??????rbf_svc的決策邊界如下,此時KBF中的參數\gamma 默認為1.0。

5.2.1?調整參數\gamma


rbf_svc2 = RBFKernelSVC(gamma=100)

rbf_svc2.fit(X,y)


????????rbf_svc2的決策邊界如下,可見分類效果非常不好,嚴重的過擬合。但可以直觀看出\gamma 的作用:已知參數\gamma 取值越大,意味著高斯函數的“山峰”越窄。對于每個樣本點來說,相當于在其周圍都形成了一個“山峰”(想象成一個俯視圖,藍色點是“山頂”),以“山峰”比較窄,所以看起來就在每個藍色點的周圍圓環(huán)區(qū)域就比較小。

? ??????由此可見,RBF核函數以該類中的每個點為“山尖”,用gamma參數表示“山峰的粗細”,所有的數據點連成“山脈”,這一區(qū)域是一類范圍,其他范圍都屬于另一類。

? ? ? ? 適當縮小\gamma 的取值,查看分類效果:


rbf_svc3 = RBFKernelSVC(gamma=10)

rbf_svc3.fit(X,y)


????????rbf_svc3的決策邊界如下,可以看出縮小\gamma 后,分類效果要平滑很多。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容