機器學習筆記(七)——初識邏輯迴歸、不同方法推導梯度公式

程式碼化前的迴歸係數怎麼算

一、演算法概述

邏輯迴歸(Logistic)雖帶有迴歸二字,但它卻是一個經典的二分類演算法,它適合處理一些二分類任務,例如疾病檢測、垃圾郵件檢測、使用者點選率以及上文所涉及的正負情感分析等等。

首先了解一下何為迴歸?假設現在有一些資料點,我們利用一條直線對這些點進行擬合(該線稱為最佳擬合直線),這個擬合的過程就稱作迴歸。利用邏輯迴歸進行分類的主要思想是:根據現有資料對分類邊界線建立迴歸公式,以此進行分類。

線性迴歸演算法後面的筆記會介紹,這裡簡單對比一下兩者,邏輯迴歸和線性迴歸的本質相同,都意在擬合一條直線,但線性迴歸的目的是擬合

輸入變數的分佈

,儘可能讓所有樣本到該條直線的距離最短;而邏輯迴歸的目的是擬合

決策邊界

,使資料集中不同的樣本儘可能分開,所以兩個演算法的目的是不同的,處理的問題也不同。

二、Sigmoid函式與相關推導

我們想要的函式應該是,能接受所有的輸入並且預測出類別,比如二分類中的0或者1、正或者負,這種性質的函式被稱為海維賽德階躍函式,影象如下:

機器學習筆記(七)——初識邏輯迴歸、不同方法推導梯度公式

但這種函式的問題在於從0跳躍到1的過程非常難處理,比如我們常接觸的多次函式,可能在某種條件下需要求導解決問題;而

Sigmoid

函式也具有類似的性質,並且在數學上更容易處理,其公式如下:

機器學習筆記(七)——初識邏輯迴歸、不同方法推導梯度公式

下圖是

Sigmoid

函式在不同座標尺度下的兩條曲線圖。當x為0時,

Sigmoid

函式值為0。5,隨著x的增大,對應的Sigmoid值將逼近於1;而隨著x的減小,

Sigmoid

值將逼近於0。如果橫座標刻度足夠大,

Sigmoid

函式看起來就很像一個階躍函式。

機器學習筆記(七)——初識邏輯迴歸、不同方法推導梯度公式

若我們將

Sigmoid

函式的輸入記作z,可推出下面公式:

機器學習筆記(七)——初識邏輯迴歸、不同方法推導梯度公式

它表示將這兩個數值向量對應元素相乘然後全部相加起來得到z值,其中向量x是分類器的輸入資料,向量w就是我們要找到的能使分類器儘可能準確的最佳引數。

由上述公式就可得:

機器學習筆記(七)——初識邏輯迴歸、不同方法推導梯度公式

其中h_w(x)的作用就是給定輸入時,輸出分類為正向類(1)的可能性。例如,對於一個給定的x,h_w(x)的值為0。8,則說明有80%的可能輸出為正向類(1),有20%的可能輸出為負向類(0),二者成補集關係。

對於一個二分類問題而言,我們給定輸入,函式最終的輸出只能有兩類,0或者1,所以我們可以對其分類。

機器學習筆記(七)——初識邏輯迴歸、不同方法推導梯度公式

為了運算便捷,我們將其整合為一個公式,如下:

機器學習筆記(七)——初識邏輯迴歸、不同方法推導梯度公式

由於乘法計算量過大,所以可以將乘法變加法,對上式求對數,如下:

機器學習筆記(七)——初識邏輯迴歸、不同方法推導梯度公式

可以看出當y=1時,加號後面式子的值為0;當y=0時,加號前面式子的值為0,這與上文分類式子達到的效果是一樣的。L(w)稱為似然函式,J(w)稱為對數似然函式,是依據最大似然函式推導而成。此時的應用是梯度上升求最大值,如果梯度下降求最小值,可在公式之前乘以-1/n。

為了學習嘛,這裡再介紹一下另一種方式,利用

損失函式

推導應用於梯度下降的公式;損失函式是衡量

真實值與預測值

之間差距的函式,所以損失函式值越小,對應模型的效果也越好,損失函式公式如下:

機器學習筆記(七)——初識邏輯迴歸、不同方法推導梯度公式

可能只看公式理解相對抽象,透過對應的函式影象足以理解上式,如下:

機器學習筆記(七)——初識邏輯迴歸、不同方法推導梯度公式

注意!!!

公式後面的y*不代表縱座標

!!!

當類標籤y=1時,對應的-log(x)影象越接近於1,其距離x軸越近,代表其損失越小;反之當類標籤y=0時,對應的-log(1-x)影象越接近於0,其距離x軸越近,代表其損失越小,也就是預測值越接近於真實值。

將兩個損失函式綜合起來得:

機器學習筆記(七)——初識邏輯迴歸、不同方法推導梯度公式

對於m個樣本,總損失函式為:

機器學習筆記(七)——初識邏輯迴歸、不同方法推導梯度公式

其中m為樣本個數、yi為標籤,可取0或1、i為第i個樣本、p(x_i)為預測輸出。

三、梯度

