1、算法簡介
1-1、算法思路
支持向量機(jī)(SVM)是90年代中期發(fā)展起來的基于統(tǒng)計(jì)學(xué)習(xí)理論的一種機(jī)器學(xué)習(xí)方法,作用是基于訓(xùn)練集在樣本空間中找到一個(gè)劃分超平面。如果處理的是二維平面數(shù)據(jù),此時(shí)超平面為一條直線,當(dāng)處理的是三維空間數(shù)據(jù)時(shí),超平面是一個(gè)二維平面。
這個(gè)超平面的表達(dá)式為:wTx+b = 0。如果兩類的標(biāo)簽是+1和-1,則兩個(gè)標(biāo)簽值的邊界表達(dá)式為:wTx+b = 1 、wTx+b = -1。即如果一個(gè)樣本點(diǎn)經(jīng)過wTx+b運(yùn)算后的結(jié)果大于1,則為+1類;運(yùn)算后的結(jié)果小于-1,則為-1類;如果結(jié)果正好等于1或-1,則為“支持向量”;當(dāng)大于-1小于1時(shí),則認(rèn)為這個(gè)點(diǎn)處于間隔之內(nèi)。
一般來講,支持向量機(jī)是一種二分類算法。其基本模型定義為特征空間上的間隔最大的線性分類器,即支持向量機(jī)的學(xué)習(xí)策略便是間隔最大化,最終可轉(zhuǎn)化為一個(gè)凸二次規(guī)劃問題的求解。
“間隔”的作用和意義:一個(gè)點(diǎn)距離分離超平面的遠(yuǎn)近,可以用來表示分類預(yù)測的確信程度,有以下原則:在超平面wTx+b=0確定的情況下:|wTx+b|能夠相對(duì)表示點(diǎn)x距離超平面的遠(yuǎn)近,而w.x+b的標(biāo)簽與類標(biāo)記的標(biāo)簽是否一致(例如:點(diǎn)在正側(cè),wTxi+b大于0,而yi為1,yi大于0,分類正確;點(diǎn)在負(fù)側(cè),wTxi+b小于0,yi為-1,符號(hào)一致,分類正確;反之符號(hào)不一致)。
wT為要求的變量。
現(xiàn)實(shí)任務(wù)中,原始樣本空間也許并不能存在一個(gè)能正確劃分出兩類樣本的超平面,不難想到,沒有條件就創(chuàng)造條件。一般采用的方法是:在原本的樣本上添加一層映射的函數(shù)--核函數(shù)。目的是將樣本從原始空間映射到一個(gè)更高維的特征空間中,使得樣本在這個(gè)新的高維空間中可以被線性劃分為兩類,即在空間內(nèi)線性劃分。常用的核函數(shù)有:線性核、多項(xiàng)式核、高斯核、拉普拉斯核、sigmoid核、通過核函數(shù)之間的線性組合或直積等運(yùn)算得出的新核函數(shù)。效果見1-2中的原始樣本、經(jīng)過核函數(shù)后的樣本。
1-2、圖示



1-3、算法流程
1--- 如果將間隔設(shè)置為1的話,可以得到h1-- w.x+b=1、h2-- w.x+b=-1兩條決策邊界,那么h1和h2的幾何距離依賴于 h1-- w.x+b=0的法向量w,即幾何距離-margin是|wTx+b| / ||w||,即 2/||w||
2--- 求margin的最大值問題就轉(zhuǎn)換為了求||w||的最小值,||w||為w的二階范數(shù)
3--- 綜合上邊的h1、h2,可轉(zhuǎn)換為一個(gè)凸優(yōu)化問題求最優(yōu)解,具體推導(dǎo)過程見https://blog.csdn.net/v_july_v/article/details/7624837或http://www.itdecent.cn/p/12ea00aa5ce4
1-4、優(yōu)缺點(diǎn)
1-4-1、優(yōu)點(diǎn)
a、使用核函數(shù)可以向高維空間進(jìn)行映射
b、使用核函數(shù)可以解決非線性的分類
c、分類思想很簡單,就是將樣本與決策面的間隔最大化
d、分類效果較好
1-4-2、缺點(diǎn)
a、大規(guī)模訓(xùn)練樣本難以實(shí)施
b、解決多分類問題困難
c、對(duì)參數(shù)和核函數(shù)選擇敏感
2、實(shí)踐
2-1、采用bobo老師創(chuàng)建簡單測試用例
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
# 導(dǎo)入sklearn 鳶尾花數(shù)據(jù)
iris = datasets.load_iris()
X = iris.data
y = iris.target
X = X[y<2,:2] # 只取前兩個(gè)label的前兩個(gè)特征,便于畫圖
y = y[y<2]
plt.scatter(X[y==0,0], X[y==0,1], color='red')
plt.scatter(X[y==1,0], X[y==1,1], color='blue')
plt.show() # 見plt.show1

from sklearn.preprocessing import StandardScaler
from sklearn.svm import LinearSVC
standardScaler = StandardScaler()
standardScaler.fit(X)
X_standard = standardScaler.transform(X)
svc = LinearSVC(C=1e9) # C越大 越趨向于hardsvc
svc.fit(X_standard, y)
svc.coef_
# [[ 4.03243037 -2.50699737]]
svc.intercept_
# [0.92736595]