41·监督学习-分类进阶

支持向量机(SVM)

classificationsvm

第41课:支持向量机(SVM)

学习目标

完成本课后,你将能够:

  1. 理解支持向量机(SVM)的基本原理和核心概念。
  2. 使用 scikit-learn 库实现一个 SVM 分类器。
  3. 解释 SVM 中“最大间隔”和“核技巧”的作用。
  4. 应用 SVM 解决实际分类问题,并评估其性能。

核心概念

想象一下,你有一堆红色和蓝色的玻璃珠混杂在桌面上。你的任务是画一条线,把它们完美分开,并且希望这条线离两边最近的珠子尽可能远。这条线就是 SVM 寻找的决策边界,而那些离边界最近、用来确定边界位置的珠子就叫做支持向量

SVM 的核心思想就是找到这样一个“最宽的走廊”来分隔不同类别的数据,从而提高模型对新数据的泛化能力。

  • 超平面(Hyperplane):在二维空间中,它是一条直线;在三维空间中,它是一个平面;在更高维空间,它就是一个“超平面”。这就是我们寻找的决策边界。
  • 最大间隔(Maximum Margin):SVM 的目标就是找到一个超平面,使得两类数据点到该超平面的最小距离(即间隔)最大化。这通常能带来更好的分类效果。
  • 支持向量(Support Vectors):那些正好位于间隔边缘(或间隔内)的数据点,它们是定义超平面位置的关键。删除非支持向量的数据点不会影响最终的决策边界。
  • 核技巧(Kernel Trick):当数据线性不可分时(比如环形分布),SVM 可以通过一个函数将数据映射到更高维的空间,在这个新空间里数据就可能变得线性可分。核函数允许我们在不直接计算高维坐标的情况下完成这个过程,大大提升了计算效率。

代码示例

我们将使用经典的 Iris(鸢尾花)数据集来演示一个线性 SVM 分类器。

# 1. 导入必要的库
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.metrics import classification_report, accuracy_score

# 2. 加载数据集
iris = datasets.load_iris()
X = iris.data  # 特征 (花萼长度、宽度,花瓣长度、宽度)
y = iris.target # 标签 (山鸢尾、变色鸢尾、维吉尼亚鸢尾)

# 3. 划分训练集和测试集 (70%训练, 30%测试)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# 4. 数据标准化
# SVM 对特征的尺度非常敏感,标准化是至关重要的一步!
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)

# 5. 创建SVM分类器 (使用线性核)
svm_classifier = SVC(kernel='linear', random_state=42)

# 6. 训练模型
svm_classifier.fit(X_train, y_train)

# 7. 在测试集上进行预测
y_pred = svm_classifier.predict(X_test)

# 8. 评估模型性能
print("模型准确率:", accuracy_score(y_test, y_pred))
print("\n分类报告:\n", classification_report(y_test, y_pred, target_names=iris.target_names))

代码解释

  1. 我们加载数据并将其划分为训练集和测试集。
  2. StandardScaler():对数据进行标准化(均值为0,方差为1),这是SVM预处理的关键步骤。
  3. SVC(kernel='linear'):创建一个使用线性核的支持向量分类器(Support Vector Classifier)。
  4. fit()方法用于训练模型,predict()方法用于预测,最后用准确率和分类报告来评估结果。

实践练习

练习1:改变核函数

  • 任务:在上面的代码基础上,将 kernel='linear' 改为 kernel='rbf'(径向基函数核),重新运行并比较结果。
  • 问题:哪个核函数在 Iris 数据集上表现更好?为什么?

练习2:探索参数C

  • 任务:SVM 有一个重要参数 C,它控制了误分类样本的惩罚程度(可以理解为正则化强度)。分别设置 C=0.1, C=1, C=100,观察测试集准确率的变化。
  • 问题:较大的 C 值会导致模型更“严格”还是更“宽容”?这可能会带来什么风险?

练习3:可视化(进阶)

  • 任务:只使用 Iris 数据集的前两个特征(X = iris.data[:, :2])和两个类别(例如,选择 y=0y=1 的数据),绘制 SVM 的决策边界和支持向量。
  • 提示:你可以使用 matplotlib 绘制散点图,并通过在网格点上预测结果来绘制决策边界。svm_classifier.support_vectors_ 属性包含了支持向量的信息。

常见错误

  1. 忽略数据标准化:这是使用 SVM 时最常见的错误。SVM 的决策边界依赖于数据点间的距离计算,如果特征尺度差异巨大(例如,一个特征范围是0-1,另一个是0-10000),尺度大的特征会主导距离计算,导致模型失效。
  2. 盲目使用复杂核函数:对于线性可分的数据,使用 kernel='linear' 通常更快、更简单且不容易过拟合。不要默认就使用 kernel='rbf'
  3. 不理解参数C和gamma的影响
    • C 值过大,模型会试图正确分类所有训练样本,可能导致过拟合(决策边界非常扭曲)。
    • C 值过小,模型会对误分类更宽容,可能导致欠拟合(决策边界过于平滑)。
    • 对于 rbf 核,gamma 参数定义了单个训练样本的影响范围。gamma 过大,影响范围小,模型可能过拟合;gamma 过小,影响范围大,模型可能欠拟合。
  4. 用SVM处理大规模数据集:SVM的训练时间复杂度较高,在数据样本量非常大(例如,超过10万)时,训练会变得很慢。此时可以考虑随机梯度下降分类器(SGDClassifier)或其他更高效的算法。

小结

本课我们学习了支持向量机(SVM):

  • 核心思想:寻找一个将不同类别数据分开且间隔最大的超平面。
  • 关键要素:支持向量是定义决策边界的关键样本点。
  • 核技巧:通过核函数将数据映射到高维空间,以解决线性不可分问题。常用核函数有 linear(线性)和 rbf(径向基函数)。
  • 实现步骤:使用 scikit-learnSVC 类。务必进行数据标准化
  • 参数调优C(正则化强度)和 gammarbf 核的影响范围)是影响模型性能的重要超参数。

SVM 是一种强大且理论优美的分类算法,尤其在特征维度高于样本数或样本量中等时表现优异。下一课,我们将学习另一种经典的分类算法——朴素贝叶斯分类器。

练习编辑器

rust
Loading...

继续学习

完成本课后,建议继续学习下一课「朴素贝叶斯分类器」 以巩固所学知识。