在很久以前的情人节,大侠要去救他的爱人,但魔鬼和他玩了一个游戏。
魔鬼在桌子上似乎有规律放了两种颜色的球,说:
“你用一根棍分开它们?要求:尽量在放更多球之后,仍然适用。”
于是大侠这样放,干的不错?
然后魔鬼,又在桌上放了更多的球,似乎有一个球站错了阵营。
怎么办??
把分解的小棍儿变粗。
SVM就是试图把棍放在最佳位置,好让在棍的两边有尽可能大的间隙。
现在即使魔鬼放了更多的球,棍仍然是一个好的分界线。
然后,在SVM 工具箱中有另一个更加重要的技巧( trick)。 魔鬼看到大侠已经学会了一个trick,于是魔鬼给了大侠一个新的挑战。
现在,大侠没有棍可以很好帮他分开两种球了,现在怎么办呢?
当然像所有武侠片中一样大侠桌子一拍,球飞到空中。然后,凭借大侠的轻功,大侠抓起一张纸,插到了两种球的中间。
现在,从魔鬼的角度看这些球,这些球看起来像是被一条曲线分开了。
再之后,无聊的大人们,把上面的物体起了别名:
案例来源:http://bytesizebio.net/2014/02/05/support-vector-machines-explained-well/
支持向量机直观感受:https://www.youtube.com/watch?v=3liCbRZPrZA
SVM:SVM全称是supported vector machine(支持向量机),即寻找到一个超平面使样本分成两类,并且间隔最大。
SVM能够执行线性或非线性分类、回归,甚至是异常值检测任务。它是机器学习领域最受欢迎的模型之一。SVM特别适用于中小型复杂数据集的分类。
上左图显示了三种可能的线性分类器的决策边界:
虚线所代表的模型表现非常糟糕,甚至都无法正确实现分类。其余两个模型在这个训练集上表现堪称完美,但是它们的决策边界与实例过于接近,导致在面对新实例时,表现可能不会太好。
右图中的实线代表SVM分类器的决策边界,不仅分离了两个类别,且尽可能远离最近的训练实例。
在上面我们使用超平面进行分割数据的过程中,如果我们严格地让所有实例都不在最大间隔之间,并且位于正确的一边,这就是硬间隔分类。
硬间隔分类有两个问题,首先,它只在数据是线性可分离的时候才有效;其次,它对异常值非常敏感。
当有一个额外异常值的鸢尾花数据:左图的数据根本找不出硬间隔,而右图最终显示的决策边界与我们之前所看到的无异常值时的决策边界也大不相同,可能无法很好地泛化。
要避免这些问题,最好使用更灵活的模型。目标是尽可能在保持最大间隔宽阔和限制间隔违例(即位于最大间隔之上,甚至在错误的一边的实例)之间找到良好的平衡,这就是软间隔分类。
要避免这些问题,最好使用更灵活的模型。目标是尽可能在保持间隔宽阔和限制间隔违例之间找到良好的平衡,这就是软间隔分类。
在Scikit-Learn的SVM类中,可以通过超参数C来控制这个平衡:C值越小,则间隔越宽,但是间隔违例也会越多。上图显示了在一个非线性可分离数据集上,两个软间隔SVM分类器各自的决策边界和间隔。
左边使用了高C值,分类器的错误样本(间隔违例)较少,但是间隔也较小。
右边使用了低C值,间隔大了很多,但是位于间隔上的实例也更多。看起来第二个分类器的泛化效果更好,因为大多数间隔违例实际上都位于决策边界正确的一边,所以即便是在该训练集上,它做出的错误预测也会更少。
。
>>> from sklearn import svm
>>> X = [[0, 0], [1, 1]]
>>> y = [0, 1]
>>> clf = svm.SVC()
>>> clf.fit(X, y)
SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
decision_function_shape='ovr', degree=3, gamma='scale', kernel='rbf',
max_iter=-1, probability=False, random_state=None, shrinking=True,
tol=0.001, verbose=False)
在拟合后, 这个模型可以用来预测新的值:
>>> clf.predict([[2., 2.]])
array([1])
假设给定一个特征空间上的训练集为:
T={(x_1, y_1),(x_2,y_2)…,(x_N,y_N)}T={(x1,y1),(x2,y2)…,(x**N,y**N)}
x_i \in R^n, y_i \in {+1, -1}, i=1,2,…,N.x**i∈R**n,y**i∈{+1,−1},i=1,2,…,N.
其中,(xi,yi)称为样本点。
至于为什么正负用(-1,1)表示呢?
其实这里没有太多原理,就是一个标记,你也可以用(2,-3)来标记。只是为了方便,y_i/y_j=y_iy_jyi*/*yj*=y**i∗y**j的过程中刚好可以相等,便于之后的计算。)
给定了上面提出的线性可分训练数据集,通过间隔最大化得到分离超平面为 :y(x)=w^T\Phi(x)+by(x)=w**TΦ(x)+b
相应的分类决策函数为: f(x)=sign(w^T\Phi(x)+b)f(x)=sig**n(w**TΦ(x)+b)
以上决策函数就称为线性可分支持向量机。
这是某个确定的特征空间转换函数,它的作用是将x映射到更高的维度,它有一个以后我们经常会见到的专有称号**”核函数“**。
比如我们看到的特征有2个: x1,x2,组成最先见到的线性函数可以是: 但也许这两个特征并不能很好地描述数据,于是我们进行维度的转化,变成了:w_1x_1+w_2x_2+w_3x_1x_2+w_4x_12+w_5x_22w1x1+w2x2+w3x1x2+w4x12+w5x22. 于是我们多了三个特征。而这个就是笼统地描述x的映射的。 最简单直接的就是:
以上就是线性可分支持向量机的模型表达式。我们要去求出这样一个模型,或者说这样一个超平面y(x),它能够最优地分离两个集合。
其实也就是我们要去求一组参数(w,b),使其构建的超平面函数能够最优地分离两个集合。
如下就是一个最优超平面:
又比如说这样:
阴影部分是一个“过渡带”,“过渡带”的边界是集合中离超平面最近的样本点落在的地方。
我们知道了支持向量机是个什么东西了。现在我们要去寻找这个支持向量机,也就是寻找一个最优的超平面。
于是我们要建立一个目标函数。那么如何建立呢?
再来看一下我们的超平面表达式: y(x)=w^T\Phi(x)+by(x)=w**TΦ(x)+b
为了方便我们让:\Phi(x)=xΦ(x)=x
则在样本空间中,划分超平面可通过如下线性方程来描述:w^Tx+b=0wTx+b=0
样本空间中任意点x到超平面(w,b)的距离可写成
令
如图所示,距离超平面最近的几个训练样本点使上式等号成立,他们被称为“支持向量",
它被称为“”间隔“”。
欲找到具有最大间隔的划分超平面,也就是要找到能满足下式中约束的参数w和b,使得 r 最大。
即:
显然,为了最大化间隔,仅需要最大化,这等价于最小化。于是上式可以重写为:
这就是支持向量机的基本型。
拓展:什么是 ||w||?
到这一步,终于把目标函数给建立起来了。
那么下一步自然是去求目标函数的最优值.
因为目标函数带有一个约束条件,所以我们可以用拉格朗日乘子法求解。
啥是拉格朗日乘子法呢?
拉格朗日乘子法 (Lagrange multipliers)是一种寻找多元函数在一组约束下的极值的方法.
通过引入拉格朗日乘子,可将有 d 个变量与 k 个约束条件的最优化问题转化为具有 d + k 个变量的无约束优化问题求解。
经过朗格朗日乘子法,我们可以把目标函数转换为:
然后我们令:
容易验证,当某个约束条件不满足时,例如,那么显然有 θ(w) = ∞ (只要令 αi = ∞ 即可)。而当所有约束条件都满足时,则有 ,亦即最初要 最小化的量。
因此,在要求约束条件得到满足的情况下最小化 ,实际上等价于直接最小化 θ(w)(当然, 这里也有约束条件, 就是 α i ≥ 0, i = 1, …, n),因为如果约束条件没有得 到满足, θ(w) 会等于无穷大,自然不会是我们所要求的最小值。
具体写出来,目标函数变成了:
这里用 p* 表示这个问题的最优值,且和最初的问题是等价的。如果直接求解,那么一上来便得面对 w 和 b 两个参数,而 α i 又是不等式约束,这个求解过程不好做。
此时,我们可以借助对偶问题进行求解。
因为我们在上面求解的过程中,直接求解 w 和 b 两个参数不方便,所以想办法转换为对偶问题。
我们要将其转换为对偶问题,变成极大极小值问题:
参考资料: https://wenku.baidu.com/view/7bf945361b37f111f18583d049649b6649d70975.html
如何获取对偶函数?
我们用数学表达式来说明上面的过程:
注意有两个约束条件。
给定3个数据点:正例点x1=(3,3),x2=(4,3),负例点x3=(1,1),求线性可分支持向量机。 三个点画出来:
因此得到分离超平面为: 0.5x_1+0.5x_2-2=00.5x1+0.5x2−2=0
得到分离决策函数为:f(x)=sign(0.5x_1+0.5x_2-2)f(x)=sig**n(0.5x1+0.5x2−2)
ps:参考的另一种计算方式: https://blog.csdn.net/zhizhjiaodelaoshu/article/details/97112073
SVM中目标函数
SVM中目标函数的求解过程
在SVM中,我们主要讨论三种损失函数:
拓展学习:PPT讲义
【SVM + 核函数】 具有极大威力。
核函数并不是SVM特有的,核函数可以和其他算法也进行结合,只是核函数与SVM结合的优势非常大。
核函数,是将原始输入空间映射到新的特征空间,从而,使得原本线性不可分的样本可能在核空间可分。
下图所示的两类数据,分别分布为两个圆圈的形状,这样的数据本身就是线性不可分的,此时该如何把这两类数据分开呢?
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-09NMo6NS-1667189866716)(images/1111.gif)]
若x,z是X空间中的点,函数k(x,z)满足下述条件,那么都成立,则称k为核函数,而ϕ为映射函数:
经过上面公式,具体变换过过程为:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0eAIB5kp-1667189866718)(assets/image-20210811152410276.png)]
(前后轴为x轴,左右轴为y轴,上下轴为z轴)
1.多项核中,d=1时,退化为线性核;
2.高斯核亦称为RBF核。
SVM回归是让尽可能多的实例位于预测线上,同时限制间隔违例(也就是不在预测线距上的实例)。
线距的宽度由超参数ε控制。
SVM方法既可以用于分类(二/多分类),也可用于回归和异常值检测。
SVM具有良好的鲁棒性,对未知数据拥有很强的泛化能力,特别是在数据量较少的情况下,相较其他传统机器学习算法具有更优的性能。
使用SVM作为模型时,通常采用如下流程:
sklearn中支持向量分类主要有三种方法:SVC、NuSVC、LinearSVC,扩展为三个支持向量回归方法:SVR、NuSVR、LinearSVR。
class sklearn.svm.SVC(C=1.0, kernel='rbf', degree=3,coef0=0.0,random_state=None)
C:
惩罚系数,用来控制损失函数的惩罚系数,类似于线性回归中的正则化系数。
kernel:
算法中采用的核函数类型,核函数是用来将非线性问题转化为线性问题的一种方法。
degree:
coef0:
核函数常数值(y=kx+b中的b值),
class sklearn.svm.NuSVC(nu=0.5)
class sklearn.svm.LinearSVC(penalty='l2', loss='squared_hinge', dual=True, C=1.0)
MNIST(“修改后的国家标准与技术研究所”)是计算机视觉事实上的“hello world”数据集。自1999年发布以来,这一经典的手写图像数据集已成为分类算法基准测试的基础。随着新的机器学习技术的出现,MNIST仍然是研究人员和学习者的可靠资源。
本次案例中,我们的目标是从数万个手写图像的数据集中正确识别数字。
数据文件train.csv和test.csv包含从0到9的手绘数字的灰度图像。
每个图像的高度为28个像素,宽度为28个像素,总共为784个像素。
每个像素具有与其相关联的单个像素值,指示该像素的亮度或暗度,较高的数字意味着较暗。该像素值是0到255之间的整数,包括0和255。
训练数据集(train.csv)有785列。第一列称为“标签”,是用户绘制的数字。其余列包含关联图像的像素值。
训练集中的每个像素列都具有像pixelx这样的名称,其中x是0到783之间的整数,包括0和783。为了在图像上定位该像素,假设我们已经将x分解为x = i * 28 + j,其中i和j是0到27之间的整数,包括0和27。然后,pixelx位于28 x 28矩阵的第i行和第j列上(索引为零)。
例如,pixel31表示从左边开始的第四列中的像素,以及从顶部开始的第二行,如下面的ascii图中所示。
在视觉上,如果我们省略“像素”前缀,像素组成图像如下:
000 001 002 003 ... 026 027
028 029 030 031 ... 054 055
056 057 058 059 ... 082 083
| | | | ...... | |
728 729 730 731 ... 754 755
756 757 758 759 ... 782 783
测试数据集(test.csv)与训练集相同,只是它不包含“标签”列。
参考:案例_手写数字分类.ipynb