支持向量机SVM(Support Vector Machine)

关注公众号“轻松学编程”了解更多。

【关键词】支持向量,最大几何间隔,拉格朗日乘子法

一、支持向量机的原理

Support Vector Machine。支持向量机,其含义是通过支持向量运算的分类器。其中“机”的意思是机器,可以理解为分类器。
那么什么是支持向量呢?在求解的过程中,会发现只根据部分数据就可以确定分类器,这些数据称为支持向量。
见下图,在一个二维环境中,其中点R,S,G点和其它靠近中间黑线的点可以看作为支持向量,它们可以决定分类器,也就是黑线的具体参数。

解决的问题:

  • 线性分类

在训练数据中,每个数据都有n个的属性和一个二类类别标志,我们可以认为这些数据在一个n维空间里。我们的目标是找到一个n-1维的超平面(hyperplane),这个超平面可以将数据分成两部分,每部分数据都属于同一个类别。 其实这样的超平面有很多,我们要找到一个最佳的。因此,增加一个约束条件:这个超平面到每边最近数据点的距离是最大的。也称为最大间隔超平面(maximum-margin hyperplane)。这个分类器也称为最大间隔分类器(maximum-margin classifier)。 支持向量机是一个二类分类器。

  • 非线性分类

SVM的一个优势是支持非线性分类。它结合使用拉格朗日乘子法和KKT条件,以及核函数可以产生非线性分类器。

SVM的目的是要找到一个线性分类的最佳超平面 f(x)=xw+b=0。求 w 和 b。

首先通过两个分类的最近点,找到f(x)的约束条件。

有了约束条件,就可以通过拉格朗日乘子法和KKT条件来求解,这时,问题变成了求拉格朗日乘子αi 和 b。

对于异常点的情况,加入松弛变量ξ来处理。

非线性分类的问题:映射到高维度、使用核函数。

线性分类及其约束条件

SVM的解决问题的思路是找到离超平面的最近点,通过其约束条件求出最优解。

最大几何间隔(geometrical margin)

求解问题w,b

