一、引言
支持向量机(Support Vector Machine,SVM)是一种广泛应用于分类和回归分析的机器学习算法。它通过将样本映射到高维特征空间,寻找一个最优的超平面来实现分类。本文将介绍 SVM 的原理,并使用 Python 实现。
二、SVM的简介
2.1 SVM的基本思想
SVM是一种经典的监督学习算法,其基本思想可以简单概括为以下几点:
1.寻找最优的超平面:SVM 的目标是在特征空间中找到一个最优的超平面,以能够将不同类别的样本正确地分开。超平面是一个 d-1 维的子空间,其中 d 是特征空间的维度。
2.最大化间隔:SVM 在寻找超平面时,会尽可能地将不同类别的样本分开,并且使得支持向量(离超平面最近的样本点)到超平面的距离最大化。这个距离被称为间隔(margin),因此 SVM 也被称为最大间隔分类器。
3.核函数技巧:当样本数据线性不可分时,SVM 通过引入核函数来将数据映射到高维特征空间,从而使得非线性问题在高维空间中变得线性可分。常用的核函数有线性核、多项式核、高斯径向基函数(RBF)核等。
4.支持向量:在 SVM 中,只有少数关键的样本点对确定超平面起作用,这些样本点被称为支持向量。SVM 的决策边界只与支持向量有关,而与其他样本点无关,这也是 SVM 算法高效的原因之一。
5.正则化参数 C:SVM 中的正则化参数 C 控制了模型的复杂度与容错能力之间的权衡。较小的 C 值会使得分类器更加允许出现错误分类,使得决策边界更加平滑;而较大的 C 值会强制分类器尽可能正确分类所有样本,可能导致过拟合。
让我们来看下面两个样本谁的拟合性会更好?
看起来其实差不多,但是如果我再加几个不同的样本进去呢?
很显然后面C2会更厉害一点,所以浅显地来说svm分类器需要加大间隔:
其目的是找到合适的决策分界线和边界分界面。
2.2线性可分与线性不可分问题
在线性可分问题中,SVM 的目标是找到一个超平面,能够完全将不同类别的样本正确地分开。这意味着存在一个超平面,使得所有正样本都在超平面的一侧,而负样本都在另一侧。
数学上,对于一个线性可分的二分类问题,可以用以下形式的方程表示超平面:
其中,w 是法向量(normal vector), x 是样本特征向量,b 是偏置(bias),w^T 表示向量 w 的转置与向量 x 的点积。
在线性可分问题中,可以通过求解一个凸优化问题来寻找最优的超平面。这个问题的目标是最大化间隔,并且要满足所有正样本和负样本的约束条件。
然而,实际应用中,许多问题并不是线性可分的,即使使用直线或平面也无法完全将不同类别的样本分开。这时候就需要引入一些方法来处理线性不可分问题。
一种常用的方法是引入松弛变量(slack variable),它允许样本出现错误分类。通过引入松弛变量,可以允许一些样本位于超平面的错误一侧,从而使得分类器具有容错能力。
线性不可分问题可以通过引入软间隔 SVM(Soft Margin SVM)来解决。软间隔 SVM 允许一些样本位于超平面的边界区域,同时尽可能地减小松弛变量的数量。这样可以在保持分类器简单性和泛化能力的同时,允许一些错误的分类。
另外,当线性不可分问题无法通过低维空间的超平面进行划分时,可以使用核函数。核函数可以将样本映射到高维特征空间,使得非线性问题在高维空间中变得线性可分。常用的核函数有线性核、多项式核、高斯径向基函数(RBF)核等。
这是可分:
这是不可分:
2.3最大间隔与分类
当超平面(决策分界面)方程等于0的时候,x便是位于超平面上的点,而f(x)大于0的点对应 y=1 的数据点,f(x)小于0的点对应y=-1的点。 也就是正样本在分隔超平面“上方”,负样本在分隔超平面”下方“。这也就意味着超平面函数需要等于0,SVM就是能将两类数据正确划分并且间隔最大的直线。
2.32软间隔与硬间隔
在SVM中,硬间隔(hard margin)和软间隔(soft margin)是用于处理线性不可分问题的两种方法。
硬间隔SVM只适用于线性可分问题,即存在一个超平面能够完全将不同类别的样本正确地分开。硬间隔SVM的目标是要找到一个最优的超平面,使得所有的样本都满足约束条件,即正样本位于超平面一侧,负样本位于另一侧,并且不存在任何样本位于超平面上或距离超平面非常接近。
然而,在实际问题中,很多数据集是线性不可分的,即无法通过一个超平面完全将不同类别的样本分开。这时就需要引入软间隔SVM。
软间隔SVM允许一些样本位于超平面的边界区域或错误分类。它通过引入松弛变量(slack variable)来实现容错能力。松弛变量表示了样本与其真实分类之间的误差程度,可以理解为对错误分类的惩罚项。软间隔SVM的目标是找到一个最优的超平面和最小化松弛变量,同时使得间隔尽可能大。
在软间隔SVM中,通过控制一个正则化参数C来平衡间隔的大小和错误分类的容忍度。较小的C值会允许更多的错误分类,使得决策边界更加平滑;而较大的C值会强制分类器尽可能正确分类所有样本,可能导致过拟合。
2.4线性可分支持向量机对偶算法
首先,我们从支持向量机的原始优化问题开始。对于线性可分支持向量机,我们要解决如下优化问题:
原始问题 (Primal problem):
约束条件 (Constraints):
为了使用拉格朗日对偶性,我们首先引入拉格朗日乘子α_i
(对每个约束条件一个)以及广义拉格朗日函数:
广义拉格朗日函数 (Lagrangian):
其中α
是一个非负的拉格朗日乘子向量。
接下来,我们计算关于w
和b
的拉格朗日函数的梯度,令它们为零。这样我们就可以消去w
和b
,将原始问题转化为对偶问题。
求解关于w
和b
的梯度:
得到:
从而得出:
将以上结果代回拉格朗日函数,我们得到对偶问题:
约束条件:
以及
2.5核函数
基本思想:
SVM核函数是用于处理非线性问题的一种技术。其基本思想是将低维输入空间中的样本通过非线性映射转换到高维特征空间,使得在高维特征空间中的样本可以通过线性超平面进行有效的分割。
核函数的作用是在不显式计算高维特征空间的情况下,隐式地将样本映射到高维空间。这样可以避免直接计算高维特征空间的复杂性,而只需要在低维空间中进行计算。
2.51 Mercer定理(充分非必要)
只要对称函数值所对应的核矩阵半正定, 则该函数可作为核函数.
2.52常用的核函数
三、SVM的实现步骤
3.1数据预处理
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.svm import SVC
# 加载数据集
iris = load_iris()
X = iris.data[:, :2] # 使用所有的特征
y = iris.target
3.2划分训练集和测试集
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)
3.3定义 SVM 模型
# 定义SVM模型
svm = SVC(kernel='rbf', C=1.0)
svm.fit(X_train, y_train)
3.4模型训练与预测与结果可视化
# 绘制散点图
def plot_scatter(X, y):
plt.scatter(X[y==0][:, 0], X[y==0][:, 1], color='red', marker='o', label='Setosa')
plt.scatter(X[y==1][:, 0], X[y==1][:, 1], color='blue', marker='x', label='Versicolor')
plt.scatter(X[y==2][:, 0], X[y==2][:, 1], color='green', marker='s', label='Virginica')
plt.xlabel('Sepal length')
plt.ylabel('Sepal width')
plt.legend(loc='upper right')
plt.show()
# 可视化训练集
plot_scatter(X_train, y_train)
# 可视化测试集和决策边界
def plot_decision_boundary(model, X, y):
h = 0.02 # 网格步长
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
Z = model.predict(np.hstack((xx.ravel()[:, np.newaxis], yy.ravel()[:, np.newaxis])))
Z = Z.reshape(xx.shape)
plt.contourf(xx, yy, Z, alpha=0.8)
plt.scatter(X[:, 0], X[:, 1], c=y, edgecolors='k', cmap=plt.cm.Paired)
plt.xlabel('Sepal length')
plt.ylabel('Sepal width')
plt.title('SVM Decision Boundary')
plt.show()
# 可视化测试集和决策边界
plot_decision_boundary(svm, X_test, y_test)
3.5输出结果
四、实验总结
本次实验主要是使用SVM模型对鸢尾花数据集进行分类,并使用可视化的方法展示训练集、测试集和决策边界的情况。
首先,通过加载数据集得到特征向量X和目标变量y,并将其划分为训练集和测试集(70%的数据作为训练集)。
然后,定义了一个SVM模型,使用径向基函数核(kernel='rbf')并设置C=1.0。径向基函数核常用于处理非线性问题,并且具有一定的容错能力。同时,C参数控制了模型的错分惩罚,C越大则惩罚越强,可能会导致过拟合。
接下来,使用plot_scatter函数可视化训练集,其中按照目标变量y的不同取值对应不同的颜色和标记。同时,通过legend函数添加图例,方便展示。
最后,使用plot_decision_boundary函数可视化测试集和决策边界。该函数首先根据X的范围定义了网格点的坐标,然后使用SVM模型进行预测,得到对应的决策边界。最后,将预测结果和测试集的实际取值进行比较,并绘制出来。其中,plt.contourf函数用于绘制等高线区域,由于SVM分类是一个二分类问题,因此使用cmap=plt.cm.Paired来指定颜色映射。
在实验中数据集不平衡:如果训练集和测试集中的样本数量差异较大,可能会导致模型的性能下降。因此,在实验中需要进行合理的样本划分和调整,以保证数据集的平衡性。