【機器學習實戰筆記】Logistic迴歸

Sigmoid函數

我們想定義一個函數,即能夠接受所有特徵輸入(自變量)然後預測出類別(因變量)。在二分類的情況下,可以定義輸出爲0和1。比如要預測一個動物是不是鳥類,是則爲1,不是則爲0。具有這種性質的函數,比較簡單的就是單位階躍函數(Heaviside step function)。但是該函數在x=0x=0處從0瞬間跳變到1,這樣就很難處理。換句話講,階躍函數在x=0x=0處不可微,這就不利於後面使用梯度上升或下降的方法。此時另一個函數就滿足類似的性質,即可以輸出0或1,這就是Sigmoid函數,如下
σ(z)=11+ez \sigma(z)=\frac{1}{1+\mathrm{e}^{-z}}
如圖5-1,當x=0x=0時,Sigmoid函數值爲0.5,隨着xx增大,對應的值將逼近於1;而隨着xx減小,Sigmoid值將逼近於0。如果橫座標刻度足夠大,如圖5-1下圖,Sigmoid函數看起來就很像一個階躍函數。
在這裏插入圖片描述

Logistic迴歸

而Logistic迴歸就是上面Sigmoid函數的輸入zz定義爲以下形式:
z=b+w1x1+w2x2+...+wnxn z=b+w_1x_1+w_2x_2+...+w_nx_n
其中x1,x2,...,xnx_1,x_2,...,x_n是輸入的特徵即自變量,w1,w2,...wnw_1,w_2,...w_n就是特徵對應的權重,或者叫迴歸係數,而通常b=w0x0b=w_0x_0是偏移量設爲1,上面公式可以簡寫爲:
z=wTx+b z=w^Tx+b
即Logistic迴歸的模型,剩下的我們只需要求出參數wwbb

梯度上升法

怎麼求出參數wwbb呢?書中給出了梯度上升法,隨機梯度上升以及改進的隨機梯度上升,梯度上升跟下降類似,只不過前者就局部最大值,後者求的是最小值。原理的雛形可結合導數與極值的關係,比較容易理解,參考:
在這裏插入圖片描述
在這裏插入圖片描述

wiki:隨機梯度下降

隨機梯度下降(Stochastic gradient descent)和 批量梯度下降(Batch gradient descent )的公式對比、實現對比

如何理解隨機梯度下降

需要理解批量梯度,也就是書中給出了第一種梯度上升,以及mini-batch梯度下降,和隨機梯度下降,簡單來講就是隨機梯度一次僅用一個樣本點來更新迴歸係數,mini-batch使用一小部分,批量梯度則是全部,這樣的話訓練速度更新會很慢,所以隨機梯度比較流行。並且隨機梯度是一個在線算法,可以在新數據到來時就完成參數更新,而不需要重新讀取整個數據集來進行批處理運算。

代碼

以下是基於梯度上升的Logistic迴歸算法,其中alpha就是機器學習中常講的學習率,也就是機器學習實戰這本書所講的步長。

import numpy as np

def sigmoid(inX):
    '''sigmoid函數
    '''
    return 1.0/(1+np.exp(-inX))

def gradAscent(dataMat,labelMat):
    '''批量梯度上升
    '''
    dataMat=np.mat(dataMat)
    labelMat=np.mat(labelMat).transpose()
    m,n=np.shape(dataMat) # m cannot be deleted
    alpha=0.001
    maxCycles=500
    weights=np.ones((n,1)) #weights[3*1]
    for k in range(maxCycles):
        h=sigmoid(dataMat*weights)
        error=(labelMat-h) #error[100*1]
        weights=weights+alpha*dataMat.transpose()*error
    print(weights)
    return weights

def stocGradAscent0(dataMat,labelMat):
    '''隨機梯度上升
    '''
    m,n=np.shape(dataMat) #dataMat[100*3]
    alpha=0.01
    weights=np.ones(n) #weights[1*3]
    dataArr=np.array(dataMat)
    for i in range(m):
        h=sigmoid(sum(dataMat[i]*weights)) # dataMat[i]表示一個樣本
        error=labelMat[i]-h
        weights=weights+alpha*error*dataArr[i]
    return weights

def stocGradAscent1(dataMat,labelMat,iteration=150):
    '''改進的隨機梯度上升
    '''
    m,n=np.shape(dataMat)
    weights=np.ones(n)
    dataArr=np.array(dataMat)
    for j in range(iteration):
        dataIndex=dataMat.copy() # initially dataIndex=range(m),but a range cannot be operated by del() at line 75
        for i in range(m):
            alpha=4/(1.0+j+i)+0.01 #apha decreases with iteration, does not
            randIndex=int(np.random.uniform(0,len(dataIndex))) #go to 0 because of the constant
            h=sigmoid(sum(dataMat[randIndex]*weights))
            error=labelMat[randIndex]-h
            weights=weights+alpha*error*dataArr[randIndex]
            del(dataIndex[randIndex])
    return weights

def classifyVector(inX,weights):
    prob=sigmoid(sum(inX*weights))
    if prob>0.5: return 1.0
    else: return 0.0

相關問題

以下問題提供思考:

  • Logistic迴歸與多重線性迴歸的區別?
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章