day-10 sklearn庫實現SVM支持向量算法



  學習了SVM分類器的簡單原理,並調用sklearn庫,對40個線性可分點進行訓練,並繪制出圖形畫界面。

一、問題引入

  如下圖所示,在x,y坐標軸上,我們繪制3個點A1,1),B2,0),C2,3),其中AB屬於一類,C屬於一類。

  我們希望找到一條直線,將兩個類分開來,且保持實線和兩條虛線的距離最大,我們就能將兩個類最大化分割開來。當然,我們還有很多其他直線的可以將兩個點分割開來,但是這樣分割效果最好。

  當一個新的點進行預測時,根據點在直線的位置,判斷所屬分類。例如D4,3)點在實線上方,判定為和C是一類。

  源碼:    

# 導入基本庫
from sklearn import svm
import pylab as pl
import numpy as np
# 初始化坐標點
x = np.zeros((3,2))
x[0] = [2,0]
x[1] = [1,1]
x[2] = [2,3]
y = [0,0,1]
# 建立一個SVM分類器,並進行預測
clf = svm.SVC(kernel='linear')
clf.fit(x,y)

# 打印出所有的支持向量點 
print(clf.support_vectors_)
# 根據方程w_0*x + w_1*y + w_3 = 0--> y = -w_0/w_1*x - w_3/w_1 = kx + b
# 根據w_0,w_1,w_3求得k和b
w = clf.coef_[0]
k = -w[0]/w[1]
b = -clf.intercept_[0]/w[1]
# 調用函數,初始化x點坐標范圍
xx = np.linspace(start=0, stop = 5)
# 計算直線方程
yy = k*xx + b

# 獲取第一個支持向量點,計算直線方程
b = clf.support_vectors_[0]
yy_down = k*xx + (b[1] - k*b[0])

# 獲取最后一個支持向量點,計算直線方程
b = clf.support_vectors_[-1]
yy_up = k*xx + (b[1] - k*b[0])

# 繪制點和直線
pl.scatter(x[:,0],x[:,1])
pl.plot(xx,yy,'k-')
pl.plot(xx,yy_down,'k--')
pl.plot(xx,yy_up,'k--')
pl.scatter(x[:,0],x[:,1],c=y,cmap=pl.cm.Paired)
pl.scatter(4,3,c=y,cmap=pl.cm.Paired)
pl.show()
View Code



二、SVM分類簡單介紹

  最早是由 Vladimir N. Vapnik Alexey Ya. Chervonenkis 1963年提出,目前的版本(soft margin)是由Corinna Cortes Vapnik1993年提出,並在1995年發表,深度學習(2012)出現之前,SVM被認為機器學習中近十幾年來最成功,表現最好的算法。

  假設我們的測試數據為一個二維平面的點,如上圖例子所示,我們定義一條直線方程為w_0*x + w_1*y + w_3 = 0SVM算法的原理就是要根據訓練集獲取到參數w_0w_1w_3的值,即可利用該模型進行新的測試數據預測。對於參數的求導過程,可以參考下面鏈接:

  https://www.zhihu.com/question/21094489

  當我們無法找到一條直線,將不同類分割開來時,我們稱之為線性不可分,否則為線性可分。例如下面所示為線性不可分的情況。對於線性不可分的情況,可以通過一定的映射關系,轉換到其他平面,變成線性可分,例如二維左邊轉換為極坐標。

    

  上面討論的是只有兩種分類,如果遇到大於2中分類的情況,我們可以用迭代分類點方式進行,例如有A,B,C三類,我們可以先將A,B化為一類,整體和C進行分類,如果屬於A,B整體類,再對A,B進行分類,以此類推。


三、簡單的SVM代碼實現

  程序效果圖:對40個線性可分點進行訓練,並繪制出圖形界面。

 

# 函數功能:以[2,2]為中心,隨機產生上下40個線性可分的點,畫出支持向量和所有的點

# 導入基本庫
import numpy as np
import pylab as pl
from sklearn import svm

# 每次程序運行時,產生的隨機點都相同
np.random.seed(0)
# 產生40行隨機坐標,且線性可區分 x = np.r_[np.random.rand(20,2) - [2,2],np.random.rand(20,2) + [2,2]] y = [0]*20 + [1]*20
# 創建一個SVM分類器並進行預測 clf = svm.SVC(kernel='linear') clf.fit(x,y)
# 根據SVM分類器類參數,獲取w_0,w_1,w3的值,並繪制出支持向量 # x_0*x + w_1 *y + w_3 = 0 --> y = -w0/w1*x - w_3/w_1 w = clf.coef_[0] a = -w[0]/w[1] b = -clf.intercept_[0]/w[1] xx = np.linspace(-5, 5) yy = a*xx + b # 斜距式方程:y = kx + b,A(b[0],b[1])為一個支持向量點 b = clf.support_vectors_[0] yy_down = a*xx + (b[1] - a*b[0]) # 斜距式方程:y = kx + b,B(b[0],b[1])為一個支持向量點 b = clf.support_vectors_[-1] yy_up = a*xx + (b[1] - a*b[0]) #畫出3條直線 pl.plot(xx,yy,'k-') pl.plot(xx,yy_down,'k--') pl.plot(xx,yy_up,'k--') #畫出支持向量點 pl.scatter(clf.support_vectors_[:,0], clf.support_vectors_[:,1], s=80,facecolors = 'none') pl.scatter(x[:,0],x[:,1],c=y,cmap=pl.cm.Paired) # 繪制平面圖 pl.axis('tight') pl.show()

 四、學習總結

  在學習過程中,重新復習了直線方程的表達式:兩點式、點斜式、斜距式、截距式,以及點到直線的距離等。同時了解numpy庫對於數組的基本操作。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM