1. 程式人生 > >牛頓法在邏輯迴歸中的使用

牛頓法在邏輯迴歸中的使用

邏輯迴歸,別看他的名字是迴歸,它其實是一個分類問題,而且是一個二分類的問題!邏輯迴歸是一個線性分類的問題。所以它的決策邊界也是一個線性的。但是它的激勵函式是非線性的哈!之前在進行ml的學習的時候,我已經介紹過相關的東西,詳見部落格邏輯迴歸,包括他的假設函式,代價函式,它的優化演算法可以是梯度下降,隨機梯度下降,牛頓法等等,但是在上學校的ml的課程的時候,我發現了不僅可以用梯度下降來更新我們的引數,還可以使用牛頓法來更新引數,而且收斂的速度更加的快!

下面我要解決四個問題,

第一牛頓法的介紹:

盜一下,老師上課的PPT的圖

結合上圖來解釋一下:

目標:求得使得代價函式J(\theta)最小的\theta,所以上圖先求得J(\theta)

的一階導數,但是不是像往常一樣令J^{'}(\theta)=0來得到\theta,而是採用迭代的方法。

具體做法:看到上圖的最佳的\theta肯定是在與x軸的交點的地方,

第一步:先隨機的選取一點\theta^{(0)},那麼在這一點對應的J^{'}(\theta)的地方畫一條切線,這個切線與X軸的交點就是\theta^{(1)}\theta^{(1)}=\theta^{(0)}-\frac{J^{'}(\theta^{(0)})}{J^{''}(\theta^{(0)})}

第二布:重複唄,

那麼怎麼判斷到了最佳的那個\theta^*,可以看前後的loss變化小於某個闕值的時候,我就結束討論!

第二邏輯迴歸牛頓法的使用:

那麼上面的那個J(\theta)不就對應了邏輯迴歸的損失函式。

上面怎麼推到的呢?

那麼總結一下:牛頓法是怎麼用到邏輯迴歸問題中的

第三牛頓法的實現程式碼:

其他的程式碼你可以參見另一個部落格,之前那個部落格實現牛頓法的時候僅僅只是跑5步,因為我看到出來的loss大約在第五步的時候就不動了,所以我直接設定成了5,這裡我稍作更改了一下:這裡面用到的其他我定義的庫,都可以在這裡看到

牛頓法的實現需要的其他檔案程式碼

import numpy as np
import matplotlib.pyplot as plt
from file2matrix import file2matrix
from sigmoid import sigmoid
from compute_loss import compute_loss

a=np.diag(np.array([1,2]))
print(a)

def nt(x,y,theta,iterations=100):
    n,m=x.shape
    J_loss=[]
    orig_loss=np.inf
    real_iter=0
    for i in range(iterations):
        l=compute_loss(x,y,theta)
        J_loss.append(l)
        h=sigmoid(np.dot(x,theta))#(n,1)
        # print("h-shape",h.shape)
        j_first_order=1/n*np.dot(x.T,h-y)#(m,1)
        j_second_order=1/n*np.dot(np.dot(np.dot(x.T,np.diag(h.reshape(n))),np.diag(1-h.reshape(n))),x)#(m,m)
        theta=theta-np.dot(np.linalg.inv(j_second_order),j_first_order)#(m,1)
        # print("theta-shape",theta.shape)
        if orig_loss-l<0.001:
            real_iter=i+1
            break
        orig_loss=l
    return theta,J_loss,real_iter

if __name__=="__main__":
    X = file2matrix('./ex4x.dat')
    # print(X.shape)#(80,2)
    # returnmat = X
    y = file2matrix('./ex4y.dat', 1)
    # print(y.shape)#(80,1)

    n, m = X.shape
    X = np.column_stack((np.ones(n), X))
    # print(X.shape)
    m = m + 1
    theta = np.zeros((m, 1))

    theta, J_his,real_iter = nt(X, y, theta)
    print(real_iter)

    print("theta", theta)
    print("J", J_his)
    plt.xlabel("iteration")
    plt.ylabel("J")
    plt.plot(np.arange(real_iter), J_his)
    plt.show()

    pos = list(np.where(y == 1.0)[0])
    X_pos = X[pos,1:3]
    neg = list(np.where(y == 0.0)[0])
    X_neg = X[neg,1:3]
    plt.plot(X_pos[:, 0], X_pos[:, 1], '+', label='admitted')
    plt.plot(X_neg[:, 0], X_neg[:, 1], 'o', label='Not admitted')
    plt.xlabel("exam1 score")
    plt.ylabel("exam2 score")
    plt.legend()

    xx = np.linspace(20, 70, 6)
    yy = []
    for i in xx:
        res = (i * -(theta[1][0]) - (theta[0][0])) / (theta[2][0])
        yy.append(res)
    plt.plot(xx, yy)
    plt.show()

第四牛頓法為什麼會比梯度下降快那麼多呢?

說是因為牛頓法使用了二階梯度,梯度下降僅僅是一階梯度,對於梯度下降而言,把它比做下山問題,那麼梯度下降站在當前的位置要找到梯度最大的點,這樣也就是坡度最大下山最快,但是牛頓法他不僅要找當前下降最快的方向,還要確保下下步的坡度更大,下山更快。

它還說:但是不太懂下面的一段話!!!

根據wiki上的解釋,從幾何上說,牛頓法就是用一個二次曲面去擬合你當前所處位置的局部曲面,而梯度下降法是用一個平面去擬合當前的局部曲面,通常情況下,二次曲面的擬合會比平面更好,所以牛頓法選擇的下降路徑會更符合真實的最優下降路徑。