【机器学习】sklearn实现SVM分类算法

概念讲解

1.什么是支持向量机?#小鲸云课堂的说法

支持向量机(support vector machines,SVM)是一种二分类模型,它的基本模型是定义在特征空间上的间隔最大的线性分类器。除此之外,SVM算法还包括核函数,核函数可以使它成为非线性分类器。在了解SVM算法之前,我们要先认识一下线性分类器。

线性分类器:假设在一个二维线性可分的数据集中,我们要找到一个超平面把两组数据分开,已知的方法有我们已经学过的线性回归和逻辑回归,这条直线可以有很多种,如下图的H1、H2、H3哪一条直线的效果最好呢,也就是说哪条直线可以使两类的空间大小相隔最大呢?

【机器学习】sklearn实现SVM分类算法

我们凭直观感受应该觉得答案是H3。首先H1不能把类别分开,这个分类器肯定是不行的;H2可以,但分割线与最近的数据点只有很小的间隔,如果测试数据有一些噪声的话可能就会被H2错误分类(即对噪声敏感、泛化能力弱)。H3以较大间隔将它们分开,这样就能容忍测试数据的一些噪声而正确分类,是一个泛化能力不错的分类器。因此我们把这个划分数据的决策边界就叫做超平面。离这个超平面最近的点就是 “支持向量”,点到超平面的距离叫做间隔, 支持向量机的意思就是使超平面和支持向量之间的间隔尽可能的大,这样才可以使两类样本准确地分开。

2.支持向量机的种类:

a) 线性可分SVM:当数据线性可分的时候,通过硬间隔最大化可以学习得到一个线性分类器,即硬间隔SVM,如上图的H3
b) 线性SVM:当训练数据不能线性可分但是可以近似线性可分时,通过软间隔(soft margin)最大化也可以学习到一个线性分类器,即软间隔SVM
c) 非线性SVM:
当训练数据线性不可分时,通过使用核技巧(kernel trick)和软间隔最大化,可以学习到一个非线性SVM。

3.超平面与间隔:

【机器学习】sklearn实现SVM分类算法

我们从图上可以看到,这条中间的实线代表的超平面离直线两边的数据的间隔最大,对训练集的数据的噪声有最大的包容力。

【机器学习】sklearn实现SVM分类算法

对一个分类问题,我们假设,

【机器学习】sklearn实现SVM分类算法

我们知道,所谓的支持向量,就是使得上式等号成立,即最靠近两条虚边界线的向量。为什么像上面的式子那么假设呢?其实是为了方便计算。

【机器学习】sklearn实现SVM分类算法

【机器学习】sklearn实现SVM分类算法

更详细的理论推导可以看看这里: 支持向量机(SVM)——原理篇

实际操作

由于 SVM 算法本身的实现非常复杂,所以不研究如何实现 SVM,而是采用 sklearn 库来学习 SVM 的应用问题。

单分类

①基本代码


from sklearn import svm
import matplotlib.pyplot as plt

定义三个点和标签
X = [[2, 0], [1, 1], [2,3]]
y = [0, 0, 1]

#可视化数据
plt.scatter(X[:, 0], X[:, 1], marker='o')  # 假设暂不知道y类别,不设置c=y,使用kmeans聚类
plt.plot([2,1,2],[0,1,3],'ro')
plt.show()
定义分类器,clf 意为 classifier,是分类器的传统命名
clf = svm.SVC(kernel = 'linear')  # .SVC()就是 SVM 的方程,参数 kernel 为线性核函数
训练分类器
clf.fit(X, y)  # 调用分类器的 fit 函数建立模型(即计算出划分超平面,且所有相关属性都保存在了分类器 cls 里)
打印分类器 clf 的一系列参数
print("打印分类器 clf 的一系列参数:\n",clf)
支持向量
print("支持向量",clf.support_vectors_)
属于支持向量的点的 index
print("属于支持向量的点的:",clf.support_)
在每一个类中有多少个点属于支持向量
print("在每一个类中有多少个点属于支持向量:",clf.n_support_)
预测一个新的点
print(clf.predict([[2,0]]))

