支持向量机SVM简单介绍及代码实践

引言

在众多机器学习算法中,支持向量机(Support Vector Machine, SVM)以其出色的泛化能力而著称。SVM不仅在理论上具有坚实的数学基础,而且在实践中也显示出了卓越的性能。本文将深入探讨SVM的工作原理、关键概念、不同变体以及实际应用。

支持向量机的数学基础

间隔与超平面

SVM的核心概念是间隔(margin)和超平面(hyperplane)。在二维空间中,超平面是一个线,而在更高维空间中,它是一个平面或更一般的线性边界。间隔是超平面到最近点(支持向量)的距离。SVM的目标是找到一个超平面,使得两个类别的数据点被分隔开,并且这个间隔最大化

线性可分与非线性可分

  • 线性可分:当数据点可以通过一个线性超平面完美分隔时,数据被认为是线性可分的。
  • 非线性可分:当数据点不能通过线性超平面分隔时,SVM通过引入核函数将数据映射到更高维的空间,在这个新空间中寻找线性分隔的可能性。

核函数

核函数是SVM处理非线性问题的关键。它允许SVM在高维空间中计算数据点的内积,而无需显式地进行高维空间的映射。常见的核函数包括:

  • 线性核(Linear Kernel) 线性核实际上是不使用核技巧的,它直接在原始特征空间中计算点积。对于两个数据点 𝑥𝑖和 𝑥𝑗,线性核函数 𝐾定义为:K(\mathbf{x}_i, \mathbf{x}_j) = \mathbf{x}_i \cdot \mathbf{x}_j 这相当于在特征空间中计算两个向量的点积。

  • 多项式核(Polynomial Kernel) 多项式核将数据映射到更高维的特征空间,然后计算点积。多项式核函数定义为: K(\mathbf{x}_i, \mathbf{x}_j) = (\gamma \mathbf{x}_i \cdot \mathbf{x}_j + r)^d其中 𝛾是一个参数,𝑟是偏置项,𝑑是多项式的度数。

  • 径向基函数(RBF,Radial Basis Function Kernel) RBF核,也称为高斯核,是一种非常流行的核函数,它测量两个数据点之间的欧几里得距离。RBF核函数定义为: K(\mathbf{x}_i, \mathbf{x}_j) = \exp\left(-\frac{\|\mathbf{x}_i - \mathbf{x}_j\|^2}{2\sigma^2}\right)其中 𝜎是一个参数,控制了核的宽度。

  • Sigmoid核 Sigmoid核类似于逻辑回归中的Sigmoid函数,可以用于模拟神经网络。Sigmoid核函数定义为: K(\mathbf{x}_i, \mathbf{x}_j) = \tanh(\gamma \mathbf{x}_i \cdot \mathbf{x}_j + r)其中 𝛾和 𝑟是参数。

  • 拉普拉斯核(Laplace Kernel) 拉普拉斯核是RBF核的一个变体,它使用拉普拉斯分布而不是高斯分布。拉普拉斯核函数定义为: K(\mathbf{x}_i, \mathbf{x}_j) = \exp\left(-\frac{\|\mathbf{x}_i - \mathbf{x}_j\|_1}{\sigma}\right) 其中 ∥⋅∥1表示L1范数(曼哈顿距离),𝜎是一个参数。

  • Chebyshev多项式核(Chebyshev Polynomial Kernel) Chebyshev核是一种特殊的多项式核,它使用Chebyshev多项式来定义核函数: K(\mathbf{x}_i, \mathbf{x}_j) = T_d(\cos(\theta))其中 𝑇𝑑是Chebyshev多项式,𝜃是两个向量的夹角

SVM的优化问题

SVM的优化问题可以通过拉格朗日乘子法解决。在优化过程中,我们寻找一组拉格朗日乘子,这些乘子对应于每个数据点,并且决定了哪些点会成为支持向量。优化问题的目标是最大化间隔,同时最小化分类误差。

软间隔与正则化

在现实世界中,数据往往包含噪声和异常值。软间隔允许一些数据点违反间隔规则,即它们可以位于间隔内或间隔的对面。通过引入正则化参数C,SVM可以在间隔最大化和分类误差之间进行权衡。C值较大时,模型对误分类的惩罚较重,可能导致过拟合;C值较小时,模型对间隔的重视程度增加,但可能会增加误分类的风险。

SVM的变体

C-SVM

C-SVM是最基本的SVM形式,通过参数C控制软间隔的大小。

ν-SVM

ν-SVM是另一种变体,它使用参数ν来控制不满足间隔要求的数据点的比例。

One-Class SVM

One-Class SVM用于异常检测,它只使用一个类别的数据来训练模型。

Support Vector Regression (SVR)

