使用Python和scikit-learn实现支持向量机(SVM)

        支持向量机(Support Vector Machine,SVM)是一种强大的监督学习算法,广泛用于分类和回归问题。它能够有效处理线性和非线性数据,并在复杂数据集中表现出色。本文将介绍如何使用Python和scikit-learn库实现SVM,以及如何通过可视化不同参数设置来理解其工作原理。

一、什么是支持向量机(SVM)?

        支持向量机是一种二类分类模型,它的基本思想是在特征空间中找到一个最优的超平面,能够将不同类别的数据点分隔开来,并且使得两侧距离最近的数据点(支持向量)到超平面的距离最大化。对于非线性可分的数据集,SVM通过核函数将数据映射到高维空间,使得数据线性可分。

二、实现步骤

        我们将使用Python的scikit-learn库来实现一个简单的支持向量机分类器,并在一个合成的数据集上进行可视化展示。

1、导入必要的库和数据集生成
from sklearn import svm
from sklearn.datasets import make_moons
import matplotlib.pyplot as plt
import numpy as np
2、定义绘制决策边界和支持向量的函数
# 定义绘制决策边界和支持向量的函数
def plot_hyperplane(clf, X, y, h=0.02, draw_sv=True, title='Hyperplane'):
    # 确定绘图边界
    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))

    # 设置绘图属性
    plt.title(title)
    plt.xlim(xx.min(), xx.max())
    plt.ylim(yy.min(), yy.max())
    plt.xticks(())
    plt.yticks(())

    # 生成网格数据并进行预测
    Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
    Z = Z.reshape(xx.shape)
    
    # 绘制决策边界
    plt.contourf(xx, yy, Z, cmap='hot', alpha=0.5)

    # 定义不同类别的标记和颜色
    markers = ['o', 's', '^']
    colors = ['b', 'r', 'c']
    labels = np.unique(y)
    
    # 绘制数据点
    for label in labels:
        plt.scatter(X[y==label][:, 0],
                    X[y==label][:, 1],
                    c=colors[label],
                    marker=markers[label])
    
    # 如果指定绘制支持向量,则绘制支持向量
    if draw_sv:
        sv = clf.support_vectors_
        plt.scatter(sv[:, 0], sv[:, 1], c='y', marker='x')
3、生成合成数据集

        使用make_moons函数生成一个合成的月亮形数据集,用于后续的分类器训练和可视化。

#生成包含150个样本的合成数据集,噪声为0.15
X, y = make_moons(n_samples=150, noise=0.15, random_state=42)
  • make_moons函数生成一个合成的月亮形状数据集。
  • n_samples: 数据集样本数量。
  • noise: 噪声水平,增加数据的随机性。
  • random_state: 随机种子,确保每次运行生成的数据一致性。
4、初始化不同参数设置的SVM分类器

        初始化了六个不同参数设置的SVM分类器,分别探索了不同的gammaC参数组合对分类性能的影响。

# 初始化不同参数设置的SVM分类器
#初始化一个RBF核支持向量机分类器,设置参数C和gamma。
clf_rbf1 = svm.SVC(C=1, kernel='rbf', gamma=0.01)
clf_rbf2 = svm.SVC(C=1, kernel='rbf', gamma=5)
clf_rbf3 = svm.SVC(C=100, kernel='rbf', gamma=0.01)
clf_rbf4 = svm.SVC(C=100, kernel='rbf', gamma=5)
clf_rbf5 = svm.SVC(C=10000, kernel='rbf', gamma=0.01)
clf_rbf6 = svm.SVC(C=10000, kernel='rbf', gamma=5)

# 创建绘图区域
plt.figure()

# 将所有分类器放入列表中
clfs = [clf_rbf1, clf_rbf2, clf_rbf3, clf_rbf4, clf_rbf5, clf_rbf6]
# 设置每个子图的标题
titles = ['gamma=0.01, C=1',
          'gamma=0.01, C=100',
          'gamma=0.01, C=10000',
          'gamma=5, C=1',
          'gamma=5, C=100',
          'gamma=5, C=10000']
  • 初始化了六个不同参数设置的SVM分类器对象。
  • svm.SVC: 创建一个支持向量机分类器。
  • C: 正则化参数。
  • kernel: 核函数类型,这里使用径向基函数(RBF)。
  • gamma: RBF核函数的参数,影响决策边界的灵活性和复杂度。
  • clfs: 包含所有分类器的列表。
  • titles: 每个分类器对应的标题,用于在图表中显示参数设置。
5、绘制不同参数设置下的SVM决策边界

        最后,我们通过循环遍历每个分类器,对其进行训练并绘制出相应的决策边界和支持向量。

# 对每个分类器进行训练和绘图
for clf, i in zip(clfs, range(len(clfs))):
    clf.fit(X, y)  # 训练分类器
    plt.subplot(3, 2, i+1)  # 创建3行2列的子图,并选择当前子图
    plot_hyperplane(clf, X, y, title=titles[i])  # 绘制决策边界和支持向量

plt.show()  # 显示图形
  • 创建一个12x10英寸大小的图形窗口。
  • 使用zip函数将每个分类器clf与其对应的索引i组合。
  • 对每个分类器进行训练(clf.fit(X, y))并调用plot_hyperplane函数绘制决策边界。
  • plt.subplot(3, 2, i+1): 将图形分成3行2列的子图,当前绘制第i+1个子图。
  • plt.tight_layout(): 调整子图的布局,防止重叠。
  • plt.show(): 显示绘制的图形。
三、结果分析

这幅图展示了使用较小的gamma(0.01)和较小的正则化参数C(1)训练的SVM模型。
决策边界相对平滑,模型的复杂度较低。
可以看到一些支持向量被标记为黄色的'x'符号。

这幅图展示了相同的低gamma值(0.01),但更大的正则化参数C(100)。
决策边界仍然平滑,但稍微更接近一些数据点,对噪声更敏感。

使用了极大的C值(10000),同时gamma仍然较低(0.01)。
决策边界非常接近许多数据点,模型非常复杂,几乎适应了每个数据点,可能存在过拟合的风险。

这幅图展示了较高的gamma值(5)和较小的正则化参数C(1)。
决策边界非常复杂,几乎适应了每个数据点,可能出现了过拟合。

在高gamma(5)和较大C(100)的设置下,决策边界略有平滑化,但仍然相对复杂。

最后一幅图展示了高gamma(5)和非常大的C值(10000)。
决策边界非常复杂,几乎适应了每个数据点,存在严重的过拟合可能性。


总体分析:

        参数gamma控制了决策边界的灵活性,较大的gamma值会导致决策边界更复杂,更贴近训练数据点。参数C是正则化参数,控制了对错误分类的惩罚,较大的C值会导致模型更关注训练数据,可能会导致过拟合。在低gamma和低C值的情况下,决策边界相对平滑,模型简单;而在高gamma和高C值的情况下,决策边界更复杂,可能会过度适应训练数据。

  • 22
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值