本文介绍支持向量机(SVM)算法在机器学习中的基本原理、特点、注意事项,以及实现 SVM 模型的完整步骤。
1. 支持向量机的基本原理
支持向量机(SVM)是一种用于分类和回归分析的监督学习模型。它通过在特征空间中找到一个最优超平面,将不同类别的样本分开。
1.1 最大间隔分类
SVM 的目标是找到一个可以最大化类别间距的超平面。对于线性可分的数据,SVM 试图找到最远离数据点的决策边界:
\[\text{Maximize } \frac{2}{\|\mathbf{w}\|}\]其中,(\mathbf{w}) 是决策边界的法向量。
1.1.1 线性可分
对于线性可分的样本,SVM 寻找能够最大化间隔的线性超平面,将数据分为两类。
- 决策函数:
- 决策边界:满足 ( f(\mathbf{x}) = 0 ) 的超平面。
1.2 非线性可分与核技巧
当数据线性不可分时,SVM 使用核技巧将数据映射到高维空间,以实现线性可分。常用的核函数有:
- 线性核:
- 多项式核:
- 高斯核(RBF 核):
- Sigmoid 核:
1.3 支持向量
在 SVM 中,支持向量是离决策边界最近的样本点。只有支持向量对构建超平面起作用。
1.4 软间隔与正则化
当数据存在噪声或重叠时,SVM 引入软间隔,通过加入松弛变量 (\xi_i) 允许部分样本位于间隔之内:
\[\min \frac{1}{2}\|\mathbf{w}\|^2 + C \sum_{i=1}^{n} \xi_i\]其中 ( C ) 是正则化参数,用于平衡间隔最大化和误分类惩罚。
2. 实现步骤
我们使用 iris
数据集来进行一个简单的实现。iris
数据集常用于分类问题,包含四个特征和三种类别的鸢尾花。
2.1 数据准备
加载数据集,分割训练集和测试集,并对特征进行标准化。
import numpy as np
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report
# 加载iris数据集
data = load_iris()
X = data.data # 特征数据
y = data.target # 目标标签
# 将数据集分为训练集和测试集,80%用于训练,20%用于测试
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
scaler = StandardScaler() # 标准化特征数据
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)
2.2 模型训练
实现支持向量机算法。
class SimpleSVM:
def __init__(self, learning_rate=0.001, lambda_param=0.01, n_iters=1000):
self.lr = learning_rate
self.lambda_param = lambda_param
self.n_iters = n_iters
self.w = None
self.b = None
def fit(self, X, y):
n_samples, n_features = X.shape
# 初始化权重和偏置
self.w = np.zeros(n_features)
self.b = 0
# 将类标签转换为-1和1
y_ = np.where(y <= 0, -1, 1)
# 梯度下降
for _ in range(self.n_iters):
for idx, x_i in enumerate(X):
condition = y_[idx] * (np.dot(x_i, self.w) - self.b) >= 1
if condition:
self.w -= self.lr * (2 * self.lambda_param * self.w)
else:
self.w -= self.lr * (2 * self.lambda_param * self.w - np.dot(x_i, y_[idx]))
self.b -= self.lr * y_[idx]
def predict(self, X):
approx = np.dot(X, self.w) - self.b
return np.sign(approx)
2.3 模型预测
对测试集进行预测。
# 创建SVM模型
svm = SimpleSVM()
# 训练模型
svm.fit(X_train, y_train)
# 预测测试集
y_pred = svm.predict(X_test)
2.4 模型评估
使用测试数据集评估模型性能。
accuracy = accuracy_score(y_test, y_pred)
conf_matrix = confusion_matrix(y_test, y_pred)
class_report = classification_report(y_test, y_pred)
print("\nAccuracy:", accuracy)
print("Confusion Matrix:\n", conf_matrix)
print("Classification Report:\n", class_report)
3. 优缺点
3.1 优点
- 有效性:在高维空间中表现良好。
- 支持非线性分类:通过核技巧可以处理非线性问题。
- 鲁棒性:对数据噪声和异常值不敏感。
3.2 缺点
- 计算复杂度高:在大规模数据集上训练时间较长。
- 参数选择复杂:选择合适的核函数和参数需要经验。
- 不适合大规模数据集:SVM 在处理大规模数据时计算开销大。
SVM 在小规模数据集和复杂分类问题上表现出色,通过选择合适的核函数和参数调整,可以有效处理线性和非线性问题。