1. 支持向量机(SVM)基础与实验概述
支持向量机(Support Vector Machine)作为机器学习领域的经典算法,在分类和回归任务中表现出色。我第一次接触SVM是在研究生阶段的模式识别课程上,当时就被其优雅的数学推导和强大的分类能力所吸引。这次实验让我有机会从理论到实践完整地走一遍SVM的实现过程,特别是对SMO算法的理解有了质的飞跃。
实验包含四个关键任务:首先是基础的线性SVM实现,用于山鸢尾的二分类;接着引入核函数处理变色鸢尾的非线性可分问题;然后通过软间隔SVM解决弗吉尼亚鸢尾的分类;最后挑战高维政治家人脸识别。这种由浅入深的设计让我逐步掌握了SVM的核心思想——寻找最优分类超平面,使不同类别的数据间隔最大化。
在开始代码实现前,有几个关键概念需要明确:
- 支持向量:距离分类超平面最近的样本点,决定了分类器的性能
- 核技巧:通过非线性映射将数据转换到高维空间实现线性可分
- 软间隔:允许部分样本违反间隔规则,提高模型鲁棒性
注意:实验中使用的鸢尾花数据集包含三个类别(setosa, versicolor, virginica),每个类别50个样本,每个样本4个特征(花萼长度、花萼宽度、花瓣长度、花瓣宽度)。政治家人脸数据集包含7位政治家的1288张图片,每张图片转换为1850维的特征向量。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 线性SVM与山鸢尾分类实现
2.1 数据准备与预处理
我们从最简单的二分类任务开始,使用sklearn自带的鸢尾花数据集,仅选取前两个特征(花萼长度和宽度)以便可视化:
python复制from sklearn import datasets
import numpy as np
iris = datasets.load_iris()
X = iris["data"][:, (0,1)] # 只取前两个特征
y = 2*(iris["target"]==0).astype(np.int32).reshape(-1,1) - 1 # 将类别0标记为-1,其他为1
这种二值化处理是SVM处理多类问题的常用策略——"一对多"(One-vs-Rest)。实验中我们专门区分山鸢尾(setosa)与其他种类,因为setosa与其他两类线性可分,适合演示基础SVM。
2.2 SVM核心算法实现
SVM的核心是求解以下优化问题:
$$
\min_{w,b} \frac{1}{2}||w||^2 \quad s.t. \quad y_i(w^Tx_i + b) \geq 1
$$
我们实现了简化版的SMO(Sequential Minimal Optimization)算法来求解:
python复制class SVM:
def __init__(self, max_iter=10):
self.max_iter = max_iter
def fit(self, X, y):
m, n = X.shape
self.w = np.zeros(n)
self.b = 0
for _ in range(self.max_iter):
for i in range(m):
if y[i]*(np.dot(X[i], self.w) + self.b) < 1: # 违反KKT条件
self.w += y[i]*X[i] # 更新权重
self.b += y[i] # 更新偏置
这个简化实现忽略了拉格朗日乘子的约束,实际应用中应该使用更完整的SMO算法。完整版需要考虑:
- 两个拉格朗日乘子的联合优化
- 乘子的上下界约束
- 偏置b的更新策略
2.3 结果可视化与分析
训练完成后,我们绘制决策边界和分类结果:
python复制def plot_decision_boundary(X, y, model):
# 创建网格点
x_min, x_max = X[:,0].min()-1, X[:,0].max()+1
y_min, y_max = X
