目录

一、支持向量机概述

1.概念

2.基本原理

3.优缺点

二、支持向量机相关概念介绍

1.间隔与支持向量

2.对偶问题

3.核函数

4.软间隔与正则化

5.支持向量回归

6.核方法

三、支持向量机具体实现

1.过程分析

2.具体代码实现

3.运行结果分析

四、实验总结


一、支持向量机概述

1.概念

支持向量机(Support Vector Machine,SVM)是一种监督学习算法,用于进行分类和回归分析。其基本原理是找到一条能够将不同类别的数据分隔开的最优超平面。支持向量机能够处理线性可分的数据集,也可以通过使用核函数将数据映射到更高维的空间来处理非线性数据。支持向量机在很多领域都有广泛的应用,如文本分类、图像识别、生物信息学等。

2.基本原理

支持向量机的基本原理是在高维空间中寻找一个超平面,能够将不同类别的数据分隔开来。这个超平面可以使得两个类别之间的间隔最大化,从而提高分类的准确性。支持向量机的目标是找到一个最优的决策边界或超平面,使得不同类别的样本点距离该超平面的距离最大化。这些最接近决策边界的样本点被称为支持向量,它们是用来拟合最优超平面的关键点。支持向量机在处理非线性问题时,可以使用核函数将原始输入空间映射到一个更高维的特征空间,从而使得数据在新的空间中变得线性可分。

3.优缺点

支持向量机是一种用于分类和回归分析的监督式学习模型,其优点和缺点如下:

优点:
(1)在高维空间中具有较好的泛化能力,可以处理高维数据;
(2)可以处理非线性数据,借助核函数可以将数据映射到更高维的空间进行分类;
(3)在数据较少的情况下表现较好,因为SVM利用支持向量进行决策,不需要依赖整个数据集;
(4)对异常值的鲁棒性较强,并且在较噪声的情况下表现较好。

缺点:
(1)对超大规模数据集的训练不太友好,由于其时间复杂度为O(n^3),一旦数据集规模变大,训练时间可能会非常长;
(2)对缺失数据敏感,需要对数据进行预处理以处理缺失值;
(3)对于多类分类问题需要进行多次二进制分类,比较麻烦;
(4)对参数的选择和核函数的选择比较敏感,需要通过交叉验证等方法进行调参。

二、支持向量机相关概念介绍

1.间隔与支持向量

(1)超平面

在SVM中,数据被看作是在高维空间中的点,而分类的目标是找到一个能够将不同类别的点分隔开的超平面。这个超平面被选为离支持向量(距离最近的数据点)最远的位置,使得两类数据点之间的间隔最大化。

在支持向量机中,超平面可由以下方程表示:w^{T}x+b=0,

其中,w=(w1,w2,...,wd)是超平面的法向量,决定了超平面的方向,b是位移项,决定了超平面与原点之间的距离,x是样本点。显然,划分超平面可被法向量w和位移b确定,我们将其记作(w,b),则样本空间中任意点x到超平面(w,b)的距离可写为r=\frac{|w^{T}x+b|}{||w||}.

超平面将样本空间分为两个部分,一个在超平面的一侧,另一个在超平面的另一侧。我们的目标是找到一个超平面,使得不同类别的样本点尽可能地分开,并且使得边界尽可能地大。在支持向量机中,支持向量是那些与超平面最近的样本点,它们决定了超平面的位置。支持向量机的训练过程是通过寻找最大化边界的方式来优化超平面参数的过程。

(2)间隔与支持向量

假设超平面(w,b)能将训练样本正确分类,即对于(xi,yi)属于D,若yi =+1,则有w^{T}x_{i}+b>0;若 yi =-1,则有w^{T}x_{i}+b<0.令


如图所示,距离超平面最近的这几个训练样本点使该式的等号成立,它们被称为"支持向量",两个异类支持向量到超平面的距离之和为\gamma =\frac{2}{||w||},它被称为"间隔".

要找到最大间隔的超平面,我们需要找到能满足上式约束的参数w和b,使得γ最大,即

max_{w,b}\frac{2}{||w||} s.t.y_{i}(w^{T}x_{i}+b)\geq 1,i=1,2,...,m.(1)

为了最大化间隔,我们需要最大化||w^{-1}||,这等价于最小化||w||^{2},于是,式(1)可重写为

min_{w.b}\frac{1}{2}||w||^{2} ,s.t.y_{i}(w^{T}x_{i}+b)\geq 1,i=1,2,..,m.(2)

这就是支持向量机的基本型。

2.对偶问题

我们希望求解式(2)来得到大间隔划分超平面所对应的模型f(x)=w^{T}x+b,(3)

其中w和b是模型参数。我们注意到式(2)本身是一个凸二次规划问题,能直接用现成的优化算法包求解,但我们可以有更高效的办法。对式(2)使用拉格朗日乘子法可得到其“对偶问题”。具体来说,对式(2)的每条约束添加拉格朗日乘子\alpha _{i}\geq 0,则该问题的拉格朗日函数可写为

L(w,b, \alpha )=\frac{1}{2}||w||^{2}+\sum_{i=1}^{m}\alpha _{i}(1-y_{i}(w^{T}x_{i}+b)),(4)

其中α=(α1;α2;...;αm),令L(w,b,α)对w和b的偏导为零可得

w=\sum_{i=1}^{m}\alpha _{i}y_{i}x_{i},(5)   0=\sum_{i=1}^{m}\alpha _{i}y_{i},(6)

将式(5)带入(4),即可将L(w,b,α)中的w和b消去,再考虑式(6)的约束,就得到式(2)的对偶问题max_{\alpha }\sum_{i=1}^{m}\alpha _{i}-\frac{1}{2}\sum_{i=1}^{m}\sum_{j=1}^{m}\alpha _{i}\alpha _{j}y_{i}y_{j}x_{i}^{T}x_{j},(7)

s.t.\sum_{i=1}^{m}\alpha _{i}y_{i}=0,\alpha _{i}\geq 0,i=1,2,...,m.

解出α后,求出w和b即可得到模型f(x)=w^{T}x+b=\sum_{i=1}^{m}\alpha _{i}y_{i}x_{i}^{T}x+b.(8)

从对偶问题(7)解出的αi是式(4)中的拉格朗日乘子,它恰对应着训练样本(xi,yi),注意到式(2)中有不等式约束,因此上述过程需满足KKT条件,即要求

