支持向量机
一.支持向量机
支持向量机介绍
支持向量机(Support Vector Machine,SVM)是一种强大的监督式学习算法,常用于分类和回归分析。它在许多机器学习任务中都表现出色,尤其在具有复杂边界和高维特征空间的数据集上效果显著。经常用在二分类等问题当中。SVM 还可以用于回归分析,即支持向量回归(Support Vector Regression,SVR)。与分类不同,SVR 试图找到一个超平面,使得样本点与该超平面的距离尽可能小,同时还要保持尽可能多的样本点在超平面的间隔之内。
工作原理
SVM 的核心思想是在特征空间中找到一个超平面,能够将不同类别的样本点正确地分开。在二维空间中,这个超平面就是一条直线;在更高维空间中,它可以是一个平面、超平面或者更高维的结构。SVM 最大化了样本到超平面的间隔,使得分类的鲁棒性和泛化能力更强。
支持向量机通俗理解
其实支持向量机可以这样理解:
如图所示的三条黑线,均可以对样本进行分类达到效果,但是军=都不是最佳的方案。我们可以这样理解支持向量机,就是把图中的要分类之间的点看成地雷,要让一排排的军队安全的通过这里,是不是要找到一条最优化的路线,使得军队距离最近距离的地雷是最远的,这个过程就是支持向量机的理解。
支持向量机优缺点
支持向量机是一种用于分类和回归分析的监督式学习模型,其优点和缺点如下:
优点:
(1)在高维空间中具有较好的泛化能力,可以处理高维数据;
(2)可以处理非线性数据,借助核函数可以将数据映射到更高维的空间进行分类;
(3)在数据较少的情况下表现较好,因为SVM利用支持向量进行决策,不需要依赖整个数据集;
(4)对异常值的鲁棒性较强,并且在较噪声的情况下表现较好。
缺点:
(1)对超大规模数据集的训练不太友好,由于其时间复杂度为O(n^3),一旦数据集规模变大,训练时间可能会非常长;
(2)对缺失数据敏感,需要对数据进行预处理以处理缺失值;
(3)对于多类分类问题需要进行多次二进制分类,比较麻烦;
(4)对参数的选择和核函数的选择比较敏感,需要通过交叉验证等方法进行调参。
二.支持向量机相关概念
支持向量
支持向量指的是在支持向量机分类中,那些离超平面最近的样本点。它们是对构建超平面有重要影响的样本点,因为它们决定了超平面的位置和方向。更具体地说,支持向量是在最大化间隔的过程中起作用的,它们是距离超平面最近的点,这些点的法向量与超平面的切线相平行。支持向量机的训练过程就是找到这些支持向量,并根据它们来确定最佳的超平面,使得间隔最大化。在分类任务中,支持向量机的决策边界是由这些支持向量所确定的。持向量在支持向量机算法中发挥了关键作用,它们是决定分类边界的重要因素。通过选择合适的支持向量,支持向量机能够构建出一个有效的分类器,并且对于新的未见过的数据也能有很好的泛化能力
如图中所示的圈起来的X和圈起来的—就是支持向量。
距离
在支持向量机(SVM)中,距离是一个重要的概念,它指的是样本点到超平面的距离。在SVM中,距离的计算有多种不同的方式,具体取决于所使用的核函数和超平面的定义。
在线性SVM中,超平面可以用一个线性方程表示: w T x − b = 0 \mathbf{w}^T\mathbf{x} - b = 0 wTx−b=0,其中 w \mathbf{w} w是法向量, b b b是偏置项。样本点到超平面的距离可以通过将样本点带入超平面方程计算得到。
在非线性SVM中,通过核函数将数据映射到高维空间,超平面在高维空间中进行定义。样本点到超平面的距离同样可以在高维空间中进行计算,但通常使用的是核函数的形式,而不是直接在高维空间中计算。
支持向量是离超平面最近的样本点,它们的距离通常被称为间隔(margin)。SVM的目标是最大化间隔,即最大化支持向量到超平面的距离,同时保持所有样本点被正确分类。这样做的目的是为了提高模型的泛化能力,使其在未知数据上的性能更好。
软间隔
在标准的支持向量机中,我们希望找到一个最大间隔的超平面,使得所有的训练样本都正确地被分开。但是,在现实问题中,数据往往是有噪声的,或者有一些离群点,这些情况下可能会导致标准的支持向量机模型无法完美地将所有的样本正确分类。
软间隔允许一些样本点位于超平面的错误一侧,从而允许一定程度上的分类错误。软间隔支持向量机的优化目标是最大化间隔的同时,尽量减少分类错误的数量。这样做的目的是为了提高模型的泛化能力,使其在未知数据上的性能更好。
软间隔通过引入一个惩罚参数(通常记为 C),来控制分类错误的惩罚程度。C 值越大,对分类错误的惩罚越严重,模型就会更倾向于选择更小的间隔来确保更少的分类错误;而C 值越小,对分类错误的惩罚越轻,模型就会更倾向于选择更大的间隔,允许更多的分类错误。
这里C就是正则化的参数。
核函数
核函数(kernel function)是用于将输入数据映射到高维特征空间的一种技术。在许多情况下,原始的数据可能不是线性可分的,即使在高维空间中也无法找到一个超平面来完美地分隔数据。核函数的作用就是通过将数据映射到更高维的特征空间,使得数据在新的特征空间中变得线性可分。
常见的核函数有:线性核函数,高斯核函数,多项式核函数等。
三.支持向量机推导过程
目标函数推导
通俗解释:找到一个或一组w和b使得距离最近的那个雷最远。将点到直线的距离化简得到:
优化目标:
又因为min里面的函数恒大于等于1,此时要使得外式子成立,就是求:
拉格朗日乘子法求解
最后得到了:
最终求解的决策方程就是:
四.代码实现
准备数据
使用sklearn.datasets模块中的make_blobs函数来生成模拟数据集:
X,y=datasets.make_blobs(n_samples=150,centers=2,random_state=6)
看看数据:
创建SVM类
构建SVM类进行数据的训练模型:
class LinearSVM:
def __init__(self,learning_rate=0.0001,lambda_param=0.1,n_iters=1000):
self.learning_rate=learning_rate#学习率
self.lambda_param=lambda_param#正则化参数
self.n_iters=n_iters#迭代次数
self.w=None
self.b=None
def fit(self,X,y):#fit方法用于模型训练
n_samples,n_features=X.shape
y_ =np.where(y<=0,-1,1)
#初始化权重和偏置为0
self.w=np.zeros(n_features)
self.b=0
for _ in range(self.n_iters):
for idx,x_i in enumerate(X):
condition = y_[idx]*(np.dot(x_i,self.w)-self.b)>=1 #遍历每个样本,检查分类条件
if condition:
self.w-=self.learning_rate*(2*self.lambda_param*self.w)#如果样本被正确分类且在正确的间隔外,仅通过正则化来更行权重(防过拟合)
else:
self.w-=self.learning_rate*(2*self.lambda_param*self.w-np.dot(x_i,y_[idx]))#样本被错误分类或者在间隔内,则权重更新包括误差项,同时更新偏置,使样本在未来被正确分类
self.b-=self.learning_rate*y_[idx]
def predict(self,X):
Linear_output=np.dot(X,self.w)-self.b
return np.sign(Linear_output)
可视化函数
def plot_hyperplane(X,y,w,b):
plt.scatter(X[:,0],X[:,1],marker='o',c=y,s=100,edgecolors='k',cmap='winter')
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=(np.dot(xy,w)-b).reshape(XX.shape)
ax.contour(XX,YY,Z,colors='k',levels=[-1,0,1],alpha=0.5,linestyles=['--','-','--'])
plt.show()
解释:plt.scatter(X[:,0],X[:,1],marker='o',c=y,s=100,edgecolors='k',cmap='winter'): 这行代码用于绘制数据点的散点图。X 是特征矩阵,y 是标签向量,散点的颜色由 y 决定,cmap='winter'指定了颜色映射。每个数据点的坐标是 X[:,0] 和 X[:,1]。
ax=plt.gca(): 获取当前的坐标轴对象。
xlim=ax.get_xlim(): 获取 x 轴的取值范围。
ylim=ax.get_ylim(): 获取 y 轴的取值范围。
xx=np.linspace(xlim[0],xlim[1],30): 在 x 轴的取值范围内生成 30 个等间距的值。
yy=np.linspace(ylim[0],ylim[1],30): 在 y 轴的取值范围内生成 30 个等间距的值。
YY,XX=np.meshgrid(yy,xx): 生成一个网格矩阵,XX 和 YY 是这个网格矩阵的 x 坐标和 y 坐标。
xy=np.vstack([XX.ravel(),YY.ravel()]).T: 将 XX 和 YY 拉平成一维数组,然后将它们堆叠起来,得到二维坐标点。
Z=(np.dot(xy,w)-b).reshape(XX.shape): 计算超平面的数学表达式,即
𝑤𝑇𝑥−𝑏 的值。这里的 w 是超平面的法向量,b 是偏置项。
ax.contour(XX,YY,Z,colors='k',levels=[-1,0,1],alpha=0.5,linestyles=['--','-','--']): 绘制等高线图,用于表示超平面。等高线的数值分别是 -1、0 和 1,对应着超平面两侧的边界。
运行结果
可见参数C为默认值时候,模型的容错率较高, 而造成这样的结果是参数lamda_param设置不当,导致模型对噪声和异常值过于敏感,从而将一些本应在间隔之外的数据点错误地分类到间隔之内。
于是我们修改参数C,重新测试:
svm1=LinearSVM1(C=200)
结果:
运行结果分析
(1)当C较小时,正则化强度较大,允许一些数据点分类错误,模型的容错能力较强,这会导致模型对误分类的惩罚较小。因此,模型可能会选择更多的支持向量,并且决策边界可能会更加平滑,因为它会尝试找到一个具有较大间隔的决策边界,即使这意味着某些样本会被错误分类。这通常会导致更高的偏差和较低的方差,因为模型可能更偏向于整体趋势,而不是单个数据点。
(2)当C=200较大时,正则化强度较小,模型会更加关注于正确地分类所有样本,这意味着决策边界的间隔较小,这通常会导致较低的偏差和较高的方差,因为模型可能会过度拟合训练数据,对噪声或异常值更加敏感。模型可能会更加关注每个数据点的分类,分类边界可能会更加严格,容错能力降低。
小结
在使用SVM之前,需要对数据进行预处理。包括数据清洗、特征选择、特征缩放等操作。特别是对于非线性可分的数据,可能需要使用核函数来将数据映射到更高维的空间。 SVM有不同的核函数和超参数,需要根据具体的问题选择合适的模型。例如,线性核函数适用于线性可分的数据,而高斯核函数适用于非线性可分的数据。对于二维或三维的数据,可以将决策边界可视化,以便直观地理解模型的分类效果。