机器学习--支持向量机

支持向量机(SVM)和支持向量机回归(SVR) - 知乎

机器学习工程师面试宝典-第一章-绪论 - 知乎

支持向量机基本概念

支持向量机”( SVM )是一种有监督的机器学习算法,以 最大间隔 分类为原则,寻找最优决策边界的算法。
SVM 计算量略大适合应用于 复杂但中小规模数据集 的分类问题。
什么是超平面?:区分两个类别的界线(决策边界)
什么是支持向量?:每个类别中距离超平面最近的点
什么是最合适的超平面?:具有最大分类间隔的决策边界

 

一个经验的法则来识别正确的超平面:“选择更好的可以隔离两个类别的超平面”

支持向量机原理

Ø 两类数据(圆圈和五角星)
Ø 每个数据样本包含两个特征( 𝑥 1 𝑥 2x_1, x_2
Ø 对于无数条线性可分的界线,哪个最好?
取最大化点到界线距离最小值的那条界线

 

 

 

 基本概念:

实线叫做 判定边界
虚线叫做 最大 间隔 分类
最大间隔分类上 的点叫做 支持向量

 

 场景1

 

 

如何选择正确的超平面, A or B
这里注意,虽然超平面 B 可以最大化支持向量与判别界线的距离,但是相比于 A B 存在一个分类错误,所以正确的超平面是 A
这种必须要把所有数据 都严格的被 正确划分的间隔
叫做 硬间隔

场景2

如何 出如下两个类别的超平面?
图中存在一个异常值
由于异常值的存在,导致无法画出一个线性间隔区分如下两类。
间隔的缺陷:
只对线性可分的数据起作用
对异常点 敏感
SVM 支持 软间隔
可以允许部分数据点分类错误
ξ 叫做松弛因子, C 是惩罚因子,也叫正则化强度
使用 惩罚 因子 来调节软间隔程度。惩罚 因子 大,说明对分类 越严格 ,正确率越高,对异常值越敏感。相反,分类 越不 严格,对异常值越稳健

                 

 场景3

如何画出如下两个类别的超平面?

        •显然,只使用之前的线性超平面是无法正确分类的

SVM通过引入额外的特征来解决以上问题。

        •添加一个新特征𝑥3=𝑥12+𝑥22x_3=x_1^2+x_2^2

        •绘制𝑥1x_1𝑥3x_3上的数据点。

引入新特征𝑥3x_3需要注意的是:

        •𝑥3x_3所有值都是正的,因为𝑥3x_3𝑥1x_1𝑥2x_2平方和

        •在原图中,红色圆圈出现在靠近𝑥1x_1𝑥2x_2轴原点的位置
导致𝑥3x_3值比较低。星形相对远离原点,导致𝑥3x_3值较高。

 

对于非线性分类问题,我们是否需要手动添加一个特征以获得超平面?

SVM有一种称为核技巧的技术

        •通过引入核函数把低维度的输入空间转换为更高维度的空间,来解决非线性分离问题

核函数

线性核函数

        •方案首选,奥卡姆剃刀原理

        •简单,求解快

        •可解释性强:可以轻易知道哪些feature是重要的

多项式核

        •基本原理:依靠升维使得原本线性不可分的数据线性可

        •可解决非线性问题

        •对于大数量级的幂数,不太适用

        •需要选择的参数较多

高斯

        优点:

        •可以映射到无限维

        •决策边界更为多样

        •只有一个参数,相比多项式核容易选择

缺点:
可解释性
计算 速度比较
容易过拟合

Sigmoid

        主要用在神经网络的设计中

在实战中通常只在线性核与高斯核之间做选择

        •数据量特别大,或者数据特征维数很高,选择线性

        •数据量中等,特征数少,选择高斯核

三种支持向量机

线性可分支持向量机
硬间隔
线性支持向量机
软间隔
非线性支持向量机
核函数

python下使用SVM

sklearn.svm.SVC(只考虑分类问题)

参数详解:

        •C: float参数 默认值为1.0

                •错误项的惩罚系数。C越大,即对分错样本的惩罚程度越大,因此在训练样本中准确率越高,但是泛化能力降低,也就是对测试数据的分类准确率降低。相反,减小C的话,容许训练样本中有一些误分类错误样本,泛化能力强。对于训练样本带有噪声的情况,一般采用后者,把训练样本集中错误分类的样本作为噪声

        •kernel: str参数默认为‘rbf:高斯核函数,其他可选核函数如下:

                •linear:线性核函数

                •poly:多项式核函数

                •sigmodsigmod核函数

                •precomputed:核矩阵

                –precomputed表示自己提前计算好核函数矩阵,这时候算法内部就不再用核函数去计算核矩阵,而是直接用你给的核矩阵。

degreeint参数,默认3

        •这个参数只对多项式核函数有用,是指多项式核函数的阶数n。如果给的核函数参数是其他核函数,则会自动忽略该参数

gamma: float参数,或者{scalerauto},默认为scaler

        •核函数系数,只对‘rbf’,‘poly’,‘sigmod有效。控制这些核函数的拟合能力,gamma越大拟合能力越强,越容易过拟合。反之,拟合能力越弱,越容易欠拟合。

        •如果gammaauto,代表其值为样本特征数的倒数,即1/n_features

        •如果为scalergamma=1/(n_features*X.var())

coef0float参数,默认为0.0

        •核函数的独立项,只有对‘poly’和‘sigmod核函数有用,是指其中的参数c

probabilitybool参数,默认False

        •是否启用概率估计。 这必须在调用fit()之前启用,并且会使fit()方法速度变慢。

shrinkingbool参数,默认True

        •是否采用启发式收缩方式

tolfloat参数,默认1e^-3

        •svm停止训练的误差精度。

cache_sizefloat参数,默认200

        •指定训练所需要的内存,以MB为单位,默认为200MB

class_weight:字典类型或者‘balance’字符串。默认为None

        •给每个类别分别设置不同的惩罚参数C,如果没有给,则会给所有类别都给C=1,即前面参数指出的参数C.

        •如果给定参数‘balance’,则使用y的值自动调整与输入数据中的类频率成反比的权重

verbosebool参数,默认False

        •是否启用详细输出。 此设置利用libsvm中的每个进程运行时设置,如果启用,可能无法在多线程上下文中正常工作。一般情况都设为False

max_iterint参数,默认-1

        •最大迭代次数,如果为-1,表示不限制

random_stateint参数,默认None

        •伪随机数发生器的种子,在混洗数据时用于概率估计

SVC的属性:

        •svc.n_support_:各类各有多少个支持向量

        •svc.support_:各类的支持向量在训练样本中的索引

        •svc.support_vectors_:各类所有的支持向量

尾花实例

为了可视化方便,只提取莺尾花数据集的头两个特征(花萼长度,花萼宽度)
使用 SVC 对莺尾花数据集进行训练,分别观察 linear rbf 核函数对结果的影响;分别观察不同 gamma 值对结果的影响;分别观察不同惩罚影子对结果的影响。
import numpy as np
import matplotlib.pyplot as plt
from sklearn import svm,datasets
iris = datasets.load_iris()
X=iris.data[:,:2]
y=iris.target
svc = svm.SVC(kernel='linear',C=1).fit(X,y)#
x_min,x_max = X[:,0].min()-1,X[:,0].max()+1
y_min,y_max = X[:,1].min()-1,X[:,1].max()+1
xx,yy = np.meshgrid(np.linspace(x_min,x_max,100),np.linspace(y_min,y_max,100))
Z = svc.predict(np.c_[xx.ravel(), yy.ravel()])      #对应的类别值
Z = Z.reshape(xx.shape)
plt.contourf(xx, yy, Z, cmap=plt.cm.Paired, alpha=0.8)
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Paired, edgecolors='k')
plt.xlabel('Sepal length')
plt.ylabel('Sepal width')
plt.xlim(xx.min(), xx.max())
plt.title('SVC with linear kernel')
plt.show()

 

