欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

牛顿法在逻辑回归中的使用

程序员文章站 2024-02-27 19:43:15
...

逻辑回归,别看他的名字是回归,它其实是一个分类问题,而且是一个二分类的问题!逻辑回归是一个线性分类的问题。所以它的决策边界也是一个线性的。但是它的激励函数是非线性的哈!之前在进行ml的学习的时候,我已经介绍过相关的东西,详见博客逻辑回归,包括他的假设函数,代价函数,它的优化算法可以是梯度下降,随机梯度下降,牛顿法等等,但是在上学校的ml的课程的时候,我发现了不仅可以用梯度下降来更新我们的参数,还可以使用牛顿法来更新参数,而且收敛的速度更加的快!

下面我要解决四个问题,

第一牛顿法的介绍:

盗一下,老师上课的PPT的图

牛顿法在逻辑回归中的使用

结合上图来解释一下:

目标:求得使得代价函数牛顿法在逻辑回归中的使用最小的牛顿法在逻辑回归中的使用,所以上图先求得牛顿法在逻辑回归中的使用的一阶导数,但是不是像往常一样令牛顿法在逻辑回归中的使用来得到牛顿法在逻辑回归中的使用,而是采用迭代的方法。

具体做法:看到上图的最佳的牛顿法在逻辑回归中的使用肯定是在与x轴的交点的地方,

第一步:先随机的选取一点牛顿法在逻辑回归中的使用,那么在这一点对应的牛顿法在逻辑回归中的使用的地方画一条切线,这个切线与X轴的交点就是牛顿法在逻辑回归中的使用牛顿法在逻辑回归中的使用

第二布:重复呗,

那么怎么判断到了最佳的那个牛顿法在逻辑回归中的使用,可以看前后的loss变化小于某个阙值的时候,我就结束讨论!

 

第二逻辑回归牛顿法的使用:

那么上面的那个牛顿法在逻辑回归中的使用不就对应了逻辑回归的损失函数。

牛顿法在逻辑回归中的使用

上面怎么推到的呢?

牛顿法在逻辑回归中的使用

那么总结一下:牛顿法是怎么用到逻辑回归问题中的

牛顿法在逻辑回归中的使用

 

第三牛顿法的实现代码:

其他的代码你可以参见另一个博客,之前那个博客实现牛顿法的时候仅仅只是跑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()

第四牛顿法为什么会比梯度下降快那么多呢?

说是因为牛顿法使用了二阶梯度,梯度下降仅仅是一阶梯度,对于梯度下降而言,把它比做下山问题,那么梯度下降站在当前的位置要找到梯度最大的点,这样也就是坡度最大下山最快,但是牛顿法他不仅要找当前下降最快的方向,还要确保下下步的坡度更大,下山更快。

参考文献https://blog.csdn.net/pi9nc/article/details/11922835

它还说:但是不太懂下面的一段话!!!

根据wiki上的解释,从几何上说,牛顿法就是用一个二次曲面去拟合你当前所处位置的局部曲面,而梯度下降法是用一个平面去拟合当前的局部曲面,通常情况下,二次曲面的拟合会比平面更好,所以牛顿法选择的下降路径会更符合真实的最优下降路径。