\left\{\begin{matrix} \alpha _{i}\geqslant 0;\\ y_{i}f(x_{i})-1\geq 0; \\ \alpha _{i}(y_{i}f(x_{i})-1)=0. \end{matrix}\right.(9)

于是,对任意训练样本(xi,yi),总有αi=0或yif(xi)=1.若αi=0,则该样本将不会再式(8)的求和中出现,也就不会对f(x)有任何影响;若αi>0,则必有yif(xi)=1,所对应的样本点位于最大间隔边界上,是一个支持向量。这显示出支持向量机的一个重要性质:训练完成后,大部分的训练样本都不需保留,最终模型仅与支持向量有关。

支持向量机的对偶问题是通过对原始问题进行优化得到的另一种形式,通常在计算上更高效。它的优化目标是最大化一个拉格朗日函数,通过最大化该拉格朗日函数可以得到支持向量机的最优解。该拉格朗日函数的变量是拉格朗日乘子,通过对其进行优化可以得到支持向量机的最优超平面。对偶问题将原始问题中的优化变量从实例空间转化为特征空间,可以通过核函数来表示特征空间中的内积,从而实现在高维特征空间的计算。对偶问题的解与原始问题的解是等价的,同时对偶问题的求解可以通过简单的凸优化算法来实现。

3.核函数

核函数是支持向量机的关键概念之一,它将输入数据映射到高维空间,使得数据在高维空间中更容易被线性分割。常用的核函数包括线性核函数、多项式核函数、高斯核函数(也称为径向基函数核函数)和sigmoid核函数。不同的核函数在不同的情况下表现可能不同,需要根据具体问题选择适合的核函数。

线性核函数将数据映射到原始特征空间,适用于数据线性可分的情况;多项式核函数和高斯核函数则能处理非线性可分的数据,通过引入非线性项将数据映射到高维空间,使得数据在高维空间中更容易被分隔;sigmoid核函数则用于处理特殊的数据分布情况。我们希望样本在特征空间内线性可分,因此特征空间的好坏对支持向量机的性能至关重要,需注意的是,在不知道特征映射的形式时,我们并不知道什么样的核函数是合适的,而核函数也仅是隐式地定义了这个特征空间,于是核函数的选择成为支持向量机的最大变数。因此,我们需要选择合适的核函数和调整核函数的参数,来提高SVM模型的性能和泛化能力。在实践中,我们通常需要通过交叉验证等方法来选择最优的核函数和参数组合,以达到最佳的分类效果。

4.软间隔与正则化

(1)软间隔

支持向量机在处理线性和非线性分类问题时表现得比较出色。在实际应用中,数据通常并不总是线性可分的,即存在一些异常值或噪声数据会使得分类器性能下降。为了解决这个问题,支持向量机引入了软间隔的概念。

软间隔允许在分类过程中某些样本点位于决策边界的一侧,即允许一定程度的误分类。通过引入松弛变量和惩罚项来控制这种误分类,使得支持向量机能够更好地适应复杂数据集,并提高泛化能力。软间隔的引入使得支持向量机在处理非线性可分数据时能够更好地处理噪声和异常值,同时保持对训练集的拟合效果。在实际应用中,通过调节软间隔的参数可以平衡模型的复杂度和泛化能力,从而获得更好的分类效果。

(2)正则化

支持向量机的目标是寻找一个最优的超平面,能够对数据进行有效的分隔。而正则化是一种用于控制模型复杂度的技术,可以在支持向量机中用来避免过拟合。

支持向量机可以通过添加一个正则化项来控制模型复杂度。这个正则化项通常是一个惩罚项,用来限制模型的参数的大小。常用的正则化项包括L1正则化和L2正则化。在支持向量机中,通常使用L2正则化,通过添加一个惩罚项来限制支持向量机的权重参数,从而使模型更加泛化。正则化可以帮助防止过拟合,提高模型在新数据上的泛化能力。通过调整正则化参数的大小,可以在偏差和方差之间找到一个平衡,从而提高模型的性能。在实际应用中,正则化常常是必不可少的技术之一,用来提高机器学习模型的性能和鲁棒性。

5.支持向量回归

支持向量回归(Support Vector Regression,简称SVR)是一种基于SVM原理的回归模型,用于处理回归问题,即预测一个连续变量的值。支持向量回归使用SVM的原理,通过找到一个超平面(在回归中通常称为决策函数或回归函数)来拟合训练数据,以最小化预测误差。

假设我们给定训练样本D={(x1,y1),(x2,y2),...,(xm,ym)},yi属于R,我们希望学得一个形如式子f(x)=w^{T}x+b,的回归模型,使得f(x)与y尽可能接近,w和b是待确定的模型参数。对样本(x,y),传统回归模型通常直接基于模型输出f(x)与真实输出y之间的差别来计算损失,当且仅当f(x)与y完全相同时,损失才为零。与此不同,支持向量回归(SVR)假设我们能容忍f(x)与y之间最多有ɛ的偏差,即当f(x)与y之间的差别绝对值大于ɛ时才计算损失。如图所示,这相当于以f(x)为中心,构建了一个宽度为2ɛ的间隔带,若训练样本落入此间隔带,则认为是被预测正确的。

SVR问题可形式化为min_{w,b}\frac{1}{2}||w||^{2}+C\sum_{i=1}^{m}\iota _{\epsilon }(f(x_{i})-y_{i}),

其中C为正则化常数,\iota _{\epsilon }是不敏感损失函数。

6.核方法

核方法也称为内核函数,是用于模式分析的不同类型算法的集合,它们可以将数据作为输入,并将其转换为所需的形式,使得线性分类器可以解决非线性问题。核方法是支持向量机中的一种重要技术,它允许SVM在非线性情况下学习并且更加灵活。

核方法的基本思想是将输入数据从原始空间映射到高维特征空间中,使得数据在新空间中变得线性可分或者更容易分隔。常用的核函数包括线性核、多项式核、高斯核等。这些核函数能够将原始空间中的数据映射到无限维的特征空间,从而提高分类的准确性。通过核方法,支持向量机可以在处理非线性数据时表现出色,并且可以更好地拟合复杂模式。然而,需要注意的是选择合适的核函数以及调优核函数的超参数是关键的一步,否则可能会导致过拟合或欠拟合的情况发生。核方法为支持向量机提供了处理非线性数据的能力,使得SVM在实际应用中更加灵活和强大。

三、支持向量机具体实现

我们可以通过随机数生成一定数量的样本数据集,使用python代码具体实现支持向量机,通过给出的数据集来分类二维数据集,并可视化不同C值(正则化参数)对分类边界和支持向量的影响,具体实现过程如下。

1.过程分析

(1)生成二维数据集

np.random.seed(0)
X = np.r_[np.random.randn(30, 2) - [2, 2], np.random.randn(30, 2) + [2, 2]]
Y = [0] * 30 + [1] * 30

(2)训练支持向量机模型

def train_svm_model(C):
    svc = svm.SVC(kernel='linear', C=C)
    svc.fit(X, Y)
    return svc

(3)可视化分类边界和支持向量

def plot_decision_boundary(svc, C):
    plt.scatter(X[:, 0], X[:, 1], c=Y, cmap=plt.cm.coolwarm, s=30)

    # plot the decision function
    ax = plt.gca()
    xlim = ax.get_xlim()
    ylim = ax.get_ylim()

    # create grid to evaluate model
    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 = svc.decision_function(xy).reshape(XX.shape)

    # plot decision boundary and margins
    plt.contour(XX, YY, Z, colors='k', levels=[-1, 0, 1], alpha=0.5, linestyles=['--', '-', '--'])

    # plot support vectors
    plt.scatter(svc.support_vectors_[:, 0], svc.support_vectors_[:, 1], s=100, linewidth=1, facecolors='none', edgecolors='k')

    plt.title('C = {}'.format(C))
    plt.show()

(4)设置不同的C值训练SVM模型

C_values = [0.1, 100,1000]
    for c in C_values:
        svc = train_svm_model(c)
        plot_decision_boundary(svc, c)
        predict_and_evaluate(svc, X_test, Y_test)

2.具体代码实现

import numpy as np  # 导入NumPy库,用于数值计算
import matplotlib.pyplot as plt  # 导入matplotlib的pyplot模块,用于绘图
from sklearn import svm  # 从scikit-learn库中导入SVM模块
from sklearn.metrics import accuracy_score  # 导入准确率计算函数
# 生成二维数据集
# 设置随机数种子,以确保结果的可重复性
np.random.seed(0)
# 生成两组正态分布的数据点,每组30个,一组中心在(-2, -2),另一组中心在(2, 2)
X = np.r_[np.random.randn(30, 2) - [2, 2], np.random.randn(30, 2) + [2, 2]]
# 为数据点分配标签,前30个为0,后30个为1
Y = [0] * 30 + [1] * 30

# 训练支持向量机模型
def train_svm_model(C):
    # 创建一个SVM分类器实例,使用线性核,并设置正则化参数C
    svc = svm.SVC(kernel='linear', C=C)
    # 使用训练数据和标签拟合模型
    svc.fit(X, Y)
    # 返回训练好的SVM模型
    return svc
# 可视化分类边界和支持向量
def plot_decision_boundary(svc, C):
    # 绘制数据点,使用不同的颜色表示不同的类别
    plt.scatter(X[:, 0], X[:, 1], c=Y, cmap=plt.cm.coolwarm, s=30)
    # 获取当前坐标轴的x和y轴的范围
    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)
    # 使用meshgrid生成网格点
    YY, XX = np.meshgrid(yy, xx)
    # 将网格点转换为模型可以接受的二维数组格式
    xy = np.vstack([XX.ravel(), YY.ravel()]).T
    # 计算网格点上的决策函数值
    Z = svc.decision_function(xy).reshape(XX.shape)
    # 绘制决策边界和间隔
    plt.contour(XX, YY, Z, colors='k', levels=[-1, 0, 1], alpha=0.5, linestyles=['--', '-', '--'])
    # 绘制支持向量
    plt.scatter(svc.support_vectors_[:, 0], svc.support_vectors_[:, 1], s=100, linewidth=1, facecolors='none',
                edgecolors='k')
    # 设置标题并显示图形
    plt.title('C = {}'.format(C))
    plt.show()

