機器學習A-Z~支持向量機

本文將介紹機器學習中一個非常重要的算法,叫做SVM,中文翻譯支持向量機。首先看一組例子來解釋這個算法。

基本概念

image

有一組數據如圖所示,有紅色的點和藍色的點,代表了兩種分類的數據,現在我們要做的是如何將這兩種數據準確的分隔開來。看圖像其實很簡單,可以橫着畫一條直線或者豎着畫或者斜着畫都能將其分隔開來。那麼svm要做的就是找到最佳的一條直線。

image

那麼這條直線要滿足的特點是它和紅組和綠組有最大的間隔。所謂最大間隔就是紅組中離直線最近的點的距離和綠組中離直線最近的距離最大。這兩個點就叫做Support Vector。這裏解釋下爲什麼叫支持向量,首先“支持”的意思,就是說這些數據點中除了兩個點之外的任何一個點都不會影響到這個算法的決策邊界,即這條直線實際上是又這兩個點支持的,然後“向量”,在二維空間中的點實際上都可以用向量表示,但在高維中沒辦法用幾何方式表示出來,它其實都是向量。

對於這條直線,我們稱作Maximum Margin Hyperplane/Classifier,即最大間隔超平面。所謂超平面就是比數據空間少一維的空間,比如這裏二維的那麼對應的就是一維的即一條直線。

image

其中和這條直線平行的這兩天直線,一個叫做正向超平面,一個叫負向超平面,這個正負這裏只是跟法向量有關,是數學上的概念,不用太在意正負。

接下來看看這個SVM算法爲什麼這麼特別。這裏假設我們需要訓練一個算法來識別蘋果和橘子,比如通過水果的顏色和水分來判斷。那麼大部分的蘋果都是青色或者紅色,而橘子一般是黃色。那麼在圖像中可以當作這個橫軸代表顏色,x1越往右的就是顏色偏黃色的,那麼這部分數據顯然都是橘子。

image

這些正常的水果都在邊界的兩側,並且這部分的數據距離邊界都相對較遠。那麼SVM最特別的地方就是它可以學習到最特殊最特別的東西,比如說這個時候出現了一個黃色的蘋果,很像橘子。那麼這樣的蘋果就是SVM中的支持向量,同樣如果這時有個綠色的橘子也是支持向量。因此SVM其實是由數據中比較極端的個例所實現的。這點和其他的算法有根本的不同。

python實現基礎的SVM

對於如何在python中實現SVM算法其實很簡單,之前的課程中已經講述了一個分類問題的Logistic Regression算法,我們要做的只是將其中的分類器由LogisticRegression改成SVM算法即可。這裏只粘貼那一部分的代碼:

from sklearn.svm import SVC
classifier = SVC(kernel='linear', random_state=0)
classifier.fit(X_train, y_train)

這裏的kernel指的是SVM算法的核,後文會詳細解釋,這裏用的是linear即線性。最終得到的結果我們會發現和之前的分類方式相比優化程度並不是很高,這個和核的選擇是有很大關係的。

核函數支持向量機

上面講的都是線性分類問題,那麼非線性的問題就暫時還無法結局,因此我們需要改良SVM算法,這就是接下來要將的Kernel SVM。

高維投射

看下面這組數據,顯然不是一個線性問題,我們無法用線性的方法將其分類。

image

首先,我們先將線性不可分的數據從低維投射到高維,使得其在高維上線性可分,接下來再將分隔好的數據投射到原先低維的空間。這裏先舉一個一維的問題。這裏有一條直線上,有紅色和綠色的點,這條直線上是否存在一個點將紅點和旅店分開。顯然是無法做到的,那麼需要將其投射到二維空間上。

image

這裏假設有個點在紅綠之間x=5,那麼將所有的點左移5個單位,然後畫出一條曲線$y=(x-5)^2$,這樣就可以將點都投射到這條曲線上。此時就可以找到一條直線將紅綠兩組數據分隔開來了。

image

那麼再回過頭看看上面的二維的問題,我們需要再添加一條座標軸將其投射到三維空間中,此時可以找到一條超平面來分隔開紅綠兩組數據。

image

找到這個平面後我們還需要將其投射回二維平面上,得到的就是如圖一樣的圈,這樣就將數據成功分隔開來。

image

但由於高維到低維然後低維到高維對於計算機而言計算量很大,那麼我們就需要引入核函數來解決非線性問題,可以繞過這裏的繁瑣的計算過程,卻依然能解決問題。

核函數技巧

首先講講非線性SVM中最常用的核函數,The Gaussian RGF Kernel。

image

這裏先假設l已經確定,那麼這個函數就是關於向量x的方程。將其在圖像上表示出來,這裏假設l就是(0,0,0)點。

image

從方程上來看,如果x與l距離很大,那麼指數就會大,由於是負數,那麼整個方程的結果就會趨向於0.如果x與l距離很接近,那麼指數就會趨向於0,加個符號依然趨向於0,那麼這個函數就趨向於1.這裏從圖像也能看出來。

那麼接下來看看如何利用這個函數來尋找數據的分類邊界。函數中的l我們可以當作基準點,在上述的數據中如圖假設是綠色點的中心,那麼很顯然,所有的綠色點距離這個點的距離一定是小於某個常數,而紅色的點距離它的距離一定大於這個常數。

image

在三維空間中我們可以畫個圈如圖所示,這個圈的縱座標並不是就是0,只是很接近於0。那麼綠色點就是坐落於圈的裏面這個高上上面,而紅色的點就在這個圈外面。此時就可以將這個圈投影到二維平面上,即這組數據的分類邊界。

image

接下來再講講這個$\sigma$是做什麼的,它實際上是控制這個圓的半徑。當其升高的時候,要達到同樣的函數值,分母也要變大,那麼圓圈的半徑就會越大,反之其越小的時候半徑也會越小。這個$\sigma$的值取決於數據本身,如果這個綠色的數據本身就蜷縮在一起,那麼它就會很小,反之很大。

再看一個稍微複雜點的數據如下所示:

image

那麼它的邊界就類似兩個圓拼接在一起,核函數就是兩個不同的核函數的和,實際情況可能會乘上一個係數。那麼綠色的點距離這兩個核的距離和較小,紅色的距離它們的和距離較大。

那麼分類邊界怎樣界定。如圖,這裏的$K(x,l1)$和$K(x,l2)$其實都是關於x1,x2的函數。關於x1,x2的函數等於0在二維空間可以得到一條曲線。假設此時有個新的點,那麼計算這個和如果大於等於0,那麼就分到綠色組,如果小於等於0則分到紅色組。其實完整的版本的函數應該在這兩個函數前都分別要加上一個係數,最後加上一個常數。但這裏爲了方便理解只寫出了簡化版本。

除去高斯核函數還有一些其他常用的核函數如下所示:

不同的核函數

但其實還有很多其他的核函數,這裏給出一個網址,裏面有很多核函數的介紹,感興趣的朋友可以自行查看。

最後的python代碼實現其實就是將上面線性的核換成高斯核,如下所示:

classifier = SVC(kernel='rbf', random_state=0)

最終得到的結果可以自行查看,會發現這個分類器的效果比之前的是有明顯提升的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章