Z = svc.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
plt.contour(xx, yy, Z, cmap=plt.cm.Paired, alpha=0.8)
# plt.contour(xx, yy, Z, cmap=plt.cm.hot, alpha=0.8)
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Paired, edgecolors='k')
plt.xlabel('Sepal length')
plt.ylabel('Sepal width')
plt.xlim(xx.min(), xx.max())
plt.title('SVC with linear kernel')
plt.show()

svc = svm.SVC(kernel='rbf',C=1).fit(X,y)
Z = svc.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
plt.contourf(xx, yy, Z, cmap=plt.cm.Paired, alpha=0.8)
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Paired, edgecolors='k')
plt.xlabel('Sepal length')
plt.ylabel('Sepal width')
plt.xlim(xx.min(), xx.max())
plt.title('SVC with rbf kernel')
plt.show()

 

plt.figure(figsize=(25,5))
plt.subplot(1,3,1)
svc = svm.SVC(kernel ='rbf',C = 1, gamma='auto').fit(X,y)
Z = svc.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
plt.contourf(xx, yy, Z, cmap=plt.cm.Paired, alpha=0.8)
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Paired, edgecolors='k')
plt.xlabel('Sepal length')
plt.ylabel('Sepal width')
plt.xlim(xx.min(), xx.max())
plt.title('gamma = auto')

