支持向量机SVM(一)

文章目录

  • 1 概述
  • 2 支持向量机分类器是如何工作的
  • 3 线性SVM用于分类的原理
    • 3.1 线性SVM的损失函数详解
    • 3.2 线性SVM的拉格朗日对偶函数和决策函数
      • 3.2.1将损失函数转换为拉格朗日乘数的形态
        • 3.2.1.1为什么可以转换成拉格朗日函数?
        • 3.2.1.2为什么可以进行转换?
        • 3.2.1.3 怎样进行转换?
      • 3.2.2将拉格朗日转换成对偶函数
        • 3.2.2.1 为什么要进行转换?
        • 3.2.2.2 为什么能够进行转换?
        • 3.2.2.3怎样转换?
    • 3.3 求解拉格朗日对偶函数极其后续过程
  • 4 线性SVM决策过程的可视化
  • 5 为非线性数据增加维度并绘制3D图像

1 概述

支持向量机(SVM,也称为支持向量网络),是机器学习中获得关注最多的算法没有之一。它源于统计学习理论,是我们除了集成算法之外,接触的第一个强学习器。它有多强呢?

从算法的功能来看,SVM几乎囊括了我们前六周讲解的所有算法的功能:
在这里插入图片描述
从分类效力来讲,SVM在无论线性还是非线性分类中,都是明星般的存在:
在这里插入图片描述

2 支持向量机分类器是如何工作的

支持向量机的分类方法,是在这组分布中找出一个超平面作为决策边界,使模型在数据上的分类误差尽量接近于小,尤其是在未知数据集上的分类误差(泛化误差)尽量小。
在这里插入图片描述
在这里插入图片描述
决策边界一侧的所有点在分类为属于一个类,而另一侧的所有点分类属于另一个类。如果我们能够找出决策边界,分类问题就可以变成探讨每个样本对于决策边界而言的相对位置。比如上面的数据分布,我们很容易就可以在方块和圆的中间画出一条线,并让所有落在直线左边的样本被分类为方块,在直线右边的样本被分类为圆。如果把数据当作我们的训练集,只要直线的一边只有一种类型的数据,就没有分类错误,我们的训练误差就会为0。但是,对于一个数据集来说,让训练误差为0的决策边界可以有无数条。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3 线性SVM用于分类的原理

3.1 线性SVM的损失函数详解

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.2 线性SVM的拉格朗日对偶函数和决策函数

在这里插入图片描述

3.2.1将损失函数转换为拉格朗日乘数的形态

3.2.1.1为什么可以转换成拉格朗日函数?

在这里插入图片描述
在这里插入图片描述

3.2.1.2为什么可以进行转换?

在这里插入图片描述

3.2.1.3 怎样进行转换?

在这里插入图片描述

3.2.2将拉格朗日转换成对偶函数

3.2.2.1 为什么要进行转换?

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.2.2.2 为什么能够进行转换?

在这里插入图片描述
在这里插入图片描述

3.2.2.3怎样转换?

在这里插入图片描述
在这里插入图片描述

3.3 求解拉格朗日对偶函数极其后续过程

在这里插入图片描述

4 线性SVM决策过程的可视化

from sklearn.datasets import make_blobs
from sklearn.svm import SVC
import matplotlib.pyplot as plt
import numpy as npx, y = make_blobs(n_samples=50, centers=2, random_state=0, cluster_std=0.6)
#print(x, y)#实例化数据集,可视化数据集plt.scatter(x[:, 0], x[:, 1], c=y, s=50, cmap="rainbow")
plt.xticks([])
plt.yticks([])
plt.show()

在这里插入图片描述

#画决策边界,理解函数counter
#首先要画散点图plt.scatter(x[:, 0], x[:, 1], c=y, s=50, cmap="rainbow")
ax = plt.gca()  #获取当前的子图,如果不存在,则创建新的子图#获取平面上两条坐标轴的最大值和最小值
xlim = ax.get_xlim()
#(-0.7503988002924934, 3.380032929005172)
ylim = ax.get_ylim()
#(-0.4292462471025815, 5.765392910228977)
#print(xlim, ylim)#在最大值和最小值之间形成30个规律的数据
axisx = np.linspace(xlim[0], xlim[1], 30)
axisy = np.linspace(ylim[0], ylim[1], 30)axisx, axisy = np.meshgrid(axisx, axisy)
#print(axisx.shape, axisy.shape)
#(30, 30) (30, 30) 这一步相当于从x轴和y轴分别找到30条线,然后让他们配对
#实质上,经过meshgrid之后呢,axisx是一个二维数组,一共30行,每行30个数据,每一行的数据分别是对应的x轴上划分的刻度值xy = np.vstack([axisx.ravel(), axisy.ravel()]).T
#print(xy.shape)
#(900, 2)
##其中ravel()是降维函数,vstack能够将多个结构一致的一维数组按行堆叠起来
#xy就是已经形成的网格,它是遍布在整个画布上的密集的点plt.scatter(xy[:, 0], xy[:, 1], s=1, cmap="rainbow")
plt.show()

