目录
一、支持向量机(SVM)算法概述
1. 什么是支持向量机
支持向量机(SVM, support Vector Machines):二分类算法模型,它的目的是寻找一个超平面来对样本进行分割,分割的原则是间隔最大化,最终转化为一个凸二次规划问题来求解。由简至繁的模型包括:
- 当训练样本线性可分时,通过硬间隔最大化,学习一个线性可分支持向量机
- 当训练样本近似线性可分时,通过软间隔最大化,学习一个线性支持向量机
- 当训练样本线性不可分时,通过核技巧和软间隔最大化,学习一个非线性支持向量机
用于解决模式识别领域中的数据分类问题,属于有监督学习算法。支持向量机可以分为线性核非线性两大类。
2. 主要思想
找到空间中的一个更够将所有数据样本划开的超平面,并且使得本本集中所有数据到这个超平面的距离最短。
3. 优点
- 当数据集较小时,分类效果优于神经网络。
- 能造出最大间距的决策边界从而提高分类算法的效率。
二、支持向量机算法原理
1. 支持向量与超平面
线性分类器:给定一系列的数据样本,每个样本都有对应的一个标签。
以二维平面举例,如下图所示是一个二维平面,平面上有两类不同的数据,分别用圆圈和方块表示。我们可以很简单地找到一条直线使得两类数据正好能够完全分开。但是能将据点完全划开直线不止一条,那么在如此众多的直线中我们应该选择哪一条呢?我们希望寻找到这样的直线,使得距离这条直线最近的点到这条直线的距离最短。
如下图,就是要求的两条外面的线之间的间隔最大。
在高维空间中这样的直线称之为超平面,因为当维数大于三的时候我们已经无法想象出这个平面的具体样子。那些距离这个超平面最近的点就是所谓支持向量,实际上如果确定了支持向量也就确定了这个超平面,找到这些支持向量之后其他样本就不会起作用了。
2. 最大间隔与分类
在样本空间
中寻找一个超平面 用于区分不同样本
支持向量——距离超平面最近的点
二分类有两个支持向量平面,这两个平面是平行的。超平面是位于这两个平面中间的。
最大化间隔:margin最大的数即为最大化的间隔
定义我们待求的超平面为
求margin:
a上有一点x1,b上有一点x2,原点为O,的表示为(x1-O),
的表示为(x2-O),所以可以得到(
—
)为两向量的差,margin可表示为:
需要使margin得到最大值:
即将求margin最大值问题转为求解w最小值:
将超平面上方标记为1,下方标记为-1,根据已设a,b面可得约束条件为:
引入拉格朗日乘子 :
将问题无约束化
此时要满足KKT条件:
KKT条件:满足所有要求条件
如
i=1,2,3...,m i的取值范围为1-m即需要满足m个条件
拉格朗日:
①
②
③带回第一步求最小值:
可得最终模型
对于KKT条件需要满足:
由此可得
若 只与支持向量上点有关
若 不在最大边界点上
3. 求解问题——SMO
SMO算法是支持向量机学习的一种快速算法,其特点是不断地将原二次规划问题分解为只有两个变量的二次规划子问题,并对子问题进行解析求解,知道所有变量满足KKT条件为止。这样通过启发式的方法得到原二次规划问题的最优解。因为子问题有解析解,所以每次计算子问题都很快,虽然计算子问题次数很多,但在总体上还是高效的。
4. 核函数
Mercer定理:只要对称函数值所对应的核函数半正定,则为核函数
为什么会用到核函数?
用于解决线性不可分问题,将线性不可分的函数进行升维到高维可分函数。
如
映射为:
基本思想为将x映射为,处理过程同二维,仅
与
不同,其余都相同计算过程,即不多赘述。
5. SVM 算法特性
- 训练好的模型的算法复杂度是由支持向量的个数决定的,而不是由数据的维度决定的。所以 SVM 不太容易产生过拟合。
- SVM 训练出来的模型完全依赖于支持向量,即使训练集里面所有非支持向量的点都被去除,重复训练过程,结果仍然会得到完全一样的模型。
- 一个 SVM 如果训练得出的支持向量个数比较少,那么SVM 训练出的模型比较容易被泛化。
三、利用SVM进行线性回归分类
代码:
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats
# 引入数据集,并可视化
from sklearn.datasets._samples_generator import make_blobs
X, y = make_blobs(n_samples=50, centers=2,
random_state=0, cluster_std=0.60)
# plt.figure(figsize=(8,8))
# plt.scatter(X[:, 0], X[:, 1], c=y, s=50)
散点图:
#要完成一个分类问题,需要在2种不同的样本点之间产出一条“决策边界”,下图显示了3条不同的可选决策边界。
xfit = np.linspace(-1, 3.5)
plt.figure(figsize=(8,8))
plt.scatter(X[:, 0], X[:, 1], c=y, s=50)
for k, b in [(1, 0.65), (0.5, 1.6), (-0.2, 2.9)]:
# print('k \t'+str(k))
# print('b \t'+str(b))
# print("-------------")
plt.plot(xfit, k * xfit + b, '-k')
plt.xlim(-1, 3.5)
#拟合支持向量机,这是一个线性可切分的例子,用sklearn中linear kernel的svm来分一下。
#构建一个线性SVM分类器
from sklearn.svm import SVC # "Support Vector Classifier"
clf = SVC(kernel='linear')
clf.fit(X, y)
# 可视化函数
def plot_svc_decision_function(clf, ax=None):
"""Plot the decision function for a 2D SVC"""
if ax is None:
ax = plt.gca()
x = np.linspace(plt.xlim()[0], plt.xlim()[1], 30)
y = np.linspace(plt.ylim()[0], plt.ylim()[1], 30)
Y, X = np.meshgrid(y, x)
P = np.zeros_like(X)
for i, xi in enumerate(x):
for j, yj in enumerate(y):
P[i, j] = clf.decision_function([[xi, yj]])
# plot the margins
ax.contour(X, Y, P, colors='k',
levels=[-1, 0, 1], alpha=0.5,
linestyles=['--', '-', '--'])
plt.figure(figsize=(8,8))
plt.scatter(X[:, 0], X[:, 1], c=y, s=50)
plot_svc_decision_function(clf)
plt.show()
分类结果:
四、总结
学习了SVM算法,勉强进行了算法的实现。