一、什么是SVM
SVM主要针对小样本数据进行学习、分类和预测(有时也叫回归)的一种方法,有很好的泛化能力
二、SVM原理
举个例子:
好吧,故事是这样子的:
在很久以前的情人节,大侠要去救他的爱人,但魔鬼和他玩了一个游戏。
魔鬼在桌子上似乎有规律放了两种颜色的球,说:“你用一根棍分开它们?要求:尽量在放更多球之后,仍然适用。”
增加难度
然后,在SVM 工具箱中有另一个更加重要的 trick。 魔鬼看到大侠已经学会了一个trick,于是魔鬼给了大侠一个新的挑战
现在,大侠没有棍可以很好帮他分开两种球了,现在怎么办呢?当然像所有武侠片中一样大侠桌子一拍,球飞到空中。然后,凭借大侠的轻功,大侠抓起一张纸,插到了两种球的中间
再后来
无聊的大人们,把这些球叫做 「data」,把棍子 叫做 「classifier」, 最大间隙trick 叫做「optimization最优化」, 拍桌子叫做「kernelling内核」, 那张纸叫做「hyperplane超平面」
三、SVM内核选择
Linear核:主要用于线性可分的情形。参数少,速度快,适用于一般数据
RBF核:主要用于线性不可分的情形。参数多,分类结果非常依赖于参数。
poly:参数较多,在另外两种都不适用的时候选择
就拟合程度来讲,linear在线性可分的情况下和rbf想过差不多,在线性不可分的情况下rbf明显优于linear,poly在前两种情况下效果都不怎么好,但是在变化剧烈的情况下ploy稍微好点。
就速度来讲,linear肯定是最快的,poly的话因为参数很多,测试中最慢。
就参数而言,linear简单易用,rbf, poly参数较多,但是调参好的话可以得到较好的结果。
图解:
四、SVM实战
直线斜率计算公式:k=(y2-y1)/(x2-x1)
#导入:
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
from sklearn.svm import SVC
#随机生成数据,并且进行训练:
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')
# 第一步:训练
clf.fit(X,y)
#提取系数获取斜率:
# 提取出系数
w = clf.coef_[0]
# 斜率 k=(y2-y1)/(x2-x1)
a = -w[0]/w[1]
#线性方程的截距:
# 分类边界
xx = np.linspace(-5,5)
#intercept截距/X轴方向的系数 == 线性方程的截距
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])
#绘制图形:
# 画出三个边界
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)
# 画出所有点
plt.scatter(X[:,0],X[:,1],c=y)
五、SVM实战:使用多种核函数对iris数据集进行分类
#第一步:导包
from sklearn.svm import SVC
from sklearn.svm import LinearSVC
from sklearn import datasets
#第二步:随机生成数据,并且进行训练
iris = datasets.load_iris()
# 只取两个特征(方便画图)
X = iris.data[:,:2]
y = iris.target
# 建立模型
svc_linear = SVC(kernel='linear')
svc_rbf = SVC(kernel='rbf')#Radial Based Function 基于半径的函数
svc_poly = SVC(kernel='poly') # poly是多项式的意思
linear_svc = LinearSVC() # SVC(kernel = 'linear')相近方法更多,可以处理更多的数据
# 训练模型
svc_linear.fit(X,y)
svc_rbf.fit(X,y)
svc_poly.fit(X,y)
linear_svc.fit(X,y)
#什么是多项式:
#在数学中,多项式(polynomial)是指由变量、系数以及它们之间的加、减、乘、幂运算(非负整数次方)得到的表达式
#形如a0+a1x+a2x^2+...+anx^n这种样子,若an≠0,就是n次多项式。
#第三步:图片背景云点
# 网格密度
h = 0.02
# 设置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
# 得到网格的坐标
xx,yy = np.meshgrid(np.arange(x_min,x_max,h),
np.arange(y_min,y_max,h))
第四步:绘制图形
# 设置图片标题
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')
# 实际点的图
plt.scatter(X[:,0],X[:,1],c=y,cmap='rainbow')
plt.title(titles[i])
六、使用SVM多种核函数进行回归
#第一步:导包
from sklearn.svm import SVR
import numpy as np
#第二步:随机生成数据,并且进行训练
#自定义样本点
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')
#训练并预测
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))
# 画出真实样本点
plt.scatter(X,y,c='k',label='data')
# 画出预测曲线
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练习
案例1、使用不同核对下面三个数据集进行分类,并画出分类边界
ex6data1.mat
ex6data2.mat
ex6data3.mat
tips 注意是分类问题--->使用SVC(Support Vector Classifier)
#第一步:导包
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
#第二步:加载数据
from scipy.io import loadmat
data1 = loadmat('./data/ex6data1.mat')
#通过scipy中加载模块加载的数据是字典
display(data1.keys(),data1)
#第三步:提取数据并进行训练
from sklearn.svm import SVC,LinearSVC
#常用的支持向量机线性、基于半径,多项式
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)
#第五步:调用绘图方法进行绘图
#线性
plot_svc(svc_linear,X,y)
#基于半径
plot_svc(svc_rbf,X,y)
#多项式
plot_svc(svc_ploy,X,y)
案例二:汽车数据
这是一个关于汽车测评的数据集,类别变量为汽车的测评,(unacc,ACC,good,vgood)分别代表(不可接受,可接受,好,非常好),而6个属性变量分别为「买入价」,「维护费」,「车门数」,「可容纳人数」,「后备箱大小」,「安全性」。值得一提的是6个属性变量全部是有序类别变量,比如「可容纳人数」值可为「2,4,more」,「安全性」值可为「low, med, high」
price、maint、doors、persons、lug_boot、safty
recommend
#第一步:导包
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())
#第二步:转换数据
#转换1,2列
price = {'vhigh':4,'high':3,'med':2,'low':1}
data['price'] = data['price'].map(price)#将购买价格的String数据修改成int 便于数据分析
data['maint'] = data['maint'].map(price)#同理修改维护费用
#转换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)
#转换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)
#第三步:提取数据并进行训练
#使用支持向量机进行数据分析,现在的问题是分类
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))
#输出数据很好,预测结果比较准确
来源:CSDN
作者:涤生(bluez)
链接:https://blog.csdn.net/weixin_40903057/article/details/103811529