1.5-机器学习分类算法-SVM算法

1. SVM支持向量机

1.1 SVM基本原理

SVM(Support Vector Machine)中文名为支持向量机,在机器学习领域属于常见的有监督学习。一如下图所示的两堆点为例子,黄色和黑色的点显然是两种不同的类别,如果想将他们区分开来。可以通过画一条直线,作为两堆点的分界线。

import matplotlib.pyplot as plt
from sklearn.datasets.samples_generator import make_blobs
import numpy as np
X, y = make_blobs(n_samples=50, centers=2,
                  random_state=0, cluster_std=0.60)#随机生成两组点
plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn')
xfit = np.linspace(-2, 5)
plt.plot(xfit, 1 * xfit + 0.5, '-k')
[<matplotlib.lines.Line2D at 0x1246dfc18>]

当纬度升高时,超平面的公式可以概括为

总的来说,支持向量机算法中,最核心的部分就是要求出,因此训练过程就是要想办法求出最优的。而预测过程就是对输入数据提取特征向量,然后带入方程计算,得出当前点在超平面分割后空间中哪个区域,得出预测结果。可以看得出,其实在训练数据中,有一部分点对于超平面选取的影响至关重要,如上图,离直线最近的红点和黄点,这些对于分离超平面影响较大的数据点也被称为支持量。而最优的超平面显然就是一个到各个支持向量距离相等,并且这个距离最大的平面,根据公式,因为距离相等所以他们的也相等。

事实上,求解的过程也就是要让分类中里超平面最近的这些点,和超平面间的距离尽可能的大。

如何求间距最大的超平面呢?

设:

  • 超平面为:
  • 分类函数为:(sign函数表示输入大于0为1,小于0为-1,等于0为0)
  • 支持向量到超平面距离为:,表示W的二范式。也就是所有元素的平方求和,再开方。

现在的目的就是要让特征点处最小。由于各个特征点到分离面距离相同,所以在各个特征点的值也相同等于某个定值,干脆就假设。这样问题转化成了求:

这个函数的最大值点,等同于下面这个函数的最小值点

当然,还有一个限制条件,之前我们假设了标签分类结果为1或者-1。支持向量处。正确预测的情况下,

最后问题转换成了求: 限制条件为:

后面的推导还用了拉格朗日乘子法,然后神奇的推导成了使用拉格朗日乘子法求:

1.2 核函数

假如在原始的特征纬度中无法找到一个能够分割数据的超平面,那么就需要核函数的帮助。所谓的核函数,本质上是将原始特征映射到一个高纬度空间,从而解决原始空间无法线性分割的问题。以下图为例,在下图的这个一纬度空间中,我们如无法找到一个分界点,将绿色点和黄色点正确分开。

import matplotlib.pyplot as plt
plt.plot([-0.1,-0.2,-0.3], [0,0,0], 'o', color='yellow', markeredgewidth=2, markersize=10)
plt.plot([0.2,0.4,0.6], [0,0,0], 'o', color='green', markeredgewidth=2, markersize=10)
plt.plot([1.1,1.2,1.3], [0,0,0], 'o', color='yellow', markeredgewidth=2, markersize=10)
[<matplotlib.lines.Line2D at 0x125a31978>]

为了解决上述问题,我们可以把该一纬特征映射到更高纬度的二维空间中,如下图所示:

import matplotlib.pyplot as plt
plt.figure(figsize=(8, 8))#设置画布大小
ax = plt.gca()
ax.spines['bottom'].set_position(('data', 0))
ax.spines['left'].set_position(('data', 0))

plt.plot([-0.1,-0.2,-0.3], [0.01,0.04,0.09], 'o', color='yellow', markeredgewidth=2, markersize=10)
plt.plot([0.2,0.4,0.6], [0.04,0.16,0.36], 'o', color='green', markeredgewidth=2, markersize=10)
plt.plot([1.1,1.2,1.3], [1.21,1.44,1.69], 'o', color='yellow', markeredgewidth=2, markersize=10)
xfit = np.linspace(-0.5, 1.5)
plt.plot(xfit, 1 * xfit, '-k')
[<matplotlib.lines.Line2D at 0x126474400>]

此时,我们可以构建分离超平面将原本线性不可分的问题解决。

参考链接:

  • https://www.cnblogs.com/shayue/p/10399143.html 画图的
  • https://blog.csdn.net/fuqiuai/article/details/79483057 svm算法原理讲解
  • https://www.jianshu.com/p/f7d2ed8aac54 svm算法代码实现
  • https://blog.csdn.net/qq_35992440/article/details/80987664 svm数学推导