支持向量机

概念

目录

概念 

什么是支持向量机

引言

 间隔与支持向量

线性可分和线形不可分

函数间隔和几何间隔

函数间隔

几何间隔

支持向量

 SVM的基本型

对偶问题

核技巧

代码

 导入库

数据集

训练模型

决策边界

对比

画图

运行结果


 

什么是支持向量机

支持向量机是一种经典的机器学习方法,在数据量小等条件下其性能仍优于神经网络。

引言

如果用苹果的颜色和大小来判断苹果是否成熟,你觉得哪种方法更合适?

通过近邻的几个苹果样本判断。

设定颜色和大小的阈值,当苹果超过该阈值时认定为成熟。显然,上图中红色直线的分类效果比绿色直线的更好。

那么,我们应如何选取一条直线使得分类效果达到最好?这就是支持向量机所探讨的问题。

 间隔与支持向量

线性可分和线形不可分

给定一个数据集

能够将数据集的正样本(+1)和负样本(-1)完全正确地划分到超平面的两侧,即:

  • 对所有 𝑦𝑖=+1𝑦𝑖=+1 的样本 𝑖𝑖,有 𝒘T𝒙+𝑏>0𝑤T𝑥+𝑏>0
  • 对所有 𝑦𝑖=−1𝑦𝑖=−1 的样本 𝑖𝑖,有 𝒘T𝒙+𝑏<0𝑤T𝑥+𝑏<0

则称数据集 𝑇𝑇 为线性可分数据集(linearly separable data set)。

 若不存在超平面能够将样本完全正确地划分,则称数据集 𝑇𝑇 线性不可分。

函数间隔和几何间隔

函数间隔

|𝒘T𝒙+𝑏| 能够表示点 𝒙𝑥距离超平面的远近,而 𝒘T𝒙+𝑏𝑤T𝑥+𝑏 的符号与类标记 𝑦 的符号是否一致可表示分类是否正确。

因此,可用 𝑦(𝒘T𝒙+𝑏)𝑦(𝑤T𝑥+𝑏) 来表示分类的正确性及确信度,这就是函数间隔(functional margin)的概念。

对于给定的训练数据集 𝑇 和超平面 (𝒘,𝑏),定义超平面 (𝒘,𝑏)关于样本点 (𝒙𝑖,𝑦𝑖) 的函数间隔为

定义超平面 (𝒘,𝑏) 关于训练数据集 𝑇的函数间隔为超平面 (𝒘,𝑏)关于 𝑇 中所有样本点 (𝒙𝑖,𝑦𝑖) 的函数间隔的最小值,即 

几何间隔

函数间隔可以表示分类预测的正确性和确信度。但在选择分离超平面时,仅用函数间隔还不够

因为只要成比例的改变 𝒘 和 𝑏,例如 2𝒘 和 2𝑏,超平面并没有改变,但函数间隔却成为原来的2倍。

我们可以对分离超平面的法向量 𝒘𝑤加某些约束,如规范化,‖𝒘‖=1,使间隔是确定的

此时,函数间隔便成为几何间隔(geometric margin)

令 ‖𝒘‖ 表示 𝒘 的 𝐿2范数,对于给定的训练数据集 𝑇和超平面 (𝒘,𝑏),定义超平面 (𝒘,𝑏) 关于样本点 (𝒙𝑖,𝑦𝑖) 的几何间隔为

定义超平面 (𝒘,𝑏) 关于训练数据集 𝑇𝑇的几何间隔为超平面 (𝒘,𝑏) 关于 𝑇 中所有样本点 (𝑥𝑖,𝑦𝑖)的几何间隔的最小值,即 

超平面 (𝒘,𝑏) 关于样本点 (𝑥𝑖,𝑦𝑖) 的几何间隔表示样本点到超平面的带符号的距离(signed distance)。

当样本点被正确分类时,几何间隔成为样本点到超平面的距离。

支持向量

距离超平面最近的几个点,将之称为支持向量(support vector)。

 SVM的基本型

上图中两个异类支持向量到超平面的距离之和为 

它被称为间隔(margin)。

通过转化可以得到

这就是支持向量机(Support Vector Machine, SVM)的基本型。

对偶问题

对 SVM 基本型使用拉格朗日乘子法可得到其对偶问题(dual problem)

根据拉格朗日对偶性,原始问题的对偶问题是极大极小问题 

为了得到对偶问题的解,需要先求 𝐿(𝒘,𝑏,𝜶)对𝒘,𝑏的极小,再求对 𝜶 的极大。 

核技巧

非线性问题往往不好求解,所以希望能用解线性分类问题的方法解决这个问题。

我们可以进行一个非线性变换,将非线性问题转化为线性问题,通过解变换后的线性问题的方法求解原来的非线性问题。

利用核技巧(kernel trick),我们可以用线性分类方法求解非线性分类问题,步骤如下

  1. 使用一个变换将原空间的数据映射到新空间(特征空间)
  2. 在新空间中用线性分类学习方法从训练数据中学习分类模型

如果原始样本空间是有限维,那么一定存在一个高维特征空间使样本可分。

常见的核函数如下:

代码

 导入库

from sklearn.svm import SVC
from sklearn import datasets
import numpy as np
import matplotlib.pyplot as plt
import math

数据集

iris = datasets.load_iris()
X = iris['data'][:,(2,3)]
y = iris["target"]

setosa_or_versicolor = (y==0)|(y==1)
X = X[setosa_or_versicolor]
y = y[setosa_or_versicolor]

训练模型

svm_clf = SVC(kernel='linear',C=float(1000000000000))
svm_clf.fit(X,y)

决策边界

def plot_svc_decision_boundary(svm_clf, xmin, xmax, sv=True):
    w = svm_clf.coef_[0]
    b = svm_clf.intercept_[0]
    x0 = np.linspace(0,5.5,200)
    decision_boundary = -w[0]/w[1]*x0-b/w[1]
    margin = 1/w[1]
    gutter_up = decision_boundary + margin
    gutter_down = decision_boundary - margin
    if sv:
        svs = svm_clf.support_vectors_
        plt.scatter(svs[:,0],svs[:,1],s=180,facecolors = "#FFAAAA")
    plt.plot(x0,decision_boundary,"k-",linewidth=2)
    plt.plot(x0,gutter_up,"k--",linewidth=2)
    plt.plot(x0,gutter_down,"k--",linewidth=2)

对比

x0 = np.linspace(0,5.5,200)
pred_1 = 5*x0 - 20
pred_2 = x0 -1.8
pred_3 = 0.1*x0 + 0.5

画图

plt.figure(figsize=(14,4))
plt.subplot(121)
plt.plot(X[:,0][y==1],X[:,1][y==1],'bs')
plt.plot(X[:,0][y==0],X[:,1][y==0],'ys')
plt.plot(x0,pred_1,"g-",linewidth=2)
plt.plot(x0,pred_2,"m-",linewidth=2)
plt.plot(x0,pred_3,"r-",linewidth=2)
plt.axis([0,5.5,0,2])

plt.subplot(122)
plot_svc_decision_boundary(svm_clf,0,5.5)
plt.plot(X[:,0][y==1],X[:,1][y==1],'bs')
plt.plot(X[:,0][y==0],X[:,1][y==0],'ys')
plt.axis([0,5.5,0,2])
plt.show()

运行结果

结论

训练好的模型的算法复杂度是由支持向量的个数决定的,而不是由数据的维度决定的。所以 SVM 不太容易产生 overfitting。
SVM 训练出来的模型完全依赖于支持向量,即使训练集里面所有非支持向量的点都被去除,重复训练过程,结果仍然会得到完全一样的模型。
一个 SVM 如果训练得出的支持向量个数比较少,那么SVM 训练出的模型比较容易被泛化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值