3。1梯度上升

上面已經列出了一大堆的公式,難道這又要開始一連串的大公式?

機器學習筆記(七)——初識邏輯迴歸、不同方法推導梯度公式

心態放平,上文雖說公式有點多,但目的都是為了推出最後的對數似然函式或者總損失函式,掌握這兩個是關鍵,梯度上升和梯度下降也會利用上面的公式做推導,所以二者之間存在關聯。首先梯度上升你需要了解一下何為梯度?

如果將梯度記為▽,則函式f(x,y)的梯度可由下式表示:

機器學習筆記(七)——初識邏輯迴歸、不同方法推導梯度公式

通俗的說,即對多元函式的引數求偏導,並把求得的各個引數的偏導以向量的形式寫出來。或者你只要理解這個梯度要沿著x的方向移動delta f(x,y)/delta x,沿著y方向移動delta f(x,y)/delta y足以,但f(x,y)必須要在待計算的點上有定義且可微。

下圖為一個梯度上升的例子,梯度上升法在到達每一個點之後都會重新評估下一步將要移動的方向。從x0開始,在計算完該點的梯度,函式就會移動到下一個點x1。在x1點,梯度會重新計算,繼而移動到x2點。如此迴圈迭代此過程,直到滿足停止條件,每次迭代過程都是為了找出當前能選取到的最佳移動方向。

機器學習筆記(七)——初識邏輯迴歸、不同方法推導梯度公式

之前一直在討論移動方向,而未提到過移動量的大小。該量值稱為步長,記作$\alpha$。那麼就可以得出梯度上升法的迭代公式:

機器學習筆記(七)——初識邏輯迴歸、不同方法推導梯度公式

所以對於上文所提及的對數似然函式J(w),我們也可以利用上述迭代的方式,一步一步移動到目標值或者無限接近於目標值,J(w)求偏導的公式如下:

機器學習筆記(七)——初識邏輯迴歸、不同方法推導梯度公式

可能有的人看到這個偏導公式有點蒙,其實這裡面用到的三個函式公式都是上文所提及的,來回顧一下。

機器學習筆記(七)——初識邏輯迴歸、不同方法推導梯度公式

求偏導過程涉及到高數知識,即最外層函式對外層函式求偏導、外層函式對內層函式求偏導、內層函式對其元素求偏導,三者相乘可得出所需偏導。推導過程有些麻煩,這裡只給出推導結果,在後面運用時我們也只會運用到最終結果,如下:

機器學習筆記(七)——初識邏輯迴歸、不同方法推導梯度公式

3。2梯度下降

如果利用將對數似然函式換成損失函式$J(\Theta)$,則得到的是有關計算梯度下降的公式,如下:

機器學習筆記(七)——初識邏輯迴歸、不同方法推導梯度公式

兩個公式中的w和Theta的含義是一樣的,都代表我們所求的最佳迴歸係數,兩個公式對比可以看出梯度上升和梯度下降只有加減號區別之分。下面這個動圖就可以很好的展示梯度下降法的過程:

機器學習筆記(七)——初識邏輯迴歸、不同方法推導梯度公式

公式推導部分至此結束了,基礎偏好的夥伴可能一遍就懂了,但基礎偏弱理解起來比較困難,偶當時也是對著書、跟著影片啃了好久,多啃幾遍終歸會理解的。

機器學習筆記(七)——初識邏輯迴歸、不同方法推導梯度公式

四、演算法應用

4。1資料概覽

有這樣一份資料集,共100個樣本、兩個特徵(X1與X2)以及一個分類標籤,所繪製圖像如下:

機器學習筆記(七)——初識邏輯迴歸、不同方法推導梯度公式

在此資料集上,我們將透過梯度下降法找到最佳迴歸係數,也就是擬合出Logistic迴歸模型的最佳引數。 該演算法的虛擬碼如下:

每個迴歸係數初始化為1重複R次: 計算整個資料集的梯度 使用alpha*gradient更新迴歸係數的向量 返回迴歸係數

4。2載入資料集

def loadDataSet():    dataMat = []    # 建立資料列表    labelMat = []    # 建立標籤列表    fr = open(‘LRData。txt’,‘r’,encoding=‘utf-8’)    #逐行讀取全部資料    for line in fr。readlines():        #將資料分割、存入列表        lineArr = line。strip()。split()        #資料存入資料列表        dataMat。append([1。0, float(lineArr[0]), float(lineArr[1])])        #標籤存入標籤列表        labelMat。append(int(lineArr[2]))    fr。close()    return dataMat, labelMat

loadDataSet

函式的作用是開啟儲存資料的文字檔案並逐行讀取。每行的前兩個值分別對應X1和X2,第三個值是資料對應的類別標籤。為了方便計算,函式還在X1和X2之前添加了一個值為1。0的X1,X1可以理解為偏置,即下圖中的x0。

機器學習筆記(七)——初識邏輯迴歸、不同方法推導梯度公式

4。3訓練演算法

#sigmoid函式def sigmoid(inX):    return 1。0 / (1 + np。exp(-inX))

sigmoid

