SVM简洁

原文链接:https://blog.csdn.net/qq_31347869/article/details/88071930

机器学习的一般框架

训练集 => 提取特征向量 => 结合一定的算法(分类器:比如决策树、KNN)=>得到结果

SVM 背景

SVM 最早是由 Vladimir N. Vapnik 和 Alexey Ya. Chervonenkis 在1963年提出,目前的版本(soft margin)是由 Corinna Cortes 和 Vapnik 在1993年提出,并在1995年发表。

深度学习(2012)出现之前,SVM 被认为机器学习中近十几年来最成功,表现最好的算法

SVM 介绍

SVM 基本概念

将实例的特征向量(以二维为例)映射为空间中的一些点,就是如下图的实心点和空心点,它们属于不同的两类。

那么 SVM 的目的就是想要画出一条线,以“最好地”区分这两类点,以至如果以后有了新的点,这条线也能做出很好的分类。
在这里插入图片描述
能够画出多少条线对样本点进行区分?
:线是有无数条可以画的,区别就在于效果好不好

比如绿线就不好,蓝线还凑合,红线看起来就比较好。
我们所希望找到的这条效果最好的线叫作划分超平面

为什么要叫作“超平面”呢?
:因为样本的特征很可能是高维的,此时样本空间的划分就需要“超平面”。

画线的标准是什么?/ 什么才叫这条线的效果好?
:SVM 将会寻找可以区分两个类别并且能使边际(margin)最大的超平面(hyper plane),即划分超平面

边际(margin)是什么?
:边际就是某一条线距离它两侧最近的点的距离之和。
比如下图中两条虚线构成的带状区域就是 margin,虚线是由距离中央实线最近的两个点所确定出来的。但此时 margin 比较小,如果用第二种方式画,margin 明显变大也更接近我们的目标。
在这里插入图片描述
为什么要让 margin 尽量大?
:因为大 margin 犯错的几率比较小

如何选取使边际最大的超平面 (Max Margin Hyperplane,简称 MMH)?
:超平面到一侧最近点的距离等于到另一侧最近点的距离,两侧的两个超平面平行

SVM 算法特性

  • 训练好的模型的算法复杂度是由支持向量的个数决定的,而不是由数据的维度决定的。所以 SVM 不太容易产生 overfitting。
  • SVM 训练出来的模型完全依赖于支持向量,即使训练集里面所有非支持向量的点都被去除,重复训练过程,结果仍然会得到完全一样的模型。
  • 一个 SVM 如果训练得出的支持向量个数比较少,那么SVM 训练出的模型比较容易被泛化。

SVM 定义与公式建立

超平面可以定义为: w T X + b = 0 w T X + b = 0 w T X + b = 0 wTX+b=0wTX+b=0 w^TX+b=0 wTX+b=0wTX+b=0wTX+b=0x1+2x25.5=0
最后可以用点(2,0)验证一下这个划分超平面的分类效果。
在这里插入图片描述

SVM 应用实例

由于 SVM 算法本身的实现非常复杂,所以这里不研究自己如何实现 SVM,而仍采用 sklearn 库来帮助我们学习 SVM 的应用问题。

sklearn 简单例子

# sklearn 库中导入 svm 模块
from sklearn import svm

# 定义三个点和标签
X = [[2, 0], [1, 1], [2,3]]
y = [0, 0, 1]
# 定义分类器,clf 意为 classifier,是分类器的传统命名
clf = svm.SVC(kernel = ‘linear’) # .SVC()就是 SVM 的方程,参数 kernel 为线性核函数
# 训练分类器
clf.fit(X, y) # 调用分类器的 fit 函数建立模型(即计算出划分超平面,且所有相关属性都保存在了分类器 cls 里)

# 打印分类器 clf 的一系列参数
print (clf)

# 支持向量
print (clf.support_vectors_)

# 属于支持向量的点的 index
print (clf.support_)

# 在每一个类中有多少个点属于支持向量
print (clf.n_support_)

# 预测一个新的点
print (clf.predict([[2,0]]))

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

输出结果:

SVC(C=1.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)
[[1. 1.]
 [2. 3.]]
[1 2]
[1 1]
[0]

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 可以看到 SVM 找到的支持向量是(1,1)和(2,3)两个点,和我们上面的例子是符合的
  • 输出的属于支持向量的点的 index 就是 1 和 2
  • 由于找到了两个支持向量分别属于正类和负类,所以输出的每个类中属于支持向量的点的个数就是 1 和 1

sklearn 划分超平面

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()

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值