什么是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颜色