【机器学习基础详解01】——支持向量机(SVM)算法原理与实践

本文主要参考浙江大学胡浩基老师的课程,加上作者自己的理解进行介绍,有理论有实践,超超详细!

目录

一、支持向量机(Support Vector Machine)

1. 基础知识

1.2 问题描述

1.2.1 如何解决线性可分问题

1.2.2 线性不可分情况

1.2.3 扩大可选函数范围

1.3 核函数定义

1.4 原问题和对偶问题

1.4.1 定义

1.4.2 支持向量机原问题转为对偶问题

1.5 算法整体流程

二、鸢尾花案例实现

2.1 数据展示

2.2 案例实现(线性案例

2.3 案例实现(非线性案例)


一、支持向量机(Support Vector Machine)

1. 基础知识

  • 线性可分:假设特征空间是二维的,而各个训练样本在特征空间的分布如下图所示

可以看到,这是一个二分类问题。那么线性可分就指的是,有一条直线可以将图中的×和○分开

敲黑板!!!用数学公式如何表示?如下:

我们给x和○分类,○用c_1表示,x用c_2表示,我们图中的这条直线可以将x和○分开,假设直线方程如下

\omega_1x_1+ \omega_2x_2+b=0

式中,\omega_1,\omega_2是权重,b表示偏置。

在○一侧,\omega_1x_1+ \omega_2x_2+b>0,另一侧\omega_1x_1+ \omega_2x_2+b<0(这个是人为规定的,颠倒也是可以滴)

敲黑板!!!用数学严格定义训练样本以及他们的标签。如下:

这些○和x用数学来表示,为(X_1,y_1),(X_2,y_2),...,(X_N,y_N)

其中,X_i=[x_{i1} ,x_{i2} ]^{T}y_i=\left \{ +1,-1 \right \},假如X_i属于c_1,那么y_i就是+1,如果属于c_2,那么y_i就是-1。(也可以反过来!都是人为规定的!+1和-1也可以为其他数)

综上,线性可分的严格定义:一个训练样本集\left \{ (X_1,y_1),(X_2,y_2),...,(X_N,y_N) \right \},在i=1\sim N线性可分,是指存在\left ( \omega_1,\omega_2,b \right ),使得对i=1\sim N,有如下式子!!!

向量形式来定义线性可分:

假设X_i={\begin{bmatrix} x_{i1}\\ x_{i2} \end{bmatrix}}^T,\omega ={\begin{bmatrix} \omega _{1}\\ \omega_{2} \end{bmatrix}}^T,上边的条件就简化为如下:

可以用一个式子来表示,即:y_i(\omega^TX_i+b)>0

如果空间是三维的呢?图就是这样的,如下所示

  • 线性不可分:指的是,不存在一条直线将图中的×和○分开,例如下图

三维的如下所示:

1.2 问题描述

上边我们了解了线性可分,我们支持向量机的作用就是① 解决线性可分问题;② 将线性可分问题中获得的结论推广到线性不可分情况

1.2.1 如何解决线性可分问题

既然数据集是线性可分的,那就存在无数多个超平面,将各个类别分开,那么在这无数多个超平面中,哪个是最好的???如下所示,123直线都可以将○和x分开,一般人都会觉得2比较好,但是,觉得2号线好的,心里是会对数据集有一些预设的。那么2号线怎么画出来的?这就是一个最优化问题了。接着往下看!

假设,对于任意一条分开○和x的直线,把这条线朝一侧平行移动,直到碰到训练样本为止,另一侧也一样,如下图:

我们将这两条虚线接触到的训练样本,称为支持向量,两条平行线的距离叫做间隔如下图:

我们所要求的2号线就是使间隔最大的一条线!那看一下1和3号线的间隔,如下图,可以看出2号线间隔最大!支持向量机要找的就是间隔最大的那条线

但是!!!间隔最大这个准则不能唯一确定一条直线,例如下面这幅图,任何一条平行于2号线,同时也能分开两类的直线,所产生的间隔是一样大的,为了让找到的线唯一,我们还需要定义这条线在两条平行线的正中间

综上,支持向量机寻找的最优分类直线应该满足3个条件:① 该直线分开了两类;② 该直线最大化间隔;③ 该直线处于间隔的最中间,到所有支持向量的距离相等

用数学该如何表示呢

假设训练样本集是线性可分的,支持向量机需要寻找的是最大化间隔的超平面,已知训练样本集\left \{ \left ( X_i,y_i \right ) \right \},求\omega和b,也就是下式:

解释一下为什么是\frac{1}{2}\left \| \mathbf{\omega } \right \| ^2

因为:\omega是个向量,假设它有m个分量,分别为:\omega =\begin{bmatrix} \omega_1\\\omega_2 \\... \\\omega_m \end{bmatrix}

然后:

因此,支持向量机优化问题就是要最小化\frac{1}{2}\left \| \mathbf{\omega } \right \| ^2,限制条件是y_i(\omega ^Tx_i+b)\ge 1,(i=1\sim N)

这里有两个事实

第一个\omega ^Tx+b=0(a\omega ^T)x+(ab)=0是同一个超平面。(a\neq 0)

第二个:一个点X_0到超平面\omega ^Tx+b=0的距离d=\frac{\left | \omega ^Tx_0+b \right | }{\left \| \omega \right \| }

所以支持向量机优化问题推导如下

根据注意的点1:用a去缩放\omega b,最终使在支持向量x_0上有{\left | \omega ^Tx_0+b \right | }=1,而在非支持向量上{\left | \omega ^Tx_0+b \right | }>1

根据注意的点2:支持向量x_0到超平面的距离将会变为:d=\frac{\left | \omega ^Tx_0+b \right | }{\left \| \omega \right \| }=\frac{1}{\left \| \omega \right \| }

因此最大化支持向量到超平面的距离等价于最小化\left \| \omega \right \|,之所以定为\frac{1}{2}\left \| \mathbf{\omega } \right \| ^2,是因为之后求导方便。

针对限制条件:y_i的作用是协调超平面的左右,让一边( \omega ^Tx+b )>1,另一边( \omega ^Tx+b )<1,和线性可分里的y_i的作用一样。注意:在限制条件中,1可以改为任意正数。例如,如果换成2,那么算出的(\omega ,b)比起原来的相差一个a,根据注意点1可知,他们代表的是一个平面。

科普一下:上边这个优化问题实际上是凸优化问题中的二次规划问题(目标函数是二次项,限制条件是一次项)!这样式儿的,要么无解!要么有唯一最小值的解

1.2.2 线性不可分情况

如果线性不可分的话,那么上述的优化问题是没有解的,也就是说不存在\omega和b 满足所有N个限制条件。怎么办!!!

我们需要适当放松限制条件,思路如下:

对每个训练样本及标签(X_i,Y_i),设置一个松弛变量\delta _i

那么,上述限制条件可写为:y_i(\omega ^TX_i+b)\ge 1-\delta _i,(i=1\sim N)

在线性不可分的情况下,我们不可能保证所有的y_i(\omega ^Tx_i+b)\ge 1,因此引入\delta _i作用在不等式右边,只要每个\delta _i取足够大,那么上述限制条件就可以成立。

所以改造后的支持向量机优化版本如下!

以前的目标函数只需要最小化\frac{1}{2}\left \| \omega \right \| ^2,现在增加了一项所有\delta _i的和。意味着不仅要让\left \| \omega \right \|越小越好,同时要让所有\delta _i的和越小越好。C是比例因子,是人为设定的,用来平衡两项的作用,实际应用中,会不断变化C的值,选取最优的超参数C。

科普一下:人为事先设定的参数叫做算法的超参数

那我们看这幅图!

很显然,这个平面远远不能让人满意,分错了将近一半的训练样本。问题出在哪里

问题在于,我们的算法模型是线性的,即我们假设分开两类的函数是线性的,但是线性模型的表现力是不够的。如上图,能够分开上述样本的应该是一个曲面。因此我们只有扩大可选的函数范围,使它超越线性,才有可能应对各种复杂的线性不可分的情况。

1.2.3 扩大可选函数范围

支持向量机的做法是通过特征空间由低维映射到高维,然后在高维的特征空间当中仍然用线性超平面对数据进行分类

举个栗子,如下图:

如上,x_1=\begin{bmatrix} 0\\0 \end{bmatrix},x_2=\begin{bmatrix} 1\\1 \end{bmatrix},x_3=\begin{bmatrix} 1\\0 \end{bmatrix},x_4=\begin{bmatrix} 0\\1 \end{bmatrix}

我们需要构造一个二维到五维的映射\varphi (x),如下:

\varphi (x):x=\begin{bmatrix} a\\b \end{bmatrix}\to \varphi (x)=\begin{bmatrix} a^2\\b^2 \\a \\b \\ab \end{bmatrix}

按照这个映射,可以算出如下对应的分量:

当映射变成五维时,\varphi (x_1)\varphi (x_4)就变成线性可分了,设\omega =\begin{bmatrix} -1\\-1 \\-1 \\-1 \\6 \end{bmatrix}b=1,可以得出如下:

由于x1和x2属于一类,x3和x4属于一类,上述例子,从2维到5维的映射后变成了线性可分的了。

用定理来说明

假设在一个M维空间上随机取N个训练样本,随机对每个训练样本赋予标签+1或-1,同时,假设这些训练样本线性可分的概率为P(M),则当M趋于无穷大时,P(M)=1

这个定理说明了:将训练样本由低维映射到高维,能够增大线性可分的概率。因此,如何构造由低维到高维的映射\varphi (x)

假设\varphi (x)已经确定,将x映射为\varphi (x),那么优化问题的表示就变为了如下:

可以看到所有的X_i都被\varphi (X_i)替换,并且\omega的维度是与\varphi (x_i)相同的。

高维情况下,优化问题的解法和低维情况是完全类似的

1.3 核函数定义

那么\varphi (X_i)的形式是怎么样的呢?这一小节研究\varphi (X_i)的形式。

对任意两个向量X_1X_2,有K(X_1,X_2)=\varphi (X_1)^T\varphi (X_2),那么仍然能够通过一些技巧获得测试样本X的类别信息,从而完成对测试样本类别的预测。

定义K(X_1,X_2)核函数,是实数。下面举例说明核函数K以及低维到高维的映射\varphi (x)的关系

例子1:已知\varphiK

假设\varphi (x)是一个将二维向量映射到三维向量映射,如下所示:

我们来看下核函数的形式,假设有两个二维向量:X_1=[x_{11} ,x_{12}]^T,X_2=[x_{21} ,x_{22}]^T,根据前边得:\varphi (X_1)=[x_{11}^2,x_{11}x_{12},x_{12}^2 ]\varphi (X_2)=[x_{21}^2,x_{21}x_{22},x_{22}^2 ],那么有如下式子:

上述就是一个已知\varphiK的例子。

例子2:已知K\varphi

假设X是一个二维向量,X_1=[x_{11} ,x_{12}]^T,X_2=[x_{21} ,x_{22}]^T

有如下式子:(为什么这么表示呢,这是一种常见的多项式核函数

根据观察发现,假设X=[x_1,x_2]^T,那么\varphi (X)如下:

综上,核函数K和映射\varphi是一一对应的关系。核函数的形式不能随意取,需要满足一定的条件,才能分解为两个\varphi内积的形式。核函数K(X_1,X_2)必须满足的条件如下:

满足上边的条件,就一定能写成\varphi内积的形式。

1.4 原问题和对偶问题

1.4.1 定义

这里边涉及了一些最优化理论的东西,基础不好的理解起来可能有点吃力。

原问题的定义

自变量\omega,是一个多维向量,目标函数是f(\omega)

对偶问题的定义:首先定义一个函数L(\omega ,\alpha, \beta )

在定义了函数L(\omega ,\alpha, \beta )的基础上,对偶问题如下

综合原问题和对偶问题的定义得到:

定理一:如果\omega^*是原问题的解,(\alpha ^*,\beta ^* )是对偶问题的解,则有:f(\omega ^*)\ge \theta (\alpha ^*,\beta ^*)

证明如下:

f(\omega ^*)- \theta (\alpha ^*,\beta ^*)定义为对偶差距,对偶差距\geqslant 0

还有强对偶定理:如果g(\omega )=A\omega+b,  h(\omega )=C\omega+d,  f(\omega)为凸函数,则有:

f(\omega ^*)= \theta (\alpha ^*,\beta ^*),则对偶差距为0。

即:如果原问题的目标函数是凸函数,而限制条件是线性函数,则f(\omega ^*)= \theta (\alpha ^*,\beta ^*),对偶差距为0。

根据定理一推出的不等式:若f(\omega ^*)= \theta (\alpha ^*,\beta ^*),则定理一中必然能够推出,对于所有的i=1\sim K,要么\alpha _i=0,要么g_i(\omega ^*)=0。这个条件称为KKT条件

1.4.2 支持向量机原问题转为对偶问题

利用1.4.1的原理,将支持向量机的原问题转化为对偶问题,进一步完成支持向量机优化问题的求解。

支持向量机的原问题满足强对偶定理。我们现在的优化问题如下所示:

我们对这个版本进行改造。首先,在原问题的描述中g_i(\omega)\le 0,而支持向量机的限制条件中,两个不等式都是大于等于0的,所以我们将限制条件①②都改为小于等于0的形式:

取相反数就可以变为小于等于0的形式!

第一步:将\delta _i\ge 0(i=1\sim N)转换成\delta _i\le 0(i=1\sim N),得到:

第二步:将限制条件②转换成小于等于0的形式,就变成了下式:

满足强对偶定理

将原问题转化为对偶问题

上一节中对偶问题的\omega等于这里的(\omega ,b,\delta _i),这里不存在h_i(\omega ),我们将对偶问题写成如下形式:

化为对偶问题

由于是遍历所有的(\omega ,b,\delta _i),求最小值,因此,可以对这三个变量求导,并令导数为0。得到如下:

化简得下边的对偶问题为:

由于\alpha _i\ge 0\beta _i\ge 0,根据前边的推导得:\alpha _i+\beta _i=C,所以\beta _i=C-\alpha _i\geqslant 0,所以\alpha _i\le C。这个对偶问题也是个二次规划问题。

1.5 算法整体流程

支持向量机的对偶问题如上所示,如何求解该对偶问题

由于式中\varphi (X_i)^T\varphi (X_j)=K(X_i,X_j),这个K是上述讲的核函数。所以我们只需要知道核函数,就能够求解这个最优化的对偶问题了。

我们要推导,在不知道\omega的显式表达时,也可以通过核函数K算出\omega ^TX+b

首先是如何求b

由于\omega = {\textstyle \sum_{j=1}^{N}\alpha _jy_j\varphi (X_j)},并且\varphi (X_i)^T\varphi (X_j)=K(X_i,X_j),则:

其次,根据KKT条件,对所有的i=1\sim N,能够推出:

如果对于某个i\alpha _i\neq 0\alpha _i\neq c,则根据KKT条件,必有\delta _i=0。所以只需要找个0<\alpha _i< C,b就可以这样求出

算出b之后,考虑对于一个测试样本X,如何预测其类别,这里需要计算\omega ^T\varphi (X)+b

\omega = {\textstyle \sum_{i=1}^{N}\alpha _iy_i\varphi (X_i)}代入得:

结论:即使不知道\varphi (X),只知道核函数K,也可以算出\omega ^T\varphi (X)+b这一结论被称为核函数戏法

最终判别标准如下:

敲黑板!!!

总结支持向量机训练流程

总结支持向量机测试流程:

以上就是原理部分,下边来做一个小小的案例实现。

二、鸢尾花案例实现

本案例使用支持向量机模型,将鸢尾花的数据进行分类。

2.1 数据展示

鸢尾花的数据如下:

数据集中包含150个样本,每行数据包含每个样本的4个特征和样本类别信息。每个样本包含了花萼长度(Sepal.Length)、花萼宽度(Sepal.Width)、花瓣宽度(Petal.Length)、花瓣宽度(Petal.Width)。我们要建立一个分类器,通过这4个特征判断样本是否属于山鸢尾(setosa)、变色鸢尾(versicolor)、维吉尼亚鸢尾(virginica)

2.2 案例实现(线性案例)

我们在jupyter里边运行,jupyter的安装见这篇文章:

【安装软件】手把手教你在Windows上安装anaconda和jupyter-CSDN博客

原始数据点分布,代码如下:

import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.preprocessing import StandardScaler
from sklearn.svm import LinearSVC

iris = datasets.load_iris()
X = iris.data
Y = iris.target

X = X [Y<2,:2] # 只取y<2的类别,也就是0 1 并且只取前两个特征
Y = Y[Y<2] # 只取y<2的类别

# 分别画出类别 0 和 1 的点
plt.scatter(X[Y==0,0],X[Y==0,1],color='red')
plt.scatter(X[Y==1,0],X[Y==1,1],color='blue')
plt.show()

将数据标准化

# 标准化
standardScaler = StandardScaler()
standardScaler.fit(X)

# 计算训练数据的均值和方差
X_standard = standardScaler.transform(X) # 再用 scaler 中的均值和方差来转换 X ,使 X 标准化
svc = LinearSVC(C=1e9) # 线性 SVM 分类器
svc.fit(X_standard,Y) # 训练svm

绘制决策边界

def plot_decision_boundary(model, axis): 
    x0, x1 = np.meshgrid( np.linspace(axis[0], axis[1], int((axis[1]-axis[0])*100)).reshape(-1,1), np.linspace(axis[2], axis[3], int((axis[3]-axis[2])*100)).reshape(-1,1) ) 
    X_new = np.c_[x0.ravel(), x1.ravel()] 
    y_predict = model.predict(X_new) 
    zz = y_predict.reshape(x0.shape)
    from matplotlib.colors import ListedColormap
    custom_cmap = ListedColormap(['#EF9A9A','#FFF59D','#90CAF9']) 
    plt.contourf(x0, x1, zz, cmap=custom_cmap) # 绘制决策边界
    
plot_decision_boundary(svc,axis=[-3,3,-3,3]) # x,y轴都在-3到3之间 

# 绘制原始数据 
plt.scatter(X_standard[Y==0,0],X_standard[Y==0,1],color='red') 
plt.scatter(X_standard[Y==1,0],X_standard[Y==1,1],color='blue') 
plt.show()

可视化如下图:

2.3 案例实现(非线性案例)

首先我们生成一些非线性的数据,然后生成一些噪声点,如下所示:

import numpy as np 
import matplotlib.pyplot as plt 
from sklearn import datasets 
X,y = datasets.make_moons() #使用生成的数据 
print(X.shape) # (100,2) 
print(y.shape) # (100,)
#接下来绘制下生成的数据
plt.scatter(X[y==0,0],X[y==0,1]) 
plt.scatter(X[y==1,0],X[y==1,1]) 
#plt.show()
X, y = datasets.make_moons(noise=0.15,random_state=777) #随机生成噪声点,random_state是随机种子,noise是方差 
plt.scatter(X[y==0,0],X[y==0,1]) 
plt.scatter(X[y==1,0],X[y==1,1]) 
plt.show()

可视化图如下:

通过多项式特征的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))#最后生成svm
                    ])

poly_svc = PolynomialSVC(degree=3)
poly_svc.fit(X,y)
plot_decision_boundary(poly_svc,axis=[-1.5,2.5,-1.0,1.5])
plt.scatter(X[y==0,0],X[y==0,1])
plt.scatter(X[y==1,0],X[y==1,1])
plt.show()

分类如下:

如上图所示,已经不是直线分割了,而是曲线。

案例代码参考:

支持向量机&鸢尾花Iris数据集的SVM线性分类练习_用支持向量机实现一个分类的案例-CSDN博客

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值