【机器学习】sklearn实现SVM分类算法

打印分类器 clf 的一系列参数: SVC(kernel=’linear’)
支持向量: [[1. 1.] [2. 3.]]
属于支持向量的点的: [1 2] #这是X数组的检索
在每一个类中有多少个点属于支持向量: [1 1]
预测一个新的点: [0]

②进阶代码

​​​

print(__doc__)
导入相关的包
import numpy as np
import pylab as pl  # 绘图功能
from sklearn import svm

创建 40 个点
np.random.seed(0) # 让每次运行程序生成的随机样本点不变
生成训练实例并保证是线性可分的
np._r表示将矩阵在行方向上进行相连
random.randn(a,b)表示生成 a 行 b 列的矩阵,且随机数服从标准正态分布
array(20,2) - [2,2] 相当于给每一行的两个数都减去 2
X = np.r_[np.random.randn(20, 2) - [2, 2], np.random.randn(20, 2) + [2, 2]]
两个类别 每类有 20 个点,Y 为 40 行 1 列的列向量
Y = [0] * 20 + [1] * 20

建立 svm 模型
clf = svm.SVC(kernel='linear')
clf.fit(X, Y)

获得划分超平面
划分超平面原方程:w0x0 + w1x1 + b = 0
将其转化为点斜式方程,并把 x0 看作 x,x1 看作 y,b 看作 w2
点斜式:y = -(w0/w1)x - (w2/w1)
w = clf.coef_[0]  # w 是一个二维数据,coef 就是 w = [w0,w1]
a = -w[0] / w[1]  # 斜率
xx = np.linspace(-5, 5)  # 从 -5 到 5 产生一些连续的值(随机的)
.intercept[0] 获得 bias,即 b 的值,b / w[1] 是截距
yy = a * xx - (clf.intercept_[0]) / w[1]  # 带入 x 的值,获得直线方程

画出和划分超平面平行且经过支持向量的两条线(斜率相同,截距不同)
b = clf.support_vectors_[0] # 取出第一个支持向量点
yy_down = a * xx + (b[1] - a * b[0])
b = clf.support_vectors_[-1] # 取出最后一个支持向量点
yy_up = a * xx + (b[1] - a * b[0])

查看相关的参数值
print("w: ", w)
print("a: ", a)
print("support_vectors_: ", clf.support_vectors_)
print("clf.coef_: ", clf.coef_)

在 scikit-learin 中,coef_ 保存了线性模型中划分超平面的参数向量。形式为(n_classes, n_features)。若 n_classes > 1,则为多分类问题,(1,n_features) 为二分类问题。

绘制划分超平面,边际平面和样本点
pl.plot(xx, yy, 'k-')
pl.plot(xx, yy_down, 'k--')
pl.plot(xx, yy_up, 'k--')
圈出支持向量
pl.scatter(clf.support_vectors_[:, 0], clf.support_vectors_[:, 1],
           s=80, facecolors='none')
pl.scatter(X[:, 0], X[:, 1], c=Y, cmap=pl.cm.Paired)

pl.axis('tight')
pl.show()

【机器学习】sklearn实现SVM分类算法

【机器学习】sklearn实现SVM分类算法

这里仅仅都是实现的二分类问题,而大多数时候我们都需要进行多分类问题。

多分类

参考资料

支持向量机(SVM)——原理篇【理论强化】顺序二#看完顺序一看顺序二会顺畅许多
什么是支持向量?【精品入门】顺序一
机器学习算法(一)SVM
支持向量机(SVM)的分析及python实现#参数说明的很到位(调参)

一个矩阵正定(Possitive definite) 到底能说明什么,能解决什么问题? – 知乎

机器学习算法(一)SVM_yaoyz105-CSDN博客_svm

Svm实现多分类_早点变成刘强东就好-CSDN博客_svm多分类算法

Original: https://blog.csdn.net/weixin_43332715/article/details/120864251
Author: 思考实践
Title: 【机器学习】sklearn实现SVM分类算法

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/661423/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球