支持向量机(Support Vector Machine, SVM)是一种广泛应用于分类和回归问题的监督学习算法。由于其出色的性能和强大的理论基础,SVM在机器学习领域占据了重要地位。本文将详细介绍SVM的基本原理、数学推导、核函数的作用以及实际应用场景,帮助读者深入理解这一强大的机器学习工具。
SVM的基本概念
1、什么是支持向量机?
支持向量机是一种二分类模型,其基本思想是找到一个超平面,将不同类别的样本分开,并且使得两类样本之间的间隔最大化。这个超平面被称为最大间隔超平面,而距离超平面最近的样本点被称为支持向量。
2、线性可分与线性不可分
线性可分:当数据集中的样本可以通过一个超平面完全分开时,我们称该数据集是线性可分的。
线性不可分:当数据集中的样本无法通过一个超平面完全分开时,我们称该数据集是线性不可分的。此时,SVM可以通过引入核函数来处理非线性问题。
SVM的数学推导
1、最大间隔超平面
假设我们有一个线性可分的数据集,样本点表示为 (xi,yi),其中 xi 是特征向量,yi∈{−1,1}是类别标签。我们的目标是找到一个超平面 w⋅x+b=0w⋅x+b=0,使得所有样本点满足:
这个超平面的间隔(即两类样本之间的最小距离)为:
为了最大化间隔,我们需要最小化 ∥w∥,即:
这是一个带约束的优化问题,可以通过拉格朗日乘子法求解。
2、拉格朗日对偶问题
通过引入拉格朗日乘子 αi,我们可以将原始优化问题转化为其对偶问题:
约束条件为:
求解这个对偶问题可以得到最优的 αi,进而得到超平面的参数 w和 b。
3、支持向量
在求解过程中,只有那些 αi>0 的样本点对最终的分类超平面有贡献,这些点就是支持向量。支持向量是距离超平面最近的样本点,它们决定了超平面的位置和方向。
核函数与非线性SVM
1、核函数的作用
当数据集线性不可分时,我们可以通过引入核函数将数据映射到高维空间,使得在高维空间中数据变得线性可分。常用的核函数包括:
线性核:
多项式核:
径向基核(RBF):
Sigmoid核:
2、非线性SVM的优化问题
引入核函数后,SVM的优化问题变为:
约束条件与线性SVM相同。
SVM的应用
1、分类问题
SVM最初是为二分类问题设计的,但可以通过一些扩展(如“一对多”或“一对一”策略)来处理多分类问题。SVM在文本分类、图像识别、生物信息学等领域有广泛应用。
2、回归问题
通过引入支持向量回归(SVR),SVM也可以用于回归问题。SVR的目标是找到一个回归函数,使得大部分样本点落在回归函数周围的某个间隔带内。
3、 异常检测
SVM还可以用于异常检测,通过将正常样本与异常样本分开,SVM可以识别出数据中的异常点。
SVM的优缺点
1、 优点
高维数据处理能力强:SVM在高维空间中表现良好,尤其适用于特征维度远大于样本数量的情况。
泛化能力强:SVM通过最大化间隔来提高模型的泛化能力,避免过拟合。
核函数灵活:通过选择不同的核函数,SVM可以处理线性和非线性问题。
2 、缺点
计算复杂度高:SVM的训练时间复杂度较高,尤其在大规模数据集上。
参数选择敏感:SVM的性能对核函数的选择和参数设置(如正则化参数 C和核参数 γ)非常敏感。
实际应用案例
下面我们来使用支持向量机(SVM)对数据进行分类来实现对鸢尾花数据集可视化
数据集
代码实现
#导入相应的库
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.svm import SVC
data = pd.read_csv("iris.csv",header=None)
"""可视化原始数据"""
data1 = data.iloc[:50, :]
data2 = data.iloc[50:, :]
# 原始数据是四维,无法展示,选择两个进行展示
plt.scatter(data1[1], data1[3], marker='+')
plt.scatter(data2[1], data2[3], marker='o')
"""使用SVM进行训练"""
#划分特征和标签
x = data.iloc[:, [1,3]]
y = data.iloc[:, -1]
# 标准化数据
# scaler = StandardScaler()
# x = scaler.fit_transform(x)
#划分训练集,测试集
x_train,x_test,y_train,y_test = \
train_test_split(x,y,test_size=0.2,random_state=42)
#建立SVM模型
#kernel='linear'表示创建线性核的SVM分类器,C=float('inf')表示不允许分类错误
svm = SVC(kernel='linear',C=float('inf'),random_state=0)
#模型训练
svm.fit(x_train,y_train)
"""可视化SVM结果"""
#获取 SVM 模型的权重向量w和偏置项b
# 参数w[原始数据为二维数组]
w = svm.coef_[0]
# 偏置项[原始数据为一维数组]
b = svm.intercept_[0]
### w 和 b 决定了模型的决策边界
# 在 0 到 7 之间生成 300 个等间距的点,作为特征x1的值
x1 = np.linspace(0, 7, 300)
# 超平面方程
x2 = -(w[0] * x1 + b) / w[1]
# 上超平面方程
x3 = (1 - (w[0] * x1 + b)) / w[1]
# 下超平面方程
x4 = (-1 - (w[0] * x1 + b)) / w[1]
# 可视化超平面
plt.plot(x1, x2, linewidth=2, color='r')
plt.plot(x1, x3, linewidth=1, color='r', linestyle='--')
plt.plot(x1, x4, linewidth=1, color='r', linestyle='--')
# 进行坐标轴限制
plt.xlim(4, 7)
plt.ylim(0, 5)
# 找到支持向量[二维数组]可视化支持向量
# svm.support_vectors_是 SVM 模型中的一个属性,返回所有支持向量。
# vets 是一个二维数组,每一行表示一个支持向量的特征值
vets = svm.support_vectors_#返回所有的支持向量
print(vets)
# vets[:, 0] 和 vets[:, 1] 分别表示支持向量的第一个和第二个特征值(假设数据是二维的)。
plt.scatter(vets[:, 0], vets[:, 1], c='b', marker='x')
plt.show()
运行结果
总结
支持向量机是一种强大的机器学习算法,具有坚实的理论基础和广泛的应用场景。通过理解SVM的基本原理、数学推导和核函数的作用,我们可以更好地应用SVM解决实际问题。尽管SVM在处理大规模数据时存在一些挑战,但其在高维数据和小样本数据上的表现仍然非常出色。
希望本文能帮助读者深入理解SVM,并在实际项目中灵活运用这一强大的工具。如果你有任何问题或建议,欢迎在评论区留言讨论!