SVM学习笔记8.27

1.SVM概念

支持向量机(support vector machines,SVM)是一种二分类模型,它将实例的特征向量映射为空间中的一些点,SVM 的目的就是想要画出一条线,以 “最好地” 区分这两类点,以至如果以后有了新的点,这条线也能做出很好的分类。SVM 适合中小型数据样本、非线性、高维的分类问题。

SVM 最早是由 Vladimir N. Vapnik 和 Alexey Ya. Chervonenkis 在1963年提出,目前的版本(soft margin)是由 Corinna Cortes 和 Vapnik 在1993年提出,并在1995年发表。深度学习(2012)出现之前,SVM 被认为机器学习中近十几年来最成功,表现最好的算法。

2.线性分类

先从线性可分的数据讲起,如果需要分类的数据都是线性可分的,那么只需要一根直线f(x)=wx+b就可以分开了。

线性分类器:一个线性分类器的学习目标便是要在n维的数据空间中找到一个超平面(hyper plane)。也就是说,数据不总是二维的,比如,三维的超平面是面。

最大间隔分类器Maximum Margin Classifier:简称MMH, 对一个数据点进行分类,当超平面离数据点的“间隔”越大,分类的确信度(confidence)也越大。所以,为了使得分类的确信度尽量高,需要让所选择的超平面能够最大化这个“间隔”值。这个间隔就是下图中的Gap的一半。

用以生成支持向量的点,如上图XO,被称为支持向量点,因此SVM有一个优点,就是即使有大量的数据,但是支持向量点是固定的,因此即使再次训练大量数据,这个超平面也可能不会变化。

3.非线性分类

 数据大多数情况都不可能是线性的,那如何分割非线性数据呢?

201712270850134.jpg

201712270850135.gif

解决方法是将数据放到高维度上再进行分割,如下图:

201712270850136.png

当f(x)=x时,这组数据是个直线,如上半部分,但是当我把这组数据变为f(x)=x^2时,这组数据就变成了下半部分的样子,也就可以被红线所分割。

比如说,我这里有一组三维的数据X=(x1,x2,x3),线性不可分割,因此我需要将他转换到六维空间去。因此我们可以假设六个维度分别是:x1,x2,x3,x1^2,x1*x2,x1*x3,当然还能继续展开,但是六维的话这样就足够了。

4.有约束最优化问题的数学模型

4.1 有约束优化问题的几何意象

约束条件一般分为等式约束和不等式约束两种,前者表示为 g(x)=0(注意这里的x跟第二章里面的样本x没有任何关系,只是一种通用的表示);后者表示为 g(x)<=0(你可能会问为什么不是   g(x)<0,别着急,到KKT那里你就明白了)。

假(就是这个向量一共有d个标量组成),则 g(x)=0 的几何意象就是d维空间中的d-1维曲面,如果函数 g(x) 是线性的,g(x)=0 则是个d-1维的超平面。那么有约束优化问题就要求在这个d-1维的曲面或者超平面上找到能使得目标函数最小的点,这个d-1维的曲面就是“可行解区域”。

对于不等式约束条件,,则可行解区域从d-1维曲面扩展成为d维空间的一个子集。我们可以从d=2的二维空间进行对比理解。等式约束对应的可行解空间就是一条线;不等式约束对应的则是这条线以及线的某一侧对应的区域,就像下面这幅图的样子(图中的目标函数等高线其实就是等值线,在同一条等值线上的点对应的目标函数值相同)。

4.2 拉格朗日乘子法

首先定义原始目标函数f(x),拉格朗日乘子法的基本思想是把约束条件转化为新的目标函数L(x,m)的一部分,从而使有约束优化问题变成我们习惯的无约束优化问题。

 结论:原始目标函数f(x)的梯度向量必然与约束条件g(x)=0的切线方向垂直。

            函数f(x)的梯度方向也必然与函数自身等值线切线方向垂直。

            函数f(x)与函数g(x)的等值线在最优解点\boldsymbol{x}^*处相切,即两者在\boldsymbol{x}^*点的梯度方向相同或相反。

4.3KKT条件

对于不等式约束条件g(x)<=0的情况,如图所示,最优解所在的位置\boldsymbol{x}^*有两种可能,或者在边界曲线g(x)=0上或者在可行解区域内部满足不等式g(x)<0的地方。

