吴恩达机器学习笔记(10)—支持向量机

目录

本节将继续介绍监督学习中的一个强力的分类器------支持向量机(Support Vector Machine,SVM),其通过「间隔最大化 」的思想来学习最优的决策边界,比逻辑回归算法更为鲁棒。

一、支持向量机

首先来直观地理解一下决策边界,考虑一个线性可分的二分类问题:


不同的决策边界

图中有三条直线分别代表三个分类器的决策边界,可以直观地感受到 H 3 H_3 H3 应该会好于 H 1 H_1 H1 和 H 2 H_2 H2 。显然, H 1 H_1 H1 甚至不能把类别正确分开,肯定不能考虑; H 2 H_2 H2 虽然可以,但是边界距离最近的数据点只有很小的间隔 ,如果测试数据有一些噪声的话,很可能会被 H 2 H_2 H2 错误地分到另一类------即对噪声敏感、泛化能力弱

而 H 3 H_3 H3 似乎距离两侧都有较大的间隔,可以容忍一些微小的噪声。如何能学习到这样一个分类器呢?

1、优化目标

回忆逻辑回归的优化目标:
min ⁡ θ 1 m [ ∑ i = 1 m y ( i ) ( − ln ⁡ h θ ( x ( i ) ) ) + ( 1 − y ( i ) ) ( − ln ⁡ ( 1 − h θ ( x ( i ) ) ) ) ] + λ 2 m ∑ j = 1 n θ j 2 \min_{\theta} \frac{1}{m} \left[ \sum_{i=1}^{m} y^{(i)} \left( -\ln h_{\theta} \left( x^{(i)} \right) \right) + \left( 1 - y^{(i)} \right) \left( -\ln \left( 1 - h_{\theta} \left( x^{(i)} \right) \right) \right) \right] + \frac{\lambda}{2m} \sum_{j=1}^{n} \theta_{j}^{2} θminm1[i=1∑my(i)(−lnhθ(x(i)))+(1−y(i))(−ln(1−hθ(x(i))))]+2mλj=1∑nθj2

