支持向量机(Support Vector Machines, SVM)是一种二分类模型,它的基本模型是定义在特征空间上的间隔最大的线性分类器。支持向量机的学习策略就是间隔最大化,可形式化为一个凸二次规划的问题,也等价于正则化的合叶损失函数最小化的问题。支持向量机分为以下三类:
- 线性可分支持向量机:又称为硬间隔支持向量机。当训练数据线性可分时,通过硬间隔最大化学习的线性分类器;
- 线性支持向量机:又称为软间隔支持向量机。当训练数据近似线性可分时,通过软间隔最大化学习的线性分类器;
- 非线性支持向量机:当训练数线性不可分时,通过核技巧及软间隔最大化学习的非线性支持向量机;
简单模型是复杂模型的基础,也是复杂模型的基础。下面先从线性可分支持向量机开始介绍。
1 线性可分支持向量机
假设给定一个特征空间上的训练数据集 T = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , … , ( x N , y N ) } T=\{(x_{1},y_{1}),(x_{2},y_{2}),\dots,(x_{N},y_{N})\} T={(x1,y1),(x2,y2),…,(xN,yN)}其中 x i ∈ R n , y i ∈ { − 1 , + 1 } , i = 1 , 2 , … , N x_{i}\in R^{n},y_{i} \in \{-1, +1\},i=1,2,\dots,N xi∈Rn,yi∈{−1,+1},i=1,2,…,N。当 y i = + 1 y_{i}=+1 yi=+1时,称 x i x_{i} xi为正例,当 y i = − 1 y_{i}=-1 yi=−1时,称 x i x_{i} xi为负例。 ( x i , y i ) (x_{i},y_{i}) (xi,yi)称为样本点。
1.1 函数间隔和几何间隔
- 函数间隔:对于给定的训练数据集
T
T
T和超平面
(
w
,
b
)
(w,b)
(w,b)。定义超平面
(
w
,
b
)
(w,b)
(w,b)关于样本点
(
x
i
,
y
i
)
(x_{i},y_{i})
(xi,yi)的函数间隔为:
γ
^
i
=
y
i
(
w
∙
x
i
+
b
)
\widehat\gamma_{i}=y_{i}(w\bullet x_{i}+b)
γ
i=yi(w∙xi+b)函数间隔能表示分类的正确性及确信度(一个点距离分类超平面的远近可以由
∣
w
∙
x
+
b
∣
|w\bullet x+b|
∣w∙x+b∣来表示,该值还可以表示分类预测的确信程度。距离超平面越远,正确分类的可能性越高;而
w
x
+
b
wx+b
wx+b的符号与类标记
y
y
y的符号是否一致能够表示分类是否正确)。
而超平面 ( w , b ) (w,b) (w,b)关于训练数据 T T T的函数间隔为超平面 ( w , b ) (w,b) (w,b)关于 T T T中所有样本点 ( x i , y i ) (x_{i},y_{i}) (xi,yi)的函数间隔的最小值。即 γ ^ = min i = 1 , 2 , … , N γ ^ i \widehat\gamma=\min\limits_{i=1,2,\dots,N}\widehat\gamma_{i} γ =i=1,2,…,Nminγ i - 几何间隔:由于函数间隔会随着 w w w和 b b b的等比例缩放而发生变动,为了使间隔固定,引入几何间隔。点 ( x i , y i ) (x_{i},y_{i}) (xi,yi)与超平面 ( w , b ) (w,b) (w,b)的几何间隔为: γ i = y i ( w ∙ x i ∥ w ∥ + b ∥ w ∥ ) \gamma_{i}=y_{i}(\frac{w\bullet x_{i}}{\|w\|}+\frac{b}{\|w\|}) γi=yi(∥w∥w∙xi+∥w∥b)从而训练数据集与超平面 ( w , b ) (w,b) (w,b)之间的几何间隔为: γ = min i = 1 , 2 , … , N γ ^ i \gamma=\min\limits_{i=1,2,\dots,N}\widehat\gamma_{i} γ=i=1,2,…,Nminγ i
1.2 数据模型
支持向量机学习的基本思想是求解能够正确划分训练数据集并且几何间隔最大的分离超平面。间隔最大化的直观解释是:对训练数据集找到几何间隔最大的超平面意味着以充分大的确信度对训练数据进行分类。故线性可分支持向量机的目标函数为: { max w , b γ s . t . y i ( w ∙ x i ∥ w ∥ + b ∥ w ∥ ) ≥ γ , i = 1 , 2 , … , N \begin{cases} \max\limits_{w,b} &\gamma\\ s.t. &y_{i}(\frac{w\bullet x_{i}}{\|w\|}+\frac{b}{\|w\|})\geq\gamma,i=1,2,\dots,N \end{cases} ⎩⎨⎧w,bmaxs.t.γyi(∥w∥w∙xi+∥w∥b)≥γ,i=1,2,…,N将上式中的几何间隔替换为函数间隔,则上式可以变换为: { max w , b γ ^ ∥ w ∥ s . t . y i ( w ∙ x i + b ) ≥ γ ^ , i = 1 , 2 , … , N \begin{cases} \max\limits_{w,b} &\frac{\widehat\gamma}{\|w\|}\\ s.t. &y_{i}(w\bullet x_{i}+b)\geq\widehat\gamma,i=1,2,\dots,N \end{cases} ⎩⎨⎧w,bmaxs.t.∥w∥γ yi(w∙xi+b)≥γ ,i=1,2,…,N因为 γ ^ \widehat\gamma γ 的取值不影响最优化问题的解,且最小化的 1 ∥ w ∥ \frac{1}{\|w\|} ∥w∥1等价于最大化的 1 2 ∥ w ∥ 2 \frac{1}{2}\|w\|^{2} 21∥w∥2。所以当 γ ^ = 1 \widehat\gamma=1 γ =1,上式变换为: { min w , b 1 2 ∥ w ∥ 2 s . t . y i ( w ∙ x i + b ) − 1 ≥ 0 , i = 1 , 2 , … , N \begin{cases} \min\limits_{w,b} &\frac{1}{2}\|w\|^{2}\\ s.t. &y_{i}(w\bullet x_{i}+b)-1\geq0,i=1,2,\dots,N \end{cases} ⎩⎨⎧w,bmins.t.21∥w∥2yi(w∙xi+b)−1≥0,i=1,2,…,N这就是一个凸优化问题。为求解该式,需要利用拉个郎日对偶性,通过求解对偶问题来求解原始问题。首先构建拉格朗日函数。为此,对每一个不等式约束引进拉格朗日乘子 α i ≥ 0 , i = 1 , 2 , … , N \alpha_{i}\geq0,i=1,2,\dots,N αi≥0,i=1,2,…,N,定义拉格朗日函数: L ( w , b , α ) = 1 2 ∥ w ∥ 2 − ∑ i = 1 N α i y i ( w ∙ x i + b ) + ∑ i = 1 N α i L(w,b,\alpha)=\frac{1}{2}\|w\|^{2}-\sum_{i=1}^{N}\alpha_{i}y_{i}(w\bullet x_{i}+b)+\sum_{i=1}^{N}\alpha_{i} L(w,b,α)=21∥w∥2−i=1∑Nαiyi(w∙xi+b)+i=1∑Nαi原问题的对偶问题是极大极小问题: max α min w , b L ( w , b , α ) \max\limits_{\alpha}\min\limits_{w,b}L(w,b,\alpha) αmaxw,bminL(w,b,α)(1)先来求极小问题: min w , b L ( w , b , α ) \min\limits_{w,b}L(w,b,\alpha) w,bminL(w,b,α)。此时对 w , b w,b w,b求偏导数,可以得到: { w − ∑ i = 1 N α i y i x i = 0 ∑ i = 1 N α i y i = 0 \begin{cases} w-\sum_{i=1}^{N}\alpha_{i}y_{i}x_{i}=0\\ \sum_{i=1}^{N}\alpha_{i}y_{i}=0 \end{cases} {w−∑i=1Nαiyixi=0∑i=1Nαiyi=0将上述两个式子带入 L ( w , b , α ) L(w,b,\alpha) L(w,b,α)里,得到 L ( w , b , α ) = − 1 2 ∑ i = 1 N ∑ j = 1 N α i α j y i y j x i ⋅ x j + ∑ i = 1 N α i L(w,b,\alpha)=-\frac{1}{2}\sum_{i=1}^{N}\sum_{j=1}^{N}\alpha_{i}\alpha_{j}y_{i}y_{j}x_{i}\cdot x_{j}+\sum_{i=1}^{N}\alpha_{i} L(w,b,α)=−21i=1∑Nj=1∑Nαiαjyiyjxi⋅xj+i=1∑Nαi(2)再求 min α L ( w , b , α ) \min\limits_{\alpha}L(w,b,\alpha) αminL(w,b,α)对 α \alpha α的极大,此时 { max α − 1 2 ∑ i = 1 N ∑ j = 1 N α i α j y i y j x i ⋅ x j + ∑ i = 1 N α i s . t ∑ i = 1 N α i y i = 0 α i ≥ 0 , i = 1 , 2 , … , N \begin{cases}\max\limits_{\alpha} & -\frac{1}{2}\sum_{i=1}^{N}\sum_{j=1}^{N}\alpha_{i}\alpha_{j}y_{i}y_{j}x_{i}\cdot x_{j}+\sum_{i=1}^{N}\alpha_{i}\\ s.t & \sum_{i=1}^{N}\alpha_{i}y_{i}=0\\ & \alpha_{i}\geq0,i=1,2,\dots,N \end{cases} ⎩⎪⎨⎪⎧αmaxs.t−21∑i=1N∑j=1Nαiαjyiyjxi⋅xj+∑i=1Nαi∑i=1Nαiyi=0αi≥0,i=1,2,…,N再将此公式从求极大值转换成求极小值,如下: { min α 1 2 ∑ i = 1 N ∑ j = 1 N α i α j y i y j ( x i ⋅ x j ) − ∑ i = 1 N α i s . t ∑ i = 1 N α i y i = 0 α i ≥ 0 , i = 1 , 2 , … , N \begin{cases} \min\limits_{\alpha}& \frac{1}{2}\sum_{i=1}^{N}\sum_{j=1}^{N}\alpha_{i}\alpha_{j}y_{i}y_{j}(x_{i}\cdot x_{j})-\sum_{i=1}^{N}\alpha_{i}\\ s.t &\sum_{i=1}^{N}\alpha_{i}y_{i}=0\\ &\alpha_{i}\geq0,i=1,2,\dots,N \end{cases} ⎩⎪⎨⎪⎧αmins.t21∑i=1N∑j=1Nαiαjyiyj(xi⋅xj)−∑i=1Nαi∑i=1Nαiyi=0αi≥0,i=1,2,…,N假设上述最优化问题的解为 α ∗ = ( α 1 ∗ , α 2 ∗ , … , α N ∗ ) \alpha^{*}=(\alpha_{1}^{*},\alpha_{2}^{*},\dots,\alpha_{N}^{*}) α∗=(α1∗,α2∗,…,αN∗),在 a ∗ a_{*} a∗中比存在一个下标 j j j,使 a j ∗ > 0 a_{j}^{*}>0 aj∗>0。此时最原始问题的解 w ∗ , b ∗ w^{*},b^{*} w∗,b∗为: w ∗ = ∑ i = 1 N a i y i x i w^{*}=\sum_{i=1}^{N}a_{i}y_{i}x_{i} w∗=i=1∑Naiyixi b ∗ = y j − ∑ i = 1 N a i y i ( x i ∗ x j ) b^{*}=y_{j}-\sum_{i=1}^{N}a_{i}y_{i}(x_{i}*x_{j}) b∗=yj−i=1∑Naiyi(xi∗xj) w ∗ , b ∗ w^{*},b^{*} w∗,b∗确定之后,支持向量机的超平面为: w ∗ ∙ x + b ∗ = 0 w^{*}\bullet x+b^{*}=0 w∗∙x+b∗=0则决策函数为: f ( x ) = s i g n ( w ∗ ∙ x + b ∗ ) f(x)=sign(w^{*}\bullet x+b^{*}) f(x)=sign(w∗∙x+b∗)
1.3 支持向量
在线性可分的情况下,训练数据集的样本点与分离超平面距离最近的样本点的实例称为支持向量。支持向量是使约束条件(原始的目标函数中的约束条件)等号成立的点,也就是
α
∗
\alpha^{*}
α∗中所有不为0的分量所对应的样本。
在决定分离超平面时只有支持向量起作用,而其他实例点并不其作用。如果移除支持向量将改变所求的解;但是如果在间隔边界以外移除其他实例,则解是不会变的。支持向量的个数一般很少,所以支持向量机是由很少的“重要的”训练样本确定的。
2 线性支持向量机
2.1 目标公式及化简
线性可分问题的支持向量机学习方法,对线性不可分训练数据是不适用的,因为这时不等式约束条件并不能都成立。为了解决这个问题,可以对每个样本点
(
x
i
,
y
i
)
(x_{i},y_{i})
(xi,yi)引进一个松弛变量
ξ
i
≥
0
\xi_{i}\geq0
ξi≥0,使函数间隔加上松弛变量
≥
1
\geq1
≥1(软间隔最大化)。同时,对每个松弛变量引入一个代价。此时,支持向量机的目标函数为:
{
min
w
,
b
,
ξ
1
2
∥
w
∥
2
+
C
∑
i
=
1
N
ξ
i
s
.
t
y
i
(
w
∗
x
i
+
b
)
≥
1
−
ξ
i
,
i
=
1
,
2
,
…
,
N
ξ
i
≥
0
,
i
=
1
,
2
,
…
,
N
\begin{cases}\min\limits_{w,b,\xi} & \frac{1}{2}\|w\|^{2}+C\sum_{i=1}^{N}\xi_{i}\\ s.t & y_{i}(w*x_{i}+b)\geq 1-\xi_{i},i=1,2,\dots,N\\ & \xi_{i}\geq0,i=1,2,\dots,N \end{cases}
⎩⎪⎪⎨⎪⎪⎧w,b,ξmins.t21∥w∥2+C∑i=1Nξiyi(w∗xi+b)≥1−ξi,i=1,2,…,Nξi≥0,i=1,2,…,N其中
C
>
0
C>0
C>0称为惩罚参数。
C
C
C值大时对误分类的惩罚增大,
C
C
C值小时对误分类的惩罚减小。经过一系列变换后,其最终的目标表达式为:
{
min
α
1
2
∑
i
=
1
N
∑
j
=
1
N
α
i
α
j
y
i
y
j
(
x
i
⋅
x
j
)
−
∑
i
=
1
N
α
i
s
.
t
∑
i
=
1
N
α
i
y
i
=
0
0
≤
α
i
≤
C
,
i
=
1
,
2
,
…
,
N
\begin{cases} \min\limits_{\alpha}& \frac{1}{2}\sum_{i=1}^{N}\sum_{j=1}^{N}\alpha_{i}\alpha_{j}y_{i}y_{j}(x_{i}\cdot x_{j})-\sum_{i=1}^{N}\alpha_{i}\\ s.t &\sum_{i=1}^{N}\alpha_{i}y_{i}=0\\ & 0\leq\alpha_{i}\leq C,i=1,2,\dots,N \end{cases}
⎩⎪⎨⎪⎧αmins.t21∑i=1N∑j=1Nαiαjyiyj(xi⋅xj)−∑i=1Nαi∑i=1Nαiyi=00≤αi≤C,i=1,2,…,N此时
w
∗
,
b
∗
w^{*},b^{*}
w∗,b∗的求解公式与线性可分支持向量机相同。
在这种情况下,支持向量或者在间隔边界上,或者在间隔边界与分离超平面之间,或者在分离超平面误分的一侧。
2.2 合叶损失函数
线性支持向量机学习还有另一种解释,就是最小化如下目标函数: ∑ i = 1 N [ 1 − y i ( w ∙ x I + b ) ] + + λ ∥ w ∥ 2 \sum_{i=1}^{N}[1-y_{i}(w\bullet x_{I}+b)]_{+}+\lambda\|w\|^{2} i=1∑N[1−yi(w∙xI+b)]++λ∥w∥2目标函数第一项 L ( y ( w ∙ x + b ) ) = [ 1 − y ( w ∙ x + b ) ] + L(y(w\bullet x+b))=[1-y(w\bullet x+b)]_{+} L(y(w∙x+b))=[1−y(w∙x+b)]+为合页损失函数。下标 + + +表示以下取正值的函数。 [ z ] + = { z , z > 0 0 , z ≤ 0 [z]_{+}=\begin{cases}z,&z>0\\ 0,&z\leq0 \end{cases} [z]+={z,0,z>0z≤0
3 非线性支持向量机
3.1 核函数
设
X
X
X是输入空间,又
H
H
H为特征空间。如果存在一个从
X
X
X到
H
H
H的映射:
ϕ
(
x
)
:
X
→
H
\phi(x):X\rightarrow H
ϕ(x):X→H使得对所有
x
,
z
∈
X
x,z\in X
x,z∈X,函数
K
(
x
,
z
)
=
ϕ
(
x
)
∙
ϕ
(
z
)
K(x,z)=\phi(x)\bullet\phi(z)
K(x,z)=ϕ(x)∙ϕ(z)则称
K
(
x
,
z
)
K(x,z)
K(x,z)为核函数,
ϕ
(
x
)
\phi(x)
ϕ(x)为映射函数,式中
ϕ
(
x
)
∙
ϕ
(
z
)
\phi(x)\bullet\phi(z)
ϕ(x)∙ϕ(z)为
ϕ
(
x
)
\phi(x)
ϕ(x)和
ϕ
(
z
)
\phi(z)
ϕ(z)的内积。常用的核函数主要有以下几种:
(1) 多项式核函数:
K
(
x
,
z
)
=
(
x
∙
z
+
1
)
p
K(x,z)=(x\bullet z+1)^{p}
K(x,z)=(x∙z+1)p
(2) 高斯核函数:
K
(
x
,
z
)
=
e
x
p
(
−
∥
x
−
z
∥
2
2
σ
2
)
K(x,z)=exp(-\frac{\|x-z\|^{2}}{2\sigma^{2}})
K(x,z)=exp(−2σ2∥x−z∥2)
3.2 非线性支持向量机
非线性问题通常不好求解,一般所采取的方法是进心一个非线性变换,将非线性问题变换为线性问题,通过解变换后的线性问题的方法求解原来的非线性问题。这就需要用到核函数了。
在核函数
K
(
x
,
z
)
K(x,z)
K(x,z)给定的情况下,学习是隐式地在特征空间中进行的,不需要显示地定义特征空间和映射函数。此时,非线性支持向量机对应的最优化问题为:
{
min
α
1
2
∑
i
=
1
N
∑
j
=
1
N
α
i
α
j
y
i
y
j
K
(
x
i
,
x
j
)
−
∑
i
=
1
N
α
i
s
.
t
.
∑
i
=
1
N
α
i
y
i
=
0
0
≤
α
i
≤
C
,
i
=
1
,
2
,
…
,
N
\begin{cases}\min\limits_{\alpha}& \frac{1}{2}\sum_{i=1}^{N}\sum_{j=1}^{N}\alpha_{i}\alpha_{j}y_{i}y_{j}K(x_{i},x_{j})-\sum_{i=1}^{N}\alpha_{i}\\s.t.&\sum_{i=1}^{N}\alpha_{i}y_{i}=0\\&0\leq\alpha_{i}\leq C,i=1,2,\dots,N\end{cases}
⎩⎪⎨⎪⎧αmins.t.21∑i=1N∑j=1NαiαjyiyjK(xi,xj)−∑i=1Nαi∑i=1Nαiyi=00≤αi≤C,i=1,2,…,N最终的决策函数为:
f
(
x
)
=
s
i
g
n
(
∑
i
=
1
N
α
i
∗
y
i
K
(
x
,
x
i
)
+
b
∗
)
f(x)=sign(\sum_{i=1}^{N}\alpha_{i}^{*}y_{i}K(x,x_{i})+b^{*})
f(x)=sign(i=1∑Nαi∗yiK(x,xi)+b∗)
4 实现
Sklearn包中提供了支持向量机算法的类SVC和SVR,现以SVC为例对其主要参数进行说明。

- C: 正则化系数。必须大于0
- kernel:{‘linear’, ‘poly’, ‘rbf’, ‘sigmoid’, ‘precomputed’}。
- degree: 当kernel='ploy’时可用。
- gamma:{‘scale’, ‘auto’} or float, default=’scale’。当kernel为‘rbf’, ‘poly’ 或‘sigmoid’时可用。
- coef0: 当kernel为‘poly’ 或 ‘sigmoid’时,可用。
- max_iter:最大迭代次数。
# 加入归一化对比是为了验证归一化会对SVM的结果产生影响
import pandas as pd
import numpy as np
from sklearn.datasets import make_classification
from sklearn.svm import SVC
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
X,y=make_classification(n_samples=500,n_features=3,n_redundant=0,
n_informative=2,random_state=0)
#归一化
X=StandardScaler().fit_transform(X)
X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.2,
random_state=0)
X_train_new=X_train.copy()
X_train_new[:,1]=X_train_new[:,1]*5+1000
X_test_new=X_test.copy()
X_test_new[:,1]=X_test_new[:,1]*5+1000
svc=SVC()
svc.fit(X_train,y_train)
y_pred_test=svc.predict(X_test)
y_pred_train=svc.predict(X_train)
svc.fit(X_train_new,y_train)
y_pred_test_1=svc.predict(X_test_new)
y_pred_train_1=svc.predict(X_train_new)
#归一化前的准确率
train_acc=accuracy_score(y_train, y_pred_train_1)
test_acc=accuracy_score(y_test,y_pred_test_1)
print("归一化前训练集的准确率为:{:.3f},测试集的准确率为:{:.3f}"\
.format(train_acc,test_acc))
#归一化前的准确率
train_acc=accuracy_score(y_train, y_pred_train)
test_acc=accuracy_score(y_test,y_pred_test)
print("归一化后训练集的准确率为:{:.3f},测试集的准确率为:{:.3f}"\
.format(train_acc,test_acc))
实验结果如下:
归一化前训练集的准确率为:0.512,测试集的准确率为:0.460
归一化后训练集的准确率为:0.895,测试集的准确率为:0.780
参考资料
- 《统计学习方法》

被折叠的 条评论
为什么被折叠?