我们使用拉格朗日乘子法(http://blog.csdn.net/on2way/article/details/47729419)
来求w和b,一个重要原因是使用拉格朗日乘子法后,还可以解决非线性划分问题。
拉格朗日乘子法可以解决下面这个问题:

消除w之后变为:

可见使用拉格朗日乘子法后,求w,b的问题变成了求拉格朗日乘子αi和b的问题。
到后面更有趣,变成了不求w了,因为αi可以直接使用到分类器中去,并且可以使用αi支持非线性的情况.

优势

SVM支持向量机,主要针对小样本数据非线性高维模式识别中表现出许多特有的优势,能解决神经网络不能解决的过学习问题,而且有很好的泛化能力

函数:

SVC(C=1.0, kernel='rbf', degree=3, gamma='auto', coef0=0.0,
shrinking=True, probability=False, tol=0.001, cache_size=200,
class_weight=None, verbose=False, max_iter=-1,
decision_function_shape=None, random_state=None)

参数的含义:

  • C:float参数 默认值为1.0。错误项的惩罚系数。C越大,即对分错样本的惩罚程度越大,因此在训练样本中准确率越高,但是泛化能力降低,也就是对测试数据的分类准确率降低。相反,减小C的话,容许训练样本中有一些误分类错误样本,泛化能力强。对于训练样本带有噪声的情况,一般采用后者,把训练样本集中错误分类的样本作为噪声。

  • kernel: str参数 默认为‘rbf‘,算法中采用的核函数类型,可选参数有:

    • linear:线性核函数
    • poly:多项式核函数
    • rbf:径像核函数/高斯核
    • sigmod:sigmod核函数
    • precomputed:核矩阵
  • degree :int型参数 (default=3),这个参数只对多项式核函数(poly)有用,是指多项式核函数的阶数n,如果给的核函数参数是其他核函数,则会自动忽略该参数。

  • gamma:float参数,默认为auto核函数系数,只对’rbf’、 ‘poly’ 、 ‘sigmoid’有效。 如果gamma为auto,代表其值为样本特征数的倒数,即1/n_features。

  • coef0:float参数 默认为0.0 核函数中的独立项,只有对‘poly’和‘sigmod’核函数有用,是指其中的参数c

  • probability:bool参数 默认为False 是否启用概率估计。 这必须在调用fit()之前启用,并且会fit()方法速度变慢。

  • shrinking:bool参数 默认为True 是否采用启发式收缩方式。

  • tol: float参数 默认为1e^-3 svm停止训练的误差精度。

  • cache_size:float参数 默认为200 指定训练所需要的内存,以MB为单位,默认为200MB。

  • class_weight:字典类型或者‘balance’字符串。默认为None 给每个类别分别设置不同的惩罚参数C,则该类别的惩罚系数为class_weight[i]*C,如果没有给,则会给所有类别都给C=1,即前面参数指出的参数C。 如果给定参数‘balance’,则使用y的值自动调整与输入数据中的类频率成反比的权重。

  • verbose :bool参数 默认为False 是否启用详细输出。 此设置利用libsvm中的每个进程运行时设置,如果启用,可能无法在多线程上下文中正常工作。一般情况都设为False,不用管它。

  • max_iter :int参数 默认为-1 最大迭代次数,如果为-1,表示不限制

  • random_state:int型参数 默认为None 伪随机数发生器的种子,在混洗数据时用于概率估计。

二、实战

1、分类

导包sklearn.svm
#导入支持向量机算法包,使用分类模型
from sklearn.svm import SVC
#导入生成聚类测试数据包
from sklearn.datasets import make_blobs
import numpy as np import matplotlib.pyplot as plt
%matplotlib inline
获取数据
#生成两个聚类数据集
X,y = make_blobs(centers=2)
plt.scatter(X[:,0],X[:,1],c=y)

训练模型
#SVC算法使用线性内核函数
svc = SVC(kernel='linear')
#训练模型
svc.fit(X,y)
#查看各类所有的支持向量
support_vectors = svc.support_vectors_
support_vectors

数组的元素是两个坐标点。

plt.scatter(X[:,0],X[:,1],c=y)
#画出支持向量所在位置
plt.scatter(support_vectors[:,0],support_vectors[:,1],
s=300, #半径为300
alpha=0.4, #透明度为0.4
color='r' #红色
)


获取斜率和截距

# 提取系数获取斜率
w_ = svc.coef_
w_

#获取截距
b_ = svc.intercept_
b_

#求出中线的斜率和截距
#三维立体空间的一条线
# f(x,y) = w_[0,0]*x w_[0,1]*y + b_
# 0 = w_[0,0]*x + w_[0,1]*y + b_
# y = -w_[0,0]/w_[0,1] * x -b_/w_[0,1]
w = -w_[0,0]/w_[0,1]
b = -b_/w_[0,1]
#求出上边界和下边界截距
# y = w*x +b
b_up = support_vectors[0][1] -w*support_vectors[0][0]
b_down = support_vectors[1][1] -w*support_vectors[1][0]
绘图
plt.scatter(X[:,0],X[:,1],c=y)
#画出支持向量所在位置
plt.scatter(support_vectors[:,0],support_vectors[:,1],
s=300, #半径为300
alpha=0.4, #透明度为0.4
color='r' #红色
)
#画出回归线
x1 = np.linspace(0,12,100)
y1 = w*x1 + b
plt.plot(x1,y1,color='green')
plt.plot(x1,w*x1 + b_up,color='red')
plt.plot(x1,w*x1 + b_down,color='blue')

2、SVM分离坐标点

导包
#导入支持向量机算法包,使用分类模型
from sklearn.svm import SVC
#导入生成聚类测试数据包
from sklearn.datasets import make_blobs
import numpy as np import matplotlib.pyplot as plt
%matplotlib inline
获取数据
#随机生成300个点
X = np.random.randn(300,2)
plt.scatter(X[:,0],X[:,1])

把坐标点分类
#第1、3象限分为一类,特点:(x,y)要么都为正,要么都为负
#第2、4象限分为一类,特点:(x,y)有正有负
#所以可以使用异或把坐标点分类
#异或操作(X[:,0],X[:,1])
y = np.logical_xor(X[:,0] > 0, X[:,1] > 0)
plt.scatter(X[:,0],X[:,1],c = y)

训练模型
svc = SVC(kernel='rbf')
svc.fit(X,y)

#####选取坐标系中的一些点作为测试点

a = np.linspace(-3,3,100)

b = np.linspace(-3,3,100)
#把a和b进行网格交叉
A,B = np.meshgrid(a,b)
#把A,B进行列与列合并,形成坐标点
X_test = np.concatenate([A.reshape(-1,1),
B.reshape(-1,1)],
axis = 1)
plt.scatter(X_test[:,0],X_test[:,1])

绘制测试点到分离超平面的距离
#计算样本点到分割超平面的函数距离
d_ = svc.decision_function(X_test)
d_

把二维的点投射到三维空间中,在两类点中有一个超平面,其中一类的的点在超平面的上面,另一类的点在超平面的下面。

绘制等高线图
plt.figure(figsize=(6,6))
#绘制等高面
plt.contourf(A,B,d_.reshape(100,100)) plt.scatter(X[:,0],X[:,1],c = y) # 绘制等高线
plt.contour(A,B,d_.reshape(100,100))

3、使用多种核函数对iris数据集进行分类

导包
from sklearn.svm import SVC
import numpy as np
import matplotlib.pyplot as plt import sklearn.datasets as datasets %matplotlib inline
获取数据
iris = datasets.load_iris()
#提取数据只提取两个特征,方便画图
X = iris.data[:,:2]
y = iris.target
plt.scatter(X[:,0],X[:,1],c = y)

训练模型
estimators = {'linear':SVC(kernel = 'linear'),
'rbf':SVC(),
'poly':SVC(kernel = 'poly')
}
for key,estimator in estimators.items():
estimator.fit(X,y)
获取测试点
x1 = np.linspace(4,8,200)
y1 = np.linspace(2,4.5,100) X1,Y1 = np.meshgrid(x1,y1)
#合并X1,Y1成为坐标点
X_test = np.c_[X1.ravel(),Y1.ravel()]
预测
result_ = {}
for key,estimator in estimators.items():
y_ = estimator.predict(X_test) result_[key] = y_
绘图
plt.figure(figsize=(12,9))
for i ,key in enumerate(result_): axes = plt.subplot(2,2,i+1) axes.contourf(X1,Y1,result_[key].reshape(100,200))
axes.scatter(X[:,0],X[:,1],c = y,cmap = 'cool')
axes.set_title(key)

4、使用SVM多种核函数进行回归

导包
#SVR为支持向量机回归算法包
from sklearn.svm import SVR
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
获取数据
X = np.linspace(0,2*np.pi,40).reshape(-1,1)
y = np.sin(X)
plt.scatter(X,y)

#数据加噪
y[::4] += np.random.randn(10,1)*0.3
plt.scatter(X,y)

训练模型
#创建三个模型,分别使用不同的内核函数
models = {'linear':SVR(kernel='linear'),
'rbf':SVR(), #kernel='rbf' 默认值
'poly':SVR(kernel='poly')
}
#测试数据
X_test = np.linspace(0,2*np.pi,150).reshape(-1,1)
result_ = {}
#训练模型并预测数据
for key,model in models.items():
model.fit(X,y)
y_ = model.predict(X_test)
result_[key] = y_
绘图
plt.scatter(X,y)
for key,y_ in result_.items():
#显示图例
plt.plot(X_test,y_,label=key)
plt.legend()

可以看出在这个例子中,基于半径(rbf)的SVR模型预测结果更准确。

后记

【后记】为了让大家能够轻松学编程,我创建了一个公众号【轻松学编程】,里面有让你快速学会编程的文章,当然也有一些干货提高你的编程水平,也有一些编程项目适合做一些课程设计等课题。

也可加我微信【1257309054】,拉你进群,大家一起交流学习。
如果文章对您有帮助,请我喝杯咖啡吧!

公众号

关注我,我们一起成长~~

python机器学习之支持向量机SVM的更多相关文章

  1. 吴裕雄--天生自然python机器学习:支持向量机SVM

    基于最大间隔分隔数据 import matplotlib import matplotlib.pyplot as plt from numpy import * xcord0 = [] ycord0 ...

  2. Python机器学习笔记:SVM(1)——SVM概述

    前言 整理SVM(support vector machine)的笔记是一个非常麻烦的事情,一方面这个东西本来就不好理解,要深入学习需要花费大量的时间和精力,另一方面我本身也是个初学者,整理起来难免思 ...

  3. 机器学习算法 - 支持向量机SVM

    在上两节中,我们讲解了机器学习的决策树和k-近邻算法,本节我们讲解另外一种分类算法:支持向量机SVM. SVM是迄今为止最好使用的分类器之一,它可以不加修改即可直接使用,从而得到低错误率的结果. [案 ...

  4. 机器学习之支持向量机—SVM原理代码实现

    支持向量机—SVM原理代码实现 本文系作者原创,转载请注明出处:https://www.cnblogs.com/further-further-further/p/9596898.html 1. 解决 ...

  5. 【机器学习】支持向量机SVM

    关于支持向量机SVM,这里也只是简单地作个要点梳理,尤其是要注意的是SVM的SMO优化算法.核函数的选择以及参数调整.在此不作过多阐述,单从应用层面来讲,重点在于如何使用libsvm,但对其原理算法要 ...

  6. Python机器学习算法 — 支持向量机(SVM)

    SVM--简介 <α∗j<C,可得:          构造决策函数:  5.求最优解         要求解的最优化问题如下:          考虑使用序列最小最优化算法(SMO,se ...

  7. Python中的支持向量机SVM的使用(有实例)

    除了在Matlab中使用PRTools工具箱中的svm算法,Python中一样可以使用支持向量机做分类.因为Python中的sklearn也集成了SVM算法. 一.简要介绍一下sklearn Scik ...

  8. 机器学习(十一) 支持向量机 SVM(上)

    一.什么是支撑向量机SVM (Support Vector Machine) SVM(Support Vector Machine)指的是支持向量机,是常见的一种判别方法.在机器学习领域,是一个有监督 ...

  9. 机器学习-5 支持向量机SVM

    一.概念和背景 SVM:Support Vector Machine 支持向量机. 最早是由Vladimir N. Vapnik和Alexey Ya. Chervonenkis在1963年提出的. 目 ...

随机推荐

  1. 配置hive的元数据到Mysql中

    在hive的安装目录下,进入conf目录,创建一个hive-site.xml文件 根据官方文档配置参数,拷贝数据到hive-site.xml文件中 https://cwiki.apache.org/c ...

  2. AES加密 Pkcs7 (BCB模式) java后端版本与JS版本对接

    1.BCB模式是需要设置iv偏移量和Key值,这两个值就像账号和密码一样,当这两个值一致时才能确保加密和解密的数据一致.(ps:这两个值千万不能暴露出去哦!) 2.JAVA版本代码: 这里的iv偏移量 ...

  3. MDK内的KEEP关键字以及$$Base $$Limit

    使用mdk编程,假如有一个有用的函数你定义了但是没有显式的调用,mdk在默认方式下,将会把这个函数从整个程序总删除掉,以节省ROM. 比如,你在ROM的0x00002000处定位了一个函数,假设为vo ...

  4. spring-boot-route(七)整合jdbcTemplate操作数据库

    在一部分内容中,我们学习了Restful接口的编写,及接口文档的生成.我们需要将接口数据进行持久化存储,这一部分我们主要学习几种持久化框架将数据进行存储.本部分内容中,我们都将使用mysql为例来做为 ...

  5. 089 01 Android 零基础入门 02 Java面向对象 02 Java封装 01 封装的实现 03 # 088 01 Android 零基础入门 02 Java面向对象 02 Java封装 01 封装的实现 03 使用包进行类管理(1)——创建包

    089 01 Android 零基础入门 02 Java面向对象 02 Java封装 01 封装的实现 03 # 088 01 Android 零基础入门 02 Java面向对象 02 Java封装 ...

  6. Arduino 跑马灯

    参考: 1. https://blog.csdn.net/hunhun1122/article/details/70254606 2. http://www.51hei.com/arduino/392 ...

  7. error C2491: 不允许 dllimport 函数 的定义

    转载:https://blog.csdn.net/gaofeidongdong/article/details/7781345 在工程属性中 预编译宏中加上 DLL_EXPORT为了减少使用dll时候 ...

  8. [学习笔记] 数位DP的dfs写法

    跟着洛谷日报走,算法习题全都有! 嗯,没错,这次我也是看了洛谷日报的第84期才学会这种算法的,也感谢Mathison大佬,素不相识,却写了一长篇文章来帮助我学习这个算法. 算法思路: 感觉dfs版的数 ...

  9. MeteoInfoLab脚本示例:站点填图

    打开包含站点填图的站点数据文件(比如micaps 1)之后,用文件对象的smodeldata函数获取StationModel数据对象,然后用stationmodel函数绘制站点填图图层.脚本程序: # ...

  10. MeteoInfoLab脚本示例:加载地图图层

    应用最广泛的的地图数据应该是shape格式,网络上有很多免费下载资源.MeteoInfoLab中读取shape文件的函数是shaperead,参数即文件名,返回数据包含图形和属性信息的图层对象.矢量图 ...