天天看點

機器學習:SVM、軟間隔、随機梯度下降SVM線性算法SVM目标函數軟間隔、松弛

文章目錄

  • SVM目标函數
    • SVM目标函數推導
      • 函數間隔:
      • 幾何間隔:
  • 軟間隔、松弛
    • HingeLoss和軟間隔
    • 随機梯度下降算法
    • 線性SVM的算法描述:
    • 線性SVM算法實作:

SVM目标函數

機器學習:SVM、軟間隔、随機梯度下降SVM線性算法SVM目标函數軟間隔、松弛

SVM目标函數推導

機器學習:SVM、軟間隔、随機梯度下降SVM線性算法SVM目标函數軟間隔、松弛

函數間隔:

機器學習:SVM、軟間隔、随機梯度下降SVM線性算法SVM目标函數軟間隔、松弛

幾何間隔:

機器學習:SVM、軟間隔、随機梯度下降SVM線性算法SVM目标函數軟間隔、松弛

SVM 算法就可以比較自然地叙述為:最大化(幾何間隔)d、使得:

機器學習:SVM、軟間隔、随機梯度下降SVM線性算法SVM目标函數軟間隔、松弛

不妨假設函數間隔為1,這樣就得到最開始的優化目标方程。

限制條件中: y i ( w . x + b ) − 1 > = 0 y_i(w . x + b) -1 >=0 yi​(w.x+b)−1>=0,那個“1”就是函數間隔,注意這裡的目标是關注的是間隔, y i ( w . x + b ) − 1 = 0 y_i(w . x + b) -1 =0 yi​(w.x+b)−1=0就是間隔直線上的點。

軟間隔、松弛

在數學上就是做了如下操作:

機器學習:SVM、軟間隔、随機梯度下降SVM線性算法SVM目标函數軟間隔、松弛

ξ i \xi_i ξi​就是松弛變量,可以把函數間隔變量化,但是變化可以控制,如何控制了,使用懲罰因子來控制函數間隔。

機器學習:SVM、軟間隔、随機梯度下降SVM線性算法SVM目标函數軟間隔、松弛

限制條件為:

機器學習:SVM、軟間隔、随機梯度下降SVM線性算法SVM目标函數軟間隔、松弛

從常識來看這個優化問題的解存在,w的解唯一,但是b的解不唯一,也就是解是一組平行線

HingeLoss和軟間隔

上述目标函數限制條件 ξ i \xi_i ξi​>=0,也就是函數間隔為1- ξ i \xi_i ξi​,當 ξ i \xi_i ξi​<0時,函數間隔就為1,當 ξ i \xi_i ξi​>0時,函數間隔就為1- ξ i \xi_i ξi​,等價為如下函數:

機器學習:SVM、軟間隔、随機梯度下降SVM線性算法SVM目标函數軟間隔、松弛

對應的目标函數為:

機器學習:SVM、軟間隔、随機梯度下降SVM線性算法SVM目标函數軟間隔、松弛

實際上我們一般見到的hingeLoss的目标函數是:

機器學習:SVM、軟間隔、随機梯度下降SVM線性算法SVM目标函數軟間隔、松弛

令 λ \lambda λ = 1\2C,他們二者是等價的。

Hinge Loss就相當于松弛因子ξ

對于間距大于一定程度的點,就沒有loss,就不用松弛。

正則化的作用相當于把分類的距離拉大。

随機梯度下降算法

松弛因子ξ>=0轉化為Hinge Loss之後使用随機梯度下降就比較友善了,針對單一樣本( x i x_i xi​, y i y_i yi​)對w,b求偏導:

機器學習:SVM、軟間隔、随機梯度下降SVM線性算法SVM目标函數軟間隔、松弛

線性SVM的算法描述:

機器學習:SVM、軟間隔、随機梯度下降SVM線性算法SVM目标函數軟間隔、松弛

首先該算法是基于hingeloss的随機梯度下降算法,和感覺機算法流程一緻:周遊樣本,找出誤差最大的樣本,也就是函數間隔比1小的最多的樣本,然後在誤差為正的樣本裡面,選出誤差最大的樣本,使用這個樣本更新w和b,使用新的參數周遊樣本,直到所有的樣本誤差為負,也就是所有的樣本函數間隔大于1。

線性SVM算法實作:

import numpy as np

class LinearSVM:
    def __init__(self):
        self._w = self._b = None
        
    def fit(self, x, y, c=1, lr=0.01, epoch=10000):
        x, y = np.asarray(x, np.float32), np.asarray(y, np.float32)
        self._w = np.zeros(x.shape[1])
        self._b = 0.
        for _ in range(epoch):
            self._w *= 1 - lr
            err = 1 - y * self.predict(x, True)
            idx = np.argmax(err)
            # 注意即使所有 x, y 都滿足 w·x + b >= 1
            # 由于損失裡面有一個 w 的模長平方
            # 是以仍然不能終止訓練,隻能截斷目前的梯度下降
            if err[idx] <= 0:
                continue
            delta = lr * c * y[idx]
            self._w += delta * x[idx]
            self._b += delta
    
    def predict(self, x, raw=False):
        x = np.asarray(x, np.float32)
        y_pred = x.dot(self._w) + self._b
        if raw:
            return y_pred
        return np.sign(y_pred).astype(np.float32)
           

這種使用最大誤差樣本更新w,b的方式,是随機梯度下降?預測一遍全部樣本找誤差最大的樣本,為什麼不使用全部樣本的來更新w,b,我覺得随機梯度就應該随便找選擇一個樣本,使用這個樣本來更新w,b,假如有誤差就按照上述更新,沒有誤差就換一個樣本。