什么是SVM
一、什么是SVM
SVM主要針對(duì)小樣本數(shù)據(jù)進(jìn)行學(xué)習(xí)、分類和預(yù)測(cè)(有時(shí)也叫回歸)的一種方法,有很好的泛化能力
二、SVM原理
舉個(gè)例子:
好吧,故事是這樣子的:
在很久以前的情人節(jié),大俠要去救他的愛(ài)人,但魔鬼和他玩了一個(gè)游戲。
魔鬼在桌子上似乎有規(guī)律放了兩種顏色的球,說(shuō):“你用一根棍分開它們?要求:盡量在放更多球之后,仍然適用。”
??
增加難度
然后,在SVM 工具箱中有另一個(gè)更加重要的 trick。 魔鬼看到大俠已經(jīng)學(xué)會(huì)了一個(gè)trick,于是魔鬼給了大俠一個(gè)新的挑戰(zhàn)
現(xiàn)在,大俠沒(méi)有棍可以很好幫他分開兩種球了,現(xiàn)在怎么辦呢?當(dāng)然像所有武俠片中一樣大俠桌子一拍,球飛到空中。然后,憑借大俠的輕功,大俠抓起一張紙,插到了兩種球的中間
再后來(lái)
無(wú)聊的大人們,把這些球叫做 「data」,把棍子 叫做 「classifier」, 最大間隙trick 叫做「optimization最優(yōu)化」, 拍桌子叫做「kernelling內(nèi)核」, 那張紙叫做「hyperplane超平面」
三、SVM內(nèi)核選擇
Linear核:主要用于線性可分的情形。參數(shù)少,速度快,適用于一般數(shù)據(jù)
RBF核:主要用于線性不可分的情形。參數(shù)多,分類結(jié)果非常依賴于參數(shù)。
poly:參數(shù)較多,在另外兩種都不適用的時(shí)候選擇
就擬合程度來(lái)講,linear在線性可分的情況下和rbf想過(guò)差不多,在線性不可分的情況下rbf明顯優(yōu)于linear,poly在前兩種情況下效果都不怎么好,但是在變化劇烈的情況下ploy稍微好點(diǎn)。
就速度來(lái)講,linear肯定是最快的,poly的話因?yàn)閰?shù)很多,測(cè)試中最慢。
就參數(shù)而言,linear簡(jiǎn)單易用,rbf, poly參數(shù)較多,但是調(diào)參好的話可以得到較好的結(jié)果。
圖解:
?
四、SVM實(shí)戰(zhàn)
直線斜率計(jì)算公式:k=(y2-y1)/(x2-x1)
#導(dǎo)入:
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
from sklearn.svm import SVC
#隨機(jī)生成數(shù)據(jù),并且進(jìn)行訓(xùn)練:
np.random.seed(0)
X = np.r_[np.random.randn(20,2) - [2,2], np.random.randn(20,2)+[2,2]]
y = [0]*20 + [1]*20
clf = SVC(kernel='linear')
# 第一步:訓(xùn)練
clf.fit(X,y)
#提取系數(shù)獲取斜率:
# 提取出系數(shù)
w = clf.coef_[0]
# 斜率 k=(y2-y1)/(x2-x1)
a = -w[0]/w[1]
#線性方程的截距:
# 分類邊界
xx = np.linspace(-5,5)
#intercept截距/X軸方向的系數(shù) == 線性方程的截距
yy = a*xx -(clf.intercept_[0])/w[1]
#上邊界和下邊界:
# 下邊界
b = clf.support_vectors_[0]
yy_down = a*xx + (b[1]-a*b[0])
# 上邊界
b = clf.support_vectors_[-1]
yy_up = a*xx + (b[1]-a*b[0])
#繪制圖形:
# 畫出三個(gè)邊界
plt.figure(figsize=(12,8))
plt.plot(xx,yy,'k-')
plt.plot(xx,yy_down,'k--')
plt.plot(xx,yy_up,'k--',c = 'r')
# 畫出支持向量
plt.scatter(clf.support_vectors_[:,0],clf.support_vectors_[:,1],s=200)
# 畫出所有點(diǎn)
plt.scatter(X[:,0],X[:,1],c=y)
?
五、SVM實(shí)戰(zhàn):使用多種核函數(shù)對(duì)iris數(shù)據(jù)集進(jìn)行分類
#第一步:導(dǎo)包
from sklearn.svm import SVC
from sklearn.svm import LinearSVC
from sklearn import datasets?
#第二步:隨機(jī)生成數(shù)據(jù),并且進(jìn)行訓(xùn)練
iris = datasets.load_iris()
# 只取兩個(gè)特征(方便畫圖)
X = iris.data[:,:2]
y = iris.target
# 建立模型
svc_linear = SVC(kernel='linear')
svc_rbf = SVC(kernel='rbf')#Radial Based Function 基于半徑的函數(shù)
svc_poly = SVC(kernel='poly') # poly是多項(xiàng)式的意思
linear_svc = LinearSVC() # SVC(kernel = 'linear')相近方法更多,可以處理更多的數(shù)據(jù)
# 訓(xùn)練模型
svc_linear.fit(X,y)
svc_rbf.fit(X,y)
svc_poly.fit(X,y)
linear_svc.fit(X,y)
#什么是多項(xiàng)式:
#在數(shù)學(xué)中,多項(xiàng)式(polynomial)是指由變量、系數(shù)以及它們之間的加、減、乘、冪運(yùn)算(非負(fù)整數(shù)次方)得到的表達(dá)式
#形如a0+a1x+a2x^2+...+anx^n這種樣子,若an≠0,就是n次多項(xiàng)式。
?
#第三步:圖片背景云點(diǎn)
# 網(wǎng)格密度
h = 0.02
# 設(shè)置x軸y軸的界限
x_min,x_max = X[:,0].min()-1, X[:,0].max()+1
y_min,y_max = X[:,1].min()-1, X[:,1].max()+1
# 得到網(wǎng)格的坐標(biāo)
xx,yy = np.meshgrid(np.arange(x_min,x_max,h),
? ? ? ? ? ? ? ? ? ?np.arange(y_min,y_max,h))
第四步:繪制圖形
# 設(shè)置圖片標(biāo)題
titles = ['svc_linear',
? ? ? ? ?'svc_rbf',
? ? ? ? ?'svc_poly',
? ? ? ? ?'linear_svc']
plt.figure(figsize=(12,8))
# 在2*2子圖中畫出四種SVC
for i,clf in enumerate((svc_linear,svc_rbf,svc_poly,linear_svc)):
? ? plt.subplot(2,2,i+1)
? ? Z = clf.predict(np.c_[xx.ravel(),yy.ravel()])
? ? Z = Z.reshape(xx.shape)
? ? # 等高線以及背景
? ? plt.contourf(xx,yy,Z,alpha=0.2,cmap = 'cool')
? ??
? ? # 實(shí)際點(diǎn)的圖
? ? plt.scatter(X[:,0],X[:,1],c=y,cmap='rainbow')
? ? plt.title(titles[i])
?
?
六、使用SVM多種核函數(shù)進(jìn)行回歸
#第一步:導(dǎo)包
from sklearn.svm import SVR
import numpy as np
#第二步:隨機(jī)生成數(shù)據(jù),并且進(jìn)行訓(xùn)練
#自定義樣本點(diǎn)
X = 5*np.random.rand(40,1)
X.sort(axis = 0)
y = np.sin(X).ravel()
#添加噪聲
y[::5] += 3*(0.5 - np.random.rand(8))
#建立模型
svr_linear = SVR(kernel='linear')
svr_rbf = SVR(kernel = 'rbf')
svr_poly = SVR(kernel = 'poly')
#訓(xùn)練并預(yù)測(cè)
p_y_linear = svr_linear.fit(X,y).predict(X)
p_y_rbf = svr_rbf.fit(X,y).predict(X)
p_y_poly = svr_poly.fit(X,y).predict(X)
#第三步:繪制圖形
# 畫圖
plt.figure(figsize=(12,8))
# 畫出真實(shí)樣本點(diǎn)
plt.scatter(X,y,c='k',label='data')
# 畫出預(yù)測(cè)曲線
plt.plot(X,p_y_linear,c='navy',label='linear')
plt.plot(X,p_y_rbf,c='r',label='rbf')
plt.plot(X,p_y_poly,c='g',label='poly')
plt.legend()
?
七、SVM練習(xí)
案例1、使用不同核對(duì)下面三個(gè)數(shù)據(jù)集進(jìn)行分類,并畫出分類邊界
ex6data1.mat
ex6data2.mat
ex6data3.mat
tips 注意是分類問(wèn)題--->使用SVC(Support Vector Classifier)
#第一步:導(dǎo)包
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
#第二步:加載數(shù)據(jù)
from scipy.io import loadmat
data1 = loadmat('./data/ex6data1.mat')
#通過(guò)scipy中加載模塊加載的數(shù)據(jù)是字典
display(data1.keys(),data1)
#第三步:提取數(shù)據(jù)并進(jìn)行訓(xùn)練
from sklearn.svm import SVC,LinearSVC
#常用的支持向量機(jī)線性、基于半徑,多項(xiàng)式
linear_svc = LinearSVC()
svc_linear = SVC(kernel = 'linear')
svc_rbf = SVC(kernel = 'rbf')
svc_ploy = SVC(kernel = 'poly')
X = data1["X"]
y = data1['y']
linear_svc.fit(X,y.ravel())
svc_linear.fit(X,y.ravel())
svc_rbf.fit(X,y.ravel())
svc_ploy.fit(X,y.ravel())
display(linear_svc.score(X,y),svc_linear.score(X,y),svc_rbf.score(X,y),svc_ploy.score(X,y))
#第四步:定義繪制圖形方法
def plot_svc(svc, X, y, h=0.02, pad=0.25):
? ? x_min, x_max = X[:, 0].min()-pad, X[:, 0].max()+pad
? ? y_min, y_max = X[:, 1].min()-pad, X[:, 1].max()+pad
? ? xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
? ? Z = svc.predict(np.c_[xx.ravel(), yy.ravel()])
? ? Z = Z.reshape(xx.shape)
? ? plt.contourf(xx, yy, Z, cmap=plt.cm.Paired, alpha=0.2)
? ? plt.scatter(X[:,0], X[:,1], s=10, c=y, cmap='rainbow')
? ? # Support vectors indicated in plot by vertical lines
? ? sv = svc.support_vectors_
? ? plt.scatter(sv[:,0], sv[:,1], c='k', marker='|', s=100, linewidths='1')
? ? plt.xlim(x_min, x_max)
? ? plt.ylim(y_min, y_max)
? ? plt.xlabel('X1')
? ? plt.ylabel('X2')
? ? plt.show()
? ? print('Number of support vectors: ', svc.support_.size)
#第五步:調(diào)用繪圖方法進(jìn)行繪圖
#線性
plot_svc(svc_linear,X,y)
#基于半徑
plot_svc(svc_rbf,X,y)
#多項(xiàng)式
plot_svc(svc_ploy,X,y)
案例二:汽車數(shù)據(jù)
這是一個(gè)關(guān)于汽車測(cè)評(píng)的數(shù)據(jù)集,類別變量為汽車的測(cè)評(píng),(unacc,ACC,good,vgood)分別代表(不可接受,可接受,好,非常好),而6個(gè)屬性變量分別為「買入價(jià)」,「維護(hù)費(fèi)」,「車門數(shù)」,「可容納人數(shù)」,「后備箱大小」,「安全性」。值得一提的是6個(gè)屬性變量全部是有序類別變量,比如「可容納人數(shù)」值可為「2,4,more」,「安全性」值可為「low, med, high」
price、maint、doors、persons、lug_boot、safty
recommend
?
#第一步:導(dǎo)包
import pandas as pd
import numpy as np
columns = ['price','maint','doors','persons','lug_boot','safty','recommend']
data = pd.read_csv('./data/cars.txt',header = None)
data.columns = columns
display(data['price'].unique(),data['safty'].unique(),data.head())
#第二步:轉(zhuǎn)換數(shù)據(jù)
#轉(zhuǎn)換1,2列
price = {'vhigh':4,'high':3,'med':2,'low':1}
data['price'] = data['price'].map(price)#將購(gòu)買價(jià)格的String數(shù)據(jù)修改成int 便于數(shù)據(jù)分析
data['maint'] = data['maint'].map(price)#同理修改維護(hù)費(fèi)用
#轉(zhuǎn)換3,4列
doors = {'2':2,'3':3,'4':4,'5more':0}
persons = {'2':2,'4':4,'more':0}
data['doors'] = data['doors'].map(doors)
data['persons'] = data['persons'].map(persons)
#轉(zhuǎn)換5,6列
lug_boot = {'small':1,'med':2,'big':3}#后備箱的大小
safty = {'low':1,'med':2,'high':3}#安全性
data['lug_boot'] = data['lug_boot'].map(lug_boot)
data['safty'] = data['safty'].map(safty)
#第三步:提取數(shù)據(jù)并進(jìn)行訓(xùn)練
#使用支持向量機(jī)進(jìn)行數(shù)據(jù)分析,現(xiàn)在的問(wèn)題是分類
from sklearn.svm import SVC
svc_linear = SVC(kernel="linear")
svc_rbf = SVC(kernel='rbf')
svc_poly = SVC(kernel='poly')
X_train = data[['price','maint','doors','persons','lug_boot','safty']]
y_train = data['recommend']
svc_linear.fit(X_train,y_train)
svc_rbf.fit(X_train,y_train)
svc_poly.fit(X_train,y_train)
display(svc_linear.score(X_train,y_train),svc_rbf.score(X_train,y_train),svc_poly.score(X_train,y_train))
#輸出數(shù)據(jù)很好,預(yù)測(cè)結(jié)果比較準(zhǔn)確
?
?
?
?
?
總結(jié)
- 上一篇: EXCEL如何合并单元格且保留全部内容
- 下一篇: aqua在HTML什么颜色,HTML颜色