ml课程:SVM相关(含代码实现)

版权声明:===========版权所有,可随意转载,欢迎互相交流=========== https://blog.csdn.net/weixin_42446330/article/details/84239448

以下是我的学习笔记,以及总结,如有错误之处请不吝赐教。

本文主要介绍svm的创始人Vapnik‘s如何一步一步构建出这个经典算法模型的,同时也可以给我们以后算法之路提供一个思路,即使你对优化等数学方法不熟悉,依然可以创造出很好的算法。

下svm关键的几个idea:

KEY IDEA 1:支持向量机最关键的一个假设是我们在分类过程中,最重要的是找到一个决策边界,而且我们希望这个决策边界泛化能力是最好的,而svm则是找到一条widest street way,这条街是由支持向量所构成的。我们假设支持向量所在点与原点构成的向量为\vec{u},与决策边界垂直的方向法向量为\vec{w},支持向量到决策边界的距离表示为b,那么我们就用这三个值表示出他们的关系:

                                                                           \vec{w}\cdot \vec{u_{x}}+b\geq 0

KEY IDEA 2:我们假设这条street的宽度为1,那么仅针对训练集有 :\left\{\begin{matrix}\vec{w}\cdot \vec{u_{x}}+b\geqslant 1 \\ \vec{w}\cdot \vec{u_{x}}+b\leqslant-1 \end{matrix}\right.,假设y_{i}=\left\{\begin{matrix} +1\\ -1 \end{matrix}\right.,那么我们将两式相乘合并为一个公式,就可以得到第二个关键公式:

                                                                          y_{i}(\vec{w}\cdot \vec{x}_{traing}+b)-1\geqslant 0

其中:取值为0的即为支持向量\vec{x}

KEY IDEA 3:那么我们如何使得这条street越宽越好呢?这条街的宽度可以表示为:width=(\vec{x_{+}}-\vec{x_{-}})\cdot \frac{\vec{w}}{||\vec{w}||},分别将y_{i}代入,可以得到:\vec{x_{+}}\cdot \vec{w}=1-b\vec{x_{-}}\cdot \vec{w}=-(1+b),得到:

                                                                                  width=\frac{2}{||\vec{w}||}

因此我们只需要求得max(width),即max\frac{2}{||\vec{w}||},即:

                                                                               min\frac{1}{2}||\vec{w}||^{2}

                                                              s.t.  y_{i}(\vec{w}\cdot \vec{x}_{i}+b)-1= 0

KEY IDEA 4:将其代入拉格朗日多项式得到:

                                                     \L =\frac{1}{2}||\vec{w}||^{2}-\sum \alpha _{i}[y_{i}(\vec{w}\cdot \vec{x}_{i}+b)-1]

分别对\vec{w}和b求导得到:

                                                             \partial L/\partial \vec{w} = \vec{w}-\sum \alpha _{i}y_{i}x_{i}

                                                              \partial L/\partial b = -\sum \alpha _{i}y_{i}

分别令其等于0,求得:

                                                         \vec{w}=\sum \alpha _{i}y_{i}x_{i}\sum \alpha _{i}y_{i}=0

代入原式:

                                                        \L =\sum \alpha _{i}-\frac{1}{2}\sum \sum \alpha _{i}\alpha _{j}y_{i}y_{j}\vec{x}_{i}\vec{x}_{j}

SVM另一种理解:假设一个函数叫做合页损失函数(hinge loss):

合页损失的函数图像如下所示:

SMO算法(sequential minimal optimization):

首先介绍坐标上升法:这个方法的思想是固定其他参数变量,先求其中一个变量的最大值。

SMO算法则是在坐标上升法之上改进一下,每次选择两个变量进行优化(两个变量其实等价于一个变量):

算法流程:(具体流程参考李航的《统计学习方法》P126-130页)

核心代码:

def smoSimple(dataMatIn, classLabels, C, toler, maxIter):
    dataMatrix = mat(dataMatIn); labelMat = mat(classLabels).transpose()
    b = 0; m,n = shape(dataMatrix)
    alphas = mat(zeros((m,1)))
    iter = 0
    while (iter < maxIter):
        alphaPairsChanged = 0
        for i in range(m):
            fXi = float(multiply(alphas,labelMat).T*(dataMatrix*dataMatrix[i,:].T)) + b
            Ei = fXi - float(labelMat[i])#if checks if an example violates KKT conditions
            if ((labelMat[i]*Ei < -toler) and (alphas[i] < C)) or ((labelMat[i]*Ei > toler) and (alphas[i] > 0)):
                j = selectJrand(i,m)
                fXj = float(multiply(alphas,labelMat).T*(dataMatrix*dataMatrix[j,:].T)) + b
                Ej = fXj - float(labelMat[j])
                alphaIold = alphas[i].copy(); alphaJold = alphas[j].copy();
                if (labelMat[i] != labelMat[j]):
                    L = max(0, alphas[j] - alphas[i])
                    H = min(C, C + alphas[j] - alphas[i])
                else:
                    L = max(0, alphas[j] + alphas[i] - C)
                    H = min(C, alphas[j] + alphas[i])
                if L==H: print("L==H"); continue
                eta = 2.0 * dataMatrix[i,:]*dataMatrix[j,:].T - dataMatrix[i,:]*dataMatrix[i,:].T - dataMatrix[j,:]*dataMatrix[j,:].T
                if eta >= 0: print("eta>=0"); continue
                alphas[j] -= labelMat[j]*(Ei - Ej)/eta
                alphas[j] = clipAlpha(alphas[j],H,L)
                if (abs(alphas[j] - alphaJold) < 0.00001): print("j not moving enough"); continue
                alphas[i] += labelMat[j]*labelMat[i]*(alphaJold - alphas[j])#update i by the same amount as j
                                                                        #the update is in the oppostie direction
                b1 = b - Ei- labelMat[i]*(alphas[i]-alphaIold)*dataMatrix[i,:]*dataMatrix[i,:].T - labelMat[j]*(alphas[j]-alphaJold)*dataMatrix[i,:]*dataMatrix[j,:].T
                b2 = b - Ej- labelMat[i]*(alphas[i]-alphaIold)*dataMatrix[i,:]*dataMatrix[j,:].T - labelMat[j]*(alphas[j]-alphaJold)*dataMatrix[j,:]*dataMatrix[j,:].T
                if (0 < alphas[i]) and (C > alphas[i]): b = b1
                elif (0 < alphas[j]) and (C > alphas[j]): b = b2
                else: b = (b1 + b2)/2.0
                alphaPairsChanged += 1
                print("iter: %d i:%d, pairs changed %d" % (iter,i,alphaPairsChanged))
        if (alphaPairsChanged == 0): iter += 1
        else: iter = 0
        print("iteration number: %d" % iter)
    return b,alphas

软间隔分类器:当数据线性不可分时,即使映射到高维空间并不能保证线性可分,如下图所示:

而软间隔分类器则是允许数据拥有小于1的几何间隔,但是要受到惩罚:

代入拉格朗日函数得到:

从而得到新的对偶问题:

对比原来只是对\alpha _{i}做了更多约束,新约束下的SMO算法如下图:

核技法:

同时我们可以在求其支持向量时使用核函数,将很多线性不可分的情况,映射至高维空间,而不用求其映射函数,只需求:

                                                          K(x_{i},x_{j} ) =\varnothing (x_{i})\cdot \varnothing (x_{j})

多项式核函数:

对应映射函数:

加常数项的多项式核函数

对应映射函数:

高斯核函数:

以上是几个核函数的例子,那么什么样的核是合法的呢?

Mercer定理:K是合法的核的充分必要条件是对于一个有限的数据集,对应的和矩阵都是半正定矩阵。关于半正定矩阵可自行百度。

以下是几个常用的核函数

通过以上的叙述,可以总结SVM有以下性质:

  • 数学特性:凸优化问题,保证会有全局最优解
  • 模型特性:
  1. 可以处理高维数据
  2. 软间隔降低过拟合
  3. 求解完成后只有少数数据起作用
  4. 灵活的选择核函数

下次将介绍另一个经典算法:EM算法,未完,To be continue......

猜你喜欢

转载自blog.csdn.net/weixin_42446330/article/details/84239448