CategoryResourceRepost/极客时间专栏/数据分析实战45讲/第二模块:数据分析算法篇/22丨SVM(上):如何用一根棍子将蓝红两色球分开?.md
louzefeng d3828a7aee mod
2024-07-11 05:50:32 +00:00

149 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<audio id="audio" title="22丨SVM如何用一根棍子将蓝红两色球分开" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/9d/49/9dedf904e39f47c1865d15ab91b18d49.mp3"></audio>
今天我来带你进行SVM的学习SVM的英文叫Support Vector Machine中文名为支持向量机。它是常见的一种分类方法在机器学习中SVM是有监督的学习模型。
什么是有监督的学习模型呢它指的是我们需要事先对数据打上分类标签这样机器就知道这个数据属于哪个分类。同样无监督学习就是数据没有被打上分类标签这可能是因为我们不具备先验的知识或者打标签的成本很高。所以我们需要机器代我们部分完成这个工作比如将数据进行聚类方便后续人工对每个类进行分析。SVM作为有监督的学习模型通常可以帮我们模式识别、分类以及回归分析。
听起来,是不是很高大上。我先带你做个小练习。
练习1桌子上我放了红色和蓝色两种球请你用一根棍子将这两种颜色的球分开。
<img src="https://static001.geekbang.org/resource/image/21/88/210bc20b5963d474d425ad1ca9ac6888.jpg" alt=""><br>
你可以很快想到解决方案,在红色和蓝色球之间画条直线就好了,如下图所示:
<img src="https://static001.geekbang.org/resource/image/ec/bb/ec657a6d274b5afb4d8169df9c248abb.jpg" alt=""><br>
练习2这次难度升级桌子上依然放着红色、蓝色两种球但是它们的摆放不规律如下图所示。如何用一根棍子把这两种颜色分开呢
<img src="https://static001.geekbang.org/resource/image/b4/a3/b4b9793cdec47d0ea1528ff1922973a3.jpg" alt=""><br>
你可能想了想,认为一根棍子是分不开的。除非把棍子弯曲,像下面这样:
<img src="https://static001.geekbang.org/resource/image/14/eb/144d72013a808e955e78718f6df3d2eb.jpg" alt=""><br>
所以这里直线变成了曲线。如果在同一个平面上来看,红蓝两种颜色的球是很难分开的。那么有没有一种方式,可以让它们自然地分开呢?
这里你可能会灵机一动,猛拍一下桌子,这些小球瞬间腾空而起,如下图所示。在腾起的那一刹那,出现了一个水平切面,恰好把红、蓝两种颜色的球分开。
<img src="https://static001.geekbang.org/resource/image/9e/dc/9e07b78932456cd8a6f46d7ea65bdadc.png" alt="">
<img src="https://static001.geekbang.org/resource/image/f3/34/f3497cd97c8bb06e952efcdae6059434.jpg" alt=""><br>
在这里,二维平面变成了三维空间。原来的曲线变成了一个平面。这个平面,我们就叫做超平面。
## SVM的工作原理
用SVM计算的过程就是帮我们找到那个超平面的过程这个超平面就是我们的SVM分类器。
我们再过头来看最简单的练习1其实我们可以有多种直线的划分比如下图所示的直线A、直线B和直线C究竟哪种才是更好的划分呢
<img src="https://static001.geekbang.org/resource/image/74/e7/7459de7fbe99af85cbfdacf2333f84e7.jpg" alt=""><br>
很明显图中的直线B更靠近蓝色球但是在真实环境下球再多一些的话蓝色球可能就被划分到了直线B的右侧被认为是红色球。同样直线A更靠近红色球在真实环境下如果红色球再多一些也可能会被误认为是蓝色球。所以相比于直线A和直线B直线C的划分更优因为它的鲁棒性更强。
那怎样才能寻找到直线C这个更优的答案呢这里我们引入一个SVM特有的概念**分类间隔**。
实际上我们的分类环境不是在二维平面中的而是在多维空间中这样直线C就变成了决策面C。
在保证决策面不变且分类不产生错误的情况下我们可以移动决策面C直到产生两个极限的位置如图中的决策面A和决策面B。极限的位置是指如果越过了这个位置就会产生分类错误。这样的话两个极限位置A和B之间的分界线C就是最优决策面。极限位置到最优决策面C之间的距离就是“分类间隔”英文叫做margin。
如果我们转动这个最优决策面你会发现可能存在多个最优决策面它们都能把数据集正确分开这些最优决策面的分类间隔可能是不同的而那个拥有“最大间隔”max margin的决策面就是SVM要找的最优解。
<img src="https://static001.geekbang.org/resource/image/50/ea/506cc4b85a9206cca12048b29919a7ea.jpg" alt=""><br>
**点到超平面的距离公式**
在上面这个例子中,如果我们把红蓝两种颜色的球放到一个三维空间里,你发现决策面就变成了一个平面。这里我们可以用线性函数来表示,如果在一维空间里就表示一个点,在二维空间里表示一条直线,在三维空间中代表一个平面,当然空间维数还可以更多,这样我们给这个线性函数起个名称叫做“超平面”。超平面的数学表达可以写成:
<img src="https://static001.geekbang.org/resource/image/76/28/765e87a2d9d6358f1274478dacbbce28.png" alt=""><br>
在这个公式里w、x是n维空间里的向量其中x是函数变量w是法向量。法向量这里指的是垂直于平面的直线所表示的向量它决定了超平面的方向。
**SVM就是帮我们找到一个超平面**,这个超平面能将不同的样本划分开,同时使得样本集中的点到这个分类超平面的最小距离(即分类间隔)最大化。
在这个过程中,**支持向量**就是离**分类超平面**最近的样本点,实际上如果确定了支持向量也就确定了这个超平面。所以支持向量决定了分类间隔到底是多少,而在最大间隔以外的样本点,其实对分类都没有意义。
所以说, SVM就是求解最大分类间隔的过程我们还需要对分类间隔的大小进行定义。
首先我们定义某类样本集到超平面的距离是这个样本集合内的样本到超平面的最短距离。我们用di代表点xi到超平面wxi+b=0的欧氏距离。因此我们要求di的最小值用它来代表这个样本到超平面的最短距离。di可以用公式计算得出
<img src="https://static001.geekbang.org/resource/image/83/76/8342b5253cb4c294c72cef6802814176.png" alt=""><br>
其中||w||为超平面的范数di的公式可以用解析几何知识进行推导这里不做解释。
**最大间隔的优化模型**
我们的目标就是找出所有分类间隔中最大的那个值对应的超平面。在数学上这是一个凸优化问题凸优化就是关于求凸集中的凸函数最小化的问题这里不具体展开。通过凸优化问题最后可以求出最优的w和b也就是我们想要找的最优超平面。中间求解的过程会用到拉格朗日乘子和KKTKarush-Kuhn-Tucker条件。数学公式比较多这里不进行展开。
## 硬间隔、软间隔和非线性SVM
假如数据是完全的线性可分的,那么学习到的模型可以称为硬间隔支持向量机。**换个说法,硬间隔指的就是完全分类准确,不能存在分类错误的情况。软间隔,就是允许一定量的样本分类错误**。
我们知道实际工作中的数据没有那么“干净”或多或少都会存在一些噪点。所以线性可分是个理想情况。这时我们需要使用到软间隔SVM近似线性可分比如下面这种情况
<img src="https://static001.geekbang.org/resource/image/7c/a6/7c913ee92cdcf4d461f0ebc1314123a6.jpg" alt=""><br>
另外还存在一种情况,就是非线性支持向量机。
比如下面的样本集就是个非线性的数据。图中的两类数据分别分布为两个圆圈的形状。那么这种情况下不论是多高级的分类器只要映射函数是线性的就没法处理SVM 也处理不了。这时,我们需要引入一个新的概念:**核函数。它可以将样本从原始空间映射到一个更高维的特质空间中,使得样本在新的空间中线性可分**。这样我们就可以使用原来的推导来进行计算,只是所有的推导是在新的空间,而不是在原来的空间中进行。
<img src="https://static001.geekbang.org/resource/image/55/23/5530b0e61085a213ef1d0dfe02b70223.jpg" alt=""><br>
所以在非线性SVM中核函数的选择就是影响SVM最大的变量。最常用的核函数有线性核、多项式核、高斯核、拉普拉斯核、sigmoid核或者是这些核函数的组合。这些函数的区别在于映射方式的不同。通过这些核函数我们就可以把样本空间投射到新的高维空间中。
当然软间隔和核函数的提出都是为了方便我们对上面超平面公式中的w*和b*进行求解,从而得到最大分类间隔的超平面。
## 用SVM如何解决多分类问题
SVM本身是一个二值分类器最初是为二分类问题设计的也就是回答Yes或者是No。而实际上我们要解决的问题可能是多分类的情况比如对文本进行分类或者对图像进行识别。
针对这种情况,我们可以将多个二分类器组合起来形成一个多分类器,常见的方法有“一对多法”和“一对一法”两种。
1.一对多法
假设我们要把物体分成A、B、C、D四种分类那么我们可以先把其中的一类作为分类1其他类统一归为分类2。这样我们可以构造4种SVM分别为以下的情况
1样本A作为正集BCD作为负集
2样本B作为正集ACD作为负集
3样本C作为正集ABD作为负集
4样本D作为正集ABC作为负集。
这种方法针对K个分类需要训练K个分类器分类速度较快但训练速度较慢因为每个分类器都需要对全部样本进行训练而且负样本数量远大于正样本数量会造成样本不对称的情况而且当增加新的分类比如第K+1类时需要重新对分类器进行构造。
2.一对一法
一对一法的初衷是想在训练的时候更加灵活。我们可以在任意两类样本之间构造一个SVM这样针对K类的样本就会有C(k,2)类分类器。
比如我们想要划分A、B、C三个类可以构造3个分类器
1分类器1A、B
2分类器2A、C
3分类器3B、C。
当对一个未知样本进行分类时每一个分类器都会有一个分类结果即为1票最终得票最多的类别就是整个未知样本的类别。
这样做的好处是如果新增一类不需要重新训练所有的SVM只需要训练和新增这一类样本的分类器。而且这种方式在训练单个SVM模型的时候训练速度快。
但这种方法的不足在于分类器的个数与K的平方成正比所以当K较大时训练和测试的时间会比较慢。
## 总结
今天我给你讲了SVM分类器它在文本分类尤其是针对二分类任务性能卓越。同样针对多分类的情况我们可以采用一对多或者一对一的方法多个二值分类器组合成一个多分类器。
另外关于SVM分类器的概念我希望你能掌握以下的三个程度
<li>
完全线性可分情况下的线性分类器也就是线性可分的情况是最原始的SVM它最核心的思想就是找到最大的分类间隔
</li>
<li>
大部分线性可分情况下的线性分类器,引入了软间隔的概念。软间隔,就是允许一定量的样本分类错误;
</li>
<li>
线性不可分情况下的非线性分类器,引入了核函数。它让原有的样本空间通过核函数投射到了一个高维的空间中,从而变得线性可分。
</li>
在SVM的推导过程中有大量的数学公式这里不进行推导演绎因为除了写论文你大部分时候不会用到这些公式推导。
所以最重要的还是理解我上面讲的这些概念能在实际工作中使用SVM才是最重要的。下一节我会和你讲如何用sklearn工具包进行SVM分类带你做一个实际的案例。
最后你能说一下你对有监督学习和无监督学习的理解吗以及SVM最主要的思想就是硬间隔、软间隔和核函数。你是如何理解它们的
欢迎你在评论区进行留言,与我分享你的答案。也欢迎点击“请朋友读”,把这篇文章分享给你的朋友或者同事。