# 输出分类结果和准确率
def predict_and_evaluate(svc, X_test, Y_test):
    # 使用模型对测试集进行预测
    Y_pred = svc.predict(X_test)
    # 计算准确率并打印
    accuracy = accuracy_score(Y_test, Y_pred)
    print('分类准确率:', accuracy)
# 主函数
if __name__ == "__main__":
    # 将数据集分割为训练集和测试集
    from sklearn.model_selection import train_test_split
    X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.3, random_state=0)
    # 为不同的C值训练SVM模型
    C_values = [0.1, 100, 1000]
    for c in C_values:
        # 训练SVM模型
        svc = train_svm_model(c)
        # 可视化分类边界和支持向量
        plot_decision_boundary(svc, c)
        # 预测并评估模型性能
        predict_and_evaluate(svc, X_test, Y_test)

3.运行结果分析

(1)当C=0.1时,正则化强度较大,允许一些数据点分类错误,模型的容错能力较强,这会导致模型对误分类的惩罚较小。因此,模型可能会选择更多的支持向量,并且决策边界可能会更加平滑,因为它会尝试找到一个具有较大间隔的决策边界,即使这意味着某些样本会被错误分类。这通常会导致更高的偏差和较低的方差,因为模型可能更偏向于整体趋势,而不是单个数据点。