在这里插入图片描述

#建模,计算决策边界并找出网格上每个点到决策边界的距离
clf = SVC(kernel="linear").fit(x, y)
z = clf.decision_function(xy).reshape(axisx.shape)
#重要接口decision_function,返回每个输入的样本所对应的决策边界的距离
#然后再将这个距离转换为axisx的结构,这是由于画图的函数contour要求z的结构必须要axisx,axisy的结构一样#画决策边界和平行于决策边界的超平面
ax.contour(axisx, axisy, z, colors="k", levels=[-1, 0, 1], alpha=0.5, linestyles=["--", "-", "--"])
#把所有的点都放进来,把计算得到的距离都放进来,把等高线的高度放进来ax.set_xlim(xlim)
ax.set_ylim(ylim)
plt.show()

在这里插入图片描述

#print(x[10]) #[1.71444449 5.02521524]
#print(x[10].reshape(1, 2)) #[[1.71444449 5.02521524]]
plt.scatter(x[:, 0], x[:, 1], c=y, s=50, cmap="rainbow")
plt.scatter(x[10, 0], x[10, 1], c="black", s=50, cmap="rainbow")
clf.decision_function(x[10].reshape(1, 2))
plt.scatter(x[:, 0], x[:, 1], c=y, s=50, cmap="rainbow")
ax = plt.gca()
ax.contour(axisx, axisy, z, colors="k", levels=[-3.33917354], alpha=0.5, linestyles=["--"])
plt.show()

在这里插入图片描述

#将绘图过程包装秤函数
def plot_scv_decision_function(model, ax=None):if ax is None:ax = plt.gca()xlim = ax.get_xlim()yilm = 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()]).TP = model.decision_function(xy).reshape(X.shape)ax.contour(X, Y, P, colors="k", levels=[-1, 0, 1], alpha=0.5, linestyles=["--", "-", "--"])ax.set_xlim(xlim)ax.set_ylim(ylim)clf = SVC(kernel="linear").fit(x, y)
plt.scatter(x[:, 0], x[:, 1], c=y, s=50, cmap="rainbow")
plot_scv_decision_function(clf)
plt.show()

在这里插入图片描述
重要的接口

#探索建好的模型
print(clf.predict(x))
#根据决策边界,对x中的样本进行分类,返回的结构为n_samples[1 1 0 0 1 1 1 1 1 0 0 0 0 1 0 0 0 1 0 0 1 1 1 1 1 0 0 0 1 0 1 0 0 0 0 1 10 1 0 1 0 1 1 0 1 1 0 1 0]print(clf.score(x, y))
#返回给定测试数据和标签的平均准确度
1.0print(clf.support_vectors_)
#返回支持向量[[0.44359863 3.11530945][2.33812285 3.43116792][2.06156753 1.96918596]]print(clf.n_support_)
#返回每个类中的支持向量个数
[2 1]

5 为非线性数据增加维度并绘制3D图像

对于环形数据来说如何寻找超平面?

import matplotlib.pyplot as plt
import numpy as np
from sklearn.datasets import make_circles
from mpl_toolkits import mplot3d
x, y = make_circles(100, factor=0.1, noise=0.1)
#print(x.shape)  #(100, 2)
#print(y.shape)  #(100,)#既然要兑换到三维,就需要建一个新的维度r
r = np.exp(-(x ** 2).sum(1))
rlim = np.linspace(min(r), max(r), 100)##定义一个绘制三维图像的函数
#elev表示上下旋转的角度
#azim表示平行旋转的角度
def plot_3D(elev=30, azim=30, x=x, y=y):ax = plt.subplot(projection="3d")ax.scatter3D(x[:, 0], x[:, 1], r, c=y, s=50, cmap="rainbow")ax.view_init(elev=elev, azim=azim)ax.set_xlabel("x")ax.set_ylabel("y")ax.set_zlabel("r")plt.show()plot_3D()

将二维图片转换到三维领域,由于x特征值不同,在更高维度中可以找到一个平面直接将两类数据进行切分!
在这里插入图片描述


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部