你在一个屋子里举行了一个聚会,里面既有男孩也有女孩。现在你想把他们按性别分开,男孩站到屋子的一边,女孩站到另一边。你肯定会想,要是能在中间划条线把他们分开多好啊!这就像是支持向量机(SVM)的工作方式,它就像一个神奇的画家,能在人群中间画出一条界限。
但是,你不想让大家挨得太紧,每个人都需要有点私人空间对不对?所以,你不单单画一条细细的线,而是想画一条足够宽的间隔,就像是两条平行的线之间的空白区域。这样,男孩和女孩都能在这条宽宽的间隔两边自在地活动,而且不会互相干扰。
现在,如果有新的朋友加入聚会,他们可能会疑惑自己该站在哪一边。这时候,我们的神奇画家,也就是支持向量机,就会利用它之前画的宽间隔来帮助判断。如果新朋友站在间隔的这一侧,那他很可能是男孩;如果站在那一侧,她很可能是女孩。
所以,支持向量机就好比是个非常聪明的画家,它不仅帮我们把人群按照性别分组,而且当有新人加入时,也能利用已经划定的宽间隔来判断新来的是男孩还是女孩。这就是支持向量机的魅力所在,它能帮我们清晰地将事物分类,并为每个类别留下足够的空间,以便未来的分类也同样准确。
线性支持向量机(Linear Support Vector Machine)是一种用于分类和回归分析的监督学习模型。在二分类中,线性支持向量机的主要目标是找出一个线性超平面,将不同类别的数据分隔开,而且要使得这个超平面到最近的数据点之间的距离(也被称为间隔)尽可能大。
支持向量机(Support Vector Machine, SVM)的基本想法是寻找一个超平面(决策边界)来分类数据,而这个超平面的选择不仅需要正确地分类数据,还需要最大化其与最近样本点的距离,这就是所谓的最大化间隔(Margin)。
假设我们的数据集是线性可分的,也就是说,存在至少一个超平面可以完全正确地将两类数据分开。在这种情况下,我们可以找到不只一个,而是很多这样的超平面。那么哪一个超平面是最好的呢?直观上,我们会认为最好的超平面是那个与最近的数据点(不管是正类还是负类)保持最大间隔的那个。这个间隔就好比是一条没有数据点的“安全带”。
为了找到这个最大间隔超平面,我们首先定义两个平行的辅助超平面,它们分别穿过最靠近决策边界的正类和负类样本点,这些点叫做支持向量。这两个辅助超平面可以用以下的数学公式表示:
这里的 是一个向量,它垂直于我们的超平面,而 是一个标量,它影响超平面的偏置。通过简单的几何推导,我们可以得出这两个超平面之间的距离是 ,其中 表示向量 的长度(或者说是范数)。为了最大化超平面之间的距离,我们需要最小化 。
然而,我们还得确保所有的样本点都被正确分类,也就是说,正类样本点应该在 这个超平面的一侧,而负类样本点在另一侧。用数学语言来表达,如果样本点 属于正类(),我们需要:
如果样本点属于负类(),我们需要:
这两种情况可以合并成一个不等式:
现在,我们的目标就变成了在保证上述不等式成立的情况下,最小化 。这个优化问题的解决方案将给我们最大间隔超平面的具体参数 和 。
最终,我们的分类器函数可以用以下公式定义:
其中 是符号函数,它根据输入的符号返回 1 或者 -1。简而言之,根据超平面的方程,我们可以预测任何新的样本点 的类别。
值得一提的是,最大间隔超平面完全由支持向量决定,这些是最靠近决策边界的样本点。我们的超平面会尽可能地远离这些点,以确保有最大的间隔,这就是为什么它被称为“硬间隔”。在实际应用中,如果数据不是完全线性可分的,我们可能需要使用所谓的“软间隔”方法来允许一些分类错误,但这已经超出了硬间隔的范畴。
硬间隔SVM适用于那些数据完全线性可分的情况,它严格要求所有的样本点都要正确分类,没有一个是被分类错误的。但现实世界中的数据往往不是那么完美,可能会有噪声,或者数据本身就不是完全线性可分的。这时候,硬间隔SVM就力不从心了,因为它不能处理分类错误的情况。为了解决这个问题,我们引入了软间隔SVM。
软间隔SVM的核心思想是容忍一些样本点被分类错误,以便在大多数样本点上得到一个较好的分类效果。为了实现这个目标,我们引入了一种称为合页损失函数的损失函数,用来量化分类错误的程度。
合页损失函数的数学表达式如下:
这里, 是我们要找的决策边界的权重向量, 是偏置项, 是第 个样本点的真实标签(+1 或 -1), 是第 个样本点的特征向量。
如果一个样本点 正确分类了,也就是说,它位于决策边界的正确一侧,那么它的合页损失函数值将为零。如果它被错误分类,那么损失函数值将随着它距离边界的距离增加而增加。
我们的目标是找到一个权重向量 和偏置项 ,使得下面的目标函数最小化:
其中,第一项是平均合页损失,也就是平均错误程度的量化;第二项是权重向量的平方范数,用于控制模型的复杂度,避免过拟合。参数 是一个正则化参数,它用于平衡间隔大小和分类错误之间的权衡。
通过调整 ,我们可以在保证大部分样本正确分类的同时,允许一些样本分类错误。当 足够小,如果数据是线性可分的,软间隔SVM和硬间隔SVM的表现是相似的。但如果数据不是线性可分的,软间隔SVM仍然能够通过容忍一些错误来找到一个有效的分类规则。这就是软间隔SVM的主要优势所在。
要评估线性SVM模型的准确率,我们可以使用混淆矩阵(Confusion Matrix)来计算各种分类指标,如准确率、精确率、召回率和F1得分。
假设我们的线性SVM回归模型有两个类别,分别为正例(Positive)和反例(Negative)。
具体可见准确性评价指标的分类问题。
1from sklearn import svm
2from sklearn.datasets import make_blobs
3import matplotlib.pyplot as plt
4import numpy as np
5
6# 创建 40个分隔的数据点
7X, y = make_blobs(n_samples=40, centers=2, random_state=20)
8
9# 拟合模型,不要规整化参数C设置为较高的值
10clf = svm.SVC(kernel='linear', C=1000)
11clf.fit(X, y)
12
13# 绘制图像
14plt.scatter(X[:, 0], X[:, 1], c=y, s=30, cmap=plt.cm.Paired)
15
16# 绘制决策函数
17ax = plt.gca()
18xlim = ax.get_xlim()
19ylim = ax.get_ylim()
20
21# 创建评估模型的网格
22xx = np.linspace(xlim[0], xlim[1], 30)
23yy = np.linspace(ylim[0], ylim[1], 30)
24YY, XX = np.meshgrid(yy, xx)
25xy = np.vstack([XX.ravel(), YY.ravel()]).T
26Z = clf.decision_function(xy).reshape(XX.shape)
27
28# 绘制决策边界和边缘
29ax.contour(XX, YY, Z, colors='k', levels=[-1, 0, 1], alpha=0.5, linestyles=['--', '-', '--'])
30
31# 绘制支持向量
32ax.scatter(clf.support_vectors_[:, 0], clf.support_vectors_[:, 1], s=100, facecolors='none', edgecolors='k')
33
34plt.show()
1from sklearn import svm
2from sklearn.datasets import make_blobs
3import matplotlib.pyplot as plt
4import numpy as np
5
6# 创建 40个分隔的数据点
7X, y = make_blobs(n_samples=40, centers=2, random_state=20)
8
9# 拟合模型,不要规整化参数C设置为较高的值
10clf = svm.SVC(kernel='linear', C=1000)
11clf.fit(X, y)
12
13# 绘制图像
14plt.scatter(X[:, 0], X[:, 1], c=y, s=30, cmap=plt.cm.Paired)
15
16# 绘制决策函数
17ax = plt.gca()
18xlim = ax.get_xlim()
19ylim = ax.get_ylim()
20
21# 创建评估模型的网格
22xx = np.linspace(xlim[0], xlim[1], 30)
23yy = np.linspace(ylim[0], ylim[1], 30)
24YY, XX = np.meshgrid(yy, xx)
25xy = np.vstack([XX.ravel(), YY.ravel()]).T
26Z = clf.decision_function(xy).reshape(XX.shape)
27
28# 绘制决策边界和边缘
29ax.contour(XX, YY, Z, colors='k', levels=[-1, 0, 1], alpha=0.5, linestyles=['--', '-', '--'])
30
31# 绘制支持向量
32ax.scatter(clf.support_vectors_[:, 0], clf.support_vectors_[:, 1], s=100, facecolors='none', edgecolors='k')
33
34plt.show()
此代码首先生成了40个服从正态分布的数据点并将其分成两类。接着初始化一个SVM分类器并对数据进行训练。然后,它创建了一个网格用于评估模型并绘制决策边界和边界以及支持向量。最后,代码生成了一个图,显示了SVM模型是如何对数据分类的,支持向量是什么,以及决策边界和边缘是如何确定的。
输出结果:
优点:
缺点: