机器学习实验——支持向量机(SVM)

目录

一、支持向量机

什么是支持向量机

什么是支持向量

什么是超平面 

二、实验内容

训练样本

数据标准化

SVM训练

三个超参数

训练方法

训练原理

实验结果展现

总体代码实现

三、实验总结

SVM的优缺点

优点:

缺点:

实验改进


一、支持向量机

什么是支持向量机

支持向量机(Support Vector Machine,SVM)是一种监督学习算法,用于分类和回归分析。其基本原理是找到一个最优的超平面,将不同类别的数据点分隔开来,并且使得间隔最大化。

什么是支持向量

在分类问题中,SVM试图找到一个能够将不同类别数据点分隔开的最佳决策边界,这个边界由离该边界最近的一些训练数据点组成,它们被称为支持向量。

什么是超平面 

超平面是几何学和线性代数中的一个重要概念,特别常见于支持向量机(SVM)等机器学习算法中。简单来说,超平面是一个维度比所在空间低一维的子空间,它将空间分割成两个部分。

在二维空间中,超平面就是一条直线,它将空间分割成两个半平面;在三维空间中,超平面是一个平面,将空间分割成两个半空间;在更高维的空间中,超平面依然是一个维度比所在空间低一维的子空间,将空间分割成两个部分。

对于一个n维空间中的超平面,可以用一个方程来表示: 

w_1x_1 + w_2x_2 + \ldots + w_nx_n + b = 0

其中 (w_1, w_2, \ldots, w_n) 是超平面的法向量(或者称为权重)

(b) 是偏置项。向量 ((w_1, w_2, \ldots, w_n)) 决定了超平面的方向,(b) 决定了超平面与原点的距离。

在机器学习中,超平面经常被用来分割数据空间,例如在二分类问题中,超平面可以将数据分成两类。支持向量机(SVM)就是基于超平面的分类器,在SVM中,我们希望找到一个最优的超平面,使得它能够最好地将不同类别的数据分开,并且具有最大的间隔(即支持向量之间的距离最大)。

二、实验内容

训练样本

本次实验内容为利用支持向量机的相关内容实现对哺乳动物和非哺乳动物的分类,分类依据为四个特征(没有具体想特征的名字,只需知道每个样本有有四个特征参数即可),训练集如下:

X = np.array([
    [70, 1.5, 1, 1],  # 哺乳动物
    [35, 1.0, 1, 1],  # 哺乳动物
    [150, 2.0, 1, 1],  # 哺乳动物
    [4, 0.3, 0, 0],  # 非哺乳动物
    [0.02, 0.05, 0, 0],  # 非哺乳动物
    [1000, 3.0, 0, 0],  # 非哺乳动物--如鲸鱼
    [85, 1.8, 1, 1],  # 哺乳动物
    [5, 0.5, 0, 0],  # 非哺乳动物
])

每个样本的分类情况如下:(一开始将分类结果分别置为0和1,考虑到支持向量机一般将分类结果置为1和-1,故对其进行修改)

y = np.array([1, 1, 1, 0, 0, 0, 1, 0])

# 将标签转换为-1和1
y = np.where(y == 0, -1, 1)

数据标准化

X = (X - np.mean(X, axis=0)) / np.std(X, axis=0)

这行代码是在对数据进行标准化处理。标准化(或称为Z-score标准化)是数据预处理中的一个常见步骤,目的是使特征数据具有零均值和单位方差,以消除不同特征之间的量纲差异,从而提高模型的训练效果和收敛速度。

具体来说,这行代码的作用是将矩阵 X 中的每个特征(即每列数据)转换为标准正态分布,即均值为0,标准差为1。公式如下:

  X_{\text{standardized}} = \frac{X - \mu}{\sigma}

这里 np.mean(X, axis=0) 计算矩阵 X 每列的均值(即每个特征的均值)。axis=0 表示沿着行方向进行平均,因此得到的是一个包含各列均值的一维数组

类似地,np.std(X, axis=0) 计算矩阵 X 每列的标准差(即每个特征的标准差)。同样,axis=0 表示沿着行方向计算,因此得到的是一个包含各列标准差的一维数组。

这一步是将每个元素减去对应列的均值,再除以对应列的标准差。这样,每个特征的数据就会被转换为均值为0、标准差为1的分布。

标准化处理后,每个特征的均值变为0,标准差变为1。这种处理方式在机器学习算法中非常常见,因为许多算法在特征值范围较大不一致时表现不佳,通过标准化可以有效提升模型的性能和训练效率。

SVM训练

# 超参数
learning_rate = 0.001
epochs = 1000
lambda_param = 0.01

# SVM训练
for epoch in range(epochs):
    for i, x_i in enumerate(X):
        condition = y[i] * np.dot(X[i], w) >= 1
        if condition:
            w -= learning_rate * (2 * lambda_param * w)
        else:
            w -= learning_rate * (2 * lambda_param * w - np.dot(X[i], y[i]))

三个超参数

learning_rate:学习率,用于控制每次梯度更新的步长。

epochs:训练轮数,即训练过程将遍历数据集的次数。

lambda_param:正则化参数,用于控制模型复杂度,防止过拟合。

训练方法

外层循环遍历 epochs,即整个数据集被训练的次数。

内层循环遍历每个样本 X[i] 和对应的标签 y[i]

对于每个样本,根据 y[i] * np.dot(X[i], w) 与1的比较,判断该样本是否满足约束条件 y[i] * (w^T * x_i) >= 1

如果满足条件,说明该样本已经分类正确且位于边界之外,此时仅需要进行正则化项的梯度更新:

w -= learning_rate * (2 * lambda_param * w)

如果不满足条件,说明该样本分类错误或位于边界之内,此时需要同时更新正则化项和损失项:

w -= learning_rate * (2 * lambda_param * w - np.dot(X[i], y[i]))

训练原理

支持向量机的目标是找到一个分离超平面,使得两个类别的数据点之间的间隔最大化。为了实现这一目标,我们最小化以下损失函数:

L(w) = \frac{1}{2} |w|^2 + C \sum_{i=1}^{n} \max(0, 1 - y_i (w^T x_i))

其中:

  • 第一项 (\frac{1}{2} |w|^2) 是正则化项,目的是防止模型过拟合。
  • 第二项 (\sum_{i=1}^{n} \max(0, 1 - y_i (w^T x_i))) 是损失项,衡量错分类程度。

在上述代码中,我们实际上是在通过梯度下降的方法最小化这个损失函数。lambda_param 对应于正则化项中的系数,learning_rate 控制的是梯度更新的步长

实验结果展现

总体代码实现

import numpy as np
import matplotlib.pyplot as plt

# 数据和标签
X = np.array([
    [70, 1.5, 1, 1],  # 哺乳动物
    [35, 1.0, 1, 1],  # 哺乳动物
    [150, 2.0, 1, 1],  # 哺乳动物
    [4, 0.3, 0, 0],  # 非哺乳动物
    [0.02, 0.05, 0, 0],  # 非哺乳动物
    [1000, 3.0, 0, 0],  # 非哺乳动物--如鲸鱼
    [85, 1.8, 1, 1],  # 哺乳动物
    [5, 0.5, 0, 0],  # 非哺乳动物
])
y = np.array([1, 1, 1, 0, 0, 0, 1, 0])

# 将标签转换为-1和1
y = np.where(y == 0, -1, 1)

# 特征标准化
X = (X - np.mean(X, axis=0)) / np.std(X, axis=0)

# 添加偏置项
X = np.hstack((np.ones((X.shape[0], 1)), X))

# 初始化权重
w = np.zeros(X.shape[1])

# 超参数
learning_rate = 0.001
epochs = 1000
lambda_param = 0.01

# SVM训练
for epoch in range(epochs):
    for i, x_i in enumerate(X):
        condition = y[i] * np.dot(X[i], w) >= 1
        if condition:
            w -= learning_rate * (2 * lambda_param * w)
        else:
            w -= learning_rate * (2 * lambda_param * w - np.dot(X[i], y[i]))


# 预测函数
def predict(X):
    predictions = np.dot(X, w)
    return np.sign(predictions)


# 预测
X_test = X  # 假设测试集就是训练集,为了演示
y_pred = predict(X_test)

# 打印预测结果
print("Predicted labels:", y_pred)


# 可视化决策边界
def plot_svm_decision_boundary(X, y, w):
    fig, ax = plt.subplots()

    # 绘制数据点
    for i in range(len(y)):
        if y[i] == 1:
            ax.scatter(X[i, 1], X[i, 2], color='blue', marker='o')
        else:
            ax.scatter(X[i, 1], X[i, 2], color='red', marker='x')

    # 绘制决策边界
    x1 = np.linspace(min(X[:, 1]), max(X[:, 1]), 200)
    x2 = -(w[0] + w[1] * x1) / w[2]
    ax.plot(x1, x2, color='black')

    # 绘制支持向量
    margins = 1 / np.sqrt(np.sum(w[1:] ** 2))
    decision_values = np.dot(X, w)
    support_vectors = np.where(np.abs(decision_values - 1) < margins)[0]

    for sv in support_vectors:
        ax.scatter(X[sv, 1], X[sv, 2], s=100, facecolors='none', edgecolors='k')

    ax.set_xlabel('Feature 1')
    ax.set_ylabel('Feature 2')
    ax.set_title('SVM Decision Boundary and Support Vectors')
    plt.show()


# 调用绘图函数
plot_svm_decision_boundary(X, y, w)

三、实验总结

SVM的优缺点

优点:

  1. 高维空间效果好:SVM在高维空间中表现良好,适用于处理高维特征的数据集。

  2. 泛化能力强:SVM通过最大化间隔来选择决策边界,因此在面对新样本时具有较好的泛化能力。

  3. 解决小样本情况:SVM在小样本情况下仍能保持较好的性能,不容易陷入过拟合。

  4. 核技巧:SVM可以通过核函数将输入空间映射到高维特征空间,从而处理非线性分类问题。

  5. 支持向量:SVM的决策边界是由支持向量唯一确定的,这使得模型具有较好的鲁棒性。

缺点:

  1. 计算开销大:SVM的训练时间复杂度较高,特别是在大规模数据集上,需要较长的训练时间。

  2. 参数选择敏感:SVM有一些超参数需要调节,如惩罚参数C、核函数选择等,选择不当会影响模型性能。

  3. 只适用于二分类问题:传统的SVM算法只适用于二分类问题,对于多分类问题需要额外的处理。

  4. 对噪声敏感:SVM对噪声和错分类样本敏感,需要谨慎处理数据。

  5. 不适用于大规模数据集:由于SVM在训练过程中需要存储支持向量,对于大规模数据集内存消耗较大。

总的来说,SVM在处理小样本、高维特征和非线性分类问题方面表现出色,但在大规模数据集和计算开销方面存在一些局限性。在实际应用中,需要根据具体情况权衡其优缺点并进行选择。

实验改进

本次实验中对SVM的训练方式是一种简单的梯度下降实现方式,但在实际应用中,我们通常会使用更先进的优化算法(如SGD、Adam等),并且会对数据进行批量处理而不是逐个样本处理。

此外,为了提高代码的可读性和可维护性,可以将训练过程封装成一个函数或类,并添加更多的调试信息和评估指标。

  • 27
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值