其中的 h θ ( x ( i ) ) h_{\theta}\left(x^{(i)}\right) hθ(x(i)) 使用 sigmoid 函数,因此对于一个 y = 1 y = 1 y=1 的样本,我们希望 h θ ( x ) h_{\theta}(x) hθ(x) 也趋近于 1,也就是 θ T x \theta^{T}x θTx 远大于 0,反之同理。进一步地,我们只考虑优化目标中的代价函数:
Cost ( h θ ( x ) , y ) = { − ln ⁡ ( h θ ( x ) ) y = 1 − ln ⁡ ( 1 − h θ ( x ) ) y = 0 \text{Cost}\left(h_{\theta}(x), y\right)= \begin{cases} -\ln \left(h_{\theta}(x)\right) & y = 1 \\ -\ln \left(1 - h_{\theta}(x)\right) & y = 0 \end{cases} Cost(hθ(x),y)={−ln(hθ(x))−ln(1−hθ(x))y=1y=0

画出两种情况下的代价函数关于 θ T x \theta^{T}x θTx 的曲线:


Sigmoid 代价函数

记上图中左图为 cost 1 ( θ T x ) \text{cost}_1(\theta^T x) cost1(θTx),即分类为 1 时采用的代价;右图为 cost 0 ( θ T x ) \text{cost}_0(\theta^T x) cost0(θTx),即分类为 0 时采用的代价。在支持向量机中,我们不再采用 sigmoid 函数,而是将其修改为一条非常接近的折线


支持向量机的代价函数

其中,折线的拐点位于 z = ± 1 z = \pm 1 z=±1 的位置,先不考虑斜率的大小,则代价函数可以表示为:
cost 1 ( z ) = { 0 z ⩾ 1 k 1 ( z − 1 ) z < 1 cost 0 ( z ) = { 0 z ⩽ − 1 k 0 ( z + 1 ) z > − 1 \text{cost}_1(z) = \begin{cases} 0 & z \geqslant 1 \\ k_1(z - 1) & z < 1 \end{cases} \quad \text{cost}_0(z) = \begin{cases} 0 & z \leqslant -1 \\ k_0(z + 1) & z > -1 \end{cases} cost1(z)={0k1(z−1)z⩾1z<1cost0(z)={0k0(z+1)z⩽−1z>−1

此代价函数也被称为折页损失(Hinge Loss) ,非常形象,常用于凸优化任务中,也被写作:
L ( y ) = max ⁡ ( 0 , 1 − y ^ ⋅ y ) L(y) = \max(0, 1 - \hat{y} \cdot y) L(y)=max(0,1−y^⋅y)

其中 y = ± 1 y = \pm 1 y=±1 为正确的标签, y ^ \hat{y} y^ 为预测输出,通常是软结果,即取 [ − 1 , 1 ] [-1, 1] [−1,1] 区间中的值。

另外,SVM 中习惯不除以样本大小 m m m,这不会影响最终的优化目标。并将正则化参数 放在第一项而非第二项,即支持向量机的优化目标为:
min ⁡ θ C ∑ i = 1 m [ y ( i ) cost 1 ( θ T x ( i ) ) + ( 1 − y ( i ) ) cost 0 ( θ T x ( i ) ) ] + 1 2 ∑ j = 1 n θ j 2 \min_{\theta} C \sum_{i=1}^{m} \left[ y^{(i)} \text{cost}_1 \left( \theta^T x^{(i)} \right) + \left( 1 - y^{(i)} \right) \text{cost}0 \left( \theta^T x^{(i)} \right) \right] + \frac{1}{2} \sum{j=1}^{n} \theta_j^2 θminCi=1∑m[y(i)cost1(θTx(i))+(1−y(i))cost0(θTx(i))]+21j=1∑nθj2

其中, C C C 就是正则化参数,类比逻辑回归中 λ \lambda λ 的作用。并且当 C C C 取到 1 λ \frac{1}{\lambda} λ1 时两者的优化目标一致。

2、大间隔思想

显然,新的代价函数会在计算速度上有一定的优势,但它是如何最大化间隔(Margin) 的呢?我们首先观察第一项代价 y 1 ( θ T x ) + ( 1 − y ) 0 ( θ T x ) y_1(\theta^T x) + (1 - y)_0(\theta^T x) y1(θTx)+(1−y)0(θTx),欲使之最小,最理想的情况就是对于每个样本,都有 cost y ( θ T x ) = 0 \text{cost}_y(\theta^T x) = 0 costy(θTx)=0,对应着:
{ θ T x ⩾ 1 if y = 1 θ T x ⩽ − 1 if y = 0 \begin{cases} \theta^T x \geqslant 1 & \text{if } y = 1 \\ \theta^T x \leqslant -1 & \text{if } y = 0 \end{cases} {θTx⩾1θTx⩽−1if y=1if y=0

而在逻辑回归中,我们只需要使误分类的样本最少 ,也就是:
{ θ T x ⩾ 0 if y = 1 θ T x ⩽ 0 if y = 0 \begin{cases} \theta^T x \geqslant 0 & \text{if } y = 1 \\ \theta^T x \leqslant 0 & \text{if } y = 0 \end{cases} {θTx⩾0θTx⩽0if y=1if y=0

因此 SVM 相当于将判别条件变得更苛刻 ,以文章开篇提到的三条决策边界为例,直线 H 2 H_2 H2 和 H 3 H_3 H3 以及它俩的任意线性组合,都能完美分开两类,也就是能有无穷多个解满足逻辑回归的优化目标。但对于支持向量机而言,可选的解会相对少很多。而这也使 SVM 能相对更具有鲁棒性,因为我们留出了一个「安全边界」来应对噪声样本。

接下来假设一种极端的情况,我们将正则化参数 C C C 取一个非常大的值 ,此时模型会倾向于将第一项收敛为 0。那么模型的优化目标可以改写为:
min ⁡ θ 1 2 ∑ j = 1 n θ j 2 s.t { θ T x ( i ) ⩾ 1 if y ( i ) = 1 θ T x ( i ) ⩽ − 1 if y ( i ) = 0 \min_{\theta} \frac{1}{2} \sum_{j=1}^{n} \theta_j^2 \text{ s.t } \begin{cases} \theta^T x^{(i)} \geqslant 1 & \text{if } y^{(i)} = 1 \\ \theta^T x^{(i)} \leqslant -1 & \text{if } y^{(i)} = 0 \end{cases} θmin21j=1∑nθj2 s.t {θTx(i)⩾1θTx(i)⩽−1if y(i)=1if y(i)=0

上式也被称为硬间隔(Hard Margin) 优化目标,用于在线性可分的数据集中找到唯一的 最优边界。但在现实情况中,数据样本通常更加复杂,即使真的线性可分,也可能会存在部分离群点 ,而模型为了得到完美的边界,会学习到偏差很大的边界。因此在实际中通常不将 C C C 设置得过大,采用软间隔(Soft Margin)


存在离群点时的硬间隔和软间隔

回顾我们前面说到的,可以将 C C C 类比为 1 λ \frac{1}{\lambda} λ1,因此:

  • C C C 较大时,相当于 λ \lambda λ 较小,可能会导致过拟合、高方差,出现如上图红线那样的情形。
  • C C C 较小时,相当于 λ \lambda λ 较大,可能会导致欠拟合、高偏差,甚至无法分类。

3、几何角度理解大间隔

在前文改写的优化目标的基础上,我们注意到 θ T x \theta^T x θTx 其实是参数 θ \theta θ 和 x x x 两个向量的点积(内积) ,可以视作 x x x 向 θ \theta θ 的投影长度乘上 θ \theta θ 的长度 ∥ θ ∥ \|\theta\| ∥θ∥。

为了更好理解,我们忽略掉截距,令 θ 0 = 0 \theta_0 = 0 θ0=0,将特征数 n n n 置为 2,于是仅有两个特征 { x 1 , x 2 } \{x_1, x_2\} {x1,x2} 和两个参数 { θ 1 , θ 2 } \{\theta_1, \theta_2\} {θ1,θ2}。则此时有:
1 2 ∑ j = 1 n θ j 2 = 1 2 ( θ 1 2 + θ 2 2 ) = 1 2 ( θ 1 2 + θ 2 2 ) 2 = 1 2 ∥ θ ∥ 2 \frac{1}{2} \sum_{j=1}^{n} \theta_j^2 = \frac{1}{2} \left( \theta_1^2 + \theta_2^2 \right) = \frac{1}{2} \left( \sqrt{\theta_1^2 + \theta_2^2} \right)^2 = \frac{1}{2} \|\theta\|^2 21j=1∑nθj2=21(θ12+θ22)=21(θ12+θ22 )2=21∥θ∥2

从几何角度理解,参数 θ \theta θ 其实是决策边界的法向量 ,因此会和边界本身呈现垂直关系。而特征 x x x 就是样本点在(特征空间)坐标系上的向量,起点为原点。绘制出如下样例:


样本点在法向量上的投影

其中 p ( i ) p^{(i)} p(i) 为投影轴的长度(可正可负),于是可以得到:
θ T x ( i ) = θ 1 x 1 ( i ) + θ 2 x 2 ( i ) = p ( i ) ∥ θ ∥ \theta^T x^{(i)} = \theta_1 x_1^{(i)} + \theta_2 x_2^{(i)} = p^{(i)} \|\theta\| θTx(i)=θ1x1(i)+θ2x2(i)=p(i)∥θ∥

因此优化目标可以从几何角度 再次改写为:
min ⁡ θ 1 2 ∥ θ ∥ 2 s. t { p ( i ) ∥ θ ∥ ⩾ 1 if y ( i ) = 1 p ( i ) ∥ θ ∥ ⩽ − 1 if y ( i ) = 0 \min_{\theta} \frac{1}{2} \|\theta\|^2 \text{ s. t } \begin{cases} p^{(i)} \|\theta\| \geqslant 1 & \text{if } y^{(i)} = 1 \\ p^{(i)} \|\theta\| \leqslant -1 & \text{if } y^{(i)} = 0 \end{cases} θmin21∥θ∥2 s. t {p(i)∥θ∥⩾1p(i)∥θ∥⩽−1if y(i)=1if y(i)=0

显然,为了让法向量的范数 ∥ θ ∥ 2 \|\theta\|^2 ∥θ∥2 最小化,我们必须增大样本在法向量上的投影 p ( i ) p^{(i)} p(i) 长度,如下图所示:


不同方向的法向量具有不同的投影长度

以上就是为什么支持向量机最终会找到最大间隔的原因。当然,在推导的过程中我们使用了简化的假设,例如 θ 0 = 0 \theta_0 = 0 θ0=0,这是为了让决策平面通过原点。

二、实际使用

1、软间隔

当训练数据不能线性可分但是可以近似线性可分 时,可以允许 SVM 在少量样本上出错,即将之前的硬间隔最大化条件放宽一点,为此引入软间隔(Soft Margin)的概念。

此时,我们就不再不将正则化参数 C C C 设置得过大,则优化目标就变成:
min ⁡ θ , θ 0 1 2 ∥ θ ∥ 2 + C ∑ i = 1 n max ⁡ ( 0 , 1 − y ( i ) ( θ T x ( i ) + θ 0 ) ) \min_{\theta, \theta_0} \frac{1}{2} \|\theta\|^2 + C \sum_{i=1}^{n} \max \left( 0, 1 - y^{(i)} \left( \theta^T x^{(i)} + \theta_0 \right) \right) θ,θ0min21∥θ∥2+Ci=1∑nmax(0,1−y(i)(θTx(i)+θ0))

2、高斯核函数

对于非线性可分的数据,在之前的文章中我们知道可以引入高阶特征 来进行多项式回归 ,而问题就是如何选择这些高阶特征?除了通过组合原有特征,在这里我们引入核函数 ϕ : x ↦ ϕ ( x ) \phi: x \mapsto \phi(x) ϕ:x↦ϕ(x),它将原来的 n n n 维向量映射为更高维的向量,使得这些向量在该更高维空间中线性可分。


原始空间通过核函数映射到高维空间

在之前的例子中,可以认为是使用了线性核 ϕ ( x ) = x \phi(x) = x ϕ(x)=x,即不做任何改变;而接下来我们将介绍一种最常用的核函数------高斯核(Gaussian Kernel)
ϕ i ( x ) = Sim ( x , l ( i ) ) = exp ⁡ { − ∥ x − l ( i ) ∥ 2 2 σ 2 } \phi_{i}(x) = \text{Sim} \left( x, l^{(i)} \right) = \exp \left\{ -\frac{\left\| x - l^{(i)} \right\|^2}{2\sigma^2} \right\} ϕi(x)=Sim(x,l(i))=exp{−2σ2 x−l(i) 2}

其中 σ \sigma σ 是可调节参数, l ( i ) l^{(i)} l(i) 被称为地标(Landmarks) ,是原始空间中选取的某些点,具有和样本特征 x x x 相同的维度。 ∥ x − l ( i ) ∥ \left\| x - l^{(i)} \right\| x−l(i) 即为样本到地标的欧氏距离。

可以看出,高斯核与正态分布的形式有些许类似,绘制出函数图像:

不同参数下的高斯核函数图像

显然, x x x 距离 l ( i ) l^{(i)} l(i) 越远时,分子越大,函数值越接近 0 0 0;距离越近时,分子越接近 0 0 0,函数值越接近 1 1 1;当 x = l ( i ) x = l^{(i)} x=l(i) 时,函数值取到最大值。因此,我们自然而然地想到可以取训练集中的样本点作为地标 ,有 m m m 个样本就取 m m m 个地标。这里不需要区分正负样本点,因为在核函数 ϕ ( i ) ( x ) \phi^{(i)}(x) ϕ(i)(x) 前面还有一个可学习的 θ ( i ) \theta^{(i)} θ(i),对于不同样本会自动区分。注意到 σ \sigma σ 较大时,变化也较为平缓,模型可能会欠拟合,造成高偏差;反之则可能会造成过拟合。

假设我们原来用 x ( i ) = { 1 , x 1 ( i ) , x 2 ( i ) , ⋯   , x n ( i ) } ∈ R n + 1 x^{(i)} = \left\{ 1, x_1^{(i)}, x_2^{(i)}, \cdots, x_n^{(i)} \right\} \in \mathbb{R}^{n + 1} x(i)={1,x1(i),x2(i),⋯,xn(i)}∈Rn+1 来描述第 j j j 个样本的特征向量,则现在就是使用:
f ( x ( i ) ) = [ 1 ϕ 1 ( x ( i ) ) ϕ 2 ( x ( i ) ) ⋮ ϕ i ( x ( i ) ) ⋮ ϕ m ( x ( i ) ) ] = [ 1 Sim ( x ( i ) , l ( 1 ) ) Sim ( x ( i ) , l ( 2 ) ) ⋮ Sim ( x ( i ) , l ( i ) ) = 1 ⋮ Sim ( x ( i ) , l ( m ) ) ] ∈ R m + 1 f \left( x^{(i)} \right) = \begin{bmatrix} 1 \\ \phi_1 \left( x^{(i)} \right) \\ \phi_2 \left( x^{(i)} \right) \\ \vdots \\ \phi_i \left( x^{(i)} \right) \\ \vdots \\ \phi_m \left( x^{(i)} \right) \end{bmatrix} = \begin{bmatrix} 1 \\ \text{Sim} \left( x^{(i)}, l^{(1)} \right) \\ \text{Sim} \left( x^{(i)}, l^{(2)} \right) \\ \vdots \\ \text{Sim} \left( x^{(i)}, l^{(i)} \right) = 1 \\ \vdots \\ \text{Sim} \left( x^{(i)}, l^{(m)} \right) \end{bmatrix} \in \mathbb{R}^{m + 1} f(x(i))= 1ϕ1(x(i))ϕ2(x(i))⋮ϕi(x(i))⋮ϕm(x(i)) = 1Sim(x(i),l(1))Sim(x(i),l(2))⋮Sim(x(i),l(i))=1⋮Sim(x(i),l(m)) ∈Rm+1

三、代码实现

在实际运用 SVM 时,我们通常会调用现成的机器学习第三方库,比较经典的就有 Python 中的 Scikit-learn ,其调用支持向量分类器的函数如下:

python 复制代码
sklearn.svm.SVC(C=1.0, kernel='rbf', gamma='auto', probability=False)

该函数的实现基于 libsvm,其中二次规划问题的解决算法是 SMO,通常需要调节的参数如下:

  • C:正则化参数,取值越大,对松弛变量(误分类的代价函数)的惩罚越大,适用于训练集几乎可分的情况,此时训练集上的准确率较高,但泛化能力弱(过拟合)。
  • kernel:默认取 rbf 径向基函数(高斯核),可选 linear 线性核、poly 多项式核、sigmod 等。
  • gamma:核函数系数,默认为 auto,取样本特征数的倒数。
  • probability:是否启用概率估计,即最后的输出会包含属于每个类的概率值。

下面以 Coursera 上的数据集 ex6data1.mat 为例,这是一个线性可分的数据集:

数据集 ex6data1 可视化

使用如下代码:

python 复制代码
import numpy as np
from scipy.io import loadmat
from sklearn import svm
import matplotlib.pyplot as plt

# load data
data = loadmat('ex6data1.mat')
X = data['X']			# (51, 2)
y = data['y'].flatten()	# (51, )

# classifier define
clf = svm.SVC(C=1, kernel='linear')
clf.fit(X, y)

# dicision boundary
x1, x2 = np.meshgrid(np.linspace(0, 4.5, 100), np.linspace(1.3, 4.5, 100))
f = np.concatenate((x1.reshape(10000, 1), x2.reshape(10000, 1)), axis = 1)
res = clf.decision_function(f).reshape((100,100))

# draw
plt.xlabel('x1')
plt.ylabel('x2')
plt.title('C=1')
plt.plot(X[y==1][:, 0], X[y==1][:, 1], '+', color='black')
plt.plot(X[y==0][:, 0], X[y==0][:, 1], 'o', color='gold')
plt.contour(x1, x2, res, [0])
plt.show()

训练结果如下:


数据集 ex6data1 训练结果

此外还有一个非线性可分的数据集 ex6data2.mat


数据集 ex6data2 可视化

使用如下代码:

python 复制代码
import numpy as np
from scipy.io import loadmat
from sklearn import svm
import matplotlib.pyplot as plt

# load data
data = loadmat('ex6data2.mat')
X = data['X']			# (863, 2)
y = data['y'].flatten()	# (863, )

# classifier define
clf = svm.SVC(C=100, kernel='rbf', gamma=10, probability=True)
clf.fit(X, y)
print(clf.score(X, y))

# dicision boundary
x1, x2 = np.meshgrid(np.linspace(0, 1, 100), np.linspace(0.38, 1, 100))
f = np.concatenate((x1.reshape(10000, 1), x2.reshape(10000, 1)), axis = 1)
res = clf.decision_function(f).reshape((100,100))

# draw
plt.xlabel('x1')
plt.ylabel('x2')
plt.title('C=100, gamma=10')
plt.plot(X[y==1][:, 0], X[y==1][:, 1], '+', color='black')
plt.plot(X[y==0][:, 0], X[y==0][:, 1], 'o', color='gold')
plt.contour(x1, x2, res, [0])
plt.show()

训练结果如下:


数据集 ex6data2 训练结果

相关推荐
芒果量化3 小时前
ML4T - 第7章第8节 利用LR预测股票价格走势Predicting stock price moves with Logistic Regression
算法·机器学习·线性回归
lisw055 小时前
数据科学与AI的未来就业前景如何?
人工智能·机器学习·软件工程
王哥儿聊AI6 小时前
告别人工出题!PromptCoT 2.0 让大模型自己造训练难题,7B 模型仅用合成数据碾压人工数据集效果!
人工智能·深度学习·算法·机器学习·软件工程
深栈6 小时前
机器学习:逻辑回归
人工智能·pytorch·机器学习·逻辑回归·scikit-learn
yourkin6666 小时前
人工智能 (AI) > 机器学习 (ML) > 深度学习 (DL)
人工智能·深度学习·机器学习
蒋星熠6 小时前
爬虫与自动化技术深度解析:从数据采集到智能运维的完整实战指南
运维·人工智能·爬虫·python·深度学习·机器学习·自动化
wuli玉shell12 小时前
机器学习、数据科学、深度学习、神经网络的区别与联系
深度学习·神经网络·机器学习
ASIAZXO12 小时前
机器学习——SVM支持向量机详解
人工智能·机器学习·支持向量机
通信小呆呆15 小时前
动态目标检测与跟踪:基于卡尔曼滤波的门限关联与可视化全流程
人工智能·目标检测·机器学习