走过路过不要错过 包你一文看懂支撑向量机SVM

假设我们要判断一个人是否得癌症,比如下图:红色得癌症,蓝色不得.

看一下上图,要把红色的点和蓝色的点分开,可以画出无数条直线.上图里黄色的分割更好还是绿色的分割更好呢?直觉上一看,就是绿色的线更好.对吧.

为啥呢?考虑下图,新来了一个黑色点,明显靠蓝色点更近,如果用黄线分割,却把它划分到了红色点这个类别里.

现在细想一下为什么绿线比黄线分隔效果更好?

  • 黄色线太贴近蓝色点
  • 绿色线到红色点群和蓝色点群距离大致相等.恰好位于两个点群中间的位置

由此我们就引申出了SVM的理论基础:使得距离决策边界最近的点的距离之和最远.  我屮艸芔茻,纳尼??这都是啥. 别慌,看下图:

还是上面的问题,什么样的分隔线才是最好的?答案是上图中的绿色线条C.

  1. 线条A平行于C平行于B.
  2. d代表距离C最近的点到C的距离.
  3. margin代表A到B的距离,margin=2d.

我们想寻找的最优分割线其实就是使得margin最大,margin最大意味着红色点和蓝色点被尽可能的分开了.  同时这个分隔线又得不偏不倚,既不偏向红点,也不偏向蓝点,

所以C是A,B正中间的线.

也就是说,A穿过的两个红点和B穿过的蓝点决定了C的位置.我们把其称为支撑向量.  这也是SVM叫做支撑向量机算法的由来.

Hard Margin SVM

假设数据是线性可分的,则我们找得到一条线将数据一分为二.这种情况下我们称之为hard margin svm。

上图中的C在二维空间(即平面)中是一条线. 推广到N维空间中,是一个N-1维的超平面.我们把这个超平面定义为$w^Tx + b = 0$。则任意一点到该超平面的距离为$\frac {|w^Tx+b|} {||w||^2}$

(用二维平面上点(x,y)到直线ax+by+c=0的距离去思考一下,高维空间就别想象了,毕竟人类这种生物是无法理解超过三维空间的)

超平面上方,红球的label我们定义为y=1,超平面下方,蓝色球的label定义为y=-1.(和逻辑回归一样,SVM本身只能解决二分类问题,当然我们可以通过不断SVM的方式以达到解决多分类的问题,这里略去不表.) 则对任意球,到这个超平面距离都大于d。

在分隔平面上方,$w^Tx^i + b$ > 0,y=1,在分隔平面下方,$w^Tx^i + b$ < 0,y=-1。所以我们有

$$y^i \frac{w^Tx^i + b} {||w||^2} \ge d$$,可以转换为 $$y^i \frac{w^Tx^i + b} {d||w||^2} \ge 1$$. $d||w||^2$是一个标量,所以可以改写成

$$y^i(w_d^Tx^i + b_d)\ge 1$$为了表示的方便,记为$$y^i(w^Tx^i + b) \ge 1$$

所以可得下图所示:

对于任意的支撑向量$x^i$而言,$d=\frac {|w^Tx^i + b|} {||w||^2} = \frac 1{||w||^2}$。我们的目标是最大化margin,也就是最大化d,也就是最小化$||w||$。实际中,为了求导的方便,通常转换为最小化$\frac 1 2 ||w||^2$

从而我们的svm的求解转换为一个限定条件下的最优化问题.