plt.subplot(1,3,2)
svc = svm.SVC(kernel ='rbf',C = 1, gamma=10).fit(X,y)
Z = svc.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
plt.contourf(xx, yy, Z, cmap=plt.cm.Paired, alpha=0.8)
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Paired, edgecolors='k')
plt.xlabel('Sepal length')
plt.ylabel('Sepal width')
plt.xlim(xx.min(), xx.max())
plt.title('gamma = 10')

plt.subplot(1,3,3)
svc = svm.SVC(kernel ='rbf',C = 1, gamma=100).fit(X,y)
Z = svc.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
plt.contourf(xx, yy, Z, cmap=plt.cm.Paired, alpha=0.8)
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Paired, edgecolors='k')
plt.xlabel('Sepal length')
plt.ylabel('Sepal width')
plt.xlim(xx.min(), xx.max())
plt.title('gamma = 100')
plt.show()

 

plt.figure(figsize=(25,5))
plt.subplot(1,3,1)
svc = svm.SVC(kernel ='rbf',C = 1).fit(X,y)
Z = svc.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
plt.contourf(xx, yy, Z, cmap=plt.cm.Paired, alpha=0.8)
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Paired, edgecolors='k')
plt.xlabel('Sepal length')
plt.ylabel('Sepal width')
plt.xlim(xx.min(), xx.max())
plt.title('C = 1')

plt.subplot(1,3,2)
svc = svm.SVC(kernel ='rbf',C = 10).fit(X,y)
Z = svc.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
plt.contourf(xx, yy, Z, cmap=plt.cm.Paired, alpha=0.8)
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Paired, edgecolors='k')
plt.xlabel('Sepal length')
plt.ylabel('Sepal width')
plt.xlim(xx.min(), xx.max())
plt.title('C = 100')

plt.subplot(1,3,3)
svc = svm.SVC(kernel ='rbf',C = 1000).fit(X,y)
Z = svc.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
plt.contourf(xx, yy, Z, cmap=plt.cm.Paired, alpha=0.8)
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Paired, edgecolors='k')
plt.xlabel('Sepal length')
plt.ylabel('Sepal width')
plt.xlim(xx.min(), xx.max())
plt.title('C = 1000')
plt.show()

 支持向量机解决回归问题

SVR算法

分类思想:最大化分类间隔( 使得到超平面 最近的点的距离最大
回归思想:最小化点与模型之间的距离( 使得到 超平面与最 远的点的距离最小

 SVR的优化问题:

 

 SVR只计算数据点落入以f(x)为中心,±ϵ范围区域外的数据点
虚线所围成的区域外),其中𝐸𝜖𝑧(z)可以理解为点到𝑓𝑥f(x)𝜖ϵ区域距离

 类似软间隔分类时引入的松弛因子。这里引入两个松弛因子𝜉ξ𝜉ξ ̂,目的是尽可能让红色区域拟合数据又不容易受异常值影响。

 利用一条固定宽度的条带,覆盖尽可能多的样本点,从而使得总误差尽可能的小。

 引入两个松弛因子𝜉ξ𝜉ξ ̂,表示对𝜖ϵ区域两边进行松弛,目的是尽可能让红色区域拟合数据又不容易受异常值影响。

利用一条固定宽度的条带,覆盖尽可能多的样本点,从而使得总误差尽可能的小

SVR优化问题可以重写为:

 

 SVM的优缺点

优点

模型学习能力很强,对于各种数据集都有不错的表现
SVM 的解为全局最优,泛化能力强
SVM 在适合特征数较多的高维数据集。
使用训练集中的支持向量 ,节约 内存

缺点:

拥有大量的数据集时,SVM表现并不好,因为计算量很大,所需要的训练时间长

数据集的噪音过多时,表现不好,需要非常仔细的数据预处理和调参

核函数选择难度较大

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值