1. 程式人生 > >ml課程:SVM相關(含程式碼實現)

ml課程:SVM相關(含程式碼實現)

以下是我的學習筆記,以及總結,如有錯誤之處請不吝賜教。

本文主要介紹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......