[吴恩达机器学习]10·支持向量机

吴恩达机器学习系列课程:https://www.bilibili.com/video/BV164411b7dx

优化目标

首先回忆逻辑回归的优化目标: \[ \min_\theta\frac{1}{m}\left[\sum_{i=1}^my^{(i)}\left(-\ln h_\theta(x^{(i)})\right)+(1-y^{(i)})\left(-\ln (1-h_\theta(x^{(i)}))\right)\right]+\frac{\lambda}{2m}\sum_{j=1}^n\theta_j^2 \] 记上式中 \(-\ln h_\theta(x^{(i)})\)\(\text{cost}_1(\theta^T x^{(i)})\),即分类为 \(1\) 时采用的代价,\(-\ln(1-h_\theta(x^{(i)}))\)\(\text{cost}_0(\theta^T x^{(i)})\),即分类为 \(0\) 时采用的代价,则支持向量机中,我们不再采用 \(\textbf{sigmoid}\) 函数,而是: \[ \text{cost}_1(z)=\begin{cases}0&z\geqslant1\\k_1(z-1)&z<1\end{cases}\quad\quad \text{cost}_0(z)=\begin{cases}0&z\leqslant-1\\k_0(z+1)&z>-1\end{cases} \]

另外,我们习惯于不除以样本大小 \(m\),并将正则化参数放在第一项而非第二项,即支持向量机的优化目标为: \[ \boxed {\min_\theta C\sum_{i=1}^m\left[y^{(i)}\text{cost}_1(\theta^Tx^{(i)})+(1-y^{(i)})\text{cost}_0(\theta^Tx^{(i)})\right]+\frac{1}{2}\sum_{j=1}^n\theta_j^2} \] 其中,\(C\) 是正则化参数,类比逻辑回归中 \(\frac{1}{\lambda}\) 的作用。

对该代价函数的理解:

首先看看 \(y\text{cost}_1(\theta^Tx)+(1-y)\text{cost}_0(\theta^Tx)\) 这一项,欲使之最小,最理想的情况就是 \(\text{cost}_y(\theta^T x)=0\),这对应着 \(\begin{cases}\theta^Tx\geqslant 1&\text{if }y=1\\\theta^Tx\leqslant -1&\text{if }y=0\end{cases}\);而在逻辑回归中,我们只需要对比 \(\theta^Tx\)\(0\) 的大小,这里相当于将条件变得更苛刻。

注意 \(\theta^Tx\) 其实是参数 \(\theta\)\(x\) 两个向量的点积,可以视作 \(x\)\(\theta\) 的投影乘上 \(\theta\) 的长度 \(||\theta||\);而 \(\sum\limits_{j=1}^n\theta_j^2\) 就是 \(||\theta||\)。从这个几何角度看,如果 \(C\) 取值较大,那么我们很关心能否把原数据集完美地线性分开,因为这样,只要 \(||\theta||\) 充分大,那么第一项就能取到 \(0\);相反地,如果 \(C\) 取值较小,那么即便有些数据点没有被正确地线性分类(第一项不为 \(0\)),由于我们需要的 \(||\theta||\) 不必太大,所以总代价依然较小。

核函数

对于非线性可分集,我们引入核函数 \(\phi:x\mapsto \phi(x)\),它将原来的 \(n\) 维向量映射为更高维的向量,使得这些向量在该更高维空间中线性可分。常用的核函数有:

  • 线性核:\(\phi(x_i)=x_i\),即不做任何改变;
  • 高斯核:\(\phi(x)=\begin{bmatrix}\exp\left(-\frac{||x-l^{(1)}||^2}{2\sigma^2}\right)\\\exp\left(-\frac{||x-l^{(2)}||^2}{2\sigma^2}\right)\\\vdots\\\exp\left(-\frac{||x-l^{(m)}||^2}{2\sigma^2}\right)\end{bmatrix}\),其中 \(\sigma\) 是参数,\(l^{(1)},\cdots,l^{(m)}\) 被称作 landmark,实践中直接采用输入数据 \(x^{(1)},\cdots,x^{(m)}\) 作为 landmark。

scikit-learn 实现

线性可分分类

首先看一下数据集的样纸:

1
2
3
4
from sklearn import svm

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

训练结果如下:

带高斯核的 \(\textbf{SVM}\)

依旧先看数据集的样子:

1
2
3
4
from sklearn import svm

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

训练结果如下:

调整参数 \(C,\sigma\)

数据集:

1
2
3
4
5
6
7
8
9
10
11
12
maxscore, maxC, maxgamma = 0, 0, 0
for C in [0.01, 0.03, 0.1, 0.3, 1, 3, 10, 30]:
for gamma in [0.01, 0.03, 0.1, 0.3, 1, 3, 10, 30]:
clf = svm.SVC(C=C, kernel='rbf', gamma=gamma, probability=True)
clf.fit(X, y)
score = clf.score(X, y)
print(C, gamma, score)
if score > maxscore:
maxscore, maxC, maxgamma = score, C, gamma

clf = svm.SVC(C=maxC, kernel='rbf', gamma=maxgamma, probability=True)
clf.fit(X, y)

训练结果如下:


[吴恩达机器学习]10·支持向量机
https://xyfjason.github.io/blog-main/2021/01/17/吴恩达机器学习-10·支持向量机/
作者
xyfJASON
发布于
2021年1月17日
许可协议