第41课:支持向量机(SVM)
学习目标
完成本课后,你将能够:
- 理解支持向量机(SVM)的基本原理和核心概念。
- 使用 scikit-learn 库实现一个 SVM 分类器。
- 解释 SVM 中“最大间隔”和“核技巧”的作用。
- 应用 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))
代码解释:
- 我们加载数据并将其划分为训练集和测试集。
StandardScaler():对数据进行标准化(均值为0,方差为1),这是SVM预处理的关键步骤。SVC(kernel='linear'):创建一个使用线性核的支持向量分类器(Support Vector Classifier)。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=0和y=1的数据),绘制 SVM 的决策边界和支持向量。 - 提示:你可以使用
matplotlib绘制散点图,并通过在网格点上预测结果来绘制决策边界。svm_classifier.support_vectors_属性包含了支持向量的信息。
常见错误
- 忽略数据标准化:这是使用 SVM 时最常见的错误。SVM 的决策边界依赖于数据点间的距离计算,如果特征尺度差异巨大(例如,一个特征范围是0-1,另一个是0-10000),尺度大的特征会主导距离计算,导致模型失效。
- 盲目使用复杂核函数:对于线性可分的数据,使用
kernel='linear'通常更快、更简单且不容易过拟合。不要默认就使用kernel='rbf'。 - 不理解参数C和gamma的影响:
C值过大,模型会试图正确分类所有训练样本,可能导致过拟合(决策边界非常扭曲)。C值过小,模型会对误分类更宽容,可能导致欠拟合(决策边界过于平滑)。- 对于
rbf核,gamma参数定义了单个训练样本的影响范围。gamma过大,影响范围小,模型可能过拟合;gamma过小,影响范围大,模型可能欠拟合。
- 用SVM处理大规模数据集:SVM的训练时间复杂度较高,在数据样本量非常大(例如,超过10万)时,训练会变得很慢。此时可以考虑随机梯度下降分类器(
SGDClassifier)或其他更高效的算法。
小结
本课我们学习了支持向量机(SVM):
- 核心思想:寻找一个将不同类别数据分开且间隔最大的超平面。
- 关键要素:支持向量是定义决策边界的关键样本点。
- 核技巧:通过核函数将数据映射到高维空间,以解决线性不可分问题。常用核函数有
linear(线性)和rbf(径向基函数)。 - 实现步骤:使用
scikit-learn的SVC类。务必进行数据标准化。 - 参数调优:
C(正则化强度)和gamma(rbf核的影响范围)是影响模型性能的重要超参数。
SVM 是一种强大且理论优美的分类算法,尤其在特征维度高于样本数或样本量中等时表现优异。下一课,我们将学习另一种经典的分类算法——朴素贝叶斯分类器。
练习编辑器
rust
Loading...