函式就是傳入一個引數(這裡是一個100x1的向量),透過公式計算並返回值。

def gradAscent(dataMatIn, classLabels):    # 將列表轉換成numpy的matrix(矩陣)    dataMatrix = np。mat(dataMatIn)    # 將列表轉換成numpy的mat,並進行轉置    labelMat = np。mat(classLabels)。T    # 獲取dataMatrix的行數和列數。    m, n = np。shape(dataMatrix)    # 設定每次移動的步長    alpha = 0。001    # 設定最大迭代次數    maxCycles = 500    # 建立一個n行1列都為1的矩陣    weights = np。ones((n,1))    for k in range(maxCycles):        # 公式中hΘ(x)        h = sigmoid(dataMatrix * weights)        # 誤差,即公式中y-hΘ(x)        error = labelMat - h        # 套入整體公式        weights = weights + alpha * dataMatrix。T * error    return weights

最後

weights

返回的是一個3x1的矩陣,執行截圖如下:

機器學習筆記(七)——初識邏輯迴歸、不同方法推導梯度公式

gradAscent

傳入引數為

loadDataSet

的兩個返回值,然後透過

numpy

mat

方法將

dataMatrix

labelMat

分為轉化為100x3和1x100的矩陣,但

labelMat

經過T轉置後變成100x1的矩陣。然後初始化權重,利用的方法就是建立一個n行1列的矩陣。整個演算法的關鍵處於for迴圈中,我們先回顧一下上文的兩個公式。

機器學習筆記(七)——初識邏輯迴歸、不同方法推導梯度公式

機器學習筆記(七)——初識邏輯迴歸、不同方法推導梯度公式

其中h的計算結果即h_w(x),權重

weight

為W向量,輸入矩陣

dataMatrix

為x向量。誤差

error

代表yi-h_w(xi),有人可能會發現1/m沒有出現在程式碼中,因為alpha和1/m都為常數,二者相乘也為常數,所以只需要用alpha代替即可。

公式中的加和部分又怎麼體現呢?如果學過線性代數或者瞭解

numpy

運算的夥伴應該都理解矩陣的乘法,不理解也沒有關係,看下圖這個例子,當兩個矩陣相乘時,對應元素之間會求和作為最終元素。

機器學習筆記(七)——初識邏輯迴歸、不同方法推導梯度公式

4。4繪製決策邊界

def plotDataSet(weight): #獲取權重陣列    weight = weight。getA()    # 載入資料和標籤    dataMat, labelMat = loadDataSet()    # 將列表轉換成numpy的array陣列    dataArr = np。array(dataMat)    #獲取樣本個數    n = np。shape(dataMat)[0]    #建立4個空列表,1代表正樣本、0代表負樣本    xcord1 = []; ycord1 = []    xcord0 = []; ycord0 = []    # 遍歷標籤列表,根據資料的標籤進行分類    for i in range(n):        if int(labelMat[i]) == 1:            # 如果標籤為1,將資料填入xcord1和ycord1            xcord1。append(dataArr[i,1]); ycord1。append(dataArr[i,2])        else:            # 如果標籤為0,將資料填入xcord0和ycord0            xcord0。append(dataArr[i,1]); ycord0。append(dataArr[i,2])    #繪製圖像    fig = plt。figure()    ax = fig。add_subplot(111)    ax。scatter(xcord1, ycord1, s = 20, c = ‘red’, marker = ‘*’,label = ‘Class1’)    ax。scatter(xcord0, ycord0, s = 20, c = ‘green’,marker = ‘s’,label = ‘Class2’)    #繪製直線,sigmoid設定為0    x = np。arange(-3。0, 3。0, 0。1)    y = (-weight[0] - weight[1] * x) / weight[2]    ax。plot(x, y)    #標題、x標籤、y標籤    plt。title(‘LRData’)    plt。legend(loc=‘upper left’)    plt。xlabel(‘X1’); plt。ylabel(‘X2’)    plt。savefig(“E:\machine_learning\LR03。jpg”)    plt。show()

這部分程式碼唯一需要注意的是,將

sigmoid

的值設定為0,可以回憶一下文章剛開始時的

Sigmoid

函式影象,0是兩個分類的分界處。因此,我們設定0=w_0x_0+w_1x_1+w_2x_2,x_0的值為1,所以已知迴歸係數,就可求得x_1和x_2的關係式,從而畫出決策邊界。

機器學習筆記(七)——初識邏輯迴歸、不同方法推導梯度公式

上圖可以看出分類的效果還是不錯的,根據函式繪製出的直線已經很大程度上將兩類樣本分隔開,100個樣本中,只有五個樣本分類錯誤,其中有三個還是位於迴歸線上。

五、文末總結

本文所講的梯度上升公式,屬於批次梯度上升,此外還有隨機梯度上升、小批次梯度上升,而批次梯度上升每次計算都要計算所有的樣本,所以程式計算過程是十分複雜的,並且容易收斂到區域性最優,而隨機梯度上升將會對演算法進行調優,下一篇文章將會介紹隨機梯度上升,並分析兩者之間的區別。

私信小編可獲取資料和原始碼供參考,感謝閱讀。