1.SVM简介
支持向量机(Support Vector Machine,简称SVM)是一种经典的机器学习算法,它的基本模型是定义在特征空间上的间隔最大的线性分类器,间隔最大使它有别于感知机;SVM还包括核技巧,这使它成为实质上的非线性分类器。SVM的的学习策略就是间隔最大化,可形式化为一个求解凸二次规划的问题。
2.线性SVM的算法原理
支持向量机(SVM)的基本想法是求解能够正确划分训练数据集并且几何间隔最大的分离超平面。对于线性可分的数据集来说,这样的超平面有无穷多个,但是几何间隔最大的分离超平面却是唯一的。
首先,我们定义超平面关于样本点 (xi,yi) 的几何间隔为。超平面关于所有样本点的几何间隔的最小值为 。
SVM模型的求解最大分割超平面问题可以表示为以下约束最优化问题:
将约束条件两边同时除以 γ,得到:
因为 ∥w∥,γ 都是标量,所以为了表达式简洁起见,令 w=∥w∥γw,b=∥w∥γb,得到:
yi(w⋅xi+b)≥1, i=1,2,...,N
又因为最大化 γ,等价于最大化 ∥w∥,也就等价于最小化 21∥w∥2 (21 是为了后面求导以后形式简洁,不影响结果),因此SVM模型的求解最大分割超平面问题又可以表示为以下约束最优化问题:
这是一个含有不等式约束的凸二次规划问题,可以对其使用拉格朗日乘子法得到其对偶问题(dual problem)1。首先,我们将有约束的原始目标函数转换为无约束的新构造的拉格朗日目标函数:
其中 αi 为拉格朗日乘子,且 αi≥01。现在我们令 θ(w)=αi≥0max L(w,b,α)1。当样本点不满足约束条件时,即在可行解区域外:yi(w⋅xi+b)<1,此时,将 αi 设置为无穷大,则 θ(w) 也为无穷大1。当满本点满足约束条件时,即在可行解区域内:yi(w⋅xi+b)≥1yi(w⋅xi+b)≥1,此时, θ(w) 为原函数本身。
3.非线性SVM算法原理
非线性支持向量机(SVM)的基本思想是通过引入核函数,用解线性分类问题的方法来求解非线性分类问题1。当训练数据线性不可分时,我们可以通过一种被称之为核方法的技术,将线性不可分的数据集转换为线性可分的数据集。
简单来说,非线性SVM的算法原理可以理解为:非线性SVM = 核技巧 + 线性SVM3。我们用向量 x 表示位于原始空间中的样本,ϕ(x) 表示 x 映射到特征空间之后的新向量。则非线性SVM对应的分隔超平面为:。
核方法的基本思想是:对于线性不可分数据集,我们可以将实例进行非线性变换,从线性不可分变成线性可分2。我们可以用数学语言对其进行表达,设原空间为 x⊂R2,z=(x(1),x(2))T∈X,新空间为 z⊂R2,z=(z(1),z(2))T∈Z,那么原空间到新空间的映射为:。经过变换,原空间 X⊂R2 变换为新空间 Z⊂R2,原空间中的点相应地变换为新空间中的点。
核函数的定义是:如果存在一个从X到H的映射:ϕ(x):x→H,使得对所有 x,z∈X,函数K(x,z)满足条件:,则称K(x,z)为核函数。
4.支持向量
支持向量是支持向量机(SVM)中的一个重要概念。在SVM中,我们试图找到一个超平面,使得正负样本点被正确地划分,且间隔最大。这个间隔被称为函数间隔。
在这个过程中,离超平面最近的样本点起着决定性的作用。这些点被称为“支持向量”。它们“支撑”起了一个分割超平面,使得超平面和支持向量之间的间隔尽可能地大。这样才可以使两类样本准确地分开。
对于线性不可分的情形,我们可以构造软间隔,位于间隔边界上及间隔边界之内的样本点的实例也称为支持向量(软间隔的支持向量)。
因此,支持向量在决定最佳超平面时起着至关重要的作用。
5.代码示例
在实际问题中应用支持向量机(SVM)的过程通常包括以下步骤:数据准备、模型定义、优化器选择、模型训练和结果评估。下面是一个使用Python和PyTorch库实现的基础的支持向量机(SVM)的示例:
# 导入所需的库
import torch
from torch import nn, optim
# 数据准备
X_train = torch.FloatTensor([[1, 1], [1, 2], [1, 3], [2, 1], [2, 2], [2, 3]])
y_train = torch.FloatTensor([1, 1, 1, -1, -1, -1])
# 定义SVM模型
class LinearSVM(nn.Module):
def __init__(self):
super(LinearSVM, self).__init__()
self.weight = nn.Parameter(torch.rand(2), requires_grad=True)
self.bias = nn.Parameter(torch.rand(1), requires_grad=True)
def forward(self, x):
return torch.matmul(x, self.weight) + self.bias
# 实例化模型和优化器
model = LinearSVM()
optimizer = optim.SGD([model.weight, model.bias], lr=0.01)
# 模型训练
for epoch in range(100):
output = model(X_train)
loss = torch.mean(torch.clamp(1 - y_train * output, min=0)) # hinge loss
loss += 0.01 * torch.dot(model.weight, model.weight) # l2 penalty
optimizer.zero_grad()
loss.backward()
optimizer.step()
# 结果评估
output = model(X_train)
predictions = [1 if i >= 0 else -1 for i in output]
correct = sum([1 if p == y else 0 for p, y in zip(predictions, y_train)])
accuracy = correct / len(y_train)
print(f'Accuracy: {accuracy * 100}%')
6.总结
在这次博客中,我们讨论了支持向量机(SVM)的一些关键概念和原理,包括:
-
线性SVM的算法原理:我们解释了线性SVM的算法原理,包括间隔最大化的数学表达,以及如何通过求解凸二次规划的问题得到最优超平面。
-
非线性SVM的算法原理:我们讨论了非线性SVM的算法原理,解释了当训练数据线性不可分时,如何通过使用核技巧和软间隔最大化,可以学习到一个非线性SVM。
-
支持向量:我们解释了什么是支持向量,以及它们在决定最佳超平面时的重要性。
-
代码实践:我们通过一个实例来展示了如何在实际问题中应用SVM,包括数据准备、模型训练、结果评估等步骤。