SVR是SVM的回归版本,用于预测连续的数值。

实际应用案例

SVM在多个领域都有广泛的应用,以下是一些例子:

  • 图像识别:SVM可以用于识别图像中的物体或场景。
  • 生物信息学:在基因表达数据中识别疾病标记。
  • 文本分类:SVM可以用于新闻文章或社交媒体帖子的情感分析。
  • 异常检测:在金融交易或网络安全中检测异常行为。

实现与评估

在Python中,Scikit-learn库提供了SVM的实现。以下是一个使用Scikit-learn实现SVM的示例:

 SVM实现部分:

class SVM:
    def __init__(self, lr=0.001, lambda_param=0.01, num_step=1000):

        self.lr = lr
        self.lambda_param = lambda_param
        self.num_step = num_step
        self.w = None
        self.b = None
 
    def fit(self, X, y):
        #初始化权重和偏置
        num_samples, num_features = X.shape
        self.w = np.zeros(num_features)
        self.b = 0
 
        #将标签从 0/1 转换为 -1/1。SVM 要求标签为 -1 和 1。
        y_ = np.where(y <= 0, -1, 1)
 
        #梯度下降
        for _ in range(self.num_step):
            for idx, x_i in enumerate(X):
                #检查样本是否满足分类条件,更新权重和偏置
                if y_[idx] * (np.dot(x_i, self.w) - self.b) >= 1:
                    self.w -= self.lr * (2 * self.lambda_param * self.w)
                else:
                    self.w -= self.lr * (2 * self.lambda_param * self.w - np.dot(x_i, y_[idx]))
                    self.b -= self.lr * y_[idx]
 
    def predict(self, X):
        pred = np.dot(X, self.w) + self.b
        return np.sign(pred)

 生成数据集:

def create_data():
    from sklearn.datasets import make_blobs
    X, y = make_blobs(n_samples=50, centers=2, random_state=45)
    y = np.where(y == 0, -1, 1)
    return X, y

 

完整代码

import numpy as np
import matplotlib.pyplot as plt

def create_data():
    from sklearn.datasets import make_blobs
    X, y = make_blobs(n_samples=50, centers=2, random_state=45)
    y = np.where(y == 0, -1, 1)
    return X, y

def show_data(X, y):
    X1, X2 = X[y==-1], X[y==1]
    print(X1)
    plt.scatter(X1[:, 0], X1[:, 1], color='blue')
    plt.scatter(X2[:, 0], X2[:, 1], color='red')
    plt.show()

def visualize_svm(X, y, svm):
    def get_hyperplane_value(x, w, b, offset):
        return (-w[0] * x + b + offset) / w[1]

    plt.scatter(X[:, 0], X[:, 1], marker='o', c=y)

    ax = plt.gca()
    xlim = ax.get_xlim()
    ylim = ax.get_ylim()

    x = np.linspace(xlim[0], xlim[1], 30)
    y_pred = get_hyperplane_value(x, svm.w, svm.b, 0)
    margin_plus = get_hyperplane_value(x, svm.w, svm.b, 1)
    margin_minus = get_hyperplane_value(x, svm.w, svm.b, -1)

    plt.plot(x, y_pred, 'k-')
    plt.plot(x, margin_plus, 'k--')
    plt.plot(x, margin_minus, 'k--')

    plt.legend()
    plt.show()

class SVM:
    def __init__(self, lr=0.001, lambda_param=0.01, num_step=1000):

        self.lr = lr
        self.lambda_param = lambda_param
        self.num_step = num_step
        self.w = None
        self.b = None

    def fit(self, X, y):
        #初始化权重和偏置
        num_samples, num_features = X.shape
        self.w = np.zeros(num_features)
        self.b = 0


        y_ = np.where(y <= 0, -1, 1)


        for _ in range(self.num_step):
            for idx, x_i in enumerate(X):

                if y_[idx] * (np.dot(x_i, self.w) - self.b) >= 1:
                    self.w -= self.lr * (2 * self.lambda_param * self.w)
                else:
                    self.w -= self.lr * (2 * self.lambda_param * self.w - np.dot(x_i, y_[idx]))
                    self.b -= self.lr * y_[idx]

    def predict(self, X):
        pred = np.dot(X, self.w) + self.b
        return np.sign(pred)


X, y = create_data()
show_data(X, y)
svm = SVM()
svm.fit(X, y)
visualize_svm(X, y, svm)

 分类结果:

结论

支持向量机是一种灵活且强大的机器学习算法,它通过最大化间隔和使用核技巧,能够有效地处理线性和非线性问题。SVM的不同变体和参数调整使其能够适应各种复杂的数据集和应用场景。通过适当的实现和评估,SVM可以成为解决分类和回归问题的强大工具。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值