什么是SVM

房东的猫 提交于 2020-01-11 08:24:34

一、什么是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))

#输出数据很好,预测结果比较准确

 

 

 

 

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!