文章目录
0 概述
前面学习了使用logistic Regression和神经网络进行分类的方法,本周将将介绍一种在工业界和学术界运用十分广泛的分类算法—支持向量机(简称SVM)。
1. 课程大纲
2. 课程内容
2.1 从逻辑回归到SVM
在逻辑回归中,我们的预测函数为:
h
θ
(
x
)
=
1
1
+
e
−
θ
T
x
h_\theta(x)=\frac{1}{1+e^{-\theta^Tx}}
hθ(x)=1+e−θTx1
对于每一个样本 (x,y) 而言(注意是每一个),其代价函数为:
J
(
θ
)
=
−
(
y
log
h
θ
(
x
)
+
(
1
−
y
)
log
(
1
−
h
θ
(
(
x
)
)
)
=
−
y
log
1
1
+
e
−
θ
T
x
−
(
1
−
y
)
log
(
1
−
1
1
+
e
−
θ
T
x
)
\begin{aligned} J(\theta) &=-\left(y \log h_{\theta}(x)+(1-y) \log \left(1-h_{\theta}((x))\right)\right.\\ &=-y \log \frac{1}{1+e^{-\theta^{T} x}}-(1-y) \log \left(1-\frac{1}{1+e^{-\theta^{T} x}}\right) \end{aligned}
J(θ)=−(yloghθ(x)+(1−y)log(1−hθ((x)))=−ylog1+e−θTx1−(1−y)log(1−1+e−θTx1)
其中,
当 y=1 的时候,
J
(
θ
)
=
−
y
l
o
g
1
1
+
e
−
θ
T
x
J(\theta)=-ylog\frac{1}{1+e^{-\theta^Tx}}
J(θ)=−ylog1+e−θTx1 ,其代价函数的图像入左下图所示。
当 y=0 的时候,
J
(
θ
)
=
−
(
1
−
y
)
l
o
g
(
1
−
1
1
+
e
−
θ
T
x
)
J(\theta)=-(1-y)log(1-\frac{1}{1+e^{-\theta^Tx}})
J(θ)=−(1−y)log(1−1+e−θTx1) ,其代价函数的图像入右下图所示。
如图,
当 y=1 时,随着 z 取值变大,预测代价变小,因此,逻辑回归想要在面对正样本 y=1 时,获得足够高的预测精度,就希望
z
=
θ
T
x
≫
0
z=\theta^{T} x \gg 0
z=θTx≫0,从而使得
h
θ
(
x
)
h_\theta(x)
hθ(x) > 0.5,并不断趋近于1。
反之,希望
z
=
θ
T
x
≪
0
z=\theta^{T} x \ll 0
z=θTx≪0,从而使得
h
θ
(
x
)
h_\theta(x)
hθ(x) < 0.5,并不断趋近于0。
对于支持向量机,我们修改损失函数,使其成为粉色的折线,如下图所示:
当
y
=
1
y=1
y=1 的时候,定义
c
o
s
t
1
(
z
)
cost_1(z)
cost1(z),为了预测精度足够高,SVM 希望
θ
T
x
⩾
1
\theta^Tx\geqslant 1
θTx⩾1
当
y
=
0
y=0
y=0 的时候,定义
c
o
s
t
0
(
z
)
cost_0(z)
cost0(z),为了预测精度足够高,SVM 希望
θ
T
x
⩽
−
1
\theta^Tx \leqslant -1
θTx⩽−1
定义SVM的损失函数:
第一步,将逻辑回归的代价函数中的log损失函数替换为
c
o
s
t
0
(
z
)
cost_0(z)
cost0(z)和
c
o
s
t
1
(
z
)
cost_1(z)
cost1(z);。
J
(
θ
)
=
min
θ
1
m
[
∑
i
=
1
m
y
(
i
)
(
c
o
s
t
1
(
z
)
)
+
(
1
−
y
(
i
)
)
(
c
o
s
t
0
(
z
)
)
]
+
λ
2
m
∑
j
=
1
n
θ
j
2
J(\theta)=\min _{\theta} \frac{1}{m}\left[\sum_{i=1}^{m} y^{(i)}\left(cost_1(z)\right)+\left(1-y^{(i)}\right)\left(cost_0(z))\right]+\frac{\lambda}{2 m} \sum_{j=1}^{n} \theta_{j}^{2}\right.
J(θ)=minθm1[∑i=1my(i)(cost1(z))+(1−y(i))(cost0(z))]+2mλ∑j=1nθj2
第二步,去掉m,因为他不会影响最后的优化求解。
J
(
θ
)
=
min
θ
[
∑
i
=
1
m
y
(
i
)
(
c
o
s
t
1
(
z
)
)
+
(
1
−
y
(
i
)
)
(
c
o
s
t
0
(
z
)
)
]
+
λ
2
∑
j
=
1
n
θ
j
2
J(\theta)=\min _{\theta}\left[\sum_{i=1}^{m} y^{(i)}\left(cost_1(z)\right)+\left(1-y^{(i)}\right)\left(cost_0(z))\right]+\frac{\lambda}{2} \sum_{j=1}^{n} \theta_{j}^{2}\right.
J(θ)=minθ[∑i=1my(i)(cost1(z))+(1−y(i))(cost0(z))]+2λ∑j=1nθj2
第三步,用
c
=
1
λ
c=\frac{1}{\lambda}
c=λ1替换,最终得到:
min
θ
C
∑
i
=
1
m
[
y
(
i
)
cost
1
(
θ
T
x
(
i
)
)
+
(
1
−
y
(
i
)
)
cost
0
(
θ
T
x
(
i
)
)
]
+
1
2
∑
i
=
1
n
θ
j
2
\min _{\theta} C \sum_{i=1}^{m}\left[y^{(i)} \operatorname{cost}_{1}\left(\theta^{T} x^{(i)}\right)+\left(1-y^{(i)}\right) \operatorname{cost}_{0}\left(\theta^{T} x^{(i)}\right)\right]+\frac{1}{2} \sum_{i=1}^{n} \theta_{j}^{2}
minθC∑i=1m[y(i)cost1(θTx(i))+(1−y(i))cost0(θTx(i))]+21∑i=1nθj2
在逻辑回归中,损失函数的形式为
A
+
λ
B
A+\lambda B
A+λB,我们通过正规化参数
λ
\lambda
λ 调节 A、B 所占的权重,且 A 的权重与
λ
\lambda
λ 取值成反比。
而在 SVM 中,损失函数的形式为
C
A
+
B
CA+B
CA+B,则通过参数 C 调节 A、B 所占的权重,且 A 的权重与 C 的取值成反比。亦即,参数 C 可以被认为是扮演了
1
λ
\frac{1}{\lambda}
λ1 的角色。
有别于逻辑回归假设函数输出的是概率,支持向量机它是直接预测 y 的值是0还是1。也就是说其假设函数是这样子的:
h θ ( x ) = { 1 ,      i f    θ T x ⩾ 0 0 ,      o t h e r w i s e h_{\theta}(x)=\left\{\begin{matrix} 1,\;\;if\; \theta^{T}x\geqslant 0\\ 0,\;\;otherwise \end{matrix}\right. hθ(x)={1,ifθTx⩾00,otherwise
以上得出的结论是从逻辑回归演进过来的,我理解吴恩达之所以按照这个逻辑来讲授SVM就是为了大家方便理解,其实在SVM有自己单独的理论体系,完全不必要从逻辑回归来引入理解,具体可参见李航的 《统计学习方法》第七章内容。
2.2 大间距分类器
支持向量机是最后一个监督学习算法,与前面我们所学的逻辑回归和神经网络相比,支持向量机在学习复杂的非线性方程时,提供了一种更为清晰、更加强大的方式。
支持向量机也叫做大间距分类器(large margin classifiers)。
如图,假如我们有一个数据集是这样的,可以看出,这是线性可分的。但是有时候我们的决策边界就好像图中绿色线或者粉红色线一样,这样的决策边界看起来都不是特别好的选择。支持向量机就会选择黑色这一条决策边界。黑色这条边界相比之前跟正负样本有更大的距离,而这个距离就叫做间距(margin)。这也是为什么我们将支持向量机叫做大间距分类器的原因。
支持向量机模型的做法是,即努力将正样本和负样本用最大的间距分开。
m
i
n
θ
C
[
∑
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
min_{\theta} C[\sum_{i=1}^{m}{y^{(i)}}cost_1(\theta^Tx^{(i)})+(1-y^{(i)})cost_0(\theta^Tx^{(i)})]+\frac{1}{2}\sum_{j=1}^{n}{\theta_j^2}
minθC[i=1∑my(i)cost1(θTx(i))+(1−y(i))cost0(θTx(i))]+21j=1∑nθj2
当 y=1 时,SVM 希望
θ
T
x
⩾
1
\theta^Tx\geqslant 1
θTx⩾1 。在 y=0 时,SVM 希望
θ
T
x
⩽
−
1
\theta^Tx \leqslant -1
θTx⩽−1,对于前面的那一项 取C很大的情况,对所有数据很敏感,不允许有分类错误,A 最小化代价函数,那么最理想当然是为0。所以这就变成了:
m
i
n
θ
1
2
∑
i
=
1
n
θ
j
2
            
{
θ
T
x
⩾
1
,
i
f
  
y
(
i
)
=
1
θ
T
x
⩽
1
,
i
f
  
y
(
i
)
=
0
min_{\theta}\frac{1}{2}\sum_{i=1}^{n}{\theta_j^2}\;\;\;\;\;\; \left\{\begin{matrix} \theta^Tx\geqslant 1,if \;y^{(i)}=1 \\ \theta^Tx\leqslant 1 ,if \;y^{(i)}=0 \end{matrix}\right.
minθ21i=1∑nθj2{θTx⩾1,ify(i)=1θTx⩽1,ify(i)=0
注意:参数 C 其实是支持向量机对异常点的敏感程度,C 越大就越敏感,任何异常点都会影响最终结果。 C 越小,对异常点就越不敏感,普通的一两个异常点都会被忽略。
2.3 推导大间隔分类
以两个二维向量为例,我们把向量 v 投影到向量 u 上,其投影的长度为 p,
∥
u
∥
\left \| u \right \|
∥u∥ 为向量 u 的模,那么向量的内积就等于
p
∗
∥
u
∥
p*\left \| u \right \|
p∗∥u∥。在代数定义向量内积可表示为:
u
1
v
1
+
u
2
v
2
u_1v_1+u_2v_2
u1v1+u2v2 ,根据此定义可以得出:
p
∗
∥
u
∥
=
u
T
v
=
u
1
v
1
+
u
2
v
2
p*\left \| u \right \|=u^Tv=u_1v_1+u_2v_2
p∗∥u∥=uTv=u1v1+u2v2 。
∥
u
∥
\left \| u \right \|
∥u∥为
u
→
\overrightarrow{u}
u 的范数,也就是向量
u
→
\overrightarrow{u}
u 的欧几里得长度。
如图所示:
最小化函数为:
m
i
n
θ
1
2
∑
i
=
1
n
θ
j
2
min_{\theta}\frac{1}{2}\sum_{i=1}^{n}{\theta_j^2}
minθ21i=1∑nθj2
这里以简单的二维为例:
m
i
n
θ
1
2
∑
i
=
1
n
θ
j
2
=
1
2
(
θ
1
2
+
θ
2
2
)
=
1
2
(
θ
1
2
+
θ
2
2
)
2
=
1
2
∥
θ
∥
2
min_{\theta}\frac{1}{2}\sum_{i=1}^{n}{\theta_j^2}=\frac{1}{2}(\theta_1^2+\theta_2^2)=\frac{1}{2}(\sqrt{\theta_1^2+\theta_2^2})^2=\frac{1}{2}\left \| \theta \right \|^2
minθ21i=1∑nθj2=21(θ12+θ22)=21(θ12+θ22)2=21∥θ∥2
只要
θ
\theta
θ 能最小,最小化函数就能取到最小。
如下图所示,对于支持向量机,可以利用以上结论转换优化目标函数和约束条件:
支持向量机希望,
x
x
x在
θ
\theta
θ方向上的投影尽量大,这样能够保证在
p
(
i
)
⋅
∥
θ
∥
≥
1
p^{(i)} \cdot\|\theta\| \geq 1
p(i)⋅∥θ∥≥1的前提下,
∥
θ
∥
2
\|\theta\|^{2}
∥θ∥2尽量小。
这就是为什么决策边界会是右图的原因,也就是为什么支持向量机能有效地产生最大间距分类的原因。
2.4 核技巧
2.4.1 定义
2.2 和 2.3节是假设样本线性可分的情况下,推导出来的大间隔分类器,但实际的使用中,并非所有训练样本都是线性可分的,或者说大多数样本线性不可分。所以本节引入了核技巧的概念,来针对这种情况,推广SVM。
如下图所示,就是一个线性不可分的数据集表示。
显然无法通过一个线性边界分隔开,对于这种非线性问题,最简单直接的想法,是通过多项式方式来进行拟合。但是这样的高阶项作为特征变量并不是我们确定所需要的,而且运算量非常巨大,那么有没有其他更高的特征变量呢?
因此引入了一种构造新特征量的想法:
其主要的思想,寻找临近点的相似度,而核函数就是相似度函数。
如图,我们这里只建立三个特征变量。首先我们在
x
1
,
x
2
x_1,x_2
x1,x2 坐标轴上手动选择3个不同的点:
l
(
1
)
,
l
(
2
)
,
l
(
3
)
l^{(1)},l^{(2)},l^{(3)}
l(1),l(2),l(3) 。
然后我们将第一个特征量定义为:
f
1
=
s
i
m
i
l
a
r
i
t
y
(
x
,
l
(
1
)
)
f_1=similarity(x,l^{(1)})
f1=similarity(x,l(1))
可以看做是样本 x 和第一个标记
l
(
1
)
l^{(1)}
l(1) 的相似度。其中可以用这个公式表达这种关系:
f
1
=
s
i
m
i
l
a
r
i
t
y
(
x
,
l
(
1
)
)
=
e
x
p
(
−
∣
∣
x
−
l
(
1
)
∣
∣
2
2
σ
2
)
f_1=similarity(x,l^{(1)})=exp(-\frac{||x-l^{(1)}||^2}{2\sigma^2})
f1=similarity(x,l(1))=exp(−2σ2∣∣x−l(1)∣∣2) (exp:自然常数e为底的指数函数)
类似的有:
f
2
=
s
i
m
i
l
a
r
i
t
y
(
x
,
l
(
2
)
)
=
e
x
p
(
−
∣
∣
x
−
l
(
2
)
∣
∣
2
2
σ
2
)
f_2=similarity(x,l^{(2)})=exp(-\frac{||x-l^{(2)}||^2}{2\sigma^2})
f2=similarity(x,l(2))=exp(−2σ2∣∣x−l(2)∣∣2) ,
f
3
=
s
i
m
i
l
a
r
i
t
y
(
x
,
l
(
3
)
)
=
e
x
p
(
−
∣
∣
x
−
l
(
3
)
∣
∣
2
2
σ
2
)
f_3=similarity(x,l^{(3)})=exp(-\frac{||x-l^{(3)}||^2}{2\sigma^2})
f3=similarity(x,l(3))=exp(−2σ2∣∣x−l(3)∣∣2) 。
这个表达式我们称之为核函数(Kernels),在这里我们选用的核函数是高斯核函数(Gaussian Kernels)。
那么高斯核函数与相似性又有什么关系呢?
先来看第一个特征量 f 1 f_1 f1 , f 1 = s i m i l a r i t y ( x , l ( 1 ) ) = e x p ( − ∣ ∣ x − l ( 1 ) ∣ ∣ 2 2 σ 2 ) = e x p ( ∑ j = 1 n ( x j − l j ( 1 ) ) 2 2 σ 2 ) f_1=similarity(x,l^{(1)})=exp(-\frac{||x-l^{(1)}||^2}{2\sigma^2})=exp(\frac{\sum_{j=1}^{n}{(x_j-l_j^{(1)})^2}}{2\sigma^2}) f1=similarity(x,l(1))=exp(−2σ2∣∣x−l(1)∣∣2)=exp(2σ2∑j=1n(xj−lj(1))2)
假如样本 x 非常接近 l ( 1 ) l^{(1)} l(1) ,即 x ≈ l ( 1 ) x\approx l^{(1)} x≈l(1) ,那么: f 1 ≈ e x p ( − 0 2 2 σ 2 ) ≈ 1 f_{1} \approx e x p\left(-\frac{0^{2}}{2 \sigma^{2}}\right) \approx 1 f1≈exp(−2σ202)≈1 。
假如样本 x 离
l
(
1
)
l^{(1)}
l(1) 非常远,即
x
≫
l
(
1
)
x\gg l^{(1)}
x≫l(1) ,那么:
f
1
≈
e
x
p
(
−
∞
2
2
σ
2
)
≈
0
f_{1} \approx e x p\left(-\frac{\infty^{2}}{2 \sigma^{2}}\right) \approx 0
f1≈exp(−2σ2∞2)≈0。
可视化如下:
从图中可以看到越接近
l
(
1
)
,
f
1
l^{(1)} , f_1
l(1),f1 的值越大。
这里顺带说一下
σ
2
\sigma^2
σ2 这个高斯核函数的参数对函数的影响。从图中可以看到,减小或者增加只会对图像的肥瘦产生影响,也就是影响增加或者减小的速度而已。
2.4.2 标记点选取
通过标记点以及核函数,训练出非常复杂的非线性判别边界。那标记点
l
(
1
)
,
l
(
2
)
,
l
(
3
)
l^{(1)},l^{(2)},l^{(3)}
l(1),l(2),l(3) 这些点是怎么来的?
假定我们有如下的数据集:
(
x
(
1
)
,
y
(
1
)
)
,
(
x
(
2
)
,
y
(
2
)
)
,
(
x
(
3
)
,
y
(
3
)
)
⋯
(
x
(
m
)
,
y
(
m
)
)
(x^{(1)},y^{(1)}),(x^{(2)},y^{(2)}),(x^{(3)},y^{(3)})\cdots(x^{(m)},y^{(m)})
(x(1),y(1)),(x(2),y(2)),(x(3),y(3))⋯(x(m),y(m))
我们就将每个样本作为一个标记点:
l
(
1
)
=
x
(
1
)
,
l
(
2
)
=
x
(
2
)
,
l
(
3
)
=
x
(
3
)
⋯
l
(
m
)
=
x
(
m
)
l^{(1)}=x^{(1)},l^{(2)}=x^{(2)},l^{(3)}=x^{(3)}\cdots l^{(m)}=x^{(m)}
l(1)=x(1),l(2)=x(2),l(3)=x(3)⋯l(m)=x(m)
则对于样本
(
x
(
i
)
,
y
(
i
)
)
(x^{(i)},y^{(i)})
(x(i),y(i)) ,我们计算其与各个标记点的距离:
f
1
(
i
)
=
s
i
m
(
x
(
i
)
,
l
(
1
)
)
f
2
(
i
)
=
s
i
m
(
x
(
i
)
,
l
(
2
)
)
⋮
f
m
(
i
)
=
s
i
m
(
x
(
i
)
,
l
(
3
)
)
\begin{matrix} f^{(i)}_1=sim(x^{(i)},l^{(1)})\\ f^{(i)}_2=sim(x^{(i)},l^{(2)})\\ \vdots \\ f^{(i)}_m=sim(x^{(i)},l^{(3)})\\ \end{matrix}
f1(i)=sim(x(i),l(1))f2(i)=sim(x(i),l(2))⋮fm(i)=sim(x(i),l(3))
得到新的特征向量:
f
∈
R
m
+
1
f \in \mathbb{R}^{m+1}
f∈Rm+1
f
=
[
f
0
f
1
f
2
⋮
f
m
]
f = \begin{bmatrix} f_0\\ f_1\\ f_2\\ \vdots \\ f_m \end{bmatrix}
f=⎣⎢⎢⎢⎢⎢⎡f0f1f2⋮fm⎦⎥⎥⎥⎥⎥⎤
其中
f
0
=
1
f_0=1
f0=1
则具备核函数的 SVM 的目标函数:
m
i
n
θ
C
[
∑
i
=
1
m
y
(
i
)
c
o
s
t
1
(
θ
T
f
(
i
)
)
+
(
1
−
y
(
i
)
)
c
o
s
t
0
(
θ
T
f
(
i
)
)
]
+
1
2
∑
j
=
1
n
θ
j
2
min_{\theta} C[\sum_{i=1}^{m}{y^{(i)}}cost_1(\theta^Tf^{(i)})+(1-y^{(i)})cost_0(\theta^Tf^{(i)})]+\frac{1}{2}\sum_{j=1}^{n}{\theta_j^2}
minθC[i=1∑my(i)cost1(θTf(i))+(1−y(i))cost0(θTf(i))]+21j=1∑nθj2
2.5 SVM实践
2.5.1 使用流行库
作为当今最为流行的分类算法之一,SVM 已经拥有了不少优秀的实现库,如 libsvm 等,因此,我们不再需要自己手动实现 SVM(要知道,一个能用于生产环境的 SVM 模型并非课程中介绍的那么简单)。
在使用这些库时,我们通常需要声明 SVM 需要的两个关键部分:
(1) 参数 C
由于 C 可以看做与正规化参数
λ
\lambda
λ 作用相反,则对于 C 的调节:
低偏差,高方差,即遇到了过拟合时:减小 C 值。
高偏差,低方差,即遇到了欠拟合时:增大 C 值。
(2) 核函数(Kernel)
对于核函数的选择有这么一些 tips:
当特征维度 n 较高,而样本规模 m 较小时,不宜使用核函数,否则容易引起过拟合。
当特征维度 n 较低,而样本规模 m 足够大时,考虑使用高斯核函数。不过在使用高斯核函数前,需要进行特征缩放(feature scaling)。
当核函数的参数
σ
2
\sigma^2
σ2 较大时,特征
f
i
f_i
fi 较为平缓,即各个样本的特征差异变小,此时会造成欠拟合(高偏差,低方差),如下图上边的图,
当
σ
2
\sigma^2
σ2 较小时,特征
f
i
f_i
fi 曲线变化剧烈,即各个样本的特征差异变大,此时会造成过拟合(低偏差,高方差),如下图下边的图:
2.5.2 多分类问题
流行的SVM库已经内置了多分类相关的 api,如果其不支持多分类,则与逻辑回归一样,使用 One-vs-All 策略来进行多分类:
轮流选中某一类型 i ,将其视为正样本,即 “1” 分类,剩下样本都看做是负样本,即 “0” 分类。
训练 SVM 得到参数
θ
(
1
)
,
θ
(
2
)
,
⋯
 
,
θ
(
K
)
\theta^{(1)},\theta^{(2)},\cdots,\theta^{(K)}
θ(1),θ(2),⋯,θ(K) ,即总共获得了 K−1 个决策边界。
2.5.3 分类模型的选择
目前为止,我们学到的分类模型有:逻辑回归、神经网络和SVM。怎么选择在这三者中做出选择呢?考虑特征维度 n 及样本规模 m 。
(1) 如果 n 相对于 m 非常大,例如 n=10000 ,而
m
∈
(
10
,
1000
)
m\in(10,1000)
m∈(10,1000) :此时选用逻辑回归或者无核的 SVM。
(2) 如果 n 较小,m 适中,如
n
∈
(
1
,
1000
)
n\in(1,1000)
n∈(1,1000) ,而
m
∈
(
10
,
10000
)
m\in(10,10000)
m∈(10,10000) :此时选用核函数为高斯核函数的 SVM。
(3) 如果 n 较小,m 较大,如
n
∈
(
1
,
1000
)
n\in(1,1000)
n∈(1,1000) ,而 m>50000 :此时,需要创建更多的特征(比如通过多项式扩展),再使用逻辑回归或者无核的 SVM。
(4) 神经网络对于上述情形都有不错的适应性,但是计算性能上较慢。
3. 课后编程作业
我将课后编程作业的参考答案上传到了github上,包括了octave版本和python版本,大家可参考使用。
https://github.com/GH-SUSAN/Machine-Learning-MarkDown/tree/master/week7
4. 总结
本周学习了一种强大的并且理论基础扎实的分类算法SVM,它是极其重要的一种机器学习算法,在过去的很长一段时间里,压的神经网络喘不过气。是机器学习必须要掌握的算法,要做到能公式推导的水平