支持向量机
(一) SVM简介
支持向量机(Support Vector Machine,SVM)是一个广泛应于在工业界和学术界的分类算法。与逻辑回归和神经网络相比,它在学习非线性复杂方程上提供了一种更加清晰、更加有效的思路。
为了描述支持向量机,我们先从逻辑回归开始讲起,再一点一点修正得到最后的支持向量机。
1.1 从逻辑回归到SVM
在逻辑回归中,我们已经熟悉了如下所示的假设函数 h θ ( x ) h_θ(x) hθ(x)和逻辑函数曲线:
对于逻辑回归的假设函数
h
θ
(
x
)
h_\theta(x)
hθ(x) :
当 y = 1 ,我们希望
h
θ
(
x
)
≈
1
h_\theta(x)≈1
hθ(x)≈1 ,即要求
θ
T
x
≫
0
\theta^Tx≫0
θTx≫0 (远大于)
当 y = 0 ,我们希望
h
θ
(
x
)
≈
0
h_\theta(x)≈0
hθ(x)≈0 ,即要求
θ
T
x
≪
0
\theta^Tx≪0
θTx≪0 (远小于)
LR中,单个样本的代价可以表示为:
C o s t = − y l o g ( h θ ( x ) ) − ( 1 − y ) l o g ( 1 − h θ ( x ) ) Cost=−ylog(hθ(x))−(1−y)log(1−hθ(x)) Cost=−ylog(hθ(x))−(1−y)log(1−hθ(x))
= − y l o g 1 1 + e − θ T X − ( 1 − y ) l o g ( 1 − 1 1 + e − θ T X ) =−ylog\frac{1}{1+e^{−θTX}} −(1−y)log(1-\frac{1}{1+e^{−θTX}}) =−ylog1+e−θTX1−(1−y)log(1−1+e−θTX1)
(1) 如果 y=1,上式中只有第一项起作用,第二项为 0。此时,画出函数图像:
-如上,当 y=1, C o s t = − log 1 1 + e − θ T X Cost =-\log \frac{1}{1+e^{-\theta^TX}} Cost=−log1+e−θTX1 ,此时为了使代价最小,则应尽可能使 z = θ T X z=θ^TX z=θTX 较大:
在SVM中这种情况可以用 两条线段 作为新的代价函数 c o s t 1 ( z ) cost_1(z) cost1(z) :
红色折线表示新的代价函数。
(2) 如果 y=0,上式中只有第二项起作用,第一项为 0,此时代价随 z的变化曲线如下图所示:
- 当 y = 0 , C o s t = − log ( 1 − 1 1 + e − θ T X ) Cost =-\log(1-\frac{1}{1+e^{-\theta^TX}}) Cost=−log(1−1+e−θTX1),为了使代价最小,应尽可能使 z = θ T X z=θ^TX z=θTX 较小:
在SVM中这种情况可以用 两条线段 作为新的代价函数
c
o
s
t
2
(
z
)
cost_2(z)
cost2(z):
红色折线表示新的代价函数。
接下来就通过 c o s t 1 ( z ) , c o s t 0 ( z ) cost_1(z) ,cost_0(z) cost1(z),cost0(z)构建支持向量机。
1.2 SVM的优化目标
Support Vector Machines(SVMs)支持向量机是一种非常强大的算法,在学习复杂的非线性方程时提供了一种更为清晰,更加强大的方式。我们首先从优化目标开始一步一步认识SVMs,首先从逻辑回归的优化目标开始:
对于逻辑回归,优化目标(代价函数)为:
m i n θ J ( θ ) = m i n θ [ 1 m ∑ i = 1 m [ y ( i ) ( − l o g h θ ( x ( i ) ) ) + ( 1 − y ( i ) ) ( − l o g ( 1 − h θ ( x ( i ) ) ) ) ] + λ 2 m ∑ j = 1 n θ j 2 ] ] \underset{θ}{min}J(θ)=\underset{θ}{min}[\frac{1}{m} \sum_{i=1}^{m} [y^{(i)}(−logh_{θ}(x^{(i)}))+(1−y^{(i)})(−log(1−h_{θ}(x^{(i)})))]+\frac{λ}{2m} \sum_{j=1}^{n} θ_{j}^{2}]] θminJ(θ)=θmin[m1i=1∑m[y(i)(−loghθ(x(i)))+(1−y(i))(−log(1−hθ(x(i))))]+2mλj=1∑nθj2]]
将逻辑回归的优化目标改成SVM的优化目标,有以下三步:
- 将
c
o
s
t
1
(
z
)
cost_1(z)
cost1(z) 、
c
o
s
t
0
(
z
)
cost_0(z)
cost0(z)替换进
J
(
θ
)
J(\theta)
J(θ):
m i n θ J ( θ ) = m i n θ [ 1 m ∑ i = 1 m [ y ( i ) c o s t 1 ( θ T x ( i ) ) + ( 1 − y ( i ) ) c o s t 0 ( θ T x ( i ) ] + λ 2 m ∑ j = 1 n θ j 2 ] \underset{θ}{min}J(θ)=\underset{θ}{min}[\frac{1}{m} \sum_{i=1}^{m} [y^{(i)}cost_{1}(θ^{T}x_{(i)})+(1−y^{(i)})cost_{0}(θ^{T}x_{(i)}]+\frac{λ}{2m} \sum_{j=1}^{n} θ_{j}^{2}] θminJ(θ)=θmin[m1i=1∑m[y(i)cost1(θTx(i))+(1−y(i))cost0(θTx(i)]+2mλj=1∑nθj2] - 由于无论是否有 1 m \frac{1}{m} m1都不会影响最小化的结果,在使用SVM时,我们可以忽略 1 m \frac{1}{m} m1。
- 逻辑回归中带正则化的代价函数可以用
A
+
λ
B
A+\lambda B
A+λB表示( A 表示训练样本的代价, B表示正则化项),在SVM中改为
C A + B CA+B CA+B 。
由此得到 SVM 的优化目标为:
m
i
n
θ
[
C
1
m
∑
i
=
1
m
[
y
(
i
)
c
o
s
t
1
(
θ
T
x
(
i
)
)
+
(
1
−
y
(
i
)
)
c
o
s
t
0
(
θ
T
x
(
i
)
]
+
1
2
∑
j
=
1
n
θ
j
2
]
\underset{θ}{min}[C\frac{1}{m} \sum_{i=1}^{m} [y^{(i)}cost_{1}(θ^{T}x_{(i)})+(1−y^{(i)})cost_{0}(θ^{T}x_{(i)}]+\frac{1}{2} \sum_{j=1}^{n} θ_{j}^{2}]
θmin[Cm1i=1∑m[y(i)cost1(θTx(i))+(1−y(i))cost0(θTx(i)]+21j=1∑nθj2]
画出 c o s t 0 ( z ) cost_0(z) cost0(z) 和 c o s t 1 ( z ) cost_1(z) cost1(z) :
-
当 y = 1 ,我们希望 h θ ( x ) = 1 h_\theta(x)=1 hθ(x)=1 ,即要求 z = θ T x ≥ 1 z=\theta^Tx≥1 z=θTx≥1 , c o s t 1 ( z ) = 0 cost_1(z)=0 cost1(z)=0
-
当 y = 0 ,我们希望 h θ ( x ) = 0 h_\theta(x)=0 hθ(x)=0 , z = θ T x ≤ − 1 z=\theta^Tx≤-1 z=θTx≤−1 , c o s t 0 ( z ) = 0 cost_0(z)=0 cost0(z)=0
(二) 最大间距分类器
2.1 决策面与分类间隔
有时,人们会将支持向量机称为最大间距分类器,这一部分会给大家解释其中原因,这样我们对SVM的假设得到一个更直观的理解。
以二维空间为例,在逻辑回归中,决策面(决策边界)是一条将正负样本分开的直线,根据参数的不同可以有不同的分类效果:
而在SVM中,除了决策边界(decision boundary),还要引入一个新名词——间隔(margin):
如上图所示,A和B两条直线对应两个决策面,在保证决策面方向不变且不会出现错分样本的情况下移动决策面,会在原来的决策面两侧找到两个极限位置(越过该位置就会产生错分现象),如虚线所示。虚线的位置由决策面的方向和距离原决策面最近的几个样本的位置决定。而这两条平行虚线正中间的分界线就是在保持当前决策面方向不变的前提下的最优决策面。
两条虚线之间的垂直距离就是这个最优决策面对应的分类间隔
显然每一个可能把数据集正确分开的方向都有一个最优决策面(有些方向无论如何移动决策面的位置也不可能将两类样本完全分开),而不同方向的最优决策面的分类间隔通常是不同的,那个具有“最大间隔”的决策面就是SVM要寻找的最优解。而这个真正的最优解对应的两侧虚线所穿过的样本点,就是SVM中的支持样本点,称为"支持向量" (support vector)。两个异类支持向量到超平面的距离之和称为“间隔” (margin)。
2.2 约束条件
样本标签
y
i
∈
{
−
1
,
1
}
y_i∈\{-1,1\}
yi∈{−1,1}
(1) 为什么不用逻辑回归的标签0和1?其实 y标注为-1和1只是为了下述公式方便表达,证明如下:
-
决策面(高维空间称为超平面): w T x + b = 0 w^Tx+b=0 wTx+b=0 (注: b = w 0 b=w_0 b=w0 ,其实就是之前文章中的 X θ = 0 X\theta=0 Xθ=0)
-
满足 w T x + b = 0 w^Tx+b=0 wTx+b=0 的 x x x 对应超平面上的点
-
满足 w T x + b ≥ 1 w T x + b ≥ 1 w^Tx+b≥1 wTx+b≥1 wTx+b≥1wTx+b≥1 的 x x x对应上方虚线之上点,换句话说, ∀ y i = 1 \forall y_i=1 ∀yi=1,有 w T x + b ≥ 1 w^Tx+b≥1 wTx+b≥1
-
满足 w T x + b ≤ − 1 w T x + b ≤ − 1 w^Tx+b≤-1 wTx+b≤−1 wTx+b≤−1wTx+b≤−1 的 x x x对应下方虚线之下点,换句话说, ∀ y i = − 1 \forall y_i=-1 ∀yi=−1,有
w T x + b ≤ 1 w^Tx+b≤1 wTx+b≤1
将上述条件变形为:(注:这里用下标 i i i表示第个 i i i样本点,之前是用上标表示) y i ( w T x i + b ) ≥ 1 , i = 1 , 2 , . . . , m y_i(w^Tx_i+b)≥1\ ,\ \ i=1,2,...,m yi(wTxi+b)≥1 , i=1,2,...,m 上式就是 SVM的约束条件,也就是说,我们要找的最优决策面一定要满足上式条件,现在再回头看 #1.2节中的 c o s t 0 ( z ) cost_0(z) cost0(z)和 c o s t 1 ( z ) cost_1(z) cost1(z),是不是清楚了一些呢。
(2) 为什么经过 支持向量 的 虚线的方程就是 w T x + b = 1 w^Tx+b=1 wTx+b=1 和 w T x + b = − 1 w^Tx+b=-1 wTx+b=−1 ,以及为什么标签取{-1,1}证明如下:
- 已知点 ( x 0 , y 0 ) (x_0,y_0) (x0,y0)到直线 A x + B y + C = 0 Ax+By+C=0 Ax+By+C=0的距离为: d = ∣ A x 0 + B y 0 + C A 2 + B 2 ∣ d=\left|\displaystyle\frac{A x_{0}+B y_{0}+C}{\sqrt{A^{2}+B^{2}}}\right| d=∣∣∣∣A2+B2Ax0+By0+C∣∣∣∣
- 对于支持向量对应的样本点到超平面的距离,即间隔为:
d = ∣ ω T x + b ∣ ∥ ω ∥ d=\frac{\left|\displaystyle\boldsymbol{\omega}^{T} \boldsymbol{x}+b\right|}{\|\displaystyle\boldsymbol{\omega}\|} d=∥ω∥∣∣∣ωTx+b∣∣∣
表示向量范数 - 假设决策面正好处于间隔区域的中轴线上,并且相应的支持向量对应的样本点到决策面的距离为 d d d,就会满足下面的方程:
- 上式的解释就是,对于所有分类标签为1和-1样本点,它们到直线的距离都大于等于
d
d
d
(支持向量上的样本点到超平面的距离)。公式两边都除以 d d d,就可以得到:
- 因为
∣
∣
w
∣
∣
||w||
∣∣w∣∣和
d
d
d都是标量。所以对于直线方程
ω
T
x
+
b
=
0
ω
T
x
+
b
=
0
\boldsymbol{\omega}^{T} \boldsymbol{x}+b=0 ωTx+b=0
ωTx+b=0ωTx+b=0 和
ω
d
T
x
+
b
d
=
0
\boldsymbol{\omega}_d^{T} \boldsymbol{x}+b_d=0
ωdTx+bd=0 其实描述的是同一条直线(举例:
2
x
1
+
4
x
2
+
2
=
0
2x_1+4x_2+2=0
2x1+4x2+2=0 和
x 1 + 2 x 2 + 1 = 0 x_1+2x_2+1=0 x1+2x2+1=0 是同一条直线),因此我们令 ω = ω d , b = b d \omega=\omega_d,\ b=b_d ω=ωd, b=bd ,更新后得到:
上述方程即给出了SVM最优化问题的约束条件。这时候,可能有人会问了,为什么标记为1和-1呢?因为这样标记方便我们将上述方程变成如下形式:
y
i
(
w
T
x
i
+
b
)
≥
1
,
i
=
1
,
2
,
.
.
.
,
m
y_{i}(w^{T}x_{i}+b)≥1 , i=1,2,...,m
yi(wTxi+b)≥1,i=1,2,...,m
2.3 约束优化目标
具有“最大间隔”的决策面就是SVM要寻找的最优解。 看 #2.1节最后几段话)
因此,简单来说,SVM的优化目标就是使下图两条虚线的 “间隔最大化”:
根据平行直线的距离公式,我们很容易得到间隔,用
γ
\gamma
γ 表示为:
γ
=
1
−
(
−
1
)
∥
ω
∥
=
2
∥
ω
∥
γ=\frac{1−(−1)}{∥ω∥} =\frac{2}{∥ω∥}
γ=∥ω∥1−(−1)=∥ω∥2
到这里,我们就可以得到SVM的优化目标:(s.t.即"Subject to",表示受限于)
m a x 2 ∥ ω ∥ w , b s . t . y i ( w T x i + b ) ≥ 1 , i = 1 , 2 , … , m max\underset{w,b}\frac{2}{∥ω∥} \underset{s.t. y_{i}(w^{T}xi+b)≥1,i=1,2,…,m}{} maxw,b∥ω∥2s.t.yi(wTxi+b)≥1,i=1,2,…,m
最大化 2 ∥ w ∥ \frac{2}{\|w\|} ∥w∥2 等价于最小化 ∥ w ∥ 2 {\|w\|}^2 ∥w∥2,于是上式也可以表示为:
m a x 1 2 w , b ∥ ω ∥ 2 s . t . y i ( w T x i + b ) ≥ 1 , i = 1 , 2 , … , m max\underset{w,b}\frac{1}{2}∥ω∥^{2} \underset{s.t. y_{i}(w^{T}xi+b)≥1,i=1,2,…,m}{} maxw,b21∥ω∥2s.t.yi(wTxi+b)≥1,i=1,2,…,m
至此,我们已经得到SVM的基本数学模型,即一个典型的不等式约束条件下的二次型函数优化问题。
现在,再回过头看吴恩达教授讲的 #1.2节中 SVM的优化目标:
m i n θ [ C 1 m ∑ i = 1 m [ y ( i ) c o s t 1 ( θ T x ( i ) ) + ( 1 − y ( i ) ) c o s t 0 ( θ T x ( i ) ] + 1 2 ∑ j = 1 n θ j 2 ] \underset{θ}{min}[C\frac{1}{m} \sum_{i=1}^{m} [y^{(i)}cost_{1}(θ^{T}x_{(i)})+(1−y^{(i)})cost_{0}(θ^{T}x_{(i)}]+\frac{1}{2} \sum_{j=1}^{n} θ_{j}^{2}] θmin[Cm1i=1∑m[y(i)cost1(θTx(i))+(1−y(i))cost0(θTx(i)]+21j=1∑nθj2]
(三) SVM求解
3.1 拉格朗日乘子法三维理解
m
i
n
f
(
x
,
y
)
=
x
y
minf(x,y)=xy
minf(x,y)=xy
(
椭
圆
)
s
.
t
.
h
i
(
x
,
y
)
=
x
2
8
+
y
2
2
−
1
=
0
(椭圆)s.t. h_{i(x,y)}=\frac{x^{2}}{8} +\frac{y^{2}}{2} −1=0
(椭圆)s.t.hi(x,y)=8x2+2y2−1=0
下面是几何解释,
f
(
x
,
y
)
=
x
y
f(x,y)=x y
f(x,y)=xy的等高线图在最下面, 也就是双曲线
x
y
=
c
x
y
=
c
x y=c xy=c
xy=cxy=c (c是相应的函数值), 椭圆
x
2
/
8
+
y
2
/
2
=
1
x^2/8+y^2/2=1
x2/8+y2/2=1 在
f
f
f 函数曲面上为蓝色曲线。
从上图可知双曲线离开原点越远, f 的绝对值越大,需要在约束条件下:椭圆
x
2
/
8
+
y
2
/
2
=
1
x^2/8+y^2/2=1
x2/8+y2/2=1上使
f
(
x
,
y
)
f(x,y)
f(x,y)取极值点,也就是与椭圆相切的双曲线会距离原点最远。在这四个切点中,双曲线的法线也是椭圆的法线。观察下图动画, 可以看到黑色
▽
f
▽f
▽f是
▽
g
▽g
▽g 的数值倍数,最大值处两个梯度向量方向相同, 最小值处方向相反。
3.2 线性SVM求解
在第一部分得到SVM的基本数学模型(基本型)后,我们现在要求解的就是一个最优化问题。
m
a
x
1
2
w
,
b
∥
ω
∥
2
s
.
t
.
y
i
(
w
T
x
i
+
b
)
≥
1
,
i
=
1
,
2
,
…
,
m
max\underset{w,b}\frac{1}{2}∥ω∥^{2} \underset{s.t. y_{i}(w^{T}xi+b)≥1,i=1,2,…,m}{}
maxw,b21∥ω∥2s.t.yi(wTxi+b)≥1,i=1,2,…,m
由于基本型的目标函数是二次的,且约束条件是线性的,这是一个 凸二次规划 问题。可以直接用现成的优化计算包求解,如scikit-learn等
二次规划:
-
目标函数和约束条件都为变量的线性函数,叫做------线性规划问题。
-
目标函数为变量的二次函数,约束条件为变量的线性函数,叫做------二次规划问题(即本问题)。
-
目标函数和约束条件都为非线性函数,叫做------非线性规划问题。
除了用现成的优化计算包,我们还可以用其他方法来解决SVM的优化问题。在此之前,我们先来看下优化问题有哪些类别以及用什么方法解决:
了解到这些,显然SVM的优化问题是属于第三类:有不等式约束的优化问题。用 拉格朗日乘数法 和 KKT条件 可以解决此类问题。
深究SVM中的数学原理是件很痛苦的事,上述数学原理了解即可,主要是为了SVM的推导做铺垫。
总结将 原始问题 转化为 拉格朗日对偶问题 的步骤如下:
对偶问题求解:
将原始问题转化为拉格朗日对偶问题后:
问题转化为:
首先固定
α
\alpha
α ,使
L
(
w
,
b
,
α
)
\mathcal{L}(w, b, \alpha)
L(w,b,α) L关于
w
,
b
w,b
w,b 最小化。分别对w和b偏导数,令其等于0,即:
将求导结果带回
L
(
w
,
b
,
α
)
\mathcal{L}(w, b, \alpha)
L(w,b,α),得到\
此时的
L
(
w
,
b
,
α
)
\mathcal{L}(w, b, \alpha)
L(w,b,α)函数只含有一个变量,即
α
i
α_i
αi,因此
再对
α
\alpha
α 求
L
(
w
,
b
,
α
)
\mathcal{L}(w, b, \alpha)
L(w,b,α)最大,对偶问题可以进一步转化为:
现在我们的优化问题变成了如上的形式。对于这个问题,我们有更高效的优化算法,即 序列最小优化(Sequential Minimal Optimizaion-SMO)算法。我们通过这个优化算法能得到
α
α
α,再根据
α
α
α,我们就可以求解出
w
w
w 和
b
b
b,进而求得我们最初的目的:找到超平面,即"决策边界"。
解得
α
\alpha
α 后,即可求出
w
w
w 和
b
b
b,得到线性SVM的超平面:
上述过程均要满足KKT条件,即:
因此对于任意训练样本 ( x i , y i ) (x_i, y_i) (xi,yi) ,总有 α i = 0 \alpha_i=0 αi=0或 y i f ( x ) − 1 = 0 y_if(x)-1=0 yif(x)−1=0。
当
α
i
=
0
\alpha_i=0
αi=0时,
f
(
x
)
=
b
f(x)= b
f(x)=b,则该样本不会对
f
(
x
)
f(x)
f(x)产生影响;
当
y
i
f
(
x
)
−
1
=
0
y_if(x)-1=0
yif(x)−1=0,此时
α
i
≥
0
\alpha_i≥0
αi≥0,对应样本点落在最大间隔边界上,即为支持向量。同时这也是支持向量的一个重要性质:模 型训练完成后,大部分的训练样本不需要保留,最终的模型参数仅与支持向量有关。
(四) 非线性问题(核函数)
4.1 非线性问题
对于非线性的情况,SVM的处理方式就是通过一个非线性变换,将输入的低维特征映射到高维特征空间,将其变成在高维空间线性可分,并在这个高维空间中构造最优分类超平面,如下图:
线性可分的情况下,可知最终的超平面方程为:
f
(
x
)
=
w
T
x
+
b
=
∑
i
=
1
m
α
i
y
i
x
i
T
x
+
b
f(x)=w^{T}x+b=\sum_{i=1}^{m}α_{i}y_{i}x_{i}^{T}x+b
f(x)=wTx+b=i=1∑mαiyixiTx+b
内积表示:
f ( x ) = ∑ i = 1 m α i y i ⟨ x i , x ⟩ + b f(x)=\sum_{i=1}^{m}α_{i}y_{i}⟨x_{i},x⟩+b f(x)=i=1∑mαiyi⟨xi,x⟩+b
对于线性不可分,我们使用一个非线性映射,将数据映射到特征空间,在特征空间中使用线性学习器,分类函数变形如下: f ( x ) = ∑ i = 1 m α i y i ⟨ ϕ ( x i ) , ϕ ( x ) ⟩ + b f(x)=\sum_{i=1}^{m}α_{i}y_{i}⟨ϕ(xi),ϕ(x)⟩+b f(x)=i=1∑mαiyi⟨ϕ(xi),ϕ(x)⟩+b
其中 ϕ ϕ ϕ 表示从输入空间(X)到某个特征空间(F)的映射,这意味着建立非线性学习器分为两步:
-
首先使用一个非线性映射将数据变换到一个特征空间F;
-
然后在特征空间使用线性学习器进行分类。
由上式可知,我们的主要计算任务就是高维特征空间的内积 < ϕ ( x i ) , ϕ ( x ) > <ϕ(x_i),ϕ(x)> <ϕ(xi),ϕ(x)>
4.2 核技巧与核函数
假如在低维空间中存在某个函数 K K K,它恰好等于在高维空间中的内积,即
K ( x i , x ) = < ϕ ( x i ) , ϕ ( x ) > K(xi,x)= <ϕ(xi),ϕ(x)> K(xi,x)=<ϕ(xi),ϕ(x)>
那么SVM就不用计算复杂的非线性变换,而由这个函数 K ( x i , x ) K(x_i, x) K(xi,x)直接得到非线性变换的内积,大大简化了计算。这样的函数 K ( x i , x ) K(x_i, x) K(xi,x)就被称为核函数。
这种将内积替换成核函数的方式被称为 核技巧(kernel trick)。
例:
假设现在有两个二维空间中的数据点
x
=
(
x
1
,
x
2
)
x=(x1,x2)
x=(x1,x2)和
y
=
(
y
1
,
y
2
)
y=(y1,y2)
y=(y1,y2),考虑下面这个二元函数:
K
(
x
,
y
)
=
(
x
.
y
+
1
)
2
=
(
x
1
y
1
+
x
2
y
2
+
1
)
2
K(x,y)=(x.y+1)2=(x1y1+x2y2+1)2
K(x,y)=(x.y+1)2=(x1y1+x2y2+1)2
=
x
1
2
y
1
2
+
x
2
2
y
2
2
+
2
x
1
y
1
+
2
x
2
y
2
+
2
x
1
x
2
y
1
y
2
=x_{1}^{2}y_{1}^{2}+x_{2}^{2}y_{2}^{2}+2x_{1}y_{1}+2x_{2}y_{2}+2x_{1}x_{2}y_{1}y_{2}
=x12y12+x22y22+2x1y1+2x2y2+2x1x2y1y2
=
(
x
1
2
,
x
2
2
,
2
x
1
x
2
,
2
x
1
,
2
x
2
,
1
)
⋅
(
y
1
2
,
y
2
2
,
2
y
1
y
2
,
2
y
1
,
2
y
2
,
1
)
=(x_{1}^{2},x_{2}^{2},\sqrt{2}x_{1}x_{2},\sqrt{2}x_{1},\sqrt{2}x_{2},1)⋅(y_{1}^{2},y_{2}^{2},\sqrt{2}y_{1}y_{2},\sqrt{2}y_{1},\sqrt{2}y_{2},1)
=(x12,x22,2x1x2,2x1,2x2,1)⋅(y12,y22,2y1y2,2y1,2y2,1)
=
<
ϕ
(
x
)
,
ϕ
(
y
)
>
=<ϕ(x),ϕ(y)>
=<ϕ(x),ϕ(y)>
发现最后结果恰好是两个向量的内积,而且两个向量分别是二维空间数据点 x x x 和 y y y 在5维空间中的映射!想到刚才核函数的定义,我们很容易知道, K ( x , y ) K(x,y) K(x,y)就是一个核函数,这样大大简化了运算。
通过核技巧的转变,我们的超平面方程变为:
f
(
x
)
=
∑
i
=
1
m
α
i
y
i
K
(
x
i
,
x
)
+
b
f(x)=\sum_{i=1}^{m}α_{i}y_{i}K(x_{i},x)+b
f(x)=i=1∑mαiyiK(xi,x)+b
对偶问题变为:
4.3 核函数的选择
常用的核函数有很多,例如,线性核、多项式核、拉普拉斯核等等,一般我们使用径向基核函数(RBF)。
径向基核函数是SVM中常用的一个核函数。径向基核函数采用向量作为自变量的函数,能够基于向量举例运算输出一个标量。径向基核函数的高斯版本的公式如下:
其中,σ是用户自定义的用于确定到达率(reach)或者说函数值跌落到0的速度参数。
-
如果σ选得很大,模型复杂度越高,高次特征上的权重实际上衰减得非常快,所以实际上(数值上近似一下)相当于一个低维的子空间;
-
如果σ选得很小,则可以将任意的数据映射为线性可分——当然,这并不一定是好事,因为随之而来的可能是非常严重的过拟合问题。
总的来说,通过调控参数σ,高斯核实际上具有相当高的灵活性,也是使用最广泛的核函数之一。
(五) 作业
5.1 线性 SVM
观察惩罚项系数 C 对决策边界的影响 :
在理论部分,我们得到SVM的代价函数为:
其中C为误差项惩罚系数,C越大,容错率越低,越易过拟合:
import numpy as np
import scipy.io as sio
import matplotlib.pyplot as plt
data = sio.loadmat('D:/data/ex6data1.mat')
X,y = data['X'],data['y']
def plot_data():
plt.scatter(X[:,0],X[:,1],c = y.flatten(), cmap ='jet')
plt.xlabel('x1')
plt.ylabel('y1')
plot_data() # 绘制原始数据
处理效果:
由图可知,左上角的那个数据点为异常点(误差点)。
Scikit-learn ,kernel=‘linear’:简称 sklearn, 提供了很多机器学习的库,本次作业主要也是用它来解决SVM的问题:
from sklearn.svm import SVC
svc1 = SVC(C=1,kernel='linear') #实例化分类器,C为误差项惩罚系数,核函数选择线性核
svc1.fit(X,y.flatten()) #导入数据进行训练
>>> svc1.score(X,y.flatten()) #分类器的准确率
> 0.9803921568627451
# 绘制决策边界
def plot_boundary(model):
x_min,x_max = -0.5,4.5
y_min,y_max = 1.3,5
xx,yy = np.meshgrid(np.linspace(x_min,x_max,500),
np.linspace(y_min,y_max,500))
z = model.predict(np.c_[xx.flatten(),yy.flatten()])
zz = z.reshape(xx.shape)
plt.contour(xx,yy,zz)
plot_boundary(svc1)
plot_data()
C=1:
svc100 = SVC(C=100,kernel='linear')
svc100.fit(X,y.flatten())
>>>svc100.score(X,y.flatten())
> 1.0
#绘制决策边界
plot_boundary(svc100)
plot_data()
C=100:
结论: 误差项惩罚系数C越大,容错率越低,越易过拟合。
5.2 非线性 SVM
使用高斯核函数解决线性不可分问题,并观察 σ \sigma σ 取值对模型复杂度的影响。数据集:data/ex6data2.mat
高斯核函数公式:
data = sio.loadmat('D:/data/ex6data2.mat')
X,y = data['X'],data['y']
def plot_data():
plt.scatter(X[:,0],X[:,1],c = y.flatten(), cmap ='jet')
plt.xlabel('x1')
plt.ylabel('y1')
plot_data() # 绘制原始数据
显示:
Scikit-learn ,kernel=‘rbf’
σ=1 ,注意:sklearn中的 σ \sigma σ表示为gammer,高斯核表示为rbf
svc1 = SVC(C=1,kernel='rbf',gamma=1) #实例化分类器,C为误差项惩罚系数,核函数选择高斯核
svc1.fit(X,y.flatten()) #导入数据进行训练
>>> svc1.score(X,y.flatten()) #分类器的准确率
> 0.8088064889918888
# 绘制决策边界
def plot_boundary(model):
x_min,x_max = 0,1
y_min,y_max = 0.4,1
xx,yy = np.meshgrid(np.linspace(x_min,x_max,500),
np.linspace(y_min,y_max,500))
z = model.predict(np.c_[xx.flatten(),yy.flatten()])
zz = z.reshape(xx.shape)
plt.contour(xx,yy,zz)
plot_boundary(svc1)
plot_data()
效果:
- σ=50:
- σ=1000:
结论:
σ
\sigma
σ 值越大,模型复杂度越高,同时也越易过拟合
σ
\sigma
σ 值越小,模型复杂度越低,同时也越易欠拟合
5.3 寻找最优参数 C 和 σ \sigma σ
导入数据集:data/ex6data3.mat
mat = sio.loadmat('D:/data/ex6data3.mat')
X, y = mat['X'], mat['y'] # 训练集
Xval, yval = mat['Xval'], mat['yval'] # 验证集
def plot_data():
plt.scatter(X[:,0],X[:,1],c = y.flatten(), cmap ='jet')
plt.xlabel('x1')
plt.ylabel('y1')
plot_data() # 绘制原始数据
显示:
C 和 σ 的候选值:
# C 和 σ 的候选值
Cvalues = [3, 10, 30, 100,0.01, 0.03, 0.1, 0.3,1 ] #9
gammas = [1 ,3, 10, 30, 100,0.01, 0.03, 0.1, 0.3] #9
# 获取最佳准确率和最优参数
best_score = 0
best_params = (0,0)
for c in Cvalues:
for gamma in gammas:
svc = SVC(C=c,kernel='rbf',gamma=gamma)
svc.fit(X,y.flatten()) # 用训练集数据拟合模型
score = svc.score(Xval,yval.flatten()) # 用验证集数据进行评分
if score > best_score:
best_score = score
best_params = (c,gamma)
>>> print(best_score,best_params)
> 0.965 (3, 30)
注意:获取到的最优参数组合不只有一组,更改候选值的顺序,最佳参数组合及其对应的决策边界也会改变
svc2 = SVC(C=3,kernel='rbf',gamma=30)
def plot_boundary(model):
x_min,x_max = -0.6,0.4
y_min,y_max = -0.7,0.6
xx,yy = np.meshgrid(np.linspace(x_min,x_max,500),
np.linspace(y_min,y_max,500))
z = model.predict(np.c_[xx.flatten(),yy.flatten()])
zz = z.reshape(xx.shape)
plt.contour(xx,yy,zz)
plot_boundary(svc2)
plot_data()
结果:
5.4 垃圾邮件过滤
注:data/spamTrain.mat是对邮件进行预处理后(自然语言处理)获得的向量
# training data
data1 = sio.loadmat('data/spamTrain.mat')
X, y = data1['X'], data1['y']
# Testing data
data2 = sio.loadmat('data/spamTest.mat')
Xtest, ytest = data2['Xtest'], data2['ytest']
>>> X.shape,y.shape # 样本数为4000
> ((4000, 1899), (4000, 1))
>>> X # 每一行代表一个邮件样本,每个样本有1899个特征,特征为1表示在跟垃圾邮件有关的语义库中找到相关单词
> array([[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
...,
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 1, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0]], dtype=uint8)
>>> y # 每一行代表一个邮件样本,等于1表示为垃圾邮件
> array([[1],
[1],
[0],
...,
[1],
[0],
[0]], dtype=uint8)
# 候选的 C值
Cvalues = [3, 10, 30, 100,0.01, 0.03, 0.1, 0.3,1 ]
# 获取最佳准确率和最优参数
best_score = 0
best_param = 0
for c in Cvalues:
svc = SVC(C=c,kernel='linear')
svc.fit(X,y.flatten()) # 用训练集数据拟合模型
score= svc.score(Xtest,ytest.flatten()) # 用验证集数据进行评分
if score > best_score:
best_score = score
best_param = c
>>> print(best_score,best_param)
> 0.99 0.03
# 带入最佳参数
svc = SVC(0.03,kernel='linear')
svc.fit(X,y.flatten())
score_train= svc.score(X,y.flatten())
score_test= svc.score(Xtest,ytest.flatten())
>>> print(score_train,score_test)
> 0.99425 0.99