1.前言
學習筆記,即TensorFlow實現源碼地址:https://github.com/lsq960124/DeepLearning/blob/master/TensorFlow%20notes/TensorFlow%20basis04%20SVM.ipynb
如圖,對於一個給定的數據集,通過直線A或直線B(多維座標系中爲平面A或平面B)可以較好的將紅點與藍點分類。那麼線A與線B那個更優呢?
在SVM算法中,我們認爲線A是優於線B的。因爲A的‘分類間隔’大於B。
那麼什麼是分類間隔呢? 以A線所在圖爲例,平移直線A直到找到一個極限位置,越過該位置,就會產生分類錯誤的現象。如圖,直線A左右兩邊的直線就是所謂的極限位置,再往左或者往右移動一下直線都會出現分類錯誤的情況。這2條直線之前的垂直距離就是分類間隔。(2d)
而這2條直線中間的分界線也是分類間隔中心所在的直線就是SVM的‘最優決策面’
而這兩條直線上面的點,我們稱之爲‘支持向量’
通俗一點來說,SVM的分類目的就是找到最大的分類間隔即使得2倍的d最大。
2.SVM的最優化問題
首先回顧一下初中便開始接觸的知識:
對於求座標系中任意點到直線的距離,我們很容易給出下面的式子:
把這個原理應用在N維的空間會怎樣?首先N維空間的曲線我們可以用一個我們熟知的式子來表示:
那麼空間中任意一點到曲線的距離可以表示爲:
其中:。
我們令左側的數據的類別爲-1,及對應決策平面左側的點。同理,右側的點爲+1,。
你不用去在意爲什麼是-1和1,實質上你可以令其爲任何你想的數,只是用1和-1會在之後的計算中更爲簡便一些。
那麼決策平面A左右2側的極限位置外的點我們就可以這樣表示:
移項:
我們令
那麼原式就可以轉化爲:
對於決策平面A我們也可以用同樣的方式表示:
這裏有個技巧性的辦法,因爲我們之前令。那麼上式也可以轉化爲:
爲了之後的便於書寫,通常情況下,在這個時候,我們會直接設
*這裏的與與之前的,是不同的概念,相差了一個係數的關係,這樣做也是爲了便於書寫,這些是約定俗成的
*記住在這之後的與都是,
這樣之後
就轉化爲了
所以我們求最大分割間隔的長度問題就可以表示爲:
而我們知道決策平面平移的極限條件爲,所以:
通常情況下我們不會去求而是轉而去求的值,這實質上也是爲了計算方便,但是從理論上上兩者結果並無差別。
我們梳理一下重點內容,通過上面的推到,我們把一個分類的問題轉化爲了一個最優化問題,
(表示的是限定的條件)
3.解決SVM最優化問題
上一節我們由分類間隔的思想得到一個最優化問題。這節將以純數學的方式和大家一起解決這個最優化問題。
首先需要爲大家介紹一下,拉格朗日算子。
百度百科:
在數學最優化問題中,拉格朗日乘數法(以數學家約瑟夫·路易斯·拉格朗日命名)是一種尋找變量受一個或多個條件所限制的多元函數的極值的方法。這種方法將一個有n 個變量與k 個約束條件的最優化問題轉換爲一個有n + k個變量的方程組的極值問題,其變量不受任何約束。這種方法引入了一種新的標量未知數,即拉格朗日乘數:約束方程的梯度(gradient)的線性組合裏每個向量的係數。
拉格朗日算子的定義是生澀不易懂的,所以這裏我將用一個例題來讓對SVM中拉格朗日算子的作用有更深刻的認識:
例:給定橢球,求這個橢球的內接長方體的最大體積,即的最大值
解:建立拉普拉斯算式,算式的偏導爲0
對的偏導結果爲0
聯立四個方程:
代入:
於是得到:
同樣以拉格朗日的算子的原理來求解我們SVM分類的最優化問題:
(表示的是限定的條件)
由拉格朗日算子定義可以轉化成:
其中對的偏導爲0
得到結果:
將這2個結果代入:
所以我們的最優化問題就轉化爲了:
4.SVM的核函數
在第三節中,我們將最優化問題使用拉格朗日算子進行了轉化,在這一小節要介紹的是SVM的核函數,瞭解SVM是怎麼通過核函數減少欠擬合和過擬合現象的。
首先觀察式子
發現這個式子會對每個進行點乘,現在我們將添加上多項式特徵使其得到更爲複雜的分割曲線:
我們設具有多項式特徵的表示爲,現在假設,我們找到一個函數使得:
那麼求解具有多項式特徵的SVM分類器的最優化問題就轉化爲:
而這個函數就是所謂的核函數:
如果不使用核函數,那麼我們需要先將轉化爲然後再將代入最優化式子去求解。而設定這個核函數就是爲了直接將代入最優化式子求得多項式最優解。這樣減少了部分計算機計算開銷和存儲開銷。
從這一點可以看出核函數並不是SVM的專用方法,實質上在我們求解最優化問題上遇到點乘的時候,我們都可以使用到核函數這種技巧。
4.0線性核函數:
4.1多項式核函數(poly):
我們以2次項爲例子,如果我們直接算,我們需要下面這個幾個步驟:
通過上面這個式子,我們可以直接理解爲我們將原來的轉化成了
而使用到核函數這種方法,我們就直接將x,y帶入,這種方式大大的降低了我們計算的複雜度。
回到這個我們最優化問題中:
我們只用將替換成,就爲其添加了多項式的特徵。其實應該爲這個C爲正則化的係數。
4.2高斯核函數(rbf):
首先我們介紹下高斯函數:
高斯核的轉化方式如上圖:雙曲線與座標軸的交點爲
關於高斯核函數的解釋我使用可視化的方式我覺得這樣可以方便理解:使用工具python的numpy和matpoltlib
import numpy as np
import matplotlib.pyplot as plt
#定義一個從-4到5分佈的數值,分割間隔爲1
In [1]:x=np.arange(-4,5,1)
Out[1]: array([-4, -3, -2, -1, 0, 1, 2, 3, 4])
#將-2到2之間的點歸爲一類,類別爲1,將小於-2和大於2的點歸爲一類,類別爲0
In [2]:y=np.array((x>=-2)&(x<=2),dtype='int')
Out[2]: array([0, 0, 1, 1, 1, 1, 1, 0, 0])
#可視化一下
plt.scatter(x[y==0],[0]*len(x[y==0]))
plt.scatter(x[y==1],[0]*len(x[y==1]))
plt.show()
#定義高斯核的公式:
def gaussian(x,l):
gamma=1.0
return np.exp(-gamma * (x-l)**2)
#定義L1和L2的值,即分類的邊界點
l1 , l2 = -1, 1
#開闢一個新的空間,用於存放之後計算出來的額高斯值
new_x = np.empty((len(x),2))
#將x中的每個值代入高斯核函數中
for i,data in enumerate(x):
new_x[i,0] = gaussian(data, l1)
new_x[i,1] = gaussian(data, l2)
#可視化一下代入高斯核函數後的x分佈情況
plt.scatter(new_x[y==0,0],new_x[y==0,1])
plt.scatter(new_x[y==1,0],new_x[y==1,1])
plt.show()
從可視化的圖形可以看出,經過高斯核函數後的x變得線性可分了。
打賞一下作者: