什么是SVM

支持向量机(Support Vector Machine, SVM)是最受欢迎的机器学习模型之一。它特别适合处理中小型复杂数据集的分类任务。

SMV在众多实例中寻找一个最优的决策边界,这个边界上的实例叫做支持向量,它们“支持”(支撑)分离开超平面,所以它叫支持向量机。



如上图,我们计算直线到分割实例的距离,使得我们的直线与数据集的距离尽可能的远,那么我们就可以得到唯一的解。最大化上图虚线之间的距离就是我们的目标。而上图中重点圈出的实例就叫做支持向量。

代码

背景

1
2
3
4
5
6
7
8
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

df = pd.read_csv('https://blog.caiyongji.com/assets/mouse_viral_study.csv')
df.head()

Med_1_mL Med_2_mL Virus Present
6.50823 8.58253 0
4.12612 3.07346 1
6.42787 6.36976 0
3.67295 4.90522 1
1.58032 2.44056 1

该数据集模拟了一项医学研究,对感染病毒的小白鼠使用不同剂量的两种药物,观察两周后小白鼠是否感染病毒。

  • 特征: 药物Med_1_mL 、药物Med_2_mL
  • 标签:是否感染病毒(1感染/0不感染)

特点



我们可以做出大概的判断,当加大药物剂量可使小白鼠避免被感染。

训练

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# 导入所需库
from sklearn.svm import SVC
import matplotlib.pyplot as plt
import numpy as np

# 准备数据
y = df['Virus Present']
X = df.drop('Virus Present',axis=1)

# 定义模型
model = SVC(kernel='linear', C=1000)

# 训练模型
model.fit(X, y)

# 定义绘制SVM边界方法
def plot_svm_boundary(model,X,y):
# 将数据转换为Numpy数组
X = X.values
y = y.values

# 绘制散点图
plt.scatter(X[:, 0], X[:, 1], c=y, s=30,cmap='coolwarm')

# 绘制决策函数
ax = plt.gca()
xlim = ax.get_xlim()
ylim = ax.get_ylim()

# 创建网格以评估模型
xx = np.linspace(xlim[0], xlim[1], 30)
yy = np.linspace(ylim[0], ylim[1], 30)
YY, XX = np.meshgrid(yy, xx)
xy = np.vstack([XX.ravel(), YY.ravel()]).T
Z = model.decision_function(xy).reshape(XX.shape)

# 绘制决策边界和边距
ax.contour(XX, YY, Z, colors='k', levels=[-1, 0, 1], alpha=0.5,
linestyles=['--', '-', '--'])

# 绘制支持向量
ax.scatter(model.support_vectors_[:, 0], model.support_vectors_[:, 1], s=100,
linewidth=1, facecolors='none', edgecolors='k')

# 显示图像
plt.show()

# 调用绘制SVM边界方法
plot_svm_boundary(model,X,y)

剖析

SVC参数C

SVC方法参数C代表L2正则化参数,正则化的强度与C的值城反比,即C值越大正则化强度越弱,其必须严格为正。

例如——

1
2
3
model = SVC(kernel='linear', C=0.05)
model.fit(X, y)
plot_svm_boundary(model,X,y)

我们减少C的值,可以看到模型拟合数据的程度减弱。

核技巧

SVC方法的kernel参数可取值{'linear', 'poly', 'rbf', 'sigmoid', 'precomputed'}。像前文中所使用的那样,我们可以使kernel='linear'进行线性分类。那么如果我们像进行非线性分类呢?

多项式内核

多项式内核kernel='poly'的原理简单来说就是,用单一特征生成多特征来拟合曲线

我们使用多项式内核,并通过degree=5设置多项式的最高次数为5。我们可以看出分割出现了一定的弧度。

1
2
3
4
model = SVC(kernel='poly', C=0.05,degree=5)
model.fit(X, y)
plot_svm_boundary(model,X,y)

高斯RBF内核

SVC方法默认内核为高斯RBF

这时我们需要引入gamma参数来控制钟形函数的形状。增加gamma值会使钟形曲线变得更窄,因此每个实例影响的范围变小,决策边界更不规则。减小gamma值会使钟形曲线变得更宽,因此每个实例的影响范围变大,决策边界更平坦。

1
2
3
4
model = SVC(kernel='rbf', C=1,gamma=0.01)
model.fit(X, y)
plot_svm_boundary(model,X,y)