在深入讨论支持向量机之前,假设已经对线性回归和逻辑回归有所了解。如果想学习逻辑回归,可以点击。也可以查看其。本文结束时,将了解支持向量机的基础知识。
支持向量机是一种监督学习算法,用于分类和回归分析。然而,数据科学家更倾向于将其主要用于分类目的。现在,来探讨SVM的特殊之处。在SVM中,数据点可以在N维空间中进行分类。例如,考虑以下在二维平面上绘制的点:
图片来源:
如果查看图像的左侧,会注意到绘制的数据点不能在给定平面上用线性方程分离。这是否意味着它不能被分类?当然不是!当然可以。只需查看图像的右侧。发现什么有趣的了吗?猜对了,它在三维平面上是可分离的。现在数据点不是用二维平面上的线性分类器分离的,而是用三维空间中的超平面分离的。这就是SVM如此特别的原因!
现在希望模型能够很好地预测新数据。当然,它可以预测训练数据,但至少希望模型能够非常准确地预测验证集数据。现在,想象一下在二维空间中绘制的点。考虑一个决策边界,它将数据很好地分成两个类别。现在,远离决策边界的点可以很容易地被分类为一个组。现在,想想那些非常靠近决策边界的点。别担心!将在更多细节中讨论。考虑下图中显示的点A和B:
现在可以清楚地看到点B属于绿色点类别,因为它远离决策线。但是A呢?它属于哪个类别?可能认为它也属于绿色点类别。但事实并非如此。如果决策边界发生变化呢?请参见下图:
现在,如果将灰线视为决策边界,点A被分类为蓝色点。另一方面,如果将粗红线视为决策边界,它被分类为绿色点。现在遇到了麻烦!为了避免这种歧义,想引入“边界”的概念。边界是一个超平面,它最大化了两个类别之间的边界。决策边界位于两个边界的中间。两个边界移动直到它们遇到类别的第一个点。为了避免错误,总是最大化边界的宽度。这将在后续部分中讨论。
让考虑向量w垂直于决策边界(注意边界和决策边界是平行线)。有一个未知向量(点)u,需要检查它位于线的绿色侧还是蓝色侧。这可以通过一个决策规则来完成,帮助找到它的正确类别。如下所示:
if (w · x + b) ≥ 0, then y = 1 (green side)
if (w · x + b) < 0, then y = -1 (blue side)
请注意,上述两个方程中的‘b’是一个常数。但可以看到,在有一个单一方程之前,这两个方程是没有帮助的。要将上述两个方程转换为一个单一方程,再次定义一个变量y,它可以取1或-1的值。这个变量y乘以上述两个方程,结果如下:
y(w · x + b) ≥ 0, then y = 1
y(w · x + b) < 0, then y = -1
现在可以看到,当乘以y时,这两个方程变成了相同的方程。现在最终决策规则如下:
正如在文章开头讨论的,希望最大化宽度以避免错误。现在是找出计算边界宽度的方法的时候了。从上述方程中可以清楚地看出,宽度等于向量w的幅度的倒数。由于分子中的2是一个常数,可以忽略它,并将分子保持为1。
现在,已经在上一节中找到了宽度。正如已经提到的,宽度必须最大化,直到遇到每个类别的任何点。现在,为了最大化宽度,实际上必须最小化以下方程:
minimize ||w||^2
现在,将使用拉格朗日方法来最小化它,如下所示:
L = ||w||^2 - Σ[αi * (w · x_i + b) - 1] * yi
∂L/∂b = Σ[αi * yi] = 0
∂L/∂w = 2w - Σ[αi * yi * x_i] = 0
# Python代码
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn import svm
import matplotlib.pyplot as plt
# 加载数据集
iris = datasets.load_iris()
X = iris.data
y = iris.target
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)
# 创建SVM分类器
clf = svm.SVC(kernel='linear')
# 训练模型
clf.fit(X_train, y_train)
# 测试模型
score = clf.score(X_test, y_test)
print("模型准确率:", score)
# 绘制决策边界
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, edgecolors='k')
plt.title("SVM决策边界")
plt.show()