$$ \left\{\begin{aligned}  {min \frac 1 2 ||w||^2 \\  S.T. \ \ \ y^{(i)}(w^T x^{(i)} + d) \ge 1}   \end{aligned}\right.$$

限定条件下的最优化问题要比全局最优化问题背后的数学推导复杂太多了,不在本篇说明了。以上,我们基本理解了svm的原理.

Soft Margin SVM

上面,我们假设数据是线性可分的,即我们找得到直线C分割成2部分.但这种假设太理想了,更多的情况下,我们找不到一条直线分隔出红蓝球.如下图:

别管红色点中的那个扎眼的蓝色点到底是一个错误的样本还是一个特殊的样本,总之吧,这种情况下,是找不出一条直线分隔出两种点的.也就是线性不可分.

回顾一下上文的约束条件:$$S.T. \\y^i(w^T x^i + d) \ge 1$$,这意味着分隔出来的区域最大.

  • 红色的点在分隔线的上方,y=1,到分隔线的距离>d。
  • 蓝色的点在分隔线的下方,y=-1,到分隔线的距离>d。

现在为了让我们的分隔线有一定的容错性,我们把它改成

$$ S.T. \ \ y^{(i)}(w^T x^{(i)} + d) \ge 1-\zeta_i   \\ \zeta_i \ge 0$$

注意:

  • 这里的$\zeta_i$不是一个常量,对每一个样本点,都有一个$\zeta_i$,即我们的模型对每一个样本都有容错能力.
  • $\zeta_i  \ge 0$,假如<0的话,相当于将A这条线上移.本来满足条件的红色点都变得不满足了.违背了我们的本意:放宽我们的限定条件.

但是我们的系统作为一个整体,不能容忍太多的错误.所以我们的目标优化函数调整为

$$ min \frac 1 2 ||w||^2 + \sum_{i=1}^{m}\zeta_i$$

此时$min \frac 1 2 ||w||^2$ 和$\sum_{i=1}^{m}\zeta_i$的比例是1:1,意味着我们对"寻找完美分隔超平面"和"模型的错误容忍度"同样看重,为了调整这种比例,即调整最优化时侧重的方面,我们的目标优化函数调整为$ min \frac 1 2 ||w||^2 + C\sum_{i=1}^{m}\zeta_i$

从而我们的问题转换为限定条件下的最优化问题$$ \left\{\begin{aligned}  {min \frac 1 2 ||w||^2  + C\sum_{i=1}^{m}\zeta_i \\  S.T. \ \ \ y^{(i)}(w^T x^{(i)} + d) \ge 1-\zeta_i}   \\  \zeta_i>0 \end{aligned}\right.$$

C越大,代表容错空间越小.

L1/L2正则

上面的$\sum_{i=1}^{m}\zeta_i$即称为L1正则.$\sum_{i=1}^{m}\zeta_i^2$称为L2正则.

正则项的加入,是为了提高模型的包容能力,也就是泛化能力.上面我们举的例子是数据是线性不可分的.实际上即便是线性可分的

在真实的数据中,红色点群中的那个蓝色点很可能是一个误标记的样本. 如果按照hard margin svm的算法,会选择黄色的线作为分隔. 而实际上绿色的分隔线的模型效果更好,泛化能力更强.

多项式特征使用svm

soft margin svm中我们通过对放宽限定条件来解决样本不是线性可分的问题,但是,注意,此时我们的svm模型仍然是线性的.

在逻辑回归和多项式回归两篇博文中我们介绍了如何通过构造新特征,解决数据不存在线性关系的问题.同样的这一思路对svm也是有效的.

from sklearn.preprocessing import PolynomialFeatures, StandardScaler
from sklearn.svm import LinearSVC
from sklearn.pipeline import Pipeline

def PolynomialSVC(degree, C=1.0):
    return Pipeline([
        ("poly", PolynomialFeatures(degree=degree)),
        ("std_scaler", StandardScaler()),
        ("linearSVC", LinearSVC(C=C))
    ])

poly_svc = PolynomialSVC(degree=3)
poly_svc.fit(X, y

核函数

上面的先构造多项式特征,再采用线性svm,可以理解为将特征从低维映射到高维,再做线性svm分隔.

你可以借助这个例子来理解这个过程:你在桌面上(二维空间,平面)有2圈小球,这时候你是找不到直线分隔的,你使劲地砸一下桌子,让球全部飞起来,现在球就到了三维空间中,可以找到一个平面分隔将两类球分隔出来.

前面我们说过了svm实际上是一个限定条件下的最优化问题.

$$ \left\{\begin{aligned}  {min \frac 1 2 ||w||^2 \\  S.T. \ \ \ y^{(i)}(w^T x^{(i)} + d) \ge 1}   \end{aligned}\right.$$

实际上在求解的时候是转化成(不要问我怎么转换的,其中用到的数学推导我已经看不明白了.......)

注意到其中的没有?

试想,如果我们用上述的多项式转换,先把特征转成高维的,比如原有特征有2个,转换为200个,$x_i \dot x_j$将有多少种组合?转换为2000个,20000个呢?此时,为了存储更多的特征,需要用到更多的内存,这还不是最重要的,关键的是带来的计算量增长将是灾难性的.

这时候核函数就闪亮登场了:

我们把上面公式里的x,y视为原始特征值,从$x \dot y$ ,经过K(x,y)后完成了$x \dot y$到$x‘ \dot y‘$的转换,x‘和y‘是多项式转换后的新特征, x‘和我们做二阶多项式转换后的特征是不是很像,区别只是有的特征前有个$\sqrt {2}$的系数,这个系数对我们模型训练无所谓,因为我们的模型是线性的,无非就是原先的系数矩阵的某一维度除以$\sqrt {2}$就是了.

所以我们可以把公式内的$x_i \dot x_j$用$K(x_i,x_j)$替代.实现低维度到高维度的特征转换后的效果.

注意:我们实现了特征低维度转高维度后再训练的效果,但是$K(x_i,x_j)$的计算仍然是在原有维度的!!!!

核函数就是这样一种trick,帮助我们做到在高维空间(甚至是无限维度空间)运算的trick。并没有真正的做低维到高维的特征转换.核函数也不是svm独有的技巧.事实上,核函数的研究比svm算法的出现早了几十年.

上面我们用二阶多项式的例子描述了核函数的原理.

常见的核函数有:

  • 多项式核 $\kappa(x, x_i) = ((x\cdot x_i) + 1)^d$
  • 线性核 $\kappa(x,x_i) = x \cdot x_i$
  • 高斯核 $\kappa(x, x_i) = exp(-\gamma {||x - x_i||^2})$
  • sigmoid核 $\kappa(x, x_i) = tanh(\eta<x, x_i> + \theta)$

高斯核函数

高斯核函数是比较常用的一个核函数,它可以把m*n(m为样本数量,n为样本特征维度)的数据映射成m*m维.当我们的数据的特征维度特别高,而样本数又不多时,就可以了使用这种方法,大大减少计算开销.比如自然语言处理中就常用.

$\kappa(x, x_i) = exp(-\gamma {||x - x_i||^2})$,以2*10的数据为例(2个样本,每个样本10个特征)

x转变为$(\exp(-\gamma {||x - x_1||^2}),\exp(-\gamma {||x - x_2||^2}))$ .即我们以每一个数据点作为参考点(地标点landmark),加以转换,从而将数据转换为m维.

对比一下高斯分布的函数$f(x) = \frac 1 {\sigma \sqrt {2 \pi}} e^{-\frac {(x-\mu)^2} {2\sigma^2}}$ 。你可以把$\gamma$理解为$-\frac 1 {2\sigma^2}$.学过概率论的话就知道高斯分布图如下:

由此,我们知道$\gamma$越大(即$\sigma$越小),分布越集中. 反映到模型中即单个样本的影响越大,最终绘制出的决策边界会围绕着样本点,容易过拟合.如下分别为$\gamma=100$和$\gamma=10$时对同样的数据用svm训练得到的模型的决策边界.

使用svm需要注意的一些事项:

对数据进行标准化,和knn一样,因为涉及到了距离的计算. 不同特征的量纲的不同会带来很大影响.

C越大,对错误分类的容忍性越小.

$\gamma$越大,即标准差越小,决策边界越容易围绕样本,容易过拟合.

SVM思想解决回归问题

前面讲svm分类原理的时候,提到要使margin区域尽可能大,也就是区域内的点尽可能少,相应的,解决回归问题即要使得margin区域内的点越多越好.

Margin边界到拟合直线的距离称为$\epsilon$是SVM解决回归问题的一个超参数。

sklearn中相应的类是sklearn.svm包中的SVR.

原文地址:https://www.cnblogs.com/sdu20112013/p/10266382.html

时间: 2024-11-11 05:12:34

走过路过不要错过 包你一文看懂支撑向量机SVM的相关文章

一文看懂java io系统 (转)

出处:  一文看懂java io系统 学习java IO系统,重点是学会IO模型,了解了各种IO模型之后就可以更好的理解java IO Java IO 是一套Java用来读写数据(输入和输出)的API.大部分程序都要处理一些输入,并由输入产生一些输出.Java为此提供了java.io包 java中io系统可以分为Bio,Nio,Aio三种io模型 关于Bio,我们需要知道什么是同步阻塞IO模型,Bio操作的对象:流,以及如何使用Bio进行网络编程,使用Bio进行网络编程的问题 关于Nio,我们需

一文看懂命令行参数的用法——Python中的getopt神器

一文看懂命令行参数的用法--Python中的getopt神器 参考原文:Python模块之命令行参数解析 - 每天进步一点点!!! - 博客园 https://www.cnblogs.com/madsnotes/articles/5687079.htmlpython getopt使用 - tianzhu123的专栏 - CSDN博客 https://blog.csdn.net/tianzhu123/article/details/7655499在运行程序时,可能需要根据不同的条件,输入不同的命令

[转帖]一文看懂mysql数据库本质及存储引擎innodb+myisam

一文看懂mysql数据库本质及存储引擎innodb+myisam https://www.toutiao.com/i6740201316745740807/ 原创 波波说运维 2019-09-29 00:01:00 概述 今天主要讲下mysql数据库引擎的一些概念和mysql数据库本质,一句话总结: 文件夹-文件:一个数据库其实就是一个的文件夹,数据库里面的表就是文件夹里的一个或者多个文件(根据数据库引擎不同而不同,MyISAM是3个,InnoDB是2.5个) mysql的数据库其实就是存放在M

一文看懂HashMap

一文看懂HashMap 总所周知HashMap是面试中经常问到的一个知识点,也是判断一个候选人基础是否扎实的标准之一,因为通过HashMap可以引出很多知识点,比如数据结构(数组.链表.红黑树).equals和hashcode方法,除此之外还可以引出线程安全的问题,HashMap是我在初学阶段学到的设计的最为巧妙的集合,里面有很多细节以及优化技巧都值得我们深入学习,话不多说先看看相关的面试题: 默认大小.负载因子以及扩容倍数是多少 底层数据结构 如何处理hash冲突的 如何计算一个key的has

【旅游类APP源码】开发者案例开源,走过路过不可错过!

小编语:继上周分享仿饿了么APP源码后,得到了开发者们的强烈反响.热心的开发者(社区ID:小小昊)又翻箱倒柜地找出一个旅游类项目,大手一挥,慷慨奉献给各位AppCan的同学了!想要学习旅游类APP开发的同学千万不要错过啦!AppCan要继续开源!开源!再开源(重要的事情说三遍!) 本案例使用Bootstrap实现css布局,用AppCan IDE开发,用AppCan实现页面跳转功能. 测试机型:红米1S.小米3 页面构成 如图为案例整体布局,起始页为index页面,index页面分为四部分,首页

男默女泪,ArcGIS AddIN 编辑逻辑赏析,走过路过,不要错过

看到了一段ESRI写的一个工具,我反编译了一下,学习工具中的几个代码片段 一. IEditTask task = (this._editor as IEditTaskSearch).get_TaskByUniqueName("GarciaUI_CreateNewFeatureTask"); this._editor.CurrentTask = task; IEditTask :Provides access to a task that receives notification wh

课设走过路过不要错过哦看一眼吧

b15lqd仄氨矢筒履岳<http://weibo.com/20180413pp/230927983046259218583552> d2254r幢柏棕泵谀镁<http://weibo.com/20180413pp/230927983081761833488384> jxoyb4涎推褪烙厝抢<http://weibo.com/20180413p/230927983041865265717248> a0hlpm呜幻痛笔郝壕<http://weibo.com/2018

再见Jenkins,从Gitlab代码提交到k8s服务持续交付只需七毛三(走过路过不要错过)

Gitlab runner 快速搭建CICD pipeline 背景 日常开发中,相信大家已经做了很多的自动化运维环境,用的最多的想必就是利用Jenkins实现代码提交到自动化测试再到自动化打包,部署全流水线Jenkins在devops担任了很重要的角色,但是另一方面相信目前大家的代码版本管理大多都是交给git来管理,在企业私有部署的大背景下,Gitlab由于丰富的插件和细粒度更高的权限控制被大家所采用.如果只是把Gitlab作为代码版本管理,那就大大浪费他的附加价值,在Gitlab中自带CIC

走过路过不要错过~java语言抓取网页想要的内容

学习了正则之后,打算用java玩一玩,所以就决定用它来实现一个好玩的idea import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; //和网络相关的操作 import java.net.URL; import java.net.URLConnection; import java.util.regex.Matcher; import java.util.regex.