支持向量机(SVM)


支持向量机简介

支持向量机 (SVM) 是强大而灵活的监督机器学习算法,可用于分类和回归。但一般来说,它们用于分类问题。SVM 在 20 世纪 60 年代首次出现,但后来在 1990 年得到完善。与其他机器学习算法相比,SVM 有其独特的实现方式。最近,它们由于能够处理多个连续变量和分类变量而非常受欢迎。

支持向量机的工作原理

SVM 模型基本上是多维空间超平面中不同类的表示。超平面将由SVM以迭代的方式生成,以便可以最小化误差。SVM 的目标是将数据集分类以找到最大边缘超平面 (MMH)。

利润

以下是 SVM 中的重要概念 -

  • 支持向量- 最接近超平面的数据点称为支持向量。将在这些数据点的帮助下定义分隔线。

  • 超平面- 正如我们在上图中看到的,它是一个决策平面或空间,被划分为一组具有不同类别的对象。

  • 边距- 它可以定义为不同类的最接近数据点上两条线之间的间隙。它可以计算为从线到支持向量的垂直距离。大的利润被认为是好的利润,小利润被认为是坏的利润。

SVM 的主要目标是将数据集分类以找到最大边缘超平面(MMH),可以通过以下两个步骤完成 -

  • 首先,SVM 将迭代生成超平面,以最佳方式分隔类别。

  • 然后,它将选择正确分隔类别的超平面。

在 Python 中实现 SVM

为了在 Python 中实现 SVM,我们将从标准库导入开始,如下所示 -

import numpy as np
import matplotlib.pyplot as plt
from scipy import stats
import seaborn as sns; sns.set()

接下来,我们从 sklearn.dataset.sample_generator 创建一个具有线性可分离数据的样本数据集,以便使用 SVM 进行分类 -

from sklearn.datasets.samples_generator import make_blobs
X, y = make_blobs(n_samples=100, centers=2, random_state=0, cluster_std=0.50)
plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='summer');

以下是生成具有 100 个样本和 2 个簇的样本数据集后的输出 -

地图

我们知道SVM支持判别分类。它通过简单地在二维情况下找到一条线或在多维情况下找到流形来将类别彼此分开。它在上述数据集上的实现如下 -

xfit = np.linspace(-1, 3.5)
plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='summer')
plt.plot([0.6], [2.1], 'x', color='black', markeredgewidth=4, markersize=12)
for m, b in [(1, 0.65), (0.5, 1.6), (-0.2, 2.9)]:
   plt.plot(xfit, m * xfit + b, '-k')
plt.xlim(-1, 3.5);   

输出如下 -

叉

从上面的输出中我们可以看到,存在三种不同的分离器可以完美地区分上述样本。

正如所讨论的,SVM 的主要目标是将数据集划分为类,以找到最大边缘超平面 (MMH),因此我们可以在每条线周围绘制一定宽度的边缘,直到最近的点,而不是在类之间绘制零线。可以按如下方式完成 -

xfit = np.linspace(-1, 3.5)
plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='summer')
   for m, b, d in [(1, 0.65, 0.33), (0.5, 1.6, 0.55), (-0.2, 2.9, 0.2)]:
   yfit = m * xfit + b
   plt.plot(xfit, yfit, '-k')
   plt.fill_between(xfit, yfit - d, yfit + d, edgecolor='none',
         color='#AAAAAA', alpha=0.4)
plt.xlim(-1, 3.5);
绿色的

从上面的输出图像中,我们可以轻松观察判别分类器内的“边缘”。SVM 将选择最大化边际的线。

接下来,我们将使用 Scikit-Learn 的支持向量分类器在此数据上训练 SVM 模型。在这里,我们使用线性核来拟合 SVM,如下所示 -

from sklearn.svm import SVC # "Support vector classifier"
model = SVC(kernel='linear', C=1E10)
model.fit(X, y)

输出如下 -

SVC(C=10000000000.0, cache_size=200, class_weight=None, coef0=0.0,
decision_function_shape='ovr', degree=3, gamma='auto_deprecated',
kernel='linear', max_iter=-1, probability=False, random_state=None,
shrinking=True, tol=0.001, verbose=False)

现在,为了更好地理解,下面将绘制 2D SVC 的决策函数 -

def decision_function(model, ax=None, plot_support=True):
   if ax is None:
      ax = plt.gca()
   xlim = ax.get_xlim()
   ylim = ax.get_ylim()

为了评估模型,我们需要创建网格如下 -

x = np.linspace(xlim[0], xlim[1], 30)
y = np.linspace(ylim[0], ylim[1], 30)
Y, X = np.meshgrid(y, x)
xy = np.vstack([X.ravel(), Y.ravel()]).T
P = model.decision_function(xy).reshape(X.shape)

接下来,我们需要绘制决策边界和边际,如下所示 -

ax.contour(X, Y, P, colors='k',
   levels=[-1, 0, 1], alpha=0.5,
   linestyles=['--', '-', '--'])

现在,类似地绘制支持向量,如下所示 -

if plot_support:
   ax.scatter(model.support_vectors_[:, 0],
      model.support_vectors_[:, 1],
      s=300, linewidth=1, facecolors='none');
ax.set_xlim(xlim)
ax.set_ylim(ylim)

现在,使用此函数来拟合我们的模型,如下所示 -

plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='summer')
decision_function(model);
黄色的

我们可以从上面的输出中观察到,SVM 分类器适合带有边距的数据,即虚线和支持向量(该拟合的关键元素),接触虚线。这些支持向量点存储在分类器的 support_vectors_ 属性中,如下所示 -

model.support_vectors_

输出如下 -

array([[0.5323772 , 3.31338909],
   [2.11114739, 3.57660449],
   [1.46870582, 1.86947425]])

支持向量机内核

在实践中,SVM算法是通过内核来实现的,该内核将输入数据空间转换为所需的形式。SVM 使用一种称为核技巧的技术,其中核采用低维输入空间并将其转换为高维空间。简而言之,内核通过添加更多维度将不可分离问题转化为可分离问题。它使SVM更加强大、灵活和准确。以下是 SVM 使用的一些内核类型 -

线性核

它可以用作任意两个观测值之间的点积。线性核的公式如下 -

k(x,x i ) = 总和(x*x i )

从上面的公式,我们可以看到两个向量之间的乘积表示