(2)当C=100时,正则化强度较小,模型会更加关注于正确地分类所有样本,这意味着决策边界的间隔较小,这通常会导致较低的偏差和较高的方差,因为模型可能会过度拟合训练数据,对噪声或异常值更加敏感。模型可能会更加关注每个数据点的分类,分类边界可能会更加严格,容错能力降低。

(3)当C=1000时,正则化程度更小,模型会更倾向于选择较小的间隔,模型会尽力使得所有数据点都被正确分类,分类边界可能会非常严格,对异常点敏感。

(4)不同C值下的分类准确率如下:

在这个特定的例子中,由于数据集是线性可分的,并且没有噪声或异常值,因此C值的变化可能不会显著影响分类准确率。然而,在实际情况中,当数据集包含噪声或异常值时,C值的选择可能会对分类准确率产生显著影响。较小的C值可能会导致较低的准确率,因为模型可能会忽略一些难以分类的样本;而较大的C值可能会导致过拟合,从而降低在测试集上的准确率。通过可视化不同C值下的决策边界和支持向量,我们可以直观地了解C值对模型行为的影响。可以观察到随着C值的增加,决策边界变得更加紧密地围绕训练数据,支持向量的数量减少。

四、实验总结

支持向量机是一种强大的机器学习算法,在实验中我们可以通过选择合适的数据集、特征选择、参数调优等方法来提高模型的性能,从而实现更好的分类或预测效果。通过实验,我们可以更好地理解支持向量机算法的原理和应用。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