牛顿法在逻辑回归中的使用
逻辑回归,别看他的名字是回归,它其实是一个分类问题,而且是一个二分类的问题!逻辑回归是一个线性分类的问题。所以它的决策边界也是一个线性的。但是它的激励函数是非线性的哈!之前在进行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上的解释,从几何上说,牛顿法就是用一个二次曲面去拟合你当前所处位置的局部曲面,而梯度下降法是用一个平面去拟合当前的局部曲面,通常情况下,二次曲面的拟合会比平面更好,所以牛顿法选择的下降路径会更符合真实的最优下降路径。
推荐阅读