7.1 线性支持向量机
7.1.1 间隔
一、函数间隔
对于一个训练样本,它到确定的超平面的函数间隔为:
函数间隔与距离是正相关的
,是一个大的正数
,是一个比较小的负数
,说明模型对样本的预测是正确的
大的函数间隔→高的预测置信度
对于训练数据集,它的函数间隔定义为所有样本中最小的那个:
二、几何间隔

对于样本,,它到决策面的距离是线段AB的长度
其中,点B可以表示为:
由于点B在决策边界上,即:
求解此方程可以得到样本的几何间隔为:
同样的,对于训练数据集,关于判别界面的几何间隔为:
函数间隔与几何间隔的关系:
显然,若,则二者相等
几何间隔具有不变性
三、最优间隔分类器
假设数据是线性可分的
给定一个训练集,一个自然的想法是试图找到一个使几何间隔最大化的决策边界,这表示对训练集的有可信的预测并且对训练数据的良好“拟合”

那么就需要最大化间隔,即:
可以将问题转化为几何间隔:
进一步简化问题,令几何间隔为单位1:
也就是说,在分类正确的情况下,样本到判别界面的距离应当大于单位1
7.1.2 拉格朗日对偶性
一、一般情况
对于一般的含有等式和不等式约束的最优化问题:
可以定义广义拉格朗日函数:
上式中,和分别是等式约束和不等式约束的拉格朗日乘子,并要求
那么考虑对于的函数:
这里下标P表示原始问题
假设存在使得约束条件不成立(即或),则可以通过令或等于正无穷来使得
而若满足全部约束,显然可以有,即:
那么如果考虑最小问题:
它与原始最优化问题是等价的,问题称为广义拉格朗日函数的极小极大问题。这样就将原始问题的最优解转化为了拉格朗日函数的极小极大问题。定义原始问题的最优值
为原始问题的值
二、对偶问题
定义:
考虑最大化,即:
问题称为广义拉格朗日函数的极大极小问题。可以将广义拉格朗日函数的极大极小问题表示为如下约束:
这一优化问题就称为原始问题的对偶问题,并定义对偶问题的最优解:
为对偶问题的值
三、原始问题和对偶问题的关系
若原始问题和对偶问题都有最优解,则:
设和,分别为原始问题和对偶问题的可行解,若,则和,分别是原始问题和对偶问题的最优解
四、KKT条件
对于原始问题和对偶问题,假设和是凸函数,是仿射函数,并且不等式约束是严格执行的,即,则存在,使得是原始问题的解,是对偶问题的解,且:
它的充分必要条件是以下Karush-Kuhn-Tucker(KKT)条件:
其中,上式中标红的部分称为KKT的对偶互补条件,总结下来就是:若强对偶(),则
7.1.3 线性SVM
支持向量:距分离超平面最近的样本
输入:线性可分的数据集
输出:判别函数及决策/判别界面
最优化问题
分离超平面:
判别函数:
理论保证:对于线性可分的训练数据集,最大间隔分类器存在且唯一
一、最优间隔分类器的对偶解

对于上面的最优化问题,其约束条件为:
由于KKT对偶互补条件为,而在本问题中显然至少有一个(证明略),因此满足KKT条件即要求:
而满足这一条件的样本就是支持向量,其距离到分离超平面的距离为单位1
支持向量的数量远小于样本数量,因此可以大大减少训练成本
将整个问题写为广义拉格朗日函数:
那么它的对偶问题为:
记对偶问题的最优值为,令偏导数等于0,求解和:
带入拉格朗日函数,即有:
二、线性可分SVM的求解过程
输入线性可分的训练数据集
首先通过求解对偶问题,得到拉格朗日乘子的最优解:
进而得到原问题的最优解:
分离超平面:
判别函数:
在计算和时,只需要利用那些的那些样本(支持向量)来计算
对偶技巧:只需要计算训练样本与输入特征的内积——
7.1.4 非线性可分SVM
假设
本文中的绘图代码:
import numpy as np
import matplotlib.pyplot as plt
from sklearn.svm import SVC
X = np.array([[3, 3], [4, 3], [1, 1], [1, 0], [0, 1.8]])
y = np.array([1, 1, -1, -1, -1])
svm = SVC(kernel='linear')
svm.fit(X, y)
w = svm.coef_[0]
b = svm.intercept_[0]
plt.scatter(X[:, 0], X[:, 1], c=['b' if label == 1 else 'orange' for label in y])
ax = plt.gca()
x_lim = ax.get_xlim()
y_lim = ax.get_ylim()
# 创建网格以绘制分离超平面
xx = np.linspace(-1, 5, 30)
yy = np.linspace(-1, 5, 30)
YY, XX = np.meshgrid(yy, xx)
xy = np.vstack([XX.ravel(), YY.ravel()]).T
Z = svm.decision_function(xy).reshape(XX.shape)
# 绘制分离超平面和间隔边界
ax.contour(XX, YY, Z, colors='k', levels=[-1, 0, 1], alpha=0.5,
linestyles=['--', '-', '--'])
# 高亮显示支持向量
ax.scatter(svm.support_vectors_[:, 0], svm.support_vectors_[:, 1], s=100,
linewidth=1, facecolors='none', edgecolors='r')
plt.show()
参考
https://www.kaggle.com/code/alaapdhall/custom-svm-with-numpy-vs-sklearn
最后更新于
这有帮助吗?