数学建模学习-支持向量机(Support Vector Machine)教程(19)
写在最前
注意本文的相关代码及例子为同学们提供参考,借鉴相关结构,在这里举一些通俗易懂的例子,方便同学们根据实际情况修改代码,很多同学私信反映能否添加一些可视化,这里每篇教程都尽可能增加一些可视化方便同学理解,但具体使用时,同学们要根据实际情况选择是否在论文中添加可视化图片。
系列教程计划持续更新,同学们可以免费订阅专栏,内容充足后专栏可能付费,提前订阅的同学可以免费阅读,同时相关代码获取可以关注博主评论或私信。
目录
算法简介
支持向量机(Support Vector Machine, SVM)是一种强大的监督学习算法,主要用于分类问题。它通过在高维空间中构建一个超平面或一组超平面,将不同类别的数据点分开。SVM的核心思想是找到最优的分隔超平面,使得不同类别的数据点之间的间隔最大化。
算法特点
-
最大间隔分类:SVM寻找能够使不同类别数据点之间的间隔最大的分隔超平面。
-
核技巧:通过核函数将数据映射到高维空间,使得线性不可分的数据在高维空间中变得线性可分。
-
支持向量:分类的决策仅依赖于少数关键的训练样本点(支持向量),这些点位于类别边界附近。
-
全局最优解:SVM的优化问题是凸优化问题,因此可以保证找到全局最优解。
-
泛化能力强:由于最大化间隔的特性,SVM具有较好的泛化能力。
数学原理
线性可分情况
对于线性可分的二分类问题,SVM的目标是找到一个超平面:
w
T
x
+
b
=
0
w^T x + b = 0
wTx+b=0
使得两类数据点分别位于超平面的两侧,且间隔最大。分类决策函数为:
f
(
x
)
=
s
i
g
n
(
w
T
x
+
b
)
f(x) = sign(w^T x + b)
f(x)=sign(wTx+b)
优化目标为:
min
w
,
b
1
2
∣
∣
w
∣
∣
2
\min_{w,b} \frac{1}{2}||w||^2
w,bmin21∣∣w∣∣2
s
.
t
.
y
i
(
w
T
x
i
+
b
)
≥
1
,
i
=
1
,
2
,
.
.
.
,
n
s.t. \quad y_i(w^T x_i + b) \geq 1, \quad i=1,2,...,n
s.t.yi(wTxi+b)≥1,i=1,2,...,n
核函数
对于线性不可分的情况,SVM使用核函数将数据映射到高维空间:
K
(
x
i
,
x
j
)
=
ϕ
(
x
i
)
T
ϕ
(
x
j
)
K(x_i, x_j) = \phi(x_i)^T \phi(x_j)
K(xi,xj)=ϕ(xi)Tϕ(xj)
常用的核函数包括:
- 线性核: K ( x i , x j ) = x i T x j K(x_i, x_j) = x_i^T x_j K(xi,xj)=xiTxj
- 多项式核: K ( x i , x j ) = ( x i T x j + c ) d K(x_i, x_j) = (x_i^T x_j + c)^d K(xi,xj)=(xiTxj+c)d
- 高斯核(RBF): K ( x i , x j ) = e x p ( − γ ∣ ∣ x i − x j ∣ ∣ 2 ) K(x_i, x_j) = exp(-\gamma ||x_i - x_j||^2) K(xi,xj)=exp(−γ∣∣xi−xj∣∣2)
代码实现
环境准备
# requirements.txt
numpy>=1.21.0
scikit-learn>=0.24.2
matplotlib>=3.4.2
pandas>=1.3.0
数据准备和模型训练
import numpy as np
import matplotlib.pyplot as plt
from sklearn import svm
from sklearn.datasets import make_blobs
from sklearn.preprocessing import StandardScaler
# 生成示例数据
def generate_data():
# 生成三类数据点
X, y = make_blobs(n_samples=300, centers=3, cluster_std=0.60, random_state=0)
# 标准化特征
scaler = StandardScaler()
X = scaler.fit_transform(X)
return X, y
# 训练SVM模型
def train_svm(X, y):
# 创建SVM分类器
clf = svm.SVC(kernel='rbf', C=1.0)
# 训练模型
clf.fit(X, y)
return clf
可视化实现
# 可视化决策边界
def plot_decision_boundary(X, y, clf, filename):
plt.figure(figsize=(10, 8))
# 创建网格点
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, 0.02),
np.arange(y_min, y_max, 0.02))
# 预测网格点的类别
Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
# 绘制决策边界
plt.contourf(xx, yy, Z, alpha=0.4)
plt.scatter(X[:, 0], X[:, 1], c=y, alpha=0.8)
plt.title('SVM分类决策边界')
plt.xlabel('特征1')
plt.ylabel('特征2')
plt.savefig(f'images/{filename}')
plt.close()
# 展示支持向量
def plot_support_vectors(X, y, clf, filename):
plt.figure(figsize=(10, 8))
# 绘制所有数据点
plt.scatter(X[:, 0], X[:, 1], c=y, alpha=0.5)
# 突出显示支持向量
sv = clf.support_vectors_
plt.scatter(sv[:, 0], sv[:, 1], c='red', marker='x', s=100, linewidth=2,
label='支持向量')
plt.title('SVM支持向量展示')
plt.xlabel('特征1')
plt.ylabel('特征2')
plt.legend()
plt.savefig(f'images/{filename}')
plt.close()
实例分析
在本教程中,我们使用了一个三类分类问题作为示例。通过生成300个数据点,这些数据点分布在三个不同的类别中。我们使用RBF核函数的SVM分类器来解决这个分类问题。
主要步骤包括:
- 数据生成和预处理
- 模型训练
- 决策边界可视化
- 支持向量可视化
结果可视化
决策边界
上图展示了SVM分类器在三类数据上的决策边界。不同颜色的区域表示不同的类别,数据点的颜色表示其真实类别。可以看到,SVM成功地将三个类别分开,并在类别之间建立了清晰的决策边界。
支持向量
红色的"X"标记表示支持向量的位置。这些点是决定分类边界的关键点,它们位于类别边界附近,对模型的决策起着决定性作用。
总结与思考
-
优势
- SVM在高维空间中表现出色
- 内存效率高,因为只使用支持向量进行决策
- 通过不同的核函数可以处理各种类型的分类问题
- 理论基础扎实,有很好的泛化性能
-
局限性
- 对大规模数据集计算开销较大
- 核函数的选择需要经验和多次尝试
- 对特征缩放敏感,需要进行适当的数据预处理
-
应用场景
- 文本分类
- 图像分类
- 生物信息学
- 金融预测
- 模式识别
-
实践建议
- 数据预处理很重要,建议进行标准化或归一化
- 根据数据特点选择合适的核函数
- 通过交叉验证选择最优的超参数
- 注意类别不平衡问题
扩展阅读
- 软间隔SVM:处理有噪声的数据
- 多类SVM:处理多类分类问题的策略
- SVR(Support Vector Regression):SVM在回归问题中的应用
- 在线SVM:处理流数据的SVM变体
同学们如果有疑问可以私信答疑,如果有讲的不好的地方或可以改善的地方可以一起交流,谢谢大家。