SVM是Support Vector Machine(支持向量机)的英文缩写,是上世纪九十年代兴起的一种机器学习算法,在目前神经网络大行其道的状况下依然保持着生命力。有人说如今是神经网络深度学习的时代了,AI从业者能够不用了解像SVM这样的古董了。姑且不说SVM是否真的已经没有前途了,仅仅是SVM在数学上优美的推导就值得后来者好好欣赏一番,这也是笔者迄今为止见过机器学习领域最优美的数学推导。算法
和大多数二分类算法同样,SVM算法也是致力于在正例和反例之间找出一个超平面来将它们区分开来,以下图所示:网络
如图所示,正例用“+”号表示,反例用“-”号表示。从图中能够看出,正例和反例是线性可分的。学习器的目的就是要学出一条如图所示的红色超平面将正例和反例区分开来。这也是其余非SVM分类器的共同目标,即:机器学习
而SVM与其它分类器所不一样的是它引入了“支持向量”这一律念,反映到图中也就是红色的小点所表明的向量。(注:因为笔者做图时采用的SVM是软间隔的版本,所以支持向量不像是大多数教科书上采用硬间隔的SVM那样)由SVM的优化目标咱们能够知道:样本空间中任意一个点x到该超平面的的距离可写为:函数
假设超平面能够彻底正确地将全部样本分类,则对于任意一个样本(xi,yi)来讲都有以下性质(注:样本的标签用+1表明正例,-1表明反例):学习
训练样本中使上式成立的样本称为支持向量,两个异类支持向量到超平面距离之和为:优化
上式被称为“间隔”。SVM的优化目标是为了找到这样一个划分超平面,该超平面能使间隔最大化,则SVM的优化目标能够表示为以下形式:spa
这就是SVM的基本数学表达,接下来就要对SVM问题进行求解。从上面的数学形式能够看出这是一个优化问题,可使用拉格朗日乘子法求解其对偶问题。因为本文不是专门介绍SVM的,所以忽略掉具体的推导,直接给出SVM的对偶问题表达:3d
因为采用了拉格朗日乘子法,所以该对偶问题还有一个KKT条件约束,即要求:orm
以上,就是SVM的一些相关介绍。须要特别说明的是,以上的推导都是创建在“硬间隔”的基础上,“硬间隔”要求样本集中每个样本都知足约束条件。在现实中每每很难肯定合适的核函数使得训练样本在特征空间中是线性可分的,缓解该问题的一个办法是容许支持向量机在一些样本上出错,为此引入“软间隔”的概念。具体来讲,“硬间隔”要求全部参与训练的样本都必须知足SVM的约束条件,而“软间隔”容许有部分样本不知足这样的约束。因为本文不是专门论述SVM的,所以就不展开讲“软间隔”所带来的一些新的问题,只说一下“软间隔”条件下新的优化目标:对象
KKT条件为:
其中,C为容忍度因子,能够理解为SVM对“软间隔”的支持度。若C为无穷大,则全部的训练样本均必须知足SVM的约束条件,C值越小就容许越多的样本不知足约束条件。
经过观察SVM的优化目标咱们能够发现其最终的目的是要计算出一组最优的alpha和常数项b的值。SMO算法的中心思想就是每次选出两个alpha进行优化(之因此是两个是由于alpha的约束条件决定了其与标签乘积的累加等于0,所以必须一次同时优化两个,不然就会破坏约束条件),而后固定其余的alpha值。重复此过程,直到达到某个终止条件程序退出并获得咱们须要的优化结果。接下来,就具体推导一下SMO算法的细节。
因为SVM中有核函数的概念,所以咱们用Kij来表示在核函数K下向量i和向量j的计算值。如今假定咱们已经选出alpha1和alpha2两个待优化项,而后将原优化目标函数展开为与alpha1和alpha2有关的部分和无关的部分:
其中c是与alpha1和alpha2无关的部分,在本次优化中当作常数项处理。由SVM优化目标函数的约束条件:
能够获得:
将优化目标中全部的alpha1都替换为用alpha2表示的形式,获得以下式子:
此时,优化目标中仅含有alpha2一个待优化变量了,咱们如今将待优化函数对alpha2求偏导获得以下结果:
已知:
将以上三个条件带入偏导式子中,获得以下结果:
化简后得:
记:
若n<=0则退出本次优化,若n>0则可获得alpha2的更新公式:
此时,咱们已经获得了alpha2的更新公式。不过咱们此时还须要考虑alpha2的取值范围问题。由于alpha2的取值范围应该是在0到C之间,可是在这里并不能简单地把取值范围限定在0至C之间,由于alpha2的取值不只仅与其自己的范围有关,也与alpha1,y1和y2有关。设alpha1*y1+alpha2*y2=k,画出其约束,在这里要分两种状况,即y1是否等于y2。咱们在这里先来考虑y1!=y2的状况:在这种状况下alpha1-alpha2=k:
能够看出此时alpha2的取值范围为:
当y1=y2时,alpha1+alpha2=k:
能够看出此时alpha2的取值范围为:
以上,能够总结出alpha2的取值上下界的规律:
故可获得alpha2的取值范围:
由alpha_old1y1+alpha_old2y2=alpha_new1y1+alpha_new2y2可得alpha1的更新公式:
接下来,须要肯定常数b的更新公式,在这里首先须要根据“软间隔”下SVM优化目标函数的KKT条件推导出新的KKT条件,获得结果以下:
因为如今alpha的取值范围已经限定在0至C之间,也就是上面KKT条件的第三种状况。接下来咱们将第三种KKT条件推广到任意核函数的情境下:
由此咱们能够获得常数b的更新公式:
其中Ei是SVM的预测偏差,计算式为:
以上,笔者就已经把SMO算法的大部分细节推导出来了。接下来,咱们能够根据这些推导对SMO算法进行实现,而且用咱们的算法训练一个SVM分类器。
SMO算法的实现仍是比较复杂的,有不少细节,咱们不用一一关注,只用抓住其中两个特别重要的点就好了:一、如何选取每次迭代的alpha对;二、如何肯定SVM优化程序的退出条件。笔者将就这两个主要问题进行论述。首先关注第一个问题:如何选取alpha对。
咱们能够简化一下第一个问题:假定如今已经选取了第一个待优化的alpha,如何选取另外一个alpha?在SMO算法中为了让迭代次数尽可能少,收敛速度尽可能快,算法要求咱们选取的两个alpha有尽量大的“差别”。在算法的实现中咱们用预测的偏差值来表征一个alpha的效果。那么两个aplha尽量不一样反映在算法上就是两个alpha所对应的预测偏差值之差的绝对值最大,该思想用代码表现出来以下图所示:
上面的代码反映出了这样一种思想:首先传入第一个alpha所对应的索引值“i”,而后搜索偏差列表eCache,在其中找到与“i”所对应的偏差值相差绝对值最大的那个索引值“j”,则另外一个alpha的索引值就定为“j”。若偏差值列表eCache尚未初始化则从全部的索引值中随机选取一个索引值做为另外一个alpha的索引值。
那么第一个alpha如何选取呢?这个问题与另外两个问题是相关的:第一个问题是选取的alpha值是否违反KKT条件,若是该alpha值违反了KKT条件则该alpha是不可以做为优化对象的;第二个问题与SMO优化算法的优化终止条件有关,一般SMO算法会在一个死循环中反复执行两个过程,第一个过程是遍历全部的alpha值,每扫描到一个alpha就将其做为alpha对的第一个值传入内循环,同时根据上一段提出的选取准则选择另外一个alpha。遍历完一次alpha值以后若alpha值被优化器改变的次数不为0则本次循环结束同时修改一些标志量而后进入下一次循环。下一次循环执行第二个过程:遍历alpha值列表中全部不为0的值,每扫描到一个不为0的alpha值以后就将其传入内循环,而后执行和上面相同的过程。重复执行上述过程,最终,当某次循环遍历优化全部alpha列表后却没有一个alpha值被优化器改变则程序认为优化任务完成了,程序退出。代码以下:
以上,就是SMO算法在实现时的一些细节。完整的SMO实现仍是比较复杂的,有不少的小细节须要注意,在这里就不一一论述了。