🧨概念
支持向量机(Support Vector Machine, SVM)是一种强大的机器学习算法,主要用于解决二分类问题。
SVM的核心思想是找到一个超平面,这个超平面能够最好地将数据分为两类,即在保证分类准确的情况下,使得两个类别的数据到超平面的最小距离(即间隔)最大。
- 对于线性可分的数据,SVM通过硬间隔最大化学习一个线性分类器。这意味着所有训练样本都能够被超平面正确分开,并且最近的样本点与超平面之间的距离(即间隔)达到最大。
- 当数据不是完全线性可分时,SVM通过软间隔最大化来学习一个线性分类器。这意味着允许一些样本不满足硬间隔的要求,但仍然尽可能地使间隔最大化。
- 对于非线性可分的数据,SVM使用核技巧将数据映射到更高维度的空间中,使其变得线性可分,然后再进行间隔最大化。这种方法使得SVM成为一个实质上的非线性分类器。
- 无论是线性还是非线性的情况,SVM的求解过程最终都转化为一个凸二次规划问题。这是因为SVM的目标函数是一个凸函数,可以通过求解凸优化问题来找到全局最优解。
- 由于其坚实的理论基础和良好的泛化能力,SVM在许多领域都得到了广泛的应用,包括文本分类、图像识别、生物信息学等。
🧨引入
对于桌面上颜色不同的两种小球,用一根棍分开它们,我们可以直接将其放在两种小球中间隔开他们,尽可能使得木棍距离两个群体都远,这样可以方便更多数据进来时有更好的分辨率。
我们放了更多的球,棍仍然是一个好的分界线,但如果我们打乱小球分布,该如何隔开他们?
现在,我们没有棍可以很好帮他分开两种球了 ,我们可以将小球扔到空中进入一个多维空间
但在上边看来就是一个曲线隔开的。我们的数据就是小球data,棍子就是分类器classifier 。
🧨支持向量机分类
- 线性SVM:对于线性可分的数据,SVM能够找到一个超平面,使得所有训练样本都能够被正确分开,并且最近的样本点与超平面之间的距离(即间隔)达到最大。这种情况下的SVM称为线性SVM。
- 非线性SVM:当数据在原始空间中不是线性可分时,SVM使用核技巧将数据映射到更高维度的空间中,使其变得线性可分。在这个高维特征空间中,SVM学习一个线性分类器来进行分类。这种方法使得SVM成为一个实质上的非线性分类器。
根据在检验样本上的运行效果,分类器必须从这些分类超平面中选择一个来表示它的决策边界。满足这个条件的很多,但是使得泛化误差最小的条件就是边际margin最大的情况。
🧨 软间隔和硬间隔
- 硬间隔指的是让所有的样本都不在最大间隔之间,并位于正确的一边,这就是硬间隔。如果出现异常值、或者样本不能线性可分,此时硬间隔无法实现。
- 软间隔指的是我们容忍一部分样本在最大间隔之内,甚至在错误的一边。相对来说,软间隔可以应用在一些线性不可分的场景。
🧨惩罚参数 C
SVM中的惩罚参数C是一个非常重要的超参数,它决定了算法对错误分类的容忍度。
在SVM中,C参数用于控制间隔大小与分类误差之间的权衡。较大的C值意味着算法更加重视分类误差,即算法会尽量减小训练集上的分类错误。相反,较小的C值意味着算法更加重视最大化间隔,即使这可能导致在训练集上有更多的分类错误。
C值的选择对模型的泛化能力有显著影响。如果C设置得过大,模型可能会过度拟合训练数据,导致在未知数据上的表现不佳。这是因为模型过于关注训练集中的每个样本,包括那些可能仅仅是噪声的样本。相反,如果C设置得过小,模型可能会欠拟合,即对训练数据的分类错误过多,这也会影响模型在新数据上的性能。
在实际的应用中,选择合适的C值是非常重要的。通常,这需要通过交叉验证等技术来进行评估和选择。
🧨SVM损失函数
SVM的损失函数通常指的是合页损失函数(Hinge Loss),它是一种变种损失函数,用于最大间隔分类。合页损失函数的表达式为:
yi 是样本的标签,omega 和 b 分别是模型的权重和偏置项,xi 是第 i 个样本的特征向量。这个损失函数的第一部分是经验风险,它度量了模型对训练数据的拟合程度。当预测值与实际标签之间的差距大于1时,损失为0;否则,损失为1−yi(ωTxi+b)。
🧨鸢尾花种类预测
Iris 数据集是常用的分类实验数据集,也称鸢尾花卉数据集,是一类多重变量分析的数据集。
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
if __name__ == '__main__':
# 加载数据集
x, y = load_iris(return_X_y=True)
# 数据集分割
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, stratify=y)
# 特征值标准化
transformer = StandardScaler()
x_train = transformer.fit_transform(x_train)
x_test = transformer.transform(x_test)
# 模型训练
estimator = SVC()
estimator.fit(x_train, y_train)
# 模型预测
print(estimator.score(x_test, y_test))
分割数据集时stratify=y
的作用是在划分训练集和测试集时,保持类别的比例。这样可以确保在训练集和测试集中各类别的比例与原始数据集中的比例相同,有助于避免因数据分布不均导致的模型性能偏差。