第一种情况:最优解在边界上,就相当于约束条件就是g(x)=0。注意此时目标函数f(\boldsymbol{x})的最优解在可行解区域外面,所以函数f(\boldsymbol{x})在最优解\boldsymbol{x}^*附近的变化趋势是“在可行解区域内侧较大而在区域外侧较小”,与之对应的是函数g(\boldsymbol{x})在可行解区域内小于0,在区域外大于零,所以在最优解\boldsymbol{x}^*附近的变化趋势是内部较小而外部较大。这意味着目标函数f(\boldsymbol{x})的梯度方向与约束条件函数g(\boldsymbol{x})的梯度方向相反。因此根据公式( ),可以推断出参数\lambda>0

 

第二种情况:如果在区域内,则相当于约束条件没有起作用,因此公式()的拉格朗日函数中的参数。整合这两种情况,可以写出一个约束条件的统一表达,如公式()所示。 

其中第一个式子是约束条件本身。第二个式子是对拉格朗日乘子的描述。第三个式子是第一种情况和第二种情况的整合:在第一种情况里,\lambda>0,~g(\boldsymbol{x})=0;在第二种情况下,\lambda=0,~g(\boldsymbol{x})<0。所以无论哪一种情况都有\lambda g(\boldsymbol{x})=0。公式(3.4)就称为Karush-Kuhn-Tucker条件,简称KKT条件。

4.4拉格朗日对偶

对偶问题是将:

 转化变成了:

 最大的里面挑出来的最小的也要比最小的里面挑出来的最大的要大。这关系实际上就是弱对偶关系,而强对偶关系是当等号成立时,既当min maxf大于等于max minf时, min maxf等于max minf

 5.核函数

几种常用核函数:

h度多项式核函数(Polynomial Kernel of Degree h)

高斯径向基和函数(Gaussian radial basis function Kernel)

S型核函数(Sigmoid function Kernel)

松弛变量:

数据本身可能有噪点,会使得原本线性可分的数据需要映射到高维度去。对于这种偏离正常位置很远的数据点,我们称之为 outlier ,在我们原来的 SVM 模型里,outlier 的存在有可能造成很大的影响,因为超平面本身就是只有少数几个 support vector 组成的,如果这些 support vector 里又存在 outlier 的话,其影响就很大了。

因此排除outlier点,可以相应的提高模型准确率和避免Overfitting的方式。

解决多分类问题:

经典的SVM只给出了二类分类的算法,现实中数据可能需要解决多类的分类问题。因此可以多次运行SVM,产生多个超平面,如需要分类1-10种产品,首先找到1和2-10的超平面,再寻找2和1,3-10的超平面,以此类推,最后需要测试数据时,按照相应的距离或者分布判定。

SVM与其他机器学习算法对比(图):

 6.实例

线性,基础:

from sklearn import svm
 
x = [[2, 0, 1], [1, 1, 2], [2, 3, 3]]
y = [0, 0, 1]  # 分类标记
clf = svm.SVC(kernel='linear')  # SVM模块,svc,线性核函数
clf.fit(x, y)
 
print(clf)
 
print(clf.support_vectors_)  # 支持向量点
 
print(clf.support_)  # 支持向量点的索引
 
print(clf.n_support_)  # 每个class有几个支持向量点
 
print(clf.predict([2, 0, 3]))  # 预测

线性展示图

from sklearn import svm
import numpy as np
import matplotlib.pyplot as plt
 
np.random.seed(0)
x = np.r_[np.random.randn(20, 2) - [2, 2], np.random.randn(20, 2) + [2, 2]]  # 正态分布来产生数字,20行2列*2 
y = [0] * 20 + [1] * 20  # 20个class0,20个class1 
 
clf = svm.SVC(kernel='linear')
clf.fit(x, y)
 
w = clf.coef_[0]  # 获取w 
a = -w[0] / w[1]  # 斜率 
# 画图划线 
xx = np.linspace(-5, 5)  # (-5,5)之间x的值 
yy = a * xx - (clf.intercept_[0]) / w[1]  # xx带入y,截距 
 
# 画出与点相切的线 
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])
 
print("W:", w)
print("a:", a)
 
print("support_vectors_:", clf.support_vectors_)
print("clf.coef_:", clf.coef_)
 
plt.figure(figsize=(8, 4))
plt.plot(xx, yy)
plt.plot(xx, yy_down)
plt.plot(xx, yy_up)
plt.scatter(clf.support_vectors_[:, 0], clf.support_vectors_[:, 1], s=80)
plt.scatter(x[:, 0], x[:, 1], c=y, cmap=plt.cm.Paired)  # [:,0]列切片,第0列 
 
plt.axis('tight')
 
plt.show() 


转载:

原文链接:https://blog.csdn.net/qq_31347869/article/details/88071930

原文链接:(8条消息) SVM原理介绍_baidu_36557924的博客-CSDN博客_svm原理               

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值